1<?php 2// $Header: /cvsroot/html2ps/box.br.php,v 1.31 2006/11/11 13:43:51 Konstantin Exp $ 3 4require_once(HTML2PS_DIR.'layout.vertical.php'); 5 6/** 7 * @package HTML2PS 8 * @subpackage Document 9 * 10 * Class defined in this file handles the layout of "BR" HTML elements 11 */ 12 13/** 14 * @package HTML2PS 15 * @subpackage Document 16 * 17 * The BRBox class dessribed the behavior of the BR HTML elements 18 * 19 * @link http://www.w3.org/TR/html4/struct/text.html#edef-BR HTML 4.01 Forcing a line break: the BR element 20 */ 21class BRBox extends GenericBox { 22 /** 23 * Create new BR element 24 */ 25 function BRBox() { 26 $this->GenericBox(); 27 } 28 29 function apply_clear($y, &$context) { 30 return LayoutVertical::apply_clear($this, $y, $context); 31 } 32 33 function out_of_flow() { 34 return true; 35 } 36 37 function readCSS(&$state) { 38 parent::readCSS($state); 39 40 /** 41 * We treat BR as a block box; as default value of 'display' property is not 'block', we should 42 * set it up manually. 43 */ 44 $this->setCSSProperty(CSS_DISPLAY, 'block'); 45 46 $this->_readCSS($state, 47 array(CSS_CLEAR)); 48 49 $this->_readCSSLengths($state, 50 array(CSS_MARGIN, 51 CSS_LINE_HEIGHT)); 52 } 53 54 /** 55 * Create new BR element 56 * 57 * @return BRBox new BR element object 58 */ 59 function &create(&$pipeline) { 60 $box =& new BRBox(); 61 $box->readCSS($pipeline->get_current_css_state()); 62 return $box; 63 } 64 65 /** 66 * BR tags do not take any horizontal space, so if minimal width is zero. 67 * 68 * @param FlowContext $context The object containing auxiliary flow data; not used here/ 69 * 70 * @return int should always return constant zero. 71 */ 72 function get_min_width(&$context) { 73 return 0; 74 } 75 76 /** 77 * BR tags do not take any horizontal space, so if maximal width is zero. 78 * 79 * @param FlowContext $context The object containing auxiliary flow data; not used here. 80 * 81 * @return int should always return constant zero. 82 */ 83 function get_max_width(&$context) { 84 return 0; 85 } 86 87 /** 88 * Layout current BR element. The reflow routine is somewhat similar to the block box reflow routine. 89 * As most CSS properties do not apply to BR elements, and BR element always have parent element, 90 * the routine is much simpler. 91 * 92 * @param GenericContainerBox $parent The document element which should be treated as the parent of current element 93 * @param FlowContext $context The flow context containing the additional layout data 94 * 95 * @see FlowContext 96 * @see GenericContainerBox 97 */ 98 function reflow(&$parent, &$context) { 99 parent::reflow($parent, $context); 100 101 /** 102 * Apply 'clear' property; the current Y coordinate can be modified as a result of 'clear'. 103 */ 104 $y = $this->apply_clear($parent->_current_y, $context); 105 106 /** 107 * Move current "box" to parent current coordinates. It is REQUIRED, in spite of the generated 108 * box itself have no dimensions and will never be drawn, as several other routines uses box coordinates. 109 */ 110 $this->put_left($parent->_current_x); 111 $this->put_top($y); 112 113 /** 114 * If we met a sequence of BR tags (like <BR><BR>), we'll have an only one item in the parent's 115 * line box - whitespace; in this case we'll need to additionally offset current y coordinate by the font size, 116 * as whitespace alone does not affect the Y-coordinate. 117 */ 118 if ($parent->line_box_empty()) { 119 /** 120 * There's no elements in the parent line box at all (e.g in the following situation: 121 * <div><br/> .. some text here...</div>); thus, as we're initiating 122 * a new line, we need to offset current Y coordinate by the font-size value. 123 */ 124 125 // Note that _current_y should be modified before 'close_line' call, as it checks for 126 // left-floating boxes, causing an issues if line bottom will be placed below 127 // float while line top is above float bottom margin 128 $font = $this->get_css_property(CSS_FONT); 129 $fs = $font->size; 130 $parent->_current_y = min($this->get_bottom(), 131 $parent->_current_y - $font->line_height->apply($fs->getPoints())); 132 133 $parent->close_line($context, true); 134 } else { 135 /** 136 * There's at least 1 non-whitespace element in the parent line box, we do not need to use whitespace 137 * height; the bottom of the line box is defined by the non-whitespace elements. Top of the new line 138 * should be equal to that value. 139 */ 140 $parent->close_line($context, true); 141 }; 142 143 /** 144 * We need to explicitly extend the parent's height, to make it contain the generated line, 145 * as we don't know if it have any children _after_ this BR box. If we will not do it, 146 * the following code will be rendred incorrectly: 147 * <div>...some text...<br/></div> 148 */ 149 $parent->extend_height($parent->_current_y); 150 } 151 152 /** 153 * Render the BR element; as BR element is non-visual, we do nothing here. 154 * 155 * @param OutputDriver $driver Current output device driver object. 156 * 157 * @return boolean true in case the box was successfully rendered 158 */ 159 function show(&$driver) { 160 return true; 161 } 162 163 /** 164 * As BR element generated a line break, it means that a new line box will be started 165 * (thus, any whitespaces immediately following the BR tag should not be rendered). 166 * To indicate this, we reset the linebox_started flag to 'false' value. 167 * 168 * @param boolean $linebox_started Flag indicating that a new line box have just started and it already contains 169 * some inline elements 170 * @param boolean $previous_whitespace Flag indicating that a previous inline element was an whitespace element. 171 * 172 * @see GenericFormattedBox::reflow_whitespace() 173 */ 174 function reflow_whitespace(&$linebox_started, &$previous_whitespace) { 175 $linebox_started = false; 176 } 177 178 function get_height() { 179 return 0; 180 } 181 182 function get_width() { 183 return 0; 184 } 185 186 /** 187 * BRBox may be placed inside InlineBox (white-space: pre) 188 */ 189 function get_ascender() { 190 return 0; 191 } 192 193 function get_descender() { 194 return 0; 195 } 196 197 function isLineBreak() { 198 return true; 199 } 200} 201?>