Fixed bug #10629: class and title parameters of typolinks get broken
[Packages/TYPO3.CMS.git] / t3lib / class.t3lib_stdgraphic.php
index 916d0e2..eb248e6 100644 (file)
@@ -1,22 +1,22 @@
 <?php
 /***************************************************************
 *  Copyright notice
-*  
-*  (c) 1999-2003 Kasper Skårhøj (kasper@typo3.com)
+*
+*  (c) 1999-2009 Kasper Skaarhoj (kasperYYYY@typo3.com)
 *  All rights reserved
 *
-*  This script is part of the TYPO3 project. The TYPO3 project is 
+*  This script is part of the TYPO3 project. The TYPO3 project is
 *  free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
-* 
+*
 *  The GNU General Public License can be found at
 *  http://www.gnu.org/copyleft/gpl.html.
-*  A copy is found in the textfile GPL.txt and important notices to the license 
+*  A copy is found in the textfile GPL.txt and important notices to the license
 *  from the author is found in LICENSE.txt distributed with these scripts.
 *
-* 
+*
 *  This script is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *
 *  This copyright notice MUST APPEAR in all copies of the script!
 ***************************************************************/
-/** 
+/**
  * Standard graphical functions
  *
- * Revised for TYPO3 3.6 July/2003 by Kasper Skårhøj
+ * $Id$
+ * Revised for TYPO3 3.6 July/2003 by Kasper Skaarhoj
+ *
+ * @author     Kasper Skaarhoj <kasperYYYY@typo3.com>
  */
 /**
  * [CLASS/FUNCTION INDEX of SCRIPT]
  *
  *
  *
- *  138: class t3lib_stdGraphic        
- *  213:     function init()   
+ *  155: class t3lib_stdGraphic
+ *  236:     function init()
  *
  *              SECTION: Layering images / "IMAGE" GIFBUILDER object
- *  312:     function maskImageOntoImage(&$im,$conf,$workArea) 
- *  372:     function copyImageOntoImage(&$im,$conf,$workArea) 
- *  394:     function copyGifOntoGif(&$im,$cpImg,$conf,$workArea)      
- *  473:     function imagecopyresized(&$im, $cpImg, $Xstart, $Ystart, $cpImgCutX, $cpImgCutY, $w, $h, $w, $h) 
+ *  366:     function maskImageOntoImage(&$im,$conf,$workArea)
+ *  436:     function copyImageOntoImage(&$im,$conf,$workArea)
+ *  458:     function copyGifOntoGif(&$im,$cpImg,$conf,$workArea)
+ *  537:     function imagecopyresized(&$im, $cpImg, $Xstart, $Ystart, $cpImgCutX, $cpImgCutY, $w, $h, $w, $h)
  *
  *              SECTION: Text / "TEXT" GIFBUILDER object
- *  522:     function makeText(&$im,$conf,$workArea)   
- *  638:     function txtPosition($conf,$workArea,$BB) 
- *  692:     function calcBBox($conf)  
- *  761:     function addToMap($cords,$conf)   
- *  776:     function calcTextCordsForMap($cords,$offset, $conf)       
- *  809:     function SpacedImageTTFText(&$im, $fontSize, $angle, $x, $y, $Fcolor, $fontFile, $text, $spacing, $wordSpacing)   
- *  842:     function fontResize($conf) 
+ *  587:     function makeText(&$im,$conf,$workArea)
+ *  707:     function txtPosition($conf,$workArea,$BB)
+ *  761:     function calcBBox($conf)
+ *  820:     function addToMap($cords,$conf)
+ *  843:     function calcTextCordsForMap($cords,$offset, $conf)
+ *  878:     function SpacedImageTTFText(&$im, $fontSize, $angle, $x, $y, $Fcolor, $fontFile, $text, $spacing, $wordSpacing, $splitRenderingConf, $sF=1)
+ *  915:     function fontResize($conf)
+ *  958:     function ImageTTFBBoxWrapper($fontSize, $angle, $fontFile, $string, $splitRendering, $sF=1)
+ * 1005:     function ImageTTFTextWrapper($im, $fontSize, $angle, $x, $y, $color, $fontFile, $string, $splitRendering,$sF=1)
+ * 1058:     function splitString($string,$splitRendering,$fontSize,$fontFile)
+ * 1208:     function calcWordSpacing($conf, $scaleFactor=1)
+ * 1227:     function getTextScalFactor($conf)
  *
  *              SECTION: Other GIFBUILDER objects related to TEXT
- *  904:     function makeOutline(&$im,$conf,$workArea,$txtConf)       
- *  933:     function circleOffset($distance, $iterations)     
- *  957:     function makeEmboss(&$im,$conf,$workArea,$txtConf)        
- *  979:     function makeShadow(&$im,$conf,$workArea,$txtConf)        
+ * 1262:     function makeOutline(&$im,$conf,$workArea,$txtConf)
+ * 1291:     function circleOffset($distance, $iterations)
+ * 1315:     function makeEmboss(&$im,$conf,$workArea,$txtConf)
+ * 1337:     function makeShadow(&$im,$conf,$workArea,$txtConf)
  *
  *              SECTION: Other GIFBUILDER objects
- * 1109:     function makeBox(&$im,$conf,$workArea)    
- * 1128:     function makeEffect(&$im, $conf)  
- * 1143:     function IMparams($setup) 
- * 1226:     function adjust(&$im, $conf)      
- * 1258:     function crop(&$im,$conf) 
- * 1288:     function scale(&$im,$conf)        
- * 1320:     function setWorkArea($workArea)   
+ * 1469:     function makeBox(&$im,$conf,$workArea)
+ * 1491:     function makeEffect(&$im, $conf)
+ * 1506:     function IMparams($setup)
+ * 1589:     function adjust(&$im, $conf)
+ * 1621:     function crop(&$im,$conf)
+ * 1652:     function scale(&$im,$conf)
+ * 1684:     function setWorkArea($workArea)
  *
  *              SECTION: Adjustment functions
- * 1361:     function autolevels(&$im) 
- * 1392:     function outputLevels(&$im,$low,$high,$swap='')   
- * 1424:     function inputLevels(&$im,$low,$high,$swap='')    
- * 1455:     function reduceColors(&$im,$limit, $cols) 
+ * 1725:     function autolevels(&$im)
+ * 1756:     function outputLevels(&$im,$low,$high,$swap='')
+ * 1788:     function inputLevels(&$im,$low,$high,$swap='')
+ * 1819:     function reduceColors(&$im,$limit, $cols)
+ * 1832:     function IMreduceColors($file, $cols)
  *
  *              SECTION: GIFBUILDER Helper functions
- * 1493:     function prependAbsolutePath($fontFile)   
- * 1507:     function v5_sharpen($factor)      
- * 1526:     function v5_blur($factor) 
- * 1543:     function randomName()     
- * 1555:     function applyOffset($cords,$OFFSET)      
- * 1568:     function convertColor($string)    
- * 1618:     function recodeString($string)    
- * 1639:     function singleChars($theText)    
- * 1662:     function objPosition($conf,$workArea,$BB) 
+ * 1875:     function prependAbsolutePath($fontFile)
+ * 1889:     function v5_sharpen($factor)
+ * 1908:     function v5_blur($factor)
+ * 1925:     function randomName()
+ * 1938:     function applyOffset($cords,$OFFSET)
+ * 1951:     function convertColor($string)
+ * 2001:     function recodeString($string)
+ * 2023:     function singleChars($theText,$returnUnicodeNumber=FALSE)
+ * 2046:     function objPosition($conf,$workArea,$BB)
  *
  *              SECTION: Scaling, Dimensions of images
- * 1741:     function imageMagickConvert($imagefile,$newExt='',$w='',$h='',$params='',$frame='',$options='',$mustCreate=0)     
- * 1824:     function getImageDimensions($imagefile)   
- * 1846:     function getImageScale($info,$w,$h,$options) 
- * 1934:     function file_exists_typo3temp_file($output,$orig='')     
+ * 2125:     function imageMagickConvert($imagefile,$newExt='',$w='',$h='',$params='',$frame='',$options='',$mustCreate=0)
+ * 2238:     function getImageDimensions($imageFile)
+ * 2266:     function cacheImageDimensions($identifyResult)
+ * 2298:     function getCachedImageDimensions($imageFile)
+ * 2332:     function getImageScale($info,$w,$h,$options)
+ * 2438:     function file_exists_typo3temp_file($output,$orig='')
  *
  *              SECTION: ImageMagick API functions
- * 1991:     function imageMagickIdentify($imagefile)  
- * 2024:     function imageMagickExec($input,$output,$params)  
- * 2042:     function combineExec($input,$overlay,$mask,$output)       
- * 2057:     function wrapFileName($inputName) 
+ * 2499:     function imageMagickIdentify($imagefile)
+ * 2534:     function imageMagickExec($input,$output,$params)
+ * 2557:     function combineExec($input,$overlay,$mask,$output, $handleNegation = false)
+ * 2588:     function wrapFileName($inputName)
  *
  *              SECTION: Various IO functions
- * 2098:     function checkFile($file) 
- * 2113:     function applyImageMagickToPHPGif(&$im, $command) 
- * 2139:     function gif_or_jpg($type,$w,$h)  
- * 2156:     function output($file)    
- * 2200:     function destroy()        
- * 2210:     function imgTag ($imgInfo) 
- * 2222:     function ImageGif($destImg, $theImage)    
- * 2239:     function imageCreateFromGif($sourceImg)   
+ * 2629:     function checkFile($file)
+ * 2643:     function createTempSubDir($dirName)
+ * 2665:     function applyImageMagickToPHPGif(&$im, $command)
+ * 2691:     function gif_or_jpg($type,$w,$h)
+ * 2708:     function output($file)
+ * 2748:     function destroy()
+ * 2758:     function imgTag ($imgInfo)
+ * 2770:     function ImageWrite($destImg, $theImage)
+ * 2808:     function imageGif($destImg, $theImage)
+ * 2820:     function imageCreateFromGif($sourceImg)
+ * 2831:     function imageCreateFromFile($sourceImg)
+ * 2870:     function imagecreate($w, $h)
+ * 2885:     function hexColor($col)
+ * 2903:     function unifyColors(&$img, $colArr, $closest = false)
  *
- * TOTAL FUNCTIONS: 52
+ * TOTAL FUNCTIONS: 66
  * (This index is automatically created/updated by the extension "extdeveval")
  *
  */
 /**
  * Class contains a bunch of cool functions for manipulating graphics with GDlib/Freetype and ImageMagick
  * VERY OFTEN used with gifbuilder that extends this class and provides a TypoScript API to using these functions
- * 
- * @author     Kasper Skårhøj <kasper@typo3.com>
+ *
+ * @author     Kasper Skaarhoj <kasperYYYY@typo3.com>
  * @package TYPO3
  * @subpackage t3lib
  * @see tslib_gifBuilder
@@ -141,22 +158,27 @@ class t3lib_stdGraphic    {
        var $combineScript = 'combine';                         // The ImageMagick filename used for combining two images. This name changed during the versions.
        var $noFramePrepended=0;                                        // If set, there is no frame pointer prepended to the filenames.
        var $GD2=0;                                                                     // Set, if the GDlib used is version 2.
+       var $imagecopyresized_fix=0;                            // If set, imagecopyresized will not be called directly. For GD2 (some PHP installs?)
        var $gifExtension = 'gif';                                      // This should be changed to 'png' if you want this class to read/make PNG-files instead!
+       var $gdlibExtensions = '';                      // File formats supported by gdlib. This variable get's filled in "init" method
+       var $truecolor = true;                                  // Internal variable which get's used to determine wheter GDlib should use function truecolor pendants
+       var $png_truecolor = false;                                     // Set to true if generated png's should be truecolor by default
+       var $truecolorColors = 0xffffff;                        // 16777216 Colors is the maximum value for PNG, JPEG truecolor images (24-bit, 8-bit / Channel)
        var $TTFLocaleConv = '';                                        // Used to recode input to TTF-functions for other charsets.
        var $enable_typo3temp_db_tracking = 0;          // If set, then all files in typo3temp will be logged in a database table. In addition to being a log of the files with original filenames, it also serves to secure that the same image is not rendered simultaneously by two different processes.
-       var $imageMagickPath = '';                                      // path to imageMagick, eg: /usr/lib/
        var $imageFileExt = 'gif,jpg,jpeg,png,tif,bmp,tga,pcx,ai,pdf';  // Commalist of file extensions perceived as images by TYPO3. List should be set to 'gif,png,jpeg,jpg' if IM is not available. Lowercase and no spaces between!
        var $webImageExt = 'gif,jpg,jpeg,png';          // Commalist of web image extensions (can be shown by a webbrowser)
        var $maskNegate = '';                                           // Will be ' -negate' if ImageMagick ver 5.2+. See init();
-       var $NO_IM_EFFECTS = '';                                        
+       var $NO_IM_EFFECTS = '';
        var $cmds = Array (
-               'jpg' => '-colorspace RGB -sharpen 50 -quality 60',
-               'jpeg' => '-colorspace RGB -sharpen 50 -quality 60',
+               'jpg' => '',
+               'jpeg' => '',
                'gif' => '-colors 64',
                'png' => '-colors 64'
        );
        var $NO_IMAGE_MAGICK = '';
        var $V5_EFFECTS = 0;
+       var $im_version_4 = 0;
        var $mayScaleUp = 1;
 
                // Variables for testing, alternative usage etc.
@@ -166,13 +188,14 @@ class t3lib_stdGraphic    {
        var $dontCompress=0;                                                            // Prevents imageMagickConvert() from compressing the gif-files with t3lib_div::gif_compress()
        var $dontUnlinkTempFiles=0;                                                     // For debugging ONLY!
        var $alternativeOutputKey='';                                           // For debugging only. Filenames will not be based on mtime and only filename (not path) will be used. This key is also included in the hash of the filename...
-       
+
                // Internal:
        var $IM_commands = Array();                                                     // All ImageMagick commands executed is stored in this array for tracking. Used by the Install Tools Image section
        var $workArea = Array();
-       
+
                // Constants:
-       var $tempPath = 'typo3temp/';                                           // The temp-directory where to store the files. Relative to PATH_site.
+       var $tempPath = 'typo3temp/';                                           // The temp-directory where to store the files. Normally relative to PATH_site but is allowed to be the absolute path AS LONG AS it is a subdir to PATH_site.
+       var $absPrefix = '';                                                            // Prefix for relative paths. Used in "show_item.php" script. Is prefixed the output file name IN imageMagickConvert()
        var $scalecmd = '-geometry';                                            // ImageMagick scaling command; "-geometry" eller "-sample". Used in makeText() and imageMagickConvert()
        var $im5fx_blurSteps='1x2,2x2,3x2,4x3,5x3,5x4,6x4,7x5,8x5,9x5';                 // Used by v5_blur() to simulate 10 continuous steps of blurring
        var $im5fx_sharpenSteps='1x2,2x2,3x2,2x3,3x3,4x3,3x4,4x4,4x5,5x5';              // Used by v5_sharpen() to simulate 10 continuous steps of sharpening.
@@ -196,7 +219,11 @@ class t3lib_stdGraphic     {
                'white' => Array(255,255,255)
        );
 
-               // Charset conversion object:
+       /**
+        * Charset conversion object:
+        *
+        * @var t3lib_cs
+        */
        var $csConvObj;
        var $nativeCharset='';          // Is set to the native character set of the input strings.
 
