モジュール java.desktop
パッケージ java.awt

クラスGraphics2D

java.lang.Object
java.awt.Graphics
java.awt.Graphics2D

public abstract class Graphics2D extends Graphics
このGraphics2Dクラスは、Graphicsクラスを拡張して、幾何学的図形、座標変換、色の管理、およびテキスト・レイアウトに対するより高度な制御を提供します。 このクラスは、Java(TM)プラットフォームで2Dの図形、テキスト、およびイメージを描画するための基本クラスです。

座標空間

Graphics2Dオブジェクトに渡されるすべての座標は、ユーザー空間(アプリケーションによって使用される)と呼ばれる、デバイスに依存しない座標系で指定されます。 Graphics2Dオブジェクトには、デバイス空間でユーザー空間の座標をデバイスに依存する座標に変換する方法を定義するAffineTransformオブジェクトが、描画状態の一部として格納されます。

デバイス空間の座標は、通常、個別のデバイス・ピクセルを示し、これらのピクセル間に無限に細い間隔に並べられています。 一部のGraphics2Dオブジェクトでは、描画操作を取り込むことができます。グラフィックス・メタファイルとして取り込むことで、後に物理的な解像度が不明な具象デバイスを使用して再生することができます。 レンダリング操作の取得時に解像度がわからない場合があるため、Graphics2D Transformは、ターゲット・デバイスの予想される解像度に近い仮想デバイス領域にユーザー座標を変換するように設定されています。 その見積もりが正しくない場合には、再生時にさらに変換を適用する必要があります。

描画属性オブジェクトによって実行される一部の操作にはデバイス空間で処理されるものもありますが、Graphics2Dのメソッドはすべてユーザー空間座標を扱います。

すべてのGraphics2Dオブジェクトは、描画の行われる位置を定義するターゲットと関連付けられています。 GraphicsConfigurationオブジェクトは、ピクセル形式および解像度といった描画ターゲットの特性を定義します。 Graphics2Dオブジェクトでは、その生存期間中常に同じ描画ターゲットが使用されます。

Graphics2Dオブジェクトが作成されるとき、GraphicsConfigurationは、Graphics2D (ComponentまたはImage)のターゲットとしてデフォルト変換を指定します。 このデフォルト変換では、ユーザー空間座標系を画面とプリンタのデバイス座標にマッピングして、原点をデバイスのターゲット領域の左上隅に、右方に拡張するにはX座標を、下方に拡張するにはY座標を増やすようなマッピングを行います。 スクリーン・デバイスなどの72 dpiに近いデバイスの場合、デフォルト変換のスケーリングはそれらのデバイスの識別情報に設定されます。 プリンタなどの高解像度デバイスの場合、デフォルト変換のスケーリングは、1平方インチあたり約72ユーザー空間座標に設定されます。 イメージ・バッファでは、デフォルトの変換はIdentity変換です。

描画プロセス

描画プロセスは、Graphics2D描画属性によって制御される4つの段階に分けることができます。 レンダリングではこうしたステップの多くを最適化できます。最適化は、将来の呼出しにそなえて結果をキャッシュに格納しておいたり、複数の仮想ステップを実質的に1つの操作にまとめたり、さまざまな属性に関する単純な共通の問題点を、操作のほかの部分を変更することにより排除したりすること、などによって行われます。

描画プロセスのステップを次に説明します。

  1. 描画する対象を指定する
  2. 描画操作を現在のClipに制限する。 Clipはユーザー空間のShapeによって指定され、GraphicsおよびGraphics2Dのさまざまなクリップ操作メソッドを使ってプログラムによって制御されます。 このユーザー・クリップは、現在のTransformによってデバイス空間に変換され、ウィンドウの可視性およびデバイスの大きさによって定義されるデバイス・クリップと結合されます。 ユーザー・クリップとデバイス・クリップの組み合わせによって、最終的なクリッピング領域を決定する複合クリップが定義されます。 レンダリング・システムは、ユーザー・クリップを変更して複合クリップの結果を反映することはできません。
  3. 描画する色を指定する
  4. Graphics2Dコンテキストの現在のComposite属性を使って、デスティネーションの描画表面に指定された色を塗る。

