Previous Next

描画

ジオメトリ

PDF は PostScript と同じジオメトリを使用します。ページの左下隅を基準とし、 デフォルトではポイント数 (1 インチの 1/72) で場所を指定します。

ページの大きさはページオブジェクトから取得できます。

getWidth();
$height = $pdfPage->getHeight();

PDF には、色を表現するためのさまざまな方法があります。Zend_Pdf では、 グレイスケール、RGB および CMYK 色空間をサポートしています。 Zend_Pdf_Color オブジェクトが要求される箇所では、 これらのどれでも使用することができます。それぞれの色空間に対応する機能を提供するのが Zend_Pdf_Color_GrayScaleZend_Pdf_Color_Rgb および Zend_Pdf_Color_Cmyk クラスです。




        

HTML 形式の色指定も Zend_Pdf_Color_Html クラスで使用できます。



    

図形の描画

描画操作は、PDF のページに対して行われます。

基本図形のセットが Zend_Pdf_Page クラスで提供されています。



        


        


        


        


    

テキストの描画

テキストに対する描画操作も、PDF のページに対して行われます。 ベースラインの x 座標および y 座標を指定することで、 ページ内の任意の場所にテキストを 1 行描画することができます。 現在のフォントおよびフォントサイズを使用して、描画操作が行われます (詳細は、以下を参照ください)。



        

Example #1 ページ上への文字列の描画

drawText('Hello world!', 72, 720);
...

デフォルトでは、現在のロケールのエンコーディングによって テキストの文字列が解釈されます。異なるエンコーディングを使用している場合 (例えば、ディスク上のファイルから UTF-8 の文字列を読み込んだり レガシーなデータベースから MacRoman の文字列を取得したりなど) は、 描画の際に文字エンコーディングを指定することができます。 そうすることで、Zend_Pdf が変換処理を行います。PHP の » iconv() 関数がサポートしているエンコーディングなら、すべて入力として使用することが可能です。

Example #2 UTF-8 でエンコードされた文字列をページに描画する

drawText($unicodeString, 72, 720, 'UTF-8');
...

フォントの使用

Zend_Pdf_Page::drawText() は、 現在設定されているフォントおよびフォントサイズを使用します。 これは Zend_Pdf_Page::setFont() メソッドで設定できます。



        

PDF ドキュメントは、PostScript Type 1 フォントおよび TrueType フォントだけでなく、 PDF 用の特別な形式である Type 3 フォントや複合フォントもサポートしています。 すべての PDF ビューアには、以下の 14 種類の標準 Type 1 フォントが組み込まれています。 その内容は Courier (4 種類)、Helvetica (4 種類)、Times (4 種類)、Symbol そして Zapf Dingbats です。

現在 Zend_Pdf は、標準の 14 種類の PDF フォントだけでなく 独自の TrueType フォントもサポートしています。フォントオブジェクトを取得するには、 2 種類のファクトリーメソッドのいずれかを使用します。使用するメソッドは、 標準の 14 種類の PDF フォントの場合は Zend_Pdf_Font::fontWithName($fontName)、 独自のフォントの場合は Zend_Pdf_Font::fontWithPath($filePath) です。

Example #3 標準フォントの作成

setFont($font, 36);
...

14 種類の標準フォント名を表す定数は、Zend_Pdf_Font クラスで定義されています。

  • Zend_Pdf_Font::FONT_COURIER

  • Zend_Pdf_Font::FONT_COURIER_BOLD

  • Zend_Pdf_Font::FONT_COURIER_ITALIC

  • Zend_Pdf_Font::FONT_COURIER_BOLD_ITALIC

  • Zend_Pdf_Font::FONT_TIMES

  • Zend_Pdf_Font::FONT_TIMES_BOLD

  • Zend_Pdf_Font::FONT_TIMES_ITALIC

  • Zend_Pdf_Font::FONT_TIMES_BOLD_ITALIC

  • Zend_Pdf_Font::FONT_HELVETICA

  • Zend_Pdf_Font::FONT_HELVETICA_BOLD

  • Zend_Pdf_Font::FONT_HELVETICA_ITALIC

  • Zend_Pdf_Font::FONT_HELVETICA_BOLD_ITALIC

  • Zend_Pdf_Font::FONT_SYMBOL

  • Zend_Pdf_Font::FONT_ZAPFDINGBATS