@@ -207,17 +234,49 @@ class t3lib_stdGraphic    {
        /**
         * Init function. Must always call this when using the class.
         * This function will read the configuration information from $GLOBALS['TYPO3_CONF_VARS']['GFX'] can set some values in internal variables.
-        * 
-        * @return      void            
+        *
+        * @return      void
         */
        function init() {
                $gfxConf = $GLOBALS['TYPO3_CONF_VARS']['GFX'];
 
+               if (function_exists('imagecreatefromjpeg')&&function_exists('imagejpeg'))       {
+                       $this->gdlibExtensions .= ',jpg,jpeg';
+               }
+               if (function_exists('imagecreatefrompng')&&function_exists('imagepng')) {
+                       $this->gdlibExtensions .= ',png';
+               }
+               if (function_exists('imagecreatefromgif')&&function_exists('imagegif')) {
+                       $this->gdlibExtensions .= ',gif';
+               }
+               if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['png_truecolor'])        {
+                       $this->png_truecolor = true;
+               }
+               if (!$gfxConf['gdlib_2'] || !function_exists('imagecreatetruecolor'))   {
+                       $this->truecolor = false;
+               }
+               if (!$gfxConf['im_version_5'])  {
+                       $this->im_version_4 = true;
+               }
+
+                       // When GIFBUILDER gets used in truecolor mode (GD2 required)
+               if ($this->truecolor)   {
+                       if ($this->png_truecolor)       {
+                               $this->cmds['png'] = '';        // No colors parameter if we generate truecolor images.
+                       }
+                       $this->cmds['gif'] = '';        // No colors parameter if we generate truecolor images.
+               }
+
+                       // Setting default JPG parameters:
+               $this->jpegQuality = t3lib_div::intInRange($gfxConf['jpg_quality'], 10, 100, 75);
+               $this->cmds['jpg'] = $this->cmds['jpeg'] = '-colorspace RGB -sharpen 50 -quality '.$this->jpegQuality;
+
                if ($gfxConf['im_combine_filename'])    $this->combineScript=$gfxConf['im_combine_filename'];
                if ($gfxConf['im_noFramePrepended'])    $this->noFramePrepended=1;
-               
+
                if ($gfxConf['gdlib_2'])        {
-                       $this->GD2=1;
+                       $this->GD2 = 1;
+                       $this->imagecopyresized_fix = $gfxConf['gdlib_2']==='no_imagecopyresized_fix' ? 0 : 1;
                }
                if ($gfxConf['gdlib_png'])      {
                        $this->gifExtension='png';
@@ -228,39 +287,36 @@ class t3lib_stdGraphic    {
                if ($gfxConf['enable_typo3temp_db_tracking']) {
                        $this->enable_typo3temp_db_tracking = $gfxConf['enable_typo3temp_db_tracking'];
                }
-               
-               $this->imageMagickPath = $gfxConf['im_path'];
+
                $this->imageFileExt = $gfxConf['imagefile_ext'];
-               
+
                        // This should be set if ImageMagick ver. 5+ is used.
                if ($gfxConf['im_negate_mask']) {
-                               // Boolean. Indicates if the mask images should be inverted first. 
-                               // This depends of the ImageMagick version. Below ver. 5.1 this should be false. 
-                               // Above ImageMagick version 5.2+ it should be true. 
+                               // Boolean. Indicates if the mask images should be inverted first.
+                               // This depends of the ImageMagick version. Below ver. 5.1 this should be false.
+                               // Above ImageMagick version 5.2+ it should be true.
                                // Just set the flag if the masks works opposite the intension!
                        $this->maskNegate = ' -negate';
                }
-               if ($gfxConf['im_no_effects'])  {       
-                               // Boolean. This is necessary if using ImageMagick 5+. 
-                               // Approved version for using effects is version 4.2.9. 
-                               // Effects in Imagemagick 5+ tends to render very slowly!! 
+               if ($gfxConf['im_no_effects'])  {
+                               // Boolean. This is necessary if using ImageMagick 5+.
+                               // Approved version for using effects is version 4.2.9.
+                               // Effects in Imagemagick 5+ tends to render very slowly!!
                                // - therefore must be disabled in order not to perform sharpen, blurring and such.
                        $this->NO_IM_EFFECTS = 1;
 
-                       $this->cmds['jpg']  = '-colorspace RGB -quality 60';
-                       $this->cmds['jpeg'] = '-colorspace RGB -quality 60';
+                       $this->cmds['jpg'] = $this->cmds['jpeg'] = '-colorspace RGB -quality '.$this->jpegQuality;
                }
-                       // ... but if 'im_v5effects' is set, dont care about 'im_no_effects'
+                       // ... but if 'im_v5effects' is set, don't care about 'im_no_effects'
                if ($gfxConf['im_v5effects'])   {
                        $this->NO_IM_EFFECTS = 0;
                        $this->V5_EFFECTS = 1;
 
                        if ($gfxConf['im_v5effects']>0) {
-                               $this->cmds['jpg']  = '-colorspace RGB -quality 60'.$this->v5_sharpen(10);
-                               $this->cmds['jpeg'] = '-colorspace RGB -quality 60'.$this->v5_sharpen(10);
+                               $this->cmds['jpg'] = $this->cmds['jpeg'] = '-colorspace RGB -quality '.intval($gfxConf['jpg_quality']).$this->v5_sharpen(10);
                        }
                }
-               
+
                if (!$gfxConf['im'])    {
                        $this->NO_IMAGE_MAGICK = 1;
                }
@@ -268,11 +324,13 @@ class t3lib_stdGraphic    {
                if ($gfxConf['im_noScaleUp']) {
                        $this->mayScaleUp=0;
                }
-               
+
                if (TYPO3_MODE=='FE')   {
-                       $this->csConvObj = &$GLOBALS['TSFE']->csConvObj;
-               } else {        // BE assumed:
-                       $this->csConvObj = &$GLOBALS['LANG']->csConvObj;
+                       $this->csConvObj = $GLOBALS['TSFE']->csConvObj;
+               } elseif(is_object($GLOBALS['LANG']))   {       // BE assumed:
+                       $this->csConvObj = $GLOBALS['LANG']->csConvObj;
+               } else  {       // The object may not exist yet, so we need to create it now. Happens in the Install Tool for example.
+                       $this->csConvObj = t3lib_div::makeInstance('t3lib_cs');
                }
                $this->nativeCharset = $GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'];
        }
@@ -302,17 +360,29 @@ class t3lib_stdGraphic    {
         * Implements the "IMAGE" GIFBUILDER object, when the "mask" property is true.
         * It reads the two images defined by $conf['file'] and $conf['mask'] and copies the $conf['file'] onto the input image pointer image using the $conf['mask'] as a grayscale mask
         * The operation involves ImageMagick for combining.
-        * 
+        *
         * @param       pointer         GDlib image pointer
         * @param       array           TypoScript array with configuration for the GIFBUILDER object.
         * @param       array           The current working area coordinates.
-        * @return      void            
+        * @return      void
         * @see tslib_gifBuilder::make()
         */
        function maskImageOntoImage(&$im,$conf,$workArea)       {
                if ($conf['file'] && $conf['mask'])     {
-                       $BBimage = $this->imageMagickConvert($conf['file'],$this->gifExtension,'','','','','');
-                       $BBmask = $this->imageMagickConvert($conf['mask'],$this->gifExtension,'','','','','');
+                       $imgInf = pathinfo($conf['file']);
+                       $imgExt = strtolower($imgInf['extension']);
+                       if (!t3lib_div::inList($this->gdlibExtensions, $imgExt))        {
+                               $BBimage = $this->imageMagickConvert($conf['file'],$this->gifExtension,'','','','','');
+                       } else  {
+                               $BBimage = $this->getImageDimensions($conf['file']);
+                       }
+                       $maskInf = pathinfo($conf['mask']);
+                       $maskExt = strtolower($maskInf['extension']);
+                       if (!t3lib_div::inList($this->gdlibExtensions, $maskExt))       {
+                               $BBmask = $this->imageMagickConvert($conf['mask'],$this->gifExtension,'','','','','');
+                       } else  {
+                               $BBmask = $this->getImageDimensions($conf['mask']);
+                       }
                        if ($BBimage && $BBmask)        {
                                $w = imagesx($im);
                                $h = imagesy($im);
@@ -320,31 +390,30 @@ class t3lib_stdGraphic    {
                                $theImage = $tmpStr.'_img.'.$this->gifExtension;
                                $theDest = $tmpStr.'_dest.'.$this->gifExtension;
                                $theMask = $tmpStr.'_mask.'.$this->gifExtension;
-                               $theMask2 = $tmpStr.'_mask2.'.trim($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_mask_temp_ext_noloss']);
                                                // prepare overlay image
-                               $cpImg = $this->imageCreateFromGif($BBimage[3]);
-                               $destImg = imagecreate($w,$h);
-                               ImageColorAllocate($destImg, 0,0,0);
+                               $cpImg = $this->imageCreateFromFile($BBimage[3]);
+                               $destImg = $this->imagecreate($w,$h);
+                               $Bcolor = ImageColorAllocate($destImg, 0,0,0);
+                               ImageFilledRectangle($destImg, 0, 0, $w, $h, $Bcolor);
                                $this->copyGifOntoGif($destImg,$cpImg,$conf,$workArea);
-                               $this->ImageGif($destImg, $theImage);
+                               $this->ImageWrite($destImg, $theImage);
                                imageDestroy($cpImg);
                                imageDestroy($destImg);
                                                // prepare mask image
-                               $cpImg = $this->imageCreateFromGif($BBmask[3]);
-                               $destImg = imagecreate($w,$h);
-                               ImageColorAllocate($destImg, 0,0,0);
+                               $cpImg = $this->imageCreateFromFile($BBmask[3]);
+                               $destImg = $this->imagecreate($w,$h);
+                               $Bcolor = ImageColorAllocate($destImg, 0, 0, 0);
+                               ImageFilledRectangle($destImg, 0, 0, $w, $h, $Bcolor);
                                $this->copyGifOntoGif($destImg,$cpImg,$conf,$workArea);
-                               $this->ImageGif($destImg, $theMask);
+                               $this->ImageWrite($destImg, $theMask);
                                imageDestroy($cpImg);
                                imageDestroy($destImg);
-                                       // treat the mask
-                               $this->imageMagickExec($theMask,$theMask2,'-colorspace GRAY'.$this->maskNegate);
                                        // mask the images
-                               $this->ImageGif($im, $theDest);
+                               $this->ImageWrite($im, $theDest);
 
-                               $this->combineExec($theDest,$theImage,$theMask2,$theDest);
+                               $this->combineExec($theDest,$theImage,$theMask,$theDest, true);         // Let combineExec handle maskNegation
 
-                               $backIm = $this->imageCreateFromGif($theDest);  // The main image is loaded again...
+                               $backIm = $this->imageCreateFromFile($theDest); // The main image is loaded again...
                                if ($backIm)    {       // ... and if nothing went wrong we load it onto the old one.
                                        ImageColorTransparent($backIm,-1);
                                        $im = $backIm;
@@ -354,7 +423,6 @@ class t3lib_stdGraphic      {
                                        unlink($theDest);
                                        unlink($theImage);
                                        unlink($theMask);
-                                       unlink($theMask2);
                                }
                        }
                }
@@ -362,20 +430,20 @@ class t3lib_stdGraphic    {
 
        /**
         * Implements the "IMAGE" GIFBUILDER object, when the "mask" property is false (using only $conf['file'])
-        * 
+        *
         * @param       pointer         GDlib image pointer
         * @param       array           TypoScript array with configuration for the GIFBUILDER object.
         * @param       array           The current working area coordinates.
-        * @return      void            
+        * @return      void
         * @see tslib_gifBuilder::make(), maskImageOntoImage()
         */
        function copyImageOntoImage(&$im,$conf,$workArea)       {
                if ($conf['file'])      {
-                       if ($conf['BBOX'][2]!=$this->gifExtension)      {
+                       if (!t3lib_div::inList($this->gdlibExtensions, $conf['BBOX'][2]))       {
                                $conf['BBOX']=$this->imageMagickConvert($conf['BBOX'][3],$this->gifExtension,'','','','','');
                                $conf['file']=$conf['BBOX'][3];
                        }
-                       $cpImg = $this->imageCreateFromGif($conf['file']);
+                       $cpImg = $this->imageCreateFromFile($conf['file']);
                        $this->copyGifOntoGif($im,$cpImg,$conf,$workArea);
                        imageDestroy($cpImg);
                }
@@ -383,7 +451,7 @@ class t3lib_stdGraphic      {
 
        /**
         * Copies two GDlib image pointers onto each other, using TypoScript configuration from $conf and the input $workArea definition.
-        * 
+        *
         * @param       pointer         GDlib image pointer, destination (bottom image)
         * @param       pointer         GDlib image pointer, source (top image)
         * @param       array           TypoScript array with the properties for the IMAGE GIFBUILDER object. Only used for the "tile" property value.
@@ -439,44 +507,46 @@ class t3lib_stdGraphic    {
        }
 
        /**
-        * Alternative function for using the similat PHP function imagecopyresized(). Used for GD2 only.
-        * 
+        * Alternative function for using the similar PHP function imagecopyresized(). Used for GD2 only.
+        *
         * OK, the reason for this stupid fix is the following story:
-        * GD1.x was capable of copying two images together and combining their palettes! GD2 is apparently not. 
-        * With GD2 only the palette of the dest-image is used which mostly results in totally black images when trying to 
+        * GD1.x was capable of copying two images together and combining their palettes! GD2 is apparently not.
+        * With GD2 only the palette of the dest-image is used which mostly results in totally black images when trying to
         * copy a color-ful image onto the destination.
-        * The GD2-fix is to 
+        * The GD2-fix is to
         *              1) Create a blank TRUE-COLOR image
         *              2) Copy the destination image onto that one
-        *              3) Then do the actual operation; Copying the source (top image) onto that 
+        *              3) Then do the actual operation; Copying the source (top image) onto that
         *              4) ... and return the result pointer.
         *              5) Reduce colors (if we do not, the result may become strange!)
         * It works, but the resulting images is now a true-color PNG which may be very large.
         * So, why not use 'imagetruecolortopalette ($im, TRUE, 256)' - well because it does NOT WORK! So simple is that.
-        * 
+        *
         * For parameters, see PHP function "imagecopyresized()"
-        * 
-        * @param       pointer         
-        * @param       pointer         
-        * @param       integer         
-        * @param       integer         
-        * @param       integer         
-        * @param       integer         
-        * @param       integer         
-        * @param       integer         
-        * @param       integer         
-        * @param       integer         
-        * @return      void            
+        *
+        * @param       pointer         see PHP function "imagecopyresized()"
+        * @param       pointer         see PHP function "imagecopyresized()"
+        * @param       integer         see PHP function "imagecopyresized()"
+        * @param       integer         see PHP function "imagecopyresized()"
+        * @param       integer         see PHP function "imagecopyresized()"
+        * @param       integer         see PHP function "imagecopyresized()"
+        * @param       integer         see PHP function "imagecopyresized()"
+        * @param       integer         see PHP function "imagecopyresized()"
+        * @param       integer         see PHP function "imagecopyresized()"
+        * @param       integer         see PHP function "imagecopyresized()"
+        * @return      void
         * @access private
         * @see t3lib_iconWorks::imagecopyresized()
         */
        function imagecopyresized(&$im, $cpImg, $Xstart, $Ystart, $cpImgCutX, $cpImgCutY, $w, $h, $w, $h)       {
-               if ($this->GD2) {
-                       $im_base = imagecreatetruecolor(imagesx($im), imagesy($im));    // Make true color image
+               if ($this->imagecopyresized_fix)        {
+                       $im_base = $this->imagecreate(imagesx($im), imagesy($im));      // Make true color image
                        imagecopyresized($im_base, $im, 0,0,0,0, imagesx($im),imagesy($im),imagesx($im),imagesy($im));  // Copy the source image onto that
                        imagecopyresized($im_base, $cpImg, $Xstart, $Ystart, $cpImgCutX, $cpImgCutY, $w, $h, $w, $h);   // Then copy the $cpImg onto that (the actual operation!)
                        $im = $im_base; // Set pointer
-                       $this->makeEffect($im, Array('value'=>'colors=256'));   // Reduce colors to 256 - make SURE that IM is working then!
+                       if (!$this->truecolor)  {
+                               $this->makeEffect($im, Array('value'=>'colors='.t3lib_div::intInRange($this->setup['reduceColors'], 256, $this->truecolorColors, 256)));                // Reduce to "reduceColors" colors - make SURE that IM is working then!
+                       }
                } else {
                        imagecopyresized($im, $cpImg, $Xstart, $Ystart, $cpImgCutX, $cpImgCutY, $w, $h, $w, $h);
                }
@@ -503,7 +573,6 @@ class t3lib_stdGraphic      {
 
 
 
-
        /********************************
         *
         * Text / "TEXT" GIFBUILDER object
@@ -512,18 +581,16 @@ class t3lib_stdGraphic    {
 
        /**
         * Implements the "TEXT" GIFBUILDER object
-        * 
+        *
         * @param       pointer         GDlib image pointer
         * @param       array           TypoScript array with configuration for the GIFBUILDER object.
         * @param       array           The current working area coordinates.
-        * @return      void            
+        * @return      void
         * @see tslib_gifBuilder::make()
         */
        function makeText(&$im,$conf,$workArea) {
                        // Spacing
-               $spacing = intval($conf['spacing']);
-               $wordSpacing = intval($conf['wordSpacing']);
-               $wordSpacing = $wordSpacing?$wordSpacing:$spacing*2;
+               list($spacing,$wordSpacing) = $this->calcWordSpacing($conf);
                        // Position
                $txtPos = $this->txtPosition($conf,$workArea,$conf['BBOX']);
                $theText = $this->recodeString($conf['text']);
@@ -537,16 +604,19 @@ class t3lib_stdGraphic    {
                                // NiceText is calculated
                        if (!$conf['niceText']) {
                                        // Font Color is reserved:
-                               $this->reduceColors($im,256, 200);
+                               if (!$this->truecolor)  {
+                                       $reduce = t3lib_div::intInRange($this->setup['reduceColors'], 256, $this->truecolorColors, 256);
+                                       $this->reduceColors($im, $reduce-49, $reduce-50);       // If "reduce-49" colors (or more) are used reduce them to "reduce-50"
+                               }
                                $Fcolor = ImageColorAllocate($im, $cols[0],$cols[1],$cols[2]);
                                        // antiAliasing is setup:
                                $Fcolor = ($conf['antiAlias']) ? $Fcolor : -$Fcolor;
-                               
+
                                for ($a=0; $a<$conf['iterations']; $a++)        {
                                        if ($spacing || $wordSpacing)   {               // If any kind of spacing applys, we use this function:
-                                               $this->SpacedImageTTFText($im, $conf['fontSize'], $conf['angle'], $txtPos[0], $txtPos[1], $Fcolor, t3lib_stdGraphic::prependAbsolutePath($conf['fontFile']), $theText, $spacing, $wordSpacing);
+                                               $this->SpacedImageTTFText($im, $conf['fontSize'], $conf['angle'], $txtPos[0], $txtPos[1], $Fcolor, t3lib_stdGraphic::prependAbsolutePath($conf['fontFile']), $theText, $spacing, $wordSpacing, $conf['splitRendering.']);
                                        } else {
-                                               ImageTTFText($im, t3lib_div::freetypeDpiComp($conf['fontSize']), $conf['angle'], $txtPos[0], $txtPos[1], $Fcolor, t3lib_stdGraphic::prependAbsolutePath($conf['fontFile']), $theText);
+                                               $this->renderTTFText($im, $conf['fontSize'], $conf['angle'], $txtPos[0], $txtPos[1], $Fcolor, $conf['fontFile'], $theText, $conf['splitRendering.'], $conf);
                                        }
                                }
                        } else {                // NICETEXT::
@@ -554,7 +624,7 @@ class t3lib_stdGraphic      {
                                $w = imagesx($im);
                                $h = imagesy($im);
                                $tmpStr = $this->randomName();
-                               
+
                                $fileMenu = $tmpStr.'_menuNT.'.$this->gifExtension;
                                $fileColor = $tmpStr.'_colorNT.'.$this->gifExtension;
                                $fileMask = $tmpStr.'_maskNT.'.$this->gifExtension;
@@ -562,17 +632,18 @@ class t3lib_stdGraphic    {
                                $sF = t3lib_div::intInRange($conf['niceText.']['scaleFactor'],2,5);
                                $newW = ceil($sF*imagesx($im));
                                $newH = ceil($sF*imagesy($im));
-       
+
                                        // Make mask
-                               $maskImg = imagecreate($newW, $newH);
-                               ImageColorAllocate($maskImg, 255,255,255);
+                               $maskImg = $this->imagecreate($newW, $newH);
+                               $Bcolor = ImageColorAllocate($maskImg, 255,255,255);
+                               ImageFilledRectangle($maskImg, 0, 0, $newW, $newH, $Bcolor);
                                $Fcolor = ImageColorAllocate($maskImg, 0,0,0);
                                if ($spacing || $wordSpacing)   {               // If any kind of spacing applys, we use this function:
-                                       $this->SpacedImageTTFText($maskImg, ceil($sF*$conf['fontSize']), $conf['angle'], ceil($sF*$txtPos[0]), ceil($sF*$txtPos[1]), $Fcolor, t3lib_stdGraphic::prependAbsolutePath($conf['fontFile']), $theText, ceil($sF*$spacing), ceil($sF*$wordSpacing));
+                                       $this->SpacedImageTTFText($maskImg, $conf['fontSize'], $conf['angle'], $txtPos[0], $txtPos[1], $Fcolor, t3lib_stdGraphic::prependAbsolutePath($conf['fontFile']), $theText, $spacing, $wordSpacing, $conf['splitRendering.'],$sF);
                                } else {
-                                       ImageTTFText($maskImg, t3lib_div::freetypeDpiComp(ceil($sF*$conf['fontSize'])), $conf['angle'], ceil($sF*$txtPos[0]), ceil($sF*$txtPos[1]), $Fcolor, t3lib_stdGraphic::prependAbsolutePath($conf['fontFile']), $theText);
+                                       $this->renderTTFText($maskImg, $conf['fontSize'], $conf['angle'], $txtPos[0], $txtPos[1], $Fcolor, $conf['fontFile'], $theText, $conf['splitRendering.'], $conf, $sF);
                                }
-                               $this->ImageGif($maskImg, $fileMask);
+                               $this->ImageWrite($maskImg, $fileMask);
                                ImageDestroy($maskImg);
 
                                        // Downscales the mask
@@ -596,30 +667,32 @@ class t3lib_stdGraphic    {
                                                }
                                        }
                                }
+
                                $this->imageMagickExec($fileMask,$fileMask,$command);
-       
+
                                        // Make the color-file
-                               $colorImg = imagecreate($w,$h);
-                               ImageColorAllocate($colorImg, $cols[0],$cols[1],$cols[2]);
-                               $this->ImageGif($colorImg, $fileColor);
+                               $colorImg = $this->imagecreate($w,$h);
+                               $Ccolor = ImageColorAllocate($colorImg, $cols[0],$cols[1],$cols[2]);
+                               ImageFilledRectangle($colorImg, 0, 0, $w, $h, $Ccolor);
+                               $this->ImageWrite($colorImg, $fileColor);
                                ImageDestroy($colorImg);
-       
+
                                        // The mask is applied
-                               $this->ImageGif($im, $fileMenu);        // The main pictures is saved temporarily
-       
-                               $this->combineExec($fileMenu,$fileColor,$fileMask,$fileMenu);
-                               
-                               $backIm = $this->imageCreateFromGif($fileMenu); // The main image is loaded again...
+                               $this->ImageWrite($im, $fileMenu);      // The main pictures is saved temporarily
+
+                               $this->combineExec($fileMenu,$fileColor,$fileMask, $fileMenu);
+
+                               $backIm = $this->imageCreateFromFile($fileMenu);        // The main image is loaded again...
                                if ($backIm)    {       // ... and if nothing went wrong we load it onto the old one.
                                        ImageColorTransparent($backIm,-1);
                                        $im = $backIm;
                                }
-       
+
                                        // Deleting temporary files;
                                if (!$this->dontUnlinkTempFiles)        {
-                                       unlink($fileMenu);      
+                                       unlink($fileMenu);
                                        unlink($fileColor);
-                                       unlink($fileMask);      
+                                       unlink($fileMask);
                                }
                        }
                }
@@ -627,7 +700,7 @@ class t3lib_stdGraphic      {
 
        /**
         * Calculates text position for printing the text onto the image based on configuration like alignment and workarea.
-        * 
+        *
         * @param       array           TypoScript array for the TEXT GIFBUILDER object
         * @param       array           Workarea definition
         * @param       array           Bounding box information, was set in tslib_gifBuilder::start()
@@ -666,11 +739,11 @@ class t3lib_stdGraphic    {
                }
                switch($conf['align'])  {
                        case 'right':
-                       break;                  
+                       break;
                        case 'center':
                                $result[0] = round(($result[0])/2);
                                $result[1] = round(($result[1])/2);
-                       break;                  
+                       break;
                        default:
                                $result[0]=0;
                                $result[1]=0;
@@ -683,28 +756,18 @@ class t3lib_stdGraphic    {
 
        /**
         * Calculates bounding box information for the TEXT GIFBUILDER object.
-        * 
+        *
         * @param       array           TypoScript array for the TEXT GIFBUILDER object
         * @return      array           Array with three keys [0]/[1] being x/y and [2] being the bounding box array
         * @access private
         * @see txtPosition(), tslib_gifBuilder::start()
         */
        function calcBBox($conf)        {
-               if (!$conf['niceText']) {
-                       $sF = 1;
-               } else {                // NICETEXT::
-                       $sF = t3lib_div::intInRange($conf['niceText.']['scaleFactor'],2,5);
-               }
-
-               $spacing = intval($conf['spacing']);
-               $wordSpacing = intval($conf['wordSpacing']);
-               $wordSpacing = $wordSpacing?$wordSpacing:$spacing*2;
-               
-               $spacing*=$sF;
-               $wordSpacing*=$sF;
+               $sF = $this->getTextScalFactor($conf);
+               list($spacing,$wordSpacing) = $this->calcWordSpacing($conf, $sF);
                $theText = $this->recodeString($conf['text']);
-               
-               $charInf = ImageTTFBBox(t3lib_div::freetypeDpiComp($sF*$conf['fontSize']), $conf['angle'], t3lib_stdGraphic::prependAbsolutePath($conf['fontFile']), $theText);
+
+               $charInf = $this->ImageTTFBBoxWrapper($conf['fontSize'], $conf['angle'], $conf['fontFile'], $theText, $conf['splitRendering.'],$sF);
                $theBBoxInfo = $charInf;
                if ($conf['angle'])     {
                        $xArr = Array($charInf[0],$charInf[2],$charInf[4],$charInf[6]);
@@ -715,13 +778,16 @@ class t3lib_stdGraphic    {
                        $x = ($charInf[2]-$charInf[0]);
                        $y = ($charInf[1]-$charInf[7]);
                }
+                       // Set original lineHeight (used by line breaks):
+               $theBBoxInfo['lineHeight'] = $y;
+
                if ($spacing || $wordSpacing)   {               // If any kind of spacing applys, we use this function:
                        $x=0;
                        if (!$spacing && $wordSpacing)  {
                                $bits = explode(' ',$theText);
                                while(list(,$word)=each($bits)) {
                                        $word.=' ';
-                                       $wordInf = ImageTTFBBox(t3lib_div::freetypeDpiComp($sF*$conf['fontSize']), $conf['angle'], t3lib_stdGraphic::prependAbsolutePath($conf['fontFile']), $word);
+                                       $wordInf = $this->ImageTTFBBoxWrapper($conf['fontSize'], $conf['angle'], $conf['fontFile'], $word, $conf['splitRendering.'],$sF);
                                        $wordW = ($wordInf[2]-$wordInf[0]);
                                        $x+=$wordW+$wordSpacing;
                                }
@@ -729,47 +795,74 @@ class t3lib_stdGraphic    {
                                $utf8Chars = $this->singleChars($theText);
                                        // For each UTF-8 char, do:
                                foreach($utf8Chars as $char)    {
-                                       $charInf = ImageTTFBBox(t3lib_div::freetypeDpiComp($sF*$conf['fontSize']), $conf['angle'], t3lib_stdGraphic::prependAbsolutePath($conf['fontFile']), $char);
+                                       $charInf = $this->ImageTTFBBoxWrapper($conf['fontSize'], $conf['angle'], $conf['fontFile'], $char, $conf['splitRendering.'],$sF);
                                        $charW = ($charInf[2]-$charInf[0]);
                                        $x+=$charW+(($char==' ')?$wordSpacing:$spacing);
                                }
                        }
+               } elseif (isset($conf['breakWidth']) && $conf['breakWidth'] && $this->getRenderedTextWidth($conf['text'], $conf) > $conf['breakWidth']) {
+                       $maxWidth = 0;
+                       $currentWidth = 0;
+                       $breakWidth = $conf['breakWidth'];
+                       $breakSpace = $this->getBreakSpace($conf, $theBBoxInfo);
+
+                       $wordPairs = $this->getWordPairsForLineBreak($conf['text']);
+                               // Iterate through all word pairs:
+                       foreach ($wordPairs as $index => $wordPair) {
+                               $wordWidth = $this->getRenderedTextWidth($wordPair, $conf);
+                               if ($index == 0 || $currentWidth + $wordWidth <= $breakWidth) {
+                                       $currentWidth+= $wordWidth;
+                               } else {
+                                       $maxWidth = max($maxWidth, $currentWidth);
+                                       $y+= $breakSpace;
+                                               // Restart:
+                                       $currentWidth = $wordWidth;
+                               }
+                       }
+                       $x = max($maxWidth, $currentWidth) * $sF;
                }
-               
-               if ($sF>1) {
-                       $x = ceil($x/$sF);
-                       $y = ceil($y/$sF);
+
+               if ($sF > 1) {
+                       $x = ceil($x / $sF);
+                       $y = ceil($y / $sF);
                        if (is_array($theBBoxInfo))     {
-                               reset($theBBoxInfo);
-                               while(list($key,$val)=each($theBBoxInfo))       {
-                                       $theBBoxInfo[$key]=ceil($theBBoxInfo[$key]/$sF);
+                               foreach ($theBBoxInfo as &$value) {
+                                       $value = ceil($value / $sF);
                                }
                        }
                }
-               return Array($x,$y,$theBBoxInfo);
+               return array($x, $y, $theBBoxInfo);
        }
 
        /**
         * Adds an <area> tag to the internal variable $this->map which is used to accumulate the content for an ImageMap
-        * 
+        *
         * @param       array           Coordinates for a polygon image map as created by ->calcTextCordsForMap()
         * @param       array           Configuration for "imgMap." property of a TEXT GIFBUILDER object.
-        * @return      void            
+        * @return      void
         * @access private
         * @see makeText(), calcTextCordsForMap()
         */
        function addToMap($cords,$conf) {
                $JS = $conf['noBlur'] ? '' : ' onfocus="blurLink(this);"';
-               $this->map.='<area shape="poly" coords="'.implode($cords,',').'" href="'.htmlspecialchars($conf['url']).'" target="'.$conf['target'].'"'.$JS.' />';
+
+               $this->map.='<area'.
+                               ' shape="poly"'.
+                               ' coords="'.implode(',',$cords).'"'.
+                               ' href="'.htmlspecialchars($conf['url']).'"'.
+                               ($conf['target'] ? ' target="'.htmlspecialchars($conf['target']).'"' : '').
+                               $JS.
+                               (strlen($conf['titleText']) ? ' title="'.htmlspecialchars($conf['titleText']).'"' : '').
+                               ' alt="'.htmlspecialchars($conf['altText']).'" />';
        }
 
        /**
         * Calculating the coordinates for a TEXT string on an image map. Used in an <area> tag
-        * 
+        *
         * @param       array           Coordinates (from BBOX array)
         * @param       array           Offset array
         * @param       array           Configuration for "imgMap." property of a TEXT GIFBUILDER object.
-        * @return      array           
+        * @return      array
         * @access private
         * @see makeText(), calcTextCordsForMap()
         */
@@ -792,7 +885,7 @@ class t3lib_stdGraphic      {
         * Printing text onto an image like the PHP function imageTTFText does but in addition it offers options for spacing of letters and words.
         * Spacing is done by printing one char at a time and this means that the spacing is rather uneven and probably not very nice.
         * See
-        * 
+        *
         * @param       pointer         (See argument for PHP function imageTTFtext())
         * @param       integer         (See argument for PHP function imageTTFtext())
         * @param       integer         (See argument for PHP function imageTTFtext())
@@ -803,28 +896,34 @@ class t3lib_stdGraphic    {
         * @param       string          (See argument for PHP function imageTTFtext()). UTF-8 string, possibly with entities in.
         * @param       integer         The spacing of letters in pixels
         * @param       integer         The spacing of words in pixels
-        * @return      void            
+        * @param       array           $splitRenderingConf array
+        * @param       integer         Scale factor
+        * @return      void
         * @access private
         */
-       function SpacedImageTTFText(&$im, $fontSize, $angle, $x, $y, $Fcolor, $fontFile, $text, $spacing, $wordSpacing) {
+       function SpacedImageTTFText(&$im, $fontSize, $angle, $x, $y, $Fcolor, $fontFile, $text, $spacing, $wordSpacing, $splitRenderingConf, $sF=1)     {
+
+               $spacing*=$sF;
+               $wordSpacing*=$sF;
+
                if (!$spacing && $wordSpacing)  {
                        $bits = explode(' ',$text);
                        reset($bits);
                        while(list(,$word)=each($bits)) {
                                $word.=' ';
                                $word = $word;
-                               $wordInf = ImageTTFBBox(t3lib_div::freetypeDpiComp($fontSize), $angle, t3lib_stdGraphic::prependAbsolutePath($fontFile), $word);
+                               $wordInf = $this->ImageTTFBBoxWrapper($fontSize, $angle, $fontFile, $word, $splitRenderingConf ,$sF);
                                $wordW = ($wordInf[2]-$wordInf[0]);
-                               ImageTTFText($im, t3lib_div::freetypeDpiComp($fontSize), $angle, $x, $y, $Fcolor, t3lib_stdGraphic::prependAbsolutePath($fontFile), $word);
+                               $this->ImageTTFTextWrapper($im, $fontSize, $angle, $x, $y, $Fcolor, $fontFile, $word, $splitRenderingConf, $sF);
                                $x+=$wordW+$wordSpacing;
                        }
                } else {
                        $utf8Chars = $this->singleChars($text);
                                // For each UTF-8 char, do:
                        foreach($utf8Chars as $char)    {
-                               $charInf = ImageTTFBBox(t3lib_div::freetypeDpiComp($fontSize), $angle, t3lib_stdGraphic::prependAbsolutePath($fontFile), $char);
+                               $charInf = $this->ImageTTFBBoxWrapper($fontSize, $angle, $fontFile, $char, $splitRenderingConf, $sF);
                                $charW = ($charInf[2]-$charInf[0]);
-                               ImageTTFText($im, t3lib_div::freetypeDpiComp($fontSize), $angle, $x, $y, $Fcolor, t3lib_stdGraphic::prependAbsolutePath($fontFile), $char);
+                               $this->ImageTTFTextWrapper($im, $fontSize, $angle, $x, $y, $Fcolor, $fontFile, $char, $splitRenderingConf, $sF);
                                $x+=$charW+(($char==' ')?$wordSpacing:$spacing);
                        }
                }
@@ -832,26 +931,25 @@ class t3lib_stdGraphic    {
 
        /**
         * Function that finds the right fontsize that will render the textstring within a certain width
-        * 
+        *
         * @param       array           The TypoScript properties of the TEXT GIFBUILDER object
         * @return      integer         The new fontSize
         * @access private
-        * @author      Rene Fritz <r.fritz@colorcube.de>
+        * @author Rene Fritz <r.fritz@colorcube.de>
         * @see tslib_gifBuilder::start()
         */
        function fontResize($conf) {
                // you have to use +calc options like [10.h] in 'offset' to get the right position of your text-image, if you use +calc in XY height!!!!
                $maxWidth = intval($conf['maxWidth']);
+               list($spacing,$wordSpacing) = $this->calcWordSpacing($conf);
                if ($maxWidth)  {
                        if ($spacing || $wordSpacing)   {               // If any kind of spacing applys, we use this function:
                                return $conf['fontSize'];
                                //  ################ no calc for spacing yet !!!!!!
                        } else {
-                               $fontSize = $conf['fontSize'];
                                do {
-                                       $conf['fontSize'] = $fontSize;
                                                // determine bounding box.
-                                       $bounds = ImageTTFBBox(t3lib_div::freetypeDpiComp($conf['fontSize']), $conf['angle'], t3lib_stdGraphic::prependAbsolutePath($conf['fontFile']), $this->recodeString($conf['text']));
+                                       $bounds = $this->ImageTTFBBoxWrapper($conf['fontSize'], $conf['angle'], $conf['fontFile'], $this->recodeString($conf['text']), $conf['splitRendering.']);
                                        if ($conf['angle']< 0) {
                                                $pixelWidth = abs($bounds[4]-$bounds[0]);
                                        } elseif ($conf['angle'] > 0) {
@@ -859,21 +957,416 @@ class t3lib_stdGraphic   {
                                        } else {
                                                $pixelWidth = abs($bounds[4]-$bounds[6]);
                                        }
-                                               // This is a very raw calculation but it makes it in one step
-                                       $fontSize=(int)($maxWidth*$fontSize/$pixelWidth);
-                                       if ($fontSize >= $conf['fontSize'])     {
-                                               $fontSize = $conf['fontSize']-1;
+
+                                               // Size is fine, exit:
+                                       if ($pixelWidth <= $maxWidth)   {
+                                               break;
+                                       } else {
+                                               $conf['fontSize']--;
                                        }
-                               } while ($pixelWidth > $maxWidth);
+                               } while ($conf['fontSize']>1);
                        }//if spacing
                }
                return $conf['fontSize'];
        }
 
+       /**
+        * Wrapper for ImageTTFBBox
+        *
+        * @param       integer         (See argument for PHP function ImageTTFBBox())
+        * @param       integer         (See argument for PHP function ImageTTFBBox())
+        * @param       string          (See argument for PHP function ImageTTFBBox())
+        * @param       string          (See argument for PHP function ImageTTFBBox())
+        * @param       array           Split-rendering configuration
+        * @param       integer         Scale factor
+        * @return      array           Information array.
+        */
+       function ImageTTFBBoxWrapper($fontSize, $angle, $fontFile, $string, $splitRendering, $sF=1)     {
+
+                       // Initialize:
+               $offsetInfo = array();
+               $stringParts = $this->splitString($string,$splitRendering,$fontSize,$fontFile);
+
+                       // Traverse string parts:
+               foreach($stringParts as $strCfg)        {
+                       $fontFile = t3lib_stdGraphic::prependAbsolutePath($strCfg['fontFile']);
+                       if (is_readable($fontFile)) {
 
+                                       // Calculate Bounding Box for part:
+                               $calc = ImageTTFBBox(t3lib_div::freetypeDpiComp($sF*$strCfg['fontSize']), $angle, $fontFile, $strCfg['str']);
 
+                                       // Calculate offsets:
+                               if (!count($offsetInfo))        {
+                                       $offsetInfo = $calc;    // First run, just copy over.
+                               } else {
+                                       $offsetInfo[2]+=$calc[2]-$calc[0]+intval($splitRendering['compX'])+intval($strCfg['xSpaceBefore'])+intval($strCfg['xSpaceAfter']);
+                                       $offsetInfo[3]+=$calc[3]-$calc[1]-intval($splitRendering['compY'])-intval($strCfg['ySpaceBefore'])-intval($strCfg['ySpaceAfter']);
+                                       $offsetInfo[4]+=$calc[4]-$calc[6]+intval($splitRendering['compX'])+intval($strCfg['xSpaceBefore'])+intval($strCfg['xSpaceAfter']);
+                                       $offsetInfo[5]+=$calc[5]-$calc[7]-intval($splitRendering['compY'])-intval($strCfg['ySpaceBefore'])-intval($strCfg['ySpaceAfter']);
+                               }
 
+                       } else {
+                               debug('cannot read file: '.$fontFile, 't3lib_stdGraphic::ImageTTFBBoxWrapper()');
+                       }
+               }
 
+               return $offsetInfo;
+       }
+
+       /**
+        * Wrapper for ImageTTFText
+        *
+        * @param       pointer         (See argument for PHP function imageTTFtext())
+        * @param       integer         (See argument for PHP function imageTTFtext())
+        * @param       integer         (See argument for PHP function imageTTFtext())
+        * @param       integer         (See argument for PHP function imageTTFtext())
+        * @param       integer         (See argument for PHP function imageTTFtext())
+        * @param       integer         (See argument for PHP function imageTTFtext())
+        * @param       string          (See argument for PHP function imageTTFtext())
+        * @param       string          (See argument for PHP function imageTTFtext()). UTF-8 string, possibly with entities in.
+        * @param       array           Split-rendering configuration
+        * @param       integer         Scale factor
+        * @return      void
+        */
+       function ImageTTFTextWrapper($im, $fontSize, $angle, $x, $y, $color, $fontFile, $string, $splitRendering,$sF=1) {
+
+                       // Initialize:
+               $stringParts = $this->splitString($string,$splitRendering,$fontSize,$fontFile);
+               $x = ceil($sF*$x);
+               $y = ceil($sF*$y);
+
+                       // Traverse string parts:
+               foreach($stringParts as $i => $strCfg)  {
+
+                               // Initialize:
+                       $colorIndex = $color;
+
+                               // Set custom color if any (only when niceText is off):
+                       if ($strCfg['color'] && $sF==1) {
+                               $cols = $this->convertColor($strCfg['color']);
+                               $colorIndex = ImageColorAllocate($im, $cols[0],$cols[1],$cols[2]);
+                               $colorIndex = $color >= 0 ? $colorIndex : -$colorIndex;
+                       }
+
+                               // Setting xSpaceBefore
+                       if ($i) {
+                               $x+= intval($strCfg['xSpaceBefore']);
+                               $y-= intval($strCfg['ySpaceBefore']);
+                       }
+
+                       $fontFile = t3lib_stdGraphic::prependAbsolutePath($strCfg['fontFile']);
+                       if (is_readable($fontFile)) {
+
+                                       // Render part:
+                               ImageTTFText($im, t3lib_div::freetypeDpiComp($sF*$strCfg['fontSize']), $angle, $x, $y, $colorIndex, $fontFile, $strCfg['str']);
+
+                                       // Calculate offset to apply:
+                               $wordInf = ImageTTFBBox(t3lib_div::freetypeDpiComp($sF*$strCfg['fontSize']), $angle, t3lib_stdGraphic::prependAbsolutePath($strCfg['fontFile']), $strCfg['str']);
+                               $x+= $wordInf[2]-$wordInf[0]+intval($splitRendering['compX'])+intval($strCfg['xSpaceAfter']);
+                               $y+= $wordInf[5]-$wordInf[7]-intval($splitRendering['compY'])-intval($strCfg['ySpaceAfter']);
+
+                       } else {
+                               debug('cannot read file: '.$fontFile, 't3lib_stdGraphic::ImageTTFTextWrapper()');
+                       }
+
+               }
+       }
+
+       /**
+        * Splitting a string for ImageTTFBBox up into an array where each part has its own configuration options.
+        *
+        * @param       string          UTF-8 string
+        * @param       array           Split-rendering configuration from GIFBUILDER TEXT object.
+        * @param       integer         Current fontsize
+        * @param       string          Current font file
+        * @return      array           Array with input string splitted according to configuration
+        */
+       function splitString($string,$splitRendering,$fontSize,$fontFile)       {
+
+                       // Initialize by setting the whole string and default configuration as the first entry.
+               $result = array();
+               $result[] = array(
+                       'str' => $string,
+                       'fontSize' => $fontSize,
+                       'fontFile' => $fontFile
+               );
+
+                       // Traverse the split-rendering configuration:
+                       // Splitting will create more entries in $result with individual configurations.
+               if (is_array($splitRendering))  {
+                       $sKeyArray = t3lib_TStemplate::sortedKeyList($splitRendering);
+
+                               // Traverse configured options:
+                       foreach($sKeyArray as $key)     {
+                               $cfg = $splitRendering[$key.'.'];
+
+                                       // Process each type of split rendering keyword:
+                               switch((string)$splitRendering[$key])   {
+                                       case 'highlightWord':
+                                               if (strlen($cfg['value']))      {
+                                                       $newResult = array();
+
+                                                               // Traverse the current parts of the result array:
+                                                       foreach($result as $part)       {
+                                                                       // Explode the string value by the word value to highlight:
+                                                               $explodedParts = explode($cfg['value'],$part['str']);
+                                                               foreach($explodedParts as $c => $expValue)      {
+                                                                       if (strlen($expValue))  {
+                                                                               $newResult[] = array_merge($part,array('str' => $expValue));
+                                                                       }
+                                                                       if ($c+1 < count($explodedParts))       {
+                                                                               $newResult[] = array(
+                                                                                       'str' => $cfg['value'],
+                                                                                       'fontSize' => $cfg['fontSize'] ? $cfg['fontSize'] : $part['fontSize'],
+                                                                                       'fontFile' => $cfg['fontFile'] ? $cfg['fontFile'] : $part['fontFile'],
+                                                                                       'color' => $cfg['color'],
+                                                                                       'xSpaceBefore' => $cfg['xSpaceBefore'],
+                                                                                       'xSpaceAfter' => $cfg['xSpaceAfter'],
+                                                                                       'ySpaceBefore' => $cfg['ySpaceBefore'],
+                                                                                       'ySpaceAfter' => $cfg['ySpaceAfter'],
+                                                                               );
+                                                                       }
+                                                               }
+                                                       }
+
+                                                               // Set the new result as result array:
+                                                       if (count($newResult))  {
+                                                               $result = $newResult;
+                                                       }
+                                               }
+                                       break;
+                                       case 'charRange':
+                                               if (strlen($cfg['value']))      {
+
+                                                               // Initialize range:
+                                                       $ranges = t3lib_div::trimExplode(',',$cfg['value'],1);
+                                                       foreach($ranges as $i => $rangeDef)     {
+                                                               $ranges[$i] = t3lib_div::intExplode('-',$ranges[$i]);
+                                                               if (!isset($ranges[$i][1]))     $ranges[$i][1] = $ranges[$i][0];
+                                                       }
+                                                       $newResult = array();
+
+                                                               // Traverse the current parts of the result array:
+                                                       foreach($result as $part)       {
+
+                                                                       // Initialize:
+                                                               $currentState = -1;
+                                                               $bankAccum = '';
+
+                                                                       // Explode the string value by the word value to highlight:
+                                                               $utf8Chars = $this->singleChars($part['str']);
+                                                               foreach($utf8Chars as $utfChar) {
+
+                                                                               // Find number and evaluate position:
+                                                                       $uNumber = $this->csConvObj->utf8CharToUnumber($utfChar);
+                                                                       $inRange = 0;
+                                                                       foreach($ranges as $rangeDef)   {
+                                                                               if ($uNumber >= $rangeDef[0] && (!$rangeDef[1] || $uNumber <= $rangeDef[1])) {
+                                                                                       $inRange = 1;
+                                                                                       break;
+                                                                               }
+                                                                       }
+                                                                       if ($currentState==-1)  $currentState = $inRange;       // Initialize first char
+
+                                                                               // Switch bank:
+                                                                       if ($inRange != $currentState && !t3lib_div::inList('32,10,13,9',$uNumber))     {
+
+                                                                                       // Set result:
+                                                                               if (strlen($bankAccum)) {
+                                                                                       $newResult[] = array(
+                                                                                               'str' => $bankAccum,
+                                                                                               'fontSize' => $currentState && $cfg['fontSize'] ? $cfg['fontSize'] : $part['fontSize'],
+                                                                                               'fontFile' => $currentState && $cfg['fontFile'] ? $cfg['fontFile'] : $part['fontFile'],
+                                                                                               'color' => $currentState ? $cfg['color'] : '',
+                                                                                               'xSpaceBefore' => $currentState ? $cfg['xSpaceBefore'] : '',
+                                                                                               'xSpaceAfter' => $currentState ? $cfg['xSpaceAfter'] : '',
+                                                                                               'ySpaceBefore' => $currentState ? $cfg['ySpaceBefore'] : '',
+                                                                                               'ySpaceAfter' => $currentState ? $cfg['ySpaceAfter'] : '',
+                                                                                       );
+                                                                               }
+
+                                                                                       // Initialize new settings:
+                                                                               $currentState = $inRange;
+                                                                               $bankAccum = '';
+                                                                       }
+
+                                                                               // Add char to bank:
+                                                                       $bankAccum.=$utfChar;
+                                                               }
+
+                                                                       // Set result for FINAL part:
+                                                               if (strlen($bankAccum)) {
+                                                                       $newResult[] = array(
+                                                                               'str' => $bankAccum,
+                                                                               'fontSize' => $currentState && $cfg['fontSize'] ? $cfg['fontSize'] : $part['fontSize'],
+                                                                               'fontFile' => $currentState && $cfg['fontFile'] ? $cfg['fontFile'] : $part['fontFile'],
+                                                                               'color' => $currentState ? $cfg['color'] : '',
+                                                                               'xSpaceBefore' => $currentState ? $cfg['xSpaceBefore'] : '',
+                                                                               'xSpaceAfter' => $currentState ? $cfg['xSpaceAfter'] : '',
+                                                                               'ySpaceBefore' => $currentState ? $cfg['ySpaceBefore'] : '',
+                                                                               'ySpaceAfter' => $currentState ? $cfg['ySpaceAfter'] : '',
+                                                                       );
+                                                               }
+                                                       }
+
+                                                               // Set the new result as result array:
+                                                       if (count($newResult))  {
+                                                               $result = $newResult;
+                                                       }
+                                               }
+                                       break;
+                               }
+                       }
+               }
+
+               return $result;
+       }
+
+       /**
+        * Calculates the spacing and wordSpacing values
+        *
+        * @param       array           TypoScript array for the TEXT GIFBUILDER object
+        * @param       integer         TypoScript value from eg $conf['niceText.']['scaleFactor']
+        * @return      array           Array with two keys [0]/[1] being array($spacing,$wordSpacing)
+        * @access private
+        * @see calcBBox()
+        */
+       function calcWordSpacing($conf, $scaleFactor=1) {
+
+               $spacing = intval($conf['spacing']);
+               $wordSpacing = intval($conf['wordSpacing']);
+               $wordSpacing = $wordSpacing?$wordSpacing:$spacing*2;
+
+               $spacing*=$scaleFactor;
+               $wordSpacing*=$scaleFactor;
+
+               return array($spacing,$wordSpacing);
+       }
+
+       /**
+        * Calculates and returns the niceText.scaleFactor
+        *
+        * @param       array           TypoScript array for the TEXT GIFBUILDER object
+        * @return      integer         TypoScript value from eg $conf['niceText.']['scaleFactor']
+        * @access private
+        */
+       function getTextScalFactor($conf) {
+               if (!$conf['niceText']) {
+                       $sF = 1;
+               } else {                // NICETEXT::
+                       $sF = t3lib_div::intInRange($conf['niceText.']['scaleFactor'],2,5);
+               }
+               return $sF;
+       }
+
+       /**
+        * Renders a regular text and takes care of a possible line break automatically.
+        *
+        * @param       pointer         (See argument for PHP function imageTTFtext())
+        * @param       integer         (See argument for PHP function imageTTFtext())
+        * @param       integer         (See argument for PHP function imageTTFtext())
+        * @param       integer         (See argument for PHP function imageTTFtext())
+        * @param       integer         (See argument for PHP function imageTTFtext())
+        * @param       integer         (See argument for PHP function imageTTFtext())
+        * @param       string          (See argument for PHP function imageTTFtext())
+        * @param       string          (See argument for PHP function imageTTFtext()). UTF-8 string, possibly with entities in.
+        * @param       array           Split-rendering configuration
+        * @param       integer         Scale factor
+        * @param       array           $conf: The configuration
+        * @return      void
+        */
+       protected function renderTTFText(&$im, $fontSize, $angle, $x, $y, $color, $fontFile, $string, $splitRendering, $conf, $sF = 1) {
+               if (isset($conf['breakWidth']) && $conf['breakWidth'] && $this->getRenderedTextWidth($string, $conf) > $conf['breakWidth']) {
+                       $phrase = '';
+                       $currentWidth = 0;
+
+                       $breakWidth = $conf['breakWidth'];
+                       $breakSpace = $this->getBreakSpace($conf);
+
+                       $wordPairs = $this->getWordPairsForLineBreak($string);
+                               // Iterate through all word pairs:
+                       foreach ($wordPairs as $index => $wordPair) {
+                               $wordWidth = $this->getRenderedTextWidth($wordPair, $conf);
+                               if ($index == 0 || $currentWidth + $wordWidth <= $breakWidth) {
+                                       $currentWidth+= $wordWidth;
+                                       $phrase.= $wordPair;
+                               } else {
+                                               // Render the current phrase that is below breakWidth:
+                                       $this->ImageTTFTextWrapper($im, $fontSize, $angle, $x, $y, $color, $fontFile, $phrase, $splitRendering, $sF);
+                                               // Calculate the news height offset:
+                                       $y+= $breakSpace;
+                                               // Restart the phrase:
+                                       $currentWidth = $wordWidth;
+                                       $phrase = $wordPair;
+                               }
+                       }
+                               // Render the remaining phrase:
+                       if ($currentWidth) {
+                               $this->ImageTTFTextWrapper($im, $fontSize, $angle, $x, $y, $color, $fontFile, $phrase, $splitRendering, $sF);
+                       }
+               } else {
+                       $this->ImageTTFTextWrapper($im, $fontSize, $angle, $x, $y, $color, $fontFile, $string, $splitRendering, $sF);
+               }
+       }
+
+       /**
+        * Gets the word pairs used for automatic line breaks.
+        *
+        * @param       string          $string
+        * @return      array
+        */
+       protected function getWordPairsForLineBreak($string) {
+               $wordPairs = array();
+
+               $wordsArray = preg_split('#([ -.,!:]+)#', $string, -1,  PREG_SPLIT_DELIM_CAPTURE);
+               $wordsCount = count($wordsArray);
+               for ($index=0; $index < $wordsCount; $index+= 2) {
+                       $wordPairs[] = $wordsArray[$index] . $wordsArray[$index + 1];
+               }
+
+               return $wordPairs;
+       }
+
+       /**
+        * Gets the rendered text width.
+        *
+        * @param       string          $text
+        * @param       array           $conf
+        * @param       integer
+        */
+       protected function getRenderedTextWidth($text, $conf) {
+               $bounds = $this->ImageTTFBBoxWrapper($conf['fontSize'], $conf['angle'], $conf['fontFile'], $this->recodeString($text), $conf['splitRendering.']);
+               if ($conf['angle']< 0) {
+                       $pixelWidth = abs($bounds[4]-$bounds[0]);
+               } elseif ($conf['angle'] > 0) {
+                       $pixelWidth = abs($bounds[2]-$bounds[6]);
+               } else {
+                       $pixelWidth = abs($bounds[4]-$bounds[6]);
+               }
+               return $pixelWidth;
+       }
+
+       /**
+        * Gets the break space for each new line.
+        *
+        * @param       array           $conf: TypoScript configuration for the currently rendered object
+        * @param       array           $boundingBox: The bounding box the the currently rendered object
+        * @return      integer         The break space
+        */
+       protected function getBreakSpace($conf, array $boundingBox = NULL) {
+               if (!isset($boundingBox)) {
+                       $boundingBox = $this->calcBBox($conf);
+                       $boundingBox = $boundingBox[2];
+               }
+
+               if (isset($conf['breakSpace']) && $conf['breakSpace']) {
+                       $breakSpace = $boundingBox['lineHeight'] * $conf['breakSpace'];
+               } else {
+                       $breakSpace = $boundingBox['lineHeight'];
+               }
+
+               return $breakSpace;
+       }
 
 
 
@@ -893,12 +1386,12 @@ class t3lib_stdGraphic   {
 
        /**
         * Implements the "OUTLINE" GIFBUILDER object / property for the TEXT object
-        * 
+        *
         * @param       pointer         GDlib image pointer
         * @param       array           TypoScript array with configuration for the GIFBUILDER object.
         * @param       array           The current working area coordinates.
         * @param       array           TypoScript array with configuration for the associated TEXT GIFBUILDER object.
-        * @return      void            
+        * @return      void
         * @see tslib_gifBuilder::make(), makeText()
         */
        function makeOutline(&$im,$conf,$workArea,$txtConf)     {
@@ -922,12 +1415,12 @@ class t3lib_stdGraphic   {
 
        /**
         * Creates some offset values in an array used to simulate a circularly applied outline around TEXT
-        * 
+        *
         * access private
-        * 
+        *
         * @param       integer         Distance
         * @param       integer         Iterations.
-        * @return      array           
+        * @return      array
         * @see makeOutline()
         */
        function circleOffset($distance, $iterations)   {
@@ -946,12 +1439,12 @@ class t3lib_stdGraphic   {
 
        /**
         * Implements the "EMBOSS" GIFBUILDER object / property for the TEXT object
-        * 
+        *
         * @param       pointer         GDlib image pointer
         * @param       array           TypoScript array with configuration for the GIFBUILDER object.
         * @param       array           The current working area coordinates.
         * @param       array           TypoScript array with configuration for the associated TEXT GIFBUILDER object.
-        * @return      void            
+        * @return      void
         * @see tslib_gifBuilder::make(), makeShadow()
         */
        function makeEmboss(&$im,$conf,$workArea,$txtConf)      {
@@ -960,7 +1453,7 @@ class t3lib_stdGraphic     {
                $newOffset = t3lib_div::intExplode(',',$conf['offset']);
                $newOffset[0]*=-1;
                $newOffset[1]*=-1;
-               $conf['offset']=implode($newOffset,',');
+               $conf['offset']=implode(',',$newOffset);
                $conf['color']=$conf['lowColor'];
                $this->makeShadow($im,$conf,$workArea,$txtConf);
        }
@@ -968,12 +1461,12 @@ class t3lib_stdGraphic   {
        /**
         * Implements the "SHADOW" GIFBUILDER object / property for the TEXT object
         * The operation involves ImageMagick for combining.
-        * 
+        *
         * @param       pointer         GDlib image pointer
         * @param       array           TypoScript array with configuration for the GIFBUILDER object.
         * @param       array           The current working area coordinates.
         * @param       array           TypoScript array with configuration for the associated TEXT GIFBUILDER object.
-        * @return      void            
+        * @return      void
         * @see tslib_gifBuilder::make(), makeText(), makeEmboss()
         */
        function makeShadow(&$im,$conf,$workArea,$txtConf)      {
@@ -993,19 +1486,21 @@ class t3lib_stdGraphic   {
                        $fileMask = $tmpStr.'_mask.'.$this->gifExtension;
 
                                // BlurColor Image laves
-                       $blurColImg = imagecreate($w,$h);
+                       $blurColImg = $this->imagecreate($w,$h);
                        $bcols=$this->convertColor($conf['color']);
-                       ImageColorAllocate($blurColImg, $bcols[0],$bcols[1],$bcols[2]);
-                       $this->ImageGif($blurColImg, $fileColor);
+                       $Bcolor = ImageColorAllocate($blurColImg, $bcols[0],$bcols[1],$bcols[2]);
+                       ImageFilledRectangle($blurColImg, 0, 0, $w, $h, $Bcolor);
+                       $this->ImageWrite($blurColImg, $fileColor);
                        ImageDestroy($blurColImg);
-       
+
                                // The mask is made: BlurTextImage
-                       $blurTextImg = imagecreate($w+$blurBorder*2,$h+$blurBorder*2);
-                       ImageColorAllocate($blurTextImg, 0,0,0);                // black background
+                       $blurTextImg = $this->imagecreate($w+$blurBorder*2,$h+$blurBorder*2);
+                       $Bcolor = ImageColorAllocate($blurTextImg, 0,0,0);              // black background
+                       ImageFilledRectangle($blurTextImg, 0, 0, $w+$blurBorder*2, $h+$blurBorder*2, $Bcolor);
                        $txtConf['fontColor'] = 'white';
                        $blurBordArr = Array($blurBorder,$blurBorder);
                        $this->makeText($blurTextImg,$txtConf,  $this->applyOffset($workArea,$blurBordArr));
-                       $this->ImageGif($blurTextImg, $fileMask);       // dump to temporary file
+                       $this->ImageWrite($blurTextImg, $fileMask);     // dump to temporary file
                        ImageDestroy($blurTextImg);     // destroy
 
 
@@ -1017,20 +1512,20 @@ class t3lib_stdGraphic  {
                        } else {
                                        // Blurring of the mask
                                $times = ceil($blurRate/10);    // How many blur-commands that is executed. Min = 1;
-                               $newBlurRate = $blurRate*4;             // Her booster vi blur-rate, så at den allerede ved 25 er på 100. Resten op til 99 går på iterationer af blur-kommandoen
+                               $newBlurRate = $blurRate*4;             // Here I boost the blur-rate so that it is 100 already at 25. The rest is done by up to 99 iterations of the blur-command.
                                $newBlurRate = t3lib_div::intInRange($newBlurRate,1,99);
                                for ($a=0;$a<$times;$a++)       {               // Building blur-command
                                        $command.=' -blur '.$blurRate;
                                }
                        }
 
-                       $this->imageMagickExec($fileMask,$fileMask,$command);
+                       $this->imageMagickExec($fileMask,$fileMask,$command.' +matte');
 
-                       $blurTextImg_tmp = $this->imageCreateFromGif($fileMask);        // the mask is loaded again
+                       $blurTextImg_tmp = $this->imageCreateFromFile($fileMask);       // the mask is loaded again
                        if ($blurTextImg_tmp)   {       // if nothing went wrong we continue with the blurred mask
 
                                        // cropping the border from the mask
-                               $blurTextImg = imagecreate($w,$h);
+                               $blurTextImg = $this->imagecreate($w,$h);
                                $this->imagecopyresized($blurTextImg, $blurTextImg_tmp, 0, 0, $blurBorder, $blurBorder, $w, $h, $w, $h);
                                ImageDestroy($blurTextImg_tmp); // Destroy the temporary mask
 
@@ -1041,22 +1536,22 @@ class t3lib_stdGraphic  {
                                }
                                $intensity = ceil(255-($intensity/100*255));
                                $this->inputLevels($blurTextImg,0,$intensity,$this->maskNegate);
-                               
+
                                $opacity = t3lib_div::intInRange(intval($conf['opacity']),0,100);
                                if ($opacity && $opacity<100)   {
                                        $high = ceil(255*$opacity/100);
                                        $this->outputLevels($blurTextImg,0,$high,$this->maskNegate);    // reducing levels as the opacity demands
                                }
 
-                               $this->ImageGif($blurTextImg, $fileMask);       // Dump the mask again
+                               $this->ImageWrite($blurTextImg, $fileMask);     // Dump the mask again
                                ImageDestroy($blurTextImg);     // Destroy the mask
-       
+
                                        // The pictures are combined
-                               $this->ImageGif($im, $fileMenu);        // The main pictures is saved temporarily
+                               $this->ImageWrite($im, $fileMenu);      // The main pictures is saved temporarily
 
                                $this->combineExec($fileMenu,$fileColor,$fileMask,$fileMenu);
 
-                               $backIm = $this->imageCreateFromGif($fileMenu); // The main image is loaded again...
+                               $backIm = $this->imageCreateFromFile($fileMenu);        // The main image is loaded again...
                                if ($backIm)    {       // ... and if nothing went wrong we load it onto the old one.
                                        ImageColorTransparent($backIm,-1);
                                        $im = $backIm;
@@ -1064,9 +1559,9 @@ class t3lib_stdGraphic    {
                        }
                                // Deleting temporary files;
                        if (!$this->dontUnlinkTempFiles)        {
-                               unlink($fileMenu);      
+                               unlink($fileMenu);
                                unlink($fileColor);
-                               unlink($fileMask);      
+                               unlink($fileMask);
                        }
                }
        }
@@ -1099,11 +1594,11 @@ class t3lib_stdGraphic  {
 
        /**
         * Implements the "BOX" GIFBUILDER object
-        * 
+        *
         * @param       pointer         GDlib image pointer
         * @param       array           TypoScript array with configuration for the GIFBUILDER object.
         * @param       array           The current working area coordinates.
-        * @return      void            
+        * @return      void
         * @see tslib_gifBuilder::make()
         */
        function makeBox(&$im,$conf,$workArea)  {
@@ -1111,18 +1606,32 @@ class t3lib_stdGraphic  {
                $conf['offset']=$cords[0].','.$cords[1];
                $cords = $this->objPosition($conf,$workArea,Array($cords[2],$cords[3]));
                $cols=$this->convertColor($conf['color']);
-               $this->reduceColors($im,256, 255);
-               $tmpColor = ImageColorAllocate($im, $cols[0],$cols[1],$cols[2]);
+               if (!$this->truecolor)  {
+                       $reduce = t3lib_div::intInRange($this->setup['reduceColors'], 256, $this->truecolorColors, 256);
+                       $this->reduceColors($im, $reduce-1, $reduce-2); // If "reduce-1" colors (or more) are used reduce them to "reduce-2"
+               }
+
+               $opacity = 0;
+               if (isset($conf['opacity'])) {
+                               // conversion:
+                               // PHP 0 = opaque, 127 = transparent
+                               // TYPO3 100 = opaque, 0 = transparent
+                       $opacity = t3lib_div::intInRange(intval($conf['opacity']), 1, 100, 1);
+                       $opacity = abs($opacity - 100);
+                       $opacity = round((127 * $opacity) / 100);
+               }
+
+               $tmpColor = ImageColorAllocateAlpha($im, $cols[0],$cols[1],$cols[2], $opacity);
                imagefilledrectangle($im, $cords[0], $cords[1], $cords[0]+$cords[2]-1, $cords[1]+$cords[3]-1, $tmpColor);
        }
 
        /**
         * Implements the "EFFECT" GIFBUILDER object
         * The operation involves ImageMagick for applying effects
-        * 
+        *
         * @param       pointer         GDlib image pointer
         * @param       array           TypoScript array with configuration for the GIFBUILDER object.
-        * @return      void            
+        * @return      void
         * @see tslib_gifBuilder::make(), applyImageMagickToPHPGif()
         */
        function makeEffect(&$im, $conf)        {
@@ -1134,7 +1643,7 @@ class t3lib_stdGraphic    {
 
        /**
         * Creating ImageMagick paramters from TypoScript property
-        * 
+        *
         * @param       string          A string with effect keywords=value pairs separated by "|"
         * @return      string          ImageMagick prepared parameters.
         * @access private
@@ -1151,7 +1660,7 @@ class t3lib_stdGraphic    {
                        switch($effect) {
                                case 'gamma':
                                        $commands.=' -gamma '.doubleval($value);
-                               break;          
+                               break;
                                case 'blur':
                                        if (!$this->NO_IM_EFFECTS)      {
                                                if ($this->V5_EFFECTS)  {
@@ -1160,7 +1669,7 @@ class t3lib_stdGraphic    {
                                                        $commands.=' -blur '.t3lib_div::intInRange($value,1,99);
                                                }
                                        }
-                               break;          
+                               break;
                                case 'sharpen':
                                        if (!$this->NO_IM_EFFECTS)      {
                                                if ($this->V5_EFFECTS)  {
@@ -1169,47 +1678,47 @@ class t3lib_stdGraphic  {
                                                        $commands.=' -sharpen '.t3lib_div::intInRange($value,1,99);
                                                }
                                        }
-                               break;          
+                               break;
                                case 'rotate':
                                        $commands.=' -rotate '.t3lib_div::intInRange($value,0,360);
-                               break;          
+                               break;
                                case 'solarize':
                                        $commands.=' -solarize '.t3lib_div::intInRange($value,0,99);
-                               break;          
+                               break;
                                case 'swirl':
                                        $commands.=' -swirl '.t3lib_div::intInRange($value,0,1000);
-                               break;          
+                               break;
                                case 'wave':
                                        $params = t3lib_div::intExplode(',',$value);
                                        $commands.=' -wave '.t3lib_div::intInRange($params[0],0,99).'x'.t3lib_div::intInRange($params[1],0,99);
-                               break;          
+                               break;
                                case 'charcoal':
                                        $commands.=' -charcoal '.t3lib_div::intInRange($value,0,100);
-                               break;          
+                               break;
                                case 'gray':
                                        $commands.=' -colorspace GRAY';
-                               break;          
+                               break;
                                case 'edge':
                                        $commands.=' -edge '.t3lib_div::intInRange($value,0,99);
-                               break;          
+                               break;
                                case 'emboss':
                                        $commands.=' -emboss';
-                               break;          
+                               break;
                                case 'flip':
                                        $commands.=' -flip';
-                               break;          
+                               break;
                                case 'flop':
                                        $commands.=' -flop';
-                               break;          
+                               break;
                                case 'colors':
                                        $commands.=' -colors '.t3lib_div::intInRange($value,2,255);
-                               break;          
+                               break;
                                case 'shear':
                                        $commands.=' -shear '.t3lib_div::intInRange($value,-90,90);
-                               break;          
+                               break;
                                case 'invert':
                                        $commands.=' -negate';
-                               break;          
+                               break;
                        }
                }
                return $commands;
@@ -1217,10 +1726,10 @@ class t3lib_stdGraphic  {
 
        /**
         * Implements the "ADJUST" GIFBUILDER object
-        * 
+        *
         * @param       pointer         GDlib image pointer
         * @param       array           TypoScript array with configuration for the GIFBUILDER object.
-        * @return      void            
+        * @return      void
         * @see tslib_gifBuilder::make(), autoLevels(), outputLevels(), inputLevels()
         */
        function adjust(&$im, $conf)    {
@@ -1249,10 +1758,10 @@ class t3lib_stdGraphic  {
 
        /**
         * Implements the "CROP" GIFBUILDER object
-        * 
+        *
         * @param       pointer         GDlib image pointer
         * @param       array           TypoScript array with configuration for the GIFBUILDER object.
-        * @return      void            
+        * @return      void
         * @see tslib_gifBuilder::make()
         */
        function crop(&$im,$conf)       {
@@ -1261,15 +1770,16 @@ class t3lib_stdGraphic  {
                $conf['offset']=$cords[0].','.$cords[1];
                $cords = $this->objPosition($conf,$this->workArea,Array($cords[2],$cords[3]));
 
-               $newIm = imagecreate($cords[2],$cords[3]);
+               $newIm = $this->imagecreate($cords[2],$cords[3]);
                $cols=$this->convertColor($conf['backColor']?$conf['backColor']:$this->setup['backColor']);
-               ImageColorAllocate($newIm, $cols[0],$cols[1],$cols[2]);
+               $Bcolor = ImageColorAllocate($newIm, $cols[0],$cols[1],$cols[2]);
+               ImageFilledRectangle($newIm, 0, 0, $cords[2], $cords[3], $Bcolor);
 
                $newConf = Array();
                $workArea = Array(0,0,$cords[2],$cords[3]);
                if ($cords[0]<0) {$workArea[0]=abs($cords[0]);} else {$newConf['offset']=-$cords[0];}
                if ($cords[1]<0) {$workArea[1]=abs($cords[1]);} else {$newConf['offset'].=','.-$cords[1];}
-               
+
                $this->copyGifOntoGif($newIm,$im,$newConf,$workArea);
                $im = $newIm;
                $this->w = imagesx($im);
@@ -1279,26 +1789,26 @@ class t3lib_stdGraphic  {
 
        /**
         * Implements the "SCALE" GIFBUILDER object
-        * 
+        *
         * @param       pointer         GDlib image pointer
         * @param       array           TypoScript array with configuration for the GIFBUILDER object.
-        * @return      void            
+        * @return      void
         * @see tslib_gifBuilder::make()
         */
        function scale(&$im,$conf)      {
                if ($conf['width'] || $conf['height'] || $conf['params'])       {
                        $tmpStr = $this->randomName();
                        $theFile = $tmpStr.'.'.$this->gifExtension;
-                       $this->ImageGif($im, $theFile);
+                       $this->ImageWrite($im, $theFile);
                        $theNewFile = $this->imageMagickConvert($theFile,$this->gifExtension,$conf['width'],$conf['height'],$conf['params'],'','');
-                       $tmpImg = $this->imageCreateFromGif($theNewFile[3]);
+                       $tmpImg = $this->imageCreateFromFile($theNewFile[3]);
                        if ($tmpImg)    {
                                ImageDestroy($im);
                                $im = $tmpImg;
                                $this->w = imagesx($im);
                                $this->h = imagesy($im);
                                $this->setWorkArea(''); // clears workArea to total image
-                       }       
+                       }
                        if (!$this->dontUnlinkTempFiles)        {
                                unlink($theFile);
                                if ($theNewFile[3] && $theNewFile[3]!=$theFile) {
@@ -1311,9 +1821,9 @@ class t3lib_stdGraphic    {
        /**
         * Implements the "WORKAREA" GIFBUILDER object when setting it
         * Setting internal working area boundaries (->workArea)
-        * 
+        *
         * @param       string          Working area dimensions, comma separated
-        * @return      void            
+        * @return      void
         * @access private
         * @see tslib_gifBuilder::make()
         */
@@ -1354,9 +1864,9 @@ class t3lib_stdGraphic    {
 
        /**
         * Apply auto-levels to input image pointer
-        * 
+        *
         * @param       integer         GDlib Image Pointer
-        * @return      void            
+        * @return      void
         */
        function autolevels(&$im)       {
                $totalCols = ImageColorsTotal($im);
@@ -1382,24 +1892,24 @@ class t3lib_stdGraphic  {
 
        /**
         * Apply output levels to input image pointer (decreasing contrast)
-        * 
+        *
         * @param       integer         GDlib Image Pointer
         * @param       integer         The "low" value (close to 0)
         * @param       integer         The "high" value (close to 255)
         * @param       boolean         If swap, then low and high are swapped. (Useful for negated masks...)
-        * @return      void            
+        * @return      void
         */
        function outputLevels(&$im,$low,$high,$swap='') {
                if ($low<$high){
                        $low = t3lib_div::intInRange($low,0,255);
                        $high = t3lib_div::intInRange($high,0,255);
-                       
+
                        if ($swap)      {
                                $temp = $low;
                                $low = 255-$high;
                                $high = 255-$temp;
                        }
-                       
+
                        $delta = $high-$low;
                        $totalCols = ImageColorsTotal($im);
                        for ($c=0; $c<$totalCols; $c++) {
@@ -1414,12 +1924,12 @@ class t3lib_stdGraphic  {
 
        /**
         * Apply input levels to input image pointer (increasing contrast)
-        * 
+        *
         * @param       integer         GDlib Image Pointer
         * @param       integer         The "low" value (close to 0)
         * @param       integer         The "high" value (close to 255)
         * @param       boolean         If swap, then low and high are swapped. (Useful for negated masks...)
-        * @return      void            
+        * @return      void
         */
        function inputLevels(&$im,$low,$high,$swap='')  {
                if ($low<$high){
@@ -1431,7 +1941,7 @@ class t3lib_stdGraphic    {
                                $low = 255-$high;
                                $high = 255-$temp;
                        }
-                       
+
                        $delta = $high-$low;
                        $totalCols = ImageColorsTotal($im);
                        for ($c=0; $c<$totalCols; $c++) {
@@ -1445,26 +1955,44 @@ class t3lib_stdGraphic  {
        }
 
        /**
-        * Reduce colors in image
-        * 
+        * Reduce colors in image dependend on the actual amount of colors (Only works if we are not in truecolor mode)
+        *
         * @param       integer         GDlib Image Pointer
         * @param       integer         The max number of colors in the image before a reduction will happen; basically this means that IF the GD image current has the same amount or more colors than $limit define, THEN a reduction is performed.
         * @param       integer         Number of colors to reduce the image to.
-        * @return      void            
+        * @return      void
         */
        function reduceColors(&$im,$limit, $cols)       {
-               if (ImageColorsTotal($im)>=$limit)      {
+               if (!$this->truecolor && ImageColorsTotal($im)>=$limit) {
                        $this->makeEffect($im, Array('value'=>'colors='.$cols) );
                }
        }
 
-
-
-
-
-
-
-
+       /**
+        * Reduce colors in image using IM and create a palette based image if possible (<=256 colors)
+        *
+        * @param       string          Image file to reduce
+        * @param       integer         Number of colors to reduce the image to.
+        * @return      string          Reduced file
+        */
+       function IMreduceColors($file, $cols)   {
+               $fI = t3lib_div::split_fileref($file);
+               $ext = strtolower($fI['fileext']);
+               $result = $this->randomName().'.'.$ext;
+               if (($reduce = t3lib_div::intInRange($cols, 0, ($ext=='gif'?256:$this->truecolorColors), 0))>0) {
+                       $params = ' -colors '.$reduce;
+                       if (!$this->im_version_4)       {
+                                       // IM4 doesn't have this options but forces them automatically if applicaple (<256 colors in image)
+                               if ($reduce<=256)       { $params .= ' -type Palette'; }
+                               if ($ext=='png' && $reduce<=256)        { $prefix = 'png8:'; }
+                       }
+                       $this->imageMagickExec($file, $prefix.$result, $params);
+                       if ($result)    {
+                               return $result;
+                       }
+               }
+               return '';
+       }
 
 
 
@@ -1478,7 +2006,7 @@ class t3lib_stdGraphic    {
 
        /*********************************
         *
-        * GIFBUILDER Helper functions 
+        * GIFBUILDER Helper functions
         *
         *********************************/
 
@@ -1486,20 +2014,20 @@ class t3lib_stdGraphic  {
         * Checks if the $fontFile is already at an absolute path and if not, prepends the correct path.
         * Use PATH_site unless we are in the backend.
         * Call it by t3lib_stdGraphic::prependAbsolutePath()
-        * 
+        *
         * @param       string          The font file
         * @return      string          The font file with absolute path.
         */
        function prependAbsolutePath($fontFile) {
                $absPath = defined('PATH_typo3') ? dirname(PATH_thisScript).'/' :PATH_site;
-               $fontFile = t3lib_div::isAbsPath($fontFile) ? $fontFile : $absPath.$fontFile;
+               $fontFile = t3lib_div::isAbsPath($fontFile) ? $fontFile : t3lib_div::resolveBackPath($absPath.$fontFile);
                return $fontFile;
        }
 
        /**
         * Returns the IM command for sharpening with ImageMagick 5 (when $this->V5_EFFECTS is set).
         * Uses $this->im5fx_sharpenSteps for translation of the factor to an actual command.
-        * 
+        *
         * @param       integer         The sharpening factor, 0-100 (effectively in 10 steps)
         * @return      string          The sharpening command, eg. " -sharpen 3x4"
         * @see makeText(), IMparams(), v5_blur()
@@ -1518,7 +2046,7 @@ class t3lib_stdGraphic    {
        /**
         * Returns the IM command for blurring with ImageMagick 5 (when $this->V5_EFFECTS is set).
         * Uses $this->im5fx_blurSteps for translation of the factor to an actual command.
-        * 
+        *
         * @param       integer         The blurring factor, 0-100 (effectively in 10 steps)
         * @return      string          The blurring command, eg. " -blur 3x4"
         * @see makeText(), IMparams(), v5_sharpen()
@@ -1537,17 +2065,18 @@ class t3lib_stdGraphic  {
        /**
         * Returns a random filename prefixed with "temp_" and then 32 char md5 hash (without extension) from $this->tempPath.
         * Used by functions in this class to create truely temporary files for the on-the-fly processing. These files will most likely be deleted right away.
-        * 
-        * @return      string          
+        *
+        * @return      string
         */
        function randomName()   {
-               return $this->tempPath.'temp_'.md5(uniqid(''));
+               $this->createTempSubDir('temp/');
+               return $this->tempPath.'temp/'.md5(uniqid(''));
        }
 
        /**
         * Applies offset value to coordinated in $cords.
         * Basically the value of key 0/1 of $OFFSET is added to keys 0/1 of $cords
-        * 
+        *
         * @param       array           Integer coordinates in key 0/1
         * @param       array           Offset values in key 0/1
         * @return      array           Modified $cords array
@@ -1561,7 +2090,7 @@ class t3lib_stdGraphic    {
        /**
         * Converts a "HTML-color" TypoScript datatype to RGB-values.
         * Default is 0,0,0
-        * 
+        *
         * @param       string          "HTML-color" data type string, eg. 'red', '#ffeedd' or '255,0,255'. You can also add a modifying operator afterwards. There are two options: "255,0,255 : 20" - will add 20 to values, result is "255,20,255". Or "255,0,255 : *1.23" which will multiply all RGB values with 1.23
         * @return      array           RGB values in key 0/1/2 of the array
         */
@@ -1572,12 +2101,12 @@ class t3lib_stdGraphic  {
                        // Finding the RGB definitions of the color:
                $string=$cParts[0];
                if (strstr($string,'#'))        {
-                       $string = ereg_replace('[^A-Fa-f0-9]*','',$string);
+                       $string = preg_replace('/[^A-Fa-f0-9]*/','',$string);
                        $col[]=HexDec(substr($string,0,2));
                        $col[]=HexDec(substr($string,2,2));
                        $col[]=HexDec(substr($string,4,2));
                } elseif (strstr($string,','))  {
-                       $string = ereg_replace('[^,0-9]*','',$string);
+                       $string = preg_replace('/[^,0-9]*/','',$string);
                        $strArr = explode(',',$string);
                        $col[]=intval($strArr[0]);
                        $col[]=intval($strArr[1]);
@@ -1611,7 +2140,7 @@ class t3lib_stdGraphic    {
        /**
         * Recode string
         * Used with text strings for fonts when languages has other character sets.
-        * 
+        *
         * @param       string          The text to recode
         * @return      string          The recoded string. Should be UTF-8 output. MAY contain entities (eg. &#123; or &#quot; which should render as real chars).
         */
@@ -1621,24 +2150,26 @@ class t3lib_stdGraphic  {
                        $string = $this->csConvObj->utf8_encode($string,$this->nativeCharset);  // Convert to UTF-8
                }
 
-                       // Recode string accoding to TTFLocaleConv. Depreciated.
+                       // Recode string accoding to TTFLocaleConv. Deprecated.
                if ($this->TTFLocaleConv)       {
-                       $string = recode_string($this->TTFLocaleConv,$string);
+                       list($from, $to) = t3lib_div::trimExplode('..', $this->TTFLocaleConv, true);
+                       $string = $this->csConvObj->conv($string, $from, $to);
                }
-               
+
                return $string;
        }
 
        /**
         * Split a string into an array of individual characters
-        * The function will look at  $this->nativeCharset and if that is set, the input string is expected to be UTF-8 encoded, possibly with entities in it. Otherwise the string is supposed to be a single-byte charset which is just splitted by a for-loop.
-        * 
-        * @param       string          The text string to spli
+        * The function will look at $this->nativeCharset and if that is set, the input string is expected to be UTF-8 encoded, possibly with entities in it. Otherwise the string is supposed to be a single-byte charset which is just splitted by a for-loop.
+        *
+        * @param       string          The text string to split
+        * @param       boolean         Return Unicode numbers instead of chars.
         * @return      array           Numerical array with a char as each value.
         */
-       function singleChars($theText)  {
+       function singleChars($theText,$returnUnicodeNumber=FALSE)       {
                if ($this->nativeCharset)       {
-                       return $this->csConvObj->utf8_to_numberarray($theText,1,1);     // Get an array of separated UTF-8 chars
+                       return $this->csConvObj->utf8_to_numberarray($theText,1,$returnUnicodeNumber ? 0 : 1);  // Get an array of separated UTF-8 chars
                } else {
                        $output=array();
                        $c=strlen($theText);
@@ -1651,7 +2182,7 @@ class t3lib_stdGraphic    {
 
        /**
         * Create an array with object position/boundaries based on input TypoScript configuration (such as the "align" property is used), the work area definition and $BB array
-        * 
+        *
         * @param       array           TypoScript configuration for a GIFBUILDER object
         * @param       array           Workarea definition
         * @param       array           BB (Bounding box) array. Not just used for TEXT objects but also for others
@@ -1661,16 +2192,16 @@ class t3lib_stdGraphic  {
         */
        function objPosition($conf,$workArea,$BB) {
                        // offset, align, valign, workarea
-               $result=Array();        
+               $result=Array();
                $result[2] = $BB[0];
                $result[3] = $BB[1];
                $w=$workArea[2];
                $h=$workArea[3];
-               
+
                $align = explode(',',$conf['align']);
                $align[0] = strtolower(substr(trim($align[0]),0,1));
                $align[1] = strtolower(substr(trim($align[1]),0,1));
-               
+
                switch($align[0])       {
                        case 'r':
                                $result[0]=$w-$result[2];
@@ -1726,7 +2257,7 @@ class t3lib_stdGraphic    {
 
        /**
         * Converts $imagefile to another file in temp-dir of type $newExt (extension).
-        * 
+        *
         * @param       string          The image filepath
         * @param       string          New extension, eg. "gif", "png", "jpg", "tif". If $newExt is NOT set, the new imagefile will be of the original format. If newExt = 'WEB' then one of the web-formats is applied.
         * @param       string          Width. $w / $h is optional. If only one is given the image is scaled proportionally. If an 'm' exists in the $w or $h and if both are present the $w and $h is regarded as the Maximum w/h and the proportions will be kept
@@ -1743,7 +2274,7 @@ class t3lib_stdGraphic    {
                                // Returning file info right away
                        return $this->getImageDimensions($imagefile);
                }
-               
+
                if($info=$this->getImageDimensions($imagefile)) {
                        $newExt=strtolower(trim($newExt));
                        if (!$newExt)   {       // If no extension is given the original extension is used
@@ -1765,44 +2296,59 @@ class t3lib_stdGraphic  {
                                $data = $this->getImageScale($info,$w,$h,$options);
                                $w=$data['origW'];
                                $h=$data['origH'];
-                               
+
                                        // if no convertion should be performed
                                $wh_noscale = (!$w && !$h) || ($data[0]==$info[0] && $data[1]==$info[1]);               // this flag is true if the width / height does NOT dictate the image to be scaled!! (that is if no w/h is given or if the destination w/h matches the original image-dimensions....
-                                       
-                               if ($wh_noscale && !$params && !$frame && $newExt==$info[2] && !$mustCreate) {  
+
+                               if ($wh_noscale && !$data['crs'] && !$params && !$frame && $newExt==$info[2] && !$mustCreate) {
                                        $info[3] = $imagefile;
                                        return $info;
                                }
                                $info[0]=$data[0];
                                $info[1]=$data[1];
 
-                               $frame = $this->noFramePrepended ? '' : '['.intval($frame).']';
-                               
+                               $frame = $this->noFramePrepended ? '' : intval($frame);
+
                                if (!$params)   {
                                        $params = $this->cmds[$newExt];
                                }
-                               
+
+                                       // Cropscaling:
+                               if ($data['crs']) {
+                                       if (!$data['origW']) { $data['origW'] = $data[0]; }
+                                       if (!$data['origH']) { $data['origH'] = $data[1]; }
+                                       $offsetX = intval(($data[0] - $data['origW']) * ($data['cropH']+100)/200);
+                                       $offsetY = intval(($data[1] - $data['origH']) * ($data['cropV']+100)/200);
+                                       $params .= ' -crop '.$data['origW'].'x'.$data['origH'].'+'.$offsetX.'+'.$offsetY.' ';
+                               }
+
                                $command = $this->scalecmd.' '.$info[0].'x'.$info[1].'! '.$params.' ';
-                               
+                               $cropscale = ($data['crs'] ? 'crs-V'.$data['cropV'].'H'.$data['cropH'] : '');
+
                                if ($this->alternativeOutputKey)        {
-                                       $theOutputName = t3lib_div::shortMD5($command.basename($imagefile).$this->alternativeOutputKey.$frame);
+                                       $theOutputName = t3lib_div::shortMD5($command.$cropscale.basename($imagefile).$this->alternativeOutputKey.'['.$frame.']');
                                } else {
-                                       $theOutputName = t3lib_div::shortMD5($command.$imagefile.filemtime($imagefile).$frame);
+                                       $theOutputName = t3lib_div::shortMD5($command.$cropscale.$imagefile.filemtime($imagefile).'['.$frame.']');
                                }
                                if ($this->imageMagickConvert_forceFileNameBody)        {
                                        $theOutputName = $this->imageMagickConvert_forceFileNameBody;
                                        $this->imageMagickConvert_forceFileNameBody='';
                                }
-                               $output = $this->tempPath.$this->filenamePrefix.$theOutputName.'.'.$newExt;
-                               $GLOBALS['TEMP_IMAGES_ON_PAGE'][]=$output;
 
-                               if (!$this->file_exists_typo3temp_file($output,$imagefile) || $this->dontCheckForExistingTempFile)      {
-                                       $this->imageMagickExec($imagefile.$frame,$output,$command);
+                                       // Making the temporary filename:
+                               $this->createTempSubDir('pics/');
+                               $output = $this->absPrefix.$this->tempPath.'pics/'.$this->filenamePrefix.$theOutputName.'.'.$newExt;
+
+                                       // Register temporary filename:
+                               $GLOBALS['TEMP_IMAGES_ON_PAGE'][] = $output;
+
+                               if ($this->dontCheckForExistingTempFile || !$this->file_exists_typo3temp_file($output, $imagefile))     {
+                                       $this->imageMagickExec($imagefile, $output, $command, $frame);
                                }
-                               if (@file_exists($output))      {
+                               if (file_exists($output))       {
                                        $info[3] = $output;
                                        $info[2] = $newExt;
-                                       if ($params)    {       // params could realisticly change som imagedata!
+                                       if ($params)    {       // params could realisticly change some imagedata!
                                                $info=$this->getImageDimensions($info[3]);
                                        }
                                        if ($info[2]==$this->gifExtension && !$this->dontCompress)      {
@@ -1816,35 +2362,109 @@ class t3lib_stdGraphic {
 
        /**
         * Gets the input image dimensions.
-        * 
+        *
         * @param       string          The image filepath
         * @return      array           Returns an array where [0]/[1] is w/h, [2] is extension and [3] is the filename.
         * @see imageMagickConvert(), tslib_cObj::getImgResource()
         */
-       function getImageDimensions($imagefile) {
-               ereg('([^\.]*)$',$imagefile,$reg);
-               if (@file_exists($imagefile) && t3lib_div::inList($this->imageFileExt,strtolower($reg[0])))     {
-                       if ($temp = @getImageSize($imagefile))  {
-                               return Array($temp[0], $temp[1], strtolower($reg[0]), $imagefile);
+       function getImageDimensions($imageFile) {
+               preg_match('/([^\.]*)$/',$imageFile,$reg);
+               if (file_exists($imageFile) && t3lib_div::inList($this->imageFileExt,strtolower($reg[0])))      {
+                       if ($returnArr = $this->getCachedImageDimensions($imageFile))   {
+                               return $returnArr;
                        } else {
-                               return $this->imageMagickIdentify($imagefile);
+                               if ($temp = @getImageSize($imageFile))  {
+                                       $returnArr = Array($temp[0], $temp[1], strtolower($reg[0]), $imageFile);
+                               } else {
+                                       $returnArr = $this->imageMagickIdentify($imageFile);
+                               }
+                               if ($returnArr) {
+                                       $this->cacheImageDimensions($returnArr);
+                                       return $returnArr;
+                               }
+                       }
+               }
+               return false;
+       }
+
+       /**
+        * Cache the result of the getImageDimensions function into the database. Does not check if the
+        * file exists!
+        *
+        * @param       array           $identifyResult: Result of the getImageDimensions function
+        * @return      boolean         True if operation was successful
+        * @author      Michael Stucki <michael@typo3.org> / Robert Lemke <rl@robertlemke.de>
+        */
+       function cacheImageDimensions($identifyResult)  {
+               global $TYPO3_DB;
+                       // Create a md5 hash of the filename
+               $md5Hash = md5_file($identifyResult[3]);
+               if ($md5Hash) {
+                       $fieldArr = array (
+                               'md5hash' => $md5Hash,
+                               'md5filename' => md5($identifyResult[3]),
+                               'tstamp' => $GLOBALS['EXEC_TIME'],
+                               'filename' => $identifyResult[3],
+                               'imagewidth' => $identifyResult[0],
+                               'imageheight' => $identifyResult[1],
+                       );
+                       $TYPO3_DB->exec_INSERTquery('cache_imagesizes', $fieldArr);
+                       if (!$err = $TYPO3_DB->sql_error())     {
+                               return true;
+                       }
+               }
+               return false;
+       }
+
+       /**
+        * Fetch the cached imageDimensions from the MySQL database. Does not check if the image file exists!
+        *
+        * @param       string          The image filepath
+        * @return      array           Returns an array where [0]/[1] is w/h, [2] is extension and [3] is the filename.
+        * @author      Michael Stucki <michael@typo3.org> / Robert Lemke <rl@robertlemke.de>
+        */
+       function getCachedImageDimensions($imageFile)   {
+               global $TYPO3_DB;
+                       // Create a md5 hash of the filename
+               $md5Hash = md5_file($imageFile);
+               preg_match('/([^\.]*)$/',$imageFile,$reg);
+               $res = $TYPO3_DB->exec_SELECTquery ('md5hash, imagewidth, imageheight', 'cache_imagesizes', 'md5filename='.$TYPO3_DB->fullQuoteStr(md5($imageFile),'cache_imagesizes'));
+               if ($res) {
+                       if ($row = $TYPO3_DB->sql_fetch_assoc($res)) {
+                               if ($row['md5hash']!=$md5Hash) {
+                                               // file has changed, delete the row
+                                       $TYPO3_DB->exec_DELETEquery ('cache_imagesizes', 'md5hash='.$TYPO3_DB->fullQuoteStr($row['md5hash'],'cache_imagesizes'));
+                               } else {
+                                       return (array((int) $row['imagewidth'], (int) $row['imageheight'], strtolower($reg[0]), $imageFile));
+                               }
                        }
                }
+               return false;
        }
 
        /**
         * Get numbers for scaling the image based on input
-        * 
+        *
         * @param       array           Current image information: Width, Height etc.
         * @param       integer         "required" width
         * @param       integer         "required" height
         * @param       array           Options: Keys are like "maxW", "maxH", "minW", "minH"
-        * @return      array           
+        * @return      array
         * @access private
         * @see imageMagickConvert()
         */
        function getImageScale($info,$w,$h,$options) {
                if (strstr($w.$h, 'm')) {$max=1;} else {$max=0;}
+
+               if (strstr($w.$h, 'c')) {
+                       $out['cropH'] = intval(substr(strstr($w, 'c'), 1));
+                       $out['cropV'] = intval(substr(strstr($h, 'c'), 1));
+                       $crs = true;
+               } else {
+                       $crs = false;
+               }
+               $out['crs'] = $crs;
+
                $w=intval($w);
                $h=intval($h);
                        // if there are max-values...
@@ -1877,7 +2497,7 @@ class t3lib_stdGraphic    {
                $out['origW']=$w;
                $out['origH']=$h;
                $out['max'] = $max;
-               
+
                if (!$this->mayScaleUp) {
                        if ($w>$info[0]){$w=$info[0];}
                        if ($h>$info[1]){$h=$info[1];}
@@ -1900,6 +2520,14 @@ class t3lib_stdGraphic   {
                                                $w = round($h*$ratio);
                                        }
                                }
+                               if ($crs)       {
+                                       $ratio = $info[0] / $info[1];
+                                       if ($h * $ratio < $w) {
+                                               $h = round($w / $ratio);
+                                       } else {
+                                               $w = round($h * $ratio);
+                                       }
+                               }
                                $info[0] = $w;
                                $info[1] = $h;
                        }
@@ -1908,24 +2536,24 @@ class t3lib_stdGraphic  {
                $out[1]=$info[1];
                        // Set minimum-measures!
                if ($options['minW'] && $out[0]<$options['minW'])       {
-                       if ($max && $out[0])    {
+                       if (($max || $crs) && $out[0])  {
                                $out[1]= round($out[1]*$options['minW']/$out[0]);
                        }
                        $out[0]=$options['minW'];
                }
                if ($options['minH'] && $out[1]<$options['minH'])       {
-                       if ($max && $out[1])    {
+                       if (($max || $crs) && $out[1])  {
                                $out[0]= round($out[0]*$options['minH']/$out[1]);
                        }
                        $out[1]=$options['minH'];
                }
-               
+
                return $out;
        }
 
        /**
-        * Used to check if a certain process of scaling an image is already being carried out (can be logged in the MySQL database)
-        * 
+        * Used to check if a certain process of scaling an image is already being carried out (can be logged in the SQL database)
+        *
         * @param       string          Output imagefile
         * @param       string          Original basis file
         * @return      boolean         Returns true if the file is already being made; thus "true" means "Don't render the image again"
@@ -1933,28 +2561,36 @@ class t3lib_stdGraphic  {
         */
        function file_exists_typo3temp_file($output,$orig='')   {
                if ($this->enable_typo3temp_db_tracking)        {
-                       if (@file_exists($output))      {       // If file exists, then we return immediately
+                       if (file_exists($output))       {       // If file exists, then we return immediately
                                return 1;
                        } else {        // If not, we look up in the cache_typo3temp_log table to see if there is a image being rendered right now.
                                $md5Hash=md5($output);
-                               $query='SELECT md5hash FROM cache_typo3temp_log WHERE md5hash="'.$md5Hash.'" AND tstamp>'.(time()-30);
-                               $res=mysql(TYPO3_db,$query);
-                               echo mysql_error();
-                               if ($row=mysql_fetch_assoc($res))       {       // If there was a record, the image is being generated by another proces (we assume)
+                               $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
+                                       'md5hash',
+                                       'cache_typo3temp_log',
+                                       'md5hash=' . $GLOBALS['TYPO3_DB']->fullQuoteStr($md5Hash, 'cache_typo3temp_log') . ' AND tstamp>' . ($GLOBALS['EXEC_TIME'] - 30)
+                               );
+                               if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {       // If there was a record, the image is being generated by another proces (we assume)
                                        if (is_object($GLOBALS['TSFE']))        $GLOBALS['TSFE']->set_no_cache();       // ...so we set no_cache, because we dont want this page (which will NOT display an image...!) to be cached! (Only a page with the correct image on...)
                                        if (is_object($GLOBALS['TT']))  $GLOBALS['TT']->setTSlogMessage('typo3temp_log: Assume this file is being rendered now: '.$output);
                                        return 2;       // Return 'success - 2'
-                               } else {                // If the current time is more than 30 seconds since this record was written, we clear the record, write a new and render the image. 
-                                       $query='DELETE FROM cache_typo3temp_log WHERE md5hash="'.$md5Hash.'"';
-                                       $res=mysql(TYPO3_db,$query);
-                                       $query='INSERT INTO cache_typo3temp_log (md5hash,tstamp,filename,orig_filename) VALUES ("'.$md5Hash.'",'.time().',"'.addslashes($output).'","'.addslashes($orig).'")';
-                                       $res=mysql(TYPO3_db,$query);
+                               } else {                // If the current time is more than 30 seconds since this record was written, we clear the record, write a new and render the image.
+
+                                       $insertFields = array(
+                                               'md5hash' => $md5Hash,
+                                               'tstamp' => $GLOBALS['EXEC_TIME'],
+                                               'filename' => $output,
+                                               'orig_filename' => $orig
+                                       );
+                                       $GLOBALS['TYPO3_DB']->exec_DELETEquery('cache_typo3temp_log', 'md5hash='.$GLOBALS['TYPO3_DB']->fullQuoteStr($md5Hash, 'cache_typo3temp_log'));
+                                       $GLOBALS['TYPO3_DB']->exec_INSERTquery('cache_typo3temp_log', $insertFields);
+
                                        if (is_object($GLOBALS['TT']))  $GLOBALS['TT']->setTSlogMessage('typo3temp_log: The row did not exist, so a new is written and file is being processed: '.$output);
                                        return 0;
                                }
                        }
                } else {
-                       return @file_exists($output);
+                       return file_exists($output);
                }
        }
 
@@ -1984,18 +2620,20 @@ class t3lib_stdGraphic  {
        /**
         * Returns an array where [0]/[1] is w/h, [2] is extension and [3] is the filename.
         * Using ImageMagick
-        * 
-        * @param       string          The absolute image filepath
-        * @return      array           
+        *
+        * @param       string          The relative (to PATH_site) image filepath
+        * @return      array
         */
        function imageMagickIdentify($imagefile)        {
                if (!$this->NO_IMAGE_MAGICK)    {
-                       $cmd = $this->imageMagickPath.'identify '.$this->wrapFileName($imagefile);
+                       $frame = $this->noFramePrepended?'':'[0]';
+                       $cmd = t3lib_div::imageMagickCommand('identify', $this->wrapFileName($imagefile).$frame);
+                       $returnVal = array();
                        exec($cmd, $returnVal);
                        $splitstring=$returnVal[0];
                        $this->IM_commands[] = Array ('identify',$cmd,$returnVal[0]);
                        if ($splitstring)       {
-                               ereg('([^\.]*)$',$imagefile,$reg);
+                               preg_match('/([^\.]*)$/',$imagefile,$reg);
                                $splitinfo = explode(' ', $splitstring);
                                while (list($key,$val) = each($splitinfo))      {
                                        $temp = '';
@@ -2015,50 +2653,79 @@ class t3lib_stdGraphic  {
        /**
         * Executes a ImageMagick "convert" on two filenames, $input and $output using $params before them.
         * Can be used for many things, mostly scaling and effects.
-        * 
-        * @param       string          The absolute image filepath, input file (read from)
-        * @param       string          The absolute image filepath, output filename (written to)
+        *
+        * @param       string          The relative (to PATH_site) image filepath, input file (read from)
+        * @param       string          The relative (to PATH_site) image filepath, output filename (written to)
         * @param       string          ImageMagick parameters
+        * @param       integer         Optional, refers to which frame-number to select in the image. '' or 0
+        *                              will select the first frame, 1 will select the next and so on...
         * @return      string          The result of a call to PHP function "exec()"
         */
-       function imageMagickExec($input,$output,$params)        {
-               if (!$this->NO_IMAGE_MAGICK)    {
-                       $cmd = $this->imageMagickPath.'convert '.$params.' '.$this->wrapFileName($input).' '.$this->wrapFileName($output);
-                       $this->IM_commands[] = Array ($output,$cmd);
-                       return exec($cmd);      
+       function imageMagickExec($input, $output, $params, $frame = 0) {
+               if (!$this->NO_IMAGE_MAGICK) {
+
+                               // Unless noFramePrepended is set in the Install Tool, a frame number is added to
+                               // select a specific page of the image (by default this will be the first page)
+                       if (!$this->noFramePrepended) {
+                               $frame = '[' . intval($frame) . ']';
+                       } else {
+                               $frame = '';
+                       }
+
+                       $cmd = t3lib_div::imageMagickCommand('convert', $params . ' ' . $this->wrapFileName($input) . $frame . ' ' . $this->wrapFileName($output));
+                       $this->IM_commands[] = array($output,$cmd);
+
+                       $ret = exec($cmd);
+                       t3lib_div::fixPermissions($output);     // Change the permissions of the file
+
+                       return $ret;
                }
        }
 
        /**
         * Executes a ImageMagick "combine" (or composite in newer times) on four filenames - $input, $overlay and $mask as input files and $output as the output filename (written to)
         * Can be used for many things, mostly scaling and effects.
-        * 
-        * @param       string          The absolute image filepath, bottom file
-        * @param       string          The absolute image filepath, overlay file (top)
-        * @param       string          The absolute image filepath, the mask file (grayscale)
-        * @param       string          The absolute image filepath, output filename (written to)
-        * @return      void            
-        */
-       function combineExec($input,$overlay,$mask,$output)     {
+        *
+        * @param       string          The relative (to PATH_site) image filepath, bottom file
+        * @param       string          The relative (to PATH_site) image filepath, overlay file (top)
+        * @param       string          The relative (to PATH_site) image filepath, the mask file (grayscale)
+        * @param       string          The relative (to PATH_site) image filepath, output filename (written to)
+        * @param       [type]          $handleNegation: ...
+        * @return      void
+        */
+       function combineExec($input,$overlay,$mask,$output, $handleNegation = false)    {
                if (!$this->NO_IMAGE_MAGICK)    {
-                       $cmd = $this->imageMagickPath.$this->combineScript.' -compose over '.$this->wrapFileName($input).' '.$this->wrapFileName($overlay).' '.$this->wrapFileName($mask).' '.$this->wrapFileName($output);
+                       $params = '-colorspace GRAY +matte';
+                       if ($handleNegation)    {
+                               if ($this->maskNegate)  {
+                                       $params .= ' '.$this->maskNegate;
+                               }
+                       }
+                       $theMask = $this->randomName().'.'.$this->gifExtension;
+                       $this->imageMagickExec($mask, $theMask, $params);
+                       $cmd = t3lib_div::imageMagickCommand('combine', '-compose over +matte '.$this->wrapFileName($input).' '.$this->wrapFileName($overlay).' '.$this->wrapFileName($theMask).' '.$this->wrapFileName($output));              // +matte = no alpha layer in output
                        $this->IM_commands[] = Array ($output,$cmd);
-                       exec($cmd);     
+
+                       $ret = exec($cmd);
+                       t3lib_div::fixPermissions($output);     // Change the permissions of the file
+
+                       if (is_file($theMask))  {
+                               @unlink($theMask);
+                       }
+
+                       return $ret;
                }
        }
 
        /**
-        * Wrapping the input filename in double-quotes
-        * 
-        * @param       string          Input filename
-        * @return      string          The outpute wrapped in ""
-        * @access private
+        * Escapes a file name so it can safely be used on the command line.
+        *
+        * @param string $inputName filename to safeguard, must not be empty
+        *
+        * @return string $inputName escaped as needed
         */
-       function wrapFileName($inputName)       {
-               if (strstr($inputName,' '))     {
-                       $inputName='"'.$inputName.'"';
-               }
-               return $inputName;
+       protected function wrapFileName($inputName) {
+               return escapeshellarg($inputName);
        }
 
 
@@ -2091,7 +2758,7 @@ class t3lib_stdGraphic    {
 
        /**
         * Returns true if the input file existed
-        * 
+        *
         * @param       string          Input file to check
         * @return      string          Returns the filename if the file existed, otherwise empty.
         */
@@ -2104,24 +2771,45 @@ class t3lib_stdGraphic  {
        }
 
        /**
+        * Creates subdirectory in typo3temp/ if not already found.
+        *
+        * @param       string          Name of sub directory
+        * @return      boolean         Result of t3lib_div::mkdir(), true if it went well.
+        */
+       function createTempSubDir($dirName)     {
+
+                       // Checking if the this->tempPath is already prefixed with PATH_site and if not, prefix it with that constant.
+               if (t3lib_div::isFirstPartOfStr($this->tempPath,PATH_site))     {
+                       $tmpPath = $this->tempPath;
+               } else {
+                       $tmpPath = PATH_site.$this->tempPath;
+               }
+
+                       // Making the temporary filename:
+               if (!@is_dir($tmpPath.$dirName))         {
+                       return t3lib_div::mkdir($tmpPath.$dirName);
+               }
+       }
+
+       /**
         * Applies an ImageMagick parameter to a GDlib image pointer resource by writing the resource to file, performing an IM operation upon it and reading back the result into the ImagePointer.
-        * 
+        *
         * @param       pointer         The image pointer (reference)
         * @param       string          The ImageMagick parameters. Like effects, scaling etc.
-        * @return      void            
+        * @return      void
         */
        function applyImageMagickToPHPGif(&$im, $command)       {
                $tmpStr = $this->randomName();
                $theFile = $tmpStr.'.'.$this->gifExtension;
-               $this->ImageGif($im, $theFile);
+               $this->ImageWrite($im, $theFile);
                $this->imageMagickExec($theFile,$theFile,$command);
-               $tmpImg = $this->imageCreateFromGif($theFile);
+               $tmpImg = $this->imageCreateFromFile($theFile);
                if ($tmpImg)    {
                        ImageDestroy($im);
                        $im = $tmpImg;
                        $this->w = imagesx($im);
                        $this->h = imagesy($im);
-               }       
+               }
                if (!$this->dontUnlinkTempFiles)        {
                        unlink($theFile);
                }
@@ -2130,7 +2818,7 @@ class t3lib_stdGraphic    {
        /**
         * Returns an image extension for an output image based on the number of pixels of the output and the file extension of the original file.
         * For example: If the number of pixels exceeds $this->pixelLimitGif (normally 10000) then it will be a "jpg" string in return.
-        * 
+        *
         * @param       string          The file extension, lowercase.
         * @param       integer         The width of the output image.
         * @param       integer         The height of the output image.
@@ -2148,42 +2836,38 @@ class t3lib_stdGraphic  {
         * Writing the internal image pointer, $this->im, to file based on the extension of the input filename
         * Used in GIFBUILDER
         * Uses $this->setup['reduceColors'] for gif/png images and $this->setup['quality'] for jpg images to reduce size/quality if needed.
-        * 
+        *
         * @param       string          The filename to write to.
         * @return      string          Returns input filename
         * @see tslib_gifBuilder::gifBuild()
         */
        function output($file)  {
                if ($file)      {
-                       ereg('([^\.]*)$',$file,$reg);
+                       $reg = array();
+                       preg_match('/([^\.]*)$/',$file,$reg);
                        $ext=strtolower($reg[0]);
                        switch($ext)    {
-                               case $this->gifExtension:
-                                       if ($this->ImageGif($this->im, $file))  {
-                                               // ImageMagick operations
-                                               if($this->setup['reduceColors'])        {
-                                                       $this->imageMagickExec($file,$file,' -colors '.t3lib_div::intInRange($this->setup['reduceColors'],2,255));
-                                                       t3lib_div::gif_compress($file,'');      // Compress with IM (lzw) or GD (rle)      (Workaround for the absence of lzw-compression in GD)
-                                               } else {
-                                                       t3lib_div::gif_compress($file, 'IM');           // Compress with IM! (adds extra compression, LZW from ImageMagick)     (Workaround for the absence of lzw-compression in GD)
+                               case 'gif':
+                               case 'png':
+                                       if ($this->ImageWrite($this->im, $file))        {
+                                                       // ImageMagick operations
+                                               if ($this->setup['reduceColors'] || (!$this->png_truecolor && $this->truecolor))        {
+                                                       $reduced = $this->IMreduceColors($file, t3lib_div::intInRange($this->setup['reduceColors'], 256, $this->truecolorColors, 256));
+                                                       if ($reduced)   {
+                                                               @copy($reduced, $file);
+                                                               @unlink($reduced);
+                                                       }
                                                }
+                                               t3lib_div::gif_compress($file, 'IM');           // Compress with IM! (adds extra compression, LZW from ImageMagick)     (Workaround for the absence of lzw-compression in GD)
                                        }
                                break;
                                case 'jpg':
                                case 'jpeg':
-                                       $tmpStr = $this->randomName();
-                                       $theFile = $tmpStr.'.'.$this->gifExtension;
-                                       if ($this->ImageGif($this->im, $theFile))       {
-                                               // ImageMagick operations
-                                               $operations='';
-                                               if($this->setup['quality'])     {
-                                                       $operations.=' -quality '.t3lib_div::intInRange($this->setup['quality'],10,100);
-                                               }
-                                               $this->imageMagickExec($theFile,$file,$operations);
-                                               if (!$this->dontUnlinkTempFiles)        {
-                                                       unlink($theFile);
-                                               }
+                                       $quality = 0;   // Use the default
+                                       if($this->setup['quality'])     {
+                                               $quality = t3lib_div::intInRange($this->setup['quality'],10,100);
                                        }
+                                       if ($this->ImageWrite($this->im, $file, $quality));
                                break;
                        }
                        $GLOBALS['TEMP_IMAGES_ON_PAGE'][]=$file;
@@ -2193,8 +2877,8 @@ class t3lib_stdGraphic    {
 
        /**
         * Destroy internal image pointer, $this->im
-        * 
-        * @return      void            
+        *
+        * @return      void
         * @see tslib_gifBuilder::gifBuild()
         */
        function destroy()      {
@@ -2203,7 +2887,7 @@ class t3lib_stdGraphic    {
 
        /**
         * Returns Image Tag for input image information array.
-        * 
+        *
         * @param       array           Image information array, key 0/1 is width/height and key 3 is the src value
         * @return      string          Image tag for the input image information array.
         */
@@ -2213,56 +2897,207 @@ class t3lib_stdGraphic {
 
        /**
         * Writes the input GDlib image pointer to file
-        * 
+        *
         * @param       pointer         The GDlib image resource pointer
         * @param       string          The filename to write to
-        * @return      ?               The output of either imageGif or imagePng based on whether the $this->gifExtension was set to "gif" or "png"
+        * @param       integer         The image quality (for JPEGs)
+        * @return      boolean         The output of either imageGif, imagePng or imageJpeg based on the filename to write
         * @see maskImageOntoImage(), scale(), output()
         */
-       function ImageGif($destImg, $theImage)  {
+       function ImageWrite($destImg, $theImage, $quality=0)    {
                imageinterlace ($destImg,0);
-               if ($this->gifExtension=='gif') {
-                       return ImageGif($destImg, $theImage);
+               $ext = strtolower(substr($theImage, strrpos($theImage, '.')+1));
+               $result = FALSE;
+               switch ($ext)   {
+                       case 'jpg':
+                       case 'jpeg':
+                               if (function_exists('imageJpeg'))       {
+                                       if ($quality == 0)      {
+                                               $quality = $this->jpegQuality;
+                                       }
+                                       $result = imageJpeg($destImg, $theImage, $quality);
+                               }
+                       break;
+                       case 'gif':
+                               if (function_exists('imageGif'))        {
+                                       if ($this->truecolor)   {
+                                               imagetruecolortopalette($destImg, true, 256);
+                                       }
+                                       $result = imageGif($destImg, $theImage);
+                               }
+                       break;
+                       case 'png':
+                               if (function_exists('imagePng'))        {
+                                       $result = ImagePng($destImg, $theImage);
+                               }
+                       break;
                }
-               if ($this->gifExtension=='png') {
-                       return ImagePng($destImg, $theImage);
+               if ($result) {
+                       t3lib_div::fixPermissions($theImage);
                }
+               return $result;
+       }
+
+
+
+       /**
+        * Writes the input GDlib image pointer to file. Now just a wrapper to ImageWrite.
+        *
+        * @param       pointer         The GDlib image resource pointer
+        * @param       string          The filename to write to
+        * @return      mixed           The output of either imageGif, imagePng or imageJpeg based on the filename to write
+        * @see imageWrite()
+        * @deprecated since TYPO3 4.0, this function will be removed in TYPO3 4.5.
+        */
+       function imageGif($destImg, $theImage)  {
+               t3lib_div::logDeprecatedFunction();
+
+               return $this->imageWrite($destImg, $theImage);
+       }
+
+       /**
+        * This function has been renamed and only exists for providing backwards compatibility.
+        * Please use $this->imageCreateFromFile() instead.
+        *
+        * @param       string          Image filename
+        * @return      pointer         Image Resource pointer
+        * @deprecated since TYPO3 4.0, this function will be removed in TYPO3 4.5.
+        */
+       function imageCreateFromGif($sourceImg) {
+               t3lib_div::logDeprecatedFunction();
+
+               return $this->imageCreateFromFile($sourceImg);
        }
 
        /**
         * Creates a new GDlib image resource based on the input image filename.
         * If it fails creating a image from the input file a blank gray image with the dimensions of the input image will be created instead.
-        * 
+        *
         * @param       string          Image filename
         * @return      pointer         Image Resource pointer
         */
-       function imageCreateFromGif($sourceImg) {
+       function imageCreateFromFile($sourceImg)        {
                $imgInf = pathinfo($sourceImg);
                $ext = strtolower($imgInf['extension']);
 
-//             if ($ext=='gif' && (ImageTypes() & IMG_GIF))    {
-               if ($ext=='gif' && function_exists('imagecreatefromgif'))       {
-                       return imageCreateFromGif($sourceImg);
-               }
-//             if ($ext=='png' && (ImageTypes() & IMG_PNG))    {
-               if ($ext=='png' && function_exists('imagecreatefrompng'))       {
-                       return imageCreateFromPng($sourceImg);
-               }
-//             if (($ext=='jpg' || $ext=='jpeg') && (ImageTypes() & IMG_JPG))  {
-               if (($ext=='jpg' || $ext=='jpeg') && function_exists('imagecreatefromjpeg'))    {
-                       return imageCreateFromJpeg($sourceImg);
+               switch ($ext)   {
+                       case 'gif':
+                               if (function_exists('imagecreatefromgif'))      {
+                                       return imageCreateFromGif($sourceImg);
+                               }
+                       break;
+                       case 'png':
+                               if (function_exists('imagecreatefrompng'))      {
+                                       return imageCreateFromPng($sourceImg);
+                               }
+                       break;
+                       case 'jpg':
+                       case 'jpeg':
+                               if (function_exists('imagecreatefromjpeg'))     {
+                                       return imageCreateFromJpeg($sourceImg);
+                               }
+                       break;
                }
 
                // If non of the above:
                $i = @getimagesize($sourceImg);
-               $im = imagecreate($i[0],$i[1]);
-               ImageColorAllocate($im, 128,128,128);
+               $im = $this->imagecreate($i[0],$i[1]);
+               $Bcolor = ImageColorAllocate($im, 128,128,128);
+               ImageFilledRectangle($im, 0, 0, $i[0], $i[1], $Bcolor);
                return $im;
        }
-}
 
 
+       /**
+        * Creates a new GD image resource. Wrapper for imagecreate(truecolor) depended if GD2 is used.
+        *
+        * @param       integer         Width of image
+        * @param       integer         Height of image
+        * @return      pointer         Image Resource pointer
+        */
+       function imagecreate($w, $h)    {
+               if($this->truecolor && function_exists('imagecreatetruecolor')) {
+                       return imagecreatetruecolor($w, $h);
+               } else  {
+                       return imagecreate($w, $h);
+               }
+
+       }
+
+       /**
+        * Returns the HEX color value for an RGB color array
+        *
+        * @param       array           RGB color array
+        * @return      string          HEX color value
+        */
+       function hexColor($col) {
+               $r = dechex($col[0]);
+               if (strlen($r)<2)       { $r = '0'.$r; }
+               $g = dechex($col[1]);
+               if (strlen($g)<2)       { $g = '0'.$g; }
+               $b = dechex($col[2]);
+               if (strlen($b)<2)       { $b = '0'.$b; }
+               return '#'.$r.$g.$b;
+       }
+
+       /**
+        * Unifies all colors given in the colArr color array to the first color in the array.
+        *
+        * @param       pointer         Image resource
+        * @param       array           Array containing RGB color arrays
+        * @param       [type]          $closest: ...
+        * @return      integer         The index of the unified color
+        */
+       function unifyColors(&$img, $colArr, $closest = false)  {
+               $retCol = -1;
+               if (is_array($colArr) && count($colArr) && function_exists('imagepng') && function_exists('imagecreatefrompng'))        {
+                       $firstCol = array_shift($colArr);
+                       $firstColArr = $this->convertColor($firstCol);
+                       if (count($colArr)>1)   {
+                               $origName = $preName = $this->randomName().'.png';
+                               $postName = $this->randomName().'.png';
+                               $this->imageWrite($img, $preName);
+                               $firstCol = $this->hexColor($firstColArr);
+                               foreach ($colArr as $transparentColor)  {
+                                       $transparentColor = $this->convertColor($transparentColor);
+                                       $transparentColor = $this->hexColor($transparentColor);
+                                       $cmd = '-fill "'.$firstCol.'" -opaque "'.$transparentColor.'"';
+                                       $this->imageMagickExec($preName, $postName, $cmd);
+                                       $preName = $postName;
+                               }
+                               $this->imageMagickExec($postName, $origName, '');
+                               if (@is_file($origName))        {
+                                       $tmpImg = $this->imageCreateFromFile($origName);
+                               }
+                       } else  {
+                               $tmpImg = $img;
+                       }
+                       if ($tmpImg)    {
+                               $img = $tmpImg;
+                               if ($closest)   {
+                                       $retCol = ImageColorClosest ($img, $firstColArr[0], $firstColArr[1], $firstColArr[2]);
+                               } else  {
+                                       $retCol = ImageColorExact ($img, $firstColArr[0], $firstColArr[1], $firstColArr[2]);
+                               }
+                       }
+                               // unlink files from process
+                       if (!$this->dontUnlinkTempFiles)        {
+                               if ($origName)  {
+                                       @unlink($origName);
+                               }
+                               if ($postName)  {
+                                       @unlink($postName);
+                               }
+                       }
+               }
+               return $retCol;
+       }
+
+
+}
+
 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_stdgraphic.php'])       {
        include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_stdgraphic.php']);
 }
+
 ?>
\ No newline at end of file