Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
// $Header: /cvsroot/html2ps/output._generic.class.php,v 1.17 2007/05/17 13:55:13 Konstantin Exp $
3
 
4
class 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
?>