"TYPO3 4.0.1: typo3_src-4.0.1/t3lib/class.t3lib_stdgraphic.php Source File", "datetime" => "Sat Dec 2 19:22:18 2006", "date" => "2 Dec 2006", "doxygenversion" => "1.4.6", "projectname" => "TYPO3 4.0.1", "projectnumber" => "4.0.1" ); get_header($doxygen_vars); ?>

class.t3lib_stdgraphic.php

00001 <?php
00002 /***************************************************************
00003 *  Copyright notice
00004 *
00005 *  (c) 1999-2006 Kasper Skaarhoj (kasperYYYY@typo3.com)
00006 *  All rights reserved
00007 *
00008 *  This script is part of the TYPO3 project. The TYPO3 project is
00009 *  free software; you can redistribute it and/or modify
00010 *  it under the terms of the GNU General Public License as published by
00011 *  the Free Software Foundation; either version 2 of the License, or
00012 *  (at your option) any later version.
00013 *
00014 *  The GNU General Public License can be found at
00015 *  http://www.gnu.org/copyleft/gpl.html.
00016 *  A copy is found in the textfile GPL.txt and important notices to the license
00017 *  from the author is found in LICENSE.txt distributed with these scripts.
00018 *
00019 *
00020 *  This script is distributed in the hope that it will be useful,
00021 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00022 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023 *  GNU General Public License for more details.
00024 *
00025 *  This copyright notice MUST APPEAR in all copies of the script!
00026 ***************************************************************/
00155 class t3lib_stdGraphic  {
00156 
00157                 // Internal configuration, set in init()
00158         var $combineScript = 'combine';                         // The ImageMagick filename used for combining two images. This name changed during the versions.
00159         var $noFramePrepended=0;                                        // If set, there is no frame pointer prepended to the filenames.
00160         var $GD2=0;                                                                     // Set, if the GDlib used is version 2.
00161         var $imagecopyresized_fix=0;                            // If set, imagecopyresized will not be called directly. For GD2 (some PHP installs?)
00162         var $gifExtension = 'gif';                                      // This should be changed to 'png' if you want this class to read/make PNG-files instead!
00163         var $gdlibExtensions = '';                      // File formats supported by gdlib. This variable get's filled in "init" method
00164         var $truecolor = true;                                  // Internal variable which get's used to determine wheter GDlib should use function truecolor pendants
00165         var $png_truecolor = false;                                     // Set to true if generated png's should be truecolor by default
00166         var $truecolorColors = 0xffffff;                        // 16777216 Colors is the maximum value for PNG, JPEG truecolor images (24-bit, 8-bit / Channel)
00167         var $TTFLocaleConv = '';                                        // Used to recode input to TTF-functions for other charsets.
00168         var $enable_typo3temp_db_tracking = 0;          // If set, then all files in typo3temp will be logged in a database table. In addition to being a log of the files with original filenames, it also serves to secure that the same image is not rendered simultaneously by two different processes.
00169         var $imageFileExt = 'gif,jpg,jpeg,png,tif,bmp,tga,pcx,ai,pdf';  // Commalist of file extensions perceived as images by TYPO3. List should be set to 'gif,png,jpeg,jpg' if IM is not available. Lowercase and no spaces between!
00170         var $webImageExt = 'gif,jpg,jpeg,png';          // Commalist of web image extensions (can be shown by a webbrowser)
00171         var $maskNegate = '';                                           // Will be ' -negate' if ImageMagick ver 5.2+. See init();
00172         var $NO_IM_EFFECTS = '';
00173         var $cmds = Array (
00174                 'jpg' => '',
00175                 'jpeg' => '',
00176                 'gif' => '-colors 64',
00177                 'png' => '-colors 64'
00178         );
00179         var $NO_IMAGE_MAGICK = '';
00180         var $V5_EFFECTS = 0;
00181         var $im_version_4 = 0;
00182         var $mayScaleUp = 1;
00183 
00184                 // Variables for testing, alternative usage etc.
00185         var $filenamePrefix='';                                                         // Filename prefix for images scaled in imageMagickConvert()
00186         var $imageMagickConvert_forceFileNameBody='';           // Forcing the output filename of imageMagickConvert() to this value. However after calling imageMagickConvert() it will be set blank again.
00187         var $dontCheckForExistingTempFile = 0;                          // This flag should always be false. If set true, imageMagickConvert will always write a new file to the tempdir! Used for debugging.
00188         var $dontCompress=0;                                                            // Prevents imageMagickConvert() from compressing the gif-files with t3lib_div::gif_compress()
00189         var $dontUnlinkTempFiles=0;                                                     // For debugging ONLY!
00190         var $alternativeOutputKey='';                                           // For debugging only. Filenames will not be based on mtime and only filename (not path) will be used. This key is also included in the hash of the filename...
00191 
00192                 // Internal:
00193         var $IM_commands = Array();                                                     // All ImageMagick commands executed is stored in this array for tracking. Used by the Install Tools Image section
00194         var $workArea = Array();
00195 
00196                 // Constants:
00197         var $tempPath = 'typo3temp/';                                           // The temp-directory where to store the files. Normally relative to PATH_site but is allowed to be the absolute path AS LONG AS it is a subdir to PATH_site.
00198         var $absPrefix = '';                                                            // Prefix for relative paths. Used in "show_item.php" script. Is prefixed the output file name IN imageMagickConvert()
00199         var $scalecmd = '-geometry';                                            // ImageMagick scaling command; "-geometry" eller "-sample". Used in makeText() and imageMagickConvert()
00200         var $im5fx_blurSteps='1x2,2x2,3x2,4x3,5x3,5x4,6x4,7x5,8x5,9x5';                 // Used by v5_blur() to simulate 10 continuous steps of blurring
00201         var $im5fx_sharpenSteps='1x2,2x2,3x2,2x3,3x3,4x3,3x4,4x4,4x5,5x5';              // Used by v5_sharpen() to simulate 10 continuous steps of sharpening.
00202         var $pixelLimitGif = 10000;                                                     // This is the limit for the number of pixels in an image before it will be rendered as JPG instead of GIF/PNG
00203         var $colMap = Array (                                                           // Array mapping HTML color names to RGB values.
00204                 'aqua' => Array(0,255,255),
00205                 'black' => Array(0,0,0),
00206                 'blue' => Array(0,0,255),
00207                 'fuchsia' => Array(255,0,255),
00208                 'gray' => Array(128,128,128),
00209                 'green' => Array(0,128,0),
00210                 'lime' => Array(0,255,0),
00211                 'maroon' => Array(128,0,0),
00212                 'navy' => Array(0,0,128),
00213                 'olive' => Array(128,128,0),
00214                 'purple' => Array(128,0,128),
00215                 'red' => Array(255,0,0),
00216                 'silver' => Array(192,192,192),
00217                 'teal' => Array(0,128,128),
00218                 'yellow' => Array(255,255,0),
00219                 'white' => Array(255,255,255)
00220         );
00221 
00222                 // Charset conversion object:
00223         var $csConvObj;
00224         var $nativeCharset='';          // Is set to the native character set of the input strings.
00225 
00226 
00227 
00228 
00229 
00236         function init() {
00237                 $gfxConf = $GLOBALS['TYPO3_CONF_VARS']['GFX'];
00238 
00239                 if (function_exists('imagecreatefromjpeg')&&function_exists('imagejpeg'))       {
00240                         $this->gdlibExtensions .= ',jpg,jpeg';
00241                 }
00242                 if (function_exists('imagecreatefrompng')&&function_exists('imagepng')) {
00243                         $this->gdlibExtensions .= ',png';
00244                 }
00245                 if (function_exists('imagecreatefromgif')&&function_exists('imagegif')) {
00246                         $this->gdlibExtensions .= ',gif';
00247                 }
00248                 if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['png_truecolor'])        {
00249                         $this->png_truecolor = true;
00250                 }
00251                 if (!$gfxConf['gdlib_2'] || !function_exists('imagecreatetruecolor'))   {
00252                         $this->truecolor = false;
00253                 }
00254                 if (!$gfxConf['im_version_5'])  {
00255                         $this->im_version_4 = true;
00256                 }
00257 
00258                         // When GIFBUILDER gets used in truecolor mode (GD2 required)
00259                 if ($this->truecolor)   {
00260                         if ($this->png_truecolor)       {
00261                                 $this->cmds['png'] = '';        // No colors parameter if we generate truecolor images.
00262                         }
00263                         $this->cmds['gif'] = '';        // No colors parameter if we generate truecolor images.
00264                 }
00265 
00266                         // Setting default JPG parameters:
00267                 $this->jpegQuality = t3lib_div::intInRange($gfxConf['jpg_quality'], 10, 100, 75);
00268                 $this->cmds['jpg'] = $this->cmds['jpeg'] = '-colorspace RGB -sharpen 50 -quality '.$this->jpegQuality;
00269 
00270                 if ($gfxConf['im_combine_filename'])    $this->combineScript=$gfxConf['im_combine_filename'];
00271                 if ($gfxConf['im_noFramePrepended'])    $this->noFramePrepended=1;
00272 
00273                 if ($gfxConf['gdlib_2'])        {
00274                         $this->GD2 = 1;
00275                         $this->imagecopyresized_fix = $gfxConf['gdlib_2']==='no_imagecopyresized_fix' ? 0 : 1;
00276                 }
00277                 if ($gfxConf['gdlib_png'])      {
00278                         $this->gifExtension='png';
00279                 }
00280                 if ($gfxConf['TTFLocaleConv']) {
00281                         $this->TTFLocaleConv = $gfxConf['TTFLocaleConv'];
00282                 }
00283                 if ($gfxConf['enable_typo3temp_db_tracking']) {
00284                         $this->enable_typo3temp_db_tracking = $gfxConf['enable_typo3temp_db_tracking'];
00285                 }
00286 
00287                 $this->imageFileExt = $gfxConf['imagefile_ext'];
00288 
00289                         // This should be set if ImageMagick ver. 5+ is used.
00290                 if ($gfxConf['im_negate_mask']) {
00291                                 // Boolean. Indicates if the mask images should be inverted first.
00292                                 // This depends of the ImageMagick version. Below ver. 5.1 this should be false.
00293                                 // Above ImageMagick version 5.2+ it should be true.
00294                                 // Just set the flag if the masks works opposite the intension!
00295                         $this->maskNegate = ' -negate';
00296                 }
00297                 if ($gfxConf['im_no_effects'])  {
00298                                 // Boolean. This is necessary if using ImageMagick 5+.
00299                                 // Approved version for using effects is version 4.2.9.
00300                                 // Effects in Imagemagick 5+ tends to render very slowly!!
00301                                 // - therefore must be disabled in order not to perform sharpen, blurring and such.
00302                         $this->NO_IM_EFFECTS = 1;
00303 
00304                         $this->cmds['jpg'] = $this->cmds['jpeg'] = '-colorspace RGB -quality '.$this->jpegQuality;
00305                 }
00306                         // ... but if 'im_v5effects' is set, don't care about 'im_no_effects'
00307                 if ($gfxConf['im_v5effects'])   {
00308                         $this->NO_IM_EFFECTS = 0;
00309                         $this->V5_EFFECTS = 1;
00310 
00311                         if ($gfxConf['im_v5effects']>0) {
00312                                 $this->cmds['jpg'] = $this->cmds['jpeg'] = '-colorspace RGB -quality '.intval($gfxConf['jpg_quality']).$this->v5_sharpen(10);
00313                         }
00314                 }
00315 
00316                 if (!$gfxConf['im'])    {
00317                         $this->NO_IMAGE_MAGICK = 1;
00318                 }
00319                         // Secures that images are not scaled up.
00320                 if ($gfxConf['im_noScaleUp']) {
00321                         $this->mayScaleUp=0;
00322                 }
00323 
00324                 if (TYPO3_MODE=='FE')   {
00325                         $this->csConvObj = &$GLOBALS['TSFE']->csConvObj;
00326                 } elseif(is_object($GLOBALS['LANG']))   {       // BE assumed:
00327                         $this->csConvObj = &$GLOBALS['LANG']->csConvObj;
00328                 } else  {       // The object may not exist yet, so we need to create it now. Happens in the Install Tool for example.
00329                         $this->csConvObj = t3lib_div::makeInstance('t3lib_cs');
00330                 }
00331                 $this->nativeCharset = $GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'];
00332         }
00333 
00334 
00335 
00336 
00337 
00338 
00339 
00340 
00341 
00342 
00343 
00344 
00345 
00346 
00347 
00348 
00349         /*************************************************
00350          *
00351          * Layering images / "IMAGE" GIFBUILDER object
00352          *
00353          *************************************************/
00354 
00366         function maskImageOntoImage(&$im,$conf,$workArea)       {
00367                 if ($conf['file'] && $conf['mask'])     {
00368                         $imgInf = pathinfo($conf['file']);
00369                         $imgExt = strtolower($imgInf['extension']);
00370                         if (!t3lib_div::inList($this->gdlibExtensions, $imgExt))        {
00371                                 $BBimage = $this->imageMagickConvert($conf['file'],$this->gifExtension,'','','','','');
00372                         } else  {
00373                                 $BBimage = $this->getImageDimensions($conf['file']);
00374                         }
00375                         $maskInf = pathinfo($conf['mask']);
00376                         $maskExt = strtolower($maskInf['extension']);
00377                         if (!t3lib_div::inList($this->gdlibExtensions, $maskExt))       {
00378                                 $BBmask = $this->imageMagickConvert($conf['mask'],$this->gifExtension,'','','','','');
00379                         } else  {
00380                                 $BBmask = $this->getImageDimensions($conf['mask']);
00381                         }
00382                         if ($BBimage && $BBmask)        {
00383                                 $w = imagesx($im);
00384                                 $h = imagesy($im);
00385                                 $tmpStr = $this->randomName();
00386                                 $theImage = $tmpStr.'_img.'.$this->gifExtension;
00387                                 $theDest = $tmpStr.'_dest.'.$this->gifExtension;
00388                                 $theMask = $tmpStr.'_mask.'.$this->gifExtension;
00389                                                 // prepare overlay image
00390                                 $cpImg = $this->imageCreateFromFile($BBimage[3]);
00391                                 $destImg = $this->imagecreate($w,$h);
00392                                 $Bcolor = ImageColorAllocate($destImg, 0,0,0);
00393                                 ImageFilledRectangle($destImg, 0, 0, $w, $h, $Bcolor);
00394                                 $this->copyGifOntoGif($destImg,$cpImg,$conf,$workArea);
00395                                 $this->ImageWrite($destImg, $theImage);
00396                                 imageDestroy($cpImg);
00397                                 imageDestroy($destImg);
00398                                                 // prepare mask image
00399                                 $cpImg = $this->imageCreateFromFile($BBmask[3]);
00400                                 $destImg = $this->imagecreate($w,$h);
00401                                 $Bcolor = ImageColorAllocate($destImg, 0, 0, 0);
00402                                 ImageFilledRectangle($destImg, 0, 0, $w, $h, $Bcolor);
00403                                 $this->copyGifOntoGif($destImg,$cpImg,$conf,$workArea);
00404                                 $this->ImageWrite($destImg, $theMask);
00405                                 imageDestroy($cpImg);
00406                                 imageDestroy($destImg);
00407                                         // mask the images
00408                                 $this->ImageWrite($im, $theDest);
00409 
00410                                 $this->combineExec($theDest,$theImage,$theMask,$theDest, true);         // Let combineExec handle maskNegation
00411 
00412                                 $backIm = $this->imageCreateFromFile($theDest); // The main image is loaded again...
00413                                 if ($backIm)    {       // ... and if nothing went wrong we load it onto the old one.
00414                                         ImageColorTransparent($backIm,-1);
00415                                         $im = $backIm;
00416                                 }
00417                                         // unlink files from process
00418                                 if (!$this->dontUnlinkTempFiles)        {
00419                                         unlink($theDest);
00420                                         unlink($theImage);
00421                                         unlink($theMask);
00422                                 }
00423                         }
00424                 }
00425         }
00426 
00436         function copyImageOntoImage(&$im,$conf,$workArea)       {
00437                 if ($conf['file'])      {
00438                         if (!t3lib_div::inList($this->gdlibExtensions, $conf['BBOX'][2]))       {
00439                                 $conf['BBOX']=$this->imageMagickConvert($conf['BBOX'][3],$this->gifExtension,'','','','','');
00440                                 $conf['file']=$conf['BBOX'][3];
00441                         }
00442                         $cpImg = $this->imageCreateFromFile($conf['file']);
00443                         $this->copyGifOntoGif($im,$cpImg,$conf,$workArea);
00444                         imageDestroy($cpImg);
00445                 }
00446         }
00447 
00458         function copyGifOntoGif(&$im,$cpImg,$conf,$workArea)    {
00459                 $cpW = imagesx($cpImg);
00460                 $cpH = imagesy($cpImg);
00461                 $tile = t3lib_div::intExplode(',',$conf['tile']);
00462                 $tile[0] = t3lib_div::intInRange($tile[0],1,20);
00463                 $tile[1] = t3lib_div::intInRange($tile[1],1,20);
00464                 $cpOff = $this->objPosition($conf,$workArea,Array($cpW*$tile[0],$cpH*$tile[1]));
00465 
00466                 for ($xt=0;$xt<$tile[0];$xt++)  {
00467                         $Xstart=$cpOff[0]+$cpW*$xt;
00468                         if ($Xstart+$cpW > $workArea[0])        {       // if this image is inside of the workArea, then go on
00469                                         // X:
00470                                 if ($Xstart < $workArea[0])     {
00471                                         $cpImgCutX = $workArea[0]-$Xstart;
00472                                         $Xstart = $workArea[0];
00473                                 } else {
00474                                         $cpImgCutX = 0;
00475                                 }
00476                                 $w = $cpW-$cpImgCutX;
00477                                 if ($Xstart > $workArea[0]+$workArea[2]-$w)     {
00478                                         $w = $workArea[0]+$workArea[2]-$Xstart;
00479                                 }
00480                                 if ($Xstart < $workArea[0]+$workArea[2])        {       // if this image is inside of the workArea, then go on
00481                                                 // Y:
00482                                         for ($yt=0;$yt<$tile[1];$yt++)  {
00483                                                 $Ystart=$cpOff[1]+$cpH*$yt;
00484                                                 if ($Ystart+$cpH > $workArea[1])        {       // if this image is inside of the workArea, then go on
00485                                                         if ($Ystart < $workArea[1])     {
00486                                                                 $cpImgCutY = $workArea[1]-$Ystart;
00487                                                                 $Ystart = $workArea[1];
00488                                                         } else {
00489                                                                 $cpImgCutY = 0;
00490                                                         }
00491                                                         $h = $cpH-$cpImgCutY;
00492                                                         if ($Ystart > $workArea[1]+$workArea[3]-$h)     {
00493                                                                 $h = $workArea[1]+$workArea[3]-$Ystart;
00494                                                         }
00495                                                         if ($Ystart < $workArea[1]+$workArea[3])        {       // if this image is inside of the workArea, then go on
00496                                                                 $this->imagecopyresized($im, $cpImg, $Xstart, $Ystart, $cpImgCutX, $cpImgCutY, $w, $h, $w, $h);
00497                                                         }
00498                                                 }
00499                                         }  // Y:
00500                                 }
00501                         }
00502                 }
00503         }
00504 
00537         function imagecopyresized(&$im, $cpImg, $Xstart, $Ystart, $cpImgCutX, $cpImgCutY, $w, $h, $w, $h)       {
00538                 if ($this->imagecopyresized_fix)        {
00539                         $im_base = $this->imagecreate(imagesx($im), imagesy($im));      // Make true color image
00540                         imagecopyresized($im_base, $im, 0,0,0,0, imagesx($im),imagesy($im),imagesx($im),imagesy($im));  // Copy the source image onto that
00541                         imagecopyresized($im_base, $cpImg, $Xstart, $Ystart, $cpImgCutX, $cpImgCutY, $w, $h, $w, $h);   // Then copy the $cpImg onto that (the actual operation!)
00542                         $im = $im_base; // Set pointer
00543                         if (!$this->truecolor)  {
00544                                 $this->makeEffect($im, Array('value'=>'colors='.t3lib_div::intInRange($this->setup['reduceColors'], 256, $this->truecolorColors, 256)));                // Reduce to "reduceColors" colors - make SURE that IM is working then!
00545                         }
00546                 } else {
00547                         imagecopyresized($im, $cpImg, $Xstart, $Ystart, $cpImgCutX, $cpImgCutY, $w, $h, $w, $h);
00548                 }
00549         }
00550 
00551 
00552 
00553 
00554 
00555 
00556 
00557 
00558 
00559 
00560 
00561 
00562 
00563 
00564 
00565 
00566 
00567 
00568 
00569 
00570 
00571 
00572         /********************************
00573          *
00574          * Text / "TEXT" GIFBUILDER object
00575          *
00576          ********************************/
00577 
00587         function makeText(&$im,$conf,$workArea) {
00588                         // Spacing
00589                 list($spacing,$wordSpacing) = $this->calcWordSpacing($conf);
00590                         // Position
00591                 $txtPos = $this->txtPosition($conf,$workArea,$conf['BBOX']);
00592                 $theText = $this->recodeString($conf['text']);
00593 
00594                 if ($conf['imgMap'] && is_array($conf['imgMap.']))      {
00595                         $this->addToMap($this->calcTextCordsForMap($conf['BBOX'][2],$txtPos, $conf['imgMap.']), $conf['imgMap.']);
00596                 }
00597                 if (!$conf['hideButCreateMap']) {
00598                                 // Font Color:
00599                         $cols=$this->convertColor($conf['fontColor']);
00600                                 // NiceText is calculated
00601                         if (!$conf['niceText']) {
00602                                         // Font Color is reserved:
00603                                 if (!$this->truecolor)  {
00604                                         $reduce = t3lib_div::intInRange($this->setup['reduceColors'], 256, $this->truecolorColors, 256);
00605                                         $this->reduceColors($im, $reduce-49, $reduce-50);       // If "reduce-49" colors (or more) are used reduce them to "reduce-50"
00606                                 }
00607                                 $Fcolor = ImageColorAllocate($im, $cols[0],$cols[1],$cols[2]);
00608                                         // antiAliasing is setup:
00609                                 $Fcolor = ($conf['antiAlias']) ? $Fcolor : -$Fcolor;
00610 
00611                                 for ($a=0; $a<$conf['iterations']; $a++)        {
00612                                         if ($spacing || $wordSpacing)   {               // If any kind of spacing applys, we use this function:
00613                                                 $this->SpacedImageTTFText($im, $conf['fontSize'], $conf['angle'], $txtPos[0], $txtPos[1], $Fcolor, t3lib_stdGraphic::prependAbsolutePath($conf['fontFile']), $theText, $spacing, $wordSpacing, $conf['splitRendering.']);
00614                                         } else {
00615                                                 $this->ImageTTFTextWrapper($im, $conf['fontSize'], $conf['angle'], $txtPos[0], $txtPos[1], $Fcolor, $conf['fontFile'], $theText, $conf['splitRendering.']);
00616                                         }
00617                                 }
00618                         } else {                // NICETEXT::
00619                                         // options anti_aliased and iterations is NOT available when doing this!!
00620                                 $w = imagesx($im);
00621                                 $h = imagesy($im);
00622                                 $tmpStr = $this->randomName();
00623 
00624                                 $fileMenu = $tmpStr.'_menuNT.'.$this->gifExtension;
00625                                 $fileColor = $tmpStr.'_colorNT.'.$this->gifExtension;
00626                                 $fileMask = $tmpStr.'_maskNT.'.$this->gifExtension;
00627                                         // Scalefactor
00628                                 $sF = t3lib_div::intInRange($conf['niceText.']['scaleFactor'],2,5);
00629                                 $newW = ceil($sF*imagesx($im));
00630                                 $newH = ceil($sF*imagesy($im));
00631 
00632                                         // Make mask
00633                                 $maskImg = $this->imagecreate($newW, $newH);
00634                                 $Bcolor = ImageColorAllocate($maskImg, 255,255,255);
00635                                 ImageFilledRectangle($maskImg, 0, 0, $newW, $newH, $Bcolor);
00636                                 $Fcolor = ImageColorAllocate($maskImg, 0,0,0);
00637                                 if ($spacing || $wordSpacing)   {               // If any kind of spacing applys, we use this function:
00638                                         $this->SpacedImageTTFText($maskImg, $conf['fontSize'], $conf['angle'], $txtPos[0], $txtPos[1], $Fcolor, t3lib_stdGraphic::prependAbsolutePath($conf['fontFile']), $theText, $spacing, $wordSpacing, $conf['splitRendering.'],$sF);
00639                                 } else {
00640                                         $this->ImageTTFTextWrapper($maskImg, $conf['fontSize'], $conf['angle'], $txtPos[0], $txtPos[1], $Fcolor, $conf['fontFile'], $theText, $conf['splitRendering.'],$sF);
00641                                 }
00642                                 $this->ImageWrite($maskImg, $fileMask);
00643                                 ImageDestroy($maskImg);
00644 
00645                                         // Downscales the mask
00646                                 if ($this->NO_IM_EFFECTS)       {
00647                                         if ($this->maskNegate)  {
00648                                                 $command = trim($this->scalecmd.' '.$w.'x'.$h.'!');             // Negate 2 times makes no negate...
00649                                         } else {
00650                                                 $command = trim($this->scalecmd.' '.$w.'x'.$h.'! -negate');
00651                                         }
00652                                 } else {
00653                                         if ($this->maskNegate)  {
00654                                                 $command = trim($conf['niceText.']['before'].' '.$this->scalecmd.' '.$w.'x'.$h.'! '.$conf['niceText.']['after']);
00655                                         } else {
00656                                                 $command = trim($conf['niceText.']['before'].' '.$this->scalecmd.' '.$w.'x'.$h.'! '.$conf['niceText.']['after'].' -negate');
00657                                         }
00658                                         if ($conf['niceText.']['sharpen']) {
00659                                                 if ($this->V5_EFFECTS)  {
00660                                                         $command.=$this->v5_sharpen($conf['niceText.']['sharpen']);
00661                                                 } else {
00662                                                         $command.=' -sharpen '.t3lib_div::intInRange($conf['niceText.']['sharpen'],1,99);
00663                                                 }
00664                                         }
00665                                 }
00666 
00667                                 $this->imageMagickExec($fileMask,$fileMask,$command);
00668 
00669                                         // Make the color-file
00670                                 $colorImg = $this->imagecreate($w,$h);
00671                                 $Ccolor = ImageColorAllocate($colorImg, $cols[0],$cols[1],$cols[2]);
00672                                 ImageFilledRectangle($colorImg, 0, 0, $w, $h, $Ccolor);
00673                                 $this->ImageWrite($colorImg, $fileColor);
00674                                 ImageDestroy($colorImg);
00675 
00676                                         // The mask is applied
00677                                 $this->ImageWrite($im, $fileMenu);      // The main pictures is saved temporarily
00678 
00679                                 $this->combineExec($fileMenu,$fileColor,$fileMask, $fileMenu);
00680 
00681                                 $backIm = $this->imageCreateFromFile($fileMenu);        // The main image is loaded again...
00682                                 if ($backIm)    {       // ... and if nothing went wrong we load it onto the old one.
00683                                         ImageColorTransparent($backIm,-1);
00684                                         $im = $backIm;
00685                                 }
00686 
00687                                         // Deleting temporary files;
00688                                 if (!$this->dontUnlinkTempFiles)        {
00689                                         unlink($fileMenu);
00690                                         unlink($fileColor);
00691                                         unlink($fileMask);
00692                                 }
00693                         }
00694                 }
00695         }
00696 
00707         function txtPosition($conf,$workArea,$BB) {
00708                 $bbox = $BB[2];
00709                 $angle=intval($conf['angle'])/180*pi();
00710                 $conf['angle']=0;
00711                 $straightBB = $this->calcBBox($conf);
00712 
00713                         // offset, align, valign, workarea
00714                 $result=Array();        // [0]=x, [1]=y, [2]=w, [3]=h
00715                 $result[2] = $BB[0];
00716                 $result[3] = $BB[1];
00717                 $w=$workArea[2];
00718                 $h=$workArea[3];
00719 
00720                 switch($conf['align'])  {
00721                         case 'right':
00722                         case 'center':
00723                                 $factor=abs(cos($angle));
00724                                 $sign=(cos($angle)<0)?-1:1;
00725                                 $len1 = $sign*$factor*$straightBB[0];
00726                                 $len2= $sign*$BB[0];
00727                                 $result[0] = $w-ceil($len2*$factor+(1-$factor)*$len1);
00728 
00729                                 $factor=abs(sin($angle));
00730                                 $sign=(sin($angle)<0)?-1:1;
00731                                 $len1= $sign*$factor*$straightBB[0];
00732                                 $len2= $sign*$BB[1];
00733                                 $result[1]=ceil($len2*$factor+(1-$factor)*$len1);
00734                         break;
00735                 }
00736                 switch($conf['align'])  {
00737                         case 'right':
00738                         break;
00739                         case 'center':
00740                                 $result[0] = round(($result[0])/2);
00741                                 $result[1] = round(($result[1])/2);
00742                         break;
00743                         default:
00744                                 $result[0]=0;
00745                                 $result[1]=0;
00746                         break;
00747                 }
00748                 $result = $this->applyOffset($result,t3lib_div::intExplode(',',$conf['offset']));
00749                 $result = $this->applyOffset($result,$workArea);
00750                 return $result;
00751         }
00752 
00761         function calcBBox($conf)        {
00762                 $sF = $this->getTextScalFactor($conf);
00763                 list($spacing,$wordSpacing) = $this->calcWordSpacing($conf, $sF);
00764                 $theText = $this->recodeString($conf['text']);
00765 
00766                 $charInf = $this->ImageTTFBBoxWrapper($conf['fontSize'], $conf['angle'], $conf['fontFile'], $theText, $conf['splitRendering.'],$sF);
00767                 $theBBoxInfo = $charInf;
00768                 if ($conf['angle'])     {
00769                         $xArr = Array($charInf[0],$charInf[2],$charInf[4],$charInf[6]);
00770                         $yArr = Array($charInf[1],$charInf[3],$charInf[5],$charInf[7]);
00771                         $x=max($xArr)-min($xArr);
00772                         $y=max($yArr)-min($yArr);
00773                 } else {
00774                         $x = ($charInf[2]-$charInf[0]);
00775                         $y = ($charInf[1]-$charInf[7]);
00776                 }
00777                 if ($spacing || $wordSpacing)   {               // If any kind of spacing applys, we use this function:
00778                         $x=0;
00779                         if (!$spacing && $wordSpacing)  {
00780                                 $bits = explode(' ',$theText);
00781                                 while(list(,$word)=each($bits)) {
00782                                         $word.=' ';
00783                                         $wordInf = $this->ImageTTFBBoxWrapper($conf['fontSize'], $conf['angle'], $conf['fontFile'], $word, $conf['splitRendering.'],$sF);
00784                                         $wordW = ($wordInf[2]-$wordInf[0]);
00785                                         $x+=$wordW+$wordSpacing;
00786                                 }
00787                         } else {
00788                                 $utf8Chars = $this->singleChars($theText);
00789                                         // For each UTF-8 char, do:
00790                                 foreach($utf8Chars as $char)    {
00791                                         $charInf = $this->ImageTTFBBoxWrapper($conf['fontSize'], $conf['angle'], $conf['fontFile'], $char, $conf['splitRendering.'],$sF);
00792                                         $charW = ($charInf[2]-$charInf[0]);
00793                                         $x+=$charW+(($char==' ')?$wordSpacing:$spacing);
00794                                 }
00795                         }
00796                 }
00797 
00798                 if ($sF>1) {
00799                         $x = ceil($x/$sF);
00800                         $y = ceil($y/$sF);
00801                         if (is_array($theBBoxInfo))     {
00802                                 reset($theBBoxInfo);
00803                                 while(list($key,$val)=each($theBBoxInfo))       {
00804                                         $theBBoxInfo[$key]=ceil($theBBoxInfo[$key]/$sF);
00805                                 }
00806                         }
00807                 }
00808                 return array($x,$y,$theBBoxInfo);
00809         }
00810 
00820         function addToMap($cords,$conf) {
00821                 $JS = $conf['noBlur'] ? '' : ' onfocus="blurLink(this);"';
00822 
00823                 $this->map.='<area'.
00824                                 ' shape="poly"'.
00825                                 ' coords="'.implode(',',$cords).'"'.
00826                                 ' href="'.htmlspecialchars($conf['url']).'"'.
00827                                 ($conf['target'] ? ' target="'.htmlspecialchars($conf['target']).'"' : '').
00828                                 $JS.
00829                                 (strlen($conf['titleText']) ? ' title="'.htmlspecialchars($conf['titleText']).'"' : '').
00830                                 ' alt="'.htmlspecialchars($conf['altText']).'" />';
00831         }
00832 
00843         function calcTextCordsForMap($cords,$offset, $conf)     {
00844                 $pars = t3lib_div::intExplode(',',$conf['explode'].',');
00845 
00846                 $newCords[0] = $cords[0]+$offset[0]-$pars[0];
00847                 $newCords[1] = $cords[1]+$offset[1]+$pars[1];
00848                 $newCords[2] = $cords[2]+$offset[0]+$pars[0];
00849                 $newCords[3] = $cords[3]+$offset[1]+$pars[1];
00850                 $newCords[4] = $cords[4]+$offset[0]+$pars[0];
00851                 $newCords[5] = $cords[5]+$offset[1]-$pars[1];
00852                 $newCords[6] = $cords[6]+$offset[0]-$pars[0];
00853                 $newCords[7] = $cords[7]+$offset[1]-$pars[1];
00854 
00855                 return $newCords;
00856         }
00857 
00878         function SpacedImageTTFText(&$im, $fontSize, $angle, $x, $y, $Fcolor, $fontFile, $text, $spacing, $wordSpacing, $splitRenderingConf, $sF=1)     {
00879 
00880                 $spacing*=$sF;
00881                 $wordSpacing*=$sF;
00882 
00883                 if (!$spacing && $wordSpacing)  {
00884                         $bits = explode(' ',$text);
00885                         reset($bits);
00886                         while(list(,$word)=each($bits)) {
00887                                 $word.=' ';
00888                                 $word = $word;
00889                                 $wordInf = $this->ImageTTFBBoxWrapper($fontSize, $angle, $fontFile, $word, $splitRenderingConf ,$sF);
00890                                 $wordW = ($wordInf[2]-$wordInf[0]);
00891                                 $this->ImageTTFTextWrapper($im, $fontSize, $angle, $x, $y, $Fcolor, $fontFile, $word, $splitRenderingConf, $sF);
00892                                 $x+=$wordW+$wordSpacing;
00893                         }
00894                 } else {
00895                         $utf8Chars = $this->singleChars($text);
00896                                 // For each UTF-8 char, do:
00897                         foreach($utf8Chars as $char)    {
00898                                 $charInf = $this->ImageTTFBBoxWrapper($fontSize, $angle, $fontFile, $char, $splitRenderingConf, $sF);
00899                                 $charW = ($charInf[2]-$charInf[0]);
00900                                 $this->ImageTTFTextWrapper($im, $fontSize, $angle, $x, $y, $Fcolor, $fontFile, $char, $splitRenderingConf, $sF);
00901                                 $x+=$charW+(($char==' ')?$wordSpacing:$spacing);
00902                         }
00903                 }
00904         }
00905 
00915         function fontResize($conf) {
00916                 // you have to use +calc options like [10.h] in 'offset' to get the right position of your text-image, if you use +calc in XY height!!!!
00917                 $maxWidth = intval($conf['maxWidth']);
00918                 list($spacing,$wordSpacing) = $this->calcWordSpacing($conf);
00919                 if ($maxWidth)  {
00920                         if ($spacing || $wordSpacing)   {               // If any kind of spacing applys, we use this function:
00921                                 return $conf['fontSize'];
00922                                 //  ################ no calc for spacing yet !!!!!!
00923                         } else {
00924                                 do {
00925                                                 // determine bounding box.
00926                                         $bounds = $this->ImageTTFBBoxWrapper($conf['fontSize'], $conf['angle'], $conf['fontFile'], $this->recodeString($conf['text']), $conf['splitRendering.']);
00927                                         if ($conf['angle']< 0) {
00928                                                 $pixelWidth = abs($bounds[4]-$bounds[0]);
00929                                         } elseif ($conf['angle'] > 0) {
00930                                                 $pixelWidth = abs($bounds[2]-$bounds[6]);
00931                                         } else {
00932                                                 $pixelWidth = abs($bounds[4]-$bounds[6]);
00933                                         }
00934 
00935                                                 // Size is fine, exit:
00936                                         if ($pixelWidth <= $maxWidth)   {
00937                                                 break;
00938                                         } else {
00939                                                 $conf['fontSize']--;
00940                                         }
00941                                 } while ($conf['fontSize']>1);
00942                         }//if spacing
00943                 }
00944                 return $conf['fontSize'];
00945         }
00946 
00958         function ImageTTFBBoxWrapper($fontSize, $angle, $fontFile, $string, $splitRendering, $sF=1)     {
00959 
00960                         // Initialize:
00961                 $offsetInfo = array();
00962                 $stringParts = $this->splitString($string,$splitRendering,$fontSize,$fontFile);
00963 
00964                         // Traverse string parts:
00965                 foreach($stringParts as $strCfg)        {
00966                         $fontFile = t3lib_stdGraphic::prependAbsolutePath($strCfg['fontFile']);
00967                         if (is_readable($fontFile)) {
00968 
00969                                         // Calculate Bounding Box for part:
00970                                 $calc = ImageTTFBBox(t3lib_div::freetypeDpiComp($sF*$strCfg['fontSize']), $angle, $fontFile, $strCfg['str']);
00971 
00972                                         // Calculate offsets:
00973                                 if (!count($offsetInfo))        {
00974                                         $offsetInfo = $calc;    // First run, just copy over.
00975                                 } else {
00976                                         $offsetInfo[2]+=$calc[2]-$calc[0]+intval($splitRendering['compX'])+intval($strCfg['xSpaceBefore'])+intval($strCfg['xSpaceAfter']);
00977                                         $offsetInfo[3]+=$calc[3]-$calc[1]-intval($splitRendering['compY'])-intval($strCfg['ySpaceBefore'])-intval($strCfg['ySpaceAfter']);
00978                                         $offsetInfo[4]+=$calc[4]-$calc[6]+intval($splitRendering['compX'])+intval($strCfg['xSpaceBefore'])+intval($strCfg['xSpaceAfter']);
00979                                         $offsetInfo[5]+=$calc[5]-$calc[7]-intval($splitRendering['compY'])-intval($strCfg['ySpaceBefore'])-intval($strCfg['ySpaceAfter']);
00980                                 }
00981 
00982                         } else {
00983                                 debug('cannot read file: '.$fontFile, 't3lib_stdGraphic::ImageTTFBBoxWrapper()');
00984                         }
00985                 }
00986 
00987                 return $offsetInfo;
00988         }
00989 
01005         function ImageTTFTextWrapper($im, $fontSize, $angle, $x, $y, $color, $fontFile, $string, $splitRendering,$sF=1) {
01006 
01007                         // Initialize:
01008                 $stringParts = $this->splitString($string,$splitRendering,$fontSize,$fontFile);
01009                 $x = ceil($sF*$x);
01010                 $y = ceil($sF*$y);
01011 
01012                         // Traverse string parts:
01013                 foreach($stringParts as $i => $strCfg)  {
01014 
01015                                 // Initialize:
01016                         $colorIndex = $color;
01017 
01018                                 // Set custom color if any (only when niceText is off):
01019                         if ($strCfg['color'] && $sF==1) {
01020                                 $cols = $this->convertColor($strCfg['color']);
01021                                 $colorIndex = ImageColorAllocate($im, $cols[0],$cols[1],$cols[2]);
01022                                 $colorIndex = $color >= 0 ? $colorIndex : -$colorIndex;
01023                         }
01024 
01025                                 // Setting xSpaceBefore
01026                         if ($i) {
01027                                 $x+= intval($strCfg['xSpaceBefore']);
01028                                 $y-= intval($strCfg['ySpaceBefore']);
01029                         }
01030 
01031                         $fontFile = t3lib_stdGraphic::prependAbsolutePath($strCfg['fontFile']);
01032                         if (is_readable($fontFile)) {
01033 
01034                                         // Render part:
01035                                 ImageTTFText($im, t3lib_div::freetypeDpiComp($sF*$strCfg['fontSize']), $angle, $x, $y, $colorIndex, $fontFile, $strCfg['str']);
01036 
01037                                         // Calculate offset to apply:
01038                                 $wordInf = ImageTTFBBox(t3lib_div::freetypeDpiComp($sF*$strCfg['fontSize']), $angle, t3lib_stdGraphic::prependAbsolutePath($strCfg['fontFile']), $strCfg['str']);
01039                                 $x+= $wordInf[2]-$wordInf[0]+intval($splitRendering['compX'])+intval($strCfg['xSpaceAfter']);
01040                                 $y+= $wordInf[5]-$wordInf[7]-intval($splitRendering['compY'])-intval($strCfg['ySpaceAfter']);
01041 
01042                         } else {
01043                                 debug('cannot read file: '.$fontFile, 't3lib_stdGraphic::ImageTTFTextWrapper()');
01044                         }
01045 
01046                 }
01047         }
01048 
01058         function splitString($string,$splitRendering,$fontSize,$fontFile)       {
01059 
01060                         // Initialize by setting the whole string and default configuration as the first entry.
01061                 $result = array();
01062                 $result[] = array(
01063                         'str' => $string,
01064                         'fontSize' => $fontSize,
01065                         'fontFile' => $fontFile
01066                 );
01067 
01068                         // Traverse the split-rendering configuration:
01069                         // Splitting will create more entries in $result with individual configurations.
01070                 if (is_array($splitRendering))  {
01071                         $sKeyArray = t3lib_TStemplate::sortedKeyList($splitRendering);
01072 
01073                                 // Traverse configured options:
01074                         foreach($sKeyArray as $key)     {
01075                                 $cfg = $splitRendering[$key.'.'];
01076 
01077                                         // Process each type of split rendering keyword:
01078                                 switch((string)$splitRendering[$key])   {
01079                                         case 'highlightWord':
01080                                                 if (strlen($cfg['value']))      {
01081                                                         $newResult = array();
01082 
01083                                                                 // Traverse the current parts of the result array:
01084                                                         foreach($result as $part)       {
01085                                                                         // Explode the string value by the word value to highlight:
01086                                                                 $explodedParts = explode($cfg['value'],$part['str']);
01087                                                                 foreach($explodedParts as $c => $expValue)      {
01088                                                                         if (strlen($expValue))  {
01089                                                                                 $newResult[] = array_merge($part,array('str' => $expValue));
01090                                                                         }
01091                                                                         if ($c+1 < count($explodedParts))       {
01092                                                                                 $newResult[] = array(
01093                                                                                         'str' => $cfg['value'],
01094                                                                                         'fontSize' => $cfg['fontSize'] ? $cfg['fontSize'] : $part['fontSize'],
01095                                                                                         'fontFile' => $cfg['fontFile'] ? $cfg['fontFile'] : $part['fontFile'],
01096                                                                                         'color' => $cfg['color'],
01097                                                                                         'xSpaceBefore' => $cfg['xSpaceBefore'],
01098                                                                                         'xSpaceAfter' => $cfg['xSpaceAfter'],
01099                                                                                         'ySpaceBefore' => $cfg['ySpaceBefore'],
01100                                                                                         'ySpaceAfter' => $cfg['ySpaceAfter'],
01101                                                                                 );
01102                                                                         }
01103                                                                 }
01104                                                         }
01105 
01106                                                                 // Set the new result as result array:
01107                                                         if (count($newResult))  {
01108                                                                 $result = $newResult;
01109                                                         }
01110                                                 }
01111                                         break;
01112                                         case 'charRange':
01113                                                 if (strlen($cfg['value']))      {
01114 
01115                                                                 // Initialize range:
01116                                                         $ranges = t3lib_div::trimExplode(',',$cfg['value'],1);
01117                                                         foreach($ranges as $i => $rangeDef)     {
01118                                                                 $ranges[$i] = t3lib_div::intExplode('-',$ranges[$i]);
01119                                                                 if (!isset($ranges[$i][1]))     $ranges[$i][1] = $ranges[$i][0];
01120                                                         }
01121                                                         $newResult = array();
01122 
01123                                                                 // Traverse the current parts of the result array:
01124                                                         foreach($result as $part)       {
01125 
01126                                                                         // Initialize:
01127                                                                 $currentState = -1;
01128                                                                 $bankAccum = '';
01129 
01130                                                                         // Explode the string value by the word value to highlight:
01131                                                                 $utf8Chars = $this->singleChars($part['str']);
01132                                                                 foreach($utf8Chars as $utfChar) {
01133 
01134                                                                                 // Find number and evaluate position:
01135                                                                         $uNumber = $this->csConvObj->utf8CharToUnumber($utfChar);
01136                                                                         $inRange = 0;
01137                                                                         foreach($ranges as $rangeDef)   {
01138                                                                                 if ($uNumber >= $rangeDef[0] && (!$rangeDef[1] || $uNumber <= $rangeDef[1])) {
01139                                                                                         $inRange = 1;
01140                                                                                         break;
01141                                                                                 }
01142                                                                         }
01143                                                                         if ($currentState==-1)  $currentState = $inRange;       // Initialize first char
01144 
01145                                                                                 // Switch bank:
01146                                                                         if ($inRange != $currentState && !t3lib_div::inList('32,10,13,9',$uNumber))     {
01147 
01148                                                                                         // Set result:
01149                                                                                 if (strlen($bankAccum)) {
01150                                                                                         $newResult[] = array(
01151                                                                                                 'str' => $bankAccum,
01152                                                                                                 'fontSize' => $currentState && $cfg['fontSize'] ? $cfg['fontSize'] : $part['fontSize'],
01153                                                                                                 'fontFile' => $currentState && $cfg['fontFile'] ? $cfg['fontFile'] : $part['fontFile'],
01154                                                                                                 'color' => $currentState ? $cfg['color'] : '',
01155                                                                                                 'xSpaceBefore' => $currentState ? $cfg['xSpaceBefore'] : '',
01156                                                                                                 'xSpaceAfter' => $currentState ? $cfg['xSpaceAfter'] : '',
01157                                                                                                 'ySpaceBefore' => $currentState ? $cfg['ySpaceBefore'] : '',
01158                                                                                                 'ySpaceAfter' => $currentState ? $cfg['ySpaceAfter'] : '',
01159                                                                                         );
01160                                                                                 }
01161 
01162                                                                                         // Initialize new settings:
01163                                                                                 $currentState = $inRange;
01164                                                                                 $bankAccum = '';
01165                                                                         }
01166 
01167                                                                                 // Add char to bank:
01168                                                                         $bankAccum.=$utfChar;
01169                                                                 }
01170 
01171                                                                         // Set result for FINAL part:
01172                                                                 if (strlen($bankAccum)) {
01173                                                                         $newResult[] = array(
01174                                                                                 'str' => $bankAccum,
01175                                                                                 'fontSize' => $currentState && $cfg['fontSize'] ? $cfg['fontSize'] : $part['fontSize'],
01176                                                                                 'fontFile' => $currentState && $cfg['fontFile'] ? $cfg['fontFile'] : $part['fontFile'],
01177                                                                                 'color' => $currentState ? $cfg['color'] : '',
01178                                                                                 'xSpaceBefore' => $currentState ? $cfg['xSpaceBefore'] : '',
01179                                                                                 'xSpaceAfter' => $currentState ? $cfg['xSpaceAfter'] : '',
01180                                                                                 'ySpaceBefore' => $currentState ? $cfg['ySpaceBefore'] : '',
01181                                                                                 'ySpaceAfter' => $currentState ? $cfg['ySpaceAfter'] : '',
01182                                                                         );
01183                                                                 }
01184                                                         }
01185 
01186                                                                 // Set the new result as result array:
01187                                                         if (count($newResult))  {
01188                                                                 $result = $newResult;
01189                                                         }
01190                                                 }
01191                                         break;
01192                                 }
01193                         }
01194                 }
01195 
01196                 return $result;
01197         }
01198 
01208         function calcWordSpacing($conf, $scaleFactor=1) {
01209 
01210                 $spacing = intval($conf['spacing']);
01211                 $wordSpacing = intval($conf['wordSpacing']);
01212                 $wordSpacing = $wordSpacing?$wordSpacing:$spacing*2;
01213 
01214                 $spacing*=$scaleFactor;
01215                 $wordSpacing*=$scaleFactor;
01216 
01217                 return array($spacing,$wordSpacing);
01218         }
01219 
01227         function getTextScalFactor($conf) {
01228                 if (!$conf['niceText']) {
01229                         $sF = 1;
01230                 } else {                // NICETEXT::
01231                         $sF = t3lib_div::intInRange($conf['niceText.']['scaleFactor'],2,5);
01232                 }
01233                 return $sF;
01234         }
01235 
01236 
01237 
01238 
01239 
01240 
01241 
01242 
01243 
01244 
01245 
01246         /*********************************************
01247          *
01248          * Other GIFBUILDER objects related to TEXT
01249          *
01250          *********************************************/
01251 
01262         function makeOutline(&$im,$conf,$workArea,$txtConf)     {
01263                 $thickness = intval($conf['thickness']);
01264                 if ($thickness) {
01265                         $txtConf['fontColor'] = $conf['color'];
01266                         $outLineDist = t3lib_div::intInRange($thickness,1,2);
01267                         for ($b=1;$b<=$outLineDist;$b++)        {
01268                                 if ($b==1)      {
01269                                         $it = 8;
01270                                 } else {
01271                                         $it = 16;
01272                                 }
01273                                 $outL = $this->circleOffset($b, $it);
01274                                 for ($a=0;$a<$it;$a++)  {
01275                                         $this->makeText($im,$txtConf,$this->applyOffset($workArea,$outL[$a]));
01276                                 }
01277                         }
01278                 }
01279         }
01280 
01291         function circleOffset($distance, $iterations)   {
01292                 $res = Array();
01293                 if ($distance && $iterations)   {
01294                         for ($a=0;$a<$iterations;$a++)  {
01295                                 $yOff = round(sin(2*pi()/$iterations*($a+1))*100*$distance);
01296                                 if ($yOff)      {$yOff = intval(ceil(abs($yOff/100))*($yOff/abs($yOff)));}
01297                                 $xOff = round(cos(2*pi()/$iterations*($a+1))*100*$distance);
01298                                 if ($xOff)      {$xOff = intval(ceil(abs($xOff/100))*($xOff/abs($xOff)));}
01299                                 $res[$a] = Array($xOff,$yOff);
01300                         }
01301                 }
01302                 return $res;
01303         }
01304 
01315         function makeEmboss(&$im,$conf,$workArea,$txtConf)      {
01316                 $conf['color']=$conf['highColor'];
01317                 $this->makeShadow($im,$conf,$workArea,$txtConf);
01318                 $newOffset = t3lib_div::intExplode(',',$conf['offset']);
01319                 $newOffset[0]*=-1;
01320                 $newOffset[1]*=-1;
01321                 $conf['offset']=implode(',',$newOffset);
01322                 $conf['color']=$conf['lowColor'];
01323                 $this->makeShadow($im,$conf,$workArea,$txtConf);
01324         }
01325 
01337         function makeShadow(&$im,$conf,$workArea,$txtConf)      {
01338                 $workArea = $this->applyOffset($workArea,t3lib_div::intExplode(',',$conf['offset']));
01339                 $blurRate = t3lib_div::intInRange(intval($conf['blur']),0,99);
01340 
01341                 if (!$blurRate || $this->NO_IM_EFFECTS) {               // No effects if ImageMagick ver. 5+
01342                         $txtConf['fontColor'] = $conf['color'];
01343                         $this->makeText($im,$txtConf,$workArea);
01344                 } else {
01345                         $w = imagesx($im);
01346                         $h = imagesy($im);
01347                         $blurBorder= 3; // area around the blur used for cropping something
01348                         $tmpStr = $this->randomName();
01349                         $fileMenu = $tmpStr.'_menu.'.$this->gifExtension;
01350                         $fileColor = $tmpStr.'_color.'.$this->gifExtension;
01351                         $fileMask = $tmpStr.'_mask.'.$this->gifExtension;
01352 
01353                                 // BlurColor Image laves
01354                         $blurColImg = $this->imagecreate($w,$h);
01355                         $bcols=$this->convertColor($conf['color']);
01356                         $Bcolor = ImageColorAllocate($blurColImg, $bcols[0],$bcols[1],$bcols[2]);
01357                         ImageFilledRectangle($blurColImg, 0, 0, $w, $h, $Bcolor);
01358                         $this->ImageWrite($blurColImg, $fileColor);
01359                         ImageDestroy($blurColImg);
01360 
01361                                 // The mask is made: BlurTextImage
01362                         $blurTextImg = $this->imagecreate($w+$blurBorder*2,$h+$blurBorder*2);
01363                         $Bcolor = ImageColorAllocate($blurTextImg, 0,0,0);              // black background
01364                         ImageFilledRectangle($blurTextImg, 0, 0, $w+$blurBorder*2, $h+$blurBorder*2, $Bcolor);
01365                         $txtConf['fontColor'] = 'white';
01366                         $blurBordArr = Array($blurBorder,$blurBorder);
01367                         $this->makeText($blurTextImg,$txtConf,  $this->applyOffset($workArea,$blurBordArr));
01368                         $this->ImageWrite($blurTextImg, $fileMask);     // dump to temporary file
01369                         ImageDestroy($blurTextImg);     // destroy
01370 
01371 
01372                         $command='';
01373                         $command.=$this->maskNegate;
01374 
01375                         if ($this->V5_EFFECTS)  {
01376                                 $command.=$this->v5_blur($blurRate+1);
01377                         } else {
01378                                         // Blurring of the mask
01379                                 $times = ceil($blurRate/10);    // How many blur-commands that is executed. Min = 1;
01380                                 $newBlurRate = $blurRate*4;             // Here I boost the blur-rate so that it is 100 already at 25. The rest is done by up to 99 iterations of the blur-command.
01381                                 $newBlurRate = t3lib_div::intInRange($newBlurRate,1,99);
01382                                 for ($a=0;$a<$times;$a++)       {               // Building blur-command
01383                                         $command.=' -blur '.$blurRate;
01384                                 }
01385                         }
01386 
01387                         $this->imageMagickExec($fileMask,$fileMask,$command.' +matte');
01388 
01389                         $blurTextImg_tmp = $this->imageCreateFromFile($fileMask);       // the mask is loaded again
01390                         if ($blurTextImg_tmp)   {       // if nothing went wrong we continue with the blurred mask
01391 
01392                                         // cropping the border from the mask
01393                                 $blurTextImg = $this->imagecreate($w,$h);
01394                                 $this->imagecopyresized($blurTextImg, $blurTextImg_tmp, 0, 0, $blurBorder, $blurBorder, $w, $h, $w, $h);
01395                                 ImageDestroy($blurTextImg_tmp); // Destroy the temporary mask
01396 
01397                                         // adjust the mask
01398                                 $intensity = 40;
01399                                 if ($conf['intensity']) {
01400                                         $intensity = t3lib_div::intInRange($conf['intensity'],0,100);
01401                                 }
01402                                 $intensity = ceil(255-($intensity/100*255));
01403                                 $this->inputLevels($blurTextImg,0,$intensity,$this->maskNegate);
01404 
01405                                 $opacity = t3lib_div::intInRange(intval($conf['opacity']),0,100);
01406                                 if ($opacity && $opacity<100)   {
01407                                         $high = ceil(255*$opacity/100);
01408                                         $this->outputLevels($blurTextImg,0,$high,$this->maskNegate);    // reducing levels as the opacity demands
01409                                 }
01410 
01411                                 $this->ImageWrite($blurTextImg, $fileMask);     // Dump the mask again
01412                                 ImageDestroy($blurTextImg);     // Destroy the mask
01413 
01414                                         // The pictures are combined
01415                                 $this->ImageWrite($im, $fileMenu);      // The main pictures is saved temporarily
01416 
01417                                 $this->combineExec($fileMenu,$fileColor,$fileMask,$fileMenu);
01418 
01419                                 $backIm = $this->imageCreateFromFile($fileMenu);        // The main image is loaded again...
01420                                 if ($backIm)    {       // ... and if nothing went wrong we load it onto the old one.
01421                                         ImageColorTransparent($backIm,-1);
01422                                         $im = $backIm;
01423                                 }
01424                         }
01425                                 // Deleting temporary files;
01426                         if (!$this->dontUnlinkTempFiles)        {
01427                                 unlink($fileMenu);
01428                                 unlink($fileColor);
01429                                 unlink($fileMask);
01430                         }
01431                 }
01432         }
01433 
01434 
01435 
01436 
01437 
01438 
01439 
01440 
01441 
01442 
01443 
01444 
01445 
01446 
01447 
01448 
01449 
01450 
01451 
01452 
01453 
01454         /****************************
01455          *
01456          * Other GIFBUILDER objects
01457          *
01458          ****************************/
01459 
01469         function makeBox(&$im,$conf,$workArea)  {
01470                 $cords = t3lib_div::intExplode(',',$conf['dimensions'].',,,');
01471                 $conf['offset']=$cords[0].','.$cords[1];
01472                 $cords = $this->objPosition($conf,$workArea,Array($cords[2],$cords[3]));
01473                 $cols=$this->convertColor($conf['color']);
01474                 if (!$this->truecolor)  {
01475                         $reduce = t3lib_div::intInRange($this->setup['reduceColors'], 256, $this->truecolorColors, 256);
01476                         $this->reduceColors($im, $reduce-1, $reduce-2); // If "reduce-1" colors (or more) are used reduce them to "reduce-2"
01477                 }
01478                 $tmpColor = ImageColorAllocate($im, $cols[0],$cols[1],$cols[2]);
01479                 imagefilledrectangle($im, $cords[0], $cords[1], $cords[0]+$cords[2]-1, $cords[1]+$cords[3]-1, $tmpColor);
01480         }
01481 
01491         function makeEffect(&$im, $conf)        {
01492                 $commands = $this->IMparams($conf['value']);
01493                 if ($commands)  {
01494                         $this->applyImageMagickToPHPGif($im, $commands);
01495                 }
01496         }
01497 
01506         function IMparams($setup)       {
01507                 if (!trim($setup)){return '';}
01508                 $effects = explode('|', $setup);
01509                 $commands = '';
01510                 while(list(,$val)=each($effects))       {
01511                         $pairs=explode('=',$val,2);
01512                         $value = trim($pairs[1]);
01513                         $effect = strtolower(trim($pairs[0]));
01514                         switch($effect) {
01515                                 case 'gamma':
01516                                         $commands.=' -gamma '.doubleval($value);
01517                                 break;
01518                                 case 'blur':
01519                                         if (!$this->NO_IM_EFFECTS)      {
01520                                                 if ($this->V5_EFFECTS)  {
01521                                                         $commands.=$this->v5_blur($value);
01522                                                 } else {
01523                                                         $commands.=' -blur '.t3lib_div::intInRange($value,1,99);
01524                                                 }
01525                                         }
01526                                 break;
01527                                 case 'sharpen':
01528                                         if (!$this->NO_IM_EFFECTS)      {
01529                                                 if ($this->V5_EFFECTS)  {
01530                                                         $commands.=$this->v5_sharpen($value);
01531                                                 } else {
01532                                                         $commands.=' -sharpen '.t3lib_div::intInRange($value,1,99);
01533                                                 }
01534                                         }
01535                                 break;
01536                                 case 'rotate':
01537                                         $commands.=' -rotate '.t3lib_div::intInRange($value,0,360);
01538                                 break;
01539                                 case 'solarize':
01540                                         $commands.=' -solarize '.t3lib_div::intInRange($value,0,99);
01541                                 break;
01542                                 case 'swirl':
01543                                         $commands.=' -swirl '.t3lib_div::intInRange($value,0,1000);
01544                                 break;
01545                                 case 'wave':
01546                                         $params = t3lib_div::intExplode(',',$value);
01547                                         $commands.=' -wave '.t3lib_div::intInRange($params[0],0,99).'x'.t3lib_div::intInRange($params[1],0,99);
01548                                 break;
01549                                 case 'charcoal':
01550                                         $commands.=' -charcoal '.t3lib_div::intInRange($value,0,100);
01551                                 break;
01552                                 case 'gray':
01553                                         $commands.=' -colorspace GRAY';
01554                                 break;
01555                                 case 'edge':
01556                                         $commands.=' -edge '.t3lib_div::intInRange($value,0,99);
01557                                 break;
01558                                 case 'emboss':
01559                                         $commands.=' -emboss';
01560                                 break;
01561                                 case 'flip':
01562                                         $commands.=' -flip';
01563                                 break;
01564                                 case 'flop':
01565                                         $commands.=' -flop';
01566                                 break;
01567                                 case 'colors':
01568                                         $commands.=' -colors '.t3lib_div::intInRange($value,2,255);
01569                                 break;
01570                                 case 'shear':
01571                                         $commands.=' -shear '.t3lib_div::intInRange($value,-90,90);
01572                                 break;
01573                                 case 'invert':
01574                                         $commands.=' -negate';
01575                                 break;
01576                         }
01577                 }
01578                 return $commands;
01579         }
01580 
01589         function adjust(&$im, $conf)    {
01590                 $setup = $conf['value'];
01591                 if (!trim($setup)){return '';}
01592                 $effects = explode('|', $setup);
01593                 while(list(,$val)=each($effects))       {
01594                         $pairs=explode('=',$val,2);
01595                         $value = trim($pairs[1]);
01596                         $effect = strtolower(trim($pairs[0]));
01597                         switch($effect) {
01598                                 case 'inputlevels':     // low,high
01599                                         $params = t3lib_div::intExplode(',',$value);
01600                                         $this->inputLevels($im,$params[0],$params[1]);
01601                                 break;
01602                                 case 'outputlevels':
01603                                         $params = t3lib_div::intExplode(',',$value);
01604                                         $this->outputLevels($im,$params[0],$params[1]);
01605                                 break;
01606                                 case 'autolevels':
01607                                         $this->autoLevels($im);
01608                                 break;
01609                         }
01610                 }
01611         }
01612 
01621         function crop(&$im,$conf)       {
01622                 $this->setWorkArea(''); // clears workArea to total image
01623                 $cords = t3lib_div::intExplode(',',$conf['crop'].',,,');
01624                 $conf['offset']=$cords[0].','.$cords[1];
01625                 $cords = $this->objPosition($conf,$this->workArea,Array($cords[2],$cords[3]));
01626 
01627                 $newIm = $this->imagecreate($cords[2],$cords[3]);
01628                 $cols=$this->convertColor($conf['backColor']?$conf['backColor']:$this->setup['backColor']);
01629                 $Bcolor = ImageColorAllocate($newIm, $cols[0],$cols[1],$cols[2]);
01630                 ImageFilledRectangle($newIm, 0, 0, $cords[2], $cords[3], $Bcolor);
01631 
01632                 $newConf = Array();
01633                 $workArea = Array(0,0,$cords[2],$cords[3]);
01634                 if ($cords[0]<0) {$workArea[0]=abs($cords[0]);} else {$newConf['offset']=-$cords[0];}
01635                 if ($cords[1]<0) {$workArea[1]=abs($cords[1]);} else {$newConf['offset'].=','.-$cords[1];}
01636 
01637                 $this->copyGifOntoGif($newIm,$im,$newConf,$workArea);
01638                 $im = $newIm;
01639                 $this->w = imagesx($im);
01640                 $this->h = imagesy($im);
01641                 $this->setWorkArea(''); // clears workArea to total image
01642         }
01643 
01652         function scale(&$im,$conf)      {
01653                 if ($conf['width'] || $conf['height'] || $conf['params'])       {
01654                         $tmpStr = $this->randomName();
01655                         $theFile = $tmpStr.'.'.$this->gifExtension;
01656                         $this->ImageWrite($im, $theFile);
01657                         $theNewFile = $this->imageMagickConvert($theFile,$this->gifExtension,$conf['width'],$conf['height'],$conf['params'],'','');
01658                         $tmpImg = $this->imageCreateFromFile($theNewFile[3]);
01659                         if ($tmpImg)    {
01660                                 ImageDestroy($im);
01661                                 $im = $tmpImg;
01662                                 $this->w = imagesx($im);
01663                                 $this->h = imagesy($im);
01664                                 $this->setWorkArea(''); // clears workArea to total image
01665                         }
01666                         if (!$this->dontUnlinkTempFiles)        {
01667                                 unlink($theFile);
01668                                 if ($theNewFile[3] && $theNewFile[3]!=$theFile) {
01669                                         unlink($theNewFile[3]);
01670                                 }
01671                         }
01672                 }
01673         }
01674 
01684         function setWorkArea($workArea) {
01685                 $this->workArea = t3lib_div::intExplode(',',$workArea);
01686                 $this->workArea = $this->applyOffset($this->workArea,$this->OFFSET);
01687                 if (!$this->workArea[2])        {$this->workArea[2]=$this->w;}
01688                 if (!$this->workArea[3])        {$this->workArea[3]=$this->h;}
01689         }
01690 
01691 
01692 
01693 
01694 
01695 
01696 
01697 
01698 
01699 
01700 
01701 
01702 
01703 
01704 
01705 
01706 
01707 
01708 
01709 
01710 
01711 
01712 
01713         /*************************
01714          *
01715          * Adjustment functions
01716          *
01717          ************************/
01718 
01725         function autolevels(&$im)       {
01726                 $totalCols = ImageColorsTotal($im);
01727                 $min=255;
01728                 $max=0;
01729                 for ($c=0; $c<$totalCols; $c++) {
01730                         $cols = ImageColorsForIndex($im,$c);
01731                         $grayArr[] = round(($cols['red']+$cols['green']+$cols['blue'])/3);
01732                 }
01733                 $min=min($grayArr);
01734                 $max=max($grayArr);
01735                 $delta = $max-$min;
01736                 if ($delta)     {
01737                         for ($c=0; $c<$totalCols; $c++) {
01738                                 $cols = ImageColorsForIndex($im,$c);
01739                                 $cols['red'] = floor(($cols['red']-$min)/$delta*255);
01740                                 $cols['green'] = floor(($cols['green']-$min)/$delta*255);
01741                                 $cols['blue'] = floor(($cols['blue']-$min)/$delta*255);
01742                                 ImageColorSet($im,$c,$cols['red'],$cols['green'],$cols['blue']);
01743                         }
01744                 }
01745         }
01746 
01756         function outputLevels(&$im,$low,$high,$swap='') {
01757                 if ($low<$high){
01758                         $low = t3lib_div::intInRange($low,0,255);
01759                         $high = t3lib_div::intInRange($high,0,255);
01760 
01761                         if ($swap)      {
01762                                 $temp = $low;
01763                                 $low = 255-$high;
01764                                 $high = 255-$temp;
01765                         }
01766 
01767                         $delta = $high-$low;
01768                         $totalCols = ImageColorsTotal($im);
01769                         for ($c=0; $c<$totalCols; $c++) {
01770                                 $cols = ImageColorsForIndex($im,$c);
01771                                 $cols['red'] = $low+floor($cols['red']/255*$delta);
01772                                 $cols['green'] = $low+floor($cols['green']/255*$delta);
01773                                 $cols['blue'] = $low+floor($cols['blue']/255*$delta);
01774                                 ImageColorSet($im,$c,$cols['red'],$cols['green'],$cols['blue']);
01775                         }
01776                 }
01777         }
01778 
01788         function inputLevels(&$im,$low,$high,$swap='')  {
01789                 if ($low<$high){
01790                         $low = t3lib_div::intInRange($low,0,255);
01791                         $high = t3lib_div::intInRange($high,0,255);
01792 
01793                         if ($swap)      {
01794                                 $temp = $low;
01795                                 $low = 255-$high;
01796                                 $high = 255-$temp;
01797                         }
01798 
01799                         $delta = $high-$low;
01800                         $totalCols = ImageColorsTotal($im);
01801                         for ($c=0; $c<$totalCols; $c++) {
01802                                 $cols = ImageColorsForIndex($im,$c);
01803                                 $cols['red'] = t3lib_div::intInRange(($cols['red']-$low)/$delta*255, 0,255);
01804                                 $cols['green'] = t3lib_div::intInRange(($cols['green']-$low)/$delta*255, 0,255);
01805                                 $cols['blue'] = t3lib_div::intInRange(($cols['blue']-$low)/$delta*255, 0,255);
01806                                 ImageColorSet($im,$c,$cols['red'],$cols['green'],$cols['blue']);
01807                         }
01808                 }
01809         }
01810 
01819         function reduceColors(&$im,$limit, $cols)       {
01820                 if (!$this->truecolor && ImageColorsTotal($im)>=$limit) {
01821                         $this->makeEffect($im, Array('value'=>'colors='.$cols) );
01822                 }
01823         }
01824 
01832         function IMreduceColors($file, $cols)   {
01833                 $fI = t3lib_div::split_fileref($file);
01834                 $ext = strtolower($fI['fileext']);
01835                 $result = $this->randomName().'.'.$ext;
01836                 if (($reduce = t3lib_div::intInRange($cols, 0, ($ext=='gif'?256:$this->truecolorColors), 0))>0) {
01837                         $params = ' -colors '.$reduce;
01838                         if (!$this->im_version_4)       {
01839                                         // IM4 doesn't have this options but forces them automatically if applicaple (<256 colors in image)
01840                                 if ($reduce<=256)       { $params .= ' -type Palette'; }
01841                                 if ($ext=='png' && $reduce<=256)        { $prefix = 'png8:'; }
01842                         }
01843                         $this->imageMagickExec($file, $prefix.$result, $params);
01844                         if ($result)    {
01845                                 return $result;
01846                         }
01847                 }
01848                 return '';
01849         }
01850 
01851 
01852 
01853 
01854 
01855 
01856 
01857 
01858 
01859 
01860 
01861         /*********************************
01862          *
01863          * GIFBUILDER Helper functions
01864          *
01865          *********************************/
01866 
01875         function prependAbsolutePath($fontFile) {
01876                 $absPath = defined('PATH_typo3') ? dirname(PATH_thisScript).'/' :PATH_site;
01877                 $fontFile = t3lib_div::isAbsPath($fontFile) ? $fontFile : t3lib_div::resolveBackPath($absPath.$fontFile);
01878                 return $fontFile;
01879         }
01880 
01889         function v5_sharpen($factor)    {
01890                 $factor = t3lib_div::intInRange(ceil($factor/10),0,10);
01891 
01892                 $sharpenArr=explode(',',','.$this->im5fx_sharpenSteps);
01893                 $sharpenF= trim($sharpenArr[$factor]);
01894                 if ($sharpenF)  {
01895                         $cmd = ' -sharpen '.$sharpenF;
01896                         return $cmd;
01897                 }
01898         }
01899 
01908         function v5_blur($factor)       {
01909                 $factor = t3lib_div::intInRange(ceil($factor/10),0,10);
01910 
01911                 $blurArr=explode(',',','.$this->im5fx_blurSteps);
01912                 $blurF= trim($blurArr[$factor]);
01913                 if ($blurF)     {
01914                         $cmd=' -blur '.$blurF;
01915                         return $cmd;
01916                 }
01917         }
01918 
01925         function randomName()   {
01926                 $this->createTempSubDir('temp/');
01927                 return $this->tempPath.'temp/'.md5(uniqid(''));
01928         }
01929 
01938         function applyOffset($cords,$OFFSET)    {
01939                 $cords[0] = intval($cords[0])+intval($OFFSET[0]);
01940                 $cords[1] = intval($cords[1])+intval($OFFSET[1]);
01941                 return $cords;
01942         }
01943 
01951         function convertColor($string)  {
01952                 $col=array();
01953                 $cParts = explode(':',$string,2);
01954 
01955                         // Finding the RGB definitions of the color:
01956                 $string=$cParts[0];
01957                 if (strstr($string,'#'))        {
01958                         $string = ereg_replace('[^A-Fa-f0-9]*','',$string);
01959                         $col[]=HexDec(substr($string,0,2));
01960                         $col[]=HexDec(substr($string,2,2));
01961                         $col[]=HexDec(substr($string,4,2));
01962                 } elseif (strstr($string,','))  {
01963                         $string = ereg_replace('[^,0-9]*','',$string);
01964                         $strArr = explode(',',$string);
01965                         $col[]=intval($strArr[0]);
01966                         $col[]=intval($strArr[1]);
01967                         $col[]=intval($strArr[2]);
01968                 } else {
01969                         $string = strtolower(trim($string));
01970                         if ($this->colMap[$string])     {
01971                                 $col = $this->colMap[$string];
01972                         } else {
01973                                 $col = Array(0,0,0);
01974                         }
01975                 }
01976                         // ... and possibly recalculating the value
01977                 if (trim($cParts[1]))   {
01978                         $cParts[1]=trim($cParts[1]);
01979                         if (substr($cParts[1],0,1)=='*')        {
01980                                 $val=doubleval(substr($cParts[1],1));
01981                                 $col[0]=t3lib_div::intInRange($col[0]*$val,0,255);
01982                                 $col[1]=t3lib_div::intInRange($col[1]*$val,0,255);
01983                                 $col[2]=t3lib_div::intInRange($col[2]*$val,0,255);
01984                         } else {
01985                                 $val=intval($cParts[1]);
01986                                 $col[0]=t3lib_div::intInRange($col[0]+$val,0,255);
01987                                 $col[1]=t3lib_div::intInRange($col[1]+$val,0,255);
01988                                 $col[2]=t3lib_div::intInRange($col[2]+$val,0,255);
01989                         }
01990                 }
01991                 return $col;
01992         }
01993 
02001         function recodeString($string)  {
02002                         // Recode string to UTF-8 from $this->nativeCharset:
02003                 if ($this->nativeCharset && $this->nativeCharset!='utf-8')      {
02004                         $string = $this->csConvObj->utf8_encode($string,$this->nativeCharset);  // Convert to UTF-8
02005                 }
02006 
02007                         // Recode string accoding to TTFLocaleConv. Deprecated.
02008                 if ($this->TTFLocaleConv)       {
02009                         $string = recode_string($this->TTFLocaleConv,$string);
02010                 }
02011 
02012                 return $string;
02013         }
02014 
02023         function singleChars($theText,$returnUnicodeNumber=FALSE)       {
02024                 if ($this->nativeCharset)       {
02025                         return $this->csConvObj->utf8_to_numberarray($theText,1,$returnUnicodeNumber ? 0 : 1);  // Get an array of separated UTF-8 chars
02026                 } else {
02027                         $output=array();
02028                         $c=strlen($theText);
02029                         for($a=0;$a<$c;$a++)    {
02030                                 $output[]=substr($theText,$a,1);
02031                         }
02032                         return $output;
02033                 }
02034         }
02035 
02046         function objPosition($conf,$workArea,$BB) {
02047                         // offset, align, valign, workarea
02048                 $result=Array();
02049                 $result[2] = $BB[0];
02050                 $result[3] = $BB[1];
02051                 $w=$workArea[2];
02052                 $h=$workArea[3];
02053 
02054                 $align = explode(',',$conf['align']);
02055                 $align[0] = strtolower(substr(trim($align[0]),0,1));
02056                 $align[1] = strtolower(substr(trim($align[1]),0,1));
02057 
02058                 switch($align[0])       {
02059                         case 'r':
02060                                 $result[0]=$w-$result[2];
02061                         break;
02062                         case 'c':
02063                                 $result[0] = round(($w-$result[2])/2);
02064                         break;
02065                         default:
02066                                 $result[0] = 0;
02067                         break;
02068                 }
02069                 switch($align[1])       {
02070                         case 'b':
02071                                 $result[1] = $h-$result[3];     // y pos
02072                         break;
02073                         case 'c':
02074                                 $result[1] = round(($h-$result[3])/2);
02075                         break;
02076                         default:
02077                                 $result[1]=0;
02078                         break;
02079                 }
02080                 $result = $this->applyOffset($result,t3lib_div::intExplode(',',$conf['offset']));
02081                 $result = $this->applyOffset($result,$workArea);
02082                 return $result;
02083         }
02084 
02085 
02086 
02087 
02088 
02089 
02090 
02091 
02092 
02093 
02094 
02095 
02096 
02097 
02098 
02099 
02100 
02101 
02102 
02103 
02104 
02105         /***********************************
02106          *
02107          * Scaling, Dimensions of images
02108          *
02109          ***********************************/
02110 
02125         function imageMagickConvert($imagefile,$newExt='',$w='',$h='',$params='',$frame='',$options='',$mustCreate=0)   {
02126                 if ($this->NO_IMAGE_MAGICK)     {
02127                                 // Returning file info right away
02128                         return $this->getImageDimensions($imagefile);
02129                 }
02130 
02131                 if($info=$this->getImageDimensions($imagefile)) {
02132                         $newExt=strtolower(trim($newExt));
02133                         if (!$newExt)   {       // If no extension is given the original extension is used
02134                                 $newExt = $info[2];
02135                         }
02136                         if ($newExt=='web')     {
02137                                 if (t3lib_div::inList($this->webImageExt,$info[2]))     {
02138                                         $newExt = $info[2];
02139                                 } else {
02140                                         $newExt = $this->gif_or_jpg($info[2],$info[0],$info[1]);
02141                                         if (!$params)   {
02142                                                 $params = $this->cmds[$newExt];
02143                                         }
02144                                 }
02145                         }
02146                         if (t3lib_div::inList($this->imageFileExt,$newExt))     {
02147                                 if (strstr($w.$h, 'm')) {$max=1;} else {$max=0;}
02148 
02149                                 $data = $this->getImageScale($info,$w,$h,$options);
02150                                 $w=$data['origW'];
02151                                 $h=$data['origH'];
02152 
02153                                         // if no convertion should be performed
02154                                 $wh_noscale = (!$w && !$h) || ($data[0]==$info[0] && $data[1]==$info[1]);               // this flag is true if the width / height does NOT dictate the image to be scaled!! (that is if no w/h is given or if the destination w/h matches the original image-dimensions....
02155 
02156                                 if ($wh_noscale && !$data['crs'] && !$params && !$frame && $newExt==$info[2] && !$mustCreate) {
02157                                         $info[3] = $imagefile;
02158                                         return $info;
02159                                 }
02160                                 $info[0]=$data[0];
02161                                 $info[1]=$data[1];
02162 
02163                                 $frame = $this->noFramePrepended ? '' : '['.intval($frame).']';
02164 
02165                                 if (!$params)   {
02166                                         $params = $this->cmds[$newExt];
02167                                 }
02168 
02169                                 $command = $this->scalecmd.' '.$info[0].'x'.$info[1].'! '.$params.' ';
02170                                 $cropscale = ($data['crs'] ? 'crs-V'.$data['cropV'].'H'.$data['cropH'] : '');
02171 
02172                                 if ($this->alternativeOutputKey)        {
02173                                         $theOutputName = t3lib_div::shortMD5($command.$cropscale.basename($imagefile).$this->alternativeOutputKey.$frame);
02174                                 } else {
02175                                         $theOutputName = t3lib_div::shortMD5($command.$cropscale.$imagefile.filemtime($imagefile).$frame);
02176                                 }
02177                                 if ($this->imageMagickConvert_forceFileNameBody)        {
02178                                         $theOutputName = $this->imageMagickConvert_forceFileNameBody;
02179                                         $this->imageMagickConvert_forceFileNameBody='';
02180                                 }
02181 
02182                                         // Making the temporary filename:
02183                                 $this->createTempSubDir('pics/');
02184                                 $output = $this->absPrefix.$this->tempPath.'pics/'.$this->filenamePrefix.$theOutputName.'.'.$newExt;
02185 
02186                                         // Register temporary filename:
02187                                 $GLOBALS['TEMP_IMAGES_ON_PAGE'][] = $output;
02188 
02189                                         // Cropscaling:
02190                                 if ($data['crs'])       {
02191                                         if ($this->dontCheckForExistingTempFile || !$this->file_exists_typo3temp_file($output, $imagefile))     {
02192                                                 $crsOutput = str_replace('pics/', 'pics/crs-', $output);
02193                                                 $this->imageMagickExec($imagefile.$frame, $crsOutput, $command);
02194                                                 $gifCreator = t3lib_div::makeInstance('tslib_gifbuilder');
02195                                                 $gifCreator->init();
02196                                                 if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib'] !== 0)  {
02197                                                         if (!$data['origW']) { $data['origW'] = $data[0]; }
02198                                                         if (!$data['origH']) { $data['origH'] = $data[1]; }
02199                                                         $ofX = intval(($data['origW'] - $data[0]) * ($data['cropH']+100)/200);
02200                                                         $ofY = intval(($data['origH'] - $data[1]) * ($data['cropV']+100)/200);
02201                                                         $tmpParm = Array('XY' => intval($data['origW']).','.intval($data['origH']),
02202                                                                         '10' => 'IMAGE',
02203                                                                         '10.' => array('file'=> $crsOutput, 'offset'=> $ofX.','.$ofY),
02204                                                         );
02205                                                         $gifCreator->start($tmpParm, array());
02206                                                         $newoutput = $gifCreator->gifBuild();
02207                                                         if (!copy($newoutput,$output)) {
02208                                                                 $output = $newoutput;
02209                                                         }
02210                                                 } else {
02211                                                         $output = $crsOutput;
02212                                                 }
02213                                         }
02214                                 } elseif ($this->dontCheckForExistingTempFile || !$this->file_exists_typo3temp_file($output,$imagefile)) {
02215                                         $this->imageMagickExec($imagefile.$frame,$output,$command);
02216                                 }
02217                                 if (@file_exists($output))      {
02218                                         $info[3] = $output;
02219                                         $info[2] = $newExt;
02220                                         if ($params)    {       // params could realisticly change some imagedata!
02221                                                 $info=$this->getImageDimensions($info[3]);
02222                                         }
02223                                         if ($info[2]==$this->gifExtension && !$this->dontCompress)      {
02224                                                 t3lib_div::gif_compress($info[3],'');           // Compress with IM (lzw) or GD (rle)  (Workaround for the absence of lzw-compression in GD)
02225                                         }
02226                                         return $info;
02227                                 }
02228                         }
02229                 }
02230         }
02231 
02239         function getImageDimensions($imageFile) {
02240                 ereg('([^\.]*)$',$imageFile,$reg);
02241                 if (@file_exists($imageFile) && t3lib_div::inList($this->imageFileExt,strtolower($reg[0])))     {
02242                         if ($returnArr = $this->getCachedImageDimensions($imageFile))   {
02243                                 return $returnArr;
02244                         } else {
02245                                 if ($temp = @getImageSize($imageFile))  {
02246                                         $returnArr = Array($temp[0], $temp[1], strtolower($reg[0]), $imageFile);
02247                                 } else {
02248                                         $returnArr = $this->imageMagickIdentify($imageFile);
02249                                 }
02250                                 if ($returnArr) {
02251                                         $this->cacheImageDimensions($returnArr);
02252                                         return $returnArr;
02253                                 }
02254                         }
02255                 }
02256                 return false;
02257         }
02258 
02267         function cacheImageDimensions($identifyResult)  {
02268                 global $TYPO3_DB;
02269                         // Create a md5 hash of the filename
02270                 if (function_exists('md5_file')) {
02271                         $md5Hash = md5_file($identifyResult[3]);
02272                 } else {
02273                         $md5Hash = md5 (t3lib_div::getURL($identifyResult[3]));
02274                 }
02275                 if ($md5Hash) {
02276                         $fieldArr = array (
02277                                 'md5hash' => $md5Hash,
02278                                 'md5filename' => md5($identifyResult[3]),
02279                                 'tstamp' => time(),
02280                                 'filename' => $identifyResult[3],
02281                                 'imagewidth' => $identifyResult[0],
02282                                 'imageheight' => $identifyResult[1],
02283                         );
02284                         $TYPO3_DB->exec_INSERTquery('cache_imagesizes', $fieldArr);
02285                         if (!$err = $TYPO3_DB->sql_error())     {
02286                                 return true;
02287                         }
02288                 }
02289                 return false;
02290         }
02291 
02299         function getCachedImageDimensions($imageFile)   {
02300                 global $TYPO3_DB;
02301                         // Create a md5 hash of the filename
02302                 if(function_exists('md5_file')) {
02303                         $md5Hash = md5_file($imageFile);
02304                 } else {
02305                         $md5Hash = md5(t3lib_div::getURL ($imageFile));
02306                 }
02307                 ereg('([^\.]*)$',$imageFile,$reg);
02308                 $res = $TYPO3_DB->exec_SELECTquery ('md5hash, imagewidth, imageheight', 'cache_imagesizes', 'md5filename='.$TYPO3_DB->fullQuoteStr(md5($imageFile),'cache_imagesizes'));
02309                 if ($res) {
02310                         if ($row = $TYPO3_DB->sql_fetch_assoc($res)) {
02311                                 if ($row['md5hash']!=$md5Hash) {
02312                                                 // file has changed, delete the row
02313                                         $TYPO3_DB->exec_DELETEquery ('cache_imagesizes', 'md5hash='.$TYPO3_DB->fullQuoteStr($row['md5hash'],'cache_imagesizes'));
02314                                 } else {
02315                                         return (array($row['imagewidth'], $row['imageheight'], strtolower($reg[0]), $imageFile));
02316                                 }
02317                         }
02318                 }
02319                 return false;
02320         }
02321 
02333         function getImageScale($info,$w,$h,$options) {
02334                 if (strstr($w.$h, 'm')) {$max=1;} else {$max=0;}
02335 
02336                 if (strstr($w.$h, 'c')) {
02337                         $out['cropH'] = intval(substr(strstr($w, 'c'), 1));
02338                         $out['cropV'] = intval(substr(strstr($h, 'c'), 1));
02339                         $crs = true;
02340                 } else {
02341                         $crs = false;
02342                 }
02343                 $out['crs'] = $crs;
02344 
02345                 $w=intval($w);
02346                 $h=intval($h);
02347                         // if there are max-values...
02348                 if ($options['maxW'])   {
02349                         if ($w) {       // if width is given...
02350                                 if ($w>$options['maxW']) {
02351                                         $w=$options['maxW'];
02352                                         $max=1; // height should follow
02353                                 }
02354                         } else {
02355                                 if ($info[0]>$options['maxW']) {
02356                                         $w=$options['maxW'];
02357                                         $max=1; // height should follow
02358                                 }
02359                         }
02360                 }
02361                 if ($options['maxH'])   {
02362                         if ($h) {       // if height is given...
02363                                 if ($h>$options['maxH']) {
02364                                         $h=$options['maxH'];
02365                                         $max=1; // height should follow
02366                                 }
02367                         } else {
02368                                 if ($info[1]>$options['maxH']) {        // Changed [0] to [1] 290801
02369                                         $h=$options['maxH'];
02370                                         $max=1; // height should follow
02371                                 }
02372                         }
02373                 }
02374                 $out['origW']=$w;
02375                 $out['origH']=$h;
02376                 $out['max'] = $max;
02377 
02378                 if (!$this->mayScaleUp) {
02379                         if ($w>$info[0]){$w=$info[0];}
02380                         if ($h>$info[1]){$h=$info[1];}
02381                 }
02382                 if ($w || $h)   {       // if scaling should be performed
02383                         if ($w && !$h)  {
02384                                 $info[1] = ceil($info[1]*($w/$info[0]));
02385                                 $info[0] = $w;
02386                         }
02387                         if (!$w && $h)  {
02388                                 $info[0] = ceil($info[0]*($h/$info[1]));
02389                                 $info[1] = $h;
02390                         }
02391                         if ($w && $h)   {
02392                                 if ($max)       {
02393                                         $ratio = $info[0]/$info[1];
02394                                         if ($h*$ratio > $w) {
02395                                                 $h = round($w/$ratio);
02396                                         } else {
02397                                                 $w = round($h*$ratio);
02398                                         }
02399                                 }
02400                                 if ($crs)       {
02401                                         $ratio = $info[0] / $info[1];
02402                                         if ($h * $ratio < $w) {
02403                                                 $h = round($w / $ratio);
02404                                         } else {
02405                                                 $w = round($h * $ratio);
02406                                         }
02407                                 }
02408                                 $info[0] = $w;
02409                                 $info[1] = $h;
02410                         }
02411                 }
02412                 $out[0]=$info[0];
02413                 $out[1]=$info[1];
02414                         // Set minimum-measures!
02415                 if ($options['minW'] && $out[0]<$options['minW'])       {
02416                         if (($max || $crs) && $out[0])  {
02417                                 $out[1]= round($out[1]*$options['minW']/$out[0]);
02418                         }
02419                         $out[0]=$options['minW'];
02420                 }
02421                 if ($options['minH'] && $out[1]<$options['minH'])       {
02422                         if (($max || $crs) && $out[1])  {
02423                                 $out[0]= round($out[0]*$options['minH']/$out[1]);
02424                         }
02425                         $out[1]=$options['minH'];
02426                 }
02427 
02428                 return $out;
02429         }
02430 
02439         function file_exists_typo3temp_file($output,$orig='')   {
02440                 if ($this->enable_typo3temp_db_tracking)        {
02441                         if (@file_exists($output))      {       // If file exists, then we return immediately
02442                                 return 1;
02443                         } else {        // If not, we look up in the cache_typo3temp_log table to see if there is a image being rendered right now.
02444                                 $md5Hash=md5($output);
02445                                 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('md5hash', 'cache_typo3temp_log', 'md5hash='.$GLOBALS['TYPO3_DB']->fullQuoteStr($md5Hash, 'cache_typo3temp_log').' AND tstamp>'.(time()-30));
02446                                 if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {       // If there was a record, the image is being generated by another proces (we assume)
02447                                         if (is_object($GLOBALS['TSFE']))        $GLOBALS['TSFE']->set_no_cache();       // ...so we set no_cache, because we dont want this page (which will NOT display an image...!) to be cached! (Only a page with the correct image on...)
02448                                         if (is_object($GLOBALS['TT']))  $GLOBALS['TT']->setTSlogMessage('typo3temp_log: Assume this file is being rendered now: '.$output);
02449                                         return 2;       // Return 'success - 2'
02450                                 } else {                // If the current time is more than 30 seconds since this record was written, we clear the record, write a new and render the image.
02451 
02452                                         $insertFields = array(
02453                                                 'md5hash' => $md5Hash,
02454                                                 'tstamp' => time(),
02455                                                 'filename' => $output,
02456                                                 'orig_filename' => $orig
02457                                         );
02458                                         $GLOBALS['TYPO3_DB']->exec_DELETEquery('cache_typo3temp_log', 'md5hash='.$GLOBALS['TYPO3_DB']->fullQuoteStr($md5Hash, 'cache_typo3temp_log'));
02459                                         $GLOBALS['TYPO3_DB']->exec_INSERTquery('cache_typo3temp_log', $insertFields);
02460 
02461                                         if (is_object($GLOBALS['TT']))  $GLOBALS['TT']->setTSlogMessage('typo3temp_log: The row did not exist, so a new is written and file is being processed: '.$output);
02462                                         return 0;
02463                                 }
02464                         }
02465                 } else {
02466                         return @file_exists($output);
02467                 }
02468         }
02469 
02470 
02471 
02472 
02473 
02474 
02475 
02476 
02477 
02478 
02479 
02480 
02481 
02482 
02483 
02484 
02485 
02486 
02487         /***********************************
02488          *
02489          * ImageMagick API functions
02490          *
02491          ***********************************/
02492 
02500         function imageMagickIdentify($imagefile)        {
02501                 if (!$this->NO_IMAGE_MAGICK)    {
02502                         $frame = $this->noFramePrepended?'':'[0]';
02503                         $cmd = t3lib_div::imageMagickCommand('identify', $this->wrapFileName($imagefile).$frame);
02504                         $returnVal = array();
02505                         exec($cmd, $returnVal);
02506                         $splitstring=$returnVal[0];
02507                         $this->IM_commands[] = Array ('identify',$cmd,$returnVal[0]);
02508                         if ($splitstring)       {
02509                                 ereg('([^\.]*)$',$imagefile,$reg);
02510                                 $splitinfo = explode(' ', $splitstring);
02511                                 while (list($key,$val) = each($splitinfo))      {
02512                                         $temp = '';
02513                                         if ($val) {$temp = explode('x', $val);}
02514                                         if (intval($temp[0]) && intval($temp[1]))       {
02515                                                 $dim=$temp;
02516                                                 break;
02517                                         }
02518                                 }
02519                                 if ($dim[0] && $dim[1]) {
02520                                         return Array($dim[0], $dim[1], strtolower($reg[0]), $imagefile);
02521                                 }
02522                         }
02523                 }
02524         }
02525 
02535         function imageMagickExec($input,$output,$params)        {
02536                 if (!$this->NO_IMAGE_MAGICK)    {
02537                         $cmd = t3lib_div::imageMagickCommand('convert', $params.' '.$this->wrapFileName($input).' '.$this->wrapFileName($output));
02538                         $this->IM_commands[] = array($output,$cmd);
02539 
02540                         $ret = exec($cmd);
02541                         t3lib_div::fixPermissions($this->wrapFileName($output));        // Change the permissions of the file
02542 
02543                         return $ret;
02544                 }
02545         }
02546 
02558         function combineExec($input,$overlay,$mask,$output, $handleNegation = false)    {
02559                 if (!$this->NO_IMAGE_MAGICK)    {
02560                         $params = '-colorspace GRAY +matte';
02561                         if ($handleNegation)    {
02562                                 if ($this->maskNegate)  {
02563                                         $params .= ' '.$this->maskNegate;
02564                                 }
02565                         }
02566                         $theMask = $this->randomName().'.'.$this->gifExtension;
02567                         $this->imageMagickExec($mask, $theMask, $params);
02568                         $cmd = t3lib_div::imageMagickCommand('combine', '-compose over +matte '.$this->wrapFileName($input).' '.$this->wrapFileName($overlay).' '.$this->wrapFileName($theMask).' '.$this->wrapFileName($output));              // +matte = no alpha layer in output
02569                         $this->IM_commands[] = Array ($output,$cmd);
02570 
02571                         $ret = exec($cmd);
02572                         t3lib_div::fixPermissions($this->wrapFileName($output));        // Change the permissions of the file
02573 
02574                         if (is_file($theMask))  {
02575                                 @unlink($theMask);
02576                         }
02577 
02578                         return $ret;
02579                 }
02580         }
02581 
02589         function wrapFileName($inputName)       {
02590                 if (strstr($inputName,' '))     {
02591                         $inputName='"'.$inputName.'"';
02592                 }
02593                 return $inputName;
02594         }
02595 
02596 
02597 
02598 
02599 
02600 
02601 
02602 
02603 
02604 
02605 
02606 
02607 
02608 
02609 
02610 
02611 
02612 
02613 
02614 
02615 
02616 
02617 
02618         /***********************************
02619          *
02620          * Various IO functions
02621          *
02622          ***********************************/
02623 
02630         function checkFile($file)       {
02631                 if (@is_file($file))    {
02632                         return $file;
02633                 } else {
02634                         return '';
02635                 }
02636         }
02637 
02644         function createTempSubDir($dirName)     {
02645 
02646                         // Checking if the this->tempPath is already prefixed with PATH_site and if not, prefix it with that constant.
02647                 if (t3lib_div::isFirstPartOfStr($this->tempPath,PATH_site))     {
02648                         $tmpPath = $this->tempPath;
02649                 } else {
02650                         $tmpPath = PATH_site.$this->tempPath;
02651                 }
02652 
02653                         // Making the temporary filename:
02654                 if (!@is_dir($tmpPath.$dirName))         {
02655                         return t3lib_div::mkdir($tmpPath.$dirName);
02656                 }
02657         }
02658 
02666         function applyImageMagickToPHPGif(&$im, $command)       {
02667                 $tmpStr = $this->randomName();
02668                 $theFile = $tmpStr.'.'.$this->gifExtension;
02669                 $this->ImageWrite($im, $theFile);
02670                 $this->imageMagickExec($theFile,$theFile,$command);
02671                 $tmpImg = $this->imageCreateFromFile($theFile);
02672                 if ($tmpImg)    {
02673                         ImageDestroy($im);
02674                         $im = $tmpImg;
02675                         $this->w = imagesx($im);
02676                         $this->h = imagesy($im);
02677                 }
02678                 if (!$this->dontUnlinkTempFiles)        {
02679                         unlink($theFile);
02680                 }
02681         }
02682 
02692         function gif_or_jpg($type,$w,$h)        {
02693                 if ($type=='ai' || $w*$h < $this->pixelLimitGif)        {
02694                         return $this->gifExtension;
02695                 } else {
02696                         return 'jpg';
02697                 }
02698         }
02699 
02709         function output($file)  {
02710                 if ($file)      {
02711                         $reg = array();
02712                         ereg('([^\.]*)$',$file,$reg);
02713                         $ext=strtolower($reg[0]);
02714                         switch($ext)    {
02715                                 case 'gif':
02716                                 case 'png':
02717                                         if ($this->ImageWrite($this->im, $file))        {
02718                                                         // ImageMagick operations
02719                                                 if ($this->setup['reduceColors'] || (!$this->png_truecolor && $this->truecolor))        {
02720                                                         $reduced = $this->IMreduceColors($file, t3lib_div::intInRange($this->setup['reduceColors'], 256, $this->truecolorColors, 256));
02721                                                         if ($reduced)   {
02722                                                                 @copy($reduced, $file);
02723                                                                 @unlink($reduced);
02724                                                         }
02725                                                 }
02726                                                 t3lib_div::gif_compress($file, 'IM');           // Compress with IM! (adds extra compression, LZW from ImageMagick)     (Workaround for the absence of lzw-compression in GD)
02727                                         }
02728                                 break;
02729                                 case 'jpg':
02730                                 case 'jpeg':
02731                                         $quality = 0;   // Use the default
02732                                         if($this->setup['quality'])     {
02733                                                 $quality = t3lib_div::intInRange($this->setup['quality'],10,100);
02734                                         }
02735                                         if ($this->ImageWrite($this->im, $file, $quality));
02736                                 break;
02737                         }
02738                         $GLOBALS['TEMP_IMAGES_ON_PAGE'][]=$file;
02739                 }
02740                 return $file;
02741         }
02742 
02749         function destroy()      {
02750                 ImageDestroy($this->im);
02751         }
02752 
02759         function imgTag ($imgInfo) {
02760                 return '<img src="'.$imgInfo[3].'" width="'.$imgInfo[0].'" height="'.$imgInfo[1].'" border="0" alt="" />';
02761         }
02762 
02771         function ImageWrite($destImg, $theImage)        {
02772                 imageinterlace ($destImg,0);
02773                 $ext = strtolower(substr($theImage, strrpos($theImage, '.')+1));
02774                 switch ($ext)   {
02775                         case 'jpg':
02776                         case 'jpeg':
02777                                 if (function_exists('imageJpeg'))       {
02778                                         return imageJpeg($destImg, $theImage, $this->jpegQuality);
02779                                 }
02780                         break;
02781                         case 'gif':
02782                                 if (function_exists('imageGif'))        {
02783                                         if ($this->truecolor)   {
02784                                                 imagetruecolortopalette($destImg, true, 256);
02785                                         }
02786                                         return imageGif($destImg, $theImage);
02787                                 }
02788                         break;
02789                         case 'png':
02790                                 if (function_exists('imagePng'))        {
02791                                         return ImagePng($destImg, $theImage);
02792                                 }
02793                         break;
02794                 }
02795                 return false;           // Extension invalid or write-function does not exist
02796         }
02797 
02798 
02799 
02809         function imageGif($destImg, $theImage)  {
02810                 return $this->imageWrite($destImg, $theImage);
02811         }
02812 
02821         function imageCreateFromGif($sourceImg) {
02822                 return $this->imageCreateFromFile($sourceImg);
02823         }
02824 
02832         function imageCreateFromFile($sourceImg)        {
02833                 $imgInf = pathinfo($sourceImg);
02834                 $ext = strtolower($imgInf['extension']);
02835 
02836                 switch ($ext)   {
02837                         case 'gif':
02838                                 if (function_exists('imagecreatefromgif'))      {
02839                                         return imageCreateFromGif($sourceImg);
02840                                 }
02841                         break;
02842                         case 'png':
02843                                 if (function_exists('imagecreatefrompng'))      {
02844                                         return imageCreateFromPng($sourceImg);
02845                                 }
02846                         break;
02847                         case 'jpg':
02848                         case 'jpeg':
02849                                 if (function_exists('imagecreatefromjpeg'))     {
02850                                         return imageCreateFromJpeg($sourceImg);
02851                                 }
02852                         break;
02853                 }
02854 
02855                 // If non of the above:
02856                 $i = @getimagesize($sourceImg);
02857                 $im = $this->imagecreate($i[0],$i[1]);
02858                 $Bcolor = ImageColorAllocate($im, 128,128,128);
02859                 ImageFilledRectangle($im, 0, 0, $i[0], $i[1], $Bcolor);
02860                 return $im;
02861         }
02862 
02863 
02871         function imagecreate($w, $h)    {
02872                 if($this->truecolor && function_exists('imagecreatetruecolor')) {
02873                         return imagecreatetruecolor($w, $h);
02874                 } else  {
02875                         return imagecreate($w, $h);
02876                 }
02877 
02878         }
02879 
02886         function hexColor($col) {
02887                 $r = dechex($col[0]);
02888                 if (strlen($r)<2)       { $r = '0'.$r; }
02889                 $g = dechex($col[1]);
02890                 if (strlen($g)<2)       { $g = '0'.$g; }
02891                 $b = dechex($col[2]);
02892                 if (strlen($b)<2)       { $b = '0'.$b; }
02893                 return '#'.$r.$g.$b;
02894         }
02895 
02904         function unifyColors(&$img, $colArr, $closest = false)  {
02905                 $retCol = -1;
02906                 if (is_array($colArr) && count($colArr) && function_exists('imagepng') && function_exists('imagecreatefrompng'))        {
02907                         $firstCol = array_shift($colArr);
02908                         $firstColArr = $this->convertColor($firstCol);
02909                         if (count($colArr)>1)   {
02910                                 $origName = $preName = $this->randomName().'.png';
02911                                 $postName = $this->randomName().'.png';
02912                                 $this->imageWrite($img, $preName);
02913                                 $firstCol = $this->hexColor($firstColArr);
02914                                 foreach ($colArr as $transparentColor)  {
02915                                         $transparentColor = $this->convertColor($transparentColor);
02916                                         $transparentColor = $this->hexColor($transparentColor);
02917                                         $cmd = '-fill "'.$firstCol.'" -opaque "'.$transparentColor.'"';
02918                                         $this->imageMagickExec($preName, $postName, $cmd);
02919                                         $preName = $postName;
02920                                 }
02921                                 $this->imageMagickExec($postName, $origName, '');
02922                                 if (@is_file($origName))        {
02923                                         $tmpImg = $this->imageCreateFromFile($origName);
02924                                 }
02925                         } else  {
02926                                 $tmpImg = $img;
02927                         }
02928                         if ($tmpImg)    {
02929                                 $img = $tmpImg;
02930                                 if ($closest)   {
02931                                         $retCol = ImageColorClosest ($img, $firstColArr[0], $firstColArr[1], $firstColArr[2]);
02932                                 } else  {
02933                                         $retCol = ImageColorExact ($img, $firstColArr[0], $firstColArr[1], $firstColArr[2]);
02934                                 }
02935                         }
02936                                 // unlink files from process
02937                         if (!$this->dontUnlinkTempFiles)        {
02938                                 if ($origName)  {
02939                                         @unlink($origName);
02940                                 }
02941                                 if ($postName)  {
02942                                         @unlink($postName);
02943                                 }
02944                         }
02945                 }
02946                 return $retCol;
02947         }
02948 
02949 
02950 }
02951 
02952 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_stdgraphic.php'])        {
02953         include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_stdgraphic.php']);
02954 }
02955 ?>