dotnet / winforms

Windows Forms is a .NET UI framework for building Windows desktop applications.
MIT License
4.43k stars 986 forks source link

Add MeasureDriverString/DrawDriverString functionality to System.Drawing #8834

Open reflectronic opened 4 years ago

reflectronic commented 4 years ago

Background

There are a couple of APIs related to advanced text drawing in GDI+. These APIs, MeasureDriverString and DrawDriverString, allow complete control over the appearance of text: layout, formatting, etc. For whatever reason, these APIs were left out of System.Drawing. This is in the same bucket as the previous CachedBitmap proposal (#36105) of features originally in GDI+ but were (perhaps unintentionally) excluded from the managed API surface.

API Proposal

See the documentation for DrawDriverString, MeasureDriverString, and DriverStringOptions.

namespace System.Drawing.Text
{
+   [Flags]
+   public enum DriverStringOptions
+   {
+       CmapLookup = 1,
+       Vertical = 2,
+       RealizedAdvance = 4,
+       LimitSubpixel = 8
+   }
} 

namespace System.Drawing
{
    public sealed class Graphics : MarshalByRefObject, IDisposable, IDeviceContext
    {
+       public void DrawDriverString(ushort[] text, Font font, Brush brush, PointF[] positions, DriverStringOptions flags, Matrix matrix);
+       public void DrawDriverString(Span<ushort> text, Font font, Brush brush, Span<PointF> positions, DriverStringOptions flags, Matrix matrix);  

+       public RectF MeasureDriverString(ushort[] text, Font font, Brush brush, PointF[] positions, DriverStringOptions flags, Matrix matrix); 
+       public RectF MeasureDriverString(Span<ushort> text, Font font, Brush brush, Span<PointF> positions, DriverStringOptions flags, Matrix matrix); 

    }
}

Honestly, the names on the enum members do not feel very descriptive to me. However, they match the native definitions, and the documentation comments on these members should be sufficient.

Regarding CmapLookup

The documentation for the DrawDriverString states:

[in] text Type: const UINT16* Pointer to an array of 16-bit values. If the DriverStringOptionsCmapLookup flag is set, each value specifies a Unicode character to be displayed. Otherwise, each value specifies an index to a font glyph that defines a character to be displayed.

The term Cmap appears to violate the naming guidelines, but it seems to refer to the cmap table in OpenType fonts which maps from character codes to glyph indices. If this flag is set, the cmap table would be used to find the glyph indices from the data encoded as UTF-16 in text. Otherwise, the text array is interpreted as a list of glyph indices in the font. (As such, the signature is represented as a ushort[] instead of a string.)

ghost commented 4 years ago

Tagging subscribers to this area: @safern, @tannergooding Notify danmosemsft if you want to be subscribed.