From: Martín Marrese Date: Tue, 28 Oct 2003 22:33:40 +0000 (+0000) Subject: MECON_PDF en proceso de desarrollo X-Git-Tag: svn_import~208 X-Git-Url: https://git.llucax.com/mecon/meconlib.git/commitdiff_plain/53dea79e14a592c07d0211cb7a7d93949c231fe1?hp=5fc4d2c060a308c91604bfec802ef67cbcd862e3 MECON_PDF en proceso de desarrollo --- diff --git a/lib/MECON/PDF.php b/lib/MECON/PDF.php new file mode 100644 index 0000000..08250ec --- /dev/null +++ b/lib/MECON/PDF.php @@ -0,0 +1,260 @@ + +------------------------------------------------------------------------------- +$Id$ +-----------------------------------------------------------------------------*/ + +require_once 'MECON/PDF/external/phppdflib.class.php'; + +/** + * Liberia base para el manejo de pdf's. + */ +class MECON_PDF { + + /** + * Libreria externa. + * @var int $pdf + * @access private + */ + var $_pdf; + + /** + * Identificacion de la pagina actual + * @var int $pagina_actual + * @access private + */ + var $_pagina_actual; + + /** + * Array de paginas. + * @var array $paginas + * @access private + */ + var $_paginas; + + /** + * Class constructor. + * + * @return void + * @access public + */ + function MECON_PDF() + { + $this->_pdf = new pdffile; + } + + /** + * Permite agregar nuevas paginas al pdf que se esta armando. + * + * @param string $pagina Tipo de pagina que se va a utilizar. + * + * @return void + * @access public + */ + function newPage($pagina = "a4") + { + $this->_pagina_actual = $this->_pdf->new_page($pagina); + $this->_paginas[] = $this->_pagina_actual; + } + + /** + * Funcion que genera el archivo y prepara los headers para que se envie. + * + * @return void + * @access public + */ + function display() + { + header("Content-Disposition: filename=Doc.pdf"); + header("Content-Type: application/pdf"); + $temp = $this->toPDF(); + header('Content-Length: ' . strlen($temp)); + echo $temp; + } + + /** + * Funcion que devuelve el PDF. + * + * @return string + * @access public + */ + function toPDF() { + return $this->_pdf->generate(); + } + + /** + * Funcion que permite agregar texto a una pagina. + * + * @param int $X $X + * @param int $Y $Y + * @param string $texto $texto + * @param int $estilo $estilo + * @param int $pag Numero de pagina virtual. + * + * @return void + * @access public + */ + function addText($X, $Y, $texto, $estilo = '', $pag = null) + { + $this->_pdf->draw_text($X, $Y, $texto, $this->refPage($pag), $estilo); + } + + /** + * Funcion que permite agregar un rectangulo a una pagina. + * + * @param int $Xi $Xi + * @param int $Yi $Yi + * @param int $Xf $Xf + * @param int $Yf $Yf + * @param long $estilo $estilo + * @param int $pag Numero de pagina virtual. + * + * @return void + * @access public + */ + function addRectangle($Xi, $Yi, $Xf, $Yf, $estilo = '', $pag = null) + { + $this->_pdf->draw_rectangle($Xi, $Yi, $Xf, $Yf, $this->refPage($pag), $estilo); + } + + /** + * Funcion que permite agregar una linea a una pagina. + * + * @param int $Xi $Xi + * @param int $Yi $Yi + * @param int $Xf $Xf + * @param int $Yf $Yf + * @param int $estilo $estilo + * @param int $pag Numero de pagina virtual. + * + * @return void + * @access public + */ + function addLine($Xi, $Yi, $Xf, $Yf, $estilo = '', $pag = null) + { + $this->_pdf->draw_line(array($Xi,$Xf),array($Yi,$Yf), + $this->refPage($pag),$estilo); + } + + /** + * Funcion que permite agregar una imagen JPG a una pagina. + * + * @param string $archivo Path completo del archivo imagen. + * @param int $X Posicion Horizontal. + * @param int $Y Posixion vertical. + * @param int $pag Numero de pagina virtual. + * @param string $formato Formato del archivo (Extension). + * + * @return void + * @access public + */ + function addImage($archivo, $X, $Y, $pag = null, $formato = null) { + $formato = strtolower($formato); + switch ($formato) { + case 'jpg': + $fh = fopen($archivo, "r"); + $filedata = fread($fh, filesize($archivo)); + fclose($fh); + $image = $this->_pdf->jfif_embed($filedata); + $this->_pdf->image_place($image, $Y, $X, + $this->refPage($pag)); + break; + } + } + + /** + * Funcion que wrappea una linea. + * + * @param strgin $texto Texto que quiere wrappearse. + * @param int $l_max Largo maximo del texto. + * @param array $attr Atributos del texto. + * + * @return string + * @access public + */ + function wrapLine($texto, $l_max, $attr) { + return $this->_pdf->wrap_line ($texto, $l_max, $attr); + } + + /** + * Funcion que calcula cuanto va a ocupar cierto texto segun su formato en + * una pagina. + * + * @param strgin $texto Texto que quiere medirse. + * @param array $attr Atributos del texto. + * + * @return int + * @access public + */ + function strlen($texto, $attr = '') { + return $this->_pdf->strlen($texto, $attr); + } + + /** + * Funcion que devuelve la cantidad de paginas que contiene el documento. + * + * @return int + * @access public + */ + function countPages() { + return count($this->_paginas); + } + + /** + * Funcion que devuelve el numero de la pagina actual. + * + * @param mixed $id Identificador de la pagina. + * + * @return int + * @access public + */ + function numPage($id = null) { + $id = ($id) ? $id : $this->_pagina_actual; + return (array_search($id, $this->_paginas)) + 1; + } + + /** + * Funcion que devuelve la referencia de una pagina vitual. Si no se pasa + * nada utilizo la actual. + * + * @param int $pag Numero de pagina. + * + * @return int + * @access public + */ + function refPage($pag = null) { + return $pag ? $this->_paginas[$pag - 1] : + $this->_pagina_actual; + } + + /** + * Funcion que devuelve el array de paginas + * + * @return array + * @access public + */ + function getPages() { + return $this->_paginas; + } +} +?> \ No newline at end of file diff --git a/lib/MECON/PDF/Marco.php b/lib/MECON/PDF/Marco.php new file mode 100644 index 0000000..8d70976 --- /dev/null +++ b/lib/MECON/PDF/Marco.php @@ -0,0 +1,314 @@ + +------------------------------------------------------------------------------- +$Id$ +-----------------------------------------------------------------------------*/ + +require_once 'MECON/PDF.php'; +require_once 'MECON/HTML/Tabla.php'; + +/** + * Libreria que crea un marco estandar para los pdfs. + */ +class MECON_PDF_Marco extends MECON_HTML_Tabla { + + /** + * Objeto MECON_PDF + * @var Object MECON_PDF + * @access protected + */ + var $_pdf; + + /** + * Archivo de configuracion de medidas + * @var array $conf + * @access protected + */ + var $_conf = array (); + + /** + * Tamanio de las paginas. + * @var string $tamanio + * @access protected + */ + var $_tamanio = "a4"; + + /** + * Orientacion (portrait o landscape). + * @var sting $orientacion + * @access protected + */ + var $_orientacion = "portrait"; + + /** + * Logo. + * @var string $logo + * @access public + */ + var $logo = '/home/mmarrese/public_html/meconlib/www/images/pdf_logo.jpg'; + //@FIXME Ponener el path del logo por defecto + + /** + * Paginador. + * @var bool $paginador + * @access public + */ + var $paginador = true; + + /** + * Fecha. Si es true se pone la fecha del servidor, si es false no se pone + * nada, en caso contrario se pone lo que haya en esta variable. + * @var mixed $fecha + * @access public + */ + var $fecha = true; + + /** + * Seccion. + * @var string $seccion + * @access public + */ + var $seccion = ''; + + /** + * SubSeccion. + * @var string $subseccion + * @access public + */ + var $subseccion = 'Ministerio de Economia'; + + /** + * Titulo. + * @var string $string + * @access public + */ + var $titulo = true; + + /** + * SubTitulo. + * @var string $subtitulo + * @access public + */ + var $subtitulo = true; + + /** + * Class constructor. + * + * @param string $tam Tamanio de las hojas. + * @param string $ori Orientacion de las hojaz (portrait o landscape). + * + * @return void + * @access public + */ + function MECON_PDF_Marco($tam = "a4", $ori = "portrait") { + $this->_pdf =& new MECON_PDF; + $this->_tamanio = $tam; + $this->_orientacion = $ori; + $this->_conf = include 'MECON/PDF/Marco/medidas.php' ; + $this->_conf = $this->_conf[$tam][$ori]; + } + + /** + * Funcion que agrega el logo al encabezado de una pagina. + * + * @return void + * @access protected + */ + function _addLogo() { + $conf = $this->_conf['encabezado']; + if ($this->logo) { + $this->_pdf->addImage($this->logo, $conf['logo']['X'], + $conf['logo']['Y'], null, 'jpg'); + } + } + + /** + * Funcion que agrega la seccion al encabezado de una pagina. + * + * @return void + * @access protected + */ + function _addSeccion() { + $conf = $this->_conf['encabezado']; + if ($this->seccion) { + $tmp = $this->_pdf->strlen($this->seccion, $conf['seccion']); + $tmp2 = $conf['linea2']['Xi'] - $conf['linea1']['Xi']; + if ($tmp >= $tmp2) { + $this->seccion = $this->_pdf->wrapLine ($this->seccion, $tmp2, + $conf['seccion']); + $tmp = $this->_pdf->strlen($this->seccion, $conf['seccion']); + } + $init = $conf['linea1']['Xi'] + ( $conf['linea2']['Xi'] + - $conf['linea1']['Xi'] - $tmp) / 2; + $this->_pdf->addText($init, $conf['seccion']['Y'], $this->seccion, $conf['seccion']); + } + } + + /** + * Funcion que agrega la subseccion al encabezado de una pagina. + * + * @return void + * @access protected + */ + function _addSubSeccion() { + $conf = $this->_conf['encabezado']; + if ($this->subseccion) { + $tmp = $this->_pdf->strlen($this->subseccion, $conf['subseccion']); + $tmp2 = $conf['linea2']['Xi'] - $conf['linea1']['Xi']; + if ($tmp >= $tmp2) { + $this->subseccion = $this->_pdf->wrapLine ($this->subseccion, $tmp2, + $conf['subseccion']); + $tmp = $this->_pdf->strlen($this->subseccion, $conf['subseccion']); + } + $init = $conf['linea1']['Xi'] + ( $conf['linea2']['Xi'] + - $conf['linea1']['Xi'] - $tmp) / 2; + $this->_pdf->addText($init, $conf['subseccion']['Y'], $this->subseccion, + $conf['subseccion']); + } + } + + /** + * Funcion que agrega el paginador al encabezado de una pagina. + * + * @return void + * @access protected + */ + function _addPager() { + $conf = $this->_conf['encabezado']; + if ($this->paginador) { + $txt = 'Pagina '.$this->_pdf->numPage().' de '. + $this->_pdf->countPages(); + $tmp = $this->_pdf->strlen($txt, $conf['paginador']); + $init = $conf['linea2']['Xi'] + ( $conf['Xf'] + - $conf['linea2']['Xi'] - $tmp) / 2; + $this->_pdf->addText($init, $conf['paginador']['Y'], $txt, + $conf['paginador']); + } + } + + /** + * Funcion que permite agregar la fecha al encabezado de una pagina. + * + * @return void + * @access protected + */ + function _addDate() { + $conf = $this->_conf['encabezado']; + if ($this->fecha) { + if ($this->fecha === true) { + $this->fecha = date("d/m/Y"); + } + $tmp = $this->_pdf->strlen($this->fecha, $conf['fecha']); + $init = $conf['linea2']['Xi'] + ( $conf['Xf'] + - $conf['linea2']['Xi'] - $tmp) / 2; + $this->_pdf->addText($init, $conf['fecha']['Y'], $this->fecha, + $conf['fecha']); + } + } + + /** + * Funcion que arma el recuadro del encabezado de las paginas. + * + * @return void + * @access protected + */ + function _addHeaderRectangle() { + $conf = $this->_conf['encabezado']; + //Armo el recuadro + $this->_pdf->addRectangle ($conf['Yi'], $conf['Xi'], $conf['Yf'], + $conf['Xf']); + $this->_pdf->addLine($conf['linea1']['Xi'], $conf['linea1']['Yi'], + $conf['linea1']['Xf'], $conf['linea1']['Yf']); + $this->_pdf->addLine($conf['linea2']['Xi'], $conf['linea2']['Yi'], + $conf['linea2']['Xf'], $conf['linea2']['Yf']); + } + + /** + * Funcion que permite agregar el titulo a una pagina. + * + * @return void + * @access protected + */ + function _addTitle() { + $conf = $this->_conf['titulo']; + if ($this->titulo) { + $tmp = $this->_pdf->strlen($this->titulo, $conf); + $tmp2 = $this->_conf['Xf'] + abs($this->_conf['Xi']); + if ($tmp >= $tmp2) { + $this->titulo = $this->_pdf->wrapLine ($this->titulo, $tmp2, + $conf); + $tmp = $this->_pdf->strlen($this->titulo, $conf); + } + $init = $this->_conf['Xi'] + ($tmp2 - $tmp) / 2; + $this->_pdf->addText($init, $conf['Y'], $this->titulo, + $conf); + } + } + + /** + * Funcion que permite agregar el subtitulo a una pagina. + * + * @return void + * @access protected + */ + function _addSubTitle() { + $conf = $this->_conf['subtitulo']; + if ($this->subtitulo) { + $tmp = $this->_pdf->strlen($this->subtitulo, $conf); + $tmp2 = $this->_conf['Xf'] + abs($this->_conf['Xi']); + if ($tmp >= $tmp2) { + $this->subtitulo = $this->_pdf->wrapLine ($this->subtitulo, $tmp2, + $conf); + $tmp = $this->_pdf->strlen($this->subtitulo, $conf); + } + $init = $this->_conf['Xi'] + ($tmp2 - $tmp) / 2; + $this->_pdf->addText($init, $conf['Y'], $this->subtitulo, + $conf); + } + } + + /** + * Funcion que agrega la informacion del marco a la pagina actual. + * + * @param bool $title Muetra o no el titulo. + * @param bool $subtitle Muestra o no el subtitulo. + * + * @return void + * @access public + */ + function buildPage($title = true, $subtitle = true) { + $this->_addLogo(); + $this->_addSeccion(); + $this->_addSubseccion(); + $this->_addPager(); + $this->_addDate(); + $this->_addHeaderRectangle(); + if ($title) { + $this->_addTitle(); + } + if ($subtitle) { + $this->_addSubTitle(); + } + } +} +?> \ No newline at end of file diff --git a/lib/MECON/PDF/Marco/medidas.php b/lib/MECON/PDF/Marco/medidas.php new file mode 100644 index 0000000..1dbb57c --- /dev/null +++ b/lib/MECON/PDF/Marco/medidas.php @@ -0,0 +1,112 @@ + +------------------------------------------------------------------------------- +$Id$ +-----------------------------------------------------------------------------*/ + +/** + * Medidas para cada formato de pagina. + */ + +return array ( + // A4 {{{ + 'a4' => array ( + //Portrait {{{ + 'portrait' => array ( + 'Xi' => -40, //Esquina inferior izquierda + 'Xf' => 490, //Esquina inferior derecha + 'Yi' => -110, //Esquina inferior izquierda + 'Yf' => 700, //Esquina superior izquierda + //Encabezado {{{ + 'encabezado' => array ( //Encabezado de cada pagina + 'Xi' => -40, + 'Xf' => 490, + 'Yi' => 657, + 'Yf' => 700, + 'logo' => array ( + 'X' => -33, + 'Y' => 665, + ), + 'linea1' => array ( + 'Xi' => 110, + 'Xf' => 110, + 'Yi' => 657, + 'Yf' => 700, + ), + 'linea2' => array ( + 'Xi' => 404, + 'Xf' => 404, + 'Yi' => 657, + 'Yf' => 700, + ), + 'linea3' => array ( + 'Xi' => -40, + 'Xf' => 110, + 'Yi' => 657, + 'Yf' => 666, + ), + 'seccion' => array ( + 'Y' => 685, + 'font' => 'Helvetica-Bold', + 'height' => 12, + ), + 'subseccion' => array ( + 'Y' => 664, + 'font' => 'Helvetica', + 'height' => 12, + ), + 'paginador' => array ( + 'Y' => 685, + 'font' => 'Helvetica', + 'height' => 9, + ), + 'fecha' => array ( + 'Y' => 664, + 'font' => 'Helvetica', + 'height' => 9, + ), + ), + //}}} + //Titulos {{{ + 'titulo' => array ( + 'Y' => 630, + 'font' => 'Helvetica-Bold', + 'height' => 16, + ), + 'subtitulo' => array ( + 'Y' => 615, + 'font' => 'Helvetica', + 'height' => 13 + ), + //}}} + ), + //}}} + //LandScape {{{ + 'landscape' => array ( + ), + //}}} + ), + //}}} + ); + +?> diff --git a/lib/MECON/PDF/Tabla.php b/lib/MECON/PDF/Tabla.php new file mode 100644 index 0000000..cd1d7d4 --- /dev/null +++ b/lib/MECON/PDF/Tabla.php @@ -0,0 +1,48 @@ + +------------------------------------------------------------------------------- +$Id$ +-----------------------------------------------------------------------------*/ + +require_once 'MECON/PDF/Marco.php'; + +/** + * Libreria que permite agregar una tabla a un pdf. + */ +class MECON_PDF_Tabla extends MECON_PDF_Marco { + + /** + * Funcion que envia el archivo a pantalla (para que el usuario haga un + * download) + * + * @return string + * @access public + */ + function display() { + $this->_pdf->newPage($this->_tamanio); + $this->buildPage(); + $this->_pdf->display(); + } + +} +?> \ No newline at end of file diff --git a/lib/MECON/PDF/external/chart.class.php b/lib/MECON/PDF/external/chart.class.php new file mode 100755 index 0000000..f867bf5 --- /dev/null +++ b/lib/MECON/PDF/external/chart.class.php @@ -0,0 +1,130 @@ +clearchart(); + } + + function clearchart() + { + // Default colors + unset($this->colors); + // This oughta make things more readible + $white['red'] = $white['green'] = $white['blue'] = 1; + $black['red'] = $black['green'] = $black['blue'] = 0; + $this->colors['background'] = $white; + $this->colors['border'] = $black; + $this->colors['hlabel'] = $black; + $this->colors['vlabel'] = $black; + $this->colors['vgrade'] = $black; + $this->colors['hgrade'] = $black; + unset($this->series); + } + + /* Set up default colors to use globally on the chart + */ + function setcolor($name, $red, $green, $blue) + { + $this->colors[$name]['red'] = $red; + $this->colors[$name]['green'] = $green; + $this->colors[$name]['blue'] = $blue; + } + + function add_series($name, $points, $color = 'black', $width = 1, $style = 'default') + { + $t['points'] = $points; + $t['color'] = $color; + $t['width'] = $width; + $t['style'] = $style; + $this->series[$name] = $t; + } + + function place_chart($page, $left, $bottom, $width, $height, $type = 'line') + { + switch (strtolower($type)) { + case 'pie' : + case '3dpie' : + case 'bar' : + case '3dbar' : + case '3dline' : + case 'line' : + default : + $this->_place_line_chart($page, $left, $bottom, $width, $height); + } + } + + function _place_line_chart($page, $left, $bottom, $width, $height) + { + // First a filled rectangle to set background color + $this->_fill_background($page, $left, $bottom, $width, $height); + // caclulate a scale + $low = $high = $numx = 0; + foreach($this->series as $data) { + foreach($data['points'] as $value) { + if ($value < $low) $low = $value; + if ($value > $high) $high = $value; + } + if (count($data['points']) > $numx) $numx = count($data); + } + if (($high - $low) <= 0) return false; + $xscale = $width / $numx; + $yscale = $height / ($high - $low); + foreach($this->series as $data) { + $a['strokecolor'] = $this->pdf->get_color($data['color']); + $a['width'] = $data['width']; + $c = 0; + unset($x); + unset($y); + foreach ($data['points'] as $value) { + $x[$c] = ($c * $xscale) + $left; + //echo $x[$c] . " "; + $y[$c] = (($value - $low) * $yscale) + $bottom; + //echo $y[$c] . "
\n"; + $c++; + } + $this->pdf->draw_line($x, $y, $page, $a); + } + } + + function _fill_background($page, $left, $bottom, $width, $height) + { + $a['fillcolor'] = $this->colors['background']; + $a['mode'] = 'fill'; + $this->pdf->draw_rectangle($bottom + $height, + $left, + $bottom, + $left + $width, + $page, + $a); + } +} + +?> diff --git a/lib/MECON/PDF/external/phppdflib.class.php b/lib/MECON/PDF/external/phppdflib.class.php new file mode 100755 index 0000000..3b4f360 --- /dev/null +++ b/lib/MECON/PDF/external/phppdflib.class.php @@ -0,0 +1,1517 @@ +generate() + * is called. + * The layout of ->objects does not directly + * mimic the pdf format, although it is similar. + * nextoid always holds the next available oid ( oid is short for object id ) + */ + var $objects, $nextoid; + + /* xreftable is an array containing data to + * create the xref section (PDF calls it a referance table) + */ + var $xreftable, $nextobj; + + /* These arrays allow quick translation between + * pdflib OIDs and the final PDF OIDs (OID stands for object ids) + */ + var $libtopdf, $pdftolib; + + // Errors + var $ermsg = array(), $erno = array(); + + var $builddata; // Various data required during the pdf build + var $nextpage; // Tracks the next page number + var $widths, $needsset; // Store the font width arrays here + var $default; // Default values for objects + var $x, $chart, $template; // extension class is instantiated here if requested + /* Constructor function: is automatically called when the + * object is created. Used to set up the environment + */ + function pdffile() + { + /* Per spec, obj 0 should always have a generation + * number of 65535 and is always free + */ + $this->xreftable[0]["gennum"] = 65535; + $this->xreftable[0]["offset"] = 0; + $this->xreftable[0]["free"] = "f"; + + // Object #1 will always be the Document Catalog + $this->xreftable[1]["gennum"] = 0; + $this->xreftable[1]["free"] = "n"; + + // Object #2 will always be the root pagenode + $this->xreftable[2]["gennum"] = 0; + $this->xreftable[2]["free"] = "n"; + $this->pdftolib[2] = 1; + $this->libtopdf[1] = 2; + + // Object #3 is always the resource library + $this->xreftable[3]["gennum"] = 0; + $this->xreftable[3]["free"] = "n"; + + /* nextoid starts at 2 because all + * drawing functions return either the + * object ID or FALSE on error, so we can't + * return an OID of 0, because it equates + * to false and error checking would think + * the procedure failed + */ + $this->nextoid = 2; + $this->nextobj = 3; + + // Pages start at 0 + $this->nextpage = 0; + + // Font width tables are not set unless they are needed + $this->needsset = true; + + // Set all the default values + $t['pagesize'] = 'letter'; + $t['font'] = 'Helvetica'; + $t['height'] = 12; + $t['align'] = 'left'; + $t['width'] = 1; + $t['rotation'] = 0; + $t['scale'] = 1; + $t['strokecolor'] = $this->get_color('black'); + $t['fillcolor'] = $this->get_color('black'); + $t['margin-left'] = $t['margin-right'] = $t['margin-top'] = $t['margin-bottom'] =72; + $t['tmode'] = 0; // Text: fill + $t['smode'] = 1; // Shapes: stroke + $this->default = $t; + } + +/****************************************************** + * These functions are the public ones, they are the * + * way that the user will actually enter the data * + * that will become the pdf * + ******************************************************/ + + function set_default($setting, $value) + { + switch ($setting) { + case 'margin' : + $this->default['margin-left'] = $value; + $this->default['margin-right'] = $value; + $this->default['margin-top'] = $value; + $this->default['margin-bottom'] = $value; + break; + + case 'mode' : + $this->default['tmode'] = $this->default['smode'] = $value; + break; + + default : + $this->default[$setting] = $value; + } + return true; + } + + function draw_rectangle($top, $left, $bottom, $right, $parent, $attrib = array()) + { + if ($this->objects[$parent]["type"] != "page") { + $this->_push_std_error(6001); + return false; + } + $o = $this->_addnewoid(); + $attrib = $this->_resolve_param($attrib, false); + $this->_resolve_colors($n, $attrib); + $this->objects[$o] = $n; + $this->objects[$o]["width"] = $attrib["width"]; + $this->objects[$o]["type"] = "rectangle"; + $this->_adjust_margin($left, $top, $parent); + $this->_adjust_margin($right, $bottom, $parent); + $this->objects[$o]["top"] = $top; + $this->objects[$o]["left"] = $left; + $this->objects[$o]["bottom"] = $bottom; + $this->objects[$o]["right"] = $right; + $this->objects[$o]["parent"] = $parent; + $this->objects[$o]["mode"] = $this->_resolve_mode($attrib, 'smode'); + return $o; + } + + function draw_circle($x, $y, $r, $parent, $attrib = array()) + { + if ($this->objects[$parent]["type"] != "page") { + $this->_push_std_error(6001); + return false; + } + $o = $this->_addnewoid(); + $attrib = $this->_resolve_param($attrib, false); + $this->_resolve_colors($n, $attrib); + $n['width'] = $attrib['width']; + $this->_adjust_margin($x, $y, $parent); + $n['x'] = $x; + $n['y'] = $y; + $n['radius'] = $r; + $n['type'] = 'circle'; + $n['parent'] = $parent; + $n['mode'] = $this->_resolve_mode($attrib, 'smode'); + $this->objects[$o] = $n; + return $o; + } + + function draw_line($x, $y, $parent, $attrib = array()) + { + if ($this->objects[$parent]["type"] != "page") { + $this->_push_std_error(6001); + return false; + } + if (count($x) != count($y)) { + $this->_push_error(6002, "X & Y variables must have equal number of elements"); + return false; + } + $o = $this->_addnewoid(); + $attrib = $this->_resolve_param($attrib, false); + $this->_resolve_colors($n, $attrib); + $this->objects[$o] = $n; + @$this->objects[$o]["width"] = $attrib["width"]; + $this->objects[$o]['mode'] = $this->_resolve_mode($attrib, 'smode'); + $this->objects[$o]["type"] = "line"; + foreach ($x as $key => $value) { + if (isset($x[$key]) && isset($y[$key])) { + $this->_adjust_margin($x[$key], $y[$key], $parent); + } + } + $this->objects[$o]["x"] = $x; + $this->objects[$o]["y"] = $y; + $this->objects[$o]["parent"] = $parent; + return $o; + } + + // draw text + function draw_text($left, $bottom, $text, $parent, $attrib = array()) + { + if ($this->objects[$parent]["type"] != "page") { + $this->_push_std_error(6001); + return false; + } + $attrib = $this->_resolve_param($attrib); + // Validate the font + if (!($n["font"] = $this->_use_font($attrib))) { + // Couldn't find/add the font + $this->_push_error(6003, "Font was not found"); + return false; + } + if (isset($attrib["rotation"])) { + $n["rotation"] = $attrib["rotation"]; + } + $n['mode'] = $this->_resolve_mode($attrib, 'tmode'); + if (isset($attrib["height"]) && $attrib["height"] > 0) { + $n["height"] = $attrib["height"]; + } + $this->_resolve_colors($n, $attrib); + $n["type"] = "texts"; + $this->_adjust_margin($left, $bottom, $parent); + $n["left"] = $left; + $n["bottom"] = $bottom; + $n["text"] = $text; + $n["parent"] = $parent; + + $o = $this->_addnewoid(); + $this->objects[$o] = $n; + return $o; + } + + function new_page($size = null) + { + if (is_null($size)) { + $size = $this->default['pagesize']; + } + switch ($size) { + case "letter" : + $o = $this->_addnewoid(); + $this->objects[$o]["height"] = 792; + $this->objects[$o]["width"] = 612; + break; + + case "legal" : + $o = $this->_addnewoid(); + $this->objects[$o]["height"] = 1008; + $this->objects[$o]["width"] = 612; + break; + + case "executive" : + $o = $this->_addnewoid(); + $this->objects[$o]["height"] = 720; + $this->objects[$o]["width"] = 540; + break; + + case "tabloid" : + $o = $this->_addnewoid(); + $this->objects[$o]["height"] = 1224; + $this->objects[$o]["width"] = 792; + break; + + case "a3" : + $o = $this->_addnewoid(); + $this->objects[$o]["height"] = 1188; + $this->objects[$o]["width"] = 842; + break; + + case "a4" : + $o = $this->_addnewoid(); + $this->objects[$o]["height"] = 842; + $this->objects[$o]["width"] = 595; + break; + + case "a5" : + $o = $this->_addnewoid(); + $this->objects[$o]["height"] = 598; + $this->objects[$o]["width"] = 418; + break; + + default : + if (preg_match("/in/",$size)) { + $o = $this->_addnewoid(); + $size = substr($size, 0, strlen($size) - 2); + $dims = split("x",$size); + $this->objects[$o]["height"] = ($dims[1] * 72); + $this->objects[$o]["width"] = ($dims[0] * 72); + } else { + if (preg_match("/cm/",$size)) { + $o = $this->_addnewoid(); + $size = substr($size, 0, strlen($size) - 2); + $dims = split("x",$size); + $this->objects[$o]["height"] = ($dims[1] * 28.346); + $this->objects[$o]["width"] = ($dims[0] * 28.346); + } else { + $this->_push_error(6004, "Could not deciper page size description: $size"); + return false; + } + + } + } + $this->objects[$o]['type'] = 'page'; + $this->objects[$o]['parent'] = 1; + $this->objects[$o]['number'] = $this->nextpage; + $this->nextpage ++; + foreach (array('margin-left', 'margin-right', 'margin-top', 'margin-bottom') as $margin) { + $this->objects[$o][$margin] = $this->default[$margin]; + } + return $o; + } + + function swap_pages($p1, $p2) + { + if ($this->objects[$p1]["type"] != "page" || + $this->objects[$p2]["type"] != "page") { + $this->_push_std_error(6001); + return false; + } + $temp = $this->objects[$p1]["number"]; + $this->objects[$p1]["number"] = $this->objects[$p2]["number"]; + $this->objects[$p2]["number"] = $temp; + return true; + } + + function move_page_before($page, $infrontof) + { + if ($this->objects[$page]["type"] != "page" || + $this->objects[$infrontof]["type"] != "page") { + $this->_push_std_error(6001); + return false; + } + if ($page == $infrontof) { + $this->_push_error(6005, "You're trying to swap a page with itself"); + return false; + } + $target = $this->objects[$infrontof]["number"]; + $leaving = $this->objects[$page]["number"]; + foreach ($this->objects as $id => $o) { + if ($o["type"] == "page") { + if ($target < $leaving) { + if ($o["number"] >= $target && $o["number"] < $leaving) { + $this->objects[$id]["number"]++; + } + } else { + if ($o["number"] < $target && $o["number"] > $leaving) { + $this->objects[$id]["number"]--; + } + } + } + } + if ($target < $leaving) { + $this->objects[$page]["number"] = $target; + } else { + $this->objects[$page]["number"] = $target - 1; + } + return true; + } + + function new_font($identifier) + { + $n["type"] = "font"; + + switch ($identifier) { + /* The "standard" Type 1 fonts + * These are "guaranteed" to be available + * to the viewer application and don't + * need embedded + */ + case "Courier": + case "Courier-Bold": + case "Courier-Oblique": + case "Courier-BoldOblique": + case "Helvetica": + case "Helvetica-Bold": + case "Helvetica-Oblique": + case "Helvetica-BoldOblique": + case "Times-Roman": + case "Times-Bold": + case "Times-Italic": + case "Times-BoldItalic": + case "Symbol": + case "ZapfDingbats": + $o = $this->_addnewoid(); + $this->builddata["fonts"][$o] = $identifier; + $n["subtype"] = "Type1"; + $n["basefont"] = $identifier; + break; + + default: + if ($this->objects[$identifier]["type"] != "fontembed") { + $this->_push_error(6006, "Object must be of type 'fontembed'"); + return false; + } else { + // Not ready yet + $this->_push_error(6007, "Feature not implemented yet"); + return false; + } + } + $this->objects[$o] = $n; + return $o; + } + + function generate($clevel = 9) + { + // Validate the compression level + if (!$clevel) { + $this->builddata["compress"] = false; + } else { + if ($clevel < 10) { + $this->builddata["compress"] = $clevel; + } else { + $this->builddata["compress"] = 9; + } + } + /* Preprocess objects to see if they can + * be combined into a single stream + * We scan through each page, and create + * a multistream object out of all viable + * child objects + */ + $temparray = $this->objects; + foreach ($this->objects as $oid => $def) { + if ( $def["type"] == "page" ) { + unset($temp); + $temp['data'] = ""; + reset($temparray); + while ( list ($liboid, $obj) = each($temparray) ) { + if (isset($obj["parent"]) && $obj["parent"] == $oid) { + switch ($obj["type"]) { + case "texts" : + $temp["data"] .= $this->_make_text($liboid); + $this->objects[$liboid]["type"] = "null"; + $this->objects[$liboid]["parent"] = -1; + break; + + case "rectangle" : + $temp["data"] .= $this->_make_rect($liboid); + $this->objects[$liboid]["type"] = "null"; + $this->objects[$liboid]["parent"] = -1; + break; + + case "iplace" : + $temp["data"] .= $this->_place_raw_image($liboid); + $this->objects[$liboid]["type"] = "null"; + $this->objects[$liboid]["parent"] = -1; + break; + + case "line" : + $temp["data"] .= $this->_make_line($liboid); + $this->objects[$liboid]["type"] = "null"; + $this->objects[$liboid]["parent"] = -1; + break; + + case "circle" : + $temp["data"] .= $this->_make_circle($liboid); + $this->objects[$liboid]["type"] = "null"; + $this->objects[$liboid]["parent"] = -1; + break; + } + } + } + if (strlen($temp["data"]) > 0) { + // this line takes the next available oid + $o = $this->_addnewoid(); + $temp["type"] = "mstream"; + $temp["parent"] = $oid; + $this->objects[$o] = $temp; + } + } + } + unset($temparray); + + // Generate a list of PDF object IDs to + // use and map them to phppdflib IDs + foreach ( $this->objects as $oid => $properties ) { + if ( $this->_becomes_object( $properties["type"] ) ) { + $o = $this->_addtoxreftable(0,0); + $this->libtopdf[$oid] = $o; + $this->pdftolib[$o] = $oid; + } + } + + /* First characters represent the version + * of the PDF spec to conform to. + * The PDF spec recommends that the next + * four bytes be a comment containing four + * non-ASCII characters, to convince + * (for example) ftp programs that this is + * a binary file + */ + $os = "%PDF-1.3%\xe2\xe3\xcf\xd3\x0a"; + + // Create the Document Catalog + $carray["Type"] = "/Catalog"; + $carray["Pages"] = "2 0 R"; + $temp = $this->_makedictionary($carray); + $temp = "1 0 obj" . $temp . "endobj\x0a"; + $this->xreftable[1]["offset"] = strlen($os); + $os .= $temp; + + // Create the root page node + unset($carray); + $kids = $this->_order_pages(2); + $this->xreftable[2]["offset"] = strlen($os); + $os .= "2 0 " . $this->_makepagenode($kids, "" ) . "\x0a"; + + /* Create a resource dictionary for the entire + * PDF file. This may not be the most efficient + * way to store it, but it makes the code simple. + * At some point, we should analyze performance + * and see if it's worth splitting the resource + * dictionary up + */ + unset($temp); + unset($carray); + if (isset($this->builddata["fonts"]) && count($this->builddata["fonts"]) > 0) { + foreach ($this->builddata["fonts"] as $id => $base) { + $ta["F$id"] = $this->libtopdf[$id] . " 0 R"; + } + $temp["Font"] = $this->_makedictionary($ta); + } + reset($this->objects); + while (list($id, $obj) = each($this->objects)) { + if ($obj["type"] == "image") { + $xol["Img$id"] = $this->libtopdf[$id] . " 0 R"; + } + } + if ( isset($xol) && count($xol) > 0 ) { + $temp["XObject"] = $this->_makedictionary($xol); + } + $this->xreftable[3]["offset"] = strlen($os); + $os .= "3 0 obj"; + if (isset($temp)) { + $os .= $this->_makedictionary($temp); + } else { + $os .= '<<>>'; + } + $os .= " endobj\x0a"; + + // Go through and add the rest of the objects + foreach ( $this->pdftolib as $pdfoid => $liboid ) { + if ($pdfoid < 4) { + continue; + } + // Set the location of the start + $this->xreftable[$pdfoid]["offset"] = strlen($os); + switch ( $this->objects[$liboid]["type"] ) { + case "page": + $kids = $this->_get_kids($pdfoid); + $os .= $pdfoid . " 0 "; + $os .= $this->_makepage($this->objects[$liboid]["parent"], + $kids, $liboid); + break; + + case "rectangle": + $os .= $pdfoid . " 0 obj"; + $os .= $this->_streamify($this->_make_rect($liboid)); + $os .= " endobj"; + break; + + case "line": + $os .= $pdfoid . " 0 obj"; + $os .= $this->_streamify($this->_make_line($liboid)); + $os .= " endobj"; + break; + + case "circle": + $os .= $pdfoid . " 0 obj"; + $os .= $this->_streamify($this->_make_circle($liboid)); + $os .= " endobj"; + break; + + case "texts": + $os .= $pdfoid . " 0 obj"; + $temp = $this->_make_text($liboid); + $os .= $this->_streamify($temp) . " endobj"; + break; + + case "mstream": + $os .= $pdfoid . " 0 obj" . + $this->_streamify(trim($this->objects[$liboid]["data"])) . + " endobj"; + break; + + case "image": + $os .= $pdfoid . " 0 obj"; + $os .= $this->_make_raw_image($liboid); + $os .= " endobj"; + break; + + case "iplace": + $os .= $pdfoid . " 0 obj"; + $os .= $this->_streamify($this->_place_raw_image($liboid)); + $os .= " endobj"; + break; + + case "font" : + $os .= $pdfoid . " 0 obj"; + unset ( $temp ); + $temp["Type"] = "/Font"; + $temp["Subtype"] = "/" . $this->objects[$liboid]["subtype"]; + $temp["BaseFont"] = "/" . $this->objects[$liboid]["basefont"]; + $temp["Encoding"] = "/WinAnsiEncoding"; + $temp["Name"] = "/F$liboid"; + $os .= $this->_makedictionary($temp); + $os .= " endobj"; + break; + } + $os .= "\x0a"; + } + + // Create an Info entry + $info = $this->_addtoxreftable(0,0); + $this->xreftable[$info]["offset"] = strlen($os); + unset($temp); + $temp["Producer"] = + $this->_stringify("phppdflib http://www.potentialtech.com/ppl.php"); + $os .= $info . " 0 obj" . $this->_makedictionary($temp) . " endobj\x0a"; + + // Create the xref table + $this->builddata["startxref"] = strlen($os); + $os .= "xref\x0a0 " . (string)($this->nextobj + 1) . "\x0a"; + for ( $i = 0; $i <= $this->nextobj; $i ++ ) { + $os .= sprintf("%010u %05u %s \x0a", $this->xreftable[$i]["offset"], + $this->xreftable[$i]["gennum"], + $this->xreftable[$i]["free"]); + } + + // Create document trailer + $os .= "trailer\x0a"; + unset($temp); + $temp["Size"] = $this->nextobj + 1; + $temp["Root"] = "1 0 R"; + $temp["Info"] = $info . " 0 R"; + $os .= $this->_makedictionary($temp); + $os .= "\x0astartxref\x0a"; + $os .= $this->builddata["startxref"] . "\x0a"; + + // Required end of file marker + $os .= "%%EOF\x0a"; + + return $os; + } + + function png_embed($data) + { + // Sanity, make sure this is a png + if (substr($data, 0, 8) != "\137PNG\x0d\x0a\x1a\x0d") { + $this->_push_std_error(6011); + return false; + } + + } + + function jfif_embed($data) + { + /* Sanity check: Check magic numbers to see if + * this is really a JFIF stream + */ + if ( substr($data, 0, 4) != "\xff\xd8\xff\xe0" || + substr($data, 6, 4) != "JFIF" ) { + // This is not in JFIF format + $this->_push_std_error(6008); + return false; + } + + /* Now we'll scan through all the markers in the + * JFIF and extract whatever data we need from them + * We're not being terribly anal about validating + * the structure of the JFIF, so a corrupt stream + * could have very unpredictable results + */ + // Default values + $pos = 0; + $size = strlen($data); + + while ( $pos < $size ) { + $marker = substr($data, $pos + 1, 1); + // Just skip these markers + if ($marker == "\xd8" || $marker == "\xd9" || $marker == "\x01") { + $pos += 2; + continue; + } + if ($marker == "\xff") { + $pos ++; + continue; + } + + switch ($marker) { + // Start of frame + // Baseline + case "\xc0": + // Extended sequential + case "\xc1": + // Differential sequential + case "\xc5": + // Progressive + case "\xc2": + // differential progressive + case "\xc6": + // Lossless + case "\xc3": + // differential lossless + case "\xc7": + // Arithmetic encoded + case "\xc9": + case "\xca": + case "\xcb": + case "\xcd": + case "\xce": + case "\xcf": + $precision = $this->_int_val(substr($data, $pos + 4, 1)); + $height = $this->_int_val(substr($data, $pos + 5, 2)); + $width = $this->_int_val(substr($data, $pos + 7, 2)); + $numcomp = $this->_int_val(substr($data, $pos + 9, 1)); + if ( $numcomp != 3 && $numcomp != 1 ) { + // Abort if we aren't encoded as B&W or YCbCr + $this->_push_std_error(6008); + return false; + } + $pos += 2 + $this->_int_val(substr($data, $pos + 2, 2)); + break 2; + } + + /* All marker identifications continue the + * loop, thus if we got here, we need to skip + * this marker as we don't understand it. + */ + $pos += 2 + $this->_int_val(substr($data, $pos + 2, 2)); + } + $cspace = $numcomp == 1 ? "/DeviceGray" : "/DeviceRGB"; + return $this->image_raw_embed($data, + $cspace, + $precision, + $height, + $width, + "/DCTDecode"); + } + + function image_raw_embed($data, $cspace, $bpc, $height, $width, $filter = "") + { + $o = $this->_addnewoid(); + $t["data"] = $data; + $t["colorspace"] = $cspace; + $t["bpc"] = $bpc; + $t["type"] = "image"; + $t["height"] = $height; + $t["width"] = $width; + $t["filter"] = $filter; + $this->objects[$o] = $t; + return $o; + } + + function get_image_size($id) + { + if ($this->objects[$id]['type'] != 'image') { + $this->_push_std_error(6009); + return false; + } + $r['width'] = $this->objects[$id]['width']; + $r['height'] = $this->objects[$id]['height']; + return $r; + } + + function image_place($oid, $bottom, $left, $parent, $param = array()) + { + if ($this->objects[$oid]["type"] != "image") { + $this->_push_std_error(6009); + return false; + } + if ($this->objects[$parent]["type"] != "page") { + $this->_push_std_error(6001); + return false; + } + + $o = $this->_addnewoid(); + $param = $this->_resolve_param($param, false); + $t["type"] = "iplace"; + $this->_adjust_margin($left, $bottom, $parent); + $t["bottom"] = $bottom; + $t["left"] = $left; + $t["parent"] = $parent; + // find out what the image size should be + $width = $this->objects[$oid]["width"]; + $height = $this->objects[$oid]["height"]; + $scale = $param['scale']; + if (is_array($scale)) { + $t["xscale"] = $scale["x"] * $width; + $t["yscale"] = $scale["y"] * $height; + } else { + $t["xscale"] = $scale * $width; + $t["yscale"] = $scale * $height; + } + $t["rotation"] = $param['rotation']; + $t["image"] = $oid; + $this->objects[$o] = $t; + return $o; + } + + function strlen($string , $params = false, $tabwidth = 4) + { + if ($this->needsset) { + require_once(dirname(__FILE__) . '/strlen.inc.php'); + } + if (empty($params["font"])) { + $font = $this->default['font']; + } else { + $font = $params["font"]; + switch ($font) { + case "Times-Roman" : + $font = "Times"; + break; + case "Helvetica-Oblique" : + $font = "Helvetica"; + break; + case "Helvetica-BoldOblique" : + $font = "Helvetica-Bold"; + break; + case "ZapfDingbats" : + $font = "Dingbats"; + break; + } + } + if ($params["height"] == 0) { + $size = $this->default['height']; + } else { + $size = $params["height"]; + } + $tab = ''; + for ($i = 0; $i < $tabwidth; $i++) { + $tab .= ' '; + } + $string = str_replace(chr(9), $tab, $string); + if (substr($font, 0, 7) == "Courier") { + // Courier is a fixed-width font + $width = strlen($string) * 600; + } else { + $width = 0; + $len = strlen($string); + for ($i = 0; $i < $len; $i++) { + $width += $this->widths[$font][ord($string{$i})]; + } + } + // We now have the string width in font units + return $width * $size / 1000; + } + + function wrap_line(&$text, $width, $param = array()) + { + $maxchars = (int)(1.1 * $width / $this->strlen("i", $param)); + $words = explode(" ", substr($text, 0, $maxchars)); + if ($this->strlen($words[0]) >= $width) { + $this->_push_error(3001, "Single token too long for allowed space"); + $final = $words[0]; + } else { + $space = $this->strlen(" ", $param); + $len = 0; + $word = 0; + $final = ""; + while ($len < $width) { + if ($word >= count($words)) { + break; + } + $temp = $this->strlen($words[$word], $param); + if ( ($len + $temp) <= $width) { + $final .= $words[$word] . " "; + $word ++; + } + $len += $space + $temp; + } + } + $text = substr($text, strlen($final)); + return $final; + } + + function word_wrap($words, $width, $param = array()) + { + // break $words into an array separated by manual paragraph break character + $paragraph = explode("\n", $words); + // find the width of 1 space in this font + $swidth = $this->strlen( " " , $param ); + // uses each element of $paragraph array and splits it at spaces + for ($lc = 0; $lc < count($paragraph); $lc++){ + while (strlen($paragraph[$lc]) > 0) { + $returnarray[] = $this->wrap_line($paragraph[$lc], $width, $param); + } + } + return $returnarray; + } + + function draw_one_paragraph($top, $left, $bottom, $right, $text, $page, $param = array()) + { + $param = $this->_resolve_param($param); + $height = 1.1 * $param['height']; + $width = $right - $left; + while ($top > $bottom) { + if (strlen($text) < 1) { + break; + } + $top -= $height; + if ($top >= $bottom) { + $line = $this->wrap_line($text, $width, $param); + switch ($param['align']) { + case 'right' : + $line = trim($line); + $l = $right - $this->strlen($line, $param); + break; + + case 'center' : + $line = trim($line); + $l = $left + (($width - $this->strlen($line, $param)) / 2); + break; + + default : + $l = $left; + } + $this->draw_text($l, $top, $line, $page, $param); + } else { + $top += $height; + break; + } + } + if (strlen($text) > 0) { + return $text; + } else { + return $top; + } + } + + function draw_paragraph($top, $left, $bottom, $right, $text, $page, $param = array()) + { + $paras = split("\n", $text); + for ($i = 0; $i < count($paras); $i++) { + $over = $this->draw_one_paragraph($top, + $left, + $bottom, + $right, + $paras[$i], + $page, + $param); + if (is_string($over)) { + break; + } + $top = $over; + } + $rv = $over; + if ($i < count($paras)) { + for ($x = $i + 1; $x < count($paras); $x++) { + $rv .= "\n" . $paras[$x]; + } + } + return $rv; + } + + function error_array() + { + $rv = array(); + while (count($this->ermsg) > 0) { + $this->pop_error($num, $msg); + $rv[] = "Error $num: $msg"; + } + return $rv; + } + + function pop_error(&$num, &$msg) + { + $num = array_pop($this->erno); + $msg = array_pop($this->ermsg); + if (is_null($num)) { + return false; + } else { + return $num; + } + } + + function enable($name) + { + $name = strtolower($name); + @include_once(dirname(__FILE__) . "/${name}.class.php"); + $this->x[$name] = new $name; + $this->x[$name]->pdf = &$this; + switch ($name) { + case 'chart' : + case 'template' : + $this->$name = &$this->x[$name]; + break; + } + } + + function get_color($desc) + { + + $r = array(); + switch (strtolower($desc)) { + case 'black' : + $r['red'] = $r['blue'] = $r['green'] = 0; + break; + + case 'white' : + $r['red'] = $r['blue'] = $r['green'] = 1; + break; + + case 'red' : + $r['red'] = 1; + $r['blue'] = $r['green'] = 0; + break; + + case 'blue' : + $r['blue'] = 1; + $r['red'] = $r['green'] = 0; + break; + + case 'green' : + $r['green'] = 1; + $r['blue'] = $r['red'] = 0; + break; + + default : + if (substr($desc, 0, 1) == '#') { + // Parse out a hex triplet + $v = substr($desc, 1, 2); + $r['red'] = eval("return ord(\"\\x$v\");") / 255; + $v = substr($desc, 3, 2); + $r['green'] = eval("return ord(\"\\x$v\");") / 255; + $v = substr($desc, 5, 2); + $r['blue'] = eval("return ord(\"\\x$v\");") / 255; + } else { + // Error condition? + $this->_push_error(6012, "Unparsable color identifier: $desc"); + $r = false; + } + } + return $r; + } + +/****************************************************** + * These functions are internally used by the library * + * and shouldn't really be called by a user of * + * phppdflib * + ******************************************************/ + + function _resolve_mode($attrib, $mode) + { + $rmode = $attrib[$mode]; + if ($rmode != 0) { + $r = $rmode; + } else { + switch ($rmode) { + case "fill": + $r = 0; + break; + + case "stroke": + $r = 1; + break; + + case "fill+stroke": + $r = 2; + break; + } + } + return $r; + } + + function _adjust_margin(&$x, &$y, $page) + { + $x += $this->objects[$page]['margin-left']; + $y += $this->objects[$page]['margin-bottom']; + } + + function _resolve_param($param, $text = true) + { + $rv = $this->default; + if (is_array($param)) { + if (isset($param['mode'])) { + $param['tmode'] = $param['smode'] = $param['mode']; + } + foreach ($param as $key => $value) { + $rv[$key] = $value; + } + } + return $rv; + } + + function _push_error($num, $msg) + { + array_push($this->erno, $num); + array_push($this->ermsg, $msg); + } + + function _push_std_error($num) + { + switch ($num) { + case 6001 : $m = "Object must be of type 'page'"; break; + case 6008 : $m = "Data stream not recognized as JFIF"; break; + case 6009 : $m = "Object must be of type 'image'"; break; + case 6011 : $m = "Data stream not recognized as PNG"; break; + default : $m = "_push_std_error() called with invalid error number: $num"; break; + } + $this->_push_error($num, $m); + } + + function _resolve_colors(&$n, $attrib) + { + $temp = array('red','green','blue'); + foreach ($temp as $colcomp) { + if (isset($attrib['fillcolor'][$colcomp])) { + $n['fillcolor'][$colcomp] = $attrib['fillcolor'][$colcomp]; + } + if (isset($attrib['strokecolor'][$colcomp])) { + $n['strokecolor'][$colcomp] = $attrib['strokecolor'][$colcomp]; + } + } + } + + /* Check to see if a requested font is already in the + * list, if not add it. Either way, return the libid + * of the font + */ + function _use_font($id) + { + if (!isset($id['font'])) { + $id['font'] = $this->default['font']; + } + if ( isset($this->builddata["fonts"]) && count($this->builddata["fonts"]) > 0 ) { + foreach ($this->builddata["fonts"] as $libid => $name) { + if ($name == $id['font']) { + return $libid; + } + } + } + /* The font isn't in the table, so we add it + * and return it's ID + */ + return $this->new_font($id['font']); + } + + /* Convert a big-endian byte stream into an integer */ + function _int_val($string) + { + $r = 0; + for ($i = 0; $i < strlen($string); $i ++ ) { + $r += ord($string{$i}) * pow(256, strlen($string) - $i -1); + } + return $r; + } + + function _make_raw_image($liboid) + { + $s["Type"] = "/XObject"; + $s["Subtype"] = "/Image"; + $s["Width"] = $this->objects[$liboid]["width"]; + $s["Height"] = $this->objects[$liboid]["height"]; + $s["ColorSpace"] = $this->objects[$liboid]["colorspace"]; + $s["BitsPerComponent"] = $this->objects[$liboid]["bpc"]; + if (strlen($this->objects[$liboid]["filter"]) > 0) { + $s["Filter"] = $this->objects[$liboid]["filter"]; + } + return $this->_streamify($this->objects[$liboid]["data"], $s); + } + + function _place_raw_image($liboid) + { + $xscale = $this->objects[$liboid]["xscale"]; + $yscale = $this->objects[$liboid]["yscale"]; + $angle = $this->objects[$liboid]["rotation"]; + $temp = "q 1 0 0 1 " . + $this->objects[$liboid]["left"] . " " . + $this->objects[$liboid]["bottom"] . " cm "; + if ($angle != 0) { + $temp .= $this->_rotate($angle) . " cm "; + } + if ($xscale != 1 || $yscale != 1) { + $temp .= "$xscale 0 0 $yscale 0 0 cm "; + } + $temp .= "/Img" . $this->objects[$liboid]["image"] . + " Do Q\x0a"; + return $temp; + } + + function _rotate($angle) + { + $a = deg2rad($angle); + $cos = cos($a); + $sin = sin($a); + $r = sprintf("%1\$01.6f %2\$01.6f %3\$01.6f %1\$01.6f 0 0", $cos, $sin, -$sin); + return $r; + } + + function _get_operator($liboid) + { + switch ($this->objects[$liboid]['mode']) { + case 0 : return "f"; break; + case 1 : return "S"; break; + case 2 : return "b"; break; + } + } + + function _make_line($liboid) + { + $gstate = ""; + if ( $colortest = $this->_colorset($liboid) ) { + $gstate .= $colortest . " "; + } + if ( isset($this->objects[$liboid]["width"]) && $this->objects[$liboid]["width"] != 1 ) { + $gstate .= $this->objects[$liboid]["width"] . " w "; + } + $firstpoint = true; + $temp = ""; + foreach ($this->objects[$liboid]["x"] as $pointid => $x) { + $y = $this->objects[$liboid]["y"][$pointid]; + $temp .= $x . " " . $y . " "; + if ($firstpoint) { + $temp .= "m "; + $firstpoint = false; + } else { + $temp .= "l "; + } + } + $temp .= $this->_get_operator($liboid); + if ( strlen($gstate) > 0 ) { + $temp = "q " . $gstate . $temp . " Q"; + } + return $temp . "\x0a"; + } + + function _make_rect($liboid) + { + $gstate = ""; + if ( $colortest = $this->_colorset($liboid) ) { + $gstate .= $colortest . " "; + } + if ( isset($this->objects[$liboid]["width"]) && $this->objects[$liboid]["width"] != 1 ) { + $gstate .= $this->objects[$liboid]["width"] . " w "; + } + $temp = $this->objects[$liboid]["left"] . " "; + $temp .= $this->objects[$liboid]["bottom"]; + $temp .= " " . ( $this->objects[$liboid]["right"] + - $this->objects[$liboid]["left"] ); + $temp .= " " . ( $this->objects[$liboid]["top"] + - $this->objects[$liboid]["bottom"] ); + $temp .= ' re '; + $temp .= $this->_get_operator($liboid); + if ( strlen($gstate) > 0 ) { + $temp = "q " . $gstate . $temp . " Q"; + } + return $temp . "\x0a"; + } + + function _make_circle($liboid) + { + $gstate = ""; + if ( $colortest = $this->_colorset($liboid) ) { + $gstate .= $colortest . " "; + } + if ( isset($this->objects[$liboid]["width"]) && $this->objects[$liboid]["width"] != 1 ) { + $gstate .= $this->objects[$liboid]["width"] . " w "; + } + $r = $this->objects[$liboid]['radius']; + $x = $this->objects[$liboid]['x']; + $y = $this->objects[$liboid]['y']; + $ql = $x - $r; + $pt = $y + $r * 1.33333; + $qr = $x + $r; + $pb = $y - $r * 1.33333; + $temp = "$ql $y m "; + $temp .= "$ql $pt $qr $pt $qr $y c "; + $temp .= "$qr $pb $ql $pb $ql $y c "; + $temp .= $this->_get_operator($liboid); + if ( strlen($gstate) > 0 ) { + $temp = "q " . $gstate . $temp . " Q"; + } + return $temp . "\x0a"; + } + + function _make_text($liboid) + { + $statechange = ""; $locateinbt = true; + $statechange = $this->_colorset($liboid); + if (isset($this->objects[$liboid]["rotation"]) && $this->objects[$liboid]["rotation"] != 0) { + $statechange .= "1 0 0 1 " . + $this->objects[$liboid]["left"] . " " . + $this->objects[$liboid]["bottom"] . " cm " . + $this->_rotate($this->objects[$liboid]["rotation"]) . + " cm "; + $locateinbt = false; + } + $temp = "BT "; + if ($this->objects[$liboid]["mode"] != 0) { + $temp .= $this->objects[$liboid]["mode"] . + " Tr "; + // Adjust stroke width + $statechange .= $this->objects[$liboid]["height"] / 35 . " w "; + } + $temp .= "/F" . $this->objects[$liboid]["font"] . " "; + $temp .= $this->objects[$liboid]["height"]; + $temp .= " Tf "; + if ($locateinbt) { + $temp .= $this->objects[$liboid]["left"] . " " . + $this->objects[$liboid]["bottom"]; + } else { + $temp .= "0 0"; + } + $temp .= " Td "; + $temp .= $this->_stringify($this->objects[$liboid]["text"]); + $temp .= " Tj "; + $temp .= "ET"; + if (strlen($statechange) > 0) { + $temp = "q " . $statechange . $temp . " Q"; + } + return $temp . "\x0a"; + } + + function _colorset($libid) + { + $red = isset($this->objects[$libid]['fillcolor']["red"]) ? (float)$this->objects[$libid]['fillcolor']["red"] : 0; + $green = isset($this->objects[$libid]['fillcolor']["green"]) ? (float)$this->objects[$libid]['fillcolor']["green"] : 0; + $blue = isset($this->objects[$libid]['fillcolor']["blue"]) ? (float)$this->objects[$libid]['fillcolor']["blue"] : 0; + if (($red > 0) || ($green > 0) || ($blue > 0)) { + $r = $red . " " . $green . " " . $blue; + $r .= " rg "; + } else { + $r = ""; + } + $red = isset($this->objects[$libid]['strokecolor']["red"]) ? (float)$this->objects[$libid]['strokecolor']["red"] : 0; + $green = isset($this->objects[$libid]['strokecolor']["green"]) ? (float)$this->objects[$libid]['strokecolor']["green"] : 0; + $blue = isset($this->objects[$libid]['strokecolor']["blue"]) ? (float)$this->objects[$libid]['strokecolor']["blue"] : 0; + if (($red > 0) || ($green > 0) || ($blue > 0) ) { + $r .= $red . " " . $green . " " . $blue; + $r .= " RG "; + } + return $r; + } + + /* Used to determine what pdflib objects need converted + * to actual PDF objects. + */ + function _becomes_object($object) + { + if ($object == "null") { + return false; + } + return true; + } + + /* builds an array of child objects */ + function _get_kids($pdfid) + { + $libid = $this->pdftolib[$pdfid]; + foreach( $this->objects as $obid => $object ) { + if (isset($object["parent"]) && $object["parent"] == $libid) { + $kids[] = $this->libtopdf[$obid] . " 0 R"; + } + } + return $kids; + } + + /* builds an array of pages, in order */ + function _order_pages($pdfid) + { + $libid = $this->pdftolib[$pdfid]; + foreach( $this->objects as $obid => $object ) { + if (isset($object["parent"]) && $object["parent"] == $libid) { + $kids[$object["number"]] = $this->libtopdf[$obid] . " 0 R"; + } + } + ksort($kids); + return $kids; + } + + /* simple helper function to return the current oid + * and increment it by one + */ + function _addnewoid() + { + $o = $this->nextoid; + $this->nextoid++; + return $o; + } + + /* The xreftable will contain a list of all the + * objects in the pdf file and the number of bytes + * from the beginning of the file that the object + * occurs. Each time we add an object, we call this + * to record it's location, then call ->_genxreftable() + * to generate the table from array + */ + function _addtoxreftable($offset, $gennum) + { + $this->nextobj ++; + $this->xreftable[$this->nextobj]["offset"] = $offset; + $this->xreftable[$this->nextobj]["gennum"] = $gennum; + $this->xreftable[$this->nextobj]["free"] = "n"; + return $this->nextobj; + } + + /* Returns a properly formatted pdf dictionary + * containing entries specified by + * the array $entries + */ + function _makedictionary($entries) + { + $rs = "<<\x0a"; + if (isset($entries) && count($entries) > 0) { + foreach ($entries as $key => $value) { + $rs .= "/" . $key . " " . $value . "\x0a"; + } + } + $rs .= ">>"; + return $rs; + } + + /* returns a properly formatted pdf array */ + function _makearray($entries) + { + $rs = "["; + if ( is_array($entries) ) { + foreach ($entries as $entry) { + $rs .= $entry . " "; + } + } else { + $rs .= $entries; + } + $rs = rtrim($rs) . "]"; + return $rs; + } + + /* Returns a properly formatted string, with any + * special characters escaped + */ + function _stringify($string) + { + // Escape potentially problematic characters + $string = preg_replace("-\\\\-","\\\\\\\\",$string); + $bad = array ("-\(-", "-\)-" ); + $good = array ("\\(", "\\)" ); + $string = preg_replace($bad,$good,$string); + return "(" . rtrim($string) . ")"; + } + + function _streamify($data, $sarray = array()) + { + /* zlib compression is a compile time option + * for php, thus we need to make sure it's + * available before using it. + */ + if ( function_exists('gzcompress') && $this->builddata["compress"] ) { + // For now, we don't compress if already using a filter + if ( !isset($sarray["Filter"]) || strlen($sarray["Filter"]) == 0 ) { + $sarray["Filter"] = "/FlateDecode"; + } else { + $sarray['Filter'] = "[/FlateDecode " . $sarray['Filter'] . "]"; + } + $data = gzcompress($data, $this->builddata["compress"]); + } + $sarray["Length"] = strlen($data); + $os = $this->_makedictionary($sarray); + $os .= "stream\x0a" . $data . "\x0aendstream"; + return $os; + } + + /* Returns a properly formatted page node + * page nodes with 0 kids are not created + */ + function _makepagenode($kids, $addtlopts = false) + { + $parray["Type"] = "/Pages"; + if ( isset($kids) AND count($kids) > 0 ) { + // Array of child objects + $parray["Kids"] = $this->_makearray($kids); + // Number of pages + $parray["Count"] = count($kids); + } else { + // No kids is an error condition + $this->_push_error(600, "Pagenode has no children"); + return false; + } + if ( is_array($addtlopts) ) { + foreach ( $addtlopts as $key => $value ) { + $parray[$key] = $value; + } + } + + /* The resource dictionary is always object 3 + */ + $parray["Resources"] = "3 0 R"; + + $os = $this->_makedictionary($parray); + $os = "obj" . $os . "endobj"; + return $os; + } + + function _makepage($parent, $contents, $liboid) + { + $parray["Type"] = "/Page"; + $parray["Parent"] = $this->libtopdf[$parent] . " 0 R"; + $parray["Contents"] = $this->_makearray($contents); + $parray["MediaBox"] = "[0 0 " + . $this->objects[$liboid]["width"] . " " + . $this->objects[$liboid]["height"] . "]"; + $os = $this->_makedictionary($parray); + $os = "obj" . $os . "endobj"; + return $os; + } + +} +?> diff --git a/lib/MECON/PDF/external/strlen.inc.php b/lib/MECON/PDF/external/strlen.inc.php new file mode 100755 index 0000000..42b9393 --- /dev/null +++ b/lib/MECON/PDF/external/strlen.inc.php @@ -0,0 +1,290 @@ +needsset = false; +$this->widths['Symbol']= array ( 32 => 250, 33 => 333, 34 => 713, 35 => 500, 36 => 549, + 37 => 833, 38 => 778, 39 => 439, 40 => 333, 41 => 333, + 42 => 500, 43 => 549, 44 => 250, 45 => 549, 46 => 250, + 47 => 278, 48 => 500, 49 => 500, 50 => 500, 51 => 500, + 52 => 500, 53 => 500, 54 => 500, 55 => 500, 56 => 500, + 57 => 500, 58 => 278, 59 => 278, 60 => 549, 61 => 549, + 62 => 549, 63 => 444, 64 => 549, 65 => 722, 66 => 667, + 67 => 722, 68 => 612, 69 => 611, 70 => 763, 71 => 603, + 72 => 722, 73 => 333, 74 => 631, 75 => 722, 76 => 686, + 77 => 889, 78 => 722, 79 => 722, 80 => 768, 81 => 741, + 82 => 556, 83 => 592, 84 => 611, 85 => 690, 86 => 439, + 87 => 768, 88 => 645, 89 => 795, 90 => 611, 91 => 333, + 92 => 863, 93 => 333, 94 => 658, 95 => 500, 96 => 500, + 97 => 631, 98 => 549, 99 => 549, 100 => 494, 101 => 439, + 102 => 521, 103 => 411, 104 => 603, 105 => 329, 106 => 603, + 107 => 549, 108 => 549, 109 => 576, 110 => 521, 111 => 549, + 112 => 549, 113 => 521, 114 => 549, 115 => 603, 116 => 439, + 117 => 576, 118 => 713, 119 => 686, 120 => 493, 121 => 686, + 122 => 494, 123 => 480, 124 => 200, 125 => 480, 126 => 549, + 161 => 620, 162 => 247, 163 => 549, 164 => 167, 165 => 713, + 166 => 500, 167 => 753, 168 => 753, 169 => 753, 170 => 753, + 171 => 1042, 172 => 987, 173 => 603, 174 => 987, 175 => 603, + 176 => 400, 177 => 549, 178 => 411, 179 => 549, 180 => 549, + 181 => 713, 182 => 494, 183 => 460, 184 => 549, 185 => 549, + 186 => 549, 187 => 549, 188 => 1000, 189 => 603, 190 => 1000, + 191 => 658, 192 => 823, 193 => 686, 194 => 795, 195 => 987, + 196 => 768, 197 => 768, 198 => 823, 199 => 768, 200 => 768, + 201 => 713, 202 => 713, 203 => 713, 204 => 713, 205 => 713, + 206 => 713, 207 => 713, 208 => 768, 209 => 713, 210 => 790, + 211 => 790, 212 => 890, 213 => 823, 214 => 549, 215 => 250, + 216 => 713, 217 => 603, 218 => 603, 219 => 1042, 220 => 987, + 221 => 603, 222 => 987, 223 => 603, 224 => 494, 225 => 329, + 226 => 790, 227 => 790, 228 => 786, 229 => 713, 230 => 384, + 231 => 384, 232 => 384, 233 => 384, 234 => 384, 235 => 384, + 236 => 494, 237 => 494, 238 => 494, 239 => 494, 241 => 329, + 242 => 274, 243 => 686, 244 => 686, 245 => 686, 246 => 384, + 247 => 384, 248 => 384, 249 => 384, 250 => 384, 251 => 384, + 252 => 494, 253 => 494, 254 => 494 ); +$this->widths['Dingbats'] = array (32 => 278, 33 => 974, 34 => 961, 35 => 974, 36 => 980, + 37 => 719, 38 => 789, 39 => 790, 40 => 791, 41 => 690, + 42 => 960, 43 => 939, 44 => 549, 45 => 855, 46 => 911, + 47 => 933, 48 => 911, 49 => 945, 50 => 974, 51 => 755, + 52 => 846, 53 => 762, 54 => 761, 55 => 571, 56 => 677, + 57 => 763, 58 => 760, 59 => 759, 60 => 754, 61 => 494, + 62 => 552, 63 => 537, 64 => 577, 65 => 692, 66 => 786, + 67 => 788, 68 => 788, 69 => 790, 70 => 793, 71 => 794, + 72 => 816, 73 => 823, 74 => 789, 75 => 841, 76 => 823, + 77 => 833, 78 => 816, 79 => 831, 80 => 923, 81 => 744, + 82 => 723, 83 => 749, 84 => 790, 85 => 792, 86 => 695, + 87 => 776, 88 => 768, 89 => 792, 90 => 759, 91 => 707, + 92 => 708, 93 => 682, 94 => 701, 95 => 826, 96 => 815, + 97 => 789, 98 => 789, 99 => 707, 100 => 687, 101 => 696, + 102 => 689, 103 => 786, 104 => 787, 105 => 713, 106 => 791, + 107 => 785, 108 => 791, 109 => 873, 110 => 761, 111 => 762, + 112 => 762, 113 => 759, 114 => 759, 115 => 892, 116 => 892, + 117 => 788, 118 => 784, 119 => 438, 120 => 138, 121 => 277, + 122 => 415, 123 => 392, 124 => 392, 125 => 668, 126 => 668, + 161 => 732, 162 => 544, 163 => 544, 164 => 910, 165 => 667, + 166 => 760, 167 => 760, 168 => 776, 169 => 595, 170 => 694, + 171 => 626, 172 => 788, 173 => 788, 174 => 788, 175 => 788, + 176 => 788, 177 => 788, 178 => 788, 179 => 788, 180 => 788, + 181 => 788, 182 => 788, 183 => 788, 184 => 788, 185 => 788, + 186 => 788, 187 => 788, 188 => 788, 189 => 788, 190 => 788, + 191 => 788, 192 => 788, 193 => 788, 194 => 788, 195 => 788, + 196 => 788, 197 => 788, 198 => 788, 199 => 788, 200 => 788, + 201 => 788, 202 => 788, 203 => 788, 204 => 788, 205 => 788, + 206 => 788, 207 => 788, 208 => 788, 209 => 788, 210 => 788, + 211 => 788, 212 => 894, 213 => 838, 214 => 1016, 215 => 458, + 216 => 748, 217 => 924, 218 => 748, 219 => 918, 220 => 927, + 221 => 928, 222 => 928, 223 => 834, 224 => 873, 225 => 828, + 226 => 924, 227 => 924, 228 => 917, 229 => 930, 230 => 931, + 231 => 463, 232 => 883, 233 => 836, 234 => 836, 235 => 867, + 236 => 867, 237 => 696, 238 => 696, 239 => 874, 241 => 874, + 242 => 760, 243 => 946, 244 => 771, 245 => 865, 246 => 771, + 247 => 888, 248 => 967, 249 => 888, 250 => 831, 251 => 873, + 252 => 927, 253 => 970, 254 => 918); +$this->widths['Helvetica-Bold'] = array (32 => 278, 33 => 333, 34 => 474, 35 => 556, + 36 => 556, 37 => 889, 38 => 722, 39 => 278, + 40 => 333, 41 => 333, 42 => 389, 43 => 584, + 44 => 278, 45 => 333, 46 => 278, 47 => 278, + 48 => 556, 49 => 556, 50 => 556, 51 => 556, + 52 => 556, 53 => 556, 54 => 556, 55 => 556, + 56 => 556, 57 => 556, 58 => 333, 59 => 333, + 60 => 584, 61 => 584, 62 => 584, 63 => 611, + 64 => 975, 65 => 722, 66 => 722, 67 => 722, + 68 => 722, 69 => 667, 70 => 611, 71 => 778, + 72 => 722, 73 => 278, 74 => 556, 75 => 722, + 76 => 611, 77 => 833, 78 => 722, 79 => 778, + 80 => 667, 81 => 778, 82 => 722, 83 => 667, + 84 => 611, 85 => 722, 86 => 667, 87 => 944, + 88 => 667, 89 => 667, 90 => 611, 91 => 333, + 92 => 278, 93 => 333, 94 => 584, 95 => 556, + 96 => 278, 97 => 556, 98 => 611, 99 => 556, + 100 => 611, 101 => 556, 102 => 333, 103 => 611, + 104 => 611, 105 => 278, 106 => 278, 107 => 556, + 108 => 278, 109 => 889, 110 => 611, 111 => 611, + 112 => 611, 113 => 611, 114 => 389, 115 => 556, + 116 => 333, 117 => 611, 118 => 556, 119 => 778, + 120 => 556, 121 => 556, 122 => 500, 123 => 389, + 124 => 280, 125 => 389, 126 => 584, 161 => 333, + 162 => 556, 163 => 556, 164 => 167, 165 => 556, + 166 => 556, 167 => 556, 168 => 556, 169 => 238, + 170 => 500, 171 => 556, 172 => 333, 173 => 333, + 174 => 611, 175 => 611, 177 => 556, 178 => 556, + 179 => 556, 180 => 278, 182 => 556, 183 => 350, + 184 => 278, 185 => 500, 186 => 500, 187 => 556, + 188 => 1000, 189 => 1000, 191 => 611, 193 => 333, + 194 => 333, 195 => 333, 196 => 333, 197 => 333, + 198 => 333, 199 => 333, 200 => 333, 202 => 333, + 203 => 333, 205 => 333, 206 => 333, 207 => 333, + 208 => 1000, 225 => 1000, 227 => 370, 232 => 611, + 233 => 778, 234 => 1000, 235 => 365, 241 => 889, + 245 => 278, 248 => 278, 249 => 611, 250 => 944, + 251 => 611 ); +$this->widths['Helvetica'] = array (32 => 278, 33 => 278, 34 => 355, 35 => 556, 36 => 556, + 37 => 889, 38 => 667, 39 => 222, 40 => 333, 41 => 333, + 42 => 389, 43 => 584, 44 => 278, 45 => 333, 46 => 278, + 47 => 278, 48 => 556, 49 => 556, 50 => 556, 51 => 556, + 52 => 556, 53 => 556, 54 => 556, 55 => 556, 56 => 556, + 57 => 556, 58 => 278, 59 => 278, 60 => 584, 61 => 584, + 62 => 584, 63 => 556, 64 => 1015, 65 => 667, 66 => 667, + 67 => 722, 68 => 722, 69 => 667, 70 => 611, 71 => 778, + 72 => 722, 73 => 278, 74 => 500, 75 => 667, 76 => 556, + 77 => 833, 78 => 722, 79 => 778, 80 => 667, 81 => 778, + 82 => 722, 83 => 667, 84 => 611, 85 => 722, 86 => 667, + 87 => 944, 88 => 667, 89 => 667, 90 => 611, 91 => 278, + 92 => 278, 93 => 278, 94 => 469, 95 => 556, 96 => 222, + 97 => 556, 98 => 556, 99 => 500, 100 => 556, 101 => 556, + 102 => 278, 103 => 556, 104 => 556, 105 => 222, 106 => 222, + 107 => 500, 108 => 222, 109 => 833, 110 => 556, 111 => 556, + 112 => 556, 113 => 556, 114 => 333, 115 => 500, 116 => 278, + 117 => 556, 118 => 500, 119 => 722, 120 => 500, 121 => 500, + 122 => 500, 123 => 334, 124 => 260, 125 => 334, 126 => 584, + 161 => 333, 162 => 556, 163 => 556, 164 => 167, 165 => 556, + 166 => 556, 167 => 556, 168 => 556, 169 => 191, 170 => 333, + 171 => 556, 172 => 333, 173 => 333, 174 => 500, 175 => 500, + 177 => 556, 178 => 556, 179 => 556, 180 => 278, 182 => 537, + 183 => 350, 184 => 222, 185 => 333, 186 => 333, 187 => 556, + 188 => 1000, 189 => 1000, 191 => 611, 193 => 333, 194 => 333, + 195 => 333, 196 => 333, 197 => 333, 198 => 333, 199 => 333, + 200 => 333, 202 => 333, 203 => 333, 205 => 333, 206 => 333, + 207 => 333, 208 => 1000, 225 => 1000, 227 => 370, 232 => 556, + 233 => 778, 234 => 1000, 235 => 365, 241 => 889, 245 => 278, + 248 => 222, 249 => 611, 250 => 944, 251 => 611 ); +$this->widths['Times'] = array (32 => 250, 33 => 333, 34 => 408, 35 => 500, 36 => 500, + 37 => 833, 38 => 778, 39 => 333, 40 => 333, 41 => 333, + 42 => 500, 43 => 564, 44 => 250, 45 => 333, 46 => 250, + 47 => 278, 48 => 500, 49 => 500, 50 => 500, 51 => 500, + 52 => 500, 53 => 500, 54 => 500, 55 => 500, 56 => 500, + 57 => 500, 58 => 278, 59 => 278, 60 => 564, 61 => 564, + 62 => 564, 63 => 444, 64 => 921, 65 => 722, 66 => 667, + 67 => 667, 68 => 722, 69 => 611, 70 => 556, 71 => 722, + 72 => 722, 73 => 333, 74 => 389, 75 => 722, 76 => 611, + 77 => 889, 78 => 722, 79 => 722, 80 => 556, 81 => 722, + 82 => 667, 83 => 556, 84 => 611, 85 => 722, 86 => 722, + 87 => 944, 88 => 722, 89 => 722, 90 => 611, 91 => 333, + 92 => 278, 93 => 333, 94 => 469, 95 => 500, 96 => 333, + 97 => 444, 98 => 500, 99 => 444, 100 => 500, 101 => 444, + 102 => 333, 103 => 500, 104 => 500, 105 => 278, 106 => 278, + 107 => 500, 108 => 278, 109 => 778, 110 => 500, 111 => 500, + 112 => 500, 113 => 500, 114 => 333, 115 => 389, 116 => 278, + 117 => 500, 118 => 500, 119 => 722, 120 => 500, 121 => 500, + 122 => 444, 123 => 480, 124 => 200, 125 => 480, 126 => 541, + 161 => 333, 162 => 500, 163 => 500, 164 => 167, 165 => 500, + 166 => 500, 167 => 500, 168 => 500, 169 => 180, 170 => 444, + 171 => 500, 172 => 333, 173 => 333, 174 => 556, 175 => 556, + 177 => 500, 178 => 500, 179 => 500, 180 => 250, 182 => 453, + 183 => 350, 184 => 333, 185 => 444, 186 => 444, 187 => 500, + 188 => 1000, 189 => 1000, 191 => 444, 193 => 333, 194 => 333, + 195 => 333, 196 => 333, 197 => 333, 198 => 333, 199 => 333, + 200 => 333, 202 => 333, 203 => 333, 205 => 333, 206 => 333, + 207 => 333, 208 => 1000, 225 => 889, 227 => 276, 232 => 611, + 233 => 722, 234 => 889, 235 => 310, 241 => 667, 245 => 278, + 248 => 278, 249 => 500, 250 => 722, 251 => 500); +$this->widths['Times-Bold'] = array (32 => 250, 33 => 333, 34 => 555, 35 => 500, 36 => 500, + 37 => 1000, 38 => 833, 39 => 333, 40 => 333, 41 => 333, + 42 => 500, 43 => 570, 44 => 250, 45 => 333, 46 => 250, + 47 => 278, 48 => 500, 49 => 500, 50 => 500, 51 => 500, + 52 => 500, 53 => 500, 54 => 500, 55 => 500, 56 => 500, + 57 => 500, 58 => 333, 59 => 333, 60 => 570, 61 => 570, + 62 => 570, 63 => 500, 64 => 930, 65 => 722, 66 => 667, + 67 => 722, 68 => 722, 69 => 667, 70 => 611, 71 => 778, + 72 => 778, 73 => 389, 74 => 500, 75 => 778, 76 => 667, + 77 => 944, 78 => 722, 79 => 778, 80 => 611, 81 => 778, + 82 => 722, 83 => 556, 84 => 667, 85 => 722, 86 => 722, + 87 => 1000, 88 => 722, 89 => 722, 90 => 667, 91 => 333, + 92 => 278, 93 => 333, 94 => 581, 95 => 500, 96 => 333, + 97 => 500, 98 => 556, 99 => 444, 100 => 556, 101 => 444, + 102 => 333, 103 => 500, 104 => 556, 105 => 278, 106 => 333, + 107 => 556, 108 => 278, 109 => 833, 110 => 556, 111 => 500, + 112 => 556, 113 => 556, 114 => 444, 115 => 389, 116 => 333, + 117 => 556, 118 => 500, 119 => 722, 120 => 500, 121 => 500, + 122 => 444, 123 => 394, 124 => 220, 125 => 394, 126 => 520, + 161 => 333, 162 => 500, 163 => 500, 164 => 167, 165 => 500, + 166 => 500, 167 => 500, 168 => 500, 169 => 278, 170 => 500, + 171 => 500, 172 => 333, 173 => 333, 174 => 556, 175 => 556, + 177 => 500, 178 => 500, 179 => 500, 180 => 250, 182 => 540, + 183 => 350, 184 => 333, 185 => 500, 186 => 500, 187 => 500, + 188 => 1000, 189 => 1000, 191 => 500, 193 => 333, 194 => 333, + 195 => 333, 196 => 333, 197 => 333, 198 => 333, 199 => 333, + 200 => 333, 202 => 333, 203 => 333, 205 => 333, 206 => 333, + 207 => 333, 208 => 1000, 225 => 1000, 227 => 300, 232 => 667, + 233 => 778, 234 => 1000, 235 => 330, 241 => 722, 245 => 278, + 248 => 278, 249 => 500, 250 => 722, 251 => 556); +$this->widths['Times-Italic'] = array (32 => 250, 33 => 333, 34 => 420, 35 => 500, 36 => 500, + 37 => 833, 38 => 778, 39 => 333, 40 => 333, 41 => 333, + 42 => 500, 43 => 675, 44 => 250, 45 => 333, 46 => 250, + 47 => 278, 48 => 500, 49 => 500, 50 => 500, 51 => 500, + 52 => 500, 53 => 500, 54 => 500, 55 => 500, 56 => 500, + 57 => 500, 58 => 333, 59 => 333, 60 => 675, 61 => 675, + 62 => 675, 63 => 500, 64 => 920, 65 => 611, 66 => 611, + 67 => 667, 68 => 722, 69 => 611, 70 => 611, 71 => 722, + 72 => 722, 73 => 333, 74 => 444, 75 => 667, 76 => 556, + 77 => 833, 78 => 667, 79 => 722, 80 => 611, 81 => 722, + 82 => 611, 83 => 500, 84 => 556, 85 => 722, 86 => 611, + 87 => 833, 88 => 611, 89 => 556, 90 => 556, 91 => 389, + 92 => 278, 93 => 389, 94 => 422, 95 => 500, 96 => 333, + 97 => 500, 98 => 500, 99 => 444, 100 => 500, 101 => 444, + 102 => 278, 103 => 500, 104 => 500, 105 => 278, 106 => 278, + 107 => 444, 108 => 278, 109 => 722, 110 => 500, 111 => 500, + 112 => 500, 113 => 500, 114 => 389, 115 => 389, 116 => 278, + 117 => 500, 118 => 444, 119 => 667, 120 => 444, 121 => 444, + 122 => 389, 123 => 400, 124 => 275, 125 => 400, 126 => 541, + 161 => 389, 162 => 500, 163 => 500, 164 => 167, 165 => 500, + 166 => 500, 167 => 500, 168 => 500, 169 => 214, 170 => 556, + 171 => 500, 172 => 333, 173 => 333, 174 => 500, 175 => 500, + 177 => 500, 178 => 500, 179 => 500, 180 => 250, 182 => 523, + 183 => 350, 184 => 333, 185 => 556, 186 => 556, 187 => 500, + 188 => 889, 189 => 1000, 191 => 500, 193 => 333, 194 => 333, + 195 => 333, 196 => 333, 197 => 333, 198 => 333, 199 => 333, + 200 => 333, 202 => 333, 203 => 333, 205 => 333, 206 => 333, + 207 => 333, 208 => 889, 225 => 889, 227 => 276, 232 => 556, + 233 => 722, 234 => 944, 235 => 310, 241 => 667, 245 => 278, + 248 => 278, 249 => 500, 250 => 667, 251 => 500); +$this->widths['Times-BoldItalic'] = array (32 => 250, 33 => 389, 34 => 555, 35 => 500, 36 => 500, + 37 => 833, 38 => 778, 39 => 333, 40 => 333, 41 => 333, + 42 => 500, 43 => 570, 44 => 250, 45 => 333, 46 => 250, + 47 => 278, 48 => 500, 49 => 500, 50 => 500, 51 => 500, + 52 => 500, 53 => 500, 54 => 500, 55 => 500, 56 => 500, + 57 => 500, 58 => 333, 59 => 333, 60 => 570, 61 => 570, + 62 => 570, 63 => 500, 64 => 832, 65 => 667, 66 => 667, + 67 => 667, 68 => 722, 69 => 667, 70 => 667, 71 => 722, + 72 => 778, 73 => 389, 74 => 500, 75 => 667, 76 => 611, + 77 => 889, 78 => 722, 79 => 722, 80 => 611, 81 => 722, + 82 => 667, 83 => 556, 84 => 611, 85 => 722, 86 => 667, + 87 => 889, 88 => 667, 89 => 611, 90 => 611, 91 => 333, + 92 => 278, 93 => 333, 94 => 570, 95 => 500, 96 => 333, + 97 => 500, 98 => 500, 99 => 444, 100 => 500, 101 => 444, + 102 => 333, 103 => 500, 104 => 556, 105 => 278, 106 => 278, + 107 => 500, 108 => 278, 109 => 778, 110 => 556, 111 => 500, + 112 => 500, 113 => 500, 114 => 389, 115 => 389, 116 => 278, + 117 => 556, 118 => 444, 119 => 667, 120 => 500, 121 => 444, + 122 => 389, 123 => 348, 124 => 220, 125 => 348, 126 => 570, + 161 => 389, 162 => 500, 163 => 500, 164 => 167, 165 => 500, + 166 => 500, 167 => 500, 168 => 500, 169 => 278, 170 => 500, + 171 => 500, 172 => 333, 173 => 333, 174 => 556, 175 => 556, + 177 => 500, 178 => 500, 179 => 500, 180 => 250, 182 => 500, + 183 => 350, 184 => 333, 185 => 500, 186 => 500, 187 => 500, + 188 => 1000, 189 => 1000, 191 => 500, 193 => 333, 194 => 333, + 195 => 333, 196 => 333, 197 => 333, 198 => 333, 199 => 333, + 200 => 333, 202 => 333, 203 => 333, 205 => 333, 206 => 333, + 207 => 333, 208 => 1000, 225 => 944, 227 => 266, 232 => 611, + 233 => 722, 234 => 944, 235 => 300, 241 => 722, 245 => 278, + 248 => 278, 249 => 500, 250 => 722, 251 => 500); + +?> \ No newline at end of file diff --git a/lib/MECON/PDF/external/template.class.php b/lib/MECON/PDF/external/template.class.php new file mode 100755 index 0000000..539ddfe --- /dev/null +++ b/lib/MECON/PDF/external/template.class.php @@ -0,0 +1,222 @@ +tid = 0; + } + + function create() + { + $temp = $this->nexttid; + // Stores the next object ID within this template + $this->templ[$temp]['next'] = 0; + $this->nexttid ++; + return $temp; + } + + function size($tid, $width, $height) + { + $this->templ[$tid]["height"] = $height; + $this->templ[$tid]["width"] = $width; + return true; + } + + function rectangle($tid, $bottom, $left, $top, $right, $attrib = array()) + { + $temp = $this->pdf->_resolve_param($attrib); + $temp["type"] = "rectangle"; + $temp["top"] = $top; + $temp["left"] = $left; + $temp["bottom"] = $bottom; + $temp["right"] = $right; + return $this->_add_object($temp, $tid); + } + + function circle($tid, $cenx, $ceny, $radius, $attrib = array()) + { + $temp = $this->pdf->_resolve_param($attrib); + $temp["type"] = "circle"; + $temp["x"] = $cenx; + $temp["y"] = $ceny; + $temp["radius"] = $radius; + return $this->_add_object($temp, $tid); + } + + function line($tid, $x, $y, $attrib = array()) + { + $temp = $this->pdf->_resolve_param($attrib); + $temp["type"] = "line"; + $temp["x"] = $x; + $temp["y"] = $y; + return $this->_add_object($temp, $tid); + } + + function image($tid, $left, $bottom, $width, $height, $image, $attrib = array()) + { + $this->ifield($tid, $left, $bottom, $width, $height, false, $image, $attrib); + } + + function ifield($tid, $left, $bottom, $width, $height, $name, $default = false, $attrib = array()) + { + $temp = $this->pdf->_resolve_param($attrib); + $temp['type'] = "ifield"; + $temp['left'] = $left; + $temp['bottom'] = $bottom; + $temp['name'] = $name; + $temp['default'] = $default; + $temp['width'] = $width; + $temp['height'] = $height; + return $this->_add_object($temp, $tid); + } + + function text($tid, $left, $bottom, $text, $attrib = array()) + { + return $this->field($tid, $left, $bottom, false, $text, $attrib); + } + + function field($tid, $left, $bottom, $name, $default = '', $attrib = array()) + { + $temp = $this->pdf->_resolve_param($attrib); + $temp["type"] = "field"; + $temp["left"] = $left; + $temp["bottom"] = $bottom; + $temp["name"] = $name; + $temp["default"] = $default; + return $this->_add_object($temp, $tid); + } + + function paragraph($tid, $bottom, $left, $top, $right, $text, $attrib = array()) + { + return $this->pfield($tid, $bottom, $left, $top, $right, false, $text, $attrib); + } + + function pfield($tid, $bottom, $left, $top, $right, $name, $default = '', $attrib = array()) + { + $temp = $this->pdf->_resolve_param($attrib); + $temp['type'] = 'pfield'; + $temp['left'] = $left; + $temp['bottom'] = $bottom; + $temp['top'] = $top; + $temp['right'] = $right; + $temp['name'] = $name; + $temp['default'] = $default; + return $this->_add_object($temp, $tid); + } + + function place($tid, $page, $left, $bottom, $data = array()) + { + $ok = true; + foreach( $this->templ[$tid]["objects"] as $o ) { + switch ($o['type']) { + case 'rectangle' : + $ok = $ok && $this->pdf->draw_rectangle($bottom + $o["top"], + $left + $o["left"], + $bottom + $o["bottom"], + $left + $o["right"], + $page, + $o); + break; + + case 'circle' : + $ok = $ok && $this->pdf->draw_circle($left + $o['x'], + $bottom + $o['y'], + $o['radius'], + $page, + $o); + break; + + case 'line' : + foreach ($o['x'] as $key => $value) { + $o['x'][$key] += $left; + $o['y'][$key] += $bottom; + } + $ok = $ok && $this->pdf->draw_line($o['x'], + $o['y'], + $page, + $o); + break; + + case 'field' : + $temp = ($o['name'] === false) || !isset($data[$o['name']]) || !strlen($data[$o['name']]) ? $o['default'] : $data[$o['name']]; + $ok = $ok && $this->pdf->draw_text($left + $o['left'], + $bottom + $o['bottom'], + $temp, + $page, + $o); + break; + + case 'pfield' : + $temp = ($o['name'] === false) || !isset($data[$o['name']]) || !strlen($data[$o['name']]) ? $o['default'] : $data[$o['name']]; + $t = $this->pdf->draw_paragraph($bottom + $o['top'], + $left + $o['left'], + $bottom + $o['bottom'], + $left + $o['right'], + $temp, + $page, + $o); + if (is_string($t)) { + $ok = false; + $this->pdf->_push_error(6013, "Text overflowed available area: $t"); + } + break; + + case 'ifield' : + $temp = ($o['name'] === false) || empty($data[$o['name']]) ? $o['default'] : $data[$o['name']]; + if ($temp === false) { + break; + } + $id = $this->pdf->get_image_size($temp); + unset($o['scale']); + $o['scale']['x'] = $o['width'] / $id['width']; + $o['scale']['y'] = $o['height'] / $id['height']; + $ok = $ok && $this->pdf->image_place($temp, + $o['bottom'] + $bottom, + $o['left'] + $left, + $page, + $o); + break; + } + } + return $ok; + } + + /* Private methods + */ + + function _add_object($objarray, $tid) + { + $oid = $this->templ[$tid]["next"]; + $this->templ[$tid]["next"] ++; + $this->templ[$tid]["objects"][$oid] = $objarray; + return $oid; + } + +} +?> diff --git a/test/PDF/downs/down b/test/PDF/downs/down new file mode 100755 index 0000000..7bff19e --- /dev/null +++ b/test/PDF/downs/down @@ -0,0 +1,2 @@ +#!/bin/sh +wget http://bal747f.mecon.ar/~mmarrese/meconlib/test/PDF/prueba_pdf.php; mv -f prueba_pdf.php prueba_pdf.pdf;gv prueba_pdf.pdf diff --git a/test/PDF/downs/prueba_pdf.pdf b/test/PDF/downs/prueba_pdf.pdf new file mode 100644 index 0000000..580d69a Binary files /dev/null and b/test/PDF/downs/prueba_pdf.pdf differ diff --git a/test/PDF/prueba_pdf.php b/test/PDF/prueba_pdf.php new file mode 100755 index 0000000..6b6c819 --- /dev/null +++ b/test/PDF/prueba_pdf.php @@ -0,0 +1,21 @@ +seccion = 'Dir. General de Despacho y Mesa de Entradas y esto eso todo oooooooooooooooooooooooooooooo'; +$pdf->seccion = 'Dir. General de Despacho y Mesa de Entradas'; +$pdf->titulo = 'Alberto Giordano'; +$pdf->subtitulo = 'Filosofo Estilista, guacho pulenta si los hay'; +//$pdf->paginador = false; +//$pdf->fecha = '2/10/2003'; + + +$pdf->display(); + +?> diff --git a/www/images/pdf_logo.gif b/www/images/pdf_logo.gif new file mode 100644 index 0000000..52359f3 Binary files /dev/null and b/www/images/pdf_logo.gif differ diff --git a/www/images/pdf_logo.jpg b/www/images/pdf_logo.jpg new file mode 100644 index 0000000..b4f58b3 Binary files /dev/null and b/www/images/pdf_logo.jpg differ diff --git a/www/images/pdf_logo.png b/www/images/pdf_logo.png new file mode 100644 index 0000000..1251f85 Binary files /dev/null and b/www/images/pdf_logo.png differ