任意の TrueType フォント (通常は '.ttf' という拡張子です) も使用できますし、 TrueType アウトラインを含む OpenType フォント (拡張子は '.otf') を使用することも可能です。現在はまだサポートしていませんが、将来は Mac OS X の .dfont ファイルや Microsoft TrueType Collection (拡張子 '.ttc') ファイルもサポートする予定です。

TrueType フォントを使用するには、フォントへのフルパスを指定しなければなりません。 何らかの理由でフォントが読み込めなかった場合、あるいはそれが TrueType フォントでなかった場合は、ファクトリーメソッドが例外をスローします。

Example #4 TrueType フォントの作成

setFont($goodDogCoolFont, 36);
...

デフォルトでは、独自のフォントは PDF ドキュメントに埋め込まれます。 そのため、閲覧者のシステムにそのフォントがインストールされていなくても、 ページをきちんと閲覧できるようになります。ファイルの大きさが気になる場合は、 ファクトリーメソッドのオプションで「フォントを埋め込まない」ことを指定することができます。

Example #5 TrueType を作成するが、PDF ドキュメントには埋め込まない

setFont($goodDogCoolFont, 36);
...

PDF ファイルにフォントが埋め込まれていないけれども 閲覧者のシステムにはそのフォントがインストールされている場合は、ドキュメントは通常通りに閲覧できます。 もし適切なフォントがインストールされていないは、PDF 閲覧アプリケーションが適切な代替フォントを選択します。

中には、PDF ドキュメントへの埋め込みを禁止するようなライセンスを使用しているフォントもあります。 これをあなどってはいけません。もし埋め込めないフォントを利用しようとすると、 ファクトリーメソッドは例外をスローします。

このようなフォントを使用することも可能ですが、そのためには、 上で説明した「埋め込まない」フラグを使用するか、あるいは例外を抑制しなければなりません。

Example #6 埋め込みが禁止されているフォントで、例外をスローさせないようにする



        

利用者にフォントを選択させる場合などは、この抑制方法を使用することをお勧めします。 PDF ドキュメントに埋め込めるフォントなら埋め込むでしょうし、 埋め込めないフォントは埋め込まないでしょう。

フォントのサイズは比較的大きく、中には 10 メガバイトに達するものもあります。 デフォルトでは埋め込みフォントは Flate 圧縮され、平均して 50% ほどサイズを節約できます。 何らかの理由でフォントを圧縮したくない場合は、以下のオプションで圧縮を無効にすることができます。

Example #7 埋め込みフォントを圧縮しない



        

最後に、必要に応じていくつかの埋め込みオプションをビット OR 演算子で連結することもできます。

Example #8 フォントの埋め込みオプションを組み合わせる



        

1.5 以降で使用できる、フォントの抽出

Zend_Pdf モジュールを使用すると、読み込んだドキュメントからフォントを抽出できるようになります。

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

Zend_Pdf オブジェクトおよび Zend_Pdf_Page オブジェクトには、 ドキュメントやページ内のすべてのフォントを抽出するためのメソッドが用意されています。

Example #9 読み込んだドキュメントからのフォントの抽出

extractFonts();
$pdf->pages[] = ($page = $pdf->newPage(Zend_Pdf_Page::SIZE_A4));
$yPosition = 700;
foreach ($fontList as $font) {
    $page->setFont($font, 15);
    $page->drawText($font->getFontName(Zend_Pdf_Font::NAME_POSTSCRIPT, 'en', 'UTF-8') 
                  . ':  The quick brown fox jumps over the lazy dog', 100, $yPosition, 'UTF-8');
    $yPosition -= 30;
}
...
// ドキュメントの最初のページで用いられているフォントを取得します
$firstPage = reset($pdf->pages);
$firstPageFonts = $firstPage->extractFonts();
...

Example #10 フォント名の指定による、読み込んだドキュメントからのフォントの抽出

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);
...
pages[] = ($page = $pdf->newPage(Zend_Pdf_Page::SIZE_A4));

$font = $pdf->extractFont($fontName);  /* $srcPage->extractFont($fontName) としてもかまいません */
$page->setFont($font, $fontSize);
$page->drawText($text, $x, $y);
...
$pdf->save($docPath, true /* インクリメンタル更新モード */);
...

フォントの抽出はどこででもできますが、次のような制限があります。

  • 抽出したフォントは、そのフォントの抽出元と同じドキュメント内でしか使用できません。

  • 埋め込まれたフォントプログラムは実際には抽出されません。 つまり、抽出されたフォントは元のフォントメトリクス (テキストの幅の計算に使用するもの) と同じものになりません。

    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);
    
        // テキストの幅の計算には元のフォントを使用します
        $xPosition += $originalFont->widthForGlyph($originalFont->glyphNumberForCharacter($text[$charIndex]))/$originalFont->getUnitsPerEm()*$fontSize;
    }
    ...

