Location: PHPKode > projects > Php Pdf Factory > Pdf.php
<?

require_once 'Pdf/FontCollection.php';
require_once 'Pdf/Objects.php';
require_once 'Pdf/Document.php';
require_once 'Pdf/Text.php';

define('PDF_O_DIVIDER'," ");
class Pdf {
  var $objects;
  var $document;
  var $fonts;
  var $messages;
  var $text;
  /**
  * a flag to say if a document is to be encrypted or not
  */
  var $encrypted=0;
  /**
  * the ancryption key for the encryption of all the document content (structure is not encrypted)
  */
  var $encryptionKey='';
  /**
  * store the stack for the transaction commands, each item in here is a record of the values of all the
  * variables within the class, so that the user can rollback at will (from each 'start' command)
  * note that this includes the objects array, so these can be large.
  */
  var $checkpoint = '';
  function Pdf ($pageSize=array(0,0,612,792)) {
    $this->objects = &new PdfObjects();

    $this->document = &new PdfDocument($this->objects,$pageSize);

    $this->fonts = &new PdfFontCollection($this->objects);

    // also initialize the font families that are known about already
    $this->fonts->setFontFamily('init');

    $this->text = &new PdfText($this->fonts,$this->objects,$this);
  }
  /**
  * used to add messages for use in debugging
  */
  function addMessage($message){
    $this->messages .= $message."\n";
  }
  /**
  * set the encryption of the document
  * can be used to turn it on and/or set the passwords which it will have.
  * also the functions that the user will have are set here, such as print, modify, add
  */
  function setEncryption($userPass='',$ownerPass='',$pc=array()){
    $p=bindec(11000000);

    $options = array(
       'print'=>4
      ,'modify'=>8
      ,'copy'=>16
      ,'add'=>32
    );
    foreach($pc as $k=>$v){
      if ($v && isset($options[$k])){
        $p+=$options[$k];
      } else if (isset($options[$v])){
        $p+=$options[$v];
      }
    }
    // implement encryption on the document
    if ($this->objects->arc4_objnum == 0){
      // then the block does not exist already, add it.
      if (strlen($ownerPass)==0){
        $ownerPass=$userPass;
      }
      $this->objects->createObject('PdfObjectEncryption',  array('user'=>$userPass,'owner'=>$ownerPass,'p'=>$p));
    }
  }
  /**
  * return the pdf stream as a string returned from the function
  */
  function output($debug=0){

    if ($debug){
      // turn compression off
      $this->options['compression']=false;
    }

    if (isset($this->objects->arc4_objnum) && $this->objects->arc4_objnum>0){
      $this->ARC4_init($this->objects->encryptionKey);
    }

//  $this->checkAllHere();

    $xref=array();
    $content="%PDF-1.3\n%òóÏÓ\n";
//    $content="%PDF-1.3\n";
    $pos=strlen($content);
    unset($this->objects->objects[0]);
    $root = $this->objects->catalogId->getId();
    foreach($this->objects->objects as $k=>$v){
      $c = (boolean)@$this->options['compression'];
      if (is_object($v)) {
        $cont = $v->out($c);
        $content .= $cont;
      }
    }
    array_unshift($this->objects->xref,$pos);
    $content.="\nxref\n0 ".(sizeof($this->objects->xref))."\n0000000000 65535 f \n";
    $pos = 0;
    foreach($this->objects->xref as $p){
      $pos += $p;
      $content .= str_pad($pos, 10, "0", STR_PAD_LEFT)." 00000 n \n";
    }
    $content.="\ntrailer\n  << /Size ".(sizeof($this->objects->xref))."\n     /Root ".$root." 0 R\n     /Info ".$this->objects->infoObject->getId()." 0 R\n";
    // if encryption has been applied to this document then add the marker for this dictionary
    if (isset($this->objects->arc4_objnum) && $this->objects->arc4_objnum > 0){
      $content .= "/Encrypt ".$this->objects->arc4_objnum." 0 R\n";
    }
/*
 * comment it now....
    if (strlen($this->fileIdentifier)){
      $content .= "/ID[<".$this->fileIdentifier."><".$this->fileIdentifier.">]\n";
    }
*/
    $content .= "  >>\nstartxref\n".$pos."\n%%EOF\n";
    return $content;
  }
  /**
  * output the pdf code, streaming it to the browser
  * the relevant headers are set so that hopefully the browser will recognise it
  */
  function stream($options=''){
    // setting the options allows the adjustment of the headers
    // values at the moment are:
    // 'Content-Disposition'=>'filename'  - sets the filename, though not too sure how well this will
    //        work as in my trial the browser seems to use the filename of the php file with .pdf on the end
    // 'Accept-Ranges'=>1 or 0 - if this is not set to 1, then this header is not included, off by default
    //    this header seems to have caused some problems despite tha fact that it is supposed to solve
    //    them, so I am leaving it off by default.
    // 'compress'=> 1 or 0 - apply content stream compression, this is on (1) by default
    if (!is_array($options)){
      $options=array();
    }
    if ( isset($options['compress']) && $options['compress']==0){
      $tmp = $this->output(1);
    } else {
      $tmp = $this->output();
    }
    header("Content-type: application/pdf");
    header("Content-Length: ".strlen(ltrim($tmp)));
    $fileName = (isset($options['Content-Disposition'])?$options['Content-Disposition']:"file.pdf");
    header("Content-Disposition: inline; filename=".$fileName);
    if (isset($options['Accept-Ranges']) && $options['Accept-Ranges']==1){
      header("Accept-Ranges: ".strlen(ltrim($tmp)));
    }
    echo ltrim($tmp);
  }

