From d6ed2191d7deae02a2c345ef585adcf93397d224 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20S=CC=8Ckoda?=
Date: Sun, 2 Sep 2012 15:58:25 +0200
Subject: [PATCH] MDL-35188 import tcpdf 5.9.181
---
lib/tcpdf/2dbarcodes.php | 12 +-
lib/tcpdf/CHANGELOG.TXT | 97 +++-
lib/tcpdf/README.TXT | 6 +-
lib/tcpdf/barcodes.php | 12 +-
lib/tcpdf/composer.json | 38 ++
lib/tcpdf/config/tcpdf_config.php | 0
lib/tcpdf/qrcode.php | 22 +-
lib/tcpdf/readme_moodle.txt | 4 +-
lib/tcpdf/tcpdf.php | 734 +++++++++++++++++++++++-------
lib/tcpdf/tcpdf_parser.php | 35 +-
lib/thirdpartylibs.xml | 2 +-
11 files changed, 747 insertions(+), 215 deletions(-)
create mode 100644 lib/tcpdf/composer.json
mode change 100644 => 100755 lib/tcpdf/config/tcpdf_config.php
diff --git a/lib/tcpdf/2dbarcodes.php b/lib/tcpdf/2dbarcodes.php
index e04b3073ce1..6490dfa7eaf 100644
--- a/lib/tcpdf/2dbarcodes.php
+++ b/lib/tcpdf/2dbarcodes.php
@@ -1,9 +1,9 @@
barcode_array['bcode'][$r][$c] == 1) {
// draw a single barcode cell
if ($imagick) {
- $bar->rectangle($x, $y, ($x + $w), ($y + $h));
+ $bar->rectangle($x, $y, ($x + $w - 1), ($y + $h - 1));
} else {
- imagefilledrectangle($png, $x, $y, ($x + $w), ($y + $h), $fgcol);
+ imagefilledrectangle($png, $x, $y, ($x + $w - 1), ($y + $h - 1), $fgcol);
}
}
$x += $w;
diff --git a/lib/tcpdf/CHANGELOG.TXT b/lib/tcpdf/CHANGELOG.TXT
index 23a14f9991d..3b87c8c356d 100644
--- a/lib/tcpdf/CHANGELOG.TXT
+++ b/lib/tcpdf/CHANGELOG.TXT
@@ -1,3 +1,98 @@
+5.9.181 (2012-08-31)
+ - composer.json file was added.
+ - Bug item #3563369 "Cached images are not unlinked some time" was fixed.
+
+5.9.180 (2012-08-22)
+ - Bug item #3560493 "Problems with nested cells in HTML" was fixed.
+
+5.9.179 (2012-08-04)
+ - SVG 'use' tag was fixed for 'circle' and 'ellipse' shift problem.
+ - Alpha status is now correctly stored and restored by getGraphicVars() and SetGraphicVars() methods.
+
+5.9.178 (2012-08-02)
+ - SVG 'use' tag was fixed for 'circle' and 'ellipse'.
+
+5.9.177 (2012-08-02)
+ - An additional control on annotations was fixed.
+
+5.9.176 (2012-07-25)
+ - A bug related to stroke width was fixed.
+ - A problem related to font spacing in HTML was fixed.
+
+5.9.175 (2012-07-25)
+ - The problem of missing letter on hyphen break was fixed.
+
+5.9.174 (2012-07-25)
+ - The problem of wrong filename when downloading PDF from an Android device was fixed.
+ - The method setHeaderData() was extended to set text and line color for header (see example n. 1).
+ - The method setFooterData() was added to set text and line color for footer (see example n. 1).
+ - The methods setTextShadow() and getTextShadow() were added to set text shadows (see example n. 1).
+ - The GetCharWidth() method was fixed for negative character spacing.
+ - A 'none' border mode is now correctly recognized.
+ - Break on hyphen problem was fixed.
+
+5.9.173 (2012-07-23)
+ - Some additional control wher added on barcode methods.
+ - The option CURLOPT_FOLLOWLOCATION on Image method is now disabled if PHP safe_mode is on or open_basedir is set.
+ - Method Bookmark() was extended to include X parameter.
+ - Method setDestination() was extended to include X parameter.
+ - A problem with Thai language was fixed.
+
+5.9.172 (2012-07-02)
+ - A PNG color profile issue was fixed.
+
+5.9.171 (2012-07-01)
+ - Some SVG rendering problems were fixed.
+
+5.9.170 (2012-06-27)
+ - Bug #3538227 "Numerous errors inserting shared images" was fixed.
+
+5.9.169 (2012-06-25)
+ - Some SVG rendering problems were fixed.
+
+5.9.168 (2012-06-22)
+ - Thai language rendering was fixed.
+
+5.9.167 (2012-06-22)
+ - Thai language rendering was fixed and improved.
+ - Method isCharDefined() was improved.
+ - Protected method replaceChar() was added.
+ - Font "kerning" word was corrected to "tracking".
+
+5.9.166 (2012-06-21)
+ - Array to string conversion on file_id creation was fixed.
+ - Thai language rendering was fixed (thanks to Atsawin Chaowanakritsanakul).
+
+5.9.165 (2012-06-07)
+ - Some HTML form related bugs were fixed.
+
+5.9.164 (2012-06-06)
+ - A bug introduced on the latest release was fixed.
+
+5.9.163 (2012-06-05)
+ - Method getGDgamma() was changed.
+ - Rendering performances of PNG images with alpha channel were improved.
+
+5.9.162 (2012-05-11)
+ - A bug related to long text on TD cells was fixed.
+
+5.9.161 (2012-05-09)
+ - A bug on XREF table was fixed (Bug ID: 3525051).
+ - Deprecated Imagick:clone was replaced.
+ - Method objclone() was fixed for PHP4.
+
+5.9.160 (2012-05-03)
+ - A bug on tcpdf_parser.php was fixed.
+
+5.9.159 (2012-04-30)
+ - Barcode classes were updated to fix PNG export Bug (ID: 3522291).
+
+5.9.158 (2012-04-22)
+ - Some SVG-related bugs were fixed.
+
+5.9.157 (2012-04-16)
+ - Some SVG-related bugs were fixed.
+
5.9.156 (2012-04-10)
- Bug item #3515885 "TOC and booklet: left and right page exchanged".
- SetAutoPageBreak(false) now works also in multicolumn mode.
@@ -567,7 +662,7 @@
- The problem of blank page for nobr table higher than a single page was fixed.
5.9.000 (2010-10-06)
- - Support for text stretching and spacing (kerning) was added, see example n. 63 and methods setFontStretching(), getFontStretching(), setFontSpacing(), getFontSpacing().
+ - Support for text stretching and spacing (tracking) was added, see example n. 63 and methods setFontStretching(), getFontStretching(), setFontSpacing(), getFontSpacing().
- Support for CSS properties 'font-stretch' and 'letter-spacing' was added (see example n. 63).
- The cMargin state was replaced by cell_padding array that can be set/get using setCellPadding() and getCellPadding() methods.
- Methods getCellPaddings() and setCellPaddings() were added to fine tune cell paddings (see example n. 5).
diff --git a/lib/tcpdf/README.TXT b/lib/tcpdf/README.TXT
index 83520bb1272..1d0fc015deb 100644
--- a/lib/tcpdf/README.TXT
+++ b/lib/tcpdf/README.TXT
@@ -8,8 +8,8 @@ http://sourceforge.net/donate/index.php?group_id=128076
------------------------------------------------------------
Name: TCPDF
-Version: 5.9.156
-Release date: 2012-04-10
+Version: 5.9.181
+Release date: 2012-08-31
Author: Nicola Asuni
Copyright (c) 2002-2012:
@@ -47,7 +47,7 @@ Main Features:
* no-write page regions;
* bookmarks, named destinations and table of content;
* text hyphenation;
- * text stretching and spacing (tracking/kerning);
+ * text stretching and spacing (tracking);
* automatic page break, line break and text alignments including justification;
* automatic page numbering and page groups;
* move and delete pages;
diff --git a/lib/tcpdf/barcodes.php b/lib/tcpdf/barcodes.php
index 4027aa7109a..c6c0172e4a3 100644
--- a/lib/tcpdf/barcodes.php
+++ b/lib/tcpdf/barcodes.php
@@ -1,9 +1,9 @@
* @package com.tecnick.tcpdf
- * @version 1.0.023
+ * @version 1.0.024
* @author Nicola Asuni
*/
class TCPDFBarcode {
@@ -201,9 +201,9 @@ class TCPDFBarcode {
$y = round(($v['p'] * $h / $this->barcode_array['maxh']), 3);
// draw a vertical bar
if ($imagick) {
- $bar->rectangle($x, $y, ($x + $bw), ($y + $bh));
+ $bar->rectangle($x, $y, ($x + $bw - 1), ($y + $bh - 1));
} else {
- imagefilledrectangle($png, $x, $y, ($x + $bw), ($y + $bh), $fgcol);
+ imagefilledrectangle($png, $x, $y, ($x + $bw - 1), ($y + $bh - 1), $fgcol);
}
}
$x += $bw;
diff --git a/lib/tcpdf/composer.json b/lib/tcpdf/composer.json
new file mode 100644
index 00000000000..4cbb538103d
--- /dev/null
+++ b/lib/tcpdf/composer.json
@@ -0,0 +1,38 @@
+{
+ "name": "tcpdf/tcpdf",
+ "version": "5.9.181",
+ "homepage": "http://www.tcpdf.org/",
+ "type": "library",
+ "description": "TCPDF is a PHP class for generating PDF files on-the-fly without requiring external extensions.",
+ "keywords": ["pdf"],
+ "license": "LGPLv3",
+ "authors": [
+ {
+ "name": "Nicola Asuni",
+ "email": "info@tecnick.com",
+ "homepage": "http://nicolaasuni.tecnick.com"
+ }
+ ],
+ "require": {
+ "php": ">5.2"
+ },
+ "autoload": {
+ "classmap": [
+ "fonts",
+ "config/lang",
+ "config",
+ "2dbarcodes.php",
+ "barcodes.php",
+ "datamatrix.php",
+ "encodings_maps.php",
+ "htmlcolors.php",
+ "pdf417.php",
+ "qrcode.php",
+ "spotcolors.php",
+ "tcpdf.php",
+ "tcpdf_filters.php",
+ "tcpdf_parser.php",
+ "unicode_data.php"
+ ]
+ }
+}
diff --git a/lib/tcpdf/config/tcpdf_config.php b/lib/tcpdf/config/tcpdf_config.php
old mode 100644
new mode 100755
diff --git a/lib/tcpdf/qrcode.php b/lib/tcpdf/qrcode.php
index 1fab6b58a77..93b05cbe0a2 100644
--- a/lib/tcpdf/qrcode.php
+++ b/lib/tcpdf/qrcode.php
@@ -1,9 +1,9 @@
dataStr) > 0) {
- if ($this->dataStr == '') {
- return 0;
- }
$mode = $this->identifyMode(0);
switch ($mode) {
case QR_MODE_NM: {
@@ -1476,6 +1474,7 @@ class QRcode {
}
$this->dataStr = substr($this->dataStr, $length);
}
+ return 0;
}
/**
@@ -2028,7 +2027,7 @@ class QRcode {
if ($ver > $this->version) {
$this->version = $ver;
}
- for (;;) {
+ while (true) {
$cbs = $this->createBitStream($items);
$items = $cbs[0];
$bits = $cbs[1];
@@ -2315,17 +2314,18 @@ class QRcode {
/**
* Return a version number that satisfies the input code length.
- * @param $size (int) input code length (byte)
+ * @param $size (int) input code length (bytes)
* @param $level (int) error correction level
* @return int version number
*/
protected function getMinimumVersion($size, $level) {
- for ($i=1; $i <= QRSPEC_VERSION_MAX; ++$i) {
- $words = $this->capacity[$i][QRCAP_WORDS] - $this->capacity[$i][QRCAP_EC][$level];
+ for ($i = 1; $i <= QRSPEC_VERSION_MAX; ++$i) {
+ $words = ($this->capacity[$i][QRCAP_WORDS] - $this->capacity[$i][QRCAP_EC][$level]);
if ($words >= $size) {
return $i;
}
}
+ // the size of input data is greater than QR capacity, try to lover the error correction mode
return -1;
}
diff --git a/lib/tcpdf/readme_moodle.txt b/lib/tcpdf/readme_moodle.txt
index 1b6d92480dd..e953af35e22 100644
--- a/lib/tcpdf/readme_moodle.txt
+++ b/lib/tcpdf/readme_moodle.txt
@@ -1,5 +1,5 @@
-Description of TCPDF library import 5.9.156
-===================================
+Description of TCPDF library import 5.9.181
+===========================================
* delete cache/ doc/ examples/ config/tcpdf_config_alt.php config/lang/ images/
* remove all fonts but the core ones (courier.php, helveticabi.php,
helveticab.php, helveticai.php, helvetica.php, symbol.php, timesbi.php,
diff --git a/lib/tcpdf/tcpdf.php b/lib/tcpdf/tcpdf.php
index 7c18096a52a..c5109bf4a68 100644
--- a/lib/tcpdf/tcpdf.php
+++ b/lib/tcpdf/tcpdf.php
@@ -1,9 +1,9 @@
no-write page regions;
* bookmarks, named destinations and table of content;
* text hyphenation;
- * text stretching and spacing (tracking/kerning);
+ * text stretching and spacing (tracking);
* automatic page break, line break and text alignments including justification;
* automatic page numbering and page groups;
* move and delete pages;
@@ -137,7 +138,7 @@
* Tools to encode your unicode fonts are on fonts/utils directory.
* @package com.tecnick.tcpdf
* @author Nicola Asuni
- * @version 5.9.156
+ * @version 5.9.181
*/
// Main configuration file. Define the K_TCPDF_EXTERNAL_CONFIG constant to skip this file.
@@ -149,7 +150,7 @@ require_once(dirname(__FILE__).'/config/tcpdf_config.php');
* TCPDF project (http://www.tcpdf.org) has been originally derived in 2002 from the Public Domain FPDF class by Olivier Plathey (http://www.fpdf.org), but now is almost entirely rewritten.
* @package com.tecnick.tcpdf
* @brief PHP class for generating PDF documents without requiring external extensions.
- * @version 5.9.156
+ * @version 5.9.181
* @author Nicola Asuni - info@tecnick.com
*/
class TCPDF {
@@ -160,7 +161,7 @@ class TCPDF {
* Current TCPDF version.
* @private
*/
- private $tcpdf_version = '5.9.156';
+ private $tcpdf_version = '5.9.181';
// Protected properties
@@ -180,7 +181,13 @@ class TCPDF {
* Array of object offsets.
* @protected
*/
- protected $offsets;
+ protected $offsets = array();
+
+ /**
+ * Array of object IDs for each page.
+ * @protected
+ */
+ protected $pageobjects = array();
/**
* Buffer holding in-memory PDF.
@@ -352,6 +359,12 @@ class TCPDF {
*/
protected $images = array();
+ /**
+ * Array of cached files.
+ * @protected
+ */
+ protected $cached_files = array();
+
/**
* Array of Annotations in pages.
* @protected
@@ -705,6 +718,41 @@ class TCPDF {
*/
protected $header_string = '';
+ /**
+ * Color for header text (RGB array).
+ * @since 5.9.174 (2012-07-25)
+ * @protected
+ */
+ protected $header_text_color = array(0,0,0);
+
+ /**
+ * Color for header line (RGB array).
+ * @since 5.9.174 (2012-07-25)
+ * @protected
+ */
+ protected $header_line_color = array(0,0,0);
+
+ /**
+ * Color for footer text (RGB array).
+ * @since 5.9.174 (2012-07-25)
+ * @protected
+ */
+ protected $footer_text_color = array(0,0,0);
+
+ /**
+ * Color for footer line (RGB array).
+ * @since 5.9.174 (2012-07-25)
+ * @protected
+ */
+ protected $footer_line_color = array(0,0,0);
+
+ /**
+ * Text shadow data array.
+ * @since 5.9.174 (2012-07-25)
+ * @protected
+ */
+ protected $txtshadow = array('enabled'=>false, 'depth_w'=>0, 'depth_h'=>0, 'color'=>false, 'opacity'=>1, 'blend_mode'=>'Normal');
+
/**
* Default number of columns for html table.
* @protected
@@ -1590,7 +1638,7 @@ class TCPDF {
protected $font_stretching = 100;
/**
- * Increases or decreases the space between characters in a text by the specified amount (tracking/kerning).
+ * Increases or decreases the space between characters in a text by the specified amount (tracking).
* @protected
* @since 5.9.000 (2010-09-29)
*/
@@ -1873,6 +1921,13 @@ class TCPDF {
*/
protected $tcpdflink = true;
+ /**
+ * Cache array for computed GD gamma values.
+ * @protected
+ * @since 5.9.1632 (2012-06-05)
+ */
+ protected $gdgammacache = array();
+
//------------------------------------------------------------
// METHODS
//------------------------------------------------------------
@@ -2006,6 +2061,7 @@ class TCPDF {
$this->strokecolor = array('R' => 0, 'G' => 0, 'B' => 0);
$this->bgcolor = array('R' => 255, 'G' => 255, 'B' => 255);
$this->extgstates = array();
+ $this->setTextShadow();
// user's rights
$this->sign = false;
$this->ur['enabled'] = false;
@@ -2037,7 +2093,8 @@ class TCPDF {
}
$this->default_form_prop = array('lineWidth'=>1, 'borderStyle'=>'solid', 'fillColor'=>array(255, 255, 255), 'strokeColor'=>array(128, 128, 128));
// set file ID for trailer
- $this->file_id = md5($this->getRandomSeed('TCPDF'.$orientation.$unit.$format.$encoding));
+ $serformat = (is_array($format) ? serialize($format) : $format);
+ $this->file_id = md5($this->getRandomSeed('TCPDF'.$orientation.$unit.$serformat.$encoding));
// set document creation and modification timestamp
$this->doc_creation_timestamp = time();
$this->doc_modification_timestamp = $this->doc_creation_timestamp;
@@ -3059,8 +3116,8 @@ class TCPDF {
// swap X and Y coordinates (change page orientation)
$this->swapPageBoxCoordinates($this->page);
}
- $this->w = $this->wPt / $this->k;
- $this->h = $this->hPt / $this->k;
+ $this->w = ($this->wPt / $this->k);
+ $this->h = ($this->hPt / $this->k);
if ($this->empty_string($autopagebreak)) {
if (isset($this->AutoPageBreak)) {
$autopagebreak = $this->AutoPageBreak;
@@ -4083,13 +4140,28 @@ class TCPDF {
* @param $lw (string) header image logo width in mm
* @param $ht (string) string to print as title on document header
* @param $hs (string) string to print on document header
+ * @param $tc (array) RGB array color for text.
+ * @param $lc (array) RGB array color for line.
* @public
*/
- public function setHeaderData($ln='', $lw=0, $ht='', $hs='') {
+ public function setHeaderData($ln='', $lw=0, $ht='', $hs='', $tc=array(0,0,0), $lc=array(0,0,0)) {
$this->header_logo = $ln;
$this->header_logo_width = $lw;
$this->header_title = $ht;
$this->header_string = $hs;
+ $this->header_text_color = $tc;
+ $this->header_line_color = $lc;
+ }
+
+ /**
+ * Set footer data.
+ * @param $tc (array) RGB array color for text.
+ * @param $lc (array) RGB array color for line.
+ * @public
+ */
+ public function setFooterData($tc=array(0,0,0), $lc=array(0,0,0)) {
+ $this->footer_text_color = $tc;
+ $this->footer_line_color = $lc;
}
/**
@@ -4105,6 +4177,8 @@ class TCPDF {
$ret['logo_width'] = $this->header_logo_width;
$ret['title'] = $this->header_title;
$ret['string'] = $this->header_string;
+ $ret['text_color'] = $this->header_text_color;
+ $ret['line_color'] = $this->header_line_color;
return $ret;
}
@@ -4238,7 +4312,7 @@ class TCPDF {
$header_x = $this->original_lMargin + ($headerdata['logo_width'] * 1.1);
}
$cw = $this->w - $this->original_lMargin - $this->original_rMargin - ($headerdata['logo_width'] * 1.1);
- $this->SetTextColor(0, 0, 0);
+ $this->SetTextColorArray($this->header_text_color);
// header title
$this->SetFont($headerfont[0], 'B', $headerfont[2] + 1);
$this->SetX($header_x);
@@ -4248,7 +4322,7 @@ class TCPDF {
$this->SetX($header_x);
$this->MultiCell($cw, $cell_height, $headerdata['string'], 0, '', 0, 1, '', '', true, 0, false, true, 0, 'T', false);
// print an ending header line
- $this->SetLineStyle(array('width' => 0.85 / $this->k, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => array(0, 0, 0)));
+ $this->SetLineStyle(array('width' => 0.85 / $this->k, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => $headerdata['line_color']));
$this->SetY((2.835 / $this->k) + max($imgy, $this->y));
if ($this->rtl) {
$this->SetX($this->original_rMargin);
@@ -4284,10 +4358,10 @@ class TCPDF {
*/
public function Footer() {
$cur_y = $this->y;
- $this->SetTextColor(0, 0, 0);
+ $this->SetTextColorArray($this->footer_text_color);
//set style for cell border
- $line_width = 0.85 / $this->k;
- $this->SetLineStyle(array('width' => $line_width, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => array(0, 0, 0)));
+ $line_width = (0.85 / $this->k);
+ $this->SetLineStyle(array('width' => $line_width, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => $this->footer_line_color));
//print document barcode
$barcode = $this->getBarcode();
if (!empty($barcode)) {
@@ -4919,9 +4993,9 @@ class TCPDF {
}
/**
- * Returns the length of the char in user unit for the current font considering current stretching and spacing (tracking/kerning).
+ * Returns the length of the char in user unit for the current font considering current stretching and spacing (tracking).
* @param $char (int) The char code whose length is to be returned
- * @param $notlast (boolean) set to false for the latest character on string, true otherwise (default)
+ * @param $notlast (boolean) If false ignore the font-spacing.
* @return float char width
* @author Nicola Asuni
* @public
@@ -4930,7 +5004,7 @@ class TCPDF {
public function GetCharWidth($char, $notlast=true) {
// get raw width
$chw = $this->getRawCharWidth($char);
- if (($this->font_spacing != 0) AND $notlast) {
+ if (($this->font_spacing < 0) OR (($this->font_spacing > 0) AND $notlast)) {
// increase/decrease font spacing
$chw += $this->font_spacing;
}
@@ -5400,7 +5474,7 @@ class TCPDF {
}
/**
- * Return the font ascent value
+ * Return the font ascent value.
* @param $font (string) font name
* @param $style (string) font style
* @param $size (float) The size (in points)
@@ -5421,7 +5495,7 @@ class TCPDF {
}
/**
- * Return the font descent value
+ * Return true in the character is present in the specified font.
* @param $char (mixed) Character to check (integer value or string)
* @param $font (string) Font name (family name).
* @param $style (string) Font style.
@@ -5436,6 +5510,9 @@ class TCPDF {
$char = $char[0];
}
if ($this->empty_string($font)) {
+ if ($this->empty_string($style)) {
+ return (isset($this->CurrentFont['cw'][intval($char)]));
+ }
$font = $this->FontFamily;
}
$fontdata = $this->AddFont($font, $style);
@@ -5828,6 +5905,35 @@ class TCPDF {
}
}
$this->checkPageBreak($h + $this->cell_margin['T'] + $this->cell_margin['B']);
+ // apply text shadow if enabled
+ if ($this->txtshadow['enabled']) {
+ // save data
+ $x = $this->x;
+ $y = $this->y;
+ $bc = $this->bgcolor;
+ $fc = $this->fgcolor;
+ $sc = $this->strokecolor;
+ $alpha = $this->alpha;
+ // print shadow
+ $this->x += $this->txtshadow['depth_w'];
+ $this->y += $this->txtshadow['depth_h'];
+ $this->SetFillColorArray($this->txtshadow['color']);
+ $this->SetTextColorArray($this->txtshadow['color']);
+ $this->SetDrawColorArray($this->txtshadow['color']);
+ if ($this->txtshadow['opacity'] != $alpha['CA']) {
+ $this->setAlpha($this->txtshadow['opacity'], $this->txtshadow['blend_mode']);
+ }
+ $this->_out($this->getCellCode($w, $h, $txt, $border, $ln, $align, $fill, $link, $stretch, true, $calign, $valign));
+ //restore data
+ $this->x = $x;
+ $this->y = $y;
+ $this->SetFillColorArray($bc);
+ $this->SetTextColorArray($fc);
+ $this->SetDrawColorArray($sc);
+ if ($this->txtshadow['opacity'] != $alpha['CA']) {
+ $this->setAlpha($alpha['CA'], $alpha['BM'], $alpha['ca'], $alpha['AIS']);
+ }
+ }
$this->_out($this->getCellCode($w, $h, $txt, $border, $ln, $align, $fill, $link, $stretch, true, $calign, $valign));
$this->cell_padding = $prev_cell_padding;
$this->cell_margin = $prev_cell_margin;
@@ -6023,34 +6129,97 @@ class TCPDF {
} else {
$unicode = $this->UTF8StringToArray($txt); // array of UTF-8 unicode values
$unicode = $this->utf8Bidi($unicode, '', $this->tmprtl);
+ // replace thai chars (if any)
if (defined('K_THAI_TOPCHARS') AND (K_THAI_TOPCHARS == true)) {
- // ---- Fix for bug #2977340 "Incorrect Thai characters position arrangement" ----
- // NOTE: this doesn't work with HTML justification
- // Symbols that could overlap on the font top (only works in LTR)
- $topchar = array(3611, 3613, 3615, 3650, 3651, 3652); // chars that extends on top
- $topsym = array(3633, 3636, 3637, 3638, 3639, 3655, 3656, 3657, 3658, 3659, 3660, 3661, 3662); // symbols with top position
- $numchars = count($unicode); // number of chars
- $unik = 0;
- $uniblock = array();
- $uniblock[$unik] = array();
- $uniblock[$unik][] = $unicode[0];
- // resolve overlapping conflicts by splitting the string in several parts
- for ($i = 1; $i < $numchars; ++$i) {
- // check if symbols overlaps at top
- if (in_array($unicode[$i], $topsym) AND (in_array($unicode[($i - 1)], $topsym) OR in_array($unicode[($i - 1)], $topchar))) {
- // move symbols to another array
- ++$unik;
- $uniblock[$unik] = array();
- $uniblock[$unik][] = $unicode[$i];
- ++$unik;
- $uniblock[$unik] = array();
- $unicode[$i] = 0x200b; // Unicode Character 'ZERO WIDTH SPACE' (DEC:8203, U+200B)
+ // number of chars
+ $numchars = count($unicode);
+ // po pla, for far, for fan
+ $longtail = array(0x0e1b, 0x0e1d, 0x0e1f);
+ // do chada, to patak
+ $lowtail = array(0x0e0e, 0x0e0f);
+ // mai hun arkad, sara i, sara ii, sara ue, sara uee
+ $upvowel = array(0x0e31, 0x0e34, 0x0e35, 0x0e36, 0x0e37);
+ // mai ek, mai tho, mai tri, mai chattawa, karan
+ $tonemark = array(0x0e48, 0x0e49, 0x0e4a, 0x0e4b, 0x0e4c);
+ // sara u, sara uu, pinthu
+ $lowvowel = array(0x0e38, 0x0e39, 0x0e3a);
+ $output = array();
+ for ($i = 0; $i < $numchars; $i++) {
+ if (($unicode[$i] >= 0x0e00) && ($unicode[$i] <= 0x0e5b)) {
+ $ch0 = $unicode[$i];
+ $ch1 = ($i > 0) ? $unicode[($i - 1)] : 0;
+ $ch2 = ($i > 1) ? $unicode[($i - 2)] : 0;
+ $chn = ($i < ($numchars - 1)) ? $unicode[($i + 1)] : 0;
+ if (in_array($ch0, $tonemark)) {
+ if ($chn == 0x0e33) {
+ // sara um
+ if (in_array($ch1, $longtail)) {
+ // tonemark at upper left
+ $output[] = $this->replaceChar($ch0, (0xf713 + $ch0 - 0x0e48));
+ } else {
+ // tonemark at upper right (normal position)
+ $output[] = $ch0;
+ }
+ } elseif (in_array($ch1, $longtail) OR (in_array($ch2, $longtail) AND in_array($ch1, $lowvowel))) {
+ // tonemark at lower left
+ $output[] = $this->replaceChar($ch0, (0xf705 + $ch0 - 0x0e48));
+ } elseif (in_array($ch1, $upvowel)) {
+ if (in_array($ch2, $longtail)) {
+ // tonemark at upper left
+ $output[] = $this->replaceChar($ch0, (0xf713 + $ch0 - 0x0e48));
+ } else {
+ // tonemark at upper right (normal position)
+ $output[] = $ch0;
+ }
+ } else {
+ // tonemark at lower right
+ $output[] = $this->replaceChar($ch0, (0xf70a + $ch0 - 0x0e48));
+ }
+ } elseif (($ch0 == 0x0e33) AND (in_array($ch1, $longtail) OR (in_array($ch2, $longtail) AND in_array($ch1, $tonemark)))) {
+ // add lower left nikhahit and sara aa
+ if ($this->isCharDefined(0xf711) AND $this->isCharDefined(0x0e32)) {
+ $output[] = 0xf711;
+ $this->CurrentFont['subsetchars'][0xf711] = true;
+ $output[] = 0x0e32;
+ $this->CurrentFont['subsetchars'][0x0e32] = true;
+ } else {
+ $output[] = $ch0;
+ }
+ } elseif (in_array($ch1, $longtail)) {
+ if ($ch0 == 0x0e31) {
+ // lower left mai hun arkad
+ $output[] = $this->replaceChar($ch0, 0xf710);
+ } elseif (in_array($ch0, $upvowel)) {
+ // lower left
+ $output[] = $this->replaceChar($ch0, (0xf701 + $ch0 - 0x0e34));
+ } elseif ($ch0 == 0x0e47) {
+ // lower left mai tai koo
+ $output[] = $this->replaceChar($ch0, 0xf712);
+ } else {
+ // normal character
+ $output[] = $ch0;
+ }
+ } elseif (in_array($ch1, $lowtail) AND in_array($ch0, $lowvowel)) {
+ // lower vowel
+ $output[] = $this->replaceChar($ch0, (0xf718 + $ch0 - 0x0e38));
+ } elseif (($ch0 == 0x0e0d) AND in_array($chn, $lowvowel)) {
+ // yo ying without lower part
+ $output[] = $this->replaceChar($ch0, 0xf70f);
+ } elseif (($ch0 == 0x0e10) AND in_array($chn, $lowvowel)) {
+ // tho santan without lower part
+ $output[] = $this->replaceChar($ch0, 0xf700);
+ } else {
+ $output[] = $ch0;
+ }
} else {
- $uniblock[$unik][] = $unicode[$i];
+ // non-thai character
+ $output[] = $unicode[$i];
}
}
- // ---- END OF Fix for bug #2977340
- }
+ $unicode = $output;
+ // update font subsetchars
+ $this->setFontSubBuffer($this->CurrentFont['fontkey'], 'subsetchars', $this->CurrentFont['subsetchars']);
+ } // end of K_THAI_TOPCHARS
$txt2 = $this->arrUTF8ToUTF16BE($unicode, false);
}
}
@@ -6094,7 +6263,7 @@ class TCPDF {
$s .= 'q '.$this->TextColor.' ';
}
// rendering mode
- $s .= sprintf('BT %d Tr %F w ET ', $this->textrendermode, $this->textstrokewidth);
+ $s .= sprintf('BT %d Tr %F w ET ', $this->textrendermode, ($this->textstrokewidth * $this->k));
// count number of spaces
$ns = substr_count($txt, chr(32));
// Justification
@@ -6250,6 +6419,25 @@ class TCPDF {
return $rs;
}
+ /**
+ * Replace a char if is defined on the current font.
+ * @param $oldchar (int) Integer code (unicode) of the character to replace.
+ * @param $newchar (int) Integer code (unicode) of the new character.
+ * @return int the replaced char or the old char in case the new char i not defined
+ * @protected
+ * @since 5.9.167 (2012-06-22)
+ */
+ protected function replaceChar($oldchar, $newchar) {
+ if ($this->isCharDefined($newchar)) {
+ // add the new char on the subset list
+ $this->CurrentFont['subsetchars'][$newchar] = true;
+ // return the new character
+ return $newchar;
+ }
+ // return the old char
+ return $oldchar;
+ }
+
/**
* Returns the code to draw the cell border
* @param $x (float) X coordinate.
@@ -7069,7 +7257,7 @@ class TCPDF {
$w = $this->w - $this->rMargin - $this->x;
}
// max column width
- $wmax = $w - $wadj;
+ $wmax = ($w - $wadj);
if (!$firstline) {
$wmax -= ($this->cell_padding['L'] + $this->cell_padding['R']);
}
@@ -7155,18 +7343,27 @@ class TCPDF {
$this->rMargin += $margin['R'];
}
$w = $this->getRemainingWidth();
- $wmax = $w - $this->cell_padding['L'] - $this->cell_padding['R'];
+ $wmax = ($w - $this->cell_padding['L'] - $this->cell_padding['R']);
} else {
// 160 is the non-breaking space.
// 173 is SHY (Soft Hypen).
// \p{Z} or \p{Separator}: any kind of Unicode whitespace or invisible separator.
// \p{Lo} or \p{Other_Letter}: a Unicode letter or ideograph that does not have lowercase and uppercase variants.
// \p{Lo} is needed because Chinese characters are packed next to each other without spaces in between.
- if (($c != 160) AND (($c == 173) OR preg_match($this->re_spaces, $this->unichr($c)))) {
+ if (($c != 160)
+ AND (($c == 173)
+ OR preg_match($this->re_spaces, $this->unichr($c))
+ OR (($c == 45)
+ AND ($i < ($nb - 1))
+ AND @preg_match('/[\p{L}]/'.$this->re_space['m'], $this->unichr($pc))
+ AND @preg_match('/[\p{L}]/'.$this->re_space['m'], $this->unichr($chars[($i + 1)]))
+ )
+ )
+ ) {
// update last blank space position
$sep = $i;
// check if is a SHY
- if ($c == 173) {
+ if (($c == 173) OR ($c == 45)) {
$shy = true;
if ($pc == 45) {
$tmp_shy_replacement_width = 0;
@@ -7191,8 +7388,8 @@ class TCPDF {
// we have reached the end of column
if ($sep == -1) {
// check if the line was already started
- if (($this->rtl AND ($this->x <= ($this->w - $this->rMargin - $chrwidth)))
- OR ((!$this->rtl) AND ($this->x >= ($this->lMargin + $chrwidth)))) {
+ if (($this->rtl AND ($this->x <= ($this->w - $this->rMargin - $this->cell_padding['R'] - $margin['R'] - $chrwidth)))
+ OR ((!$this->rtl) AND ($this->x >= ($this->lMargin + $this->cell_padding['L'] + $margin['L'] + $chrwidth)))) {
// print a void cell and go to next line
$this->Cell($w, $h, '', 0, 1);
$linebreak = true;
@@ -7255,9 +7452,9 @@ class TCPDF {
$linew = $this->GetArrStringWidth($tmparr);
unset($tmparr);
if ($this->rtl) {
- $this->endlinex = $startx - $linew;
+ $this->endlinex = ($startx - $linew);
} else {
- $this->endlinex = $startx + $linew;
+ $this->endlinex = ($startx + $linew);
}
$w = $linew;
$tmpcellpadding = $this->cell_padding;
@@ -7320,6 +7517,9 @@ class TCPDF {
$this->Cell($w, $h, $shy_char_left.$tmpstr.$shy_char_right, 0, 1, $align, $fill, $link, $stretch);
unset($tmpstr);
if ($firstline) {
+ if ($chars[$sep] == 45) {
+ $endspace += 1;
+ }
// return the remaining text
$this->cell_padding = $tmpcellpadding;
return ($this->UniArrSubString($uchars, ($sep + $endspace)));
@@ -7327,7 +7527,7 @@ class TCPDF {
$i = $sep;
$sep = -1;
$shy = false;
- $j = ($i+1);
+ $j = ($i + 1);
}
}
// account for margin changes
@@ -7655,22 +7855,21 @@ class TCPDF {
}
// check page for no-write regions and adapt page margins if necessary
list($x, $y) = $this->checkPageRegions($h, $x, $y);
- $cached_file = false; // true when the file is cached
$exurl = ''; // external streams
// check if we are passing an image as file or string
if ($file[0] === '@') {
// image from string
$imgdata = substr($file, 1);
- $file = K_PATH_CACHE.'img_'.md5($imgdata);
+ $file = $this->getObjFilename('img');
$fp = fopen($file, 'w');
fwrite($fp, $imgdata);
fclose($fp);
unset($imgdata);
- $cached_file = true;
$imsize = @getimagesize($file);
if ($imsize === FALSE) {
unlink($file);
- $cached_file = false;
+ } else {
+ $this->cached_files[] = $file;
}
} else { // image file
if ($file{0} === '*') {
@@ -7697,7 +7896,9 @@ class TCPDF {
curl_setopt($cs, CURLOPT_BINARYTRANSFER, true);
curl_setopt($cs, CURLOPT_FAILONERROR, true);
curl_setopt($cs, CURLOPT_RETURNTRANSFER, true);
- curl_setopt($cs, CURLOPT_FOLLOWLOCATION, true);
+ if ((ini_get('open_basedir') == '') AND (ini_get('safe_mode') == 'Off')) {
+ curl_setopt($cs, CURLOPT_FOLLOWLOCATION, true);
+ }
curl_setopt($cs, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($cs, CURLOPT_TIMEOUT, 30);
curl_setopt($cs, CURLOPT_SSL_VERIFYPEER, false);
@@ -7707,16 +7908,16 @@ class TCPDF {
curl_close($cs);
if ($imgdata !== FALSE) {
// copy image to cache
- $file = K_PATH_CACHE.'img_'.md5($imgdata);
+ $file = $this->getObjFilename('img');
$fp = fopen($file, 'w');
fwrite($fp, $imgdata);
fclose($fp);
unset($imgdata);
- $cached_file = true;
$imsize = @getimagesize($file);
if ($imsize === FALSE) {
unlink($file);
- $cached_file = false;
+ } else {
+ $this->cached_files[] = $file;
}
}
} elseif (($w > 0) AND ($h > 0)) {
@@ -7738,7 +7939,7 @@ class TCPDF {
}
}
// file hash
- $filehash = md5($file);
+ $filehash = md5($this->file_id.$file);
// get original image width and height in pixels
list($pixw, $pixh) = $imsize;
// calculate image width and height on document
@@ -7976,10 +8177,6 @@ class TCPDF {
// add image to document
$this->setImageBuffer($file, $info);
}
- if ($cached_file) {
- // remove cached file
- unlink($file);
- }
// set alignment
$this->img_rb_y = $y + $h;
// set alignment
@@ -8320,11 +8517,13 @@ class TCPDF {
$data .= $this->rfread($f, $n);
fread($f, 4);
} elseif ($type == 'iCCP') {
- // skip profile name and null separator
+ // skip profile name
$len = 0;
while ((ord(fread($f, 1)) > 0) AND ($len < 80)) {
++$len;
}
+ // skip null separator
+ fread($f, 1);
// get compression method
if (ord(fread($f, 1)) != 0) {
//$this->Error('Unknown filter method: '.$file);
@@ -8396,7 +8595,7 @@ class TCPDF {
*/
protected function ImagePngAlpha($file, $x, $y, $wpx, $hpx, $w, $h, $type, $link, $align, $resize, $dpi, $palign, $filehash='') {
if (empty($filehash)) {
- $filehash = md5($file);
+ $filehash = md5($this->file_id.$file);
}
// create temp image file (without alpha channel)
$tempfile_plain = K_PATH_CACHE.'mskp_'.$filehash;
@@ -8407,7 +8606,7 @@ class TCPDF {
$img = new Imagick();
$img->readImage($file);
// clone image object
- $imga = $img->clone();
+ $imga = $this->objclone($img);
// extract alpha channel
$img->separateImageChannel(8); // 8 = (imagick::CHANNEL_ALPHA | imagick::CHANNEL_OPACITY | imagick::CHANNEL_MATTE);
$img->negateImage(true);
@@ -8429,9 +8628,7 @@ class TCPDF {
for ($xpx = 0; $xpx < $wpx; ++$xpx) {
for ($ypx = 0; $ypx < $hpx; ++$ypx) {
$color = imagecolorat($img, $xpx, $ypx);
- $alpha = ($color >> 24); // shifts off the first 24 bits (where 8x3 are used for each color), and returns the remaining 7 allocated bits (commonly used for alpha)
- $alpha = (((127 - $alpha) / 127) * 255); // GD alpha is only 7 bit (0 -> 127)
- $alpha = $this->getGDgamma($alpha); // correct gamma
+ $alpha = $this->getGDgamma($color); // correct gamma
imagesetpixel($imgalpha, $xpx, $ypx, $alpha);
}
}
@@ -8455,13 +8652,27 @@ class TCPDF {
}
/**
- * Correct the gamma value to be used with GD library
- * @param $v (float) the gamma value to be corrected
+ * Get the GD-corrected PNG gamma value from alpha color
+ * @param $c (int) alpha color
* @protected
* @since 4.3.007 (2008-12-04)
*/
- protected function getGDgamma($v) {
- return (pow(($v / 255), 2.2) * 255);
+ protected function getGDgamma($c) {
+ if (!isset($this->gdgammacache["'".$c."'"])) {
+ // shifts off the first 24 bits (where 8x3 are used for each color),
+ // and returns the remaining 7 allocated bits (commonly used for alpha)
+ $alpha = ($c >> 24);
+ // GD alpha is only 7 bit (0 -> 127)
+ $alpha = (((127 - $alpha) / 127) * 255);
+ // correct gamma
+ $this->gdgammacache["'".$c."'"] = (pow(($alpha / 255), 2.2) * 255);
+ // store the latest values on cache to improve performances
+ if (count($this->gdgammacache) > 8) {
+ // remove one element from the cache array
+ array_shift($this->gdgammacache);
+ }
+ }
+ return $this->gdgammacache["'".$c."'"];
}
/**
@@ -8736,7 +8947,7 @@ class TCPDF {
header('Pragma: public');
header('Expires: Sat, 26 Jul 1997 05:00:00 GMT'); // Date in the past
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
- header('Content-Disposition: inline; filename="'.basename($name).'";');
+ header('Content-Disposition: inline; filename="'.basename($name).'"');
$this->sendOutputData($this->getBuffer(), $this->bufferlen);
} else {
echo $this->getBuffer();
@@ -8767,7 +8978,7 @@ class TCPDF {
header('Content-Type: application/pdf');
}
// use the Content-Disposition header to supply a recommended filename
- header('Content-Disposition: attachment; filename="'.basename($name).'";');
+ header('Content-Disposition: attachment; filename="'.basename($name).'"');
header('Content-Transfer-Encoding: binary');
$this->sendOutputData($this->getBuffer(), $this->bufferlen);
break;
@@ -8794,7 +9005,7 @@ class TCPDF {
header('Pragma: public');
header('Expires: Sat, 26 Jul 1997 05:00:00 GMT'); // Date in the past
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
- header('Content-Disposition: inline; filename="'.basename($name).'";');
+ header('Content-Disposition: inline; filename="'.basename($name).'"');
$this->sendOutputData(file_get_contents($name), filesize($name));
} elseif ($dest == 'FD') {
// send headers to browser
@@ -8819,7 +9030,7 @@ class TCPDF {
header('Content-Type: application/pdf');
}
// use the Content-Disposition header to supply a recommended filename
- header('Content-Disposition: attachment; filename="'.basename($name).'";');
+ header('Content-Disposition: attachment; filename="'.basename($name).'"');
header('Content-Transfer-Encoding: binary');
$this->sendOutputData(file_get_contents($name), filesize($name));
}
@@ -8865,6 +9076,7 @@ class TCPDF {
AND ($val != 'bufferlen')
AND ($val != 'buffer')
AND ($val != 'diskcache')
+ AND ($val != 'cached_files')
AND ($val != 'sign')
AND ($val != 'signature_data')
AND ($val != 'signature_max_length')
@@ -8875,6 +9087,15 @@ class TCPDF {
}
}
}
+ if (isset($this->cached_files) AND !empty($this->cached_files)) {
+ // remove cached files
+ foreach ($this->cached_files as $cachefile) {
+ if (is_file($cachefile)) {
+ unlink($cachefile);
+ }
+ }
+ unset($this->cached_files);
+ }
}
/**
@@ -9430,7 +9651,7 @@ class TCPDF {
if (isset($pl['opt']['be']) AND (is_array($pl['opt']['be']))) {
$annots .= ' /BE <<';
$bstyles = array('S', 'C');
- if (isset($pl['opt']['be']['s']) AND in_array($pl['opt']['be']['s'], $markups)) {
+ if (isset($pl['opt']['be']['s']) AND in_array($pl['opt']['be']['s'], $bstyles)) {
$annots .= ' /S /'.$pl['opt']['bs']['s'];
} else {
$annots .= ' /S /S';
@@ -9509,9 +9730,11 @@ class TCPDF {
$annots .= ' /A <_datastring($this->unhtmlentities($pl['txt']), $annot_obj_id).'>>';
} else {
// internal link
- $l = $this->links[$pl['txt']];
- if (isset($this->page_obj_id[($l[0])])) {
- $annots .= sprintf(' /Dest [%u 0 R /XYZ 0 %F null]', $this->page_obj_id[($l[0])], ($this->pagedim[$l[0]]['h'] - ($l[1] * $this->k)));
+ if (isset($this->links[$pl['txt']])) {
+ $l = $this->links[$pl['txt']];
+ if (isset($this->page_obj_id[($l[0])])) {
+ $annots .= sprintf(' /Dest [%u 0 R /XYZ 0 %F null]', $this->page_obj_id[($l[0])], ($this->pagedim[$l[0]]['h'] - ($l[1] * $this->k)));
+ }
}
}
$hmodes = array('N', 'I', 'O', 'P');
@@ -12855,11 +13078,14 @@ class TCPDF {
$this->_out('xref');
$this->_out('0 '.($this->n + 1));
$this->_out('0000000000 65535 f ');
+ $freegen = ($this->n + 2);
for ($i=1; $i <= $this->n; ++$i) {
if (!isset($this->offsets[$i]) AND ($i > 1)) {
- $this->offsets[$i] = $this->offsets[($i - 1)];
+ $this->_out(sprintf('0000000000 %05d f ', $freegen));
+ ++$freegen;
+ } else {
+ $this->_out(sprintf('%010d 00000 n ', $this->offsets[$i]));
}
- $this->_out(sprintf('%010d 00000 n ', $this->offsets[$i]));
}
// TRAILER
$out = 'trailer'."\n";
@@ -12899,6 +13125,7 @@ class TCPDF {
*/
protected function _beginpage($orientation='', $format='') {
++$this->page;
+ $this->pageobjects[$this->page] = array();
$this->setPageBuffer($this->page, '');
// initialize array for graphics tranformation positions inside a page buffer
$this->transfmrk[$this->page] = array();
@@ -12967,6 +13194,7 @@ class TCPDF {
$objid = $this->n;
}
$this->offsets[$objid] = $this->bufferlen;
+ $this->pageobjects[$this->page][] = $objid;
return $objid.' 0 obj';
}
@@ -15012,7 +15240,7 @@ class TCPDF {
* @since 2.1.000 (2008-01-08)
*/
protected function _outPoint($x, $y) {
- $this->_out(sprintf('%F %F m', $x * $this->k, ($this->h - $y) * $this->k));
+ $this->_out(sprintf('%F %F m', ($x * $this->k), (($this->h - $y) * $this->k)));
}
/**
@@ -15024,7 +15252,7 @@ class TCPDF {
* @since 2.1.000 (2008-01-08)
*/
protected function _outLine($x, $y) {
- $this->_out(sprintf('%F %F l', $x * $this->k, ($this->h - $y) * $this->k));
+ $this->_out(sprintf('%F %F l', ($x * $this->k), (($this->h - $y) * $this->k)));
}
/**
@@ -16404,12 +16632,13 @@ class TCPDF {
* @param $name (string) Destination name.
* @param $y (float) Y position in user units of the destiantion on the selected page (default = -1 = current position; 0 = page start;).
* @param $page (int) Target page number (leave empty for current page).
+ * @param $x (float) X position in user units of the destiantion on the selected page (default = -1 = current position;).
* @return (string) Stripped named destination identifier or false in case of error.
* @public
* @author Christian Deligant, Nicola Asuni
* @since 5.9.097 (2011-06-23)
*/
- public function setDestination($name, $y=-1, $page='') {
+ public function setDestination($name, $y=-1, $page='', $x=-1) {
// remove unsupported characters
$name = $this->encodeNameObject($name);
if ($this->empty_string($name)) {
@@ -16417,6 +16646,17 @@ class TCPDF {
}
if ($y == -1) {
$y = $this->GetY();
+ } elseif ($y < 0) {
+ $y = 0;
+ } elseif ($y > $this->h) {
+ $y = $this->h;
+ }
+ if ($x == -1) {
+ $x = $this->GetX();
+ } elseif ($x < 0) {
+ $x = 0;
+ } elseif ($x > $this->w) {
+ $x = $this->w;
}
if (empty($page)) {
$page = $this->PageNo();
@@ -16424,7 +16664,7 @@ class TCPDF {
return;
}
}
- $this->dests[$name] = array('y' => $y, 'p' => $page);
+ $this->dests[$name] = array('x' => $x, 'y' => $y, 'p' => $page);
return $name;
}
@@ -16452,7 +16692,7 @@ class TCPDF {
$this->n_dests = $this->_newobj();
$out = ' <<';
foreach($this->dests as $name => $o) {
- $out .= ' /'.$name.' '.sprintf('[%u 0 R /XYZ 0 %F null]', $this->page_obj_id[($o['p'])], ($this->pagedim[$o['p']]['h'] - ($o['y'] * $this->k)));
+ $out .= ' /'.$name.' '.sprintf('[%u 0 R /XYZ %F %F null]', $this->page_obj_id[($o['p'])], ($o['x'] * $this->k), ($this->pagedim[$o['p']]['h'] - ($o['y'] * $this->k)));
}
$out .= ' >>';
$out .= "\n".'endobj';
@@ -16481,11 +16721,12 @@ class TCPDF {
* @param $page (int) Target page number (leave empty for current page).
* @param $style (string) Font style: B = Bold, I = Italic, BI = Bold + Italic.
* @param $color (array) RGB color array (values from 0 to 255).
+ * @param $x (float) X position in user units of the bookmark on the selected page (default = -1 = current position;).
* @public
* @author Olivier Plathey, Nicola Asuni
* @since 2.1.002 (2008-02-12)
*/
- public function Bookmark($txt, $level=0, $y=-1, $page='', $style='', $color=array(0,0,0)) {
+ public function Bookmark($txt, $level=0, $y=-1, $page='', $style='', $color=array(0,0,0), $x=-1) {
if ($level < 0) {
$level = 0;
}
@@ -16500,6 +16741,17 @@ class TCPDF {
}
if ($y == -1) {
$y = $this->GetY();
+ } elseif ($y < 0) {
+ $y = 0;
+ } elseif ($y > $this->h) {
+ $y = $this->h;
+ }
+ if ($x == -1) {
+ $x = $this->GetX();
+ } elseif ($x < 0) {
+ $x = 0;
+ } elseif ($x > $this->w) {
+ $x = $this->w;
}
if (empty($page)) {
$page = $this->PageNo();
@@ -16507,7 +16759,7 @@ class TCPDF {
return;
}
}
- $this->outlines[] = array('t' => $txt, 'l' => $level, 'y' => $y, 'p' => $page, 's' => strtoupper($style), 'c' => $color);
+ $this->outlines[] = array('t' => $txt, 'l' => $level, 'x' => $x, 'y' => $y, 'p' => $page, 's' => strtoupper($style), 'c' => $color);
}
/**
@@ -16590,7 +16842,7 @@ class TCPDF {
$out .= ' /Last '.($n + $o['last']).' 0 R';
}
if (isset($this->page_obj_id[($o['p'])])) {
- $out .= ' '.sprintf('/Dest [%u 0 R /XYZ 0 %F null]', $this->page_obj_id[($o['p'])], ($this->pagedim[$o['p']]['h'] - ($o['y'] * $this->k)));
+ $out .= ' '.sprintf('/Dest [%u 0 R /XYZ %F %F null]', $this->page_obj_id[($o['p'])], ($o['x'] * $this->k), ($this->pagedim[$o['p']]['h'] - ($o['y'] * $this->k)));
}
// set font style
$style = 0;
@@ -19169,7 +19421,7 @@ class TCPDF {
*/
public function PieSectorXY($xc, $yc, $rx, $ry, $a, $b, $style='FD', $cw=false, $o=0, $nc=2) {
if ($this->rtl) {
- $xc = $this->w - $xc;
+ $xc = ($this->w - $xc);
}
$op = $this->getPathPaintOperator($style);
if ($op == 'f') {
@@ -19177,8 +19429,8 @@ class TCPDF {
}
if ($cw) {
$d = $b;
- $b = 360 - $a + $o;
- $a = 360 - $d + $o;
+ $b = (360 - $a + $o);
+ $a = (360 - $d + $o);
} else {
$b += $o;
$a += $o;
@@ -19578,7 +19830,7 @@ class TCPDF {
// create new barcode object
$barcodeobj = new TCPDFBarcode($code, $type);
$arrcode = $barcodeobj->getBarcodeArray();
- if ($arrcode === false) {
+ if (($arrcode === false) OR empty($arrcode) OR ($arrcode['maxw'] == 0)) {
$this->Error('Error in 1D barcode string');
}
// set default values
@@ -19949,7 +20201,7 @@ class TCPDF {
// create new barcode object
$barcodeobj = new TCPDF2DBarcode($code, $type);
$arrcode = $barcodeobj->getBarcodeArray();
- if (($arrcode === false) OR empty($arrcode)) {
+ if (($arrcode === false) OR empty($arrcode) OR !isset($arrcode['num_rows']) OR ($arrcode['num_rows'] == 0) OR !isset($arrcode['num_cols']) OR ($arrcode['num_cols'] == 0)) {
$this->Error('Error in 2D barcode string');
}
// set default values
@@ -20004,6 +20256,9 @@ class TCPDF {
// module width and height
$mw = $style['module_width'];
$mh = $style['module_height'];
+ if (($mw == 0) OR ($mh == 0)) {
+ $this->Error('Error in 2D barcode string');
+ }
// get max dimensions
if ($this->rtl) {
$maxw = $x - $this->lMargin;
@@ -20886,7 +21141,7 @@ class TCPDF {
/**
* Returns the letter-spacing value from CSS value
* @param $spacing (string) letter-spacing value
- * @param $parent (float) font spacing (tracking/kerning) value of the parent element
+ * @param $parent (float) font spacing (tracking) value of the parent element
* @return float quantity to increases or decreases the space between characters in a text.
* @protected
* @since 5.9.000 (2010-10-02)
@@ -21499,7 +21754,7 @@ class TCPDF {
}
if (isset($dom[$key]['style']['border-style'])) {
$brd_styles = preg_split('/[\s]+/', trim($dom[$key]['style']['border-style']));
- if (isset($brd_styles[3])) {
+ if (isset($brd_styles[3]) AND ($brd_styles[3]!='none')) {
$dom[$key]['border']['L']['cap'] = 'square';
$dom[$key]['border']['L']['join'] = 'miter';
$dom[$key]['border']['L']['dash'] = $this->getCSSBorderDashStyle($brd_styles[3]);
@@ -21834,7 +22089,7 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
$curfontascent = $this->getFontAscent($curfontname, $curfontstyle, $curfontsize);
$curfontdescent = $this->getFontDescent($curfontname, $curfontstyle, $curfontsize);
$curfontstretcing = $this->font_stretching;
- $curfontkerning = $this->font_spacing;
+ $curfonttracking = $this->font_spacing;
$this->newline = true;
$newline = true;
$startlinepage = $this->page;
@@ -21973,7 +22228,7 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
$this_method_vars['curfontascent'] = $curfontascent;
$this_method_vars['curfontdescent'] = $curfontdescent;
$this_method_vars['curfontstretcing'] = $curfontstretcing;
- $this_method_vars['curfontkerning'] = $curfontkerning;
+ $this_method_vars['curfonttracking'] = $curfonttracking;
$this_method_vars['minstartliney'] = $minstartliney;
$this_method_vars['maxbottomliney'] = $maxbottomliney;
$this_method_vars['yshift'] = $yshift;
@@ -23051,9 +23306,9 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
} else {
$wadj = 0; // space to leave for block continuity
if ($this->rtl) {
- $cwa = $this->x - $this->lMargin;
+ $cwa = ($this->x - $this->lMargin);
} else {
- $cwa = $this->w - $this->rMargin - $this->x;
+ $cwa = ($this->w - $this->rMargin - $this->x);
}
if (($strlinelen < $cwa) AND (isset($dom[($key + 1)])) AND ($dom[($key + 1)]['tag']) AND (!$dom[($key + 1)]['block'])) {
// check the next text blocks for continuity
@@ -23143,6 +23398,14 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
}
} else {
$loop = 0;
+ // add the positive font spacing of the last character (if any)
+ if ($this->font_spacing > 0) {
+ if ($this->rtl) {
+ $this->x -= $this->font_spacing;
+ } else {
+ $this->x += $this->font_spacing;
+ }
+ }
}
}
++$key;
@@ -23740,7 +24003,7 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
$value = $tag['attribute']['value'];
}
if (isset($tag['attribute']['maxlength']) AND !$this->empty_string($tag['attribute']['maxlength'])) {
- $opt['maxlen'] = intval($tag['attribute']['value']);
+ $opt['maxlen'] = intval($tag['attribute']['maxlength']);
}
$h = $this->FontSize * $this->cell_height_ratio;
if (isset($tag['attribute']['size']) AND !$this->empty_string($tag['attribute']['size'])) {
@@ -23786,14 +24049,23 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
break;
}
case 'checkbox': {
+ if (!isset($value)) {
+ break;
+ }
$this->CheckBox($name, $w, $checked, $prop, $opt, $value, '', '', false);
break;
}
case 'radio': {
+ if (!isset($value)) {
+ break;
+ }
$this->RadioButton($name, $w, $prop, $opt, $value, $checked, '', '', false);
break;
}
case 'submit': {
+ if (!isset($value)) {
+ $value = 'submit';
+ }
$w = $this->GetStringWidth($value) * 1.5;
$h *= 1.6;
$prop = array('lineWidth'=>1, 'borderStyle'=>'beveled', 'fillColor'=>array(196, 196, 196), 'strokeColor'=>array(255, 255, 255));
@@ -23810,6 +24082,9 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
break;
}
case 'reset': {
+ if (!isset($value)) {
+ $value = 'reset';
+ }
$w = $this->GetStringWidth($value) * 1.5;
$h *= 1.6;
$prop = array('lineWidth'=>1, 'borderStyle'=>'beveled', 'fillColor'=>array(196, 196, 196), 'strokeColor'=>array(255, 255, 255));
@@ -23855,6 +24130,9 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
break;
}
case 'button': {
+ if (!isset($value)) {
+ $value = ' ';
+ }
$w = $this->GetStringWidth($value) * 1.5;
$h *= 1.6;
$prop = array('lineWidth'=>1, 'borderStyle'=>'beveled', 'fillColor'=>array(196, 196, 196), 'strokeColor'=>array(255, 255, 255));
@@ -24328,13 +24606,10 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
if (end($this->transfmrk[$this->page]) !== false) {
$pagemarkkey = key($this->transfmrk[$this->page]);
$pagemark = $this->transfmrk[$this->page][$pagemarkkey];
- $this->transfmrk[$this->page][$pagemarkkey] += $offsetlen;
} elseif ($this->InFooter) {
$pagemark = $this->footerpos[$this->page];
- $this->footerpos[$this->page] += $offsetlen;
} else {
$pagemark = $this->intmrk[$this->page];
- $this->intmrk[$this->page] += $offsetlen;
}
$pagebuff = $this->getPageBuffer($this->page);
$pstart = substr($pagebuff, 0, $pagemark);
@@ -24738,17 +25013,14 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
if (end($this->transfmrk[$this->page]) !== false) {
$pagemarkkey = key($this->transfmrk[$this->page]);
$pagemark = $this->transfmrk[$this->page][$pagemarkkey];
- $this->transfmrk[$this->page][$pagemarkkey] += $offsetlen;
} elseif ($this->InFooter) {
$pagemark = $this->footerpos[$this->page];
- $this->footerpos[$this->page] += $offsetlen;
} else {
$pagemark = $this->intmrk[$this->page];
- $this->intmrk[$this->page] += $offsetlen;
}
$pagebuff = $this->getPageBuffer($this->page);
- $pstart = substr($pagebuff, 0, $this->bordermrk[$this->page]);
- $pend = substr($pagebuff, $this->bordermrk[$this->page]);
+ $pstart = substr($pagebuff, 0, $pagemark);
+ $pend = substr($pagebuff, $pagemark);
$this->setPageBuffer($this->page, $pstart.$ccode.$pend);
$this->bordermrk[$this->page] += $offsetlen;
$this->cntmrk[$this->page] += $offsetlen;
@@ -25278,6 +25550,7 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
'cell_height_ratio' => $this->cell_height_ratio,
'font_stretching' => $this->font_stretching,
'font_spacing' => $this->font_spacing,
+ 'alpha' => $this->alpha,
// extended
'lasth' => $this->lasth,
'tMargin' => $this->tMargin,
@@ -25337,6 +25610,7 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
$this->cell_height_ratio = $gvars['cell_height_ratio'];
$this->font_stretching = $gvars['font_stretching'];
$this->font_spacing = $gvars['font_spacing'];
+ $this->alpha = $gvars['alpha'];
if ($extended) {
// restore extended values
$this->lasth = $gvars['lasth'];
@@ -25651,6 +25925,7 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
$tmpintmrk = $this->intmrk[$frompage];
$tmpbordermrk = $this->bordermrk[$frompage];
$tmpcntmrk = $this->cntmrk[$frompage];
+ $tmppageobjects = $this->pageobjects[$frompage];
if (isset($this->footerpos[$frompage])) {
$tmpfooterpos = $this->footerpos[$frompage];
}
@@ -25686,6 +25961,7 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
$this->intmrk[$i] = $this->intmrk[$j];
$this->bordermrk[$i] = $this->bordermrk[$j];
$this->cntmrk[$i] = $this->cntmrk[$j];
+ $this->pageobjects[$i] = $this->pageobjects[$j];
if (isset($this->footerpos[$j])) {
$this->footerpos[$i] = $this->footerpos[$j];
} elseif (isset($this->footerpos[$i])) {
@@ -25720,6 +25996,7 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
$this->intmrk[$topage] = $tmpintmrk;
$this->bordermrk[$topage] = $tmpbordermrk;
$this->cntmrk[$topage] = $tmpcntmrk;
+ $this->pageobjects[$topage] = $tmppageobjects;
if (isset($tmpfooterpos)) {
$this->footerpos[$topage] = $tmpfooterpos;
} elseif (isset($this->footerpos[$topage])) {
@@ -25807,6 +26084,12 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
unset($this->intmrk[$page]);
unset($this->bordermrk[$page]);
unset($this->cntmrk[$page]);
+ foreach ($this->pageobjects[$page] as $oid) {
+ if (isset($this->offsets[$oid])){
+ unset($this->offsets[$oid]);
+ }
+ }
+ unset($this->pageobjects[$page]);
if (isset($this->footerpos[$page])) {
unset($this->footerpos[$page]);
}
@@ -25841,6 +26124,7 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
$this->intmrk[$i] = $this->intmrk[$j];
$this->bordermrk[$i] = $this->bordermrk[$j];
$this->cntmrk[$i] = $this->cntmrk[$j];
+ $this->pageobjects[$i] = $this->pageobjects[$j];
if (isset($this->footerpos[$j])) {
$this->footerpos[$i] = $this->footerpos[$j];
} elseif (isset($this->footerpos[$i])) {
@@ -25881,6 +26165,12 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
unset($this->intmrk[$this->numpages]);
unset($this->bordermrk[$this->numpages]);
unset($this->cntmrk[$this->numpages]);
+ foreach ($this->pageobjects[$this->numpages] as $oid) {
+ if (isset($this->offsets[$oid])){
+ unset($this->offsets[$oid]);
+ }
+ }
+ unset($this->pageobjects[$this->numpages]);
if (isset($this->footerpos[$this->numpages])) {
unset($this->footerpos[$this->numpages]);
}
@@ -25982,6 +26272,7 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
$this->intmrk[$this->page] = $this->intmrk[$page];
$this->bordermrk[$this->page] = $this->bordermrk[$page];
$this->cntmrk[$this->page] = $this->cntmrk[$page];
+ $this->pageobjects[$this->page] = $this->pageobjects[$page];
$this->pageopen[$this->page] = false;
if (isset($this->footerpos[$page])) {
$this->footerpos[$this->page] = $this->footerpos[$page];
@@ -26007,7 +26298,7 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
$tmpoutlines = $this->outlines;
foreach ($tmpoutlines as $key => $outline) {
if ($outline['p'] == $page) {
- $this->outlines[] = array('t' => $outline['t'], 'l' => $outline['l'], 'y' => $outline['y'], 'p' => $this->page, 's' => $outline['s'], 'c' => $outline['c']);
+ $this->outlines[] = array('t' => $outline['t'], 'l' => $outline['l'], 'x' => $outline['x'], 'y' => $outline['y'], 'p' => $this->page, 's' => $outline['s'], 'c' => $outline['c']);
}
}
// copy links
@@ -26695,7 +26986,59 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
}
}
$this->textrendermode = $textrendermode;
- $this->textstrokewidth = $stroke * $this->k;
+ $this->textstrokewidth = $stroke;
+ }
+
+ /**
+ * Set parameters for drop shadow effect for text.
+ * @param $params (array) Array of parameters: enabled (boolean) set to true to enable shadow; depth_w (float) shadow width in user units; depth_h (float) shadow height in user units; color (array) shadow color or false to use the stroke color; opacity (float) Alpha value: real value from 0 (transparent) to 1 (opaque); blend_mode (string) blend mode, one of the following: Normal, Multiply, Screen, Overlay, Darken, Lighten, ColorDodge, ColorBurn, HardLight, SoftLight, Difference, Exclusion, Hue, Saturation, Color, Luminosity.
+ * @since 5.9.174 (2012-07-25)
+ * @public
+ */
+ public function setTextShadow($params=array('enabled'=>false, 'depth_w'=>0, 'depth_h'=>0, 'color'=>false, 'opacity'=>1, 'blend_mode'=>'Normal')) {
+ if (isset($params['enabled'])) {
+ $this->txtshadow['enabled'] = $params['enabled']?true:false;
+ } else {
+ $this->txtshadow['enabled'] = false;
+ }
+ if (isset($params['depth_w'])) {
+ $this->txtshadow['depth_w'] = floatval($params['depth_w']);
+ } else {
+ $this->txtshadow['depth_w'] = 0;
+ }
+ if (isset($params['depth_h'])) {
+ $this->txtshadow['depth_h'] = floatval($params['depth_h']);
+ } else {
+ $this->txtshadow['depth_h'] = 0;
+ }
+ if (isset($params['color']) AND ($params['color'] !== false) AND is_array($params['color'])) {
+ $this->txtshadow['color'] = $params['color'];
+ } else {
+ $this->txtshadow['color'] = $this->strokecolor;
+ }
+ if (isset($params['opacity'])) {
+ $this->txtshadow['opacity'] = min(1, max(0, floatval($params['opacity'])));
+ } else {
+ $this->txtshadow['opacity'] = 1;
+ }
+ if (isset($params['blend_mode']) AND in_array($params['blend_mode'], array('Normal', 'Multiply', 'Screen', 'Overlay', 'Darken', 'Lighten', 'ColorDodge', 'ColorBurn', 'HardLight', 'SoftLight', 'Difference', 'Exclusion', 'Hue', 'Saturation', 'Color', 'Luminosity'))) {
+ $this->txtshadow['blend_mode'] = $params['blend_mode'];
+ } else {
+ $this->txtshadow['blend_mode'] = 'Normal';
+ }
+ if ((($this->txtshadow['depth_w'] == 0) AND ($this->txtshadow['depth_h'] == 0)) OR ($this->txtshadow['opacity'] == 0)) {
+ $this->txtshadow['enabled'] = false;
+ }
+ }
+
+ /**
+ * Return the text shadow parameters array.
+ * @return Array of parameters.
+ * @since 5.9.174 (2012-07-25)
+ * @public
+ */
+ public function getTextShadow() {
+ return $this->txtshadow;
}
/**
@@ -27337,7 +27680,7 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
/**
* Get the amount to increase or decrease the space between characters in a text.
- * @return int font spacing (tracking/kerning) value
+ * @return int font spacing (tracking) value
* @author Nicola Asuni
* @public
* @since 5.9.000 (2010-09-29)
@@ -27741,7 +28084,7 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
// scale and translate
$e = $ox * $this->k * (1 - $svgscale_x);
$f = ($this->h - $oy) * $this->k * (1 - $svgscale_y);
- $this->_out(sprintf('%F %F %F %F %F %F cm', $svgscale_x, 0, 0, $svgscale_y, $e + $svgoffset_x, $f + $svgoffset_y));
+ $this->_out(sprintf('%F %F %F %F %F %F cm', $svgscale_x, 0, 0, $svgscale_y, ($e + $svgoffset_x), ($f + $svgoffset_y)));
// creates a new XML parser to be used by the other XML functions
$this->parser = xml_parser_create('UTF-8');
// the following function allows to use parser inside object
@@ -28089,10 +28432,10 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
$gradient['coords'][3] += $y;
}
// calculate percentages
- $gradient['coords'][0] = ($gradient['coords'][0] - $x) / $w;
- $gradient['coords'][1] = ($gradient['coords'][1] - $y) / $h;
- $gradient['coords'][2] = ($gradient['coords'][2] - $x) / $w;
- $gradient['coords'][3] = ($gradient['coords'][3] - $y) / $h;
+ $gradient['coords'][0] = (($gradient['coords'][0] - $x) / $w);
+ $gradient['coords'][1] = (($gradient['coords'][1] - $y) / $h);
+ $gradient['coords'][2] = (($gradient['coords'][2] - $x) / $w);
+ $gradient['coords'][3] = (($gradient['coords'][3] - $y) / $h);
if (isset($gradient['coords'][4])) {
$gradient['coords'][4] /= $w;
}
@@ -28121,9 +28464,9 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
if ($gradient['type'] == 3) {
// circular gradient
$cy = $this->h - $y - ($gradient['coords'][1] * ($w + $h));
- $this->_out(sprintf('%F 0 0 %F %F %F cm', $w*$this->k, $w*$this->k, $x*$this->k, $cy*$this->k));
+ $this->_out(sprintf('%F 0 0 %F %F %F cm', ($w * $this->k), ($w * $this->k), ($x * $this->k), ($cy * $this->k)));
} else {
- $this->_out(sprintf('%F 0 0 %F %F %F cm', $w*$this->k, $h*$this->k, $x*$this->k, ($this->h-($y+$h))*$this->k));
+ $this->_out(sprintf('%F 0 0 %F %F %F cm', ($w * $this->k), ($h * $this->k), ($x * $this->k), (($this->h - ($y + $h)) * $this->k)));
}
if (count($gradient['stops']) > 1) {
$this->Gradient($gradient['type'], $gradient['coords'], $gradient['stops'], array(), false);
@@ -28331,6 +28674,8 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
} else {
$this->_outLine($x, $y);
}
+ $x0 = $x;
+ $y0 = $y;
}
$xmin = min($xmin, $x);
$ymin = min($ymin, $y);
@@ -28352,6 +28697,8 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
$y = $cp + $yoffset;
if ((abs($x0 - $x) >= $minlen) OR (abs($y0 - $y) >= $minlen)) {
$this->_outLine($x, $y);
+ $x0 = $x;
+ $y0 = $y;
}
$xmin = min($xmin, $x);
$ymin = min($ymin, $y);
@@ -28370,6 +28717,8 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
$x = $cp + $xoffset;
if ((abs($x0 - $x) >= $minlen) OR (abs($y0 - $y) >= $minlen)) {
$this->_outLine($x, $y);
+ $x0 = $x;
+ $y0 = $y;
}
$xmin = min($xmin, $x);
$xmax = max($xmax, $x);
@@ -28384,6 +28733,8 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
$y = $cp + $yoffset;
if ((abs($x0 - $x) >= $minlen) OR (abs($y0 - $y) >= $minlen)) {
$this->_outLine($x, $y);
+ $x0 = $x;
+ $y0 = $y;
}
$ymin = min($ymin, $y);
$ymax = max($ymax, $y);
@@ -28661,6 +29012,10 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
// get styling properties
$prev_svgstyle = $this->svgstyles[(count($this->svgstyles) - 1)]; // previous style
$svgstyle = $this->svgstyles[0]; // set default style
+ if ($clipping AND !isset($attribs['fill']) AND (!isset($attribs['style']) OR (!preg_match('/[;\"\s]{1}fill[\s]*:[\s]*([^;\"]*)/si', $attribs['style'], $attrval)))) {
+ // default fill attribute for clipping
+ $attribs['fill'] = 'none';
+ }
if (isset($attribs['style']) AND !$this->empty_string($attribs['style'])) {
// fix style for regular expression
$attribs['style'] = ';'.$attribs['style'];
@@ -28693,7 +29048,8 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
if (!empty($ctm)) {
$tm = $ctm;
} else {
- $tm = $this->svgstyles[(count($this->svgstyles) - 1)]['transfmatrix'];
+ //$tm = $this->svgstyles[(count($this->svgstyles) - 1)]['transfmatrix'];
+ $tm = array(1,0,0,1,0,0);
}
if (isset($attribs['transform']) AND !empty($attribs['transform'])) {
$tm = $this->getTransformationMatrixProduct($tm, $this->getSVGTransformMatrix($attribs['transform']));
@@ -28732,6 +29088,7 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
// group together related graphics elements
array_push($this->svgstyles, $svgstyle);
$this->StartTransform();
+ $this->SVGTransform($tm);
$this->setSVGStyles($svgstyle, $prev_svgstyle);
break;
}
@@ -28752,15 +29109,19 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
$this->svggradients[$this->svggradientid]['gradientUnits'] = 'objectBoundingBox';
}
//$attribs['spreadMethod']
- $x1 = (isset($attribs['x1'])?$attribs['x1']:'0%');
- $y1 = (isset($attribs['y1'])?$attribs['y1']:'0%');
- $x2 = (isset($attribs['x2'])?$attribs['x2']:'100%');
- $y2 = (isset($attribs['y2'])?$attribs['y2']:'0%');
- if (substr($x1, -1) != '%') {
- $this->svggradients[$this->svggradientid]['mode'] = 'measure';
- } else {
+ if (((!isset($attribs['x1'])) AND (!isset($attribs['y1'])) AND (!isset($attribs['x2'])) AND (!isset($attribs['y2'])))
+ OR ((isset($attribs['x1']) AND (substr($attribs['x1'], -1) == '%'))
+ OR (isset($attribs['y1']) AND (substr($attribs['y1'], -1) == '%'))
+ OR (isset($attribs['x2']) AND (substr($attribs['x2'], -1) == '%'))
+ OR (isset($attribs['y2']) AND (substr($attribs['y2'], -1) == '%')))) {
$this->svggradients[$this->svggradientid]['mode'] = 'percentage';
+ } else {
+ $this->svggradients[$this->svggradientid]['mode'] = 'measure';
}
+ $x1 = (isset($attribs['x1'])?$attribs['x1']:'0');
+ $y1 = (isset($attribs['y1'])?$attribs['y1']:'0');
+ $x2 = (isset($attribs['x2'])?$attribs['x2']:'100');
+ $y2 = (isset($attribs['y2'])?$attribs['y2']:'0');
if (isset($attribs['gradientTransform'])) {
$this->svggradients[$this->svggradientid]['gradientTransform'] = $this->getSVGTransformMatrix($attribs['gradientTransform']);
}
@@ -28788,16 +29149,18 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
$this->svggradients[$this->svggradientid]['gradientUnits'] = 'objectBoundingBox';
}
//$attribs['spreadMethod']
- $cx = (isset($attribs['cx'])?$attribs['cx']:0.5);
- $cy = (isset($attribs['cy'])?$attribs['cy']:0.5);
- $fx = (isset($attribs['fx'])?$attribs['fx']:$cx);
- $fy = (isset($attribs['fy'])?$attribs['fy']:$cy);
- $r = (isset($attribs['r'])?$attribs['r']:0.5);
- if (isset($attribs['cx']) AND (substr($attribs['cx'], -1) != '%')) {
- $this->svggradients[$this->svggradientid]['mode'] = 'measure';
- } else {
+ if (((!isset($attribs['cx'])) AND (!isset($attribs['cy'])))
+ OR ((isset($attribs['cx']) AND (substr($attribs['cx'], -1) == '%'))
+ OR (isset($attribs['cy']) AND (substr($attribs['cy'], -1) == '%')) )) {
$this->svggradients[$this->svggradientid]['mode'] = 'percentage';
+ } else {
+ $this->svggradients[$this->svggradientid]['mode'] = 'measure';
}
+ $cx = (isset($attribs['cx']) ? $attribs['cx'] : 0.5);
+ $cy = (isset($attribs['cy']) ? $attribs['cy'] : 0.5);
+ $fx = (isset($attribs['fx']) ? $attribs['fx'] : $cx);
+ $fy = (isset($attribs['fy']) ? $attribs['fy'] : $cy);
+ $r = (isset($attribs['r']) ? $attribs['r'] : 0.5);
if (isset($attribs['gradientTransform'])) {
$this->svggradients[$this->svggradientid]['gradientTransform'] = $this->getSVGTransformMatrix($attribs['gradientTransform']);
}
@@ -28876,12 +29239,12 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
if ($invisible) {
break;
}
- $cx = (isset($attribs['cx'])?$this->getHTMLUnitToUnits($attribs['cx'], 0, $this->svgunit, false):0);
- $cy = (isset($attribs['cy'])?$this->getHTMLUnitToUnits($attribs['cy'], 0, $this->svgunit, false):0);
- $r = (isset($attribs['r'])?$this->getHTMLUnitToUnits($attribs['r'], 0, $this->svgunit, false):0);
- $x = $cx - $r;
- $y = $cy - $r;
- $w = 2 * $r;
+ $r = (isset($attribs['r']) ? $this->getHTMLUnitToUnits($attribs['r'], 0, $this->svgunit, false) : 0);
+ $cx = (isset($attribs['cx']) ? $this->getHTMLUnitToUnits($attribs['cx'], 0, $this->svgunit, false) : (isset($attribs['x']) ? $this->getHTMLUnitToUnits($attribs['x'], 0, $this->svgunit, false) : 0));
+ $cy = (isset($attribs['cy']) ? $this->getHTMLUnitToUnits($attribs['cy'], 0, $this->svgunit, false) : (isset($attribs['y']) ? $this->getHTMLUnitToUnits($attribs['y'], 0, $this->svgunit, false) : 0));
+ $x = ($cx - $r);
+ $y = ($cy - $r);
+ $w = (2 * $r);
$h = $w;
if ($clipping) {
$this->SVGTransform($tm);
@@ -28901,14 +29264,14 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
if ($invisible) {
break;
}
- $cx = (isset($attribs['cx'])?$this->getHTMLUnitToUnits($attribs['cx'], 0, $this->svgunit, false):0);
- $cy = (isset($attribs['cy'])?$this->getHTMLUnitToUnits($attribs['cy'], 0, $this->svgunit, false):0);
- $rx = (isset($attribs['rx'])?$this->getHTMLUnitToUnits($attribs['rx'], 0, $this->svgunit, false):0);
- $ry = (isset($attribs['ry'])?$this->getHTMLUnitToUnits($attribs['ry'], 0, $this->svgunit, false):0);
- $x = $cx - $rx;
- $y = $cy - $ry;
- $w = 2 * $rx;
- $h = 2 * $ry;
+ $rx = (isset($attribs['rx']) ? $this->getHTMLUnitToUnits($attribs['rx'], 0, $this->svgunit, false) : 0);
+ $ry = (isset($attribs['ry']) ? $this->getHTMLUnitToUnits($attribs['ry'], 0, $this->svgunit, false) : 0);
+ $cx = (isset($attribs['cx']) ? $this->getHTMLUnitToUnits($attribs['cx'], 0, $this->svgunit, false) : (isset($attribs['x']) ? $this->getHTMLUnitToUnits($attribs['x'], 0, $this->svgunit, false) : 0));
+ $cy = (isset($attribs['cy']) ? $this->getHTMLUnitToUnits($attribs['cy'], 0, $this->svgunit, false) : (isset($attribs['y']) ? $this->getHTMLUnitToUnits($attribs['y'], 0, $this->svgunit, false) : 0));
+ $x = ($cx - $rx);
+ $y = ($cy - $ry);
+ $w = (2 * $rx);
+ $h = (2 * $ry);
if ($clipping) {
$this->SVGTransform($tm);
$this->Ellipse($cx, $cy, $rx, $ry, 0, 0, 360, 'CNZ', array(), array(), 8);
@@ -28981,7 +29344,9 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
$this->StartTransform();
$this->SVGTransform($tm);
$obstyle = $this->setSVGStyles($svgstyle, $prev_svgstyle, $x, $y, $w, $h, 'PolyLine', array($p, 'CNZ'));
- $this->PolyLine($p, 'D', array(), array());
+ if (!empty($obstyle)) {
+ $this->PolyLine($p, $obstyle, array(), array());
+ }
$this->StopTransform();
} else { // polygon
if ($clipping) {
@@ -29050,14 +29415,26 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
// text
case 'text':
case 'tspan': {
+ // only basic support - advanced features must be implemented
$this->svgtextmode['invisible'] = $invisible;
if ($invisible) {
break;
}
array_push($this->svgstyles, $svgstyle);
- // only basic support - advanced features must be implemented
- $x = (isset($attribs['x'])?$this->getHTMLUnitToUnits($attribs['x'], 0, $this->svgunit, false):$this->x);
- $y = (isset($attribs['y'])?$this->getHTMLUnitToUnits($attribs['y'], 0, $this->svgunit, false):$this->y);
+ if (isset($attribs['x'])) {
+ $x = $this->getHTMLUnitToUnits($attribs['x'], 0, $this->svgunit, false);
+ } elseif ($name == 'tspan') {
+ $x = $this->x;
+ } else {
+ $x = 0;
+ }
+ if (isset($attribs['y'])) {
+ $y = $this->getHTMLUnitToUnits($attribs['y'], 0, $this->svgunit, false);
+ } elseif ($name == 'tspan') {
+ $y = $this->y;
+ } else {
+ $y = 0;
+ }
$svgstyle['text-color'] = $svgstyle['fill'];
$this->svgtext = '';
if (isset($svgstyle['text-anchor'])) {
@@ -29088,16 +29465,19 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
}
// use
case 'use': {
- if (isset($attribs['xlink:href'])) {
- $use = $this->svgdefs[substr($attribs['xlink:href'], 1)];
- if (isset($attribs['xlink:href'])) {
- unset($attribs['xlink:href']);
+ if (isset($attribs['xlink:href']) AND !empty($attribs['xlink:href'])) {
+ $svgdefid = substr($attribs['xlink:href'], 1);
+ if (isset($this->svgdefs[$svgdefid])) {
+ $use = $this->svgdefs[$svgdefid];
+ if (isset($attribs['xlink:href'])) {
+ unset($attribs['xlink:href']);
+ }
+ if (isset($attribs['id'])) {
+ unset($attribs['id']);
+ }
+ $attribs = array_merge($attribs, $use['attribs']);
+ $this->startSVGElementHandler($parser, $use['name'], $attribs);
}
- if (isset($attribs['id'])) {
- unset($attribs['id']);
- }
- $attribs = array_merge($use['attribs'], $attribs);
- $this->startSVGElementHandler($parser, $use['name'], $use['attribs']);
}
break;
}
@@ -29162,7 +29542,17 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
$textrendermode = $this->textrendermode;
$textstrokewidth = $this->textstrokewidth;
$this->setTextRenderingMode($this->svgtextmode['stroke'], true, false);
+ if ($name == 'text') {
+ // store current coordinates
+ $tmpx = $this->x;
+ $tmpy = $this->y;
+ }
$this->Cell($textlen, 0, $text, 0, 0, '', false, '', 0, false, 'L', 'T');
+ if ($name == 'text') {
+ // restore coordinates
+ $this->x = $tmpx;
+ $this->y = $tmpy;
+ }
// restore previous rendering mode
$this->textrendermode = $textrendermode;
$this->textstrokewidth = $textstrokewidth;
diff --git a/lib/tcpdf/tcpdf_parser.php b/lib/tcpdf/tcpdf_parser.php
index 122676034d3..f17359f2134 100644
--- a/lib/tcpdf/tcpdf_parser.php
+++ b/lib/tcpdf/tcpdf_parser.php
@@ -1,9 +1,9 @@
* @package com.tecnick.tcpdf
* @author Nicola Asuni
- * @version 1.0.000
+ * @version 1.0.001
*/
// include class for decoding filters
@@ -48,7 +48,7 @@ require_once(dirname(__FILE__).'/tcpdf_filters.php');
* This is a PHP class for parsing PDF documents.
* @package com.tecnick.tcpdf
* @brief This is a PHP class for parsing PDF documents..
- * @version 1.0.000
+ * @version 1.0.001
* @author Nicola Asuni - info@tecnick.com
*/
class TCPDF_PARSER {
@@ -127,20 +127,29 @@ class TCPDF_PARSER {
* @since 1.0.000 (2011-05-24)
*/
protected function getXrefData($offset=0, $xref=array()) {
- // find last startxref
- if (preg_match_all('/[\r\n]startxref[\s]*[\r\n]+([0-9]+)[\s]*[\r\n]+%%EOF/i', $this->pdfdata, $matches, PREG_SET_ORDER, $offset) == 0) {
- $this->Error('Unable to find startxref');
+ if ($offset == 0) {
+ // find last startxref
+ if (preg_match_all('/[\r\n]startxref[\s]*[\r\n]+([0-9]+)[\s]*[\r\n]+%%EOF/i', $this->pdfdata, $matches, PREG_SET_ORDER, $offset) == 0) {
+ $this->Error('Unable to find startxref');
+ }
+ $matches = array_pop($matches);
+ $startxref = $matches[1];
+ } else {
+ // get the first xref at the specified offset
+ if (preg_match('/[\r\n]startxref[\s]*[\r\n]+([0-9]+)[\s]*[\r\n]+%%EOF/i', $this->pdfdata, $matches, PREG_OFFSET_CAPTURE, $offset) == 0) {
+ $this->Error('Unable to find startxref');
+ }
+ $startxref = $matches[1][0];
}
- $matches = array_pop($matches);
- $startxref = $matches[1];
// check xref position
if (strpos($this->pdfdata, 'xref', $startxref) != $startxref) {
$this->Error('Unable to find xref');
}
// extract xref data (object indexes and offsets)
- $offset = $startxref + 5;
+ $xoffset = $startxref + 5;
// initialize object number
$obj_num = 0;
+ $offset = $xoffset;
while (preg_match('/^([0-9]+)[\s]([0-9]+)[\s]?([nf]?)/im', $this->pdfdata, $matches, PREG_OFFSET_CAPTURE, $offset) > 0) {
$offset = (strlen($matches[0][0]) + $matches[0][1]);
if ($matches[3][0] == 'n') {
@@ -162,7 +171,7 @@ class TCPDF_PARSER {
}
}
// get trailer data
- if (preg_match('/trailer[\s]*<<(.*)>>[\s]*[\r\n]+startxref[\s]*[\r\n]+/isU', $this->pdfdata, $matches, PREG_OFFSET_CAPTURE, $offset) > 0) {
+ if (preg_match('/trailer[\s]*<<(.*)>>[\s]*[\r\n]+startxref[\s]*[\r\n]+/isU', $this->pdfdata, $matches, PREG_OFFSET_CAPTURE, $xoffset) > 0) {
$trailer_data = $matches[1][0];
if (!isset($xref['trailer'])) {
// get only the last updated version
@@ -188,7 +197,7 @@ class TCPDF_PARSER {
}
if (preg_match('/Prev[\s]+([0-9]+)/i', $trailer_data, $matches) > 0) {
// get previous xref
- $xref = getXrefData(substr($this->pdfdata, 0, $startxref), intval($matches[1]), $xref);
+ $xref = $this->getXrefData(intval($matches[1]), $xref);
}
} else {
$this->Error('Unable to find trailer');
@@ -399,7 +408,7 @@ class TCPDF_PARSER {
$offset = $element[2];
// decode stream using stream's dictionary information
if ($decoding AND ($element[0] == 'stream') AND (isset($objdata[($i - 1)][0])) AND ($objdata[($i - 1)][0] == '<<')) {
- $element[3] = $this->decodeStream($objdata[($i - 1)][1], $element[1]);
+ $element[3] = $this->decodeStream($objdata[($i - 1)][1], substr($element[1], 1));
}
$objdata[$i] = $element;
++$i;
diff --git a/lib/thirdpartylibs.xml b/lib/thirdpartylibs.xml
index 48811300c00..43a932fe4c2 100644
--- a/lib/thirdpartylibs.xml
+++ b/lib/thirdpartylibs.xml
@@ -179,7 +179,7 @@
tcpdf
TCPDF
LGPL
- 5.9.156
+ 5.9.181
3