cosmic-text icon indicating copy to clipboard operation
cosmic-text copied to clipboard

Emoji rendering with NotoColorEmoji yields an empty image

Open bschwind opened this issue 1 year ago • 2 comments

I might be doing something wrong or naive here, but here's a minimal example:

# Cargo.toml
[package]
name = "cosmic-text-test"
version = "0.1.0"
edition = "2021"

[dependencies]
cosmic-text = "0.12"
fontdb = "0.16"
sys-locale = "0.3"
// src/main.rs
use cosmic_text::{Attrs, Buffer, FontSystem, Metrics, Shaping, SwashCache};
use fontdb::Database;
use std::sync::Arc;

fn main() {
    // Create a custom FontSystem with only an emoji font.
    let emoji_font = Arc::new(include_bytes!("../fonts/NotoColorEmoji-Regular.ttf"));

    let mut font_db = Database::new();
    font_db.load_font_source(fontdb::Source::Binary(emoji_font));

    let locale = sys_locale::get_locale().unwrap_or_else(|| "en-US".to_string());
    let mut font_system = FontSystem::new_with_locale_and_db(locale, font_db);
    let mut swash_cache = SwashCache::new();

    // Shape a buffer
    let mut buffer = Buffer::new_empty(Metrics::relative(32.0, 1.0));
    buffer.set_size(&mut font_system, Some(3000.0), Some(3000.0));

    let default_attrs = Attrs::new();

    buffer.set_text(&mut font_system, "😂", default_attrs, Shaping::Advanced);

    let prune = true;
    buffer.shape_until_scroll(&mut font_system, prune);

    let x = 0.0;
    let y = 0.0;
    let scale = 1.0;

    // Iterate over glyphs
    for run in buffer.layout_runs() {
        dbg!(run.text);

        for glyph in run.glyphs.iter() {
            let physical_glyph = glyph.physical((x, y), scale);
            dbg!(&physical_glyph.cache_key);

            let Some(image) =
                swash_cache.get_image_uncached(&mut font_system, physical_glyph.cache_key)
            else {
                println!("No rasterization needed?");
                continue;
            };

            dbg!(image.source);
            dbg!(image.content);
            dbg!(image.placement);
            dbg!(image.data.len());
        }
    }
}
$ cargo run --release
   Compiling cosmic-text-test v0.1.0 (/Users/brian/projects/cosmic-text-test/cosmic-text-test)
    Finished `release` profile [optimized] target(s) in 1.64s
     Running `target/release/cosmic-text-test`
[src/main.rs:33:9] run.text = "😂"
[src/main.rs:37:13] &physical_glyph.cache_key = CacheKey {
    font_id: ID(
        InnerId(
            1v1,
        ),
    ),
    glyph_id: 2285,
    font_size_bits: 1107296256,
    x_bin: Zero,
    y_bin: Zero,
    flags: CacheKeyFlags(
        0x0,
    ),
}
[src/main.rs:46:13] image.source = Outline
[src/main.rs:47:13] image.content = Mask
[src/main.rs:48:13] image.placement = Placement {
    left: -1,
    top: 0,
    width: 2,
    height: 0,
}
[src/main.rs:49:13] image.data.len() = 0

I'm using the NotoColorEmoji-Regular.ttf file downloaded from Google Fonts.

Any help would be appreciated, I'm assuming this is not the expected output for shaping a singular emoji in a run of text, with a database which consists of only 1 emoji font.

bschwind avatar Sep 02 '24 11:09 bschwind

After more poking around, it seems maybe the TTF I downloaded isn't correct?

I tried substituting in this one and it seems to be rendering correctly now.

Something seems off about downloading the TTF from the google fonts website. There's even an empty issue about it.

bschwind avatar Sep 02 '24 11:09 bschwind

Had the exact same experience just now... can confirm that @bschwind 's alternative TTF file works fine.

bas-ie avatar Dec 09 '24 23:12 bas-ie