2011年04月03日

メイリオの描画位置がずれる問題の解決方法(Transform)(C#)

前回『メイリオの描画位置がずれる問題(C#)』の解決方法です。これはTransformによる解決方法です。別の解決方法も→『メイリオの描画位置がずれる問題の解決方法(クリッピング)(C#)

GraphicsPathにAddStringするときに、あらかじめ座標をずらしておけば良いのですが、Pathの位置を知ることができるのはAddStringした後です。
また、DrawPathでは座標をずらすことはできません。

そこで、AddStringでPathを追加した後に、Pathの位置をずらします。GraphicsPath.Transformを使います。
文字を描画したい位置が"pos.X"、"pos.X"、実際に文字が描画される位置が"gp.GetBounds().X"、"gp.GetBounds().Y"、であるため、その差分の分をTransformで移動させてやります。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // PictureBoxを生成しFormに追加
            PictureBox picture = new PictureBox();
            picture.Width = this.Width;
            picture.Height = this.Height;
            this.Controls.Add(picture);

            // Imageを生成してPictureBoxに割当
            Bitmap image = new Bitmap(this.Width, this.Height);
            picture.Image = image;

            // Imageに描画
            Graphics g = Graphics.FromImage(image);
            g.Clear(Color.Black);

            // アンチエリアス
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;

            // レンダリング品質
            g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;

            // 描画する文字
            string text = "Aaあぁアァ亜宇";

            // メイリオでの描画
            {
                Font font = new Font("メイリオ", 24, FontStyle.Bold);
                Point pos = new Point(20, 20);

                // GraphicsPathの生成
                System.Drawing.Drawing2D.GraphicsPath gp = new System.Drawing.Drawing2D.GraphicsPath();

                // テキストをPathに変換
                gp.AddString(text, font.FontFamily, (int)font.Style, font.SizeInPoints,
                    pos, StringFormat.GenericDefault);

                // ☆パスを移動させる
                {
                    System.Drawing.Drawing2D.Matrix translateMatrix = new System.Drawing.Drawing2D.Matrix();
                    translateMatrix.Translate(pos.X - gp.GetBounds().X, pos.Y - gp.GetBounds().Y);
                    gp.Transform(translateMatrix);
                    translateMatrix.Dispose();
                }

                // 文字の縁を描画
                g.DrawPath(new Pen(Brushes.Blue, 3.0f), gp);

                // 文字を塗る
                g.FillPath(Brushes.White, gp);

                // Pathに内接する四角形を描画
                RectangleF rect = gp.GetBounds();
                g.DrawRectangle(Pens.Red, rect.X, rect.Y, rect.Width, rect.Height);

                // 描画位置にマーキング
                g.DrawLine(Pens.Pink, pos.X - 20, pos.Y, pos.X + 20, pos.Y);
                g.DrawLine(Pens.Pink, pos.X, pos.Y - 20, pos.X, pos.Y + 20);

                // 終了
                gp.Dispose();
            }

            // MSゴシックでの描画
            {
                Font font = new Font("MS Pゴシック", 24, FontStyle.Bold);
                Point pos = new Point(20, 120);

                // GraphicsPathの生成
                System.Drawing.Drawing2D.GraphicsPath gp = new System.Drawing.Drawing2D.GraphicsPath();

                // テキストをPathに変換
                gp.AddString(text, font.FontFamily, (int)font.Style, font.SizeInPoints,
                    pos, StringFormat.GenericDefault);

                // ☆パスを移動させる
                {
                    System.Drawing.Drawing2D.Matrix translateMatrix = new System.Drawing.Drawing2D.Matrix();
                    translateMatrix.Translate(pos.X - gp.GetBounds().X, pos.Y - gp.GetBounds().Y);
                    gp.Transform(translateMatrix);
                    translateMatrix.Dispose();
                }

                // 文字の縁を描画
                g.DrawPath(new Pen(Brushes.Blue, 3.0f), gp);

                // 文字を塗る
                g.FillPath(Brushes.White, gp);

                // Pathに内接する四角形を描画
                RectangleF rect = gp.GetBounds();
                g.DrawRectangle(Pens.Red, rect.X, rect.Y, rect.Width, rect.Height);


                // 描画位置にマーキング
                g.DrawLine(Pens.Pink, pos.X - 20, pos.Y, pos.X + 20, pos.Y);
                g.DrawLine(Pens.Pink, pos.X, pos.Y - 20, pos.X, pos.Y + 20);

                // 終了
                gp.Dispose();
            }
        }
    }
}

実行するとこのようになります。
meyrio-2.png
白っぽい十字の線が本来描画させたい位置です。実際に描画されたのが赤い四角形の位置です。
今回は、ずれがなく表示できています。

良かったらクリックしてください
にほんブログ村 IT技術ブログ プログラム・プログラマーへ  人気ブログランキングへ

posted by among at 19:36 | Comment(1) | TrackBack(0) | C#
この記事へのコメント
トミーヒルフィガー
Posted by tumi 財布 at 2013年09月09日 10:22
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

この記事へのトラックバックURL
http://blog.sakura.ne.jp/tb/44122359

この記事へのトラックバック