From df9b495d27c0665872c217ef7e216ffd4bdb30e3 Mon Sep 17 00:00:00 2001 From: nick Date: Wed, 25 Jul 2012 15:16:42 +0100 Subject: [PATCH] 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. --- CHANGELOG.TXT | 9 ++ README.TXT | 4 +- config/lang/ukr.php | 47 ++++++++++ examples/example_001.php | 8 +- qrcode.php | 22 ++--- tcpdf.php | 193 ++++++++++++++++++++++++++++++++++----- 6 files changed, 245 insertions(+), 38 deletions(-) create mode 100644 config/lang/ukr.php diff --git a/CHANGELOG.TXT b/CHANGELOG.TXT index d747939..271bfd3 100755 --- a/CHANGELOG.TXT +++ b/CHANGELOG.TXT @@ -1,3 +1,12 @@ +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. diff --git a/README.TXT b/README.TXT index 3f0ea8f..5934f93 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.173 -Release date: 2012-07-23 +Version: 5.9.174 +Release date: 2012-07-25 Author: Nicola Asuni Copyright (c) 2002-2012: diff --git a/config/lang/ukr.php b/config/lang/ukr.php new file mode 100644 index 0000000..dbf567d --- /dev/null +++ b/config/lang/ukr.php @@ -0,0 +1,47 @@ +SetSubject('TCPDF Tutorial'); $pdf->SetKeywords('TCPDF, PDF, example, test, guide'); // set default header data -$pdf->SetHeaderData(PDF_HEADER_LOGO, PDF_HEADER_LOGO_WIDTH, PDF_HEADER_TITLE.' 001', PDF_HEADER_STRING); +$pdf->SetHeaderData(PDF_HEADER_LOGO, PDF_HEADER_LOGO_WIDTH, PDF_HEADER_TITLE.' 001', PDF_HEADER_STRING, array(0,64,255), array(0,64,128)); +$pdf->setFooterData($tc=array(0,64,0), $lc=array(0,64,128)); // set header and footer fonts $pdf->setHeaderFont(Array(PDF_FONT_NAME_MAIN, '', PDF_FONT_SIZE_MAIN)); @@ -79,6 +80,9 @@ $pdf->SetFont('dejavusans', '', 14, '', true); // This method has several options, check the source code documentation for more information. $pdf->AddPage(); +// set text shadow effect +$pdf->setTextShadow(array('enabled'=>true, 'depth_w'=>0.2, 'depth_h'=>0.2, 'color'=>array(196,196,196), 'opacity'=>1, 'blend_mode'=>'Normal')); + // Set some content to print $html = <<Welcome to  TCPDF ! diff --git a/qrcode.php b/qrcode.php index 1fab6b5..93b05cb 100755 --- a/qrcode.php +++ b/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/tcpdf.php b/tcpdf.php index 0b846c7..11a3261 100755 --- a/tcpdf.php +++ b/tcpdf.php @@ -1,9 +1,9 @@ * @package com.tecnick.tcpdf * @author Nicola Asuni - * @version 5.9.173 + * @version 5.9.174 */ // 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.173 + * @version 5.9.174 * @author Nicola Asuni - info@tecnick.com */ class TCPDF { @@ -160,7 +161,7 @@ class TCPDF { * Current TCPDF version. * @private */ - private $tcpdf_version = '5.9.173'; + private $tcpdf_version = '5.9.174'; // Protected properties @@ -711,6 +712,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 @@ -2019,6 +2055,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; @@ -4097,13 +4134,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; } /** @@ -4119,6 +4171,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; } @@ -4252,7 +4306,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); @@ -4262,7 +4316,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); @@ -4298,10 +4352,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)) { @@ -4944,7 +4998,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; } @@ -5845,6 +5899,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; @@ -7261,9 +7344,21 @@ class TCPDF { // \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; + if ($c == 45) { + ++$sep; + } // check if is a SHY if ($c == 173) { $shy = true; @@ -8851,7 +8946,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(); @@ -8882,7 +8977,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; @@ -8909,7 +9004,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 @@ -8934,7 +9029,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)); } @@ -19315,7 +19410,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') { @@ -19323,8 +19418,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; @@ -20095,7 +20190,7 @@ class TCPDF { // create new barcode object $barcodeobj = new TCPDF2DBarcode($code, $type); $arrcode = $barcodeobj->getBarcodeArray(); - if (($arrcode === false) OR empty($arrcode) OR ($arrcode['num_rows'] == 0) OR ($arrcode['num_cols'] == 0)) { + 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 @@ -21648,7 +21743,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]); @@ -26879,6 +26974,58 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value: $this->textstrokewidth = $stroke * $this->k; } + /** + * 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; + } + /** * Returns an array of chars containing soft hyphens. * @param $word (array) array of chars