Project

General

Profile

Bug #22410 » 14050_cleaning_t3lib_stdgraphic.patch

Administrator Admin, 2010-11-24 16:23

View differences:

t3lib/class.t3lib_stdgraphic.php (revision )
<?php
/***************************************************************
* Copyright notice
*
* (c) 1999-2010 Kasper Sk?rh?j (kasperYYYY@typo3.com)
* All rights reserved
*
* 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
* 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
* GNU General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
* Copyright notice
*
* (c) 1999-2010 Kasper Sk?rh?j (kasperYYYY@typo3.com)
* All rights reserved
*
* 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
* 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
* GNU General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
/**
* Standard graphical functions
*
......
*
*
* 155: class t3lib_stdGraphic
* 236: function init()
* 236: function init()
*
* SECTION: Layering images / "IMAGE" GIFBUILDER object
* SECTION: Layering images / "IMAGE" GIFBUILDER object
* 366: function maskImageOntoImage(&$im,$conf,$workArea)
* 366: function maskImageOntoImage(&$im,$conf,$workArea)
* 436: function copyImageOntoImage(&$im,$conf,$workArea)
* 436: function copyImageOntoImage(&$im,$conf,$workArea)
* 458: function copyGifOntoGif(&$im,$cpImg,$conf,$workArea)
* 458: function copyGifOntoGif(&$im,$cpImg,$conf,$workArea)
* 537: function imagecopyresized(&$im, $cpImg, $Xstart, $Ystart, $cpImgCutX, $cpImgCutY, $w, $h, $w, $h)
* 537: function imagecopyresized(&$im, $cpImg, $Xstart, $Ystart, $cpImgCutX, $cpImgCutY, $w, $h, $w, $h)
*
* SECTION: Text / "TEXT" GIFBUILDER object
* SECTION: Text / "TEXT" GIFBUILDER object
* 587: function makeText(&$im,$conf,$workArea)
* 587: function makeText(&$im,$conf,$workArea)
* 707: function txtPosition($conf,$workArea,$BB)
* 707: function txtPosition($conf,$workArea,$BB)
* 761: function calcBBox($conf)
* 761: function calcBBox($conf)
* 820: function addToMap($cords,$conf)
* 820: function addToMap($cords,$conf)
* 843: function calcTextCordsForMap($cords,$offset, $conf)
* 843: function calcTextCordsForMap($cords,$offset, $conf)
* 878: function SpacedImageTTFText(&$im, $fontSize, $angle, $x, $y, $Fcolor, $fontFile, $text, $spacing, $wordSpacing, $splitRenderingConf, $sF=1)
* 878: function SpacedImageTTFText(&$im, $fontSize, $angle, $x, $y, $Fcolor, $fontFile, $text, $spacing, $wordSpacing, $splitRenderingConf, $sF=1)
* 915: function fontResize($conf)
* 915: function fontResize($conf)
* 958: function ImageTTFBBoxWrapper($fontSize, $angle, $fontFile, $string, $splitRendering, $sF=1)
* 958: function ImageTTFBBoxWrapper($fontSize, $angle, $fontFile, $string, $splitRendering, $sF=1)
* 1005: function ImageTTFTextWrapper($im, $fontSize, $angle, $x, $y, $color, $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)
* 1058: function splitString($string,$splitRendering,$fontSize,$fontFile)
* 1208: function calcWordSpacing($conf, $scaleFactor=1)
* 1208: function calcWordSpacing($conf, $scaleFactor=1)
* 1227: function getTextScalFactor($conf)
* 1227: function getTextScalFactor($conf)
*
* SECTION: Other GIFBUILDER objects related to TEXT
* SECTION: Other GIFBUILDER objects related to TEXT
* 1262: function makeOutline(&$im,$conf,$workArea,$txtConf)
* 1262: function makeOutline(&$im,$conf,$workArea,$txtConf)
* 1291: function circleOffset($distance, $iterations)
* 1291: function circleOffset($distance, $iterations)
* 1315: function makeEmboss(&$im,$conf,$workArea,$txtConf)
* 1315: function makeEmboss(&$im,$conf,$workArea,$txtConf)
* 1337: function makeShadow(&$im,$conf,$workArea,$txtConf)
* 1337: function makeShadow(&$im,$conf,$workArea,$txtConf)
*
* SECTION: Other GIFBUILDER objects
* SECTION: Other GIFBUILDER objects
* 1469: function makeBox(&$im,$conf,$workArea)
* 1469: function makeBox(&$im,$conf,$workArea)
* 1491: function makeEffect(&$im, $conf)
* 1491: function makeEffect(&$im, $conf)
* 1506: function IMparams($setup)
* 1506: function IMparams($setup)
* 1589: function adjust(&$im, $conf)
* 1589: function adjust(&$im, $conf)
* 1621: function crop(&$im,$conf)
* 1621: function crop(&$im,$conf)
* 1652: function scale(&$im,$conf)
* 1652: function scale(&$im,$conf)
* 1684: function setWorkArea($workArea)
* 1684: function setWorkArea($workArea)
*
* SECTION: Adjustment functions
* SECTION: Adjustment functions
* 1725: function autolevels(&$im)
* 1725: function autolevels(&$im)
* 1756: function outputLevels(&$im,$low,$high,$swap='')
* 1756: function outputLevels(&$im,$low,$high,$swap='')
* 1788: function inputLevels(&$im,$low,$high,$swap='')
* 1788: function inputLevels(&$im,$low,$high,$swap='')
* 1819: function reduceColors(&$im,$limit, $cols)
* 1819: function reduceColors(&$im,$limit, $cols)
* 1832: function IMreduceColors($file, $cols)
* 1832: function IMreduceColors($file, $cols)
*
* SECTION: GIFBUILDER Helper functions
* SECTION: GIFBUILDER Helper functions
* 1875: function prependAbsolutePath($fontFile)
* 1875: function prependAbsolutePath($fontFile)
* 1889: function v5_sharpen($factor)
* 1889: function v5_sharpen($factor)
* 1908: function v5_blur($factor)
* 1908: function v5_blur($factor)
* 1925: function randomName()
* 1925: function randomName()
* 1938: function applyOffset($cords,$OFFSET)
* 1938: function applyOffset($cords,$OFFSET)
* 1951: function convertColor($string)
* 1951: function convertColor($string)
* 2001: function recodeString($string)
* 2001: function recodeString($string)
* 2023: function singleChars($theText,$returnUnicodeNumber=FALSE)
* 2023: function singleChars($theText,$returnUnicodeNumber=FALSE)
* 2046: function objPosition($conf,$workArea,$BB)
* 2046: function objPosition($conf,$workArea,$BB)
*
* SECTION: Scaling, Dimensions of images
* SECTION: Scaling, Dimensions of images
* 2125: function imageMagickConvert($imagefile,$newExt='',$w='',$h='',$params='',$frame='',$options='',$mustCreate=0)
* 2125: function imageMagickConvert($imagefile,$newExt='',$w='',$h='',$params='',$frame='',$options='',$mustCreate=0)
* 2238: function getImageDimensions($imageFile)
* 2238: function getImageDimensions($imageFile)
* 2266: function cacheImageDimensions($identifyResult)
* 2266: function cacheImageDimensions($identifyResult)
* 2298: function getCachedImageDimensions($imageFile)
* 2298: function getCachedImageDimensions($imageFile)
* 2332: function getImageScale($info,$w,$h,$options)
* 2332: function getImageScale($info,$w,$h,$options)
* 2438: function file_exists_typo3temp_file($output,$orig='')
* 2438: function file_exists_typo3temp_file($output,$orig='')
*
* SECTION: ImageMagick API functions
* SECTION: ImageMagick API functions
* 2499: function imageMagickIdentify($imagefile)
* 2499: function imageMagickIdentify($imagefile)
* 2534: function imageMagickExec($input,$output,$params)
* 2534: function imageMagickExec($input,$output,$params)
* 2557: function combineExec($input,$overlay,$mask,$output, $handleNegation = false)
* 2557: function combineExec($input,$overlay,$mask,$output, $handleNegation = false)
* 2588: function wrapFileName($inputName)
* 2588: function wrapFileName($inputName)
*
* SECTION: Various IO functions
* SECTION: Various IO functions
* 2629: function checkFile($file)
* 2629: function checkFile($file)
* 2643: function createTempSubDir($dirName)
* 2643: function createTempSubDir($dirName)
* 2665: function applyImageMagickToPHPGif(&$im, $command)
* 2665: function applyImageMagickToPHPGif(&$im, $command)
* 2691: function gif_or_jpg($type,$w,$h)
* 2691: function gif_or_jpg($type,$w,$h)
* 2708: function output($file)
* 2708: function output($file)
* 2748: function destroy()
* 2748: function destroy()
* 2758: function imgTag ($imgInfo)
* 2758: function imgTag ($imgInfo)
* 2770: function ImageWrite($destImg, $theImage)
* 2770: function ImageWrite($destImg, $theImage)
* 2808: function imageGif($destImg, $theImage)
* 2808: function imageGif($destImg, $theImage)
* 2820: function imageCreateFromGif($sourceImg)
* 2820: function imageCreateFromGif($sourceImg)
* 2831: function imageCreateFromFile($sourceImg)
* 2831: function imageCreateFromFile($sourceImg)
* 2870: function imagecreate($w, $h)
* 2870: function imagecreate($w, $h)
* 2885: function hexColor($col)
* 2885: function hexColor($col)
* 2903: function unifyColors(&$img, $colArr, $closest = false)
* 2903: function unifyColors(&$img, $colArr, $closest = false)
*
* 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
......
* @subpackage t3lib
* @see tslib_gifBuilder
*/
class t3lib_stdGraphic {
class t3lib_stdGraphic {
// Internal configuration, set in init()
var $combineScript = 'combine'; // The ImageMagick filename used for combining two images. This name changed during the versions.
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 $noFramePrepended = 0; // If set, there is no frame pointer prepended to the filenames.
var $GD2 = 1; // Set, if the GDlib used is version 2. @deprecated as of TYPO3 4.4, as this variables is now always set (GDlib2 always has this method, and PHP recommends to only use imagecreatetruecolor() over imagecreate())
var $GD2 = 1; // Set, if the GDlib used is version 2. @deprecated as of TYPO3 4.4, as this variables is now always set (GDlib2 always has this method, and PHP recommends to only use imagecreatetruecolor() over imagecreate())
var $imagecopyresized_fix=0; // If set, imagecopyresized will not be called directly. For GD2 (some PHP installs?)
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 $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 $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, @deprecated as of TYPO3 4.4, as this variables is now always set (GDlib2 always has this method, and PHP recommends to only use imagecreatetruecolor() over imagecreate())
var $truecolor = TRUE; // Internal variable which get's used to determine wheter GDlib should use function truecolor pendants, @deprecated as of TYPO3 4.4, as this variables is now always set (GDlib2 always has this method, and PHP recommends to only use imagecreatetruecolor() over imagecreate())
var $png_truecolor = false; // Set to true if generated png's should be truecolor by default
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 $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. Deprecated since TYPO3 3.6, will be removed in TYPO3 4.6
var $TTFLocaleConv = ''; // Used to recode input to TTF-functions for other charsets. Deprecated since TYPO3 3.6, will be removed in TYPO3 4.6
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 $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 $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 $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 $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 $maskNegate = ''; // Will be ' -negate' if ImageMagick ver 5.2+. See init();
var $NO_IM_EFFECTS = '';
var $cmds = array(
'jpg' => '',
......
var $mayScaleUp = 1;
// Variables for testing, alternative usage etc.
var $filenamePrefix=''; // Filename prefix for images scaled in imageMagickConvert()
var $filenamePrefix = ''; // Filename prefix for images scaled in imageMagickConvert()
var $imageMagickConvert_forceFileNameBody=''; // Forcing the output filename of imageMagickConvert() to this value. However after calling imageMagickConvert() it will be set blank again.
var $imageMagickConvert_forceFileNameBody = ''; // Forcing the output filename of imageMagickConvert() to this value. However after calling imageMagickConvert() it will be set blank again.
var $dontCheckForExistingTempFile = 0; // This flag should always be false. If set true, imageMagickConvert will always write a new file to the tempdir! Used for debugging.
var $dontCheckForExistingTempFile = 0; // This flag should always be false. If set true, imageMagickConvert will always write a new file to the tempdir! Used for debugging.
var $dontCompress=0; // Prevents imageMagickConvert() from compressing the gif-files with t3lib_div::gif_compress()
var $dontCompress = 0; // Prevents imageMagickConvert() from compressing the gif-files with t3lib_div::gif_compress()
var $dontUnlinkTempFiles=0; // For debugging ONLY!
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...
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();
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. Normally relative to PATH_site but is allowed to be the absolute path AS LONG AS it is a subdir 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 $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 $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_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.
var $im5fx_sharpenSteps = '1x2,2x2,3x2,2x3,3x3,4x3,3x4,4x4,4x5,5x5'; // Used by v5_sharpen() to simulate 10 continuous steps of sharpening.
var $pixelLimitGif = 10000; // This is the limit for the number of pixels in an image before it will be rendered as JPG instead of GIF/PNG
var $pixelLimitGif = 10000; // This is the limit for the number of pixels in an image before it will be rendered as JPG instead of GIF/PNG
var $colMap = Array ( // Array mapping HTML color names to RGB values.
'aqua' => Array(0,255,255),
'black' => Array(0,0,0),
'blue' => Array(0,0,255),
'fuchsia' => Array(255,0,255),
'gray' => Array(128,128,128),
'green' => Array(0,128,0),
'lime' => Array(0,255,0),
'maroon' => Array(128,0,0),
'navy' => Array(0,0,128),
'olive' => Array(128,128,0),
'purple' => Array(128,0,128),
'red' => Array(255,0,0),
'silver' => Array(192,192,192),
'teal' => Array(0,128,128),
'yellow' => Array(255,255,0),
'white' => Array(255,255,255)
var $colMap = array( // Array mapping HTML color names to RGB values.
'aqua' => array(0, 255, 255),
'black' => array(0, 0, 0),
'blue' => array(0, 0, 255),
'fuchsia' => array(255, 0, 255),
'gray' => array(128, 128, 128),
'green' => array(0, 128, 0),
'lime' => array(0, 255, 0),
'maroon' => array(128, 0, 0),
'navy' => array(0, 0, 128),
'olive' => array(128, 128, 0),
'purple' => array(128, 0, 128),
'red' => array(255, 0, 0),
'silver' => array(192, 192, 192),
'teal' => array(0, 128, 128),
'yellow' => array(255, 255, 0),
'white' => array(255, 255, 255)
);
/**
......
* @var t3lib_cs
*/
var $csConvObj;
var $nativeCharset=''; // Is set to the native character set of the input strings.
var $nativeCharset = ''; // Is set to the native character set of the input strings.
/**
* 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
*/
function init() {
function init() {
$gfxConf = $GLOBALS['TYPO3_CONF_VARS']['GFX'];
if (function_exists('imagecreatefromjpeg')&&function_exists('imagejpeg')) {
if (function_exists('imagecreatefromjpeg') && function_exists('imagejpeg')) {
$this->gdlibExtensions .= ',jpg,jpeg';
}
if (function_exists('imagecreatefrompng')&&function_exists('imagepng')) {
if (function_exists('imagecreatefrompng') && function_exists('imagepng')) {
$this->gdlibExtensions .= ',png';
}
if (function_exists('imagecreatefromgif')&&function_exists('imagegif')) {
if (function_exists('imagecreatefromgif') && function_exists('imagegif')) {
$this->gdlibExtensions .= ',gif';
}
if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['png_truecolor']) {
if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['png_truecolor']) {
$this->png_truecolor = true;
}
if (!$gfxConf['im_version_5']) {
if (!$gfxConf['im_version_5']) {
t3lib_div::deprecationLog('The option $TYPO3_CONF_VARS[\'GFX\'][\'im_version_5\'] is not set, ImageMagic 4 is assumed. This is deprecated since TYPO3 4.5, support will be removed in TYPO3 4.6. Make sure to upgrade to ImageMagick version 6 or GraphichsMagick.');
$this->im_version_4 = true;
} elseif ($gfxConf['im_version_5'] === 'im5') {
......
// 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;
$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['im_combine_filename']) {
$this->combineScript = $gfxConf['im_combine_filename'];
}
if ($gfxConf['im_noFramePrepended']) {
$this->noFramePrepended = 1;
}
// kept for backwards compatibility, can be turned on manually through localconf.php,
// but not through the installer anymore
$this->imagecopyresized_fix = ($gfxConf['gdlib_2'] === 'no_imagecopyresized_fix' ? 0 : 1);
if ($gfxConf['gdlib_png']) {
if ($gfxConf['gdlib_png']) {
$this->gifExtension='png';
$this->gifExtension = 'png';
}
if ($gfxConf['TTFLocaleConv']) {
$this->TTFLocaleConv = $gfxConf['TTFLocaleConv'];
......
$this->imageFileExt = $gfxConf['imagefile_ext'];
// This should be set if ImageMagick ver. 5+ is used.
if ($gfxConf['im_negate_mask']) {
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.
// Just set the flag if the masks works opposite the intension!
$this->maskNegate = ' -negate';
}
if ($gfxConf['im_no_effects']) {
if ($gfxConf['im_no_effects']) {
// Boolean. This is necessary if using ImageMagick 5+.
// 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'] = $this->cmds['jpeg'] = '-colorspace RGB -quality '.$this->jpegQuality;
$this->cmds['jpg'] = $this->cmds['jpeg'] = '-colorspace RGB -quality ' . $this->jpegQuality;
}
// ... but if 'im_v5effects' is set, don't care about 'im_no_effects'
if ($gfxConf['im_v5effects']) {
if ($gfxConf['im_v5effects']) {
$this->NO_IM_EFFECTS = 0;
$this->V5_EFFECTS = 1;
if ($gfxConf['im_v5effects']>0) {
if ($gfxConf['im_v5effects'] > 0) {
$this->cmds['jpg'] = $this->cmds['jpeg'] = '-colorspace RGB -quality '.intval($gfxConf['jpg_quality']).$this->v5_sharpen(10);
$this->cmds['jpg'] = $this->cmds['jpeg'] = '-colorspace RGB -quality ' . intval($gfxConf['jpg_quality']) . $this->v5_sharpen(10);
}
}
if (!$gfxConf['im']) {
if (!$gfxConf['im']) {
$this->NO_IMAGE_MAGICK = 1;
}
// Secures that images are not scaled up.
if ($gfxConf['im_noScaleUp']) {
$this->mayScaleUp=0;
$this->mayScaleUp = 0;
}
if (TYPO3_MODE=='FE') {
if (TYPO3_MODE == 'FE') {
$this->csConvObj = $GLOBALS['TSFE']->csConvObj;
} elseif(is_object($GLOBALS['LANG'])) { // BE assumed:
} 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.
} 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'];
}
/*************************************************
*
* Layering images / "IMAGE" GIFBUILDER object
......
* @return void
* @see tslib_gifBuilder::make()
*/
function maskImageOntoImage(&$im,$conf,$workArea) {
function maskImageOntoImage(&$im, $conf, $workArea) {
if ($conf['file'] && $conf['mask']) {
if ($conf['file'] && $conf['mask']) {
$imgInf = pathinfo($conf['file']);
$imgExt = strtolower($imgInf['extension']);
if (!t3lib_div::inList($this->gdlibExtensions, $imgExt)) {
if (!t3lib_div::inList($this->gdlibExtensions, $imgExt)) {
$BBimage = $this->imageMagickConvert($conf['file'],$this->gifExtension,'','','','','');
$BBimage = $this->imageMagickConvert($conf['file'], $this->gifExtension, '', '', '', '', '');
} else {
} else {
$BBimage = $this->getImageDimensions($conf['file']);
}
$maskInf = pathinfo($conf['mask']);
$maskExt = strtolower($maskInf['extension']);
if (!t3lib_div::inList($this->gdlibExtensions, $maskExt)) {
if (!t3lib_div::inList($this->gdlibExtensions, $maskExt)) {
$BBmask = $this->imageMagickConvert($conf['mask'],$this->gifExtension,'','','','','');
$BBmask = $this->imageMagickConvert($conf['mask'], $this->gifExtension, '', '', '', '', '');
} else {
} else {
$BBmask = $this->getImageDimensions($conf['mask']);
}
if ($BBimage && $BBmask) {
if ($BBimage && $BBmask) {
$w = imagesx($im);
$h = imagesy($im);
$tmpStr = $this->randomName();
$theImage = $tmpStr.'_img.'.$this->gifExtension;
$theImage = $tmpStr . '_img.' . $this->gifExtension;
$theDest = $tmpStr.'_dest.'.$this->gifExtension;
$theDest = $tmpStr . '_dest.' . $this->gifExtension;
$theMask = $tmpStr.'_mask.'.$this->gifExtension;
$theMask = $tmpStr . '_mask.' . $this->gifExtension;
// prepare overlay image
// prepare overlay image
$cpImg = $this->imageCreateFromFile($BBimage[3]);
$destImg = imagecreatetruecolor($w, $h);
$Bcolor = ImageColorAllocate($destImg, 0,0,0);
$Bcolor = ImageColorAllocate($destImg, 0, 0, 0);
ImageFilledRectangle($destImg, 0, 0, $w, $h, $Bcolor);
$this->copyGifOntoGif($destImg,$cpImg,$conf,$workArea);
$this->copyGifOntoGif($destImg, $cpImg, $conf, $workArea);
$this->ImageWrite($destImg, $theImage);
imageDestroy($cpImg);
imageDestroy($destImg);
// prepare mask image
// prepare mask image
$cpImg = $this->imageCreateFromFile($BBmask[3]);
$destImg = imagecreatetruecolor($w, $h);
$Bcolor = ImageColorAllocate($destImg, 0, 0, 0);
ImageFilledRectangle($destImg, 0, 0, $w, $h, $Bcolor);
$this->copyGifOntoGif($destImg,$cpImg,$conf,$workArea);
$this->copyGifOntoGif($destImg, $cpImg, $conf, $workArea);
$this->ImageWrite($destImg, $theMask);
imageDestroy($cpImg);
imageDestroy($destImg);
// mask the images
$this->ImageWrite($im, $theDest);
$this->combineExec($theDest,$theImage,$theMask,$theDest, true); // Let combineExec handle maskNegation
$this->combineExec($theDest, $theImage, $theMask, $theDest, TRUE); // Let combineExec handle maskNegation
$backIm = $this->imageCreateFromFile($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.
if ($backIm) { // ... and if nothing went wrong we load it onto the old one.
ImageColorTransparent($backIm,-1);
ImageColorTransparent($backIm, -1);
$im = $backIm;
}
// unlink files from process
if (!$this->dontUnlinkTempFiles) {
if (!$this->dontUnlinkTempFiles) {
unlink($theDest);
unlink($theImage);
unlink($theMask);
......
* @return void
* @see tslib_gifBuilder::make(), maskImageOntoImage()
*/
function copyImageOntoImage(&$im,$conf,$workArea) {
function copyImageOntoImage(&$im, $conf, $workArea) {
if ($conf['file']) {
if ($conf['file']) {
if (!t3lib_div::inList($this->gdlibExtensions, $conf['BBOX'][2])) {
if (!t3lib_div::inList($this->gdlibExtensions, $conf['BBOX'][2])) {
$conf['BBOX']=$this->imageMagickConvert($conf['BBOX'][3],$this->gifExtension,'','','','','');
$conf['BBOX'] = $this->imageMagickConvert($conf['BBOX'][3], $this->gifExtension, '', '', '', '', '');
$conf['file']=$conf['BBOX'][3];
$conf['file'] = $conf['BBOX'][3];
}
$cpImg = $this->imageCreateFromFile($conf['file']);
$this->copyGifOntoGif($im,$cpImg,$conf,$workArea);
$this->copyGifOntoGif($im, $cpImg, $conf, $workArea);
imageDestroy($cpImg);
}
}
......
* @return void Works on the $im image pointer
* @access private
*/
function copyGifOntoGif(&$im,$cpImg,$conf,$workArea) {
function copyGifOntoGif(&$im, $cpImg, $conf, $workArea) {
$cpW = imagesx($cpImg);
$cpH = imagesy($cpImg);
$tile = t3lib_div::intExplode(',',$conf['tile']);
$tile = t3lib_div::intExplode(',', $conf['tile']);
$tile[0] = t3lib_div::intInRange($tile[0],1,20);
$tile[0] = t3lib_div::intInRange($tile[0], 1, 20);
$tile[1] = t3lib_div::intInRange($tile[1],1,20);
$tile[1] = t3lib_div::intInRange($tile[1], 1, 20);
$cpOff = $this->objPosition($conf,$workArea,Array($cpW*$tile[0],$cpH*$tile[1]));
$cpOff = $this->objPosition($conf, $workArea, array($cpW * $tile[0], $cpH * $tile[1]));
for ($xt=0;$xt<$tile[0];$xt++) {
for ($xt = 0; $xt < $tile[0]; $xt++) {
$Xstart=$cpOff[0]+$cpW*$xt;
$Xstart = $cpOff[0] + $cpW * $xt;
if ($Xstart+$cpW > $workArea[0]) { // if this image is inside of the workArea, then go on
if ($Xstart + $cpW > $workArea[0]) { // if this image is inside of the workArea, then go on
// X:
if ($Xstart < $workArea[0]) {
if ($Xstart < $workArea[0]) {
$cpImgCutX = $workArea[0]-$Xstart;
$cpImgCutX = $workArea[0] - $Xstart;
$Xstart = $workArea[0];
} else {
$cpImgCutX = 0;
}
$w = $cpW-$cpImgCutX;
$w = $cpW - $cpImgCutX;
if ($Xstart > $workArea[0]+$workArea[2]-$w) {
if ($Xstart > $workArea[0] + $workArea[2] - $w) {
$w = $workArea[0]+$workArea[2]-$Xstart;
$w = $workArea[0] + $workArea[2] - $Xstart;
}
if ($Xstart < $workArea[0]+$workArea[2]) { // if this image is inside of the workArea, then go on
if ($Xstart < $workArea[0] + $workArea[2]) { // if this image is inside of the workArea, then go on
// Y:
for ($yt=0;$yt<$tile[1];$yt++) {
for ($yt = 0; $yt < $tile[1]; $yt++) {
$Ystart=$cpOff[1]+$cpH*$yt;
$Ystart = $cpOff[1] + $cpH * $yt;
if ($Ystart+$cpH > $workArea[1]) { // if this image is inside of the workArea, then go on
if ($Ystart + $cpH > $workArea[1]) { // if this image is inside of the workArea, then go on
if ($Ystart < $workArea[1]) {
if ($Ystart < $workArea[1]) {
$cpImgCutY = $workArea[1]-$Ystart;
$cpImgCutY = $workArea[1] - $Ystart;
$Ystart = $workArea[1];
} else {
$cpImgCutY = 0;
}
$h = $cpH-$cpImgCutY;
$h = $cpH - $cpImgCutY;
if ($Ystart > $workArea[1]+$workArea[3]-$h) {
if ($Ystart > $workArea[1] + $workArea[3] - $h) {
$h = $workArea[1]+$workArea[3]-$Ystart;
$h = $workArea[1] + $workArea[3] - $Ystart;
}
if ($Ystart < $workArea[1]+$workArea[3]) { // if this image is inside of the workArea, then go on
if ($Ystart < $workArea[1] + $workArea[3]) { // if this image is inside of the workArea, then go on
$this->imagecopyresized($im, $cpImg, $Xstart, $Ystart, $cpImgCutX, $cpImgCutY, $w, $h, $w, $h);
}
}
} // Y:
} // Y:
}
}
}
......
* 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
* 1) Create a blank TRUE-COLOR image
* 1) Create a blank TRUE-COLOR image
* 2) Copy the destination image onto that one
* 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.
* 4) ... and return the result pointer.
* 5) Reduce colors (if we do not, the result may become strange!)
* 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.
*
......
* @access private
* @see t3lib_iconWorks::imagecopyresized()
*/
function imagecopyresized(&$im, $cpImg, $Xstart, $Ystart, $cpImgCutX, $cpImgCutY, $w, $h, $w, $h) {
function imagecopyresized(&$im, $cpImg, $Xstart, $Ystart, $cpImgCutX, $cpImgCutY, $w, $h, $w, $h) {
if ($this->imagecopyresized_fix) {
if ($this->imagecopyresized_fix) {
$im_base = imagecreatetruecolor(imagesx($im), imagesy($im)); // Make true color image
$im_base = imagecreatetruecolor(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, $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!)
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
$im = $im_base; // Set pointer
if (!$this->truecolor) {
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!
$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);
......
}
/********************************
*
* Text / "TEXT" GIFBUILDER object
......
* @return void
* @see tslib_gifBuilder::make()
*/
function makeText(&$im,$conf,$workArea) {
function makeText(&$im, $conf, $workArea) {
// Spacing
list($spacing,$wordSpacing) = $this->calcWordSpacing($conf);
list($spacing, $wordSpacing) = $this->calcWordSpacing($conf);
// Position
$txtPos = $this->txtPosition($conf,$workArea,$conf['BBOX']);
$txtPos = $this->txtPosition($conf, $workArea, $conf['BBOX']);
$theText = $this->recodeString($conf['text']);
if ($conf['imgMap'] && is_array($conf['imgMap.'])) {
if ($conf['imgMap'] && is_array($conf['imgMap.'])) {
$this->addToMap($this->calcTextCordsForMap($conf['BBOX'][2],$txtPos, $conf['imgMap.']), $conf['imgMap.']);
$this->addToMap($this->calcTextCordsForMap($conf['BBOX'][2], $txtPos, $conf['imgMap.']), $conf['imgMap.']);
}
if (!$conf['hideButCreateMap']) {
if (!$conf['hideButCreateMap']) {
// Font Color:
$cols=$this->convertColor($conf['fontColor']);
$cols = $this->convertColor($conf['fontColor']);
// NiceText is calculated
if (!$conf['niceText']) {
// Font Color is reserved:
if (!$this->truecolor) {
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"
$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]);
$Fcolor = ImageColorAllocate($im, $cols[0], $cols[1], $cols[2]);
// antiAliasing is setup:
$Fcolor = ($conf['antiAlias']) ? $Fcolor : -$Fcolor;
for ($a=0; $a<$conf['iterations']; $a++) {
for ($a = 0; $a < $conf['iterations']; $a++) {
if ($spacing || $wordSpacing) { // If any kind of spacing applys, we use this function:
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, $conf['splitRendering.']);
} else {
$this->renderTTFText($im, $conf['fontSize'], $conf['angle'], $txtPos[0], $txtPos[1], $Fcolor, $conf['fontFile'], $theText, $conf['splitRendering.'], $conf);
}
}
} else { // NICETEXT::
} else { // NICETEXT::
// options anti_aliased and iterations is NOT available when doing this!!
$w = imagesx($im);
$h = imagesy($im);
$tmpStr = $this->randomName();
$fileMenu = $tmpStr.'_menuNT.'.$this->gifExtension;
$fileMenu = $tmpStr . '_menuNT.' . $this->gifExtension;
$fileColor = $tmpStr.'_colorNT.'.$this->gifExtension;
$fileColor = $tmpStr . '_colorNT.' . $this->gifExtension;
$fileMask = $tmpStr.'_maskNT.'.$this->gifExtension;
$fileMask = $tmpStr . '_maskNT.' . $this->gifExtension;
// Scalefactor
$sF = t3lib_div::intInRange($conf['niceText.']['scaleFactor'],2,5);
$sF = t3lib_div::intInRange($conf['niceText.']['scaleFactor'], 2, 5);
$newW = ceil($sF*imagesx($im));
$newW = ceil($sF * imagesx($im));
$newH = ceil($sF*imagesy($im));
$newH = ceil($sF * imagesy($im));
// Make mask
$maskImg = imagecreatetruecolor($newW, $newH);
$Bcolor = ImageColorAllocate($maskImg, 255,255,255);
$Bcolor = ImageColorAllocate($maskImg, 255, 255, 255);
ImageFilledRectangle($maskImg, 0, 0, $newW, $newH, $Bcolor);
$Fcolor = ImageColorAllocate($maskImg, 0,0,0);
$Fcolor = ImageColorAllocate($maskImg, 0, 0, 0);
if ($spacing || $wordSpacing) { // If any kind of spacing applys, we use this function:
if ($spacing || $wordSpacing) { // If any kind of spacing applys, we use this function:
$this->SpacedImageTTFText($maskImg, $conf['fontSize'], $conf['angle'], $txtPos[0], $txtPos[1], $Fcolor, t3lib_stdGraphic::prependAbsolutePath($conf['fontFile']), $theText, $spacing, $wordSpacing, $conf['splitRendering.'],$sF);
$this->SpacedImageTTFText($maskImg, $conf['fontSize'], $conf['angle'], $txtPos[0], $txtPos[1], $Fcolor, t3lib_stdGraphic::prependAbsolutePath($conf['fontFile']), $theText, $spacing, $wordSpacing, $conf['splitRendering.'], $sF);
} else {
$this->renderTTFText($maskImg, $conf['fontSize'], $conf['angle'], $txtPos[0], $txtPos[1], $Fcolor, $conf['fontFile'], $theText, $conf['splitRendering.'], $conf, $sF);
}
......
ImageDestroy($maskImg);
// Downscales the mask
if ($this->NO_IM_EFFECTS) {
if ($this->NO_IM_EFFECTS) {
if ($this->maskNegate) {
if ($this->maskNegate) {
$command = trim($this->scalecmd.' '.$w.'x'.$h.'!'); // Negate 2 times makes no negate...
$command = trim($this->scalecmd . ' ' . $w . 'x' . $h . '!'); // Negate 2 times makes no negate...
} else {
$command = trim($this->scalecmd.' '.$w.'x'.$h.'! -negate');
$command = trim($this->scalecmd . ' ' . $w . 'x' . $h . '! -negate');
}
} else {
if ($this->maskNegate) {
if ($this->maskNegate) {
$command = trim($conf['niceText.']['before'].' '.$this->scalecmd.' '.$w.'x'.$h.'! '.$conf['niceText.']['after']);
$command = trim($conf['niceText.']['before'] . ' ' . $this->scalecmd . ' ' . $w . 'x' . $h . '! ' . $conf['niceText.']['after']);
} else {
$command = trim($conf['niceText.']['before'].' '.$this->scalecmd.' '.$w.'x'.$h.'! '.$conf['niceText.']['after'].' -negate');
$command = trim($conf['niceText.']['before'] . ' ' . $this->scalecmd . ' ' . $w . 'x' . $h . '! ' . $conf['niceText.']['after'] . ' -negate');
}
if ($conf['niceText.']['sharpen']) {
if ($this->V5_EFFECTS) {
if ($this->V5_EFFECTS) {
$command.=$this->v5_sharpen($conf['niceText.']['sharpen']);
$command .= $this->v5_sharpen($conf['niceText.']['sharpen']);
} else {
$command.=' -sharpen '.t3lib_div::intInRange($conf['niceText.']['sharpen'],1,99);
$command .= ' -sharpen ' . t3lib_div::intInRange($conf['niceText.']['sharpen'], 1, 99);
}
}
}
$this->imageMagickExec($fileMask,$fileMask,$command);
$this->imageMagickExec($fileMask, $fileMask, $command);
// Make the color-file
$colorImg = imagecreatetruecolor($w, $h);
$Ccolor = ImageColorAllocate($colorImg, $cols[0],$cols[1],$cols[2]);
$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->ImageWrite($im, $fileMenu); // The main pictures is saved temporarily
$this->ImageWrite($im, $fileMenu); // The main pictures is saved temporarily
$this->combineExec($fileMenu,$fileColor,$fileMask, $fileMenu);
$this->combineExec($fileMenu, $fileColor, $fileMask, $fileMenu);
$backIm = $this->imageCreateFromFile($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.
if ($backIm) { // ... and if nothing went wrong we load it onto the old one.
ImageColorTransparent($backIm,-1);
ImageColorTransparent($backIm, -1);
$im = $backIm;
}
// Deleting temporary files;
if (!$this->dontUnlinkTempFiles) {
if (!$this->dontUnlinkTempFiles) {
unlink($fileMenu);
unlink($fileColor);
unlink($fileMask);
......
* @access private
* @see makeText()
*/
function txtPosition($conf,$workArea,$BB) {
function txtPosition($conf, $workArea, $BB) {
$bbox = $BB[2];
$angle=intval($conf['angle'])/180*pi();
$angle = intval($conf['angle']) / 180 * pi();
$conf['angle']=0;
$conf['angle'] = 0;
$straightBB = $this->calcBBox($conf);
// offset, align, valign, workarea
$result=Array(); // [0]=x, [1]=y, [2]=w, [3]=h
$result = array(); // [0]=x, [1]=y, [2]=w, [3]=h
$result[2] = $BB[0];
$result[3] = $BB[1];
$w=$workArea[2];
$w = $workArea[2];
$h=$workArea[3];
$h = $workArea[3];
switch($conf['align']) {
switch ($conf['align']) {
case 'right':
case 'center':
$factor=abs(cos($angle));
$factor = abs(cos($angle));
$sign=(cos($angle)<0)?-1:1;
$sign = (cos($angle) < 0) ? -1 : 1;
$len1 = $sign*$factor*$straightBB[0];
$len1 = $sign * $factor * $straightBB[0];
$len2= $sign*$BB[0];
$len2 = $sign * $BB[0];
$result[0] = $w-ceil($len2*$factor+(1-$factor)*$len1);
$result[0] = $w - ceil($len2 * $factor + (1 - $factor) * $len1);
$factor=abs(sin($angle));
$factor = abs(sin($angle));
$sign=(sin($angle)<0)?-1:1;
$sign = (sin($angle) < 0) ? -1 : 1;
$len1= $sign*$factor*$straightBB[0];
$len1 = $sign * $factor * $straightBB[0];
$len2= $sign*$BB[1];
$len2 = $sign * $BB[1];
$result[1]=ceil($len2*$factor+(1-$factor)*$len1);
$result[1] = ceil($len2 * $factor + (1 - $factor) * $len1);
break;
}
switch($conf['align']) {
switch ($conf['align']) {
case 'right':
break;
case 'center':
$result[0] = round(($result[0])/2);
$result[0] = round(($result[0]) / 2);
$result[1] = round(($result[1])/2);
$result[1] = round(($result[1]) / 2);
break;
default:
$result[0]=0;
$result[0] = 0;
$result[1]=0;
$result[1] = 0;
break;
}
$result = $this->applyOffset($result,t3lib_div::intExplode(',',$conf['offset']));
$result = $this->applyOffset($result, t3lib_div::intExplode(',', $conf['offset']));
$result = $this->applyOffset($result,$workArea);
$result = $this->applyOffset($result, $workArea);
return $result;
}
......
* @access private
* @see txtPosition(), tslib_gifBuilder::start()
*/
function calcBBox($conf) {
function calcBBox($conf) {
$sF = $this->getTextScalFactor($conf);
list($spacing,$wordSpacing) = $this->calcWordSpacing($conf, $sF);
list($spacing, $wordSpacing) = $this->calcWordSpacing($conf, $sF);
$theText = $this->recodeString($conf['text']);
$charInf = $this->ImageTTFBBoxWrapper($conf['fontSize'], $conf['angle'], $conf['fontFile'], $theText, $conf['splitRendering.'],$sF);
$charInf = $this->ImageTTFBBoxWrapper($conf['fontSize'], $conf['angle'], $conf['fontFile'], $theText, $conf['splitRendering.'], $sF);
$theBBoxInfo = $charInf;
if ($conf['angle']) {
if ($conf['angle']) {
$xArr = Array($charInf[0],$charInf[2],$charInf[4],$charInf[6]);
$yArr = Array($charInf[1],$charInf[3],$charInf[5],$charInf[7]);
$xArr = array($charInf[0], $charInf[2], $charInf[4], $charInf[6]);
$yArr = array($charInf[1], $charInf[3], $charInf[5], $charInf[7]);
$x=max($xArr)-min($xArr);
$x = max($xArr) - min($xArr);
$y=max($yArr)-min($yArr);
$y = max($yArr) - min($yArr);
} else {
$x = ($charInf[2]-$charInf[0]);
$x = ($charInf[2] - $charInf[0]);
$y = ($charInf[1]-$charInf[7]);
$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:
if ($spacing || $wordSpacing) { // If any kind of spacing applys, we use this function:
$x=0;
$x = 0;
if (!$spacing && $wordSpacing) {
if (!$spacing && $wordSpacing) {
$bits = explode(' ',$theText);
$bits = explode(' ', $theText);
foreach ($bits as $word) {
$word.=' ';
$word .= ' ';
$wordInf = $this->ImageTTFBBoxWrapper($conf['fontSize'], $conf['angle'], $conf['fontFile'], $word, $conf['splitRendering.'],$sF);
$wordInf = $this->ImageTTFBBoxWrapper($conf['fontSize'], $conf['angle'], $conf['fontFile'], $word, $conf['splitRendering.'], $sF);
$wordW = ($wordInf[2]-$wordInf[0]);
$wordW = ($wordInf[2] - $wordInf[0]);
$x+=$wordW+$wordSpacing;
$x += $wordW + $wordSpacing;
}
} else {
$utf8Chars = $this->singleChars($theText);
// For each UTF-8 char, do:
foreach($utf8Chars as $char) {
foreach ($utf8Chars as $char) {
$charInf = $this->ImageTTFBBoxWrapper($conf['fontSize'], $conf['angle'], $conf['fontFile'], $char, $conf['splitRendering.'],$sF);
$charInf = $this->ImageTTFBBoxWrapper($conf['fontSize'], $conf['angle'], $conf['fontFile'], $char, $conf['splitRendering.'], $sF);
$charW = ($charInf[2]-$charInf[0]);
$charW = ($charInf[2] - $charInf[0]);
$x+=$charW+(($char==' ')?$wordSpacing:$spacing);
$x += $charW + (($char == ' ') ? $wordSpacing : $spacing);
}
}
} elseif (isset($conf['breakWidth']) && $conf['breakWidth'] && $this->getRenderedTextWidth($conf['text'], $conf) > $conf['breakWidth']) {
......
foreach ($wordPairs as $index => $wordPair) {
$wordWidth = $this->getRenderedTextWidth($wordPair, $conf);
if ($index == 0 || $currentWidth + $wordWidth <= $breakWidth) {
$currentWidth+= $wordWidth;
$currentWidth += $wordWidth;
} else {
$maxWidth = max($maxWidth, $currentWidth);
$y+= $breakSpace;
$y += $breakSpace;
// Restart:
$currentWidth = $wordWidth;
}
......
if ($sF > 1) {
$x = ceil($x / $sF);
$y = ceil($y / $sF);
if (is_array($theBBoxInfo)) {
if (is_array($theBBoxInfo)) {
foreach ($theBBoxInfo as &$value) {
$value = ceil($value / $sF);
}
......
* @access private
* @see makeText(), calcTextCordsForMap()
*/
function addToMap($cords,$conf) {
function addToMap($cords, $conf) {
$JS = $conf['noBlur'] ? '' : ' onfocus="blurLink(this);"';
$this->map.='<area'.
$this->map .= '<area' .
' shape="poly"'.
' shape="poly"' .
' coords="'.implode(',',$cords).'"'.
' coords="' . implode(',', $cords) . '"' .
' href="'.htmlspecialchars($conf['url']).'"'.
' href="' . htmlspecialchars($conf['url']) . '"' .
($conf['target'] ? ' target="'.htmlspecialchars($conf['target']).'"' : '').
($conf['target'] ? ' target="' . htmlspecialchars($conf['target']) . '"' : '') .
$JS.
$JS .
(strlen($conf['titleText']) ? ' title="'.htmlspecialchars($conf['titleText']).'"' : '').
(strlen($conf['titleText']) ? ' title="' . htmlspecialchars($conf['titleText']) . '"' : '') .
' alt="'.htmlspecialchars($conf['altText']).'" />';
' alt="' . htmlspecialchars($conf['altText']) . '" />';
}
/**
......
* @access private
* @see makeText(), calcTextCordsForMap()
*/
function calcTextCordsForMap($cords,$offset, $conf) {
function calcTextCordsForMap($cords, $offset, $conf) {
$pars = t3lib_div::intExplode(',',$conf['explode'].',');
$pars = t3lib_div::intExplode(',', $conf['explode'] . ',');
$newCords[0] = $cords[0]+$offset[0]-$pars[0];
$newCords[0] = $cords[0] + $offset[0] - $pars[0];
$newCords[1] = $cords[1]+$offset[1]+$pars[1];
$newCords[1] = $cords[1] + $offset[1] + $pars[1];
$newCords[2] = $cords[2]+$offset[0]+$pars[0];
$newCords[2] = $cords[2] + $offset[0] + $pars[0];
$newCords[3] = $cords[3]+$offset[1]+$pars[1];
$newCords[3] = $cords[3] + $offset[1] + $pars[1];
$newCords[4] = $cords[4]+$offset[0]+$pars[0];
$newCords[4] = $cords[4] + $offset[0] + $pars[0];
$newCords[5] = $cords[5]+$offset[1]-$pars[1];
$newCords[5] = $cords[5] + $offset[1] - $pars[1];
$newCords[6] = $cords[6]+$offset[0]-$pars[0];
$newCords[6] = $cords[6] + $offset[0] - $pars[0];
$newCords[7] = $cords[7]+$offset[1]-$pars[1];
$newCords[7] = $cords[7] + $offset[1] - $pars[1];
return $newCords;
}
......
* @return void
* @access private
*/
function SpacedImageTTFText(&$im, $fontSize, $angle, $x, $y, $Fcolor, $fontFile, $text, $spacing, $wordSpacing, $splitRenderingConf, $sF=1) {
function SpacedImageTTFText(&$im, $fontSize, $angle, $x, $y, $Fcolor, $fontFile, $text, $spacing, $wordSpacing, $splitRenderingConf, $sF = 1) {
$spacing*=$sF;
$spacing *= $sF;
$wordSpacing*=$sF;
$wordSpacing *= $sF;
if (!$spacing && $wordSpacing) {
if (!$spacing && $wordSpacing) {
$bits = explode(' ',$text);
$bits = explode(' ', $text);
foreach ($bits as $word) {
$word.=' ';
$word .= ' ';
$wordInf = $this->ImageTTFBBoxWrapper($fontSize, $angle, $fontFile, $word, $splitRenderingConf ,$sF);
$wordInf = $this->ImageTTFBBoxWrapper($fontSize, $angle, $fontFile, $word, $splitRenderingConf, $sF);
$wordW = ($wordInf[2]-$wordInf[0]);
$wordW = ($wordInf[2] - $wordInf[0]);
$this->ImageTTFTextWrapper($im, $fontSize, $angle, $x, $y, $Fcolor, $fontFile, $word, $splitRenderingConf, $sF);
$x+=$wordW+$wordSpacing;
$x += $wordW + $wordSpacing;
}
} else {
$utf8Chars = $this->singleChars($text);
// For each UTF-8 char, do:
foreach($utf8Chars as $char) {
foreach ($utf8Chars as $char) {
$charInf = $this->ImageTTFBBoxWrapper($fontSize, $angle, $fontFile, $char, $splitRenderingConf, $sF);
$charW = ($charInf[2]-$charInf[0]);
$charW = ($charInf[2] - $charInf[0]);
$this->ImageTTFTextWrapper($im, $fontSize, $angle, $x, $y, $Fcolor, $fontFile, $char, $splitRenderingConf, $sF);
$x+=$charW+(($char==' ')?$wordSpacing:$spacing);
$x += $charW + (($char == ' ') ? $wordSpacing : $spacing);
}
}
}
......
* @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!!!!
// 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);
list($spacing, $wordSpacing) = $this->calcWordSpacing($conf);
if ($maxWidth) {
if ($maxWidth) {
if ($spacing || $wordSpacing) { // If any kind of spacing applys, we use this function:
if ($spacing || $wordSpacing) { // If any kind of spacing applys, we use this function:
return $conf['fontSize'];
// ################ no calc for spacing yet !!!!!!
// ################ no calc for spacing yet !!!!!!
} else {
do {
// determine bounding box.
$bounds = $this->ImageTTFBBoxWrapper($conf['fontSize'], $conf['angle'], $conf['fontFile'], $this->recodeString($conf['text']), $conf['splitRendering.']);
if ($conf['angle']< 0) {
if ($conf['angle'] < 0) {
$pixelWidth = abs($bounds[4]-$bounds[0]);
$pixelWidth = abs($bounds[4] - $bounds[0]);
} elseif ($conf['angle'] > 0) {
$pixelWidth = abs($bounds[2]-$bounds[6]);
$pixelWidth = abs($bounds[2] - $bounds[6]);
} else {
$pixelWidth = abs($bounds[4]-$bounds[6]);
$pixelWidth = abs($bounds[4] - $bounds[6]);
}
// Size is fine, exit:
if ($pixelWidth <= $maxWidth) {
if ($pixelWidth <= $maxWidth) {
break;
} else {
$conf['fontSize']--;
}
} while ($conf['fontSize']>1);
} while ($conf['fontSize'] > 1);
}//if spacing
}
}
//if spacing
}
return $conf['fontSize'];
}
......
* @param integer Scale factor
* @return array Information array.
*/
function ImageTTFBBoxWrapper($fontSize, $angle, $fontFile, $string, $splitRendering, $sF=1) {
function ImageTTFBBoxWrapper($fontSize, $angle, $fontFile, $string, $splitRendering, $sF = 1) {
// Initialize:
$offsetInfo = array();
$stringParts = $this->splitString($string,$splitRendering,$fontSize,$fontFile);
$stringParts = $this->splitString($string, $splitRendering, $fontSize, $fontFile);
// Traverse string parts:
foreach($stringParts as $strCfg) {
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']);
$calc = ImageTTFBBox(t3lib_div::freetypeDpiComp($sF * $strCfg['fontSize']), $angle, $fontFile, $strCfg['str']);
// Calculate offsets:
if (!count($offsetInfo)) {
if (!count($offsetInfo)) {
$offsetInfo = $calc; // First run, just copy over.
$offsetInfo = $calc; // First run, just copy over.
} else {
$offsetInfo[2]+=$calc[2]-$calc[0]+intval($splitRendering['compX'])+intval($strCfg['xSpaceBefore'])+intval($strCfg['xSpaceAfter']);
$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[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[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']);
$offsetInfo[5] += $calc[5] - $calc[7] - intval($splitRendering['compY']) - intval($strCfg['ySpaceBefore']) - intval($strCfg['ySpaceAfter']);
}
} else {
debug('cannot read file: '.$fontFile, 't3lib_stdGraphic::ImageTTFBBoxWrapper()');
debug('cannot read file: ' . $fontFile, 't3lib_stdGraphic::ImageTTFBBoxWrapper()');
}
}
......
* @param integer Scale factor
* @return void
*/
function ImageTTFTextWrapper($im, $fontSize, $angle, $x, $y, $color, $fontFile, $string, $splitRendering,$sF=1) {
function ImageTTFTextWrapper($im, $fontSize, $angle, $x, $y, $color, $fontFile, $string, $splitRendering, $sF = 1) {
// Initialize:
$stringParts = $this->splitString($string,$splitRendering,$fontSize,$fontFile);
$stringParts = $this->splitString($string, $splitRendering, $fontSize, $fontFile);
$x = ceil($sF*$x);
$x = ceil($sF * $x);
$y = ceil($sF*$y);
$y = ceil($sF * $y);
// Traverse string parts:
foreach($stringParts as $i => $strCfg) {
foreach ($stringParts as $i => $strCfg) {
// Initialize:
$colorIndex = $color;
// Set custom color if any (only when niceText is off):
if ($strCfg['color'] && $sF==1) {
if ($strCfg['color'] && $sF == 1) {
$cols = $this->convertColor($strCfg['color']);
$colorIndex = ImageColorAllocate($im, $cols[0],$cols[1],$cols[2]);
$colorIndex = ImageColorAllocate($im, $cols[0], $cols[1], $cols[2]);
$colorIndex = $color >= 0 ? $colorIndex : -$colorIndex;
}
// Setting xSpaceBefore
if ($i) {
if ($i) {
$x+= intval($strCfg['xSpaceBefore']);
$x += intval($strCfg['xSpaceBefore']);
$y-= intval($strCfg['ySpaceBefore']);
$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']);
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']);
$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']);
$x += $wordInf[2] - $wordInf[0] + intval($splitRendering['compX']) + intval($strCfg['xSpaceAfter']);
$y+= $wordInf[5]-$wordInf[7]-intval($splitRendering['compY'])-intval($strCfg['ySpaceAfter']);
$y += $wordInf[5] - $wordInf[7] - intval($splitRendering['compY']) - intval($strCfg['ySpaceAfter']);
} else {
debug('cannot read file: '.$fontFile, 't3lib_stdGraphic::ImageTTFTextWrapper()');
debug('cannot read file: ' . $fontFile, 't3lib_stdGraphic::ImageTTFTextWrapper()');
}
}
......
* @param string Current font file
* @return array Array with input string splitted according to configuration
*/
function splitString($string,$splitRendering,$fontSize,$fontFile) {
function splitString($string, $splitRendering, $fontSize, $fontFile) {
// Initialize by setting the whole string and default configuration as the first entry.
$result = array();
......
// Traverse the split-rendering configuration:
// Splitting will create more entries in $result with individual configurations.
if (is_array($splitRendering)) {
if (is_array($splitRendering)) {
$sKeyArray = t3lib_TStemplate::sortedKeyList($splitRendering);
// Traverse configured options:
foreach($sKeyArray as $key) {
foreach ($sKeyArray as $key) {
$cfg = $splitRendering[$key.'.'];
$cfg = $splitRendering[$key . '.'];
// Process each type of split rendering keyword:
switch((string)$splitRendering[$key]) {
switch ((string) $splitRendering[$key]) {
case 'highlightWord':
if (strlen($cfg['value'])) {
if (strlen($cfg['value'])) {
$newResult = array();
// Traverse the current parts of the result array:
foreach($result as $part) {
foreach ($result as $part) {
// Explode the string value by the word value to highlight:
$explodedParts = explode($cfg['value'],$part['str']);
$explodedParts = explode($cfg['value'], $part['str']);
foreach($explodedParts as $c => $expValue) {
foreach ($explodedParts as $c => $expValue) {
if (strlen($expValue)) {
if (strlen($expValue)) {
$newResult[] = array_merge($part,array('str' => $expValue));
$newResult[] = array_merge($part, array('str' => $expValue));
}
if ($c+1 < count($explodedParts)) {
if ($c + 1 < count($explodedParts)) {
$newResult[] = array(
'str' => $cfg['value'],
'fontSize' => $cfg['fontSize'] ? $cfg['fontSize'] : $part['fontSize'],
......
}
// Set the new result as result array:
if (count($newResult)) {
if (count($newResult)) {
$result = $newResult;
}
}
break;
case 'charRange':
if (strlen($cfg['value'])) {
if (strlen($cfg['value'])) {
// Initialize range:
$ranges = t3lib_div::trimExplode(',',$cfg['value'],1);
$ranges = t3lib_div::trimExplode(',', $cfg['value'], 1);
foreach($ranges as $i => $rangeDef) {
foreach ($ranges as $i => $rangeDef) {
$ranges[$i] = t3lib_div::intExplode('-',$ranges[$i]);
$ranges[$i] = t3lib_div::intExplode('-', $ranges[$i]);
if (!isset($ranges[$i][1])) $ranges[$i][1] = $ranges[$i][0];
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) {
foreach ($result as $part) {
// Initialize:
$currentState = -1;
......
// Explode the string value by the word value to highlight:
$utf8Chars = $this->singleChars($part['str']);
foreach($utf8Chars as $utfChar) {
foreach ($utf8Chars as $utfChar) {
// Find number and evaluate position:
$uNumber = $this->csConvObj->utf8CharToUnumber($utfChar);
$inRange = 0;
foreach($ranges as $rangeDef) {
foreach ($ranges as $rangeDef) {
if ($uNumber >= $rangeDef[0] && (!$rangeDef[1] || $uNumber <= $rangeDef[1])) {
$inRange = 1;
break;
}
}
if ($currentState==-1) $currentState = $inRange; // Initialize first char
if ($currentState == -1) {
$currentState = $inRange;
} // Initialize first char
// Switch bank:
if ($inRange != $currentState && !t3lib_div::inList('32,10,13,9',$uNumber)) {
if ($inRange != $currentState && !t3lib_div::inList('32,10,13,9', $uNumber)) {
// Set result:
if (strlen($bankAccum)) {
if (strlen($bankAccum)) {
$newResult[] = array(
'str' => $bankAccum,
'fontSize' => $currentState && $cfg['fontSize'] ? $cfg['fontSize'] : $part['fontSize'],
......
}
// Add char to bank:
$bankAccum.=$utfChar;
$bankAccum .= $utfChar;
}
// Set result for FINAL part:
if (strlen($bankAccum)) {
if (strlen($bankAccum)) {
$newResult[] = array(
'str' => $bankAccum,
'fontSize' => $currentState && $cfg['fontSize'] ? $cfg['fontSize'] : $part['fontSize'],
......
}
// Set the new result as result array:
if (count($newResult)) {
if (count($newResult)) {
$result = $newResult;
}
}
......
* @access private
* @see calcBBox()
*/
function calcWordSpacing($conf, $scaleFactor=1) {
function calcWordSpacing($conf, $scaleFactor = 1) {
$spacing = intval($conf['spacing']);
$wordSpacing = intval($conf['wordSpacing']);
$wordSpacing = $wordSpacing?$wordSpacing:$spacing*2;
$wordSpacing = $wordSpacing ? $wordSpacing : $spacing * 2;
$spacing*=$scaleFactor;
$spacing *= $scaleFactor;
$wordSpacing*=$scaleFactor;
$wordSpacing *= $scaleFactor;
return array($spacing,$wordSpacing);
return array($spacing, $wordSpacing);
}
/**
......
function getTextScalFactor($conf) {
if (!$conf['niceText']) {
$sF = 1;
} else { // NICETEXT::
} else { // NICETEXT::
$sF = t3lib_div::intInRange($conf['niceText.']['scaleFactor'],2,5);
$sF = t3lib_div::intInRange($conf['niceText.']['scaleFactor'], 2, 5);
}
return $sF;
}
......
foreach ($wordPairs as $index => $wordPair) {
$wordWidth = $this->getRenderedTextWidth($wordPair, $conf);
if ($index == 0 || $currentWidth + $wordWidth <= $breakWidth) {
$currentWidth+= $wordWidth;
$currentWidth += $wordWidth;
$phrase.= $wordPair;
$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;
$y += $breakSpace;
// Restart the phrase:
$currentWidth = $wordWidth;
$phrase = $wordPair;
......
protected function getWordPairsForLineBreak($string) {
$wordPairs = array();
$wordsArray = preg_split('#([- .,!:]+)#', $string, -1, PREG_SPLIT_DELIM_CAPTURE);
$wordsArray = preg_split('#([- .,!:]+)#', $string, -1, PREG_SPLIT_DELIM_CAPTURE);
... This diff was truncated because it exceeds the maximum size that can be displayed.
(56-56/93)