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

Side by Side Diff: third_party/harfbuzz-ng/src/hb-shape-plan.cc

Issue 205003003: Update harfbuzz-ng to 0.9.27 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: w/missing files Created 6 years, 9 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 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 hb_shape_plan_t * 100 hb_shape_plan_t *
101 hb_shape_plan_create (hb_face_t *face, 101 hb_shape_plan_create (hb_face_t *face,
102 const hb_segment_properties_t *props, 102 const hb_segment_properties_t *props,
103 const hb_feature_t *user_features, 103 const hb_feature_t *user_features,
104 unsigned int num_user_features, 104 unsigned int num_user_features,
105 const char * const *shaper_list) 105 const char * const *shaper_list)
106 { 106 {
107 assert (props->direction != HB_DIRECTION_INVALID); 107 assert (props->direction != HB_DIRECTION_INVALID);
108 108
109 hb_shape_plan_t *shape_plan; 109 hb_shape_plan_t *shape_plan;
110 hb_feature_t *features = NULL;
110 111
111 if (unlikely (!face)) 112 if (unlikely (!face))
112 face = hb_face_get_empty (); 113 face = hb_face_get_empty ();
113 if (unlikely (!props || hb_object_is_inert (face))) 114 if (unlikely (!props || hb_object_is_inert (face)))
114 return hb_shape_plan_get_empty (); 115 return hb_shape_plan_get_empty ();
115 if (!(shape_plan = hb_object_create<hb_shape_plan_t> ())) 116 if (num_user_features && !(features = (hb_feature_t *) malloc (num_user_featur es * sizeof (hb_feature_t))))
116 return hb_shape_plan_get_empty (); 117 return hb_shape_plan_get_empty ();
118 if (!(shape_plan = hb_object_create<hb_shape_plan_t> ())) {
119 free (features);
120 return hb_shape_plan_get_empty ();
121 }
117 122
118 hb_face_make_immutable (face); 123 hb_face_make_immutable (face);
119 shape_plan->default_shaper_list = shaper_list == NULL; 124 shape_plan->default_shaper_list = shaper_list == NULL;
120 shape_plan->face_unsafe = face; 125 shape_plan->face_unsafe = face;
121 shape_plan->props = *props; 126 shape_plan->props = *props;
127 shape_plan->num_user_features = num_user_features;
128 shape_plan->user_features = features;
129 if (num_user_features)
130 memcpy (features, user_features, num_user_features * sizeof (hb_feature_t));
122 131
123 hb_shape_plan_plan (shape_plan, user_features, num_user_features, shaper_list) ; 132 hb_shape_plan_plan (shape_plan, user_features, num_user_features, shaper_list) ;
124 133
125 return shape_plan; 134 return shape_plan;
126 } 135 }
127 136
128 /** 137 /**
129 * hb_shape_plan_get_empty: 138 * hb_shape_plan_get_empty:
130 * 139 *
131 * 140 *
132 * 141 *
133 * Return value: (transfer full): 142 * Return value: (transfer full):
134 * 143 *
135 * Since: 1.0 144 * Since: 1.0
136 **/ 145 **/
137 hb_shape_plan_t * 146 hb_shape_plan_t *
138 hb_shape_plan_get_empty (void) 147 hb_shape_plan_get_empty (void)
139 { 148 {
140 static const hb_shape_plan_t _hb_shape_plan_nil = { 149 static const hb_shape_plan_t _hb_shape_plan_nil = {
141 HB_OBJECT_HEADER_STATIC, 150 HB_OBJECT_HEADER_STATIC,
142 151
143 true, /* default_shaper_list */ 152 true, /* default_shaper_list */
144 NULL, /* face */ 153 NULL, /* face */
145 HB_SEGMENT_PROPERTIES_DEFAULT, /* props */ 154 HB_SEGMENT_PROPERTIES_DEFAULT, /* props */
146 155
147 NULL, /* shaper_func */ 156 NULL, /* shaper_func */
148 NULL, /* shaper_name */ 157 NULL, /* shaper_name */
149 158
159 NULL, /* user_features */
160 0, /* num_user_featurs */
161
150 { 162 {
151 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID, 163 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID,
152 #include "hb-shaper-list.hh" 164 #include "hb-shaper-list.hh"
153 #undef HB_SHAPER_IMPLEMENT 165 #undef HB_SHAPER_IMPLEMENT
154 } 166 }
155 }; 167 };
156 168
157 return const_cast<hb_shape_plan_t *> (&_hb_shape_plan_nil); 169 return const_cast<hb_shape_plan_t *> (&_hb_shape_plan_nil);
158 } 170 }
159 171
(...skipping 23 matching lines...) Expand all
183 **/ 195 **/
184 void 196 void
185 hb_shape_plan_destroy (hb_shape_plan_t *shape_plan) 197 hb_shape_plan_destroy (hb_shape_plan_t *shape_plan)
186 { 198 {
187 if (!hb_object_destroy (shape_plan)) return; 199 if (!hb_object_destroy (shape_plan)) return;
188 200
189 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, shape_plan); 201 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, shape_plan);
190 #include "hb-shaper-list.hh" 202 #include "hb-shaper-list.hh"
191 #undef HB_SHAPER_IMPLEMENT 203 #undef HB_SHAPER_IMPLEMENT
192 204
205 free (shape_plan->user_features);
206
193 free (shape_plan); 207 free (shape_plan);
194 } 208 }
195 209
196 /** 210 /**
197 * hb_shape_plan_set_user_data: (skip) 211 * hb_shape_plan_set_user_data: (skip)
198 * @shape_plan: a shape plan. 212 * @shape_plan: a shape plan.
199 * @key: 213 * @key:
200 * @data: 214 * @data:
201 * @destroy: 215 * @destroy:
202 * @replace: 216 * @replace:
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 306
293 #if 0 307 #if 0
294 static unsigned int 308 static unsigned int
295 hb_shape_plan_hash (const hb_shape_plan_t *shape_plan) 309 hb_shape_plan_hash (const hb_shape_plan_t *shape_plan)
296 { 310 {
297 return hb_segment_properties_hash (&shape_plan->props) + 311 return hb_segment_properties_hash (&shape_plan->props) +
298 shape_plan->default_shaper_list ? 0 : (intptr_t) shape_plan->shaper_fun c; 312 shape_plan->default_shaper_list ? 0 : (intptr_t) shape_plan->shaper_fun c;
299 } 313 }
300 #endif 314 #endif
301 315
302 /* TODO no user-feature caching for now. */ 316 /* User-feature caching is currently somewhat dumb:
317 * it only finds matches where the feature array is identical,
318 * not cases where the feature lists would be compatible for plan purposes
319 * but have different ranges, for example.
320 */
303 struct hb_shape_plan_proposal_t 321 struct hb_shape_plan_proposal_t
304 { 322 {
305 const hb_segment_properties_t props; 323 const hb_segment_properties_t props;
306 const char * const *shaper_list; 324 const char * const *shaper_list;
325 const hb_feature_t *user_features;
326 unsigned int num_user_features;
307 hb_shape_func_t *shaper_func; 327 hb_shape_func_t *shaper_func;
308 }; 328 };
309 329
330 static inline hb_bool_t
331 hb_shape_plan_user_features_match (const hb_shape_plan_t *shape_plan,
332 const hb_shape_plan_proposal_t *proposal)
333 {
334 if (proposal->num_user_features != shape_plan->num_user_features) return false ;
335 for (unsigned int i = 0, n = proposal->num_user_features; i < n; i++)
336 if (proposal->user_features[i].tag != shape_plan->user_features[i].tag | |
337 proposal->user_features[i].value != shape_plan->user_features[i].value | |
338 proposal->user_features[i].start != shape_plan->user_features[i].start | |
339 proposal->user_features[i].end != shape_plan->user_features[i].end) re turn false;
340 return true;
341 }
342
310 static hb_bool_t 343 static hb_bool_t
311 hb_shape_plan_matches (const hb_shape_plan_t *shape_plan, 344 hb_shape_plan_matches (const hb_shape_plan_t *shape_plan,
312 const hb_shape_plan_proposal_t *proposal) 345 const hb_shape_plan_proposal_t *proposal)
313 { 346 {
314 return hb_segment_properties_equal (&shape_plan->props, &proposal->props) && 347 return hb_segment_properties_equal (&shape_plan->props, &proposal->props) &&
348 hb_shape_plan_user_features_match (shape_plan, proposal) &&
315 ((shape_plan->default_shaper_list && proposal->shaper_list == NULL) || 349 ((shape_plan->default_shaper_list && proposal->shaper_list == NULL) ||
316 (shape_plan->shaper_func == proposal->shaper_func)); 350 (shape_plan->shaper_func == proposal->shaper_func));
317 } 351 }
318 352
353 static inline hb_bool_t
354 hb_non_global_user_features_present (const hb_feature_t *user_features,
355 unsigned int num_user_features)
356 {
357 while (num_user_features)
358 if (user_features->start != 0 || user_features->end != (unsigned int) -1)
359 return true;
360 else
361 num_user_features--, user_features++;
362 return false;
363 }
364
319 /** 365 /**
320 * hb_shape_plan_create_cached: 366 * hb_shape_plan_create_cached:
321 * @face: 367 * @face:
322 * @props: 368 * @props:
323 * @user_features: (array length=num_user_features): 369 * @user_features: (array length=num_user_features):
324 * @num_user_features: 370 * @num_user_features:
325 * @shaper_list: (array zero-terminated=1): 371 * @shaper_list: (array zero-terminated=1):
326 * 372 *
327 * 373 *
328 * 374 *
329 * Return value: (transfer full): 375 * Return value: (transfer full):
330 * 376 *
331 * Since: 1.0 377 * Since: 1.0
332 **/ 378 **/
333 hb_shape_plan_t * 379 hb_shape_plan_t *
334 hb_shape_plan_create_cached (hb_face_t *face, 380 hb_shape_plan_create_cached (hb_face_t *face,
335 const hb_segment_properties_t *props, 381 const hb_segment_properties_t *props,
336 const hb_feature_t *user_features, 382 const hb_feature_t *user_features,
337 unsigned int num_user_features, 383 unsigned int num_user_features,
338 const char * const *shaper_list) 384 const char * const *shaper_list)
339 { 385 {
340 if (num_user_features)
341 return hb_shape_plan_create (face, props, user_features, num_user_features, shaper_list);
342
343 hb_shape_plan_proposal_t proposal = { 386 hb_shape_plan_proposal_t proposal = {
344 *props, 387 *props,
345 shaper_list, 388 shaper_list,
389 user_features,
390 num_user_features,
346 NULL 391 NULL
347 }; 392 };
348 393
349 if (shaper_list) { 394 if (shaper_list) {
350 /* Choose shaper. Adapted from hb_shape_plan_plan(). */ 395 /* Choose shaper. Adapted from hb_shape_plan_plan(). */
351 #define HB_SHAPER_PLAN(shaper) \ 396 #define HB_SHAPER_PLAN(shaper) \
352 HB_STMT_START { \ 397 HB_STMT_START { \
353 if (hb_##shaper##_shaper_face_data_ensure (face)) \ 398 if (hb_##shaper##_shaper_face_data_ensure (face)) \
354 proposal.shaper_func = _hb_##shaper##_shape; \ 399 proposal.shaper_func = _hb_##shaper##_shape; \
355 } HB_STMT_END 400 } HB_STMT_END
(...skipping 17 matching lines...) Expand all
373 retry: 418 retry:
374 hb_face_t::plan_node_t *cached_plan_nodes = (hb_face_t::plan_node_t *) hb_atom ic_ptr_get (&face->shape_plans); 419 hb_face_t::plan_node_t *cached_plan_nodes = (hb_face_t::plan_node_t *) hb_atom ic_ptr_get (&face->shape_plans);
375 for (hb_face_t::plan_node_t *node = cached_plan_nodes; node; node = node->next ) 420 for (hb_face_t::plan_node_t *node = cached_plan_nodes; node; node = node->next )
376 if (hb_shape_plan_matches (node->shape_plan, &proposal)) 421 if (hb_shape_plan_matches (node->shape_plan, &proposal))
377 return hb_shape_plan_reference (node->shape_plan); 422 return hb_shape_plan_reference (node->shape_plan);
378 423
379 /* Not found. */ 424 /* Not found. */
380 425
381 hb_shape_plan_t *shape_plan = hb_shape_plan_create (face, props, user_features , num_user_features, shaper_list); 426 hb_shape_plan_t *shape_plan = hb_shape_plan_create (face, props, user_features , num_user_features, shaper_list);
382 427
428 /* Don't add the plan to the cache if there were user features with non-global ranges */
429
430 if (hb_non_global_user_features_present (user_features, num_user_features))
431 return shape_plan;
432
383 hb_face_t::plan_node_t *node = (hb_face_t::plan_node_t *) calloc (1, sizeof (h b_face_t::plan_node_t)); 433 hb_face_t::plan_node_t *node = (hb_face_t::plan_node_t *) calloc (1, sizeof (h b_face_t::plan_node_t));
384 if (unlikely (!node)) 434 if (unlikely (!node))
385 return shape_plan; 435 return shape_plan;
386 436
387 node->shape_plan = shape_plan; 437 node->shape_plan = shape_plan;
388 node->next = cached_plan_nodes; 438 node->next = cached_plan_nodes;
389 439
390 if (!hb_atomic_ptr_cmpexch (&face->shape_plans, cached_plan_nodes, node)) { 440 if (!hb_atomic_ptr_cmpexch (&face->shape_plans, cached_plan_nodes, node)) {
391 hb_shape_plan_destroy (shape_plan); 441 hb_shape_plan_destroy (shape_plan);
392 free (node); 442 free (node);
(...skipping 11 matching lines...) Expand all
404 * 454 *
405 * Return value: (transfer none): 455 * Return value: (transfer none):
406 * 456 *
407 * Since: 1.0 457 * Since: 1.0
408 **/ 458 **/
409 const char * 459 const char *
410 hb_shape_plan_get_shaper (hb_shape_plan_t *shape_plan) 460 hb_shape_plan_get_shaper (hb_shape_plan_t *shape_plan)
411 { 461 {
412 return shape_plan->shaper_name; 462 return shape_plan->shaper_name;
413 } 463 }
OLDNEW
« no previous file with comments | « third_party/harfbuzz-ng/src/hb-set-private.hh ('k') | third_party/harfbuzz-ng/src/hb-shape-plan-private.hh » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698