Giter Club home page Giter Club logo

ab-glyph's Introduction

ab-glyph's People

Contributors

alexheretic avatar alexparlett avatar asibahi avatar danieldg avatar dhardy avatar ehfive avatar ekicyou avatar kianmeng avatar rlespinet avatar waywardmonkeys avatar yzsolt avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ab-glyph's Issues

What are ascent and descent?

For example, I get:

scale_font.ascent() = 16.147337
scale_font.descent() = -4.1026635

with y increasing downwards, thus I understand both numbers must be subtracted to go from the baseline (which is used in position) to the ascent/descent. This ought to be documented, but appears to be sufficient (in this case, subtract ascent/2 to find the mid-line, in order to find the mid-line closest to a click).

Direct access to backing store

I've got some code which rasterises some curves using ab_glyph_rasterizer and then converts it to a Rust image. On profiling the code, I found that 50% of the time was spent copying data from the rasterizer into the image object, since I only have access to the image data through for_each_pixel or for_each_pixel_2d. The fastest I could do was this:

        let dims = rasterizer.dimensions();
        let mut store = Vec::with_capacity(dims.0 * dims.1);
        rasterizer.for_each_pixel(|_, alpha| {
            let amount = (alpha * 255.0) as u8;
            store.push(amount);
        });
        let image = GrayImage::from_raw(dims.0 * dims.1, store)

But that pixel-at-a-time loop is a killer. Making the array available to the user would make it able to be blatted much more quickly into an image.

OTF feature tags

OTF files have feature flags, like tnum.

It would be wonderful to be able to enable such flags in ab-glyph

Provide benchmarks against rusttype

As this is a direct descendant of rusttype, and a continuation of that project aimed at solving, in part, performance it would be nice to see some common cases where performance will have increased (or decreased!!).
These might not be perfect since the API changed, but they should be an indication of common operations like rendering some text.

EDIT: I didnt look closely enough, but maybe put the benchmarks in the repo readme.md as well, thats where people will often look for them.

Anyway, looks like a nice performance bump you got from doing the revamp!

Documentation on glyph_bounds Unclear

The documentation for Font::glyph_bounds says

/// Returns the layout bounds of this glyph. These are different to the outline `px_bounds()`.
///
/// Horizontally: Glyph position +/- h_advance/h_side_bearing.
/// Vertically: Glyph position +/- ascent/descent.

As someone with no formal typesetting education, I don't know what this text is trying to tell me. So, the result is different to px_bounds, but how? Why?

I'm currently trying to use this function, but the result cuts off the text on the left and right. I guess this comment is supposed to explain why, but it's a mystery to me.

Frankly, this feels like a quick note by the author of that code to themselves, rather than something others should be able to interpret. Could you expand on that definition?

please include license text in published crates

The ab_glyph and ab_glyph_rasterizer crates that get produced and uploaded to crates.io don't include the license text for your specified license - however, the Apache 2.0 license usually requires that you ship the text alongside the licensed material (see "License and Copyright notice" here).

Can you please include the license text in the published crates? If you're cargo publishing from linux/macos, adding a symlink LICENSE → ../LICENSE in both directories should be enough to accomplish this (since you're not excludeing anything in Cargo.toml).

EDIT: Forgot to actually link the thing I wanted to link to here.

Coverage out of `[0, 1`] range

I have observed OutlinedGlyph::draw call my callback with a coverage of 1.0000001. This goes against the documentation, which says "with a coverage value in the range [0.0, 1.0]". This is likely due to floating point error.

I see two ways of addressing the problem:

  1. Document that the value is supposed to be in this range but might sometimes be outside. The user needs to clamp it if the exact range is important.
  2. Clamp the value in ab-glyph like with coverage.clamp(0.0, 1.0).

I can give a full reproduction if required.

panic (index out of bounds) for specific character in a specific font when rasterizing

As per the title.

For the font "Airstrip Four", the 'v' character appears to not have a bounding box, so when the rasterizer runs, it tries to index into the Vec but it is out of bounds.

