IT-Tecスクラップ

IT技術に関する覚え書き。
Hu-BasicからVistaまで、思いついたら都度更新。

PDFlibの実践4

2006年09月06日 15時36分27秒 | PHP
  • 指定領域内に文字列を均等割付する

  • 【導入】
    「1文字当たりの文字幅を縮小」することで、領域を超過する場合の対処は行えた。
    他方、領域に満たない場合の対処はどうであろうか。

    先の、チラシに複数の店舗名を縦に列記するという例では、さらに下記のような要求が加わることがままある。
    ・領域内の最大文字数に満たない場合は、領域内に均等割付をする

    ここで言う「均等割付」とは、文字間隔(ピッチ)を増加させることにより、
    指定領域内に文字を収める(先頭文字の左端が領域の左端、末尾文字の右端が領域の右端に接する)
    という手法である。

    しかし、PDFlibには「ピッチを調整するオプションは存在しない」ようである。
    よって、自分でその仕組みを実装する必要がある。

    【1文字当たりのピッチ算出アルゴリズム】
    1.領域内の最大文字数($max_length)から1文字あたりの幅($letter_w)を算出
    2.出力文字数($length)×$letter_wで文字出力領域幅(非ピッチ領域幅)を算出
    3.領域幅($width)-非ピッチ領域幅でピッチ領域幅($pitch_total_w)を算出
    4.$pitch_total_wをピッチ適用文字数($length-1)で割って、1文字当たりのピッチ($ptich_w)を取得
    (ただし「$length > 1」かつ「$length < $max_length」)

    【例1】
    ピッチ算出処理

    /* ================================================== */
    /* 文字間隔(ピッチ)幅の取得
    /* ================================================== */
    function GetLetterPitchWidth($text,$max_length,$width) {

    //文字数を取得
    $length = mb_strlen($text);

    //最大文字数に満たない場合はピッチを適用
    if ($length < $max_length) {

    $letter_w = $width / $max_length;;

    $pitch_total_w = $width - ($length * $letter_w);

    //2文字以上の場合はピッチを適用する
    if ($length!=1) {
    $ptich_w = $pitch_total_w / ($length - 1);
    }

    //1文字しかない場合はピッチを適用しない
    else {
    $ptich_w = 0;
    }

    }

    //最大文字数以上ならばピッチは適用しない
    else {

    $ptich_w = 0;
    }

    return $ptich_w;

    }
    /* ================================================== */

    【ピッチ適用アルゴリズム】
    1.出力文字を1文字($letter)取り出す
    2.始点・終点が(x1,y1)(x2,y2)である場合、x2=x1+1文字あたりの幅($letter_w)である
    3.$letterを出力する
    4.次の文字の始点x1=現在のx2+1文字当たりのピッチ($ptich_w)である
    5.全ての出力文字を処理するまで繰り返す

    【例2】
    ピッチ適用処理


    //文字数を取得
    $length = mb_strlen($text);

    for ($i=0;$i<$length;$i++) {

    //終点(x2)は始点(x1)+1文字幅
    $xy['x2'] = $xy['x1'] + $letter_w;

    $letter = mb_substr($text,$i,1);

    //ここに1文字を出力する処理

    //次の始点(x1)は現在の終点(x2)+ピッチ幅
    $xy['x1'] = $xy['x2'] + $pitch_w;

    }

    【残った問題】
    今回の均等割付処理には、以下の問題が残っている。
    これらは解決次第、別途記述したいと思う。

  • 半角文字が含まれる場合、きれいに均等割りにならない

  • プロポーショナルフォントへの対応が漏れている