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

class.tslib_gifbuilder.php

Go to the documentation of this file.
00001 <?php
00002 /***************************************************************
00003 *  Copyright notice
00004 *
00005 *  (c) 1999-2004 Kasper Skaarhoj (kasperYYYY@typo3.com)
00006 *  All rights reserved
00007 *
00008 *  This script is part of the TYPO3 project. The TYPO3 project is
00009 *  free software; you can redistribute it and/or modify
00010 *  it under the terms of the GNU General Public License as published by
00011 *  the Free Software Foundation; either version 2 of the License, or
00012 *  (at your option) any later version.
00013 *
00014 *  The GNU General Public License can be found at
00015 *  http://www.gnu.org/copyleft/gpl.html.
00016 *  A copy is found in the textfile GPL.txt and important notices to the license
00017 *  from the author is found in LICENSE.txt distributed with these scripts.
00018 *
00019 *
00020 *  This script is distributed in the hope that it will be useful,
00021 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00022 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023 *  GNU General Public License for more details.
00024 *
00025 *  This copyright notice MUST APPEAR in all copies of the script!
00026 ***************************************************************/
00102 class tslib_gifBuilder extends t3lib_stdGraphic {
00103 
00104       // Internal
00105    var $im = '';     // the main image
00106    var $w = 0;       // the image-width
00107    var $h = 0;       // the image-height
00108    var $map;         // map-data
00109    var $workArea;
00110    var $setup = Array ();     // This holds the operational setup for gifbuilder. Basically this is a TypoScript array with properties.
00111    var $data = Array();    // This is the array from which data->field: [key] is fetched. So this is the current record!
00112    var $objBB = Array();
00113    var $myClassName = 'gifbuilder';
00114    var $charRangeMap=array();
00115 
00127    function start($conf,$data)   {
00128 
00129       if (is_array($conf)) {
00130          $this->setup = $conf;
00131          $this->data = $data;
00132 
00133             // Initializing global Char Range Map
00134          $this->charRangeMap = array();
00135          if (is_array($GLOBALS['TSFE']->tmpl->setup['_GIFBUILDER.']['charRangeMap.'])) {
00136             foreach($GLOBALS['TSFE']->tmpl->setup['_GIFBUILDER.']['charRangeMap.'] as $cRMcfgkey => $cRMcfg)   {
00137                if (is_array($cRMcfg))  {
00138 
00139                      // Initializing:
00140                   $cRMkey = $GLOBALS['TSFE']->tmpl->setup['_GIFBUILDER.']['charRangeMap.'][substr($cRMcfgkey,0,-1)];
00141                   $this->charRangeMap[$cRMkey] = array();
00142                   $this->charRangeMap[$cRMkey]['charMapConfig'] =  $cRMcfg['charMapConfig.'];
00143                   $this->charRangeMap[$cRMkey]['cfgKey'] = substr($cRMcfgkey,0,-1);
00144                   $this->charRangeMap[$cRMkey]['multiplicator'] = (double)$cRMcfg['fontSizeMultiplicator'];
00145                   $this->charRangeMap[$cRMkey]['pixelSpace'] = intval($cRMcfg['pixelSpaceFontSizeRef']);
00146                }
00147             }
00148          }
00149 
00150             // Getting sorted list of TypoScript keys from setup.
00151          $sKeyArray=t3lib_TStemplate::sortedKeyList($this->setup);
00152 
00153             // Setting the background color, passing it through stdWrap
00154          if ($conf['backColor.'] || $conf['backColor'])  {
00155             $cObj =t3lib_div::makeInstance('tslib_cObj');
00156             $cObj->start($this->data);
00157             $this->setup['backColor'] = trim($cObj->stdWrap($this->setup['backColor'], $this->setup['backColor.']));
00158          }
00159          if (!$this->setup['backColor'])  {$this->setup['backColor']='white';}
00160 
00161             // Transparent GIFs
00162             // not working with reduceColors
00163             // there's an option for IM: -transparent colors
00164          if ($conf['transparentColor.'] || $conf['transparentColor'])   {
00165             $cObj =t3lib_div::makeInstance('tslib_cObj');
00166             $cObj->start($this->data);
00167             $this->setup['transparentColor_array'] = explode('|', trim($cObj->stdWrap($this->setup['transparentColor'], $this->setup['transparentColor.'])));
00168          }
00169 
00170             // Set default dimensions
00171          if (!$this->setup['XY'])   {$this->setup['XY']='120,50';}
00172 
00173 
00174             // Checking TEXT and IMAGE objects for files. If any errors the objects are cleared.
00175             // The Bounding Box for the objects is stored in an array
00176          foreach($sKeyArray as $theKey) {
00177             $theValue=$this->setup[$theKey];
00178 
00179             if (intval($theKey) && $conf=$this->setup[$theKey.'.'])  {
00180                   // Swipes through TEXT and IMAGE-objects
00181                switch($theValue) {
00182                   case 'TEXT':
00183                      if ($this->setup[$theKey.'.'] = $this->checkTextObj($conf)) {
00184 
00185                            // Adjust font width if max size is set:
00186                         if ($this->setup[$theKey.'.']['maxWidth'])   {
00187                            $this->setup[$theKey.'.']['fontSize'] = $this->fontResize($this->setup[$theKey.'.']); //RTF - this has to be done before calcBBox
00188                         }
00189 
00190                            // Calculate bounding box:
00191                         $txtInfo=$this->calcBBox($this->setup[$theKey.'.']);
00192                         $this->setup[$theKey.'.']['BBOX']=$txtInfo;
00193                         $this->objBB[$theKey]=$txtInfo;
00194                         $this->setup[$theKey.'.']['imgMap']=0;
00195                      }
00196                   break;
00197                   case 'IMAGE':
00198                      $fileInfo = $this->getResource($conf['file'],$conf['file.']);
00199                      if ($fileInfo) {
00200                         $this->setup[$theKey.'.']['file']=$fileInfo[3];
00201                         $this->setup[$theKey.'.']['BBOX']=$fileInfo;
00202                         $this->objBB[$theKey]=$fileInfo;
00203                         if ($conf['mask'])   {
00204                            $maskInfo = $this->getResource($conf['mask'],$conf['mask.']);
00205                            if ($maskInfo) {
00206                               $this->setup[$theKey.'.']['mask']=$maskInfo[3];
00207                            } else {
00208                               $this->setup[$theKey.'.']['mask'] = '';
00209                            }
00210                         }
00211                      } else {
00212                         unset($this->setup[$theKey.'.']);
00213                      }
00214                   break;
00215                }
00216                   // Checks if disabled is set... (this is also done in menu.php / imgmenu!!)
00217                if ($conf['if.']) {
00218                   $cObj =t3lib_div::makeInstance('tslib_cObj');
00219                   $cObj->start($this->data);
00220 
00221                   if (!$cObj->checkIf($conf['if.']))  {
00222                      unset($this->setup[$theKey]);
00223                      unset($this->setup[$theKey.'.']);
00224                   }
00225                }
00226             }
00227          }
00228 
00229             // Calculate offsets on elements
00230          $this->setup['XY'] = $this->calcOffset($this->setup['XY']);
00231          $this->setup['offset'] = $this->calcOffset($this->setup['offset']);
00232          $this->setup['workArea'] = $this->calcOffset($this->setup['workArea']);
00233 
00234          foreach ($sKeyArray as $theKey) {
00235             $theValue=$this->setup[$theKey];
00236 
00237             if (intval($theKey) && $conf=$this->setup[$theKey.'.'])  {
00238                switch($theValue) {
00239                   case 'TEXT':
00240                   case 'IMAGE':
00241                      if ($this->setup[$theKey.'.']['offset'])  {
00242                         $this->setup[$theKey.'.']['offset'] = $this->calcOffset($this->setup[$theKey.'.']['offset']);
00243                      }
00244                   break;
00245                   case 'BOX':
00246                      if ($this->setup[$theKey.'.']['dimensions']) {
00247                         $this->setup[$theKey.'.']['dimensions'] = $this->calcOffset($this->setup[$theKey.'.']['dimensions']);
00248                      }
00249                   break;
00250                   case 'WORKAREA':
00251                      if ($this->setup[$theKey.'.']['set'])  {
00252                         $this->setup[$theKey.'.']['set'] = $this->calcOffset($this->setup[$theKey.'.']['set']);
00253                      }
00254                   break;
00255                   case 'CROP':
00256                      if ($this->setup[$theKey.'.']['crop']) {
00257                         $this->setup[$theKey.'.']['crop'] = $this->calcOffset($this->setup[$theKey.'.']['crop']);
00258                      }
00259                   break;
00260                   case 'SCALE':
00261                      if ($this->setup[$theKey.'.']['width'])   {
00262                         $this->setup[$theKey.'.']['width'] = $this->calcOffset($this->setup[$theKey.'.']['width']);
00263                      }
00264                      if ($this->setup[$theKey.'.']['height'])  {
00265                         $this->setup[$theKey.'.']['height'] = $this->calcOffset($this->setup[$theKey.'.']['height']);
00266                      }
00267                   break;
00268                }
00269             }
00270          }
00271             // Get trivial data
00272          $XY = t3lib_div::intExplode(',',$this->setup['XY']);
00273          $maxWidth = intval($this->setup['maxWidth']);
00274          $maxHeight = intval($this->setup['maxHeight']);
00275 
00276          $XY[0] = t3lib_div::intInRange($XY[0],1, $maxWidth?$maxWidth:2000);
00277          $XY[1] = t3lib_div::intInRange($XY[1],1, $maxHeight?$maxHeight:2000);
00278          $this->XY = $XY;
00279          $this->w = $XY[0];
00280          $this->h = $XY[1];
00281          $this->OFFSET = t3lib_div::intExplode(',',$this->setup['offset']);
00282 
00283          $this->setWorkArea($this->setup['workArea']);   // this sets the workArea
00284          $this->defaultWorkArea = $this->workArea; // this sets the default to the current;
00285       }
00286    }
00287 
00296    function gifBuild()  {
00297       if ($this->setup) {
00298          $gifFileName = $this->fileName('GB/'); // Relative to PATH_site
00299          if (!@file_exists($gifFileName)) {     // File exists
00300 
00301                // Create temporary directory if not done:
00302             $this->createTempSubDir('GB/');
00303 
00304                // Create file:
00305             $this->make();
00306             $this->output($gifFileName);
00307             $this->destroy();
00308          }
00309          return $gifFileName;
00310       }
00311    }
00312 
00324    function make()   {
00325          // Get trivial data
00326       $XY = $this->XY;
00327 
00328          // Gif-start
00329       $this->im = imagecreate($XY[0],$XY[1]);
00330       $this->w = $XY[0];
00331       $this->h = $XY[1];
00332 
00333          // backColor is set
00334       $cols=$this->convertColor($this->setup['backColor']);
00335       ImageColorAllocate($this->im, $cols[0],$cols[1],$cols[2]);
00336 
00337          // Traverse the GIFBUILDER objects an render each one:
00338       if (is_array($this->setup))   {
00339          $sKeyArray=t3lib_TStemplate::sortedKeyList($this->setup);
00340          foreach($sKeyArray as $theKey)   {
00341             $theValue=$this->setup[$theKey];
00342 
00343             if (intval($theKey) && $conf=$this->setup[$theKey.'.'])  {
00344                switch($theValue) {
00345                      // Images
00346                   case 'IMAGE':
00347                      if ($conf['mask'])   {
00348                         $this->maskImageOntoImage($this->im,$conf,$this->workArea);
00349                      } else {
00350                         $this->copyImageOntoImage($this->im,$conf,$this->workArea);
00351                      }
00352                   break;
00353 
00354                      // Text
00355                   case 'TEXT':
00356                      if (!$conf['hide'])  {
00357                         if (is_array($conf['shadow.']))  {
00358                            $this->makeShadow($this->im,$conf['shadow.'],$this->workArea,$conf);
00359                         }
00360                         if (is_array($conf['emboss.']))  {
00361                            $this->makeEmboss($this->im,$conf['emboss.'],$this->workArea,$conf);
00362                         }
00363                         if (is_array($conf['outline.'])) {
00364                            $this->makeOutline($this->im,$conf['outline.'],$this->workArea,$conf);
00365                         }
00366                         $conf['imgMap']=1;
00367                         $this->makeText($this->im,$conf,$this->workArea);
00368                      }
00369                   break;
00370 
00371                      // Text effects:
00372                   case 'OUTLINE':
00373                      if ($this->setup[$conf['textObjNum']]=='TEXT' && $txtConf=$this->checkTextObj($this->setup[$conf['textObjNum'].'.']))   {
00374                         $this->makeOutline($this->im,$conf,$this->workArea,$txtConf);
00375                      }
00376                   break;
00377                   case 'EMBOSS':
00378                      if ($this->setup[$conf['textObjNum']]=='TEXT' && $txtConf=$this->checkTextObj($this->setup[$conf['textObjNum'].'.']))   {
00379                         $this->makeEmboss($this->im,$conf,$this->workArea,$txtConf);
00380                      }
00381                   break;
00382                   case 'SHADOW':
00383                      if ($this->setup[$conf['textObjNum']]=='TEXT' && $txtConf=$this->checkTextObj($this->setup[$conf['textObjNum'].'.']))   {
00384                         $this->makeShadow($this->im,$conf,$this->workArea,$txtConf);
00385                      }
00386                   break;
00387 
00388                      // Other
00389                   case 'BOX':
00390                      $this->makeBox($this->im,$conf,$this->workArea);
00391                   break;
00392                   case 'EFFECT':
00393                      $this->makeEffect($this->im,$conf);
00394                   break;
00395                   case 'ADJUST':
00396                      $this->adjust($this->im,$conf);
00397                   break;
00398                   case 'CROP':
00399                      $this->crop($this->im,$conf);
00400                   break;
00401                   case 'SCALE':
00402                      $this->scale($this->im,$conf);
00403                   break;
00404                   case 'WORKAREA':
00405                      if ($conf['set']) {
00406                         $this->setWorkArea($conf['set']);   // this sets the workArea
00407                      }
00408                      if (isset($conf['clear'])) {
00409                         $this->workArea = $this->defaultWorkArea; // this sets the current to the default;
00410                      }
00411                   break;
00412                }
00413             }
00414          }
00415       }
00416          // Auto transparent background is set
00417       if ($this->setup['transparentBackground'])   {
00418          imagecolortransparent($this->im, imagecolorat($this->im, 0, 0));
00419       }
00420          // TransparentColors are set
00421       if (is_array($this->setup['transparentColor_array'])) {
00422          reset($this->setup['transparentColor_array']);
00423          while(list(,$transparentColor)=each($this->setup['transparentColor_array']))  {
00424             $cols=$this->convertColor($transparentColor);
00425             if ($this->setup['transparentColor.']['closest'])  {
00426                $colIndex = ImageColorClosest ($this->im, $cols[0],$cols[1],$cols[2]);
00427             } else {
00428                $colIndex = ImageColorExact ($this->im, $cols[0],$cols[1],$cols[2]);
00429             }
00430             if ($colIndex > -1) {
00431                ImageColorTransparent($this->im, $colIndex);
00432             } else {
00433                ImageColorTransparent($this->im, ImageColorAllocate($this->im, $cols[0],$cols[1],$cols[2]));
00434             }
00435             break;      // Originally we thought of letting many colors be defined as transparent, but GDlib seems to accept only one definition. Therefore we break here. Maybe in the future this 'break' will be cancelled if a method of truly defining many transparent colors could be found.
00436          }
00437       }
00438    }
00439 
00440 
00441 
00442 
00443 
00444 
00445 
00446 
00447 
00448 
00449 
00450 
00451 
00452 
00453 
00454 
00455 
00456 
00457    /*********************************************
00458     *
00459     * Various helper functions
00460     *
00461     ********************************************/
00462 
00463 
00475    function checkTextObj($conf)  {
00476       $conf['fontFile']=$this->checkFile($conf['fontFile']);
00477       if (!$conf['fontFile']){$conf['fontFile']='t3lib/fonts/arial.ttf';}
00478       if (!$conf['iterations']){$conf['iterations'] = 1;}
00479       if (!$conf['fontSize']){$conf['fontSize']=12;}
00480       if ($conf['spacing'] || $conf['wordSpacing'])   {     // If any kind of spacing applys, we cannot use angles!!
00481          $conf['angle']=0;
00482       }
00483       if (!isset($conf['antiAlias'])){$conf['antiAlias']=1;}
00484       $cObj =t3lib_div::makeInstance('tslib_cObj');
00485       $cObj->start($this->data);
00486 
00487       $conf['text']=$cObj->stdWrap($conf['text'],$conf['text.']);
00488          // Strip HTML
00489       if (!$conf['doNotStripHTML']) {
00490          $conf['text'] = strip_tags($conf['text']);
00491       }
00492          // Max length = 100
00493       $tlen = intval($conf['textMaxLength']) ? intval($conf['textMaxLength']) : 100;
00494       $conf['text'] = substr($conf['text'],0,$tlen);
00495       if ((string)$conf['text']!='')   {
00496 
00497             // Char range map thingie:
00498          $fontBaseName = basename($conf['fontFile']);
00499          if (is_array($this->charRangeMap[$fontBaseName]))  {
00500 
00501                // Initialize splitRendering array:
00502             if (!is_array($conf['splitRendering.']))  {
00503                $conf['splitRendering.'] = array();
00504             }
00505 
00506             $cfgK = $this->charRangeMap[$fontBaseName]['cfgKey'];
00507             if (!isset($conf['splitRendering.'][$cfgK])) {  // Do not impose settings if a splitRendering object already exists:
00508                   // Set configuration:
00509                $conf['splitRendering.'][$cfgK] = 'charRange';
00510                $conf['splitRendering.'][$cfgK.'.'] = $this->charRangeMap[$fontBaseName]['charMapConfig'];
00511 
00512                   // multiplicator of fontsize:
00513                if ($this->charRangeMap[$fontBaseName]['multiplicator']) {
00514                   $conf['splitRendering.'][$cfgK.'.']['fontSize'] = round($conf['fontSize'] * $this->charRangeMap[$fontBaseName]['multiplicator']);
00515                }
00516                   // multiplicator of pixelSpace:
00517                if ($this->charRangeMap[$fontBaseName]['pixelSpace']) {
00518                   $travKeys = array('xSpaceBefore','xSpaceAfter','ySpaceBefore','ySpaceAfter');
00519                   foreach($travKeys as $pxKey)  {
00520                      if (isset($conf['splitRendering.'][$cfgK.'.'][$pxKey]))  {
00521                         $conf['splitRendering.'][$cfgK.'.'][$pxKey] = round($conf['splitRendering.'][$cfgK.'.'][$pxKey] * ($conf['fontSize'] / $this->charRangeMap[$fontBaseName]['pixelSpace']));
00522                      }
00523                   }
00524                }
00525             }
00526          }
00527          if (is_array($conf['splitRendering.']))   {
00528             foreach($conf['splitRendering.'] as $key => $value)   {
00529                if (is_array($conf['splitRendering.'][$key]))   {
00530                   if (isset($conf['splitRendering.'][$key]['fontFile']))   {
00531                      $conf['splitRendering.'][$key]['fontFile'] = $this->checkFile($conf['splitRendering.'][$key]['fontFile']);
00532                   }
00533                }
00534             }
00535          }
00536 
00537          return $conf;
00538       }
00539    }
00540 
00552    function calcOffset($string)  {
00553       $numbers=explode(',',$string);
00554       while(list($key,$val)=each($numbers))  {
00555          $val = trim($val);
00556          if ((string)$val==(string)intval($val)) {
00557             $value[$key]=intval($val);
00558          } else {
00559             $parts= t3lib_div::splitCalc($val,'+-*/%');
00560             $value[$key]=0;
00561             reset($parts);
00562             while(list(,$part)=each($parts)) {
00563                $theVal = $part[1];
00564                $sign =  $part[0];
00565                if ((string)intval($theVal)==(string)$theVal)   {
00566                   $theVal = intval($theVal);
00567                } elseif ('['.substr($theVal,1,-1).']'==$theVal)   {
00568                   $objParts=explode('.',substr($theVal,1,-1));
00569                   $theVal=0;
00570                   if (isset($this->objBB[$objParts[0]])) {
00571                      if ($objParts[1]=='w')  {$theVal=intval($this->objBB[$objParts[0]][0]);}
00572                      if ($objParts[1]=='h')  {$theVal=intval($this->objBB[$objParts[0]][1]);}
00573                   }
00574                } else {
00575                   $theVal =0;
00576                }
00577                if ($sign=='-')   {$value[$key]-=$theVal;}
00578                if ($sign=='+')   {$value[$key]+=$theVal;}
00579                if ($sign=='/')   {if (intval($theVal)) $value[$key]/=intval($theVal);}
00580                if ($sign=='*')   {$value[$key]*=$theVal;}
00581                if ($sign=='%') {if (intval($theVal)) $value[$key]%=intval($theVal);}
00582             }
00583             $value[$key]=intval($value[$key]);
00584          }
00585       }
00586       $string = implode(',',$value);
00587       return $string;
00588    }
00589 
00601    function getResource($file,$fileArray) {
00602       $fileArray['ext']= $this->gifExtension;
00603       $cObj =t3lib_div::makeInstance('tslib_cObj');
00604       $cObj->start($this->data);
00605       return $cObj->getImgResource($file,$fileArray);
00606    }
00607 
00616    function checkFile($file)  {
00617       return $GLOBALS['TSFE']->tmpl->getFileName($file);
00618    }
00619 
00627    function fileName($pre) {
00628       return $this->tempPath.$pre.t3lib_div::shortMD5(serialize($this->setup)).'.'.$this->extension();
00629    }
00630 
00637    function extension() {
00638       switch(strtolower($this->setup['format']))   {
00639          case 'jpg':
00640          case 'jpeg':
00641             return 'jpg';
00642          break;
00643          default:
00644             return $this->gifExtension;
00645          break;
00646       }
00647    }
00648 }
00649 
00650 
00651 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['tslib/class.tslib_gifbuilder.php']) {
00652    include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['tslib/class.tslib_gifbuilder.php']);
00653 }
00654 
00655 ?>

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