画像の描画

Zend_Pdf_Page クラスの drawImage() メソッドで、 画像の描画を行います。



        

画像オブジェクトは、Zend_Pdf_Image::imageWithPath($filePath) メソッドで作成しなければなりません (現在は JPG、PNG および TIFF 画像をサポートしています)。

Example #11 画像の描画

drawImage($image, 100, 100, 400, 300);
...

重要! JPEG のサポートには PHP の GD 拡張モジュールを必要とします。 重要! PNG でアルファチャネルを使用した画像を扱うには、ZLIB 拡張モジュールを必要とします。

詳細な情報は、PHP のドキュメント (» http://www.php.net/manual/ja/ref.image.php), (» http://www.php.net/manual/ja/ref.zlib.php) を参照ください。

直線の描画スタイル

直線の描画スタイルは、線幅と線の色、そして破線のパターンで定義されます。 これらはすべて、Zend_Pdf_Page クラスのメソッドで設定します。



    

塗りつぶしのスタイル

Zend_Pdf_Page::drawRectangle()Zend_Pdf_Page::drawPoligon()Zend_Pdf_Page::drawCircle() および Zend_Pdf_Page::drawEllipse() メソッドは、オプションのパラメータとして $fillType を受け取ります。これは以下のいずれかの値となります。

  • Zend_Pdf_Page::SHAPE_DRAW_STROKE - 図形の輪郭を描画します

  • Zend_Pdf_Page::SHAPE_DRAW_FILL - 図形を塗りつぶすだけです

  • Zend_Pdf_Page::SHAPE_DRAW_FILL_AND_STROKE - 輪郭を描画し、塗りつぶします (デフォルトの挙動です)

Zend_Pdf_Page::drawPoligon() メソッドには、さらにパラメータ $fillMethod を指定することができます。

  • Zend_Pdf_Page::FILL_METHOD_NON_ZERO_WINDING (デフォルトの挙動)

    PDF リファレンス によると、これは以下のように定義されています。

    nonzero winding number ルールは、ある点がパスの内側にあるかどうかを 判断するため、その点からどこかの方向に放射線を引いて その線がパスを構成する線と交わる場所を調べます。 0 からカウントをはじめ、放射線の左から右にパスの線が横切った場合に +1、放射線の右から左に横切った場合に -1 します。 すべての交点について調べた後、もし結果が 0 ならその点はパスの外側です。 0 でなければ内側です。 注意: この方式では、放射線とパスの線が同一になった場合や 放射線がパスの線の接線となった場合のことを指定していません。 放射線は任意の方向に伸ばせるので、このような状況にならないような放射線が選ばれます。 単純な凸状のパスの場合、この方式で判断した内側・外側は、 直感的に予想できるのと同じ結果になります。 ただ、パスを構成する線自身が交わっているなどの複雑なパスの場合は、 興味深い結果となります。この例を、(PDF リファレンスの) 図 4.10 に示します。 5 本の直線を互いに交差させて作成した星型の場合、このルールでは 星型で囲まれるすべての部分をパスの内側として扱います。真ん中の 五角形も内側となります。2 つの同心円からなるパスの場合、 2 つの円が同じ方向に描画された際には両方の円に囲まれている部分が 内側となります。2 つの円が反対方向に描画された際には、2 つの円からなる 「ドーナツ型」の部分が内側となります。このルールの場合は、 「ドーナツの穴」の部分は外側という扱いになります。

  • Zend_Pdf_Const::FILLMETHOD_EVENODD

    PDF リファレンス によると、これは以下のように定義されています。

    nonzero winding number ルールに対するもうひとつのルールが even-odd ルールです。 このルールでは、ある点が「内側である」かどうかを判断する材料として、 その点からどこかの方向に放射線を引いてその線がパスを構成する線と何回交わるか ということを用います。交わる回数が奇数だった場合、その点は内側です。 交わる回数が偶数だった場合、その点は外側です。単純なパスの場合は、 これは nonzero winding number ルールと同じ結果になります。 しかし、複雑な図形の場合は異なる結果となります。 複雑なパスに対して even-odd ルールを適用した場合の例を (PDF リファレンスの) 図 4.11 に示します。このルールの場合、5 本の交差する直線からなる星型では、 三角形の部分のみが内側として扱われます。真ん中の五角形は、内側とはみなされません。 2 つの同心円の場合、2 つの円からなる「ドーナツ型」の部分のみが内側として扱われます。 これは、円の描画された方向に依存しません。

回転

描画操作を適用する前に、PDF のページを回転させることができます。 それには Zend_Pdf_Page::rotate() メソッドを使用します。



    

グラフィックの状態の保存/復元

好きな時点でのグラフィックの状態 (現在のフォント、フォントサイズ、線の色、塗りつぶしの色、線の形式、 ページの回転、クリップ領域) を保存/復元することができます。 保存操作はグラフィックの状態をスタックに保存し、復元の際にはそこから取り出されます。

Zend_Pdf_Page クラスには、これらの操作を行うための 2 つのメソッドがあります。



    

描画領域のクリッピング

PDF および Zend_Pdf モジュールは、描画領域のクリッピングに対応しています。 描画演算子が影響を及ぼす範囲を、このクリップ領域内に制限します。 クリップ領域の初期値は、ページ全体です。

Zend_Pdf_Page クラスでは、 クリッピングに関連するいくつかのメソッドを提供しています。



        


        


        


    

スタイル

Zend_Pdf_Style クラスがスタイルに関する機能を提供します。

スタイルは、グラフィックの状態に関する複数の設定を保存し、 PDF のページに 1 回の操作でそれを適用するために使用されます。




        

Zend_Pdf_Style クラスでは、 さまざまなグラフィックの状態を設定あるいは取得するためのメソッドが提供されています。



        


        


        


        


        


        


        


        


        


        


        


        


    
Previous Next
Introduction to Zend Framework
概要
インストール
Zend_Acl
導入
アクセス制御の洗練
高度な使用法
Zend_Auth
導入
データベースのテーブルでの認証
ダイジェスト認証
HTTP 認証アダプタ
LDAP 認証
Open ID 認証
Zend_Cache
導入
キャッシュの仕組み
Zend_Cache のフロントエンド
Zend_Cache のバックエンド
Zend_Captcha
Introduction
Captcha Operation
Captcha Adapters
Zend_Config
導入
動作原理
Zend_Config_Ini
Zend_Config_Xml
Zend_Console_Getopt
Getopt について
Getopt の規則の宣言
オプションおよび引数の取得
Zend_Console_Getopt の設定
Zend_Controller
Zend_Controller クイックスタート
Zend_Controller の基本
フロントコントローラ
リクエストオブジェクト
標準のルータ: Zend_Controller_Router_Rewrite
ディスパッチャ
アクションコントローラ
アクションヘルパー
レスポンスオブジェクト
プラグイン
モジュラーディレクトリ構造の規約の使用
MVC での例外
以前のバージョンからの移行
Zend_Currency
Zend_Currency について
通貨の操作方法
以前のバージョンからの移行
Zend_Date
導入
動作原理
基本メソッド
Zend_Date API の概要
日付の作成
日付関数全般用の定数
動作例
Zend_Db
Zend_Db_Adapter
Zend_Db_Statement
Zend_Db_Profiler
Zend_Db_Select
Zend_Db_Table
Zend_Db_Table_Row
Zend_Db_Table_Rowset
導入
Zend_Debug
変数の出力
Zend_Dojo
Introduction
Zend_Dojo_Data: dojo.data Envelopes
Dojo View Helpers
Dojo Form Elements and Decorators
Zend_Dom
導入
Zend_Dom_Query
Zend_Exception
例外の使用法
Zend_Feed
導入
フィードの読み込み
ウェブページからのフィードの取得
RSS フィードの使用
Atom フィードの使用
単一の Atom エントリの処理
フィードおよびエントリの構造の変更
独自のフィードクラスおよびエントリクラス
Zend_File
Zend_File_Transfer
Validators for Zend_File_Transfer
Zend_Filter
導入
標準のフィルタクラス群
フィルタチェイン
フィルタの書き方
Zend_Filter_Input
Zend_Filter_Inflector
Zend_Form
Zend_Form
Zend_Form クイックスタート
Zend_Form_Element を用いたフォーム要素の作成
Zend_Form によるフォームの作成
Zend_Form_Decorator による独自のフォームマークアップの作成
Zend Framework に同梱されている標準のフォーム要素
Zend Framework に同梱されている標準のデコレータ
Zend_Form の国際化
Zend_Form の高度な使用法
Zend_Gdata
Gdata について
AuthSub による認証
ClientLogin による認証
Google Calendar の使用法
Google Documents List Data API の使用法
Google Spreadsheets の使用法
Google Apps Provisioning の使用法
Google Base の使用法
YouTube Data API の使用法
Picasa Web Albums の使用法
Gdata の例外処理
Zend_Http
Zend_Http_Client - 導入
Zend_Http_Client - 高度な使用法
Zend_Http_Client - 接続アダプタ
Zend_Http_Cookie および Zend_Http_CookieJar
Zend_Http_Response
Zend_InfoCard
導入
Zend_Json
導入
基本的な使用法
JSON オブジェクト
XML から JSON への変換
Zend_Json_Server - JSON-RPC server
Zend_Layout
導入
Zend_Layout クイックスタート
Zend_Layout の設定オプション
Zend_Layout の高度な使用法
Zend_Ldap
導入
Zend_Loader
ファイルやクラスの動的な読み込み
プラグインのロード
Zend_Locale
導入
Zend_Locale の使用法
正規化および地域化
日付および時刻の扱い
ロケールがサポートする言語
ロケールがサポートする地域
Zend_Log
概要
ライター
フォーマッタ
フィルタ
Zend_Mail
導入
SMTP 経由での送信
SMTP 接続による複数のメールの送信
異なる転送手段の使用
HTML メール
ファイルの添付
受信者の追加
MIME バウンダリの制御
追加のヘッダ
文字セット
エンコーディング
SMTP 認証
セキュアな SMTP トランスポート
メールメッセージの読み込み
Zend_Measure
導入
計測値の作成
計測値の出力
計測値の操作
計測値の型
Zend_Memory
概要
メモリマネージャ
メモリオブジェクト
Zend_Mime
Zend_Mime
Zend_Mime_Message
Zend_Mime_Part
Zend_OpenId
導入
Zend_OpenId_Consumer の基本
Zend_OpenId_Provider
Zend_Paginator
Introduction
Usage
Configuration
Advanced usage
Zend_Pdf
導入
PDF ドキュメントの作成および読み込み
PDF ドキュメントへの変更内容の保存
ドキュメントのページ
描画
ドキュメントの情報およびメタデータ
Zend_Pdf モジュールの使用例
Zend_Registry
レジストリの使用法
Zend_Rest
導入
Zend_Rest_Client
Zend_Rest_Server
Zend_Search_Lucene
概要
インデックスの構築
インデックスの検索
クエリ言語
クエリ作成用の API
文字セット
拡張性
Java Lucene との相互運用
応用
ベストプラクティス
Zend_Server
導入
Zend_Server_Reflection
Zend_Service
導入
Zend_Service_Akismet
Zend_Service_Amazon
Zend_Service_Audioscrobbler
Zend_Service_Delicious
Zend_Service_Flickr
Zend_Service_Nirvanix
Zend_Service_ReCaptcha
Zend_Service_Simpy
導入
Zend_Service_StrikeIron
Zend_Service_StrikeIron: バンドルされているサービス
Zend_Service_StrikeIron: 応用編
Zend_Service_Technorati
Zend_Service_Yahoo
Zend_Session
導入
基本的な使用法
高度な使用法
グローバルセッションの管理
Zend_Session_SaveHandler_DbTable
Zend_Soap
Zend_Soap_Server
Zend_Soap_Client
WSDL Accessor
AutoDiscovery. Introduction
Class autodiscovering.
Functions autodiscovering.
Autodiscovering. Datatypes.
Zend_Test
Introduction
Zend_Test_PHPUnit
Zend_Text
Zend_Text_Figlet
Zend_TimeSync
導入
Zend_TimeSync の動作
Zend_Translate
導入
Zend_Translate のアダプタ
翻訳アダプタの使用法
Zend_Uri
Zend_Uri
Zend_Validate
導入
標準のバリデーションクラス群
バリデータチェイン
バリデータの書き方
Zend_Version
Zend Framework のバージョンの取得
Zend_View
導入
コントローラスクリプト
ビュースクリプト
ビューヘルパー
Zend_View_Abstract
Zend_Wildfire
Zend_Wildfire
Zend_XmlRpc
導入
Zend_XmlRpc_Client
Zend_XmlRpc_Server
Zend Framework のシステム要件
PHP のバージョン
PHP の拡張モジュール
Zend Framework のコンポーネント
Zend Framework の依存性
Zend Framework PHP 標準コーディング規約
概要
PHP ファイルの書式
命名規約
コーディングスタイル
著作権に関する情報