4 class XML_SvgToPDF_Text extends XML_SvgToPDF_Base {
10 function fromXmlNode($node) {
12 parent::fromXmlNode($node);
15 function fromNode($node) {
17 parent::fromNode($node);
23 if (empty($this->children) || empty($this->children[0]->content)) {
27 // modify the alignment of the if this block content of the first child is "=="
29 if (substr($this->children[0]->content,0,2) == '==') {
30 $this->style['text-anchor'] = 'justify';
31 $this->children[0]->content = substr($this->children[0]->content,2);
35 function transform() {
38 if (empty($this->transform)) {
41 if (preg_match('/scale\(([0-9e.-]+),([0-9e.-]+)\)/',$this->transform,$args)) {
42 $xscale = $args[1]; // do we use this??? = what do do about 'e'?
44 $this->style['font-size'] *= $args[1];
50 function writePDF($pdf,$data) {
53 $font = strtolower($this->style['font-family']);
54 $font = trim($font, "'");
57 'times new roman' => 'times',
58 'courier new' => 'courier',
61 if (isset($map[$font])) {
67 if (preg_match('/big5/i',$this->style['font-family'])) {
70 //$ffont = 'ARIALUNI';
71 // $font = 'arial'; // default if not bigg
77 if ($this->style['font-weight'] == 'bold') {
80 if (@$this->style['font-style'] == 'italic') {
84 if (@$this->style['text-decoration'] == 'underline') {
88 $size = $this->style['font-size'] * 0.85;
90 $pdf->setFont($font,$weight,$size);
92 switch(@$this->style['text-anchor']) {
102 foreach ($this->children as $child) {
103 if (!@$child->content) {
106 $l = $pdf->getStringWidth($child->content);
107 $max = ($l > $max) ? $l : $max;
110 $this->justifyLen = $max;
117 $f = $this->toColor(@$this->style['fill']);
119 $pdf->setTextColor($f[0],$f[1],$f[2]);
125 $x = $this->x + @$this->xx;
126 $y = $this->y + @$this->yy;
127 if (empty($this->children)) {
131 foreach($this->children as $i=>$c) {
133 $xx = $c->x !== false ? $c->x + @$this->xx : $x;
134 $yy = $c->y !== false ? $c->y + @$this->yy : $y + ($lineno * $size * 1.3);
136 if (empty($c->content)) {
140 //if ($ffont == 'ARIALUNI') { //) && preg_match('/[\x7f-\xff]+/',$val)) {
141 // $pdf->setFont('ARIALUNI' ,
145 if (isset($c->args)) {
148 foreach($c->args as $v) {
150 $args[] = $pdf->PageNo();
158 // echo "GET: $v : '$val'<BR>";
159 $args[] = trim($this->getValue($data,trim($v))); // removes trailing CRLF...
163 $has_template = preg_match('/%s/', $val);
165 $val = empty($val) || empty($args) ? $val : trim(vsprintf($val,$args));
167 //if ($has_template && ($ffont == 'ARIALUNI') && preg_match('/[\x7f-\xff]+/',$val)) {
168 if ($has_template && ($font == 'Big5') && preg_match('/[\x7f-\xff]+/',$val)) {
169 require_once 'Text/ZhDetect.php';
170 $detect = new Text_zhDetect;
171 $type = $detect->guess($val);
174 $val = @iconv('utf8', 'GB2312//IGNORE', $val);
179 $val = @iconv('utf8', 'BIG5//IGNORE', $val);
180 $pdf->setFont('Big5' ,
185 $val = @iconv('utf8','ascii//ignore',$val);
193 if ((!@$this->children[$i+1] || !strlen(trim(@$this->children[$i+1]->content))) && ($align == 'J')) {
197 $yoffset += $this->multiLine($pdf, str_replace("\r", "", explode("\n",$val)),
199 ($yy / 3.543307) + $yoffset,
200 ($size / 3.543307) + 1,
212 * get a value from the data
215 * 'fred' => 'somevalue'
217 * getValue ($data,'fred') returns 'somevalue'
219 * value can also be a method = eg. getFred()
221 * @param object|array $data
222 * @param string $v key to get.
229 function getValue($data,$v) {
231 // print_R(array("GET VALUE: ", $v));
234 if ($v[strlen($v)-1] != ')') {
236 $data = (array) $data;
237 //echo "<PRE>";print_r(array_keys($data));
238 if (false === strpos($v,'.')) {
239 if (!isset($data[$v])) {
240 // echo "missing $v\n";
243 if (is_array($data[$v]) || is_object($data[$v])) {
244 // echo "array/object $v\n";
247 //echo "returning $v\n";
251 foreach(explode('.', $v) as $vv) {
252 if (!is_array($dd)) {
255 if (!isset($dd[$vv])) {
258 $dd = is_object($dd[$vv]) ? ((array) $dd[$vv]) : $dd[$vv];
260 //echo "ATTEMPT: $v: got $dd\n";
262 if (is_array($dd) || is_object($dd)) {
268 if (!is_object($data)) {
271 $method = substr($v,0,-2);
273 if (is_object($data) && method_exists($data,$method)) {
274 // echo "call $method<BR>";
275 $ret = $data->$method();
276 // echo "done $method $ret<BR>";
277 if (is_array($ret) || is_object($ret)) {
287 return "no method $method in ".get_class($data);
293 function breakLines($pdf,$str,$x,$y,$h,$align) {
294 // do the estimation...
297 $total = $pdf->getStringWidth($str . ' ');
299 $charsize = $total/$len;
301 $max_chars = floor(($this->maxWidth / 3.543307) / $charsize);
302 //echo "LEN: $len, $total, $charsize, $max_chars";
303 $lines = explode("\n",wordwrap($str,$max_chars));
305 return $this->multiLine($pdf,$lines,$x,$y,$h,$align);
307 var $maxWidth = false;
309 function multiLine($pdf,$lines,$x,$y,$h,$align) {
310 // now dealing with mm
311 ///XML_SvgToPDF::debug("MULTILINE " .implode("\n",$lines) . " $x, $y, $h");
314 foreach ($lines as $l=>$v) {
316 if ($this->maxWidth !== false && ($pdf->getStringWidth($v) > ($this->maxWidth / 3.543307))) {
317 $yoffset += $this->breakLines($pdf,$v,$x,$y + ($l * $h) + $yoffset, $h,$align);
320 XML_SvgToPDF::debug("TEXT: $x,$y, $l * $h + $yoffset,$v");
322 if ($align == 'M') { // center
323 $xoffset = -1 * ($pdf->getStringWidth($v) / 2);
325 if ($align == 'E') { // right/end
326 $xoffset = -1 * $pdf->getStringWidth($v);
329 if ($align == 'J' ) { // justified (eg. started with ==
330 $this->justify($pdf, $x , $y + ($l * $h) + $yoffset , $v, $this->justifyLen);
335 $y + ($l * $h) + $yoffset ,
339 return ($l * $h) + $yoffset;
344 function justify($pdf,$x,$y,$text,$len) {
345 if (!strlen(trim($text))) {
348 $bits = explode(' ', $text);
349 $textlen = $pdf->getStringWidth(implode('',$bits));
350 $spacesize = ($len - $textlen) / (count($bits) -1);
351 foreach($bits as $word) {
352 $pdf->text($x , $y ,$word );
353 $x += $spacesize + $pdf->getStringWidth($word);