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/box.img.php,v 1.50 2007/05/06 18:49:29 Konstantin Exp $
3
 
4
define('SCALE_NONE',0);
5
define('SCALE_WIDTH',1);
6
define('SCALE_HEIGHT',2);
7
 
8
class GenericImgBox extends GenericInlineBox {
9
  function GenericImgBox() {
10
    $this->GenericInlineBox();
11
  }
12
 
13
  function get_max_width_natural(&$context) {
14
    return $this->get_full_width($context);
15
  }
16
 
17
  function get_min_width(&$context) {
18
    return $this->get_full_width();
19
  }
20
 
21
  function get_max_width(&$context) {
22
    return $this->get_full_width();
23
  }
24
 
25
  function is_null() {
26
    return false;
27
  }
28
 
29
  function pre_reflow_images() {
30
    switch ($this->scale) {
31
    case SCALE_WIDTH:
32
      // Only 'width' attribute given
33
      $size =
34
        $this->src_width/$this->src_height*
35
        $this->get_width();
36
 
37
      $this->put_height($size);
38
 
39
      // Update baseline according to constrained image height
40
      $this->default_baseline = $this->get_full_height();
41
      break;
42
    case SCALE_HEIGHT:
43
      // Only 'height' attribute given
44
      $size =
45
        $this->src_height/$this->src_width*
46
        $this->get_height();
47
 
48
      $this->put_width($size);
49
      $this->setCSSProperty(CSS_WIDTH, new WCConstant($size));
50
 
51
      $this->default_baseline = $this->get_full_height();
52
      break;
53
    };
54
  }
55
 
56
  function readCSS(&$state) {
57
    parent::readCSS($state);
58
 
59
    // '-html2ps-link-target'
60
    global $g_config;
61
    if ($g_config["renderlinks"]) {
62
      $this->_readCSS($state,
63
                      array(CSS_HTML2PS_LINK_TARGET));
64
    };
65
  }
66
 
67
  function reflow_static(&$parent, &$context) {
68
    $this->pre_reflow_images();
69
 
70
    GenericFormattedBox::reflow($parent, $context);
71
 
72
    // Check if we need a line break here
73
    $this->maybe_line_break($parent, $context);
74
 
75
    // set default baseline
76
    $this->baseline = $this->default_baseline;
77
 
78
    // append to parent line box
79
    $parent->append_line($this);
80
 
81
    // Move box to the parent current point
82
    $this->guess_corner($parent);
83
 
84
    // Move parent's X coordinate
85
    $parent->_current_x += $this->get_full_width();
86
 
87
    // Extend parent height
88
    $parent->extend_height($this->get_bottom_margin());
89
  }
90
 
91
  function _get_font_name(&$driver, $subword_index) {
92
    if (isset($this->_cache[CACHE_TYPEFACE][$subword_index])) {
93
      return $this->_cache[CACHE_TYPEFACE][$subword_index];
94
    };
95
 
96
    $font_resolver =& $driver->get_font_resolver();
97
 
98
    $font = $this->get_css_property(CSS_FONT);
99
    $typeface = $font_resolver->get_typeface_name($font->family,
100
                                                $font->weight,
101
                                                $font->style,
102
                                                'iso-8859-1');
103
 
104
    $this->_cache[CACHE_TYPEFACE][$subword_index] = $typeface;
105
 
106
    return $typeface;
107
  }
108
 
109
  function reflow_text(&$driver) {
110
    // In XHTML images are treated as a common inline elements; they are affected by line-height and font-size
111
    global $g_config;
112
    if ($g_config['mode'] == 'xhtml') {
113
      /**
114
       * A simple assumption is made: fonts used for different encodings
115
       * have equal ascender/descender values  (while they have the same
116
       * typeface, style and weight).
117
       */
118
      $font_name = $this->_get_font_name($driver, 0);
119
 
120
      /**
121
       * Get font vertical metrics
122
       */
123
      $ascender  = $driver->font_ascender($font_name, 'iso-8859-1');
124
      if (is_null($ascender)) {
125
        error_log("ImgBox::reflow_text: cannot get font ascender");
126
        return null;
127
      };
128
 
129
      $descender = $driver->font_descender($font_name, 'iso-8859-1');
130
      if (is_null($descender)) {
131
        error_log("ImgBox::reflow_text: cannot get font descender");
132
        return null;
133
      };
134
 
135
      /**
136
       * Setup box size
137
       */
138
      $font = $this->get_css_property(CSS_FONT_SIZE);
139
      $font_size       = $font->getPoints();
140
 
141
      $this->ascender         = $ascender  * $font_size;
142
      $this->descender        = $descender * $font_size;
143
    } else {
144
      $this->ascender = $this->get_height();
145
      $this->descender = 0;
146
    };
147
 
148
    return true;
149
  }
150
 
151
  // Image boxes are regular inline boxes; whitespaces after images should be rendered
152
  //
153
  function reflow_whitespace(&$linebox_started, &$previous_whitespace) {
154
    $linebox_started = true;
155
    $previous_whitespace = false;
156
    return;
157
  }
158
 
159
  function show_fixed(&$driver) {
160
    return $this->show($driver);
161
  }
162
}
163
 
