mono / SkiaSharp

SkiaSharp is a cross-platform 2D graphics API for .NET platforms based on Google's Skia Graphics Library. It provides a comprehensive 2D API that can be used across mobile, server and desktop models to render images.
MIT License
4.24k stars 525 forks source link

[FEATURE] Variable fonts support, shaping with opentype features opt-in #2318

Open themcoo opened 1 year ago

themcoo commented 1 year ago

Is your feature request related to a problem? Please describe.

We are developing a windows .net app that is required to provide some typographical features to the user. Current version of SkiaSharp does not expose some of the API available in native skia and harfbuzz that allows to achieve things like opentype features (e.g. kerning, ligatures) or setting design coords of variable font axis. Currently we are working around some of these limitations by PInvoking functions from libSkiaSharp and libHarfBuzzSharp but it becomes more and more clunky I feel. Also worth mentioning is that this needs to be supported for ad hoc uploaded font files, for which the support in SkiaSharp is even more limited, as you can't really use SkFontManager for these as it only handles system fonts. (or can you but I didn't find how?)

Also if there is actually some other way to achieve what I am trying to do - please point me that way :) I'm also more than eager to contribute, the problem is I really have a hard time getting everything built locally, not mentioning to run tests for various platforms. I was not able to get the whole skiasharp to build correctly, I managed to get libSkiaSharp built which allowed me to expose some of the API I was missing.

Describe the solution you'd like

For much better experience with typography in SkiaSharp I'd like to expose following API:

  1. SkShaper.Shape should get Feature[] features parameter which would enable easy access to features like 'liga' or 'kern' (and tens more available in open type fonts)
  2. Harfbuzz Font: hb_font_set_var_coords_design, hb_font_set_var_named_instance should be exposed to allow proper shaping of variable fonts.
  3. SkTypeFace:

Describe alternatives you've considered

There is not really a good alternative at the moment. At least that I'm not aware of. SkiaSharp is a fantastic library and I hesitate from using anything more. There is just a lot of useful api still not exposed. The current workarounds I did to get above things working: Ad. 1. Implemented SkShaperFeatured which is basically source copy of SkShaper, but has features parameter enabled. Ad. 2. PInvoking to already available libHarfbuzz extern functions. Ad. 3. Had to expose extern static funcs to above api and rebuild libSkiasharp. I didn't succeed getting SkiaSharp nuget built, but that's work in progress, so I'm PInvoking to these functions at the moment. This requires maintaining a fork though.

Additional context

Ad. 1 I was able to render all kinds of featured type faces with the workarounds (example of Calibri below) image

Ad. 2/3 I'm currently testing the workarounds, with mostly successes, but I do not have a screenshot to share.

avisra commented 4 days ago

Can you share your code for enabling the kern option?

themcoo commented 1 day ago

Unfortunately I don't work for the company I developed the font features for anymore. But actually everything worked out, including handling fonts from arbitrary streams, variable fonts, precise text measurement and positioning, etc.