web/lib/Zend/Pdf/Element/String.php
changeset 64 162c1de6545a
parent 19 1c2f13fd785c
child 68 ecaf28ffe26e
equal deleted inserted replaced
63:5b37998e522e 64:162c1de6545a
       
     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-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    18  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    19  * @version    $Id: String.php 21542 2010-03-18 08:56:40Z bate $
       
    20  */
       
    21 
       
    22 
       
    23 /** Zend_Pdf_Element */
       
    24 require_once 'Zend/Pdf/Element.php';
       
    25 
       
    26 /**
       
    27  * PDF file 'string' element implementation
       
    28  *
       
    29  * @category   Zend
       
    30  * @package    Zend_Pdf
       
    31  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    32  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    33  */
       
    34 class Zend_Pdf_Element_String extends Zend_Pdf_Element
       
    35 {
       
    36     /**
       
    37      * Object value
       
    38      *
       
    39      * @var string
       
    40      */
       
    41     public $value;
       
    42 
       
    43     /**
       
    44      * Object constructor
       
    45      *
       
    46      * @param string $val
       
    47      */
       
    48     public function __construct($val)
       
    49     {
       
    50         $this->value   = (string)$val;
       
    51     }
       
    52 
       
    53 
       
    54     /**
       
    55      * Return type of the element.
       
    56      *
       
    57      * @return integer
       
    58      */
       
    59     public function getType()
       
    60     {
       
    61         return Zend_Pdf_Element::TYPE_STRING;
       
    62     }
       
    63 
       
    64 
       
    65     /**
       
    66      * Return object as string
       
    67      *
       
    68      * @param Zend_Pdf_Factory $factory
       
    69      * @return string
       
    70      */
       
    71     public function toString($factory = null)
       
    72     {
       
    73         return '(' . self::escape((string)$this->value) . ')';
       
    74     }
       
    75 
       
    76 
       
    77     /**
       
    78      * Escape string according to the PDF rules
       
    79      *
       
    80      * @param string $str
       
    81      * @return string
       
    82      */
       
    83     public static function escape($str)
       
    84     {
       
    85         $outEntries = array();
       
    86 
       
    87         foreach (str_split($str, 128) as $chunk) {
       
    88             // Collect sequence of unescaped characters
       
    89             $offset = strcspn($chunk, "\n\r\t\x08\x0C()\\");
       
    90             $chunkOut = substr($chunk, 0, $offset);
       
    91 
       
    92             while ($offset < strlen($chunk)) {
       
    93                 $nextCode = ord($chunk[$offset++]);
       
    94                 switch ($nextCode) {
       
    95                     // "\n" - line feed (LF)
       
    96                     case 10:
       
    97                         $chunkOut .= '\\n';
       
    98                         break;
       
    99 
       
   100                     // "\r" - carriage return (CR)
       
   101                     case 13:
       
   102                         $chunkOut .= '\\r';
       
   103                         break;
       
   104 
       
   105                     // "\t" - horizontal tab (HT)
       
   106                     case 9:
       
   107                         $chunkOut .= '\\t';
       
   108                         break;
       
   109 
       
   110                     // "\b" - backspace (BS)
       
   111                     case 8:
       
   112                         $chunkOut .= '\\b';
       
   113                         break;
       
   114 
       
   115                     // "\f" - form feed (FF)
       
   116                     case 12:
       
   117                         $chunkOut .= '\\f';
       
   118                         break;
       
   119 
       
   120                     // '(' - left paranthesis
       
   121                     case 40:
       
   122                         $chunkOut .= '\\(';
       
   123                         break;
       
   124 
       
   125                     // ')' - right paranthesis
       
   126                     case 41:
       
   127                         $chunkOut .= '\\)';
       
   128                         break;
       
   129 
       
   130                     // '\' - backslash
       
   131                     case 92:
       
   132                         $chunkOut .= '\\\\';
       
   133                         break;
       
   134 
       
   135                     default:
       
   136                         // This code is never executed extually
       
   137                         //
       
   138                         // Don't use non-ASCII characters escaping
       
   139                         // if ($nextCode >= 32 && $nextCode <= 126 ) {
       
   140                         //     // Visible ASCII symbol
       
   141                         //     $chunkEntries[] = chr($nextCode);
       
   142                         // } else {
       
   143                         //     $chunkEntries[] = sprintf('\\%03o', $nextCode);
       
   144                         // }
       
   145 
       
   146                         break;
       
   147                 }
       
   148 
       
   149                 // Collect sequence of unescaped characters
       
   150                 $start = $offset;
       
   151                 $offset += strcspn($chunk, "\n\r\t\x08\x0C()\\", $offset);
       
   152                 $chunkOut .= substr($chunk, $start, $offset - $start);
       
   153             }
       
   154 
       
   155             $outEntries[] = $chunkOut;
       
   156         }
       
   157 
       
   158         return implode("\\\n", $outEntries);
       
   159     }
       
   160 
       
   161 
       
   162     /**
       
   163      * Unescape string according to the PDF rules
       
   164      *
       
   165      * @param string $str
       
   166      * @return string
       
   167      */
       
   168     public static function unescape($str)
       
   169     {
       
   170         $outEntries = array();
       
   171 
       
   172         $offset = 0;
       
   173         while ($offset < strlen($str)) {
       
   174             // Searche for the next escaped character/sequence
       
   175             $escapeCharOffset = strpos($str, '\\', $offset);
       
   176             if ($escapeCharOffset === false  ||  $escapeCharOffset == strlen($str) - 1) {
       
   177                 // There are no escaped characters or '\' char has came at the end of string
       
   178                 $outEntries[] = substr($str, $offset);
       
   179                 break;
       
   180             } else {
       
   181                 // Collect unescaped characters sequence
       
   182                 $outEntries[] = substr($str, $offset, $escapeCharOffset - $offset);
       
   183                 // Go to the escaped character
       
   184                 $offset = $escapeCharOffset + 1;
       
   185 
       
   186                 switch ($str[$offset]) {
       
   187                     // '\\n' - line feed (LF)
       
   188                     case 'n':
       
   189                         $outEntries[] = "\n";
       
   190                         break;
       
   191 
       
   192                     // '\\r' - carriage return (CR)
       
   193                     case 'r':
       
   194                         $outEntries[] = "\r";
       
   195                         break;
       
   196 
       
   197                     // '\\t' - horizontal tab (HT)
       
   198                     case 't':
       
   199                         $outEntries[] = "\t";
       
   200                         break;
       
   201 
       
   202                     // '\\b' - backspace (BS)
       
   203                     case 'b':
       
   204                         $outEntries[] = "\x08";
       
   205                         break;
       
   206 
       
   207                     // '\\f' - form feed (FF)
       
   208                     case 'f':
       
   209                         $outEntries[] = "\x0C";
       
   210                         break;
       
   211 
       
   212                     // '\\(' - left paranthesis
       
   213                     case '(':
       
   214                         $outEntries[] = '(';
       
   215                         break;
       
   216 
       
   217                     // '\\)' - right paranthesis
       
   218                     case ')':
       
   219                         $outEntries[] = ')';
       
   220                         break;
       
   221 
       
   222                     // '\\\\' - backslash
       
   223                     case '\\':
       
   224                         $outEntries[] = '\\';
       
   225                         break;
       
   226 
       
   227                     // "\\\n" or "\\\n\r"
       
   228                     case "\n":
       
   229                         // skip new line symbol
       
   230                         if ($str[$offset + 1] == "\r") {
       
   231                             $offset++;
       
   232                         }
       
   233                         break;
       
   234 
       
   235                     default:
       
   236                         if (strpos('0123456789', $str[$offset]) !== false) {
       
   237                             // Character in octal representation
       
   238                             // '\\xxx'
       
   239                             $nextCode = '0' . $str[$offset];
       
   240 
       
   241                             if (strpos('0123456789', $str[$offset + 1]) !== false) {
       
   242                                 $nextCode .= $str[++$offset];
       
   243 
       
   244                                 if (strpos('0123456789', $str[$offset + 1]) !== false) {
       
   245                                     $nextCode .= $str[++$offset];
       
   246                                 }
       
   247                             }
       
   248 
       
   249                             $outEntries[] = chr(octdec($nextCode));
       
   250                         } else {
       
   251                             $outEntries[] = $str[$offset];
       
   252                         }
       
   253                         break;
       
   254                 }
       
   255 
       
   256                 $offset++;
       
   257             }
       
   258         }
       
   259 
       
   260         return implode($outEntries);
       
   261     }
       
   262 
       
   263 }