| 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 |