You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

464 lines
14KB

  1. <?php
  2. class directw
  3. {
  4. var $mpdf = null;
  5. public function __construct(mPDF $mpdf)
  6. {
  7. $this->mpdf = $mpdf;
  8. }
  9. function Write($h, $txt, $currentx = 0, $link = '', $directionality = 'ltr', $align = '')
  10. {
  11. if (!$align) {
  12. if ($directionality == 'rtl') {
  13. $align = 'R';
  14. } else {
  15. $align = 'L';
  16. }
  17. }
  18. if ($h == 0) {
  19. $this->mpdf->SetLineHeight();
  20. $h = $this->mpdf->lineheight;
  21. }
  22. //Output text in flowing mode
  23. $w = $this->mpdf->w - $this->mpdf->rMargin - $this->mpdf->x;
  24. $wmax = ($w - ($this->mpdf->cMarginL + $this->mpdf->cMarginR));
  25. $s = str_replace("\r", '', $txt);
  26. if ($this->mpdf->usingCoreFont) {
  27. $nb = strlen($s);
  28. } else {
  29. $nb = mb_strlen($s, $this->mpdf->mb_enc);
  30. // handle single space character
  31. if (($nb == 1) && $s == " ") {
  32. $this->mpdf->x += $this->mpdf->GetStringWidth($s);
  33. return;
  34. }
  35. }
  36. $sep = -1;
  37. $i = 0;
  38. $j = 0;
  39. $l = 0;
  40. $nl = 1;
  41. if (!$this->mpdf->usingCoreFont) {
  42. if (preg_match("/([" . $this->mpdf->pregRTLchars . "])/u", $txt)) {
  43. $this->mpdf->biDirectional = true;
  44. } // *RTL*
  45. while ($i < $nb) {
  46. //Get next character
  47. $c = mb_substr($s, $i, 1, $this->mpdf->mb_enc);
  48. if ($c == "\n") {
  49. // WORD SPACING
  50. $this->mpdf->ResetSpacing();
  51. //Explicit line break
  52. $tmp = rtrim(mb_substr($s, $j, $i - $j, $this->mpdf->mb_enc));
  53. $this->mpdf->Cell($w, $h, $tmp, 0, 2, $align, $fill, $link);
  54. $i++;
  55. $sep = -1;
  56. $j = $i;
  57. $l = 0;
  58. if ($nl == 1) {
  59. if ($currentx != 0)
  60. $this->mpdf->x = $currentx;
  61. else
  62. $this->mpdf->x = $this->mpdf->lMargin;
  63. $w = $this->mpdf->w - $this->mpdf->rMargin - $this->mpdf->x;
  64. $wmax = ($w - ($this->mpdf->cMarginL + $this->mpdf->cMarginR));
  65. }
  66. $nl++;
  67. continue;
  68. }
  69. if ($c == " ") {
  70. $sep = $i;
  71. }
  72. $l += $this->mpdf->GetCharWidthNonCore($c); // mPDF 5.3.04
  73. if ($l > $wmax) {
  74. //Automatic line break (word wrapping)
  75. if ($sep == -1) {
  76. // WORD SPACING
  77. $this->mpdf->ResetSpacing();
  78. if ($this->mpdf->x > $this->mpdf->lMargin) {
  79. //Move to next line
  80. if ($currentx != 0)
  81. $this->mpdf->x = $currentx;
  82. else
  83. $this->mpdf->x = $this->mpdf->lMargin;
  84. $this->mpdf->y+=$h;
  85. $w = $this->mpdf->w - $this->mpdf->rMargin - $this->mpdf->x;
  86. $wmax = ($w - ($this->mpdf->cMarginL + $this->mpdf->cMarginR));
  87. $i++;
  88. $nl++;
  89. continue;
  90. }
  91. if ($i == $j) {
  92. $i++;
  93. }
  94. $tmp = rtrim(mb_substr($s, $j, $i - $j, $this->mpdf->mb_enc));
  95. $this->mpdf->Cell($w, $h, $tmp, 0, 2, $align, $fill, $link);
  96. } else {
  97. $tmp = rtrim(mb_substr($s, $j, $sep - $j, $this->mpdf->mb_enc));
  98. if ($align == 'J') {
  99. //////////////////////////////////////////
  100. // JUSTIFY J using Unicode fonts (Word spacing doesn't work)
  101. // WORD SPACING
  102. // Change NON_BREAKING SPACE to spaces so they are 'spaced' properly
  103. $tmp = str_replace(chr(194) . chr(160), chr(32), $tmp);
  104. $len_ligne = $this->mpdf->GetStringWidth($tmp);
  105. $nb_carac = mb_strlen($tmp, $this->mpdf->mb_enc);
  106. $nb_spaces = mb_substr_count($tmp, ' ', $this->mpdf->mb_enc);
  107. $inclCursive = false;
  108. if (isset($this->mpdf->CurrentFont['useOTL']) && $this->mpdf->CurrentFont['useOTL']) {
  109. if (preg_match("/([" . $this->mpdf->pregCURSchars . "])/u", $tmp)) {
  110. $inclCursive = true;
  111. }
  112. }
  113. list($charspacing, $ws) = $this->mpdf->GetJspacing($nb_carac, $nb_spaces, ((($w - 2) - $len_ligne) * _MPDFK), $inclCursive);
  114. $this->mpdf->SetSpacing($charspacing, $ws);
  115. //////////////////////////////////////////
  116. }
  117. $this->mpdf->Cell($w, $h, $tmp, 0, 2, $align, $fill, $link);
  118. $i = $sep + 1;
  119. }
  120. $sep = -1;
  121. $j = $i;
  122. $l = 0;
  123. if ($nl == 1) {
  124. if ($currentx != 0)
  125. $this->mpdf->x = $currentx;
  126. else
  127. $this->mpdf->x = $this->mpdf->lMargin;
  128. $w = $this->mpdf->w - $this->mpdf->rMargin - $this->mpdf->x;
  129. $wmax = ($w - ($this->mpdf->cMarginL + $this->mpdf->cMarginR));
  130. }
  131. $nl++;
  132. }
  133. else {
  134. $i++;
  135. }
  136. }
  137. //Last chunk
  138. // WORD SPACING
  139. $this->mpdf->ResetSpacing();
  140. } else {
  141. while ($i < $nb) {
  142. //Get next character
  143. $c = $s[$i];
  144. if ($c == "\n") {
  145. //Explicit line break
  146. // WORD SPACING
  147. $this->mpdf->ResetSpacing();
  148. $this->mpdf->Cell($w, $h, substr($s, $j, $i - $j), 0, 2, $align, $fill, $link);
  149. $i++;
  150. $sep = -1;
  151. $j = $i;
  152. $l = 0;
  153. if ($nl == 1) {
  154. if ($currentx != 0)
  155. $this->mpdf->x = $currentx;
  156. else
  157. $this->mpdf->x = $this->mpdf->lMargin;
  158. $w = $this->mpdf->w - $this->mpdf->rMargin - $this->mpdf->x;
  159. $wmax = $w - ($this->mpdf->cMarginL + $this->mpdf->cMarginR);
  160. }
  161. $nl++;
  162. continue;
  163. }
  164. if ($c == " ") {
  165. $sep = $i;
  166. }
  167. $l += $this->mpdf->GetCharWidthCore($c); // mPDF 5.3.04
  168. if ($l > $wmax) {
  169. //Automatic line break (word wrapping)
  170. if ($sep == -1) {
  171. // WORD SPACING
  172. $this->mpdf->ResetSpacing();
  173. if ($this->mpdf->x > $this->mpdf->lMargin) {
  174. //Move to next line
  175. if ($currentx != 0)
  176. $this->mpdf->x = $currentx;
  177. else
  178. $this->mpdf->x = $this->mpdf->lMargin;
  179. $this->mpdf->y+=$h;
  180. $w = $this->mpdf->w - $this->mpdf->rMargin - $this->mpdf->x;
  181. $wmax = $w - ($this->mpdf->cMarginL + $this->mpdf->cMarginR);
  182. $i++;
  183. $nl++;
  184. continue;
  185. }
  186. if ($i == $j) {
  187. $i++;
  188. }
  189. $this->mpdf->Cell($w, $h, substr($s, $j, $i - $j), 0, 2, $align, $fill, $link);
  190. } else {
  191. $tmp = substr($s, $j, $sep - $j);
  192. if ($align == 'J') {
  193. //////////////////////////////////////////
  194. // JUSTIFY J using Unicode fonts
  195. // WORD SPACING is not fully supported for complex scripts
  196. // Change NON_BREAKING SPACE to spaces so they are 'spaced' properly
  197. $tmp = str_replace(chr(160), chr(32), $tmp);
  198. $len_ligne = $this->mpdf->GetStringWidth($tmp);
  199. $nb_carac = strlen($tmp);
  200. $nb_spaces = substr_count($tmp, ' ');
  201. list($charspacing, $ws) = $this->mpdf->GetJspacing($nb_carac, $nb_spaces, ((($w - 2) - $len_ligne) * _MPDFK), $false);
  202. $this->mpdf->SetSpacing($charspacing, $ws);
  203. //////////////////////////////////////////
  204. }
  205. $this->mpdf->Cell($w, $h, $tmp, 0, 2, $align, $fill, $link);
  206. $i = $sep + 1;
  207. }
  208. $sep = -1;
  209. $j = $i;
  210. $l = 0;
  211. if ($nl == 1) {
  212. if ($currentx != 0)
  213. $this->mpdf->x = $currentx;
  214. else
  215. $this->mpdf->x = $this->mpdf->lMargin;
  216. $w = $this->mpdf->w - $this->mpdf->rMargin - $this->mpdf->x;
  217. $wmax = $w - ($this->mpdf->cMarginL + $this->mpdf->cMarginR);
  218. }
  219. $nl++;
  220. }
  221. else {
  222. $i++;
  223. }
  224. }
  225. // WORD SPACING
  226. $this->mpdf->ResetSpacing();
  227. }
  228. //Last chunk
  229. if ($i != $j) {
  230. if ($currentx != 0)
  231. $this->mpdf->x = $currentx;
  232. else
  233. $this->mpdf->x = $this->mpdf->lMargin;
  234. if ($this->mpdf->usingCoreFont) {
  235. $tmp = substr($s, $j, $i - $j);
  236. } else {
  237. $tmp = mb_substr($s, $j, $i - $j, $this->mpdf->mb_enc);
  238. }
  239. $this->mpdf->Cell($w, $h, $tmp, 0, 0, $align, $fill, $link);
  240. }
  241. }
  242. function CircularText($x, $y, $r, $text, $align = 'top', $fontfamily = '', $fontsizePt = 0, $fontstyle = '', $kerning = 120, $fontwidth = 100, $divider = '')
  243. {
  244. if ($fontfamily || $fontstyle || $fontsizePt)
  245. $this->mpdf->SetFont($fontfamily, $fontstyle, $fontsizePt);
  246. $kerning/=100;
  247. $fontwidth/=100;
  248. if ($kerning == 0)
  249. $this->mpdf->Error('Please use values unequal to zero for kerning (CircularText)');
  250. if ($fontwidth == 0)
  251. $this->mpdf->Error('Please use values unequal to zero for font width (CircularText)');
  252. $text = str_replace("\r", '', $text);
  253. //circumference
  254. $u = ($r * 2) * M_PI;
  255. $checking = true;
  256. $autoset = false;
  257. while ($checking) {
  258. $t = 0;
  259. $w = array();
  260. if ($this->mpdf->usingCoreFont) {
  261. $nb = strlen($text);
  262. for ($i = 0; $i < $nb; $i++) {
  263. $w[$i] = $this->mpdf->GetStringWidth($text[$i]);
  264. $w[$i]*=$kerning * $fontwidth;
  265. $t+=$w[$i];
  266. }
  267. } else {
  268. $nb = mb_strlen($text, $this->mpdf->mb_enc);
  269. $lastchar = '';
  270. $unicode = $this->mpdf->UTF8StringToArray($text);
  271. for ($i = 0; $i < $nb; $i++) {
  272. $c = mb_substr($text, $i, 1, $this->mpdf->mb_enc);
  273. $w[$i] = $this->mpdf->GetStringWidth($c);
  274. $w[$i]*=$kerning * $fontwidth;
  275. $char = $unicode[$i];
  276. if ($this->mpdf->useKerning && $lastchar) {
  277. if (isset($this->mpdf->CurrentFont['kerninfo'][$lastchar][$char])) {
  278. $tk = $this->mpdf->CurrentFont['kerninfo'][$lastchar][$char] * ($this->mpdf->FontSize / 1000) * $kerning * $fontwidth;
  279. $w[$i] += $tk / 2;
  280. $w[$i - 1] += $tk / 2;
  281. $t+=$tk;
  282. }
  283. }
  284. $lastchar = $char;
  285. $t+=$w[$i];
  286. }
  287. }
  288. if ($fontsizePt >= 0 || $autoset) {
  289. $checking = false;
  290. } else {
  291. $t+=$this->mpdf->GetStringWidth(' ');
  292. if ($divider)
  293. $t+=$this->mpdf->GetStringWidth(' ');
  294. if ($fontsizePt == -2)
  295. $fontsizePt = $this->mpdf->FontSizePt * 0.5 * $u / $t;
  296. else
  297. $fontsizePt = $this->mpdf->FontSizePt * $u / $t;
  298. $this->mpdf->SetFontSize($fontsizePt);
  299. $autoset = true;
  300. }
  301. }
  302. //total width of string in degrees
  303. $d = ($t / $u) * 360;
  304. $this->mpdf->StartTransform();
  305. // rotate matrix for the first letter to center the text
  306. // (half of total degrees)
  307. if ($align == 'top') {
  308. $this->mpdf->transformRotate(-$d / 2, $x, $y);
  309. } else {
  310. $this->mpdf->transformRotate($d / 2, $x, $y);
  311. }
  312. //run through the string
  313. for ($i = 0; $i < $nb; $i++) {
  314. if ($align == 'top') {
  315. //rotate matrix half of the width of current letter + half of the width of preceding letter
  316. if ($i == 0) {
  317. $this->mpdf->transformRotate((($w[$i] / 2) / $u) * 360, $x, $y);
  318. } else {
  319. $this->mpdf->transformRotate((($w[$i] / 2 + $w[$i - 1] / 2) / $u) * 360, $x, $y);
  320. }
  321. if ($fontwidth != 1) {
  322. $this->mpdf->StartTransform();
  323. $this->mpdf->transformScale($fontwidth * 100, 100, $x, $y);
  324. }
  325. $this->mpdf->SetXY($x - $w[$i] / 2, $y - $r);
  326. } else {
  327. //rotate matrix half of the width of current letter + half of the width of preceding letter
  328. if ($i == 0) {
  329. $this->mpdf->transformRotate(-(($w[$i] / 2) / $u) * 360, $x, $y);
  330. } else {
  331. $this->mpdf->transformRotate(-(($w[$i] / 2 + $w[$i - 1] / 2) / $u) * 360, $x, $y);
  332. }
  333. if ($fontwidth != 1) {
  334. $this->mpdf->StartTransform();
  335. $this->mpdf->transformScale($fontwidth * 100, 100, $x, $y);
  336. }
  337. $this->mpdf->SetXY($x - $w[$i] / 2, $y + $r - ($this->mpdf->FontSize));
  338. }
  339. if ($this->mpdf->usingCoreFont) {
  340. $c = $text[$i];
  341. } else {
  342. $c = mb_substr($text, $i, 1, $this->mpdf->mb_enc);
  343. }
  344. $this->mpdf->Cell(($w[$i]), $this->mpdf->FontSize, $c, 0, 0, 'C'); // mPDF 5.3.53
  345. if ($fontwidth != 1) {
  346. $this->mpdf->StopTransform();
  347. }
  348. }
  349. $this->mpdf->StopTransform();
  350. // mPDF 5.5.23
  351. if ($align == 'top' && $divider != '') {
  352. $wc = $this->mpdf->GetStringWidth($divider);
  353. $wc*=$kerning * $fontwidth;
  354. $this->mpdf->StartTransform();
  355. $this->mpdf->transformRotate(90, $x, $y);
  356. $this->mpdf->SetXY($x - $wc / 2, $y - $r);
  357. $this->mpdf->Cell(($wc), $this->mpdf->FontSize, $divider, 0, 0, 'C');
  358. $this->mpdf->StopTransform();
  359. $this->mpdf->StartTransform();
  360. $this->mpdf->transformRotate(-90, $x, $y);
  361. $this->mpdf->SetXY($x - $wc / 2, $y - $r);
  362. $this->mpdf->Cell(($wc), $this->mpdf->FontSize, $divider, 0, 0, 'C');
  363. $this->mpdf->StopTransform();
  364. }
  365. }
  366. function Shaded_box($text, $font = '', $fontstyle = 'B', $szfont = '', $width = '70%', $style = 'DF', $radius = 2.5, $fill = '#FFFFFF', $color = '#000000', $pad = 2)
  367. {
  368. // F (shading - no line),S (line, no shading),DF (both)
  369. if (!$font) {
  370. $font = $this->mpdf->default_font;
  371. }
  372. if (!$szfont) {
  373. $szfont = ($this->mpdf->default_font_size * 1.8);
  374. }
  375. $text = ' ' . $text . ' ';
  376. $this->mpdf->SetFont($font, $fontstyle, $szfont, false);
  377. $text = $this->mpdf->purify_utf8_text($text);
  378. if ($this->mpdf->text_input_as_HTML) {
  379. $text = $this->mpdf->all_entities_to_utf8($text);
  380. }
  381. if ($this->mpdf->usingCoreFont) {
  382. $text = mb_convert_encoding($text, $this->mpdf->mb_enc, 'UTF-8');
  383. }
  384. // DIRECTIONALITY
  385. if (preg_match("/([" . $this->mpdf->pregRTLchars . "])/u", $text)) {
  386. $this->mpdf->biDirectional = true;
  387. } // *RTL*
  388. $textvar = 0;
  389. $save_OTLtags = $this->mpdf->OTLtags;
  390. $this->mpdf->OTLtags = array();
  391. if ($this->mpdf->useKerning) {
  392. if ($this->mpdf->CurrentFont['haskernGPOS']) {
  393. $this->mpdf->OTLtags['Plus'] .= ' kern';
  394. } else {
  395. $textvar = ($textvar | FC_KERNING);
  396. }
  397. }
  398. // Use OTL OpenType Table Layout - GSUB & GPOS
  399. if (isset($this->mpdf->CurrentFont['useOTL']) && $this->mpdf->CurrentFont['useOTL']) {
  400. $text = $this->mpdf->otl->applyOTL($text, $this->mpdf->CurrentFont['useOTL']);
  401. $OTLdata = $this->mpdf->otl->OTLdata;
  402. }
  403. $this->mpdf->OTLtags = $save_OTLtags;
  404. $this->mpdf->magic_reverse_dir($text, $this->mpdf->directionality, $OTLdata);
  405. if (!$width) {
  406. $width = $this->mpdf->pgwidth;
  407. } else {
  408. $width = $this->mpdf->ConvertSize($width, $this->mpdf->pgwidth);
  409. }
  410. $midpt = $this->mpdf->lMargin + ($this->mpdf->pgwidth / 2);
  411. $r1 = $midpt - ($width / 2); //($this->mpdf->w / 2) - 40;
  412. $r2 = $r1 + $width; //$r1 + 80;
  413. $y1 = $this->mpdf->y;
  414. $mid = ($r1 + $r2 ) / 2;
  415. $loop = 0;
  416. while ($loop == 0) {
  417. $this->mpdf->SetFont($font, $fontstyle, $szfont, false);
  418. $sz = $this->mpdf->GetStringWidth($text, true, $OTLdata, $textvar);
  419. if (($r1 + $sz) > $r2)
  420. $szfont --;
  421. else
  422. $loop ++;
  423. }
  424. $this->mpdf->SetFont($font, $fontstyle, $szfont, true, true);
  425. $y2 = $this->mpdf->FontSize + ($pad * 2);
  426. $this->mpdf->SetLineWidth(0.1);
  427. $fc = $this->mpdf->ConvertColor($fill);
  428. $tc = $this->mpdf->ConvertColor($color);
  429. $this->mpdf->SetFColor($fc);
  430. $this->mpdf->SetTColor($tc);
  431. $this->mpdf->RoundedRect($r1, $y1, ($r2 - $r1), $y2, $radius, $style);
  432. $this->mpdf->SetX($r1);
  433. $this->mpdf->Cell($r2 - $r1, $y2, $text, 0, 1, "C", 0, '', 0, 0, 0, 'M', 0, false, $OTLdata, $textvar);
  434. $this->mpdf->SetY($y1 + $y2 + 2); // +2 = mm margin below shaded box
  435. $this->mpdf->Reset();
  436. }
  437. }