文字の見栄えを良くしたいときや、背景の画面と文字の色が近い場合には、 縁取り文字を使うとよい[1]。
下に、プログラム例とその実行結果を示す。
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
class Halo : Form {
[STAThread]
static void Main() {
Application.EnableVisualStyles();
Form form = new Halo();
form.Text = "Halo Test"; // フォームのタイトル
Application.Run(form);
}
protected override void OnPaint(PaintEventArgs e) {
Graphics g = e.Graphics;
using (Image img = Image.FromFile("c:/gisdata/tiles/osmx/12/3638/1612.png")) {
g.DrawImage(img, 4, 4, 256, 256);
}
//アンチエリアス
SmoothingMode initialMode = g.SmoothingMode;
g.SmoothingMode = SmoothingMode.HighQuality;
//レンダリング品質
CompositingQuality initialQuality = g.CompositingQuality;
g.CompositingQuality = CompositingQuality.HighQuality;
GraphicsPath gp = new GraphicsPath();
gp.AddString("ふちどりテスト", new FontFamily("MS Gothic"), (int)FontStyle.Regular,
16.0F, new Point(10,10), StringFormat.GenericDefault);
gp.AddString("東京都", new FontFamily("Meiryo UI"), (int)FontStyle.Regular, 14.0F,
new Point(100,100), StringFormat.GenericDefault);
//パスの線分を描画
Pen drawPen = new Pen(Color.White, 1.0F);
g.DrawPath(drawPen, gp);
//塗る
Brush fillBrush = new SolidBrush(Color.Purple);
g.FillPath(fillBrush, gp);
drawPen.Dispose();
fillBrush.Dispose();
//念のため元に戻しておきます
g.SmoothingMode = initialMode;
g.CompositingQuality = initialQuality;
}
}
地図システムで使うため、再実験をした。
Mapnikで生成したタイル地図(左図)に "兵庫県三木市"を3行上書きした。
前節の方法でこの例の大きさの文字を描画すると、なぜか、色が薄くなる。 そのため、縁取りは上の方法で行い、文字描画は普通に行ってみた(右図)。
下から二番目の文字は縁取りなしで普通に描画したものである。 一番上と一番下は縁取りした。
縁取りの線の太さは 3.0 としている。 縁取りのフォントサイズは 上が11.0、下が 10.0 で、文字のフォントサイズは 上が 8.0、下が 7.5 である。
縁取りのフォントサイズは「文字のフォントサイズ+縁取り線の太さ」が目安となる。
このような方法を採れば、小さい文字でも、Mapnikに比べて、 それほど見劣りしない文字が描画できそうである。
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
class Halo : Form {
[STAThread]
static void Main() {
Application.EnableVisualStyles();
Form form = new Halo();
form.Text = "Halo Test"; // フォームのタイトル
Application.Run(form);
}
protected override void OnPaint(PaintEventArgs e) {
Graphics g = e.Graphics;
using (Image img = Image.FromFile("c:/gis/896_406.png")) {
g.DrawImage(img, 4, 4, 256, 256);
}
//アンチエリアス
SmoothingMode initialMode = g.SmoothingMode;
g.SmoothingMode = SmoothingMode.HighQuality;
//レンダリング品質
CompositingQuality initialQuality = g.CompositingQuality;
g.CompositingQuality = CompositingQuality.HighQuality;
GraphicsPath gp = new GraphicsPath();
gp.AddString("兵庫県三木市", new FontFamily("Meiryo UI"), (int)FontStyle.Regular, 11.0F,
new Point(6,10), StringFormat.GenericDefault);
gp.AddString("兵庫県三木市", new FontFamily("Meiryo UI"), (int)FontStyle.Regular, 10.0F,
new Point(6,60), StringFormat.GenericDefault);
//パスの線分を描画
Pen drawPen = new Pen(Color.White, 3.0F);
g.DrawPath(drawPen, gp);
//塗る
Brush fillBrush = new SolidBrush(Color.Black);
Font font = new Font("Meiryo UI", 8.0f, FontStyle.Regular);
g.DrawString("兵庫県三木市", font, fillBrush, 7, 10);
g.DrawString("兵庫県三木市", font, fillBrush, 7, 40);
g.DrawString("兵庫県三木市", new Font("Meiryo UI", 7.5f, FontStyle.Regular), fillBrush, 7, 60);
drawPen.Dispose();
fillBrush.Dispose();
//念のため元に戻す
g.SmoothingMode = initialMode;
g.CompositingQuality = initialQuality;
}
縁取りの太さを halo としたとき、文字の描画位置を x, y とすると、縁取り位置は x-halo, y-halo とすべきであろう。 線分の太さは halo か halo*2 のどちらだろう。 大きなフォントサイズで試行錯誤で適切な値を探るのがいい。
試行錯誤の末、現在(2019.6)は次のようにしている。
SmoothingMode initialMode = g.SmoothingMode;
g.SmoothingMode = SmoothingMode.HighQuality; // アンチエリアス
CompositingQuality initialQuality = g.CompositingQuality;
g.CompositingQuality = CompositingQuality.HighQuality; // レンダリング品質
GraphicsPath gp = new GraphicsPath();
gp.AddString(name, new FontFamily("Meiryo UI"), (int)FontStyle.Regular,
(float)(fsize*96/72), new Point(rc.X, rc.Y), StringFormat.GenericDefault);
Pen drawPen = new Pen(Color.FromArgb(160,255,255,255), (float)(halo*2));
g.DrawPath(drawPen, gp); // パスの線分を描画
drawPen = new Pen(Color.FromArgb(120,rx,gx,bx), 0.1f);
g.DrawPath(drawPen, gp); // パスの線分を描画
g.FillPath(brush, gp); // 線分の内部を塗る
drawPen.Dispose();
g.SmoothingMode = initialMode; // 念のため元に戻しておく
g.CompositingQuality = initialQuality; // 同上