PageRenderTime 53ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/libs/PdfNFePHP.class.php

https://github.com/trsanabio/nfephp
PHP | 855 lines | 562 code | 21 blank | 272 comment | 103 complexity | f4fbb77b898033deb5c51449b71b00cf MD5 | raw file
Possible License(s): LGPL-3.0, LGPL-2.1, GPL-3.0
  1. <?php
  2. /**
  3. * Este arquivo é parte do projeto NFePHP - Nota Fiscal eletrônica em PHP.
  4. *
  5. * Este programa é um software livre: você pode redistribuir e/ou modificá-lo
  6. * sob os termos da Licença Pública Geral GNU como é publicada pela Fundação
  7. * para o Software Livre, na versão 3 da licença, ou qualquer versão posterior.
  8. * e/ou
  9. * sob os termos da Licença Pública Geral Menor GNU (LGPL) como é publicada pela
  10. * Fundação para o Software Livre, na versão 3 da licença, ou qualquer versão posterior.
  11. *
  12. * Este programa é distribuído na esperança que será útil, mas SEM NENHUMA
  13. * GARANTIA; nem mesmo a garantia explícita definida por qualquer VALOR COMERCIAL
  14. * ou de ADEQUAÇÃO PARA UM PROPÓSITO EM PARTICULAR,
  15. * veja a Licença Pública Geral GNU para mais detalhes.
  16. *
  17. * Você deve ter recebido uma cópia da Licença Publica GNU e da
  18. * Licença Pública Geral Menor GNU (LGPL) junto com este programa.
  19. * Caso contrário consulte
  20. * <http://www.fsfla.org/svnwiki/trad/GPLv3>
  21. * ou
  22. * <http://www.fsfla.org/svnwiki/trad/LGPLv3>.
  23. *
  24. * @package NFePHP
  25. * @name PdfNFePHP.class.php
  26. * @version 1.0.4
  27. * @license http://www.gnu.org/licenses/gpl.html GNU/GPL v.3
  28. * @license http://www.gnu.org/licenses/lgpl.html GNU/LGPL v.3
  29. * @copyright 2009-2011 &copy; NFePHP
  30. * @link http://www.nfephp.org/
  31. * @author Roberto L. Machado <linux.rlm at gmail dot com>
  32. *
  33. * Esta classe contêm todas as funções necessárias para a criação dos arquivos
  34. * PDF usando o FPDF padrão sem a necessidade de modificação ou de outras classes
  35. * auxiliares
  36. *
  37. */
  38. require_once('FPDF/fpdf.php');
  39. class PdfNFePHP extends FPDF {
  40. private $T128; // tabela de codigos 128
  41. private $ABCset=""; // conjunto de caracteres legiveis em 128
  42. private $Aset=""; // grupo A do conjunto de de caracteres legiveis
  43. private $Bset=""; // grupo B do conjunto de caracteres legiveis
  44. private $Cset=""; // grupo C do conjunto de caracteres legiveis
  45. private $SetFrom; // converter de
  46. private $SetTo; // converter para
  47. private $JStart = array("A"=>103, "B"=>104, "C"=>105); // Caracteres de seleção do grupo 128
  48. private $JSwap = array("A"=>101, "B"=>100, "C"=>99); // Caracteres de troca de grupo
  49. function __construct($orientation='P',$unit='mm',$format='A4') {
  50. //passar parametros para a classe principal
  51. parent::FPDF($orientation,$unit,$format);
  52. // composição dos caracteres do barcode 128
  53. $this->T128[] = array(2, 1, 2, 2, 2, 2); //0 : [ ]
  54. $this->T128[] = array(2, 2, 2, 1, 2, 2); //1 : [!]
  55. $this->T128[] = array(2, 2, 2, 2, 2, 1); //2 : ["]
  56. $this->T128[] = array(1, 2, 1, 2, 2, 3); //3 : [#]
  57. $this->T128[] = array(1, 2, 1, 3, 2, 2); //4 : [$]
  58. $this->T128[] = array(1, 3, 1, 2, 2, 2); //5 : [%]
  59. $this->T128[] = array(1, 2, 2, 2, 1, 3); //6 : [&]
  60. $this->T128[] = array(1, 2, 2, 3, 1, 2); //7 : [']
  61. $this->T128[] = array(1, 3, 2, 2, 1, 2); //8 : [(]
  62. $this->T128[] = array(2, 2, 1, 2, 1, 3); //9 : [)]
  63. $this->T128[] = array(2, 2, 1, 3, 1, 2); //10 : [*]
  64. $this->T128[] = array(2, 3, 1, 2, 1, 2); //11 : [+]
  65. $this->T128[] = array(1, 1, 2, 2, 3, 2); //12 : [,]
  66. $this->T128[] = array(1, 2, 2, 1, 3, 2); //13 : [-]
  67. $this->T128[] = array(1, 2, 2, 2, 3, 1); //14 : [.]
  68. $this->T128[] = array(1, 1, 3, 2, 2, 2); //15 : [/]
  69. $this->T128[] = array(1, 2, 3, 1, 2, 2); //16 : [0]
  70. $this->T128[] = array(1, 2, 3, 2, 2, 1); //17 : [1]
  71. $this->T128[] = array(2, 2, 3, 2, 1, 1); //18 : [2]
  72. $this->T128[] = array(2, 2, 1, 1, 3, 2); //19 : [3]
  73. $this->T128[] = array(2, 2, 1, 2, 3, 1); //20 : [4]
  74. $this->T128[] = array(2, 1, 3, 2, 1, 2); //21 : [5]
  75. $this->T128[] = array(2, 2, 3, 1, 1, 2); //22 : [6]
  76. $this->T128[] = array(3, 1, 2, 1, 3, 1); //23 : [7]
  77. $this->T128[] = array(3, 1, 1, 2, 2, 2); //24 : [8]
  78. $this->T128[] = array(3, 2, 1, 1, 2, 2); //25 : [9]
  79. $this->T128[] = array(3, 2, 1, 2, 2, 1); //26 : [:]
  80. $this->T128[] = array(3, 1, 2, 2, 1, 2); //27 : [;]
  81. $this->T128[] = array(3, 2, 2, 1, 1, 2); //28 : [<]
  82. $this->T128[] = array(3, 2, 2, 2, 1, 1); //29 : [=]
  83. $this->T128[] = array(2, 1, 2, 1, 2, 3); //30 : [>]
  84. $this->T128[] = array(2, 1, 2, 3, 2, 1); //31 : [?]
  85. $this->T128[] = array(2, 3, 2, 1, 2, 1); //32 : [@]
  86. $this->T128[] = array(1, 1, 1, 3, 2, 3); //33 : [A]
  87. $this->T128[] = array(1, 3, 1, 1, 2, 3); //34 : [B]
  88. $this->T128[] = array(1, 3, 1, 3, 2, 1); //35 : [C]
  89. $this->T128[] = array(1, 1, 2, 3, 1, 3); //36 : [D]
  90. $this->T128[] = array(1, 3, 2, 1, 1, 3); //37 : [E]
  91. $this->T128[] = array(1, 3, 2, 3, 1, 1); //38 : [F]
  92. $this->T128[] = array(2, 1, 1, 3, 1, 3); //39 : [G]
  93. $this->T128[] = array(2, 3, 1, 1, 1, 3); //40 : [H]
  94. $this->T128[] = array(2, 3, 1, 3, 1, 1); //41 : [I]
  95. $this->T128[] = array(1, 1, 2, 1, 3, 3); //42 : [J]
  96. $this->T128[] = array(1, 1, 2, 3, 3, 1); //43 : [K]
  97. $this->T128[] = array(1, 3, 2, 1, 3, 1); //44 : [L]
  98. $this->T128[] = array(1, 1, 3, 1, 2, 3); //45 : [M]
  99. $this->T128[] = array(1, 1, 3, 3, 2, 1); //46 : [N]
  100. $this->T128[] = array(1, 3, 3, 1, 2, 1); //47 : [O]
  101. $this->T128[] = array(3, 1, 3, 1, 2, 1); //48 : [P]
  102. $this->T128[] = array(2, 1, 1, 3, 3, 1); //49 : [Q]
  103. $this->T128[] = array(2, 3, 1, 1, 3, 1); //50 : [R]
  104. $this->T128[] = array(2, 1, 3, 1, 1, 3); //51 : [S]
  105. $this->T128[] = array(2, 1, 3, 3, 1, 1); //52 : [T]
  106. $this->T128[] = array(2, 1, 3, 1, 3, 1); //53 : [U]
  107. $this->T128[] = array(3, 1, 1, 1, 2, 3); //54 : [V]
  108. $this->T128[] = array(3, 1, 1, 3, 2, 1); //55 : [W]
  109. $this->T128[] = array(3, 3, 1, 1, 2, 1); //56 : [X]
  110. $this->T128[] = array(3, 1, 2, 1, 1, 3); //57 : [Y]
  111. $this->T128[] = array(3, 1, 2, 3, 1, 1); //58 : [Z]
  112. $this->T128[] = array(3, 3, 2, 1, 1, 1); //59 : [[]
  113. $this->T128[] = array(3, 1, 4, 1, 1, 1); //60 : [\]
  114. $this->T128[] = array(2, 2, 1, 4, 1, 1); //61 : []]
  115. $this->T128[] = array(4, 3, 1, 1, 1, 1); //62 : [^]
  116. $this->T128[] = array(1, 1, 1, 2, 2, 4); //63 : [_]
  117. $this->T128[] = array(1, 1, 1, 4, 2, 2); //64 : [`]
  118. $this->T128[] = array(1, 2, 1, 1, 2, 4); //65 : [a]
  119. $this->T128[] = array(1, 2, 1, 4, 2, 1); //66 : [b]
  120. $this->T128[] = array(1, 4, 1, 1, 2, 2); //67 : [c]
  121. $this->T128[] = array(1, 4, 1, 2, 2, 1); //68 : [d]
  122. $this->T128[] = array(1, 1, 2, 2, 1, 4); //69 : [e]
  123. $this->T128[] = array(1, 1, 2, 4, 1, 2); //70 : [f]
  124. $this->T128[] = array(1, 2, 2, 1, 1, 4); //71 : [g]
  125. $this->T128[] = array(1, 2, 2, 4, 1, 1); //72 : [h]
  126. $this->T128[] = array(1, 4, 2, 1, 1, 2); //73 : [i]
  127. $this->T128[] = array(1, 4, 2, 2, 1, 1); //74 : [j]
  128. $this->T128[] = array(2, 4, 1, 2, 1, 1); //75 : [k]
  129. $this->T128[] = array(2, 2, 1, 1, 1, 4); //76 : [l]
  130. $this->T128[] = array(4, 1, 3, 1, 1, 1); //77 : [m]
  131. $this->T128[] = array(2, 4, 1, 1, 1, 2); //78 : [n]
  132. $this->T128[] = array(1, 3, 4, 1, 1, 1); //79 : [o]
  133. $this->T128[] = array(1, 1, 1, 2, 4, 2); //80 : [p]
  134. $this->T128[] = array(1, 2, 1, 1, 4, 2); //81 : [q]
  135. $this->T128[] = array(1, 2, 1, 2, 4, 1); //82 : [r]
  136. $this->T128[] = array(1, 1, 4, 2, 1, 2); //83 : [s]
  137. $this->T128[] = array(1, 2, 4, 1, 1, 2); //84 : [t]
  138. $this->T128[] = array(1, 2, 4, 2, 1, 1); //85 : [u]
  139. $this->T128[] = array(4, 1, 1, 2, 1, 2); //86 : [v]
  140. $this->T128[] = array(4, 2, 1, 1, 1, 2); //87 : [w]
  141. $this->T128[] = array(4, 2, 1, 2, 1, 1); //88 : [x]
  142. $this->T128[] = array(2, 1, 2, 1, 4, 1); //89 : [y]
  143. $this->T128[] = array(2, 1, 4, 1, 2, 1); //90 : [z]
  144. $this->T128[] = array(4, 1, 2, 1, 2, 1); //91 : [{]
  145. $this->T128[] = array(1, 1, 1, 1, 4, 3); //92 : [|]
  146. $this->T128[] = array(1, 1, 1, 3, 4, 1); //93 : [}]
  147. $this->T128[] = array(1, 3, 1, 1, 4, 1); //94 : [~]
  148. $this->T128[] = array(1, 1, 4, 1, 1, 3); //95 : [DEL]
  149. $this->T128[] = array(1, 1, 4, 3, 1, 1); //96 : [FNC3]
  150. $this->T128[] = array(4, 1, 1, 1, 1, 3); //97 : [FNC2]
  151. $this->T128[] = array(4, 1, 1, 3, 1, 1); //98 : [SHIFT]
  152. $this->T128[] = array(1, 1, 3, 1, 4, 1); //99 : [Cswap]
  153. $this->T128[] = array(1, 1, 4, 1, 3, 1); //100 : [Bswap]
  154. $this->T128[] = array(3, 1, 1, 1, 4, 1); //101 : [Aswap]
  155. $this->T128[] = array(4, 1, 1, 1, 3, 1); //102 : [FNC1]
  156. $this->T128[] = array(2, 1, 1, 4, 1, 2); //103 : [Astart]
  157. $this->T128[] = array(2, 1, 1, 2, 1, 4); //104 : [Bstart]
  158. $this->T128[] = array(2, 1, 1, 2, 3, 2); //105 : [Cstart]
  159. $this->T128[] = array(2, 3, 3, 1, 1, 1); //106 : [STOP]
  160. $this->T128[] = array(2, 1); //107 : [END BAR]
  161. for ($i = 32; $i <= 95; $i++) { // conjunto de caracteres
  162. $this->ABCset .= chr($i);
  163. }
  164. $this->Aset = $this->ABCset;
  165. $this->Bset = $this->ABCset;
  166. for ($i = 0; $i <= 31; $i++) {
  167. $this->ABCset .= chr($i);
  168. $this->Aset .= chr($i);
  169. }
  170. for ($i = 96; $i <= 126; $i++) {
  171. $this->ABCset .= chr($i);
  172. $this->Bset .= chr($i);
  173. }
  174. $this->Cset="0123456789";
  175. for ($i=0; $i<96; $i++) { // convertendo grupos A & B
  176. @$this->SetFrom["A"] .= chr($i);
  177. @$this->SetFrom["B"] .= chr($i + 32);
  178. @$this->SetTo["A"] .= chr(($i < 32) ? $i+64 : $i-32);
  179. @$this->SetTo["B"] .= chr($i);
  180. }
  181. }//fim __construct
  182. /**
  183. * Code128
  184. * Imprime barcode 128
  185. * @package FPDF
  186. * @name Code128
  187. * @version 1.0
  188. * @author Roland Gautier
  189. */
  190. public function Code128($x,$y,$code,$w,$h) {
  191. $Aguid="";
  192. $Bguid="";
  193. $Cguid="";
  194. for ($i=0; $i < strlen($code); $i++) {
  195. $needle=substr($code,$i,1);
  196. $Aguid .= ((strpos($this->Aset,$needle)===FALSE) ? "N" : "O");
  197. $Bguid .= ((strpos($this->Bset,$needle)===FALSE) ? "N" : "O");
  198. $Cguid .= ((strpos($this->Cset,$needle)===FALSE) ? "N" : "O");
  199. }
  200. $SminiC = "OOOO";
  201. $IminiC = 4;
  202. $crypt = "";
  203. while ($code > "") {
  204. $i = strpos($Cguid,$SminiC);
  205. if ($i!==FALSE) {
  206. $Aguid [$i] = "N";
  207. $Bguid [$i] = "N";
  208. }
  209. if (substr($Cguid,0,$IminiC) == $SminiC) {
  210. $crypt .= chr(($crypt > "") ? $this->JSwap["C"] : $this->JStart["C"]);
  211. $made = strpos($Cguid,"N");
  212. if ($made === FALSE) $made = strlen($Cguid);
  213. if (fmod($made,2)==1) $made--;
  214. for ($i=0; $i < $made; $i += 2) $crypt .= chr(strval(substr($code,$i,2)));
  215. $jeu = "C";
  216. } else {
  217. $madeA = strpos($Aguid,"N");
  218. if ($madeA === FALSE) $madeA = strlen($Aguid);
  219. $madeB = strpos($Bguid,"N");
  220. if ($madeB === FALSE) $madeB = strlen($Bguid);
  221. $made = (($madeA < $madeB) ? $madeB : $madeA );
  222. $jeu = (($madeA < $madeB) ? "B" : "A" );
  223. $jeuguid = $jeu . "guid";
  224. $crypt .= chr(($crypt > "") ? $this->JSwap["$jeu"] : $this->JStart["$jeu"]);
  225. $crypt .= strtr(substr($code, 0,$made), $this->SetFrom[$jeu], $this->SetTo[$jeu]);
  226. }
  227. $code = substr($code,$made);
  228. $Aguid = substr($Aguid,$made);
  229. $Bguid = substr($Bguid,$made);
  230. $Cguid = substr($Cguid,$made);
  231. }
  232. $check=ord($crypt[0]);
  233. for ($i=0; $i<strlen($crypt); $i++) {
  234. $check += (ord($crypt[$i]) * $i);
  235. }
  236. $check %= 103;
  237. $crypt .= chr($check) . chr(106) . chr(107);
  238. $i = (strlen($crypt) * 11) - 8;
  239. $modul = $w/$i;
  240. for ($i=0; $i<strlen($crypt); $i++) {
  241. $c = $this->T128[ord($crypt[$i])];
  242. for ($j=0; $j<count($c); $j++) {
  243. $this->Rect($x,$y,$c[$j]*$modul,$h,"F");
  244. $x += ($c[$j++]+$c[$j])*$modul;
  245. }
  246. }
  247. } //fim Code128
  248. /**
  249. * Rotate
  250. * Rotaciona para impressão paisagem (landscape)
  251. * @package FPDF
  252. * @name Rotate
  253. * @version 1.0
  254. * @author Oliver
  255. * @param number $angle
  256. * @param number $x
  257. * @param number $y
  258. */
  259. public function Rotate($angle,$x=-1,$y=-1) {
  260. if($x==-1){
  261. $x=$this->x;
  262. }
  263. if($y==-1){
  264. $y=$this->y;
  265. }
  266. if( isset( $this->angle ) && $this->angle != 0){
  267. $this->_out('Q');
  268. }
  269. $this->angle=$angle;
  270. if($angle!=0){
  271. $angle*=M_PI/180;
  272. $c=cos($angle);
  273. $s=sin($angle);
  274. $cx=$x*$this->k;
  275. $cy=($this->h-$y)*$this->k;
  276. $this->_out(sprintf('q %.5F %.5F %.5F %.5F %.2F %.2F cm 1 0 0 1 %.2F %.2F cm',$c,$s,-$s,$c,$cx,$cy,-$cx,-$cy));
  277. }
  278. } //fim função rotate
  279. /**
  280. * RoundedRect
  281. * Desenha um retangulo com cantos arredondados
  282. * @package FPDF
  283. * @name RoundedRect
  284. * @version 1.0
  285. * @author Maxime Delorme & Christophe Prugnaud
  286. * @param number $x
  287. * @param number $y
  288. * @param number $w
  289. * @param number $h
  290. * @param number $r
  291. * @param string $corners
  292. * @param string $style
  293. */
  294. public function RoundedRect($x, $y, $w, $h, $r, $corners = '1234', $style = '') {
  295. $k = $this->k;
  296. $hp = $this->h;
  297. if($style=='F'){
  298. $op='f';
  299. } elseif($style=='FD' || $style=='DF') {
  300. $op='B';
  301. } else {
  302. $op='S';
  303. }
  304. $MyArc = 4/3 * (sqrt(2) - 1);
  305. $this->_out(sprintf('%.2F %.2F m',($x+$r)*$k,($hp-$y)*$k ));
  306. $xc = $x+$w-$r;
  307. $yc = $y+$r;
  308. $this->_out(sprintf('%.2F %.2F l', $xc*$k,($hp-$y)*$k ));
  309. if (strpos($corners, '2')===false){
  310. $this->_out(sprintf('%.2F %.2F l', ($x+$w)*$k,($hp-$y)*$k ));
  311. } else {
  312. $this->_arc($xc + $r*$MyArc, $yc - $r, $xc + $r, $yc - $r*$MyArc, $xc + $r, $yc);
  313. }
  314. $xc = $x+$w-$r;
  315. $yc = $y+$h-$r;
  316. $this->_out(sprintf('%.2F %.2F l',($x+$w)*$k,($hp-$yc)*$k));
  317. if (strpos($corners, '3')===false){
  318. $this->_out(sprintf('%.2F %.2F l',($x+$w)*$k,($hp-($y+$h))*$k));
  319. } else {
  320. $this->_arc($xc + $r, $yc + $r*$MyArc, $xc + $r*$MyArc, $yc + $r, $xc, $yc + $r);
  321. }
  322. $xc = $x+$r;
  323. $yc = $y+$h-$r;
  324. $this->_out(sprintf('%.2F %.2F l',$xc*$k,($hp-($y+$h))*$k));
  325. if (strpos($corners, '4')===false){
  326. $this->_out(sprintf('%.2F %.2F l',($x)*$k,($hp-($y+$h))*$k));
  327. } else {
  328. $this->_arc($xc - $r*$MyArc, $yc + $r, $xc - $r, $yc + $r*$MyArc, $xc - $r, $yc);
  329. }
  330. $xc = $x+$r ;
  331. $yc = $y+$r;
  332. $this->_out(sprintf('%.2F %.2F l',($x)*$k,($hp-$yc)*$k ));
  333. if (strpos($corners, '1')===false){
  334. $this->_out(sprintf('%.2F %.2F l',($x)*$k,($hp-$y)*$k ));
  335. $this->_out(sprintf('%.2F %.2F l',($x+$r)*$k,($hp-$y)*$k ));
  336. }else{
  337. $this->_arc($xc - $r, $yc - $r*$MyArc, $xc - $r*$MyArc, $yc - $r, $xc, $yc - $r);
  338. }
  339. $this->_out($op);
  340. }//fim RoundedRect
  341. /**
  342. * _arc
  343. * Desenha o arco para arredondar o canto do retangulo
  344. * @package FPDF
  345. * @name _arc
  346. * @version 1.0
  347. * @author Maxime Delorme & Christophe Prugnaud
  348. * @param number $x1
  349. * @param number $y1
  350. * @param number $x2
  351. * @param number $y2
  352. * @param number $x3
  353. * @param number $y3
  354. */
  355. private function _arc($x1, $y1, $x2, $y2, $x3, $y3){
  356. $h = $this->h;
  357. $this->_out(sprintf('%.2F %.2F %.2F %.2F %.2F %.2F c ', $x1*$this->k, ($h-$y1)*$this->k,$x2*$this->k, ($h-$y2)*$this->k, $x3*$this->k, ($h-$y3)*$this->k));
  358. } // fim _Arc
  359. /**
  360. * DashedRect
  361. * Desenha um retangulo com linhas tracejadas
  362. * @package FPDF
  363. * @name DashedRect
  364. * @version 1.0
  365. * @author Antoine Michéa
  366. * @param number $x1
  367. * @param number $y1
  368. * @param number $x2
  369. * @param number $y2
  370. * @param number $width
  371. * @param number $nb
  372. */
  373. public function DashedRect($x1, $y1, $x2, $y2, $width=1, $nb=15) {
  374. $this->SetLineWidth($width);
  375. $longueur=abs($x1-$x2);
  376. $hauteur=abs($y1-$y2);
  377. if($longueur>$hauteur) {
  378. $Pointilles=($longueur/$nb)/2;
  379. }
  380. else {
  381. $Pointilles=($hauteur/$nb)/2;
  382. }
  383. for($i=$x1;$i<=$x2;$i+=$Pointilles+$Pointilles) {
  384. for($j=$i;$j<=($i+$Pointilles);$j++) {
  385. if($j<=($x2-1)) {
  386. $this->Line($j,$y1,$j+1,$y1);
  387. $this->Line($j,$y2,$j+1,$y2);
  388. }
  389. }
  390. }
  391. for($i=$y1;$i<=$y2;$i+=$Pointilles+$Pointilles) {
  392. for($j=$i;$j<=($i+$Pointilles);$j++) {
  393. if($j<=($y2-1)) {
  394. $this->Line($x1,$j,$x1,$j+1);
  395. $this->Line($x2,$j,$x2,$j+1);
  396. }
  397. }
  398. }
  399. }//fim DashedRect
  400. /**
  401. * drawTextBox
  402. * Monta uma caixa de texto
  403. * @package FPDF
  404. * @name drawTextBox
  405. * @version 1.0
  406. * @author Darren Gates & Adrian Tufa
  407. * @param string $strText
  408. * @param number $w
  409. * @param number $h
  410. * @param string $align
  411. * @param string $valign
  412. * @param boolean $border
  413. */
  414. public function drawTextBox($strText, $w, $h, $align='L', $valign='T', $border=true) {
  415. $xi=$this->GetX();
  416. $yi=$this->GetY();
  417. $hrow=$this->FontSize;
  418. $textrows=$this->_drawRows($w,$hrow,$strText,0,$align,0,0,0);
  419. $maxrows=floor($h/$this->FontSize);
  420. $rows=min($textrows,$maxrows);
  421. $dy=0;
  422. if (strtoupper($valign)=='M'){
  423. $dy=($h-$rows*$this->FontSize)/2;
  424. }
  425. if (strtoupper($valign)=='B'){
  426. $dy=$h-$rows*$this->FontSize;
  427. }
  428. $this->SetY($yi+$dy);
  429. $this->SetX($xi);
  430. $this->_drawRows($w,$hrow,$strText,0,$align,false,$rows,1);
  431. if ($border){
  432. $this->Rect($xi,$yi,$w,$h);
  433. }
  434. }// fim drawTextBox
  435. /**
  436. * _drawRows
  437. * Insere linhas de texto na caixa
  438. * @package FPDF
  439. * @name _drawRows
  440. * @version 1.0
  441. * @author Darren Gates & Adrian Tufa
  442. * @param number $w
  443. * @param number $h
  444. * @param string $txt
  445. * @param string $border
  446. * @param string $align
  447. * @param boolean $fill
  448. * @param number $maxline
  449. * @param number $prn
  450. * @return int
  451. */
  452. private function _drawRows($w, $h, $txt, $border=0, $align='J', $fill=false, $maxline=0, $prn=0){
  453. $cw=&$this->CurrentFont['cw'];
  454. if($w==0){
  455. $w=$this->w-$this->rMargin-$this->x;
  456. }
  457. $wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
  458. $s=str_replace("\r",'',$txt);
  459. $nb=strlen($s);
  460. if($nb>0 && $s[$nb-1]=="\n"){
  461. $nb--;
  462. }
  463. $b=0;
  464. if($border){
  465. if($border==1){
  466. $border='LTRB';
  467. $b='LRT';
  468. $b2='LR';
  469. } else{
  470. $b2='';
  471. if(is_int(strpos($border,'L'))){
  472. $b2.='L';
  473. }
  474. if(is_int(strpos($border,'R'))){
  475. $b2.='R';
  476. }
  477. $b=is_int(strpos($border,'T')) ? $b2.'T' : $b2;
  478. }
  479. }
  480. $sep=-1;
  481. $i=0;
  482. $j=0;
  483. $l=0;
  484. $ns=0;
  485. $nl=1;
  486. while($i<$nb){
  487. $c=$s[$i];
  488. if($c=="\n"){
  489. if($this->ws>0){
  490. $this->ws=0;
  491. if ($prn==1){
  492. $this->_out('0 Tw');
  493. }
  494. }
  495. if ($prn==1) {
  496. $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill);
  497. }
  498. $i++;
  499. $sep=-1;
  500. $j=$i;
  501. $l=0;
  502. $ns=0;
  503. $nl++;
  504. if($border && $nl==2){
  505. $b=$b2;
  506. }
  507. if ( $maxline && $nl > $maxline ){
  508. return substr($s,$i);
  509. }
  510. continue;
  511. }
  512. if($c==' '){
  513. $sep=$i;
  514. $ls=$l;
  515. $ns++;
  516. }
  517. $l+=$cw[$c];
  518. if($l>$wmax){
  519. if($sep==-1){
  520. if($i==$j){
  521. $i++;
  522. }
  523. if($this->ws>0){
  524. $this->ws=0;
  525. if ($prn==1){
  526. $this->_out('0 Tw');
  527. }
  528. }
  529. if ($prn==1) {
  530. $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill);
  531. }
  532. } else {
  533. if($align=='J') {
  534. $this->ws=($ns>1) ? ($wmax-$ls)/1000*$this->FontSize/($ns-1) : 0;
  535. if ($prn==1){
  536. $this->_out(sprintf('%.3F Tw',$this->ws*$this->k));
  537. }
  538. }
  539. if ($prn==1){
  540. $this->Cell($w,$h,substr($s,$j,$sep-$j),$b,2,$align,$fill);
  541. }
  542. $i=$sep+1;
  543. }
  544. $sep=-1;
  545. $j=$i;
  546. $l=0;
  547. $ns=0;
  548. $nl++;
  549. if($border && $nl==2){
  550. $b=$b2;
  551. }
  552. if ( $maxline && $nl > $maxline ){
  553. return substr($s,$i);
  554. }
  555. } else {
  556. $i++;
  557. }
  558. }
  559. if($this->ws>0) {
  560. $this->ws=0;
  561. if ($prn==1){
  562. $this->_out('0 Tw');
  563. }
  564. }
  565. if($border && is_int(strpos($border,'B'))){
  566. $b.='B';
  567. }
  568. if ($prn==1) {
  569. $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill);
  570. }
  571. $this->x=$this->lMargin;
  572. return $nl;
  573. }//fim _drawRows
  574. /**
  575. * WordWrap
  576. * Quebra o texto para caber na caixa
  577. * @package FPDF
  578. * @name WordWrap
  579. * @version 1.0
  580. * @author Ron Korving
  581. * @param type $text
  582. * @param type $maxwidth
  583. * @return int
  584. */
  585. public function WordWrap(&$text, $maxwidth){
  586. $text = trim($text);
  587. if ($text===''){
  588. return 0;
  589. }
  590. $space = $this->GetStringWidth(' ');
  591. $lines = explode("\n", $text);
  592. $text = '';
  593. $count = 0;
  594. foreach ($lines as $line) {
  595. $words = preg_split('/ +/', $line);
  596. $width = 0;
  597. foreach ($words as $word) {
  598. $wordwidth = $this->GetStringWidth($word);
  599. if ($wordwidth > $maxwidth){
  600. // Word is too long, we cut it
  601. for($i=0; $i<strlen($word); $i++){
  602. $wordwidth = $this->GetStringWidth(substr($word, $i, 1));
  603. if($width + $wordwidth <= $maxwidth){
  604. $width += $wordwidth;
  605. $text .= substr($word, $i, 1);
  606. } else {
  607. $width = $wordwidth;
  608. $text = rtrim($text)."\n".substr($word, $i, 1);
  609. $count++;
  610. }
  611. }
  612. } elseif($width + $wordwidth <= $maxwidth) {
  613. $width += $wordwidth + $space;
  614. $text .= $word.' ';
  615. } else {
  616. $width = $wordwidth + $space;
  617. $text = rtrim($text)."\n".$word.' ';
  618. $count++;
  619. }
  620. }
  621. $text = rtrim($text)."\n";
  622. $count++;
  623. }
  624. $text = rtrim($text);
  625. return $count;
  626. } //fim WordWrap
  627. /**
  628. * CellFit
  629. * Celula com escala horizontal caso o texto seja muito largo
  630. * @package FPDF
  631. * @name CellFit
  632. * @version 1.0
  633. * @author Patrick Benny
  634. * @param number $w
  635. * @param number $h
  636. * @param string $txt
  637. * @param number $border
  638. * @param number $ln
  639. * @param string $align
  640. * @param boolean $fill
  641. * @param string $link
  642. * @param boolean $scale
  643. * @param boolean $force
  644. */
  645. public function CellFit($w, $h=0, $txt='', $border=0, $ln=0, $align='', $fill=false, $link='', $scale=false, $force=true){
  646. $str_width=$this->GetStringWidth($txt);
  647. if($w==0){
  648. $w = $this->w-$this->rMargin-$this->x;
  649. }
  650. $ratio = ($w-$this->cMargin*2)/$str_width;
  651. $fit = ($ratio < 1 || ($ratio > 1 && $force));
  652. if ($fit){
  653. if ($scale){
  654. //Calcula a escala horizontal
  655. $horiz_scale=$ratio*100.0;
  656. //Ajusta a escala horizontal
  657. $this->_out(sprintf('BT %.2F Tz ET',$horiz_scale));
  658. } else {
  659. //Calcula o espaçamento de caracteres em pontos
  660. $char_space=($w-$this->cMargin*2-$str_width)/max($this->_MBGetStringLength($txt)-1,1)*$this->k;
  661. //Ajusta o espaçamento de caracteres
  662. $this->_out(sprintf('BT %.2F Tc ET',$char_space));
  663. }
  664. //Sobrescreve o alinhamento informado (desde que o texto caiba na celula)
  665. $align='';
  666. }
  667. //Passa para o método cell
  668. $this->Cell($w,$h,$txt,$border,$ln,$align,$fill,$link);
  669. //Reseta o espaçamento de caracteres e a escala horizontal
  670. if ($fit){
  671. $this->_out('BT '.($scale ? '100 Tz' : '0 Tc').' ET');
  672. }
  673. }//fim CellFit
  674. /**
  675. * CellFitScale
  676. * Celula com escalamento horizontal somente se necessário
  677. * @package FPDF
  678. * @name CellFitScale
  679. * @version 1.0
  680. * @author Patrick Benny
  681. * @param number $w
  682. * @param number $h
  683. * @param string $txt
  684. * @param number $border
  685. * @param number $ln
  686. * @param string $align
  687. * @param boolean $fill
  688. * @param string $link
  689. */
  690. public function CellFitScale($w, $h=0, $txt='', $border=0, $ln=0, $align='', $fill=false, $link=''){
  691. $this->CellFit($w,$h,$txt,$border,$ln,$align,$fill,$link,true,false);
  692. }
  693. /**
  694. * CellFitScaleForce
  695. * Celula com escalamento forçado
  696. * @package FPDF
  697. * @name CellFitScaleForce
  698. * @version 1.0
  699. * @author Patrick Benny
  700. * @param number $w
  701. * @param number $h
  702. * @param string $txt
  703. * @param number $border
  704. * @param number $ln
  705. * @param string $align
  706. * @param boolean $fill
  707. * @param string $link
  708. */
  709. public function CellFitScaleForce($w, $h=0, $txt='', $border=0, $ln=0, $align='', $fill=false, $link=''){
  710. $this->CellFit($w,$h,$txt,$border,$ln,$align,$fill,$link,true,true);
  711. }
  712. /**
  713. * CellFitSpace
  714. * Celula com espaçamento de caracteres somente se necessário
  715. * @package FPDF
  716. * @name CellFitSpace
  717. * @version 1.0
  718. * @author Patrick Benny
  719. * @param number $w
  720. * @param number $h
  721. * @param string $txt
  722. * @param number $border
  723. * @param number $ln
  724. * @param string $align
  725. * @param boolean $fill
  726. * @param string $link
  727. */
  728. public function CellFitSpace($w, $h=0, $txt='', $border=0, $ln=0, $align='', $fill=false, $link=''){
  729. $this->CellFit($w,$h,$txt,$border,$ln,$align,$fill,$link,false,false);
  730. }
  731. /**
  732. * CellFitSpaceForce
  733. * Celula com espaçamento de caracteres forçado
  734. * @package FPDF
  735. * @name CellFitSpaceForce
  736. * @version 1.0
  737. * @author Patrick Benny
  738. * @param number $w
  739. * @param number $h
  740. * @param string $txt
  741. * @param number $border
  742. * @param number $ln
  743. * @param string $align
  744. * @param boolean $fill
  745. * @param string $link
  746. */
  747. public function CellFitSpaceForce($w, $h=0, $txt='', $border=0, $ln=0, $align='', $fill=false, $link=''){
  748. $this->CellFit($w,$h,$txt,$border,$ln,$align,$fill,$link,false,true);
  749. }
  750. /**
  751. * _MBGetStringLength
  752. * Patch para trabalhar com textos de duplo byte CJK
  753. * @package FPDF
  754. * @name _MBGetStringLength
  755. * @version 1.0
  756. * @author Patrick Benny
  757. * @param string $s
  758. * @return int
  759. */
  760. private function _MBGetStringLength($s){
  761. if($this->CurrentFont['type']=='Type0'){
  762. $len = 0;
  763. $nbbytes = strlen($s);
  764. for ($i = 0; $i < $nbbytes; $i++){
  765. if (ord($s[$i])<128){
  766. $len++;
  767. } else {
  768. $len++;
  769. $i++;
  770. }
  771. }
  772. return $len;
  773. } else {
  774. return strlen($s);
  775. }
  776. }
  777. /**
  778. * DashedLine
  779. * Desenha uma linha horizontal tracejada com o FPDF
  780. * @package NFePHP
  781. * @name DashedHLine
  782. * @version 1.0.1
  783. * @author Roberto L. Machado <linux.rlm at gmail dot com>
  784. * @param number $x Posição horizontal inicial, em mm
  785. * @param number $y Posição vertical inicial, em mm
  786. * @param number $w Comprimento da linha, em mm
  787. * @param number $h Espessura da linha, em mm
  788. * @param number $n Numero de traços na seção da linha com o comprimento $w
  789. * @return none
  790. */
  791. public function DashedHLine($x,$y,$w,$h,$n) {
  792. $this->SetDrawColor(110);
  793. $this->SetLineWidth($h);
  794. $wDash=($w/$n)/2; // comprimento dos traços
  795. for( $i=$x; $i<=$x+$w; $i += $wDash+$wDash ) {
  796. for( $j=$i; $j<= ($i+$wDash); $j++ ) {
  797. if( $j <= ($x+$w-1) ) {
  798. $this->Line($j,$y,$j+1,$y);
  799. }
  800. }
  801. }
  802. $this->SetDrawColor(0);
  803. } //fim função DashedHLine
  804. /**
  805. * DashedVLine
  806. * Desenha uma linha vertical tracejada com o FPDF
  807. * @package NFePHP
  808. * @name DashedVLine
  809. * @version 1.0
  810. * @author Roberto L. Machado <linux.rlm at gmail dot com>
  811. * @author Guilherme Calabria Filho <guiga86 at gmail dot com>
  812. * @param number $x Posição horizontal inicial, em mm
  813. * @param number $y Posição vertical inicial, em mm
  814. * @param number $w Comprimento da linha, em mm
  815. * @param number $yfinal Espessura da linha, em mm
  816. * @param number $n Numero de traços na seção da linha com o comprimento $w
  817. * @return none
  818. */
  819. public function DashedVLine($x,$y,$w,$yfinal,$n) {
  820. $this->SetLineWidth($w);
  821. //Organizando valores
  822. if($y>$yfinal) {
  823. $aux = $yfinal;
  824. $yfinal = $y;
  825. $y = $aux;
  826. }
  827. while($y<$yfinal&&$n>0){
  828. $this->Line($x,$y,$x,$y+1);
  829. $y += 3;
  830. $n--;
  831. }
  832. } //fim função DashedVLine
  833. } //fim da classe PdfNFe
  834. ?>