fpdi_bridge.php 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. <?php
  2. //
  3. // FPDI - Version 1.5.2
  4. //
  5. // Copyright 2004-2014 Setasign - Jan Slabon
  6. //
  7. // Licensed under the Apache License, Version 2.0 (the "License");
  8. // you may not use this file except in compliance with the License.
  9. // You may obtain a copy of the License at
  10. //
  11. // http://www.apache.org/licenses/LICENSE-2.0
  12. //
  13. // Unless required by applicable law or agreed to in writing, software
  14. // distributed under the License is distributed on an "AS IS" BASIS,
  15. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. // See the License for the specific language governing permissions and
  17. // limitations under the License.
  18. //
  19. /**
  20. * This file is used as a bridge between TCPDF or FPDF
  21. * It will dynamically create the class extending the available
  22. * class FPDF or TCPDF.
  23. *
  24. * This way it is possible to use FPDI for both FPDF and TCPDF with one FPDI version.
  25. */
  26. if (!class_exists('TCPDF', false)) {
  27. /**
  28. * Class fpdi_bridge
  29. */
  30. class fpdi_bridge extends FPDF
  31. {
  32. // empty body
  33. }
  34. } else {
  35. /**
  36. * Class fpdi_bridge
  37. */
  38. class fpdi_bridge extends TCPDF
  39. {
  40. /**
  41. * Array of Tpl-Data
  42. *
  43. * @var array
  44. */
  45. protected $_tpls = array();
  46. /**
  47. * Name-prefix of Templates used in Resources-Dictionary
  48. *
  49. * @var string A String defining the Prefix used as Template-Object-Names. Have to begin with an /
  50. */
  51. public $tplPrefix = "/TPL";
  52. /**
  53. * Current Object Id.
  54. *
  55. * @var integer
  56. */
  57. protected $_currentObjId;
  58. /**
  59. * Return XObjects Dictionary.
  60. *
  61. * Overwritten to add additional XObjects to the resources dictionary of TCPDF
  62. *
  63. * @return string
  64. */
  65. protected function _getxobjectdict()
  66. {
  67. $out = parent::_getxobjectdict();
  68. foreach ($this->_tpls as $tplIdx => $tpl) {
  69. $out .= sprintf('%s%d %d 0 R', $this->tplPrefix, $tplIdx, $tpl['n']);
  70. }
  71. return $out;
  72. }
  73. /**
  74. * Writes a PDF value to the resulting document.
  75. *
  76. * Prepares the value for encryption of imported data by FPDI
  77. *
  78. * @param array $value
  79. */
  80. protected function _prepareValue(&$value)
  81. {
  82. switch ($value[0]) {
  83. case pdf_parser::TYPE_STRING:
  84. if ($this->encrypted) {
  85. $value[1] = $this->_unescape($value[1]);
  86. $value[1] = $this->_encrypt_data($this->_currentObjId, $value[1]);
  87. $value[1] = TCPDF_STATIC::_escape($value[1]);
  88. }
  89. break;
  90. case pdf_parser::TYPE_STREAM:
  91. if ($this->encrypted) {
  92. $value[2][1] = $this->_encrypt_data($this->_currentObjId, $value[2][1]);
  93. $value[1][1]['/Length'] = array(
  94. pdf_parser::TYPE_NUMERIC,
  95. strlen($value[2][1])
  96. );
  97. }
  98. break;
  99. case pdf_parser::TYPE_HEX:
  100. if ($this->encrypted) {
  101. $value[1] = $this->hex2str($value[1]);
  102. $value[1] = $this->_encrypt_data($this->_currentObjId, $value[1]);
  103. // remake hexstring of encrypted string
  104. $value[1] = $this->str2hex($value[1]);
  105. }
  106. break;
  107. }
  108. }
  109. /**
  110. * Un-escapes a PDF string
  111. *
  112. * @param string $s
  113. * @return string
  114. */
  115. protected function _unescape($s)
  116. {
  117. $out = '';
  118. for ($count = 0, $n = strlen($s); $count < $n; $count++) {
  119. if ($s[$count] != '\\' || $count == $n-1) {
  120. $out .= $s[$count];
  121. } else {
  122. switch ($s[++$count]) {
  123. case ')':
  124. case '(':
  125. case '\\':
  126. $out .= $s[$count];
  127. break;
  128. case 'f':
  129. $out .= chr(0x0C);
  130. break;
  131. case 'b':
  132. $out .= chr(0x08);
  133. break;
  134. case 't':
  135. $out .= chr(0x09);
  136. break;
  137. case 'r':
  138. $out .= chr(0x0D);
  139. break;
  140. case 'n':
  141. $out .= chr(0x0A);
  142. break;
  143. case "\r":
  144. if ($count != $n-1 && $s[$count+1] == "\n")
  145. $count++;
  146. break;
  147. case "\n":
  148. break;
  149. default:
  150. // Octal-Values
  151. if (ord($s[$count]) >= ord('0') &&
  152. ord($s[$count]) <= ord('9')) {
  153. $oct = ''. $s[$count];
  154. if (ord($s[$count+1]) >= ord('0') &&
  155. ord($s[$count+1]) <= ord('9')) {
  156. $oct .= $s[++$count];
  157. if (ord($s[$count+1]) >= ord('0') &&
  158. ord($s[$count+1]) <= ord('9')) {
  159. $oct .= $s[++$count];
  160. }
  161. }
  162. $out .= chr(octdec($oct));
  163. } else {
  164. $out .= $s[$count];
  165. }
  166. }
  167. }
  168. }
  169. return $out;
  170. }
  171. /**
  172. * Hexadecimal to string
  173. *
  174. * @param string $data
  175. * @return string
  176. */
  177. public function hex2str($data)
  178. {
  179. $data = preg_replace('/[^0-9A-Fa-f]/', '', rtrim($data, '>'));
  180. if ((strlen($data) % 2) == 1) {
  181. $data .= '0';
  182. }
  183. return pack('H*', $data);
  184. }
  185. /**
  186. * String to hexadecimal
  187. *
  188. * @param string $str
  189. * @return string
  190. */
  191. public function str2hex($str)
  192. {
  193. return current(unpack('H*', $str));
  194. }
  195. }
  196. }