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_codepoint_t glyph, |
118 | const int *coords, unsigned int coord_count) const |
119 | { |
120 | unsigned int varidx = (this+advMap).map (glyph); |
121 | return (this+varStore).get_delta (varidx, coords, coord_count); |
122 | } |
123 | |
124 | bool has_sidebearing_deltas () const { 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 constexpr hb_tag_t tableTag = HB_OT_TAG_HVAR; |
144 | }; |
145 | struct VVAR : HVARVVAR { |
146 | static constexpr hb_tag_t tableTag = HB_OT_TAG_VVAR; |
147 | |
148 | 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 | |