**
* add text to the document, at a specified location, size and angle on the page
*/
function addText($x,$y,$size,$text,$angle=0,$wordSpaceAdjust=0){
if (!$this->numFonts){$this->selectFont('./fonts/Helvetica');}
// if there are any open callbacks, then they should be called, to show the start of the line
if ($this->nCallback>0){
for ($i=$this->nCallback;$i>0;$i--){
// call each function
$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']);
$func = $this->callback[$i]['f'];
$this->$func($info);
}
}
if ($angle==0){
$this->objects[$this->currentContents]['c'].="\n".'BT '.sprintf('%.3f',$x).' '.sprintf('%.3f',$y).' Td';
} else {
$a = deg2rad((float)$angle);
$tmp = "\n".'BT ';
$tmp .= sprintf('%.3f',cos($a)).' '.sprintf('%.3f',(-1.0*sin($a))).' '.sprintf('%.3f',sin($a)).' '.sprintf('%.3f',cos($a)).' ';
$tmp .= sprintf('%.3f',$x).' '.sprintf('%.3f',$y).' Tm';
$this->objects[$this->currentContents]['c'] .= $tmp;
}
if ($wordSpaceAdjust!=0 || $wordSpaceAdjust != $this->wordSpaceAdjust){
$this->wordSpaceAdjust=$wordSpaceAdjust;
$this->objects[$this->currentContents]['c'].=' '.sprintf('%.3f',$wordSpaceAdjust).' Tw';
}
$len=strlen($text);
$start=0;
for ($i=0;$i<$len;$i++){
$f=1;
$directive = $this->PRVTcheckTextDirective($text,$i,$f);
if ($directive){
// then we should write what we need to
if ($i>$start){
$part = substr($text,$start,$i-$start);
$this->objects[$this->currentContents]['c'].=' /F'.$this->currentFontNum.' '.sprintf('%.1f',$size).' Tf ';
$this->objects[$this->currentContents]['c'].=' ('.$this->filterText($part).') Tj';
}
if ($f){
// then there was nothing drastic done here, restore the contents
$this->setCurrentFont();
} else {
$this->objects[$this->currentContents]['c'] .= ' ET';
$f=1;
$xp=$x;
$yp=$y;
$directive = $this->PRVTcheckTextDirective1($text,$i,$f,1,$xp,$yp,$size,$angle,$wordSpaceAdjust);
// restart the text object
if ($angle==0){
$this->objects[$this->currentContents]['c'].="\n".'BT '.sprintf('%.3f',$xp).' '.sprintf('%.3f',$yp).' Td';
} else {
$a = deg2rad((float)$angle);
$tmp = "\n".'BT ';
$tmp .= sprintf('%.3f',cos($a)).' '.sprintf('%.3f',(-1.0*sin($a))).' '.sprintf('%.3f',sin($a)).' '.sprintf('%.3f',cos($a)).' ';
$tmp .= sprintf('%.3f',$xp).' '.sprintf('%.3f',$yp).' Tm';
$this->objects[$this->currentContents]['c'] .= $tmp;
}
if ($wordSpaceAdjust!=0 || $wordSpaceAdjust != $this->wordSpaceAdjust){
$this->wordSpaceAdjust=$wordSpaceAdjust;
$this->objects[$this->currentContents]['c'].=' '.sprintf('%.3f',$wordSpaceAdjust).' Tw';
}
}
// and move the writing point to the next piece of text
$i=$i+$directive-1;
$start=$i+1;
}
}
if ($start<$len){
$part = substr($text,$start);
$this->objects[$this->currentContents]['c'].=' /F'.$this->currentFontNum.' '.sprintf('%.1f',$size).' Tf ';
$this->objects[$this->currentContents]['c'].=' ('.$this->filterText($part).') Tj';
}
$this->objects[$this->currentContents]['c'].=' ET';
// if there are any open callbacks, then they should be called, to show the end of the line
if ($this->nCallback>0){
for ($i=$this->nCallback;$i>0;$i--){
// call each function
$tmp = $this->PRVTgetTextPosition($x,$y,$angle,$size,$wordSpaceAdjust,$text);
$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']);
$func = $this->callback[$i]['f'];
$this->$func($info);
}
}
}
/**
* calculate how wide a given text string will be on a page, at a given size.
* this can be called externally, but is alse used by the other class functions
*/
function getTextWidth($size,$text){
// this function should not change any of the settings, though it will need to
// track any directives which change during calculation, so copy them at the start
// and put them back at the end.
$store_currentTextState = $this->currentTextState;
if (!$this->numFonts){
$this->selectFont('./fonts/Helvetica');
}
// converts a number or a float to a string so it can get the width
$text = "$text";
// hmm, this is where it all starts to get tricky - use the font information to
// calculate the width of each character, add them up and convert to user units
$w=0;
$len=strlen($text);
$cf = $this->currentFont;
for ($i=0;$i<$len;$i++){
$f=1;
$directive = $this->PRVTcheckTextDirective($text,$i,$f);
if ($directive){
if ($f){
$this->setCurrentFont();
$cf = $this->currentFont;
}
$i=$i+$directive-1;
} else {
$char=ord($text[$i]);
if (isset($this->fonts[$cf]['differences'][$char])){
// then this character is being replaced by another
$name = $this->fonts[$cf]['differences'][$char];
if (isset($this->fonts[$cf]['C'][$name]['WX'])){
$w+=$this->fonts[$cf]['C'][$name]['WX'];
}
} else if (isset($this->fonts[$cf]['C'][$char]['WX'])){
$w+=$this->fonts[$cf]['C'][$char]['WX'];
}
}
}
$this->currentTextState = $store_currentTextState;
$this->setCurrentFont();
return $w*$size/1000;
}
/**
* do a part of the calculation for sorting out the justification of the text
*
* @access private
*/
function PRVTadjustWrapText($text,$actual,$width,&$x,&$adjust,$justification){
switch ($justification){
case 'left':
return;
break;
case 'right':
$x+=$width-$actual;
break;
case 'center':
case 'centre':
$x+=($width-$actual)/2;
break;
case 'full':
// count the number of words
$words = explode(' ',$text);
$nspaces=count($words)-1;
if ($nspaces>0){
$adjust = ($width-$actual)/$nspaces;
} else {
$adjust=0;
}
break;
}
}
/**
* add text to the page, but ensure that it fits within a certain width
* if it does not fit then put in as much as possible, splitting at word boundaries
* and return the remainder.
* justification and angle can also be specified for the text
*/
function addTextWrap($x,$y,$width,$size,$text,$justification='left',$angle=0,$test=0){
// this will display the text, and if it goes beyond the width $width, will backtrack to the
// previous space or hyphen, and return the remainder of the text.
// $justification can be set to 'left','right','center','centre','full'
// need to store the initial text state, as this will change during the width calculation
// but will need to be re-set before printing, so that the chars work out right
$store_currentTextState = $this->currentTextState;
if (!$this->numFonts){$this->selectFont('./fonts/Helvetica');}
if ($width<=0){
// error, pretend it printed ok, otherwise risking a loop
return '';
}
$w=0;
$break=0;
$breakWidth=0;
$len=strlen($text);
$cf = $this->currentFont;
$tw = $width/$size*1000;
for ($i=0;$i<$len;$i++){
$f=1;
$directive = $this->PRVTcheckTextDirective($text,$i,$f);
if ($directive){
if ($f){
$this->setCurrentFont();
$cf = $this->currentFont;
}
$i=$i+$directive-1;
} else {
$cOrd = ord($text[$i]);
if (isset($this->fonts[$cf]['differences'][$cOrd])){
// then this character is being replaced by another
$cOrd2 = $this->fonts[$cf]['differences'][$cOrd];
} else {
$cOrd2 = $cOrd;
}
if (isset($this->fonts[$cf]['C'][$cOrd2]['WX'])){
$w+=$this->fonts[$cf]['C'][$cOrd2]['WX'];
}
if ($w>$tw){
// then we need to truncate this line
if ($break>0){
// then we have somewhere that we can split :)
if ($text[$break]==' '){
$tmp = substr($text,0,$break);
} else {
$tmp = substr($text,0,$break+1);
}
$adjust=0;
$this->PRVTadjustWrapText($tmp,$breakWidth,$width,$x,$adjust,$justification);
// reset the text state
$this->currentTextState = $store_currentTextState;
$this->setCurrentFont();
if (!$test){
$this->addText($x,$y,$size,$tmp,$angle,$adjust);
}
return substr($text,$break+1);
} else {
// just split before the current character
$tmp = substr($text,0,$i);
$adjust=0;
$ctmp=ord($text[$i]);
if (isset($this->fonts[$cf]['differences'][$ctmp])){
$ctmp=$this->fonts[$cf]['differences'][$ctmp];
}
$tmpw=($w-$this->fonts[$cf]['C'][$ctmp]['WX'])*$size/1000;
$this->PRVTadjustWrapText($tmp,$tmpw,$width,$x,$adjust,$justification);
// reset the text state
$this->currentTextState = $store_currentTextState;
$this->setCurrentFont();
if (!$test){
$this->addText($x,$y,$size,$tmp,$angle,$adjust);
}
return substr($text,$i);
}
}
if ($text[$i]=='-'){
$break=$i;
$breakWidth = $w*$size/1000;
}
if ($text[$i]==' '){
$break=$i;
$ctmp=ord($text[$i]);
if (isset($this->fonts[$cf]['differences'][$ctmp])){
$ctmp=$this->fonts[$cf]['differences'][$ctmp];
}
$breakWidth = ($w-$this->fonts[$cf]['C'][$ctmp]['WX'])*$size/1000;
}
}
}
// then there was no need to break this line
if ($justification=='full'){
$justification='left';
}
$adjust=0;
$tmpw=$w*$size/1000;
$this->PRVTadjustWrapText($text,$tmpw,$width,$x,$adjust,$justification);
// reset the text state
$this->currentTextState = $store_currentTextState;
$this->setCurrentFont();
if (!$test){
$this->addText($x,$y,$size,$text,$angle,$adjust,$angle);
}
return '';
}
/**
* this will be called at a new page to return the state to what it was on the
* end of the previous page, before the stack was closed down
* This is to get around not being able to have open 'q' across pages
*
*/
function saveState($pageEnd=0){
if ($pageEnd){
// this will be called at a new page to return the state to what it was on the
// end of the previous page, before the stack was closed down
// This is to get around not being able to have open 'q' across pages
$opt = $this->stateStack[$pageEnd]; // ok to use this as stack starts numbering at 1
$this->setColor($opt['col']['r'],$opt['col']['g'],$opt['col']['b'],1);
$this->setStrokeColor($opt['str']['r'],$opt['str']['g'],$opt['str']['b'],1);
$this->objects[$this->currentContents]['c'].="\n".$opt['lin'];
// $this->currentLineStyle = $opt['lin'];
} else {
$this->nStateStack++;
$this->stateStack[$this->nStateStack]=array(
'col'=>$this->currentColour
,'str'=>$this->currentStrokeColour
,'lin'=>$this->currentLineStyle
);
}
$this->objects[$this->currentContents]['c'].="\nq";
}
/**
* restore a previously saved state
*/
function restoreState($pageEnd=0){
if (!$pageEnd){
$n = $this->nStateStack;
$this->currentColour = $this->stateStack[$n]['col'];
$this->currentStrokeColour = $this->stateStack[$n]['str'];
$this->objects[$this->currentContents]['c'].="\n".$this->stateStack[$n]['lin'];
$this->currentLineStyle = $this->stateStack[$n]['lin'];
unset($this->stateStack[$n]);
$this->nStateStack--;
}
$this->objects[$this->currentContents]['c'].="\nQ";
}
/**
* make a loose object, the output will go into this object, until it is closed, then will revert to
* the current one.
* this object will not appear until it is included within a page.
* the function will return the object number
*/
function openObject(){
$this->nStack++;
$this->stack[$this->nStack]=array('c'=>$this->currentContents,'p'=>$this->currentPage);
// add a new object of the content type, to hold the data flow
$this->numObj++;
$this->o_contents($this->numObj,'new');
$this->currentContents=$this->numObj;
$this->looseObjects[$this->numObj]=1;
return $this->numObj;
}
/**
* open an existing object for editing
*/
function reopenObject($id){
$this->nStack++;
$this->stack[$this->nStack]=array('c'=>$this->currentContents,'p'=>$this->currentPage);
$this->currentContents=$id;
// also if this object is the primary contents for a page, then set the current page to its parent
if (isset($this->objects[$id]['onPage'])){
$this->currentPage = $this->objects[$id]['onPage'];
}
}
/**
* close an object
*/
function closeObject(){
// close the object, as long as there was one open in the first place, which will be indicated by
// an objectId on the stack.
if ($this->nStack>0){
$this->currentContents=$this->stack[$this->nStack]['c'];
$this->currentPage=$this->stack[$this->nStack]['p'];
$this->nStack--;
// easier to probably not worry about removing the old entries, they will be overwritten
// if there are new ones.
}
}
/**
* stop an object from appearing on pages from this point on
*/
function stopObject($id){
// if an object has been appearing on pages up to now, then stop it, this page will
// be the last one that could contian it.
if (isset($this->addLooseObjects[$id])){
$this->addLooseObjects[$id]='';
}
}
/**
* after an object has been created, it wil only show if it has been added, using this function.
*/
function addObject($id,$options='add'){
// add the specified object to the page
if (isset($this->looseObjects[$id]) && $this->currentContents!=$id){
// then it is a valid object, and it is not being added to itself
switch($options){
case 'all':
// then this object is to be added to this page (done in the next block) and
// all future new pages.
$this->addLooseObjects[$id]='all';
case 'add':
if (isset($this->objects[$this->currentContents]['onPage'])){
// then the destination contents is the primary for the page
// (though this object is actually added to that page)
$this->o_page($this->objects[$this->currentContents]['onPage'],'content',$id);
}
break;
case 'even':
$this->addLooseObjects[$id]='even';
$pageObjectId=$this->objects[$this->currentContents]['onPage'];
if ($this->objects[$pageObjectId]['info']['pageNum']%2==0){
$this->addObject($id); // hacky huh :)
}
break;
case 'odd':
$this->addLooseObjects[$id]='odd';
$pageObjectId=$this->objects[$this->currentContents]['onPage'];
if ($this->objects[$pageObjectId]['info']['pageNum']%2==1){
$this->addObject($id); // hacky huh :)
}
break;
case 'next':
$this->addLooseObjects[$id]='all';
break;
case 'nexteven':
$this->addLooseObjects[$id]='even';
break;
case 'nextodd':
$this->addLooseObjects[$id]='odd';
break;
}
}
}
/**
* add content to the documents info object
*/
function addInfo($label,$value=0){
// this will only work if the label is one of the valid ones.
// modify this so that arrays can be passed as well.
// if $label is an array then assume that it is key=>value pairs
// else assume that they are both scalar, anything else will probably error
if (is_array($label)){
foreach ($label as $l=>$v){
$this->o_info($this->infoObject,$l,$v);
}
} else {
$this->o_info($this->infoObject,$label,$value);
}
}
/**
* set the viewer preferences of the document, it is up to the browser to obey these.
*/
function setPreferences($label,$value=0){
// this will only work if the label is one of the valid ones.
if (is_array($label)){
foreach ($label as $l=>$v){
$this->o_catalog($this->catalogId,'viewerPreferences',array($l=>$v));
}
} else {
$this->o_catalog($this->catalogId,'viewerPreferences',array($label=>$value));
}
}
/**
* extract an integer from a position in a byte stream
*
* @access private
*/
function PRVT_getBytes(&$data,$pos,$num){
// return the integer represented by $num bytes from $pos within $data
$ret=0;
for ($i=0;$i<$num;$i++){
$ret=$ret*256;
$ret+=ord($data[$pos+$i]);
}
return $ret;
}
/**
* add a PNG image into the document, from a file
* this should work with remote files
*/
function addPngFromFile($file,$x,$y,$w=0,$h=0){
// read in a png file, interpret it, then add to the system
$error=0;
$tmp = get_magic_quotes_runtime();
set_magic_quotes_runtime(0);
$fp = @fopen($file,'rb');
if ($fp){
$data='';
while(!feof($fp)){
$data .= fread($fp,1024);
}
fclose($fp);
} else {
$error = 1;
$errormsg = 'trouble opening file: '.$file;
}
set_magic_quotes_runtime($tmp);
if (!$error){
$header = chr(137).chr(80).chr(78).chr(71).chr(13).chr(10).chr(26).chr(10);
if (substr($data,0,8)!=$header){
$error=1;
$errormsg = 'this file does not have a valid header';
}
}
if (!$error){
// set pointer
$p = 8;
$len = strlen($data);
// cycle through the file, identifying chunks
$haveHeader=0;
$info=array();
$idata='';
$pdata='';
while ($p<$len){
$chunkLen = $this->PRVT_getBytes($data,$p,4);
$chunkType = substr($data,$p+4,4);
// echo $chunkType.' - '.$chunkLen.'
';
switch($chunkType){
case 'IHDR':
// this is where all the file information comes from
$info['width']=$this->PRVT_getBytes($data,$p+8,4);
$info['height']=$this->PRVT_getBytes($data,$p+12,4);
$info['bitDepth']=ord($data[$p+16]);
$info['colorType']=ord($data[$p+17]);
$info['compressionMethod']=ord($data[$p+18]);
$info['filterMethod']=ord($data[$p+19]);
$info['interlaceMethod']=ord($data[$p+20]);
//print_r($info);
$haveHeader=1;
if ($info['compressionMethod']!=0){
$error=1;
$errormsg = 'unsupported compression method';
}
if ($info['filterMethod']!=0){
$error=1;
$errormsg = 'unsupported filter method';
}
break;
case 'PLTE':
$pdata.=substr($data,$p+8,$chunkLen);
break;
case 'IDAT':
$idata.=substr($data,$p+8,$chunkLen);
break;
case 'tRNS':
//this chunk can only occur once and it must occur after the PLTE chunk and before IDAT chunk
//print "tRNS found, color type = ".$info['colorType']."
";
$transparency = array();
if ($info['colorType'] == 3) { // indexed color, rbg
/* corresponding to entries in the plte chunk
Alpha for palette index 0: 1 byte
Alpha for palette index 1: 1 byte
...etc...
*/
// there will be one entry for each palette entry. up until the last non-opaque entry.
// set up an array, stretching over all palette entries which will be o (opaque) or 1 (transparent)
$transparency['type']='indexed';
$numPalette = strlen($pdata)/3;
$trans=0;
for ($i=$chunkLen;$i>=0;$i--){
if (ord($data[$p+8+$i])==0){
$trans=$i;
}
}
$transparency['data'] = $trans;
} elseif($info['colorType'] == 0) { // grayscale
/* corresponding to entries in the plte chunk
Gray: 2 bytes, range 0 .. (2^bitdepth)-1
*/
// $transparency['grayscale']=$this->PRVT_getBytes($data,$p+8,2); // g = grayscale
$transparency['type']='indexed';
$transparency['data'] = ord($data[$p+8+1]);
} elseif($info['colorType'] == 2) { // truecolor
/* corresponding to entries in the plte chunk
Red: 2 bytes, range 0 .. (2^bitdepth)-1
Green: 2 bytes, range 0 .. (2^bitdepth)-1
Blue: 2 bytes, range 0 .. (2^bitdepth)-1
*/
$transparency['r']=$this->PRVT_getBytes($data,$p+8,2); // r from truecolor
$transparency['g']=$this->PRVT_getBytes($data,$p+10,2); // g from truecolor
$transparency['b']=$this->PRVT_getBytes($data,$p+12,2); // b from truecolor
} else {
//unsupported transparency type
}
// KS End new code
break;
default:
break;
}
$p += $chunkLen+12;
}
if(!$haveHeader){
$error = 1;
$errormsg = 'information header is missing';
}
if (isset($info['interlaceMethod']) && $info['interlaceMethod']){
$error = 1;
$errormsg = 'There appears to be no support for interlaced images in pdf.';
}
}
if (!$error && $info['bitDepth'] > 8){
$error = 1;
$errormsg = 'only bit depth of 8 or less is supported';
}
if (!$error){
if ($info['colorType']!=2 && $info['colorType']!=0 && $info['colorType']!=3){
$error = 1;
$errormsg = 'transparancey alpha channel not supported, transparency only supported for palette images.';
} else {
switch ($info['colorType']){
case 3:
$color = 'DeviceRGB';
$ncolor=1;
break;
case 2:
$color = 'DeviceRGB';
$ncolor=3;
break;
case 0:
$color = 'DeviceGray';
$ncolor=1;
break;
}
}
}
if ($error){
$this->addMessage('PNG error - ('.$file.') '.$errormsg);
return;
}
if ($w==0){
$w=$h/$info['height']*$info['width'];
}
if ($h==0){
$h=$w*$info['height']/$info['width'];
}
//print_r($info);
// so this image is ok... add it in.
$this->numImages++;
$im=$this->numImages;
$label='I'.$im;
$this->numObj++;
// $this->o_image($this->numObj,'new',array('label'=>$label,'data'=>$idata,'iw'=>$w,'ih'=>$h,'type'=>'png','ic'=>$info['width']));
$options = array('label'=>$label,'data'=>$idata,'bitsPerComponent'=>$info['bitDepth'],'pdata'=>$pdata
,'iw'=>$info['width'],'ih'=>$info['height'],'type'=>'png','color'=>$color,'ncolor'=>$ncolor);
if (isset($transparency)){
$options['transparency']=$transparency;
}
$this->o_image($this->numObj,'new',$options);
$this->objects[$this->currentContents]['c'].="\nq";
$this->objects[$this->currentContents]['c'].="\n".sprintf('%.3f',$w)." 0 0 ".sprintf('%.3f',$h)." ".sprintf('%.3f',$x)." ".sprintf('%.3f',$y)." cm";
$this->objects[$this->currentContents]['c'].="\n/".$label.' Do';
$this->objects[$this->currentContents]['c'].="\nQ";
}
/**
* add a JPEG image into the document, from a file
*/
function addJpegFromFile($img,$x,$y,$w=0,$h=0){
// attempt to add a jpeg image straight from a file, using no GD commands
// note that this function is unable to operate on a remote file.
if (!file_exists($img)){
return;
}
$tmp=getimagesize($img);
$imageWidth=$tmp[0];
$imageHeight=$tmp[1];
if (isset($tmp['channels'])){
$channels = $tmp['channels'];
} else {
$channels = 3;
}
if ($w<=0 && $h<=0){
$w=$imageWidth;
}
if ($w==0){
$w=$h/$imageHeight*$imageWidth;
}
if ($h==0){
$h=$w*$imageHeight/$imageWidth;
}
$fp=fopen($img,'rb');
$tmp = get_magic_quotes_runtime();
set_magic_quotes_runtime(0);
$data = fread($fp,filesize($img));
set_magic_quotes_runtime($tmp);
fclose($fp);
$this->addJpegImage_common($data,$x,$y,$w,$h,$imageWidth,$imageHeight,$channels);
}
/**
* add an image into the document, from a GD object
* this function is not all that reliable, and I would probably encourage people to use
* the file based functions
*/
function addImage(&$img,$x,$y,$w=0,$h=0,$quality=75){
// add a new image into the current location, as an external object
// add the image at $x,$y, and with width and height as defined by $w & $h
// note that this will only work with full colour images and makes them jpg images for display
// later versions could present lossless image formats if there is interest.
// there seems to be some problem here in that images that have quality set above 75 do not appear
// not too sure why this is, but in the meantime I have restricted this to 75.
if ($quality>75){
$quality=75;
}
// if the width or height are set to zero, then set the other one based on keeping the image
// height/width ratio the same, if they are both zero, then give up :)
$imageWidth=imagesx($img);
$imageHeight=imagesy($img);
if ($w<=0 && $h<=0){
return;
}
if ($w==0){
$w=$h/$imageHeight*$imageWidth;
}
if ($h==0){
$h=$w*$imageHeight/$imageWidth;
}
// gotta get the data out of the img..
// so I write to a temp file, and then read it back.. soo ugly, my apologies.
$tmpDir='/tmp';
$tmpName=tempnam($tmpDir,'img');
imagejpeg($img,$tmpName,$quality);
$fp=fopen($tmpName,'rb');
$tmp = get_magic_quotes_runtime();
set_magic_quotes_runtime(0);
$fp = @fopen($tmpName,'rb');
if ($fp){
$data='';
while(!feof($fp)){
$data .= fread($fp,1024);
}
fclose($fp);
} else {
$error = 1;
$errormsg = 'trouble opening file';
}
// $data = fread($fp,filesize($tmpName));
set_magic_quotes_runtime($tmp);
// fclose($fp);
unlink($tmpName);
$this->addJpegImage_common($data,$x,$y,$w,$h,$imageWidth,$imageHeight);
}
/**
* common code used by the two JPEG adding functions
*
* @access private
*/
function addJpegImage_common(&$data,$x,$y,$w=0,$h=0,$imageWidth,$imageHeight,$channels=3){
// note that this function is not to be called externally
// it is just the common code between the GD and the file options
$this->numImages++;
$im=$this->numImages;
$label='I'.$im;
$this->numObj++;
$this->o_image($this->numObj,'new',array('label'=>$label,'data'=>$data,'iw'=>$imageWidth,'ih'=>$imageHeight,'channels'=>$channels));
$this->objects[$this->currentContents]['c'].="\nq";
$this->objects[$this->currentContents]['c'].="\n".sprintf('%.3f',$w)." 0 0 ".sprintf('%.3f',$h)." ".sprintf('%.3f',$x)." ".sprintf('%.3f',$y)." cm";
$this->objects[$this->currentContents]['c'].="\n/".$label.' Do';
$this->objects[$this->currentContents]['c'].="\nQ";
}
/**
* specify where the document should open when it first starts
*/
function openHere($style,$a=0,$b=0,$c=0){
// this function will open the document at a specified page, in a specified style
// the values for style, and the required paramters are:
// 'XYZ' left, top, zoom
// 'Fit'
// 'FitH' top
// 'FitV' left
// 'FitR' left,bottom,right
// 'FitB'
// 'FitBH' top
// 'FitBV' left
$this->numObj++;
$this->o_destination($this->numObj,'new',array('page'=>$this->currentPage,'type'=>$style,'p1'=>$a,'p2'=>$b,'p3'=>$c));
$id = $this->catalogId;
$this->o_catalog($id,'openHere',$this->numObj);
}
/**
* create a labelled destination within the document
*/
function addDestination($label,$style,$a=0,$b=0,$c=0){
// associates the given label with the destination, it is done this way so that a destination can be specified after
// it has been linked to
// styles are the same as the 'openHere' function
$this->numObj++;
$this->o_destination($this->numObj,'new',array('page'=>$this->currentPage,'type'=>$style,'p1'=>$a,'p2'=>$b,'p3'=>$c));
$id = $this->numObj;
// store the label->idf relationship, note that this means that labels can be used only once
$this->destinations["$label"]=$id;
}
/**
* define font families, this is used to initialize the font families for the default fonts
* and for the user to add new ones for their fonts. The default bahavious can be overridden should
* that be desired.
*/
function setFontFamily($family,$options=''){
if (!is_array($options)){
if ($family=='init'){
// set the known family groups
// these font families will be used to enable bold and italic markers to be included
// within text streams. html forms will be used...
$this->fontFamilies['Helvetica.afm']=array(
'b'=>'Helvetica-Bold.afm'
,'i'=>'Helvetica-Oblique.afm'
,'bi'=>'Helvetica-BoldOblique.afm'
,'ib'=>'Helvetica-BoldOblique.afm'
);
$this->fontFamilies['Courier.afm']=array(
'b'=>'Courier-Bold.afm'
,'i'=>'Courier-Oblique.afm'
,'bi'=>'Courier-BoldOblique.afm'
,'ib'=>'Courier-BoldOblique.afm'
);
$this->fontFamilies['Times-Roman.afm']=array(
'b'=>'Times-Bold.afm'
,'i'=>'Times-Italic.afm'
,'bi'=>'Times-BoldItalic.afm'
,'ib'=>'Times-BoldItalic.afm'
);
}
} else {
// the user is trying to set a font family
// note that this can also be used to set the base ones to something else
if (strlen($family)){
$this->fontFamilies[$family] = $options;
}
}
}
/**
* used to add messages for use in debugging
*/
function addMessage($message){
$this->messages.=$message."\n";
}
/**
* 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;
}
}
} // end of class
?>
Fatal error: Class 'Cpdf' not found in /home/clight/public_html/includes/class.ezpdf.php on line 5