mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 921858 - distinguish space features in default features from those in non-default features. r=jfkthame
This commit is contained in:
parent
753d90ac34
commit
9209c56b9d
@ -104,7 +104,6 @@ gfxFontEntry::gfxFontEntry() :
|
||||
mHasSpaceFeatures(false),
|
||||
mHasSpaceFeaturesKerning(false),
|
||||
mHasSpaceFeaturesNonKerning(false),
|
||||
mHasSpaceFeaturesSubDefault(false),
|
||||
mCheckedForGraphiteTables(false),
|
||||
mHasCmapTable(false),
|
||||
mGrFaceInitialized(false),
|
||||
@ -116,6 +115,8 @@ gfxFontEntry::gfxFontEntry() :
|
||||
mGrFace(nullptr),
|
||||
mGrFaceRefCnt(0)
|
||||
{
|
||||
memset(&mDefaultSubSpaceFeatures, 0, sizeof(mDefaultSubSpaceFeatures));
|
||||
memset(&mNonDefaultSubSpaceFeatures, 0, sizeof(mNonDefaultSubSpaceFeatures));
|
||||
}
|
||||
|
||||
gfxFontEntry::gfxFontEntry(const nsAString& aName, bool aIsStandardFace) :
|
||||
@ -131,7 +132,6 @@ gfxFontEntry::gfxFontEntry(const nsAString& aName, bool aIsStandardFace) :
|
||||
mHasSpaceFeatures(false),
|
||||
mHasSpaceFeaturesKerning(false),
|
||||
mHasSpaceFeaturesNonKerning(false),
|
||||
mHasSpaceFeaturesSubDefault(false),
|
||||
mCheckedForGraphiteTables(false),
|
||||
mHasCmapTable(false),
|
||||
mGrFaceInitialized(false),
|
||||
@ -143,7 +143,8 @@ gfxFontEntry::gfxFontEntry(const nsAString& aName, bool aIsStandardFace) :
|
||||
mGrFace(nullptr),
|
||||
mGrFaceRefCnt(0)
|
||||
{
|
||||
memset(&mHasSpaceFeaturesSub, 0, sizeof(mHasSpaceFeaturesSub));
|
||||
memset(&mDefaultSubSpaceFeatures, 0, sizeof(mDefaultSubSpaceFeatures));
|
||||
memset(&mNonDefaultSubSpaceFeatures, 0, sizeof(mNonDefaultSubSpaceFeatures));
|
||||
}
|
||||
|
||||
gfxFontEntry::~gfxFontEntry()
|
||||
@ -1941,36 +1942,6 @@ gfxFont::AgeCacheEntry(CacheHashEntry *aEntry, void *aUserData)
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
static bool
|
||||
HasLookupRuleWithGlyphByScript(hb_face_t *aFace, hb_tag_t aTableTag,
|
||||
hb_tag_t aScript, uint16_t aGlyph)
|
||||
{
|
||||
hb_set_t *lookups = hb_set_create();
|
||||
hb_set_t *glyphs = hb_set_create();
|
||||
hb_tag_t scripts[2] = {0};
|
||||
scripts[0] = aScript;
|
||||
|
||||
bool result = false;
|
||||
hb_ot_layout_collect_lookups(aFace, aTableTag, scripts, nullptr, nullptr,
|
||||
lookups);
|
||||
|
||||
hb_codepoint_t index = -1;
|
||||
while (hb_set_next(lookups, &index)) {
|
||||
hb_ot_layout_lookup_collect_glyphs(aFace, aTableTag, index,
|
||||
glyphs, glyphs, glyphs,
|
||||
glyphs);
|
||||
if (hb_set_has(glyphs, aGlyph)) {
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
hb_set_destroy(glyphs);
|
||||
hb_set_destroy(lookups);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
CollectLookupsByFeature(hb_face_t *aFace, hb_tag_t aTableTag,
|
||||
uint32_t aFeatureIndex, hb_set_t *aLookups)
|
||||
@ -1992,8 +1963,10 @@ CollectLookupsByFeature(hb_face_t *aFace, hb_tag_t aTableTag,
|
||||
|
||||
static void
|
||||
CollectLookupsByLanguage(hb_face_t *aFace, hb_tag_t aTableTag,
|
||||
hb_tag_t aExcludeFeature,
|
||||
hb_set_t *aLookups, hb_set_t *aExcludedFeatureLookups,
|
||||
const nsTHashtable<nsUint32HashKey>&
|
||||
aSpecificFeatures,
|
||||
hb_set_t *aOtherLookups,
|
||||
hb_set_t *aSpecificFeatureLookups,
|
||||
uint32_t aScriptIndex, uint32_t aLangIndex)
|
||||
{
|
||||
uint32_t reqFeatureIndex;
|
||||
@ -2001,7 +1974,8 @@ CollectLookupsByLanguage(hb_face_t *aFace, hb_tag_t aTableTag,
|
||||
aScriptIndex,
|
||||
aLangIndex,
|
||||
&reqFeatureIndex)) {
|
||||
CollectLookupsByFeature(aFace, aTableTag, reqFeatureIndex, aLookups);
|
||||
CollectLookupsByFeature(aFace, aTableTag, reqFeatureIndex,
|
||||
aOtherLookups);
|
||||
}
|
||||
|
||||
uint32_t featureIndexes[32];
|
||||
@ -2026,31 +2000,101 @@ CollectLookupsByLanguage(hb_face_t *aFace, hb_tag_t aTableTag,
|
||||
&featureTag);
|
||||
|
||||
// collect lookups
|
||||
hb_set_t *lookups = featureTag == aExcludeFeature ?
|
||||
aExcludedFeatureLookups : aLookups;
|
||||
hb_set_t *lookups = aSpecificFeatures.GetEntry(featureTag) ?
|
||||
aSpecificFeatureLookups : aOtherLookups;
|
||||
CollectLookupsByFeature(aFace, aTableTag, featureIndex, lookups);
|
||||
}
|
||||
offset += len;
|
||||
} while (len == ArrayLength(featureIndexes));
|
||||
}
|
||||
|
||||
static bool
|
||||
HasLookupRuleWithGlyphByScript(hb_face_t *aFace, hb_tag_t aTableTag,
|
||||
hb_tag_t aScriptTag, uint32_t aScriptIndex,
|
||||
uint16_t aGlyph,
|
||||
const nsTHashtable<nsUint32HashKey>&
|
||||
aDefaultFeatures,
|
||||
bool& aHasDefaultFeatureWithGlyph)
|
||||
{
|
||||
uint32_t numLangs, lang;
|
||||
hb_set_t *defaultFeatureLookups = hb_set_create();
|
||||
hb_set_t *nonDefaultFeatureLookups = hb_set_create();
|
||||
|
||||
// default lang
|
||||
CollectLookupsByLanguage(aFace, aTableTag, aDefaultFeatures,
|
||||
nonDefaultFeatureLookups, defaultFeatureLookups,
|
||||
aScriptIndex,
|
||||
HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX);
|
||||
|
||||
// iterate over langs
|
||||
numLangs = hb_ot_layout_script_get_language_tags(aFace, aTableTag,
|
||||
aScriptIndex, 0,
|
||||
nullptr, nullptr);
|
||||
for (lang = 0; lang < numLangs; lang++) {
|
||||
CollectLookupsByLanguage(aFace, aTableTag, aDefaultFeatures,
|
||||
nonDefaultFeatureLookups,
|
||||
defaultFeatureLookups,
|
||||
aScriptIndex, lang);
|
||||
}
|
||||
|
||||
// look for the glyph among default feature lookups
|
||||
aHasDefaultFeatureWithGlyph = false;
|
||||
hb_set_t *glyphs = hb_set_create();
|
||||
hb_codepoint_t index = -1;
|
||||
while (hb_set_next(defaultFeatureLookups, &index)) {
|
||||
hb_ot_layout_lookup_collect_glyphs(aFace, aTableTag, index,
|
||||
glyphs, glyphs, glyphs,
|
||||
glyphs);
|
||||
if (hb_set_has(glyphs, aGlyph)) {
|
||||
aHasDefaultFeatureWithGlyph = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// look for the glyph among non-default feature lookups
|
||||
// if no default feature lookups contained spaces
|
||||
bool hasNonDefaultFeatureWithGlyph = false;
|
||||
if (!aHasDefaultFeatureWithGlyph) {
|
||||
hb_set_clear(glyphs);
|
||||
index = -1;
|
||||
while (hb_set_next(nonDefaultFeatureLookups, &index)) {
|
||||
hb_ot_layout_lookup_collect_glyphs(aFace, aTableTag, index,
|
||||
glyphs, glyphs, glyphs,
|
||||
glyphs);
|
||||
if (hb_set_has(glyphs, aGlyph)) {
|
||||
hasNonDefaultFeatureWithGlyph = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hb_set_destroy(glyphs);
|
||||
hb_set_destroy(defaultFeatureLookups);
|
||||
hb_set_destroy(nonDefaultFeatureLookups);
|
||||
|
||||
return aHasDefaultFeatureWithGlyph || hasNonDefaultFeatureWithGlyph;
|
||||
}
|
||||
|
||||
static void
|
||||
HasLookupRuleWithGlyph(hb_face_t *aFace, hb_tag_t aTableTag, bool& aHasGlyph,
|
||||
hb_tag_t aExcludeFeature, bool& aHasGlyphExcluded,
|
||||
hb_tag_t aSpecificFeature, bool& aHasGlyphSpecific,
|
||||
uint16_t aGlyph)
|
||||
{
|
||||
// iterate over the scripts in the font
|
||||
uint32_t numScripts, numLangs, script, lang;
|
||||
hb_set_t *lookups = hb_set_create();
|
||||
hb_set_t *excludedFeatureLookups = hb_set_create();
|
||||
hb_set_t *otherLookups = hb_set_create();
|
||||
hb_set_t *specificFeatureLookups = hb_set_create();
|
||||
nsTHashtable<nsUint32HashKey> specificFeature;
|
||||
|
||||
specificFeature.PutEntry(aSpecificFeature);
|
||||
|
||||
numScripts = hb_ot_layout_table_get_script_tags(aFace, aTableTag, 0,
|
||||
nullptr, nullptr);
|
||||
|
||||
for (script = 0; script < numScripts; script++) {
|
||||
// default lang
|
||||
CollectLookupsByLanguage(aFace, aTableTag, aExcludeFeature,
|
||||
lookups, excludedFeatureLookups,
|
||||
CollectLookupsByLanguage(aFace, aTableTag, specificFeature,
|
||||
otherLookups, specificFeatureLookups,
|
||||
script, HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX);
|
||||
|
||||
// iterate over langs
|
||||
@ -2058,16 +2102,16 @@ HasLookupRuleWithGlyph(hb_face_t *aFace, hb_tag_t aTableTag, bool& aHasGlyph,
|
||||
script, 0,
|
||||
nullptr, nullptr);
|
||||
for (lang = 0; lang < numLangs; lang++) {
|
||||
CollectLookupsByLanguage(aFace, aTableTag, aExcludeFeature,
|
||||
lookups, excludedFeatureLookups,
|
||||
CollectLookupsByLanguage(aFace, aTableTag, specificFeature,
|
||||
otherLookups, specificFeatureLookups,
|
||||
script, lang);
|
||||
}
|
||||
}
|
||||
|
||||
// look for the glyph among non-excluded lookups
|
||||
// look for the glyph among non-specific feature lookups
|
||||
hb_set_t *glyphs = hb_set_create();
|
||||
hb_codepoint_t index = -1;
|
||||
while (hb_set_next(lookups, &index)) {
|
||||
while (hb_set_next(otherLookups, &index)) {
|
||||
hb_ot_layout_lookup_collect_glyphs(aFace, aTableTag, index,
|
||||
glyphs, glyphs, glyphs,
|
||||
glyphs);
|
||||
@ -2077,25 +2121,75 @@ HasLookupRuleWithGlyph(hb_face_t *aFace, hb_tag_t aTableTag, bool& aHasGlyph,
|
||||
}
|
||||
}
|
||||
|
||||
// look for the glyph among excluded lookups
|
||||
// look for the glyph among specific feature lookups
|
||||
hb_set_clear(glyphs);
|
||||
index = -1;
|
||||
while (hb_set_next(excludedFeatureLookups, &index)) {
|
||||
while (hb_set_next(specificFeatureLookups, &index)) {
|
||||
hb_ot_layout_lookup_collect_glyphs(aFace, aTableTag, index,
|
||||
glyphs, glyphs, glyphs,
|
||||
glyphs);
|
||||
if (hb_set_has(glyphs, aGlyph)) {
|
||||
aHasGlyphExcluded = true;
|
||||
aHasGlyphSpecific = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
hb_set_destroy(glyphs);
|
||||
hb_set_destroy(excludedFeatureLookups);
|
||||
hb_set_destroy(lookups);
|
||||
hb_set_destroy(specificFeatureLookups);
|
||||
hb_set_destroy(otherLookups);
|
||||
}
|
||||
|
||||
nsDataHashtable<nsUint32HashKey, int32_t> *gfxFont::sScriptTagToCode = nullptr;
|
||||
nsTHashtable<nsUint32HashKey> *gfxFont::sDefaultFeatures = nullptr;
|
||||
|
||||
static inline bool
|
||||
HasSubstitution(uint32_t *aBitVector, uint32_t aBit) {
|
||||
return (aBitVector[aBit >> 5] & (1 << (aBit & 0x1f))) != 0;
|
||||
}
|
||||
|
||||
// union of all default substitution features across scripts
|
||||
static const hb_tag_t defaultFeatures[] = {
|
||||
HB_TAG('a','b','v','f'),
|
||||
HB_TAG('a','b','v','s'),
|
||||
HB_TAG('a','k','h','n'),
|
||||
HB_TAG('b','l','w','f'),
|
||||
HB_TAG('b','l','w','s'),
|
||||
HB_TAG('c','a','l','t'),
|
||||
HB_TAG('c','c','m','p'),
|
||||
HB_TAG('c','f','a','r'),
|
||||
HB_TAG('c','j','c','t'),
|
||||
HB_TAG('c','l','i','g'),
|
||||
HB_TAG('f','i','n','2'),
|
||||
HB_TAG('f','i','n','3'),
|
||||
HB_TAG('f','i','n','a'),
|
||||
HB_TAG('h','a','l','f'),
|
||||
HB_TAG('h','a','l','n'),
|
||||
HB_TAG('i','n','i','t'),
|
||||
HB_TAG('i','s','o','l'),
|
||||
HB_TAG('l','i','g','a'),
|
||||
HB_TAG('l','j','m','o'),
|
||||
HB_TAG('l','o','c','l'),
|
||||
HB_TAG('l','t','r','a'),
|
||||
HB_TAG('l','t','r','m'),
|
||||
HB_TAG('m','e','d','2'),
|
||||
HB_TAG('m','e','d','i'),
|
||||
HB_TAG('m','s','e','t'),
|
||||
HB_TAG('n','u','k','t'),
|
||||
HB_TAG('p','r','e','f'),
|
||||
HB_TAG('p','r','e','s'),
|
||||
HB_TAG('p','s','t','f'),
|
||||
HB_TAG('p','s','t','s'),
|
||||
HB_TAG('r','c','l','t'),
|
||||
HB_TAG('r','l','i','g'),
|
||||
HB_TAG('r','k','r','f'),
|
||||
HB_TAG('r','p','h','f'),
|
||||
HB_TAG('r','t','l','a'),
|
||||
HB_TAG('r','t','l','m'),
|
||||
HB_TAG('t','j','m','o'),
|
||||
HB_TAG('v','a','t','u'),
|
||||
HB_TAG('v','e','r','t'),
|
||||
HB_TAG('v','j','m','o')
|
||||
};
|
||||
|
||||
void
|
||||
gfxFont::CheckForFeaturesInvolvingSpace()
|
||||
@ -2104,21 +2198,23 @@ gfxFont::CheckForFeaturesInvolvingSpace()
|
||||
|
||||
bool result = false;
|
||||
|
||||
hb_face_t *face = GetFontEntry()->GetHBFace();
|
||||
|
||||
uint32_t i, len, offset;
|
||||
uint32_t spaceGlyph = GetSpaceGlyph();
|
||||
int32_t s;
|
||||
if (!spaceGlyph) {
|
||||
return;
|
||||
}
|
||||
|
||||
mFontEntry->mHasSpaceFeaturesSubDefault = false;
|
||||
hb_face_t *face = GetFontEntry()->GetHBFace();
|
||||
|
||||
// GSUB lookups - examine per script
|
||||
if (hb_ot_layout_has_substitution(face)) {
|
||||
|
||||
// set up the script ==> code hashtable if needed
|
||||
if (!sScriptTagToCode) {
|
||||
sScriptTagToCode = new nsDataHashtable<nsUint32HashKey, int32_t>(MOZ_NUM_SCRIPT_CODES);
|
||||
for (s = MOZ_SCRIPT_ARABIC; s < MOZ_NUM_SCRIPT_CODES; s++) {
|
||||
sScriptTagToCode =
|
||||
new nsDataHashtable<nsUint32HashKey,
|
||||
int32_t>(MOZ_NUM_SCRIPT_CODES);
|
||||
sScriptTagToCode->Put(HB_TAG('D','F','L','T'), MOZ_SCRIPT_COMMON);
|
||||
for (int32_t s = MOZ_SCRIPT_ARABIC; s < MOZ_NUM_SCRIPT_CODES; s++) {
|
||||
hb_script_t scriptTag = hb_script_t(GetScriptTagForCode(s));
|
||||
hb_tag_t s1, s2;
|
||||
hb_ot_tags_from_script(scriptTag, &s1, &s2);
|
||||
@ -2127,40 +2223,61 @@ gfxFont::CheckForFeaturesInvolvingSpace()
|
||||
sScriptTagToCode->Put(s2, s);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t numDefaultFeatures = ArrayLength(defaultFeatures);
|
||||
sDefaultFeatures =
|
||||
new nsTHashtable<nsUint32HashKey>(numDefaultFeatures);
|
||||
for (uint32_t i = 0; i < numDefaultFeatures; i++) {
|
||||
sDefaultFeatures->PutEntry(defaultFeatures[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// iterate over the scripts in the font
|
||||
hb_tag_t scriptTags[8];
|
||||
|
||||
offset = 0;
|
||||
uint32_t len, offset = 0;
|
||||
do {
|
||||
len = ArrayLength(scriptTags);
|
||||
hb_ot_layout_table_get_script_tags(face, HB_OT_TAG_GSUB, offset,
|
||||
&len, scriptTags);
|
||||
for (i = 0; i < len; i++) {
|
||||
if (HasLookupRuleWithGlyphByScript(face, HB_OT_TAG_GSUB,
|
||||
scriptTags[i], spaceGlyph))
|
||||
for (uint32_t i = 0; i < len; i++) {
|
||||
bool isDefaultFeature = false;
|
||||
int32_t s;
|
||||
if (!HasLookupRuleWithGlyphByScript(face, HB_OT_TAG_GSUB,
|
||||
scriptTags[i], offset + i,
|
||||
spaceGlyph,
|
||||
*sDefaultFeatures,
|
||||
isDefaultFeature) ||
|
||||
!sScriptTagToCode->Get(scriptTags[i], &s))
|
||||
{
|
||||
result = true;
|
||||
if (scriptTags[i] == HB_TAG('D','F','L','T')) {
|
||||
mFontEntry->mHasSpaceFeaturesSubDefault = true;
|
||||
}
|
||||
if (sScriptTagToCode->Get(scriptTags[i], &s)) {
|
||||
uint32_t index = s >> 5;
|
||||
uint32_t bit = s & 0x1f;
|
||||
mFontEntry->mHasSpaceFeaturesSub[index] |= (1 << bit);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
result = true;
|
||||
uint32_t index = s >> 5;
|
||||
uint32_t bit = s & 0x1f;
|
||||
if (isDefaultFeature) {
|
||||
mFontEntry->mDefaultSubSpaceFeatures[index] |= (1 << bit);
|
||||
} else {
|
||||
mFontEntry->mNonDefaultSubSpaceFeatures[index] |= (1 << bit);
|
||||
}
|
||||
}
|
||||
offset += len;
|
||||
} while (len == ArrayLength(scriptTags));
|
||||
}
|
||||
|
||||
// spaces in default features of default script?
|
||||
// ==> can't use word cache, skip GPOS analysis
|
||||
bool canUseWordCache = true;
|
||||
if (HasSubstitution(mFontEntry->mDefaultSubSpaceFeatures,
|
||||
MOZ_SCRIPT_COMMON)) {
|
||||
canUseWordCache = false;
|
||||
}
|
||||
|
||||
// GPOS lookups - distinguish kerning from non-kerning features
|
||||
mFontEntry->mHasSpaceFeaturesKerning = false;
|
||||
mFontEntry->mHasSpaceFeaturesNonKerning = false;
|
||||
|
||||
if (hb_ot_layout_has_positioning(face)) {
|
||||
if (canUseWordCache && hb_ot_layout_has_positioning(face)) {
|
||||
bool hasKerning = false, hasNonKerning = false;
|
||||
HasLookupRuleWithGlyph(face, HB_OT_TAG_GPOS, hasNonKerning,
|
||||
HB_TAG('k','e','r','n'), hasKerning, spaceGlyph);
|
||||
@ -2175,20 +2292,91 @@ gfxFont::CheckForFeaturesInvolvingSpace()
|
||||
mFontEntry->mHasSpaceFeatures = result;
|
||||
|
||||
#ifdef DEBUG_SPACE_LOOKUPS
|
||||
printf("font: %s - subst: %8.8x %8.8x %8.8x %8.8x "
|
||||
"default: %s kerning: %s non-kerning: %s\n",
|
||||
printf("font: %s - subst default: %8.8x %8.8x %8.8x %8.8x "
|
||||
"subst non-default: %8.8x %8.8x %8.8x %8.8x "
|
||||
"kerning: %s non-kerning: %s\n",
|
||||
NS_ConvertUTF16toUTF8(mFontEntry->Name()).get(),
|
||||
mFontEntry->mHasSpaceFeaturesSub[0],
|
||||
mFontEntry->mHasSpaceFeaturesSub[1],
|
||||
mFontEntry->mHasSpaceFeaturesSub[2],
|
||||
mFontEntry->mHasSpaceFeaturesSub[3],
|
||||
(mFontEntry->mHasSpaceFeaturesSubDefault ? "true" : "false"),
|
||||
mFontEntry->mDefaultSubSpaceFeatures[3],
|
||||
mFontEntry->mDefaultSubSpaceFeatures[2],
|
||||
mFontEntry->mDefaultSubSpaceFeatures[1],
|
||||
mFontEntry->mDefaultSubSpaceFeatures[0],
|
||||
mFontEntry->mNonDefaultSubSpaceFeatures[3],
|
||||
mFontEntry->mNonDefaultSubSpaceFeatures[2],
|
||||
mFontEntry->mNonDefaultSubSpaceFeatures[1],
|
||||
mFontEntry->mNonDefaultSubSpaceFeatures[0],
|
||||
(mFontEntry->mHasSpaceFeaturesKerning ? "true" : "false"),
|
||||
(mFontEntry->mHasSpaceFeaturesNonKerning ? "true" : "false")
|
||||
);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
gfxFont::HasSubstitutionRulesWithSpaceLookups(int32_t aRunScript)
|
||||
{
|
||||
NS_ASSERTION(GetFontEntry()->mHasSpaceFeaturesInitialized,
|
||||
"need to initialize space lookup flags");
|
||||
NS_ASSERTION(aRunScript < MOZ_NUM_SCRIPT_CODES, "weird script code");
|
||||
if (aRunScript == MOZ_SCRIPT_INVALID ||
|
||||
aRunScript >= MOZ_NUM_SCRIPT_CODES) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// default features have space lookups ==> true
|
||||
if (HasSubstitution(mFontEntry->mDefaultSubSpaceFeatures,
|
||||
MOZ_SCRIPT_COMMON) ||
|
||||
HasSubstitution(mFontEntry->mDefaultSubSpaceFeatures,
|
||||
aRunScript))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// non-default features have space lookups and some type of
|
||||
// font feature, in font or style is specified ==> true
|
||||
if ((HasSubstitution(mFontEntry->mNonDefaultSubSpaceFeatures,
|
||||
MOZ_SCRIPT_COMMON) ||
|
||||
HasSubstitution(mFontEntry->mNonDefaultSubSpaceFeatures,
|
||||
aRunScript)) &&
|
||||
(!mStyle.featureSettings.IsEmpty() ||
|
||||
!mFontEntry->mFeatureSettings.IsEmpty()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
gfxFont::BypassShapedWordCache(int32_t aRunScript)
|
||||
{
|
||||
// We record the presence of space-dependent features in the font entry
|
||||
// so that subsequent instantiations for the same font face won't
|
||||
// require us to re-check the tables; however, the actual check is done
|
||||
// by gfxFont because not all font entry subclasses know how to create
|
||||
// a harfbuzz face for introspection.
|
||||
if (!mFontEntry->mHasSpaceFeaturesInitialized) {
|
||||
CheckForFeaturesInvolvingSpace();
|
||||
}
|
||||
|
||||
if (!mFontEntry->mHasSpaceFeatures) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// if font has substitution rules or non-kerning positioning rules
|
||||
// that involve spaces, bypass
|
||||
if (HasSubstitutionRulesWithSpaceLookups(aRunScript) ||
|
||||
mFontEntry->mHasSpaceFeaturesNonKerning) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// if kerning explicitly enabled/disabled via font-feature-settings or
|
||||
// font-kerning and kerning rules use spaces, only bypass when enabled
|
||||
if (mKerningSet && mFontEntry->mHasSpaceFeaturesKerning) {
|
||||
return mKerningEnabled;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
gfxFont::HasFeatureSet(uint32_t aFeature, bool& aFeatureOn)
|
||||
{
|
||||
|
@ -438,14 +438,15 @@ public:
|
||||
bool mHasSpaceFeatures : 1;
|
||||
bool mHasSpaceFeaturesKerning : 1;
|
||||
bool mHasSpaceFeaturesNonKerning : 1;
|
||||
bool mHasSpaceFeaturesSubDefault : 1;
|
||||
bool mHasGraphiteTables : 1;
|
||||
bool mCheckedForGraphiteTables : 1;
|
||||
bool mHasCmapTable : 1;
|
||||
bool mGrFaceInitialized : 1;
|
||||
|
||||
// bitvector of substitution space features per script
|
||||
uint32_t mHasSpaceFeaturesSub[(MOZ_NUM_SCRIPT_CODES + 31) / 32];
|
||||
// bitvector of substitution space features per script, one each
|
||||
// for default and non-default features
|
||||
uint32_t mDefaultSubSpaceFeatures[(MOZ_NUM_SCRIPT_CODES + 31) / 32];
|
||||
uint32_t mNonDefaultSubSpaceFeatures[(MOZ_NUM_SCRIPT_CODES + 31) / 32];
|
||||
|
||||
uint16_t mWeight;
|
||||
int16_t mStretch;
|
||||
@ -1794,53 +1795,20 @@ public:
|
||||
return mFontEntry->TryGetSVGData(this);
|
||||
}
|
||||
|
||||
static void DestroySingletons() {
|
||||
delete sScriptTagToCode;
|
||||
delete sDefaultFeatures;
|
||||
}
|
||||
|
||||
protected:
|
||||
void AddGlyphChangeObserver(GlyphChangeObserver *aObserver);
|
||||
void RemoveGlyphChangeObserver(GlyphChangeObserver *aObserver);
|
||||
|
||||
bool HasSubstitutionRulesWithSpaceLookups(int32_t aRunScript) {
|
||||
NS_ASSERTION(GetFontEntry()->mHasSpaceFeaturesInitialized,
|
||||
"need to initialize space lookup flags");
|
||||
NS_ASSERTION(aRunScript < MOZ_NUM_SCRIPT_CODES, "weird script code");
|
||||
if (aRunScript == MOZ_SCRIPT_INVALID ||
|
||||
aRunScript >= MOZ_NUM_SCRIPT_CODES) {
|
||||
return false;
|
||||
}
|
||||
uint32_t index = aRunScript >> 5;
|
||||
uint32_t bit = aRunScript & 0x1f;
|
||||
return (mFontEntry->mHasSpaceFeaturesSub[index] & (1 << bit)) != 0;
|
||||
}
|
||||
// whether font contains substitution lookups containing spaces
|
||||
bool HasSubstitutionRulesWithSpaceLookups(int32_t aRunScript);
|
||||
|
||||
bool BypassShapedWordCache(int32_t aRunScript) {
|
||||
// We record the presence of space-dependent features in the font entry
|
||||
// so that subsequent instantiations for the same font face won't
|
||||
// require us to re-check the tables; however, the actual check is done
|
||||
// by gfxFont because not all font entry subclasses know how to create
|
||||
// a harfbuzz face for introspection.
|
||||
if (!mFontEntry->mHasSpaceFeaturesInitialized) {
|
||||
CheckForFeaturesInvolvingSpace();
|
||||
}
|
||||
|
||||
if (!mFontEntry->mHasSpaceFeatures) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// if font has substitution rules or non-kerning positioning rules
|
||||
// that involve spaces, bypass
|
||||
if (HasSubstitutionRulesWithSpaceLookups(aRunScript) ||
|
||||
mFontEntry->mHasSpaceFeaturesNonKerning ||
|
||||
mFontEntry->mHasSpaceFeaturesSubDefault) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// if kerning explicitly enabled/disabled via font-feature-settings or
|
||||
// font-kerning and kerning rules use spaces, only bypass when enabled
|
||||
if (mKerningSet && mFontEntry->mHasSpaceFeaturesKerning) {
|
||||
return mKerningEnabled;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
// whether to use word cache or not
|
||||
bool BypassShapedWordCache(int32_t aRunScript);
|
||||
|
||||
// For 8-bit text, expand to 16-bit and then call the following method.
|
||||
bool ShapeText(gfxContext *aContext,
|
||||
@ -1904,7 +1872,9 @@ protected:
|
||||
// font and the style. aFeatureOn set if resolved feature value is non-zero
|
||||
bool HasFeatureSet(uint32_t aFeature, bool& aFeatureOn);
|
||||
|
||||
// used when analyzing whether a font has space contextual lookups
|
||||
static nsDataHashtable<nsUint32HashKey, int32_t> *sScriptTagToCode;
|
||||
static nsTHashtable<nsUint32HashKey> *sDefaultFeatures;
|
||||
|
||||
nsRefPtr<gfxFontEntry> mFontEntry;
|
||||
|
||||
|
@ -501,6 +501,7 @@ gfxPlatform::Shutdown()
|
||||
delete gGfxPlatformPrefsLock;
|
||||
|
||||
gfxPrefs::DestroySingleton();
|
||||
gfxFont::DestroySingletons();
|
||||
|
||||
delete gPlatform;
|
||||
gPlatform = nullptr;
|
||||
|
Loading…
Reference in New Issue
Block a user