3種類の描画操作について、それぞれの描画プロセスの詳細を次に示します。
  1. Shapeの操作
    1. draw(Shape)操作の場合は、Graphics2Dコンテキストの現在のStroke属性でcreateStrokedShapeメソッドを使用して、指定のShapeの輪郭を格納する新しいShapeオブジェクトが構築されます。
    2. Shapeは、Graphics2Dコンテキストの現在のTransformを使ってユーザー空間からデバイス空間に変換されます。
    3. Shapeの輪郭は、ShapegetPathIteratorメソッドを使って抽出されます。このメソッドは、Shapeの境界に沿って反復処理を行うPathIteratorオブジェクトを返します。
    4. PathIteratorオブジェクトによって返される曲線セグメントをGraphics2Dオブジェクトが処理できない場合は、Shapeの平坦化を行うShapeの代替メソッドgetPathIteratorを呼び出すことができます。
    5. Graphics2Dコンテキストの現在のPaintが、デバイス空間で描画する色を指定するPaintContextを取得するために照会されます。
  2. テキストの操作
    1. 指定されたStringを描画するために必要なグリフのセットは、次のステップで指定されます。
      1. 引数がStringの場合、フォントが実装する基本レイアウトおよび形状決定アルゴリズムに関係なくそれらを用いて表示するために、Graphics2Dコンテキストの現在のFontStringのUnicode文字列をグリフのセットに変換するように要求されます。
      2. 引数がAttributedCharacterIteratorの場合、イテレータは、埋込みフォント属性を使って、それ自体をTextLayoutに変換するように要求されます。 TextLayoutは、書込み方向が異なる複数のフォントのために自動的にUnicodeの双方向レイアウト調整を実行する、より高性能なグリフ・レイアウト・アルゴリズムを実装できます。
      3. 引数がGlyphVectorの場合、GlyphVectorオブジェクトは、各グリフの位置を示す明示的な座標を持つフォント独自の適切なグリフ・コードをすでに格納しています。
    2. 現在のFontを照会すると、指定されたグリフのアウトラインを取得できます。 これらのアウトラインは、ステップ1で指定された各グリフの位置を基準にしたユーザー空間の形状として処理されます。
    3. 文字のアウトラインが、Shapeの操作」で説明したように塗りつぶされます。
    4. 現在のPaintが、デバイス空間で描画する色を指定するPaintContextを取得するために照会されます。
  3. Imageの操作
    1. 対象となる領域は、ソースImageのバウンディング・ボックスで定義されます。 このバウンディング・ボックスは、Imageオブジェクトのローカルな座標系であるイメージ空間で指定されます。
    2. AffineTransformdrawImage(Image, AffineTransform, ImageObserver)に渡される場合は、イメージ空間からユーザー空間にバウンディング・ボックスを変換するために、そのAffineTransformが使われます。 AffineTransformが指定されない場合、バウンディング・ボックスはすでにユーザー空間にあるものとして扱われます。
    3. ソースImageのバウンディング・ボックスは、現在のTransformを使ってユーザー空間からデバイス空間に変換されます。 ただし、バウンディング・ボックスを変換した結果が、デバイス空間で矩形領域となるとは限りません。
    4. Imageオブジェクトは描画する色を指定します。色は、現在のTransformとオプションのイメージ変換によって指定されたソースからデスティネーションへのマッピングに従ってサンプリングされます。

デフォルトの描画属性

Graphics2D描画属性のデフォルト値を次に示します。
Paint
Componentの色。
Font
ComponentFont
Stroke
線幅1、破線なし、マイター・セグメント結合、および角エンド・キャップを持つ角ペン
Transform
ComponentGraphicsConfiguration用のgetDefaultTransform
Composite
AlphaComposite.SRC_OVERルール。
Clip
描画Clipなし、出力はComponentにクリップされる。

描画互換性

JDK(tm) 1.1描画モデルは、座標がピクセル間の無限に細い間隔に存在するというピクセル化モデルに基づきます。 描画操作は、輪郭線上のアンカー・ポイントの右および下のピクセルを塗りつぶす1ピクセル幅のペンを使って行われます。 JDK 1.1描画モデルは、指定された番号のピクセルにきっちりと収まらなければならない離散ペンに整数座標を変換する必要がある、プラットフォーム・レンダリングの大半の既存クラスの機能に準拠しています。

Java 2D(TM)(Java(TM) 2プラットフォーム) APIは、平滑化レンダリングをサポートしています。 1ピクセル幅のペンは、ピクセルN+1と対比したピクセルNに完全に収まる必要はありません。 ペンは、部分的に両方のピクセルにかかることができます。 移動しているペンの縁が両方のピクセルにかかると、ペンのサブピクセル位置がユーザーに表示されるため、幅広ペンのバイアス方向を選択する必要はありません。 一方、KEY_ANTIALIASINGヒント・キーをVALUE_ANTIALIAS_OFFヒント値に設定することによって平滑化を無効にした場合は、デバイス空間で整数座標に沿って描画しているときなど、ペンがピクセル境界を越えようとしているときにどちらのピクセルを修正するか判断するために、レンダリングはバイアスを適用する必要があります。 平滑化レンダリングの機能により、描画モデルはペンのバイアスを指定する必要性がなくなりましたが、画面上で1ピクセル幅の水平線および垂直線を描画する共通のケースでは、平滑化レンダリングと非平滑化レンダリングは同じように動作する必要があります。 KEY_ANTIALIASINGヒント・キーをVALUE_ANTIALIAS_ONに設定して平滑化を有効にしたために、この線幅が突然2倍になり不透明度が半分になることを防ぐには、そのような線の輪郭線をモデルで指定することによって、その線が特定のピクセルのセットを完全にカバーして輪郭が鮮明になるようにします。