  /**
  * a few functions which should allow the document to be treated transactionally.
  */
  function transaction($action){
    switch ($action){
      case 'start':
        // store all the data away into the checkpoint variable
        $data = get_object_vars($this);
        $this->checkpoint = $data;
        unset($data);
        break;
      case 'commit':
        if (is_array($this->checkpoint) && isset($this->checkpoint['checkpoint'])){
          $tmp = $this->checkpoint['checkpoint'];
          $this->checkpoint = $tmp;
          unset($tmp);
        } else {
          $this->checkpoint='';
        }
        break;
      case 'rewind':
        // do not destroy the current checkpoint, but move us back to the state then, so that we can try again
        if (is_array($this->checkpoint)){
          // can only abort if were inside a checkpoint
          $tmp = $this->checkpoint;
          foreach ($tmp as $k=>$v){
            if ($k != 'checkpoint'){
              $this->$k=$v;
            }
          }
          unset($tmp);
        }
        break;
      case 'abort':
        if (is_array($this->checkpoint)){
          // can only abort if were inside a checkpoint
          $tmp = $this->checkpoint;
          foreach ($tmp as $k=>$v){
            $this->$k=$v;
          }
          unset($tmp);
        }
        break;
    }
  }

  /**
  *
  *  Interface for PdfText;
  *
  **/
  function addText($x,$y,$size,$text,$angle=0,$wordSpaceAdjust=0){
    $this->text->addText($x,$y,$size,$text,$angle,$wordSpaceAdjust);
  }
  function getTextWidth($size,$text){
    return $this->text->getTextWidth($size,$text);
  }
  function addTextWrap($x,$y,$width,$size,$text,$justification='left',$angle=0,$test=0){
    return $this->text->addTextWrap($x,$y,$width,$size,$text,$justification,$angle,$test);
  }
  /**
  *
  *  Interface for PdfFontCollection;
  *
  **/
  function selectFont($font,$options='') {
    return $this->fonts->select($font,$options);
  }
  function setCurrentFont($textState=false) {
    return $this->fonts->setCurrentFont($textState=false);
  }
  function getFontHeight($size){
    return $this->fonts->getFontHeight($size);
  }
  function getFontDecender($size){
    return $this->fonts->getFontDecender($size);
  }
  /**
  *
  *  Interface for PdfObjects;
  *
  **/
  function addObject($id,$options='add'){
    return $this->objects->addObject($id,$options);
  }
  function openObject () {
    return $this->objects->openObject();
  }
  function reopenObject($id){
    return $this->objects->reopenObject($id);
  }
  function closeObject(){
    return $this->objects->closeObject();
  }
  function stopObject($id){
    return $this->objects->stopObject($id);
  }
  function addContent($content){
    $this->objects->addContent($content);
  }
  /**
  *
  *  Interface for PdfDocument;
  *
  **/
  function addLink($url,$x0,$y0,$x1,$y1){
    $this->document->addLink($url,$x0,$y0,$x1,$y1);
  }
  function addInternalLink($label,$x0,$y0,$x1,$y1){
    $this->document->addInternalLink($label,$x0,$y0,$x1,$y1);
  }
  function addDestination($label,$style,$a=0,$b=0,$c=0){
    $this->document->addDestination($label,$style,$a,$b,$c);
  }
  function openHere($style,$a=0,$b=0,$c=0){
    $this->document->openHere($style,$a,$b,$c);
  }
  function newPage($insert=false,$id=0,$pos='after'){
    return $this->document->newPage($insert,$id,$pos);
  }
  function saveState () {
    $this->document->saveState();
  }
  function restoreState () {
    $this->document->restoreState();
  }
  function setColor ($r,$g,$b,$force=false) {
    $this->document->styles->setColor($r,$g,$b,$force);
  }
  function setStrokeColor ($r,$g,$b,$force=false) {
    $this->document->styles->setStrokeColor($r,$g,$b,$force);
  }
  function setLineStyle ($w=1,$c='',$j='',$d='',$p=0) {
    $this->document->styles->setLine($w,$c,$j,$d,$p);
  }
  function addInfo($label,$value=0) {
    $this->document->addInfo($label,$value);
  }
  function setPreferences($label,$value=0){
    $this->document->setPreferences($label,$value);
  }
  /**
  *  Adds image using callbacks
  *
  *  @param string filename can be either local or remote file or image contents
  *  @param int x position
  *  @param int y position
  *  @param int width
  *  @param int height
  *  @param mixed options
  *  @param string forced type, valid image parser should exists
  *  @param bolean img is file or image stream
  *  @return ref image object
  *  @access public
  */
  function &addImage ($img,$x,$y,$w=0,$h=0,$options=array(),$fType=false,$isFile=true){
    $options['x'] = $x;
    $options['y'] = $y;
    $options['w'] = $w;
    $options['h'] = $h;
    return $this->objects->currentContents->addImage($img,$options,$fType=false,$isFile=true);
  }
  function &addImageGd (&$img,$x,$y,$w=0,$h=0,$quality=100,$options=array()){
    $options['x'] = $x;
    $options['y'] = $y;
    $options['w'] = $w;
    $options['h'] = $h;
    $options['quality'] = $quality;
    return $this->objects->currentContents->addImage(&$img,$options,$fType='GD',$isFile=false);
  }
  function addJpegFromFile($img,$x,$y,$w=0,$h=0){
    $this->addImage($img,$x,$y,$w,$h);
  }
  function addPngFromFile($img,$x,$y,$w=0,$h=0){
    $this->addImage($img,$x,$y,$w,$h);
  }

