dotnet / dotnet/winforms

Font API

Open
#8,828 8 comments 1 reaction 0 assignees View on GitHub
api-suggestion area-System.Drawing
Dominant language
C#
Stars
4.9k
Forks
1.1k
Avg merge
20h 23m
Merged PRs (30d)
103

Description

## Background and Motivation

Right now, it's fundamentally impossible to list all available fonts.
The existing API is Windows only.
If I want to generate a PDF on Linux, Mac, Android or iOS, I can't get a list of installed font files.
On Linux, I can call libfontconfig, if it's installed, which is relatively straight-forward.
But on OSX, the entire thing is a nightmare.
I can either hard-code the font files, embed them (if the license allows it), or I can add a 500+ MB dependency on Xamarin.Mac/Xamarin.IOS, and add the objective-c-runtime & entire frameworks that would otherwise be completely unnecessary.
If I don't want to do that, I have to write a C++ dll, something along [NodeJS's font-manger](https://github.com/foliojs/font-manager/tree/master/src), which is platform specific code.

All existing programs that handle fonts basically hard-code the paths, and to hell with you if that list doesn't include yours.

On top of that, the existing font API doesn't show the font's path.
So if I have to actually read the font-file to e.g. create a svg-path from Text and a font-file (and size and style), I can't do that with the existing API. I have to call GetFontData and operate on a stream instead.

Naturally, GetFontData is Windows-Only, and if you want to emulate it, you need freetype, which is yet another very platform-specific binary. On top of that, the freetype-types differ on 32 vs. 64 bit between Windows and Linux, which means you need typedefs which you don't have. So you need to manually modify the .csproj file with ifdef-symbols to hack around that, and then add a ifdef-cascade on top of every file that uses them... nuint or System.IntPtr cannot be used, because a native-C-int doesn't vary on Linux on 32 vs. 64, but it does on Windows...

Also, there's no API to create embeddable font-packages.
There is only the CreateFontPackage API-call, and it is Windows-specific.

## Proposal
```
public class Font
{
public string Path;
public string FontName;
public Styles[] AvailableStyles;
public Span FontData;

// Perhaps for backwards-compatibility, but unnecessary
public System.Drawing.Font { get; }
}

public List ListInstalledFonts() {}
public IEnumerable EnumerateInstalledFonts() {}

public Span CreateFontPackage(Stream fontFile, int[] codePoints) {}
public Span CreateFontPackage(Span fontData, int[] codePoints) {}
public Span CreateFontPackage(byte[] fontData, int[] codePoints) {}
public Span CreateFontPackage(string fontFile, int[] codePoints) {}
```
And some kind of unified font-metrics and glyph-metrics API, capable of reading TrueType/OpenType/WOFF/etc.
An APIs that allows for a high degree of control for fine typography and for processing complex scripts, the rules governing the shaping and positioning of glyphs, including line-breaks in complex scripts, without native dependencies.

Nice-to have:
A simple API to create, edit and convert font-files ?

And all of it not Windows-Specific.
**Dependencies: self-contained .NET Runtime Only**

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.