SixLabors / Fonts

:black_nib: Font loading and layout library.
https://sixlabors.com/products/fonts
Other
306 stars 71 forks source link

UnicodeData class is not working without reflection #279

Closed kant2002 closed 2 years ago

kant2002 commented 2 years ago

Simple call to UnicodeData.GetBidiData produce error in NativeAOT reflection-free mode. Even reflection-free mode is niche, would be good somehow provide workaround for these scenarios.

Underlying issues is https://github.com/SixLabors/Fonts/blob/034a440aece357341fcc6b02db58ffbe153e54ef/src/SixLabors.Fonts/Unicode/UnicodeData.cs#L45-L48

Embedded resources unlikely will even work in reflection-free mode for NativeAOT so maybe would be possible provide some additional API which provide additional sources for these data, maybe from extenally supplied Stream?

Sergio0694 commented 2 years ago

Not as nice to work with, but it should be possible to just embed these files directly in the assembly as ReadOnlySpan<byte> (so they just get embedded in the .data section and are free and with no reflection). I could see hacking together either a small script to generate this, or maybe a source generator to annotate files in the project and have it generate the properties for you (ie. use the AdditionalFiles provider from Roslyn, get the list of files ร  la CsWin32, read, emit the binary blob in some target class). That'd solve the issue mentioned here, especially given all these files are known at build time in this case ๐Ÿ™‚

JimBobSquarePants commented 2 years ago

That would probably lead to some major performance wins also. Some recent profiling of text shaping indicated that almost all time was spent unpacking the data.

I wouldn't have a clue where to start though with source generators. I'd also need someone with smarts to better pack the data so that I don't have so many trie structures. I'm currently doing a poor job there. Avalonia seem to get most of what I need into only 3 (I currently use 7!!).

Sergio0694 commented 2 years ago

I can probably help with the source generator part. Happy to put together a small prototype if you need ๐Ÿ™‚ To save the unpacking time though you'd also need to find a way to precompute the data you need somewhat, so that there'd be less work to load it after getting the embedded binary blobs. That's orthogonal though, so the two problems can be tackled separately. Even just doing this embedded resource trick alone would at least fix the issue related to reflection ๐Ÿ‘

JimBobSquarePants commented 2 years ago

That would be incredible if you could. Thanks!

kant2002 commented 2 years ago

That's alternative way. Maybe that approach would be interesting too. https://github.com/AvaloniaUI/Avalonia/pull/8368

JimBobSquarePants commented 2 years ago

Oh thatโ€™s clever! Very simple approach also.