00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00155 class t3lib_stdGraphic {
00156
00157
00158 var $combineScript = 'combine';
00159 var $noFramePrepended=0;
00160 var $GD2=0;
00161 var $imagecopyresized_fix=0;
00162 var $gifExtension = 'gif';
00163 var $gdlibExtensions = '';
00164 var $truecolor = true;
00165 var $png_truecolor = false;
00166 var $truecolorColors = 0xffffff;
00167 var $TTFLocaleConv = '';
00168 var $enable_typo3temp_db_tracking = 0;
00169 var $imageFileExt = 'gif,jpg,jpeg,png,tif,bmp,tga,pcx,ai,pdf';
00170 var $webImageExt = 'gif,jpg,jpeg,png';
00171 var $maskNegate = '';
00172 var $NO_IM_EFFECTS = '';
00173 var $cmds = Array (
00174 'jpg' => '',
00175 'jpeg' => '',
00176 'gif' => '-colors 64',
00177 'png' => '-colors 64'
00178 );
00179 var $NO_IMAGE_MAGICK = '';
00180 var $V5_EFFECTS = 0;
00181 var $im_version_4 = 0;
00182 var $mayScaleUp = 1;
00183
00184
00185 var $filenamePrefix='';
00186 var $imageMagickConvert_forceFileNameBody='';
00187 var $dontCheckForExistingTempFile = 0;
00188 var $dontCompress=0;
00189 var $dontUnlinkTempFiles=0;
00190 var $alternativeOutputKey='';
00191
00192
00193 var $IM_commands = Array();
00194 var $workArea = Array();
00195
00196
00197 var $tempPath = 'typo3temp/';
00198 var $absPrefix = '';
00199 var $scalecmd = '-geometry';
00200 var $im5fx_blurSteps='1x2,2x2,3x2,4x3,5x3,5x4,6x4,7x5,8x5,9x5';
00201 var $im5fx_sharpenSteps='1x2,2x2,3x2,2x3,3x3,4x3,3x4,4x4,4x5,5x5';
00202 var $pixelLimitGif = 10000;
00203 var $colMap = Array (
00204 'aqua' => Array(0,255,255),
00205 'black' => Array(0,0,0),
00206 'blue' => Array(0,0,255),
00207 'fuchsia' => Array(255,0,255),
00208 'gray' => Array(128,128,128),
00209 'green' => Array(0,128,0),
00210 'lime' => Array(0,255,0),
00211 'maroon' => Array(128,0,0),
00212 'navy' => Array(0,0,128),
00213 'olive' => Array(128,128,0),
00214 'purple' => Array(128,0,128),
00215 'red' => Array(255,0,0),
00216 'silver' => Array(192,192,192),
00217 'teal' => Array(0,128,128),
00218 'yellow' => Array(255,255,0),
00219 'white' => Array(255,255,255)
00220 );
00221
00222
00223 var $csConvObj;
00224 var $nativeCharset='';
00225
00226
00227
00228
00229
00236 function init() {
00237 $gfxConf = $GLOBALS['TYPO3_CONF_VARS']['GFX'];
00238
00239 if (function_exists('imagecreatefromjpeg')&&function_exists('imagejpeg')) {
00240 $this->gdlibExtensions .= ',jpg,jpeg';
00241 }
00242 if (function_exists('imagecreatefrompng')&&function_exists('imagepng')) {
00243 $this->gdlibExtensions .= ',png';
00244 }
00245 if (function_exists('imagecreatefromgif')&&function_exists('imagegif')) {
00246 $this->gdlibExtensions .= ',gif';
00247 }
00248 if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['png_truecolor']) {
00249 $this->png_truecolor = true;
00250 }
00251 if (!$gfxConf['gdlib_2'] || !function_exists('imagecreatetruecolor')) {
00252 $this->truecolor = false;
00253 }
00254 if (!$gfxConf['im_version_5']) {
00255 $this->im_version_4 = true;
00256 }
00257
00258
00259 if ($this->truecolor) {
00260 if ($this->png_truecolor) {
00261 $this->cmds['png'] = '';
00262 }
00263 $this->cmds['gif'] = '';
00264 }
00265
00266
00267 $this->jpegQuality = t3lib_div::intInRange($gfxConf['jpg_quality'], 10, 100, 75);
00268 $this->cmds['jpg'] = $this->cmds['jpeg'] = '-colorspace RGB -sharpen 50 -quality '.$this->jpegQuality;
00269
00270 if ($gfxConf['im_combine_filename']) $this->combineScript=$gfxConf['im_combine_filename'];
00271 if ($gfxConf['im_noFramePrepended']) $this->noFramePrepended=1;
00272
00273 if ($gfxConf['gdlib_2']) {
00274 $this->GD2 = 1;
00275 $this->imagecopyresized_fix = $gfxConf['gdlib_2']==='no_imagecopyresized_fix' ? 0 : 1;
00276 }
00277 if ($gfxConf['gdlib_png']) {
00278 $this->gifExtension='png';
00279 }
00280 if ($gfxConf['TTFLocaleConv']) {
00281 $this->TTFLocaleConv = $gfxConf['TTFLocaleConv'];
00282 }
00283 if ($gfxConf['enable_typo3temp_db_tracking']) {
00284 $this->enable_typo3temp_db_tracking = $gfxConf['enable_typo3temp_db_tracking'];
00285 }
00286
00287 $this->imageFileExt = $gfxConf['imagefile_ext'];
00288
00289
00290 if ($gfxConf['im_negate_mask']) {
00291
00292
00293
00294
00295 $this->maskNegate = ' -negate';
00296 }
00297 if ($gfxConf['im_no_effects']) {
00298
00299
00300
00301
00302 $this->NO_IM_EFFECTS = 1;
00303
00304 $this->cmds['jpg'] = $this->cmds['jpeg'] = '-colorspace RGB -quality '.$this->jpegQuality;
00305 }
00306
00307 if ($gfxConf['im_v5effects']) {
00308 $this->NO_IM_EFFECTS = 0;
00309 $this->V5_EFFECTS = 1;
00310
00311 if ($gfxConf['im_v5effects']>0) {
00312 $this->cmds['jpg'] = $this->cmds['jpeg'] = '-colorspace RGB -quality '.intval($gfxConf['jpg_quality']).$this->v5_sharpen(10);
00313 }
00314 }
00315
00316 if (!$gfxConf['im']) {
00317 $this->NO_IMAGE_MAGICK = 1;
00318 }
00319
00320 if ($gfxConf['im_noScaleUp']) {
00321 $this->mayScaleUp=0;
00322 }
00323
00324 if (TYPO3_MODE=='FE') {
00325 $this->csConvObj = &$GLOBALS['TSFE']->csConvObj;
00326 } elseif(is_object($GLOBALS['LANG'])) {
00327 $this->csConvObj = &$GLOBALS['LANG']->csConvObj;
00328 } else {
00329 $this->csConvObj = t3lib_div::makeInstance('t3lib_cs');
00330 }
00331 $this->nativeCharset = $GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'];
00332 }
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00366 function maskImageOntoImage(&$im,$conf,$workArea) {
00367 if ($conf['file'] && $conf['mask']) {
00368 $imgInf = pathinfo($conf['file']);
00369 $imgExt = strtolower($imgInf['extension']);
00370 if (!t3lib_div::inList($this->gdlibExtensions, $imgExt)) {
00371 $BBimage = $this->imageMagickConvert($conf['file'],$this->gifExtension,'','','','','');
00372 } else {
00373 $BBimage = $this->getImageDimensions($conf['file']);
00374 }
00375 $maskInf = pathinfo($conf['mask']);
00376 $maskExt = strtolower($maskInf['extension']);
00377 if (!t3lib_div::inList($this->gdlibExtensions, $maskExt)) {
00378 $BBmask = $this->imageMagickConvert($conf['mask'],$this->gifExtension,'','','','','');
00379 } else {
00380 $BBmask = $this->getImageDimensions($conf['mask']);
00381 }
00382 if ($BBimage && $BBmask) {
00383 $w = imagesx($im);
00384 $h = imagesy($im);
00385 $tmpStr = $this->randomName();
00386 $theImage = $tmpStr.'_img.'.$this->gifExtension;
00387 $theDest = $tmpStr.'_dest.'.$this->gifExtension;
00388 $theMask = $tmpStr.'_mask.'.$this->gifExtension;
00389
00390 $cpImg = $this->imageCreateFromFile($BBimage[3]);
00391 $destImg = $this->imagecreate($w,$h);
00392 $Bcolor = ImageColorAllocate($destImg, 0,0,0);
00393 ImageFilledRectangle($destImg, 0, 0, $w, $h, $Bcolor);
00394 $this->copyGifOntoGif($destImg,$cpImg,$conf,$workArea);
00395 $this->ImageWrite($destImg, $theImage);
00396 imageDestroy($cpImg);
00397 imageDestroy($destImg);
00398
00399 $cpImg = $this->imageCreateFromFile($BBmask[3]);
00400 $destImg = $this->imagecreate($w,$h);
00401 $Bcolor = ImageColorAllocate($destImg, 0, 0, 0);
00402 ImageFilledRectangle($destImg, 0, 0, $w, $h, $Bcolor);
00403 $this->copyGifOntoGif($destImg,$cpImg,$conf,$workArea);
00404 $this->ImageWrite($destImg, $theMask);
00405 imageDestroy($cpImg);
00406 imageDestroy($destImg);
00407
00408 $this->ImageWrite($im, $theDest);
00409
00410 $this->combineExec($theDest,$theImage,$theMask,$theDest, true);
00411
00412 $backIm = $this->imageCreateFromFile($theDest);
00413 if ($backIm) {
00414 ImageColorTransparent($backIm,-1);
00415 $im = $backIm;
00416 }
00417
00418 if (!$this->dontUnlinkTempFiles) {
00419 unlink($theDest);
00420 unlink($theImage);
00421 unlink($theMask);
00422 }
00423 }
00424 }
00425 }
00426
00436 function copyImageOntoImage(&$im,$conf,$workArea) {
00437 if ($conf['file']) {
00438 if (!t3lib_div::inList($this->gdlibExtensions, $conf['BBOX'][2])) {
00439 $conf['BBOX']=$this->imageMagickConvert($conf['BBOX'][3],$this->gifExtension,'','','','','');
00440 $conf['file']=$conf['BBOX'][3];
00441 }
00442 $cpImg = $this->imageCreateFromFile($conf['file']);
00443 $this->copyGifOntoGif($im,$cpImg,$conf,$workArea);
00444 imageDestroy($cpImg);
00445 }
00446 }
00447
00458 function copyGifOntoGif(&$im,$cpImg,$conf,$workArea) {
00459 $cpW = imagesx($cpImg);
00460 $cpH = imagesy($cpImg);
00461 $tile = t3lib_div::intExplode(',',$conf['tile']);
00462 $tile[0] = t3lib_div::intInRange($tile[0],1,20);
00463 $tile[1] = t3lib_div::intInRange($tile[1],1,20);
00464 $cpOff = $this->objPosition($conf,$workArea,Array($cpW*$tile[0],$cpH*$tile[1]));
00465
00466 for ($xt=0;$xt<$tile[0];$xt++) {
00467 $Xstart=$cpOff[0]+$cpW*$xt;
00468 if ($Xstart+$cpW > $workArea[0]) {
00469
00470 if ($Xstart < $workArea[0]) {
00471 $cpImgCutX = $workArea[0]-$Xstart;
00472 $Xstart = $workArea[0];
00473 } else {
00474 $cpImgCutX = 0;
00475 }
00476 $w = $cpW-$cpImgCutX;
00477 if ($Xstart > $workArea[0]+$workArea[2]-$w) {
00478 $w = $workArea[0]+$workArea[2]-$Xstart;
00479 }
00480 if ($Xstart < $workArea[0]+$workArea[2]) {
00481
00482 for ($yt=0;$yt<$tile[1];$yt++) {
00483 $Ystart=$cpOff[1]+$cpH*$yt;
00484 if ($Ystart+$cpH > $workArea[1]) {
00485 if ($Ystart < $workArea[1]) {
00486 $cpImgCutY = $workArea[1]-$Ystart;
00487 $Ystart = $workArea[1];
00488 } else {
00489 $cpImgCutY = 0;
00490 }
00491 $h = $cpH-$cpImgCutY;
00492 if ($Ystart > $workArea[1]+$workArea[3]-$h) {
00493 $h = $workArea[1]+$workArea[3]-$Ystart;
00494 }
00495 if ($Ystart < $workArea[1]+$workArea[3]) {
00496 $this->imagecopyresized($im, $cpImg, $Xstart, $Ystart, $cpImgCutX, $cpImgCutY, $w, $h, $w, $h);
00497 }
00498 }
00499 }
00500 }
00501 }
00502 }
00503 }
00504
00537 function imagecopyresized(&$im, $cpImg, $Xstart, $Ystart, $cpImgCutX, $cpImgCutY, $w, $h, $w, $h) {
00538 if ($this->imagecopyresized_fix) {
00539 $im_base = $this->imagecreate(imagesx($im), imagesy($im));
00540 imagecopyresized($im_base, $im, 0,0,0,0, imagesx($im),imagesy($im),imagesx($im),imagesy($im));
00541 imagecopyresized($im_base, $cpImg, $Xstart, $Ystart, $cpImgCutX, $cpImgCutY, $w, $h, $w, $h);
00542 $im = $im_base;
00543 if (!$this->truecolor) {
00544 $this->makeEffect($im, Array('value'=>'colors='.t3lib_div::intInRange($this->setup['reduceColors'], 256, $this->truecolorColors, 256)));
00545 }
00546 } else {
00547 imagecopyresized($im, $cpImg, $Xstart, $Ystart, $cpImgCutX, $cpImgCutY, $w, $h, $w, $h);
00548 }
00549 }
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00587 function makeText(&$im,$conf,$workArea) {
00588
00589 list($spacing,$wordSpacing) = $this->calcWordSpacing($conf);
00590
00591 $txtPos = $this->txtPosition($conf,$workArea,$conf['BBOX']);
00592 $theText = $this->recodeString($conf['text']);
00593
00594 if ($conf['imgMap'] && is_array($conf['imgMap.'])) {
00595 $this->addToMap($this->calcTextCordsForMap($conf['BBOX'][2],$txtPos, $conf['imgMap.']), $conf['imgMap.']);
00596 }
00597 if (!$conf['hideButCreateMap']) {
00598
00599 $cols=$this->convertColor($conf['fontColor']);
00600
00601 if (!$conf['niceText']) {
00602
00603 if (!$this->truecolor) {
00604 $reduce = t3lib_div::intInRange($this->setup['reduceColors'], 256, $this->truecolorColors, 256);
00605 $this->reduceColors($im, $reduce-49, $reduce-50);
00606 }
00607 $Fcolor = ImageColorAllocate($im, $cols[0],$cols[1],$cols[2]);
00608
00609 $Fcolor = ($conf['antiAlias']) ? $Fcolor : -$Fcolor;
00610
00611 for ($a=0; $a<$conf['iterations']; $a++) {
00612 if ($spacing || $wordSpacing) {
00613 $this->SpacedImageTTFText($im, $conf['fontSize'], $conf['angle'], $txtPos[0], $txtPos[1], $Fcolor, t3lib_stdGraphic::prependAbsolutePath($conf['fontFile']), $theText, $spacing, $wordSpacing, $conf['splitRendering.']);
00614 } else {
00615 $this->ImageTTFTextWrapper($im, $conf['fontSize'], $conf['angle'], $txtPos[0], $txtPos[1], $Fcolor, $conf['fontFile'], $theText, $conf['splitRendering.']);
00616 }
00617 }
00618 } else {
00619
00620 $w = imagesx($im);
00621 $h = imagesy($im);
00622 $tmpStr = $this->randomName();
00623
00624 $fileMenu = $tmpStr.'_menuNT.'.$this->gifExtension;
00625 $fileColor = $tmpStr.'_colorNT.'.$this->gifExtension;
00626 $fileMask = $tmpStr.'_maskNT.'.$this->gifExtension;
00627
00628 $sF = t3lib_div::intInRange($conf['niceText.']['scaleFactor'],2,5);
00629 $newW = ceil($sF*imagesx($im));
00630 $newH = ceil($sF*imagesy($im));
00631
00632
00633 $maskImg = $this->imagecreate($newW, $newH);
00634 $Bcolor = ImageColorAllocate($maskImg, 255,255,255);
00635 ImageFilledRectangle($maskImg, 0, 0, $newW, $newH, $Bcolor);
00636 $Fcolor = ImageColorAllocate($maskImg, 0,0,0);
00637 if ($spacing || $wordSpacing) {
00638 $this->SpacedImageTTFText($maskImg, $conf['fontSize'], $conf['angle'], $txtPos[0], $txtPos[1], $Fcolor, t3lib_stdGraphic::prependAbsolutePath($conf['fontFile']), $theText, $spacing, $wordSpacing, $conf['splitRendering.'],$sF);
00639 } else {
00640 $this->ImageTTFTextWrapper($maskImg, $conf['fontSize'], $conf['angle'], $txtPos[0], $txtPos[1], $Fcolor, $conf['fontFile'], $theText, $conf['splitRendering.'],$sF);
00641 }
00642 $this->ImageWrite($maskImg, $fileMask);
00643 ImageDestroy($maskImg);
00644
00645
00646 if ($this->NO_IM_EFFECTS) {
00647 if ($this->maskNegate) {
00648 $command = trim($this->scalecmd.' '.$w.'x'.$h.'!');
00649 } else {
00650 $command = trim($this->scalecmd.' '.$w.'x'.$h.'! -negate');
00651 }
00652 } else {
00653 if ($this->maskNegate) {
00654 $command = trim($conf['niceText.']['before'].' '.$this->scalecmd.' '.$w.'x'.$h.'! '.$conf['niceText.']['after']);
00655 } else {
00656 $command = trim($conf['niceText.']['before'].' '.$this->scalecmd.' '.$w.'x'.$h.'! '.$conf['niceText.']['after'].' -negate');
00657 }
00658 if ($conf['niceText.']['sharpen']) {
00659 if ($this->V5_EFFECTS) {
00660 $command.=$this->v5_sharpen($conf['niceText.']['sharpen']);
00661 } else {
00662 $command.=' -sharpen '.t3lib_div::intInRange($conf['niceText.']['sharpen'],1,99);
00663 }
00664 }
00665 }
00666
00667 $this->imageMagickExec($fileMask,$fileMask,$command);
00668
00669
00670 $colorImg = $this->imagecreate($w,$h);
00671 $Ccolor = ImageColorAllocate($colorImg, $cols[0],$cols[1],$cols[2]);
00672 ImageFilledRectangle($colorImg, 0, 0, $w, $h, $Ccolor);
00673 $this->ImageWrite($colorImg, $fileColor);
00674 ImageDestroy($colorImg);
00675
00676
00677 $this->ImageWrite($im, $fileMenu);
00678
00679 $this->combineExec($fileMenu,$fileColor,$fileMask, $fileMenu);
00680
00681 $backIm = $this->imageCreateFromFile($fileMenu);
00682 if ($backIm) {
00683 ImageColorTransparent($backIm,-1);
00684 $im = $backIm;
00685 }
00686
00687
00688 if (!$this->dontUnlinkTempFiles) {
00689 unlink($fileMenu);
00690 unlink($fileColor);
00691 unlink($fileMask);
00692 }
00693 }
00694 }
00695 }
00696
00707 function txtPosition($conf,$workArea,$BB) {
00708 $bbox = $BB[2];
00709 $angle=intval($conf['angle'])/180*pi();
00710 $conf['angle']=0;
00711 $straightBB = $this->calcBBox($conf);
00712
00713
00714 $result=Array();
00715 $result[2] = $BB[0];
00716 $result[3] = $BB[1];
00717 $w=$workArea[2];
00718 $h=$workArea[3];
00719
00720 switch($conf['align']) {
00721 case 'right':
00722 case 'center':
00723 $factor=abs(cos($angle));
00724 $sign=(cos($angle)<0)?-1:1;
00725 $len1 = $sign*$factor*$straightBB[0];
00726 $len2= $sign*$BB[0];
00727 $result[0] = $w-ceil($len2*$factor+(1-$factor)*$len1);
00728
00729 $factor=abs(sin($angle));
00730 $sign=(sin($angle)<0)?-1:1;
00731 $len1= $sign*$factor*$straightBB[0];
00732 $len2= $sign*$BB[1];
00733 $result[1]=ceil($len2*$factor+(1-$factor)*$len1);
00734 break;
00735 }
00736 switch($conf['align']) {
00737 case 'right':
00738 break;
00739 case 'center':
00740 $result[0] = round(($result[0])/2);
00741 $result[1] = round(($result[1])/2);
00742 break;
00743 default:
00744 $result[0]=0;
00745 $result[1]=0;
00746 break;
00747 }
00748 $result = $this->applyOffset($result,t3lib_div::intExplode(',',$conf['offset']));
00749 $result = $this->applyOffset($result,$workArea);
00750 return $result;
00751 }
00752
00761 function calcBBox($conf) {
00762 $sF = $this->getTextScalFactor($conf);
00763 list($spacing,$wordSpacing) = $this->calcWordSpacing($conf, $sF);
00764 $theText = $this->recodeString($conf['text']);
00765
00766 $charInf = $this->ImageTTFBBoxWrapper($conf['fontSize'], $conf['angle'], $conf['fontFile'], $theText, $conf['splitRendering.'],$sF);
00767 $theBBoxInfo = $charInf;
00768 if ($conf['angle']) {
00769 $xArr = Array($charInf[0],$charInf[2],$charInf[4],$charInf[6]);
00770 $yArr = Array($charInf[1],$charInf[3],$charInf[5],$charInf[7]);
00771 $x=max($xArr)-min($xArr);
00772 $y=max($yArr)-min($yArr);
00773 } else {
00774 $x = ($charInf[2]-$charInf[0]);
00775 $y = ($charInf[1]-$charInf[7]);
00776 }
00777 if ($spacing || $wordSpacing) {
00778 $x=0;
00779 if (!$spacing && $wordSpacing) {
00780 $bits = explode(' ',$theText);
00781 while(list(,$word)=each($bits)) {
00782 $word.=' ';
00783 $wordInf = $this->ImageTTFBBoxWrapper($conf['fontSize'], $conf['angle'], $conf['fontFile'], $word, $conf['splitRendering.'],$sF);
00784 $wordW = ($wordInf[2]-$wordInf[0]);
00785 $x+=$wordW+$wordSpacing;
00786 }
00787 } else {
00788 $utf8Chars = $this->singleChars($theText);
00789
00790 foreach($utf8Chars as $char) {
00791 $charInf = $this->ImageTTFBBoxWrapper($conf['fontSize'], $conf['angle'], $conf['fontFile'], $char, $conf['splitRendering.'],$sF);
00792 $charW = ($charInf[2]-$charInf[0]);
00793 $x+=$charW+(($char==' ')?$wordSpacing:$spacing);
00794 }
00795 }
00796 }
00797
00798 if ($sF>1) {
00799 $x = ceil($x/$sF);
00800 $y = ceil($y/$sF);
00801 if (is_array($theBBoxInfo)) {
00802 reset($theBBoxInfo);
00803 while(list($key,$val)=each($theBBoxInfo)) {
00804 $theBBoxInfo[$key]=ceil($theBBoxInfo[$key]/$sF);
00805 }
00806 }
00807 }
00808 return array($x,$y,$theBBoxInfo);
00809 }
00810
00820 function addToMap($cords,$conf) {
00821 $JS = $conf['noBlur'] ? '' : ' onfocus="blurLink(this);"';
00822
00823 $this->map.='<area'.
00824 ' shape="poly"'.
00825 ' coords="'.implode(',',$cords).'"'.
00826 ' href="'.htmlspecialchars($conf['url']).'"'.
00827 ($conf['target'] ? ' target="'.htmlspecialchars($conf['target']).'"' : '').
00828 $JS.
00829 (strlen($conf['titleText']) ? ' title="'.htmlspecialchars($conf['titleText']).'"' : '').
00830 ' alt="'.htmlspecialchars($conf['altText']).'" />';
00831 }
00832
00843 function calcTextCordsForMap($cords,$offset, $conf) {
00844 $pars = t3lib_div::intExplode(',',$conf['explode'].',');
00845
00846 $newCords[0] = $cords[0]+$offset[0]-$pars[0];
00847 $newCords[1] = $cords[1]+$offset[1]+$pars[1];
00848 $newCords[2] = $cords[2]+$offset[0]+$pars[0];
00849 $newCords[3] = $cords[3]+$offset[1]+$pars[1];
00850 $newCords[4] = $cords[4]+$offset[0]+$pars[0];
00851 $newCords[5] = $cords[5]+$offset[1]-$pars[1];
00852 $newCords[6] = $cords[6]+$offset[0]-$pars[0];
00853 $newCords[7] = $cords[7]+$offset[1]-$pars[1];
00854
00855 return $newCords;
00856 }
00857
00878 function SpacedImageTTFText(&$im, $fontSize, $angle, $x, $y, $Fcolor, $fontFile, $text, $spacing, $wordSpacing, $splitRenderingConf, $sF=1) {
00879
00880 $spacing*=$sF;
00881 $wordSpacing*=$sF;
00882
00883 if (!$spacing && $wordSpacing) {
00884 $bits = explode(' ',$text);
00885 reset($bits);
00886 while(list(,$word)=each($bits)) {
00887 $word.=' ';
00888 $word = $word;
00889 $wordInf = $this->ImageTTFBBoxWrapper($fontSize, $angle, $fontFile, $word, $splitRenderingConf ,$sF);
00890 $wordW = ($wordInf[2]-$wordInf[0]);
00891 $this->ImageTTFTextWrapper($im, $fontSize, $angle, $x, $y, $Fcolor, $fontFile, $word, $splitRenderingConf, $sF);
00892 $x+=$wordW+$wordSpacing;
00893 }
00894 } else {
00895 $utf8Chars = $this->singleChars($text);
00896
00897 foreach($utf8Chars as $char) {
00898 $charInf = $this->ImageTTFBBoxWrapper($fontSize, $angle, $fontFile, $char, $splitRenderingConf, $sF);
00899 $charW = ($charInf[2]-$charInf[0]);
00900 $this->ImageTTFTextWrapper($im, $fontSize, $angle, $x, $y, $Fcolor, $fontFile, $char, $splitRenderingConf, $sF);
00901 $x+=$charW+(($char==' ')?$wordSpacing:$spacing);
00902 }
00903 }
00904 }
00905
00915 function fontResize($conf) {
00916
00917 $maxWidth = intval($conf['maxWidth']);
00918 list($spacing,$wordSpacing) = $this->calcWordSpacing($conf);
00919 if ($maxWidth) {
00920 if ($spacing || $wordSpacing) {
00921 return $conf['fontSize'];
00922
00923 } else {
00924 do {
00925
00926 $bounds = $this->ImageTTFBBoxWrapper($conf['fontSize'], $conf['angle'], $conf['fontFile'], $this->recodeString($conf['text']), $conf['splitRendering.']);
00927 if ($conf['angle']< 0) {
00928 $pixelWidth = abs($bounds[4]-$bounds[0]);
00929 } elseif ($conf['angle'] > 0) {
00930 $pixelWidth = abs($bounds[2]-$bounds[6]);
00931 } else {
00932 $pixelWidth = abs($bounds[4]-$bounds[6]);
00933 }
00934
00935
00936 if ($pixelWidth <= $maxWidth) {
00937 break;
00938 } else {
00939 $conf['fontSize']--;
00940 }
00941 } while ($conf['fontSize']>1);
00942 }
00943 }
00944 return $conf['fontSize'];
00945 }
00946
00958 function ImageTTFBBoxWrapper($fontSize, $angle, $fontFile, $string, $splitRendering, $sF=1) {
00959
00960
00961 $offsetInfo = array();
00962 $stringParts = $this->splitString($string,$splitRendering,$fontSize,$fontFile);
00963
00964
00965 foreach($stringParts as $strCfg) {
00966 $fontFile = t3lib_stdGraphic::prependAbsolutePath($strCfg['fontFile']);
00967 if (is_readable($fontFile)) {
00968
00969
00970 $calc = ImageTTFBBox(t3lib_div::freetypeDpiComp($sF*$strCfg['fontSize']), $angle, $fontFile, $strCfg['str']);
00971
00972
00973 if (!count($offsetInfo)) {
00974 $offsetInfo = $calc;
00975 } else {
00976 $offsetInfo[2]+=$calc[2]-$calc[0]+intval($splitRendering['compX'])+intval($strCfg['xSpaceBefore'])+intval($strCfg['xSpaceAfter']);
00977 $offsetInfo[3]+=$calc[3]-$calc[1]-intval($splitRendering['compY'])-intval($strCfg['ySpaceBefore'])-intval($strCfg['ySpaceAfter']);
00978 $offsetInfo[4]+=$calc[4]-$calc[6]+intval($splitRendering['compX'])+intval($strCfg['xSpaceBefore'])+intval($strCfg['xSpaceAfter']);
00979 $offsetInfo[5]+=$calc[5]-$calc[7]-intval($splitRendering['compY'])-intval($strCfg['ySpaceBefore'])-intval($strCfg['ySpaceAfter']);
00980 }
00981
00982 } else {
00983 debug('cannot read file: '.$fontFile, 't3lib_stdGraphic::ImageTTFBBoxWrapper()');
00984 }
00985 }
00986
00987 return $offsetInfo;
00988 }
00989
01005 function ImageTTFTextWrapper($im, $fontSize, $angle, $x, $y, $color, $fontFile, $string, $splitRendering,$sF=1) {
01006
01007
01008 $stringParts = $this->splitString($string,$splitRendering,$fontSize,$fontFile);
01009 $x = ceil($sF*$x);
01010 $y = ceil($sF*$y);
01011
01012
01013 foreach($stringParts as $i => $strCfg) {
01014
01015
01016 $colorIndex = $color;
01017
01018
01019 if ($strCfg['color'] && $sF==1) {
01020 $cols = $this->convertColor($strCfg['color']);
01021 $colorIndex = ImageColorAllocate($im, $cols[0],$cols[1],$cols[2]);
01022 $colorIndex = $color >= 0 ? $colorIndex : -$colorIndex;
01023 }
01024
01025
01026 if ($i) {
01027 $x+= intval($strCfg['xSpaceBefore']);
01028 $y-= intval($strCfg['ySpaceBefore']);
01029 }
01030
01031 $fontFile = t3lib_stdGraphic::prependAbsolutePath($strCfg['fontFile']);
01032 if (is_readable($fontFile)) {
01033
01034
01035 ImageTTFText($im, t3lib_div::freetypeDpiComp($sF*$strCfg['fontSize']), $angle, $x, $y, $colorIndex, $fontFile, $strCfg['str']);
01036
01037
01038 $wordInf = ImageTTFBBox(t3lib_div::freetypeDpiComp($sF*$strCfg['fontSize']), $angle, t3lib_stdGraphic::prependAbsolutePath($strCfg['fontFile']), $strCfg['str']);
01039 $x+= $wordInf[2]-$wordInf[0]+intval($splitRendering['compX'])+intval($strCfg['xSpaceAfter']);
01040 $y+= $wordInf[5]-$wordInf[7]-intval($splitRendering['compY'])-intval($strCfg['ySpaceAfter']);
01041
01042 } else {
01043 debug('cannot read file: '.$fontFile, 't3lib_stdGraphic::ImageTTFTextWrapper()');
01044 }
01045
01046 }
01047 }
01048
01058 function splitString($string,$splitRendering,$fontSize,$fontFile) {
01059
01060
01061 $result = array();
01062 $result[] = array(
01063 'str' => $string,
01064 'fontSize' => $fontSize,
01065 'fontFile' => $fontFile
01066 );
01067
01068
01069
01070 if (is_array($splitRendering)) {
01071 $sKeyArray = t3lib_TStemplate::sortedKeyList($splitRendering);
01072
01073
01074 foreach($sKeyArray as $key) {
01075 $cfg = $splitRendering[$key.'.'];
01076
01077
01078 switch((string)$splitRendering[$key]) {
01079 case 'highlightWord':
01080 if (strlen($cfg['value'])) {
01081 $newResult = array();
01082
01083
01084 foreach($result as $part) {
01085
01086 $explodedParts = explode($cfg['value'],$part['str']);
01087 foreach($explodedParts as $c => $expValue) {
01088 if (strlen($expValue)) {
01089 $newResult[] = array_merge($part,array('str' => $expValue));
01090 }
01091 if ($c+1 < count($explodedParts)) {
01092 $newResult[] = array(
01093 'str' => $cfg['value'],
01094 'fontSize' => $cfg['fontSize'] ? $cfg['fontSize'] : $part['fontSize'],
01095 'fontFile' => $cfg['fontFile'] ? $cfg['fontFile'] : $part['fontFile'],
01096 'color' => $cfg['color'],
01097 'xSpaceBefore' => $cfg['xSpaceBefore'],
01098 'xSpaceAfter' => $cfg['xSpaceAfter'],
01099 'ySpaceBefore' => $cfg['ySpaceBefore'],
01100 'ySpaceAfter' => $cfg['ySpaceAfter'],
01101 );
01102 }
01103 }
01104 }
01105
01106
01107 if (count($newResult)) {
01108 $result = $newResult;
01109 }
01110 }
01111 break;
01112 case 'charRange':
01113 if (strlen($cfg['value'])) {
01114
01115
01116 $ranges = t3lib_div::trimExplode(',',$cfg['value'],1);
01117 foreach($ranges as $i => $rangeDef) {
01118 $ranges[$i] = t3lib_div::intExplode('-',$ranges[$i]);
01119 if (!isset($ranges[$i][1])) $ranges[$i][1] = $ranges[$i][0];
01120 }
01121 $newResult = array();
01122
01123
01124 foreach($result as $part) {
01125
01126
01127 $currentState = -1;
01128 $bankAccum = '';
01129
01130
01131 $utf8Chars = $this->singleChars($part['str']);
01132 foreach($utf8Chars as $utfChar) {
01133
01134
01135 $uNumber = $this->csConvObj->utf8CharToUnumber($utfChar);
01136 $inRange = 0;
01137 foreach($ranges as $rangeDef) {
01138 if ($uNumber >= $rangeDef[0] && (!$rangeDef[1] || $uNumber <= $rangeDef[1])) {
01139 $inRange = 1;
01140 break;
01141 }
01142 }
01143 if ($currentState==-1) $currentState = $inRange;
01144
01145
01146 if ($inRange != $currentState && !t3lib_div::inList('32,10,13,9',$uNumber)) {
01147
01148
01149 if (strlen($bankAccum)) {
01150 $newResult[] = array(
01151 'str' => $bankAccum,
01152 'fontSize' => $currentState && $cfg['fontSize'] ? $cfg['fontSize'] : $part['fontSize'],
01153 'fontFile' => $currentState && $cfg['fontFile'] ? $cfg['fontFile'] : $part['fontFile'],
01154 'color' => $currentState ? $cfg['color'] : '',
01155 'xSpaceBefore' => $currentState ? $cfg['xSpaceBefore'] : '',
01156 'xSpaceAfter' => $currentState ? $cfg['xSpaceAfter'] : '',
01157 'ySpaceBefore' => $currentState ? $cfg['ySpaceBefore'] : '',
01158 'ySpaceAfter' => $currentState ? $cfg['ySpaceAfter'] : '',
01159 );
01160 }
01161
01162
01163 $currentState = $inRange;
01164 $bankAccum = '';
01165 }
01166
01167
01168 $bankAccum.=$utfChar;
01169 }
01170
01171
01172 if (strlen($bankAccum)) {
01173 $newResult[] = array(
01174 'str' => $bankAccum,
01175 'fontSize' => $currentState && $cfg['fontSize'] ? $cfg['fontSize'] : $part['fontSize'],
01176 'fontFile' => $currentState && $cfg['fontFile'] ? $cfg['fontFile'] : $part['fontFile'],
01177 'color' => $currentState ? $cfg['color'] : '',
01178 'xSpaceBefore' => $currentState ? $cfg['xSpaceBefore'] : '',
01179 'xSpaceAfter' => $currentState ? $cfg['xSpaceAfter'] : '',
01180 'ySpaceBefore' => $currentState ? $cfg['ySpaceBefore'] : '',
01181 'ySpaceAfter' => $currentState ? $cfg['ySpaceAfter'] : '',
01182 );
01183 }
01184 }
01185
01186
01187 if (count($newResult)) {
01188 $result = $newResult;
01189 }
01190 }
01191 break;
01192 }
01193 }
01194 }
01195
01196 return $result;
01197 }
01198
01208 function calcWordSpacing($conf, $scaleFactor=1) {
01209
01210 $spacing = intval($conf['spacing']);
01211 $wordSpacing = intval($conf['wordSpacing']);
01212 $wordSpacing = $wordSpacing?$wordSpacing:$spacing*2;
01213
01214 $spacing*=$scaleFactor;
01215 $wordSpacing*=$scaleFactor;
01216
01217 return array($spacing,$wordSpacing);
01218 }
01219
01227 function getTextScalFactor($conf) {
01228 if (!$conf['niceText']) {
01229 $sF = 1;
01230 } else {
01231 $sF = t3lib_div::intInRange($conf['niceText.']['scaleFactor'],2,5);
01232 }
01233 return $sF;
01234 }
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01262 function makeOutline(&$im,$conf,$workArea,$txtConf) {
01263 $thickness = intval($conf['thickness']);
01264 if ($thickness) {
01265 $txtConf['fontColor'] = $conf['color'];
01266 $outLineDist = t3lib_div::intInRange($thickness,1,2);
01267 for ($b=1;$b<=$outLineDist;$b++) {
01268 if ($b==1) {
01269 $it = 8;
01270 } else {
01271 $it = 16;
01272 }
01273 $outL = $this->circleOffset($b, $it);
01274 for ($a=0;$a<$it;$a++) {
01275 $this->makeText($im,$txtConf,$this->applyOffset($workArea,$outL[$a]));
01276 }
01277 }
01278 }
01279 }
01280
01291 function circleOffset($distance, $iterations) {
01292 $res = Array();
01293 if ($distance && $iterations) {
01294 for ($a=0;$a<$iterations;$a++) {
01295 $yOff = round(sin(2*pi()/$iterations*($a+1))*100*$distance);
01296 if ($yOff) {$yOff = intval(ceil(abs($yOff/100))*($yOff/abs($yOff)));}
01297 $xOff = round(cos(2*pi()/$iterations*($a+1))*100*$distance);
01298 if ($xOff) {$xOff = intval(ceil(abs($xOff/100))*($xOff/abs($xOff)));}
01299 $res[$a] = Array($xOff,$yOff);
01300 }
01301 }
01302 return $res;
01303 }
01304
01315 function makeEmboss(&$im,$conf,$workArea,$txtConf) {
01316 $conf['color']=$conf['highColor'];
01317 $this->makeShadow($im,$conf,$workArea,$txtConf);
01318 $newOffset = t3lib_div::intExplode(',',$conf['offset']);
01319 $newOffset[0]*=-1;
01320 $newOffset[1]*=-1;
01321 $conf['offset']=implode(',',$newOffset);
01322 $conf['color']=$conf['lowColor'];
01323 $this->makeShadow($im,$conf,$workArea,$txtConf);
01324 }
01325
01337 function makeShadow(&$im,$conf,$workArea,$txtConf) {
01338 $workArea = $this->applyOffset($workArea,t3lib_div::intExplode(',',$conf['offset']));
01339 $blurRate = t3lib_div::intInRange(intval($conf['blur']),0,99);
01340
01341 if (!$blurRate || $this->NO_IM_EFFECTS) {
01342 $txtConf['fontColor'] = $conf['color'];
01343 $this->makeText($im,$txtConf,$workArea);
01344 } else {
01345 $w = imagesx($im);
01346 $h = imagesy($im);
01347 $blurBorder= 3;
01348 $tmpStr = $this->randomName();
01349 $fileMenu = $tmpStr.'_menu.'.$this->gifExtension;
01350 $fileColor = $tmpStr.'_color.'.$this->gifExtension;
01351 $fileMask = $tmpStr.'_mask.'.$this->gifExtension;
01352
01353
01354 $blurColImg = $this->imagecreate($w,$h);
01355 $bcols=$this->convertColor($conf['color']);
01356 $Bcolor = ImageColorAllocate($blurColImg, $bcols[0],$bcols[1],$bcols[2]);
01357 ImageFilledRectangle($blurColImg, 0, 0, $w, $h, $Bcolor);
01358 $this->ImageWrite($blurColImg, $fileColor);
01359 ImageDestroy($blurColImg);
01360
01361
01362 $blurTextImg = $this->imagecreate($w+$blurBorder*2,$h+$blurBorder*2);
01363 $Bcolor = ImageColorAllocate($blurTextImg, 0,0,0);
01364 ImageFilledRectangle($blurTextImg, 0, 0, $w+$blurBorder*2, $h+$blurBorder*2, $Bcolor);
01365 $txtConf['fontColor'] = 'white';
01366 $blurBordArr = Array($blurBorder,$blurBorder);
01367 $this->makeText($blurTextImg,$txtConf, $this->applyOffset($workArea,$blurBordArr));
01368 $this->ImageWrite($blurTextImg, $fileMask);
01369 ImageDestroy($blurTextImg);
01370
01371
01372 $command='';
01373 $command.=$this->maskNegate;
01374
01375 if ($this->V5_EFFECTS) {
01376 $command.=$this->v5_blur($blurRate+1);
01377 } else {
01378
01379 $times = ceil($blurRate/10);
01380 $newBlurRate = $blurRate*4;
01381 $newBlurRate = t3lib_div::intInRange($newBlurRate,1,99);
01382 for ($a=0;$a<$times;$a++) {
01383 $command.=' -blur '.$blurRate;
01384 }
01385 }
01386
01387