dfrg / swash Goto Github PK
View Code? Open in Web Editor NEWFont introspection, complex text shaping and glyph rendering.
License: Apache License 2.0
Font introspection, complex text shaping and glyph rendering.
License: Apache License 2.0
The subpixel format is described as "32-bit RGBA subpixel mask with 1/3 pixel offsets for the red and blue channels."
Could you elaborate on what 1/3 pixel offset means in this case? I'm not quite sure how to actually apply the subpixel mask to render text in a given color from looking at the docs (though I may have missed something obvious).
I would like to be able to cache glyphs in a font atlas at startup. The issue that I am running into is that ligature glyph IDs and other substitutions are not included in the charmap, so those characters would need to cached lazily during shaping because I cannot enumerate them upfront. Is there an easy way to enumerate the contents of the GLYF and CFF tables instead? It seems that the parsers for them are well-established but only set up to access entries by glyph ID on demand.
As a side note, navigating this codebase over the last few hours to see if I could do it myself has given me a new appreciation for how complex font handling is ๐. Hats off to you.
It would be useful to have a minimal example of shaping some text or similar functionality. This way somebody could bootstrap themselves easier when they find the library.
Side note: incredible work. I've been waiting for a library like this for ages. Between this and rustybuzz, things are looking up.
This may very well be out of scope for the library.
I'm very interested in swash as a font parsing engine for https://github.com/Kethku/neovide which is a gui for Neovim written in rust. It uses skia for rendering, but the built in harfbuzz bindings in skia leave much to be desired. Effectively Neovide is just a fancy terminal renderer which draws characters in a grid. However we use harfbuzz to select which glyphs to render for the text. This lets us combine certain glyphs into ligatures.
Currently we rely on harfbuzz to also position the glyphs, but this leads to grid positioning problems and I would like to eventually position the glyphs myself based on user config and some basic heuristics that assume fonts are monospace. The problems occur when font fallback produces a font which has different spacing from the font used to align the grid. So you get misaligned text. However if I position glyphs manually, this problem goes away.
So what would be awesome is a way to just use the glyph selection portion of the shaper rather than going through the entire shaping process. I'm not interested in the glyph positions because I'm going to place the glyphs myself on the monospace grid. I'm only interested in when a substitution is made which turns 1 or more glyphs into a single ligature, or similar such swaps. I'm not familiar with all of the types of substitutions that can be made, but I'm wondering if such a thing would be possible.
I've looked into doing this with harfbuzz, and I think it would also be possible to do it with it, but to my knowledge it would require using the clustering mechanism which I find VERY confusing. Maybe this use case could be better covered in swash? No biggy if not, just figured I'd ask.
As an aside, I would LOVE to get rid of the skia dependency all together as building it is hard and being pure rust would be badass. I've looked at pathfinder before, but was confused by the various levels at which I could integrate and eventually just went with skia as the easier thing to get myself up and running faster. You mention pathfinder in the readme as a possible renderer for swash's output. Have you done such a thing? Is there an example of such an integration? I'd be interested
If I use skia + swash, would these possible?
The JetBrains Mono font does have that glyph present (which I inspected using the BirdFont font inspector), I suspect that some glyph resolution code is might be wrong somewhere, but I don't know which (trust me I tried).
I built the swash_demo from source using the following code for build_document
fn build_document() -> doc::Document {
use layout::*;
let mut db = doc::Document::builder();
use SpanStyle as S;
let underline = &[
S::Underline(true),
S::UnderlineOffset(Some(-1.)),
S::UnderlineSize(Some(1.)),
];
db.enter_span(&[S::family_list("JetBrains Mono"), S::Size(22.)]);
db.add_text("๐ฎ");
db.leave_span();
db.build()
}
Would be grateful if you could provide some pointers on where should I be looking for what, thanks!
Implement support for parsing version 1 of the COLR table and expose the additional data in the outline API.
I see that this crate uses its own code for TTF parsing. Is there a reason why ttf-parser
isn't used here? It has no dependencies and is written in exclusively safe code.
The hinter currently doesn't allocate so this may require some restructuring.
See https://gitlab.freedesktop.org/freetype/freetype/-/merge_requests/23
Repro case
It looks like both of these render partially (I haven't tried many more, however ๐ฅ from the documentation seems to render correctly). The robot-man seems to have his mouth cut off, and the log seems to have the top cut off.
Since this is my very first time diving into this library, I may well be doing something wrong. I've attached the repro of what I'm trying to do.
I've also attached the rendered image below;
use swash::scale::ScaleContext;
use swash::scale::StrikeWith;
use swash::scale::*;
use zeno::Vector;
fn main() {
use swash::FontRef;
let font_path = "C:/Windows/Fonts/seguiemj.ttf";
let font_data = std::fs::read(font_path).ok().unwrap();
let font = FontRef::from_index(&font_data, 0).unwrap();
let mut context = ScaleContext::new();
let mut scaler = context.builder(font).hint(true).build();
let glyph_id = font.charmap().map('๐ค');
let image = Render::new(&[
Source::ColorBitmap(StrikeWith::ExactSize),
Source::ColorOutline(1),
Source::Outline,
])
.format(zeno::Format::Subpixel)
.offset(Vector::new(0.0, 0.0))
.render(&mut scaler, glyph_id)
.unwrap();
dbg!(image.placement);
let img =
::image::RgbaImage::from_raw(image.placement.width, image.placement.height, image.data)
.unwrap();
img.save_with_format("stuff.png", ::image::ImageFormat::Png);
}
just a heads up On nightly 4-1-2023
rust-lang/rust@22a7a19
is causing issues in swash in debug mode
all newer nightlys will have the same issue. I am unsure if i should Report it here to fix the alignment issue or to rust lang....
the error occurs here due to the new alignment check.
https://github.com/dfrg/swash/blob/master/src/internal/parse.rs#L452
This entails extending the basic alpha compositor to support additional modes and affine transformations.
Will this library ever add no_std
support?
I ask because it's not in the Non Goals section of the README, yet it does not appear to have any allocations or use any features from libstd.
The comment at the top says that it is automatically generated, but I can't find what code generated it.
I am trying to match on the whitespace enum, but it appears that parsing any kind of tab (unicode, control, etc) doesn't appear to match the Whitespace::Tab
variant.
let font_size = 16.;
let mut shape_context = ShapeContext::new();
let mut shaper = shape_context
.builder(*font_ref)
.script(Script::Latin)
.size(font_size)
.direction(Direction::LeftToRight)
.build();
// 4 variants of how to input a `tab`
shaper.add_str("\t\u{0009} \u{2B7E}");
shaper.shape_with(|glyph_cluster| {
let info = glyph_cluster.info;
println!("got INFO: '{:?}'", info.0);
println!("got whitespace: '{:?}'", info.whitespace());
});
got INFO: '0'
got whitespace: 'None'
got INFO: '0'
got whitespace: 'None'
got INFO: '0'
got whitespace: 'None'
got INFO: '0'
got whitespace: 'None'
got INFO: '7'
got whitespace: 'Tab'
got INFO: '7'
got whitespace: 'Tab'
got INFO: '7'
got whitespace: 'Tab'
got INFO: '7'
got whitespace: 'Tab'
I am using the Roboto-Regular.ttf
font.
The text analysis code including segmentation, cluster parsing and Unicode properties is not font dependent and should be moved to a new crate. The cluster model also needs to be updated to accommodate additional Indic scripts (specifically those with multiple pre-base forms).
I think there is a bug in 0.1.10:
error[E0446]: crate-private type `Outlines<'_>` in public interface
--> ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/swash-0.1.10/src/scale/cff/mod.rs:24:5
|
24 | / pub fn scale(
25 | | &mut self,
26 | | outlines: &outlines::Outlines,
27 | | id: u64,
... |
32 | | outline: &mut Outline,
33 | | ) -> Option<()> {
| |___________________^ can't leak crate-private type
|
::: ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/swash-0.1.10/src/scale/cff/outlines.rs:39:1
|
39 | pub(crate) struct Outlines<'a> {
| ------------------------------ `Outlines<'_>` declared as crate-private
Outlines
should be pub
I guess instead of pub(crate)
.
https://github.com/be5invis/Iosevka
Looks like something about the way iosevka renders ligatures doesn't play well with swash
Hello,
I am playing with swash (and Harfbuzz too), sometimes I try to experience with algorithms and source code. However, I cannot sure whether it works for all font/script except for my limited testcases.
Does swash have testcases, test data already?
Thanks,
This is largely because I am unfamiliar with shaping, but I'm also not that skilled in programming yet either. So, I was wondering how you achieved zero transient heap allocations. At least to me, it seems like it would cause a stack overflow if you had to shape a large amount of text. You mention a cache, but I'm still pretty confused. How does the cache work without transiently allocating to the heap?
In Neovide we determine the grid size by looking at the average glyph width and assuming that for monospace fonts, that will give us a reasonable size for a character grid.
However in your recent change, that average width has increased. Plus I think thats actually a bad metric to use because some fonts have a few very wide glyphs, so it would be incorrect to use the average glyph width.
I'm wondering if you have a better recommendation for what metric to look at. I've seen some systems pick an arbitrary character such as capital X and assume that it is representative. I've also attempted in the past to actually shape a representative piece of text and measure the spacing used there are the ground truth for the entire grid.
To be honest I don't know what the "Correct" solution is. Does swash have any metric that would work well for this use case?
To be able to render composite glyphs that uses this technique.
For reference the implementations in freetype2 and ttf-parser.
I am having an issue using swash with WebRender glyph rasterizer. The swash-demo works just fine. So I guess it's that webrender using different gl shader when rendering font glyphs.
Without any changes to swash this is output of emojis using wr_glyph_rasterizer
This is increasingly important for digital typography so we want to support it throughout the stack.
The documentation of the text::cluster::Token
module does not explain what a code unit is. From the example code in the shape
module it seems that the offset
property is index of the character in the text and len
its length when represented as UTF8, but is it?
In my code I don't use UTF8 strings because I have extra information and I keep an array of "chars" like this:
(char 'A') (char 'B')(kern -0.5pt)(char '๐')
I suppose this is three tokens but what values for offset
and len
should one use?
offset: 0 len: 'A'.len_utf8()
offset: 1 len: 'B'.len_utf8()
offset: 2 len: '๐'.len_utf8()
Should the offset of the third token be 2 (logical index into the characters) or 3 (index into my array)?
You briefly mentioned this on the Reddit announcement:
Correctness is... tricky. I would like to run it against the Harfbuzz test suite, but I will have to account for differences in output both with respect to cluster numbering and how Harfbuzz distributes some positioning information differently between offsets and advances. Still, this is an area that needs attention.
I'm admittedly unqualified to understand why it's difficult to integrate the HarfBuzz test suite like rustybuzz did, but how immediate is it on your TODO list?
I'm trying to use swash for font rasterisation in Lapce. The subpixel works great. But I do have a weird issue that some fonts are rasterised very small. The font file I've got issue with is this https://github.com/lapce/piet-wgpu/blob/master/fonts/CascadiaCode-Regular.otf
I experienced this crash after upgrading rustc
to 1.70.0, and I cannot reproduce it using rustc
1.69.0. The crash happens in an iced
application (with a dependency on swash
0.1.6).
The full crash log is attached here for your information. It seems there is something wrong about the font parsing process. I tested the application in Windows Sandbox (which comes with only the fonts that Microsoft ships with Windows), so the issue should not be about the custom fonts I installed.
thread 'main' panicked at 'misaligned pointer dereference: address must be a multiple of 0x2 but is 0x25ace2382a5', $HOME\.cargo\registry\src\mirrors.tuna.tsinghua.edu.cn-df7c3c540f42cdbd\swash-0.1.6\src\internal\parse.rs:452:13
stack backtrace:
0: std::panicking::begin_panic_handler
at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library\std\src\panicking.rs:578
1: core::panicking::panic_fmt
at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library\core\src\panicking.rs:67
2: core::panicking::panic_misaligned_pointer_dereference
at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library\core\src\panicking.rs:174
3: swash::internal::parse::impl$9::from_be_data_unchecked
at $HOME\.cargo\registry\src\mirrors.tuna.tsinghua.edu.cn-df7c3c540f42cdbd\swash-0.1.6\src\internal\parse.rs:452
4: swash::internal::parse::FromBeData::from_be_data
at $HOME\.cargo\registry\src\mirrors.tuna.tsinghua.edu.cn-df7c3c540f42cdbd\swash-0.1.6\src\internal\parse.rs:424
5: swash::internal::parse::Bytes::read
at $HOME\.cargo\registry\src\mirrors.tuna.tsinghua.edu.cn-df7c3c540f42cdbd\swash-0.1.6\src\internal\parse.rs:55
6: swash::scale::cff::cff::IndexMetadata::unpack
at $HOME\.cargo\registry\src\mirrors.tuna.tsinghua.edu.cn-df7c3c540f42cdbd\swash-0.1.6\src\scale\cff\cff.rs:1191
7: swash::scale::cff::cff::Index::new
at $HOME\.cargo\registry\src\mirrors.tuna.tsinghua.edu.cn-df7c3c540f42cdbd\swash-0.1.6\src\scale\cff\cff.rs:1226
8: swash::scale::cff::cff::CffProxy::parse
at $HOME\.cargo\registry\src\mirrors.tuna.tsinghua.edu.cn-df7c3c540f42cdbd\swash-0.1.6\src\scale\cff\cff.rs:92
9: swash::scale::cff::cff::CffProxy::from_font
at $HOME\.cargo\registry\src\mirrors.tuna.tsinghua.edu.cn-df7c3c540f42cdbd\swash-0.1.6\src\scale\cff\cff.rs:54
10: swash::scale::proxy::ScalerProxy::from_font
at $HOME\.cargo\registry\src\mirrors.tuna.tsinghua.edu.cn-df7c3c540f42cdbd\swash-0.1.6\src\scale\proxy.rs:28
11: swash::scale::impl$3::new::closure$0<swash::font::FontRef>
at $HOME\.cargo\registry\src\mirrors.tuna.tsinghua.edu.cn-df7c3c540f42cdbd\swash-0.1.6\src\scale\mod.rs:351
12: swash::cache::FontCache<swash::scale::proxy::ScalerProxy>::get<swash::scale::proxy::ScalerProxy,swash::scale::impl$3::new::closure_env$0<swash::font::FontRef> >
at $HOME\.cargo\registry\src\mirrors.tuna.tsinghua.edu.cn-df7c3c540f42cdbd\swash-0.1.6\src\cache.rs:50
13: swash::scale::ScalerBuilder::new<swash::font::FontRef>
at $HOME\.cargo\registry\src\mirrors.tuna.tsinghua.edu.cn-df7c3c540f42cdbd\swash-0.1.6\src\scale\mod.rs:349
14: swash::scale::ScaleContext::builder<swash::font::FontRef>
at $HOME\.cargo\registry\src\mirrors.tuna.tsinghua.edu.cn-df7c3c540f42cdbd\swash-0.1.6\src\scale\mod.rs:325
15: cosmic_text::swash::swash_image
at $HOME\.cargo\git\checkouts\cosmic-text-ea4fb601986df06b\b85d6a4\src\swash.rs:32
16: cosmic_text::swash::SwashCache::get_image_uncached
at $HOME\.cargo\git\checkouts\cosmic-text-ea4fb601986df06b\b85d6a4\src\swash.rs:115
17: glyphon::text_render::TextRenderer::prepare_with_depth<core::iter::adapters::filter_map::FilterMap<core::iter::adapters::zip::Zip<core::slice::iter::Iter<iced_wgpu::layer::text::Text>,core::slice::iter::Iter<u64> >,iced_wgpu::text::impl$0::prepare::closur
at $HOME\.cargo\git\checkouts\glyphon-70ff9ac92aaa9d8a\f145067\src\text_render.rs:103
18: glyphon::text_render::TextRenderer::prepare<core::iter::adapters::filter_map::FilterMap<core::iter::adapters::zip::Zip<core::slice::iter::Iter<iced_wgpu::layer::text::Text>,core::slice::iter::Iter<u64> >,iced_wgpu::text::impl$0::prepare::closure_env$1> >
at $HOME\.cargo\git\checkouts\glyphon-70ff9ac92aaa9d8a\f145067\src\text_render.rs:347
19: iced_wgpu::text::Pipeline::prepare
at $HOME\.cargo\git\checkouts\iced-f01cba4d5e61fd0a\fcb1b45\wgpu\src\text.rs:170
20: iced_wgpu::backend::Backend::prepare_text
at $HOME\.cargo\git\checkouts\iced-f01cba4d5e61fd0a\fcb1b45\wgpu\src\backend.rs:141
21: iced_wgpu::backend::Backend::present<alloc::string::String>
at $HOME\.cargo\git\checkouts\iced-f01cba4d5e61fd0a\fcb1b45\wgpu\src\backend.rs:99
22: iced_wgpu::window::compositor::present<enum2$<iced_style::theme::Theme>,alloc::string::String>
at $HOME\.cargo\git\checkouts\iced-f01cba4d5e61fd0a\fcb1b45\wgpu\src\window\compositor.rs:172
23: iced_renderer::compositor::impl$0::present::closure$0<enum2$<iced_style::theme::Theme>,alloc::string::String>
at $HOME\.cargo\git\checkouts\iced-f01cba4d5e61fd0a\fcb1b45\renderer\src\compositor.rs:122
24: iced_graphics::renderer::Renderer<enum2$<iced_renderer::backend::Backend>,enum2$<iced_style::theme::Theme> >::with_primitives<enum2$<iced_renderer::backend::Backend>,enum2$<iced_style::theme::Theme>,enum2$<core::result::Result<tuple$<>,iced_graphics::comp
at $HOME\.cargo\git\checkouts\iced-f01cba4d5e61fd0a\fcb1b45\graphics\src\renderer.rs:51
25: iced_renderer::compositor::impl$0::present<enum2$<iced_style::theme::Theme>,alloc::string::String>
at $HOME\.cargo\git\checkouts\iced-f01cba4d5e61fd0a\fcb1b45\renderer\src\compositor.rs:103
26: iced_winit::application::run_instance::async_fn$0<iced::application::Instance<bin_data_inspector::App>,iced_futures::backend::null::Executor,enum2$<iced_renderer::compositor::Compositor<enum2$<iced_style::theme::Theme> > > >
at $HOME\.cargo\git\checkouts\iced-f01cba4d5e61fd0a\fcb1b45\winit\src\application.rs:532
27: iced_winit::application::run::closure$1<iced::application::Instance<bin_data_inspector::App>,iced_futures::backend::null::Executor,enum2$<iced_renderer::compositor::Compositor<enum2$<iced_style::theme::Theme> > > >
at $HOME\.cargo\git\checkouts\iced-f01cba4d5e61fd0a\fcb1b45\winit\src\application.rs:251
28: winit::platform_impl::platform::event_loop::impl$3::run_return::closure$0<tuple$<>,iced_winit::application::run::closure_env$1<iced::application::Instance<bin_data_inspector::App>,iced_futures::backend::null::Executor,enum2$<iced_renderer::compositor::Com
at $HOME\.cargo\git\checkouts\winit-57d3141eaf559308\ac1ddfe\src\platform_impl\windows\event_loop.rs:260
29: alloc::boxed::impl$46::call_mut<tuple$<enum2$<winit::event::Event<tuple$<> > >,ref_mut$<enum2$<winit::event_loop::ControlFlow> > >,dyn$<core::ops::function::FnMut<tuple$<enum2$<winit::event::Event<tuple$<> > >,ref_mut$<enum2$<winit::event_loop::ControlFlo
at /rustc/90c541806f23a127002de5b4038be731ba1458ca\library\alloc\src\boxed.rs:1980
30: winit::platform_impl::platform::event_loop::runner::impl$3::call_event_handler::closure$0<tuple$<> >
at $HOME\.cargo\git\checkouts\winit-57d3141eaf559308\ac1ddfe\src\platform_impl\windows\event_loop\runner.rs:250
31: core::panic::unwind_safe::impl$23::call_once<tuple$<>,winit::platform_impl::platform::event_loop::runner::impl$3::call_event_handler::closure_env$0<tuple$<> > >
at /rustc/90c541806f23a127002de5b4038be731ba1458ca\library\core\src\panic\unwind_safe.rs:271
32: std::panicking::try::do_call<core::panic::unwind_safe::AssertUnwindSafe<winit::platform_impl::platform::event_loop::runner::impl$3::call_event_handler::closure_env$0<tuple$<> > >,tuple$<> >
at /rustc/90c541806f23a127002de5b4038be731ba1458ca\library\std\src\panicking.rs:485
33: winit::platform_impl::platform::icon::impl$8::clone
34: std::panicking::try<tuple$<>,core::panic::unwind_safe::AssertUnwindSafe<winit::platform_impl::platform::event_loop::runner::impl$3::call_event_handler::closure_env$0<tuple$<> > > >
at /rustc/90c541806f23a127002de5b4038be731ba1458ca\library\std\src\panicking.rs:449
35: std::panic::catch_unwind<core::panic::unwind_safe::AssertUnwindSafe<winit::platform_impl::platform::event_loop::runner::impl$3::call_event_handler::closure_env$0<tuple$<> > >,tuple$<> >
at /rustc/90c541806f23a127002de5b4038be731ba1458ca\library\std\src\panic.rs:140
36: winit::platform_impl::platform::event_loop::runner::EventLoopRunner<tuple$<> >::catch_unwind<tuple$<>,tuple$<>,winit::platform_impl::platform::event_loop::runner::impl$3::call_event_handler::closure_env$0<tuple$<> > >
at $HOME\.cargo\git\checkouts\winit-57d3141eaf559308\ac1ddfe\src\platform_impl\windows\event_loop\runner.rs:157
37: winit::platform_impl::platform::event_loop::runner::EventLoopRunner<tuple$<> >::call_event_handler<tuple$<> >
at $HOME\.cargo\git\checkouts\winit-57d3141eaf559308\ac1ddfe\src\platform_impl\windows\event_loop\runner.rs:242
38: winit::platform_impl::platform::event_loop::runner::EventLoopRunner<tuple$<> >::send_event<tuple$<> >
at $HOME\.cargo\git\checkouts\winit-57d3141eaf559308\ac1ddfe\src\platform_impl\windows\event_loop\runner.rs:215
39: winit::platform_impl::platform::event_loop::WindowData<tuple$<> >::send_event<tuple$<> >
at $HOME\.cargo\git\checkouts\winit-57d3141eaf559308\ac1ddfe\src\platform_impl\windows\event_loop.rs:142
40: winit::platform_impl::platform::event_loop::public_window_callback_inner::closure$0<tuple$<> >
at $HOME\.cargo\git\checkouts\winit-57d3141eaf559308\ac1ddfe\src\platform_impl\windows\event_loop.rs:1125
41: core::ops::function::FnOnce::call_once<winit::platform_impl::platform::event_loop::public_window_callback_inner::closure_env$0<tuple$<> >,tuple$<> >
at /rustc/90c541806f23a127002de5b4038be731ba1458ca\library\core\src\ops\function.rs:250
42: core::panic::unwind_safe::impl$23::call_once<isize,winit::platform_impl::platform::event_loop::public_window_callback_inner::closure_env$0<tuple$<> > >
at /rustc/90c541806f23a127002de5b4038be731ba1458ca\library\core\src\panic\unwind_safe.rs:271
43: std::panicking::try::do_call<core::panic::unwind_safe::AssertUnwindSafe<winit::platform_impl::platform::event_loop::public_window_callback_inner::closure_env$0<tuple$<> > >,isize>
at /rustc/90c541806f23a127002de5b4038be731ba1458ca\library\std\src\panicking.rs:485
44: std::panicking::try::do_catch<core::panic::unwind_safe::AssertUnwindSafe<winit::platform_impl::platform::window::impl$4::on_nccreate::closure_env$0<tuple$<> > >,tuple$<winit::platform_impl::platform::window::Window,winit::platform_impl::platform::event_lo
45: std::panicking::try<isize,core::panic::unwind_safe::AssertUnwindSafe<winit::platform_impl::platform::event_loop::public_window_callback_inner::closure_env$0<tuple$<> > > >
at /rustc/90c541806f23a127002de5b4038be731ba1458ca\library\std\src\panicking.rs:449
46: std::panic::catch_unwind<core::panic::unwind_safe::AssertUnwindSafe<winit::platform_impl::platform::event_loop::public_window_callback_inner::closure_env$0<tuple$<> > >,isize>
at /rustc/90c541806f23a127002de5b4038be731ba1458ca\library\std\src\panic.rs:140
47: winit::platform_impl::platform::event_loop::runner::EventLoopRunner<tuple$<> >::catch_unwind<tuple$<>,isize,winit::platform_impl::platform::event_loop::public_window_callback_inner::closure_env$0<tuple$<> > >
at $HOME\.cargo\git\checkouts\winit-57d3141eaf559308\ac1ddfe\src\platform_impl\windows\event_loop\runner.rs:157
48: winit::platform_impl::platform::event_loop::public_window_callback_inner<tuple$<> >
at $HOME\.cargo\git\checkouts\winit-57d3141eaf559308\ac1ddfe\src\platform_impl\windows\event_loop.rs:2320
49: winit::platform_impl::platform::event_loop::public_window_callback<tuple$<> >
at $HOME\.cargo\git\checkouts\winit-57d3141eaf559308\ac1ddfe\src\platform_impl\windows\event_loop.rs:994
50: DispatchMessageW
51: DispatchMessageW
52: GetClassLongW
53: KiUserCallbackDispatcher
54: NtUserDispatchMessage
55: DispatchMessageW
56: winit::platform_impl::platform::event_loop::EventLoop<tuple$<> >::run_return<tuple$<>,iced_winit::application::run::closure_env$1<iced::application::Instance<bin_data_inspector::App>,iced_futures::backend::null::Executor,enum2$<iced_renderer::compositor::
at $HOME\.cargo\git\checkouts\winit-57d3141eaf559308\ac1ddfe\src\platform_impl\windows\event_loop.rs:282
57: winit::platform::run_return::impl$0::run_return<tuple$<>,iced_winit::application::run::closure_env$1<iced::application::Instance<bin_data_inspector::App>,iced_futures::backend::null::Executor,enum2$<iced_renderer::compositor::Compositor<enum2$<iced_style:
at $HOME\.cargo\git\checkouts\winit-57d3141eaf559308\ac1ddfe\src\platform\run_return.rs:51
58: iced_winit::application::platform::run<tuple$<>,iced_winit::application::run::closure_env$1<iced::application::Instance<bin_data_inspector::App>,iced_futures::backend::null::Executor,enum2$<iced_renderer::compositor::Compositor<enum2$<iced_style::theme::T
at $HOME\.cargo\git\checkouts\iced-f01cba4d5e61fd0a\fcb1b45\winit\src\application.rs:887
59: iced_winit::application::run<iced::application::Instance<bin_data_inspector::App>,iced_futures::backend::null::Executor,enum2$<iced_renderer::compositor::Compositor<enum2$<iced_style::theme::Theme> > > >
at $HOME\.cargo\git\checkouts\iced-f01cba4d5e61fd0a\fcb1b45\winit\src\application.rs:226
60: iced::application::Application::run<bin_data_inspector::App>
at $HOME\.cargo\git\checkouts\iced-f01cba4d5e61fd0a\fcb1b45\src\application.rs:208
61: iced::sandbox::Sandbox::run<bin_data_inspector::App>
at $HOME\.cargo\git\checkouts\iced-f01cba4d5e61fd0a\fcb1b45\src\sandbox.rs:153
The crash can be consistently reproduced on my PC with the following simple program:
use iced::{Element, Sandbox, Settings};
use iced::widget::TextInput;
struct App;
impl Sandbox for App {
type Message = ();
fn new() -> Self { App }
fn title(&self) -> String { "Swash Crash".to_string() }
fn update(&mut self, _message: Self::Message) {}
fn view(&self) -> Element<'_, Self::Message> {
TextInput::new("Placeholder", "Value").into()
}
}
fn main() -> iced::Result { App::run(Settings::default()) }
with the following in Cargo.toml
configuration (to use iced
master):
[dependencies.iced]
git = "https://github.com/iced-rs/iced.git"
rev = "fcb1b454368638209862aeb5db41bc5f7d6d51a7"
I have already filed iced-rs/iced#1905, but I feel that this is more related to swash
, so I also file a copy here.
Hi I'm looking at how ligatures work in the AAT morx table and I note that in fontkit it pushes the ligature glyphs back onto the stack after generating them:
This is necessary for the Zapfino font, where the "ffi" ligature is implemented by first generating an "ff" ligature and then using that followed by the "i" to generate the "ffi" ligature, however the second ligature action won't work unless the "ff" is on the stack.
It doesn't seem that swash does this at the moment, although I haven't been able to test it with the Zapfino font yet, is there a simple shaping test program I could try?
Hey!
The font Exposure from 205TF renders incorrectly with certain settings. The EXPO axis range is [-100, 100]. On swash version 0.1.12 it did not render any change on values > 0, but this seems to have been fixed between 0.1.12 and 0.1.17!
However, the issue I'm seeing now is that it renders incorrectly when the variation makes the paths cross each other. If that makes sense.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.