44#define GET_BE_WORD(x) (x)
45#define GET_BE_DWORD(x) (x)
47#define GET_BE_WORD(x) RtlUshortByteSwap(x)
48#define GET_BE_DWORD(x) RtlUlongByteSwap(x)
51#define round(x) (((x) < 0) ? (int)((x) - 0.5) : (int)((x) + 0.5))
54#define CMAP_TAG MS_MAKE_TAG('c', 'm', 'a', 'p')
680 if (utf32c < 0x10000)
690 *glyph_index = 0xffffu;
723 if (!
table)
return 0;
758 void *glyph_class_table =
NULL;
807 ERR(
"Unknown glyph class %i\n",
class);
833 TRACE(
"Coverage Format 1, %i glyphs\n",
count);
847 TRACE(
"Coverage Format 2, %i ranges\n",
count);
889 TRACE(
"Single Substitution Subtable\n");
900 TRACE(
" Glyph 0x%x ->",glyphs[glyph_index]);
902 TRACE(
" 0x%x\n",glyphs[glyph_index]);
903 return glyph_index + write_dir;
922 TRACE(
" Glyph is 0x%x ->",glyphs[glyph_index]);
924 TRACE(
"0x%x\n",glyphs[glyph_index]);
925 return glyph_index + write_dir;
935 TRACE(
"Multiple Substitution Subtable\n");
953 TRACE(
" Glyph 0x%x (+%i)->",glyphs[glyph_index],(sub_count-1));
955 for (
j = (*glyph_count)+(sub_count-1);
j > glyph_index;
j--)
956 glyphs[
j] =glyphs[
j-(sub_count-1)];
958 for (
j = 0;
j < sub_count;
j++)
964 *glyph_count = *glyph_count + (sub_count - 1);
968 for (
j = 0;
j < sub_count;
j++)
969 TRACE(
" 0x%x",glyphs[glyph_index+
j]);
974 return glyph_index + sub_count;
976 return glyph_index - 1;
985 TRACE(
"Alternate Substitution Subtable\n");
1006 TRACE(
" Glyph 0x%x ->",glyphs[glyph_index]);
1008 TRACE(
" 0x%x\n",glyphs[glyph_index]);
1009 return glyph_index + write_dir;
1019 TRACE(
"Ligature Substitution Subtable\n");
1037 TRACE(
" LigatureSet has %i members\n",
count);
1041 int CompCount,
l,CompIndex;
1046 CompIndex = glyph_index+write_dir;
1047 for (
l = 0; l < CompCount && CompIndex >= 0 && CompIndex < *glyph_count;
l++)
1051 if (CompGlyph != glyphs[CompIndex])
1053 CompIndex += write_dir;
1057 int replaceIdx = glyph_index;
1059 replaceIdx = glyph_index - CompCount;
1061 TRACE(
" Glyph is 0x%x (+%i) ->",glyphs[glyph_index],CompCount);
1063 TRACE(
"0x%x\n",glyphs[replaceIdx]);
1066 unsigned int j = replaceIdx + 1;
1067 memmove(&glyphs[
j], &glyphs[
j + CompCount], (*glyph_count -
j) *
sizeof(*glyphs));
1068 *glyph_count = *glyph_count - CompCount;
1070 return replaceIdx + write_dir;
1081 TRACE(
"Context Substitution Subtable\n");
1090 TRACE(
"Context Substitution Subtable: Class 1\n");
1108 int newIndex = glyph_index;
1113 TRACE(
" SubRule has %i glyphs\n",g_count);
1115 g = glyph_index + write_dir * (g_count - 1);
1116 if (
g >= *glyph_count)
1119 for (
l = 0;
l < g_count-1;
l++)
1124 TRACE(
" Rule does not match\n");
1128 TRACE(
" Rule matches\n");
1136 g = glyph_index + write_dir * sequence_index;
1137 if (
g >= *glyph_count)
1139 WARN(
"Invalid sequence index %u (glyph index %u, write dir %d).\n",
1140 sequence_index, glyph_index, write_dir);
1144 TRACE(
" SUBST: %u -> %u %u.\n",
l, sequence_index, lookup_index);
1148 ERR(
" Chain failed to generate a glyph\n");
1159 const void *glyph_class_table;
1163 TRACE(
"Context Substitution Subtable: Class 2\n");
1173 glyph_class_table = (
const BYTE *)csf2 +
offset;
1180 TRACE(
" No class rule table for class %i\n",
class);
1185 TRACE(
" SubClassSet has %i members\n",
count);
1192 int newIndex = glyph_index;
1197 TRACE(
" SubClassRule has %i glyphs classes\n",g_count);
1199 g = glyph_index + write_dir * (g_count - 1);
1200 if (
g >= *glyph_count)
1203 for (
l = 0;
l < g_count-1;
l++)
1205 int g_class =
OT_get_glyph_class(glyph_class_table, glyphs[glyph_index + (write_dir * (
l+1))]);
1211 TRACE(
" Rule does not match\n");
1215 TRACE(
" Rule matches\n");
1223 g = glyph_index + write_dir * sequence_index;
1224 if (
g >= *glyph_count)
1226 WARN(
"Invalid sequence index %u (glyph index %u, write dir %d).\n",
1227 sequence_index, glyph_index, write_dir);
1231 TRACE(
" SUBST: %u -> %u %u.\n",
l, sequence_index, lookup_index);
1235 ERR(
" Chain failed to generate a glyph\n");
1253 TRACE(
"Chaining Contextual Substitution Subtable\n");
1258 int dirLookahead = write_dir;
1259 int dirBacktrack = -1 * write_dir;
1266 FIXME(
" TODO: subtype 1 (Simple context glyph substitution)\n");
1272 const void *backtrack_class_table;
1273 const void *input_class_table;
1274 const void *lookahead_class_table;
1281 TRACE(
" subtype 2 (Class-based Chaining Context Glyph Substitution)\n");
1287 TRACE(
"Glyph not covered\n");
1291 backtrack_class_table = (
const BYTE*)ccsf2+
offset;
1293 input_class_table = (
const BYTE*)ccsf2+
offset;
1295 lookahead_class_table = (
const BYTE*)ccsf2+
offset;
1303 TRACE(
"No rules for class\n");
1314 WORD backtrack_count, input_count, lookahead_count, substitute_count;
1325 k = glyph_index + dirBacktrack * backtrack_count;
1326 if (k < 0 || k >= *glyph_count)
1331 k = glyph_index + write_dir * input_count;
1332 if (k < 0 || k >= *glyph_count)
1337 k = glyph_index + dirLookahead * (input_count + lookahead_count);
1338 if (k < 0 || k >= *glyph_count)
1343 for (
k = 0;
k < backtrack_count; ++
k)
1347 if (target_class != glyph_class)
1350 if (
k != backtrack_count)
1352 TRACE(
"Matched Backtrack\n");
1354 for (
k = 0;
k < input_count; ++
k)
1358 if (target_class != glyph_class)
1361 if (
k != input_count)
1363 TRACE(
"Matched IndexGlyphs\n");
1365 for (
k = 0;
k < lookahead_count; ++
k)
1369 glyphs[glyph_index + (dirLookahead * (input_count +
k + 1))]);
1370 if (target_class != glyph_class)
1373 if (
k != lookahead_count)
1375 TRACE(
"Matched LookAhead\n");
1378 for (
k = 0;
k < substitute_count; ++
k)
1382 unsigned int g = glyph_index + write_dir * sequence_index;
1384 if (
g >= *glyph_count)
1386 WARN(
"Skipping invalid sequence index %u (glyph index %u, write dir %d).\n",
1387 sequence_index, glyph_index, write_dir);
1391 TRACE(
"SUBST: %u -> %u %u.\n",
k, sequence_index, lookup_index);
1394 ERR(
"Chain failed to generate a glyph.\n");
1401 WORD backtrack_count, input_count, lookahead_count, substitution_count;
1409 TRACE(
" subtype 3 (Coverage-based Chaining Context Glyph Substitution)\n");
1413 k = glyph_index + dirBacktrack * backtrack_count;
1414 if (k < 0 || k >= *glyph_count)
1419 k = glyph_index + write_dir * (input_count - 1);
1420 if (k < 0 || k >= *glyph_count)
1425 k = glyph_index + dirLookahead * (input_count + lookahead_count - 1);
1426 if (k < 0 || k >= *glyph_count)
1431 for (
k = 0;
k < backtrack_count; ++
k)
1435 glyphs[glyph_index + (dirBacktrack * (
k + 1))]) == -1)
1438 if (
k != backtrack_count)
1440 TRACE(
"Matched Backtrack\n");
1442 for (
k = 0;
k < input_count; ++
k)
1446 glyphs[glyph_index + (write_dir *
k)]) == -1)
1449 if (
k != input_count)
1451 TRACE(
"Matched IndexGlyphs\n");
1453 for (
k = 0;
k < lookahead_count; ++
k)
1457 glyphs[glyph_index + (dirLookahead * (input_count +
k))]) == -1)
1460 if (
k != lookahead_count)
1462 TRACE(
"Matched LookAhead\n");
1465 for (
k = 0;
k < substitution_count; ++
k)
1469 unsigned int g = glyph_index + write_dir * sequence_index;
1471 if (
g >= *glyph_count)
1473 WARN(
"Skipping invalid sequence index %u (glyph index %u, write dir %d).\n",
1474 sequence_index, glyph_index, write_dir);
1478 TRACE(
"SUBST: %u -> %u %u.\n",
k, sequence_index, lookup_index);
1481 ERR(
"Chain failed to generate a glyph.\n");
1498 TRACE(
"type %#x, flag %#x, subtables %u.\n",
type,
1518 WARN(
"lookup type is Extension Substitution but no extension subtable exists\n");
1536 FIXME(
"Extension Substitution types not valid here\n");
1539 FIXME(
"Unhandled GSUB lookup type %#x.\n",
type);
1545 unsigned int glyph_index,
int write_dir,
int *glyph_count)
1558 unsigned int lookup_index,
const WORD *glyphs,
unsigned int glyph_index,
unsigned int glyph_count,
1563 static const WORD mask[3] = {3,0xf,0xff};
1572 if (format < 1 || format > 3)
1596 TRACE(
"Anchor Format 1\n");
1604 TRACE(
"Anchor Format 2\n");
1613 TRACE(
"Anchor Format 3\n");
1617 TRACE(
"ppem %i\n",ppem);
1641 int desX,
int desY,
double *devX,
double *devY)
1645 TRACE(
"emHeight %i lfWidth %li\n",emHeight, logfont->
lfWidth);
1646 *devX = (desX * emHeight) / (
double)otm->
otmEMSquare;
1647 *devY = (desY * emHeight) / (
double)otm->
otmEMSquare;
1649 FIXME(
"Font with lfWidth set not handled properly.\n");
1667 WORD ValueFormat,
unsigned int ppem,
POINT *ptPlacement,
POINT *ptAdvance)
1669 if (ValueFormat & 0x0001) ptPlacement->
x += (
short)ValueRecord->
XPlacement;
1677 if (ValueFormat & 0xFF00)
FIXME(
"Unhandled Value Format %x\n",ValueFormat&0xFF00);
1700 const WORD *glyphs,
unsigned int glyph_index,
unsigned int glyph_count,
unsigned int ppem,
1705 TRACE(
"Single Adjustment Positioning Subtable\n");
1775 const WORD *glyphs,
unsigned int glyph_index,
unsigned int glyph_count,
unsigned int ppem,
1781 if (glyph_index + write_dir >= glyph_count)
1784 TRACE(
"Pair Adjustment Positioning Subtable\n");
1809 for (
k = 0;
k < pair_count;
k++)
1812 if (glyphs[glyph_index+write_dir] == second_glyph)
1815 TRACE(
"Format 1: Found Pair %x,%x\n",glyphs[glyph_index],glyphs[glyph_index+write_dir]);
1818 if (ValueFormat2)
next++;
1840 WORD class1, class2;
1843 if (class1 < class1_count && class2 < class2_count)
1845 const WORD *pair_val = ppf2->
Class1Record + (class1 * class2_count + class2) * (val_fmt1_size + val_fmt2_size);
1848 TRACE(
"Format 2: Found Pair %x,%x\n", glyphs[glyph_index], glyphs[glyph_index + write_dir] );
1851 if (ValueFormat2)
next++;
1863 const WORD *glyphs,
unsigned int glyph_index,
unsigned int glyph_count,
unsigned int ppem,
POINT *
pt)
1868 if (glyph_index + write_dir >= glyph_count)
1871 TRACE(
"Cursive Attachment Positioning Subtable\n");
1878 int index_exit, index_entry;
1886 POINT exit_pt, entry_pt;
1892 pt->x = entry_pt.
x - exit_pt.
x;
1893 pt->y = entry_pt.
y - exit_pt.
y;
1906 unsigned int glyph_count,
unsigned int ppem,
POINT *
pt)
1910 const void *glyph_class_table =
NULL;
1921 TRACE(
"MarkToBase Attachment Positioning Subtable\n");
1931 if (mark_index != -1)
1934 int base_glyph = glyph_index - write_dir;
1936 if (glyph_class_table)
1939 base_glyph -= write_dir;
1944 if (base_index != -1)
1952 int baserecord_size;
1955 TRACE(
"Mark %x(%i) and base %x(%i)\n",glyphs[glyph_index], mark_index, glyphs[base_glyph], base_index);
1960 ERR(
"Mark index exceeded mark count\n");
1965 TRACE(
"Mark Class %i total classes %i\n",mark_class,class_count);
1968 baserecord_size = class_count *
sizeof(
WORD);
1976 pt->x += base_pt.
x - mark_pt.
x;
1977 pt->y += base_pt.
y - mark_pt.
y;
1990 const WORD *glyphs,
unsigned int glyph_index,
unsigned int glyph_count,
unsigned int ppem,
POINT *
pt)
1995 TRACE(
"MarkToLigature Attachment Positioning Subtable\n");
2005 if (mark_index != -1)
2010 if (ligature_index != -1)
2025 TRACE(
"Mark %x(%i) and ligature %x(%i)\n",glyphs[glyph_index], mark_index, glyphs[glyph_index - write_dir], ligature_index);
2030 ERR(
"Mark index exceeded mark count\n");
2035 TRACE(
"Mark Class %i total classes %i\n",mark_class,class_count);
2040 ERR(
"Ligature index exceeded ligature count\n");
2053 for (
k = 0;
k < class_count && !
offset;
k++)
2059 ERR(
"Failed to find available ligature connection point\n");
2068 pt->x += ligature_pt.
x - mark_pt.
x;
2069 pt->y += ligature_pt.
y - mark_pt.
y;
2080 const WORD *glyphs,
unsigned int glyph_index,
unsigned int glyph_count,
unsigned int ppem,
POINT *
pt)
2086 TRACE(
"MarkToMark Attachment Positioning Subtable\n");
2096 if (mark_index != -1)
2099 unsigned int prev_glyph_index = glyph_index - write_dir;
2100 if (prev_glyph_index >= glyph_count)
2102 TRACE(
"Mark looking outside range\n");
2107 if (mark2_index != -1)
2115 int mark2record_size;
2118 TRACE(
"Mark %x(%i) and Mark2 %x(%i)\n",glyphs[glyph_index], mark_index, glyphs[prev_glyph_index], mark2_index);
2123 ERR(
"Mark index exceeded mark count\n");
2128 TRACE(
"Mark Class %i total classes %i\n",mark_class,class_count);
2131 mark2record_size = class_count *
sizeof(
WORD);
2139 pt->x += mark2_pt.
x - mark_pt.
x;
2140 pt->y += mark2_pt.
y - mark_pt.
y;
2154 const OT_LookupTable *look,
const WORD *glyphs,
unsigned int glyph_index,
unsigned int glyph_count,
2160 TRACE(
"Contextual Positioning Subtable\n");
2170 FIXME(
" TODO: subtype 1\n");
2178 TRACE(
"Contextual Positioning Subtable: Format 2\n");
2186 const void *glyph_class_table =
NULL;
2189 glyph_class_table = (
const BYTE *)cpf2 +
offset;
2196 TRACE(
"No class rule table for class %i\n",
class);
2212 TRACE(
"PosClassRule has %i glyphs classes\n",g_count);
2214 g = glyph_index + write_dir * (g_count - 1);
2215 if (
g >= glyph_count)
2218 for (
l = 0;
l < g_count-1;
l++)
2220 g = glyph_index + (write_dir * (
l+1));
2221 if (
g < glyph_count)
2230 TRACE(
"Rule does not match\n");
2234 TRACE(
"Rule matches\n");
2242 g = glyph_index + write_dir * sequence_index;
2243 if (
g >= glyph_count)
2245 WARN(
"Invalid sequence index %u (glyph index %u, write dir %d).\n",
2246 sequence_index, glyph_index, write_dir);
2250 TRACE(
"Position: %u -> %u %u.\n",
l, sequence_index, lookup_index);
2253 lookup, lookup_index, glyphs,
g, glyph_count, goffset);
2259 TRACE(
"Not covered\n");
2266 FIXME(
" TODO: subtype 3\n");
2277 const OT_LookupTable *look,
const WORD *glyphs,
unsigned int glyph_index,
unsigned int glyph_count,
2283 TRACE(
"Chaining Contextual Positioning Subtable\n");
2289 int dirLookahead = write_dir;
2290 int dirBacktrack = -1 * write_dir;
2296 FIXME(
" TODO: subtype 1 (Simple Chaining Context Glyph Positioning)\n");
2303 FIXME(
" TODO: subtype 2 (Class-based Chaining Context Glyph Positioning)\n");
2308 WORD backtrack_count, input_count, lookahead_count, positioning_count;
2314 TRACE(
" subtype 3 (Coverage-based Chaining Context Glyph Positioning)\n");
2317 k = glyph_index + dirBacktrack * backtrack_count;
2318 if (k < 0 || k >= glyph_count)
2323 k = glyph_index + write_dir * (input_count - 1);
2324 if (k < 0 || k >= glyph_count)
2329 k = glyph_index + dirLookahead * (input_count + lookahead_count - 1);
2330 if (k < 0 || k >= glyph_count)
2335 for (
k = 0;
k < backtrack_count; ++
k)
2337 unsigned int prev_glyph_index;
2339 prev_glyph_index = glyph_index + (dirBacktrack * (
k + 1));
2340 if (prev_glyph_index >= glyph_count)
2345 if (
k != backtrack_count)
2347 TRACE(
"Matched Backtrack\n");
2349 for (
k = 0;
k < input_count; ++
k)
2351 unsigned int next_glyph_index = glyph_index + (write_dir *
k);
2352 if (next_glyph_index >= glyph_count)
2356 glyphs[next_glyph_index]) == -1)
2359 if (
k != input_count)
2361 TRACE(
"Matched IndexGlyphs\n");
2363 for (
k = 0;
k < lookahead_count; ++
k)
2365 unsigned int next_glyph_index = glyph_index + (dirLookahead * (input_count +
k));
2366 if (next_glyph_index >= glyph_count)
2370 glyphs[next_glyph_index]) == -1)
2373 if (
k != lookahead_count)
2375 TRACE(
"Matched LookAhead\n");
2380 for (
k = 0;
k < positioning_count; ++
k)
2384 unsigned int g = glyph_index + write_dir * sequence_index;
2386 if (
g >= glyph_count)
2388 WARN(
"Skipping invalid sequence index %u (glyph index %u, write dir %d).\n",
2389 sequence_index, glyph_index, write_dir);
2393 TRACE(
"Position: %u -> %u %u.\n",
k, sequence_index, lookup_index);
2395 glyphs,
g, glyph_count, goffset);
2397 return input_count + lookahead_count;
2407 unsigned int lookup_index,
const WORD *glyphs,
unsigned int glyph_index,
unsigned int glyph_count,
2418 TRACE(
"type %#x, flag %#x, subtables %u.\n",
type,
2438 WARN(
"lookup type is Extension Positioning but no extension subtable exists\n");
2446 POINT adjust = {0,0};
2449 if (adjust.
x || adjust.
y)
2452 pGoffset[glyph_index].
du +=
round(devX);
2453 pGoffset[glyph_index].
dv +=
round(devY);
2458 piAdvance[glyph_index] +=
round(devX);
2460 FIXME(
"Unhandled adjustment to Y advancement\n");
2468 POINT adjust[2]= {{0,0},{0,0}};
2473 unsigned int next_glyph_index = glyph_index + write_dir;
2474 if (next_glyph_index >= glyph_count)
2476 WARN(
"Skipping invalid glyph index %u, write dir %d.\n", glyph_index, write_dir);
2481 glyph_index, glyph_count, ppem, adjust,
advance);
2482 if (adjust[0].
x || adjust[0].
y)
2485 pGoffset[glyph_index].
du +=
round(devX) * offset_sign;
2486 pGoffset[glyph_index].
dv +=
round(devY);
2491 piAdvance[glyph_index] +=
round(devX);
2493 if (adjust[1].
x || adjust[1].
y)
2496 pGoffset[next_glyph_index].
du +=
round(devX) * offset_sign;
2497 pGoffset[next_glyph_index].
dv +=
round(devY);
2502 piAdvance[next_glyph_index] +=
round(devX);
2504 return index_offset;
2512 unsigned int next_glyph_index = glyph_index + write_dir;
2513 if (next_glyph_index >= glyph_count)
2515 WARN(
"Skipping invalid glyph index %u, write dir %d.\n", glyph_index, write_dir);
2520 if (desU.
x || desU.
y)
2524 pGoffset[glyph_index].
dv =
round(devY) + pGoffset[next_glyph_index].
dv;
2534 glyphs, glyph_index, glyph_count, ppem, &desU);
2535 if (base_index != -1)
2538 if (!analysis->
fRTL) pGoffset[glyph_index].
du =
round(devX) - piAdvance[base_index];
2542 pGoffset[glyph_index].
du =
round(devX);
2544 pGoffset[glyph_index].
dv =
round(devY);
2554 if (desU.
x || desU.
y)
2557 pGoffset[glyph_index].
du = (
round(devX) - piAdvance[glyph_index-1]);
2558 pGoffset[glyph_index].
dv =
round(devY);
2568 unsigned int prev_glyph_index = glyph_index - write_dir;
2569 if (prev_glyph_index >= glyph_count)
2571 WARN(
"Skipping invalid glyph index %u, write dir %d.\n", glyph_index, write_dir);
2579 pGoffset[glyph_index].
du =
round(devX) + pGoffset[prev_glyph_index].
du;
2580 pGoffset[glyph_index].
dv =
round(devY) + pGoffset[prev_glyph_index].
dv;
2587 lookup, look, glyphs, glyph_index, glyph_count, pGoffset);
2591 lookup, look, glyphs, glyph_index, glyph_count, pGoffset);
2594 FIXME(
"Unhandled GPOS lookup type %#x.\n",
type);
2601 const WORD *glyphs,
unsigned int glyph_index,
unsigned int glyph_count,
GOFFSET *goffset)
2607 lookup_index, glyphs, glyph_index, glyph_count, goffset);
2617 ERR(
"Failed to grow scripts array.\n");
2647 TRACE(
"script_cache %p, table %#x, list %p.\n", script_cache,
table,
list);
2658 list->ScriptRecord[
i].ScriptTag[1],
2659 list->ScriptRecord[
i].ScriptTag[2],
2660 list->ScriptRecord[
i].ScriptTag[3]);
2678 if ((gsub_header = script_cache->
GSUB_Table))
2682 if ((gpos_header = script_cache->
GPOS_Table))
2704 *pScriptTags =
script->tag;
2709 if (cMaxTags < *pcTags)
2713 for (
i = 0;
i < cMaxTags; ++
i)
2725 script->language_count + 1,
sizeof(*
script->languages)))
2727 ERR(
"Failed to grow languages array.\n");
2731 language = &
script->languages[
script->language_count++];
2741 for (
i = 0;
i <
script->language_count; ++
i)
2772 initial_count =
script->language_count;
2776 list->LangSysRecord[
i].LangSysTag[1],
2777 list->LangSysRecord[
i].LangSysTag[2],
2778 list->LangSysRecord[
i].LangSysTag[3]);
2792 if (
script->languages_initialized)
2815 if (!searchingFor && cMaxTags < script->language_count)
2817 else if (searchingFor)
2820 *pcTags =
script->language_count;
2822 for (
i = 0;
i <
script->language_count;
i++)
2825 pLanguageTags[
i] =
script->languages[
i].tag;
2829 if (searchingFor ==
script->languages[
i].tag)
2831 pLanguageTags[0] =
script->languages[
i].tag;
2842 pLanguageTags[
i] =
script->default_language.tag;
2844 if (searchingFor &&
FAILED(rc))
2846 pLanguageTags[0] =
script->default_language.tag;
2849 *pcTags = (*pcTags) + 1;
2861 TRACE(
"table_type %#x, %u features.\n", table_type,
count);
2933 language = &
script->default_language;
2951 *pcTags = (*pcTags)+1;
2956 if (!searchingFor && cMaxTags < *pcTags)
2958 else if (searchingFor)
static VOID Substitute(_Out_writes_bytes_(BufferSize) PWCHAR Buffer, _In_ ULONG BufferSize, _In_ PCWSTR Template, _In_ PCWSTR SystemDriveName, _In_ PCWSTR SystemRootName)
_STLP_MOVE_TO_STD_NAMESPACE void _STLP_CALL advance(_InputIterator &__i, _Distance __n)
struct outqueuenode * head
static const char * wine_dbgstr_point(const POINT *ppt)
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
void ls(int argc, const char *argv[])
unsigned int component_count
unsigned int component_size
static const WCHAR *const ext[]
#define MS_MAKE_TAG(ch0, ch1, ch2, ch3)
static void Lookup(RTF_Info *, char *)
BOOL usp10_array_reserve(void **elements, SIZE_T *capacity, SIZE_T count, SIZE_T size)
int USP10_FindGlyphInLogClust(const WORD *pwLogClust, int cChars, WORD target)
unsigned short(__cdecl typeof(TIFFCurrentDirectory))(struct tiff *)
static const uint32_t k[]
struct nls_table * tables
GLint GLint GLint GLint GLint x
GLuint GLuint GLsizei count
GLuint GLuint GLsizei GLenum type
GLint GLint GLint GLint GLint GLint y
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
GLdouble GLdouble GLdouble GLdouble top
GLboolean GLboolean GLboolean b
GLuint GLsizei GLsizei * length
GLboolean GLboolean GLboolean GLboolean a
GLenum GLenum GLenum input
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
ROSDATA LIGATURE2 Ligature[]
#define memmove(s1, s2, n)
INTERNETFEATURELIST feature
for(i=0;i< sizeof(testsuite)/sizeof(testsuite[0]);++i) ok(call_test(testsuite[i].func)
GPOS_PosLookupRecord PosLookupRecord[1]
GPOS_ComponentRecord ComponentRecord[1]
GPOS_MarkRecord MarkRecord[1]
GPOS_PairValueRecord PairValueRecord[1]
GPOS_PosLookupRecord PosLookupRecord[1]
WORD ChainSubRuleSetCount
GSUB_SubstLookupRecord SubstLookupRecord[1]
GSUB_SubstLookupRecord SubstLookupRecord[1]
WORD ChainSubClassRule[1]
WORD ChainSubClassRuleCnt
GSUB_SubstLookupRecord SubstLookupRecord[1]
GSUB_SubstLookupRecord SubstLookupRecord[1]
BOOL features_initialized
const void * table[USP10_LANGUAGE_TABLE_COUNT]
OT_FeatureRecord FeatureRecord[1]
void * CMAP_format12_Table
TEXTMETRICW otmTextMetrics
PSYMCRYPT_PARALLEL_HASH_OPERATION next
#define USP_E_SCRIPT_NOT_IN_FONT
#define FEATURE_GSUB_TABLE
@ USP10_LANGUAGE_TABLE_GSUB
@ USP10_LANGUAGE_TABLE_GPOS
#define FEATURE_GPOS_TABLE
@ USP10_SCRIPT_TABLE_GSUB
@ USP10_SCRIPT_TABLE_GPOS
static const WCHAR lang[]
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
static int GSUB_is_glyph_covered(const void *table, unsigned int glyph)
static void GPOS_apply_SingleAdjustment(const OT_LookupTable *look, const SCRIPT_ANALYSIS *analysis, const WORD *glyphs, unsigned int glyph_index, unsigned int glyph_count, unsigned int ppem, POINT *adjust, POINT *advance)
static INT GSUB_apply_ContextSubst(const OT_LookupList *lookup, const OT_LookupTable *look, WORD *glyphs, INT glyph_index, INT write_dir, INT *glyph_count)
static void apply_pair_value(const void *pos_table, WORD val_fmt1, WORD val_fmt2, const WORD *pair, INT ppem, POINT *adjust, POINT *advance)
static void usp10_language_add_feature_list(LoadedLanguage *language, char table_type, const OT_LangSys *lang, const OT_FeatureList *feature_list)
@ GPOS_LOOKUP_POSITION_CONTEXT_CHAINED
@ GPOS_LOOKUP_ATTACH_MARK_TO_LIGATURE
@ GPOS_LOOKUP_ADJUST_SINGLE
@ GPOS_LOOKUP_ADJUST_PAIR
@ GPOS_LOOKUP_ATTACH_MARK_TO_BASE
@ GPOS_LOOKUP_POSITION_EXTENSION
@ GPOS_LOOKUP_ATTACH_MARK_TO_MARK
@ GPOS_LOOKUP_ATTACH_CURSIVE
@ GPOS_LOOKUP_POSITION_CONTEXT
static int GPOS_apply_PairAdjustment(const OT_LookupTable *look, const SCRIPT_ANALYSIS *analysis, const WORD *glyphs, unsigned int glyph_index, unsigned int glyph_count, unsigned int ppem, POINT *adjust, POINT *advance)
HRESULT OpenType_GetFontFeatureTags(ScriptCache *psc, OPENTYPE_TAG script_tag, OPENTYPE_TAG language_tag, BOOL filtered, OPENTYPE_TAG searchingFor, char tableType, int cMaxTags, OPENTYPE_TAG *pFeatureTags, int *pcTags, LoadedFeature **feature)
static INT GSUB_apply_ChainContextSubst(const OT_LookupList *lookup, const OT_LookupTable *look, WORD *glyphs, INT glyph_index, INT write_dir, INT *glyph_count)
static void _initialize_script_cache(ScriptCache *script_cache)
HRESULT OpenType_GetFontLanguageTags(ScriptCache *psc, OPENTYPE_TAG script_tag, OPENTYPE_TAG searchingFor, int cMaxTags, OPENTYPE_TAG *pLanguageTags, int *pcTags)
static void _initialize_language_cache(LoadedScript *script)
static LoadedLanguage * usp10_script_add_language(LoadedScript *script, OPENTYPE_TAG tag)
static INT GPOS_get_value_record(WORD ValueFormat, const WORD data[], GPOS_ValueRecord *record)
static unsigned int GPOS_apply_ChainContextPos(const ScriptCache *script_cache, const OUTLINETEXTMETRICW *otm, const LOGFONTW *logfont, const SCRIPT_ANALYSIS *analysis, int *advance, const OT_LookupList *lookup, const OT_LookupTable *look, const WORD *glyphs, unsigned int glyph_index, unsigned int glyph_count, GOFFSET *goffset)
static void GPOS_apply_CursiveAttachment(const OT_LookupTable *look, const SCRIPT_ANALYSIS *analysis, const WORD *glyphs, unsigned int glyph_index, unsigned int glyph_count, unsigned int ppem, POINT *pt)
static INT GSUB_apply_LigatureSubst(const OT_LookupTable *look, WORD *glyphs, INT glyph_index, INT write_dir, INT *glyph_count)
static WORD OT_get_glyph_class(const void *table, WORD glyph)
static void usp10_script_add_language_list(LoadedScript *script, enum usp10_language_table table, const OT_Script *list)
static void usp10_script_cache_add_script_list(ScriptCache *script_cache, enum usp10_script_table table, const OT_ScriptList *list)
static const BYTE * GSUB_get_subtable(const OT_LookupTable *look, int index)
static INT GSUB_apply_SingleSubst(const OT_LookupTable *look, WORD *glyphs, INT glyph_index, INT write_dir, INT *glyph_count)
@ GSUB_LOOKUP_CONTEXT_CHAINED_REVERSE
@ GSUB_LOOKUP_CONTEXT_CHAINED
static int GPOS_apply_MarkToBase(const ScriptCache *script_cache, const OT_LookupTable *look, const SCRIPT_ANALYSIS *analysis, const WORD *glyphs, unsigned int glyph_index, unsigned int glyph_count, unsigned int ppem, POINT *pt)
static LoadedScript * usp10_script_cache_get_script(ScriptCache *script_cache, OPENTYPE_TAG tag)
static void GPOS_convert_design_units_to_device(const OUTLINETEXTMETRICW *otm, const LOGFONTW *logfont, int desX, int desY, double *devX, double *devY)
static void GPOS_apply_MarkToLigature(const OT_LookupTable *look, const SCRIPT_ANALYSIS *analysis, const WORD *glyphs, unsigned int glyph_index, unsigned int glyph_count, unsigned int ppem, POINT *pt)
unsigned int OpenType_apply_GPOS_lookup(const ScriptCache *script_cache, const OUTLINETEXTMETRICW *otm, const LOGFONTW *logfont, const SCRIPT_ANALYSIS *analysis, int *advance, unsigned int lookup_index, const WORD *glyphs, unsigned int glyph_index, unsigned int glyph_count, GOFFSET *goffset)
static void GPOS_get_anchor_values(const void *table, POINT *pt, WORD ppem)
static unsigned int GPOS_apply_lookup(const ScriptCache *script_cache, const OUTLINETEXTMETRICW *otm, const LOGFONTW *logfont, const SCRIPT_ANALYSIS *analysis, int *advance, const OT_LookupList *lookup, unsigned int lookup_index, const WORD *glyphs, unsigned int glyph_index, unsigned int glyph_count, GOFFSET *goffset)
static INT GSUB_apply_lookup(const OT_LookupList *lookup, INT lookup_index, WORD *glyphs, INT glyph_index, INT write_dir, INT *glyph_count)
static BOOL GPOS_apply_MarkToMark(const OT_LookupTable *look, const SCRIPT_ANALYSIS *analysis, const WORD *glyphs, unsigned int glyph_index, unsigned int glyph_count, unsigned int ppem, POINT *pt)
static void _initialize_feature_cache(ScriptCache *psc, LoadedLanguage *language)
void OpenType_GDEF_UpdateGlyphProps(ScriptCache *psc, const WORD *pwGlyphs, const WORD cGlyphs, WORD *pwLogClust, const WORD cChars, SCRIPT_GLYPHPROP *pGlyphProp)
static void GPOS_get_value_record_offsets(const BYTE *head, GPOS_ValueRecord *ValueRecord, WORD ValueFormat, unsigned int ppem, POINT *ptPlacement, POINT *ptAdvance)
static INT GSUB_apply_MultipleSubst(const OT_LookupTable *look, WORD *glyphs, INT glyph_index, INT write_dir, INT *glyph_count)
static VOID * load_CMAP_format12_table(HDC hdc, ScriptCache *psc)
DWORD OpenType_CMAP_GetGlyphIndex(HDC hdc, ScriptCache *psc, DWORD utf32c, WORD *glyph_index, DWORD flags)
static LoadedLanguage * usp10_script_get_language(LoadedScript *script, OPENTYPE_TAG tag)
static INT GSUB_apply_AlternateSubst(const OT_LookupTable *look, WORD *glyphs, INT glyph_index, INT write_dir, INT *glyph_count)
static LoadedScript * usp10_script_cache_add_script(ScriptCache *script_cache, OPENTYPE_TAG tag)
static const BYTE * GPOS_get_subtable(const OT_LookupTable *look, int index)
int OpenType_apply_GSUB_lookup(const void *table, unsigned int lookup_index, WORD *glyphs, unsigned int glyph_index, int write_dir, int *glyph_count)
HRESULT OpenType_GetFontScriptTags(ScriptCache *psc, OPENTYPE_TAG searchingFor, int cMaxTags, OPENTYPE_TAG *pScriptTags, int *pcTags)
static unsigned int GPOS_apply_ContextPos(const ScriptCache *script_cache, const OUTLINETEXTMETRICW *otm, const LOGFONTW *logfont, const SCRIPT_ANALYSIS *analysis, int *advance, const OT_LookupList *lookup, const OT_LookupTable *look, const WORD *glyphs, unsigned int glyph_index, unsigned int glyph_count, GOFFSET *goffset)
static int __cdecl compare_group(const void *a, const void *b)
static INT GPOS_get_device_table_value(const OT_DeviceTable *DeviceTable, WORD ppem)
_In_ FONTOBJ _In_ ULONG _In_ ULONG cGlyphs
#define NtGdiGetGlyphIndicesW(A, B, C, D, E)
#define NtGdiGetFontData(A, B, C, D, E)
#define GGI_MARK_NONEXISTING_GLYPHS