-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Vectorial text for Canvas
#1610
Conversation
1326cdd
to
f150e2d
Compare
`fill_rectangle` can only be used with axis-aligned rectangles.
let attrs = match text.font { | ||
Font::Default => cosmic_text::Attrs::new(), | ||
Font::External { name, .. } => cosmic_text::Attrs { | ||
family: cosmic_text::Family::Name(name), | ||
..cosmic_text::Attrs::new() | ||
}, | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Has there been thoughts around how to align iced::Font
w/ use of cosmic-text
? Does cosmic-text
support loading fonts from bytes? I'm sure this is already a known regression, but just want to point it out & start a conversation around it:
Font::Default
/Attrs::new
will use the default sans serif font registered w/ thecosmic_text::FontSystem
...Fira Sans
. If not found, uses a system found fallback.Font::External
/cosmic_text::Family::Name(..)
won't use the included font bytes at all, but will see if there is a matching font family for the provided name on the users system, otherwise uses a system found fallback.
I don't see any way currently to load font bytes w/ cosmic-text
or set a default font.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mentioned some ideas in the Discord, but basically we will change the way iced
deals with fonts.
cosmic-text
should be able to add support for loading fonts from bytes by leveraging Database::load_font_data
.
let attrs = match text.font { | ||
Font::Default => cosmic_text::Attrs::new(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Attrs
allows us to specify style & weight, would be cool to see these added to Text
so user can control those attributes as well. I'd imagine Text
is going to need to change in order to support these and other changes, together w/ Font
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Eventually! Currently just focused on improving the text foundations. API should be accommodated later.
// TODO: Raster image support for `Canvas` | ||
let [r, g, b, a] = text.color.into_rgba8(); | ||
|
||
swash_cache.with_pixels( | ||
glyph.cache_key, | ||
cosmic_text::Color::rgba(r, g, b, a), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did some profiling and the bitmap pixels -> lyon tessellation is a huge performance killer. Even on release mode, I'm getting primitive generation times for size 80 text in the 8ms
range. This drops to ~400μs
when removing the emoji.
Maybe we add a disclaimer to the fill_text
docs until there is better support for rastered images w/ transformations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I ported the new example to master
, but it's near impossible compare performance differences between the old / new fill_text
since previously this was GPU rendered text and now it's tessellated by CPU. New changes are exposed in primitive generation
numbers, but previously the impact would be hidden in render
. Both maintain 60fps in release mode.
Obviously the canvas will most likely sit behind a canvas::Cache
and in most workflows, the text is fairly static outside applying transformations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, as I mentioned it's pretty inefficient!
The bitmap support is just a nice to have. For vectorial text, you'll want to deal with fonts that have outline information, so I don't think it's a big deal.
That said, we can probably skip the generic tessellation algorithm and hardcode the triangles ourselves.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, important to note that, once we remove glyph-brush
, we will be able to compose primitives much more efficiently (a new draw call vs a new render pass). We may be able to use the GPU glyph atlas approach for text that isn't transformed for better readability and performance (with proper layering and caching!).
Lots of doors will open once we get that bottleneck out of the way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense!
That said, we can probably skip the generic tessellation algorithm and hardcode the triangles ourselves.
That would be nice. Even though tessellating rectangles should be very cheap, I'd imagine there's still some overhead with lyon
that we can get around building the mesh ourselves.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe it's as cheap as any other path of 4 points, since we are using the generic path algorithm and not fill_rectangle
(which only works with axis-aligned rectangles).
This PR implements vectorial text support for the
Canvas
widget by leveragingcosmic-text
🎉This means that text now is no different than any other kind of geometry in a
Canvas
and, as a result, it can be transformed (translated, rotated, and scaled) and composed (layering!) freely.Also,
cosmic-text
implements both text shaping and font fallback, so aCanvas
should now be able to support different scripts as well.2022-12-20.11-05-30.mp4
The bitmap font support is wonky (and very inefficient), as you can see in the example above. This is just the start of a series of PRs that will improve our text handling and rendering. Further improvements are coming!