]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/fpdf/japanese.php
Reformat code
[SourceForge/phpwiki.git] / lib / fpdf / japanese.php
1 <?php
2 // PDF functions taken from FPDF http://www.fpdf.org
3
4 require_once 'lib/pdf.php';
5
6 class PDF_Japanese extends PDF
7 {
8     var $B;
9     var $I;
10     var $U;
11     var $HREF;
12     var $SJIS_widths = array(' ' => 278, '!' => 299, '"' => 353, '#' => 614, '$' => 614, '%' => 721, '&' => 735, '\'' => 216,
13         '(' => 323, ')' => 323, '*' => 449, '+' => 529, ',' => 219, '-' => 306, '.' => 219, '/' => 453, '0' => 614, '1' => 614,
14         '2' => 614, '3' => 614, '4' => 614, '5' => 614, '6' => 614, '7' => 614, '8' => 614, '9' => 614, ':' => 219, ';' => 219,
15         '<' => 529, '=' => 529, '>' => 529, '?' => 486, '@' => 744, 'A' => 646, 'B' => 604, 'C' => 617, 'D' => 681, 'E' => 567,
16         'F' => 537, 'G' => 647, 'H' => 738, 'I' => 320, 'J' => 433, 'K' => 637, 'L' => 566, 'M' => 904, 'N' => 710, 'O' => 716,
17         'P' => 605, 'Q' => 716, 'R' => 623, 'S' => 517, 'T' => 601, 'U' => 690, 'V' => 668, 'W' => 990, 'X' => 681, 'Y' => 634,
18         'Z' => 578, '[' => 316, '\\' => 614, ']' => 316, '^' => 529, '_' => 500, '`' => 387, 'a' => 509, 'b' => 566, 'c' => 478,
19         'd' => 565, 'e' => 503, 'f' => 337, 'g' => 549, 'h' => 580, 'i' => 275, 'j' => 266, 'k' => 544, 'l' => 276, 'm' => 854,
20         'n' => 579, 'o' => 550, 'p' => 578, 'q' => 566, 'r' => 410, 's' => 444, 't' => 340, 'u' => 575, 'v' => 512, 'w' => 760,
21         'x' => 503, 'y' => 529, 'z' => 453, '{' => 326, '|' => 380, '}' => 326, '~' => 387);
22
23     function AddCIDFont($family, $style, $name, $cw, $CMap, $registry)
24     {
25         $fontkey = strtolower($family) . strtoupper($style);
26         if (isset($this->fonts[$fontkey]))
27             $this->Error("CID font already added: $family $style");
28         $i = count($this->fonts) + 1;
29         $this->fonts[$fontkey] = array('i' => $i, 'type' => 'Type0', 'name' => $name, 'up' => -120, 'ut' => 40, 'cw' => $cw, 'CMap' => $CMap, 'registry' => $registry);
30     }
31
32     function AddCIDFonts($family, $name, $cw, $CMap, $registry)
33     {
34         $this->AddCIDFont($family, '', $name, $cw, $CMap, $registry);
35         $this->AddCIDFont($family, 'B', $name . ',Bold', $cw, $CMap, $registry);
36         $this->AddCIDFont($family, 'I', $name . ',Italic', $cw, $CMap, $registry);
37         $this->AddCIDFont($family, 'BI', $name . ',BoldItalic', $cw, $CMap, $registry);
38     }
39
40     function AddSJISFont($family = 'SJIS')
41     {
42         //Add SJIS font with proportional Latin
43         $name = 'KozMinPro-Regular-Acro';
44         $cw = $this->SJIS_widths;
45         $CMap = '90msp-RKSJ-H';
46         $registry = array('ordering' => 'Japan1', 'supplement' => 2);
47         $this->AddCIDFonts($family, $name, $cw, $CMap, $registry);
48     }
49
50     function AddSJIShwFont($family = 'SJIS-hw')
51     {
52         //Add SJIS font with half-width Latin
53         $name = 'KozMinPro-Regular-Acro';
54         for ($i = 32; $i <= 126; $i++)
55             $cw[chr($i)] = 500;
56         $CMap = '90ms-RKSJ-H';
57         $registry = array('ordering' => 'Japan1', 'supplement' => 2);
58         $this->AddCIDFonts($family, $name, $cw, $CMap, $registry);
59     }
60
61     function GetStringWidth($s)
62     {
63         if ($this->CurrentFont['type'] == 'Type0')
64             return $this->GetSJISStringWidth($s);
65         else
66             return parent::GetStringWidth($s);
67     }
68
69     function GetSJISStringWidth($s)
70     {
71         //SJIS version of GetStringWidth()
72         $l = 0;
73         $cw =& $this->CurrentFont['cw'];
74         $nb = strlen($s);
75         $i = 0;
76         while ($i < $nb) {
77             $o = ord($s{$i});
78             if ($o < 128) {
79                 //ASCII
80                 $l += $cw[$s{$i}];
81                 $i++;
82             } elseif ($o >= 161 and $o <= 223) {
83                 //Half-width katakana
84                 $l += 500;
85                 $i++;
86             } else {
87                 //Full-width character
88                 $l += 1000;
89                 $i += 2;
90             }
91         }
92         return $l * $this->FontSize / 1000;
93     }
94
95     function MultiCell($w, $h, $txt, $border = 0, $align = 'L', $fill = 0)
96     {
97         if ($this->CurrentFont['type'] == 'Type0')
98             $this->SJISMultiCell($w, $h, $txt, $border, $align, $fill);
99         else
100             parent::MultiCell($w, $h, $txt, $border, $align, $fill);
101     }
102
103     function SJISMultiCell($w, $h, $txt, $border = 0, $align = 'L', $fill = 0)
104     {
105         //Output text with automatic or explicit line breaks
106         $cw =& $this->CurrentFont['cw'];
107         if ($w == 0)
108             $w = $this->w - $this->rMargin - $this->x;
109         $wmax = ($w - 2 * $this->cMargin) * 1000 / $this->FontSize;
110         $s = str_replace("\r", '', $txt);
111         $nb = strlen($s);
112         if ($nb > 0 and $s{$nb - 1} == "\n")
113             $nb--;
114         $b = 0;
115         if ($border) {
116             if ($border == 1) {
117                 $border = 'LTRB';
118                 $b = 'LRT';
119                 $b2 = 'LR';
120             } else {
121                 $b2 = '';
122                 if (is_int(strpos($border, 'L')))
123                     $b2 .= 'L';
124                 if (is_int(strpos($border, 'R')))
125                     $b2 .= 'R';
126                 $b = is_int(strpos($border, 'T')) ? $b2 . 'T' : $b2;
127             }
128         }
129         $sep = -1;
130         $i = 0;
131         $j = 0;
132         $l = 0;
133         $nl = 1;
134         while ($i < $nb) {
135             //Get next character
136             $c = $s{$i};
137             $o = ord($c);
138             if ($o == 10) {
139                 //Explicit line break
140                 $this->Cell($w, $h, substr($s, $j, $i - $j), $b, 2, $align, $fill);
141                 $i++;
142                 $sep = -1;
143                 $j = $i;
144                 $l = 0;
145                 $nl++;
146                 if ($border and $nl == 2)
147                     $b = $b2;
148                 continue;
149             }
150             if ($o < 128) {
151                 //ASCII
152                 $l += $cw[$c];
153                 $n = 1;
154                 if ($o == 32)
155                     $sep = $i;
156             } elseif ($o >= 161 and $o <= 223) {
157                 //Half-width katakana
158                 $l += 500;
159                 $n = 1;
160                 $sep = $i;
161             } else {
162                 //Full-width character
163                 $l += 1000;
164                 $n = 2;
165                 $sep = $i;
166             }
167             if ($l > $wmax) {
168                 //Automatic line break
169                 if ($sep == -1 or $i == $j) {
170                     if ($i == $j)
171                         $i += $n;
172                     $this->Cell($w, $h, substr($s, $j, $i - $j), $b, 2, $align, $fill);
173                 } else {
174                     $this->Cell($w, $h, substr($s, $j, $sep - $j), $b, 2, $align, $fill);
175                     $i = ($s[$sep] == ' ') ? $sep + 1 : $sep;
176                 }
177                 $sep = -1;
178                 $j = $i;
179                 $l = 0;
180                 $nl++;
181                 if ($border and $nl == 2)
182                     $b = $b2;
183             } else {
184                 $i += $n;
185                 if ($o >= 128)
186                     $sep = $i;
187             }
188         }
189         //Last chunk
190         if ($border and is_int(strpos($border, 'B')))
191             $b .= 'B';
192         $this->Cell($w, $h, substr($s, $j, $i - $j), $b, 2, $align, $fill);
193         $this->x = $this->lMargin;
194     }
195
196     function Write($h, $txt, $link = '')
197     {
198         if ($this->CurrentFont['type'] == 'Type0')
199             $this->SJISWrite($h, $txt, $link);
200         else
201             parent::Write($h, $txt, $link);
202     }
203
204     function SJISWrite($h, $txt, $link)
205     {
206         //SJIS version of Write()
207         $cw =& $this->CurrentFont['cw'];
208         $w = $this->w - $this->rMargin - $this->x;
209         $wmax = ($w - 2 * $this->cMargin) * 1000 / $this->FontSize;
210         $s = str_replace("\r", '', $txt);
211         $nb = strlen($s);
212         $sep = -1;
213         $i = 0;
214         $j = 0;
215         $l = 0;
216         $nl = 1;
217         while ($i < $nb) {
218             //Get next character
219             $c = $s{$i};
220             $o = ord($c);
221             if ($o == 10) {
222                 //Explicit line break
223                 $this->Cell($w, $h, substr($s, $j, $i - $j), 0, 2, '', 0, $link);
224                 $i++;
225                 $sep = -1;
226                 $j = $i;
227                 $l = 0;
228                 if ($nl == 1) {
229                     //Go to left margin
230                     $this->x = $this->lMargin;
231                     $w = $this->w - $this->rMargin - $this->x;
232                     $wmax = ($w - 2 * $this->cMargin) * 1000 / $this->FontSize;
233                 }
234                 $nl++;
235                 continue;
236             }
237             if ($o < 128) {
238                 //ASCII
239                 $l += $cw[$c];
240                 $n = 1;
241                 if ($o == 32)
242                     $sep = $i;
243             } elseif ($o >= 161 and $o <= 223) {
244                 //Half-width katakana
245                 $l += 500;
246                 $n = 1;
247                 $sep = $i;
248             } else {
249                 //Full-width character
250                 $l += 1000;
251                 $n = 2;
252                 $sep = $i;
253             }
254             if ($l > $wmax) {
255                 //Automatic line break
256                 if ($sep == -1 or $i == $j) {
257                     if ($this->x > $this->lMargin) {
258                         //Move to next line
259                         $this->x = $this->lMargin;
260                         $this->y += $h;
261                         $w = $this->w - $this->rMargin - $this->x;
262                         $wmax = ($w - 2 * $this->cMargin) * 1000 / $this->FontSize;
263                         $i += $n;
264                         $nl++;
265                         continue;
266                     }
267                     if ($i == $j)
268                         $i += $n;
269                     $this->Cell($w, $h, substr($s, $j, $i - $j), 0, 2, '', 0, $link);
270                 } else {
271                     $this->Cell($w, $h, substr($s, $j, $sep - $j), 0, 2, '', 0, $link);
272                     $i = ($s[$sep] == ' ') ? $sep + 1 : $sep;
273                 }
274                 $sep = -1;
275                 $j = $i;
276                 $l = 0;
277                 if ($nl == 1) {
278                     $this->x = $this->lMargin;
279                     $w = $this->w - $this->rMargin - $this->x;
280                     $wmax = ($w - 2 * $this->cMargin) * 1000 / $this->FontSize;
281                 }
282                 $nl++;
283             } else {
284                 $i += $n;
285                 if ($o >= 128)
286                     $sep = $i;
287             }
288         }
289         //Last chunk
290         if ($i != $j)
291             $this->Cell($l / 1000 * $this->FontSize, $h, substr($s, $j, $i - $j), 0, 0, '', 0, $link);
292     }
293
294     function _putfonts()
295     {
296         $nf = $this->n;
297         foreach ($this->diffs as $diff) {
298             //Encodings
299             $this->_newobj();
300             $this->_out('<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences [' . $diff . ']>>');
301             $this->_out('endobj');
302         }
303         if (!check_php_version(5, 3)) {
304             $mqr = get_magic_quotes_runtime();
305             set_magic_quotes_runtime(0);
306         }
307         foreach ($this->FontFiles as $file => $info) {
308             //Font file embedding
309             $this->_newobj();
310             $this->FontFiles[$file]['n'] = $this->n;
311             if (defined('FPDF_FONTPATH'))
312                 $file = FPDF_FONTPATH . $file;
313             $size = filesize($file);
314             if (!$size)
315                 $this->Error('Font file not found');
316             $this->_out('<</Length ' . $size);
317             if (substr($file, -2) == '.z')
318                 $this->_out('/Filter /FlateDecode');
319             $this->_out('/Length1 ' . $info['length1']);
320             if (isset($info['length2']))
321                 $this->_out('/Length2 ' . $info['length2'] . ' /Length3 0');
322             $this->_out('>>');
323             $f = fopen($file, 'rb');
324             $this->_putstream(fread($f, $size));
325             fclose($f);
326             $this->_out('endobj');
327         }
328         if (!check_php_version(5, 3)) {
329             set_magic_quotes_runtime($mqr);
330         }
331         foreach ($this->fonts as $k => $font) {
332             //Font objects
333             $this->_newobj();
334             $this->fonts[$k]['n'] = $this->n;
335             $this->_out('<</Type /Font');
336             if ($font['type'] == 'Type0')
337                 $this->_putType0($font);
338             else {
339                 $name = $font['name'];
340                 $this->_out('/BaseFont /' . $name);
341                 if ($font['type'] == 'core') {
342                     //Standard font
343                     $this->_out('/Subtype /Type1');
344                     if ($name != 'Symbol' and $name != 'ZapfDingbats')
345                         $this->_out('/Encoding /WinAnsiEncoding');
346                 } else {
347                     //Additional font
348                     $this->_out('/Subtype /' . $font['type']);
349                     $this->_out('/FirstChar 32');
350                     $this->_out('/LastChar 255');
351                     $this->_out('/Widths ' . ($this->n + 1) . ' 0 R');
352                     $this->_out('/FontDescriptor ' . ($this->n + 2) . ' 0 R');
353                     if ($font['enc']) {
354                         if (isset($font['diff']))
355                             $this->_out('/Encoding ' . ($nf + $font['diff']) . ' 0 R');
356                         else
357                             $this->_out('/Encoding /WinAnsiEncoding');
358                     }
359                 }
360                 $this->_out('>>');
361                 $this->_out('endobj');
362                 if ($font['type'] != 'core') {
363                     //Widths
364                     $this->_newobj();
365                     $cw =& $font['cw'];
366                     $s = '[';
367                     for ($i = 32; $i <= 255; $i++)
368                         $s .= $cw[chr($i)] . ' ';
369                     $this->_out($s . ']');
370                     $this->_out('endobj');
371                     //Descriptor
372                     $this->_newobj();
373                     $s = '<</Type /FontDescriptor /FontName /' . $name;
374                     foreach ($font['desc'] as $k => $v)
375                         $s .= ' /' . $k . ' ' . $v;
376                     $file = $font['file'];
377                     if ($file)
378                         $s .= ' /FontFile' . ($font['type'] == 'Type1' ? '' : '2') . ' ' . $this->FontFiles[$file]['n'] . ' 0 R';
379                     $this->_out($s . '>>');
380                     $this->_out('endobj');
381                 }
382             }
383         }
384     }
385
386     function _putType0($font)
387     {
388         //Type0
389         $this->_out('/Subtype /Type0');
390         $this->_out('/BaseFont /' . $font['name'] . '-' . $font['CMap']);
391         $this->_out('/Encoding /' . $font['CMap']);
392         $this->_out('/DescendantFonts [' . ($this->n + 1) . ' 0 R]');
393         $this->_out('>>');
394         $this->_out('endobj');
395         //CIDFont
396         $this->_newobj();
397         $this->_out('<</Type /Font');
398         $this->_out('/Subtype /CIDFontType0');
399         $this->_out('/BaseFont /' . $font['name']);
400         $this->_out('/CIDSystemInfo <</Registry (Adobe) /Ordering (' . $font['registry']['ordering'] . ') /Supplement ' . $font['registry']['supplement'] . '>>');
401         $this->_out('/FontDescriptor ' . ($this->n + 1) . ' 0 R');
402         $W = '/W [1 [';
403         foreach ($font['cw'] as $w)
404             $W .= $w . ' ';
405         $this->_out($W . '] 231 325 500 631 [500] 326 389 500]');
406         $this->_out('>>');
407         $this->_out('endobj');
408         //Font descriptor
409         $this->_newobj();
410         $this->_out('<</Type /FontDescriptor');
411         $this->_out('/FontName /' . $font['name']);
412         $this->_out('/Flags 6');
413         $this->_out('/FontBBox [0 -200 1000 900]');
414         $this->_out('/ItalicAngle 0');
415         $this->_out('/Ascent 800');
416         $this->_out('/Descent -200');
417         $this->_out('/CapHeight 800');
418         $this->_out('/StemV 60');
419         $this->_out('>>');
420         $this->_out('endobj');
421     }
422 }
423
424 // Local Variables:
425 // mode: php
426 // tab-width: 8
427 // c-basic-offset: 4
428 // c-hanging-comment-ender-p: nil
429 // indent-tabs-mode: nil
430 // End: