Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(96)

Side by Side Diff: third_party/harfbuzz-ng/src/hb-ot-shape-complex-arabic-fallback.hh

Issue 475363002: Roll HarfBuzz to 0.9.35 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Windows build fix attempt Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright © 2012 Google, Inc. 2 * Copyright © 2012 Google, Inc.
3 * 3 *
4 * This is part of HarfBuzz, a text shaping library. 4 * This is part of HarfBuzz, a text shaping library.
5 * 5 *
6 * Permission is hereby granted, without written agreement and without 6 * Permission is hereby granted, without written agreement and without
7 * license or royalty fees, to use, copy, modify, and distribute this 7 * license or royalty fees, to use, copy, modify, and distribute this
8 * software and its documentation for any purpose, provided that the 8 * software and its documentation for any purpose, provided that the
9 * above copyright notice and the following two paragraphs appear in 9 * above copyright notice and the following two paragraphs appear in
10 * all copies of this software. 10 * all copies of this software.
(...skipping 15 matching lines...) Expand all
26 26
27 #ifndef HB_OT_SHAPE_COMPLEX_ARABIC_FALLBACK_HH 27 #ifndef HB_OT_SHAPE_COMPLEX_ARABIC_FALLBACK_HH
28 #define HB_OT_SHAPE_COMPLEX_ARABIC_FALLBACK_HH 28 #define HB_OT_SHAPE_COMPLEX_ARABIC_FALLBACK_HH
29 29
30 #include "hb-private.hh" 30 #include "hb-private.hh"
31 31
32 #include "hb-ot-shape-private.hh" 32 #include "hb-ot-shape-private.hh"
33 #include "hb-ot-layout-gsub-table.hh" 33 #include "hb-ot-layout-gsub-table.hh"
34 34
35 35
36 /* Features ordered the same as the entries in shaping_table rows,
37 * followed by rlig. Don't change. */
36 static const hb_tag_t arabic_fallback_features[] = 38 static const hb_tag_t arabic_fallback_features[] =
37 { 39 {
38 HB_TAG('i','n','i','t'), 40 HB_TAG('i','n','i','t'),
39 HB_TAG('m','e','d','i'), 41 HB_TAG('m','e','d','i'),
40 HB_TAG('f','i','n','a'), 42 HB_TAG('f','i','n','a'),
41 HB_TAG('i','s','o','l'), 43 HB_TAG('i','s','o','l'),
42 HB_TAG('r','l','i','g'), 44 HB_TAG('r','l','i','g'),
43 }; 45 };
44 46
45 /* Same order as the fallback feature array */
46 enum {
47 FALLBACK_INIT,
48 FALLBACK_MEDI,
49 FALLBACK_FINA,
50 FALLBACK_ISOL,
51 FALLBACK_RLIG,
52 ARABIC_NUM_FALLBACK_FEATURES
53 };
54
55 static OT::SubstLookup * 47 static OT::SubstLookup *
56 arabic_fallback_synthesize_lookup_single (const hb_ot_shape_plan_t *plan HB_UNUS ED, 48 arabic_fallback_synthesize_lookup_single (const hb_ot_shape_plan_t *plan HB_UNUS ED,
57 hb_font_t *font, 49 hb_font_t *font,
58 unsigned int feature_index) 50 unsigned int feature_index)
59 { 51 {
60 OT::GlyphID glyphs[SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1]; 52 OT::GlyphID glyphs[SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1];
61 OT::GlyphID substitutes[SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1]; 53 OT::GlyphID substitutes[SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1];
62 unsigned int num_glyphs = 0; 54 unsigned int num_glyphs = 0;
63 55
64 /* Populate arrays */ 56 /* Populate arrays */
65 for (hb_codepoint_t u = SHAPING_TABLE_FIRST; u < SHAPING_TABLE_LAST + 1; u++) 57 for (hb_codepoint_t u = SHAPING_TABLE_FIRST; u < SHAPING_TABLE_LAST + 1; u++)
66 { 58 {
67 hb_codepoint_t s = shaping_table[u - SHAPING_TABLE_FIRST][feature_index]; 59 hb_codepoint_t s = shaping_table[u - SHAPING_TABLE_FIRST][feature_index];
68 hb_codepoint_t u_glyph, s_glyph; 60 hb_codepoint_t u_glyph, s_glyph;
69 61
70 if (!s || 62 if (!s ||
71 !hb_font_get_glyph (font, u, 0, &u_glyph) || 63 !hb_font_get_glyph (font, u, 0, &u_glyph) ||
72 !hb_font_get_glyph (font, s, 0, &s_glyph) || 64 !hb_font_get_glyph (font, s, 0, &s_glyph) ||
73 u_glyph == s_glyph || 65 u_glyph == s_glyph ||
74 u_glyph > 0xFFFFu || s_glyph > 0xFFFFu) 66 u_glyph > 0xFFFFu || s_glyph > 0xFFFFu)
75 continue; 67 continue;
76 68
77 glyphs[num_glyphs].set (u_glyph); 69 glyphs[num_glyphs].set (u_glyph);
78 substitutes[num_glyphs].set (s_glyph); 70 substitutes[num_glyphs].set (s_glyph);
79 71
80 num_glyphs++; 72 num_glyphs++;
81 } 73 }
82 74
75 if (!num_glyphs)
76 return NULL;
77
83 /* Bubble-sort! 78 /* Bubble-sort!
84 * May not be good-enough for presidential candidate interviews, but good-enou gh for us... */ 79 * May not be good-enough for presidential candidate interviews, but good-enou gh for us... */
85 hb_bubble_sort (&glyphs[0], num_glyphs, OT::GlyphID::cmp, &substitutes[0]); 80 hb_bubble_sort (&glyphs[0], num_glyphs, OT::GlyphID::cmp, &substitutes[0]);
86 81
87 OT::Supplier<OT::GlyphID> glyphs_supplier (glyphs, num_glyphs); 82 OT::Supplier<OT::GlyphID> glyphs_supplier (glyphs, num_glyphs);
88 OT::Supplier<OT::GlyphID> substitutes_supplier (substitutes, num_glyphs); 83 OT::Supplier<OT::GlyphID> substitutes_supplier (substitutes, num_glyphs);
89 84
90 /* Each glyph takes four bytes max, and there's some overhead. */ 85 /* Each glyph takes four bytes max, and there's some overhead. */
91 char buf[(SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1) * 4 + 128]; 86 char buf[(SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1) * 4 + 128];
92 OT::hb_serialize_context_t c (buf, sizeof (buf)); 87 OT::hb_serialize_context_t c (buf, sizeof (buf));
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 145
151 ligature_per_first_glyph_count_list[i]++; 146 ligature_per_first_glyph_count_list[i]++;
152 147
153 ligature_list[num_ligatures].set (ligature_glyph); 148 ligature_list[num_ligatures].set (ligature_glyph);
154 component_count_list[num_ligatures] = 2; 149 component_count_list[num_ligatures] = 2;
155 component_list[num_ligatures].set (second_glyph); 150 component_list[num_ligatures].set (second_glyph);
156 num_ligatures++; 151 num_ligatures++;
157 } 152 }
158 } 153 }
159 154
155 if (!num_ligatures)
156 return NULL;
157
160 OT::Supplier<OT::GlyphID> first_glyphs_supplier (first_ glyphs, num_first_glyphs); 158 OT::Supplier<OT::GlyphID> first_glyphs_supplier (first_ glyphs, num_first_glyphs);
161 OT::Supplier<unsigned int > ligature_per_first_glyph_count_supplier (ligatu re_per_first_glyph_count_list, num_first_glyphs); 159 OT::Supplier<unsigned int > ligature_per_first_glyph_count_supplier (ligatu re_per_first_glyph_count_list, num_first_glyphs);
162 OT::Supplier<OT::GlyphID> ligatures_supplier (ligatu re_list, num_ligatures); 160 OT::Supplier<OT::GlyphID> ligatures_supplier (ligatu re_list, num_ligatures);
163 OT::Supplier<unsigned int > component_count_supplier (compon ent_count_list, num_ligatures); 161 OT::Supplier<unsigned int > component_count_supplier (compon ent_count_list, num_ligatures);
164 OT::Supplier<OT::GlyphID> component_supplier (compon ent_list, num_ligatures); 162 OT::Supplier<OT::GlyphID> component_supplier (compon ent_list, num_ligatures);
165 163
166 /* 16 bytes per ligature ought to be enough... */ 164 /* 16 bytes per ligature ought to be enough... */
167 char buf[ARRAY_LENGTH_CONST (ligature_list) * 16 + 128]; 165 char buf[ARRAY_LENGTH_CONST (ligature_list) * 16 + 128];
168 OT::hb_serialize_context_t c (buf, sizeof (buf)); 166 OT::hb_serialize_context_t c (buf, sizeof (buf));
169 OT::SubstLookup *lookup = c.start_serialize<OT::SubstLookup> (); 167 OT::SubstLookup *lookup = c.start_serialize<OT::SubstLookup> ();
(...skipping 16 matching lines...) Expand all
186 arabic_fallback_synthesize_lookup (const hb_ot_shape_plan_t *plan, 184 arabic_fallback_synthesize_lookup (const hb_ot_shape_plan_t *plan,
187 hb_font_t *font, 185 hb_font_t *font,
188 unsigned int feature_index) 186 unsigned int feature_index)
189 { 187 {
190 if (feature_index < 4) 188 if (feature_index < 4)
191 return arabic_fallback_synthesize_lookup_single (plan, font, feature_index); 189 return arabic_fallback_synthesize_lookup_single (plan, font, feature_index);
192 else 190 else
193 return arabic_fallback_synthesize_lookup_ligature (plan, font); 191 return arabic_fallback_synthesize_lookup_ligature (plan, font);
194 } 192 }
195 193
194 #define ARABIC_FALLBACK_MAX_LOOKUPS 5
195
196 struct arabic_fallback_plan_t 196 struct arabic_fallback_plan_t
197 { 197 {
198 ASSERT_POD (); 198 ASSERT_POD ();
199 199
200 hb_mask_t mask_array[ARABIC_NUM_FALLBACK_FEATURES]; 200 unsigned int num_lookups;
201 OT::SubstLookup *lookup_array[ARABIC_NUM_FALLBACK_FEATURES]; 201 bool free_lookups;
202 hb_ot_layout_lookup_accelerator_t accel_array[ARABIC_NUM_FALLBACK_FEATURES]; 202
203 hb_mask_t mask_array[ARABIC_FALLBACK_MAX_LOOKUPS];
204 OT::SubstLookup *lookup_array[ARABIC_FALLBACK_MAX_LOOKUPS];
205 hb_ot_layout_lookup_accelerator_t accel_array[ARABIC_FALLBACK_MAX_LOOKUPS];
203 }; 206 };
204 207
205 static const arabic_fallback_plan_t arabic_fallback_plan_nil = {}; 208 static const arabic_fallback_plan_t arabic_fallback_plan_nil = {};
206 209
210 #if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(HB_WITH_WIN1256)
211 #define HB_WITH_WIN1256
212 #endif
213
214 #ifdef HB_WITH_WIN1256
215 #include "hb-ot-shape-complex-arabic-win1256.hh"
216 #endif
217
218 struct ManifestLookup {
219 OT::Tag tag;
220 OT::OffsetTo<OT::SubstLookup> lookupOffset;
221 };
222 typedef OT::ArrayOf<ManifestLookup> Manifest;
223
224 static bool
225 arabic_fallback_plan_init_win1256 (arabic_fallback_plan_t *fallback_plan,
226 const hb_ot_shape_plan_t *plan,
227 hb_font_t *font)
228 {
229 #ifdef HB_WITH_WIN1256
230 /* Does this font look like it's Windows-1256-encoded? */
231 hb_codepoint_t g;
232 if (!(hb_font_get_glyph (font, 0x0627u, 0, &g) && g == 199 /* ALEF */ &&
233 hb_font_get_glyph (font, 0x0644u, 0, &g) && g == 225 /* LAM */ &&
234 hb_font_get_glyph (font, 0x0649u, 0, &g) && g == 236 /* ALEF MAKSURA */ &&
235 hb_font_get_glyph (font, 0x064Au, 0, &g) && g == 237 /* YEH */ &&
236 hb_font_get_glyph (font, 0x0652u, 0, &g) && g == 250 /* SUKUN */))
237 return false;
238
239 const Manifest &manifest = reinterpret_cast<const Manifest&> (arabic_win1256_g sub_lookups.manifest);
240 ASSERT_STATIC (sizeof (arabic_win1256_gsub_lookups.manifestData) / sizeof (Man ifestLookup)
241 <= ARABIC_FALLBACK_MAX_LOOKUPS);
242 /* TODO sanitize the table? */
243
244 unsigned j = 0;
245 unsigned int count = manifest.len;
246 for (unsigned int i = 0; i < count; i++)
247 {
248 fallback_plan->mask_array[j] = plan->map.get_1_mask (manifest[i].tag);
249 if (fallback_plan->mask_array[j])
250 {
251 fallback_plan->lookup_array[j] = const_cast<OT::SubstLookup*> (&(&manifest +manifest[i].lookupOffset));
252 if (fallback_plan->lookup_array[j])
253 {
254 fallback_plan->accel_array[j].init (*fallback_plan->lookup_array[j]);
255 j++;
256 }
257 }
258 }
259
260 fallback_plan->num_lookups = j;
261 fallback_plan->free_lookups = false;
262
263 return j > 0;
264 #else
265 return false;
266 #endif
267 }
268
269 static bool
270 arabic_fallback_plan_init_unicode (arabic_fallback_plan_t *fallback_plan,
271 const hb_ot_shape_plan_t *plan,
272 hb_font_t *font)
273 {
274 ASSERT_STATIC (ARRAY_LENGTH_CONST(arabic_fallback_features) <= ARABIC_FALLBACK _MAX_LOOKUPS);
275 unsigned int j = 0;
276 for (unsigned int i = 0; i < ARRAY_LENGTH(arabic_fallback_features) ; i++)
277 {
278 fallback_plan->mask_array[j] = plan->map.get_1_mask (arabic_fallback_feature s[i]);
279 if (fallback_plan->mask_array[j])
280 {
281 fallback_plan->lookup_array[j] = arabic_fallback_synthesize_lookup (plan, font, i);
282 if (fallback_plan->lookup_array[j])
283 {
284 fallback_plan->accel_array[j].init (*fallback_plan->lookup_array[j]);
285 j++;
286 }
287 }
288 }
289
290 fallback_plan->num_lookups = j;
291 fallback_plan->free_lookups = true;
292
293 return j > 0;
294 }
295
207 static arabic_fallback_plan_t * 296 static arabic_fallback_plan_t *
208 arabic_fallback_plan_create (const hb_ot_shape_plan_t *plan, 297 arabic_fallback_plan_create (const hb_ot_shape_plan_t *plan,
209 hb_font_t *font) 298 hb_font_t *font)
210 { 299 {
211 arabic_fallback_plan_t *fallback_plan = (arabic_fallback_plan_t *) calloc (1, sizeof (arabic_fallback_plan_t)); 300 arabic_fallback_plan_t *fallback_plan = (arabic_fallback_plan_t *) calloc (1, sizeof (arabic_fallback_plan_t));
212 if (unlikely (!fallback_plan)) 301 if (unlikely (!fallback_plan))
213 return const_cast<arabic_fallback_plan_t *> (&arabic_fallback_plan_nil); 302 return const_cast<arabic_fallback_plan_t *> (&arabic_fallback_plan_nil);
214 303
215 for (unsigned int i = 0; i < ARABIC_NUM_FALLBACK_FEATURES; i++) 304 fallback_plan->num_lookups = 0;
216 { 305 fallback_plan->free_lookups = false;
217 fallback_plan->mask_array[i] = plan->map.get_1_mask (arabic_fallback_feature s[i]);
218 if (fallback_plan->mask_array[i]) {
219 fallback_plan->lookup_array[i] = arabic_fallback_synthesize_lookup (plan, font, i);
220 if (fallback_plan->lookup_array[i])
221 » fallback_plan->accel_array[i].init (*fallback_plan->lookup_array[i]);
222 }
223 }
224 306
225 return fallback_plan; 307 /* Try synthesizing GSUB table using Unicode Arabic Presentation Forms,
308 * in case the font has cmap entries for the presentation-forms characters. */
309 if (arabic_fallback_plan_init_unicode (fallback_plan, plan, font))
310 return fallback_plan;
311
312 /* See if this looks like a Windows-1256-encoded font. If it does, use a
313 * hand-coded GSUB table. */
314 if (arabic_fallback_plan_init_win1256 (fallback_plan, plan, font))
315 return fallback_plan;
316
317 free (fallback_plan);
318 return const_cast<arabic_fallback_plan_t *> (&arabic_fallback_plan_nil);
226 } 319 }
227 320
228 static void 321 static void
229 arabic_fallback_plan_destroy (arabic_fallback_plan_t *fallback_plan) 322 arabic_fallback_plan_destroy (arabic_fallback_plan_t *fallback_plan)
230 { 323 {
231 if (!fallback_plan || fallback_plan == &arabic_fallback_plan_nil) 324 if (!fallback_plan || fallback_plan == &arabic_fallback_plan_nil)
232 return; 325 return;
233 326
234 for (unsigned int i = 0; i < ARABIC_NUM_FALLBACK_FEATURES; i++) 327 for (unsigned int i = 0; i < fallback_plan->num_lookups; i++)
235 if (fallback_plan->lookup_array[i]) 328 if (fallback_plan->lookup_array[i])
236 { 329 {
237 fallback_plan->accel_array[i].fini (fallback_plan->lookup_array[i]); 330 fallback_plan->accel_array[i].fini (fallback_plan->lookup_array[i]);
238 free (fallback_plan->lookup_array[i]); 331 if (fallback_plan->free_lookups)
332 » free (fallback_plan->lookup_array[i]);
239 } 333 }
240 334
241 free (fallback_plan); 335 free (fallback_plan);
242 } 336 }
243 337
244 static void 338 static void
245 arabic_fallback_plan_shape (arabic_fallback_plan_t *fallback_plan, 339 arabic_fallback_plan_shape (arabic_fallback_plan_t *fallback_plan,
246 hb_font_t *font, 340 hb_font_t *font,
247 hb_buffer_t *buffer) 341 hb_buffer_t *buffer)
248 { 342 {
249 OT::hb_apply_context_t c (0, font, buffer); 343 OT::hb_apply_context_t c (0, font, buffer);
250 for (unsigned int i = 0; i < ARABIC_NUM_FALLBACK_FEATURES; i++) 344 for (unsigned int i = 0; i < fallback_plan->num_lookups; i++)
251 if (fallback_plan->lookup_array[i]) { 345 if (fallback_plan->lookup_array[i]) {
252 c.set_lookup_mask (fallback_plan->mask_array[i]); 346 c.set_lookup_mask (fallback_plan->mask_array[i]);
253 hb_ot_layout_substitute_lookup (&c, 347 hb_ot_layout_substitute_lookup (&c,
254 *fallback_plan->lookup_array[i], 348 *fallback_plan->lookup_array[i],
255 fallback_plan->accel_array[i]); 349 fallback_plan->accel_array[i]);
256 } 350 }
257 } 351 }
258 352
259 353
260 #endif /* HB_OT_SHAPE_COMPLEX_ARABIC_FALLBACK_HH */ 354 #endif /* HB_OT_SHAPE_COMPLEX_ARABIC_FALLBACK_HH */
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698