Loading gfx/thebes/gfxFont.cpp +42 −0 Original line number Diff line number Diff line Loading @@ -1350,6 +1350,48 @@ gfxFontCache::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf, SizeOfExcludingThis(aMallocSizeOf, aSizes); } /* static */ bool gfxFontShaper::MergeFontFeatures( const nsTArray<gfxFontFeature>& aStyleRuleFeatures, const nsTArray<gfxFontFeature>& aFontFeatures, bool aDisableLigatures, nsDataHashtable<nsUint32HashKey,PRUint32>& aMergedFeatures) { // bail immediately if nothing to do if (aStyleRuleFeatures.IsEmpty() && aFontFeatures.IsEmpty() && !aDisableLigatures) { return false; } aMergedFeatures.Init(); // Ligature features are enabled by default in the generic shaper, // so we explicitly turn them off if necessary (for letter-spacing) if (aDisableLigatures) { aMergedFeatures.Put(HB_TAG('l','i','g','a'), 0); aMergedFeatures.Put(HB_TAG('c','l','i','g'), 0); } // add feature values from font PRUint32 i, count; count = aFontFeatures.Length(); for (i = 0; i < count; i++) { const gfxFontFeature& feature = aFontFeatures.ElementAt(i); aMergedFeatures.Put(feature.mTag, feature.mValue); } // add feature values from style rules count = aStyleRuleFeatures.Length(); for (i = 0; i < count; i++) { const gfxFontFeature& feature = aStyleRuleFeatures.ElementAt(i); aMergedFeatures.Put(feature.mTag, feature.mValue); } return aMergedFeatures.Count() != 0; } void gfxFont::RunMetrics::CombineWith(const RunMetrics& aOther, bool aOtherIsOnLeft) { Loading gfx/thebes/gfxFont.h +7 −0 Original line number Diff line number Diff line Loading @@ -1154,6 +1154,13 @@ public: gfxFont *GetFont() const { return mFont; } // returns true if features exist in output, false otherwise static bool MergeFontFeatures(const nsTArray<gfxFontFeature>& aStyleRuleFeatures, const nsTArray<gfxFontFeature>& aFontFeatures, bool aDisableLigatures, nsDataHashtable<nsUint32HashKey,PRUint32>& aMergedFeatures); protected: // the font this shaper is working with gfxFont * mFont; Loading gfx/thebes/gfxGraphiteShaper.cpp +26 −20 Original line number Diff line number Diff line Loading @@ -154,6 +154,23 @@ MakeGraphiteLangTag(PRUint32 aTag) return grLangTag; } struct GrFontFeatures { gr_face *mFace; gr_feature_val *mFeatures; }; static PLDHashOperator AddFeature(const PRUint32& aTag, PRUint32& aValue, void *aUserArg) { GrFontFeatures *f = static_cast<GrFontFeatures*>(aUserArg); const gr_feature_ref* fref = gr_face_find_fref(f->mFace, aTag); if (fref) { gr_fref_set_feature_value(fref, aValue, f->mFeatures); } return PL_DHASH_NEXT; } bool gfxGraphiteShaper::ShapeWord(gfxContext *aContext, gfxShapedWord *aShapedWord, Loading Loading @@ -197,32 +214,21 @@ gfxGraphiteShaper::ShapeWord(gfxContext *aContext, } gr_feature_val *grFeatures = gr_face_featureval_for_lang(mGrFace, grLang); if (aShapedWord->DisableLigatures()) { const gr_feature_ref* fref = gr_face_find_fref(mGrFace, TRUETYPE_TAG('l','i','g','a')); if (fref) { gr_fref_set_feature_value(fref, 0, grFeatures); } } nsDataHashtable<nsUint32HashKey,PRUint32> mergedFeatures; const nsTArray<gfxFontFeature> *features = &style->featureSettings; if (features->IsEmpty()) { features = &entry->mFeatureSettings; } for (PRUint32 i = 0; i < features->Length(); ++i) { const gr_feature_ref* fref = gr_face_find_fref(mGrFace, (*features)[i].mTag); if (fref) { gr_fref_set_feature_value(fref, (*features)[i].mValue, grFeatures); } if (MergeFontFeatures(style->featureSettings, entry->mFeatureSettings, aShapedWord->DisableLigatures(), mergedFeatures)) { // enumerate result and insert into Graphite feature list GrFontFeatures f = {mGrFace, grFeatures}; mergedFeatures.Enumerate(AddFeature, &f); } gr_segment *seg = gr_make_seg(mGrFont, mGrFace, 0, grFeatures, gr_utf16, aText, aShapedWord->Length(), aShapedWord->IsRightToLeft()); if (features) { gr_featureval_destroy(grFeatures); } if (!seg) { return false; } Loading gfx/thebes/gfxHarfBuzzShaper.cpp +20 −27 Original line number Diff line number Diff line Loading @@ -842,6 +842,18 @@ HBUnicodeDecompose(hb_unicode_funcs_t *ufuncs, return nsUnicodeNormalizer::DecomposeNonRecursively(ab, a, b); } static PLDHashOperator AddFeature(const PRUint32& aTag, PRUint32& aValue, void *aUserArg) { nsTArray<hb_feature_t>* features = static_cast<nsTArray<hb_feature_t>*> (aUserArg); hb_feature_t feat = { 0, 0, 0, UINT_MAX }; feat.tag = aTag; feat.value = aValue; features->AppendElement(feat); return PL_DHASH_NEXT; } /* * gfxFontShaper override to initialize the text run using HarfBuzz */ Loading Loading @@ -973,35 +985,16 @@ gfxHarfBuzzShaper::ShapeWord(gfxContext *aContext, nsAutoTArray<hb_feature_t,20> features; // Ligature features are enabled by default in the generic shaper, // so we explicitly turn them off if necessary (for letter-spacing) if (aShapedWord->DisableLigatures()) { hb_feature_t ligaOff = { HB_TAG('l','i','g','a'), 0, 0, UINT_MAX }; hb_feature_t cligOff = { HB_TAG('c','l','i','g'), 0, 0, UINT_MAX }; features.AppendElement(ligaOff); features.AppendElement(cligOff); } // css features need to be merged with the existing ones, if any gfxFontEntry *entry = mFont->GetFontEntry(); const gfxFontStyle *style = mFont->GetStyle(); const nsTArray<gfxFontFeature> *cssFeatures = &style->featureSettings; if (cssFeatures->IsEmpty()) { cssFeatures = &entry->mFeatureSettings; } for (PRUint32 i = 0; i < cssFeatures->Length(); ++i) { PRUint32 j; for (j = 0; j < features.Length(); ++j) { if (cssFeatures->ElementAt(i).mTag == features[j].tag) { features[j].value = cssFeatures->ElementAt(i).mValue; break; } } if (j == features.Length()) { const gfxFontFeature& f = cssFeatures->ElementAt(i); hb_feature_t hbf = { f.mTag, f.mValue, 0, UINT_MAX }; features.AppendElement(hbf); } nsDataHashtable<nsUint32HashKey,PRUint32> mergedFeatures; if (MergeFontFeatures(style->featureSettings, mFont->GetFontEntry()->mFeatureSettings, aShapedWord->DisableLigatures(), mergedFeatures)) { // enumerate result and insert into hb_feature array mergedFeatures.Enumerate(AddFeature, &features); } bool isRightToLeft = aShapedWord->IsRightToLeft(); Loading Loading
gfx/thebes/gfxFont.cpp +42 −0 Original line number Diff line number Diff line Loading @@ -1350,6 +1350,48 @@ gfxFontCache::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf, SizeOfExcludingThis(aMallocSizeOf, aSizes); } /* static */ bool gfxFontShaper::MergeFontFeatures( const nsTArray<gfxFontFeature>& aStyleRuleFeatures, const nsTArray<gfxFontFeature>& aFontFeatures, bool aDisableLigatures, nsDataHashtable<nsUint32HashKey,PRUint32>& aMergedFeatures) { // bail immediately if nothing to do if (aStyleRuleFeatures.IsEmpty() && aFontFeatures.IsEmpty() && !aDisableLigatures) { return false; } aMergedFeatures.Init(); // Ligature features are enabled by default in the generic shaper, // so we explicitly turn them off if necessary (for letter-spacing) if (aDisableLigatures) { aMergedFeatures.Put(HB_TAG('l','i','g','a'), 0); aMergedFeatures.Put(HB_TAG('c','l','i','g'), 0); } // add feature values from font PRUint32 i, count; count = aFontFeatures.Length(); for (i = 0; i < count; i++) { const gfxFontFeature& feature = aFontFeatures.ElementAt(i); aMergedFeatures.Put(feature.mTag, feature.mValue); } // add feature values from style rules count = aStyleRuleFeatures.Length(); for (i = 0; i < count; i++) { const gfxFontFeature& feature = aStyleRuleFeatures.ElementAt(i); aMergedFeatures.Put(feature.mTag, feature.mValue); } return aMergedFeatures.Count() != 0; } void gfxFont::RunMetrics::CombineWith(const RunMetrics& aOther, bool aOtherIsOnLeft) { Loading
gfx/thebes/gfxFont.h +7 −0 Original line number Diff line number Diff line Loading @@ -1154,6 +1154,13 @@ public: gfxFont *GetFont() const { return mFont; } // returns true if features exist in output, false otherwise static bool MergeFontFeatures(const nsTArray<gfxFontFeature>& aStyleRuleFeatures, const nsTArray<gfxFontFeature>& aFontFeatures, bool aDisableLigatures, nsDataHashtable<nsUint32HashKey,PRUint32>& aMergedFeatures); protected: // the font this shaper is working with gfxFont * mFont; Loading
gfx/thebes/gfxGraphiteShaper.cpp +26 −20 Original line number Diff line number Diff line Loading @@ -154,6 +154,23 @@ MakeGraphiteLangTag(PRUint32 aTag) return grLangTag; } struct GrFontFeatures { gr_face *mFace; gr_feature_val *mFeatures; }; static PLDHashOperator AddFeature(const PRUint32& aTag, PRUint32& aValue, void *aUserArg) { GrFontFeatures *f = static_cast<GrFontFeatures*>(aUserArg); const gr_feature_ref* fref = gr_face_find_fref(f->mFace, aTag); if (fref) { gr_fref_set_feature_value(fref, aValue, f->mFeatures); } return PL_DHASH_NEXT; } bool gfxGraphiteShaper::ShapeWord(gfxContext *aContext, gfxShapedWord *aShapedWord, Loading Loading @@ -197,32 +214,21 @@ gfxGraphiteShaper::ShapeWord(gfxContext *aContext, } gr_feature_val *grFeatures = gr_face_featureval_for_lang(mGrFace, grLang); if (aShapedWord->DisableLigatures()) { const gr_feature_ref* fref = gr_face_find_fref(mGrFace, TRUETYPE_TAG('l','i','g','a')); if (fref) { gr_fref_set_feature_value(fref, 0, grFeatures); } } nsDataHashtable<nsUint32HashKey,PRUint32> mergedFeatures; const nsTArray<gfxFontFeature> *features = &style->featureSettings; if (features->IsEmpty()) { features = &entry->mFeatureSettings; } for (PRUint32 i = 0; i < features->Length(); ++i) { const gr_feature_ref* fref = gr_face_find_fref(mGrFace, (*features)[i].mTag); if (fref) { gr_fref_set_feature_value(fref, (*features)[i].mValue, grFeatures); } if (MergeFontFeatures(style->featureSettings, entry->mFeatureSettings, aShapedWord->DisableLigatures(), mergedFeatures)) { // enumerate result and insert into Graphite feature list GrFontFeatures f = {mGrFace, grFeatures}; mergedFeatures.Enumerate(AddFeature, &f); } gr_segment *seg = gr_make_seg(mGrFont, mGrFace, 0, grFeatures, gr_utf16, aText, aShapedWord->Length(), aShapedWord->IsRightToLeft()); if (features) { gr_featureval_destroy(grFeatures); } if (!seg) { return false; } Loading
gfx/thebes/gfxHarfBuzzShaper.cpp +20 −27 Original line number Diff line number Diff line Loading @@ -842,6 +842,18 @@ HBUnicodeDecompose(hb_unicode_funcs_t *ufuncs, return nsUnicodeNormalizer::DecomposeNonRecursively(ab, a, b); } static PLDHashOperator AddFeature(const PRUint32& aTag, PRUint32& aValue, void *aUserArg) { nsTArray<hb_feature_t>* features = static_cast<nsTArray<hb_feature_t>*> (aUserArg); hb_feature_t feat = { 0, 0, 0, UINT_MAX }; feat.tag = aTag; feat.value = aValue; features->AppendElement(feat); return PL_DHASH_NEXT; } /* * gfxFontShaper override to initialize the text run using HarfBuzz */ Loading Loading @@ -973,35 +985,16 @@ gfxHarfBuzzShaper::ShapeWord(gfxContext *aContext, nsAutoTArray<hb_feature_t,20> features; // Ligature features are enabled by default in the generic shaper, // so we explicitly turn them off if necessary (for letter-spacing) if (aShapedWord->DisableLigatures()) { hb_feature_t ligaOff = { HB_TAG('l','i','g','a'), 0, 0, UINT_MAX }; hb_feature_t cligOff = { HB_TAG('c','l','i','g'), 0, 0, UINT_MAX }; features.AppendElement(ligaOff); features.AppendElement(cligOff); } // css features need to be merged with the existing ones, if any gfxFontEntry *entry = mFont->GetFontEntry(); const gfxFontStyle *style = mFont->GetStyle(); const nsTArray<gfxFontFeature> *cssFeatures = &style->featureSettings; if (cssFeatures->IsEmpty()) { cssFeatures = &entry->mFeatureSettings; } for (PRUint32 i = 0; i < cssFeatures->Length(); ++i) { PRUint32 j; for (j = 0; j < features.Length(); ++j) { if (cssFeatures->ElementAt(i).mTag == features[j].tag) { features[j].value = cssFeatures->ElementAt(i).mValue; break; } } if (j == features.Length()) { const gfxFontFeature& f = cssFeatures->ElementAt(i); hb_feature_t hbf = { f.mTag, f.mValue, 0, UINT_MAX }; features.AppendElement(hbf); } nsDataHashtable<nsUint32HashKey,PRUint32> mergedFeatures; if (MergeFontFeatures(style->featureSettings, mFont->GetFontEntry()->mFeatureSettings, aShapedWord->DisableLigatures(), mergedFeatures)) { // enumerate result and insert into hb_feature array mergedFeatures.Enumerate(AddFeature, &features); } bool isRightToLeft = aShapedWord->IsRightToLeft(); Loading