|
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
|
|
|
?> |
|
|
|
|
|
|
211
|
|
|
|
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.