164
class BrokenImgBox extends GenericImgBox {
165
  var $alt;
166
 
167
  function BrokenImgBox($width, $height, $alt) {
168
    $this->scale = SCALE_NONE;
169
    $this->encoding = DEFAULT_ENCODING;
170
 
171
    // Call parent constructor
172
    $this->GenericImgBox();
173
 
174
    $this->alt = $alt;
175
  }
176
 
177
  function show(&$driver) {
178
    $driver->save();
179
 
180
    // draw generic box
181
    GenericFormattedBox::show($driver);
182
 
183
    $driver->setlinewidth(0.1);
184
    $driver->moveto($this->get_left(),  $this->get_top());
185
    $driver->lineto($this->get_right(), $this->get_top());
186
    $driver->lineto($this->get_right(), $this->get_bottom());
187
    $driver->lineto($this->get_left(),  $this->get_bottom());
188
    $driver->closepath();
189
    $driver->stroke();
190
 
191
    if (!$GLOBALS['g_config']['debugnoclip']) {
192
      $driver->moveto($this->get_left(),  $this->get_top());
193
      $driver->lineto($this->get_right(), $this->get_top());
194
      $driver->lineto($this->get_right(), $this->get_bottom());
195
      $driver->lineto($this->get_left(),  $this->get_bottom());
196
      $driver->closepath();
197
      $driver->clip();
198
    };
199
 
200
    // Output text with the selected font
201
    $size = pt2pt(BROKEN_IMAGE_ALT_SIZE_PT);
202
 
203
    $status = $driver->setfont("Times-Roman", "iso-8859-1", $size);
204
    if (is_null($status)) {
205
      return null;
206
    };
207
 
208
    $driver->show_xy($this->alt,
209
                     $this->get_left() + $this->width/2 - $driver->stringwidth($this->alt,
210
                                                                               "Times-Roman",
211
                                                                               "iso-8859-1",
212
                                                                               $size)/2,
213
                     $this->get_top()  - $this->height/2 - $size/2);
214
 
215
    $driver->restore();
216
 
217
    $strategy =& new StrategyLinkRenderingNormal();
218
    $strategy->apply($this, $driver);
219
 
220
    return true;
221
  }
222
}
223
 
