Skip to content

Commit 2d8b1fd

Browse files
committed
[TTF] Model ascent and descent metrics
1 parent 09a7890 commit 2d8b1fd

File tree

3 files changed

+59
-29
lines changed

3 files changed

+59
-29
lines changed

rust_programs/ttf_renderer/src/character_map.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ pub(crate) fn parse_character_map(parser: &FontParser) -> BTreeMap<usize, usize>
232232
.find_map(|_| {
233233
let character_map_subtable =
234234
CharacterMapSubtable::from_in_place_buf(parser.read_with_cursor(&mut cursor));
235-
println!("Character map subtable {character_map_subtable:?}");
235+
//println!("Character map subtable {character_map_subtable:?}");
236236
let recognized_unicode_encodings = [
237237
CharacterMapPlatformAndEncoding::Unicode(
238238
CharacterMapUnicodeEncoding::Version2_0Bmp,

rust_programs/ttf_renderer/src/hints.rs

+27-25
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ pub(crate) fn parse_instructions(
367367
loop {
368368
let opcode: &u8 = FontParser::read_data_with_cursor(instructions, &mut cursor);
369369
if operations.should_print() {
370-
print!("{cursor:04x}\t{opcode:02x}\t");
370+
//print!("{cursor:04x}\t{opcode:02x}\t");
371371
}
372372
match opcode {
373373
0x00 | 0x01 => {
@@ -379,7 +379,7 @@ pub(crate) fn parse_instructions(
379379
};
380380

381381
if operations.should_print() {
382-
println!("Set freedom and projection vectors to {axis:?}");
382+
//println!("Set freedom and projection vectors to {axis:?}");
383383
}
384384
if operations.should_execute() {
385385
graphics_state.projection_vector = axis;
@@ -391,7 +391,7 @@ pub(crate) fn parse_instructions(
391391
let zone_number = graphics_state.pop();
392392
let zone = Zone::from(zone_number);
393393
if operations.should_print() {
394-
println!("SZP0\tZone pointer 0 = {zone:?}");
394+
//println!("SZP0\tZone pointer 0 = {zone:?}");
395395
}
396396
if operations.should_execute() {
397397
graphics_state.zone_pointers[0] = zone;
@@ -406,7 +406,7 @@ pub(crate) fn parse_instructions(
406406
true => "(taken)",
407407
false => "(not taken)",
408408
};
409-
println!("ELSE {}", take_else_str);
409+
//println!("ELSE {}", take_else_str);
410410
}
411411
if operations.should_execute() {
412412
if !take_else {
@@ -425,11 +425,11 @@ pub(crate) fn parse_instructions(
425425
0x23 => {
426426
// Swap
427427
if operations.should_print() {
428-
println!("SWAP\ttop 2 stack elements");
428+
//println!("SWAP\ttop 2 stack elements");
429429
}
430-
println!("Stack: ");
430+
//println!("Stack: ");
431431
for x in graphics_state.interpreter_stack.iter().rev() {
432-
println!("\t\t\t{x:08x}");
432+
//println!("\t\t\t{x:08x}");
433433
}
434434
if operations.should_execute() {
435435
let e2 = graphics_state.pop();
@@ -443,7 +443,7 @@ pub(crate) fn parse_instructions(
443443
// Function identifier number is popped from the stack
444444
let function_identifier_number = graphics_state.pop();
445445
if operations.should_print() {
446-
println!("CALL #{function_identifier_number}");
446+
//println!("CALL #{function_identifier_number}");
447447
}
448448
if operations.should_execute() {
449449
let function = &font.functions_table[&(function_identifier_number as _)];
@@ -455,7 +455,7 @@ pub(crate) fn parse_instructions(
455455
// Function identifier number is popped from the stack
456456
let function_identifier_number = graphics_state.pop();
457457
if operations.should_print() {
458-
println!("Function define #{function_identifier_number}");
458+
//println!("Function define #{function_identifier_number}");
459459
}
460460
if operations.should_execute() {
461461
//
@@ -464,16 +464,18 @@ pub(crate) fn parse_instructions(
464464
0x2d => {
465465
// ENDF
466466
if operations.should_print() {
467-
println!("ENDF");
467+
//println!("ENDF");
468468
}
469469
}
470470
0x4b => {
471471
// Measure pixels per em in the projection vector's axis
472472
if operations.should_print() {
473+
/*
473474
println!(
474475
"MPPEM\tMeasure pixels per em in {:?}",
475476
graphics_state.projection_vector
476477
);
478+
*/
477479
}
478480
if operations.should_execute() {
479481
let val = match graphics_state.projection_vector {
@@ -489,7 +491,7 @@ pub(crate) fn parse_instructions(
489491
let e1 = graphics_state.pop();
490492
let result = e1 < e2;
491493
if operations.should_print() {
492-
println!("LT\tLess than? {e1} < {e2} = {result}");
494+
//println!("LT\tLess than? {e1} < {e2} = {result}");
493495
}
494496
if operations.should_execute() {
495497
graphics_state.push(if result { 1 } else { 0 });
@@ -506,7 +508,7 @@ pub(crate) fn parse_instructions(
506508
last_if_condition_passed = Some(condition_passed);
507509

508510
if operations.should_print() {
509-
println!("IF\t{condition_passed}");
511+
//println!("IF\t{condition_passed}");
510512
}
511513
if operations.should_execute() {
512514
if !condition_passed {
@@ -526,14 +528,14 @@ pub(crate) fn parse_instructions(
526528
0x59 => {
527529
// Nothing to do
528530
if operations.should_print() {
529-
println!("EIF");
531+
//println!("EIF");
530532
}
531533
}
532534
0x5c => {
533535
// NOT
534536
let val = graphics_state.pop();
535537
if operations.should_print() {
536-
println!("NOT {val:08x}");
538+
//println!("NOT {val:08x}");
537539
}
538540
if operations.should_execute() {
539541
let result = if val != 0 { 0 } else { 1 };
@@ -554,15 +556,15 @@ pub(crate) fn parse_instructions(
554556
let period = RoundStatePeriod::from(period_val as usize);
555557

556558
if operations.should_print() {
557-
println!("SROUND\tperiod={period:?}, phase={phase:?}, threshold={threshold:?}");
559+
//println!("SROUND\tperiod={period:?}, phase={phase:?}, threshold={threshold:?}");
558560
}
559561
if operations.should_execute() {
560562
graphics_state.round_state = RoundState::new(period, phase, threshold);
561563
}
562564
//
563565
}
564566
0x77 => {
565-
println!("TODO: Super round @ 45 degrees");
567+
//println!("TODO: Super round @ 45 degrees");
566568
let val = graphics_state.pop();
567569
}
568570
0x85 => {
@@ -572,7 +574,7 @@ pub(crate) fn parse_instructions(
572574
let low = word & 0xff;
573575
let high = (word >> 8) & 0xff;
574576
if operations.should_print() {
575-
println!("SCANCTRL {low:04x} : {high:04x}");
577+
//println!("SCANCTRL {low:04x} : {high:04x}");
576578
}
577579
if operations.should_execute() {
578580
// TODO(PT): Which axis should this use?
@@ -588,7 +590,7 @@ pub(crate) fn parse_instructions(
588590
// GETINFO
589591
let selector = graphics_state.pop();
590592
if operations.should_print() {
591-
println!("GETINFO");
593+
//println!("GETINFO");
592594
}
593595
let mut result = 0_u32;
594596
if operations.should_execute() {
@@ -609,7 +611,7 @@ pub(crate) fn parse_instructions(
609611
// SCANTYPE
610612
let word = graphics_state.pop();
611613
if operations.should_print() {
612-
println!("SCANTYPE {word:08x}");
614+
//println!("SCANTYPE {word:08x}");
613615
}
614616
if operations.should_execute() {
615617
graphics_state.scan_control.dropout_control_mode =
@@ -625,11 +627,11 @@ pub(crate) fn parse_instructions(
625627
number_of_bytes_to_push as usize,
626628
);
627629
if operations.should_print() {
628-
print!("Push {number_of_bytes_to_push} bytes:");
630+
//print!("Push {number_of_bytes_to_push} bytes:");
629631
for byte in bytes_to_push.iter() {
630-
print!(" {byte:02x}");
632+
//print!(" {byte:02x}");
631633
}
632-
println!();
634+
//println!();
633635
}
634636
if operations.should_execute() {
635637
for byte in bytes_to_push.iter() {
@@ -649,11 +651,11 @@ pub(crate) fn parse_instructions(
649651
words_to_push.push(word);
650652
}
651653
if operations.should_print() {
652-
print!("Push {number_of_words_to_push} words:");
654+
//print!("Push {number_of_words_to_push} words:");
653655
for word in words_to_push.iter() {
654-
print!(" {word:02x}");
656+
//print!(" {word:02x}");
655657
}
656-
println!();
658+
//println!();
657659
}
658660
if operations.should_execute() {
659661
for word in words_to_push.iter() {

rust_programs/ttf_renderer/src/metrics.rs

+31-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::parse_utils::{BigEndianValue, FromFontBufInPlace, TransmuteFontBufInPlace};
22
use crate::parser::FontParser;
3-
use agx_definitions::Rect;
3+
use agx_definitions::{Rect, Size};
44
use alloc::vec;
55
use alloc::vec::Vec;
66
use core::cell::RefCell;
@@ -32,17 +32,31 @@ impl TransmuteFontBufInPlace for HheaTableRaw {}
3232

3333
#[derive(Debug, Clone)]
3434
pub struct HheaTable {
35+
pub ascent: isize,
36+
pub descent: isize,
37+
pub line_gap: isize,
3538
pub long_hor_metrics_count: usize,
3639
}
3740

3841
impl FromFontBufInPlace<HheaTableRaw> for HheaTable {
3942
fn from_in_place_buf(raw: &HheaTableRaw) -> Self {
4043
Self {
44+
ascent: raw.ascent.into_value() as _,
45+
descent: raw.descent.into_value() as _,
46+
line_gap: raw.line_gap.into_value() as _,
4147
long_hor_metrics_count: raw.long_hor_metrics_count.into_value() as _,
4248
}
4349
}
4450
}
4551

52+
#[derive(Debug, Clone)]
53+
pub struct FontGlobalLayoutMetrics {
54+
pub ascent: isize,
55+
pub descent: isize,
56+
pub line_gap: isize,
57+
pub long_hor_metrics: Vec<LongHorMetric>,
58+
}
59+
4660
#[repr(C, packed)]
4761
#[derive(Debug, Copy, Clone)]
4862
pub struct LongHorMetricRaw {
@@ -161,6 +175,14 @@ impl GlyphRenderMetrics {
161175
let horizontal_metrics = self.horizontal_metrics.borrow();
162176
let vertical_metrics = self.vertical_metrics.borrow();
163177
let h = horizontal_metrics.as_ref().unwrap();
178+
// TODO(PT): We're not finding vertical metrics for any glyph! This is causing the rendering to go bad?
179+
// Update: vmtx is only for vertical-layout scripts, not English, so I had a misunderstanding
180+
/*
181+
println!(
182+
"Found vert metrics? {}",
183+
vertical_metrics.as_ref().is_some()
184+
);
185+
*/
164186
let v = vertical_metrics
165187
.as_ref()
166188
.unwrap_or(&VerticalMetrics {
@@ -177,7 +199,7 @@ impl GlyphRenderMetrics {
177199
}
178200
}
179201

180-
pub(crate) fn parse_horizontal_metrics(parser: &FontParser) -> Vec<LongHorMetric> {
202+
pub(crate) fn parse_horizontal_metrics(parser: &FontParser) -> FontGlobalLayoutMetrics {
181203
let hhea: HheaTable = parser.parse_table("hhea");
182204
let hmtx_offset = parser.table_headers.get("hmtx").unwrap().offset;
183205
let mut cursor = hmtx_offset;
@@ -186,13 +208,19 @@ pub(crate) fn parse_horizontal_metrics(parser: &FontParser) -> Vec<LongHorMetric
186208
let glyph_metric = LongHorMetric::from_in_place_buf(parser.read_with_cursor(&mut cursor));
187209
glyph_metrics.push(glyph_metric);
188210
}
189-
glyph_metrics
211+
FontGlobalLayoutMetrics {
212+
ascent: hhea.ascent,
213+
descent: hhea.descent,
214+
line_gap: hhea.line_gap,
215+
long_hor_metrics: glyph_metrics,
216+
}
190217
}
191218

192219
pub(crate) fn parse_vertical_metrics(
193220
parser: &FontParser,
194221
glyph_count: usize,
195222
) -> Option<Vec<VerticalMetrics>> {
223+
//println!("Vmtx table {:?}", parser.table_headers.get("vmtx"));
196224
let vmtx_offset = match parser.table_headers.get("vmtx") {
197225
None => return None,
198226
Some(vmtx_header) => vmtx_header.offset,

0 commit comments

Comments
 (0)