Index: branches/version-2_12-dev/data/class/helper/SC_Helper_FPDI.php
===================================================================
--- branches/version-2_12-dev/data/class/helper/SC_Helper_FPDI.php	(revision 21814)
+++ branches/version-2_12-dev/data/class/helper/SC_Helper_FPDI.php	(revision 21826)
@@ -1,110 +1,34 @@
 <?php
 require DATA_REALDIR . 'module/fpdf/fpdf.php';
-require DATA_REALDIR . 'module/fpdi/fpdi.php';
-
-class SC_Helper_FPDI extends FPDI {
-    public static $SJIS_widths = array(
-        ' ' => 278, '!' => 299, '"' => 353, '#' => 614, '$' => 614, '%' => 721, '&' => 735, '\'' => 216,
-        '(' => 323, ')' => 323, '*' => 449, '+' => 529, ',' => 219, '-' => 306, '.' => 219, '/' => 453, '0' => 614, '1' => 614,
-        '2' => 614, '3' => 614, '4' => 614, '5' => 614, '6' => 614, '7' => 614, '8' => 614, '9' => 614, ':' => 219, ';' => 219,
-        '<' => 529, '=' => 529, '>' => 529, '?' => 486, '@' => 744, 'A' => 646, 'B' => 604, 'C' => 617, 'D' => 681, 'E' => 567,
-        'F' => 537, 'G' => 647, 'H' => 738, 'I' => 320, 'J' => 433, 'K' => 637, 'L' => 566, 'M' => 904, 'N' => 710, 'O' => 716,
-        'P' => 605, 'Q' => 716, 'R' => 623, 'S' => 517, 'T' => 601, 'U' => 690, 'V' => 668, 'W' => 990, 'X' => 681, 'Y' => 634,
-        'Z' => 578, '[' => 316, '\\' => 614, ']' => 316, '^' => 529, '_' => 500, '`' => 387, 'a' => 509, 'b' => 566, 'c' => 478,
-        'd' => 565, 'e' => 503, 'f' => 337, 'g' => 549, 'h' => 580, 'i' => 275, 'j' => 266, 'k' => 544, 'l' => 276, 'm' => 854,
-        'n' => 579, 'o' => 550, 'p' => 578, 'q' => 566, 'r' => 410, 's' => 444, 't' => 340, 'u' => 575, 'v' => 512, 'w' => 760,
-        'x' => 503, 'y' => 529, 'z' => 453, '{' => 326, '|' => 380, '}' => 326, '~' => 387,
-    );
-
-    function AddCIDFont($family, $style, $name, $cw, $CMap, $registry) {
-        $fontkey = strtolower($family).strtoupper($style);
-        if (isset($this->fonts[$fontkey])) {
-            $this->Error("CID font already added: $family $style");
-        }
-        $i = count($this->fonts) + 1;
-        $this->fonts[$fontkey] = array(
-            'i' => $i,
-            'type' => 'Type0',
-            'name' => $name,
-            'up' => -120,
-            'ut' => 40,
-            'cw' => $cw,
-            'CMap' => $CMap,
-            'registry' => $registry,
-        );
-    }
-
-    function AddCIDFonts($family, $name, $cw, $CMap, $registry) {
-        $this->AddCIDFont($family, '', $name, $cw, $CMap, $registry);
-        $this->AddCIDFont($family, 'B', $name . ',Bold', $cw, $CMap, $registry);
-        $this->AddCIDFont($family, 'I', $name . ',Italic', $cw, $CMap, $registry);
-        $this->AddCIDFont($family, 'BI', $name . ',BoldItalic', $cw, $CMap, $registry);
-    }
-
-    function AddSJISFont($family = 'SJIS') {
-        //Add SJIS font with proportional Latin
-        $name = 'KozMinPro-Regular-Acro';
-        $cw = SC_Helper_FPDI_Ex::$SJIS_widths;
-        $CMap = '90msp-RKSJ-H';
-        $registry = array('ordering' => 'Japan1', 'supplement' => 2);
-        $this->AddCIDFonts($family, $name, $cw, $CMap, $registry);
-    }
-
-    function AddSJIShwFont($family = 'SJIS-hw') {
-        //Add SJIS font with half-width Latin
-        $name = 'KozMinPro-Regular-Acro';
-        for ($i = 32; $i <= 126; $i++) {
-            $cw[chr($i)] = 500;
-        }
-        $CMap = '90ms-RKSJ-H';
-        $registry = array('ordering' => 'Japan1', 'supplement' => 2);
-        $this->AddCIDFonts($family, $name, $cw, $CMap, $registry);
-    }
-
-    function GetStringWidth($s) {
-        if ($this->CurrentFont['type']=='Type0') {
-            return $this->GetSJISStringWidth($s);
-        } else {
-            return parent::GetStringWidth($s);
-        }
-    }
-
-    function GetSJISStringWidth($s) {
-        //SJIS version of GetStringWidth()
-        $l = 0;
-        $cw =& $this->CurrentFont['cw'];
-        $nb = strlen($s);
-        $i = 0;
-        while ($i<$nb) {
-            $o = ord($s{$i});
-            if ($o < 128) {
-                //ASCII
-                $l += $cw[$s{$i}];
-                $i++;
-            }
-            elseif($o >= 161 && $o <= 223) {
-                //Half-width katakana
-                $l += 500;
-                $i++;
-            }
-            else {
-                //Full-width character
-                $l += 1000;
-                $i += 2;
-            }
-        }
-        return $l * $this->FontSize / 1000;
-    }
-
-    function MultiCell($w, $h, $txt, $border = 0, $align = 'L', $fill = 0, $ln = 2) {
-        if ($this->CurrentFont['type'] == 'Type0') {
-            $this->SJISMultiCell($w, $h, $txt, $border, $align, $fill, $ln);
-        } else {
-            parent::MultiCell($w, $h, $txt, $border, $align, $fill, $ln);
-        }
-    }
-
-    function SJISMultiCell($w, $h, $txt, $border = 0, $align = 'L', $fill = 0, $ln = 2) {
-        //Output text with automatic or explicit line breaks
+require DATA_REALDIR . 'module/fpdi/japanese.php';
+
+// japanese.php のバグ回避
+$GLOBALS[SJIS_widths] = $SJIS_widths;
+
+class SC_Helper_FPDI extends PDF_Japanese {
+    /**
+     * PDF_Japanese の明朝フォントに加えゴシックフォントを追加定義
+     *
+     * @return void
+     */
+    function AddSJISFont() {
+        parent::AddSJISFont();
+        $cw = $GLOBALS['SJIS_widths'];
+        $c_map = '90msp-RKSJ-H';
+        $registry = array('ordering'=>'Japan1','supplement'=>2);
+        $this->AddCIDFonts('Gothic', 'KozGoPro-Medium-Acro,MS-PGothic,Osaka', $cw, $c_map, $registry);
+    }
+
+    /**
+     * FancyTable から利用するための SJISMultiCell
+     *
+     * PDF_Japanese#SJISMultiCell をベースにカスタマイズ。
+     */
+    function SJISMultiCellForFancyTable($w, $h, $txt, $border = 0, $align = 'L', $fill = 0) {
+        $y = $this->y;
+
+        // ここで SJIS に変換する。そのため、このメソッドの中では、PDF_Japanese#Cell を直接呼ぶ。
+        $txt = $this->lfConvSjis($txt);
+        // Output text with automatic or explicit line breaks
         $cw =& $this->CurrentFont['cw'];
         if ($w == 0) {
@@ -138,13 +62,13 @@
         $l = 0;
         $nl = 1;
-        $this->rise_h = 0; //³vZp
+        $rise_h = $h; // 高さ計算用
 
         while ($i < $nb) {
-            //Get next character
+            // Get next character
             $c = $s{$i};
             $o = ord($c);
             if ($o == 10) {
-                //Explicit line break
-                $this->Cell($w, $h, substr($s, $j, $i - $j), $b, 2, $align, $fill);
+                // Explicit line break
+                parent::Cell($w, $h, substr($s, $j, $i - $j), $b, 2, $align, $fill);
                 $i++;
                 $sep = -1;
@@ -152,5 +76,5 @@
                 $l = 0;
                 $nl++;
-                $this->rise_h += $h; //³vZp
+                $rise_h += $h; // 高さ計算用
                 if ($border && $nl == 2) {
                     $b=$b2;
@@ -159,5 +83,5 @@
             }
             if ($o < 128) {
-                //ASCII
+                // ASCII
                 $l += $cw[$c];
                 $n = 1;
@@ -167,5 +91,5 @@
             }
             elseif($o >= 161 && $o <= 223) {
-                //Half-width katakana
+                // Half-width katakana
                 $l += 500;
                 $n = 1;
@@ -173,5 +97,5 @@
             }
             else {
-                //Full-width character
+                // Full-width character
                 $l += 1000;
                 $n = 2;
@@ -179,16 +103,16 @@
             }
             if ($l > $wmax) {
-                //Automatic line break
+                // Automatic line break
                 if ($sep == -1 || $i == $j) {
                     if ($i == $j) {
                         $i += $n;
                     }
-                    $this->Cell($w, $h, substr($s, $j, $i - $j), $b, 2, $align, $fill);
+                    parent::Cell($w, $h, substr($s, $j, $i - $j), $b, 2, $align, $fill);
                 }
                 else {
-                    $this->Cell($w, $h, substr($s, $j, $sep - $j), $b, 2, $align, $fill);
+                    parent::Cell($w, $h, substr($s, $j, $sep - $j), $b, 2, $align, $fill);
                     $i = ($s[$sep] == ' ') ? $sep + 1 : $sep;
                 }
-                $this->rise_h += $h; //³vZp
+                $rise_h += $h; // 高さ計算用
                 $sep = -1;
                 $j = $i;
@@ -206,271 +130,22 @@
             }
         }
-        //Last chunk
+        // Last chunk
         if ($border && is_int(strpos($border, 'B'))) {
             $b .= 'B';
         }
-        $this->Cell($w, $h, substr($s, $j, $i - $j), $b, $ln, $align, $fill);
-        $this->rise_h += $h; //ÁªÌ³ðvZ
-        //üsÈµÝè©ÂA³ªKèÌ³ÈãÅ êÎY²ðÝèµÈ¨·B
-        if ($ln == 0 && $h < $this->rise_h) {
-          $this->y = $this->y - $this->rise_h + $h;
-        }
-
-        //$this->x = $this->lMargin;
-    }
-
-    function Write($h, $txt, $link = '') {
-        if ($this->CurrentFont['type'] == 'Type0') {
-            $this->SJISWrite($h, $txt, $link);
-        }
-        else {
-            parent::Write($h, $txt, $link);
-        }
-    }
-
-    function SJISWrite($h, $txt, $link) {
-        //SJIS version of Write()
-        $cw =& $this->CurrentFont['cw'];
-        $w = $this->w - $this->rMargin - $this->x;
-        $wmax = ($w - 2 * $this->cMargin) * 1000 / $this->FontSize;
-        $s = str_replace("\r", '', $txt);
-        $nb = strlen($s);
-        $sep = -1;
-        $i = 0;
-        $j = 0;
-        $l = 0;
-        $nl = 1;
-        while($i < $nb) {
-            //Get next character
-            $c = $s[$i];
-            $o = ord($c);
-            if ($o == 10) {
-                //Explicit line break
-                $this->Cell($w, $h, substr($s, $j, $i - $j), 0, 2, '', 0, $link);
-                $i++;
-                $sep = -1;
-                $j = $i;
-                $l = 0;
-                if ($nl == 1) {
-                    //Go to left margin
-                    $this->x = $this->lMargin;
-                    $w = $this->w - $this->rMargin - $this->x;
-                    $wmax = ($w - 2 * $this->cMargin) * 1000 / $this->FontSize;
-                }
-                $nl++;
-                continue;
-            }
-            if ($o < 128) {
-                //ASCII
-                $l += $cw[$c];
-                $n = 1;
-                if ($o == 32) {
-                    $sep = $i;
-                }
-            }
-            elseif($o >= 161 && $o <= 223) {
-                //Half-width katakana
-                $l += 500;
-                $n = 1;
-                $sep = $i;
-            }
-            else {
-                //Full-width character
-                $l += 1000;
-                $n = 2;
-                $sep = $i;
-            }
-            if ($l > $wmax) {
-                //Automatic line break
-                if ($sep == -1 || $i == $j) {
-                    if ($this->x > $this->lMargin) {
-                        //Move to next line
-                        $this->x = $this->lMargin;
-                        $this->y += $h;
-                        $w = $this->w - $this->rMargin - $this->x;
-                        $wmax = ($w - 2 * $this->cMargin) * 1000 / $this->FontSize;
-                        $i += $n;
-                        $nl++;
-                        continue;
-                    }
-                    if($i == $j)
-                        $i += $n;
-                    $this->Cell($w, $h, substr($s, $j, $i - $j), 0, 2, '', 0, $link);
-                }
-                else {
-                    $this->Cell($w, $h, substr($s, $j, $sep - $j), 0, 2, '', 0, $link);
-                    $i = ($s[$sep] == ' ') ? $sep + 1 : $sep;
-                }
-                $sep =- 1;
-                $j = $i;
-                $l = 0;
-                if ($nl == 1) {
-                    $this->x = $this->lMargin;
-                    $w = $this->w - $this->rMargin - $this->x;
-                    $wmax = ($w - 2 * $this->cMargin) * 1000 / $this->FontSize;
-                }
-                $nl++;
-            }
-            else {
-                $i += $n;
-                if ($o >= 128) {
-                    $sep = $i;
-                }
-            }
-        }
-        //Last chunk
-        if ($i != $j) {
-            $this->Cell($l / 1000 * $this->FontSize, $h, substr($s, $j, $i - $j), 0, 0, '', 0, $link);
-        }
-    }
-
-    function _putfonts() {
-        $nf = $this->n;
-        foreach ($this->diffs as $diff) {
-            //Encodings
-            $this->_newobj();
-            $this->_out('<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences ['.$diff.']>>');
-            $this->_out('endobj');
-        }
-        $mqr = get_magic_quotes_runtime();
-        set_magic_quotes_runtime(0);
-        foreach ($this->FontFiles as $file => $info) {
-            //Font file embedding
-            $this->_newobj();
-            $this->FontFiles[$file]['n'] = $this->n;
-            if (defined('FPDF_FONTPATH')) {
-                $file = FPDF_FONTPATH . $file;
-            }
-            $size = filesize($file);
-            if (!$size) {
-                $this->Error('Font file not found');
-            }
-            $this->_out('<</Length '.$size);
-            if (substr($file, -2) == '.z') {
-                $this->_out('/Filter /FlateDecode');
-            }
-            $this->_out('/Length1 '.$info['length1']);
-            if (isset($info['length2'])) {
-                $this->_out('/Length2 '.$info['length2'].' /Length3 0');
-            }
-            $this->_out('>>');
-            $f = fopen($file, 'rb');
-            $this->_putstream(fread($f, $size));
-            fclose($f);
-            $this->_out('endobj');
-        }
-        set_magic_quotes_runtime($mqr);
-        foreach ($this->fonts as $k => $font) {
-            //Font objects
-            $this->_newobj();
-            $this->fonts[$k]['n'] = $this->n;
-            $this->_out('<</Type /Font');
-            if ($font['type'] == 'Type0') {
-                $this->_putType0($font);
-            } else {
-                $name = $font['name'];
-                $this->_out('/BaseFont /'.$name);
-                if ($font['type'] == 'core') {
-                    //Standard font
-                    $this->_out('/Subtype /Type1');
-                    if ($name!='Symbol' && $name!='ZapfDingbats') {
-                        $this->_out('/Encoding /WinAnsiEncoding');
-                    }
-                }
-                else {
-                    //Additional font
-                    $this->_out('/Subtype /'.$font['type']);
-                    $this->_out('/FirstChar 32');
-                    $this->_out('/LastChar 255');
-                    $this->_out('/Widths '.($this->n+1).' 0 R');
-                    $this->_out('/FontDescriptor '.($this->n+2).' 0 R');
-                    if ($font['enc']) {
-                        if (isset($font['diff'])) {
-                            $this->_out('/Encoding '.($nf+$font['diff']).' 0 R');
-                        }
-                        else {
-                            $this->_out('/Encoding /WinAnsiEncoding');
-                        }
-                    }
-                }
-                $this->_out('>>');
-                $this->_out('endobj');
-                if ($font['type'] != 'core') {
-                    //Widths
-                    $this->_newobj();
-                    $cw =& $font['cw'];
-                    $s = '[';
-                    for ($i = 32; $i <= 255 ; $i++) {
-                        $s .= $cw[chr($i)] . ' ';
-                    }
-                    $this->_out($s . ']');
-                    $this->_out('endobj');
-                    //Descriptor
-                    $this->_newobj();
-                    $s = '<</Type /FontDescriptor /FontName /' . $name;
-                    foreach ($font['desc'] as $k => $v) {
-                        $s .= ' /' . $k . ' ' . $v;
-                    }
-                    $file = $font['file'];
-                    if ($file) {
-                        $s .= ' /FontFile' . ($font['type'] == 'Type1' ? '' : '2') . ' ' . $this->FontFiles[$file]['n'] . ' 0 R';
-                    }
-                    $this->_out($s . '>>');
-                    $this->_out('endobj');
-                }
-            }
-        }
-    }
-
-    function _putType0($font) {
-        //Type0
-        $this->_out('/Subtype /Type0');
-        $this->_out('/BaseFont /' . $font['name'] . '-' . $font['CMap']);
-        $this->_out('/Encoding /' . $font['CMap']);
-        $this->_out('/DescendantFonts [' . ($this->n + 1) . ' 0 R]');
-        $this->_out('>>');
-        $this->_out('endobj');
-        //CIDFont
-        $this->_newobj();
-        $this->_out('<</Type /Font');
-        $this->_out('/Subtype /CIDFontType0');
-        $this->_out('/BaseFont /' . $font['name']);
-        $this->_out('/CIDSystemInfo <</Registry (Adobe) /Ordering (' . $font['registry']['ordering'] . ') /Supplement ' . $font['registry']['supplement'] . '>>');
-        $this->_out('/FontDescriptor ' . ($this->n + 1) . ' 0 R');
-        $W = '/W [1 [';
-        foreach ($font['cw'] as $w) {
-            $W .= $w . ' ';
-        }
-        $this->_out($W . '] 231 325 500 631 [500] 326 389 500]');
-        $this->_out('>>');
-        $this->_out('endobj');
-        //Font descriptor
-        $this->_newobj();
-        $this->_out('<</Type /FontDescriptor');
-        $this->_out('/FontName /' . $font['name']);
-        $this->_out('/Flags 6');
-        $this->_out('/FontBBox [0 -200 1000 900]');
-        $this->_out('/ItalicAngle 0');
-        $this->_out('/Ascent 800');
-        $this->_out('/Descent -200');
-        $this->_out('/CapHeight 800');
-        $this->_out('/StemV 60');
-        $this->_out('>>');
-        $this->_out('endobj');
-    }
-
-    //Load data
-    function LoadData($file) {
-        //Read file lines
-        $lines = file($file);
-        $data = array();
-        foreach ($lines as $line)
-            $data[] = explode(';', chop($line));
-        return $data;
-    }
-
-    //Colored table
+        parent::Cell($w, $h, substr($s, $j, $i - $j), $b, 0, $align, $fill);
+        // メソッド内でY軸を増す操作を行う場合があるので戻す。
+        $this->y = $y;
+
+        return $rise_h;
+    }
+
+    /**
+     * Colored table
+     *
+     * FIXME: 後の列の高さが大きい場合、表示が乱れる。
+     */
     function FancyTable($header, $data, $w) {
-        //Colors, line width and bold font
+        // Colors, line width and bold font
         $this->SetFillColor(216, 216, 216);
         $this->SetTextColor(0);
@@ -478,48 +153,50 @@
         $this->SetLineWidth(.3);
         $this->SetFont('', 'B');
-        //Header
+        // Header
         for ($i = 0; $i < count($header); $i++) {
             $this->Cell($w[$i], 7, $header[$i], 1, 0, 'C', 1);
         }
         $this->Ln();
-        //Color and font restoration
+        // Color and font restoration
         $this->SetFillColor(235, 235, 235);
         $this->SetTextColor(0);
         $this->SetFont('');
-        //Data
+        // Data
         $fill = 0;
         foreach ($data as $row) {
             $h = 4;
             $i = 0;
+            $y = $this->y;
             $this->Cell(5, $h, '', 0, 0, '', 0, '');
             foreach ($row as $col) {
-                if ($i > 3) {
-                    $i = 0;
-                }
-                if ($i != 0) {
-                    //$this->MultiCell($w[$i], $h, number_format($col), 1, 'R', $fill, 0);
-                    $this->MultiCell($w[$i], $h, $col, 1, 'R', $fill, 0);
+                $this->y = $y;
+                // FIXME 汎用的ではない処理。この指定は呼び出し元で行うようにしたい。
+                if ($i == 0) {
+                    $align = 'L';
                 } else {
-                    $this->MultiCell($w[$i], $h, $col, 1, 'L', $fill, 0);
-                }
-                $h = $this->rise_h;
+                    $align = 'R';
+                }
+                $h = $this->SJISMultiCellForFancyTable($w[$i], $h, $col, 1, $align, $fill, 0);
                 $i++;
             }
             $this->Ln();
-            $fill =! $fill;
-
+            $fill = !$fill;
         }
         $this->Cell(5, $h, '', 0, 0, '', 0, '');
         $this->Cell(array_sum($w), 0, '', 'T');
-    }
-
-    function Footer() {
-        //º[©ç1.5 cm ÉÚ®
-        $this->SetY(-15);
-        //tHgðÝèB Arial italic 8
-        $this->SetFont('Arial', 'I', 8);
-        //»ÝÌy[WÔÆy[WðoÍ
-        #$this->Cell(0, 10, ''.$this->PageNo().' / {nb}', 0, 0, 'C');
-    }
-
+        $this->SetFillColor(255);
+    }
+
+    function Text($x, $y, $txt) {
+        parent::Text($x, $y, $this->lfConvSjis($txt));
+    }
+
+    function Cell($w, $h=0, $txt='', $border=0, $ln=0, $align='', $fill=false, $link='') {
+        parent::Cell($w, $h, $this->lfConvSjis($txt), $border, $ln, $align, $fill, $link);
+    }
+
+    // 文字コードSJIS変換 -> japanese.phpで使用出来る文字コードはSJIS-winのみ
+    function lfConvSjis($conv_str) {
+        return mb_convert_encoding($conv_str, 'SJIS-win', CHAR_CODE);
+    }
 }
