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];
|
WORD Alternate[1];
|
||||||
} GSUB_AlternateSet;
|
} 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);
|
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 */
|
/* 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;
|
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 )
|
static void UpdateClusters(int nextIndex, int changeCount, int write_dir, int chars, WORD* pwLogClust )
|
||||||
{
|
{
|
||||||
if (changeCount == 0)
|
if (changeCount == 0)
|
||||||
|
@ -1351,6 +1483,8 @@ static void ShapeCharGlyphProp_Default( HDC hdc, ScriptCache* psc, SCRIPT_ANALYS
|
||||||
else
|
else
|
||||||
pGlyphProp[i].sva.uJustification = SCRIPT_JUSTIFY_CHARACTER;
|
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)
|
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