generated_frame_reflower.cls.php 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. <?php
  2. /**
  3. * DOMPDF - PHP5 HTML to PDF renderer
  4. *
  5. * File: $RCSfile: generated_frame_reflower.cls.php,v $
  6. * Created on: 2004-06-23
  7. *
  8. * Copyright (c) 2004 - Benj Carson <benjcarson@digitaljunkies.ca>
  9. *
  10. * This library is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU Lesser General Public
  12. * License as published by the Free Software Foundation; either
  13. * version 2.1 of the License, or (at your option) any later version.
  14. *
  15. * This library is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  18. * Lesser General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU Lesser General Public License
  21. * along with this library in the file LICENSE.LGPL; if not, write to the
  22. * Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  23. * 02111-1307 USA
  24. *
  25. * Alternatively, you may distribute this software under the terms of the
  26. * PHP License, version 3.0 or later. A copy of this license should have
  27. * been distributed with this file in the file LICENSE.PHP . If this is not
  28. * the case, you can obtain a copy at http://www.php.net/license/3_0.txt.
  29. *
  30. * The latest version of DOMPDF might be available at:
  31. * http://www.dompdf.com/
  32. *
  33. * @link http://www.dompdf.com/
  34. * @copyright 2004 Benj Carson
  35. * @author Benj Carson <benjcarson@digitaljunkies.ca>
  36. * @package dompdf
  37. */
  38. /* $Id: generated_frame_reflower.cls.php 216 2010-03-11 22:49:18Z ryan.masten $ */
  39. /**
  40. * Reflows generated content frames (decorates reflower)
  41. *
  42. * @access private
  43. * @package dompdf
  44. */
  45. class Generated_Frame_Reflower extends Frame_Reflower {
  46. protected $_reflower; // Decoration target
  47. function __construct(Frame $frame) {
  48. parent::__construct($frame);
  49. }
  50. function set_reflower(Frame_Reflower $reflow) {
  51. $this->_reflower = $reflow;
  52. }
  53. //........................................................................
  54. protected function _parse_string($string) {
  55. $string = trim($string, "'\"");
  56. $string = str_replace(array("\\\n",'\\"',"\\'"),
  57. array("",'"',"'"), $string);
  58. // Convert escaped hex characters into ascii characters (e.g. \A => newline)
  59. $string = preg_replace_callback("/\\\\([0-9a-fA-F]{0,6})(\s)?(?(2)|(?=[^0-9a-fA-F]))/",
  60. create_function('$matches',
  61. 'return chr(hexdec($matches[1]));'),
  62. $string);
  63. return $string;
  64. }
  65. protected function _parse_content() {
  66. $style = $this->_frame->get_style();
  67. // Matches generated content
  68. $re = "/\n".
  69. "\s(counters?\\([^)]*\\))|\n".
  70. "\A(counters?\\([^)]*\\))|\n".
  71. "\s([\"']) ( (?:[^\"']|\\\\[\"'])+ )(?<!\\\\)\\3|\n".
  72. "\A([\"']) ( (?:[^\"']|\\\\[\"'])+ )(?<!\\\\)\\5|\n" .
  73. "\s([^\s\"']+)|\n" .
  74. "\A([^\s\"']+)\n".
  75. "/xi";
  76. $content = $style->content;
  77. // split on spaces, except within quotes
  78. if (!preg_match_all($re, $content, $matches, PREG_SET_ORDER))
  79. return;
  80. $text = "";
  81. foreach ($matches as $match) {
  82. if ( isset($match[2]) && $match[2] !== "" )
  83. $match[1] = $match[1];
  84. if ( isset($match[6]) && $match[6] !== "" )
  85. $match[4] = $match[6];
  86. if ( isset($match[8]) && $match[8] !== "" )
  87. $match[7] = $match[8];
  88. if ( isset($match[1]) && $match[1] !== "" ) {
  89. // counters?(...)
  90. $match[1] = mb_strtolower(trim($match[1]));
  91. // Handle counter() references:
  92. // http://www.w3.org/TR/CSS21/generate.html#content
  93. $i = mb_strpos($match[1], ")");
  94. if ( $i === false )
  95. continue;
  96. $args = explode(",", mb_substr($match[1], 7, $i - 7));
  97. $counter_id = $args[0];
  98. if ( $match[1]{7} === "(" ) {
  99. // counter(name [,style])
  100. if ( isset($args[1]) )
  101. $type = $args[1];
  102. else
  103. $type = null;
  104. $p = $this->_frame->find_block_parent();
  105. $text .= $p->counter_value($counter_id, $type);
  106. } else if ( $match[1]{7} === "s" ) {
  107. // counters(name, string [,style])
  108. if ( isset($args[1]) )
  109. $string = $this->_parse_string(trim($args[1]));
  110. else
  111. $string = "";
  112. if ( isset($args[2]) )
  113. $type = $args[2];
  114. else
  115. $type = null;
  116. $p = $this->_frame->find_block_parent();
  117. $tmp = "";
  118. while ($p) {
  119. $tmp = $p->counter_value($counter_id, $type) . $string . $tmp;
  120. $p = $p->find_block_parent();
  121. }
  122. $text .= $tmp;
  123. } else
  124. // countertops?
  125. continue;
  126. } else if ( isset($match[4]) && $match[4] !== "" ) {
  127. // String match
  128. $text .= $this->_parse_string($match[4]);
  129. } else if ( isset($match[7]) && $match[7] !== "" ) {
  130. // Directive match
  131. if ( $match[7] === "open-quote" ) {
  132. // FIXME: do something here
  133. } else if ( $match[7] === "close-quote" ) {
  134. // FIXME: do something else here
  135. } else if ( $match[7] === "no-open-quote" ) {
  136. // FIXME:
  137. } else if ( $match[7] === "no-close-quote" ) {
  138. // FIXME:
  139. } else if ( mb_strpos($match[7],"attr(") === 0 ) {
  140. $i = mb_strpos($match[7],")");
  141. if ( $i === false )
  142. continue;
  143. $attr = mb_substr($match[7], 6, $i - 6);
  144. if ( $attr == "" )
  145. continue;
  146. $text .= $this->_frame->get_node()->getAttribute($attr);
  147. } else
  148. continue;
  149. }
  150. }
  151. return $text;
  152. }
  153. function reflow() {
  154. $style = $this->_frame->get_style();
  155. $text = $this->_parse_content();
  156. $t_node = $this->_frame->get_node()->ownerDocument->createTextNode($text);
  157. $t_frame = new Frame($t_node);
  158. $t_style = $style->get_stylesheet()->create_style();
  159. $t_style->inherit($style);
  160. $t_frame->set_style($t_style);
  161. $this->_frame->prepend_child(Frame_Factory::decorate_frame($t_frame));
  162. $this->_reflower->reflow();
  163. }
  164. }