Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upCross-platform font selection engine #4901
Comments
|
@kmcallister, is this still useful? If so, I might try and look at it, at least for some platforms. Also, is there any kind of consensus for an API? |
|
cc @vvuk |
|
If fontconfig-rs has an acceptable API, I can work on making it cross-platform. |
|
Fontconfig is not an API that you want to base anything on. It is basically a "pick a font" API that doesn't, by intention, cover all the font services needed by a browser engine. A cross-platform API needs to integrate appropriately with underlying system font services, which means doing more work for older platforms (e.g. XP, Linux) and less for more modern ones (DirectWrite, CoreText). |
|
As I have little-to-no knowledge in (cross-platform) font management, any suggestion of a nice API would be very useful. Should I try to ape CoreText (actually, did you mean CoreText or Apple Type Services?) or DirectWrite, for instance? |
|
cc @retep998 for status on DirectWrite bindings in winapi, I can't seem to find them. The DirectWrite API is C++/COM so it might be a little more involved to call into. Servo actually already has CoreText bindings. I don't know how useful they are though. Edit: looks like the DirectWrite bindings have yet to be filled out: https://crates.io/crates/dwrite-sys |
|
DWrite is COM; as far as I can tell, the winapi bindings are complete for it (despite the docs saying otherwise). The only public entry point is via the DWriteCreateFactory factory getter, everything else is done through interface structs. e.g. https://github.com/retep998/winapi-rs/blob/master/src/dwrite.rs For an API for this, I would suggest looking at what Gecko does -- gfxPlatformFontList/gfxFont and friends. It's been fairly recently designed and is pretty clean, though is support for lots of things that servo may not want to deal with right away. It would also give you an idea of how it maps to the various platforms. |
|
Would it be best to implement this as a separate lib? |
|
Definitely. Cross-platform font selection isn't just a problem for browser engines. It would be really beneficial if it were reusable for other projects. |
|
The initial description of the issue didn't mention actual rendering. Is that still true? |
|
Font management, shaping and rendering are really three separate pieces that are pretty distinct, especially the rendering part. I would keep rendering separate. Note that you really need more than just "font selection", you need a way of managing font resources efficiently. |
|
Do note that on Windows, DirectWrite handles all aspects of dealing with fonts including management shaping and rendering. I'm currently polishing up the dwrite bindings so I can bump them on crates.io soon. |
|
Gecko uses harfbuzz for shaping on all platforms with the exception of Apple-flavored TrueType fonts which require CoreText shaping. Using DirectWrite to do shaping will work just fine but you may not end up with consistent results across platforms and you increase your per-platform testing requirements. |
|
I'm currently working on #7029, so I may not have time to get started on this before a few weeks. |
|
@Yoric: Are you currently working on this? Or is anyone else? I've been looking into how to improve font selection on Linux (see e.g. #12944), but I figured an ideal solution would likely involve something like this. I'd volunteer myself, but testing on Windows and OS X would be very time-consuming for me. I'd be willing to look into handling Fontconfig, though. |
|
Sorry about that, I've been asked to work on other stuff and I forgot to mention it. So, anyone, feel free to pick this up. |
Lazy load fonts in a FontGroup The first commit message explains this so I'll just copy it here: --- This is a step towards fixing #17267. To fix that, we need to be able to try various different fallback fonts in turn, which would become unweildy with the prior eager-loading strategy. Prior to this change, FontGroup loaded up all Font instances, including the fallback font, before any of them were checked for the presence of the glyphs we're trying to render. So for the following CSS: font-family: Helvetica, Arial; The FontGroup would contain a Font instance for Helvetica, and a Font instance for Arial, and a Font instance for the fallback font. It may be that Helvetica contains glyphs for every character in the document, and therefore Arial and the fallback font are not needed at all. This change makes the strategy lazy, so that we'll only create a Font for Arial if we cannot find a glyph within Helvetica. I've also substantially refactored the existing code in the process and added some documentation along the way. --- I've added some tests in the second commit, but it required quite a bit of gymnastics to make it possible to write such a test. I'm not sure if the added complexity to the production code is worth it? On the other hand, having this infrastructure in place may be useful for testing future changes in this area, and also possibly brings us a step closer to extracting a library as discussed in #4901. (What I mean by that is: it reduces coupling between `FontCacheThread` and `FontContext` -- the latter would have a place in such a library, the former wouldn't.) <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/20021) <!-- Reviewable:end -->
Lazy load fonts in a FontGroup The first commit message explains this so I'll just copy it here: --- This is a step towards fixing #17267. To fix that, we need to be able to try various different fallback fonts in turn, which would become unweildy with the prior eager-loading strategy. Prior to this change, FontGroup loaded up all Font instances, including the fallback font, before any of them were checked for the presence of the glyphs we're trying to render. So for the following CSS: font-family: Helvetica, Arial; The FontGroup would contain a Font instance for Helvetica, and a Font instance for Arial, and a Font instance for the fallback font. It may be that Helvetica contains glyphs for every character in the document, and therefore Arial and the fallback font are not needed at all. This change makes the strategy lazy, so that we'll only create a Font for Arial if we cannot find a glyph within Helvetica. I've also substantially refactored the existing code in the process and added some documentation along the way. --- I've added some tests in the second commit, but it required quite a bit of gymnastics to make it possible to write such a test. I'm not sure if the added complexity to the production code is worth it? On the other hand, having this infrastructure in place may be useful for testing future changes in this area, and also possibly brings us a step closer to extracting a library as discussed in #4901. (What I mean by that is: it reduces coupling between `FontCacheThread` and `FontContext` -- the latter would have a place in such a library, the former wouldn't.) <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/20021) <!-- Reviewable:end -->
|
Does font-kit take care of this? |
|
It takes care of some of it. I don't see a good reason for this issue to remain open, though, since we have many of the requirements implemented in Servo. |
See discussion on #1908.
@cybergeek94:
@nattokirai:
See also #3369, #3030, #1677, #249, #190, #186, and many others.
cc @Manishearth, @jdm