Block_Renderer

Renders block frames.

Defined (1)

The class is defined in the following location(s).

/lib/dompdf/include/block_renderer.cls.php  
  1. class Block_Renderer extends Abstract_Renderer { 
  2.  
  3. //........................................................................ 
  4.  
  5. function render(Frame $frame) { 
  6. $style = $frame->get_style(); 
  7. $node = $frame->get_node(); 
  8.  
  9. list($x, $y, $w, $h) = $frame->get_border_box(); 
  10.  
  11. $this->_set_opacity( $frame->get_opacity( $style->opacity ) ); 
  12.  
  13. if ( $node->nodeName === "body" ) { 
  14. $h = $frame->get_containing_block("h") - $style->length_in_pt(array( 
  15. $style->margin_top,  
  16. $style->border_top_width,  
  17. $style->border_bottom_width,  
  18. $style->margin_bottom),  
  19. $style->width); 
  20.  
  21. // Handle anchors & links 
  22. if ( $node->nodeName === "a" && $href = $node->getAttribute("href") ) { 
  23. $this->_canvas->add_link($href, $x, $y, $w, $h); 
  24.  
  25. // Draw our background, border and content 
  26. list($tl, $tr, $br, $bl) = $style->get_computed_border_radius($w, $h); 
  27.  
  28. if ( $tl + $tr + $br + $bl > 0 ) { 
  29. $this->_canvas->clipping_roundrectangle( $x, $y, $w, $h, $tl, $tr, $br, $bl ); 
  30.  
  31. if ( ($bg = $style->background_color) !== "transparent" ) { 
  32. $this->_canvas->filled_rectangle( $x, $y, $w, $h, $bg ); 
  33.  
  34. if ( ($url = $style->background_image) && $url !== "none" ) { 
  35. $this->_background_image($url, $x, $y, $w, $h, $style); 
  36.  
  37. if ( $tl + $tr + $br + $bl > 0 ) { 
  38. $this->_canvas->clipping_end(); 
  39.  
  40. $border_box = array($x, $y, $w, $h); 
  41. $this->_render_border($frame, $border_box); 
  42. $this->_render_outline($frame, $border_box); 
  43.  
  44. if (DEBUG_LAYOUT && DEBUG_LAYOUT_BLOCKS) { 
  45. $this->_debug_layout($frame->get_border_box(), "red"); 
  46. if (DEBUG_LAYOUT_PADDINGBOX) { 
  47. $this->_debug_layout($frame->get_padding_box(), "red", array(0.5, 0.5)); 
  48.  
  49. if (DEBUG_LAYOUT && DEBUG_LAYOUT_LINES && $frame->get_decorator()) { 
  50. foreach ($frame->get_decorator()->get_line_boxes() as $line) { 
  51. $frame->_debug_layout(array($line->x, $line->y, $line->w, $line->h), "orange"); 
  52.  
  53. protected function _render_border(Frame_Decorator $frame, $border_box = null, $corner_style = "bevel") { 
  54. $style = $frame->get_style(); 
  55. $bp = $style->get_border_properties(); 
  56.  
  57. if ( empty($border_box) ) { 
  58. $border_box = $frame->get_border_box(); 
  59.  
  60. // find the radius 
  61. $radius = $style->get_computed_border_radius($border_box[2], $border_box[3]); // w, h 
  62.  
  63. // Short-cut: If all the borders are "solid" with the same color and style, and no radius, we'd better draw a rectangle 
  64. if ( 
  65. in_array($bp["top"]["style"], array("solid", "dashed", "dotted")) &&  
  66. $bp["top"] == $bp["right"] && 
  67. $bp["right"] == $bp["bottom"] && 
  68. $bp["bottom"] == $bp["left"] && 
  69. array_sum($radius) == 0 
  70. ) { 
  71. $props = $bp["top"]; 
  72. if ( $props["color"] === "transparent" || $props["width"] <= 0 ) return; 
  73.  
  74. list($x, $y, $w, $h) = $border_box; 
  75. $width = $style->length_in_pt($props["width"]); 
  76. $pattern = $this->_get_dash_pattern($props["style"], $width); 
  77. $this->_canvas->rectangle($x + $width / 2, $y + $width / 2, $w - $width, $h - $width, $props["color"], $width, $pattern); 
  78. return; 
  79.  
  80. // Do it the long way 
  81. $widths = array($style->length_in_pt($bp["top"]["width"]),  
  82. $style->length_in_pt($bp["right"]["width"]),  
  83. $style->length_in_pt($bp["bottom"]["width"]),  
  84. $style->length_in_pt($bp["left"]["width"])); 
  85.  
  86. foreach ($bp as $side => $props) { 
  87. list($x, $y, $w, $h) = $border_box; 
  88. $length = 0; 
  89. $r1 = 0; 
  90. $r2 = 0; 
  91.  
  92. if ( !$props["style"] ||  
  93. $props["style"] === "none" ||  
  94. $props["width"] <= 0 ||  
  95. $props["color"] == "transparent" ) 
  96. continue; 
  97.  
  98. switch($side) { 
  99. case "top": 
  100. $length = $w; 
  101. $r1 = $radius["top-left"]; 
  102. $r2 = $radius["top-right"]; 
  103. break; 
  104.  
  105. case "bottom": 
  106. $length = $w; 
  107. $y += $h; 
  108. $r1 = $radius["bottom-left"]; 
  109. $r2 = $radius["bottom-right"]; 
  110. break; 
  111.  
  112. case "left": 
  113. $length = $h; 
  114. $r1 = $radius["top-left"]; 
  115. $r2 = $radius["bottom-left"]; 
  116. break; 
  117.  
  118. case "right": 
  119. $length = $h; 
  120. $x += $w; 
  121. $r1 = $radius["top-right"]; 
  122. $r2 = $radius["bottom-right"]; 
  123. break; 
  124. default: 
  125. break; 
  126. $method = "_border_" . $props["style"]; 
  127.  
  128. // draw rounded corners 
  129. $this->$method($x, $y, $length, $props["color"], $widths, $side, $corner_style, $r1, $r2); 
  130.  
  131. protected function _render_outline(Frame_Decorator $frame, $border_box = null, $corner_style = "bevel") { 
  132. $style = $frame->get_style(); 
  133.  
  134. $props = array( 
  135. "width" => $style->outline_width,  
  136. "style" => $style->outline_style,  
  137. "color" => $style->outline_color,  
  138. ); 
  139.  
  140. if ( !$props["style"] || $props["style"] === "none" || $props["width"] <= 0 ) 
  141. return; 
  142.  
  143. if ( empty($border_box) ) { 
  144. $border_box = $frame->get_border_box(); 
  145.  
  146. $offset = $style->length_in_pt($props["width"]); 
  147. $pattern = $this->_get_dash_pattern($props["style"], $offset); 
  148.  
  149. // If the outline style is "solid" we'd better draw a rectangle 
  150. if ( in_array($props["style"], array("solid", "dashed", "dotted")) ) { 
  151. $border_box[0] -= $offset / 2; 
  152. $border_box[1] -= $offset / 2; 
  153. $border_box[2] += $offset; 
  154. $border_box[3] += $offset; 
  155.  
  156. list($x, $y, $w, $h) = $border_box; 
  157. $this->_canvas->rectangle($x, $y, $w, $h, $props["color"], $offset, $pattern); 
  158. return; 
  159.  
  160. $border_box[0] -= $offset; 
  161. $border_box[1] -= $offset; 
  162. $border_box[2] += $offset * 2; 
  163. $border_box[3] += $offset * 2; 
  164.  
  165. $method = "_border_" . $props["style"]; 
  166. $widths = array_fill(0, 4, $props["width"]); 
  167. $sides = array("top", "right", "left", "bottom"); 
  168. $length = 0; 
  169.  
  170. foreach ($sides as $side) { 
  171. list($x, $y, $w, $h) = $border_box; 
  172.  
  173. switch($side) { 
  174. case "top": 
  175. $length = $w; 
  176. break; 
  177.  
  178. case "bottom": 
  179. $length = $w; 
  180. $y += $h; 
  181. break; 
  182.  
  183. case "left": 
  184. $length = $h; 
  185. break; 
  186.  
  187. case "right": 
  188. $length = $h; 
  189. $x += $w; 
  190. break; 
  191. default: 
  192. break; 
  193.  
  194. $this->$method($x, $y, $length, $props["color"], $widths, $side, $corner_style);