1<?php 2// $Header: /cvsroot/html2ps/box.list-item.php,v 1.34 2006/09/07 18:38:12 Konstantin Exp $ 3 4class ListItemBox extends BlockBox { 5 var $size; 6 7 function &create(&$root, &$pipeline) { 8 $box = new ListItemBox($root, $pipeline); 9 $box->readCSS($pipeline->get_current_css_state()); 10 11 /** 12 * Create text box containing item number 13 */ 14 $css_state =& $pipeline->get_current_css_state(); 15 $css_state->pushState(); 16 // $css_state->set_property(CSS_COLOR, CSSColor::parse('transparent')); 17 18 $list_style = $css_state->get_property(CSS_LIST_STYLE); 19 $box->str_number_box = TextBox::create(CSSListStyleType::format_number($list_style->type, 20 $css_state->get_property(CSS_HTML2PS_LIST_COUNTER)).". ", 21 'iso-8859-1', 22 $pipeline); 23 $box->str_number_box->readCSS($pipeline->get_current_css_state()); 24 $box->str_number_box->baseline = $box->str_number_box->default_baseline; 25 26 $css_state->popState(); 27 28 /** 29 * Create nested items 30 */ 31 $box->create_content($root, $pipeline); 32 33 return $box; 34 } 35 36 function readCSS(&$state) { 37 parent::readCSS($state); 38 39 $this->_readCSS($state, 40 array(CSS_LIST_STYLE)); 41 42 // Pseudo-CSS properties 43 // '-list-counter' 44 45 // increase counter value 46 $value = $state->get_property(CSS_HTML2PS_LIST_COUNTER) + 1; 47 $state->set_property(CSS_HTML2PS_LIST_COUNTER, $value); 48 $state->set_property_on_level(CSS_HTML2PS_LIST_COUNTER, CSS_PROPERTY_LEVEL_PARENT, $value); 49 50 // open the marker image if specified 51 $list_style = $this->get_css_property(CSS_LIST_STYLE); 52 53 if (!$list_style->image->is_default()) { 54 $this->marker_image = new ImgBox($list_style->image->_image); 55 $state->pushDefaultState(); 56 $this->marker_image->readCSS($state); 57 $state->popState(); 58 $this->marker_image->_setupSize(); 59 } else { 60 $this->marker_image = null; 61 }; 62 } 63 64 function ListItemBox(&$root, &$pipeline) { 65 // Call parent constructor 66 $this->BlockBox($root); 67 } 68 69 function reflow(&$parent, &$context) { 70 $list_style = $this->get_css_property(CSS_LIST_STYLE); 71 72 // If list-style-position is inside, we'll need to move marker box inside the 73 // list-item box and offset all content by its size; 74 if ($list_style->position === LSP_INSIDE) { 75 // Add marker box width to text-indent value 76 $this->_additional_text_indent = $this->get_marker_box_width(); 77 }; 78 79 // Procees with normal block box flow algorithm 80 BlockBox::reflow($parent, $context); 81 } 82 83 function reflow_text(&$driver) { 84 if (is_null($this->str_number_box->reflow_text($driver))) { 85 return null; 86 }; 87 88 return GenericContainerBox::reflow_text($driver); 89 } 90 91 function show(&$viewport) { 92 // draw generic block box 93 if (is_null(BlockBox::show($viewport))) { 94 return null; 95 }; 96 97 // Draw marker 98 /** 99 * Determine the marker box base X coordinate 100 * If possible, the marker box should be drawn immediately to the left of the first word in this 101 * box; this means that marker should be tied to the first text box, not to the left 102 * edge of the list block box 103 */ 104 $child = $this->get_first_data(); 105 if (is_null($child)) { 106 $x = $this->get_left(); 107 108 $list_style = $this->get_css_property(CSS_LIST_STYLE); 109 110 // If list-style-position is inside, we'll need to move marker box inside the 111 // list-item box and offset all content by its size; 112 if ($list_style->position === LSP_INSIDE) { 113 $x += $this->get_marker_box_width(); 114 }; 115 } else { 116 $x = $child->get_left(); 117 }; 118 119 // Determine the base Y coordinate of marker box 120 $element = $this->get_first_data(); 121 122 if ($element) { 123 $y = $element->get_top() - $element->default_baseline; 124 } else { 125 $y = $this->get_top(); 126 } 127 128 if (!is_null($this->marker_image)) { 129 $this->mb_image($viewport, $x, $y); 130 } else { 131 $list_style = $this->get_css_property(CSS_LIST_STYLE); 132 133 switch ($list_style->type) { 134 case LST_NONE: 135 // No marker at all 136 break; 137 case LST_DISC: 138 $this->mb_disc($viewport, $x, $y); 139 break; 140 case LST_CIRCLE: 141 $this->mb_circle($viewport, $x, $y); 142 break; 143 case LST_SQUARE: 144 $this->mb_square($viewport, $x, $y); 145 break; 146 default: 147 $this->mb_string($viewport, $x, $y); 148 break; 149 } 150 }; 151 152 return true; 153 } 154 155 function get_marker_box_width() { 156 $list_style = $this->get_css_property(CSS_LIST_STYLE); 157 158 switch ($list_style->type) { 159 case LST_NONE: 160 // no marker box will be rendered at all 161 return 0; 162 case LST_DISC: 163 case LST_CIRCLE: 164 case LST_SQUARE: 165 // simple graphic marker 166 $font = $this->get_css_property(CSS_FONT); 167 return $font->size->getPoints(); 168 default: 169 // string marker. Return the width of the marker text 170 return $this->str_number_box->get_full_width(); 171 }; 172 } 173 174 function mb_string(&$viewport, $x, $y) { 175 $this->str_number_box->put_top($y + $this->str_number_box->default_baseline); 176 $this->str_number_box->put_left($x - $this->str_number_box->get_full_width()); 177 178 $this->str_number_box->show($viewport); 179 } 180 181 function mb_disc(&$viewport, $x, $y) { 182 $color = $this->get_css_property(CSS_COLOR); 183 $color->apply($viewport); 184 185 $font = $this->get_css_property(CSS_FONT); 186 187 $viewport->circle( $x - $font->size->getPoints()*0.5, $y + $font->size->getPoints()*0.4*HEIGHT_KOEFF, $font->size->getPoints() * BULLET_SIZE_KOEFF); 188 $viewport->fill(); 189 } 190 191 function mb_circle(&$viewport, $x, $y) { 192 $color = $this->get_css_property(CSS_COLOR); 193 $color->apply($viewport); 194 195 $viewport->setlinewidth(0.1); 196 197 $font = $this->get_css_property(CSS_FONT); 198 $viewport->circle( $x - $font->size->getPoints()*0.5, $y + $font->size->getPoints()*0.4*HEIGHT_KOEFF, $font->size->getPoints() * BULLET_SIZE_KOEFF); 199 $viewport->stroke(); 200 } 201 202 function mb_square(&$viewport, $x, $y) { 203 $color = $this->get_css_property(CSS_COLOR); 204 $color->apply($viewport); 205 206 $font = $this->get_css_property(CSS_FONT); 207 $viewport->rect($x - $font->size->getPoints()*0.512, $y + $font->size->getPoints()*0.3*HEIGHT_KOEFF, $font->size->getPoints() * 0.25, $font->size->getPoints() * 0.25); 208 $viewport->fill(); 209 } 210 211 function mb_image(&$viewport, $x, $y) { 212 $font = $this->get_css_property(CSS_FONT); 213 214 $imagebox =& $this->marker_image; 215 $imagebox->moveto($x - $font->size->getPoints()*0.5 - $imagebox->get_width()/2, 216 $y + $font->size->getPoints()*0.4*HEIGHT_KOEFF + $imagebox->get_height()/2); 217 $imagebox->show($viewport); 218 } 219 220 function isBlockLevel() { 221 return true; 222 } 223} 224 225?>