WPF DrawingContext DrawGlyphRun blur text

954 views Asked by At

I'm using the DrawingContext DrawGlyphRun(GlyphRun) function to draw text in the Canvas using the solution from https://smellegantcode.wordpress.com/2008/07/03/glyphrun-and-so-forth/.

I'm using this over the FormattedText because it's faster and it's also used for calculating text width.

This works well except for 2 problems:

  1. Text is blurred (see below the image). Text at the top is displayed using GlyphRun. The bottom text is displayed using FormattedText which has better quality.

Blur Image

  1. Cannot display Japanese or Chinese characters.

Problem with characters seems to be that GlyphTypeface.CharacterToGlyphMap cannot find the jp or cn character, so I'm not sure how exactly to deal with these characters.

1

There are 1 answers

0
Nikolay On

I just found your question after some research that I made.

GlyphRun created using public constructors creates object with TextFormattingMode = Ideal

All WPF contols for their rendring use methods/constructors that accepts TextFormattingMode as parameter.

You can call GlyphRun.TryCreate() static method via reflection:

internal static GlyphRun TryCreate(
        GlyphTypeface           glyphTypeface,
        int                     bidiLevel,
        bool                    isSideways,
        double                  renderingEmSize,
        IList<ushort>           glyphIndices,
        Point                   baselineOrigin,
        IList<double>           advanceWidths,
        IList<Point>            glyphOffsets,
        IList<char>             characters,
        string                  deviceFontName,
        IList<ushort>           clusterMap,
        IList<bool>             caretStops,
        XmlLanguage             language,
        TextFormattingMode      textLayout
        )

but the problem that you need to get advanceWidths with TextFormattingMode = Ideal. For this you need access via reflection to internal methods provided by GlyphTypeface class.

GlyphTypeface.AdvanceWidths property that returns dictionary with these widths internally calls to

internal double GetAdvanceWidth(ushort glyph, TextFormattingMode textFormattingMode, bool isSideways)

when you access dictionary by index with textFormattingMode = TextFormattingMode.Ideal

You can download .Net source code and check it yourself.

As for your second question I think that you use chars instead of unicode code points to get glyph index.