In more detail, I've done some research and did a write-up here: bevyengine/bevy#1254

I cloned this repo, made a small change to the image example (below) to accept text as a second parameter, and downloaded airstrip.ttf into dev/fonts, and run cargo run --example image -- "dev/fonts/airstrip.ttf" "v". I put some dbg!()s in places, and the output is below:

    Finished dev [unoptimized + debuginfo] target(s) in 
1.48s
     Running `target\debug\examples\image.exe dev/fonts/airstrip.ttf v`
Using font: airstrip.ttf
[glyph\src\ttfp.rs:297] x_min = 0
[glyph\src\ttfp.rs:297] y_min = 0
[glyph\src\ttfp.rs:297] x_max = 0
[glyph\src\ttfp.rs:297] y_max = 0
[glyph\src\outlined.rs:36] &a = Rect {
    min: point(20.0, 56.0),
    max: point(20.0, 57.0),
}
[glyph\src\outlined.rs:101] h_factor = 0.019667832      
[glyph\src\outlined.rs:101] v_factor = -0.019667832     
[glyph\src\outlined.rs:101] offset = point(0.0, 0.46416092)
[glyph\src\outlined.rs:101] w = 0
[glyph\src\outlined.rs:101] h = 1
thread 'main' panicked at 'index out of bounds: the len 
is 4 but the index is 9', rasterizer\src\raster.rs:128:17
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
error: process didn't exit successfully: `target\debug\examples\image.exe dev/fonts/airstrip.ttf v` (exit code: 
101)
//! Draws text into `image_example.png`.
//!
//! Use a custom font file: `cargo run --example image /path/to/font.otf`
use ab_glyph::{point, Font, FontRef, FontVec, PxScale, ScaleFont};
use image::{DynamicImage, Rgba};

const TEXT: &str = "This is ab_glyph rendered into a png!";

fn main() {
    let maybe_text = std::env::args().nth(2);
    if let Some(font_path) = std::env::args().nth(1) {
        let font_path = std::env::current_dir().unwrap().join(font_path);
        let data = std::fs::read(&font_path).unwrap();
        let font = FontVec::try_from_vec(data).unwrap_or_else(|_| {
            panic!(format!(
                "error constructing a Font from data at {:?}",
                font_path
            ));
        });
        if let Some(name) = font_path.file_name().and_then(|n| n.to_str()) {
            eprintln!("Using font: {}", name);
        }
        draw_image(font, maybe_text);
    } else {
        eprintln!("No font specified ... using OpenSans-Italic.ttf");
        let font = FontRef::try_from_slice(include_bytes!("../fonts/OpenSans-Italic.ttf")).unwrap();
        draw_image(font, maybe_text);
    };
}

fn draw_image<F: Font>(font: F, maybe_text: Option<String>) {
    // The font size to use
    let scale = PxScale::from(45.0);

    let scaled_font = font.as_scaled(scale);

    let mut glyphs = Vec::new();
    dev::layout_paragraph(
        scaled_font,
        point(20.0, 20.0),
        9999.0,
        maybe_text.as_deref().unwrap_or(TEXT),
        &mut glyphs,
    );

    // Use a dark red colour
    let colour = (150, 0, 0);

    // work out the layout size
    let glyphs_height = scaled_font.height().ceil() as u32;
    let glyphs_width = {
        let min_x = glyphs.first().unwrap().position.x;
        let last_glyph = glyphs.last().unwrap();
        let max_x = last_glyph.position.x + scaled_font.h_advance(last_glyph.id);
        (max_x - min_x).ceil() as u32
    };

    // Create a new rgba image with some padding
    let mut image = DynamicImage::new_rgba8(glyphs_width + 40, glyphs_height + 40).to_rgba();

    // Loop through the glyphs in the text, positing each one on a line
    for glyph in glyphs {
        if let Some(outlined) = scaled_font.outline_glyph(glyph) {
            let bounds = outlined.px_bounds();
            // Draw the glyph into the image per-pixel by using the draw closure
            outlined.draw(|x, y, v| {
                // Offset the position by the glyph bounding box
                let px = image.get_pixel_mut(x + bounds.min.x as u32, y + bounds.min.y as u32);
                // Turn the coverage into an alpha value (blended with any previous)
                *px = Rgba([
                    colour.0,
                    colour.1,
                    colour.2,
                    px.0[3].saturating_add((v * 255.0) as u8),
                ]);
            });
        }
    }

    // Save the image to a png file
    image.save("image_example.png").unwrap();
    println!("Generated: image_example.png");
}

