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

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

Issue 9223010: Update harfbuzz-ng to 1a5a91dc0d8bf4b72a2f22dc6300b06ad7000b79. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Don't use -M option for 'git diff' to patch correctly Created 8 years, 10 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 (C) 2007,2008,2009,2010 Red Hat, Inc. 2 * Copyright © 2007,2008,2009,2010 Red Hat, Inc.
3 * Copyright (C) 2010 Google, Inc. 3 * Copyright © 2010 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
11 * all copies of this software. 11 * all copies of this software.
12 * 12 *
13 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 13 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
14 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 14 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
15 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 15 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
16 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 16 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
17 * DAMAGE. 17 * DAMAGE.
18 * 18 *
19 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 19 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
20 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21 * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 21 * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
22 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 22 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
23 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 23 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
24 * 24 *
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_PRIVATE_HH 29 #ifndef HB_OT_LAYOUT_GPOS_TABLE_HH
30 #define HB_OT_LAYOUT_GPOS_PRIVATE_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 HB_BEGIN_DECLS
35 34
36 35
37 /* buffer var allocations */ 36 /* buffer **position** var allocations */
38 #define attach_lookback() var.u16[0] /* number of glyphs to go back to attach th is glyph to its base */ 37 #define attach_lookback() var.u16[0] /* number of glyphs to go back to attach th is glyph to its base */
39 #define cursive_chain() var.i16[1] /* character to which this connects, may be p ositive or negative */ 38 #define cursive_chain() var.i16[1] /* character to which this connects, may be p ositive or negative */
40 39
41 40
42 /* Shared Tables: ValueRecord, Anchor Table, and MarkArray */ 41 /* Shared Tables: ValueRecord, Anchor Table, and MarkArray */
43 42
44 typedef USHORT Value; 43 typedef USHORT Value;
45 44
46 typedef Value ValueRecord[VAR]; 45 typedef Value ValueRecord[VAR];
47 46
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 Offset yAdvDevice; /* Offset to Device table for vertical 86 Offset yAdvDevice; /* Offset to Device table for vertical
88 * advance--measured from beginning of 87 * advance--measured from beginning of
89 * PosTable (may be NULL) */ 88 * PosTable (may be NULL) */
90 #endif 89 #endif
91 90
92 inline unsigned int get_len (void) const 91 inline unsigned int get_len (void) const
93 { return _hb_popcount32 ((unsigned int) *this); } 92 { return _hb_popcount32 ((unsigned int) *this); }
94 inline unsigned int get_size (void) const 93 inline unsigned int get_size (void) const
95 { return get_len () * Value::static_size; } 94 { return get_len () * Value::static_size; }
96 95
97 void apply_value (hb_ot_layout_context_t *layout, 96 void apply_value (hb_font_t *font,
98 » » const void *base, 97 » » hb_direction_t direction,
99 » » const Value *values, 98 » » const void *base,
100 » » hb_glyph_position_t &glyph_pos) const 99 » » const Value *values,
100 » » hb_glyph_position_t &glyph_pos) const
101 { 101 {
102 unsigned int x_ppem, y_ppem; 102 unsigned int x_ppem, y_ppem;
103 unsigned int format = *this; 103 unsigned int format = *this;
104 hb_bool_t horizontal = HB_DIRECTION_IS_HORIZONTAL (direction);
104 105
105 if (!format) return; 106 if (!format) return;
106 107
107 /* design units -> fractional pixel */ 108 if (format & xPlacement) glyph_pos.x_offset += font->em_scale_x (get_short (values++));
108 if (format & xPlacement) glyph_pos.x_offset += layout->scale_x (get_short ( values++)); 109 if (format & yPlacement) glyph_pos.y_offset += font->em_scale_y (get_short (values++));
109 if (format & yPlacement) glyph_pos.y_offset += layout->scale_y (get_short ( values++)); 110 if (format & xAdvance) {
110 if (format & xAdvance) glyph_pos.x_advance += layout->scale_x (get_short ( values++)); 111 if (likely (horizontal)) glyph_pos.x_advance += font->em_scale_x (get_shor t (values++)); else values++;
111 if (format & yAdvance) glyph_pos.y_advance += layout->scale_y (get_short ( values++)); 112 }
113 /* y_advance values grow downward but font-space grows upward, hence negatio n */
114 if (format & yAdvance) {
115 if (unlikely (!horizontal)) glyph_pos.y_advance -= font->em_scale_y (get_s hort (values++)); else values++;
116 }
112 117
113 if (!has_device ()) return; 118 if (!has_device ()) return;
114 119
115 x_ppem = layout->font->x_ppem; 120 x_ppem = font->x_ppem;
116 y_ppem = layout->font->y_ppem; 121 y_ppem = font->y_ppem;
117 122
118 if (!x_ppem && !y_ppem) return; 123 if (!x_ppem && !y_ppem) return;
119 124
120 /* pixel -> fractional pixel */ 125 /* pixel -> fractional pixel */
121 if (format & xPlaDevice) { 126 if (format & xPlaDevice) {
122 if (x_ppem) glyph_pos.x_offset += (base + get_device (values++)).get_x_de lta (layout); else values++; 127 if (x_ppem) glyph_pos.x_offset += (base + get_device (values++)).get_x_de lta (font); else values++;
123 } 128 }
124 if (format & yPlaDevice) { 129 if (format & yPlaDevice) {
125 if (y_ppem) glyph_pos.y_offset += (base + get_device (values++)).get_y_de lta (layout); else values++; 130 if (y_ppem) glyph_pos.y_offset += (base + get_device (values++)).get_y_de lta (font); else values++;
126 } 131 }
127 if (format & xAdvDevice) { 132 if (format & xAdvDevice) {
128 if (x_ppem) glyph_pos.x_advance += (base + get_device (values++)).get_x_de lta (layout); else values++; 133 if (horizontal && x_ppem) glyph_pos.x_advance += (base + get_device (value s++)).get_x_delta (font); else values++;
129 } 134 }
130 if (format & yAdvDevice) { 135 if (format & yAdvDevice) {
131 if (y_ppem) glyph_pos.y_advance += (base + get_device (values++)).get_y_de lta (layout); else values++; 136 /* y_advance values grow downward but font-space grows upward, hence negat ion */
137 if (!horizontal && y_ppem) glyph_pos.y_advance -= (base + get_device (valu es++)).get_y_delta (font); else values++;
132 } 138 }
133 } 139 }
134 140
135 private: 141 private:
136 inline bool sanitize_value_devices (hb_sanitize_context_t *c, void *base, Valu e *values) { 142 inline bool sanitize_value_devices (hb_sanitize_context_t *c, void *base, Valu e *values) {
137 unsigned int format = *this; 143 unsigned int format = *this;
138 144
139 if (format & xPlacement) values++; 145 if (format & xPlacement) values++;
140 if (format & yPlacement) values++; 146 if (format & yPlacement) values++;
141 if (format & xAdvance) values++; 147 if (format & xAdvance) values++;
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 return true; 208 return true;
203 } 209 }
204 }; 210 };
205 211
206 212
207 struct AnchorFormat1 213 struct AnchorFormat1
208 { 214 {
209 friend struct Anchor; 215 friend struct Anchor;
210 216
211 private: 217 private:
212 inline void get_anchor (hb_ot_layout_context_t *layout, hb_codepoint_t glyph_i d HB_UNUSED, 218 inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id HB_UNUSED,
213 hb_position_t *x, hb_position_t *y) const 219 hb_position_t *x, hb_position_t *y) const
214 { 220 {
215 *x = layout->scale_x (xCoordinate); 221 *x = font->em_scale_x (xCoordinate);
216 *y = layout->scale_y (yCoordinate); 222 *y = font->em_scale_y (yCoordinate);
217 } 223 }
218 224
219 inline bool sanitize (hb_sanitize_context_t *c) { 225 inline bool sanitize (hb_sanitize_context_t *c) {
220 TRACE_SANITIZE (); 226 TRACE_SANITIZE ();
221 return c->check_struct (this); 227 return c->check_struct (this);
222 } 228 }
223 229
224 private: 230 private:
225 USHORT format; /* Format identifier--format = 1 */ 231 USHORT format; /* Format identifier--format = 1 */
226 SHORT xCoordinate; /* Horizontal value--in design units */ 232 SHORT xCoordinate; /* Horizontal value--in design units */
227 SHORT yCoordinate; /* Vertical value--in design units */ 233 SHORT yCoordinate; /* Vertical value--in design units */
228 public: 234 public:
229 DEFINE_SIZE_STATIC (6); 235 DEFINE_SIZE_STATIC (6);
230 }; 236 };
231 237
232 struct AnchorFormat2 238 struct AnchorFormat2
233 { 239 {
234 friend struct Anchor; 240 friend struct Anchor;
235 241
236 private: 242 private:
237 inline void get_anchor (hb_ot_layout_context_t *layout, hb_codepoint_t glyph_i d, 243 inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id,
238 hb_position_t *x, hb_position_t *y) const 244 hb_position_t *x, hb_position_t *y) const
239 { 245 {
240 unsigned int x_ppem = layout->font->x_ppem; 246 unsigned int x_ppem = font->x_ppem;
241 unsigned int y_ppem = layout->font->y_ppem; 247 unsigned int y_ppem = font->y_ppem;
242 hb_position_t cx, cy; 248 hb_position_t cx, cy;
243 hb_bool_t ret = false; 249 hb_bool_t ret = false;
244 250
245 if (x_ppem || y_ppem) 251 if (x_ppem || y_ppem)
246 » ret = hb_font_get_contour_point (layout->font, layout->face, anchorPoint , glyph_id, &cx, &cy); 252 » ret = hb_font_get_glyph_contour_point_for_origin (font, glyph_id, anchor Point, HB_DIRECTION_LTR, &cx, &cy);
247 *x = x_ppem && ret ? cx : layout->scale_x (xCoordinate); 253 *x = x_ppem && ret ? cx : font->em_scale_x (xCoordinate);
248 *y = y_ppem && ret ? cy : layout->scale_y (yCoordinate); 254 *y = y_ppem && ret ? cy : font->em_scale_y (yCoordinate);
249 } 255 }
250 256
251 inline bool sanitize (hb_sanitize_context_t *c) { 257 inline bool sanitize (hb_sanitize_context_t *c) {
252 TRACE_SANITIZE (); 258 TRACE_SANITIZE ();
253 return c->check_struct (this); 259 return c->check_struct (this);
254 } 260 }
255 261
256 private: 262 private:
257 USHORT format; /* Format identifier--format = 2 */ 263 USHORT format; /* Format identifier--format = 2 */
258 SHORT xCoordinate; /* Horizontal value--in design units */ 264 SHORT xCoordinate; /* Horizontal value--in design units */
259 SHORT yCoordinate; /* Vertical value--in design units */ 265 SHORT yCoordinate; /* Vertical value--in design units */
260 USHORT anchorPoint; /* Index to glyph contour point */ 266 USHORT anchorPoint; /* Index to glyph contour point */
261 public: 267 public:
262 DEFINE_SIZE_STATIC (8); 268 DEFINE_SIZE_STATIC (8);
263 }; 269 };
264 270
265 struct AnchorFormat3 271 struct AnchorFormat3
266 { 272 {
267 friend struct Anchor; 273 friend struct Anchor;
268 274
269 private: 275 private:
270 inline void get_anchor (hb_ot_layout_context_t *layout, hb_codepoint_t glyph_i d HB_UNUSED, 276 inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id HB_UNUSED,
271 hb_position_t *x, hb_position_t *y) const 277 hb_position_t *x, hb_position_t *y) const
272 { 278 {
273 *x = layout->scale_x (xCoordinate); 279 *x = font->em_scale_x (xCoordinate);
274 *y = layout->scale_y (yCoordinate); 280 *y = font->em_scale_y (yCoordinate);
275 281
276 /* pixel -> fractional pixel */ 282 if (font->x_ppem)
277 if (layout->font->x_ppem) 283 » *x += (this+xDeviceTable).get_x_delta (font);
278 » *x += (this+xDeviceTable).get_x_delta (layout); 284 if (font->y_ppem)
279 if (layout->font->y_ppem) 285 » *y += (this+yDeviceTable).get_x_delta (font);
280 » *y += (this+yDeviceTable).get_x_delta (layout);
281 } 286 }
282 287
283 inline bool sanitize (hb_sanitize_context_t *c) { 288 inline bool sanitize (hb_sanitize_context_t *c) {
284 TRACE_SANITIZE (); 289 TRACE_SANITIZE ();
285 return c->check_struct (this) 290 return c->check_struct (this)
286 && xDeviceTable.sanitize (c, this) 291 && xDeviceTable.sanitize (c, this)
287 && yDeviceTable.sanitize (c, this); 292 && yDeviceTable.sanitize (c, this);
288 } 293 }
289 294
290 private: 295 private:
291 USHORT format; /* Format identifier--format = 3 */ 296 USHORT format; /* Format identifier--format = 3 */
292 SHORT xCoordinate; /* Horizontal value--in design units */ 297 SHORT xCoordinate; /* Horizontal value--in design units */
293 SHORT yCoordinate; /* Vertical value--in design units */ 298 SHORT yCoordinate; /* Vertical value--in design units */
294 OffsetTo<Device> 299 OffsetTo<Device>
295 xDeviceTable; /* Offset to Device table for X 300 xDeviceTable; /* Offset to Device table for X
296 * coordinate-- from beginning of 301 * coordinate-- from beginning of
297 * Anchor table (may be NULL) */ 302 * Anchor table (may be NULL) */
298 OffsetTo<Device> 303 OffsetTo<Device>
299 yDeviceTable; /* Offset to Device table for Y 304 yDeviceTable; /* Offset to Device table for Y
300 * coordinate-- from beginning of 305 * coordinate-- from beginning of
301 * Anchor table (may be NULL) */ 306 * Anchor table (may be NULL) */
302 public: 307 public:
303 DEFINE_SIZE_STATIC (10); 308 DEFINE_SIZE_STATIC (10);
304 }; 309 };
305 310
306 struct Anchor 311 struct Anchor
307 { 312 {
308 inline void get_anchor (hb_ot_layout_context_t *layout, hb_codepoint_t glyph_i d, 313 inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id,
309 hb_position_t *x, hb_position_t *y) const 314 hb_position_t *x, hb_position_t *y) const
310 { 315 {
311 *x = *y = 0; 316 *x = *y = 0;
312 switch (u.format) { 317 switch (u.format) {
313 case 1: u.format1.get_anchor (layout, glyph_id, x, y); return; 318 case 1: u.format1.get_anchor (font, glyph_id, x, y); return;
314 case 2: u.format2.get_anchor (layout, glyph_id, x, y); return; 319 case 2: u.format2.get_anchor (font, glyph_id, x, y); return;
315 case 3: u.format3.get_anchor (layout, glyph_id, x, y); return; 320 case 3: u.format3.get_anchor (font, glyph_id, x, y); return;
316 default:» » » » » » return; 321 default:» » » » » » return;
317 } 322 }
318 } 323 }
319 324
320 inline bool sanitize (hb_sanitize_context_t *c) { 325 inline bool sanitize (hb_sanitize_context_t *c) {
321 TRACE_SANITIZE (); 326 TRACE_SANITIZE ();
322 if (!u.format.sanitize (c)) return false; 327 if (!u.format.sanitize (c)) return false;
323 switch (u.format) { 328 switch (u.format) {
324 case 1: return u.format1.sanitize (c); 329 case 1: return u.format1.sanitize (c);
325 case 2: return u.format2.sanitize (c); 330 case 2: return u.format2.sanitize (c);
326 case 3: return u.format3.sanitize (c); 331 case 3: return u.format3.sanitize (c);
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
396 { 401 {
397 TRACE_APPLY (); 402 TRACE_APPLY ();
398 const MarkRecord &record = ArrayOf<MarkRecord>::operator[](mark_index); 403 const MarkRecord &record = ArrayOf<MarkRecord>::operator[](mark_index);
399 unsigned int mark_class = record.klass; 404 unsigned int mark_class = record.klass;
400 405
401 const Anchor& mark_anchor = this + record.markAnchor; 406 const Anchor& mark_anchor = this + record.markAnchor;
402 const Anchor& glyph_anchor = anchors.get_anchor (glyph_index, mark_class, cl ass_count); 407 const Anchor& glyph_anchor = anchors.get_anchor (glyph_index, mark_class, cl ass_count);
403 408
404 hb_position_t mark_x, mark_y, base_x, base_y; 409 hb_position_t mark_x, mark_y, base_x, base_y;
405 410
406 mark_anchor.get_anchor (c->layout, c->buffer->info[c->buffer->i].codepoint, &mark_x, &mark_y); 411 mark_anchor.get_anchor (c->font, c->buffer->info[c->buffer->idx].codepoint, &mark_x, &mark_y);
407 glyph_anchor.get_anchor (c->layout, c->buffer->info[glyph_pos].codepoint, &b ase_x, &base_y); 412 glyph_anchor.get_anchor (c->font, c->buffer->info[glyph_pos].codepoint, &bas e_x, &base_y);
408 413
409 hb_glyph_position_t &o = c->buffer->pos[c->buffer->i]; 414 hb_glyph_position_t &o = c->buffer->pos[c->buffer->idx];
410 o.x_offset = base_x - mark_x; 415 o.x_offset = base_x - mark_x;
411 o.y_offset = base_y - mark_y; 416 o.y_offset = base_y - mark_y;
412 o.attach_lookback() = c->buffer->i - glyph_pos; 417 o.attach_lookback() = c->buffer->idx - glyph_pos;
413 418
414 c->buffer->i++; 419 c->buffer->idx++;
415 return true; 420 return true;
416 } 421 }
417 422
418 inline bool sanitize (hb_sanitize_context_t *c) { 423 inline bool sanitize (hb_sanitize_context_t *c) {
419 TRACE_SANITIZE (); 424 TRACE_SANITIZE ();
420 return ArrayOf<MarkRecord>::sanitize (c, this); 425 return ArrayOf<MarkRecord>::sanitize (c, this);
421 } 426 }
422 }; 427 };
423 428
424 429
425 /* Lookups */ 430 /* Lookups */
426 431
427 struct SinglePosFormat1 432 struct SinglePosFormat1
428 { 433 {
429 friend struct SinglePos; 434 friend struct SinglePos;
430 435
431 private: 436 private:
432 inline bool apply (hb_apply_context_t *c) const 437 inline bool apply (hb_apply_context_t *c) const
433 { 438 {
434 TRACE_APPLY (); 439 TRACE_APPLY ();
435 unsigned int index = (this+coverage) (c->buffer->info[c->buffer->i].codepoin t); 440 unsigned int index = (this+coverage) (c->buffer->info[c->buffer->idx].codepo int);
436 if (likely (index == NOT_COVERED)) 441 if (likely (index == NOT_COVERED))
437 return false; 442 return false;
438 443
439 valueFormat.apply_value (c->layout, this, values, c->buffer->pos[c->buffer-> i]); 444 valueFormat.apply_value (c->font, c->direction, this,
445 » » » values, c->buffer->pos[c->buffer->idx]);
440 446
441 c->buffer->i++; 447 c->buffer->idx++;
442 return true; 448 return true;
443 } 449 }
444 450
445 inline bool sanitize (hb_sanitize_context_t *c) { 451 inline bool sanitize (hb_sanitize_context_t *c) {
446 TRACE_SANITIZE (); 452 TRACE_SANITIZE ();
447 return c->check_struct (this) 453 return c->check_struct (this)
448 && coverage.sanitize (c, this) 454 && coverage.sanitize (c, this)
449 && valueFormat.sanitize_value (c, this, values); 455 && valueFormat.sanitize_value (c, this, values);
450 } 456 }
451 457
(...skipping 12 matching lines...) Expand all
464 }; 470 };
465 471
466 struct SinglePosFormat2 472 struct SinglePosFormat2
467 { 473 {
468 friend struct SinglePos; 474 friend struct SinglePos;
469 475
470 private: 476 private:
471 inline bool apply (hb_apply_context_t *c) const 477 inline bool apply (hb_apply_context_t *c) const
472 { 478 {
473 TRACE_APPLY (); 479 TRACE_APPLY ();
474 unsigned int index = (this+coverage) (c->buffer->info[c->buffer->i].codepoin t); 480 unsigned int index = (this+coverage) (c->buffer->info[c->buffer->idx].codepo int);
475 if (likely (index == NOT_COVERED)) 481 if (likely (index == NOT_COVERED))
476 return false; 482 return false;
477 483
478 if (likely (index >= valueCount)) 484 if (likely (index >= valueCount))
479 return false; 485 return false;
480 486
481 valueFormat.apply_value (c->layout, this, 487 valueFormat.apply_value (c->font, c->direction, this,
482 &values[index * valueFormat.get_len ()], 488 &values[index * valueFormat.get_len ()],
483 » » » c->buffer->pos[c->buffer->i]); 489 » » » c->buffer->pos[c->buffer->idx]);
484 490
485 c->buffer->i++; 491 c->buffer->idx++;
486 return true; 492 return true;
487 } 493 }
488 494
489 inline bool sanitize (hb_sanitize_context_t *c) { 495 inline bool sanitize (hb_sanitize_context_t *c) {
490 TRACE_SANITIZE (); 496 TRACE_SANITIZE ();
491 return c->check_struct (this) 497 return c->check_struct (this)
492 && coverage.sanitize (c, this) 498 && coverage.sanitize (c, this)
493 && valueFormat.sanitize_values (c, this, values, valueCount); 499 && valueFormat.sanitize_values (c, this, values, valueCount);
494 } 500 }
495 501
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
567 unsigned int len1 = valueFormats[0].get_len (); 573 unsigned int len1 = valueFormats[0].get_len ();
568 unsigned int len2 = valueFormats[1].get_len (); 574 unsigned int len2 = valueFormats[1].get_len ();
569 unsigned int record_size = USHORT::static_size * (1 + len1 + len2); 575 unsigned int record_size = USHORT::static_size * (1 + len1 + len2);
570 576
571 unsigned int count = len; 577 unsigned int count = len;
572 const PairValueRecord *record = CastP<PairValueRecord> (array); 578 const PairValueRecord *record = CastP<PairValueRecord> (array);
573 for (unsigned int i = 0; i < count; i++) 579 for (unsigned int i = 0; i < count; i++)
574 { 580 {
575 if (c->buffer->info[pos].codepoint == record->secondGlyph) 581 if (c->buffer->info[pos].codepoint == record->secondGlyph)
576 { 582 {
577 » valueFormats[0].apply_value (c->layout, this, &record->values[0], c->buf fer->pos[c->buffer->i]); 583 » valueFormats[0].apply_value (c->font, c->direction, this,
578 » valueFormats[1].apply_value (c->layout, this, &record->values[len1], c-> buffer->pos[pos]); 584 » » » » &record->values[0], c->buffer->pos[c->buffe r->idx]);
585 » valueFormats[1].apply_value (c->font, c->direction, this,
586 » » » » &record->values[len1], c->buffer->pos[pos]) ;
579 if (len2) 587 if (len2)
580 pos++; 588 pos++;
581 » c->buffer->i = pos; 589 » c->buffer->idx = pos;
582 return true; 590 return true;
583 } 591 }
584 record = &StructAtOffset<PairValueRecord> (record, record_size); 592 record = &StructAtOffset<PairValueRecord> (record, record_size);
585 } 593 }
586 594
587 return false; 595 return false;
588 } 596 }
589 597
590 struct sanitize_closure_t { 598 struct sanitize_closure_t {
591 void *base; 599 void *base;
(...skipping 22 matching lines...) Expand all
614 }; 622 };
615 623
616 struct PairPosFormat1 624 struct PairPosFormat1
617 { 625 {
618 friend struct PairPos; 626 friend struct PairPos;
619 627
620 private: 628 private:
621 inline bool apply (hb_apply_context_t *c) const 629 inline bool apply (hb_apply_context_t *c) const
622 { 630 {
623 TRACE_APPLY (); 631 TRACE_APPLY ();
624 unsigned int end = MIN (c->buffer->len, c->buffer->i + c->context_length); 632 hb_apply_context_t::mark_skipping_forward_iterator_t skippy_iter (c, c->buff er->idx, 1);
625 if (unlikely (c->buffer->i + 2 > end)) 633 if (skippy_iter.has_no_chance ())
626 return false; 634 return false;
627 635
628 unsigned int index = (this+coverage) (c->buffer->info[c->buffer->i].codepoin t); 636 unsigned int index = (this+coverage) (c->buffer->info[c->buffer->idx].codepo int);
629 if (likely (index == NOT_COVERED)) 637 if (likely (index == NOT_COVERED))
630 return false; 638 return false;
631 639
632 unsigned int j = c->buffer->i + 1; 640 if (!skippy_iter.next ())
633 while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->info[j], c->loo kup_props, NULL)) 641 return false;
634 {
635 if (unlikely (j == end))
636 » return false;
637 j++;
638 }
639 642
640 return (this+pairSet[index]).apply (c, &valueFormat1, j); 643 return (this+pairSet[index]).apply (c, &valueFormat1, skippy_iter.idx);
641 } 644 }
642 645
643 inline bool sanitize (hb_sanitize_context_t *c) { 646 inline bool sanitize (hb_sanitize_context_t *c) {
644 TRACE_SANITIZE (); 647 TRACE_SANITIZE ();
645 648
646 unsigned int len1 = valueFormat1.get_len (); 649 unsigned int len1 = valueFormat1.get_len ();
647 unsigned int len2 = valueFormat2.get_len (); 650 unsigned int len2 = valueFormat2.get_len ();
648 PairSet::sanitize_closure_t closure = { 651 PairSet::sanitize_closure_t closure = {
649 this, 652 this,
650 &valueFormat1, 653 &valueFormat1,
(...skipping 25 matching lines...) Expand all
676 }; 679 };
677 680
678 struct PairPosFormat2 681 struct PairPosFormat2
679 { 682 {
680 friend struct PairPos; 683 friend struct PairPos;
681 684
682 private: 685 private:
683 inline bool apply (hb_apply_context_t *c) const 686 inline bool apply (hb_apply_context_t *c) const
684 { 687 {
685 TRACE_APPLY (); 688 TRACE_APPLY ();
686 unsigned int end = MIN (c->buffer->len, c->buffer->i + c->context_length); 689 hb_apply_context_t::mark_skipping_forward_iterator_t skippy_iter (c, c->buff er->idx, 1);
687 if (unlikely (c->buffer->i + 2 > end)) 690 if (skippy_iter.has_no_chance ())
688 return false; 691 return false;
689 692
690 unsigned int index = (this+coverage) (c->buffer->info[c->buffer->i].codepoin t); 693 unsigned int index = (this+coverage) (c->buffer->info[c->buffer->idx].codepo int);
691 if (likely (index == NOT_COVERED)) 694 if (likely (index == NOT_COVERED))
692 return false; 695 return false;
693 696
694 unsigned int j = c->buffer->i + 1; 697 if (!skippy_iter.next ())
695 while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->info[j], c->loo kup_props, NULL)) 698 return false;
696 {
697 if (unlikely (j == end))
698 » return false;
699 j++;
700 }
701 699
702 unsigned int len1 = valueFormat1.get_len (); 700 unsigned int len1 = valueFormat1.get_len ();
703 unsigned int len2 = valueFormat2.get_len (); 701 unsigned int len2 = valueFormat2.get_len ();
704 unsigned int record_len = len1 + len2; 702 unsigned int record_len = len1 + len2;
705 703
706 unsigned int klass1 = (this+classDef1) (c->buffer->info[c->buffer->i].codepo int); 704 unsigned int klass1 = (this+classDef1) (c->buffer->info[c->buffer->idx].code point);
707 unsigned int klass2 = (this+classDef2) (c->buffer->info[j].codepoint); 705 unsigned int klass2 = (this+classDef2) (c->buffer->info[skippy_iter.idx].cod epoint);
708 if (unlikely (klass1 >= class1Count || klass2 >= class2Count)) 706 if (unlikely (klass1 >= class1Count || klass2 >= class2Count))
709 return false; 707 return false;
710 708
711 const Value *v = &values[record_len * (klass1 * class2Count + klass2)]; 709 const Value *v = &values[record_len * (klass1 * class2Count + klass2)];
712 valueFormat1.apply_value (c->layout, this, v, c->buffer->pos[c->buffer->i]); 710 valueFormat1.apply_value (c->font, c->direction, this,
713 valueFormat2.apply_value (c->layout, this, v + len1, c->buffer->pos[j]); 711 » » » v, c->buffer->pos[c->buffer->idx]);
712 valueFormat2.apply_value (c->font, c->direction, this,
713 » » » v + len1, c->buffer->pos[skippy_iter.idx]);
714 714
715 c->buffer->idx = skippy_iter.idx;
715 if (len2) 716 if (len2)
716 j++; 717 c->buffer->idx++;
717 c->buffer->i = j;
718 718
719 return true; 719 return true;
720 } 720 }
721 721
722 inline bool sanitize (hb_sanitize_context_t *c) { 722 inline bool sanitize (hb_sanitize_context_t *c) {
723 TRACE_SANITIZE (); 723 TRACE_SANITIZE ();
724 if (!(c->check_struct (this) 724 if (!(c->check_struct (this)
725 && coverage.sanitize (c, this) 725 && coverage.sanitize (c, this)
726 && classDef1.sanitize (c, this) 726 && classDef1.sanitize (c, this)
727 && classDef2.sanitize (c, this))) return false; 727 && classDef2.sanitize (c, this))) return false;
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
829 829
830 private: 830 private:
831 inline bool apply (hb_apply_context_t *c) const 831 inline bool apply (hb_apply_context_t *c) const
832 { 832 {
833 TRACE_APPLY (); 833 TRACE_APPLY ();
834 834
835 /* We don't handle mark glyphs here. */ 835 /* We don't handle mark glyphs here. */
836 if (c->property & HB_OT_LAYOUT_GLYPH_CLASS_MARK) 836 if (c->property & HB_OT_LAYOUT_GLYPH_CLASS_MARK)
837 return false; 837 return false;
838 838
839 unsigned int end = MIN (c->buffer->len, c->buffer->i + c->context_length); 839 hb_apply_context_t::mark_skipping_forward_iterator_t skippy_iter (c, c->buff er->idx, 1);
840 if (unlikely (c->buffer->i + 2 > end)) 840 if (skippy_iter.has_no_chance ())
841 return false; 841 return false;
842 842
843 const EntryExitRecord &this_record = entryExitRecord[(this+coverage) (c->buf fer->info[c->buffer->i].codepoint)]; 843 const EntryExitRecord &this_record = entryExitRecord[(this+coverage) (c->buf fer->info[c->buffer->idx].codepoint)];
844 if (!this_record.exitAnchor) 844 if (!this_record.exitAnchor)
845 return false; 845 return false;
846 846
847 unsigned int j = c->buffer->i + 1; 847 if (!skippy_iter.next ())
848 while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->info[j], c->loo kup_props, NULL)) 848 return false;
849 {
850 if (unlikely (j == end))
851 » return false;
852 j++;
853 }
854 849
855 const EntryExitRecord &next_record = entryExitRecord[(this+coverage) (c->buf fer->info[j].codepoint)]; 850 const EntryExitRecord &next_record = entryExitRecord[(this+coverage) (c->buf fer->info[skippy_iter.idx].codepoint)];
856 if (!next_record.entryAnchor) 851 if (!next_record.entryAnchor)
857 return false; 852 return false;
858 853
859 unsigned int i = c->buffer->i; 854 unsigned int i = c->buffer->idx;
855 unsigned int j = skippy_iter.idx;
860 856
861 hb_position_t entry_x, entry_y, exit_x, exit_y; 857 hb_position_t entry_x, entry_y, exit_x, exit_y;
862 (this+this_record.exitAnchor).get_anchor (c->layout, c->buffer->info[i].code point, &exit_x, &exit_y); 858 (this+this_record.exitAnchor).get_anchor (c->font, c->buffer->info[i].codepo int, &exit_x, &exit_y);
863 (this+next_record.entryAnchor).get_anchor (c->layout, c->buffer->info[j].cod epoint, &entry_x, &entry_y); 859 (this+next_record.entryAnchor).get_anchor (c->font, c->buffer->info[j].codep oint, &entry_x, &entry_y);
864 860
865 hb_direction_t direction = c->buffer->props.direction; 861 hb_glyph_position_t *pos = c->buffer->pos;
866 862
867 /* Align the exit anchor of the left/top glyph with the entry anchor of the right/bottom glyph 863 hb_position_t d;
868 * by adjusting advance of the left/top glyph. */ 864 /* Main-direction adjustment */
869 if (HB_DIRECTION_IS_BACKWARD (direction)) 865 switch (c->direction) {
870 { 866 case HB_DIRECTION_LTR:
871 if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) 867 » pos[i].x_advance = exit_x + pos[i].x_offset;
872 » c->buffer->pos[j].x_advance = c->buffer->pos[j].x_offset + entry_x - exi t_x; 868
873 else 869 » d = entry_x + pos[j].x_offset;
874 » c->buffer->pos[j].y_advance = c->buffer->pos[j].y_offset + entry_y - exi t_y; 870 » pos[j].x_advance -= d;
875 } 871 » pos[j].x_offset -= d;
876 else 872 » break;
877 { 873 case HB_DIRECTION_RTL:
878 if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) 874 » d = exit_x + pos[i].x_offset;
879 » c->buffer->pos[i].x_advance = c->buffer->pos[i].x_offset + exit_x - entr y_x; 875 » pos[i].x_advance -= d;
880 else 876 » pos[i].x_offset -= d;
881 » c->buffer->pos[i].y_advance = c->buffer->pos[i].y_offset + exit_y - entr y_y; 877
878 » pos[j].x_advance = entry_x + pos[j].x_offset;
879 » break;
880 case HB_DIRECTION_TTB:
881 » pos[i].y_advance = exit_y + pos[i].y_offset;
882
883 » d = entry_y + pos[j].y_offset;
884 » pos[j].y_advance -= d;
885 » pos[j].y_offset -= d;
886 » break;
887 case HB_DIRECTION_BTT:
888 » d = exit_y + pos[i].y_offset;
889 » pos[i].y_advance -= d;
890 » pos[i].y_offset -= d;
891
892 » pos[j].y_advance = entry_y;
893 » break;
894 case HB_DIRECTION_INVALID:
895 default:
896 » break;
882 } 897 }
883 898
884 if (c->lookup_props & LookupFlag::RightToLeft) 899 /* Cross-direction adjustment */
885 { 900 if (c->lookup_props & LookupFlag::RightToLeft) {
886 c->buffer->pos[i].cursive_chain() = j - i; 901 pos[i].cursive_chain() = j - i;
887 if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) 902 if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction)))
888 » c->buffer->pos[i].y_offset = entry_y - exit_y; 903 » pos[i].y_offset = entry_y - exit_y;
889 else 904 else
890 » c->buffer->pos[i].x_offset = entry_x - exit_x; 905 » pos[i].x_offset = entry_x - exit_x;
891 } 906 } else {
892 else 907 pos[j].cursive_chain() = i - j;
893 { 908 if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction)))
894 c->buffer->pos[j].cursive_chain() = i - j; 909 » pos[j].y_offset = exit_y - entry_y;
895 if (likely (HB_DIRECTION_IS_HORIZONTAL (direction)))
896 » c->buffer->pos[j].y_offset = exit_y - entry_y;
897 else 910 else
898 » c->buffer->pos[j].x_offset = exit_x - entry_x; 911 » pos[j].x_offset = exit_x - entry_x;
899 } 912 }
900 913
901 c->buffer->i = j; 914 c->buffer->idx = j;
902 return true; 915 return true;
903 } 916 }
904 917
905 inline bool sanitize (hb_sanitize_context_t *c) { 918 inline bool sanitize (hb_sanitize_context_t *c) {
906 TRACE_SANITIZE (); 919 TRACE_SANITIZE ();
907 return coverage.sanitize (c, this) 920 return coverage.sanitize (c, this)
908 && entryExitRecord.sanitize (c, this); 921 && entryExitRecord.sanitize (c, this);
909 } 922 }
910 923
911 private: 924 private:
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
957 * ordered by class--zero-based. */ 970 * ordered by class--zero-based. */
958 971
959 struct MarkBasePosFormat1 972 struct MarkBasePosFormat1
960 { 973 {
961 friend struct MarkBasePos; 974 friend struct MarkBasePos;
962 975
963 private: 976 private:
964 inline bool apply (hb_apply_context_t *c) const 977 inline bool apply (hb_apply_context_t *c) const
965 { 978 {
966 TRACE_APPLY (); 979 TRACE_APPLY ();
967 unsigned int mark_index = (this+markCoverage) (c->buffer->info[c->buffer->i] .codepoint); 980 unsigned int mark_index = (this+markCoverage) (c->buffer->info[c->buffer->id x].codepoint);
968 if (likely (mark_index == NOT_COVERED)) 981 if (likely (mark_index == NOT_COVERED))
969 return false; 982 return false;
970 983
971 /* now we search backwards for a non-mark glyph */ 984 /* now we search backwards for a non-mark glyph */
972 unsigned int property; 985 unsigned int property;
973 unsigned int j = c->buffer->i; 986 hb_apply_context_t::mark_skipping_backward_iterator_t skippy_iter (c, c->buf fer->idx, 1);
974 do 987 if (!skippy_iter.prev (&property, LookupFlag::IgnoreMarks))
975 { 988 return false;
976 if (unlikely (!j))
977 » return false;
978 j--;
979 } while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->info[j], Look upFlag::IgnoreMarks, &property));
980 989
981 /* The following assertion is too strong, so we've disabled it. */ 990 /* The following assertion is too strong, so we've disabled it. */
982 if (!(property & HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH)) 991 if (!(property & HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH))
983 {/*return false;*/} 992 {/*return false;*/}
984 993
985 unsigned int base_index = (this+baseCoverage) (c->buffer->info[j].codepoint) ; 994 unsigned int base_index = (this+baseCoverage) (c->buffer->info[skippy_iter.i dx].codepoint);
986 if (base_index == NOT_COVERED) 995 if (base_index == NOT_COVERED)
987 return false; 996 return false;
988 997
989 return (this+markArray).apply (c, mark_index, base_index, this+baseArray, cl assCount, j); 998 return (this+markArray).apply (c, mark_index, base_index, this+baseArray, cl assCount, skippy_iter.idx);
990 } 999 }
991 1000
992 inline bool sanitize (hb_sanitize_context_t *c) { 1001 inline bool sanitize (hb_sanitize_context_t *c) {
993 TRACE_SANITIZE (); 1002 TRACE_SANITIZE ();
994 return c->check_struct (this) 1003 return c->check_struct (this)
995 && markCoverage.sanitize (c, this) 1004 && markCoverage.sanitize (c, this)
996 && baseCoverage.sanitize (c, this) 1005 && baseCoverage.sanitize (c, this)
997 && markArray.sanitize (c, this) 1006 && markArray.sanitize (c, this)
998 && baseArray.sanitize (c, this, (unsigned int) classCount); 1007 && baseArray.sanitize (c, this, (unsigned int) classCount);
999 } 1008 }
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1059 * LigatureCoverage Index */ 1068 * LigatureCoverage Index */
1060 1069
1061 struct MarkLigPosFormat1 1070 struct MarkLigPosFormat1
1062 { 1071 {
1063 friend struct MarkLigPos; 1072 friend struct MarkLigPos;
1064 1073
1065 private: 1074 private:
1066 inline bool apply (hb_apply_context_t *c) const 1075 inline bool apply (hb_apply_context_t *c) const
1067 { 1076 {
1068 TRACE_APPLY (); 1077 TRACE_APPLY ();
1069 unsigned int mark_index = (this+markCoverage) (c->buffer->info[c->buffer->i] .codepoint); 1078 unsigned int mark_index = (this+markCoverage) (c->buffer->info[c->buffer->id x].codepoint);
1070 if (likely (mark_index == NOT_COVERED)) 1079 if (likely (mark_index == NOT_COVERED))
1071 return false; 1080 return false;
1072 1081
1073 /* now we search backwards for a non-mark glyph */ 1082 /* now we search backwards for a non-mark glyph */
1074 unsigned int property; 1083 unsigned int property;
1075 unsigned int j = c->buffer->i; 1084 hb_apply_context_t::mark_skipping_backward_iterator_t skippy_iter (c, c->buf fer->idx, 1);
1076 do 1085 if (!skippy_iter.prev (&property, LookupFlag::IgnoreMarks))
1077 { 1086 return false;
1078 if (unlikely (!j))
1079 » return false;
1080 j--;
1081 } while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->info[j], Look upFlag::IgnoreMarks, &property));
1082 1087
1083 /* The following assertion is too strong, so we've disabled it. */ 1088 /* The following assertion is too strong, so we've disabled it. */
1084 if (!(property & HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE)) 1089 if (!(property & HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE))
1085 {/*return false;*/} 1090 {/*return false;*/}
1086 1091
1092 unsigned int j = skippy_iter.idx;
1087 unsigned int lig_index = (this+ligatureCoverage) (c->buffer->info[j].codepoi nt); 1093 unsigned int lig_index = (this+ligatureCoverage) (c->buffer->info[j].codepoi nt);
1088 if (lig_index == NOT_COVERED) 1094 if (lig_index == NOT_COVERED)
1089 return false; 1095 return false;
1090 1096
1091 const LigatureArray& lig_array = this+ligatureArray; 1097 const LigatureArray& lig_array = this+ligatureArray;
1092 const LigatureAttach& lig_attach = lig_array[lig_index]; 1098 const LigatureAttach& lig_attach = lig_array[lig_index];
1093 1099
1094 /* Find component to attach to */ 1100 /* Find component to attach to */
1095 unsigned int comp_count = lig_attach.rows; 1101 unsigned int comp_count = lig_attach.rows;
1096 if (unlikely (!comp_count)) 1102 if (unlikely (!comp_count))
1097 return false; 1103 return false;
1098 unsigned int comp_index; 1104 unsigned int comp_index;
1099 /* We must now check whether the ligature ID of the current mark glyph 1105 /* We must now check whether the ligature ID of the current mark glyph
1100 * is identical to the ligature ID of the found ligature. If yes, we 1106 * is identical to the ligature ID of the found ligature. If yes, we
1101 * can directly use the component index. If not, we attach the mark 1107 * can directly use the component index. If not, we attach the mark
1102 * glyph to the last component of the ligature. */ 1108 * glyph to the last component of the ligature. */
1103 if (c->buffer->info[j].lig_id() && c->buffer->info[j].lig_id() == c->buffer- >info[c->buffer->i].lig_id() && c->buffer->info[c->buffer->i].lig_comp()) 1109 if (c->buffer->info[j].lig_id() && c->buffer->info[j].lig_id() == c->buffer- >info[c->buffer->idx].lig_id() && c->buffer->info[c->buffer->idx].lig_comp())
1104 { 1110 {
1105 comp_index = c->buffer->info[c->buffer->i].lig_comp() - 1; 1111 comp_index = c->buffer->info[c->buffer->idx].lig_comp() - 1;
1106 if (comp_index >= comp_count) 1112 if (comp_index >= comp_count)
1107 comp_index = comp_count - 1; 1113 comp_index = comp_count - 1;
1108 } 1114 }
1109 else 1115 else
1110 comp_index = comp_count - 1; 1116 comp_index = comp_count - 1;
1111 1117
1112 return (this+markArray).apply (c, mark_index, comp_index, lig_attach, classC ount, j); 1118 return (this+markArray).apply (c, mark_index, comp_index, lig_attach, classC ount, j);
1113 } 1119 }
1114 1120
1115 inline bool sanitize (hb_sanitize_context_t *c) { 1121 inline bool sanitize (hb_sanitize_context_t *c) {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1178 * ordered by class--zero-based. */ 1184 * ordered by class--zero-based. */
1179 1185
1180 struct MarkMarkPosFormat1 1186 struct MarkMarkPosFormat1
1181 { 1187 {
1182 friend struct MarkMarkPos; 1188 friend struct MarkMarkPos;
1183 1189
1184 private: 1190 private:
1185 inline bool apply (hb_apply_context_t *c) const 1191 inline bool apply (hb_apply_context_t *c) const
1186 { 1192 {
1187 TRACE_APPLY (); 1193 TRACE_APPLY ();
1188 unsigned int mark1_index = (this+mark1Coverage) (c->buffer->info[c->buffer-> i].codepoint); 1194 unsigned int mark1_index = (this+mark1Coverage) (c->buffer->info[c->buffer-> idx].codepoint);
1189 if (likely (mark1_index == NOT_COVERED)) 1195 if (likely (mark1_index == NOT_COVERED))
1190 return false; 1196 return false;
1191 1197
1192 /* now we search backwards for a suitable mark glyph until a non-mark glyph */ 1198 /* now we search backwards for a suitable mark glyph until a non-mark glyph */
1193 unsigned int property; 1199 unsigned int property;
1194 unsigned int j = c->buffer->i; 1200 hb_apply_context_t::mark_skipping_backward_iterator_t skippy_iter (c, c->buf fer->idx, 1);
1195 do 1201 if (!skippy_iter.prev (&property))
1196 { 1202 return false;
1197 if (unlikely (!j))
1198 » return false;
1199 j--;
1200 } while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->info[j], c->l ookup_props, &property));
1201 1203
1202 if (!(property & HB_OT_LAYOUT_GLYPH_CLASS_MARK)) 1204 if (!(property & HB_OT_LAYOUT_GLYPH_CLASS_MARK))
1203 return false; 1205 return false;
1204 1206
1207 unsigned int j = skippy_iter.idx;
1208
1205 /* Two marks match only if they belong to the same base, or same component 1209 /* Two marks match only if they belong to the same base, or same component
1206 * of the same ligature. That is, the component numbers must match, and 1210 * of the same ligature. That is, the component numbers must match, and
1207 * if those are non-zero, the ligid number should also match. */ 1211 * if those are non-zero, the ligid number should also match. */
1208 if ((c->buffer->info[j].lig_comp() != c->buffer->info[c->buffer->i].lig_comp ()) || 1212 if ((c->buffer->info[j].lig_comp() != c->buffer->info[c->buffer->idx].lig_co mp()) ||
1209 » (c->buffer->info[j].lig_comp() && c->buffer->info[j].lig_id() != c->buff er->info[c->buffer->i].lig_id())) 1213 » (c->buffer->info[j].lig_comp() && c->buffer->info[j].lig_id() != c->buff er->info[c->buffer->idx].lig_id()))
1210 return false; 1214 return false;
1211 1215
1212 unsigned int mark2_index = (this+mark2Coverage) (c->buffer->info[j].codepoin t); 1216 unsigned int mark2_index = (this+mark2Coverage) (c->buffer->info[j].codepoin t);
1213 if (mark2_index == NOT_COVERED) 1217 if (mark2_index == NOT_COVERED)
1214 return false; 1218 return false;
1215 1219
1216 return (this+mark1Array).apply (c, mark1_index, mark2_index, this+mark2Array , classCount, j); 1220 return (this+mark1Array).apply (c, mark1_index, mark2_index, this+mark2Array , classCount, j);
1217 } 1221 }
1218 1222
1219 inline bool sanitize (hb_sanitize_context_t *c) { 1223 inline bool sanitize (hb_sanitize_context_t *c) {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1270 } 1274 }
1271 1275
1272 private: 1276 private:
1273 union { 1277 union {
1274 USHORT format; /* Format identifier */ 1278 USHORT format; /* Format identifier */
1275 MarkMarkPosFormat1 format1; 1279 MarkMarkPosFormat1 format1;
1276 } u; 1280 } u;
1277 }; 1281 };
1278 1282
1279 1283
1280 HB_BEGIN_DECLS
1281 static inline bool position_lookup (hb_apply_context_t *c, unsigned int lookup_i ndex); 1284 static inline bool position_lookup (hb_apply_context_t *c, unsigned int lookup_i ndex);
1282 HB_END_DECLS
1283 1285
1284 struct ContextPos : Context 1286 struct ContextPos : Context
1285 { 1287 {
1286 friend struct PosLookupSubTable; 1288 friend struct PosLookupSubTable;
1287 1289
1288 private: 1290 private:
1289 inline bool apply (hb_apply_context_t *c) const 1291 inline bool apply (hb_apply_context_t *c) const
1290 { 1292 {
1291 TRACE_APPLY (); 1293 TRACE_APPLY ();
1292 return Context::apply (c, position_lookup); 1294 return Context::apply (c, position_lookup);
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1395 public: 1397 public:
1396 DEFINE_SIZE_UNION (2, sub_format); 1398 DEFINE_SIZE_UNION (2, sub_format);
1397 }; 1399 };
1398 1400
1399 1401
1400 struct PosLookup : Lookup 1402 struct PosLookup : Lookup
1401 { 1403 {
1402 inline const PosLookupSubTable& get_subtable (unsigned int i) const 1404 inline const PosLookupSubTable& get_subtable (unsigned int i) const
1403 { return this+CastR<OffsetArrayOf<PosLookupSubTable> > (subTable)[i]; } 1405 { return this+CastR<OffsetArrayOf<PosLookupSubTable> > (subTable)[i]; }
1404 1406
1405 inline bool apply_once (hb_ot_layout_context_t *layout, 1407 inline bool apply_once (hb_font_t *font,
1406 hb_buffer_t *buffer, 1408 hb_buffer_t *buffer,
1407 hb_mask_t lookup_mask, 1409 hb_mask_t lookup_mask,
1408 unsigned int context_length, 1410 unsigned int context_length,
1409 unsigned int nesting_level_left) const 1411 unsigned int nesting_level_left) const
1410 { 1412 {
1411 unsigned int lookup_type = get_type (); 1413 unsigned int lookup_type = get_type ();
1412 hb_apply_context_t c[1] = {{0}}; 1414 hb_apply_context_t c[1] = {{0}};
1413 1415
1414 c->layout = layout; 1416 c->font = font;
1417 c->face = font->face;
1415 c->buffer = buffer; 1418 c->buffer = buffer;
1419 c->direction = buffer->props.direction;
1416 c->lookup_mask = lookup_mask; 1420 c->lookup_mask = lookup_mask;
1417 c->context_length = context_length; 1421 c->context_length = context_length;
1418 c->nesting_level_left = nesting_level_left; 1422 c->nesting_level_left = nesting_level_left;
1419 c->lookup_props = get_props (); 1423 c->lookup_props = get_props ();
1420 1424
1421 if (!_hb_ot_layout_check_glyph_property (c->layout->face, &c->buffer->info[c ->buffer->i], c->lookup_props, &c->property)) 1425 if (!_hb_ot_layout_check_glyph_property (c->face, &c->buffer->info[c->buffer ->idx], c->lookup_props, &c->property))
1422 return false; 1426 return false;
1423 1427
1424 for (unsigned int i = 0; i < get_subtable_count (); i++) 1428 for (unsigned int i = 0; i < get_subtable_count (); i++)
1425 if (get_subtable (i).apply (c, lookup_type)) 1429 if (get_subtable (i).apply (c, lookup_type))
1426 return true; 1430 return true;
1427 1431
1428 return false; 1432 return false;
1429 } 1433 }
1430 1434
1431 inline bool apply_string (hb_ot_layout_context_t *layout, 1435 inline bool apply_string (hb_font_t *font,
1432 hb_buffer_t *buffer, 1436 hb_buffer_t *buffer,
1433 hb_mask_t mask) const 1437 hb_mask_t mask) const
1434 { 1438 {
1435 bool ret = false; 1439 bool ret = false;
1436 1440
1437 if (unlikely (!buffer->len)) 1441 if (unlikely (!buffer->len))
1438 return false; 1442 return false;
1439 1443
1440 buffer->i = 0; 1444 buffer->idx = 0;
1441 while (buffer->i < buffer->len) 1445 while (buffer->idx < buffer->len)
1442 { 1446 {
1443 if ((buffer->info[buffer->i].mask & mask) && 1447 if ((buffer->info[buffer->idx].mask & mask) &&
1444 » apply_once (layout, buffer, mask, NO_CONTEXT, MAX_NESTING_LEVEL)) 1448 » apply_once (font, buffer, mask, NO_CONTEXT, MAX_NESTING_LEVEL))
1445 ret = true; 1449 ret = true;
1446 else 1450 else
1447 » buffer->i++; 1451 » buffer->idx++;
1448 } 1452 }
1449 1453
1450 return ret; 1454 return ret;
1451 } 1455 }
1452 1456
1453 inline bool sanitize (hb_sanitize_context_t *c) { 1457 inline bool sanitize (hb_sanitize_context_t *c) {
1454 TRACE_SANITIZE (); 1458 TRACE_SANITIZE ();
1455 if (unlikely (!Lookup::sanitize (c))) return false; 1459 if (unlikely (!Lookup::sanitize (c))) return false;
1456 OffsetArrayOf<PosLookupSubTable> &list = CastR<OffsetArrayOf<PosLookupSubTab le> > (subTable); 1460 OffsetArrayOf<PosLookupSubTable> &list = CastR<OffsetArrayOf<PosLookupSubTab le> > (subTable);
1457 return list.sanitize (c, this, get_type ()); 1461 return list.sanitize (c, this, get_type ());
1458 } 1462 }
1459 }; 1463 };
1460 1464
1461 typedef OffsetListOf<PosLookup> PosLookupList; 1465 typedef OffsetListOf<PosLookup> PosLookupList;
1462 1466
1463 /* 1467 /*
1464 * GPOS 1468 * GPOS -- The Glyph Positioning Table
1465 */ 1469 */
1466 1470
1467 struct GPOS : GSUBGPOS 1471 struct GPOS : GSUBGPOS
1468 { 1472 {
1469 static const hb_tag_t Tag = HB_OT_TAG_GPOS; 1473 static const hb_tag_t Tag = HB_OT_TAG_GPOS;
1470 1474
1471 inline const PosLookup& get_lookup (unsigned int i) const 1475 inline const PosLookup& get_lookup (unsigned int i) const
1472 { return CastR<PosLookup> (GSUBGPOS::get_lookup (i)); } 1476 { return CastR<PosLookup> (GSUBGPOS::get_lookup (i)); }
1473 1477
1474 inline bool position_lookup (hb_ot_layout_context_t *layout, 1478 inline bool position_lookup (hb_font_t *font,
1475 hb_buffer_t *buffer, 1479 hb_buffer_t *buffer,
1476 unsigned int lookup_index, 1480 unsigned int lookup_index,
1477 hb_mask_t mask) const 1481 hb_mask_t mask) const
1478 { return get_lookup (lookup_index).apply_string (layout, buffer, mask); } 1482 { return get_lookup (lookup_index).apply_string (font, buffer, mask); }
1479 1483
1484 static inline void position_start (hb_buffer_t *buffer);
1480 static inline void position_finish (hb_buffer_t *buffer); 1485 static inline void position_finish (hb_buffer_t *buffer);
1481 1486
1482 inline bool sanitize (hb_sanitize_context_t *c) { 1487 inline bool sanitize (hb_sanitize_context_t *c) {
1483 TRACE_SANITIZE (); 1488 TRACE_SANITIZE ();
1484 if (unlikely (!GSUBGPOS::sanitize (c))) return false; 1489 if (unlikely (!GSUBGPOS::sanitize (c))) return false;
1485 OffsetTo<PosLookupList> &list = CastR<OffsetTo<PosLookupList> > (lookupList) ; 1490 OffsetTo<PosLookupList> &list = CastR<OffsetTo<PosLookupList> > (lookupList) ;
1486 return list.sanitize (c, this); 1491 return list.sanitize (c, this);
1487 } 1492 }
1488 public: 1493 public:
1489 DEFINE_SIZE_STATIC (10); 1494 DEFINE_SIZE_STATIC (10);
1490 }; 1495 };
1491 1496
1497
1498 static void
1499 fix_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direction _t direction)
1500 {
1501 unsigned int j = pos[i].cursive_chain();
1502 if (likely (!j))
1503 return;
1504
1505 j += i;
1506
1507 pos[i].cursive_chain() = 0;
1508
1509 fix_cursive_minor_offset (pos, j, direction);
1510
1511 if (HB_DIRECTION_IS_HORIZONTAL (direction))
1512 pos[i].y_offset += pos[j].y_offset;
1513 else
1514 pos[i].x_offset += pos[j].x_offset;
1515 }
1516
1517 static void
1518 fix_mark_attachment (hb_glyph_position_t *pos, unsigned int i, hb_direction_t di rection)
1519 {
1520 if (likely (!(pos[i].attach_lookback())))
1521 return;
1522
1523 unsigned int j = i - pos[i].attach_lookback();
1524
1525 pos[i].x_advance = 0;
1526 pos[i].y_advance = 0;
1527 pos[i].x_offset += pos[j].x_offset;
1528 pos[i].y_offset += pos[j].y_offset;
1529
1530 if (HB_DIRECTION_IS_FORWARD (direction))
1531 for (unsigned int k = j; k < i; k++) {
1532 pos[i].x_offset -= pos[k].x_advance;
1533 pos[i].y_offset -= pos[k].y_advance;
1534 }
1535 else
1536 for (unsigned int k = j + 1; k < i + 1; k++) {
1537 pos[i].x_offset += pos[k].x_advance;
1538 pos[i].y_offset += pos[k].y_advance;
1539 }
1540 }
1541
1542 void
1543 GPOS::position_start (hb_buffer_t *buffer)
1544 {
1545 buffer->clear_positions ();
1546
1547 unsigned int count = buffer->len;
1548 for (unsigned int i = 0; i < count; i++)
1549 buffer->pos[i].attach_lookback() = buffer->pos[i].cursive_chain() = 0;
1550 }
1551
1492 void 1552 void
1493 GPOS::position_finish (hb_buffer_t *buffer) 1553 GPOS::position_finish (hb_buffer_t *buffer)
1494 { 1554 {
1495 unsigned int i, j; 1555 unsigned int len;
1496 unsigned int len = hb_buffer_get_length (buffer); 1556 hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, &len);
1497 hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer);
1498 hb_direction_t direction = buffer->props.direction; 1557 hb_direction_t direction = buffer->props.direction;
1499 1558
1500 /* Handle cursive connections: 1559 /* Handle cursive connections */
1501 * First handle all chain-back connections, then handle all chain-forward conn ections. */ 1560 for (unsigned int i = 0; i < len; i++)
1502 if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) 1561 fix_cursive_minor_offset (pos, i, direction);
1503 {
1504 for (j = 0; j < len; j++) {
1505 if (pos[j].cursive_chain() < 0)
1506 » pos[j].y_offset += pos[j + pos[j].cursive_chain()].y_offset;
1507 }
1508 for (i = len; i > 0; i--) {
1509 j = i - 1;
1510 if (pos[j].cursive_chain() > 0)
1511 » pos[j].y_offset += pos[j + pos[j].cursive_chain()].y_offset;
1512 }
1513 }
1514 else
1515 {
1516 for (j = 0; j < len; j++) {
1517 if (pos[j].cursive_chain() < 0)
1518 » pos[j].x_offset += pos[j + pos[j].cursive_chain()].x_offset;
1519 }
1520 for (i = len; i > 0; i--) {
1521 j = i - 1;
1522 if (pos[j].cursive_chain() > 0)
1523 » pos[j].x_offset += pos[j + pos[j].cursive_chain()].x_offset;
1524 }
1525 }
1526
1527 1562
1528 /* Handle attachments */ 1563 /* Handle attachments */
1529 for (i = 0; i < len; i++) 1564 for (unsigned int i = 0; i < len; i++)
1530 if (pos[i].attach_lookback()) 1565 fix_mark_attachment (pos, i, direction);
1531 {
1532 unsigned int back = i - pos[i].attach_lookback();
1533 pos[i].x_offset += pos[back].x_offset;
1534 pos[i].y_offset += pos[back].y_offset;
1535 1566
1536 if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction)) 1567 HB_BUFFER_DEALLOCATE_VAR (buffer, lig_comp);
1537 » for (j = back + 1; j < i + 1; j++) { 1568 HB_BUFFER_DEALLOCATE_VAR (buffer, lig_id);
1538 » pos[i].x_offset += pos[j].x_advance; 1569 HB_BUFFER_DEALLOCATE_VAR (buffer, props_cache);
1539 » pos[i].y_offset += pos[j].y_advance;
1540 » }
1541 else
1542 » for (j = back; j < i; j++) {
1543 » pos[i].x_offset -= pos[j].x_advance;
1544 » pos[i].y_offset -= pos[j].y_advance;
1545 » }
1546 }
1547 } 1570 }
1548 1571
1549 1572
1550 /* Out-of-class implementation for methods recursing */ 1573 /* Out-of-class implementation for methods recursing */
1551 1574
1552 inline bool ExtensionPos::apply (hb_apply_context_t *c) const 1575 inline bool ExtensionPos::apply (hb_apply_context_t *c) const
1553 { 1576 {
1554 TRACE_APPLY (); 1577 TRACE_APPLY ();
1555 return get_subtable ().apply (c, get_type ()); 1578 return get_subtable ().apply (c, get_type ());
1556 } 1579 }
1557 1580
1558 inline bool ExtensionPos::sanitize (hb_sanitize_context_t *c) 1581 inline bool ExtensionPos::sanitize (hb_sanitize_context_t *c)
1559 { 1582 {
1560 TRACE_SANITIZE (); 1583 TRACE_SANITIZE ();
1561 if (unlikely (!Extension::sanitize (c))) return false; 1584 if (unlikely (!Extension::sanitize (c))) return false;
1562 unsigned int offset = get_offset (); 1585 unsigned int offset = get_offset ();
1563 if (unlikely (!offset)) return true; 1586 if (unlikely (!offset)) return true;
1564 return StructAtOffset<PosLookupSubTable> (this, offset).sanitize (c, get_type ()); 1587 return StructAtOffset<PosLookupSubTable> (this, offset).sanitize (c, get_type ());
1565 } 1588 }
1566 1589
1567 static inline bool position_lookup (hb_apply_context_t *c, unsigned int lookup_i ndex) 1590 static inline bool position_lookup (hb_apply_context_t *c, unsigned int lookup_i ndex)
1568 { 1591 {
1569 const GPOS &gpos = *(c->layout->face->ot_layout->gpos); 1592 const GPOS &gpos = *(c->face->ot_layout->gpos);
1570 const PosLookup &l = gpos.get_lookup (lookup_index); 1593 const PosLookup &l = gpos.get_lookup (lookup_index);
1571 1594
1572 if (unlikely (c->nesting_level_left == 0)) 1595 if (unlikely (c->nesting_level_left == 0))
1573 return false; 1596 return false;
1574 1597
1575 if (unlikely (c->context_length < 1)) 1598 if (unlikely (c->context_length < 1))
1576 return false; 1599 return false;
1577 1600
1578 return l.apply_once (c->layout, c->buffer, c->lookup_mask, c->context_length, c->nesting_level_left - 1); 1601 return l.apply_once (c->font, c->buffer, c->lookup_mask, c->context_length, c- >nesting_level_left - 1);
1579 } 1602 }
1580 1603
1581 1604
1582 #undef attach_lookback 1605 #undef attach_lookback
1583 #undef cursive_chain 1606 #undef cursive_chain
1584 1607
1585 1608
1586 HB_END_DECLS
1587 1609
1588 #endif /* HB_OT_LAYOUT_GPOS_PRIVATE_HH */ 1610 #endif /* HB_OT_LAYOUT_GPOS_TABLE_HH */
OLDNEW
« no previous file with comments | « third_party/harfbuzz-ng/src/hb-ot-layout-gpos-private.hh ('k') | third_party/harfbuzz-ng/src/hb-ot-layout-gsub-private.hh » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698