source: branches/2.2/filemanager/tp/dompdf/include/gd_adapter.cls.php @ 3019

Revision 3019, 17.5 KB checked in by amuller, 14 years ago (diff)

Ticket #1135 - Corrigindo CSS e adicionando filemanager

Line 
1<?php
2/**
3 * DOMPDF - PHP5 HTML to PDF renderer
4 *
5 * File: $RCSfile: gd_adapter.cls.php,v $
6 * Created on: 2004-06-06
7 *
8 * Copyright (c) 2004 - Benj Carson <benjcarson@digitaljunkies.ca>
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this library in the file LICENSE.LGPL; if not, write to the
22 * Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
23 * 02111-1307 USA
24 *
25 * Alternatively, you may distribute this software under the terms of the
26 * PHP License, version 3.0 or later.  A copy of this license should have
27 * been distributed with this file in the file LICENSE.PHP .  If this is not
28 * the case, you can obtain a copy at http://www.php.net/license/3_0.txt.
29 *
30 * The latest version of DOMPDF might be available at:
31 * http://www.digitaljunkies.ca/dompdf
32 *
33 * @link http://www.digitaljunkies.ca/dompdf
34 * @copyright 2004 Benj Carson
35 * @author Benj Carson <benjcarson@digitaljunkies.ca>
36 * @package dompdf
37 * @version 0.5.1
38 */
39
40/* $Id */
41
42/**
43 * Image rendering interface
44 *
45 * Renders to an image format supported by GD (jpeg, gif, png, xpm).
46 * Not super-useful day-to-day but handy nonetheless
47 *
48 * @package dompdf
49 */
50class GD_Adapter implements Canvas {
51
52  /**
53   * Resoure handle for the image
54   *
55   * @var resource
56   */
57  private $_img;
58
59  /**
60   * Image width in pixels
61   *
62   * @var int
63   */
64  private $_width;
65
66  /**
67   * Image height in pixels
68   *
69   * @var int
70   */
71  private $_height;
72
73  /**
74   * Image antialias factor
75   *
76   * @var float
77   */
78  private $_aa_factor;
79
80  /**
81   * Allocated colors
82   *
83   * @var array
84   */
85  private $_colors;
86
87  /**
88   * Background color
89   *
90   * @var int
91   */
92  private $_bg_color;
93 
94  /**
95   * Class constructor
96   *
97   * @param mixed  $size         The size of image to create: array(x1,y1,x2,y2) or "letter", "legal", etc.
98   * @param string $orientation  The orientation of the document (either 'landscape' or 'portrait')
99   * @param float  $aa_factor    Anti-aliasing factor, 1 for no AA
100   * @param array  $bg_color     Image background color: array(r,g,b,a), 0 <= r,g,b,a <= 1
101   */
102  function __construct($size, $orientation = "portrait", $aa_factor = 1, $bg_color = array(1,1,1,0) ) {
103
104    if ( !is_array($size) ) {
105
106      if ( isset(CPDF_Adapter::$PAPER_SIZES[ strtolower($size)]) )
107        $size = CPDF_Adapter::$PAPER_SIZES[$size];
108      else
109        $size = CPDF_Adapter::$PAPER_SIZES["letter"];
110   
111    }
112
113    if ( strtolower($orientation) == "landscape" ) {
114      list($size[2],$size[3]) = array($size[3],$size[2]);
115    }
116
117    if ( $aa_factor < 1 )
118      $aa_factor = 1;
119
120    $this->_aa_factor = $aa_factor;
121   
122    $size[2] *= $aa_factor;
123    $size[3] *= $aa_factor;
124   
125    $this->_width = $size[2] - $size[0];
126    $this->_height = $size[3] - $size[1];
127
128    $this->_img = imagecreatetruecolor($this->_width, $this->_height);
129
130    if ( is_null($bg_color) || !is_array($bg_color) ) {
131      // Pure white bg
132      $bg_color = array(1,1,1,0);
133    }
134
135    $this->_bg_color = $this->_allocate_color($bg_color);
136    imagealphablending($this->_img, false);
137    imagesavealpha($this->_img, true);
138    imagefill($this->_img, 0, 0, $this->_bg_color);
139       
140  }
141
142  /**
143   * Return the GF image resource
144   *
145   * @return resource
146   */
147  function get_image() { return $this->_img; }
148
149  /**
150   * Return the image's width in pixels
151   *
152   * @return float
153   */
154  function get_width() { return $this->_width / $this->_aa_factor; }
155
156  /**
157   * Return the image's height in pixels
158   *
159   * @return float
160   */
161  function get_height() { return $this->_height / $this->_aa_factor; }
162 
163  /**
164   * Returns the current page number
165   *
166   * @return int
167   */
168  function get_page_number() {
169    // FIXME
170  }
171   
172  /**
173   * Returns the total number of pages
174   *
175   * @return int
176   */
177  function get_page_count() {
178    // FIXME
179  }   
180
181  /**
182   * Sets the total number of pages
183   *
184   * @param int $count
185   */
186  function set_page_count($count) {
187    // FIXME
188  }   
189
190  /**
191   * Allocate a new color.  Allocate with GD as needed and store
192   * previously allocated colors in $this->_colors.
193   *
194   * @param array $color  The new current color
195   * @return int           The allocated color
196   */
197  private function _allocate_color($color) {
198   
199    // Full opacity if no alpha set
200    if ( !isset($color[3]) )
201      $color[3] = 0;
202   
203    list($r,$g,$b,$a) = $color;
204   
205    $r *= 255;
206    $g *= 255;
207    $b *= 255;
208    $a *= 127;
209   
210    // Clip values
211    $r = $r > 255 ? 255 : $r;
212    $g = $g > 255 ? 255 : $g;
213    $b = $b > 255 ? 255 : $b;
214    $a = $a > 127 ? 127 : $a;
215     
216    $r = $r < 0 ? 0 : $r;
217    $g = $g < 0 ? 0 : $g;
218    $b = $b < 0 ? 0 : $b;
219    $a = $a < 0 ? 0 : $a;
220     
221    $key = sprintf("#%02X%02X%02X%02X", $r, $g, $b, $a);
222     
223    if ( isset($this->_colors[$key]) )
224      return $this->_colors[$key];
225
226    if ( $a != 0 )
227      $this->_colors[$key] = imagecolorallocatealpha($this->_img, $r, $g, $b, $a);
228    else
229      $this->_colors[$key] = imagecolorallocate($this->_img, $r, $g, $b);
230     
231    return $this->_colors[$key];
232   
233  }
234 
235  /**
236   * Draws a line from x1,y1 to x2,y2
237   *
238   * See {@link Style::munge_color()} for the format of the color array.
239   * See {@link Cpdf::setLineStyle()} for a description of the format of the
240   * $style parameter (aka dash).
241   *
242   * @param float $x1
243   * @param float $y1
244   * @param float $x2
245   * @param float $y2
246   * @param array $color
247   * @param float $width
248   * @param array $style
249   */
250  function line($x1, $y1, $x2, $y2, $color, $width, $style = null) {
251
252    // Scale by the AA factor
253    $x1 *= $this->_aa_factor;
254    $y1 *= $this->_aa_factor;
255    $x2 *= $this->_aa_factor;
256    $y2 *= $this->_aa_factor;
257    $width *= $this->_aa_factor;
258
259    $c = $this->_allocate_color($color);
260
261    // Convert the style array if required
262    if ( !is_null($style) ) {
263      $gd_style = array();
264
265      if ( count($style) == 1 ) {
266        for ($i = 0; $i < $style[0] * $this->_aa_factor; $i++) {
267          $gd_style[] = $c;
268        }
269
270        for ($i = 0; $i < $style[0] * $this->_aa_factor; $i++) {
271          $gd_style[] = $this->_bg_color;
272        }
273
274      } else {
275
276        $i = 0;
277        foreach ($style as $length) {
278
279          if ( $i % 2 == 0 ) {
280            // 'On' pattern
281            for ($i = 0; $i < $style[0] * $this->_aa_factor; $i++)
282              $gd_style[] = $c;
283           
284          } else {
285            // Off pattern
286            for ($i = 0; $i < $style[0] * $this->_aa_factor; $i++)
287              $gd_style[] = $this->_bg_color;
288           
289          }
290          $i++;
291        }
292      }
293     
294      imagesetstyle($this->_img, $gd_style);
295      $c = IMG_COLOR_STYLED;
296    }
297   
298    imagesetthickness($this->_img, $width);
299
300    imageline($this->_img, $x1, $y1, $x2, $y2, $c);
301   
302  }
303
304  /**
305   * Draws a rectangle at x1,y1 with width w and height h
306   *
307   * See {@link Style::munge_color()} for the format of the color array.
308   * See {@link Cpdf::setLineStyle()} for a description of the $style
309   * parameter (aka dash)
310   *
311   * @param float $x1
312   * @param float $y1
313   * @param float $w
314   * @param float $h
315   * @param array $color
316   * @param float $width
317   * @param array $style
318   */   
319  function rectangle($x1, $y1, $w, $h, $color, $width, $style = null) {
320
321    // Scale by the AA factor
322    $x1 *= $this->_aa_factor;
323    $y1 *= $this->_aa_factor;
324    $w *= $this->_aa_factor;
325    $h *= $this->_aa_factor;
326
327    $c = $this->_allocate_color($color);
328
329    // Convert the style array if required
330    if ( !is_null($style) ) {
331      $gd_style = array();
332
333      foreach ($style as $length) {
334        for ($i = 0; $i < $length; $i++) {
335          $gd_style[] = $c;
336        }
337      }
338
339      imagesetstyle($this->_img, $gd_style);
340      $c = IMG_COLOR_STYLED;
341    }
342
343    imagesetthickness($this->_img, $width);
344
345    imagerectangle($this->_img, $x1, $y1, $x1 + $w, $y1 + $h, $c);
346   
347  }
348
349  /**
350   * Draws a filled rectangle at x1,y1 with width w and height h
351   *
352   * See {@link Style::munge_color()} for the format of the color array.
353   *
354   * @param float $x1
355   * @param float $y1
356   * @param float $w
357   * @param float $h
358   * @param array $color
359   */   
360  function filled_rectangle($x1, $y1, $w, $h, $color) {
361
362    // Scale by the AA factor
363    $x1 *= $this->_aa_factor;
364    $y1 *= $this->_aa_factor;
365    $w *= $this->_aa_factor;
366    $h *= $this->_aa_factor;
367
368    $c = $this->_allocate_color($color);
369
370    imagefilledrectangle($this->_img, $x1, $y1, $x1 + $w, $y1 + $h, $c);
371
372  }
373
374  /**
375   * Draws a polygon
376   *
377   * The polygon is formed by joining all the points stored in the $points
378   * array.  $points has the following structure:
379   * <code>
380   * array(0 => x1,
381   *       1 => y1,
382   *       2 => x2,
383   *       3 => y2,
384   *       ...
385   *       );
386   * </code>
387   *
388   * See {@link Style::munge_color()} for the format of the color array.
389   * See {@link Cpdf::setLineStyle()} for a description of the $style
390   * parameter (aka dash)   
391   *
392   * @param array $points
393   * @param array $color
394   * @param float $width
395   * @param array $style
396   * @param bool  $fill  Fills the polygon if true
397   */
398  function polygon($points, $color, $width = null, $style = null, $fill = false) {
399
400    // Scale each point by the AA factor
401    foreach (array_keys($points) as $i)
402      $points[$i] *= $this->_aa_factor;
403
404    $c = $this->_allocate_color($color);
405
406    // Convert the style array if required
407    if ( !is_null($style) && !$fill ) {
408      $gd_style = array();
409
410      foreach ($style as $length) {
411        for ($i = 0; $i < $length; $i++) {
412          $gd_style[] = $c;
413        }
414      }
415
416      imagesetstyle($this->_img, $gd_style);
417      $c = IMG_COLOR_STYLED;
418    }
419
420    imagesetthickness($this->_img, $width);
421
422    if ( $fill )
423      imagefilledpolygon($this->_img, $points, count($points) / 2, $c);
424    else
425      imagepolygon($this->_img, $points, count($points) / 2, $c);
426       
427  }
428
429  /**
430   * Draws a circle at $x,$y with radius $r
431   *
432   * See {@link Style::munge_color()} for the format of the color array.
433   * See {@link Cpdf::setLineStyle()} for a description of the $style
434   * parameter (aka dash)
435   *
436   * @param float $x
437   * @param float $y
438   * @param float $r
439   * @param array $color
440   * @param float $width
441   * @param array $style
442   * @param bool $fill Fills the circle if true   
443   */   
444  function circle($x, $y, $r, $color, $width = null, $style = null, $fill = false) {
445
446    // Scale by the AA factor
447    $x *= $this->_aa_factor;
448    $y *= $this->_aa_factor;
449    $r *= $this->_aa_factor;
450
451    $c = $this->_allocate_color($color);
452
453    // Convert the style array if required
454    if ( !is_null($style) && !$fill ) {
455      $gd_style = array();
456
457      foreach ($style as $length) {
458        for ($i = 0; $i < $length; $i++) {
459          $gd_style[] = $c;
460        }
461      }
462
463      imagesetstyle($this->_img, $gd_style);
464      $c = IMG_COLOR_STYLED;
465    }
466
467    imagesetthickness($this->_img, $width);
468
469    if ( $fill )
470      imagefilledellipse($this->_img, $x, $y, $r, $r, $c);
471    else
472      imageellipse($this->_img, $x, $y, $r, $r, $c);
473       
474  }
475
476  /**
477   * Add an image to the pdf.
478   *
479   * The image is placed at the specified x and y coordinates with the
480   * given width and height.
481   *
482   * @param string $img_url the path to the image
483   * @param string $img_type the type (e.g. extension) of the image
484   * @param float $x x position
485   * @param float $y y position
486   * @param int $w width (in pixels)
487   * @param int $h height (in pixels)
488   */
489  function image($img_url, $img_type, $x, $y, $w, $h) {
490
491    switch ($img_type) {
492    case "png":
493      $src = @imagecreatefrompng($img_url);
494      break;
495     
496    case "gif":
497      $src = @imagecreatefromgif($img_url);
498      break;
499     
500    case "jpg":
501    case "jpeg":
502      $src = @imagecreatefromjpeg($img_url);
503      break;
504
505    default:
506      break;
507     
508    }
509
510    if ( !$src )
511      return; // Probably should add to $_dompdf_errors or whatever here
512   
513    // Scale by the AA factor
514    $x *= $this->_aa_factor;
515    $y *= $this->_aa_factor;
516
517    $w *= $this->_aa_factor;
518    $h *= $this->_aa_factor;
519   
520    $img_w = imagesx($src);
521    $img_h = imagesy($src);
522
523   
524    imagecopyresampled($this->_img, $src, $x, $y, 0, 0, $w, $h, $img_w, $img_h);
525   
526  }
527
528  /**
529   * Writes text at the specified x and y coordinates
530   *
531   * See {@link Style::munge_color()} for the format of the color array.
532   *
533   * @param float $x
534   * @param float $y
535   * @param string $text the text to write
536   * @param string $font the font file to use
537   * @param float $size the font size, in points
538   * @param array $color
539   * @param float $adjust word spacing adjustment
540   * @param float $angle Text angle
541   */
542  function text($x, $y, $text, $font, $size, $color = array(0,0,0), $adjust = 0, $angle = 0) {
543
544    // Scale by the AA factor
545    $x *= $this->_aa_factor;
546    $y *= $this->_aa_factor;
547    $size *= $this->_aa_factor;
548   
549    $h = $this->get_font_height($font, $size);
550   
551    $c = $this->_allocate_color($color);
552
553    if ( strpos($font, '.ttf') === false )
554      $font .= ".ttf";
555
556    // FIXME: word spacing
557    imagettftext($this->_img, $size, $angle, $x, $y + $h, $c, $font, $text);
558   
559  }
560
561  /**
562   * Add a named destination (similar to <a name="foo">...</a> in html)
563   *
564   * @param string $anchorname The name of the named destination
565   */
566  function add_named_dest($anchorname) {
567    // Not implemented
568  }
569
570  /**
571   * Add a link to the pdf
572   *
573   * @param string $url The url to link to
574   * @param float  $x   The x position of the link
575   * @param float  $y   The y position of the link
576   * @param float  $width   The width of the link
577   * @param float  $height   The height of the link
578   */
579  function add_link($url, $x, $y, $width, $height) {
580    // Not implemented
581  }
582
583  /**
584   * Calculates text size, in points
585   *
586   * @param string $text the text to be sized
587   * @param string $font the desired font
588   * @param float  $size the desired font size
589   * @param float  $spacing word spacing, if any
590   * @return float
591   */
592  function get_text_width($text, $font, $size, $spacing = 0) {   
593
594    if ( strpos($font, '.ttf') === false )
595      $font .= ".ttf";
596
597    // FIXME: word spacing
598    list($x1,,$x2) = imagettfbbox($size, 0, $font, $text);
599    return $x2 - $x1;
600  }
601
602  /**
603   * Calculates font height, in points
604   *
605   * @param string $font
606   * @param float $size
607   * @return float
608   */
609  function get_font_height($font, $size) {
610    if ( strpos($font, '.ttf') === false )
611      $font .= ".ttf";
612
613    // FIXME: word spacing
614    list(,$y2,,,,$y1) = imagettfbbox($size, 0, $font, "MXjpqytfhl");  // Test string with ascenders, descenders and caps
615    return $y2 - $y1;
616  }
617
618 
619  /**
620   * Starts a new page
621   *
622   * Subsequent drawing operations will appear on the new page.
623   */
624  function new_page() {
625    // FIXME
626  }   
627
628  /**
629   * Streams the image directly to the browser
630   *
631   * @param string $filename the name of the image file (ignored)
632   * @param array  $options associative array, 'type' => jpeg|jpg|png, 'quality' => 0 - 100 (jpeg only)
633   */
634  function stream($filename, $options = null) {
635
636    // Perform any antialiasing
637    if ( $this->_aa_factor != 1 ) {
638      $dst_w = $this->_width / $this->_aa_factor;
639      $dst_h = $this->_height / $this->_aa_factor;
640      $dst = imagecreatetruecolor($dst_w, $dst_h);
641      imagecopyresampled($dst, $this->_img, 0, 0, 0, 0,
642                         $dst_w, $dst_h,
643                         $this->_width, $this->_height);
644    } else {
645      $dst = $this->_img;
646    }
647
648    if ( !isset($options["type"]) )
649      $options["type"] = "png";
650
651    $type = strtolower($options["type"]);
652   
653    header("Cache-Control: private");
654   
655    switch ($type) {
656
657    case "jpg":
658    case "jpeg":
659      if ( !isset($options["quality"]) )
660        $options["quality"] = 75;
661     
662      header("Content-type: image/jpeg");
663      imagejpeg($dst, '', $options["quality"]);
664      break;
665
666    case "png":
667    default:
668      header("Content-type: image/png");
669      imagepng($dst);
670      break;
671    }
672
673    if ( $this->_aa_factor != 1 )
674      imagedestroy($dst);
675  }
676
677  /**
678   * Returns the PNG as a string
679   *
680   * @param array  $options associative array, 'type' => jpeg|jpg|png, 'quality' => 0 - 100 (jpeg only)
681   * @return string
682   */
683  function output($options = null) {
684
685    if ( $this->_aa_factor != 1 ) {
686      $dst_w = $this->_width / $this->_aa_factor;
687      $dst_h = $this->_height / $this->_aa_factor;
688      $dst = imagecreatetruecolor($dst_w, $dst_h);
689      imagecopyresampled($dst, $this->_img, 0, 0, 0, 0,
690                         $dst_w, $dst_h,
691                         $this->_width, $this->_height);
692    } else {
693      $dst = $this->_img;
694    }
695   
696    if ( !isset($options["type"]) )
697      $options["type"] = "png";
698
699    $type = $options["type"];
700   
701    ob_start();
702
703    switch ($type) {
704
705    case "jpg":
706    case "jpeg":
707      if ( !isset($options["quality"]) )
708        $options["quality"] = 75;
709     
710      imagejpeg($dst, '', $options["quality"]);
711      break;
712
713    case "png":
714    default:
715      imagepng($dst);
716      break;
717    }
718
719    $image = ob_get_contents();
720    ob_end_clean();
721
722    if ( $this->_aa_factor != 1 )
723      imagedestroy($dst);
724   
725    return $image;
726  }
727 
728 
729}
730?>
Note: See TracBrowser for help on using the repository browser.