[Mapbender-commits] r3371 - branches/print_dev/http/extensions/fpdf
svn_mapbender at osgeo.org
svn_mapbender at osgeo.org
Fri Dec 19 12:39:49 EST 2008
Author: mschulz
Date: 2008-12-19 12:39:49 -0500 (Fri, 19 Dec 2008)
New Revision: 3371
Added:
branches/print_dev/http/extensions/fpdf/mb_fpdi.php
Log:
first sketches to new pdf template printing
Added: branches/print_dev/http/extensions/fpdf/mb_fpdi.php
===================================================================
--- branches/print_dev/http/extensions/fpdf/mb_fpdi.php (rev 0)
+++ branches/print_dev/http/extensions/fpdf/mb_fpdi.php 2008-12-19 17:39:49 UTC (rev 3371)
@@ -0,0 +1,379 @@
+<?php
+
+require_once(dirname(__FILE__)."/fpdi.php");
+
+class mb_fpdi extends FPDI {
+
+ function mb_fpdi($orientation='L',$unit='mm',$format='A4') {
+ parent::FPDI($orientation,$unit,$format);
+ }
+
+ // ====================================
+ // Image with png alpha extension
+ // ====================================
+
+ //Private properties
+ var $tmpFiles = array();
+
+ /*******************************************************************************
+ * *
+ * Public methods *
+ * *
+ *******************************************************************************/
+ function Image($file,$x,$y,$w=0,$h=0,$type='',$link='', $isMask=false, $maskImg=0)
+ {
+ //Put an image on the page
+ if(!isset($this->images[$file]))
+ {
+ //First use of image, get info
+ if($type=='')
+ {
+ $pos=strrpos($file,'.');
+ if(!$pos)
+ $this->Error('Image file has no extension and no type was specified: '.$file);
+ $type=substr($file,$pos+1);
+ }
+ $type=strtolower($type);
+ $mqr=get_magic_quotes_runtime();
+ set_magic_quotes_runtime(0);
+ if($type=='jpg' || $type=='jpeg')
+ $info=$this->_parsejpg($file);
+ elseif($type=='png'){
+ $info=$this->_parsepng($file);
+ if ($info=='alpha') return $this->ImagePngWithAlpha($file,$x,$y,$w,$h,$link);
+ }
+ else
+ {
+ //Allow for additional formats
+ $mtd='_parse'.$type;
+ if(!method_exists($this,$mtd))
+ $this->Error('Unsupported image type: '.$type);
+ $info=$this->$mtd($file);
+ }
+ set_magic_quotes_runtime($mqr);
+
+ if ($isMask){
+ $info['cs']="DeviceGray"; // try to force grayscale (instead of indexed)
+ }
+ $info['i']=count($this->images)+1;
+ if ($maskImg>0) $info['masked'] = $maskImg;###
+ $this->images[$file]=$info;
+ }
+ else
+ $info=$this->images[$file];
+ //Automatic width and height calculation if needed
+ if($w==0 && $h==0)
+ {
+ //Put image at 72 dpi
+ $w=$info['w']/$this->k;
+ $h=$info['h']/$this->k;
+ }
+ if($w==0)
+ $w=$h*$info['w']/$info['h'];
+ if($h==0)
+ $h=$w*$info['h']/$info['w'];
+
+ if ($isMask) $x = $this->fwPt + 10; // embed hidden, ouside the canvas
+ $this->_out(sprintf('q %.2f 0 0 %.2f %.2f %.2f cm /I%d Do Q',$w*$this->k,$h*$this->k,$x*$this->k,($this->h-($y+$h))*$this->k,$info['i']));
+ if($link)
+ $this->Link($x,$y,$w,$h,$link);
+
+ return $info['i'];
+ }
+
+ // needs GD 2.x extension
+ // pixel-wise operation, not very fast
+ function ImagePngWithAlpha($file,$x,$y,$w=0,$h=0,$link='')
+ {
+ $tmp_alpha = tempnam('.', 'mska');
+ $this->tmpFiles[] = $tmp_alpha;
+ $tmp_plain = tempnam('.', 'mskp');
+ $this->tmpFiles[] = $tmp_plain;
+
+ list($wpx, $hpx) = getimagesize($file);
+ $img = imagecreatefrompng($file);
+ $alpha_img = imagecreate( $wpx, $hpx );
+
+ // generate gray scale pallete
+ for($c=0;$c<256;$c++) ImageColorAllocate($alpha_img, $c, $c, $c);
+
+ // extract alpha channel
+ $xpx=0;
+ while ($xpx<$wpx){
+ $ypx = 0;
+ while ($ypx<$hpx){
+ $color_index = imagecolorat($img, $xpx, $ypx);
+ $col = imagecolorsforindex($img, $color_index);
+ imagesetpixel($alpha_img, $xpx, $ypx, $this->_gamma( (127-$col['alpha'])*255/127) );
+ ++$ypx;
+ }
+ ++$xpx;
+ }
+
+ imagepng($alpha_img, $tmp_alpha);
+ imagedestroy($alpha_img);
+
+ // extract image without alpha channel
+ $plain_img = imagecreatetruecolor ( $wpx, $hpx );
+ imagecopy ($plain_img, $img, 0, 0, 0, 0, $wpx, $hpx );
+ imagepng($plain_img, $tmp_plain);
+ imagedestroy($plain_img);
+
+ //first embed mask image (w, h, x, will be ignored)
+ $maskImg = $this->Image($tmp_alpha, 0,0,0,0, 'PNG', '', true);
+
+ //embed image, masked with previously embedded mask
+ $this->Image($tmp_plain,$x,$y,$w,$h,'PNG',$link, false, $maskImg);
+ }
+
+ function Close()
+ {
+ parent::Close();
+ // clean up tmp files
+ foreach($this->tmpFiles as $tmp) @unlink($tmp);
+ }
+
+ /*******************************************************************************
+ * *
+ * Private methods *
+ * *
+ *******************************************************************************/
+ function _putimages()
+ {
+ $filter=($this->compress) ? '/Filter /FlateDecode ' : '';
+ reset($this->images);
+ while(list($file,$info)=each($this->images))
+ {
+ $this->_newobj();
+ $this->images[$file]['n']=$this->n;
+ $this->_out('<</Type /XObject');
+ $this->_out('/Subtype /Image');
+ $this->_out('/Width '.$info['w']);
+ $this->_out('/Height '.$info['h']);
+
+ if (isset($info["masked"])) $this->_out('/SMask '.($this->n-1).' 0 R'); ###
+
+ if($info['cs']=='Indexed')
+ $this->_out('/ColorSpace [/Indexed /DeviceRGB '.(strlen($info['pal'])/3-1).' '.($this->n+1).' 0 R]');
+ else
+ {
+ $this->_out('/ColorSpace /'.$info['cs']);
+ if($info['cs']=='DeviceCMYK')
+ $this->_out('/Decode [1 0 1 0 1 0 1 0]');
+ }
+ $this->_out('/BitsPerComponent '.$info['bpc']);
+ if(isset($info['f']))
+ $this->_out('/Filter /'.$info['f']);
+ if(isset($info['parms']))
+ $this->_out($info['parms']);
+ if(isset($info['trns']) && is_array($info['trns']))
+ {
+ $trns='';
+ for($i=0;$i<count($info['trns']);$i++)
+ $trns.=$info['trns'][$i].' '.$info['trns'][$i].' ';
+ $this->_out('/Mask ['.$trns.']');
+ }
+ $this->_out('/Length '.strlen($info['data']).'>>');
+ $this->_putstream($info['data']);
+ unset($this->images[$file]['data']);
+ $this->_out('endobj');
+ //Palette
+ if($info['cs']=='Indexed')
+ {
+ $this->_newobj();
+ $pal=($this->compress) ? gzcompress($info['pal']) : $info['pal'];
+ $this->_out('<<'.$filter.'/Length '.strlen($pal).'>>');
+ $this->_putstream($pal);
+ $this->_out('endobj');
+ }
+ }
+ }
+
+ // GD seems to use a different gamma, this method is used to correct it again
+ function _gamma($v){
+ return pow ($v/255, 2.2) * 255;
+ }
+
+ function _parsegif($file)
+ {
+ //Function by Jerome Fenal
+ require_once(BASECLASSES.'/fpdi/gif.php'); //GIF class in pure PHP from Yamasoft (formerly at http://www.yamasoft.com)
+
+ $h=0;
+ $w=0;
+ $gif=new CGIF();
+
+ if (!$gif->loadFile($file, 0))
+ $this->Error("GIF parser: unable to open file $file");
+
+ if($gif->m_img->m_gih->m_bLocalClr) {
+ $nColors = $gif->m_img->m_gih->m_nTableSize;
+ $pal = $gif->m_img->m_gih->m_colorTable->toString();
+ if($bgColor != -1) {
+ $bgColor = $gif->m_img->m_gih->m_colorTable->colorIndex($bgColor);
+ }
+ $colspace='Indexed';
+ } elseif($gif->m_gfh->m_bGlobalClr) {
+ $nColors = $gif->m_gfh->m_nTableSize;
+ $pal = $gif->m_gfh->m_colorTable->toString();
+ if($bgColor != -1) {
+ $bgColor = $gif->m_gfh->m_colorTable->colorIndex($bgColor);
+ }
+ $colspace='Indexed';
+ } else {
+ $nColors = 0;
+ $bgColor = -1;
+ $colspace='DeviceGray';
+ $pal='';
+ }
+
+ $trns='';
+ if($gif->m_img->m_bTrans && ($nColors > 0)) {
+ $trns=array($gif->m_img->m_nTrans);
+ }
+
+ $data=$gif->m_img->m_data;
+ $w=$gif->m_gfh->m_nWidth;
+ $h=$gif->m_gfh->m_nHeight;
+
+ if($colspace=='Indexed' and empty($pal))
+ $this->Error('Missing palette in '.$file);
+
+ if ($this->compress) {
+ $data=gzcompress($data);
+ return array( 'w'=>$w, 'h'=>$h, 'cs'=>$colspace, 'bpc'=>8, 'f'=>'FlateDecode', 'pal'=>$pal, 'trns'=>$trns, 'data'=>$data);
+ } else {
+ return array( 'w'=>$w, 'h'=>$h, 'cs'=>$colspace, 'bpc'=>8, 'pal'=>$pal, 'trns'=>$trns, 'data'=>$data);
+ }
+}
+
+ // this method overwriing the original version is only needed to make the Image method support PNGs with alpha channels.
+ // if you only use the ImagePngWithAlpha method for such PNGs, you can remove it from this script.
+ function _parsepng($file)
+ {
+ //Extract info from a PNG file
+ $f=fopen($file,'rb');
+ if(!$f)
+ $this->Error('Can\'t open image file: '.$file);
+ //Check signature
+ if(fread($f,8)!=chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10))
+ $this->Error('Not a PNG file: '.$file);
+ //Read header chunk
+ fread($f,4);
+ if(fread($f,4)!='IHDR')
+ $this->Error('Incorrect PNG file: '.$file);
+ $w=$this->_freadint($f);
+ $h=$this->_freadint($f);
+ $bpc=ord(fread($f,1));
+ if($bpc>8)
+ $this->Error('16-bit depth not supported: '.$file);
+ $ct=ord(fread($f,1));
+ if($ct==0)
+ $colspace='DeviceGray';
+ elseif($ct==2)
+ $colspace='DeviceRGB';
+ elseif($ct==3)
+ $colspace='Indexed';
+ else {
+ fclose($f); // the only changes are
+ return 'alpha'; // made in those 2 lines
+ }
+ if(ord(fread($f,1))!=0)
+ $this->Error('Unknown compression method: '.$file);
+ if(ord(fread($f,1))!=0)
+ $this->Error('Unknown filter method: '.$file);
+ if(ord(fread($f,1))!=0)
+ $this->Error('Interlacing not supported: '.$file);
+ fread($f,4);
+ $parms='/DecodeParms <</Predictor 15 /Colors '.($ct==2 ? 3 : 1).' /BitsPerComponent '.$bpc.' /Columns '.$w.'>>';
+ //Scan chunks looking for palette, transparency and image data
+ $pal='';
+ $trns='';
+ $data='';
+ do
+ {
+ $n=$this->_freadint($f);
+ $type=fread($f,4);
+ if($type=='PLTE')
+ {
+ //Read palette
+ $pal=fread($f,$n);
+ fread($f,4);
+ }
+ elseif($type=='tRNS')
+ {
+ //Read transparency info
+ $t=fread($f,$n);
+ if($ct==0)
+ $trns=array(ord(substr($t,1,1)));
+ elseif($ct==2)
+ $trns=array(ord(substr($t,1,1)),ord(substr($t,3,1)),ord(substr($t,5,1)));
+ else
+ {
+ $pos=strpos($t,chr(0));
+ if($pos!==false)
+ $trns=array($pos);
+ }
+ fread($f,4);
+ }
+ elseif($type=='IDAT')
+ {
+ //Read image data block
+ $data.=fread($f,$n);
+ fread($f,4);
+ }
+ elseif($type=='IEND')
+ break;
+ else
+ fread($f,$n+4);
+ }
+ while($n);
+ if($colspace=='Indexed' && empty($pal))
+ $this->Error('Missing palette in '.$file);
+ fclose($f);
+ return array('w'=>$w,'h'=>$h,'cs'=>$colspace,'bpc'=>$bpc,'f'=>'FlateDecode','parms'=>$parms,'pal'=>$pal,'trns'=>$trns,'data'=>$data);
+ }
+
+ var $angle=0;
+
+ function Rotate($angle, $x=-1, $y=-1)
+ {
+ if($x==-1)
+ $x=$this->x;
+ if($y==-1)
+ $y=$this->y;
+ if($this->angle!=0)
+ $this->_out('Q');
+ $this->angle=$angle;
+ if($angle!=0)
+ {
+ $angle*=M_PI/180;
+ $c=cos($angle);
+ $s=sin($angle);
+ $cx=$x*$this->k;
+ $cy=($this->h-$y)*$this->k;
+ $this->_out(sprintf('q %.5f %.5f %.5f %.5f %.2f %.2f cm 1 0 0 1 %.2f %.2f cm', $c, $s, -$s, $c, $cx, $cy, -$cx, -$cy));
+ }
+ }
+
+ function _endpage()
+ {
+ if($this->angle!=0)
+ {
+ $this->angle=0;
+ $this->_out('Q');
+ }
+ parent::_endpage();
+ }
+
+ function RotatedText($x, $y, $txt, $angle)
+ {
+ //Text rotated around its origin
+ $this->Rotate($angle, $x, $y);
+ $this->Text($x, $y, $txt);
+ $this->Rotate(0);
+ }
+
+}
+
+?>
\ No newline at end of file
More information about the Mapbender_commits
mailing list