OLD | NEW |
1 /* | 1 /* |
2 * Copyright © 2007,2008,2009,2010 Red Hat, Inc. | 2 * Copyright © 2007,2008,2009,2010 Red Hat, Inc. |
3 * Copyright © 2010,2012,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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 */ |
OLD | NEW |