1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* @package dompdf |
4
|
|
|
* @link http://dompdf.github.com/ |
5
|
|
|
* @author Benj Carson <[email protected]> |
6
|
|
|
* @author Orion Richardson <[email protected]> |
7
|
|
|
* @author Helmut Tischer <[email protected]> |
8
|
|
|
* @author Fabien Ménager <[email protected]> |
9
|
|
|
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License |
10
|
|
|
*/ |
11
|
|
|
|
12
|
|
|
// FIXME: Need to sanity check inputs to this class |
13
|
|
|
namespace Dompdf\Adapter; |
14
|
|
|
|
15
|
|
|
use Dompdf\Canvas; |
16
|
|
|
use Dompdf\Dompdf; |
17
|
|
|
use Dompdf\Helpers; |
18
|
|
|
use Dompdf\Exception; |
19
|
|
|
use Dompdf\Image\Cache; |
20
|
|
|
use Dompdf\PhpEvaluator; |
21
|
|
|
|
22
|
|
|
/** |
23
|
|
|
* PDF rendering interface |
24
|
|
|
* |
25
|
|
|
* Dompdf\Adapter\CPDF provides a simple stateless interface to the stateful one |
26
|
|
|
* provided by the Cpdf class. |
27
|
|
|
* |
28
|
|
|
* Unless otherwise mentioned, all dimensions are in points (1/72 in). The |
29
|
|
|
* coordinate origin is in the top left corner, and y values increase |
30
|
|
|
* downwards. |
31
|
|
|
* |
32
|
|
|
* See {@link http://www.ros.co.nz/pdf/} for more complete documentation |
33
|
|
|
* on the underlying {@link Cpdf} class. |
34
|
|
|
* |
35
|
|
|
* @package dompdf |
36
|
|
|
*/ |
37
|
|
|
class CPDF implements Canvas |
38
|
|
|
{ |
39
|
|
|
|
40
|
|
|
/** |
41
|
|
|
* Dimensions of paper sizes in points |
42
|
|
|
* |
43
|
|
|
* @var array; |
44
|
|
|
*/ |
45
|
|
|
static $PAPER_SIZES = array( |
|
|
|
|
46
|
|
|
"4a0" => array(0, 0, 4767.87, 6740.79), |
47
|
|
|
"2a0" => array(0, 0, 3370.39, 4767.87), |
48
|
|
|
"a0" => array(0, 0, 2383.94, 3370.39), |
49
|
|
|
"a1" => array(0, 0, 1683.78, 2383.94), |
50
|
|
|
"a2" => array(0, 0, 1190.55, 1683.78), |
51
|
|
|
"a3" => array(0, 0, 841.89, 1190.55), |
52
|
|
|
"a4" => array(0, 0, 595.28, 841.89), |
53
|
|
|
"a5" => array(0, 0, 419.53, 595.28), |
54
|
|
|
"a6" => array(0, 0, 297.64, 419.53), |
55
|
|
|
"a7" => array(0, 0, 209.76, 297.64), |
56
|
|
|
"a8" => array(0, 0, 147.40, 209.76), |
57
|
|
|
"a9" => array(0, 0, 104.88, 147.40), |
58
|
|
|
"a10" => array(0, 0, 73.70, 104.88), |
59
|
|
|
"b0" => array(0, 0, 2834.65, 4008.19), |
60
|
|
|
"b1" => array(0, 0, 2004.09, 2834.65), |
61
|
|
|
"b2" => array(0, 0, 1417.32, 2004.09), |
62
|
|
|
"b3" => array(0, 0, 1000.63, 1417.32), |
63
|
|
|
"b4" => array(0, 0, 708.66, 1000.63), |
64
|
|
|
"b5" => array(0, 0, 498.90, 708.66), |
65
|
|
|
"b6" => array(0, 0, 354.33, 498.90), |
66
|
|
|
"b7" => array(0, 0, 249.45, 354.33), |
67
|
|
|
"b8" => array(0, 0, 175.75, 249.45), |
68
|
|
|
"b9" => array(0, 0, 124.72, 175.75), |
69
|
|
|
"b10" => array(0, 0, 87.87, 124.72), |
70
|
|
|
"c0" => array(0, 0, 2599.37, 3676.54), |
71
|
|
|
"c1" => array(0, 0, 1836.85, 2599.37), |
72
|
|
|
"c2" => array(0, 0, 1298.27, 1836.85), |
73
|
|
|
"c3" => array(0, 0, 918.43, 1298.27), |
74
|
|
|
"c4" => array(0, 0, 649.13, 918.43), |
75
|
|
|
"c5" => array(0, 0, 459.21, 649.13), |
76
|
|
|
"c6" => array(0, 0, 323.15, 459.21), |
77
|
|
|
"c7" => array(0, 0, 229.61, 323.15), |
78
|
|
|
"c8" => array(0, 0, 161.57, 229.61), |
79
|
|
|
"c9" => array(0, 0, 113.39, 161.57), |
80
|
|
|
"c10" => array(0, 0, 79.37, 113.39), |
81
|
|
|
"ra0" => array(0, 0, 2437.80, 3458.27), |
82
|
|
|
"ra1" => array(0, 0, 1729.13, 2437.80), |
83
|
|
|
"ra2" => array(0, 0, 1218.90, 1729.13), |
84
|
|
|
"ra3" => array(0, 0, 864.57, 1218.90), |
85
|
|
|
"ra4" => array(0, 0, 609.45, 864.57), |
86
|
|
|
"sra0" => array(0, 0, 2551.18, 3628.35), |
87
|
|
|
"sra1" => array(0, 0, 1814.17, 2551.18), |
88
|
|
|
"sra2" => array(0, 0, 1275.59, 1814.17), |
89
|
|
|
"sra3" => array(0, 0, 907.09, 1275.59), |
90
|
|
|
"sra4" => array(0, 0, 637.80, 907.09), |
91
|
|
|
"letter" => array(0, 0, 612.00, 792.00), |
92
|
|
|
"half-letter" => array(0, 0, 396.00, 612.00), |
93
|
|
|
"legal" => array(0, 0, 612.00, 1008.00), |
94
|
|
|
"ledger" => array(0, 0, 1224.00, 792.00), |
95
|
|
|
"tabloid" => array(0, 0, 792.00, 1224.00), |
96
|
|
|
"executive" => array(0, 0, 521.86, 756.00), |
97
|
|
|
"folio" => array(0, 0, 612.00, 936.00), |
98
|
|
|
"commercial #10 envelope" => array(0, 0, 684, 297), |
99
|
|
|
"catalog #10 1/2 envelope" => array(0, 0, 648, 864), |
100
|
|
|
"8.5x11" => array(0, 0, 612.00, 792.00), |
101
|
|
|
"8.5x14" => array(0, 0, 612.00, 1008.0), |
102
|
|
|
"11x17" => array(0, 0, 792.00, 1224.00), |
103
|
|
|
); |
104
|
|
|
|
105
|
|
|
/** |
106
|
|
|
* The Dompdf object |
107
|
|
|
* |
108
|
|
|
* @var Dompdf |
109
|
|
|
*/ |
110
|
|
|
private $_dompdf; |
111
|
|
|
|
112
|
|
|
/** |
113
|
|
|
* Instance of Cpdf class |
114
|
|
|
* |
115
|
|
|
* @var Cpdf |
116
|
|
|
*/ |
117
|
|
|
private $_pdf; |
118
|
|
|
|
119
|
|
|
/** |
120
|
|
|
* PDF width, in points |
121
|
|
|
* |
122
|
|
|
* @var float |
123
|
|
|
*/ |
124
|
|
|
private $_width; |
125
|
|
|
|
126
|
|
|
/** |
127
|
|
|
* PDF height, in points |
128
|
|
|
* |
129
|
|
|
* @var float; |
130
|
|
|
*/ |
131
|
|
|
private $_height; |
132
|
|
|
|
133
|
|
|
/** |
134
|
|
|
* Current page number |
135
|
|
|
* |
136
|
|
|
* @var int |
137
|
|
|
*/ |
138
|
|
|
private $_page_number; |
139
|
|
|
|
140
|
|
|
/** |
141
|
|
|
* Total number of pages |
142
|
|
|
* |
143
|
|
|
* @var int |
144
|
|
|
*/ |
145
|
|
|
private $_page_count; |
146
|
|
|
|
147
|
|
|
/** |
148
|
|
|
* Text to display on every page |
149
|
|
|
* |
150
|
|
|
* @var array |
151
|
|
|
*/ |
152
|
|
|
private $_page_text; |
153
|
|
|
|
154
|
|
|
/** |
155
|
|
|
* Array of pages for accesing after rendering is initially complete |
156
|
|
|
* |
157
|
|
|
* @var array |
158
|
|
|
*/ |
159
|
|
|
private $_pages; |
160
|
|
|
|
161
|
|
|
/** |
162
|
|
|
* Array of temporary cached images to be deleted when processing is complete |
163
|
|
|
* |
164
|
|
|
* @var array |
165
|
|
|
*/ |
166
|
|
|
private $_image_cache; |
167
|
|
|
|
168
|
|
|
/** |
169
|
|
|
* Currently-applied opacity level (0 - 1) |
170
|
|
|
* |
171
|
|
|
* @var float |
172
|
|
|
*/ |
173
|
|
|
private $_current_opacity = 1; |
174
|
|
|
|
175
|
|
|
/** |
176
|
|
|
* Class constructor |
177
|
|
|
* |
178
|
|
|
* @param mixed $paper The size of paper to use in this PDF ({@link CPDF::$PAPER_SIZES}) |
179
|
|
|
* @param string $orientation The orientation of the document (either 'landscape' or 'portrait') |
180
|
|
|
* @param Dompdf $dompdf The Dompdf instance |
181
|
|
|
*/ |
182
|
|
|
public function __construct($paper = "letter", $orientation = "portrait", Dompdf $dompdf) |
183
|
|
|
{ |
184
|
|
View Code Duplication |
if (is_array($paper)) { |
|
|
|
|
185
|
|
|
$size = $paper; |
186
|
|
|
} else if (isset(self::$PAPER_SIZES[mb_strtolower($paper)])) { |
187
|
|
|
$size = self::$PAPER_SIZES[mb_strtolower($paper)]; |
188
|
|
|
} else { |
189
|
|
|
$size = self::$PAPER_SIZES["letter"]; |
190
|
|
|
} |
191
|
|
|
|
192
|
|
View Code Duplication |
if (mb_strtolower($orientation) === "landscape") { |
|
|
|
|
193
|
|
|
list($size[2], $size[3]) = array($size[3], $size[2]); |
194
|
|
|
} |
195
|
|
|
|
196
|
|
|
$this->_dompdf = $dompdf; |
197
|
|
|
|
198
|
|
|
$this->_pdf = new \Cpdf( |
|
|
|
|
199
|
|
|
$size, |
200
|
|
|
true, |
201
|
|
|
$dompdf->getOptions()->getFontCache(), |
202
|
|
|
$dompdf->getOptions()->getTempDir() |
203
|
|
|
); |
204
|
|
|
|
205
|
|
|
$this->_pdf->addInfo("Producer", sprintf("%s + CPDF", $dompdf->version)); |
|
|
|
|
206
|
|
|
$time = substr_replace(date('YmdHisO'), '\'', -2, 0) . '\''; |
207
|
|
|
$this->_pdf->addInfo("CreationDate", "D:$time"); |
208
|
|
|
$this->_pdf->addInfo("ModDate", "D:$time"); |
209
|
|
|
|
210
|
|
|
$this->_width = $size[2] - $size[0]; |
|
|
|
|
211
|
|
|
$this->_height = $size[3] - $size[1]; |
212
|
|
|
|
213
|
|
|
$this->_page_number = $this->_page_count = 1; |
214
|
|
|
$this->_page_text = array(); |
215
|
|
|
|
216
|
|
|
$this->_pages = array($this->_pdf->getFirstPageId()); |
217
|
|
|
|
218
|
|
|
$this->_image_cache = array(); |
219
|
|
|
} |
220
|
|
|
|
221
|
|
|
/** |
222
|
|
|
* @return Dompdf |
223
|
|
|
*/ |
224
|
|
|
public function get_dompdf() |
225
|
|
|
{ |
226
|
|
|
return $this->_dompdf; |
227
|
|
|
} |
228
|
|
|
|
229
|
|
|
/** |
230
|
|
|
* Class destructor |
231
|
|
|
* |
232
|
|
|
* Deletes all temporary image files |
233
|
|
|
*/ |
234
|
|
|
public function __destruct() |
235
|
|
|
{ |
236
|
|
|
foreach ($this->_image_cache as $img) { |
237
|
|
|
// The file might be already deleted by 3rd party tmp cleaner, |
238
|
|
|
// the file might not have been created at all |
239
|
|
|
// (if image outputting commands failed) |
240
|
|
|
// or because the destructor was called twice accidentally. |
241
|
|
|
if (!file_exists($img)) { |
242
|
|
|
continue; |
243
|
|
|
} |
244
|
|
|
|
245
|
|
|
if ($this->_dompdf->getOptions()->getDebugPng()) { |
246
|
|
|
print '[__destruct unlink ' . $img . ']'; |
247
|
|
|
} |
248
|
|
|
if (!$this->_dompdf->getOptions()->getDebugKeepTemp()) { |
249
|
|
|
unlink($img); |
250
|
|
|
} |
251
|
|
|
} |
252
|
|
|
} |
253
|
|
|
|
254
|
|
|
/** |
255
|
|
|
* Returns the Cpdf instance |
256
|
|
|
* |
257
|
|
|
* @return \Cpdf |
258
|
|
|
*/ |
259
|
|
|
public function get_cpdf() |
260
|
|
|
{ |
261
|
|
|
return $this->_pdf; |
262
|
|
|
} |
263
|
|
|
|
264
|
|
|
/** |
265
|
|
|
* Add meta information to the PDF |
266
|
|
|
* |
267
|
|
|
* @param string $label label of the value (Creator, Producer, etc.) |
268
|
|
|
* @param string $value the text to set |
269
|
|
|
*/ |
270
|
|
|
public function add_info($label, $value) |
271
|
|
|
{ |
272
|
|
|
$this->_pdf->addInfo($label, $value); |
|
|
|
|
273
|
|
|
} |
274
|
|
|
|
275
|
|
|
/** |
276
|
|
|
* Opens a new 'object' |
277
|
|
|
* |
278
|
|
|
* While an object is open, all drawing actions are recored in the object, |
279
|
|
|
* as opposed to being drawn on the current page. Objects can be added |
280
|
|
|
* later to a specific page or to several pages. |
281
|
|
|
* |
282
|
|
|
* The return value is an integer ID for the new object. |
283
|
|
|
* |
284
|
|
|
* @see CPDF::close_object() |
285
|
|
|
* @see CPDF::add_object() |
286
|
|
|
* |
287
|
|
|
* @return int |
288
|
|
|
*/ |
289
|
|
|
public function open_object() |
290
|
|
|
{ |
291
|
|
|
$ret = $this->_pdf->openObject(); |
|
|
|
|
292
|
|
|
$this->_pdf->saveState(); |
|
|
|
|
293
|
|
|
return $ret; |
294
|
|
|
} |
295
|
|
|
|
296
|
|
|
/** |
297
|
|
|
* Reopens an existing 'object' |
298
|
|
|
* |
299
|
|
|
* @see CPDF::open_object() |
300
|
|
|
* @param int $object the ID of a previously opened object |
301
|
|
|
*/ |
302
|
|
|
public function reopen_object($object) |
303
|
|
|
{ |
304
|
|
|
$this->_pdf->reopenObject($object); |
|
|
|
|
305
|
|
|
$this->_pdf->saveState(); |
|
|
|
|
306
|
|
|
} |
307
|
|
|
|
308
|
|
|
/** |
309
|
|
|
* Closes the current 'object' |
310
|
|
|
* |
311
|
|
|
* @see CPDF::open_object() |
312
|
|
|
*/ |
313
|
|
|
public function close_object() |
314
|
|
|
{ |
315
|
|
|
$this->_pdf->restoreState(); |
|
|
|
|
316
|
|
|
$this->_pdf->closeObject(); |
|
|
|
|
317
|
|
|
} |
318
|
|
|
|
319
|
|
|
/** |
320
|
|
|
* Adds a specified 'object' to the document |
321
|
|
|
* |
322
|
|
|
* $object int specifying an object created with {@link |
323
|
|
|
* CPDF::open_object()}. $where can be one of: |
324
|
|
|
* - 'add' add to current page only |
325
|
|
|
* - 'all' add to every page from the current one onwards |
326
|
|
|
* - 'odd' add to all odd numbered pages from now on |
327
|
|
|
* - 'even' add to all even numbered pages from now on |
328
|
|
|
* - 'next' add the object to the next page only |
329
|
|
|
* - 'nextodd' add to all odd numbered pages from the next one |
330
|
|
|
* - 'nexteven' add to all even numbered pages from the next one |
331
|
|
|
* |
332
|
|
|
* @see Cpdf::addObject() |
333
|
|
|
* |
334
|
|
|
* @param int $object |
335
|
|
|
* @param string $where |
336
|
|
|
*/ |
337
|
|
|
public function add_object($object, $where = 'all') |
338
|
|
|
{ |
339
|
|
|
$this->_pdf->addObject($object, $where); |
|
|
|
|
340
|
|
|
} |
341
|
|
|
|
342
|
|
|
/** |
343
|
|
|
* Stops the specified 'object' from appearing in the document. |
344
|
|
|
* |
345
|
|
|
* The object will stop being displayed on the page following the current |
346
|
|
|
* one. |
347
|
|
|
* |
348
|
|
|
* @param int $object |
349
|
|
|
*/ |
350
|
|
|
public function stop_object($object) |
351
|
|
|
{ |
352
|
|
|
$this->_pdf->stopObject($object); |
|
|
|
|
353
|
|
|
} |
354
|
|
|
|
355
|
|
|
/** |
356
|
|
|
* @access private |
357
|
|
|
*/ |
358
|
|
|
public function serialize_object($id) |
359
|
|
|
{ |
360
|
|
|
// Serialize the pdf object's current state for retrieval later |
361
|
|
|
return $this->_pdf->serializeObject($id); |
|
|
|
|
362
|
|
|
} |
363
|
|
|
|
364
|
|
|
/** |
365
|
|
|
* @access private |
366
|
|
|
*/ |
367
|
|
|
public function reopen_serialized_object($obj) |
368
|
|
|
{ |
369
|
|
|
return $this->_pdf->restoreSerializedObject($obj); |
|
|
|
|
370
|
|
|
} |
371
|
|
|
|
372
|
|
|
//........................................................................ |
|
|
|
|
373
|
|
|
|
374
|
|
|
/** |
375
|
|
|
* Returns the PDF's width in points |
376
|
|
|
* @return float |
377
|
|
|
*/ |
378
|
|
|
public function get_width() |
379
|
|
|
{ |
380
|
|
|
return $this->_width; |
381
|
|
|
} |
382
|
|
|
|
383
|
|
|
/** |
384
|
|
|
* Returns the PDF's height in points |
385
|
|
|
* @return float |
386
|
|
|
*/ |
387
|
|
|
public function get_height() |
388
|
|
|
{ |
389
|
|
|
return $this->_height; |
390
|
|
|
} |
391
|
|
|
|
392
|
|
|
/** |
393
|
|
|
* Returns the current page number |
394
|
|
|
* @return int |
395
|
|
|
*/ |
396
|
|
|
public function get_page_number() |
397
|
|
|
{ |
398
|
|
|
return $this->_page_number; |
399
|
|
|
} |
400
|
|
|
|
401
|
|
|
/** |
402
|
|
|
* Returns the total number of pages in the document |
403
|
|
|
* @return int |
404
|
|
|
*/ |
405
|
|
|
public function get_page_count() |
406
|
|
|
{ |
407
|
|
|
return $this->_page_count; |
408
|
|
|
} |
409
|
|
|
|
410
|
|
|
/** |
411
|
|
|
* Sets the current page number |
412
|
|
|
* |
413
|
|
|
* @param int $num |
414
|
|
|
*/ |
415
|
|
|
public function set_page_number($num) |
416
|
|
|
{ |
417
|
|
|
$this->_page_number = $num; |
418
|
|
|
} |
419
|
|
|
|
420
|
|
|
/** |
421
|
|
|
* Sets the page count |
422
|
|
|
* |
423
|
|
|
* @param int $count |
424
|
|
|
*/ |
425
|
|
|
public function set_page_count($count) |
426
|
|
|
{ |
427
|
|
|
$this->_page_count = $count; |
428
|
|
|
} |
429
|
|
|
|
430
|
|
|
/** |
431
|
|
|
* Sets the stroke color |
432
|
|
|
* |
433
|
|
|
* See {@link Style::set_color()} for the format of the color array. |
434
|
|
|
* @param array $color |
435
|
|
|
*/ |
436
|
|
View Code Duplication |
protected function _set_stroke_color($color) |
|
|
|
|
437
|
|
|
{ |
438
|
|
|
$this->_pdf->setStrokeColor($color); |
|
|
|
|
439
|
|
|
$alpha = isset($color["alpha"]) ? $color["alpha"] : 1; |
440
|
|
|
if ($this->_current_opacity != 1) { |
441
|
|
|
$alpha *= $this->_current_opacity; |
442
|
|
|
} |
443
|
|
|
$this->_set_line_transparency("Normal", $alpha); |
444
|
|
|
} |
445
|
|
|
|
446
|
|
|
/** |
447
|
|
|
* Sets the fill colour |
448
|
|
|
* |
449
|
|
|
* See {@link Style::set_color()} for the format of the colour array. |
450
|
|
|
* @param array $color |
451
|
|
|
*/ |
452
|
|
View Code Duplication |
protected function _set_fill_color($color) |
|
|
|
|
453
|
|
|
{ |
454
|
|
|
$this->_pdf->setColor($color); |
|
|
|
|
455
|
|
|
$alpha = isset($color["alpha"]) ? $color["alpha"] : 1; |
456
|
|
|
if ($this->_current_opacity) { |
457
|
|
|
$alpha *= $this->_current_opacity; |
458
|
|
|
} |
459
|
|
|
$this->_set_fill_transparency("Normal", $alpha); |
460
|
|
|
} |
461
|
|
|
|
462
|
|
|
/** |
463
|
|
|
* Sets line transparency |
464
|
|
|
* @see Cpdf::setLineTransparency() |
465
|
|
|
* |
466
|
|
|
* Valid blend modes are (case-sensitive): |
467
|
|
|
* |
468
|
|
|
* Normal, Multiply, Screen, Overlay, Darken, Lighten, |
469
|
|
|
* ColorDodge, ColorBurn, HardLight, SoftLight, Difference, |
470
|
|
|
* Exclusion |
471
|
|
|
* |
472
|
|
|
* @param string $mode the blending mode to use |
473
|
|
|
* @param float $opacity 0.0 fully transparent, 1.0 fully opaque |
474
|
|
|
*/ |
475
|
|
|
protected function _set_line_transparency($mode, $opacity) |
476
|
|
|
{ |
477
|
|
|
$this->_pdf->setLineTransparency($mode, $opacity); |
|
|
|
|
478
|
|
|
} |
479
|
|
|
|
480
|
|
|
/** |
481
|
|
|
* Sets fill transparency |
482
|
|
|
* @see Cpdf::setFillTransparency() |
483
|
|
|
* |
484
|
|
|
* Valid blend modes are (case-sensitive): |
485
|
|
|
* |
486
|
|
|
* Normal, Multiply, Screen, Overlay, Darken, Lighten, |
487
|
|
|
* ColorDogde, ColorBurn, HardLight, SoftLight, Difference, |
488
|
|
|
* Exclusion |
489
|
|
|
* |
490
|
|
|
* @param string $mode the blending mode to use |
491
|
|
|
* @param float $opacity 0.0 fully transparent, 1.0 fully opaque |
492
|
|
|
*/ |
493
|
|
|
protected function _set_fill_transparency($mode, $opacity) |
494
|
|
|
{ |
495
|
|
|
$this->_pdf->setFillTransparency($mode, $opacity); |
|
|
|
|
496
|
|
|
} |
497
|
|
|
|
498
|
|
|
/** |
499
|
|
|
* Sets the line style |
500
|
|
|
* |
501
|
|
|
* @see Cpdf::setLineStyle() |
502
|
|
|
* |
503
|
|
|
* @param float $width |
504
|
|
|
* @param string $cap |
505
|
|
|
* @param string $join |
506
|
|
|
* @param array $dash |
507
|
|
|
*/ |
508
|
|
|
protected function _set_line_style($width, $cap, $join, $dash) |
509
|
|
|
{ |
510
|
|
|
$this->_pdf->setLineStyle($width, $cap, $join, $dash); |
|
|
|
|
511
|
|
|
} |
512
|
|
|
|
513
|
|
|
/** |
514
|
|
|
* Sets the opacity |
515
|
|
|
* |
516
|
|
|
* @param $opacity |
517
|
|
|
* @param $mode |
518
|
|
|
*/ |
519
|
|
|
public function set_opacity($opacity, $mode = "Normal") |
520
|
|
|
{ |
521
|
|
|
$this->_set_line_transparency($mode, $opacity); |
522
|
|
|
$this->_set_fill_transparency($mode, $opacity); |
523
|
|
|
$this->_current_opacity = $opacity; |
524
|
|
|
} |
525
|
|
|
|
526
|
|
|
public function set_default_view($view, $options = array()) |
527
|
|
|
{ |
528
|
|
|
array_unshift($options, $view); |
529
|
|
|
call_user_func_array(array($this->_pdf, "openHere"), $options); |
530
|
|
|
} |
531
|
|
|
|
532
|
|
|
/** |
533
|
|
|
* Remaps y coords from 4th to 1st quadrant |
534
|
|
|
* |
535
|
|
|
* @param float $y |
536
|
|
|
* @return float |
537
|
|
|
*/ |
538
|
|
|
protected function y($y) |
539
|
|
|
{ |
540
|
|
|
return $this->_height - $y; |
541
|
|
|
} |
542
|
|
|
|
543
|
|
|
/** |
544
|
|
|
* Canvas implementation |
545
|
|
|
* |
546
|
|
|
* @param float $x1 |
547
|
|
|
* @param float $y1 |
548
|
|
|
* @param float $x2 |
549
|
|
|
* @param float $y2 |
550
|
|
|
* @param array $color |
551
|
|
|
* @param float $width |
552
|
|
|
* @param array $style |
553
|
|
|
*/ |
554
|
|
|
public function line($x1, $y1, $x2, $y2, $color, $width, $style = array()) |
555
|
|
|
{ |
556
|
|
|
$this->_set_stroke_color($color); |
557
|
|
|
$this->_set_line_style($width, "butt", "", $style); |
558
|
|
|
|
559
|
|
|
$this->_pdf->line($x1, $this->y($y1), |
|
|
|
|
560
|
|
|
$x2, $this->y($y2)); |
561
|
|
|
$this->_set_line_transparency("Normal", $this->_current_opacity); |
562
|
|
|
} |
563
|
|
|
|
564
|
|
|
/** |
565
|
|
|
* Draw line at the specified coordinates on every page. |
566
|
|
|
* |
567
|
|
|
* See {@link Style::munge_color()} for the format of the colour array. |
568
|
|
|
* |
569
|
|
|
* @param float $x1 |
570
|
|
|
* @param float $y1 |
571
|
|
|
* @param float $x2 |
572
|
|
|
* @param float $y2 |
573
|
|
|
* @param array $color |
574
|
|
|
* @param float $width |
575
|
|
|
* @param array $style optional |
576
|
|
|
*/ |
577
|
|
|
public function page_line($x1, $y1, $x2, $y2, $color, $width, $style = array()) |
578
|
|
|
{ |
579
|
|
|
$_t = 'line'; |
580
|
|
|
$this->_page_text[] = compact('_t', 'x1', 'y1', 'x2', 'y2', 'color', 'width', 'style'); |
581
|
|
|
} |
582
|
|
|
|
583
|
|
|
/** |
584
|
|
|
* @param float $x |
585
|
|
|
* @param float $y |
586
|
|
|
* @param float $r1 |
587
|
|
|
* @param float $r2 |
588
|
|
|
* @param float $astart |
589
|
|
|
* @param float $aend |
590
|
|
|
* @param array $color |
591
|
|
|
* @param float $width |
592
|
|
|
* @param array $style |
593
|
|
|
*/ |
594
|
|
|
public function arc($x, $y, $r1, $r2, $astart, $aend, $color, $width, $style = array()) |
595
|
|
|
{ |
596
|
|
|
$this->_set_stroke_color($color); |
597
|
|
|
$this->_set_line_style($width, "butt", "", $style); |
598
|
|
|
|
599
|
|
|
$this->_pdf->ellipse($x, $this->y($y), $r1, $r2, 0, 8, $astart, $aend, false, false, true, false); |
|
|
|
|
600
|
|
|
$this->_set_line_transparency("Normal", $this->_current_opacity); |
601
|
|
|
} |
602
|
|
|
|
603
|
|
|
/** |
604
|
|
|
* Convert a GIF or BMP image to a PNG image |
605
|
|
|
* |
606
|
|
|
* @param string $image_url |
607
|
|
|
* @param integer $type |
608
|
|
|
* |
609
|
|
|
* @throws Exception |
610
|
|
|
* @return string The url of the newly converted image |
611
|
|
|
*/ |
612
|
|
|
protected function _convert_gif_bmp_to_png($image_url, $type) |
613
|
|
|
{ |
614
|
|
|
$func_name = "imagecreatefrom$type"; |
615
|
|
|
|
616
|
|
View Code Duplication |
if (!function_exists($func_name)) { |
|
|
|
|
617
|
|
|
if (!method_exists("Dompdf\Helpers", $func_name)) { |
618
|
|
|
throw new Exception("Function $func_name() not found. Cannot convert $type image: $image_url. Please install the image PHP extension."); |
619
|
|
|
} |
620
|
|
|
$func_name = "\\Dompdf\\Helpers::" . $func_name; |
621
|
|
|
} |
622
|
|
|
|
623
|
|
|
set_error_handler(array("\\Dompdf\\Helpers", "record_warnings")); |
624
|
|
|
$im = call_user_func($func_name, $image_url); |
625
|
|
|
|
626
|
|
|
if ($im) { |
627
|
|
|
imageinterlace($im, false); |
628
|
|
|
|
629
|
|
|
$tmp_dir = $this->_dompdf->getOptions()->getTempDir(); |
630
|
|
|
$tmp_name = tempnam($tmp_dir, "{$type}dompdf_img_"); |
631
|
|
|
@unlink($tmp_name); |
|
|
|
|
632
|
|
|
$filename = "$tmp_name.png"; |
633
|
|
|
$this->_image_cache[] = $filename; |
634
|
|
|
|
635
|
|
|
imagepng($im, $filename); |
636
|
|
|
imagedestroy($im); |
637
|
|
|
} else { |
638
|
|
|
$filename = Cache::$broken_image; |
639
|
|
|
} |
640
|
|
|
|
641
|
|
|
restore_error_handler(); |
642
|
|
|
|
643
|
|
|
return $filename; |
644
|
|
|
} |
645
|
|
|
|
646
|
|
|
/** |
647
|
|
|
* @param float $x1 |
648
|
|
|
* @param float $y1 |
649
|
|
|
* @param float $w |
650
|
|
|
* @param float $h |
651
|
|
|
* @param array $color |
652
|
|
|
* @param float $width |
653
|
|
|
* @param array $style |
654
|
|
|
*/ |
655
|
|
|
public function rectangle($x1, $y1, $w, $h, $color, $width, $style = array()) |
656
|
|
|
{ |
657
|
|
|
$this->_set_stroke_color($color); |
658
|
|
|
$this->_set_line_style($width, "butt", "", $style); |
659
|
|
|
$this->_pdf->rectangle($x1, $this->y($y1) - $h, $w, $h); |
|
|
|
|
660
|
|
|
$this->_set_line_transparency("Normal", $this->_current_opacity); |
661
|
|
|
} |
662
|
|
|
|
663
|
|
|
/** |
664
|
|
|
* @param float $x1 |
665
|
|
|
* @param float $y1 |
666
|
|
|
* @param float $w |
667
|
|
|
* @param float $h |
668
|
|
|
* @param array $color |
669
|
|
|
*/ |
670
|
|
|
public function filled_rectangle($x1, $y1, $w, $h, $color) |
671
|
|
|
{ |
672
|
|
|
$this->_set_fill_color($color); |
673
|
|
|
$this->_pdf->filledRectangle($x1, $this->y($y1) - $h, $w, $h); |
|
|
|
|
674
|
|
|
$this->_set_fill_transparency("Normal", $this->_current_opacity); |
675
|
|
|
} |
676
|
|
|
|
677
|
|
|
/** |
678
|
|
|
* @param float $x1 |
679
|
|
|
* @param float $y1 |
680
|
|
|
* @param float $w |
681
|
|
|
* @param float $h |
682
|
|
|
*/ |
683
|
|
|
public function clipping_rectangle($x1, $y1, $w, $h) |
684
|
|
|
{ |
685
|
|
|
$this->_pdf->clippingRectangle($x1, $this->y($y1) - $h, $w, $h); |
|
|
|
|
686
|
|
|
} |
687
|
|
|
|
688
|
|
|
/** |
689
|
|
|
* @param float $x1 |
690
|
|
|
* @param float $y1 |
691
|
|
|
* @param float $w |
692
|
|
|
* @param float $h |
693
|
|
|
* @param float $rTL |
694
|
|
|
* @param float $rTR |
695
|
|
|
* @param float $rBR |
696
|
|
|
* @param float $rBL |
697
|
|
|
*/ |
698
|
|
|
public function clipping_roundrectangle($x1, $y1, $w, $h, $rTL, $rTR, $rBR, $rBL) |
699
|
|
|
{ |
700
|
|
|
$this->_pdf->clippingRectangleRounded($x1, $this->y($y1) - $h, $w, $h, $rTL, $rTR, $rBR, $rBL); |
|
|
|
|
701
|
|
|
} |
702
|
|
|
|
703
|
|
|
/** |
704
|
|
|
* |
705
|
|
|
*/ |
706
|
|
|
public function clipping_end() |
707
|
|
|
{ |
708
|
|
|
$this->_pdf->clippingEnd(); |
|
|
|
|
709
|
|
|
} |
710
|
|
|
|
711
|
|
|
/** |
712
|
|
|
* |
713
|
|
|
*/ |
714
|
|
|
public function save() |
715
|
|
|
{ |
716
|
|
|
$this->_pdf->saveState(); |
|
|
|
|
717
|
|
|
} |
718
|
|
|
|
719
|
|
|
/** |
720
|
|
|
* |
721
|
|
|
*/ |
722
|
|
|
public function restore() |
723
|
|
|
{ |
724
|
|
|
$this->_pdf->restoreState(); |
|
|
|
|
725
|
|
|
} |
726
|
|
|
|
727
|
|
|
/** |
728
|
|
|
* @param $angle |
729
|
|
|
* @param $x |
730
|
|
|
* @param $y |
731
|
|
|
*/ |
732
|
|
|
public function rotate($angle, $x, $y) |
733
|
|
|
{ |
734
|
|
|
$this->_pdf->rotate($angle, $x, $y); |
735
|
|
|
} |
736
|
|
|
|
737
|
|
|
/** |
738
|
|
|
* @param $angle_x |
739
|
|
|
* @param $angle_y |
740
|
|
|
* @param $x |
741
|
|
|
* @param $y |
742
|
|
|
*/ |
743
|
|
|
public function skew($angle_x, $angle_y, $x, $y) |
744
|
|
|
{ |
745
|
|
|
$this->_pdf->skew($angle_x, $angle_y, $x, $y); |
746
|
|
|
} |
747
|
|
|
|
748
|
|
|
/** |
749
|
|
|
* @param $s_x |
750
|
|
|
* @param $s_y |
751
|
|
|
* @param $x |
752
|
|
|
* @param $y |
753
|
|
|
*/ |
754
|
|
|
public function scale($s_x, $s_y, $x, $y) |
755
|
|
|
{ |
756
|
|
|
$this->_pdf->scale($s_x, $s_y, $x, $y); |
757
|
|
|
} |
758
|
|
|
|
759
|
|
|
/** |
760
|
|
|
* @param $t_x |
761
|
|
|
* @param $t_y |
762
|
|
|
*/ |
763
|
|
|
public function translate($t_x, $t_y) |
764
|
|
|
{ |
765
|
|
|
$this->_pdf->translate($t_x, $t_y); |
766
|
|
|
} |
767
|
|
|
|
768
|
|
|
/** |
769
|
|
|
* @param $a |
770
|
|
|
* @param $b |
771
|
|
|
* @param $c |
772
|
|
|
* @param $d |
773
|
|
|
* @param $e |
774
|
|
|
* @param $f |
775
|
|
|
*/ |
776
|
|
|
public function transform($a, $b, $c, $d, $e, $f) |
777
|
|
|
{ |
778
|
|
|
$this->_pdf->transform(array($a, $b, $c, $d, $e, $f)); |
|
|
|
|
779
|
|
|
} |
780
|
|
|
|
781
|
|
|
/** |
782
|
|
|
* @param array $points |
783
|
|
|
* @param array $color |
784
|
|
|
* @param null $width |
785
|
|
|
* @param array $style |
786
|
|
|
* @param bool $fill |
787
|
|
|
*/ |
788
|
|
|
public function polygon($points, $color, $width = null, $style = array(), $fill = false) |
789
|
|
|
{ |
790
|
|
|
$this->_set_fill_color($color); |
791
|
|
|
$this->_set_stroke_color($color); |
792
|
|
|
|
793
|
|
|
// Adjust y values |
794
|
|
|
for ($i = 1; $i < count($points); $i += 2) { |
|
|
|
|
795
|
|
|
$points[$i] = $this->y($points[$i]); |
796
|
|
|
} |
797
|
|
|
|
798
|
|
|
$this->_pdf->polygon($points, count($points) / 2, $fill); |
|
|
|
|
799
|
|
|
|
800
|
|
|
$this->_set_fill_transparency("Normal", $this->_current_opacity); |
801
|
|
|
$this->_set_line_transparency("Normal", $this->_current_opacity); |
802
|
|
|
} |
803
|
|
|
|
804
|
|
|
/** |
805
|
|
|
* @param float $x |
806
|
|
|
* @param float $y |
807
|
|
|
* @param float $r1 |
808
|
|
|
* @param array $color |
809
|
|
|
* @param null $width |
810
|
|
|
* @param null $style |
811
|
|
|
* @param bool $fill |
812
|
|
|
*/ |
813
|
|
|
public function circle($x, $y, $r1, $color, $width = null, $style = null, $fill = false) |
814
|
|
|
{ |
815
|
|
|
$this->_set_fill_color($color); |
816
|
|
|
$this->_set_stroke_color($color); |
817
|
|
|
|
818
|
|
|
if (!$fill && isset($width)) { |
819
|
|
|
$this->_set_line_style($width, "round", "round", $style); |
|
|
|
|
820
|
|
|
} |
821
|
|
|
|
822
|
|
|
$this->_pdf->ellipse($x, $this->y($y), $r1, 0, 0, 8, 0, 360, 1, $fill); |
|
|
|
|
823
|
|
|
|
824
|
|
|
$this->_set_fill_transparency("Normal", $this->_current_opacity); |
825
|
|
|
$this->_set_line_transparency("Normal", $this->_current_opacity); |
826
|
|
|
} |
827
|
|
|
|
828
|
|
|
/** |
829
|
|
|
* @param string $img |
830
|
|
|
* @param float $x |
831
|
|
|
* @param float $y |
832
|
|
|
* @param int $w |
833
|
|
|
* @param int $h |
834
|
|
|
* @param string $resolution |
835
|
|
|
*/ |
836
|
|
|
public function image($img, $x, $y, $w, $h, $resolution = "normal") |
837
|
|
|
{ |
838
|
|
|
list($width, $height, $type) = Helpers::dompdf_getimagesize($img, $this->get_dompdf()->getHttpContext()); |
839
|
|
|
|
840
|
|
|
$debug_png = $this->_dompdf->getOptions()->getDebugPng(); |
841
|
|
|
|
842
|
|
|
if ($debug_png) { |
843
|
|
|
print "[image:$img|$width|$height|$type]"; |
844
|
|
|
} |
845
|
|
|
|
846
|
|
|
switch ($type) { |
847
|
|
View Code Duplication |
case "jpeg": |
|
|
|
|
848
|
|
|
if ($debug_png) { |
849
|
|
|
print '!!!jpg!!!'; |
850
|
|
|
} |
851
|
|
|
$this->_pdf->addJpegFromFile($img, $x, $this->y($y) - $h, $w, $h); |
|
|
|
|
852
|
|
|
break; |
853
|
|
|
|
854
|
|
|
case "gif": |
|
|
|
|
855
|
|
|
/** @noinspection PhpMissingBreakStatementInspection */ |
856
|
|
|
case "bmp": |
|
|
|
|
857
|
|
|
if ($debug_png) print '!!!bmp or gif!!!'; |
858
|
|
|
// @todo use cache for BMP and GIF |
859
|
|
|
$img = $this->_convert_gif_bmp_to_png($img, $type); |
860
|
|
|
|
861
|
|
View Code Duplication |
case "png": |
|
|
|
|
862
|
|
|
if ($debug_png) print '!!!png!!!'; |
863
|
|
|
|
864
|
|
|
$this->_pdf->addPngFromFile($img, $x, $this->y($y) - $h, $w, $h); |
|
|
|
|
865
|
|
|
break; |
866
|
|
|
|
867
|
|
View Code Duplication |
case "svg": |
|
|
|
|
868
|
|
|
if ($debug_png) print '!!!SVG!!!'; |
869
|
|
|
|
870
|
|
|
$this->_pdf->addSvgFromFile($img, $x, $this->y($y) - $h, $w, $h); |
|
|
|
|
871
|
|
|
break; |
872
|
|
|
|
873
|
|
|
default: |
874
|
|
|
if ($debug_png) print '!!!unknown!!!'; |
875
|
|
|
} |
876
|
|
|
} |
877
|
|
|
|
878
|
|
|
/** |
879
|
|
|
* @param float $x |
880
|
|
|
* @param float $y |
881
|
|
|
* @param string $text |
882
|
|
|
* @param string $font |
883
|
|
|
* @param float $size |
884
|
|
|
* @param array $color |
885
|
|
|
* @param float $word_space |
886
|
|
|
* @param float $char_space |
887
|
|
|
* @param float $angle |
888
|
|
|
*/ |
889
|
|
|
public function text($x, $y, $text, $font, $size, $color = array(0, 0, 0), $word_space = 0.0, $char_space = 0.0, $angle = 0.0) |
890
|
|
|
{ |
891
|
|
|
$pdf = $this->_pdf; |
892
|
|
|
|
893
|
|
|
$this->_set_fill_color($color); |
894
|
|
|
|
895
|
|
|
$font .= ".afm"; |
896
|
|
|
$pdf->selectFont($font); |
|
|
|
|
897
|
|
|
|
898
|
|
|
//FontMetrics::getFontHeight($font, $size) == |
|
|
|
|
899
|
|
|
//$this->getFontHeight($font, $size) == |
|
|
|
|
900
|
|
|
//$this->_pdf->selectFont($font),$this->_pdf->getFontHeight($size) |
|
|
|
|
901
|
|
|
//- FontBBoxheight+FontHeightOffset, scaled to $size, in pt |
902
|
|
|
//$this->_pdf->getFontDescender($size) |
|
|
|
|
903
|
|
|
//- Descender scaled to size |
904
|
|
|
// |
905
|
|
|
//$this->_pdf->fonts[$this->_pdf->currentFont] sizes: |
|
|
|
|
906
|
|
|
//['FontBBox'][0] left, ['FontBBox'][1] bottom, ['FontBBox'][2] right, ['FontBBox'][3] top |
|
|
|
|
907
|
|
|
//Maximum extent of all glyphs of the font from the baseline point |
908
|
|
|
//['Ascender'] maximum height above baseline except accents |
909
|
|
|
//['Descender'] maximum depth below baseline, negative number means below baseline |
910
|
|
|
//['FontHeightOffset'] manual enhancement of .afm files to trim windows fonts. currently not used. |
911
|
|
|
//Values are in 1/1000 pt for a font size of 1 pt |
912
|
|
|
// |
913
|
|
|
//['FontBBox'][1] should be close to ['Descender'] |
|
|
|
|
914
|
|
|
//['FontBBox'][3] should be close to ['Ascender']+Accents |
|
|
|
|
915
|
|
|
//in practice, FontBBox values are a little bigger |
916
|
|
|
// |
917
|
|
|
//The text position is referenced to the baseline, not to the lower corner of the FontBBox, |
918
|
|
|
//for what the left,top corner is given. |
919
|
|
|
//FontBBox spans also the background box for the text. |
920
|
|
|
//If the lower corner would be used as reference point, the Descents of the glyphs would |
921
|
|
|
//hang over the background box border. |
922
|
|
|
//Therefore compensate only the extent above the Baseline. |
923
|
|
|
// |
924
|
|
|
//print '<pre>['.$font.','.$size.','.$pdf->getFontHeight($size).','.$pdf->getFontDescender($size).','.$pdf->fonts[$pdf->currentFont]['FontBBox'][3].','.$pdf->fonts[$pdf->currentFont]['FontBBox'][1].','.$pdf->fonts[$pdf->currentFont]['FontHeightOffset'].','.$pdf->fonts[$pdf->currentFont]['Ascender'].','.$pdf->fonts[$pdf->currentFont]['Descender'].']</pre>'; |
|
|
|
|
925
|
|
|
// |
926
|
|
|
//$pdf->addText($x, $this->y($y) - ($pdf->fonts[$pdf->currentFont]['FontBBox'][3]*$size)/1000, $size, $text, $angle, $word_space, $char_space); |
|
|
|
|
927
|
|
|
$pdf->addText($x, $this->y($y) - $pdf->getFontHeight($size), $size, $text, $angle, $word_space, $char_space); |
|
|
|
|
928
|
|
|
|
929
|
|
|
$this->_set_fill_transparency("Normal", $this->_current_opacity); |
930
|
|
|
} |
931
|
|
|
|
932
|
|
|
/** |
933
|
|
|
* @param string $code |
934
|
|
|
*/ |
935
|
|
|
public function javascript($code) |
936
|
|
|
{ |
937
|
|
|
$this->_pdf->addJavascript($code); |
|
|
|
|
938
|
|
|
} |
939
|
|
|
|
940
|
|
|
//........................................................................ |
|
|
|
|
941
|
|
|
|
942
|
|
|
/** |
943
|
|
|
* Add a named destination (similar to <a name="foo">...</a> in html) |
944
|
|
|
* |
945
|
|
|
* @param string $anchorname The name of the named destination |
946
|
|
|
*/ |
947
|
|
|
public function add_named_dest($anchorname) |
948
|
|
|
{ |
949
|
|
|
$this->_pdf->addDestination($anchorname, "Fit"); |
|
|
|
|
950
|
|
|
} |
951
|
|
|
|
952
|
|
|
/** |
953
|
|
|
* Add a link to the pdf |
954
|
|
|
* |
955
|
|
|
* @param string $url The url to link to |
956
|
|
|
* @param float $x The x position of the link |
957
|
|
|
* @param float $y The y position of the link |
958
|
|
|
* @param float $width The width of the link |
959
|
|
|
* @param float $height The height of the link |
960
|
|
|
*/ |
961
|
|
|
public function add_link($url, $x, $y, $width, $height) |
962
|
|
|
{ |
963
|
|
|
$y = $this->y($y) - $height; |
964
|
|
|
|
965
|
|
|
if (strpos($url, '#') === 0) { |
966
|
|
|
// Local link |
967
|
|
|
$name = substr($url, 1); |
968
|
|
|
if ($name) { |
969
|
|
|
$this->_pdf->addInternalLink($name, $x, $y, $x + $width, $y + $height); |
|
|
|
|
970
|
|
|
} |
971
|
|
|
} else { |
972
|
|
|
$this->_pdf->addLink(rawurldecode($url), $x, $y, $x + $width, $y + $height); |
|
|
|
|
973
|
|
|
} |
974
|
|
|
} |
975
|
|
|
|
976
|
|
|
/** |
977
|
|
|
* @param string $text |
978
|
|
|
* @param string $font |
979
|
|
|
* @param float $size |
980
|
|
|
* @param int $word_spacing |
981
|
|
|
* @param int $char_spacing |
982
|
|
|
* @return float|int |
983
|
|
|
*/ |
984
|
|
|
public function get_text_width($text, $font, $size, $word_spacing = 0, $char_spacing = 0) |
985
|
|
|
{ |
986
|
|
|
$this->_pdf->selectFont($font); |
|
|
|
|
987
|
|
|
return $this->_pdf->getTextWidth($size, $text, $word_spacing, $char_spacing); |
|
|
|
|
988
|
|
|
} |
989
|
|
|
|
990
|
|
|
/** |
991
|
|
|
* @param $font |
992
|
|
|
* @param $string |
993
|
|
|
*/ |
994
|
|
|
public function register_string_subset($font, $string) |
995
|
|
|
{ |
996
|
|
|
$this->_pdf->registerText($font, $string); |
|
|
|
|
997
|
|
|
} |
998
|
|
|
|
999
|
|
|
/** |
1000
|
|
|
* @param string $font |
1001
|
|
|
* @param float $size |
1002
|
|
|
* @return float|int |
1003
|
|
|
*/ |
1004
|
|
|
public function get_font_height($font, $size) |
1005
|
|
|
{ |
1006
|
|
|
$this->_pdf->selectFont($font); |
|
|
|
|
1007
|
|
|
|
1008
|
|
|
$ratio = $this->_dompdf->getOptions()->getFontHeightRatio(); |
1009
|
|
|
return $this->_pdf->getFontHeight($size) * $ratio; |
|
|
|
|
1010
|
|
|
} |
1011
|
|
|
|
1012
|
|
|
/*function get_font_x_height($font, $size) { |
|
|
|
|
1013
|
|
|
$this->_pdf->selectFont($font); |
1014
|
|
|
$ratio = $this->_dompdf->getOptions()->getFontHeightRatio(); |
1015
|
|
|
return $this->_pdf->getFontXHeight($size) * $ratio; |
1016
|
|
|
}*/ |
1017
|
|
|
|
1018
|
|
|
/** |
1019
|
|
|
* @param string $font |
1020
|
|
|
* @param float $size |
1021
|
|
|
* @return float |
1022
|
|
|
*/ |
1023
|
|
|
public function get_font_baseline($font, $size) |
1024
|
|
|
{ |
1025
|
|
|
$ratio = $this->_dompdf->getOptions()->getFontHeightRatio(); |
1026
|
|
|
return $this->get_font_height($font, $size) / $ratio; |
1027
|
|
|
} |
1028
|
|
|
|
1029
|
|
|
/** |
1030
|
|
|
* Writes text at the specified x and y coordinates on every page |
1031
|
|
|
* |
1032
|
|
|
* The strings '{PAGE_NUM}' and '{PAGE_COUNT}' are automatically replaced |
1033
|
|
|
* with their current values. |
1034
|
|
|
* |
1035
|
|
|
* See {@link Style::munge_color()} for the format of the colour array. |
1036
|
|
|
* |
1037
|
|
|
* @param float $x |
1038
|
|
|
* @param float $y |
1039
|
|
|
* @param string $text the text to write |
1040
|
|
|
* @param string $font the font file to use |
1041
|
|
|
* @param float $size the font size, in points |
1042
|
|
|
* @param array $color |
1043
|
|
|
* @param float $word_space word spacing adjustment |
1044
|
|
|
* @param float $char_space char spacing adjustment |
1045
|
|
|
* @param float $angle angle to write the text at, measured CW starting from the x-axis |
1046
|
|
|
*/ |
1047
|
|
|
public function page_text($x, $y, $text, $font, $size, $color = array(0, 0, 0), $word_space = 0.0, $char_space = 0.0, $angle = 0.0) |
1048
|
|
|
{ |
1049
|
|
|
$_t = "text"; |
1050
|
|
|
$this->_page_text[] = compact("_t", "x", "y", "text", "font", "size", "color", "word_space", "char_space", "angle"); |
1051
|
|
|
} |
1052
|
|
|
|
1053
|
|
|
/** |
1054
|
|
|
* Processes a script on every page |
1055
|
|
|
* |
1056
|
|
|
* The variables $pdf, $PAGE_NUM, and $PAGE_COUNT are available. |
1057
|
|
|
* |
1058
|
|
|
* This function can be used to add page numbers to all pages |
1059
|
|
|
* after the first one, for example. |
1060
|
|
|
* |
1061
|
|
|
* @param string $code the script code |
1062
|
|
|
* @param string $type the language type for script |
1063
|
|
|
*/ |
1064
|
|
|
public function page_script($code, $type = "text/php") |
1065
|
|
|
{ |
1066
|
|
|
$_t = "script"; |
1067
|
|
|
$this->_page_text[] = compact("_t", "code", "type"); |
1068
|
|
|
} |
1069
|
|
|
|
1070
|
|
|
/** |
1071
|
|
|
* @return int |
1072
|
|
|
*/ |
1073
|
|
|
public function new_page() |
1074
|
|
|
{ |
1075
|
|
|
$this->_page_number++; |
1076
|
|
|
$this->_page_count++; |
1077
|
|
|
|
1078
|
|
|
$ret = $this->_pdf->newPage(); |
|
|
|
|
1079
|
|
|
$this->_pages[] = $ret; |
1080
|
|
|
return $ret; |
1081
|
|
|
} |
1082
|
|
|
|
1083
|
|
|
/** |
1084
|
|
|
* Add text to each page after rendering is complete |
1085
|
|
|
*/ |
1086
|
|
|
protected function _add_page_text() |
1087
|
|
|
{ |
1088
|
|
|
if (!count($this->_page_text)) { |
1089
|
|
|
return; |
1090
|
|
|
} |
1091
|
|
|
|
1092
|
|
|
$page_number = 1; |
1093
|
|
|
$eval = null; |
1094
|
|
|
|
1095
|
|
|
foreach ($this->_pages as $pid) { |
1096
|
|
|
$this->reopen_object($pid); |
1097
|
|
|
|
1098
|
|
View Code Duplication |
foreach ($this->_page_text as $pt) { |
|
|
|
|
1099
|
|
|
extract($pt); |
1100
|
|
|
|
1101
|
|
|
switch ($_t) { |
1102
|
|
|
case "text": |
1103
|
|
|
$text = str_replace(array("{PAGE_NUM}", "{PAGE_COUNT}"), |
1104
|
|
|
array($page_number, $this->_page_count), $text); |
1105
|
|
|
$this->text($x, $y, $text, $font, $size, $color, $word_space, $char_space, $angle); |
1106
|
|
|
break; |
1107
|
|
|
|
1108
|
|
|
case "script": |
1109
|
|
|
if (!$eval) { |
1110
|
|
|
$eval = new PhpEvaluator($this); |
1111
|
|
|
} |
1112
|
|
|
$eval->evaluate($code, array('PAGE_NUM' => $page_number, 'PAGE_COUNT' => $this->_page_count)); |
1113
|
|
|
break; |
1114
|
|
|
|
1115
|
|
|
case 'line': |
1116
|
|
|
$this->line( $x1, $y1, $x2, $y2, $color, $width, $style ); |
1117
|
|
|
break; |
1118
|
|
|
} |
1119
|
|
|
} |
1120
|
|
|
|
1121
|
|
|
$this->close_object(); |
1122
|
|
|
$page_number++; |
1123
|
|
|
} |
1124
|
|
|
} |
1125
|
|
|
|
1126
|
|
|
/** |
1127
|
|
|
* Streams the PDF to the client. |
1128
|
|
|
* |
1129
|
|
|
* @param string $filename The filename to present to the client. |
1130
|
|
|
* @param array $options Associative array: 'compress' => 1 or 0 (default 1); 'Attachment' => 1 or 0 (default 1). |
1131
|
|
|
*/ |
1132
|
|
|
public function stream($filename = "document.pdf", $options = array()) |
1133
|
|
|
{ |
1134
|
|
|
if (headers_sent()) { |
1135
|
|
|
die("Unable to stream pdf: headers already sent"); |
|
|
|
|
1136
|
|
|
} |
1137
|
|
|
|
1138
|
|
|
if (!isset($options["compress"])) $options["compress"] = true; |
1139
|
|
|
if (!isset($options["Attachment"])) $options["Attachment"] = true; |
1140
|
|
|
|
1141
|
|
|
$this->_add_page_text(); |
1142
|
|
|
|
1143
|
|
|
$debug = !$options['compress']; |
1144
|
|
|
$tmp = ltrim($this->_pdf->output($debug)); |
|
|
|
|
1145
|
|
|
|
1146
|
|
|
header("Cache-Control: private"); |
1147
|
|
|
header("Content-Type: application/pdf"); |
1148
|
|
|
header("Content-Length: " . mb_strlen($tmp, "8bit")); |
1149
|
|
|
|
1150
|
|
|
$filename = str_replace(array("\n", "'"), "", basename($filename, ".pdf")) . ".pdf"; |
1151
|
|
|
$attachment = $options["Attachment"] ? "attachment" : "inline"; |
1152
|
|
|
header(Helpers::buildContentDispositionHeader($attachment, $filename)); |
1153
|
|
|
|
1154
|
|
|
echo $tmp; |
1155
|
|
|
flush(); |
1156
|
|
|
} |
1157
|
|
|
|
1158
|
|
|
/** |
1159
|
|
|
* Returns the PDF as a string. |
1160
|
|
|
* |
1161
|
|
|
* @param array $options Associative array: 'compress' => 1 or 0 (default 1). |
1162
|
|
|
* @return string |
1163
|
|
|
*/ |
1164
|
|
|
public function output($options = array()) |
1165
|
|
|
{ |
1166
|
|
|
if (!isset($options["compress"])) $options["compress"] = true; |
1167
|
|
|
|
1168
|
|
|
$this->_add_page_text(); |
1169
|
|
|
|
1170
|
|
|
$debug = !$options['compress']; |
1171
|
|
|
|
1172
|
|
|
return $this->_pdf->output($debug); |
|
|
|
|
1173
|
|
|
} |
1174
|
|
|
|
1175
|
|
|
/** |
1176
|
|
|
* Returns logging messages generated by the Cpdf class |
1177
|
|
|
* |
1178
|
|
|
* @return string |
1179
|
|
|
*/ |
1180
|
|
|
public function get_messages() |
1181
|
|
|
{ |
1182
|
|
|
return $this->_pdf->messages; |
|
|
|
|
1183
|
|
|
} |
1184
|
|
|
} |
1185
|
|
|
|
The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using
the property is implicitly global.
To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.