diff --git a/CHANGELOG.TXT b/CHANGELOG.TXT
index 368af52..2fb5ed4 100755
--- a/CHANGELOG.TXT
+++ b/CHANGELOG.TXT
@@ -1,3 +1,7 @@
+5.9.102 (2011-07-13)
+ - Methods startLayer() and endLayer() were added to support arbitrary PDF layers.
+ - Some improvements/fixes for images were added (thanks to Brendan Abbott).
+
5.9.101 (2011-07-07)
- Support for JPEG and PNG ICC Color Profiles was added.
- Method addEmptySignatureAppearance() was added to add empty signature fields (see example n. 52).
diff --git a/README.TXT b/README.TXT
index 4bfd86b..cdfcf50 100755
--- a/README.TXT
+++ b/README.TXT
@@ -8,8 +8,8 @@ http://sourceforge.net/donate/index.php?group_id=128076
------------------------------------------------------------
Name: TCPDF
-Version: 5.9.101
-Release date: 2011-07-07
+Version: 5.9.102
+Release date: 2011-07-13
Author: Nicola Asuni
Copyright (c) 2002-2011:
@@ -53,6 +53,7 @@ Main Features:
* move and delete pages;
* page compression (requires php-zlib extension);
* XOBject Templates;
+ * Layers and object visibility.
Installation (full instructions on http: www.tcpdf.org):
1. copy the folder on your Web server
diff --git a/examples/example_024.php b/examples/example_024.php
index 2d53a5e..8c0cf8f 100755
--- a/examples/example_024.php
+++ b/examples/example_024.php
@@ -5,7 +5,7 @@
// Last Update : 2010-08-08
//
// Description : Example 024 for TCPDF class
-// Object Visibility
+// Object Visibility and Layers
//
// Author: Nicola Asuni
//
@@ -22,7 +22,7 @@
/**
* Creates an example PDF TEST document using TCPDF
* @package com.tecnick.tcpdf
- * @abstract TCPDF - Example: Object Visibility
+ * @abstract TCPDF - Example: Object Visibility and Layers
* @author Nicola Asuni
* @since 2008-03-04
*/
@@ -110,6 +110,28 @@ $pdf->setVisibility('all');
// ---------------------------------------------------------
+// LAYERS
+
+// start a new layer
+$pdf->startLayer('layer1', true, true);
+
+// change font size
+$pdf->SetFontSize(18);
+
+// change text color
+$pdf->SetTextColor(0,127,0);
+
+$txt = 'Using the startLayer() method you can group PDF objects into layers.
+This text is on "layer1".';
+
+// write something
+$pdf->Write(0, $txt, '', 0, 'L', true, 0, false, false, 0);
+
+// close the current layer
+$pdf->endLayer();
+
+// ---------------------------------------------------------
+
//Close and output PDF document
$pdf->Output('example_024.pdf', 'I');
diff --git a/examples/index.php b/examples/index.php
index 00a095d..81ee89c 100644
--- a/examples/index.php
+++ b/examples/index.php
@@ -41,7 +41,7 @@ echo '<'.'?'.'xml version="1.0" encoding="UTF-8"'.'?'.'>';
writeHTML alignment: [PDF]
CMYK colors: [PDF]
Page Groups: [PDF]
-Object Visibility: [PDF]
+Object Visibility and Layers: [PDF]
Object Transparency: [PDF]
Text Rendering Modes and Text Clipping: [PDF]
Barcodes: [PDF]
diff --git a/tcpdf.php b/tcpdf.php
index ec5d73f..6aa7eb4 100755
--- a/tcpdf.php
+++ b/tcpdf.php
@@ -1,9 +1,9 @@
move and delete pages;
* page compression (requires php-zlib extension);
* XOBject Templates;
+ * Layers and object visibility;
*
* Tools to encode your unicode fonts are on fonts/utils directory.
* @package com.tecnick.tcpdf
* @author Nicola Asuni
- * @version 5.9.101
+ * @version 5.9.102
*/
// Main configuration file. Define the K_TCPDF_EXTERNAL_CONFIG constant to skip this file.
@@ -146,7 +148,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.101
+ * @version 5.9.102
* @author Nicola Asuni - info@tecnick.com
*/
class TCPDF {
@@ -157,7 +159,7 @@ class TCPDF {
* Current TCPDF version.
* @private
*/
- private $tcpdf_version = '5.9.101';
+ private $tcpdf_version = '5.9.102';
// Protected properties
@@ -913,27 +915,6 @@ class TCPDF {
*/
protected $currpagegroup = 0;
- /**
- * Restrict the rendering of some elements to screen or printout.
- * @protected
- * @since 3.0.000 (2008-03-27)
- */
- protected $visibility = 'all';
-
- /**
- * Print visibility.
- * @protected
- * @since 3.0.000 (2008-03-27)
- */
- protected $n_ocg_print;
-
- /**
- * View visibility.
- * @protected
- * @since 3.0.000 (2008-03-27)
- */
- protected $n_ocg_view;
-
/**
* Array of transparency objects and parameters.
* @protected
@@ -1629,11 +1610,11 @@ class TCPDF {
protected $spotcolor = array();
/**
- * Boolean value true when PDF layers are used.
+ * Array of PDF layers data.
* @protected
- * @since 5.9.046 (2011-01-18)
+ * @since 5.9.102 (2011-07-13)
*/
- protected $pdflayers = false;
+ protected $pdflayers = array();
/**
* A dictionary of names and corresponding destinations (Dests key on document Catalog).
@@ -1882,7 +1863,7 @@ class TCPDF {
$this->FillColor = '0 g';
$this->TextColor = '0 g';
$this->ColorFlag = false;
- $this->pdflayers = false;
+ $this->pdflayers = array();
// encryption values
$this->encrypted = false;
$this->last_enc_key = '';
@@ -3704,6 +3685,7 @@ class TCPDF {
if ($this->page == 0) {
$this->AddPage();
}
+ $this->endLayer();
// save current graphic settings
$gvars = $this->getGraphicVars();
$this->setEqualColumns();
@@ -7387,6 +7369,7 @@ 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);
curl_setopt($cs, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($cs, CURLOPT_TIMEOUT, 30);
$imgdata = curl_exec($cs);
@@ -11002,9 +10985,13 @@ class TCPDF {
$out .= ' /XObject <<';
$out .= $this->_getxobjectdict();
$out .= ' >>';
- // visibility
- if ($this->pdflayers) {
- $out .= ' /Properties <n_ocg_print.' 0 R /OC2 '.$this->n_ocg_view.' 0 R>>';
+ // layers
+ if (!empty($this->pdflayers)) {
+ $out .= ' /Properties <<';
+ foreach ($this->pdflayers as $layer) {
+ $out .= ' /'.$layer['layer'].' '.$layer['objid'].' 0 R';
+ }
+ $out .= ' >>';
}
// transparency
$out .= ' /ExtGState <<';
@@ -11169,11 +11156,26 @@ class TCPDF {
//$out .= ' /SpiderInfo <<>>';
//$out .= ' /OutputIntents []';
//$out .= ' /PieceInfo <<>>';
- if ($this->pdflayers) {
- $p = $this->n_ocg_print.' 0 R';
- $v = $this->n_ocg_view.' 0 R';
- $as = '<< /Event /Print /OCGs ['.$p.' '.$v.'] /Category [/Print] >> << /Event /View /OCGs ['.$p.' '.$v.'] /Category [/View] >>';
- $out .= ' /OCProperties << /OCGs ['.$p.' '.$v.'] /D << /ON ['.$p.'] /OFF ['.$v.'] /AS ['.$as.'] >> >>';
+ if (!empty($this->pdflayers)) {
+ $lyrobjs = '';
+ $lyrobjs_print = '';
+ $lyrobjs_view = '';
+ foreach ($this->pdflayers as $layer) {
+ $lyrobjs .= ' '.$layer['objid'].' 0 R';
+ if ($layer['print']) {
+ $lyrobjs_print .= ' '.$layer['objid'].' 0 R';
+ }
+ if ($layer['view']) {
+ $lyrobjs_view .= ' '.$layer['objid'].' 0 R';
+ }
+ }
+ $out .= ' /OCProperties << /OCGs ['.$lyrobjs.']';
+ $out .= ' /D << /ON ['.$lyrobjs_print.']';
+ $out .= ' /OFF ['.$lyrobjs_view.']';
+ $out .= ' /AS [';
+ $out .= '<< /Event /Print /OCGs ['.$lyrobjs.'] /Category [/Print] >> << /Event /View /OCGs ['.$lyrobjs.'] /Category [/View] >>';
+ $out .= ' ]';
+ $out .= ' >> >>';
}
// AcroForm
if (!empty($this->form_obj_id) OR ($this->sign AND isset($this->signature_data['cert_type']))) {
@@ -16438,16 +16440,57 @@ class TCPDF {
}
/**
- * Put visibility settings.
+ * Put pdf layers.
* @protected
* @since 3.0.000 (2008-03-27)
*/
protected function _putocg() {
- if ($this->pdflayers) {
- $this->n_ocg_print = $this->_newobj();
- $this->_out('<< /Type /OCG /Name '.$this->_textstring('print', $this->n_ocg_print).' /Usage << /Print <> /View <> >> >>'."\n".'endobj');
- $this->n_ocg_view = $this->_newobj();
- $this->_out('<< /Type /OCG /Name '.$this->_textstring('view', $this->n_ocg_view).' /Usage << /Print <> /View <> >> >>'."\n".'endobj');
+ if (empty($this->pdflayers)) {
+ return;
+ }
+ foreach ($this->pdflayers as $key => $layer) {
+ $this->pdflayers[$key]['objid'] = $this->_newobj();
+ $out = '<< /Type /OCG';
+ $out .= ' /Name '.$this->_textstring($layer['name'], $this->pdflayers[$key]['objid']);
+ $out .= ' /Usage <<';
+ $out .= ' /Print <>';
+ $out .= ' /View <>';
+ $out .= ' >> >>';
+ $out .= "\n".'endobj';
+ $this->_out($out);
+ }
+ }
+
+ /**
+ * Start a new pdf layer.
+ * @param $name (string) Layer name (only a-z letters and numbers). Leave empty for automatic name.
+ * @param $print (boolean) Set to true to print this layer.
+ * @param $view (boolean) Set to true to view this layer.
+ * @public
+ * @since 5.9.102 (2011-07-13)
+ */
+ public function startLayer($name='', $print=true, $view=true) {
+ $layer = sprintf('LYR%03d', (count($this->pdflayers) + 1));
+ if (empty($name)) {
+ $name = $layer;
+ } else {
+ $name = preg_replace('/[^a-zA-Z0-9_]/', '', $name);
+ }
+ $this->pdflayers[] = array('layer' => $layer, 'name' => $name, 'print' => $print, 'view' => $view);
+ $this->openMarkedContent = true;
+ $this->_out('/OC /'.$layer.' BDC');
+ }
+
+ /**
+ * End the current PDF layer.
+ * @public
+ * @since 5.9.102 (2011-07-13)
+ */
+ public function endLayer() {
+ if ($this->openMarkedContent) {
+ // close existing open marked-content layer
+ $this->_out('EMC');
+ $this->openMarkedContent = false;
}
}
@@ -16455,27 +16498,20 @@ class TCPDF {
* Set the visibility of the successive elements.
* This can be useful, for instance, to put a background
* image or color that will show on screen but won't print.
- * @param $v (string) visibility mode. Legal values are: all, print, screen.
+ * @param $v (string) visibility mode. Legal values are: all, print, screen or view.
* @public
* @since 3.0.000 (2008-03-27)
*/
public function setVisibility($v) {
- if ($this->openMarkedContent) {
- // close existing open marked-content
- $this->_out('EMC');
- $this->openMarkedContent = false;
- }
+ $this->endLayer();
switch($v) {
case 'print': {
- $this->_out('/OC /OC1 BDC');
- $this->openMarkedContent = true;
- $this->pdflayers = true;
+ $this->startLayer('Print', true, false);
break;
}
+ case 'view':
case 'screen': {
- $this->_out('/OC /OC2 BDC');
- $this->openMarkedContent = true;
- $this->pdflayers = true;
+ $this->startLayer('View', false, true);
break;
}
case 'all': {
@@ -16487,7 +16523,6 @@ class TCPDF {
break;
}
}
- $this->visibility = $v;
}
/**
@@ -21566,6 +21601,10 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
}
case 'img': {
if (isset($tag['attribute']['src'])) {
+ // check for images without protocol
+ if (preg_match('%^/{2}%', $tag['attribute']['src'])) {
+ $tag['attribute']['src'] = 'http:'.$tag['attribute']['src'];
+ }
// replace relative path with real server path
if (($tag['attribute']['src'][0] == '/') AND !empty($_SERVER['DOCUMENT_ROOT']) AND ($_SERVER['DOCUMENT_ROOT'] != '/')) {
$findroot = strpos($tag['attribute']['src'], $_SERVER['DOCUMENT_ROOT']);
@@ -21577,7 +21616,7 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
}
}
}
- $tag['attribute']['src'] = urldecode($tag['attribute']['src']);
+ $tag['attribute']['src'] = htmlspecialchars_decode(urldecode($tag['attribute']['src']));
$type = $this->getImageFileType($tag['attribute']['src']);
$testscrtype = @parse_url($tag['attribute']['src']);
if (!isset($testscrtype['query']) OR empty($testscrtype['query'])) {