要約: | - Fill または Frame のような GUI オブジェクトをサブクラス化して、ほとんどの 2D レンダリングタスクに適した Renderer2d にアクセスします。
- Renderer2d には、レンダリング プロパティの状態を保持し、表面へのレンダリングを実行するためのさまざまなメソッドがあります。
- 特定の目的でより正確なレンダリングが必要な場合は、Renderer2dGraphic から Renderer2d を取得します。
|
2Dレンダリングに関連する主なクラスは
Renderer2dです。このクラスはレンダリング プロパティの状態を保持し、描画面を持ち、描画面にレンダリングを実行する為の様々なレンダリング メソッドを持っています。
Curl®言語は、
Renderer2dの2種類の実装を提供します。グラフィック オブジェクトのサブクラスを作成し、そのdrawメソッドをオーバーライドすることで、それらの1つにアクセスすることが出来ます。そのdrawメソッドは、引数として
Renderer2dを取り、そのRenderer2dを描画します。このレンダラの正確な機能はプラットフォームに依存します。Windows と Macシステム上では、アルファ混合やテクスチャの回転を含む、幾つかの高度な機能をサポートします。Linux上では、これらの機能を得る為には、フル機能のレンダラを使用する必要があります。
追加のレンダリング機能が必要な場合、
Renderer2dGraphicを作成するか、その
repaint-handlerに渡される
Renderer2dを使用して、フル機能を備えた
Renderer2dを取得することが出来ます。オフスクリーン レンダラを使用する場合は、
Frameのようなグラフィック オブジェクトを使用して、レンダリングされるイメージを画面に配置する必要があります。
全てのGUIツールキット オブジェクトは、
Graphicから
drawメソッドを継承します。グラフィックオブジェクトは、
drawメソッドに渡される
Renderer2dがレンダリングするオンスクリーン領域を表します。
以下のサンプルでは、
Renderer2d.render-rectangleを使用して、ピンクの長方形をレンダリングする
rect-procと呼ばれるプロシージャを定義しています。次に、その
drawメソッドで
rect-procを使用する
RepaintFrameと呼ばれる
Frameのサブクラスを作成します。サンプルでは、
RepaintFrameのインスタンスを作成し、
Renderer2dを
rect-procに渡してピンクの長方形をレンダリングします。
render-rectangleに渡されるx、y座標は、グラフィックオブジェクトの境界から相対的に長方形の位置を決定します。
例:
Renderer2dの使用 |
|
{define-proc
{rect-proc ren:Renderer2d}:void
{ren.render-rectangle
0.5cm, 0.5cm,
2cm, 2cm,
fill-pattern = {FillPattern.get-pink}
}
}
{define-class RepaintFrame {inherits Frame}
{constructor {default ...}
{construct-super ...}
}
{method public {draw ren:Renderer2d}:void
{rect-proc ren}
}
}
{RepaintFrame
border-width = 1px,
width = 4cm,
height = 4cm
}
| |
以下のメソッドは、 線をレンダリングします。
以下のサンプルでは、render-triangleメソッドを示しています。
例:
Renderer2d.render-triangleの使用 |
|
{define-proc
{tri-proc ren:Renderer2d}:void
{ren.render-triangle
{Distance2d 1cm, 4cm},
{Distance2d 4cm, 1cm},
{Distance2d 0cm, 0cm},
fill-pattern = {url "curl://install/docs/default/images/adria.jpg"}
}
}
{define-class RepaintFrame {inherits Frame}
{constructor {default ...}
{construct-super ...}
}
{method public {draw ren:Renderer2d}:void
{tri-proc ren}
}
}
{RepaintFrame
width = 4cm,
height = 4cm
}
| |
レンダリング プロパティは、どのようにレンダリングを実行するのかについての情報を提供します。
Renderer2d.render-lineのようなメソッドを使ってレンダリングする際に使われます。各レンダリング メソッドのAPIリファレンスにはメソッドが使用するプロパティが説明されています。例えば、
Renderer2d.render-lineは以下のレンダリング プロパティを使用しています。
- fill-pattern: ソースFillPattern。(純色など)
- draw-operation: ソース ピクセルおよび出力先ピクセルを結合する方法についての情報
- stroke-thickness: 線の太さ
レンダリング プロパティは、メソッドに引数として渡すことで設定できます。このようなメソッドは、レンダリング プロパティを指定されたとおりに一時的に設定して、レンダリング実行します。
with-render-propertiesマクロ ブロックで、レンダリング メソッドの1つまたは複数の呼び出しを囲むことが出来ます。このマクロは、全てのメソッド呼び出しのレンダリング プロパティに指定された値を設定し、レンダリングの実行後、コードブロックの最後で、プロパティの値を元に戻します。レンダリング メソッドを呼び出す時に、プロパティを設定することで
with-render-propertiesの中でプロパティの設定をオーバーライドすることが出来ます。
レンダリング メソッドでは、メソッドの呼び出しを通じて、関連する全てのプロパティの
設定ができるわけではありません。例えば、回転などの、変換レンダリング プロパティは
全てのレンダリング メソッドに影響しますが、with-render-properties によってのみ
設定できます。
以下のサンプルでは、4本の線を描画します。赤い線の色は、
Renderer2d.render-lineの引数で設定されています。残りの3本の線は、
with-render-properties内でのレンダリングの呼び出しで描画されます。colorとstroke-thicknessは
with-render-properties内で設定されています。緑色の線の色は、
with-render-propertiesで設定されている色をオーバーライドする
render-lineへ引数を渡すことで設定されます。
例:
一連のレンダリング呼び出しをwith-render-propertiesでラップする |
|
{define-proc
{lines-proc ren:Renderer2d}:void
{ren.render-line
2cm, 0cm,
2cm, 4cm,
fill-pattern = {FillPattern.get-red}
}
{with-render-properties
fill-pattern = {FillPattern.get-blue},
stroke-thickness = 2pt
on ren do
{ren.render-line
1cm, 2cm,
3cm, 2cm}
{ren.render-line
fill-pattern = {FillPattern.get-green},
0cm, 0cm,
4cm, 4cm}
{ren.render-line
0cm, 4cm,
4cm, 0cm}
}
}
{define-class RepaintFrame {inherits Frame}
{constructor {default ...}
{construct-super ...}
}
{method public {draw ren:Renderer2d}:void
{lines-proc ren}
}
}
{RepaintFrame
border-width = 1px,
width = 4cm,
height = 4cm
}
| |
レンダリングを実行する時に、
Renderer2dは定義されたクリッピング領域内に
収まるものだけをレンダリングします。クリッピング領域外になるものはレンダリングされず、
画面に表示されません。最初のクリッピング領域は、
Renderer2dに関連付けられている
描画面によって定義されているので、描画面の境界でクリッピングが発生します。
drawメソッドに渡される
Renderer2dは自動的に、そのクリッピング領域を
Graphicによって占められているエリアに設定します。
clipping-regionレンダリング プロパティはクリッピング領域を設定する相対的なプロパティです。
clipping-regionが、
with-render-properties呼び出しで指定されている場合、レンダラーは、新しく設定されたクリッピング領域と以前のクリッピング領域の交点を計算し、その領域にレンダリングを制限します。
with-render-propertiesコード ブロックの最後で、レンダラーは、描画面の境界に囲まれている当初のクリッピング領域に戻します。
例:
クリッピング領域の使用 |
|
{define-proc {clip-lines-proc
ren:Renderer2d
}:void
let clip:Region =
{Region.from-rectangle
0.5cm, 0.5cm,
3cm,
2cm
}
{with-render-properties
fill-pattern = {FillPattern.get-blue},
|| Comment out the following line to see
|| the example without the clipping region
clipping-region = clip,
stroke-thickness = 2pt
on ren do
{ren.render-line
0cm, 0cm,
4cm, 4cm}
{ren.render-line
0cm, 4cm,
4cm, 0cm}
}
}
{define-class RepaintFrame {inherits Frame}
{constructor {default ...}
{construct-super ...}
}
{method public {draw ren:Renderer2d}:void
{clip-lines-proc ren}
}
}
{RepaintFrame
border-width = 1px,
width = 4cm,
height = 4cm
}
| |
テクスチャ マッピングを使用してレンダリングを実行すると、レンダリングされるシェイプの各頂点は、空間座標とテクスチャ座標を持ちます。空間座標は明示的に提供されます。しかしテクスチャ座標は、テクスチャが正確にレンダリングされたシェイプを覆うように通常自動的に生成されます。
Renderer2d.render-pixmap と
Renderer2d.render-rectangleでは明示的にテクスチャ座標を記述することが出来るメソッドです。以下のサンプルでは
TextureFrameは、オプション パラメータ
uv1 と
uv2を指定して、長方形にマッピングするテクスチャの部分を指定するテクスチャ座標を提供します。
例:
テクスチャ座標の指定 |
|
{define-class TextureFrame {inherits Frame}
{constructor {default ...}
{construct-super ...}
}
{method public {draw ren:Renderer2d}:void
{ren.render-rectangle
0cm, 0cm, 2cm, 2cm,
fill-pattern = {url "curl://install/docs/default/images/adria.jpg"},
uv1 = {Fraction2d .3, .3},
uv2 = {Fraction2d .7, .7}
}
}
}
{define-class RepaintFrame {inherits Frame}
{constructor {default ...}
{construct-super ...}
}
{method public {draw ren:Renderer2d}:void
{ren.render-rectangle
0cm, 0cm, 2cm, 2cm,
fill-pattern = {url "curl://install/docs/default/images/adria.jpg"}
}
}
}
{RepaintFrame
width = 2cm,
height = 2cm
}
{TextureFrame
width = 2cm,
height = 2cm
}
| |
座標変換は、レンダリングの前に、全ての座標に適用される線形関数を示します。以下のサンプルで示す変換は、x及びyのスケーリング係数がそれぞれ2、3として
Transformation2d.local-scaleを使って作成されています。この変換は、各x座標を2倍し、各y座標を3倍する効果があります。
例:
長方形のスケーリング |
|
{define-class package ExampleFrame {inherits BaseFrame}
field private xform:Transformation2d =
{Transformation2d}
{constructor package {default
xform:Transformation2d,
...
}
set self.xform = xform
{construct-super ...}
}
{method public {draw r2d:Renderer2d}:void
let bounds:GRect = {self.layout.get-bounds}
{with-render-properties
transformation = self.xform
on r2d do
{r2d.render-rectangle
0cm, 0cm, 2cm, 2cm,
fill-pattern =
{url "curl://install/docs/default/images/adria.jpg"}
}
}
}
}
{let identity-xform:Transformation2d = {Transformation2d}}
{let xform:Transformation2d = {Transformation2d}}
{xform.local-scale 3, 2}
{ExampleFrame
background = {FillPattern.get-gray},
identity-xform,
width = 6cm,
height = 4cm
}
{ExampleFrame
background = {FillPattern.get-gray},
xform,
width = 6cm,
height = 4cm
}
| |
次のサンプルでは、変換の平行移動を示しています。
例:
長方形の平行移動 |
|
{define-class package QuickExampleWidget {inherits BaseFrame}
field private xform:Transformation2d =
{Transformation2d}
{constructor package {default
xform:Transformation2d,
...
}
set self.xform = xform
{construct-super ...}
}
{method public {draw r2d:Renderer2d}:void
let bounds:GRect = {self.layout.get-bounds}
{with-render-properties
transformation = self.xform
on r2d do
{r2d.render-rectangle
0cm, 0cm, 2cm, 2cm,
fill-pattern = {url "curl://install/docs/default/images/adria.jpg"}
}
}
}
}
{let identity-xform:Transformation2d = {Transformation2d}}
{let xform:Transformation2d = {Transformation2d}}
{xform.local-translate 2cm, 2cm}
{spaced-hbox
{VBox
{QuickExampleWidget
identity-xform,
width = 4cm,
height = 4cm,
background = {FillPattern.get-gray}
}
},
{VBox
{QuickExampleWidget
xform,
width = 4cm,
height = 4cm,
background = {FillPattern.get-gray}
}
}
}
| |
以下のサンプルは、テクスチャの回転を含んでいるので、幾つかのプラットフォーム上では
Renderer2dGraphicから取得される
Renderer2dを通じて利用できる高度な機能を必要とします。このタイプの
Renderer2dの取得の詳細については
高度な2Dレンダリングを参照してください。このサンプルでは、
transform-procプロシージャは、
Renderer2d.caps.can-render-rotated-textures?をチェックして2Dレンダラーがテクスチャの回転を扱うことができるかどうかを判断しています。
このサンプルでは、Transformation2dを使用して座標変換を行い、長方形を回転させています。テクスチャ変換は明示的には実行されません。テクスチャは長方形の回転の結果のとおり回転されます。
例:
テクスチャを含む長方形の回転 |
|
{define-proc {identity-proc
ren:Renderer2d
}:void
{ren.clear fill-pattern = {FillPattern.get-gray}}
{ren.render-rectangle
0cm, 1cm,
2cm, 2cm,
fill-pattern =
{url "curl://install/docs/default/images/adria.jpg"}
}
}
{define-proc {transform-proc
ren:Renderer2d
}:void
{ren.clear fill-pattern = {FillPattern.get-gray}}
{if ren.caps.can-render-rotated-textures? then
{with-render-properties
transformation = xform
on ren do
{ren.render-rectangle
0cm, 1cm,
2cm, 2cm,
fill-pattern =
{url "curl://install/docs/default/images/adria.jpg"}
}
}
else
{ren.render-rectangle
0cm, 1cm,
2cm, 2cm,
fill-pattern =
{url "curl://install/docs/default/images/adria.jpg"}
}
}
}
{let xform:Transformation2d = {Transformation2d}}
{xform.local-rotate -30deg}
{define-class IdentityFrame {inherits Frame}
{constructor {default ...}
{construct-super ...}
}
{method public {draw ren:Renderer2d}:void
{identity-proc ren}
}
}
{define-class TransformFrame {inherits Frame}
{constructor {default ...}
{construct-super ...}
}
{method public {draw ren:Renderer2d}:void
{transform-proc ren}
}
}
{spaced-hbox
{IdentityFrame
width = 5cm,
height = 3cm,
background = "silver"
},
{TransformFrame
width = 5cm,
height = 3cm,
background = "silver"
}
}
| |
以下のサンプルでは、よりRenderer2dのより複雑な使用法を示します。このコードは、Renderer2d.render-rectangleを呼び出して、FillPatternの一部をレンダリングします。コマンドボタンをクリックするとピクチャの象限の位置が変わります。
例:
Rendering parts of a FillPattern |
|
{define-class public KidGraphic {inherits Frame}
field fill-pattern:FillPattern
field quads:{Array-of Fraction2d} =
{new {Array-of Fraction2d},
{Fraction2d 0.0, 0.0},
{Fraction2d 0.5, 0.0},
{Fraction2d 0.5, 0.5},
{Fraction2d 0.0, 0.5}
}
{constructor public
{default
fill-pattern:FillPattern =
{url "curl://install/docs/default/images/adria.jpg"},
...
}
{construct-super ...}
set self.fill-pattern = fill-pattern
}
{method private {render-quadrant
renderer2d:Renderer2d,
quadrant:int,
uv:Fraction2d
}:void
let bounds:GRect = {self.layout.get-bounds}
let width:Distance = (bounds.lextent + bounds.rextent) / 2
let height:Distance = (bounds.ascent + bounds.descent) / 2
let x:Distance = -bounds.lextent
let y:Distance = -bounds.ascent
{if quadrant == 1 or quadrant == 2 then {inc x, width}}
{if quadrant == 2 or quadrant == 3 then {inc y, height}}
{renderer2d.render-rectangle
x, y, width, height,
fill-pattern = self.fill-pattern,
uv1 = uv, uv2 = uv + {Fraction2d 0.5, 0.5}
}
}
{method public {draw renderer2d:Renderer2d}:void
{for i = 0 below 4 do
{self.render-quadrant renderer2d, i, self.quads[i]}
}
}
{method public {shift}:void
let tmp:Fraction2d = self.quads[0]
set self.quads[0] = self.quads[1]
set self.quads[1] = self.quads[2]
set self.quads[2] = self.quads[3]
set self.quads[3] = tmp
{self.request-draw}
}
}
{value
let obj:KidGraphic =
{KidGraphic
width = 2in,
height = 2in
}
let button:CommandButton =
{CommandButton
width = 1in,
label = "Rotate",
{on Action do
{obj.shift}
}
}
{center
{spaced-vbox
obj,
{HBox {Fill}, button, {Fill}}
}
}
}
| |
Pathは、無限に細く方向を持った 2 次元の曲線として正式に定義されています。線を描画する為の方向のセットとして解釈することが出来ます。方向は、点で構成され、
Distance2dとして記述されます。点を接続するパス セグメントを作成する操作は
PathOperationとして記述されます。結果のパスには、切れ目や直線の部分、曲線の部分を含めることが出来ます。
以下の例で示すように、パスを作成する時にコンストラクタに対して点とパス操作を指定することが出来ます。このサンプルでは3つのパス操作move-to、 line-to、curve-toを使用して、直線セグメントと曲線からなるパスを生成しています。
curve-to操作に続く2つの点は、曲線を制御する点です。インタラクティブにベジェ曲線を描画させるグラフィック アプリケーションでは、これらの点をスクリーン上で視覚化し、それらをドラッグして曲線を形成します。パスの曲線部分を生成する為には、それらの点をx、yの座標として指定する必要があります。
例:
シンプル Path |
|
{define-proc public {draw-a-path
renderer2d:Renderer2d
}:void
|| Here is the Path definition:
let path:Path = {Path
{Distance2d 0.5cm, 0.5cm},
PathOperation.line-to,
{Distance2d 3cm, 2cm},
PathOperation.move-to,
{Distance2d 2cm, 3cm},
PathOperation.curve-to,
{Distance2d 4cm, 3cm},
{Distance2d 4cm, 2cm},
{Distance2d 2cm, 0.5cm}
}
{renderer2d.render-path path}
}
{define-class RepaintFrame {inherits Frame}
{constructor {default ...}
{construct-super ...}
}
{method public {draw ren:Renderer2d}:void
{draw-a-path ren}
}
}
{RepaintFrame
border-width = 1px,
width = 4cm,
height = 4cm
}
| |
Pathは、パスを作成した後にパスに線セグメントを追加するメソッドも提供します。点を
Distance2dとして記述し、メソッドの引数として渡します。各メソッドには、2つのバージョンがあります。ひとつは、引数を座標空間として解釈し、もう1つは、パスに記述された最後の点からの相対的に引数を解釈します。
以下は、座標空間内の点で実行されるメソッドの一覧です。
例:
セグメント生成メソッドの使用 |
|
{define-proc public {draw-a-path
renderer2d:Renderer2d
}:void
let path:Path = {Path}
{path.move-to {Distance2d 0.5cm, 0.5cm}}
{path.line-to {Distance2d 3cm, 2cm}}
{path.move-to{Distance2d 2cm, 3cm}}
{path.curve-to
{Distance2d 4cm, 3cm},
{Distance2d 4cm, 2cm},
{Distance2d 2cm, 0.5cm}
}
{renderer2d.render-path path}
}
{define-class RepaintFrame {inherits Frame}
{constructor {default ...}
{construct-super ...}
}
{method public {draw ren:Renderer2d}:void
{draw-a-path ren}
}
}
{RepaintFrame
border-width = 1px,
width = 4cm,
height = 4cm
}
| |
セグメント生成メソッドでは、curve-toによって作成される3次曲線に加えて、2次曲線と弧を作成することが出来ます。次の例では、3次曲線と2次曲線と弧を作成しており、全て同じ端点と制御点を使用しています。
例:
曲線の種類 |
|
{let start-point:Distance2d = {Distance2d 1cm, 4cm}}
{let control-point:Distance2d = {Distance2d 1cm, -1cm}}
{let end-point:Distance2d = {Distance2d 5cm, 4cm}}
{let path:Path = {Path}}
{path.move-to start-point}
{path.curve-to
control-point,
control-point,
end-point
}
{path.move-to start-point}
{path.quadratic-curve-to
control-point,
end-point
}
{path.move-to start-point}
{path.arc-to
2cm,
2cm,
0deg,
false,
false,
end-point
}
{define-proc public {draw-a-path
renderer2d:Renderer2d,
path:Path
}:void
on renderer2d do
{renderer2d.render-path path}
}
{define-class RepaintFrame {inherits Frame}
{constructor {default ...}
{construct-super ...}
}
{method public {draw ren:Renderer2d}:void
{draw-a-path ren, path}
}
}
{RepaintFrame
border-width = 1px,
width = 6cm,
height = 4.5cm
}
| |
既に触れたとおり、
Pathは、点引数をパス内の最後の点からの相対距離と解釈するセグメント生成メソッドも提供します。以下はこれらのメソッドの一覧です。
相対セグメント生成メソッドの使用法の1つは、異なる場所で同じ曲線を繰り返すことです。次のサンプルで示しているように、1つの曲線を複数回繰り返してパスを作り上げています。それぞれの新しい曲線は、最後の端点から始まっています。
例:
Using relative segment-creation methods |
|
{define-proc public {draw-a-path
renderer2d:Renderer2d
}:void
let path:Path = {Path}
{path.move-to {Distance2d 0.5cm, 0.5cm}}
{for i:int = 0 to 5 do
{path.curve-to-relative
{Distance2d 1cm, 0cm},
{Distance2d 2cm, 0cm},
{Distance2d 2cm, 0.5cm}
}
}
{with-render-properties
fill-pattern = "darkgreen",
stroke-thickness = 2pt
on renderer2d do
{renderer2d.render-path path}
}
}
{define-class RepaintFrame {inherits Frame}
{constructor {default ...}
{construct-super ...}
}
{method public {draw ren:Renderer2d}:void
{draw-a-path ren}
}
}
{RepaintFrame
border-width = 1px,
width = 13cm,
height = 5cm
}
| |
smooth-*メソッドは、先立つ曲線の最後の制御点の反射である暗黙的な最初の制御点を使用します。それは2つの曲線間の滑らかな接続を保証します。次のサンプルでは、
Path.smooth-curve-toを前の曲線との滑らかな結合を行っています。また
Path.closeを使用して、閉じたパス内の曲線の2端点を接続しています。
例:
滑らかに曲線を接続 |
|
{define-proc public {draw-a-path
renderer2d:Renderer2d
}:void
let path:Path =
{Path}
{path.curve-to
{Distance2d 8cm, 2cm},
{Distance2d 8cm, 3cm},
{Distance2d 4cm, 4cm}
}
{path.smooth-curve-to
{Distance2d 0cm, 8cm},
{Distance2d 4cm, 8cm}
}
{path.close}
{renderer2d.render-path path}
}
{define-class RepaintFrame {inherits Frame}
{constructor {default ...}
{construct-super ...}
}
{method public {draw ren:Renderer2d}:void
{draw-a-path ren}
}
}
{RepaintFrame
border-width = 1px,
width = 7cm,
height = 8.5cm
}
| |
Pathは、パスで動作するメソッドも提供します。
それらのうちいくつかを以下に挙げます。
例:
Pathの操作 |
|
{let path:Path = {Path}}
{path.move-to {Distance2d 0.5cm, 3cm}}
{path.quadratic-curve-to
{Distance2d 1cm, -2cm},
{Distance2d 3cm, 3cm}
}
{let xform:Transformation2d = {Transformation2d}}
{xform.local-translate 2.5cm, 0cm}
{let path1:Path = {path.transform-clone xform, out = path1}}
{path.append path1}
{define-proc public {draw-a-path
renderer2d:Renderer2d,
path:Path
}:void
{for i:int = 0 to 2 do
let r:double = 1/(i + .5)
{with-render-properties
fill-pattern = {FillPattern.from-rgb r, .4, .6, opacity = .5},
stroke-thickness = 6pt,
draw-operation = DrawOperation.blend,
translation = {Distance2d (i * .7cm), (i * .3cm)}
on renderer2d do
{renderer2d.render-path path}
}
}
}
{define-class RepaintFrame {inherits Frame}
{constructor {default ...}
{construct-super ...}
}
{method public {draw ren:Renderer2d}:void
{draw-a-path ren, path}
}
}
{RepaintFrame
border-width = 1px,
width = 7.5cm,
height = 4cm
}
| |
Regionを作成するもっとも簡単な方法は、以下で示されるように
from-rectangleコンストラクタを使用して、長方形(rectangle)から
することです。
例:
長方形から Region の作成 |
|
{define-proc {region-proc ren:Renderer2d}:void
{ren.render-region
{Region.from-rectangle
.5cm, .5cm, 5cm, 3cm
},
fill-pattern = "orange"
}
}
{define-class RepaintFrame {inherits Frame}
{constructor {default ...}
{construct-super ...}
}
{method public {draw ren:Renderer2d}:void
{region-proc ren}
}
}
{RepaintFrame
border-width = 1px,
width = 6cm,
height = 4cm
}
| |
例:
頂点を指定してRegionの作成 |
|
{define-proc {region-proc ren:Renderer2d}:void
{ren.render-region
{Region.from-vertices
{Distance2d 1cm, .5cm},
{Distance2d .5cm, 3.5cm},
{Distance2d 5.5cm, 3.5cm},
{Distance2d 6cm, .5cm}
},
fill-pattern = "orange"
}
}
{define-class RepaintFrame {inherits Frame}
{constructor {default ...}
{construct-super ...}
}
{method public {draw ren:Renderer2d}:void
{region-proc ren}
}
}
{RepaintFrame
border-width = 1px,
width = 6.5cm,
height = 4cm
}
| |
頂点の順序は重要です。y軸で下向き方向を正とする座標系で反時計回りに指定しなければなりません。もしも頂点を時計回りに指定すると、領域の動作は定義されず、数学的に不安定になります。以下で示すように、自身と交差した領域を作成する頂点を指定することも出来ます。
例:
自己交差した Region |
|
{define-proc {region-proc ren:Renderer2d}:void
{ren.render-region
{Region.from-vertices
{Distance2d 6cm, .5cm},
{Distance2d 5.5cm, 3.5cm},
{Distance2d 1cm, .5cm},
{Distance2d .5cm, 3.5cm}
},
fill-pattern = "orange"
}
}
{define-class RepaintFrame {inherits Frame}
{constructor {default ...}
{construct-super ...}
}
{method public {draw ren:Renderer2d}:void
{region-proc ren}
}
}
{RepaintFrame
border-width = 1px,
width = 6.5cm,
height = 4cm
}
| |
例:
頂点の配列から Region の作成 |
|
{let arr:{Array-of Distance2d} = {new {Array-of Distance2d}}}
{let x:Distance = 0cm}
{let y:Distance = 6cm}
{arr.append {Distance2d x, y}}
{for i:int = 0 to 5 do
set x = x + 1cm
{if i mod 2 == 0 then
set y = y - 2cm
else
set y = y + 1cm
}
{arr.append {Distance2d x, y}}
}
{arr.append {Distance2d x, 6cm}}
{define-proc {region-proc ren:Renderer2d}:void
{ren.render-region
{Region.from-vertex-array arr},
fill-pattern = "orange"
}
}
{define-class RepaintFrame {inherits Frame}
{constructor {default ...}
{construct-super ...}
}
{method public {draw ren:Renderer2d}:void
{region-proc ren}
}
}
{RepaintFrame
border-width = 1px,
width = 6cm,
height = 6cm
}
| |
例:
Path から Region を生成 |
|
{define-proc public {draw-a-region
renderer2d:Renderer2d
}:void
|| Here is the Path definition:
let path:Path =
{Path }
{path.move-to {Distance2d 2.5cm, 0.5cm}}
{path.arc-to-relative
2cm,
2cm,
0deg,
false,
false,
{Distance2d 0cm, 4cm}
}
{path.arc-to-relative
2cm,
2cm,
0deg,
false,
false,
{Distance2d 0cm, -4cm}
}
let region:Region =
{Region.from-path path}
{renderer2d.render-region
region,
fill-pattern = "orange"
}
}
{define-class RepaintFrame {inherits Frame}
{constructor {default ...}
{construct-super ...}
}
{method public {draw ren:Renderer2d}:void
{draw-a-region ren}
}
}
{RepaintFrame
border-width = 1px,
width = 5cm,
height = 5cm
}
| |
例:
領域の作成 |
|
{define-proc {region-proc ren:Renderer2d}:void
|| Here is the Region definition:
let region:Region =
{Region.from-vertex-array
{new {Array-of Distance2d},
{Double2d {cos 0deg}, {sin 0deg}} * 1in +
{Distance2d 1in, 1in},
{Double2d {cos 2*72deg}, {sin 2*72deg}} * 1in +
{Distance2d 1in, 1in},
{Double2d {cos 4*72deg}, {sin 4*72deg}} * 1in +
{Distance2d 1in, 1in},
{Double2d {cos 6*72deg}, {sin 6*72deg}} * 1in +
{Distance2d 1in, 1in},
{Double2d {cos 8*72deg}, {sin 8*72deg}} * 1in +
{Distance2d 1in, 1in}
}
}
{ren.render-region region, fill-pattern = "orange"}
}
{define-class RepaintFrame {inherits Frame}
{constructor {default ...}
{construct-super ...}
}
{method public {draw ren:Renderer2d}:void
{region-proc ren}
}
}
{RepaintFrame
border-width = 1px,
width = 2in,
height = 2in
}
| |
グラフィック オブジェクトの
drawメソッドに渡される
Renderer2dは、
DrawOperationで定義されている全てのレンダリング操作をサポートするわけではありません。
DrawOperation.source と
DrawOperation.maskをサポートすることを保証します。他の描画操作がサポートされるかどうかはプラットフォームに依存します。Windows プラットフォームと Mac プラットフォームにおいては、このレンダラーは、
DrawOperation.blendと回転したテクスチャもサポートします。
Renderer2dの全ての機能を引き出す必要がある時には、
Renderer2dGraphicを通じて
Renderer2dを取得するか、または、
Renderer2d.create-offscreenメソッドを呼び出す必要があります。2Dレンダリングに追加の機能を提供する必要がある時だけ、
Renderer2dGraphic や
Renderer2d.create-offscreenを呼び出してください。
Renderer2dGraphicは、Renderer2dとオフスクリーンDrawableへのアクセスを提供するGraphicです。
Renderer2dGraphicを生成する時、
Renderer2dは、
repaint-handlerに渡されます。関連した
Drawable上でレンダリングを実行する為には、この
Renderer2dを使用して、再描画プロシージャを記述します。Drawableには、
Renderer2dGraphic.drawableでアクセスすることが出来ます。
Renderer2dGraphicは、インスタンス化し、その再描画ハンドラとしてprocを提供することで直接利用することが出来ます。ここでは、テクスチャで埋められた長方形を回転する簡単なサンプルを示します。以前のサンプルテクスチャを含む長方形の回転を、グラフィックのdrawメソッド内で回転したテクスチャのレンダリングをサポートしないプットフォームで実行させる為にどのように書き換えるかを示しています。
例:
Renderer2dGraphicを使用してテクスチャを含む長方形の回転 |
|
{define-proc {identity-proc
rg:Renderer2dGraphic,
ren:Renderer2d,
area:#RectangleSet}:void
{ren.clear fill-pattern = {FillPattern.get-gray}}
{ren.render-rectangle
0cm, 1cm,
2cm, 2cm,
fill-pattern =
{url "curl://install/docs/default/images/adria.jpg"}
}
}
{define-proc {transform-proc
rg:Renderer2dGraphic,
ren:Renderer2d,
area:#RectangleSet}:void
{ren.clear fill-pattern = {FillPattern.get-gray}}
{with-render-properties
transformation = xform
on ren do
{ren.render-rectangle
0cm, 1cm,
2cm, 2cm,
fill-pattern =
{url "curl://install/docs/default/images/adria.jpg"}
}
}
}
{let xform:Transformation2d = {Transformation2d}}
{xform.local-rotate -30deg}
{spaced-hbox
{VBox
{Renderer2dGraphic
width = 4cm,
height = 3cm,
repaint-handler = identity-proc
}
},
{VBox
{Renderer2dGraphic
width = 4cm,
height = 3cm,
repaint-handler = transform-proc
}
}
}
| |
Renderer2dGraphicの既定のコンストラクタは、ブール値の引数
advanced-draw-operations?を取ります。それは、関連付けられた
Renderer2dによってサポートされる描画操作を決定します。既定値は、
falseです。全ての描画機能をサポートする必要がある場合には 、
trueに設定します。
advanced-draw-operations? = true,
レンダラーは、より制限され機能を提供することに注意してください。
例:
レンダラーの機能の決定 |
|
{let message:VBox = {VBox}}
{define-proc {add-proc
dg:DrawableGraphic,
ren:Renderer2d,
area:#RectangleSet}:void
{ren.clear fill-pattern = {FillPattern.get-maroon}}
{message.clear}
{message.add
"accurate-fill-rules?: " &
ren.caps.accurate-fill-rules?
}
{message.add
"can-antialias?: " &
ren.caps.can-antialias?
}
{message.add
"can-render-rotated-textures?: " &
ren.caps.can-render-rotated-textures?
}
{message.add
"DrawOperation.accumulate: " &
{ren.caps.draw-operation-supported? DrawOperation.accumulate}
}
{message.add
"DrawOperation.add: " &
{ren.caps.draw-operation-supported? DrawOperation.add}
}
{message.add
"DrawOperation.blend: " &
{ren.caps.draw-operation-supported? DrawOperation.blend}
}
{message.add
"DrawOperation.invert-destination: " &
{ren.caps.draw-operation-supported? DrawOperation.invert-destination}
}
{message.add
"DrawOperation.invert-source: " &
{ren.caps.draw-operation-supported? DrawOperation.invert-source}
}
{message.add
"DrawOperation.source: " &
{ren.caps.draw-operation-supported? DrawOperation.source}
}
{message.add
"DrawOperation.mask: " &
{ren.caps.draw-operation-supported? DrawOperation.mask}
}
{with-render-properties
draw-operation = DrawOperation.add
on ren do
{ren.render-rectangle
0.5cm, 0.5cm,
3cm, 3cm,
fill-pattern =
{url "curl://install/docs/default/images/adria.jpg"}
}
}
}
{spaced-vbox
{CommandButton
label = "Show renderer capabilities",
{on Action do
{popup-message
message
}
}
},
{Renderer2dGraphic
width = 4cm,
height = 4cm,
advanced-draw-operations? = true,
repaint-handler = add-proc
}
}
| |
Renderer2d.create-offscreenメソッドは、2D レンダラーとレンダラーに関連したオフスクリーン描画面を返します。そのDrawableにレンダリングを行うことができ、結果をグラフィック オブジェクトとして表示することが出来ます。このメソッドは、
advanced-draw-operations?引数をとり、描画サポートのレベルを決定します。
以下のサンプルは、直前のサンプルと同じレンダリング操作を実行します。今回は、Renderer2dGraphicではなく、Renderer2d.create-offscreenを使用しています。
例:
Renderer2d.create-offscreenの使用 |
|
{let g-width:Distance = 4cm}
{let g-height:Distance = 4cm}
{let (ren:Renderer2d, d:Drawable) =
{Renderer2d.create-offscreen
g-width,
g-height,
advanced-draw-operations? = true,
resolution = 100dpi
}
}
{ren.clear fill-pattern = {FillPattern.get-maroon}}
{with-render-properties
draw-operation = DrawOperation.add
on ren do
{ren.render-rectangle
0.5cm, 0.5cm,
3cm, 3cm,
fill-pattern =
{url "curl://install/docs/default/images/adria.jpg"}
}
}
{Frame
width = g-width,
height = g-height,
background = {d.to-Pixmap}
}
{d.destroy}
| |
Copyright © 1998-2019 SCSK Corporation.
All rights reserved.
Curl, the Curl logo, Surge, and the Surge logo are trademarks of SCSK Corporation.
that are registered in the United States. Surge
Lab, the Surge Lab logo, and the Surge Lab Visual Layout Editor (VLE)
logo are trademarks of SCSK Corporation.