blob: 2ad3b3c41fc0ff70724b517dcd2203be24525ff0 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
//! Horizontal Metrics
const font = @import("shared").font;
const sfnt = @import("shared").sfnt;
const Face = font.types.face.Face;
const FontError = font.errors.font.FontError;
const GlyphMetrics = font.types.metrics.GlyphMetrics;
const Reader = sfnt.types.reader.Reader;
const LONG_METRIC_SIZE: usize = 4;
pub fn glyphMetrics(face: *const Face, glyph_id: u16) FontError!GlyphMetrics {
if (glyph_id >= face.GlyphCount) {
return FontError.GlyphOutOfRange;
}
if (face.LongMetricCount == 0) {
return FontError.TableOutOfBounds;
}
var reader = Reader.initialize(face.Hmtx);
if (glyph_id < face.LongMetricCount) {
try reader.seek(@as(usize, glyph_id) * LONG_METRIC_SIZE);
return GlyphMetrics{
.AdvanceWidth = try reader.readU16(),
.LeftSideBearing = try reader.readI16(),
};
}
try reader.seek(@as(usize, face.LongMetricCount - 1) * LONG_METRIC_SIZE);
const advance = try reader.readU16();
const trailing = @as(usize, face.LongMetricCount) * LONG_METRIC_SIZE +
@as(usize, glyph_id - face.LongMetricCount) * 2;
try reader.seek(trailing);
return GlyphMetrics{
.AdvanceWidth = advance,
.LeftSideBearing = try reader.readI16(),
};
}
pub fn advanceWidth(face: *const Face, glyph_id: u16) FontError!u16 {
const metrics = try glyphMetrics(face, glyph_id);
return metrics.AdvanceWidth;
}
|