Skip to content
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

Unable to load a font and use it in a label (Windows) #1622

Closed
SecondFlight opened this issue Feb 25, 2021 · 6 comments · Fixed by linebender/piet#410 or #1677
Closed

Unable to load a font and use it in a label (Windows) #1622

SecondFlight opened this issue Feb 25, 2021 · 6 comments · Fixed by linebender/piet#410 or #1677
Labels
bug does not behave the way it is supposed to shell/win concerns the Windows backend text
Milestone

Comments

@SecondFlight
Copy link
Collaborator

Tested on Windows 10 with the latest master (3661030).

Repo: https://github.com/SecondFlight/druid-font-repro

image

I include a font (Noto Sans Mono in this case) with

pub const FONT: &[u8] = include_bytes!("NotoSansMono-Regular.ttf");
pub const FONT_KEY: Key<FontDescriptor> = Key::new("fonts.NotoSansMono-Regular");

I then load it into the environment in my parent widget, like so:

fn lifecycle(&mut self, ctx: &mut LifeCycleCtx, event: &LifeCycle, data: &(), env: &Env) {
    if let LifeCycle::WidgetAdded = event {
        let mono_regular_family = ctx.text().load_font(FONT).unwrap();

        self.content = WidgetPod::new(Box::new(Padding::new(3., Child::new()).env_scope(
            move |env, _data| {
                let mono_regular = FontDescriptor::new(mono_regular_family.clone())
                    .with_weight(FontWeight::REGULAR);

                env.set(FONT_KEY, mono_regular.clone());
            },
        )));
    }
    
    // ...
}

Then, in a child widget, I try to use the font:

fn lifecycle(&mut self, ctx: &mut LifeCycleCtx, event: &LifeCycle, data: &(), env: &Env) {
    if let LifeCycle::WidgetAdded = event {
        self.content = WidgetPod::new(Box::new(
            Flex::column()
                .with_child(Label::new("This does have a font").with_font(env.get(FONT_KEY).with_size(15.)))
                .with_spacer(10.)
                .with_child(Label::new("This does not have a font")),
        ));
        ctx.children_changed();
    }

    // ...
}

I expect the first label to have a monospace font, but it has the same font as the second label.

@SecondFlight SecondFlight changed the title Can't load a font and use it in a label (Windows) Unable to load a font and use it in a label (Windows) Feb 25, 2021
@cmyr
Copy link
Member

cmyr commented Feb 25, 2021

@SecondFlight hmm. Maybe try some println'ing down into the logic for resolving that font? In particular take a look at what's going on in TextLayout::rebuild_if_needed, where we call self.font.resolve(env). Does the font we resolve to have the correct family name?

This will be easier to debug if you don't have many text objects active.

@SecondFlight
Copy link
Collaborator Author

SecondFlight commented Feb 26, 2021

It seems to, yes. Thanks for the pointer; by adding a println, I can see that it seems to have the correct family name. Specifically, I've added the following after the descriptor is fetched in TextLayout::rebuild_if_needed:

println!("{:?}", descriptor.family.clone());

This prints the following:

FontFamily(Named("Noto Sans Mono"))

I've also tested this against piet#406 with no change, though I haven't yet tried verifying piet#406 against what it was actually meant to fix.

@SecondFlight
Copy link
Collaborator Author

SecondFlight commented Feb 26, 2021

set_font_family from piet-direct2d/dwrite is getting called as expected. I added these lines to the top of the function:

println!("{}", family);
println!("{:?}", range);

This prints:

Noto Sans Mono
Utf16Range { start: 0, len: 21 }

Gave the same treatment to LoadedFonts::add(). Added this directly before Ok(fam_name):

println!("{:?}", self.names);

Which prints:

[FontFamily(Named("Noto Sans Mono"))]

@SecondFlight
Copy link
Collaborator Author

SecondFlight commented Feb 26, 2021

With my very limited Direct2D knowledge, it does seem like everything is going as expected. The font loads (or at least RegisterFontCollectionLoader gives back S_OK in dwrote). I've confirmed via assert_eq! that IDWriteTextLayout::SetFontFamilyName, called by set_font_family, also returns S_OK.

All the pieces appear to be functioning and in play in this example. The Direct2D samples include some custom fonts and they work, so it's not like piet-direct2d can't render custom fonts, but it sure seems like piet-direct2d is handwaving and not actually changing the font. I'm not sure where the missing piece is here.

@cmyr
Copy link
Member

cmyr commented Feb 26, 2021

It would be nice to know if this is a problem somewhere in piet, or if it's a problem somewhere in druid.

For instance: it's possible that in druid we're loading this font into a particular Text object, but then using a different Text object when we build the layout, and not having the font available there?

What I would check here is in D2DTextLayoutBuilder::add_attribute_shared: when adding this attribute, are we correctly identifying it as a custom font?

@SecondFlight
Copy link
Collaborator Author

SecondFlight commented Mar 2, 2021

The test case does not fail on macOS (see below). I'm hoping this is evidence that the issue is in piet-driect2d, not druid. I'll poke around more soon.

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug does not behave the way it is supposed to shell/win concerns the Windows backend text
Projects
None yet
2 participants