class.tslib_gifbuilder.php

Go to the documentation of this file.
00001 <?php
00002 /***************************************************************
00003 *  Copyright notice
00004 *
00005 *  (c) 1999-2010 Kasper Skårhøj (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 ***************************************************************/
00027 /**
00028  * Generating gif/png-files from TypoScript
00029  * Used by the menu-objects and imgResource in TypoScript.
00030  *
00031  * $Id: class.tslib_gifbuilder.php 8742 2010-08-30 18:55:32Z baschny $
00032  * Revised for TYPO3 3.6 June/2003 by Kasper Skårhøj
00033  *
00034  * @author  Kasper Skårhøj <kasperYYYY@typo3.com>
00035  */
00036 /**
00037  * [CLASS/FUNCTION INDEX of SCRIPT]
00038  *
00039  *
00040  *
00041  *  102: class tslib_gifBuilder extends t3lib_stdGraphic
00042  *  129:     function start($conf,$data)
00043  *  315:     function gifBuild()
00044  *  343:     function make()
00045  *
00046  *              SECTION: Various helper functions
00047  *  486:     function checkTextObj($conf)
00048  *  566:     function calcOffset($string)
00049  *  615:     function getResource($file,$fileArray)
00050  *  632:     function checkFile($file)
00051  *  643:     function fileName($pre)
00052  *  659:     function extension()
00053  *
00054  * TOTAL FUNCTIONS: 9
00055  * (This index is automatically created/updated by the extension "extdeveval")
00056  *
00057  */
00058 
00059 
00060 
00061 
00062 
00063 
00064 
00065 
00066 
00067 
00068 
00069 
00070 
00071 
00072 
00073 
00074 
00075 
00076 
00077 
00078 
00079 /**
00080  * GIFBUILDER extension class.
00081  * This class allows for advanced rendering of images with various layers of images, text and graphical primitives.
00082  * The concept is known from TypoScript as "GIFBUILDER" where you can define a "numerical array" (TypoScript term as well) of "GIFBUILDER OBJECTS" (like "TEXT", "IMAGE", etc.) and they will be rendered onto an image one by one.
00083  * The name "GIFBUILDER" comes from the time where GIF was the only file format supported. PNG is just as well to create today (configured with TYPO3_CONF_VARS[GFX])
00084  * Not all instances of this class is truely building gif/png files by layers; You may also see the class instantiated for the purpose of using the scaling functions in the parent class, t3lib_stdGraphic.
00085  *
00086  * Here is an example of how to use this class (from tslib_content.php, function getImgResource):
00087  *
00088  * $gifCreator = t3lib_div::makeInstance('tslib_gifbuilder');
00089  * $gifCreator->init();
00090  * $theImage='';
00091  * if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib']) {
00092  * $gifCreator->start($fileArray,$this->data);
00093  * $theImage = $gifCreator->gifBuild();
00094  * }
00095  * return $gifCreator->getImageDimensions($theImage);
00096  *
00097  * @author  Kasper Skårhøj <kasperYYYY@typo3.com>
00098  * @package TYPO3
00099  * @subpackage tslib
00100  * @link http://typo3.org/doc.0.html?&tx_extrepmgm_pi1[extUid]=270&tx_extrepmgm_pi1[tocEl]=377&cHash=e00ac666f3
00101  */
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 $combinedTextStrings = array();     // Contains all text strings used on this image
00112     var $combinedFileNames = array();       // Contains all filenames (basename without extension) used on this image
00113     var $data = Array();        // This is the array from which data->field: [key] is fetched. So this is the current record!
00114     var $objBB = Array();
00115     var $myClassName = 'gifbuilder';
00116     var $charRangeMap=array();
00117 
00118     /**
00119      * Initialization of the GIFBUILDER objects, in particular TEXT and IMAGE. This includes finding the bounding box, setting dimensions and offset values before the actual rendering is started.
00120      * Modifies the ->setup, ->objBB internal arrays
00121      * Should be called after the ->init() function which initializes the parent class functions/variables in general.
00122      * The class tslib_gmenu also uses gifbuilder and here there is an interesting use since the function findLargestDims() from that class calls the init() and start() functions to find the total dimensions before starting the rendering of the images.
00123      *
00124      * @param   array       TypoScript properties for the GIFBUILDER session. Stored internally in the variable ->setup
00125      * @param   array       The current data record from tslib_cObj. Stored internally in the variable ->data
00126      * @return  void
00127      * @see tslib_cObj::getImgResource(), tslib_gmenu::makeGifs(), tslib_gmenu::findLargestDims()
00128      */
00129     function start($conf,$data) {
00130 
00131         if (is_array($conf))    {
00132             $this->setup = $conf;
00133             $this->data = $data;
00134 
00135 
00136             /* Hook preprocess gifbuilder conf
00137              * Added by Julle for 3.8.0
00138              *
00139              * Let's you pre-process the gifbuilder configuration. for
00140              * example you can split a string up into lines and render each
00141              * line as TEXT obj, see extension julle_gifbconf
00142              */
00143 
00144             if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_gifbuilder.php']['gifbuilder-ConfPreProcess']))    {
00145                 foreach($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_gifbuilder.php']['gifbuilder-ConfPreProcess'] as $_funcRef)    {
00146                     $_params = $this->setup;
00147                     $this->setup = t3lib_div::callUserFunction($_funcRef,$_params,$this);
00148                 }
00149             }
00150 
00151                 // Initializing global Char Range Map
00152             $this->charRangeMap = array();
00153             if (is_array($GLOBALS['TSFE']->tmpl->setup['_GIFBUILDER.']['charRangeMap.']))   {
00154                 foreach($GLOBALS['TSFE']->tmpl->setup['_GIFBUILDER.']['charRangeMap.'] as $cRMcfgkey => $cRMcfg)    {
00155                     if (is_array($cRMcfg))  {
00156 
00157                             // Initializing:
00158                         $cRMkey = $GLOBALS['TSFE']->tmpl->setup['_GIFBUILDER.']['charRangeMap.'][substr($cRMcfgkey,0,-1)];
00159                         $this->charRangeMap[$cRMkey] = array();
00160                         $this->charRangeMap[$cRMkey]['charMapConfig'] =  $cRMcfg['charMapConfig.'];
00161                         $this->charRangeMap[$cRMkey]['cfgKey'] = substr($cRMcfgkey,0,-1);
00162                         $this->charRangeMap[$cRMkey]['multiplicator'] = (double)$cRMcfg['fontSizeMultiplicator'];
00163                         $this->charRangeMap[$cRMkey]['pixelSpace'] = intval($cRMcfg['pixelSpaceFontSizeRef']);
00164                     }
00165                 }
00166             }
00167 
00168                 // Getting sorted list of TypoScript keys from setup.
00169             $sKeyArray=t3lib_TStemplate::sortedKeyList($this->setup);
00170 
00171                 // Setting the background color, passing it through stdWrap
00172             if ($conf['backColor.'] || $conf['backColor'])  {
00173                 $cObj =t3lib_div::makeInstance('tslib_cObj');
00174                 $cObj->start($this->data);
00175                 $this->setup['backColor'] = trim($cObj->stdWrap($this->setup['backColor'], $this->setup['backColor.']));
00176             }
00177             if (!$this->setup['backColor']) { $this->setup['backColor']='white'; }
00178 
00179             if ($conf['transparentColor.'] || $conf['transparentColor'])    {
00180                 $cObj =t3lib_div::makeInstance('tslib_cObj');
00181                 $cObj->start($this->data);
00182                 $this->setup['transparentColor_array'] = explode('|', trim($cObj->stdWrap($this->setup['transparentColor'], $this->setup['transparentColor.'])));
00183             }
00184 
00185                 // Transparency does not properly work when, GIFs or 8-bit PNGs are generated or reduceColors is set -- disable truecolor flag so they get generated "natively" in 8-bit.
00186                 // not working with reduceColors and truecolor images
00187             if (($this->setup['transparentBackground'] || is_array($this->setup['transparentColor_array'])) && ($this->gifExtension=='gif' || !$this->png_truecolor || isset($this->setup['reduceColors'])))    {
00188                 $this->truecolor = false;
00189             }
00190 
00191                 // Set default dimensions
00192             if (!$this->setup['XY'])    {$this->setup['XY']='120,50';}
00193 
00194 
00195                 // Checking TEXT and IMAGE objects for files. If any errors the objects are cleared.
00196                 // The Bounding Box for the objects is stored in an array
00197             foreach($sKeyArray as $theKey) {
00198                 $theValue = $this->setup[$theKey];
00199 
00200                 if (intval($theKey) && $conf=$this->setup[$theKey.'.']) {
00201                         // Swipes through TEXT and IMAGE-objects
00202                     switch($theValue)   {
00203                         case 'TEXT':
00204                             if ($this->setup[$theKey.'.'] = $this->checkTextObj($conf)) {
00205 
00206                                     // Adjust font width if max size is set:
00207                                 if ($this->setup[$theKey.'.']['maxWidth'])  {
00208                                     $this->setup[$theKey.'.']['fontSize'] = $this->fontResize($this->setup[$theKey.'.']); //RTF - this has to be done before calcBBox
00209                                 }
00210 
00211                                     // Calculate bounding box:
00212                                 $txtInfo=$this->calcBBox($this->setup[$theKey.'.']);
00213                                 $this->setup[$theKey.'.']['BBOX'] = $txtInfo;
00214                                 $this->objBB[$theKey] = $txtInfo;
00215                                 $this->setup[$theKey.'.']['imgMap'] = 0;
00216                             }
00217                         break;
00218                         case 'IMAGE':
00219                             $fileInfo = $this->getResource($conf['file'],$conf['file.']);
00220                             if ($fileInfo)  {
00221                                 $this->combinedFileNames[] = preg_replace('/\.[[:alnum:]]+$/','',basename($fileInfo[3]));
00222                                 $this->setup[$theKey.'.']['file'] = $fileInfo[3];
00223                                 $this->setup[$theKey.'.']['BBOX'] = $fileInfo;
00224                                 $this->objBB[$theKey] = $fileInfo;
00225                                 if ($conf['mask'])  {
00226                                     $maskInfo = $this->getResource($conf['mask'],$conf['mask.']);
00227                                     if ($maskInfo)  {
00228                                         $this->setup[$theKey.'.']['mask'] = $maskInfo[3];
00229                                     } else {
00230                                         $this->setup[$theKey.'.']['mask'] = '';
00231                                     }
00232                                 }
00233                             } else {
00234                                 unset($this->setup[$theKey.'.']);
00235                             }
00236                         break;
00237                     }
00238                         // Checks if disabled is set... (this is also done in menu.php / imgmenu!!)
00239                     if ($conf['if.'])   {
00240                         $cObj =t3lib_div::makeInstance('tslib_cObj');
00241                         $cObj->start($this->data);
00242 
00243                         if (!$cObj->checkIf($conf['if.']))  {
00244                             unset($this->setup[$theKey]);
00245                             unset($this->setup[$theKey.'.']);
00246                         }
00247                     }
00248                 }
00249             }
00250 
00251                 // Calculate offsets on elements
00252             $this->setup['XY'] = $this->calcOffset($this->setup['XY']);
00253             $this->setup['offset'] = $this->calcOffset($this->setup['offset']);
00254             $this->setup['workArea'] = $this->calcOffset($this->setup['workArea']);
00255 
00256             foreach ($sKeyArray as $theKey) {
00257                 $theValue=$this->setup[$theKey];
00258 
00259                 if (intval($theKey) && $conf=$this->setup[$theKey.'.']) {
00260                     switch($theValue)   {
00261                         case 'TEXT':
00262                         case 'IMAGE':
00263                             if ($this->setup[$theKey.'.']['offset'])    {
00264                                 $this->setup[$theKey.'.']['offset'] = $this->calcOffset($this->setup[$theKey.'.']['offset']);
00265                             }
00266                         break;
00267                         case 'BOX':
00268                             if ($this->setup[$theKey.'.']['dimensions'])    {
00269                                 $this->setup[$theKey.'.']['dimensions'] = $this->calcOffset($this->setup[$theKey.'.']['dimensions']);
00270                             }
00271                         break;
00272                         case 'WORKAREA':
00273                             if ($this->setup[$theKey.'.']['set'])   {
00274                                 $this->setup[$theKey.'.']['set'] = $this->calcOffset($this->setup[$theKey.'.']['set']);
00275                             }
00276                         break;
00277                         case 'CROP':
00278                             if ($this->setup[$theKey.'.']['crop'])  {
00279                                 $this->setup[$theKey.'.']['crop'] = $this->calcOffset($this->setup[$theKey.'.']['crop']);
00280                             }
00281                         break;
00282                         case 'SCALE':
00283                             if ($this->setup[$theKey.'.']['width']) {
00284                                 $this->setup[$theKey.'.']['width'] = $this->calcOffset($this->setup[$theKey.'.']['width']);
00285                             }
00286                             if ($this->setup[$theKey.'.']['height'])    {
00287                                 $this->setup[$theKey.'.']['height'] = $this->calcOffset($this->setup[$theKey.'.']['height']);
00288                             }
00289                         break;
00290                         case 'ELLIPSE':
00291                             if ($this->setup[$theKey . '.']['dimensions']) {
00292                                 $this->setup[$theKey . '.']['dimensions'] = $this->calcOffset($this->setup[$theKey . '.']['dimensions']);
00293                             }
00294                         break;
00295                     }
00296                 }
00297             }
00298                 // Get trivial data
00299             $XY = t3lib_div::intExplode(',',$this->setup['XY']);
00300             $maxWidth = intval($this->setup['maxWidth']);
00301             $maxHeight = intval($this->setup['maxHeight']);
00302 
00303             $XY[0] = t3lib_div::intInRange($XY[0],1, $maxWidth?$maxWidth:2000);
00304             $XY[1] = t3lib_div::intInRange($XY[1],1, $maxHeight?$maxHeight:2000);
00305             $this->XY = $XY;
00306             $this->w = $XY[0];
00307             $this->h = $XY[1];
00308             $this->OFFSET = t3lib_div::intExplode(',',$this->setup['offset']);
00309 
00310             $this->setWorkArea($this->setup['workArea']);   // this sets the workArea
00311             $this->defaultWorkArea = $this->workArea;   // this sets the default to the current;
00312         }
00313     }
00314 
00315     /**
00316      * Initiates the image file generation if ->setup is true and if the file did not exist already.
00317      * Gets filename from fileName() and if file exists in typo3temp/ dir it will - of course - not be rendered again.
00318      * Otherwise rendering means calling ->make(), then ->output(), then ->destroy()
00319      *
00320      * @return  string      The filename for the created GIF/PNG file. The filename will be prefixed "GB_"
00321      * @see make(), fileName()
00322      */
00323     function gifBuild() {
00324         if ($this->setup)   {
00325             $gifFileName = $this->fileName('GB/');  // Relative to PATH_site
00326             if (!file_exists($gifFileName)) {       // File exists
00327 
00328                     // Create temporary directory if not done:
00329                 $this->createTempSubDir('GB/');
00330 
00331                     // Create file:
00332                 $this->make();
00333                 $this->output($gifFileName);
00334                 $this->destroy();
00335             }
00336             return $gifFileName;
00337         }
00338     }
00339 
00340     /**
00341      * The actual rendering of the image file.
00342      * Basically sets the dimensions, the background color, the traverses the array of GIFBUILDER objects and finally setting the transparent color if defined.
00343      * Creates a GDlib resource in $this->im and works on that
00344      * Called by gifBuild()
00345      *
00346      * @return  void
00347      * @access private
00348      * @see gifBuild()
00349      * @link http://typo3.org/doc.0.html?&tx_extrepmgm_pi1[extUid]=270&tx_extrepmgm_pi1[tocEl]=378&cHash=3c2ae4a1ab
00350      */
00351     function make() {
00352             // Get trivial data
00353         $XY = $this->XY;
00354 
00355             // Gif-start
00356         $this->im = imagecreatetruecolor($XY[0], $XY[1]);
00357         $this->w = $XY[0];
00358         $this->h = $XY[1];
00359 
00360             // backColor is set
00361         $BGcols = $this->convertColor($this->setup['backColor']);
00362         $Bcolor = ImageColorAllocate($this->im, $BGcols[0],$BGcols[1],$BGcols[2]);
00363         ImageFilledRectangle($this->im, 0, 0, $XY[0], $XY[1], $Bcolor);
00364 
00365             // Traverse the GIFBUILDER objects an render each one:
00366         if (is_array($this->setup)) {
00367             $sKeyArray=t3lib_TStemplate::sortedKeyList($this->setup);
00368             foreach($sKeyArray as $theKey)  {
00369                 $theValue=$this->setup[$theKey];
00370 
00371                 if (intval($theKey) && $conf=$this->setup[$theKey.'.']) {
00372                     switch($theValue)   {
00373                             // Images
00374                         case 'IMAGE':
00375                             if ($conf['mask'])  {
00376                                 $this->maskImageOntoImage($this->im,$conf,$this->workArea);
00377                             } else {
00378                                 $this->copyImageOntoImage($this->im,$conf,$this->workArea);
00379                             }
00380                         break;
00381 
00382                             // Text
00383                         case 'TEXT':
00384                             if (!$conf['hide']) {
00385                                 if (is_array($conf['shadow.'])) {
00386                                     $this->makeShadow($this->im,$conf['shadow.'],$this->workArea,$conf);
00387                                 }
00388                                 if (is_array($conf['emboss.'])) {
00389                                     $this->makeEmboss($this->im,$conf['emboss.'],$this->workArea,$conf);
00390                                 }
00391                                 if (is_array($conf['outline.']))    {
00392                                     $this->makeOutline($this->im,$conf['outline.'],$this->workArea,$conf);
00393                                 }
00394                                 $conf['imgMap']=1;
00395                                 $this->makeText($this->im,$conf,$this->workArea);
00396                             }
00397                         break;
00398 
00399                             // Text effects:
00400                         case 'OUTLINE':
00401                             if ($this->setup[$conf['textObjNum']]=='TEXT' && $txtConf=$this->checkTextObj($this->setup[$conf['textObjNum'].'.']))   {
00402                                 $this->makeOutline($this->im,$conf,$this->workArea,$txtConf);
00403                             }
00404                         break;
00405                         case 'EMBOSS':
00406                             if ($this->setup[$conf['textObjNum']]=='TEXT' && $txtConf=$this->checkTextObj($this->setup[$conf['textObjNum'].'.']))   {
00407                                 $this->makeEmboss($this->im,$conf,$this->workArea,$txtConf);
00408                             }
00409                         break;
00410                         case 'SHADOW':
00411                             if ($this->setup[$conf['textObjNum']]=='TEXT' && $txtConf=$this->checkTextObj($this->setup[$conf['textObjNum'].'.']))   {
00412                                 $this->makeShadow($this->im,$conf,$this->workArea,$txtConf);
00413                             }
00414                         break;
00415 
00416                             // Other
00417                         case 'BOX':
00418                             $this->makeBox($this->im,$conf,$this->workArea);
00419                         break;
00420                         case 'EFFECT':
00421                             $this->makeEffect($this->im,$conf);
00422                         break;
00423                         case 'ADJUST':
00424                             $this->adjust($this->im,$conf);
00425                         break;
00426                         case 'CROP':
00427                             $this->crop($this->im,$conf);
00428                         break;
00429                         case 'SCALE':
00430                             $this->scale($this->im,$conf);
00431                         break;
00432                         case 'WORKAREA':
00433                             if ($conf['set'])   {
00434                                 $this->setWorkArea($conf['set']);   // this sets the workArea
00435                             }
00436                             if (isset($conf['clear']))  {
00437                                 $this->workArea = $this->defaultWorkArea;   // this sets the current to the default;
00438                             }
00439                         break;
00440                         case 'ELLIPSE':
00441                             $this->makeEllipse($this->im, $conf, $this->workArea);
00442                         break;
00443                     }
00444                 }
00445             }
00446         }
00447 
00448 
00449         if ($this->setup['transparentBackground'])  {
00450                 // Auto transparent background is set
00451             $Bcolor = ImageColorExact($this->im, $BGcols[0],$BGcols[1],$BGcols[2]);
00452             imagecolortransparent($this->im, $Bcolor);
00453         } elseif (is_array($this->setup['transparentColor_array'])) {
00454                 // Multiple transparent colors are set. This is done via the trick that all transparent colors get converted to one color and then this one gets set as transparent as png/gif can just have one transparent color.
00455             $Tcolor = $this->unifyColors($this->im, $this->setup['transparentColor_array'], intval($this->setup['transparentColor.']['closest']));
00456             if ($Tcolor>=0) {
00457                 imagecolortransparent($this->im, $Tcolor);
00458             }
00459         }
00460 
00461     }
00462 
00463 
00464 
00465 
00466 
00467 
00468 
00469 
00470 
00471 
00472 
00473 
00474 
00475 
00476 
00477 
00478 
00479 
00480     /*********************************************
00481      *
00482      * Various helper functions
00483      *
00484      ********************************************/
00485 
00486 
00487     /**
00488      * Initializing/Cleaning of TypoScript properties for TEXT GIFBUILDER objects
00489      *
00490      * 'cleans' TEXT-object; Checks fontfile and other vital setup
00491      * Finds the title if its a 'variable' (instantiates a cObj and loads it with the ->data record)
00492      * Performs caseshift if any.
00493      *
00494      * @param   array       GIFBUILDER object TypoScript properties
00495      * @return  array       Modified $conf array IF the "text" property is not blank
00496      * @access private
00497      */
00498     function checkTextObj($conf)    {
00499         $conf['fontFile']=$this->checkFile($conf['fontFile']);
00500         if (!$conf['fontFile']){$conf['fontFile']='t3lib/fonts/nimbus.ttf';}
00501         if (!$conf['iterations']){$conf['iterations'] = 1;}
00502         if (!$conf['fontSize']){$conf['fontSize']=12;}
00503         if ($conf['spacing'] || $conf['wordSpacing'])   {       // If any kind of spacing applys, we cannot use angles!!
00504             $conf['angle']=0;
00505         }
00506         if (!isset($conf['antiAlias'])){$conf['antiAlias']=1;}
00507         $cObj =t3lib_div::makeInstance('tslib_cObj');
00508         $cObj->start($this->data);
00509 
00510         $conf['fontColor'] = trim($cObj->stdWrap($conf['fontColor'], $conf['fontColor.']));
00511         $conf['text']=$cObj->stdWrap($conf['text'],$conf['text.']);
00512             // Strip HTML
00513         if (!$conf['doNotStripHTML'])   {
00514             $conf['text'] = strip_tags($conf['text']);
00515         }
00516         $this->combinedTextStrings[] = strip_tags($conf['text']);
00517 
00518             // Max length = 100 if automatic line braks are not defined:
00519         if (!isset($conf['breakWidth']) || !$conf['breakWidth']) {
00520             $tlen = (intval($conf['textMaxLength']) ? intval($conf['textMaxLength']) : 100);
00521             $conf['text'] = substr($conf['text'], 0, $tlen);
00522         }
00523         if ((string)$conf['text']!='')  {
00524 
00525                 // Char range map thingie:
00526             $fontBaseName = basename($conf['fontFile']);
00527             if (is_array($this->charRangeMap[$fontBaseName]))   {
00528 
00529                     // Initialize splitRendering array:
00530                 if (!is_array($conf['splitRendering.']))    {
00531                     $conf['splitRendering.'] = array();
00532                 }
00533 
00534                 $cfgK = $this->charRangeMap[$fontBaseName]['cfgKey'];
00535                 if (!isset($conf['splitRendering.'][$cfgK]))    {   // Do not impose settings if a splitRendering object already exists:
00536                         // Set configuration:
00537                     $conf['splitRendering.'][$cfgK] = 'charRange';
00538                     $conf['splitRendering.'][$cfgK.'.'] = $this->charRangeMap[$fontBaseName]['charMapConfig'];
00539 
00540                         // multiplicator of fontsize:
00541                     if ($this->charRangeMap[$fontBaseName]['multiplicator'])    {
00542                         $conf['splitRendering.'][$cfgK.'.']['fontSize'] = round($conf['fontSize'] * $this->charRangeMap[$fontBaseName]['multiplicator']);
00543                     }
00544                         // multiplicator of pixelSpace:
00545                     if ($this->charRangeMap[$fontBaseName]['pixelSpace'])   {
00546                         $travKeys = array('xSpaceBefore','xSpaceAfter','ySpaceBefore','ySpaceAfter');
00547                         foreach($travKeys as $pxKey)    {
00548                             if (isset($conf['splitRendering.'][$cfgK.'.'][$pxKey])) {
00549                                 $conf['splitRendering.'][$cfgK.'.'][$pxKey] = round($conf['splitRendering.'][$cfgK.'.'][$pxKey] * ($conf['fontSize'] / $this->charRangeMap[$fontBaseName]['pixelSpace']));
00550                             }
00551                         }
00552                     }
00553                 }
00554             }
00555             if (is_array($conf['splitRendering.'])) {
00556                 foreach($conf['splitRendering.'] as $key => $value) {
00557                     if (is_array($conf['splitRendering.'][$key]))   {
00558                         if (isset($conf['splitRendering.'][$key]['fontFile']))  {
00559                             $conf['splitRendering.'][$key]['fontFile'] = $this->checkFile($conf['splitRendering.'][$key]['fontFile']);
00560                         }
00561                     }
00562                 }
00563             }
00564 
00565             return $conf;
00566         }
00567     }
00568 
00569     /**
00570      * Calculation of offset using "splitCalc" and insertion of dimensions from other GIFBUILDER objects.
00571      *
00572      * Example:
00573      * Input: 2+2, 2*3, 123, [10.w]
00574      * Output: 4,6,123,45  (provided that the width of object in position 10 was 45 pixels wide)
00575      *
00576      * @param   string      The string to resolve/calculate the result of. The string is divided by a comma first and each resulting part is calculated into an integer.
00577      * @return  string      The resolved string with each part (separated by comma) returned separated by comma
00578      * @access private
00579      */
00580     function calcOffset($string)    {
00581         $value = array();
00582         $numbers = t3lib_div::trimExplode(',', $this->calculateFunctions($string));
00583 
00584         foreach ($numbers as $key => $val) {
00585             if ((string)$val == (string)intval($val)) {
00586                 $value[$key] = intval($val);
00587             } else {
00588                 $value[$key] = $this->calculateValue($val);
00589             }
00590         }
00591 
00592         $string = implode(',', $value);
00593         return $string;
00594     }
00595 
00596     /**
00597      * Returns an "imgResource" creating an instance of the tslib_cObj class and calling tslib_cObj::getImgResource
00598      *
00599      * @param   string      Filename value OR the string "GIFBUILDER", see documentation in TSref for the "datatype" called "imgResource"
00600      * @param   array       TypoScript properties passed to the function. Either GIFBUILDER properties or imgResource properties, depending on the value of $file (whether that is "GIFBUILDER" or a file reference)
00601      * @return  array       Returns an array with file information if an image was returned. Otherwise false.
00602      * @access private
00603      * @see tslib_cObj::getImgResource()
00604      * @link http://typo3.org/doc.0.html?&tx_extrepmgm_pi1[extUid]=270&tx_extrepmgm_pi1[tocEl]=315&cHash=63b593a934
00605      * @link http://typo3.org/doc.0.html?&tx_extrepmgm_pi1[extUid]=270&tx_extrepmgm_pi1[tocEl]=282&cHash=831a95115d
00606      */
00607     function getResource($file,$fileArray)  {
00608         if (!t3lib_div::inList($this->imageFileExt, $fileArray['ext'])) {
00609             $fileArray['ext'] = $this->gifExtension;
00610         }
00611         $cObj =t3lib_div::makeInstance('tslib_cObj');
00612         $cObj->start($this->data);
00613         return $cObj->getImgResource($file,$fileArray);
00614     }
00615 
00616     /**
00617      * Returns the reference to a "resource" in TypoScript.
00618      *
00619      * @param   string      The resource value.
00620      * @return  string      Returns the relative filepath
00621      * @access private
00622      * @see t3lib_TStemplate::getFileName()
00623      */
00624     function checkFile($file)   {
00625         return $GLOBALS['TSFE']->tmpl->getFileName($file);
00626     }
00627 
00628     /**
00629      * Calculates the GIFBUILDER output filename/path based on a serialized, hashed value of this->setup
00630      *
00631      * @param   string      Filename prefix, eg. "GB_"
00632      * @return  string      The relative filepath (relative to PATH_site)
00633      * @access private
00634      */
00635     function fileName($pre) {
00636 
00637         $meaningfulPrefix = '';
00638 
00639         if ($GLOBALS['TSFE']->config['config']['meaningfulTempFilePrefix']) {
00640             $meaningfulPrefix = implode('_', array_merge($this->combinedTextStrings, $this->combinedFileNames));
00641                 // strip everything non-ascii
00642             $meaningfulPrefix = preg_replace('/[^A-Za-z0-9_-]/', '', trim($meaningfulPrefix));
00643             $meaningfulPrefix = substr($meaningfulPrefix, 0, intval($GLOBALS['TSFE']->config['config']['meaningfulTempFilePrefix'])) . '_';
00644         }
00645 
00646             // WARNING: In PHP5 I discovered that rendering with freetype of Japanese letters was totally corrupt. Not only the wrong glyphs are printed but also some memory stack overflow resulted in strange additional chars - and finally the reason for this investigation: The Bounding box data was changing all the time resulting in new images being generated all the time. With PHP4 it works fine.
00647         return $this->tempPath.
00648                 $pre.
00649                 $meaningfulPrefix .
00650                 t3lib_div::shortMD5(serialize($this->setup)).
00651                 '.'.$this->extension();
00652     }
00653 
00654     /**
00655      * Returns the file extension used in the filename
00656      *
00657      * @return  string      Extension; "jpg" or "gif"/"png"
00658      * @access private
00659      */
00660     function extension() {
00661         switch(strtolower($this->setup['format']))  {
00662             case 'jpg':
00663             case 'jpeg':
00664                 return 'jpg';
00665             break;
00666             case 'png':
00667                 return 'png';
00668             break;
00669             case 'gif':
00670                 return 'gif';
00671             break;
00672             default:
00673                 return $this->gifExtension;
00674             break;
00675         }
00676     }
00677 
00678     /**
00679      * Calculates the value concerning the dimensions of objects.
00680      *
00681      * @param   string      $string: The string to be calculated (e.g. "[20.h]+13")
00682      * @return  integer     The calculated value (e.g. "23")
00683      * @see     calcOffset()
00684      */
00685     protected function calculateValue($string) {
00686         $calculatedValue = 0;
00687         $parts = t3lib_div::splitCalc($string, '+-*/%');
00688 
00689         foreach ($parts as $part) {
00690             $theVal = $part[1];
00691             $sign = $part[0];
00692 
00693             if ((string)intval($theVal) == (string)$theVal) {
00694                 $theVal = intval($theVal);
00695             } elseif ('[' . substr($theVal, 1, -1) . ']' == $theVal) {
00696                 $objParts = explode('.', substr($theVal, 1, -1));
00697                 $theVal = 0;
00698                 if (isset($this->objBB[$objParts[0]])) {
00699                     if ($objParts[1] == 'w') {
00700                         $theVal = $this->objBB[$objParts[0]][0];
00701                     } elseif ($objParts[1] == 'h') {
00702                         $theVal = $this->objBB[$objParts[0]][1];
00703                     } elseif ($objParts[1] == 'lineHeight') {
00704                         $theVal = $this->objBB[$objParts[0]][2]['lineHeight'];
00705                     }
00706                     $theVal = intval($theVal);
00707                 }
00708             } elseif (floatval($theVal)) {
00709                 $theVal = floatval($theVal);
00710             } else {
00711                 $theVal = 0;
00712             }
00713 
00714             if ($sign == '-') {
00715                 $calculatedValue-= $theVal;
00716             } elseif ($sign == '+') {
00717                 $calculatedValue+= $theVal;
00718             } elseif ($sign == '/' && $theVal) {
00719                 $calculatedValue = $calculatedValue / $theVal;
00720             } elseif ($sign == '*') {
00721                 $calculatedValue = $calculatedValue * $theVal;
00722             } elseif ($sign == '%' && $theVal) {
00723                 $calculatedValue%= $theVal;
00724             }
00725         }
00726 
00727         return round($calculatedValue);
00728     }
00729 
00730     /**
00731      * Calculates special functions:
00732      * + max([10.h], [20.h])    -> gets the maximum of the given values
00733      *
00734      * @param   string      $string: The raw string with functions to be calculated
00735      * @return  string      The calculated values
00736      */
00737     protected function calculateFunctions($string) {
00738         if (preg_match_all('#max\(([^)]+)\)#', $string, $matches)) {
00739             foreach ($matches[1] as $index => $maxExpression) {
00740                 $string = str_replace(
00741                     $matches[0][$index],
00742                     $this->calculateMaximum(
00743                         $maxExpression
00744                     ),
00745                     $string
00746                 );
00747             }
00748         }
00749 
00750         return $string;
00751     }
00752 
00753     /**
00754      * Calculates the maximum of a set of values defined like "[10.h],[20.h],1000"
00755      *
00756      * @param   string      $string: The string to be used to calculate the maximum (e.g. "[10.h],[20.h],1000")
00757      * @return  integer     The maxium value of the given comma separated and calculated values
00758      */
00759     protected function calculateMaximum($string) {
00760         $parts = t3lib_div::trimExplode(',', $this->calcOffset($string), true);
00761         $maximum = (count($parts) ? max($parts) : 0);
00762         return $maximum;
00763     }
00764 }
00765 
00766 
00767 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['tslib/class.tslib_gifbuilder.php'])    {
00768     include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['tslib/class.tslib_gifbuilder.php']);
00769 }
00770 
00771 ?>

Generated on Sat Sep 4 04:17:14 2010 for TYPO3 API by  doxygen 1.4.7