Bug 1744765 - Add font features config from user's fontconfig r=jfkthame,layout-reviewers
authorCoelacanthus <coelacanthus@outlook.com>
Wed, 16 Feb 2022 23:00:52 +0000
changeset 607981 182c89c77191fde2b9d8253c0c471b85f569a36c
parent 607980 b764644bbd84c039470d3a1cc08cd26284246122
child 607982 85a7ef274151addbfb5d654b67c3d2c7c1afadd6
push id39299
push userabutkovits@mozilla.com
push dateThu, 17 Feb 2022 05:15:17 +0000
treeherdermozilla-central@430986e11fd2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjfkthame, layout-reviewers
bugs1744765
milestone99.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1744765 - Add font features config from user's fontconfig r=jfkthame,layout-reviewers As Pango do, we get font feature settings for specfied from user's fontconfig. This will not affect users that don't use this feature, because they will not add fontfeatures setting in their fontconfig. There is an example config I use to test: <match target="pattern"> <test name="family" compare="eq" ignore-blanks="true"> <string>Iosevka</string> </test> <edit name="fontfeatures" mode="append"> <string>ss10 on</string> <!-- using SS10 variant shape --> <string>cv49 1</string> <!-- straight y --> <string>cv83 2</string> <!-- underline, not too high, not too low --> </edit> </match> Signed-off-by: Coelacanthus <coelacanthus@outlook.com> Differential Revision: https://phabricator.services.mozilla.com/D138757
gfx/thebes/gfxFcPlatformFontList.cpp
gfx/thebes/gfxFcPlatformFontList.h
--- a/gfx/thebes/gfxFcPlatformFontList.cpp
+++ b/gfx/thebes/gfxFcPlatformFontList.cpp
@@ -27,16 +27,17 @@
 #include "nsXULAppAPI.h"
 #include "SharedFontList-impl.h"
 #include "StandardFonts-linux.inc"
 
 #include "mozilla/gfx/HelpersCairo.h"
 
 #include <cairo-ft.h>
 #include <fontconfig/fcfreetype.h>
+#include <harfbuzz/hb.h>
 #include <dlfcn.h>
 #include <unistd.h>
 
 #ifdef MOZ_WIDGET_GTK
 #  include <gdk/gdk.h>
 #  include <gtk/gtk.h>
 #  include "gfxPlatformGtk.h"
 #  include "mozilla/WidgetUtilsGtk.h"
@@ -246,25 +247,41 @@ static void GetFontProperties(FcPattern*
         *aSize = uint16_t(NS_round(size));
       } else {
         *aSize = 0;
       }
     }
   }
 }
 
+void gfxFontconfigFontEntry::GetUserFontFeatures(FcPattern* aPattern) {
+  int fontFeaturesNum = 0;
+  char* s;
+  hb_feature_t tmpFeature;
+  while (FcResultMatch == FcPatternGetString(aPattern, "fontfeatures",
+                                             fontFeaturesNum, (FcChar8**)&s)) {
+    bool ret = hb_feature_from_string(s, -1, &tmpFeature);
+    if (ret) {
+      mFeatureSettings.AppendElement(
+          (gfxFontFeature){tmpFeature.tag, tmpFeature.value});
+    }
+    fontFeaturesNum++;
+  }
+}
+
 gfxFontconfigFontEntry::gfxFontconfigFontEntry(const nsACString& aFaceName,
                                                FcPattern* aFontPattern,
                                                bool aIgnoreFcCharmap)
     : gfxFT2FontEntryBase(aFaceName),
       mFontPattern(aFontPattern),
       mFTFaceInitialized(false),
       mIgnoreFcCharmap(aIgnoreFcCharmap),
       mHasVariationsInitialized(false) {
   GetFontProperties(aFontPattern, &mWeightRange, &mStretchRange, &mStyleRange);
+  GetUserFontFeatures(mFontPattern);
 }
 
 gfxFontEntry* gfxFontconfigFontEntry::Clone() const {
   MOZ_ASSERT(!IsUserFont(), "we can only clone installed fonts!");
   return new gfxFontconfigFontEntry(Name(), mFontPattern, mIgnoreFcCharmap);
 }
 
 static already_AddRefed<FcPattern> CreatePatternForFace(FT_Face aFace) {
@@ -346,16 +363,18 @@ gfxFontconfigFontEntry::gfxFontconfigFon
   // if the default glyphs are blank; but if the local font is a non-
   // sfnt face (e.g. legacy type 1) then we need to set it to false
   // because our cmap-reading code will fail and we depend on FT+Fc to
   // determine the coverage.
   // We set the flag here, but may flip it the first time TestCharacterMap
   // is called, at which point we'll look to see whether a 'cmap' is
   // actually present in the font.
   mIgnoreFcCharmap = true;
+
+  GetUserFontFeatures(mFontPattern);
 }
 
 typedef FT_Error (*GetVarFunc)(FT_Face, FT_MM_Var**);
 typedef FT_Error (*DoneVarFunc)(FT_Library, FT_MM_Var*);
 static GetVarFunc sGetVar;
 static DoneVarFunc sDoneVar;
 static bool sInitializedVarFuncs = false;
 
--- a/gfx/thebes/gfxFcPlatformFontList.h
+++ b/gfx/thebes/gfxFcPlatformFontList.h
@@ -109,16 +109,18 @@ class gfxFontconfigFontEntry final : pub
 
   double GetAspect(uint8_t aSizeAdjustBasis);
 
  protected:
   virtual ~gfxFontconfigFontEntry();
 
   gfxFont* CreateFontInstance(const gfxFontStyle* aFontStyle) override;
 
+  void GetUserFontFeatures(FcPattern* aPattern);
+
   // pattern for a single face of a family
   RefPtr<FcPattern> mFontPattern;
 
   // FTFace - initialized when needed
   RefPtr<mozilla::gfx::SharedFTFace> mFTFace;
   bool mFTFaceInitialized;
 
   // Whether TestCharacterMap should check the actual cmap rather than asking