2 * Copyright © 2018 Adobe Inc.
4 * This is part of HarfBuzz, a text shaping library.
6 * Permission is hereby granted, without written agreement and without
7 * license or royalty fees, to use, copy, modify, and distribute this
8 * software and its documentation for any purpose, provided that the
9 * above copyright notice and the following two paragraphs appear in
10 * all copies of this software.
12 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
13 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
14 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
15 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
18 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
19 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20 * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
21 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
22 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
24 * Adobe Author(s): Michiharu Ariza
29 #ifndef HB_NO_OT_FONT_CFF
31 #include "hb-ot-cff2-table.hh"
32 #include "hb-cff2-interp-cs.hh"
37 struct cff2_extents_param_t
42 min_x.set_int (INT_MAX);
43 min_y.set_int (INT_MAX);
44 max_x.set_int (INT_MIN);
45 max_y.set_int (INT_MIN);
48 void start_path () { path_open = true; }
49 void end_path () { path_open = false; }
50 bool is_path_open () const { return path_open; }
52 void update_bounds (const point_t &pt)
54 if (pt.x < min_x) min_x = pt.x;
55 if (pt.x > max_x) max_x = pt.x;
56 if (pt.y < min_y) min_y = pt.y;
57 if (pt.y > max_y) max_y = pt.y;
67 struct cff2_path_procs_extents_t : path_procs_t<cff2_path_procs_extents_t, cff2_cs_interp_env_t, cff2_extents_param_t>
69 static void moveto (cff2_cs_interp_env_t &env, cff2_extents_param_t& param, const point_t &pt)
75 static void line (cff2_cs_interp_env_t &env, cff2_extents_param_t& param, const point_t &pt1)
77 if (!param.is_path_open ())
80 param.update_bounds (env.get_pt ());
83 param.update_bounds (env.get_pt ());
86 static void curve (cff2_cs_interp_env_t &env, cff2_extents_param_t& param, const point_t &pt1, const point_t &pt2, const point_t &pt3)
88 if (!param.is_path_open ())
91 param.update_bounds (env.get_pt ());
93 /* include control points */
94 param.update_bounds (pt1);
95 param.update_bounds (pt2);
97 param.update_bounds (env.get_pt ());
101 struct cff2_cs_opset_extents_t : cff2_cs_opset_t<cff2_cs_opset_extents_t, cff2_extents_param_t, cff2_path_procs_extents_t> {};
103 bool OT::cff2::accelerator_t::get_extents (hb_font_t *font,
104 hb_codepoint_t glyph,
105 hb_glyph_extents_t *extents) const
107 #ifdef HB_NO_OT_FONT_CFF
108 /* XXX Remove check when this code moves to .hh file. */
112 if (unlikely (!is_valid () || (glyph >= num_glyphs))) return false;
114 unsigned int fd = fdSelect->get_fd (glyph);
115 cff2_cs_interpreter_t<cff2_cs_opset_extents_t, cff2_extents_param_t> interp;
116 const byte_str_t str = (*charStrings)[glyph];
117 interp.env.init (str, *this, fd, font->coords, font->num_coords);
118 cff2_extents_param_t param;
120 if (unlikely (!interp.interpret (param))) return false;
122 if (param.min_x >= param.max_x)
125 extents->x_bearing = 0;
129 extents->x_bearing = font->em_scalef_x (param.min_x.to_real ());
130 extents->width = font->em_scalef_x (param.max_x.to_real () - param.min_x.to_real ());
132 if (param.min_y >= param.max_y)
135 extents->y_bearing = 0;
139 extents->y_bearing = font->em_scalef_y (param.max_y.to_real ());
140 extents->height = font->em_scalef_y (param.min_y.to_real () - param.max_y.to_real ());
146 #ifdef HB_EXPERIMENTAL_API
147 struct cff2_path_param_t
149 cff2_path_param_t (hb_font_t *font_, draw_helper_t &draw_helper_)
151 draw_helper = &draw_helper_;
155 void move_to (const point_t &p)
156 { draw_helper->move_to (font->em_scalef_x (p.x.to_real ()), font->em_scalef_y (p.y.to_real ())); }
158 void line_to (const point_t &p)
159 { draw_helper->line_to (font->em_scalef_x (p.x.to_real ()), font->em_scalef_y (p.y.to_real ())); }
161 void cubic_to (const point_t &p1, const point_t &p2, const point_t &p3)
163 draw_helper->cubic_to (font->em_scalef_x (p1.x.to_real ()), font->em_scalef_y (p1.y.to_real ()),
164 font->em_scalef_x (p2.x.to_real ()), font->em_scalef_y (p2.y.to_real ()),
165 font->em_scalef_x (p3.x.to_real ()), font->em_scalef_y (p3.y.to_real ()));
169 draw_helper_t *draw_helper;
173 struct cff2_path_procs_path_t : path_procs_t<cff2_path_procs_path_t, cff2_cs_interp_env_t, cff2_path_param_t>
175 static void moveto (cff2_cs_interp_env_t &env, cff2_path_param_t& param, const point_t &pt)
181 static void line (cff2_cs_interp_env_t &env, cff2_path_param_t& param, const point_t &pt1)
187 static void curve (cff2_cs_interp_env_t &env, cff2_path_param_t& param, const point_t &pt1, const point_t &pt2, const point_t &pt3)
189 param.cubic_to (pt1, pt2, pt3);
194 struct cff2_cs_opset_path_t : cff2_cs_opset_t<cff2_cs_opset_path_t, cff2_path_param_t, cff2_path_procs_path_t> {};
196 bool OT::cff2::accelerator_t::get_path (hb_font_t *font, hb_codepoint_t glyph, draw_helper_t &draw_helper) const
198 #ifdef HB_NO_OT_FONT_CFF
199 /* XXX Remove check when this code moves to .hh file. */
203 if (unlikely (!is_valid () || (glyph >= num_glyphs))) return false;
205 unsigned int fd = fdSelect->get_fd (glyph);
206 cff2_cs_interpreter_t<cff2_cs_opset_path_t, cff2_path_param_t> interp;
207 const byte_str_t str = (*charStrings)[glyph];
208 interp.env.init (str, *this, fd, font->coords, font->num_coords);
209 cff2_path_param_t param (font, draw_helper);
210 if (unlikely (!interp.interpret (param))) return false;