usp10: Check font for required features and report error if missing.

This commit is contained in:
Aric Stewart 2010-09-09 15:27:57 -05:00 committed by Alexandre Julliard
parent 29d2c5a208
commit 7bf4db877a
3 changed files with 79 additions and 25 deletions

View File

@ -273,6 +273,15 @@ static OPENTYPE_FEATURE_RECORD arabic_features[] =
{ 0x7465736d /*mset*/, 1},
};
static const char* required_arabic_features[] =
{
"fina",
"init",
"medi",
"rlig",
NULL
};
static OPENTYPE_FEATURE_RECORD hebrew_features[] =
{
{ 0x67696c64 /*dlig*/, 1},
@ -286,6 +295,18 @@ static OPENTYPE_FEATURE_RECORD syriac_features[] =
{ 0x67696c64 /*dlig*/, 1},
};
static const char* required_syriac_features[] =
{
"fina",
"fin2",
"fin3",
"init",
"medi",
"med2",
"rlig",
NULL
};
static OPENTYPE_FEATURE_RECORD sinhala_features[] =
{
/* Base forms */
@ -310,8 +331,15 @@ static OPENTYPE_FEATURE_RECORD thai_features[] =
{ 0x706d6363 /*ccmp*/, 1},
};
static const char* required_lao_features[] =
{
"ccmp",
NULL
};
typedef struct ScriptShapeDataTag {
TEXTRANGE_PROPERTIES defaultTextRange;
const char** requiredFeatures;
CHAR otTag[5];
ContextualShapingProc contextProc;
} ScriptShapeData;
@ -319,30 +347,30 @@ typedef struct ScriptShapeDataTag {
/* in order of scripts */
static const ScriptShapeData ShapingData[] =
{
{{ standard_features, 2}, "", NULL},
{{ standard_features, 2}, "latn", NULL},
{{ standard_features, 2}, "latn", NULL},
{{ standard_features, 2}, "latn", NULL},
{{ standard_features, 2}, "" , NULL},
{{ standard_features, 2}, "latn", NULL},
{{ arabic_features, 6}, "arab", ContextualShape_Arabic},
{{ arabic_features, 6}, "arab", ContextualShape_Arabic},
{{ hebrew_features, 1}, "hebr", NULL},
{{ syriac_features, 4}, "syrc", ContextualShape_Syriac},
{{ arabic_features, 6}, "arab", ContextualShape_Arabic},
{{ NULL, 0}, "thaa", NULL},
{{ standard_features, 2}, "grek", NULL},
{{ standard_features, 2}, "cyrl", NULL},
{{ standard_features, 2}, "armn", NULL},
{{ standard_features, 2}, "geor", NULL},
{{ sinhala_features, 7}, "sinh", NULL},
{{ tibetan_features, 2}, "tibt", NULL},
{{ tibetan_features, 2}, "tibt", NULL},
{{ tibetan_features, 2}, "phag", ContextualShape_Phags_pa},
{{ thai_features, 1}, "thai", NULL},
{{ thai_features, 1}, "thai", NULL},
{{ thai_features, 1}, "lao", NULL},
{{ thai_features, 1}, "lao", NULL},
{{ standard_features, 2}, NULL, "", NULL},
{{ standard_features, 2}, NULL, "latn", NULL},
{{ standard_features, 2}, NULL, "latn", NULL},
{{ standard_features, 2}, NULL, "latn", NULL},
{{ standard_features, 2}, NULL, "" , NULL},
{{ standard_features, 2}, NULL, "latn", NULL},
{{ arabic_features, 6}, required_arabic_features, "arab", ContextualShape_Arabic},
{{ arabic_features, 6}, required_arabic_features, "arab", ContextualShape_Arabic},
{{ hebrew_features, 1}, NULL, "hebr", NULL},
{{ syriac_features, 4}, required_syriac_features, "syrc", ContextualShape_Syriac},
{{ arabic_features, 6}, required_arabic_features, "arab", ContextualShape_Arabic},
{{ NULL, 0}, NULL, "thaa", NULL},
{{ standard_features, 2}, NULL, "grek", NULL},
{{ standard_features, 2}, NULL, "cyrl", NULL},
{{ standard_features, 2}, NULL, "armn", NULL},
{{ standard_features, 2}, NULL, "geor", NULL},
{{ sinhala_features, 7}, NULL, "sinh", NULL},
{{ tibetan_features, 2}, NULL, "tibt", NULL},
{{ tibetan_features, 2}, NULL, "tibt", NULL},
{{ tibetan_features, 2}, NULL, "phag", ContextualShape_Phags_pa},
{{ thai_features, 1}, NULL, "thai", NULL},
{{ thai_features, 1}, NULL, "thai", NULL},
{{ thai_features, 1}, required_lao_features, "lao", NULL},
{{ thai_features, 1}, required_lao_features, "lao", NULL},
};
static INT GSUB_is_glyph_covered(LPCVOID table , UINT glyph)
@ -1308,3 +1336,25 @@ rpRangeProperties = &ShapingData[psa->eScript].defaultTextRange;
SHAPE_ApplyOpenTypeFeatures(hdc, psc, psa, pwOutGlyphs, pcGlyphs, cMaxGlyphs, cChars, rpRangeProperties, pwLogClust);
}
HRESULT SHAPE_CheckFontForRequiredFeatures(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa)
{
const GSUB_Feature *feature;
int i;
if (!ShapingData[psa->eScript].requiredFeatures)
return S_OK;
if (!psc->GSUB_Table)
psc->GSUB_Table = load_gsub_table(hdc);
i = 0;
while (ShapingData[psa->eScript].requiredFeatures[i])
{
feature = load_GSUB_feature(hdc, psa, psc, ShapingData[psa->eScript].requiredFeatures[i]);
if (!feature)
return USP_E_SCRIPT_NOT_IN_FONT;
i++;
}
return S_OK;
}

View File

@ -1290,7 +1290,10 @@ HRESULT WINAPI ScriptShape(HDC hdc, SCRIPT_CACHE *psc, const WCHAR *pwcChars,
if (!psa->fNoGlyphIndex)
{
WCHAR *rChars = heap_alloc(sizeof(WCHAR) * cChars);
WCHAR *rChars;
if ((hr = SHAPE_CheckFontForRequiredFeatures(hdc, (ScriptCache *)*psc, psa)) != S_OK) return hr;
rChars = heap_alloc(sizeof(WCHAR) * cChars);
if (!rChars) return E_OUTOFMEMORY;
for (i = 0; i < cChars; i++)
{

View File

@ -75,3 +75,4 @@ INT BIDI_ReorderV2lLevel(int level, int *pIndexs, const BYTE* plevel, int cch, B
INT BIDI_ReorderL2vLevel(int level, int *pIndexs, const BYTE* plevel, int cch, BOOL fReverse);
void SHAPE_ContextualShaping(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, WCHAR* pwcChars, INT cChars, WORD* pwOutGlyphs, INT* pcGlyphs, INT cMaxGlyphs, WORD *pwLogClust);
void SHAPE_ApplyDefaultOpentypeFeatures(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, WORD* pwOutGlyphs, INT* pcGlyphs, INT cMaxGlyphs, INT cChars, WORD *pwLogClust);
HRESULT SHAPE_CheckFontForRequiredFeatures(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa);