You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

263 lines
7.7 KiB

11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Pdf
  17. * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
  18. * @license http://framework.zend.com/license/new-bsd New BSD License
  19. * @version $Id$
  20. */
  21. /** Zend_Pdf_Element */
  22. // require_once 'Zend/Pdf/Element.php';
  23. /**
  24. * PDF file 'string' element implementation
  25. *
  26. * @category Zend
  27. * @package Zend_Pdf
  28. * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
  29. * @license http://framework.zend.com/license/new-bsd New BSD License
  30. */
  31. class Zend_Pdf_Element_String extends Zend_Pdf_Element
  32. {
  33. /**
  34. * Object value
  35. *
  36. * @var string
  37. */
  38. public $value;
  39. /**
  40. * Object constructor
  41. *
  42. * @param string $val
  43. */
  44. public function __construct($val)
  45. {
  46. $this->value = (string)$val;
  47. }
  48. /**
  49. * Return type of the element.
  50. *
  51. * @return integer
  52. */
  53. public function getType()
  54. {
  55. return Zend_Pdf_Element::TYPE_STRING;
  56. }
  57. /**
  58. * Return object as string
  59. *
  60. * @param Zend_Pdf_Factory $factory
  61. * @return string
  62. */
  63. public function toString($factory = null)
  64. {
  65. return '(' . self::escape((string)$this->value) . ')';
  66. }
  67. /**
  68. * Escape string according to the PDF rules
  69. *
  70. * @param string $str
  71. * @return string
  72. */
  73. public static function escape($str)
  74. {
  75. $outEntries = array();
  76. foreach (str_split($str, 128) as $chunk) {
  77. // Collect sequence of unescaped characters
  78. $offset = strcspn($chunk, "\n\r\t\x08\x0C()\\");
  79. $chunkOut = substr($chunk, 0, $offset);
  80. while ($offset < strlen($chunk)) {
  81. $nextCode = ord($chunk[$offset++]);
  82. switch ($nextCode) {
  83. // "\n" - line feed (LF)
  84. case 10:
  85. $chunkOut .= '\\n';
  86. break;
  87. // "\r" - carriage return (CR)
  88. case 13:
  89. $chunkOut .= '\\r';
  90. break;
  91. // "\t" - horizontal tab (HT)
  92. case 9:
  93. $chunkOut .= '\\t';
  94. break;
  95. // "\b" - backspace (BS)
  96. case 8:
  97. $chunkOut .= '\\b';
  98. break;
  99. // "\f" - form feed (FF)
  100. case 12:
  101. $chunkOut .= '\\f';
  102. break;
  103. // '(' - left paranthesis
  104. case 40:
  105. $chunkOut .= '\\(';
  106. break;
  107. // ')' - right paranthesis
  108. case 41:
  109. $chunkOut .= '\\)';
  110. break;
  111. // '\' - backslash
  112. case 92:
  113. $chunkOut .= '\\\\';
  114. break;
  115. default:
  116. // This code is never executed extually
  117. //
  118. // Don't use non-ASCII characters escaping
  119. // if ($nextCode >= 32 && $nextCode <= 126 ) {
  120. // // Visible ASCII symbol
  121. // $chunkEntries[] = chr($nextCode);
  122. // } else {
  123. // $chunkEntries[] = sprintf('\\%03o', $nextCode);
  124. // }
  125. break;
  126. }
  127. // Collect sequence of unescaped characters
  128. $start = $offset;
  129. $offset += strcspn($chunk, "\n\r\t\x08\x0C()\\", $offset);
  130. $chunkOut .= substr($chunk, $start, $offset - $start);
  131. }
  132. $outEntries[] = $chunkOut;
  133. }
  134. return implode("\\\n", $outEntries);
  135. }
  136. /**
  137. * Unescape string according to the PDF rules
  138. *
  139. * @param string $str
  140. * @return string
  141. */
  142. public static function unescape($str)
  143. {
  144. $outEntries = array();
  145. $offset = 0;
  146. while ($offset < strlen($str)) {
  147. // Searche for the next escaped character/sequence
  148. $escapeCharOffset = strpos($str, '\\', $offset);
  149. if ($escapeCharOffset === false || $escapeCharOffset == strlen($str) - 1) {
  150. // There are no escaped characters or '\' char has came at the end of string
  151. $outEntries[] = substr($str, $offset);
  152. break;
  153. } else {
  154. // Collect unescaped characters sequence
  155. $outEntries[] = substr($str, $offset, $escapeCharOffset - $offset);
  156. // Go to the escaped character
  157. $offset = $escapeCharOffset + 1;
  158. switch ($str[$offset]) {
  159. // '\\n' - line feed (LF)
  160. case 'n':
  161. $outEntries[] = "\n";
  162. break;
  163. // '\\r' - carriage return (CR)
  164. case 'r':
  165. $outEntries[] = "\r";
  166. break;
  167. // '\\t' - horizontal tab (HT)
  168. case 't':
  169. $outEntries[] = "\t";
  170. break;
  171. // '\\b' - backspace (BS)
  172. case 'b':
  173. $outEntries[] = "\x08";
  174. break;
  175. // '\\f' - form feed (FF)
  176. case 'f':
  177. $outEntries[] = "\x0C";
  178. break;
  179. // '\\(' - left paranthesis
  180. case '(':
  181. $outEntries[] = '(';
  182. break;
  183. // '\\)' - right paranthesis
  184. case ')':
  185. $outEntries[] = ')';
  186. break;
  187. // '\\\\' - backslash
  188. case '\\':
  189. $outEntries[] = '\\';
  190. break;
  191. // "\\\n" or "\\\n\r"
  192. case "\n":
  193. // skip new line symbol
  194. if ($str[$offset + 1] == "\r") {
  195. $offset++;
  196. }
  197. break;
  198. default:
  199. if (strpos('0123456789', $str[$offset]) !== false) {
  200. // Character in octal representation
  201. // '\\xxx'
  202. $nextCode = '0' . $str[$offset];
  203. if (strpos('0123456789', $str[$offset + 1]) !== false) {
  204. $nextCode .= $str[++$offset];
  205. if (strpos('0123456789', $str[$offset + 1]) !== false) {
  206. $nextCode .= $str[++$offset];
  207. }
  208. }
  209. $outEntries[] = chr(octdec($nextCode));
  210. } else {
  211. $outEntries[] = $str[$offset];
  212. }
  213. break;
  214. }
  215. $offset++;
  216. }
  217. }
  218. return implode($outEntries);
  219. }
  220. }