Documentation TYPO3 par Ameos |
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 ?>