hb-ot-layout-common-private.hh revision 67bb9e8cea49a44be6996515e1c7d8cdc95a77e6
16f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod/*
22409d5f8d7dd8b535ce5ea29e933f7db27d33793Behdad Esfahbod * Copyright © 2007,2008,2009  Red Hat, Inc.
35b93e8d94fb4c2474816304ae3f52e1c704882deBehdad Esfahbod * Copyright © 2010,2012  Google, Inc.
46f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod *
5c755cb3e3ac55156d0d2ec05adea7a650b97cc41Behdad Esfahbod *  This is part of HarfBuzz, a text shaping library.
66f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod *
76f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * Permission is hereby granted, without written agreement and without
86f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * license or royalty fees, to use, copy, modify, and distribute this
96f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * software and its documentation for any purpose, provided that the
106f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * above copyright notice and the following two paragraphs appear in
116f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * all copies of this software.
126f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod *
136f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
146f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
156f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
166f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
176f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * DAMAGE.
186f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod *
196f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
206f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
216f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
226f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
236f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
246f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod *
256f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * Red Hat Author(s): Behdad Esfahbod
265bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod * Google Author(s): Behdad Esfahbod
276f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod */
286f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
295f5b24f99f52bbc922e238b65c06061ba07c8548Behdad Esfahbod#ifndef HB_OT_LAYOUT_COMMON_PRIVATE_HH
305f5b24f99f52bbc922e238b65c06061ba07c8548Behdad Esfahbod#define HB_OT_LAYOUT_COMMON_PRIVATE_HH
316f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
3222da7fd94d6318c52df69d70470a85464ffc533dBehdad Esfahbod#include "hb-ot-layout-private.hh"
337edb430f9182723b7b720708c56088cec1200a70Behdad Esfahbod#include "hb-open-type-private.hh"
340b08adb3539f2ec29682456b89c69e89ff5e9c03Behdad Esfahbod#include "hb-set-private.hh"
356f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
366f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
37cd33cb9ed84308da72bd7c64b9355dc2410c63ecBehdad Esfahbod#define NOT_COVERED		((unsigned int) 0x110000)
38cd33cb9ed84308da72bd7c64b9355dc2410c63ecBehdad Esfahbod#define MAX_NESTING_LEVEL	8
39cd33cb9ed84308da72bd7c64b9355dc2410c63ecBehdad Esfahbod
40acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod
41cd33cb9ed84308da72bd7c64b9355dc2410c63ecBehdad Esfahbod
426f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod/*
436f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod *
446f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * OpenType Layout Common Table Formats
456f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod *
466f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod */
476f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
482e8fb6c38dbc01cb77b384c0ae0212514dfbb588Behdad Esfahbod
496f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod/*
506f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * Script, ScriptList, LangSys, Feature, FeatureList, Lookup, LookupList
516f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod */
526f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
536f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbodtemplate <typename Type>
5460d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct Record
5560d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{
564e573715ae5f5ed486ad66382bb44c47a86591ffBehdad Esfahbod  inline int cmp (hb_tag_t a) const {
5736b3862009c00ad922d68810173a69ac59723365Behdad Esfahbod    return tag.cmp (a);
58cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod  }
59cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod
60d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod  inline bool sanitize (hb_sanitize_context_t *c, void *base) {
613e2401f6c53d2b047954d75c37aef5e5e7cdc51aBehdad Esfahbod    TRACE_SANITIZE ();
620ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod    return TRACE_RETURN (c->check_struct (this) && offset.sanitize (c, base));
63cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod  }
64cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod
656f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod  Tag		tag;		/* 4-byte Tag identifier */
666f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod  OffsetTo<Type>
676f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod		offset;		/* Offset from beginning of object holding
686f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod				 * the Record */
69569da92bc6956f42d9b2d65c784e184fb6380efeBehdad Esfahbod  public:
70569da92bc6956f42d9b2d65c784e184fb6380efeBehdad Esfahbod  DEFINE_SIZE_STATIC (6);
716f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod};
726f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
736f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbodtemplate <typename Type>
74cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbodstruct RecordArrayOf : SortedArrayOf<Record<Type> > {
7560d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod  inline const Tag& get_tag (unsigned int i) const
7660d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod  {
774e22c7e94102c9f00c32b8cb6aaa832f83909149Behdad Esfahbod    /* We cheat slightly and don't define separate Null objects
784e22c7e94102c9f00c32b8cb6aaa832f83909149Behdad Esfahbod     * for Record types.  Instead, we return the correct Null(Tag)
794e22c7e94102c9f00c32b8cb6aaa832f83909149Behdad Esfahbod     * here. */
8064d3fc8d0dada673245cc8c0b1c12cd849b30997Behdad Esfahbod    if (unlikely (i >= this->len)) return Null(Tag);
81d3480ba37fbb5d4be75b094060f5b2f1ce98fb53Behdad Esfahbod    return (*this)[i].tag;
826f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod  }
83e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod  inline unsigned int get_tags (unsigned int start_offset,
84e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod				unsigned int *record_count /* IN/OUT */,
85e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod				hb_tag_t     *record_tags /* OUT */) const
86bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod  {
87e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod    if (record_count) {
8831f18abecb149f8888a72510f2660328dd6de16dBehdad Esfahbod      const Record<Type> *arr = this->sub_array (start_offset, record_count);
8948de3730cdf91b9f6473509e22260a902ccec992Behdad Esfahbod      unsigned int count = *record_count;
90e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod      for (unsigned int i = 0; i < count; i++)
9131f18abecb149f8888a72510f2660328dd6de16dBehdad Esfahbod	record_tags[i] = arr[i].tag;
92e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod    }
93e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod    return this->len;
94bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod  }
95bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod  inline bool find_index (hb_tag_t tag, unsigned int *index) const
96bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod  {
97cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod    int i = this->search (tag);
98cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod    if (i != -1) {
99bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod        if (index) *index = i;
100bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod        return true;
101cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod    } else {
102cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod      if (index) *index = Index::NOT_FOUND_INDEX;
103cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod      return false;
104bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod    }
105bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod  }
106bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod};
107bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod
108bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbodtemplate <typename Type>
109bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbodstruct RecordListOf : RecordArrayOf<Type>
110bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod{
111bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod  inline const Type& operator [] (unsigned int i) const
1126bec81aa3a58b8be255568b2ea63b7854e1b0ea7Behdad Esfahbod  { return this+RecordArrayOf<Type>::operator [](i).offset; }
113cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod
114d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod  inline bool sanitize (hb_sanitize_context_t *c) {
1153e2401f6c53d2b047954d75c37aef5e5e7cdc51aBehdad Esfahbod    TRACE_SANITIZE ();
1160ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod    return TRACE_RETURN (RecordArrayOf<Type>::sanitize (c, this));
117cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod  }
1186f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod};
1196f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
1206f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
121cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbodstruct RangeRecord
122cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod{
123cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod  inline int cmp (hb_codepoint_t g) const {
124cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod    hb_codepoint_t a = start, b = end;
125cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod    return g < a ? -1 : g <= b ? 0 : +1 ;
126cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod  }
127cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod
128cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod  inline bool sanitize (hb_sanitize_context_t *c) {
129cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod    TRACE_SANITIZE ();
1300ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod    return TRACE_RETURN (c->check_struct (this));
131cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod  }
132cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod
1336a9be5bd3524dc3eb1e88d1063bde2e4d8b57011Behdad Esfahbod  inline bool intersects (const hb_set_t *glyphs) const {
13431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod    return glyphs->intersects (start, end);
13531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod  }
13631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod
13767bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod  inline void add_coverage (hb_set_t *glyphs) const {
13867bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod    glyphs->add_range (start, end);
13967bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod  }
14067bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod
141cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod  GlyphID	start;		/* First GlyphID in the range */
142cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod  GlyphID	end;		/* Last GlyphID in the range */
143cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod  USHORT	value;		/* Value */
144cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod  public:
145cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod  DEFINE_SIZE_STATIC (6);
146cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod};
147cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad EsfahbodDEFINE_NULL_DATA (RangeRecord, "\000\001");
148cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod
149cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod
150b5db4f1e4eefa266a71a28b5496f47ff9d1a81e8Behdad Esfahbodstruct IndexArray : ArrayOf<Index>
151bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod{
152e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod  inline unsigned int get_indexes (unsigned int start_offset,
153e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod				   unsigned int *_count /* IN/OUT */,
154e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod				   unsigned int *_indexes /* OUT */) const
155bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod  {
156e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod    if (_count) {
15731f18abecb149f8888a72510f2660328dd6de16dBehdad Esfahbod      const USHORT *arr = this->sub_array (start_offset, _count);
15848de3730cdf91b9f6473509e22260a902ccec992Behdad Esfahbod      unsigned int count = *_count;
159e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod      for (unsigned int i = 0; i < count; i++)
16031f18abecb149f8888a72510f2660328dd6de16dBehdad Esfahbod	_indexes[i] = arr[i];
161e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod    }
162e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod    return this->len;
163bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod  }
164bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod};
165bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod
166bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod
1676f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbodstruct Script;
1686f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbodstruct LangSys;
1696f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbodstruct Feature;
1706f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
1716f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
17260d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct LangSys
17360d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{
174bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod  inline unsigned int get_feature_count (void) const
175bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod  { return featureIndex.len; }
176bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod  inline hb_tag_t get_feature_index (unsigned int i) const
177bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod  { return featureIndex[i]; }
178e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod  inline unsigned int get_feature_indexes (unsigned int start_offset,
179e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod					   unsigned int *feature_count /* IN/OUT */,
180e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod					   unsigned int *feature_indexes /* OUT */) const
181e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod  { return featureIndex.get_indexes (start_offset, feature_count, feature_indexes); }
1826f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
183cc6c644ff2af5f6669b6ec100ff13e904872b21cBehdad Esfahbod  inline bool has_required_feature (void) const { return reqFeatureIndex != 0xffff; }
1843d44fb6f15177dc6518166e435597936b044acc1Behdad Esfahbod  inline unsigned int get_required_feature_index (void) const
18560d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod  {
1866f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod    if (reqFeatureIndex == 0xffff)
187b5db4f1e4eefa266a71a28b5496f47ff9d1a81e8Behdad Esfahbod      return Index::NOT_FOUND_INDEX;
1886f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod   return reqFeatureIndex;;
1896f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod  }
1906f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
191d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod  inline bool sanitize (hb_sanitize_context_t *c) {
1923e2401f6c53d2b047954d75c37aef5e5e7cdc51aBehdad Esfahbod    TRACE_SANITIZE ();
1930ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod    return TRACE_RETURN (c->check_struct (this) && featureIndex.sanitize (c));
194cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod  }
195cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod
1966f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod  Offset	lookupOrder;	/* = Null (reserved for an offset to a
1976f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod				 * reordering table) */
1986f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod  USHORT	reqFeatureIndex;/* Index of a feature required for this
1996f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod				 * language system--if no required features
2006f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod				 * = 0xFFFF */
201bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod  IndexArray	featureIndex;	/* Array of indices into the FeatureList */
202569da92bc6956f42d9b2d65c784e184fb6380efeBehdad Esfahbod  public:
2030eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod  DEFINE_SIZE_ARRAY (6, featureIndex);
2046f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod};
20565f46b00333e20ab8a52a4b350747507541ec1dbBehdad EsfahbodDEFINE_NULL_DATA (LangSys, "\0\0\xFF\xFF");
2066f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
2076f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
20860d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct Script
20960d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{
210bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod  inline unsigned int get_lang_sys_count (void) const
211bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod  { return langSys.len; }
212bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod  inline const Tag& get_lang_sys_tag (unsigned int i) const
213bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod  { return langSys.get_tag (i); }
214e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod  inline unsigned int get_lang_sys_tags (unsigned int start_offset,
215e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod					 unsigned int *lang_sys_count /* IN/OUT */,
216e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod					 hb_tag_t     *lang_sys_tags /* OUT */) const
217e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod  { return langSys.get_tags (start_offset, lang_sys_count, lang_sys_tags); }
21860d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod  inline const LangSys& get_lang_sys (unsigned int i) const
21960d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod  {
220b5db4f1e4eefa266a71a28b5496f47ff9d1a81e8Behdad Esfahbod    if (i == Index::NOT_FOUND_INDEX) return get_default_lang_sys ();
2216f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod    return this+langSys[i].offset;
2226f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod  }
223bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod  inline bool find_lang_sys_index (hb_tag_t tag, unsigned int *index) const
224bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod  { return langSys.find_index (tag, index); }
2256f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
226cc6c644ff2af5f6669b6ec100ff13e904872b21cBehdad Esfahbod  inline bool has_default_lang_sys (void) const { return defaultLangSys != 0; }
22760d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod  inline const LangSys& get_default_lang_sys (void) const { return this+defaultLangSys; }
2286f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
229d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod  inline bool sanitize (hb_sanitize_context_t *c) {
2303e2401f6c53d2b047954d75c37aef5e5e7cdc51aBehdad Esfahbod    TRACE_SANITIZE ();
2310ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod    return TRACE_RETURN (defaultLangSys.sanitize (c, this) && langSys.sanitize (c, this));
232cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod  }
233cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod
2346f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod  private:
2356f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod  OffsetTo<LangSys>
2366f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod		defaultLangSys;	/* Offset to DefaultLangSys table--from
2376f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod				 * beginning of Script table--may be Null */
238cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod  RecordArrayOf<LangSys>
2396f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod		langSys;	/* Array of LangSysRecords--listed
2406f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod				 * alphabetically by LangSysTag */
241b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod  public:
2420eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod  DEFINE_SIZE_ARRAY (4, langSys);
2436f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod};
2446f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
2456f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbodtypedef RecordListOf<Script> ScriptList;
2466f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
2476f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
24860d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct Feature
24960d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{
250bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod  inline unsigned int get_lookup_count (void) const
251bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod  { return lookupIndex.len; }
252bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod  inline hb_tag_t get_lookup_index (unsigned int i) const
253bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod  { return lookupIndex[i]; }
254e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod  inline unsigned int get_lookup_indexes (unsigned int start_index,
255e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod					  unsigned int *lookup_count /* IN/OUT */,
256e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod					  unsigned int *lookup_tags /* OUT */) const
257e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod  { return lookupIndex.get_indexes (start_index, lookup_count, lookup_tags); }
2586f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
259d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod  inline bool sanitize (hb_sanitize_context_t *c) {
2603e2401f6c53d2b047954d75c37aef5e5e7cdc51aBehdad Esfahbod    TRACE_SANITIZE ();
2610ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod    return TRACE_RETURN (c->check_struct (this) && lookupIndex.sanitize (c));
262cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod  }
263cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod
2646f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod  Offset	featureParams;	/* Offset to Feature Parameters table (if one
2656f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod				 * has been defined for the feature), relative
2666f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod				 * to the beginning of the Feature Table; = Null
2676f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod				 * if not required */
268bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod  IndexArray	 lookupIndex;	/* Array of LookupList indices */
269b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod  public:
2700eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod  DEFINE_SIZE_ARRAY (4, lookupIndex);
2716f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod};
2726f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
2736f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbodtypedef RecordListOf<Feature> FeatureList;
2746f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
2756f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
27660d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct LookupFlag : USHORT
27760d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{
278c6035cf802c60f0526f421f39a55886061df94eeBehdad Esfahbod  enum Flags {
2794fa77d3c4305a76b956de8c1a9b83a961d035a80Behdad Esfahbod    RightToLeft		= 0x0001u,
2804fa77d3c4305a76b956de8c1a9b83a961d035a80Behdad Esfahbod    IgnoreBaseGlyphs	= 0x0002u,
2814fa77d3c4305a76b956de8c1a9b83a961d035a80Behdad Esfahbod    IgnoreLigatures	= 0x0004u,
2824fa77d3c4305a76b956de8c1a9b83a961d035a80Behdad Esfahbod    IgnoreMarks		= 0x0008u,
283aa87d951739f6beacb66daa235cd033fdcfcadd7Behdad Esfahbod    IgnoreFlags		= 0x000Eu,
284d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod    UseMarkFilteringSet	= 0x0010u,
285d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod    Reserved		= 0x00E0u,
2868f034d5849627ee95a5889fa34c9ba294fff13caBehdad Esfahbod    MarkAttachmentType	= 0xFF00u
2874fa77d3c4305a76b956de8c1a9b83a961d035a80Behdad Esfahbod  };
288b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod  public:
289b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod  DEFINE_SIZE_STATIC (2);
2906f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod};
2916f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
29260d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct Lookup
29360d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{
29460d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod  inline unsigned int get_subtable_count (void) const { return subTable.len; }
2956f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
2966f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod  inline unsigned int get_type (void) const { return lookupType; }
2978c69e65abed961002d90024c92e18538c6516262Behdad Esfahbod
2988c69e65abed961002d90024c92e18538c6516262Behdad Esfahbod  /* lookup_props is a 32-bit integer where the lower 16-bit is LookupFlag and
2998c69e65abed961002d90024c92e18538c6516262Behdad Esfahbod   * higher 16-bit is mark-filtering-set if the lookup uses one.
3008c69e65abed961002d90024c92e18538c6516262Behdad Esfahbod   * Not to be confused with glyph_props which is very similar. */
3018c69e65abed961002d90024c92e18538c6516262Behdad Esfahbod  inline uint32_t get_props (void) const
302d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod  {
303d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod    unsigned int flag = lookupFlag;
30464d3fc8d0dada673245cc8c0b1c12cd849b30997Behdad Esfahbod    if (unlikely (flag & LookupFlag::UseMarkFilteringSet))
305d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod    {
306e961c86c579fd98ee604342a9c70c4e7f8d4f220Behdad Esfahbod      const USHORT &markFilteringSet = StructAfter<USHORT> (subTable);
30709c292e3b688a67fbae67b645d1e6ffcf8d8eb6eBehdad Esfahbod      flag += (markFilteringSet << 16);
308d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod    }
309d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod    return flag;
310d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod  }
3116f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
312d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod  inline bool sanitize (hb_sanitize_context_t *c) {
3133e2401f6c53d2b047954d75c37aef5e5e7cdc51aBehdad Esfahbod    TRACE_SANITIZE ();
3143b2c2df41b90f2a1d9e33b3dc15a92cff58a689aBehdad Esfahbod    /* Real sanitize of the subtables is done by GSUB/GPOS/... */
3150ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod    if (!(c->check_struct (this) && subTable.sanitize (c))) return TRACE_RETURN (false);
31664d3fc8d0dada673245cc8c0b1c12cd849b30997Behdad Esfahbod    if (unlikely (lookupFlag & LookupFlag::UseMarkFilteringSet))
317cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod    {
318e961c86c579fd98ee604342a9c70c4e7f8d4f220Behdad Esfahbod      USHORT &markFilteringSet = StructAfter<USHORT> (subTable);
3190ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod      if (!markFilteringSet.sanitize (c)) return TRACE_RETURN (false);
320cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod    }
3210ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod    return TRACE_RETURN (true);
322cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod  }
323cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod
324d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod  USHORT	lookupType;		/* Different enumerations for GSUB and GPOS */
325d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod  USHORT	lookupFlag;		/* Lookup qualifiers */
3263b2c2df41b90f2a1d9e33b3dc15a92cff58a689aBehdad Esfahbod  ArrayOf<Offset>
327d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod		subTable;		/* Array of SubTables */
328d3480ba37fbb5d4be75b094060f5b2f1ce98fb53Behdad Esfahbod  USHORT	markFilteringSetX[VAR];	/* Index (base 0) into GDEF mark glyph sets
329d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod					 * structure. This field is only present if bit
330d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod					 * UseMarkFilteringSet of lookup flags is set. */
331569da92bc6956f42d9b2d65c784e184fb6380efeBehdad Esfahbod  public:
3320eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod  DEFINE_SIZE_ARRAY2 (6, subTable, markFilteringSetX);
3336f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod};
3346f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
3356f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbodtypedef OffsetListOf<Lookup> LookupList;
3366f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
3376f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
3386f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod/*
3396f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * Coverage Table
3406f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod */
3416f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
34260d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct CoverageFormat1
34360d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{
3446f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod  friend struct Coverage;
3456f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
3466f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod  private:
34760d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod  inline unsigned int get_coverage (hb_codepoint_t glyph_id) const
34860d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod  {
349cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod    int i = glyphArray.search (glyph_id);
350cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod    if (i != -1)
3516f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod        return i;
3526f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod    return NOT_COVERED;
3536f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod  }
3546f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
355d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod  inline bool sanitize (hb_sanitize_context_t *c) {
3563e2401f6c53d2b047954d75c37aef5e5e7cdc51aBehdad Esfahbod    TRACE_SANITIZE ();
3570ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod    return TRACE_RETURN (glyphArray.sanitize (c));
35870de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod  }
35970de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod
3606a9be5bd3524dc3eb1e88d1063bde2e4d8b57011Behdad Esfahbod  inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const {
36131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod    return glyphs->has (glyphArray[index]);
36231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod  }
36331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod
36467bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod  inline void add_coverage (hb_set_t *glyphs) const {
36567bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod    unsigned int count = glyphArray.len;
36667bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod    for (unsigned int i = 0; i < count; i++)
36767bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod      glyphs->add (glyphArray[i]);
36867bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod  }
36967bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod
3707d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod  struct Iter {
371c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod    inline void init (const struct CoverageFormat1 &c_) { c = &c_; i = 0; };
372c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod    inline bool more (void) { return i < c->glyphArray.len; }
373c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod    inline void next (void) { i++; }
374c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod    inline uint16_t get_glyph (void) { return c->glyphArray[i]; }
375c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod    inline uint16_t get_coverage (void) { return i; }
3767d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod
3777d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod    private:
3787d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod    const struct CoverageFormat1 *c;
3797d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod    unsigned int i;
3807d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod  };
3817d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod
38270de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod  private:
3836f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod  USHORT	coverageFormat;	/* Format identifier--format = 1 */
384cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod  SortedArrayOf<GlyphID>
3856f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod		glyphArray;	/* Array of GlyphIDs--in numerical order */
386b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod  public:
3870eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod  DEFINE_SIZE_ARRAY (4, glyphArray);
3886f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod};
3896f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
39060d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct CoverageFormat2
39160d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{
3926f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod  friend struct Coverage;
3936f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
3946f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod  private:
39560d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod  inline unsigned int get_coverage (hb_codepoint_t glyph_id) const
39660d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod  {
397cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod    int i = rangeRecord.search (glyph_id);
398cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod    if (i != -1) {
399cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod      const RangeRecord &range = rangeRecord[i];
400cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod      return (unsigned int) range.value + (glyph_id - range.start);
4016f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod    }
4026f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod    return NOT_COVERED;
4036f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod  }
4046f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
405d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod  inline bool sanitize (hb_sanitize_context_t *c) {
4063e2401f6c53d2b047954d75c37aef5e5e7cdc51aBehdad Esfahbod    TRACE_SANITIZE ();
4070ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod    return TRACE_RETURN (rangeRecord.sanitize (c));
40870de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod  }
40970de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod
4106a9be5bd3524dc3eb1e88d1063bde2e4d8b57011Behdad Esfahbod  inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const {
41131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod    unsigned int i;
41231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod    unsigned int count = rangeRecord.len;
41331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod    for (i = 0; i < count; i++) {
41431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod      const RangeRecord &range = rangeRecord[i];
41531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod      if (range.value <= index &&
4163f18236a03880c0960f5990dc90685f6146951a6Behdad Esfahbod	  index < (unsigned int) range.value + (range.end - range.start) &&
41731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod	  range.intersects (glyphs))
41831081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod        return true;
41931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod      else if (index < range.value)
42031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod        return false;
42131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod    }
42231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod    return false;
42331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod  }
42431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod
42567bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod  inline void add_coverage (hb_set_t *glyphs) const {
42667bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod    unsigned int count = rangeRecord.len;
42767bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod    for (unsigned int i = 0; i < count; i++)
42867bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod      rangeRecord[i].add_coverage (glyphs);
42967bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod  }
43067bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod
4317d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod  struct Iter {
432c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod    inline void init (const CoverageFormat2 &c_) {
433c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod      c = &c_;
434c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod      coverage = 0;
435c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod      i = 0;
436c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod      j = c->rangeRecord.len ? c_.rangeRecord[0].start : 0;
437c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod    }
438c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod    inline bool more (void) { return i < c->rangeRecord.len; }
439c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod    inline void next (void) {
440c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod      coverage++;
4417d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod      if (j == c->rangeRecord[i].end) {
4427d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod        i++;
4430da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod	if (more ())
4440da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod	  j = c->rangeRecord[i].start;
4450da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod	return;
4467d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod      }
4470da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod      j++;
4480da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod    }
449c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod    inline uint16_t get_glyph (void) { return j; }
450c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod    inline uint16_t get_coverage (void) { return coverage; }
4517d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod
4527d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod    private:
4537d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod    const struct CoverageFormat2 *c;
454c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod    unsigned int i, j, coverage;
4557d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod  };
4567d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod
45770de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod  private:
4586f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod  USHORT	coverageFormat;	/* Format identifier--format = 2 */
459cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod  SortedArrayOf<RangeRecord>
4606f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod		rangeRecord;	/* Array of glyph ranges--ordered by
4616f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod				 * Start GlyphID. rangeCount entries
4626f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod				 * long */
463b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod  public:
4640eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod  DEFINE_SIZE_ARRAY (4, rangeRecord);
4656f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod};
4666f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
46760d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct Coverage
46860d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{
46900e23fcc6fd0eee5c582251bf3de6a2703fbbd3eBehdad Esfahbod  inline unsigned int operator () (hb_codepoint_t glyph_id) const { return get_coverage (glyph_id); }
47070de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod
47120b035dad41247076815a2bbb0346d63058b322fBehdad Esfahbod  inline unsigned int get_coverage (hb_codepoint_t glyph_id) const
47260d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod  {
4736f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod    switch (u.format) {
474dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod    case 1: return u.format1.get_coverage(glyph_id);
475dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod    case 2: return u.format2.get_coverage(glyph_id);
4766f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod    default:return NOT_COVERED;
4776f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod    }
4786f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod  }
4796f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
480d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod  inline bool sanitize (hb_sanitize_context_t *c) {
4813e2401f6c53d2b047954d75c37aef5e5e7cdc51aBehdad Esfahbod    TRACE_SANITIZE ();
4820ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod    if (!u.format.sanitize (c)) return TRACE_RETURN (false);
48370de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod    switch (u.format) {
4840ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod    case 1: return TRACE_RETURN (u.format1.sanitize (c));
4850ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod    case 2: return TRACE_RETURN (u.format2.sanitize (c));
4860ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod    default:return TRACE_RETURN (true);
48770de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod    }
48870de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod  }
4896f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
4906a9be5bd3524dc3eb1e88d1063bde2e4d8b57011Behdad Esfahbod  inline bool intersects (const hb_set_t *glyphs) const {
491c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod    /* TODO speed this up */
492c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod    Coverage::Iter iter;
493c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod    for (iter.init (*this); iter.more (); iter.next ()) {
494c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod      if (glyphs->has (iter.get_glyph ()))
495c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod        return true;
496c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod    }
497c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod    return false;
49831081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod  }
499c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod
5006a9be5bd3524dc3eb1e88d1063bde2e4d8b57011Behdad Esfahbod  inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const {
50131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod    switch (u.format) {
50231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod    case 1: return u.format1.intersects_coverage (glyphs, index);
50331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod    case 2: return u.format2.intersects_coverage (glyphs, index);
50431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod    default:return false;
50531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod    }
506c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod  }
507c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod
50867bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod  inline void add_coverage (hb_set_t *glyphs) const {
50967bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod    switch (u.format) {
51067bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod    case 1: u.format1.add_coverage (glyphs); break;
51167bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod    case 2: u.format2.add_coverage (glyphs); break;
51267bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod    default:                                 break;
51367bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod    }
51467bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod  }
51567bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod
5167d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod  struct Iter {
517c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod    Iter (void) : format (0) {};
518c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod    inline void init (const Coverage &c_) {
5197d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod      format = c_.u.format;
5207d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod      switch (format) {
5217d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod      case 1: return u.format1.init (c_.u.format1);
5227d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod      case 2: return u.format2.init (c_.u.format2);
5237d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod      default:return;
5247d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod      }
5257d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod    }
526c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod    inline bool more (void) {
5277d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod      switch (format) {
5287d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod      case 1: return u.format1.more ();
5297d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod      case 2: return u.format2.more ();
5307d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod      default:return true;
5317d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod      }
5327d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod    }
533c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod    inline void next (void) {
5340da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod      switch (format) {
5350da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod      case 1: u.format1.next (); break;
5360da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod      case 2: u.format2.next (); break;
5370da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod      default:                   break;
5380da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod      }
5390da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod    }
540c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod    inline uint16_t get_glyph (void) {
541c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod      switch (format) {
542c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod      case 1: return u.format1.get_glyph ();
543c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod      case 2: return u.format2.get_glyph ();
544c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod      default:return true;
545c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod      }
546c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod    }
547c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod    inline uint16_t get_coverage (void) {
5487d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod      switch (format) {
549c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod      case 1: return u.format1.get_coverage ();
550c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod      case 2: return u.format2.get_coverage ();
5517d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod      default:return true;
5527d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod      }
5537d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod    }
5547d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod
5557d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod    private:
556c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod    unsigned int format;
5577d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod    union {
5587d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod    CoverageFormat1::Iter	format1;
5597d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod    CoverageFormat2::Iter	format2;
5607d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod    } u;
5617d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod  };
5627d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod
5636f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod  private:
5646f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod  union {
5656f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod  USHORT		format;		/* Format identifier */
566dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod  CoverageFormat1	format1;
567dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod  CoverageFormat2	format2;
5686f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod  } u;
569ed07422c33bbb52ff4d79e65986171e3f07697d8Behdad Esfahbod  public:
570596e471aa5053d955fb5d5b5923088c8814469b1Behdad Esfahbod  DEFINE_SIZE_UNION (2, format);
5716f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod};
5726f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
5736f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
5746f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod/*
5756f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * Class Definition Table
5766f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod */
5776f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
57860d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct ClassDefFormat1
57960d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{
5806f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod  friend struct ClassDef;
5816f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
5826f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod  private:
58398370e89d1bff248737b482d129c2a4deb8bfd95Behdad Esfahbod  inline unsigned int get_class (hb_codepoint_t glyph_id) const
58460d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod  {
585caf0412690542e58e23246dccc4b2fb83bd652ecBehdad Esfahbod    if (unlikely ((unsigned int) (glyph_id - startGlyph) < classValue.len))
5866f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod      return classValue[glyph_id - startGlyph];
5876f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod    return 0;
5886f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod  }
5896f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
590d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod  inline bool sanitize (hb_sanitize_context_t *c) {
5913e2401f6c53d2b047954d75c37aef5e5e7cdc51aBehdad Esfahbod    TRACE_SANITIZE ();
5920ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod    return TRACE_RETURN (c->check_struct (this) && classValue.sanitize (c));
59370de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod  }
59470de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod
5956a9be5bd3524dc3eb1e88d1063bde2e4d8b57011Behdad Esfahbod  inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const {
59631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod    unsigned int count = classValue.len;
59731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod    for (unsigned int i = 0; i < count; i++)
59831081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod      if (classValue[i] == klass && glyphs->has (startGlyph + i))
59931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod        return true;
60031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod    return false;
60131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod  }
60231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod
6036f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod  USHORT	classFormat;		/* Format identifier--format = 1 */
6046f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod  GlyphID	startGlyph;		/* First GlyphID of the classValueArray */
6056f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod  ArrayOf<USHORT>
6066f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod		classValue;		/* Array of Class Values--one per GlyphID */
607b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod  public:
6080eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod  DEFINE_SIZE_ARRAY (6, classValue);
6096f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod};
6106f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
61160d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct ClassDefFormat2
61260d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{
6136f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod  friend struct ClassDef;
6146f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
6156f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod  private:
61698370e89d1bff248737b482d129c2a4deb8bfd95Behdad Esfahbod  inline unsigned int get_class (hb_codepoint_t glyph_id) const
61760d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod  {
618cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod    int i = rangeRecord.search (glyph_id);
619cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod    if (i != -1)
620cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod      return rangeRecord[i].value;
6216f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod    return 0;
6226f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod  }
6236f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
624d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod  inline bool sanitize (hb_sanitize_context_t *c) {
6253e2401f6c53d2b047954d75c37aef5e5e7cdc51aBehdad Esfahbod    TRACE_SANITIZE ();
6260ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod    return TRACE_RETURN (rangeRecord.sanitize (c));
62770de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod  }
62870de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod
6296a9be5bd3524dc3eb1e88d1063bde2e4d8b57011Behdad Esfahbod  inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const {
63031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod    unsigned int count = rangeRecord.len;
63131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod    for (unsigned int i = 0; i < count; i++)
63231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod      if (rangeRecord[i].value == klass && rangeRecord[i].intersects (glyphs))
63331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod        return true;
63431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod    return false;
63531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod  }
63631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod
6376f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod  USHORT	classFormat;	/* Format identifier--format = 2 */
638cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod  SortedArrayOf<RangeRecord>
6396f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod		rangeRecord;	/* Array of glyph ranges--ordered by
6406f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod				 * Start GlyphID */
641b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod  public:
6420eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod  DEFINE_SIZE_ARRAY (4, rangeRecord);
6436f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod};
6446f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
64560d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct ClassDef
64660d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{
64798370e89d1bff248737b482d129c2a4deb8bfd95Behdad Esfahbod  inline unsigned int operator () (hb_codepoint_t glyph_id) const { return get_class (glyph_id); }
64870de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod
64998370e89d1bff248737b482d129c2a4deb8bfd95Behdad Esfahbod  inline unsigned int get_class (hb_codepoint_t glyph_id) const
65060d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod  {
6516f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod    switch (u.format) {
652dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod    case 1: return u.format1.get_class(glyph_id);
653dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod    case 2: return u.format2.get_class(glyph_id);
6546f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod    default:return 0;
6556f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod    }
6566f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod  }
6576f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
658d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod  inline bool sanitize (hb_sanitize_context_t *c) {
6593e2401f6c53d2b047954d75c37aef5e5e7cdc51aBehdad Esfahbod    TRACE_SANITIZE ();
6600ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod    if (!u.format.sanitize (c)) return TRACE_RETURN (false);
66170de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod    switch (u.format) {
6620ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod    case 1: return TRACE_RETURN (u.format1.sanitize (c));
6630ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod    case 2: return TRACE_RETURN (u.format2.sanitize (c));
6640ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod    default:return TRACE_RETURN (true);
66570de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod    }
66670de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod  }
667aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod
6686a9be5bd3524dc3eb1e88d1063bde2e4d8b57011Behdad Esfahbod  inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const {
66931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod    switch (u.format) {
67031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod    case 1: return u.format1.intersects_class (glyphs, klass);
67131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod    case 2: return u.format2.intersects_class (glyphs, klass);
67231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod    default:return false;
67331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod    }
67431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod  }
67531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod
6766f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod  private:
6776f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod  union {
6786f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod  USHORT		format;		/* Format identifier */
679dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod  ClassDefFormat1	format1;
680dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod  ClassDefFormat2	format2;
6816f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod  } u;
682ed07422c33bbb52ff4d79e65986171e3f07697d8Behdad Esfahbod  public:
683596e471aa5053d955fb5d5b5923088c8814469b1Behdad Esfahbod  DEFINE_SIZE_UNION (2, format);
6846f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod};
6856f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
6866f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
6876f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod/*
6886f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * Device Tables
6896f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod */
6906f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
69160d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct Device
69260d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{
693b634beb39e0a4fef7167a8af646f6b2d8cafe69bBehdad Esfahbod
694abcfe9b59b4475eb02dd679aac4bc59616713b28Behdad Esfahbod  inline hb_position_t get_x_delta (hb_font_t *font) const
695abcfe9b59b4475eb02dd679aac4bc59616713b28Behdad Esfahbod  { return get_delta (font->x_ppem, font->x_scale); }
696b634beb39e0a4fef7167a8af646f6b2d8cafe69bBehdad Esfahbod
697abcfe9b59b4475eb02dd679aac4bc59616713b28Behdad Esfahbod  inline hb_position_t get_y_delta (hb_font_t *font) const
698abcfe9b59b4475eb02dd679aac4bc59616713b28Behdad Esfahbod  { return get_delta (font->y_ppem, font->y_scale); }
699b634beb39e0a4fef7167a8af646f6b2d8cafe69bBehdad Esfahbod
700da975419884a535281745f30f4b32fee0bc8a7a1Behdad Esfahbod  inline int get_delta (unsigned int ppem, int scale) const
7015bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod  {
7025bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod    if (!ppem) return 0;
7035bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod
7045bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod    int pixels = get_delta_pixels (ppem);
7055bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod
7065bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod    if (!pixels) return 0;
7075bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod
7085bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod    return pixels * (int64_t) scale / ppem;
7095bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod  }
7105bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod
7115bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod
7125bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod  inline int get_delta_pixels (unsigned int ppem_size) const
71360d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod  {
714056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod    unsigned int f = deltaFormat;
71564d3fc8d0dada673245cc8c0b1c12cd849b30997Behdad Esfahbod    if (unlikely (f < 1 || f > 3))
716056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod      return 0;
7176f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
718056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod    if (ppem_size < startSize || ppem_size > endSize)
719056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod      return 0;
7206f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
721056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod    unsigned int s = ppem_size - startSize;
7226f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
723056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod    unsigned int byte = deltaValue[s >> (4 - f)];
72409c292e3b688a67fbae67b645d1e6ffcf8d8eb6eBehdad Esfahbod    unsigned int bits = (byte >> (16 - (((s & ((1 << (4 - f)) - 1)) + 1) << f)));
72509c292e3b688a67fbae67b645d1e6ffcf8d8eb6eBehdad Esfahbod    unsigned int mask = (0xFFFF >> (16 - (1 << f)));
726056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod
727056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod    int delta = bits & mask;
728056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod
72915164d9258a74122a4db748d35532bd72c47cec2Behdad Esfahbod    if ((unsigned int) delta >= ((mask + 1) >> 1))
730056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod      delta -= mask + 1;
731056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod
732056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod    return delta;
733056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod  }
734056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod
7357f97d2cd904ea999c099c73c52187c5d65aeec67Behdad Esfahbod  inline unsigned int get_size (void) const
736dc9c4d93cd0f3ac991f32df08c1c17fc389054c0Behdad Esfahbod  {
737dc9c4d93cd0f3ac991f32df08c1c17fc389054c0Behdad Esfahbod    unsigned int f = deltaFormat;
738b961518b9611471ff7060e97686e5625974847ebBehdad Esfahbod    if (unlikely (f < 1 || f > 3 || startSize > endSize)) return 3 * USHORT::static_size;
739b961518b9611471ff7060e97686e5625974847ebBehdad Esfahbod    return USHORT::static_size * (4 + ((endSize - startSize) >> (4 - f)));
740dc9c4d93cd0f3ac991f32df08c1c17fc389054c0Behdad Esfahbod  }
741dc9c4d93cd0f3ac991f32df08c1c17fc389054c0Behdad Esfahbod
742d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod  inline bool sanitize (hb_sanitize_context_t *c) {
7433e2401f6c53d2b047954d75c37aef5e5e7cdc51aBehdad Esfahbod    TRACE_SANITIZE ();
7440ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod    return TRACE_RETURN (c->check_struct (this) && c->check_range (this, this->get_size ()));
745dc9c4d93cd0f3ac991f32df08c1c17fc389054c0Behdad Esfahbod  }
7466f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
7476f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod  private:
7480795b784dd1009976c185482a376df250167e73bBehdad Esfahbod  USHORT	startSize;		/* Smallest size to correct--in ppem */
7490795b784dd1009976c185482a376df250167e73bBehdad Esfahbod  USHORT	endSize;		/* Largest size to correct--in ppem */
750caff7db93d205e32a535d49e51a3cad70f91dfddBehdad Esfahbod  USHORT	deltaFormat;		/* Format of DeltaValue array data: 1, 2, or 3
751caff7db93d205e32a535d49e51a3cad70f91dfddBehdad Esfahbod					 * 1	Signed 2-bit value, 8 values per uint16
752caff7db93d205e32a535d49e51a3cad70f91dfddBehdad Esfahbod					 * 2	Signed 4-bit value, 4 values per uint16
753caff7db93d205e32a535d49e51a3cad70f91dfddBehdad Esfahbod					 * 3	Signed 8-bit value, 2 values per uint16
754caff7db93d205e32a535d49e51a3cad70f91dfddBehdad Esfahbod					 */
755d3480ba37fbb5d4be75b094060f5b2f1ce98fb53Behdad Esfahbod  USHORT	deltaValue[VAR];	/* Array of compressed data */
756569da92bc6956f42d9b2d65c784e184fb6380efeBehdad Esfahbod  public:
7570eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod  DEFINE_SIZE_ARRAY (6, deltaValue);
7586f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod};
7596f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
7606f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod
761acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod
7625f5b24f99f52bbc922e238b65c06061ba07c8548Behdad Esfahbod#endif /* HB_OT_LAYOUT_COMMON_PRIVATE_HH */
763