Main Page | Directories | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members | Related Pages | Examples

class.t3lib_stdgraphic.php

Go to the documentation of this file.
00001 <?php
00002 /***************************************************************
00003 *  Copyright notice
00004 *
00005 *  (c) 1999-2004 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 ***************************************************************/
00147 class t3lib_stdGraphic  {
00148 
00149       // Internal configuration, set in init()
00150    var $combineScript = 'combine';           // The ImageMagick filename used for combining two images. This name changed during the versions.
00151    var $noFramePrepended=0;               // If set, there is no frame pointer prepended to the filenames.
00152    var $GD2=0;                         // Set, if the GDlib used is version 2.
00153    var $imagecopyresized_fix=0;           // If set, imagecopyresized will not be called directly. For GD2 (some PHP installs?)
00154    var $gifExtension = 'gif';             // This should be changed to 'png' if you want this class to read/make PNG-files instead!
00155    var $TTFLocaleConv = '';               // Used to recode input to TTF-functions for other charsets.
00156    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.
00157    var $imageMagickPath = '';             // path to imageMagick, eg: /usr/lib/
00158    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!
00159    var $webImageExt = 'gif,jpg,jpeg,png';    // Commalist of web image extensions (can be shown by a webbrowser)
00160    var $maskNegate = '';                  // Will be ' -negate' if ImageMagick ver 5.2+. See init();
00161    var $NO_IM_EFFECTS = '';
00162    var $cmds = Array (
00163       'jpg' => '',
00164       'jpeg' => '',
00165       'gif' => '-colors 64',
00166       'png' => '-colors 64'
00167    );
00168    var $NO_IMAGE_MAGICK = '';
00169    var $V5_EFFECTS = 0;
00170    var $mayScaleUp = 1;
00171 
00172       // Variables for testing, alternative usage etc.
00173    var $filenamePrefix='';                      // Filename prefix for images scaled in imageMagickConvert()
00174    var $imageMagickConvert_forceFileNameBody='';      // Forcing the output filename of imageMagickConvert() to this value. However after calling imageMagickConvert() it will be set blank again.
00175    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.
00176    var $dontCompress=0;                      // Prevents imageMagickConvert() from compressing the gif-files with t3lib_div::gif_compress()
00177    var $dontUnlinkTempFiles=0;                     // For debugging ONLY!
00178    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...
00179 
00180       // Internal:
00181    var $IM_commands = Array();                     // All ImageMagick commands executed is stored in this array for tracking. Used by the Install Tools Image section
00182    var $workArea = Array();
00183 
00184       // Constants:
00185    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.
00186    var $absPrefix = '';                      // Prefix for relative paths. Used in "show_item.php" script. Is prefixed the output file name IN imageMagickConvert()
00187    var $scalecmd = '-geometry';                 // ImageMagick scaling command; "-geometry" eller "-sample". Used in makeText() and imageMagickConvert()
00188    var $im5fx_blurSteps='1x2,2x2,3x2,4x3,5x3,5x4,6x4,7x5,8x5,9x5';         // Used by v5_blur() to simulate 10 continuous steps of blurring
00189    var $im5fx_sharpenSteps='1x2,2x2,3x2,2x3,3x3,4x3,3x4,4x4,4x5,5x5';      // Used by v5_sharpen() to simulate 10 continuous steps of sharpening.
00190    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
00191    var $colMap = Array (                        // Array mapping HTML color names to RGB values.
00192       'aqua' => Array(0,255,255),
00193       'black' => Array(0,0,0),
00194       'blue' => Array(0,0,255),
00195       'fuchsia' => Array(255,0,255),
00196       'gray' => Array(128,128,128),
00197       'green' => Array(0,128,0),
00198       'lime' => Array(0,255,0),
00199       'maroon' => Array(128,0,0),
00200       'navy' => Array(0,0,128),
00201       'olive' => Array(128,128,0),
00202       'purple' => Array(128,0,128),
00203       'red' => Array(255,0,0),
00204       'silver' => Array(192,192,192),
00205       'teal' => Array(0,128,128),
00206       'yellow' => Array(255,255,0),
00207       'white' => Array(255,255,255)
00208    );
00209 
00210       // Charset conversion object:
00211    var $csConvObj;
00212    var $nativeCharset='';     // Is set to the native character set of the input strings.
00213 
00214 
00215 
00216 
00217 
00224    function init()   {
00225       $gfxConf = $GLOBALS['TYPO3_CONF_VARS']['GFX'];
00226 
00227          // Setting default JPG parameters:
00228       $this->cmds['jpg'] = $this->cmds['jpeg'] = '-colorspace RGB -sharpen 50 -quality '.intval($gfxConf['im_jpg_quality']);
00229 
00230       if ($gfxConf['im_combine_filename'])   $this->combineScript=$gfxConf['im_combine_filename'];
00231       if ($gfxConf['im_noFramePrepended'])   $this->noFramePrepended=1;
00232 
00233       if ($gfxConf['gdlib_2'])   {
00234          $this->GD2 = 1;
00235          $this->imagecopyresized_fix = $gfxConf['gdlib_2']==='no_imagecopyresized_fix' ? 0 : 1;
00236       }
00237       if ($gfxConf['gdlib_png']) {
00238          $this->gifExtension='png';
00239       }
00240       if ($gfxConf['TTFLocaleConv']) {
00241          $this->TTFLocaleConv = $gfxConf['TTFLocaleConv'];
00242       }
00243       if ($gfxConf['enable_typo3temp_db_tracking']) {
00244          $this->enable_typo3temp_db_tracking = $gfxConf['enable_typo3temp_db_tracking'];
00245       }
00246 
00247       $this->imageMagickPath = $gfxConf['im_path'];
00248       $this->imageFileExt = $gfxConf['imagefile_ext'];
00249 
00250          // This should be set if ImageMagick ver. 5+ is used.
00251       if ($gfxConf['im_negate_mask'])  {
00252             // Boolean. Indicates if the mask images should be inverted first.
00253             // This depends of the ImageMagick version. Below ver. 5.1 this should be false.
00254             // Above ImageMagick version 5.2+ it should be true.
00255             // Just set the flag if the masks works opposite the intension!
00256          $this->maskNegate = ' -negate';
00257       }
00258       if ($gfxConf['im_no_effects'])   {
00259             // Boolean. This is necessary if using ImageMagick 5+.
00260             // Approved version for using effects is version 4.2.9.
00261             // Effects in Imagemagick 5+ tends to render very slowly!!
00262             // - therefore must be disabled in order not to perform sharpen, blurring and such.
00263          $this->NO_IM_EFFECTS = 1;
00264 
00265          $this->cmds['jpg'] = $this->cmds['jpeg'] = '-colorspace RGB -quality '.intval($gfxConf['im_jpg_quality']);
00266       }
00267          // ... but if 'im_v5effects' is set, dont care about 'im_no_effects'
00268       if ($gfxConf['im_v5effects']) {
00269          $this->NO_IM_EFFECTS = 0;
00270          $this->V5_EFFECTS = 1;
00271 
00272          if ($gfxConf['im_v5effects']>0)  {
00273             $this->cmds['jpg'] = $this->cmds['jpeg'] = '-colorspace RGB -quality '.intval($gfxConf['im_jpg_quality']).$this->v5_sharpen(10);
00274          }
00275       }
00276 
00277       if (!$gfxConf['im']) {
00278          $this->NO_IMAGE_MAGICK = 1;
00279       }
00280          // Secures that images are not scaled up.
00281       if ($gfxConf['im_noScaleUp']) {
00282          $this->mayScaleUp=0;
00283       }
00284 
00285       if (TYPO3_MODE=='FE')   {
00286          $this->csConvObj = &$GLOBALS['TSFE']->csConvObj;
00287       } else { // BE assumed:
00288          $this->csConvObj = &$GLOBALS['LANG']->csConvObj;
00289       }
00290       $this->nativeCharset = $GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'];
00291    }
00292 
00293 
00294 
00295 
00296 
00297 
00298 
00299 
00300 
00301 
00302 
00303 
00304 
00305 
00306 
00307 
00308    /*************************************************
00309     *
00310     * Layering images / "IMAGE" GIFBUILDER object
00311     *
00312     *************************************************/
00313 
00325    function maskImageOntoImage(&$im,$conf,$workArea)  {
00326       if ($conf['file'] && $conf['mask']) {
00327          $BBimage = $this->imageMagickConvert($conf['file'],$this->gifExtension,'','','','','');
00328          $BBmask = $this->imageMagickConvert($conf['mask'],$this->gifExtension,'','','','','');
00329          if ($BBimage && $BBmask)   {
00330             $w = imagesx($im);
00331             $h = imagesy($im);
00332             $tmpStr = $this->randomName();
00333             $theImage = $tmpStr.'_img.'.$this->gifExtension;
00334             $theDest = $tmpStr.'_dest.'.$this->gifExtension;
00335             $theMask = $tmpStr.'_mask.'.$this->gifExtension;
00336             $theMask2 = $tmpStr.'_mask2.'.trim($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_mask_temp_ext_noloss']);
00337                   // prepare overlay image
00338             $cpImg = $this->imageCreateFromGif($BBimage[3]);
00339             $destImg = imagecreate($w,$h);
00340             ImageColorAllocate($destImg, 0,0,0);
00341             $this->copyGifOntoGif($destImg,$cpImg,$conf,$workArea);
00342             $this->ImageGif($destImg, $theImage);
00343             imageDestroy($cpImg);
00344             imageDestroy($destImg);
00345                   // prepare mask image
00346             $cpImg = $this->imageCreateFromGif($BBmask[3]);
00347             $destImg = imagecreate($w,$h);
00348             ImageColorAllocate($destImg, 0,0,0);
00349             $this->copyGifOntoGif($destImg,$cpImg,$conf,$workArea);
00350             $this->ImageGif($destImg, $theMask);
00351             imageDestroy($cpImg);
00352             imageDestroy($destImg);
00353                // treat the mask
00354             $this->imageMagickExec($theMask,$theMask2,'-colorspace GRAY'.$this->maskNegate);
00355                // mask the images
00356             $this->ImageGif($im, $theDest);
00357 
00358             $this->combineExec($theDest,$theImage,$theMask2,$theDest);
00359 
00360             $backIm = $this->imageCreateFromGif($theDest);  // The main image is loaded again...
00361             if ($backIm)   {  // ... and if nothing went wrong we load it onto the old one.
00362                ImageColorTransparent($backIm,-1);
00363                $im = $backIm;
00364             }
00365                // unlink files from process
00366             if (!$this->dontUnlinkTempFiles) {
00367                unlink($theDest);
00368                unlink($theImage);
00369                unlink($theMask);
00370                unlink($theMask2);
00371             }
00372          }
00373       }
00374    }
00375 
00385    function copyImageOntoImage(&$im,$conf,$workArea)  {
00386       if ($conf['file'])   {
00387          if ($conf['BBOX'][2]!=$this->gifExtension)   {
00388             $conf['BBOX']=$this->imageMagickConvert($conf['BBOX'][3],$this->gifExtension,'','','','','');
00389             $conf['file']=$conf['BBOX'][3];
00390          }
00391          $cpImg = $this->imageCreateFromGif($conf['file']);
00392          $this->copyGifOntoGif($im,$cpImg,$conf,$workArea);
00393          imageDestroy($cpImg);
00394       }
00395    }
00396 
00407    function copyGifOntoGif(&$im,$cpImg,$conf,$workArea)  {
00408       $cpW = imagesx($cpImg);
00409       $cpH = imagesy($cpImg);
00410       $tile = t3lib_div::intExplode(',',$conf['tile']);
00411       $tile[0] = t3lib_div::intInRange($tile[0],1,20);
00412       $tile[1] = t3lib_div::intInRange($tile[1],1,20);
00413       $cpOff = $this->objPosition($conf,$workArea,Array($cpW*$tile[0],$cpH*$tile[1]));
00414 
00415       for ($xt=0;$xt<$tile[0];$xt++)   {
00416          $Xstart=$cpOff[0]+$cpW*$xt;
00417          if ($Xstart+$cpW > $workArea[0]) {  // if this image is inside of the workArea, then go on
00418                // X:
00419             if ($Xstart < $workArea[0])   {
00420                $cpImgCutX = $workArea[0]-$Xstart;
00421                $Xstart = $workArea[0];
00422             } else {
00423                $cpImgCutX = 0;
00424             }
00425             $w = $cpW-$cpImgCutX;
00426             if ($Xstart > $workArea[0]+$workArea[2]-$w)  {
00427                $w = $workArea[0]+$workArea[2]-$Xstart;
00428             }
00429             if ($Xstart < $workArea[0]+$workArea[2])  {  // if this image is inside of the workArea, then go on
00430                   // Y:
00431                for ($yt=0;$yt<$tile[1];$yt++)   {
00432                   $Ystart=$cpOff[1]+$cpH*$yt;
00433                   if ($Ystart+$cpH > $workArea[1]) {  // if this image is inside of the workArea, then go on
00434                      if ($Ystart < $workArea[1])   {
00435                         $cpImgCutY = $workArea[1]-$Ystart;
00436                         $Ystart = $workArea[1];
00437                      } else {
00438                         $cpImgCutY = 0;
00439                      }
00440                      $h = $cpH-$cpImgCutY;
00441                      if ($Ystart > $workArea[1]+$workArea[3]-$h)  {
00442                         $h = $workArea[1]+$workArea[3]-$Ystart;
00443                      }
00444                      if ($Ystart < $workArea[1]+$workArea[3])  {  // if this image is inside of the workArea, then go on
00445                         $this->imagecopyresized($im, $cpImg, $Xstart, $Ystart, $cpImgCutX, $cpImgCutY, $w, $h, $w, $h);
00446                      }
00447                   }
00448                }  // Y:
00449             }
00450          }
00451       }
00452    }
00453 
00486    function imagecopyresized(&$im, $cpImg, $Xstart, $Ystart, $cpImgCutX, $cpImgCutY, $w, $h, $w, $h)  {
00487       if ($this->imagecopyresized_fix) {
00488          $im_base = imagecreatetruecolor(imagesx($im), imagesy($im));   // Make true color image
00489          imagecopyresized($im_base, $im, 0,0,0,0, imagesx($im),imagesy($im),imagesx($im),imagesy($im));  // Copy the source image onto that
00490          imagecopyresized($im_base, $cpImg, $Xstart, $Ystart, $cpImgCutX, $cpImgCutY, $w, $h, $w, $h);   // Then copy the $cpImg onto that (the actual operation!)
00491          $im = $im_base;   // Set pointer
00492          $this->makeEffect($im, Array('value'=>'colors=256')); // Reduce colors to 256 - make SURE that IM is working then!
00493       } else {
00494          imagecopyresized($im, $cpImg, $Xstart, $Ystart, $cpImgCutX, $cpImgCutY, $w, $h, $w, $h);
00495       }
00496    }
00497 
00498 
00499 
00500 
00501 
00502 
00503 
00504 
00505 
00506 
00507 
00508 
00509 
00510 
00511 
00512 
00513 
00514 
00515 
00516 
00517 
00518 
00519 
00520    /********************************
00521     *
00522     * Text / "TEXT" GIFBUILDER object
00523     *
00524     ********************************/
00525 
00535    function makeText(&$im,$conf,$workArea)   {
00536          // Spacing
00537       $spacing = intval($conf['spacing']);
00538       $wordSpacing = intval($conf['wordSpacing']);
00539       $wordSpacing = $wordSpacing?$wordSpacing:$spacing*2;
00540          // Position
00541       $txtPos = $this->txtPosition($conf,$workArea,$conf['BBOX']);
00542       $theText = $this->recodeString($conf['text']);
00543 
00544       if ($conf['imgMap'] && is_array($conf['imgMap.'])) {
00545          $this->addToMap($this->calcTextCordsForMap($conf['BBOX'][2],$txtPos, $conf['imgMap.']), $conf['imgMap.']);
00546       }
00547       if (!$conf['hideButCreateMap'])  {
00548             // Font Color:
00549          $cols=$this->convertColor($conf['fontColor']);
00550             // NiceText is calculated
00551          if (!$conf['niceText']) {
00552                // Font Color is reserved:
00553             $this->reduceColors($im,256, 200);
00554             $Fcolor = ImageColorAllocate($im, $cols[0],$cols[1],$cols[2]);
00555                // antiAliasing is setup:
00556             $Fcolor = ($conf['antiAlias']) ? $Fcolor : -$Fcolor;
00557 
00558             for ($a=0; $a<$conf['iterations']; $a++)  {
00559                if ($spacing || $wordSpacing) {     // If any kind of spacing applys, we use this function:
00560                   $this->SpacedImageTTFText($im, $conf['fontSize'], $conf['angle'], $txtPos[0], $txtPos[1], $Fcolor, t3lib_stdGraphic::prependAbsolutePath($conf['fontFile']), $theText, $spacing, $wordSpacing, $conf['splitRendering.']);
00561                } else {
00562                   $this->ImageTTFTextWrapper($im, $conf['fontSize'], $conf['angle'], $txtPos[0], $txtPos[1], $Fcolor, $conf['fontFile'], $theText, $conf['splitRendering.']);
00563                }
00564             }
00565          } else {    // NICETEXT::
00566                // options anti_aliased and iterations is NOT available when doing this!!
00567             $w = imagesx($im);
00568             $h = imagesy($im);
00569             $tmpStr = $this->randomName();
00570 
00571             $fileMenu = $tmpStr.'_menuNT.'.$this->gifExtension;
00572             $fileColor = $tmpStr.'_colorNT.'.$this->gifExtension;
00573             $fileMask = $tmpStr.'_maskNT.'.$this->gifExtension;
00574                // Scalefactor
00575             $sF = t3lib_div::intInRange($conf['niceText.']['scaleFactor'],2,5);
00576             $newW = ceil($sF*imagesx($im));
00577             $newH = ceil($sF*imagesy($im));
00578 
00579                // Make mask
00580             $maskImg = imagecreate($newW, $newH);
00581             ImageColorAllocate($maskImg, 255,255,255);
00582             $Fcolor = ImageColorAllocate($maskImg, 0,0,0);
00583             if ($spacing || $wordSpacing) {     // If any kind of spacing applys, we use this function:
00584                $this->SpacedImageTTFText($maskImg, $conf['fontSize'], $conf['angle'], $txtPos[0], $txtPos[1], $Fcolor, t3lib_stdGraphic::prependAbsolutePath($conf['fontFile']), $theText, $spacing, $wordSpacing, $conf['splitRendering.'],$sF);
00585             } else {
00586                $this->ImageTTFTextWrapper($maskImg, $conf['fontSize'], $conf['angle'], $txtPos[0], $txtPos[1], $Fcolor, $conf['fontFile'], $theText, $conf['splitRendering.'],$sF);
00587             }
00588             $this->ImageGif($maskImg, $fileMask);
00589             ImageDestroy($maskImg);
00590 
00591                // Downscales the mask
00592             if ($this->NO_IM_EFFECTS)  {
00593                if ($this->maskNegate)  {
00594                   $command = trim($this->scalecmd.' '.$w.'x'.$h.'!');      // Negate 2 times makes no negate...
00595                } else {
00596                   $command = trim($this->scalecmd.' '.$w.'x'.$h.'! -negate');
00597                }
00598             } else {
00599                if ($this->maskNegate)  {
00600                   $command = trim($conf['niceText.']['before'].' '.$this->scalecmd.' '.$w.'x'.$h.'! '.$conf['niceText.']['after']);
00601                } else {
00602                   $command = trim($conf['niceText.']['before'].' '.$this->scalecmd.' '.$w.'x'.$h.'! '.$conf['niceText.']['after'].' -negate');
00603                }
00604                if ($conf['niceText.']['sharpen']) {
00605                   if ($this->V5_EFFECTS)  {
00606                      $command.=$this->v5_sharpen($conf['niceText.']['sharpen']);
00607                   } else {
00608                      $command.=' -sharpen '.t3lib_div::intInRange($conf['niceText.']['sharpen'],1,99);
00609                   }
00610                }
00611             }
00612             $this->imageMagickExec($fileMask,$fileMask,$command);
00613 
00614                // Make the color-file
00615             $colorImg = imagecreate($w,$h);
00616             ImageColorAllocate($colorImg, $cols[0],$cols[1],$cols[2]);
00617             $this->ImageGif($colorImg, $fileColor);
00618             ImageDestroy($colorImg);
00619 
00620                // The mask is applied
00621             $this->ImageGif($im, $fileMenu); // The main pictures is saved temporarily
00622 
00623             $this->combineExec($fileMenu,$fileColor,$fileMask,$fileMenu);
00624 
00625             $backIm = $this->imageCreateFromGif($fileMenu); // The main image is loaded again...
00626             if ($backIm)   {  // ... and if nothing went wrong we load it onto the old one.
00627                ImageColorTransparent($backIm,-1);
00628                $im = $backIm;
00629             }
00630 
00631                // Deleting temporary files;
00632             if (!$this->dontUnlinkTempFiles) {
00633                unlink($fileMenu);
00634                unlink($fileColor);
00635                unlink($fileMask);
00636             }
00637          }
00638       }
00639    }
00640 
00651    function txtPosition($conf,$workArea,$BB) {
00652       $bbox = $BB[2];
00653       $angle=intval($conf['angle'])/180*pi();
00654       $conf['angle']=0;
00655       $straightBB = $this->calcBBox($conf);
00656 
00657          // offset, align, valign, workarea
00658       $result=Array();  // [0]=x, [1]=y, [2]=w, [3]=h
00659       $result[2] = $BB[0];
00660       $result[3] = $BB[1];
00661       $w=$workArea[2];
00662       $h=$workArea[3];
00663 
00664       switch($conf['align'])  {
00665          case 'right':
00666          case 'center':
00667             $factor=abs(cos($angle));
00668             $sign=(cos($angle)<0)?-1:1;
00669             $len1 = $sign*$factor*$straightBB[0];
00670             $len2= $sign*$BB[0];
00671             $result[0] = $w-ceil($len2*$factor+(1-$factor)*$len1);
00672 
00673             $factor=abs(sin($angle));
00674             $sign=(sin($angle)<0)?-1:1;
00675             $len1= $sign*$factor*$straightBB[0];
00676             $len2= $sign*$BB[1];
00677             $result[1]=ceil($len2*$factor+(1-$factor)*$len1);
00678          break;
00679       }
00680       switch($conf['align'])  {
00681          case 'right':
00682          break;
00683          case 'center':
00684             $result[0] = round(($result[0])/2);
00685             $result[1] = round(($result[1])/2);
00686          break;
00687          default:
00688             $result[0]=0;
00689             $result[1]=0;
00690          break;
00691       }
00692       $result = $this->applyOffset($result,t3lib_div::intExplode(',',$conf['offset']));
00693       $result = $this->applyOffset($result,$workArea);
00694       return $result;
00695    }
00696 
00705    function calcBBox($conf)   {
00706       if (!$conf['niceText']) {
00707          $sF = 1;
00708       } else {    // NICETEXT::
00709          $sF = t3lib_div::intInRange($conf['niceText.']['scaleFactor'],2,5);
00710       }
00711 
00712       $spacing = intval($conf['spacing']);
00713       $wordSpacing = intval($conf['wordSpacing']);
00714       $wordSpacing = $wordSpacing?$wordSpacing:$spacing*2;
00715 
00716       $spacing*=$sF;
00717       $wordSpacing*=$sF;
00718       $theText = $this->recodeString($conf['text']);
00719 
00720       $charInf = $this->ImageTTFBBoxWrapper($conf['fontSize'], $conf['angle'], $conf['fontFile'], $theText, $conf['splitRendering.'],$sF);
00721       $theBBoxInfo = $charInf;
00722       if ($conf['angle'])  {
00723          $xArr = Array($charInf[0],$charInf[2],$charInf[4],$charInf[6]);
00724          $yArr = Array($charInf[1],$charInf[3],$charInf[5],$charInf[7]);
00725          $x=max($xArr)-min($xArr);
00726          $y=max($yArr)-min($yArr);
00727       } else {
00728          $x = ($charInf[2]-$charInf[0]);
00729          $y = ($charInf[1]-$charInf[7]);
00730       }
00731       if ($spacing || $wordSpacing) {     // If any kind of spacing applys, we use this function:
00732          $x=0;
00733          if (!$spacing && $wordSpacing)   {
00734             $bits = explode(' ',$theText);
00735             while(list(,$word)=each($bits))  {
00736                $word.=' ';
00737                $wordInf = $this->ImageTTFBBoxWrapper($conf['fontSize'], $conf['angle'], $conf['fontFile'], $word, $conf['splitRendering.'],$sF);
00738                $wordW = ($wordInf[2]-$wordInf[0]);
00739                $x+=$wordW+$wordSpacing;
00740             }
00741          } else {
00742             $utf8Chars = $this->singleChars($theText);
00743                // For each UTF-8 char, do:
00744             foreach($utf8Chars as $char)  {
00745                $charInf = $this->ImageTTFBBoxWrapper($conf['fontSize'], $conf['angle'], $conf['fontFile'], $char, $conf['splitRendering.'],$sF);
00746                $charW = ($charInf[2]-$charInf[0]);
00747                $x+=$charW+(($char==' ')?$wordSpacing:$spacing);
00748             }
00749          }
00750       }
00751 
00752       if ($sF>1) {
00753          $x = ceil($x/$sF);
00754          $y = ceil($y/$sF);
00755          if (is_array($theBBoxInfo))   {
00756             reset($theBBoxInfo);
00757             while(list($key,$val)=each($theBBoxInfo)) {
00758                $theBBoxInfo[$key]=ceil($theBBoxInfo[$key]/$sF);
00759             }
00760          }
00761       }
00762       return Array($x,$y,$theBBoxInfo);
00763    }
00764 
00774    function addToMap($cords,$conf)  {
00775       $JS = $conf['noBlur'] ? '' : ' onfocus="blurLink(this);"';
00776 
00777       $this->map.='<area'.
00778             ' shape="poly"'.
00779             ' coords="'.implode(',',$cords).'"'.
00780             ' href="'.htmlspecialchars($conf['url']).'"'.
00781             ($conf['target'] ? ' target="'.htmlspecialchars($conf['target']).'"' : '').
00782             $JS.
00783             (strlen($conf['titleText']) ? ' title="'.htmlspecialchars($conf['titleText']).'"' : '').
00784             ' alt="'.htmlspecialchars($conf['altText']).'" />';
00785    }
00786 
00797    function calcTextCordsForMap($cords,$offset, $conf)   {
00798       $pars = t3lib_div::intExplode(',',$conf['explode'].',');
00799 
00800       $newCords[0] = $cords[0]+$offset[0]-$pars[0];
00801       $newCords[1] = $cords[1]+$offset[1]+$pars[1];
00802       $newCords[2] = $cords[2]+$offset[0]+$pars[0];
00803       $newCords[3] = $cords[3]+$offset[1]+$pars[1];
00804       $newCords[4] = $cords[4]+$offset[0]+$pars[0];
00805       $newCords[5] = $cords[5]+$offset[1]-$pars[1];
00806       $newCords[6] = $cords[6]+$offset[0]-$pars[0];
00807       $newCords[7] = $cords[7]+$offset[1]-$pars[1];
00808 
00809       return $newCords;
00810    }
00811 
00832    function SpacedImageTTFText(&$im, $fontSize, $angle, $x, $y, $Fcolor, $fontFile, $text, $spacing, $wordSpacing, $splitRenderingConf, $sF=1)  {
00833 
00834       $spacing*=$sF;
00835       $wordSpacing*=$sF;
00836 
00837       if (!$spacing && $wordSpacing)   {
00838          $bits = explode(' ',$text);
00839          reset($bits);
00840          while(list(,$word)=each($bits))  {
00841             $word.=' ';
00842             $word = $word;
00843             $wordInf = $this->ImageTTFBBoxWrapper($fontSize, $angle, $fontFile, $word, $splitRenderingConf ,$sF);
00844             $wordW = ($wordInf[2]-$wordInf[0]);
00845             $this->ImageTTFTextWrapper($im, $fontSize, $angle, $x, $y, $Fcolor, $fontFile, $word, $splitRenderingConf, $sF);
00846             $x+=$wordW+$wordSpacing;
00847          }
00848       } else {
00849          $utf8Chars = $this->singleChars($text);
00850             // For each UTF-8 char, do:
00851          foreach($utf8Chars as $char)  {
00852             $charInf = $this->ImageTTFBBoxWrapper($fontSize, $angle, $fontFile, $char, $splitRenderingConf, $sF);
00853             $charW = ($charInf[2]-$charInf[0]);
00854             $this->ImageTTFTextWrapper($im, $fontSize, $angle, $x, $y, $Fcolor, $fontFile, $char, $splitRenderingConf, $sF);
00855             $x+=$charW+(($char==' ')?$wordSpacing:$spacing);
00856          }
00857       }
00858    }
00859 
00869    function fontResize($conf) {
00870       // 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!!!!
00871       $maxWidth = intval($conf['maxWidth']);
00872       if ($maxWidth) {
00873          if ($spacing || $wordSpacing) {     // If any kind of spacing applys, we use this function:
00874             return $conf['fontSize'];
00875             //  ################ no calc for spacing yet !!!!!!
00876          } else {
00877             do {
00878                   // determine bounding box.
00879                $bounds = $this->ImageTTFBBoxWrapper($conf['fontSize'], $conf['angle'], $conf['fontFile'], $this->recodeString($conf['text']), $conf['splitRendering.']);
00880                if ($conf['angle']< 0) {
00881                   $pixelWidth = abs($bounds[4]-$bounds[0]);
00882                } elseif ($conf['angle'] > 0) {
00883                   $pixelWidth = abs($bounds[2]-$bounds[6]);
00884                } else {
00885                   $pixelWidth = abs($bounds[4]-$bounds[6]);
00886                }
00887 
00888                   // Size is fine, exit:
00889                if ($pixelWidth <= $maxWidth) {
00890                   break;
00891                } else {
00892                   $conf['fontSize']--;
00893                }
00894             } while ($conf['fontSize']>1);
00895          }//if spacing
00896       }
00897       return $conf['fontSize'];
00898    }
00899 
00911    function ImageTTFBBoxWrapper($fontSize, $angle, $fontFile, $string, $splitRendering, $sF=1)  {
00912 
00913          // Initialize:
00914       $offsetInfo = array();
00915       $stringParts = $this->splitString($string,$splitRendering,$fontSize,$fontFile);
00916 
00917          // Traverse string parts:
00918       foreach($stringParts as $strCfg) {
00919 
00920             // Calculate Bounding Box for part:
00921          $calc = ImageTTFBBox(t3lib_div::freetypeDpiComp($sF*$strCfg['fontSize']), $angle, t3lib_stdGraphic::prependAbsolutePath($strCfg['fontFile']), $strCfg['str']);
00922 
00923             // Calculate offsets:
00924          if (!count($offsetInfo))   {
00925             $offsetInfo = $calc; // First run, just copy over.
00926          } else {
00927             $offsetInfo[2]+=$calc[2]-$calc[0]+intval($splitRendering['compX'])+intval($strCfg['xSpaceBefore'])+intval($strCfg['xSpaceAfter']);
00928             $offsetInfo[3]+=$calc[3]-$calc[1]-intval($splitRendering['compY'])-intval($strCfg['ySpaceBefore'])-intval($strCfg['ySpaceAfter']);
00929             $offsetInfo[4]+=$calc[4]-$calc[6]+intval($splitRendering['compX'])+intval($strCfg['xSpaceBefore'])+intval($strCfg['xSpaceAfter']);
00930             $offsetInfo[5]+=$calc[5]-$calc[7]-intval($splitRendering['compY'])-intval($strCfg['ySpaceBefore'])-intval($strCfg['ySpaceAfter']);
00931          }
00932       }
00933 
00934       return $offsetInfo;
00935    }
00936 
00952    function ImageTTFTextWrapper($im, $fontSize, $angle, $x, $y, $color, $fontFile, $string, $splitRendering,$sF=1)   {
00953 
00954          // Initialize:
00955       $stringParts = $this->splitString($string,$splitRendering,$fontSize,$fontFile);
00956       $x = ceil($sF*$x);
00957       $y = ceil($sF*$y);
00958 
00959          // Traverse string parts:
00960       foreach($stringParts as $i => $strCfg) {
00961 
00962             // Initialize:
00963          $colorIndex = $color;
00964 
00965             // Set custom color if any (only when niceText is off):
00966          if ($strCfg['color'] && $sF==1)  {
00967             $cols = $this->convertColor($strCfg['color']);
00968             $colorIndex = ImageColorAllocate($im, $cols[0],$cols[1],$cols[2]);
00969             $colorIndex = $color >= 0 ? $colorIndex : -$colorIndex;
00970          }
00971 
00972             // Setting xSpaceBefore
00973          if ($i)  {
00974             $x+= intval($strCfg['xSpaceBefore']);
00975             $y-= intval($strCfg['ySpaceBefore']);
00976          }
00977 
00978             // Render part:
00979          ImageTTFText($im, t3lib_div::freetypeDpiComp($sF*$strCfg['fontSize']), $angle, $x, $y, $colorIndex, t3lib_stdGraphic::prependAbsolutePath($strCfg['fontFile']), $strCfg['str']);
00980 
00981             // Calculate offset to apply:
00982          $wordInf = ImageTTFBBox(t3lib_div::freetypeDpiComp($sF*$strCfg['fontSize']), $angle, t3lib_stdGraphic::prependAbsolutePath($strCfg['fontFile']), $strCfg['str']);
00983          $x+= $wordInf[2]-$wordInf[0]+intval($splitRendering['compX'])+intval($strCfg['xSpaceAfter']);
00984          $y+= $wordInf[5]-$wordInf[7]-intval($splitRendering['compY'])-intval($strCfg['ySpaceAfter']);
00985       }
00986    }
00987 
00997    function splitString($string,$splitRendering,$fontSize,$fontFile) {
00998 
00999          // Initialize by setting the whole string and default configuration as the first entry.
01000       $result = array();
01001       $result[] = array(
01002          'str' => $string,
01003          'fontSize' => $fontSize,
01004          'fontFile' => $fontFile
01005       );
01006 
01007          // Traverse the split-rendering configuration:
01008          // Splitting will create more entries in $result with individual configurations.
01009       if (is_array($splitRendering))   {
01010          $sKeyArray = t3lib_TStemplate::sortedKeyList($splitRendering);
01011 
01012             // Traverse configured options:
01013          foreach($sKeyArray as $key)   {
01014             $cfg = $splitRendering[$key.'.'];
01015 
01016                // Process each type of split rendering keyword:
01017             switch((string)$splitRendering[$key])  {
01018                case 'highlightWord':
01019                   if (strlen($cfg['value'])) {
01020                      $newResult = array();
01021 
01022                         // Traverse the current parts of the result array:
01023                      foreach($result as $part)  {
01024                            // Explode the string value by the word value to highlight:
01025                         $explodedParts = explode($cfg['value'],$part['str']);
01026                         foreach($explodedParts as $c => $expValue)   {
01027                            if (strlen($expValue))  {
01028                               $newResult[] = array_merge($part,array('str' => $expValue));
01029                            }
01030                            if ($c+1 < count($explodedParts))   {
01031                               $newResult[] = array(
01032                                  'str' => $cfg['value'],
01033                                  'fontSize' => $cfg['fontSize'] ? $cfg['fontSize'] : $part['fontSize'],
01034                                  'fontFile' => $cfg['fontFile'] ? $cfg['fontFile'] : $part['fontFile'],
01035                                  'color' => $cfg['color'],
01036                                  'xSpaceBefore' => $cfg['xSpaceBefore'],
01037                                  'xSpaceAfter' => $cfg['xSpaceAfter'],
01038                                  'ySpaceBefore' => $cfg['ySpaceBefore'],
01039                                  'ySpaceAfter' => $cfg['ySpaceAfter'],
01040                               );
01041                            }
01042                         }
01043                      }
01044 
01045                         // Set the new result as result array:
01046                      if (count($newResult))  {
01047                         $result = $newResult;
01048                      }
01049                   }
01050                break;
01051                case 'charRange':
01052                   if (strlen($cfg['value'])) {
01053 
01054                         // Initialize range:
01055                      $ranges = t3lib_div::trimExplode(',',$cfg['value'],1);
01056                      foreach($ranges as $i => $rangeDef) {
01057                         $ranges[$i] = t3lib_div::intExplode('-',$ranges[$i]);
01058                         if (!isset($ranges[$i][1]))   $ranges[$i][1] = $ranges[$i][0];
01059                      }
01060                      $newResult = array();
01061 
01062                         // Traverse the current parts of the result array:
01063                      foreach($result as $part)  {
01064 
01065                            // Initialize:
01066                         $currentState = -1;
01067                         $bankAccum = '';
01068 
01069                            // Explode the string value by the word value to highlight:
01070                         $utf8Chars = $this->singleChars($part['str']);
01071                         foreach($utf8Chars as $utfChar)  {
01072 
01073                               // Find number and evaluate position:
01074                            $uNumber = $this->csConvObj->utf8CharToUnumber($utfChar);
01075                            $inRange = 0;
01076                            foreach($ranges as $rangeDef) {
01077                               if ($uNumber >= $rangeDef[0] && (!$rangeDef[1] || $uNumber <= $rangeDef[1])) {
01078                                  $inRange = 1;
01079                                  break;
01080                               }
01081                            }
01082                            if ($currentState==-1)  $currentState = $inRange;  // Initialize first char
01083 
01084                               // Switch bank:
01085                            if ($inRange != $currentState && !t3lib_div::inList('32,10,13,9',$uNumber))   {
01086 
01087                                  // Set result:
01088                               if (strlen($bankAccum)) {
01089                                  $newResult[] = array(
01090                                     'str' => $bankAccum,
01091                                     'fontSize' => $currentState && $cfg['fontSize'] ? $cfg['fontSize'] : $part['fontSize'],
01092                                     'fontFile' => $currentState && $cfg['fontFile'] ? $cfg['fontFile'] : $part['fontFile'],
01093                                     'color' => $currentState ? $cfg['color'] : '',
01094                                     'xSpaceBefore' => $currentState ? $cfg['xSpaceBefore'] : '',
01095                                     'xSpaceAfter' => $currentState ? $cfg['xSpaceAfter'] : '',
01096                                     'ySpaceBefore' => $currentState ? $cfg['ySpaceBefore'] : '',
01097                                     'ySpaceAfter' => $currentState ? $cfg['ySpaceAfter'] : '',
01098                                  );
01099                               }
01100 
01101                                  // Initialize new settings:
01102                               $currentState = $inRange;
01103                               $bankAccum = '';
01104                            }
01105 
01106                               // Add char to bank:
01107                            $bankAccum.=$utfChar;
01108                         }
01109 
01110                            // Set result for FINAL part:
01111                         if (strlen($bankAccum)) {
01112                            $newResult[] = array(
01113                               'str' => $bankAccum,
01114                               'fontSize' => $currentState && $cfg['fontSize'] ? $cfg['fontSize'] : $part['fontSize'],
01115                               'fontFile' => $currentState && $cfg['fontFile'] ? $cfg['fontFile'] : $part['fontFile'],
01116                               'color' => $currentState ? $cfg['color'] : '',
01117                               'xSpaceBefore' => $currentState ? $cfg['xSpaceBefore'] : '',
01118                               'xSpaceAfter' => $currentState ? $cfg['xSpaceAfter'] : '',
01119                               'ySpaceBefore' => $currentState ? $cfg['ySpaceBefore'] : '',
01120                               'ySpaceAfter' => $currentState ? $cfg['ySpaceAfter'] : '',
01121                            );
01122                         }
01123                      }
01124 
01125                         // Set the new result as result array:
01126                      if (count($newResult))  {
01127                         $result = $newResult;
01128                      }
01129                   }
01130                break;
01131             }
01132          }
01133       }
01134 
01135       return $result;
01136    }
01137 
01138 
01139 
01140 
01141 
01142 
01143 
01144 
01145 
01146 
01147 
01148 
01149 
01150 
01151 
01152    /*********************************************
01153     *
01154     * Other GIFBUILDER objects related to TEXT
01155     *
01156     *********************************************/
01157 
01168    function makeOutline(&$im,$conf,$workArea,$txtConf)   {
01169       $thickness = intval($conf['thickness']);
01170       if ($thickness)   {
01171          $txtConf['fontColor'] = $conf['color'];
01172          $outLineDist = t3lib_div::intInRange($thickness,1,2);
01173          for ($b=1;$b<=$outLineDist;$b++) {
01174             if ($b==1)  {
01175                $it = 8;
01176             } else {
01177                $it = 16;
01178             }
01179             $outL = $this->circleOffset($b, $it);
01180             for ($a=0;$a<$it;$a++)  {
01181                $this->makeText($im,$txtConf,$this->applyOffset($workArea,$outL[$a]));
01182             }
01183          }
01184       }
01185    }
01186 
01197    function circleOffset($distance, $iterations)   {
01198       $res = Array();
01199       if ($distance && $iterations) {
01200          for ($a=0;$a<$iterations;$a++)   {
01201             $yOff = round(sin(2*pi()/$iterations*($a+1))*100*$distance);
01202             if ($yOff)  {$yOff = intval(ceil(abs($yOff/100))*($yOff/abs($yOff)));}
01203             $xOff = round(cos(2*pi()/$iterations*($a+1))*100*$distance);
01204             if ($xOff)  {$xOff = intval(ceil(abs($xOff/100))*($xOff/abs($xOff)));}
01205             $res[$a] = Array($xOff,$yOff);
01206          }
01207       }
01208       return $res;
01209    }
01210 
01221    function makeEmboss(&$im,$conf,$workArea,$txtConf) {
01222       $conf['color']=$conf['highColor'];
01223       $this->makeShadow($im,$conf,$workArea,$txtConf);
01224       $newOffset = t3lib_div::intExplode(',',$conf['offset']);
01225       $newOffset[0]*=-1;
01226       $newOffset[1]*=-1;
01227       $conf['offset']=implode(',',$newOffset);
01228       $conf['color']=$conf['lowColor'];
01229       $this->makeShadow($im,$conf,$workArea,$txtConf);
01230    }
01231 
01243    function makeShadow(&$im,$conf,$workArea,$txtConf) {
01244       $workArea = $this->applyOffset($workArea,t3lib_div::intExplode(',',$conf['offset']));
01245       $blurRate = t3lib_div::intInRange(intval($conf['blur']),0,99);
01246 
01247       if (!$blurRate || $this->NO_IM_EFFECTS)   {     // No effects if ImageMagick ver. 5+
01248          $txtConf['fontColor'] = $conf['color'];
01249          $this->makeText($im,$txtConf,$workArea);
01250       } else {
01251          $w = imagesx($im);
01252          $h = imagesy($im);
01253          $blurBorder= 3;   // area around the blur used for cropping something
01254          $tmpStr = $this->randomName();
01255          $fileMenu = $tmpStr.'_menu.'.$this->gifExtension;
01256          $fileColor = $tmpStr.'_color.'.$this->gifExtension;
01257          $fileMask = $tmpStr.'_mask.'.$this->gifExtension;
01258 
01259             // BlurColor Image laves
01260          $blurColImg = imagecreate($w,$h);
01261          $bcols=$this->convertColor($conf['color']);
01262          ImageColorAllocate($blurColImg, $bcols[0],$bcols[1],$bcols[2]);
01263          $this->ImageGif($blurColImg, $fileColor);
01264          ImageDestroy($blurColImg);
01265 
01266             // The mask is made: BlurTextImage
01267          $blurTextImg = imagecreate($w+$blurBorder*2,$h+$blurBorder*2);
01268          ImageColorAllocate($blurTextImg, 0,0,0);     // black background
01269          $txtConf['fontColor'] = 'white';
01270          $blurBordArr = Array($blurBorder,$blurBorder);
01271          $this->makeText($blurTextImg,$txtConf,  $this->applyOffset($workArea,$blurBordArr));
01272          $this->ImageGif($blurTextImg, $fileMask); // dump to temporary file
01273          ImageDestroy($blurTextImg);   // destroy
01274 
01275 
01276          $command='';
01277          $command.=$this->maskNegate;
01278 
01279          if ($this->V5_EFFECTS)  {
01280             $command.=$this->v5_blur($blurRate+1);
01281          } else {
01282                // Blurring of the mask
01283             $times = ceil($blurRate/10);  // How many blur-commands that is executed. Min = 1;
01284             $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.
01285             $newBlurRate = t3lib_div::intInRange($newBlurRate,1,99);
01286             for ($a=0;$a<$times;$a++)  {     // Building blur-command
01287                $command.=' -blur '.$blurRate;
01288             }
01289          }
01290 
01291          $this->imageMagickExec($fileMask,$fileMask,$command);
01292 
01293          $blurTextImg_tmp = $this->imageCreateFromGif($fileMask); // the mask is loaded again
01294          if ($blurTextImg_tmp)   {  // if nothing went wrong we continue with the blurred mask
01295 
01296                // cropping the border from the mask
01297             $blurTextImg = imagecreate($w,$h);
01298             $this->imagecopyresized($blurTextImg, $blurTextImg_tmp, 0, 0, $blurBorder, $blurBorder, $w, $h, $w, $h);
01299             ImageDestroy($blurTextImg_tmp);  // Destroy the temporary mask
01300 
01301                // adjust the mask
01302             $intensity = 40;
01303             if ($conf['intensity']) {
01304                $intensity = t3lib_div::intInRange($conf['intensity'],0,100);
01305             }
01306             $intensity = ceil(255-($intensity/100*255));
01307             $this->inputLevels($blurTextImg,0,$intensity,$this->maskNegate);
01308 
01309             $opacity = t3lib_div::intInRange(intval($conf['opacity']),0,100);
01310             if ($opacity && $opacity<100) {
01311                $high = ceil(255*$opacity/100);
01312                $this->outputLevels($blurTextImg,0,$high,$this->maskNegate);   // reducing levels as the opacity demands
01313             }
01314 
01315             $this->ImageGif($blurTextImg, $fileMask); // Dump the mask again
01316             ImageDestroy($blurTextImg);   // Destroy the mask
01317 
01318                // The pictures are combined
01319             $this->ImageGif($im, $fileMenu); // The main pictures is saved temporarily
01320 
01321             $this->combineExec($fileMenu,$fileColor,$fileMask,$fileMenu);
01322 
01323             $backIm = $this->imageCreateFromGif($fileMenu); // The main image is loaded again...
01324             if ($backIm)   {  // ... and if nothing went wrong we load it onto the old one.
01325                ImageColorTransparent($backIm,-1);
01326                $im = $backIm;
01327             }
01328          }
01329             // Deleting temporary files;
01330          if (!$this->dontUnlinkTempFiles) {
01331             unlink($fileMenu);
01332             unlink($fileColor);
01333             unlink($fileMask);
01334          }
01335       }
01336    }
01337 
01338 
01339 
01340 
01341 
01342 
01343 
01344 
01345 
01346 
01347 
01348 
01349 
01350 
01351 
01352 
01353 
01354 
01355 
01356 
01357 
01358    /****************************
01359     *
01360     * Other GIFBUILDER objects
01361     *
01362     ****************************/
01363 
01373    function makeBox(&$im,$conf,$workArea) {
01374       $cords = t3lib_div::intExplode(',',$conf['dimensions'].',,,');
01375       $conf['offset']=$cords[0].','.$cords[1];
01376       $cords = $this->objPosition($conf,$workArea,Array($cords[2],$cords[3]));
01377       $cols=$this->convertColor($conf['color']);
01378       $this->reduceColors($im,256, 255);
01379       $tmpColor = ImageColorAllocate($im, $cols[0],$cols[1],$cols[2]);
01380       imagefilledrectangle($im, $cords[0], $cords[1], $cords[0]+$cords[2]-1, $cords[1]+$cords[3]-1, $tmpColor);
01381    }
01382 
01392    function makeEffect(&$im, $conf) {
01393       $commands = $this->IMparams($conf['value']);
01394       if ($commands) {
01395          $this->applyImageMagickToPHPGif($im, $commands);
01396       }
01397    }
01398 
01407    function IMparams($setup)  {
01408       if (!trim($setup)){return '';}
01409       $effects = explode('|', $setup);
01410       $commands = '';
01411       while(list(,$val)=each($effects))   {
01412          $pairs=explode('=',$val,2);
01413          $value = trim($pairs[1]);
01414          $effect = strtolower(trim($pairs[0]));
01415          switch($effect)   {
01416             case 'gamma':
01417                $commands.=' -gamma '.doubleval($value);
01418             break;
01419             case 'blur':
01420                if (!$this->NO_IM_EFFECTS) {
01421                   if ($this->V5_EFFECTS)  {
01422                      $commands.=$this->v5_blur($value);
01423                   } else {
01424                      $commands.=' -blur '.t3lib_div::intInRange($value,1,99);
01425                   }
01426                }
01427             break;
01428             case 'sharpen':
01429                if (!$this->NO_IM_EFFECTS) {
01430                   if ($this->V5_EFFECTS)  {
01431                      $commands.=$this->v5_sharpen($value);
01432                   } else {
01433                      $commands.=' -sharpen '.t3lib_div::intInRange($value,1,99);
01434                   }
01435                }
01436             break;
01437             case 'rotate':
01438                $commands.=' -rotate '.t3lib_div::intInRange($value,0,360);
01439             break;
01440             case 'solarize':
01441                $commands.=' -solarize '.t3lib_div::intInRange($value,0,99);
01442             break;
01443             case 'swirl':
01444                $commands.=' -swirl '.t3lib_div::intInRange($value,0,1000);
01445             break;
01446             case 'wave':
01447                $params = t3lib_div::intExplode(',',$value);
01448                $commands.=' -wave '.t3lib_div::intInRange($params[0],0,99).'x'.t3lib_div::intInRange($params[1],0,99);
01449             break;
01450             case 'charcoal':
01451                $commands.=' -charcoal '.t3lib_div::intInRange($value,0,100);
01452             break;
01453             case 'gray':
01454                $commands.=' -colorspace GRAY';
01455             break;
01456             case 'edge':
01457                $commands.=' -edge '.t3lib_div::intInRange($value,0,99);
01458             break;
01459             case 'emboss':
01460                $commands.=' -emboss';
01461             break;
01462             case 'flip':
01463                $commands.=' -flip';
01464             break;
01465             case 'flop':
01466                $commands.=' -flop';
01467             break;
01468             case 'colors':
01469                $commands.=' -colors '.t3lib_div::intInRange($value,2,255);
01470             break;
01471             case 'shear':
01472                $commands.=' -shear '.t3lib_div::intInRange($value,-90,90);
01473             break;
01474             case 'invert':
01475                $commands.=' -negate';
01476             break;
01477          }
01478       }
01479       return $commands;
01480    }
01481 
01490    function adjust(&$im, $conf)  {
01491       $setup = $conf['value'];
01492       if (!trim($setup)){return '';}
01493       $effects = explode('|', $setup);
01494       while(list(,$val)=each($effects))   {
01495          $pairs=explode('=',$val,2);
01496          $value = trim($pairs[1]);
01497          $effect = strtolower(trim($pairs[0]));
01498          switch($effect)   {
01499             case 'inputlevels':  // low,high
01500                $params = t3lib_div::intExplode(',',$value);
01501                $this->inputLevels($im,$params[0],$params[1]);
01502             break;
01503             case 'outputlevels':
01504                $params = t3lib_div::intExplode(',',$value);
01505                $this->outputLevels($im,$params[0],$params[1]);
01506             break;
01507             case 'autolevels':
01508                $this->autoLevels($im);
01509             break;
01510          }
01511       }
01512    }
01513 
01522    function crop(&$im,$conf)  {
01523       $this->setWorkArea(''); // clears workArea to total image
01524       $cords = t3lib_div::intExplode(',',$conf['crop'].',,,');
01525       $conf['offset']=$cords[0].','.$cords[1];
01526       $cords = $this->objPosition($conf,$this->workArea,Array($cords[2],$cords[3]));
01527 
01528       $newIm = imagecreate($cords[2],$cords[3]);
01529       $cols=$this->convertColor($conf['backColor']?$conf['backColor']:$this->setup['backColor']);
01530       ImageColorAllocate($newIm, $cols[0],$cols[1],$cols[2]);
01531 
01532       $newConf = Array();
01533       $workArea = Array(0,0,$cords[2],$cords[3]);
01534       if ($cords[0]<0) {$workArea[0]=abs($cords[0]);} else {$newConf['offset']=-$cords[0];}
01535       if ($cords[1]<0) {$workArea[1]=abs($cords[1]);} else {$newConf['offset'].=','.-$cords[1];}
01536 
01537       $this->copyGifOntoGif($newIm,$im,$newConf,$workArea);
01538       $im = $newIm;
01539       $this->w = imagesx($im);
01540       $this->h = imagesy($im);
01541       $this->setWorkArea(''); // clears workArea to total image
01542    }
01543 
01552    function scale(&$im,$conf) {
01553       if ($conf['width'] || $conf['height'] || $conf['params'])   {
01554          $tmpStr = $this->randomName();
01555          $theFile = $tmpStr.'.'.$this->gifExtension;
01556          $this->ImageGif($im, $theFile);
01557          $theNewFile = $this->imageMagickConvert($theFile,$this->gifExtension,$conf['width'],$conf['height'],$conf['params'],'','');
01558          $tmpImg = $this->imageCreateFromGif($theNewFile[3]);
01559          if ($tmpImg)   {
01560             ImageDestroy($im);
01561             $im = $tmpImg;
01562             $this->w = imagesx($im);
01563             $this->h = imagesy($im);
01564             $this->setWorkArea(''); // clears workArea to total image
01565          }
01566          if (!$this->dontUnlinkTempFiles) {
01567             unlink($theFile);
01568             if ($theNewFile[3] && $theNewFile[3]!=$theFile) {
01569                unlink($theNewFile[3]);
01570             }
01571          }
01572       }
01573    }
01574 
01584    function setWorkArea($workArea)  {
01585       $this->workArea = t3lib_div::intExplode(',',$workArea);
01586       $this->workArea = $this->applyOffset($this->workArea,$this->OFFSET);
01587       if (!$this->workArea[2])   {$this->workArea[2]=$this->w;}
01588       if (!$this->workArea[3])   {$this->workArea[3]=$this->h;}
01589    }
01590 
01591 
01592 
01593 
01594 
01595 
01596 
01597 
01598 
01599 
01600 
01601 
01602 
01603 
01604 
01605 
01606 
01607 
01608 
01609 
01610 
01611 
01612 
01613    /*************************
01614     *
01615     * Adjustment functions
01616     *
01617     ************************/
01618 
01625    function autolevels(&$im)  {
01626       $totalCols = ImageColorsTotal($im);
01627       $min=255;
01628       $max=0;
01629       for ($c=0; $c<$totalCols; $c++)  {
01630          $cols = ImageColorsForIndex($im,$c);
01631          $grayArr[] = round(($cols['red']+$cols['green']+$cols['blue'])/3);
01632       }
01633       $min=min($grayArr);
01634       $max=max($grayArr);
01635       $delta = $max-$min;
01636       if ($delta) {
01637          for ($c=0; $c<$totalCols; $c++)  {
01638             $cols = ImageColorsForIndex($im,$c);
01639             $cols['red'] = floor(($cols['red']-$min)/$delta*255);
01640             $cols['green'] = floor(($cols['green']-$min)/$delta*255);
01641             $cols['blue'] = floor(($cols['blue']-$min)/$delta*255);
01642             ImageColorSet($im,$c,$cols['red'],$cols['green'],$cols['blue']);
01643          }
01644       }
01645    }
01646 
01656    function outputLevels(&$im,$low,$high,$swap='') {
01657       if ($low<$high){
01658          $low = t3lib_div::intInRange($low,0,255);
01659          $high = t3lib_div::intInRange($high,0,255);
01660 
01661          if ($swap)  {
01662             $temp = $low;
01663             $low = 255-$high;
01664             $high = 255-$temp;
01665          }
01666 
01667          $delta = $high-$low;
01668          $totalCols = ImageColorsTotal($im);
01669          for ($c=0; $c<$totalCols; $c++)  {
01670             $cols = ImageColorsForIndex($im,$c);
01671             $cols['red'] = $low+floor($cols['red']/255*$delta);
01672             $cols['green'] = $low+floor($cols['green']/255*$delta);
01673             $cols['blue'] = $low+floor($cols['blue']/255*$delta);
01674             ImageColorSet($im,$c,$cols['red'],$cols['green'],$cols['blue']);
01675          }
01676       }
01677    }
01678 
01688    function inputLevels(&$im,$low,$high,$swap='')  {
01689       if ($low<$high){
01690          $low = t3lib_div::intInRange($low,0,255);
01691          $high = t3lib_div::intInRange($high,0,255);
01692 
01693          if ($swap)  {
01694             $temp = $low;
01695             $low = 255-$high;
01696             $high = 255-$temp;
01697          }
01698 
01699          $delta = $high-$low;
01700          $totalCols = ImageColorsTotal($im);
01701          for ($c=0; $c<$totalCols; $c++)  {
01702             $cols = ImageColorsForIndex($im,$c);
01703             $cols['red'] = t3lib_div::intInRange(($cols['red']-$low)/$delta*255, 0,255);
01704             $cols['green'] = t3lib_div::intInRange(($cols['green']-$low)/$delta*255, 0,255);
01705             $cols['blue'] = t3lib_div::intInRange(($cols['blue']-$low)/$delta*255, 0,255);
01706             ImageColorSet($im,$c,$cols['red'],$cols['green'],$cols['blue']);
01707          }
01708       }
01709    }
01710 
01719    function reduceColors(&$im,$limit, $cols) {
01720       if (ImageColorsTotal($im)>=$limit)  {
01721          $this->makeEffect($im, Array('value'=>'colors='.$cols) );
01722       }
01723    }
01724 
01725 
01726 
01727 
01728 
01729 
01730 
01731 
01732 
01733 
01734 
01735 
01736 
01737 
01738 
01739 
01740 
01741 
01742 
01743    /*********************************
01744     *
01745     * GIFBUILDER Helper functions
01746     *
01747     *********************************/
01748 
01757    function prependAbsolutePath($fontFile)   {
01758       $absPath = defined('PATH_typo3') ? dirname(PATH_thisScript).'/' :PATH_site;
01759       $fontFile = t3lib_div::isAbsPath($fontFile) ? $fontFile : $absPath.$fontFile;
01760       return $fontFile;
01761    }
01762 
01771    function v5_sharpen($factor)  {
01772       $factor = t3lib_div::intInRange(ceil($factor/10),0,10);
01773 
01774       $sharpenArr=explode(',',','.$this->im5fx_sharpenSteps);
01775       $sharpenF= trim($sharpenArr[$factor]);
01776       if ($sharpenF) {
01777          $cmd = ' -sharpen '.$sharpenF;
01778          return $cmd;
01779       }
01780    }
01781 
01790    function v5_blur($factor)  {
01791       $factor = t3lib_div::intInRange(ceil($factor/10),0,10);
01792 
01793       $blurArr=explode(',',','.$this->im5fx_blurSteps);
01794       $blurF= trim($blurArr[$factor]);
01795       if ($blurF) {
01796          $cmd=' -blur '.$blurF;
01797          return $cmd;
01798       }
01799    }
01800 
01807    function randomName()   {
01808       $this->createTempSubDir('temp/');
01809       return $this->tempPath.'temp/'.md5(uniqid(''));
01810    }
01811 
01820    function applyOffset($cords,$OFFSET)   {
01821       $cords[0] = intval($cords[0])+intval($OFFSET[0]);
01822       $cords[1] = intval($cords[1])+intval($OFFSET[1]);
01823       return $cords;
01824    }
01825 
01833    function convertColor($string)   {
01834       $col=array();
01835       $cParts = explode(':',$string,2);
01836 
01837          // Finding the RGB definitions of the color:
01838       $string=$cParts[0];
01839       if (strstr($string,'#'))   {
01840          $string = ereg_replace('[^A-Fa-f0-9]*','',$string);
01841          $col[]=HexDec(substr($string,0,2));
01842          $col[]=HexDec(substr($string,2,2));
01843          $col[]=HexDec(substr($string,4,2));
01844       } elseif (strstr($string,','))   {
01845          $string = ereg_replace('[^,0-9]*','',$string);
01846          $strArr = explode(',',$string);
01847          $col[]=intval($strArr[0]);
01848          $col[]=intval($strArr[1]);
01849          $col[]=intval($strArr[2]);
01850       } else {
01851          $string = strtolower(trim($string));
01852          if ($this->colMap[$string])   {
01853             $col = $this->colMap[$string];
01854          } else {
01855             $col = Array(0,0,0);
01856          }
01857       }
01858          // ... and possibly recalculating the value
01859       if (trim($cParts[1]))   {
01860          $cParts[1]=trim($cParts[1]);
01861          if (substr($cParts[1],0,1)=='*') {
01862             $val=doubleval(substr($cParts[1],1));
01863             $col[0]=t3lib_div::intInRange($col[0]*$val,0,255);
01864             $col[1]=t3lib_div::intInRange($col[1]*$val,0,255);
01865             $col[2]=t3lib_div::intInRange($col[2]*$val,0,255);
01866          } else {
01867             $val=intval($cParts[1]);
01868             $col[0]=t3lib_div::intInRange($col[0]+$val,0,255);
01869             $col[1]=t3lib_div::intInRange($col[1]+$val,0,255);
01870             $col[2]=t3lib_div::intInRange($col[2]+$val,0,255);
01871          }
01872       }
01873       return $col;
01874    }
01875 
01883    function recodeString($string)   {
01884          // Recode string to UTF-8 from $this->nativeCharset:
01885       if ($this->nativeCharset && $this->nativeCharset!='utf-8')  {
01886          $string = $this->csConvObj->utf8_encode($string,$this->nativeCharset);  // Convert to UTF-8
01887       }
01888 
01889          // Recode string accoding to TTFLocaleConv. Depreciated.
01890       if ($this->TTFLocaleConv)  {
01891          $string = recode_string($this->TTFLocaleConv,$string);
01892       }
01893 
01894       return $string;
01895    }
01896 
01905    function singleChars($theText,$returnUnicodeNumber=FALSE)   {
01906       if ($this->nativeCharset)  {
01907          return $this->csConvObj->utf8_to_numberarray($theText,1,$returnUnicodeNumber ? 0 : 1); // Get an array of separated UTF-8 chars
01908       } else {
01909          $output=array();
01910          $c=strlen($theText);
01911          for($a=0;$a<$c;$a++) {
01912             $output[]=substr($theText,$a,1);
01913          }
01914          return $output;
01915       }
01916    }
01917 
01928    function objPosition($conf,$workArea,$BB) {
01929          // offset, align, valign, workarea
01930       $result=Array();
01931       $result[2] = $BB[0];
01932       $result[3] = $BB[1];
01933       $w=$workArea[2];
01934       $h=$workArea[3];
01935 
01936       $align = explode(',',$conf['align']);
01937       $align[0] = strtolower(substr(trim($align[0]),0,1));
01938       $align[1] = strtolower(substr(trim($align[1]),0,1));
01939 
01940       switch($align[0]) {
01941          case 'r':
01942             $result[0]=$w-$result[2];
01943          break;
01944          case 'c':
01945             $result[0] = round(($w-$result[2])/2);
01946          break;
01947          default:
01948             $result[0] = 0;
01949          break;
01950       }
01951       switch($align[1]) {
01952          case 'b':
01953             $result[1] = $h-$result[3];   // y pos
01954          break;
01955          case 'c':
01956             $result[1] = round(($h-$result[3])/2);
01957          break;
01958          default:
01959             $result[1]=0;
01960          break;
01961       }
01962       $result = $this->applyOffset($result,t3lib_div::intExplode(',',$conf['offset']));
01963       $result = $this->applyOffset($result,$workArea);
01964       return $result;
01965    }
01966 
01967 
01968 
01969 
01970 
01971 
01972 
01973 
01974 
01975 
01976 
01977 
01978 
01979 
01980 
01981 
01982 
01983 
01984 
01985 
01986 
01987    /***********************************
01988     *
01989     * Scaling, Dimensions of images
01990     *
01991     ***********************************/
01992 
02007    function imageMagickConvert($imagefile,$newExt='',$w='',$h='',$params='',$frame='',$options='',$mustCreate=0)  {
02008       if ($this->NO_IMAGE_MAGICK)   {
02009             // Returning file info right away
02010          return $this->getImageDimensions($imagefile);
02011       }
02012 
02013       if($info=$this->getImageDimensions($imagefile)) {
02014          $newExt=strtolower(trim($newExt));
02015          if (!$newExt)  {  // If no extension is given the original extension is used
02016             $newExt = $info[2];
02017          }
02018          if ($newExt=='web')  {
02019             if (t3lib_div::inList($this->webImageExt,$info[2]))   {
02020                $newExt = $info[2];
02021             } else {
02022                $newExt = $this->gif_or_jpg($info[2],$info[0],$info[1]);
02023                if (!$params)  {
02024                   $params = $this->cmds[$newExt];
02025                }
02026             }
02027          }
02028          if (t3lib_div::inList($this->imageFileExt,$newExt))   {
02029             if (strstr($w.$h, 'm')) {$max=1;} else {$max=0;}
02030 
02031             $data = $this->getImageScale($info,$w,$h,$options);
02032             $w=$data['origW'];
02033             $h=$data['origH'];
02034 
02035                // if no convertion should be performed
02036             $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....
02037 
02038             if ($wh_noscale && !$params && !$frame && $newExt==$info[2] && !$mustCreate) {
02039                $info[3] = $imagefile;
02040                return $info;
02041             }
02042             $info[0]=$data[0];
02043             $info[1]=$data[1];
02044 
02045             $frame = $this->noFramePrepended ? '' : '['.intval($frame).']';
02046 
02047             if (!$params)  {
02048                $params = $this->cmds[$newExt];
02049             }
02050 
02051             $command = $this->scalecmd.' '.$info[0].'x'.$info[1].'! '.$params.' ';
02052 
02053             if ($this->alternativeOutputKey) {
02054                $theOutputName = t3lib_div::shortMD5($command.basename($imagefile).$this->alternativeOutputKey.$frame);
02055             } else {
02056                $theOutputName = t3lib_div::shortMD5($command.$imagefile.filemtime($imagefile).$frame);
02057             }
02058             if ($this->imageMagickConvert_forceFileNameBody)   {
02059                $theOutputName = $this->imageMagickConvert_forceFileNameBody;
02060                $this->imageMagickConvert_forceFileNameBody='';
02061             }
02062 
02063                // Making the temporary filename:
02064             $this->createTempSubDir('pics/');
02065             $output = $this->absPrefix.$this->tempPath.'pics/'.$this->filenamePrefix.$theOutputName.'.'.$newExt;
02066 
02067                // Register temporary filename:
02068             $GLOBALS['TEMP_IMAGES_ON_PAGE'][] = $output;
02069 
02070             if (!$this->file_exists_typo3temp_file($output,$imagefile) || $this->dontCheckForExistingTempFile) {
02071                $this->imageMagickExec($imagefile.$frame,$output,$command);
02072             }
02073             if (@file_exists($output)) {
02074                $info[3] = $output;
02075                $info[2] = $newExt;
02076                if ($params)   {  // params could realisticly change som imagedata!
02077                   $info=$this->getImageDimensions($info[3]);
02078                }
02079                if ($info[2]==$this->gifExtension && !$this->dontCompress)  {
02080                   t3lib_div::gif_compress($info[3],'');     // Compress with IM (lzw) or GD (rle)  (Workaround for the absence of lzw-compression in GD)
02081                }
02082                return $info;
02083             }
02084          }
02085       }
02086    }
02087 
02095    function getImageDimensions($imageFile)   {
02096       ereg('([^\.]*)$',$imageFile,$reg);
02097       if (@file_exists($imageFile) && t3lib_div::inList($this->imageFileExt,strtolower($reg[0])))  {
02098          if ($returnArr = $this->getCachedImageDimensions($imageFile))  {
02099             return $returnArr;
02100          } else {
02101             if ($temp = @getImageSize($imageFile)) {
02102                $returnArr = Array($temp[0], $temp[1], strtolower($reg[0]), $imageFile);
02103             } else {
02104                $returnArr = $this->imageMagickIdentify($imageFile);
02105             }
02106             if ($returnArr) {
02107                $this->cacheImageDimensions($returnArr);
02108                return $returnArr;
02109             }
02110          }
02111       }
02112       return false;
02113    }
02114 
02123    function cacheImageDimensions($identifyResult)  {
02124       global $TYPO3_DB;
02125          // Create a md5 hash of the filename
02126       if (function_exists('md5_file')) {
02127          $md5Hash = md5_file($identifyResult[3]);
02128       } else {
02129          $md5Hash = md5 (t3lib_div::getURL($identifyResult[3]));
02130       }
02131       if ($md5Hash) {
02132          $fieldArr = array (
02133             'md5hash' => $md5Hash,
02134             'md5filename' => md5($identifyResult[3]),
02135             'tstamp' => time(),
02136             'filename' => $identifyResult[3],
02137             'imagewidth' => $identifyResult[0],
02138             'imageheight' => $identifyResult[1],
02139          );
02140          $TYPO3_DB->exec_INSERTquery('cache_imagesizes', $fieldArr);
02141          if (!$err = $TYPO3_DB->sql_error()) {
02142             return true;
02143          }
02144       }
02145       return false;
02146    }
02147 
02155    function getCachedImageDimensions($imageFile)   {
02156       global $TYPO3_DB;
02157          // Create a md5 hash of the filename
02158       if(function_exists('md5_file')) {
02159          $md5Hash = md5_file($imageFile);
02160       } else {
02161          $md5Hash = md5(t3lib_div::getURL ($imageFile));
02162       }
02163       ereg('([^\.]*)$',$imageFile,$reg);
02164       $res = $TYPO3_DB->exec_SELECTquery ('md5hash, imagewidth, imageheight', 'cache_imagesizes', 'md5filename="'.md5($imageFile).'"');
02165       if ($res) {
02166          if ($row = $TYPO3_DB->sql_fetch_assoc($res)) {
02167             if ($row['md5hash']!=$md5Hash) {
02168                   // file has changed, delete the row
02169                $TYPO3_DB->exec_DELETEquery ('cache_imagesizes', 'md5hash="'.$TYPO3_DB->quoteStr($row['md5hash'], 'cache_imagesizes').'"');
02170             } else {
02171                return (array($row['imagewidth'], $row['imageheight'], strtolower($reg[0]), $imageFile));
02172             }
02173          }
02174       }
02175       return false;
02176    }
02177 
02189    function getImageScale($info,$w,$h,$options) {
02190       if (strstr($w.$h, 'm')) {$max=1;} else {$max=0;}
02191       $w=intval($w);
02192       $h=intval($h);
02193          // if there are max-values...
02194       if ($options['maxW'])   {
02195          if ($w) {   // if width is given...
02196             if ($w>$options['maxW']) {
02197                $w=$options['maxW'];
02198                $max=1;  // height should follow
02199             }
02200          } else {
02201             if ($info[0]>$options['maxW']) {
02202                $w=$options['maxW'];
02203                $max=1; // height should follow
02204             }
02205          }
02206       }
02207       if ($options['maxH'])   {
02208          if ($h) {   // if height is given...
02209             if ($h>$options['maxH']) {
02210                $h=$options['maxH'];
02211                $max=1;  // height should follow
02212             }
02213          } else {
02214             if ($info[1]>$options['maxH']) { // Changed [0] to [1] 290801
02215                $h=$options['maxH'];
02216                $max=1; // height should follow
02217             }
02218          }
02219       }
02220       $out['origW']=$w;
02221       $out['origH']=$h;
02222       $out['max'] = $max;
02223 
02224       if (!$this->mayScaleUp) {
02225          if ($w>$info[0]){$w=$info[0];}
02226          if ($h>$info[1]){$h=$info[1];}
02227       }
02228       if ($w || $h)  {  // if scaling should be performed
02229          if ($w && !$h) {
02230             $info[1] = ceil($info[1]*($w/$info[0]));
02231             $info[0] = $w;
02232          }
02233          if (!$w && $h) {
02234             $info[0] = ceil($info[0]*($h/$info[1]));
02235             $info[1] = $h;
02236          }
02237          if ($w && $h)  {
02238             if ($max)   {
02239                $ratio = $info[0]/$info[1];
02240                if ($h*$ratio > $w) {
02241                   $h = round($w/$ratio);
02242                } else {
02243                   $w = round($h*$ratio);
02244                }
02245             }
02246             $info[0] = $w;
02247             $info[1] = $h;
02248          }
02249       }
02250       $out[0]=$info[0];
02251       $out[1]=$info[1];
02252          // Set minimum-measures!
02253       if ($options['minW'] && $out[0]<$options['minW'])  {
02254          if ($max && $out[0]) {
02255             $out[1]= round($out[1]*$options['minW']/$out[0]);
02256          }
02257          $out[0]=$options['minW'];
02258       }
02259       if ($options['minH'] && $out[1]<$options['minH'])  {
02260          if ($max && $out[1]) {
02261             $out[0]= round($out[0]*$options['minH']/$out[1]);
02262          }
02263          $out[1]=$options['minH'];
02264       }
02265 
02266       return $out;
02267    }
02268 
02277    function file_exists_typo3temp_file($output,$orig='') {
02278       if ($this->enable_typo3temp_db_tracking)  {
02279          if (@file_exists($output)) {  // If file exists, then we return immediately
02280             return 1;
02281          } else { // If not, we look up in the cache_typo3temp_log table to see if there is a image being rendered right now.
02282             $md5Hash=md5($output);
02283             $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('md5hash', 'cache_typo3temp_log', 'md5hash="'.$GLOBALS['TYPO3_DB']->quoteStr($md5Hash, 'cache_typo3temp_log').'" AND tstamp>'.(time()-30));
02284             if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))  {  // If there was a record, the image is being generated by another proces (we assume)
02285                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...)
02286                if (is_object($GLOBALS['TT']))   $GLOBALS['TT']->setTSlogMessage('typo3temp_log: Assume this file is being rendered now: '.$output);
02287                return 2;   // Return 'success - 2'
02288             } 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.
02289 
02290                $insertFields = array(
02291                   'md5hash' => $md5Hash,
02292                   'tstamp' => time(),
02293                   'filename' => $output,
02294                   'orig_filename' => $orig
02295                );
02296                $GLOBALS['TYPO3_DB']->exec_DELETEquery('cache_typo3temp_log', 'md5hash="'.$GLOBALS['TYPO3_DB']->quoteStr($md5Hash, 'cache_typo3temp_log').'"');
02297                $GLOBALS['TYPO3_DB']->exec_INSERTquery('cache_typo3temp_log', $insertFields);
02298 
02299                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);
02300                return 0;
02301             }
02302          }
02303       } else {
02304          return @file_exists($output);
02305       }
02306    }
02307 
02308 
02309 
02310 
02311 
02312 
02313 
02314 
02315 
02316 
02317 
02318 
02319 
02320 
02321 
02322 
02323 
02324 
02325    /***********************************
02326     *
02327     * ImageMagick API functions
02328     *
02329     ***********************************/
02330 
02338    function imageMagickIdentify($imagefile)  {
02339       if (!$this->NO_IMAGE_MAGICK)  {
02340          $frame = $this->noFramePrepended?'':'[0]';
02341          $cmd = $this->imageMagickPath.'identify '.$this->wrapFileName($imagefile).$frame;
02342          exec($cmd, $returnVal);
02343          $splitstring=$returnVal[0];
02344          $this->IM_commands[] = Array ('identify',$cmd,$returnVal[0]);
02345          if ($splitstring) {
02346             ereg('([^\.]*)$',$imagefile,$reg);
02347             $splitinfo = explode(' ', $splitstring);
02348             while (list($key,$val) = each($splitinfo))   {
02349                $temp = '';
02350                if ($val) {$temp = explode('x', $val);}
02351                if (intval($temp[0]) && intval($temp[1])) {
02352                   $dim=$temp;
02353                   break;
02354                }
02355             }
02356             if ($dim[0] && $dim[1]) {
02357                return Array($dim[0], $dim[1], strtolower($reg[0]), $imagefile);
02358             }
02359          }
02360       }
02361    }
02362 
02372    function imageMagickExec($input,$output,$params)   {
02373       if (!$this->NO_IMAGE_MAGICK)  {
02374          $cmd = $this->imageMagickPath.'convert '.$params.' '.$this->wrapFileName($input).' '.$this->wrapFileName($output);
02375          $this->IM_commands[] = Array ($output,$cmd);
02376          return exec($cmd);
02377       }
02378    }
02379 
02390    function combineExec($input,$overlay,$mask,$output)   {
02391       if (!$this->NO_IMAGE_MAGICK)  {
02392          $cmd = $this->imageMagickPath.$this->combineScript.' -compose over '.$this->wrapFileName($input).' '.$this->wrapFileName($overlay).' '.$this->wrapFileName($mask).' '.$this->wrapFileName($output);
02393          $this->IM_commands[] = Array ($output,$cmd);
02394          exec($cmd);
02395       }
02396    }
02397 
02405    function wrapFileName($inputName)   {
02406       if (strstr($inputName,' '))   {
02407          $inputName='"'.$inputName.'"';
02408       }
02409       return $inputName;
02410    }
02411 
02412 
02413 
02414 
02415 
02416 
02417 
02418 
02419 
02420 
02421 
02422 
02423 
02424 
02425 
02426 
02427 
02428 
02429 
02430 
02431 
02432 
02433 
02434    /***********************************
02435     *
02436     * Various IO functions
02437     *
02438     ***********************************/
02439 
02446    function checkFile($file)  {
02447       if (@is_file($file)) {
02448          return $file;
02449       } else {
02450          return '';
02451       }
02452    }
02453 
02460    function createTempSubDir($dirName) {
02461 
02462          // Checking if the this->tempPath is already prefixed with PATH_site and if not, prefix it with that constant.
02463       if (t3lib_div::isFirstPartOfStr($this->tempPath,PATH_site)) {
02464          $tmpPath = $this->tempPath;
02465       } else {
02466          $tmpPath = PATH_site.$this->tempPath;
02467       }
02468 
02469          // Making the temporary filename:
02470       if (!@is_dir($tmpPath.$dirName))  {
02471          return t3lib_div::mkdir($tmpPath.$dirName);
02472       }
02473    }
02474 
02482    function applyImageMagickToPHPGif(&$im, $command)  {
02483       $tmpStr = $this->randomName();
02484       $theFile = $tmpStr.'.'.$this->gifExtension;
02485       $this->ImageGif($im, $theFile);
02486       $this->imageMagickExec($theFile,$theFile,$command);
02487       $tmpImg = $this->imageCreateFromGif($theFile);
02488       if ($tmpImg)   {
02489          ImageDestroy($im);
02490          $im = $tmpImg;
02491          $this->w = imagesx($im);
02492          $this->h = imagesy($im);
02493       }
02494       if (!$this->dontUnlinkTempFiles) {
02495          unlink($theFile);
02496       }
02497    }
02498 
02508    function gif_or_jpg($type,$w,$h) {
02509       if ($type=='ai' || $w*$h < $this->pixelLimitGif)   {
02510          return $this->gifExtension;
02511       } else {
02512          return 'jpg';
02513       }
02514    }
02515 
02525    function output($file)  {
02526       if ($file)  {
02527          ereg('([^\.]*)$',$file,$reg);
02528          $ext=strtolower($reg[0]);
02529          switch($ext)   {
02530             case $this->gifExtension:
02531                if ($this->ImageGif($this->im, $file)) {
02532                   // ImageMagick operations
02533                   if($this->setup['reduceColors']) {
02534                      $this->imageMagickExec($file,$file,' -colors '.t3lib_div::intInRange($this->setup['reduceColors'],2,255));
02535                      t3lib_div::gif_compress($file,'');  // Compress with IM (lzw) or GD (rle)      (Workaround for the absence of lzw-compression in GD)
02536                   } else {
02537                      t3lib_div::gif_compress($file, 'IM');     // Compress with IM! (adds extra compression, LZW from ImageMagick)     (Workaround for the absence of lzw-compression in GD)
02538                   }
02539                }
02540             break;
02541             case 'jpg':
02542             case 'jpeg':
02543                $tmpStr = $this->randomName();
02544                $theFile = $tmpStr.'.'.$this->gifExtension;
02545                if ($this->ImageGif($this->im, $theFile)) {
02546                   // ImageMagick operations
02547                   $operations='';
02548                   if($this->setup['quality'])   {
02549                      $operations.=' -quality '.t3lib_div::intInRange($this->setup['quality'],10,100);
02550                   }
02551                   $this->imageMagickExec($theFile,$file,$operations);
02552                   if (!$this->dontUnlinkTempFiles) {
02553                      unlink($theFile);
02554                   }
02555                }
02556             break;
02557          }
02558          $GLOBALS['TEMP_IMAGES_ON_PAGE'][]=$file;
02559       }
02560       return $file;
02561    }
02562 
02569    function destroy()   {
02570       ImageDestroy($this->im);
02571    }
02572 
02579    function imgTag ($imgInfo) {
02580       return '<img src="'.$imgInfo[3].'" width="'.$imgInfo[0].'" height="'.$imgInfo[1].'" border="0" alt="" />';
02581    }
02582 
02591    function ImageGif($destImg, $theImage) {
02592       imageinterlace ($destImg,0);
02593       if ($this->gifExtension=='gif')  {
02594          return ImageGif($destImg, $theImage);
02595       }
02596       if ($this->gifExtension=='png')  {
02597          return ImagePng($destImg, $theImage);
02598       }
02599    }
02600 
02608    function imageCreateFromGif($sourceImg)   {
02609       $imgInf = pathinfo($sourceImg);
02610       $ext = strtolower($imgInf['extension']);
02611 
02612 //    if ($ext=='gif' && (ImageTypes() & IMG_GIF)) {
02613       if ($ext=='gif' && function_exists('imagecreatefromgif'))   {
02614          return imageCreateFromGif($sourceImg);
02615       }
02616 //    if ($ext=='png' && (ImageTypes() & IMG_PNG)) {
02617       if ($ext=='png' && function_exists('imagecreatefrompng'))   {
02618          return imageCreateFromPng($sourceImg);
02619       }
02620 //    if (($ext=='jpg' || $ext=='jpeg') && (ImageTypes() & IMG_JPG)) {
02621       if (($ext=='jpg' || $ext=='jpeg') && function_exists('imagecreatefromjpeg'))  {
02622          return imageCreateFromJpeg($sourceImg);
02623       }
02624 
02625       // If non of the above:
02626       $i = @getimagesize($sourceImg);
02627       $im = imagecreate($i[0],$i[1]);
02628       ImageColorAllocate($im, 128,128,128);
02629       return $im;
02630    }
02631 }
02632 
02633 
02634 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_stdgraphic.php']) {
02635    include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_stdgraphic.php']);
02636 }
02637 ?>

Generated on Sun Oct 3 01:05:49 2004 for TYPO3core 3.7.0 dev by  doxygen 1.3.8-20040913