works right. var $B = 0; var $I = 0; var $U = 0; var $left_margin = array( 28.35 ); // 1cm var $right_margin = array( 28.35 ); // 1cm var $bottom_margin = array( 28.35 ); // 1cm var $div_x = array(); var $div_y = array(); var $cell_info; // stuff to keep around until a shows up var $cell_text; // text to put in a cell. var $script; // stuff to put in our script. var $header=''; var $footer=''; var $parserBreak; // when you want to break parsing, put a stop word here. var $multicol = array(); // stack of columns. you never know. /* Rotation extension. Should go away with 1.6 */ var $angle=0; function Rotate($angle,$x=-1,$y=-1) { if($x==-1) $x=$this->x; if($y==-1) $y=$this->y; if($this->angle!=0) $this->_out('Q'); $this->angle=$angle; if($angle!=0) { $angle*=M_PI/180; $c=cos($angle); $s=sin($angle); $cx=$x*$this->k; $cy=($this->h-$y)*$this->k; $this->_out(sprintf('q %.5f %.5f %.5f %.5f %.2f %.2f cm 1 0 0 1 %.2f %.2f cm',$c, $s,-$s,$c,$cx,$cy,-$cx,-$cy)); } } function _endpage() { if($this->angle!=0) { $this->angle=0; $this->_out('Q'); } parent::_endpage(); } /* End of Rotation Extension */ /* Ellipse extension. Should go away with 1.6 */ function Circle($x,$y,$r,$style='') { $this->Ellipse($x,$y,$r,$r,$style); } function Ellipse($x,$y,$rx,$ry,$style='D') { if($style=='F') $op='f'; elseif($style=='FD' or $style=='DF') $op='B'; else $op='S'; $lx=4/3*(M_SQRT2-1)*$rx; $ly=4/3*(M_SQRT2-1)*$ry; $k=$this->k; $h=$this->h; $this->_out(sprintf('%.2f %.2f m %.2f %.2f %.2f %.2f %.2f %.2f c', ($x+$rx)*$k,($h-$y)*$k, ($x+$rx)*$k,($h-($y-$ly))*$k, ($x+$lx)*$k,($h-($y-$ry))*$k, $x*$k,($h-($y-$ry))*$k)); $this->_out(sprintf('%.2f %.2f %.2f %.2f %.2f %.2f c', ($x-$lx)*$k,($h-($y-$ry))*$k, ($x-$rx)*$k,($h-($y-$ly))*$k, ($x-$rx)*$k,($h-$y)*$k)); $this->_out(sprintf('%.2f %.2f %.2f %.2f %.2f %.2f c', ($x-$rx)*$k,($h-($y+$ly))*$k, ($x-$lx)*$k,($h-($y+$ry))*$k, $x*$k,($h-($y+$ry))*$k)); $this->_out(sprintf('%.2f %.2f %.2f %.2f %.2f %.2f c %s', ($x+$lx)*$k,($h-($y+$ry))*$k, ($x+$rx)*$k,($h-($y+$ly))*$k, ($x+$rx)*$k,($h-$y)*$k, $op)); } /* End of Ellipse Extension */ /* Javascript extension. That may stick here a while. */ var $javascript; var $n_js; function IncludeJS($script) { $this->javascript.=$script; } function _putjavascript() { $this->_newobj(); $this->n_js=$this->n; $this->_out('<<'); $this->_out('/Names [(EmbeddedJS) '.($this->n+1).' 0 R ]'); $this->_out('>>'); $this->_out('endobj'); $this->_newobj(); $this->_out('<<'); $this->_out('/S /JavaScript'); $this->_out('/JS '.$this->_textstring($this->javascript)); $this->_out('>>'); $this->_out('endobj'); } function _putresources() { parent::_putresources(); if (!empty($this->javascript)) { $this->_putjavascript(); } $this->_putbookmarks(); } function _putcatalog() { parent::_putcatalog(); if (isset($this->javascript)) { $this->_out('/Names <n_js).' 0 R>>'); } if(count($this->outlines)>0) { $this->_out('/Outlines '.$this->OutlineRoot.' 0 R'); $this->_out('/PageMode /UseOutlines'); } } /* End of Javascript Extension */ /* Bookmark Extension. Should go away with 1.6 */ var $outlines=array(); var $OutlineRoot; function Bookmark($txt,$level=0,$y=0) { if($y==-1) $y=$this->GetY(); $this->outlines[]=array('t'=>$txt,'l'=>$level,'y'=>$y,'p'=>$this->PageNo()); } function _putbookmarks() { $nb=count($this->outlines); if($nb==0) return; $lru=array(); $level=0; foreach($this->outlines as $i=>$o) { if($o['l']>0) { $parent=$lru[$o['l']-1]; //Set parent and last pointers $this->outlines[$i]['parent']=$parent; $this->outlines[$parent]['last']=$i; if($o['l']>$level) { //Level increasing: set first pointer $this->outlines[$parent]['first']=$i; } } else $this->outlines[$i]['parent']=$nb; if($o['l']<=$level and $i>0) { //Set prev and next pointers $prev=$lru[$o['l']]; $this->outlines[$prev]['next']=$i; $this->outlines[$i]['prev']=$prev; } $lru[$o['l']]=$i; $level=$o['l']; } //Outline items $n=$this->n+1; foreach($this->outlines as $i=>$o) { $this->_newobj(); $this->_out('<_textstring($o['t'])); $this->_out('/Parent '.($n+$o['parent']).' 0 R'); if(isset($o['prev'])) $this->_out('/Prev '.($n+$o['prev']).' 0 R'); if(isset($o['next'])) $this->_out('/Next '.($n+$o['next']).' 0 R'); if(isset($o['first'])) $this->_out('/First '.($n+$o['first']).' 0 R'); if(isset($o['last'])) $this->_out('/Last '.($n+$o['last']).' 0 R'); $this->_out(sprintf('/Dest [%d 0 R /XYZ 0 %.2f null]',1+2*$o['p'],($this->h-$o['y'])*$this->k)); $this->_out('/Count 0>>'); $this->_out('endobj'); } //Outline root $this->_newobj(); $this->OutlineRoot=$this->n; $this->_out('<_out('/Last '.($n+$lru[0]).' 0 R>>'); $this->_out('endobj'); } /* End of Bookmark Extension */ function ParsePDML($pdml) { // default font. $this->SetFont($this->font_face[0],'',$this->font_size[0]); // apply margins $this->SetRightMargin($this->right_margin[0]); $this->SetLeftMargin($this->left_margin[0]); // bottom margin $this->SetAutoPageBreak(true, $this->bottom_margin[0]); $this->AliasNbPages('&pagecount;'); $this->_parsePDML($pdml); //return $this->final; } function Header() { $this->_parsePDML($this->header); } function Footer() { $this->_parsePDML($this->footer); } function AcceptPageBreak() { if (count($this->multicol>0)) { // we need: starting y0, col_width, col_spacing, columns, height, break=page/line list($x0, $y0, $width, $height, $spacing, $break, $cols, $current) = $this->multicol[0]; if ($current<$cols-1) { // next column $current++; $this->multicol[0][7] = $current; $x = $x0 + $current * $width; $this->SetLeftMargin($x); $this->SetX($x); $this->SetY($y0); return false; } else { // ok. we need to break. $this->SetLeftMargin($x0); $this->SetX($x0); $this->multicol[0][7] = 0; // $current if ($break=="line") { $y0 += $spacing + $height; // y0 $this->multicol[0][1] = $y0; $this->SetAutoPageBreak(true, $this->hPt - ( $y0 + $height)); $this->SetY($y0); //$this->Write(10,"This sux0rs."); return false; } else { // page break. return true; } } } else { // no multi-column tag. do the normal thing. return true; } } function _parsePDML($pdml) { $a = preg_split('/<([^<]*)\/?>/U',$pdml,-1,PREG_SPLIT_DELIM_CAPTURE); foreach ($a as $i=>$e) { if ($this->parserBreak) { if ($i%2==0) { $this->ProcessText($e); continue; } if (strcasecmp($e,$this->parserBreak)) { $this->ProcessText('<'.$e.'>'); continue; } } if ($i%2==0) { // text $this->ProcessText(pdml_entity_decode(preg_replace( array( '/\s+/', '/&pagenumber;/', '/&title;/', '/&author;/', '/&subject;/', '/&creator;/' ), array( ' ', $this->PageNo(), $this->title, $this->author, $this->subject, $this->creator ) ,$e))); } else { // tag if ($e{0}=='/') { $this->CloseTag(strtoupper(substr($e,1))); } else { $a2 = explode(' ',$e,2); $tag = strtoupper(array_shift($a2)); $e = substr($e, strlen($tag)+1); // stolen from http://www.cs.sfu.ca/~cameron/REX.html // bugified into uselessness. It's the intent that counts. right? $NameStrt = "[A-Za-z_:]|[^\\x00-\\x7F]"; $NameChar = "[A-Za-z0-9_:.-]|[^\\x00-\\x7F]"; $Name = "(?:$NameStrt)(?:$NameChar)*"; $S = "[ \\n\\t\\r]+"; $AttValSE = "\"[^\"]*\"|'[^']*'|[^ \\n\\t\\r]+"; $ElemTagCE = "($Name)(?:$S)?=(?:$S)?($AttValSE)"; $attr = array(); preg_match_all("/$ElemTagCE/", $e, $matches, PREG_SET_ORDER); for ($i=0;$iOpenTag($tag,$attr); } } } } function ProcessText($text) { switch ($this->parserState) { case 0: case 1: case 2: // ignore text/whitespace in there. break; case 3: $this->SetTitle($text); break; case 4: $this->SetSubject($text); break; case 5: $this->SetAuthor($text); break; case 6: $this->SetKeywords($text); break; case 51: $this->cell_text .= $text; break; case 10: $this->script .= $text; break; case 63: $this->header .= $text; break; case 64: $this->footer .= $text; break; default: // ignore pure whitespace if (preg_match("/^[ \\n\\t\\r]*$/",$text)) break; // auto-create a page if needed. if (!$this->inPage) { $this->inPage = true; $this->AddPage(); } // write stuff. // do we have a link to use? if (sizeof($this->href)>0) { if ($this->href_style[0]) { $this->SetTextColor(0,0,255); $this->_setStyle('U',true, true); } $this->Write($this->font_size[0],$text,$this->href[0]); if ($this->href_style[0]) { $this->_setStyle('U', $this->U>0, true); $this->_setFontColor($this->font_color[0]); } } else { $this->Write($this->font_size[0],$text); } } } function OpenTag($tag, $attr) { switch ($tag) { case "PDML": $this->_enforceState(0,1); break; case "HEAD": $this->_enforceState(1,2); break; case "TITLE": $this->_enforceState(2,3); break; case "SUBJECT": $this->_enforceState(2,4); break; case "AUTHOR": $this->_enforceState(2,5); break; case "KEYWORDS": $this->_enforceState(2,6); break; case "SCRIPT": $this->_enforceState(2,10); $this->script=''; $this->parserBreak="/script"; break; case "BODY": $this->_enforceState(1,50); break; case "PAGE": $this->_enforceState(50,50); $o = "P"; if (isset($attr["ORIENTATION"])) { if (strcasecmp($attr["ORIENTATION"],"LANDSCAPE")==0) { $o = "L"; } } $this->inPage=true; $this->AddPage($o); break; case "BR": // no enforcement. if ($this->parserState==51) { $this->cell_text.="\n"; break; } if (isset($attr["HEIGHT"])) { $h=$this->_getUnit($attr["HEIGHT"], $this->font_size[0]); $this->Ln($h); } else { $this->Ln($this->font_size[0]); } break; case "A": $this->_enforceState(50,50); // name= if (isset($attr["NAME"])) { // local anchor $name = $attr["NAME"]; if (!isset($this->anchors[$name])) { $this->anchors[$name] = $this->AddLink(); } $this->SetLink($this->anchors[$name], -1); } // href= if (isset($attr["HREF"])) { $href = $attr["HREF"]; if ($href[0]=='#') { // local anchor $href = substr($href,1); if (!isset($this->anchors[$href])) { $this->anchors[$href] = $this->AddLink(); } array_unshift ($this->href, $this->anchors[$href]); } else { array_unshift ($this->href, $href); } // we should set style to underlined blue. XXX array_unshift ($this->href_style, isset($attr["HIDDEN"])?0:1); } break; case "B": case "I": case "U": $this->_enforceState(50,50); $this->_setStyle($tag, true); break; case "FONT": $this->_enforceState(50,50); $mask = 0; if (isset($attr["COLOR"])) { // hex-encoded color. no space for long color name list. $color = $attr["COLOR"]; if ($color[0]=="#") { $color = substr($color,1); } array_unshift($this->font_color, $color); $this->_setFontColor($color); $mask |= 1; } if (isset($attr["SIZE"])) { $size = $this->_getUnit($attr["SIZE"], $this->font_size[0]); array_unshift($this->font_size, $size); $this->SetFontSize($size); $mask |= 2; } if (isset($attr["FACE"])) { $face = $attr["FACE"]; array_unshift($this->font_face, $face); $this->_setFontFace($face); $mask |= 4; } array_unshift($this->font_mask, $mask); break; case "IMG": $this->_enforceState(50,50); if (!isset($attr["SRC"])) break; $src = $attr["SRC"]; $x = $this->GetX(); if (isset($attr["LEFT"])) { $x = $this->_getUnit($attr["LEFT"], $this->wPt); } $y = $this->GetY(); if (isset($attr["TOP"])) { $y = $this->_getUnit($attr["TOP"], $this->hPt); } $width = 0; if (isset($attr["WIDTH"])) { $width = $this->_getUnit($attr["WIDTH"], $this->wPt); } $height = 0; if (isset($attr["HEIGHT"])) { $height = $this->_getUnit($attr["HEIGHT"], $this->hPt); } // try to resolve src a bit if necessary. if (!file_exists($src)) { $src1 = getenv("DOCUMENT_ROOT")."/".$src; $src2 = dirname(getenv("SCRIPT_FILENAME"))."/".$src; if (file_exists($src1)) { $src = $src1; } elseif (file_exists($src2)) { $src = $src2; } } if (sizeof($this->href)>0) { $this->Image($src, $x, $y, $width, $height, '', $this->href[0]); } else { $this->Image($src, $x, $y, $width, $height); } break; case "LINE": $this->_enforceState(50,50); $x1 = $this->GetX(); $y1 = $this->GetY(); if (isset($attr["FROM"])) { list($x1,$y1) = explode(',',$attr["FROM"]); $x1 = $this->_getUnit($x1, $this->wPt); $y1 = $this->_getUnit($y1, $this->hPt); } $x2 = $this->wPt; $y2 = $y1; if (isset($attr["TO"])) { list($x2,$y2) = explode(',',$attr["TO"]); $x2 = $this->_getUnit($x2, $this->wPt); $y2 = $this->_getUnit($y2, $this->hPt); } $color = "000000"; if (isset($attr["COLOR"])) { $color = $attr["COLOR"]; if ($color[0]=="#") { $color = substr($color,1); } } $lwidth = $this->_getUnit("0.2mm"); if (isset($attr["WIDTH"])) { $lwidth = $this->_getUnit($attr["WIDTH"], $lwidth); } $this->_setLineColor($color); $this->SetLineWidth($lwidth); $this->Line($x1,$y1,$x2,$y2); break; case "RECT": $this->_enforceState(50,50); $x1 = $this->GetX(); $y1 = $this->GetY(); if (isset($attr["FROM"])) { list($x1,$y1) = explode(',',$attr["FROM"]); $x1 = $this->_getUnit($x1, $this->wPt); $y1 = $this->_getUnit($y1, $this->hPt); } if (isset($attr["LEFT"])) { $x1 = $this->_getUnit($attr["LEFT"], $this->wPt); } if (isset($attr["TOP"])) { $y1 = $this->_getUnit($attr["TOP"], $this->hPt); } $width= 144; $height= 36; if (isset($attr["TO"])) { list($x2,$y2) = explode(',',$attr["TO"]); $x2 = $this->_getUnit($x2, $this->wPt); $y2 = $this->_getUnit($y2, $this->hPt); $width = $x2-$x1+1; $height = $y2-$y1+1; } if (isset($attr["WIDTH"])) { $width = $this->_getUnit($attr["WIDTH"], $this->wPt); } if (isset($attr["HEIGHT"])) { $height = $this->_getUnit($attr["HEIGHT"], $this->hPt); } $style=""; $color = "000000"; if (isset($attr["COLOR"])) { $color = $attr["COLOR"]; if ($color[0]=="#") { $color = substr($color,1); } $style.="D"; } $fill = "000000"; if (isset($attr["FILLCOLOR"])) { $fill = $attr["FILLCOLOR"]; if ($fill[0]=="#") { $fill = substr($fill,1); } $style.="F"; } $border = $this->_getUnit("0.2mm"); if (isset($attr["BORDER"])) { $border = $this->_getUnit($attr["BORDER"], $border); } $this->_setLineColor($color); $this->SetLineWidth($border); $this->_setRectColor($fill); $this->Rect($x1,$y1,$width,$height,$style); break; case "CIRCLE": case "ELLIPSE": $this->_enforceState(50,50); $x1 = $this->GetX(); $y1 = $this->GetY(); if (isset($attr["FROM"])) { list($x1,$y1) = explode(',',$attr["FROM"]); $x1 = $this->_getUnit($x1, $this->wPt); $y1 = $this->_getUnit($y1, $this->hPt); } $radius = $this->_getAttrUnit($this->font_size[0], $attr, "RADIUS", $this->font_size[0]); $xradius = $this->_getAttrUnit($radius, $attr, "XRADIUS", $this->font_size[0]); $yradius = $this->_getAttrUnit($radius, $attr, "YRADIUS", $this->font_size[0]); $style=""; $color = "000000"; if (isset($attr["COLOR"])) { $color = $attr["COLOR"]; if ($color[0]=="#") { $color = substr($color,1); } $style.="D"; } $fill = "000000"; if (isset($attr["FILLCOLOR"])) { $fill = $attr["FILLCOLOR"]; if ($fill[0]=="#") { $fill = substr($fill,1); } $style.="F"; } $border = $this->_getUnit("0.2mm"); if (isset($attr["BORDER"])) { $border = $this->_getUnit($attr["BORDER"], $border); } $this->_setLineColor($color); $this->SetLineWidth($border); $this->_setRectColor($fill); $this->Ellipse($x1, $y1, $xradius, $yradius, $style); break; case "DIV": $this->_enforceState(50,50); $save_x = $this->GetX(); $x = $this->_getAttrUnit($save_x, $attr, "LEFT", $this->wPt); $save_y = $this->GetY(); $y = $this->_getAttrUnit($save_y, $attr, "TOP", $this->hPt); $width = $this->_getAttrUnit($this->wPt-$x, $attr, "WIDTH", $this->wPt); $height = $this->_getAttrUnit($this->hPt-$y, $attr, "HEIGHT", $this->hPt); if ($x == $save_x) { $save_x+=$width; } array_unshift($this->left_margin, $x); array_unshift($this->right_margin, $this->wPt-$width-$x); array_unshift($this->div_x, $save_x); array_unshift($this->div_y, $save_y); // draw a rect, just to debug. XXX $style=""; $color = "000000"; if (isset($attr["COLOR"])) { $color = $attr["COLOR"]; if ($color[0]=="#") { $color = substr($color,1); } $style.="D"; } $fill = "000000"; if (isset($attr["FILLCOLOR"])) { $fill = $attr["FILLCOLOR"]; if ($fill[0]=="#") { $fill = substr($fill,1); } $style.="F"; } $border = $this->_getUnit("0.2mm"); if (isset($attr["BORDER"])) { $border = $this->_getUnit($attr["BORDER"], $border); } $this->_setLineColor($color); $this->SetLineWidth($border); $this->_setRectColor($fill); if ($style) { $this->Rect($x,$y,$width,$height,$style); } $this->SetLeftMargin($this->left_margin[0]); $this->SetRightMargin($this->right_margin[0]); $this->SetXY($x,$y); break; case "MULTICELL": case "CELL": $this->_enforceState(50,51); $save_x = $this->GetX(); $x = $this->_getAttrUnit($save_x, $attr, "LEFT", $this->wPt); $save_y = $this->GetY(); $y = $this->_getAttrUnit($save_y, $attr, "TOP", $this->hPt); $width = $this->_getAttrUnit($this->wPt-$x, $attr, "WIDTH", $this->wPt); // used by multicell only $inter = $this->_getAttrUnit($this->font_size[0], $attr, "INTER", $this->font_size[0]); // used by cell only. $height = $this->_getAttrUnit($this->font_size[0], $attr, "HEIGHT", $this->font_size[0]); $next = 0; if (isset($attr["NEXT"])) { $n = strtolower($attr["NEXT"]); switch ($n) { case "right": $next =0; break; case "bottom": case "down": $next=2; break; case "break": $next = 1; break; } } $style=""; $color = "000000"; if (isset($attr["COLOR"])) { $color = $attr["COLOR"]; if ($color[0]=="#") { $color = substr($color,1); } $style.="D"; } $fillflag = 0; $fill = "000000"; if (isset($attr["FILLCOLOR"])) { $fill = $attr["FILLCOLOR"]; if ($fill[0]=="#") { $fill = substr($fill,1); } $fillflag=1; } $borderflag=0; $border = $this->_getUnit("0.2mm"); if (isset($attr["BORDER"])) { $border = $this->_getUnit($attr["BORDER"], $border); $borderflag=1; } $align = ($tag=="CELL")?"L":"J"; if (isset($attr["ALIGN"])) { $al = strtolower($attr["ALIGN"]); switch ($al){ case "left": $align="L"; break; case "center": $align="C"; break; case "right": $align="R"; break; case "justify": $align="J"; break; } } $this->_setLineColor($color); $this->SetLineWidth($border); $this->_setRectColor($fill); $this->SetXY($x,$y); $this->cell_info = array($width, $inter, $height, $borderflag, $align, $fillflag, $next); $this->cell_text = ''; break; case "ROTATE": $angle=45; if (isset($attr["ANGLE"])) { $angle = $attr["ANGLE"]; } $x=-1; $y=-1; if (isset($attr["CENTER"])) { list($x,$y) = explode(',',$attr["CENTER"]); $x = $this->_getUnit($x, $this->wPt); $y = $this->_getUnit($y, $this->hPt); } $this->rotate($angle, $x, $y); break; case "BOOKMARK": if (!isset($attr["TITLE"])) break; $title = $attr["TITLE"]; $level = 0; if (isset($attr["LEVEL"])) { $level = $attr["LEVEL"]; } $top = -1; if (isset($attr["TOP"])) { $top = $this->_getUnit($attr["TOP"], $this->hPt); } $this->Bookmark($title, $level, $top); break; case "HEADER": $this->_enforceState(50,63); $this->header=''; $this->parserBreak='/header'; break; case "FOOTER": $this->_enforceState(50,64); $this->footer=''; $this->parserBreak='/footer'; break; case "COLUMN": $this->_enforceState(50,50); $save_x = $this->GetX(); $x = $this->_getAttrUnit($save_x, $attr, "LEFT", $this->wPt); $save_y = $this->GetY(); $y = $this->_getAttrUnit($save_y, $attr, "TOP", $this->hPt); $count = 2; if (isset($attr["COUNT"])) { $count = (int)$attr["COUNT"]; } $width = $this->_getAttrUnit(($this->wPt-$x)/$count, $attr, "WIDTH", $this->wPt); $height = $this->_getAttrUnit($this->hPt-$y, $attr, "HEIGHT", $this->hPt); $spacing = $this->_getAttrUnit($this->font_size[0], $attr, "SPACING", $this->font_size[0]); $break = "page"; if (isset($attr["BREAK"]) and (strtolower($attr["BREAK"])=="line")) { $break = "line"; } // store stuff for acceptPageBreak to make sense of, and stuff we're saving array_unshift($this->multicol, array($x,$y,$width,$height,$spacing, $break, $count, 0, )); array_unshift($this->left_margin, $x); array_unshift($this->bottom_margin, $this->hPt-($y+$height)); // set margins to make things work. $this->SetLeftMargin($this->left_margin[0]); $this->SetAutoPageBreak(true, $this->bottom_margin[0]); break; } } function CloseTag($tag) { switch ($tag) { case "PDML": $this->_enforceState(1,0); //$this->final = $this->Output("","S"); break; case "HEAD": $this->_enforceState(2,1); break; case "TITLE": $this->_enforceState(3,2); break; case "SUBJECT": $this->_enforceState(4,2); break; case "AUTHOR": $this->_enforceState(5,2); break; case "KEYWORDS": $this->_enforceState(6,2); break; case "SCRIPT": $this->_enforceState(10,2); $this->IncludeJS($this->script); $this->parserBreak=''; break; case "BODY": $this->Close(); $this->_enforceState(50,1); break; case "A": array_shift ($this->href); array_shift ($this->href_style); // we should remove underline + blue. break; case "B": case "I": case "U": $this->_setStyle($tag, false); break; case "FONT": if (sizeof($this->font_mask)>0) { $mask = array_shift($this->font_mask); } if (($mask&1)==1) { array_shift($this->font_color); $this->_setFontColor($this->font_color[0]); } if (($mask&2)==2) { array_shift($this->font_size); $this->SetFontSize($this->font_size[0]); } if (($mask&4)==4) { array_shift($this->font_face); $this->_setFontFace($this->font_face[0]); } break; case "DIV": if (sizeof($this->div_x)<1) break; array_shift($this->left_margin); array_shift($this->right_margin); $this->SetLeftMargin($this->left_margin[0]); $this->SetRightMargin($this->right_margin[0]); $this->SetXY($this->div_x[0],$this->div_y[0]); array_shift($this->div_x); array_shift($this->div_y); break; case "MULTICELL": $this->_enforceState(51,50); // auto-create a page if needed. if (!$this->inPage) { $this->inPage = true; $this->AddPage(); } $this->MultiCell( $this->cell_info[0], $this->cell_info[1], $this->cell_text, $this->cell_info[3], $this->cell_info[4], $this->cell_info[5]); break; case "CELL": $this->_enforceState(51,50); // auto-create a page if needed. if (!$this->inPage) { $this->inPage = true; $this->AddPage(); } // redo the link logic here. blah. if (sizeof($this->href)>0) { if ($this->href_style[0]) { $this->SetTextColor(0,0,255); $this->_setStyle('U',true, true); } $this->Cell( $this->cell_info[0], $this->cell_info[2], $this->cell_text, $this->cell_info[3], $this->cell_info[6], $this->cell_info[4], $this->cell_info[5], $this->href[0]); if ($this->href_style[0]) { $this->_setStyle('U', $this->U>0, true); $this->_setFontColor($this->font_color[0]); } } else { $this->Cell( $this->cell_info[0], $this->cell_info[2], $this->cell_text, $this->cell_info[3], $this->cell_info[6], $this->cell_info[4], $this->cell_info[5]); } break; case "ROTATE": $this->rotate(0); break; case "HEADER": $this->_enforceState(63,50); $this->parserBreak=''; break; case "FOOTER": $this->_enforceState(64,50); $this->parserBreak=''; break; case "COLUMN": $this->_enforceState(50,50); array_shift($this->multicol); array_shift($this->left_margin); array_shift($this->bottom_margin); $this->SetLeftMargin($this->left_margin[0]); $this->SetAutoPageBreak(true, $this->bottom_margin[0]); break; } } function _enforceState($from, $to) { if ($this->parserState!=$from) { error_log("unexpected tag (from $from to $to, but state=".$this->parserState.")"); //$this->Write("[unexpected tag (from $from to $to)]"); } $this->parserState=$to; } // default is pt. works good for fonts, so yeah. function _getUnit($str, $max=100) { $str=rtrim($str); $v=(float)$str; if (substr($str,-1)=='%') { return $max * $v / 100; } $u=substr($str,-2); switch ($u) { default: case "pt": $m=1; break; case "mm": $m=72/25.4; break; case "cm": $m=72/2.54; break; case "in": $m=72; break; } return $v * $m; } function _getAttrUnit($default, $attr, $name, $ref) { if (isset($attr[$name])) { return $this->_getUnit($attr[$name], $ref); } else { return $default; } } function _setStyle($tag, $enable, $forget=0) { $this->$tag+=($enable ? 1: -1); $style=''; foreach(array('B','I','U') as $s) { if ($this->$s>0) { $style.=$s; } } $this->SetFont('',$style); if ($forget) { $this->$tag-=($enable ? 1: -1); } } function _setFontFace($face) { $style=''; foreach(array('B','I','U') as $s) { if ($this->$s>0) { $style.=$s; } } $this->SetFont($face,$style); } function _setFontColor($hex) { $this->SetTextColor( hexdec(substr($hex,0,2)), hexdec(substr($hex,2,2)), hexdec(substr($hex,4,2))); } function _setLineColor($hex) { $this->SetDrawColor( hexdec(substr($hex,0,2)), hexdec(substr($hex,2,2)), hexdec(substr($hex,4,2))); } function _setRectColor($hex) { $this->SetFillColor( hexdec(substr($hex,0,2)), hexdec(substr($hex,2,2)), hexdec(substr($hex,4,2))); } } function ob_pdml($buffer) { $pdml = new PDML('P','pt','A4'); // P and A4 should be customizable. XXX $pdml->compress=0; $pdml->ParsePDML($buffer); $s = $pdml->Output("","S"); Header('Content-Type: application/pdf'); Header('Content-Length: '.strlen($s)); Header('Content-disposition: inline; filename=doc.pdf'); return $s; } function pdml_entity_decode( $given_html, $quote_style = ENT_QUOTES ) { $trans_table = array_flip(array_merge( get_html_translation_table( HTML_SPECIALCHARS, $quote_style ), get_html_translation_table( HTML_ENTITIES, $quote_style) )); $trans_table['''] = "'"; return ( strtr( $given_html, $trans_table ) ); } //ob_start("ob_pdml"); ?>