Version: 0.30
Type: Class
Category: Other
License: GNU General Public License
Description: A class which helps you to create pdf documents from xml sources. An own set of tags like <page>, <showxy>, <setfont> will be converted into a pdf documents with the help of PHP and the PDFlib(lite).
<?php
/**
* @author Roy Kaldung
* @copyright "2003 Roy Kaldung"
* @package pdfTag
*/
class pdfTag {
/**
* @var string where to store the generated PDF (in memory or as a file)
* @access private
*/
var $pdfDest;
/**
* @var resource the PDFlib resourcehandle
* @access private
*/
var $pPDF;
/**
* @var string contains the source XML
* @access private
*/
var $XML;
/**
* @var resource the filehandle, when creating the PDf on the filesystem
* @access private
*/
var $fpPDF;
/**
* @var string the filename for the created pdf (temporary)
* @access private
*/
var $filePDF; // the filename for creating the PDF on the filesystem
/**
* @var string contains the generated PDF data
* @access private
*/
var $PDFdata;
/**
* @var array pre-defined page formats
* @access private
*/
var $pageFormat;
/**
* @var string the place to look for an errormessage
* @access public
*/
var $error = '';
/**
* @var boolean
*/
var $printDebug;
/**
* @var integer
* @access private
*/
var $debugIndent;
/**
* @var boolean if true, the processing time is measured
* @access public
*/
var $pdfProfile;
/**
* @var array contains the data for images in memory
* @access private
*/
var $imgDataStack = array();
/**
* @var float
*/
var $processingTime;
/**
* @var double the start time of processing
* @access private
*/
var $tStart;
/**
* @var double the end time of processing
* @access private
*/
var $tEnd;
/**
* @var boolean
*/
var $printWarning;
/**
* @var array contains all warnings
*/
var $warnings = array();
/**
* @var array for alias mapping of elements
* @access private
*/
var $tagAlias = array();
/**
* @access private
*/
var $fontStack = array();
/**
* @access private
*/
var $outlineStack = array();
/**
* @access private
*/
var $tmplStack;
/**
* @var integer pageCount
* @access public
*/
var $pageCount = 0;
/**
* @access private
*/
var $imgStack = array();
/**
* hier steht die beschreibung
* @access public
* @var array
*/
var $allowedAttributes = array();
/**
* @var boolean
* @access private
*/
var $checkOnly = false;
/**
* @var double
* @access private
*/
var $versionPDFlib;
/**
* @var string
* @access private
*/
var $useParser;
/**
* @var boolean
* @access private
*/
var $stopOnWarning = false;
/**
* tells pdfTag which XML parser should be used
* @param string $parser
* @access public
* @return boolean
*/
function setParser($parser = 'DOM') {
$this->useParser = (strtoupper($parser) == 'DOM') ? 'DOM' : 'SAX';
return true;
}
/**
* returns which xml parser should be used
* @return string
* @access public
* @return string
*/
function getParser() {
return $this->useParser;
}
/**
* the constructor for the class
* @param string $type default 'mem', for creating the pdf in memory, otherwise 'fs' (on filesystem)
* @param string $src optional, contains the XML source, if $src is a file, the class use it's content
* @access public
* @return void
*/
function pdfTag($type = 'mem', $src = '') {
if(!defined('PDFTAG_VERSION')) {
define('PDFTAG_VERSION', '0.30');
}
if(!defined('PDFTAG_PTPERMM')) {
define('PDFTAG_PTPERMM', 0.3528); // points per mm 1pt = 1/72 inch = 0.3528 mm
}
if(!defined('PDFTAG_INDENTCHAR')) {
define('PDFTAG_INDENTCHAR', ' ');
}
if(!defined('PDFTAG_INDENT')) {
define('PDFTAG_INDENT', 2);
}
if(!defined('MEASURE_REGEX')) {
define('MEASURE_REGEX', "([0-9]{1,5}(\.[0-9]{1,}){0,1})([ ]{0,1})(cm|mm|in|pt){0,1}");
}
if(!defined('OP_REGEX')) {
define('OP_REGEX', "[+*-/]");
}
/* get the version of the PDFlib */
$tmpPDF = PDF_new();
$majorVersion = PDF_get_value($tmpPDF, "major");
$minorVersion = PDF_get_value($tmpPDF, "minor");
unset($tmpPDF);
$this->versionPDFlib = "$majorVersion.$minorVersion";
$this->setType($type);
$this->pageFormat = array( 'A4' => array( 210 / PDFTAG_PTPERMM, 297 / PDFTAG_PTPERMM),
'DIN A4' => array( 210 / PDFTAG_PTPERMM, 297 / PDFTAG_PTPERMM),
'A5' => array( 148 / PDFTAG_PTPERMM, 210 / 0.3528),
'DIN A5' => array( 148 / PDFTAG_PTPERMM, 210 / PDFTAG_PTPERMM),
'A6' => array( 105 / PDFTAG_PTPERMM, 148 / PDFTAG_PTPERMM ),
'DIN A6' => array( 105 / PDFTAG_PTPERMM, 148 / PDFTAG_PTPERMM ),
'letter' => array( 612, 792 ),
'legal' => array( 612, 1008 ),
'ledger' => array( 1224, 792 ),
'11x17' => array( 792, 1224 )
);
$this->tagAlias = array('text' => 'showxy',
'setlinewidth' => 'linewidth');
$this->printDebug = false;
$this->debugIndent = 1;
$this->printWarning = true;
//$this->fontStack = array();
if($src != '') {
$this->XML = $src;
}
/* check for all required php extensions */
if(!extension_loaded('domxml')) {
$this->warning("missing php-extension 'domxml'");
$this->setParser('SAX');
} else {
$this->setParser('DOM');
}
if(!extension_loaded('pdf')) {
$this->error = "missing php-extension 'pdf'";
}
}
/**
* returns the version of pdfTag
* @access public
* @return double
*/
function version() {
return (double)PDFTAG_VERSION;
}
/**
* decides if pdfTag will stop on errors, without a parameter it returns the current state
* @access public
* @param $mode boolean optional
* @return boolean
*/
function stopOnWarning($mode=NULL) {
if($mode == NULL) {
return $this->stopOnWarning;
} else {
$this->stopOnWarning = ($mode == true) ? true : false;
return true;
}
}
/**
* set the attribute checkOnly for pdfTag and enable checking the source without generating the pdf
* @param boolean
* @access public
* @return boolean
*/
function setCheckOnly($mode) {
$this->checkOnly = $mode;
return true;
}
/**
* defines where to create the PDF, in memory or in the filesystem
* @param string $type either 'mem' or 'fs'
* @access public
* @return boolean
*/
function setType($type = "") {
$this->pdfDest = (strtoupper($type) == "FS") ? 'fs' : 'mem';
return true;
}
/**
* read the XML source from a string
* @param string $XMLstring
* @access public
* @return boolean
*/
function readFromString($XMLstring) {
$this->XML = $XMLstring;
return true;
}
/**
* read the source XML from the specified file
* @param string $file the file containing the XML
* @access public
* @return boolean true on success, otherwise false (check pdfTag::error)
*/
function readFromFile($file) {
$this->error = '';
$srcExist = file_exists($file);
$fp = fopen($file , "r");
if(!$fp) {
if(!$srcExist) {
$this->error = "Can't find source file '$file'";
} else {
$this->error = "Can't open source file '$file'";
}
return false;
}
$data = '';
while(!feof($fp)) {
$data .= fgets($fp, 8192);
}
fclose($fp);
$this->XML = $data;
return true;
}
/**
* sends the generated pdf to the browser, even when no headers are send
* @param string $desc if not empty this string will be sent with the header 'Content-Description'
* @return boolean true if all works fine, otherwise false
* @access public
*/
function dumpPDF($desc = '') {
$this->error = '';
if(!headers_sent()) {
header('Pragma: ');
header('Cache-control: cache');
if($desc != '') {
header("Content-Description: $desc");
}
header("Content-Type: application/pdf");
$pdf_length = strlen($this->PDFdata);
header("Content-length: $pdf_length");
print $this->PDFdata;
return true;
} else {
$this->error = "There are already any headers send";
return false;
}
}
/**
* print debug information if requested by setting printDebug to true
* @access private
* @param object $node
* @return boolean
*/
function debugPrint($node) {
$output = $node->tagname;
/* extract id if exist for information */
$attr = $node->attributes();
for($i=0; $i<count($attr); $i++) {
${$attr[$i]->name} = $attr[$i]->value;
}
if(isset($id)) {
$output .= " ( id = $id )";
}
$output = str_repeat(PDFTAG_INDENTCHAR, $this->debugIndent * PDFTAG_INDENT).htmlentities( $output );
print "$output<br>";
return true;
}
/**
* add a warning to the warnings array
* @param string $txt
* @access private
* @return boolean
*/
function warning($txt) {
$this->warnings[] = $txt;
if($this->printWarning) {
$txt = htmlentities($txt);
print "Warning: $txt<br>";
}
return true;
}
/**
* return the current time
* @access private
* @return float
*/
function getMicrotime() {
list($usec, $sec) = explode(" ", microtime());
return ((float)$usec + (float)$sec);
}
/**
* creates the desired PDF from the source
* @access public
* @return boolean true on success, otherwise false
*/
function generatePDF() {
$this->error = '';
if(strlen(trim($this->XML)) == 0) {
$this->error = "XML source is empty";
return false;
}
$this->tStart = pdfTag::getMicrotime();
if($this->useParser == 'DOM') {
$dom = @domxml_open_mem($this->XML);
if(!$dom) {
$this->error = "Can't create DOM object";
return false;
}
$root = $dom->document_element();
$ret = $this->parseXML_DOM($root);
} else {
$ret = $this->parseXML_SAX();
}
if(!$ret) {
$this->cleanUp();
return false;
}
$this->tEnd = pdfTag::getMicrotime();
$this->processingTime = ($this->tEnd - $this->tStart);
if($this->pdfProfile) {
print "processing time ".substr($this->processingTime, 0, 5)." sec<br>";
print "generated pages: ".number_format($this->pageCount,0)."<br>";
print "Size for source: ".number_format(strlen($this->XML)/1024,2,',','.')." kb<br>";
print "Size for generatet PDF: ".number_format(strlen($this->PDFdata)/1024, 2, ',', '.')." kb<br>";
print "Avg size per page: ".number_format(strlen($this->PDFdata)/1024/$this->pageCount,2, ',', '.')." kb<br>";
}
return $ret;
}
/**
* clean the workspace, close file and free resources if called
* @access private
* @return boolean
*/
function cleanUp() {
if(isset($this->pPDF)) {
@PDF_close($this->pPDF);
}
return true;
}
/**
* parses the desired xml node via the domxml extension of php
* @param object $node
* @access private
* @return boolean
*/
function parseXML_DOM(&$node) {
$tag = '';
$ret = true;
if($node->type == XML_ELEMENT_NODE) {
$tag = $node->tagname;
if($node->has_attributes()) {
$attributes = $node->attributes();
} else {
$attributes = NULL;
}
}
if($tag != "") {
if($this->printDebug) {
$this->debugIndent += PDFTAG_INDENT;
$this->debugPrint($node);
}
$fn = "element_$tag";
if(!method_exists($this, $fn)) {
if(isset($this->tagAlias[$tag])) {
$fn = "element_".$this->tagAlias[$tag];
}
if(!method_exists($this, $fn)) {
$this->warning("Non-existing handler for $tag");
if($this->stopOnWarning == true) {
return false;
}
}
} else {
$ret = $this->$fn($node);
if(!$ret) {
print "error $tag ".__LINE__."<br>";
}
}
if($node->has_child_nodes()) {
$child = $node->child_nodes();
for($i=0; $i<count($child);$i++) {
$ret = $this->parseXML_DOM($child[$i]);
if($this->error != '') {
return false;
}
if($this->stopOnWarning == true && $ret == false) {
return false;
}
}
}
if(method_exists($this, $fn)) {
$nullRef = NULL;
$ret = $this->$fn($nullRef);
}
if($this->printDebug) {
$this->debugIndent -= PDFTAG_INDENT;
}
}
return $ret;
}
/**
* parses the xml document with the php builtin sax parser
* @access private
* @return void
*/
function parseXML_SAX() {
$parser = xml_parser_create();
if(!$parser) {
$this->error = "Can't create xml parser (sax)";
return false;
} else {
$values = array();
if(xml_parse_into_struct($parser, $this->XML, $values)) {
xml_parser_free($parser);
$nullRef = NULL;
for($i=0; $i<count($values); $i++) {
$tag = strtolower($values[$i]["tag"]);
$tag = str_replace("pdftag:","",$tag);
$fn = "element_".$tag;
if(!method_exists($this, $fn)) {
if(isset($this->tagAlias[$tag])) {
$fn = "element_".$this->tagAlias[$tag];
}
if(!method_exists($this, $fn)) {
$this->warning("Non-existing handler for $tag");
if($this->stopOnWarning == true) {
return false;
}
break;
}
}
$node = new pdfTagNode($tag, $values[$i]["attributes"]);
$node->set_content($values[$i]["value"]);
switch($values[$i]["type"]) {
case 'open':
if($this->printDebug) {
$this->debugIndent += PDFTAG_INDENT;
$this->debugPrint($node);
}
$ret = $this->$fn($node);
break;
case 'close':
if($this->printDebug) {
$this->debugIndent -= PDFTAG_INDENT;
}
$ret = $this->$fn($nullRef);
break;
case 'complete':
if($this->printDebug) {
$this->debugIndent += PDFTAG_INDENT;
$this->debugPrint($node);
$this->debugIndent -= PDFTAG_INDENT;
}
$ret = $this->$fn($node);
/* ROY hier steht eigentlich $ret or $ret2 */
$ret = $this->$fn($nullRef) || $ret;
break;
case 'cdata':
default:
}
unset($node);
if($this->error != '') {
return false;
}
if($this->stopOnWarning == true && $ret == false) {
return false;
}
}
} else {
$this->error = "XML parser error (";
$this->error .= xml_error_string(xml_get_error_code($parser));
$this->error .= ") in line ".xml_get_current_line_number($parser);
xml_parser_free($parser);
return false;
}
}
return true;
}
/**
* process element document
* @param object $node
* @access private
* @return boolean
*/
function element_document(&$node) {
$this->error = '';
if($node == NULL) {
if( $this->pdfDest == 'fs') {
fclose($this->fpPDF);
}
PDF_close($this->pPDF);
$this->PDFdata = PDF_get_buffer($this->pPDF);
if(strlen($this->PDFdata) > 0) {
PDF_delete($this->pPDF);
}
} else {
if($this->pdfDest == 'fs') {
// generate temporary filename
if($this->filePDF == '') {
$this->filePDF = tempnam('.', 'pdftag_');
}
$this->fpPDF = fopen($this->filePDF, 'wb');
if(!$this->fpPDF) {
$this->error = "Can't create outputfile '".$this->filePDF."'";
return false;
}
$this->pPDF = PDF_open($this->fpPDF);
} else {
$this->pPDF = PDF_new();
PDF_open_file($this->pPDF, "");
}
$attr = $node->attributes();
for($i=0; $i<count($attr); $i++) {
${$attr[$i]->name} = ($this->getParser() == 'DOM') ? utf8_decode($attr[$i]->value) : $attr[$i]->value;
}
if(isset($author)) {
PDF_set_info($this->pPDF, 'Author', $author);
}
if(isset($creator)) {
PDF_set_info($this->pPDF, 'Creator', $creator.' / pdfTag '.$this->version());
} else {
PDF_set_info($this->pPDF, 'Creator', 'pdfTag '.$this->version());
}
if(isset($title)) {
PDF_set_info($this->pPDF, 'Title', $title);
}
if(isset($subject)) {
PDF_set_info($this->pPDF, 'Subject', $subject);
}
if(isset($keywords)) {
PDF_set_info($this->pPDF, 'Keywords', $keywords);
}
$this->commonAttributes($attr);
}
return true;
}
/**
*
* implements common attributs, will only be called by function _$tag
* these attributes are:
* {font="" size="" encoding="" {embed="embed"}}|{id="" size=""} set_font / setfont
* {bordercolor="r,g,b"} set_border_color
* {borderdash="b,w"} set_border_dash
* {borderstyle="[solid|dashed]" borderwidth=""} set_border_style
* {charspacing=""} set_char_spacing
* {horiz_scaling=""} set_horiz_scaling
* {leading=""} set_leading
* {text_rendering="[[0|1|2|3|4|5|6|7]|[filled|border|filledborder|hidden|filledclipped|borderclipped|filledborderclipped|clipped]]"} set_text_rendering
* {text_rise=""} set_text_rise
* {word_spacing=""} set_word_spacing
* {dash="b,w"} set_dash
* {flat=""} set_flat
* {gray=""} set_gray
* {grayfill=""} set_grayfill
* {graystroke=""} set_gray_stroke
* {linecap=[0|1|2]} set_linecap
* {linejoin=[0|1|2]} set_linejoin
* {linewidth=""} set_linewidth
* {matrix="a,b,c,d,e,f"} setmatrix
* {color="r,g,b"} setrgbcolor
* {fillcolor="r,g,b"} setrgbcolor_fill
* {strokecolor="r,g,b"} setrgbcolor_stroke
*
* @param $attr array which contains attributes
*
* @access private
*/
function commonAttributes(&$attr) {
for($i=0; $i<count($attr); $i++) {
${$attr[$i]->name} = $attr[$i]->value;
}
// charspacing
if(isset($charspacing)) {
//PDF_set_char_spacing($this->pPDF, (double)$charspacing);
PDF_set_value($this->pPDF, 'charspacing', (double)pdfTag::measure2Pt($charspacing));
}
// gray
if(isset($gray)) {
PDF_setgray($this->pPDF, (double)$gray);
}
// grayfill
if(isset($grayfill)) {
PDF_setgray_fill($this->pPDF, (double)$grayfill);
}
// graystroke
if(isset($graystroke)) {
PDF_setgray_stroke($this->pPDF, (double)$graystroke);
}
// linewidth
if(isset($linewidth)) {
PDF_setlinewidth($this->pPDF, (double)pdfTag::measure2Pt($linewidth));
}
if(isset($flat)) {
PDF_setflat($this->pPDF, (double)$flat);
}
// color
if(isset($color)) {
$color = explode( ',', $color);
if(count($color) == 3) {
$r = $color[0];
$g = $color[1];
$b = $color[2];
PDF_setrgbcolor($this->pPDF, (double)$r, (double)$g, (double)$b);
} else {
$this->warning("wrong values for color='r,g,b'");
}
}
// strokecolor
if(isset($strokecolor)) {
$strokecolor = explode( ',', $strokecolor);
if(count($strokecolor) == 3) {
$r = $strokecolor[0];
$g = $strokecolor[1];
$b = $strokecolor[2];
PDF_setrgbcolor_stroke($this->pPDF, (double)$r, (double)$g, (double)$b);
} else {
$this->warning("wrong values for strokecolor='r,g,b'");
}
}
// fillcolor
if(isset( $fillcolor )) {
$fillcolor = explode(',', $fillcolor);
if(count($fillcolor) == 3) {
$r = $fillcolor[0];
$g = $fillcolor[1];
$b = $fillcolor[2];
PDF_setrgbcolor_fill($this->pPDF, (double)$r, (double)$g, (double)$b);
} else {
$this->warning("wrong values for fillcolor=\"r,g,b\"");
}
}
// font
if(isset($font) && isset($size) && isset($encoding)) {
$embed = (isset($embed) && $embed == 'embed') ? 1 : 0;
$fontHandle = PDF_findfont($this->pPDF, $font, $encoding, $embed);
if(!$fontHandle) {
die("Error while PDF_findfont");
}
PDF_setfont($this->pPDF, $fontHandle, (double)pdfTag::measure2Pt($size));
//PDF_set_font($this->pPDF, $font, doubleval($size), $encoding, $embed);
}
if(isset($fontid)) {
if(isset($this->fontStack[$fontid])) {
$curFont = $this->fontStack[$fontid];
if(!isset($size)) {
$size = $curFont["handle"];
}
PDF_setfont($this->pPDF, $fontHandle, (double)pdfTag::measure2Pt($size));
//PDF_set_font($this->pPDF, $curFont["font"], doubleval($curFont["size"]), $curFont["encoding"], $curFont["embed"]);
} else {
$this->warning("usage of prior undefined font fontid='$fontid'");
}
}
if(isset($linecap)) {
$linecap = (int)$linecap;
if($linecap < 0 || $linecap > 2) {
$this->warning("wrong value for attribute 'linecap'");
} else {
PDF_setlinecap($this->pPDF, $linecap);
}
}
// dash
if(isset($dash)) {
$dash = explode( ',', $dash);
if(count($dash) == 2) {
$b = $dash[0];
$w = $dash[1];
PDF_setdash($this->pPDF, (double)$b, (double)$w);
} else {
$this->warning("wrong values for dash=\"b,w\"");
}
}
return true;
}
/**
* syntaxcheck for attributes
* @access private
* @return boolean
* EXPERIMENTAL
*/
function checkAttribute($var) {
print $$var;
$attr = var_export($var);
$value = $var;
if($var == '') {
$this->warning("empty attribute '$attr' not allowed");
} else {
switch($attr) {
case 'border':
if(in_array($value, array('on', 'off','filled'))) {
return true;
} else {
return false;
}
break;
default:
$this->warning("unkown attribute '$attr'" );
break;
}
}
}
/**
* process element page
* @param object $node
* @access private
* @return boolean
*/
function element_page(&$node) {
if($node == NULL) {
PDF_restore($this->pPDF);
PDF_end_page($this->pPDF);
} else {
$attr = $node->attributes();
for($i=0; $i<count($attr); $i++) {
${$attr[$i]->name} = $attr[$i]->value;
}
if(isset($format)) {
if(isset($this->pageFormat[$format])) {
$width = $this->pageFormat[$format][0];
$height = $this->pageFormat[$format][1];
} else {
$this->warning("undefined page-format $format");
}
}
if(isset($width) && isset($height)) {
if(isset($orientation)) {
if($orientation == "landscape") {
$save = $width;
$width = $height;
$height = $save;
unset($save);
} else {
if($orientation != "portrait") {
$this->warning('wrong value for <page orientation="">');
}
}
}
PDF_begin_page($this->pPDF, (double)pdftag::measure2Pt($width), (double)pdfTag::measure2Pt($height));
PDF_save($this->pPDF);
$this->commonAttributes($attr);
$this->pageCount++;
} else {
$this->warning("wrong/missing attributes 'format|(width|height)' for element 'page");
}
}
return true;
}
/**
* process element outline
* @access private
* @return boolean
*/
function element_outline(&$node) {
if($node == NULL) {
} else {
$attr = $node->attributes();
for($i=0; $i<count($attr); $i++) {
${$attr[$i]->name} = $attr[$i]->value;
}
if( $node->get_content()!='' ) {
//$text = $node->get_content();
$text = ($this->getParser() == 'DOM') ? utf8_decode($node->get_content()) : $node->get_content();
}
if(isset($text)) {
$text = utf8_decode($text);
if(isset($parent)) {
if(isset($this->outlineStack[$parent])) {
if(isset($open)) {
$open = ($open == 'open') ? 1 : 0;
$ret = PDF_add_bookmark($this->pPDF, $text, $this->outlineStack[$parent], $open);
} else {
$ret = PDF_add_bookmark($this->pPDF, $text, $this->outlineStack[$parent]);
}
} else {
$this->warning("undefined parent id '$parent' in element 'outline'");
if($this->stopOnWarning == true) {
return false;
}
}
} else {
$ret = PDF_add_bookmark($this->pPDF, $text);
}
if(isset($id)) {
if(isset($this->outlineStack[$id])) {
$this->warning("overwriting existing outline id '$id'");
if($this->stopOnWarning == true) {
return false;
}
} else {
$this->outlineStack[$id] = $ret;
}
}
} else {
$this->warning("element 'outline without content");
if($this->stopOnWarning == true) {
return false;
}
}
}
return true;
}
/**
* process element path
* @param object $node
* @access private
* @return boolean
*/
function element_path(&$node) {
if($node == NULL) {
PDF_restore($this->pPDF);
} else {
$attr = $node->attributes();
for($i=0; $i<count($attr); $i++) {
${$attr[$i]->name} = $attr[$i]->value;
}
PDF_save($this->pPDF);
if($node->get_content() != '') {
$text = $node->get_content();
}
if(isset($coord) || isset($text)) {
if(isset($text)) {
$coord = $text;
}
$coord = explode(',', $coord);
if((count($coord) % 2) != 0) {
$this->warning("wrong parameter count for element 'path'");
if($this->stopOnWarning == true) {
return false;
}
} else {
PDF_moveto($this->pPDF, (double)pdfTag::measure2Pt($coord[0]), (double)pdfTag::measure2Pt($coord[1]));
for($i=2; $i<count($coord); $i=$i+2) {
PDF_lineto($this->pPDF, (double)pdfTag::measure2Pt($coord[$i]), (double)pdfTag::measure2Pt($coord[$i+1]));
}
PDF_closepath($this->pPDF);
if(isset($filled) && $filled == "filled") {
if(isset($border) && $border == "border") {
PDF_fill_stroke($this->pPDF);
} else {
PDF_fill($this->pPDF);
}
} else {
PDF_stroke($this->pPDF);
}
}
} else {
$this->warning("wrong/missing attribute(s)/content for element 'path'");
if($this->stopOnWarning == true) {
return false;
}
}
}
return true;
}
/**
* process element setfont
* @param object $node
* @return boolean
* @access private
*/
function element_setfont(&$node) {
if($node == NULL) {
} else {
$attr = $node->attributes();
for($i=0; $i<count($attr); $i++) {
${$attr[$i]->name} = $attr[$i]->value;
}
if(!isset($encoding)) {
$encoding="winansi";
}
if(isset($font) && isset($size) && isset($encoding)) {
$embed = (isset($embed) && $embed == 'embed') ? 1 : 0;
$fontHandle = PDF_findfont($this->pPDF, $font, $encoding, $embed);
if(!$fontHandle) {
die("Error while PDF_findfont");
}
PDF_setfont($this->pPDF, $fontHandle, (double)pdfTag::measure2Pt($size));
if(isset($id)) {
if(isset($this->fontStack[$id])) {
$this->warning("overwriting existing font id '$id'");
} else {
$this->fontStack[$id]["font"] = "$font";
$this->fontStack[$id]["size"] = $size;
$this->fontStack[$id]["encoding"] = "$encoding";
$this->fontStack[$id]["embed"] = (int)$embed;
$this->fontStack[$id]["handle"] = $fontHandle;
}
}
} else {
if(isset($fontid)) {
if(isset($this->fontStack[$id])) {
if(!isset($size)) {
$size = $this->fontStack[$id]["size"];
}
PDF_setfont($this->pPDF, $this->fontStack[$id]["handle"], (double)$size);
} else {
$this->warning("usage of prior undefined font with id='$id'");
if($this->stopOnWarning == true) {
return false;
}
}
} else {
$this->warning("missing attributes for element 'setfont'");
if($this->stopOnWarning == true) {
return false;
}
}
}
}
return true;
}
/**
* process element showxy
* @param object $node
* @access private
* @return boolean
*/
function element_showxy(&$node) {
if($node == NULL) {
PDF_restore($this->pPDF);
} else {
PDF_save($this->pPDF);
$attr = $node->attributes();
for($i=0; $i<count($attr); $i++) {
${$attr[$i]->name} = ($this->getParser() == 'DOM' ) ? utf8_decode($attr[$i]->value) : $attr[$i]->value;
}
$this->commonAttributes($attr);
if($node->get_content() != '') {
$text = ($this->getParser() == 'DOM') ? utf8_decode($node->get_content()) : $node->get_content();
}
if(isset($x) && isset($y)) {
if(isset($text)) {
PDF_show_xy($this->pPDF, pdfTag::strClean($text), (double)pdfTag::measure2Pt($x), (double)pdfTag::measure2Pt($y));
}
} else {
$this->warning("missing attribute(s) for element 'showxy'");
if($this->stopOnWarning == true) {
return false;
}
}
}
return true;
}
/**
* remove leading and trailing whitespaces
* @access private
* @param string $text
* @return string
*/
function strClean($text) {
return pdfTag::strReverse(chop(pdfTag::strReverse($text)));
}
/**
* returns a given string in reversed order
* @access private
* @param string $text
* @return string
*/
function strReverse($text) {
$str1 = $text;
$str2 = '';
while(strlen($str1) > 0) {
$str2 .= substr($str1, -1);
$str1 = substr($str1, 0, -1);
}
return $str2;
}
/**
* process element annotation
* @param object $node
* @access private
* @return boolean
*/
function element_annotation(&$node) {
if($node == NULL) {
} else {
$attr = $node->attributes();
for($i=0; $i<count($attr); $i++) {
${$attr[$i]->name} = ($this->getParser() == 'DOM' ) ? utf8_decode($attr[$i]->value) : $attr[$i]->value;
}
if($node->get_content() != '') {
$text = ($this->getParser() == 'DOM') ? utf8_decode($node->get_content()) : $node->get_content;
}
if(isset($llx) && isset($lly) && isset($urx) && isset($ury) && isset($title) && isset($text)) {
$text = $text;
PDF_add_annotation($this->pPDF, (double)pdfTag::measure2Pt($llx), (double)pdfTag::measure2Pt($lly), (double)pdfTag::measure2Pt($urx), (double)pdfTag::measure2Pt($ury), $title, $text);
} else {
$this->warning("missing attribute(s) for element 'annotation'");
if($this->stopOnWarning == true) {
return false;
}
}
}
return true;
}
/**
* process element note
* @param object $node
* @access private
* @return boolean
*/
function element_note(&$node) {
$iconArray = array('comment', 'insert', 'note', 'paragraph', 'newparagraph', 'key', 'help');
if($node == NULL) {
} else {
$attr = $node->attributes();
for($i=0; $i<count($attr); $i++) {
${$attr[$i]->name} = ($this->getParser() == 'DOM') ? utf8_decode($attr[$i]->value) : $attr[$i]->value;
}
if($node->get_content() != '') {
$text = ($this->getParser() == 'DOM') ? utf8_decode($node->get_content()) : $node->get_content();
}
$open = ($open == 'open') ? 1 : 0;
if(!in_array($icon, $iconArray)) {
unset($icon);
}
if(isset($llx) && isset($lly) && isset($urx) && isset($ury) && isset($title) && isset($text) && isset($icon) && isset($open)) {
PDF_add_note($this->pPDF, (double)pdfTag::measure2Pt($llx), (double)pdfTag::measure2Pt($lly), (double)pdfTag::measure2Pt($urx), (double)pdfTag::measure2Pt($ury), $text, $title, $icon, (int)$open);
} else {
$this->warning("missing attribute(s) for element 'note'");
if($this->stopOnWarning == true) {
return false;
}
}
}
return true;
}
/**
* process element arc
* @param object $node
* @access private
* @return boolean
*/
function element_arc(&$node) {
if($node == NULL) {
PDF_restore($this->pPDF);
} else {
PDF_save($this->pPDF);
$attr = $node->attributes();
for($i=0; $i<count($attr); $i++) {
${$attr[$i]->name} = $attr[$i]->value;
}
$this->commonAttributes($attr);
if(isset($x) && isset($y) && isset($radius) && isset($start) && isset($end)) {
PDF_arc($this->pPDF, (double)pdfTag::measure2Pt($x), (double)pdfTag::measure2Pt($y), (double)pdfTag::measure2Pt($radius), (double)$start, (double)$end);
if(isset($filled) && $filled == "filled") {
if(isset($border) && $border == "border") {
PDF_fill_stroke($this->pPDF);
} else {
PDF_fill($this->pPDF);
}
} else {
PDF_stroke($this->pPDF);
}
} else {
$this->warning("missing attribute(s) for element 'arc'");
if($this->stopOnWarning == true) {
return false;
}
}
}
return true;
}
/**
* process element circle
* @param object $node
* @access private
* @return boolean
*/
function element_circle(&$node) {
if($node == NULL) {
PDF_restore($this->pPDF);
} else {
$attr = $node->attributes();
for($i=0; $i<count($attr); $i++) {
${$attr[$i]->name} = $attr[$i]->value;
}
PDF_save($this->pPDF);
$this->commonAttributes($attr);
if(isset($x) && isset($y) && isset($radius)) {
PDF_circle($this->pPDF, (double)pdfTag::measure2Pt($x), (double)pdfTag::measure2Pt($y), (double)pdfTag::measure2Pt($radius));
if(isset($filled) && $filled == "filled") {
if(isset($border) && $border == "border") {
PDF_fill_stroke($this->pPDF);
} else {
PDF_fill($this->pPDF);
}
} else {
PDF_stroke($this->pPDF);
}
} else {
$this->warning("missing attribute(s) for element 'circle'");
if($this->stopOnWarning == true) {
return false;
}
}
}
return true;
}
/**
* processing element clip
* @param object $node
* @access private
* @return boolean
*/
function element_clip(&$node) {
if($node == NULL) {
} else {
PDF_clip($this->pPDF);
}
return true;
}
/**
* process element continue_text
* @param object $node
* @access private
* @return boolean
*/
function element_continue_text(&$node) {
if($node == NULL) {
PDF_restore($this->pPDF);
} else {
$attr = $node->attributes();
for($i=0; $i<count($attr); $i++) {
${$attr[$i]->name} = ($this->getParser() == 'DOM') ? utf8_decode($attr[$i]->value) : $attr[$i]->value;
}
if($node->get_content() != '') {
$text = ($this->getParser() == 'DOM') ? utf8_decode($node->get_content) : $node->get_content();
}
PDF_save($this->pPDF);
$this->commonAttributes($attr);
if(isset($text)) {
PDF_continue_text($this->pPDF, $text);
} else {
$this->warning("missing attribute 'text' for element 'continue_text'");
if($this->stopOnWarning == true) {
return false;
}
}
}
return true;
}
/**
* process element curveto
* @param object $node
* @access private
* @return boolean
*/
function element_curveto(&$node) {
if($node == NULL) {
//PDF_restore($this->pPDF);
} else {
$attr = $node->attributes();
for($i=0; $i<count($attr); $i++) {
${$attr[$i]->name} = $attr[$i]->value;
}
//PDF_save($this->pPDF);
//$this->commonAttributes($attr);
if($node->get_content() != '') {
$coord = $node->get_content();
}
if(isset($coord) && trim($coord) != '') {
$coord = explode(',', $coord);
}
if(count($coord) != 6) {
$this->warning("there must be six doublevalues in element 'curveto' present'");
if($this->stopOnWarning == true) {
return false;
}
} else {
$x1 = $coord[0];
$y1 = $coord[1];
$x2 = $coord[2];
$y2 = $coord[3];
$x3 = $coord[4];
$y3 = $coord[5];
}
if(isset($x1) && isset($y1) && isset($x2) && isset($y2) && isset($x3) && isset($y3)) {
PDF_curveto($this->pPDF, (double)pdfTag::calcTerm($x1), (double)pdfTag::calcTerm($y1),
(double)pdfTag::calcTerm($x2), (double)pdfTag::calcTerm($y2),
(double)pdfTag::calcTerm($x3), (double)pdfTag::calcTerm($y3));
} else {
$this->warning("missing attribute(s) for element 'curveto'");
if($this->stopOnWarning == true) {
return false;
}
}
}
return true;
}
/**
* process element fill
* @param object $node
* @access private
* @return boolean
*/
function element_fill(&$node) {
if($node == NULL) {
PDF_restore($this->pPDF);
} else {
$attr = $node->attributes();
for($i=0; $i<count($attr); $i++) {
${$attr[$i]->name} = $attr[$i]->value;
}
PDF_save($this->pPDF);
$this->commonAttributes($attr);
PDF_fill($this->pPDF);
}
return true;
}
/**
* process element fill_stroke
* @param object $node
* @access private
* @return boolean
*/
function element_fill_stroke(&$node) {
if($node == NULL) {
PDF_restore($this->pPDF);
} else {
$attr = $node->attributes();
for($i=0; $i<count($attr); $i++) {
${$attr[$i]->name} = $attr[$i]->value;
}
PDF_save($this->pPDF);
$this->commonAttributes($attr);
PDF_fill_stroke($this->pPDF);
}
return true;
}
/**
* process element lineto
* @param object $node
* @access private
* @return boolean
*/
function element_lineto(&$node) {
if($node == NULL) {
} else {
$attr = $node->attributes();
for($i=0; $i<count($attr); $i++) {
${$attr[$i]->name} = $attr[$i]->value;
}
if(isset($x) && isset($y)) {
PDF_lineto($this->pPDF, (double)pdfTag::measure2Pt($x), (double)pdfTag::measure2Pt($y));
} else {
$this->warning("missing attribute(s) for element 'moveto'");
if($this->stopOnWarning == true) {
return false;
}
}
}
return true;
}
/**
* process element rect
* @param object $node
* @access private
* @return boolean
*/
function element_rect(&$node) {
if($node == NULL) {
PDF_restore($this->pPDF);
} else {
$attr = $node->attributes();
for($i=0; $i<count($attr); $i++) {
${$attr[$i]->name} = $attr[$i]->value;
}
PDF_save($this->pPDF);
$this->commonAttributes($attr);
if(isset($x) && isset($y) && isset($width) && isset($height)) {
PDF_rect($this->pPDF, (double)pdfTag::measure2Pt($x), (double)pdfTag::measure2Pt($y), (double)pdfTag::measure2Pt($width), (double)pdfTag::measure2Pt($height));
if(isset($filled) && $filled == "filled") {
if(isset($border) && $border == "border") {
PDF_fill_stroke($this->pPDF);
} else {
PDF_fill($this->pPDF);
}
} else {
PDF_stroke($this->pPDF);
}
} else {
$this->warning("missing attribute(s) for element 'rect'");
if($this->stopOnWarning == true) {
return false;
}
}
}
return true;
}
/**
* process element save
* @param object $node
* @access private
* @return boolean
*/
function element_save(&$node) {
if($node == NULL) {
PDF_restore($this->pPDF);
} else {
PDF_save($this->pPDF);
}
return true;
}
/**
* process element rotate
* @param object $node
* @access private
* @return boolean
*/
function element_rotate(&$node) {
if($node == NULL) {
} else {
$attr = $node->attributes();
for($i=0; $i<count($attr); $i++) {
${$attr[$i]->name} = $attr[$i]->value;
}
if(isset($angle)) {
PDF_rotate($this->pPDF, (double)$angle);
} else {
$this->warning("missing attribute 'angle' for element 'rotate'");
if($this->stopOnWarning == true) {
return false;
}
}
}
return true;
}
/**
* process element stroke
* @param object $node
* @access private
* @return boolean
*/
function element_stroke(&$node) {
if($node == NULL) {
} else {
$attr = $node->attributes();
for($i=0; $i<count($attr); $i++) {
${$attr[$i]->name} = $attr[$i]->value;
}
if(isset($filled) && $filled == "filled") {
if(isset($border)) {
if(checkAttribute($border)) {
PDF_fill_stroke($this->pPDF);
}
} else {
PDF_fill($this->pPDF);
}
} else {
PDF_stroke($this->pPDF);
}
}
return true;
}
/**
* process element moveto
* @param object $node
* @access private
* @return boolean
*/
function element_moveto(&$node) {
if($node == NULL) {
//PDF_restore($this->pPDF);
} else {
$attr = $node->attributes();
for($i=0; $i<count($attr); $i++) {
${$attr[$i]->name} = $attr[$i]->value;
}
//PDF_save($this->pPDF);
//$this->commonAttributes($attr);
if(isset($x) && isset($y)) {
PDF_moveto($this->pPDF, (double)pdfTag::measure2Pt($x), (double)pdfTag::measure2Pt($y));
} else {
$this->warning("missing attribute(s) for 'moveto'");
if($this->stopOnWarning == true) {
return false;
}
}
}
return true;
}
/**
* process element scale
* @param object $node
* @access private
* @return boolean
*/
function element_scale(&$node) {
if($node == NULL) {
} else {
$attr = $node->attributes();
for($i=0; $i<count($attr); $i++) {
${$attr[$i]->name} = $attr[$i]->value;
}
if(isset($sx) && isset($sy)) {
PDF_scale($this->pPDF, (double)$sx, (double)$sy);
} else {
$this->warning("missing attribute(s) for 'scale'");
if($this->stopOnWarning == true) {
return false;
}
}
}
return true;
}
/**
* process element show
* @param object $node
* @access private
* @return boolean
*/
function element_show(&$node) {
if($node == NULL) {
PDF_restore($this->pPDF);
} else {
$attr = $node->attributes();
for($i=0; $i<count($attr); $i++) {
${$attr[$i]->name} = ($this->getParser() == 'DOM') ? utf8_decode($attr[$i]->value) : $attr[$i]->value;
}
if($node->get_content() != '') {
$text = ($this->getParser() == 'DOM') ? utf8_decode($node->get_content()) : $node->get_content();
}
PDF_save($this->pPDF);
$this->commonAttributes($attr);
if(isset($text)) {
PDF_show($this->pPDF, $text);
} else {
$this->warning("missing content/attribute 'text' for element show");
if($this->stopOnWarning == true) {
return false;
}
}
}
return true;
}
/**
* process element set_leading
* @param object $node
* @access private
* @return boolean
*/
function element_set_leading(&$node) {
if($node == NULL) {
} else {
$attr = $node->attributes();
for($i=0; $i<count($attr); $i++) {
${$attr[$i]->name} = $attr[$i]->value;
}
if(isset($offset)) {
//PDF_set_leading($this->pPDF, doubleval($offset));
PDF_set_value($this->pPDF, 'leading', (double)$offset);
} else {
$this->warning("missing attribute 'offset' for element 'set_leading'");
if($this->stopOnWarning == true) {
return false;
}
}
}
return true;
}
/**
* process element initgraphics
* @param object $node
* @access private
* @return boolean
*/
function element_initgraphics(&$node) {
if($node == NULL) {
} else {
PDF_initgraphics($this->pPDF);
}
return true;
}
/**
* process element border_color
* @param object $node
* @access private
* @return boolean
*/
function element_border_color(&$node) {
if($node == NULL) {
} else {
$attr = $node->attributes();
for($i=0; $i<count($attr); $i++) {
${$attr[$i]->name} = $attr[$i]->value;
}
if($node->get_content() != '') {
$colors = $node->get_content();
}
if(isset($colors) || (isset($r) && isset($g) && isset($b))) {
if(isset($colors)) {
$colors = explode(',', $colors);
if(count($colors) != 3) {
$this->warning("wrong parameter count for element 'border_color'");
if($this->stopOnWarning == true) {
return false;
}
} else {
$r = $colors[0];
$g = $colors[1];
$b = $colors[2];
}
}
PDF_set_border_color($this->pPDF, (double)$r, (double)$g, (double)$b);
} else {
$this->warning("missing attribute(s) for element 'border_color'");
if($this->stopOnWarning == true) {
return false;
}
}
}
return true;
}
/**
* process element translate
* @param object $node
* @access private
* @return boolean
*/
function element_translate(&$node) {
if($node == NULL) {
} else {
$attr = $node->attributes();
for($i=0; $i<count($attr); $i++) {
${$attr[$i]->name} = $attr[$i]->value;
}
if(isset($x) && isset($y)) {
PDF_translate($this->pPDF, (double)pdfTag::measure2Pt($x), (double)pdfTag::measure2Pt($y));
} else {
$this->warning("missing attribute(s) for element 'translate'");
if($this->stopOnWarning == true) {
return false;
}
}
}
return true;
}
/**
* process element duration
* @param object $node
* @access private
* @return boolean
*/
function element_duration(&$node) {
if($node == NULL) {
} else {
$attr = $node->attributes();
for($i=0; $i<count($attr); $i++) {
${$attr[$i]->name} = $attr[$i]->value;
}
if(isset($value)) {
PDF_set_duration($this->pPDF, (double)$value);
} else {
$this->warning("missing attribute 'value' for element 'duration'");
if($this->stopOnWarning == true) {
return false;
}
}
}
return true;
}
/**
* process element setrgbcolor
* @param object $node
* @access private
* @return boolean
*/
function element_setrgbcolor(&$node) {
if($node == NULL) {
} else {
$attr = $node->attributes();
for($i=0; $i<count($attr); $i++) {
${$attr[$i]->name} = $attr[$i]->value;
}
if($node->get_content() != '') {
$colors = $node->get_content();
}
if(isset($colors) || (isset($r) && isset( $g) && isset($b))) {
if(isset($colors)) {
$colors = explode(',', $colors);
if(count($colors) != 3) {
$this->warning("wrong colour value for element 'border_color'");
if($this->stopOnWarning == true) {
return false;
}
} else {
$r = $colors[0];
$g = $colors[1];
$b = $colors[2];
}
}
PDF_setrgbcolor($this->pPDF, (double)$r, (double)$g, (double)$b);
} else {
$this->warning("missing attribute(s) for element 'setrgbcolor'");
if($this->stopOnWarning == true) {
return false;
}
}
}
return true;
}
/**
* process element set
* @param object $node
* @access private
* @return boolean
*/
function element_set(&$node) {
if($node == NULL) {
} else {
$attr = $node->attributes();
$this->commonAttributes($attr);
}
return true;
}
/**
* process element closepath
* @param object $node
* @access private
* @return boolean
*/
function element_closepath(&$node) {
if($node == NULL) {
} else {
$attr = $node->attributes();
for($i=0; $i<count($attr); $i++) {
${$attr[$i]->name} = $attr[$i]->value;
}
PDF_closepath($this->pPDF);
}
return true;
}
/**
* process element template
* @param object $node
* @access private
* @return boolean
*/
function element_template(&$node) {
if($node == NULL) {
PDF_end_template($this->pPDF);
} else {
$attr = $node->attributes();
for($i=0; $i<count($attr); $i++) {
${$attr[$i]->name} = $attr[$i]->value;
}
if(isset($width) && isset($height) && isset($id)) {
$ret = PDF_begin_template($this->pPDF, (float)pdfTag::measure2Pt($width), (float)pdfTag::measure2Pt($height));
if(isset($this->tmplStack[$id])) {
$this->warning("overwriting existing template id '$id'");
if($this->stopOnWarning == true) {
return false;
}
} else {
$this->tmplStack[$id] = $ret;
}
} else {
$this->warning("wrong/missing parameter for element 'template'");
if($this->stopOnWarning == true) {
return false;
}
}
}
return true;
}
/**
* process element settemplate
* @param object $node
* @access private
* @return boolean
*/
function element_settemplate(&$node) {
if($node == NULL) {
PDF_restore($this->pPDF);
} else {
PDF_save($this->pPDF);
$attr = $node->attributes();
for($i=0; $i<count($attr); $i++) {
${$attr[$i]->name} = $attr[$i]->value;
}
$this->commonAttributes($attr);
if(isset($x) && isset($y) && isset($id)) {
if(isset($this->tmplStack[$id])) {
if(!isset($scale)) {
$scale = 1.0;
}
PDF_place_image($this->pPDF, $this->tmplStack[$id], (double)pdfTag::measure2Pt($x), (double)pdfTag::measure2Pt($y), (double)$scale);
} else {
$this->warning("id '$id' is not defined beyond this point");
if($this->stopOnWarning == true) {
return false;
}
}
} else {
$this->warning("wrong/missing attributes for 'settemplate'");
if($this->stopOnWarning == true) {
return false;
}
}
}
return true;
}
/**
* process element openimagefile
* @param object $node
* @access private
* @return boolean
*/
function element_openimagefile(&$node) {
if($node == NULL) {
} else {
$attr = $node->attributes();
for($i=0; $i<count($attr); $i++) {
${$attr[$i]->name} = $attr[$i]->value;
}
if(isset($type)) {
if(in_array($type, array('tiff', 'png', 'jpeg', 'gif'))) {
if(isset($src)) {
if(file_exists($src)) {
$fp = @fopen($src, "rb");
if(!$fp) {
$this->error = "Can't open file '$src' for element 'openimagefile'";
return false;
} else {
$imgData = '';
while(!feof($fp)) {
$imgData .