  /**
  *
  *  Interface for PdfDocument/PdfGeometry;
  *
  **/
  function line ($x1,$y1,$x2,$y2){
    $this->document->geometry->line($x1,$y1,$x2,$y2);
  }
  function curve($x0,$y0,$x1,$y1,$x2,$y2,$x3,$y3) {
    $this->document->geometry->curve($x0,$y0,$x1,$y1,$x2,$y2,$x3,$y3);
  }
  function partEllipse($x0,$y0,$astart,$afinish,$r1,$r2=0,$angle=0,$nSeg=8){
    $this->document->geometry->partEllipse($x0,$y0,$astart,$afinish,$r1,$r2,$angle,$nSeg);
  }
  function filledEllipse($x0,$y0,$r1,$r2=0,$angle=0,$nSeg=8,$astart=0,$afinish=360){
    $this->document->geometry->filledEllipse($x0,$y0,$r1,$r2,$angle,$nSeg,$astart,$afinish);
  }
  function ellipse($x0,$y0,$r1,$r2=0,$angle=0,$nSeg=8,$astart=0,$afinish=360,$close=1,$fill=0){
    $this->document->geometry->ellipse($x0,$y0,$r1,$r2,$angle,$nSeg,$astart,$afinish,$close,$fill);
  }
  function polygon($p,$np,$f=0){
    $this->document->geometry->polygon($p,$np,$f);
  }
  function filledRectangle($x1,$y1,$width,$height){
    $this->document->geometry->filledRectangle($x1,$y1,$width,$height);
  }
  function rectangle($x1,$y1,$width,$height){
    $this->document->geometry->filledRectangle($x1,$y1,$width,$height);
  }

}
?>
Return current item: Php Pdf Factory