| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 */ |
| OLD | NEW |