PluginProbe
PDF & Print by BestWebSoft – WordPress Posts and Pages PDF Generator Plugin / 1.8.1
PDF & Print by BestWebSoft – WordPress Posts and Pages PDF Generator Plugin v1.8.1
trunk 1.5 1.6 1.7 1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 1.7.6 1.7.7 1.7.8 1.7.9 1.8.0 1.8.1 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 1.9.0 1.9.1 All 71 releases
pdf-print / mpdf / classes / grad.php

grad.php in PDF & Print by BestWebSoft – WordPress Posts and Pages PDF Generator Plugin 1.8.1, at mpdf/classes/grad.php

724 lines 32.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 class grad {
4
5 var $mpdf = null;
6
7 function grad(&$mpdf) {
8 $this->mpdf = $mpdf;
9 }
10
11 // mPDF 5.3.A1
12 function CoonsPatchMesh($x, $y, $w, $h, $patch_array=array(), $x_min=0, $x_max=1, $y_min=0, $y_max=1, $colspace='RGB', $return=false){
13 $s=' q ';
14 $s.=sprintf(' %.3F %.3F %.3F %.3F re W n ', $x*_MPDFK, ($this->mpdf->h-$y)*_MPDFK, $w*_MPDFK, -$h*_MPDFK);
15 $s.=sprintf(' %.3F 0 0 %.3F %.3F %.3F cm ', $w*_MPDFK, $h*_MPDFK, $x*_MPDFK, ($this->mpdf->h-($y+$h))*_MPDFK);
16 $n = count($this->mpdf->gradients)+1;
17 $this->mpdf->gradients[$n]['type'] = 6; //coons patch mesh
18 $this->mpdf->gradients[$n]['colorspace'] = $colspace; //coons patch mesh
19 $bpcd=65535; //16 BitsPerCoordinate
20 $trans = false;
21 $this->mpdf->gradients[$n]['stream']='';
22 for($i=0;$i<count($patch_array);$i++){
23 $this->mpdf->gradients[$n]['stream'].=chr($patch_array[$i]['f']); //start with the edge flag as 8 bit
24 for($j=0;$j<count($patch_array[$i]['points']);$j++){
25 //each point as 16 bit
26 if (($j % 2) == 1) { // Y coordinate (adjusted as input is From top left)
27 $patch_array[$i]['points'][$j]=(($patch_array[$i]['points'][$j]-$y_min)/($y_max-$y_min))*$bpcd;
28 $patch_array[$i]['points'][$j]=$bpcd-$patch_array[$i]['points'][$j];
29 }
30 else {
31 $patch_array[$i]['points'][$j]=(($patch_array[$i]['points'][$j]-$x_min)/($x_max-$x_min))*$bpcd;
32 }
33 if($patch_array[$i]['points'][$j]<0) $patch_array[$i]['points'][$j]=0;
34 if($patch_array[$i]['points'][$j]>$bpcd) $patch_array[$i]['points'][$j]=$bpcd;
35 $this->mpdf->gradients[$n]['stream'].=chr(floor($patch_array[$i]['points'][$j]/256));
36 $this->mpdf->gradients[$n]['stream'].=chr(floor($patch_array[$i]['points'][$j]%256));
37 }
38 for($j=0;$j<count($patch_array[$i]['colors']);$j++){
39 //each color component as 8 bit
40 if ($colspace=='RGB') {
41 $this->mpdf->gradients[$n]['stream'].=($patch_array[$i]['colors'][$j][1]);
42 $this->mpdf->gradients[$n]['stream'].=($patch_array[$i]['colors'][$j][2]);
43 $this->mpdf->gradients[$n]['stream'].=($patch_array[$i]['colors'][$j][3]);
44 if (isset($patch_array[$i]['colors'][$j][4]) && ord($patch_array[$i]['colors'][$j][4])<100) { $trans = true; }
45 }
46 else if ($colspace=='CMYK') {
47 $this->mpdf->gradients[$n]['stream'].=chr(ord($patch_array[$i]['colors'][$j][1])*2.55);
48 $this->mpdf->gradients[$n]['stream'].=chr(ord($patch_array[$i]['colors'][$j][2])*2.55);
49 $this->mpdf->gradients[$n]['stream'].=chr(ord($patch_array[$i]['colors'][$j][3])*2.55);
50 $this->mpdf->gradients[$n]['stream'].=chr(ord($patch_array[$i]['colors'][$j][4])*2.55);
51 if (isset($patch_array[$i]['colors'][$j][5]) && ord($patch_array[$i]['colors'][$j][5])<100) { $trans = true; }
52 }
53 else if ($colspace=='Gray') {
54 $this->mpdf->gradients[$n]['stream'].=($patch_array[$i]['colors'][$j][1]);
55 if ($patch_array[$i]['colors'][$j][2]==1) { $trans = true; } // transparency converted from rgba or cmyka()
56 }
57 }
58 }
59 // TRANSPARENCY
60 if ($trans) {
61 $this->mpdf->gradients[$n]['stream_trans']='';
62 for($i=0;$i<count($patch_array);$i++){
63 $this->mpdf->gradients[$n]['stream_trans'].=chr($patch_array[$i]['f']);
64 for($j=0;$j<count($patch_array[$i]['points']);$j++){
65 //each point as 16 bit
66 $this->mpdf->gradients[$n]['stream_trans'].=chr(floor($patch_array[$i]['points'][$j]/256));
67 $this->mpdf->gradients[$n]['stream_trans'].=chr(floor($patch_array[$i]['points'][$j]%256));
68 }
69 for($j=0;$j<count($patch_array[$i]['colors']);$j++){
70 //each color component as 8 bit // OPACITY
71 if ($colspace=='RGB') {
72 $this->mpdf->gradients[$n]['stream_trans'].=chr(intval(ord($patch_array[$i]['colors'][$j][4])*2.55));
73 }
74 else if ($colspace=='CMYK') {
75 $this->mpdf->gradients[$n]['stream_trans'].=chr(intval(ord($patch_array[$i]['colors'][$j][5])*2.55));
76 }
77 else if ($colspace=='Gray') {
78 $this->mpdf->gradients[$n]['stream_trans'].=chr(intval(ord($patch_array[$i]['colors'][$j][3])*2.55));
79 }
80 }
81 }
82 $this->mpdf->gradients[$n]['trans'] = true;
83 $s .= ' /TGS'.$n.' gs ';
84 }
85 //paint the gradient
86 $s .= '/Sh'.$n.' sh'."\n";
87 //restore previous Graphic State
88 $s .= 'Q'."\n";
89 if ($return) { return $s; }
90 else { $this->mpdf->_out($s); }
91 }
92
93
94 // type = linear:2; radial: 3;
95 // Linear: $coords - array of the form (x1, y1, x2, y2) which defines the gradient vector (see linear_gradient_coords.jpg).
96 // The default value is from left to right (x1=0, y1=0, x2=1, y2=0).
97 // Radial: $coords - array of the form (fx, fy, cx, cy, r) where (fx, fy) is the starting point of the gradient with color1,
98 // (cx, cy) is the center of the circle with color2, and r is the radius of the circle (see radial_gradient_coords.jpg).
99 // (fx, fy) should be inside the circle, otherwise some areas will not be defined
100 // $col = array(R,G,B/255); or array(G/255); or array(C,M,Y,K/100)
101 // $stops = array('col'=>$col [, 'opacity'=>0-1] [, 'offset'=>0-1])
102 function Gradient($x, $y, $w, $h, $type, $stops=array(), $colorspace='RGB', $coords='', $extend='', $return=false, $is_mask=false) {
103 if (strtoupper(substr($type,0,1)) == 'L') { $type = 2; } // linear
104 else if (strtoupper(substr($type,0,1)) == 'R') { $type = 3; } // radial
105 if ($colorspace != 'CMYK' && $colorspace != 'Gray') {
106 $colorspace = 'RGB';
107 }
108 $bboxw = $w;
109 $bboxh = $h;
110 $usex = $x;
111 $usey = $y;
112 $usew = $bboxw;
113 $useh = $bboxh;
114
115 if ($type < 1) { $type = 2; }
116 if ($coords[0]!==false && preg_match('/([0-9.]+(px|em|ex|pc|pt|cm|mm|in))/i',$coords[0],$m)) {
117 $tmp = $this->mpdf->ConvertSize($m[1],$this->mpdf->w,$this->mpdf->FontSize,false);
118 if ($tmp) { $coords[0] = $tmp/$w; }
119 }
120 if ($coords[1]!==false && preg_match('/([0-9.]+(px|em|ex|pc|pt|cm|mm|in))/i',$coords[1],$m)) {
121 $tmp = $this->mpdf->ConvertSize($m[1],$this->mpdf->w,$this->mpdf->FontSize,false);
122 if ($tmp) { $coords[1] = 1-($tmp/$h); }
123 }
124 // LINEAR
125 if ($type == 2) {
126 $angle = (isset($coords[4]) ? $coords[4] : false);
127 $repeat = (isset($coords[5]) ? $coords[5] : false);
128 // ALL POINTS SET (default for custom mPDF linear gradient) - no -moz
129 if ($coords[0]!==false && $coords[1]!==false && $coords[2]!==false && $coords[3]!==false) {
130 // do nothing - coords used as they are
131 }
132
133 // If both a <point> and <angle> are defined, the gradient axis starts from the point and runs along the angle. The end point is
134 // defined as before - in this case start points may not be in corners, and axis may not correctly fall in the right quadrant.
135 // NO end points (Angle defined & Start points)
136 else if ($angle!==false && $coords[0]!==false && $coords[1]!==false && $coords[2]===false && $coords[3]===false) {
137 if ($angle==0 || $angle==360) { $coords[3]=$coords[1]; if ($coords[0]==1) $coords[2]=2; else $coords[2]=1; }
138 else if ($angle==90) { $coords[2]=$coords[0]; $coords[3]=1; if ($coords[1]==1) $coords[3]=2; else $coords[3]=1; }
139 else if ($angle==180) { if ($coords[4]==0) $coords[2]=-1; else $coords[2]=0; $coords[3]=$coords[1]; }
140 else if ($angle==270) { $coords[2]=$coords[0]; if ($coords[1]==0) $coords[3]=-1; else $coords[3]=0; }
141 else {
142 $endx=1; $endy=1;
143 if ($angle <=90) {
144 if ($angle <=45) { $endy=tan(deg2rad($angle)); }
145 else { $endx=tan(deg2rad(90-$angle)); }
146 $b = atan2(($endy*$bboxh), ($endx*$bboxw));
147 $ny = 1 - $coords[1] - (tan($b) * (1-$coords[0]));
148 $tx = sin($b) * cos($b) * $ny;
149 $ty = cos($b) * cos($b) * $ny;
150 $coords[2] = 1+$tx; $coords[3] = 1-$ty;
151 }
152 else if ($angle <=180) {
153 if ($angle <=135) { $endx=tan(deg2rad($angle-90)); }
154 else { $endy=tan(deg2rad(180-$angle)); }
155 $b = atan2(($endy*$bboxh), ($endx*$bboxw));
156 $ny = 1 - $coords[1] - (tan($b) * ($coords[0]));
157 $tx = sin($b) * cos($b) * $ny;
158 $ty = cos($b) * cos($b) * $ny;
159 $coords[2] = -$tx; $coords[3] = 1-$ty;
160 }
161 else if ($angle <=270) {
162 if ($angle <=225) { $endy=tan(deg2rad($angle-180)); }
163 else { $endx=tan(deg2rad(270-$angle)); }
164 $b = atan2(($endy*$bboxh), ($endx*$bboxw));
165 $ny = $coords[1] - (tan($b) * ($coords[0]));
166 $tx = sin($b) * cos($b) * $ny;
167 $ty = cos($b) * cos($b) * $ny;
168 $coords[2] = -$tx; $coords[3] = $ty;
169 }
170 else {
171 if ($angle <=315) { $endx=tan(deg2rad($angle-270)); }
172 else { $endy=tan(deg2rad(360-$angle)); }
173 $b = atan2(($endy*$bboxh), ($endx*$bboxw));
174 $ny = $coords[1] - (tan($b) * (1-$coords[0]));
175 $tx = sin($b) * cos($b) * $ny;
176 $ty = cos($b) * cos($b) * $ny;
177 $coords[2] = 1+$tx; $coords[3] = $ty;
178
179 }
180 }
181 }
182
183 // -moz If the first parameter is only an <angle>, the gradient axis starts from the box's corner that would ensure the
184 // axis goes through the box. The axis runs along the specified angle. The end point of the axis is defined such that the
185 // farthest corner of the box from the starting point is perpendicular to the gradient axis at that point.
186 // NO end points or Start points (Angle defined)
187 else if ($angle!==false && $coords[0]===false && $coords[1]===false) {
188 if ($angle==0 || $angle==360) { $coords[0]=0; $coords[1]=0; $coords[2]=1; $coords[3]=0; }
189 else if ($angle==90) { $coords[0]=0; $coords[1]=0; $coords[2]=0; $coords[3]=1; }
190 else if ($angle==180) { $coords[0]=1; $coords[1]=0; $coords[2]=0; $coords[3]=0; }
191 else if ($angle==270) { $coords[0]=0; $coords[1]=1; $coords[2]=0; $coords[3]=0; }
192 else {
193 if ($angle <=90) {
194 $coords[0]=0; $coords[1]=0;
195 if ($angle <=45) { $endx=1; $endy=tan(deg2rad($angle)); }
196 else { $endx=tan(deg2rad(90-$angle)); $endy=1; }
197 }
198 else if ($angle <=180) {
199 $coords[0]=1; $coords[1]=0;
200 if ($angle <=135) { $endx=tan(deg2rad($angle-90)); $endy=1; }
201 else { $endx=1; $endy=tan(deg2rad(180-$angle)); }
202 }
203 else if ($angle <=270) {
204 $coords[0]=1; $coords[1]=1;
205 if ($angle <=225) { $endx=1; $endy=tan(deg2rad($angle-180)); }
206 else { $endx=tan(deg2rad(270-$angle)); $endy=1; }
207 }
208 else {
209 $coords[0]=0; $coords[1]=1;
210 if ($angle <=315) { $endx=tan(deg2rad($angle-270)); $endy=1; }
211 else { $endx=1; $endy=tan(deg2rad(360-$angle)); }
212 }
213 $b = atan2(($endy*$bboxh), ($endx*$bboxw));
214 $h2 = $bboxh - ($bboxh * tan($b));
215 $px = $bboxh + ($h2 * sin($b) * cos($b));
216 $py = ($bboxh * tan($b)) + ($h2 * sin($b) * sin($b));
217 $x1 = $px / $bboxh;
218 $y1 = $py / $bboxh;
219 if ($angle <=90) { $coords[2] = $x1; $coords[3] = $y1; }
220 else if ($angle <=180) { $coords[2] = 1-$x1; $coords[3] = $y1; }
221 else if ($angle <=270) { $coords[2] = 1-$x1; $coords[3] = 1-$y1; }
222 else { $coords[2] = $x1; $coords[3] = 1-$y1; }
223 }
224 }
225 // -moz If the first parameter to the gradient function is only a <point>, the gradient axis starts from the specified point,
226 // and ends at the point you would get if you rotated the starting point by 180 degrees about the center of the box that the
227 // gradient is to be applied to.
228 // NO angle and NO end points (Start points defined)
229 else if ((!isset($angle) || $angle===false) && $coords[0]!==false && $coords[1]!==false) { // should have start and end defined
230 $coords[2] = 1-$coords[0]; $coords[3] = 1-$coords[1];
231 $angle = rad2deg(atan2($coords[3]-$coords[1],$coords[2]-$coords[0]));
232 if ($angle < 0) { $angle += 360; }
233 else if ($angle > 360) { $angle -= 360; }
234 if ($angle!=0 && $angle!=360 && $angle!=90 && $angle!=180 && $angle!=270) {
235 if ($w >= $h) {
236 $coords[1] *= $h/$w ;
237 $coords[3] *= $h/$w ;
238 $usew = $useh = $bboxw;
239 $usey -= ($w-$h);
240 }
241 else {
242 $coords[0] *= $w/$h ;
243 $coords[2] *= $w/$h ;
244 $usew = $useh = $bboxh;
245 }
246 }
247 }
248
249 // -moz If neither a <point> or <angle> is specified, i.e. the entire function consists of only <stop> values, the gradient
250 // axis starts from the top of the box and runs vertically downwards, ending at the bottom of the box.
251 else { // default values T2B
252 // All values are set in parseMozGradient - so won't appear here
253 $coords = array(0,0,1,0); // default for original linear gradient (L2R)
254 }
255 $s = ' q';
256 $s .= sprintf(' %.3F %.3F %.3F %.3F re W n', $x*_MPDFK, ($this->mpdf->h-$y)*_MPDFK, $w*_MPDFK, -$h*_MPDFK)."\n";
257 $s .= sprintf(' %.3F 0 0 %.3F %.3F %.3F cm', $usew*_MPDFK, $useh*_MPDFK, $usex*_MPDFK, ($this->mpdf->h-($usey+$useh))*_MPDFK)."\n";
258 }
259
260 // RADIAL
261 else if ($type == 3) {
262 $radius = (isset($coords[4]) ? $coords[4] : false);
263 $angle = (isset($coords[5]) ? $coords[5] : false); // ?? no effect
264 $shape = (isset($coords[6]) ? $coords[6] : false);
265 $size = (isset($coords[7]) ? $coords[7] : false);
266 $repeat = (isset($coords[8]) ? $coords[8] : false);
267 // ALL POINTS AND RADIUS SET (default for custom mPDF radial gradient) - no -moz
268 if ($coords[0]!==false && $coords[1]!==false && $coords[2]!==false && $coords[3]!==false && $coords[4]!==false) {
269 // do nothing - coords used as they are
270 }
271 // If a <point> is defined
272 else if ($shape!==false && $size!==false) {
273 if ($coords[2]==false) { $coords[2] = $coords[0]; }
274 if ($coords[3]==false) { $coords[3] = $coords[1]; }
275 // ELLIPSE
276 if ($shape=='ellipse') {
277 $corner1 = sqrt(pow($coords[0],2) + pow($coords[1],2));
278 $corner2 = sqrt(pow($coords[0],2) + pow((1-$coords[1]),2));
279 $corner3 = sqrt(pow((1-$coords[0]),2) + pow($coords[1],2));
280 $corner4 = sqrt(pow((1-$coords[0]),2) + pow((1-$coords[1]),2));
281 if ($size=='closest-side') { $radius = min($coords[0], $coords[1], (1-$coords[0]), (1-$coords[1])); }
282 else if ($size=='closest-corner') { $radius = min($corner1, $corner2, $corner3, $corner4); }
283 else if ($size=='farthest-side') { $radius = max($coords[0], $coords[1], (1-$coords[0]), (1-$coords[1])); }
284 else { $radius = max($corner1, $corner2, $corner3, $corner4); } // farthest corner (default)
285 }
286 // CIRCLE
287 else if ($shape=='circle') {
288 if ($w >= $h) {
289 $coords[1] = $coords[3] = ($coords[1] * $h/$w) ;
290 $corner1 = sqrt(pow($coords[0],2) + pow($coords[1],2));
291 $corner2 = sqrt(pow($coords[0],2) + pow((($h/$w)-$coords[1]),2));
292 $corner3 = sqrt(pow((1-$coords[0]),2) + pow($coords[1],2));
293 $corner4 = sqrt(pow((1-$coords[0]),2) + pow((($h/$w)-$coords[1]),2));
294 if ($size=='closest-side') { $radius = min($coords[0], $coords[1], (1-$coords[0]), (($h/$w)-$coords[1])); }
295 else if ($size=='closest-corner') { $radius = min($corner1, $corner2, $corner3, $corner4); }
296 else if ($size=='farthest-side') { $radius = max($coords[0], $coords[1], (1-$coords[0]), (($h/$w)-$coords[1])); }
297 else if ($size=='farthest-corner') { $radius = max($corner1, $corner2, $corner3, $corner4); } // farthest corner (default)
298 $usew = $useh = $bboxw;
299 $usey -= ($w-$h);
300 }
301 else {
302 $coords[0] = $coords[2] = ($coords[0] * $w/$h) ;
303 $corner1 = sqrt(pow($coords[0],2) + pow($coords[1],2));
304 $corner2 = sqrt(pow($coords[0],2) + pow((1-$coords[1]),2));
305 $corner3 = sqrt(pow((($w/$h)-$coords[0]),2) + pow($coords[1],2));
306 $corner4 = sqrt(pow((($w/$h)-$coords[0]),2) + pow((1-$coords[1]),2));
307 if ($size=='closest-side') { $radius = min($coords[0], $coords[1], (($w/$h)-$coords[0]), (1-$coords[1])); }
308 else if ($size=='closest-corner') { $radius = min($corner1, $corner2, $corner3, $corner4); }
309 else if ($size=='farthest-side') { $radius = max($coords[0], $coords[1], (($w/$h)-$coords[0]), (1-$coords[1])); }
310 else if ($size=='farthest-corner') { $radius = max($corner1, $corner2, $corner3, $corner4); } // farthest corner (default)
311 $usew = $useh = $bboxh;
312 }
313 }
314 if ($radius==0) { $radius=0.001; } // to prevent error
315 $coords[4] = $radius;
316 }
317
318 // -moz If entire function consists of only <stop> values
319 else { // default values
320 // All values are set in parseMozGradient - so won't appear here
321 $coords = array(0.5,0.5,0.5,0.5); // default for radial gradient (centred)
322 }
323 $s = ' q';
324 $s .= sprintf(' %.3F %.3F %.3F %.3F re W n', $x*_MPDFK, ($this->mpdf->h-$y)*_MPDFK, $w*_MPDFK, -$h*_MPDFK)."\n";
325 $s .= sprintf(' %.3F 0 0 %.3F %.3F %.3F cm', $usew*_MPDFK, $useh*_MPDFK, $usex*_MPDFK, ($this->mpdf->h-($usey+$useh))*_MPDFK)."\n";
326 }
327
328 $n = count($this->mpdf->gradients) + 1;
329 $this->mpdf->gradients[$n]['type'] = $type;
330 $this->mpdf->gradients[$n]['colorspace'] = $colorspace;
331 $trans = false;
332 $this->mpdf->gradients[$n]['is_mask'] = $is_mask;
333 if ($is_mask) { $trans = true; }
334 if (count($stops) == 1) { $stops[1] = $stops[0]; }
335 if (!isset($stops[0]['offset'])) { $stops[0]['offset'] = 0; }
336 if (!isset($stops[(count($stops)-1)]['offset'])) { $stops[(count($stops)-1)]['offset'] = 1; }
337
338 // Fix stop-offsets set as absolute lengths
339 if ($type==2) {
340 $axisx = ($coords[2]-$coords[0])*$usew;
341 $axisy = ($coords[3]-$coords[1])*$useh;
342 $axis_length = sqrt(pow($axisx,2) + pow($axisy,2));
343 }
344 else { $axis_length = $coords[4]*$usew; } // Absolute lengths are meaningless for an ellipse - Firefox uses Width as reference
345
346 for($i=0;$i<count($stops);$i++) {
347 if (isset($stops[$i]['offset']) && preg_match('/([0-9.]+(px|em|ex|pc|pt|cm|mm|in))/i',$stops[$i]['offset'],$m)) {
348 $tmp = $this->mpdf->ConvertSize($m[1],$this->mpdf->w,$this->mpdf->FontSize,false);
349 $stops[$i]['offset'] = $tmp/$axis_length;
350 }
351 }
352
353
354 if (isset($stops[0]['offset']) && $stops[0]['offset']>0) {
355 $firststop = $stops[0];
356 $firststop['offset'] = 0;
357 array_unshift($stops, $firststop);
358 }
359 if (!$repeat && isset($stops[(count($stops)-1)]['offset']) && $stops[(count($stops)-1)]['offset']<1) {
360 $endstop = $stops[(count($stops)-1)];
361 $endstop['offset'] = 1;
362 $stops[] = $endstop;
363 }
364 if ($stops[0]['offset'] > $stops[(count($stops)-1)]['offset']) {
365 $stops[0]['offset'] = 0;
366 $stops[(count($stops)-1)]['offset'] = 1;
367 }
368
369 for($i=0;$i<count($stops);$i++) {
370 // mPDF 5.3.74
371 if ($colorspace == 'CMYK') {
372 $this->mpdf->gradients[$n]['stops'][$i]['col'] = sprintf('%.3F %.3F %.3F %.3F', (ord($stops[$i]['col']{1})/100), (ord($stops[$i]['col']{2})/100), (ord($stops[$i]['col']{3})/100), (ord($stops[$i]['col']{4})/100));
373 }
374 else if ($colorspace == 'Gray') {
375 $this->mpdf->gradients[$n]['stops'][$i]['col'] = sprintf('%.3F', (ord($stops[$i]['col']{1})/255));
376 }
377 else {
378 $this->mpdf->gradients[$n]['stops'][$i]['col'] = sprintf('%.3F %.3F %.3F', (ord($stops[$i]['col']{1})/255), (ord($stops[$i]['col']{2})/255), (ord($stops[$i]['col']{3})/255));
379 }
380 if (!isset($stops[$i]['opacity'])) { $stops[$i]['opacity'] = 1; }
381 else if ($stops[$i]['opacity'] > 1 || $stops[$i]['opacity'] < 0) { $stops[$i]['opacity'] = 1; }
382 else if ($stops[$i]['opacity'] < 1) {
383 $trans = true;
384 }
385 $this->mpdf->gradients[$n]['stops'][$i]['opacity'] = $stops[$i]['opacity'];
386 // OFFSET
387 if ($i>0 && $i<(count($stops)-1)) {
388 if (!isset($stops[$i]['offset']) || (isset($stops[$i+1]['offset']) && $stops[$i]['offset']>$stops[$i+1]['offset']) || $stops[$i]['offset']<$stops[$i-1]['offset']) {
389 if (isset($stops[$i-1]['offset']) && isset($stops[$i+1]['offset'])) {
390 $stops[$i]['offset'] = ($stops[$i-1]['offset']+$stops[$i+1]['offset'])/2;
391 }
392 else {
393 for($j=($i+1);$j<count($stops);$j++) {
394 if(isset($stops[$j]['offset'])) { break; }
395 }
396 $int = ($stops[$j]['offset'] - $stops[($i-1)]['offset'])/($j-$i+1);
397 for($f=0;$f<($j-$i-1);$f++) {
398 $stops[($i+$f)]['offset'] = $stops[($i+$f-1)]['offset'] + ($int);
399 }
400 }
401 }
402 }
403 $this->mpdf->gradients[$n]['stops'][$i]['offset'] = $stops[$i]['offset'];
404 $this->mpdf->gradients[$n]['stops'][$i]['offset'] = $stops[$i]['offset'];
405 }
406
407 if ($repeat) {
408 $ns = count($this->mpdf->gradients[$n]['stops']);
409 $offs = array();
410 for($i=0;$i<$ns;$i++) {
411 $offs[$i] = $this->mpdf->gradients[$n]['stops'][$i]['offset'];
412 }
413 $gp = 0;
414 $inside=true;
415 while($inside) {
416 $gp++;
417 for($i=0;$i<$ns;$i++) {
418 $this->mpdf->gradients[$n]['stops'][(($ns*$gp)+$i)] = $this->mpdf->gradients[$n]['stops'][(($ns*($gp-1))+$i)];
419 $tmp = $this->mpdf->gradients[$n]['stops'][(($ns*($gp-1))+($ns-1))]['offset']+$offs[$i] ;
420 if ($tmp < 1) { $this->mpdf->gradients[$n]['stops'][(($ns*$gp)+$i)]['offset'] = $tmp; }
421 else {
422 $this->mpdf->gradients[$n]['stops'][(($ns*$gp)+$i)]['offset'] = 1;
423 $inside = false;
424 break(2);
425 }
426 }
427 }
428 }
429
430 if ($trans) {
431 $this->mpdf->gradients[$n]['trans'] = true;
432 $s .= ' /TGS'.$n.' gs ';
433 }
434 if (!is_array($extend) || count($extend) <1) {
435 $extend=array('true', 'true'); // These are supposed to be quoted - appear in PDF file as text
436 }
437 $this->mpdf->gradients[$n]['coords'] = $coords;
438 $this->mpdf->gradients[$n]['extend'] = $extend;
439 //paint the gradient
440 $s .= '/Sh'.$n.' sh '."\n";
441 //restore previous Graphic State
442 $s .= ' Q '."\n";
443 if ($return) { return $s; }
444 else { $this->mpdf->_out($s); }
445 }
446
447
448 function parseMozGradient($bg) {
449 // background[-image]: -moz-linear-gradient(left, #c7Fdde 20%, #FF0000 );
450 // background[-image]: linear-gradient(left, #c7Fdde 20%, #FF0000 ); // CSS3
451 if (preg_match('/repeating-/',$bg)) { $repeat = true; }
452 else { $repeat = false; }
453 if (preg_match('/linear-gradient\((.*)\)/',$bg,$m)) {
454 $g = array();
455 $g['type'] = 2;
456 $g['colorspace'] = 'RGB';
457 $g['extend'] = array('true','true');
458 $v = trim($m[1]);
459 // Change commas inside e.g. rgb(x,x,x)
460 while(preg_match('/(\([^\)]*?),/',$v)) { $v = preg_replace('/(\([^\)]*?),/','\\1@',$v); }
461 // Remove spaces inside e.g. rgb(x, x, x)
462 while(preg_match('/(\([^\)]*?)[ ]/',$v)) { $v = preg_replace('/(\([^\)]*?)[ ]/','\\1',$v); }
463 $bgr = preg_split('/\s*,\s*/',$v);
464 for($i=0;$i<count($bgr);$i++) { $bgr[$i] = preg_replace('/@/', ',', $bgr[$i]); }
465 // Is first part $bgr[0] a valid point/angle?
466 $first = preg_split('/\s+/',trim($bgr[0]));
467 if (preg_match('/(left|center|right|bottom|top|deg|grad|rad)/i',$bgr[0]) && !preg_match('/(<#|rgb|rgba|hsl|hsla)/i',$bgr[0])) {
468 $startStops = 1;
469 }
470 else if (trim($first[(count($first)-1)]) === "0") {
471 $startStops = 1;
472 }
473 else {
474 $check = $this->mpdf->ConvertColor($first[0]);
475 if ($check) $startStops = 0;
476 else $startStops = 1;
477 }
478 // first part a valid point/angle?
479 if ($startStops == 1) { // default values
480 // [<point> || <angle>,] = [<% em px left center right bottom top> || <deg grad rad 0>,]
481 if (preg_match('/([\-]*[0-9\.]+)(deg|grad|rad)/i',$bgr[0],$m)) {
482 $angle = $m[1] + 0;
483 if (strtolower($m[2])=='deg') { $angle = $angle; }
484 else if (strtolower($m[2])=='grad') { $angle *= (360/400); }
485 else if (strtolower($m[2])=='rad') { $angle = rad2deg($angle); }
486 while($angle < 0) { $angle += 360; }
487 $angle = ($angle % 360);
488 }
489 else if (trim($first[(count($first)-1)]) === "0") { $angle = 0; }
490 if (preg_match('/left/i',$bgr[0])) { $startx = 0; }
491 else if (preg_match('/right/i',$bgr[0])) { $startx = 1; }
492 if (preg_match('/top/i',$bgr[0])) { $starty = 1; }
493 else if (preg_match('/bottom/i',$bgr[0])) { $starty = 0; }
494 // Check for %? ?% or %%
495 if (preg_match('/(\d+)[%]/i',$first[0],$m)) { $startx = $m[1]/100; }
496 else if (!isset($startx) && preg_match('/([0-9.]+(px|em|ex|pc|pt|cm|mm|in))/i',$first[0],$m)) {
497 $tmp = $this->mpdf->ConvertSize($m[1],$this->mpdf->w,$this->mpdf->FontSize,false);
498 if ($tmp) { $startx = $m[1]; }
499 }
500 if (isset($first[1]) && preg_match('/(\d+)[%]/i',$first[1],$m)) { $starty = 1 - ($m[1]/100); }
501 else if (!isset($starty) && isset($first[1]) && preg_match('/([0-9.]+(px|em|ex|pc|pt|cm|mm|in))/i',$first[1],$m)) {
502 $tmp = $this->mpdf->ConvertSize($m[1],$this->mpdf->w,$this->mpdf->FontSize,false);
503 if ($tmp) { $starty = $m[1]; }
504 }
505 if (isset($startx) && !isset($starty)) { $starty = 0.5; }
506 if (!isset($startx) && isset($starty)) { $startx = 0.5; }
507
508 }
509 // If neither a <point> or <angle> is specified, i.e. the entire function consists of only <stop> values, the gradient axis starts from the top of the box and runs vertically downwards, ending at the bottom of the box.
510 else { // default values T2B
511 $starty = 1; $startx = 0.5;
512 $endy = 0; $endx = 0.5;
513 }
514 $coords = array();
515 if (!isset($startx)) { $startx = false; }
516 if (!isset($starty)) { $starty = false; }
517 if (!isset($endx)) { $endx = false; }
518 if (!isset($endy)) { $endy = false; }
519 if (!isset($angle)) { $angle = false; }
520 $g['coords'] = array($startx ,$starty ,$endx ,$endy, $angle, $repeat );
521 $g['stops'] = array();
522 for($i=$startStops;$i<count($bgr);$i++) {
523 $stop = array();
524 // parse stops
525 $el = preg_split('/\s+/',trim($bgr[$i]));
526 // mPDF 5.3.74
527 $col = $this->mpdf->ConvertColor($el[0]);
528 if ($col) { $stop['col'] = $col; }
529 else { $stop['col'] = $col = $this->mpdf->ConvertColor(255); }
530 if ($col{0}==1) $g['colorspace'] = 'Gray';
531 else if ($col{0}==4 || $col{0}==6) $g['colorspace'] = 'CMYK';
532 if ($col{0}==5) { $stop['opacity'] = ord($col{4})/100; } // transparency from rgba()
533 else if ($col{0}==6) { $stop['opacity'] = ord($col{5})/100; } // transparency from cmyka()
534 else if ($col{0}==1 && $col{2}==1) { $stop['opacity'] = ord($col{3})/100; } // transparency converted from rgba or cmyka()
535
536 if (isset($el[1]) && preg_match('/(\d+)[%]/',$el[1],$m)) {
537 $stop['offset'] = $m[1]/100;
538 if ($stop['offset']>1) { unset($stop['offset']); }
539 }
540 else if (isset($el[1]) && preg_match('/([0-9.]+(px|em|ex|pc|pt|cm|mm|in))/i',$el[1],$m)) {
541 $tmp = $this->mpdf->ConvertSize($m[1],$this->mpdf->w,$this->mpdf->FontSize,false);
542 if ($tmp) { $stop['offset'] = $m[1]; }
543 }
544 $g['stops'][] = $stop;
545 }
546 if (count($g['stops'] )) { return $g; }
547 }
548 else if (preg_match('/radial-gradient\((.*)\)/',$bg,$m)) {
549 $g = array();
550 $g['type'] = 3;
551 $g['colorspace'] = 'RGB';
552 $g['extend'] = array('true','true');
553 $v = trim($m[1]);
554 // Change commas inside e.g. rgb(x,x,x)
555 while(preg_match('/(\([^\)]*?),/',$v)) { $v = preg_replace('/(\([^\)]*?),/','\\1@',$v); }
556 // Remove spaces inside e.g. rgb(x, x, x)
557 while(preg_match('/(\([^\)]*?)[ ]/',$v)) { $v = preg_replace('/(\([^\)]*?)[ ]/','\\1',$v); }
558 $bgr = preg_split('/\s*,\s*/',$v);
559 for($i=0;$i<count($bgr);$i++) { $bgr[$i] = preg_replace('/@/', ',', $bgr[$i]); }
560
561 // Is first part $bgr[0] a valid point/angle?
562 $startStops = 0;
563 $pos_angle = false;
564 $shape_size = false;
565 $first = preg_split('/\s+/',trim($bgr[0]));
566 $checkCol = $this->mpdf->ConvertColor($first[0]);
567 if (preg_match('/(left|center|right|bottom|top|deg|grad|rad)/i',$bgr[0]) && !preg_match('/(<#|rgb|rgba|hsl|hsla)/i',$bgr[0])) {
568 $startStops=1;
569 $pos_angle = $bgr[0];
570 }
571 else if (trim($first[(count($first)-1)]) === "0") {
572 $startStops=1;
573 $pos_angle = $bgr[0];
574 }
575 else if (preg_match('/(circle|ellipse|closest-side|closest-corner|farthest-side|farthest-corner|contain|cover)/i',$bgr[0])) {
576 $startStops=1;
577 $shape_size = $bgr[0];
578 }
579 else if (!$checkCol) {
580 $startStops=1;
581 $pos_angle = $bgr[0];
582 }
583 if (preg_match('/(circle|ellipse|closest-side|closest-corner|farthest-side|farthest-corner|contain|cover)/i',$bgr[1])) {
584 $startStops=2;
585 $shape_size = $bgr[1];
586 }
587
588 // If valid point/angle?
589 if ($pos_angle) { // default values
590 // [<point> || <angle>,] = [<% em px left center right bottom top> || <deg grad rad 0>,]
591 if (preg_match('/left/i',$pos_angle)) { $startx = 0; }
592 else if (preg_match('/right/i',$pos_angle)) { $startx = 1; }
593 if (preg_match('/top/i',$pos_angle)) { $starty = 1; }
594 else if (preg_match('/bottom/i',$pos_angle)) { $starty = 0; }
595 // Check for %? ?% or %%
596 if (preg_match('/(\d+)[%]/i',$first[0],$m)) { $startx = $m[1]/100; }
597 else if (!isset($startx) && preg_match('/([0-9.]+(px|em|ex|pc|pt|cm|mm|in))/i',$first[0],$m)) {
598 $tmp = $this->mpdf->ConvertSize($m[1],$this->mpdf->w,$this->mpdf->FontSize,false);
599 if ($tmp) { $startx = $m[1]; }
600 }
601 if (isset($first[1]) && preg_match('/(\d+)[%]/i',$first[1],$m)) { $starty = 1 - ($m[1]/100); }
602 else if (!isset($starty) && isset($first[1]) && preg_match('/([0-9.]+(px|em|ex|pc|pt|cm|mm|in))/i',$first[1],$m)) {
603 $tmp = $this->mpdf->ConvertSize($m[1],$this->mpdf->w,$this->mpdf->FontSize,false);
604 if ($tmp) { $starty = $m[1]; }
605 }
606
607 /*
608 // ?? Angle has no effect in radial gradient (does not exist in CSS3 spec.)
609 if (preg_match('/([\-]*[0-9\.]+)(deg|grad|rad)/i',$pos_angle,$m)) {
610 $angle = $m[1] + 0;
611 if (strtolower($m[2])=='deg') { $angle = $angle; }
612 else if (strtolower($m[2])=='grad') { $angle *= (360/400); }
613 else if (strtolower($m[2])=='rad') { $angle = rad2deg($angle); }
614 while($angle < 0) { $angle += 360; }
615 $angle = ($angle % 360);
616 }
617 */
618 if (!isset($starty)) { $starty = 0.5; }
619 if (!isset($startx)) { $startx = 0.5; }
620
621 }
622 // If neither a <point> or <angle> is specified, i.e. the entire function consists of only <stop> values, the gradient axis starts from the top of the box and runs vertically downwards, ending at the bottom of the box.
623 else { // default values Center
624 $starty = 0.5; $startx = 0.5;
625 $endy = 0.5; $endx = 0.5;
626 }
627
628 // If valid shape/size?
629 $shape = 'ellipse'; // default
630 $size = 'farthest-corner'; // default
631 if ($shape_size) { // default values
632 if (preg_match('/(circle|ellipse)/i',$shape_size, $m)) {
633 $shape = $m[1];
634 }
635 if (preg_match('/(closest-side|closest-corner|farthest-side|farthest-corner|contain|cover)/i',$shape_size, $m)) {
636 $size = $m[1];
637 if ($size=='contain') { $size = 'closest-side'; }
638 else if ($size=='cover') { $size = 'farthest-corner'; }
639 }
640 }
641
642 $coords = array();
643 if (!isset($startx)) { $startx = false; }
644 if (!isset($starty)) { $starty = false; }
645 if (!isset($endx)) { $endx = false; }
646 if (!isset($endy)) { $endy = false; }
647 if (!isset($radius)) { $radius = false; }
648 if (!isset($angle)) { $angle = 0; }
649 $g['coords'] = array($startx ,$starty ,$endx ,$endy, $radius, $angle, $shape, $size, $repeat );
650
651 $g['stops'] = array();
652 for($i=$startStops;$i<count($bgr);$i++) {
653 $stop = array();
654 // parse stops
655 $el = preg_split('/\s+/',trim($bgr[$i]));
656 // mPDF 5.3.74
657 $col = $this->mpdf->ConvertColor($el[0]);
658 if ($col) { $stop['col'] = $col; }
659 else { $stop['col'] = $col = $this->mpdf->ConvertColor(255); }
660 if ($col{0}==1) $g['colorspace'] = 'Gray';
661 else if ($col{0}==4 || $col{0}==6) $g['colorspace'] = 'CMYK';
662 if ($col{0}==5) { $stop['opacity'] = ord($col{4})/100; } // transparency from rgba()
663 else if ($col{0}==6) { $stop['opacity'] = ord($col{5})/100; } // transparency from cmyka()
664 else if ($col{0}==1 && $col{2}==1) { $stop['opacity'] = ord($col{3})/100; } // transparency converted from rgba or cmyka()
665
666 if (isset($el[1]) && preg_match('/(\d+)[%]/',$el[1],$m)) {
667 $stop['offset'] = $m[1]/100;
668 if ($stop['offset']>1) { unset($stop['offset']); }
669 }
670 else if (isset($el[1]) && preg_match('/([0-9.]+(px|em|ex|pc|pt|cm|mm|in))/i',$el[1],$m)) {
671 $tmp = $this->mpdf->ConvertSize($m[1],$this->mpdf->w,$this->mpdf->FontSize,false);
672 $stop['offset'] = $el[1];
673 }
674 $g['stops'][] = $stop;
675 }
676 if (count($g['stops'] )) { return $g; }
677 }
678 return array();
679 }
680
681 function parseBackgroundGradient($bg) {
682 // background-gradient: linear #00FFFF #FFFF00 0 0.5 1 0.5; or
683 // background-gradient: radial #00FFFF #FFFF00 0.5 0.5 1 1 1.2;
684
685 $v = trim($bg);
686 $bgr = preg_split('/\s+/',$v);
687 $g = array();
688 if (count($bgr)> 6) {
689 if (strtoupper(substr($bgr[0],0,1)) == 'L' && count($bgr)==7) { // linear
690 $g['type'] = 2;
691 //$coords = array(0,0,1,1 ); // 0 0 1 0 or 0 1 1 1 is L 2 R; 1,1,0,1 is R2L; 1,1,1,0 is T2B; 1,0,1,1 is B2T
692 // Linear: $coords - array of the form (x1, y1, x2, y2) which defines the gradient vector (see linear_gradient_coords.jpg).
693 // The default value is from left to right (x1=0, y1=0, x2=1, y2=0).
694 $g['coords'] = array($bgr[3], $bgr[4], $bgr[5], $bgr[6]);
695 }
696 else if (count($bgr)==8) { // radial
697 $g['type'] = 3;
698 // Radial: $coords - array of the form (fx, fy, cx, cy, r) where (fx, fy) is the starting point of the gradient with color1,
699 // (cx, cy) is the center of the circle with color2, and r is the radius of the circle (see radial_gradient_coords.jpg).
700 // (fx, fy) should be inside the circle, otherwise some areas will not be defined
701 $g['coords'] = array($bgr[3], $bgr[4], $bgr[5], $bgr[6], $bgr[7]);
702 }
703 $g['colorspace'] = 'RGB';
704 // mPDF 5.3.74
705 $cor = $this->mpdf->ConvertColor($bgr[1]);
706 if ($cor{0}==1) $g['colorspace'] = 'Gray';
707 else if ($cor{0}==4 || $cor{0}==6) $g['colorspace'] = 'CMYK';
708 if ($cor) { $g['col'] = $cor; }
709 else { $g['col'] = $this->mpdf->ConvertColor(255); }
710 $cor = $this->mpdf->ConvertColor($bgr[2]);
711 if ($cor) { $g['col2'] = $cor; }
712 else { $g['col2'] = $this->mpdf->ConvertColor(255); }
713 $g['extend'] = array('true','true');
714 $g['stops'] = array(array('col'=>$g['col'], 'opacity'=>1, 'offset'=>0), array('col'=>$g['col2'], 'opacity'=>1, 'offset'=>1));
715 return $g;
716 }
717 return false;
718 }
719
720
721
722 }
723
724 ?>