GDI+のフォントのパス取得に限界はありますか?

MFCプログラマー 121 評価のポイント
2024-04-09T07:30:29.63+00:00

Windows11 MFC/C++でソフトを開発しています。

GDI+を使ってフォントを画面に描画してします。

方法はGraphicsPath::AddStringでフォントのパスを得てGraphics::FillPathで描画しているのですが、

拡張フォント系は全部表示できません。

AddStringは正常に返っているのですが、パスが取れてない感じです。

拡張系のフォント(CJK互換文字 や CJK総合漢字拡張(U+3400~) 等)はGDI+では使えないのでしょうか?

C++
C++
C プログラミング言語の拡張機能として作成された高レベルの汎用プログラミング言語。低レベルのメモリ操作機能に加えて、オブジェクト指向、汎用、関数型の機能を備えています。
20 件の質問
0 件のコメント コメントはありません
{count} 件の投票

承認済みの回答
  1. gekka 9,666 評価のポイント MVP
    2024-04-09T09:42:30.78+00:00

    MFC/C++でテストするのは面倒なので、C#でGDI+の技術を使っているGraphicsでテストしましたが、問題なくパスの取得も描画もできました。
    よって、C++でも使えるはずです。

    using System;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Windows.Forms;
    
    public partial class Form1 : Form
    {
        private ListBox listBox1 = new ListBox();
        private TextBox textBox1 = new TextBox();
        private PictureBox pictureBox1 = new PictureBox();
        private FontFamily[] fontFamilies;
        private const int fontSize = 50;
    
        public Form1()
        {
            this.Width = 500;
            this.Height = 500;
    
            textBox1 = new TextBox();
            textBox1.Location = new Point(2, 2);
            textBox1.Width = 150;
            textBox1.Text = char.ConvertFromUtf32(0x20BB7) + "\r\n" + string.Join("", Enumerable.Range(0x3400, 100).Select(_ => char.ConvertFromUtf32(_)));
            textBox1.TextChanged += OnChanged;
            this.Controls.Add(textBox1);
    
            listBox1 = new ListBox();
            listBox1.Left = 2;
            listBox1.Top = textBox1.Bottom + 2;
            listBox1.Width = 150;
            listBox1.Height = this.ClientSize.Height - listBox1.Top - 5;
            listBox1.SelectedIndexChanged += OnChanged;
            listBox1.Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Bottom;
            this.Controls.Add(listBox1);
    
            pictureBox1 = new PictureBox();
            pictureBox1.Left = 150;
            pictureBox1.Top = 0;
            pictureBox1.Width = this.ClientSize.Width - 150;
            pictureBox1.Height = this.ClientSize.Height;
            pictureBox1.Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right | AnchorStyles.Bottom;
            this.Controls.Add(pictureBox1);
    
            this.SizeChanged += OnChanged;
    
            fontFamilies = new System.Drawing.Text.InstalledFontCollection().Families;
            foreach (var ff in fontFamilies)
            {
                this.listBox1.Items.Add(ff.Name);
            }
            if (this.listBox1.Items.Count > 0)
            {
                this.listBox1.SelectedIndex = 0;
            }
        }
    
        private void OnChanged(object sender, EventArgs e)
        {
            this.pictureBox1.Image?.Dispose();
            this.pictureBox1.Image = null;
    
            if (listBox1.SelectedIndex < 0 || this.pictureBox1.Width==0 || this.pictureBox1.Height==0)// サイズ0のBitmapはエラーになる
            {
                return;
            }
    
            Bitmap bmp = new Bitmap(this.pictureBox1.Size.Width, this.pictureBox1.Size.Height);
            string text = this.textBox1.Text;
    
            FontFamily ff = fontFamilies[listBox1.SelectedIndex];
    
            using (StringFormat sf = new System.Drawing.StringFormat())
            {
                using (System.Drawing.Drawing2D.GraphicsPath path = new System.Drawing.Drawing2D.GraphicsPath())
                {
                    try
                    {
                        path.AddString(text, ff, (int)System.Drawing.FontStyle.Regular, fontSize, new Rectangle(0, 0, pictureBox1.Width, pictureBox1.Height), sf); //環境とフォントによってはエラーになることがある?
                    }
                    catch(Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                        return;
                    }
                    using (Graphics g = Graphics.FromImage(bmp))
                    {
                        g.FillRectangle(Brushes.White, 0, 0, bmp.Width, bmp.Height);
    
    
                        g.DrawPath(Pens.Black, path);
                        //g.FillPath(Brushes.Red, path);
                    }
                }
    
            }
    
    
            this.pictureBox1.Image = bmp;
        }
    }
    

    2024-04-09 22:48エラーになるところをちょっと対応

    1 人がこの回答が役に立ったと思いました。

1 件の追加の回答

並べ替え方法: 最も役に立つ
  1. MFCプログラマー 121 評価のポイント
    2024-04-09T08:35:06.7066667+00:00

    フォントによっては 拡張系も極一部の文字だけ表示する事が判りましたが、

    何が原因で表示可/不可なのか未だ不明です。

    0 件のコメント コメントはありません

お客様の回答

回答は、質問作成者が [承諾された回答] としてマークできます。これは、ユーザーが回答が作成者の問題を解決したことを知るのに役立ちます。