alexheretic / ab-glyph Goto Github PK
View Code? Open in Web Editor NEWRust API for loading, scaling, positioning and rasterizing OpenType font glyphs
License: Apache License 2.0
Rust API for loading, scaling, positioning and rasterizing OpenType font glyphs
License: Apache License 2.0
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
.
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.
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 files have feature flags, like tnum.
It would be wonderful to be able to enable such flags in ab-glyph
I was able to hit this panic when trying to draw code points 0x2001..0x2004 from Symbola.ttf (https://fedoraproject.org/wiki/Gdouros_Symbola). These code points are all whitespace of some kind, so I suspect (but have not verified) that the bounding box has a zero-size dimension.
Line 253 in cb8241d
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!
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.
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
Some otf font parse have no outline glyph.
I make sure the font file is correct, and parse have no error.
But have no glyph.
The otf font from:
https://github.com/adobe-fonts/source-han-sans
font.glyph_count() is 65535,
font.outline_glyph(glyph) return None.
Rasterize glyphs into a signed distance field for use in 3D graphics pipelines.
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");
}
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.
I'm currently trying to replace the unmaintained rusttype
crate with ab_glyph
but I don't really know what I'm doing...
I think I've got everything covered except one instance of the Font::layout
method from rusttype
: https://gitlab.redox-os.org/redox-os/rusttype/-/blob/master/src/font.rs#L191
How would you implement something like that method using ab_glyph?
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!
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
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.
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.
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());
=======================================
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
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 publish
ing from linux/macos, adding a symlink LICENSE โ ../LICENSE
in both directories should be enough to accomplish this (since you're not exclude
ing anything in Cargo.toml).
EDIT: Forgot to actually link the thing I wanted to link to here.
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!
As discussed in #81 (comment) covering all outline builder methods with OutlineCurve
variants will make it more useful to usage outside of regular rasterization.
This would be a breaking change.
since 0.1.6 uses is_x86_feature_detected!
, the package no longer works with no_std
I used an unscaled Font metrics by mistake when migrating Robo Instructus, so having distinct names will probably be a good thing.
Hello all, found an issue using while using Bevy that involves using variable fonts. I'll link the issue from Bevy since all the info is there.
Issue: bevyengine/bevy#5018
If layout horizontal and from left to right:
advance_height = px_scale_font.ascent() - px_scale_font.descent(); //
advance_width = ?
image ref from #6
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.
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?
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).
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
:
And here is the same example using OpenSans-Light.ttf
:
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).
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
Right now the rasterizer uses a nonzero filling method, which is convenient for many cases. It would be nice if it also provided an odd filling method, as well as positive/negative
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.
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.
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
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):
Running the 0.2.12 example results in the following (where the top of the text gets slightly clipped):
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).
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.
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.
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.
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.
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.
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.
Hello,
First of all, thanks for ab_glyph
and glyph_brush
; ab_glyph
is what's used to render glyphs in my acrylic
crate.
I was wondering how I could configure a font's variations?
I see that ttf-parser
has a Face::set_variation
method, is this method available from ab_glyph
?
I'd like to reference https://lorp.github.io/samsa/src/samsa-gui.html which is a great tool for playing with font variations.
Thank you very much.
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:
coverage.clamp(0.0, 1.0)
.I can give a full reproduction if required.
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 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:
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.
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?
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
.
My repository https://github.com/treetertot/cantarell_test demonstrates an issue in how ab_glyph renders Cantarell. There are large rectangles over many of the letters that do not appear when rendered by gtk.
I've cloned ab_glyph and am still tracking down the exact problem myself.
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.