1 | /* |
2 | * Copyright © 2017 Google, Inc. |
3 | * |
4 | * This is part of HarfBuzz, a text shaping library. |
5 | * |
6 | * Permission is hereby granted, without written agreement and without |
7 | * license or royalty fees, to use, copy, modify, and distribute this |
8 | * software and its documentation for any purpose, provided that the |
9 | * above copyright notice and the following two paragraphs appear in |
10 | * all copies of this software. |
11 | * |
12 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR |
13 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES |
14 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN |
15 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH |
16 | * DAMAGE. |
17 | * |
18 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, |
19 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND |
20 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS |
21 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO |
22 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. |
23 | * |
24 | * Google Author(s): Behdad Esfahbod |
25 | */ |
26 | |
27 | #ifndef HB_OT_VAR_HVAR_TABLE_HH |
28 | #define HB_OT_VAR_HVAR_TABLE_HH |
29 | |
30 | #include "hb-ot-layout-common.hh" |
31 | |
32 | |
33 | namespace OT { |
34 | |
35 | |
36 | struct DeltaSetIndexMap |
37 | { |
38 | inline bool sanitize (hb_sanitize_context_t *c) const |
39 | { |
40 | TRACE_SANITIZE (this); |
41 | return_trace (c->check_struct (this) && |
42 | c->check_array (mapData, get_width (), mapCount)); |
43 | } |
44 | |
45 | unsigned int map (unsigned int v) const /* Returns 16.16 outer.inner. */ |
46 | { |
47 | /* If count is zero, pass value unchanged. This takes |
48 | * care of direct mapping for advance map. */ |
49 | if (!mapCount) |
50 | return v; |
51 | |
52 | if (v >= mapCount) |
53 | v = mapCount - 1; |
54 | |
55 | unsigned int u = 0; |
56 | { /* Fetch it. */ |
57 | unsigned int w = get_width (); |
58 | const HBUINT8 *p = mapData + w * v; |
59 | for (; w; w--) |
60 | u = (u << 8) + *p++; |
61 | } |
62 | |
63 | { /* Repack it. */ |
64 | unsigned int n = get_inner_bitcount (); |
65 | unsigned int outer = u >> n; |
66 | unsigned int inner = u & ((1 << n) - 1); |
67 | u = (outer<<16) | inner; |
68 | } |
69 | |
70 | return u; |
71 | } |
72 | |
73 | protected: |
74 | inline unsigned int get_width (void) const |
75 | { return ((format >> 4) & 3) + 1; } |
76 | |
77 | inline unsigned int get_inner_bitcount (void) const |
78 | { return (format & 0xF) + 1; } |
79 | |
80 | protected: |
81 | HBUINT16 format; /* A packed field that describes the compressed |
82 | * representation of delta-set indices. */ |
83 | HBUINT16 mapCount; /* The number of mapping entries. */ |
84 | HBUINT8 mapData[VAR]; /* The delta-set index mapping data. */ |
85 | |
86 | public: |
87 | DEFINE_SIZE_ARRAY (4, mapData); |
88 | }; |
89 | |
90 | |
91 | /* |
92 | * HVAR -- Horizontal Metrics Variations |
93 | * https://docs.microsoft.com/en-us/typography/opentype/spec/hvar |
94 | * VVAR -- Vertical Metrics Variations |
95 | * https://docs.microsoft.com/en-us/typography/opentype/spec/vvar |
96 | */ |
97 | #define HB_OT_TAG_HVAR HB_TAG('H','V','A','R') |
98 | #define HB_OT_TAG_VVAR HB_TAG('V','V','A','R') |
99 | |
100 | struct HVARVVAR |
101 | { |
102 | static const hb_tag_t HVARTag = HB_OT_TAG_HVAR; |
103 | static const hb_tag_t VVARTag = HB_OT_TAG_VVAR; |
104 | |
105 | inline bool sanitize (hb_sanitize_context_t *c) const |
106 | { |
107 | TRACE_SANITIZE (this); |
108 | return_trace (version.sanitize (c) && |
109 | likely (version.major == 1) && |
110 | varStore.sanitize (c, this) && |
111 | advMap.sanitize (c, this) && |
112 | lsbMap.sanitize (c, this) && |
113 | rsbMap.sanitize (c, this)); |
114 | } |
115 | |
116 | inline float get_advance_var (hb_codepoint_t glyph, |
117 | int *coords, unsigned int coord_count) const |
118 | { |
119 | unsigned int varidx = (this+advMap).map (glyph); |
120 | return (this+varStore).get_delta (varidx, coords, coord_count); |
121 | } |
122 | |
123 | inline bool has_sidebearing_deltas (void) const |
124 | { return lsbMap && rsbMap; } |
125 | |
126 | protected: |
127 | FixedVersion<>version; /* Version of the metrics variation table |
128 | * initially set to 0x00010000u */ |
129 | LOffsetTo<VariationStore> |
130 | varStore; /* Offset to item variation store table. */ |
131 | LOffsetTo<DeltaSetIndexMap> |
132 | advMap; /* Offset to advance var-idx mapping. */ |
133 | LOffsetTo<DeltaSetIndexMap> |
134 | lsbMap; /* Offset to lsb/tsb var-idx mapping. */ |
135 | LOffsetTo<DeltaSetIndexMap> |
136 | rsbMap; /* Offset to rsb/bsb var-idx mapping. */ |
137 | |
138 | public: |
139 | DEFINE_SIZE_STATIC (20); |
140 | }; |
141 | |
142 | struct HVAR : HVARVVAR { |
143 | static const hb_tag_t tableTag = HB_OT_TAG_HVAR; |
144 | }; |
145 | struct VVAR : HVARVVAR { |
146 | static const hb_tag_t tableTag = HB_OT_TAG_VVAR; |
147 | |
148 | inline bool sanitize (hb_sanitize_context_t *c) const |
149 | { |
150 | TRACE_SANITIZE (this); |
151 | return_trace (static_cast<const HVARVVAR *> (this)->sanitize (c) && |
152 | vorgMap.sanitize (c, this)); |
153 | } |
154 | |
155 | protected: |
156 | LOffsetTo<DeltaSetIndexMap> |
157 | vorgMap; /* Offset to vertical-origin var-idx mapping. */ |
158 | |
159 | public: |
160 | DEFINE_SIZE_STATIC (24); |
161 | }; |
162 | |
163 | } /* namespace OT */ |
164 | |
165 | |
166 | #endif /* HB_OT_VAR_HVAR_TABLE_HH */ |
167 | |