Documentation TYPO3 par Ameos

class.t3lib_stdgraphic.php

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 ?>


Généré par L'expert TYPO3 avec  doxygen 1.4.6