Helix Installation   Getting Started   Reference Documentation   Global Functions   Quick Start
ModulesClassesFunctions
 

Class Reference

class cpdf

Helixcpdf
Hide Inherited MembersHelix Core
Description
No description.
 
Constants
No constants.
 
Properties
publicaddLooseObjects[ cpdf ]
publicarc4[ cpdf ]
publicarc4_objnum[ cpdf ]
publiccallback[ cpdf ]
publiccatalogId[ cpdf ]
publiccheckpoint[ cpdf ]
publiccurrentBaseFont[ cpdf ]
publiccurrentColour[ cpdf ]
publiccurrentContents[ cpdf ]
publiccurrentFont[ cpdf ]
publiccurrentFontNum[ cpdf ]
publiccurrentLineStyle[ cpdf ]
publiccurrentNode[ cpdf ]
publiccurrentPage[ cpdf ]
publiccurrentStrokeColour[ cpdf ]
publiccurrentTextState[ cpdf ]
publicdestinations[ cpdf ]
publicencrypted[ cpdf ]
publicencryptionKey[ cpdf ]
publicfileIdentifier[ cpdf ]
publicfirstPageId[ cpdf ]
publicfontFamilies[ cpdf ]
publicfonts[ cpdf ]
publicinfoObject[ cpdf ]
publiclooseObjects[ cpdf ]
publicmessages[ cpdf ]
publicnCallback[ cpdf ]
publicnStack[ cpdf ]
publicnStateStack[ cpdf ]
publicnumFonts[ cpdf ]
publicnumImages[ cpdf ]
publicnumObj[ cpdf ]
publicnumPages[ cpdf ]
publicobjects[ cpdf ]
publicoptions[ cpdf ]
publicprocsetObjectId[ cpdf ]
publicstack[ cpdf ]
publicstateStack[ cpdf ]
publicwordSpaceAdjust[ cpdf ]
 
