techno
techno

Reputation: 6508

Filtering out /Removing Non True Type Fonts from Font Dialog in C#

I,m using a font dialog to select a font and create a font from the selected font using

font = new Font(fontDialog1.Font.Name, fontDialog1.Font.Size, FontStyle.Regular, GraphicsUnit.Pixel);

When i Select a Non True type font I'm getting an 'This is not a TrueType font' Exception,I know GDI+ has support only for TTF.I've worked around this by using a try catch block.But how can i configure the font dialog to show only TTF's.

Upvotes: 4

Views: 3218

Answers (2)

Simon Mourier
Simon Mourier

Reputation: 139187

I don't think there is a solution to this issue (as stated by numerous others articles on the web), but you can rewrite the FontDialog somehow to fit your need.

To get you started, here is the implementation of a FontListBox that displays an owner draw listbox with fonts rendered in it:

enter image description here

Sample dialog that hosts it:

public partial class MyFontDialog : Form
{
    private FontListBox _fontListBox;

    public MyFontDialog()
    {
        InitializeComponent();

        _fontListBox = new FontListBox();
        _fontListBox.Dock = DockStyle.Fill;
        Controls.Add(_fontListBox);
    }
}

The list box:

public class FontListBox : ListBox
{
    private List<Font> _fonts = new List<Font>();
    private Brush _foreBrush;

    public FontListBox()
    {
        DrawMode = DrawMode.OwnerDrawFixed;
        ItemHeight = 20;
        foreach (FontFamily ff in FontFamily.Families)
        {
            // determine the first available style, as all fonts don't support all styles
            FontStyle? availableStyle = null;
            foreach (FontStyle style in Enum.GetValues(typeof(FontStyle)))
            {
                if (ff.IsStyleAvailable(style))
                {
                    availableStyle = style;
                    break;
                }
            }

            if (availableStyle.HasValue)
            {
                Font font = null;
                try
                {
                    // do your own Font initialization here
                    // discard the one you don't like :-)
                    font = new Font(ff, 12, availableStyle.Value);
                }
                catch
                {
                }
                if (font != null)
                {
                    _fonts.Add(font);
                    Items.Add(font);
                }
            }
        }
    }

    protected override void Dispose(bool disposing)
    {
        base.Dispose(disposing);
        if (_fonts != null)
        {
            foreach (Font font in _fonts)
            {
                font.Dispose();
            }
            _fonts = null;
        }
        if (_foreBrush != null)
        {
            _foreBrush.Dispose();
            _foreBrush = null;
        }
    }

    public override Color ForeColor
    {
        get
        {
            return base.ForeColor;
        }
        set
        {
            base.ForeColor = value;
            if (_foreBrush != null)
            {
                _foreBrush.Dispose();
            }
            _foreBrush = null;
        }
    }

    private Brush ForeBrush
    {
        get
        {
            if (_foreBrush == null)
            {
                _foreBrush = new SolidBrush(ForeColor);
            }
            return _foreBrush;
        }
    }

    protected override void OnDrawItem(DrawItemEventArgs e)
    {
        base.OnDrawItem(e);
        if (e.Index < 0)
            return;

        e.DrawBackground();
        e.DrawFocusRectangle();
        Rectangle bounds = e.Bounds;
        Font font = (Font)Items[e.Index];
        e.Graphics.DrawString(font.Name, font, ForeBrush, bounds.Left, bounds.Top);
    }
}

Upvotes: 2

Gabe
Gabe

Reputation: 86798

Unfortunately it seems that GDI+ just can't handle certain fonts. To make a long story short, there were two common scalable font standards: TrueType and PostScript. These were merged into OpenType, such that an OpenType font may have TT outlines, PS outlines, or both. When you ask for only TT fonts to be shown in the font picker, OT fonts are included, even those that contain only PS outlines. This is because GDI can render them even though GDI+ cannot.

If you wanted to make a font picker that didn't show those fonts, you'd have to figure out some way of determining which fonts were supported (either open them up and parse them looking for the TT outlines, try to use each one and see if you get an exception, or have a whitelist). Then you'd have to make a font picker dialog that only showed those fonts.

Upvotes: 0

Related Questions