Bug 1603665 - Convert font family name to UTF-16 only once under nsFontFaceUtils::MarkDirtyForFontChange. r=jfkthame
authorCameron McCormack <cam@mcc.id.au>
Fri, 13 Dec 2019 11:01:14 +0000
changeset 506887 162eb0db41958eba57661cbf2ece98feac508ac8
parent 506886 a57473caa2871a8ef3a38a7172b57ab5ad0b1ff6
child 506888 82a7408c8b3202774a3a01ef1b5f5646365f52ab
push id36913
push useropoprus@mozilla.com
push dateFri, 13 Dec 2019 16:53:24 +0000
treeherdermozilla-central@1ed684598bd0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjfkthame
bugs1603665
milestone73.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 1603665 - Convert font family name to UTF-16 only once under nsFontFaceUtils::MarkDirtyForFontChange. r=jfkthame Differential Revision: https://phabricator.services.mozilla.com/D57055
gfx/thebes/gfxFontFamilyList.h
layout/style/nsFontFaceUtils.cpp
--- a/gfx/thebes/gfxFontFamilyList.h
+++ b/gfx/thebes/gfxFontFamilyList.h
@@ -295,24 +295,23 @@ class FontFamilyList {
         aFamilyList.AppendLiteral("serif");
       } else {
         aFamilyList.AppendLiteral("sans-serif");
       }
     }
   }
 
   // searches for a specific non-generic name, case-insensitive comparison
-  bool Contains(const nsACString& aFamilyName) const {
-    NS_ConvertUTF8toUTF16 fam(aFamilyName);
+  bool Contains(const nsAString& aFamilyName) const {
     for (const FontFamilyName& name : mFontlist->mNames) {
       if (!name.IsNamed()) {
         continue;
       }
       nsDependentAtomString listname(name.mName);
-      if (listname.Equals(fam, nsCaseInsensitiveStringComparator())) {
+      if (listname.Equals(aFamilyName, nsCaseInsensitiveStringComparator())) {
         return true;
       }
     }
     return false;
   }
 
   StyleGenericFontFamily GetDefaultFontType() const { return mDefaultFontType; }
   void SetDefaultFontType(StyleGenericFontFamily aType) {
--- a/layout/style/nsFontFaceUtils.cpp
+++ b/layout/style/nsFontFaceUtils.cpp
@@ -28,20 +28,22 @@ enum class FontUsageKind {
   // This means that its style depends on this font, and we need to restyle the
   // element the frame came from.
   FrameAndFontMetrics,
 };
 
 static FontUsageKind StyleFontUsage(ComputedStyle* aComputedStyle,
                                     nsPresContext* aPresContext,
                                     const gfxUserFontSet* aUserFontSet,
-                                    const gfxUserFontEntry* aFont) {
+                                    const gfxUserFontEntry* aFont,
+                                    const nsAString& aFamilyName) {
+  MOZ_ASSERT(NS_ConvertUTF8toUTF16(aFont->FamilyName()) == aFamilyName);
+
   // first, check if the family name is in the fontlist
-  if (!aComputedStyle->StyleFont()->mFont.fontlist.Contains(
-          aFont->FamilyName())) {
+  if (!aComputedStyle->StyleFont()->mFont.fontlist.Contains(aFamilyName)) {
     return FontUsageKind::None;
   }
 
   // family name is in the fontlist, check to see if the font group
   // associated with the frame includes the specific userfont
   RefPtr<nsFontMetrics> fm = nsLayoutUtils::GetFontMetricsForComputedStyle(
       aComputedStyle, aPresContext, 1.0f);
 
@@ -54,32 +56,33 @@ static FontUsageKind StyleFontUsage(Comp
     return FontUsageKind::FrameAndFontMetrics;
   }
 
   return FontUsageKind::Frame;
 }
 
 static FontUsageKind FrameFontUsage(nsIFrame* aFrame,
                                     nsPresContext* aPresContext,
-                                    const gfxUserFontEntry* aFont) {
+                                    const gfxUserFontEntry* aFont,
+                                    const nsAString& aFamilyName) {
   // check the style of the frame
   gfxUserFontSet* ufs = aPresContext->GetUserFontSet();
   FontUsageKind kind =
-      StyleFontUsage(aFrame->Style(), aPresContext, ufs, aFont);
+      StyleFontUsage(aFrame->Style(), aPresContext, ufs, aFont, aFamilyName);
   if (kind == FontUsageKind::FrameAndFontMetrics) {
     return kind;
   }
 
   // check additional styles
   int32_t contextIndex = 0;
   for (ComputedStyle* extraContext;
        (extraContext = aFrame->GetAdditionalComputedStyle(contextIndex));
        ++contextIndex) {
-    kind =
-        std::max(kind, StyleFontUsage(extraContext, aPresContext, ufs, aFont));
+    kind = std::max(kind, StyleFontUsage(extraContext, aPresContext, ufs, aFont,
+                                         aFamilyName));
     if (kind == FontUsageKind::FrameAndFontMetrics) {
       break;
     }
   }
 
   return kind;
 }
 
@@ -128,33 +131,37 @@ void nsFontFaceUtils::MarkDirtyForFontCh
                                              const gfxUserFontEntry* aFont) {
   MOZ_ASSERT(aFont);
   AutoTArray<nsIFrame*, 4> subtrees;
   subtrees.AppendElement(aSubtreeRoot);
 
   nsPresContext* pc = aSubtreeRoot->PresContext();
   PresShell* presShell = pc->PresShell();
 
+  // gfxFontFamilyList::Contains expects a UTF-16 string. Convert it once
+  // here rather than on each call.
+  NS_ConvertUTF8toUTF16 familyName(aFont->FamilyName());
+
   // check descendants, iterating over subtrees that may include
   // additional subtrees associated with placeholders
   do {
     nsIFrame* subtreeRoot = subtrees.PopLastElement();
 
     // Check all descendants to see if they use the font
     AutoTArray<Pair<nsIFrame*, ReflowAlreadyScheduled>, 32> stack;
     stack.AppendElement(MakePair(subtreeRoot, ReflowAlreadyScheduled::No));
 
     do {
       auto pair = stack.PopLastElement();
       nsIFrame* f = pair.first();
       ReflowAlreadyScheduled alreadyScheduled = pair.second();
 
       // if this frame uses the font, mark its descendants dirty
       // and skip checking its children
-      FontUsageKind kind = FrameFontUsage(f, pc, aFont);
+      FontUsageKind kind = FrameFontUsage(f, pc, aFont, familyName);
       if (kind != FontUsageKind::None) {
         if (alreadyScheduled == ReflowAlreadyScheduled::No) {
           ScheduleReflow(presShell, f);
           alreadyScheduled = ReflowAlreadyScheduled::Yes;
         }
         if (kind == FontUsageKind::FrameAndFontMetrics) {
           MOZ_ASSERT(f->GetContent() && f->GetContent()->IsElement(),
                      "How could we target a non-element with selectors?");