harfrust/hb/ot/gpos/
mod.rs1use crate::hb::ot_layout_gsubgpos::OT::hb_ot_apply_context_t;
4use read_fonts::{
5 tables::{gpos::ValueFormat, variations::DeltaSetIndex},
6 FontData,
7};
8
9mod cursive;
10mod mark;
11mod pair;
12mod single;
13
14#[allow(unused_assignments)]
15fn apply_value(
16 ctx: &mut hb_ot_apply_context_t,
17 idx: usize,
18 data: &FontData,
19 mut offset: usize,
20 format: ValueFormat,
21) -> Option<bool> {
22 let scale = ctx.scale;
23 let pos = &mut ctx.buffer.pos[idx];
24 let is_horizontal = ctx.buffer.direction.is_horizontal();
25 let mut worked = false;
26 macro_rules! read_value {
27 () => {{
28 let value = data.read_at::<i16>(offset).ok()? as i32;
29 worked |= value != 0;
30 offset += 2;
31 value
32 }};
33 }
34 if format.contains(ValueFormat::X_PLACEMENT) {
35 pos.x_offset += scale.scale_x(read_value!());
36 }
37 if format.contains(ValueFormat::Y_PLACEMENT) {
38 pos.y_offset += scale.scale_y(read_value!());
39 }
40 if format.contains(ValueFormat::X_ADVANCE) {
41 if is_horizontal {
42 pos.x_advance += scale.scale_x(read_value!());
43 } else {
44 offset += 2;
45 }
46 }
47 if format.contains(ValueFormat::Y_ADVANCE) {
48 if !is_horizontal {
49 pos.y_advance -= scale.scale_y(read_value!());
50 } else {
51 offset += 2;
52 }
53 }
54 if !format.intersects(ValueFormat::ANY_DEVICE_OR_VARIDX) {
55 return Some(worked);
56 }
57 if let Some(vs) = &ctx.face.ot_tables.var_store {
58 let coords = ctx.face.ot_tables.coords;
59 macro_rules! read_delta {
60 () => {{
61 let rec_offset = data.read_at::<u16>(offset).ok()? as usize;
62 offset += 2;
63 let mut value = 0.0f32;
67 if rec_offset != 0 {
69 let format = data.read_at::<u16>(rec_offset + 4).ok()?;
70 const VARIATION_INDEX_FORMAT: u16 = 0x8000;
73 if format == VARIATION_INDEX_FORMAT {
74 let outer = data.read_at::<u16>(rec_offset).ok()?;
75 let inner = data.read_at::<u16>(rec_offset + 2).ok()?;
76 value = vs
77 .compute_float_delta(DeltaSetIndex { outer, inner }, coords)
78 .unwrap_or_default()
79 .to_f64() as f32;
80 worked |= value != 0.0;
81 }
82 }
83 value
84 }};
85 }
86 if format.contains(ValueFormat::X_PLACEMENT_DEVICE) {
87 pos.x_offset += scale.scale_x_f(read_delta!());
88 }
89 if format.contains(ValueFormat::Y_PLACEMENT_DEVICE) {
90 pos.y_offset += scale.scale_y_f(read_delta!());
91 }
92 if format.contains(ValueFormat::X_ADVANCE_DEVICE) {
93 if is_horizontal {
94 pos.x_advance += scale.scale_x_f(read_delta!());
95 } else {
96 offset += 2;
97 }
98 }
99 if format.contains(ValueFormat::Y_ADVANCE_DEVICE) {
100 if !is_horizontal {
101 pos.y_advance -= scale.scale_y_f(read_delta!());
102 } else {
103 offset += 2;
104 }
105 }
106 }
107 Some(worked)
108}