1/*
2 * Copyright © 2015 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_GLYF_TABLE_HH
28#define HB_OT_GLYF_TABLE_HH
29
30#include "hb-open-type-private.hh"
31#include "hb-ot-head-table.hh"
32
33
34namespace OT {
35
36
37/*
38 * loca -- Index to Location
39 */
40
41#define HB_OT_TAG_loca HB_TAG('l','o','c','a')
42
43
44struct loca
45{
46 friend struct glyf;
47
48 static const hb_tag_t tableTag = HB_OT_TAG_loca;
49
50 inline bool sanitize (hb_sanitize_context_t *c) const
51 {
52 TRACE_SANITIZE (this);
53 return_trace (true);
54 }
55
56 protected:
57 UINT8 dataX[VAR]; /* Location data. */
58 DEFINE_SIZE_ARRAY (0, dataX);
59};
60
61
62/*
63 * glyf -- TrueType Glyph Data
64 */
65
66#define HB_OT_TAG_glyf HB_TAG('g','l','y','f')
67
68
69struct glyf
70{
71 static const hb_tag_t tableTag = HB_OT_TAG_glyf;
72
73 inline bool sanitize (hb_sanitize_context_t *c) const
74 {
75 TRACE_SANITIZE (this);
76 /* We don't check for anything specific here. The users of the
77 * struct do all the hard work... */
78 return_trace (true);
79 }
80
81 struct GlyphHeader
82 {
83 INT16 numberOfContours; /* If the number of contours is
84 * greater than or equal to zero,
85 * this is a simple glyph; if negative,
86 * this is a composite glyph. */
87 FWORD xMin; /* Minimum x for coordinate data. */
88 FWORD yMin; /* Minimum y for coordinate data. */
89 FWORD xMax; /* Maximum x for coordinate data. */
90 FWORD yMax; /* Maximum y for coordinate data. */
91
92 DEFINE_SIZE_STATIC (10);
93 };
94
95 struct accelerator_t
96 {
97 inline void init (hb_face_t *face)
98 {
99 hb_blob_t *head_blob = Sanitizer<head>::sanitize (blob: face->reference_table (HB_OT_TAG_head));
100 const head *head_table = Sanitizer<head>::lock_instance (blob: head_blob);
101 if ((unsigned int) head_table->indexToLocFormat > 1 || head_table->glyphDataFormat != 0)
102 {
103 /* Unknown format. Leave num_glyphs=0, that takes care of disabling us. */
104 hb_blob_destroy (blob: head_blob);
105 return;
106 }
107 short_offset = 0 == head_table->indexToLocFormat;
108 hb_blob_destroy (blob: head_blob);
109
110 loca_blob = Sanitizer<loca>::sanitize (blob: face->reference_table (HB_OT_TAG_loca));
111 loca_table = Sanitizer<loca>::lock_instance (blob: loca_blob);
112 glyf_blob = Sanitizer<glyf>::sanitize (blob: face->reference_table (HB_OT_TAG_glyf));
113 glyf_table = Sanitizer<glyf>::lock_instance (blob: glyf_blob);
114
115 num_glyphs = MAX (a: 1u, b: hb_blob_get_length (blob: loca_blob) / (short_offset ? 2 : 4)) - 1;
116 glyf_len = hb_blob_get_length (blob: glyf_blob);
117 }
118
119 inline void fini (void)
120 {
121 hb_blob_destroy (blob: loca_blob);
122 hb_blob_destroy (blob: glyf_blob);
123 }
124
125 inline bool get_extents (hb_codepoint_t glyph,
126 hb_glyph_extents_t *extents) const
127 {
128 if (unlikely (glyph >= num_glyphs))
129 return false;
130
131 unsigned int start_offset, end_offset;
132 if (short_offset)
133 {
134 const UINT16 *offsets = (const UINT16 *) loca_table->dataX;
135 start_offset = 2 * offsets[glyph];
136 end_offset = 2 * offsets[glyph + 1];
137 }
138 else
139 {
140 const UINT32 *offsets = (const UINT32 *) loca_table->dataX;
141 start_offset = offsets[glyph];
142 end_offset = offsets[glyph + 1];
143 }
144
145 if (start_offset > end_offset || end_offset > glyf_len)
146 return false;
147
148 if (end_offset - start_offset < GlyphHeader::static_size)
149 return true; /* Empty glyph; zero extents. */
150
151 const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (P: glyf_table, offset: start_offset);
152
153 extents->x_bearing = MIN (a: glyph_header.xMin, b: glyph_header.xMax);
154 extents->y_bearing = MAX (a: glyph_header.yMin, b: glyph_header.yMax);
155 extents->width = MAX (a: glyph_header.xMin, b: glyph_header.xMax) - extents->x_bearing;
156 extents->height = MIN (a: glyph_header.yMin, b: glyph_header.yMax) - extents->y_bearing;
157
158 return true;
159 }
160
161 private:
162 bool short_offset;
163 unsigned int num_glyphs;
164 const loca *loca_table;
165 const glyf *glyf_table;
166 hb_blob_t *loca_blob;
167 hb_blob_t *glyf_blob;
168 unsigned int glyf_len;
169 };
170
171 protected:
172 UINT8 dataX[VAR]; /* Glyphs data. */
173
174 DEFINE_SIZE_ARRAY (0, dataX);
175};
176
177} /* namespace OT */
178
179
180#endif /* HB_OT_GLYF_TABLE_HH */
181

source code of qtbase/src/3rdparty/harfbuzz-ng/src/hb-ot-glyf-table.hh