comparison mupdf-source/thirdparty/harfbuzz/src/OT/glyf/path-builder.hh @ 2:b50eed0cc0ef upstream

ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4. The directory name has changed: no version number in the expanded directory now.
author Franz Glasner <fzglas.hg@dom66.de>
date Mon, 15 Sep 2025 11:43:07 +0200
parents
children
comparison
equal deleted inserted replaced
1:1d09e1dec1d9 2:b50eed0cc0ef
1 #ifndef OT_GLYF_PATH_BUILDER_HH
2 #define OT_GLYF_PATH_BUILDER_HH
3
4
5 #include "../../hb.hh"
6
7
8 namespace OT {
9 namespace glyf_impl {
10
11
12 struct path_builder_t
13 {
14 hb_font_t *font;
15 hb_draw_session_t *draw_session;
16
17 struct optional_point_t
18 {
19 optional_point_t () {}
20 optional_point_t (float x_, float y_) : has_data (true), x (x_), y (y_) {}
21 operator bool () const { return has_data; }
22
23 bool has_data = false;
24 float x = 0.;
25 float y = 0.;
26
27 optional_point_t lerp (optional_point_t p, float t)
28 { return optional_point_t (x + t * (p.x - x), y + t * (p.y - y)); }
29 } first_oncurve, first_offcurve, last_offcurve;
30
31 path_builder_t (hb_font_t *font_, hb_draw_session_t &draw_session_)
32 {
33 font = font_;
34 draw_session = &draw_session_;
35 first_oncurve = first_offcurve = last_offcurve = optional_point_t ();
36 }
37
38 /* based on https://github.com/RazrFalcon/ttf-parser/blob/4f32821/src/glyf.rs#L287
39 See also:
40 * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM01/Chap1.html
41 * https://stackoverflow.com/a/20772557 */
42 void consume_point (const contour_point_t &point)
43 {
44 bool is_on_curve = point.flag & glyf_impl::SimpleGlyph::FLAG_ON_CURVE;
45 optional_point_t p (font->em_fscalef_x (point.x), font->em_fscalef_y (point.y));
46 if (!first_oncurve)
47 {
48 if (is_on_curve)
49 {
50 first_oncurve = p;
51 draw_session->move_to (p.x, p.y);
52 }
53 else
54 {
55 if (first_offcurve)
56 {
57 optional_point_t mid = first_offcurve.lerp (p, .5f);
58 first_oncurve = mid;
59 last_offcurve = p;
60 draw_session->move_to (mid.x, mid.y);
61 }
62 else
63 first_offcurve = p;
64 }
65 }
66 else
67 {
68 if (last_offcurve)
69 {
70 if (is_on_curve)
71 {
72 draw_session->quadratic_to (last_offcurve.x, last_offcurve.y,
73 p.x, p.y);
74 last_offcurve = optional_point_t ();
75 }
76 else
77 {
78 optional_point_t mid = last_offcurve.lerp (p, .5f);
79 draw_session->quadratic_to (last_offcurve.x, last_offcurve.y,
80 mid.x, mid.y);
81 last_offcurve = p;
82 }
83 }
84 else
85 {
86 if (is_on_curve)
87 draw_session->line_to (p.x, p.y);
88 else
89 last_offcurve = p;
90 }
91 }
92
93 if (point.is_end_point)
94 {
95 if (first_offcurve && last_offcurve)
96 {
97 optional_point_t mid = last_offcurve.lerp (first_offcurve, .5f);
98 draw_session->quadratic_to (last_offcurve.x, last_offcurve.y,
99 mid.x, mid.y);
100 last_offcurve = optional_point_t ();
101 /* now check the rest */
102 }
103
104 if (first_offcurve && first_oncurve)
105 draw_session->quadratic_to (first_offcurve.x, first_offcurve.y,
106 first_oncurve.x, first_oncurve.y);
107 else if (last_offcurve && first_oncurve)
108 draw_session->quadratic_to (last_offcurve.x, last_offcurve.y,
109 first_oncurve.x, first_oncurve.y);
110 else if (first_oncurve)
111 draw_session->line_to (first_oncurve.x, first_oncurve.y);
112 else if (first_offcurve)
113 {
114 float x = first_offcurve.x, y = first_offcurve.y;
115 draw_session->move_to (x, y);
116 draw_session->quadratic_to (x, y, x, y);
117 }
118
119 /* Getting ready for the next contour */
120 first_oncurve = first_offcurve = last_offcurve = optional_point_t ();
121 draw_session->close_path ();
122 }
123 }
124 void points_end () {}
125
126 bool is_consuming_contour_points () { return true; }
127 contour_point_t *get_phantoms_sink () { return nullptr; }
128 };
129
130
131 } /* namespace glyf_impl */
132 } /* namespace OT */
133
134
135 #endif /* OT_GLYF_PATH_BUILDER_HH */