Java 2D APIはJDK 1.1の描画動作との互換性を維持しており、Java 2D APIでは従来からの操作や既存のレンダリングの動作に変更はありません。 一般的なdrawメソッドおよびfillメソッドにマッピングされる従来のメソッドが定義されているため、Stroke属性とTransform属性の設定および描画ヒントに基づいてGraphics2DGraphicsをどのように拡張しているかが明確に示されています。 その定義は、デフォルトの属性設定では同じように実行されます。 たとえば、デフォルトのStrokeは、幅1および破線なしのBasicStrokeであり、画面描画のデフォルトのTransformは恒等変換です。

次の2つのルールは、アンチエイリアスまたは非アンチエイリアスのどちらが使用されていても、予測可能な描画動作を提供します。

  • デバイス・ピクセル間にデバイス座標が定義され、それによりエイリアス描画とアンチエイリアス描画の間で一貫性のある結果が得られます。 座標がピクセルの中心にあるように定義された場合、矩形などの形状によってカバーされる一部のピクセルは半分だけしかカバーされません。 非アンチエイリアスの描画の場合、半分カバーされたピクセルは形状の内側か外側のどちらかが描画されます。 アンチエイリアスの描画では、形状のエッジ全体にあるピクセルが半分だけカバーされます。 しかし、ピクセルの間に座標が定義されていれば、矩形などの形状は、アンチエイリアスを使って描画されるどうかに関係なく、半分だけカバーされたピクセルを持つことはありません。
  • BasicStrokeオブジェクトを使ってストロークした線および図形の輪郭を「正規化」することで、描画可能なさまざまな位置で非アンチエイリアス描画またはアンチエイリアス描画するときに、一貫性のある輪郭を描画することができます。 この正規化プロセスはKEY_STROKE_CONTROLヒントによって制御されます。 正確な正規化アルゴリズムは指定されませんが、この正規化の目標は、ピクセル・グリッドに線がどのように収まるかに関わらず、視覚的に一貫性のある線を描画できるようにすること、およびアンチエイリアス・モードでの水平線および垂直線をより緻密にして、アンチエイリアスされていない場合の線になるべく近づけることです。 通常の正規化のステップでは、浮動小数点の線幅が同等の可能性で偶数または奇数のピクセル数に四捨五入できるように、アンチエイリアスされた線の終端をよりピクセルの中心にして重なる量を減らすか、あるいはアンチエイリアスされていない線のサブピクセルの位置決めを調整します。 このプロセスでは、終端をピクセルの半分まで移動して(通常は両軸に沿って正の無限大方向)、これらの結果の一貫性を高めることができます。

次に示す一般的な従来のメソッドの定義は、デフォルト属性設定では以前に指定された動作と同じように実行されます。

  • fillRectfillRoundRectfillOvalfillArcfillPolygonclearRectなどのfill操作の場合は、目的のShapeを指定してfillを呼び出すことができます。 たとえば矩形を塗りつぶす場合は、
     fill(new Rectangle(x, y, w, h));
     
    を呼び出します。
  • 同じように、drawLinedrawRectdrawRoundRectdrawOvaldrawArcdrawPolylinedrawPolygonなどの描画操作の場合は、目的のShapeを指定してdrawを呼び出すことができます。 たとえば矩形を描画する場合は、
     draw(new Rectangle(x, y, w, h));
     
    を呼び出します。
  • draw3DRectメソッドとfill3DRectメソッドは、GraphicsクラスではdrawLineメソッドとfillRectメソッドを使って実装されています。これらの動作は、Graphics2Dコンテキストの現在のStrokeオブジェクトとPaintオブジェクトに基づいて予測できます。 このクラスは、現在のPaintをオーバーライドし、これらの2つのオブジェクトの実装を現在のColorを排他的に使うバージョンでオーバーライドします。このクラスは、既存のメソッドと完全に等しい動作を記述するために、Strokeの現在の設定とは無関係にfillRectを使用します。
Graphicsクラスは、ペイントされる色を制御するためにsetColorメソッドだけを定義します。 Java 2D APIは、Colorオブジェクトを拡張して新しいPaintインタフェースを実装するので、既存のsetColorメソッドは現在のPaint属性をColorオブジェクトに設定するための簡易メソッドになっています。setColor(c)setPaint(c)に相当します。

Graphicsクラスは、色をデスティネーションに適用する方法を制御するために2つのメソッドを定義します。

  1. setPaintModeメソッドは、setComposite(new AlphaComposite.SrcOver)に相当するデフォルトのCompositeを設定する簡易メソッドとして実装されます。
  2. setXORMode(Color xorcolor)メソッドは、ソース・カラーのAlpha成分を無視し、デスティネーション・カラーをその値に設定する特殊なCompositeオブジェクトを設定するための簡易メソッドとして実装されます。
     dstpixel = (PixelOf(srccolor) ^ PixelOf(xorcolor) ^ dstpixel);
     

関連項目: