mirror of
https://github.com/reactos/wine.git
synced 2024-11-29 22:50:43 +00:00
usp10: Use the font GDEF table to update glyph properties.
This commit is contained in:
parent
c7e42c05a5
commit
8e8d4be5a4
@ -241,6 +241,38 @@ typedef struct{
|
||||
WORD Alternate[1];
|
||||
} GSUB_AlternateSet;
|
||||
|
||||
/* These are all structures needed for the GDEF table */
|
||||
#define GDEF_TAG MS_MAKE_TAG('G', 'D', 'E', 'F')
|
||||
|
||||
enum {BaseGlyph=1, LigatureGlyph, MarkGlyph, ComponentGlyph};
|
||||
|
||||
typedef struct {
|
||||
DWORD Version;
|
||||
WORD GlyphClassDef;
|
||||
WORD AttachList;
|
||||
WORD LigCaretList;
|
||||
WORD MarkAttachClassDef;
|
||||
} GDEF_Header;
|
||||
|
||||
typedef struct {
|
||||
WORD ClassFormat;
|
||||
WORD StartGlyph;
|
||||
WORD GlyphCount;
|
||||
WORD ClassValueArray[1];
|
||||
} GDEF_ClassDefFormat1;
|
||||
|
||||
typedef struct {
|
||||
WORD Start;
|
||||
WORD End;
|
||||
WORD Class;
|
||||
} GDEF_ClassRangeRecord;
|
||||
|
||||
typedef struct {
|
||||
WORD ClassFormat;
|
||||
WORD ClassRangeCount;
|
||||
GDEF_ClassRangeRecord ClassRangeRecord[1];
|
||||
} GDEF_ClassDefFormat2;
|
||||
|
||||
static INT GSUB_apply_lookup(const GSUB_LookupList* lookup, INT lookup_index, WORD *glyphs, INT glyph_index, INT write_dir, INT *glyph_count);
|
||||
|
||||
/* the orders of joined_forms and contextual_features need to line up */
|
||||
@ -894,6 +926,106 @@ static VOID *load_gsub_table(HDC hdc)
|
||||
return GSUB_Table;
|
||||
}
|
||||
|
||||
static WORD GDEF_get_glyph_class(const GDEF_Header *header, WORD glyph)
|
||||
{
|
||||
int offset;
|
||||
WORD class = 0;
|
||||
const GDEF_ClassDefFormat1 *cf1;
|
||||
|
||||
if (!header)
|
||||
return 0;
|
||||
|
||||
offset = GET_BE_WORD(header->GlyphClassDef);
|
||||
if (!offset)
|
||||
return 0;
|
||||
|
||||
cf1 = (GDEF_ClassDefFormat1*)(((BYTE*)header)+offset);
|
||||
if (GET_BE_WORD(cf1->ClassFormat) == 1)
|
||||
{
|
||||
if (glyph >= GET_BE_WORD(cf1->StartGlyph))
|
||||
{
|
||||
int index = glyph - GET_BE_WORD(cf1->StartGlyph);
|
||||
if (index < GET_BE_WORD(cf1->GlyphCount))
|
||||
class = GET_BE_WORD(cf1->ClassValueArray[index]);
|
||||
}
|
||||
}
|
||||
else if (GET_BE_WORD(cf1->ClassFormat) == 2)
|
||||
{
|
||||
const GDEF_ClassDefFormat2 *cf2 = (GDEF_ClassDefFormat2*)cf1;
|
||||
int i, top;
|
||||
top = GET_BE_WORD(cf2->ClassRangeCount);
|
||||
for (i = 0; i < top; i++)
|
||||
{
|
||||
if (glyph >= GET_BE_WORD(cf2->ClassRangeRecord[i].Start) &&
|
||||
glyph <= GET_BE_WORD(cf2->ClassRangeRecord[i].End))
|
||||
{
|
||||
class = GET_BE_WORD(cf2->ClassRangeRecord[i].Class);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
ERR("Unknown Class Format %i\n",GET_BE_WORD(cf1->ClassFormat));
|
||||
|
||||
return class;
|
||||
}
|
||||
|
||||
static VOID *load_gdef_table(HDC hdc)
|
||||
{
|
||||
VOID* GDEF_Table = NULL;
|
||||
int length = GetFontData(hdc, GDEF_TAG , 0, NULL, 0);
|
||||
if (length != GDI_ERROR)
|
||||
{
|
||||
GDEF_Table = HeapAlloc(GetProcessHeap(),0,length);
|
||||
GetFontData(hdc, GDEF_TAG , 0, GDEF_Table, length);
|
||||
TRACE("Loaded GDEF table of %i bytes\n",length);
|
||||
}
|
||||
return GDEF_Table;
|
||||
}
|
||||
|
||||
static void GDEF_UpdateGlyphProps(HDC hdc, const WORD *pwGlyphs, const WORD cGlyphs, WORD* pwLogClust, SCRIPT_GLYPHPROP *pGlyphProp)
|
||||
{
|
||||
VOID* header = load_gdef_table(hdc);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < cGlyphs; i++)
|
||||
{
|
||||
WORD class;
|
||||
|
||||
class = GDEF_get_glyph_class(header, pwGlyphs[i]);
|
||||
|
||||
switch (class)
|
||||
{
|
||||
case 0:
|
||||
case BaseGlyph:
|
||||
pGlyphProp[i].sva.fClusterStart = 1;
|
||||
pGlyphProp[i].sva.fDiacritic = 0;
|
||||
pGlyphProp[i].sva.fZeroWidth = 0;
|
||||
break;
|
||||
case LigatureGlyph:
|
||||
pGlyphProp[i].sva.fClusterStart = 1;
|
||||
pGlyphProp[i].sva.fDiacritic = 0;
|
||||
pGlyphProp[i].sva.fZeroWidth = 0;
|
||||
break;
|
||||
case MarkGlyph:
|
||||
pGlyphProp[i].sva.fClusterStart = 0;
|
||||
pGlyphProp[i].sva.fDiacritic = 1;
|
||||
pGlyphProp[i].sva.fZeroWidth = 1;
|
||||
break;
|
||||
case ComponentGlyph:
|
||||
pGlyphProp[i].sva.fClusterStart = 0;
|
||||
pGlyphProp[i].sva.fDiacritic = 0;
|
||||
pGlyphProp[i].sva.fZeroWidth = 0;
|
||||
break;
|
||||
default:
|
||||
ERR("Unknown glyph class %i\n",class);
|
||||
pGlyphProp[i].sva.fClusterStart = 1;
|
||||
pGlyphProp[i].sva.fDiacritic = 0;
|
||||
pGlyphProp[i].sva.fZeroWidth = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void UpdateClusters(int nextIndex, int changeCount, int write_dir, int chars, WORD* pwLogClust )
|
||||
{
|
||||
if (changeCount == 0)
|
||||
@ -1351,6 +1483,8 @@ static void ShapeCharGlyphProp_Default( HDC hdc, ScriptCache* psc, SCRIPT_ANALYS
|
||||
else
|
||||
pGlyphProp[i].sva.uJustification = SCRIPT_JUSTIFY_CHARACTER;
|
||||
}
|
||||
|
||||
GDEF_UpdateGlyphProps(hdc, pwGlyphs, cGlyphs, pwLogClust, pGlyphProp);
|
||||
}
|
||||
|
||||
void SHAPE_CharGlyphProp(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, const WCHAR* pwcChars, const INT cChars, const WORD* pwGlyphs, const INT cGlyphs, WORD *pwLogClust, SCRIPT_CHARPROP *pCharProp, SCRIPT_GLYPHPROP *pGlyphProp)
|
||||
|
Loading…
Reference in New Issue
Block a user