linebender / skribo

A Rust library for low-level text layout.
Apache License 2.0
327 stars 35 forks source link

High level goal: render to image #34

Open dakom opened 4 years ago

dakom commented 4 years ago

This is probably not the right place to ask this, but it's got to be one of them :)

I have a high level goal of being able to render to a plain image. No cache, no major performance constraints like fast scrolling windows - just simple text+markup+style -> image

In fact, my need for this is actually on the web, and the reason I need skribo or something similar is because there's no way to do this natively (assuming the user can edit rich text in some widget- i.e. html/css, not canvas text. The svg foreignObject hack doesn't work reliably either).

skribo as wasm would fill in the gaps wonderfully ... would something like this be on the roadmap? Am I barking up the wrong tree? Thanks!

jdm commented 4 years ago

The actual rendering is unlikely to be part of skribo's concerns. It might be simplest to focus on bridging skribo's layout output and raqote's rendering (or some other backend that can render positioned glyphs into an image) in some other crate/app.

RazrFalcon commented 4 years ago

Right now, skribo is just a thin wrapper around harfbuzz. So you can use harfbuzz directly + some good glyph rasterization library like freetype. All of this is C/C++, of course.

raphlinus commented 4 years ago

I agree with Josh that rendering (outside perhaps some very basic functionality for testing) is outside the scope of this crate. We should have good integration points for other renderers, and raqote is probably a very good first choice for that. (A large part of the motivation of this crate is GPU-accelerated renderers such as Pathfinder and piet-gpu).f

The goal of this crate is to provide useful features, including interfacing with system font fallback, and script-guided itemization, not provided by raw harfbuzz. I am disappointed that RazrFalcon did not find it aligned with his goals.

RazrFalcon commented 4 years ago

@raphlinus My problem with skribo is that it doesn't do much on top of harfbuzz. And it heavily relies on system libraries, which is what I'm trying to avoid in resvg at any cost. Pretty successfully actually. Also, resvg text layout has like 4-6 times more code than skribo and supports way more features. On the other hand, I still haven't find a time to dive into font fallback, therefore the current implementation is pretty bad.

raphlinus commented 4 years ago

Right, font fallback is a hard problem. The intent of skribo is to provide a solid solution to these problems, and a clean interface to harfbuzz, for the Rust ecosystem.

The dependence on system libraries is largely through the font-kit dependency. It's to a very large extent motivated by font enumeration and fallback. I do understand the trend to very lean dependencies. People who are value that goal should probably do their own implementations rather than relying on ecosystem crates. I'm also interested in pursuing an approach where the heavier dependencies become optional (feature-gated), so it's more "pay for what you use."

I acknowledge that skribo has a lot of limitations in its current form and does not yet fully realize its vision. I'll be working on that some over the next couple of months or so, as we're now seriously roadmapping text improvements in Druid, and skribo is part of our plan for good Linux support. (On Windows and mac we will likely rely heavily on platform text, but we're still in the process of making those decisions)

RazrFalcon commented 4 years ago

People who are value that goal should probably do their own implementations rather than relying on ecosystem crates.

Yeah, this is basically what I'm doing with ttf-parser, fontdb and rustybuzz. And I've actually plan to write something like skribo on top of this stack.

By the way, this is what resvg text layout is capable off.

I do understand the trend to very lean dependencies.

Actually, the binary size/compilation time is just one of my pain points. The other one is that you cannot write reproducible code using system libraries, because you do not control them. Which was one of the main problems with testing resvg for the past 3 years. And it was "fixed" just yesterday...

And, since we're talking Rust, the other problem is obviously memory issues and overall stability. In bindings and the libraries itself. I've actually wrote the current fontconfig code in font-kit and it was a nightmare to do right. And turns out that fontconfig is slow as hell. For example, a simple fc-match serif takes up to 40ms on my machine, while fontdb does it in 0.003ms. And also, it ignores KDE font settings for some reason, at least for me. Which makes it kinda useless.