blob: d61a24758b5f420174df192fbed864243a2950a3 [file] [log] [blame]
<?php
/*********************************************************************
* exFPDF extend FPDF v1.81 *
* *
* Version: 2.2 *
* Date: 12-10-2017 *
* Author: Dan Machado *
* Require FPDF v1.81, formatedstring v1.0 *
**********************************************************************/
include 'formatedstring.php';
class exFPDF extends FPDF{
public function PageBreak(){
return $this->PageBreakTrigger;
}
public function current_font($c){
if($c=='family'){
return $this->FontFamily;
}
elseif($c=='style'){
return $this->FontStyle;
}
elseif($c=='size'){
return $this->FontSizePt;
}
}
public function get_color($c){
if($c=='fill'){
return $this->FillColor;
}
elseif($c=='text'){
return $this->TextColor;
}
}
public function get_page_width(){
return $this->w;
}
public function get_margin($c){
if($c=='l'){
return $this->lMargin;
}
elseif($c=='r'){
return $this->rMargin;
}
elseif($c=='t'){
return $this->tMargin;
}
}
public function get_linewidth(){
return $this->LineWidth;
}
public function get_orientation(){
return $this->CurOrientation;
}
public function get_page_size()
{
return $this->CurPageSize;
}
public function get_rotation()
{
return $this->CurRotation;
}
public function get_scale_factor()
{
return $this->k;
}
static private $hex=array('0'=>0,'1'=>1,'2'=>2,'3'=>3,'4'=>4,'5'=>5,'6'=>6,'7'=>7,'8'=>8,'9'=>9,
'A'=>10,'B'=>11,'C'=>12,'D'=>13,'E'=>14,'F'=>15);
public function is_rgb($str){
$a=true;
$tmp=explode(',', trim($str, ','));
foreach($tmp as $color){
if(!is_numeric($color) || $color<0 || $color>255){
$a=false;
break;
}
}
return $a;
}
public function is_hex($str){
$a=true;
$str=strtoupper($str);
$n=strlen($str);
if(($n==7 || $n==4) && $str[0]=='#'){
for($i=1; $i<$n; $i++){
if(!isset(self::$hex[$str[$i]])){
$a=false;
break;
}
}
}
else{
$a=false;
}
return $a;
}
public function hextodec($str){
$result=array();
$str=strtoupper(substr($str,1));
$n=strlen($str);
for($i=0; $i<3; $i++){
if($n==6){
$result[$i]=self::$hex[$str[2*$i]]*16+self::$hex[$str[2*$i+1]];
}
else{
$result[$i]=self::$hex[$str[$i]]*16+self::$hex[$str[$i]];
}
}
return $result;
}
static private $options=array('F'=>'', 'T'=>'', 'D'=>'');
public function resetColor($str, $p='F'){
if(isset(self::$options[$p]) && self::$options[$p]!=$str){
self::$options[$p]=$str;
$array=array();
if($this->is_hex($str)){
$array=$this->hextodec($str);
}
elseif($this->is_rgb($str)){
$array=explode(',', trim($str, ','));
for($i=0; $i<3; $i++){
if(!isset($array[$i])){
$array[$i]=0;
}
}
}
else{
$array=array(null, null, null);
$i=0;
$tmp=explode(' ', $str);
foreach($tmp as $c){
if(is_numeric($c)){
$array[$i]=$c*256;
$i++;
}
}
}
if($p=='T'){
$this->SetTextColor($array[0],$array[1],$array[2]);
}
elseif($p=='D'){
$this->SetDrawColor($array[0],$array[1], $array[2]);
}
elseif($p=='F'){
$this->SetFillColor($array[0],$array[1],$array[2]);
}
}
}
static private $font_def='';
public function resetFont($font_family, $font_style, $font_size){
if(self::$font_def!=$font_family .'-' . $font_style . '-' .$font_size){
self::$font_def=$font_family .'-' . $font_style . '-' .$font_size;
$this->SetFont($font_family, $font_style, $font_size);
}
}
public function resetStaticData(){
self::$font_def='';
self::$options=array('F'=>'', 'T'=>'', 'D'=>'');
}
/***********************************************************************
*
* Based on FPDF method SetFont
*
************************************************************************/
private function &FontData($family, $style, $size){
if($family=='')
$family = $this->FontFamily;
else
$family = strtolower($family);
$style = strtoupper($style);
if(strpos($style,'U')!==false){
$this->underline = true;
$style = str_replace('U','',$style);
}
if($style=='IB')
$style = 'BI';
$fontkey = $family.$style;
if(!isset($this->fonts[$fontkey])){
if($family=='arial')
$family = 'helvetica';
if(in_array($family,$this->CoreFonts)){
if($family=='symbol' || $family=='zapfdingbats')
$style = '';
$fontkey = $family.$style;
if(!isset($this->fonts[$fontkey]))
$this->AddFont($family,$style);
}
else
$this->Error('Undefined font: '.$family.' '.$style);
}
$result['FontSize'] = $size/$this->k;
$result['CurrentFont']=&$this->fonts[$fontkey];
return $result;
}
private function setLines(&$fstring, $p, $q){
$parced_str=& $fstring->parced_str;
$lines=& $fstring->lines;
$linesmap=& $fstring->linesmap;
$cfty=$fstring->get_current_style($p);
$ffs=$cfty['font-family'] . $cfty['style'];
if(!isset($fstring->used_fonts[$ffs])){
$fstring->used_fonts[$ffs]=& $this->FontData($cfty['font-family'], $cfty['style'], $cfty['font-size']);
}
$cw=& $fstring->used_fonts[$ffs]['CurrentFont']['cw'];
$wmax = $fstring->width*1000*$this->k;
$j=count($lines)-1;
$k=strlen($lines[$j]);
if(!isset($linesmap[$j][0])) {
$linesmap[$j]=array($p,$p, 0);
}
$sl=$cw[' ']*$cfty['font-size'];
$x=$a=$linesmap[$j][2];
if($k>0){
$x+=$sl;
$lines[$j].=' ';
$linesmap[$j][2]+=$sl;
}
$u=$p;
$t='';
$l=$p+$q;
$ftmp='';
for($i=$p; $i<$l; $i++){
if($ftmp!=$ffs){
$cfty=$fstring->get_current_style($i);
$ffs=$cfty['font-family'] . $cfty['style'];
if(!isset($fstring->used_fonts[$ffs])){
$fstring->used_fonts[$ffs]=& $this->FontData($cfty['font-family'], $cfty['style'], $cfty['font-size']);
}
$cw=& $fstring->used_fonts[$ffs]['CurrentFont']['cw'];
$ftmp=$ffs;
}
$x+=$cw[$parced_str[$i]]*$cfty['font-size'];
if($x>$wmax){
if($a>0){
$t=substr($parced_str,$p, $i-$p);
$lines[$j]=substr($lines[$j],0,$k);
$linesmap[$j][1]=$p-1;
$linesmap[$j][2]=$a;
$x-=($a+$sl);
$a=0;
$u=$p;
}
else{
$x=$cw[$parced_str[$i]]*$cfty['font-size'];
$t='';
$u=$i;
}
$j++;
$lines[$j]=$t;
$linesmap[$j]=array();
$linesmap[$j][0]=$u;
$linesmap[$j][2]=0;
}
$lines[$j].=$parced_str[$i];
$linesmap[$j][1]=$i;
$linesmap[$j][2]=$x;
}
return;
}
public function &extMultiCell($font_family, $font_style, $font_size, $font_color, $w, $txt){
$result=array();
if($w==0){
return $result;
}
$current_font=array('font-family'=>$font_family, 'style'=>$font_style, 'font-size'=>$font_size, 'font-color'=>$font_color);
$fstring=new formatedString($txt, $w, $current_font);
$word='';
$p=0;
$i=0;
$n=strlen($fstring->parced_str);
while($i<$n){
$word.=$fstring->parced_str[$i];
if($fstring->parced_str[$i]=="\n" || $fstring->parced_str[$i]==' ' || $i==$n-1){
$word=trim($word);
$this->setLines($fstring, $p, strlen($word));
$p=$i+1;
$word='';
if($fstring->parced_str[$i]=="\n" && $i<$n-1){
$z=0;
$j=count($fstring->lines);
$fstring->lines[$j]='';
$fstring->linesmap[$j]=array();
}
}
$i++;
}
if($n==0){
return $result;
}
$n=count($fstring->lines);
for($i=0; $i<$n; $i++){
$result[$i]=$fstring->break_by_style($i);
}
return $result;
}
private function GetMixStringWidth($line){
$w = 0;
foreach($line['chunks'] as $i=>$chunk){
$t=0;
$cf=& $this->FontData($line['style'][$i]['font-family'], $line['style'][$i]['style'], $line['style'][$i]['font-size']);
$cw=& $cf['CurrentFont']['cw'];
$s=implode('', explode(' ',$chunk));
$l = strlen($s);
for($j=0;$j<$l;$j++){
$t+=$cw[$s[$j]];
}
$w+=$t*$line['style'][$i]['font-size'];
}
return $w;
}
public function CellBlock($w, $lh, &$lines, $align='J'){
if($w==0){
return;
}
$ctmp='';
$ftmp='';
foreach($lines as $i=>$line){
$k = $this->k;
if($this->y+$lh*$line['height']>$this->PageBreakTrigger){
break;
}
$dx=0;
$dw=0;
if($line['width']!=0){
if($align=='R'){
$dx = $w-$line['width']/($this->k*1000);
}
elseif($align=='C'){
$dx = ($w-$line['width']/($this->k*1000))/2;
}
if($align=='J'){
$tmp=explode(' ', implode('',$line['chunks']));
$ns=count($tmp);
if($ns>1){
$sx=implode('',$tmp);
$delta=$this->GetMixStringWidth($line)/($this->k*1000);
$dw=($w-$delta)*(1/($ns-1));
}
}
}
$xx=$this->x+$dx;
foreach($line['chunks'] as $tj=>$txt){
$this->resetFont($line['style'][$tj]['font-family'], $line['style'][$tj]['style'], $line['style'][$tj]['font-size']);
$this->resetColor($line['style'][$tj]['font-color'], 'T');
$y=$this->y+0.5*$lh*$line['height'] +0.3*$line['height']/$this->k;
if($dw){
$tmp=explode(' ', $txt);
foreach($tmp as $e=>$tt){
if($e>0){
$xx+=$dw;
if($tt==''){
continue;
}
}
$this->Text($xx, $y, $tt);
if($line['style'][$tj]['href']){
$yr=$this->y+0.5*($lh*$line['height']-$line['height']/$this->k);
$this->Link($xx, $yr, $this->GetStringWidth($txt),$line['height']/$this->k, $line['style'][$tj]['href']);
}
$xx+=$this->GetStringWidth($tt);
}
}
else{
$this->Text($xx, $y, $txt);
if($line['style'][$tj]['href']){
$yr=$this->y+0.5*($lh*$line['height']-$line['height']/$this->k);
$this->Link($xx, $yr, $this->GetStringWidth($txt),$line['height']/$this->k, $line['style'][$tj]['href']);
}
$xx+=$this->GetStringWidth($txt);
}
}
unset($lines[$i]);
$this->y += $lh*$line['height'];
}
}
}
?>