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

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

Issue 1408003004: Roll harfbuzz-ng to 1.0.5 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@2526
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright © 2007,2008,2009,2010 Red Hat, Inc. 2 * Copyright © 2007,2008,2009,2010 Red Hat, Inc.
3 * Copyright © 2010,2012,2013 Google, Inc. 3 * Copyright © 2010,2012,2013 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 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 public: 174 public:
175 175
176 inline bool has_device (void) const { 176 inline bool has_device (void) const {
177 unsigned int format = *this; 177 unsigned int format = *this;
178 return (format & devices) != 0; 178 return (format & devices) != 0;
179 } 179 }
180 180
181 inline bool sanitize_value (hb_sanitize_context_t *c, const void *base, const Value *values) const 181 inline bool sanitize_value (hb_sanitize_context_t *c, const void *base, const Value *values) const
182 { 182 {
183 TRACE_SANITIZE (this); 183 TRACE_SANITIZE (this);
184 return TRACE_RETURN (c->check_range (values, get_size ()) && (!has_device () || sanitize_value_devices (c, base, values))); 184 return_trace (c->check_range (values, get_size ()) && (!has_device () || san itize_value_devices (c, base, values)));
185 } 185 }
186 186
187 inline bool sanitize_values (hb_sanitize_context_t *c, const void *base, const Value *values, unsigned int count) const 187 inline bool sanitize_values (hb_sanitize_context_t *c, const void *base, const Value *values, unsigned int count) const
188 { 188 {
189 TRACE_SANITIZE (this); 189 TRACE_SANITIZE (this);
190 unsigned int len = get_len (); 190 unsigned int len = get_len ();
191 191
192 if (!c->check_array (values, get_size (), count)) return TRACE_RETURN (false ); 192 if (!c->check_array (values, get_size (), count)) return_trace (false);
193 193
194 if (!has_device ()) return TRACE_RETURN (true); 194 if (!has_device ()) return_trace (true);
195 195
196 for (unsigned int i = 0; i < count; i++) { 196 for (unsigned int i = 0; i < count; i++) {
197 if (!sanitize_value_devices (c, base, values)) 197 if (!sanitize_value_devices (c, base, values))
198 return TRACE_RETURN (false); 198 return_trace (false);
199 values += len; 199 values += len;
200 } 200 }
201 201
202 return TRACE_RETURN (true); 202 return_trace (true);
203 } 203 }
204 204
205 /* Just sanitize referenced Device tables. Doesn't check the values themselve s. */ 205 /* Just sanitize referenced Device tables. Doesn't check the values themselve s. */
206 inline bool sanitize_values_stride_unsafe (hb_sanitize_context_t *c, const voi d *base, const Value *values, unsigned int count, unsigned int stride) const 206 inline bool sanitize_values_stride_unsafe (hb_sanitize_context_t *c, const voi d *base, const Value *values, unsigned int count, unsigned int stride) const
207 { 207 {
208 TRACE_SANITIZE (this); 208 TRACE_SANITIZE (this);
209 209
210 if (!has_device ()) return TRACE_RETURN (true); 210 if (!has_device ()) return_trace (true);
211 211
212 for (unsigned int i = 0; i < count; i++) { 212 for (unsigned int i = 0; i < count; i++) {
213 if (!sanitize_value_devices (c, base, values)) 213 if (!sanitize_value_devices (c, base, values))
214 return TRACE_RETURN (false); 214 return_trace (false);
215 values += stride; 215 values += stride;
216 } 216 }
217 217
218 return TRACE_RETURN (true); 218 return_trace (true);
219 } 219 }
220 }; 220 };
221 221
222 222
223 struct AnchorFormat1 223 struct AnchorFormat1
224 { 224 {
225 inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id HB_UNUSED, 225 inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id HB_UNUSED,
226 hb_position_t *x, hb_position_t *y) const 226 hb_position_t *x, hb_position_t *y) const
227 { 227 {
228 *x = font->em_scale_x (xCoordinate); 228 *x = font->em_scale_x (xCoordinate);
229 *y = font->em_scale_y (yCoordinate); 229 *y = font->em_scale_y (yCoordinate);
230 } 230 }
231 231
232 inline bool sanitize (hb_sanitize_context_t *c) const 232 inline bool sanitize (hb_sanitize_context_t *c) const
233 { 233 {
234 TRACE_SANITIZE (this); 234 TRACE_SANITIZE (this);
235 return TRACE_RETURN (c->check_struct (this)); 235 return_trace (c->check_struct (this));
236 } 236 }
237 237
238 protected: 238 protected:
239 USHORT format; /* Format identifier--format = 1 */ 239 USHORT format; /* Format identifier--format = 1 */
240 SHORT xCoordinate; /* Horizontal value--in design units */ 240 SHORT xCoordinate; /* Horizontal value--in design units */
241 SHORT yCoordinate; /* Vertical value--in design units */ 241 SHORT yCoordinate; /* Vertical value--in design units */
242 public: 242 public:
243 DEFINE_SIZE_STATIC (6); 243 DEFINE_SIZE_STATIC (6);
244 }; 244 };
245 245
246 struct AnchorFormat2 246 struct AnchorFormat2
247 { 247 {
248 inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id, 248 inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id,
249 hb_position_t *x, hb_position_t *y) const 249 hb_position_t *x, hb_position_t *y) const
250 { 250 {
251 unsigned int x_ppem = font->x_ppem; 251 unsigned int x_ppem = font->x_ppem;
252 unsigned int y_ppem = font->y_ppem; 252 unsigned int y_ppem = font->y_ppem;
253 hb_position_t cx, cy; 253 hb_position_t cx, cy;
254 hb_bool_t ret; 254 hb_bool_t ret;
255 255
256 ret = (x_ppem || y_ppem) && 256 ret = (x_ppem || y_ppem) &&
257 font->get_glyph_contour_point_for_origin (glyph_id, anchorPoint, HB _DIRECTION_LTR, &cx, &cy); 257 font->get_glyph_contour_point_for_origin (glyph_id, anchorPoint, HB _DIRECTION_LTR, &cx, &cy);
258 *x = ret && x_ppem ? cx : font->em_scale_x (xCoordinate); 258 *x = ret && x_ppem ? cx : font->em_scale_x (xCoordinate);
259 *y = ret && y_ppem ? cy : font->em_scale_y (yCoordinate); 259 *y = ret && y_ppem ? cy : font->em_scale_y (yCoordinate);
260 } 260 }
261 261
262 inline bool sanitize (hb_sanitize_context_t *c) const 262 inline bool sanitize (hb_sanitize_context_t *c) const
263 { 263 {
264 TRACE_SANITIZE (this); 264 TRACE_SANITIZE (this);
265 return TRACE_RETURN (c->check_struct (this)); 265 return_trace (c->check_struct (this));
266 } 266 }
267 267
268 protected: 268 protected:
269 USHORT format; /* Format identifier--format = 2 */ 269 USHORT format; /* Format identifier--format = 2 */
270 SHORT xCoordinate; /* Horizontal value--in design units */ 270 SHORT xCoordinate; /* Horizontal value--in design units */
271 SHORT yCoordinate; /* Vertical value--in design units */ 271 SHORT yCoordinate; /* Vertical value--in design units */
272 USHORT anchorPoint; /* Index to glyph contour point */ 272 USHORT anchorPoint; /* Index to glyph contour point */
273 public: 273 public:
274 DEFINE_SIZE_STATIC (8); 274 DEFINE_SIZE_STATIC (8);
275 }; 275 };
276 276
277 struct AnchorFormat3 277 struct AnchorFormat3
278 { 278 {
279 inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id HB_UNUSED, 279 inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id HB_UNUSED,
280 hb_position_t *x, hb_position_t *y) const 280 hb_position_t *x, hb_position_t *y) const
281 { 281 {
282 *x = font->em_scale_x (xCoordinate); 282 *x = font->em_scale_x (xCoordinate);
283 *y = font->em_scale_y (yCoordinate); 283 *y = font->em_scale_y (yCoordinate);
284 284
285 if (font->x_ppem) 285 if (font->x_ppem)
286 *x += (this+xDeviceTable).get_x_delta (font); 286 *x += (this+xDeviceTable).get_x_delta (font);
287 if (font->y_ppem) 287 if (font->y_ppem)
288 *y += (this+yDeviceTable).get_x_delta (font); 288 *y += (this+yDeviceTable).get_x_delta (font);
289 } 289 }
290 290
291 inline bool sanitize (hb_sanitize_context_t *c) const 291 inline bool sanitize (hb_sanitize_context_t *c) const
292 { 292 {
293 TRACE_SANITIZE (this); 293 TRACE_SANITIZE (this);
294 return TRACE_RETURN (c->check_struct (this) && xDeviceTable.sanitize (c, thi s) && yDeviceTable.sanitize (c, this)); 294 return_trace (c->check_struct (this) && xDeviceTable.sanitize (c, this) && y DeviceTable.sanitize (c, this));
295 } 295 }
296 296
297 protected: 297 protected:
298 USHORT format; /* Format identifier--format = 3 */ 298 USHORT format; /* Format identifier--format = 3 */
299 SHORT xCoordinate; /* Horizontal value--in design units */ 299 SHORT xCoordinate; /* Horizontal value--in design units */
300 SHORT yCoordinate; /* Vertical value--in design units */ 300 SHORT yCoordinate; /* Vertical value--in design units */
301 OffsetTo<Device> 301 OffsetTo<Device>
302 xDeviceTable; /* Offset to Device table for X 302 xDeviceTable; /* Offset to Device table for X
303 * coordinate-- from beginning of 303 * coordinate-- from beginning of
304 * Anchor table (may be NULL) */ 304 * Anchor table (may be NULL) */
(...skipping 15 matching lines...) Expand all
320 case 1: u.format1.get_anchor (font, glyph_id, x, y); return; 320 case 1: u.format1.get_anchor (font, glyph_id, x, y); return;
321 case 2: u.format2.get_anchor (font, glyph_id, x, y); return; 321 case 2: u.format2.get_anchor (font, glyph_id, x, y); return;
322 case 3: u.format3.get_anchor (font, glyph_id, x, y); return; 322 case 3: u.format3.get_anchor (font, glyph_id, x, y); return;
323 default: return; 323 default: return;
324 } 324 }
325 } 325 }
326 326
327 inline bool sanitize (hb_sanitize_context_t *c) const 327 inline bool sanitize (hb_sanitize_context_t *c) const
328 { 328 {
329 TRACE_SANITIZE (this); 329 TRACE_SANITIZE (this);
330 if (!u.format.sanitize (c)) return TRACE_RETURN (false); 330 if (!u.format.sanitize (c)) return_trace (false);
331 switch (u.format) { 331 switch (u.format) {
332 case 1: return TRACE_RETURN (u.format1.sanitize (c)); 332 case 1: return_trace (u.format1.sanitize (c));
333 case 2: return TRACE_RETURN (u.format2.sanitize (c)); 333 case 2: return_trace (u.format2.sanitize (c));
334 case 3: return TRACE_RETURN (u.format3.sanitize (c)); 334 case 3: return_trace (u.format3.sanitize (c));
335 default:return TRACE_RETURN (true); 335 default:return_trace (true);
336 } 336 }
337 } 337 }
338 338
339 protected: 339 protected:
340 union { 340 union {
341 USHORT format; /* Format identifier */ 341 USHORT format; /* Format identifier */
342 AnchorFormat1 format1; 342 AnchorFormat1 format1;
343 AnchorFormat2 format2; 343 AnchorFormat2 format2;
344 AnchorFormat3 format3; 344 AnchorFormat3 format3;
345 } u; 345 } u;
346 public: 346 public:
347 DEFINE_SIZE_UNION (2, format); 347 DEFINE_SIZE_UNION (2, format);
348 }; 348 };
349 349
350 350
351 struct AnchorMatrix 351 struct AnchorMatrix
352 { 352 {
353 inline const Anchor& get_anchor (unsigned int row, unsigned int col, unsigned int cols, bool *found) const { 353 inline const Anchor& get_anchor (unsigned int row, unsigned int col, unsigned int cols, bool *found) const {
354 *found = false; 354 *found = false;
355 if (unlikely (row >= rows || col >= cols)) return Null(Anchor); 355 if (unlikely (row >= rows || col >= cols)) return Null(Anchor);
356 *found = !matrixZ[row * cols + col].is_null (); 356 *found = !matrixZ[row * cols + col].is_null ();
357 return this+matrixZ[row * cols + col]; 357 return this+matrixZ[row * cols + col];
358 } 358 }
359 359
360 inline bool sanitize (hb_sanitize_context_t *c, unsigned int cols) const 360 inline bool sanitize (hb_sanitize_context_t *c, unsigned int cols) const
361 { 361 {
362 TRACE_SANITIZE (this); 362 TRACE_SANITIZE (this);
363 if (!c->check_struct (this)) return TRACE_RETURN (false); 363 if (!c->check_struct (this)) return_trace (false);
364 if (unlikely (rows > 0 && cols >= ((unsigned int) -1) / rows)) return TRACE_ RETURN (false); 364 if (unlikely (rows > 0 && cols >= ((unsigned int) -1) / rows)) return_trace (false);
365 unsigned int count = rows * cols; 365 unsigned int count = rows * cols;
366 if (!c->check_array (matrixZ, matrixZ[0].static_size, count)) return TRACE_R ETURN (false); 366 if (!c->check_array (matrixZ, matrixZ[0].static_size, count)) return_trace ( false);
367 for (unsigned int i = 0; i < count; i++) 367 for (unsigned int i = 0; i < count; i++)
368 if (!matrixZ[i].sanitize (c, this)) return TRACE_RETURN (false); 368 if (!matrixZ[i].sanitize (c, this)) return_trace (false);
369 return TRACE_RETURN (true); 369 return_trace (true);
370 } 370 }
371 371
372 USHORT rows; /* Number of rows */ 372 USHORT rows; /* Number of rows */
373 protected: 373 protected:
374 OffsetTo<Anchor> 374 OffsetTo<Anchor>
375 matrixZ[VAR]; /* Matrix of offsets to Anchor tables-- 375 matrixZ[VAR]; /* Matrix of offsets to Anchor tables--
376 * from beginning of AnchorMatrix table */ 376 * from beginning of AnchorMatrix table */
377 public: 377 public:
378 DEFINE_SIZE_ARRAY (2, matrixZ); 378 DEFINE_SIZE_ARRAY (2, matrixZ);
379 }; 379 };
380 380
381 381
382 struct MarkRecord 382 struct MarkRecord
383 { 383 {
384 friend struct MarkArray; 384 friend struct MarkArray;
385 385
386 inline bool sanitize (hb_sanitize_context_t *c, const void *base) const 386 inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
387 { 387 {
388 TRACE_SANITIZE (this); 388 TRACE_SANITIZE (this);
389 return TRACE_RETURN (c->check_struct (this) && markAnchor.sanitize (c, base) ); 389 return_trace (c->check_struct (this) && markAnchor.sanitize (c, base));
390 } 390 }
391 391
392 protected: 392 protected:
393 USHORT klass; /* Class defined for this mark */ 393 USHORT klass; /* Class defined for this mark */
394 OffsetTo<Anchor> 394 OffsetTo<Anchor>
395 markAnchor; /* Offset to Anchor table--from 395 markAnchor; /* Offset to Anchor table--from
396 * beginning of MarkArray table */ 396 * beginning of MarkArray table */
397 public: 397 public:
398 DEFINE_SIZE_STATIC (4); 398 DEFINE_SIZE_STATIC (4);
399 }; 399 };
400 400
401 struct MarkArray : ArrayOf<MarkRecord> /* Array of MarkRecords--in Coverage ord er */ 401 struct MarkArray : ArrayOf<MarkRecord> /* Array of MarkRecords--in Coverage ord er */
402 { 402 {
403 inline bool apply (hb_apply_context_t *c, 403 inline bool apply (hb_apply_context_t *c,
404 unsigned int mark_index, unsigned int glyph_index, 404 unsigned int mark_index, unsigned int glyph_index,
405 const AnchorMatrix &anchors, unsigned int class_count, 405 const AnchorMatrix &anchors, unsigned int class_count,
406 unsigned int glyph_pos) const 406 unsigned int glyph_pos) const
407 { 407 {
408 TRACE_APPLY (this); 408 TRACE_APPLY (this);
409 hb_buffer_t *buffer = c->buffer; 409 hb_buffer_t *buffer = c->buffer;
410 const MarkRecord &record = ArrayOf<MarkRecord>::operator[](mark_index); 410 const MarkRecord &record = ArrayOf<MarkRecord>::operator[](mark_index);
411 unsigned int mark_class = record.klass; 411 unsigned int mark_class = record.klass;
412 412
413 const Anchor& mark_anchor = this + record.markAnchor; 413 const Anchor& mark_anchor = this + record.markAnchor;
414 bool found; 414 bool found;
415 const Anchor& glyph_anchor = anchors.get_anchor (glyph_index, mark_class, cl ass_count, &found); 415 const Anchor& glyph_anchor = anchors.get_anchor (glyph_index, mark_class, cl ass_count, &found);
416 /* If this subtable doesn't have an anchor for this base and this class, 416 /* If this subtable doesn't have an anchor for this base and this class,
417 * return false such that the subsequent subtables have a chance at it. */ 417 * return false such that the subsequent subtables have a chance at it. */
418 if (unlikely (!found)) return TRACE_RETURN (false); 418 if (unlikely (!found)) return_trace (false);
419 419
420 hb_position_t mark_x, mark_y, base_x, base_y; 420 hb_position_t mark_x, mark_y, base_x, base_y;
421 421
422 mark_anchor.get_anchor (c->font, buffer->cur().codepoint, &mark_x, &mark_y); 422 mark_anchor.get_anchor (c->font, buffer->cur().codepoint, &mark_x, &mark_y);
423 glyph_anchor.get_anchor (c->font, buffer->info[glyph_pos].codepoint, &base_x , &base_y); 423 glyph_anchor.get_anchor (c->font, buffer->info[glyph_pos].codepoint, &base_x , &base_y);
424 424
425 hb_glyph_position_t &o = buffer->cur_pos(); 425 hb_glyph_position_t &o = buffer->cur_pos();
426 o.x_offset = base_x - mark_x; 426 o.x_offset = base_x - mark_x;
427 o.y_offset = base_y - mark_y; 427 o.y_offset = base_y - mark_y;
428 o.attach_lookback() = buffer->idx - glyph_pos; 428 o.attach_lookback() = buffer->idx - glyph_pos;
429 429
430 buffer->idx++; 430 buffer->idx++;
431 return TRACE_RETURN (true); 431 return_trace (true);
432 } 432 }
433 433
434 inline bool sanitize (hb_sanitize_context_t *c) const 434 inline bool sanitize (hb_sanitize_context_t *c) const
435 { 435 {
436 TRACE_SANITIZE (this); 436 TRACE_SANITIZE (this);
437 return TRACE_RETURN (ArrayOf<MarkRecord>::sanitize (c, this)); 437 return_trace (ArrayOf<MarkRecord>::sanitize (c, this));
438 } 438 }
439 }; 439 };
440 440
441 441
442 /* Lookups */ 442 /* Lookups */
443 443
444 struct SinglePosFormat1 444 struct SinglePosFormat1
445 { 445 {
446 inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 446 inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
447 { 447 {
448 TRACE_COLLECT_GLYPHS (this); 448 TRACE_COLLECT_GLYPHS (this);
449 (this+coverage).add_coverage (c->input); 449 (this+coverage).add_coverage (c->input);
450 } 450 }
451 451
452 inline const Coverage &get_coverage (void) const 452 inline const Coverage &get_coverage (void) const
453 { 453 {
454 return this+coverage; 454 return this+coverage;
455 } 455 }
456 456
457 inline bool apply (hb_apply_context_t *c) const 457 inline bool apply (hb_apply_context_t *c) const
458 { 458 {
459 TRACE_APPLY (this); 459 TRACE_APPLY (this);
460 hb_buffer_t *buffer = c->buffer; 460 hb_buffer_t *buffer = c->buffer;
461 unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint) ; 461 unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint) ;
462 if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); 462 if (likely (index == NOT_COVERED)) return_trace (false);
463 463
464 valueFormat.apply_value (c->font, c->direction, this, 464 valueFormat.apply_value (c->font, c->direction, this,
465 values, buffer->cur_pos()); 465 values, buffer->cur_pos());
466 466
467 buffer->idx++; 467 buffer->idx++;
468 return TRACE_RETURN (true); 468 return_trace (true);
469 } 469 }
470 470
471 inline bool sanitize (hb_sanitize_context_t *c) const 471 inline bool sanitize (hb_sanitize_context_t *c) const
472 { 472 {
473 TRACE_SANITIZE (this); 473 TRACE_SANITIZE (this);
474 return TRACE_RETURN (c->check_struct (this) 474 return_trace (c->check_struct (this) &&
475 && coverage.sanitize (c, this) 475 » » coverage.sanitize (c, this) &&
476 » && valueFormat.sanitize_value (c, this, values)); 476 » » valueFormat.sanitize_value (c, this, values));
477 } 477 }
478 478
479 protected: 479 protected:
480 USHORT format; /* Format identifier--format = 1 */ 480 USHORT format; /* Format identifier--format = 1 */
481 OffsetTo<Coverage> 481 OffsetTo<Coverage>
482 coverage; /* Offset to Coverage table--from 482 coverage; /* Offset to Coverage table--from
483 * beginning of subtable */ 483 * beginning of subtable */
484 ValueFormat valueFormat; /* Defines the types of data in the 484 ValueFormat valueFormat; /* Defines the types of data in the
485 * ValueRecord */ 485 * ValueRecord */
486 ValueRecord values; /* Defines positioning 486 ValueRecord values; /* Defines positioning
(...skipping 14 matching lines...) Expand all
501 inline const Coverage &get_coverage (void) const 501 inline const Coverage &get_coverage (void) const
502 { 502 {
503 return this+coverage; 503 return this+coverage;
504 } 504 }
505 505
506 inline bool apply (hb_apply_context_t *c) const 506 inline bool apply (hb_apply_context_t *c) const
507 { 507 {
508 TRACE_APPLY (this); 508 TRACE_APPLY (this);
509 hb_buffer_t *buffer = c->buffer; 509 hb_buffer_t *buffer = c->buffer;
510 unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint) ; 510 unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint) ;
511 if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); 511 if (likely (index == NOT_COVERED)) return_trace (false);
512 512
513 if (likely (index >= valueCount)) return TRACE_RETURN (false); 513 if (likely (index >= valueCount)) return_trace (false);
514 514
515 valueFormat.apply_value (c->font, c->direction, this, 515 valueFormat.apply_value (c->font, c->direction, this,
516 &values[index * valueFormat.get_len ()], 516 &values[index * valueFormat.get_len ()],
517 buffer->cur_pos()); 517 buffer->cur_pos());
518 518
519 buffer->idx++; 519 buffer->idx++;
520 return TRACE_RETURN (true); 520 return_trace (true);
521 } 521 }
522 522
523 inline bool sanitize (hb_sanitize_context_t *c) const 523 inline bool sanitize (hb_sanitize_context_t *c) const
524 { 524 {
525 TRACE_SANITIZE (this); 525 TRACE_SANITIZE (this);
526 return TRACE_RETURN (c->check_struct (this) 526 return_trace (c->check_struct (this) &&
527 » && coverage.sanitize (c, this) 527 » » coverage.sanitize (c, this) &&
528 » && valueFormat.sanitize_values (c, this, values, valueCount)); 528 » » valueFormat.sanitize_values (c, this, values, valueCount));
529 } 529 }
530 530
531 protected: 531 protected:
532 USHORT format; /* Format identifier--format = 2 */ 532 USHORT format; /* Format identifier--format = 2 */
533 OffsetTo<Coverage> 533 OffsetTo<Coverage>
534 coverage; /* Offset to Coverage table--from 534 coverage; /* Offset to Coverage table--from
535 * beginning of subtable */ 535 * beginning of subtable */
536 ValueFormat valueFormat; /* Defines the types of data in the 536 ValueFormat valueFormat; /* Defines the types of data in the
537 * ValueRecord */ 537 * ValueRecord */
538 USHORT valueCount; /* Number of ValueRecords */ 538 USHORT valueCount; /* Number of ValueRecords */
539 ValueRecord values; /* Array of ValueRecords--positioning 539 ValueRecord values; /* Array of ValueRecords--positioning
540 * values applied to glyphs */ 540 * values applied to glyphs */
541 public: 541 public:
542 DEFINE_SIZE_ARRAY (8, values); 542 DEFINE_SIZE_ARRAY (8, values);
543 }; 543 };
544 544
545 struct SinglePos 545 struct SinglePos
546 { 546 {
547 template <typename context_t> 547 template <typename context_t>
548 inline typename context_t::return_t dispatch (context_t *c) const 548 inline typename context_t::return_t dispatch (context_t *c) const
549 { 549 {
550 TRACE_DISPATCH (this, u.format); 550 TRACE_DISPATCH (this, u.format);
551 if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_ return_value ()); 551 if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispa tch_return_value ());
552 switch (u.format) { 552 switch (u.format) {
553 case 1: return TRACE_RETURN (c->dispatch (u.format1)); 553 case 1: return_trace (c->dispatch (u.format1));
554 case 2: return TRACE_RETURN (c->dispatch (u.format2)); 554 case 2: return_trace (c->dispatch (u.format2));
555 default:return TRACE_RETURN (c->default_return_value ()); 555 default:return_trace (c->default_return_value ());
556 } 556 }
557 } 557 }
558 558
559 protected: 559 protected:
560 union { 560 union {
561 USHORT format; /* Format identifier */ 561 USHORT format; /* Format identifier */
562 SinglePosFormat1 format1; 562 SinglePosFormat1 format1;
563 SinglePosFormat2 format2; 563 SinglePosFormat2 format2;
564 } u; 564 } u;
565 }; 565 };
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
608 hb_buffer_t *buffer = c->buffer; 608 hb_buffer_t *buffer = c->buffer;
609 unsigned int len1 = valueFormats[0].get_len (); 609 unsigned int len1 = valueFormats[0].get_len ();
610 unsigned int len2 = valueFormats[1].get_len (); 610 unsigned int len2 = valueFormats[1].get_len ();
611 unsigned int record_size = USHORT::static_size * (1 + len1 + len2); 611 unsigned int record_size = USHORT::static_size * (1 + len1 + len2);
612 612
613 const PairValueRecord *record_array = CastP<PairValueRecord> (arrayZ); 613 const PairValueRecord *record_array = CastP<PairValueRecord> (arrayZ);
614 unsigned int count = len; 614 unsigned int count = len;
615 615
616 /* Hand-coded bsearch. */ 616 /* Hand-coded bsearch. */
617 if (unlikely (!count)) 617 if (unlikely (!count))
618 return TRACE_RETURN (false); 618 return_trace (false);
619 hb_codepoint_t x = buffer->info[pos].codepoint; 619 hb_codepoint_t x = buffer->info[pos].codepoint;
620 int min = 0, max = (int) count - 1; 620 int min = 0, max = (int) count - 1;
621 while (min <= max) 621 while (min <= max)
622 { 622 {
623 int mid = (min + max) / 2; 623 int mid = (min + max) / 2;
624 const PairValueRecord *record = &StructAtOffset<PairValueRecord> (record_a rray, record_size * mid); 624 const PairValueRecord *record = &StructAtOffset<PairValueRecord> (record_a rray, record_size * mid);
625 hb_codepoint_t mid_x = record->secondGlyph; 625 hb_codepoint_t mid_x = record->secondGlyph;
626 if (x < mid_x) 626 if (x < mid_x)
627 max = mid - 1; 627 max = mid - 1;
628 else if (x > mid_x) 628 else if (x > mid_x)
629 min = mid + 1; 629 min = mid + 1;
630 else 630 else
631 { 631 {
632 valueFormats[0].apply_value (c->font, c->direction, this, 632 valueFormats[0].apply_value (c->font, c->direction, this,
633 &record->values[0], buffer->cur_pos()); 633 &record->values[0], buffer->cur_pos());
634 valueFormats[1].apply_value (c->font, c->direction, this, 634 valueFormats[1].apply_value (c->font, c->direction, this,
635 &record->values[len1], buffer->pos[pos]); 635 &record->values[len1], buffer->pos[pos]);
636 if (len2) 636 if (len2)
637 pos++; 637 pos++;
638 buffer->idx = pos; 638 buffer->idx = pos;
639 » return TRACE_RETURN (true); 639 » return_trace (true);
640 } 640 }
641 } 641 }
642 642
643 return TRACE_RETURN (false); 643 return_trace (false);
644 } 644 }
645 645
646 struct sanitize_closure_t { 646 struct sanitize_closure_t {
647 const void *base; 647 const void *base;
648 const ValueFormat *valueFormats; 648 const ValueFormat *valueFormats;
649 unsigned int len1; /* valueFormats[0].get_len() */ 649 unsigned int len1; /* valueFormats[0].get_len() */
650 unsigned int stride; /* 1 + len1 + len2 */ 650 unsigned int stride; /* 1 + len1 + len2 */
651 }; 651 };
652 652
653 inline bool sanitize (hb_sanitize_context_t *c, const sanitize_closure_t *clos ure) const 653 inline bool sanitize (hb_sanitize_context_t *c, const sanitize_closure_t *clos ure) const
654 { 654 {
655 TRACE_SANITIZE (this); 655 TRACE_SANITIZE (this);
656 if (!(c->check_struct (this) 656 if (!(c->check_struct (this)
657 && c->check_array (arrayZ, USHORT::static_size * closure->stride, len))) return TRACE_RETURN (false); 657 && c->check_array (arrayZ, USHORT::static_size * closure->stride, len))) return_trace (false);
658 658
659 unsigned int count = len; 659 unsigned int count = len;
660 const PairValueRecord *record = CastP<PairValueRecord> (arrayZ); 660 const PairValueRecord *record = CastP<PairValueRecord> (arrayZ);
661 return TRACE_RETURN (closure->valueFormats[0].sanitize_values_stride_unsafe (c, closure->base, &record->values[0], count, closure->stride) 661 return_trace (closure->valueFormats[0].sanitize_values_stride_unsafe (c, clo sure->base, &record->values[0], count, closure->stride) &&
662 » » && closure->valueFormats[1].sanitize_values_stride_unsafe (c, closure->base, &record->values[closure->len1], count, closure->stride)); 662 » » closure->valueFormats[1].sanitize_values_stride_unsafe (c, clo sure->base, &record->values[closure->len1], count, closure->stride));
663 } 663 }
664 664
665 protected: 665 protected:
666 USHORT len; /* Number of PairValueRecords */ 666 USHORT len; /* Number of PairValueRecords */
667 USHORT arrayZ[VAR]; /* Array of PairValueRecords--ordered 667 USHORT arrayZ[VAR]; /* Array of PairValueRecords--ordered
668 * by GlyphID of the second glyph */ 668 * by GlyphID of the second glyph */
669 public: 669 public:
670 DEFINE_SIZE_ARRAY (2, arrayZ); 670 DEFINE_SIZE_ARRAY (2, arrayZ);
671 }; 671 };
672 672
(...skipping 11 matching lines...) Expand all
684 inline const Coverage &get_coverage (void) const 684 inline const Coverage &get_coverage (void) const
685 { 685 {
686 return this+coverage; 686 return this+coverage;
687 } 687 }
688 688
689 inline bool apply (hb_apply_context_t *c) const 689 inline bool apply (hb_apply_context_t *c) const
690 { 690 {
691 TRACE_APPLY (this); 691 TRACE_APPLY (this);
692 hb_buffer_t *buffer = c->buffer; 692 hb_buffer_t *buffer = c->buffer;
693 unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint) ; 693 unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint) ;
694 if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); 694 if (likely (index == NOT_COVERED)) return_trace (false);
695 695
696 hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; 696 hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
697 skippy_iter.reset (buffer->idx, 1); 697 skippy_iter.reset (buffer->idx, 1);
698 if (!skippy_iter.next ()) return TRACE_RETURN (false); 698 if (!skippy_iter.next ()) return_trace (false);
699 699
700 return TRACE_RETURN ((this+pairSet[index]).apply (c, &valueFormat1, skippy_i ter.idx)); 700 return_trace ((this+pairSet[index]).apply (c, &valueFormat1, skippy_iter.idx ));
701 } 701 }
702 702
703 inline bool sanitize (hb_sanitize_context_t *c) const 703 inline bool sanitize (hb_sanitize_context_t *c) const
704 { 704 {
705 TRACE_SANITIZE (this); 705 TRACE_SANITIZE (this);
706 706
707 if (!c->check_struct (this)) return_trace (false);
708
707 unsigned int len1 = valueFormat1.get_len (); 709 unsigned int len1 = valueFormat1.get_len ();
708 unsigned int len2 = valueFormat2.get_len (); 710 unsigned int len2 = valueFormat2.get_len ();
709 PairSet::sanitize_closure_t closure = { 711 PairSet::sanitize_closure_t closure = {
710 this, 712 this,
711 &valueFormat1, 713 &valueFormat1,
712 len1, 714 len1,
713 1 + len1 + len2 715 1 + len1 + len2
714 }; 716 };
715 717
716 return TRACE_RETURN (c->check_struct (this) && coverage.sanitize (c, this) & & pairSet.sanitize (c, this, &closure)); 718 return_trace (coverage.sanitize (c, this) && pairSet.sanitize (c, this, &clo sure));
717 } 719 }
718 720
719 protected: 721 protected:
720 USHORT format; /* Format identifier--format = 1 */ 722 USHORT format; /* Format identifier--format = 1 */
721 OffsetTo<Coverage> 723 OffsetTo<Coverage>
722 coverage; /* Offset to Coverage table--from 724 coverage; /* Offset to Coverage table--from
723 * beginning of subtable */ 725 * beginning of subtable */
724 ValueFormat valueFormat1; /* Defines the types of data in 726 ValueFormat valueFormat1; /* Defines the types of data in
725 * ValueRecord1--for the first glyph 727 * ValueRecord1--for the first glyph
726 * in the pair--may be zero (0) */ 728 * in the pair--may be zero (0) */
(...skipping 28 matching lines...) Expand all
755 inline const Coverage &get_coverage (void) const 757 inline const Coverage &get_coverage (void) const
756 { 758 {
757 return this+coverage; 759 return this+coverage;
758 } 760 }
759 761
760 inline bool apply (hb_apply_context_t *c) const 762 inline bool apply (hb_apply_context_t *c) const
761 { 763 {
762 TRACE_APPLY (this); 764 TRACE_APPLY (this);
763 hb_buffer_t *buffer = c->buffer; 765 hb_buffer_t *buffer = c->buffer;
764 unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint) ; 766 unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint) ;
765 if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); 767 if (likely (index == NOT_COVERED)) return_trace (false);
766 768
767 hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; 769 hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
768 skippy_iter.reset (buffer->idx, 1); 770 skippy_iter.reset (buffer->idx, 1);
769 if (!skippy_iter.next ()) return TRACE_RETURN (false); 771 if (!skippy_iter.next ()) return_trace (false);
770 772
771 unsigned int len1 = valueFormat1.get_len (); 773 unsigned int len1 = valueFormat1.get_len ();
772 unsigned int len2 = valueFormat2.get_len (); 774 unsigned int len2 = valueFormat2.get_len ();
773 unsigned int record_len = len1 + len2; 775 unsigned int record_len = len1 + len2;
774 776
775 unsigned int klass1 = (this+classDef1).get_class (buffer->cur().codepoint); 777 unsigned int klass1 = (this+classDef1).get_class (buffer->cur().codepoint);
776 unsigned int klass2 = (this+classDef2).get_class (buffer->info[skippy_iter.i dx].codepoint); 778 unsigned int klass2 = (this+classDef2).get_class (buffer->info[skippy_iter.i dx].codepoint);
777 if (unlikely (klass1 >= class1Count || klass2 >= class2Count)) return TRACE_ RETURN (false); 779 if (unlikely (klass1 >= class1Count || klass2 >= class2Count)) return_trace (false);
778 780
779 const Value *v = &values[record_len * (klass1 * class2Count + klass2)]; 781 const Value *v = &values[record_len * (klass1 * class2Count + klass2)];
780 valueFormat1.apply_value (c->font, c->direction, this, 782 valueFormat1.apply_value (c->font, c->direction, this,
781 v, buffer->cur_pos()); 783 v, buffer->cur_pos());
782 valueFormat2.apply_value (c->font, c->direction, this, 784 valueFormat2.apply_value (c->font, c->direction, this,
783 v + len1, buffer->pos[skippy_iter.idx]); 785 v + len1, buffer->pos[skippy_iter.idx]);
784 786
785 buffer->idx = skippy_iter.idx; 787 buffer->idx = skippy_iter.idx;
786 if (len2) 788 if (len2)
787 buffer->idx++; 789 buffer->idx++;
788 790
789 return TRACE_RETURN (true); 791 return_trace (true);
790 } 792 }
791 793
792 inline bool sanitize (hb_sanitize_context_t *c) const 794 inline bool sanitize (hb_sanitize_context_t *c) const
793 { 795 {
794 TRACE_SANITIZE (this); 796 TRACE_SANITIZE (this);
795 if (!(c->check_struct (this) 797 if (!(c->check_struct (this)
796 && coverage.sanitize (c, this) 798 && coverage.sanitize (c, this)
797 && classDef1.sanitize (c, this) 799 && classDef1.sanitize (c, this)
798 && classDef2.sanitize (c, this))) return TRACE_RETURN (false); 800 && classDef2.sanitize (c, this))) return_trace (false);
799 801
800 unsigned int len1 = valueFormat1.get_len (); 802 unsigned int len1 = valueFormat1.get_len ();
801 unsigned int len2 = valueFormat2.get_len (); 803 unsigned int len2 = valueFormat2.get_len ();
802 unsigned int stride = len1 + len2; 804 unsigned int stride = len1 + len2;
803 unsigned int record_size = valueFormat1.get_size () + valueFormat2.get_size (); 805 unsigned int record_size = valueFormat1.get_size () + valueFormat2.get_size ();
804 unsigned int count = (unsigned int) class1Count * (unsigned int) class2Count ; 806 unsigned int count = (unsigned int) class1Count * (unsigned int) class2Count ;
805 return TRACE_RETURN (c->check_array (values, record_size, count) && 807 return_trace (c->check_array (values, record_size, count) &&
806 » » » valueFormat1.sanitize_values_stride_unsafe (c, this, &v alues[0], count, stride) && 808 » » valueFormat1.sanitize_values_stride_unsafe (c, this, &values[0 ], count, stride) &&
807 » » » valueFormat2.sanitize_values_stride_unsafe (c, this, &v alues[len1], count, stride)); 809 » » valueFormat2.sanitize_values_stride_unsafe (c, this, &values[l en1], count, stride));
808 } 810 }
809 811
810 protected: 812 protected:
811 USHORT format; /* Format identifier--format = 2 */ 813 USHORT format; /* Format identifier--format = 2 */
812 OffsetTo<Coverage> 814 OffsetTo<Coverage>
813 coverage; /* Offset to Coverage table--from 815 coverage; /* Offset to Coverage table--from
814 * beginning of subtable */ 816 * beginning of subtable */
815 ValueFormat valueFormat1; /* ValueRecord definition--for the 817 ValueFormat valueFormat1; /* ValueRecord definition--for the
816 * first glyph of the pair--may be zero 818 * first glyph of the pair--may be zero
817 * (0) */ 819 * (0) */
(...skipping 18 matching lines...) Expand all
836 public: 838 public:
837 DEFINE_SIZE_ARRAY (16, values); 839 DEFINE_SIZE_ARRAY (16, values);
838 }; 840 };
839 841
840 struct PairPos 842 struct PairPos
841 { 843 {
842 template <typename context_t> 844 template <typename context_t>
843 inline typename context_t::return_t dispatch (context_t *c) const 845 inline typename context_t::return_t dispatch (context_t *c) const
844 { 846 {
845 TRACE_DISPATCH (this, u.format); 847 TRACE_DISPATCH (this, u.format);
846 if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_ return_value ()); 848 if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispa tch_return_value ());
847 switch (u.format) { 849 switch (u.format) {
848 case 1: return TRACE_RETURN (c->dispatch (u.format1)); 850 case 1: return_trace (c->dispatch (u.format1));
849 case 2: return TRACE_RETURN (c->dispatch (u.format2)); 851 case 2: return_trace (c->dispatch (u.format2));
850 default:return TRACE_RETURN (c->default_return_value ()); 852 default:return_trace (c->default_return_value ());
851 } 853 }
852 } 854 }
853 855
854 protected: 856 protected:
855 union { 857 union {
856 USHORT format; /* Format identifier */ 858 USHORT format; /* Format identifier */
857 PairPosFormat1 format1; 859 PairPosFormat1 format1;
858 PairPosFormat2 format2; 860 PairPosFormat2 format2;
859 } u; 861 } u;
860 }; 862 };
861 863
862 864
863 struct EntryExitRecord 865 struct EntryExitRecord
864 { 866 {
865 friend struct CursivePosFormat1; 867 friend struct CursivePosFormat1;
866 868
867 inline bool sanitize (hb_sanitize_context_t *c, const void *base) const 869 inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
868 { 870 {
869 TRACE_SANITIZE (this); 871 TRACE_SANITIZE (this);
870 return TRACE_RETURN (entryAnchor.sanitize (c, base) && exitAnchor.sanitize ( c, base)); 872 return_trace (entryAnchor.sanitize (c, base) && exitAnchor.sanitize (c, base ));
871 } 873 }
872 874
873 protected: 875 protected:
874 OffsetTo<Anchor> 876 OffsetTo<Anchor>
875 entryAnchor; /* Offset to EntryAnchor table--from 877 entryAnchor; /* Offset to EntryAnchor table--from
876 * beginning of CursivePos 878 * beginning of CursivePos
877 * subtable--may be NULL */ 879 * subtable--may be NULL */
878 OffsetTo<Anchor> 880 OffsetTo<Anchor>
879 exitAnchor; /* Offset to ExitAnchor table--from 881 exitAnchor; /* Offset to ExitAnchor table--from
880 * beginning of CursivePos 882 * beginning of CursivePos
881 * subtable--may be NULL */ 883 * subtable--may be NULL */
882 public: 884 public:
883 DEFINE_SIZE_STATIC (4); 885 DEFINE_SIZE_STATIC (4);
884 }; 886 };
885 887
888 static void
889 reverse_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direc tion_t direction, unsigned int new_parent);
890
886 struct CursivePosFormat1 891 struct CursivePosFormat1
887 { 892 {
888 inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 893 inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
889 { 894 {
890 TRACE_COLLECT_GLYPHS (this); 895 TRACE_COLLECT_GLYPHS (this);
891 (this+coverage).add_coverage (c->input); 896 (this+coverage).add_coverage (c->input);
892 } 897 }
893 898
894 inline const Coverage &get_coverage (void) const 899 inline const Coverage &get_coverage (void) const
895 { 900 {
896 return this+coverage; 901 return this+coverage;
897 } 902 }
898 903
899 inline bool apply (hb_apply_context_t *c) const 904 inline bool apply (hb_apply_context_t *c) const
900 { 905 {
901 TRACE_APPLY (this); 906 TRACE_APPLY (this);
902 hb_buffer_t *buffer = c->buffer; 907 hb_buffer_t *buffer = c->buffer;
903 908
904 /* We don't handle mark glyphs here. */ 909 /* We don't handle mark glyphs here. */
905 if (unlikely (_hb_glyph_info_is_mark (&buffer->cur()))) return TRACE_RETURN (false); 910 if (unlikely (_hb_glyph_info_is_mark (&buffer->cur()))) return_trace (false) ;
906 911
907 const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_cov erage (buffer->cur().codepoint)]; 912 const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_cov erage (buffer->cur().codepoint)];
908 if (!this_record.exitAnchor) return TRACE_RETURN (false); 913 if (!this_record.exitAnchor) return_trace (false);
909 914
910 hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; 915 hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
911 skippy_iter.reset (buffer->idx, 1); 916 skippy_iter.reset (buffer->idx, 1);
912 if (!skippy_iter.next ()) return TRACE_RETURN (false); 917 if (!skippy_iter.next ()) return_trace (false);
913 918
914 const EntryExitRecord &next_record = entryExitRecord[(this+coverage).get_cov erage (buffer->info[skippy_iter.idx].codepoint)]; 919 const EntryExitRecord &next_record = entryExitRecord[(this+coverage).get_cov erage (buffer->info[skippy_iter.idx].codepoint)];
915 if (!next_record.entryAnchor) return TRACE_RETURN (false); 920 if (!next_record.entryAnchor) return_trace (false);
916 921
917 unsigned int i = buffer->idx; 922 unsigned int i = buffer->idx;
918 unsigned int j = skippy_iter.idx; 923 unsigned int j = skippy_iter.idx;
919 924
920 hb_position_t entry_x, entry_y, exit_x, exit_y; 925 hb_position_t entry_x, entry_y, exit_x, exit_y;
921 (this+this_record.exitAnchor).get_anchor (c->font, buffer->info[i].codepoint , &exit_x, &exit_y); 926 (this+this_record.exitAnchor).get_anchor (c->font, buffer->info[i].codepoint , &exit_x, &exit_y);
922 (this+next_record.entryAnchor).get_anchor (c->font, buffer->info[j].codepoin t, &entry_x, &entry_y); 927 (this+next_record.entryAnchor).get_anchor (c->font, buffer->info[j].codepoin t, &entry_x, &entry_y);
923 928
924 hb_glyph_position_t *pos = buffer->pos; 929 hb_glyph_position_t *pos = buffer->pos;
925 930
(...skipping 27 matching lines...) Expand all
953 pos[i].y_offset -= d; 958 pos[i].y_offset -= d;
954 959
955 pos[j].y_advance = entry_y; 960 pos[j].y_advance = entry_y;
956 break; 961 break;
957 case HB_DIRECTION_INVALID: 962 case HB_DIRECTION_INVALID:
958 default: 963 default:
959 break; 964 break;
960 } 965 }
961 966
962 /* Cross-direction adjustment */ 967 /* Cross-direction adjustment */
963 if (c->lookup_props & LookupFlag::RightToLeft) { 968
964 pos[i].cursive_chain() = j - i; 969 /* We attach child to parent (think graph theory and rooted trees whereas
965 if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction))) 970 * the root stays on baseline and each node aligns itself against its
966 » pos[i].y_offset = entry_y - exit_y; 971 * parent.
967 else 972 *
968 » pos[i].x_offset = entry_x - exit_x; 973 * Optimize things for the case of RightToLeft, as that's most common in
969 } else { 974 * Arabinc. */
970 pos[j].cursive_chain() = i - j; 975 unsigned int child = i;
971 if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction))) 976 unsigned int parent = j;
972 » pos[j].y_offset = exit_y - entry_y; 977 hb_position_t x_offset = entry_x - exit_x;
973 else 978 hb_position_t y_offset = entry_y - exit_y;
974 » pos[j].x_offset = exit_x - entry_x; 979 if (!(c->lookup_props & LookupFlag::RightToLeft))
980 {
981 unsigned int k = child;
982 child = parent;
983 parent = k;
984 x_offset = -x_offset;
985 y_offset = -y_offset;
975 } 986 }
976 987
988 /* If child was already connected to someone else, walk through its old
989 * chain and reverse the link direction, such that the whole tree of its
990 * previous connection now attaches to new parent. Watch out for case
991 * where new parent is on the path from old chain...
992 */
993 reverse_cursive_minor_offset (pos, child, c->direction, parent);
994
995 pos[child].cursive_chain() = parent - child;
996 if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction)))
997 pos[child].y_offset = y_offset;
998 else
999 pos[child].x_offset = x_offset;
1000
977 buffer->idx = j; 1001 buffer->idx = j;
978 return TRACE_RETURN (true); 1002 return_trace (true);
979 } 1003 }
980 1004
981 inline bool sanitize (hb_sanitize_context_t *c) const 1005 inline bool sanitize (hb_sanitize_context_t *c) const
982 { 1006 {
983 TRACE_SANITIZE (this); 1007 TRACE_SANITIZE (this);
984 return TRACE_RETURN (coverage.sanitize (c, this) && entryExitRecord.sanitize (c, this)); 1008 return_trace (coverage.sanitize (c, this) && entryExitRecord.sanitize (c, th is));
985 } 1009 }
986 1010
987 protected: 1011 protected:
988 USHORT format; /* Format identifier--format = 1 */ 1012 USHORT format; /* Format identifier--format = 1 */
989 OffsetTo<Coverage> 1013 OffsetTo<Coverage>
990 coverage; /* Offset to Coverage table--from 1014 coverage; /* Offset to Coverage table--from
991 * beginning of subtable */ 1015 * beginning of subtable */
992 ArrayOf<EntryExitRecord> 1016 ArrayOf<EntryExitRecord>
993 entryExitRecord; /* Array of EntryExit records--in 1017 entryExitRecord; /* Array of EntryExit records--in
994 * Coverage Index order */ 1018 * Coverage Index order */
995 public: 1019 public:
996 DEFINE_SIZE_ARRAY (6, entryExitRecord); 1020 DEFINE_SIZE_ARRAY (6, entryExitRecord);
997 }; 1021 };
998 1022
999 struct CursivePos 1023 struct CursivePos
1000 { 1024 {
1001 template <typename context_t> 1025 template <typename context_t>
1002 inline typename context_t::return_t dispatch (context_t *c) const 1026 inline typename context_t::return_t dispatch (context_t *c) const
1003 { 1027 {
1004 TRACE_DISPATCH (this, u.format); 1028 TRACE_DISPATCH (this, u.format);
1005 if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_ return_value ()); 1029 if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispa tch_return_value ());
1006 switch (u.format) { 1030 switch (u.format) {
1007 case 1: return TRACE_RETURN (c->dispatch (u.format1)); 1031 case 1: return_trace (c->dispatch (u.format1));
1008 default:return TRACE_RETURN (c->default_return_value ()); 1032 default:return_trace (c->default_return_value ());
1009 } 1033 }
1010 } 1034 }
1011 1035
1012 protected: 1036 protected:
1013 union { 1037 union {
1014 USHORT format; /* Format identifier */ 1038 USHORT format; /* Format identifier */
1015 CursivePosFormat1 format1; 1039 CursivePosFormat1 format1;
1016 } u; 1040 } u;
1017 }; 1041 };
1018 1042
(...skipping 15 matching lines...) Expand all
1034 inline const Coverage &get_coverage (void) const 1058 inline const Coverage &get_coverage (void) const
1035 { 1059 {
1036 return this+markCoverage; 1060 return this+markCoverage;
1037 } 1061 }
1038 1062
1039 inline bool apply (hb_apply_context_t *c) const 1063 inline bool apply (hb_apply_context_t *c) const
1040 { 1064 {
1041 TRACE_APPLY (this); 1065 TRACE_APPLY (this);
1042 hb_buffer_t *buffer = c->buffer; 1066 hb_buffer_t *buffer = c->buffer;
1043 unsigned int mark_index = (this+markCoverage).get_coverage (buffer->cur().c odepoint); 1067 unsigned int mark_index = (this+markCoverage).get_coverage (buffer->cur().c odepoint);
1044 if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false); 1068 if (likely (mark_index == NOT_COVERED)) return_trace (false);
1045 1069
1046 /* now we search backwards for a non-mark glyph */ 1070 /* now we search backwards for a non-mark glyph */
1047 hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; 1071 hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
1048 skippy_iter.reset (buffer->idx, 1); 1072 skippy_iter.reset (buffer->idx, 1);
1049 skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks); 1073 skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks);
1050 do { 1074 do {
1051 if (!skippy_iter.prev ()) return TRACE_RETURN (false); 1075 if (!skippy_iter.prev ()) return_trace (false);
1052 /* We only want to attach to the first of a MultipleSubst sequence. Rejec t others. */ 1076 /* We only want to attach to the first of a MultipleSubst sequence. Rejec t others. */
1053 if (0 == _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx])) bre ak; 1077 if (0 == _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx])) bre ak;
1054 skippy_iter.reject (); 1078 skippy_iter.reject ();
1055 } while (1); 1079 } while (1);
1056 1080
1057 /* Checking that matched glyph is actually a base glyph by GDEF is too stron g; disabled */ 1081 /* Checking that matched glyph is actually a base glyph by GDEF is too stron g; disabled */
1058 if (!_hb_glyph_info_is_base_glyph (&buffer->info[skippy_iter.idx])) { /*retu rn TRACE_RETURN (false);*/ } 1082 if (!_hb_glyph_info_is_base_glyph (&buffer->info[skippy_iter.idx])) { /*retu rn_trace (false);*/ }
1059 1083
1060 unsigned int base_index = (this+baseCoverage).get_coverage (buffer->info[sk ippy_iter.idx].codepoint); 1084 unsigned int base_index = (this+baseCoverage).get_coverage (buffer->info[sk ippy_iter.idx].codepoint);
1061 if (base_index == NOT_COVERED) return TRACE_RETURN (false); 1085 if (base_index == NOT_COVERED) return_trace (false);
1062 1086
1063 return TRACE_RETURN ((this+markArray).apply (c, mark_index, base_index, this +baseArray, classCount, skippy_iter.idx)); 1087 return_trace ((this+markArray).apply (c, mark_index, base_index, this+baseAr ray, classCount, skippy_iter.idx));
1064 } 1088 }
1065 1089
1066 inline bool sanitize (hb_sanitize_context_t *c) const 1090 inline bool sanitize (hb_sanitize_context_t *c) const
1067 { 1091 {
1068 TRACE_SANITIZE (this); 1092 TRACE_SANITIZE (this);
1069 return TRACE_RETURN (c->check_struct (this) && markCoverage.sanitize (c, thi s) && baseCoverage.sanitize (c, this) && 1093 return_trace (c->check_struct (this) &&
1070 » » » markArray.sanitize (c, this) && baseArray.sanitize (c, this, (unsigned int) classCount)); 1094 » » markCoverage.sanitize (c, this) &&
1095 » » baseCoverage.sanitize (c, this) &&
1096 » » markArray.sanitize (c, this) &&
1097 » » baseArray.sanitize (c, this, (unsigned int) classCount));
1071 } 1098 }
1072 1099
1073 protected: 1100 protected:
1074 USHORT format; /* Format identifier--format = 1 */ 1101 USHORT format; /* Format identifier--format = 1 */
1075 OffsetTo<Coverage> 1102 OffsetTo<Coverage>
1076 markCoverage; /* Offset to MarkCoverage table--from 1103 markCoverage; /* Offset to MarkCoverage table--from
1077 * beginning of MarkBasePos subtable */ 1104 * beginning of MarkBasePos subtable */
1078 OffsetTo<Coverage> 1105 OffsetTo<Coverage>
1079 baseCoverage; /* Offset to BaseCoverage table--from 1106 baseCoverage; /* Offset to BaseCoverage table--from
1080 * beginning of MarkBasePos subtable */ 1107 * beginning of MarkBasePos subtable */
1081 USHORT classCount; /* Number of classes defined for marks * / 1108 USHORT classCount; /* Number of classes defined for marks * /
1082 OffsetTo<MarkArray> 1109 OffsetTo<MarkArray>
1083 markArray; /* Offset to MarkArray table--from 1110 markArray; /* Offset to MarkArray table--from
1084 * beginning of MarkBasePos subtable */ 1111 * beginning of MarkBasePos subtable */
1085 OffsetTo<BaseArray> 1112 OffsetTo<BaseArray>
1086 baseArray; /* Offset to BaseArray table--from 1113 baseArray; /* Offset to BaseArray table--from
1087 * beginning of MarkBasePos subtable */ 1114 * beginning of MarkBasePos subtable */
1088 public: 1115 public:
1089 DEFINE_SIZE_STATIC (12); 1116 DEFINE_SIZE_STATIC (12);
1090 }; 1117 };
1091 1118
1092 struct MarkBasePos 1119 struct MarkBasePos
1093 { 1120 {
1094 template <typename context_t> 1121 template <typename context_t>
1095 inline typename context_t::return_t dispatch (context_t *c) const 1122 inline typename context_t::return_t dispatch (context_t *c) const
1096 { 1123 {
1097 TRACE_DISPATCH (this, u.format); 1124 TRACE_DISPATCH (this, u.format);
1098 if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_ return_value ()); 1125 if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispa tch_return_value ());
1099 switch (u.format) { 1126 switch (u.format) {
1100 case 1: return TRACE_RETURN (c->dispatch (u.format1)); 1127 case 1: return_trace (c->dispatch (u.format1));
1101 default:return TRACE_RETURN (c->default_return_value ()); 1128 default:return_trace (c->default_return_value ());
1102 } 1129 }
1103 } 1130 }
1104 1131
1105 protected: 1132 protected:
1106 union { 1133 union {
1107 USHORT format; /* Format identifier */ 1134 USHORT format; /* Format identifier */
1108 MarkBasePosFormat1 format1; 1135 MarkBasePosFormat1 format1;
1109 } u; 1136 } u;
1110 }; 1137 };
1111 1138
(...skipping 20 matching lines...) Expand all
1132 inline const Coverage &get_coverage (void) const 1159 inline const Coverage &get_coverage (void) const
1133 { 1160 {
1134 return this+markCoverage; 1161 return this+markCoverage;
1135 } 1162 }
1136 1163
1137 inline bool apply (hb_apply_context_t *c) const 1164 inline bool apply (hb_apply_context_t *c) const
1138 { 1165 {
1139 TRACE_APPLY (this); 1166 TRACE_APPLY (this);
1140 hb_buffer_t *buffer = c->buffer; 1167 hb_buffer_t *buffer = c->buffer;
1141 unsigned int mark_index = (this+markCoverage).get_coverage (buffer->cur().c odepoint); 1168 unsigned int mark_index = (this+markCoverage).get_coverage (buffer->cur().c odepoint);
1142 if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false); 1169 if (likely (mark_index == NOT_COVERED)) return_trace (false);
1143 1170
1144 /* now we search backwards for a non-mark glyph */ 1171 /* now we search backwards for a non-mark glyph */
1145 hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; 1172 hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
1146 skippy_iter.reset (buffer->idx, 1); 1173 skippy_iter.reset (buffer->idx, 1);
1147 skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks); 1174 skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks);
1148 if (!skippy_iter.prev ()) return TRACE_RETURN (false); 1175 if (!skippy_iter.prev ()) return_trace (false);
1149 1176
1150 /* Checking that matched glyph is actually a ligature by GDEF is too strong; disabled */ 1177 /* Checking that matched glyph is actually a ligature by GDEF is too strong; disabled */
1151 if (!_hb_glyph_info_is_ligature (&buffer->info[skippy_iter.idx])) { /*return TRACE_RETURN (false);*/ } 1178 if (!_hb_glyph_info_is_ligature (&buffer->info[skippy_iter.idx])) { /*return _trace (false);*/ }
1152 1179
1153 unsigned int j = skippy_iter.idx; 1180 unsigned int j = skippy_iter.idx;
1154 unsigned int lig_index = (this+ligatureCoverage).get_coverage (buffer->info [j].codepoint); 1181 unsigned int lig_index = (this+ligatureCoverage).get_coverage (buffer->info [j].codepoint);
1155 if (lig_index == NOT_COVERED) return TRACE_RETURN (false); 1182 if (lig_index == NOT_COVERED) return_trace (false);
1156 1183
1157 const LigatureArray& lig_array = this+ligatureArray; 1184 const LigatureArray& lig_array = this+ligatureArray;
1158 const LigatureAttach& lig_attach = lig_array[lig_index]; 1185 const LigatureAttach& lig_attach = lig_array[lig_index];
1159 1186
1160 /* Find component to attach to */ 1187 /* Find component to attach to */
1161 unsigned int comp_count = lig_attach.rows; 1188 unsigned int comp_count = lig_attach.rows;
1162 if (unlikely (!comp_count)) return TRACE_RETURN (false); 1189 if (unlikely (!comp_count)) return_trace (false);
1163 1190
1164 /* We must now check whether the ligature ID of the current mark glyph 1191 /* We must now check whether the ligature ID of the current mark glyph
1165 * is identical to the ligature ID of the found ligature. If yes, we 1192 * is identical to the ligature ID of the found ligature. If yes, we
1166 * can directly use the component index. If not, we attach the mark 1193 * can directly use the component index. If not, we attach the mark
1167 * glyph to the last component of the ligature. */ 1194 * glyph to the last component of the ligature. */
1168 unsigned int comp_index; 1195 unsigned int comp_index;
1169 unsigned int lig_id = _hb_glyph_info_get_lig_id (&buffer->info[j]); 1196 unsigned int lig_id = _hb_glyph_info_get_lig_id (&buffer->info[j]);
1170 unsigned int mark_id = _hb_glyph_info_get_lig_id (&buffer->cur()); 1197 unsigned int mark_id = _hb_glyph_info_get_lig_id (&buffer->cur());
1171 unsigned int mark_comp = _hb_glyph_info_get_lig_comp (&buffer->cur()); 1198 unsigned int mark_comp = _hb_glyph_info_get_lig_comp (&buffer->cur());
1172 if (lig_id && lig_id == mark_id && mark_comp > 0) 1199 if (lig_id && lig_id == mark_id && mark_comp > 0)
1173 comp_index = MIN (comp_count, _hb_glyph_info_get_lig_comp (&buffer->cur()) ) - 1; 1200 comp_index = MIN (comp_count, _hb_glyph_info_get_lig_comp (&buffer->cur()) ) - 1;
1174 else 1201 else
1175 comp_index = comp_count - 1; 1202 comp_index = comp_count - 1;
1176 1203
1177 return TRACE_RETURN ((this+markArray).apply (c, mark_index, comp_index, lig_ attach, classCount, j)); 1204 return_trace ((this+markArray).apply (c, mark_index, comp_index, lig_attach, classCount, j));
1178 } 1205 }
1179 1206
1180 inline bool sanitize (hb_sanitize_context_t *c) const 1207 inline bool sanitize (hb_sanitize_context_t *c) const
1181 { 1208 {
1182 TRACE_SANITIZE (this); 1209 TRACE_SANITIZE (this);
1183 return TRACE_RETURN (c->check_struct (this) && markCoverage.sanitize (c, thi s) && ligatureCoverage.sanitize (c, this) && 1210 return_trace (c->check_struct (this) &&
1184 » » » markArray.sanitize (c, this) && ligatureArray.sanitize (c, this, (unsigned int) classCount)); 1211 » » markCoverage.sanitize (c, this) &&
1212 » » ligatureCoverage.sanitize (c, this) &&
1213 » » markArray.sanitize (c, this) &&
1214 » » ligatureArray.sanitize (c, this, (unsigned int) classCount));
1185 } 1215 }
1186 1216
1187 protected: 1217 protected:
1188 USHORT format; /* Format identifier--format = 1 */ 1218 USHORT format; /* Format identifier--format = 1 */
1189 OffsetTo<Coverage> 1219 OffsetTo<Coverage>
1190 markCoverage; /* Offset to Mark Coverage table--from 1220 markCoverage; /* Offset to Mark Coverage table--from
1191 * beginning of MarkLigPos subtable */ 1221 * beginning of MarkLigPos subtable */
1192 OffsetTo<Coverage> 1222 OffsetTo<Coverage>
1193 ligatureCoverage; /* Offset to Ligature Coverage 1223 ligatureCoverage; /* Offset to Ligature Coverage
1194 * table--from beginning of MarkLigPos 1224 * table--from beginning of MarkLigPos
1195 * subtable */ 1225 * subtable */
1196 USHORT classCount; /* Number of defined mark classes */ 1226 USHORT classCount; /* Number of defined mark classes */
1197 OffsetTo<MarkArray> 1227 OffsetTo<MarkArray>
1198 markArray; /* Offset to MarkArray table--from 1228 markArray; /* Offset to MarkArray table--from
1199 * beginning of MarkLigPos subtable */ 1229 * beginning of MarkLigPos subtable */
1200 OffsetTo<LigatureArray> 1230 OffsetTo<LigatureArray>
1201 ligatureArray; /* Offset to LigatureArray table--from 1231 ligatureArray; /* Offset to LigatureArray table--from
1202 * beginning of MarkLigPos subtable */ 1232 * beginning of MarkLigPos subtable */
1203 public: 1233 public:
1204 DEFINE_SIZE_STATIC (12); 1234 DEFINE_SIZE_STATIC (12);
1205 }; 1235 };
1206 1236
1207 struct MarkLigPos 1237 struct MarkLigPos
1208 { 1238 {
1209 template <typename context_t> 1239 template <typename context_t>
1210 inline typename context_t::return_t dispatch (context_t *c) const 1240 inline typename context_t::return_t dispatch (context_t *c) const
1211 { 1241 {
1212 TRACE_DISPATCH (this, u.format); 1242 TRACE_DISPATCH (this, u.format);
1213 if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_ return_value ()); 1243 if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispa tch_return_value ());
1214 switch (u.format) { 1244 switch (u.format) {
1215 case 1: return TRACE_RETURN (c->dispatch (u.format1)); 1245 case 1: return_trace (c->dispatch (u.format1));
1216 default:return TRACE_RETURN (c->default_return_value ()); 1246 default:return_trace (c->default_return_value ());
1217 } 1247 }
1218 } 1248 }
1219 1249
1220 protected: 1250 protected:
1221 union { 1251 union {
1222 USHORT format; /* Format identifier */ 1252 USHORT format; /* Format identifier */
1223 MarkLigPosFormat1 format1; 1253 MarkLigPosFormat1 format1;
1224 } u; 1254 } u;
1225 }; 1255 };
1226 1256
(...skipping 15 matching lines...) Expand all
1242 inline const Coverage &get_coverage (void) const 1272 inline const Coverage &get_coverage (void) const
1243 { 1273 {
1244 return this+mark1Coverage; 1274 return this+mark1Coverage;
1245 } 1275 }
1246 1276
1247 inline bool apply (hb_apply_context_t *c) const 1277 inline bool apply (hb_apply_context_t *c) const
1248 { 1278 {
1249 TRACE_APPLY (this); 1279 TRACE_APPLY (this);
1250 hb_buffer_t *buffer = c->buffer; 1280 hb_buffer_t *buffer = c->buffer;
1251 unsigned int mark1_index = (this+mark1Coverage).get_coverage (buffer->cur() .codepoint); 1281 unsigned int mark1_index = (this+mark1Coverage).get_coverage (buffer->cur() .codepoint);
1252 if (likely (mark1_index == NOT_COVERED)) return TRACE_RETURN (false); 1282 if (likely (mark1_index == NOT_COVERED)) return_trace (false);
1253 1283
1254 /* now we search backwards for a suitable mark glyph until a non-mark glyph */ 1284 /* now we search backwards for a suitable mark glyph until a non-mark glyph */
1255 hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; 1285 hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
1256 skippy_iter.reset (buffer->idx, 1); 1286 skippy_iter.reset (buffer->idx, 1);
1257 skippy_iter.set_lookup_props (c->lookup_props & ~LookupFlag::IgnoreFlags); 1287 skippy_iter.set_lookup_props (c->lookup_props & ~LookupFlag::IgnoreFlags);
1258 if (!skippy_iter.prev ()) return TRACE_RETURN (false); 1288 if (!skippy_iter.prev ()) return_trace (false);
1259 1289
1260 if (!_hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx])) { return TRACE _RETURN (false); } 1290 if (!_hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx])) { return_trace (false); }
1261 1291
1262 unsigned int j = skippy_iter.idx; 1292 unsigned int j = skippy_iter.idx;
1263 1293
1264 unsigned int id1 = _hb_glyph_info_get_lig_id (&buffer->cur()); 1294 unsigned int id1 = _hb_glyph_info_get_lig_id (&buffer->cur());
1265 unsigned int id2 = _hb_glyph_info_get_lig_id (&buffer->info[j]); 1295 unsigned int id2 = _hb_glyph_info_get_lig_id (&buffer->info[j]);
1266 unsigned int comp1 = _hb_glyph_info_get_lig_comp (&buffer->cur()); 1296 unsigned int comp1 = _hb_glyph_info_get_lig_comp (&buffer->cur());
1267 unsigned int comp2 = _hb_glyph_info_get_lig_comp (&buffer->info[j]); 1297 unsigned int comp2 = _hb_glyph_info_get_lig_comp (&buffer->info[j]);
1268 1298
1269 if (likely (id1 == id2)) { 1299 if (likely (id1 == id2)) {
1270 if (id1 == 0) /* Marks belonging to the same base. */ 1300 if (id1 == 0) /* Marks belonging to the same base. */
1271 goto good; 1301 goto good;
1272 else if (comp1 == comp2) /* Marks belonging to the same ligature component . */ 1302 else if (comp1 == comp2) /* Marks belonging to the same ligature component . */
1273 goto good; 1303 goto good;
1274 } else { 1304 } else {
1275 /* If ligature ids don't match, it may be the case that one of the marks 1305 /* If ligature ids don't match, it may be the case that one of the marks
1276 * itself is a ligature. In which case match. */ 1306 * itself is a ligature. In which case match. */
1277 if ((id1 > 0 && !comp1) || (id2 > 0 && !comp2)) 1307 if ((id1 > 0 && !comp1) || (id2 > 0 && !comp2))
1278 goto good; 1308 goto good;
1279 } 1309 }
1280 1310
1281 /* Didn't match. */ 1311 /* Didn't match. */
1282 return TRACE_RETURN (false); 1312 return_trace (false);
1283 1313
1284 good: 1314 good:
1285 unsigned int mark2_index = (this+mark2Coverage).get_coverage (buffer->info[ j].codepoint); 1315 unsigned int mark2_index = (this+mark2Coverage).get_coverage (buffer->info[ j].codepoint);
1286 if (mark2_index == NOT_COVERED) return TRACE_RETURN (false); 1316 if (mark2_index == NOT_COVERED) return_trace (false);
1287 1317
1288 return TRACE_RETURN ((this+mark1Array).apply (c, mark1_index, mark2_index, t his+mark2Array, classCount, j)); 1318 return_trace ((this+mark1Array).apply (c, mark1_index, mark2_index, this+mar k2Array, classCount, j));
1289 } 1319 }
1290 1320
1291 inline bool sanitize (hb_sanitize_context_t *c) const 1321 inline bool sanitize (hb_sanitize_context_t *c) const
1292 { 1322 {
1293 TRACE_SANITIZE (this); 1323 TRACE_SANITIZE (this);
1294 return TRACE_RETURN (c->check_struct (this) && mark1Coverage.sanitize (c, th is) && 1324 return_trace (c->check_struct (this) &&
1295 » » » mark2Coverage.sanitize (c, this) && mark1Array.sanitize (c, this) 1325 » » mark1Coverage.sanitize (c, this) &&
1296 » » » && mark2Array.sanitize (c, this, (unsigned int) classCo unt)); 1326 » » mark2Coverage.sanitize (c, this) &&
1327 » » mark1Array.sanitize (c, this) &&
1328 » » mark2Array.sanitize (c, this, (unsigned int) classCount));
1297 } 1329 }
1298 1330
1299 protected: 1331 protected:
1300 USHORT format; /* Format identifier--format = 1 */ 1332 USHORT format; /* Format identifier--format = 1 */
1301 OffsetTo<Coverage> 1333 OffsetTo<Coverage>
1302 mark1Coverage; /* Offset to Combining Mark1 Coverage 1334 mark1Coverage; /* Offset to Combining Mark1 Coverage
1303 * table--from beginning of MarkMarkPos 1335 * table--from beginning of MarkMarkPos
1304 * subtable */ 1336 * subtable */
1305 OffsetTo<Coverage> 1337 OffsetTo<Coverage>
1306 mark2Coverage; /* Offset to Combining Mark2 Coverage 1338 mark2Coverage; /* Offset to Combining Mark2 Coverage
1307 * table--from beginning of MarkMarkPos 1339 * table--from beginning of MarkMarkPos
1308 * subtable */ 1340 * subtable */
1309 USHORT classCount; /* Number of defined mark classes */ 1341 USHORT classCount; /* Number of defined mark classes */
1310 OffsetTo<MarkArray> 1342 OffsetTo<MarkArray>
1311 mark1Array; /* Offset to Mark1Array table--from 1343 mark1Array; /* Offset to Mark1Array table--from
1312 * beginning of MarkMarkPos subtable */ 1344 * beginning of MarkMarkPos subtable */
1313 OffsetTo<Mark2Array> 1345 OffsetTo<Mark2Array>
1314 mark2Array; /* Offset to Mark2Array table--from 1346 mark2Array; /* Offset to Mark2Array table--from
1315 * beginning of MarkMarkPos subtable */ 1347 * beginning of MarkMarkPos subtable */
1316 public: 1348 public:
1317 DEFINE_SIZE_STATIC (12); 1349 DEFINE_SIZE_STATIC (12);
1318 }; 1350 };
1319 1351
1320 struct MarkMarkPos 1352 struct MarkMarkPos
1321 { 1353 {
1322 template <typename context_t> 1354 template <typename context_t>
1323 inline typename context_t::return_t dispatch (context_t *c) const 1355 inline typename context_t::return_t dispatch (context_t *c) const
1324 { 1356 {
1325 TRACE_DISPATCH (this, u.format); 1357 TRACE_DISPATCH (this, u.format);
1326 if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_ return_value ()); 1358 if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispa tch_return_value ());
1327 switch (u.format) { 1359 switch (u.format) {
1328 case 1: return TRACE_RETURN (c->dispatch (u.format1)); 1360 case 1: return_trace (c->dispatch (u.format1));
1329 default:return TRACE_RETURN (c->default_return_value ()); 1361 default:return_trace (c->default_return_value ());
1330 } 1362 }
1331 } 1363 }
1332 1364
1333 protected: 1365 protected:
1334 union { 1366 union {
1335 USHORT format; /* Format identifier */ 1367 USHORT format; /* Format identifier */
1336 MarkMarkPosFormat1 format1; 1368 MarkMarkPosFormat1 format1;
1337 } u; 1369 } u;
1338 }; 1370 };
1339 1371
(...skipping 27 matching lines...) Expand all
1367 MarkMark = 6, 1399 MarkMark = 6,
1368 Context = 7, 1400 Context = 7,
1369 ChainContext = 8, 1401 ChainContext = 8,
1370 Extension = 9 1402 Extension = 9
1371 }; 1403 };
1372 1404
1373 template <typename context_t> 1405 template <typename context_t>
1374 inline typename context_t::return_t dispatch (context_t *c, unsigned int looku p_type) const 1406 inline typename context_t::return_t dispatch (context_t *c, unsigned int looku p_type) const
1375 { 1407 {
1376 TRACE_DISPATCH (this, lookup_type); 1408 TRACE_DISPATCH (this, lookup_type);
1377 /* The sub_format passed to may_dispatch is unnecessary but harmless. */ 1409 if (unlikely (!c->may_dispatch (this, &u.sub_format))) return_trace (c->no_d ispatch_return_value ());
1378 if (unlikely (!c->may_dispatch (this, &u.sub_format))) TRACE_RETURN (c->defa ult_return_value ());
1379 switch (lookup_type) { 1410 switch (lookup_type) {
1380 case Single:» » return TRACE_RETURN (u.single.dispatch (c)); 1411 case Single:» » return_trace (u.single.dispatch (c));
1381 case Pair:» » » return TRACE_RETURN (u.pair.dispatch (c)); 1412 case Pair:» » » return_trace (u.pair.dispatch (c));
1382 case Cursive:» » return TRACE_RETURN (u.cursive.dispatch (c)); 1413 case Cursive:» » return_trace (u.cursive.dispatch (c));
1383 case MarkBase:» » return TRACE_RETURN (u.markBase.dispatch (c)); 1414 case MarkBase:» » return_trace (u.markBase.dispatch (c));
1384 case MarkLig:» » return TRACE_RETURN (u.markLig.dispatch (c)); 1415 case MarkLig:» » return_trace (u.markLig.dispatch (c));
1385 case MarkMark:» » return TRACE_RETURN (u.markMark.dispatch (c)); 1416 case MarkMark:» » return_trace (u.markMark.dispatch (c));
1386 case Context:» » return TRACE_RETURN (u.context.dispatch (c)); 1417 case Context:» » return_trace (u.context.dispatch (c));
1387 case ChainContext:» » return TRACE_RETURN (u.chainContext.dispatch (c) ); 1418 case ChainContext:» » return_trace (u.chainContext.dispatch (c));
1388 case Extension:» » return TRACE_RETURN (u.extension.dispatch (c)); 1419 case Extension:» » return_trace (u.extension.dispatch (c));
1389 default:» » » return TRACE_RETURN (c->default_return_value ()) ; 1420 default:» » » return_trace (c->default_return_value ());
1390 } 1421 }
1391 } 1422 }
1392 1423
1393 protected: 1424 protected:
1394 union { 1425 union {
1395 USHORT sub_format; 1426 USHORT sub_format;
1396 SinglePos single; 1427 SinglePos single;
1397 PairPos pair; 1428 PairPos pair;
1398 CursivePos cursive; 1429 CursivePos cursive;
1399 MarkBasePos markBase; 1430 MarkBasePos markBase;
(...skipping 14 matching lines...) Expand all
1414 { return Lookup::get_subtable<PosLookupSubTable> (i); } 1445 { return Lookup::get_subtable<PosLookupSubTable> (i); }
1415 1446
1416 inline bool is_reverse (void) const 1447 inline bool is_reverse (void) const
1417 { 1448 {
1418 return false; 1449 return false;
1419 } 1450 }
1420 1451
1421 inline bool apply (hb_apply_context_t *c) const 1452 inline bool apply (hb_apply_context_t *c) const
1422 { 1453 {
1423 TRACE_APPLY (this); 1454 TRACE_APPLY (this);
1424 return TRACE_RETURN (dispatch (c)); 1455 return_trace (dispatch (c));
1425 } 1456 }
1426 1457
1427 inline hb_collect_glyphs_context_t::return_t collect_glyphs (hb_collect_glyphs _context_t *c) const 1458 inline hb_collect_glyphs_context_t::return_t collect_glyphs (hb_collect_glyphs _context_t *c) const
1428 { 1459 {
1429 TRACE_COLLECT_GLYPHS (this); 1460 TRACE_COLLECT_GLYPHS (this);
1430 return TRACE_RETURN (dispatch (c)); 1461 return_trace (dispatch (c));
1431 } 1462 }
1432 1463
1433 template <typename set_t> 1464 template <typename set_t>
1434 inline void add_coverage (set_t *glyphs) const 1465 inline void add_coverage (set_t *glyphs) const
1435 { 1466 {
1436 hb_add_coverage_context_t<set_t> c (glyphs); 1467 hb_add_coverage_context_t<set_t> c (glyphs);
1437 dispatch (&c); 1468 dispatch (&c);
1438 } 1469 }
1439 1470
1440 static bool apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_ind ex); 1471 static bool apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_ind ex);
1441 1472
1442 template <typename context_t> 1473 template <typename context_t>
1443 static inline typename context_t::return_t dispatch_recurse_func (context_t *c , unsigned int lookup_index); 1474 static inline typename context_t::return_t dispatch_recurse_func (context_t *c , unsigned int lookup_index);
1444 1475
1445 template <typename context_t> 1476 template <typename context_t>
1446 inline typename context_t::return_t dispatch (context_t *c) const 1477 inline typename context_t::return_t dispatch (context_t *c) const
1447 { return Lookup::dispatch<PosLookupSubTable> (c); } 1478 { return Lookup::dispatch<PosLookupSubTable> (c); }
1448 1479
1449 inline bool sanitize (hb_sanitize_context_t *c) const 1480 inline bool sanitize (hb_sanitize_context_t *c) const
1450 { 1481 {
1451 TRACE_SANITIZE (this); 1482 TRACE_SANITIZE (this);
1452 if (unlikely (!Lookup::sanitize (c))) return TRACE_RETURN (false); 1483 if (unlikely (!Lookup::sanitize (c))) return_trace (false);
1453 return TRACE_RETURN (dispatch (c)); 1484 return_trace (dispatch (c));
1454 } 1485 }
1455 }; 1486 };
1456 1487
1457 typedef OffsetListOf<PosLookup> PosLookupList; 1488 typedef OffsetListOf<PosLookup> PosLookupList;
1458 1489
1459 /* 1490 /*
1460 * GPOS -- The Glyph Positioning Table 1491 * GPOS -- The Glyph Positioning Table
1461 */ 1492 */
1462 1493
1463 struct GPOS : GSUBGPOS 1494 struct GPOS : GSUBGPOS
1464 { 1495 {
1465 static const hb_tag_t tableTag = HB_OT_TAG_GPOS; 1496 static const hb_tag_t tableTag = HB_OT_TAG_GPOS;
1466 1497
1467 inline const PosLookup& get_lookup (unsigned int i) const 1498 inline const PosLookup& get_lookup (unsigned int i) const
1468 { return CastR<PosLookup> (GSUBGPOS::get_lookup (i)); } 1499 { return CastR<PosLookup> (GSUBGPOS::get_lookup (i)); }
1469 1500
1470 static inline void position_start (hb_font_t *font, hb_buffer_t *buffer); 1501 static inline void position_start (hb_font_t *font, hb_buffer_t *buffer);
1471 static inline void position_finish (hb_font_t *font, hb_buffer_t *buffer); 1502 static inline void position_finish (hb_font_t *font, hb_buffer_t *buffer);
1472 1503
1473 inline bool sanitize (hb_sanitize_context_t *c) const 1504 inline bool sanitize (hb_sanitize_context_t *c) const
1474 { 1505 {
1475 TRACE_SANITIZE (this); 1506 TRACE_SANITIZE (this);
1476 if (unlikely (!GSUBGPOS::sanitize (c))) return TRACE_RETURN (false); 1507 if (unlikely (!GSUBGPOS::sanitize (c))) return_trace (false);
1477 const OffsetTo<PosLookupList> &list = CastR<OffsetTo<PosLookupList> > (looku pList); 1508 const OffsetTo<PosLookupList> &list = CastR<OffsetTo<PosLookupList> > (looku pList);
1478 return TRACE_RETURN (list.sanitize (c, this)); 1509 return_trace (list.sanitize (c, this));
1479 } 1510 }
1480 public: 1511 public:
1481 DEFINE_SIZE_STATIC (10); 1512 DEFINE_SIZE_STATIC (10);
1482 }; 1513 };
1483 1514
1484 1515
1485 static void 1516 static void
1517 reverse_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direc tion_t direction, unsigned int new_parent)
1518 {
1519 unsigned int j = pos[i].cursive_chain();
1520 if (likely (!j))
1521 return;
1522
1523 j += i;
1524
1525 pos[i].cursive_chain() = 0;
1526
1527 /* Stop if we see new parent in the chain. */
1528 if (j == new_parent)
1529 return;
1530
1531 reverse_cursive_minor_offset (pos, j, direction, new_parent);
1532
1533 if (HB_DIRECTION_IS_HORIZONTAL (direction))
1534 pos[j].y_offset = -pos[i].y_offset;
1535 else
1536 pos[j].x_offset = -pos[i].x_offset;
1537
1538 pos[j].cursive_chain() = i - j;
1539 }
1540 static void
1486 fix_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direction _t direction) 1541 fix_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direction _t direction)
1487 { 1542 {
1488 unsigned int j = pos[i].cursive_chain(); 1543 unsigned int j = pos[i].cursive_chain();
1489 if (likely (!j)) 1544 if (likely (!j))
1490 return; 1545 return;
1491 1546
1492 j += i; 1547 j += i;
1493 1548
1494 pos[i].cursive_chain() = 0; 1549 pos[i].cursive_chain() = 0;
1495 1550
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1579 1634
1580 1635
1581 #undef attach_lookback 1636 #undef attach_lookback
1582 #undef cursive_chain 1637 #undef cursive_chain
1583 1638
1584 1639
1585 } /* namespace OT */ 1640 } /* namespace OT */
1586 1641
1587 1642
1588 #endif /* HB_OT_LAYOUT_GPOS_TABLE_HH */ 1643 #endif /* HB_OT_LAYOUT_GPOS_TABLE_HH */
OLDNEW
« no previous file with comments | « third_party/harfbuzz-ng/src/hb-ot-layout-gdef-table.hh ('k') | third_party/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698