source: sandbox/filemanager/tp/dompdf/include/gd_adapter.cls.php @ 1575

Revision 1575, 17.4 KB checked in by amuller, 14 years ago (diff)

Ticket #597 - Implentação, melhorias do modulo gerenciador de arquivos

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   */
541  function text($x, $y, $text, $font, $size, $color = array(0,0,0), $adjust = 0) {
542
543    // Scale by the AA factor
544    $x *= $this->_aa_factor;
545    $y *= $this->_aa_factor;
546    $size *= $this->_aa_factor;
547   
548    $h = $this->get_font_height($font, $size);
549   
550    $c = $this->_allocate_color($color);
551
552    if ( strpos($font, '.ttf') === false )
553      $font .= ".ttf";
554
555    // FIXME: word spacing
556    imagettftext($this->_img, $size, 0, $x, $y + $h, $c, $font, $text);
557   
558  }
559
560  /**
561   * Add a named destination (similar to <a name="foo">...</a> in html)
562   *
563   * @param string $anchorname The name of the named destination
564   */
565  function add_named_dest($anchorname) {
566    // Not implemented
567  }
568
569  /**
570   * Add a link to the pdf
571   *
572   * @param string $url The url to link to
573   * @param float  $x   The x position of the link
574   * @param float  $y   The y position of the link
575   * @param float  $width   The width of the link
576   * @param float  $height   The height of the link
577   */
578  function add_link($url, $x, $y, $width, $height) {
579    // Not implemented
580  }
581
582  /**
583   * Calculates text size, in points
584   *
585   * @param string $text the text to be sized
586   * @param string $font the desired font
587   * @param float  $size the desired font size
588   * @param float  $spacing word spacing, if any
589   * @return float
590   */
591  function get_text_width($text, $font, $size, $spacing = 0) {   
592
593    if ( strpos($font, '.ttf') === false )
594      $font .= ".ttf";
595
596    // FIXME: word spacing
597    list($x1,,$x2) = imagettfbbox($size, 0, $font, $text);
598    return $x2 - $x1;
599  }
600
601  /**
602   * Calculates font height, in points
603   *
604   * @param string $font
605   * @param float $size
606   * @return float
607   */
608  function get_font_height($font, $size) {
609    if ( strpos($font, '.ttf') === false )
610      $font .= ".ttf";
611
612    // FIXME: word spacing
613    list(,$y2,,,,$y1) = imagettfbbox($size, 0, $font, "MXjpqytfhl");  // Test string with ascenders, descenders and caps
614    return $y2 - $y1;
615  }
616
617 
618  /**
619   * Starts a new page
620   *
621   * Subsequent drawing operations will appear on the new page.
622   */
623  function new_page() {
624    // FIXME
625  }   
626
627  /**
628   * Streams the image directly to the browser
629   *
630   * @param string $filename the name of the image file (ignored)
631   * @param array  $options associative array, 'type' => jpeg|jpg|png, 'quality' => 0 - 100 (jpeg only)
632   */
633  function stream($filename, $options = null) {
634
635    // Perform any antialiasing
636    if ( $this->_aa_factor != 1 ) {
637      $dst_w = $this->_width / $this->_aa_factor;
638      $dst_h = $this->_height / $this->_aa_factor;
639      $dst = imagecreatetruecolor($dst_w, $dst_h);
640      imagecopyresampled($dst, $this->_img, 0, 0, 0, 0,
641                         $dst_w, $dst_h,
642                         $this->_width, $this->_height);
643    } else {
644      $dst = $this->_img;
645    }
646
647    if ( !isset($options["type"]) )
648      $options["type"] = "png";
649
650    $type = strtolower($options["type"]);
651   
652    header("Cache-Control: private");
653   
654    switch ($type) {
655
656    case "jpg":
657    case "jpeg":
658      if ( !isset($options["quality"]) )
659        $options["quality"] = 75;
660     
661      header("Content-type: image/jpeg");
662      imagejpeg($dst, '', $options["quality"]);
663      break;
664
665    case "png":
666    default:
667      header("Content-type: image/png");
668      imagepng($dst);
669      break;
670    }
671
672    if ( $this->_aa_factor != 1 )
673      imagedestroy($dst);
674  }
675
676  /**
677   * Returns the PNG as a string
678   *
679   * @param array  $options associative array, 'type' => jpeg|jpg|png, 'quality' => 0 - 100 (jpeg only)
680   * @return string
681   */
682  function output($options = null) {
683
684    if ( $this->_aa_factor != 1 ) {
685      $dst_w = $this->_width / $this->_aa_factor;
686      $dst_h = $this->_height / $this->_aa_factor;
687      $dst = imagecreatetruecolor($dst_w, $dst_h);
688      imagecopyresampled($dst, $this->_img, 0, 0, 0, 0,
689                         $dst_w, $dst_h,
690                         $this->_width, $this->_height);
691    } else {
692      $dst = $this->_img;
693    }
694   
695    if ( !isset($options["type"]) )
696      $options["type"] = "png";
697
698    $type = $options["type"];
699   
700    ob_start();
701
702    switch ($type) {
703
704    case "jpg":
705    case "jpeg":
706      if ( !isset($options["quality"]) )
707        $options["quality"] = 75;
708     
709      imagejpeg($dst, '', $options["quality"]);
710      break;
711
712    case "png":
713    default:
714      imagepng($dst);
715      break;
716    }
717
718    $image = ob_get_contents();
719    ob_end_clean();
720
721    if ( $this->_aa_factor != 1 )
722      imagedestroy($dst);
723   
724    return $image;
725  }
726 
727 
728}
729?>
Note: See TracBrowser for help on using the repository browser.