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

API paper-cuts when using the library in a non-gui context #324

Open
vbfox opened this issue Oct 28, 2024 · 0 comments
Open

API paper-cuts when using the library in a non-gui context #324

vbfox opened this issue Oct 28, 2024 · 0 comments

Comments

@vbfox
Copy link

vbfox commented Oct 28, 2024

This issue follow a discussion on Mastodon at https://hachyderm.io/@vbfox/113384209703350917 with @jackpot51

I'm writting a small StreamDeck plugin for monitoring CPU/RAM usage mostly to play a bit with Rust. My needs are really far from a full text editor, and I encountered a few missing features, cases where the API could accomodate my usecase a bit more or missing features.

I'm generally needing a single line of text, with a size chosen so that not wrapping happen. Or a few lines for information/error messages, displayed over an already rendered image

image

  • FontSystem::new_with_fonts is a bit misleading as it doesn't only load the fonts passed in, but same as FontSystem::new actually scan the whole system font folders, neither having this specified in doc comments. Loading a single font is still possible but require building a database first:

    let font_source = Source::Binary(Arc::new(include_bytes!("Roboto-Bold.ttf")));
    let mut font_db = Database::new();
    font_db.load_font_source(font_source);
    
    let font_system = FontSystem::new_with_locale_and_db(String::from("en-US"), font_db);

    I think the easiest here would have been to have a FontSystem::new_empty() + FontSystem::add_font or a FontSystem::new_with_fonts_only

  • Targeting a specific font loaded either need out-of code knowledge or need some manual access to the database:

    let font_ids = font_db.load_font_source(font_source);
    let font = font_db.face(font_ids[0]);
    let roboto_family = font.unwrap().families[0].0.clone();
    
    // Later
    
    let attrs = Attrs::new();
    attrs.family(Family::Name(roboto_family));
    attrs.weight(Weight::BOLD);

    I don't know how common it is to get a single ttf load multiple families but maybe that kind of API mix could work:

    let font_system: FontSystem = FontSystem::empty_with_locale("en-US");
    let font = font_system.add(font_source);
    
    // Later
    
    let attrs = Attrs::from(font);
  • I didn't find how to center text horizontally so I ended up doing it myself. It seem to be currently possible iterating over BufferLine after adding text and calling set_align on them but it's pretty hidden. Feel fixed by Add alignment option to Buffer::set_rich_text #304 (But I was using the crate.io release)

  • Same in the other direction, I did vertical alignment by hand but Support vertical alignment #79 would be nice to have.

  • Speaking of alignment I couldn't find a good way to get the text size. Getting bounding box of text after layout #205 is marked as closed but I couldn't find the API and for now did it like that:

    let (width, total_lines) = buffer
    .layout_runs()
    .fold((0.0, 0usize), |(width, total_lines), run| {
        (run.line_w.max(width), total_lines + 1)
    });
    let height = total_lines as f32 * buffer.metrics().line_height;

    (A bit of an overkill for my current usage as I have a single layout run anyway)

    Ideally I would like to have a way to find the layout box (Where the lines should go) and also the box where pixels will really be drawn (for each line or total). I'm sure swash has it somewhere but I didn't hunt for it.
    For example I might want to center the pixels here, not the (red) layout box:
    image

  • The color passed in Attrs or the default one passed to draw (Btw why not have it as a field in Buffer?) isn't blended (but there is a comment about that in the code). Surprising, but very easy to fix for my case by doing manual blending as I only have a single color, but it wouldn't work if I had multiple rich text spans with different alpha.

  • The api for shaping is a bit confusing when you don't use the full capacity. For example, what does shape_until_scroll do when my buffer isn't sized ? What is the prune parameter to this method ( The prune parameter to shape_until_scroll is not documented #232 ) ? It might be a need for a more general doc comment somewhere of the design assumptions of the layouting and scrolling system and how to use them.

  • For performance reasons, I wasn't expecting the fn passed to Buffer::draw to be called with 100% transparent pixels

  • On that subject an (optional) integration with the image-rs/image crate would be very nice as it could use faster drawing methods directly.

Here it is, lots of nitpicks but in I was able to do everything I wanted so great job with the lib 👍🏼.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant