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

Side by Side Diff: third_party/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh

Issue 10915172: harfbuzz-ng roll (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 3 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 | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright © 2007,2008,2009,2010 Red Hat, Inc. 2 * Copyright © 2007,2008,2009,2010 Red Hat, Inc.
3 * Copyright © 2010,2012 Google, Inc. 3 * Copyright © 2010,2012 Google, Inc.
4 * 4 *
5 * This is part of HarfBuzz, a text shaping library. 5 * This is part of HarfBuzz, a text shaping library.
6 * 6 *
7 * Permission is hereby granted, without written agreement and without 7 * Permission is hereby granted, without written agreement and without
8 * license or royalty fees, to use, copy, modify, and distribute this 8 * license or royalty fees, to use, copy, modify, and distribute this
9 * software and its documentation for any purpose, provided that the 9 * software and its documentation for any purpose, provided that the
10 * above copyright notice and the following two paragraphs appear in 10 * above copyright notice and the following two paragraphs appear in
(...skipping 14 matching lines...) Expand all
25 * Red Hat Author(s): Behdad Esfahbod 25 * Red Hat Author(s): Behdad Esfahbod
26 * Google Author(s): Behdad Esfahbod 26 * Google Author(s): Behdad Esfahbod
27 */ 27 */
28 28
29 #ifndef HB_OT_LAYOUT_GPOS_TABLE_HH 29 #ifndef HB_OT_LAYOUT_GPOS_TABLE_HH
30 #define HB_OT_LAYOUT_GPOS_TABLE_HH 30 #define HB_OT_LAYOUT_GPOS_TABLE_HH
31 31
32 #include "hb-ot-layout-gsubgpos-private.hh" 32 #include "hb-ot-layout-gsubgpos-private.hh"
33 33
34 34
35 namespace OT {
36
35 37
36 /* buffer **position** var allocations */ 38 /* buffer **position** var allocations */
37 #define attach_lookback() var.u16[0] /* number of glyphs to go back to attach th is glyph to its base */ 39 #define attach_lookback() var.u16[0] /* number of glyphs to go back to attach th is glyph to its base */
38 #define cursive_chain() var.i16[1] /* character to which this connects, may be p ositive or negative */ 40 #define cursive_chain() var.i16[1] /* character to which this connects, may be p ositive or negative */
39 41
40 42
41 /* Shared Tables: ValueRecord, Anchor Table, and MarkArray */ 43 /* Shared Tables: ValueRecord, Anchor Table, and MarkArray */
42 44
43 typedef USHORT Value; 45 typedef USHORT Value;
44 46
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 { 220 {
219 *x = font->em_scale_x (xCoordinate); 221 *x = font->em_scale_x (xCoordinate);
220 *y = font->em_scale_y (yCoordinate); 222 *y = font->em_scale_y (yCoordinate);
221 } 223 }
222 224
223 inline bool sanitize (hb_sanitize_context_t *c) { 225 inline bool sanitize (hb_sanitize_context_t *c) {
224 TRACE_SANITIZE (); 226 TRACE_SANITIZE ();
225 return TRACE_RETURN (c->check_struct (this)); 227 return TRACE_RETURN (c->check_struct (this));
226 } 228 }
227 229
228 private: 230 protected:
229 USHORT format; /* Format identifier--format = 1 */ 231 USHORT format; /* Format identifier--format = 1 */
230 SHORT xCoordinate; /* Horizontal value--in design units */ 232 SHORT xCoordinate; /* Horizontal value--in design units */
231 SHORT yCoordinate; /* Vertical value--in design units */ 233 SHORT yCoordinate; /* Vertical value--in design units */
232 public: 234 public:
233 DEFINE_SIZE_STATIC (6); 235 DEFINE_SIZE_STATIC (6);
234 }; 236 };
235 237
236 struct AnchorFormat2 238 struct AnchorFormat2
237 { 239 {
238 friend struct Anchor; 240 friend struct Anchor;
239 241
240 private: 242 private:
241 inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id, 243 inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id,
242 hb_position_t *x, hb_position_t *y) const 244 hb_position_t *x, hb_position_t *y) const
243 { 245 {
244 unsigned int x_ppem = font->x_ppem; 246 unsigned int x_ppem = font->x_ppem;
245 unsigned int y_ppem = font->y_ppem; 247 unsigned int y_ppem = font->y_ppem;
246 hb_position_t cx, cy; 248 hb_position_t cx, cy;
247 hb_bool_t ret = false; 249 hb_bool_t ret = false;
248 250
249 if (x_ppem || y_ppem) 251 if (x_ppem || y_ppem)
250 » ret = hb_font_get_glyph_contour_point_for_origin (font, glyph_id, anchor Point, HB_DIRECTION_LTR, &cx, &cy); 252 » ret = font->get_glyph_contour_point_for_origin (glyph_id, anchorPoint, H B_DIRECTION_LTR, &cx, &cy);
251 *x = x_ppem && ret ? cx : font->em_scale_x (xCoordinate); 253 *x = x_ppem && ret ? cx : font->em_scale_x (xCoordinate);
252 *y = y_ppem && ret ? cy : font->em_scale_y (yCoordinate); 254 *y = y_ppem && ret ? cy : font->em_scale_y (yCoordinate);
253 } 255 }
254 256
255 inline bool sanitize (hb_sanitize_context_t *c) { 257 inline bool sanitize (hb_sanitize_context_t *c) {
256 TRACE_SANITIZE (); 258 TRACE_SANITIZE ();
257 return TRACE_RETURN (c->check_struct (this)); 259 return TRACE_RETURN (c->check_struct (this));
258 } 260 }
259 261
260 private: 262 protected:
261 USHORT format; /* Format identifier--format = 2 */ 263 USHORT format; /* Format identifier--format = 2 */
262 SHORT xCoordinate; /* Horizontal value--in design units */ 264 SHORT xCoordinate; /* Horizontal value--in design units */
263 SHORT yCoordinate; /* Vertical value--in design units */ 265 SHORT yCoordinate; /* Vertical value--in design units */
264 USHORT anchorPoint; /* Index to glyph contour point */ 266 USHORT anchorPoint; /* Index to glyph contour point */
265 public: 267 public:
266 DEFINE_SIZE_STATIC (8); 268 DEFINE_SIZE_STATIC (8);
267 }; 269 };
268 270
269 struct AnchorFormat3 271 struct AnchorFormat3
270 { 272 {
(...skipping 10 matching lines...) Expand all
281 *x += (this+xDeviceTable).get_x_delta (font); 283 *x += (this+xDeviceTable).get_x_delta (font);
282 if (font->y_ppem) 284 if (font->y_ppem)
283 *y += (this+yDeviceTable).get_x_delta (font); 285 *y += (this+yDeviceTable).get_x_delta (font);
284 } 286 }
285 287
286 inline bool sanitize (hb_sanitize_context_t *c) { 288 inline bool sanitize (hb_sanitize_context_t *c) {
287 TRACE_SANITIZE (); 289 TRACE_SANITIZE ();
288 return TRACE_RETURN (c->check_struct (this) && xDeviceTable.sanitize (c, thi s) && yDeviceTable.sanitize (c, this)); 290 return TRACE_RETURN (c->check_struct (this) && xDeviceTable.sanitize (c, thi s) && yDeviceTable.sanitize (c, this));
289 } 291 }
290 292
291 private: 293 protected:
292 USHORT format; /* Format identifier--format = 3 */ 294 USHORT format; /* Format identifier--format = 3 */
293 SHORT xCoordinate; /* Horizontal value--in design units */ 295 SHORT xCoordinate; /* Horizontal value--in design units */
294 SHORT yCoordinate; /* Vertical value--in design units */ 296 SHORT yCoordinate; /* Vertical value--in design units */
295 OffsetTo<Device> 297 OffsetTo<Device>
296 xDeviceTable; /* Offset to Device table for X 298 xDeviceTable; /* Offset to Device table for X
297 * coordinate-- from beginning of 299 * coordinate-- from beginning of
298 * Anchor table (may be NULL) */ 300 * Anchor table (may be NULL) */
299 OffsetTo<Device> 301 OffsetTo<Device>
300 yDeviceTable; /* Offset to Device table for Y 302 yDeviceTable; /* Offset to Device table for Y
301 * coordinate-- from beginning of 303 * coordinate-- from beginning of
(...skipping 20 matching lines...) Expand all
322 TRACE_SANITIZE (); 324 TRACE_SANITIZE ();
323 if (!u.format.sanitize (c)) return TRACE_RETURN (false); 325 if (!u.format.sanitize (c)) return TRACE_RETURN (false);
324 switch (u.format) { 326 switch (u.format) {
325 case 1: return TRACE_RETURN (u.format1.sanitize (c)); 327 case 1: return TRACE_RETURN (u.format1.sanitize (c));
326 case 2: return TRACE_RETURN (u.format2.sanitize (c)); 328 case 2: return TRACE_RETURN (u.format2.sanitize (c));
327 case 3: return TRACE_RETURN (u.format3.sanitize (c)); 329 case 3: return TRACE_RETURN (u.format3.sanitize (c));
328 default:return TRACE_RETURN (true); 330 default:return TRACE_RETURN (true);
329 } 331 }
330 } 332 }
331 333
332 private: 334 protected:
333 union { 335 union {
334 USHORT format; /* Format identifier */ 336 USHORT format; /* Format identifier */
335 AnchorFormat1 format1; 337 AnchorFormat1 format1;
336 AnchorFormat2 format2; 338 AnchorFormat2 format2;
337 AnchorFormat3 format3; 339 AnchorFormat3 format3;
338 } u; 340 } u;
339 public: 341 public:
340 DEFINE_SIZE_UNION (2, format); 342 DEFINE_SIZE_UNION (2, format);
341 }; 343 };
342 344
(...skipping 10 matching lines...) Expand all
353 if (!c->check_struct (this)) return TRACE_RETURN (false); 355 if (!c->check_struct (this)) return TRACE_RETURN (false);
354 if (unlikely (rows > 0 && cols >= ((unsigned int) -1) / rows)) return TRACE_ RETURN (false); 356 if (unlikely (rows > 0 && cols >= ((unsigned int) -1) / rows)) return TRACE_ RETURN (false);
355 unsigned int count = rows * cols; 357 unsigned int count = rows * cols;
356 if (!c->check_array (matrix, matrix[0].static_size, count)) return TRACE_RET URN (false); 358 if (!c->check_array (matrix, matrix[0].static_size, count)) return TRACE_RET URN (false);
357 for (unsigned int i = 0; i < count; i++) 359 for (unsigned int i = 0; i < count; i++)
358 if (!matrix[i].sanitize (c, this)) return TRACE_RETURN (false); 360 if (!matrix[i].sanitize (c, this)) return TRACE_RETURN (false);
359 return TRACE_RETURN (true); 361 return TRACE_RETURN (true);
360 } 362 }
361 363
362 USHORT rows; /* Number of rows */ 364 USHORT rows; /* Number of rows */
363 private: 365 protected:
364 OffsetTo<Anchor> 366 OffsetTo<Anchor>
365 matrix[VAR]; /* Matrix of offsets to Anchor tables-- 367 matrix[VAR]; /* Matrix of offsets to Anchor tables--
366 * from beginning of AnchorMatrix table */ 368 * from beginning of AnchorMatrix table */
367 public: 369 public:
368 DEFINE_SIZE_ARRAY (2, matrix); 370 DEFINE_SIZE_ARRAY (2, matrix);
369 }; 371 };
370 372
371 373
372 struct MarkRecord 374 struct MarkRecord
373 { 375 {
374 friend struct MarkArray; 376 friend struct MarkArray;
375 377
376 inline bool sanitize (hb_sanitize_context_t *c, void *base) { 378 inline bool sanitize (hb_sanitize_context_t *c, void *base) {
377 TRACE_SANITIZE (); 379 TRACE_SANITIZE ();
378 return TRACE_RETURN (c->check_struct (this) && markAnchor.sanitize (c, base) ); 380 return TRACE_RETURN (c->check_struct (this) && markAnchor.sanitize (c, base) );
379 } 381 }
380 382
381 private: 383 protected:
382 USHORT klass; /* Class defined for this mark */ 384 USHORT klass; /* Class defined for this mark */
383 OffsetTo<Anchor> 385 OffsetTo<Anchor>
384 markAnchor; /* Offset to Anchor table--from 386 markAnchor; /* Offset to Anchor table--from
385 * beginning of MarkArray table */ 387 * beginning of MarkArray table */
386 public: 388 public:
387 DEFINE_SIZE_STATIC (4); 389 DEFINE_SIZE_STATIC (4);
388 }; 390 };
389 391
390 struct MarkArray : ArrayOf<MarkRecord> /* Array of MarkRecords--in Coverage ord er */ 392 struct MarkArray : ArrayOf<MarkRecord> /* Array of MarkRecords--in Coverage ord er */
391 { 393 {
(...skipping 30 matching lines...) Expand all
422 }; 424 };
423 425
424 426
425 /* Lookups */ 427 /* Lookups */
426 428
427 struct SinglePosFormat1 429 struct SinglePosFormat1
428 { 430 {
429 friend struct SinglePos; 431 friend struct SinglePos;
430 432
431 private: 433 private:
434
435 inline const Coverage &get_coverage (void) const
436 {
437 return this+coverage;
438 }
439
432 inline bool apply (hb_apply_context_t *c) const 440 inline bool apply (hb_apply_context_t *c) const
433 { 441 {
434 TRACE_APPLY (); 442 TRACE_APPLY ();
435 unsigned int index = (this+coverage) (c->buffer->cur().codepoint); 443 unsigned int index = (this+coverage) (c->buffer->cur().codepoint);
436 if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); 444 if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
437 445
438 valueFormat.apply_value (c->font, c->direction, this, 446 valueFormat.apply_value (c->font, c->direction, this,
439 values, c->buffer->cur_pos()); 447 values, c->buffer->cur_pos());
440 448
441 c->buffer->idx++; 449 c->buffer->idx++;
442 return TRACE_RETURN (true); 450 return TRACE_RETURN (true);
443 } 451 }
444 452
445 inline bool sanitize (hb_sanitize_context_t *c) { 453 inline bool sanitize (hb_sanitize_context_t *c) {
446 TRACE_SANITIZE (); 454 TRACE_SANITIZE ();
447 return TRACE_RETURN (c->check_struct (this) && coverage.sanitize (c, this) & & valueFormat.sanitize_value (c, this, values)); 455 return TRACE_RETURN (c->check_struct (this) && coverage.sanitize (c, this) & & valueFormat.sanitize_value (c, this, values));
448 } 456 }
449 457
450 private: 458 protected:
451 USHORT format; /* Format identifier--format = 1 */ 459 USHORT format; /* Format identifier--format = 1 */
452 OffsetTo<Coverage> 460 OffsetTo<Coverage>
453 coverage; /* Offset to Coverage table--from 461 coverage; /* Offset to Coverage table--from
454 * beginning of subtable */ 462 * beginning of subtable */
455 ValueFormat valueFormat; /* Defines the types of data in the 463 ValueFormat valueFormat; /* Defines the types of data in the
456 * ValueRecord */ 464 * ValueRecord */
457 ValueRecord values; /* Defines positioning 465 ValueRecord values; /* Defines positioning
458 * value(s)--applied to all glyphs in 466 * value(s)--applied to all glyphs in
459 * the Coverage table */ 467 * the Coverage table */
460 public: 468 public:
461 DEFINE_SIZE_ARRAY (6, values); 469 DEFINE_SIZE_ARRAY (6, values);
462 }; 470 };
463 471
464 struct SinglePosFormat2 472 struct SinglePosFormat2
465 { 473 {
466 friend struct SinglePos; 474 friend struct SinglePos;
467 475
468 private: 476 private:
477
478 inline const Coverage &get_coverage (void) const
479 {
480 return this+coverage;
481 }
482
469 inline bool apply (hb_apply_context_t *c) const 483 inline bool apply (hb_apply_context_t *c) const
470 { 484 {
471 TRACE_APPLY (); 485 TRACE_APPLY ();
472 unsigned int index = (this+coverage) (c->buffer->cur().codepoint); 486 unsigned int index = (this+coverage) (c->buffer->cur().codepoint);
473 if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); 487 if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
474 488
475 if (likely (index >= valueCount)) return TRACE_RETURN (false); 489 if (likely (index >= valueCount)) return TRACE_RETURN (false);
476 490
477 valueFormat.apply_value (c->font, c->direction, this, 491 valueFormat.apply_value (c->font, c->direction, this,
478 &values[index * valueFormat.get_len ()], 492 &values[index * valueFormat.get_len ()],
479 c->buffer->cur_pos()); 493 c->buffer->cur_pos());
480 494
481 c->buffer->idx++; 495 c->buffer->idx++;
482 return TRACE_RETURN (true); 496 return TRACE_RETURN (true);
483 } 497 }
484 498
485 inline bool sanitize (hb_sanitize_context_t *c) { 499 inline bool sanitize (hb_sanitize_context_t *c) {
486 TRACE_SANITIZE (); 500 TRACE_SANITIZE ();
487 return TRACE_RETURN (c->check_struct (this) && coverage.sanitize (c, this) & & valueFormat.sanitize_values (c, this, values, valueCount)); 501 return TRACE_RETURN (c->check_struct (this) && coverage.sanitize (c, this) & & valueFormat.sanitize_values (c, this, values, valueCount));
488 } 502 }
489 503
490 private: 504 protected:
491 USHORT format; /* Format identifier--format = 2 */ 505 USHORT format; /* Format identifier--format = 2 */
492 OffsetTo<Coverage> 506 OffsetTo<Coverage>
493 coverage; /* Offset to Coverage table--from 507 coverage; /* Offset to Coverage table--from
494 * beginning of subtable */ 508 * beginning of subtable */
495 ValueFormat valueFormat; /* Defines the types of data in the 509 ValueFormat valueFormat; /* Defines the types of data in the
496 * ValueRecord */ 510 * ValueRecord */
497 USHORT valueCount; /* Number of ValueRecords */ 511 USHORT valueCount; /* Number of ValueRecords */
498 ValueRecord values; /* Array of ValueRecords--positioning 512 ValueRecord values; /* Array of ValueRecords--positioning
499 * values applied to glyphs */ 513 * values applied to glyphs */
500 public: 514 public:
501 DEFINE_SIZE_ARRAY (8, values); 515 DEFINE_SIZE_ARRAY (8, values);
502 }; 516 };
503 517
504 struct SinglePos 518 struct SinglePos
505 { 519 {
506 friend struct PosLookupSubTable; 520 friend struct PosLookupSubTable;
507 521
508 private: 522 private:
523
524 inline const Coverage &get_coverage (void) const
525 {
526 switch (u.format) {
527 case 1: return u.format1.get_coverage ();
528 case 2: return u.format2.get_coverage ();
529 default:return Null(Coverage);
530 }
531 }
532
509 inline bool apply (hb_apply_context_t *c) const 533 inline bool apply (hb_apply_context_t *c) const
510 { 534 {
511 TRACE_APPLY (); 535 TRACE_APPLY ();
512 switch (u.format) { 536 switch (u.format) {
513 case 1: return TRACE_RETURN (u.format1.apply (c)); 537 case 1: return TRACE_RETURN (u.format1.apply (c));
514 case 2: return TRACE_RETURN (u.format2.apply (c)); 538 case 2: return TRACE_RETURN (u.format2.apply (c));
515 default:return TRACE_RETURN (false); 539 default:return TRACE_RETURN (false);
516 } 540 }
517 } 541 }
518 542
519 inline bool sanitize (hb_sanitize_context_t *c) { 543 inline bool sanitize (hb_sanitize_context_t *c) {
520 TRACE_SANITIZE (); 544 TRACE_SANITIZE ();
521 if (!u.format.sanitize (c)) return TRACE_RETURN (false); 545 if (!u.format.sanitize (c)) return TRACE_RETURN (false);
522 switch (u.format) { 546 switch (u.format) {
523 case 1: return TRACE_RETURN (u.format1.sanitize (c)); 547 case 1: return TRACE_RETURN (u.format1.sanitize (c));
524 case 2: return TRACE_RETURN (u.format2.sanitize (c)); 548 case 2: return TRACE_RETURN (u.format2.sanitize (c));
525 default:return TRACE_RETURN (true); 549 default:return TRACE_RETURN (true);
526 } 550 }
527 } 551 }
528 552
529 private: 553 protected:
530 union { 554 union {
531 USHORT format; /* Format identifier */ 555 USHORT format; /* Format identifier */
532 SinglePosFormat1 format1; 556 SinglePosFormat1 format1;
533 SinglePosFormat2 format2; 557 SinglePosFormat2 format2;
534 } u; 558 } u;
535 }; 559 };
536 560
537 561
538 struct PairValueRecord 562 struct PairValueRecord
539 { 563 {
540 friend struct PairSet; 564 friend struct PairSet;
541 565
542 private: 566 protected:
543 GlyphID secondGlyph; /* GlyphID of second glyph in the 567 GlyphID secondGlyph; /* GlyphID of second glyph in the
544 * pair--first glyph is listed in the 568 * pair--first glyph is listed in the
545 * Coverage table */ 569 * Coverage table */
546 ValueRecord values; /* Positioning data for the first glyph 570 ValueRecord values; /* Positioning data for the first glyph
547 * followed by for second glyph */ 571 * followed by for second glyph */
548 public: 572 public:
549 DEFINE_SIZE_ARRAY (2, values); 573 DEFINE_SIZE_ARRAY (2, values);
550 }; 574 };
551 575
552 struct PairSet 576 struct PairSet
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
594 TRACE_SANITIZE (); 618 TRACE_SANITIZE ();
595 if (!(c->check_struct (this) 619 if (!(c->check_struct (this)
596 && c->check_array (array, USHORT::static_size * closure->stride, len))) r eturn TRACE_RETURN (false); 620 && c->check_array (array, USHORT::static_size * closure->stride, len))) r eturn TRACE_RETURN (false);
597 621
598 unsigned int count = len; 622 unsigned int count = len;
599 PairValueRecord *record = CastP<PairValueRecord> (array); 623 PairValueRecord *record = CastP<PairValueRecord> (array);
600 return TRACE_RETURN (closure->valueFormats[0].sanitize_values_stride_unsafe (c, closure->base, &record->values[0], count, closure->stride) 624 return TRACE_RETURN (closure->valueFormats[0].sanitize_values_stride_unsafe (c, closure->base, &record->values[0], count, closure->stride)
601 && closure->valueFormats[1].sanitize_values_stride_unsafe (c, closure->base, &record->values[closure->len1], count, closure->stride)); 625 && closure->valueFormats[1].sanitize_values_stride_unsafe (c, closure->base, &record->values[closure->len1], count, closure->stride));
602 } 626 }
603 627
604 private: 628 protected:
605 USHORT len; /* Number of PairValueRecords */ 629 USHORT len; /* Number of PairValueRecords */
606 USHORT array[VAR]; /* Array of PairValueRecords--ordered 630 USHORT array[VAR]; /* Array of PairValueRecords--ordered
607 * by GlyphID of the second glyph */ 631 * by GlyphID of the second glyph */
608 public: 632 public:
609 DEFINE_SIZE_ARRAY (2, array); 633 DEFINE_SIZE_ARRAY (2, array);
610 }; 634 };
611 635
612 struct PairPosFormat1 636 struct PairPosFormat1
613 { 637 {
614 friend struct PairPos; 638 friend struct PairPos;
615 639
616 private: 640 private:
641
642 inline const Coverage &get_coverage (void) const
643 {
644 return this+coverage;
645 }
646
617 inline bool apply (hb_apply_context_t *c) const 647 inline bool apply (hb_apply_context_t *c) const
618 { 648 {
619 TRACE_APPLY (); 649 TRACE_APPLY ();
620 hb_apply_context_t::mark_skipping_forward_iterator_t skippy_iter (c, c->buff er->idx, 1); 650 hb_apply_context_t::mark_skipping_forward_iterator_t skippy_iter (c, c->buff er->idx, 1);
621 if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); 651 if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
622 652
623 unsigned int index = (this+coverage) (c->buffer->cur().codepoint); 653 unsigned int index = (this+coverage) (c->buffer->cur().codepoint);
624 if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); 654 if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
625 655
626 if (!skippy_iter.next ()) return TRACE_RETURN (false); 656 if (!skippy_iter.next ()) return TRACE_RETURN (false);
627 657
628 return TRACE_RETURN ((this+pairSet[index]).apply (c, &valueFormat1, skippy_i ter.idx)); 658 return TRACE_RETURN ((this+pairSet[index]).apply (c, &valueFormat1, skippy_i ter.idx));
629 } 659 }
630 660
631 inline bool sanitize (hb_sanitize_context_t *c) { 661 inline bool sanitize (hb_sanitize_context_t *c) {
632 TRACE_SANITIZE (); 662 TRACE_SANITIZE ();
633 663
634 unsigned int len1 = valueFormat1.get_len (); 664 unsigned int len1 = valueFormat1.get_len ();
635 unsigned int len2 = valueFormat2.get_len (); 665 unsigned int len2 = valueFormat2.get_len ();
636 PairSet::sanitize_closure_t closure = { 666 PairSet::sanitize_closure_t closure = {
637 this, 667 this,
638 &valueFormat1, 668 &valueFormat1,
639 len1, 669 len1,
640 1 + len1 + len2 670 1 + len1 + len2
641 }; 671 };
642 672
643 return TRACE_RETURN (c->check_struct (this) && coverage.sanitize (c, this) & & pairSet.sanitize (c, this, &closure)); 673 return TRACE_RETURN (c->check_struct (this) && coverage.sanitize (c, this) & & pairSet.sanitize (c, this, &closure));
644 } 674 }
645 675
646 private: 676 protected:
647 USHORT format; /* Format identifier--format = 1 */ 677 USHORT format; /* Format identifier--format = 1 */
648 OffsetTo<Coverage> 678 OffsetTo<Coverage>
649 coverage; /* Offset to Coverage table--from 679 coverage; /* Offset to Coverage table--from
650 * beginning of subtable */ 680 * beginning of subtable */
651 ValueFormat valueFormat1; /* Defines the types of data in 681 ValueFormat valueFormat1; /* Defines the types of data in
652 * ValueRecord1--for the first glyph 682 * ValueRecord1--for the first glyph
653 * in the pair--may be zero (0) */ 683 * in the pair--may be zero (0) */
654 ValueFormat valueFormat2; /* Defines the types of data in 684 ValueFormat valueFormat2; /* Defines the types of data in
655 * ValueRecord2--for the second glyph 685 * ValueRecord2--for the second glyph
656 * in the pair--may be zero (0) */ 686 * in the pair--may be zero (0) */
657 OffsetArrayOf<PairSet> 687 OffsetArrayOf<PairSet>
658 pairSet; /* Array of PairSet tables 688 pairSet; /* Array of PairSet tables
659 * ordered by Coverage Index */ 689 * ordered by Coverage Index */
660 public: 690 public:
661 DEFINE_SIZE_ARRAY (10, pairSet); 691 DEFINE_SIZE_ARRAY (10, pairSet);
662 }; 692 };
663 693
664 struct PairPosFormat2 694 struct PairPosFormat2
665 { 695 {
666 friend struct PairPos; 696 friend struct PairPos;
667 697
668 private: 698 private:
699
700 inline const Coverage &get_coverage (void) const
701 {
702 return this+coverage;
703 }
704
669 inline bool apply (hb_apply_context_t *c) const 705 inline bool apply (hb_apply_context_t *c) const
670 { 706 {
671 TRACE_APPLY (); 707 TRACE_APPLY ();
672 hb_apply_context_t::mark_skipping_forward_iterator_t skippy_iter (c, c->buff er->idx, 1); 708 hb_apply_context_t::mark_skipping_forward_iterator_t skippy_iter (c, c->buff er->idx, 1);
673 if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); 709 if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
674 710
675 unsigned int index = (this+coverage) (c->buffer->cur().codepoint); 711 unsigned int index = (this+coverage) (c->buffer->cur().codepoint);
676 if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); 712 if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
677 713
678 if (!skippy_iter.next ()) return TRACE_RETURN (false); 714 if (!skippy_iter.next ()) return TRACE_RETURN (false);
(...skipping 29 matching lines...) Expand all
708 unsigned int len1 = valueFormat1.get_len (); 744 unsigned int len1 = valueFormat1.get_len ();
709 unsigned int len2 = valueFormat2.get_len (); 745 unsigned int len2 = valueFormat2.get_len ();
710 unsigned int stride = len1 + len2; 746 unsigned int stride = len1 + len2;
711 unsigned int record_size = valueFormat1.get_size () + valueFormat2.get_size (); 747 unsigned int record_size = valueFormat1.get_size () + valueFormat2.get_size ();
712 unsigned int count = (unsigned int) class1Count * (unsigned int) class2Count ; 748 unsigned int count = (unsigned int) class1Count * (unsigned int) class2Count ;
713 return TRACE_RETURN (c->check_array (values, record_size, count) && 749 return TRACE_RETURN (c->check_array (values, record_size, count) &&
714 valueFormat1.sanitize_values_stride_unsafe (c, this, &v alues[0], count, stride) && 750 valueFormat1.sanitize_values_stride_unsafe (c, this, &v alues[0], count, stride) &&
715 valueFormat2.sanitize_values_stride_unsafe (c, this, &v alues[len1], count, stride)); 751 valueFormat2.sanitize_values_stride_unsafe (c, this, &v alues[len1], count, stride));
716 } 752 }
717 753
718 private: 754 protected:
719 USHORT format; /* Format identifier--format = 2 */ 755 USHORT format; /* Format identifier--format = 2 */
720 OffsetTo<Coverage> 756 OffsetTo<Coverage>
721 coverage; /* Offset to Coverage table--from 757 coverage; /* Offset to Coverage table--from
722 * beginning of subtable */ 758 * beginning of subtable */
723 ValueFormat valueFormat1; /* ValueRecord definition--for the 759 ValueFormat valueFormat1; /* ValueRecord definition--for the
724 * first glyph of the pair--may be zero 760 * first glyph of the pair--may be zero
725 * (0) */ 761 * (0) */
726 ValueFormat valueFormat2; /* ValueRecord definition--for the 762 ValueFormat valueFormat2; /* ValueRecord definition--for the
727 * second glyph of the pair--may be 763 * second glyph of the pair--may be
728 * zero (0) */ 764 * zero (0) */
(...skipping 14 matching lines...) Expand all
743 * Each entry has value1 and value2 */ 779 * Each entry has value1 and value2 */
744 public: 780 public:
745 DEFINE_SIZE_ARRAY (16, values); 781 DEFINE_SIZE_ARRAY (16, values);
746 }; 782 };
747 783
748 struct PairPos 784 struct PairPos
749 { 785 {
750 friend struct PosLookupSubTable; 786 friend struct PosLookupSubTable;
751 787
752 private: 788 private:
789
790 inline const Coverage &get_coverage (void) const
791 {
792 switch (u.format) {
793 case 1: return u.format1.get_coverage ();
794 case 2: return u.format2.get_coverage ();
795 default:return Null(Coverage);
796 }
797 }
798
753 inline bool apply (hb_apply_context_t *c) const 799 inline bool apply (hb_apply_context_t *c) const
754 { 800 {
755 TRACE_APPLY (); 801 TRACE_APPLY ();
756 switch (u.format) { 802 switch (u.format) {
757 case 1: return TRACE_RETURN (u.format1.apply (c)); 803 case 1: return TRACE_RETURN (u.format1.apply (c));
758 case 2: return TRACE_RETURN (u.format2.apply (c)); 804 case 2: return TRACE_RETURN (u.format2.apply (c));
759 default:return TRACE_RETURN (false); 805 default:return TRACE_RETURN (false);
760 } 806 }
761 } 807 }
762 808
763 inline bool sanitize (hb_sanitize_context_t *c) { 809 inline bool sanitize (hb_sanitize_context_t *c) {
764 TRACE_SANITIZE (); 810 TRACE_SANITIZE ();
765 if (!u.format.sanitize (c)) return TRACE_RETURN (false); 811 if (!u.format.sanitize (c)) return TRACE_RETURN (false);
766 switch (u.format) { 812 switch (u.format) {
767 case 1: return TRACE_RETURN (u.format1.sanitize (c)); 813 case 1: return TRACE_RETURN (u.format1.sanitize (c));
768 case 2: return TRACE_RETURN (u.format2.sanitize (c)); 814 case 2: return TRACE_RETURN (u.format2.sanitize (c));
769 default:return TRACE_RETURN (true); 815 default:return TRACE_RETURN (true);
770 } 816 }
771 } 817 }
772 818
773 private: 819 protected:
774 union { 820 union {
775 USHORT format; /* Format identifier */ 821 USHORT format; /* Format identifier */
776 PairPosFormat1 format1; 822 PairPosFormat1 format1;
777 PairPosFormat2 format2; 823 PairPosFormat2 format2;
778 } u; 824 } u;
779 }; 825 };
780 826
781 827
782 struct EntryExitRecord 828 struct EntryExitRecord
783 { 829 {
784 friend struct CursivePosFormat1; 830 friend struct CursivePosFormat1;
785 831
786 inline bool sanitize (hb_sanitize_context_t *c, void *base) { 832 inline bool sanitize (hb_sanitize_context_t *c, void *base) {
787 TRACE_SANITIZE (); 833 TRACE_SANITIZE ();
788 return TRACE_RETURN (entryAnchor.sanitize (c, base) && exitAnchor.sanitize ( c, base)); 834 return TRACE_RETURN (entryAnchor.sanitize (c, base) && exitAnchor.sanitize ( c, base));
789 } 835 }
790 836
791 private: 837 protected:
792 OffsetTo<Anchor> 838 OffsetTo<Anchor>
793 entryAnchor; /* Offset to EntryAnchor table--from 839 entryAnchor; /* Offset to EntryAnchor table--from
794 * beginning of CursivePos 840 * beginning of CursivePos
795 * subtable--may be NULL */ 841 * subtable--may be NULL */
796 OffsetTo<Anchor> 842 OffsetTo<Anchor>
797 exitAnchor; /* Offset to ExitAnchor table--from 843 exitAnchor; /* Offset to ExitAnchor table--from
798 * beginning of CursivePos 844 * beginning of CursivePos
799 * subtable--may be NULL */ 845 * subtable--may be NULL */
800 public: 846 public:
801 DEFINE_SIZE_STATIC (4); 847 DEFINE_SIZE_STATIC (4);
802 }; 848 };
803 849
804 struct CursivePosFormat1 850 struct CursivePosFormat1
805 { 851 {
806 friend struct CursivePos; 852 friend struct CursivePos;
807 853
808 private: 854 private:
855
856 inline const Coverage &get_coverage (void) const
857 {
858 return this+coverage;
859 }
860
809 inline bool apply (hb_apply_context_t *c) const 861 inline bool apply (hb_apply_context_t *c) const
810 { 862 {
811 TRACE_APPLY (); 863 TRACE_APPLY ();
812 864
813 /* We don't handle mark glyphs here. */ 865 /* We don't handle mark glyphs here. */
814 if (c->property & HB_OT_LAYOUT_GLYPH_CLASS_MARK) return TRACE_RETURN (false) ; 866 if (c->property & HB_OT_LAYOUT_GLYPH_CLASS_MARK) return TRACE_RETURN (false) ;
815 867
816 hb_apply_context_t::mark_skipping_forward_iterator_t skippy_iter (c, c->buff er->idx, 1); 868 hb_apply_context_t::mark_skipping_forward_iterator_t skippy_iter (c, c->buff er->idx, 1);
817 if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); 869 if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
818 870
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
886 938
887 c->buffer->idx = j; 939 c->buffer->idx = j;
888 return TRACE_RETURN (true); 940 return TRACE_RETURN (true);
889 } 941 }
890 942
891 inline bool sanitize (hb_sanitize_context_t *c) { 943 inline bool sanitize (hb_sanitize_context_t *c) {
892 TRACE_SANITIZE (); 944 TRACE_SANITIZE ();
893 return TRACE_RETURN (coverage.sanitize (c, this) && entryExitRecord.sanitize (c, this)); 945 return TRACE_RETURN (coverage.sanitize (c, this) && entryExitRecord.sanitize (c, this));
894 } 946 }
895 947
896 private: 948 protected:
897 USHORT format; /* Format identifier--format = 1 */ 949 USHORT format; /* Format identifier--format = 1 */
898 OffsetTo<Coverage> 950 OffsetTo<Coverage>
899 coverage; /* Offset to Coverage table--from 951 coverage; /* Offset to Coverage table--from
900 * beginning of subtable */ 952 * beginning of subtable */
901 ArrayOf<EntryExitRecord> 953 ArrayOf<EntryExitRecord>
902 entryExitRecord; /* Array of EntryExit records--in 954 entryExitRecord; /* Array of EntryExit records--in
903 * Coverage Index order */ 955 * Coverage Index order */
904 public: 956 public:
905 DEFINE_SIZE_ARRAY (6, entryExitRecord); 957 DEFINE_SIZE_ARRAY (6, entryExitRecord);
906 }; 958 };
907 959
908 struct CursivePos 960 struct CursivePos
909 { 961 {
910 friend struct PosLookupSubTable; 962 friend struct PosLookupSubTable;
911 963
912 private: 964 private:
965
966 inline const Coverage &get_coverage (void) const
967 {
968 switch (u.format) {
969 case 1: return u.format1.get_coverage ();
970 default:return Null(Coverage);
971 }
972 }
973
913 inline bool apply (hb_apply_context_t *c) const 974 inline bool apply (hb_apply_context_t *c) const
914 { 975 {
915 TRACE_APPLY (); 976 TRACE_APPLY ();
916 switch (u.format) { 977 switch (u.format) {
917 case 1: return TRACE_RETURN (u.format1.apply (c)); 978 case 1: return TRACE_RETURN (u.format1.apply (c));
918 default:return TRACE_RETURN (false); 979 default:return TRACE_RETURN (false);
919 } 980 }
920 } 981 }
921 982
922 inline bool sanitize (hb_sanitize_context_t *c) { 983 inline bool sanitize (hb_sanitize_context_t *c) {
923 TRACE_SANITIZE (); 984 TRACE_SANITIZE ();
924 if (!u.format.sanitize (c)) return TRACE_RETURN (false); 985 if (!u.format.sanitize (c)) return TRACE_RETURN (false);
925 switch (u.format) { 986 switch (u.format) {
926 case 1: return TRACE_RETURN (u.format1.sanitize (c)); 987 case 1: return TRACE_RETURN (u.format1.sanitize (c));
927 default:return TRACE_RETURN (true); 988 default:return TRACE_RETURN (true);
928 } 989 }
929 } 990 }
930 991
931 private: 992 protected:
932 union { 993 union {
933 USHORT format; /* Format identifier */ 994 USHORT format; /* Format identifier */
934 CursivePosFormat1 format1; 995 CursivePosFormat1 format1;
935 } u; 996 } u;
936 }; 997 };
937 998
938 999
939 typedef AnchorMatrix BaseArray; /* base-major-- 1000 typedef AnchorMatrix BaseArray; /* base-major--
940 * in order of BaseCoverage Index--, 1001 * in order of BaseCoverage Index--,
941 * mark-minor-- 1002 * mark-minor--
942 * ordered by class--zero-based. */ 1003 * ordered by class--zero-based. */
943 1004
944 struct MarkBasePosFormat1 1005 struct MarkBasePosFormat1
945 { 1006 {
946 friend struct MarkBasePos; 1007 friend struct MarkBasePos;
947 1008
948 private: 1009 private:
1010
1011 inline const Coverage &get_coverage (void) const
1012 {
1013 return this+markCoverage;
1014 }
1015
949 inline bool apply (hb_apply_context_t *c) const 1016 inline bool apply (hb_apply_context_t *c) const
950 { 1017 {
951 TRACE_APPLY (); 1018 TRACE_APPLY ();
952 unsigned int mark_index = (this+markCoverage) (c->buffer->cur().codepoint); 1019 unsigned int mark_index = (this+markCoverage) (c->buffer->cur().codepoint);
953 if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false); 1020 if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false);
954 1021
955 /* now we search backwards for a non-mark glyph */ 1022 /* now we search backwards for a non-mark glyph */
956 unsigned int property; 1023 unsigned int property;
957 hb_apply_context_t::mark_skipping_backward_iterator_t skippy_iter (c, c->buf fer->idx, 1); 1024 hb_apply_context_t::mark_skipping_backward_iterator_t skippy_iter (c, c->buf fer->idx, 1);
958 if (!skippy_iter.prev (&property, LookupFlag::IgnoreMarks)) return TRACE_RET URN (false); 1025 do {
1026 if (!skippy_iter.prev (&property, LookupFlag::IgnoreMarks)) return TRACE_R ETURN (false);
1027 /* We only want to attach to the first of a MultipleSubst sequence. Rejec t others. */
1028 if (0 == get_lig_comp (c->buffer->info[skippy_iter.idx])) break;
1029 skippy_iter.reject ();
1030 } while (1);
959 1031
960 /* The following assertion is too strong, so we've disabled it. */ 1032 /* The following assertion is too strong, so we've disabled it. */
961 if (!(property & HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH)) {/*return TRACE_RETUR N (false);*/} 1033 if (!(property & HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH)) {/*return TRACE_RETUR N (false);*/}
962 1034
963 unsigned int base_index = (this+baseCoverage) (c->buffer->info[skippy_iter.i dx].codepoint); 1035 unsigned int base_index = (this+baseCoverage) (c->buffer->info[skippy_iter.i dx].codepoint);
964 if (base_index == NOT_COVERED) return TRACE_RETURN (false); 1036 if (base_index == NOT_COVERED) return TRACE_RETURN (false);
965 1037
966 return TRACE_RETURN ((this+markArray).apply (c, mark_index, base_index, this +baseArray, classCount, skippy_iter.idx)); 1038 return TRACE_RETURN ((this+markArray).apply (c, mark_index, base_index, this +baseArray, classCount, skippy_iter.idx));
967 } 1039 }
968 1040
969 inline bool sanitize (hb_sanitize_context_t *c) { 1041 inline bool sanitize (hb_sanitize_context_t *c) {
970 TRACE_SANITIZE (); 1042 TRACE_SANITIZE ();
971 return TRACE_RETURN (c->check_struct (this) && markCoverage.sanitize (c, thi s) && baseCoverage.sanitize (c, this) && 1043 return TRACE_RETURN (c->check_struct (this) && markCoverage.sanitize (c, thi s) && baseCoverage.sanitize (c, this) &&
972 markArray.sanitize (c, this) && baseArray.sanitize (c, this, (unsigned int) classCount)); 1044 markArray.sanitize (c, this) && baseArray.sanitize (c, this, (unsigned int) classCount));
973 } 1045 }
974 1046
975 private: 1047 protected:
976 USHORT format; /* Format identifier--format = 1 */ 1048 USHORT format; /* Format identifier--format = 1 */
977 OffsetTo<Coverage> 1049 OffsetTo<Coverage>
978 markCoverage; /* Offset to MarkCoverage table--from 1050 markCoverage; /* Offset to MarkCoverage table--from
979 * beginning of MarkBasePos subtable */ 1051 * beginning of MarkBasePos subtable */
980 OffsetTo<Coverage> 1052 OffsetTo<Coverage>
981 baseCoverage; /* Offset to BaseCoverage table--from 1053 baseCoverage; /* Offset to BaseCoverage table--from
982 * beginning of MarkBasePos subtable */ 1054 * beginning of MarkBasePos subtable */
983 USHORT classCount; /* Number of classes defined for marks * / 1055 USHORT classCount; /* Number of classes defined for marks * /
984 OffsetTo<MarkArray> 1056 OffsetTo<MarkArray>
985 markArray; /* Offset to MarkArray table--from 1057 markArray; /* Offset to MarkArray table--from
986 * beginning of MarkBasePos subtable */ 1058 * beginning of MarkBasePos subtable */
987 OffsetTo<BaseArray> 1059 OffsetTo<BaseArray>
988 baseArray; /* Offset to BaseArray table--from 1060 baseArray; /* Offset to BaseArray table--from
989 * beginning of MarkBasePos subtable */ 1061 * beginning of MarkBasePos subtable */
990 public: 1062 public:
991 DEFINE_SIZE_STATIC (12); 1063 DEFINE_SIZE_STATIC (12);
992 }; 1064 };
993 1065
994 struct MarkBasePos 1066 struct MarkBasePos
995 { 1067 {
996 friend struct PosLookupSubTable; 1068 friend struct PosLookupSubTable;
997 1069
998 private: 1070 private:
1071
1072 inline const Coverage &get_coverage (void) const
1073 {
1074 switch (u.format) {
1075 case 1: return u.format1.get_coverage ();
1076 default:return Null(Coverage);
1077 }
1078 }
1079
999 inline bool apply (hb_apply_context_t *c) const 1080 inline bool apply (hb_apply_context_t *c) const
1000 { 1081 {
1001 TRACE_APPLY (); 1082 TRACE_APPLY ();
1002 switch (u.format) { 1083 switch (u.format) {
1003 case 1: return TRACE_RETURN (u.format1.apply (c)); 1084 case 1: return TRACE_RETURN (u.format1.apply (c));
1004 default:return TRACE_RETURN (false); 1085 default:return TRACE_RETURN (false);
1005 } 1086 }
1006 } 1087 }
1007 1088
1008 inline bool sanitize (hb_sanitize_context_t *c) { 1089 inline bool sanitize (hb_sanitize_context_t *c) {
1009 TRACE_SANITIZE (); 1090 TRACE_SANITIZE ();
1010 if (!u.format.sanitize (c)) return TRACE_RETURN (false); 1091 if (!u.format.sanitize (c)) return TRACE_RETURN (false);
1011 switch (u.format) { 1092 switch (u.format) {
1012 case 1: return TRACE_RETURN (u.format1.sanitize (c)); 1093 case 1: return TRACE_RETURN (u.format1.sanitize (c));
1013 default:return TRACE_RETURN (true); 1094 default:return TRACE_RETURN (true);
1014 } 1095 }
1015 } 1096 }
1016 1097
1017 private: 1098 protected:
1018 union { 1099 union {
1019 USHORT format; /* Format identifier */ 1100 USHORT format; /* Format identifier */
1020 MarkBasePosFormat1 format1; 1101 MarkBasePosFormat1 format1;
1021 } u; 1102 } u;
1022 }; 1103 };
1023 1104
1024 1105
1025 typedef AnchorMatrix LigatureAttach; /* component-major-- 1106 typedef AnchorMatrix LigatureAttach; /* component-major--
1026 * in order of writing direction--, 1107 * in order of writing direction--,
1027 * mark-minor-- 1108 * mark-minor--
1028 * ordered by class--zero-based. */ 1109 * ordered by class--zero-based. */
1029 1110
1030 typedef OffsetListOf<LigatureAttach> LigatureArray; 1111 typedef OffsetListOf<LigatureAttach> LigatureArray;
1031 /* Array of LigatureAttach 1112 /* Array of LigatureAttach
1032 * tables ordered by 1113 * tables ordered by
1033 * LigatureCoverage Index */ 1114 * LigatureCoverage Index */
1034 1115
1035 struct MarkLigPosFormat1 1116 struct MarkLigPosFormat1
1036 { 1117 {
1037 friend struct MarkLigPos; 1118 friend struct MarkLigPos;
1038 1119
1039 private: 1120 private:
1121
1122 inline const Coverage &get_coverage (void) const
1123 {
1124 return this+markCoverage;
1125 }
1126
1040 inline bool apply (hb_apply_context_t *c) const 1127 inline bool apply (hb_apply_context_t *c) const
1041 { 1128 {
1042 TRACE_APPLY (); 1129 TRACE_APPLY ();
1043 unsigned int mark_index = (this+markCoverage) (c->buffer->cur().codepoint); 1130 unsigned int mark_index = (this+markCoverage) (c->buffer->cur().codepoint);
1044 if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false); 1131 if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false);
1045 1132
1046 /* now we search backwards for a non-mark glyph */ 1133 /* now we search backwards for a non-mark glyph */
1047 unsigned int property; 1134 unsigned int property;
1048 hb_apply_context_t::mark_skipping_backward_iterator_t skippy_iter (c, c->buf fer->idx, 1); 1135 hb_apply_context_t::mark_skipping_backward_iterator_t skippy_iter (c, c->buf fer->idx, 1);
1049 if (!skippy_iter.prev (&property, LookupFlag::IgnoreMarks)) return TRACE_RET URN (false); 1136 if (!skippy_iter.prev (&property, LookupFlag::IgnoreMarks)) return TRACE_RET URN (false);
1050 1137
1051 /* The following assertion is too strong, so we've disabled it. */ 1138 /* The following assertion is too strong, so we've disabled it. */
1052 if (!(property & HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE)) {/*return TRACE_RETURN (false);*/} 1139 if (!(property & HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE)) {/*return TRACE_RETURN (false);*/}
1053 1140
1054 unsigned int j = skippy_iter.idx; 1141 unsigned int j = skippy_iter.idx;
1055 unsigned int lig_index = (this+ligatureCoverage) (c->buffer->info[j].codepoi nt); 1142 unsigned int lig_index = (this+ligatureCoverage) (c->buffer->info[j].codepoi nt);
1056 if (lig_index == NOT_COVERED) return TRACE_RETURN (false); 1143 if (lig_index == NOT_COVERED) return TRACE_RETURN (false);
1057 1144
1058 const LigatureArray& lig_array = this+ligatureArray; 1145 const LigatureArray& lig_array = this+ligatureArray;
1059 const LigatureAttach& lig_attach = lig_array[lig_index]; 1146 const LigatureAttach& lig_attach = lig_array[lig_index];
1060 1147
1061 /* Find component to attach to */ 1148 /* Find component to attach to */
1062 unsigned int comp_count = lig_attach.rows; 1149 unsigned int comp_count = lig_attach.rows;
1063 if (unlikely (!comp_count)) return TRACE_RETURN (false); 1150 if (unlikely (!comp_count)) return TRACE_RETURN (false);
1064 1151
1065 unsigned int comp_index;
1066 /* We must now check whether the ligature ID of the current mark glyph 1152 /* We must now check whether the ligature ID of the current mark glyph
1067 * is identical to the ligature ID of the found ligature. If yes, we 1153 * is identical to the ligature ID of the found ligature. If yes, we
1068 * can directly use the component index. If not, we attach the mark 1154 * can directly use the component index. If not, we attach the mark
1069 * glyph to the last component of the ligature. */ 1155 * glyph to the last component of the ligature. */
1070 if (get_lig_id (c->buffer->info[j]) && 1156 unsigned int comp_index;
1071 » get_lig_id (c->buffer->cur()) && 1157 unsigned int lig_id = get_lig_id (c->buffer->info[j]);
1072 » get_lig_comp (c->buffer->cur()) > 0) 1158 unsigned int mark_id = get_lig_id (c->buffer->cur());
1073 { 1159 unsigned int mark_comp = get_lig_comp (c->buffer->cur());
1074 comp_index = get_lig_comp (c->buffer->cur()) - 1; 1160 if (lig_id && lig_id == mark_id && mark_comp > 0)
1075 if (comp_index >= comp_count) 1161 comp_index = MIN (comp_count, get_lig_comp (c->buffer->cur())) - 1;
1076 » comp_index = comp_count - 1;
1077 }
1078 else 1162 else
1079 comp_index = comp_count - 1; 1163 comp_index = comp_count - 1;
1080 1164
1081 return TRACE_RETURN ((this+markArray).apply (c, mark_index, comp_index, lig_ attach, classCount, j)); 1165 return TRACE_RETURN ((this+markArray).apply (c, mark_index, comp_index, lig_ attach, classCount, j));
1082 } 1166 }
1083 1167
1084 inline bool sanitize (hb_sanitize_context_t *c) { 1168 inline bool sanitize (hb_sanitize_context_t *c) {
1085 TRACE_SANITIZE (); 1169 TRACE_SANITIZE ();
1086 return TRACE_RETURN (c->check_struct (this) && markCoverage.sanitize (c, thi s) && ligatureCoverage.sanitize (c, this) && 1170 return TRACE_RETURN (c->check_struct (this) && markCoverage.sanitize (c, thi s) && ligatureCoverage.sanitize (c, this) &&
1087 markArray.sanitize (c, this) && ligatureArray.sanitize (c, this, (unsigned int) classCount)); 1171 markArray.sanitize (c, this) && ligatureArray.sanitize (c, this, (unsigned int) classCount));
1088 } 1172 }
1089 1173
1090 private: 1174 protected:
1091 USHORT format; /* Format identifier--format = 1 */ 1175 USHORT format; /* Format identifier--format = 1 */
1092 OffsetTo<Coverage> 1176 OffsetTo<Coverage>
1093 markCoverage; /* Offset to Mark Coverage table--from 1177 markCoverage; /* Offset to Mark Coverage table--from
1094 * beginning of MarkLigPos subtable */ 1178 * beginning of MarkLigPos subtable */
1095 OffsetTo<Coverage> 1179 OffsetTo<Coverage>
1096 ligatureCoverage; /* Offset to Ligature Coverage 1180 ligatureCoverage; /* Offset to Ligature Coverage
1097 * table--from beginning of MarkLigPos 1181 * table--from beginning of MarkLigPos
1098 * subtable */ 1182 * subtable */
1099 USHORT classCount; /* Number of defined mark classes */ 1183 USHORT classCount; /* Number of defined mark classes */
1100 OffsetTo<MarkArray> 1184 OffsetTo<MarkArray>
1101 markArray; /* Offset to MarkArray table--from 1185 markArray; /* Offset to MarkArray table--from
1102 * beginning of MarkLigPos subtable */ 1186 * beginning of MarkLigPos subtable */
1103 OffsetTo<LigatureArray> 1187 OffsetTo<LigatureArray>
1104 ligatureArray; /* Offset to LigatureArray table--from 1188 ligatureArray; /* Offset to LigatureArray table--from
1105 * beginning of MarkLigPos subtable */ 1189 * beginning of MarkLigPos subtable */
1106 public: 1190 public:
1107 DEFINE_SIZE_STATIC (12); 1191 DEFINE_SIZE_STATIC (12);
1108 }; 1192 };
1109 1193
1110 struct MarkLigPos 1194 struct MarkLigPos
1111 { 1195 {
1112 friend struct PosLookupSubTable; 1196 friend struct PosLookupSubTable;
1113 1197
1114 private: 1198 private:
1199
1200 inline const Coverage &get_coverage (void) const
1201 {
1202 switch (u.format) {
1203 case 1: return u.format1.get_coverage ();
1204 default:return Null(Coverage);
1205 }
1206 }
1207
1115 inline bool apply (hb_apply_context_t *c) const 1208 inline bool apply (hb_apply_context_t *c) const
1116 { 1209 {
1117 TRACE_APPLY (); 1210 TRACE_APPLY ();
1118 switch (u.format) { 1211 switch (u.format) {
1119 case 1: return TRACE_RETURN (u.format1.apply (c)); 1212 case 1: return TRACE_RETURN (u.format1.apply (c));
1120 default:return TRACE_RETURN (false); 1213 default:return TRACE_RETURN (false);
1121 } 1214 }
1122 } 1215 }
1123 1216
1124 inline bool sanitize (hb_sanitize_context_t *c) { 1217 inline bool sanitize (hb_sanitize_context_t *c) {
1125 TRACE_SANITIZE (); 1218 TRACE_SANITIZE ();
1126 if (!u.format.sanitize (c)) return TRACE_RETURN (false); 1219 if (!u.format.sanitize (c)) return TRACE_RETURN (false);
1127 switch (u.format) { 1220 switch (u.format) {
1128 case 1: return TRACE_RETURN (u.format1.sanitize (c)); 1221 case 1: return TRACE_RETURN (u.format1.sanitize (c));
1129 default:return TRACE_RETURN (true); 1222 default:return TRACE_RETURN (true);
1130 } 1223 }
1131 } 1224 }
1132 1225
1133 private: 1226 protected:
1134 union { 1227 union {
1135 USHORT format; /* Format identifier */ 1228 USHORT format; /* Format identifier */
1136 MarkLigPosFormat1 format1; 1229 MarkLigPosFormat1 format1;
1137 } u; 1230 } u;
1138 }; 1231 };
1139 1232
1140 1233
1141 typedef AnchorMatrix Mark2Array; /* mark2-major-- 1234 typedef AnchorMatrix Mark2Array; /* mark2-major--
1142 * in order of Mark2Coverage Index--, 1235 * in order of Mark2Coverage Index--,
1143 * mark1-minor-- 1236 * mark1-minor--
1144 * ordered by class--zero-based. */ 1237 * ordered by class--zero-based. */
1145 1238
1146 struct MarkMarkPosFormat1 1239 struct MarkMarkPosFormat1
1147 { 1240 {
1148 friend struct MarkMarkPos; 1241 friend struct MarkMarkPos;
1149 1242
1150 private: 1243 private:
1244
1245 inline const Coverage &get_coverage (void) const
1246 {
1247 return this+mark1Coverage;
1248 }
1249
1151 inline bool apply (hb_apply_context_t *c) const 1250 inline bool apply (hb_apply_context_t *c) const
1152 { 1251 {
1153 TRACE_APPLY (); 1252 TRACE_APPLY ();
1154 unsigned int mark1_index = (this+mark1Coverage) (c->buffer->cur().codepoint) ; 1253 unsigned int mark1_index = (this+mark1Coverage) (c->buffer->cur().codepoint) ;
1155 if (likely (mark1_index == NOT_COVERED)) return TRACE_RETURN (false); 1254 if (likely (mark1_index == NOT_COVERED)) return TRACE_RETURN (false);
1156 1255
1157 /* now we search backwards for a suitable mark glyph until a non-mark glyph */ 1256 /* now we search backwards for a suitable mark glyph until a non-mark glyph */
1158 unsigned int property; 1257 unsigned int property;
1159 hb_apply_context_t::mark_skipping_backward_iterator_t skippy_iter (c, c->buf fer->idx, 1); 1258 hb_apply_context_t::mark_skipping_backward_iterator_t skippy_iter (c, c->buf fer->idx, 1);
1160 if (!skippy_iter.prev (&property)) return TRACE_RETURN (false); 1259 if (!skippy_iter.prev (&property)) return TRACE_RETURN (false);
1161 1260
1162 if (!(property & HB_OT_LAYOUT_GLYPH_CLASS_MARK)) return TRACE_RETURN (false) ; 1261 if (!(property & HB_OT_LAYOUT_GLYPH_CLASS_MARK)) return TRACE_RETURN (false) ;
1163 1262
1164 unsigned int j = skippy_iter.idx; 1263 unsigned int j = skippy_iter.idx;
1165 1264
1166 /* Two marks match only if they belong to the same base, or same component 1265 unsigned int id1 = get_lig_id (c->buffer->cur());
1167 * of the same ligature. That is, the component numbers must match, and 1266 unsigned int id2 = get_lig_id (c->buffer->info[j]);
1168 * if those are non-zero, the ligid number should also match. */ 1267 unsigned int comp1 = get_lig_comp (c->buffer->cur());
1169 if ((get_lig_comp (c->buffer->cur())) || 1268 unsigned int comp2 = get_lig_comp (c->buffer->info[j]);
1170 » (get_lig_comp (c->buffer->info[j]) > 0 &&
1171 » get_lig_id (c->buffer->cur())))
1172 return TRACE_RETURN (false);
1173 1269
1270 if (likely (id1 == id2)) {
1271 if (id1 == 0) /* Marks belonging to the same base. */
1272 goto good;
1273 else if (comp1 == comp2) /* Marks belonging to the same ligature component . */
1274 goto good;
1275 } else {
1276 /* If ligature ids don't match, it may be the case that one of the marks
1277 * itself is a ligature. In which case match. */
1278 if ((id1 > 0 && !comp1) || (id2 > 0 && !comp2))
1279 goto good;
1280 }
1281
1282 /* Didn't match. */
1283 return TRACE_RETURN (false);
1284
1285 good:
1174 unsigned int mark2_index = (this+mark2Coverage) (c->buffer->info[j].codepoin t); 1286 unsigned int mark2_index = (this+mark2Coverage) (c->buffer->info[j].codepoin t);
1175 if (mark2_index == NOT_COVERED) return TRACE_RETURN (false); 1287 if (mark2_index == NOT_COVERED) return TRACE_RETURN (false);
1176 1288
1177 return TRACE_RETURN ((this+mark1Array).apply (c, mark1_index, mark2_index, t his+mark2Array, classCount, j)); 1289 return TRACE_RETURN ((this+mark1Array).apply (c, mark1_index, mark2_index, t his+mark2Array, classCount, j));
1178 } 1290 }
1179 1291
1180 inline bool sanitize (hb_sanitize_context_t *c) { 1292 inline bool sanitize (hb_sanitize_context_t *c) {
1181 TRACE_SANITIZE (); 1293 TRACE_SANITIZE ();
1182 return TRACE_RETURN (c->check_struct (this) && mark1Coverage.sanitize (c, th is) && 1294 return TRACE_RETURN (c->check_struct (this) && mark1Coverage.sanitize (c, th is) &&
1183 mark2Coverage.sanitize (c, this) && mark1Array.sanitize (c, this) 1295 mark2Coverage.sanitize (c, this) && mark1Array.sanitize (c, this)
1184 && mark2Array.sanitize (c, this, (unsigned int) classCo unt)); 1296 && mark2Array.sanitize (c, this, (unsigned int) classCo unt));
1185 } 1297 }
1186 1298
1187 private: 1299 protected:
1188 USHORT format; /* Format identifier--format = 1 */ 1300 USHORT format; /* Format identifier--format = 1 */
1189 OffsetTo<Coverage> 1301 OffsetTo<Coverage>
1190 mark1Coverage; /* Offset to Combining Mark1 Coverage 1302 mark1Coverage; /* Offset to Combining Mark1 Coverage
1191 * table--from beginning of MarkMarkPos 1303 * table--from beginning of MarkMarkPos
1192 * subtable */ 1304 * subtable */
1193 OffsetTo<Coverage> 1305 OffsetTo<Coverage>
1194 mark2Coverage; /* Offset to Combining Mark2 Coverage 1306 mark2Coverage; /* Offset to Combining Mark2 Coverage
1195 * table--from beginning of MarkMarkPos 1307 * table--from beginning of MarkMarkPos
1196 * subtable */ 1308 * subtable */
1197 USHORT classCount; /* Number of defined mark classes */ 1309 USHORT classCount; /* Number of defined mark classes */
1198 OffsetTo<MarkArray> 1310 OffsetTo<MarkArray>
1199 mark1Array; /* Offset to Mark1Array table--from 1311 mark1Array; /* Offset to Mark1Array table--from
1200 * beginning of MarkMarkPos subtable */ 1312 * beginning of MarkMarkPos subtable */
1201 OffsetTo<Mark2Array> 1313 OffsetTo<Mark2Array>
1202 mark2Array; /* Offset to Mark2Array table--from 1314 mark2Array; /* Offset to Mark2Array table--from
1203 * beginning of MarkMarkPos subtable */ 1315 * beginning of MarkMarkPos subtable */
1204 public: 1316 public:
1205 DEFINE_SIZE_STATIC (12); 1317 DEFINE_SIZE_STATIC (12);
1206 }; 1318 };
1207 1319
1208 struct MarkMarkPos 1320 struct MarkMarkPos
1209 { 1321 {
1210 friend struct PosLookupSubTable; 1322 friend struct PosLookupSubTable;
1211 1323
1212 private: 1324 private:
1325
1326 inline const Coverage &get_coverage (void) const
1327 {
1328 switch (u.format) {
1329 case 1: return u.format1.get_coverage ();
1330 default:return Null(Coverage);
1331 }
1332 }
1333
1213 inline bool apply (hb_apply_context_t *c) const 1334 inline bool apply (hb_apply_context_t *c) const
1214 { 1335 {
1215 TRACE_APPLY (); 1336 TRACE_APPLY ();
1216 switch (u.format) { 1337 switch (u.format) {
1217 case 1: return TRACE_RETURN (u.format1.apply (c)); 1338 case 1: return TRACE_RETURN (u.format1.apply (c));
1218 default:return TRACE_RETURN (false); 1339 default:return TRACE_RETURN (false);
1219 } 1340 }
1220 } 1341 }
1221 1342
1222 inline bool sanitize (hb_sanitize_context_t *c) { 1343 inline bool sanitize (hb_sanitize_context_t *c) {
1223 TRACE_SANITIZE (); 1344 TRACE_SANITIZE ();
1224 if (!u.format.sanitize (c)) return TRACE_RETURN (false); 1345 if (!u.format.sanitize (c)) return TRACE_RETURN (false);
1225 switch (u.format) { 1346 switch (u.format) {
1226 case 1: return TRACE_RETURN (u.format1.sanitize (c)); 1347 case 1: return TRACE_RETURN (u.format1.sanitize (c));
1227 default:return TRACE_RETURN (true); 1348 default:return TRACE_RETURN (true);
1228 } 1349 }
1229 } 1350 }
1230 1351
1231 private: 1352 protected:
1232 union { 1353 union {
1233 USHORT format; /* Format identifier */ 1354 USHORT format; /* Format identifier */
1234 MarkMarkPosFormat1 format1; 1355 MarkMarkPosFormat1 format1;
1235 } u; 1356 } u;
1236 }; 1357 };
1237 1358
1238 1359
1239 static inline bool position_lookup (hb_apply_context_t *c, unsigned int lookup_i ndex); 1360 static inline bool position_lookup (hb_apply_context_t *c, unsigned int lookup_i ndex);
1240 1361
1241 struct ContextPos : Context 1362 struct ContextPos : Context
(...skipping 26 matching lines...) Expand all
1268 friend struct PosLookupSubTable; 1389 friend struct PosLookupSubTable;
1269 1390
1270 private: 1391 private:
1271 inline const struct PosLookupSubTable& get_subtable (void) const 1392 inline const struct PosLookupSubTable& get_subtable (void) const
1272 { 1393 {
1273 unsigned int offset = get_offset (); 1394 unsigned int offset = get_offset ();
1274 if (unlikely (!offset)) return Null(PosLookupSubTable); 1395 if (unlikely (!offset)) return Null(PosLookupSubTable);
1275 return StructAtOffset<PosLookupSubTable> (this, offset); 1396 return StructAtOffset<PosLookupSubTable> (this, offset);
1276 } 1397 }
1277 1398
1399 inline const Coverage &get_coverage (void) const;
1400
1278 inline bool apply (hb_apply_context_t *c) const; 1401 inline bool apply (hb_apply_context_t *c) const;
1279 1402
1280 inline bool sanitize (hb_sanitize_context_t *c); 1403 inline bool sanitize (hb_sanitize_context_t *c);
1281 }; 1404 };
1282 1405
1283 1406
1284 1407
1285 /* 1408 /*
1286 * PosLookup 1409 * PosLookup
1287 */ 1410 */
1288 1411
1289 1412
1290 struct PosLookupSubTable 1413 struct PosLookupSubTable
1291 { 1414 {
1292 friend struct PosLookup; 1415 friend struct PosLookup;
1293 1416
1294 enum Type { 1417 enum Type {
1295 Single = 1, 1418 Single = 1,
1296 Pair = 2, 1419 Pair = 2,
1297 Cursive = 3, 1420 Cursive = 3,
1298 MarkBase = 4, 1421 MarkBase = 4,
1299 MarkLig = 5, 1422 MarkLig = 5,
1300 MarkMark = 6, 1423 MarkMark = 6,
1301 Context = 7, 1424 Context = 7,
1302 ChainContext = 8, 1425 ChainContext = 8,
1303 Extension = 9 1426 Extension = 9
1304 }; 1427 };
1305 1428
1429 inline const Coverage &get_coverage (unsigned int lookup_type) const
1430 {
1431 switch (lookup_type) {
1432 case Single: return u.single.get_coverage ();
1433 case Pair: return u.pair.get_coverage ();
1434 case Cursive: return u.cursive.get_coverage ();
1435 case MarkBase: return u.markBase.get_coverage ();
1436 case MarkLig: return u.markLig.get_coverage ();
1437 case MarkMark: return u.markMark.get_coverage ();
1438 case Context: return u.context.get_coverage ();
1439 case ChainContext: return u.chainContext.get_coverage ();
1440 case Extension: return u.extension.get_coverage ();
1441 default: return Null(Coverage);
1442 }
1443 }
1444
1306 inline bool apply (hb_apply_context_t *c, unsigned int lookup_type) const 1445 inline bool apply (hb_apply_context_t *c, unsigned int lookup_type) const
1307 { 1446 {
1308 TRACE_APPLY (); 1447 TRACE_APPLY ();
1309 switch (lookup_type) { 1448 switch (lookup_type) {
1310 case Single: return TRACE_RETURN (u.single.apply (c)); 1449 case Single: return TRACE_RETURN (u.single.apply (c));
1311 case Pair: return TRACE_RETURN (u.pair.apply (c)); 1450 case Pair: return TRACE_RETURN (u.pair.apply (c));
1312 case Cursive: return TRACE_RETURN (u.cursive.apply (c)); 1451 case Cursive: return TRACE_RETURN (u.cursive.apply (c));
1313 case MarkBase: return TRACE_RETURN (u.markBase.apply (c)); 1452 case MarkBase: return TRACE_RETURN (u.markBase.apply (c));
1314 case MarkLig: return TRACE_RETURN (u.markLig.apply (c)); 1453 case MarkLig: return TRACE_RETURN (u.markLig.apply (c));
1315 case MarkMark: return TRACE_RETURN (u.markMark.apply (c)); 1454 case MarkMark: return TRACE_RETURN (u.markMark.apply (c));
1316 case Context:» » return TRACE_RETURN (u.c.apply (c)); 1455 case Context:» » return TRACE_RETURN (u.context.apply (c));
1317 case ChainContext: return TRACE_RETURN (u.chainContext.apply (c)); 1456 case ChainContext: return TRACE_RETURN (u.chainContext.apply (c));
1318 case Extension: return TRACE_RETURN (u.extension.apply (c)); 1457 case Extension: return TRACE_RETURN (u.extension.apply (c));
1319 default: return TRACE_RETURN (false); 1458 default: return TRACE_RETURN (false);
1320 } 1459 }
1321 } 1460 }
1322 1461
1323 inline bool sanitize (hb_sanitize_context_t *c, unsigned int lookup_type) { 1462 inline bool sanitize (hb_sanitize_context_t *c, unsigned int lookup_type) {
1324 TRACE_SANITIZE (); 1463 TRACE_SANITIZE ();
1464 if (!u.header.sub_format.sanitize (c))
1465 return TRACE_RETURN (false);
1325 switch (lookup_type) { 1466 switch (lookup_type) {
1326 case Single: return TRACE_RETURN (u.single.sanitize (c)); 1467 case Single: return TRACE_RETURN (u.single.sanitize (c));
1327 case Pair: return TRACE_RETURN (u.pair.sanitize (c)); 1468 case Pair: return TRACE_RETURN (u.pair.sanitize (c));
1328 case Cursive: return TRACE_RETURN (u.cursive.sanitize (c)); 1469 case Cursive: return TRACE_RETURN (u.cursive.sanitize (c));
1329 case MarkBase: return TRACE_RETURN (u.markBase.sanitize (c)); 1470 case MarkBase: return TRACE_RETURN (u.markBase.sanitize (c));
1330 case MarkLig: return TRACE_RETURN (u.markLig.sanitize (c)); 1471 case MarkLig: return TRACE_RETURN (u.markLig.sanitize (c));
1331 case MarkMark: return TRACE_RETURN (u.markMark.sanitize (c)); 1472 case MarkMark: return TRACE_RETURN (u.markMark.sanitize (c));
1332 case Context:» » return TRACE_RETURN (u.c.sanitize (c)); 1473 case Context:» » return TRACE_RETURN (u.context.sanitize (c));
1333 case ChainContext: return TRACE_RETURN (u.chainContext.sanitize (c) ); 1474 case ChainContext: return TRACE_RETURN (u.chainContext.sanitize (c) );
1334 case Extension: return TRACE_RETURN (u.extension.sanitize (c)); 1475 case Extension: return TRACE_RETURN (u.extension.sanitize (c));
1335 default: return TRACE_RETURN (true); 1476 default: return TRACE_RETURN (true);
1336 } 1477 }
1337 } 1478 }
1338 1479
1339 private: 1480 protected:
1340 union { 1481 union {
1341 USHORT» » sub_format; 1482 struct {
1483 USHORT» » » sub_format;
1484 } header;
1342 SinglePos single; 1485 SinglePos single;
1343 PairPos pair; 1486 PairPos pair;
1344 CursivePos cursive; 1487 CursivePos cursive;
1345 MarkBasePos markBase; 1488 MarkBasePos markBase;
1346 MarkLigPos markLig; 1489 MarkLigPos markLig;
1347 MarkMarkPos markMark; 1490 MarkMarkPos markMark;
1348 ContextPos» » c; 1491 ContextPos» » context;
1349 ChainContextPos chainContext; 1492 ChainContextPos chainContext;
1350 ExtensionPos extension; 1493 ExtensionPos extension;
1351 } u; 1494 } u;
1352 public: 1495 public:
1353 DEFINE_SIZE_UNION (2, sub_format); 1496 DEFINE_SIZE_UNION (2, header.sub_format);
1354 }; 1497 };
1355 1498
1356 1499
1357 struct PosLookup : Lookup 1500 struct PosLookup : Lookup
1358 { 1501 {
1359 inline const PosLookupSubTable& get_subtable (unsigned int i) const 1502 inline const PosLookupSubTable& get_subtable (unsigned int i) const
1360 { return this+CastR<OffsetArrayOf<PosLookupSubTable> > (subTable)[i]; } 1503 { return this+CastR<OffsetArrayOf<PosLookupSubTable> > (subTable)[i]; }
1361 1504
1505 template <typename set_t>
1506 inline void add_coverage (set_t *glyphs) const
1507 {
1508 const Coverage *last = NULL;
1509 unsigned int count = get_subtable_count ();
1510 for (unsigned int i = 0; i < count; i++) {
1511 const Coverage *c = &get_subtable (i).get_coverage (get_type ());
1512 if (c != last) {
1513 c->add_coverage (glyphs);
1514 last = c;
1515 }
1516 }
1517 }
1518
1362 inline bool apply_once (hb_apply_context_t *c) const 1519 inline bool apply_once (hb_apply_context_t *c) const
1363 { 1520 {
1364 unsigned int lookup_type = get_type (); 1521 unsigned int lookup_type = get_type ();
1365 1522
1366 if (!_hb_ot_layout_check_glyph_property (c->face, &c->buffer->cur(), c->look up_props, &c->property)) 1523 if (!c->check_glyph_property (&c->buffer->cur(), c->lookup_props, &c->proper ty))
1367 return false; 1524 return false;
1368 1525
1369 for (unsigned int i = 0; i < get_subtable_count (); i++) 1526 unsigned int count = get_subtable_count ();
1527 for (unsigned int i = 0; i < count; i++)
1370 if (get_subtable (i).apply (c, lookup_type)) 1528 if (get_subtable (i).apply (c, lookup_type))
1371 return true; 1529 return true;
1372 1530
1373 return false; 1531 return false;
1374 } 1532 }
1375 1533
1376 inline bool apply_string (hb_apply_context_t *c) const 1534 inline bool apply_string (hb_apply_context_t *c, const hb_set_digest_t *digest ) const
1377 { 1535 {
1378 bool ret = false; 1536 bool ret = false;
1379 1537
1380 if (unlikely (!c->buffer->len)) 1538 if (unlikely (!c->buffer->len || !c->lookup_mask))
1381 return false; 1539 return false;
1382 1540
1383 c->set_lookup (*this); 1541 c->set_lookup (*this);
1384 1542
1385 c->buffer->idx = 0; 1543 c->buffer->idx = 0;
1544
1386 while (c->buffer->idx < c->buffer->len) 1545 while (c->buffer->idx < c->buffer->len)
1387 { 1546 {
1388 if ((c->buffer->cur().mask & c->lookup_mask) && apply_once (c)) 1547 if ((c->buffer->cur().mask & c->lookup_mask) &&
1548 » digest->may_have (c->buffer->cur().codepoint) &&
1549 » apply_once (c))
1389 ret = true; 1550 ret = true;
1390 else 1551 else
1391 c->buffer->idx++; 1552 c->buffer->idx++;
1392 } 1553 }
1393 1554
1394 return ret; 1555 return ret;
1395 } 1556 }
1396 1557
1397 inline bool sanitize (hb_sanitize_context_t *c) { 1558 inline bool sanitize (hb_sanitize_context_t *c) {
1398 TRACE_SANITIZE (); 1559 TRACE_SANITIZE ();
1399 if (unlikely (!Lookup::sanitize (c))) return TRACE_RETURN (false); 1560 if (unlikely (!Lookup::sanitize (c))) return TRACE_RETURN (false);
1400 OffsetArrayOf<PosLookupSubTable> &list = CastR<OffsetArrayOf<PosLookupSubTab le> > (subTable); 1561 OffsetArrayOf<PosLookupSubTable> &list = CastR<OffsetArrayOf<PosLookupSubTab le> > (subTable);
1401 return TRACE_RETURN (list.sanitize (c, this, get_type ())); 1562 return TRACE_RETURN (list.sanitize (c, this, get_type ()));
1402 } 1563 }
1403 }; 1564 };
1404 1565
1405 typedef OffsetListOf<PosLookup> PosLookupList; 1566 typedef OffsetListOf<PosLookup> PosLookupList;
1406 1567
1407 /* 1568 /*
1408 * GPOS -- The Glyph Positioning Table 1569 * GPOS -- The Glyph Positioning Table
1409 */ 1570 */
1410 1571
1411 struct GPOS : GSUBGPOS 1572 struct GPOS : GSUBGPOS
1412 { 1573 {
1413 static const hb_tag_t Tag = HB_OT_TAG_GPOS; 1574 static const hb_tag_t Tag = HB_OT_TAG_GPOS;
1414 1575
1415 inline const PosLookup& get_lookup (unsigned int i) const 1576 inline const PosLookup& get_lookup (unsigned int i) const
1416 { return CastR<PosLookup> (GSUBGPOS::get_lookup (i)); } 1577 { return CastR<PosLookup> (GSUBGPOS::get_lookup (i)); }
1417 1578
1418 inline bool position_lookup (hb_apply_context_t *c, unsigned int lookup_index) const 1579 template <typename set_t>
1419 { return get_lookup (lookup_index).apply_string (c); } 1580 inline void add_coverage (set_t *glyphs, unsigned int lookup_index) const
1581 { get_lookup (lookup_index).add_coverage (glyphs); }
1420 1582
1421 static inline void position_start (hb_buffer_t *buffer); 1583 static inline void position_start (hb_font_t *font, hb_buffer_t *buffer);
1422 static inline void position_finish (hb_buffer_t *buffer); 1584 static inline void position_finish (hb_font_t *font, hb_buffer_t *buffer, hb_b ool_t zero_width_attahced_marks);
1423 1585
1424 inline bool sanitize (hb_sanitize_context_t *c) { 1586 inline bool sanitize (hb_sanitize_context_t *c) {
1425 TRACE_SANITIZE (); 1587 TRACE_SANITIZE ();
1426 if (unlikely (!GSUBGPOS::sanitize (c))) return TRACE_RETURN (false); 1588 if (unlikely (!GSUBGPOS::sanitize (c))) return TRACE_RETURN (false);
1427 OffsetTo<PosLookupList> &list = CastR<OffsetTo<PosLookupList> > (lookupList) ; 1589 OffsetTo<PosLookupList> &list = CastR<OffsetTo<PosLookupList> > (lookupList) ;
1428 return TRACE_RETURN (list.sanitize (c, this)); 1590 return TRACE_RETURN (list.sanitize (c, this));
1429 } 1591 }
1430 public: 1592 public:
1431 DEFINE_SIZE_STATIC (10); 1593 DEFINE_SIZE_STATIC (10);
1432 }; 1594 };
1433 1595
1434 1596
1435 static void 1597 static void
1436 fix_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direction _t direction) 1598 fix_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direction _t direction)
1437 { 1599 {
1438 unsigned int j = pos[i].cursive_chain(); 1600 unsigned int j = pos[i].cursive_chain();
1439 if (likely (!j)) 1601 if (likely (!j))
1440 return; 1602 return;
1441 1603
1442 j += i; 1604 j += i;
1443 1605
1444 pos[i].cursive_chain() = 0; 1606 pos[i].cursive_chain() = 0;
1445 1607
1446 fix_cursive_minor_offset (pos, j, direction); 1608 fix_cursive_minor_offset (pos, j, direction);
1447 1609
1448 if (HB_DIRECTION_IS_HORIZONTAL (direction)) 1610 if (HB_DIRECTION_IS_HORIZONTAL (direction))
1449 pos[i].y_offset += pos[j].y_offset; 1611 pos[i].y_offset += pos[j].y_offset;
1450 else 1612 else
1451 pos[i].x_offset += pos[j].x_offset; 1613 pos[i].x_offset += pos[j].x_offset;
1452 } 1614 }
1453 1615
1454 static void 1616 static void
1455 fix_mark_attachment (hb_glyph_position_t *pos, unsigned int i, hb_direction_t di rection) 1617 fix_mark_attachment (hb_glyph_position_t *pos, unsigned int i, hb_direction_t di rection, hb_bool_t zero_width_attached_marks)
1456 { 1618 {
1457 if (likely (!(pos[i].attach_lookback()))) 1619 if (likely (!(pos[i].attach_lookback())))
1458 return; 1620 return;
1459 1621
1460 unsigned int j = i - pos[i].attach_lookback(); 1622 unsigned int j = i - pos[i].attach_lookback();
1461 1623
1462 pos[i].x_advance = 0; 1624 if (zero_width_attached_marks) {
1463 pos[i].y_advance = 0; 1625 pos[i].x_advance = 0;
1626 pos[i].y_advance = 0;
1627 }
1464 pos[i].x_offset += pos[j].x_offset; 1628 pos[i].x_offset += pos[j].x_offset;
1465 pos[i].y_offset += pos[j].y_offset; 1629 pos[i].y_offset += pos[j].y_offset;
1466 1630
1467 if (HB_DIRECTION_IS_FORWARD (direction)) 1631 if (HB_DIRECTION_IS_FORWARD (direction))
1468 for (unsigned int k = j; k < i; k++) { 1632 for (unsigned int k = j; k < i; k++) {
1469 pos[i].x_offset -= pos[k].x_advance; 1633 pos[i].x_offset -= pos[k].x_advance;
1470 pos[i].y_offset -= pos[k].y_advance; 1634 pos[i].y_offset -= pos[k].y_advance;
1471 } 1635 }
1472 else 1636 else
1473 for (unsigned int k = j + 1; k < i + 1; k++) { 1637 for (unsigned int k = j + 1; k < i + 1; k++) {
1474 pos[i].x_offset += pos[k].x_advance; 1638 pos[i].x_offset += pos[k].x_advance;
1475 pos[i].y_offset += pos[k].y_advance; 1639 pos[i].y_offset += pos[k].y_advance;
1476 } 1640 }
1477 } 1641 }
1478 1642
1479 void 1643 void
1480 GPOS::position_start (hb_buffer_t *buffer) 1644 GPOS::position_start (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer)
1481 { 1645 {
1482 buffer->clear_positions (); 1646 buffer->clear_positions ();
1483 1647
1484 unsigned int count = buffer->len; 1648 unsigned int count = buffer->len;
1485 for (unsigned int i = 0; i < count; i++) 1649 for (unsigned int i = 0; i < count; i++)
1486 buffer->pos[i].attach_lookback() = buffer->pos[i].cursive_chain() = 0; 1650 buffer->pos[i].attach_lookback() = buffer->pos[i].cursive_chain() = 0;
1487 } 1651 }
1488 1652
1489 void 1653 void
1490 GPOS::position_finish (hb_buffer_t *buffer) 1654 GPOS::position_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer, hb_bool_t zero_width_attached_marks)
1491 { 1655 {
1492 unsigned int len; 1656 unsigned int len;
1493 hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, &len); 1657 hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, &len);
1494 hb_direction_t direction = buffer->props.direction; 1658 hb_direction_t direction = buffer->props.direction;
1495 1659
1496 /* Handle cursive connections */ 1660 /* Handle cursive connections */
1497 for (unsigned int i = 0; i < len; i++) 1661 for (unsigned int i = 0; i < len; i++)
1498 fix_cursive_minor_offset (pos, i, direction); 1662 fix_cursive_minor_offset (pos, i, direction);
1499 1663
1500 /* Handle attachments */ 1664 /* Handle attachments */
1501 for (unsigned int i = 0; i < len; i++) 1665 for (unsigned int i = 0; i < len; i++)
1502 fix_mark_attachment (pos, i, direction); 1666 fix_mark_attachment (pos, i, direction, zero_width_attached_marks);
1503 1667
1504 HB_BUFFER_DEALLOCATE_VAR (buffer, syllable); 1668 HB_BUFFER_DEALLOCATE_VAR (buffer, syllable);
1505 HB_BUFFER_DEALLOCATE_VAR (buffer, lig_props); 1669 HB_BUFFER_DEALLOCATE_VAR (buffer, lig_props);
1506 HB_BUFFER_DEALLOCATE_VAR (buffer, props_cache); 1670 HB_BUFFER_DEALLOCATE_VAR (buffer, glyph_props);
1507 } 1671 }
1508 1672
1509 1673
1510 /* Out-of-class implementation for methods recursing */ 1674 /* Out-of-class implementation for methods recursing */
1511 1675
1676 inline const Coverage & ExtensionPos::get_coverage (void) const
1677 {
1678 return get_subtable ().get_coverage (get_type ());
1679 }
1680
1512 inline bool ExtensionPos::apply (hb_apply_context_t *c) const 1681 inline bool ExtensionPos::apply (hb_apply_context_t *c) const
1513 { 1682 {
1514 TRACE_APPLY (); 1683 TRACE_APPLY ();
1515 return TRACE_RETURN (get_subtable ().apply (c, get_type ())); 1684 return TRACE_RETURN (get_subtable ().apply (c, get_type ()));
1516 } 1685 }
1517 1686
1518 inline bool ExtensionPos::sanitize (hb_sanitize_context_t *c) 1687 inline bool ExtensionPos::sanitize (hb_sanitize_context_t *c)
1519 { 1688 {
1520 TRACE_SANITIZE (); 1689 TRACE_SANITIZE ();
1521 if (unlikely (!Extension::sanitize (c))) return TRACE_RETURN (false); 1690 if (unlikely (!Extension::sanitize (c))) return TRACE_RETURN (false);
1522 unsigned int offset = get_offset (); 1691 unsigned int offset = get_offset ();
1523 if (unlikely (!offset)) return TRACE_RETURN (true); 1692 if (unlikely (!offset)) return TRACE_RETURN (true);
1524 return TRACE_RETURN (StructAtOffset<PosLookupSubTable> (this, offset).sanitize (c, get_type ())); 1693 return TRACE_RETURN (StructAtOffset<PosLookupSubTable> (this, offset).sanitize (c, get_type ()));
1525 } 1694 }
1526 1695
1527 static inline bool position_lookup (hb_apply_context_t *c, unsigned int lookup_i ndex) 1696 static inline bool position_lookup (hb_apply_context_t *c, unsigned int lookup_i ndex)
1528 { 1697 {
1529 const GPOS &gpos = *(c->face->ot_layout->gpos); 1698 const GPOS &gpos = *(hb_ot_layout_from_face (c->face)->gpos);
1530 const PosLookup &l = gpos.get_lookup (lookup_index); 1699 const PosLookup &l = gpos.get_lookup (lookup_index);
1531 1700
1532 if (unlikely (c->nesting_level_left == 0)) 1701 if (unlikely (c->nesting_level_left == 0))
1533 return false; 1702 return false;
1534 1703
1535 hb_apply_context_t new_c (*c); 1704 hb_apply_context_t new_c (*c);
1536 new_c.nesting_level_left--; 1705 new_c.nesting_level_left--;
1537 new_c.set_lookup (l); 1706 new_c.set_lookup (l);
1538 return l.apply_once (&new_c); 1707 return l.apply_once (&new_c);
1539 } 1708 }
1540 1709
1541 1710
1542 #undef attach_lookback 1711 #undef attach_lookback
1543 #undef cursive_chain 1712 #undef cursive_chain
1544 1713
1545 1714
1715 } // namespace OT
1716
1546 1717
1547 #endif /* HB_OT_LAYOUT_GPOS_TABLE_HH */ 1718 #endif /* HB_OT_LAYOUT_GPOS_TABLE_HH */
OLDNEW
« no previous file with comments | « third_party/harfbuzz-ng/src/hb-ot-layout-gdef-table.hh ('k') | third_party/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698