- <?php
- /**
- * Page manager extension with support to printer (Windows box only)
- * It use the extension php_printer.dll to write out directly to
- * the printer
- *
- * Require:
- * aprint.php (class module used to print download it at
- * http://www.phpclasses.org/browse.html/package/1159.html )
- * sptpl_clsPageManager.php
- *
- * @copyright sptpl_clsPagePrinter.php is part of Sptpl project {@link http://www.andrioli.com/en/sptpl.html} and it is LGPL
- * @author Andrioli Darvin <darvin (inside) andrioli (dot) com>
- * @version $Header: d:\cvs/classistd/sptpl/sptpl_clsPagePrinter.php,v 2.9 2005/03/17 12:46:48 Darvin Exp $
- */
- /*
- * +-------------------------------------------------------------------------+
- * | Sptpl |
- * +-------------------------------------------------------------------------+
- * | Copyright (c) 2003-2005 Andrioli Darvin |
- * | Email <darvin (inside) andrioli (dot) com> |
- * | Web http://www.andrioli.com/en/sptpl.html |
- * | Download http://www.phpclasses.org/browse.html/package/1326.html |
- * | |
- * +-------------------------------------------------------------------------+
- * | This library is free software; you can redistribute it and/or modify |
- * | it under the terms of the GNU Lesser General Public License as |
- * | published by the Free Software Foundation; either version 2 of the |
- * | License, or (at your option) any later version. |
- * | |
- * | This library is distributed in the hope that it will be useful, but |
- * | WITHOUT ANY WARRANTY; without even the implied warranty of |
- * | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
- * | Lesser General Public License for more details. |
- * | |
- * | You should have received a copy of the GNU Lesser General Public |
- * | License along with this library; if not, write to the Free Software |
- * | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
- * +-------------------------------------------------------------------------+
- */
-
- class CPagePrinter extends CPageMgr {
-
- /**
- * Class Aprint instance
- * @var object APrint
- */
- var $clsAprint;
-
- /**
- * The array contains the handlers returnt by Aprint's CreateFont
- * @var array
- * @see _DownloadFont()
- */
- var $FontsId;
- /**
- * Class constructor. Call the parent class (CPageMgr) constructor
- * and istance the Aprint module
- * @param object CDataStorage &$DataMgr Reference to the DataStorage istance
- * @access public
- */
- function CPagePrinter(&$DataMgr)
- {
- parent::CPageMgr(&$DataMgr);
- $this->Margins=array('top' =>500,
- 'bottom' =>300,
- 'left' =>100,
- 'right' =>100);
- $this->clsAprint=new Aprint();
- $this->clsAprint->SetPrintFooter(FALSE);
- $this->FontsId=array();
- }
-
- /**
- * Create one default font named STANDARD
- * @access private
- */
- function _CreateDefaultFont()
- {
- $q="?"; // It makes happy my editor!!
- $XmlStr="<".$q."xml version='1.0' ".$q.">
- <font id='STANDARD' face='Arial' size='12' />
- ";
- $tmpRoot=new CXml2Array();
- $tmpRoot->LoadFromString($XmlStr);
- $this->NewFont($tmpRoot);
- }
-
- /**
- * Create an istance of the CFont class based on configuration
- * file.
- * @param object CXml2Array Node with font configuration
- * @access public
- */
- function NewFont($node)
- {
- $tmpFont=new CPrFont($node);
- if(array_key_exists($tmpFont->GetId(),$this->Fonts))
- trigger_error('Font '.$tmpFont->GetId().' already exist',E_USER_ERROR);
- $this->Fonts[$tmpFont->GetId()]=$tmpFont;
- }
-
- /**
- * Download the defined font to the printer. I must perform this
- * job after I opened the connection to the printer.
- * @access private
- */
- function _DownloadFont()
- {
- foreach($this->Fonts as $key => $tmpFont)
- {
- $Weight=($tmpFont->Bold)?800:400;
- // 25, allow to maint the standard font size, while the printer module has its own!
- $this->FontsId[$key]=$this->clsAprint->CreateFont($tmpFont->GetFace(),$tmpFont->GetHeight(),
- $tmpFont->GetWidth(),$Weight,
- $tmpFont->GetItalic(),$tmpFont->GetUnderline());
- }
- }
-
- /**
- * Load margins setting from the configuration file
- * Default values are set by the class constructor.
- * Extend the base class
- * @param object CXml2Array
- * @access private
- *
- */
- function _SetMargins($Cfg)
- {
- // The parent class parse the configuration and load
- // the information, now using that information I set the
- // Aprint module
- parent::_SetMargins($Cfg);
- $this->clsAprint->SetMargin($this->Margins['top'],$this->Margins['bottom'],$this->Margins['left'],$this->Margins['right']);
- }
-
-
- /**
- * Check whether the margins are placed inside or outside the page
- * No check is made by this module. I haven't information about paper size.
- * The Aprint module will made the checks.
- */
- function CheckMargins()
- {
- }
-
- /**
- * Start to printout the report. OPen the output file,
- * initialize some variable.
- * Notice: this module use the outfile as printer name
- * @param string $OutFile output printer name
- * @access public
- */
- function BeginReport($OutFile="")
- {
- $this->CurrentLine=MAXPAGEROWS+1;
- $this->CurrentPage=0;
- // Setup the callback. I don't understand why, but I can't do this
- // after istancing tha class Aprint in the constructor.
- // $this->clsAprint->SetCallBack('newpage',array(&$this,'NewPage'),array());
- $this->clsAprint->SetPrintFooter(FALSE);
- $this->clsAprint->OpenPrinter($OutFile);
- $this->clsAprint->SetAutoNewPage(FALSE);
- list($dimX,$dimY)=$this->clsAprint->GetPageSize();
- $this->PageSize['length']=$dimY;
- $this->PageSize['width']=$dimX;
- // Now I know the page size, I set the parameter to the base column
- $this->ColumnSet[0]->SetWidth($this->PageSize['width']-$this->Margins['left']-$this->Margins['right']); // page with
- $this->HeaderColSet[0]->SetWidth($this->PageSize['width']-$this->Margins['left']-$this->Margins['right']); // page with
- $this->FooterColSet[0]->SetWidth($this->PageSize['width']-$this->Margins['left']-$this->Margins['right']); // page with
- $this->_DownloadFont();
- $this->_OpenPage();
- $this->_StartReport();
- }
-
- /**
- * Perform the requested job to end the report.
- * Print the end report text, close the current page and the output file
- * @access public
- */
- function CloseReport()
- {
- $this->_EndReport();
- $this->_ComposeRow($this->ColumnSet);
- $this->CurrentLine=$this->PageSize['length']-$this->Margins['bottom'];
- $this->_ClosePage();
- $this->clsAprint->run();
- }
-
- /**
- * Begin a new page. Close the previous, if any,
- * and printout the 'openpage' text if specified
- *
- * @access public
- */
- function NewPage($FromComposeRow=FALSE)
- {
- // If this function is not called from composerow, but as page skip
- // in the middle of the page, before change the page, I close the
- // current text
- if(!$FromComposeRow)
- $this->_ComposeRow($this->ColumnSet);
-
- if($this->CurrentPage)
- {
- $this->CurrentLine=$this->PageSize['length']-$this->Margins['bottom'];
- $this->_ClosePage();
- $this->clsAprint->NewPage();
- }
- // print "<br>".$this->CurrentPage;
- $this->_OpenPage();
- }
-
- /**
- * Printout the closepage text (if any)
- * @access private
- */
- function _ClosePage()
- {
- if(array_key_exists('closepage',$this->Report))
- {
- $txt=$this->Report['closepage']->WriteOut($this);
- //$this->clsAprint->TextFooter(trim($txt));
- }
- }
-
- /**
- * Now each column has its own text for the current row. This function
- * merge all texts from the columns and fill the PageData array.
- * Note a column may span over one or more row
- * @param array column set to print
- * @param bool the row to print is the footer? If so don't skip to the new page
- * @return bool return true if the function writes almost 1 row
- * @access private
- */
- function _ComposeRow($ColSet,$PageFooter=FALSE)
- {
- $nColumn=count($ColSet);
- $RowWritten=FALSE;
- /*
- if($PageFooter) {
- $GLOBALS['dbg']->pray($this);
- $GLOBALS['dbg']->Backtrace();
- die('prova');
- }
- */
- // Check each row to know the max height
- $maxHeight=0;
- for($i=0;$i<$nColumn;$i++)
- {
- assert('is_object($ColSet[$i])');
- $maxHeight=($ColSet[$i]->GetHeight()>$maxHeight)?$ColSet[$i]->GetHeight():$maxHeight;
- }
-
- if($this->CurrentLine+$maxHeight>($this->PageSize['length']-$this->Margins['bottom'])&&!$PageFooter)
- $this->NewPage(TRUE);
-
- $conta=0;
- $NewLinePos=0;
- for($i=0;$i<$nColumn;$i++)
- {
- // I've got one columns, check where it starts
- $posY=$this->CurrentLine;
- while($ColSet[$i]->HasAnotherText())
- {
- $LeftPos=$ColSet[$i]->GetLeftTextPos();
- $Text=$ColSet[$i]->GetText();
- $FontToUse=$ColSet[$i]->GetFontId();
- $this->clsAprint->TextXY($LeftPos,$posY,$Text,$this->FontsId[$FontToUse]);
- $posY+=$this->Fonts[$FontToUse]->GetHeight();
- }
- $NewLinePos=($NewLinePos>$posY)?$NewLinePos:$posY;
- }
- $this->CurrentLine=$NewLinePos;
- // Clear all used text
- for($i=0;$i<$nColumn;$i++)
- $ColSet[$i]->ClearText();
- return($RowWritten);
- }
-
- }
- /**
- * PostScript output module. It requires the ps extension of PHP
- * and Aprint rel 2.0 or better
- * @package SpoolTemplate
- */
- class CPagePs extends CPageMgr
- {
-
- /**
- * Class PsPrint instance
- * @var object PsPrint
- */
- var $clsPSprint;
-
- /**
- * The array contains the handlers returnt by Aprint's CreateFont
- * @var array
- * @see _DownloadFont()
- */
- var $FontsId;
- /**
- * ps module handler, used to open an temporary file used by the font class. Note,
- * some fonts related functions don't work without an open file
- * @var resource
- * @see $TmpFileName
- */
- var $lclPs;
- /**
- * Temporary file name
- * @var string
- */
- var $TmpFileName;
- /**
- * Class constructor. Call the parent class (CPageMgr) constructor
- * and istance the Aprint module
- * @param object CDataStorage &$DataMgr Reference to the DataStorage istance
- * @access public
- */
- function CPagePs(&$DataMgr)
- {
- $this->TmpFileName='tmpps'.time();
- $this->lclPs=ps_new();
- if(!ps_open_file($this->lclPs, $this->TmpFileName))
- trigger_error('Error open file '.$this->TmpFileName,E_USER_ERROR);
- ps_begin_page($this->lclPs,500,200);
- parent::CPageMgr(&$DataMgr);
- // set the default margins and page size.
- $this->tblFormatIso=array( 'A3' => array( 'width' => 16840, 'length' => 23814),
- 'A4' => array( 'width' => 11520, 'length' => 16840),
- 'A5' => array( 'width' => 8391, 'length' => 11907),
- );
-
- $this->PageFormat='A4';
- $this->Margins=array('top' =>200,
- 'bottom' =>200,
- 'left' =>40,
- 'right' =>40);
- $this->clsPSprint=new PSPrint();
- $this->clsPSprint->SetPrintFooter(FALSE);
- $this->FontsId=array();
- }
-
- /**
- * Function executd at the end of the xml parsing. I run the final configuration
- * checks and complete the configration data
- * @access public
- */
- function EndParseXml()
- {
- $this->PageSize=$this->tblFormatIso[$this->PageFormat];
- $this->clsPSprint->SetPageSize($this->PageFormat,1);
- parent::EndParseXml();
- }
-
- /**
- * Create one default font named STANDARD
- * @access private
- */
- function _CreateDefaultFont()
- {
- $q="?"; // It makes happy my editor!!
- $XmlStr="<".$q."xml version='1.0' ".$q.">
- <font id='STANDARD' face='Dustismo' size='12' />
- ";
- $tmpRoot=new CXml2Array();
- $tmpRoot->LoadFromString($XmlStr);
- $this->NewFont($tmpRoot);
- }
-
- /**
- * Create an instance of the CFont class based on configuration
- * file.
- * @param object CXml2Array Node with font configuration
- * @access public
- */
- function NewFont($node)
- {
- $tmpFont=new CPsFont($node);
- if(array_key_exists($tmpFont->GetId(),$this->Fonts))
- trigger_error('Font '.$tmpFont->GetId().' already exist',E_USER_ERROR);
- // Set the ps handler
- $tmpFont->SetPsHandler($this->lclPs);
- $this->Fonts[$tmpFont->GetId()]=$tmpFont;
- }
-
- /**
- * Download the defined font to the PostScript module. I must perform this
- * job after I opened the ps file.
- * @access private
- */
- function _DownloadFont()
- {
- foreach($this->Fonts as $key => $tmpFont)
- {
- $Weight=($tmpFont->Bold)?800:400;
- // 25, allow to maint the standard font size, while the printer module has its own!
- $this->FontsId[$key]=$this->clsPSprint->CreateFont($tmpFont->GetFace(),$tmpFont->GetHeight(),
- $tmpFont->GetWidth(),$Weight,
- $tmpFont->GetItalic(),$tmpFont->GetUnderline());
- }
- }
-
- /**
- * Load margins setting from the configuration file
- * Default values are set by the class constructor.
- * Extend the base class
- * @param object CXml2Array
- * @access private
- *
- */
- function _SetMargins($Cfg)
- {
- // The parent class parse the configuration and load
- // the information, now using that information I set the
- // Aprint module
- parent::_SetMargins($Cfg);
- $this->clsPSprint->SetMargin($this->Margins['top'],$this->Margins['bottom'],$this->Margins['left'],$this->Margins['right']);
- }
-
-
- /**
- * Check whether the margins are placed inside or outside the page
- * No check is made by this module. I haven't information about paper size.
- * The Aprint module will made the checks.
- */
- function CheckMargins()
- {
- }
-
- /**
- * Start to printout the report. OPen the output file,
- * initialize some variable.
- * Notice: this module use the outfile as printer name
- * @param string $OutFile output printer name
- * @access public
- */
- function BeginReport($OutFile="")
- {
- $this->CurrentLine=MAXPAGEROWS+1;
- $this->CurrentPage=0;
- $this->clsPSprint->SetPrintFooter(FALSE);
- $this->clsPSprint->OpenPrinter($OutFile);
- $this->clsPSprint->SetAutoNewPage(FALSE);
- // Now I know the page size, I set the parameter to the base column
- $this->ColumnSet[0]->SetWidth($this->PageSize['width']-$this->Margins['left']-$this->Margins['right']); // page with
- $this->HeaderColSet[0]->SetWidth($this->PageSize['width']-$this->Margins['left']-$this->Margins['right']); // page with
- $this->FooterColSet[0]->SetWidth($this->PageSize['width']-$this->Margins['left']-$this->Margins['right']); // page with
- $this->_DownloadFont();
- $this->_OpenPage();
- $this->_StartReport();
- }
-
- /**
- * Perform the requested job to end the report.
- * Print the end report text, close the current page and the output file
- * @access public
- */
- function CloseReport()
- {
- $this->_EndReport();
- $this->_ComposeRow($this->ColumnSet);
- $this->CurrentLine=$this->PageSize['length']-$this->Margins['bottom']-100;
- $this->_ClosePage();
- $this->clsPSprint->run();
- ps_end_page($this->lclPs);
- ps_close($this->lclPs);
- if(file_exists($this->TmpFileName))
- unlink($this->TmpFileName);
- }
-
- /**
- * Begin a new page. Close the previous, if any,
- * and printout the 'openpage' text if specified
- *
- * @access public
- */
- function NewPage($FromComposeRow=FALSE)
- {
- // If this function is not called from composerow, but as page skip
- // in the middle of the page, before change the page, I close the
- // current text
- if(!$FromComposeRow)
- $this->_ComposeRow($this->ColumnSet);
-
- if($this->CurrentPage)
- {
- $this->CurrentLine=$this->PageSize['length']-$this->Margins['bottom']-100;
- $this->_ClosePage();
- $this->clsPSprint->NewPage();
- }
- // print "<br>".$this->CurrentPage;
- $this->_OpenPage();
- }
-
- /**
- * Printout the closepage text (if any)
- * @access private
- */
- function _ClosePage()
- {
- if(array_key_exists('closepage',$this->Report))
- {
- $txt=$this->Report['closepage']->WriteOut($this);
- //$this->clsAprint->TextFooter(trim($txt));
- }
- }
-
- /**
- * Now each column has its own text for the current row. This function
- * merge all texts from the columns and fill the PageData array.
- * Note a column may span over one or more row
- * @param array column set to print
- * @param bool the row to print is the footer or header? If so don't skip to the new page
- * @return bool return true if the function writes almost 1 row
- * @access private
- */
- function _ComposeRow($ColSet,$PageFooter=FALSE)
- {
- $nColumn=count($ColSet);
- $RowWritten=FALSE;
-
- // Check each row to know the max height
- $maxHeight=0;
- for($i=0;$i<$nColumn;$i++)
- {
- assert('is_object($ColSet[$i])');
- $maxHeight=($ColSet[$i]->GetHeight()>$maxHeight)?$ColSet[$i]->GetHeight():$maxHeight;
- }
-
- if($this->CurrentLine+$maxHeight>($this->PageSize['length']-$this->Margins['bottom'])&&!$PageFooter)
- $this->NewPage(TRUE);
-
- $conta=0;
- $NewLinePos=0;
- for($i=0;$i<$nColumn;$i++)
- {
- // I've got one columns, check where it starts
- $posY=$this->CurrentLine;
- while($ColSet[$i]->HasAnotherText())
- {
- $LeftPos=$ColSet[$i]->GetLeftTextPos();
- $Text=$ColSet[$i]->GetText();
- $FontToUse=$ColSet[$i]->GetFontId();
- if(!($PageFooter&&$posY>1))
- $posY+=$this->Fonts[$FontToUse]->GetFontHeight($Text);
- $this->clsPSprint->TextXY($LeftPos,$posY,$Text,$this->FontsId[$FontToUse]);
- // echo "\n this->clsPSprint->TextXY($LeftPos,$posY,$Text,this->FontsId[$FontToUse]);";
- // $posY+=$this->Fonts[$FontToUse]->GetFontHeight();
- }
- $NewLinePos=($NewLinePos>$posY)?$NewLinePos:$posY;
- }
- $this->CurrentLine=$NewLinePos;
- // Clear all used text
- for($i=0;$i<$nColumn;$i++)
- $ColSet[$i]->ClearText();
- return($RowWritten);
- }
- }
-
- ?>