]> git.immae.eu Git - github/wallabag/wallabag.git/blob - inc/3rdparty/libraries/mpdf/classes/wmf.php
add pdf and mobi libraries
[github/wallabag/wallabag.git] / inc / 3rdparty / libraries / mpdf / classes / wmf.php
1 <?php
2
3 class wmf {
4
5 var $mpdf = null;
6 var $gdiObjectArray;
7
8 function wmf(&$mpdf) {
9 $this->mpdf = $mpdf;
10 }
11
12
13 function _getWMFimage($data) {
14 $k = _MPDFK;
15
16 $this->gdiObjectArray = array();
17 $a=unpack('stest',"\1\0");
18 if ($a['test']!=1)
19 return array(0, 'Error parsing WMF image - Big-endian architecture not supported');
20 // check for Aldus placeable metafile header
21 $key = unpack('Lmagic', substr($data, 0, 4));
22 $p = 18; // WMF header
23 if ($key['magic'] == (int)0x9AC6CDD7) { $p +=22; } // Aldus header
24 // define some state variables
25 $wo=null; // window origin
26 $we=null; // window extent
27 $polyFillMode = 0;
28 $nullPen = false;
29 $nullBrush = false;
30 $endRecord = false;
31 $wmfdata = '';
32 while ($p < strlen($data) && !$endRecord) {
33 $recordInfo = unpack('Lsize/Sfunc', substr($data, $p, 6)); $p += 6;
34 // size of record given in WORDs (= 2 bytes)
35 $size = $recordInfo['size'];
36 // func is number of GDI function
37 $func = $recordInfo['func'];
38 if ($size > 3) {
39 $parms = substr($data, $p, 2*($size-3)); $p += 2*($size-3);
40 }
41 switch ($func) {
42 case 0x020b: // SetWindowOrg
43 // do not allow window origin to be changed
44 // after drawing has begun
45 if (!$wmfdata)
46 $wo = array_reverse(unpack('s2', $parms));
47 break;
48 case 0x020c: // SetWindowExt
49 // do not allow window extent to be changed
50 // after drawing has begun
51 if (!$wmfdata)
52 $we = array_reverse(unpack('s2', $parms));
53 break;
54 case 0x02fc: // CreateBrushIndirect
55 $brush = unpack('sstyle/Cr/Cg/Cb/Ca/Shatch', $parms);
56 $brush['type'] = 'B';
57 $this->_AddGDIObject($brush);
58 break;
59 case 0x02fa: // CreatePenIndirect
60 $pen = unpack('Sstyle/swidth/sdummy/Cr/Cg/Cb/Ca', $parms);
61 // convert width from twips to user unit
62 $pen['width'] /= (20 * $k);
63 $pen['type'] = 'P';
64 $this->_AddGDIObject($pen);
65 break;
66
67 // MUST create other GDI objects even if we don't handle them
68 case 0x06fe: // CreateBitmap
69 case 0x02fd: // CreateBitmapIndirect
70 case 0x00f8: // CreateBrush
71 case 0x02fb: // CreateFontIndirect
72 case 0x00f7: // CreatePalette
73 case 0x01f9: // CreatePatternBrush
74 case 0x06ff: // CreateRegion
75 case 0x0142: // DibCreatePatternBrush
76 $dummyObject = array('type'=>'D');
77 $this->_AddGDIObject($dummyObject);
78 break;
79 case 0x0106: // SetPolyFillMode
80 $polyFillMode = unpack('smode', $parms);
81 $polyFillMode = $polyFillMode['mode'];
82 break;
83 case 0x01f0: // DeleteObject
84 $idx = unpack('Sidx', $parms);
85 $idx = $idx['idx'];
86 $this->_DeleteGDIObject($idx);
87 break;
88 case 0x012d: // SelectObject
89 $idx = unpack('Sidx', $parms);
90 $idx = $idx['idx'];
91 $obj = $this->_GetGDIObject($idx);
92 switch ($obj['type']) {
93 case 'B':
94 $nullBrush = false;
95 if ($obj['style'] == 1) { $nullBrush = true; }
96 else {
97 $wmfdata .= $this->mpdf->SetFColor($this->mpdf->ConvertColor('rgb('.$obj['r'].','.$obj['g'].','.$obj['b'].')'), true)."\n";
98 }
99 break;
100 case 'P':
101 $nullPen = false;
102 $dashArray = array();
103 // dash parameters are custom
104 switch ($obj['style']) {
105 case 0: // PS_SOLID
106 break;
107 case 1: // PS_DASH
108 $dashArray = array(3,1);
109 break;
110 case 2: // PS_DOT
111 $dashArray = array(0.5,0.5);
112 break;
113 case 3: // PS_DASHDOT
114 $dashArray = array(2,1,0.5,1);
115 break;
116 case 4: // PS_DASHDOTDOT
117 $dashArray = array(2,1,0.5,1,0.5,1);
118 break;
119 case 5: // PS_NULL
120 $nullPen = true;
121 break;
122 }
123 if (!$nullPen) {
124 $wmfdata .= $this->mpdf->SetDColor($this->mpdf->ConvertColor('rgb('.$obj['r'].','.$obj['g'].','.$obj['b'].')'), true)."\n";
125 $wmfdata .= sprintf("%.3F w\n",$obj['width']*$k);
126 }
127 if (!empty($dashArray)) {
128 $s = '[';
129 for ($i=0; $i<count($dashArray);$i++) {
130 $s .= $dashArray[$i] * $k;
131 if ($i != count($dashArray)-1) { $s .= ' '; }
132 }
133 $s .= '] 0 d';
134 $wmfdata .= $s."\n";
135 }
136 break;
137 }
138 break;
139 case 0x0325: // Polyline
140 case 0x0324: // Polygon
141 $coords = unpack('s'.($size-3), $parms);
142 $numpoints = $coords[1];
143 for ($i = $numpoints; $i > 0; $i--) {
144 $px = $coords[2*$i];
145 $py = $coords[2*$i+1];
146
147 if ($i < $numpoints) { $wmfdata .= $this->_LineTo($px, $py); }
148 else { $wmfdata .= $this->_MoveTo($px, $py); }
149 }
150 if ($func == 0x0325) { $op = 's'; }
151 else if ($func == 0x0324) {
152 if ($nullPen) {
153 if ($nullBrush) { $op = 'n'; } // no op
154 else { $op = 'f'; } // fill
155 }
156 else {
157 if ($nullBrush) { $op = 's'; } // stroke
158 else { $op = 'b'; } // stroke and fill
159 }
160 if ($polyFillMode==1 && ($op=='b' || $op=='f')) { $op .= '*'; } // use even-odd fill rule
161 }
162 $wmfdata .= $op."\n";
163 break;
164 case 0x0538: // PolyPolygon
165 $coords = unpack('s'.($size-3), $parms);
166 $numpolygons = $coords[1];
167 $adjustment = $numpolygons;
168 for ($j = 1; $j <= $numpolygons; $j++) {
169 $numpoints = $coords[$j + 1];
170 for ($i = $numpoints; $i > 0; $i--) {
171 $px = $coords[2*$i + $adjustment];
172 $py = $coords[2*$i+1 + $adjustment];
173 if ($i == $numpoints) { $wmfdata .= $this->_MoveTo($px, $py); }
174 else { $wmfdata .= $this->_LineTo($px, $py); }
175 }
176 $adjustment += $numpoints * 2;
177 }
178
179 if ($nullPen) {
180 if ($nullBrush) { $op = 'n'; } // no op
181 else { $op = 'f'; } // fill
182 }
183 else {
184 if ($nullBrush) { $op = 's'; } // stroke
185 else { $op = 'b'; } // stroke and fill
186 }
187 if ($polyFillMode==1 && ($op=='b' || $op=='f')) { $op .= '*'; } // use even-odd fill rule
188 $wmfdata .= $op."\n";
189 break;
190 case 0x0000:
191 $endRecord = true;
192 break;
193 }
194 }
195
196
197 return array(1,$wmfdata,$wo,$we);
198 }
199
200
201 function _MoveTo($x, $y) {
202 return "$x $y m\n";
203 }
204
205 // a line must have been started using _MoveTo() first
206 function _LineTo($x, $y) {
207 return "$x $y l\n";
208 }
209
210 function _AddGDIObject($obj) {
211 // find next available slot
212 $idx = 0;
213 if (!empty($this->gdiObjectArray)) {
214 $empty = false;
215 $i = 0;
216 while (!$empty) {
217 $empty = !isset($this->gdiObjectArray[$i]);
218 $i++;
219 }
220 $idx = $i-1;
221 }
222 $this->gdiObjectArray[$idx] = $obj;
223 }
224
225 function _GetGDIObject($idx) {
226 return $this->gdiObjectArray[$idx];
227 }
228
229 function _DeleteGDIObject($idx) {
230 unset($this->gdiObjectArray[$idx]);
231 }
232
233
234 }
235
236 ?>