w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

NameTable.cpp
Go to the documentation of this file.
1 /* GRAPHITE2 LICENSING
2 
3  Copyright 2010, SIL International
4  All rights reserved.
5 
6  This library is free software; you can redistribute it and/or modify
7  it under the terms of the GNU Lesser General Public License as published
8  by the Free Software Foundation; either version 2.1 of License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  Lesser General Public License for more details.
15 
16  You should also have received a copy of the GNU Lesser General Public
17  License along with this library in the file named "LICENSE".
18  If not, write to the Free Software Foundation, 51 Franklin Street,
19  Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
20  internet at http://www.fsf.org/licenses/lgpl.html.
21 
22 Alternatively, the contents of this file may be used under the terms of the
23 Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
24 License, as published by the Free Software Foundation, either version 2
25 of the License or (at your option) any later version.
26 */
27 #include "inc/Main.h"
28 #include "inc/Endian.h"
29 
30 #include "inc/NameTable.h"
31 #include "inc/UtfCodec.h"
32 
33 using namespace graphite2;
34 
35 NameTable::NameTable(const void* data, size_t length, uint16 platformId, uint16 encodingID)
36  : m_platformId(0), m_encodingId(0), m_languageCount(0),
37  m_platformOffset(0), m_platformLastRecord(0), m_nameDataLength(0),
38  m_table(0), m_nameData(NULL)
39 {
40  void *pdata = gralloc<byte>(length);
41  if (!pdata) return;
42  memcpy(pdata, data, length);
43  m_table = reinterpret_cast<const TtfUtil::Sfnt::FontNames*>(pdata);
44 
45  if ((length > sizeof(TtfUtil::Sfnt::FontNames)) &&
46  (length > sizeof(TtfUtil::Sfnt::FontNames) +
47  sizeof(TtfUtil::Sfnt::NameRecord) * ( be::swap<uint16>(m_table->count) - 1)))
48  {
49  uint16 offset = be::swap<uint16>(m_table->string_offset);
50  if (offset < length)
51  {
52  m_nameData = reinterpret_cast<const uint8*>(pdata) + offset;
53  setPlatformEncoding(platformId, encodingID);
54  m_nameDataLength = uint16(length - offset);
55  return;
56  }
57  }
58  free(const_cast<TtfUtil::Sfnt::FontNames*>(m_table));
59  m_table = NULL;
60 }
61 
62 uint16 NameTable::setPlatformEncoding(uint16 platformId, uint16 encodingID)
63 {
64  if (!m_nameData) return 0;
65  uint16 i = 0;
66  uint16 count = be::swap<uint16>(m_table->count);
67  for (; i < count; i++)
68  {
69  if (be::swap<uint16>(m_table->name_record[i].platform_id) == platformId &&
70  be::swap<uint16>(m_table->name_record[i].platform_specific_id) == encodingID)
71  {
73  break;
74  }
75  }
76  while ((++i < count) &&
77  (be::swap<uint16>(m_table->name_record[i].platform_id) == platformId) &&
78  (be::swap<uint16>(m_table->name_record[i].platform_specific_id) == encodingID))
79  {
81  }
82  m_encodingId = encodingID;
83  m_platformId = platformId;
84  return 0;
85 }
86 
87 void* NameTable::getName(uint16& languageId, uint16 nameId, gr_encform enc, uint32& length)
88 {
89  uint16 anyLang = 0;
90  uint16 enUSLang = 0;
91  uint16 bestLang = 0;
92  if (!m_table)
93  {
94  languageId = 0;
95  length = 0;
96  return NULL;
97  }
99  {
100  if (be::swap<uint16>(m_table->name_record[i].name_id) == nameId)
101  {
102  uint16 langId = be::swap<uint16>(m_table->name_record[i].language_id);
103  if (langId == languageId)
104  {
105  bestLang = i;
106  break;
107  }
108  // MS language tags have the language in the lower byte, region in the higher
109  else if ((langId & 0xFF) == (languageId & 0xFF))
110  {
111  bestLang = i;
112  }
113  else if (langId == 0x409)
114  {
115  enUSLang = i;
116  }
117  else
118  {
119  anyLang = i;
120  }
121  }
122  }
123  if (!bestLang)
124  {
125  if (enUSLang) bestLang = enUSLang;
126  else
127  {
128  bestLang = anyLang;
129  if (!anyLang)
130  {
131  languageId = 0;
132  length = 0;
133  return NULL;
134  }
135  }
136  }
137  const TtfUtil::Sfnt::NameRecord & nameRecord = m_table->name_record[bestLang];
138  languageId = be::swap<uint16>(nameRecord.language_id);
139  uint16 utf16Length = be::swap<uint16>(nameRecord.length);
140  uint16 offset = be::swap<uint16>(nameRecord.offset);
141  if(offset + utf16Length > m_nameDataLength)
142  {
143  languageId = 0;
144  length = 0;
145  return NULL;
146  }
147  utf16Length >>= 1; // in utf16 units
148  utf16::codeunit_t * utf16Name = gralloc<utf16::codeunit_t>(utf16Length + 1);
149  if (!utf16Name)
150  {
151  languageId = 0;
152  length = 0;
153  return NULL;
154  }
155  const uint8* pName = m_nameData + offset;
156  for (size_t i = 0; i < utf16Length; i++)
157  {
158  utf16Name[i] = be::read<uint16>(pName);
159  }
160  utf16Name[utf16Length] = 0;
161  if (!utf16::validate(utf16Name, utf16Name + utf16Length))
162  {
163  free(utf16Name);
164  languageId = 0;
165  length = 0;
166  return NULL;
167  }
168  switch (enc)
169  {
170  case gr_utf8:
171  {
172  utf8::codeunit_t* uniBuffer = gralloc<utf8::codeunit_t>(3 * utf16Length + 1);
173  if (!uniBuffer)
174  {
175  free(utf16Name);
176  languageId = 0;
177  length = 0;
178  return NULL;
179  }
180  utf8::iterator d = uniBuffer;
181  for (utf16::const_iterator s = utf16Name, e = utf16Name + utf16Length; s != e; ++s, ++d)
182  *d = *s;
183  length = uint32(d - uniBuffer);
184  uniBuffer[length] = 0;
185  free(utf16Name);
186  return uniBuffer;
187  }
188  case gr_utf16:
189  length = utf16Length;
190  return utf16Name;
191  case gr_utf32:
192  {
193  utf32::codeunit_t * uniBuffer = gralloc<utf32::codeunit_t>(utf16Length + 1);
194  if (!uniBuffer)
195  {
196  free(utf16Name);
197  languageId = 0;
198  length = 0;
199  return NULL;
200  }
201  utf32::iterator d = uniBuffer;
202  for (utf16::const_iterator s = utf16Name, e = utf16Name + utf16Length; s != e; ++s, ++d)
203  *d = *s;
204  length = uint32(d - uniBuffer);
205  uniBuffer[length] = 0;
206  free(utf16Name);
207  return uniBuffer;
208  }
209  }
210  free(utf16Name);
211  languageId = 0;
212  length = 0;
213  return NULL;
214 }
215 
216 uint16 NameTable::getLanguageId(const char * bcp47Locale)
217 {
218  size_t localeLength = strlen(bcp47Locale);
219  uint16 localeId = m_locale2Lang.getMsId(bcp47Locale);
220  if (m_table && (be::swap<uint16>(m_table->format) == 1))
221  {
222  const uint8 * pLangEntries = reinterpret_cast<const uint8*>(m_table) +
224  + sizeof(TtfUtil::Sfnt::NameRecord) * ( be::swap<uint16>(m_table->count) - 1);
225  uint16 numLangEntries = be::read<uint16>(pLangEntries);
226  const TtfUtil::Sfnt::LangTagRecord * langTag =
227  reinterpret_cast<const TtfUtil::Sfnt::LangTagRecord*>(pLangEntries);
228  if (pLangEntries + numLangEntries * sizeof(TtfUtil::Sfnt::LangTagRecord) <= m_nameData)
229  {
230  for (uint16 i = 0; i < numLangEntries; i++)
231  {
232  uint16 offset = be::swap<uint16>(langTag[i].offset);
233  uint16 length = be::swap<uint16>(langTag[i].length);
234  if ((offset + length <= m_nameDataLength) && (length == 2 * localeLength))
235  {
236  const uint8* pName = m_nameData + offset;
237  bool match = true;
238  for (size_t j = 0; j < localeLength; j++)
239  {
240  uint16 code = be::read<uint16>(pName);
241  if ((code > 0x7F) || (code != bcp47Locale[j]))
242  {
243  match = false;
244  break;
245  }
246  }
247  if (match)
248  return 0x8000 + i;
249  }
250  }
251  }
252  }
253  return localeId;
254 }
#define match
Definition: aptex-macros.h:359
#define count(a)
Definition: aptex-macros.h:781
unsigned short getMsId(const char *locale) const
Definition: locale2lcid.h:307
const TtfUtil::Sfnt::FontNames * m_table
Definition: NameTable.h:60
uint16 getLanguageId(const char *bcp47Locale)
Definition: NameTable.cpp:216
uint16 m_nameDataLength
Definition: NameTable.h:59
uint16 m_platformOffset
Definition: NameTable.h:57
uint16 m_platformLastRecord
Definition: NameTable.h:58
void * getName(uint16 &languageId, uint16 nameId, gr_encform enc, uint32 &length)
Definition: NameTable.cpp:87
const uint8 * m_nameData
Definition: NameTable.h:61
Locale2Lang m_locale2Lang
Definition: NameTable.h:62
#define free(a)
Definition: decNumber.cpp:310
struct rect data
Definition: dvipdfm.c:64
#define s
Definition: afcover.h:80
#define d(n)
Definition: gpos-common.c:151
#define memcpy(d, s, n)
Definition: gsftopk.c:64
#define NULL
Definition: ftobjs.h:61
small capitals from c petite p scientific i
Definition: afcover.h:80
#define length(c)
Definition: ctangleboot.c:65
unsigned short uint16
Definition: tiff.h:62
unsigned long uint32
Definition: tiff.h:68
unsigned char uint8
Definition: tiff.h:60
#define uint16
Definition: unibasics.h:51
Definition: bits.h:30
gr_uint32 uint32
Definition: Main.h:41
static int offset
Definition: ppmtogif.c:642
gr_encform
Definition: Types.h:39
@ gr_utf16
Definition: Types.h:40
@ gr_utf32
Definition: Types.h:40
@ gr_utf8
Definition: Types.h:40
ShellFileEnvironment e
Definition: sh6.c:388
Definition: inftrees.h:24
_utf_codec< sizeof(C) *8 >::codeunit_t codeunit_t
Definition: UtfCodec.h:235
static bool validate(codeunit_t *s, codeunit_t *e)
Definition: UtfCodec.h:241
int j
Definition: t4ht.c:1589
*job_name strlen((char *) job_name) - 4)
static const char * pName
Definition: wrtjava.cpp:92