| 1 |
lars |
1 |
<?php
|
|
|
2 |
// $Header: /cvsroot/html2ps/box.list-item.php,v 1.34 2006/09/07 18:38:12 Konstantin Exp $
|
|
|
3 |
|
|
|
4 |
class 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 |
?>
|