OLD | NEW |
1 /* | 1 /* |
2 * Copyright © 2007,2008,2009,2010 Red Hat, Inc. | 2 * Copyright © 2007,2008,2009,2010 Red Hat, Inc. |
3 * Copyright © 2010 Google, Inc. | 3 * Copyright © 2010,2012 Google, Inc. |
4 * | 4 * |
5 * This is part of HarfBuzz, a text shaping library. | 5 * This is part of HarfBuzz, a text shaping library. |
6 * | 6 * |
7 * Permission is hereby granted, without written agreement and without | 7 * Permission is hereby granted, without written agreement and without |
8 * license or royalty fees, to use, copy, modify, and distribute this | 8 * license or royalty fees, to use, copy, modify, and distribute this |
9 * software and its documentation for any purpose, provided that the | 9 * software and its documentation for any purpose, provided that the |
10 * above copyright notice and the following two paragraphs appear in | 10 * above copyright notice and the following two paragraphs appear in |
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 |
(...skipping 25 matching lines...) Expand all Loading... |
39 | 39 |
40 | 40 |
41 /* Shared Tables: ValueRecord, Anchor Table, and MarkArray */ | 41 /* Shared Tables: ValueRecord, Anchor Table, and MarkArray */ |
42 | 42 |
43 typedef USHORT Value; | 43 typedef USHORT Value; |
44 | 44 |
45 typedef Value ValueRecord[VAR]; | 45 typedef Value ValueRecord[VAR]; |
46 | 46 |
47 struct ValueFormat : USHORT | 47 struct ValueFormat : USHORT |
48 { | 48 { |
49 enum | 49 enum Flags { |
50 { | |
51 xPlacement = 0x0001, /* Includes horizontal adjustment for placement
*/ | 50 xPlacement = 0x0001, /* Includes horizontal adjustment for placement
*/ |
52 yPlacement = 0x0002, /* Includes vertical adjustment for placement */ | 51 yPlacement = 0x0002, /* Includes vertical adjustment for placement */ |
53 xAdvance = 0x0004, /* Includes horizontal adjustment for advance */ | 52 xAdvance = 0x0004, /* Includes horizontal adjustment for advance */ |
54 yAdvance = 0x0008, /* Includes vertical adjustment for advance */ | 53 yAdvance = 0x0008, /* Includes vertical adjustment for advance */ |
55 xPlaDevice = 0x0010, /* Includes horizontal Device table for placemen
t */ | 54 xPlaDevice = 0x0010, /* Includes horizontal Device table for placemen
t */ |
56 yPlaDevice = 0x0020, /* Includes vertical Device table for placement
*/ | 55 yPlaDevice = 0x0020, /* Includes vertical Device table for placement
*/ |
57 xAdvDevice = 0x0040, /* Includes horizontal Device table for advance
*/ | 56 xAdvDevice = 0x0040, /* Includes horizontal Device table for advance
*/ |
58 yAdvDevice = 0x0080, /* Includes vertical Device table for advance */ | 57 yAdvDevice = 0x0080, /* Includes vertical Device table for advance */ |
59 ignored = 0x0F00, /* Was used in TrueType Open for MM fonts */ | 58 ignored = 0x0F00, /* Was used in TrueType Open for MM fonts */ |
60 reserved = 0xF000, /* For future use */ | 59 reserved = 0xF000, /* For future use */ |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
165 | 164 |
166 public: | 165 public: |
167 | 166 |
168 inline bool has_device (void) const { | 167 inline bool has_device (void) const { |
169 unsigned int format = *this; | 168 unsigned int format = *this; |
170 return (format & devices) != 0; | 169 return (format & devices) != 0; |
171 } | 170 } |
172 | 171 |
173 inline bool sanitize_value (hb_sanitize_context_t *c, void *base, Value *value
s) { | 172 inline bool sanitize_value (hb_sanitize_context_t *c, void *base, Value *value
s) { |
174 TRACE_SANITIZE (); | 173 TRACE_SANITIZE (); |
175 return c->check_range (values, get_size ()) | 174 return TRACE_RETURN (c->check_range (values, get_size ()) && (!has_device ()
|| sanitize_value_devices (c, base, values))); |
176 » && (!has_device () || sanitize_value_devices (c, base, values)); | |
177 } | 175 } |
178 | 176 |
179 inline bool sanitize_values (hb_sanitize_context_t *c, void *base, Value *valu
es, unsigned int count) { | 177 inline bool sanitize_values (hb_sanitize_context_t *c, void *base, Value *valu
es, unsigned int count) { |
180 TRACE_SANITIZE (); | 178 TRACE_SANITIZE (); |
181 unsigned int len = get_len (); | 179 unsigned int len = get_len (); |
182 | 180 |
183 if (!c->check_array (values, get_size (), count)) return false; | 181 if (!c->check_array (values, get_size (), count)) return TRACE_RETURN (false
); |
184 | 182 |
185 if (!has_device ()) return true; | 183 if (!has_device ()) return TRACE_RETURN (true); |
186 | 184 |
187 for (unsigned int i = 0; i < count; i++) { | 185 for (unsigned int i = 0; i < count; i++) { |
188 if (!sanitize_value_devices (c, base, values)) | 186 if (!sanitize_value_devices (c, base, values)) |
189 return false; | 187 return TRACE_RETURN (false); |
190 values += len; | 188 values += len; |
191 } | 189 } |
192 | 190 |
193 return true; | 191 return TRACE_RETURN (true); |
194 } | 192 } |
195 | 193 |
196 /* Just sanitize referenced Device tables. Doesn't check the values themselve
s. */ | 194 /* Just sanitize referenced Device tables. Doesn't check the values themselve
s. */ |
197 inline bool sanitize_values_stride_unsafe (hb_sanitize_context_t *c, void *bas
e, Value *values, unsigned int count, unsigned int stride) { | 195 inline bool sanitize_values_stride_unsafe (hb_sanitize_context_t *c, void *bas
e, Value *values, unsigned int count, unsigned int stride) { |
198 TRACE_SANITIZE (); | 196 TRACE_SANITIZE (); |
199 | 197 |
200 if (!has_device ()) return true; | 198 if (!has_device ()) return TRACE_RETURN (true); |
201 | 199 |
202 for (unsigned int i = 0; i < count; i++) { | 200 for (unsigned int i = 0; i < count; i++) { |
203 if (!sanitize_value_devices (c, base, values)) | 201 if (!sanitize_value_devices (c, base, values)) |
204 return false; | 202 return TRACE_RETURN (false); |
205 values += stride; | 203 values += stride; |
206 } | 204 } |
207 | 205 |
208 return true; | 206 return TRACE_RETURN (true); |
209 } | 207 } |
210 }; | 208 }; |
211 | 209 |
212 | 210 |
213 struct AnchorFormat1 | 211 struct AnchorFormat1 |
214 { | 212 { |
215 friend struct Anchor; | 213 friend struct Anchor; |
216 | 214 |
217 private: | 215 private: |
218 inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id HB_UNUSED, | 216 inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id HB_UNUSED, |
219 hb_position_t *x, hb_position_t *y) const | 217 hb_position_t *x, hb_position_t *y) const |
220 { | 218 { |
221 *x = font->em_scale_x (xCoordinate); | 219 *x = font->em_scale_x (xCoordinate); |
222 *y = font->em_scale_y (yCoordinate); | 220 *y = font->em_scale_y (yCoordinate); |
223 } | 221 } |
224 | 222 |
225 inline bool sanitize (hb_sanitize_context_t *c) { | 223 inline bool sanitize (hb_sanitize_context_t *c) { |
226 TRACE_SANITIZE (); | 224 TRACE_SANITIZE (); |
227 return c->check_struct (this); | 225 return TRACE_RETURN (c->check_struct (this)); |
228 } | 226 } |
229 | 227 |
230 private: | 228 private: |
231 USHORT format; /* Format identifier--format = 1 */ | 229 USHORT format; /* Format identifier--format = 1 */ |
232 SHORT xCoordinate; /* Horizontal value--in design units */ | 230 SHORT xCoordinate; /* Horizontal value--in design units */ |
233 SHORT yCoordinate; /* Vertical value--in design units */ | 231 SHORT yCoordinate; /* Vertical value--in design units */ |
234 public: | 232 public: |
235 DEFINE_SIZE_STATIC (6); | 233 DEFINE_SIZE_STATIC (6); |
236 }; | 234 }; |
237 | 235 |
(...skipping 11 matching lines...) Expand all Loading... |
249 hb_bool_t ret = false; | 247 hb_bool_t ret = false; |
250 | 248 |
251 if (x_ppem || y_ppem) | 249 if (x_ppem || y_ppem) |
252 ret = hb_font_get_glyph_contour_point_for_origin (font, glyph_id, anchor
Point, HB_DIRECTION_LTR, &cx, &cy); | 250 ret = hb_font_get_glyph_contour_point_for_origin (font, glyph_id, anchor
Point, HB_DIRECTION_LTR, &cx, &cy); |
253 *x = x_ppem && ret ? cx : font->em_scale_x (xCoordinate); | 251 *x = x_ppem && ret ? cx : font->em_scale_x (xCoordinate); |
254 *y = y_ppem && ret ? cy : font->em_scale_y (yCoordinate); | 252 *y = y_ppem && ret ? cy : font->em_scale_y (yCoordinate); |
255 } | 253 } |
256 | 254 |
257 inline bool sanitize (hb_sanitize_context_t *c) { | 255 inline bool sanitize (hb_sanitize_context_t *c) { |
258 TRACE_SANITIZE (); | 256 TRACE_SANITIZE (); |
259 return c->check_struct (this); | 257 return TRACE_RETURN (c->check_struct (this)); |
260 } | 258 } |
261 | 259 |
262 private: | 260 private: |
263 USHORT format; /* Format identifier--format = 2 */ | 261 USHORT format; /* Format identifier--format = 2 */ |
264 SHORT xCoordinate; /* Horizontal value--in design units */ | 262 SHORT xCoordinate; /* Horizontal value--in design units */ |
265 SHORT yCoordinate; /* Vertical value--in design units */ | 263 SHORT yCoordinate; /* Vertical value--in design units */ |
266 USHORT anchorPoint; /* Index to glyph contour point */ | 264 USHORT anchorPoint; /* Index to glyph contour point */ |
267 public: | 265 public: |
268 DEFINE_SIZE_STATIC (8); | 266 DEFINE_SIZE_STATIC (8); |
269 }; | 267 }; |
(...skipping 10 matching lines...) Expand all Loading... |
280 *y = font->em_scale_y (yCoordinate); | 278 *y = font->em_scale_y (yCoordinate); |
281 | 279 |
282 if (font->x_ppem) | 280 if (font->x_ppem) |
283 *x += (this+xDeviceTable).get_x_delta (font); | 281 *x += (this+xDeviceTable).get_x_delta (font); |
284 if (font->y_ppem) | 282 if (font->y_ppem) |
285 *y += (this+yDeviceTable).get_x_delta (font); | 283 *y += (this+yDeviceTable).get_x_delta (font); |
286 } | 284 } |
287 | 285 |
288 inline bool sanitize (hb_sanitize_context_t *c) { | 286 inline bool sanitize (hb_sanitize_context_t *c) { |
289 TRACE_SANITIZE (); | 287 TRACE_SANITIZE (); |
290 return c->check_struct (this) | 288 return TRACE_RETURN (c->check_struct (this) && xDeviceTable.sanitize (c, thi
s) && yDeviceTable.sanitize (c, this)); |
291 » && xDeviceTable.sanitize (c, this) | |
292 » && yDeviceTable.sanitize (c, this); | |
293 } | 289 } |
294 | 290 |
295 private: | 291 private: |
296 USHORT format; /* Format identifier--format = 3 */ | 292 USHORT format; /* Format identifier--format = 3 */ |
297 SHORT xCoordinate; /* Horizontal value--in design units */ | 293 SHORT xCoordinate; /* Horizontal value--in design units */ |
298 SHORT yCoordinate; /* Vertical value--in design units */ | 294 SHORT yCoordinate; /* Vertical value--in design units */ |
299 OffsetTo<Device> | 295 OffsetTo<Device> |
300 xDeviceTable; /* Offset to Device table for X | 296 xDeviceTable; /* Offset to Device table for X |
301 * coordinate-- from beginning of | 297 * coordinate-- from beginning of |
302 * Anchor table (may be NULL) */ | 298 * Anchor table (may be NULL) */ |
(...skipping 14 matching lines...) Expand all Loading... |
317 switch (u.format) { | 313 switch (u.format) { |
318 case 1: u.format1.get_anchor (font, glyph_id, x, y); return; | 314 case 1: u.format1.get_anchor (font, glyph_id, x, y); return; |
319 case 2: u.format2.get_anchor (font, glyph_id, x, y); return; | 315 case 2: u.format2.get_anchor (font, glyph_id, x, y); return; |
320 case 3: u.format3.get_anchor (font, glyph_id, x, y); return; | 316 case 3: u.format3.get_anchor (font, glyph_id, x, y); return; |
321 default: return; | 317 default: return; |
322 } | 318 } |
323 } | 319 } |
324 | 320 |
325 inline bool sanitize (hb_sanitize_context_t *c) { | 321 inline bool sanitize (hb_sanitize_context_t *c) { |
326 TRACE_SANITIZE (); | 322 TRACE_SANITIZE (); |
327 if (!u.format.sanitize (c)) return false; | 323 if (!u.format.sanitize (c)) return TRACE_RETURN (false); |
328 switch (u.format) { | 324 switch (u.format) { |
329 case 1: return u.format1.sanitize (c); | 325 case 1: return TRACE_RETURN (u.format1.sanitize (c)); |
330 case 2: return u.format2.sanitize (c); | 326 case 2: return TRACE_RETURN (u.format2.sanitize (c)); |
331 case 3: return u.format3.sanitize (c); | 327 case 3: return TRACE_RETURN (u.format3.sanitize (c)); |
332 default:return true; | 328 default:return TRACE_RETURN (true); |
333 } | 329 } |
334 } | 330 } |
335 | 331 |
336 private: | 332 private: |
337 union { | 333 union { |
338 USHORT format; /* Format identifier */ | 334 USHORT format; /* Format identifier */ |
339 AnchorFormat1 format1; | 335 AnchorFormat1 format1; |
340 AnchorFormat2 format2; | 336 AnchorFormat2 format2; |
341 AnchorFormat3 format3; | 337 AnchorFormat3 format3; |
342 } u; | 338 } u; |
343 public: | 339 public: |
344 DEFINE_SIZE_UNION (2, format); | 340 DEFINE_SIZE_UNION (2, format); |
345 }; | 341 }; |
346 | 342 |
347 | 343 |
348 struct AnchorMatrix | 344 struct AnchorMatrix |
349 { | 345 { |
350 inline const Anchor& get_anchor (unsigned int row, unsigned int col, unsigned
int cols) const { | 346 inline const Anchor& get_anchor (unsigned int row, unsigned int col, unsigned
int cols) const { |
351 if (unlikely (row >= rows || col >= cols)) return Null(Anchor); | 347 if (unlikely (row >= rows || col >= cols)) return Null(Anchor); |
352 return this+matrix[row * cols + col]; | 348 return this+matrix[row * cols + col]; |
353 } | 349 } |
354 | 350 |
355 inline bool sanitize (hb_sanitize_context_t *c, unsigned int cols) { | 351 inline bool sanitize (hb_sanitize_context_t *c, unsigned int cols) { |
356 TRACE_SANITIZE (); | 352 TRACE_SANITIZE (); |
357 if (!c->check_struct (this)) return false; | 353 if (!c->check_struct (this)) return TRACE_RETURN (false); |
358 if (unlikely (rows > 0 && cols >= ((unsigned int) -1) / rows)) return false; | 354 if (unlikely (rows > 0 && cols >= ((unsigned int) -1) / rows)) return TRACE_
RETURN (false); |
359 unsigned int count = rows * cols; | 355 unsigned int count = rows * cols; |
360 if (!c->check_array (matrix, matrix[0].static_size, count)) return false; | 356 if (!c->check_array (matrix, matrix[0].static_size, count)) return TRACE_RET
URN (false); |
361 for (unsigned int i = 0; i < count; i++) | 357 for (unsigned int i = 0; i < count; i++) |
362 if (!matrix[i].sanitize (c, this)) return false; | 358 if (!matrix[i].sanitize (c, this)) return TRACE_RETURN (false); |
363 return true; | 359 return TRACE_RETURN (true); |
364 } | 360 } |
365 | 361 |
366 USHORT rows; /* Number of rows */ | 362 USHORT rows; /* Number of rows */ |
367 private: | 363 private: |
368 OffsetTo<Anchor> | 364 OffsetTo<Anchor> |
369 matrix[VAR]; /* Matrix of offsets to Anchor tables-- | 365 matrix[VAR]; /* Matrix of offsets to Anchor tables-- |
370 * from beginning of AnchorMatrix table
*/ | 366 * from beginning of AnchorMatrix table
*/ |
371 public: | 367 public: |
372 DEFINE_SIZE_ARRAY (2, matrix); | 368 DEFINE_SIZE_ARRAY (2, matrix); |
373 }; | 369 }; |
374 | 370 |
375 | 371 |
376 struct MarkRecord | 372 struct MarkRecord |
377 { | 373 { |
378 friend struct MarkArray; | 374 friend struct MarkArray; |
379 | 375 |
380 inline bool sanitize (hb_sanitize_context_t *c, void *base) { | 376 inline bool sanitize (hb_sanitize_context_t *c, void *base) { |
381 TRACE_SANITIZE (); | 377 TRACE_SANITIZE (); |
382 return c->check_struct (this) | 378 return TRACE_RETURN (c->check_struct (this) && markAnchor.sanitize (c, base)
); |
383 » && markAnchor.sanitize (c, base); | |
384 } | 379 } |
385 | 380 |
386 private: | 381 private: |
387 USHORT klass; /* Class defined for this mark */ | 382 USHORT klass; /* Class defined for this mark */ |
388 OffsetTo<Anchor> | 383 OffsetTo<Anchor> |
389 markAnchor; /* Offset to Anchor table--from | 384 markAnchor; /* Offset to Anchor table--from |
390 * beginning of MarkArray table */ | 385 * beginning of MarkArray table */ |
391 public: | 386 public: |
392 DEFINE_SIZE_STATIC (4); | 387 DEFINE_SIZE_STATIC (4); |
393 }; | 388 }; |
394 | 389 |
395 struct MarkArray : ArrayOf<MarkRecord> /* Array of MarkRecords--in Coverage ord
er */ | 390 struct MarkArray : ArrayOf<MarkRecord> /* Array of MarkRecords--in Coverage ord
er */ |
396 { | 391 { |
397 inline bool apply (hb_apply_context_t *c, | 392 inline bool apply (hb_apply_context_t *c, |
398 unsigned int mark_index, unsigned int glyph_index, | 393 unsigned int mark_index, unsigned int glyph_index, |
399 const AnchorMatrix &anchors, unsigned int class_count, | 394 const AnchorMatrix &anchors, unsigned int class_count, |
400 unsigned int glyph_pos) const | 395 unsigned int glyph_pos) const |
401 { | 396 { |
402 TRACE_APPLY (); | 397 TRACE_APPLY (); |
403 const MarkRecord &record = ArrayOf<MarkRecord>::operator[](mark_index); | 398 const MarkRecord &record = ArrayOf<MarkRecord>::operator[](mark_index); |
404 unsigned int mark_class = record.klass; | 399 unsigned int mark_class = record.klass; |
405 | 400 |
406 const Anchor& mark_anchor = this + record.markAnchor; | 401 const Anchor& mark_anchor = this + record.markAnchor; |
407 const Anchor& glyph_anchor = anchors.get_anchor (glyph_index, mark_class, cl
ass_count); | 402 const Anchor& glyph_anchor = anchors.get_anchor (glyph_index, mark_class, cl
ass_count); |
408 | 403 |
409 hb_position_t mark_x, mark_y, base_x, base_y; | 404 hb_position_t mark_x, mark_y, base_x, base_y; |
410 | 405 |
411 mark_anchor.get_anchor (c->font, c->buffer->info[c->buffer->idx].codepoint,
&mark_x, &mark_y); | 406 mark_anchor.get_anchor (c->font, c->buffer->cur().codepoint, &mark_x, &mark_
y); |
412 glyph_anchor.get_anchor (c->font, c->buffer->info[glyph_pos].codepoint, &bas
e_x, &base_y); | 407 glyph_anchor.get_anchor (c->font, c->buffer->info[glyph_pos].codepoint, &bas
e_x, &base_y); |
413 | 408 |
414 hb_glyph_position_t &o = c->buffer->pos[c->buffer->idx]; | 409 hb_glyph_position_t &o = c->buffer->cur_pos(); |
415 o.x_offset = base_x - mark_x; | 410 o.x_offset = base_x - mark_x; |
416 o.y_offset = base_y - mark_y; | 411 o.y_offset = base_y - mark_y; |
417 o.attach_lookback() = c->buffer->idx - glyph_pos; | 412 o.attach_lookback() = c->buffer->idx - glyph_pos; |
418 | 413 |
419 c->buffer->idx++; | 414 c->buffer->idx++; |
420 return true; | 415 return TRACE_RETURN (true); |
421 } | 416 } |
422 | 417 |
423 inline bool sanitize (hb_sanitize_context_t *c) { | 418 inline bool sanitize (hb_sanitize_context_t *c) { |
424 TRACE_SANITIZE (); | 419 TRACE_SANITIZE (); |
425 return ArrayOf<MarkRecord>::sanitize (c, this); | 420 return TRACE_RETURN (ArrayOf<MarkRecord>::sanitize (c, this)); |
426 } | 421 } |
427 }; | 422 }; |
428 | 423 |
429 | 424 |
430 /* Lookups */ | 425 /* Lookups */ |
431 | 426 |
432 struct SinglePosFormat1 | 427 struct SinglePosFormat1 |
433 { | 428 { |
434 friend struct SinglePos; | 429 friend struct SinglePos; |
435 | 430 |
436 private: | 431 private: |
437 inline bool apply (hb_apply_context_t *c) const | 432 inline bool apply (hb_apply_context_t *c) const |
438 { | 433 { |
439 TRACE_APPLY (); | 434 TRACE_APPLY (); |
440 unsigned int index = (this+coverage) (c->buffer->info[c->buffer->idx].codepo
int); | 435 unsigned int index = (this+coverage) (c->buffer->cur().codepoint); |
441 if (likely (index == NOT_COVERED)) | 436 if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); |
442 return false; | |
443 | 437 |
444 valueFormat.apply_value (c->font, c->direction, this, | 438 valueFormat.apply_value (c->font, c->direction, this, |
445 » » » values, c->buffer->pos[c->buffer->idx]); | 439 » » » values, c->buffer->cur_pos()); |
446 | 440 |
447 c->buffer->idx++; | 441 c->buffer->idx++; |
448 return true; | 442 return TRACE_RETURN (true); |
449 } | 443 } |
450 | 444 |
451 inline bool sanitize (hb_sanitize_context_t *c) { | 445 inline bool sanitize (hb_sanitize_context_t *c) { |
452 TRACE_SANITIZE (); | 446 TRACE_SANITIZE (); |
453 return c->check_struct (this) | 447 return TRACE_RETURN (c->check_struct (this) && coverage.sanitize (c, this) &
& valueFormat.sanitize_value (c, this, values)); |
454 » && coverage.sanitize (c, this) | |
455 » && valueFormat.sanitize_value (c, this, values); | |
456 } | 448 } |
457 | 449 |
458 private: | 450 private: |
459 USHORT format; /* Format identifier--format = 1 */ | 451 USHORT format; /* Format identifier--format = 1 */ |
460 OffsetTo<Coverage> | 452 OffsetTo<Coverage> |
461 coverage; /* Offset to Coverage table--from | 453 coverage; /* Offset to Coverage table--from |
462 * beginning of subtable */ | 454 * beginning of subtable */ |
463 ValueFormat valueFormat; /* Defines the types of data in the | 455 ValueFormat valueFormat; /* Defines the types of data in the |
464 * ValueRecord */ | 456 * ValueRecord */ |
465 ValueRecord values; /* Defines positioning | 457 ValueRecord values; /* Defines positioning |
466 * value(s)--applied to all glyphs in | 458 * value(s)--applied to all glyphs in |
467 * the Coverage table */ | 459 * the Coverage table */ |
468 public: | 460 public: |
469 DEFINE_SIZE_ARRAY (6, values); | 461 DEFINE_SIZE_ARRAY (6, values); |
470 }; | 462 }; |
471 | 463 |
472 struct SinglePosFormat2 | 464 struct SinglePosFormat2 |
473 { | 465 { |
474 friend struct SinglePos; | 466 friend struct SinglePos; |
475 | 467 |
476 private: | 468 private: |
477 inline bool apply (hb_apply_context_t *c) const | 469 inline bool apply (hb_apply_context_t *c) const |
478 { | 470 { |
479 TRACE_APPLY (); | 471 TRACE_APPLY (); |
480 unsigned int index = (this+coverage) (c->buffer->info[c->buffer->idx].codepo
int); | 472 unsigned int index = (this+coverage) (c->buffer->cur().codepoint); |
481 if (likely (index == NOT_COVERED)) | 473 if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); |
482 return false; | |
483 | 474 |
484 if (likely (index >= valueCount)) | 475 if (likely (index >= valueCount)) return TRACE_RETURN (false); |
485 return false; | |
486 | 476 |
487 valueFormat.apply_value (c->font, c->direction, this, | 477 valueFormat.apply_value (c->font, c->direction, this, |
488 &values[index * valueFormat.get_len ()], | 478 &values[index * valueFormat.get_len ()], |
489 » » » c->buffer->pos[c->buffer->idx]); | 479 » » » c->buffer->cur_pos()); |
490 | 480 |
491 c->buffer->idx++; | 481 c->buffer->idx++; |
492 return true; | 482 return TRACE_RETURN (true); |
493 } | 483 } |
494 | 484 |
495 inline bool sanitize (hb_sanitize_context_t *c) { | 485 inline bool sanitize (hb_sanitize_context_t *c) { |
496 TRACE_SANITIZE (); | 486 TRACE_SANITIZE (); |
497 return c->check_struct (this) | 487 return TRACE_RETURN (c->check_struct (this) && coverage.sanitize (c, this) &
& valueFormat.sanitize_values (c, this, values, valueCount)); |
498 » && coverage.sanitize (c, this) | |
499 » && valueFormat.sanitize_values (c, this, values, valueCount); | |
500 } | 488 } |
501 | 489 |
502 private: | 490 private: |
503 USHORT format; /* Format identifier--format = 2 */ | 491 USHORT format; /* Format identifier--format = 2 */ |
504 OffsetTo<Coverage> | 492 OffsetTo<Coverage> |
505 coverage; /* Offset to Coverage table--from | 493 coverage; /* Offset to Coverage table--from |
506 * beginning of subtable */ | 494 * beginning of subtable */ |
507 ValueFormat valueFormat; /* Defines the types of data in the | 495 ValueFormat valueFormat; /* Defines the types of data in the |
508 * ValueRecord */ | 496 * ValueRecord */ |
509 USHORT valueCount; /* Number of ValueRecords */ | 497 USHORT valueCount; /* Number of ValueRecords */ |
510 ValueRecord values; /* Array of ValueRecords--positioning | 498 ValueRecord values; /* Array of ValueRecords--positioning |
511 * values applied to glyphs */ | 499 * values applied to glyphs */ |
512 public: | 500 public: |
513 DEFINE_SIZE_ARRAY (8, values); | 501 DEFINE_SIZE_ARRAY (8, values); |
514 }; | 502 }; |
515 | 503 |
516 struct SinglePos | 504 struct SinglePos |
517 { | 505 { |
518 friend struct PosLookupSubTable; | 506 friend struct PosLookupSubTable; |
519 | 507 |
520 private: | 508 private: |
521 inline bool apply (hb_apply_context_t *c) const | 509 inline bool apply (hb_apply_context_t *c) const |
522 { | 510 { |
523 TRACE_APPLY (); | 511 TRACE_APPLY (); |
524 switch (u.format) { | 512 switch (u.format) { |
525 case 1: return u.format1.apply (c); | 513 case 1: return TRACE_RETURN (u.format1.apply (c)); |
526 case 2: return u.format2.apply (c); | 514 case 2: return TRACE_RETURN (u.format2.apply (c)); |
527 default:return false; | 515 default:return TRACE_RETURN (false); |
528 } | 516 } |
529 } | 517 } |
530 | 518 |
531 inline bool sanitize (hb_sanitize_context_t *c) { | 519 inline bool sanitize (hb_sanitize_context_t *c) { |
532 TRACE_SANITIZE (); | 520 TRACE_SANITIZE (); |
533 if (!u.format.sanitize (c)) return false; | 521 if (!u.format.sanitize (c)) return TRACE_RETURN (false); |
534 switch (u.format) { | 522 switch (u.format) { |
535 case 1: return u.format1.sanitize (c); | 523 case 1: return TRACE_RETURN (u.format1.sanitize (c)); |
536 case 2: return u.format2.sanitize (c); | 524 case 2: return TRACE_RETURN (u.format2.sanitize (c)); |
537 default:return true; | 525 default:return TRACE_RETURN (true); |
538 } | 526 } |
539 } | 527 } |
540 | 528 |
541 private: | 529 private: |
542 union { | 530 union { |
543 USHORT format; /* Format identifier */ | 531 USHORT format; /* Format identifier */ |
544 SinglePosFormat1 format1; | 532 SinglePosFormat1 format1; |
545 SinglePosFormat2 format2; | 533 SinglePosFormat2 format2; |
546 } u; | 534 } u; |
547 }; | 535 }; |
(...skipping 26 matching lines...) Expand all Loading... |
574 unsigned int len2 = valueFormats[1].get_len (); | 562 unsigned int len2 = valueFormats[1].get_len (); |
575 unsigned int record_size = USHORT::static_size * (1 + len1 + len2); | 563 unsigned int record_size = USHORT::static_size * (1 + len1 + len2); |
576 | 564 |
577 unsigned int count = len; | 565 unsigned int count = len; |
578 const PairValueRecord *record = CastP<PairValueRecord> (array); | 566 const PairValueRecord *record = CastP<PairValueRecord> (array); |
579 for (unsigned int i = 0; i < count; i++) | 567 for (unsigned int i = 0; i < count; i++) |
580 { | 568 { |
581 if (c->buffer->info[pos].codepoint == record->secondGlyph) | 569 if (c->buffer->info[pos].codepoint == record->secondGlyph) |
582 { | 570 { |
583 valueFormats[0].apply_value (c->font, c->direction, this, | 571 valueFormats[0].apply_value (c->font, c->direction, this, |
584 » » » » &record->values[0], c->buffer->pos[c->buffe
r->idx]); | 572 » » » » &record->values[0], c->buffer->cur_pos()); |
585 valueFormats[1].apply_value (c->font, c->direction, this, | 573 valueFormats[1].apply_value (c->font, c->direction, this, |
586 &record->values[len1], c->buffer->pos[pos])
; | 574 &record->values[len1], c->buffer->pos[pos])
; |
587 if (len2) | 575 if (len2) |
588 pos++; | 576 pos++; |
589 c->buffer->idx = pos; | 577 c->buffer->idx = pos; |
590 » return true; | 578 » return TRACE_RETURN (true); |
591 } | 579 } |
592 record = &StructAtOffset<PairValueRecord> (record, record_size); | 580 record = &StructAtOffset<PairValueRecord> (record, record_size); |
593 } | 581 } |
594 | 582 |
595 return false; | 583 return TRACE_RETURN (false); |
596 } | 584 } |
597 | 585 |
598 struct sanitize_closure_t { | 586 struct sanitize_closure_t { |
599 void *base; | 587 void *base; |
600 ValueFormat *valueFormats; | 588 ValueFormat *valueFormats; |
601 unsigned int len1; /* valueFormats[0].get_len() */ | 589 unsigned int len1; /* valueFormats[0].get_len() */ |
602 unsigned int stride; /* 1 + len1 + len2 */ | 590 unsigned int stride; /* 1 + len1 + len2 */ |
603 }; | 591 }; |
604 | 592 |
605 inline bool sanitize (hb_sanitize_context_t *c, const sanitize_closure_t *clos
ure) { | 593 inline bool sanitize (hb_sanitize_context_t *c, const sanitize_closure_t *clos
ure) { |
606 TRACE_SANITIZE (); | 594 TRACE_SANITIZE (); |
607 if (!(c->check_struct (this) | 595 if (!(c->check_struct (this) |
608 && c->check_array (array, USHORT::static_size * closure->stride, len))) r
eturn false; | 596 && c->check_array (array, USHORT::static_size * closure->stride, len))) r
eturn TRACE_RETURN (false); |
609 | 597 |
610 unsigned int count = len; | 598 unsigned int count = len; |
611 PairValueRecord *record = CastP<PairValueRecord> (array); | 599 PairValueRecord *record = CastP<PairValueRecord> (array); |
612 return closure->valueFormats[0].sanitize_values_stride_unsafe (c, closure->b
ase, &record->values[0], count, closure->stride) | 600 return TRACE_RETURN (closure->valueFormats[0].sanitize_values_stride_unsafe
(c, closure->base, &record->values[0], count, closure->stride) |
613 » && closure->valueFormats[1].sanitize_values_stride_unsafe (c, closure->b
ase, &record->values[closure->len1], count, closure->stride); | 601 » » && closure->valueFormats[1].sanitize_values_stride_unsafe
(c, closure->base, &record->values[closure->len1], count, closure->stride)); |
614 } | 602 } |
615 | 603 |
616 private: | 604 private: |
617 USHORT len; /* Number of PairValueRecords */ | 605 USHORT len; /* Number of PairValueRecords */ |
618 USHORT array[VAR]; /* Array of PairValueRecords--ordered | 606 USHORT array[VAR]; /* Array of PairValueRecords--ordered |
619 * by GlyphID of the second glyph */ | 607 * by GlyphID of the second glyph */ |
620 public: | 608 public: |
621 DEFINE_SIZE_ARRAY (2, array); | 609 DEFINE_SIZE_ARRAY (2, array); |
622 }; | 610 }; |
623 | 611 |
624 struct PairPosFormat1 | 612 struct PairPosFormat1 |
625 { | 613 { |
626 friend struct PairPos; | 614 friend struct PairPos; |
627 | 615 |
628 private: | 616 private: |
629 inline bool apply (hb_apply_context_t *c) const | 617 inline bool apply (hb_apply_context_t *c) const |
630 { | 618 { |
631 TRACE_APPLY (); | 619 TRACE_APPLY (); |
632 hb_apply_context_t::mark_skipping_forward_iterator_t skippy_iter (c, c->buff
er->idx, 1); | 620 hb_apply_context_t::mark_skipping_forward_iterator_t skippy_iter (c, c->buff
er->idx, 1); |
633 if (skippy_iter.has_no_chance ()) | 621 if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); |
634 return false; | |
635 | 622 |
636 unsigned int index = (this+coverage) (c->buffer->info[c->buffer->idx].codepo
int); | 623 unsigned int index = (this+coverage) (c->buffer->cur().codepoint); |
637 if (likely (index == NOT_COVERED)) | 624 if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); |
638 return false; | |
639 | 625 |
640 if (!skippy_iter.next ()) | 626 if (!skippy_iter.next ()) return TRACE_RETURN (false); |
641 return false; | |
642 | 627 |
643 return (this+pairSet[index]).apply (c, &valueFormat1, skippy_iter.idx); | 628 return TRACE_RETURN ((this+pairSet[index]).apply (c, &valueFormat1, skippy_i
ter.idx)); |
644 } | 629 } |
645 | 630 |
646 inline bool sanitize (hb_sanitize_context_t *c) { | 631 inline bool sanitize (hb_sanitize_context_t *c) { |
647 TRACE_SANITIZE (); | 632 TRACE_SANITIZE (); |
648 | 633 |
649 unsigned int len1 = valueFormat1.get_len (); | 634 unsigned int len1 = valueFormat1.get_len (); |
650 unsigned int len2 = valueFormat2.get_len (); | 635 unsigned int len2 = valueFormat2.get_len (); |
651 PairSet::sanitize_closure_t closure = { | 636 PairSet::sanitize_closure_t closure = { |
652 this, | 637 this, |
653 &valueFormat1, | 638 &valueFormat1, |
654 len1, | 639 len1, |
655 1 + len1 + len2 | 640 1 + len1 + len2 |
656 }; | 641 }; |
657 | 642 |
658 return c->check_struct (this) | 643 return TRACE_RETURN (c->check_struct (this) && coverage.sanitize (c, this) &
& pairSet.sanitize (c, this, &closure)); |
659 » && coverage.sanitize (c, this) | |
660 » && pairSet.sanitize (c, this, &closure); | |
661 } | 644 } |
662 | 645 |
663 private: | 646 private: |
664 USHORT format; /* Format identifier--format = 1 */ | 647 USHORT format; /* Format identifier--format = 1 */ |
665 OffsetTo<Coverage> | 648 OffsetTo<Coverage> |
666 coverage; /* Offset to Coverage table--from | 649 coverage; /* Offset to Coverage table--from |
667 * beginning of subtable */ | 650 * beginning of subtable */ |
668 ValueFormat valueFormat1; /* Defines the types of data in | 651 ValueFormat valueFormat1; /* Defines the types of data in |
669 * ValueRecord1--for the first glyph | 652 * ValueRecord1--for the first glyph |
670 * in the pair--may be zero (0) */ | 653 * in the pair--may be zero (0) */ |
671 ValueFormat valueFormat2; /* Defines the types of data in | 654 ValueFormat valueFormat2; /* Defines the types of data in |
672 * ValueRecord2--for the second glyph | 655 * ValueRecord2--for the second glyph |
673 * in the pair--may be zero (0) */ | 656 * in the pair--may be zero (0) */ |
674 OffsetArrayOf<PairSet> | 657 OffsetArrayOf<PairSet> |
675 pairSet; /* Array of PairSet tables | 658 pairSet; /* Array of PairSet tables |
676 * ordered by Coverage Index */ | 659 * ordered by Coverage Index */ |
677 public: | 660 public: |
678 DEFINE_SIZE_ARRAY (10, pairSet); | 661 DEFINE_SIZE_ARRAY (10, pairSet); |
679 }; | 662 }; |
680 | 663 |
681 struct PairPosFormat2 | 664 struct PairPosFormat2 |
682 { | 665 { |
683 friend struct PairPos; | 666 friend struct PairPos; |
684 | 667 |
685 private: | 668 private: |
686 inline bool apply (hb_apply_context_t *c) const | 669 inline bool apply (hb_apply_context_t *c) const |
687 { | 670 { |
688 TRACE_APPLY (); | 671 TRACE_APPLY (); |
689 hb_apply_context_t::mark_skipping_forward_iterator_t skippy_iter (c, c->buff
er->idx, 1); | 672 hb_apply_context_t::mark_skipping_forward_iterator_t skippy_iter (c, c->buff
er->idx, 1); |
690 if (skippy_iter.has_no_chance ()) | 673 if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); |
691 return false; | |
692 | 674 |
693 unsigned int index = (this+coverage) (c->buffer->info[c->buffer->idx].codepo
int); | 675 unsigned int index = (this+coverage) (c->buffer->cur().codepoint); |
694 if (likely (index == NOT_COVERED)) | 676 if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); |
695 return false; | |
696 | 677 |
697 if (!skippy_iter.next ()) | 678 if (!skippy_iter.next ()) return TRACE_RETURN (false); |
698 return false; | |
699 | 679 |
700 unsigned int len1 = valueFormat1.get_len (); | 680 unsigned int len1 = valueFormat1.get_len (); |
701 unsigned int len2 = valueFormat2.get_len (); | 681 unsigned int len2 = valueFormat2.get_len (); |
702 unsigned int record_len = len1 + len2; | 682 unsigned int record_len = len1 + len2; |
703 | 683 |
704 unsigned int klass1 = (this+classDef1) (c->buffer->info[c->buffer->idx].code
point); | 684 unsigned int klass1 = (this+classDef1) (c->buffer->cur().codepoint); |
705 unsigned int klass2 = (this+classDef2) (c->buffer->info[skippy_iter.idx].cod
epoint); | 685 unsigned int klass2 = (this+classDef2) (c->buffer->info[skippy_iter.idx].cod
epoint); |
706 if (unlikely (klass1 >= class1Count || klass2 >= class2Count)) | 686 if (unlikely (klass1 >= class1Count || klass2 >= class2Count)) return TRACE_
RETURN (false); |
707 return false; | |
708 | 687 |
709 const Value *v = &values[record_len * (klass1 * class2Count + klass2)]; | 688 const Value *v = &values[record_len * (klass1 * class2Count + klass2)]; |
710 valueFormat1.apply_value (c->font, c->direction, this, | 689 valueFormat1.apply_value (c->font, c->direction, this, |
711 » » » v, c->buffer->pos[c->buffer->idx]); | 690 » » » v, c->buffer->cur_pos()); |
712 valueFormat2.apply_value (c->font, c->direction, this, | 691 valueFormat2.apply_value (c->font, c->direction, this, |
713 v + len1, c->buffer->pos[skippy_iter.idx]); | 692 v + len1, c->buffer->pos[skippy_iter.idx]); |
714 | 693 |
715 c->buffer->idx = skippy_iter.idx; | 694 c->buffer->idx = skippy_iter.idx; |
716 if (len2) | 695 if (len2) |
717 c->buffer->idx++; | 696 c->buffer->idx++; |
718 | 697 |
719 return true; | 698 return TRACE_RETURN (true); |
720 } | 699 } |
721 | 700 |
722 inline bool sanitize (hb_sanitize_context_t *c) { | 701 inline bool sanitize (hb_sanitize_context_t *c) { |
723 TRACE_SANITIZE (); | 702 TRACE_SANITIZE (); |
724 if (!(c->check_struct (this) | 703 if (!(c->check_struct (this) |
725 && coverage.sanitize (c, this) | 704 && coverage.sanitize (c, this) |
726 && classDef1.sanitize (c, this) | 705 && classDef1.sanitize (c, this) |
727 && classDef2.sanitize (c, this))) return false; | 706 && classDef2.sanitize (c, this))) return TRACE_RETURN (false); |
728 | 707 |
729 unsigned int len1 = valueFormat1.get_len (); | 708 unsigned int len1 = valueFormat1.get_len (); |
730 unsigned int len2 = valueFormat2.get_len (); | 709 unsigned int len2 = valueFormat2.get_len (); |
731 unsigned int stride = len1 + len2; | 710 unsigned int stride = len1 + len2; |
732 unsigned int record_size = valueFormat1.get_size () + valueFormat2.get_size
(); | 711 unsigned int record_size = valueFormat1.get_size () + valueFormat2.get_size
(); |
733 unsigned int count = (unsigned int) class1Count * (unsigned int) class2Count
; | 712 unsigned int count = (unsigned int) class1Count * (unsigned int) class2Count
; |
734 return c->check_array (values, record_size, count) && | 713 return TRACE_RETURN (c->check_array (values, record_size, count) && |
735 » valueFormat1.sanitize_values_stride_unsafe (c, this, &values[0], coun
t, stride) && | 714 » » » valueFormat1.sanitize_values_stride_unsafe (c, this, &v
alues[0], count, stride) && |
736 » valueFormat2.sanitize_values_stride_unsafe (c, this, &values[len1], c
ount, stride); | 715 » » » valueFormat2.sanitize_values_stride_unsafe (c, this, &v
alues[len1], count, stride)); |
737 } | 716 } |
738 | 717 |
739 private: | 718 private: |
740 USHORT format; /* Format identifier--format = 2 */ | 719 USHORT format; /* Format identifier--format = 2 */ |
741 OffsetTo<Coverage> | 720 OffsetTo<Coverage> |
742 coverage; /* Offset to Coverage table--from | 721 coverage; /* Offset to Coverage table--from |
743 * beginning of subtable */ | 722 * beginning of subtable */ |
744 ValueFormat valueFormat1; /* ValueRecord definition--for the | 723 ValueFormat valueFormat1; /* ValueRecord definition--for the |
745 * first glyph of the pair--may be zero | 724 * first glyph of the pair--may be zero |
746 * (0) */ | 725 * (0) */ |
(...skipping 21 matching lines...) Expand all Loading... |
768 | 747 |
769 struct PairPos | 748 struct PairPos |
770 { | 749 { |
771 friend struct PosLookupSubTable; | 750 friend struct PosLookupSubTable; |
772 | 751 |
773 private: | 752 private: |
774 inline bool apply (hb_apply_context_t *c) const | 753 inline bool apply (hb_apply_context_t *c) const |
775 { | 754 { |
776 TRACE_APPLY (); | 755 TRACE_APPLY (); |
777 switch (u.format) { | 756 switch (u.format) { |
778 case 1: return u.format1.apply (c); | 757 case 1: return TRACE_RETURN (u.format1.apply (c)); |
779 case 2: return u.format2.apply (c); | 758 case 2: return TRACE_RETURN (u.format2.apply (c)); |
780 default:return false; | 759 default:return TRACE_RETURN (false); |
781 } | 760 } |
782 } | 761 } |
783 | 762 |
784 inline bool sanitize (hb_sanitize_context_t *c) { | 763 inline bool sanitize (hb_sanitize_context_t *c) { |
785 TRACE_SANITIZE (); | 764 TRACE_SANITIZE (); |
786 if (!u.format.sanitize (c)) return false; | 765 if (!u.format.sanitize (c)) return TRACE_RETURN (false); |
787 switch (u.format) { | 766 switch (u.format) { |
788 case 1: return u.format1.sanitize (c); | 767 case 1: return TRACE_RETURN (u.format1.sanitize (c)); |
789 case 2: return u.format2.sanitize (c); | 768 case 2: return TRACE_RETURN (u.format2.sanitize (c)); |
790 default:return true; | 769 default:return TRACE_RETURN (true); |
791 } | 770 } |
792 } | 771 } |
793 | 772 |
794 private: | 773 private: |
795 union { | 774 union { |
796 USHORT format; /* Format identifier */ | 775 USHORT format; /* Format identifier */ |
797 PairPosFormat1 format1; | 776 PairPosFormat1 format1; |
798 PairPosFormat2 format2; | 777 PairPosFormat2 format2; |
799 } u; | 778 } u; |
800 }; | 779 }; |
801 | 780 |
802 | 781 |
803 struct EntryExitRecord | 782 struct EntryExitRecord |
804 { | 783 { |
805 friend struct CursivePosFormat1; | 784 friend struct CursivePosFormat1; |
806 | 785 |
807 inline bool sanitize (hb_sanitize_context_t *c, void *base) { | 786 inline bool sanitize (hb_sanitize_context_t *c, void *base) { |
808 TRACE_SANITIZE (); | 787 TRACE_SANITIZE (); |
809 return entryAnchor.sanitize (c, base) | 788 return TRACE_RETURN (entryAnchor.sanitize (c, base) && exitAnchor.sanitize (
c, base)); |
810 » && exitAnchor.sanitize (c, base); | |
811 } | 789 } |
812 | 790 |
813 private: | 791 private: |
814 OffsetTo<Anchor> | 792 OffsetTo<Anchor> |
815 entryAnchor; /* Offset to EntryAnchor table--from | 793 entryAnchor; /* Offset to EntryAnchor table--from |
816 * beginning of CursivePos | 794 * beginning of CursivePos |
817 * subtable--may be NULL */ | 795 * subtable--may be NULL */ |
818 OffsetTo<Anchor> | 796 OffsetTo<Anchor> |
819 exitAnchor; /* Offset to ExitAnchor table--from | 797 exitAnchor; /* Offset to ExitAnchor table--from |
820 * beginning of CursivePos | 798 * beginning of CursivePos |
821 * subtable--may be NULL */ | 799 * subtable--may be NULL */ |
822 public: | 800 public: |
823 DEFINE_SIZE_STATIC (4); | 801 DEFINE_SIZE_STATIC (4); |
824 }; | 802 }; |
825 | 803 |
826 struct CursivePosFormat1 | 804 struct CursivePosFormat1 |
827 { | 805 { |
828 friend struct CursivePos; | 806 friend struct CursivePos; |
829 | 807 |
830 private: | 808 private: |
831 inline bool apply (hb_apply_context_t *c) const | 809 inline bool apply (hb_apply_context_t *c) const |
832 { | 810 { |
833 TRACE_APPLY (); | 811 TRACE_APPLY (); |
834 | 812 |
835 /* We don't handle mark glyphs here. */ | 813 /* We don't handle mark glyphs here. */ |
836 if (c->property & HB_OT_LAYOUT_GLYPH_CLASS_MARK) | 814 if (c->property & HB_OT_LAYOUT_GLYPH_CLASS_MARK) return TRACE_RETURN (false)
; |
837 return false; | |
838 | 815 |
839 hb_apply_context_t::mark_skipping_forward_iterator_t skippy_iter (c, c->buff
er->idx, 1); | 816 hb_apply_context_t::mark_skipping_forward_iterator_t skippy_iter (c, c->buff
er->idx, 1); |
840 if (skippy_iter.has_no_chance ()) | 817 if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); |
841 return false; | |
842 | 818 |
843 const EntryExitRecord &this_record = entryExitRecord[(this+coverage) (c->buf
fer->info[c->buffer->idx].codepoint)]; | 819 const EntryExitRecord &this_record = entryExitRecord[(this+coverage) (c->buf
fer->cur().codepoint)]; |
844 if (!this_record.exitAnchor) | 820 if (!this_record.exitAnchor) return TRACE_RETURN (false); |
845 return false; | |
846 | 821 |
847 if (!skippy_iter.next ()) | 822 if (!skippy_iter.next ()) return TRACE_RETURN (false); |
848 return false; | |
849 | 823 |
850 const EntryExitRecord &next_record = entryExitRecord[(this+coverage) (c->buf
fer->info[skippy_iter.idx].codepoint)]; | 824 const EntryExitRecord &next_record = entryExitRecord[(this+coverage) (c->buf
fer->info[skippy_iter.idx].codepoint)]; |
851 if (!next_record.entryAnchor) | 825 if (!next_record.entryAnchor) return TRACE_RETURN (false); |
852 return false; | |
853 | 826 |
854 unsigned int i = c->buffer->idx; | 827 unsigned int i = c->buffer->idx; |
855 unsigned int j = skippy_iter.idx; | 828 unsigned int j = skippy_iter.idx; |
856 | 829 |
857 hb_position_t entry_x, entry_y, exit_x, exit_y; | 830 hb_position_t entry_x, entry_y, exit_x, exit_y; |
858 (this+this_record.exitAnchor).get_anchor (c->font, c->buffer->info[i].codepo
int, &exit_x, &exit_y); | 831 (this+this_record.exitAnchor).get_anchor (c->font, c->buffer->info[i].codepo
int, &exit_x, &exit_y); |
859 (this+next_record.entryAnchor).get_anchor (c->font, c->buffer->info[j].codep
oint, &entry_x, &entry_y); | 832 (this+next_record.entryAnchor).get_anchor (c->font, c->buffer->info[j].codep
oint, &entry_x, &entry_y); |
860 | 833 |
861 hb_glyph_position_t *pos = c->buffer->pos; | 834 hb_glyph_position_t *pos = c->buffer->pos; |
862 | 835 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
905 pos[i].x_offset = entry_x - exit_x; | 878 pos[i].x_offset = entry_x - exit_x; |
906 } else { | 879 } else { |
907 pos[j].cursive_chain() = i - j; | 880 pos[j].cursive_chain() = i - j; |
908 if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction))) | 881 if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction))) |
909 pos[j].y_offset = exit_y - entry_y; | 882 pos[j].y_offset = exit_y - entry_y; |
910 else | 883 else |
911 pos[j].x_offset = exit_x - entry_x; | 884 pos[j].x_offset = exit_x - entry_x; |
912 } | 885 } |
913 | 886 |
914 c->buffer->idx = j; | 887 c->buffer->idx = j; |
915 return true; | 888 return TRACE_RETURN (true); |
916 } | 889 } |
917 | 890 |
918 inline bool sanitize (hb_sanitize_context_t *c) { | 891 inline bool sanitize (hb_sanitize_context_t *c) { |
919 TRACE_SANITIZE (); | 892 TRACE_SANITIZE (); |
920 return coverage.sanitize (c, this) | 893 return TRACE_RETURN (coverage.sanitize (c, this) && entryExitRecord.sanitize
(c, this)); |
921 » && entryExitRecord.sanitize (c, this); | |
922 } | 894 } |
923 | 895 |
924 private: | 896 private: |
925 USHORT format; /* Format identifier--format = 1 */ | 897 USHORT format; /* Format identifier--format = 1 */ |
926 OffsetTo<Coverage> | 898 OffsetTo<Coverage> |
927 coverage; /* Offset to Coverage table--from | 899 coverage; /* Offset to Coverage table--from |
928 * beginning of subtable */ | 900 * beginning of subtable */ |
929 ArrayOf<EntryExitRecord> | 901 ArrayOf<EntryExitRecord> |
930 entryExitRecord; /* Array of EntryExit records--in | 902 entryExitRecord; /* Array of EntryExit records--in |
931 * Coverage Index order */ | 903 * Coverage Index order */ |
932 public: | 904 public: |
933 DEFINE_SIZE_ARRAY (6, entryExitRecord); | 905 DEFINE_SIZE_ARRAY (6, entryExitRecord); |
934 }; | 906 }; |
935 | 907 |
936 struct CursivePos | 908 struct CursivePos |
937 { | 909 { |
938 friend struct PosLookupSubTable; | 910 friend struct PosLookupSubTable; |
939 | 911 |
940 private: | 912 private: |
941 inline bool apply (hb_apply_context_t *c) const | 913 inline bool apply (hb_apply_context_t *c) const |
942 { | 914 { |
943 TRACE_APPLY (); | 915 TRACE_APPLY (); |
944 switch (u.format) { | 916 switch (u.format) { |
945 case 1: return u.format1.apply (c); | 917 case 1: return TRACE_RETURN (u.format1.apply (c)); |
946 default:return false; | 918 default:return TRACE_RETURN (false); |
947 } | 919 } |
948 } | 920 } |
949 | 921 |
950 inline bool sanitize (hb_sanitize_context_t *c) { | 922 inline bool sanitize (hb_sanitize_context_t *c) { |
951 TRACE_SANITIZE (); | 923 TRACE_SANITIZE (); |
952 if (!u.format.sanitize (c)) return false; | 924 if (!u.format.sanitize (c)) return TRACE_RETURN (false); |
953 switch (u.format) { | 925 switch (u.format) { |
954 case 1: return u.format1.sanitize (c); | 926 case 1: return TRACE_RETURN (u.format1.sanitize (c)); |
955 default:return true; | 927 default:return TRACE_RETURN (true); |
956 } | 928 } |
957 } | 929 } |
958 | 930 |
959 private: | 931 private: |
960 union { | 932 union { |
961 USHORT format; /* Format identifier */ | 933 USHORT format; /* Format identifier */ |
962 CursivePosFormat1 format1; | 934 CursivePosFormat1 format1; |
963 } u; | 935 } u; |
964 }; | 936 }; |
965 | 937 |
966 | 938 |
967 typedef AnchorMatrix BaseArray; /* base-major-- | 939 typedef AnchorMatrix BaseArray; /* base-major-- |
968 * in order of BaseCoverage Index--, | 940 * in order of BaseCoverage Index--, |
969 * mark-minor-- | 941 * mark-minor-- |
970 * ordered by class--zero-based. */ | 942 * ordered by class--zero-based. */ |
971 | 943 |
972 struct MarkBasePosFormat1 | 944 struct MarkBasePosFormat1 |
973 { | 945 { |
974 friend struct MarkBasePos; | 946 friend struct MarkBasePos; |
975 | 947 |
976 private: | 948 private: |
977 inline bool apply (hb_apply_context_t *c) const | 949 inline bool apply (hb_apply_context_t *c) const |
978 { | 950 { |
979 TRACE_APPLY (); | 951 TRACE_APPLY (); |
980 unsigned int mark_index = (this+markCoverage) (c->buffer->info[c->buffer->id
x].codepoint); | 952 unsigned int mark_index = (this+markCoverage) (c->buffer->cur().codepoint); |
981 if (likely (mark_index == NOT_COVERED)) | 953 if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false); |
982 return false; | |
983 | 954 |
984 /* now we search backwards for a non-mark glyph */ | 955 /* now we search backwards for a non-mark glyph */ |
985 unsigned int property; | 956 unsigned int property; |
986 hb_apply_context_t::mark_skipping_backward_iterator_t skippy_iter (c, c->buf
fer->idx, 1); | 957 hb_apply_context_t::mark_skipping_backward_iterator_t skippy_iter (c, c->buf
fer->idx, 1); |
987 if (!skippy_iter.prev (&property, LookupFlag::IgnoreMarks)) | 958 if (!skippy_iter.prev (&property, LookupFlag::IgnoreMarks)) return TRACE_RET
URN (false); |
988 return false; | |
989 | 959 |
990 /* The following assertion is too strong, so we've disabled it. */ | 960 /* The following assertion is too strong, so we've disabled it. */ |
991 if (!(property & HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH)) | 961 if (!(property & HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH)) {/*return TRACE_RETUR
N (false);*/} |
992 {/*return false;*/} | |
993 | 962 |
994 unsigned int base_index = (this+baseCoverage) (c->buffer->info[skippy_iter.i
dx].codepoint); | 963 unsigned int base_index = (this+baseCoverage) (c->buffer->info[skippy_iter.i
dx].codepoint); |
995 if (base_index == NOT_COVERED) | 964 if (base_index == NOT_COVERED) return TRACE_RETURN (false); |
996 return false; | |
997 | 965 |
998 return (this+markArray).apply (c, mark_index, base_index, this+baseArray, cl
assCount, skippy_iter.idx); | 966 return TRACE_RETURN ((this+markArray).apply (c, mark_index, base_index, this
+baseArray, classCount, skippy_iter.idx)); |
999 } | 967 } |
1000 | 968 |
1001 inline bool sanitize (hb_sanitize_context_t *c) { | 969 inline bool sanitize (hb_sanitize_context_t *c) { |
1002 TRACE_SANITIZE (); | 970 TRACE_SANITIZE (); |
1003 return c->check_struct (this) | 971 return TRACE_RETURN (c->check_struct (this) && markCoverage.sanitize (c, thi
s) && baseCoverage.sanitize (c, this) && |
1004 && markCoverage.sanitize (c, this) | 972 » » » markArray.sanitize (c, this) && baseArray.sanitize (c,
this, (unsigned int) classCount)); |
1005 » && baseCoverage.sanitize (c, this) | |
1006 » && markArray.sanitize (c, this) | |
1007 » && baseArray.sanitize (c, this, (unsigned int) classCount); | |
1008 } | 973 } |
1009 | 974 |
1010 private: | 975 private: |
1011 USHORT format; /* Format identifier--format = 1 */ | 976 USHORT format; /* Format identifier--format = 1 */ |
1012 OffsetTo<Coverage> | 977 OffsetTo<Coverage> |
1013 markCoverage; /* Offset to MarkCoverage table--from | 978 markCoverage; /* Offset to MarkCoverage table--from |
1014 * beginning of MarkBasePos subtable */ | 979 * beginning of MarkBasePos subtable */ |
1015 OffsetTo<Coverage> | 980 OffsetTo<Coverage> |
1016 baseCoverage; /* Offset to BaseCoverage table--from | 981 baseCoverage; /* Offset to BaseCoverage table--from |
1017 * beginning of MarkBasePos subtable */ | 982 * beginning of MarkBasePos subtable */ |
(...skipping 10 matching lines...) Expand all Loading... |
1028 | 993 |
1029 struct MarkBasePos | 994 struct MarkBasePos |
1030 { | 995 { |
1031 friend struct PosLookupSubTable; | 996 friend struct PosLookupSubTable; |
1032 | 997 |
1033 private: | 998 private: |
1034 inline bool apply (hb_apply_context_t *c) const | 999 inline bool apply (hb_apply_context_t *c) const |
1035 { | 1000 { |
1036 TRACE_APPLY (); | 1001 TRACE_APPLY (); |
1037 switch (u.format) { | 1002 switch (u.format) { |
1038 case 1: return u.format1.apply (c); | 1003 case 1: return TRACE_RETURN (u.format1.apply (c)); |
1039 default:return false; | 1004 default:return TRACE_RETURN (false); |
1040 } | 1005 } |
1041 } | 1006 } |
1042 | 1007 |
1043 inline bool sanitize (hb_sanitize_context_t *c) { | 1008 inline bool sanitize (hb_sanitize_context_t *c) { |
1044 TRACE_SANITIZE (); | 1009 TRACE_SANITIZE (); |
1045 if (!u.format.sanitize (c)) return false; | 1010 if (!u.format.sanitize (c)) return TRACE_RETURN (false); |
1046 switch (u.format) { | 1011 switch (u.format) { |
1047 case 1: return u.format1.sanitize (c); | 1012 case 1: return TRACE_RETURN (u.format1.sanitize (c)); |
1048 default:return true; | 1013 default:return TRACE_RETURN (true); |
1049 } | 1014 } |
1050 } | 1015 } |
1051 | 1016 |
1052 private: | 1017 private: |
1053 union { | 1018 union { |
1054 USHORT format; /* Format identifier */ | 1019 USHORT format; /* Format identifier */ |
1055 MarkBasePosFormat1 format1; | 1020 MarkBasePosFormat1 format1; |
1056 } u; | 1021 } u; |
1057 }; | 1022 }; |
1058 | 1023 |
1059 | 1024 |
1060 typedef AnchorMatrix LigatureAttach; /* component-major-- | 1025 typedef AnchorMatrix LigatureAttach; /* component-major-- |
1061 * in order of writing direction--, | 1026 * in order of writing direction--, |
1062 * mark-minor-- | 1027 * mark-minor-- |
1063 * ordered by class--zero-based. */ | 1028 * ordered by class--zero-based. */ |
1064 | 1029 |
1065 typedef OffsetListOf<LigatureAttach> LigatureArray; | 1030 typedef OffsetListOf<LigatureAttach> LigatureArray; |
1066 /* Array of LigatureAttach | 1031 /* Array of LigatureAttach |
1067 * tables ordered by | 1032 * tables ordered by |
1068 * LigatureCoverage Index */ | 1033 * LigatureCoverage Index */ |
1069 | 1034 |
1070 struct MarkLigPosFormat1 | 1035 struct MarkLigPosFormat1 |
1071 { | 1036 { |
1072 friend struct MarkLigPos; | 1037 friend struct MarkLigPos; |
1073 | 1038 |
1074 private: | 1039 private: |
1075 inline bool apply (hb_apply_context_t *c) const | 1040 inline bool apply (hb_apply_context_t *c) const |
1076 { | 1041 { |
1077 TRACE_APPLY (); | 1042 TRACE_APPLY (); |
1078 unsigned int mark_index = (this+markCoverage) (c->buffer->info[c->buffer->id
x].codepoint); | 1043 unsigned int mark_index = (this+markCoverage) (c->buffer->cur().codepoint); |
1079 if (likely (mark_index == NOT_COVERED)) | 1044 if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false); |
1080 return false; | |
1081 | 1045 |
1082 /* now we search backwards for a non-mark glyph */ | 1046 /* now we search backwards for a non-mark glyph */ |
1083 unsigned int property; | 1047 unsigned int property; |
1084 hb_apply_context_t::mark_skipping_backward_iterator_t skippy_iter (c, c->buf
fer->idx, 1); | 1048 hb_apply_context_t::mark_skipping_backward_iterator_t skippy_iter (c, c->buf
fer->idx, 1); |
1085 if (!skippy_iter.prev (&property, LookupFlag::IgnoreMarks)) | 1049 if (!skippy_iter.prev (&property, LookupFlag::IgnoreMarks)) return TRACE_RET
URN (false); |
1086 return false; | |
1087 | 1050 |
1088 /* The following assertion is too strong, so we've disabled it. */ | 1051 /* The following assertion is too strong, so we've disabled it. */ |
1089 if (!(property & HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE)) | 1052 if (!(property & HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE)) {/*return TRACE_RETURN
(false);*/} |
1090 {/*return false;*/} | |
1091 | 1053 |
1092 unsigned int j = skippy_iter.idx; | 1054 unsigned int j = skippy_iter.idx; |
1093 unsigned int lig_index = (this+ligatureCoverage) (c->buffer->info[j].codepoi
nt); | 1055 unsigned int lig_index = (this+ligatureCoverage) (c->buffer->info[j].codepoi
nt); |
1094 if (lig_index == NOT_COVERED) | 1056 if (lig_index == NOT_COVERED) return TRACE_RETURN (false); |
1095 return false; | |
1096 | 1057 |
1097 const LigatureArray& lig_array = this+ligatureArray; | 1058 const LigatureArray& lig_array = this+ligatureArray; |
1098 const LigatureAttach& lig_attach = lig_array[lig_index]; | 1059 const LigatureAttach& lig_attach = lig_array[lig_index]; |
1099 | 1060 |
1100 /* Find component to attach to */ | 1061 /* Find component to attach to */ |
1101 unsigned int comp_count = lig_attach.rows; | 1062 unsigned int comp_count = lig_attach.rows; |
1102 if (unlikely (!comp_count)) | 1063 if (unlikely (!comp_count)) return TRACE_RETURN (false); |
1103 return false; | 1064 |
1104 unsigned int comp_index; | 1065 unsigned int comp_index; |
1105 /* We must now check whether the ligature ID of the current mark glyph | 1066 /* We must now check whether the ligature ID of the current mark glyph |
1106 * is identical to the ligature ID of the found ligature. If yes, we | 1067 * is identical to the ligature ID of the found ligature. If yes, we |
1107 * can directly use the component index. If not, we attach the mark | 1068 * can directly use the component index. If not, we attach the mark |
1108 * glyph to the last component of the ligature. */ | 1069 * glyph to the last component of the ligature. */ |
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()) | 1070 if (get_lig_id (c->buffer->info[j]) && |
| 1071 » get_lig_id (c->buffer->cur()) && |
| 1072 » get_lig_comp (c->buffer->cur()) > 0) |
1110 { | 1073 { |
1111 comp_index = c->buffer->info[c->buffer->idx].lig_comp() - 1; | 1074 comp_index = get_lig_comp (c->buffer->cur()) - 1; |
1112 if (comp_index >= comp_count) | 1075 if (comp_index >= comp_count) |
1113 comp_index = comp_count - 1; | 1076 comp_index = comp_count - 1; |
1114 } | 1077 } |
1115 else | 1078 else |
1116 comp_index = comp_count - 1; | 1079 comp_index = comp_count - 1; |
1117 | 1080 |
1118 return (this+markArray).apply (c, mark_index, comp_index, lig_attach, classC
ount, j); | 1081 return TRACE_RETURN ((this+markArray).apply (c, mark_index, comp_index, lig_
attach, classCount, j)); |
1119 } | 1082 } |
1120 | 1083 |
1121 inline bool sanitize (hb_sanitize_context_t *c) { | 1084 inline bool sanitize (hb_sanitize_context_t *c) { |
1122 TRACE_SANITIZE (); | 1085 TRACE_SANITIZE (); |
1123 return c->check_struct (this) | 1086 return TRACE_RETURN (c->check_struct (this) && markCoverage.sanitize (c, thi
s) && ligatureCoverage.sanitize (c, this) && |
1124 && markCoverage.sanitize (c, this) | 1087 » » » markArray.sanitize (c, this) && ligatureArray.sanitize
(c, this, (unsigned int) classCount)); |
1125 » && ligatureCoverage.sanitize (c, this) | |
1126 » && markArray.sanitize (c, this) | |
1127 » && ligatureArray.sanitize (c, this, (unsigned int) classCount); | |
1128 } | 1088 } |
1129 | 1089 |
1130 private: | 1090 private: |
1131 USHORT format; /* Format identifier--format = 1 */ | 1091 USHORT format; /* Format identifier--format = 1 */ |
1132 OffsetTo<Coverage> | 1092 OffsetTo<Coverage> |
1133 markCoverage; /* Offset to Mark Coverage table--from | 1093 markCoverage; /* Offset to Mark Coverage table--from |
1134 * beginning of MarkLigPos subtable */ | 1094 * beginning of MarkLigPos subtable */ |
1135 OffsetTo<Coverage> | 1095 OffsetTo<Coverage> |
1136 ligatureCoverage; /* Offset to Ligature Coverage | 1096 ligatureCoverage; /* Offset to Ligature Coverage |
1137 * table--from beginning of MarkLigPos | 1097 * table--from beginning of MarkLigPos |
(...skipping 11 matching lines...) Expand all Loading... |
1149 | 1109 |
1150 struct MarkLigPos | 1110 struct MarkLigPos |
1151 { | 1111 { |
1152 friend struct PosLookupSubTable; | 1112 friend struct PosLookupSubTable; |
1153 | 1113 |
1154 private: | 1114 private: |
1155 inline bool apply (hb_apply_context_t *c) const | 1115 inline bool apply (hb_apply_context_t *c) const |
1156 { | 1116 { |
1157 TRACE_APPLY (); | 1117 TRACE_APPLY (); |
1158 switch (u.format) { | 1118 switch (u.format) { |
1159 case 1: return u.format1.apply (c); | 1119 case 1: return TRACE_RETURN (u.format1.apply (c)); |
1160 default:return false; | 1120 default:return TRACE_RETURN (false); |
1161 } | 1121 } |
1162 } | 1122 } |
1163 | 1123 |
1164 inline bool sanitize (hb_sanitize_context_t *c) { | 1124 inline bool sanitize (hb_sanitize_context_t *c) { |
1165 TRACE_SANITIZE (); | 1125 TRACE_SANITIZE (); |
1166 if (!u.format.sanitize (c)) return false; | 1126 if (!u.format.sanitize (c)) return TRACE_RETURN (false); |
1167 switch (u.format) { | 1127 switch (u.format) { |
1168 case 1: return u.format1.sanitize (c); | 1128 case 1: return TRACE_RETURN (u.format1.sanitize (c)); |
1169 default:return true; | 1129 default:return TRACE_RETURN (true); |
1170 } | 1130 } |
1171 } | 1131 } |
1172 | 1132 |
1173 private: | 1133 private: |
1174 union { | 1134 union { |
1175 USHORT format; /* Format identifier */ | 1135 USHORT format; /* Format identifier */ |
1176 MarkLigPosFormat1 format1; | 1136 MarkLigPosFormat1 format1; |
1177 } u; | 1137 } u; |
1178 }; | 1138 }; |
1179 | 1139 |
1180 | 1140 |
1181 typedef AnchorMatrix Mark2Array; /* mark2-major-- | 1141 typedef AnchorMatrix Mark2Array; /* mark2-major-- |
1182 * in order of Mark2Coverage Index--, | 1142 * in order of Mark2Coverage Index--, |
1183 * mark1-minor-- | 1143 * mark1-minor-- |
1184 * ordered by class--zero-based. */ | 1144 * ordered by class--zero-based. */ |
1185 | 1145 |
1186 struct MarkMarkPosFormat1 | 1146 struct MarkMarkPosFormat1 |
1187 { | 1147 { |
1188 friend struct MarkMarkPos; | 1148 friend struct MarkMarkPos; |
1189 | 1149 |
1190 private: | 1150 private: |
1191 inline bool apply (hb_apply_context_t *c) const | 1151 inline bool apply (hb_apply_context_t *c) const |
1192 { | 1152 { |
1193 TRACE_APPLY (); | 1153 TRACE_APPLY (); |
1194 unsigned int mark1_index = (this+mark1Coverage) (c->buffer->info[c->buffer->
idx].codepoint); | 1154 unsigned int mark1_index = (this+mark1Coverage) (c->buffer->cur().codepoint)
; |
1195 if (likely (mark1_index == NOT_COVERED)) | 1155 if (likely (mark1_index == NOT_COVERED)) return TRACE_RETURN (false); |
1196 return false; | |
1197 | 1156 |
1198 /* now we search backwards for a suitable mark glyph until a non-mark glyph
*/ | 1157 /* now we search backwards for a suitable mark glyph until a non-mark glyph
*/ |
1199 unsigned int property; | 1158 unsigned int property; |
1200 hb_apply_context_t::mark_skipping_backward_iterator_t skippy_iter (c, c->buf
fer->idx, 1); | 1159 hb_apply_context_t::mark_skipping_backward_iterator_t skippy_iter (c, c->buf
fer->idx, 1); |
1201 if (!skippy_iter.prev (&property)) | 1160 if (!skippy_iter.prev (&property)) return TRACE_RETURN (false); |
1202 return false; | |
1203 | 1161 |
1204 if (!(property & HB_OT_LAYOUT_GLYPH_CLASS_MARK)) | 1162 if (!(property & HB_OT_LAYOUT_GLYPH_CLASS_MARK)) return TRACE_RETURN (false)
; |
1205 return false; | |
1206 | 1163 |
1207 unsigned int j = skippy_iter.idx; | 1164 unsigned int j = skippy_iter.idx; |
1208 | 1165 |
1209 /* Two marks match only if they belong to the same base, or same component | 1166 /* Two marks match only if they belong to the same base, or same component |
1210 * of the same ligature. That is, the component numbers must match, and | 1167 * of the same ligature. That is, the component numbers must match, and |
1211 * if those are non-zero, the ligid number should also match. */ | 1168 * if those are non-zero, the ligid number should also match. */ |
1212 if ((c->buffer->info[j].lig_comp() != c->buffer->info[c->buffer->idx].lig_co
mp()) || | 1169 if ((get_lig_comp (c->buffer->cur())) || |
1213 » (c->buffer->info[j].lig_comp() && c->buffer->info[j].lig_id() != c->buff
er->info[c->buffer->idx].lig_id())) | 1170 » (get_lig_comp (c->buffer->info[j]) > 0 && |
1214 return false; | 1171 » get_lig_id (c->buffer->cur()))) |
| 1172 return TRACE_RETURN (false); |
1215 | 1173 |
1216 unsigned int mark2_index = (this+mark2Coverage) (c->buffer->info[j].codepoin
t); | 1174 unsigned int mark2_index = (this+mark2Coverage) (c->buffer->info[j].codepoin
t); |
1217 if (mark2_index == NOT_COVERED) | 1175 if (mark2_index == NOT_COVERED) return TRACE_RETURN (false); |
1218 return false; | |
1219 | 1176 |
1220 return (this+mark1Array).apply (c, mark1_index, mark2_index, this+mark2Array
, classCount, j); | 1177 return TRACE_RETURN ((this+mark1Array).apply (c, mark1_index, mark2_index, t
his+mark2Array, classCount, j)); |
1221 } | 1178 } |
1222 | 1179 |
1223 inline bool sanitize (hb_sanitize_context_t *c) { | 1180 inline bool sanitize (hb_sanitize_context_t *c) { |
1224 TRACE_SANITIZE (); | 1181 TRACE_SANITIZE (); |
1225 return c->check_struct (this) | 1182 return TRACE_RETURN (c->check_struct (this) && mark1Coverage.sanitize (c, th
is) && |
1226 » && mark1Coverage.sanitize (c, this) | 1183 » » » mark2Coverage.sanitize (c, this) && mark1Array.sanitize
(c, this) |
1227 » && mark2Coverage.sanitize (c, this) | 1184 » » » && mark2Array.sanitize (c, this, (unsigned int) classCo
unt)); |
1228 » && mark1Array.sanitize (c, this) | |
1229 » && mark2Array.sanitize (c, this, (unsigned int) classCount); | |
1230 } | 1185 } |
1231 | 1186 |
1232 private: | 1187 private: |
1233 USHORT format; /* Format identifier--format = 1 */ | 1188 USHORT format; /* Format identifier--format = 1 */ |
1234 OffsetTo<Coverage> | 1189 OffsetTo<Coverage> |
1235 mark1Coverage; /* Offset to Combining Mark1 Coverage | 1190 mark1Coverage; /* Offset to Combining Mark1 Coverage |
1236 * table--from beginning of MarkMarkPos | 1191 * table--from beginning of MarkMarkPos |
1237 * subtable */ | 1192 * subtable */ |
1238 OffsetTo<Coverage> | 1193 OffsetTo<Coverage> |
1239 mark2Coverage; /* Offset to Combining Mark2 Coverage | 1194 mark2Coverage; /* Offset to Combining Mark2 Coverage |
(...skipping 12 matching lines...) Expand all Loading... |
1252 | 1207 |
1253 struct MarkMarkPos | 1208 struct MarkMarkPos |
1254 { | 1209 { |
1255 friend struct PosLookupSubTable; | 1210 friend struct PosLookupSubTable; |
1256 | 1211 |
1257 private: | 1212 private: |
1258 inline bool apply (hb_apply_context_t *c) const | 1213 inline bool apply (hb_apply_context_t *c) const |
1259 { | 1214 { |
1260 TRACE_APPLY (); | 1215 TRACE_APPLY (); |
1261 switch (u.format) { | 1216 switch (u.format) { |
1262 case 1: return u.format1.apply (c); | 1217 case 1: return TRACE_RETURN (u.format1.apply (c)); |
1263 default:return false; | 1218 default:return TRACE_RETURN (false); |
1264 } | 1219 } |
1265 } | 1220 } |
1266 | 1221 |
1267 inline bool sanitize (hb_sanitize_context_t *c) { | 1222 inline bool sanitize (hb_sanitize_context_t *c) { |
1268 TRACE_SANITIZE (); | 1223 TRACE_SANITIZE (); |
1269 if (!u.format.sanitize (c)) return false; | 1224 if (!u.format.sanitize (c)) return TRACE_RETURN (false); |
1270 switch (u.format) { | 1225 switch (u.format) { |
1271 case 1: return u.format1.sanitize (c); | 1226 case 1: return TRACE_RETURN (u.format1.sanitize (c)); |
1272 default:return true; | 1227 default:return TRACE_RETURN (true); |
1273 } | 1228 } |
1274 } | 1229 } |
1275 | 1230 |
1276 private: | 1231 private: |
1277 union { | 1232 union { |
1278 USHORT format; /* Format identifier */ | 1233 USHORT format; /* Format identifier */ |
1279 MarkMarkPosFormat1 format1; | 1234 MarkMarkPosFormat1 format1; |
1280 } u; | 1235 } u; |
1281 }; | 1236 }; |
1282 | 1237 |
1283 | 1238 |
1284 static inline bool position_lookup (hb_apply_context_t *c, unsigned int lookup_i
ndex); | 1239 static inline bool position_lookup (hb_apply_context_t *c, unsigned int lookup_i
ndex); |
1285 | 1240 |
1286 struct ContextPos : Context | 1241 struct ContextPos : Context |
1287 { | 1242 { |
1288 friend struct PosLookupSubTable; | 1243 friend struct PosLookupSubTable; |
1289 | 1244 |
1290 private: | 1245 private: |
1291 inline bool apply (hb_apply_context_t *c) const | 1246 inline bool apply (hb_apply_context_t *c) const |
1292 { | 1247 { |
1293 TRACE_APPLY (); | 1248 TRACE_APPLY (); |
1294 return Context::apply (c, position_lookup); | 1249 return TRACE_RETURN (Context::apply (c, position_lookup)); |
1295 } | 1250 } |
1296 }; | 1251 }; |
1297 | 1252 |
1298 struct ChainContextPos : ChainContext | 1253 struct ChainContextPos : ChainContext |
1299 { | 1254 { |
1300 friend struct PosLookupSubTable; | 1255 friend struct PosLookupSubTable; |
1301 | 1256 |
1302 private: | 1257 private: |
1303 inline bool apply (hb_apply_context_t *c) const | 1258 inline bool apply (hb_apply_context_t *c) const |
1304 { | 1259 { |
1305 TRACE_APPLY (); | 1260 TRACE_APPLY (); |
1306 return ChainContext::apply (c, position_lookup); | 1261 return TRACE_RETURN (ChainContext::apply (c, position_lookup)); |
1307 } | 1262 } |
1308 }; | 1263 }; |
1309 | 1264 |
1310 | 1265 |
1311 struct ExtensionPos : Extension | 1266 struct ExtensionPos : Extension |
1312 { | 1267 { |
1313 friend struct PosLookupSubTable; | 1268 friend struct PosLookupSubTable; |
1314 | 1269 |
1315 private: | 1270 private: |
1316 inline const struct PosLookupSubTable& get_subtable (void) const | 1271 inline const struct PosLookupSubTable& get_subtable (void) const |
(...skipping 12 matching lines...) Expand all Loading... |
1329 | 1284 |
1330 /* | 1285 /* |
1331 * PosLookup | 1286 * PosLookup |
1332 */ | 1287 */ |
1333 | 1288 |
1334 | 1289 |
1335 struct PosLookupSubTable | 1290 struct PosLookupSubTable |
1336 { | 1291 { |
1337 friend struct PosLookup; | 1292 friend struct PosLookup; |
1338 | 1293 |
1339 enum { | 1294 enum Type { |
1340 Single = 1, | 1295 Single = 1, |
1341 Pair = 2, | 1296 Pair = 2, |
1342 Cursive = 3, | 1297 Cursive = 3, |
1343 MarkBase = 4, | 1298 MarkBase = 4, |
1344 MarkLig = 5, | 1299 MarkLig = 5, |
1345 MarkMark = 6, | 1300 MarkMark = 6, |
1346 Context = 7, | 1301 Context = 7, |
1347 ChainContext = 8, | 1302 ChainContext = 8, |
1348 Extension = 9 | 1303 Extension = 9 |
1349 }; | 1304 }; |
1350 | 1305 |
1351 inline bool apply (hb_apply_context_t *c, unsigned int lookup_type) const | 1306 inline bool apply (hb_apply_context_t *c, unsigned int lookup_type) const |
1352 { | 1307 { |
1353 TRACE_APPLY (); | 1308 TRACE_APPLY (); |
1354 switch (lookup_type) { | 1309 switch (lookup_type) { |
1355 case Single:» » return u.single.apply (c); | 1310 case Single:» » return TRACE_RETURN (u.single.apply (c)); |
1356 case Pair:» » » return u.pair.apply (c); | 1311 case Pair:» » » return TRACE_RETURN (u.pair.apply (c)); |
1357 case Cursive:» » return u.cursive.apply (c); | 1312 case Cursive:» » return TRACE_RETURN (u.cursive.apply (c)); |
1358 case MarkBase:» » return u.markBase.apply (c); | 1313 case MarkBase:» » return TRACE_RETURN (u.markBase.apply (c)); |
1359 case MarkLig:» » return u.markLig.apply (c); | 1314 case MarkLig:» » return TRACE_RETURN (u.markLig.apply (c)); |
1360 case MarkMark:» » return u.markMark.apply (c); | 1315 case MarkMark:» » return TRACE_RETURN (u.markMark.apply (c)); |
1361 case Context:» » return u.c.apply (c); | 1316 case Context:» » return TRACE_RETURN (u.c.apply (c)); |
1362 case ChainContext:» » return u.chainContext.apply (c); | 1317 case ChainContext:» » return TRACE_RETURN (u.chainContext.apply (c)); |
1363 case Extension:» » return u.extension.apply (c); | 1318 case Extension:» » return TRACE_RETURN (u.extension.apply (c)); |
1364 default:return false; | 1319 default:» » » return TRACE_RETURN (false); |
1365 } | 1320 } |
1366 } | 1321 } |
1367 | 1322 |
1368 inline bool sanitize (hb_sanitize_context_t *c, unsigned int lookup_type) { | 1323 inline bool sanitize (hb_sanitize_context_t *c, unsigned int lookup_type) { |
1369 TRACE_SANITIZE (); | 1324 TRACE_SANITIZE (); |
1370 switch (lookup_type) { | 1325 switch (lookup_type) { |
1371 case Single:» » return u.single.sanitize (c); | 1326 case Single:» » return TRACE_RETURN (u.single.sanitize (c)); |
1372 case Pair:» » » return u.pair.sanitize (c); | 1327 case Pair:» » » return TRACE_RETURN (u.pair.sanitize (c)); |
1373 case Cursive:» » return u.cursive.sanitize (c); | 1328 case Cursive:» » return TRACE_RETURN (u.cursive.sanitize (c)); |
1374 case MarkBase:» » return u.markBase.sanitize (c); | 1329 case MarkBase:» » return TRACE_RETURN (u.markBase.sanitize (c)); |
1375 case MarkLig:» » return u.markLig.sanitize (c); | 1330 case MarkLig:» » return TRACE_RETURN (u.markLig.sanitize (c)); |
1376 case MarkMark:» » return u.markMark.sanitize (c); | 1331 case MarkMark:» » return TRACE_RETURN (u.markMark.sanitize (c)); |
1377 case Context:» » return u.c.sanitize (c); | 1332 case Context:» » return TRACE_RETURN (u.c.sanitize (c)); |
1378 case ChainContext:» » return u.chainContext.sanitize (c); | 1333 case ChainContext:» » return TRACE_RETURN (u.chainContext.sanitize (c)
); |
1379 case Extension:» » return u.extension.sanitize (c); | 1334 case Extension:» » return TRACE_RETURN (u.extension.sanitize (c)); |
1380 default:return true; | 1335 default:» » » return TRACE_RETURN (true); |
1381 } | 1336 } |
1382 } | 1337 } |
1383 | 1338 |
1384 private: | 1339 private: |
1385 union { | 1340 union { |
1386 USHORT sub_format; | 1341 USHORT sub_format; |
1387 SinglePos single; | 1342 SinglePos single; |
1388 PairPos pair; | 1343 PairPos pair; |
1389 CursivePos cursive; | 1344 CursivePos cursive; |
1390 MarkBasePos markBase; | 1345 MarkBasePos markBase; |
1391 MarkLigPos markLig; | 1346 MarkLigPos markLig; |
1392 MarkMarkPos markMark; | 1347 MarkMarkPos markMark; |
1393 ContextPos c; | 1348 ContextPos c; |
1394 ChainContextPos chainContext; | 1349 ChainContextPos chainContext; |
1395 ExtensionPos extension; | 1350 ExtensionPos extension; |
1396 } u; | 1351 } u; |
1397 public: | 1352 public: |
1398 DEFINE_SIZE_UNION (2, sub_format); | 1353 DEFINE_SIZE_UNION (2, sub_format); |
1399 }; | 1354 }; |
1400 | 1355 |
1401 | 1356 |
1402 struct PosLookup : Lookup | 1357 struct PosLookup : Lookup |
1403 { | 1358 { |
1404 inline const PosLookupSubTable& get_subtable (unsigned int i) const | 1359 inline const PosLookupSubTable& get_subtable (unsigned int i) const |
1405 { return this+CastR<OffsetArrayOf<PosLookupSubTable> > (subTable)[i]; } | 1360 { return this+CastR<OffsetArrayOf<PosLookupSubTable> > (subTable)[i]; } |
1406 | 1361 |
1407 inline bool apply_once (hb_font_t *font, | 1362 inline bool apply_once (hb_apply_context_t *c) const |
1408 » » » hb_buffer_t *buffer, | |
1409 » » » hb_mask_t lookup_mask, | |
1410 » » » unsigned int context_length, | |
1411 » » » unsigned int nesting_level_left) const | |
1412 { | 1363 { |
1413 unsigned int lookup_type = get_type (); | 1364 unsigned int lookup_type = get_type (); |
1414 hb_apply_context_t c[1] = {{0}}; | |
1415 | 1365 |
1416 c->font = font; | 1366 if (!_hb_ot_layout_check_glyph_property (c->face, &c->buffer->cur(), c->look
up_props, &c->property)) |
1417 c->face = font->face; | |
1418 c->buffer = buffer; | |
1419 c->direction = buffer->props.direction; | |
1420 c->lookup_mask = lookup_mask; | |
1421 c->context_length = context_length; | |
1422 c->nesting_level_left = nesting_level_left; | |
1423 c->lookup_props = get_props (); | |
1424 | |
1425 if (!_hb_ot_layout_check_glyph_property (c->face, &c->buffer->info[c->buffer
->idx], c->lookup_props, &c->property)) | |
1426 return false; | 1367 return false; |
1427 | 1368 |
1428 for (unsigned int i = 0; i < get_subtable_count (); i++) | 1369 for (unsigned int i = 0; i < get_subtable_count (); i++) |
1429 if (get_subtable (i).apply (c, lookup_type)) | 1370 if (get_subtable (i).apply (c, lookup_type)) |
1430 return true; | 1371 return true; |
1431 | 1372 |
1432 return false; | 1373 return false; |
1433 } | 1374 } |
1434 | 1375 |
1435 inline bool apply_string (hb_font_t *font, | 1376 inline bool apply_string (hb_apply_context_t *c) const |
1436 » » » hb_buffer_t *buffer, | |
1437 » » » hb_mask_t mask) const | |
1438 { | 1377 { |
1439 bool ret = false; | 1378 bool ret = false; |
1440 | 1379 |
1441 if (unlikely (!buffer->len)) | 1380 if (unlikely (!c->buffer->len)) |
1442 return false; | 1381 return false; |
1443 | 1382 |
1444 buffer->idx = 0; | 1383 c->set_lookup (*this); |
1445 while (buffer->idx < buffer->len) | 1384 |
| 1385 c->buffer->idx = 0; |
| 1386 while (c->buffer->idx < c->buffer->len) |
1446 { | 1387 { |
1447 if ((buffer->info[buffer->idx].mask & mask) && | 1388 if ((c->buffer->cur().mask & c->lookup_mask) && apply_once (c)) |
1448 » apply_once (font, buffer, mask, NO_CONTEXT, MAX_NESTING_LEVEL)) | |
1449 ret = true; | 1389 ret = true; |
1450 else | 1390 else |
1451 » buffer->idx++; | 1391 » c->buffer->idx++; |
1452 } | 1392 } |
1453 | 1393 |
1454 return ret; | 1394 return ret; |
1455 } | 1395 } |
1456 | 1396 |
1457 inline bool sanitize (hb_sanitize_context_t *c) { | 1397 inline bool sanitize (hb_sanitize_context_t *c) { |
1458 TRACE_SANITIZE (); | 1398 TRACE_SANITIZE (); |
1459 if (unlikely (!Lookup::sanitize (c))) return false; | 1399 if (unlikely (!Lookup::sanitize (c))) return TRACE_RETURN (false); |
1460 OffsetArrayOf<PosLookupSubTable> &list = CastR<OffsetArrayOf<PosLookupSubTab
le> > (subTable); | 1400 OffsetArrayOf<PosLookupSubTable> &list = CastR<OffsetArrayOf<PosLookupSubTab
le> > (subTable); |
1461 return list.sanitize (c, this, get_type ()); | 1401 return TRACE_RETURN (list.sanitize (c, this, get_type ())); |
1462 } | 1402 } |
1463 }; | 1403 }; |
1464 | 1404 |
1465 typedef OffsetListOf<PosLookup> PosLookupList; | 1405 typedef OffsetListOf<PosLookup> PosLookupList; |
1466 | 1406 |
1467 /* | 1407 /* |
1468 * GPOS -- The Glyph Positioning Table | 1408 * GPOS -- The Glyph Positioning Table |
1469 */ | 1409 */ |
1470 | 1410 |
1471 struct GPOS : GSUBGPOS | 1411 struct GPOS : GSUBGPOS |
1472 { | 1412 { |
1473 static const hb_tag_t Tag = HB_OT_TAG_GPOS; | 1413 static const hb_tag_t Tag = HB_OT_TAG_GPOS; |
1474 | 1414 |
1475 inline const PosLookup& get_lookup (unsigned int i) const | 1415 inline const PosLookup& get_lookup (unsigned int i) const |
1476 { return CastR<PosLookup> (GSUBGPOS::get_lookup (i)); } | 1416 { return CastR<PosLookup> (GSUBGPOS::get_lookup (i)); } |
1477 | 1417 |
1478 inline bool position_lookup (hb_font_t *font, | 1418 inline bool position_lookup (hb_apply_context_t *c, unsigned int lookup_index)
const |
1479 » » » hb_buffer_t *buffer, | 1419 { return get_lookup (lookup_index).apply_string (c); } |
1480 » » » unsigned int lookup_index, | |
1481 » » » hb_mask_t mask) const | |
1482 { return get_lookup (lookup_index).apply_string (font, buffer, mask); } | |
1483 | 1420 |
1484 static inline void position_start (hb_buffer_t *buffer); | 1421 static inline void position_start (hb_buffer_t *buffer); |
1485 static inline void position_finish (hb_buffer_t *buffer); | 1422 static inline void position_finish (hb_buffer_t *buffer); |
1486 | 1423 |
1487 inline bool sanitize (hb_sanitize_context_t *c) { | 1424 inline bool sanitize (hb_sanitize_context_t *c) { |
1488 TRACE_SANITIZE (); | 1425 TRACE_SANITIZE (); |
1489 if (unlikely (!GSUBGPOS::sanitize (c))) return false; | 1426 if (unlikely (!GSUBGPOS::sanitize (c))) return TRACE_RETURN (false); |
1490 OffsetTo<PosLookupList> &list = CastR<OffsetTo<PosLookupList> > (lookupList)
; | 1427 OffsetTo<PosLookupList> &list = CastR<OffsetTo<PosLookupList> > (lookupList)
; |
1491 return list.sanitize (c, this); | 1428 return TRACE_RETURN (list.sanitize (c, this)); |
1492 } | 1429 } |
1493 public: | 1430 public: |
1494 DEFINE_SIZE_STATIC (10); | 1431 DEFINE_SIZE_STATIC (10); |
1495 }; | 1432 }; |
1496 | 1433 |
1497 | 1434 |
1498 static void | 1435 static void |
1499 fix_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direction
_t direction) | 1436 fix_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direction
_t direction) |
1500 { | 1437 { |
1501 unsigned int j = pos[i].cursive_chain(); | 1438 unsigned int j = pos[i].cursive_chain(); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1557 hb_direction_t direction = buffer->props.direction; | 1494 hb_direction_t direction = buffer->props.direction; |
1558 | 1495 |
1559 /* Handle cursive connections */ | 1496 /* Handle cursive connections */ |
1560 for (unsigned int i = 0; i < len; i++) | 1497 for (unsigned int i = 0; i < len; i++) |
1561 fix_cursive_minor_offset (pos, i, direction); | 1498 fix_cursive_minor_offset (pos, i, direction); |
1562 | 1499 |
1563 /* Handle attachments */ | 1500 /* Handle attachments */ |
1564 for (unsigned int i = 0; i < len; i++) | 1501 for (unsigned int i = 0; i < len; i++) |
1565 fix_mark_attachment (pos, i, direction); | 1502 fix_mark_attachment (pos, i, direction); |
1566 | 1503 |
1567 HB_BUFFER_DEALLOCATE_VAR (buffer, lig_comp); | 1504 HB_BUFFER_DEALLOCATE_VAR (buffer, syllable); |
1568 HB_BUFFER_DEALLOCATE_VAR (buffer, lig_id); | 1505 HB_BUFFER_DEALLOCATE_VAR (buffer, lig_props); |
1569 HB_BUFFER_DEALLOCATE_VAR (buffer, props_cache); | 1506 HB_BUFFER_DEALLOCATE_VAR (buffer, props_cache); |
1570 } | 1507 } |
1571 | 1508 |
1572 | 1509 |
1573 /* Out-of-class implementation for methods recursing */ | 1510 /* Out-of-class implementation for methods recursing */ |
1574 | 1511 |
1575 inline bool ExtensionPos::apply (hb_apply_context_t *c) const | 1512 inline bool ExtensionPos::apply (hb_apply_context_t *c) const |
1576 { | 1513 { |
1577 TRACE_APPLY (); | 1514 TRACE_APPLY (); |
1578 return get_subtable ().apply (c, get_type ()); | 1515 return TRACE_RETURN (get_subtable ().apply (c, get_type ())); |
1579 } | 1516 } |
1580 | 1517 |
1581 inline bool ExtensionPos::sanitize (hb_sanitize_context_t *c) | 1518 inline bool ExtensionPos::sanitize (hb_sanitize_context_t *c) |
1582 { | 1519 { |
1583 TRACE_SANITIZE (); | 1520 TRACE_SANITIZE (); |
1584 if (unlikely (!Extension::sanitize (c))) return false; | 1521 if (unlikely (!Extension::sanitize (c))) return TRACE_RETURN (false); |
1585 unsigned int offset = get_offset (); | 1522 unsigned int offset = get_offset (); |
1586 if (unlikely (!offset)) return true; | 1523 if (unlikely (!offset)) return TRACE_RETURN (true); |
1587 return StructAtOffset<PosLookupSubTable> (this, offset).sanitize (c, get_type
()); | 1524 return TRACE_RETURN (StructAtOffset<PosLookupSubTable> (this, offset).sanitize
(c, get_type ())); |
1588 } | 1525 } |
1589 | 1526 |
1590 static inline bool position_lookup (hb_apply_context_t *c, unsigned int lookup_i
ndex) | 1527 static inline bool position_lookup (hb_apply_context_t *c, unsigned int lookup_i
ndex) |
1591 { | 1528 { |
1592 const GPOS &gpos = *(c->face->ot_layout->gpos); | 1529 const GPOS &gpos = *(c->face->ot_layout->gpos); |
1593 const PosLookup &l = gpos.get_lookup (lookup_index); | 1530 const PosLookup &l = gpos.get_lookup (lookup_index); |
1594 | 1531 |
1595 if (unlikely (c->nesting_level_left == 0)) | 1532 if (unlikely (c->nesting_level_left == 0)) |
1596 return false; | 1533 return false; |
1597 | 1534 |
1598 if (unlikely (c->context_length < 1)) | 1535 hb_apply_context_t new_c (*c); |
1599 return false; | 1536 new_c.nesting_level_left--; |
1600 | 1537 new_c.set_lookup (l); |
1601 return l.apply_once (c->font, c->buffer, c->lookup_mask, c->context_length, c-
>nesting_level_left - 1); | 1538 return l.apply_once (&new_c); |
1602 } | 1539 } |
1603 | 1540 |
1604 | 1541 |
1605 #undef attach_lookback | 1542 #undef attach_lookback |
1606 #undef cursive_chain | 1543 #undef cursive_chain |
1607 | 1544 |
1608 | 1545 |
1609 | 1546 |
1610 #endif /* HB_OT_LAYOUT_GPOS_TABLE_HH */ | 1547 #endif /* HB_OT_LAYOUT_GPOS_TABLE_HH */ |
OLD | NEW |