| 1 |
lars |
1 |
<?php
|
|
|
2 |
// $Header: /cvsroot/html2ps/output.pdflib.class.php,v 1.18 2007/05/17 13:55:13 Konstantin Exp $
|
|
|
3 |
|
|
|
4 |
define('PDFLIB_STATUS_INITIALIZED', 0);
|
|
|
5 |
define('PDFLIB_STATUS_DOCUMENT_STARTED', 1);
|
|
|
6 |
define('PDFLIB_STATUS_PAGE_STARTED', 2);
|
|
|
7 |
|
|
|
8 |
class OutputDriverPdflib extends OutputDriverGenericPDF {
|
|
|
9 |
var $pdf;
|
|
|
10 |
|
|
|
11 |
/**
|
|
|
12 |
* @var ? Contains the PDFLIB handle of currently selected PDF font
|
|
|
13 |
* @access private
|
|
|
14 |
*/
|
|
|
15 |
var $_currentfont;
|
|
|
16 |
var $_forms;
|
|
|
17 |
var $_field_names;
|
|
|
18 |
|
|
|
19 |
var $_radiogroups;
|
|
|
20 |
var $_watermark;
|
|
|
21 |
|
|
|
22 |
var $_status;
|
|
|
23 |
|
|
|
24 |
// Converts common encoding names to their PDFLIB equivalents
|
|
|
25 |
// (for example, PDFLIB does not understand iso-8859-1 encoding name,
|
|
|
26 |
// but have its equivalent names winansi..)
|
|
|
27 |
//
|
|
|
28 |
function encoding($encoding) {
|
|
|
29 |
$encoding = trim(strtolower($encoding));
|
|
|
30 |
|
|
|
31 |
$translations = array('iso-8859-1' => 'winansi',
|
|
|
32 |
'iso-8859-2' => 'iso8859-2',
|
|
|
33 |
'iso-8859-3' => 'iso8859-3',
|
|
|
34 |
'iso-8859-4' => 'iso8859-4',
|
|
|
35 |
'iso-8859-5' => 'iso8859-5',
|
|
|
36 |
'iso-8859-6' => 'iso8859-6',
|
|
|
37 |
'iso-8859-7' => 'iso8859-7',
|
|
|
38 |
'iso-8859-8' => 'iso8859-8',
|
|
|
39 |
'iso-8859-9' => 'iso8859-9',
|
|
|
40 |
'iso-8859-10' => 'iso8859-10',
|
|
|
41 |
'iso-8859-13' => 'iso8859-13',
|
|
|
42 |
'iso-8859-14' => 'iso8859-14',
|
|
|
43 |
'iso-8859-15' => 'iso8859-15',
|
|
|
44 |
'iso-8859-16' => 'iso8859-16',
|
|
|
45 |
'windows-1250' => 'cp1250',
|
|
|
46 |
'windows-1251' => 'cp1251',
|
|
|
47 |
'windows-1252' => 'cp1252',
|
|
|
48 |
'symbol' => 'symbol');
|
|
|
49 |
|
|
|
50 |
if (isset($translations[$encoding])) { return $translations[$encoding]; };
|
|
|
51 |
return $encoding;
|
|
|
52 |
}
|
|
|
53 |
|
|
|
54 |
function add_link($left, $top, $width, $height, $url) {
|
|
|
55 |
pdf_add_weblink($this->pdf, $left, $top-$height, $left+$width, $top, $url);
|
|
|
56 |
}
|
|
|
57 |
|
|
|
58 |
function add_local_link($left, $top, $width, $height, $anchor) {
|
|
|
59 |
pdf_add_locallink($this->pdf,
|
|
|
60 |
$left,
|
|
|
61 |
$top-$height - $this->offset ,
|
|
|
62 |
$left+$width,
|
|
|
63 |
$top - $this->offset,
|
|
|
64 |
$anchor->page,
|
|
|
65 |
"fitwidth");
|
|
|
66 |
}
|
|
|
67 |
|
|
|
68 |
function circle($x, $y, $r) {
|
|
|
69 |
pdf_circle($this->pdf, $x, $y, $r);
|
|
|
70 |
}
|
|
|
71 |
|
|
|
72 |
function clip() {
|
|
|
73 |
pdf_clip($this->pdf);
|
|
|
74 |
}
|
|
|
75 |
|
|
|
76 |
function close() {
|
|
|
77 |
pdf_end_page($this->pdf);
|
|
|
78 |
pdf_close($this->pdf);
|
|
|
79 |
pdf_delete($this->pdf);
|
|
|
80 |
}
|
|
|
81 |
|
|
|
82 |
function closepath() {
|
|
|
83 |
pdf_closepath($this->pdf);
|
|
|
84 |
}
|
|
|
85 |
|
|
|
86 |
function dash($x, $y) {
|
|
|
87 |
pdf_setdash($this->pdf, $x, $y);
|
|
|
88 |
}
|
|
|
89 |
|
|
|
90 |
function decoration($underline, $overline, $strikeout) {
|
|
|
91 |
// underline
|
|
|
92 |
pdf_set_parameter($this->pdf, "underline", $underline ? "true" : "false");
|
|
|
93 |
// overline
|
|
|
94 |
pdf_set_parameter($this->pdf, "overline", $overline ? "true" : "false");
|
|
|
95 |
// line through
|
|
|
96 |
pdf_set_parameter($this->pdf, "strikeout", $strikeout ? "true" : "false");
|
|
|
97 |
}
|
|
|
98 |
|
|
|
99 |
function fill() {
|
|
|
100 |
pdf_fill($this->pdf);
|
|
|
101 |
}
|
|
|
102 |
|
|
|
103 |
function findfont($name, $encoding) {
|
|
|
104 |
// PDFLIB is limited by 'builtin' encoding for "Symbol" font
|
|
|
105 |
if ($name == 'Symbol') {
|
|
|
106 |
$encoding = 'builtin';
|
|
|
107 |
};
|
|
|
108 |
|
|
|
109 |
global $g_font_resolver_pdf;
|
|
|
110 |
$embed = $g_font_resolver_pdf->embed[$name];
|
|
|
111 |
return pdf_findfont($this->pdf, $name, $this->encoding($encoding), $embed);
|
|
|
112 |
}
|
|
|
113 |
|
|
|
114 |
function font_ascender($name, $encoding) {
|
|
|
115 |
return pdf_get_value($this->pdf, "ascender", $this->findfont($name, $encoding));
|
|
|
116 |
}
|
|
|
117 |
|
|
|
118 |
function font_descender($name, $encoding) {
|
|
|
119 |
return -pdf_get_value($this->pdf, "descender", $this->findfont($name, $encoding));
|
|
|
120 |
}
|
|
|
121 |
|
|
|
122 |
function get_bottom() {
|
|
|
123 |
return $this->bottom + $this->offset;
|
|
|
124 |
}
|
|
|
125 |
|
|
|
126 |
function image($image, $x, $y, $scale) {
|
|
|
127 |
$tmpname = tempnam(WRITER_TEMPDIR,WRITER_FILE_PREFIX);
|
|
|
128 |
imagepng($image->get_handle(), $tmpname);
|
|
|
129 |
$pim = pdf_open_image_file($this->pdf, "png", $tmpname, "", 0);
|
|
|
130 |
pdf_place_image($this->pdf, $pim, $x, $y, $scale);
|
|
|
131 |
pdf_close_image($this->pdf, $pim);
|
|
|
132 |
unlink($tmpname);
|
|
|
133 |
}
|
|
|
134 |
|
|
|
135 |
function image_scaled($image, $x, $y, $scale_x, $scale_y) {
|
|
|
136 |
$tmpname = tempnam(WRITER_TEMPDIR,WRITER_FILE_PREFIX);
|
|
|
137 |
imagepng($image->get_handle(), $tmpname);
|
|
|
138 |
|
|
|
139 |
$pim = pdf_open_image_file($this->pdf, "png", $tmpname, "", 0);
|
|
|
140 |
|
|
|
141 |
$this->save();
|
|
|
142 |
pdf_translate($this->pdf, $x, $y);
|
|
|
143 |
pdf_scale($this->pdf, $scale_x, $scale_y);
|
|
|
144 |
pdf_place_image($this->pdf, $pim, 0, 0, 1);
|
|
|
145 |
$this->restore();
|
|
|
146 |
|
|
|
147 |
pdf_close_image($this->pdf, $pim);
|
|
|
148 |
unlink($tmpname);
|
|
|
149 |
}
|
|
|
150 |
|
|
|
151 |
function image_ry($image, $x, $y, $height, $bottom, $ox, $oy, $scale) {
|
|
|
152 |
$tmpname = tempnam(WRITER_TEMPDIR,WRITER_FILE_PREFIX);
|
|
|
153 |
imagepng($image->get_handle(), $tmpname);
|
|
|
154 |
$pim = pdf_open_image_file($this->pdf, "png", $tmpname, "", 0);
|
|
|
155 |
|
|
|
156 |
// Fill part to the bottom
|
|
|
157 |
$cy = $y;
|
|
|
158 |
while ($cy+$height > $bottom) {
|
|
|
159 |
pdf_place_image($this->pdf, $pim, $x, $cy, $scale);
|
|
|
160 |
$cy -= $height;
|
|
|
161 |
};
|
|
|
162 |
|
|
|
163 |
// Fill part to the top
|
|
|
164 |
$cy = $y;
|
|
|
165 |
while ($cy-$height < $y + $oy) {
|
|
|
166 |
pdf_place_image($this->pdf, $pim, $x, $cy, $scale);
|
|
|
167 |
$cy += $height;
|
|
|
168 |
};
|
|
|
169 |
|
|
|
170 |
pdf_close_image($this->pdf, $pim);
|
|
|
171 |
unlink($tmpname);
|
|
|
172 |
}
|
|
|
173 |
|
|
|
174 |
function image_rx($image, $x, $y, $width, $right, $ox, $oy, $scale) {
|
|
|
175 |
$tmpname = tempnam(WRITER_TEMPDIR,WRITER_FILE_PREFIX);
|
|
|
176 |
imagepng($image->get_handle(), $tmpname);
|
|
|
177 |
$pim = pdf_open_image_file($this->pdf, "png", $tmpname, "", 0);
|
|
|
178 |
|
|
|
179 |
// Fill part to the right
|
|
|
180 |
$cx = $x;
|
|
|
181 |
while ($cx < $right) {
|
|
|
182 |
pdf_place_image($this->pdf, $pim, $cx, $y, $scale);
|
|
|
183 |
$cx += $width;
|
|
|
184 |
};
|
|
|
185 |
|
|
|
186 |
// Fill part to the left
|
|
|
187 |
$cx = $x;
|
|
|
188 |
while ($cx+$width >= $x - $ox) {
|
|
|
189 |
pdf_place_image($this->pdf, $pim, $cx-$width, $y, $scale);
|
|
|
190 |
$cx -= $width;
|
|
|
191 |
};
|
|
|
192 |
|
|
|
193 |
pdf_close_image($this->pdf, $pim);
|
|
|
194 |
unlink($tmpname);
|
|
|
195 |
}
|
|
|
196 |
|
|
|
197 |
function image_rx_ry($image, $x, $y, $width, $height, $right, $bottom, $ox, $oy, $scale) {
|
|
|
198 |
$tmpname = tempnam(WRITER_TEMPDIR,WRITER_FILE_PREFIX);
|
|
|
199 |
imagepng($image->get_handle(), $tmpname);
|
|
|
200 |
$pim = pdf_open_image_file($this->pdf, "png", $tmpname, "", 0);
|
|
|
201 |
|
|
|
202 |
// Fill bottom-right quadrant
|
|
|
203 |
$cy = $y;
|
|
|
204 |
while ($cy+$height > $bottom) {
|
|
|
205 |
$cx = $x;
|
|
|
206 |
while ($cx < $right) {
|
|
|
207 |
pdf_place_image($this->pdf, $pim, $cx, $cy, $scale);
|
|
|
208 |
$cx += $width;
|
|
|
209 |
};
|
|
|
210 |
$cy -= $height;
|
|
|
211 |
}
|
|
|
212 |
|
|
|
213 |
// Fill bottom-left quadrant
|
|
|
214 |
$cy = $y;
|
|
|
215 |
while ($cy+$height > $bottom) {
|
|
|
216 |
$cx = $x;
|
|
|
217 |
while ($cx+$width > $x - $ox) {
|
|
|
218 |
pdf_place_image($this->pdf, $pim, $cx, $cy, $scale);
|
|
|
219 |
$cx -= $width;
|
|
|
220 |
};
|
|
|
221 |
$cy -= $height;
|
|
|
222 |
}
|
|
|
223 |
|
|
|
224 |
// Fill top-right quadrant
|
|
|
225 |
$cy = $y;
|
|
|
226 |
while ($cy < $y + $oy) {
|
|
|
227 |
$cx = $x;
|
|
|
228 |
while ($cx < $right) {
|
|
|
229 |
pdf_place_image($this->pdf, $pim, $cx, $cy, $scale);
|
|
|
230 |
$cx += $width;
|
|
|
231 |
};
|
|
|
232 |
$cy += $height;
|
|
|
233 |
}
|
|
|
234 |
|
|
|
235 |
// Fill top-left quadrant
|
|
|
236 |
$cy = $y;
|
|
|
237 |
while ($cy < $y + $oy) {
|
|
|
238 |
$cx = $x;
|
|
|
239 |
while ($cx+$width > $x - $ox) {
|
|
|
240 |
pdf_place_image($this->pdf, $pim, $cx, $cy, $scale);
|
|
|
241 |
$cx -= $width;
|
|
|
242 |
};
|
|
|
243 |
$cy += $height;
|
|
|
244 |
}
|
|
|
245 |
|
|
|
246 |
pdf_close_image($this->pdf, $pim);
|
|
|
247 |
unlink($tmpname);
|
|
|
248 |
}
|
|
|
249 |
|
|
|
250 |
function lineto($x, $y) {
|
|
|
251 |
pdf_lineto($this->pdf, $x, $y);
|
|
|
252 |
}
|
|
|
253 |
|
|
|
254 |
function moveto($x, $y) {
|
|
|
255 |
pdf_moveto($this->pdf, $x, $y);
|
|
|
256 |
}
|
|
|
257 |
|
|
|
258 |
// OutputDriver interface functions
|
|
|
259 |
function next_page($height) {
|
|
|
260 |
if ($this->_status == PDFLIB_STATUS_PAGE_STARTED) {
|
|
|
261 |
pdf_end_page($this->pdf);
|
|
|
262 |
};
|
|
|
263 |
pdf_begin_page($this->pdf, mm2pt($this->media->width()), mm2pt($this->media->height()));
|
|
|
264 |
|
|
|
265 |
// Calculate coordinate of the next page bottom edge
|
|
|
266 |
$this->offset -= $height - $this->offset_delta;
|
|
|
267 |
|
|
|
268 |
// Reset the "correction" offset to it normal value
|
|
|
269 |
// Note: "correction" offset is an offset value required to avoid page breaking
|
|
|
270 |
// in the middle of text boxes
|
|
|
271 |
$this->offset_delta = 0;
|
|
|
272 |
|
|
|
273 |
pdf_translate($this->pdf, 0, -$this->offset);
|
|
|
274 |
|
|
|
275 |
parent::next_page($height);
|
|
|
276 |
|
|
|
277 |
$this->_status = PDFLIB_STATUS_PAGE_STARTED;
|
|
|
278 |
}
|
|
|
279 |
|
|
|
280 |
function OutputDriverPdflib($version) {
|
|
|
281 |
$this->OutputDriverGenericPDF();
|
|
|
282 |
$this->set_pdf_version($version);
|
|
|
283 |
|
|
|
284 |
$this->_currentfont = null;
|
|
|
285 |
$this->_radiogroups = array();
|
|
|
286 |
$this->_field_names = array();
|
|
|
287 |
|
|
|
288 |
$this->_status = PDFLIB_STATUS_INITIALIZED;
|
|
|
289 |
}
|
|
|
290 |
|
|
|
291 |
function prepare() {
|
|
|
292 |
parent::prepare();
|
|
|
293 |
|
|
|
294 |
// Generate custom encoding vector mappings
|
|
|
295 |
$manager_encoding = ManagerEncoding::get();
|
|
|
296 |
for ($i = 1, $size = $manager_encoding->get_custom_vector_index(); $i <= $size; $i++) {
|
|
|
297 |
$encoding_name = $manager_encoding->get_custom_encoding_name($i);
|
|
|
298 |
$filename = $this->generate_cpg($encoding_name,
|
|
|
299 |
true);
|
|
|
300 |
pdf_set_parameter($this->pdf,
|
|
|
301 |
'Encoding',
|
|
|
302 |
sprintf('%s=%s',
|
|
|
303 |
$encoding_name,
|
|
|
304 |
$filename));
|
|
|
305 |
};
|
|
|
306 |
}
|
|
|
307 |
|
|
|
308 |
function reset(&$media) {
|
|
|
309 |
OutputDriverGenericPDF::reset($media);
|
|
|
310 |
|
|
|
311 |
// Check if PDFLIB is available
|
|
|
312 |
if (!extension_loaded('pdf')) {
|
|
|
313 |
|
|
|
314 |
// Try to use "dl" to dynamically load PDFLIB
|
|
|
315 |
$result = dl(PDFLIB_DL_PATH);
|
|
|
316 |
|
|
|
317 |
if (!$result) {
|
|
|
318 |
readfile(HTML2PS_DIR.'templates/missing_pdflib.html');
|
|
|
319 |
error_log("No PDFLIB extension found");
|
|
|
320 |
die("HTML2PS Error");
|
|
|
321 |
}
|
|
|
322 |
}
|
|
|
323 |
|
|
|
324 |
$this->pdf = pdf_new();
|
|
|
325 |
|
|
|
326 |
// Set PDF compatibility level
|
|
|
327 |
pdf_set_parameter($this->pdf, "compatibility", $this->get_pdf_version());
|
|
|
328 |
|
|
|
329 |
/**
|
|
|
330 |
* Use PDF license key, if present
|
|
|
331 |
*
|
|
|
332 |
* PDFLIB_LICENSE constant is defined in 'config.inc.php' file in "PDFLIB-specific" section.
|
|
|
333 |
*/
|
|
|
334 |
if (defined("PDFLIB_LICENSE")) {
|
|
|
335 |
pdf_set_parameter($this->pdf, "license", PDFLIB_LICENSE);
|
|
|
336 |
};
|
|
|
337 |
|
|
|
338 |
pdf_open_file($this->pdf, $this->get_filename());
|
|
|
339 |
|
|
|
340 |
// @TODO: compression level, debug
|
|
|
341 |
pdf_set_value($this->pdf, "compress", 0);
|
|
|
342 |
|
|
|
343 |
// Set path to the PDFLIB UPR file containig information about fonts and encodings
|
|
|
344 |
if (defined("PDFLIB_UPR_PATH")) {
|
|
|
345 |
pdf_set_parameter($this->pdf, "resourcefile", PDFLIB_UPR_PATH);
|
|
|
346 |
};
|
|
|
347 |
|
|
|
348 |
// Setup encodings not bundled with PDFLIB
|
|
|
349 |
$filename = $this->generate_cpg('koi8-r');
|
|
|
350 |
pdf_set_parameter($this->pdf, 'Encoding', sprintf('koi8-r=%s', $filename));
|
|
|
351 |
|
|
|
352 |
// Setup font outlines
|
|
|
353 |
global $g_font_resolver_pdf;
|
|
|
354 |
$g_font_resolver_pdf->setup_ttf_mappings($this->pdf);
|
|
|
355 |
|
|
|
356 |
$pdf = $this->pdf;
|
|
|
357 |
pdf_set_info($pdf, "Creator", "html2ps (PHP version)");
|
|
|
358 |
|
|
|
359 |
// No borders around links in the generated PDF
|
|
|
360 |
pdf_set_border_style($this->pdf, "solid", 0);
|
|
|
361 |
|
|
|
362 |
$this->_status = PDFLIB_STATUS_DOCUMENT_STARTED;
|
|
|
363 |
}
|
|
|
364 |
|
|
|
365 |
function rect($x, $y, $w, $h) {
|
|
|
366 |
pdf_rect($this->pdf, $x, $y, $w, $h);
|
|
|
367 |
}
|
|
|
368 |
|
|
|
369 |
function restore() {
|
|
|
370 |
pdf_restore($this->pdf);
|
|
|
371 |
}
|
|
|
372 |
|
|
|
373 |
function save() {
|
|
|
374 |
pdf_save($this->pdf);
|
|
|
375 |
}
|
|
|
376 |
|
|
|
377 |
function setfont($name, $encoding, $size) {
|
|
|
378 |
$this->_currentfont = $this->findfont($name, $encoding);
|
|
|
379 |
|
|
|
380 |
pdf_setfont($this->pdf, $this->_currentfont, $size);
|
|
|
381 |
|
|
|
382 |
return true;
|
|
|
383 |
}
|
|
|
384 |
|
|
|
385 |
// function setfontcore($name, $size) {
|
|
|
386 |
// $this->_currentfont = pdf_findfont($this->pdf, $name, 'host', 1 /* embed */);
|
|
|
387 |
|
|
|
388 |
// pdf_setfont($this->pdf, $this->_currentfont, $size);
|
|
|
389 |
|
|
|
390 |
// return true;
|
|
|
391 |
// }
|
|
|
392 |
|
|
|
393 |
function setlinewidth($x) {
|
|
|
394 |
pdf_setlinewidth($this->pdf, $x);
|
|
|
395 |
}
|
|
|
396 |
|
|
|
397 |
// PDFLIB wrapper functions
|
|
|
398 |
function setrgbcolor($r, $g, $b) {
|
|
|
399 |
pdf_setcolor($this->pdf, "both", "rgb", $r, $g, $b, 0);
|
|
|
400 |
}
|
|
|
401 |
|
|
|
402 |
function show_xy($text, $x, $y) {
|
|
|
403 |
pdf_show_xy($this->pdf, $text, $x, $y);
|
|
|
404 |
}
|
|
|
405 |
|
|
|
406 |
function stroke() {
|
|
|
407 |
pdf_stroke($this->pdf);
|
|
|
408 |
}
|
|
|
409 |
|
|
|
410 |
function stringwidth($string, $name, $encoding, $size) {
|
|
|
411 |
return pdf_stringwidth($this->pdf, $string, $this->findfont($name, $encoding), $size);
|
|
|
412 |
}
|
|
|
413 |
|
|
|
414 |
/* private routines */
|
|
|
415 |
|
|
|
416 |
function _show_watermark($watermark) {
|
|
|
417 |
$font = $this->findfont('Helvetica', 'iso-8859-1');
|
|
|
418 |
pdf_setfont($this->pdf, $font, 100);
|
|
|
419 |
|
|
|
420 |
$x = $this->left + $this->width / 2;
|
|
|
421 |
$y = $this->bottom + $this->height / 2 + $this->offset;
|
|
|
422 |
|
|
|
423 |
pdf_set_value($this->pdf, "textrendering", 1);
|
|
|
424 |
pdf_translate($this->pdf, $x, $y);
|
|
|
425 |
pdf_rotate($this->pdf, 60);
|
|
|
426 |
pdf_show_xy($this->pdf, $watermark, -pdf_stringwidth($this->pdf, $watermark, $font, 100)/2, -50);
|
|
|
427 |
}
|
|
|
428 |
|
|
|
429 |
function generate_cpg($encoding, $force = false) {
|
|
|
430 |
if (!$force) {
|
|
|
431 |
$filename = CACHE_DIR.$encoding.'.cpg';
|
|
|
432 |
} else {
|
|
|
433 |
$filename = CACHE_DIR.uniqid('', false).'.cpg';
|
|
|
434 |
};
|
|
|
435 |
|
|
|
436 |
if (file_exists($filename)) {
|
|
|
437 |
return $filename;
|
|
|
438 |
};
|
|
|
439 |
|
|
|
440 |
$output = fopen($filename, 'w');
|
|
|
441 |
$manager_encoding =& ManagerEncoding::get();
|
|
|
442 |
$vector = $manager_encoding->get_encoding_vector($encoding);
|
|
|
443 |
|
|
|
444 |
foreach ($vector as $code => $utf) {
|
|
|
445 |
fwrite($output, sprintf("0x%04X 0x%02X\n", $utf, ord($code)));
|
|
|
446 |
};
|
|
|
447 |
fclose($output);
|
|
|
448 |
|
|
|
449 |
return $filename;
|
|
|
450 |
}
|
|
|
451 |
}
|
|
|
452 |
?>
|