Passed
Push — master ( 63d1f8...7c50e7 )
by Joe Nilson
02:33
created

formatedString::style_merge()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 5
c 1
b 0
f 0
nc 3
nop 2
dl 0
loc 8
rs 10
1
<?php
2
 /**********************************************************************
3
 * formateString                                                       *
4
 *                                                                     *
5
 * Version: 1.2                                                        *
6
 * Date:    04-10-2017                                                 *
7
 * Author:  Dan Machado                                                *
8
 * Use within exfpdf class                                             *
9
 **********************************************************************/
10
 class formatedString
11
 {
12
    public $parced_str;
13
    public $style_map;
14
    public $positions;
15
    private $np;
16
    public $iterator;
17
    public $width;
18
    public $lines;
19
    public $linesmap;
20
    public $used_fonts;
21
22
    private function get_style($str){
23
       $style=array('font-family'=>false, 'font-weight'=>false, 'font-style'=>false,
24
       'font-size'=>false, 'font-color'=>false, 'href'=>'');
25
       $tmp=explode(';', trim($str, '",\', '));
26
       foreach($tmp as $x){
27
          if($x && strpos($x,':')>0){
28
             $r=explode(':',$x);
29
             $r[0]=trim($r[0]);
30
             $r[1]=trim($r[1]);
31
             if(isset($style[$r[0]]) || $r[0]=='style'){
32
                if($r[0]=='style' || $r[0]=='font-style'){
33
                   $r[1]=strtoupper($r[1]);
34
                   if(strpos($r[1], 'B')!==false){
35
                      $style['font-weight']='B';
36
                  }
37
                  if(strpos($r[1], 'I')!==false){
38
                     $style['font-style']='I';
39
                  }
40
                  if(strpos($r[1], 'U')!==false){
41
                     $style['font-style'].='U';
42
                  }
43
               }
44
               elseif($r[1]){
45
                  if($r[0]=='href'){
46
                     $style[$r[0]]=implode(':', array_slice($r,1));
47
                  }
48
                  else{
49
                     $style[$r[0]]=$r[1];
50
                  }
51
               }
52
            }
53
         }
54
      }
55
      return $style;
56
   }
57
    
58
59
   private function style_merge($style1, $style2){
60
      $result=$style1;
61
      foreach($style2 as $k=>$v){
62
         if($v){
63
            $result[$k]=$v;
64
         }
65
      }
66
      return $result;
67
   }
68
69
   private function style_parcer($text, &$font_data){
70
      $str=trim(strtr($text, array("\r"=>'', "\t"=>'')));
71
      $rep=array('[bB]{1}'=>'B', '[iI]{1}'=>'I', '[iI]{1}[ ]*[bB]{1}'=>'BI', '[bB]{1}[ ]*[iI]{1}'=>'BI' );
72
      foreach($rep as $a=>$v){
73
         $str=preg_replace('/<[ ]*'.$a.'[ ]*>/', "<$v>", $str);
74
         $str=preg_replace('/<[ ]*\/+[ ]*'.$a.'[ ]*>/', "</$v>", $str);
75
      }
76
      $str=preg_replace('/<BI>/', '<s "font-weight:B;font-style:I">', $str);
77
      $str=preg_replace('/<\/BI>/', "</s>", $str);
78
      $str=preg_replace('/<B>/', '<s "font-weight:B;">', $str);
79
      $str=preg_replace('/<\/B>/', "</s>", $str);
80
      $str=preg_replace('/<I>/', '<s "font-style:I;">', $str);
81
      $str=preg_replace('/<\/I>/', "</s>", $str);
82
      $open=array();
83
      $total=array();
84
      $lt="<s";
85
      $rt="</s>";
86
      $j=strpos($str, $lt, 0);
87
      while($j!==false){
88
            if($j>0 && ord($str[$j-1])==92){
89
            $j=strpos($str, $lt, $j+1);
90
            continue;
91
         }
92
         $k=strpos($str, '>',$j+1);
93
         $open[$j]=substr($str, $j+2, $k-($j+2));
94
         $total[]=$j;
95
         $j=strpos($str, $lt, $j+1);
96
      }
97
      $j=strpos($str, $rt, 0);
98
      while($j!==false){
99
         $total[]=$j;
100
         $j=strpos($str, $rt, $j+1);
101
      }
102
      sort($total);
103
      
104
      $cs='';
105
      foreach($font_data as $k=>$v){
106
         $cs.=$k . ':'. $v . '; ';
107
      }
108
      $cs=$this->get_style($cs);
109
      $tmp=array($cs);
110
      $blocks=array();
111
      $blockstyle=array();
112
      $n=count($total);
113
      $k=0;
114
      for($i=0; $i<$n; $i++){
115
         $blocks[]=substr($str, $k, $total[$i]-$k);
116
         $blockstyle[]=$cs;
117
         if(isset($open[$total[$i]])){
118
            $cs=$this->style_merge($cs, $this->get_style($open[$total[$i]]));
119
            array_push($tmp, $cs);
120
            $k=strpos($str, '>',$total[$i]+1)+1;
121
         }
122
         else{
123
            $k=$total[$i]+4;
124
            array_pop($tmp);
125
            $l=count($tmp)-1;
126
            $cs=$tmp[$l];
127
         }
128
      }
129
      if($k<strlen($str)){
130
         $blocks[]=substr($str, $k);
131
         $blockstyle[]=$cs;
132
      }
133
      $n=count($blocks);
134
      for($i=0; $i<$n; $i++){
135
         $this->parced_str.=strtr($blocks[$i], array('\<s'=>'<s'));
136
         if(strlen($blocks[$i])>0){
137
            $blockstyle[$i]['style']=$blockstyle[$i]['font-weight'] . $blockstyle[$i]['font-style'];
138
            unset($blockstyle[$i]['font-weight']);
139
            unset($blockstyle[$i]['font-style']);
140
            $this->style_map[strlen($this->parced_str)-1]=$blockstyle[$i];
141
         }
142
      }
143
   }
144
145
   public function __construct($text, $width, &$font_data){
146
      $this->iterator=0;
147
      $this->parced_str='';
148
      $this->style_map=array();
149
      $this->style_parcer($text, $font_data);
150
      $this->positions=array_keys($this->style_map);
151
      $this->np=(bool)count($this->positions);
152
      $this->width=$width;
153
      $this->lines=array('');
154
      $this->linesmap[0]=array(0, 0, 0);
155
      $this->used_fonts=array();
156
   }
157
158
   public function get_str(){
159
      return $this->parced_str;
160
   }
161
162
   public function get_current_style($i){
163
      if(!$this->np){
164
         return '';
165
      }
166
      while($this->positions[$this->iterator]<$i){
167
         $this->iterator++;
168
      }
169
      return $this->style_map[$this->positions[$this->iterator]];
170
   }
171
   
172
173
      public function break_by_style($t){
174
      $i=$this->linesmap[$t][0];
175
      $j=$this->linesmap[$t][1];
176
      $this->iterator=0;
177
      $result=array('chunks'=>array(), 'style'=>array(), 'height'=>0, 'width'=>$this->linesmap[$t][2]);
178
      if(strlen($this->parced_str)==0){
179
         return $result;
180
      }
181
      $cs=$this->get_current_style($i);
182
      $result['height']=$cs['font-size'];
183
      $r=0;
184
      $result['chunks'][$r]='';
185
      $result['style'][$r]=$cs;
186
      while($this->parced_str[$j]==' '){
187
         $j--;
188
      }
189
      $tmp=$i;
190
         for($k=$i; $k<=$j; $k++){
191
         if($this->parced_str[$tmp]==' ' && $this->parced_str[$k]==' '){
192
            $tmp=$k;
193
            continue;
194
         }
195
            if($cs!=$this->get_current_style($k)) {
196
            $r++;
197
            $cs=$this->get_current_style($k);
198
            $result['chunks'][$r]='';
199
            $result['style'][$r]=$cs;
200
            if($result['height']<$cs['font-size']){
201
               $result['height']=$cs['font-size'];
202
            }
203
         }
204
         $result['chunks'][$r].=$this->parced_str[$k];
205
         $tmp=$k;
206
      }
207
      return $result;
208
   }
209
}
210
?>
0 ignored issues
show
Best Practice introduced by
It is not recommended to use PHP's closing tag ?> in files other than templates.

Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.

A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.

Loading history...
211