skrifa/outline/autohint/hint/
mod.rs
1mod edges;
4mod outline;
5
6use super::{
7 metrics::{scale_style_metrics, Scale, UnscaledStyleMetrics},
8 outline::Outline,
9 style::{GlyphStyle, ScriptGroup},
10 topo::{self, Axis},
11};
12
13#[derive(Copy, Clone, PartialEq, Default, Debug)]
16pub(crate) struct EdgeMetrics {
17 pub left_opos: i32,
18 pub left_pos: i32,
19 pub right_opos: i32,
20 pub right_pos: i32,
21}
22
23#[derive(Copy, Clone, PartialEq, Default, Debug)]
24pub(crate) struct HintedMetrics {
25 pub x_scale: i32,
26 pub edge_metrics: Option<EdgeMetrics>,
31}
32
33pub(crate) fn hint_outline(
37 outline: &mut Outline,
38 metrics: &UnscaledStyleMetrics,
39 scale: &Scale,
40 glyph_style: Option<GlyphStyle>,
41) -> HintedMetrics {
42 let scaled_metrics = scale_style_metrics(metrics, *scale);
43 let scale = &scaled_metrics.scale;
44 let mut axis = Axis::default();
45 let hint_top_to_bottom = metrics.style_class().script.hint_top_to_bottom;
46 outline.scale(&scaled_metrics.scale);
47 let mut hinted_metrics = HintedMetrics {
48 x_scale: scale.x_scale,
49 ..Default::default()
50 };
51 let group = metrics.style_class().script.group;
52 if group == ScriptGroup::Default && scaled_metrics.axes[1].blues.is_empty() {
56 return hinted_metrics;
57 }
58 for dim in 0..2 {
59 if (dim == Axis::HORIZONTAL && scale.flags & Scale::NO_HORIZONTAL != 0)
60 || (dim == Axis::VERTICAL && scale.flags & Scale::NO_VERTICAL != 0)
61 {
62 continue;
63 }
64 axis.reset(dim, outline.orientation);
65 topo::compute_segments(outline, &mut axis, group);
66 topo::link_segments(
67 outline,
68 &mut axis,
69 scaled_metrics.axes[dim].scale,
70 group,
71 metrics.axes[dim].max_width(),
72 );
73 topo::compute_edges(
74 &mut axis,
75 &scaled_metrics.axes[dim],
76 hint_top_to_bottom,
77 scaled_metrics.scale.y_scale,
78 group,
79 );
80 if dim == Axis::VERTICAL {
81 if group != ScriptGroup::Default
82 || glyph_style
83 .map(|style| !style.is_non_base())
84 .unwrap_or(true)
85 {
86 topo::compute_blue_edges(
87 &mut axis,
88 scale,
89 &metrics.axes[dim].blues,
90 &scaled_metrics.axes[dim].blues,
91 group,
92 );
93 }
94 } else {
95 hinted_metrics.x_scale = scaled_metrics.axes[0].scale;
96 }
97 edges::hint_edges(
98 &mut axis,
99 &scaled_metrics.axes[dim],
100 group,
101 scale,
102 hint_top_to_bottom,
103 );
104 outline::align_edge_points(outline, &axis, group, scale);
105 outline::align_strong_points(outline, &mut axis);
106 outline::align_weak_points(outline, dim);
107 if dim == 0 && axis.edges.len() > 1 {
108 let left = axis.edges.first().unwrap();
109 let right = axis.edges.last().unwrap();
110 hinted_metrics.edge_metrics = Some(EdgeMetrics {
111 left_pos: left.pos,
112 left_opos: left.opos,
113 right_pos: right.pos,
114 right_opos: right.opos,
115 });
116 }
117 }
118 hinted_metrics
119}