|
From: <dai...@us...> - 2012-05-04 21:56:02
|
Revision: 5315
http://web-erp.svn.sourceforge.net/web-erp/?rev=5315&view=rev
Author: daintree
Date: 2012-05-04 21:55:53 +0000 (Fri, 04 May 2012)
Log Message:
-----------
update to 5.9.160 tcpdf
Modified Paths:
--------------
trunk/doc/Change.log
trunk/includes/tcpdf/2dbarcodes.php
trunk/includes/tcpdf/CHANGELOG.TXT
trunk/includes/tcpdf/README.TXT
trunk/includes/tcpdf/barcodes.php
trunk/includes/tcpdf/tcpdf.php
trunk/sql/mysql/upgrade4.07-4.08.sql
Modified: trunk/doc/Change.log
===================================================================
--- trunk/doc/Change.log 2012-05-04 02:48:41 UTC (rev 5314)
+++ trunk/doc/Change.log 2012-05-04 21:55:53 UTC (rev 5315)
@@ -1,6 +1,8 @@
webERP Change Log
-1/5/2012 MTPubRadio: Measurement unit in FormDesigner.php should be points instead of millimeters.
-1/5/2012 MTPubRadio: Fixed Purch Order PDF file text of Order Total- Excl tax does not align with amount horizontally.
+
+4/5/12 Phil: Default lastcostupdate to 0000-00-00 to avoid issues inserting new items.
+1/5/12 MTPubRadio: Measurement unit in FormDesigner.php should be points instead of millimeters.
+1/5/12 MTPubRadio: Fixed Purch Order PDF file text of Order Total- Excl tax does not align with amount horizontally.
29/4/12 Opto/Klaus: SelectWorkOrder.php added start date for the work order to the work orders displayed for selection
29/4/12 David Short: Added EDISendInvoices_Reece.php to send Reece format EDI invoices - approved by Reece (Australian Plumbing retailer)
28/4/2012 Exson: Fixed bugs in MRPCalendar.php which caused working days cannot be calculated correctly.
Modified: trunk/includes/tcpdf/2dbarcodes.php
===================================================================
--- trunk/includes/tcpdf/2dbarcodes.php 2012-05-04 02:48:41 UTC (rev 5314)
+++ trunk/includes/tcpdf/2dbarcodes.php 2012-05-04 21:55:53 UTC (rev 5315)
@@ -1,9 +1,9 @@
<?php
//============================================================+
// File name : 2dbarcodes.php
-// Version : 1.0.013
+// Version : 1.0.014
// Begin : 2009-04-07
-// Last Update : 2012-01-12
+// Last Update : 2012-04-30
// Author : Nicola Asuni - Tecnick.com LTD - Manor Coach House, Church Hill, Aldershot, Hants, GU12 4RQ, UK - www.tecnick.com - in...@te...
// License : GNU-LGPL v3 (http://www.gnu.org/copyleft/lesser.html)
// -------------------------------------------------------------------
@@ -37,14 +37,14 @@
* PHP class to creates array representations for 2D barcodes to be used with TCPDF.
* @package com.tecnick.tcpdf
* @author Nicola Asuni
- * @version 1.0.013
+ * @version 1.0.014
*/
/**
* @class TCPDF2DBarcode
* PHP class to creates array representations for 2D barcodes to be used with TCPDF (http://www.tcpdf.org).
* @package com.tecnick.tcpdf
- * @version 1.0.013
+ * @version 1.0.014
* @author Nicola Asuni
*/
class TCPDF2DBarcode {
@@ -202,9 +202,9 @@
if ($this->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;
Modified: trunk/includes/tcpdf/CHANGELOG.TXT
===================================================================
--- trunk/includes/tcpdf/CHANGELOG.TXT 2012-05-04 02:48:41 UTC (rev 5314)
+++ trunk/includes/tcpdf/CHANGELOG.TXT 2012-05-04 21:55:53 UTC (rev 5315)
@@ -1,3 +1,55 @@
+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.
+
+5.9.155 (2012-04-02)
+ - Bug item #3512596 "font import problems" was fixed.
+ - Method addTTFfont() was modified to extract only specified Platform ID and Encoding ID (check the source code documentation).
+ - All fonts were updated.
+ - Bug item #3513867 "booklet and setHeaderTemplateAutoreset: header shifted left" was fixed.
+ - Bug item #3513749 "TCPDF Superscript/Subscript" was fixed.
+
+5.9.154 (2012-03-29)
+ - A debug echo was removed.
+
+5.9.153 (2012-03-28)
+ - A bug on font conversion was fixed.
+ - All fonts were updated.
+ - Method isCharDefined() was added to find if a character is defined on the selected font.
+ - Method replaceMissingChars() was added to automatically replace missing chars on selected font.
+ - SetFont() method was fixed.
+
+5.9.152 (2012-03-23)
+ - The following overprint methods were added: setOverprint(), getOverprint().
+ - Signature of setAlpha() method was changed and method getAlpha() was added.
+ - stroke-opacity support was added on SVG.
+ - The following date methods were added: setDocCreationTimestamp(), setDocModificationTimestamp(), getDocCreationTimestamp(), getDocModificationTimestamp(), getFormattedDate(), getTimestamp().
+ - Signature of _datestring() method was changed.
+ - Method getFontBBox() was added.
+ - Method setPageBoxTypes() was aded.
+
+5.9.151 (2012-03-22)
+ - Bug item #3509889 "Transform() distorts PDF" was fixed.
+ - Precision of real number were extended.
+ - ComboBox and ListBox methods were fixed.
+ - Bulgarian language file was added.
+ - addTOC() method was improved to include bookmark color and font style.
+
+5.9.150 (2012-03-16)
+ - A bug related to form fields in PDF/A mode was fixed.
+
5.9.149 (2012-02-21)
- Bug item #3489933 "SVG Parser treats tspan like text" was fixed.
Modified: trunk/includes/tcpdf/README.TXT
===================================================================
--- trunk/includes/tcpdf/README.TXT 2012-05-04 02:48:41 UTC (rev 5314)
+++ trunk/includes/tcpdf/README.TXT 2012-05-04 21:55:53 UTC (rev 5315)
@@ -8,8 +8,8 @@
------------------------------------------------------------
Name: TCPDF
-Version: 5.9.149
-Release date: 2012-02-21
+Version: 5.9.160
+Release date: 2012-05-03
Author: Nicola Asuni
Copyright (c) 2002-2012:
@@ -93,5 +93,5 @@
To get the original distribution archives please check the information on fonts subfolders:
- DejaVu fonts 2.33 (Bitstream) - Copyright, License and other info: fonts/dejavu-fonts-ttf-2.33
- GNU FreeFont (GNU-GPLv3) - Copyright, License and other info: fonts/freefont-20100919
-
+
============================================================
Modified: trunk/includes/tcpdf/barcodes.php
===================================================================
--- trunk/includes/tcpdf/barcodes.php 2012-05-04 02:48:41 UTC (rev 5314)
+++ trunk/includes/tcpdf/barcodes.php 2012-05-04 21:55:53 UTC (rev 5315)
@@ -1,9 +1,9 @@
<?php
//============================================================+
// File name : barcodes.php
-// Version : 1.0.023
+// Version : 1.0.024
// Begin : 2008-06-09
-// Last Update : 2012-01-14
+// Last Update : 2012-04-30
// Author : Nicola Asuni - Tecnick.com LTD - Manor Coach House, Church Hill, Aldershot, Hants, GU12 4RQ, UK - www.tecnick.com - in...@te...
// License : GNU-LGPL v3 (http://www.gnu.org/copyleft/lesser.html)
// -------------------------------------------------------------------
@@ -37,14 +37,14 @@
* PHP class to creates array representations for common 1D barcodes to be used with TCPDF.
* @package com.tecnick.tcpdf
* @author Nicola Asuni
- * @version 1.0.023
+ * @version 1.0.024
*/
/**
* @class TCPDFBarcode
* PHP class to creates array representations for common 1D barcodes to be used with TCPDF (http://www.tcpdf.org).<br>
* @package com.tecnick.tcpdf
- * @version 1.0.023
+ * @version 1.0.024
* @author Nicola Asuni
*/
class TCPDFBarcode {
@@ -201,9 +201,9 @@
$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;
Modified: trunk/includes/tcpdf/tcpdf.php
===================================================================
--- trunk/includes/tcpdf/tcpdf.php 2012-05-04 02:48:41 UTC (rev 5314)
+++ trunk/includes/tcpdf/tcpdf.php 2012-05-04 21:55:53 UTC (rev 5315)
@@ -1,9 +1,9 @@
<?php
//============================================================+
// File name : tcpdf.php
-// Version : 5.9.149
+// Version : 5.9.160
// Begin : 2002-08-03
-// Last Update : 2012-02-21
+// Last Update : 2012-05-03
// Author : Nicola Asuni - Tecnick.com LTD - Manor Coach House, Church Hill, Aldershot, Hants, GU12 4RQ, UK - www.tecnick.com - in...@te...
// License : http://www.tecnick.com/pagefiles/tcpdf/LICENSE.TXT GNU-LGPLv3
// -------------------------------------------------------------------
@@ -137,7 +137,7 @@
* Tools to encode your unicode fonts are on fonts/utils directory.</p>
* @package com.tecnick.tcpdf
* @author Nicola Asuni
- * @version 5.9.149
+ * @version 5.9.160
*/
// Main configuration file. Define the K_TCPDF_EXTERNAL_CONFIG constant to skip this file.
@@ -149,7 +149,7 @@
* 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.<br>
* @package com.tecnick.tcpdf
* @brief PHP class for generating PDF documents without requiring external extensions.
- * @version 5.9.149
+ * @version 5.9.160
* @author Nicola Asuni - in...@te...
*/
class TCPDF {
@@ -160,7 +160,7 @@
* Current TCPDF version.
* @private
*/
- private $tcpdf_version = '5.9.149';
+ private $tcpdf_version = '5.9.160';
// Protected properties
@@ -1816,19 +1816,63 @@
protected $pdfa_mode = false;
/**
- * Document creation date
+ * Document creation date-time
* @protected
- * @since 5.9.121 (2011-09-28)
+ * @since 5.9.152 (2012-03-22)
*/
- protected $doc_date;
+ protected $doc_creation_timestamp;
/**
+ * Document modification date-time
+ * @protected
+ * @since 5.9.152 (2012-03-22)
+ */
+ protected $doc_modification_timestamp;
+
+ /**
* Custom XMP data.
* @protected
* @since 5.9.128 (2011-10-06)
*/
protected $custom_xmp = '';
+ /**
+ * Overprint mode array.
+ * (Check the "Entries in a Graphics State Parameter Dictionary" on PDF 32000-1:2008).
+ * @protected
+ * @since 5.9.152 (2012-03-23)
+ */
+ protected $overprint = array('OP' => false, 'op' => false, 'OPM' => 0);
+
+ /**
+ * Alpha mode array.
+ * (Check the "Entries in a Graphics State Parameter Dictionary" on PDF 32000-1:2008).
+ * @protected
+ * @since 5.9.152 (2012-03-23)
+ */
+ protected $alpha = array('CA' => 1, 'ca' => 1, 'BM' => '/Normal', 'AIS' => false);
+
+ /**
+ * Define the page boundaries boxes to be set on document.
+ * @protected
+ * @since 5.9.152 (2012-03-23)
+ */
+ protected $page_boxes = array('MediaBox', 'CropBox', 'BleedBox', 'TrimBox', 'ArtBox');
+
+ /**
+ * Set the document producer metadata.
+ * @protected
+ * @since 5.9.152 (2012-03-23)
+ */
+ protected $pdfproducer;
+
+ /**
+ * If true print TCPDF meta link.
+ * @protected
+ * @since 5.9.152 (2012-03-23)
+ */
+ protected $tcpdflink = true;
+
//------------------------------------------------------------
// METHODS
//------------------------------------------------------------
@@ -1941,7 +1985,7 @@
$this->setCellMargins(0, 0, 0, 0);
// line width (0.2 mm)
$this->LineWidth = 0.57 / $this->k;
- $this->linestyleWidth = sprintf('%.2F w', ($this->LineWidth * $this->k));
+ $this->linestyleWidth = sprintf('%F w', ($this->LineWidth * $this->k));
$this->linestyleCap = '0 J';
$this->linestyleJoin = '0 j';
$this->linestyleDash = '[] 0 d';
@@ -1953,6 +1997,8 @@
$this->SetCompression();
// set default PDF version number
$this->setPDFVersion();
+ $this->pdfproducer = "\x54\x43\x50\x44\x46\x20".$this->tcpdf_version."\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x74\x63\x70\x64\x66\x2e\x6f\x72\x67\x29";
+ $this->tcpdflink = true;
$this->encoding = $encoding;
$this->HREF = array();
$this->getFontsList();
@@ -1992,8 +2038,9 @@
$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));
- // set document date
- $this->doc_date = substr_replace(date('YmdHisO'), '\'', (0 - 2), 0).'\'';
+ // set document creation and modification timestamp
+ $this->doc_creation_timestamp = time();
+ $this->doc_modification_timestamp = $this->doc_creation_timestamp;
// get default graphic vars
$this->default_graphic_vars = $this->getGraphicVars();
$this->header_xobj_autoreset = false;
@@ -3742,24 +3789,26 @@
$this->AddPage();
}
$this->endLayer();
- // save current graphic settings
- $gvars = $this->getGraphicVars();
- $this->setEqualColumns();
- $this->lastpage(true);
- $this->SetAutoPageBreak(false);
- $this->x = 0;
- $this->y = $this->h - (1 / $this->k);
- $this->lMargin = 0;
- $this->_out('q');
- $font = defined('PDF_FONT_NAME_MAIN')?PDF_FONT_NAME_MAIN:'helvetica';
- $this->SetFont($font, '', 1);
- $this->setTextRenderingMode(0, false, false);
- $msg = "\x50\x6f\x77\x65\x72\x65\x64\x20\x62\x79\x20\x54\x43\x50\x44\x46\x20\x28\x77\x77\x77\x2e\x74\x63\x70\x64\x66\x2e\x6f\x72\x67\x29";
- $lnk = "\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x74\x63\x70\x64\x66\x2e\x6f\x72\x67";
- $this->Cell(0, 0, $msg, 0, 0, 'L', 0, $lnk, 0, false, 'D', 'B');
- $this->_out('Q');
- // restore graphic settings
- $this->setGraphicVars($gvars);
+ if ($this->tcpdflink) {
+ // save current graphic settings
+ $gvars = $this->getGraphicVars();
+ $this->setEqualColumns();
+ $this->lastpage(true);
+ $this->SetAutoPageBreak(false);
+ $this->x = 0;
+ $this->y = $this->h - (1 / $this->k);
+ $this->lMargin = 0;
+ $this->_out('q');
+ $font = defined('PDF_FONT_NAME_MAIN')?PDF_FONT_NAME_MAIN:'helvetica';
+ $this->SetFont($font, '', 1);
+ $this->setTextRenderingMode(0, false, false);
+ $msg = "\x50\x6f\x77\x65\x72\x65\x64\x20\x62\x79\x20\x54\x43\x50\x44\x46\x20\x28\x77\x77\x77\x2e\x74\x63\x70\x64\x66\x2e\x6f\x72\x67\x29";
+ $lnk = "\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x74\x63\x70\x64\x66\x2e\x6f\x72\x67";
+ $this->Cell(0, 0, $msg, 0, 0, 'L', 0, $lnk, 0, false, 'D', 'B');
+ $this->_out('Q');
+ // restore graphic settings
+ $this->setGraphicVars($gvars);
+ }
// close page
$this->endPage();
// close document
@@ -4212,7 +4261,7 @@
// print header template
$x = 0;
$dx = 0;
- if ($this->booklet AND (($this->page % 2) == 0)) {
+ if (!$this->header_xobj_autoreset AND $this->booklet AND (($this->page % 2) == 0)) {
// adjust margins for booklet mode
$dx = ($this->original_lMargin - $this->original_rMargin);
}
@@ -4503,19 +4552,19 @@
$pdfcolor = sprintf('/CS%d ', $this->spot_colors[$name]['i']);
switch ($type) {
case 'draw': {
- $pdfcolor .= sprintf('CS %.3F SCN', $tint);
+ $pdfcolor .= sprintf('CS %F SCN', $tint);
$this->DrawColor = $pdfcolor;
$this->strokecolor = $spotcolor;
break;
}
case 'fill': {
- $pdfcolor .= sprintf('cs %.3F scn', $tint);
+ $pdfcolor .= sprintf('cs %F scn', $tint);
$this->FillColor = $pdfcolor;
$this->bgcolor = $spotcolor;
break;
}
case 'text': {
- $pdfcolor .= sprintf('cs %.3F scn', $tint);
+ $pdfcolor .= sprintf('cs %F scn', $tint);
$this->TextColor = $pdfcolor;
$this->fgcolor = $spotcolor;
break;
@@ -4674,7 +4723,7 @@
// Grey scale
$col1 = max(0, min(255, $col1));
$intcolor = array('G' => $col1);
- $pdfcolor = sprintf('%.3F ', ($col1 / 255));
+ $pdfcolor = sprintf('%F ', ($col1 / 255));
$suffix = 'g';
} elseif ($col4 == -1) {
// RGB
@@ -4682,7 +4731,7 @@
$col2 = max(0, min(255, $col2));
$col3 = max(0, min(255, $col3));
$intcolor = array('R' => $col1, 'G' => $col2, 'B' => $col3);
- $pdfcolor = sprintf('%.3F %.3F %.3F ', ($col1 / 255), ($col2 / 255), ($col3 / 255));
+ $pdfcolor = sprintf('%F %F %F ', ($col1 / 255), ($col2 / 255), ($col3 / 255));
$suffix = 'rg';
} else {
$col1 = max(0, min(100, $col1));
@@ -4692,7 +4741,7 @@
if (empty($name)) {
// CMYK
$intcolor = array('C' => $col1, 'M' => $col2, 'Y' => $col3, 'K' => $col4);
- $pdfcolor = sprintf('%.3F %.3F %.3F %.3F ', ($col1 / 100), ($col2 / 100), ($col3 / 100), ($col4 / 100));
+ $pdfcolor = sprintf('%F %F %F %F ', ($col1 / 100), ($col2 / 100), ($col3 / 100), ($col4 / 100));
$suffix = 'k';
} else {
// SPOT COLOR
@@ -4744,17 +4793,17 @@
switch (count($c)) {
case 4: {
// CMYK
- $color .= sprintf('%.3F %.3F %.3F %.3F', (max(0, min(100, floatval($c[0]))) / 100), (max(0, min(100, floatval($c[1]))) / 100), (max(0, min(100, floatval($c[2]))) / 100), (max(0, min(100, floatval($c[3]))) / 100));
+ $color .= sprintf('%F %F %F %F', (max(0, min(100, floatval($c[0]))) / 100), (max(0, min(100, floatval($c[1]))) / 100), (max(0, min(100, floatval($c[2]))) / 100), (max(0, min(100, floatval($c[3]))) / 100));
break;
}
case 3: {
// RGB
- $color .= sprintf('%.3F %.3F %.3F', (max(0, min(255, floatval($c[0]))) / 255), (max(0, min(255, floatval($c[1]))) / 255), (max(0, min(255, floatval($c[2]))) / 255));
+ $color .= sprintf('%F %F %F', (max(0, min(255, floatval($c[0]))) / 255), (max(0, min(255, floatval($c[1]))) / 255), (max(0, min(255, floatval($c[2]))) / 255));
break;
}
case 1: {
// grayscale
- $color .= sprintf('%.3F', (max(0, min(255, floatval($c[0]))) / 255));
+ $color .= sprintf('%F', (max(0, min(255, floatval($c[0]))) / 255));
break;
}
}
@@ -5230,11 +5279,14 @@
* @since 1.0
* @see AddFont(), SetFontSize()
*/
- public function SetFont($family, $style='', $size=0, $fontfile='', $subset='default', $out=true) {
+ public function SetFont($family, $style='', $size=null, $fontfile='', $subset='default', $out=true) {
//Select a font; size given in points
- if ($size == 0) {
+ if ($size === null) {
$size = $this->FontSizePt;
}
+ if ($size < 0) {
+ $size = 0;
+ }
// try to add font (if not already added)
$fontdata = $this->AddFont($family, $style, $fontfile, $subset);
$this->FontFamily = $fontdata['family'];
@@ -5281,11 +5333,52 @@
$this->FontAscent = ($font_ascent / $this->k);
$this->FontDescent = ($font_descent / $this->k);
if ($out AND ($this->page > 0) AND (isset($this->CurrentFont['i']))) {
- $this->_out(sprintf('BT /F%d %.2F Tf ET', $this->CurrentFont['i'], $this->FontSizePt));
+ $this->_out(sprintf('BT /F%d %F Tf ET', $this->CurrentFont['i'], $this->FontSizePt));
}
}
/**
+ * Returns the bounding box of the current font in user units.
+ * @return array
+ * @public
+ * @since 5.9.152 (2012-03-23)
+ */
+ public function getFontBBox() {
+ $result = array();
+ if (isset($this->CurrentFont['desc']['FontBBox'])) {
+ $bbox = explode(' ', substr($this->CurrentFont['desc']['FontBBox'], 1, -1));
+ foreach ($bbox as $v) {
+ $result[] = (intval($v) * $this->FontSize / 1000);
+ }
+ } else {
+ // Find max width
+ if (isset($this->CurrentFont['desc']['MaxWidth'])) {
+ $maxw = (intval($this->CurrentFont['desc']['MaxWidth']) * $this->FontSize / 1000);
+ } else {
+ $maxw = 0;
+ if (isset($this->CurrentFont['desc']['MissingWidth'])) {
+ $maxw = max($maxw, $this->CurrentFont['desc']['MissingWidth']);
+ }
+ if (isset($this->CurrentFont['desc']['AvgWidth'])) {
+ $maxw = max($maxw, $this->CurrentFont['desc']['AvgWidth']);
+ }
+ if (isset($this->CurrentFont['dw'])) {
+ $maxw = max($maxw, $this->CurrentFont['dw']);
+ }
+ foreach ($this->CurrentFont['cw'] as $char => $w) {
+ $maxw = max($maxw, $w);
+ }
+ if ($maxw == 0) {
+ $maxw = 600;
+ }
+ $maxw = ($maxw * $this->FontSize / 1000);
+ }
+ $result = array(0, -$this->FontDescent, $maxw, $this->FontAscent);
+ }
+ return $result;
+ }
+
+ /**
* Return the font descent value
* @param $font (string) font name
* @param $style (string) font style
@@ -5328,6 +5421,70 @@
}
/**
+ * Return the font descent value
+ * @param $char (mixed) Character to check (integer value or string)
+ * @param $font (string) Font name (family name).
+ * @param $style (string) Font style.
+ * @return (boolean) true if the char is defined, false otherwise.
+ * @public
+ * @since 5.9.153 (2012-03-28)
+ */
+ public function isCharDefined($char, $font='', $style='') {
+ if (is_string($char)) {
+ // get character code
+ $char = $this->UTF8StringToArray($char);
+ $char = $char[0];
+ }
+ if ($this->empty_string($font)) {
+ $font = $this->FontFamily;
+ }
+ $fontdata = $this->AddFont($font, $style);
+ $fontinfo = $this->getFontBuffer($fontdata['fontkey']);
+ return (isset($fontinfo['cw'][intval($char)]));
+ }
+
+ /**
+ * Replace missing font characters on selected font with specified substitutions.
+ * @param $text (string) Text to process.
+ * @param $font (string) Font name (family name).
+ * @param $style (string) Font style.
+ * @param $subs (array) Array of possible character substitutions. The key is the character to check (integer value) and the value is a single intege value or an array of possible substitutes.
+ * @return (string) Processed text.
+ * @public
+ * @since 5.9.153 (2012-03-28)
+ */
+ public function replaceMissingChars($text, $font='', $style='', $subs=array()) {
+ if (empty($subs)) {
+ return $text;
+ }
+ if ($this->empty_string($font)) {
+ $font = $this->FontFamily;
+ }
+ $fontdata = $this->AddFont($font, $style);
+ $fontinfo = $this->getFontBuffer($fontdata['fontkey']);
+ $uniarr = $this->UTF8StringToArray($text);
+ foreach ($uniarr as $k => $chr) {
+ if (!isset($fontinfo['cw'][$chr])) {
+ // this character is missing on the selected font
+ if (isset($subs[$chr])) {
+ // we have available substitutions
+ if (is_array($subs[$chr])) {
+ foreach($subs[$chr] as $s) {
+ if (isset($fontinfo['cw'][$s])) {
+ $uniarr[$k] = $s;
+ break;
+ }
+ }
+ } elseif (isset($fontinfo['cw'][$subs[$chr]])) {
+ $uniarr[$k] = $subs[$chr];
+ }
+ }
+ }
+ }
+ return $this->UniArrSubString($this->UTF8ArrayToUniArray($uniarr));
+ }
+
+ /**
* Defines the default monospaced font.
* @param $font (string) Font name.
* @public
@@ -5561,7 +5718,7 @@
if ($this->current_column < ($this->num_columns - 1)) {
// go to next column
$this->selectColumn($this->current_column + 1);
- } else {
+ } elseif ($this->AutoPageBreak) {
// add a new page
$this->AddPage();
// set first column
@@ -5854,7 +6011,7 @@
} else {
$xk = ($x * $k);
}
- $s .= sprintf('%.2F %.2F %.2F %.2F re %s ', $xk, (($this->h - $y) * $k), ($w * $k), (-$h * $k), $op);
+ $s .= sprintf('%F %F %F %F re %s ', $xk, (($this->h - $y) * $k), ($w * $k), (-$h * $k), $op);
}
// draw borders
$s .= $this->getCellBorder($x, $y, $w, $h, $border);
@@ -5927,17 +6084,17 @@
}
if ($this->font_stretching != 100) {
// apply font stretching
- $rs .= sprintf('BT %.2F Tz ET ', $this->font_stretching);
+ $rs .= sprintf('BT %F Tz ET ', $this->font_stretching);
}
if ($this->font_spacing != 0) {
// increase/decrease font spacing
- $rs .= sprintf('BT %.2F Tc ET ', ($this->font_spacing * $this->k));
+ $rs .= sprintf('BT %F Tc ET ', ($this->font_spacing * $this->k));
}
if ($this->ColorFlag AND ($this->textrendermode < 4)) {
$s .= 'q '.$this->TextColor.' ';
}
// rendering mode
- $s .= sprintf('BT %d Tr %.2F w ET ', $this->textrendermode, $this->textstrokewidth);
+ $s .= sprintf('BT %d Tr %F w ET ', $this->textrendermode, $this->textstrokewidth);
// count number of spaces
$ns = substr_count($txt, chr(32));
// Justification
@@ -5953,7 +6110,7 @@
$spacewidth /= ($this->font_stretching / 100);
}
// set word position to be used with TJ operator
- $txt2 = str_replace(chr(0).chr(32), ') '.sprintf('%.3F', $spacewidth).' (', $txt2);
+ $txt2 = str_replace(chr(0).chr(32), ') '.sprintf('%F', $spacewidth).' (', $txt2);
$unicode_justification = true;
} else {
// get string width
@@ -5965,7 +6122,7 @@
$spacewidth /= ($this->font_stretching / 100);
}
// set word spacing
- $rs .= sprintf('BT %.3F Tw ET ', $spacewidth);
+ $rs .= sprintf('BT %F Tw ET ', $spacewidth);
}
$width = $w - $this->cell_padding['L'] - $this->cell_padding['R'];
}
@@ -6009,7 +6166,7 @@
}
$xdk = $xdx * $k;
// print text
- $s .= sprintf('BT %.2F %.2F Td [(%s)] TJ ET', $xdk, (($this->h - $basefonty) * $k), $txt2);
+ $s .= sprintf('BT %F %F Td [(%s)] TJ ET', $xdk, (($this->h - $basefonty) * $k), $txt2);
if (isset($uniblock)) {
// print overlapping characters as separate string
$xshift = 0; // horizontal shift
@@ -6027,7 +6184,7 @@
// character to print
$topchr = $this->arrUTF8ToUTF16BE($uniarr, false);
$topchr = $this->_escape($topchr);
- $s .= sprintf(' BT %.2F %.2F Td [(%s)] TJ ET', ($xdk + ($xshift * $k)), $ty, $topchr);
+ $s .= sprintf(' BT %F %F Td [(%s)] TJ ET', ($xdk + ($xshift * $k)), $ty, $topchr);
}
}
}
@@ -6193,85 +6350,85 @@
}
// draw borders by case
if (strlen($border) == 4) {
- $s .= sprintf('%.2F %.2F %.2F %.2F re S ', $xT, $yT, ($w * $k), (-$h * $k));
+ $s .= sprintf('%F %F %F %F re S ', $xT, $yT, ($w * $k), (-$h * $k));
} elseif (strlen($border) == 3) {
if (strpos($border,'B') === false) { // LTR
- $s .= sprintf('%.2F %.2F m ', $xL, $yL);
- $s .= sprintf('%.2F %.2F l ', $xT, $yT);
- $s .= sprintf('%.2F %.2F l ', $xR, $yR);
- $s .= sprintf('%.2F %.2F l ', $xB, $yB);
+ $s .= sprintf('%F %F m ', $xL, $yL);
+ $s .= sprintf('%F %F l ', $xT, $yT);
+ $s .= sprintf('%F %F l ', $xR, $yR);
+ $s .= sprintf('%F %F l ', $xB, $yB);
$s .= 'S ';
} elseif (strpos($border,'L') === false) { // TRB
- $s .= sprintf('%.2F %.2F m ', $xT, $yT);
- $s .= sprintf('%.2F %.2F l ', $xR, $yR);
- $s .= sprintf('%.2F %.2F l ', $xB, $yB);
- $s .= sprintf('%.2F %.2F l ', $xL, $yL);
+ $s .= sprintf('%F %F m ', $xT, $yT);
+ $s .= sprintf('%F %F l ', $xR, $yR);
+ $s .= sprintf('%F %F l ', $xB, $yB);
+ $s .= sprintf('%F %F l ', $xL, $yL);
$s .= 'S ';
} elseif (strpos($border,'T') === false) { // RBL
- $s .= sprintf('%.2F %.2F m ', $xR, $yR);
- $s .= sprintf('%.2F %.2F l ', $xB, $yB);
- $s .= sprintf('%.2F %.2F l ', $xL, $yL);
- $s .= sprintf('%.2F %.2F l ', $xT, $yT);
+ $s .= sprintf('%F %F m ', $xR, $yR);
+ $s .= sprintf('%F %F l ', $xB, $yB);
+ $s .= sprintf('%F %F l ', $xL, $yL);
+ $s .= sprintf('%F %F l ', $xT, $yT);
$s .= 'S ';
} elseif (strpos($border,'R') === false) { // BLT
- $s .= sprintf('%.2F %.2F m ', $xB, $yB);
- $s .= sprintf('%.2F %.2F l ', $xL, $yL);
- $s .= sprintf('%.2F %.2F l ', $xT, $yT);
- $s .= sprintf('%.2F %.2F l ', $xR, $yR);
+ $s .= sprintf('%F %F m ', $xB, $yB);
+ $s .= sprintf('%F %F l ', $xL, $yL);
+ $s .= sprintf('%F %F l ', $xT, $yT);
+ $s .= sprintf('%F %F l ', $xR, $yR);
$s .= 'S ';
}
} elseif (strlen($border) == 2) {
if ((strpos($border,'L') !== false) AND (strpos($border,'T') !== false)) { // LT
- $s .= sprintf('%.2F %.2F m ', $xL, $yL);
- $s .= sprintf('%.2F %.2F l ', $xT, $yT);
- $s .= sprintf('%.2F %.2F l ', $xR, $yR);
+ $s .= sprintf('%F %F m ', $xL, $yL);
+ $s .= sprintf('%F %F l ', $xT, $yT);
+ $s .= sprintf('%F %F l ', $xR, $yR);
$s .= 'S ';
} elseif ((strpos($border,'T') !== false) AND (strpos($border,'R') !== false)) { // TR
- $s .= sprintf('%.2F %.2F m ', $xT, $yT);
- $s .= sprintf('%.2F %.2F l ', $xR, $yR);
- $s .= sprintf('%.2F %.2F l ', $xB, $yB);
+ $s .= sprintf('%F %F m ', $xT, $yT);
+ $s .= sprintf('%F %F l ', $xR, $yR);
+ $s .= sprintf('%F %F l ', $xB, $yB);
$s .= 'S ';
} elseif ((strpos($border,'R') !== false) AND (strpos($border,'B') !== false)) { // RB
- $s .= sprintf('%.2F %.2F m ', $xR, $yR);
- $s .= sprintf('%.2F %.2F l ', $xB, $yB);
- $s .= sprintf('%.2F %.2F l ', $xL, $yL);
+ $s .= sprintf('%F %F m ', $xR, $yR);
+ $s .= sprintf('%F %F l ', $xB, $yB);
+ $s .= sprintf('%F %F l ', $xL, $yL);
$s .= 'S ';
} elseif ((strpos($border,'B') !== false) AND (strpos($border,'L') !== false)) { // BL
- $s .= sprintf('%.2F %.2F m ', $xB, $yB);
- $s .= sprintf('%.2F %.2F l ', $xL, $yL);
- $s .= sprintf('%.2F %.2F l ', $xT, $yT);
+ $s .= sprintf('%F %F m ', $xB, $yB);
+ $s .= sprintf('%F %F l ', $xL, $yL);
+ $s .= sprintf('%F %F l ', $xT, $yT);
$s .= 'S ';
} elseif ((strpos($border,'L') !== false) AND (strpos($border,'R') !== false)) { // LR
- $s .= sprintf('%.2F %.2F m ', $xL, $yL);
- $s .= sprintf('%.2F %.2F l ', $xT, $yT);
+ $s .= sprintf('%F %F m ', $xL, $yL);
+ $s .= sprintf('%F %F l ', $xT, $yT);
$s .= 'S ';
- $s .= sprintf('%.2F %.2F m ', $xR, $yR);
- $s .= sprintf('%.2F %.2F l ', $xB, $yB);
+ $s .= sprintf('%F %F m ', $xR, $yR);
+ $s .= sprintf('%F %F l ', $xB, $yB);
$s .= 'S ';
} elseif ((strpos($border,'T') !== false) AND (strpos($border,'B') !== false)) { // TB
- $s .= sprintf('%.2F %.2F m ', $xT, $yT);
- $s .= sprintf('%.2F %.2F l ', $xR, $yR);
+ $s .= sprintf('%F %F m ', $xT, $yT);
+ $s .= sprintf('%F %F l ', $xR, $yR);
$s .= 'S ';
- $s .= sprintf('%.2F %.2F m ', $xB, $yB);
- $s .= sprintf('%.2F %.2F l ', $xL, $yL);
+ $s .= sprintf('%F %F m ', $xB, $yB);
+ $s .= sprintf('%F %F l ', $xL, $yL);
$s .= 'S ';
}
} else { // strlen($border) == 1
if (strpos($border,'L') !== false) { // L
- $s .= sprintf('%.2F %.2F m ', $xL, $yL);
- $s .= sprintf('%.2F %.2F l ', $xT, $yT);
+ $s .= sprintf('%F %F m ', $xL, $yL);
+ $s .= sprintf('%F %F l ', $xT, $yT);
$s .= 'S ';
} elseif (strpos($border,'T') !== false) { // T
- $s .= sprintf('%.2F %.2F m ', $xT, $yT);
- $s .= sprintf('%.2F %.2F l ', $xR, $yR);
+ $s .= sprintf('%F %F m ', $xT, $yT);
+ $s .= sprintf('%F %F l ', $xR, $yR);
$s .= 'S ';
} elseif (strpos($border,'R') !== false) { // R
- $s .= sprintf('%.2F %.2F m ', $xR, $yR);
- $s .= sprintf('%.2F %.2F l ', $xB, $yB);
+ $s .= sprintf('%F %F m ', $xR, $yR);
+ $s .= sprintf('%F %F l ', $xB, $yB);
$s .= 'S ';
} elseif (strpos($border,'B') !== false) { // B
- $s .= sprintf('%.2F %.2F m ', $xB, $yB);
- $s .= sprintf('%.2F %.2F l ', $xL, $yL);
+ $s .= sprintf('%F %F m ', $xB, $yB);
+ $s .= sprintf('%F %F l ', $xL, $yL);
$s .= 'S ';
}
}
@@ -7755,7 +7912,7 @@
$tmp = array();
if (preg_match('/[\s]+width[\s]*=[\s]*"([^"]*)"/si', $svgtag, $tmp)) {
$ow = $this->getHTMLUnitToUnits($tmp[1], 1, $this->svgunit, false);
- $owu = sprintf('%.3F', ($ow * $dpi / 72)).$this->pdfunit;
+ $owu = sprintf('%F', ($ow * $dpi / 72)).$this->pdfunit;
$svgtag = preg_replace('/[\s]+width[\s]*=[\s]*"[^"]*"/si', ' width="'.$owu.'"', $svgtag, 1);
} else {
$ow = $w;
@@ -7763,7 +7920,7 @@
$tmp = array();
if (preg_match('/[\s]+height[\s]*=[\s]*"([^"]*)"/si', $svgtag, $tmp)) {
$oh = $this->getHTMLUnitToUnits($tmp[1], 1, $this->svgunit, false);
- $ohu = sprintf('%.3F', ($oh * $dpi / 72)).$this->pdfunit;
+ $ohu = sprintf('%F', ($oh * $dpi / 72)).$this->pdfunit;
$svgtag = preg_replace('/[\s]+height[\s]*=[\s]*"[^"]*"/si', ' height="'.$ohu.'"', $svgtag, 1);
} else {
$oh = $h;
@@ -7772,7 +7929,7 @@
if (!preg_match('/[\s]+viewBox[\s]*=[\s]*"[\s]*([0-9\.]+)[\s]+([0-9\.]+)[\s]+([0-9\.]+)[\s]+([0-9\.]+)[\s]*"/si', $svgtag, $tmp)) {
$vbw = ($ow * $this->imgscale * $this->k);
$vbh = ($oh * $this->imgscale * $this->k);
- $vbox = sprintf(' viewBox="0 0 %.3F %.3F" ', $vbw, $vbh);
+ $vbox = sprintf(' viewBox="0 0 %F %F" ', $vbw, $vbh);
$svgtag = $vbox.$svgtag;
}
$svgimg = preg_replace('/<svg([^\>]*)>/si', '<svg'.$svgtag.'>', $svgimg, 1);
@@ -7856,7 +8013,7 @@
$xkimg = $ximg * $this->k;
if (!$alt) {
// only non-alternative immages will be set
- $this->_out(sprintf('q %.2F 0 0 %.2F %.2F %.2F cm /I%u Do Q', ($w * $this->k), ($h * $this->k), $xkimg, (($this->h - ($y + $h)) * $this->k), $info['i']));
+ $this->_out(sprintf('q %F 0 0 %F %F %F cm /I%u Do Q', ($w * $this->k), ($h * $this->k), $xkimg, (($this->h - ($y + $h)) * $this->k), $info['i']));
}
if (!empty($border)) {
$bx = $this->x;
@@ -8843,6 +9000,21 @@
}
/**
+ * Set page boxes to be included on page descriptions.
+ * @param $boxes (array) Array of page boxes to set on document: ('MediaBox', 'CropBox', 'BleedBox', 'TrimBox', 'ArtBox').
+ * @protected
+ */
+ protected function setPageBoxTypes($boxes) {
+ $validboxes = array('MediaBox', 'CropBox', 'BleedBox', 'TrimBox', 'ArtBox');
+ $this->page_boxes = array();
+ foreach ($boxes as $box) {
+ if (in_array($box, $validboxes)) {
+ $this->page_boxes[] = $box;
+ }
+ }
+ }
+
+ /**
* Output pages (and replace page number aliases).
* @protected
*/
@@ -8904,22 +9076,21 @@
$out = '<<';
$out .= ' /Type /Page';
$out .= ' /Parent 1 0 R';
- $out .= ' /LastModified '.$this->_datestring();
+ $out .= ' /LastModified '.$this->_datestring(0, $this->doc_modification_timestamp);
$out .= ' /Resources 2 0 R';
- $boxes = array('MediaBox', 'CropBox', 'BleedBox', 'TrimBox', 'ArtBox');
- foreach ($boxes as $box) {
+ foreach ($this->page_boxes as $box) {
$out .= ' /'.$box;
- $out .= sprintf(' [%.2F %.2F %.2F %.2F]', $this->pagedim[$n][$box]['llx'], $this->pagedim[$n][$box]['lly'], $this->pagedim[$n][$box]['urx'], $this->pagedim[$n][$box]['ury']);
+ $out .= sprintf(' [%F %F %F %F]', $this->pagedim[$n][$box]['llx'], $this->pagedim[$n][$box]['lly'], $this->pagedim[$n][$box]['urx'], $this->pagedim[$n][$box]['ury']);
}
if (isset($this->pagedim[$n]['BoxColorInfo']) AND !empty($this->pagedim[$n]['BoxColorInfo'])) {
$out .= ' /BoxColorInfo <<';
- foreach ($boxes as $box) {
+ foreach ($this->page_boxes as $box) {
if (isset($this->pagedim[$n]['BoxColorInfo'][$box])) {
$out .= ' /'.$box.' <<';
if (isset($this->pagedim[$n]['BoxColorInfo'][$box]['C'])) {
$color = $this->pagedim[$n]['BoxColorInfo'][$box]['C'];
$out .= ' /C [';
- $out .= sprintf(' %.3F %.3F %.3F', $color[0]/255, $color[1]/255, $color[2]/255);
+ $out .= sprintf(' %F %F %F', ($color[0] / 255), ($color[1] / 255), ($color[2] / 255));
$out .= ' ]';
}
if (isset($this->pagedim[$n]['BoxColorInfo'][$box]['W'])) {
@@ -8932,7 +9103,7 @@
$dashes = $this->pagedim[$n]['BoxColorInfo'][$box]['D'];
$out .= ' /D [';
foreach ($dashes as $dash) {
- $out .= sprintf(' %.3F', ($dash * $this->k));
+ $out .= sprintf(' %F', ($dash * $this->k));
}
$out .= ' ]';
}
@@ -9116,7 +9287,7 @@
$b = $this->pagedim[$n]['h'] - (($pl['y'] + $pl['h']) * $this->k);
$c = $pl['w'] * $this->k;
$d = $pl['h'] * $this->k;
- $rect = sprintf('%.2F %.2F %.2F %.2F', $a, $b, $a+$c, $b+$d);
+ $rect = sprintf('%F %F %F %F', $a, $b, $a+$c, $b+$d);
// create new annotation object
$annots = '<</Type /Annot';
$annots .= ' /Subtype /'.$pl['opt']['subtype'];
@@ -9129,7 +9300,7 @@
$annots .= ' /Contents '.$this->_textstring($pl['txt'], $annot_obj_id);
$annots .= ' /P '.$this->page_obj_id[$n].' 0 R';
$annots .= ' /NM '.$this->_datastring(sprintf('%04u-%04u', $n, $key), $annot_obj_id);
- $annots .= ' /M '.$this->_datestring($annot_obj_id);
+ $annots .= ' /M '.$this->_datestring($annot_obj_id, $this->doc_modification_timestamp);
if (isset($pl['opt']['f'])) {
$fval = 0;
if (is_array($pl['opt']['f'])) {
@@ -9265,7 +9436,7 @@
$annots .= ' /S /S';
}
if (isset($pl['opt']['be']['i']) AND ($pl['opt']['be']['i'] >= 0) AND ($pl['opt']['be']['i'] <= 2)) {
- $annots .= ' /I '.sprintf(' %.4F', $pl['opt']['be']['i']);
+ $annots .= ' /I '.sprintf(' %F', $pl['opt']['be']['i']);
}
$annots .= '>>';
}
@@ -9282,12 +9453,12 @@
}
//$annots .= ' /Popup ';
if (isset($pl['opt']['ca'])) {
- $annots .= ' /CA '.sprintf('%.4F', floatval($pl['opt']['ca']));
+ $annots .= ' /CA '.sprintf('%F', floatval($pl['opt']['ca']));
}
if (isset($pl['opt']['rc'])) {
$annots .= ' /RC '.$this->_textstring($pl['opt']['rc'], $annot_obj_id);
}
- $annots .= ' /CreationDate '.$this->_datestring($annot_obj_id);
+ $annots .= ' /CreationDate '.$this->_datestring($annot_obj_id, $this->doc_creation_timestamp);
//$annots .= ' /IRT ';
if (isset($pl['opt']['subj'])) {
$annots .= ' /Subj '.$this->_textstring($pl['opt']['subj'], $annot_obj_id);
@@ -9340,7 +9511,7 @@
// internal link
$l = $this->links[$pl['txt']];
if (isset($this->page_obj_id[($l[0])])) {
- $annots .= sprintf(' /Dest [%u 0 R /XYZ 0 %.2F null]', $this->page_obj_id[($l[0])], ($this->pagedim[$l[0]]['h'] - ($l[1] * $this->k)));
+ $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');
@@ -9369,7 +9540,7 @@
if (isset($pl['opt']['cl']) AND is_array($pl['opt']['cl'])) {
$annots .= ' /CL [';
foreach ($pl['opt']['cl'] as $cl) {
- $annots .= sprintf('%.4F ', $cl * $this->k);
+ $annots .= sprintf('%F ', $cl * $this->k);
}
$annots .= ']';
}
@@ -9382,7 +9553,7 @@
$r = $pl['opt']['rd'][1] * $this->k;
$t = $pl['opt']['rd'][2] * $this->k;
$b = $pl['opt']['rd'][3] * $this->k;
- $annots .= ' /RD ['.sprintf('%.2F %.2F %.2F %.2F', $l, $r, $t, $b).']';
+ $annots .= ' /RD ['.sprintf('%F %F %F %F', $l, $r, $t, $b).']';
}
if (isset($pl['opt']['le']) AND in_array($pl['opt']['le'], $lineendings)) {
$annots .= ' /LE /'.$pl['opt']['le'];
@@ -9523,7 +9694,7 @@
$annots .= ' /S /'.$pl['opt']['mk']['if']['s'];
}
if (isset($pl['opt']['mk']['if']['a']) AND (is_array($pl['opt']['mk']['if']['a'])) AND !empty($pl['opt']['mk']['if']['a'])) {
- $annots .= sprintf(' /A [%.2F %.2F]', $pl['opt']['mk']['if']['a'][0], $pl['opt']['mk']['if']['a'][1]);
+ $annots .= sprintf(' /A [%F %F]', $pl['opt']['mk']['if']['a'][0], $pl['opt']['mk']['if']['a'][1]);
}
if (isset($pl['opt']['mk']['if']['fb']) AND ($pl['opt']['mk']['if']['fb'])) {
$annots .= ' /FB true';
@@ -9569,7 +9740,7 @@
if (is_array($pl['opt']['v'])) {
foreach ($pl['opt']['v'] AS $optval) {
if (is_float($optval)) {
- $optval = sprintf('%.2F', $optval);
+ $optval = sprintf('%F', $optval);
}
$annots .= ' '.$optval;
}
@@ -9582,7 +9753,7 @@
if (is_array($pl['opt']['dv'])) {
foreach ($pl['opt']['dv'] AS $optval) {
if (is_float($optval)) {
- $optval = sprintf('%.2F', $optval);
+ $optval = sprintf('%F', $optval);
}
$annots .= ' '.$optval;
}
@@ -9595,7 +9766,7 @@
if (is_array($pl['opt']['rv'])) {
foreach ($pl['opt']['rv'] AS $optval) {
if (is_float($optval)) {
- $optval = sprintf('%.2F', $optval);
+ $optval = sprintf('%F', $optval);
}
$annots .= ' '.$optval;
}
@@ -9690,7 +9861,7 @@
$stream = gzcompress($stream);
$out .= ' /Filter /FlateDecode';
}
- $rect = sprintf('%.2F %.2F', $w, $h);
+ $rect = sprintf('%F %F', $w, $h);
$out .= ' /BBox [0 0 '.$rect.']';
$out .= ' /Matrix [1 0 0 1 0 0]';
$out .= ' /Resources 2 0 R';
@@ -9733,8 +9904,8 @@
/**
* Get SHORT from string (Big Endian 16-bit signed integer).
- * @param $str (string) string from where to extract value
- * @param $offset (int) point from where to read the data
+ * @param $str (string) String from where to extract value.
+ * @param $offset (int) Point from where to read the data.
* @return int 16 bit value
* @author Nicola Asuni
* @protected
@@ -9747,8 +9918,8 @@
/**
* Get FWORD from string (Big Endian 16-bit signed integer).
- * @param $str (string) string from where to extract value
- * @param $offset (int) point from where to read the data
+ * @param $str (string) String from where to extract value.
+ * @param $offset (int) Point from where to read the data.
* @return int 16 bit value
* @author Nicola Asuni
* @protected
@@ -9830,17 +10001,19 @@
/**
* Convert and add the selected TrueType or Type1 font to the fonts folder (that must be writeable).
- * @param $fontfile (string) TrueType or Type1 font file (full path).
+ * @param $fontfile (string) Font file (full path).
* @param $fonttype (string) Font type. Leave empty for autodetect mode. Valid values are: TrueTypeUnicode, TrueType, Type1, CID0JP = CID-0 Japanese, CID0KR = CID-0 Korean, CID0CS = CID-0 Chinese Simplified, CID0CT = CID-0 Chinese Traditional.
* @param $enc (string) Name of the encoding table to use. Leave empty for default mode. Omit this parameter for TrueType Unicode and symbolic fonts like Symbol or ZapfDingBats.
* @param $flags (int) Unsigned 32-bit integer containing flags specifying various characteristics of the font (PDF32000:2008 - 9.8.2 Font Descriptor Flags): +1 for fixed font; +4 for symbol or +32 for non-symbol; +64 for italic. Fixed and Italic mode are generally autodetected so you have to set it to 32 = non-symbolic font (default) or 4 = symbolic font.
* @param $outpath (string) Output path for generated font files (must be writeable by the web server). Leave empty for default font folder.
+ * @param $platid (int) Platform ID for CMAP table to extract (when building a Unicode font for Windows this value should be 3, for Macintosh should be 1).
+ * @param $encid (int) Encoding ID for CMAP table to extract (when building a Unicode font for Windows this value should be 1, for Macintosh should be 0). When Platform ID is 3, legal values for Encoding ID are: 0=Symbol, 1=Unicode, 2=ShiftJIS, 3=PRC, 4=Big5, 5=Wansung, 6=Johab, 7=Reserved, 8=Reserved, 9=Reserved, 10=UCS-4.
* @return (string) TCPDF font name.
* @author Nicola Asuni
* @public
* @since 5.9.123 (2010-09-30)
*/
- public function addTTFfont($fontfile, $fonttype='', $enc='', $flags=32, $outpath='') {
+ public function addTTFfont($fontfile, $fonttype='', $enc='', $flags=32, $outpath='', $platid=3, $encid=1) {
if (!file_exists($fontfile)) {
$this->Error('Could not find file: '.$fontfile.'');
}
@@ -10309,220 +10482,216 @@
// ---------- get CIDToGIDMap ----------
$ctg = array();
foreach ($encodingTables as $enctable) {
- if (($enctable['platformID'] == 3) AND ($enctable['encodingID'] == 0)) {
- $modesymbol = true;
- } else {
- $modesymbol = false;
- }
- $offset = $table['cmap']['offset'] + $enctable['offset'];
- $format = $this->_getUSHORT($font, $offset);
- $offset += 2;
- switch ($format) {
- case 0: { // Format 0: Byte encoding table
- $offset += 4; // skip length and version/language
- for ($c = 0; $c < 256; ++$c) {
- $g = $this->_getBYTE($font, $offset);
- $ctg[$c] = $g;
- ++$offset;
+ // get only specified Platform ID and Encoding ID
+ if (($enctable['platformID'] == $platid) AND ($enctable['encodingID'] == $encid)) {
+ $offset = $table['cmap']['offset'] + $enctable['offset'];
+ $format = $this->_getUSHORT($font, $offset);
+ $offset += 2;
+ switch ($format) {
+ case 0: { // Format 0: Byte encoding table
+ $offset += 4; // skip length and version/language
+ for ($c = 0; $c < 256; ++$c) {
+ $g = $this->_getBYTE($font, $offset);
+ $ctg[$c] = $g;
+ ++$offset;
+ }
+ break;
}
- break;
- }
- case 2: { // Format 2: High-byte mapping through table
- $offset += 4; // skip length and version/language
- $numSubHeaders = 0;
- for ($i = 0; $i < 256; ++$i) {
- // Array that maps high bytes to subHeaders: value is subHeader index * 8.
- $subHeaderKeys[$i] = ($this->_getUSHORT($font, $offset) / 8);
- $offset += 2;
- if ($numSubHeaders < $subHeaderKeys[$i]) {
- $numSubHeaders = $subHeaderKeys[$i];
+ case 2: { // Format 2: High-byte mapping through table
+ $offset += 4; // skip length and version/language
+ $numSubHeaders = 0;
+ for ($i = 0; $i < 256; ++$i) {
+ // Array that maps high bytes to subHeaders: value is subHeader index * 8.
+ $subHeaderKeys[$i] = ($this->_getUSHORT($font, $offset) / 8);
+ $offset += 2;
+ if ($numSubHeaders < $subHeaderKeys[$i]) {
+ $numSubHeaders = $subHeaderKeys[$i];
+ }
}
+ // the number of subHeaders is equal to the max of subHeaderKeys + 1
+ ++$numSubHeaders;
+ // read subHeader structures
+ $subHeaders = array();
+ $numGlyphIndexArray = 0;
+ for ($k = 0; $k < $numSubHeaders; ++$k) {
+ $subHeaders[$k]['firstCode'] = $this->_getUSHORT($font, $offset);
+ $offset += 2;
+ $subHeaders[$k]['entryCount'] = $this->_getUSHORT($font, $offset);
+ $offset += 2;
+ $subHeaders[$k]['idDelta'] = $this->_getUSHORT($font, $offset);
+ $offset += 2;
+ $subHeaders[$k]['idRangeOffset'] = $this->_getUSHORT($font, $offset);
+ $offset += 2;
+ $subHeaders[$k]['idRangeOffset'] -= (2 + (($numSubHeaders - $k - 1) * 8));
+ $subHeaders[$k]['idRangeOffset'] /= 2;
+ $numGlyphIndexArray += $subHeaders[$k]['entryCount'];
+ }
+ for ($k = 0; $k < $numGlyphIndexArray; ++$k) {
+ $glyphIndexArray[$k] = $this->_getUSHORT($font, $offset);
+ $offset += 2;
+ }
+ for ($i = 0; $i < 256; ++$i) {
+ $k = $subHeaderKeys[$i];
+ if ($k == 0) {
+ // one byte code
+ $c = $i;
+ $g = $glyphIndexArray[0];
+ $ctg[$c] = $g;
+ } else {
+ // two bytes code
+ $start_byte = $subHeaders[$k]['firstCode'];
+ $end_byte = $start_byte + $subHeaders[$k]['entryCount'];
+ for ($j = $start_byte; $j < $end_byte; ++$j) {
+ // combine high and low bytes
+ $c = (($i << 8) + $j);
+ $idRangeOffset = ($subHeaders[$k]['idRangeOffset'] + $j - $subHeaders[$k]['firstCode']);
+ $g = ($glyphIndexArray[$idRangeOffset] + $idDelta[$k]) % 65536;
+ if ($g < 0) {
+ $g = 0;
+ }
+ $ctg[$c] = $g;
+ }
+ }
+ }
+ break;
}
- // the number of subHeaders is equal to the max of subHeaderKeys + 1
- ++$numSubHeaders;
- // read subHeader structures
- $subHeaders = array();
- $numGlyphIndexArray = 0;
- for ($k = 0; $k < $numSubHeaders; ++$k) {
- $subHeaders[$k]['firstCode'] = $this->_getUSHORT($font, $offset);
+ case 4: { // Format 4: Segment mapping to delta values
+ $length = $this->_getUSHORT($font, $offset);
$offset += 2;
- $subHeaders[$k]['entryCount'] = $this->_getUSHORT($font, $offset);
+ $offset += 2; // skip version/language
+ $segCount = ($this->_getUSHORT($font, $offset) / 2);
$offset += 2;
- $subHeaders[$k]['idDelta'] = $this->_getSHORT($font, $offset);
- $offset += 2;
- $subHeaders[$k]['idRangeOffset'] = $this->_getUSHORT($font, $offset);
- $offset += 2;
- $subHeaders[$k]['idRangeOffset'] -= (2 + (($numSubHeaders - $k - 1) * 8));
- $subHeaders[$k]['idRangeOffset'] /= 2;
- $numGlyphIndexArray += $subHeaders[$k]['entryCount'];
- }
- for ($k = 0; $k < $numGlyphIndexArray; ++$k) {
- $glyphIndexArray[$k] = $this->_getUSHORT($font, $offset);
- $offset += 2;
- }
- for ($i = 0; $i < 256; ++$i) {
- $k = $subHeaderKeys[$i];
- if ($k == 0) {
- // one byte code
- $c = $i;
- $g = $glyphIndexArray[0];
- $ctg[$c] = $g;
- } else {
- // two bytes code
- $start_byte = $subHeaders[$k]['firstCode'];
- $end_byte = $start_byte + $subHeaders[$k]['entryCount'];
- for ($j = $start_byte; $j < $end_byte; ++$j) {
- // combine high and low bytes
- $c = (($i << 8) + $j);
- $idRangeOffset = ($subHeaders[$k]['idRangeOffset'] + $j - $subHeaders[$k]['firstCode']);
- $g = $glyphIndexArray[$idRangeOffset];
- $g += ($idDelta[$k] - 65536);
+ $offset += 6; // skip searchRange, entrySelector, rangeShift
+ $endCount = array(); // array of end character codes for each segment
+ for ($k = 0; $k < $segCount; ++$k) {
+ $endCount[$k] = $this->_getUSHORT($font, $offset);
+ $offset += 2;
+ }
+ $offset += 2; // skip reservedPad
+ $startCount = array(); // array of start character codes for each segment
+ for ($k = 0; $k < $segCount; ++$k) {
+ $startCount[$k] = $this->_getUSHORT($font, $offset);
+ $offset += 2;
+ }
+ $idDelta = array(); // delta for all character codes in segment
+ for ($k = 0; $k < $segCount; ++$k) {
+ $idDelta[$k] = $this->_getUSHORT($font, $offset);
+ $offset += 2;
+ }
+ $idRangeOffset = array(); // Offsets into glyphIdArray or 0
+ for ($k = 0; $k < $segCount; ++$k) {
+ $idRangeOffset[$k] = $this->_getUSHORT($font, $offset);
+ $offset += 2;
+ }
+ $gidlen = ($length / 2) - 8 - (4 * $segCount);
+ $glyphIdArray = array(); // glyph index array
+ for ($k = 0; $k < $gidlen; ++$k) {
+ $glyphIdArray[$k] = $this->_getUSHORT($font, $offset);
+ $offset += 2;
+ }
+ for ($k = 0; $k < $segCount; ++$k) {
+ for ($c = $startCount[$k]; $c <= $endCount[$k]; ++$c) {
+ if ($idRangeOffset[$k] == 0) {
+ $g = ($idDelta[$k] + $c) % 65536;
+ } else {
+ $gid = (($idRangeOffset[$k] / 2) + ($c - $startCount[$k]) - ($segCount - $k));
+ $g = ($glyphIdArray[$gid] + $idDelta[$k]) % 65536;
+ }
if ($g < 0) {
$g = 0;
}
$ctg[$c] = $g;
}
}
+ break;
}
- break;
- }
- case 4: { // Format 4: Segment mapping to delta values
- $length = $this->_getUSHORT($font, $offset);
- $offset += 2;
- $offset += 2; // skip version/language
- $segCount = ($this->_getUSHORT($font, $offset) / 2);
- $offset += 2;
- $offset += 6; // skip searchRange, entrySelector, rangeShift
- $endCount = array(); // array of end character codes for each segment
- for ($k = 0; $k < $segCount; ++$k) {
- $endCount[$k] = $this->_getUSHORT($font, $offset);
+ case 6: { // Format 6: Trimmed table mapping
+ $offset += 4; // skip length and version/language
+ $firstCode = $this->_getUSHORT($font, $offset);
$offset += 2;
- }
- $offset += 2; // skip reservedPad
- $startCount = array(); // array of start character codes for each segment
- for ($k = 0; $k < $segCount; ++$k) {
- $startCount[$k] = $this->_getUSHORT($font, $offset);
+ $entryCount = $this->_getUSHORT($font, $offset);
$offset += 2;
+ for ($k = 0; $k < $entryCount; ++$k) {
+ $c = ($k + $firstCode);
+ $g = $this->_getUSHORT($font, $offset);
+ $offset += 2;
+ $ctg[$c] = $g;
+ }
+ break;
}
- $idDelta = array(); // delta for all character codes in segment
- for ($k = 0; $k < $segCount; ++$k) {
- $idDelta[$k] = $this->_getUSHORT($font, $offset);
- $offset += 2;
- }
- $idRangeOffset = array(); // Offsets into glyphIdArray or 0
- for ($k = 0; $k < $segCount; ++$k) {
- $idRangeOffset[$k] = $this->_getUSHORT($font, $offset);
- $offset += 2;
- }
- $gidlen = ($length / 2) - 8 - (4 * $segCount);
- $glyphIdArray = array(); // glyph index array
- for ($k = 0; $k < $gidlen; ++$k) {
- $glyphIdArray[$k] = $this->_getUSHORT($font, $offset);
- $offset += 2;
- }
- for ($k = 0; $k < $segCount; ++$k) {
- for ($c = $startCount[$k]; $c <= $endCount[$k]; ++$c) {
- if ($idRangeOffset[$k] == 0) {
- $g = $c;
- } else {
- $gid = (($idRangeOffset[$k] / 2) + ($c - $startCount[$k]) - ($segCount - $k));
- $g = $glyphIdArray[$gid];
+ case 8: { // Format 8: Mixed 16-bit and 32-bit coverage
+ $offset += 10; // skip reserved, length and version/language
+ for ($k = 0; $k < 8192; ++$k) {
+ $is32[$k] = $this->_getBYTE($font, $offset);
+ ++$offset;
+ }
+ $nGroups = $this->_getULONG($font, $offset);
+ $offset += 4;
+ for ($i = 0; $i < $nGroups; ++$i) {
+ $startCharCode = $this->_getULONG($font, $offset);
+ $offset += 4;
+ $endCharCode = $this->_getULONG($font, $offset);
+ $offset += 4;
+ $startGlyphID = $this->_getULONG($font, $offset);
+ $offset += 4;
+ for ($k = $startCharCode; $k <= $endCharCode; ++$k) {
+ $is32idx = floor($c / 8);
+ if ((isset($is32[$is32idx])) AND (($is32[$is32idx] & (1 << (7 - ($c % 8)))) == 0)) {
+ $c = $k;
+ } else {
+ // 32 bit format
+ // convert to decimal (http://www.unicode.org/faq//utf_bom.html#utf16-4)
+ //LEAD_OFFSET = (0xD800 - (0x10000 >> 10)) = 55232
+ //SURROGATE_OFFSET = (0x10000 - (0xD800 << 10) - 0xDC00) = -56613888
+ $c = ((55232 + ($k >> 10)) << 10) + (0xDC00 + ($k & 0x3FF)) -56613888;
+ }
+ $ctg[$c] = 0;
+ ++$startGlyphID;
}
- $g += ($idDelta[$k] - 65536);
- if ($g < 0) {
- $g = 0;
- }
- $ctg[$c] = $g;
}
+ break;
}
- break;
- }
- case 6: { // Format 6: Trimmed table mapping
- $offset += 4; // skip length and version/language
- $firstCode = $this->_getUSHORT($font, $offset);
- $offset += 2;
- $entryCount = $this->_getUSHORT($font, $offset);
- $offset += 2;
- for ($k = 0; $k < $entryCount; ++$k) {
- $c = ($k + $firstCode);
- $g = $this->_getUSHORT($font, $offset);
- $ctg[$c] = $g;
- $offset += 2;
- }
- break;
- }
- case 8: { // Format 8: Mixed 16-bit and 32-bit coverage
- $offset += 10; // skip reserved, length and version/language
- for ($k = 0; $k < 8192; ++$k) {
- $is32[$k] = $this->_getBYTE($font, $offset);
- ++$offset;
- }
- $nGroups = $this->_getULONG($font, $offset);
- $offset += 4;
- for ($i = 0; $i < $nGroups; ++$i) {
+ case 10: { // Format 10: Trimmed array
+ $offset += 10; // skip reserved, length and version/language
$startCharCode = $this->_getULONG($font, $offset);
$offset += 4;
- $endCharCode = $this->_getULONG($font, $offset);
+ $numChars = $this->_getULONG($font, $offset);
$offset += 4;
- $startGlyphID = $this->_getULONG($font, $offset);
- $offset += 4;
- for ($k = $startCharCode; $k <= $endCharCode; ++$k) {
- $is32idx = floor($c / 8);
- if ((isset($is32[$is32idx])) AND (($is32[$is32idx] & (1 << (7 - ($c % 8)))) == 0)) {
- $c = $k;
- } else {
- // 32 bit format
- // convert to decimal (http://www.unicode.org/faq//utf_bom.html#utf16-4)
- //LEAD_OFFSET = (0xD800 - (0x10000 >> 10)) = 55232
- //SURROGATE_OFFSET = (0x10000 - (0xD800 << 10) - 0xDC00) = -56613888
- $c = ((55232 + ($k >> 10)) << 10) + (0xDC00 + ($k & 0x3FF)) -56613888;
- }
+ for ($k = 0; $k < $numChars; ++$k) {
+ $c = ($k + $startCharCode);
+ $g = $this->_getUSHORT($font, $offset);
$ctg[$c] = $g;
- ++$startGlyphID;
+ $offset += 2;
}
+ break;
}
- break;
- }
- case 10: { // Format 10: Trimmed array
- $offset += 10; // skip reserved, length and version/language
- $startCharCode = $this->_getULONG($font, $offset);
- $offset += 4;
- $numChars = $this->_getULONG($font, $offset);
- $offset += 4;
- for ($k = 0; $k < $numChars; ++$k) {
- $c = ($k + $startCharCode);
- $g = $this->_getUSHORT($font, $offset);
- $ctg[$c] = $g;
- $offset += 2;
- }
- break;
- }
- case 12: { // Format 12: Segmented coverage
- $offset += 10; // skip length and version/language
- $nGroups = $this->_getULONG($font, $offset);
- $offset += 4;
- for ($k = 0; $k < $nGroups; ++$k) {
- $startCharCode = $this->_getULONG($font, $offset);
+ case 12: { // Format 12: Segmented coverage
+ $offset += 10; // skip length and version/language
+ $nGroups = $this->_getULONG($font, $offset);
$offset += 4;
- $endCharCode = $this->_getULONG($font, $offset);
- $offset += 4;
- $startGlyphCode = $this->_getULONG($font, $offset);
- $offset += 4;
- for ($c = $startCharCode; $c <= $endCharCode; ++$c) {
- $ctg[$c] = $startGlyphCode;
- ++$startGlyphCode;
+ for ($k = 0; $k < $nGroups; ++$k) {
+ $startCharCode = $this->_getULONG($font, $offset);
+ $offset += 4;
+ $endCharCode = $this->_getULONG($font, $offset);
+ $offset += 4;
+ $startGlyphCode = $this->_getULONG($font, $offset);
+ $offset += 4;
+ for ($c = $startCharCode; $c <= $endCharCode; ++$c) {
+ $ctg[$c] = $startGlyphCode;
+ ++$startGlyphCode;
+ }
}
+ break;
}
- break;
+ case 13: { // Format 13: Many-to-one range mappings
+ // to be implemented ...
+ break;
+ }
+ case 14: { // Format 14: Unicode Variation Sequences
+ // to be implemented ...
+ break;
+ }
}
- case 13: { // Format 13: Many-to-one range mappings
- // to be implemented ...
- break;
- }
- case 14: { // Format 14: Unicode Variation Sequences
- // to be implemented ...
- break;
- }
}
}
if (!isset($ctg[0])) {
@@ -10741,11 +10910,7 @@
$offset += 4;
}
foreach ($encodingTables as $enctable) {
- if (($enctable['platformID'] == 3) AND ($enctable['encodingID'] == 0)) {
- $modesymbol = true;
- } else {
- $modesymbol = false;
- }
+ // get all platforms and encodings
$offset = $table['cmap']['offset'] + $enctable['offset'];
$format = $this->_getUSHORT($font, $offset);
$offset += 2;
@@ -10782,7 +10947,7 @@
$offset += 2;
$subHeaders[$k]['entryCount'] = $this->_getUSHORT($font, $offset);
$offset += 2;
- $subHeaders[$k]['idDelta'] = $this->_getSHORT($font, $offset);
+ $subHeaders[$k]['idDelta'] = $this->_getUSHORT($font, $offset);
$offset += 2;
$subHeaders[$k]['idRangeOffset'] = $this->_getUSHORT($font, $offset);
$offset += 2;
@@ -10812,8 +10977,7 @@
$c = (($i << 8) + $j);
if (isset($subsetchars[$c])) {
$idRangeOffset = ($subHeaders[$k]['idRangeOffset'] + $j - $subHeaders[$k]['firstCode']);
- $g = $glyphIndexArray[$idRangeOffset];
- $g += ($idDelta[$k] - 65536);
+ $g = ($glyphIndexArray[$idRangeOffset] + $idDelta[$k]) % 65536;
if ($g < 0) {
$g = 0;
}
@@ -10862,12 +11026,11 @@...
[truncated message content] |