Project import generated by Copybara.

GitOrigin-RevId: 63746295f1a5ab5a619056791995793d65529e62
diff --git a/src/lib/fpdf-easytable/exfpdf.php b/src/lib/fpdf-easytable/exfpdf.php
new file mode 100755
index 0000000..d61a247
--- /dev/null
+++ b/src/lib/fpdf-easytable/exfpdf.php
@@ -0,0 +1,401 @@
+<?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'];
+      }
+   }
+   
+}
+?>