Get vertical writing attribute

I want a table reference API for vertical layout research.
If it's easy, I'll make a pull request.

v_advance, v_side_bearing, ...

Are there any plans to expand the layout API?
I would like to study it myself, so I would like to ask if you have any advice on extension points.

Drawing offset curves

Are there plans to support drawing offset curves for font outlines? I’m currently using ab_glyph_rasterizer for rasterizing glyphs from a font and would like to support outlined text as well.

Font::units_per_em should not return Option

This method returns None in the case of an invalid font, currently in the same way ttf-parser provides this. This also means Font::pt_to_px_scale returns Option.

However, I don't think there is much of a way to handle invalid fonts at the point of using this method. I think it would be better to either just panic for invalid fonts in the method call, or check when initializing a font and return an Err if units_per_em is none immediately, which will allow us to unwrap it later.

Having to handle the option makes using point sizes harder than it should be, related #15

Change default pixel scaling method

The current PxScale method was inherited from rusttype and defines the pixel height of glyphs in pixels. There are different ways that users would expect this work.

My current thoughts:

  • I don't want multiple px scale concepts inside ab-glyph. One is ok, and you should be able to convert that to any other.
  • Changing how it's done would clearly be breaking.
  • It would be nice to handle this in the least surprising & most common way as default.

Related: #11, #14

Add abilty to tweak font metrics

Considering #50 a fairly nice workaround would be to manually tweak the font v-metrics (In that case to add some extra ascent).

Perhaps a Tweak<Font> kinda thing that allows you to add ascent/descent/line-gap modifiers & maybe more stuff in future.

How to get `fonts_in_collection`

I want to load multiple font data.
When load font data, output the following error.

thread 'main' panicked at 'Invalid glyph_ver_side_bearing', /Users/keiya/.cargo/registry/src/github.com-1ecc6299db9ec823/ab_glyph-0.2.12/src/ttfp.rs:334:1

I'm using try_from_slice_and_index to load some font data.
But I don't know how to get next index. If fonts_in_collection is exported, I should be able to get next index.

Is there the way to get fonts collection length like the following ?

let i = owned_ttf_parser::fonts_in_collection().unwrap_or(0);
match FontRef::try_from_slice_and_index(data, i) {
    Ok(font) => Ok(font),
    Err(_) => Err(Error::InvalidFontBytes),
}

Thank you.

Glyph smudging with small fonts

Hi,

I wrote a small 2d lib which implements font rendering. I use ab_glyph_rasterizer to rasterize TrueType fonts, which works pretty well. However under specifc combinations of font size and font type I get a weird issue where the font doesn't rasterize properly and it create a smudging effect.

I have included a repository that replicates this issue. The README explains how it works in details.

In context, it results in these kinds of visual artifacts:
Screenshot from 2023-03-27 19-18-02

Some .ttf fonts seem to be missing glyphs

Hi! First of all, thank you, thank you for these great crates!

I'm trying to use the font Recursive for my game and I've found that it displays the incorrect is missing glyphs.

Here is a screeny of the version using Recursive_VF_1.070.ttf:
Screen Shot 2021-01-16 at 8 45 40 AM

And here is the same example using OpenSans-Light.ttf:
Screen Shot 2021-01-16 at 8 47 06 AM

