目次 | 前の項目 | 次の項目 | Java 2D API |
基本的なグラフィックスレンダリングモデルについては、Java 2DTM API の追加に伴う変更はありません。 グラフィックをレンダリングするには、グラフィックスコンテキストを設定し、Graphics オブジェクトのレンダリングメソッドを呼び出します。Java 2D API の Graphics2D クラスは、多くのグラフィックス属性をサポートし、新しいレンダリングメソッドを提供するため、Graphics を継承しています。 Graphics2D コンテキストの設定については、「Graphics2D を使ったレンダリング」を参照してください。
Java 2D API は、レンダリング装置の違いを自動的に補正し、どのような種類の装置に対しても同じレンダリングモデルを提供します。 レンダリング先の装置がディスプレイでもプリンタでも、アプリケーションレベルでのレンダリング処理は同じです。
JavaTM 2 SDK バージョン 1.3 のリリースにより、Java 2D API はマルチスクリーン環境をサポートします。 詳細は、「1.2.1 座標系」および 「マルチスクリーン環境でのレンダリング」を参照してください。
Java 2D API では、2 種類の座標系が使われています。
- 「ユーザ空間」は、装置に依存しない論理的な座標系です。 アプリケーションでは、この座標系だけを使います。 Java 2D のレンダリングルーチンに渡す幾何図形はすべて、ユーザ空間で指定します。
- 「デバイス空間」は装置に依存する座標系で、レンダリング先の装置によって異なります。 複数の物理画面デバイスにまたがってウィンドウを表示可能な仮想デスクトップを持つマルチスクリーン環境では、すべての画面を含む仮想デスクトップの座標系が使用されます。 Java 2DTM API によるマルチスクリーン環境サポートについての詳細は、「マルチスクリーン環境でのレンダリング」 を参照してください。
Java 2D システムは、ユーザ空間と使用するレンダリング装置のデバイス空間との間で必要な変換を、自動的に行います。 モニタの座標系はプリンタの座標系と大きく異なりますが、アプリケーションからこの違いが見えることはありません。
図 1-1 に示すように、ユーザ空間の原点は領域の左上隅にあり、x 座標の値は左から右に、y 座標は上から下に、それぞれ大きくなります。
ユーザ空間は、使用可能なすべての装置の座標系を統一する抽象表現です。 個々の装置のデバイス空間の原点と向きは、ユーザ空間と同じ場合も異なる場合もあります。 どちらの場合も、グラフィックオブジェクトがレンダリングされるときに、ユーザ空間の座標は適切なデバイス空間に自動的に変換されます。 多くの場合、この変換は、基になっているプラットフォームのデバイスドライバを使って行われます。
Java 2D API では、ユーザ空間からデバイス空間への変換をサポートするために、3 つのレベルの構成情報が定義されています。 この情報は、3 つのクラスにカプセル化されています
GraphicsEnvironment と GraphicsDevice と GraphicsConfiguration の 3 つのクラスを使って、Java プラットフォーム上でのレンダリング装置とフォントの特定と、ユーザ空間からデバイス空間への座標変換に必要な情報が、すべて表されます。 アプリケーションはこの情報にアクセスできますが、ユーザ空間とデバイス空間の間の変換を行う必要はありません。GraphicsEnvironment では、特定のプラットフォームの Java アプリケーションが認識できるレンダリング装置の集合が記述されています。 レンダリング装置としては、画面、プリンタ、イメージバッファなどがあります。 GraphicsEnvironment には、プラットフォームで利用可能なフォントの一覧も含まれています。
GraphicsDevice では、画面やプリンタなど、アプリケーションが認識できるレンダリング装置が記述されています。 装置で使用可能な構成は、それぞれ GraphicsConfiguration で表されます。 たとえば、SVGA ディスプレイ装置は、640x480x16 色、640x480x256 色、800x600x256 色など、さまざまなモードで動作できます。 SVGA ディスプレイは GraphicsDevice オブジェクトで表されて、個々のモードは GraphicsConfiguration オブジェクトで表されます。
1 つの GraphicsEnvironment には 1 つ以上の GraphicsDevice を含めることができ、個々の GraphicsDevice には 1 つ以上の GraphicsConfiguration を含めることができます。
Java 2D API では、統一された座標変換モデルが使われています。 ユーザ空間からデバイス空間への変換を含むすべての座標変換は、AffineTransform オブジェクトで表されます。 AffineTransform では、変換操作の規則が行列で定義されています。グラフィックスコンテキストに AffineTransform を追加すれば、図形、テキスト、またはイメージをレンダリングするときに、回転、拡大縮小、平行移動、変形などを実行できます。 追加した変換は、そのコンテキストでレンダリングされるすべてのグラフィックオブジェクトに適用されます。 変換は、ユーザ空間の座標がデバイス空間の座標に変換されるときに行われます。
文字列は、一般に、文字列を構成する文字という観点から考えられます。 文字列を描画するとき、その体裁は、選択されているフォントで決まります。 ただし、文字列を表示するためにフォントで使われている形状は、個々の文字と一致しない場合もあります。 たとえば、出版業界などでは、2 つ以上の文字の特定の組み合わせを、「合字」と呼ばれる単一の形状に置き換えることがよく行われます。文字列の中の文字を表すためにフォントで使われる形状を、「グリフ」と呼びます。 フォントでは、a のような斜体文字を複数のグリフで表したり、fi のような特定の文字の組み合わせを最終的に 1 つのグリフで表したりすることがあります。 Java 2D API の場合、グリフは単なる Shape で、ほかの Shape と同じように操作したりレンダリングしたりできます。
「フォント」はグリフの集合と考えることができます。 1 つのフォントには、heavy、medium、oblique、gothic、regular など多くの派生形がある場合があります。 このような異なる派生形を、「フェース」と呼びます。 同じフォントから作られるフェースはすべて似た文字体裁のデザインになっており、同じ「ファミリ」のメンバと考えることができます。 つまり、特定のスタイルを持つグリフの集合がフォントフェースを形成し、フォントフェースの集合がフォントファミリを形成し、フォントファミリの集合が特定の GraphicsEnvironment で利用できるフォントのグループを形成しています。
Java 2D API では、Helvetica Bold のように特定のフォントフェースを示す名前を使ってフォントを指定します。 これは JDK 1.1 と異なる点です。 JDK 1.1 では、フォントは論理名で記述されており、特定のプラットフォームで利用可能なフォントフェースの種類によっては、同じ論理名が異なるフォントフェースにマッピングされます。 旧バージョンとの互換性を保つため、Java 2D API では、フォントフェース名だけでなく論理名によるフォントの指定もサポートされています。
Java 2D API を使うと、ファミリ、フェース、サイズ、さらには言語まで異なる複数のフォントを含む文字列を、変換したりレンダリングしたりすることができます。 テキストの体裁は、テキストのレイアウトとは切り離されて、論理的に保持されます。 フォントの体裁は Font オブジェクトを使って記述されて、レイアウトの情報は TextLayout オブジェクトと TextAttributeSet オブジェクトに格納されます。 フォントの情報とレイアウトの情報を別に持つことで、同じフォントを別のレイアウト構成で簡単に使えるようになります。
イメージは、空間に組織的に配置されたピクセルの集合です。 「ピクセル」は、1 つの表示位置におけるイメージの体裁を定義しています。 ピクセルの 2 次元配列を「ラスタ」と呼びます。ピクセルの表現方法は、直接定義することも、イメージのカラーテーブルに対するインデックスとして定義することもできます。
多くの (256 色より多い) 色を使うイメージの場合は、通常、スクリーンの個々の位置に対する色、アルファ、およびそのほかの表示特性を、ピクセルで直接表します。 このようなイメージは、インデックスで色を指定したイメージよりかなり大きくなりますが、より実物に近い表現になります。
インデックスカラーイメージの場合、イメージの色は、カラーテーブルで指定されている色だけに制限されます。 その結果、イメージで使用できる色数が少なくなることがよくあります。 ただし、一般に、色の値よりインデックスの方が必要な記憶領域が少なくて済むので、インデックス指定の色の集まりとして格納されたイメージの方が小さくなります。 このピクセル形式は、16 色または 256 色だけで表現されたイメージによく使われています。
Java 2D API のイメージには、2 つの重要な要素があります。
ピクセルを解釈するときの規則は、ColorModel オブジェクトでカプセル化されています。 たとえば、値を色として直接解釈するのか、それともインデックスで表された色として解釈するのか、などの情報です。 ピクセルを表示するときは、ピクセルとカラーモデルをあわせて扱う必要があります。バンドは、イメージに対するカラー領域の 1 つの成分です。 たとえば、赤、緑、青の各成分は、RGB イメージのバンドです。 直接カラーモデルのイメージで使われるピクセルは、スクリーン上の 1 地点に対するバンド値の集合として考えることができます。
java.awt.image パッケージには、ColorModel の複数の実装が含まれています。 これには、パック形式とコンポーネント形式のピクセル表現も含まれます。
ColorSpace オブジェクトは、測定した数値の集合と特定の色の間の対応方法を管理する規則をカプセル化しています。 java.awt.color での ColorSpace の実装は、RGB や グレースケールを含む大部分の一般的なカラー領域を表しています。 カラー領域は色の集合ではないことに注意してください。 カラー領域は、具体的な色の値を解釈する方法についての規則を定義するものです。
カラー領域とカラーモデルを切り離すことで、色の表現方法と、異なる表現の間での色の変換方法が、より柔軟になります。
Java 2D API では、さまざまなペンスタイルと塗りつぶしパターンを使って Shape をレンダリングできます。 テキストは最終的にグリフの集合で表されるので、文字列にもペンスタイルや塗りつぶしを適用できます。ペンのスタイルは、Stroke インタフェースを実装するオブジェクトで定義されます。 Stroke を使うと、直線や曲線に、さまざまな幅や破線パターンを指定できます。
塗りつぶしのパターンは、Paint インタフェースを実装するオブジェクトで定義されます。 旧バージョンの AWT で利用できた Color クラスは、単純な型の Paint オブジェクトで、1 色の塗りつぶしを定義するために使います。 Java 2D API では、Paint インタフェースの新しい実装として、TexturePaint と GradientPaint の 2 つが提供されています。 TexturePaint は、規則的に繰り返される単純なイメージ片を使った塗りつぶしパターンを定義しています。 GradientPaint は、2 種類の色の間のグラデーションとして塗りつぶしパターンを定義します。
Java 2D では、図形の輪郭線のレンダリングと、パターンを使った図形の塗りつぶしは、2 種類の異なる操作です。
文字列のレンダリングでは、そのときの Paint 属性が、文字列を形成するグリフに適用されます。 ただし、レンダリングされるグリフを実際に塗りつぶすのは drawString です。テキスト文字列のグリフの輪郭線を描画するには、輪郭線を取得し、draw メソッドを使って輪郭線を図形としてレンダリングする必要があります。
既存のオブジェクトと重なるオブジェクトをレンダリングするときは、描画しようとする領域の現在の色と新しいオブジェクトの色を混合する方法を決める必要があります。 Java 2D API では、色を混合する際の規則は、Composite オブジェクトにカプセル化されています。簡単なレンダリングシステムでは、基本的なブール演算だけで色の混合が行われます。 たとえば、ブール演算による合成規則では、ソース色の値とデスティネーション色の値の論理積 (AND)、論理和 (OR)、または排他的論理和 (XOR) を求めることが可能です。 このような方法には、いくつか問題があります。
Java 2D API では、色を合成するときにカラーモデルの情報を考慮するアルファブレンディング1規則を実装することで、これらの欠点を回避しています。 AlphaComposite オブジェクトには、ソース色とデスティネーション色のカラーモデルが含まれています。