TYPO3 CMS  TYPO3_6-2
GifBuilder.php
Go to the documentation of this file.
1 <?php
3 
18 
44 
45  // Internal
46  // the main image
50  public $im = '';
51 
52  // the image-width
56  public $w = 0;
57 
58  // the image-height
62  public $h = 0;
63 
64  // map-data
68  public $map;
69 
73  public $workArea;
74 
75  // This holds the operational setup for gifbuilder. Basically this is a TypoScript array with properties.
79  public $setup = array();
80 
81  // Contains all text strings used on this image
85  public $combinedTextStrings = array();
86 
87  // Contains all filenames (basename without extension) used on this image
91  public $combinedFileNames = array();
92 
93  // This is the array from which data->field: [key] is fetched. So this is the current record!
97  public $data = array();
98 
102  public $objBB = array();
103 
107  public $myClassName = 'gifbuilder';
108 
112  public $charRangeMap = array();
113 
126  public function start($conf, $data) {
127  if (is_array($conf)) {
128  $this->setup = $conf;
129  $this->data = $data;
130  $this->cObj = GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\ContentObject\\ContentObjectRenderer');
131  $this->cObj->start($this->data);
132  // Hook preprocess gifbuilder conf
133  // Added by Julle for 3.8.0
134  //
135  // Let's you pre-process the gifbuilder configuration. for
136  // example you can split a string up into lines and render each
137  // line as TEXT obj, see extension julle_gifbconf
138  if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_gifbuilder.php']['gifbuilder-ConfPreProcess'])) {
139  foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_gifbuilder.php']['gifbuilder-ConfPreProcess'] as $_funcRef) {
140  $_params = $this->setup;
141  $this->setup = GeneralUtility::callUserFunction($_funcRef, $_params, $this);
142  }
143  }
144  // Initializing global Char Range Map
145  $this->charRangeMap = array();
146  if (is_array($GLOBALS['TSFE']->tmpl->setup['_GIFBUILDER.']['charRangeMap.'])) {
147  foreach ($GLOBALS['TSFE']->tmpl->setup['_GIFBUILDER.']['charRangeMap.'] as $cRMcfgkey => $cRMcfg) {
148  if (is_array($cRMcfg)) {
149  // Initializing:
150  $cRMkey = $GLOBALS['TSFE']->tmpl->setup['_GIFBUILDER.']['charRangeMap.'][substr($cRMcfgkey, 0, -1)];
151  $this->charRangeMap[$cRMkey] = array();
152  $this->charRangeMap[$cRMkey]['charMapConfig'] = $cRMcfg['charMapConfig.'];
153  $this->charRangeMap[$cRMkey]['cfgKey'] = substr($cRMcfgkey, 0, -1);
154  $this->charRangeMap[$cRMkey]['multiplicator'] = (double) $cRMcfg['fontSizeMultiplicator'];
155  $this->charRangeMap[$cRMkey]['pixelSpace'] = (int)$cRMcfg['pixelSpaceFontSizeRef'];
156  }
157  }
158  }
159  // Getting sorted list of TypoScript keys from setup.
161  // Setting the background color, passing it through stdWrap
162  if ($conf['backColor.'] || $conf['backColor']) {
163  $this->setup['backColor'] = isset($this->setup['backColor.']) ? trim($this->cObj->stdWrap($this->setup['backColor'], $this->setup['backColor.'])) : $this->setup['backColor'];
164  }
165  if (!$this->setup['backColor']) {
166  $this->setup['backColor'] = 'white';
167  }
168  if ($conf['transparentColor.'] || $conf['transparentColor']) {
169  $this->setup['transparentColor_array'] = isset($this->setup['transparentColor.']) ? explode('|', trim($this->cObj->stdWrap($this->setup['transparentColor'], $this->setup['transparentColor.']))) : explode('|', trim($this->setup['transparentColor']));
170  }
171  if (isset($this->setup['transparentBackground.'])) {
172  $this->setup['transparentBackground'] = $this->cObj->stdWrap($this->setup['transparentBackground'], $this->setup['transparentBackground.']);
173  }
174  if (isset($this->setup['reduceColors.'])) {
175  $this->setup['reduceColors'] = $this->cObj->stdWrap($this->setup['reduceColors'], $this->setup['reduceColors.']);
176  }
177  // Set default dimensions
178  if (isset($this->setup['XY.'])) {
179  $this->setup['XY'] = $this->cObj->stdWrap($this->setup['XY'], $this->setup['XY.']);
180  }
181  if (!$this->setup['XY']) {
182  $this->setup['XY'] = '120,50';
183  }
184  // Checking TEXT and IMAGE objects for files. If any errors the objects are cleared.
185  // The Bounding Box for the objects is stored in an array
186  foreach ($sKeyArray as $theKey) {
187  $theValue = $this->setup[$theKey];
188  if ((int)$theKey && ($conf = $this->setup[$theKey . '.'])) {
189  // Swipes through TEXT and IMAGE-objects
190  switch ($theValue) {
191  case 'TEXT':
192  if ($this->setup[$theKey . '.'] = $this->checkTextObj($conf)) {
193  // Adjust font width if max size is set:
194  $maxWidth = isset($this->setup[$theKey . '.']['maxWidth.']) ? $this->cObj->stdWrap($this->setup[$theKey . '.']['maxWidth'], $this->setup[$theKey . '.']['maxWidth.']) : $this->setup[$theKey . '.']['maxWidth'];
195  if ($maxWidth) {
196  $this->setup[$theKey . '.']['fontSize'] = $this->fontResize($this->setup[$theKey . '.']);
197  }
198  // Calculate bounding box:
199  $txtInfo = $this->calcBBox($this->setup[$theKey . '.']);
200  $this->setup[$theKey . '.']['BBOX'] = $txtInfo;
201  $this->objBB[$theKey] = $txtInfo;
202  $this->setup[$theKey . '.']['imgMap'] = 0;
203  }
204  break;
205  case 'IMAGE':
206  $fileInfo = $this->getResource($conf['file'], $conf['file.']);
207  if ($fileInfo) {
208  $this->combinedFileNames[] = preg_replace('/\\.[[:alnum:]]+$/', '', basename($fileInfo[3]));
209  if ($fileInfo['processedFile'] instanceof \TYPO3\CMS\Core\Resource\ProcessedFile) {
210  // Use processed file, if a FAL file has been processed by GIFBUILDER (e.g. scaled/cropped)
211  $this->setup[$theKey . '.']['file'] = $fileInfo['processedFile']->getForLocalProcessing(FALSE);
212  } elseif (!isset($fileInfo['origFile']) && $fileInfo['originalFile'] instanceof \TYPO3\CMS\Core\Resource\File) {
213  // Use FAL file with getForLocalProcessing to circumvent problems with umlauts, if it is a FAL file (origFile not set)
214  $this->setup[$theKey . '.']['file'] = $fileInfo['originalFile']->getForLocalProcessing(FALSE);
215  } else {
216  // Use normal path from fileInfo if it is a non-FAL file (even non-FAL files have originalFile set, but only non-FAL files have origFile set)
217  $this->setup[$theKey . '.']['file'] = $fileInfo[3];
218  }
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  // the same selection criteria as regarding fileInfo above apply here
225  if ($maskInfo['processedFile'] instanceof \TYPO3\CMS\Core\Resource\ProcessedFile) {
226  $this->setup[$theKey . '.']['mask'] = $maskInfo['processedFile']->getForLocalProcessing(FALSE);
227  } elseif (!isset($maskInfo['origFile']) && $maskInfo['originalFile'] instanceof \TYPO3\CMS\Core\Resource\File) {
228  $this->setup[$theKey . '.']['mask'] = $maskInfo['originalFile']->getForLocalProcessing(FALSE);
229  } else {
230  $this->setup[$theKey . '.']['mask'] = $maskInfo[3];
231  }
232  } else {
233  $this->setup[$theKey . '.']['mask'] = '';
234  }
235  }
236  } else {
237  unset($this->setup[$theKey . '.']);
238  }
239  break;
240  }
241  // Checks if disabled is set... (this is also done in menu.php / imgmenu!!)
242  if ($conf['if.']) {
243  $cObj = GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\ContentObject\\ContentObjectRenderer');
244  $cObj->start($this->data);
245  if (!$cObj->checkIf($conf['if.'])) {
246  unset($this->setup[$theKey]);
247  unset($this->setup[$theKey . '.']);
248  unset($this->objBB[$theKey]);
249  }
250  }
251  }
252  }
253  // Calculate offsets on elements
254  $this->setup['XY'] = $this->calcOffset($this->setup['XY']);
255  if (isset($this->setup['offset.'])) {
256  $this->setup['offset'] = $this->cObj->stdWrap($this->setup['offset'], $this->setup['offset.']);
257  }
258  $this->setup['offset'] = $this->calcOffset($this->setup['offset']);
259  if (isset($this->setup['workArea.'])) {
260  $this->setup['workArea'] = $this->cObj->stdWrap($this->setup['workArea'], $this->setup['workArea.']);
261  }
262  $this->setup['workArea'] = $this->calcOffset($this->setup['workArea']);
263  foreach ($sKeyArray as $theKey) {
264  $theValue = $this->setup[$theKey];
265  if ((int)$theKey && ($conf = $this->setup[$theKey . '.'])) {
266  switch ($theValue) {
267  case 'TEXT':
268 
269  case 'IMAGE':
270  if (isset($this->setup[$theKey . '.']['offset.'])) {
271  $this->setup[$theKey . '.']['offset'] = $this->cObj->stdWrap($this->setup[$theKey . '.']['offset'], $this->setup[$theKey . '.']['offset.']);
272  unset($this->setup[$theKey . '.']['offset.']);
273  }
274  if ($this->setup[$theKey . '.']['offset']) {
275  $this->setup[$theKey . '.']['offset'] = $this->calcOffset($this->setup[$theKey . '.']['offset']);
276  }
277  break;
278  case 'BOX':
279 
280  case 'ELLIPSE':
281  if (isset($this->setup[$theKey . '.']['dimensions.'])) {
282  $this->setup[$theKey . '.']['dimensions'] = $this->cObj->stdWrap($this->setup[$theKey . '.']['dimensions'], $this->setup[$theKey . '.']['dimensions.']);
283  unset($this->setup[$theKey . '.']['dimensions.']);
284  }
285  if ($this->setup[$theKey . '.']['dimensions']) {
286  $this->setup[$theKey . '.']['dimensions'] = $this->calcOffset($this->setup[$theKey . '.']['dimensions']);
287  }
288  break;
289  case 'WORKAREA':
290  if (isset($this->setup[$theKey . '.']['set.'])) {
291  $this->setup[$theKey . '.']['set'] = $this->cObj->stdWrap($this->setup[$theKey . '.']['set'], $this->setup[$theKey . '.']['set.']);
292  unset($this->setup[$theKey . '.']['set.']);
293  }
294  if ($this->setup[$theKey . '.']['set']) {
295  $this->setup[$theKey . '.']['set'] = $this->calcOffset($this->setup[$theKey . '.']['set']);
296  }
297  break;
298  case 'CROP':
299  if (isset($this->setup[$theKey . '.']['crop.'])) {
300  $this->setup[$theKey . '.']['crop'] = $this->cObj->stdWrap($this->setup[$theKey . '.']['crop'], $this->setup[$theKey . '.']['crop.']);
301  unset($this->setup[$theKey . '.']['crop.']);
302  }
303  if ($this->setup[$theKey . '.']['crop']) {
304  $this->setup[$theKey . '.']['crop'] = $this->calcOffset($this->setup[$theKey . '.']['crop']);
305  }
306  break;
307  case 'SCALE':
308  if (isset($this->setup[$theKey . '.']['width.'])) {
309  $this->setup[$theKey . '.']['width'] = $this->cObj->stdWrap($this->setup[$theKey . '.']['width'], $this->setup[$theKey . '.']['width.']);
310  unset($this->setup[$theKey . '.']['width.']);
311  }
312  if ($this->setup[$theKey . '.']['width']) {
313  $this->setup[$theKey . '.']['width'] = $this->calcOffset($this->setup[$theKey . '.']['width']);
314  }
315  if (isset($this->setup[$theKey . '.']['height.'])) {
316  $this->setup[$theKey . '.']['height'] = $this->cObj->stdWrap($this->setup[$theKey . '.']['height'], $this->setup[$theKey . '.']['height.']);
317  unset($this->setup[$theKey . '.']['height.']);
318  }
319  if ($this->setup[$theKey . '.']['height']) {
320  $this->setup[$theKey . '.']['height'] = $this->calcOffset($this->setup[$theKey . '.']['height']);
321  }
322  break;
323  }
324  }
325  }
326  // Get trivial data
327  $XY = GeneralUtility::intExplode(',', $this->setup['XY']);
328  $maxWidth = isset($this->setup['maxWidth.']) ? (int)$this->cObj->stdWrap($this->setup['maxWidth'], $this->setup['maxWidth.']) : (int)$this->setup['maxWidth'];
329  $maxHeight = isset($this->setup['maxHeight.']) ? (int)$this->cObj->stdWrap($this->setup['maxHeight'], $this->setup['maxHeight.']) : (int)$this->setup['maxHeight'];
330  $XY[0] = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($XY[0], 1, $maxWidth ?: 2000);
331  $XY[1] = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($XY[1], 1, $maxHeight ?: 2000);
332  $this->XY = $XY;
333  $this->w = $XY[0];
334  $this->h = $XY[1];
335  $this->OFFSET = GeneralUtility::intExplode(',', $this->setup['offset']);
336  // this sets the workArea
337  $this->setWorkArea($this->setup['workArea']);
338  // this sets the default to the current;
339  $this->defaultWorkArea = $this->workArea;
340  }
341  }
342 
352  public function gifBuild() {
353  if ($this->setup) {
354  // Relative to PATH_site
355  $gifFileName = $this->fileName('GB/');
356  // File exists
357  if (!file_exists($gifFileName)) {
358  // Create temporary directory if not done:
359  $this->createTempSubDir('GB/');
360  // Create file:
361  $this->make();
362  $this->output($gifFileName);
363  $this->destroy();
364  }
365  return $gifFileName;
366  }
367  }
368 
380  public function make() {
381  // Get trivial data
382  $XY = $this->XY;
383  // Reset internal properties
384  $this->saveAlphaLayer = FALSE;
385  // Gif-start
386  $this->im = imagecreatetruecolor($XY[0], $XY[1]);
387  $this->w = $XY[0];
388  $this->h = $XY[1];
389  // Transparent layer as background if set and requirements are met
390  if (!empty($this->setup['backColor']) && $this->setup['backColor'] === 'transparent' && $this->png_truecolor && !$this->setup['reduceColors'] && (empty($this->setup['format']) || $this->setup['format'] === 'png')) {
391  // Set transparency properties
392  imagesavealpha($this->im, TRUE);
393  // Fill with a transparent background
394  $transparentColor = imagecolorallocatealpha($this->im, 0, 0, 0, 127);
395  imagefill($this->im, 0, 0, $transparentColor);
396  // Set internal properties to keep the transparency over the rendering process
397  $this->saveAlphaLayer = TRUE;
398  // Force PNG in case no format is set
399  $this->setup['format'] = 'png';
400  } else {
401  // Fill the background with the given color
402  $BGcols = $this->convertColor($this->setup['backColor']);
403  $Bcolor = ImageColorAllocate($this->im, $BGcols[0], $BGcols[1], $BGcols[2]);
404  ImageFilledRectangle($this->im, 0, 0, $XY[0], $XY[1], $Bcolor);
405  }
406  // Traverse the GIFBUILDER objects an render each one:
407  if (is_array($this->setup)) {
409  foreach ($sKeyArray as $theKey) {
410  $theValue = $this->setup[$theKey];
411  if ((int)$theKey && ($conf = $this->setup[$theKey . '.'])) {
412  // apply stdWrap to all properties, except for TEXT objects
413  // all properties of the TEXT sub-object have already been stdWrap-ped
414  // before in ->checkTextObj()
415  if ($theValue !== 'TEXT') {
416  $isStdWrapped = array();
417  foreach ($conf as $key => $value) {
418  $parameter = rtrim($key, '.');
419  if (!$isStdWrapped[$parameter] && isset($conf[$parameter . '.'])) {
420  $conf[$parameter] = $this->cObj->stdWrap($conf[$parameter], $conf[$parameter . '.']);
421  $isStdWrapped[$parameter] = 1;
422  }
423  }
424  }
425 
426  switch ($theValue) {
427  case 'IMAGE':
428  if ($conf['mask']) {
429  $this->maskImageOntoImage($this->im, $conf, $this->workArea);
430  } else {
431  $this->copyImageOntoImage($this->im, $conf, $this->workArea);
432  }
433  break;
434  case 'TEXT':
435  if (!$conf['hide']) {
436  if (is_array($conf['shadow.'])) {
437  $isStdWrapped = array();
438  foreach ($conf['shadow.'] as $key => $value) {
439  $parameter = rtrim($key, '.');
440  if (!$isStdWrapped[$parameter] && isset($conf[$parameter . '.'])) {
441  $conf['shadow.'][$parameter] = $this->cObj->stdWrap($conf[$parameter], $conf[$parameter . '.']);
442  $isStdWrapped[$parameter] = 1;
443  }
444  }
445  $this->makeShadow($this->im, $conf['shadow.'], $this->workArea, $conf);
446  }
447  if (is_array($conf['emboss.'])) {
448  $isStdWrapped = array();
449  foreach ($conf['emboss.'] as $key => $value) {
450  $parameter = rtrim($key, '.');
451  if (!$isStdWrapped[$parameter] && isset($conf[$parameter . '.'])) {
452  $conf['emboss.'][$parameter] = $this->cObj->stdWrap($conf[$parameter], $conf[$parameter . '.']);
453  $isStdWrapped[$parameter] = 1;
454  }
455  }
456  $this->makeEmboss($this->im, $conf['emboss.'], $this->workArea, $conf);
457  }
458  if (is_array($conf['outline.'])) {
459  $isStdWrapped = array();
460  foreach ($conf['outline.'] as $key => $value) {
461  $parameter = rtrim($key, '.');
462  if (!$isStdWrapped[$parameter] && isset($conf[$parameter . '.'])) {
463  $conf['outline.'][$parameter] = $this->cObj->stdWrap($conf[$parameter], $conf[$parameter . '.']);
464  $isStdWrapped[$parameter] = 1;
465  }
466  }
467  $this->makeOutline($this->im, $conf['outline.'], $this->workArea, $conf);
468  }
469  $conf['imgMap'] = 1;
470  $this->makeText($this->im, $conf, $this->workArea);
471  }
472  break;
473  case 'OUTLINE':
474  if ($this->setup[$conf['textObjNum']] == 'TEXT' && ($txtConf = $this->checkTextObj($this->setup[$conf['textObjNum'] . '.']))) {
475  $this->makeOutline($this->im, $conf, $this->workArea, $txtConf);
476  }
477  break;
478  case 'EMBOSS':
479  if ($this->setup[$conf['textObjNum']] == 'TEXT' && ($txtConf = $this->checkTextObj($this->setup[$conf['textObjNum'] . '.']))) {
480  $this->makeEmboss($this->im, $conf, $this->workArea, $txtConf);
481  }
482  break;
483  case 'SHADOW':
484  if ($this->setup[$conf['textObjNum']] == 'TEXT' && ($txtConf = $this->checkTextObj($this->setup[$conf['textObjNum'] . '.']))) {
485  $this->makeShadow($this->im, $conf, $this->workArea, $txtConf);
486  }
487  break;
488  case 'BOX':
489  $this->makeBox($this->im, $conf, $this->workArea);
490  break;
491  case 'EFFECT':
492  $this->makeEffect($this->im, $conf);
493  break;
494  case 'ADJUST':
495  $this->adjust($this->im, $conf);
496  break;
497  case 'CROP':
498  $this->crop($this->im, $conf);
499  break;
500  case 'SCALE':
501  $this->scale($this->im, $conf);
502  break;
503  case 'WORKAREA':
504  if ($conf['set']) {
505  // this sets the workArea
506  $this->setWorkArea($conf['set']);
507  }
508  if (isset($conf['clear'])) {
509  // This sets the current to the default;
510  $this->workArea = $this->defaultWorkArea;
511  }
512  break;
513  case 'ELLIPSE':
514  $this->makeEllipse($this->im, $conf, $this->workArea);
515  break;
516  }
517  }
518  }
519  }
520  // Preserve alpha transparency
521  if (!$this->saveAlphaLayer) {
522  if ($this->setup['transparentBackground']) {
523  // Auto transparent background is set
524  $Bcolor = ImageColorClosest($this->im, $BGcols[0], $BGcols[1], $BGcols[2]);
525  imagecolortransparent($this->im, $Bcolor);
526  } elseif (is_array($this->setup['transparentColor_array'])) {
527  // Multiple transparent colors are set. This is done via the trick that all transparent colors get
528  // converted to one color and then this one gets set as transparent as png/gif can just have one
529  // transparent color.
530  $Tcolor = $this->unifyColors($this->im, $this->setup['transparentColor_array'], (int)$this->setup['transparentColor.']['closest']);
531  if ($Tcolor >= 0) {
532  imagecolortransparent($this->im, $Tcolor);
533  }
534  }
535  }
536  }
537 
538  /*********************************************
539  *
540  * Various helper functions
541  *
542  ********************************************/
555  public function checkTextObj($conf) {
556  $cObj = GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\ContentObject\\ContentObjectRenderer');
557  $cObj->start($this->data);
558  $isStdWrapped = array();
559  foreach ($conf as $key => $value) {
560  $parameter = rtrim($key, '.');
561  if (!$isStdWrapped[$parameter] && isset($conf[$parameter . '.'])) {
562  $conf[$parameter] = $cObj->stdWrap($conf[$parameter], $conf[$parameter . '.']);
563  $isStdWrapped[$parameter] = 1;
564  }
565  }
566  $conf['fontFile'] = $this->checkFile($conf['fontFile']);
567  if (!$conf['fontFile']) {
568  $conf['fontFile'] = 'typo3/sysext/core/Resources/Private/Font/nimbus.ttf';
569  }
570  if (!$conf['iterations']) {
571  $conf['iterations'] = 1;
572  }
573  if (!$conf['fontSize']) {
574  $conf['fontSize'] = 12;
575  }
576  // If any kind of spacing applys, we cannot use angles!!
577  if ($conf['spacing'] || $conf['wordSpacing']) {
578  $conf['angle'] = 0;
579  }
580  if (!isset($conf['antiAlias'])) {
581  $conf['antiAlias'] = 1;
582  }
583  $conf['fontColor'] = trim($conf['fontColor']);
584  // Strip HTML
585  if (!$conf['doNotStripHTML']) {
586  $conf['text'] = strip_tags($conf['text']);
587  }
588  $this->combinedTextStrings[] = strip_tags($conf['text']);
589  // Max length = 100 if automatic line braks are not defined:
590  if (!isset($conf['breakWidth']) || !$conf['breakWidth']) {
591  $tlen = (int)$conf['textMaxLength'] ?: 100;
592  if ($this->nativeCharset) {
593  $conf['text'] = $this->csConvObj->substr($this->nativeCharset, $conf['text'], 0, $tlen);
594  } else {
595  $conf['text'] = substr($conf['text'], 0, $tlen);
596  }
597  }
598  if ((string) $conf['text'] != '') {
599  // Char range map thingie:
600  $fontBaseName = basename($conf['fontFile']);
601  if (is_array($this->charRangeMap[$fontBaseName])) {
602  // Initialize splitRendering array:
603  if (!is_array($conf['splitRendering.'])) {
604  $conf['splitRendering.'] = array();
605  }
606  $cfgK = $this->charRangeMap[$fontBaseName]['cfgKey'];
607  // Do not impose settings if a splitRendering object already exists:
608  if (!isset($conf['splitRendering.'][$cfgK])) {
609  // Set configuration:
610  $conf['splitRendering.'][$cfgK] = 'charRange';
611  $conf['splitRendering.'][$cfgK . '.'] = $this->charRangeMap[$fontBaseName]['charMapConfig'];
612  // Multiplicator of fontsize:
613  if ($this->charRangeMap[$fontBaseName]['multiplicator']) {
614  $conf['splitRendering.'][$cfgK . '.']['fontSize'] = round($conf['fontSize'] * $this->charRangeMap[$fontBaseName]['multiplicator']);
615  }
616  // Multiplicator of pixelSpace:
617  if ($this->charRangeMap[$fontBaseName]['pixelSpace']) {
618  $travKeys = array('xSpaceBefore', 'xSpaceAfter', 'ySpaceBefore', 'ySpaceAfter');
619  foreach ($travKeys as $pxKey) {
620  if (isset($conf['splitRendering.'][$cfgK . '.'][$pxKey])) {
621  $conf['splitRendering.'][$cfgK . '.'][$pxKey] = round($conf['splitRendering.'][($cfgK . '.')][$pxKey] * ($conf['fontSize'] / $this->charRangeMap[$fontBaseName]['pixelSpace']));
622  }
623  }
624  }
625  }
626  }
627  if (is_array($conf['splitRendering.'])) {
628  foreach ($conf['splitRendering.'] as $key => $value) {
629  if (is_array($conf['splitRendering.'][$key])) {
630  if (isset($conf['splitRendering.'][$key]['fontFile'])) {
631  $conf['splitRendering.'][$key]['fontFile'] = $this->checkFile($conf['splitRendering.'][$key]['fontFile']);
632  }
633  }
634  }
635  }
636  return $conf;
637  }
638  }
639 
652  public function calcOffset($string) {
653  $value = array();
654  $numbers = GeneralUtility::trimExplode(',', $this->calculateFunctions($string));
655  foreach ($numbers as $key => $val) {
656  if ((string)$val == (string)(int)$val) {
657  $value[$key] = (int)$val;
658  } else {
659  $value[$key] = $this->calculateValue($val);
660  }
661  }
662  $string = implode(',', $value);
663  return $string;
664  }
665 
676  public function getResource($file, $fileArray) {
677  if (!GeneralUtility::inList($this->imageFileExt, $fileArray['ext'])) {
678  $fileArray['ext'] = $this->gifExtension;
679  }
681  $cObj = GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\ContentObject\\ContentObjectRenderer');
682  $cObj->start($this->data);
683  return $cObj->getImgResource($file, $fileArray);
684  }
685 
695  public function checkFile($file) {
696  return $GLOBALS['TSFE']->tmpl->getFileName($file);
697  }
698 
707  public function fileName($pre) {
708  $meaningfulPrefix = '';
709  if ($GLOBALS['TSFE']->config['config']['meaningfulTempFilePrefix']) {
711  $basicFileFunctions = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Utility\\File\\BasicFileUtility');
712  $meaningfulPrefix = implode('_', array_merge($this->combinedTextStrings, $this->combinedFileNames));
713  $meaningfulPrefix = $basicFileFunctions->cleanFileName($meaningfulPrefix);
714  $meaningfulPrefixLength = (int)$GLOBALS['TSFE']->config['config']['meaningfulTempFilePrefix'];
715  if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['UTF8filesystem']) {
717  $t3libCsInstance = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Charset\\CharsetConverter');
718  $meaningfulPrefix = $t3libCsInstance->substr('utf-8', $meaningfulPrefix, 0, $meaningfulPrefixLength);
719  } else {
720  $meaningfulPrefix = substr($meaningfulPrefix, 0, $meaningfulPrefixLength);
721  }
722  $meaningfulPrefix .= '_';
723  }
724  // WARNING: In PHP5 I discovered that rendering with freetype of Japanese letters was totally corrupt.
725  // Not only the wrong glyphs are printed but also some memory stack overflow resulted in strange additional
726  // chars - and finally the reason for this investigation: The Bounding box data was changing all the time
727  // resulting in new images being generated all the time. With PHP4 it works fine.
728  return $this->tempPath . $pre . $meaningfulPrefix . GeneralUtility::shortMD5(serialize($this->setup)) . '.' . $this->extension();
729  }
730 
738  public function extension() {
739  switch (strtolower($this->setup['format'])) {
740  case 'jpg':
741 
742  case 'jpeg':
743  return 'jpg';
744  break;
745  case 'png':
746  return 'png';
747  break;
748  case 'gif':
749  return 'gif';
750  break;
751  default:
752  return $this->gifExtension;
753  }
754  }
755 
763  protected function calculateValue($string) {
764  $calculatedValue = 0;
765  $parts = GeneralUtility::splitCalc($string, '+-*/%');
766  foreach ($parts as $part) {
767  $theVal = $part[1];
768  $sign = $part[0];
769  if (((string)(int)$theVal) == ((string)$theVal)) {
770  $theVal = (int)$theVal;
771  } elseif ('[' . substr($theVal, 1, -1) . ']' == $theVal) {
772  $objParts = explode('.', substr($theVal, 1, -1));
773  $theVal = 0;
774  if (isset($this->objBB[$objParts[0]])) {
775  if ($objParts[1] == 'w') {
776  $theVal = $this->objBB[$objParts[0]][0];
777  } elseif ($objParts[1] == 'h') {
778  $theVal = $this->objBB[$objParts[0]][1];
779  } elseif ($objParts[1] == 'lineHeight') {
780  $theVal = $this->objBB[$objParts[0]][2]['lineHeight'];
781  }
782  $theVal = (int)$theVal;
783  }
784  } elseif (floatval($theVal)) {
785  $theVal = floatval($theVal);
786  } else {
787  $theVal = 0;
788  }
789  if ($sign == '-') {
790  $calculatedValue -= $theVal;
791  } elseif ($sign == '+') {
792  $calculatedValue += $theVal;
793  } elseif ($sign == '/' && $theVal) {
794  $calculatedValue = $calculatedValue / $theVal;
795  } elseif ($sign == '*') {
796  $calculatedValue = $calculatedValue * $theVal;
797  } elseif ($sign == '%' && $theVal) {
798  $calculatedValue %= $theVal;
799  }
800  }
801  return round($calculatedValue);
802  }
803 
811  protected function calculateFunctions($string) {
812  if (preg_match_all('#max\\(([^)]+)\\)#', $string, $matches)) {
813  foreach ($matches[1] as $index => $maxExpression) {
814  $string = str_replace($matches[0][$index], $this->calculateMaximum($maxExpression), $string);
815  }
816  }
817  return $string;
818  }
819 
826  protected function calculateMaximum($string) {
827  $parts = GeneralUtility::trimExplode(',', $this->calcOffset($string), TRUE);
828  $maximum = count($parts) ? max($parts) : 0;
829  return $maximum;
830  }
831 
832 }
makeEmboss(&$im, $conf, $workArea, $txtConf)
static forceIntegerInRange($theInt, $min, $max=2000000000, $defaultValue=0)
Definition: MathUtility.php:32
makeEllipse(&$im, array $conf, array $workArea)
static intExplode($delimiter, $string, $removeEmptyValues=FALSE, $limit=0)
static trimExplode($delim, $string, $removeEmptyValues=FALSE, $limit=0)
static callUserFunction($funcName, &$params, &$ref, $checkPrefix='', $errorMode=0)
makeShadow(&$im, $conf, $workArea, $txtConf)
makeOutline(&$im, $conf, $workArea, $txtConf)
static splitCalc($string, $operators)
unifyColors(&$img, $colArr, $closest=FALSE)
if(!defined('TYPO3_MODE')) $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauth.php']['logoff_pre_processing'][]
static sortedKeyList($setupArr, $acceptOnlyProperties=FALSE)