Here's my initial layout:

    let font = {
        let mut fonts = world.write_resource::<Assets<FontArc>>();
        //fonts.load("assets/fonts/OpenSans-Light.ttf") 
        fonts.load("assets/fonts/Recursive_VF_1.070.ttf")
    };
    world
        .create_entity()
        .with(Text {
            fonts: vec![font],
            sections: vec![OwnedSection::default()
                .add_text(
                    OwnedText::new("A spot of text that has some nice layout and ")
                        .with_scale(32.0)
                        .with_color(Color::RGBA(0x33, 0x33, 0x33, 255).to_text_color()),
                )
                .add_text(
                    OwnedText::new("EVERYTHING! ")
                        .with_scale(32.0)
                        .with_color(Color::RGB(255, 255, 0).to_text_color()),
                )
                .add_text(
                    OwnedText::new("Another spot of text with transparency")
                        .with_scale(24.0)
                        .with_color(Color::RGBA(0x33, 0x33, 0x33, 127).to_text_color()),
                )
                .with_bounds((800.0, 600.0))],
        })
        .with(Name::from("welcome_text"))
        .with(Transform::default())
        .with(RenderLayers::layer2d())
        .build();

The system that builds and buffers the geometry is mostly copied from your OpenGL example in glyph_brush/examples/opengl.rs.

Furthermore, it doesn't seem to depend on what font index I decode the font with (Recursive is a big family).

Returning partially clipped glyphs

Last I checked a year ago, if a glyph was partially outside of the bounds for the text section it would not be included when calling process_queued.

I’d like to be able to instead have these partially clipped glyphs returned, with the glyph’s texture and size bounds adjusted to only encompass the part that is within the text bounds.

This would make things such as scrolling windows easier as you wouldn’t need to handle partial clipping at the edges when scrolling yourself.

Would there be any downsides to this design? I can’t think of any but I’m not familiar with the reason that it isn’t done that way currently.

Thanks!

Subpixel Antialiasing

Hi,

great job, any plans to support sub pixel AA ? At small resolutions and low contrast things can get ugly. Would be great if we would have better AA support one day.

Thanks!

SDF Rasterization

Rasterize glyphs into a signed distance field for use in 3D graphics pipelines.

Support laying out text using rustbuzz

This crate looks very good, and I wanted to use it in combination with rustbuzz to lay out text. However, it looks like there is no support for accessing the underlying ttf_parser font (unless I missed something). I assume that you don't want to make it a public dependency. Therefore, it would be nice if there was some way (with a feature gate or something) to enable a function that would layout text using rustbuzz.

This violates the original license of font-rs

This isn't "Inspired by font-rs & stb_truetype", it is the raster from font-rs with modifications. Please properly attribute, list changes, and license under Apache. After reading your blog post and reviewing the code, this feels extremely disingenuous.

If licensing is a pain for projects without re-used licensed code, consider using Zlib :D.

GPU Caching

