文字列中の HTML 用「数値文字参照」文字列( &#数値; ) の変換
このサンプルでは、元のソースコードが UTF-8 なので、変換が成功しますが
EUC-JP や SHIFT_JIS では変換できないので正しく表示されません。
つまり、&#数値; 表現のままであれば、全てのキャラクタセットで
文字列が正しく表示されるという事です。
( ※ DBとしてデータを正しく登録したい場合以外は変換する必要は無いという結論 )
ここで重要なのは、$b が正しい unicode 文字列 であるテストがされた
という事で、これを使って、FPDF の japanese.php を少し変更して
SHIFT_JIS ベースのソースから SHIFT_JIS に無い文字を出力する事ができます。
こちら では、画像を使ってその実現をしていますが、これを書いた
時は、まだ PDF の仕様について調査していなかったので、
簡単に unicode で渡せる事を知らなかったからです。
<? header( "Content-Type: text/html; Charset=utf-8" ); ?>
<STYLE type="text/css">
* {
font-size:22px;
}
</STYLE>
<?
mb_language( "ja" );
mb_internal_encoding("EUC-JP");
// ***********************************************
// 変換用のコールバック関数
// ***********************************************
function rep_func($matches)
{
$a = $matches[1]+0;
$b = chr(($a-($a%256))/256).chr($a%256);
$c = mb_convert_encoding( $b, "utf-8", "unicode" );
return( $c );
}
$target = "文字列中に<b>(⅓)</b>含まれた &#数値;
を実コード(<b>鼿</b>)に変換する";
$a = preg_replace_callback(
"/&#(\d+);/",
rep_func,
$target
);
print $a;
print "<br>";
print $target;
?>
EUC 用と unicode 用のフォント追加関数(AddSJISFontは、こちらを参照)
二つ追加しています。それぞれ EUC-H と UniJIS-UTF16-H を使用していますが、
これは PDF の仕様にある以下の表にあったものを使用しています。
最初、UniJIS.UCS2.H を使用してテストしていると、SHIFT_JISに無い文字
を殆ど表示できない事が解り、UniJIS.UTF16-H に変更しました。
Predefined CJK CMap |
83pv.RKSJ.H | Mac OS, JIS X 0208 character set with KanjiTalk6 extensions, Shift-JIS encoding, Script Manager code 1 |
90ms.RKSJ.H | Microsoft Code Page 932 (lfCharSet 0x80), JIS X 0208 character set with NEC and IBMRextensions |
90ms.RKSJ.V | Vertical version of 90ms.RKSJ.H |
90msp.RKSJ.H | Same as 90ms.RKSJ.H but replaces half-width Latin characters with proportional forms |
90msp.RKSJ.V | Vertical version of 90msp.RKSJ.H |
90pv.RKSJ.H | Mac OS, JIS X 0208 character set with KanjiTalk7 extensions, Shift-JIS encoding, Script Manager code 1 |
Add.RKSJ.H | JIS X 0208 character set with Fujitsu FMR extensions, Shift-JIS encoding |
Add.RKSJ.V | Vertical version of Add.RKSJ.H |
EUC.H | JIS X 0208 character set, EUC-JP encoding |
EUC.V | Vertical version of EUC.H |
Ext.RKSJ.H | JIS C 6226 (JIS78) character set with NEC extensions, Shift-JIS encoding |
Ext.RKSJ.V | Vertical version of Ext.RKSJ.H |
H | JIS X 0208 character set, ISO-2022-JP encoding |
V | Vertical version of H |
UniJIS.UCS2.H | Unicode (UCS-2) encoding for the Adobe-Japan1 character collection |
UniJIS.UCS2.V | Vertical version of UniJIS.UCS2.H |
UniJIS.UCS2.HW.H | Same as UniJIS.UCS2.H but replaces proportional Latin characters with half-width forms |
UniJIS.UCS2.HW.V | Vertical version of UniJIS.UCS2.HW.H |
UniJIS.UTF16-H | Unicode (UTF-16BE) encoding for the Adobe-Japan1 character collection; contains mappings for all characters in the JIS X 0213:1000 character set |
UniJIS.UTF16-V | Vertical version of UniJIS.UTF16-H NAME DESCRIPTION |
function AddSJISFont($font='MS-Mincho',$family='SJIS')
{
//Add SJIS font with proportional Latin
$name=$font;
$cw=$GLOBALS['SJIS_widths'];
$CMap='90msp-RKSJ-H';
$registry=array('ordering'=>'Japan1','supplement'=>2);
$this->AddCIDFonts($family,$name,$cw,$CMap,$registry);
}
function AddUJISFont($font='MS-Mincho',$family='UJIS')
{
//Add SJIS font with proportional Latin
$name=$font;
$cw=$GLOBALS['SJIS_widths'];
$CMap='EUC-H';
$registry=array('ordering'=>'Japan1','supplement'=>2);
$this->AddCIDFonts($family,$name,$cw,$CMap,$registry);
}
function AddUniJISFont($font='MS-Mincho',$family='UniJIS')
{
//Add SJIS font with proportional Latin
$name=$font;
$cw=$GLOBALS['SJIS_widths'];
$CMap='UniJIS-UTF16-H';
$registry=array('ordering'=>'Japan1','supplement'=>2);
$this->AddCIDFonts($family,$name,$cw,$CMap,$registry);
}
SHIFT_JIS 環境における、&#数値; 文字混在データを FPDF に渡す実装
SHIFT_JIS 部分は単純に UNICODE に変換すればいいのですが、&#数値; 部分は
自分でデコードするので最初にテストした、preg_replace_callback を利用して
完全コンバートします
// フォント追加
$this->AddUniJISFont();
// フォント選択
$this->SetFont( 'UniJIS', '', 16 );
// 入力値をコンバートして出力
// ※ SHIFT_JIS で 「あ⅓い鼿う」 のようなデータが対象
$this->LocText( 40, 23, ConvUniJIS($_GET['text']) );
function rep_func($matches)
{
$a = $matches[1]+0;
$b = chr(($a-($a%256))/256).chr($a%256);
$GLOBALS['uni_parts'][] = $b;
return( chr(1) );
}
function ConvUniJIS($text) {
$GLOBALS['uni_parts'] = array();
$ret =preg_replace_callback(
"/&#(\d+);/",
rep_func,
$text
);
$ar = explode(chr(1),$ret);
$result = "";
for( $i = 0; $i < count( $ar ); $i++ ) {
if ( $ar[$i] != '' ) {
$result .=
mb_convert_encoding( $ar[$i], "unicode", "shift_jis" );
}
if ( count( $ar ) > 0 ) {
if ( $i < count( $GLOBALS['uni_parts'] ) ){
$result .= $GLOBALS['uni_parts'][$i];
}
}
}
return $result;
}
で、何故か 蕙 の文字が PDF に出力できないです。
Microsoft では表示されるので、単純に考えるとAdobe のバグですが、
GD でもダメだったので、ひょっとすると Microsoft 側かもしれないです。
|
|