File indexing completed on 2025-01-19 05:21:21
0001 <?php 0002 /** 0003 * Zend Framework 0004 * 0005 * LICENSE 0006 * 0007 * This source file is subject to the new BSD license that is bundled 0008 * with this package in the file LICENSE.txt. 0009 * It is also available through the world-wide-web at this URL: 0010 * http://framework.zend.com/license/new-bsd 0011 * If you did not receive a copy of the license and are unable to 0012 * obtain it through the world-wide-web, please send an email 0013 * to license@zend.com so we can send you a copy immediately. 0014 * 0015 * @category Zend 0016 * @package Zend_Pdf 0017 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0018 * @license http://framework.zend.com/license/new-bsd New BSD License 0019 * @version $Id$ 0020 */ 0021 0022 0023 /** Zend_Pdf_Element */ 0024 // require_once 'Zend/Pdf/Element.php'; 0025 0026 /** 0027 * PDF file 'string' element implementation 0028 * 0029 * @category Zend 0030 * @package Zend_Pdf 0031 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0032 * @license http://framework.zend.com/license/new-bsd New BSD License 0033 */ 0034 class Zend_Pdf_Element_String extends Zend_Pdf_Element 0035 { 0036 /** 0037 * Object value 0038 * 0039 * @var string 0040 */ 0041 public $value; 0042 0043 /** 0044 * Object constructor 0045 * 0046 * @param string $val 0047 */ 0048 public function __construct($val) 0049 { 0050 $this->value = (string)$val; 0051 } 0052 0053 0054 /** 0055 * Return type of the element. 0056 * 0057 * @return integer 0058 */ 0059 public function getType() 0060 { 0061 return Zend_Pdf_Element::TYPE_STRING; 0062 } 0063 0064 0065 /** 0066 * Return object as string 0067 * 0068 * @param Zend_Pdf_Factory $factory 0069 * @return string 0070 */ 0071 public function toString($factory = null) 0072 { 0073 return '(' . self::escape((string)$this->value) . ')'; 0074 } 0075 0076 0077 /** 0078 * Escape string according to the PDF rules 0079 * 0080 * @param string $str 0081 * @return string 0082 */ 0083 public static function escape($str) 0084 { 0085 $outEntries = array(); 0086 0087 foreach (str_split($str, 128) as $chunk) { 0088 // Collect sequence of unescaped characters 0089 $offset = strcspn($chunk, "\n\r\t\x08\x0C()\\"); 0090 $chunkOut = substr($chunk, 0, $offset); 0091 0092 while ($offset < strlen($chunk)) { 0093 $nextCode = ord($chunk[$offset++]); 0094 switch ($nextCode) { 0095 // "\n" - line feed (LF) 0096 case 10: 0097 $chunkOut .= '\\n'; 0098 break; 0099 0100 // "\r" - carriage return (CR) 0101 case 13: 0102 $chunkOut .= '\\r'; 0103 break; 0104 0105 // "\t" - horizontal tab (HT) 0106 case 9: 0107 $chunkOut .= '\\t'; 0108 break; 0109 0110 // "\b" - backspace (BS) 0111 case 8: 0112 $chunkOut .= '\\b'; 0113 break; 0114 0115 // "\f" - form feed (FF) 0116 case 12: 0117 $chunkOut .= '\\f'; 0118 break; 0119 0120 // '(' - left paranthesis 0121 case 40: 0122 $chunkOut .= '\\('; 0123 break; 0124 0125 // ')' - right paranthesis 0126 case 41: 0127 $chunkOut .= '\\)'; 0128 break; 0129 0130 // '\' - backslash 0131 case 92: 0132 $chunkOut .= '\\\\'; 0133 break; 0134 0135 default: 0136 // This code is never executed extually 0137 // 0138 // Don't use non-ASCII characters escaping 0139 // if ($nextCode >= 32 && $nextCode <= 126 ) { 0140 // // Visible ASCII symbol 0141 // $chunkEntries[] = chr($nextCode); 0142 // } else { 0143 // $chunkEntries[] = sprintf('\\%03o', $nextCode); 0144 // } 0145 0146 break; 0147 } 0148 0149 // Collect sequence of unescaped characters 0150 $start = $offset; 0151 $offset += strcspn($chunk, "\n\r\t\x08\x0C()\\", $offset); 0152 $chunkOut .= substr($chunk, $start, $offset - $start); 0153 } 0154 0155 $outEntries[] = $chunkOut; 0156 } 0157 0158 return implode("\\\n", $outEntries); 0159 } 0160 0161 0162 /** 0163 * Unescape string according to the PDF rules 0164 * 0165 * @param string $str 0166 * @return string 0167 */ 0168 public static function unescape($str) 0169 { 0170 $outEntries = array(); 0171 0172 $offset = 0; 0173 while ($offset < strlen($str)) { 0174 // Searche for the next escaped character/sequence 0175 $escapeCharOffset = strpos($str, '\\', $offset); 0176 if ($escapeCharOffset === false || $escapeCharOffset == strlen($str) - 1) { 0177 // There are no escaped characters or '\' char has came at the end of string 0178 $outEntries[] = substr($str, $offset); 0179 break; 0180 } else { 0181 // Collect unescaped characters sequence 0182 $outEntries[] = substr($str, $offset, $escapeCharOffset - $offset); 0183 // Go to the escaped character 0184 $offset = $escapeCharOffset + 1; 0185 0186 switch ($str[$offset]) { 0187 // '\\n' - line feed (LF) 0188 case 'n': 0189 $outEntries[] = "\n"; 0190 break; 0191 0192 // '\\r' - carriage return (CR) 0193 case 'r': 0194 $outEntries[] = "\r"; 0195 break; 0196 0197 // '\\t' - horizontal tab (HT) 0198 case 't': 0199 $outEntries[] = "\t"; 0200 break; 0201 0202 // '\\b' - backspace (BS) 0203 case 'b': 0204 $outEntries[] = "\x08"; 0205 break; 0206 0207 // '\\f' - form feed (FF) 0208 case 'f': 0209 $outEntries[] = "\x0C"; 0210 break; 0211 0212 // '\\(' - left paranthesis 0213 case '(': 0214 $outEntries[] = '('; 0215 break; 0216 0217 // '\\)' - right paranthesis 0218 case ')': 0219 $outEntries[] = ')'; 0220 break; 0221 0222 // '\\\\' - backslash 0223 case '\\': 0224 $outEntries[] = '\\'; 0225 break; 0226 0227 // "\\\n" or "\\\n\r" 0228 case "\n": 0229 // skip new line symbol 0230 if ($str[$offset + 1] == "\r") { 0231 $offset++; 0232 } 0233 break; 0234 0235 default: 0236 if (strpos('0123456789', $str[$offset]) !== false) { 0237 // Character in octal representation 0238 // '\\xxx' 0239 $nextCode = '0' . $str[$offset]; 0240 0241 if (strpos('0123456789', $str[$offset + 1]) !== false) { 0242 $nextCode .= $str[++$offset]; 0243 0244 if (strpos('0123456789', $str[$offset + 1]) !== false) { 0245 $nextCode .= $str[++$offset]; 0246 } 0247 } 0248 0249 $outEntries[] = chr(octdec($nextCode)); 0250 } else { 0251 $outEntries[] = $str[$offset]; 0252 } 0253 break; 0254 } 0255 0256 $offset++; 0257 } 0258 } 0259 0260 return implode($outEntries); 0261 } 0262 0263 }