ws2_32: Return a valid value for WSAIoctl SIO_IDEAL_SEND_BACKLOG_QUERY.
[wine.git] / dlls / win32u / opentype.c
blobc206d6dae57f3924b02ac79fe2e6c2d016396022
1 /*
2 * Copyright 2020 RĂ©mi Bernon for CodeWeavers
3 * Copyright 2014 Aric Stewart for CodeWeavers
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #if 0
21 #pragma makedep unix
22 #endif
24 #include <stdarg.h>
25 #include <stdlib.h>
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winnls.h"
31 #include "wine/debug.h"
33 #include "ntgdi_private.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(font);
37 #define MS_OTTO_TAG MS_MAKE_TAG('O','T','T','O')
38 #define MS_HEAD_TAG MS_MAKE_TAG('h','e','a','d')
39 #define MS_HHEA_TAG MS_MAKE_TAG('h','h','e','a')
40 #define MS_OS_2_TAG MS_MAKE_TAG('O','S','/','2')
41 #define MS_EBSC_TAG MS_MAKE_TAG('E','B','S','C')
42 #define MS_EBDT_TAG MS_MAKE_TAG('E','B','D','T')
43 #define MS_CBDT_TAG MS_MAKE_TAG('C','B','D','T')
44 #define MS_NAME_TAG MS_MAKE_TAG('n','a','m','e')
45 #define MS_CFF__TAG MS_MAKE_TAG('C','F','F',' ')
47 #ifdef WORDS_BIGENDIAN
48 #define GET_BE_WORD(x) (x)
49 #define GET_BE_DWORD(x) (x)
50 #else
51 #define GET_BE_WORD(x) RtlUshortByteSwap(x)
52 #define GET_BE_DWORD(x) RtlUlongByteSwap(x)
53 #endif
55 #include "pshpack2.h"
56 struct ttc_header_v1
58 CHAR TTCTag[4];
59 DWORD Version;
60 DWORD numFonts;
61 DWORD OffsetTable[1];
64 struct ttc_sfnt_v1
66 DWORD version;
67 WORD numTables;
68 WORD searchRange;
69 WORD entrySelector;
70 WORD rangeShift;
73 struct tt_tablerecord
75 DWORD tag;
76 DWORD checkSum;
77 DWORD offset;
78 DWORD length;
81 struct tt_os2_v1
83 USHORT version;
84 SHORT xAvgCharWidth;
85 USHORT usWeightClass;
86 USHORT usWidthClass;
87 SHORT fsType;
88 SHORT ySubscriptXSize;
89 SHORT ySubscriptYSize;
90 SHORT ySubscriptXOffset;
91 SHORT ySubscriptYOffset;
92 SHORT ySuperscriptXSize;
93 SHORT ySuperscriptYSize;
94 SHORT ySuperscriptXOffset;
95 SHORT ySuperscriptYOffset;
96 SHORT yStrikeoutSize;
97 SHORT yStrikeoutPosition;
98 SHORT sFamilyClass;
99 PANOSE panose;
100 ULONG ulUnicodeRange1;
101 ULONG ulUnicodeRange2;
102 ULONG ulUnicodeRange3;
103 ULONG ulUnicodeRange4;
104 CHAR achVendID[4];
105 USHORT fsSelection;
106 USHORT usFirstCharIndex;
107 USHORT usLastCharIndex;
108 /* According to the Apple spec, original version didn't have the below fields,
109 * version numbers were taken from the OpenType spec.
111 /* version 0 (TrueType 1.5) */
112 USHORT sTypoAscender;
113 USHORT sTypoDescender;
114 USHORT sTypoLineGap;
115 USHORT usWinAscent;
116 USHORT usWinDescent;
117 /* version 1 (TrueType 1.66) */
118 ULONG ulCodePageRange1;
119 ULONG ulCodePageRange2;
122 struct tt_namerecord
124 WORD platformID;
125 WORD encodingID;
126 WORD languageID;
127 WORD nameID;
128 WORD length;
129 WORD offset;
132 struct tt_name_v0
134 WORD format;
135 WORD count;
136 WORD stringOffset;
137 struct tt_namerecord nameRecord[1];
140 struct tt_head
142 USHORT majorVersion;
143 USHORT minorVersion;
144 ULONG revision;
145 ULONG checksumadj;
146 ULONG magic;
147 USHORT flags;
148 USHORT unitsPerEm;
149 ULONGLONG created;
150 ULONGLONG modified;
151 SHORT xMin;
152 SHORT yMin;
153 SHORT xMax;
154 SHORT yMax;
155 USHORT macStyle;
156 USHORT lowestRecPPEM;
157 SHORT direction_hint;
158 SHORT index_format;
159 SHORT glyphdata_format;
161 #include "poppack.h"
163 enum OPENTYPE_PLATFORM_ID
165 OPENTYPE_PLATFORM_UNICODE = 0,
166 OPENTYPE_PLATFORM_MAC,
167 OPENTYPE_PLATFORM_ISO,
168 OPENTYPE_PLATFORM_WIN,
169 OPENTYPE_PLATFORM_CUSTOM
172 enum TT_NAME_WIN_ENCODING_ID
174 TT_NAME_WIN_ENCODING_SYMBOL = 0,
175 TT_NAME_WIN_ENCODING_UNICODE_BMP,
176 TT_NAME_WIN_ENCODING_SJIS,
177 TT_NAME_WIN_ENCODING_PRC,
178 TT_NAME_WIN_ENCODING_BIG5,
179 TT_NAME_WIN_ENCODING_WANSUNG,
180 TT_NAME_WIN_ENCODING_JOHAB,
181 TT_NAME_WIN_ENCODING_RESERVED1,
182 TT_NAME_WIN_ENCODING_RESERVED2,
183 TT_NAME_WIN_ENCODING_RESERVED3,
184 TT_NAME_WIN_ENCODING_UNICODE_FULL
187 enum TT_NAME_UNICODE_ENCODING_ID
189 TT_NAME_UNICODE_ENCODING_1_0 = 0,
190 TT_NAME_UNICODE_ENCODING_1_1,
191 TT_NAME_UNICODE_ENCODING_ISO_10646,
192 TT_NAME_UNICODE_ENCODING_2_0_BMP,
193 TT_NAME_UNICODE_ENCODING_2_0_FULL,
194 TT_NAME_UNICODE_ENCODING_VAR,
195 TT_NAME_UNICODE_ENCODING_FULL,
198 enum TT_NAME_MAC_ENCODING_ID
200 TT_NAME_MAC_ENCODING_ROMAN = 0,
201 TT_NAME_MAC_ENCODING_JAPANESE,
202 TT_NAME_MAC_ENCODING_TRAD_CHINESE,
203 TT_NAME_MAC_ENCODING_KOREAN,
204 TT_NAME_MAC_ENCODING_ARABIC,
205 TT_NAME_MAC_ENCODING_HEBREW,
206 TT_NAME_MAC_ENCODING_GREEK,
207 TT_NAME_MAC_ENCODING_RUSSIAN,
208 TT_NAME_MAC_ENCODING_RSYMBOL,
209 TT_NAME_MAC_ENCODING_DEVANAGARI,
210 TT_NAME_MAC_ENCODING_GURMUKHI,
211 TT_NAME_MAC_ENCODING_GUJARATI,
212 TT_NAME_MAC_ENCODING_ORIYA,
213 TT_NAME_MAC_ENCODING_BENGALI,
214 TT_NAME_MAC_ENCODING_TAMIL,
215 TT_NAME_MAC_ENCODING_TELUGU,
216 TT_NAME_MAC_ENCODING_KANNADA,
217 TT_NAME_MAC_ENCODING_MALAYALAM,
218 TT_NAME_MAC_ENCODING_SINHALESE,
219 TT_NAME_MAC_ENCODING_BURMESE,
220 TT_NAME_MAC_ENCODING_KHMER,
221 TT_NAME_MAC_ENCODING_THAI,
222 TT_NAME_MAC_ENCODING_LAOTIAN,
223 TT_NAME_MAC_ENCODING_GEORGIAN,
224 TT_NAME_MAC_ENCODING_ARMENIAN,
225 TT_NAME_MAC_ENCODING_SIMPL_CHINESE,
226 TT_NAME_MAC_ENCODING_TIBETAN,
227 TT_NAME_MAC_ENCODING_MONGOLIAN,
228 TT_NAME_MAC_ENCODING_GEEZ,
229 TT_NAME_MAC_ENCODING_SLAVIC,
230 TT_NAME_MAC_ENCODING_VIETNAMESE,
231 TT_NAME_MAC_ENCODING_SINDHI,
232 TT_NAME_MAC_ENCODING_UNINTERPRETED
235 enum OPENTYPE_NAME_ID
237 OPENTYPE_NAME_COPYRIGHT_NOTICE = 0,
238 OPENTYPE_NAME_FAMILY,
239 OPENTYPE_NAME_SUBFAMILY,
240 OPENTYPE_NAME_UNIQUE_IDENTIFIER,
241 OPENTYPE_NAME_FULLNAME,
242 OPENTYPE_NAME_VERSION_STRING,
243 OPENTYPE_NAME_POSTSCRIPT,
244 OPENTYPE_NAME_TRADEMARK,
245 OPENTYPE_NAME_MANUFACTURER,
246 OPENTYPE_NAME_DESIGNER,
247 OPENTYPE_NAME_DESCRIPTION,
248 OPENTYPE_NAME_VENDOR_URL,
249 OPENTYPE_NAME_DESIGNER_URL,
250 OPENTYPE_NAME_LICENSE_DESCRIPTION,
251 OPENTYPE_NAME_LICENSE_INFO_URL,
252 OPENTYPE_NAME_RESERVED_ID15,
253 OPENTYPE_NAME_TYPOGRAPHIC_FAMILY,
254 OPENTYPE_NAME_TYPOGRAPHIC_SUBFAMILY,
255 OPENTYPE_NAME_COMPATIBLE_FULLNAME,
256 OPENTYPE_NAME_SAMPLE_TEXT,
257 OPENTYPE_NAME_POSTSCRIPT_CID,
258 OPENTYPE_NAME_WWS_FAMILY,
259 OPENTYPE_NAME_WWS_SUBFAMILY
262 enum OS2_FSSELECTION
264 OS2_FSSELECTION_ITALIC = 1 << 0,
265 OS2_FSSELECTION_UNDERSCORE = 1 << 1,
266 OS2_FSSELECTION_NEGATIVE = 1 << 2,
267 OS2_FSSELECTION_OUTLINED = 1 << 3,
268 OS2_FSSELECTION_STRIKEOUT = 1 << 4,
269 OS2_FSSELECTION_BOLD = 1 << 5,
270 OS2_FSSELECTION_REGULAR = 1 << 6,
271 OS2_FSSELECTION_USE_TYPO_METRICS = 1 << 7,
272 OS2_FSSELECTION_WWS = 1 << 8,
273 OS2_FSSELECTION_OBLIQUE = 1 << 9
276 static BOOL opentype_get_table_ptr( const void *data, size_t size, const struct ttc_sfnt_v1 *ttc_sfnt_v1,
277 UINT32 table_tag, const void **table_ptr, UINT32 *table_size )
279 const struct tt_tablerecord *table_record;
280 UINT16 i, table_count;
281 UINT32 offset, length;
283 if (!ttc_sfnt_v1) return FALSE;
285 table_record = (const struct tt_tablerecord *)(ttc_sfnt_v1 + 1);
286 table_count = GET_BE_WORD( ttc_sfnt_v1->numTables );
287 for (i = 0; i < table_count; i++, table_record++)
289 if (table_record->tag != table_tag) continue;
290 offset = GET_BE_DWORD( table_record->offset );
291 length = GET_BE_DWORD( table_record->length );
292 if (size < offset + length) return FALSE;
293 if (table_size && length < *table_size) return FALSE;
295 if (table_ptr) *table_ptr = (const char *)data + offset;
296 if (table_size) *table_size = length;
297 return TRUE;
300 return FALSE;
303 static BOOL opentype_get_tt_os2_v1( const void *data, size_t size, const struct ttc_sfnt_v1 *ttc_sfnt_v1,
304 const struct tt_os2_v1 **tt_os2_v1 )
306 UINT32 table_size = sizeof(**tt_os2_v1);
307 return opentype_get_table_ptr( data, size, ttc_sfnt_v1, MS_OS_2_TAG, (const void **)tt_os2_v1, &table_size );
310 static BOOL opentype_get_tt_head( const void *data, size_t size, const struct ttc_sfnt_v1 *ttc_sfnt_v1,
311 const struct tt_head **tt_head )
313 UINT32 table_size = sizeof(**tt_head);
314 return opentype_get_table_ptr( data, size, ttc_sfnt_v1, MS_HEAD_TAG, (const void **)tt_head, &table_size );
317 static UINT get_name_record_codepage( enum OPENTYPE_PLATFORM_ID platform, USHORT encoding )
319 switch (platform)
321 case OPENTYPE_PLATFORM_UNICODE:
322 return 0;
323 case OPENTYPE_PLATFORM_MAC:
324 switch (encoding)
326 case TT_NAME_MAC_ENCODING_ROMAN:
327 return 10000;
328 case TT_NAME_MAC_ENCODING_JAPANESE:
329 return 10001;
330 case TT_NAME_MAC_ENCODING_TRAD_CHINESE:
331 return 10002;
332 case TT_NAME_MAC_ENCODING_KOREAN:
333 return 10003;
334 case TT_NAME_MAC_ENCODING_ARABIC:
335 return 10004;
336 case TT_NAME_MAC_ENCODING_HEBREW:
337 return 10005;
338 case TT_NAME_MAC_ENCODING_GREEK:
339 return 10006;
340 case TT_NAME_MAC_ENCODING_RUSSIAN:
341 return 10007;
342 case TT_NAME_MAC_ENCODING_SIMPL_CHINESE:
343 return 10008;
344 case TT_NAME_MAC_ENCODING_THAI:
345 return 10021;
346 default:
347 WARN( "default ascii encoding used for encoding %d, platform %d\n", encoding, platform );
348 return 20127;
350 break;
351 case OPENTYPE_PLATFORM_WIN:
352 switch (encoding)
354 case TT_NAME_WIN_ENCODING_SYMBOL:
355 case TT_NAME_WIN_ENCODING_UNICODE_BMP:
356 case TT_NAME_WIN_ENCODING_UNICODE_FULL:
357 return 0;
358 case TT_NAME_WIN_ENCODING_SJIS:
359 return 932;
360 case TT_NAME_WIN_ENCODING_PRC:
361 return 936;
362 case TT_NAME_WIN_ENCODING_BIG5:
363 return 950;
364 case TT_NAME_WIN_ENCODING_WANSUNG:
365 return 20949;
366 case TT_NAME_WIN_ENCODING_JOHAB:
367 return 1361;
368 default:
369 WARN( "default ascii encoding used for encoding %d, platform %d\n", encoding, platform );
370 return 20127;
372 break;
373 default:
374 FIXME( "unknown platform %d\n", platform );
375 break;
378 return 0;
381 static const LANGID mac_langid_table[] =
383 MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT),
384 MAKELANGID(LANG_FRENCH, SUBLANG_DEFAULT),
385 MAKELANGID(LANG_GERMAN, SUBLANG_DEFAULT),
386 MAKELANGID(LANG_ITALIAN, SUBLANG_DEFAULT),
387 MAKELANGID(LANG_DUTCH, SUBLANG_DEFAULT),
388 MAKELANGID(LANG_SWEDISH, SUBLANG_DEFAULT),
389 MAKELANGID(LANG_SPANISH, SUBLANG_DEFAULT),
390 MAKELANGID(LANG_DANISH, SUBLANG_DEFAULT),
391 MAKELANGID(LANG_PORTUGUESE, SUBLANG_DEFAULT),
392 MAKELANGID(LANG_NORWEGIAN, SUBLANG_DEFAULT),
393 MAKELANGID(LANG_HEBREW, SUBLANG_DEFAULT),
394 MAKELANGID(LANG_JAPANESE, SUBLANG_DEFAULT),
395 MAKELANGID(LANG_ARABIC, SUBLANG_DEFAULT),
396 MAKELANGID(LANG_FINNISH, SUBLANG_DEFAULT),
397 MAKELANGID(LANG_GREEK, SUBLANG_DEFAULT),
398 MAKELANGID(LANG_ICELANDIC, SUBLANG_DEFAULT),
399 MAKELANGID(LANG_MALTESE, SUBLANG_DEFAULT),
400 MAKELANGID(LANG_TURKISH, SUBLANG_DEFAULT),
401 MAKELANGID(LANG_CROATIAN, SUBLANG_DEFAULT),
402 MAKELANGID(LANG_CHINESE_TRADITIONAL, SUBLANG_DEFAULT),
403 MAKELANGID(LANG_URDU, SUBLANG_DEFAULT),
404 MAKELANGID(LANG_HINDI, SUBLANG_DEFAULT),
405 MAKELANGID(LANG_THAI, SUBLANG_DEFAULT),
406 MAKELANGID(LANG_KOREAN, SUBLANG_DEFAULT),
407 MAKELANGID(LANG_LITHUANIAN, SUBLANG_DEFAULT),
408 MAKELANGID(LANG_POLISH, SUBLANG_DEFAULT),
409 MAKELANGID(LANG_HUNGARIAN, SUBLANG_DEFAULT),
410 MAKELANGID(LANG_ESTONIAN, SUBLANG_DEFAULT),
411 MAKELANGID(LANG_LATVIAN, SUBLANG_DEFAULT),
412 MAKELANGID(LANG_SAMI, SUBLANG_DEFAULT),
413 MAKELANGID(LANG_FAEROESE, SUBLANG_DEFAULT),
414 MAKELANGID(LANG_FARSI, SUBLANG_DEFAULT),
415 MAKELANGID(LANG_RUSSIAN, SUBLANG_DEFAULT),
416 MAKELANGID(LANG_CHINESE_SIMPLIFIED, SUBLANG_DEFAULT),
417 MAKELANGID(LANG_DUTCH, SUBLANG_DUTCH_BELGIAN),
418 MAKELANGID(LANG_IRISH, SUBLANG_DEFAULT),
419 MAKELANGID(LANG_ALBANIAN, SUBLANG_DEFAULT),
420 MAKELANGID(LANG_ROMANIAN, SUBLANG_DEFAULT),
421 MAKELANGID(LANG_CZECH, SUBLANG_DEFAULT),
422 MAKELANGID(LANG_SLOVAK, SUBLANG_DEFAULT),
423 MAKELANGID(LANG_SLOVENIAN, SUBLANG_DEFAULT),
425 MAKELANGID(LANG_SERBIAN, SUBLANG_DEFAULT),
426 MAKELANGID(LANG_MACEDONIAN, SUBLANG_DEFAULT),
427 MAKELANGID(LANG_BULGARIAN, SUBLANG_DEFAULT),
428 MAKELANGID(LANG_UKRAINIAN, SUBLANG_DEFAULT),
429 MAKELANGID(LANG_BELARUSIAN, SUBLANG_DEFAULT),
430 MAKELANGID(LANG_UZBEK, SUBLANG_DEFAULT),
431 MAKELANGID(LANG_KAZAK, SUBLANG_DEFAULT),
432 MAKELANGID(LANG_AZERI, SUBLANG_AZERI_CYRILLIC),
434 MAKELANGID(LANG_ARMENIAN, SUBLANG_DEFAULT),
435 MAKELANGID(LANG_GEORGIAN, SUBLANG_DEFAULT),
437 MAKELANGID(LANG_KYRGYZ, SUBLANG_DEFAULT),
438 MAKELANGID(LANG_TAJIK, SUBLANG_DEFAULT),
439 MAKELANGID(LANG_TURKMEN, SUBLANG_DEFAULT),
440 MAKELANGID(LANG_MONGOLIAN, SUBLANG_DEFAULT),
441 MAKELANGID(LANG_MONGOLIAN, SUBLANG_MONGOLIAN_CYRILLIC_MONGOLIA),
442 MAKELANGID(LANG_PASHTO, SUBLANG_DEFAULT),
444 MAKELANGID(LANG_KASHMIRI, SUBLANG_DEFAULT),
445 MAKELANGID(LANG_SINDHI, SUBLANG_DEFAULT),
446 MAKELANGID(LANG_TIBETAN, SUBLANG_DEFAULT),
447 MAKELANGID(LANG_NEPALI, SUBLANG_DEFAULT),
448 MAKELANGID(LANG_SANSKRIT, SUBLANG_DEFAULT),
449 MAKELANGID(LANG_MARATHI, SUBLANG_DEFAULT),
450 MAKELANGID(LANG_BENGALI, SUBLANG_DEFAULT),
451 MAKELANGID(LANG_ASSAMESE, SUBLANG_DEFAULT),
452 MAKELANGID(LANG_GUJARATI, SUBLANG_DEFAULT),
453 MAKELANGID(LANG_PUNJABI, SUBLANG_DEFAULT),
454 MAKELANGID(LANG_ORIYA, SUBLANG_DEFAULT),
455 MAKELANGID(LANG_MALAYALAM, SUBLANG_DEFAULT),
456 MAKELANGID(LANG_KANNADA, SUBLANG_DEFAULT),
457 MAKELANGID(LANG_TAMIL, SUBLANG_DEFAULT),
458 MAKELANGID(LANG_TELUGU, SUBLANG_DEFAULT),
459 MAKELANGID(LANG_SINHALESE, SUBLANG_DEFAULT),
461 MAKELANGID(LANG_KHMER, SUBLANG_DEFAULT),
462 MAKELANGID(LANG_LAO, SUBLANG_DEFAULT),
463 MAKELANGID(LANG_VIETNAMESE, SUBLANG_DEFAULT),
464 MAKELANGID(LANG_INDONESIAN, SUBLANG_DEFAULT),
466 MAKELANGID(LANG_MALAY, SUBLANG_DEFAULT),
468 MAKELANGID(LANG_AMHARIC, SUBLANG_DEFAULT),
469 MAKELANGID(LANG_TIGRIGNA, SUBLANG_DEFAULT),
472 MAKELANGID(LANG_SWAHILI, SUBLANG_DEFAULT),
476 MAKELANGID(LANG_MALAGASY, SUBLANG_DEFAULT),
477 MAKELANGID(LANG_ESPERANTO, SUBLANG_DEFAULT),
511 MAKELANGID(LANG_WELSH, SUBLANG_DEFAULT),
512 MAKELANGID(LANG_BASQUE, SUBLANG_DEFAULT),
513 MAKELANGID(LANG_CATALAN, SUBLANG_DEFAULT),
515 MAKELANGID(LANG_QUECHUA, SUBLANG_DEFAULT),
518 MAKELANGID(LANG_TATAR, SUBLANG_DEFAULT),
519 MAKELANGID(LANG_UIGHUR, SUBLANG_DEFAULT),
523 MAKELANGID(LANG_GALICIAN, SUBLANG_DEFAULT),
524 MAKELANGID(LANG_AFRIKAANS, SUBLANG_DEFAULT),
525 MAKELANGID(LANG_BRETON, SUBLANG_DEFAULT),
526 MAKELANGID(LANG_INUKTITUT, SUBLANG_DEFAULT),
527 MAKELANGID(LANG_SCOTTISH_GAELIC, SUBLANG_DEFAULT),
528 MAKELANGID(LANG_MANX_GAELIC, SUBLANG_DEFAULT),
529 MAKELANGID(LANG_IRISH, SUBLANG_IRISH_IRELAND),
532 MAKELANGID(LANG_GREENLANDIC, SUBLANG_DEFAULT),
533 MAKELANGID(LANG_AZERI, SUBLANG_AZERI_LATIN),
536 static LANGID get_name_record_langid( enum OPENTYPE_PLATFORM_ID platform, USHORT encoding, USHORT language )
538 switch (platform)
540 case OPENTYPE_PLATFORM_WIN:
541 return language;
542 case OPENTYPE_PLATFORM_MAC:
543 if (language < ARRAY_SIZE(mac_langid_table)) return mac_langid_table[language];
544 WARN( "invalid mac lang id %d\n", language );
545 break;
546 case OPENTYPE_PLATFORM_UNICODE:
547 switch (encoding)
549 case TT_NAME_UNICODE_ENCODING_1_0:
550 case TT_NAME_UNICODE_ENCODING_ISO_10646:
551 case TT_NAME_UNICODE_ENCODING_2_0_BMP:
552 if (language < ARRAY_SIZE(mac_langid_table)) return mac_langid_table[language];
553 WARN( "invalid unicode lang id %d\n", language );
554 break;
555 default:
556 break;
558 break;
559 default:
560 FIXME( "unknown platform %d\n", platform );
561 break;
564 return MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
567 static BOOL opentype_enum_font_names( const struct tt_name_v0 *header, enum OPENTYPE_PLATFORM_ID platform,
568 enum OPENTYPE_NAME_ID name, opentype_enum_names_cb callback, void *user )
570 const char *name_data;
571 USHORT i, name_count, encoding, language, length, offset;
572 USHORT platform_id = GET_BE_WORD( platform ), name_id = GET_BE_WORD( name );
573 LANGID langid;
574 BOOL ret = FALSE;
576 switch (GET_BE_WORD( header->format ))
578 case 0:
579 case 1:
580 break;
581 default:
582 FIXME( "unsupported name format %d\n", GET_BE_WORD( header->format ) );
583 return FALSE;
586 name_data = (const char *)header + GET_BE_WORD( header->stringOffset );
587 name_count = GET_BE_WORD( header->count );
588 for (i = 0; i < name_count; i++)
590 const struct tt_namerecord *record = &header->nameRecord[i];
591 struct opentype_name opentype_name;
593 if (record->nameID != name_id) continue;
594 if (record->platformID != platform_id) continue;
596 language = GET_BE_WORD( record->languageID );
597 if (language >= 0x8000)
599 FIXME( "handle name format 1\n" );
600 continue;
603 encoding = GET_BE_WORD( record->encodingID );
604 offset = GET_BE_WORD( record->offset );
605 length = GET_BE_WORD( record->length );
606 langid = get_name_record_langid( platform, encoding, language );
608 opentype_name.codepage = get_name_record_codepage( platform, encoding );
609 opentype_name.length = length;
610 opentype_name.bytes = name_data + offset;
612 if ((ret = callback( langid, &opentype_name, user ))) break;
615 return ret;
618 BOOL opentype_get_ttc_sfnt_v1( const void *data, size_t size, DWORD index, DWORD *count, const struct ttc_sfnt_v1 **ttc_sfnt_v1 )
620 const struct ttc_header_v1 *ttc_header_v1 = data;
621 const struct tt_os2_v1 *tt_os2_v1;
622 UINT32 offset, fourcc;
624 *ttc_sfnt_v1 = NULL;
625 *count = 1;
627 if (size < sizeof(fourcc)) return FALSE;
628 memcpy( &fourcc, data, sizeof(fourcc) );
630 switch (fourcc)
632 default:
633 WARN( "unsupported font format %x\n", fourcc );
634 return FALSE;
635 case MS_TTCF_TAG:
636 if (size < sizeof(ttc_header_v1)) return FALSE;
637 if (index >= (*count = GET_BE_DWORD( ttc_header_v1->numFonts ))) return FALSE;
638 offset = GET_BE_DWORD( ttc_header_v1->OffsetTable[index] );
639 break;
640 case 0x00000100:
641 case MS_OTTO_TAG:
642 offset = 0;
643 break;
646 if (size < offset + sizeof(**ttc_sfnt_v1)) return FALSE;
647 *ttc_sfnt_v1 = (const struct ttc_sfnt_v1 *)((const char *)data + offset);
649 if (!opentype_get_table_ptr( data, size, *ttc_sfnt_v1, MS_HEAD_TAG, NULL, NULL ))
651 WARN( "unsupported sfnt font: missing head table.\n" );
652 return FALSE;
655 if (!opentype_get_table_ptr( data, size, *ttc_sfnt_v1, MS_HHEA_TAG, NULL, NULL ))
657 WARN( "unsupported sfnt font: missing hhea table.\n" );
658 return FALSE;
661 if (!opentype_get_tt_os2_v1( data, size, *ttc_sfnt_v1, &tt_os2_v1 ))
663 WARN( "unsupported sfnt font: missing OS/2 table.\n" );
664 return FALSE;
667 /* Wine uses ttfs as an intermediate step in building its bitmap fonts;
668 we don't want to load these. */
669 if (!memcmp( tt_os2_v1->achVendID, "Wine", sizeof(tt_os2_v1->achVendID) ) &&
670 opentype_get_table_ptr( data, size, *ttc_sfnt_v1, MS_EBSC_TAG, NULL, NULL ))
672 TRACE( "ignoring wine bitmap-only sfnt font.\n" );
673 return FALSE;
676 if (opentype_get_table_ptr( data, size, *ttc_sfnt_v1, MS_EBDT_TAG, NULL, NULL ) ||
677 opentype_get_table_ptr( data, size, *ttc_sfnt_v1, MS_CBDT_TAG, NULL, NULL ))
679 WARN( "unsupported sfnt font: embedded bitmap data.\n" );
680 return FALSE;
683 return TRUE;
686 BOOL opentype_get_tt_name_v0( const void *data, size_t size, const struct ttc_sfnt_v1 *ttc_sfnt_v1,
687 const struct tt_name_v0 **tt_name_v0 )
689 UINT32 table_size = sizeof(**tt_name_v0);
690 return opentype_get_table_ptr( data, size, ttc_sfnt_v1, MS_NAME_TAG, (const void **)tt_name_v0, &table_size );
693 BOOL opentype_enum_family_names( const struct tt_name_v0 *header, opentype_enum_names_cb callback, void *user )
695 if (opentype_enum_font_names( header, OPENTYPE_PLATFORM_WIN, OPENTYPE_NAME_FAMILY, callback, user ))
696 return TRUE;
697 if (opentype_enum_font_names( header, OPENTYPE_PLATFORM_MAC, OPENTYPE_NAME_FAMILY, callback, user ))
698 return TRUE;
699 if (opentype_enum_font_names( header, OPENTYPE_PLATFORM_UNICODE, OPENTYPE_NAME_FAMILY, callback, user ))
700 return TRUE;
701 return FALSE;
704 BOOL opentype_enum_style_names( const struct tt_name_v0 *header, opentype_enum_names_cb callback, void *user )
706 if (opentype_enum_font_names( header, OPENTYPE_PLATFORM_WIN, OPENTYPE_NAME_SUBFAMILY, callback, user ))
707 return TRUE;
708 if (opentype_enum_font_names( header, OPENTYPE_PLATFORM_MAC, OPENTYPE_NAME_SUBFAMILY, callback, user ))
709 return TRUE;
710 if (opentype_enum_font_names( header, OPENTYPE_PLATFORM_UNICODE, OPENTYPE_NAME_SUBFAMILY, callback, user ))
711 return TRUE;
712 return FALSE;
715 BOOL opentype_enum_full_names( const struct tt_name_v0 *header, opentype_enum_names_cb callback, void *user )
717 if (opentype_enum_font_names( header, OPENTYPE_PLATFORM_WIN, OPENTYPE_NAME_FULLNAME, callback, user ))
718 return TRUE;
719 if (opentype_enum_font_names( header, OPENTYPE_PLATFORM_MAC, OPENTYPE_NAME_FULLNAME, callback, user ))
720 return TRUE;
721 if (opentype_enum_font_names( header, OPENTYPE_PLATFORM_UNICODE, OPENTYPE_NAME_FULLNAME, callback, user ))
722 return TRUE;
723 return FALSE;
726 BOOL opentype_get_properties( const void *data, size_t size, const struct ttc_sfnt_v1 *ttc_sfnt_v1,
727 DWORD *version, FONTSIGNATURE *fs, DWORD *ntm_flags )
729 const struct tt_os2_v1 *tt_os2_v1;
730 const struct tt_head *tt_head;
731 const void *cff_header;
732 UINT32 table_size = 0;
733 USHORT idx, selection;
734 DWORD flags = 0;
736 if (!opentype_get_tt_head( data, size, ttc_sfnt_v1, &tt_head )) return FALSE;
737 if (!opentype_get_tt_os2_v1( data, size, ttc_sfnt_v1, &tt_os2_v1 )) return FALSE;
739 *version = GET_BE_DWORD( tt_head->revision );
741 fs->fsUsb[0] = GET_BE_DWORD( tt_os2_v1->ulUnicodeRange1 );
742 fs->fsUsb[1] = GET_BE_DWORD( tt_os2_v1->ulUnicodeRange2 );
743 fs->fsUsb[2] = GET_BE_DWORD( tt_os2_v1->ulUnicodeRange3 );
744 fs->fsUsb[3] = GET_BE_DWORD( tt_os2_v1->ulUnicodeRange4 );
746 if (tt_os2_v1->version == 0)
748 idx = GET_BE_WORD( tt_os2_v1->usFirstCharIndex );
749 if (idx >= 0xf000 && idx < 0xf100) fs->fsCsb[0] = FS_SYMBOL;
750 else fs->fsCsb[0] = FS_LATIN1;
751 fs->fsCsb[1] = 0;
753 else
755 fs->fsCsb[0] = GET_BE_DWORD( tt_os2_v1->ulCodePageRange1 );
756 fs->fsCsb[1] = GET_BE_DWORD( tt_os2_v1->ulCodePageRange2 );
759 selection = GET_BE_WORD( tt_os2_v1->fsSelection );
761 if (selection & OS2_FSSELECTION_ITALIC) flags |= NTM_ITALIC;
762 if (selection & OS2_FSSELECTION_BOLD) flags |= NTM_BOLD;
763 if (selection & OS2_FSSELECTION_REGULAR) flags |= NTM_REGULAR;
764 if (flags == 0) flags = NTM_REGULAR;
766 if (opentype_get_table_ptr( data, size, ttc_sfnt_v1, MS_CFF__TAG, &cff_header, &table_size ))
767 flags |= NTM_PS_OPENTYPE;
769 *ntm_flags = flags;
770 return TRUE;