QtBase  v6.3.1
hb-ot-post-table.hh
Go to the documentation of this file.
1 /*
2  * Copyright © 2016 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_POST_TABLE_HH
28 #define HB_OT_POST_TABLE_HH
29 
30 #include "hb-open-type.hh"
31 
32 #define HB_STRING_ARRAY_NAME format1_names
33 #define HB_STRING_ARRAY_LIST "hb-ot-post-macroman.hh"
34 #include "hb-string-array.hh"
35 #undef HB_STRING_ARRAY_LIST
36 #undef HB_STRING_ARRAY_NAME
37 
38 /*
39  * post -- PostScript
40  * https://docs.microsoft.com/en-us/typography/opentype/spec/post
41  */
42 #define HB_OT_TAG_post HB_TAG('p','o','s','t')
43 
44 
45 namespace OT {
46 
47 
48 struct postV2Tail
49 {
50  friend struct post;
51 
53  {
54  TRACE_SANITIZE (this);
55  return_trace (glyphNameIndex.sanitize (c));
56  }
57 
58  template<typename Iterator>
60  Iterator it,
61  const void* _post) const;
62 
63  bool subset (hb_subset_context_t *c) const;
64 
65  protected:
66  Array16Of<HBUINT16> glyphNameIndex; /* This is not an offset, but is the
67  * ordinal number of the glyph in 'post'
68  * string tables. */
69 /*UnsizedArrayOf<HBUINT8>
70  namesX;*/ /* Glyph names with length bytes [variable]
71  * (a Pascal string). */
72 
73  public:
75 };
76 
77 struct post
78 {
79  static constexpr hb_tag_t tableTag = HB_OT_TAG_post;
80 
81  bool serialize (hb_serialize_context_t *c, bool glyph_names) const
82  {
83  TRACE_SERIALIZE (this);
84  post *post_prime = c->allocate_min<post> ();
85  if (unlikely (!post_prime)) return_trace (false);
86 
87  memcpy (post_prime, this, post::min_size);
88  if (!glyph_names)
89  return_trace (c->check_assign (post_prime->version.major, 3,
90  HB_SERIALIZE_ERROR_INT_OVERFLOW)); // Version 3 does not have any glyph names.
91 
92  return_trace (true);
93  }
94 
96  {
97  TRACE_SUBSET (this);
98  post *post_prime = c->serializer->start_embed<post> ();
99  if (unlikely (!post_prime)) return_trace (false);
100 
101  bool glyph_names = c->plan->flags & HB_SUBSET_FLAGS_GLYPH_NAMES;
102  if (!serialize (c->serializer, glyph_names))
103  return_trace (false);
104 
105  if (glyph_names && version.major == 2)
106  return_trace (v2X.subset (c));
107 
108  return_trace (true);
109  }
110 
112  {
113  friend struct postV2Tail;
114 
116  {
117  table = hb_sanitize_context_t ().reference_table<post> (face);
118  unsigned int table_length = table.get_length ();
119 
120  version = table->version.to_int ();
121  if (version != 0x00020000) return;
122 
123  const postV2Tail &v2 = table->v2X;
124 
125  glyphNameIndex = &v2.glyphNameIndex;
126  pool = &StructAfter<uint8_t> (v2.glyphNameIndex);
127 
128  const uint8_t *end = (const uint8_t *) (const void *) table + table_length;
129  for (const uint8_t *data = pool;
130  index_to_offset.length < 65535 && data < end && data + *data < end;
131  data += 1 + *data)
132  index_to_offset.push (data - pool);
133  }
135  {
136  hb_free (gids_sorted_by_name.get ());
137  table.destroy ();
138  }
139 
141  char *buf, unsigned int buf_len) const
142  {
143  hb_bytes_t s = find_glyph_name (glyph);
144  if (!s.length) return false;
145  if (!buf_len) return true;
146  unsigned int len = hb_min (buf_len - 1, s.length);
147  strncpy (buf, s.arrayZ, len);
148  buf[len] = '\0';
149  return true;
150  }
151 
152  bool get_glyph_from_name (const char *name, int len,
153  hb_codepoint_t *glyph) const
154  {
155  unsigned int count = get_glyph_count ();
156  if (unlikely (!count)) return false;
157 
158  if (len < 0) len = strlen (name);
159 
160  if (unlikely (!len)) return false;
161 
162  retry:
163  uint16_t *gids = gids_sorted_by_name.get ();
164 
165  if (unlikely (!gids))
166  {
167  gids = (uint16_t *) hb_malloc (count * sizeof (gids[0]));
168  if (unlikely (!gids))
169  return false; /* Anything better?! */
170 
171  for (unsigned int i = 0; i < count; i++)
172  gids[i] = i;
173  hb_qsort (gids, count, sizeof (gids[0]), cmp_gids, (void *) this);
174 
175  if (unlikely (!gids_sorted_by_name.cmpexch (nullptr, gids)))
176  {
177  hb_free (gids);
178  goto retry;
179  }
180  }
181 
182  hb_bytes_t st (name, len);
183  auto* gid = hb_bsearch (st, gids, count, sizeof (gids[0]), cmp_key, (void *) this);
184  if (gid)
185  {
186  *glyph = *gid;
187  return true;
188  }
189 
190  return false;
191  }
192 
194 
195  protected:
196 
197  unsigned int get_glyph_count () const
198  {
199  if (version == 0x00010000)
200  return format1_names_length;
201 
202  if (version == 0x00020000)
203  return glyphNameIndex->len;
204 
205  return 0;
206  }
207 
208  static int cmp_gids (const void *pa, const void *pb, void *arg)
209  {
210  const accelerator_t *thiz = (const accelerator_t *) arg;
211  uint16_t a = * (const uint16_t *) pa;
212  uint16_t b = * (const uint16_t *) pb;
213  return thiz->find_glyph_name (b).cmp (thiz->find_glyph_name (a));
214  }
215 
216  static int cmp_key (const void *pk, const void *po, void *arg)
217  {
218  const accelerator_t *thiz = (const accelerator_t *) arg;
219  const hb_bytes_t *key = (const hb_bytes_t *) pk;
220  uint16_t o = * (const uint16_t *) po;
221  return thiz->find_glyph_name (o).cmp (*key);
222  }
223 
225  {
226  if (version == 0x00010000)
227  {
228  if (glyph >= format1_names_length)
229  return hb_bytes_t ();
230 
231  return format1_names (glyph);
232  }
233 
234  if (version != 0x00020000 || glyph >= glyphNameIndex->len)
235  return hb_bytes_t ();
236 
237  unsigned int index = glyphNameIndex->arrayZ[glyph];
238  if (index < format1_names_length)
239  return format1_names (index);
240  index -= format1_names_length;
241 
242  if (index >= index_to_offset.length)
243  return hb_bytes_t ();
244  unsigned int offset = index_to_offset[index];
245 
246  const uint8_t *data = pool + offset;
247  unsigned int name_length = *data;
248  data++;
249 
250  return hb_bytes_t ((const char *) data, name_length);
251  }
252 
253  private:
254  uint32_t version;
255  const Array16Of<HBUINT16> *glyphNameIndex = nullptr;
256  hb_vector_t<uint32_t> index_to_offset;
257  const uint8_t *pool = nullptr;
258  hb_atomic_ptr_t<uint16_t *> gids_sorted_by_name;
259  };
260 
261  bool has_data () const { return version.to_int (); }
262 
264  {
265  TRACE_SANITIZE (this);
266  return_trace (likely (c->check_struct (this) &&
267  (version.to_int () == 0x00010000 ||
268  (version.to_int () == 0x00020000 && v2X.sanitize (c)) ||
269  version.to_int () == 0x00030000)));
270  }
271 
272  public:
273  FixedVersion<>version; /* 0x00010000 for version 1.0
274  * 0x00020000 for version 2.0
275  * 0x00025000 for version 2.5 (deprecated)
276  * 0x00030000 for version 3.0 */
277  HBFixed italicAngle; /* Italic angle in counter-clockwise degrees
278  * from the vertical. Zero for upright text,
279  * negative for text that leans to the right
280  * (forward). */
281  FWORD underlinePosition; /* This is the suggested distance of the top
282  * of the underline from the baseline
283  * (negative values indicate below baseline).
284  * The PostScript definition of this FontInfo
285  * dictionary key (the y coordinate of the
286  * center of the stroke) is not used for
287  * historical reasons. The value of the
288  * PostScript key may be calculated by
289  * subtracting half the underlineThickness
290  * from the value of this field. */
291  FWORD underlineThickness; /* Suggested values for the underline
292  thickness. */
293  HBUINT32 isFixedPitch; /* Set to 0 if the font is proportionally
294  * spaced, non-zero if the font is not
295  * proportionally spaced (i.e. monospaced). */
296  HBUINT32 minMemType42; /* Minimum memory usage when an OpenType font
297  * is downloaded. */
298  HBUINT32 maxMemType42; /* Maximum memory usage when an OpenType font
299  * is downloaded. */
300  HBUINT32 minMemType1; /* Minimum memory usage when an OpenType font
301  * is downloaded as a Type 1 font. */
302  HBUINT32 maxMemType1; /* Maximum memory usage when an OpenType font
303  * is downloaded as a Type 1 font. */
306 };
307 
310 };
311 
312 
313 } /* namespace OT */
314 
315 
316 #endif /* HB_OT_POST_TABLE_HH */
small capitals from c petite p scientific i
[1]
Definition: afcover.h:80
int const char * version
Definition: zlib.h:814
hb_array_t< const char > hb_bytes_t
Definition: hb-array.hh:434
#define TRACE_SERIALIZE(this)
Definition: hb-debug.hh:426
#define TRACE_SANITIZE(this)
Definition: hb-debug.hh:414
#define return_trace(RET)
Definition: hb-debug.hh:349
#define TRACE_SUBSET(this)
Definition: hb-debug.hh:438
#define HB_OT_TAG_post
@ HB_SERIALIZE_ERROR_INT_OVERFLOW
Definition: hb-serialize.hh:52
@ HB_SUBSET_FLAGS_GLYPH_NAMES
Definition: hb-subset.h:87
#define hb_malloc
Definition: hb.hh:235
#define likely(expr)
Definition: hb.hh:250
#define unlikely(expr)
Definition: hb.hh:251
#define hb_free
Definition: hb.hh:238
PCRE2_SIZE PRIV() strlen(PCRE2_SPTR str)
GLint GLfloat GLfloat GLfloat v2
GLboolean GLboolean GLboolean b
GLuint64 key
GLboolean GLboolean GLboolean GLboolean a
[7]
GLuint index
[2]
GLuint GLuint end
GLenum GLenum GLsizei count
GLenum face
GLenum GLuint GLenum GLsizei const GLchar * buf
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum GLuint GLintptr offset
const GLubyte * c
Definition: qopenglext.h:12701
GLenum GLsizei len
Definition: qopenglext.h:3292
GLdouble s
[6]
Definition: qopenglext.h:235
GLenum GLenum GLsizei void * table
Definition: qopenglext.h:2745
SSL_CTX int(*) void arg)
uint32_t hb_codepoint_t
Definition: hb-common.h:106
uint32_t hb_tag_t
Definition: hb-common.h:157
QThreadPool pool
QStringList::Iterator it
uint32_t to_int() const
bool get_glyph_from_name(const char *name, int len, hb_codepoint_t *glyph) const
unsigned int get_glyph_count() const
bool get_glyph_name(hb_codepoint_t glyph, char *buf, unsigned int buf_len) const
hb_blob_ptr_t< post > table
static int cmp_gids(const void *pa, const void *pb, void *arg)
accelerator_t(hb_face_t *face)
static int cmp_key(const void *pk, const void *po, void *arg)
hb_bytes_t find_glyph_name(hb_codepoint_t glyph) const
post_accelerator_t(hb_face_t *face)
FWORD underlinePosition
HBUINT32 isFixedPitch
HBUINT32 minMemType42
HBUINT32 maxMemType1
postV2Tail v2X
HBUINT32 maxMemType42
bool serialize(hb_serialize_context_t *c, bool glyph_names) const
HBFixed italicAngle
bool has_data() const
DEFINE_SIZE_MIN(32)
FWORD underlineThickness
HBUINT32 minMemType1
FixedVersion version
static constexpr hb_tag_t tableTag
bool sanitize(hb_sanitize_context_t *c) const
bool subset(hb_subset_context_t *c) const
bool serialize(hb_serialize_context_t *c, Iterator it, const void *_post) const
bool subset(hb_subset_context_t *c) const
Array16Of< HBUINT16 > glyphNameIndex
DEFINE_SIZE_ARRAY(2, glyphNameIndex)
bool sanitize(hb_sanitize_context_t *c) const
int cmp(const hb_array_t &a) const
Definition: hb-array.hh:130
T * get() const
Definition: hb-atomic.hh:170
bool cmpexch(const T *old, T *new_) const
Definition: hb-atomic.hh:171
Type * push()
Definition: hb-vector.hh:183
unsigned int length
Definition: hb-vector.hh:76
QCommandLinkButton * pb