phpBMS

Ticket #330: fpdiUpload.patch

File fpdiUpload.patch, 145.8 KB (added by nate, 3 years ago)

see nate's post.

Line 
1Index: fpdf/decoders/ASCII85Decode.php
2===================================================================
3--- fpdf/decoders/ASCII85Decode.php     (revision 0)
4+++ fpdf/decoders/ASCII85Decode.php     (revision 0)
5@@ -0,0 +1,95 @@
6+<?php
7+//
8+//  FPDI - Version 1.3
9+//
10+//    Copyright 2004-2009 Setasign - Jan Slabon
11+//
12+//  Licensed under the Apache License, Version 2.0 (the "License");
13+//  you may not use this file except in compliance with the License.
14+//  You may obtain a copy of the License at
15+//
16+//      http://www.apache.org/licenses/LICENSE-2.0
17+//
18+//  Unless required by applicable law or agreed to in writing, software
19+//  distributed under the License is distributed on an "AS IS" BASIS,
20+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21+//  See the License for the specific language governing permissions and
22+//  limitations under the License.
23+//
24+
25+if (!defined('ORD_z'))
26+       define('ORD_z',ord('z'));
27+if (!defined('ORD_exclmark'))
28+       define('ORD_exclmark', ord('!'));
29+if (!defined('ORD_u'))
30+       define('ORD_u', ord('u'));
31+if (!defined('ORD_tilde'))
32+       define('ORD_tilde', ord('~'));
33+
34+class ASCII85Decode {
35+
36+    function ASCII85Decode(&$fpdi) {
37+        $this->fpdi =& $fpdi;
38+    }
39+
40+
41+    function decode($in) {
42+        $out = '';
43+        $state = 0;
44+        $chn = null;
45+       
46+        $l = strlen($in);
47+       
48+        for ($k = 0; $k < $l; ++$k) {
49+            $ch = ord($in[$k]) & 0xff;
50+           
51+            if ($ch == ORD_tilde) {
52+                break;
53+            }
54+            if (preg_match('/^\s$/',chr($ch))) {
55+                continue;
56+            }
57+            if ($ch == ORD_z && $state == 0) {
58+                $out .= chr(0).chr(0).chr(0).chr(0);
59+                continue;
60+            }
61+            if ($ch < ORD_exclmark || $ch > ORD_u) {
62+                $this->fpdi->error('Illegal character in ASCII85Decode.');
63+            }
64+           
65+            $chn[$state++] = $ch - ORD_exclmark;
66+           
67+            if ($state == 5) {
68+                $state = 0;
69+                $r = 0;
70+                for ($j = 0; $j < 5; ++$j)
71+                    $r = $r * 85 + $chn[$j];
72+                $out .= chr($r >> 24);
73+                $out .= chr($r >> 16);
74+                $out .= chr($r >> 8);
75+                $out .= chr($r);
76+            }
77+        }
78+        $r = 0;
79+       
80+        if ($state == 1)
81+            $this->fpdi->error('Illegal length in ASCII85Decode.');
82+        if ($state == 2) {
83+            $r = $chn[0] * 85 * 85 * 85 * 85 + ($chn[1]+1) * 85 * 85 * 85;
84+            $out .= chr($r >> 24);
85+        }
86+        else if ($state == 3) {
87+            $r = $chn[0] * 85 * 85 * 85 * 85 + $chn[1] * 85 * 85 * 85  + ($chn[2]+1) * 85 * 85;
88+            $out .= chr($r >> 24);
89+            $out .= chr($r >> 16);
90+        }
91+        else if ($state == 4) {
92+            $r = $chn[0] * 85 * 85 * 85 * 85 + $chn[1] * 85 * 85 * 85  + $chn[2] * 85 * 85  + ($chn[3]+1) * 85 ;
93+            $out .= chr($r >> 24);
94+            $out .= chr($r >> 16);
95+            $out .= chr($r >> 8);
96+        }
97+
98+        return $out;
99+    }
100+}
101Index: fpdf/decoders/LZWDecode.php
102===================================================================
103--- fpdf/decoders/LZWDecode.php (revision 0)
104+++ fpdf/decoders/LZWDecode.php (revision 0)
105@@ -0,0 +1,150 @@
106+<?php
107+//
108+//  FPDI - Version 1.3
109+//
110+//    Copyright 2004-2009 Setasign - Jan Slabon
111+//
112+//  Licensed under the Apache License, Version 2.0 (the "License");
113+//  you may not use this file except in compliance with the License.
114+//  You may obtain a copy of the License at
115+//
116+//      http://www.apache.org/licenses/LICENSE-2.0
117+//
118+//  Unless required by applicable law or agreed to in writing, software
119+//  distributed under the License is distributed on an "AS IS" BASIS,
120+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
121+//  See the License for the specific language governing permissions and
122+//  limitations under the License.
123+//
124+
125+class LZWDecode {
126+
127+    var $sTable = array();
128+    var $data = null;
129+    var $dataLength = 0;
130+    var $tIdx;
131+    var $bitsToGet = 9;
132+    var $bytePointer;
133+    var $bitPointer;
134+    var $nextData = 0;
135+    var $nextBits = 0;
136+    var $andTable = array(511, 1023, 2047, 4095);
137+
138+    function LZWDecode(&$fpdi) {
139+        $this->fpdi =& $fpdi;
140+    }
141+
142+    /**
143+     * Method to decode LZW compressed data.
144+     *
145+     * @param string data    The compressed data.
146+     */
147+    function decode($data) {
148+
149+        if($data[0] == 0x00 && $data[1] == 0x01) {
150+            $this->fpdi->error('LZW flavour not supported.');
151+        }
152+
153+        $this->initsTable();
154+
155+        $this->data = $data;
156+        $this->dataLength = strlen($data);
157+
158+        // Initialize pointers
159+        $this->bytePointer = 0;
160+        $this->bitPointer = 0;
161+
162+        $this->nextData = 0;
163+        $this->nextBits = 0;
164+
165+        $oldCode = 0;
166+
167+        $string = '';
168+        $uncompData = '';
169+
170+        while (($code = $this->getNextCode()) != 257) {
171+            if ($code == 256) {
172+                $this->initsTable();
173+                $code = $this->getNextCode();
174+
175+                if ($code == 257) {
176+                    break;
177+                }
178+
179+                $uncompData .= $this->sTable[$code];
180+                $oldCode = $code;
181+
182+            } else {
183+
184+                if ($code < $this->tIdx) {
185+                    $string = $this->sTable[$code];
186+                    $uncompData .= $string;
187+
188+                    $this->addStringToTable($this->sTable[$oldCode], $string[0]);
189+                    $oldCode = $code;
190+                } else {
191+                    $string = $this->sTable[$oldCode];
192+                    $string = $string.$string[0];
193+                    $uncompData .= $string;
194+
195+                    $this->addStringToTable($string);
196+                    $oldCode = $code;
197+                }
198+            }
199+        }
200+       
201+        return $uncompData;
202+    }
203+
204+
205+    /**
206+     * Initialize the string table.
207+     */
208+    function initsTable() {
209+        $this->sTable = array();
210+
211+        for ($i = 0; $i < 256; $i++)
212+            $this->sTable[$i] = chr($i);
213+
214+        $this->tIdx = 258;
215+        $this->bitsToGet = 9;
216+    }
217+
218+    /**
219+     * Add a new string to the string table.
220+     */
221+    function addStringToTable ($oldString, $newString='') {
222+        $string = $oldString.$newString;
223+
224+        // Add this new String to the table
225+        $this->sTable[$this->tIdx++] = $string;
226+
227+        if ($this->tIdx == 511) {
228+            $this->bitsToGet = 10;
229+        } else if ($this->tIdx == 1023) {
230+            $this->bitsToGet = 11;
231+        } else if ($this->tIdx == 2047) {
232+            $this->bitsToGet = 12;
233+        }
234+    }
235+
236+    // Returns the next 9, 10, 11 or 12 bits
237+    function getNextCode() {
238+        if ($this->bytePointer == $this->dataLength) {
239+            return 257;
240+        }
241+
242+        $this->nextData = ($this->nextData << 8) | (ord($this->data[$this->bytePointer++]) & 0xff);
243+        $this->nextBits += 8;
244+
245+        if ($this->nextBits < $this->bitsToGet) {
246+            $this->nextData = ($this->nextData << 8) | (ord($this->data[$this->bytePointer++]) & 0xff);
247+            $this->nextBits += 8;
248+        }
249+
250+        $code = ($this->nextData >> ($this->nextBits - $this->bitsToGet)) & $this->andTable[$this->bitsToGet-9];
251+        $this->nextBits -= $this->bitsToGet;
252+
253+        return $code;
254+    }
255+}
256Index: fpdf/fpdf_tpl.php
257===================================================================
258--- fpdf/fpdf_tpl.php   (revision 0)
259+++ fpdf/fpdf_tpl.php   (revision 0)
260@@ -0,0 +1,409 @@
261+<?php
262+//
263+//  FPDF_TPL - Version 1.1.3
264+//
265+//    Copyright 2004-2009 Setasign - Jan Slabon
266+//
267+//  Licensed under the Apache License, Version 2.0 (the "License");
268+//  you may not use this file except in compliance with the License.
269+//  You may obtain a copy of the License at
270+//
271+//      http://www.apache.org/licenses/LICENSE-2.0
272+//
273+//  Unless required by applicable law or agreed to in writing, software
274+//  distributed under the License is distributed on an "AS IS" BASIS,
275+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
276+//  See the License for the specific language governing permissions and
277+//  limitations under the License.
278+//
279+
280+class FPDF_TPL extends FPDF {
281+    /**
282+     * Array of Tpl-Data
283+     * @var array
284+     */
285+    var $tpls = array();
286+
287+    /**
288+     * Current Template-ID
289+     * @var int
290+     */
291+    var $tpl = 0;
292+   
293+    /**
294+     * "In Template"-Flag
295+     * @var boolean
296+     */
297+    var $_intpl = false;
298+   
299+    /**
300+     * Nameprefix of Templates used in Resources-Dictonary
301+     * @var string A String defining the Prefix used as Template-Object-Names. Have to beginn with an /
302+     */
303+    var $tplprefix = "/TPL";
304+
305+    /**
306+     * Resources used By Templates and Pages
307+     * @var array
308+     */
309+    var $_res = array();
310+   
311+    /**
312+     * Last used Template data
313+     *
314+     * @var array
315+     */
316+    var $lastUsedTemplateData = array();
317+   
318+    /**
319+     * Start a Template
320+     *
321+     * This method starts a template. You can give own coordinates to build an own sized
322+     * Template. Pay attention, that the margins are adapted to the new templatesize.
323+     * If you want to write outside the template, for example to build a clipped Template,
324+     * you have to set the Margins and "Cursor"-Position manual after beginTemplate-Call.
325+     *
326+     * If no parameter is given, the template uses the current page-size.
327+     * The Method returns an ID of the current Template. This ID is used later for using this template.
328+     * Warning: A created Template is used in PDF at all events. Still if you don't use it after creation!
329+     *
330+     * @param int $x The x-coordinate given in user-unit
331+     * @param int $y The y-coordinate given in user-unit
332+     * @param int $w The width given in user-unit
333+     * @param int $h The height given in user-unit
334+     * @return int The ID of new created Template
335+     */
336+    function beginTemplate($x=null, $y=null, $w=null, $h=null) {
337+        if ($this->page <= 0)
338+            $this->error("You have to add a page to fpdf first!");
339+
340+        if ($x == null)
341+            $x = 0;
342+        if ($y == null)
343+            $y = 0;
344+        if ($w == null)
345+            $w = $this->w;
346+        if ($h == null)
347+            $h = $this->h;
348+
349+        // Save settings
350+        $this->tpl++;
351+        $tpl =& $this->tpls[$this->tpl];
352+        $tpl = array(
353+            'o_x' => $this->x,
354+            'o_y' => $this->y,
355+            'o_AutoPageBreak' => $this->AutoPageBreak,
356+            'o_bMargin' => $this->bMargin,
357+            'o_tMargin' => $this->tMargin,
358+            'o_lMargin' => $this->lMargin,
359+            'o_rMargin' => $this->rMargin,
360+            'o_h' => $this->h,
361+            'o_w' => $this->w,
362+            'buffer' => '',
363+            'x' => $x,
364+            'y' => $y,
365+            'w' => $w,
366+            'h' => $h
367+        );
368+
369+        $this->SetAutoPageBreak(false);
370+       
371+        // Define own high and width to calculate possitions correct
372+        $this->h = $h;
373+        $this->w = $w;
374+
375+        $this->_intpl = true;
376+        $this->SetXY($x+$this->lMargin, $y+$this->tMargin);
377+        $this->SetRightMargin($this->w-$w+$this->rMargin);
378+
379+        return $this->tpl;
380+    }
381+   
382+    /**
383+     * End Template
384+     *
385+     * This method ends a template and reset initiated variables on beginTemplate.
386+     *
387+     * @return mixed If a template is opened, the ID is returned. If not a false is returned.
388+     */
389+    function endTemplate() {
390+        if ($this->_intpl) {
391+            $this->_intpl = false;
392+            $tpl =& $this->tpls[$this->tpl];
393+            $this->SetXY($tpl['o_x'], $tpl['o_y']);
394+            $this->tMargin = $tpl['o_tMargin'];
395+            $this->lMargin = $tpl['o_lMargin'];
396+            $this->rMargin = $tpl['o_rMargin'];
397+            $this->h = $tpl['o_h'];
398+            $this->w = $tpl['o_w'];
399+            $this->SetAutoPageBreak($tpl['o_AutoPageBreak'], $tpl['o_bMargin']);
400+           
401+            return $this->tpl;
402+        } else {
403+            return false;
404+        }
405+    }
406+   
407+    /**
408+     * Use a Template in current Page or other Template
409+     *
410+     * You can use a template in a page or in another template.
411+     * You can give the used template a new size like you use the Image()-method.
412+     * All parameters are optional. The width or height is calculated automaticaly
413+     * if one is given. If no parameter is given the origin size as defined in
414+     * beginTemplate() is used.
415+     * The calculated or used width and height are returned as an array.
416+     *
417+     * @param int $tplidx A valid template-Id
418+     * @param int $_x The x-position
419+     * @param int $_y The y-position
420+     * @param int $_w The new width of the template
421+     * @param int $_h The new height of the template
422+     * @retrun array The height and width of the template
423+     */
424+    function useTemplate($tplidx, $_x=null, $_y=null, $_w=0, $_h=0) {
425+        if ($this->page <= 0)
426+            $this->error("You have to add a page to fpdf first!");
427+
428+        if (!isset($this->tpls[$tplidx]))
429+            $this->error("Template does not exist!");
430+           
431+        if ($this->_intpl) {
432+            $this->_res['tpl'][$this->tpl]['tpls'][$tplidx] =& $this->tpls[$tplidx];
433+        }
434+       
435+        $tpl =& $this->tpls[$tplidx];
436+        $w = $tpl['w'];
437+        $h = $tpl['h'];
438+       
439+        if ($_x == null)
440+            $_x = 0;
441+        if ($_y == null)
442+            $_y = 0;
443+           
444+        $_x += $tpl['x'];
445+        $_y += $tpl['y'];
446+       
447+        $wh = $this->getTemplateSize($tplidx, $_w, $_h);
448+        $_w = $wh['w'];
449+        $_h = $wh['h'];
450+   
451+        $tData = array(
452+            'x' => $this->x,
453+            'y' => $this->y,
454+            'w' => $_w,
455+            'h' => $_h,
456+            'scaleX' => ($_w/$w),
457+            'scaleY' => ($_h/$h),
458+            'tx' => $_x,
459+            'ty' =>  ($this->h-$_y-$_h),
460+            'lty' => ($this->h-$_y-$_h) - ($this->h-$h) * ($_h/$h)
461+        );
462+       
463+        $this->_out(sprintf("q %.4F 0 0 %.4F %.4F %.4F cm", $tData['scaleX'], $tData['scaleY'], $tData['tx']*$this->k, $tData['ty']*$this->k)); // Translate
464+        $this->_out(sprintf('%s%d Do Q', $this->tplprefix, $tplidx));
465+
466+        $this->lastUsedTemplateData = $tData;
467+       
468+        return array("w" => $_w, "h" => $_h);
469+    }
470+   
471+    /**
472+     * Get The calculated Size of a Template
473+     *
474+     * If one size is given, this method calculates the other one.
475+     *
476+     * @param int $tplidx A valid template-Id
477+     * @param int $_w The width of the template
478+     * @param int $_h The height of the template
479+     * @return array The height and width of the template
480+     */
481+    function getTemplateSize($tplidx, $_w=0, $_h=0) {
482+        if (!$this->tpls[$tplidx])
483+            return false;
484+
485+        $tpl =& $this->tpls[$tplidx];
486+        $w = $tpl['w'];
487+        $h = $tpl['h'];
488+       
489+        if ($_w == 0 and $_h == 0) {
490+            $_w = $w;
491+            $_h = $h;
492+        }
493+
494+       if($_w==0)
495+               $_w = $_h*$w/$h;
496+       if($_h==0)
497+               $_h = $_w*$h/$w;
498+               
499+        return array("w" => $_w, "h" => $_h);
500+    }
501+   
502+    /**
503+     * See FPDF/TCPDF-Documentation ;-)
504+     */
505+    function SetFont($family, $style='', $size=0, $fontfile='') {
506+        if (!is_subclass_of($this, 'TCPDF') && func_num_args() > 3) {
507+            $this->Error('More than 3 arguments for the SetFont method are only available in TCPDF.');
508+        }
509+        /**
510+         * force the resetting of font changes in a template
511+         */
512+        if ($this->_intpl)
513+            $this->FontFamily = '';
514+           
515+        parent::SetFont($family, $style, $size, $fontfile);
516+       
517+        $fontkey = $this->FontFamily.$this->FontStyle;
518+       
519+        if ($this->_intpl) {
520+            $this->_res['tpl'][$this->tpl]['fonts'][$fontkey] =& $this->fonts[$fontkey];
521+        } else {
522+            $this->_res['page'][$this->page]['fonts'][$fontkey] =& $this->fonts[$fontkey];
523+        }
524+    }
525+   
526+    /**
527+     * See FPDF/TCPDF-Documentation ;-)
528+     */
529+    function Image($file, $x, $y, $w=0, $h=0, $type='', $link='', $align='', $resize=false, $dpi=300, $palign='', $ismask=false, $imgmask=false, $border=0) {
530+        if (!is_subclass_of($this, 'TCPDF') && func_num_args() > 7) {
531+            $this->Error('More than 7 arguments for the Image method are only available in TCPDF.');
532+        }
533+       
534+        parent::Image($file, $x, $y, $w, $h, $type, $link, $align, $resize, $dpi, $palign, $ismask, $imgmask, $border);
535+        if ($this->_intpl) {
536+            $this->_res['tpl'][$this->tpl]['images'][$file] =& $this->images[$file];
537+        } else {
538+            $this->_res['page'][$this->page]['images'][$file] =& $this->images[$file];
539+        }
540+    }
541+   
542+    /**
543+     * See FPDF-Documentation ;-)
544+     *
545+     * AddPage is not available when you're "in" a template.
546+     */
547+    function AddPage($orientation='', $format='') {
548+        if ($this->_intpl)
549+            $this->Error('Adding pages in templates isn\'t possible!');
550+        parent::AddPage($orientation, $format);
551+    }
552+
553+    /**
554+     * Preserve adding Links in Templates ...won't work
555+     */
556+    function Link($x, $y, $w, $h, $link, $spaces=0) {
557+        if (!is_subclass_of($this, 'TCPDF') && func_num_args() > 5) {
558+            $this->Error('More than 7 arguments for the Image method are only available in TCPDF.');
559+        }
560+       
561+        if ($this->_intpl)
562+            $this->Error('Using links in templates aren\'t possible!');
563+        parent::Link($x, $y, $w, $h, $link, $spaces);
564+    }
565+   
566+    function AddLink() {
567+        if ($this->_intpl)
568+            $this->Error('Adding links in templates aren\'t possible!');
569+        return parent::AddLink();
570+    }
571+   
572+    function SetLink($link, $y=0, $page=-1) {
573+        if ($this->_intpl)
574+            $this->Error('Setting links in templates aren\'t possible!');
575+        parent::SetLink($link, $y, $page);
576+    }
577+   
578+    /**
579+     * Private Method that writes the form xobjects
580+     */
581+    function _putformxobjects() {
582+        $filter=($this->compress) ? '/Filter /FlateDecode ' : '';
583+           reset($this->tpls);
584+        foreach($this->tpls AS $tplidx => $tpl) {
585+
586+            $p=($this->compress) ? gzcompress($tpl['buffer']) : $tpl['buffer'];
587+               $this->_newobj();
588+               $this->tpls[$tplidx]['n'] = $this->n;
589+               $this->_out('<<'.$filter.'/Type /XObject');
590+            $this->_out('/Subtype /Form');
591+            $this->_out('/FormType 1');
592+            $this->_out(sprintf('/BBox [%.2F %.2F %.2F %.2F]',
593+                // llx
594+                $tpl['x'],
595+                // lly
596+                -$tpl['y'],
597+                // urx
598+                ($tpl['w']+$tpl['x'])*$this->k,
599+                // ury
600+                ($tpl['h']-$tpl['y'])*$this->k
601+            ));
602+           
603+            if ($tpl['x'] != 0 || $tpl['y'] != 0) {
604+                $this->_out(sprintf('/Matrix [1 0 0 1 %.5F %.5F]',
605+                     -$tpl['x']*$this->k*2, $tpl['y']*$this->k*2
606+                ));
607+            }
608+           
609+            $this->_out('/Resources ');
610+
611+            $this->_out('<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
612+               if (isset($this->_res['tpl'][$tplidx]['fonts']) && count($this->_res['tpl'][$tplidx]['fonts'])) {
613+               $this->_out('/Font <<');
614+                foreach($this->_res['tpl'][$tplidx]['fonts'] as $font)
615+                       $this->_out('/F'.$font['i'].' '.$font['n'].' 0 R');
616+               $this->_out('>>');
617+            }
618+               if(isset($this->_res['tpl'][$tplidx]['images']) && count($this->_res['tpl'][$tplidx]['images']) ||
619+                  isset($this->_res['tpl'][$tplidx]['tpls']) && count($this->_res['tpl'][$tplidx]['tpls']))
620+               {
621+                $this->_out('/XObject <<');
622+                if (isset($this->_res['tpl'][$tplidx]['images']) && count($this->_res['tpl'][$tplidx]['images'])) {
623+                    foreach($this->_res['tpl'][$tplidx]['images'] as $image)
624+                               $this->_out('/I'.$image['i'].' '.$image['n'].' 0 R');
625+                }
626+                if (isset($this->_res['tpl'][$tplidx]['tpls']) && count($this->_res['tpl'][$tplidx]['tpls'])) {
627+                    foreach($this->_res['tpl'][$tplidx]['tpls'] as $i => $tpl)
628+                        $this->_out($this->tplprefix.$i.' '.$tpl['n'].' 0 R');
629+                }
630+                $this->_out('>>');
631+               }
632+               $this->_out('>>');
633+               
634+               $this->_out('/Length '.strlen($p).' >>');
635+               $this->_putstream($p);
636+               $this->_out('endobj');
637+        }
638+    }
639+   
640+    /**
641+     * Overwritten to add _putformxobjects() after _putimages()
642+     *
643+     */
644+    function _putimages() {
645+        parent::_putimages();
646+        $this->_putformxobjects();
647+    }
648+   
649+    function _putxobjectdict() {
650+        parent::_putxobjectdict();
651+       
652+        if (count($this->tpls)) {
653+            foreach($this->tpls as $tplidx => $tpl) {
654+                $this->_out(sprintf('%s%d %d 0 R', $this->tplprefix, $tplidx, $tpl['n']));
655+            }
656+        }
657+    }
658+
659+    /**
660+     * Private Method
661+     */
662+    function _out($s) {
663+        if ($this->state==2 && $this->_intpl) {
664+            $this->tpls[$this->tpl]['buffer'] .= $s."\n";
665+        } else {
666+            parent::_out($s);
667+        }
668+    }
669+}
670Index: fpdf/fpdi.php
671===================================================================
672--- fpdf/fpdi.php       (revision 0)
673+++ fpdf/fpdi.php       (revision 0)
674@@ -0,0 +1,504 @@
675+<?php
676+//
677+//  FPDI - Version 1.3
678+//
679+//    Copyright 2004-2009 Setasign - Jan Slabon
680+//
681+//  Licensed under the Apache License, Version 2.0 (the "License");
682+//  you may not use this file except in compliance with the License.
683+//  You may obtain a copy of the License at
684+//
685+//      http://www.apache.org/licenses/LICENSE-2.0
686+//
687+//  Unless required by applicable law or agreed to in writing, software
688+//  distributed under the License is distributed on an "AS IS" BASIS,
689+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
690+//  See the License for the specific language governing permissions and
691+//  limitations under the License.
692+//
693+
694+define('FPDI_VERSION','1.3');
695+
696+// Check for TCPDF and remap TCPDF to FPDF
697+if (class_exists('TCPDF')) {
698+    require_once('fpdi2tcpdf_bridge.php');
699+}
700+
701+require_once('fpdf_tpl.php');
702+require_once('fpdi_pdf_parser.php');
703+
704+
705+class FPDI extends FPDF_TPL {
706+    /**
707+     * Actual filename
708+     * @var string
709+     */
710+    var $current_filename;
711+
712+    /**
713+     * Parser-Objects
714+     * @var array
715+     */
716+    var $parsers;
717+   
718+    /**
719+     * Current parser
720+     * @var object
721+     */
722+    var $current_parser;
723+   
724+    /**
725+     * object stack
726+     * @var array
727+     */
728+    var $_obj_stack;
729+   
730+    /**
731+     * done object stack
732+     * @var array
733+     */
734+    var $_don_obj_stack;
735+
736+    /**
737+     * Current Object Id.
738+     * @var integer
739+     */
740+    var $_current_obj_id;
741+   
742+    /**
743+     * The name of the last imported page box
744+     * @var string
745+     */
746+    var $lastUsedPageBox;
747+   
748+    var $_importedPages = array();
749+   
750+   
751+    /**
752+     * Set a source-file
753+     *
754+     * @param string $filename a valid filename
755+     * @return int number of available pages
756+     */
757+    function setSourceFile($filename) {
758+        $this->current_filename = $filename;
759+        $fn =& $this->current_filename;
760+
761+        if (!isset($this->parsers[$fn]))
762+            $this->parsers[$fn] =& new fpdi_pdf_parser($fn, $this);
763+        $this->current_parser =& $this->parsers[$fn];
764+       
765+        return $this->parsers[$fn]->getPageCount();
766+    }
767+   
768+    /**
769+     * Import a page
770+     *
771+     * @param int $pageno pagenumber
772+     * @return int Index of imported page - to use with fpdf_tpl::useTemplate()
773+     */
774+    function importPage($pageno, $boxName='/CropBox') {
775+        if ($this->_intpl) {
776+            return $this->error('Please import the desired pages before creating a new template.');
777+        }
778+       
779+        $fn =& $this->current_filename;
780+       
781+        // check if page already imported
782+        $pageKey = $fn.((int)$pageno).$boxName;
783+        if (isset($this->_importedPages[$pageKey]))
784+            return $this->_importedPages[$pageKey];
785+       
786+        $parser =& $this->parsers[$fn];
787+        $parser->setPageno($pageno);
788+
789+        $this->tpl++;
790+        $this->tpls[$this->tpl] = array();
791+        $tpl =& $this->tpls[$this->tpl];
792+        $tpl['parser'] =& $parser;
793+        $tpl['resources'] = $parser->getPageResources();
794+        $tpl['buffer'] = $parser->getContent();
795+       
796+        if (!in_array($boxName, $parser->availableBoxes))
797+            return $this->Error(sprintf('Unknown box: %s', $boxName));
798+        $pageboxes = $parser->getPageBoxes($pageno);
799+       
800+        /**
801+         * MediaBox
802+         * CropBox: Default -> MediaBox
803+         * BleedBox: Default -> CropBox
804+         * TrimBox: Default -> CropBox
805+         * ArtBox: Default -> CropBox
806+         */
807+        if (!isset($pageboxes[$boxName]) && ($boxName == '/BleedBox' || $boxName == '/TrimBox' || $boxName == '/ArtBox'))
808+            $boxName = '/CropBox';
809+        if (!isset($pageboxes[$boxName]) && $boxName == '/CropBox')
810+            $boxName = '/MediaBox';
811+       
812+        if (!isset($pageboxes[$boxName]))
813+            return false;
814+        $this->lastUsedPageBox = $boxName;
815+       
816+        $box = $pageboxes[$boxName];
817+        $tpl['box'] = $box;
818+       
819+        // To build an array that can be used by PDF_TPL::useTemplate()
820+        $this->tpls[$this->tpl] = array_merge($this->tpls[$this->tpl],$box);
821+       
822+        // An imported page will start at 0,0 everytime. Translation will be set in _putformxobjects()
823+        $tpl['x'] = 0;
824+        $tpl['y'] = 0;
825+       
826+        $page =& $parser->pages[$parser->pageno];
827+       
828+        // handle rotated pages
829+        $rotation = $parser->getPageRotation($pageno);
830+        $tpl['_rotationAngle'] = 0;
831+        if (isset($rotation[1]) && ($angle = $rotation[1] % 360) != 0) {
832+            $steps = $angle / 90;
833+               
834+            $_w = $tpl['w'];
835+            $_h = $tpl['h'];
836+            $tpl['w'] = $steps % 2 == 0 ? $_w : $_h;
837+            $tpl['h'] = $steps % 2 == 0 ? $_h : $_w;
838+           
839+            $tpl['_rotationAngle'] = $angle*-1;
840+        }
841+       
842+        $this->_importedPages[$pageKey] = $this->tpl;
843+       
844+        return $this->tpl;
845+    }
846+   
847+    function getLastUsedPageBox() {
848+        return $this->lastUsedPageBox;
849+    }
850+   
851+    function useTemplate($tplidx, $_x=null, $_y=null, $_w=0, $_h=0, $adjustPageSize=false) {
852+        if ($adjustPageSize == true && is_null($_x) && is_null($_y)) {
853+            $size = $this->getTemplateSize($tplidx, $_w, $_h);
854+            $format = array($size['w'], $size['h']);
855+            if ($format[0]!=$this->CurPageFormat[0] || $format[1]!=$this->CurPageFormat[1]) {
856+                $this->w=$format[0];
857+                $this->h=$format[1];
858+                $this->wPt=$this->w*$this->k;
859+                       $this->hPt=$this->h*$this->k;
860+                       $this->PageBreakTrigger=$this->h-$this->bMargin;
861+                       $this->CurPageFormat=$format;
862+                       $this->PageSizes[$this->page]=array($this->wPt, $this->hPt);
863+            }
864+        }
865+       
866+        $this->_out('q 0 J 1 w 0 j 0 G 0 g'); // reset standard values
867+        $s = parent::useTemplate($tplidx, $_x, $_y, $_w, $_h);
868+        $this->_out('Q');
869+        return $s;
870+    }
871+   
872+    /**
873+     * Private method, that rebuilds all needed objects of source files
874+     */
875+    function _putimportedobjects() {
876+        if (is_array($this->parsers) && count($this->parsers) > 0) {
877+            foreach($this->parsers AS $filename => $p) {
878+                $this->current_parser =& $this->parsers[$filename];
879+                if (isset($this->_obj_stack[$filename]) && is_array($this->_obj_stack[$filename])) {
880+                    while(($n = key($this->_obj_stack[$filename])) !== null) {
881+                        $nObj = $this->current_parser->pdf_resolve_object($this->current_parser->c,$this->_obj_stack[$filename][$n][1]);
882+                                               
883+                        $this->_newobj($this->_obj_stack[$filename][$n][0]);
884+                       
885+                        if ($nObj[0] == PDF_TYPE_STREAM) {
886+                                                       $this->pdf_write_value ($nObj);
887+                        } else {
888+                            $this->pdf_write_value ($nObj[1]);
889+                        }
890+                       
891+                        $this->_out('endobj');
892+                        $this->_obj_stack[$filename][$n] = null; // free memory
893+                        unset($this->_obj_stack[$filename][$n]);
894+                        reset($this->_obj_stack[$filename]);
895+                    }
896+                }
897+            }
898+        }
899+    }
900+   
901+   
902+    /**
903+     * Private Method that writes the form xobjects
904+     */
905+    function _putformxobjects() {
906+        $filter=($this->compress) ? '/Filter /FlateDecode ' : '';
907+           reset($this->tpls);
908+        foreach($this->tpls AS $tplidx => $tpl) {
909+            $p=($this->compress) ? gzcompress($tpl['buffer']) : $tpl['buffer'];
910+               $this->_newobj();
911+               $cN = $this->n; // TCPDF/Protection: rem current "n"
912+               
913+               $this->tpls[$tplidx]['n'] = $this->n;
914+               $this->_out('<<'.$filter.'/Type /XObject');
915+            $this->_out('/Subtype /Form');
916+            $this->_out('/FormType 1');
917+           
918+            $this->_out(sprintf('/BBox [%.2F %.2F %.2F %.2F]',
919+                (isset($tpl['box']['llx']) ? $tpl['box']['llx'] : $tpl['x'])*$this->k,
920+                (isset($tpl['box']['lly']) ? $tpl['box']['lly'] : -$tpl['y'])*$this->k,
921+                (isset($tpl['box']['urx']) ? $tpl['box']['urx'] : $tpl['w'] + $tpl['x'])*$this->k,
922+                (isset($tpl['box']['ury']) ? $tpl['box']['ury'] : $tpl['h']-$tpl['y'])*$this->k
923+            ));
924+           
925+            $c = 1;
926+            $s = 0;
927+            $tx = 0;
928+            $ty = 0;
929+           
930+            if (isset($tpl['box'])) {
931+                $tx = -$tpl['box']['llx'];
932+                $ty = -$tpl['box']['lly'];
933+               
934+                if ($tpl['_rotationAngle'] <> 0) {
935+                    $angle = $tpl['_rotationAngle'] * M_PI/180;
936+                    $c=cos($angle);
937+                    $s=sin($angle);
938+                   
939+                    switch($tpl['_rotationAngle']) {
940+                        case -90:
941+                           $tx = -$tpl['box']['lly'];
942+                           $ty = $tpl['box']['urx'];
943+                           break;
944+                        case -180:
945+                            $tx = $tpl['box']['urx'];
946+                            $ty = $tpl['box']['ury'];
947+                            break;
948+                        case -270:
949+                            $tx = $tpl['box']['ury'];
950+                            $ty = 0;
951+                            break;
952+                    }
953+                }
954+            } else if ($tpl['x'] != 0 || $tpl['y'] != 0) {
955+                $tx = -$tpl['x']*2;
956+                $ty = $tpl['y']*2;
957+            }
958+           
959+            $tx *= $this->k;
960+            $ty *= $this->k;
961+           
962+            if ($c != 1 || $s != 0 || $tx != 0 || $ty != 0) {
963+                $this->_out(sprintf('/Matrix [%.5F %.5F %.5F %.5F %.5F %.5F]',
964+                    $c, $s, -$s, $c, $tx, $ty
965+                ));
966+            }
967+           
968+            $this->_out('/Resources ');
969+
970+            if (isset($tpl['resources'])) {
971+                $this->current_parser =& $tpl['parser'];
972+                $this->pdf_write_value($tpl['resources']); // "n" will be changed
973+            } else {
974+                $this->_out('<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
975+               if (isset($this->_res['tpl'][$tplidx]['fonts']) && count($this->_res['tpl'][$tplidx]['fonts'])) {
976+                       $this->_out('/Font <<');
977+                    foreach($this->_res['tpl'][$tplidx]['fonts'] as $font)
978+                               $this->_out('/F'.$font['i'].' '.$font['n'].' 0 R');
979+                       $this->_out('>>');
980+                }
981+               if(isset($this->_res['tpl'][$tplidx]['images']) && count($this->_res['tpl'][$tplidx]['images']) ||
982+                  isset($this->_res['tpl'][$tplidx]['tpls']) && count($this->_res['tpl'][$tplidx]['tpls']))
983+               {
984+                    $this->_out('/XObject <<');
985+                    if (isset($this->_res['tpl'][$tplidx]['images']) && count($this->_res['tpl'][$tplidx]['images'])) {
986+                        foreach($this->_res['tpl'][$tplidx]['images'] as $image)
987+                                       $this->_out('/I'.$image['i'].' '.$image['n'].' 0 R');
988+                    }
989+                    if (isset($this->_res['tpl'][$tplidx]['tpls']) && count($this->_res['tpl'][$tplidx]['tpls'])) {
990+                        foreach($this->_res['tpl'][$tplidx]['tpls'] as $i => $tpl)
991+                            $this->_out($this->tplprefix.$i.' '.$tpl['n'].' 0 R');
992+                    }
993+                    $this->_out('>>');
994+               }
995+               $this->_out('>>');
996+            }
997+
998+            $nN = $this->n; // TCPDF: rem new "n"
999+            $this->n = $cN; // TCPDF: reset to current "n"
1000+            $this->_out('/Length '.strlen($p).' >>');
1001+               $this->_putstream($p);
1002+               $this->_out('endobj');
1003+               $this->n = $nN; // TCPDF: reset to new "n"
1004+        }
1005+       
1006+        $this->_putimportedobjects();
1007+    }
1008+
1009+    /**
1010+     * Rewritten to handle existing own defined objects
1011+     */
1012+    function _newobj($obj_id=false,$onlynewobj=false) {
1013+        if (!$obj_id) {
1014+            $obj_id = ++$this->n;
1015+        }
1016+
1017+        //Begin a new object
1018+        if (!$onlynewobj) {
1019+            $this->offsets[$obj_id] = is_subclass_of($this, 'TCPDF') ? $this->bufferlen : strlen($this->buffer);
1020+            $this->_out($obj_id.' 0 obj');
1021+            $this->_current_obj_id = $obj_id; // for later use with encryption
1022+        }
1023+    }
1024+
1025+    /**
1026+     * Writes a value
1027+     * Needed to rebuild the source document
1028+     *
1029+     * @param mixed $value A PDF-Value. Structure of values see cases in this method
1030+     */
1031+    function pdf_write_value(&$value)
1032+    {
1033+        if (is_subclass_of($this, 'TCPDF')) {
1034+            parent::pdf_write_value($value);
1035+        }
1036+       
1037+        switch ($value[0]) {
1038+
1039+               case PDF_TYPE_TOKEN :
1040+                $this->_straightOut($value[1] . ' ');
1041+                       break;
1042+                   case PDF_TYPE_NUMERIC :
1043+               case PDF_TYPE_REAL :
1044+                if (is_float($value[1]) && $value[1] != 0) {
1045+                           $this->_straightOut(rtrim(rtrim(sprintf('%F', $value[1]), '0'), '.') .' ');
1046+                       } else {
1047+                               $this->_straightOut($value[1] . ' ');
1048+                       }
1049+                       break;
1050+                       
1051+               case PDF_TYPE_ARRAY :
1052+
1053+                       // An array. Output the proper
1054+                       // structure and move on.
1055+
1056+                       $this->_straightOut('[');
1057+                for ($i = 0; $i < count($value[1]); $i++) {
1058+                               $this->pdf_write_value($value[1][$i]);
1059+                       }
1060+
1061+                       $this->_out(']');
1062+                       break;
1063+
1064+               case PDF_TYPE_DICTIONARY :
1065+
1066+                       // A dictionary.
1067+                       $this->_straightOut('<<');
1068+
1069+                       reset ($value[1]);
1070+
1071+                       while (list($k, $v) = each($value[1])) {
1072+                               $this->_straightOut($k . ' ');
1073+                               $this->pdf_write_value($v);
1074+                       }
1075+
1076+                       $this->_straightOut('>>');
1077+                       break;
1078+
1079+               case PDF_TYPE_OBJREF :
1080+
1081+                       // An indirect object reference
1082+                       // Fill the object stack if needed
1083+                       $cpfn =& $this->current_parser->filename;
1084+                       
1085+                       if (!isset($this->_don_obj_stack[$cpfn][$value[1]])) {
1086+                           $this->_newobj(false,true);
1087+                           $this->_obj_stack[$cpfn][$value[1]] = array($this->n, $value);
1088+                    $this->_don_obj_stack[$cpfn][$value[1]] = array($this->n, $value); // Value is maybee obsolete!!!
1089+                }
1090+                $objid = $this->_don_obj_stack[$cpfn][$value[1]][0];
1091+
1092+                       $this->_out($objid.' 0 R');
1093+                       break;
1094+
1095+               case PDF_TYPE_STRING :
1096+
1097+                       // A string.
1098+                $this->_straightOut('('.$value[1].')');
1099+
1100+                       break;
1101+
1102+               case PDF_TYPE_STREAM :
1103+
1104+                       // A stream. First, output the
1105+                       // stream dictionary, then the
1106+                       // stream data itself.
1107+                $this->pdf_write_value($value[1]);
1108+                       $this->_out('stream');
1109+                       $this->_out($value[2][1]);
1110+                       $this->_out('endstream');
1111+                       break;
1112+            case PDF_TYPE_HEX :
1113+                $this->_straightOut('<'.$value[1].'>');
1114+                break;
1115+
1116+            case PDF_TYPE_BOOLEAN :
1117+                   $this->_straightOut($value[1] ? 'true ' : 'false ');
1118+                   break;
1119+           
1120+               case PDF_TYPE_NULL :
1121+                // The null object.
1122+
1123+                       $this->_straightOut('null ');
1124+                       break;
1125+       }
1126+    }
1127+   
1128+   
1129+    /**
1130+     * Modified so not each call will add a newline to the output.
1131+     */
1132+    function _straightOut($s) {
1133+        if (!is_subclass_of($this, 'TCPDF')) {
1134+            if($this->state==2)
1135+                       $this->pages[$this->page] .= $s;
1136+               else
1137+                       $this->buffer .= $s;
1138+        } else {
1139+            if ($this->state == 2) {
1140+                               if (isset($this->footerlen[$this->page]) AND ($this->footerlen[$this->page] > 0)) {
1141+                                       // puts data before page footer
1142+                                       $page = substr($this->getPageBuffer($this->page), 0, -$this->footerlen[$this->page]);
1143+                                       $footer = substr($this->getPageBuffer($this->page), -$this->footerlen[$this->page]);
1144+                                       $this->setPageBuffer($this->page, $page.' '.$s."\n".$footer);
1145+                               } else {
1146+                                       $this->setPageBuffer($this->page, $s, true);
1147+                               }
1148+                       } else {
1149+                               $this->setBuffer($s);
1150+                       }
1151+        }
1152+    }
1153+
1154+    /**
1155+     * rewritten to close opened parsers
1156+     *
1157+     */
1158+    function _enddoc() {
1159+        parent::_enddoc();
1160+        $this->_closeParsers();
1161+    }
1162+   
1163+    /**
1164+     * close all files opened by parsers
1165+     */
1166+    function _closeParsers() {
1167+        if ($this->state > 2 && count($this->parsers) > 0) {
1168+               foreach ($this->parsers as $k => $_){
1169+               $this->parsers[$k]->closeFile();
1170+               $this->parsers[$k] = null;
1171+               unset($this->parsers[$k]);
1172+            }
1173+            return true;
1174+        }
1175+        return false;
1176+    }
1177+
1178+}
1179Index: fpdf/fpdi2tcpdf_bridge.php
1180===================================================================
1181--- fpdf/fpdi2tcpdf_bridge.php  (revision 0)
1182+++ fpdf/fpdi2tcpdf_bridge.php  (revision 0)
1183@@ -0,0 +1,171 @@
1184+<?php
1185+//
1186+//  FPDI - Version 1.3
1187+//
1188+//    Copyright 2004-2009 Setasign - Jan Slabon
1189+//
1190+//  Licensed under the Apache License, Version 2.0 (the "License");
1191+//  you may not use this file except in compliance with the License.
1192+//  You may obtain a copy of the License at
1193+//
1194+//      http://www.apache.org/licenses/LICENSE-2.0
1195+//
1196+//  Unless required by applicable law or agreed to in writing, software
1197+//  distributed under the License is distributed on an "AS IS" BASIS,
1198+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1199+//  See the License for the specific language governing permissions and
1200+//  limitations under the License.
1201+//
1202+
1203+/**
1204+ * This class is used as a bridge between TCPDF and FPDI
1205+ * and will create the possibility to use both FPDF and TCPDF
1206+ * via one FPDI version.
1207+ *
1208+ * We'll simply remap TCPDF to FPDF again.
1209+ *
1210+ * It'll be loaded and extended by FPDF_TPL.
1211+ */
1212+class FPDF extends TCPDF {
1213+   
1214+    function __get($name) {
1215+        switch ($name) {
1216+            case 'PDFVersion':
1217+                return $this->PDFVersion;
1218+            case 'k':
1219+                return $this->k;
1220+            default:
1221+                // Error handling
1222+                $this->Error('Cannot access protected property '.get_class($this).':$'.$name.' / Undefined property: '.get_class($this).'::$'.$name);
1223+        }
1224+    }
1225+
1226+    function __set($name, $value) {
1227+        switch ($name) {
1228+            case 'PDFVersion':
1229+                $this->PDFVersion = $value;
1230+                break;
1231+            default:
1232+                // Error handling
1233+                $this->Error('Cannot access protected property '.get_class($this).':$'.$name.' / Undefined property: '.get_class($this).'::$'.$name);
1234+        }
1235+    }
1236+
1237+    /**
1238+     * Encryption of imported data by FPDI
1239+     *
1240+     * @param array $value
1241+     */
1242+    function pdf_write_value(&$value) {
1243+        switch ($value[0]) {
1244+               case PDF_TYPE_STRING :
1245+                               if ($this->encrypted) {
1246+                                   $value[1] = $this->_unescape($value[1]);
1247+                    $value[1] = $this->_RC4($this->_objectkey($this->_current_obj_id), $value[1]);
1248+                       $value[1] = $this->_escape($value[1]);
1249+                }
1250+                       break;
1251+                       
1252+                       case PDF_TYPE_STREAM :
1253+                           if ($this->encrypted) {
1254+                               $value[2][1] = $this->_RC4($this->_objectkey($this->_current_obj_id), $value[2][1]);
1255+                }
1256+                break;
1257+               
1258+            case PDF_TYPE_HEX :
1259+               if ($this->encrypted) {
1260+                       $value[1] = $this->hex2str($value[1]);
1261+                       $value[1] = $this->_RC4($this->_objectkey($this->_current_obj_id), $value[1]);
1262+                   
1263+                       // remake hexstring of encrypted string
1264+                               $value[1] = $this->str2hex($value[1]);
1265+                }
1266+                break;
1267+       }
1268+    }
1269+   
1270+    /**
1271+     * Unescapes a PDF string
1272+     *
1273+     * @param string $s
1274+     * @return string
1275+     */
1276+    function _unescape($s) {
1277+        $out = '';
1278+        for ($count = 0, $n = strlen($s); $count < $n; $count++) {
1279+            if ($s[$count] != '\\' || $count == $n-1) {
1280+                $out .= $s[$count];
1281+            } else {
1282+                switch ($s[++$count]) {
1283+                    case ')':
1284+                    case '(':
1285+                    case '\\':
1286+                        $out .= $s[$count];
1287+                        break;
1288+                    case 'f':
1289+                        $out .= chr(0x0C);
1290+                        break;
1291+                    case 'b':
1292+                        $out .= chr(0x08);
1293+                        break;
1294+                    case 't':
1295+                        $out .= chr(0x09);
1296+                        break;
1297+                    case 'r':
1298+                        $out .= chr(0x0D);
1299+                        break;
1300+                    case 'n':
1301+                        $out .= chr(0x0A);
1302+                        break;
1303+                    case "\r":
1304+                        if ($count != $n-1 && $s[$count+1] == "\n")
1305+                            $count++;
1306+                        break;
1307+                    case "\n":
1308+                        break;
1309+                    default:
1310+                        // Octal-Values
1311+                        if (ord($s[$count]) >= ord('0') &&
1312+                            ord($s[$count]) <= ord('9')) {
1313+                            $oct = ''. $s[$count];
1314+                               
1315+                            if (ord($s[$count+1]) >= ord('0') &&
1316+                                ord($s[$count+1]) <= ord('9')) {
1317+                                $oct .= $s[++$count];
1318+                               
1319+                                if (ord($s[$count+1]) >= ord('0') &&
1320+                                    ord($s[$count+1]) <= ord('9')) {
1321+                                    $oct .= $s[++$count];   
1322+                                }                           
1323+                            }
1324+                           
1325+                            $out .= chr(octdec($oct));
1326+                        } else {
1327+                            $out .= $s[$count];
1328+                        }
1329+                }
1330+            }
1331+        }
1332+        return $out;
1333+    }
1334+   
1335+    /**
1336+     * Hexadecimal to string
1337+     *
1338+     * @param string $hex
1339+     * @return string
1340+     */
1341+    function hex2str($hex) {
1342+       return pack('H*', str_replace(array("\r", "\n", ' '), '', $hex));
1343+    }
1344+   
1345+    /**
1346+     * String to hexadecimal
1347+     *
1348+     * @param string $str
1349+     * @return string
1350+     */
1351+    function str2hex($str) {
1352+        return current(unpack('H*', $str));
1353+    }
1354+}
1355Index: fpdf/fpdi_pdf_parser.php
1356===================================================================
1357--- fpdf/fpdi_pdf_parser.php    (revision 0)
1358+++ fpdf/fpdi_pdf_parser.php    (revision 0)
1359@@ -0,0 +1,384 @@
1360+<?php
1361+//
1362+//  FPDI - Version 1.3
1363+//
1364+//    Copyright 2004-2009 Setasign - Jan Slabon
1365+//
1366+//  Licensed under the Apache License, Version 2.0 (the "License");
1367+//  you may not use this file except in compliance with the License.
1368+//  You may obtain a copy of the License at
1369+//
1370+//      http://www.apache.org/licenses/LICENSE-2.0
1371+//
1372+//  Unless required by applicable law or agreed to in writing, software
1373+//  distributed under the License is distributed on an "AS IS" BASIS,
1374+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1375+//  See the License for the specific language governing permissions and
1376+//  limitations under the License.
1377+//
1378+
1379+require_once('pdf_parser.php');
1380+
1381+class fpdi_pdf_parser extends pdf_parser {
1382+
1383+    /**
1384+     * Pages
1385+     * Index beginns at 0
1386+     *
1387+     * @var array
1388+     */
1389+    var $pages;
1390+   
1391+    /**
1392+     * Page count
1393+     * @var integer
1394+     */
1395+    var $page_count;
1396+   
1397+    /**
1398+     * actual page number
1399+     * @var integer
1400+     */
1401+    var $pageno;
1402+   
1403+    /**
1404+     * PDF Version of imported Document
1405+     * @var string
1406+     */
1407+    var $pdfVersion;
1408+   
1409+    /**
1410+     * FPDI Reference
1411+     * @var object
1412+     */
1413+    var $fpdi;
1414+   
1415+    /**
1416+     * Available BoxTypes
1417+     *
1418+     * @var array
1419+     */
1420+    var $availableBoxes = array('/MediaBox', '/CropBox', '/BleedBox', '/TrimBox', '/ArtBox');
1421+       
1422+    /**
1423+     * Constructor
1424+     *
1425+     * @param string $filename  Source-Filename
1426+     * @param object $fpdi      Object of type fpdi
1427+     */
1428+    function fpdi_pdf_parser($filename, &$fpdi) {
1429+        $this->fpdi =& $fpdi;
1430+               
1431+        parent::pdf_parser($filename);
1432+
1433+        // resolve Pages-Dictonary
1434+        $pages = $this->pdf_resolve_object($this->c, $this->root[1][1]['/Pages']);
1435+
1436+        // Read pages
1437+        $this->read_pages($this->c, $pages, $this->pages);
1438+       
1439+        // count pages;
1440+        $this->page_count = count($this->pages);
1441+    }
1442+   
1443+    /**
1444+     * Overwrite parent::error()
1445+     *
1446+     * @param string $msg  Error-Message
1447+     */
1448+    function error($msg) {
1449+       $this->fpdi->error($msg);       
1450+    }
1451+   
1452+    /**
1453+     * Get pagecount from sourcefile
1454+     *
1455+     * @return int
1456+     */
1457+    function getPageCount() {
1458+        return $this->page_count;
1459+    }
1460+
1461+
1462+    /**
1463+     * Set pageno
1464+     *
1465+     * @param int $pageno Pagenumber to use
1466+     */
1467+    function setPageno($pageno) {
1468+        $pageno = ((int) $pageno) - 1;
1469+
1470+        if ($pageno < 0 || $pageno >= $this->getPageCount()) {
1471+            $this->fpdi->error('Pagenumber is wrong!');
1472+        }
1473+
1474+        $this->pageno = $pageno;
1475+    }
1476+   
1477+    /**
1478+     * Get page-resources from current page
1479+     *
1480+     * @return array
1481+     */
1482+    function getPageResources() {
1483+        return $this->_getPageResources($this->pages[$this->pageno]);
1484+    }
1485+   
1486+    /**
1487+     * Get page-resources from /Page
1488+     *
1489+     * @param array $obj Array of pdf-data
1490+     */
1491+    function _getPageResources ($obj) { // $obj = /Page
1492+       $obj = $this->pdf_resolve_object($this->c, $obj);
1493+
1494+        // If the current object has a resources
1495+       // dictionary associated with it, we use
1496+       // it. Otherwise, we move back to its
1497+       // parent object.
1498+        if (isset ($obj[1][1]['/Resources'])) {
1499+               $res = $this->pdf_resolve_object($this->c, $obj[1][1]['/Resources']);
1500+               if ($res[0] == PDF_TYPE_OBJECT)
1501+                return $res[1];
1502+            return $res;
1503+       } else {
1504+               if (!isset ($obj[1][1]['/Parent'])) {
1505+                       return false;
1506+               } else {
1507+                $res = $this->_getPageResources($obj[1][1]['/Parent']);
1508+                if ($res[0] == PDF_TYPE_OBJECT)
1509+                    return $res[1];
1510+                return $res;
1511+               }
1512+       }
1513+    }
1514+
1515+
1516+    /**
1517+     * Get content of current page
1518+     *
1519+     * If more /Contents is an array, the streams are concated
1520+     *
1521+     * @return string
1522+     */
1523+    function getContent() {
1524+        $buffer = '';
1525+       
1526+        if (isset($this->pages[$this->pageno][1][1]['/Contents'])) {
1527+            $contents = $this->_getPageContent($this->pages[$this->pageno][1][1]['/Contents']);
1528+            foreach($contents AS $tmp_content) {
1529+                $buffer .= $this->_rebuildContentStream($tmp_content).' ';
1530+            }
1531+        }
1532+       
1533+        return $buffer;
1534+    }
1535+   
1536+   
1537+    /**
1538+     * Resolve all content-objects
1539+     *
1540+     * @param array $content_ref
1541+     * @return array
1542+     */
1543+    function _getPageContent($content_ref) {
1544+        $contents = array();
1545+       
1546+        if ($content_ref[0] == PDF_TYPE_OBJREF) {
1547+            $content = $this->pdf_resolve_object($this->c, $content_ref);
1548+            if ($content[1][0] == PDF_TYPE_ARRAY) {
1549+                $contents = $this->_getPageContent($content[1]);
1550+            } else {
1551+                $contents[] = $content;
1552+            }
1553+        } else if ($content_ref[0] == PDF_TYPE_ARRAY) {
1554+            foreach ($content_ref[1] AS $tmp_content_ref) {
1555+                $contents = array_merge($contents,$this->_getPageContent($tmp_content_ref));
1556+            }
1557+        }
1558+
1559+        return $contents;
1560+    }
1561+
1562+
1563+    /**
1564+     * Rebuild content-streams
1565+     *
1566+     * @param array $obj
1567+     * @return string
1568+     */
1569+    function _rebuildContentStream($obj) {
1570+        $filters = array();
1571+       
1572+        if (isset($obj[1][1]['/Filter'])) {
1573+            $_filter = $obj[1][1]['/Filter'];
1574+
1575+            if ($_filter[0] == PDF_TYPE_TOKEN) {
1576+                $filters[] = $_filter;
1577+            } else if ($_filter[0] == PDF_TYPE_ARRAY) {
1578+                $filters = $_filter[1];
1579+            }
1580+        }
1581+
1582+        $stream = $obj[2][1];
1583+
1584+        foreach ($filters AS $_filter) {
1585+            switch ($_filter[1]) {
1586+                case '/FlateDecode':
1587+                    if (function_exists('gzuncompress')) {
1588+                        $stream = (strlen($stream) > 0) ? @gzuncompress($stream) : '';                       
1589+                    } else {
1590+                        $this->fpdi->error(sprintf('To handle %s filter, please compile php with zlib support.',$_filter[1]));
1591+                    }
1592+                    if ($stream === false) {
1593+                        $this->fpdi->error('Error while decompressing stream.');
1594+                    }
1595+                break;
1596+                case null:
1597+                    $stream = $stream;
1598+                break;
1599+                default:
1600+                    if (preg_match('/^\/[a-z85]*$/i', $_filter[1], $filterName) && @include_once('decoders'.$_filter[1].'.php')) {
1601+                        $filterName = substr($_filter[1],1);
1602+                        if (class_exists($filterName)) {
1603+                               $decoder =& new $filterName($this->fpdi);
1604+                           $stream = $decoder->decode($stream);
1605+                        } else {
1606+                               $this->fpdi->error(sprintf('Unsupported Filter: %s',$_filter[1]));
1607+                        }
1608+                    } else {
1609+                        $this->fpdi->error(sprintf('Unsupported Filter: %s',$_filter[1]));
1610+                    }
1611+            }
1612+        }
1613+       
1614+        return $stream;
1615+    }
1616+   
1617+   
1618+    /**
1619+     * Get a Box from a page
1620+     * Arrayformat is same as used by fpdf_tpl
1621+     *
1622+     * @param array $page a /Page
1623+     * @param string $box_index Type of Box @see $availableBoxes
1624+     * @return array
1625+     */
1626+    function getPageBox($page, $box_index) {
1627+        $page = $this->pdf_resolve_object($this->c,$page);
1628+        $box = null;
1629+        if (isset($page[1][1][$box_index]))
1630+            $box =& $page[1][1][$box_index];
1631+       
1632+        if (!is_null($box) && $box[0] == PDF_TYPE_OBJREF) {
1633+            $tmp_box = $this->pdf_resolve_object($this->c,$box);
1634+            $box = $tmp_box[1];
1635+        }
1636+           
1637+        if (!is_null($box) && $box[0] == PDF_TYPE_ARRAY) {
1638+            $b =& $box[1];
1639+            return array('x' => $b[0][1]/$this->fpdi->k,
1640+                         'y' => $b[1][1]/$this->fpdi->k,
1641+                         'w' => abs($b[0][1]-$b[2][1])/$this->fpdi->k,
1642+                         'h' => abs($b[1][1]-$b[3][1])/$this->fpdi->k,
1643+                         'llx' => $b[0][1]/$this->fpdi->k,
1644+                         'lly' => $b[1][1]/$this->fpdi->k,
1645+                         'urx' => $b[2][1]/$this->fpdi->k,
1646+                         'ury' => $b[3][1]/$this->fpdi->k,
1647+                         );
1648+        } else if (!isset ($page[1][1]['/Parent'])) {
1649+            return false;
1650+        } else {
1651+            return $this->getPageBox($this->pdf_resolve_object($this->c, $page[1][1]['/Parent']), $box_index);
1652+        }
1653+    }
1654+
1655+    function getPageBoxes($pageno) {
1656+        return $this->_getPageBoxes($this->pages[$pageno-1]);
1657+    }
1658+   
1659+    /**
1660+     * Get all Boxes from /Page
1661+     *
1662+     * @param array a /Page
1663+     * @return array
1664+     */
1665+    function _getPageBoxes($page) {
1666+        $boxes = array();
1667+
1668+        foreach($this->availableBoxes AS $box) {
1669+            if ($_box = $this->getPageBox($page,$box)) {
1670+                $boxes[$box] = $_box;
1671+            }
1672+        }
1673+
1674+        return $boxes;
1675+    }
1676+
1677+    /**
1678+     * Get the page rotation by pageno
1679+     *
1680+     * @param integer $pageno
1681+     * @return array
1682+     */
1683+    function getPageRotation($pageno) {
1684+        return $this->_getPageRotation($this->pages[$pageno-1]);
1685+    }
1686+   
1687+    function _getPageRotation ($obj) { // $obj = /Page
1688+       $obj = $this->pdf_resolve_object($this->c, $obj);
1689+       if (isset ($obj[1][1]['/Rotate'])) {
1690+               $res = $this->pdf_resolve_object($this->c, $obj[1][1]['/Rotate']);
1691+               if ($res[0] == PDF_TYPE_OBJECT)
1692+                return $res[1];
1693+            return $res;
1694+       } else {
1695+               if (!isset ($obj[1][1]['/Parent'])) {
1696+                       return false;
1697+               } else {
1698+                $res = $this->_getPageRotation($obj[1][1]['/Parent']);
1699+                if ($res[0] == PDF_TYPE_OBJECT)
1700+                    return $res[1];
1701+                return $res;
1702+               }
1703+       }
1704+    }
1705+   
1706+    /**
1707+     * Read all /Page(es)
1708+     *
1709+     * @param object pdf_context
1710+     * @param array /Pages
1711+     * @param array the result-array
1712+     */
1713+    function read_pages (&$c, &$pages, &$result) {
1714+        // Get the kids dictionary
1715+       $kids = $this->pdf_resolve_object ($c, $pages[1][1]['/Kids']);
1716+
1717+        if (!is_array($kids))
1718+            $this->fpdi->Error('Cannot find /Kids in current /Page-Dictionary');
1719+        foreach ($kids[1] as $v) {
1720+               $pg = $this->pdf_resolve_object ($c, $v);
1721+            if ($pg[1][1]['/Type'][1] === '/Pages') {
1722+                // If one of the kids is an embedded
1723+                       // /Pages array, resolve it as well.
1724+                $this->read_pages ($c, $pg, $result);
1725+               } else {
1726+                       $result[] = $pg;
1727+               }
1728+       }
1729+    }
1730+
1731+   
1732+   
1733+    /**
1734+     * Get PDF-Version
1735+     *
1736+     * And reset the PDF Version used in FPDI if needed
1737+     */
1738+    function getPDFVersion() {
1739+        parent::getPDFVersion();
1740+        $this->fpdi->PDFVersion = max($this->fpdi->PDFVersion, $this->pdfVersion);
1741+    }
1742+   
1743+}
1744Index: fpdf/pdf_context.php
1745===================================================================
1746--- fpdf/pdf_context.php        (revision 0)
1747+++ fpdf/pdf_context.php        (revision 0)
1748@@ -0,0 +1,97 @@
1749+<?php
1750+//
1751+//  FPDI - Version 1.3
1752+//
1753+//    Copyright 2004-2009 Setasign - Jan Slabon
1754+//
1755+//  Licensed under the Apache License, Version 2.0 (the "License");
1756+//  you may not use this file except in compliance with the License.
1757+//  You may obtain a copy of the License at
1758+//
1759+//      http://www.apache.org/licenses/LICENSE-2.0
1760+//
1761+//  Unless required by applicable law or agreed to in writing, software
1762+//  distributed under the License is distributed on an "AS IS" BASIS,
1763+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1764+//  See the License for the specific language governing permissions and
1765+//  limitations under the License.
1766+//
1767+
1768+class pdf_context {
1769+
1770+    /**
1771+     * Modi
1772+     *
1773+     * @var integer 0 = file | 1 = string
1774+     */
1775+    var $_mode = 0;
1776+   
1777+       var $file;
1778+       var $buffer;
1779+       var $offset;
1780+       var $length;
1781+
1782+       var $stack;
1783+
1784+       // Constructor
1785+
1786+       function pdf_context(&$f) {
1787+               $this->file =& $f;
1788+               if (is_string($this->file))
1789+                   $this->_mode = 1;
1790+               $this->reset();
1791+       }
1792+
1793+       // Optionally move the file
1794+       // pointer to a new location
1795+       // and reset the buffered data
1796+
1797+       function reset($pos = null, $l = 100) {
1798+           if ($this->_mode == 0) {
1799+               if (!is_null ($pos)) {
1800+                       fseek ($this->file, $pos);
1801+               }
1802+   
1803+               $this->buffer = $l > 0 ? fread($this->file, $l) : '';
1804+               $this->length = strlen($this->buffer);
1805+               if ($this->length < $l)
1806+                $this->increase_length($l - $this->length);
1807+           } else {
1808+               $this->buffer = $this->file;
1809+               $this->length = strlen($this->buffer);
1810+           }
1811+               $this->offset = 0;
1812+               $this->stack = array();
1813+       }
1814+
1815+       // Make sure that there is at least one
1816+       // character beyond the current offset in
1817+       // the buffer to prevent the tokenizer
1818+       // from attempting to access data that does
1819+       // not exist
1820+
1821+       function ensure_content() {
1822+               if ($this->offset >= $this->length - 1) {
1823+                       return $this->increase_length();
1824+               } else {
1825+                       return true;
1826+               }
1827+       }
1828+
1829+       // Forcefully read more data into the buffer
1830+
1831+       function increase_length($l=100) {
1832+               if ($this->_mode == 0 && feof($this->file)) {
1833+                       return false;
1834+               } else if ($this->_mode == 0) {
1835+                   $totalLength = $this->length + $l;
1836+                   do {
1837+                $this->buffer .= fread($this->file, $totalLength-$this->length);
1838+            } while ((($this->length = strlen($this->buffer)) != $totalLength) && !feof($this->file));
1839+                       
1840+                       return true;
1841+               } else {
1842+               return false;
1843+               }
1844+       }
1845+}
1846Index: fpdf/pdf_parser.php
1847===================================================================
1848--- fpdf/pdf_parser.php (revision 0)
1849+++ fpdf/pdf_parser.php (revision 0)
1850@@ -0,0 +1,694 @@
1851+<?php
1852+//
1853+//  FPDI - Version 1.3
1854+//
1855+//    Copyright 2004-2009 Setasign - Jan Slabon
1856+//
1857+//  Licensed under the Apache License, Version 2.0 (the "License");
1858+//  you may not use this file except in compliance with the License.
1859+//  You may obtain a copy of the License at
1860+//
1861+//      http://www.apache.org/licenses/LICENSE-2.0
1862+//
1863+//  Unless required by applicable law or agreed to in writing, software
1864+//  distributed under the License is distributed on an "AS IS" BASIS,
1865+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1866+//  See the License for the specific language governing permissions and
1867+//  limitations under the License.
1868+//
1869+
1870+if (!defined ('PDF_TYPE_NULL'))
1871+    define ('PDF_TYPE_NULL', 0);
1872+if (!defined ('PDF_TYPE_NUMERIC'))
1873+    define ('PDF_TYPE_NUMERIC', 1);
1874+if (!defined ('PDF_TYPE_TOKEN'))
1875+    define ('PDF_TYPE_TOKEN', 2);
1876+if (!defined ('PDF_TYPE_HEX'))
1877+    define ('PDF_TYPE_HEX', 3);
1878+if (!defined ('PDF_TYPE_STRING'))
1879+    define ('PDF_TYPE_STRING', 4);
1880+if (!defined ('PDF_TYPE_DICTIONARY'))
1881+    define ('PDF_TYPE_DICTIONARY', 5);
1882+if (!defined ('PDF_TYPE_ARRAY'))
1883+    define ('PDF_TYPE_ARRAY', 6);
1884+if (!defined ('PDF_TYPE_OBJDEC'))
1885+    define ('PDF_TYPE_OBJDEC', 7);
1886+if (!defined ('PDF_TYPE_OBJREF'))
1887+    define ('PDF_TYPE_OBJREF', 8);
1888+if (!defined ('PDF_TYPE_OBJECT'))
1889+    define ('PDF_TYPE_OBJECT', 9);
1890+if (!defined ('PDF_TYPE_STREAM'))
1891+    define ('PDF_TYPE_STREAM', 10);
1892+if (!defined ('PDF_TYPE_BOOLEAN'))
1893+    define ('PDF_TYPE_BOOLEAN', 11);
1894+if (!defined ('PDF_TYPE_REAL'))
1895+    define ('PDF_TYPE_REAL', 12);
1896+   
1897+require_once('pdf_context.php');
1898+
1899+class pdf_parser {
1900+       
1901+       /**
1902+     * Filename
1903+     * @var string
1904+     */
1905+    var $filename;
1906+   
1907+    /**
1908+     * File resource
1909+     * @var resource
1910+     */
1911+    var $f;
1912+   
1913+    /**
1914+     * PDF Context
1915+     * @var object pdf_context-Instance
1916+     */
1917+    var $c;
1918+   
1919+    /**
1920+     * xref-Data
1921+     * @var array
1922+     */
1923+    var $xref;
1924+
1925+    /**
1926+     * root-Object
1927+     * @var array
1928+     */
1929+    var $root;
1930+       
1931+    /**
1932+     * PDF version of the loaded document
1933+     * @var string
1934+     */
1935+    var $pdfVersion;
1936+   
1937+    /**
1938+     * Constructor
1939+     *
1940+     * @param string $filename  Source-Filename
1941+     */
1942+       function pdf_parser($filename) {
1943+        $this->filename = $filename;
1944+       
1945+        $this->f = @fopen($this->filename, 'rb');
1946+
1947+        if (!$this->f)
1948+            $this->error(sprintf('Cannot open %s !', $filename));
1949+
1950+        $this->getPDFVersion();
1951+
1952+        $this->c =& new pdf_context($this->f);
1953+       
1954+        // Read xref-Data
1955+        $this->pdf_read_xref($this->xref, $this->pdf_find_xref());
1956+       
1957+        // Check for Encryption
1958+        $this->getEncryption();
1959+
1960+        // Read root
1961+        $this->pdf_read_root();
1962+    }
1963+   
1964+    /**
1965+     * Close the opened file
1966+     */
1967+    function closeFile() {
1968+       if (isset($this->f)) {
1969+           fclose($this->f);   
1970+               unset($this->f);
1971+       }       
1972+    }
1973+   
1974+    /**
1975+     * Print Error and die
1976+     *
1977+     * @param string $msg  Error-Message
1978+     */
1979+    function error($msg) {
1980+       die('<b>PDF-Parser Error:</b> '.$msg); 
1981+    }
1982+   
1983+    /**
1984+     * Check Trailer for Encryption
1985+     */
1986+    function getEncryption() {
1987+        if (isset($this->xref['trailer'][1]['/Encrypt'])) {
1988+            $this->error('File is encrypted!');
1989+        }
1990+    }
1991+   
1992+       /**
1993+     * Find/Return /Root
1994+     *
1995+     * @return array
1996+     */
1997+    function pdf_find_root() {
1998+        if ($this->xref['trailer'][1]['/Root'][0] != PDF_TYPE_OBJREF) {
1999+            $this->error('Wrong Type of Root-Element! Must be an indirect reference');
2000+        }
2001+        return $this->xref['trailer'][1]['/Root'];
2002+    }
2003+
2004+    /**
2005+     * Read the /Root
2006+     */
2007+    function pdf_read_root() {
2008+        // read root
2009+        $this->root = $this->pdf_resolve_object($this->c, $this->pdf_find_root());
2010+    }
2011+   
2012+    /**
2013+     * Get PDF-Version
2014+     *
2015+     * And reset the PDF Version used in FPDI if needed
2016+     */
2017+    function getPDFVersion() {
2018+        fseek($this->f, 0);
2019+        preg_match('/\d\.\d/',fread($this->f,16),$m);
2020+        if (isset($m[0]))
2021+            $this->pdfVersion = $m[0];
2022+        return $this->pdfVersion;
2023+    }
2024+   
2025+    /**
2026+     * Find the xref-Table
2027+     */
2028+    function pdf_find_xref() {
2029+               $toRead = 1500;
2030+               
2031+        $stat = fseek ($this->f, -$toRead, SEEK_END);
2032+        if ($stat === -1) {
2033+            fseek ($this->f, 0);
2034+        }
2035+               $data = fread($this->f, $toRead);
2036+       
2037+        $pos = strlen($data) - strpos(strrev($data), strrev('startxref'));
2038+        $data = substr($data, $pos);
2039+       
2040+        if (!preg_match('/\s*(\d+).*$/s', $data, $matches)) {
2041+            $this->error('Unable to find pointer to xref table');
2042+       }
2043+
2044+       return (int) $matches[1];
2045+    }
2046+
2047+    /**
2048+     * Read xref-table
2049+     *
2050+     * @param array $result Array of xref-table
2051+     * @param integer $offset of xref-table
2052+     */
2053+    function pdf_read_xref(&$result, $offset) {
2054+       
2055+        fseek($this->f, $o_pos = $offset-20); // set some bytes backwards to fetch errorious docs
2056+           
2057+        $data = fread($this->f, 100);
2058+       
2059+        $xrefPos = strpos($data, 'xref');
2060+       
2061+        if ($xrefPos === false) {
2062+            $this->error('Unable to find xref table.');
2063+        }
2064+       
2065+        if (!isset($result['xref_location'])) {
2066+            $result['xref_location'] = $o_pos+$xrefPos;
2067+            $result['max_object'] = 0;
2068+       }
2069+
2070+       $cylces = -1;
2071+        $bytesPerCycle = 100;
2072+       
2073+       fseek($this->f, $o_pos = $o_pos+$xrefPos+4); // set the handle directly after the "xref"-keyword
2074+        $data = fread($this->f, $bytesPerCycle);
2075+       
2076+        while (($trailerPos = strpos($data, 'trailer', max($bytesPerCycle*$cylces++, 0))) === false && !feof($this->f)) {
2077+            $data .= fread($this->f, $bytesPerCycle);
2078+        }
2079+       
2080+        if ($trailerPos === false) {
2081+            $this->error('Trailer keyword not found after xref table');
2082+        }
2083+       
2084+        $data = substr($data, 0, $trailerPos);
2085+       
2086+        // get Line-Ending
2087+        preg_match_all("/(\r\n|\n|\r)/", substr($data, 0, 100), $m); // check the first 100 bytes for linebreaks
2088+
2089+        $differentLineEndings = count(array_unique($m[0]));
2090+        if ($differentLineEndings > 1) {
2091+            $lines = preg_split("/(\r\n|\n|\r)/", $data, -1, PREG_SPLIT_NO_EMPTY);
2092+        } else {
2093+            $lines = explode($m[0][1], $data);
2094+        }
2095+       
2096+        $data = $differentLineEndings = $m = null;
2097+        unset($data, $differentLineEndings, $m);
2098+       
2099+        $linesCount = count($lines);
2100+       
2101+        $start = 1;
2102+       
2103+        for ($i = 0; $i < $linesCount; $i++) {
2104+            $line = trim($lines[$i]);
2105+            if ($line) {
2106+                $pieces = explode(' ', $line);
2107+                $c = count($pieces);
2108+                switch($c) {
2109+                    case 2:
2110+                        $start = (int)$pieces[0];
2111+                        $end   = $start+(int)$pieces[1];
2112+                        if ($end > $result['max_object'])
2113+                            $result['max_object'] = $end;
2114+                        break;
2115+                    case 3:
2116+                        if (!isset($result['xref'][$start]))
2117+                            $result['xref'][$start] = array();
2118+                       
2119+                        if (!array_key_exists($gen = (int) $pieces[1], $result['xref'][$start])) {
2120+                               $result['xref'][$start][$gen] = $pieces[2] == 'n' ? (int) $pieces[0] : null;
2121+                           }
2122+                        $start++;
2123+                        break;
2124+                    default:
2125+                        $this->error('Unexpected data in xref table');
2126+                }
2127+            }
2128+        }
2129+       
2130+        $lines = $pieces = $line = $start = $end = $gen = null;
2131+        unset($lines, $pieces, $line, $start, $end, $gen);
2132+       
2133+        fseek($this->f, $o_pos+$trailerPos+7);
2134+       
2135+        $c =&  new pdf_context($this->f);
2136+           $trailer = $this->pdf_read_value($c);
2137+           
2138+           $c = null;
2139+           unset($c);
2140+           
2141+           if (!isset($result['trailer'])) {
2142+            $result['trailer'] = $trailer;         
2143+           }
2144+           
2145+           if (isset($trailer[1]['/Prev'])) {
2146+               $this->pdf_read_xref($result, $trailer[1]['/Prev'][1]);
2147+           }
2148+           
2149+           $trailer = null;
2150+           unset($trailer);
2151+       
2152+        return true;
2153+    }
2154+   
2155+    /**
2156+     * Reads an Value
2157+     *
2158+     * @param object $c pdf_context
2159+     * @param string $token a Token
2160+     * @return mixed
2161+     */
2162+    function pdf_read_value(&$c, $token = null) {
2163+       if (is_null($token)) {
2164+           $token = $this->pdf_read_token($c);
2165+       }
2166+       
2167+        if ($token === false) {
2168+           return false;
2169+       }
2170+
2171+       switch ($token) {
2172+            case       '<':
2173+                       // This is a hex string.
2174+                       // Read the value, then the terminator
2175+
2176+                $pos = $c->offset;
2177+
2178+                       while(1) {
2179+
2180+                    $match = strpos ($c->buffer, '>', $pos);
2181+                               
2182+                               // If you can't find it, try
2183+                               // reading more data from the stream
2184+
2185+                               if ($match === false) {
2186+                                       if (!$c->increase_length()) {
2187+                                               return false;
2188+                                       } else {
2189+                               continue;
2190+                       }
2191+                               }
2192+
2193+                               $result = substr ($c->buffer, $c->offset, $match - $c->offset);
2194+                               $c->offset = $match + 1;
2195+                               
2196+                               return array (PDF_TYPE_HEX, $result);
2197+                }
2198+               
2199+                break;
2200+               case    '<<':
2201+                       // This is a dictionary.
2202+
2203+                       $result = array();
2204+
2205+                       // Recurse into this function until we reach
2206+                       // the end of the dictionary.
2207+                       while (($key = $this->pdf_read_token($c)) !== '>>') {
2208+                               if ($key === false) {
2209+                                       return false;
2210+                               }
2211+                               
2212+                               if (($value =   $this->pdf_read_value($c)) === false) {
2213+                                       return false;
2214+                               }
2215+                               
2216+                               // Catch missing value
2217+                               if ($value[0] == PDF_TYPE_TOKEN && $value[1] == '>>') {
2218+                                   $result[$key] = array(PDF_TYPE_NULL);
2219+                                   break;
2220+                               }
2221+                               
2222+                               $result[$key] = $value;
2223+                       }
2224+                               
2225+                       return array (PDF_TYPE_DICTIONARY, $result);
2226+
2227+               case    '[':
2228+                       // This is an array.
2229+
2230+                       $result = array();
2231+
2232+                       // Recurse into this function until we reach
2233+                       // the end of the array.
2234+                       while (($token = $this->pdf_read_token($c)) !== ']') {
2235+                    if ($token === false) {
2236+                                       return false;
2237+                               }
2238+                                       
2239+                               if (($value = $this->pdf_read_value($c, $token)) === false) {
2240+                        return false;
2241+                               }
2242+                                       
2243+                               $result[] = $value;
2244+                       }
2245+                       
2246+                return array (PDF_TYPE_ARRAY, $result);
2247+
2248+               case    '('             :
2249+                // This is a string
2250+                $pos = $c->offset;
2251+               
2252+                $openBrackets = 1;
2253+                       do {
2254+                    for (; $openBrackets != 0 && $pos < $c->length; $pos++) {
2255+                        switch (ord($c->buffer[$pos])) {
2256+                            case 0x28: // '('
2257+                                $openBrackets++;
2258+                                break;
2259+                            case 0x29: // ')'
2260+                                $openBrackets--;
2261+                                break;
2262+                            case 0x5C: // backslash
2263+                                $pos++;
2264+                        }
2265+                    }
2266+                       } while($openBrackets != 0 && $c->increase_length());
2267+                       
2268+                       $result = substr($c->buffer, $c->offset, $pos - $c->offset - 1);
2269+                       $c->offset = $pos;
2270+                       
2271+                       return array (PDF_TYPE_STRING, $result);
2272+
2273+                       
2274+            case 'stream':
2275+               $o_pos = ftell($c->file)-strlen($c->buffer);
2276+                       $o_offset = $c->offset;
2277+                       
2278+                       $c->reset($startpos = $o_pos + $o_offset);
2279+                       
2280+                       $e = 0; // ensure line breaks in front of the stream
2281+                       if ($c->buffer[0] == chr(10) || $c->buffer[0] == chr(13))
2282+                               $e++;
2283+                       if ($c->buffer[1] == chr(10) && $c->buffer[0] != chr(10))
2284+                               $e++;
2285+                       
2286+                       if ($this->actual_obj[1][1]['/Length'][0] == PDF_TYPE_OBJREF) {
2287+                               $tmp_c =& new pdf_context($this->f);
2288+                               $tmp_length = $this->pdf_resolve_object($tmp_c,$this->actual_obj[1][1]['/Length']);
2289+                               $length = $tmp_length[1][1];
2290+                       } else {
2291+                               $length = $this->actual_obj[1][1]['/Length'][1];       
2292+                       }
2293+                       
2294+                       if ($length > 0) {
2295+                       $c->reset($startpos+$e,$length);
2296+                       $v = $c->buffer;
2297+                       } else {
2298+                           $v = '';   
2299+                       }
2300+                       $c->reset($startpos+$e+$length+9); // 9 = strlen("endstream")
2301+                       
2302+                       return array(PDF_TYPE_STREAM, $v);
2303+                       
2304+               default :
2305+               if (is_numeric ($token)) {
2306+                    // A numeric token. Make sure that
2307+                               // it is not part of something else.
2308+                               if (($tok2 = $this->pdf_read_token ($c)) !== false) {
2309+                        if (is_numeric ($tok2)) {
2310+
2311+                                               // Two numeric tokens in a row.
2312+                                               // In this case, we're probably in
2313+                                               // front of either an object reference
2314+                                               // or an object specification.
2315+                                               // Determine the case and return the data
2316+                                               if (($tok3 = $this->pdf_read_token ($c)) !== false) {
2317+                                switch ($tok3) {
2318+                                                               case    'obj'   :
2319+                                        return array (PDF_TYPE_OBJDEC, (int) $token, (int) $tok2);
2320+                                                               case    'R'             :
2321+                                                                       return array (PDF_TYPE_OBJREF, (int) $token, (int) $tok2);
2322+                                                       }
2323+                                                       // If we get to this point, that numeric value up
2324+                                                       // there was just a numeric value. Push the extra
2325+                                                       // tokens back into the stack and return the value.
2326+                                                       array_push ($c->stack, $tok3);
2327+                                               }
2328+                                       }
2329+
2330+                                       array_push ($c->stack, $tok2);
2331+                               }
2332+
2333+                               if ($token === (string)((int)$token))
2334+                                       return array (PDF_TYPE_NUMERIC, (int)$token);
2335+                               else
2336+                                       return array (PDF_TYPE_REAL, (float)$token);
2337+                       } else if ($token == 'true' || $token == 'false') {
2338+                    return array (PDF_TYPE_BOOLEAN, $token == 'true');
2339+                       } else if ($token == 'null') {
2340+                          return array (PDF_TYPE_NULL);
2341+                       } else {
2342+
2343+                    // Just a token. Return it.
2344+                               return array (PDF_TYPE_TOKEN, $token);
2345+                       }
2346+
2347+         }
2348+    }
2349+   
2350+    /**
2351+     * Resolve an object
2352+     *
2353+     * @param object $c pdf_context
2354+     * @param array $obj_spec The object-data
2355+     * @param boolean $encapsulate Must set to true, cause the parsing and fpdi use this method only without this para
2356+     */
2357+    function pdf_resolve_object(&$c, $obj_spec, $encapsulate = true) {
2358+        // Exit if we get invalid data
2359+       if (!is_array($obj_spec)) {
2360+            return false;
2361+       }
2362+
2363+       if ($obj_spec[0] == PDF_TYPE_OBJREF) {
2364+
2365+               // This is a reference, resolve it
2366+               if (isset($this->xref['xref'][$obj_spec[1]][$obj_spec[2]])) {
2367+
2368+                       // Save current file position
2369+                       // This is needed if you want to resolve
2370+                       // references while you're reading another object
2371+                       // (e.g.: if you need to determine the length
2372+                       // of a stream)
2373+
2374+                       $old_pos = ftell($c->file);
2375+
2376+                       // Reposition the file pointer and
2377+                       // load the object header.
2378+                               
2379+                       $c->reset($this->xref['xref'][$obj_spec[1]][$obj_spec[2]]);
2380+
2381+                       $header = $this->pdf_read_value($c);
2382+
2383+                       if ($header[0] != PDF_TYPE_OBJDEC || $header[1] != $obj_spec[1] || $header[2] != $obj_spec[2]) {
2384+                               $this->error("Unable to find object ({$obj_spec[1]}, {$obj_spec[2]}) at expected location");
2385+                       }
2386+
2387+                       // If we're being asked to store all the information
2388+                       // about the object, we add the object ID and generation
2389+                       // number for later use
2390+                               $this->actual_obj =& $result;
2391+                       if ($encapsulate) {
2392+                               $result = array (
2393+                                       PDF_TYPE_OBJECT,
2394+                                       'obj' => $obj_spec[1],
2395+                                       'gen' => $obj_spec[2]
2396+                               );
2397+                       } else {
2398+                               $result = array();
2399+                       }
2400+
2401+                       // Now simply read the object data until
2402+                       // we encounter an end-of-object marker
2403+                       while(1) {
2404+                    $value = $this->pdf_read_value($c);
2405+                                       if ($value === false || count($result) > 4) {
2406+                                               // in this case the parser coudn't find an endobj so we break here
2407+                                               break;
2408+                               }
2409+
2410+                               if ($value[0] == PDF_TYPE_TOKEN && $value[1] === 'endobj') {
2411+                                       break;
2412+                               }
2413+
2414+                    $result[] = $value;
2415+                       }
2416+
2417+                       $c->reset($old_pos);
2418+
2419+                if (isset($result[2][0]) && $result[2][0] == PDF_TYPE_STREAM) {
2420+                    $result[0] = PDF_TYPE_STREAM;
2421+                }
2422+
2423+                       return $result;
2424+               }
2425+       } else {
2426+               return $obj_spec;
2427+       }
2428+    }
2429+
2430+   
2431+   
2432+    /**
2433+     * Reads a token from the file
2434+     *
2435+     * @param object $c pdf_context
2436+     * @return mixed
2437+     */
2438+    function pdf_read_token(&$c)
2439+    {
2440+       // If there is a token available
2441+       // on the stack, pop it out and
2442+       // return it.
2443+
2444+       if (count($c->stack)) {
2445+               return array_pop($c->stack);
2446+       }
2447+
2448+       // Strip away any whitespace
2449+
2450+       do {
2451+               if (!$c->ensure_content()) {
2452+                       return false;
2453+               }
2454+               $c->offset += strspn($c->buffer, " \n\r\t", $c->offset);
2455+       } while ($c->offset >= $c->length - 1);
2456+
2457+       // Get the first character in the stream
2458+
2459+       $char = $c->buffer[$c->offset++];
2460+
2461+       switch ($char) {
2462+
2463+               case '['        :
2464+               case ']'        :
2465+               case '('        :
2466+               case ')'        :
2467+               
2468+                       // This is either an array or literal string
2469+                       // delimiter, Return it
2470+
2471+                       return $char;
2472+
2473+               case '<'        :
2474+               case '>'        :
2475+
2476+                       // This could either be a hex string or
2477+                       // dictionary delimiter. Determine the
2478+                       // appropriate case and return the token
2479+
2480+                       if ($c->buffer[$c->offset] == $char) {
2481+                               if (!$c->ensure_content()) {
2482+                                   return false;
2483+                               }
2484+                               $c->offset++;
2485+                               return $char . $char;
2486+                       } else {
2487+                               return $char;
2488+                       }
2489+
2490+                       case '%'    :
2491+                           
2492+                           // This is a comment - jump over it!
2493+                           
2494+                $pos = $c->offset;
2495+                       while(1) {
2496+                           $match = preg_match("/(\r\n|\r|\n)/", $c->buffer, $m, PREG_OFFSET_CAPTURE, $pos);
2497+                    if ($match === 0) {
2498+                                       if (!$c->increase_length()) {
2499+                                               return false;
2500+                                       } else {
2501+                               continue;
2502+                       }
2503+                               }
2504+
2505+                               $c->offset = $m[0][1]+strlen($m[0][0]);
2506+                               
2507+                               return $this->pdf_read_token($c);
2508+                }
2509+               
2510+               default         :
2511+
2512+                       // This is "another" type of token (probably
2513+                       // a dictionary entry or a numeric value)
2514+                       // Find the end and return it.
2515+
2516+                       if (!$c->ensure_content()) {
2517+                               return false;
2518+                       }
2519+
2520+                       while(1) {
2521+
2522+                               // Determine the length of the token
2523+
2524+                               $pos = strcspn($c->buffer, " %[]<>()\r\n\t/", $c->offset);
2525+                               if ($c->offset + $pos <= $c->length - 1) {
2526+                                       break;
2527+                               } else {
2528+                                       // If the script reaches this point,
2529+                                       // the token may span beyond the end
2530+                                       // of the current buffer. Therefore,
2531+                                       // we increase the size of the buffer
2532+                                       // and try again--just to be safe.
2533+
2534+                                       $c->increase_length();
2535+                               }
2536+                       }
2537+
2538+                       $result = substr($c->buffer, $c->offset - 1, $pos + 1);
2539+
2540+                       $c->offset += $pos;
2541+                       return $result;
2542+       }
2543+    }
2544+}
2545Index: fpdf/wrapper.php
2546===================================================================
2547--- fpdf/wrapper.php    (revision 0)
2548+++ fpdf/wrapper.php    (revision 0)
2549@@ -0,0 +1,84 @@
2550+<?php //Class to stream wrap db pdf file
2551+class VarStream {
2552+    private $_pos;
2553+    private $_stream;
2554+    private $_cDataIdx;
2555+
2556+    static protected $_data = array();
2557+    static protected $_dataIdx = 0;
2558+   
2559+    static function createReference(&$var) {
2560+        $idx = self::$_dataIdx++;
2561+        self::$_data[$idx] =& $var;
2562+        return __CLASS__.'://'.$idx;
2563+    }
2564+
2565+    public function stream_open($path, $mode, $options, &$opened_path) {
2566+        $url = parse_url($path);
2567+        $cDataIdx = $url["host"];
2568+        if (!isset(self::$_data[$cDataIdx]))
2569+            return false;
2570+        $this->_stream = &self::$_data[$cDataIdx];
2571+        $this->_pos = 0;
2572+        if (!is_string($this->_stream)) return false;
2573+        $this->_cDataIdx = $cDataIdx;
2574+        return true;
2575+    }
2576+
2577+    public function stream_read($count) {
2578+        $ret = substr($this->_stream, $this->_pos, $count);
2579+        $this->_pos += strlen($ret);
2580+        return $ret;
2581+    }
2582+
2583+    public function stream_write($data){
2584+        $l=strlen($data);
2585+        $this->_stream =
2586+            substr($this->_stream, 0, $this->_pos) .
2587+            $data .
2588+            substr($this->_stream, $this->_pos += $l);
2589+        return $l;
2590+    }
2591+
2592+    public function stream_tell() {
2593+        return $this->_pos;
2594+    }
2595+
2596+    public function stream_eof() {
2597+        return $this->_pos >= strlen($this->_stream);
2598+    }
2599+
2600+    public function stream_seek($offset, $whence) {
2601+        $l=strlen($this->_stream);
2602+        switch ($whence) {
2603+            case SEEK_SET: $newPos = $offset; break;
2604+            case SEEK_CUR: $newPos = $this->_pos + $offset; break;
2605+            case SEEK_END: $newPos = $l + $offset; break;
2606+            default: return false;
2607+        }
2608+        $ret = ($newPos >=0 && $newPos <=$l);
2609+        if ($ret) $this->_pos=$newPos;
2610+        return $ret;
2611+    }
2612+   
2613+    public function stream_close() {
2614+        unset(self::$_data[$this->_cDataIdx]);
2615+    }
2616+   
2617+    public function url_stat ($path, $flags) {
2618+        $url = parse_url($path);
2619+        $dataIdx = $url["host"];
2620+        if (!isset(self::$_data[$dataIdx]))
2621+            return false;
2622+
2623+        $size = strlen(self::$_data[$dataIdx]);
2624+        return array(
2625+            7 => $size,
2626+            'size' => $size
2627+        );
2628+    }
2629+}
2630+
2631+stream_wrapper_register('VarStream', 'VarStream') or die('Failed to register protocol VarStream://');
2632+
2633+?>
2634Index: install/files.sql
2635===================================================================
2636--- install/files.sql   (revision 514)
2637+++ install/files.sql   (working copy)
2638@@ -1 +1,2 @@
2639-INSERT INTO files VALUES (1,'logo.png','Company Logo Used in PDF reports','‰PNG\r\n\Z\n\0\0\0\rIHDR\0\0\0\0\0]\0\0\0ŸS°\0\0\0gAMA\0\0¯È7Šé\0\0\0tEXtSoftware\0Adobe ImageReadyqÉe<\0\0\0`PLTE666ÑÑѶ¶¶óó󪪪kkk   rrrœœœÅÅŎŽŽèèèÛÛۄ„„¿¿¿|||XXXÞÞÞðððˆˆˆÉÉÉââ╕•€€€KKK&&&QQQPPP%%%bbbcccÿÿÿV\"l\0\0\0ØIDATxÚb \0@£A\0\0D£påΡ\0D£pà”®¡\04ˆÃA‘‘‘‰˜±I#€<^inT)&1^v99YYv^.f°@\0a†ƒ /¿¬X#%á I~8°\0] +t*‚#ËÏ&‚¬†WVVN®‚ÝV~šŽ¬Bœ›\"\n0àgj Žp\0«’“…™!Ë*&B^8HR” »ìYš‹XYþåE\n\'9Y>4Dà¡\0bð„™ÅPtA[–•Y €P‘ŠQJ;ýó4`±ˆ³XEéæUkÑ­b“Eòƒ,,DXáA%‡]^ €Â›Y…48@و‘Þá\0    \0H’”ƒš,óCÓ$ݰ¢™ÀӖ‡†ŸÜHx~qØäå|¬²ð —…¹\ZlÌdäIJ҃¬R”ÈÂD@šT`*QãJáO€„Ÿ,<¡#ùÈŠ1€\0‚‡ƒ,úå`@óØ-ü̑/d‘\0–: Ά©‘ƒû‰\r-[ •0@\Z6¬pŸÁÊHšwž D0È\"r%\"`)“UÄp€(_ Õðr  b\rV–\".;z¶@$) ZÁÀJGx      ,+=\0ˆ²rˆBZžÜ \ZA9†Ž€ 8`Y‚       ìgfF6V9xE**¹¹a>%ä67<aCT    r\Z°\"e5+XØÀ•P € á &+‹€Mžq <.™Žá\0/Äàٞ™Q€sÁœ…T±0!ég’E*¡ùBQÞq!ŒÂÌÇ%Ša€\0‡“rÙËr°àc‘g;‹—ÞåÈáˆâ™]–øAá\0ËéŒPQdË a&ÇÏ@CµcÖ±à„@àÂQÙ\"אŠÐ%,lÅB×ô\0IŒ(‘+%Àá\0M\nl²ÐÒ%[€œÃ¯#å™á9][ xˑìd…$        ‰AÌcåÆépFNNQ<é(-„ÏßèÚáõr80Âê\0p2çƒú^–…]^ûÁBš»áu#0ÉÂÊIl.\0 ‰0ßÓ#¬Œ„¶Þx¡á\"†Ö¯†úY\\äiI9lá Ä\"\0îl0°sâÖL=ÈÚ5 ©”CY`řԱbÈMnHÛ\næ)`p2‹YlÑ    @ЊR³M^yŠ1#šò`AnJ‚Yà@\0z”X0ƒ*ÄrBiII˜vp_DY;¢Ý‡œ/`•)ž­ÀMrŒ,PßÂkNfh¶âBä/x8€xØò7@\01\0{$PÃËXµÊˆÒµ“EjÓBý dˆË \0È¿B(á $!)G±j—„‡T;Ì=šå$<²@œVŸ12¢–ïù )…O֙uÐR<–@\01ÈsÁœ.‹È\ZÀj©£É\'x…õ;ؒÐ`\0        !x¿[’KH)À!ŠÐ.        ю\n Úeá­D8ˆÁ\Zvò^ÖÂc”‡uHa5\'ŽUÁ-/XY u¬&äÅÈ\Z\0ÄÀŒÒ|‡¶5eyQ»úðJ8ˆB¢“‹K\\\0§Hé\\2HˆsqÉ1À\"Š]M»²vx&…ç>vXHҜ„wA>»\ZV±³B<ÃMW M,à(rC\n­Ò\0 €:Ñb“åçbácDîâBJ8p}-þ€Ÿ‚äqx8\0=/ “fa€$\n˜vIí +\'Á®\rG±ñ²\"ZüІ-/¬ c”gƒu=P†@œHx…Ü\0Eî5Èñó!7ˆ\rÑr„u=`Mk~€òš(YQÂ8\ntšWEaá\0äq!ÉJÂã§vQHß>…/G:3R\Z— \nâExš”xa±@JÄ8˜Cä:€\0bàE4%Ñ»žŒhõH”5$QÊ^šOØaõ‰Œ€8F›BFž/d`©5ÙíIx_æ0Ä +¬†Æ4,ã³Á&À=CšÃåàY†ÑS‡¯\0ˆUQ¡ †€À­RHmÅIÐaD\nIŒ#‡$4F9Á²’(²ˆ ‰];D—š<b°)•‚:•‚(C5Ðp€7™ù!IHrƒVt`ÏóBº(ÈWš¡Ð¶@\01È\"Æ|Àvòs³C¹ÜÆ/Žš†$>D8\0ý̀ÞJ„yÒ®–AÀ`W\"rˆä„S;b \0%­™ðóˆ,Ž›O­Ðf!Ø¥Œ°<À+xqc°‚£ €PFe3€\'kžMƒô³ ŽaAΒÍ`ÿ@󀪀¢Æ€4°h‡š@)³‘Æa@€RçÁkQy€±tA\Z&Œ0gó\"ÆgkXX€B €‡ d!ãN,à1nHÙd²1!rrzÅl@Zœ¥LR’ vx8È\"†UáýaH…!oô@ûUŸtÀÖýä…%,~€¡hxJ€À@rðÁYYØð¿¬ÔÃìÊÑùBIX&äÀœØÇí`ÍHp8Hb×Ôɉhúñó?Rú€ö÷a1Ã\nu&ldIÚJà“G.äåáC|03-€\0b@.‡`£‚¬Ð±/>9”i\0 \Z&äpÀô8cp‚;’XÃA^_`ÕFDmÁ›\\bG4ýA±ËË,ŒHKPaë…pC>ÐðBÄc…Ò@’•˜<@\01ÀG.ÁeŒKNfVDQ\rMLŒÂ   ÒÀ§ÌpDJžŽƒªD¯Qó \r–ñÁ:ŸÐp`‚ò\\Д2\\+\'‡f¯\"ï:\0ÄÀŸÞA“fƒZT§¢ŽaHJb÷t\0ûxR8àÔևyDéoÂG™ùÁ#oˆôÀËíLò¬CÒ-ŒÃ‰a·òp7@\01pÁ’=4¡Á͊’+`žxÓþp!”àá\0s!#J7înX™Æ‹Ò„F37R8 â\"&·àÅ%@\010A͆+ÂñbHShdŠ·G(øtrz\0g}h»Ÿ‘VØñB=Içü|§Bëø`,¶)9AÄx6?@\01p£‘ ¹&Ĝʀ0lˆ[_A)X°Ïw€¬=‰K»€\"\r\"»ŸQw²ÀÁæ%ˆ;¹à3uò°Á\Z°¬S“lð~¹,@\01€ç    ©ÔÀâFšH…ux ñÃM( >§Ör’`z@ª/PÛñp€Ä°ÀkØ4?ʔš RÙ*\'‹1í‡2â  ¶        €À%Rj€\'*F9äñ)ÞÁéHûA”[÷%$ñi‡÷6QÒ3¢õ˚乐\n1ĝŒ£Œ+`\"@\01€*GDj€,Æ|.>ªÏ‡\ZX\ZBq\\ùB9_àÐl_!   ‘Ýυð*#lš–øó• 0\"AsÖ9ØL\0°”  [X24m   BçȑK\0™Hsˆ f³€#¶úÔsƕ$‘óVí@ìòp÷¡ŒÛ#ÍØsóÂ\"êAnøä-Hr—…†úŒ3+ŒQ @Àp`Fd\nXmËΝ=B\ZŠ‚vcËô(ƁâLòD•XµË€ŽÃ\"RŸdEL<óËça\nøaMJèÐŒD„(š:Å͐•ã $kŠýÅXºè²hãHã0¢˜­IPz\'”/pkgø8      <žzÀ=DøX##bŒ$†Z²Ê‚“€•ÄÆÇ\nn1€Q8Vf€\0b€R;Ô©“…;V–°2Ë£§èð2ŒcÍ\0k6jOJBÆ2qiGL­q×Ëq±#zþâZœBA*ËDPÂìU6H%‰²Fiø €Œ2«ƒ>…2Àˆìð(œ$xtW;J90ŽKÂgàÀHC0Hë6å™áž`DY+\0Iðc†EòÊóÊ!8bŒÌ`g– غ   YÄšR!_u ‡:ùŸ{ÏAF€áƒP8ëMI”|ª8œòÐp•EžbD\Z2ãƒu»Q\ZH\\ð.ԅVЕArÈËk36Ð5.\0Ä Ôr@n, \n˜‡6ö‘€šgâäd‡ŒÑB<íjIx8H@*Yžv„äî>ÊÈ({òÁ\Z7°áI€É]Øä|ÂÞc„—sðp˜‡Aê^>°Ã{×H\rÞ,Ehؑy²\nØñ¬#Ei?H\"ŽÃôƒ«\\Ä\Z0Y€%Zð&5¿ <bˆ,¢ãiZƒ•3£, €vÏYäPÖC\"†d!ó!\0¯/˜y‘—#\"§9ØX&Fz\0OJ@ Ä/°dާœ”„Ë       ÈCc¢eœ ÒÂ5`?\ny®¹ÎÛ5èïÀӔ,°pEÀÉ!- €6+Ry ‹ŒŽŒsI$BååEQŠ(ÙEñ®A­7%QŽK\"k‡\'”Å?üˆ–|Äy12𡆎š“gfâGY:«fƒu˜\0¹mË,&+‹R.ÉB³–&)¢!*.‰PQŽèûXàË`á\0ÑÔEÖÎÇò?̵ŒŒ\\,L(®`dükøPÔ1óg!+/òòq€\0b@[^͊-HŠÃŸ˜µŸ…Ÿž…  P;E€sŸŒ<@\0aôuÙxáå#»3Q!àêo\0 œ!Æ(H|„’’2ƒ+\0ˆì¥0=²p\0 \n\"Tr…@\0Š\0 Ñp€\0€\0\Z\r\0 rÃAr˜…@\0Q’†S9 @ä§IÉá”\0hŽ|€\0€\0\"7À=&²­¥P;õ@\0î÷‡\0€\0\Z\r\0 Ñp€\0€\0\">˜ÙØØšw 3›4h›0ÐLÐ\\$”¢àšFêÆ[€\0\">ž¥€¥©çXi `–—’’’ò€4õ\rh47‰z\0h ÂM\nìX \n\0`hHËSÓl)Rà €*x€ \0P8€ÇÀŠ€\0\"%€š 1/p\0@ò$YP-€H€\0\\œÍ\nÀ €ç“È›àAßÿ=çO«±[jš‰}‡ Ž¢T5\nĈǘW³äz\06Å|\\ìý Y‡ëD5p3•ÌÛ)cxç|¯wƒ°)N\Z†gR·çépe`b4ö?1i¬Q,4\ZªòYʗ¬ÉÄÈŽ£ñ¿ ø^™Ô^hA$V/ó#\0ÕÖ²0ÃÇÊÀ›°C{Øÿÿ嚀²)(ŽZè+ñTäÁASž¬Õ\r…ÉÍæ†n¥>Ÿ<ŒÒál|t§dʊé6~sЩ1YÒÂ5PvÂÔk©\Zœj?#£>—<        ç§U+”ÇŽ‹Žò Ž©ñ;–§á~ý\nÀD#‚°Ö¡wÒÿÿ²1ÁցA„’Ó£^\'üe€–0zEd˜Xˆ\rœ?EÏ\'xxa`¢AJMɛÅMh,iªÁ{.S¹þކ4H•vÃβî…]‡Ç#Ÿ?8Š!\"Ɠ¡^Ø¥\"ª„®_˜*—€aˆV)Ew.â\"÷¿e1…ló‘ñ9êµÙvUÆÌ¢j¯Œ…Ɉ=ø;À„•˜ÜåÃç!–žŽ4TŒcš ó¶”ôu5H&5™‡æhÊøéÉ.ý`u‰ÿuï³xÇÞ0Ü\rx\ZnǜÌ},Rhö}͎\0ÁÙ|\\Cè\'\0“V0Â21ó°àÁÿÿrÐâÉ\rÒÒÊù\"åhlé|:ò}$g:9¿ÇŒŽ»ÀÃh?Á˜‰ù£!á.*ê\ra¥®­~ËÔ·Yp2Õþ˜e“$xÐËÚÚݓ?“@É .ÌD“6¯c‡î~ž¬‚€a¶@av+ì ÿÿçŒÖêv-(&&±G]-ˆ6Ÿ‚‚Ô+ÄäØ>„»ýÔÒc‹ŽÍ2ɛþ>áÊVóãx€]Œá­ÉçœC‚L›?z_\\?l<«qp    ÙÀJÇp¯\0\\V1À +S‡ºõ®ƒüÿŸÄë‚\'Iâ%ó2¯éñLYƒ»Ð‚bZ7œ\'ý~‚Ù¡\\h‡h“{¶>ÁšúÁ©_7nkPð^aÜK×+ÒJ~a\\ÊD\0͚6•Ð%\0•åŽ0ÃÐÒ¡[6îËÊv~dE€ó ‰Ÿ“lAÕŸˆEdzjŽê¡þPè¿ËŸîìgD˜àŒ\"méFÜ8‡î±ÉŒËiImpñ>I€       %:™š&\"ë\r£|™ž,c\0@†8ž0óÿ§*p6*-m¡ñàÀl`ʅèŽd»vE–ɺÂ­„ÿ·Sà–ÍÈ€æôE~]͚› yL+y9>ƒ#dî<-™E“Z7=Ù/•VÀ…‘ÛŽ±ß€l+H„at‹àzèÿ¹µi&cg±Ä’&‘:IÆIåaR’\nƒ“ÉÉëüëwÁ/äèŸ7^Ÿwru[T˜Òy¿è<YªwvÙQÅ6œy–cüúj›s8zþ­ÓÐҀǢöhõx–ož®‚€A—/»™p€ƒÿÿåŽÝôFL\Z”–Ï<T˞¡Uñ­’@šŸ…lÐiÂÎòà{`DÚë)×ôD·K÷ÿ}q\\—3É쪵–òÌzVÙúÉ  C«F÷ÄX{$êšÐ_È.c€B†FŒAþýoùÅÖªq–\0Ò>Î>|\"®ó$íûÎÂi[     J]ÌIy†Yìڏ$œƒüE4\"ûë\'^¿Èƒ,¢“ÏÐ7ûFMO‚Þ“™ÀF6Ë͆ÄxþJïÖve‚9]ïœÐú\rZî€òº˜,@‚vú\Z\'ŽædBwªf„†9,_ §”³Œ–\0Û66ĉJp«QøË#ç.P[Éa`‡J³³À:uŒ„H ºÚR\0\0Ac_Qwèþ·ÌW5ûJsn\nsŠ­÷6X”Á[Unè5›-†\\é!ÿËâž DõU@QRŽ‹ÁÃ>˜ðý.«ã]r|ž~7Z®\0Àn×R€J`o–™3­‚\0@\0á©P\rÇD=àÝ?ä>\0Ð`N°\'u\0¬Ï-…Ü€€\0Â(­UºH•B=óÄ u¶±*€\0\ZYóÜšå0\0 Ñy\0 Ñp€\0€\0\Z\r\00\0tP|O;ë\0\0\0\0IEND®B`‚','image/png',2,NOW(),2,NOW(),90);
2640\ No newline at end of file
2641+INSERT INTO files VALUES (1,'logo.png','Company Logo Used in PDF reports','‰PNG\r\n\Z\n\0\0\0\rIHDR\0\0\0\0\0]\0\0\0ŸS°\0\0\0gAMA\0\0¯È7Šé\0\0\0tEXtSoftware\0Adobe ImageReadyqÉe<\0\0\0`PLTE666ÑÑѶ¶¶óó󪪪kkk   rrrœœœÅÅŎŽŽèèèÛÛۄ„„¿¿¿|||XXXÞÞÞðððˆˆˆÉÉÉââ╕•€€€KKK&&&QQQPPP%%%bbbcccÿÿÿV\"l\0\0\0ØIDATxÚb \0@£A\0\0D£påΡ\0D£pà”®¡\04ˆÃA‘‘‘‰˜±I#€<^inT)&1^v99YYv^.f°@\0a†ƒ /¿¬X#%á I~8°\0] +t*‚#ËÏ&‚¬†WVVN®‚ÝV~šŽ¬Bœ›\"\n0àgj Žp\0«’“…™!Ë*&B^8HR” »ìYš‹XYþåE\n\'9Y>4Dà¡\0bð„™ÅPtA[–•Y €P‘ŠQJ;ýó4`±ˆ³XEéæUkÑ­b“Eòƒ,,DXáA%‡]^ €Â›Y…48@و‘Þá\0    \0H’”ƒš,óCÓ$ݰ¢™ÀӖ‡†ŸÜHx~qØäå|¬²ð —…¹\ZlÌdäIJ҃¬R”ÈÂD@šT`*QãJáO€„Ÿ,<¡#ùÈŠ1€\0‚‡ƒ,úå`@óØ-ü̑/d‘\0–: Ά©‘ƒû‰\r-[ •0@\Z6¬pŸÁÊHšwž D0È\"r%\"`)“UÄp€(_ Õðr  b\rV–\".;z¶@$) ZÁÀJGx      ,+=\0ˆ²rˆBZžÜ \ZA9†Ž€ 8`Y‚       ìgfF6V9xE**¹¹a>%ä67<aCT    r\Z°\"e5+XØÀ•P € á &+‹€Mžq <.™Žá\0/Äàٞ™Q€sÁœ…T±0!ég’E*¡ùBQÞq!ŒÂÌÇ%Ša€\0‡“rÙËr°àc‘g;‹—ÞåÈáˆâ™]–øAá\0ËéŒPQdË a&ÇÏ@CµcÖ±à„@àÂQÙ\"אŠÐ%,lÅB×ô\0IŒ(‘+%Àá\0M\nl²ÐÒ%[€œÃ¯#å™á9][ xˑìd…$        ‰AÌcåÆépFNNQ<é(-„ÏßèÚáõr80Âê\0p2çƒú^–…]^ûÁBš»áu#0ÉÂÊIl.\0 ‰0ßÓ#¬Œ„¶Þx¡á\"†Ö¯†úY\\äiI9lá Ä\"\0îl0°sâÖL=ÈÚ5 ©”CY`řԱbÈMnHÛ\næ)`p2‹YlÑ    @ЊR³M^yŠ1#šò`AnJ‚Yà@\0z”X0ƒ*ÄrBiII˜vp_DY;¢Ý‡œ/`•)ž­ÀMrŒ,PßÂkNfh¶âBä/x8€xØò7@\01\0{$PÃËXµÊˆÒµ“EjÓBý dˆË \0È¿B(á $!)G±j—„‡T;Ì=šå$<²@œVŸ12¢–ïù )…O֙uÐR<–@\01ÈsÁœ.‹È\ZÀj©£É\'x…õ;ؒÐ`\0        !x¿[’KH)À!ŠÐ.        ю\n Úeá­D8ˆÁ\Zvò^ÖÂc”‡uHa5\'ŽUÁ-/XY u¬&äÅÈ\Z\0ÄÀŒÒ|‡¶5eyQ»úðJ8ˆB¢“‹K\\\0§Hé\\2HˆsqÉ1À\"Š]M»²vx&…ç>vXHҜ„wA>»\ZV±³B<ÃMW M,à(rC\n­Ò\0 €:Ñb“åçbácDîâBJ8p}-þ€Ÿ‚äqx8\0=/ “fa€$\n˜vIí +\'Á®\rG±ñ²\"ZüІ-/¬ c”gƒu=P†@œHx…Ü\0Eî5Èñó!7ˆ\rÑr„u=`Mk~€òš(YQÂ8\ntšWEaá\0äq!ÉJÂã§vQHß>…/G:3R\Z— \nâExš”xa±@JÄ8˜Cä:€\0bàE4%Ñ»žŒhõH”5$QÊ^šOØaõ‰Œ€8F›BFž/d`©5ÙíIx_æ0Ä +¬†Æ4,ã³Á&À=CšÃåàY†ÑS‡¯\0ˆUQ¡ †€À­RHmÅIÐaD\nIŒ#‡$4F9Á²’(²ˆ ‰];D—š<b°)•‚:•‚(C5Ðp€7™ù!IHrƒVt`ÏóBº(ÈWš¡Ð¶@\01È\"Æ|Àvòs³C¹ÜÆ/Žš†$>D8\0ý̀ÞJ„yÒ®–AÀ`W\"rˆä„S;b \0%­™ðóˆ,Ž›O­Ðf!Ø¥Œ°<À+xqc°‚£ €PFe3€\'kžMƒô³ ŽaAΒÍ`ÿ@󀪀¢Æ€4°h‡š@)³‘Æa@€RçÁkQy€±tA\Z&Œ0gó\"ÆgkXX€B €‡ d!ãN,à1nHÙd²1!rrzÅl@Zœ¥LR’ vx8È\"†UáýaH…!oô@ûUŸtÀÖýä…%,~€¡hxJ€À@rðÁYYØð¿¬ÔÃìÊÑùBIX&äÀœØÇí`ÍHp8Hb×Ôɉhúñó?Rú€ö÷a1Ã\nu&ldIÚJà“G.äåáC|03-€\0b@.‡`£‚¬Ð±/>9”i\0 \Z&äpÀô8cp‚;’XÃA^_`ÕFDmÁ›\\bG4ýA±ËË,ŒHKPaë…pC>ÐðBÄc…Ò@’•˜<@\01ÀG.ÁeŒKNfVDQ\rMLŒÂ   ÒÀ§ÌpDJžŽƒªD¯Qó \r–ñÁ:ŸÐp`‚ò\\Д2\\+\'‡f¯\"ï:\0ÄÀŸÞA“fƒZT§¢ŽaHJb÷t\0ûxR8àÔևyDéoÂG™ùÁ#oˆôÀËíLò¬CÒ-ŒÃ‰a·òp7@\01pÁ’=4¡Á͊’+`žxÓþp!”àá\0s!#J7înX™Æ‹Ò„F37R8 â\"&·àÅ%@\010A͆+ÂñbHShdŠ·G(øtrz\0g}h»Ÿ‘VØñB=Içü|§Bëø`,¶)9AÄx6?@\01p£‘ ¹&Ĝʀ0lˆ[_A)X°Ïw€¬=‰K»€\"\r\"»ŸQw²ÀÁæ%ˆ;¹à3uò°Á\Z°¬S“lð~¹,@\01€ç    ©ÔÀâFšH…ux ñÃM( >§Ör’`z@ª/PÛñp€Ä°ÀkØ4?ʔš RÙ*\'‹1í‡2â  ¶        €À%Rj€\'*F9äñ)ÞÁéHûA”[÷%$ñi‡÷6QÒ3¢õ˚乐\n1ĝŒ£Œ+`\"@\01€*GDj€,Æ|.>ªÏ‡\ZX\ZBq\\ùB9_àÐl_!   ‘Ýυð*#lš–øó• 0\"AsÖ9ØL\0°”  [X24m   BçȑK\0™Hsˆ f³€#¶úÔsƕ$‘óVí@ìòp÷¡ŒÛ#ÍØsóÂ\"êAnøä-Hr—…†úŒ3+ŒQ @Àp`Fd\nXmËΝ=B\ZŠ‚vcËô(ƁâLòD•XµË€ŽÃ\"RŸdEL<óËça\nøaMJèÐŒD„(š:Å͐•ã $kŠýÅXºè²hãHã0¢˜­IPz\'”/pkgø8      <žzÀ=DøX##bŒ$†Z²Ê‚“€•ÄÆÇ\nn1€Q8Vf€\0b€R;Ô©“…;V–°2Ë£§èð2ŒcÍ\0k6jOJBÆ2qiGL­q×Ëq±#zþâZœBA*ËDPÂìU6H%‰²Fiø €Œ2«ƒ>…2Àˆìð(œ$xtW;J90ŽKÂgàÀHC0Hë6å™áž`DY+\0Iðc†EòÊóÊ!8bŒÌ`g– غ   YÄšR!_u ‡:ùŸ{ÏAF€áƒP8ëMI”|ª8œòÐp•EžbD\Z2ãƒu»Q\ZH\\ð.ԅVЕArÈËk36Ð5.\0Ä Ôr@n, \n˜‡6ö‘€šgâäd‡ŒÑB<íjIx8H@*Yžv„äî>ÊÈ({òÁ\Z7°áI€É]Øä|ÂÞc„—sðp˜‡Aê^>°Ã{×H\rÞ,Ehؑy²\nØñ¬#Ei?H\"ŽÃôƒ«\\Ä\Z0Y€%Zð&5¿ <bˆ,¢ãiZƒ•3£, €vÏYäPÖC\"†d!ó!\0¯/˜y‘—#\"§9ØX&Fz\0OJ@ Ä/°dާœ”„Ë       ÈCc¢eœ ÒÂ5`?\ny®¹ÎÛ5èïÀӔ,°pEÀÉ!- €6+Ry ‹ŒŽŒsI$BååEQŠ(ÙEñ®A­7%QŽK\"k‡\'”Å?üˆ–|Äy12𡆎š“gfâGY:«fƒu˜\0¹mË,&+‹R.ÉB³–&)¢!*.‰PQŽèûXàË`á\0ÑÔEÖÎÇò?̵ŒŒ\\,L(®`dükøPÔ1óg!+/òòq€\0b@[^͊-HŠÃŸ˜µŸ…Ÿž…  P;E€sŸŒ<@\0aôuÙxáå#»3Q!àêo\0 œ!Æ(H|„’’2ƒ+\0ˆì¥0=²p\0 \n\"Tr…@\0Š\0 Ñp€\0€\0\Z\r\0 rÃAr˜…@\0Q’†S9 @ä§IÉá”\0hŽ|€\0€\0\"7À=&²­¥P;õ@\0î÷‡\0€\0\Z\r\0 Ñp€\0€\0\">˜ÙØØšw 3›4h›0ÐLÐ\\$”¢àšFêÆ[€\0\">ž¥€¥©çXi `–—’’’ò€4õ\rh47‰z\0h ÂM\nìX \n\0`hHËSÓl)Rà €*x€ \0P8€ÇÀŠ€\0\"%€š 1/p\0@ò$YP-€H€\0\\œÍ\nÀ €ç“È›àAßÿ=çO«±[jš‰}‡ Ž¢T5\nĈǘW³äz\06Å|\\ìý Y‡ëD5p3•ÌÛ)cxç|¯wƒ°)N\Z†gR·çépe`b4ö?1i¬Q,4\ZªòYʗ¬ÉÄÈŽ£ñ¿ ø^™Ô^hA$V/ó#\0ÕÖ²0ÃÇÊÀ›°C{Øÿÿ嚀²)(ŽZè+ñTäÁASž¬Õ\r…ÉÍæ†n¥>Ÿ<ŒÒál|t§dʊé6~sЩ1YÒÂ5PvÂÔk©\Zœj?#£>—<        ç§U+”ÇŽ‹Žò Ž©ñ;–§á~ý\nÀD#‚°Ö¡wÒÿÿ²1ÁցA„’Ó£^\'üe€–0zEd˜Xˆ\rœ?EÏ\'xxa`¢AJMɛÅMh,iªÁ{.S¹þކ4H•vÃβî…]‡Ç#Ÿ?8Š!\"Ɠ¡^Ø¥\"ª„®_˜*—€aˆV)Ew.â\"÷¿e1…ló‘ñ9êµÙvUÆÌ¢j¯Œ…Ɉ=ø;À„•˜ÜåÃç!–žŽ4TŒcš ó¶”ôu5H&5™‡æhÊøéÉ.ý`u‰ÿuï³xÇÞ0Ü\rx\ZnǜÌ},Rhö}͎\0ÁÙ|\\Cè\'\0“V0Â21ó°àÁÿÿrÐâÉ\rÒÒÊù\"åhlé|:ò}$g:9¿ÇŒŽ»ÀÃh?Á˜‰ù£!á.*ê\ra¥®­~ËÔ·Yp2Õþ˜e“$xÐËÚÚݓ?“@É .ÌD“6¯c‡î~ž¬‚€a¶@av+ì ÿÿçŒÖêv-(&&±G]-ˆ6Ÿ‚‚Ô+ÄäØ>„»ýÔÒc‹ŽÍ2ɛþ>áÊVóãx€]Œá­ÉçœC‚L›?z_\\?l<«qp    ÙÀJÇp¯\0\\V1À +S‡ºõ®ƒüÿŸÄë‚\'Iâ%ó2¯éñLYƒ»Ð‚bZ7œ\'ý~‚Ù¡\\h‡h“{¶>ÁšúÁ©_7nkPð^aÜK×+ÒJ~a\\ÊD\0͚6•Ð%\0•åŽ0ÃÐÒ¡[6îËÊv~dE€ó ‰Ÿ“lAÕŸˆEdzjŽê¡þPè¿ËŸîìgD˜àŒ\"méFÜ8‡î±ÉŒËiImpñ>I€       %:™š&\"ë\r£|™ž,c\0@†8ž0óÿ§*p6*-m¡ñàÀl`ʅèŽd»vE–ɺÂ­„ÿ·Sà–ÍÈ€æôE~]͚› yL+y9>ƒ#dî<-™E“Z7=Ù/•VÀ…‘ÛŽ±ß€l+H„at‹àzèÿ¹µi&cg±Ä’&‘:IÆIåaR’\nƒ“ÉÉëüëwÁ/äèŸ7^Ÿwru[T˜Òy¿è<YªwvÙQÅ6œy–cüúj›s8zþ­ÓÐҀǢöhõx–ož®‚€A—/»™p€ƒÿÿåŽÝôFL\Z”–Ï<T˞¡Uñ­’@šŸ…lÐiÂÎòà{`DÚë)×ôD·K÷ÿ}q\\—3É쪵–òÌzVÙúÉ  C«F÷ÄX{$êšÐ_È.c€B†FŒAþýoùÅÖªq–\0Ò>Î>|\"®ó$íûÎÂi[     J]ÌIy†Yìڏ$œƒüE4\"ûë\'^¿Èƒ,¢“ÏÐ7ûFMO‚Þ“™ÀF6Ë͆ÄxþJïÖve‚9]ïœÐú\rZî€òº˜,@‚vú\Z\'ŽædBwªf„†9,_ §”³Œ–\0Û66ĉJp«QøË#ç.P[Éa`‡J³³À:uŒ„H ºÚR\0\0Ac_Qwèþ·ÌW5ûJsn\nsŠ­÷6X”Á[Unè5›-†\\é!ÿËâž DõU@QRŽ‹ÁÃ>˜ðý.«ã]r|ž~7Z®\0Àn×R€J`o–™3­‚\0@\0á©P\rÇD=àÝ?ä>\0Ð`N°\'u\0¬Ï-…Ü€€\0Â(­UºH•B=óÄ u¶±*€\0\ZYóÜšå0\0 Ñy\0 Ñp€\0€\0\Z\r\00\0tP|O;ë\0\0\0\0IEND®B`‚','image/png',2,NOW(),2,NOW(),90);
2642+INSERT INTO `files` (`id`, `name`, `description`, `file`, `type`, `createdby`, `creationdate`, `modifiedby`, `modifieddate`, `roleid`) VALUES ('2', 'invoice.pdf', 'PDF', '%PDF-1.4\r%âãÏÓ\r\n14 0 obj\r<</Linearized 1/L 15879/O 16/E 10758/N 1/T 15552/H [ 616 187]>>\rendobj\r                  \r\nxref\r\n14 16\r\n0000000016 00000 n\r\n0000000969 00000 n\r\n0000001242 00000 n\r\n0000001533 00000 n\r\n0000001578 00000 n\r\n0000002058 00000 n\r\n0000002458 00000 n\r\n0000002726 00000 n\r\n0000002761 00000 n\r\n0000005454 00000 n\r\n0000005643 00000 n\r\n0000010189 00000 n\r\n0000010432 00000 n\r\n0000010681 00000 n\r\n0000000803 00000 n\r\n0000000616 00000 n\r\ntrailer\r\n<</Size 30/Prev 15541/XRefStm 803/Root 15 0 R/Info 6 0 R/ID[<18B83AADEF3A9530529D4B8D4E5D7BAE><806765DA6F59664397BA0CBC3A9F9431>]>>\r\nstartxref\r\n0\r\n%%EOF\r\n  \r\n29 0 obj\r<</Length 96/C 101/Filter/FlateDecode/I 123/L 85/S 39>>stream\r\nxÚb``àa``‘g\0UTÀÄ,\rŒ*H‚<PÌÀ ÌÀËÁÀÔ\\%v¡€ÑÇaVÏÆ5LÀrLZ\'!4ƒ320hzChÆ:žYlÖÜQ†÷\0\0ÀÃî\r\nendstream\rendobj\r28 0 obj\r<</Length 20/Filter/FlateDecode/W[1 1 1]/Index[7 7]/DecodeParms<</Columns 3/Predictor 12>>/Size 14/Type/XRef>>stream\r\nxÚbbbd`b``Ć\0Ž\0\r\nendstream\rendobj\r15 0 obj\r<</MarkInfo<</LetterspaceFlags 0/Marked true>>/Metadata 5 0 R/PieceInfo<</MarkedPDF<</LastModified(D:20090424131355)>>>>/Pages 4 0 R/PageLayout/OneColumn/StructTreeRoot 7 0 R/Type/Catalog/Lang(þÿ\0E\0N\0-\0U\0S)/LastModified(D:20090424131355)/PageLabels 2 0 R>>\rendobj\r16 0 obj\r<</CropBox[0 0 612 792]/Parent 4 0 R/StructParents 0/Contents 18 0 R/Rotate 0/MediaBox[0 0 612 792]/Resources<</XObject<</Im0 24 0 R>>/ColorSpace<</CS0 17 0 R/CS1 21 0 R>>/Font<</TT0 19 0 R/TT1 20 0 R>>/ProcSet[/PDF/Text/ImageC/ImageI]/ExtGState<</GS0 27 0 R>>>>/Type/Page>>\rendobj\r17 0 obj\r[/Indexed 21 0 R 255 23 0 R]\rendobj\r18 0 obj\r<</Length 410/Filter/FlateDecode>>stream\r\nH‰tRQOã0~ϯøáDS\'MšXBH·n‡žcÐJ<£²w·MlÓñ÷ÏI›„ê:þ>۟ýª˜BÐÁÂpÐ6¢šYG‡Í\\ÝÃJœ*I`«©Bm,\nñó[~*/[ÂÓVeh`æAbB,  ñSÐìä×:ôKU^-   ãµºÍ6êTù}³{Y<ô;œŸ_\\ŒÆ\r>ˆË®#t%T‰Y>6æ>«”ë–ê§ÝoU–]œ÷†ÂH煯uÅèÕɯÍ|œ›ÿÁõu“aRÁ(CÊTš‡AÏË\0šŒ¶¹^ñüܚqº¶‡Džhp÷²ÆÝê^cô÷ߣÆl‚â(z†Ù1Q\'ñ:kéØhrÞŒfÞJŠM    “©4ٚ֠ßÂdö_)ë*ÑÅÂ;ؐ֎²švŸÕ63E:xŒ!b*‘ŸP–‚eQÉ¡p™HBKõ¬Ú/vDÚ0ãéHÁaUÒñ“„ž’2Áxmë¬ÍÍøÇaœòFxËis5ĞàŠ£í”ætdu:ԏØëò_€\0?›œ‡\r\nendstream\rendobj\r19 0 obj\r<</Subtype/TrueType/FontDescriptor 25 0 R/LastChar 118/Widths[250 0 0 0 0 0 0 0 0 0 0 0 250 333 250 0 500 500 500 500 500 500 500 500 500 500 0 0 0 0 0 0 0 0 667 667 0 611 0 0 0 0 0 722 611 889 722 0 0 0 667 0 0 0 0 0 0 0 0 0 0 0 0 0 0 444 0 444 500 444 0 0 500 278 0 500 278 0 500 500 0 0 333 0 278 0 500]/BaseFont/TimesNewRomanPSMT/FirstChar 32/Encoding/WinAnsiEncoding/Type/Font>>\rendobj\r20 0 obj\r<</Subtype/TrueType/FontDescriptor 26 0 R/LastChar 80/Widths[250 0 0 0 0 0 0 0 0 0 0 0 0 333 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 722 0 611 0 0 0 0 0 0 0 0 0 611]/BaseFont/TimesNewRomanPS-BoldMT/FirstChar 32/Encoding/WinAnsiEncoding/Type/Font>>\rendobj\r21 0 obj\r[/ICCBased 22 0 R]\rendobj\r22 0 obj\r<</Length 2598/Filter/FlateDecode/N 3/Alternate/DeviceRGB>>stream\r\nhޜ–wTTׇϜwz¡Í0Òz“.0€ô. QfÊ\0ÃMlˆš@DE €£¡H¬ˆb!(š`HPb0ŠššdFÖJ|yyïåå÷ÇœßÚgïs÷Ù{Ÿµ.\0$O./– ™\'àz8ÓW…Gбý\0x€Š\00Y驟AîÁ@$/7zºÈ ü‹ÞHüŸeèéO§ƒÿOÒ¬TŸ\0\0È_ÄælN:KÄù\"NÊ€Ší3\"ŠÆ$ŠF‰™/JPÄrbŽ[䥟}ÙQÌìd[ÄâœSÙÉl1÷ˆx{†#bÄGÄ\\NЈo‹X3I˜Ìñ[ql2‡™\0Š$¶8¬x›ˆ˜Ätñr\0p€ž/8æp²âC¹€€fó¹qñº.KnjmÍ {r2“8¡?“•Èä³é.)É©L^6\0‹gþ,qmé¢\"[šZ[Z\Zš™~Qšÿºø7%îí\"œ\nøÜ3ˆÖ÷‡í¯üRê\0`̊j³ë[Ì~\0:¶ wÿ›æ!\0$E}k¿ñÅyhây‰RmŒ333ž–‘ž ¿ë:ü\r}ñ=#ñv¿—‡îʉe\n“tqÝX)I)B>==•ÉâÐ\rÿ<Äÿ8ð¯óX\Zȉåð9<QDšhÊžŒ8Q»yl®€›Â£syÿ©‰ÿ0ìOZœk‘(õŸ\05ÊHÝ äç>€¢yPÜõßûæƒâ›Š:±8÷Ÿýû®p‰ø‘΍ûçLg  ù‹kâk  Ѐ\0$È t!0VÀ87°ø`ֈɀ2A.Ø\n@Øö‚JPêA#h\'@8\r.€Ëà:ž        î€`Œƒç`Œóa!2Dä!UH2€Ì d¹A>P ECqB¹Ðš*…*¡Zšú:]€®BÐ=hš‚~…ÞÃL‚©°2¬\rÃØ      ö†ƒá5pœçÀùðNž®ƒÁíðø:|ŸÃ³@ˆ\rQCâ‚ø!H,ÂG6 …H9R‡Ž ]H/rAŠ‘w(Š‚¢£Q¶(OTŠ…JCm@£*QGQíšÔ-Ô(jõ      MF+¡\rÐ6h/ô*t:]€.G7 ÛЗÐwÐãè7††ÑÁXa<1á˜Ì:L1æ\0Šs3€ÃÌb±Xy¬Öë‡ebØì~ì1ì9ì vûGÄ©âÌp‡+Ç5áÎâqžyŒ^oƒ÷óñÙø|=Ÿ?ŽŸ\'Htv„`Ba3¡‚ÐBžDxHxE$ՉÖÄ\0\"—ž‰XA<NŒB%Ÿ#ɐôI.€H’Ž“t„tžtôŠL&k“Édy\'¹‘|‘ü˜üV‚\"a$á%Á–Ø(Q%Ñ.1(ñB/©%é$¹V2G²\\ò€ä\rÉi)Œ”¶”‹SjƒT•Ô)©a©YiŠŽ©ŽŸt²t±t“ôUéI¬Œ¶Œ›[&_æ°ÌE™1\nBÑ žPX”-”zÊ%Ê8CÕ¡zQšEÔošýÔYÙe²¡²Y²U²gdGhM›æEK¢•ÐNІhï—(/qZÂY²cI˒Á%srŠrŽr¹B¹V¹;rïåéònò‰ò»å;ä) ô2*\\R˜V€*Ú*²O(ÞW‚•ô••Ö)VêSšUVQöPNUÞ¯|QyZ…Šâš’ RŠrVeJ•¢j¯ÊU-S=§úŒ.Kw¢\'Ñ+è=ô5%5O5¡Z­Z¿ÚŒºŽzˆzžz«ú#\r‚C#V£L£[cFSUÓW3W³YóŸ^‹¡¯µO«WkN[G;L{›v‡ö€ŽœŽ—NŽN³ÎC]²®ƒnšnîm=ŒC/Qï€ÞM}XßB?^¿Jÿ†l`iÀ58`0°œÔz)oiÝÒaC’¡“a†a³ášÍÈÇ(ÏšÃ腱Šq„ñnã^ãO&&I&õ&LeLW˜æ™v™þjŠoÆ2«2»mN6w7ßhÞiþr™Á2βƒËîZP,|-¶Yt[|ŽŽ²ä[¶XNYiZE[U[\r3šF1ãŠ5ÚÚÙz£õiëw6–6›6¿Ø\ZÚ&Ú6ÙN.×YÎY^¿|ÌNݎiWk7bO·¶?d?â æÀtšsxâšáÈvlpœpÒsJp:æôÂÙęïÜæ<çbã²ÞåŒ+âêáZèÚï&ãâVéöØ]Ý=ΜÙ}ÆÃÂcÇyOާ·çnÏa/e/–W£×Ì\n«ëWôx“ŒƒŒ+œŸøèûð}º|aߟ{|®ÔZÉ[ÙáüŒüöø=ò×ñOóÿ>\0àPð4Ð407°7ˆÔô&Ø9ž$øAˆnˆ0€;T242Ž1t.Ì5¬4ld•ñªõ«®‡+„sÃ;#°¡\r³«ÝVï]=iY9ŽFgM֚«kÖ&­=%Ō:Ž‹nŠþÀôcÖ1gcŒbªcfX.¬}¬çlGv{ŠcÇ)åLÄÚŖÆNÆÙÅ퉛Šwˆ/Ÿæºp+¹/<jæý$.$…%µ&㒣“Oñdx‰Œž•”¬”TƒÔ‚Ô‘4›Žœi3|o~C:”Ÿ&œS@ýLõ        u…[…£öUo3C3OfIgñ²ú²õ³wdOäžç|œµŽµ®;W-wsîèz§õµ \r1º7jlÌß8ŸÉcÓÑ͉̈́›È3É+Í{œ%lKWŸrþŠü±­[›$\nøÃÛl·ÕlGmçnïßaŸcÿŽO…ìÂkE&EåEŠYÅן2ýªâ«…±;ûK,KîÂìâí\ZÚí°ûh©tiNéØß=íeô²Â²×{£ö^-_V^³°Ožo€Â§¢s¿æþ]û?TÆWÞ©r®j­VªÞQ=w€}`ð ãÁ–\Z嚢š÷‡ž‡îÖzÔ¶×iוÆÎ8üŽ>ŽŸ÷kÆ×\r\n\rE\rðŽŒ\r<ÚÓhÕØØ€ÔTÒ7›§ŽE»ùë7-†-µ­ŽÖ¢ãàžðø³o£¿:á}¢û$ãdËwZßU·QÚ\nÛ¡öìö™ŽøŽ‘Îð΁S+NuwÙvµ}oôý‘Ój§«ÎȞ)9K8›vá\\ιÙó©ç§/Ä]ëŽê~pqÕÅÛ==ý—Œ/]¹ì~ùb¯Sï¹+vWN_µ¹zê\ZãZÇuËëí}}m?XüÐÖoÙß~ÃêFçMë›]ËÎ:^žåzëòm¯Û×﬌302tw8rxä.ûî䜀{/ïgܟ°é!úaá#©G叕×ýš÷cëˆåșQ×ÑŸ\'AOŒ±Æžÿ”þӇñü§ä§åª“f“§§Ü§n>[ýlüyêóù邟¥®~¡ûâ»_é›Y53þ’ÿrá×âWò¯ŽŒ^öº{Ööñ›ä7ós…oåß}Çx×û>ìýÄ|æì‡Šz»>yzžŒ°ð›\0\0÷„óû\n\r\nendstream\rendobj\r23 0 obj\r<</Length 119/Filter/FlateDecode>>stream\r\nhÞìÁ!\0\0ÐŽà\nm3Q“A¶mdP%A”Í’hÆÌ^ã‡}!Tk1îœCBÒ9—sŸï{ÎÙZ3Æ€””R×uõÞ×ZÖÚRÊãy­5ÆBH)%„\0\0cœósÎïóùc¯\0\0…‹7Ž\n\r\nendstream\rendobj\r24 0 obj\r<</Subtype/Image/Length 4391/Filter/FlateDecode/BitsPerComponent 8/ColorSpace 17 0 R/Width 263/Height 93/Type/XObject>>stream\r\nhÞì[‹z›žŽ@@\rƎc‡0ðþoy4W0NÚ&§ÝýÖjã˜Ëˆ™_sY–ÇxŒÿïx­aìþë0ì®0ê_‡áäœË<ŽÌ¹ÓÖå8–/7饬k«yžŠª­ý%¿óô¬lÓŒ÷ž¯ÀÐÿ>>p0́SøÿÃÁt,/öžvšæI\0zŸ<uñ|SVt\ZpÀqÌnˆñŠy’)Š¢»üý—ށøD&‘™‰9*|äž50ÍÓa5ÃEA€/­œÎ»„аžŠ×\nÝĿÚÞ(xdÍb«žDmIÛõ£ÊÉÈ0  —B‘à J4¡¶7̌˜ûÓ0ü€³>\'\n~dm!­)V3TB×†Ã¬Sª±ÁAiÅ€ÀO¯B™ÿ†Qô_цi6+2)ðÁ8°¢ÈéR¢˜0†Ã€jn$\r‡Æð;YüYægûAVŽùÕõMQ~Ñ\råZՄ€)W6aŒKøÐ*™žG7·(LÑ\"#¢–Åéaè¿dÆK«G<Ø£‰§cµ­Ö6*|áÐ\"ŽQïd= 0ÍÑ=ϪkDæòk8|±\nf¹+‹Y#èN»ADilnКZ3–àÿ£™…šA:áK7™¢0M†jV£¡£úGUþaPÿ¥&Ÿ£ï®U*R2CŸMƲQtÑ×ÕQ”üPO²ÀÙlœ®˜›€ç\\µÚ7\0ßÑóåÕ$ÚpÄÊ[>kFÍ­\ZF›Éoƒk£n5Y\'(c      Œx2)ÿGµ4Â%K,a`E(\'ö$‰M 8^ƒ£[r5óéŽy·Q»bœ`7‚úÓÑtEs—o·Ûœ~ \ráòËGb¯É5BXœxÔñ?ùj^‡œŒMû€ÑÎ#šÄEnópPáUÅ=rÎÖ2,15§BšE~{™û§ÙoÁð⟱Àxªv÷ɃîXòhô)¬«`ž^\\Ù¥ff;»®”R‰PM§îbÚ^ÍÊ€1y€S]ÕO6‰˜=~C‚`Oþ†O|-üÌ/ñrß_…돫%Ùž5\n‰¢˜#x֌ÙyVCfÎ6UGãRàhÓž/’§©‘pª,Ž9ºtµÃ—·k îóKÃË{@N·IÞ+L.ü€.R×\nŒÛK$sNVñ€êM©Ÿ ò2úŸU%Õ*ùí\"ÄNju“F\Z–£B!zFÆû‹ÈÙ÷õË»Áqxä=‘§ƒÈ\'Íb\"äsäé;IìÜ\"%hŠ‘{mõ©ž¢‡ÄÀöÆ.ò$eçsjÓÒ^óªCÃ+-æSU×oϲ¢ïFÐ+Œ¿Õõü$Ë-äýŠüjÉÕBÕ(•d>3%‘Z;¹–ˆ^0GÖ* òXsÚü鎶‰Ù֓R~k0F!XÕ    5\nƞ/EðŠ0Ù{¹ìŸH%Œ÷7ä4ÞÄE\"74ŸÊ¶ˆi>§³­81·”RnD‰0’Jà\r‡ÓN[*Ìǃ͢/Jµ!ùôÑøÖÈ\"ÆãÊYÒW!Õæj¯«}—ny¥zA»N±=‚Kž\rEß\0¡Ž$$.9Ö9V˜À“7‰]\'üìœUx­[V5­[ 8›§0ô‰×eA*‰$×þí&—žŸªQ\\E7R«˜Ejy\'ŒÅP!¡=¬³}É)$ƒÌø¬örŒ¥¹L¬a ˜b$‰\rLE)Lå€\rŒÎÀÐßä‰?z^Ï^ퟓ«Ïqýûmr¢z]bkÈè(”‘\'“hòb-1O>R\nIÊÐqˆCÙ[*Kl©Ê“rR0Å>òØT|ØPÎÒ²“&u8D‚ÈOëÜP$¥dúšnTxsTŠ»ä±1hjøªê rPÕdt•³AäŽhÁA=­|)œ8åšó1§ÚM’²0QG¥ñâ­Qô?ÖqÇ£øÏl\0ïéŗ+(UØ §;wmÚ.0Ž.ŸŽ4ŸPæçs\rq&ˆ”¶”(1}g—„]&=†Fr«©Ì¢©x«\r×כ,ä‰2‚ݍg‹ýÓ§äW…aŠT­€)Tœ4ÙáRŠê‹…:óRp¶¢Vêí]_„[–Y[1Ó$œ¶ã4³ŒE­Xo%ÚðŽQâ…ÝvƒþY’G„¡ß&”»˜ðÛ0ŽF;žÄs²0³)}€g‡ÅúS~ºVûy2gÈD¬’Žã©àF×aNÚýážÌÂðŒ‘“¢Uì°hè7aè5Rl’#Š1N°K>eUÌ÷amXJkRJpRy4œð0\\ö!§®ÐŠ)U·h“ý‚V1f^D\'͚ä>!£Œ\nµá†ÞhÃ=r ±Î‘Ý›ÖØAÊM†á\"ÎëŽÔ¬×šBÕ¯«êvކ5ãQ7ql÷¹ä\'›`š¶,ú~[î·lwŸwɑ.v“\nSûÉGl³EmÈÅÒ³¥ ¹Ikœ–˜7Oj:ÛØÎjÑyFáÁhŠÄ$€·ù¡6|Ãõ3mP„A—”6ÊJãşµIñםx‘úa+eDwlꌧŠÈ{gv6V»`ñîËñEtOÎjš=\'û΋ŸkY^RòãXåÈ œ™ikãí;×Ç&ñް¥!^ð4¥­ß€—}ÏǑoðÛ;ÚÏš*’EÞ#ï¯>j eßÅ é/Ÿu²çÕµoî?–ZˆOžuÒª&֕Zãðê4ŸÁÀ®~wÝt‘Ÿjƒ‰iòN0hãÅkðŠ&ˆÛž\'ãVçéfo/â*z‡ÎÆè‚j”›m7ŠŸirWÊ^w[%CCÿ¹Ö—‰2bÒãÛT–Ú8°Ø»hi| …£.+ð”Cé~Ÿ¶ï)ùϝ¿gWkwÈCZ;‚–ý:Jê€/(Úpˆ{’÷FýaóÚì?JË=Œ7ÁŠuâMpû.Døjö   !Wî¯n+îC©|Ozk›ä°Z”œ€Ao¶ä›VֆåktnžX­Ÿ¿ÞŸÈÍB•G‹([åŒGdšR\\¹Xßp]\r°Þá|¶ü”oØ$¿¹ª¡±éS÷–‹î1Ê\rGI$¹Õ Þ„\0õ[€\r§æšÍךæ§b2ûú7%ùŽêõE9ÖÅÑ»ÓO˧FqŸmEÛ\"\nCßÖÁšPûŠrC[©q?ʼnkÚp¡ìš<8À¢¹tŠçŠoýˆ.H¢VLʉž‘ä\r!nœ\'ƒ—\'I>Ë\"{ê[Þ#h5Ÿ     WW±Ô\'O=­#áÅø±KJZRtL^r™m«ÒhœŠÍÉæÍºñdµ!Ûñ=6Sî¥Oœ…ᆌ—^ŒöüLÇÅŒ–q‚~:Ë \\™ÜX×+×¶c»ŽsTïØÒÁ/ºY_Å\nk²ÁaÒ·\nætC·Xt§        zÏÚrº0ûÄ(RrÂÈ㫊g®:|:;ɋjí ˜Ç*„í2ۗgâÎLò\ne6I0˜àÑj§z§øö–ívþÚ±ì>HŠ{…ᝢ«’G\Z[ß\'}(°Íƒ$5Ҋ”TÛlQÉPånú8my‹ÀæþS¥åŽ12ÍE×(p6ìžì–ŽJkƒOò†>’=ÆZ†!vA’—˜ŠãIr;:k+†+·Ú õžŸ“cû5}\'oík†Vqfi[ÞhÃ3n>Ð?Etü)ÚÐ#yŠ¢\'/šwÒBéÄQ;øqöJöaÌÃʬ±Ý6oŸä—ÆLö¥±úö}ZÎeyM¶!«×$ô}0û„Œ·äª\nɛ=ǘ\0yíŽÆÙ}KãÂÀnnɳcòVv¥Ë<ïŠ)qI›ÕF\ZkŠ×·wZÎç1\rØþC¯¯5DŽý[K~ð ÓQ˜mÛÚg   ÎËX>‡äŸü€Û€äŠöî+áMYD¬Hºí{ÓÒjý¶Ê§ã‹ä_\ZÍí;õ·Ã•­ºÆª;ä?%Ç/{æ?j ^îôóËùë0ô×>¿¬ÕšüŸÃíN톇6<`xÀŽþƒÈñp‘vd0<|,’üß\"ŒÇxŒÎÈ˲Ü}ãl#ü±o˜öù×7]˜-ÿÁÐãø}Œú1Œ|†aGcøý}œ–aêæßC9 ¯áä`ŒËwÎ=üK`ØùÏ(?À\0ªñ¯Ñ†áa€ÊOFAJñm0¿øŸn÷à]º0wa÷áŒsçqšð/„ƒ6CžUÃxv.\\ÞÓñ9áAol\'œ«ãÁ/ D‡»CÓ\'ÁE4>xumpS£ßàA¯†áœ5Âs©î8ÝUãy\rƒëÂÄ¥rB²ìÕ»ž®—ðPCpXyË~poӁªâá8ì#{>ŸoËGRÑÕÑü1s8S%RT 4˜X       €àFŽl5¬|:ÓeGœŒ†+ö­d\0̂O\"‡ÕÑÎôwÞÝ(œ¢®./ÌDQPšœš¥!Ÿ\Zdf ó¹££žÍs‡l@ ;|ʲ7g8[9¢˜²€AzX™ÀFà4ž£iá¶YÓ`aéê~Xd,ü \'ÒŽHÌ(ž˜QžµÌsœ2,i^’ÀeqÍHÏAþŽáŒŒ4®\"mh€øìš p#ذ@sO‚û%GìóÅÇCÞÀ©Š!ü,rð/ü×Ñïöûr žGŽ-àÖqß\"H\rƂZÚ5”0ÁˆnÙ\\fFÒŜB9=9°ëX—ɐårÉQÜ\naȂdôr     ŸD’f•ïÅõ‚d8-ëÖȑ\"üòì1E\Z`§RãðÂ-à›‘!óa€ÔÌã&gõ$\0óE×Åctι<°ÖIžrÃhlԁ6Žä?åàˆq§6èÐÒ«1*£ub3l€Ýϟª5*    ƒ,@7˜Pçqj€s¯€ZœhÅnC`oð<Èk Ò(‡g%Qˍb9#^qÊ`\08ÁRIºoZåšžìË $Õ ðDF†×6ÌŠ0À»}ø8GÉߎòÉQ!2#…éˆ{Ã(>Ó\rñ23ÊÈŠçRÆ£…\'íÈ7Dà÷š,CšøÀ#í2΄MF@Ÿ5á„!Â`ó? :³\rƋžXØEŠL‹‚        œ£;”“b!\Z€/†ÈÕ%\"q¢€N›œZ0UÔIÆÜ¡ÿ5¬çÐ\\M¥ÂX‰,³Qð£e©ÒüoOØaìèdÍ@Œ!B˜r—2.r/”àԒÈí0֚ËbÖ#Ë7ïðFÈÂ(jJ\rŽ—Q€pš>ö#³›—ÉNx>Òd;ÎP$5—š‚³Htx‘ªŠÆQZö‰\\bð!—Àтz¶ýг ]ŸPp¥¹={ŽÊšÏÙ9Ï©U9ÆÐXŠõ—uù®`K0+ ƒ—Ã̵ŽŽ\\F’.ŠæcZS¬ªlTqM‡óYÔcpVZÚ²6\nœhč’6N<‚K†…ó¬pC§Y$Ž.–V.è ôy%™&9æNS°Ä8»ºŽU³Ž{£Í      Òe†lˆÜ/e;Ý3^éHÚøžŒ&ІâfšfâtĉJš        ç­úŽ#CÉ.ìŒDý •ÊÉCœc1±bp¬ÜŠ^œÑ†€(ʍøœW:*ސ˜\nG·¿XӂÏ0†ŒŽ•—:ÎÑVú\"nꖜsûÜ$p\"—ÛèK÷,yr쌘9LEÉÏ\"¢æG¹á„7hâsòôPÉÌóâ,û”1dbs­õåͱ²ž¿0*Ìf¿g€W õkîn5õ†¿„¶ìû&ãŠÏÖ-?Eø·µAjÌï™Ùð_~ †$EýãcOÁäûæë(Jøfù&uÁñqüO€\0×ø|O\n\r\nendstream\rendobj\r25 0 obj\r<</StemV 82/FontName/TimesNewRomanPSMT/FontStretch/Normal/FontWeight 400/Flags 34/Descent -216/FontBBox[-568 -307 2000 1007]/Ascent 891/FontFamily(Times New Roman)/CapHeight 656/XHeight -546/Type/FontDescriptor/ItalicAngle 0>>\rendobj\r26 0 obj\r<</StemV 136/FontName/TimesNewRomanPS-BoldMT/FontStretch/Normal/FontWeight 700/Flags 34/Descent -216/FontBBox[-558 -307 2000 1026]/Ascent 891/FontFamily(Times New Roman)/CapHeight 656/XHeight -546/Type/FontDescriptor/ItalicAngle 0>>\rendobj\r27 0 obj\r<</OPM 1/OP false/op false/Type/ExtGState/SA false/SM 0.02>>\rendobj\r1 0 obj\r<</First 44/Length 288/Filter/FlateDecode/N 7/Type/ObjStm>>stream\r\nxÚTQÁnÂ0ݧøž&7ë6˜„*m@%ÄV*\'Ä!+VW\r’(M\'øû9éãà8vžýì—$0‘$ðâQð\rÄ3›€tÀÑ»\')€ÃF#œ38%–Ê‘ö+GÄu׉‚Ž~N\'ž4{úP6ôÕÉJïº*â–ÆxïUÛFŒ˜,‹Ì{ z‰’*ïJ×·Óâ~-oî\"°èí&   C2jS3œo4É/ÅTySwŽpâŒ+{”Vi”Ýg[¹ÆúshÉýO¬¯lc¶<zžŸù&ӝŸyÕ7sÄIóƒSœÓÆáÈy·KŽÖ;rRn6Ýf˜;u X}51³ö€°R–mz9¶Qš„Uþ©RbYóoõÂý\n0\0SY‰x\r\nendstream\rendobj\r2 0 obj\r<</Nums[0 3 0 R]>>\rendobj\r3 0 obj\r<</S/D>>\rendobj\r4 0 obj\r<</Count 1/Type/Pages/Kids[16 0 R]>>\rendobj\r5 0 obj\r<</Subtype/XML/Length 3975/Type/Metadata>>stream\r\n<?xpacket begin=\"\" id=\"W5M0MpCehiHzreSzNTczkc9d\"?>\n<x:xmpmeta xmlns:x=\"adobe:ns:meta/\" x:xmptk=\"Adobe XMP Core 4.0-c320 44.284297, Sun Apr 15 2007 17:19:00\">\n   <rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">\n      <rdf:Description rdf:about=\"\"\n            xmlns:pdf=\"http://ns.adobe.com/pdf/1.3/\">\n         <pdf:Producer>Acrobat Elements 8.0.0 (Windows)</pdf:Producer>\n      </rdf:Description>\n      <rdf:Description rdf:about=\"\"\n            xmlns:pdfx=\"http://ns.adobe.com/pdfx/1.3/\">\n         <pdfx:Company>CDOC</pdfx:Company>\n         <pdfx:SourceModified>D:20090424191324</pdfx:SourceModified>\n      </rdf:Description>\n      <rdf:Description rdf:about=\"\"\n            xmlns:xap=\"http://ns.adobe.com/xap/1.0/\">\n         <xap:CreatorTool>Acrobat PDFMaker 8.1 for Word</xap:CreatorTool>\n         <xap:ModifyDate>2009-04-24T13:13:55-06:00</xap:ModifyDate>\n         <xap:CreateDate>2009-04-24T13:13:45-06:00</xap:CreateDate>\n         <xap:MetadataDate>2009-04-24T13:13:55-06:00</xap:MetadataDate>\n      </rdf:Description>\n      <rdf:Description rdf:about=\"\"\n            xmlns:xapMM=\"http://ns.adobe.com/xap/1.0/mm/\">\n         <xapMM:DocumentID>uuid:5a739654-6d18-4da2-8743-6248962559e2</xapMM:DocumentID>\n         <xapMM:InstanceID>uuid:72085637-7bdb-4b64-8ca5-592cf09f40da</xapMM:InstanceID>\n         <xapMM:subject>\n            <rdf:Seq>\n               <rdf:li>1</rdf:li>\n            </rdf:Seq>\n         </xapMM:subject>\n      </rdf:Description>\n      <rdf:Description rdf:about=\"\"\n            xmlns:dc=\"http://purl.org/dc/elements/1.1/\">\n         <dc:format>application/pdf</dc:format>\n         <dc:creator>\n            <rdf:Seq>\n               <rdf:li/>\n            </rdf:Seq>\n         </dc:creator>\n         <dc:title>\n            <rdf:Alt>\n               <rdf:li xml:lang=\"x-default\"/>\n            </rdf:Alt>\n         </dc:title>\n      </rdf:Description>\n   </rdf:RDF>\n</x:xmpmeta>\n                                                                                                    \n                                                                                                    \n                                                                                                    \n                                                                                                    \n                                                                                                    \n                                                                                                    \n                                                                                                    \n                                                                                                    \n                                                                                                    \n                                                                                                    \n                                                                                                    \n                                                                                                    \n                                                                                                    \n                                                                                                    \n                                                                                                    \n                                                                                                    \n                                                                                                    \n                                                                                                    \n                                                                                                    \n                                                                                                    \n                           \n<?xpacket end=\"w\"?>\r\nendstream\rendobj\r6 0 obj\r<</CreationDate(D:20090424131345-06\'00\')/Author()/Creator(Acrobat PDFMaker 8.1 for Word)/Producer(Acrobat Elements 8.0.0 \\(Windows\\))/ModDate(D:20090424131355-06\'00\')/Company(CDOC)/SourceModified(D:20090424191324)/Title()>>\rendobj\rxref\r\n0 14\r\n0000000000 65535 f\r\n0000010758 00000 n\r\n0000011140 00000 n\r\n0000011174 00000 n\r\n0000011198 00000 n\r\n0000011250 00000 n\r\n0000015302 00000 n\r\n0000000000 65535 f\r\n0000000000 65535 f\r\n0000000000 65535 f\r\n0000000000 65535 f\r\n0000000000 65535 f\r\n0000000000 65535 f\r\n0000000000 65535 f\r\ntrailer\r\n<</Size 14>>\r\nstartxref\r\n116\r\n%%EOF\r\n', 'application/pdf', 1, NOW(), 1, NOW(), '0');
2643\ No newline at end of file
2644Index: modules/base/adminsettings.php
2645===================================================================
2646--- modules/base/adminsettings.php      (revision 514)
2647+++ modules/base/adminsettings.php      (working copy)
2648@@ -198,7 +198,7 @@
2649 
2650                <div class="fauxP">
2651                        print logo
2652-                       <div id="graphicHolder"><img alt="logo" src="<?php echo APP_PATH?>dbgraphic.php?t=files&amp;f=file&amp;mf=type&amp;r=1" /></div>
2653+                       <div id="graphicHolder"><img alt="logo" src="<?php echo APP_PATH?>dbgraphic.php?t=files&amp;f=file&amp;mf=type&amp;r=1&amp;rand=<?php echo rand();?>" /></div>
2654                </div>
2655 
2656                <p>
2657@@ -211,6 +211,16 @@
2658                        On PDF reports, phpBMS prints the logo at maximum dimensions of 1.75" x 1.75".<br />
2659                        If you are uploading a PNG, <strong>it must be an 8-bit (256 color) non-interlaced PNG without transparency or alpha channels/layers.</strong>.
2660                </p>
2661+       
2662+        <p>
2663+               print PDF template</br>
2664+                       <button  type="button" class="Buttons" onclick="document.location='../../servefile.php?i=2&amp;rand=<?php echo rand();?>'">View/Download PDF</button>
2665+               </p>
2666+       
2667+        <p>
2668+                       <label for="printedpdf">upload new PDF file</label> <span class="notes"> (Single page PDF)</span><br />
2669+                       <input id="printedpdf" name="printedpdf" type="file" size="64" /><br />
2670+               </p>
2671 
2672        </fieldset>
2673        <p class="updateButtonP"><input name="command" type="submit" class="Buttons" value="update settings" /></p>
2674Index: modules/base/include/adminsettings_include.php
2675===================================================================
2676--- modules/base/include/adminsettings_include.php      (revision 514)
2677+++ modules/base/include/adminsettings_include.php      (working copy)
2678@@ -138,7 +138,7 @@
2679                                "image/x-png",
2680                                "image/jpg",
2681                                "image/jpeg",
2682-                               "imagep/jpeg",
2683+                               "image/pjpeg",
2684                        );
2685 
2686                        if(in_array($_FILES["printedlogo"]["type"], $validFileTypes)){
2687@@ -174,7 +174,49 @@
2688                        }//endif file types
2689 
2690                }//endif file exists
2691+               
2692+               // deal with pdf template.
2693+               if(isset($_FILES["printedpdf"])){
2694 
2695+                       $validPDF = array(
2696+                               "application/pdf",
2697+                               "pdf",
2698+                       );
2699+
2700+                       if(in_array($_FILES["printedpdf"]["type"], $validPDF)){
2701+
2702+                               if (function_exists('file_get_contents')) {
2703+
2704+                                       $file = mysql_real_escape_string(file_get_contents($_FILES['printedpdf']['tmp_name']));
2705+
2706+                               } else {
2707+
2708+                                       // If using PHP < 4.3.0 use the following:
2709+                                       $file = mysql_real_escape_string(fread(fopen($_FILES['printedpdf']['tmp_name'], 'r'), filesize($_FILES['printedlogo']['tmp_name'])));
2710+
2711+                               }//endif
2712+
2713+                               if($_FILES["printedpdf"]["type"] == "application/pdf")
2714+                                       $name = "invoice.pdf";
2715+                               else
2716+                                       $name = "invoice.pdf";
2717+
2718+                               $updatepdf = "
2719+                                       UPDATE
2720+                                               `files`
2721+                                       SET
2722+                                               `file` = '".$file."',
2723+                                               `type` = '".$_FILES["printedpdf"]["type"]."',
2724+                                               `name`='".$name."'
2725+                                       WHERE
2726+                                               id = 2";
2727+
2728+                               $this->db->query($updatepdf);
2729+
2730+                       }//endif file types
2731+
2732+               }//endif file exists
2733+
2734                return true;
2735 
2736        }//end method
2737Index: modules/bms/install/reports.sql
2738===================================================================
2739--- modules/bms/install/reports.sql     (revision 514)
2740+++ modules/bms/install/reports.sql     (working copy)
2741@@ -26,3 +26,4 @@
2742 INSERT INTO `reports` (`name`, `type`, `tabledefid`, `displayorder`, `roleid`, `reportfile`, `description`, `createdby`, `creationdate`, `modifiedby`, `modifieddate`) VALUES ('Summary', 'report', '303', '10', '80', 'modules/bms/report/aritems_summary.php', 'Items grouped and totaled by clients, with grand totals.', 1, NOW(), 1, NOW());
2743 INSERT INTO `reports` (`name`, `type`, `tabledefid`, `displayorder`, `roleid`, `reportfile`, `description`, `createdby`, `creationdate`, `modifiedby`, `modifieddate`) VALUES ('Payment Type Totals', 'report', '304', '10', '80', 'modules/bms/report/receipts_pttotals.php', 'Totals grouped by payment method.', 1, NOW(), 1, NOW());
2744 INSERT INTO `reports` (`name`, `type`, `tabledefid`, `displayorder`, `roleid`, `reportfile`, `description`, `createdby`, `creationdate`, `modifiedby`, `modifieddate`) VALUES ('Incoming Cash Flow', 'report', '3', '55', '50', 'modules/bms/report/incoming_cashflow.php', 'This report shows total incoming monies for a time period from both posted sales orders AND posted receipts. It can be grouped by week, month, quarter and year.\r\n\r\nThis report runs is unaffected by selected records, search or sort parameters.  It requires input of it\'s own start and end dates.', 1, NOW(), 1, NOW());
2745+INSERT INTO `reports` (`name`, `type`, `tabledefid`, `displayorder`, `roleid`, `reportfile`, `description`, `createdby`, `creationdate`, `modifiedby`, `modifieddate`) VALUES ('Invoice2', 'PDF Report', 3, 100, 0, 'modules/bms/report/invoices_pdfinvoice2.php', 'This report will generate and display an invoice in PDF format based on an uploaded PDF template.  The PDF file will contain one page per invoice. PDF files can be printed or saved.', 1, NOW(), 1, NOW());
2746Index: modules/bms/report/invoices_pdf_class2.php
2747===================================================================
2748--- modules/bms/report/invoices_pdf_class2.php  (revision 0)
2749+++ modules/bms/report/invoices_pdf_class2.php  (revision 0)
2750@@ -0,0 +1,692 @@
2751+<?php
2752+/*
2753+ $Rev: 290 $ | $LastChangedBy: brieb $
2754+ $LastChangedDate: 2007-08-27 18:15:00 -0600 (Mon, 27 Aug 2007) $
2755+ +-------------------------------------------------------------------------+
2756+ | Copyright (c) 2004 - 2007, Kreotek LLC                                  |
2757+ | All rights reserved.                                                    |
2758+ +-------------------------------------------------------------------------+
2759+ |                                                                         |
2760+ | Redistribution and use in source and binary forms, with or without      |
2761+ | modification, are permitted provided that the following conditions are  |
2762+ | met:                                                                    |
2763+ |                                                                         |
2764+ | - Redistributions of source code must retain the above copyright        |
2765+ |   notice, this list of conditions and the following disclaimer.         |
2766+ |                                                                         |
2767+ | - Redistributions in binary form must reproduce the above copyright     |
2768+ |   notice, this list of conditions and the following disclaimer in the   |
2769+ |   documentation and/or other materials provided with the distribution.  |
2770+ |                                                                         |
2771+ | - Neither the name of Kreotek LLC nor the names of its contributore may |
2772+ |   be used to endorse or promote products derived from this software     |
2773+ |   without specific prior written permission.                            |
2774+ |                                                                         |
2775+ | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS     |
2776+ | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT       |
2777+ | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A |
2778+ | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT      |
2779+ | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,   |
2780+ | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT        |
2781+ | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,   |
2782+ | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY   |
2783+ | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT     |
2784+ | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE   |
2785+ | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.    |
2786+ |                                                                         |
2787+ +-------------------------------------------------------------------------+
2788+*/
2789+
2790+       if(!class_exists("phpbmsReport"))
2791+               include("report/report_class.php");
2792+               
2793+       class invoicePDF extends phpbmsReport{
2794+       
2795+               var $title = "Invoice";
2796+               var $showShipNameInShipTo = true;
2797+               var $lineitemBoxHeight = 4.25;
2798+                       
2799+               function invoicePDF($db, $orientation='P', $unit='mm', $format='Letter'){
2800+               
2801+                       $this->db = $db;
2802+                       
2803+                       if(!class_exists("phpbmsPDFReport"))
2804+                               include("report/pdfreport_class2.php");
2805+                       
2806+                       $this->pdf = new phpbmsPDFReport($db, $orientation, $unit, $format);
2807+                       
2808+                       $this->initialize();
2809+                                               
2810+               }//end method
2811+               
2812+               
2813+               function initialize(){
2814+                       //This function will set column headings, sizes and formatting
2815+
2816+                       $pdf = &$this->pdf;
2817+                       
2818+                       $topinfo = array();
2819+                       $topinfo[] = new pdfColumn("Invoice Number", "id", 1.5);
2820+                       $topinfo[] = new pdfColumn("Order Date", "orderdate", 1.5, "date");
2821+//                     $topinfo[] = new pdfColumn("Customer PO", "ponumber", 2);
2822+                       $topinfo[] = new pdfColumn("Processed By", "processedby", 2);
2823+                       $topinfo[] = new pdfColumn("Payment Method", "paymentname",2.5);
2824+                       
2825+                       $size = 0;
2826+                       foreach($topinfo as $column)
2827+                               $size += $column->size;
2828+                               
2829+                       $topinfo[3]->size = $pdf->paperwidth - $pdf->leftmargin - $pdf->rightmargin - $size;
2830+
2831+                       $this->topinfo = $topinfo;
2832+                       
2833+                       
2834+                       $lineitems = array();
2835+                       $lineitems[] = new pdfColumn("Product", "parts", 0);
2836+                       $lineitems[] = new pdfColumn("Qty", "quantity", 1, "real","L");
2837+                       $lineitems[] = new pdfColumn("Taxable", "taxable", 0.5, "boolean", "C");
2838+                       $lineitems[] = new pdfColumn("Unit Price", "unitprice", 0.75, "currency", "R");
2839+                       $lineitems[] = new pdfColumn("Extended", "extended", 0.75, "currency", "R");
2840+                                               
2841+                       $size = 0;
2842+                       foreach($lineitems as $column)
2843+                               $size += $column->size;
2844+                               
2845+                       $lineitems[0]->size = $pdf->paperwidth - $pdf->leftmargin - $pdf->rightmargin - $size;
2846+                       
2847+                       $this->lineitems = $lineitems;
2848+                       
2849+                       $totalsinfo = array();
2850+                       $totalsinfo[] = new pdfColumn("Discount", "discountamount", 1, "currency", "R");
2851+                       $totalsinfo[] = new pdfColumn("Subtotal", "totaltni", 0, "currency", "R");
2852+                       $totalsinfo[] = new pdfColumn("Tax", "tax", 1, "currency", "R");
2853+                       $totalsinfo[] = new pdfColumn("Shipping", "shipping", 1, "currency", "R");
2854+                       $totalsinfo[] = new pdfColumn("Total", "totalti", 1, "currency", "R");
2855+                       $totalsinfo[] = new pdfColumn("Amount Due", "amountdue", 1, "currency", "R");
2856+                                                                       
2857+                       $this->totalsinfo = $totalsinfo;
2858+
2859+               }//end method
2860+
2861+               
2862+               function generate($whereclause = NULL, $sortorder = "invoices.id"){
2863+               
2864+                       $pdf = &$this->pdf;
2865+                       
2866+                       if($whereclause)
2867+                               $this->whereclause = $whereclause;
2868+                       elseif(!$this->whereclause)
2869+                               $this->whereclause = "invoices.id = -400";
2870+                       
2871+                       if($sortorder)
2872+                               $this->sortorder = $sortorder;
2873+                       elseif(!$this->sortorder)
2874+                               $this->sortorder = "invoices.id";
2875+                               
2876+                       $querystatement = "
2877+                               SELECT
2878+                                       invoices.*,
2879+                                       
2880+                                       invoices.totalti - invoices.amountpaid AS amountdue,
2881+                                       
2882+                                       clients.firstname,
2883+                                       clients.lastname,
2884+                                       clients.company,
2885+                                       clients.address1 AS billtoaddress1,
2886+                                       clients.address2 AS billtoaddress2,
2887+                                       clients.city AS billtocity,
2888+                                       clients.state AS billtostate,
2889+                                       clients.postalcode AS billtopostalcode,
2890+                                       clients.country AS billtocountry,
2891+                                       clients.homephone,
2892+                                       clients.workphone,
2893+                                       clients.email,
2894+                                       
2895+                                       shippingmethods.name AS shippingname,
2896+                                       
2897+                                       paymentmethods.name AS paymentname,
2898+                                       paymentmethods.type AS paymenttype,
2899+                                       
2900+                                       tax.name as taxname,
2901+                                                                               
2902+                                       users.firstname AS processorfirst,
2903+                                       users.lastname AS processorlast
2904+                                                                                                                       
2905+                               FROM
2906+                                       invoices INNER JOIN clients ON invoices.clientid = clients.id
2907+                                       INNER JOIN users ON invoices.modifiedby = users.id
2908+                                       LEFT JOIN shippingmethods ON invoices.shippingmethodid = shippingmethods.id
2909+                                       LEFT JOIN paymentmethods ON invoices.paymentmethodid = paymentmethods.id
2910+                                       LEFT JOIN tax ON invoices.taxareaid = tax.id";
2911+                                       
2912+                       $querystatement = $this->assembleSQL($querystatement);
2913+                       $queryresult = $this->db->query($querystatement);
2914+
2915+                       if($this->db->numRows($queryresult) == 0){
2916+                       
2917+                               $this->_showNoRecords();
2918+                               exit;
2919+
2920+                       }//end if
2921+                       
2922+                       $pdf->hasComapnyHeader = true;
2923+                       $pdf->SetMargins();
2924+                       
2925+                       
2926+                       
2927+                       //iterate through each invoice record
2928+                       while($invoicerecord = $this->db->fetchArray($queryresult)){
2929+                       
2930+                               $this->page = 0;
2931+                               
2932+                               $this->invoicerecord = $invoicerecord;
2933+                               
2934+                               //adds top info                 
2935+                               $top = $this->_addPage();
2936+                       
2937+                               $this->_addLineItems($top);
2938+                       
2939+                               $pdf->SetXY($pdf->leftmargin, $top["y"] + $this->lineitemBoxHeight + 0.125);
2940+                               
2941+                               //Print any special/instructions and stuff                                                     
2942+                               $this->_addNotes();
2943+                               
2944+                               //totals
2945+                               $this->_addTotals();
2946+                               
2947+                               //payment details
2948+                               $this->_addPaymentDetails();
2949+                               
2950+                       }//end while;
2951+               
2952+               
2953+               }//end method
2954+               
2955+               
2956+               function _addPage(){
2957+               
2958+                       $pdf = &$this->pdf;
2959+                                               
2960+                       $pdf->AddPage();
2961+                       // test query;                                                         
2962+                               
2963+                               $querystatement = "
2964+                                       SELECT
2965+                                               `file`,
2966+                                               UPPER(`type`) AS `type`
2967+                                       FROM
2968+                                               files
2969+                                       WHERE
2970+                                               id=2";
2971+                                               
2972+                               $pdfresult = $this->db->query($querystatement);                         
2973+                               $thepdf = $this->db->fetchArray($pdfresult);                           
2974+                                       
2975+                                       $pdftemplate = $thepdf["file"];                         
2976+                                                               
2977+                       
2978+                       
2979+                       // set the sourcefile
2980+                       $pdf->setSourceFile(VarStream::createReference($pdftemplate));
2981+                       // import page 1
2982+                       $tplIdx = $pdf->importPage(1);
2983+                       // use the imported page and place it at point 10,10 with a width of 100 mm
2984+                       $pdf->useTemplate($tplIdx, 0, 0, 8.5);
2985+                       
2986+                       $this->page++;
2987+                       
2988+                       $nextY = $pdf->getY();
2989+                       
2990+                       //TITLE
2991+                       //$title = "Statement";
2992+                       $titleWidth=2.375;
2993+                       $titleHeight=1.5;
2994+                       $pdf->setStyle("title");
2995+                       $pdf->SetXY(.80*($titleWidth+$pdf->rightmargin), $titleHeight);
2996+                       $pdf->Cell($titleWidth, .25,$this->title, $pdf->borderDebug,1,"R");
2997+                       
2998+                       $startY = $pdf->GetY() + .15;
2999+
3000+                       //page number?
3001+                       $pdf->setStyle("normal");
3002+                       $pageNoWidth = 1;
3003+                       $pdf->SetFontSize(8);
3004+                       $pdf->SetXY(-1*($pageNoWidth + $pdf->rightmargin), $pdf->topmargin + $titleHeight - 1);
3005+                       $pdf->Cell($pageNoWidth, 0.17, "Pages: ".$this->page, $pdf->borderDebug,1,"R");
3006+
3007+                       
3008+                       //SOLD TO
3009+                       $boxHeight = 1.25;
3010+                       $boxWidth = ($pdf->paperwidth - $pdf->leftmargin - $pdf->rightmargin)/2 -0.0625;
3011+
3012+                       $pdf->SetDrawColor(255, 255, 255);
3013+                       $pdf->setLineWidth(0.00);
3014+                       $pdf->Rect(.75, $startY, 3.5, $boxHeight);
3015+                       $pdf->setLineWidth(0.00);
3016+                       
3017+                       $pdf->setStyle("header");
3018+                       $pdf->setXY(.75, $startY);
3019+                       $pdf->Cell(3.5, 0.17, "SOLD TO", $pdf->borderDebug, 2, "L", 1);
3020+                       $pdf->setStyle("normal");
3021+                                               
3022+                       //Company Name
3023+                       $companyDisplay = "";
3024+                       $companyDisplayname = "";
3025+                       if($this->invoicerecord["company"]){
3026+                               $companyDisplay .= $this->invoicerecord["company"];
3027+                               if($this->invoicerecord["firstname"])
3028+                                       $companyDisplayname .= $this->invoicerecord["firstname"]." ".$this->invoicerecord["lastname"];                 
3029+                       } else
3030+                               $companyDisplay .= $this->invoicerecord["firstname"]." ".$this->invoicerecord["lastname"];                     
3031+
3032+                       $pdf->SetXY($pdf->GetX() + 0.0625, $pdf->GetY() - 0.0625);
3033+                       $pdf->SetFont("Arial", "B", 10);
3034+                       $pdf->Cell($boxWidth - 0.125, 0.17, $companyDisplayname, $pdf->borderDebug, 2, "L");
3035+                       $pdf->Cell($boxWidth - 0.125, 0.17, $companyDisplay, $pdf->borderDebug, 2, "L");
3036+
3037+                       $billto = $this->_setBillTo();
3038+                       $pdf->SetFont("Arial", "", 10);
3039+                       $pdf->setXY($pdf->GetX(), $pdf->GetY() + 0.0625);
3040+                       $pdf->MultiCell($boxWidth - 0.125,.17,$billto, $pdf->borderDebug);
3041+                       
3042+                       //SHIP TO
3043+                       $pdf->SetDrawColor(255, 255, 255);
3044+                       $pdf->setLineWidth(0.00);
3045+                       $pdf->Rect($pdf->leftmargin + $boxWidth + 0.125, $startY, $boxWidth, $boxHeight);
3046+                       $pdf->setLineWidth(0.00);
3047+                       
3048+                       $pdf->setStyle("header");
3049+                       $pdf->setXY($pdf->leftmargin + $boxWidth + 0.125, $startY);
3050+                       $pdf->Cell($boxWidth, 0.17, "SHIP TO", $pdf->borderDebug, 2, "L", 1);
3051+                       $pdf->setStyle("normal");
3052+
3053+                       $pdf->SetXY($pdf->GetX() + 0.0625, $pdf->GetY() + 0.1);
3054+                       $pdf->SetFont("Arial", "B", 10);
3055+                       $pdf->Cell($boxWidth - 0.125, 0.17, $companyDisplay, $pdf->borderDebug, 2, "L");
3056+                       
3057+                       $shipto = $this->_setShipTo();
3058+                       $pdf->SetFont("Arial", "", 10);
3059+                       $pdf->setXY($pdf->GetX(), $pdf->GetY() + 0.0625);
3060+                       $pdf->MultiCell($boxWidth - 0.125,.17, $shipto, $pdf->borderDebug);     
3061+                       
3062+                       $pdf->setXY($pdf->leftmargin, $startY + $boxHeight + 0.375);
3063+                       
3064+                       $this->_topInvoiceInfo();
3065+                       
3066+                       //line item headings
3067+                       $pdf->setStyle("header");
3068+                       $pdf->SetLineWidth(0.00);
3069+
3070+                       $coords["x"] = $pdf->GetX();
3071+                       $coords["y"] = $pdf->GetY();
3072+                       
3073+                       foreach($this->lineitems as $column)
3074+                               $pdf->Cell($column->size, 0.18, $column->title, 1, 0, $column->align, 1);
3075+                       
3076+                       return $coords;
3077+
3078+               }//end method
3079+
3080+
3081+               function _setBillTo(){
3082+
3083+                       $billto = $this->invoicerecord["billtoaddress1"];
3084+                       
3085+                       if($this->invoicerecord["billtoaddress2"])
3086+                               $billto .= "\n".$this->invoicerecord["billtoaddress2"];
3087+                               
3088+                       $billto .="\n".$this->invoicerecord["billtocity"].", ".$this->invoicerecord["billtostate"]." ".$this->invoicerecord["billtopostalcode"];
3089+                       
3090+                       if($this->invoicerecord["billtocountry"])
3091+                               $billto .=" ".$this->invoicerecord["billtocountry"];
3092+                               
3093+                       $phoneemail = "";
3094+                       if($this->invoicerecord["workphone"] || $this->invoicerecord["homephone"]){
3095+                       
3096+                               if($this->invoicerecord["workphone"])
3097+                                       $phoneemail = $this->invoicerecord["workphone"]." (W)";
3098+                               else
3099+                                       $phoneemail = $this->invoicerecord["homephone"]." (H)";
3100+                               
3101+                               $phoneemail.="\n";
3102+                               
3103+                       }//end if
3104+                       
3105+                       if($this->invoicerecord["email"])
3106+                               $phoneemail .= $this->invoicerecord["email"];
3107+                       
3108+                       if($phoneemail)
3109+                               $billto .= "\n\n".$phoneemail;
3110+                       
3111+                       return $billto;
3112+               
3113+               }//end method
3114+
3115+               
3116+               function _setShipTo(){
3117+
3118+                       $shipto = $this->invoicerecord["address1"];
3119+                       
3120+                       if($this->invoicerecord["address2"])
3121+                               $shipto .= "\n".$this->invoicerecord["address2"];
3122+                               
3123+                       $shipto .="\n".$this->invoicerecord["city"].", ".$this->invoicerecord["state"]." ".$this->invoicerecord["postalcode"];
3124+                       
3125+                       if($this->invoicerecord["country"])
3126+                               $shipto .=" ".$this->invoicerecord["country"];                         
3127+                       
3128+                       if($this->showShipNameInShipTo)
3129+                               if($this->invoicerecord["shippingname"])
3130+                                       $shipto .="\n\n\n\nShipping Method:  ".$this->invoicerecord["shippingname"];
3131+                       
3132+                       return $shipto;
3133+
3134+               }//end method
3135+
3136+
3137+               function _topInvoiceInfo(){
3138+                       
3139+                       $pdf = &$this->pdf;
3140+                       
3141+                       $pdf->setStyle("header");
3142+                       $pdf->SetLineWidth(0.00);
3143+
3144+                       foreach($this->topinfo as $column)
3145+                               $pdf->Cell($column->size, 0.18, $column->title, 1, 0, $column->align, 1);
3146+
3147+//                     $pdf->Rect($pdf->leftmargin, $pdf->GetY(), ($pdf->paperwidth - $pdf->leftmargin - $pdf->rightmargin), 0.39);           
3148+               
3149+                       $pdf->SetXY($pdf->leftmargin, $pdf->GetY() + .2);
3150+                       
3151+                       
3152+                       $this->invoicerecord["processedby"] = $this->invoicerecord["processorfirst"]." ".$this->invoicerecord["processorlast"];
3153+                       $pdf->setStyle("normal");
3154+                       
3155+                       foreach($this->topinfo as $column){
3156+                       
3157+                               if($column->format != "")
3158+                                       $value = formatVariable($this->invoicerecord[$column->fieldname], $column->format);
3159+                               else
3160+                                       $value = $this->invoicerecord[$column->fieldname];
3161+                               
3162+                               $pdf->Cell($column->size, 0.18, $value, $pdf->borderDebug, 0, $column->align);
3163+                       
3164+                       }//end foreach
3165+                       
3166+                       $pdf->SetY($pdf->GetY() + 0.18 + 0.125);
3167+                       
3168+               }//end method
3169+
3170+
3171+               function _addLineItems($coords){
3172+               
3173+                       $pdf = &$this->pdf;
3174+               
3175+                       $lineitemresult = $this->_getLineItems();
3176+               
3177+                       $pdf->setStyle("normal");
3178+                       
3179+                       $pdf->SetY($pdf->GetY() + 0.18 + 0.0625);
3180+
3181+                       while($line = $this->db->fetchArray($lineitemresult)){
3182+                               
3183+                               
3184+                       if($line["partname"] || $line["partnumber"] || $line["extended"]){
3185+                       
3186+                               if($pdf->GetY() + 0.17*3 > $coords["y"] + $this->lineitemBoxHeight){
3187+                                       
3188+                                       $pdf->SetLineWidth(0.00);
3189+                                       $pdf->SetDrawColor(255, 255, 255);
3190+                                       $pdf->Rect($coords["x"], $coords["y"], $pdf->paperwidth - $pdf->leftmargin - $pdf->rightmargin, $this->lineitemBoxHeight);
3191+                                       $pdf->SetLineWidth(0.00);
3192+                               
3193+                                       $this->_addPage();
3194+                                       
3195+                                       $pdf->setStyle("normal");
3196+                                       
3197+                                       $pdf->SetY($pdf->GetY() + 0.18 + 0.0625);
3198+                                       
3199+                               }//end if
3200+
3201+                               foreach($this->lineitems as $column){
3202+                               
3203+                                       $ln = 0;
3204+
3205+
3206+                                       switch($column->fieldname){
3207+                                       
3208+                                               case "parts":
3209+                                                       $pdf->SetFont("Arial", "B", 8);
3210+                                                       $pdf->Write(0.17, $line["partname"]);
3211+                                                       $pdf->setStyle("normal");
3212+                                                       $pdf->SetX($pdf->leftmargin + $column->size);
3213+                                                       break;
3214+
3215+                                               default:                                               
3216+                                                       if($column->format != "")
3217+                                                               $value = formatVariable($line[$column->fieldname], $column->format);
3218+                                                       else
3219+                                                               $value = $line[$column->fieldname];
3220+                                                       
3221+                                                       if($value == "&middot;")
3222+                                                               $value = " ";
3223+                                                               
3224+                                                       if($column->fieldname == $this->lineitems[count($this->lineitems)-1]->fieldname)
3225+                                                               $ln = 2;
3226+                                                       
3227+                                                       $pdf->Cell($column->size, 0.17, $value, $pdf->borderDebug, $ln, $column->align);
3228+                                                       break;
3229+                                                       
3230+                                       }//end switch                                                                   
3231+                                                                               
3232+                               }//end foreach
3233+                               
3234+/*                             $pdf->SetX($pdf->leftmargin);                           
3235+                               $pdf->Write(0.17, "(".$line["partnumber"].")");
3236+                               $pdf->Ln();
3237+*/
3238+                                       
3239+                               }//endif
3240+
3241+                               if($line["memo"]){
3242+                               
3243+                                       $pdf->SetX($pdf->leftmargin + 0.0625);
3244+                                       $pdf->SetFont("Arial", "I", 8);
3245+                                       $pdf->MultiCell($this->lineitems[0]->size - 0.0625, 0.16, $line["memo"], $pdf->borderDebug);
3246+                                       $pdf->setStyle("normal");
3247+                                       
3248+                               }//end if
3249+                               
3250+                               $pdf->SetXY($pdf->leftmargin, $pdf->GetY() + 0.0625);
3251+                               $pdf->SetLineWidth(0.00);
3252+                               $pdf->SetDrawColor(180,180,180);
3253+                               $pdf->Line($pdf->leftmargin, $pdf->GetY(), $pdf->paperwidth - $pdf->rightmargin, $pdf->GetY());
3254+                               $pdf->SetDrawColor(0,0,0);
3255+                               $pdf->SetLineWidth(0.00);                               
3256+                               $pdf->SetXY($pdf->leftmargin, $pdf->GetY() + 0.0625);
3257+                       
3258+                       }//end while
3259+                                               
3260+                       $pdf->SetLineWidth(0.00);
3261+                       $pdf->SetDrawColor(255, 255, 255);
3262+                       $pdf->Rect($coords["x"], $coords["y"], $pdf->paperwidth - $pdf->leftmargin - $pdf->rightmargin, $this->lineitemBoxHeight);
3263+               
3264+               }//end method
3265+               
3266+               
3267+               function _getLineItems(){
3268+               
3269+                       $querystatement = "
3270+                       SELECT
3271+                               lineitems.*,
3272+                               lineitems.quantity * lineitems.unitprice AS extended,
3273+                               products.partname,
3274+                               products.partnumber
3275+                       FROM
3276+                               lineitems LEFT JOIN products ON lineitems.productid = products.id
3277+                       WHERE
3278+                               lineitems.invoiceid =".((int) $this->invoicerecord["id"])."
3279+                       ORDER BY
3280+                               displayorder";
3281+
3282+                       $queryresult = $this->db->query($querystatement);
3283+                       
3284+                       return $queryresult;
3285+               
3286+               }//end method
3287+
3288+
3289+               function _addNotes(){
3290+               
3291+                       $pdf = &$this->pdf;
3292+               
3293+                       $height = 1;
3294+                       $nextPos = $pdf->GetY() + $height + 0.125;
3295+               
3296+                       $pdf->SetDrawColor(255, 255, 255);
3297+                       $pdf->Rect($pdf->GetX(), $pdf->GetY(), $pdf->paperwidth - $pdf->leftmargin - $pdf->rightmargin, $height);
3298+                       $pdf->setStyle("header");
3299+                       $pdf->Cell($pdf->paperwidth - $pdf->leftmargin - $pdf->rightmargin, 0.18, "Notes/Instructions", 1, 2, "L", 1);
3300+                                               
3301+                       $pdf->setStyle("normal");
3302+                       $pdf->SetXY($pdf->GetX() + .06125, $pdf->GetY() + .06125);
3303+                       $pdf->MultiCell($pdf->paperwidth - $pdf->leftmargin - $pdf->rightmargin - 0.125, 0.18, $this->invoicerecord["printedinstructions"]);
3304+                       
3305+                       $pdf->SetXY($pdf->leftmargin, $nextPos);
3306+               
3307+               }//end method
3308+               
3309+               
3310+               function _addTotals(){
3311+
3312+                       $pdf = &$this->pdf;
3313+               
3314+                       $size = 0;
3315+                       foreach($this->totalsinfo as $column)
3316+                               switch($column->fieldname){
3317+                                       case "shipping":
3318+                                       case "discountamount":
3319+                                               if($this->invoicerecord[$column->fieldname])
3320+                                                       $size += $column->size;
3321+                                               break;
3322+                                       default:
3323+                                               $size += $column->size;
3324+                               }//endswitch
3325+                       $this->totalsinfo[1]->size = $pdf->paperwidth - $pdf->leftmargin - $pdf->rightmargin - $size;                   
3326+                                       
3327+                       $height = .5;
3328+                       $nextPos = $pdf->GetY() + $height + 0.125;
3329+               
3330+                       $pdf->SetDrawColor(255, 255, 255);
3331+                       $pdf->Rect($pdf->GetX(), $pdf->GetY(), $pdf->paperwidth - $pdf->leftmargin - $pdf->rightmargin, $height);
3332+                       
3333+                       $pdf->setStyle("header");
3334+                       foreach($this->totalsinfo as $column)
3335+                               switch($column->fieldname){
3336+                                       case "shipping":
3337+                                       case "discountamount":
3338+                                               if($this->invoicerecord[$column->fieldname])
3339+                                                       $pdf->Cell($column->size, 0.18, $column->title, 1, 0, $column->align, 1);
3340+                                               break;
3341+                                       default:
3342+                                               $pdf->Cell($column->size, 0.18, $column->title, 1, 0, $column->align, 1);
3343+                               }//endswitch
3344+                       
3345+                       $pdf->setStyle("normal");
3346+                       $pdf->SetFont("Arial", "B", 10);
3347+                       $pdf->SetXY($pdf->leftmargin, $pdf->GetY() + 0.18 + 0.0625);
3348+                       
3349+                       foreach($this->totalsinfo as $column){
3350+                       
3351+                               if($column->format != "")
3352+                                       $value = formatVariable($this->invoicerecord[$column->fieldname], $column->format);
3353+                               else
3354+                                       $value = $this->invoicerecord[$column->fieldname];                             
3355+                       
3356+                               switch($column->fieldname){
3357+                                       case "shipping":
3358+                                       case "discountamount":
3359+                                               if($this->invoicerecord[$column->fieldname])
3360+                                                       $pdf->Cell($column->size, 0.18, $value, $pdf->borderDebug, 0, $column->align);
3361+                                               break;
3362+                                       default:
3363+                                               $pdf->Cell($column->size, 0.18, $value, $pdf->borderDebug, 0, $column->align);
3364+                               }//endswitch
3365+                       }//end foreach
3366+                       $this->totalsinfo[1]->size = 0;                 
3367+                       
3368+                       $pdf->SetXY($pdf->leftmargin, $nextPos);                       
3369+
3370+               }//end method
3371+               
3372+               
3373+               function _addPaymentDetails(){
3374+               }//end method
3375+                               
3376+
3377+               function output($destination = "screen" , $userinfo = NULL){
3378+       
3379+                       switch($destination){
3380+                               
3381+                               case "screen":
3382+                                       $this->pdf->Output();
3383+                                       break;
3384+                                       
3385+                               case "email":
3386+                               
3387+                                       if(!$userinfo)
3388+                                               $userinfo = $_SESSION["userinfo"];
3389+                               
3390+                                       if(!$userinfo["email"] || !$this->invoicerecord["email"])
3391+                                               return false;
3392+                               
3393+                                       $pdf = $this->pdf->Output(NULL, "S");
3394+                                       
3395+                                       $to =           $this->invoicerecord["email"];
3396+                                       $from =         $userinfo["email"];
3397+                                       $subject =      "Your ".$this->title." from ".COMPANY_NAME;
3398+                                       $message =      "Attached is your ".$this->title." from ".COMPANY_NAME."\n\n" .
3399+                                                               "The attachment requires Adobe Acrobat Reader to view. \n If you do not " .
3400+                                                               "have Acrobat Reader, you can download it at http://www.adobe.com  \n\n" .
3401+                                                               COMPANY_NAME."\n".
3402+                                                               COMPANY_ADDRESS."\n".COMPANY_CSZ."\n".COMPANY_PHONE;
3403+                                       
3404+                                       $headers = "From: $from";
3405+                                       
3406+                                       $semi_rand = md5( time() );
3407+                                       $mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";
3408+                               
3409+                                       $headers .= "\nMIME-Version: 1.0\n" .
3410+                                                               "Content-Type: multipart/mixed;\n" .
3411+                                                               " boundary=\"{$mime_boundary}\"";
3412+                               
3413+                                       $message = "This is a multi-part message in MIME format.\n\n" .
3414+                                                       "--{$mime_boundary}\n" .
3415+                                                       "Content-Type: text/plain; charset=\"iso-8859-1\"\n" .
3416+                                                       "Content-Transfer-Encoding: 7bit\n\n" .
3417+                                                       $message . "\n\n";
3418+                               
3419+                                       $pdf = chunk_split( base64_encode( $pdf ) );
3420+                                                       
3421+                                       $message .= "--{$mime_boundary}\n" .
3422+                                                        "Content-Type: {application/pdf};\n" .
3423+                                                        " name=\"".$this->title.$this->invoicerecord["id"].".pdf\"\n" .
3424+                                                        "Content-Disposition: attachment;\n" .
3425+                                                        " filename=\"".$this->title.$this->invoicerecord["id"].".pdf\"\n" .
3426+                                                        "Content-Transfer-Encoding: base64\n\n" .
3427+                                                        $pdf . "\n\n" .
3428+                                                        "--{$mime_boundary}--\n";
3429+                                       
3430+                                       return @ mail($to, $subject, $message, $headers);
3431+                                       
3432+                                       break;
3433+                               
3434+                       }//endswitch
3435+               
3436+               }//end method           
3437+       
3438+       }//end class
3439+       
3440+
3441+
3442+?>
3443Index: modules/bms/report/invoices_pdfinvoice2.php
3444===================================================================
3445--- modules/bms/report/invoices_pdfinvoice2.php (revision 0)
3446+++ modules/bms/report/invoices_pdfinvoice2.php (revision 0)
3447@@ -0,0 +1,22 @@
3448+<?php
3449+//PROCESSING
3450+//=============================================================================
3451+if(!isset($noOutput)){
3452+
3453+       //IE needs caching to be set to private in order to display PDFS
3454+       session_cache_limiter('private');
3455+
3456+       //set encoding to latin1 (fpdf doesnt like utf8)
3457+       $sqlEncoding = "latin1";       
3458+       require_once("../../../include/session.php");
3459+       
3460+       include("modules/bms/report/invoices_pdf_class2.php");
3461+       
3462+       $report = new invoicePDF($db, 'P', 'in', 'Letter');
3463+       $report->setupFromPrintScreen();
3464+       $report->generate();
3465+       $report->output();
3466+       
3467+}//end if
3468+
3469+?>
3470Index: report/pdfreport_class2.php
3471===================================================================
3472--- report/pdfreport_class2.php (revision 0)
3473+++ report/pdfreport_class2.php (revision 0)
3474@@ -0,0 +1,222 @@
3475+<?php
3476+/*
3477+ $Rev: 290 $ | $LastChangedBy: brieb $
3478+ $LastChangedDate: 2007-08-27 18:15:00 -0600 (Mon, 27 Aug 2007) $
3479+ +-------------------------------------------------------------------------+
3480+ | Copyright (c) 2004 - 2007, Kreotek LLC                                  |
3481+ | All rights reserved.                                                    |
3482+ +-------------------------------------------------------------------------+
3483+ |                                                                         |
3484+ | Redistribution and use in source and binary forms, with or without      |
3485+ | modification, are permitted provided that the following conditions are  |
3486+ | met:                                                                    |
3487+ |                                                                         |
3488+ | - Redistributions of source code must retain the above copyright        |
3489+ |   notice, this list of conditions and the following disclaimer.         |
3490+ |                                                                         |
3491+ | - Redistributions in binary form must reproduce the above copyright     |
3492+ |   notice, this list of conditions and the following disclaimer in the   |
3493+ |   documentation and/or other materials provided with the distribution.  |
3494+ |                                                                         |
3495+ | - Neither the name of Kreotek LLC nor the names of its contributore may |
3496+ |   be used to endorse or promote products derived from this software     |
3497+ |   without specific prior written permission.                            |
3498+ |                                                                         |
3499+ | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS     |
3500+ | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT       |
3501+ | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A |
3502+ | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT      |
3503+ | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,   |
3504+ | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT        |
3505+ | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,   |
3506+ | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY   |
3507+ | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT     |
3508+ | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE   |
3509+ | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.    |
3510+ |                                                                         |
3511+ +-------------------------------------------------------------------------+
3512+*/
3513+       class pdfColumn{
3514+               
3515+               var $title;
3516+               var $fieldname;
3517+               var $size = 1;
3518+               var $format;
3519+               var $align = "L";
3520+               
3521+       
3522+               function pdfColumn($title, $fieldname, $size = 1, $format = "", $align = "L"){
3523+               
3524+                       $this->title = $title;
3525+                       $this->fieldname = $fieldname;
3526+                       $this->size = ((real) $size);
3527+                       $this->format = $format;
3528+                       $this->align = $align;
3529+               
3530+               }//end method
3531+       
3532+       }//end class
3533+
3534+       class pdfColor{
3535+               
3536+               var $r = 0;
3537+               var $g = 0;
3538+               var $b = 0;
3539+
3540+               function pdfColor($r = 0,$g = 0,$b = 0){
3541+               
3542+                       $this->r = $r;
3543+                       $this->g = $g;
3544+                       $this->b = $b;
3545+               
3546+               }//end method
3547+                               
3548+       }//end class
3549+
3550+       
3551+       class pdfFont {
3552+       
3553+               var $family = "Arial";
3554+               var $style = "";
3555+               var $size = 8;
3556+               
3557+               function pdfFont($family = "Arial", $style ="", $size = 8){
3558+                       
3559+                       $this->family = $family;
3560+                       $this->style = $style;
3561+                       $this->size = $size;                   
3562+               
3563+               }//end method
3564+       
3565+       }//end class
3566+       
3567+       
3568+       class pdfStyle{
3569+       
3570+               var $font = NULL;
3571+               var $textColor = NULL;
3572+               var $backgroundColor = NULL;
3573+               
3574+               function pdfStyle($font = NULL, $textColor = NULL, $backgroundColor = NULL){
3575+                       
3576+                       if($font) $this->font = $font;
3577+                       if($textColor) $this->textColor = $textColor;
3578+                       if($backgroundColor) $this->backgroundColor = $backgroundColor;
3579+               
3580+               }//end method
3581+               
3582+       }//end class
3583+       
3584+
3585+       if(!class_exists("FPDI")){
3586+       
3587+               include("fpdf/fpdf.php");
3588+               /*include("fpdf/mem_image.php");*/
3589+               include("fpdf/fpdi.php");
3590+               include("fpdf/wrapper.php");
3591+               
3592+       }//end if
3593+
3594+       class phpbmsPDFReport extends FPDI {
3595+       
3596+               var $borderDebug = 0;
3597+       
3598+               var $leftmargin = 0.5;
3599+               var $rightmargin = 0.5;
3600+               var $topmargin = 0.75;
3601+               var $paperwidth = 8.5;
3602+               var $paperlength = 11;
3603+               
3604+               var $hasComapnyHeader = false;
3605+               var $companyImageWidth = 1;
3606+               
3607+               var $styles = array();
3608+               
3609+       
3610+               function phpbmsPDFReport($db, $orientation='P', $unit='mm', $format='Letter'){
3611+               
3612+                       $this->db = $db;
3613+                       
3614+                       parent::FPDI($orientation, $unit, $format);
3615+                       
3616+                       $this->initStyles();
3617+                       $this->SetLineWidth(0.00);
3618+                       
3619+               }//end method
3620+               
3621+               
3622+               function initStyles(){
3623+                       
3624+                       //here we set the standard styles
3625+
3626+                       // NORMAL                       
3627+                       $font = new pdfFont("Arial", "", 8);
3628+                       $style = new pdfStyle($font);
3629+
3630+                       $this->styles["normal"] = $style;
3631+
3632+
3633+                       // TITLES
3634+                       $font = new pdfFont("Arial", "B", 16);
3635+                       $style = new pdfStyle($font);
3636+
3637+                       $this->styles["title"] = $style;
3638+
3639+
3640+                       // HEADER
3641+                       $font = new pdfFont("Arial", "B", 8);
3642+                       $bgC = new pdfColor(0,0,0);
3643+                       $txtC = new pdfColor(255,255,255);
3644+                       $style = new pdfStyle($font, $txtC, $bgC);
3645+
3646+                       $this->styles["header"] = $style;
3647+               
3648+               }//end method
3649+
3650+
3651+               function defineStyle($name, $pdfStyleObj){
3652+               
3653+                       if(get_class($pdfStyleObj) != "pdfStyle")
3654+                               $error = new appError(1400,"defineStyle Method needs pdfStyle obeject as paramater 2","PDF Error",true,true,false);
3655+                       
3656+                       $this->styles[$name] = $pdfStyleObj;
3657+               
3658+               }//end if
3659+
3660+
3661+               function setStyle($name){
3662+               
3663+                       if(!isset($this->styles[$name]))
3664+                               $name = "normal";
3665+                               
3666+                       $newStyle = $this->styles[$name];
3667+
3668+                       if(isset($newStyle->font))
3669+                               $this->SetFont($newStyle->font->family, $newStyle->font->style, $newStyle->font->size);
3670+                       else
3671+                               $this->SetFont("Arial", "", 8);
3672+                               
3673+                       if(isset($newStyle->textColor))
3674+                               $this->SetTextColor($newStyle->textColor->r, $newStyle->textColor->g, $newStyle->textColor->b);
3675+                       else
3676+                               $this->SetTextColor(0,0,0);
3677+               
3678+                       if(isset($newStyle->backgroundColor))
3679+                               $this->SetFillColor($newStyle->backgroundColor->r, $newStyle->backgroundColor->g, $newStyle->backgroundColor->b);
3680+                       else
3681+                               $this->SetFillColor(255,255,255);
3682+               
3683+               }//end if
3684+
3685+
3686+               function SetMargins(){
3687+                                               
3688+                       parent::SetMargins($this->leftmargin, $this->topmargin, $this->rightmargin);
3689+                       
3690+               }//end method   
3691+               
3692+                       
3693+               
3694+       }//end class
3695+       
3696+?>
phpBMS vulnerability assesment provided by Orvant Inc. Copyright © 2010 Kreotek, LLC. All Rights reserved.