Methods
publicARC4 ( text )[ cpdf ]
Parameters
requiredtext
Code
1122  function ARC4($text){
1123    $len=strlen($text);
1124    $a=0;
1125    $b=0;
1126    $c = $this->arc4;
1127    $out='';
1128    for ($i=0;$i<$len;$i++){
1129      $a = ($a+1)%256;
1130      $t= $c[$a];
1131      $b = ($b+ord($t))%256;
1132      $c[$a]=$c[$b];
1133      $c[$b]=$t;
1134      $k = ord($c[(ord($c[$a])+ord($c[$b]))%256]);
1135      $out.=chr(ord($text[$i]) ^ $k);
1136    }
1137 
1138    return $out;
1139  }
publicARC4_init ( key [""] )[ cpdf ]
Parameters
optionalkey [""]
Code
1096  function ARC4_init($key=''){
1097    $this->arc4 = '';
1098    // setup the control array
1099    if (strlen($key)==0){
1100      return;
1101    }
1102    $k = '';
1103    while(strlen($k)<256){
1104      $k.=$key;
1105    }
1106    $k=substr($k,0,256);
1107    for ($i=0;$i<256;$i++){
1108      $this->arc4 .= chr($i);
1109    }
1110    $j=0;
1111    for ($i=0;$i<256;$i++){
1112      $t = $this->arc4[$i];
1113      $j = ($j + ord($t) + ord($k[$i]))%256;
1114      $this->arc4[$i]=$this->arc4[$j];
1115      $this->arc4[$j]=$t;
1116    }
1117  }
publicPRVT_getBytes ( &data , pos , num )[ cpdf ]
Parameters
required&data
requiredpos
requirednum
Code
2616  function PRVT_getBytes(&$data,$pos,$num){
2617    // return the integer represented by $num bytes from $pos within $data
2618    $ret=0;
2619    for ($i=0;$i<$num;$i++){
2620      $ret=$ret*256;
2621      $ret+=ord($data[$pos+$i]);
2622    }
2623    return $ret;
2624  }
publicPRVTadjustWrapText ( text , actual , width , &x , &adjust , justification )[ cpdf ]
Parameters
requiredtext
requiredactual
requiredwidth
required&x
required&adjust
requiredjustification
Code
2294  function PRVTadjustWrapText($text,$actual,$width,&$x,&$adjust,$justification){
2295    switch ($justification){
2296      case 'left':
2297        return;
2298      case 'right':
2299        $x+=$width-$actual;
2300        break;
2301      case 'center':
2302      case 'centre':
2303        $x+=($width-$actual)/2;
2304        break;
2305      case 'full':
2306        // count the number of words
2307        $words = explode(' ',$text);
2308        $nspaces=count($words)-1;
2309        if ($nspaces>0){
2310          $adjust = ($width-$actual)/$nspaces;
2311        } else {
2312          $adjust=0;
2313        }
2314        break;
2315    }
2316  }
publicPRVTcheckTextDirective ( &text , i , &f )[ cpdf ]
Parameters
required&text
requiredi
required&f
Code
1987  function PRVTcheckTextDirective(&$text,$i,&$f){
1988    $x=0;
1989    $y=0;
1990    return $this->PRVTcheckTextDirective1($text,$i,$f,0,$x,$y);
1991  }
publicPRVTcheckTextDirective1 ( &text , i , &f , final , &x , &y , size [0] , angle [0] , wordSpaceAdjust [0] )[ cpdf ]
Parameters
required&text
requiredi
required&f
requiredfinal
required&x
required&y
optionalsize [0]
optionalangle [0]
optionalwordSpaceAdjust [0]
Code
2002  function PRVTcheckTextDirective1(&$text,$i,&$f,$final,&$x,&$y,$size=0,$angle=0,$wordSpaceAdjust=0){
2003    $directive = 0;
2004    $j=$i;
2005    if ($text[$j]=='<'){
2006      $j++;
2007      switch($text[$j]){
2008        case '/':
2009          $j++;
2010          if (strlen($text) <= $j){
2011            return $directive;
2012          }
2013          switch($text[$j]){
2014            case 'b':
2015            case 'i':
2016              $j++;
2017              if ($text[$j]=='>'){
2018                $p = strrpos($this->currentTextState,$text[$j-1]);
2019                if ($p !== false){
2020                  // then there is one to remove
2021                  $this->currentTextState = substr($this->currentTextState,0,$p).substr($this->currentTextState,$p+1);
2022                }
2023                $directive=$j-$i+1;
2024              }
2025              break;
2026            case 'c':
2027              // this this might be a callback function
2028              $j++;
2029              $k = strpos($text,'>',$j);
2030              if ($k!==false && $text[$j]==':'){
2031                // then this will be treated as a callback directive
2032                $directive = $k-$i+1;
2033                $f=0;
2034                // split the remainder on colons to get the function name and the paramater
2035                $tmp = substr($text,$j+1,$k-$j-1);
2036                $b1 = strpos($tmp,':');
2037                if ($b1!==false){
2038                  $func = substr($tmp,0,$b1);
2039                  $parm = substr($tmp,$b1+1);
2040                } else {
2041                  $func=$tmp;
2042                  $parm='';
2043                }
2044                if (!isset($func) || !strlen(trim($func))){
2045                  $directive=0;
2046                } else {
2047                  // only call the function if this is the final call
2048                  if ($final){
2049                    // need to assess the text position, calculate the text width to this point
2050                    // can use getTextWidth to find the text width I think
2051                    $tmp = $this->PRVTgetTextPosition($x,$y,$angle,$size,$wordSpaceAdjust,substr($text,0,$i));
2052                    $info = array('x'=>$tmp[0],'y'=>$tmp[1],'angle'=>$angle,'status'=>'end','p'=>$parm,'nCallback'=>$this->nCallback);
2053                    $x=$tmp[0];
2054                    $y=$tmp[1];
2055                    $ret = $this->$func($info);
2056                    if (is_array($ret)){
2057                      // then the return from the callback function could set the position, to start with, later will do font colour, and font
2058                      foreach($ret as $rk=>$rv){
2059                        switch($rk){
2060                          case 'x':
2061                          case 'y':
2062                            $$rk=$rv;
2063                            break;
2064                        }
2065                      }
2066                    }
2067                    // also remove from to the stack
2068                    // for simplicity, just take from the end, fix this another day
2069                    $this->nCallback--;
2070                    if ($this->nCallback<0){
2071                      $this->nCallBack=0;
2072                    }
2073                  }
2074                }
2075              }
2076              break;
2077          }
2078          break;
2079        case 'b':
2080        case 'i':
2081          $j++;
2082          if ($text[$j]=='>'){
2083            $this->currentTextState.=$text[$j-1];
2084            $directive=$j-$i+1;
2085          }
2086          break;
2087        case 'C':
2088          $noClose=1;
2089        case 'c':
2090          // this this might be a callback function
2091          $j++;
2092          $k = strpos($text,'>',$j);
2093          if ($k!==false && $text[$j]==':'){
2094            // then this will be treated as a callback directive
2095            $directive = $k-$i+1;
2096            $f=0;
2097            // split the remainder on colons to get the function name and the paramater
2098  //          $bits = explode(':',substr($text,$j+1,$k-$j-1));
2099            $tmp = substr($text,$j+1,$k-$j-1);
2100            $b1 = strpos($tmp,':');
2101            if ($b1!==false){
2102              $func = substr($tmp,0,$b1);
2103              $parm = substr($tmp,$b1+1);
2104            } else {
2105              $func=$tmp;
2106              $parm='';
2107            }
2108            if (!isset($func) || !strlen(trim($func))){
2109              $directive=0;
2110            } else {
2111              // only call the function if this is the final call, ie, the one actually doing printing, not measurement
2112              if ($final){
2113                // need to assess the text position, calculate the text width to this point
2114                // can use getTextWidth to find the text width I think
2115                // also add the text height and decender
2116                $tmp = $this->PRVTgetTextPosition($x,$y,$angle,$size,$wordSpaceAdjust,substr($text,0,$i));
2117                $info = array('x'=>$tmp[0],'y'=>$tmp[1],'angle'=>$angle,'status'=>'start','p'=>$parm,'f'=>$func,'height'=>$this->getFontHeight($size),'decender'=>$this->getFontDecender($size));
2118                $x=$tmp[0];
2119                $y=$tmp[1];
2120                if (!isset($noClose) || !$noClose){
2121                  // only add to the stack if this is a small 'c', therefore is a start-stop pair
2122                  $this->nCallback++;
2123                  $info['nCallback']=$this->nCallback;
2124                  $this->callback[$this->nCallback]=$info;
2125                }
2126                $ret = $this->$func($info);
2127                if (is_array($ret)){
2128                  // then the return from the callback function could set the position, to start with, later will do font colour, and font
2129                  foreach($ret as $rk=>$rv){
2130                    switch($rk){
2131                      case 'x':
2132                      case 'y':
2133                        $$rk=$rv;
2134                        break;
2135                    }
2136                  }
2137                }
2138              }
2139            }
2140          }
2141          break;
2142      }
2143    }
2144    return $directive;
2145  }
publicPRVTgetTextPosition ( x , y , angle , size , wa , text )[ cpdf ]
Parameters
requiredx
requiredy
requiredangle
requiredsize
requiredwa
requiredtext
Code
1971  function PRVTgetTextPosition($x,$y,$angle,$size,$wa,$text){
1972    // given this information return an array containing x and y for the end position as elements 0 and 1
1973    $w = $this->getTextWidth($size,$text);
1974    // need to adjust for the number of spaces in this text
1975    $words = explode(' ',$text);
1976    $nspaces=count($words)-1;
1977    $w += $wa*$nspaces;
1978    $a = deg2rad((float)$angle);
1979    return array(cos($a)*$w+$x,-sin($a)*$w+$y);
1980  }
publicaddContent ( content )[ cpdf ]
Parameters
requiredcontent
Code
1632  function addContent($content){
1633    $this->objects[$this->currentContents]['c'].=$content;
1634  }
publicaddDestination ( label , style , a [0] , b [0] , c [0] )[ cpdf ]
Parameters
requiredlabel
requiredstyle
optionala [0]
optionalb [0]
optionalc [0]
Code
2962  function addDestination($label,$style,$a=0,$b=0,$c=0){
2963    // associates the given label with the destination, it is done this way so that a destination can be specified after
2964    // it has been linked to
2965    // styles are the same as the 'openHere' function
2966    $this->numObj++;
2967    $this->o_destination($this->numObj,'new',array('page'=>$this->currentPage,'type'=>$style,'p1'=>$a,'p2'=>$b,'p3'=>$c));
2968    $id = $this->numObj;
2969    // store the label->idf relationship, note that this means that labels can be used only once
2970    $this->destinations["$label"]=$id;
2971  }
publicaddImage ( &img , x , y , w [0] , h [0] , quality [75] )[ cpdf ]
Parameters
required&img
requiredx
requiredy
optionalw [0]
optionalh [0]
optionalquality [75]
Code
2863  function addImage(&$img,$x,$y,$w=0,$h=0,$quality=75){
2864    // add a new image into the current location, as an external object
2865    // add the image at $x,$y, and with width and height as defined by $w & $h
2866 
2867    // note that this will only work with full colour images and makes them jpg images for display
2868    // later versions could present lossless image formats if there is interest.
2869 
2870    // there seems to be some problem here in that images that have quality set above 75 do not appear
2871    // not too sure why this is, but in the meantime I have restricted this to 75.
2872    if ($quality>75){
2873      $quality=75;
2874    }
2875 
2876    // if the width or height are set to zero, then set the other one based on keeping the image
2877    // height/width ratio the same, if they are both zero, then give up :)
2878    $imageWidth=imagesx($img);
2879    $imageHeight=imagesy($img);
2880 
2881    if ($w<=0 && $h<=0){
2882      return;
2883    }
2884    if ($w==0){
2885      $w=$h/$imageHeight*$imageWidth;
2886    }
2887    if ($h==0){
2888      $h=$w*$imageHeight/$imageWidth;
2889    }
2890 
2891    // gotta get the data out of the img..
2892 
2893    // so I write to a temp file, and then read it back.. soo ugly, my apologies.
2894    $tmpDir='/tmp';
2895    $tmpName=tempnam($tmpDir,'img');
2896    imagejpeg($img,$tmpName,$quality);
2897    $fp=fopen($tmpName,'rb');
2898 
2899    $tmp = get_magic_quotes_runtime();
2900    set_magic_quotes_runtime(0);
2901    $fp = @fopen($tmpName,'rb');
2902    if ($fp){
2903      $data='';
2904      while(!feof($fp)){
2905        $data .= fread($fp,1024);
2906      }
2907      fclose($fp);
2908    } else {
2909      $error = 1;
2910      $errormsg = 'trouble opening file';
2911    }
2912  //  $data = fread($fp,filesize($tmpName));
2913    set_magic_quotes_runtime($tmp);
2914  //  fclose($fp);
2915    unlink($tmpName);
2916    $this->addJpegImage_common($data,$x,$y,$w,$h,$imageWidth,$imageHeight);
2917  }
publicaddInfo ( label , value [0] )[ cpdf ]
Parameters
requiredlabel
optionalvalue [0]
Code
2583  function addInfo($label,$value=0){
2584    // this will only work if the label is one of the valid ones.
2585    // modify this so that arrays can be passed as well.
2586    // if $label is an array then assume that it is key=>value pairs
2587    // else assume that they are both scalar, anything else will probably error
2588    if (is_array($label)){
2589      foreach ($label as $l=>$v){
2590        $this->o_info($this->infoObject,$l,$v);
2591      }
2592    } else {
2593      $this->o_info($this->infoObject,$label,$value);
2594    }
2595  }
publicaddInternalLink ( label , x0 , y0 , x1 , y1 )[ cpdf ]
publicaddJpegFromFile ( img , x , y , w [0] , h [0] )[ cpdf ]
Parameters
requiredimg
requiredx
requiredy
optionalw [0]
optionalh [0]
Code
2818  function addJpegFromFile($img,$x,$y,$w=0,$h=0){
2819    // attempt to add a jpeg image straight from a file, using no GD commands
2820    // note that this function is unable to operate on a remote file.
2821 
2822    if (!file_exists($img)){
2823      return;
2824    }
2825 
2826    $tmp=getimagesize($img);
2827    $imageWidth=$tmp[0];
2828    $imageHeight=$tmp[1];
2829 
2830    if (isset($tmp['channels'])){
2831      $channels = $tmp['channels'];
2832    } else {
2833      $channels = 3;
2834    }
2835 
2836    if ($w<=0 && $h<=0){
2837      $w=$imageWidth;
2838    }
2839    if ($w==0){
2840      $w=$h/$imageHeight*$imageWidth;
2841    }
2842    if ($h==0){
2843      $h=$w*$imageHeight/$imageWidth;
2844    }
2845 
2846    $fp=fopen($img,'rb');
2847 
2848    $tmp = get_magic_quotes_runtime();
2849    set_magic_quotes_runtime(0);
2850    $data = fread($fp,filesize($img));
2851    set_magic_quotes_runtime($tmp);
2852 
2853    fclose($fp);
2854 
2855    $this->addJpegImage_common($data,$x,$y,$w,$h,$imageWidth,$imageHeight,$channels);
2856  }
publicaddJpegImage_common ( &data , x , y , w , h , imageWidth , imageHeight , channels [3] )[ cpdf ]
Parameters
required&data
requiredx
requiredy
requiredw
requiredh
requiredimageWidth
requiredimageHeight
optionalchannels [3]
Code
2924  function addJpegImage_common(&$data,$x,$y,$w=0,$h=0,$imageWidth,$imageHeight,$channels=3){
2925    // note that this function is not to be called externally
2926    // it is just the common code between the GD and the file options
2927    $this->numImages++;
2928    $im=$this->numImages;
2929    $label='I'.$im;
2930    $this->numObj++;
2931    $this->o_image($this->numObj,'new',array('label'=>$label,'data'=>$data,'iw'=>$imageWidth,'ih'=>$imageHeight,'channels'=>$channels));
2932 
2933    $this->objects[$this->currentContents]['c'].="\nq";
2934    $this->objects[$this->currentContents]['c'].="\n".sprintf('%.3f',$w)." 0 0 ".sprintf('%.3f',$h)." ".sprintf('%.3f',$x)." ".sprintf('%.3f',$y)." cm";
2935    $this->objects[$this->currentContents]['c'].="\n/".$label.' Do';
2936    $this->objects[$this->currentContents]['c'].="\nQ";
2937  }
publicaddLink ( url , x0 , y0 , x1 , y1 )[ cpdf ]
publicaddMessage ( message )[ cpdf ]
Parameters
requiredmessage
Code
3015  function addMessage($message){
3016    $this->messages.=$message."\n";
3017  }
publicaddObject ( id , options ["add"] )[ cpdf ]
Parameters
requiredid
optionaloptions ["add"]
Code
2537  function addObject($id,$options='add'){
2538    // add the specified object to the page
2539    if (isset($this->looseObjects[$id]) && $this->currentContents!=$id){
2540      // then it is a valid object, and it is not being added to itself
2541      switch($options){
2542        case 'all':
2543          // then this object is to be added to this page (done in the next block) and
2544          // all future new pages.
2545          $this->addLooseObjects[$id]='all';
2546        case 'add':
2547          if (isset($this->objects[$this->currentContents]['onPage'])){
2548            // then the destination contents is the primary for the page
2549            // (though this object is actually added to that page)
2550            $this->o_page($this->objects[$this->currentContents]['onPage'],'content',$id);
2551          }
2552          break;
2553        case 'even':
2554          $this->addLooseObjects[$id]='even';
2555          $pageObjectId=$this->objects[$this->currentContents]['onPage'];
2556          if ($this->objects[$pageObjectId]['info']['pageNum']%2==0){
2557            $this->addObject($id); // hacky huh :)
2558          }
2559          break;
2560        case 'odd':
2561          $this->addLooseObjects[$id]='odd';
2562          $pageObjectId=$this->objects[$this->currentContents]['onPage'];
2563          if ($this->objects[$pageObjectId]['info']['pageNum']%2==1){
2564            $this->addObject($id); // hacky huh :)
2565          }
2566          break;
2567        case 'next':
2568          $this->addLooseObjects[$id]='all';
2569          break;
2570        case 'nexteven':
2571          $this->addLooseObjects[$id]='even';
2572          break;
2573        case 'nextodd':
2574          $this->addLooseObjects[$id]='odd';
2575          break;
2576      }
2577    }
2578  }
publicaddPngFromFile ( file , x , y , w [0] , h [0] )[ cpdf ]
Parameters
requiredfile
requiredx
requiredy
optionalw [0]
optionalh [0]
Code
2630  function addPngFromFile($file,$x,$y,$w=0,$h=0){
2631    // read in a png file, interpret it, then add to the system
2632    $error=0;
2633    $tmp = get_magic_quotes_runtime();
2634    set_magic_quotes_runtime(0);
2635    $fp = @fopen($file,'rb');
2636    if ($fp){
2637      $data='';
2638      while(!feof($fp)){
2639        $data .= fread($fp,1024);
2640      }
2641      fclose($fp);
2642    } else {
2643      $error = 1;
2644      $errormsg = 'trouble opening file: '.$file;
2645    }
2646    set_magic_quotes_runtime($tmp);
2647 
2648    if (!$error){
2649      $header = chr(137).chr(80).chr(78).chr(71).chr(13).chr(10).chr(26).chr(10);
2650      if (substr($data,0,8)!=$header){
2651        $error=1;
2652        $errormsg = 'this file does not have a valid header';
2653      }
2654    }
2655 
2656    if (!$error){
2657      // set pointer
2658      $p = 8;
2659      $len = strlen($data);
2660      // cycle through the file, identifying chunks
2661      $haveHeader=0;
2662      $info=array();
2663      $idata='';
2664      $pdata='';
2665      while ($p<$len){
2666        $chunkLen = $this->PRVT_getBytes($data,$p,4);
2667        $chunkType = substr($data,$p+4,4);
2668  //      echo $chunkType.' - '.$chunkLen.'<br>';
2669 
2670        switch($chunkType){
2671          case 'IHDR':
2672            // this is where all the file information comes from
2673            $info['width']=$this->PRVT_getBytes($data,$p+8,4);
2674            $info['height']=$this->PRVT_getBytes($data,$p+12,4);
2675            $info['bitDepth']=ord($data[$p+16]);
2676            $info['colorType']=ord($data[$p+17]);
2677            $info['compressionMethod']=ord($data[$p+18]);
2678            $info['filterMethod']=ord($data[$p+19]);
2679            $info['interlaceMethod']=ord($data[$p+20]);
2680  //print_r($info);
2681            $haveHeader=1;
2682            if ($info['compressionMethod']!=0){
2683              $error=1;
2684              $errormsg = 'unsupported compression method';
2685            }
2686            if ($info['filterMethod']!=0){
2687              $error=1;
2688              $errormsg = 'unsupported filter method';
2689            }
2690            break;
2691          case 'PLTE':
2692            $pdata.=substr($data,$p+8,$chunkLen);
2693            break;
2694          case 'IDAT':
2695            $idata.=substr($data,$p+8,$chunkLen);
2696            break;
2697          case 'tRNS':
2698            //this chunk can only occur once and it must occur after the PLTE chunk and before IDAT chunk
2699            //print "tRNS found, color type = ".$info['colorType']."<BR>";
2700            $transparency = array();
2701            if ($info['colorType'] == 3) { // indexed color, rbg
2702            /* corresponding to entries in the plte chunk
2703            Alpha for palette index 0: 1 byte
2704            Alpha for palette index 1: 1 byte
2705            ...etc...
2706            */
2707              // there will be one entry for each palette entry. up until the last non-opaque entry.
2708              // set up an array, stretching over all palette entries which will be o (opaque) or 1 (transparent)
2709              $transparency['type']='indexed';
2710              $numPalette = strlen($pdata)/3;
2711              $trans=0;
2712              for ($i=$chunkLen;$i>=0;$i--){
2713                if (ord($data[$p+8+$i])==0){
2714                  $trans=$i;
2715                }
2716              }
2717              $transparency['data'] = $trans;
2718 
2719            } elseif($info['colorType'] == 0) { // grayscale
2720            /* corresponding to entries in the plte chunk
2721            Gray: 2 bytes, range 0 .. (2^bitdepth)-1
2722            */
2723  //            $transparency['grayscale']=$this->PRVT_getBytes($data,$p+8,2); // g = grayscale
2724              $transparency['type']='indexed';
2725              $transparency['data'] = ord($data[$p+8+1]);
2726 
2727            } elseif($info['colorType'] == 2) { // truecolor
2728            /* corresponding to entries in the plte chunk
2729            Red: 2 bytes, range 0 .. (2^bitdepth)-1
2730            Green: 2 bytes, range 0 .. (2^bitdepth)-1
2731            Blue: 2 bytes, range 0 .. (2^bitdepth)-1
2732            */
2733              $transparency['r']=$this->PRVT_getBytes($data,$p+8,2); // r from truecolor
2734              $transparency['g']=$this->PRVT_getBytes($data,$p+10,2); // g from truecolor
2735              $transparency['b']=$this->PRVT_getBytes($data,$p+12,2); // b from truecolor
2736 
2737            } else {
2738            //unsupported transparency type
2739            }
2740            // KS End new code
2741            break;
2742          default:
2743            break;
2744        }
2745 
2746        $p += $chunkLen+12;
2747      }
2748 
2749      if(!$haveHeader){
2750        $error = 1;
2751        $errormsg = 'information header is missing';
2752      }
2753      if (isset($info['interlaceMethod']) && $info['interlaceMethod']){
2754        $error = 1;
2755        $errormsg = 'There appears to be no support for interlaced images in pdf.';
2756      }
2757    }
2758 
2759    if (!$error && $info['bitDepth'] > 8){
2760      $error = 1;
2761      $errormsg = 'only bit depth of 8 or less is supported';
2762    }
2763 
2764    if (!$error){
2765      if ($info['colorType']!=2 && $info['colorType']!=0 && $info['colorType']!=3){
2766        $error = 1;
2767        $errormsg = 'transparancey alpha channel not supported, transparency only supported for palette images.';
2768      } else {
2769        switch ($info['colorType']){
2770          case 3:
2771            $color = 'DeviceRGB';
2772            $ncolor=1;
2773            break;
2774          case 2:
2775            $color = 'DeviceRGB';
2776            $ncolor=3;
2777            break;
2778          case 0:
2779            $color = 'DeviceGray';
2780            $ncolor=1;
2781            break;
2782        }
2783      }
2784    }
2785    if ($error){
2786      $this->addMessage('PNG error - ('.$file.') '.$errormsg);
2787      return;
2788    }
2789    if ($w==0){
2790      $w=$h/$info['height']*$info['width'];
2791    }
2792    if ($h==0){
2793      $h=$w*$info['height']/$info['width'];
2794    }
2795  //print_r($info);
2796    // so this image is ok... add it in.
2797    $this->numImages++;
2798    $im=$this->numImages;
2799    $label='I'.$im;
2800    $this->numObj++;
2801  //  $this->o_image($this->numObj,'new',array('label'=>$label,'data'=>$idata,'iw'=>$w,'ih'=>$h,'type'=>'png','ic'=>$info['width']));
2802    $options = array('label'=>$label,'data'=>$idata,'bitsPerComponent'=>$info['bitDepth'],'pdata'=>$pdata
2803                                        ,'iw'=>$info['width'],'ih'=>$info['height'],'type'=>'png','color'=>$color,'ncolor'=>$ncolor);
2804    if (isset($transparency)){
2805      $options['transparency']=$transparency;
2806    }
2807    $this->o_image($this->numObj,'new',$options);
2808 
2809    $this->objects[$this->currentContents]['c'].="\nq";
2810    $this->objects[$this->currentContents]['c'].="\n".sprintf('%.3f',$w)." 0 0 ".sprintf('%.3f',$h)." ".sprintf('%.3f',$x)." ".sprintf('%.3f',$y)." cm";
2811    $this->objects[$this->currentContents]['c'].="\n/".$label.' Do';
2812    $this->objects[$this->currentContents]['c'].="\nQ";
2813  }
publicaddText ( x , y , size , text , angle [0] , wordSpaceAdjust [0] )[ cpdf ]
Parameters
requiredx
requiredy
requiredsize
requiredtext
optionalangle [0]
optionalwordSpaceAdjust [0]
Code
2150  function addText($x,$y,$size,$text,$angle=0,$wordSpaceAdjust=0){
2151    if (!$this->numFonts){$this->selectFont(SITES  . 'helix/resources/fonts/Helvetica');}
2152 
2153    // if there are any open callbacks, then they should be called, to show the start of the line
2154    if ($this->nCallback>0){
2155      for ($i=$this->nCallback;$i>0;$i--){
2156        // call each function
2157        $info = array('x'=>$x,'y'=>$y,'angle'=>$angle,'status'=>'sol','p'=>$this->callback[$i]['p'],'nCallback'=>$this->callback[$i]['nCallback'],'height'=>$this->callback[$i]['height'],'decender'=>$this->callback[$i]['decender']);
2158        $func = $this->callback[$i]['f'];
2159        $this->$func($info);
2160      }
2161    }
2162    if ($angle==0){
2163      $this->objects[$this->currentContents]['c'].="\n".'BT '.sprintf('%.3f',$x).' '.sprintf('%.3f',$y).' Td';
2164    } else {
2165      $a = deg2rad((float)$angle);
2166      $tmp = "\n".'BT ';
2167      $tmp .= sprintf('%.3f',cos($a)).' '.sprintf('%.3f',(-1.0*sin($a))).' '.sprintf('%.3f',sin($a)).' '.sprintf('%.3f',cos($a)).' ';
2168      $tmp .= sprintf('%.3f',$x).' '.sprintf('%.3f',$y).' Tm';
2169      $this->objects[$this->currentContents]['c'] .= $tmp;
2170    }
2171    if ($wordSpaceAdjust!=0 || $wordSpaceAdjust != $this->wordSpaceAdjust){
2172      $this->wordSpaceAdjust=$wordSpaceAdjust;
2173      $this->objects[$this->currentContents]['c'].=' '.sprintf('%.3f',$wordSpaceAdjust).' Tw';
2174    }
2175    $len=strlen($text);
2176    $start=0;
2177    for ($i=0;$i<$len;$i++){
2178      $f=1;
2179      $directive = $this->PRVTcheckTextDirective($text,$i,$f);
2180      if ($directive){
2181        // then we should write what we need to
2182        if ($i>$start){
2183          $part = substr($text,$start,$i-$start);
2184          $this->objects[$this->currentContents]['c'].=' /F'.$this->currentFontNum.' '.sprintf('%.1f',$size).' Tf ';
2185          $this->objects[$this->currentContents]['c'].=' ('.$this->filterText($part).') Tj';
2186        }
2187        if ($f){
2188          // then there was nothing drastic done here, restore the contents
2189          $this->setCurrentFont();
2190        } else {
2191          $this->objects[$this->currentContents]['c'] .= ' ET';
2192          $f=1;
2193          $xp=$x;
2194          $yp=$y;
2195          $directive = $this->PRVTcheckTextDirective1($text,$i,$f,1,$xp,$yp,$size,$angle,$wordSpaceAdjust);
2196 
2197          // restart the text object
2198            if ($angle==0){
2199              $this->objects[$this->currentContents]['c'].="\n".'BT '.sprintf('%.3f',$xp).' '.sprintf('%.3f',$yp).' Td';
2200            } else {
2201              $a = deg2rad((float)$angle);
2202              $tmp = "\n".'BT ';
2203              $tmp .= sprintf('%.3f',cos($a)).' '.sprintf('%.3f',(-1.0*sin($a))).' '.sprintf('%.3f',sin($a)).' '.sprintf('%.3f',cos($a)).' ';
2204              $tmp .= sprintf('%.3f',$xp).' '.sprintf('%.3f',$yp).' Tm';
2205              $this->objects[$this->currentContents]['c'] .= $tmp;
2206            }
2207            if ($wordSpaceAdjust!=0 || $wordSpaceAdjust != $this->wordSpaceAdjust){
2208              $this->wordSpaceAdjust=$wordSpaceAdjust;
2209              $this->objects[$this->currentContents]['c'].=' '.sprintf('%.3f',$wordSpaceAdjust).' Tw';
2210            }
2211        }
2212        // and move the writing point to the next piece of text
2213        $i=$i+$directive-1;
2214        $start=$i+1;
2215      }
2216 
2217    }
2218    if ($start<$len){
2219      $part = substr($text,$start);
2220      $this->objects[$this->currentContents]['c'].=' /F'.$this->currentFontNum.' '.sprintf('%.1f',$size).' Tf ';
2221      $this->objects[$this->currentContents]['c'].=' ('.$this->filterText($part).') Tj';
2222    }
2223    $this->objects[$this->currentContents]['c'].=' ET';
2224 
2225    // if there are any open callbacks, then they should be called, to show the end of the line
2226    if ($this->nCallback>0){
2227      for ($i=$this->nCallback;$i>0;$i--){
2228        // call each function
2229        $tmp = $this->PRVTgetTextPosition($x,$y,$angle,$size,$wordSpaceAdjust,$text);
2230        $info = array('x'=>$tmp[0],'y'=>$tmp[1],'angle'=>$angle,'status'=>'eol','p'=>$this->callback[$i]['p'],'nCallback'=>$this->callback[$i]['nCallback'],'height'=>$this->callback[$i]['height'],'decender'=>$this->callback[$i]['decender']);
2231        $func = $this->callback[$i]['f'];
2232        $this->$func($info);
2233      }
2234    }
2235 
2236  }
publicaddTextWrap ( x , y , width , size , text , justification ["left"] , angle [0] , test [0] )[ cpdf ]
Parameters
requiredx
requiredy
requiredwidth
requiredsize
requiredtext
optionaljustification ["left"]
optionalangle [0]
optionaltest [0]
Code
2324  function addTextWrap($x,$y,$width,$size,$text,$justification='left',$angle=0,$test=0){
2325    // this will display the text, and if it goes beyond the width $width, will backtrack to the
2326    // previous space or hyphen, and return the remainder of the text.
2327 
2328    // $justification can be set to 'left','right','center','centre','full'
2329 
2330    // need to store the initial text state, as this will change during the width calculation
2331    // but will need to be re-set before printing, so that the chars work out right
2332    $store_currentTextState = $this->currentTextState;
2333 
2334    if (!$this->numFonts){$this->selectFont(SITES . 'helix/resources/fonts/Helvetica');}
2335    if ($width<=0){
2336      // error, pretend it printed ok, otherwise risking a loop
2337      return '';
2338    }
2339    $w=0;
2340    $break=0;
2341    $breakWidth=0;
2342    $len=strlen($text);
2343    $cf = $this->currentFont;
2344    $tw = $width/$size*1000;
2345    for ($i=0;$i<$len;$i++){
2346      $f=1;
2347      $directive = $this->PRVTcheckTextDirective($text,$i,$f);
2348      if ($directive){
2349        if ($f){
2350          $this->setCurrentFont();
2351          $cf = $this->currentFont;
2352        }
2353        $i=$i+$directive-1;
2354      } else {
2355        $cOrd = ord($text[$i]);
2356        if (isset($this->fonts[$cf]['differences'][$cOrd])){
2357          // then this character is being replaced by another
2358          $cOrd2 = $this->fonts[$cf]['differences'][$cOrd];
2359        } else {
2360          $cOrd2 = $cOrd;
2361        }
2362 
2363        if (isset($this->fonts[$cf]['C'][$cOrd2]['WX'])){
2364          $w+=$this->fonts[$cf]['C'][$cOrd2]['WX'];
2365        }
2366        if ($w>$tw){
2367          // then we need to truncate this line
2368          if ($break>0){
2369            // then we have somewhere that we can split :)
2370            if ($text[$break]==' '){
2371              $tmp = substr($text,0,$break);
2372            } else {
2373              $tmp = substr($text,0,$break+1);
2374            }
2375            $adjust=0;
2376            $this->PRVTadjustWrapText($tmp,$breakWidth,$width,$x,$adjust,$justification);
2377 
2378            // reset the text state
2379            $this->currentTextState = $store_currentTextState;
2380            $this->setCurrentFont();
2381            if (!$test){
2382              $this->addText($x,$y,$size,$tmp,$angle,$adjust);
2383            }
2384            return substr($text,$break+1);
2385          } else {
2386            // just split before the current character
2387            $tmp = substr($text,0,$i);
2388            $adjust=0;
2389            $ctmp=ord($text[$i]);
2390            if (isset($this->fonts[$cf]['differences'][$ctmp])){
2391              $ctmp=$this->fonts[$cf]['differences'][$ctmp];
2392            }
2393            $tmpw=($w-$this->fonts[$cf]['C'][$ctmp]['WX'])*$size/1000;
2394            $this->PRVTadjustWrapText($tmp,$tmpw,$width,$x,$adjust,$justification);
2395            // reset the text state
2396            $this->currentTextState = $store_currentTextState;
2397            $this->setCurrentFont();
2398            if (!$test){
2399              $this->addText($x,$y,$size,$tmp,$angle,$adjust);
2400            }
2401            return substr($text,$i);
2402          }
2403        }
2404        if ($text[$i]=='-'){
2405          $break=$i;
2406          $breakWidth = $w*$size/1000;
2407        }
2408        if ($text[$i]==' '){
2409          $break=$i;
2410          $ctmp=ord($text[$i]);
2411          if (isset($this->fonts[$cf]['differences'][$ctmp])){
2412            $ctmp=$this->fonts[$cf]['differences'][$ctmp];
2413          }
2414          $breakWidth = ($w-$this->fonts[$cf]['C'][$ctmp]['WX'])*$size/1000;
2415        }
2416      }
2417    }
2418    // then there was no need to break this line
2419    if ($justification=='full'){
2420      $justification='left';
2421    }
2422    $adjust=0;
2423    $tmpw=$w*$size/1000;
2424    $this->PRVTadjustWrapText($text,$tmpw,$width,$x,$adjust,$justification);
2425    // reset the text state
2426    $this->currentTextState = $store_currentTextState;
2427    $this->setCurrentFont();
2428    if (!$test){
2429      $this->addText($x,$y,$size,$text,$angle,$adjust,$angle);
2430    }
2431    return '';
2432  }
publiccheckAllHere ( )[ cpdf ]
Parameters
No parameters for this method
Code
1198  function checkAllHere(){
1199  }
publiccloseObject ( )[ cpdf ]
Parameters
No parameters for this method
Code
2511  function closeObject(){
2512    // close the object, as long as there was one open in the first place, which will be indicated by
2513    // an objectId on the stack.
2514    if ($this->nStack>0){
2515      $this->currentContents=$this->stack[$this->nStack]['c'];
2516      $this->currentPage=$this->stack[$this->nStack]['p'];
2517      $this->nStack--;
2518      // easier to probably not worry about removing the old entries, they will be overwritten
2519      // if there are new ones.
2520    }
2521  }
public__construct ( pageSize [Array] )[ cpdf ]
Parameters
optionalpageSize [Array]
Code
197  function __construct($pageSize=array(0,0,612,792)){
198    $this->newDocument($pageSize);
199 
200    // also initialize the font families that are known about already
201    $this->setFontFamily('init');
202  //  $this->fileIdentifier = md5('xxxxxxxx'.time());
203 
204  }
publiccurve ( x0 , y0 , x1 , y1 , x2 , y2 , x3 , y3 )[ cpdf ]
Parameters
requiredx0
requiredy0
requiredx1
requiredy1
requiredx2
requiredy2
requiredx3
requiredy3
Code
1666  function curve($x0,$y0,$x1,$y1,$x2,$y2,$x3,$y3){
1667    // in the current line style, draw a bezier curve from (x0,y0) to (x3,y3) using the other two points
1668    // as the control points for the curve.
1669    $this->objects[$this->currentContents]['c'].="\n".sprintf('%.3f',$x0).' '.sprintf('%.3f',$y0).' m '.sprintf('%.3f',$x1).' '.sprintf('%.3f',$y1);
1670    $this->objects[$this->currentContents]['c'].= ' '.sprintf('%.3f',$x2).' '.sprintf('%.3f',$y2).' '.sprintf('%.3f',$x3).' '.sprintf('%.3f',$y3).' c S';
1671  }
publicellipse ( x0 , y0 , r1 , r2 [0] , angle [0] , nSeg [8] , astart [0] , afinish [360] , close [1] , fill [0] )[ cpdf ]
Parameters
requiredx0
requiredy0
requiredr1
optionalr2 [0]
optionalangle [0]
optionalnSeg [8]
optionalastart [0]
optionalafinish [360]
optionalclose [1]
optionalfill [0]
Code
1697  function ellipse($x0,$y0,$r1,$r2=0,$angle=0,$nSeg=8,$astart=0,$afinish=360,$close=1,$fill=0){
1698    if ($r1==0){
1699      return;
1700    }
1701    if ($r2==0){
1702      $r2=$r1;
1703    }
1704    if ($nSeg<2){
1705      $nSeg=2;
1706    }
1707 
1708    $astart = deg2rad((float)$astart);
1709    $afinish = deg2rad((float)$afinish);
1710    $totalAngle =$afinish-$astart;
1711 
1712    $dt = $totalAngle/$nSeg;
1713    $dtm = $dt/3;
1714 
1715    if ($angle != 0){
1716      $a = -1*deg2rad((float)$angle);
1717      $tmp = "\n q ";
1718      $tmp .= sprintf('%.3f',cos($a)).' '.sprintf('%.3f',(-1.0*sin($a))).' '.sprintf('%.3f',sin($a)).' '.sprintf('%.3f',cos($a)).' ';
1719      $tmp .= sprintf('%.3f',$x0).' '.sprintf('%.3f',$y0).' cm';
1720      $this->objects[$this->currentContents]['c'].= $tmp;
1721      $x0=0;
1722      $y0=0;
1723    }
1724 
1725    $t1 = $astart;
1726    $a0 = $x0+$r1*cos($t1);
1727    $b0 = $y0+$r2*sin($t1);
1728    $c0 = -$r1*sin($t1);
1729    $d0 = $r2*cos($t1);
1730 
1731    $this->objects[$this->currentContents]['c'].="\n".sprintf('%.3f',$a0).' '.sprintf('%.3f',$b0).' m ';
1732    for ($i=1;$i<=$nSeg;$i++){
1733      // draw this bit of the total curve
1734      $t1 = $i*$dt+$astart;
1735      $a1 = $x0+$r1*cos($t1);
1736      $b1 = $y0+$r2*sin($t1);
1737      $c1 = -$r1*sin($t1);
1738      $d1 = $r2*cos($t1);
1739      $this->objects[$this->currentContents]['c'].="\n".sprintf('%.3f',($a0+$c0*$dtm)).' '.sprintf('%.3f',($b0+$d0*$dtm));
1740      $this->objects[$this->currentContents]['c'].= ' '.sprintf('%.3f',($a1-$c1*$dtm)).' '.sprintf('%.3f',($b1-$d1*$dtm)).' '.sprintf('%.3f',$a1).' '.sprintf('%.3f',$b1).' c';
1741      $a0=$a1;
1742      $b0=$b1;
1743      $c0=$c1;
1744      $d0=$d1;
1745    }
1746    if ($fill){
1747      $this->objects[$this->currentContents]['c'].=' f';
1748    } else {
1749      if ($close){
1750        $this->objects[$this->currentContents]['c'].=' s'; // small 's' signifies closing the path as well
1751      } else {
1752        $this->objects[$this->currentContents]['c'].=' S';
1753      }
1754    }
1755    if ($angle !=0){
1756      $this->objects[$this->currentContents]['c'].=' Q';
1757    }
1758  }
publicencryptInit ( id )[ cpdf ]
Parameters
requiredid
Code
1082  function encryptInit($id){
1083    $tmp = $this->encryptionKey;
1084    $hex = dechex($id);
1085    if (strlen($hex)<6){
1086      $hex = substr('000000',0,6-strlen($hex)).$hex;
1087    }
1088    $tmp.= chr(hexdec(substr($hex,4,2))).chr(hexdec(substr($hex,2,2))).chr(hexdec(substr($hex,0,2))).chr(0).chr(0);
1089    $key = $this->md5_16($tmp);
1090    $this->ARC4_init(substr($key,0,10));
1091  }
publicfilledEllipse ( x0 , y0 , r1 , r2 [0] , angle [0] , nSeg [8] , astart [0] , afinish [360] )[ cpdf ]
Parameters
requiredx0
requiredy0
requiredr1
optionalr2 [0]
optionalangle [0]
optionalnSeg [8]
optionalastart [0]
optionalafinish [360]
Code
1683  function filledEllipse($x0,$y0,$r1,$r2=0,$angle=0,$nSeg=8,$astart=0,$afinish=360){
1684    return $this->ellipse($x0,$y0,$r1,$r2=0,$angle,$nSeg,$astart,$afinish,1,1);
1685  }
publicfilledRectangle ( x1 , y1 , width , height )[ cpdf ]
Parameters
requiredx1
requiredy1
requiredwidth
requiredheight
Code
1819  function filledRectangle($x1,$y1,$width,$height){
1820    $this->objects[$this->currentContents]['c'].="\n".sprintf('%.3f',$x1).' '.sprintf('%.3f',$y1).' '.sprintf('%.3f',$width).' '.sprintf('%.3f',$height).' re f';
1821  }
publicfilterText ( text )[ cpdf ]
Parameters
requiredtext
Code
1952  function filterText($text){
1953    $text = str_replace('\\','\\\\',$text);
1954    $text = str_replace('(','\(',$text);
1955    $text = str_replace(')','\)',$text);
1956    $text = str_replace('&lt;','<',$text);
1957    $text = str_replace('&gt;','>',$text);
1958    $text = str_replace('&#039;','\'',$text);
1959    $text = str_replace('&quot;','"',$text);
1960    $text = str_replace('&','&',$text);
1961 
1962    return $text;
1963  }
publicgetFirstPageId ( )[ cpdf ]
Parameters
No parameters for this method
Code
1623  function getFirstPageId(){
1624    return $this->firstPageId;
1625  }
publicgetFontDecender ( size )[ cpdf ]
Parameters
requiredsize
Code
1937  function getFontDecender($size){
1938    // note that this will most likely return a negative value
1939    if (!$this->numFonts){
1940      $this->selectFont(SITES . 'helix/resources/fonts/Helvetica');
1941    }
1942    $h = $this->fonts[$this->currentFont]['FontBBox'][1];
1943    return $size*$h/1000;
1944  }
publicgetFontHeight ( size )[ cpdf ]
Parameters
requiredsize
Code
1923  function getFontHeight($size){
1924    if (!$this->numFonts){
1925      $this->selectFont(SITES . 'helix/resources/fonts/Helvetica');
1926    }
1927    // for the current font, and the given size, what is the height of the font in user units
1928    $h = $this->fonts[$this->currentFont]['FontBBox'][3]-$this->fonts[$this->currentFont]['FontBBox'][1];
1929    return $size*$h/1000;
1930  }
publicgetTextWidth ( size , text )[ cpdf ]
Parameters
requiredsize
requiredtext
Code
2242  function getTextWidth($size,$text){
2243    // this function should not change any of the settings, though it will need to
2244    // track any directives which change during calculation, so copy them at the start
2245    // and put them back at the end.
2246    $store_currentTextState = $this->currentTextState;
2247 
2248    if (!$this->numFonts){
2249      $this->selectFont(SITES . 'helix/resources/fonts/Helvetica');
2250    }
2251 
2252    // converts a number or a float to a string so it can get the width
2253    $text = "$text";
2254 
2255    // hmm, this is where it all starts to get tricky - use the font information to
2256    // calculate the width of each character, add them up and convert to user units
2257    $w=0;
2258    $len=strlen($text);
2259    $cf = $this->currentFont;
2260    for ($i=0;$i<$len;$i++){
2261      $f=1;
2262      $directive = $this->PRVTcheckTextDirective($text,$i,$f);
2263      if ($directive){
2264        if ($f){
2265          $this->setCurrentFont();
2266          $cf = $this->currentFont;
2267        }
2268        $i=$i+$directive-1;
2269      } else {
2270        $char=ord($text[$i]);
2271        if (isset($this->fonts[$cf]['differences'][$char])){
2272          // then this character is being replaced by another
2273          $name = $this->fonts[$cf]['differences'][$char];
2274          if (isset($this->fonts[$cf]['C'][$name]['WX'])){
2275            $w+=$this->fonts[$cf]['C'][$name]['WX'];
2276          }
2277        } else if (isset($this->fonts[$cf]['C'][$char]['WX'])){
2278          $w+=$this->fonts[$cf]['C'][$char]['WX'];
2279        }
2280      }
2281    }
2282 
2283    $this->currentTextState = $store_currentTextState;
2284    $this->setCurrentFont();
2285 
2286    return $w*$size/1000;
2287  }
publicline ( x1 , y1 , x2 , y2 )[ cpdf ]
Parameters
requiredx1
requiredy1
requiredx2
requiredy2
Code
1659  function line($x1,$y1,$x2,$y2){
1660    $this->objects[$this->currentContents]['c'].="\n".sprintf('%.3f',$x1).' '.sprintf('%.3f',$y1).' m '.sprintf('%.3f',$x2).' '.sprintf('%.3f',$y2).' l S';
1661  }
publicmd5_16 ( string )[ cpdf ]
Parameters
requiredstring
Code
1070  function md5_16($string){
1071    $tmp = md5($string);
1072    $out='';
1073    for ($i=0;$i<=30;$i=$i+2){
1074      $out.=chr(hexdec(substr($tmp,$i,2)));
1075    }
1076    return $out;
1077  }
publicnewDocument ( pageSize [Array] )[ cpdf ]
Parameters
optionalpageSize [Array]
Code
1251  function newDocument($pageSize=array(0,0,612,792)){
1252    $this->numObj=0;
1253    $this->objects = array();
1254 
1255    $this->numObj++;
1256    $this->o_catalog($this->numObj,'new');
1257 
1258    $this->numObj++;
1259    $this->o_outlines($this->numObj,'new');
1260 
1261    $this->numObj++;
1262    $this->o_pages($this->numObj,'new');
1263 
1264    $this->o_pages($this->numObj,'mediaBox',$pageSize);
1265    $this->currentNode = 3;
1266 
1267    $this->numObj++;
1268    $this->o_procset($this->numObj,'new');
1269 
1270    $this->numObj++;
1271    $this->o_info($this->numObj,'new');
1272 
1273    $this->numObj++;
1274    $this->o_page($this->numObj,'new');
1275 
1276    // need to store the first page id as there is no way to get it to the user during
1277    // startup
1278    $this->firstPageId = $this->currentContents;
1279  }
publicnewPage ( insert [0] , id [0] , pos ["after"] )[ cpdf ]
Parameters
optionalinsert [0]
optionalid [0]
optionalpos ["after"]
Code
1835  function newPage($insert=0,$id=0,$pos='after'){
1836 
1837    // if there is a state saved, then go up the stack closing them
1838    // then on the new page, re-open them with the right setings
1839 
1840    if ($this->nStateStack){
1841      for ($i=$this->nStateStack;$i>=1;$i--){
1842        $this->restoreState($i);
1843      }
1844    }
1845 
1846    $this->numObj++;
1847    if ($insert){
1848      // the id from the ezPdf class is the od of the contents of the page, not the page object itself
1849      // query that object to find the parent
1850      $rid = $this->objects[$id]['onPage'];
1851      $opt= array('rid'=>$rid,'pos'=>$pos);
1852      $this->o_page($this->numObj,'new',$opt);
1853    } else {
1854      $this->o_page($this->numObj,'new');
1855    }
1856    // if there is a stack saved, then put that onto the page
1857    if ($this->nStateStack){
1858      for ($i=1;$i<=$this->nStateStack;$i++){
1859        $this->saveState($i);
1860      }
1861    }
1862    // and if there has been a stroke or fill colour set, then transfer them
1863    if ($this->currentColour['r']>=0){
1864      $this->setColor($this->currentColour['r'],$this->currentColour['g'],$this->currentColour['b'],1);
1865    }
1866    if ($this->currentStrokeColour['r']>=0){
1867      $this->setStrokeColor($this->currentStrokeColour['r'],$this->currentStrokeColour['g'],$this->currentStrokeColour['b'],1);
1868    }
1869 
1870    // if there is a line style set, then put this in too
1871    if (strlen($this->currentLineStyle)){
1872      $this->objects[$this->currentContents]['c'].="\n".$this->currentLineStyle;
1873    }
1874 
1875    // the call to the o_page object set currentContents to the present page, so this can be returned as the page id
1876    return $this->currentContents;
1877  }
publico_action ( id , action , options [""] )[ cpdf ]
Parameters
requiredid
requiredaction
optionaloptions [""]
Code
716  function o_action($id,$action,$options=''){
717    if ($action!='new'){
718      $o =& $this->objects[$id];
719    }
720    switch ($action){
721      case 'new':
722        if (is_array($options)){
723          $this->objects[$id]=array('t'=>'action','info'=>$options,'type'=>$options['type']);
724        } else {
725          // then assume a URI action
726          $this->objects[$id]=array('t'=>'action','info'=>$options,'type'=>'URI');
727        }
728        break;
729      case 'out':
730        if ($this->encrypted){
731          $this->encryptInit($id);
732        }
733        $res="\n".$id." 0 obj\n<< /Type /Action";
734        switch($o['type']){
735          case 'ilink':
736            // there will be an 'label' setting, this is the name of the destination
737            $res.="\n/S /GoTo\n/D ".$this->destinations[(string)$o['info']['label']]." 0 R";
738            break;
739          case 'URI':
740            $res.="\n/S /URI\n/URI (";
741            if ($this->encrypted){
742              $res.=$this->filterText($this->ARC4($o['info']));
743            } else {
744              $res.=$this->filterText($o['info']);
745            }
746            $res.=")";
747            break;
748        }
749        $res.="\n>>\nendobj";
750        return $res;
751    }
752  }
publico_annotation ( id , action , options [""] )[ cpdf ]
Parameters
requiredid
requiredaction
optionaloptions [""]
Code
758  function o_annotation($id,$action,$options=''){
759    if ($action!='new'){
760      $o =& $this->objects[$id];
761    }
762    switch ($action){
763      case 'new':
764        // add the annotation to the current page
765        $pageId = $this->currentPage;
766        $this->o_page($pageId,'annot',$id);
767        // and add the action object which is going to be required
768        switch($options['type']){
769          case 'link':
770            $this->objects[$id]=array('t'=>'annotation','info'=>$options);
771            $this->numObj++;
772            $this->o_action($this->numObj,'new',$options['url']);
773            $this->objects[$id]['info']['actionId']=$this->numObj;
774            break;
775          case 'ilink':
776            // this is to a named internal link
777            $label = $options['label'];
778            $this->objects[$id]=array('t'=>'annotation','info'=>$options);
779            $this->numObj++;
780            $this->o_action($this->numObj,'new',array('type'=>'ilink','label'=>$label));
781            $this->objects[$id]['info']['actionId']=$this->numObj;
782            break;
783        }
784        break;
785      case 'out':
786        $res="\n".$id." 0 obj\n<< /Type /Annot";
787        switch($o['info']['type']){
788          case 'link':
789          case 'ilink':
790            $res.= "\n/Subtype /Link";
791            break;
792        }
793        $res.="\n/A ".$o['info']['actionId']." 0 R";
794        $res.="\n/Border [0 0 0]";
795        $res.="\n/H /I";
796        $res.="\n/Rect [ ";
797        foreach($o['info']['rect'] as $v){
798          $res.= sprintf("%.4f ",$v);
799        }
800        $res.="]";
801        $res.="\n>>\nendobj";
802        return $res;
803    }
804  }
publico_catalog ( id , action , options [""] )[ cpdf ]
Parameters
requiredid
requiredaction
optionaloptions [""]
Code
295  function o_catalog($id,$action,$options=''){
296    if ($action!='new'){
297      $o =& $this->objects[$id];
298    }
299    switch ($action){
300      case 'new':
301        $this->objects[$id]=array('t'=>'catalog','info'=>array());
302        $this->catalogId=$id;
303        break;
304      case 'outlines':
305      case 'pages':
306      case 'openHere':
307        $o['info'][$action]=$options;
308        break;
309      case 'viewerPreferences':
310        if (!isset($o['info']['viewerPreferences'])){
311          $this->numObj++;
312          $this->o_viewerPreferences($this->numObj,'new');
313          $o['info']['viewerPreferences']=$this->numObj;
314        }
315        $vp = $o['info']['viewerPreferences'];
316        $this->o_viewerPreferences($vp,'add',$options);
317        break;
318      case 'out':
319        $res="\n".$id." 0 obj\n".'<< /Type /Catalog';
320        foreach($o['info'] as $k=>$v){
321          switch($k){
322            case 'outlines':
323              $res.="\n".'/Outlines '.$v.' 0 R';
324              break;
325            case 'pages':
326              $res.="\n".'/Pages '.$v.' 0 R';
327              break;
328            case 'viewerPreferences':
329              $res.="\n".'/ViewerPreferences '.$o['info']['viewerPreferences'].' 0 R';
330              break;
331            case 'openHere':
332              $res.="\n".'/OpenAction '.$o['info']['openHere'].' 0 R';
333              break;
334          }
335        }
336        $res.=" >>\nendobj";
337        return $res;
338    }
339  }
publico_contents ( id , action , options [""] )[ cpdf ]
Parameters
requiredid
requiredaction
optionaloptions [""]
Code
877  function o_contents($id,$action,$options=''){
878    if ($action!='new'){
879      $o =& $this->objects[$id];
880    }
881    switch ($action){
882      case 'new':
883        $this->objects[$id]=array('t'=>'contents','c'=>'','info'=>array());
884        if (strlen($options) && intval($options)){
885          // then this contents is the primary for a page
886          $this->objects[$id]['onPage']=$options;
887        } else if ($options=='raw'){
888          // then this page contains some other type of system object
889          $this->objects[$id]['raw']=1;
890        }
891        break;
892      case 'add':
893        // add more options to the decleration
894        foreach ($options as $k=>$v){
895          $o['info'][$k]=$v;
896        }
897      case 'out':
898        $tmp=$o['c'];
899        $res= "\n".$id." 0 obj\n";
900        if (isset($this->objects[$id]['raw'])){
901          $res.=$tmp;
902        } else {
903          $res.= "<<";
904          if (function_exists('gzcompress') && $this->options['compression']){
905            // then implement ZLIB based compression on this content stream
906            $res.=" /Filter /FlateDecode";
907            $tmp = gzcompress($tmp);
908          }
909          if ($this->encrypted){
910            $this->encryptInit($id);
911            $tmp = $this->ARC4($tmp);
912          }
913          foreach($o['info'] as $k=>$v){
914            $res .= "\n/".$k.' '.$v;
915          }
916          $res.="\n/Length ".strlen($tmp)." >>\nstream\n".$tmp."\nendstream";
917        }
918        $res.="\nendobj\n";
919        return $res;
920    }
921  }
publico_destination ( id , action , options [""] )[ cpdf ]
Parameters
requiredid
requiredaction
optionaloptions [""]
Code
224  function o_destination($id,$action,$options=''){
225    if ($action!='new'){
226      $o =& $this->objects[$id];
227    }
228    switch($action){
229      case 'new':
230        $this->objects[$id]=array('t'=>'destination','info'=>array());
231        $tmp = '';
232        switch ($options['type']){
233          case 'XYZ':
234          case 'FitR':
235            $tmp ' '.$options['p3'].$tmp;
236          case 'FitH':
237          case 'FitV':
238          case 'FitBH':
239          case 'FitBV':
240            $tmp ' '.$options['p1'].' '.$options['p2'].$tmp;
241          case 'Fit':
242          case 'FitB':
243            $tmp $options['type'].$tmp;
244            $this->objects[$id]['info']['string']=$tmp;
245            $this->objects[$id]['info']['page']=$options['page'];
246        }
247        break;
248      case 'out':
249        $tmp = $o['info'];
250        $res="\n".$id." 0 obj\n".'['.$tmp['page'].' 0 R /'.$tmp['string']."]\nendobj\n";
251        return $res;
252    }
253  }
publico_encryption ( id , action , options [""] )[ cpdf ]
Parameters
requiredid
requiredaction
optionaloptions [""]
Code
1000  function o_encryption($id,$action,$options=''){
1001    if ($action!='new'){
1002      $o =& $this->objects[$id];
1003    }
1004    switch($action){
1005      case 'new':
1006        // make the new object
1007        $this->objects[$id]=array('t'=>'encryption','info'=>$options);
1008        $this->arc4_objnum=$id;
1009        // figure out the additional paramaters required
1010        $pad = chr(0x28).chr(0xBF).chr(0x4E).chr(0x5E).chr(0x4E).chr(0x75).chr(0x8A).chr(0x41).chr(0x64).chr(0x00).chr(0x4E).chr(0x56).chr(0xFF).chr(0xFA).chr(0x01).chr(0x08).chr(0x2E).chr(0x2E).chr(0x00).chr(0xB6).chr(0xD0).chr(0x68).chr(0x3E).chr(0x80).chr(0x2F).chr(0x0C).chr(0xA9).chr(0xFE).chr(0x64).chr(0x53).chr(0x69).chr(0x7A);
1011        $len = strlen($options['owner']);
1012        if ($len>32){
1013          $owner = substr($options['owner'],0,32);
1014        } else if ($len<32){
1015          $owner = $options['owner'].substr($pad,0,32-$len);
1016        } else {
1017          $owner = $options['owner'];
1018        }
1019        $len = strlen($options['user']);
1020        if ($len>32){
1021          $user = substr($options['user'],0,32);
1022        } else if ($len<32){
1023          $user = $options['user'].substr($pad,0,32-$len);
1024        } else {
1025          $user = $options['user'];
1026        }
1027        $tmp = $this->md5_16($owner);
1028        $okey = substr($tmp,0,5);
1029        $this->ARC4_init($okey);
1030        $ovalue=$this->ARC4($user);
1031        $this->objects[$id]['info']['O']=$ovalue;
1032        // now make the u value, phew.
1033        $tmp = $this->md5_16($user.$ovalue.chr($options['p']).chr(255).chr(255).chr(255).$this->fileIdentifier);
1034        $ukey = substr($tmp,0,5);
1035 
1036        $this->ARC4_init($ukey);
1037        $this->encryptionKey = $ukey;
1038        $this->encrypted=1;
1039        $uvalue=$this->ARC4($pad);
1040 
1041        $this->objects[$id]['info']['U']=$uvalue;
1042        $this->encryptionKey=$ukey;
1043 
1044        // initialize the arc4 array
1045        break;
1046      case 'out':
1047        $res= "\n".$id." 0 obj\n<<";
1048        $res.="\n/Filter /Standard";
1049        $res.="\n/V 1";
1050        $res.="\n/R 2";
1051        $res.="\n/O (".$this->filterText($o['info']['O']).')';
1052        $res.="\n/U (".$this->filterText($o['info']['U']).')';
1053        // and the p-value needs to be converted to account for the twos-complement approach
1054        $o['info']['p'] = (($o['info']['p']^255)+1)*-1;
1055        $res.="\n/P ".($o['info']['p']);
1056        $res.="\n>>\nendobj\n";
1057 
1058        return $res;
1059    }
1060  }
publico_font ( id , action , options [""] )[ cpdf ]
Parameters
requiredid
requiredaction
optionaloptions [""]
Code
470  function o_font($id,$action,$options=''){
471    if ($action!='new'){
472      $o =& $this->objects[$id];
473    }
474    switch ($action){
475      case 'new':
476        $this->objects[$id]=array('t'=>'font','info'=>array('name'=>$options['name'],'SubType'=>'Type1'));
477        $fontNum=$this->numFonts;
478        $this->objects[$id]['info']['fontNum']=$fontNum;
479        // deal with the encoding and the differences
480        if (isset($options['differences'])){
481          // then we'll need an encoding dictionary
482          $this->numObj++;
483          $this->o_fontEncoding($this->numObj,'new',$options);
484          $this->objects[$id]['info']['encodingDictionary']=$this->numObj;
485        } else if (isset($options['encoding'])){
486          // we can specify encoding here
487          switch($options['encoding']){
488            case 'WinAnsiEncoding':
489            case 'MacRomanEncoding':
490            case 'MacExpertEncoding':
491              $this->objects[$id]['info']['encoding']=$options['encoding'];
492              break;
493            case 'none':
494              break;
495            default:
496              $this->objects[$id]['info']['encoding']='WinAnsiEncoding';
497              break;
498          }
499        } else {
500          $this->objects[$id]['info']['encoding']='WinAnsiEncoding';
501        }
502        // also tell the pages node about the new font
503        $this->o_pages($this->currentNode,'font',array('fontNum'=>$fontNum,'objNum'=>$id));
504        break;
505      case 'add':
506        foreach ($options as $k=>$v){
507          switch ($k){
508            case 'BaseFont':
509              $o['info']['name'] = $v;
510              break;
511            case 'FirstChar':
512            case 'LastChar':
513            case 'Widths':
514            case 'FontDescriptor':
515            case 'SubType':
516            $this->addMessage('o_font '.$k." : ".$v);
517              $o['info'][$k] = $v;
518              break;
519          }
520       }
521        break;
522      case 'out':
523        $res="\n".$id." 0 obj\n<< /Type /Font\n/Subtype /".$o['info']['SubType']."\n";
524        $res.="/Name /F".$o['info']['fontNum']."\n";
525        $res.="/BaseFont /".$o['info']['name']."\n";
526        if (isset($o['info']['encodingDictionary'])){
527          // then place a reference to the dictionary
528          $res.="/Encoding ".$o['info']['encodingDictionary']." 0 R\n";
529        } else if (isset($o['info']['encoding'])){
530          // use the specified encoding
531          $res.="/Encoding /".$o['info']['encoding']."\n";
532        }
533        if (isset($o['info']['FirstChar'])){
534          $res.="/FirstChar ".$o['info']['FirstChar']."\n";
535        }
536        if (isset($o['info']['LastChar'])){
537          $res.="/LastChar ".$o['info']['LastChar']."\n";
538        }
539        if (isset($o['info']['Widths'])){
540          $res.="/Widths ".$o['info']['Widths']." 0 R\n";
541        }
542        if (isset($o['info']['FontDescriptor'])){
543          $res.="/FontDescriptor ".$o['info']['FontDescriptor']." 0 R\n";
544        }
545        $res.=">>\nendobj";
546        return $res;
547    }
548  }
publico_fontDescriptor ( id , action , options [""] )[ cpdf ]
Parameters
requiredid
requiredaction
optionaloptions [""]
Code
553  function o_fontDescriptor($id,$action,$options=''){
554    if ($action!='new'){
555      $o =& $this->objects[$id];
556    }
557    switch ($action){
558      case 'new':
559        $this->objects[$id]=array('t'=>'fontDescriptor','info'=>$options);
560        break;
561      case 'out':
562        $res="\n".$id." 0 obj\n<< /Type /FontDescriptor\n";
563        foreach ($o['info'] as $label => $value){
564          switch ($label){
565            case 'Ascent':
566            case 'CapHeight':
567            case 'Descent':
568            case 'Flags':
569            case 'ItalicAngle':
570            case 'StemV':
571            case 'AvgWidth':
572            case 'Leading':
573            case 'MaxWidth':
574            case 'MissingWidth':
575            case 'StemH':
576            case 'XHeight':
577            case 'CharSet':
578              if (strlen($value)){
579                $res.='/'.$label.' '.$value."\n";
580              }
581              break;
582            case 'FontFile':
583