-
Notifications
You must be signed in to change notification settings - Fork 70
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Text rendering #1
Comments
I think woff2 is better than ttf. |
@yisar WOFF2 is a file format organization and compression scheme to optimize transmission of fonts over the internet for embedding in websites. The font payload you get after transfer and decompression in the end is the same. These days whether packaged as TTF, OTF, or WOFF2 what you are getting in terms of shapes and font functionality is identical. And hence you need a TTF parser to handle WOFF2 ;-) And WOFF2 doesn't make much sense for local font rendering, it's more CPU time to optimize away something that isn't even a bottleneck when working with local font files. |
Maybe https://github.com/servo/font-kit is also suitable for |
@Brooooooklyn |
Take a look at ‘fontdue’ by @mooman219 It may meet your requirements: https://github.com/mooman219/fontdue |
@kettle11 |
@kettle11 this is kinda a small rundown of my opinion of the situation
This is fairly accurate. The problem is that overall, the crates mentioned above (no-std crates with nice APIs) in rust are very limited in their scope over the domains they cover.
The big one here is shaping, which in pure rust is immature and greatly influences the design of implementing some of these features like BiDi. Any serious work from any no-std font-engine can really start once that's settled in my opinion, so we're basically hoping that either A quick note: |
I wanted to add linebreaking to that list as well. It's wildly more complex than the spec implies. The unicode linebreak annex defines the bare minimum you should handle, but is not This feels like making a working group territory, but also there's not a ton of people that actually care about pure rust solutions :'( . I think the xi zulip is the most concentrated group so far, but there's not a big push for no-std solutions there. I'd be happy to break anything out of |
@mooman219 Afaik, Also, Skia has it's own paragraph implementation on top of harfbuzz. This what flutter use (or plan to use). PS: Why do you care about no-std solutions? |
Whoops, I'm conflating
Yep! I've read a lot about it the past few weeks which is why I wanted to mention linebreaking as a problem that still needs to be solved in pure rust, even if it's just cloned from Skia.
This is mostly a personal opinion. I think that a huge benefit of having the ecosystem in pure rust is going the next step to being no-std. |
In this sense, tiny-skia also can be |
No-std is a well defined term since it's a crate level attribute. I like to think alloc is in the spirit of no-std. Alloc is reasonably free to add on most no-std environments. Requiring all the threading/networking/file system/etc components is really heavy. Making tiny-skia no-std and just needing alloc would be great for some of the common no-std environments like consoles |
I've been using |
@bschwind You have a very large text. It will always look good. The problem is in the tiny one. To test shaping, you can simply try rendering Arabic text. To test the layout, you can use a mix of Arabic and English. |
Ahhh okay, today I learned :) Makes sense though! I'm sure Arabic text or Arabic + English wouldn't turn out well currently. As mooman219 mentioned, it just does basic rasterization and layout at the moment. |
Anyway,
I think it would be productive to make an exhaustive list of what this means and see if we can those on the radar of the existing pure-rust rasters. |
@mooman219 All I want to see, as I've mentioned a while ago, is a detailed comparison between different libraries. Here is PNG generated by fontdue, here is one by freetype, etc. As a library author, you should sell your library first. Performance is great, but this in not what I care about. Font's rendering is one of the areas that I really don't want to go into, because it's too subjective. |
I’d expect this (and parsing as necessary for this) to be in scope for tiny-skia eventually. Everything else (shaping, layout, bidi, fallback, …) could be built separately on top, though that doesn’t mean smooth integration can’t exist. Compare with Cairo v.s. Pango (and |
@SimonSapin I actually haven't looked into how Skia renders glyphs yet, so I'm not sure. It clearly depends on freetype, so I assume it uses it for rasterization (or maybe just for outlining). It also has it's own minimal TrueType parser for some additional info I guess. |
Barely worth a mention here, but KAS-text implements:
The library vaguely follows the relevant Unicode specifications but isn't fully compliant. Caveats: the API won't suit all users, likely significant redesign is needed for freetype-quality and performance. |
@dhardy I don't know when I would have time to implement text support, but it would probably be implemented from scratch using ttf-parser + rustybuzz + fontdb + ab_glyph_rasterizer/fontdue/own renderer. I.e. a pure Rust solution. Any non-Rust dependencies are forbidden. |
@RazrFalcon the only non-Rust dep in KAS-text is HarfBuzz, which is optional (and probably will be replaced soon). In any case, I was more pointing out another "piece" for the Rust font ecosystem, for anyone here interested. |
@dhardy What about Sure. I'm still not sure what API I want, but it probably will be low-level enough to be used in resvg. Basically, I need a very good font fallback support (which I don't have) and an ability to modify position of each glyph (each glyph should also have some metadata left, so I could match it with an original string). |
You're right, KAS-text does include the string index with each glyph, but no, I wouldn't recommend |
Nice. I didn't know about this crate. I've actually wanted to write one myself, but fontconfig is an untested mess, so I've ended up writing |
I'm asking, since OrbTK as a pure rust UI toolkit did fully integrate tiny-skia for 2D rendering. It is still lagging a freetype grade solution for text rendering and handling. This is needed to support i.e multiline text blocks. So I'm highly interested in any progress in this front. |
@rzerres it's done (couple of weeks ago). It appears I didn't enable the feature for Do let me know how you get on; I'm open to design changes. It's not FreeType grade; a couple of major omissions are support for embedded objects (e.g. emojis) and scalability to larger texts (possibly by stitching together "paragraphs"; I think some redesign is needed but haven't thought too much about it). Font fallback support is also not complete. |
I've created a Even though |
@notgull Great! I still plan to implement my own text layout library for tiny-skia one day. |
Is there any plan for implementing text rendering in |
Nope. Maybe in a couple of years. |
I've read the thread and as you're very serious about implementing your own text rendering system, I would like you to look at stb_truetype.h. I hope you find it useful. |
|
OK, got it! |
@RazrFalcon |
@RazrFalcon whoops I mixed the libaries 😵💫 |
@RazrFalcon What do you imagine under a I'm currently experimenting with a concept somewhat akin to It's a early Proof of Concept and based on
and ofc any thoughts in general. Thanks 🙌 |
@bennoinbeta Yes, the idea is to extract The main issue with the current Another A yet another Also, the API should provide a way to distinguish between logical and visual indexing. To properly support BIDI text. And so on and so on... It would be nice to have a library like this, but it's an extremely hard task. |
@RazrFalcon No worries, I'll give it a try as I've a bit free time right now (but not the expertise in Rust and especially text layout, shaping, .. so don't expect too much). But learning by doing :) The current iteration offers the following API: let text = String::from("Hello, world!\nשלום עולם!\nThis is a mix of English and Hebrew.");
let attrs_intervals = vec![
AttrsInterval {
start: 0,
stop: 10,
val: Attrs::new()
.font_family(FontFamily::Monospace)
.font_weight(400)
.font_size(24.0),
},
AttrsInterval {
start: 10,
stop: text.len(),
val: Attrs::new()
.font_family(FontFamily::Serif)
.font_weight(400)
.font_size(12.0),
},
];
let mut attributed_string = AttributedString::new(
text,
attrs_intervals,
AttributedStringConfig {
bbox: Vec2::new(100.0, 100.0),
..Default::default()
},
);
// Tokenize the text (String) in logical intervals for further processing
attributed_string.tokenize_text(&mut fonts_cache);
// Apply the layout like linebreaks, letter spacing, ..
attributed_string.layout();
// Create tiny-skia-path
let path = attributed_string.to_path(&mut fonts_cache); Right now, it's early work in progress and mostly a mixture of concepts from Would appreciate your thoughts on the current API and (maybe) implementation as I've no plan what I'm doing and am figuring it out on the go.. Implementation details: Initially the text is divided into spans ( Thanks 🙌 |
@bennoinbeta the attribution is vaguely similar to my How do you plan on handling overlapping ... this is not the right place to discuss this type of detail however. |
@dhardy Yeah probably not the right place @RazrFalcon ?
I'm using self.attrs_intervals.divide_overlaps_with(|overlaps| {
let mut merged_attrs = Attrs::new();
for &attrs in overlaps.iter() {
merged_attrs.merge(attrs.clone());
}
return merged_attrs;
}); For uncovered regions I structured the Thanks for sharing |
@bennoinbeta the |
@bennoinbeta Not being much of an expert here as well, I would try to clarify what
Overall, I appreciate your effort, but I'm not sure I would be able to use it. I'm not even really sure what I want from a AttributedString-like library myself, therefore I cannot judge your implementation either. |
@RazrFalcon Understood, and thanks for the insights :) |
I've just implemented an example demonstrating integration of parley with tiny-skia using skrifa to do scaling and hinting. Emoji rendering is currently missing which is:
|
I've learned to appreciate |
yeah @notgull let it do one thing and do it well |
@rawhuul, It won't hurt adding text support behind a feature flag |
Would this provide a reason to implement? |
No. |
As an update to the last comment here, for those reading today. Fontations is now shipping in Chrome, Rustybuzz has been moved to the Harfbuzz organization and is being migrated to the Fontations stack. Conic and Sweep gradients are still the main thing preventing Fontations users from rendering COLRv1 with tiny-skia. |
No idea. There will be no more commits from me. At least in the near feature. |
Yeah, we're likely to do radial and sweep gradients, since it means we will have a complete software renderer for COLRv1 on Parley/Fontations. Right now the only one we have that does radial and sweep gradients is Vello, but for a variety of reasons Vello is not currently ideal on the CPU. |
Text rendering is not supported and not planned. This is an absurdly complex task and the Rust ecosystem doesn't provide basically any libraries to implement this.
We need:
tiny-skia
that ties it all together.The text was updated successfully, but these errors were encountered: