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 | bool sanitize (hb_sanitize_context_t *c) const |
39 | { |
40 | TRACE_SANITIZE (this); |
41 | return_trace (c->check_struct (this) && |
42 | c->check_range (mapDataZ.arrayZ, |
43 | mapCount, |
44 | get_width ())); |
45 | } |
46 | |
47 | unsigned int map (unsigned int v) const /* Returns 16.16 outer.inner. */ |
48 | { |
49 | /* If count is zero, pass value unchanged. This takes |
50 | * care of direct mapping for advance map. */ |
51 | if (!mapCount) |
52 | return v; |
53 | |
54 | if (v >= mapCount) |
55 | v = mapCount - 1; |
56 | |
57 | unsigned int u = 0; |
58 | { /* Fetch it. */ |
59 | unsigned int w = get_width (); |
60 | const HBUINT8 *p = mapDataZ.arrayZ + w * v; |
61 | for (; w; w--) |
62 | u = (u << 8) + *p++; |
63 | } |
64 | |
65 | { /* Repack it. */ |
66 | unsigned int n = get_inner_bitcount (); |
67 | unsigned int outer = u >> n; |
68 | unsigned int inner = u & ((1 << n) - 1); |
69 | u = (outer<<16) | inner; |
70 | } |
71 | |
72 | return u; |
73 | } |
74 | |
75 | protected: |
76 | unsigned int get_width () const { return ((format >> 4) & 3) + 1; } |
77 | |
78 | unsigned int get_inner_bitcount () const { 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 | UnsizedArrayOf<HBUINT8> |
85 | mapDataZ; /* The delta-set index mapping data. */ |
86 | |
87 | public: |
88 | DEFINE_SIZE_ARRAY (4, mapDataZ); |
89 | }; |
90 | |
91 | |
92 | /* |
93 | * HVAR -- Horizontal Metrics Variations |
94 | * https://docs.microsoft.com/en-us/typography/opentype/spec/hvar |
95 | * VVAR -- Vertical Metrics Variations |
96 | * https://docs.microsoft.com/en-us/typography/opentype/spec/vvar |
97 | */ |
98 | #define HB_OT_TAG_HVAR HB_TAG('H','V','A','R') |
99 | #define HB_OT_TAG_VVAR HB_TAG('V','V','A','R') |
100 | |
101 | struct HVARVVAR |
102 | { |
103 | static constexpr hb_tag_t HVARTag = HB_OT_TAG_HVAR; |
104 | static constexpr hb_tag_t VVARTag = HB_OT_TAG_VVAR; |
105 | |
106 | bool sanitize (hb_sanitize_context_t *c) const |
107 | { |
108 | TRACE_SANITIZE (this); |
109 | return_trace (version.sanitize (c) && |
110 | likely (version.major == 1) && |
111 | varStore.sanitize (c, this) && |
112 | advMap.sanitize (c, this) && |
113 | lsbMap.sanitize (c, this) && |
114 | rsbMap.sanitize (c, this)); |
115 | } |
116 | |
117 | float get_advance_var (hb_font_t *font, hb_codepoint_t glyph) const |
118 | { |
119 | unsigned int varidx = (this+advMap).map (glyph); |
120 | return (this+varStore).get_delta (varidx, font->coords, font->num_coords); |
121 | } |
122 | |
123 | float get_side_bearing_var (hb_codepoint_t glyph, |
124 | const int *coords, unsigned int coord_count) const |
125 | { |
126 | if (!has_side_bearing_deltas ()) return 0.f; |
127 | unsigned int varidx = (this+lsbMap).map (glyph); |
128 | return (this+varStore).get_delta (varidx, coords, coord_count); |
129 | } |
130 | |
131 | bool has_side_bearing_deltas () const { return lsbMap && rsbMap; } |
132 | |
133 | protected: |
134 | FixedVersion<>version; /* Version of the metrics variation table |
135 | * initially set to 0x00010000u */ |
136 | LOffsetTo<VariationStore> |
137 | varStore; /* Offset to item variation store table. */ |
138 | LOffsetTo<DeltaSetIndexMap> |
139 | advMap; /* Offset to advance var-idx mapping. */ |
140 | LOffsetTo<DeltaSetIndexMap> |
141 | lsbMap; /* Offset to lsb/tsb var-idx mapping. */ |
142 | LOffsetTo<DeltaSetIndexMap> |
143 | rsbMap; /* Offset to rsb/bsb var-idx mapping. */ |
144 | |
145 | public: |
146 | DEFINE_SIZE_STATIC (20); |
147 | }; |
148 | |
149 | struct HVAR : HVARVVAR { |
150 | static constexpr hb_tag_t tableTag = HB_OT_TAG_HVAR; |
151 | }; |
152 | struct VVAR : HVARVVAR { |
153 | static constexpr hb_tag_t tableTag = HB_OT_TAG_VVAR; |
154 | |
155 | bool sanitize (hb_sanitize_context_t *c) const |
156 | { |
157 | TRACE_SANITIZE (this); |
158 | return_trace (static_cast<const HVARVVAR *> (this)->sanitize (c) && |
159 | vorgMap.sanitize (c, this)); |
160 | } |
161 | |
162 | protected: |
163 | LOffsetTo<DeltaSetIndexMap> |
164 | vorgMap; /* Offset to vertical-origin var-idx mapping. */ |
165 | |
166 | public: |
167 | DEFINE_SIZE_STATIC (24); |
168 | }; |
169 | |
170 | } /* namespace OT */ |
171 | |
172 | |
173 | #endif /* HB_OT_VAR_HVAR_TABLE_HH */ |
174 | |