xref: /aosp_15_r20/external/harfbuzz_ng/src/hb-ot-font.cc (revision 2d1272b857b1f7575e6e246373e1cb218663db8a)
1*2d1272b8SAndroid Build Coastguard Worker /*
2*2d1272b8SAndroid Build Coastguard Worker  * Copyright © 2011,2014  Google, Inc.
3*2d1272b8SAndroid Build Coastguard Worker  *
4*2d1272b8SAndroid Build Coastguard Worker  *  This is part of HarfBuzz, a text shaping library.
5*2d1272b8SAndroid Build Coastguard Worker  *
6*2d1272b8SAndroid Build Coastguard Worker  * Permission is hereby granted, without written agreement and without
7*2d1272b8SAndroid Build Coastguard Worker  * license or royalty fees, to use, copy, modify, and distribute this
8*2d1272b8SAndroid Build Coastguard Worker  * software and its documentation for any purpose, provided that the
9*2d1272b8SAndroid Build Coastguard Worker  * above copyright notice and the following two paragraphs appear in
10*2d1272b8SAndroid Build Coastguard Worker  * all copies of this software.
11*2d1272b8SAndroid Build Coastguard Worker  *
12*2d1272b8SAndroid Build Coastguard Worker  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
13*2d1272b8SAndroid Build Coastguard Worker  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
14*2d1272b8SAndroid Build Coastguard Worker  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
15*2d1272b8SAndroid Build Coastguard Worker  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
16*2d1272b8SAndroid Build Coastguard Worker  * DAMAGE.
17*2d1272b8SAndroid Build Coastguard Worker  *
18*2d1272b8SAndroid Build Coastguard Worker  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
19*2d1272b8SAndroid Build Coastguard Worker  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20*2d1272b8SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
21*2d1272b8SAndroid Build Coastguard Worker  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
22*2d1272b8SAndroid Build Coastguard Worker  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
23*2d1272b8SAndroid Build Coastguard Worker  *
24*2d1272b8SAndroid Build Coastguard Worker  * Google Author(s): Behdad Esfahbod, Roozbeh Pournader
25*2d1272b8SAndroid Build Coastguard Worker  */
26*2d1272b8SAndroid Build Coastguard Worker 
27*2d1272b8SAndroid Build Coastguard Worker #include "hb.hh"
28*2d1272b8SAndroid Build Coastguard Worker 
29*2d1272b8SAndroid Build Coastguard Worker #ifndef HB_NO_OT_FONT
30*2d1272b8SAndroid Build Coastguard Worker 
31*2d1272b8SAndroid Build Coastguard Worker #include "hb-ot.h"
32*2d1272b8SAndroid Build Coastguard Worker 
33*2d1272b8SAndroid Build Coastguard Worker #include "hb-cache.hh"
34*2d1272b8SAndroid Build Coastguard Worker #include "hb-font.hh"
35*2d1272b8SAndroid Build Coastguard Worker #include "hb-machinery.hh"
36*2d1272b8SAndroid Build Coastguard Worker #include "hb-ot-face.hh"
37*2d1272b8SAndroid Build Coastguard Worker #include "hb-outline.hh"
38*2d1272b8SAndroid Build Coastguard Worker 
39*2d1272b8SAndroid Build Coastguard Worker #include "hb-ot-cmap-table.hh"
40*2d1272b8SAndroid Build Coastguard Worker #include "hb-ot-glyf-table.hh"
41*2d1272b8SAndroid Build Coastguard Worker #include "hb-ot-cff2-table.hh"
42*2d1272b8SAndroid Build Coastguard Worker #include "hb-ot-cff1-table.hh"
43*2d1272b8SAndroid Build Coastguard Worker #include "hb-ot-hmtx-table.hh"
44*2d1272b8SAndroid Build Coastguard Worker #include "hb-ot-post-table.hh"
45*2d1272b8SAndroid Build Coastguard Worker #include "hb-ot-stat-table.hh" // Just so we compile it; unused otherwise.
46*2d1272b8SAndroid Build Coastguard Worker #include "hb-ot-var-varc-table.hh"
47*2d1272b8SAndroid Build Coastguard Worker #include "hb-ot-vorg-table.hh"
48*2d1272b8SAndroid Build Coastguard Worker #include "OT/Color/CBDT/CBDT.hh"
49*2d1272b8SAndroid Build Coastguard Worker #include "OT/Color/COLR/COLR.hh"
50*2d1272b8SAndroid Build Coastguard Worker #include "OT/Color/sbix/sbix.hh"
51*2d1272b8SAndroid Build Coastguard Worker #include "OT/Color/svg/svg.hh"
52*2d1272b8SAndroid Build Coastguard Worker 
53*2d1272b8SAndroid Build Coastguard Worker 
54*2d1272b8SAndroid Build Coastguard Worker /**
55*2d1272b8SAndroid Build Coastguard Worker  * SECTION:hb-ot-font
56*2d1272b8SAndroid Build Coastguard Worker  * @title: hb-ot-font
57*2d1272b8SAndroid Build Coastguard Worker  * @short_description: OpenType font implementation
58*2d1272b8SAndroid Build Coastguard Worker  * @include: hb-ot.h
59*2d1272b8SAndroid Build Coastguard Worker  *
60*2d1272b8SAndroid Build Coastguard Worker  * Functions for using OpenType fonts with hb_shape().  Note that fonts returned
61*2d1272b8SAndroid Build Coastguard Worker  * by hb_font_create() default to using these functions, so most clients would
62*2d1272b8SAndroid Build Coastguard Worker  * never need to call these functions directly.
63*2d1272b8SAndroid Build Coastguard Worker  **/
64*2d1272b8SAndroid Build Coastguard Worker 
65*2d1272b8SAndroid Build Coastguard Worker using hb_ot_font_cmap_cache_t    = hb_cache_t<21, 16, 8, true>;
66*2d1272b8SAndroid Build Coastguard Worker using hb_ot_font_advance_cache_t = hb_cache_t<24, 16, 8, true>;
67*2d1272b8SAndroid Build Coastguard Worker 
68*2d1272b8SAndroid Build Coastguard Worker #ifndef HB_NO_OT_FONT_CMAP_CACHE
69*2d1272b8SAndroid Build Coastguard Worker static hb_user_data_key_t hb_ot_font_cmap_cache_user_data_key;
70*2d1272b8SAndroid Build Coastguard Worker #endif
71*2d1272b8SAndroid Build Coastguard Worker 
72*2d1272b8SAndroid Build Coastguard Worker struct hb_ot_font_t
73*2d1272b8SAndroid Build Coastguard Worker {
74*2d1272b8SAndroid Build Coastguard Worker   const hb_ot_face_t *ot_face;
75*2d1272b8SAndroid Build Coastguard Worker 
76*2d1272b8SAndroid Build Coastguard Worker #ifndef HB_NO_OT_FONT_CMAP_CACHE
77*2d1272b8SAndroid Build Coastguard Worker   hb_ot_font_cmap_cache_t *cmap_cache;
78*2d1272b8SAndroid Build Coastguard Worker #endif
79*2d1272b8SAndroid Build Coastguard Worker 
80*2d1272b8SAndroid Build Coastguard Worker   /* h_advance caching */
81*2d1272b8SAndroid Build Coastguard Worker   mutable hb_atomic_int_t cached_coords_serial;
82*2d1272b8SAndroid Build Coastguard Worker   mutable hb_atomic_ptr_t<hb_ot_font_advance_cache_t> advance_cache;
83*2d1272b8SAndroid Build Coastguard Worker };
84*2d1272b8SAndroid Build Coastguard Worker 
85*2d1272b8SAndroid Build Coastguard Worker static hb_ot_font_t *
_hb_ot_font_create(hb_font_t * font)86*2d1272b8SAndroid Build Coastguard Worker _hb_ot_font_create (hb_font_t *font)
87*2d1272b8SAndroid Build Coastguard Worker {
88*2d1272b8SAndroid Build Coastguard Worker   hb_ot_font_t *ot_font = (hb_ot_font_t *) hb_calloc (1, sizeof (hb_ot_font_t));
89*2d1272b8SAndroid Build Coastguard Worker   if (unlikely (!ot_font))
90*2d1272b8SAndroid Build Coastguard Worker     return nullptr;
91*2d1272b8SAndroid Build Coastguard Worker 
92*2d1272b8SAndroid Build Coastguard Worker   ot_font->ot_face = &font->face->table;
93*2d1272b8SAndroid Build Coastguard Worker 
94*2d1272b8SAndroid Build Coastguard Worker #ifndef HB_NO_OT_FONT_CMAP_CACHE
95*2d1272b8SAndroid Build Coastguard Worker   // retry:
96*2d1272b8SAndroid Build Coastguard Worker   auto *cmap_cache  = (hb_ot_font_cmap_cache_t *) hb_face_get_user_data (font->face,
97*2d1272b8SAndroid Build Coastguard Worker 									 &hb_ot_font_cmap_cache_user_data_key);
98*2d1272b8SAndroid Build Coastguard Worker   if (!cmap_cache)
99*2d1272b8SAndroid Build Coastguard Worker   {
100*2d1272b8SAndroid Build Coastguard Worker     cmap_cache = (hb_ot_font_cmap_cache_t *) hb_malloc (sizeof (hb_ot_font_cmap_cache_t));
101*2d1272b8SAndroid Build Coastguard Worker     if (unlikely (!cmap_cache)) goto out;
102*2d1272b8SAndroid Build Coastguard Worker     new (cmap_cache) hb_ot_font_cmap_cache_t ();
103*2d1272b8SAndroid Build Coastguard Worker     if (unlikely (!hb_face_set_user_data (font->face,
104*2d1272b8SAndroid Build Coastguard Worker 					  &hb_ot_font_cmap_cache_user_data_key,
105*2d1272b8SAndroid Build Coastguard Worker 					  cmap_cache,
106*2d1272b8SAndroid Build Coastguard Worker 					  hb_free,
107*2d1272b8SAndroid Build Coastguard Worker 					  false)))
108*2d1272b8SAndroid Build Coastguard Worker     {
109*2d1272b8SAndroid Build Coastguard Worker       hb_free (cmap_cache);
110*2d1272b8SAndroid Build Coastguard Worker       cmap_cache = nullptr;
111*2d1272b8SAndroid Build Coastguard Worker       /* Normally we would retry here, but that would
112*2d1272b8SAndroid Build Coastguard Worker        * infinite-loop if the face is the empty-face.
113*2d1272b8SAndroid Build Coastguard Worker        * Just let it go and this font will be uncached if it
114*2d1272b8SAndroid Build Coastguard Worker        * happened to collide with another thread creating the
115*2d1272b8SAndroid Build Coastguard Worker        * cache at the same time. */
116*2d1272b8SAndroid Build Coastguard Worker       // goto retry;
117*2d1272b8SAndroid Build Coastguard Worker     }
118*2d1272b8SAndroid Build Coastguard Worker   }
119*2d1272b8SAndroid Build Coastguard Worker   out:
120*2d1272b8SAndroid Build Coastguard Worker   ot_font->cmap_cache = cmap_cache;
121*2d1272b8SAndroid Build Coastguard Worker #endif
122*2d1272b8SAndroid Build Coastguard Worker 
123*2d1272b8SAndroid Build Coastguard Worker   return ot_font;
124*2d1272b8SAndroid Build Coastguard Worker }
125*2d1272b8SAndroid Build Coastguard Worker 
126*2d1272b8SAndroid Build Coastguard Worker static void
_hb_ot_font_destroy(void * font_data)127*2d1272b8SAndroid Build Coastguard Worker _hb_ot_font_destroy (void *font_data)
128*2d1272b8SAndroid Build Coastguard Worker {
129*2d1272b8SAndroid Build Coastguard Worker   hb_ot_font_t *ot_font = (hb_ot_font_t *) font_data;
130*2d1272b8SAndroid Build Coastguard Worker 
131*2d1272b8SAndroid Build Coastguard Worker   auto *cache = ot_font->advance_cache.get_relaxed ();
132*2d1272b8SAndroid Build Coastguard Worker   hb_free (cache);
133*2d1272b8SAndroid Build Coastguard Worker 
134*2d1272b8SAndroid Build Coastguard Worker   hb_free (ot_font);
135*2d1272b8SAndroid Build Coastguard Worker }
136*2d1272b8SAndroid Build Coastguard Worker 
137*2d1272b8SAndroid Build Coastguard Worker static hb_bool_t
hb_ot_get_nominal_glyph(hb_font_t * font HB_UNUSED,void * font_data,hb_codepoint_t unicode,hb_codepoint_t * glyph,void * user_data HB_UNUSED)138*2d1272b8SAndroid Build Coastguard Worker hb_ot_get_nominal_glyph (hb_font_t *font HB_UNUSED,
139*2d1272b8SAndroid Build Coastguard Worker 			 void *font_data,
140*2d1272b8SAndroid Build Coastguard Worker 			 hb_codepoint_t unicode,
141*2d1272b8SAndroid Build Coastguard Worker 			 hb_codepoint_t *glyph,
142*2d1272b8SAndroid Build Coastguard Worker 			 void *user_data HB_UNUSED)
143*2d1272b8SAndroid Build Coastguard Worker {
144*2d1272b8SAndroid Build Coastguard Worker   const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
145*2d1272b8SAndroid Build Coastguard Worker   const hb_ot_face_t *ot_face = ot_font->ot_face;
146*2d1272b8SAndroid Build Coastguard Worker   hb_ot_font_cmap_cache_t *cmap_cache = nullptr;
147*2d1272b8SAndroid Build Coastguard Worker #ifndef HB_NO_OT_FONT_CMAP_CACHE
148*2d1272b8SAndroid Build Coastguard Worker   cmap_cache = ot_font->cmap_cache;
149*2d1272b8SAndroid Build Coastguard Worker #endif
150*2d1272b8SAndroid Build Coastguard Worker   return ot_face->cmap->get_nominal_glyph (unicode, glyph, cmap_cache);
151*2d1272b8SAndroid Build Coastguard Worker }
152*2d1272b8SAndroid Build Coastguard Worker 
153*2d1272b8SAndroid Build Coastguard Worker static unsigned int
hb_ot_get_nominal_glyphs(hb_font_t * font HB_UNUSED,void * font_data,unsigned int count,const hb_codepoint_t * first_unicode,unsigned int unicode_stride,hb_codepoint_t * first_glyph,unsigned int glyph_stride,void * user_data HB_UNUSED)154*2d1272b8SAndroid Build Coastguard Worker hb_ot_get_nominal_glyphs (hb_font_t *font HB_UNUSED,
155*2d1272b8SAndroid Build Coastguard Worker 			  void *font_data,
156*2d1272b8SAndroid Build Coastguard Worker 			  unsigned int count,
157*2d1272b8SAndroid Build Coastguard Worker 			  const hb_codepoint_t *first_unicode,
158*2d1272b8SAndroid Build Coastguard Worker 			  unsigned int unicode_stride,
159*2d1272b8SAndroid Build Coastguard Worker 			  hb_codepoint_t *first_glyph,
160*2d1272b8SAndroid Build Coastguard Worker 			  unsigned int glyph_stride,
161*2d1272b8SAndroid Build Coastguard Worker 			  void *user_data HB_UNUSED)
162*2d1272b8SAndroid Build Coastguard Worker {
163*2d1272b8SAndroid Build Coastguard Worker   const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
164*2d1272b8SAndroid Build Coastguard Worker   const hb_ot_face_t *ot_face = ot_font->ot_face;
165*2d1272b8SAndroid Build Coastguard Worker   hb_ot_font_cmap_cache_t *cmap_cache = nullptr;
166*2d1272b8SAndroid Build Coastguard Worker #ifndef HB_NO_OT_FONT_CMAP_CACHE
167*2d1272b8SAndroid Build Coastguard Worker   cmap_cache = ot_font->cmap_cache;
168*2d1272b8SAndroid Build Coastguard Worker #endif
169*2d1272b8SAndroid Build Coastguard Worker   return ot_face->cmap->get_nominal_glyphs (count,
170*2d1272b8SAndroid Build Coastguard Worker 					    first_unicode, unicode_stride,
171*2d1272b8SAndroid Build Coastguard Worker 					    first_glyph, glyph_stride,
172*2d1272b8SAndroid Build Coastguard Worker 					    cmap_cache);
173*2d1272b8SAndroid Build Coastguard Worker }
174*2d1272b8SAndroid Build Coastguard Worker 
175*2d1272b8SAndroid Build Coastguard Worker static hb_bool_t
hb_ot_get_variation_glyph(hb_font_t * font HB_UNUSED,void * font_data,hb_codepoint_t unicode,hb_codepoint_t variation_selector,hb_codepoint_t * glyph,void * user_data HB_UNUSED)176*2d1272b8SAndroid Build Coastguard Worker hb_ot_get_variation_glyph (hb_font_t *font HB_UNUSED,
177*2d1272b8SAndroid Build Coastguard Worker 			   void *font_data,
178*2d1272b8SAndroid Build Coastguard Worker 			   hb_codepoint_t unicode,
179*2d1272b8SAndroid Build Coastguard Worker 			   hb_codepoint_t variation_selector,
180*2d1272b8SAndroid Build Coastguard Worker 			   hb_codepoint_t *glyph,
181*2d1272b8SAndroid Build Coastguard Worker 			   void *user_data HB_UNUSED)
182*2d1272b8SAndroid Build Coastguard Worker {
183*2d1272b8SAndroid Build Coastguard Worker   const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
184*2d1272b8SAndroid Build Coastguard Worker   const hb_ot_face_t *ot_face = ot_font->ot_face;
185*2d1272b8SAndroid Build Coastguard Worker   hb_ot_font_cmap_cache_t *cmap_cache = nullptr;
186*2d1272b8SAndroid Build Coastguard Worker #ifndef HB_NO_OT_FONT_CMAP_CACHE
187*2d1272b8SAndroid Build Coastguard Worker   cmap_cache = ot_font->cmap_cache;
188*2d1272b8SAndroid Build Coastguard Worker #endif
189*2d1272b8SAndroid Build Coastguard Worker   return ot_face->cmap->get_variation_glyph (unicode,
190*2d1272b8SAndroid Build Coastguard Worker                                              variation_selector, glyph,
191*2d1272b8SAndroid Build Coastguard Worker                                              cmap_cache);
192*2d1272b8SAndroid Build Coastguard Worker }
193*2d1272b8SAndroid Build Coastguard Worker 
194*2d1272b8SAndroid Build Coastguard Worker static void
hb_ot_get_glyph_h_advances(hb_font_t * font,void * font_data,unsigned count,const hb_codepoint_t * first_glyph,unsigned glyph_stride,hb_position_t * first_advance,unsigned advance_stride,void * user_data HB_UNUSED)195*2d1272b8SAndroid Build Coastguard Worker hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data,
196*2d1272b8SAndroid Build Coastguard Worker 			    unsigned count,
197*2d1272b8SAndroid Build Coastguard Worker 			    const hb_codepoint_t *first_glyph,
198*2d1272b8SAndroid Build Coastguard Worker 			    unsigned glyph_stride,
199*2d1272b8SAndroid Build Coastguard Worker 			    hb_position_t *first_advance,
200*2d1272b8SAndroid Build Coastguard Worker 			    unsigned advance_stride,
201*2d1272b8SAndroid Build Coastguard Worker 			    void *user_data HB_UNUSED)
202*2d1272b8SAndroid Build Coastguard Worker {
203*2d1272b8SAndroid Build Coastguard Worker 
204*2d1272b8SAndroid Build Coastguard Worker   const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
205*2d1272b8SAndroid Build Coastguard Worker   const hb_ot_face_t *ot_face = ot_font->ot_face;
206*2d1272b8SAndroid Build Coastguard Worker   const OT::hmtx_accelerator_t &hmtx = *ot_face->hmtx;
207*2d1272b8SAndroid Build Coastguard Worker 
208*2d1272b8SAndroid Build Coastguard Worker   hb_position_t *orig_first_advance = first_advance;
209*2d1272b8SAndroid Build Coastguard Worker 
210*2d1272b8SAndroid Build Coastguard Worker #if !defined(HB_NO_VAR) && !defined(HB_NO_OT_FONT_ADVANCE_CACHE)
211*2d1272b8SAndroid Build Coastguard Worker   const OT::HVAR &HVAR = *hmtx.var_table;
212*2d1272b8SAndroid Build Coastguard Worker   const OT::ItemVariationStore &varStore = &HVAR + HVAR.varStore;
213*2d1272b8SAndroid Build Coastguard Worker   OT::ItemVariationStore::cache_t *varStore_cache = font->num_coords * count >= 128 ? varStore.create_cache () : nullptr;
214*2d1272b8SAndroid Build Coastguard Worker 
215*2d1272b8SAndroid Build Coastguard Worker   bool use_cache = font->num_coords;
216*2d1272b8SAndroid Build Coastguard Worker #else
217*2d1272b8SAndroid Build Coastguard Worker   OT::ItemVariationStore::cache_t *varStore_cache = nullptr;
218*2d1272b8SAndroid Build Coastguard Worker   bool use_cache = false;
219*2d1272b8SAndroid Build Coastguard Worker #endif
220*2d1272b8SAndroid Build Coastguard Worker 
221*2d1272b8SAndroid Build Coastguard Worker   hb_ot_font_advance_cache_t *cache = nullptr;
222*2d1272b8SAndroid Build Coastguard Worker   if (use_cache)
223*2d1272b8SAndroid Build Coastguard Worker   {
224*2d1272b8SAndroid Build Coastguard Worker   retry:
225*2d1272b8SAndroid Build Coastguard Worker     cache = ot_font->advance_cache.get_acquire ();
226*2d1272b8SAndroid Build Coastguard Worker     if (unlikely (!cache))
227*2d1272b8SAndroid Build Coastguard Worker     {
228*2d1272b8SAndroid Build Coastguard Worker       cache = (hb_ot_font_advance_cache_t *) hb_malloc (sizeof (hb_ot_font_advance_cache_t));
229*2d1272b8SAndroid Build Coastguard Worker       if (unlikely (!cache))
230*2d1272b8SAndroid Build Coastguard Worker       {
231*2d1272b8SAndroid Build Coastguard Worker 	use_cache = false;
232*2d1272b8SAndroid Build Coastguard Worker 	goto out;
233*2d1272b8SAndroid Build Coastguard Worker       }
234*2d1272b8SAndroid Build Coastguard Worker       new (cache) hb_ot_font_advance_cache_t;
235*2d1272b8SAndroid Build Coastguard Worker 
236*2d1272b8SAndroid Build Coastguard Worker       if (unlikely (!ot_font->advance_cache.cmpexch (nullptr, cache)))
237*2d1272b8SAndroid Build Coastguard Worker       {
238*2d1272b8SAndroid Build Coastguard Worker 	hb_free (cache);
239*2d1272b8SAndroid Build Coastguard Worker 	goto retry;
240*2d1272b8SAndroid Build Coastguard Worker       }
241*2d1272b8SAndroid Build Coastguard Worker       ot_font->cached_coords_serial.set_release (font->serial_coords);
242*2d1272b8SAndroid Build Coastguard Worker     }
243*2d1272b8SAndroid Build Coastguard Worker   }
244*2d1272b8SAndroid Build Coastguard Worker   out:
245*2d1272b8SAndroid Build Coastguard Worker 
246*2d1272b8SAndroid Build Coastguard Worker   if (!use_cache)
247*2d1272b8SAndroid Build Coastguard Worker   {
248*2d1272b8SAndroid Build Coastguard Worker     for (unsigned int i = 0; i < count; i++)
249*2d1272b8SAndroid Build Coastguard Worker     {
250*2d1272b8SAndroid Build Coastguard Worker       *first_advance = font->em_scale_x (hmtx.get_advance_with_var_unscaled (*first_glyph, font, varStore_cache));
251*2d1272b8SAndroid Build Coastguard Worker       first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
252*2d1272b8SAndroid Build Coastguard Worker       first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
253*2d1272b8SAndroid Build Coastguard Worker     }
254*2d1272b8SAndroid Build Coastguard Worker   }
255*2d1272b8SAndroid Build Coastguard Worker   else
256*2d1272b8SAndroid Build Coastguard Worker   { /* Use cache. */
257*2d1272b8SAndroid Build Coastguard Worker     if (ot_font->cached_coords_serial.get_acquire () != (int) font->serial_coords)
258*2d1272b8SAndroid Build Coastguard Worker     {
259*2d1272b8SAndroid Build Coastguard Worker       ot_font->advance_cache->clear ();
260*2d1272b8SAndroid Build Coastguard Worker       ot_font->cached_coords_serial.set_release (font->serial_coords);
261*2d1272b8SAndroid Build Coastguard Worker     }
262*2d1272b8SAndroid Build Coastguard Worker 
263*2d1272b8SAndroid Build Coastguard Worker     for (unsigned int i = 0; i < count; i++)
264*2d1272b8SAndroid Build Coastguard Worker     {
265*2d1272b8SAndroid Build Coastguard Worker       hb_position_t v;
266*2d1272b8SAndroid Build Coastguard Worker       unsigned cv;
267*2d1272b8SAndroid Build Coastguard Worker       if (ot_font->advance_cache->get (*first_glyph, &cv))
268*2d1272b8SAndroid Build Coastguard Worker 	v = cv;
269*2d1272b8SAndroid Build Coastguard Worker       else
270*2d1272b8SAndroid Build Coastguard Worker       {
271*2d1272b8SAndroid Build Coastguard Worker         v = hmtx.get_advance_with_var_unscaled (*first_glyph, font, varStore_cache);
272*2d1272b8SAndroid Build Coastguard Worker 	ot_font->advance_cache->set (*first_glyph, v);
273*2d1272b8SAndroid Build Coastguard Worker       }
274*2d1272b8SAndroid Build Coastguard Worker       *first_advance = font->em_scale_x (v);
275*2d1272b8SAndroid Build Coastguard Worker       first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
276*2d1272b8SAndroid Build Coastguard Worker       first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
277*2d1272b8SAndroid Build Coastguard Worker     }
278*2d1272b8SAndroid Build Coastguard Worker   }
279*2d1272b8SAndroid Build Coastguard Worker 
280*2d1272b8SAndroid Build Coastguard Worker #if !defined(HB_NO_VAR) && !defined(HB_NO_OT_FONT_ADVANCE_CACHE)
281*2d1272b8SAndroid Build Coastguard Worker   OT::ItemVariationStore::destroy_cache (varStore_cache);
282*2d1272b8SAndroid Build Coastguard Worker #endif
283*2d1272b8SAndroid Build Coastguard Worker 
284*2d1272b8SAndroid Build Coastguard Worker   if (font->x_strength && !font->embolden_in_place)
285*2d1272b8SAndroid Build Coastguard Worker   {
286*2d1272b8SAndroid Build Coastguard Worker     /* Emboldening. */
287*2d1272b8SAndroid Build Coastguard Worker     hb_position_t x_strength = font->x_scale >= 0 ? font->x_strength : -font->x_strength;
288*2d1272b8SAndroid Build Coastguard Worker     first_advance = orig_first_advance;
289*2d1272b8SAndroid Build Coastguard Worker     for (unsigned int i = 0; i < count; i++)
290*2d1272b8SAndroid Build Coastguard Worker     {
291*2d1272b8SAndroid Build Coastguard Worker       *first_advance += *first_advance ? x_strength : 0;
292*2d1272b8SAndroid Build Coastguard Worker       first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
293*2d1272b8SAndroid Build Coastguard Worker     }
294*2d1272b8SAndroid Build Coastguard Worker   }
295*2d1272b8SAndroid Build Coastguard Worker }
296*2d1272b8SAndroid Build Coastguard Worker 
297*2d1272b8SAndroid Build Coastguard Worker #ifndef HB_NO_VERTICAL
298*2d1272b8SAndroid Build Coastguard Worker static void
hb_ot_get_glyph_v_advances(hb_font_t * font,void * font_data,unsigned count,const hb_codepoint_t * first_glyph,unsigned glyph_stride,hb_position_t * first_advance,unsigned advance_stride,void * user_data HB_UNUSED)299*2d1272b8SAndroid Build Coastguard Worker hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data,
300*2d1272b8SAndroid Build Coastguard Worker 			    unsigned count,
301*2d1272b8SAndroid Build Coastguard Worker 			    const hb_codepoint_t *first_glyph,
302*2d1272b8SAndroid Build Coastguard Worker 			    unsigned glyph_stride,
303*2d1272b8SAndroid Build Coastguard Worker 			    hb_position_t *first_advance,
304*2d1272b8SAndroid Build Coastguard Worker 			    unsigned advance_stride,
305*2d1272b8SAndroid Build Coastguard Worker 			    void *user_data HB_UNUSED)
306*2d1272b8SAndroid Build Coastguard Worker {
307*2d1272b8SAndroid Build Coastguard Worker   const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
308*2d1272b8SAndroid Build Coastguard Worker   const hb_ot_face_t *ot_face = ot_font->ot_face;
309*2d1272b8SAndroid Build Coastguard Worker   const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx;
310*2d1272b8SAndroid Build Coastguard Worker 
311*2d1272b8SAndroid Build Coastguard Worker   hb_position_t *orig_first_advance = first_advance;
312*2d1272b8SAndroid Build Coastguard Worker 
313*2d1272b8SAndroid Build Coastguard Worker   if (vmtx.has_data ())
314*2d1272b8SAndroid Build Coastguard Worker   {
315*2d1272b8SAndroid Build Coastguard Worker #if !defined(HB_NO_VAR) && !defined(HB_NO_OT_FONT_ADVANCE_CACHE)
316*2d1272b8SAndroid Build Coastguard Worker     const OT::VVAR &VVAR = *vmtx.var_table;
317*2d1272b8SAndroid Build Coastguard Worker     const OT::ItemVariationStore &varStore = &VVAR + VVAR.varStore;
318*2d1272b8SAndroid Build Coastguard Worker     OT::ItemVariationStore::cache_t *varStore_cache = font->num_coords ? varStore.create_cache () : nullptr;
319*2d1272b8SAndroid Build Coastguard Worker #else
320*2d1272b8SAndroid Build Coastguard Worker     OT::ItemVariationStore::cache_t *varStore_cache = nullptr;
321*2d1272b8SAndroid Build Coastguard Worker #endif
322*2d1272b8SAndroid Build Coastguard Worker 
323*2d1272b8SAndroid Build Coastguard Worker     for (unsigned int i = 0; i < count; i++)
324*2d1272b8SAndroid Build Coastguard Worker     {
325*2d1272b8SAndroid Build Coastguard Worker       *first_advance = font->em_scale_y (-(int) vmtx.get_advance_with_var_unscaled (*first_glyph, font, varStore_cache));
326*2d1272b8SAndroid Build Coastguard Worker       first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
327*2d1272b8SAndroid Build Coastguard Worker       first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
328*2d1272b8SAndroid Build Coastguard Worker     }
329*2d1272b8SAndroid Build Coastguard Worker 
330*2d1272b8SAndroid Build Coastguard Worker #if !defined(HB_NO_VAR) && !defined(HB_NO_OT_FONT_ADVANCE_CACHE)
331*2d1272b8SAndroid Build Coastguard Worker     OT::ItemVariationStore::destroy_cache (varStore_cache);
332*2d1272b8SAndroid Build Coastguard Worker #endif
333*2d1272b8SAndroid Build Coastguard Worker   }
334*2d1272b8SAndroid Build Coastguard Worker   else
335*2d1272b8SAndroid Build Coastguard Worker   {
336*2d1272b8SAndroid Build Coastguard Worker     hb_font_extents_t font_extents;
337*2d1272b8SAndroid Build Coastguard Worker     font->get_h_extents_with_fallback (&font_extents);
338*2d1272b8SAndroid Build Coastguard Worker     hb_position_t advance = -(font_extents.ascender - font_extents.descender);
339*2d1272b8SAndroid Build Coastguard Worker 
340*2d1272b8SAndroid Build Coastguard Worker     for (unsigned int i = 0; i < count; i++)
341*2d1272b8SAndroid Build Coastguard Worker     {
342*2d1272b8SAndroid Build Coastguard Worker       *first_advance = advance;
343*2d1272b8SAndroid Build Coastguard Worker       first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
344*2d1272b8SAndroid Build Coastguard Worker       first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
345*2d1272b8SAndroid Build Coastguard Worker     }
346*2d1272b8SAndroid Build Coastguard Worker   }
347*2d1272b8SAndroid Build Coastguard Worker 
348*2d1272b8SAndroid Build Coastguard Worker   if (font->y_strength && !font->embolden_in_place)
349*2d1272b8SAndroid Build Coastguard Worker   {
350*2d1272b8SAndroid Build Coastguard Worker     /* Emboldening. */
351*2d1272b8SAndroid Build Coastguard Worker     hb_position_t y_strength = font->y_scale >= 0 ? font->y_strength : -font->y_strength;
352*2d1272b8SAndroid Build Coastguard Worker     first_advance = orig_first_advance;
353*2d1272b8SAndroid Build Coastguard Worker     for (unsigned int i = 0; i < count; i++)
354*2d1272b8SAndroid Build Coastguard Worker     {
355*2d1272b8SAndroid Build Coastguard Worker       *first_advance += *first_advance ? y_strength : 0;
356*2d1272b8SAndroid Build Coastguard Worker       first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
357*2d1272b8SAndroid Build Coastguard Worker     }
358*2d1272b8SAndroid Build Coastguard Worker   }
359*2d1272b8SAndroid Build Coastguard Worker }
360*2d1272b8SAndroid Build Coastguard Worker #endif
361*2d1272b8SAndroid Build Coastguard Worker 
362*2d1272b8SAndroid Build Coastguard Worker #ifndef HB_NO_VERTICAL
363*2d1272b8SAndroid Build Coastguard Worker static hb_bool_t
hb_ot_get_glyph_v_origin(hb_font_t * font,void * font_data,hb_codepoint_t glyph,hb_position_t * x,hb_position_t * y,void * user_data HB_UNUSED)364*2d1272b8SAndroid Build Coastguard Worker hb_ot_get_glyph_v_origin (hb_font_t *font,
365*2d1272b8SAndroid Build Coastguard Worker 			  void *font_data,
366*2d1272b8SAndroid Build Coastguard Worker 			  hb_codepoint_t glyph,
367*2d1272b8SAndroid Build Coastguard Worker 			  hb_position_t *x,
368*2d1272b8SAndroid Build Coastguard Worker 			  hb_position_t *y,
369*2d1272b8SAndroid Build Coastguard Worker 			  void *user_data HB_UNUSED)
370*2d1272b8SAndroid Build Coastguard Worker {
371*2d1272b8SAndroid Build Coastguard Worker   const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
372*2d1272b8SAndroid Build Coastguard Worker   const hb_ot_face_t *ot_face = ot_font->ot_face;
373*2d1272b8SAndroid Build Coastguard Worker 
374*2d1272b8SAndroid Build Coastguard Worker   *x = font->get_glyph_h_advance (glyph) / 2;
375*2d1272b8SAndroid Build Coastguard Worker 
376*2d1272b8SAndroid Build Coastguard Worker   const OT::VORG &VORG = *ot_face->VORG;
377*2d1272b8SAndroid Build Coastguard Worker   if (VORG.has_data ())
378*2d1272b8SAndroid Build Coastguard Worker   {
379*2d1272b8SAndroid Build Coastguard Worker     float delta = 0;
380*2d1272b8SAndroid Build Coastguard Worker 
381*2d1272b8SAndroid Build Coastguard Worker #ifndef HB_NO_VAR
382*2d1272b8SAndroid Build Coastguard Worker     const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx;
383*2d1272b8SAndroid Build Coastguard Worker     const OT::VVAR &VVAR = *vmtx.var_table;
384*2d1272b8SAndroid Build Coastguard Worker     if (font->num_coords)
385*2d1272b8SAndroid Build Coastguard Worker       VVAR.get_vorg_delta_unscaled (glyph,
386*2d1272b8SAndroid Build Coastguard Worker 				    font->coords, font->num_coords,
387*2d1272b8SAndroid Build Coastguard Worker 				    &delta);
388*2d1272b8SAndroid Build Coastguard Worker #endif
389*2d1272b8SAndroid Build Coastguard Worker 
390*2d1272b8SAndroid Build Coastguard Worker     *y = font->em_scalef_y (VORG.get_y_origin (glyph) + delta);
391*2d1272b8SAndroid Build Coastguard Worker     return true;
392*2d1272b8SAndroid Build Coastguard Worker   }
393*2d1272b8SAndroid Build Coastguard Worker 
394*2d1272b8SAndroid Build Coastguard Worker   hb_glyph_extents_t extents = {0};
395*2d1272b8SAndroid Build Coastguard Worker   if (ot_face->glyf->get_extents (font, glyph, &extents))
396*2d1272b8SAndroid Build Coastguard Worker   {
397*2d1272b8SAndroid Build Coastguard Worker     const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx;
398*2d1272b8SAndroid Build Coastguard Worker     int tsb = 0;
399*2d1272b8SAndroid Build Coastguard Worker     if (vmtx.get_leading_bearing_with_var_unscaled (font, glyph, &tsb))
400*2d1272b8SAndroid Build Coastguard Worker     {
401*2d1272b8SAndroid Build Coastguard Worker       *y = extents.y_bearing + font->em_scale_y (tsb);
402*2d1272b8SAndroid Build Coastguard Worker       return true;
403*2d1272b8SAndroid Build Coastguard Worker     }
404*2d1272b8SAndroid Build Coastguard Worker 
405*2d1272b8SAndroid Build Coastguard Worker     hb_font_extents_t font_extents;
406*2d1272b8SAndroid Build Coastguard Worker     font->get_h_extents_with_fallback (&font_extents);
407*2d1272b8SAndroid Build Coastguard Worker     hb_position_t advance = font_extents.ascender - font_extents.descender;
408*2d1272b8SAndroid Build Coastguard Worker     int diff = advance - -extents.height;
409*2d1272b8SAndroid Build Coastguard Worker     *y = extents.y_bearing + (diff >> 1);
410*2d1272b8SAndroid Build Coastguard Worker     return true;
411*2d1272b8SAndroid Build Coastguard Worker   }
412*2d1272b8SAndroid Build Coastguard Worker 
413*2d1272b8SAndroid Build Coastguard Worker   hb_font_extents_t font_extents;
414*2d1272b8SAndroid Build Coastguard Worker   font->get_h_extents_with_fallback (&font_extents);
415*2d1272b8SAndroid Build Coastguard Worker   *y = font_extents.ascender;
416*2d1272b8SAndroid Build Coastguard Worker 
417*2d1272b8SAndroid Build Coastguard Worker   return true;
418*2d1272b8SAndroid Build Coastguard Worker }
419*2d1272b8SAndroid Build Coastguard Worker #endif
420*2d1272b8SAndroid Build Coastguard Worker 
421*2d1272b8SAndroid Build Coastguard Worker static hb_bool_t
hb_ot_get_glyph_extents(hb_font_t * font,void * font_data,hb_codepoint_t glyph,hb_glyph_extents_t * extents,void * user_data HB_UNUSED)422*2d1272b8SAndroid Build Coastguard Worker hb_ot_get_glyph_extents (hb_font_t *font,
423*2d1272b8SAndroid Build Coastguard Worker 			 void *font_data,
424*2d1272b8SAndroid Build Coastguard Worker 			 hb_codepoint_t glyph,
425*2d1272b8SAndroid Build Coastguard Worker 			 hb_glyph_extents_t *extents,
426*2d1272b8SAndroid Build Coastguard Worker 			 void *user_data HB_UNUSED)
427*2d1272b8SAndroid Build Coastguard Worker {
428*2d1272b8SAndroid Build Coastguard Worker   const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
429*2d1272b8SAndroid Build Coastguard Worker   const hb_ot_face_t *ot_face = ot_font->ot_face;
430*2d1272b8SAndroid Build Coastguard Worker 
431*2d1272b8SAndroid Build Coastguard Worker #if !defined(HB_NO_OT_FONT_BITMAP) && !defined(HB_NO_COLOR)
432*2d1272b8SAndroid Build Coastguard Worker   if (ot_face->sbix->get_extents (font, glyph, extents)) return true;
433*2d1272b8SAndroid Build Coastguard Worker   if (ot_face->CBDT->get_extents (font, glyph, extents)) return true;
434*2d1272b8SAndroid Build Coastguard Worker #endif
435*2d1272b8SAndroid Build Coastguard Worker #if !defined(HB_NO_COLOR) && !defined(HB_NO_PAINT)
436*2d1272b8SAndroid Build Coastguard Worker   if (ot_face->COLR->get_extents (font, glyph, extents)) return true;
437*2d1272b8SAndroid Build Coastguard Worker #endif
438*2d1272b8SAndroid Build Coastguard Worker   if (ot_face->glyf->get_extents (font, glyph, extents)) return true;
439*2d1272b8SAndroid Build Coastguard Worker #ifndef HB_NO_OT_FONT_CFF
440*2d1272b8SAndroid Build Coastguard Worker   if (ot_face->cff2->get_extents (font, glyph, extents)) return true;
441*2d1272b8SAndroid Build Coastguard Worker   if (ot_face->cff1->get_extents (font, glyph, extents)) return true;
442*2d1272b8SAndroid Build Coastguard Worker #endif
443*2d1272b8SAndroid Build Coastguard Worker 
444*2d1272b8SAndroid Build Coastguard Worker   return false;
445*2d1272b8SAndroid Build Coastguard Worker }
446*2d1272b8SAndroid Build Coastguard Worker 
447*2d1272b8SAndroid Build Coastguard Worker #ifndef HB_NO_OT_FONT_GLYPH_NAMES
448*2d1272b8SAndroid Build Coastguard Worker static hb_bool_t
hb_ot_get_glyph_name(hb_font_t * font HB_UNUSED,void * font_data,hb_codepoint_t glyph,char * name,unsigned int size,void * user_data HB_UNUSED)449*2d1272b8SAndroid Build Coastguard Worker hb_ot_get_glyph_name (hb_font_t *font HB_UNUSED,
450*2d1272b8SAndroid Build Coastguard Worker 		      void *font_data,
451*2d1272b8SAndroid Build Coastguard Worker 		      hb_codepoint_t glyph,
452*2d1272b8SAndroid Build Coastguard Worker 		      char *name, unsigned int size,
453*2d1272b8SAndroid Build Coastguard Worker 		      void *user_data HB_UNUSED)
454*2d1272b8SAndroid Build Coastguard Worker {
455*2d1272b8SAndroid Build Coastguard Worker   const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
456*2d1272b8SAndroid Build Coastguard Worker   const hb_ot_face_t *ot_face = ot_font->ot_face;
457*2d1272b8SAndroid Build Coastguard Worker 
458*2d1272b8SAndroid Build Coastguard Worker   if (ot_face->post->get_glyph_name (glyph, name, size)) return true;
459*2d1272b8SAndroid Build Coastguard Worker #ifndef HB_NO_OT_FONT_CFF
460*2d1272b8SAndroid Build Coastguard Worker   if (ot_face->cff1->get_glyph_name (glyph, name, size)) return true;
461*2d1272b8SAndroid Build Coastguard Worker #endif
462*2d1272b8SAndroid Build Coastguard Worker   return false;
463*2d1272b8SAndroid Build Coastguard Worker }
464*2d1272b8SAndroid Build Coastguard Worker static hb_bool_t
hb_ot_get_glyph_from_name(hb_font_t * font HB_UNUSED,void * font_data,const char * name,int len,hb_codepoint_t * glyph,void * user_data HB_UNUSED)465*2d1272b8SAndroid Build Coastguard Worker hb_ot_get_glyph_from_name (hb_font_t *font HB_UNUSED,
466*2d1272b8SAndroid Build Coastguard Worker 			   void *font_data,
467*2d1272b8SAndroid Build Coastguard Worker 			   const char *name, int len,
468*2d1272b8SAndroid Build Coastguard Worker 			   hb_codepoint_t *glyph,
469*2d1272b8SAndroid Build Coastguard Worker 			   void *user_data HB_UNUSED)
470*2d1272b8SAndroid Build Coastguard Worker {
471*2d1272b8SAndroid Build Coastguard Worker   const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
472*2d1272b8SAndroid Build Coastguard Worker   const hb_ot_face_t *ot_face = ot_font->ot_face;
473*2d1272b8SAndroid Build Coastguard Worker 
474*2d1272b8SAndroid Build Coastguard Worker   if (ot_face->post->get_glyph_from_name (name, len, glyph)) return true;
475*2d1272b8SAndroid Build Coastguard Worker #ifndef HB_NO_OT_FONT_CFF
476*2d1272b8SAndroid Build Coastguard Worker     if (ot_face->cff1->get_glyph_from_name (name, len, glyph)) return true;
477*2d1272b8SAndroid Build Coastguard Worker #endif
478*2d1272b8SAndroid Build Coastguard Worker   return false;
479*2d1272b8SAndroid Build Coastguard Worker }
480*2d1272b8SAndroid Build Coastguard Worker #endif
481*2d1272b8SAndroid Build Coastguard Worker 
482*2d1272b8SAndroid Build Coastguard Worker static hb_bool_t
hb_ot_get_font_h_extents(hb_font_t * font,void * font_data HB_UNUSED,hb_font_extents_t * metrics,void * user_data HB_UNUSED)483*2d1272b8SAndroid Build Coastguard Worker hb_ot_get_font_h_extents (hb_font_t *font,
484*2d1272b8SAndroid Build Coastguard Worker 			  void *font_data HB_UNUSED,
485*2d1272b8SAndroid Build Coastguard Worker 			  hb_font_extents_t *metrics,
486*2d1272b8SAndroid Build Coastguard Worker 			  void *user_data HB_UNUSED)
487*2d1272b8SAndroid Build Coastguard Worker {
488*2d1272b8SAndroid Build Coastguard Worker   bool ret = _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER, &metrics->ascender) &&
489*2d1272b8SAndroid Build Coastguard Worker 	     _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_HORIZONTAL_DESCENDER, &metrics->descender) &&
490*2d1272b8SAndroid Build Coastguard Worker 	     _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_HORIZONTAL_LINE_GAP, &metrics->line_gap);
491*2d1272b8SAndroid Build Coastguard Worker 
492*2d1272b8SAndroid Build Coastguard Worker   /* Embolden */
493*2d1272b8SAndroid Build Coastguard Worker   int y_shift = font->y_strength;
494*2d1272b8SAndroid Build Coastguard Worker   if (font->y_scale < 0) y_shift = -y_shift;
495*2d1272b8SAndroid Build Coastguard Worker   metrics->ascender += y_shift;
496*2d1272b8SAndroid Build Coastguard Worker 
497*2d1272b8SAndroid Build Coastguard Worker   return ret;
498*2d1272b8SAndroid Build Coastguard Worker }
499*2d1272b8SAndroid Build Coastguard Worker 
500*2d1272b8SAndroid Build Coastguard Worker #ifndef HB_NO_VERTICAL
501*2d1272b8SAndroid Build Coastguard Worker static hb_bool_t
hb_ot_get_font_v_extents(hb_font_t * font,void * font_data HB_UNUSED,hb_font_extents_t * metrics,void * user_data HB_UNUSED)502*2d1272b8SAndroid Build Coastguard Worker hb_ot_get_font_v_extents (hb_font_t *font,
503*2d1272b8SAndroid Build Coastguard Worker 			  void *font_data HB_UNUSED,
504*2d1272b8SAndroid Build Coastguard Worker 			  hb_font_extents_t *metrics,
505*2d1272b8SAndroid Build Coastguard Worker 			  void *user_data HB_UNUSED)
506*2d1272b8SAndroid Build Coastguard Worker {
507*2d1272b8SAndroid Build Coastguard Worker   return _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_VERTICAL_ASCENDER, &metrics->ascender) &&
508*2d1272b8SAndroid Build Coastguard Worker 	 _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_VERTICAL_DESCENDER, &metrics->descender) &&
509*2d1272b8SAndroid Build Coastguard Worker 	 _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_VERTICAL_LINE_GAP, &metrics->line_gap);
510*2d1272b8SAndroid Build Coastguard Worker }
511*2d1272b8SAndroid Build Coastguard Worker #endif
512*2d1272b8SAndroid Build Coastguard Worker 
513*2d1272b8SAndroid Build Coastguard Worker #ifndef HB_NO_DRAW
514*2d1272b8SAndroid Build Coastguard Worker static void
hb_ot_draw_glyph(hb_font_t * font,void * font_data HB_UNUSED,hb_codepoint_t glyph,hb_draw_funcs_t * draw_funcs,void * draw_data,void * user_data)515*2d1272b8SAndroid Build Coastguard Worker hb_ot_draw_glyph (hb_font_t *font,
516*2d1272b8SAndroid Build Coastguard Worker 		  void *font_data HB_UNUSED,
517*2d1272b8SAndroid Build Coastguard Worker 		  hb_codepoint_t glyph,
518*2d1272b8SAndroid Build Coastguard Worker 		  hb_draw_funcs_t *draw_funcs, void *draw_data,
519*2d1272b8SAndroid Build Coastguard Worker 		  void *user_data)
520*2d1272b8SAndroid Build Coastguard Worker {
521*2d1272b8SAndroid Build Coastguard Worker   bool embolden = font->x_strength || font->y_strength;
522*2d1272b8SAndroid Build Coastguard Worker   hb_outline_t outline;
523*2d1272b8SAndroid Build Coastguard Worker 
524*2d1272b8SAndroid Build Coastguard Worker   { // Need draw_session to be destructed before emboldening.
525*2d1272b8SAndroid Build Coastguard Worker     hb_draw_session_t draw_session (embolden ? hb_outline_recording_pen_get_funcs () : draw_funcs,
526*2d1272b8SAndroid Build Coastguard Worker 				    embolden ? &outline : draw_data, font->slant_xy);
527*2d1272b8SAndroid Build Coastguard Worker #ifndef HB_NO_VAR_COMPOSITES
528*2d1272b8SAndroid Build Coastguard Worker     if (!font->face->table.VARC->get_path (font, glyph, draw_session))
529*2d1272b8SAndroid Build Coastguard Worker #endif
530*2d1272b8SAndroid Build Coastguard Worker     // Keep the following in synch with VARC::get_path_at()
531*2d1272b8SAndroid Build Coastguard Worker     if (!font->face->table.glyf->get_path (font, glyph, draw_session))
532*2d1272b8SAndroid Build Coastguard Worker #ifndef HB_NO_CFF
533*2d1272b8SAndroid Build Coastguard Worker     if (!font->face->table.cff2->get_path (font, glyph, draw_session))
534*2d1272b8SAndroid Build Coastguard Worker     if (!font->face->table.cff1->get_path (font, glyph, draw_session))
535*2d1272b8SAndroid Build Coastguard Worker #endif
536*2d1272b8SAndroid Build Coastguard Worker     {}
537*2d1272b8SAndroid Build Coastguard Worker   }
538*2d1272b8SAndroid Build Coastguard Worker 
539*2d1272b8SAndroid Build Coastguard Worker   if (embolden)
540*2d1272b8SAndroid Build Coastguard Worker   {
541*2d1272b8SAndroid Build Coastguard Worker     float x_shift = font->embolden_in_place ? 0 : (float) font->x_strength / 2;
542*2d1272b8SAndroid Build Coastguard Worker     float y_shift = (float) font->y_strength / 2;
543*2d1272b8SAndroid Build Coastguard Worker     if (font->x_scale < 0) x_shift = -x_shift;
544*2d1272b8SAndroid Build Coastguard Worker     if (font->y_scale < 0) y_shift = -y_shift;
545*2d1272b8SAndroid Build Coastguard Worker     outline.embolden (font->x_strength, font->y_strength,
546*2d1272b8SAndroid Build Coastguard Worker 		      x_shift, y_shift);
547*2d1272b8SAndroid Build Coastguard Worker 
548*2d1272b8SAndroid Build Coastguard Worker     outline.replay (draw_funcs, draw_data);
549*2d1272b8SAndroid Build Coastguard Worker   }
550*2d1272b8SAndroid Build Coastguard Worker }
551*2d1272b8SAndroid Build Coastguard Worker #endif
552*2d1272b8SAndroid Build Coastguard Worker 
553*2d1272b8SAndroid Build Coastguard Worker #ifndef HB_NO_PAINT
554*2d1272b8SAndroid Build Coastguard Worker static void
hb_ot_paint_glyph(hb_font_t * font,void * font_data,hb_codepoint_t glyph,hb_paint_funcs_t * paint_funcs,void * paint_data,unsigned int palette,hb_color_t foreground,void * user_data)555*2d1272b8SAndroid Build Coastguard Worker hb_ot_paint_glyph (hb_font_t *font,
556*2d1272b8SAndroid Build Coastguard Worker                    void *font_data,
557*2d1272b8SAndroid Build Coastguard Worker                    hb_codepoint_t glyph,
558*2d1272b8SAndroid Build Coastguard Worker                    hb_paint_funcs_t *paint_funcs, void *paint_data,
559*2d1272b8SAndroid Build Coastguard Worker                    unsigned int palette,
560*2d1272b8SAndroid Build Coastguard Worker                    hb_color_t foreground,
561*2d1272b8SAndroid Build Coastguard Worker                    void *user_data)
562*2d1272b8SAndroid Build Coastguard Worker {
563*2d1272b8SAndroid Build Coastguard Worker #ifndef HB_NO_COLOR
564*2d1272b8SAndroid Build Coastguard Worker   if (font->face->table.COLR->paint_glyph (font, glyph, paint_funcs, paint_data, palette, foreground)) return;
565*2d1272b8SAndroid Build Coastguard Worker   if (font->face->table.SVG->paint_glyph (font, glyph, paint_funcs, paint_data)) return;
566*2d1272b8SAndroid Build Coastguard Worker #ifndef HB_NO_OT_FONT_BITMAP
567*2d1272b8SAndroid Build Coastguard Worker   if (font->face->table.CBDT->paint_glyph (font, glyph, paint_funcs, paint_data)) return;
568*2d1272b8SAndroid Build Coastguard Worker   if (font->face->table.sbix->paint_glyph (font, glyph, paint_funcs, paint_data)) return;
569*2d1272b8SAndroid Build Coastguard Worker #endif
570*2d1272b8SAndroid Build Coastguard Worker #endif
571*2d1272b8SAndroid Build Coastguard Worker #ifndef HB_NO_VAR_COMPOSITES
572*2d1272b8SAndroid Build Coastguard Worker   if (font->face->table.VARC->paint_glyph (font, glyph, paint_funcs, paint_data, foreground)) return;
573*2d1272b8SAndroid Build Coastguard Worker #endif
574*2d1272b8SAndroid Build Coastguard Worker   if (font->face->table.glyf->paint_glyph (font, glyph, paint_funcs, paint_data, foreground)) return;
575*2d1272b8SAndroid Build Coastguard Worker #ifndef HB_NO_CFF
576*2d1272b8SAndroid Build Coastguard Worker   if (font->face->table.cff2->paint_glyph (font, glyph, paint_funcs, paint_data, foreground)) return;
577*2d1272b8SAndroid Build Coastguard Worker   if (font->face->table.cff1->paint_glyph (font, glyph, paint_funcs, paint_data, foreground)) return;
578*2d1272b8SAndroid Build Coastguard Worker #endif
579*2d1272b8SAndroid Build Coastguard Worker }
580*2d1272b8SAndroid Build Coastguard Worker #endif
581*2d1272b8SAndroid Build Coastguard Worker 
582*2d1272b8SAndroid Build Coastguard Worker static inline void free_static_ot_funcs ();
583*2d1272b8SAndroid Build Coastguard Worker 
584*2d1272b8SAndroid Build Coastguard Worker static struct hb_ot_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ot_font_funcs_lazy_loader_t>
585*2d1272b8SAndroid Build Coastguard Worker {
createhb_ot_font_funcs_lazy_loader_t586*2d1272b8SAndroid Build Coastguard Worker   static hb_font_funcs_t *create ()
587*2d1272b8SAndroid Build Coastguard Worker   {
588*2d1272b8SAndroid Build Coastguard Worker     hb_font_funcs_t *funcs = hb_font_funcs_create ();
589*2d1272b8SAndroid Build Coastguard Worker 
590*2d1272b8SAndroid Build Coastguard Worker     hb_font_funcs_set_nominal_glyph_func (funcs, hb_ot_get_nominal_glyph, nullptr, nullptr);
591*2d1272b8SAndroid Build Coastguard Worker     hb_font_funcs_set_nominal_glyphs_func (funcs, hb_ot_get_nominal_glyphs, nullptr, nullptr);
592*2d1272b8SAndroid Build Coastguard Worker     hb_font_funcs_set_variation_glyph_func (funcs, hb_ot_get_variation_glyph, nullptr, nullptr);
593*2d1272b8SAndroid Build Coastguard Worker 
594*2d1272b8SAndroid Build Coastguard Worker     hb_font_funcs_set_font_h_extents_func (funcs, hb_ot_get_font_h_extents, nullptr, nullptr);
595*2d1272b8SAndroid Build Coastguard Worker     hb_font_funcs_set_glyph_h_advances_func (funcs, hb_ot_get_glyph_h_advances, nullptr, nullptr);
596*2d1272b8SAndroid Build Coastguard Worker     //hb_font_funcs_set_glyph_h_origin_func (funcs, hb_ot_get_glyph_h_origin, nullptr, nullptr);
597*2d1272b8SAndroid Build Coastguard Worker 
598*2d1272b8SAndroid Build Coastguard Worker #ifndef HB_NO_VERTICAL
599*2d1272b8SAndroid Build Coastguard Worker     hb_font_funcs_set_font_v_extents_func (funcs, hb_ot_get_font_v_extents, nullptr, nullptr);
600*2d1272b8SAndroid Build Coastguard Worker     hb_font_funcs_set_glyph_v_advances_func (funcs, hb_ot_get_glyph_v_advances, nullptr, nullptr);
601*2d1272b8SAndroid Build Coastguard Worker     hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ot_get_glyph_v_origin, nullptr, nullptr);
602*2d1272b8SAndroid Build Coastguard Worker #endif
603*2d1272b8SAndroid Build Coastguard Worker 
604*2d1272b8SAndroid Build Coastguard Worker #ifndef HB_NO_DRAW
605*2d1272b8SAndroid Build Coastguard Worker     hb_font_funcs_set_draw_glyph_func (funcs, hb_ot_draw_glyph, nullptr, nullptr);
606*2d1272b8SAndroid Build Coastguard Worker #endif
607*2d1272b8SAndroid Build Coastguard Worker 
608*2d1272b8SAndroid Build Coastguard Worker #ifndef HB_NO_PAINT
609*2d1272b8SAndroid Build Coastguard Worker     hb_font_funcs_set_paint_glyph_func (funcs, hb_ot_paint_glyph, nullptr, nullptr);
610*2d1272b8SAndroid Build Coastguard Worker #endif
611*2d1272b8SAndroid Build Coastguard Worker 
612*2d1272b8SAndroid Build Coastguard Worker     hb_font_funcs_set_glyph_extents_func (funcs, hb_ot_get_glyph_extents, nullptr, nullptr);
613*2d1272b8SAndroid Build Coastguard Worker     //hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ot_get_glyph_contour_point, nullptr, nullptr);
614*2d1272b8SAndroid Build Coastguard Worker 
615*2d1272b8SAndroid Build Coastguard Worker #ifndef HB_NO_OT_FONT_GLYPH_NAMES
616*2d1272b8SAndroid Build Coastguard Worker     hb_font_funcs_set_glyph_name_func (funcs, hb_ot_get_glyph_name, nullptr, nullptr);
617*2d1272b8SAndroid Build Coastguard Worker     hb_font_funcs_set_glyph_from_name_func (funcs, hb_ot_get_glyph_from_name, nullptr, nullptr);
618*2d1272b8SAndroid Build Coastguard Worker #endif
619*2d1272b8SAndroid Build Coastguard Worker 
620*2d1272b8SAndroid Build Coastguard Worker     hb_font_funcs_make_immutable (funcs);
621*2d1272b8SAndroid Build Coastguard Worker 
622*2d1272b8SAndroid Build Coastguard Worker     hb_atexit (free_static_ot_funcs);
623*2d1272b8SAndroid Build Coastguard Worker 
624*2d1272b8SAndroid Build Coastguard Worker     return funcs;
625*2d1272b8SAndroid Build Coastguard Worker   }
626*2d1272b8SAndroid Build Coastguard Worker } static_ot_funcs;
627*2d1272b8SAndroid Build Coastguard Worker 
628*2d1272b8SAndroid Build Coastguard Worker static inline
free_static_ot_funcs()629*2d1272b8SAndroid Build Coastguard Worker void free_static_ot_funcs ()
630*2d1272b8SAndroid Build Coastguard Worker {
631*2d1272b8SAndroid Build Coastguard Worker   static_ot_funcs.free_instance ();
632*2d1272b8SAndroid Build Coastguard Worker }
633*2d1272b8SAndroid Build Coastguard Worker 
634*2d1272b8SAndroid Build Coastguard Worker static hb_font_funcs_t *
_hb_ot_get_font_funcs()635*2d1272b8SAndroid Build Coastguard Worker _hb_ot_get_font_funcs ()
636*2d1272b8SAndroid Build Coastguard Worker {
637*2d1272b8SAndroid Build Coastguard Worker   return static_ot_funcs.get_unconst ();
638*2d1272b8SAndroid Build Coastguard Worker }
639*2d1272b8SAndroid Build Coastguard Worker 
640*2d1272b8SAndroid Build Coastguard Worker 
641*2d1272b8SAndroid Build Coastguard Worker /**
642*2d1272b8SAndroid Build Coastguard Worker  * hb_ot_font_set_funcs:
643*2d1272b8SAndroid Build Coastguard Worker  * @font: #hb_font_t to work upon
644*2d1272b8SAndroid Build Coastguard Worker  *
645*2d1272b8SAndroid Build Coastguard Worker  * Sets the font functions to use when working with @font to
646*2d1272b8SAndroid Build Coastguard Worker  * the HarfBuzz's native implementation. This is the default
647*2d1272b8SAndroid Build Coastguard Worker  * for fonts newly created.
648*2d1272b8SAndroid Build Coastguard Worker  *
649*2d1272b8SAndroid Build Coastguard Worker  * Since: 0.9.28
650*2d1272b8SAndroid Build Coastguard Worker  **/
651*2d1272b8SAndroid Build Coastguard Worker void
hb_ot_font_set_funcs(hb_font_t * font)652*2d1272b8SAndroid Build Coastguard Worker hb_ot_font_set_funcs (hb_font_t *font)
653*2d1272b8SAndroid Build Coastguard Worker {
654*2d1272b8SAndroid Build Coastguard Worker   hb_ot_font_t *ot_font = _hb_ot_font_create (font);
655*2d1272b8SAndroid Build Coastguard Worker   if (unlikely (!ot_font))
656*2d1272b8SAndroid Build Coastguard Worker     return;
657*2d1272b8SAndroid Build Coastguard Worker 
658*2d1272b8SAndroid Build Coastguard Worker   hb_font_set_funcs (font,
659*2d1272b8SAndroid Build Coastguard Worker 		     _hb_ot_get_font_funcs (),
660*2d1272b8SAndroid Build Coastguard Worker 		     ot_font,
661*2d1272b8SAndroid Build Coastguard Worker 		     _hb_ot_font_destroy);
662*2d1272b8SAndroid Build Coastguard Worker }
663*2d1272b8SAndroid Build Coastguard Worker 
664*2d1272b8SAndroid Build Coastguard Worker #endif
665