Closed TakWolf closed 4 years ago
new_line_width
is the advance width of a new line for vertical fonts. Both of the new line offsets being unscaled is a bug (I haven't done any layout work yet, it's a TODO).
If you're looking for how far you need to offset for the next glyph, Metrics.advance_width
for the distance you need to advance for the associated character in a horizontal layout. The bounds: AABB
for the glyph is its offset in the line. If you're drawing the textures at (x, y)
, change it to (x + Metrics.xmin, y + Metrics.ymin)
. For example, g
falls belong the baseline and has a negative ymin
to represent that.
But the metrics.bounds values seems not correct.
I use coordinate origin top left and direction is right down.
0 ----------> +x |
---|
+y
vertex order is :
1 --- 2 | / | 3---4
let vertices = vec![
Vertex {
position: Position::new(
position.x + metrics.bounds.xmin,
position.y + metrics.bounds.ymin,
),
uv: uv.top_left(),
color,
},
Vertex {
position: Position::new(
position.x + metrics.bounds.xmin + metrics.width as f32,
position.y + metrics.bounds.ymin,
),
uv: uv.top_right(),
color,
},
Vertex {
position: Position::new(
position.x + metrics.bounds.xmin,
position.y + metrics.bounds.ymin + metrics.height as f32,
),
uv: uv.bottom_left(),
color,
},
Vertex {
position: Position::new(
position.x + metrics.bounds.xmin + metrics.width as f32,
position.y + metrics.bounds.ymin + metrics.height as f32,
),
uv: uv.bottom_right(),
color,
},
];
Metrics assume positive y us up. Subtract ymin in your case
font = Roboto-Regular.ttf px = 32.0 text = "AaGg"
A:
Metrics { width: 21, height: 23, advance_width: 20.875, advance_height: 0.0, bounds: AABB { xmin: 0.453125, xmax: 20.46875, ymin: 0.0, ymax: 22.75 } }
a:
Metrics { width: 14, height: 18, advance_width: 17.40625, advance_height: 0.0, bounds: AABB { xmin: 1.703125, xmax: 15.65625, ymin: -0.3125, ymax: 17.21875 } }
G:
Metrics { width: 18, height: 24, advance_width: 21.796875, advance_height: 0.0, bounds: AABB { xmin: 1.90625, xmax: 19.453125, ymin: -0.3125, ymax: 23.0625 } }
g:
Metrics { width: 15, height: 24, advance_width: 17.96875, advance_height: 0.0, bounds: AABB { xmin: 1.515625, xmax: 15.78125, ymin: -6.671875, ymax: 17.21875 } }
(x + Metrics.xmin, y - Metrics.ymin)
It's still a little strange
The char a
aabb.ymin = -0.3125, not even enough -1px
Ah I think that's because you're aligning to the top of the line, all values are relative to the baseline which is below the letters. Xmin and Ymin are the offsets relative to the bottom left of the texture.
(x + Metrics.xmin,y + px - metrics.height - metrics.ymin)
This seems ok.
But there is no base-line y position. I draw text at y = 0, so the texts is offset at y axis.
Here's an example of what the metrics should represent in ms paint real quick
Anyway, I fixed the actual bug for the missing line information in https://github.com/mooman219/fontdue/commit/5703cde10e8f8e609363073c38d5d3a79ba9f618
I think there should a baseline y position in the draw region. Now I set baseline y position at the draw region bottom, so it cause like that:
But the text should in the region box.
https://github.com/redox-os/rusttype/blob/master/src/lib.rs#L302
I see rusttype VMetrics has a concept:
pub struct VMetrics {
/// The highest point that any glyph in the font extends to above the
/// baseline. Typically positive.
pub ascent: f32,
/// The lowest point that any glyph in the font extends to below the
/// baseline. Typically negative.
pub descent: f32,
/// The gap to leave between the descent of one line and the ascent of the
/// next. This is of course only a guideline given by the font's designers.
pub line_gap: f32,
}
If so I can set baseline y position in draw region at: line_gap + descent
Can fontdue provide the similar params?
====================
This is I found in Android text draw FontMetrics:
I don't have layout tools in fontdue yet, but it looks fine to me with a naive implementation I had laying around?
Pseudo code:
let caret = Vector2::new(0.0, 0.0);
for each character:
glpyhs.push(Sprite::new(
Vector2::new(
caret.x + metrics.bounds.xmin,
caret.y + metrics.bounds.ymin,
),
));
}
// Move the caret forward.
caret.x += metrics.advance_width;
if caret.x > max_width {
caret.y -= font.advance_height;
caret.x = 0.0;
}
I try to add a header table info to the font.
https://github.com/TakWolf/fontdue/tree/feature/header_table https://github.com/TakWolf/fontdue/blob/96ebc49e5747a18b6f784567bbe271633d6d0c9b/src/font.rs#L137
I can calculate baseline y position in box at -descent + line_gap
(The algorithm is similar to https://github.com/redox-os/rusttype/blob/1346e49673127f6698053148da572c5e2e5fc3b9/dev/examples/gpu_cache.rs#L21)
The effect is:
This way solved my layout problem.
There is a
Metrics
struct, but have no baseline info.How to use the bounds?
================================
font.new_line_width()
is a fixed value, This has no scale with it?