15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright © 2007,2008,2009,2010 Red Hat, Inc. 3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * Copyright © 2010,2012,2013 Google, Inc. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This is part of HarfBuzz, a text shaping library. 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Permission is hereby granted, without written agreement and without 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * license or royalty fees, to use, copy, modify, and distribute this 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * software and its documentation for any purpose, provided that the 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * above copyright notice and the following two paragraphs appear in 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * all copies of this software. 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * DAMAGE. 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Red Hat Author(s): Behdad Esfahbod 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Google Author(s): Behdad Esfahbod 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef HB_OT_LAYOUT_GPOS_TABLE_HH 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HB_OT_LAYOUT_GPOS_TABLE_HH 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "hb-ot-layout-gsubgpos-private.hh" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace OT { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* buffer **position** var allocations */ 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define attach_lookback() var.u16[0] /* number of glyphs to go back to attach this glyph to its base */ 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define cursive_chain() var.i16[1] /* character to which this connects, may be positive or negative */ 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Shared Tables: ValueRecord, Anchor Table, and MarkArray */ 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef USHORT Value; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef Value ValueRecord[VAR]; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ValueFormat : USHORT 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum Flags { 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xPlacement = 0x0001, /* Includes horizontal adjustment for placement */ 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) yPlacement = 0x0002, /* Includes vertical adjustment for placement */ 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xAdvance = 0x0004, /* Includes horizontal adjustment for advance */ 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) yAdvance = 0x0008, /* Includes vertical adjustment for advance */ 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xPlaDevice = 0x0010, /* Includes horizontal Device table for placement */ 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) yPlaDevice = 0x0020, /* Includes vertical Device table for placement */ 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xAdvDevice = 0x0040, /* Includes horizontal Device table for advance */ 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) yAdvDevice = 0x0080, /* Includes vertical Device table for advance */ 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ignored = 0x0F00, /* Was used in TrueType Open for MM fonts */ 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reserved = 0xF000, /* For future use */ 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) devices = 0x00F0 /* Mask for having any Device table */ 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* All fields are options. Only those available advance the value pointer. */ 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if 0 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SHORT xPlacement; /* Horizontal adjustment for 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * placement--in design units */ 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SHORT yPlacement; /* Vertical adjustment for 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * placement--in design units */ 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SHORT xAdvance; /* Horizontal adjustment for 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * advance--in design units (only used 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * for horizontal writing) */ 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SHORT yAdvance; /* Vertical adjustment for advance--in 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * design units (only used for vertical 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * writing) */ 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Offset xPlaDevice; /* Offset to Device table for 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * horizontal placement--measured from 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of PosTable (may be NULL) */ 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Offset yPlaDevice; /* Offset to Device table for vertical 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * placement--measured from beginning 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * of PosTable (may be NULL) */ 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Offset xAdvDevice; /* Offset to Device table for 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * horizontal advance--measured from 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of PosTable (may be NULL) */ 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Offset yAdvDevice; /* Offset to Device table for vertical 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * advance--measured from beginning of 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * PosTable (may be NULL) */ 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline unsigned int get_len (void) const 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return _hb_popcount32 ((unsigned int) *this); } 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline unsigned int get_size (void) const 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return get_len () * Value::static_size; } 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void apply_value (hb_font_t *font, 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_direction_t direction, 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *base, 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Value *values, 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_glyph_position_t &glyph_pos) const 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int x_ppem, y_ppem; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int format = *this; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_bool_t horizontal = HB_DIRECTION_IS_HORIZONTAL (direction); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!format) return; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (format & xPlacement) glyph_pos.x_offset += font->em_scale_x (get_short (values++)); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (format & yPlacement) glyph_pos.y_offset += font->em_scale_y (get_short (values++)); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (format & xAdvance) { 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (horizontal)) glyph_pos.x_advance += font->em_scale_x (get_short (values++)); else values++; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* y_advance values grow downward but font-space grows upward, hence negation */ 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (format & yAdvance) { 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unlikely (!horizontal)) glyph_pos.y_advance -= font->em_scale_y (get_short (values++)); else values++; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!has_device ()) return; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x_ppem = font->x_ppem; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) y_ppem = font->y_ppem; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!x_ppem && !y_ppem) return; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* pixel -> fractional pixel */ 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (format & xPlaDevice) { 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (x_ppem) glyph_pos.x_offset += (base + get_device (values++)).get_x_delta (font); else values++; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (format & yPlaDevice) { 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (y_ppem) glyph_pos.y_offset += (base + get_device (values++)).get_y_delta (font); else values++; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (format & xAdvDevice) { 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (horizontal && x_ppem) glyph_pos.x_advance += (base + get_device (values++)).get_x_delta (font); else values++; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (format & yAdvDevice) { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* y_advance values grow downward but font-space grows upward, hence negation */ 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!horizontal && y_ppem) glyph_pos.y_advance -= (base + get_device (values++)).get_y_delta (font); else values++; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize_value_devices (hb_sanitize_context_t *c, void *base, Value *values) { 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int format = *this; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (format & xPlacement) values++; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (format & yPlacement) values++; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (format & xAdvance) values++; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (format & yAdvance) values++; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((format & xPlaDevice) && !get_device (values++).sanitize (c, base)) return false; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((format & yPlaDevice) && !get_device (values++).sanitize (c, base)) return false; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((format & xAdvDevice) && !get_device (values++).sanitize (c, base)) return false; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((format & yAdvDevice) && !get_device (values++).sanitize (c, base)) return false; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static inline OffsetTo<Device>& get_device (Value* value) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return *CastP<OffsetTo<Device> > (value); } 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static inline const OffsetTo<Device>& get_device (const Value* value) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return *CastP<OffsetTo<Device> > (value); } 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static inline const SHORT& get_short (const Value* value) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return *CastP<SHORT> (value); } 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool has_device (void) const { 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int format = *this; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (format & devices) != 0; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize_value (hb_sanitize_context_t *c, void *base, Value *values) { 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (c->check_range (values, get_size ()) && (!has_device () || sanitize_value_devices (c, base, values))); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize_values (hb_sanitize_context_t *c, void *base, Value *values, unsigned int count) { 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int len = get_len (); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!c->check_array (values, get_size (), count)) return TRACE_RETURN (false); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!has_device ()) return TRACE_RETURN (true); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < count; i++) { 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!sanitize_value_devices (c, base, values)) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (false); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) values += len; 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (true); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Just sanitize referenced Device tables. Doesn't check the values themselves. */ 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize_values_stride_unsafe (hb_sanitize_context_t *c, void *base, Value *values, unsigned int count, unsigned int stride) { 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!has_device ()) return TRACE_RETURN (true); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < count; i++) { 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!sanitize_value_devices (c, base, values)) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (false); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) values += stride; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (true); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct AnchorFormat1 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id HB_UNUSED, 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_position_t *x, hb_position_t *y) const 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *x = font->em_scale_x (xCoordinate); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *y = font->em_scale_y (yCoordinate); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (c->check_struct (this)); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier--format = 1 */ 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SHORT xCoordinate; /* Horizontal value--in design units */ 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SHORT yCoordinate; /* Vertical value--in design units */ 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_STATIC (6); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct AnchorFormat2 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id, 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_position_t *x, hb_position_t *y) const 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int x_ppem = font->x_ppem; 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int y_ppem = font->y_ppem; 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_position_t cx, cy; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_bool_t ret = false; 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (x_ppem || y_ppem) 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = font->get_glyph_contour_point_for_origin (glyph_id, anchorPoint, HB_DIRECTION_LTR, &cx, &cy); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *x = x_ppem && ret ? cx : font->em_scale_x (xCoordinate); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *y = y_ppem && ret ? cy : font->em_scale_y (yCoordinate); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (c->check_struct (this)); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier--format = 2 */ 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SHORT xCoordinate; /* Horizontal value--in design units */ 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SHORT yCoordinate; /* Vertical value--in design units */ 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT anchorPoint; /* Index to glyph contour point */ 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_STATIC (8); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct AnchorFormat3 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id HB_UNUSED, 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_position_t *x, hb_position_t *y) const 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *x = font->em_scale_x (xCoordinate); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *y = font->em_scale_y (yCoordinate); 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (font->x_ppem) 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *x += (this+xDeviceTable).get_x_delta (font); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (font->y_ppem) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *y += (this+yDeviceTable).get_x_delta (font); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (c->check_struct (this) && xDeviceTable.sanitize (c, this) && yDeviceTable.sanitize (c, this)); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier--format = 3 */ 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SHORT xCoordinate; /* Horizontal value--in design units */ 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SHORT yCoordinate; /* Vertical value--in design units */ 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<Device> 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xDeviceTable; /* Offset to Device table for X 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * coordinate-- from beginning of 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Anchor table (may be NULL) */ 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<Device> 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) yDeviceTable; /* Offset to Device table for Y 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * coordinate-- from beginning of 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Anchor table (may be NULL) */ 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_STATIC (10); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct Anchor 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id, 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_position_t *x, hb_position_t *y) const 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *x = *y = 0; 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: u.format1.get_anchor (font, glyph_id, x, y); return; 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 2: u.format2.get_anchor (font, glyph_id, x, y); return; 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 3: u.format3.get_anchor (font, glyph_id, x, y); return; 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: return; 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!u.format.sanitize (c)) return TRACE_RETURN (false); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: return TRACE_RETURN (u.format1.sanitize (c)); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 2: return TRACE_RETURN (u.format2.sanitize (c)); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 3: return TRACE_RETURN (u.format3.sanitize (c)); 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default:return TRACE_RETURN (true); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) union { 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier */ 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AnchorFormat1 format1; 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AnchorFormat2 format2; 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AnchorFormat3 format3; 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } u; 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_UNION (2, format); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct AnchorMatrix 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline const Anchor& get_anchor (unsigned int row, unsigned int col, unsigned int cols, bool *found) const { 340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *found = false; 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unlikely (row >= rows || col >= cols)) return Null(Anchor); 342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *found = !matrix[row * cols + col].is_null (); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return this+matrix[row * cols + col]; 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c, unsigned int cols) { 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!c->check_struct (this)) return TRACE_RETURN (false); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unlikely (rows > 0 && cols >= ((unsigned int) -1) / rows)) return TRACE_RETURN (false); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int count = rows * cols; 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!c->check_array (matrix, matrix[0].static_size, count)) return TRACE_RETURN (false); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < count; i++) 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!matrix[i].sanitize (c, this)) return TRACE_RETURN (false); 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (true); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT rows; /* Number of rows */ 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<Anchor> 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) matrix[VAR]; /* Matrix of offsets to Anchor tables-- 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * from beginning of AnchorMatrix table */ 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_ARRAY (2, matrix); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct MarkRecord 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend struct MarkArray; 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c, void *base) { 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (c->check_struct (this) && markAnchor.sanitize (c, base)); 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT klass; /* Class defined for this mark */ 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<Anchor> 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) markAnchor; /* Offset to Anchor table--from 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of MarkArray table */ 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_STATIC (4); 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct MarkArray : ArrayOf<MarkRecord> /* Array of MarkRecords--in Coverage order */ 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool apply (hb_apply_context_t *c, 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int mark_index, unsigned int glyph_index, 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const AnchorMatrix &anchors, unsigned int class_count, 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int glyph_pos) const 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (this); 393f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_buffer_t *buffer = c->buffer; 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const MarkRecord &record = ArrayOf<MarkRecord>::operator[](mark_index); 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int mark_class = record.klass; 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Anchor& mark_anchor = this + record.markAnchor; 398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool found; 399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const Anchor& glyph_anchor = anchors.get_anchor (glyph_index, mark_class, class_count, &found); 400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /* If this subtable doesn't have an anchor for this base and this class, 401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * return false such that the subsequent subtables have a chance at it. */ 402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (unlikely (!found)) return TRACE_RETURN (false); 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_position_t mark_x, mark_y, base_x, base_y; 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 406f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) mark_anchor.get_anchor (c->font, buffer->cur().codepoint, &mark_x, &mark_y); 407f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) glyph_anchor.get_anchor (c->font, buffer->info[glyph_pos].codepoint, &base_x, &base_y); 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 409f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_glyph_position_t &o = buffer->cur_pos(); 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) o.x_offset = base_x - mark_x; 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) o.y_offset = base_y - mark_y; 412f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) o.attach_lookback() = buffer->idx - glyph_pos; 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 414f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) buffer->idx++; 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (true); 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (ArrayOf<MarkRecord>::sanitize (c, this)); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Lookups */ 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct SinglePosFormat1 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_COLLECT_GLYPHS (this); 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (this+coverage).add_coverage (c->input); 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const Coverage &get_coverage (void) const 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return this+coverage; 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool apply (hb_apply_context_t *c) const 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (this); 443f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_buffer_t *buffer = c->buffer; 444f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valueFormat.apply_value (c->font, c->direction, this, 448f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) values, buffer->cur_pos()); 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 450f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) buffer->idx++; 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (true); 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (c->check_struct (this) && coverage.sanitize (c, this) && valueFormat.sanitize_value (c, this, values)); 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier--format = 1 */ 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<Coverage> 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coverage; /* Offset to Coverage table--from 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of subtable */ 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ValueFormat valueFormat; /* Defines the types of data in the 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ValueRecord */ 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ValueRecord values; /* Defines positioning 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * value(s)--applied to all glyphs in 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the Coverage table */ 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_ARRAY (6, values); 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct SinglePosFormat2 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_COLLECT_GLYPHS (this); 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (this+coverage).add_coverage (c->input); 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const Coverage &get_coverage (void) const 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return this+coverage; 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool apply (hb_apply_context_t *c) const 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (this); 489f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_buffer_t *buffer = c->buffer; 490f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (index >= valueCount)) return TRACE_RETURN (false); 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valueFormat.apply_value (c->font, c->direction, this, 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &values[index * valueFormat.get_len ()], 497f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) buffer->cur_pos()); 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 499f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) buffer->idx++; 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (true); 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (c->check_struct (this) && coverage.sanitize (c, this) && valueFormat.sanitize_values (c, this, values, valueCount)); 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier--format = 2 */ 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<Coverage> 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coverage; /* Offset to Coverage table--from 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of subtable */ 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ValueFormat valueFormat; /* Defines the types of data in the 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ValueRecord */ 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT valueCount; /* Number of ValueRecords */ 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ValueRecord values; /* Array of ValueRecords--positioning 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * values applied to glyphs */ 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_ARRAY (8, values); 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct SinglePos 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) template <typename context_t> 525c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline typename context_t::return_t dispatch (context_t *c) const 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 527c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TRACE_DISPATCH (this); 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 529c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case 1: return TRACE_RETURN (c->dispatch (u.format1)); 530c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case 2: return TRACE_RETURN (c->dispatch (u.format2)); 5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default:return TRACE_RETURN (c->default_return_value ()); 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!u.format.sanitize (c)) return TRACE_RETURN (false); 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: return TRACE_RETURN (u.format1.sanitize (c)); 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 2: return TRACE_RETURN (u.format2.sanitize (c)); 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default:return TRACE_RETURN (true); 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) union { 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier */ 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SinglePosFormat1 format1; 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SinglePosFormat2 format2; 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } u; 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct PairValueRecord 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend struct PairSet; 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GlyphID secondGlyph; /* GlyphID of second glyph in the 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * pair--first glyph is listed in the 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Coverage table */ 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ValueRecord values; /* Positioning data for the first glyph 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * followed by for second glyph */ 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_ARRAY (2, values); 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct PairSet 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend struct PairPosFormat1; 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void collect_glyphs (hb_collect_glyphs_context_t *c, 5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ValueFormat *valueFormats) const 5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_COLLECT_GLYPHS (this); 5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int len1 = valueFormats[0].get_len (); 5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int len2 = valueFormats[1].get_len (); 5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int record_size = USHORT::static_size * (1 + len1 + len2); 5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const PairValueRecord *record = CastP<PairValueRecord> (array); 5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int count = len; 5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (unsigned int i = 0; i < count; i++) 5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) c->input->add (record->secondGlyph); 5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) record = &StructAtOffset<PairValueRecord> (record, record_size); 5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool apply (hb_apply_context_t *c, 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ValueFormat *valueFormats, 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int pos) const 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (this); 594f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_buffer_t *buffer = c->buffer; 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int len1 = valueFormats[0].get_len (); 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int len2 = valueFormats[1].get_len (); 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int record_size = USHORT::static_size * (1 + len1 + len2); 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PairValueRecord *record = CastP<PairValueRecord> (array); 6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int count = len; 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < count; i++) 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 603c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /* TODO bsearch */ 604f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (buffer->info[pos].codepoint == record->secondGlyph) 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valueFormats[0].apply_value (c->font, c->direction, this, 607f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) &record->values[0], buffer->cur_pos()); 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valueFormats[1].apply_value (c->font, c->direction, this, 609f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) &record->values[len1], buffer->pos[pos]); 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (len2) 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos++; 612f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) buffer->idx = pos; 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (true); 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) record = &StructAtOffset<PairValueRecord> (record, record_size); 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (false); 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct sanitize_closure_t { 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *base; 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ValueFormat *valueFormats; 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int len1; /* valueFormats[0].get_len() */ 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int stride; /* 1 + len1 + len2 */ 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c, const sanitize_closure_t *closure) { 6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(c->check_struct (this) 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && c->check_array (array, USHORT::static_size * closure->stride, len))) return TRACE_RETURN (false); 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int count = len; 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PairValueRecord *record = CastP<PairValueRecord> (array); 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (closure->valueFormats[0].sanitize_values_stride_unsafe (c, closure->base, &record->values[0], count, closure->stride) 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && closure->valueFormats[1].sanitize_values_stride_unsafe (c, closure->base, &record->values[closure->len1], count, closure->stride)); 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT len; /* Number of PairValueRecords */ 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT array[VAR]; /* Array of PairValueRecords--ordered 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * by GlyphID of the second glyph */ 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_ARRAY (2, array); 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct PairPosFormat1 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_COLLECT_GLYPHS (this); 6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (this+coverage).add_coverage (c->input); 6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int count = pairSet.len; 6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (unsigned int i = 0; i < count; i++) 6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (this+pairSet[i]).collect_glyphs (c, &valueFormat1); 6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const Coverage &get_coverage (void) const 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return this+coverage; 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool apply (hb_apply_context_t *c) const 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (this); 666f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_buffer_t *buffer = c->buffer; 667f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, buffer->idx, 1); 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 670f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!skippy_iter.next ()) return TRACE_RETURN (false); 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN ((this+pairSet[index]).apply (c, &valueFormat1, skippy_iter.idx)); 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int len1 = valueFormat1.get_len (); 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int len2 = valueFormat2.get_len (); 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PairSet::sanitize_closure_t closure = { 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &valueFormat1, 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len1, 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1 + len1 + len2 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (c->check_struct (this) && coverage.sanitize (c, this) && pairSet.sanitize (c, this, &closure)); 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier--format = 1 */ 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<Coverage> 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coverage; /* Offset to Coverage table--from 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of subtable */ 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ValueFormat valueFormat1; /* Defines the types of data in 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ValueRecord1--for the first glyph 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * in the pair--may be zero (0) */ 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ValueFormat valueFormat2; /* Defines the types of data in 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ValueRecord2--for the second glyph 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * in the pair--may be zero (0) */ 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetArrayOf<PairSet> 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pairSet; /* Array of PairSet tables 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ordered by Coverage Index */ 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_ARRAY (10, pairSet); 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct PairPosFormat2 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_COLLECT_GLYPHS (this); 7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /* (this+coverage).add_coverage (c->input); // Don't need this. */ 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int count1 = class1Count; 7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ClassDef &klass1 = this+classDef1; 7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (unsigned int i = 0; i < count1; i++) 7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) klass1.add_class (c->input, i); 7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int count2 = class2Count; 7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ClassDef &klass2 = this+classDef2; 7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (unsigned int i = 0; i < count2; i++) 7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) klass2.add_class (c->input, i); 7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const Coverage &get_coverage (void) const 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return this+coverage; 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool apply (hb_apply_context_t *c) const 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (this); 737f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_buffer_t *buffer = c->buffer; 738f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, buffer->idx, 1); 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 741f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!skippy_iter.next ()) return TRACE_RETURN (false); 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int len1 = valueFormat1.get_len (); 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int len2 = valueFormat2.get_len (); 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int record_len = len1 + len2; 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 750f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int klass1 = (this+classDef1).get_class (buffer->cur().codepoint); 751f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int klass2 = (this+classDef2).get_class (buffer->info[skippy_iter.idx].codepoint); 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unlikely (klass1 >= class1Count || klass2 >= class2Count)) return TRACE_RETURN (false); 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Value *v = &values[record_len * (klass1 * class2Count + klass2)]; 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valueFormat1.apply_value (c->font, c->direction, this, 756f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) v, buffer->cur_pos()); 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valueFormat2.apply_value (c->font, c->direction, this, 758f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) v + len1, buffer->pos[skippy_iter.idx]); 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 760f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) buffer->idx = skippy_iter.idx; 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (len2) 762f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) buffer->idx++; 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (true); 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(c->check_struct (this) 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && coverage.sanitize (c, this) 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && classDef1.sanitize (c, this) 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && classDef2.sanitize (c, this))) return TRACE_RETURN (false); 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int len1 = valueFormat1.get_len (); 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int len2 = valueFormat2.get_len (); 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int stride = len1 + len2; 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int record_size = valueFormat1.get_size () + valueFormat2.get_size (); 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int count = (unsigned int) class1Count * (unsigned int) class2Count; 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (c->check_array (values, record_size, count) && 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valueFormat1.sanitize_values_stride_unsafe (c, this, &values[0], count, stride) && 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valueFormat2.sanitize_values_stride_unsafe (c, this, &values[len1], count, stride)); 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier--format = 2 */ 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<Coverage> 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coverage; /* Offset to Coverage table--from 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of subtable */ 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ValueFormat valueFormat1; /* ValueRecord definition--for the 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * first glyph of the pair--may be zero 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * (0) */ 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ValueFormat valueFormat2; /* ValueRecord definition--for the 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * second glyph of the pair--may be 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * zero (0) */ 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<ClassDef> 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) classDef1; /* Offset to ClassDef table--from 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of PairPos subtable--for 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the first glyph of the pair */ 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<ClassDef> 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) classDef2; /* Offset to ClassDef table--from 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of PairPos subtable--for 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the second glyph of the pair */ 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT class1Count; /* Number of classes in ClassDef1 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * table--includes Class0 */ 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT class2Count; /* Number of classes in ClassDef2 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * table--includes Class0 */ 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ValueRecord values; /* Matrix of value pairs: 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * class1-major, class2-minor, 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Each entry has value1 and value2 */ 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_ARRAY (16, values); 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct PairPos 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 8162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) template <typename context_t> 817c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline typename context_t::return_t dispatch (context_t *c) const 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 819c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TRACE_DISPATCH (this); 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 821c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case 1: return TRACE_RETURN (c->dispatch (u.format1)); 822c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case 2: return TRACE_RETURN (c->dispatch (u.format2)); 8232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default:return TRACE_RETURN (c->default_return_value ()); 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 8282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!u.format.sanitize (c)) return TRACE_RETURN (false); 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: return TRACE_RETURN (u.format1.sanitize (c)); 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 2: return TRACE_RETURN (u.format2.sanitize (c)); 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default:return TRACE_RETURN (true); 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) union { 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier */ 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PairPosFormat1 format1; 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PairPosFormat2 format2; 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } u; 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct EntryExitRecord 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend struct CursivePosFormat1; 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c, void *base) { 8512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (entryAnchor.sanitize (c, base) && exitAnchor.sanitize (c, base)); 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<Anchor> 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entryAnchor; /* Offset to EntryAnchor table--from 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of CursivePos 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * subtable--may be NULL */ 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<Anchor> 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exitAnchor; /* Offset to ExitAnchor table--from 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of CursivePos 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * subtable--may be NULL */ 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_STATIC (4); 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct CursivePosFormat1 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 8702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 8712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 8722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_COLLECT_GLYPHS (this); 8732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (this+coverage).add_coverage (c->input); 8742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const Coverage &get_coverage (void) const 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return this+coverage; 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool apply (hb_apply_context_t *c) const 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (this); 884f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_buffer_t *buffer = c->buffer; 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* We don't handle mark glyphs here. */ 887f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (unlikely (_hb_glyph_info_is_mark (&buffer->cur()))) return TRACE_RETURN (false); 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 889f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, buffer->idx, 1); 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 892f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_coverage (buffer->cur().codepoint)]; 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!this_record.exitAnchor) return TRACE_RETURN (false); 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!skippy_iter.next ()) return TRACE_RETURN (false); 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 897f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const EntryExitRecord &next_record = entryExitRecord[(this+coverage).get_coverage (buffer->info[skippy_iter.idx].codepoint)]; 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!next_record.entryAnchor) return TRACE_RETURN (false); 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 900f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int i = buffer->idx; 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int j = skippy_iter.idx; 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_position_t entry_x, entry_y, exit_x, exit_y; 904f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) (this+this_record.exitAnchor).get_anchor (c->font, buffer->info[i].codepoint, &exit_x, &exit_y); 905f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) (this+next_record.entryAnchor).get_anchor (c->font, buffer->info[j].codepoint, &entry_x, &entry_y); 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 907f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_glyph_position_t *pos = buffer->pos; 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_position_t d; 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Main-direction adjustment */ 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (c->direction) { 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case HB_DIRECTION_LTR: 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[i].x_advance = exit_x + pos[i].x_offset; 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) d = entry_x + pos[j].x_offset; 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[j].x_advance -= d; 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[j].x_offset -= d; 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case HB_DIRECTION_RTL: 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) d = exit_x + pos[i].x_offset; 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[i].x_advance -= d; 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[i].x_offset -= d; 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[j].x_advance = entry_x + pos[j].x_offset; 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case HB_DIRECTION_TTB: 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[i].y_advance = exit_y + pos[i].y_offset; 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) d = entry_y + pos[j].y_offset; 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[j].y_advance -= d; 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[j].y_offset -= d; 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case HB_DIRECTION_BTT: 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) d = exit_y + pos[i].y_offset; 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[i].y_advance -= d; 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[i].y_offset -= d; 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[j].y_advance = entry_y; 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case HB_DIRECTION_INVALID: 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Cross-direction adjustment */ 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (c->lookup_props & LookupFlag::RightToLeft) { 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[i].cursive_chain() = j - i; 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction))) 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[i].y_offset = entry_y - exit_y; 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[i].x_offset = entry_x - exit_x; 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[j].cursive_chain() = i - j; 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction))) 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[j].y_offset = exit_y - entry_y; 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[j].x_offset = exit_x - entry_x; 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 960f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) buffer->idx = j; 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (true); 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 9652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (coverage.sanitize (c, this) && entryExitRecord.sanitize (c, this)); 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier--format = 1 */ 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<Coverage> 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coverage; /* Offset to Coverage table--from 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of subtable */ 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayOf<EntryExitRecord> 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entryExitRecord; /* Array of EntryExit records--in 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Coverage Index order */ 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_ARRAY (6, entryExitRecord); 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct CursivePos 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 9832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) template <typename context_t> 984c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline typename context_t::return_t dispatch (context_t *c) const 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 986c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TRACE_DISPATCH (this); 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 988c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case 1: return TRACE_RETURN (c->dispatch (u.format1)); 9892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default:return TRACE_RETURN (c->default_return_value ()); 9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 9942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!u.format.sanitize (c)) return TRACE_RETURN (false); 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: return TRACE_RETURN (u.format1.sanitize (c)); 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default:return TRACE_RETURN (true); 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) union { 10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier */ 10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CursivePosFormat1 format1; 10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } u; 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef AnchorMatrix BaseArray; /* base-major-- 10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * in order of BaseCoverage Index--, 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * mark-minor-- 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ordered by class--zero-based. */ 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct MarkBasePosFormat1 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 10172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 10182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 10192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_COLLECT_GLYPHS (this); 10202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (this+markCoverage).add_coverage (c->input); 10212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (this+baseCoverage).add_coverage (c->input); 10222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const Coverage &get_coverage (void) const 10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return this+markCoverage; 10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool apply (hb_apply_context_t *c) const 10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 10312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (this); 1032f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_buffer_t *buffer = c->buffer; 1033f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int mark_index = (this+markCoverage).get_coverage (buffer->cur().codepoint); 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false); 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* now we search backwards for a non-mark glyph */ 1037f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, buffer->idx, 1); 1038c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks); 10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 1040c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!skippy_iter.prev ()) return TRACE_RETURN (false); 10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* We only want to attach to the first of a MultipleSubst sequence. Reject others. */ 1042f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (0 == _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx])) break; 10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) skippy_iter.reject (); 10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (1); 10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1046f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) /* Checking that matched glyph is actually a base glyph by GDEF is too strong; disabled */ 1047f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!_hb_glyph_info_is_base_glyph (&buffer->info[skippy_iter.idx])) { /*return TRACE_RETURN (false);*/ } 10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1049f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int base_index = (this+baseCoverage).get_coverage (buffer->info[skippy_iter.idx].codepoint); 10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base_index == NOT_COVERED) return TRACE_RETURN (false); 10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN ((this+markArray).apply (c, mark_index, base_index, this+baseArray, classCount, skippy_iter.idx)); 10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 10562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (c->check_struct (this) && markCoverage.sanitize (c, this) && baseCoverage.sanitize (c, this) && 10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) markArray.sanitize (c, this) && baseArray.sanitize (c, this, (unsigned int) classCount)); 10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier--format = 1 */ 10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<Coverage> 10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) markCoverage; /* Offset to MarkCoverage table--from 10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of MarkBasePos subtable */ 10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<Coverage> 10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) baseCoverage; /* Offset to BaseCoverage table--from 10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of MarkBasePos subtable */ 10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT classCount; /* Number of classes defined for marks */ 10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<MarkArray> 10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) markArray; /* Offset to MarkArray table--from 10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of MarkBasePos subtable */ 10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<BaseArray> 10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) baseArray; /* Offset to BaseArray table--from 10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of MarkBasePos subtable */ 10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_STATIC (12); 10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct MarkBasePos 10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 10822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) template <typename context_t> 1083c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline typename context_t::return_t dispatch (context_t *c) const 10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1085c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TRACE_DISPATCH (this); 10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 1087c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case 1: return TRACE_RETURN (c->dispatch (u.format1)); 10882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default:return TRACE_RETURN (c->default_return_value ()); 10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 10932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!u.format.sanitize (c)) return TRACE_RETURN (false); 10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: return TRACE_RETURN (u.format1.sanitize (c)); 10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default:return TRACE_RETURN (true); 10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) union { 11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier */ 11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MarkBasePosFormat1 format1; 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } u; 11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef AnchorMatrix LigatureAttach; /* component-major-- 11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * in order of writing direction--, 11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * mark-minor-- 11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ordered by class--zero-based. */ 11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef OffsetListOf<LigatureAttach> LigatureArray; 11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Array of LigatureAttach 11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * tables ordered by 11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * LigatureCoverage Index */ 11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct MarkLigPosFormat1 11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 11212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 11222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 11232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_COLLECT_GLYPHS (this); 11242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (this+markCoverage).add_coverage (c->input); 11252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (this+ligatureCoverage).add_coverage (c->input); 11262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const Coverage &get_coverage (void) const 11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return this+markCoverage; 11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool apply (hb_apply_context_t *c) const 11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 11352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (this); 1136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_buffer_t *buffer = c->buffer; 1137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int mark_index = (this+markCoverage).get_coverage (buffer->cur().codepoint); 11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false); 11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* now we search backwards for a non-mark glyph */ 1141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, buffer->idx, 1); 1142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks); 1143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!skippy_iter.prev ()) return TRACE_RETURN (false); 11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) /* Checking that matched glyph is actually a ligature by GDEF is too strong; disabled */ 1146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!_hb_glyph_info_is_ligature (&buffer->info[skippy_iter.idx])) { /*return TRACE_RETURN (false);*/ } 11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int j = skippy_iter.idx; 1149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int lig_index = (this+ligatureCoverage).get_coverage (buffer->info[j].codepoint); 11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (lig_index == NOT_COVERED) return TRACE_RETURN (false); 11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const LigatureArray& lig_array = this+ligatureArray; 11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const LigatureAttach& lig_attach = lig_array[lig_index]; 11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Find component to attach to */ 11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int comp_count = lig_attach.rows; 11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unlikely (!comp_count)) return TRACE_RETURN (false); 11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* We must now check whether the ligature ID of the current mark glyph 11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * is identical to the ligature ID of the found ligature. If yes, we 11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * can directly use the component index. If not, we attach the mark 11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * glyph to the last component of the ligature. */ 11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int comp_index; 1164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int lig_id = _hb_glyph_info_get_lig_id (&buffer->info[j]); 1165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int mark_id = _hb_glyph_info_get_lig_id (&buffer->cur()); 1166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int mark_comp = _hb_glyph_info_get_lig_comp (&buffer->cur()); 11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (lig_id && lig_id == mark_id && mark_comp > 0) 1168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) comp_index = MIN (comp_count, _hb_glyph_info_get_lig_comp (&buffer->cur())) - 1; 11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp_index = comp_count - 1; 11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN ((this+markArray).apply (c, mark_index, comp_index, lig_attach, classCount, j)); 11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 11762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (c->check_struct (this) && markCoverage.sanitize (c, this) && ligatureCoverage.sanitize (c, this) && 11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) markArray.sanitize (c, this) && ligatureArray.sanitize (c, this, (unsigned int) classCount)); 11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier--format = 1 */ 11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<Coverage> 11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) markCoverage; /* Offset to Mark Coverage table--from 11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of MarkLigPos subtable */ 11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<Coverage> 11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ligatureCoverage; /* Offset to Ligature Coverage 11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * table--from beginning of MarkLigPos 11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * subtable */ 11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT classCount; /* Number of defined mark classes */ 11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<MarkArray> 11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) markArray; /* Offset to MarkArray table--from 11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of MarkLigPos subtable */ 11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<LigatureArray> 11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ligatureArray; /* Offset to LigatureArray table--from 11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of MarkLigPos subtable */ 11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_STATIC (12); 11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct MarkLigPos 12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 12032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) template <typename context_t> 1204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline typename context_t::return_t dispatch (context_t *c) const 12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TRACE_DISPATCH (this); 12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 1208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case 1: return TRACE_RETURN (c->dispatch (u.format1)); 12092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default:return TRACE_RETURN (c->default_return_value ()); 12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 12142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!u.format.sanitize (c)) return TRACE_RETURN (false); 12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: return TRACE_RETURN (u.format1.sanitize (c)); 12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default:return TRACE_RETURN (true); 12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) union { 12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier */ 12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MarkLigPosFormat1 format1; 12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } u; 12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef AnchorMatrix Mark2Array; /* mark2-major-- 12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * in order of Mark2Coverage Index--, 12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * mark1-minor-- 12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ordered by class--zero-based. */ 12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct MarkMarkPosFormat1 12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 12372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 12382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 12392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_COLLECT_GLYPHS (this); 12402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (this+mark1Coverage).add_coverage (c->input); 12412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (this+mark2Coverage).add_coverage (c->input); 12422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const Coverage &get_coverage (void) const 12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return this+mark1Coverage; 12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool apply (hb_apply_context_t *c) const 12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 12512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (this); 1252f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_buffer_t *buffer = c->buffer; 1253f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int mark1_index = (this+mark1Coverage).get_coverage (buffer->cur().codepoint); 12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (mark1_index == NOT_COVERED)) return TRACE_RETURN (false); 12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* now we search backwards for a suitable mark glyph until a non-mark glyph */ 1257f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, buffer->idx, 1); 1258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) skippy_iter.set_lookup_props (c->lookup_props & ~LookupFlag::IgnoreFlags); 1259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!skippy_iter.prev ()) return TRACE_RETURN (false); 12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1261f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!_hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx])) { return TRACE_RETURN (false); } 12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int j = skippy_iter.idx; 12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int id1 = _hb_glyph_info_get_lig_id (&buffer->cur()); 1266f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int id2 = _hb_glyph_info_get_lig_id (&buffer->info[j]); 1267f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int comp1 = _hb_glyph_info_get_lig_comp (&buffer->cur()); 1268f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int comp2 = _hb_glyph_info_get_lig_comp (&buffer->info[j]); 12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (id1 == id2)) { 12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (id1 == 0) /* Marks belonging to the same base. */ 12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto good; 12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (comp1 == comp2) /* Marks belonging to the same ligature component. */ 12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto good; 12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If ligature ids don't match, it may be the case that one of the marks 12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * itself is a ligature. In which case match. */ 12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((id1 > 0 && !comp1) || (id2 > 0 && !comp2)) 12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto good; 12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Didn't match. */ 12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (false); 12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) good: 1286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int mark2_index = (this+mark2Coverage).get_coverage (buffer->info[j].codepoint); 12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (mark2_index == NOT_COVERED) return TRACE_RETURN (false); 12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN ((this+mark1Array).apply (c, mark1_index, mark2_index, this+mark2Array, classCount, j)); 12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 12932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (c->check_struct (this) && mark1Coverage.sanitize (c, this) && 12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mark2Coverage.sanitize (c, this) && mark1Array.sanitize (c, this) 12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && mark2Array.sanitize (c, this, (unsigned int) classCount)); 12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier--format = 1 */ 13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<Coverage> 13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mark1Coverage; /* Offset to Combining Mark1 Coverage 13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * table--from beginning of MarkMarkPos 13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * subtable */ 13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<Coverage> 13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mark2Coverage; /* Offset to Combining Mark2 Coverage 13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * table--from beginning of MarkMarkPos 13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * subtable */ 13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT classCount; /* Number of defined mark classes */ 13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<MarkArray> 13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mark1Array; /* Offset to Mark1Array table--from 13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of MarkMarkPos subtable */ 13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<Mark2Array> 13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mark2Array; /* Offset to Mark2Array table--from 13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of MarkMarkPos subtable */ 13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_STATIC (12); 13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct MarkMarkPos 13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 13222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) template <typename context_t> 1323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline typename context_t::return_t dispatch (context_t *c) const 13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TRACE_DISPATCH (this); 13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 1327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case 1: return TRACE_RETURN (c->dispatch (u.format1)); 13282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default:return TRACE_RETURN (c->default_return_value ()); 13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 13332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!u.format.sanitize (c)) return TRACE_RETURN (false); 13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: return TRACE_RETURN (u.format1.sanitize (c)); 13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default:return TRACE_RETURN (true); 13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) union { 13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier */ 13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MarkMarkPosFormat1 format1; 13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } u; 13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct ContextPos : Context {}; 13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct ChainContextPos : ChainContext {}; 13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct ExtensionPos : Extension<ExtensionPos> 13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 13552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef struct PosLookupSubTable LookupSubTable; 13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * PosLookup 13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct PosLookupSubTable 13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend struct PosLookup; 13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum Type { 13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Single = 1, 13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pair = 2, 13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Cursive = 3, 13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MarkBase = 4, 13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MarkLig = 5, 13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MarkMark = 6, 13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Context = 7, 13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChainContext = 8, 13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Extension = 9 13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) template <typename context_t> 1382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type) const 13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TRACE_DISPATCH (this); 13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (lookup_type) { 1386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case Single: return TRACE_RETURN (u.single.dispatch (c)); 1387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case Pair: return TRACE_RETURN (u.pair.dispatch (c)); 1388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case Cursive: return TRACE_RETURN (u.cursive.dispatch (c)); 1389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case MarkBase: return TRACE_RETURN (u.markBase.dispatch (c)); 1390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case MarkLig: return TRACE_RETURN (u.markLig.dispatch (c)); 1391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case MarkMark: return TRACE_RETURN (u.markMark.dispatch (c)); 1392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case Context: return TRACE_RETURN (u.context.dispatch (c)); 1393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case ChainContext: return TRACE_RETURN (u.chainContext.dispatch (c)); 1394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case Extension: return TRACE_RETURN (u.extension.dispatch (c)); 13952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: return TRACE_RETURN (c->default_return_value ()); 13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c, unsigned int lookup_type) { 14002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!u.header.sub_format.sanitize (c)) 14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (false); 14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (lookup_type) { 14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case Single: return TRACE_RETURN (u.single.sanitize (c)); 14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case Pair: return TRACE_RETURN (u.pair.sanitize (c)); 14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case Cursive: return TRACE_RETURN (u.cursive.sanitize (c)); 14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MarkBase: return TRACE_RETURN (u.markBase.sanitize (c)); 14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MarkLig: return TRACE_RETURN (u.markLig.sanitize (c)); 14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MarkMark: return TRACE_RETURN (u.markMark.sanitize (c)); 14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case Context: return TRACE_RETURN (u.context.sanitize (c)); 14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ChainContext: return TRACE_RETURN (u.chainContext.sanitize (c)); 14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case Extension: return TRACE_RETURN (u.extension.sanitize (c)); 14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: return TRACE_RETURN (true); 14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) union { 14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct { 14202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) USHORT sub_format; 14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } header; 14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SinglePos single; 14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PairPos pair; 14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CursivePos cursive; 14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MarkBasePos markBase; 14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MarkLigPos markLig; 14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MarkMarkPos markMark; 14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContextPos context; 14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChainContextPos chainContext; 14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionPos extension; 14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } u; 14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_UNION (2, header.sub_format); 14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct PosLookup : Lookup 14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const PosLookupSubTable& get_subtable (unsigned int i) const 14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return this+CastR<OffsetArrayOf<PosLookupSubTable> > (subTable)[i]; } 14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1442f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) inline bool is_reverse (void) const 1443f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) { 1444f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return false; 1445f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1446f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1447f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) inline hb_collect_glyphs_context_t::return_t collect_glyphs (hb_collect_glyphs_context_t *c) const 14482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 14492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_COLLECT_GLYPHS (this); 14502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) c->set_recurse_func (NULL); 1451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return TRACE_RETURN (dispatch (c)); 14522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 14532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <typename set_t> 14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void add_coverage (set_t *glyphs) const 14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 14572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_get_coverage_context_t c; 14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Coverage *last = NULL; 14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int count = get_subtable_count (); 14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < count; i++) { 1461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const Coverage *coverage = &get_subtable (i).dispatch (&c, get_type ()); 14622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (coverage != last) { 14632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) coverage->add_coverage (glyphs); 14642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last = coverage; 14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool apply_once (hb_apply_context_t *c) const 14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 14712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (this); 1472c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!c->check_glyph_property (&c->buffer->cur(), c->lookup_props)) 14732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return TRACE_RETURN (false); 1474c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return TRACE_RETURN (dispatch (c)); 14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static bool apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index); 14782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) template <typename context_t> 1480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static inline typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index); 1481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) template <typename context_t> 1483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline typename context_t::return_t dispatch (context_t *c) const 1484c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { 1485c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TRACE_DISPATCH (this); 1486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned int lookup_type = get_type (); 1487c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned int count = get_subtable_count (); 1488c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (unsigned int i = 0; i < count; i++) { 1489c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) typename context_t::return_t r = get_subtable (i).dispatch (c, lookup_type); 1490c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (c->stop_sublookup_iteration (r)) 1491c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return TRACE_RETURN (r); 1492c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1493c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return TRACE_RETURN (c->default_return_value ()); 1494c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1495c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 14972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unlikely (!Lookup::sanitize (c))) return TRACE_RETURN (false); 14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetArrayOf<PosLookupSubTable> &list = CastR<OffsetArrayOf<PosLookupSubTable> > (subTable); 15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (list.sanitize (c, this, get_type ())); 15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef OffsetListOf<PosLookup> PosLookupList; 15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * GPOS -- The Glyph Positioning Table 15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct GPOS : GSUBGPOS 15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1512f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) static const hb_tag_t tableTag = HB_OT_TAG_GPOS; 15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const PosLookup& get_lookup (unsigned int i) const 15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return CastR<PosLookup> (GSUBGPOS::get_lookup (i)); } 15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static inline void position_start (hb_font_t *font, hb_buffer_t *buffer); 1518c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static inline void position_finish (hb_font_t *font, hb_buffer_t *buffer); 15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 15212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unlikely (!GSUBGPOS::sanitize (c))) return TRACE_RETURN (false); 15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<PosLookupList> &list = CastR<OffsetTo<PosLookupList> > (lookupList); 15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (list.sanitize (c, this)); 15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_STATIC (10); 15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fix_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction) 15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int j = pos[i].cursive_chain(); 15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (!j)) 15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) j += i; 15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[i].cursive_chain() = 0; 15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fix_cursive_minor_offset (pos, j, direction); 15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HB_DIRECTION_IS_HORIZONTAL (direction)) 15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[i].y_offset += pos[j].y_offset; 15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[i].x_offset += pos[j].x_offset; 15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 1551c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)fix_mark_attachment (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction) 15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (!(pos[i].attach_lookback()))) 15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int j = i - pos[i].attach_lookback(); 15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[i].x_offset += pos[j].x_offset; 15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[i].y_offset += pos[j].y_offset; 15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HB_DIRECTION_IS_FORWARD (direction)) 15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int k = j; k < i; k++) { 15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[i].x_offset -= pos[k].x_advance; 15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[i].y_offset -= pos[k].y_advance; 15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int k = j + 1; k < i + 1; k++) { 15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[i].x_offset += pos[k].x_advance; 15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[i].y_offset += pos[k].y_advance; 15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GPOS::position_start (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) 15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer->clear_positions (); 15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int count = buffer->len; 15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < count; i++) 15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer->pos[i].attach_lookback() = buffer->pos[i].cursive_chain() = 0; 15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 1584c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)GPOS::position_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) 15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int len; 15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, &len); 15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_direction_t direction = buffer->props.direction; 15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Handle cursive connections */ 15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < len; i++) 15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fix_cursive_minor_offset (pos, i, direction); 15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Handle attachments */ 15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < len; i++) 1596c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fix_mark_attachment (pos, i, direction); 15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1598f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) _hb_buffer_deallocate_gsubgpos_vars (buffer); 15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Out-of-class implementation for methods recursing */ 16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template <typename context_t> 1605c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)inline typename context_t::return_t PosLookup::dispatch_recurse_func (context_t *c, unsigned int lookup_index) 16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 16072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GPOS &gpos = *(hb_ot_layout_from_face (c->face)->gpos); 16082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const PosLookup &l = gpos.get_lookup (lookup_index); 1609c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return l.dispatch (c); 16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)inline bool PosLookup::apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index) 16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GPOS &gpos = *(hb_ot_layout_from_face (c->face)->gpos); 16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PosLookup &l = gpos.get_lookup (lookup_index); 16162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int saved_lookup_props = c->lookup_props; 16172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) c->set_lookup (l); 16182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool ret = l.apply_once (c); 16192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) c->lookup_props = saved_lookup_props; 16202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ret; 16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef attach_lookback 16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef cursive_chain 16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} /* namespace OT */ 16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* HB_OT_LAYOUT_GPOS_TABLE_HH */ 1632