phpDocumentor SpoolTemplate
[ Back ] [ class tree: SpoolTemplate ] [ index: SpoolTemplate ] [ all elements ]

Source for file sptpl_clsPagePrinter.php

Documentation is available at sptpl_clsPagePrinter.php

  1. <?php
  2. /**
  3. * Page manager extension with support to printer (Windows box only)
  4. * It use the extension php_printer.dll to write out directly to
  5. * the printer
  6. *
  7. * Require:
  8. * aprint.php (class module used to print download it at
  9. * http://www.phpclasses.org/browse.html/package/1159.html )
  10. * sptpl_clsPageManager.php
  11. *
  12. * @copyright sptpl_clsPagePrinter.php is part of Sptpl project {@link http://www.andrioli.com/en/sptpl.html} and it is LGPL
  13. * @author Andrioli Darvin <darvin (inside) andrioli (dot) com>
  14. * @version $Header: d:\cvs/classistd/sptpl/sptpl_clsPagePrinter.php,v 2.9 2005/03/17 12:46:48 Darvin Exp $
  15. */
  16. /*
  17. * +-------------------------------------------------------------------------+
  18. * | Sptpl |
  19. * +-------------------------------------------------------------------------+
  20. * | Copyright (c) 2003-2005 Andrioli Darvin |
  21. * | Email <darvin (inside) andrioli (dot) com> |
  22. * | Web http://www.andrioli.com/en/sptpl.html |
  23. * | Download http://www.phpclasses.org/browse.html/package/1326.html |
  24. * | |
  25. * +-------------------------------------------------------------------------+
  26. * | This library is free software; you can redistribute it and/or modify |
  27. * | it under the terms of the GNU Lesser General Public License as |
  28. * | published by the Free Software Foundation; either version 2 of the |
  29. * | License, or (at your option) any later version. |
  30. * | |
  31. * | This library is distributed in the hope that it will be useful, but |
  32. * | WITHOUT ANY WARRANTY; without even the implied warranty of |
  33. * | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
  34. * | Lesser General Public License for more details. |
  35. * | |
  36. * | You should have received a copy of the GNU Lesser General Public |
  37. * | License along with this library; if not, write to the Free Software |
  38. * | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
  39. * +-------------------------------------------------------------------------+
  40. */
  41.  
  42. class CPagePrinter extends CPageMgr {
  43.  
  44. /**
  45. * Class Aprint instance
  46. * @var object APrint
  47. */
  48. var $clsAprint;
  49.  
  50. /**
  51. * The array contains the handlers returnt by Aprint's CreateFont
  52. * @var array
  53. * @see _DownloadFont()
  54. */
  55. var $FontsId;
  56. /**
  57. * Class constructor. Call the parent class (CPageMgr) constructor
  58. * and istance the Aprint module
  59. * @param object CDataStorage &$DataMgr Reference to the DataStorage istance
  60. * @access public
  61. */
  62. function CPagePrinter(&$DataMgr)
  63. {
  64. parent::CPageMgr(&$DataMgr);
  65. $this->Margins=array('top' =>500,
  66. 'bottom' =>300,
  67. 'left' =>100,
  68. 'right' =>100);
  69. $this->clsAprint=new Aprint();
  70. $this->clsAprint->SetPrintFooter(FALSE);
  71. $this->FontsId=array();
  72. }
  73.  
  74. /**
  75. * Create one default font named STANDARD
  76. * @access private
  77. */
  78. function _CreateDefaultFont()
  79. {
  80. $q="?"; // It makes happy my editor!!
  81. $XmlStr="<".$q."xml version='1.0' ".$q.">
  82. <font id='STANDARD' face='Arial' size='12' />
  83. ";
  84. $tmpRoot=new CXml2Array();
  85. $tmpRoot->LoadFromString($XmlStr);
  86. $this->NewFont($tmpRoot);
  87. }
  88.  
  89. /**
  90. * Create an istance of the CFont class based on configuration
  91. * file.
  92. * @param object CXml2Array Node with font configuration
  93. * @access public
  94. */
  95. function NewFont($node)
  96. {
  97. $tmpFont=new CPrFont($node);
  98. if(array_key_exists($tmpFont->GetId(),$this->Fonts))
  99. trigger_error('Font '.$tmpFont->GetId().' already exist',E_USER_ERROR);
  100. $this->Fonts[$tmpFont->GetId()]=$tmpFont;
  101. }
  102.  
  103. /**
  104. * Download the defined font to the printer. I must perform this
  105. * job after I opened the connection to the printer.
  106. * @access private
  107. */
  108. function _DownloadFont()
  109. {
  110. foreach($this->Fonts as $key => $tmpFont)
  111. {
  112. $Weight=($tmpFont->Bold)?800:400;
  113. // 25, allow to maint the standard font size, while the printer module has its own!
  114. $this->FontsId[$key]=$this->clsAprint->CreateFont($tmpFont->GetFace(),$tmpFont->GetHeight(),
  115. $tmpFont->GetWidth(),$Weight,
  116. $tmpFont->GetItalic(),$tmpFont->GetUnderline());
  117. }
  118. }
  119.  
  120. /**
  121. * Load margins setting from the configuration file
  122. * Default values are set by the class constructor.
  123. * Extend the base class
  124. * @param object CXml2Array
  125. * @access private
  126. *
  127. */
  128. function _SetMargins($Cfg)
  129. {
  130. // The parent class parse the configuration and load
  131. // the information, now using that information I set the
  132. // Aprint module
  133. parent::_SetMargins($Cfg);
  134. $this->clsAprint->SetMargin($this->Margins['top'],$this->Margins['bottom'],$this->Margins['left'],$this->Margins['right']);
  135. }
  136.  
  137.  
  138. /**
  139. * Check whether the margins are placed inside or outside the page
  140. * No check is made by this module. I haven't information about paper size.
  141. * The Aprint module will made the checks.
  142. */
  143. function CheckMargins()
  144. {
  145. }
  146.  
  147. /**
  148. * Start to printout the report. OPen the output file,
  149. * initialize some variable.
  150. * Notice: this module use the outfile as printer name
  151. * @param string $OutFile output printer name
  152. * @access public
  153. */
  154. function BeginReport($OutFile="")
  155. {
  156. $this->CurrentLine=MAXPAGEROWS+1;
  157. $this->CurrentPage=0;
  158. // Setup the callback. I don't understand why, but I can't do this
  159. // after istancing tha class Aprint in the constructor.
  160. // $this->clsAprint->SetCallBack('newpage',array(&$this,'NewPage'),array());
  161. $this->clsAprint->SetPrintFooter(FALSE);
  162. $this->clsAprint->OpenPrinter($OutFile);
  163. $this->clsAprint->SetAutoNewPage(FALSE);
  164. list($dimX,$dimY)=$this->clsAprint->GetPageSize();
  165. $this->PageSize['length']=$dimY;
  166. $this->PageSize['width']=$dimX;
  167. // Now I know the page size, I set the parameter to the base column
  168. $this->ColumnSet[0]->SetWidth($this->PageSize['width']-$this->Margins['left']-$this->Margins['right']); // page with
  169. $this->HeaderColSet[0]->SetWidth($this->PageSize['width']-$this->Margins['left']-$this->Margins['right']); // page with
  170. $this->FooterColSet[0]->SetWidth($this->PageSize['width']-$this->Margins['left']-$this->Margins['right']); // page with
  171. $this->_DownloadFont();
  172. $this->_OpenPage();
  173. $this->_StartReport();
  174. }
  175.  
  176. /**
  177. * Perform the requested job to end the report.
  178. * Print the end report text, close the current page and the output file
  179. * @access public
  180. */
  181. function CloseReport()
  182. {
  183. $this->_EndReport();
  184. $this->_ComposeRow($this->ColumnSet);
  185. $this->CurrentLine=$this->PageSize['length']-$this->Margins['bottom'];
  186. $this->_ClosePage();
  187. $this->clsAprint->run();
  188. }
  189.  
  190. /**
  191. * Begin a new page. Close the previous, if any,
  192. * and printout the 'openpage' text if specified
  193. *
  194. * @access public
  195. */
  196. function NewPage($FromComposeRow=FALSE)
  197. {
  198. // If this function is not called from composerow, but as page skip
  199. // in the middle of the page, before change the page, I close the
  200. // current text
  201. if(!$FromComposeRow)
  202. $this->_ComposeRow($this->ColumnSet);
  203.  
  204. if($this->CurrentPage)
  205. {
  206. $this->CurrentLine=$this->PageSize['length']-$this->Margins['bottom'];
  207. $this->_ClosePage();
  208. $this->clsAprint->NewPage();
  209. }
  210. // print "<br>".$this->CurrentPage;
  211. $this->_OpenPage();
  212. }
  213.  
  214. /**
  215. * Printout the closepage text (if any)
  216. * @access private
  217. */
  218. function _ClosePage()
  219. {
  220. if(array_key_exists('closepage',$this->Report))
  221. {
  222. $txt=$this->Report['closepage']->WriteOut($this);
  223. //$this->clsAprint->TextFooter(trim($txt));
  224. }
  225. }
  226.  
  227. /**
  228. * Now each column has its own text for the current row. This function
  229. * merge all texts from the columns and fill the PageData array.
  230. * Note a column may span over one or more row
  231. * @param array column set to print
  232. * @param bool the row to print is the footer? If so don't skip to the new page
  233. * @return bool return true if the function writes almost 1 row
  234. * @access private
  235. */
  236. function _ComposeRow($ColSet,$PageFooter=FALSE)
  237. {
  238. $nColumn=count($ColSet);
  239. $RowWritten=FALSE;
  240. /*
  241. if($PageFooter) {
  242. $GLOBALS['dbg']->pray($this);
  243. $GLOBALS['dbg']->Backtrace();
  244. die('prova');
  245. }
  246. */
  247. // Check each row to know the max height
  248. $maxHeight=0;
  249. for($i=0;$i<$nColumn;$i++)
  250. {
  251. assert('is_object($ColSet[$i])');
  252. $maxHeight=($ColSet[$i]->GetHeight()>$maxHeight)?$ColSet[$i]->GetHeight():$maxHeight;
  253. }
  254. if($this->CurrentLine+$maxHeight>($this->PageSize['length']-$this->Margins['bottom'])&&!$PageFooter)
  255. $this->NewPage(TRUE);
  256. $conta=0;
  257. $NewLinePos=0;
  258. for($i=0;$i<$nColumn;$i++)
  259. {
  260. // I've got one columns, check where it starts
  261. $posY=$this->CurrentLine;
  262. while($ColSet[$i]->HasAnotherText())
  263. {
  264. $LeftPos=$ColSet[$i]->GetLeftTextPos();
  265. $Text=$ColSet[$i]->GetText();
  266. $FontToUse=$ColSet[$i]->GetFontId();
  267. $this->clsAprint->TextXY($LeftPos,$posY,$Text,$this->FontsId[$FontToUse]);
  268. $posY+=$this->Fonts[$FontToUse]->GetHeight();
  269. }
  270. $NewLinePos=($NewLinePos>$posY)?$NewLinePos:$posY;
  271. }
  272. $this->CurrentLine=$NewLinePos;
  273. // Clear all used text
  274. for($i=0;$i<$nColumn;$i++)
  275. $ColSet[$i]->ClearText();
  276. return($RowWritten);
  277. }
  278.  
  279. }
  280. /**
  281. * PostScript output module. It requires the ps extension of PHP
  282. * and Aprint rel 2.0 or better
  283. * @package SpoolTemplate
  284. */
  285. class CPagePs extends CPageMgr
  286. {
  287.  
  288. /**
  289. * Class PsPrint instance
  290. * @var object PsPrint
  291. */
  292. var $clsPSprint;
  293.  
  294. /**
  295. * The array contains the handlers returnt by Aprint's CreateFont
  296. * @var array
  297. * @see _DownloadFont()
  298. */
  299. var $FontsId;
  300. /**
  301. * ps module handler, used to open an temporary file used by the font class. Note,
  302. * some fonts related functions don't work without an open file
  303. * @var resource
  304. * @see $TmpFileName
  305. */
  306. var $lclPs;
  307. /**
  308. * Temporary file name
  309. * @var string
  310. */
  311. var $TmpFileName;
  312. /**
  313. * Class constructor. Call the parent class (CPageMgr) constructor
  314. * and istance the Aprint module
  315. * @param object CDataStorage &$DataMgr Reference to the DataStorage istance
  316. * @access public
  317. */
  318. function CPagePs(&$DataMgr)
  319. {
  320. $this->TmpFileName='tmpps'.time();
  321. $this->lclPs=ps_new();
  322. if(!ps_open_file($this->lclPs, $this->TmpFileName))
  323. trigger_error('Error open file '.$this->TmpFileName,E_USER_ERROR);
  324. ps_begin_page($this->lclPs,500,200);
  325. parent::CPageMgr(&$DataMgr);
  326. // set the default margins and page size.
  327. $this->tblFormatIso=array( 'A3' => array( 'width' => 16840, 'length' => 23814),
  328. 'A4' => array( 'width' => 11520, 'length' => 16840),
  329. 'A5' => array( 'width' => 8391, 'length' => 11907),
  330. );
  331.  
  332. $this->PageFormat='A4';
  333. $this->Margins=array('top' =>200,
  334. 'bottom' =>200,
  335. 'left' =>40,
  336. 'right' =>40);
  337. $this->clsPSprint=new PSPrint();
  338. $this->clsPSprint->SetPrintFooter(FALSE);
  339. $this->FontsId=array();
  340. }
  341.  
  342. /**
  343. * Function executd at the end of the xml parsing. I run the final configuration
  344. * checks and complete the configration data
  345. * @access public
  346. */
  347. function EndParseXml()
  348. {
  349. $this->PageSize=$this->tblFormatIso[$this->PageFormat];
  350. $this->clsPSprint->SetPageSize($this->PageFormat,1);
  351. parent::EndParseXml();
  352. }
  353.  
  354. /**
  355. * Create one default font named STANDARD
  356. * @access private
  357. */
  358. function _CreateDefaultFont()
  359. {
  360. $q="?"; // It makes happy my editor!!
  361. $XmlStr="<".$q."xml version='1.0' ".$q.">
  362. <font id='STANDARD' face='Dustismo' size='12' />
  363. ";
  364. $tmpRoot=new CXml2Array();
  365. $tmpRoot->LoadFromString($XmlStr);
  366. $this->NewFont($tmpRoot);
  367. }
  368.  
  369. /**
  370. * Create an instance of the CFont class based on configuration
  371. * file.
  372. * @param object CXml2Array Node with font configuration
  373. * @access public
  374. */
  375. function NewFont($node)
  376. {
  377. $tmpFont=new CPsFont($node);
  378. if(array_key_exists($tmpFont->GetId(),$this->Fonts))
  379. trigger_error('Font '.$tmpFont->GetId().' already exist',E_USER_ERROR);
  380. // Set the ps handler
  381. $tmpFont->SetPsHandler($this->lclPs);
  382. $this->Fonts[$tmpFont->GetId()]=$tmpFont;
  383. }
  384.  
  385. /**
  386. * Download the defined font to the PostScript module. I must perform this
  387. * job after I opened the ps file.
  388. * @access private
  389. */
  390. function _DownloadFont()
  391. {
  392. foreach($this->Fonts as $key => $tmpFont)
  393. {
  394. $Weight=($tmpFont->Bold)?800:400;
  395. // 25, allow to maint the standard font size, while the printer module has its own!
  396. $this->FontsId[$key]=$this->clsPSprint->CreateFont($tmpFont->GetFace(),$tmpFont->GetHeight(),
  397. $tmpFont->GetWidth(),$Weight,
  398. $tmpFont->GetItalic(),$tmpFont->GetUnderline());
  399. }
  400. }
  401.  
  402. /**
  403. * Load margins setting from the configuration file
  404. * Default values are set by the class constructor.
  405. * Extend the base class
  406. * @param object CXml2Array
  407. * @access private
  408. *
  409. */
  410. function _SetMargins($Cfg)
  411. {
  412. // The parent class parse the configuration and load
  413. // the information, now using that information I set the
  414. // Aprint module
  415. parent::_SetMargins($Cfg);
  416. $this->clsPSprint->SetMargin($this->Margins['top'],$this->Margins['bottom'],$this->Margins['left'],$this->Margins['right']);
  417. }
  418.  
  419.  
  420. /**
  421. * Check whether the margins are placed inside or outside the page
  422. * No check is made by this module. I haven't information about paper size.
  423. * The Aprint module will made the checks.
  424. */
  425. function CheckMargins()
  426. {
  427. }
  428.  
  429. /**
  430. * Start to printout the report. OPen the output file,
  431. * initialize some variable.
  432. * Notice: this module use the outfile as printer name
  433. * @param string $OutFile output printer name
  434. * @access public
  435. */
  436. function BeginReport($OutFile="")
  437. {
  438. $this->CurrentLine=MAXPAGEROWS+1;
  439. $this->CurrentPage=0;
  440. $this->clsPSprint->SetPrintFooter(FALSE);
  441. $this->clsPSprint->OpenPrinter($OutFile);
  442. $this->clsPSprint->SetAutoNewPage(FALSE);
  443. // Now I know the page size, I set the parameter to the base column
  444. $this->ColumnSet[0]->SetWidth($this->PageSize['width']-$this->Margins['left']-$this->Margins['right']); // page with
  445. $this->HeaderColSet[0]->SetWidth($this->PageSize['width']-$this->Margins['left']-$this->Margins['right']); // page with
  446. $this->FooterColSet[0]->SetWidth($this->PageSize['width']-$this->Margins['left']-$this->Margins['right']); // page with
  447. $this->_DownloadFont();
  448. $this->_OpenPage();
  449. $this->_StartReport();
  450. }
  451.  
  452. /**
  453. * Perform the requested job to end the report.
  454. * Print the end report text, close the current page and the output file
  455. * @access public
  456. */
  457. function CloseReport()
  458. {
  459. $this->_EndReport();
  460. $this->_ComposeRow($this->ColumnSet);
  461. $this->CurrentLine=$this->PageSize['length']-$this->Margins['bottom']-100;
  462. $this->_ClosePage();
  463. $this->clsPSprint->run();
  464. ps_end_page($this->lclPs);
  465. ps_close($this->lclPs);
  466. if(file_exists($this->TmpFileName))
  467. unlink($this->TmpFileName);
  468. }
  469.  
  470. /**
  471. * Begin a new page. Close the previous, if any,
  472. * and printout the 'openpage' text if specified
  473. *
  474. * @access public
  475. */
  476. function NewPage($FromComposeRow=FALSE)
  477. {
  478. // If this function is not called from composerow, but as page skip
  479. // in the middle of the page, before change the page, I close the
  480. // current text
  481. if(!$FromComposeRow)
  482. $this->_ComposeRow($this->ColumnSet);
  483.  
  484. if($this->CurrentPage)
  485. {
  486. $this->CurrentLine=$this->PageSize['length']-$this->Margins['bottom']-100;
  487. $this->_ClosePage();
  488. $this->clsPSprint->NewPage();
  489. }
  490. // print "<br>".$this->CurrentPage;
  491. $this->_OpenPage();
  492. }
  493.  
  494. /**
  495. * Printout the closepage text (if any)
  496. * @access private
  497. */
  498. function _ClosePage()
  499. {
  500. if(array_key_exists('closepage',$this->Report))
  501. {
  502. $txt=$this->Report['closepage']->WriteOut($this);
  503. //$this->clsAprint->TextFooter(trim($txt));
  504. }
  505. }
  506.  
  507. /**
  508. * Now each column has its own text for the current row. This function
  509. * merge all texts from the columns and fill the PageData array.
  510. * Note a column may span over one or more row
  511. * @param array column set to print
  512. * @param bool the row to print is the footer or header? If so don't skip to the new page
  513. * @return bool return true if the function writes almost 1 row
  514. * @access private
  515. */
  516. function _ComposeRow($ColSet,$PageFooter=FALSE)
  517. {
  518. $nColumn=count($ColSet);
  519. $RowWritten=FALSE;
  520.  
  521. // Check each row to know the max height
  522. $maxHeight=0;
  523. for($i=0;$i<$nColumn;$i++)
  524. {
  525. assert('is_object($ColSet[$i])');
  526. $maxHeight=($ColSet[$i]->GetHeight()>$maxHeight)?$ColSet[$i]->GetHeight():$maxHeight;
  527. }
  528. if($this->CurrentLine+$maxHeight>($this->PageSize['length']-$this->Margins['bottom'])&&!$PageFooter)
  529. $this->NewPage(TRUE);
  530. $conta=0;
  531. $NewLinePos=0;
  532. for($i=0;$i<$nColumn;$i++)
  533. {
  534. // I've got one columns, check where it starts
  535. $posY=$this->CurrentLine;
  536. while($ColSet[$i]->HasAnotherText())
  537. {
  538. $LeftPos=$ColSet[$i]->GetLeftTextPos();
  539. $Text=$ColSet[$i]->GetText();
  540. $FontToUse=$ColSet[$i]->GetFontId();
  541. if(!($PageFooter&&$posY>1))
  542. $posY+=$this->Fonts[$FontToUse]->GetFontHeight($Text);
  543. $this->clsPSprint->TextXY($LeftPos,$posY,$Text,$this->FontsId[$FontToUse]);
  544. // echo "\n this->clsPSprint->TextXY($LeftPos,$posY,$Text,this->FontsId[$FontToUse]);";
  545. // $posY+=$this->Fonts[$FontToUse]->GetFontHeight();
  546. }
  547. $NewLinePos=($NewLinePos>$posY)?$NewLinePos:$posY;
  548. }
  549. $this->CurrentLine=$NewLinePos;
  550. // Clear all used text
  551. for($i=0;$i<$nColumn;$i++)
  552. $ColSet[$i]->ClearText();
  553. return($RowWritten);
  554. }
  555. }
  556.  
  557. ?>

Documentation generated on Mon, 28 Mar 2005 15:13:20 +0200 by phpDocumentor 1.3.0RC3