224
class ImgBox extends GenericImgBox {
225
  var $image;
226
  var $type; // unused; should store the preferred image format (JPG / PNG)
227
 
228
  function ImgBox($img) {
229
    $this->encoding = DEFAULT_ENCODING;
230
    $this->scale = SCALE_NONE;
231
 
232
    // Call parent constructor
233
    $this->GenericImgBox();
234
 
235
    // Store image for further processing
236
    $this->image = $img;
237
  }
238
 
239
  function &create(&$root, &$pipeline) {
240
    // Open image referenced by HTML tag
241
    // Some crazy HTML writers add leading and trailing spaces to SRC attribute value - we need to remove them
242
    //
243
    $url_autofix = new AutofixUrl();
244
    $src = $url_autofix->apply(trim($root->get_attribute("src")));
245
 
246
    $image_url = $pipeline->guess_url($src);
247
    $src_img = ImageFactory::get($image_url, $pipeline);
248
 
249
    if (is_null($src_img)) {
250
      // image could not be opened, use ALT attribute
251
 
252
      if ($root->has_attribute('width')) {
253
        $width = px2pt($root->get_attribute('width'));
254
      } else {
255
        $width = px2pt(BROKEN_IMAGE_DEFAULT_SIZE_PX);
256
      };
257
 
258
      if ($root->has_attribute('height')) {
259
        $height = px2pt($root->get_attribute('height'));
260
      } else {
261
        $height = px2pt(BROKEN_IMAGE_DEFAULT_SIZE_PX);
262
      };
263
 
264
      $alt = $root->get_attribute('alt');
265
 
266
      $box =& new BrokenImgBox($width, $height, $alt);
267
 
268
      $box->readCSS($pipeline->get_current_css_state());
269
 
270
      $box->put_width($width);
271
      $box->put_height($height);
272
 
273
      $box->default_baseline = $box->get_full_height();
274
 
275
      $box->src_height = $box->get_height();
276
      $box->src_width  = $box->get_width();
277
 
278
      return $box;
279
    } else {
280
      $box =& new ImgBox($src_img);
281
      $box->readCSS($pipeline->get_current_css_state());
282
      $box->_setupSize();
283
 
284
      return $box;
285
    }
286
  }
287
 
288
  function _setupSize() {
289
    $this->put_width(px2pt($this->image->sx()));
290
    $this->put_height(px2pt($this->image->sy()));
291
    $this->default_baseline = $this->get_full_height();
292
 
293
    $this->src_height = $this->image->sx();
294
    $this->src_width  = $this->image->sy();
295
 
296
    $wc = $this->get_css_property(CSS_WIDTH);
297
    $hc = $this->get_height_constraint();
298
 
299
    // Proportional scaling
300
    if ($hc->is_null() && !$wc->isNull()) {
301
      $this->scale = SCALE_WIDTH;
302
 
303
      // Only 'width' attribute given
304
      $size =
305
        $this->src_width/$this->src_height*
306
        $this->get_width();
307
 
308
      $this->put_height($size);
309
 
310
      // Update baseline according to constrained image height
311
      $this->default_baseline = $this->get_full_height();
312
 
313
    } elseif (!$hc->is_null() && $wc->isNull()) {
314
      $this->scale = SCALE_HEIGHT;
315
 
316
      // Only 'height' attribute given
317
      $size =
318
        $this->src_height/$this->src_width*
319
        $this->get_height();
320
 
321
      $this->put_width($size);
322
      $this->setCSSProperty(CSS_WIDTH, new WCConstant($size));
323
 
324
      $this->default_baseline = $this->get_full_height();
325
    };
326
  }
327
 
328
  function show(&$driver) {
329
    // draw generic box
330
    GenericFormattedBox::show($driver);
331
 
332
    // Check if "designer" set the height or width of this image to zero; in this there will be no reason
333
    // in drawing the image at all
334
    //
335
    if ($this->get_width() < EPSILON ||
336
        $this->get_height() < EPSILON) {
337
      return true;
338
    };
339
 
340
    $driver->image_scaled($this->image,
341
                          $this->get_left(), $this->get_bottom(),
342
                          $this->get_width() / $this->image->sx(),
343
                          $this->get_height() / $this->image->sy());
344
 
345
    $strategy =& new StrategyLinkRenderingNormal();
346
    $strategy->apply($this, $driver);
347
 
348
    return true;
349
  }
350
}
351
?>