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

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

Issue 2622553002: Roll HarfBuzz to 1.4.1 (Closed)
Patch Set: Linux rebaselines Created 3 years, 11 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 28 matching lines...) Expand all
39 HB_SHAPER_DATA_ENSURE_DECLARE(shaper, face) \ 39 HB_SHAPER_DATA_ENSURE_DECLARE(shaper, face) \
40 HB_SHAPER_DATA_ENSURE_DECLARE(shaper, font) 40 HB_SHAPER_DATA_ENSURE_DECLARE(shaper, font)
41 #include "hb-shaper-list.hh" 41 #include "hb-shaper-list.hh"
42 #undef HB_SHAPER_IMPLEMENT 42 #undef HB_SHAPER_IMPLEMENT
43 43
44 44
45 static void 45 static void
46 hb_shape_plan_plan (hb_shape_plan_t *shape_plan, 46 hb_shape_plan_plan (hb_shape_plan_t *shape_plan,
47 const hb_feature_t *user_features, 47 const hb_feature_t *user_features,
48 unsigned int num_user_features, 48 unsigned int num_user_features,
49 const int *coords,
50 unsigned int num_coords,
49 const char * const *shaper_list) 51 const char * const *shaper_list)
50 { 52 {
51 DEBUG_MSG_FUNC (SHAPE_PLAN, shape_plan, 53 DEBUG_MSG_FUNC (SHAPE_PLAN, shape_plan,
52 » » "num_features=%d shaper_list=%p", 54 » » "num_features=%d num_coords=%d shaper_list=%p",
53 num_user_features, 55 num_user_features,
56 num_coords,
54 shaper_list); 57 shaper_list);
55 58
56 const hb_shaper_pair_t *shapers = _hb_shapers_get (); 59 const hb_shaper_pair_t *shapers = _hb_shapers_get ();
57 60
58 #define HB_SHAPER_PLAN(shaper) \ 61 #define HB_SHAPER_PLAN(shaper) \
59 HB_STMT_START { \ 62 HB_STMT_START { \
60 if (hb_##shaper##_shaper_face_data_ensure (shape_plan->face_unsafe)) { \ 63 if (hb_##shaper##_shaper_face_data_ensure (shape_plan->face_unsafe)) { \
61 HB_SHAPER_DATA (shaper, shape_plan) = \ 64 HB_SHAPER_DATA (shaper, shape_plan) = \
62 » HB_SHAPER_DATA_CREATE_FUNC (shaper, shape_plan) (shape_plan, user_ features, num_user_features); \ 65 » HB_SHAPER_DATA_CREATE_FUNC (shaper, shape_plan) (shape_plan, \
66 » » » » » » » user_features, nu m_user_features, \
67 » » » » » » » coords, num_coord s); \
63 shape_plan->shaper_func = _hb_##shaper##_shape; \ 68 shape_plan->shaper_func = _hb_##shaper##_shape; \
64 shape_plan->shaper_name = #shaper; \ 69 shape_plan->shaper_name = #shaper; \
65 return; \ 70 return; \
66 } \ 71 } \
67 } HB_STMT_END 72 } HB_STMT_END
68 73
69 if (likely (!shaper_list)) { 74 if (likely (!shaper_list)) {
70 for (unsigned int i = 0; i < HB_SHAPERS_COUNT; i++) 75 for (unsigned int i = 0; i < HB_SHAPERS_COUNT; i++)
71 if (0) 76 if (0)
72 ; 77 ;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 * 113 *
109 * Since: 0.9.7 114 * Since: 0.9.7
110 **/ 115 **/
111 hb_shape_plan_t * 116 hb_shape_plan_t *
112 hb_shape_plan_create (hb_face_t *face, 117 hb_shape_plan_create (hb_face_t *face,
113 const hb_segment_properties_t *props, 118 const hb_segment_properties_t *props,
114 const hb_feature_t *user_features, 119 const hb_feature_t *user_features,
115 unsigned int num_user_features, 120 unsigned int num_user_features,
116 const char * const *shaper_list) 121 const char * const *shaper_list)
117 { 122 {
123 return hb_shape_plan_create2 (face, props,
124 user_features, num_user_features,
125 NULL, 0,
126 shaper_list);
127 }
128
129 hb_shape_plan_t *
130 hb_shape_plan_create2 (hb_face_t *face,
131 const hb_segment_properties_t *props,
132 const hb_feature_t *user_features,
133 unsigned int num_user_features,
134 const int *orig_coords,
135 unsigned int num_coords,
136 const char * const *shaper_list)
137 {
118 DEBUG_MSG_FUNC (SHAPE_PLAN, NULL, 138 DEBUG_MSG_FUNC (SHAPE_PLAN, NULL,
119 » » "face=%p num_features=%d shaper_list=%p", 139 » » "face=%p num_features=%d num_coords=%d shaper_list=%p",
120 face, 140 face,
121 num_user_features, 141 num_user_features,
142 num_coords,
122 shaper_list); 143 shaper_list);
123 144
124 hb_shape_plan_t *shape_plan; 145 hb_shape_plan_t *shape_plan;
125 hb_feature_t *features = NULL; 146 hb_feature_t *features = NULL;
147 int *coords = NULL;
126 148
127 if (unlikely (!face)) 149 if (unlikely (!face))
128 face = hb_face_get_empty (); 150 face = hb_face_get_empty ();
129 if (unlikely (!props)) 151 if (unlikely (!props))
130 return hb_shape_plan_get_empty (); 152 return hb_shape_plan_get_empty ();
131 if (num_user_features && !(features = (hb_feature_t *) calloc (num_user_featur es, sizeof (hb_feature_t)))) 153 if (num_user_features && !(features = (hb_feature_t *) calloc (num_user_featur es, sizeof (hb_feature_t))))
132 return hb_shape_plan_get_empty (); 154 return hb_shape_plan_get_empty ();
133 if (!(shape_plan = hb_object_create<hb_shape_plan_t> ())) { 155 if (num_coords && !(coords = (int *) calloc (num_coords, sizeof (int))))
156 {
134 free (features); 157 free (features);
135 return hb_shape_plan_get_empty (); 158 return hb_shape_plan_get_empty ();
136 } 159 }
160 if (!(shape_plan = hb_object_create<hb_shape_plan_t> ()))
161 {
162 free (coords);
163 free (features);
164 return hb_shape_plan_get_empty ();
165 }
137 166
138 assert (props->direction != HB_DIRECTION_INVALID); 167 assert (props->direction != HB_DIRECTION_INVALID);
139 168
140 hb_face_make_immutable (face); 169 hb_face_make_immutable (face);
141 shape_plan->default_shaper_list = shaper_list == NULL; 170 shape_plan->default_shaper_list = shaper_list == NULL;
142 shape_plan->face_unsafe = face; 171 shape_plan->face_unsafe = face;
143 shape_plan->props = *props; 172 shape_plan->props = *props;
144 shape_plan->num_user_features = num_user_features; 173 shape_plan->num_user_features = num_user_features;
145 shape_plan->user_features = features; 174 shape_plan->user_features = features;
146 if (num_user_features) 175 if (num_user_features)
147 memcpy (features, user_features, num_user_features * sizeof (hb_feature_t)); 176 memcpy (features, user_features, num_user_features * sizeof (hb_feature_t));
177 shape_plan->num_coords = num_coords;
178 shape_plan->coords = coords;
179 if (num_coords)
180 memcpy (coords, orig_coords, num_coords * sizeof (int));
148 181
149 hb_shape_plan_plan (shape_plan, user_features, num_user_features, shaper_list) ; 182 hb_shape_plan_plan (shape_plan,
183 » » user_features, num_user_features,
184 » » coords, num_coords,
185 » » shaper_list);
150 186
151 return shape_plan; 187 return shape_plan;
152 } 188 }
153 189
154 /** 190 /**
155 * hb_shape_plan_get_empty: 191 * hb_shape_plan_get_empty:
156 * 192 *
157 * 193 *
158 * 194 *
159 * Return value: (transfer full): 195 * Return value: (transfer full):
160 * 196 *
161 * Since: 0.9.7 197 * Since: 0.9.7
162 **/ 198 **/
163 hb_shape_plan_t * 199 hb_shape_plan_t *
164 hb_shape_plan_get_empty (void) 200 hb_shape_plan_get_empty (void)
165 { 201 {
166 static const hb_shape_plan_t _hb_shape_plan_nil = { 202 static const hb_shape_plan_t _hb_shape_plan_nil = {
167 HB_OBJECT_HEADER_STATIC, 203 HB_OBJECT_HEADER_STATIC,
168 204
169 true, /* default_shaper_list */ 205 true, /* default_shaper_list */
170 NULL, /* face */ 206 NULL, /* face */
171 HB_SEGMENT_PROPERTIES_DEFAULT, /* props */ 207 HB_SEGMENT_PROPERTIES_DEFAULT, /* props */
172 208
173 NULL, /* shaper_func */ 209 NULL, /* shaper_func */
174 NULL, /* shaper_name */ 210 NULL, /* shaper_name */
175 211
176 NULL, /* user_features */ 212 NULL, /* user_features */
177 0, /* num_user_featurs */ 213 0, /* num_user_featurs */
178 214
215 NULL, /* coords */
216 0, /* num_coords */
217
179 { 218 {
180 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID, 219 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID,
181 #include "hb-shaper-list.hh" 220 #include "hb-shaper-list.hh"
182 #undef HB_SHAPER_IMPLEMENT 221 #undef HB_SHAPER_IMPLEMENT
183 } 222 }
184 }; 223 };
185 224
186 return const_cast<hb_shape_plan_t *> (&_hb_shape_plan_nil); 225 return const_cast<hb_shape_plan_t *> (&_hb_shape_plan_nil);
187 } 226 }
188 227
(...skipping 24 matching lines...) Expand all
213 void 252 void
214 hb_shape_plan_destroy (hb_shape_plan_t *shape_plan) 253 hb_shape_plan_destroy (hb_shape_plan_t *shape_plan)
215 { 254 {
216 if (!hb_object_destroy (shape_plan)) return; 255 if (!hb_object_destroy (shape_plan)) return;
217 256
218 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, shape_plan); 257 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, shape_plan);
219 #include "hb-shaper-list.hh" 258 #include "hb-shaper-list.hh"
220 #undef HB_SHAPER_IMPLEMENT 259 #undef HB_SHAPER_IMPLEMENT
221 260
222 free (shape_plan->user_features); 261 free (shape_plan->user_features);
262 free (shape_plan->coords);
223 263
224 free (shape_plan); 264 free (shape_plan);
225 } 265 }
226 266
227 /** 267 /**
228 * hb_shape_plan_set_user_data: (skip) 268 * hb_shape_plan_set_user_data: (skip)
229 * @shape_plan: a shape plan. 269 * @shape_plan: a shape plan.
230 * @key: 270 * @key:
231 * @data: 271 * @data:
232 * @destroy: 272 * @destroy:
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
344 * it only finds matches where the feature array is identical, 384 * it only finds matches where the feature array is identical,
345 * not cases where the feature lists would be compatible for plan purposes 385 * not cases where the feature lists would be compatible for plan purposes
346 * but have different ranges, for example. 386 * but have different ranges, for example.
347 */ 387 */
348 struct hb_shape_plan_proposal_t 388 struct hb_shape_plan_proposal_t
349 { 389 {
350 const hb_segment_properties_t props; 390 const hb_segment_properties_t props;
351 const char * const *shaper_list; 391 const char * const *shaper_list;
352 const hb_feature_t *user_features; 392 const hb_feature_t *user_features;
353 unsigned int num_user_features; 393 unsigned int num_user_features;
394 const int *coords;
395 unsigned int num_coords;
354 hb_shape_func_t *shaper_func; 396 hb_shape_func_t *shaper_func;
355 }; 397 };
356 398
357 static inline hb_bool_t 399 static inline hb_bool_t
358 hb_shape_plan_user_features_match (const hb_shape_plan_t *shape_plan, 400 hb_shape_plan_user_features_match (const hb_shape_plan_t *shape_plan,
359 const hb_shape_plan_proposal_t *proposal) 401 const hb_shape_plan_proposal_t *proposal)
360 { 402 {
361 if (proposal->num_user_features != shape_plan->num_user_features) return false ; 403 if (proposal->num_user_features != shape_plan->num_user_features)
404 return false;
362 for (unsigned int i = 0, n = proposal->num_user_features; i < n; i++) 405 for (unsigned int i = 0, n = proposal->num_user_features; i < n; i++)
363 if (proposal->user_features[i].tag != shape_plan->user_features[i].tag | | 406 if (proposal->user_features[i].tag != shape_plan->user_features[i].tag | |
364 proposal->user_features[i].value != shape_plan->user_features[i].value | | 407 proposal->user_features[i].value != shape_plan->user_features[i].value | |
365 proposal->user_features[i].start != shape_plan->user_features[i].start | | 408 proposal->user_features[i].start != shape_plan->user_features[i].start | |
366 proposal->user_features[i].end != shape_plan->user_features[i].end) re turn false; 409 proposal->user_features[i].end != shape_plan->user_features[i].end)
410 return false;
367 return true; 411 return true;
368 } 412 }
369 413
414 static inline hb_bool_t
415 hb_shape_plan_coords_match (const hb_shape_plan_t *shape_plan,
416 const hb_shape_plan_proposal_t *proposal)
417 {
418 if (proposal->num_coords != shape_plan->num_coords)
419 return false;
420 for (unsigned int i = 0, n = proposal->num_coords; i < n; i++)
421 if (proposal->coords[i] != shape_plan->coords[i])
422 return false;
423 return true;
424 }
425
370 static hb_bool_t 426 static hb_bool_t
371 hb_shape_plan_matches (const hb_shape_plan_t *shape_plan, 427 hb_shape_plan_matches (const hb_shape_plan_t *shape_plan,
372 const hb_shape_plan_proposal_t *proposal) 428 const hb_shape_plan_proposal_t *proposal)
373 { 429 {
374 return hb_segment_properties_equal (&shape_plan->props, &proposal->props) && 430 return hb_segment_properties_equal (&shape_plan->props, &proposal->props) &&
375 hb_shape_plan_user_features_match (shape_plan, proposal) && 431 hb_shape_plan_user_features_match (shape_plan, proposal) &&
432 hb_shape_plan_coords_match (shape_plan, proposal) &&
376 ((shape_plan->default_shaper_list && proposal->shaper_list == NULL) || 433 ((shape_plan->default_shaper_list && proposal->shaper_list == NULL) ||
377 (shape_plan->shaper_func == proposal->shaper_func)); 434 (shape_plan->shaper_func == proposal->shaper_func));
378 } 435 }
379 436
380 static inline hb_bool_t 437 static inline hb_bool_t
381 hb_non_global_user_features_present (const hb_feature_t *user_features, 438 hb_non_global_user_features_present (const hb_feature_t *user_features,
382 unsigned int num_user_features) 439 unsigned int num_user_features)
383 { 440 {
384 while (num_user_features) 441 while (num_user_features)
385 if (user_features->start != 0 || user_features->end != (unsigned int) -1) 442 if (user_features->start != 0 || user_features->end != (unsigned int) -1)
386 return true; 443 return true;
387 else 444 else
388 num_user_features--, user_features++; 445 num_user_features--, user_features++;
389 return false; 446 return false;
390 } 447 }
391 448
449 static inline hb_bool_t
450 hb_coords_present (const int *coords,
451 unsigned int num_coords)
452 {
453 return num_coords != 0;
454 }
455
392 /** 456 /**
393 * hb_shape_plan_create_cached: 457 * hb_shape_plan_create_cached:
394 * @face: 458 * @face:
395 * @props: 459 * @props:
396 * @user_features: (array length=num_user_features): 460 * @user_features: (array length=num_user_features):
397 * @num_user_features: 461 * @num_user_features:
398 * @shaper_list: (array zero-terminated=1): 462 * @shaper_list: (array zero-terminated=1):
399 * 463 *
400 * 464 *
401 * 465 *
402 * Return value: (transfer full): 466 * Return value: (transfer full):
403 * 467 *
404 * Since: 0.9.7 468 * Since: 0.9.7
405 **/ 469 **/
406 hb_shape_plan_t * 470 hb_shape_plan_t *
407 hb_shape_plan_create_cached (hb_face_t *face, 471 hb_shape_plan_create_cached (hb_face_t *face,
408 const hb_segment_properties_t *props, 472 const hb_segment_properties_t *props,
409 const hb_feature_t *user_features, 473 const hb_feature_t *user_features,
410 unsigned int num_user_features, 474 unsigned int num_user_features,
411 const char * const *shaper_list) 475 const char * const *shaper_list)
412 { 476 {
477 return hb_shape_plan_create_cached2 (face, props,
478 user_features, num_user_features,
479 NULL, 0,
480 shaper_list);
481 }
482
483 hb_shape_plan_t *
484 hb_shape_plan_create_cached2 (hb_face_t *face,
485 const hb_segment_properties_t *props,
486 const hb_feature_t *user_features,
487 unsigned int num_user_features,
488 const int *coords,
489 unsigned int num_coords,
490 const char * const *shaper_list)
491 {
413 DEBUG_MSG_FUNC (SHAPE_PLAN, NULL, 492 DEBUG_MSG_FUNC (SHAPE_PLAN, NULL,
414 "face=%p num_features=%d shaper_list=%p", 493 "face=%p num_features=%d shaper_list=%p",
415 face, 494 face,
416 num_user_features, 495 num_user_features,
417 shaper_list); 496 shaper_list);
418 497
419 hb_shape_plan_proposal_t proposal = { 498 hb_shape_plan_proposal_t proposal = {
420 *props, 499 *props,
421 shaper_list, 500 shaper_list,
422 user_features, 501 user_features,
(...skipping 26 matching lines...) Expand all
449 hb_face_t::plan_node_t *cached_plan_nodes = (hb_face_t::plan_node_t *) hb_atom ic_ptr_get (&face->shape_plans); 528 hb_face_t::plan_node_t *cached_plan_nodes = (hb_face_t::plan_node_t *) hb_atom ic_ptr_get (&face->shape_plans);
450 for (hb_face_t::plan_node_t *node = cached_plan_nodes; node; node = node->next ) 529 for (hb_face_t::plan_node_t *node = cached_plan_nodes; node; node = node->next )
451 if (hb_shape_plan_matches (node->shape_plan, &proposal)) 530 if (hb_shape_plan_matches (node->shape_plan, &proposal))
452 { 531 {
453 DEBUG_MSG_FUNC (SHAPE_PLAN, node->shape_plan, "fulfilled from cache"); 532 DEBUG_MSG_FUNC (SHAPE_PLAN, node->shape_plan, "fulfilled from cache");
454 return hb_shape_plan_reference (node->shape_plan); 533 return hb_shape_plan_reference (node->shape_plan);
455 } 534 }
456 535
457 /* Not found. */ 536 /* Not found. */
458 537
459 hb_shape_plan_t *shape_plan = hb_shape_plan_create (face, props, user_features , num_user_features, shaper_list); 538 hb_shape_plan_t *shape_plan = hb_shape_plan_create2 (face, props,
539 » » » » » » user_features, num_user_f eatures,
540 » » » » » » coords, num_coords,
541 » » » » » » shaper_list);
460 542
461 /* Don't add to the cache if face is inert. */ 543 /* Don't add to the cache if face is inert. */
462 if (unlikely (hb_object_is_inert (face))) 544 if (unlikely (hb_object_is_inert (face)))
463 return shape_plan; 545 return shape_plan;
464 546
465 /* Don't add the plan to the cache if there were user features with non-global ranges */ 547 /* Don't add the plan to the cache if there were user features with non-global ranges */
466
467 if (hb_non_global_user_features_present (user_features, num_user_features)) 548 if (hb_non_global_user_features_present (user_features, num_user_features))
468 return shape_plan; 549 return shape_plan;
550 /* Don't add the plan to the cache if there were variation coordinates XXX Fix me. */
551 if (hb_coords_present (coords, num_coords))
552 return shape_plan;
469 553
470 hb_face_t::plan_node_t *node = (hb_face_t::plan_node_t *) calloc (1, sizeof (h b_face_t::plan_node_t)); 554 hb_face_t::plan_node_t *node = (hb_face_t::plan_node_t *) calloc (1, sizeof (h b_face_t::plan_node_t));
471 if (unlikely (!node)) 555 if (unlikely (!node))
472 return shape_plan; 556 return shape_plan;
473 557
474 node->shape_plan = shape_plan; 558 node->shape_plan = shape_plan;
475 node->next = cached_plan_nodes; 559 node->next = cached_plan_nodes;
476 560
477 if (!hb_atomic_ptr_cmpexch (&face->shape_plans, cached_plan_nodes, node)) { 561 if (!hb_atomic_ptr_cmpexch (&face->shape_plans, cached_plan_nodes, node)) {
478 hb_shape_plan_destroy (shape_plan); 562 hb_shape_plan_destroy (shape_plan);
(...skipping 13 matching lines...) Expand all
492 * 576 *
493 * Return value: (transfer none): 577 * Return value: (transfer none):
494 * 578 *
495 * Since: 0.9.7 579 * Since: 0.9.7
496 **/ 580 **/
497 const char * 581 const char *
498 hb_shape_plan_get_shaper (hb_shape_plan_t *shape_plan) 582 hb_shape_plan_get_shaper (hb_shape_plan_t *shape_plan)
499 { 583 {
500 return shape_plan->shaper_name; 584 return shape_plan->shaper_name;
501 } 585 }
OLDNEW
« no previous file with comments | « third_party/harfbuzz-ng/src/hb-shape-plan.h ('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