1<?php 2// $Header: /cvsroot/html2ps/output._generic.class.php,v 1.17 2007/05/17 13:55:13 Konstantin Exp $ 3 4class OutputDriverGeneric extends OutputDriver { 5 var $media; 6 var $bottom; 7 var $left; 8 var $width; 9 var $height; 10 11 var $_watermark; 12 13 // Offset (in device points) of the current page from the first page. 14 // Can be treated as coordinate of the bottom page edge (as first page 15 // will have zero Y value at its bottom). 16 // Note that ir is PAGE edge coordinate, NOT PRINTABLE AREA! If you want to get 17 // the position of the lowest pixel on the page which won't be cut-off, use 18 // $offset+$bottom expression, as $bottom contains bottom white margin size 19 var $offset; 20 21 var $expected_pages; 22 var $current_page; 23 24 var $filename; 25 26 // Properties 27 28 var $debug_boxes; 29 var $show_page_border; 30 31 var $error_message; 32 33 var $_footnote_area_height; 34 var $_footnote_count; 35 36 var $_page_height; 37 38 var $_postponed; 39 40 var $anchors; 41 42 function OutputDriverGeneric() { 43 // Properties setup 44 $this->set_debug_boxes(false); 45 $this->set_filename($this->mk_filename()); 46 $this->set_show_page_border(false); 47 48 $this->setFootnoteAreaHeight(0); 49 $this->setFootnoteCount(0); 50 51 $this->_postponed = array(); 52 53 $this->anchors = array(); 54 } 55 56 function postpone(&$box) { 57 $this->_postponed[] =& $box; 58 } 59 60 function show_postponed() { 61 $size = count($this->_postponed); 62 for ($i=0; $i<$size; $i++) { 63 $box =& $this->_postponed[$i]; 64 65 $this->save(); 66 $box->_setupClip($this); 67 $box->show_postponed($this, true); 68 $this->restore(); 69 }; 70 } 71 72 function show_postponed_in_absolute() { 73 $size = count($this->_postponed); 74 for ($i=0; $i<$size; $i++) { 75 $box =& $this->_postponed[$i]; 76 77 if ($box->hasAbsolutePositionedParent()) { 78 79 $this->save(); 80 $box->_setupClip($this); 81 $box->show_postponed($this, true); 82 $this->restore(); 83 }; 84 }; 85 } 86 87 function show_postponed_in_fixed() { 88 $size = count($this->_postponed); 89 for ($i=0; $i<$size; $i++) { 90 $box =& $this->_postponed[$i]; 91 92 if ($box->hasFixedPositionedParent()) { 93 $this->save(); 94 $box->_setupClip($this); 95 $box->show_postponed($this, true); 96 $this->restore(); 97 }; 98 }; 99 } 100 101 function next_page($old_page_height) { 102 $this->setFootnoteAreaHeight(0); 103 $this->setFootnoteCount(0); 104 $this->setPageHeight(mm2pt($this->media->real_height())); 105 106 $this->_postponed = array(); 107 $this->current_page ++; 108 } 109 110 function setPageHeight($value) { 111 $this->_page_height = $value; 112 } 113 114 function getPageHeight() { 115 return $this->_page_height; 116 } 117 118 function getPageMaxHeight() { 119 return round(mm2pt($this->media->real_height()),2); 120 } 121 122 function getPageWidth() { 123 return round(mm2pt($this->media->real_width()),2); 124 } 125 126 function getPageLeft() { 127 return round(mm2pt($this->media->margins['left']),2); 128 } 129 130 function getPageTop() { 131 return round($this->offset + mm2pt($this->media->height() - $this->media->margins['top']),2); 132 } 133 134 function getPageBottom() { 135 return $this->getPageTop() - $this->getPageHeight(); 136 } 137 138 function getFootnoteTop() { 139 return round($this->offset + 140 mm2pt($this->media->margins['bottom']) + 141 $this->getFootnoteAreaHeight(), 142 2); 143 } 144 145 function getFootnoteAreaHeight() { 146 return $this->_footnote_area_height; 147 } 148 149 function setFootnoteAreaHeight($value) { 150 $this->_footnote_area_height = $value; 151 } 152 153 function setFootnoteCount($value) { 154 $this->_footnote_count = $value; 155 } 156 157 function getFootnoteCount() { 158 return $this->_footnote_count; 159 } 160 161 function error_message() { 162 return $this->error_message; 163 } 164 165 /** 166 * Checks if a given box should be drawn on the current page. 167 * Basically, box should be drawn if its top or bottom edge is "inside" the page "viewport" 168 * 169 * @param GenericBox $box Box we're using for check 170 * @return boolean flag indicating of any part of this box should be placed on the current page 171 */ 172 function contains(&$box) { 173 return $this->willContain($box, 0); 174 } 175 176 function willContain(&$box, $footnote_height) { 177 /** 178 * These two types of boxes are not visual and 179 * may have incorrect position 180 */ 181 if (is_a($box, 'TableSectionBox')) { return true; }; 182 if (is_a($box, 'TableRowBox')) { return true; }; 183 184 $top = round($box->get_top(),2); 185 $bottom = round($box->get_bottom(),2); 186 187 $vp_top = $this->getPageTop(); 188 $vp_bottom = max($this->getFootnoteTop() + $footnote_height, 189 $this->getPageTop() - $this->getPageHeight()); 190 191 return ($top > $vp_bottom && 192 $bottom <= $vp_top); 193 } 194 195 function draw_page_border() { 196 $this->setlinewidth(1); 197 $this->setrgbcolor(0,0,0); 198 199 $this->moveto($this->left, $this->bottom + $this->offset); 200 $this->lineto($this->left, $this->bottom + $this->height + $this->offset); 201 $this->lineto($this->left + $this->width, $this->bottom + $this->height + $this->offset); 202 $this->lineto($this->left + $this->width, $this->bottom + $this->offset); 203 $this->closepath(); 204 $this->stroke(); 205 } 206 207 function get_expected_pages() { 208 return $this->expected_pages; 209 } 210 211 function mk_filename() { 212 // Check if we can use tempnam to create files (so, we have PHP version 213 // with fixed bug it this function behaviour and open_basedir/environment 214 // variables are not maliciously set to move temporary files out of open_basedir 215 // In general, we'll try to create these files in ./temp subdir of current 216 // directory, but it can be overridden by environment vars both on Windows and 217 // Linux 218 $filename = tempnam(WRITER_TEMPDIR,WRITER_FILE_PREFIX); 219 $filehandle = @fopen($filename, "wb"); 220 221 // Now, if we have had any troubles, $filehandle will be 222 if ($filehandle === false) { 223 // Note: that we definitely need to unlink($filename); - tempnam just created it for us! 224 // but we can't ;) because of open_basedir (or whatelse prevents us from opening it) 225 226 // Fallback to some stupid algorithm of filename generation 227 $tries = 0; 228 do { 229 $filename = WRITER_TEMPDIR.DIRECTORY_SEPARATOR.WRITER_FILE_PREFIX.md5(uniqid(rand(), true)); 230 // Note: "x"-mode prevents us from re-using existing files 231 // But it require PHP 4.3.2 or later 232 $filehandle = @fopen($filename, "xb"); 233 $tries++; 234 } while (!$filehandle && $tries < WRITER_RETRIES); 235 }; 236 237 if (!$filehandle) { 238 die(WRITER_CANNOT_CREATE_FILE); 239 }; 240 241 // Release this filehandle - we'll reopen it using some gzip wrappers 242 // (if they are available) 243 fclose($filehandle); 244 245 // Remove temporary file we've just created during testing 246 unlink($filename); 247 248 return $filename; 249 } 250 251 function get_filename() { 252 return $this->filename; 253 } 254 255 function &get_font_resolver() { 256 global $g_font_resolver_pdf; 257 return $g_font_resolver_pdf; 258 } 259 260 function is_debug_boxes() { 261 return $this->debug_boxes; 262 } 263 264 function is_show_page_border() { 265 return $this->show_page_border; 266 } 267 268 function rect($x, $y, $w, $h) { 269 $this->moveto($x, $y); 270 $this->lineto($x + $w, $y); 271 $this->lineto($x + $w, $y + $h); 272 $this->lineto($x, $y + $h); 273 $this->closepath(); 274 } 275 276 function set_debug_boxes($debug) { 277 $this->debug_boxes = $debug; 278 } 279 280 function set_expected_pages($num) { 281 $this->expected_pages = $num; 282 } 283 284 function set_filename($filename) { 285 $this->filename = $filename; 286 } 287 288 function set_show_page_border($show) { 289 $this->show_page_border = $show; 290 } 291 292 function setup_clip() { 293 if (!$GLOBALS['g_config']['debugnoclip']) { 294 $this->moveto($this->left, $this->bottom + $this->height + $this->offset); 295 $this->lineto($this->left + $this->width, $this->bottom + $this->height + $this->offset); 296 $this->lineto($this->left + $this->width, $this->bottom + $this->height + $this->offset - $this->getPageHeight()); 297 $this->lineto($this->left, $this->bottom + $this->height + $this->offset - $this->getPageHeight()); 298 $this->clip(); 299 }; 300 } 301 302 function prepare() { 303 } 304 305 function reset(&$media) { 306 $this->update_media($media); 307 $this->_postponed = array(); 308 309 $this->offset = 0; 310 $this->offset_delta = 0; 311 $this->expected_pages = 0; 312 $this->current_page = 0; 313 } 314 315 function &get_media() { 316 return $this->media; 317 } 318 319 function update_media(&$media) { 320 $this->media =& $media; 321 $this->width = mm2pt($media->width() - $media->margins['left'] - $media->margins['right']); 322 $this->height = mm2pt($media->height() - $media->margins['top'] - $media->margins['bottom']); 323 $this->left = mm2pt($media->margins['left']); 324 $this->bottom = mm2pt($media->margins['bottom']); 325 326 $this->setPageHeight(mm2pt($media->real_height())); 327 } 328} 329?>