<?xml version="1.0" encoding="UTF-8"?>
<!-- Reviewed: no -->
<!-- EN-Revision: 24604 -->
<sect1 id="zend.pdf.drawing">
    <title>描画</title>

    <sect2 id="zend.pdf.drawing.geometry">
        <title>ジオメトリ</title>
        <para>
        <acronym>PDF</acronym> は PostScript と同じジオメトリを使用します。ページの左下隅を基準とし、
        デフォルトではポイント数 (1 インチの 1/72) で場所を指定します。
        </para>
        <para>
        ページの大きさはページオブジェクトから取得できます。
        </para>

        <programlisting language="php"><![CDATA[
$width  = $pdfPage->getWidth();
$height = $pdfPage->getHeight();
]]></programlisting>
    </sect2>

    <sect2 id="zend.pdf.drawing.color">
        <title>色</title>
        <para>
        <acronym>PDF</acronym> には、色を表現するためのさまざまな方法があります。<classname>Zend_Pdf</classname> では、
        グレイスケール、RGB および CMYK 色空間をサポートしています。
        <classname>Zend_Pdf_Color</classname> オブジェクトが要求される箇所では、
        これらのどれでも使用できます。それぞれの色空間に対応する機能を提供するのが
        <classname>Zend_Pdf_Color_GrayScale</classname>、<classname>Zend_Pdf_Color_Rgb</classname> および
        <classname>Zend_Pdf_Color_Cmyk</classname> クラスです。
        </para>

        <programlisting language="php"><![CDATA[
// $grayLevel (float 型の数値)。0.0 (黒) - 1.0 (白)
$color1 = new Zend_Pdf_Color_GrayScale($grayLevel);

// $r, $g, $b (float 型の数値)。0.0 (最低の強度) - 1.0 (最大の強度)
$color2 = new Zend_Pdf_Color_Rgb($r, $g, $b);

// $c, $m, $y, $k (float 型の数値)。0.0 (最小の強度) - 1.0 (最大の強度)
$color3 = new Zend_Pdf_Color_Cmyk($c, $m, $y, $k);
]]></programlisting>

        <para>
        <acronym>HTML</acronym> 形式の色指定も <classname>Zend_Pdf_Color_Html</classname> クラスで使用できます。
        </para>
        <programlisting language="php"><![CDATA[
$color1 = new Zend_Pdf_Color_Html('#3366FF');
$color2 = new Zend_Pdf_Color_Html('silver');
$color3 = new Zend_Pdf_Color_Html('forestgreen');
]]></programlisting>
    </sect2>

    <sect2 id="zend.pdf.drawing.shape-drawing">
        <title>図形の描画</title>
        <para>
        描画操作は、<acronym>PDF</acronym> のページに対して行われます。
        </para>
        <para>
        基本図形のセットが <classname>Zend_Pdf_Page</classname> クラスで提供されています。
        </para>
        <programlisting language="php"><![CDATA[
/**
 * x1,y1 から x2,y2 まで直線を描画します。
 *
 * @param float $x1
 * @param float $y1
 * @param float $x2
 * @param float $y2
 * @return Zend_Pdf_Page
 */
public function drawLine($x1, $y1, $x2, $y2);
]]></programlisting>
        <programlisting language="php"><![CDATA[
/**
 * 矩形を描画します。
 *
 * 描画方法
 * Zend_Pdf_Page::SHAPE_DRAW_FILL_AND_STROKE - 輪郭を描画して塗りつぶします (デフォルト)
 * Zend_Pdf_Page::SHAPE_DRAW_STROKE          - 輪郭を描画します
 * Zend_Pdf_Page::SHAPE_DRAW_FILL            - 矩形を塗りつぶします
 *
 * @param float $x1
 * @param float $y1
 * @param float $x2
 * @param float $y2
 * @param integer $fillType
 * @return Zend_Pdf_Page
 */
public function drawRectangle($x1, $y1, $x2, $y2,
                    $fillType = Zend_Pdf_Page::SHAPE_DRAW_FILL_AND_STROKE);
]]></programlisting>

        <programlisting language="php"><![CDATA[
/**
 * 丸みをつけた矩形を描きます。
 *
 * 描画方法
 * Zend_Pdf_Page::SHAPE_DRAW_FILL_AND_STROKE - 輪郭を描画して塗りつぶします (デフォルト)
 * Zend_Pdf_Page::SHAPE_DRAW_STROKE      - 輪郭を描画します
 * Zend_Pdf_Page::SHAPE_DRAW_FILL        - 矩形を塗りつぶします
 *
 * radius は、４つの角の半径を表す整数、または角の半径を左上から時計回りで示す４つの整数の配列です。
 *
 * @param float $x1
 * @param float $y1
 * @param float $x2
 * @param float $y2
 * @param integer|array $radius
 * @param integer $fillType
 * @return Zend_Pdf_Page
 */
public function drawRoundedRectangle($x1, $y1, $x2, $y2, $radius,
                       $fillType = Zend_Pdf_Page::SHAPE_DRAW_FILL_AND_STROKE);
]]></programlisting>
        <programlisting language="php"><![CDATA[
/**
 * 多角形を描画します。
 *
 * $fillType が Zend_Pdf_Page::SHAPE_DRAW_FILL_AND_STROKE あるいは Zend_Pdf_Page::SHAPE_DRAW_FILL
 * の場合、多角形は自動的に閉じられます。このメソッドについての詳細は、
 * PDF のドキュメント (section 4.4.2 Path painting Operators, Filling)
 * を参照ください。
 *
 * @param array $x  - float の配列 (頂点の X 座標)
 * @param array $y  - float の配列 (頂点の Y 座標)
 * @param integer $fillType
 * @param integer $fillMethod
 * @return Zend_Pdf_Page
 */
public function drawPolygon($x, $y,
                            $fillType =
                                Zend_Pdf_Page::SHAPE_DRAW_FILL_AND_STROKE,
                            $fillMethod =
                                Zend_Pdf_Page::FILL_METHOD_NON_ZERO_WINDING);
]]></programlisting>
        <programlisting language="php"><![CDATA[
/**
 * 中心が x, y で半径が radius の円を描画します。
 *
 * 角度はラジアンで指定します。
 *
 * Method signatures:
 * drawCircle($x, $y, $radius);
 * drawCircle($x, $y, $radius, $fillType);
 * drawCircle($x, $y, $radius, $startAngle, $endAngle);
 * drawCircle($x, $y, $radius, $startAngle, $endAngle, $fillType);
 *
 *
 * これは本当の円ではありません。PDF は 3 次ベジエ曲線しかサポートしていないからです。
 * とはいえ、本当の円にかなり近くなります。
 * 本当の円との誤差は、最大でも半径の 0.00026 倍にしかなりません
 * (角度が PI/8, 3*PI/8, 5*PI/8, 7*PI/8, 9*PI/8, 11*PI/8, 13*PI/8 そして 15*PI/8 の場合)。
 * 0, PI/4, PI/2, 3*PI/4, PI, 5*PI/4, 3*PI/2 そして 7*PI/4 の場合は、円の正確な接線となります。
 *
 * @param float $x
 * @param float $y
 * @param float $radius
 * @param mixed $param4
 * @param mixed $param5
 * @param mixed $param6
 * @return Zend_Pdf_Page
 */
public function  drawCircle($x,
                            $y,
                            $radius,
                            $param4 = null,
                            $param5 = null,
                            $param6 = null);
]]></programlisting>
        <programlisting language="php"><![CDATA[
/**
 * 指定した矩形に内接する楕円を描画します。
 *
 * Method signatures:
 * drawEllipse($x1, $y1, $x2, $y2);
 * drawEllipse($x1, $y1, $x2, $y2, $fillType);
 * drawEllipse($x1, $y1, $x2, $y2, $startAngle, $endAngle);
 * drawEllipse($x1, $y1, $x2, $y2, $startAngle, $endAngle, $fillType);
 *
 * 角度はラジアンで指定します。
 *
 * @param float $x1
 * @param float $y1
 * @param float $x2
 * @param float $y2
 * @param mixed $param5
 * @param mixed $param6
 * @param mixed $param7
 * @return Zend_Pdf_Page
 */
public function drawEllipse($x1,
                            $y1,
                            $x2,
                            $y2,
                            $param5 = null,
                            $param6 = null,
                            $param7 = null);
]]></programlisting>
    </sect2>

    <sect2 id="zend.pdf.drawing.text-drawing">
        <title>テキストの描画</title>
        <para>
        テキストに対する描画操作も、<acronym>PDF</acronym> のページに対して行われます。
        ベースラインの x 座標および y 座標を指定することで、
        ページ内の任意の場所にテキストを 1 行描画できます。
        現在のフォント、フォントサイズおよびページの塗りつぶしの色を使用して、描画操作が行われます
        (詳細は、以下を参照ください)。
        </para>
        <programlisting language="php"><![CDATA[
/**
 * 指定した位置にテキストを描画します。
 *
 * @param string $text
 * @param float $x
 * @param float $y
 * @param string $charEncoding (オプション) ソーステキストの文字エンコーディング。
 *   デフォルトは現在のロケールです。
 * @throws Zend_Pdf_Exception
 * @return Zend_Pdf_Page
 */
public function drawText($text, $x, $y, $charEncoding = '');
]]></programlisting>
        <example id="zend.pdf.drawing.text-drawing.example-1">
            <title>ページ上への文字列の描画</title>
            <programlisting language="php"><![CDATA[
...
$pdfPage->drawText('Hello world!', 72, 720);
...
]]></programlisting>
        </example>

        <example id="zend.pdf.drawing.text-drawing.example-2">
            <title>フォントの色を設定</title>

            <programlisting language="php"><![CDATA[
...
$pdfPage->setFillColor(Zend_Pdf_Color_Html::color('#990000'))
        ->drawText('Hello world (in red)!', 72, 720);
....
]]></programlisting>
        </example>

        <para>
        デフォルトでは、現在のロケールのエンコーディングによって
        テキストの文字列が解釈されます。異なるエンコーディングを使用している場合
        (例えば、ディスク上のファイルから UTF-8 の文字列を読み込んだり
        レガシーなデータベースから MacRoman の文字列を取得したりなど) は、
        描画の際に文字エンコーディングを指定できます。
        そうすることで、<classname>Zend_Pdf</classname> が変換処理を行います。<acronym>PHP</acronym> の
        <ulink url="http://www.php.net/manual/ja/function.iconv.php">iconv()</ulink>
        関数がサポートしているエンコーディングなら、すべて入力として使用することが可能です。
        </para>
        <example id="zend.pdf.drawing.text-drawing.example-3">
            <title>UTF-8 でエンコードされた文字列をページに描画する</title>
            <programlisting language="php"><![CDATA[
...
// UTF-8 エンコードされた文字列をディスクから読み込みます
$unicodeString = fread($fp, 1024);

// 文字列をページ上に描画します
$pdfPage->drawText($unicodeString, 72, 720, 'UTF-8');
...
]]></programlisting>
        </example>
    </sect2>

    <sect2 id="zend.pdf.drawing.using-fonts">
        <title>フォントの使用</title>
        <para>
        <methodname>Zend_Pdf_Page::drawText()</methodname> は、
        現在設定されているフォントおよびフォントサイズを使用します。
        これは <methodname>Zend_Pdf_Page::setFont()</methodname> メソッドで設定できます。
        </para>
        <programlisting language="php"><![CDATA[
/**
 * 現在のフォントを設定します。
 *
 * @param Zend_Pdf_Resource_Font $font
 * @param float $fontSize
 * @return Zend_Pdf_Page
 */
public function setFont(Zend_Pdf_Resource_Font $font, $fontSize);
]]></programlisting>
        <para>
        <acronym>PDF</acronym> ドキュメントは、PostScript Type 1 フォントおよび TrueType フォントだけでなく、
        <acronym>PDF</acronym> 用の特別な形式である Type 3 フォントや複合フォントもサポートしています。
        すべての <acronym>PDF</acronym> ビューアには、以下の 14 種類の標準 Type 1 フォントが組み込まれています。
        その内容は Courier (4 種類)、Helvetica (4 種類)、Times (4 種類)、Symbol
        そして Zapf Dingbats です。
        </para>
        <para>
        現在 <classname>Zend_Pdf</classname> は、標準の 14 種類の <acronym>PDF</acronym> フォントだけでなく
        独自の TrueType フォントもサポートしています。フォントオブジェクトを取得するには、
        2 種類のファクトリーメソッドのいずれかを使用します。使用するメソッドは、
        標準の 14 種類の <acronym>PDF</acronym> フォントの場合は <methodname>Zend_Pdf_Font::fontWithName($fontName)</methodname>、
        独自のフォントの場合は <methodname>Zend_Pdf_Font::fontWithPath($filePath)</methodname> です。
        </para>
        <example id="zend.pdf.drawing.using-fonts.example-1">
            <title>標準フォントの作成</title>
            <programlisting language="php"><![CDATA[
...
// 新しいフォントを作成します。
$font = Zend_Pdf_Font::fontWithName(Zend_Pdf_Font::FONT_HELVETICA);

// フォントを適用します。
$pdfPage->setFont($font, 36);
...
]]></programlisting>
        </example>
        <para>
        14 種類の標準フォント名を表す定数は、<classname>Zend_Pdf_Font</classname> クラスで定義されています。
        <itemizedlist>
            <listitem>
                <para>Zend_Pdf_Font::FONT_COURIER</para>
            </listitem>
            <listitem>
                <para>Zend_Pdf_Font::FONT_COURIER_BOLD</para>
            </listitem>
            <listitem>
                <para>Zend_Pdf_Font::FONT_COURIER_ITALIC</para>
            </listitem>
            <listitem>
                <para>Zend_Pdf_Font::FONT_COURIER_BOLD_ITALIC</para>
            </listitem>
            <listitem>
                <para>Zend_Pdf_Font::FONT_TIMES</para>
            </listitem>
            <listitem>
                <para>Zend_Pdf_Font::FONT_TIMES_BOLD</para>
            </listitem>
            <listitem>
                <para>Zend_Pdf_Font::FONT_TIMES_ITALIC</para>
            </listitem>
            <listitem>
                <para>Zend_Pdf_Font::FONT_TIMES_BOLD_ITALIC</para>
            </listitem>
            <listitem>
                <para>Zend_Pdf_Font::FONT_HELVETICA</para>
            </listitem>
            <listitem>
                <para>Zend_Pdf_Font::FONT_HELVETICA_BOLD</para>
            </listitem>
            <listitem>
                <para>Zend_Pdf_Font::FONT_HELVETICA_ITALIC</para>
            </listitem>
            <listitem>
                <para>Zend_Pdf_Font::FONT_HELVETICA_BOLD_ITALIC</para>
            </listitem>
            <listitem>
                <para>Zend_Pdf_Font::FONT_SYMBOL</para>
            </listitem>
            <listitem>
                <para>Zend_Pdf_Font::FONT_ZAPFDINGBATS</para>
            </listitem>
        </itemizedlist>
        </para>
        <para>
        任意の TrueType フォント (通常は '.ttf' という拡張子です) も使用できますし、
        TrueType アウトラインを含む OpenType フォント (拡張子は '.otf')
        を使用することも可能です。現在はまだサポートしていませんが、将来は
        Mac OS X の .dfont ファイルや Microsoft TrueType Collection
        (拡張子 '.ttc') ファイルもサポートする予定です。
        </para>
        <para>
        TrueType フォントを使用するには、フォントへのフルパスを指定しなければなりません。
        何らかの理由でフォントが読み込めなかった場合、あるいはそれが TrueType
        フォントでなかった場合は、ファクトリーメソッドが例外をスローします。
        </para>
        <example id="zend.pdf.drawing.using-fonts.example-2">
            <title>TrueType フォントの作成</title>
            <programlisting language="php"><![CDATA[
...
// 新しいフォントを作成します
$goodDogCoolFont = Zend_Pdf_Font::fontWithPath('/path/to/GOODDC__.TTF');

// フォントを適用します
$pdfPage->setFont($goodDogCoolFont, 36);
...
]]></programlisting>
        </example>
        <para>
        デフォルトでは、独自のフォントは <acronym>PDF</acronym> ドキュメントに埋め込まれます。
        そのため、閲覧者のシステムにそのフォントがインストールされていなくても、
        ページをきちんと閲覧できるようになります。ファイルの大きさが気になる場合は、
        ファクトリーメソッドのオプションで「フォントを埋め込まない」ことを指定できます。
        </para>
        <example id="zend.pdf.drawing.using-fonts.example-3">
            <title>TrueType を作成するが、PDF ドキュメントには埋め込まない</title>
            <programlisting language="php"><![CDATA[
...
// 新しいフォントを作成します
$goodDogCoolFont = Zend_Pdf_Font::fontWithPath('/path/to/GOODDC__.TTF',
                                               Zend_Pdf_Font::EMBED_DONT_EMBED);

// フォントを適用します
$pdfPage->setFont($goodDogCoolFont, 36);
...
]]></programlisting>
        </example>
        <para>
        <acronym>PDF</acronym> ファイルにフォントが埋め込まれていないけれども
        閲覧者のシステムにはそのフォントがインストールされている場合は、ドキュメントは通常通りに閲覧できます。
        もし適切なフォントがインストールされていないは、<acronym>PDF</acronym> 閲覧アプリケーションが適切な代替フォントを選択します。
        </para>
        <para>
        中には、<acronym>PDF</acronym> ドキュメントへの埋め込みを禁止するようなライセンスを使用しているフォントもあります。
        これをあなどってはいけません。もし埋め込めないフォントを利用しようとすると、
        ファクトリーメソッドは例外をスローします。
        </para>
        <para>
        このようなフォントを使用することも可能ですが、そのためには、
        上で説明した「埋め込まない」フラグを使用するか、あるいは例外を抑制しなければなりません。
        </para>
        <example id="zend.pdf.drawing.using-fonts.example-4">
            <title>埋め込みが禁止されているフォントで、例外をスローさせないようにする</title>
            <programlisting language="php"><![CDATA[
...
$font = Zend_Pdf_Font::fontWithPath(
           '/path/to/unEmbeddableFont.ttf',
           Zend_Pdf_Font::EMBED_SUPPRESS_EMBED_EXCEPTION
        );
...
]]></programlisting>
        </example>
        <para>
        利用者にフォントを選択させる場合などは、この抑制方法を使用することをお勧めします。
        <acronym>PDF</acronym> ドキュメントに埋め込めるフォントなら埋め込むでしょうし、
        埋め込めないフォントは埋め込まないでしょう。
        </para>
        <para>
        フォントのサイズは比較的大きく、中には 10 メガバイトに達するものもあります。
        デフォルトでは埋め込みフォントは Flate 圧縮され、平均して 50% ほどサイズを節約できます。
        何らかの理由でフォントを圧縮したくない場合は、以下のオプションで圧縮を無効にできます。
        </para>
        <example id="zend.pdf.drawing.using-fonts.example-5">
            <title>埋め込みフォントを圧縮しない</title>
            <programlisting language="php"><![CDATA[
...
$font = Zend_Pdf_Font::fontWithPath('/path/to/someReallyBigFont.ttf',
                                    Zend_Pdf_Font::EMBED_DONT_COMPRESS);
...
]]></programlisting>
        </example>
        <para>
        最後に、必要に応じていくつかの埋め込みオプションをビット OR 演算子で連結することもできます。
        </para>
        <example id="zend.pdf.drawing.using-fonts.example-6">
            <title>フォントの埋め込みオプションを組み合わせる</title>
            <programlisting language="php"><![CDATA[
...
$font = Zend_Pdf_Font::fontWithPath(
            $someUserSelectedFontPath,
            (Zend_Pdf_Font::EMBED_SUPPRESS_EMBED_EXCEPTION |
            Zend_Pdf_Font::EMBED_DONT_COMPRESS));
...
]]></programlisting>
        </example>
    </sect2>

    <sect2 id="zend.pdf.drawing.standard-fonts-limitations">
        <title>標準 PDF フォントの制限</title>
        <para>
            標準 <acronym>PDF</acronym> フォントは、いくつかのシングルバイトエンコーディング
            (詳細は <ulink url="http://www.adobe.com/devnet/acrobat/pdfs/pdf_reference_1-7.pdf"><acronym>PDF</acronym> Reference, Sixth Edition, version 1.7</ulink>
            の Appendix D を参照ください) を内部的に使用しています。
            これらは、ほぼ Latin1 文字セットと同じものです (Symbol フォントと ZapfDingbats
            フォントは例外です)。
        </para>
        <para>
            <classname>Zend_Pdf</classname> は、標準フォントでのテキストの描画時に CP1252 (WinLatin1) を使用します。
        </para>
        <para>
            他のエンコーディングでもテキストは描画できますが、
            現在のロケールと異なる場合はそれを指定する必要があります。
            実際に描画されるのは WinLatin1 の文字のみです。
        </para>
        <example id="zend.pdf.drawing.using-fonts.example-7">
            <title>フォント埋め込みオプションの使用</title>
            <programlisting language="php"><![CDATA[
...
$font = Zend_Pdf_Font::fontWithName(Zend_Pdf_Font::FONT_COURIER);
$pdfPage->setFont($font, 36)
        ->drawText('Euro sign - €', 72, 720, 'UTF-8')
        ->drawText('Text with umlauts - à è ì', 72, 650, 'UTF-8');
...
]]></programlisting>
        </example>
    </sect2>

    <sect2 id="zend.pdf.drawing.extracting-fonts">
        <title>フォントの抽出</title>
        <para>
            <classname>Zend_Pdf</classname> モジュールを使用すると、読み込んだドキュメントからフォントを抽出できるようになります。
        </para>

        <para>
            これは、ドキュメントをインクリメンタルに更新する際に便利です。
            この機能がなければ、ドキュメントを更新するたびにフォントをアタッチしたり
            ドキュメントに埋め込んだりしなければならなくなります。
        </para>

        <para>
            <classname>Zend_Pdf</classname> オブジェクトおよび <classname>Zend_Pdf_Page</classname> オブジェクトには、
            ドキュメントやページ内のすべてのフォントを抽出するためのメソッドが用意されています。
        </para>
        <example id="zend.pdf.drawing.extracting-fonts.example-1">
            <title>読み込んだドキュメントからのフォントの抽出</title>
            <programlisting language="php"><![CDATA[
...
$pdf = Zend_Pdf::load($documentPath);
...
// ドキュメントのすべてのフォントを取得します
$fontList = $pdf->extractFonts();
$pdf->pages[] = ($page = $pdf->newPage(Zend_Pdf_Page::SIZE_A4));
$yPosition = 700;
foreach ($fontList as $font) {
    $page->setFont($font, 15);
    $fontName = $font->getFontName(Zend_Pdf_Font::NAME_POSTSCRIPT,
                                   'en',
                                   'UTF-8');
    $page->drawText($fontName . ': The quick brown fox jumps over the lazy dog',
                    100,
                    $yPosition,
                    'UTF-8');
    $yPosition -= 30;
}
...
// ドキュメントの最初のページで用いられているフォントを取得します
$firstPage = reset($pdf->pages);
$firstPageFonts = $firstPage->extractFonts();
...
]]></programlisting>
        </example>
        <example id="zend.pdf.drawing.extracting-fonts.example-2">
            <title>フォント名の指定による、読み込んだドキュメントからのフォントの抽出</title>
            <programlisting language="php"><![CDATA[
...
$pdf = new Zend_Pdf();
...
$pdf->pages[] = ($page = $pdf->newPage(Zend_Pdf_Page::SIZE_A4));

$font = Zend_Pdf_Font::fontWithPath($fontPath);
$page->setFont($font, $fontSize);
$page->drawText($text, $x, $y);
...
// フォント名をどこかに保存しておきます...
$fontName = $font->getFontName(Zend_Pdf_Font::NAME_POSTSCRIPT,
                               'en',
                               'UTF-8');
...
$pdf->save($docPath);
...
]]></programlisting>
            <programlisting language="php"><![CDATA[
...
$pdf = Zend_Pdf::load($docPath);
...
$pdf->pages[] = ($page = $pdf->newPage(Zend_Pdf_Page::SIZE_A4));

/* $srcPage->extractFont($fontName) としてもかまいません */
$font = $pdf->extractFont($fontName);

$page->setFont($font, $fontSize);
$page->drawText($text, $x, $y);
...
$pdf->save($docPath, true /* インクリメンタル更新モード */);
...
]]></programlisting>
        </example>

        <para>
            フォントの抽出はどこででもできますが、次のような制限があります。
            <itemizedlist>
                <listitem><para>抽出したフォントは、そのフォントの抽出元と同じドキュメント内でしか使用できません。</para></listitem>
                <listitem>
                    <para>
                        埋め込まれたフォントプログラムは実際には抽出されません。
                        つまり、抽出されたフォントは元のフォントメトリクス
                        (テキストの幅の計算に使用するもの) と同じものになりません。
            <programlisting language="php"><![CDATA[
...
$font = $pdf->extractFont($fontName);
$originalFont = Zend_Pdf_Font::fontWithPath($fontPath);

$page->setFont($font /* 描画用に抽出したフォント */, $fontSize);
$xPosition = $x;
for ($charIndex = 0; $charIndex < strlen($text); $charIndex++) {
    $page->drawText($text[$charIndex], xPosition, $y);

    // テキストの幅の計算には元のフォントを使用します
    $width = $originalFont->widthForGlyph(
                 $originalFont->glyphNumberForCharacter($text[$charIndex])
             );
    $xPosition += $width/$originalFont->getUnitsPerEm()*$fontSize;
}
...
]]></programlisting>
                    </para>
                </listitem>
            </itemizedlist>
        </para>
    </sect2>

    <sect2 id="zend.pdf.drawing.image-drawing">
        <title>画像の描画</title>
        <para>
        <classname>Zend_Pdf_Page</classname> クラスの drawImage() メソッドで、
        画像の描画を行います。
        </para>
        <programlisting language="php"><![CDATA[
/**
 * ページ内の指定した位置に画像を描画します。
 *
 * @param Zend_Pdf_Resource_Image $image
 * @param float $x1
 * @param float $y1
 * @param float $x2
 * @param float $y2
 * @return Zend_Pdf_Page
 */
public function drawImage(Zend_Pdf_Resource_Image $image, $x1, $y1, $x2, $y2);
]]></programlisting>
        <para>
        画像オブジェクトは、<methodname>Zend_Pdf_Image::imageWithPath($filePath)</methodname>
        メソッドで作成しなければなりません (現在は JPG、PNG および TIFF
        画像をサポートしています)。
        </para>
        <example id="zend.pdf.drawing.image-drawing.example-1">
            <title>画像の描画</title>
            <programlisting language="php"><![CDATA[
...
// 画像を読み込みます
$image = Zend_Pdf_Image::imageWithPath('my_image.jpg');

$pdfPage->drawImage($image, 100, 100, 400, 300);
...
]]></programlisting>
        </example>

        <para>
            <emphasis>重要! JPEG のサポートには <acronym>PHP</acronym> の GD 拡張モジュールを必要とします。</emphasis>
            <emphasis>重要! PNG でアルファチャネルを使用した画像を扱うには、ZLIB 拡張モジュールを必要とします。</emphasis>
        </para>
        <para>
            詳細な情報は、<acronym>PHP</acronym> のドキュメント
            (<ulink url="http://www.php.net/manual/ja/ref.image.php">http://www.php.net/manual/ja/ref.image.php</ulink>),
            (<ulink url="http://www.php.net/manual/ja/ref.zlib.php">http://www.php.net/manual/ja/ref.zlib.php</ulink>)
            を参照ください。
        </para>
    </sect2>

    <sect2 id="zend.pdf.drawing.line-drawing-style">
        <title>直線の描画スタイル</title>
        <para>
        直線の描画スタイルは、線幅と線の色、そして破線のパターンで定義されます。
        これらはすべて、<classname>Zend_Pdf_Page</classname> クラスのメソッドで設定します。
        </para>
        <programlisting language="php"><![CDATA[
/** 線の色を設定します。*/
public function setLineColor(Zend_Pdf_Color $color);

/** 線の幅を設定します。*/
public function setLineWidth(float $width);

/**
 * 破線のパターンを設定します。
 *
 * pattern は float の配列です:
 *     array(on_length, off_length, on_length, off_length, ...)
 * phase は線の開始位置から移動する距離です。
 *
 * @param array $pattern
 * @param array $phase
 * @return Zend_Pdf_Page
 */
public function setLineDashingPattern($pattern, $phase = 0);
]]></programlisting>
    </sect2>

    <sect2 id="zend.pdf.drawing.fill-style">
        <title>塗りつぶしのスタイル</title>
        <para>
        <methodname>Zend_Pdf_Page::drawRectangle()</methodname>、<methodname>Zend_Pdf_Page::drawPolygon()</methodname>、
        <methodname>Zend_Pdf_Page::drawCircle()</methodname> および <methodname>Zend_Pdf_Page::drawEllipse()</methodname>
        メソッドは、オプションのパラメータとして <varname>$fillType</varname>
        を受け取ります。これは以下のいずれかの値となります。
        </para>

        <itemizedlist>
            <listitem>
                <para>Zend_Pdf_Page::SHAPE_DRAW_STROKE - 図形の輪郭を描画します</para>
            </listitem>
            <listitem>
                <para>Zend_Pdf_Page::SHAPE_DRAW_FILL - 図形を塗りつぶすだけです</para>
            </listitem>
            <listitem>
                <para>Zend_Pdf_Page::SHAPE_DRAW_FILL_AND_STROKE - 輪郭を描画し、塗りつぶします (デフォルトの挙動です)</para>
            </listitem>
        </itemizedlist>

        <para>
        <methodname>Zend_Pdf_Page::drawPolygon()</methodname> メソッドには、さらにパラメータ
        <varname>$fillMethod</varname> を指定できます。
        </para>
        <itemizedlist>
            <listitem>
                <para>Zend_Pdf_Page::FILL_METHOD_NON_ZERO_WINDING (デフォルトの挙動)</para>
                <para>
                <citetitle><acronym>PDF</acronym> リファレンス</citetitle> によると、これは以下のように定義されています。
                <blockquote>
                    <para>
                        nonzero winding number ルールは、ある点がパスの内側にあるかどうかを
                        判断するため、その点からどこかの方向に放射線を引いて
                        その線がパスを構成する線と交わる場所を調べます。
                        0 からカウントをはじめ、放射線の左から右にパスの線が横切った場合に
                        +1、放射線の右から左に横切った場合に -1 します。
                        すべての交点について調べた後、もし結果が 0 ならその点はパスの外側です。
                        0 でなければ内側です。

                        注意: この方式では、放射線とパスの線が同一になった場合や
                        放射線がパスの線の接線となった場合のことを指定していません。
                        放射線は任意の方向に伸ばせるので、このような状況にならないような放射線が選ばれます。
                        単純な凸状のパスの場合、この方式で判断した内側・外側は、
                        直感的に予想できるのと同じ結果になります。
                        ただ、パスを構成する線自身が交わっているなどの複雑なパスの場合は、
                        興味深い結果となります。この例を、(<acronym>PDF</acronym> リファレンスの) 図 4.10 に示します。

                        5 本の直線を互いに交差させて作成した星型の場合、このルールでは
                        星型で囲まれるすべての部分をパスの内側として扱います。真ん中の
                        五角形も内側となります。2 つの同心円からなるパスの場合、
                        2 つの円が同じ方向に描画された際には両方の円に囲まれている部分が
                        内側となります。2 つの円が反対方向に描画された際には、2 つの円からなる
                        「ドーナツ型」の部分が内側となります。このルールの場合は、
                        「ドーナツの穴」の部分は外側という扱いになります。
                    </para>
                </blockquote>
                </para>
            </listitem>
            <listitem>
                <para>Zend_Pdf_Const::FILLMETHOD_EVENODD</para>
                <para>
                <citetitle><acronym>PDF</acronym> リファレンス</citetitle> によると、これは以下のように定義されています。
                <blockquote>
                    <para>
                        nonzero winding number ルールに対するもうひとつのルールが even-odd ルールです。
                        このルールでは、ある点が「内側である」かどうかを判断する材料として、
                        その点からどこかの方向に放射線を引いてその線がパスを構成する線と何回交わるか
                        ということを用います。交わる回数が奇数だった場合、その点は内側です。
                        交わる回数が偶数だった場合、その点は外側です。単純なパスの場合は、
                        これは nonzero winding number ルールと同じ結果になります。
                        しかし、複雑な図形の場合は異なる結果となります。

                        複雑なパスに対して even-odd ルールを適用した場合の例を (<acronym>PDF</acronym> リファレンスの)
                        図 4.11 に示します。このルールの場合、5 本の交差する直線からなる星型では、
                        三角形の部分のみが内側として扱われます。真ん中の五角形は、内側とはみなされません。
                        2 つの同心円の場合、2 つの円からなる「ドーナツ型」の部分のみが内側として扱われます。
                        これは、円の描画された方向に依存しません。
                    </para>
                </blockquote>
            </para>
            </listitem>
        </itemizedlist>
    </sect2>

    <sect2 id="zend.pdf.drawing.linear-transformations">
        <title>線形変換</title>
        <sect3 id="zend.pdf.drawing.linear-transformations.rotations">
            <title>回転</title>
            <para>
            描画操作を適用する前に、<acronym>PDF</acronym> のページを回転させることができます。
            それには <methodname>Zend_Pdf_Page::rotate()</methodname> メソッドを使用します。
            </para>
            <programlisting language="php"><![CDATA[
/**
 * ページを回転します。
 *
 * @param float $x  - 回転の中心の X 座標
 * @param float $y  - 回転の中心の Y 座標
 * @param float $angle - 回転角度
 * @return Zend_Pdf_Page
 */
public function rotate($x, $y, $angle);
]]></programlisting>
        </sect3>

        <sect3 id="zend.pdf.drawing.linear-transformations.scale">
            <title>ZF 1.8 以降で使用できる拡大/縮小</title>
            <para>
            倍率の変更は <methodname>Zend_Pdf_Page::scale()</methodname> メソッドで行います。
            </para>
            <programlisting language="php"><![CDATA[
/**
 * 座標系の拡大/縮小
 *
 * @param float $xScale - X 方向の倍率
 * @param float $yScale - Y 方向の倍率
 * @return Zend_Pdf_Page
 */
public function scale($xScale, $yScale);
]]></programlisting>
        </sect3>

        <sect3 id="zend.pdf.drawing.linear-transformations.translate">
            <title>ZF 1.8 以降で使用できる移動</title>
            <para>
                座標系の移動は <methodname>Zend_Pdf_Page::translate()</methodname> メソッドで行います。
            </para>
            <programlisting language="php"><![CDATA[
/**
 * 座標系の移動
 *
 * @param float $xShift - X 方向の移動
 * @param float $yShift - Y 方向の移動
 * @return Zend_Pdf_Page
 */
public function translate($xShift, $yShift);
]]></programlisting>
        </sect3>

        <sect3 id="zend.pdf.drawing.linear-transformations.skew">
            <title>ZF 1.8 以降で使用できる傾斜</title>
            <para>
                ページを傾けるには <methodname>Zend_Pdf_Page::skew()</methodname> メソッドを使用します。
            </para>
            <programlisting language="php"><![CDATA[
/**
 * 座標系の変換
 *
 * @param float $x  - 傾斜点の X 座標
 * @param float $y  - 傾斜点の Y 座標
 * @param float $xAngle - X 軸の傾斜角度
 * @param float $yAngle - Y 軸の傾斜角度
 * @return Zend_Pdf_Page
 */
public function skew($x, $y, $xAngle, $yAngle);
]]></programlisting>
        </sect3>
    </sect2>

    <sect2 id="zend.pdf.drawing.save-restore">
        <title>グラフィックの状態の保存/復元</title>
        <para>
        好きな時点でのグラフィックの状態
        (現在のフォント、フォントサイズ、線の色、塗りつぶしの色、線の形式、
        ページの回転、クリップ領域) を保存/復元できます。
        保存操作はグラフィックの状態をスタックに保存し、復元の際にはそこから取り出されます。
        </para>
        <para>
        <classname>Zend_Pdf_Page</classname>
        クラスには、これらの操作を行うための 2 つのメソッドがあります。
        </para>
        <programlisting language="php"><![CDATA[
/**
 * このページのグラフィックの状態を保存します。
 * 現在適用されているスタイル・位置・クリップ領域および
 * 回転/移動/拡大縮小などを情報を保存します。
 *
 * @return Zend_Pdf_Page
 */
public function saveGS();

/**
 * 直近の saveGS() で保存されたグラフィックの状態を復元します。
 *
 * @return Zend_Pdf_Page
 */
public function restoreGS();
]]></programlisting>
    </sect2>

    <sect2 id="zend.pdf.drawing.clipping">
        <title>描画領域のクリッピング</title>
        <para>
        <acronym>PDF</acronym> および <classname>Zend_Pdf</classname> モジュールは、描画領域のクリッピングに対応しています。
        描画演算子が影響を及ぼす範囲を、このクリップ領域内に制限します。
        クリップ領域の初期値は、ページ全体です。
        </para>
        <para>
        <classname>Zend_Pdf_Page</classname> クラスでは、
        クリッピングに関連するいくつかのメソッドを提供しています。
        </para>
        <programlisting language="php"><![CDATA[
/**
 * 矩形のクリップ領域を設定します。
 *
 * @param float $x1
 * @param float $y1
 * @param float $x2
 * @param float $y2
 * @return Zend_Pdf_Page
 */
public function clipRectangle($x1, $y1, $x2, $y2);
]]></programlisting>
        <programlisting language="php"><![CDATA[
/**
 * 多角形のクリップ領域を設定します。
 *
 * @param array $x  - float の配列 (頂点の X 座標)
 * @param array $y  - float の配列 (頂点の Y 座標)
 * @param integer $fillMethod
 * @return Zend_Pdf_Page
 */
public function clipPolygon($x,
                            $y,
                            $fillMethod =
                                Zend_Pdf_Page::FILL_METHOD_NON_ZERO_WINDING);
]]></programlisting>
        <programlisting language="php"><![CDATA[
/**
 * 円形のクリップ領域を設定します。
 *
 * @param float $x
 * @param float $y
 * @param float $radius
 * @param float $startAngle
 * @param float $endAngle
 * @return Zend_Pdf_Page
 */
public function clipCircle($x,
                           $y,
                           $radius,
                           $startAngle = null,
                           $endAngle = null);
]]></programlisting>
        <programlisting language="php"><![CDATA[
/**
 * 楕円のクリップ領域を設定します。
 *
 * メソッドの書式
 * drawEllipse($x1, $y1, $x2, $y2);
 * drawEllipse($x1, $y1, $x2, $y2, $startAngle, $endAngle);
 *
 * @todo $x2-$x1 == 0 や $y2-$y1 == 0 のような特別な場合への対応
 *
 * @param float $x1
 * @param float $y1
 * @param float $x2
 * @param float $y2
 * @param float $startAngle
 * @param float $endAngle
 * @return Zend_Pdf_Page
 */
public function clipEllipse($x1,
                            $y1,
                            $x2,
                            $y2,
                            $startAngle = null,
                            $endAngle = null);
]]></programlisting>
    </sect2>

    <sect2 id="zend.pdf.drawing.styles">
        <title>スタイル</title>
        <para>
        <classname>Zend_Pdf_Style</classname> クラスがスタイルに関する機能を提供します。
        </para>
        <para>
        スタイルは、グラフィックの状態に関する複数の設定を保存し、
        <acronym>PDF</acronym> のページに 1 回の操作でそれを適用するために使用されます。
        </para>
        <programlisting language="php"><![CDATA[
/**
 * このページの描画操作で使用する予定のスタイルを設定します。
 *
 * @param Zend_Pdf_Style $style
 * @return Zend_Pdf_Page
 */
public function setStyle(Zend_Pdf_Style $style);

/**
 * スタイルを返し、それをページに適用します。
 *
 * @return Zend_Pdf_Style|null
 */
public function getStyle();
]]></programlisting>

        <para>
        <classname>Zend_Pdf_Style</classname> クラスでは、
        さまざまなグラフィックの状態を設定あるいは取得するためのメソッドが提供されています。
        </para>
        <programlisting language="php"><![CDATA[
/**
 * 線の色を設定します。
 *
 * @param Zend_Pdf_Color $color
 * @return Zend_Pdf_Page
 */
public function setLineColor(Zend_Pdf_Color $color);
]]></programlisting>
        <programlisting language="php"><![CDATA[
/**
 * 線の色を取得します。
 *
 * @return Zend_Pdf_Color|null
 */
public function getLineColor();
]]></programlisting>
        <programlisting language="php"><![CDATA[
/**
 * 線の幅を設定します。
 *
 * @param float $width
 * @return Zend_Pdf_Page
 */
public function setLineWidth($width);
]]></programlisting>
        <programlisting language="php"><![CDATA[
/**
 * 線の幅を取得します。
 *
 * @return float
 */
public function getLineWidth();
]]></programlisting>
        <programlisting language="php"><![CDATA[
/**
 * 破線のパターンを設定します。
 *
 * @param array $pattern
 * @param float $phase
 * @return Zend_Pdf_Page
 */
public function setLineDashingPattern($pattern, $phase = 0);
]]></programlisting>
        <programlisting language="php"><![CDATA[
/**
 * 破線のパターンを取得します。
 *
 * @return array
 */
public function getLineDashingPattern();
]]></programlisting>
        <programlisting language="php"><![CDATA[
/**
 * 破線の位相を取得します。
 *
 * @return float
 */
public function getLineDashingPhase();
]]></programlisting>
        <programlisting language="php"><![CDATA[
/**
 * 塗りつぶし色を設定します。
 *
 * @param Zend_Pdf_Color $color
 * @return Zend_Pdf_Page
 */
public function setFillColor(Zend_Pdf_Color $color);
]]></programlisting>
        <programlisting language="php"><![CDATA[
/**
 * 塗りつぶし色を取得します。
 *
 * @return Zend_Pdf_Color|null
 */
public function getFillColor();
]]></programlisting>
        <programlisting language="php"><![CDATA[
/**
 * 現在のフォントを設定します。
 *
 * @param Zend_Pdf_Resource_Font $font
 * @param float $fontSize
 * @return Zend_Pdf_Page
 */
public function setFont(Zend_Pdf_Resource_Font $font, $fontSize);
]]></programlisting>
        <programlisting language="php"><![CDATA[
/**
 * 現在のフォントサイズを変更します。
 *
 * @param float $fontSize
 * @return Zend_Pdf_Page
 */
public function setFontSize($fontSize);
]]></programlisting>
        <programlisting language="php"><![CDATA[
/**
 * 現在のフォントを取得します。
 *
 * @return Zend_Pdf_Resource_Font $font
 */
public function getFont();
]]></programlisting>
        <programlisting language="php"><![CDATA[
/**
 * 現在のフォントサイズを取得します。
 *
 * @return float $fontSize
 */
public function getFontSize();
]]></programlisting>
    </sect2>

    <sect2 id="zend.pdf.drawing.alpha">
        <title>透明度</title>
        <para>
        <classname>Zend_Pdf</classname> モジュールは、透明度の処理に対応しています。
        </para>
        <para>
            透明度を設定するには <methodname>Zend_Pdf_Page::setAlpha()</methodname> メソッドを使用します。
        </para>

        <programlisting language="php"><![CDATA[
/**
 * 透明度を設定します
 *
 * $alpha == 0  - 透明
 * $alpha == 1  - 不透明
 *
 * PDF でサポートするモードは次のとおりです
 * Normal (デフォルト), Multiply, Screen, Overlay, Darken, Lighten,
 * ColorDodge, ColorBurn, HardLight, SoftLight, Difference, Exclusion
 *
 * @param float $alpha
 * @param string $mode
 * @throws Zend_Pdf_Exception
 * @return Zend_Pdf_Page
 */
public function setAlpha($alpha, $mode = 'Normal');
]]></programlisting>
    </sect2>
</sect1>
