2.6 ペン
2.6.1 ペンの色とサイズ
Graphics クラスの Draw 系メソッドで線を描画するときに重要となるのが Pen オブジェクトです。これまでは黒の 1 ピクセルの単純な線だけを使ってきましたが、この場ではさらに Pen クラスの機能について、詳細に説明します。演出が重要になるゲームアプリケーションなどの開発では様々な場面で使えるでしょう。
ペンのサイズと色はコンストラクタで設定する以外に、オブジェクトのプロパティから設定または取得できます。ペンの幅は Width プロパティで、色は Color プロパティで表されます。
public float Width { get; set; }
public Color Color { get; set; }
例えば、情報を維持する必要の無い不要になった Pen オブジェクトの設定を変更して Draw メソッドで使いまわすということができます。コードの可読性や設計の問題は別とすれば、ひとつのメソッドの中で一度しか使わない Pen オブジェクトを何個も生成するよりも、Pen オブジェクトの設定を変更しながら使った方が負荷は軽減できるでしょう。
using System.Drawing; using System.Windows.Forms; public class Test : Form { protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); Pen pen = new Pen(Color.Black); e.Graphics.DrawLine(pen, 10, 10, 200, 10); pen.Width = 10; pen.Color = Color.Red; e.Graphics.DrawLine(pen, 10, 30, 200, 30); pen.Width = 20; pen.Color = Color.Blue; e.Graphics.DrawLine(pen, 10, 60, 200, 60); } static void Main() { Application.Run(new Test()); } }
コード1は、生成した Pen オブジェクトのプロパティを変更して DrawLine() メソッドを呼び出しています。初期状態では黒い幅 1 ピクセルの線でしたが、幅や色を変更して DrawLine() メソッドにペンを渡すと実行結果のように描画する線の色や変化することを確認できます。
2.6.2 破線スタイル
Pen オブジェクトのデフォルトの状態では切れ目の無い実践を引きますが、DashStyle プロパティを変更することで線の途中に切れ目が生じる破線を描画することができます。
public DashStyle DashStyle { get; set; }
このプロパティに設定する値は System.Drawing.Drawing2D.DashStyle 列挙体のいずれかのメンバです。デフォルトでは実践を表す Solid メンバが設定されています。
[Serializable] public enum DashStyle
Solid の他に、破線を表す Dash と Dot が定義されています。Dash は線の方が空白よりも長く引かれますが Dot は線と空白の間隔が等間隔なので連続した点で線を引きます。Dash と Dot を組み合わせた DashDot と DashDotDot というメンバも存在します。
using System.Drawing; using System.Drawing.Drawing2D; using System.Windows.Forms; public class Test : Form { protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); Pen pen = new Pen(Color.Black, 10); pen.DashStyle = DashStyle.Dash; e.Graphics.DrawLine(pen, 10, 10, 400, 10); pen.DashStyle = DashStyle.Dot; e.Graphics.DrawLine(pen, 10, 30, 400, 30); pen.DashStyle = DashStyle.DashDot; e.Graphics.DrawLine(pen, 10, 50, 400, 50); pen.DashStyle = DashStyle.DashDotDot; e.Graphics.DrawLine(pen, 10, 70, 400, 70); } static void Main() { Application.Run(new Test()); } }
コード2は、破線スタイルをペンに設定して線を描画するプログラムです。線と空白の間隔を確認しやすくするために線の太さを 10 に設定しています。実行結果の上から順に Dash メンバ、Dot メンバ、DashDot メンバ、DashDotDot メンバを設定して描画しています。
2.6.3 キャップ
1ピクセルの単純な線においては重要ではありませんが、太い線の場合は線の開始と終端がどのように終わるのか重要になることがあります。線の開始点と終了点の描画スタイルをキャップスタイルと呼びます。デフォルトでは平坦なキャップが設定されていますが、軟らかさを演出するために丸いキャップを設定するということができます。
キャップの設定は StartCap プロパティ及び EndCap プロパティで設定します。StartCap プロパティは線の始点、EndCap プロパティは線の終点を表します。
public LineCap StartCap { get; set; }
public LineCap EndCap { get; set; }
これらのプロパティに設定する値は System.Drawing.Drawing2D.LineCap 列挙体のいずれかのメンバです。
[Serializable] public enum LineCap
デフォルトでは LineFlat が設定されていますが、このほかに多くのキャップが定義されています。
using System.Drawing; using System.Drawing.Drawing2D; using System.Windows.Forms; public class Test : Form { protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); Pen pen = new Pen(Color.Black, 10); pen.StartCap = LineCap.ArrowAnchor; pen.EndCap = LineCap.DiamondAnchor; e.Graphics.DrawLine(pen, 10, 20, 400, 20); pen.StartCap = LineCap.Round; pen.EndCap = LineCap.RoundAnchor; e.Graphics.DrawLine(pen, 10, 50, 400, 50); pen.StartCap = LineCap.SquareAnchor; pen.EndCap = LineCap.Triangle; e.Graphics.DrawLine(pen, 10, 80, 400, 80); } static void Main() { Application.Run(new Test()); } }
コード3は、pen オブジェクトに任意の LineCap を設定することでユニークな始点と終点を描画しています。
2.6.4 ペンにブラシを設定する
太いペンの内部を塗りつぶす方法として、ブラシを設定することができます。この機能を利用することによって、グラデーションする線や内部がハッチで塗りつぶされる線など、さらにこだわったデザインを実現することができます。
ペンにブラシを設定するには、コンストラクタから設定する方法とプロパティから設定する方法があります。コンストラクタから設定する場合は Color オブジェクトを渡す代わりに Brush オブジェクトを渡します。
public Pen(Brush brush)
public Pen(Brush brush, float width)
brush パラメータにブラシオブジェクトを設定します。width パラメータは Color を渡すコンストラクタと同様に線の太さを指定します。
プロパティから設定・取得する場合は Brush プロパティを使います。
public Brush Brush { get; set; }
Color プロパティと Brush プロパティは競合しているので注意してください。Color を設定した場合は、内部的には SolidBrush オブジェクトが生成されて設定されていると考えてください。よって、ブラシ機能を解除しようとして Brush プロパティに null を設定すれば例外が発生する可能性がありますし、Color を上書きすれば、それに合わせて直前まで設定されていた Brush オブジェクトの効果もなくなります。
using System.Drawing; using System.Drawing.Drawing2D; using System.Windows.Forms; public class Test : Form { protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); Point pt1 = new Point(20, 30); Point pt2 = new Point(400, 200); Brush brush = new LinearGradientBrush( pt1, pt2, Color.Black, Color.Red ); Pen pen = new Pen(brush, 50); e.Graphics.DrawLine(pen, pt1, pt2); } static void Main() { Application.Run(new Test()); } }
コード4では、LinearGradientBrush オブジェクトをペンに設定することでグラデーションする線を実現しています。