1b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod/*
20ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod * Copyright © 2011,2012  Google, Inc.
3b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod *
4b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod *  This is part of HarfBuzz, a text shaping library.
5b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod *
6b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod * Permission is hereby granted, without written agreement and without
7b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod * license or royalty fees, to use, copy, modify, and distribute this
8b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod * software and its documentation for any purpose, provided that the
9b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod * above copyright notice and the following two paragraphs appear in
10b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod * all copies of this software.
11b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod *
12b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
13b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
14b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
15b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
16b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod * DAMAGE.
17b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod *
18b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
19b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
21b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
22b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
23b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod *
24b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod * Google Author(s): Behdad Esfahbod
25b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod */
26b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod
277a750ac33ec482e2c4856c19ea607f3563741c24Behdad Esfahbod#ifndef HB_OT_NAME_TABLE_HH
287a750ac33ec482e2c4856c19ea607f3563741c24Behdad Esfahbod#define HB_OT_NAME_TABLE_HH
29b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod
30b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod#include "hb-open-type-private.hh"
31b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod
32b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod
337c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbodnamespace OT {
347c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod
35b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod
36b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod/*
37ae9877dea6a1aed3566d9b87a75ede84259deacaBehdad Esfahbod * name -- The Naming Table
38b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod */
39b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod
40b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod#define HB_OT_TAG_name HB_TAG('n','a','m','e')
41b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod
42ae9877dea6a1aed3566d9b87a75ede84259deacaBehdad Esfahbod
43b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbodstruct NameRecord
44b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod{
45892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod  static int cmp (const NameRecord *a, const NameRecord *b)
46892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod  {
47892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod    int ret;
48892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod    ret = b->platformID.cmp (a->platformID);
49892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod    if (ret) return ret;
50892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod    ret = b->encodingID.cmp (a->encodingID);
51892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod    if (ret) return ret;
52892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod    ret = b->languageID.cmp (a->languageID);
53892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod    if (ret) return ret;
54892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod    ret = b->nameID.cmp (a->nameID);
55892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod    if (ret) return ret;
56892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod    return 0;
57892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod  }
58892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod
59b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod  inline bool sanitize (hb_sanitize_context_t *c, void *base) {
60be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod    TRACE_SANITIZE (this);
61b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod    /* We can check from base all the way up to the end of string... */
620ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod    return TRACE_RETURN (c->check_struct (this) && c->check_range ((char *) base, (unsigned int) length + offset));
63b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod  }
64b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod
65b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod  USHORT	platformID;	/* Platform ID. */
66b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod  USHORT	encodingID;	/* Platform-specific encoding ID. */
67b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod  USHORT	languageID;	/* Language ID. */
68b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod  USHORT	nameID;		/* Name ID. */
69b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod  USHORT	length;		/* String length (in bytes). */
70b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod  USHORT	offset;		/* String offset from start of storage area (in bytes). */
71b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod  public:
72b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod  DEFINE_SIZE_STATIC (12);
73b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod};
74b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod
75b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbodstruct name
76b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod{
776c48f20eea22c6e686416ab4ec8388be3e8cd0b5Behdad Esfahbod  static const hb_tag_t tableTag	= HB_OT_TAG_name;
78b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod
79892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod  inline unsigned int get_name (unsigned int platform_id,
80892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod				unsigned int encoding_id,
81892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod				unsigned int language_id,
82892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod				unsigned int name_id,
83892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod				void *buffer,
84892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod				unsigned int buffer_length) const
85892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod  {
86892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod    NameRecord key;
87892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod    key.platformID.set (platform_id);
88892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod    key.encodingID.set (encoding_id);
89892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod    key.languageID.set (language_id);
90892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod    key.nameID.set (name_id);
91892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod    NameRecord *match = (NameRecord *) bsearch (&key, nameRecord, count, sizeof (nameRecord[0]), (hb_compare_func_t) NameRecord::cmp);
92892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod
93892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod    if (!match)
94892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod      return 0;
95892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod
96892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod    unsigned int length = MIN (buffer_length, (unsigned int) match->length);
97e9c71fab30fd1d5b163c8a072f9e2d3eb8ba3a92Behdad Esfahbod    memcpy (buffer, (char *) this + stringOffset + match->offset, length);
98892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod    return length;
99892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod  }
100892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod
10105bad3b8c25a89bc0f20f99f9215e492f48f03feBehdad Esfahbod  inline unsigned int get_size (void) const
10205bad3b8c25a89bc0f20f99f9215e492f48f03feBehdad Esfahbod  { return min_size + count * nameRecord[0].min_size; }
10305bad3b8c25a89bc0f20f99f9215e492f48f03feBehdad Esfahbod
104b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod  inline bool sanitize_records (hb_sanitize_context_t *c) {
105be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod    TRACE_SANITIZE (this);
106d6016e49108be183ab2dc9c226447d1db3a09b90Behdad Esfahbod    char *string_pool = (char *) this + stringOffset;
107b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod    unsigned int _count = count;
108b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod    for (unsigned int i = 0; i < _count; i++)
1090ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod      if (!nameRecord[i].sanitize (c, string_pool)) return TRACE_RETURN (false);
1100ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod    return TRACE_RETURN (true);
111b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod  }
112b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod
113b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod  inline bool sanitize (hb_sanitize_context_t *c) {
114be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod    TRACE_SANITIZE (this);
1150ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod    return TRACE_RETURN (c->check_struct (this) &&
1160ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod			 likely (format == 0 || format == 1) &&
1170ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod			 c->check_array (nameRecord, nameRecord[0].static_size, count) &&
1180ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod			 sanitize_records (c));
119b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod  }
120b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod
121b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod  /* We only implement format 0 for now. */
122b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod  USHORT	format;			/* Format selector (=0/1). */
123b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod  USHORT	count;			/* Number of name records. */
1248b16ff12590200afb08e8821e3f14d2fdf8efbdaBehdad Esfahbod  Offset<>	stringOffset;		/* Offset to start of string storage (from start of table). */
125b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod  NameRecord	nameRecord[VAR];	/* The name records where count is the number of records. */
126b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod  public:
127b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod  DEFINE_SIZE_ARRAY (6, nameRecord);
128b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod};
129b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod
130b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod
1317d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod} /* namespace OT */
1327c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod
133b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod
1347a750ac33ec482e2c4856c19ea607f3563741c24Behdad Esfahbod#endif /* HB_OT_NAME_TABLE_HH */
135