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 { 525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) xPlacement = 0x0001u, /* Includes horizontal adjustment for placement */ 535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) yPlacement = 0x0002u, /* Includes vertical adjustment for placement */ 545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) xAdvance = 0x0004u, /* Includes horizontal adjustment for advance */ 555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) yAdvance = 0x0008u, /* Includes vertical adjustment for advance */ 565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) xPlaDevice = 0x0010u, /* Includes horizontal Device table for placement */ 575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) yPlaDevice = 0x0020u, /* Includes vertical Device table for placement */ 585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) xAdvDevice = 0x0040u, /* Includes horizontal Device table for advance */ 595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) yAdvDevice = 0x0080u, /* Includes vertical Device table for advance */ 605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ignored = 0x0F00u, /* Was used in TrueType Open for MM fonts */ 615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) reserved = 0xF000u, /* For future use */ 625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) devices = 0x00F0u /* 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) { 11223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (likely (horizontal)) glyph_pos.x_advance += font->em_scale_x (get_short (values)); 11323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) values++; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* y_advance values grow downward but font-space grows upward, hence negation */ 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (format & yAdvance) { 11723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (unlikely (!horizontal)) glyph_pos.y_advance -= font->em_scale_y (get_short (values)); 11823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) values++; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!has_device ()) return; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x_ppem = font->x_ppem; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) y_ppem = font->y_ppem; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!x_ppem && !y_ppem) return; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* pixel -> fractional pixel */ 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (format & xPlaDevice) { 13023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (x_ppem) glyph_pos.x_offset += (base + get_device (values)).get_x_delta (font); 13123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) values++; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (format & yPlaDevice) { 13423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (y_ppem) glyph_pos.y_offset += (base + get_device (values)).get_y_delta (font); 13523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) values++; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (format & xAdvDevice) { 13823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (horizontal && x_ppem) glyph_pos.x_advance += (base + get_device (values)).get_x_delta (font); 13923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) values++; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (format & yAdvDevice) { 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* y_advance values grow downward but font-space grows upward, hence negation */ 14323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (!horizontal && y_ppem) glyph_pos.y_advance -= (base + get_device (values)).get_y_delta (font); 14423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) values++; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize_value_devices (hb_sanitize_context_t *c, void *base, Value *values) { 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int format = *this; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (format & xPlacement) values++; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (format & yPlacement) values++; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (format & xAdvance) values++; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (format & yAdvance) values++; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((format & xPlaDevice) && !get_device (values++).sanitize (c, base)) return false; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((format & yPlaDevice) && !get_device (values++).sanitize (c, base)) return false; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((format & xAdvDevice) && !get_device (values++).sanitize (c, base)) return false; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((format & yAdvDevice) && !get_device (values++).sanitize (c, base)) return false; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static inline OffsetTo<Device>& get_device (Value* value) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return *CastP<OffsetTo<Device> > (value); } 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static inline const OffsetTo<Device>& get_device (const Value* value) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return *CastP<OffsetTo<Device> > (value); } 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static inline const SHORT& get_short (const Value* value) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return *CastP<SHORT> (value); } 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool has_device (void) const { 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int format = *this; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (format & devices) != 0; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize_value (hb_sanitize_context_t *c, void *base, Value *values) { 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (c->check_range (values, get_size ()) && (!has_device () || sanitize_value_devices (c, base, values))); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize_values (hb_sanitize_context_t *c, void *base, Value *values, unsigned int count) { 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int len = get_len (); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!c->check_array (values, get_size (), count)) return TRACE_RETURN (false); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!has_device ()) return TRACE_RETURN (true); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < count; i++) { 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!sanitize_value_devices (c, base, values)) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (false); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) values += len; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (true); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Just sanitize referenced Device tables. Doesn't check the values themselves. */ 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize_values_stride_unsafe (hb_sanitize_context_t *c, void *base, Value *values, unsigned int count, unsigned int stride) { 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!has_device ()) return TRACE_RETURN (true); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < count; i++) { 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!sanitize_value_devices (c, base, values)) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (false); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) values += stride; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (true); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct AnchorFormat1 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id HB_UNUSED, 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_position_t *x, hb_position_t *y) const 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *x = font->em_scale_x (xCoordinate); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *y = font->em_scale_y (yCoordinate); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (c->check_struct (this)); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier--format = 1 */ 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SHORT xCoordinate; /* Horizontal value--in design units */ 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SHORT yCoordinate; /* Vertical value--in design units */ 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_STATIC (6); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct AnchorFormat2 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id, 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_position_t *x, hb_position_t *y) const 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int x_ppem = font->x_ppem; 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int y_ppem = font->y_ppem; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_position_t cx, cy; 24923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) hb_bool_t ret; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ret = (x_ppem || y_ppem) && 25223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) font->get_glyph_contour_point_for_origin (glyph_id, anchorPoint, HB_DIRECTION_LTR, &cx, &cy); 25323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) *x = ret && x_ppem ? cx : font->em_scale_x (xCoordinate); 25423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) *y = ret && y_ppem ? cy : font->em_scale_y (yCoordinate); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (c->check_struct (this)); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier--format = 2 */ 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SHORT xCoordinate; /* Horizontal value--in design units */ 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SHORT yCoordinate; /* Vertical value--in design units */ 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT anchorPoint; /* Index to glyph contour point */ 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_STATIC (8); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct AnchorFormat3 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id HB_UNUSED, 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_position_t *x, hb_position_t *y) const 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *x = font->em_scale_x (xCoordinate); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *y = font->em_scale_y (yCoordinate); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (font->x_ppem) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *x += (this+xDeviceTable).get_x_delta (font); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (font->y_ppem) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *y += (this+yDeviceTable).get_x_delta (font); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (c->check_struct (this) && xDeviceTable.sanitize (c, this) && yDeviceTable.sanitize (c, this)); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier--format = 3 */ 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SHORT xCoordinate; /* Horizontal value--in design units */ 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SHORT yCoordinate; /* Vertical value--in design units */ 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<Device> 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xDeviceTable; /* Offset to Device table for X 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * coordinate-- from beginning of 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Anchor table (may be NULL) */ 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<Device> 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) yDeviceTable; /* Offset to Device table for Y 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * coordinate-- from beginning of 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Anchor table (may be NULL) */ 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_STATIC (10); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct Anchor 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id, 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_position_t *x, hb_position_t *y) const 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *x = *y = 0; 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: u.format1.get_anchor (font, glyph_id, x, y); return; 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 2: u.format2.get_anchor (font, glyph_id, x, y); return; 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 3: u.format3.get_anchor (font, glyph_id, x, y); return; 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: return; 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!u.format.sanitize (c)) return TRACE_RETURN (false); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: return TRACE_RETURN (u.format1.sanitize (c)); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 2: return TRACE_RETURN (u.format2.sanitize (c)); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 3: return TRACE_RETURN (u.format3.sanitize (c)); 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default:return TRACE_RETURN (true); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) union { 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier */ 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AnchorFormat1 format1; 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AnchorFormat2 format2; 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AnchorFormat3 format3; 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } u; 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_UNION (2, format); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct AnchorMatrix 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline const Anchor& get_anchor (unsigned int row, unsigned int col, unsigned int cols, bool *found) const { 346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *found = false; 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unlikely (row >= rows || col >= cols)) return Null(Anchor); 348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *found = !matrix[row * cols + col].is_null (); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return this+matrix[row * cols + col]; 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c, unsigned int cols) { 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!c->check_struct (this)) return TRACE_RETURN (false); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unlikely (rows > 0 && cols >= ((unsigned int) -1) / rows)) return TRACE_RETURN (false); 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int count = rows * cols; 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!c->check_array (matrix, matrix[0].static_size, count)) return TRACE_RETURN (false); 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < count; i++) 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!matrix[i].sanitize (c, this)) return TRACE_RETURN (false); 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (true); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT rows; /* Number of rows */ 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<Anchor> 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) matrix[VAR]; /* Matrix of offsets to Anchor tables-- 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * from beginning of AnchorMatrix table */ 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_ARRAY (2, matrix); 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct MarkRecord 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend struct MarkArray; 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c, void *base) { 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (c->check_struct (this) && markAnchor.sanitize (c, base)); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT klass; /* Class defined for this mark */ 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<Anchor> 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) markAnchor; /* Offset to Anchor table--from 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of MarkArray table */ 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_STATIC (4); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct MarkArray : ArrayOf<MarkRecord> /* Array of MarkRecords--in Coverage order */ 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool apply (hb_apply_context_t *c, 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int mark_index, unsigned int glyph_index, 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const AnchorMatrix &anchors, unsigned int class_count, 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int glyph_pos) const 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (this); 399f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_buffer_t *buffer = c->buffer; 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const MarkRecord &record = ArrayOf<MarkRecord>::operator[](mark_index); 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int mark_class = record.klass; 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Anchor& mark_anchor = this + record.markAnchor; 404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool found; 405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const Anchor& glyph_anchor = anchors.get_anchor (glyph_index, mark_class, class_count, &found); 406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /* If this subtable doesn't have an anchor for this base and this class, 407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * return false such that the subsequent subtables have a chance at it. */ 408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (unlikely (!found)) return TRACE_RETURN (false); 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_position_t mark_x, mark_y, base_x, base_y; 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 412f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) mark_anchor.get_anchor (c->font, buffer->cur().codepoint, &mark_x, &mark_y); 413f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) glyph_anchor.get_anchor (c->font, buffer->info[glyph_pos].codepoint, &base_x, &base_y); 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_glyph_position_t &o = buffer->cur_pos(); 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) o.x_offset = base_x - mark_x; 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) o.y_offset = base_y - mark_y; 418f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) o.attach_lookback() = buffer->idx - glyph_pos; 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 420f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) buffer->idx++; 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (true); 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (ArrayOf<MarkRecord>::sanitize (c, this)); 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Lookups */ 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct SinglePosFormat1 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_COLLECT_GLYPHS (this); 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (this+coverage).add_coverage (c->input); 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const Coverage &get_coverage (void) const 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return this+coverage; 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool apply (hb_apply_context_t *c) const 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (this); 449f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_buffer_t *buffer = c->buffer; 450f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valueFormat.apply_value (c->font, c->direction, this, 454f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) values, buffer->cur_pos()); 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 456f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) buffer->idx++; 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (true); 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (c->check_struct (this) && coverage.sanitize (c, this) && valueFormat.sanitize_value (c, this, values)); 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier--format = 1 */ 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<Coverage> 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coverage; /* Offset to Coverage table--from 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of subtable */ 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ValueFormat valueFormat; /* Defines the types of data in the 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ValueRecord */ 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ValueRecord values; /* Defines positioning 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * value(s)--applied to all glyphs in 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the Coverage table */ 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_ARRAY (6, values); 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct SinglePosFormat2 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_COLLECT_GLYPHS (this); 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (this+coverage).add_coverage (c->input); 4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const Coverage &get_coverage (void) const 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return this+coverage; 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool apply (hb_apply_context_t *c) const 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (this); 495f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_buffer_t *buffer = c->buffer; 496f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (index >= valueCount)) return TRACE_RETURN (false); 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valueFormat.apply_value (c->font, c->direction, this, 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &values[index * valueFormat.get_len ()], 503f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) buffer->cur_pos()); 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) buffer->idx++; 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (true); 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (c->check_struct (this) && coverage.sanitize (c, this) && valueFormat.sanitize_values (c, this, values, valueCount)); 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier--format = 2 */ 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<Coverage> 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coverage; /* Offset to Coverage table--from 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of subtable */ 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ValueFormat valueFormat; /* Defines the types of data in the 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ValueRecord */ 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT valueCount; /* Number of ValueRecords */ 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ValueRecord values; /* Array of ValueRecords--positioning 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * values applied to glyphs */ 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_ARRAY (8, values); 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct SinglePos 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) template <typename context_t> 531c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline typename context_t::return_t dispatch (context_t *c) const 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 533c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TRACE_DISPATCH (this); 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 535c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case 1: return TRACE_RETURN (c->dispatch (u.format1)); 536c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case 2: return TRACE_RETURN (c->dispatch (u.format2)); 5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default:return TRACE_RETURN (c->default_return_value ()); 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!u.format.sanitize (c)) return TRACE_RETURN (false); 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: return TRACE_RETURN (u.format1.sanitize (c)); 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 2: return TRACE_RETURN (u.format2.sanitize (c)); 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default:return TRACE_RETURN (true); 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) union { 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier */ 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SinglePosFormat1 format1; 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SinglePosFormat2 format2; 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } u; 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct PairValueRecord 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend struct PairSet; 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GlyphID secondGlyph; /* GlyphID of second glyph in the 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * pair--first glyph is listed in the 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Coverage table */ 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ValueRecord values; /* Positioning data for the first glyph 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * followed by for second glyph */ 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_ARRAY (2, values); 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct PairSet 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend struct PairPosFormat1; 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void collect_glyphs (hb_collect_glyphs_context_t *c, 5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ValueFormat *valueFormats) const 5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_COLLECT_GLYPHS (this); 5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int len1 = valueFormats[0].get_len (); 5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int len2 = valueFormats[1].get_len (); 5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int record_size = USHORT::static_size * (1 + len1 + len2); 5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const PairValueRecord *record = CastP<PairValueRecord> (array); 5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int count = len; 5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (unsigned int i = 0; i < count; i++) 5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) c->input->add (record->secondGlyph); 5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) record = &StructAtOffset<PairValueRecord> (record, record_size); 5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool apply (hb_apply_context_t *c, 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ValueFormat *valueFormats, 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int pos) const 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (this); 600f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_buffer_t *buffer = c->buffer; 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int len1 = valueFormats[0].get_len (); 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int len2 = valueFormats[1].get_len (); 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int record_size = USHORT::static_size * (1 + len1 + len2); 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PairValueRecord *record = CastP<PairValueRecord> (array); 6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int count = len; 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < count; i++) 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 609c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /* TODO bsearch */ 610f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (buffer->info[pos].codepoint == record->secondGlyph) 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valueFormats[0].apply_value (c->font, c->direction, this, 613f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) &record->values[0], buffer->cur_pos()); 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valueFormats[1].apply_value (c->font, c->direction, this, 615f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) &record->values[len1], buffer->pos[pos]); 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (len2) 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos++; 618f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) buffer->idx = pos; 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (true); 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) record = &StructAtOffset<PairValueRecord> (record, record_size); 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (false); 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct sanitize_closure_t { 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *base; 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ValueFormat *valueFormats; 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int len1; /* valueFormats[0].get_len() */ 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int stride; /* 1 + len1 + len2 */ 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c, const sanitize_closure_t *closure) { 6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(c->check_struct (this) 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && c->check_array (array, USHORT::static_size * closure->stride, len))) return TRACE_RETURN (false); 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int count = len; 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PairValueRecord *record = CastP<PairValueRecord> (array); 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (closure->valueFormats[0].sanitize_values_stride_unsafe (c, closure->base, &record->values[0], count, closure->stride) 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && closure->valueFormats[1].sanitize_values_stride_unsafe (c, closure->base, &record->values[closure->len1], count, closure->stride)); 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT len; /* Number of PairValueRecords */ 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT array[VAR]; /* Array of PairValueRecords--ordered 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * by GlyphID of the second glyph */ 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_ARRAY (2, array); 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct PairPosFormat1 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_COLLECT_GLYPHS (this); 6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (this+coverage).add_coverage (c->input); 6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int count = pairSet.len; 6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (unsigned int i = 0; i < count; i++) 6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (this+pairSet[i]).collect_glyphs (c, &valueFormat1); 6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const Coverage &get_coverage (void) const 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return this+coverage; 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool apply (hb_apply_context_t *c) const 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (this); 672f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_buffer_t *buffer = c->buffer; 673f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, buffer->idx, 1); 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 676f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!skippy_iter.next ()) return TRACE_RETURN (false); 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN ((this+pairSet[index]).apply (c, &valueFormat1, skippy_iter.idx)); 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int len1 = valueFormat1.get_len (); 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int len2 = valueFormat2.get_len (); 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PairSet::sanitize_closure_t closure = { 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &valueFormat1, 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len1, 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1 + len1 + len2 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (c->check_struct (this) && coverage.sanitize (c, this) && pairSet.sanitize (c, this, &closure)); 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier--format = 1 */ 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<Coverage> 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coverage; /* Offset to Coverage table--from 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of subtable */ 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ValueFormat valueFormat1; /* Defines the types of data in 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ValueRecord1--for the first glyph 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * in the pair--may be zero (0) */ 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ValueFormat valueFormat2; /* Defines the types of data in 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ValueRecord2--for the second glyph 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * in the pair--may be zero (0) */ 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetArrayOf<PairSet> 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pairSet; /* Array of PairSet tables 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ordered by Coverage Index */ 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_ARRAY (10, pairSet); 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct PairPosFormat2 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_COLLECT_GLYPHS (this); 7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /* (this+coverage).add_coverage (c->input); // Don't need this. */ 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int count1 = class1Count; 7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ClassDef &klass1 = this+classDef1; 7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (unsigned int i = 0; i < count1; i++) 7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) klass1.add_class (c->input, i); 7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int count2 = class2Count; 7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ClassDef &klass2 = this+classDef2; 7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (unsigned int i = 0; i < count2; i++) 7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) klass2.add_class (c->input, i); 7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const Coverage &get_coverage (void) const 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return this+coverage; 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool apply (hb_apply_context_t *c) const 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (this); 743f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_buffer_t *buffer = c->buffer; 744f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, buffer->idx, 1); 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 747f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!skippy_iter.next ()) return TRACE_RETURN (false); 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int len1 = valueFormat1.get_len (); 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int len2 = valueFormat2.get_len (); 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int record_len = len1 + len2; 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 756f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int klass1 = (this+classDef1).get_class (buffer->cur().codepoint); 757f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int klass2 = (this+classDef2).get_class (buffer->info[skippy_iter.idx].codepoint); 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unlikely (klass1 >= class1Count || klass2 >= class2Count)) return TRACE_RETURN (false); 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Value *v = &values[record_len * (klass1 * class2Count + klass2)]; 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valueFormat1.apply_value (c->font, c->direction, this, 762f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) v, buffer->cur_pos()); 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valueFormat2.apply_value (c->font, c->direction, this, 764f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) v + len1, buffer->pos[skippy_iter.idx]); 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 766f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) buffer->idx = skippy_iter.idx; 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (len2) 768f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) buffer->idx++; 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (true); 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 7742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(c->check_struct (this) 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && coverage.sanitize (c, this) 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && classDef1.sanitize (c, this) 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && classDef2.sanitize (c, this))) return TRACE_RETURN (false); 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int len1 = valueFormat1.get_len (); 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int len2 = valueFormat2.get_len (); 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int stride = len1 + len2; 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int record_size = valueFormat1.get_size () + valueFormat2.get_size (); 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int count = (unsigned int) class1Count * (unsigned int) class2Count; 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (c->check_array (values, record_size, count) && 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valueFormat1.sanitize_values_stride_unsafe (c, this, &values[0], count, stride) && 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valueFormat2.sanitize_values_stride_unsafe (c, this, &values[len1], count, stride)); 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier--format = 2 */ 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<Coverage> 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coverage; /* Offset to Coverage table--from 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of subtable */ 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ValueFormat valueFormat1; /* ValueRecord definition--for the 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * first glyph of the pair--may be zero 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * (0) */ 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ValueFormat valueFormat2; /* ValueRecord definition--for the 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * second glyph of the pair--may be 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * zero (0) */ 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<ClassDef> 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) classDef1; /* Offset to ClassDef table--from 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of PairPos subtable--for 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the first glyph of the pair */ 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<ClassDef> 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) classDef2; /* Offset to ClassDef table--from 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of PairPos subtable--for 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the second glyph of the pair */ 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT class1Count; /* Number of classes in ClassDef1 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * table--includes Class0 */ 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT class2Count; /* Number of classes in ClassDef2 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * table--includes Class0 */ 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ValueRecord values; /* Matrix of value pairs: 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * class1-major, class2-minor, 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Each entry has value1 and value2 */ 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_ARRAY (16, values); 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct PairPos 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 8222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) template <typename context_t> 823c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline typename context_t::return_t dispatch (context_t *c) const 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 825c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TRACE_DISPATCH (this); 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 827c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case 1: return TRACE_RETURN (c->dispatch (u.format1)); 828c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case 2: return TRACE_RETURN (c->dispatch (u.format2)); 8292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default:return TRACE_RETURN (c->default_return_value ()); 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 8342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!u.format.sanitize (c)) return TRACE_RETURN (false); 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: return TRACE_RETURN (u.format1.sanitize (c)); 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 2: return TRACE_RETURN (u.format2.sanitize (c)); 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default:return TRACE_RETURN (true); 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) union { 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier */ 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PairPosFormat1 format1; 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PairPosFormat2 format2; 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } u; 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct EntryExitRecord 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend struct CursivePosFormat1; 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c, void *base) { 8572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (entryAnchor.sanitize (c, base) && exitAnchor.sanitize (c, base)); 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<Anchor> 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entryAnchor; /* Offset to EntryAnchor table--from 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of CursivePos 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * subtable--may be NULL */ 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<Anchor> 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exitAnchor; /* Offset to ExitAnchor table--from 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of CursivePos 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * subtable--may be NULL */ 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_STATIC (4); 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct CursivePosFormat1 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 8762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 8772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 8782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_COLLECT_GLYPHS (this); 8792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (this+coverage).add_coverage (c->input); 8802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const Coverage &get_coverage (void) const 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return this+coverage; 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool apply (hb_apply_context_t *c) const 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (this); 890f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_buffer_t *buffer = c->buffer; 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* We don't handle mark glyphs here. */ 893f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (unlikely (_hb_glyph_info_is_mark (&buffer->cur()))) return TRACE_RETURN (false); 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, buffer->idx, 1); 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 898f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_coverage (buffer->cur().codepoint)]; 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!this_record.exitAnchor) return TRACE_RETURN (false); 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!skippy_iter.next ()) return TRACE_RETURN (false); 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 903f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const EntryExitRecord &next_record = entryExitRecord[(this+coverage).get_coverage (buffer->info[skippy_iter.idx].codepoint)]; 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!next_record.entryAnchor) return TRACE_RETURN (false); 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 906f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int i = buffer->idx; 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int j = skippy_iter.idx; 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_position_t entry_x, entry_y, exit_x, exit_y; 910f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) (this+this_record.exitAnchor).get_anchor (c->font, buffer->info[i].codepoint, &exit_x, &exit_y); 911f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) (this+next_record.entryAnchor).get_anchor (c->font, buffer->info[j].codepoint, &entry_x, &entry_y); 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 913f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_glyph_position_t *pos = buffer->pos; 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_position_t d; 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Main-direction adjustment */ 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (c->direction) { 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case HB_DIRECTION_LTR: 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[i].x_advance = exit_x + pos[i].x_offset; 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) d = entry_x + pos[j].x_offset; 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[j].x_advance -= d; 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[j].x_offset -= d; 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case HB_DIRECTION_RTL: 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) d = exit_x + pos[i].x_offset; 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[i].x_advance -= d; 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[i].x_offset -= d; 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[j].x_advance = entry_x + pos[j].x_offset; 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case HB_DIRECTION_TTB: 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[i].y_advance = exit_y + pos[i].y_offset; 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) d = entry_y + pos[j].y_offset; 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[j].y_advance -= d; 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[j].y_offset -= d; 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case HB_DIRECTION_BTT: 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) d = exit_y + pos[i].y_offset; 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[i].y_advance -= d; 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[i].y_offset -= d; 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[j].y_advance = entry_y; 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case HB_DIRECTION_INVALID: 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Cross-direction adjustment */ 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (c->lookup_props & LookupFlag::RightToLeft) { 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[i].cursive_chain() = j - i; 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction))) 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[i].y_offset = entry_y - exit_y; 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[i].x_offset = entry_x - exit_x; 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[j].cursive_chain() = i - j; 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction))) 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[j].y_offset = exit_y - entry_y; 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[j].x_offset = exit_x - entry_x; 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 966f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) buffer->idx = j; 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (true); 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 9712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (coverage.sanitize (c, this) && entryExitRecord.sanitize (c, this)); 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier--format = 1 */ 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<Coverage> 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coverage; /* Offset to Coverage table--from 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of subtable */ 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayOf<EntryExitRecord> 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entryExitRecord; /* Array of EntryExit records--in 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Coverage Index order */ 9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_ARRAY (6, entryExitRecord); 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct CursivePos 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 9892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) template <typename context_t> 990c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline typename context_t::return_t dispatch (context_t *c) const 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 992c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TRACE_DISPATCH (this); 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 994c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case 1: return TRACE_RETURN (c->dispatch (u.format1)); 9952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default:return TRACE_RETURN (c->default_return_value ()); 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 10002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!u.format.sanitize (c)) return TRACE_RETURN (false); 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: return TRACE_RETURN (u.format1.sanitize (c)); 10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default:return TRACE_RETURN (true); 10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) union { 10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier */ 10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CursivePosFormat1 format1; 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } u; 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef AnchorMatrix BaseArray; /* base-major-- 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * in order of BaseCoverage Index--, 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * mark-minor-- 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ordered by class--zero-based. */ 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct MarkBasePosFormat1 10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 10232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 10242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 10252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_COLLECT_GLYPHS (this); 10262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (this+markCoverage).add_coverage (c->input); 10272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (this+baseCoverage).add_coverage (c->input); 10282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const Coverage &get_coverage (void) const 10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return this+markCoverage; 10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool apply (hb_apply_context_t *c) const 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 10372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (this); 1038f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_buffer_t *buffer = c->buffer; 1039f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int mark_index = (this+markCoverage).get_coverage (buffer->cur().codepoint); 10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false); 10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* now we search backwards for a non-mark glyph */ 1043f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, buffer->idx, 1); 1044c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks); 10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 1046c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!skippy_iter.prev ()) return TRACE_RETURN (false); 10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* We only want to attach to the first of a MultipleSubst sequence. Reject others. */ 1048f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (0 == _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx])) break; 10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) skippy_iter.reject (); 10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (1); 10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1052f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) /* Checking that matched glyph is actually a base glyph by GDEF is too strong; disabled */ 1053f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!_hb_glyph_info_is_base_glyph (&buffer->info[skippy_iter.idx])) { /*return TRACE_RETURN (false);*/ } 10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int base_index = (this+baseCoverage).get_coverage (buffer->info[skippy_iter.idx].codepoint); 10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base_index == NOT_COVERED) return TRACE_RETURN (false); 10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN ((this+markArray).apply (c, mark_index, base_index, this+baseArray, classCount, skippy_iter.idx)); 10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 10622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (c->check_struct (this) && markCoverage.sanitize (c, this) && baseCoverage.sanitize (c, this) && 10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) markArray.sanitize (c, this) && baseArray.sanitize (c, this, (unsigned int) classCount)); 10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier--format = 1 */ 10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<Coverage> 10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) markCoverage; /* Offset to MarkCoverage table--from 10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of MarkBasePos subtable */ 10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<Coverage> 10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) baseCoverage; /* Offset to BaseCoverage table--from 10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of MarkBasePos subtable */ 10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT classCount; /* Number of classes defined for marks */ 10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<MarkArray> 10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) markArray; /* Offset to MarkArray table--from 10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of MarkBasePos subtable */ 10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<BaseArray> 10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) baseArray; /* Offset to BaseArray table--from 10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of MarkBasePos subtable */ 10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_STATIC (12); 10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct MarkBasePos 10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 10882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) template <typename context_t> 1089c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline typename context_t::return_t dispatch (context_t *c) const 10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1091c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TRACE_DISPATCH (this); 10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 1093c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case 1: return TRACE_RETURN (c->dispatch (u.format1)); 10942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default:return TRACE_RETURN (c->default_return_value ()); 10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 10992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!u.format.sanitize (c)) return TRACE_RETURN (false); 11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: return TRACE_RETURN (u.format1.sanitize (c)); 11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default:return TRACE_RETURN (true); 11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) union { 11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier */ 11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MarkBasePosFormat1 format1; 11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } u; 11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef AnchorMatrix LigatureAttach; /* component-major-- 11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * in order of writing direction--, 11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * mark-minor-- 11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ordered by class--zero-based. */ 11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef OffsetListOf<LigatureAttach> LigatureArray; 11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Array of LigatureAttach 11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * tables ordered by 11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * LigatureCoverage Index */ 11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct MarkLigPosFormat1 11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 11272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 11282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 11292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_COLLECT_GLYPHS (this); 11302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (this+markCoverage).add_coverage (c->input); 11312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (this+ligatureCoverage).add_coverage (c->input); 11322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const Coverage &get_coverage (void) const 11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return this+markCoverage; 11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool apply (hb_apply_context_t *c) const 11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 11412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (this); 1142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_buffer_t *buffer = c->buffer; 1143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int mark_index = (this+markCoverage).get_coverage (buffer->cur().codepoint); 11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false); 11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* now we search backwards for a non-mark glyph */ 1147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, buffer->idx, 1); 1148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks); 1149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!skippy_iter.prev ()) return TRACE_RETURN (false); 11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) /* Checking that matched glyph is actually a ligature by GDEF is too strong; disabled */ 1152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!_hb_glyph_info_is_ligature (&buffer->info[skippy_iter.idx])) { /*return TRACE_RETURN (false);*/ } 11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int j = skippy_iter.idx; 1155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int lig_index = (this+ligatureCoverage).get_coverage (buffer->info[j].codepoint); 11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (lig_index == NOT_COVERED) return TRACE_RETURN (false); 11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const LigatureArray& lig_array = this+ligatureArray; 11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const LigatureAttach& lig_attach = lig_array[lig_index]; 11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Find component to attach to */ 11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int comp_count = lig_attach.rows; 11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unlikely (!comp_count)) return TRACE_RETURN (false); 11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* We must now check whether the ligature ID of the current mark glyph 11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * is identical to the ligature ID of the found ligature. If yes, we 11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * can directly use the component index. If not, we attach the mark 11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * glyph to the last component of the ligature. */ 11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int comp_index; 1170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int lig_id = _hb_glyph_info_get_lig_id (&buffer->info[j]); 1171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int mark_id = _hb_glyph_info_get_lig_id (&buffer->cur()); 1172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int mark_comp = _hb_glyph_info_get_lig_comp (&buffer->cur()); 11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (lig_id && lig_id == mark_id && mark_comp > 0) 1174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) comp_index = MIN (comp_count, _hb_glyph_info_get_lig_comp (&buffer->cur())) - 1; 11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp_index = comp_count - 1; 11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN ((this+markArray).apply (c, mark_index, comp_index, lig_attach, classCount, j)); 11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 11822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (c->check_struct (this) && markCoverage.sanitize (c, this) && ligatureCoverage.sanitize (c, this) && 11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) markArray.sanitize (c, this) && ligatureArray.sanitize (c, this, (unsigned int) classCount)); 11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier--format = 1 */ 11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<Coverage> 11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) markCoverage; /* Offset to Mark Coverage table--from 11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of MarkLigPos subtable */ 11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<Coverage> 11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ligatureCoverage; /* Offset to Ligature Coverage 11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * table--from beginning of MarkLigPos 11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * subtable */ 11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT classCount; /* Number of defined mark classes */ 11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<MarkArray> 11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) markArray; /* Offset to MarkArray table--from 11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of MarkLigPos subtable */ 12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<LigatureArray> 12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ligatureArray; /* Offset to LigatureArray table--from 12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of MarkLigPos subtable */ 12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_STATIC (12); 12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct MarkLigPos 12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 12092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) template <typename context_t> 1210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline typename context_t::return_t dispatch (context_t *c) const 12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TRACE_DISPATCH (this); 12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 1214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case 1: return TRACE_RETURN (c->dispatch (u.format1)); 12152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default:return TRACE_RETURN (c->default_return_value ()); 12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 12202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!u.format.sanitize (c)) return TRACE_RETURN (false); 12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: return TRACE_RETURN (u.format1.sanitize (c)); 12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default:return TRACE_RETURN (true); 12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) union { 12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier */ 12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MarkLigPosFormat1 format1; 12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } u; 12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef AnchorMatrix Mark2Array; /* mark2-major-- 12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * in order of Mark2Coverage Index--, 12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * mark1-minor-- 12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ordered by class--zero-based. */ 12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct MarkMarkPosFormat1 12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 12432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 12442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 12452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_COLLECT_GLYPHS (this); 12462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (this+mark1Coverage).add_coverage (c->input); 12472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (this+mark2Coverage).add_coverage (c->input); 12482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const Coverage &get_coverage (void) const 12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return this+mark1Coverage; 12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool apply (hb_apply_context_t *c) const 12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 12572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (this); 1258f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_buffer_t *buffer = c->buffer; 1259f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int mark1_index = (this+mark1Coverage).get_coverage (buffer->cur().codepoint); 12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (mark1_index == NOT_COVERED)) return TRACE_RETURN (false); 12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* now we search backwards for a suitable mark glyph until a non-mark glyph */ 1263f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, buffer->idx, 1); 1264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) skippy_iter.set_lookup_props (c->lookup_props & ~LookupFlag::IgnoreFlags); 1265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!skippy_iter.prev ()) return TRACE_RETURN (false); 12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1267f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!_hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx])) { return TRACE_RETURN (false); } 12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int j = skippy_iter.idx; 12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1271f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int id1 = _hb_glyph_info_get_lig_id (&buffer->cur()); 1272f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int id2 = _hb_glyph_info_get_lig_id (&buffer->info[j]); 1273f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int comp1 = _hb_glyph_info_get_lig_comp (&buffer->cur()); 1274f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int comp2 = _hb_glyph_info_get_lig_comp (&buffer->info[j]); 12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (id1 == id2)) { 12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (id1 == 0) /* Marks belonging to the same base. */ 12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto good; 12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (comp1 == comp2) /* Marks belonging to the same ligature component. */ 12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto good; 12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If ligature ids don't match, it may be the case that one of the marks 12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * itself is a ligature. In which case match. */ 12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((id1 > 0 && !comp1) || (id2 > 0 && !comp2)) 12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto good; 12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Didn't match. */ 12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (false); 12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) good: 1292f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int mark2_index = (this+mark2Coverage).get_coverage (buffer->info[j].codepoint); 12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (mark2_index == NOT_COVERED) return TRACE_RETURN (false); 12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN ((this+mark1Array).apply (c, mark1_index, mark2_index, this+mark2Array, classCount, j)); 12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 12992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (c->check_struct (this) && mark1Coverage.sanitize (c, this) && 13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mark2Coverage.sanitize (c, this) && mark1Array.sanitize (c, this) 13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && mark2Array.sanitize (c, this, (unsigned int) classCount)); 13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier--format = 1 */ 13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<Coverage> 13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mark1Coverage; /* Offset to Combining Mark1 Coverage 13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * table--from beginning of MarkMarkPos 13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * subtable */ 13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<Coverage> 13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mark2Coverage; /* Offset to Combining Mark2 Coverage 13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * table--from beginning of MarkMarkPos 13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * subtable */ 13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT classCount; /* Number of defined mark classes */ 13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<MarkArray> 13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mark1Array; /* Offset to Mark1Array table--from 13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of MarkMarkPos subtable */ 13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<Mark2Array> 13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mark2Array; /* Offset to Mark2Array table--from 13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of MarkMarkPos subtable */ 13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_STATIC (12); 13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct MarkMarkPos 13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 13282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) template <typename context_t> 1329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline typename context_t::return_t dispatch (context_t *c) const 13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TRACE_DISPATCH (this); 13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 1333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case 1: return TRACE_RETURN (c->dispatch (u.format1)); 13342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default:return TRACE_RETURN (c->default_return_value ()); 13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 13392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!u.format.sanitize (c)) return TRACE_RETURN (false); 13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: return TRACE_RETURN (u.format1.sanitize (c)); 13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default:return TRACE_RETURN (true); 13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) union { 13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier */ 13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MarkMarkPosFormat1 format1; 13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } u; 13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct ContextPos : Context {}; 13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct ChainContextPos : ChainContext {}; 13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct ExtensionPos : Extension<ExtensionPos> 13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 13612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef struct PosLookupSubTable LookupSubTable; 13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * PosLookup 13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct PosLookupSubTable 13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend struct PosLookup; 13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum Type { 13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Single = 1, 13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pair = 2, 13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Cursive = 3, 13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MarkBase = 4, 13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MarkLig = 5, 13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MarkMark = 6, 13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Context = 7, 13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChainContext = 8, 13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Extension = 9 13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) template <typename context_t> 1388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type) const 13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TRACE_DISPATCH (this); 13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (lookup_type) { 1392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case Single: return TRACE_RETURN (u.single.dispatch (c)); 1393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case Pair: return TRACE_RETURN (u.pair.dispatch (c)); 1394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case Cursive: return TRACE_RETURN (u.cursive.dispatch (c)); 1395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case MarkBase: return TRACE_RETURN (u.markBase.dispatch (c)); 1396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case MarkLig: return TRACE_RETURN (u.markLig.dispatch (c)); 1397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case MarkMark: return TRACE_RETURN (u.markMark.dispatch (c)); 1398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case Context: return TRACE_RETURN (u.context.dispatch (c)); 1399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case ChainContext: return TRACE_RETURN (u.chainContext.dispatch (c)); 1400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case Extension: return TRACE_RETURN (u.extension.dispatch (c)); 14012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: return TRACE_RETURN (c->default_return_value ()); 14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c, unsigned int lookup_type) { 14062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!u.header.sub_format.sanitize (c)) 14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (false); 14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (lookup_type) { 14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case Single: return TRACE_RETURN (u.single.sanitize (c)); 14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case Pair: return TRACE_RETURN (u.pair.sanitize (c)); 14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case Cursive: return TRACE_RETURN (u.cursive.sanitize (c)); 14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MarkBase: return TRACE_RETURN (u.markBase.sanitize (c)); 14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MarkLig: return TRACE_RETURN (u.markLig.sanitize (c)); 14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MarkMark: return TRACE_RETURN (u.markMark.sanitize (c)); 14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case Context: return TRACE_RETURN (u.context.sanitize (c)); 14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ChainContext: return TRACE_RETURN (u.chainContext.sanitize (c)); 14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case Extension: return TRACE_RETURN (u.extension.sanitize (c)); 14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: return TRACE_RETURN (true); 14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) union { 14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct { 14262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) USHORT sub_format; 14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } header; 14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SinglePos single; 14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PairPos pair; 14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CursivePos cursive; 14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MarkBasePos markBase; 14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MarkLigPos markLig; 14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MarkMarkPos markMark; 14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContextPos context; 14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChainContextPos chainContext; 14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionPos extension; 14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } u; 14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_UNION (2, header.sub_format); 14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct PosLookup : Lookup 14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const PosLookupSubTable& get_subtable (unsigned int i) const 14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return this+CastR<OffsetArrayOf<PosLookupSubTable> > (subTable)[i]; } 14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1448f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) inline bool is_reverse (void) const 1449f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) { 1450f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return false; 1451f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1452f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1453f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) inline hb_collect_glyphs_context_t::return_t collect_glyphs (hb_collect_glyphs_context_t *c) const 14542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 14552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_COLLECT_GLYPHS (this); 14562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) c->set_recurse_func (NULL); 1457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return TRACE_RETURN (dispatch (c)); 14582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 14592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <typename set_t> 14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void add_coverage (set_t *glyphs) const 14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 14632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_get_coverage_context_t c; 14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Coverage *last = NULL; 14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int count = get_subtable_count (); 14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < count; i++) { 1467c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const Coverage *coverage = &get_subtable (i).dispatch (&c, get_type ()); 14682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (coverage != last) { 14692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) coverage->add_coverage (glyphs); 14702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last = coverage; 14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool apply_once (hb_apply_context_t *c) const 14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 14772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (this); 1478c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!c->check_glyph_property (&c->buffer->cur(), c->lookup_props)) 14792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return TRACE_RETURN (false); 1480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return TRACE_RETURN (dispatch (c)); 14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static bool apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index); 14842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1485c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) template <typename context_t> 1486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static inline typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index); 1487c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1488c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) template <typename context_t> 1489c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline typename context_t::return_t dispatch (context_t *c) const 1490c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { 1491c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TRACE_DISPATCH (this); 1492c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned int lookup_type = get_type (); 1493c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned int count = get_subtable_count (); 1494c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (unsigned int i = 0; i < count; i++) { 1495c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) typename context_t::return_t r = get_subtable (i).dispatch (c, lookup_type); 1496c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (c->stop_sublookup_iteration (r)) 1497c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return TRACE_RETURN (r); 1498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1499c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return TRACE_RETURN (c->default_return_value ()); 1500c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 15032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unlikely (!Lookup::sanitize (c))) return TRACE_RETURN (false); 15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetArrayOf<PosLookupSubTable> &list = CastR<OffsetArrayOf<PosLookupSubTable> > (subTable); 15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (list.sanitize (c, this, get_type ())); 15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef OffsetListOf<PosLookup> PosLookupList; 15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * GPOS -- The Glyph Positioning Table 15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct GPOS : GSUBGPOS 15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1518f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) static const hb_tag_t tableTag = HB_OT_TAG_GPOS; 15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const PosLookup& get_lookup (unsigned int i) const 15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return CastR<PosLookup> (GSUBGPOS::get_lookup (i)); } 15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static inline void position_start (hb_font_t *font, hb_buffer_t *buffer); 1524c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static inline void position_finish (hb_font_t *font, hb_buffer_t *buffer); 15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 15272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unlikely (!GSUBGPOS::sanitize (c))) return TRACE_RETURN (false); 15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<PosLookupList> &list = CastR<OffsetTo<PosLookupList> > (lookupList); 15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (list.sanitize (c, this)); 15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_STATIC (10); 15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fix_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction) 15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int j = pos[i].cursive_chain(); 15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (!j)) 15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) j += i; 15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[i].cursive_chain() = 0; 15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fix_cursive_minor_offset (pos, j, direction); 15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HB_DIRECTION_IS_HORIZONTAL (direction)) 15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[i].y_offset += pos[j].y_offset; 15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[i].x_offset += pos[j].x_offset; 15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 1557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)fix_mark_attachment (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction) 15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (!(pos[i].attach_lookback()))) 15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int j = i - pos[i].attach_lookback(); 15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[i].x_offset += pos[j].x_offset; 15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[i].y_offset += pos[j].y_offset; 15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HB_DIRECTION_IS_FORWARD (direction)) 15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int k = j; k < i; k++) { 15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[i].x_offset -= pos[k].x_advance; 15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[i].y_offset -= pos[k].y_advance; 15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int k = j + 1; k < i + 1; k++) { 15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[i].x_offset += pos[k].x_advance; 15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos[i].y_offset += pos[k].y_advance; 15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GPOS::position_start (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) 15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer->clear_positions (); 15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int count = buffer->len; 15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < count; i++) 15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer->pos[i].attach_lookback() = buffer->pos[i].cursive_chain() = 0; 15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 1590c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)GPOS::position_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) 15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 159203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) _hb_buffer_assert_gsubgpos_vars (buffer); 159303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int len; 15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, &len); 15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_direction_t direction = buffer->props.direction; 15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Handle cursive connections */ 15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < len; i++) 16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fix_cursive_minor_offset (pos, i, direction); 16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Handle attachments */ 16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < len; i++) 1604c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fix_mark_attachment (pos, i, direction); 16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Out-of-class implementation for methods recursing */ 16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template <typename context_t> 16115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)/*static*/ inline typename context_t::return_t PosLookup::dispatch_recurse_func (context_t *c, unsigned int lookup_index) 16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 16132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GPOS &gpos = *(hb_ot_layout_from_face (c->face)->gpos); 16142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const PosLookup &l = gpos.get_lookup (lookup_index); 1615c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return l.dispatch (c); 16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)/*static*/ inline bool PosLookup::apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index) 16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GPOS &gpos = *(hb_ot_layout_from_face (c->face)->gpos); 16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PosLookup &l = gpos.get_lookup (lookup_index); 16222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int saved_lookup_props = c->lookup_props; 16232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) c->set_lookup (l); 16242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool ret = l.apply_once (c); 16252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) c->lookup_props = saved_lookup_props; 16262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ret; 16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef attach_lookback 16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef cursive_chain 16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} /* namespace OT */ 16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* HB_OT_LAYOUT_GPOS_TABLE_HH */ 1638