TextRenderer で描画する文字列をクリップする - C#
TextRenderer で描画する文字列をクリップするコードを紹介します。
概要
TextRenderer で描画する文字列をクリップするには、boundsパラメーターにクリップする範囲を指定します。
プログラム例
UI
下図のフォームを作成します。Panelを一つ配置します。
コード:背景を描画するのみ
以下のコードを記述します。背景色を描画するのみのコードです。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace TextRendererDemo
{
public partial class FormTextRendererClip : Form
{
public FormTextRendererClip()
{
InitializeComponent();
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
SolidBrush sbk = new SolidBrush(Color.FromArgb(0xA0, 0xA0, 0xA0));
e.Graphics.FillRectangle(sbk, new Rectangle(0, 0, panel1.Width, panel1.Height));
SolidBrush sb = new SolidBrush(Color.FromArgb(0x00, 0x77, 0xe6));
e.Graphics.FillRectangle(sb,new Rectangle(128,48,360,96));
}
}
}
実行結果
実行すると下図のウィンドウが表示されます。背景部分に着色されます。
今回は青の部分の領域でテキストをクリップして描画したいです。
コード:単純なTextRendererの描画
描画位置の座標のみを指定してTextRendererで描画します。下記のコードに変更します。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace TextRendererDemo
{
public partial class FormTextRendererClip : Form
{
public FormTextRendererClip()
{
InitializeComponent();
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
SolidBrush sbk = new SolidBrush(Color.FromArgb(0xA0, 0xA0, 0xA0));
e.Graphics.FillRectangle(sbk, new Rectangle(0, 0, panel1.Width, panel1.Height));
SolidBrush sb = new SolidBrush(Color.FromArgb(0x00, 0x77, 0xe6));
e.Graphics.FillRectangle(sb,new Rectangle(128,48,360,96));
string Drawtext = "ぺんぎんクッキー";
Font f = new Font("Yu Gothic UI", 48);
TextRenderer.DrawText(e.Graphics, Drawtext, f, new Point(128, 88), Color.White);
}
}
}
実行結果
プロジェクトを実行します。下図のウィンドウが表示されます。テキストが描画されますが、あお枠の外側にも描画されています。
コード:boundsパラメーターを指定した描画
以下のコードに変更し、TextRendererのDrawTextメソッドにboundsパラメーターを指定します。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace TextRendererDemo
{
public partial class FormTextRendererClip : Form
{
public FormTextRendererClip()
{
InitializeComponent();
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
SolidBrush sbk = new SolidBrush(Color.FromArgb(0xA0, 0xA0, 0xA0));
e.Graphics.FillRectangle(sbk, new Rectangle(0, 0, panel1.Width, panel1.Height));
Rectangle Area = new Rectangle(128, 48, 360, 96);
SolidBrush sb = new SolidBrush(Color.FromArgb(0x00, 0x77, 0xe6));
e.Graphics.FillRectangle(sb, Area);
string Drawtext = "ぺんぎんクッキー";
Font f = new Font("Yu Gothic UI", 48);
Rectangle DrawRect = new Rectangle(128, 88, 10000, 10000);
Rectangle ClipArea = Rectangle.Intersect(DrawRect, Area);
TextRenderer.DrawText(e.Graphics, Drawtext, f, ClipArea, Color.White);
}
}
}
解説
青い枠を描画するRectangleオブジェクトを変数に格納します。
Rectangle Area = new Rectangle(128, 48, 360, 96);
テキストを描画するRectangleを用意します。左上の開始位置のみを指定し、幅と高さは十分大きい値を設定しておきます。
Rectangle DrawRect = new Rectangle(128, 88, 10000, 10000);
Intersectメソッドを利用して、青枠の領域と、テキストを描画する領域の共通部分のRectangleを求めます。
Intersectメソッドの動作の詳細は
こちらの記事を参照して下さい。
Rectangle ClipArea = Rectangle.Intersect(DrawRect, Area);
実行結果
プロジェクトを実行すると下図の画面が表示されます。青枠内でテキストがクリップされて描画できています。
ただし、クリップを指定しなかった場合と比べると、描画開始の位置が左にずれています。
これは、boundsパラメーターを指定した場合は、デフォルトでは、TextFormatFlags.HorizontalCenter フラグが適用されるためだと考えられます。
コード:TextFormatFlags パラメーターを指定する場合
TextFormatFlags パラメーターを指定して左寄せで描画します。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace TextRendererDemo
{
public partial class FormTextRendererClip : Form
{
public FormTextRendererClip()
{
InitializeComponent();
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
SolidBrush sbk = new SolidBrush(Color.FromArgb(0xA0, 0xA0, 0xA0));
e.Graphics.FillRectangle(sbk, new Rectangle(0, 0, panel1.Width, panel1.Height));
Rectangle Area = new Rectangle(128, 48, 360, 96);
SolidBrush sb = new SolidBrush(Color.FromArgb(0x00, 0x77, 0xe6));
e.Graphics.FillRectangle(sb, Area);
string Drawtext = "ぺんぎんクッキー";
Font f = new Font("Yu Gothic UI", 48);
Rectangle DrawRect = new Rectangle(128, 88, 10000, 10000);
Rectangle ClipArea = Rectangle.Intersect(DrawRect, Area);
TextRenderer.DrawText(e.Graphics, Drawtext, f, ClipArea, Color.White,TextFormatFlags.Default);
}
}
}
解説
TextFormatFlags.Default
を指定します。
TextRenderer.DrawText(e.Graphics, Drawtext, f, ClipArea, Color.White,TextFormatFlags.Default);
実行結果
下図の結果となります。bounds パラメータを指定しなかった場合と同様の位置で、青枠のエリアでクリップされてテキストが描画されています。
プログラム例:GraphicsオブジェクトのSetClipを利用する例
メモ
クリップされて描画できない場合は、Graphicsオブジェクトでクリップされている場合があります。その際は、TextFormatFlags.PreserveGraphicsClipping フラグを追加します。
TextRenderer.DrawText(e.Graphics, Drawtext, f, ClipArea,
Color.White,TextFormatFlags.Default | TextFormatFlags.PreserveGraphicsClipping);
UI
下図のフォームを作成します。Panelを一つ配置します。
コード
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace TextRendererDemo
{
public partial class FormTextRendererClip2 : Form
{
public FormTextRendererClip2()
{
InitializeComponent();
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
Rectangle frame = new Rectangle(64, 32, 240, 96);
Pen p = new Pen(Color.FromArgb(0x41, 0x93, 0xf8),2);
e.Graphics.DrawRectangle(p, frame);
e.Graphics.SetClip(frame);
e.Graphics.DrawLine(p, new Point(128, 0), new Point(512, 256));
string drawText = "Penguin Cookie";
Rectangle textArea = new Rectangle(64, 72, 512, 512);
Font f = new Font("Yu Gothic UI",48);
TextRenderer.DrawText(e.Graphics, drawText, f, textArea, Color.FromArgb(0x5e,0xa5,0x45),TextFormatFlags.Default);
e.Graphics.ResetClip();
}
}
}
解説
四角形の枠を描画します。
Rectangle frame = new Rectangle(64, 32, 240, 96);
Pen p = new Pen(Color.FromArgb(0x41, 0x93, 0xf8),2);
e.Graphics.DrawRectangle(p, frame);
描画した四角形の大きさでクリップします。Graphicsオブジェクトのクリップについては
こちらの記事を参照してください。
e.Graphics.SetClip(frame);
クリップされた状態で線を描画します。
e.Graphics.DrawLine(p, new Point(128, 0), new Point(512, 256));
TextRendererでテキストを描画します。
string drawText = "Penguin Cookie";
Rectangle textArea = new Rectangle(64, 72, 512, 512);
Font f = new Font("Yu Gothic UI",48);
TextRenderer.DrawText(e.Graphics, drawText, f, textArea, Color.FromArgb(0x5e,0xa5,0x45),TextFormatFlags.Default);
クリップを解除します。
e.Graphics.ResetClip();
実行結果
実行します。下図の画面が表示されます。クリップされないことが確認できます。
コードの修正
以下のコードに変更します。
private void panel1_Paint(object sender, PaintEventArgs e)
{
Rectangle frame = new Rectangle(64, 32, 240, 96);
Pen p = new Pen(Color.FromArgb(0x41, 0x93, 0xf8),2);
e.Graphics.DrawRectangle(p, frame);
e.Graphics.SetClip(frame);
e.Graphics.DrawLine(p, new Point(128, 0), new Point(512, 256));
string drawText = "Penguin Cookie";
Rectangle textArea = new Rectangle(64, 72, 512, 512);
Font f = new Font("Yu Gothic UI",48);
TextRenderer.DrawText(e.Graphics, drawText, f, textArea, Color.FromArgb(0x5e, 0xa5, 0x45), TextFormatFlags.Default | TextFormatFlags.PreserveGraphicsClipping);
e.Graphics.ResetClip();
}
実行結果
実行します。下図の画面が表示されます。クリップされて描画されます。
著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用