2005-11-23 Sebastian Kurfuerst <sebastian@garbage-group.de>
[Packages/TYPO3.CMS.git] / typo3 / sysext / cms / tslib / class.tslib_gifbuilder.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 1999-2005 Kasper Skaarhoj (kasperYYYY@typo3.com)
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 * A copy is found in the textfile GPL.txt and important notices to the license
17 * from the author is found in LICENSE.txt distributed with these scripts.
18 *
19 *
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
27 /**
28 * Generating gif/png-files from TypoScript
29 * Used by the menu-objects and imgResource in TypoScript.
30 *
31 * $Id$
32 * Revised for TYPO3 3.6 June/2003 by Kasper Skaarhoj
33 *
34 * @author Kasper Skaarhoj <kasperYYYY@typo3.com>
35 */
36 /**
37 * [CLASS/FUNCTION INDEX of SCRIPT]
38 *
39 *
40 *
41 * 102: class tslib_gifBuilder extends t3lib_stdGraphic
42 * 129: function start($conf,$data)
43 * 299: function gifBuild()
44 * 327: function make()
45 *
46 * SECTION: Various helper functions
47 * 478: function checkTextObj($conf)
48 * 557: function calcOffset($string)
49 * 606: function getResource($file,$fileArray)
50 * 621: function checkFile($file)
51 * 632: function fileName($pre)
52 * 648: function extension()
53 *
54 * TOTAL FUNCTIONS: 9
55 * (This index is automatically created/updated by the extension "extdeveval")
56 *
57 */
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79 /**
80 * GIFBUILDER extension class.
81 * This class allows for advanced rendering of images with various layers of images, text and graphical primitives.
82 * 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.
83 * 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])
84 * 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.
85 *
86 * Here is an example of how to use this class (from tslib_content.php, function getImgResource):
87 *
88 * $gifCreator = t3lib_div::makeInstance('tslib_gifbuilder');
89 * $gifCreator->init();
90 * $theImage='';
91 * if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib']) {
92 * $gifCreator->start($fileArray,$this->data);
93 * $theImage = $gifCreator->gifBuild();
94 * }
95 * return $gifCreator->getImageDimensions($theImage);
96 *
97 * @author Kasper Skaarhoj <kasperYYYY@typo3.com>
98 * @package TYPO3
99 * @subpackage tslib
100 * @link http://typo3.org/doc.0.html?&tx_extrepmgm_pi1[extUid]=270&tx_extrepmgm_pi1[tocEl]=377&cHash=e00ac666f3
101 */
102 class tslib_gifBuilder extends t3lib_stdGraphic {
103
104 // Internal
105 var $im = ''; // the main image
106 var $w = 0; // the image-width
107 var $h = 0; // the image-height
108 var $map; // map-data
109 var $workArea;
110 var $setup = Array (); // This holds the operational setup for gifbuilder. Basically this is a TypoScript array with properties.
111 var $combinedTextStrings = array(); // Contains all text strings used on this image
112 var $combinedFileNames = array(); // Contains all filenames (basename without extension) used on this image
113 var $data = Array(); // This is the array from which data->field: [key] is fetched. So this is the current record!
114 var $objBB = Array();
115 var $myClassName = 'gifbuilder';
116 var $charRangeMap=array();
117
118 /**
119 * 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.
120 * Modifies the ->setup, ->objBB internal arrays
121 * Should be called after the ->init() function which initializes the parent class functions/variables in general.
122 * 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.
123 *
124 * @param array TypoScript properties for the GIFBUILDER session. Stored internally in the variable ->setup
125 * @param array The current data record from tslib_cObj. Stored internally in the variable ->data
126 * @return void
127 * @see tslib_cObj::getImgResource(), tslib_gmenu::makeGifs(), tslib_gmenu::findLargestDims()
128 */
129 function start($conf,$data) {
130
131 if (is_array($conf)) {
132 $this->setup = $conf;
133 $this->data = $data;
134
135 /* Hook preprocess gifbuilder conf
136 * Added by Julle for 3.8.0
137 *
138 * Let's you pre-process the gifbuilder configuration. for
139 * example you can split a string up into lines and render each
140 * line as TEXT obj, see extension julle_gifbconf
141 */
142
143 if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_gifbuilder.php']['gifbuilder-ConfPreProcess'])) {
144 foreach($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_gifbuilder.php']['gifbuilder-ConfPreProcess'] as $_funcRef) {
145 $_params = $this->setup;
146 $this->setup = t3lib_div::callUserFunction($_funcRef,$_params,$this);
147 }
148 }
149
150 // Initializing global Char Range Map
151 $this->charRangeMap = array();
152 if (is_array($GLOBALS['TSFE']->tmpl->setup['_GIFBUILDER.']['charRangeMap.'])) {
153 foreach($GLOBALS['TSFE']->tmpl->setup['_GIFBUILDER.']['charRangeMap.'] as $cRMcfgkey => $cRMcfg) {
154 if (is_array($cRMcfg)) {
155
156 // Initializing:
157 $cRMkey = $GLOBALS['TSFE']->tmpl->setup['_GIFBUILDER.']['charRangeMap.'][substr($cRMcfgkey,0,-1)];
158 $this->charRangeMap[$cRMkey] = array();
159 $this->charRangeMap[$cRMkey]['charMapConfig'] = $cRMcfg['charMapConfig.'];
160 $this->charRangeMap[$cRMkey]['cfgKey'] = substr($cRMcfgkey,0,-1);
161 $this->charRangeMap[$cRMkey]['multiplicator'] = (double)$cRMcfg['fontSizeMultiplicator'];
162 $this->charRangeMap[$cRMkey]['pixelSpace'] = intval($cRMcfg['pixelSpaceFontSizeRef']);
163 }
164 }
165 }
166
167 // Getting sorted list of TypoScript keys from setup.
168 $sKeyArray=t3lib_TStemplate::sortedKeyList($this->setup);
169
170 // Setting the background color, passing it through stdWrap
171 if ($conf['backColor.'] || $conf['backColor']) {
172 $cObj =t3lib_div::makeInstance('tslib_cObj');
173 $cObj->start($this->data);
174 $this->setup['backColor'] = trim($cObj->stdWrap($this->setup['backColor'], $this->setup['backColor.']));
175 }
176 if (!$this->setup['backColor']) {$this->setup['backColor']='white';}
177
178 // Transparent GIFs
179 // not working with reduceColors
180 // there's an option for IM: -transparent colors
181 if ($conf['transparentColor.'] || $conf['transparentColor']) {
182 $cObj =t3lib_div::makeInstance('tslib_cObj');
183 $cObj->start($this->data);
184 $this->setup['transparentColor_array'] = explode('|', trim($cObj->stdWrap($this->setup['transparentColor'], $this->setup['transparentColor.'])));
185 }
186
187 // Set default dimensions
188 if (!$this->setup['XY']) {$this->setup['XY']='120,50';}
189
190
191 // Checking TEXT and IMAGE objects for files. If any errors the objects are cleared.
192 // The Bounding Box for the objects is stored in an array
193 foreach($sKeyArray as $theKey) {
194 $theValue = $this->setup[$theKey];
195
196 if (intval($theKey) && $conf=$this->setup[$theKey.'.']) {
197 // Swipes through TEXT and IMAGE-objects
198 switch($theValue) {
199 case 'TEXT':
200 if ($this->setup[$theKey.'.'] = $this->checkTextObj($conf)) {
201
202 // Adjust font width if max size is set:
203 if ($this->setup[$theKey.'.']['maxWidth']) {
204 $this->setup[$theKey.'.']['fontSize'] = $this->fontResize($this->setup[$theKey.'.']); //RTF - this has to be done before calcBBox
205 }
206
207 // Calculate bounding box:
208 $txtInfo=$this->calcBBox($this->setup[$theKey.'.']);
209 $this->setup[$theKey.'.']['BBOX'] = $txtInfo;
210 $this->objBB[$theKey] = $txtInfo;
211 $this->setup[$theKey.'.']['imgMap'] = 0;
212 }
213 break;
214 case 'IMAGE':
215 $fileInfo = $this->getResource($conf['file'],$conf['file.']);
216 if ($fileInfo) {
217 $this->combinedFileNames[] = ereg_replace('\.[[:alnum:]]+$','',basename($fileInfo[3]));
218 $this->setup[$theKey.'.']['file'] = $fileInfo[3];
219 $this->setup[$theKey.'.']['BBOX'] = $fileInfo;
220 $this->objBB[$theKey] = $fileInfo;
221 if ($conf['mask']) {
222 $maskInfo = $this->getResource($conf['mask'],$conf['mask.']);
223 if ($maskInfo) {
224 $this->setup[$theKey.'.']['mask'] = $maskInfo[3];
225 } else {
226 $this->setup[$theKey.'.']['mask'] = '';
227 }
228 }
229 } else {
230 unset($this->setup[$theKey.'.']);
231 }
232 break;
233 }
234 // Checks if disabled is set... (this is also done in menu.php / imgmenu!!)
235 if ($conf['if.']) {
236 $cObj =t3lib_div::makeInstance('tslib_cObj');
237 $cObj->start($this->data);
238
239 if (!$cObj->checkIf($conf['if.'])) {
240 unset($this->setup[$theKey]);
241 unset($this->setup[$theKey.'.']);
242 }
243 }
244 }
245 }
246
247 // Calculate offsets on elements
248 $this->setup['XY'] = $this->calcOffset($this->setup['XY']);
249 $this->setup['offset'] = $this->calcOffset($this->setup['offset']);
250 $this->setup['workArea'] = $this->calcOffset($this->setup['workArea']);
251
252 foreach ($sKeyArray as $theKey) {
253 $theValue=$this->setup[$theKey];
254
255 if (intval($theKey) && $conf=$this->setup[$theKey.'.']) {
256 switch($theValue) {
257 case 'TEXT':
258 case 'IMAGE':
259 if ($this->setup[$theKey.'.']['offset']) {
260 $this->setup[$theKey.'.']['offset'] = $this->calcOffset($this->setup[$theKey.'.']['offset']);
261 }
262 break;
263 case 'BOX':
264 if ($this->setup[$theKey.'.']['dimensions']) {
265 $this->setup[$theKey.'.']['dimensions'] = $this->calcOffset($this->setup[$theKey.'.']['dimensions']);
266 }
267 break;
268 case 'WORKAREA':
269 if ($this->setup[$theKey.'.']['set']) {
270 $this->setup[$theKey.'.']['set'] = $this->calcOffset($this->setup[$theKey.'.']['set']);
271 }
272 break;
273 case 'CROP':
274 if ($this->setup[$theKey.'.']['crop']) {
275 $this->setup[$theKey.'.']['crop'] = $this->calcOffset($this->setup[$theKey.'.']['crop']);
276 }
277 break;
278 case 'SCALE':
279 if ($this->setup[$theKey.'.']['width']) {
280 $this->setup[$theKey.'.']['width'] = $this->calcOffset($this->setup[$theKey.'.']['width']);
281 }
282 if ($this->setup[$theKey.'.']['height']) {
283 $this->setup[$theKey.'.']['height'] = $this->calcOffset($this->setup[$theKey.'.']['height']);
284 }
285 break;
286 }
287 }
288 }
289 // Get trivial data
290 $XY = t3lib_div::intExplode(',',$this->setup['XY']);
291 $maxWidth = intval($this->setup['maxWidth']);
292 $maxHeight = intval($this->setup['maxHeight']);
293
294 $XY[0] = t3lib_div::intInRange($XY[0],1, $maxWidth?$maxWidth:2000);
295 $XY[1] = t3lib_div::intInRange($XY[1],1, $maxHeight?$maxHeight:2000);
296 $this->XY = $XY;
297 $this->w = $XY[0];
298 $this->h = $XY[1];
299 $this->OFFSET = t3lib_div::intExplode(',',$this->setup['offset']);
300
301 $this->setWorkArea($this->setup['workArea']); // this sets the workArea
302 $this->defaultWorkArea = $this->workArea; // this sets the default to the current;
303 }
304 }
305
306 /**
307 * Initiates the image file generation if ->setup is true and if the file did not exist already.
308 * Gets filename from fileName() and if file exists in typo3temp/ dir it will - of course - not be rendered again.
309 * Otherwise rendering means calling ->make(), then ->output(), then ->destroy()
310 *
311 * @return string The filename for the created GIF/PNG file. The filename will be prefixed "GB_"
312 * @see make(), fileName()
313 */
314 function gifBuild() {
315 if ($this->setup) {
316 $gifFileName = $this->fileName('GB/'); // Relative to PATH_site
317 if (!@file_exists($gifFileName)) { // File exists
318
319 // Create temporary directory if not done:
320 $this->createTempSubDir('GB/');
321
322 // Create file:
323 $this->make();
324 $this->output($gifFileName);
325 $this->destroy();
326 }
327 return $gifFileName;
328 }
329 }
330
331 /**
332 * The actual rendering of the image file.
333 * Basically sets the dimensions, the background color, the traverses the array of GIFBUILDER objects and finally setting the transparent color if defined.
334 * Creates a GDlib resource in $this->im and works on that
335 * Called by gifBuild()
336 *
337 * @return void
338 * @access private
339 * @see gifBuild()
340 * @link http://typo3.org/doc.0.html?&tx_extrepmgm_pi1[extUid]=270&tx_extrepmgm_pi1[tocEl]=378&cHash=3c2ae4a1ab
341 */
342 function make() {
343 // Get trivial data
344 $XY = $this->XY;
345
346 // Gif-start
347 $this->im = imagecreate($XY[0],$XY[1]);
348 $this->w = $XY[0];
349 $this->h = $XY[1];
350
351 // backColor is set
352 $cols=$this->convertColor($this->setup['backColor']);
353 ImageColorAllocate($this->im, $cols[0],$cols[1],$cols[2]);
354
355 // Traverse the GIFBUILDER objects an render each one:
356 if (is_array($this->setup)) {
357 $sKeyArray=t3lib_TStemplate::sortedKeyList($this->setup);
358 foreach($sKeyArray as $theKey) {
359 $theValue=$this->setup[$theKey];
360
361 if (intval($theKey) && $conf=$this->setup[$theKey.'.']) {
362 switch($theValue) {
363 // Images
364 case 'IMAGE':
365 if ($conf['mask']) {
366 $this->maskImageOntoImage($this->im,$conf,$this->workArea);
367 } else {
368 $this->copyImageOntoImage($this->im,$conf,$this->workArea);
369 }
370 break;
371
372 // Text
373 case 'TEXT':
374 if (!$conf['hide']) {
375 if (is_array($conf['shadow.'])) {
376 $this->makeShadow($this->im,$conf['shadow.'],$this->workArea,$conf);
377 }
378 if (is_array($conf['emboss.'])) {
379 $this->makeEmboss($this->im,$conf['emboss.'],$this->workArea,$conf);
380 }
381 if (is_array($conf['outline.'])) {
382 $this->makeOutline($this->im,$conf['outline.'],$this->workArea,$conf);
383 }
384 $conf['imgMap']=1;
385 $this->makeText($this->im,$conf,$this->workArea);
386 }
387 break;
388
389 // Text effects:
390 case 'OUTLINE':
391 if ($this->setup[$conf['textObjNum']]=='TEXT' && $txtConf=$this->checkTextObj($this->setup[$conf['textObjNum'].'.'])) {
392 $this->makeOutline($this->im,$conf,$this->workArea,$txtConf);
393 }
394 break;
395 case 'EMBOSS':
396 if ($this->setup[$conf['textObjNum']]=='TEXT' && $txtConf=$this->checkTextObj($this->setup[$conf['textObjNum'].'.'])) {
397 $this->makeEmboss($this->im,$conf,$this->workArea,$txtConf);
398 }
399 break;
400 case 'SHADOW':
401 if ($this->setup[$conf['textObjNum']]=='TEXT' && $txtConf=$this->checkTextObj($this->setup[$conf['textObjNum'].'.'])) {
402 $this->makeShadow($this->im,$conf,$this->workArea,$txtConf);
403 }
404 break;
405
406 // Other
407 case 'BOX':
408 $this->makeBox($this->im,$conf,$this->workArea);
409 break;
410 case 'EFFECT':
411 $this->makeEffect($this->im,$conf);
412 break;
413 case 'ADJUST':
414 $this->adjust($this->im,$conf);
415 break;
416 case 'CROP':
417 $this->crop($this->im,$conf);
418 break;
419 case 'SCALE':
420 $this->scale($this->im,$conf);
421 break;
422 case 'WORKAREA':
423 if ($conf['set']) {
424 $this->setWorkArea($conf['set']); // this sets the workArea
425 }
426 if (isset($conf['clear'])) {
427 $this->workArea = $this->defaultWorkArea; // this sets the current to the default;
428 }
429 break;
430 }
431 }
432 }
433 }
434 // Auto transparent background is set
435 if ($this->setup['transparentBackground']) {
436 imagecolortransparent($this->im, imagecolorat($this->im, 0, 0));
437 }
438 // TransparentColors are set
439 if (is_array($this->setup['transparentColor_array'])) {
440 reset($this->setup['transparentColor_array']);
441 while(list(,$transparentColor)=each($this->setup['transparentColor_array'])) {
442 $cols=$this->convertColor($transparentColor);
443 if ($this->setup['transparentColor.']['closest']) {
444 $colIndex = ImageColorClosest ($this->im, $cols[0],$cols[1],$cols[2]);
445 } else {
446 $colIndex = ImageColorExact ($this->im, $cols[0],$cols[1],$cols[2]);
447 }
448 if ($colIndex > -1) {
449 ImageColorTransparent($this->im, $colIndex);
450 } else {
451 ImageColorTransparent($this->im, ImageColorAllocate($this->im, $cols[0],$cols[1],$cols[2]));
452 }
453 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.
454 }
455 }
456 }
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475 /*********************************************
476 *
477 * Various helper functions
478 *
479 ********************************************/
480
481
482 /**
483 * Initializing/Cleaning of TypoScript properties for TEXT GIFBUILDER objects
484 *
485 * 'cleans' TEXT-object; Checks fontfile and other vital setup
486 * Finds the title if its a 'variable' (instantiates a cObj and loads it with the ->data record)
487 * Performs caseshift if any.
488 *
489 * @param array GIFBUILDER object TypoScript properties
490 * @return array Modified $conf array IF the "text" property is not blank
491 * @access private
492 */
493 function checkTextObj($conf) {
494 $conf['fontFile']=$this->checkFile($conf['fontFile']);
495 if (!$conf['fontFile']){$conf['fontFile']='t3lib/fonts/nimbus.ttf';}
496 if (!$conf['iterations']){$conf['iterations'] = 1;}
497 if (!$conf['fontSize']){$conf['fontSize']=12;}
498 if ($conf['spacing'] || $conf['wordSpacing']) { // If any kind of spacing applys, we cannot use angles!!
499 $conf['angle']=0;
500 }
501 if (!isset($conf['antiAlias'])){$conf['antiAlias']=1;}
502 $cObj =t3lib_div::makeInstance('tslib_cObj');
503 $cObj->start($this->data);
504
505 $conf['fontColor'] = trim($cObj->stdWrap($conf['fontColor'], $conf['fontColor.']));
506 $conf['text']=$cObj->stdWrap($conf['text'],$conf['text.']);
507 // Strip HTML
508 if (!$conf['doNotStripHTML']) {
509 $conf['text'] = strip_tags($conf['text']);
510 }
511 $this->combinedTextStrings[] = strip_tags($conf['text']);
512
513 // Max length = 100
514 $tlen = intval($conf['textMaxLength']) ? intval($conf['textMaxLength']) : 100;
515 $conf['text'] = substr($conf['text'],0,$tlen);
516 if ((string)$conf['text']!='') {
517
518 // Char range map thingie:
519 $fontBaseName = basename($conf['fontFile']);
520 if (is_array($this->charRangeMap[$fontBaseName])) {
521
522 // Initialize splitRendering array:
523 if (!is_array($conf['splitRendering.'])) {
524 $conf['splitRendering.'] = array();
525 }
526
527 $cfgK = $this->charRangeMap[$fontBaseName]['cfgKey'];
528 if (!isset($conf['splitRendering.'][$cfgK])) { // Do not impose settings if a splitRendering object already exists:
529 // Set configuration:
530 $conf['splitRendering.'][$cfgK] = 'charRange';
531 $conf['splitRendering.'][$cfgK.'.'] = $this->charRangeMap[$fontBaseName]['charMapConfig'];
532
533 // multiplicator of fontsize:
534 if ($this->charRangeMap[$fontBaseName]['multiplicator']) {
535 $conf['splitRendering.'][$cfgK.'.']['fontSize'] = round($conf['fontSize'] * $this->charRangeMap[$fontBaseName]['multiplicator']);
536 }
537 // multiplicator of pixelSpace:
538 if ($this->charRangeMap[$fontBaseName]['pixelSpace']) {
539 $travKeys = array('xSpaceBefore','xSpaceAfter','ySpaceBefore','ySpaceAfter');
540 foreach($travKeys as $pxKey) {
541 if (isset($conf['splitRendering.'][$cfgK.'.'][$pxKey])) {
542 $conf['splitRendering.'][$cfgK.'.'][$pxKey] = round($conf['splitRendering.'][$cfgK.'.'][$pxKey] * ($conf['fontSize'] / $this->charRangeMap[$fontBaseName]['pixelSpace']));
543 }
544 }
545 }
546 }
547 }
548 if (is_array($conf['splitRendering.'])) {
549 foreach($conf['splitRendering.'] as $key => $value) {
550 if (is_array($conf['splitRendering.'][$key])) {
551 if (isset($conf['splitRendering.'][$key]['fontFile'])) {
552 $conf['splitRendering.'][$key]['fontFile'] = $this->checkFile($conf['splitRendering.'][$key]['fontFile']);
553 }
554 }
555 }
556 }
557
558 return $conf;
559 }
560 }
561
562 /**
563 * Calculation of offset using "splitCalc" and insertion of dimensions from other GIFBUILDER objects.
564 *
565 * Example:
566 * Input: 2+2, 2*3, 123, [10.w]
567 * Output: 4,6,123,45 (provided that the width of object in position 10 was 45 pixels wide)
568 *
569 * @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.
570 * @return string The resolved string with each part (separated by comma) returned separated by comma
571 * @access private
572 */
573 function calcOffset($string) {
574 $numbers=explode(',',$string);
575 while(list($key,$val)=each($numbers)) {
576 $val = trim($val);
577 if ((string)$val==(string)intval($val)) {
578 $value[$key]=intval($val);
579 } else {
580 $parts= t3lib_div::splitCalc($val,'+-*/%');
581 $value[$key]=0;
582 reset($parts);
583 while(list(,$part)=each($parts)) {
584 $theVal = $part[1];
585 $sign = $part[0];
586 if ((string)intval($theVal)==(string)$theVal) {
587 $theVal = intval($theVal);
588 } elseif ('['.substr($theVal,1,-1).']'==$theVal) {
589 $objParts=explode('.',substr($theVal,1,-1));
590 $theVal=0;
591 if (isset($this->objBB[$objParts[0]])) {
592 if ($objParts[1]=='w') {$theVal=intval($this->objBB[$objParts[0]][0]);}
593 if ($objParts[1]=='h') {$theVal=intval($this->objBB[$objParts[0]][1]);}
594 }
595 } else {
596 $theVal =0;
597 }
598 if ($sign=='-') {$value[$key]-=$theVal;}
599 if ($sign=='+') {$value[$key]+=$theVal;}
600 if ($sign=='/') {if (intval($theVal)) $value[$key]/=intval($theVal);}
601 if ($sign=='*') {$value[$key]*=$theVal;}
602 if ($sign=='%') {if (intval($theVal)) $value[$key]%=intval($theVal);}
603 }
604 $value[$key]=intval($value[$key]);
605 }
606 }
607 $string = implode(',',$value);
608 return $string;
609 }
610
611 /**
612 * Returns an "imgResource" creating an instance of the tslib_cObj class and calling tslib_cObj::getImgResource
613 *
614 * @param string Filename value OR the string "GIFBUILDER", see documentation in TSref for the "datatype" called "imgResource"
615 * @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)
616 * @return array Returns an array with file information if an image was returned. Otherwise false.
617 * @access private
618 * @see tslib_cObj::getImgResource()
619 * @link http://typo3.org/doc.0.html?&tx_extrepmgm_pi1[extUid]=270&tx_extrepmgm_pi1[tocEl]=315&cHash=63b593a934
620 * @link http://typo3.org/doc.0.html?&tx_extrepmgm_pi1[extUid]=270&tx_extrepmgm_pi1[tocEl]=282&cHash=831a95115d
621 */
622 function getResource($file,$fileArray) {
623 $fileArray['ext']= $this->gifExtension;
624 $cObj =t3lib_div::makeInstance('tslib_cObj');
625 $cObj->start($this->data);
626 return $cObj->getImgResource($file,$fileArray);
627 }
628
629 /**
630 * Returns the reference to a "resource" in TypoScript.
631 *
632 * @param string The resource value.
633 * @return string Returns the relative filepath
634 * @access private
635 * @see t3lib_TStemplate::getFileName()
636 */
637 function checkFile($file) {
638 return $GLOBALS['TSFE']->tmpl->getFileName($file);
639 }
640
641 /**
642 * Calculates the GIFBUILDER output filename/path based on a serialized, hashed value of this->setup
643 *
644 * @param string Filename prefix, eg. "GB_"
645 * @return string The relative filepath (relative to PATH_site)
646 * @access private
647 */
648 function fileName($pre) {
649
650 // 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.
651 return $this->tempPath.
652 $pre.
653 ($GLOBALS['TSFE']->config['config']['meaningfulTempFilePrefix'] ? $GLOBALS['TSFE']->fileNameASCIIPrefix(implode('_',array_merge($this->combinedTextStrings,$this->combinedFileNames)),intval($GLOBALS['TSFE']->config['config']['meaningfulTempFilePrefix']),'_') : '').
654 t3lib_div::shortMD5(serialize($this->setup)).
655 '.'.$this->extension();
656 }
657
658 /**
659 * Returns the file extension used in the filename
660 *
661 * @return string Extension; "jpg" or "gif"/"png"
662 * @access private
663 */
664 function extension() {
665 switch(strtolower($this->setup['format'])) {
666 case 'jpg':
667 case 'jpeg':
668 return 'jpg';
669 break;
670 default:
671 return $this->gifExtension;
672 break;
673 }
674 }
675 }
676
677
678 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['tslib/class.tslib_gifbuilder.php']) {
679 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['tslib/class.tslib_gifbuilder.php']);
680 }
681
682 ?>