I was originally looking at going with rusttype, but I found this and it looks like it might suit my needs better (it's also actively maintained).

The one thing that concerns me is GPU caching - this seems to be something this crate is missing compared to rusttype, and I was wondering a couple of things:

  • Do you have plans to implement this in the future?
  • Have I just missed or misunderstood something? Is there a reason why it isn't included yet?

My use case involves potentially rendering new text every frame, which is why it's a feature I'm interested in.

Thanks for your work on this crate as well as your work maintaining rusttype - I appreciate it.

Top of text is slightly clipped in ab-glyph 0.2.12 but not in ab-glyph 0.2.11

I've got a graphical program that transitively depends on ab-glyph (wgpu_glyph -> glyph-brush -> ab_glyph). I recently ran cargo update and noticed some text clipping I hadn't seen before. The change seems to be caused by upgrading ab-glyph 0.2.11 to ab-glyph 0.2.12.

The text clipping doesn't seem to happen with every font.

I've created a repository with scripts to run example code against the two versions. The example it runs is the hello example from wgpu_glyph, modified to use a font that clips in 0.2.12 but not 0.2.11. It also contains the glyph-brush crate modified to use a specific ab-glyph version (either 0.2.12 or 0.2.11, depending on which script is run). The code requires a unix-like environment with basic utilities (e.g., tar, mv, etc.).

https://github.com/MichaelMMacLeod/debugging-font-weirdness

Running the 0.2.11 example results in the following (which seems correctly displayed):

Screenshot_20211211_145430

Running the 0.2.12 example results in the following (where the top of the text gets slightly clipped):

image

The text also appears a bit bigger in 0.2.12 than it did in 0.2.11 (which might be why it's clipping).

provide alternative to Font::glyph_id for specifying glyphs for whom no char exists

i would like to use ab-glyph with a font-shaping library, like harfbuzz.

ab-glyph is great for writing-systems with nice char->glyph mappings, but many writing systems have glyphs that are effected by the surrounding text or glyphs that are composed of multiple char.

if there was some way of feeding a glyph id as an integer value, i could ask my font-shaping library what glyph i need, and ab-glyph could render it for me.

Embedding fonts at compile time

I think there should be a proc macro or a const fn or something we can use to embed a Font directly in the binary such that error handling doesn't have to be performed at runtime (no possibility of a panic). Would be nice for embedded applications

Make the rasterizer a default feature and a required dependency

Hi,

Would it be possible to make the rasterizer an optional dependency and add it to the default features. I would like to use ab_glyph instead of rusttype since it is clear more maintained, but since I will be generating an SVG path I have no need for the actual rasterizer. It is not a huge issue, but I feel like this is a situation more people may be in.

To solve this we could make the rasterizer an optional dependency, add a default feature for the rasterizer. If you want, I can make the PR for this. Let me know.

Outline with custom `OutlineBuilder`

Would it be possible to utilize a custom owned_ttf_parser::OutlineBuilder to outline a glyph? The current implementation embeds the MoveTo and Close operations into the outline curves by adding extra points. This cannot be reliably extracted anymore, since f32s do not allow for reliable equalities. Therefore, it would be really handy to have a outline_with_builder method that provides similar behavior to outline however allows of use of a custom OutlineBuilder.

Example

use ab_glyph::{point, Font, FontRef, Glyph, OutlineBuilder};

enum OutlineCurve {
    Move(f32, f32),
    Line(f32, f32),
    Cubic(f32, f32, f32, f32, f32, f32),
    Quad(f32, f32, f32, f32),
    Close,
}

#[derive(Default)]
struct SvgOutlineBuilder(Vec<OutlineCurve>);

impl OutlineBuilder for SvgOutlineBuilder {
    fn move_to(&mut self, x: f32, y: f32) {
        self.0.push(OutlineCurve::Move(x, y))
    }

    fn line_to(&mut self, x: f32, y: f32) {
        self.0.push(OutlineCurve::Line(x, y))
    }

    fn curve_to(&mut self, x1: f32, y1: f32, x2: f32, y2: f32, x: f32, y: f32) {
        self.0.push(OutlineCurve::Cubic(x1, y1, x2, y2, x, y))
    }

    fn quad_to(&mut self, x1: f32, y1: f32, x: f32, y: f32) {
        self.0.push(OutlineCurve::Quad(x1, y1, x, y))
    }

    fn close(&mut self) {
        self.0.push(OutlineCurve::Close)
    }
}

let q_glyph: Glyph = font
    .glyph_id('q')
    .with_scale_and_position(24.0, point(100.0, 0.0));

let mut outline_builder = SvgOutlineBuilder::default();
let outline = font.outline_with_builder(q_glyph, &mut outline_builder);

This is not currently possible with the current API. This should probably also include reexporting the OutlineBuilder from owned_ttf_parser.

I apologize for filing yet another issue, but I feel like this could make the crate more useful in a wider range of use cases. If you feel like this is a welcome change, I would be happy to submit a PR for it.

Get the associated `char` of a `GlyphId` ?

I can query the glyph ID from a char but how to do the opposite?

The use case is to make a list of char available in the font. To do that, I'm able to get the number of glyph with glyph_count(). It says "Glyph identifiers for this font will always be in the range 0..self.glyph_count()", therefore I understand that all the glyphs are from 0 to this number. But then I don't know how to retrieve the char associated to each glyph ID.

Also, I'm not sure if all glyph has an associated char. I think it does, but I can't be sure.


By the way, I prefer ab_glyph interface over rusttype, however, for developers who don't have a strong background in font-related stuff, it's a bit cryptic. Stuff like 'side bearing', kern, advance, ascent, descent, I was able to figure out the meaning of some but not all of them. Do you have a link where I could get those infos ? For instance, even the description of the draw() message is unclear, at least to me: "[...] with a coverage value in the range [0.0, 1.0].". It took me time to understand it was the amount of gray color. But that's just my opinion, I may be lacking in the literature.

Are bitmap fonts supported?

When i try to use .otb fonts (terminus-font-4.49.1 or gohufont-2.1-otb) with the examples i get no errors and no output except that both ./ascii and ./image report width and height. so i'm unsure whether these fonts are supported by ab_glyph or not.

Compilation error on fedora copr

https://download.copr.fedorainfracloud.org/results/remilauzier/zemeroth/fedora-rawhide-x86_64/02303655-rust-ab_glyph/builder-live.log.gz

error[E0432]: unresolved import owned_ttf_parser::AsFaceRef
--> src/ttfp.rs:10:5
|
10 | use owned_ttf_parser::AsFaceRef;
| ^^^^^^^^^^^^^^^^^^---------
| | |
| | help: a similar name exists in the module: AsFontRef
| no AsFaceRef in the root

error[E0433]: failed to resolve: could not find Face in owned_ttf_parser
--> src/ttfp.rs:113:31
|
113 | owned_ttf_parser::Face::from_slice(data, index).map_err(|_| InvalidFont)?,
| ^^^^ could not find Face in owned_ttf_parser

error[E0433]: failed to resolve: could not find OwnedFace in owned_ttf_parser
--> src/ttfp.rs:177:31
|
177 | owned_ttf_parser::OwnedFace::from_vec(data, index).map_err(|_| InvalidFont)?,
| ^^^^^^^^^ could not find OwnedFace in owned_ttf_parser

error[E0412]: cannot find type Face in crate owned_ttf_parser
--> src/ttfp.rs:71:45
|
71 | pub struct FontRef<'font>(owned_ttf_parser::Face<'font>);
| ^^^^ not found in owned_ttf_parser

error[E0412]: cannot find type OwnedFace in crate owned_ttf_parser
--> src/ttfp.rs:134:38
|
134 | pub struct FontVec(owned_ttf_parser::OwnedFace);
| ^^^^^^^^^ help: a struct with a similar name exists: OwnedFont
|
::: /usr/share/cargo/registry/owned_ttf_parser-0.6.0/src/owned.rs:6:1
|
6 | pub struct OwnedFont(Pin<Box>);
| ----------------------------------------------- similarly named struct OwnedFont defined here

error[E0277]: the size for values of type dyn Iterator<Item = (glyph::GlyphId, char)> cannot be known at compilation time
--> src/ttfp.rs:306:29
|
306 | let inner = Box::new(
| ^^^^^^^^ doesn't have a size known at compile-time
...
338 | impl_font!(FontRef<'_>);
| ------------------------ in this macro invocation
|
= help: the trait Sized is not implemented for dyn Iterator<Item = (glyph::GlyphId, char)>
= note: required by Box::<T>::new
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the size for values of type dyn Iterator<Item = (glyph::GlyphId, char)> cannot be known at compilation time
--> src/ttfp.rs:306:29
|
306 | let inner = Box::new(
| ^^^^^^^^ doesn't have a size known at compile-time
...
339 | impl_font!(FontVec);
| -------------------- in this macro invocation
|
= help: the trait Sized is not implemented for dyn Iterator<Item = (glyph::GlyphId, char)>
= note: required by Box::<T>::new
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to 7 previous errors

About font scale_factor calculate

For example:

    let font = FontRef::try_from_slice(include_bytes!("../assets/SourceHanSansSC/SourceHanSansSC-Regular.otf")).unwrap();
    let font_size = 24.0;
    let px_scale_font = font.as_scaled(font_size);

    dbg!(font.units_per_em().unwrap());
    dbg!(font.height_unscaled());
    dbg!(font.ascent_unscaled());
    dbg!(font.descent_unscaled());
    dbg!(px_scale_font.ascent());
    dbg!(px_scale_font.descent());

    println!("font size as units per em");
    let scale_factor = font_size / font.units_per_em().unwrap();
    dbg!(scale_factor);
    dbg!(font.ascent_unscaled() * scale_factor);

    println!("font size as height units");
    let scale_factor = font_size / font.height_unscaled();
    dbg!(scale_factor);
    dbg!(font.ascent_unscaled() * scale_factor);

output:

[src/main.rs:10] font.units_per_em().unwrap() = 1000.0
[src/main.rs:11] font.height_unscaled() = 1448.0
[src/main.rs:12] font.ascent_unscaled() = 1160.0
[src/main.rs:13] font.descent_unscaled() = -288.0
[src/main.rs:14] px_scale_font.ascent() = 19.226519
[src/main.rs:15] px_scale_font.descent() = -4.773481
font size as units per em
[src/main.rs:19] scale_factor = 0.024
[src/main.rs:20] font.ascent_unscaled() * scale_factor = 27.84
font size as height units
[src/main.rs:24] scale_factor = 0.016574586
[src/main.rs:25] font.ascent_unscaled() * scale_factor = 19.226519

In font Roboto, units per em = 1000, height = 1448
so the text rasterize seems smaller.

Font size is 24px, left is in chrome, right is in ab_glyph.

image

I am not sure which is correct, but I found in another font parse library fontdue:
It use units_per_em.

https://github.com/mooman219/fontdue/blob/master/src/font.rs#L243-L247

    /// Calculates the glyph scale factor for a given px size.
    #[inline(always)]
    fn scale_factor(px: f32, units_per_em: f32) -> f32 {
        px / units_per_em
    }

======================

I try to adjust the scale factory to fit units_per_em, it seems size equal:

 let text_size = text_size * (font.font().height_unscaled() / font.font().units_per_em().unwrap());

image

=======================================
Chrome demo:
http://static.takwolf.com/font-test/index.html
https://github.com/TakWolf/static.takwolf.com/blob/master/font-test/index.html

ab-glyph demo:
https://github.com/TakWolf/tge/blob/feature/ab-glyph/examples/text_layout.rs

Handling of unexpected advance/side bearing values

Currently the unscaled advance and side bearing getters in ttfp.rs expect that the underlying values exist.
I've run into a simple v_side_bearing_unscaled() panicking on me on a Times New Roman Italic TTF - I guess it's not a bug in the font. But even if it were, I think expect-ing these values is risky in a library depending on a parser, where the input files can sometimes be invalid(ish) but still generally usable.
I think it'd make more sense to return 0.0 for these values instead, since doing so is harmless for the user, regardless if the values are absent either because the font or the TTF parser is buggy. What do you think?

index out of bounds: the len is 4 but the index is 5

I encounter this error:

thread 'main' panicked at 'index out of bounds: the len is 4 but the index is 5', /home/yatekii/.cargo/registry/src/github.com-1ecc6299db9ec823/ab_glyph_rasterizer-0.1.5/src/raster.rs:128:17
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

when running. I feel like this should not happen or if there are limitations, they should be outlined in the help text.

Documentation on what is supported

i.e. kerning, ligatures, metrics, variable fonts, and so on. Currently everything is kind of up in the air. Going to have to do some local testing to figure this out.

Test failed due to missing files

https://download.copr.fedorainfracloud.org/results/remilauzier/zemeroth/fedora-rawhide-x86_64/02311687-rust-ab_glyph/builder-live.log.gz

Fedora as update there version of ttf-parser but the test failed due to missing files.

---- src/font.rs - font::Font::as_scaled (line 175) stdout ----
error: couldn't read src/../../dev/fonts/Exo2-Light.otf: No such file or directory (os error 2)
--> src/font.rs:178:36
|
5 | let font = FontRef::try_from_slice(include_bytes!("../../dev/fonts/Exo2-Light.otf"))?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to previous error

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.