b=455243, weird behaviour with fonts with bad faces; r=jdaggett
authorVladimir Vukicevic <vladimir@pobox.com>
Mon, 12 Jan 2009 11:23:41 -0800
changeset 23553 da0a0796090fad74500b59ffab6e8de148e5df07
parent 23552 19757a81c07cba3e89613c2da7bbb8901da036c6
child 23554 61ca5667346845391496df48802cb4a83a8f87e0
push id4601
push uservladimir@mozilla.com
push dateMon, 12 Jan 2009 19:24:05 +0000
treeherdermozilla-central@da0a0796090f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjdaggett
bugs455243
milestone1.9.2a1pre
b=455243, weird behaviour with fonts with bad faces; r=jdaggett
gfx/thebes/src/gfxQuartzFontCache.h
gfx/thebes/src/gfxQuartzFontCache.mm
--- a/gfx/thebes/src/gfxQuartzFontCache.h
+++ b/gfx/thebes/src/gfxQuartzFontCache.h
@@ -60,26 +60,28 @@ struct FontSearch {
     const PRUint32 ch;
     gfxFont *fontToMatch;
     PRInt32 matchRank;
     nsRefPtr<MacOSFontEntry> bestMatch;
 };
 
 class MacOSFamilyEntry;
 class gfxQuartzFontCache;
+class FontEntryStandardFaceComparator;
 
 // a single member of a font family (i.e. a single face, such as Times Italic)
 class MacOSFontEntry : public gfxFontEntry
 {
 public:
     friend class gfxQuartzFontCache;
+    friend class FontEntryStandardFaceComparator;
 
     // initialize with Apple-type weight [1..14]
     MacOSFontEntry(const nsAString& aPostscriptName, PRInt32 aAppleWeight, PRUint32 aTraits, 
-                    MacOSFamilyEntry *aFamily);
+                   MacOSFamilyEntry *aFamily, PRBool aIsStandardFace = PR_FALSE);
 
     const nsString& FamilyName();
 
     PRUint32 Traits() { return mTraits; }
     
     ATSUFontID GetFontID();
     nsresult ReadCMAP();
 
@@ -89,16 +91,17 @@ protected:
                    PRUint16 aWeight, PRUint16 aStretch, PRUint32 aItalicStyle,
                    gfxUserFontData *aUserFontData);
 
     PRUint32 mTraits;
     MacOSFamilyEntry *mFamily;
 
     ATSUFontID mATSUFontID;
     PRPackedBool mATSUIDInitialized;
+    PRPackedBool mStandardFace;
 };
 
 // helper class for adding other family names back into font cache
 class AddOtherFamilyNameFunctor;
 
 // a single font family, referencing one or more faces 
 class MacOSFamilyEntry : public gfxFontFamily
 {
@@ -146,16 +149,19 @@ public:
 
     // set whether this font family is in "bad" underline offset blacklist.
     void SetBadUnderlineFont(PRBool aIsBadUnderlineFont) {
         PRUint32 i, numFonts = mAvailableFonts.Length();
         for (i = 0; i < numFonts; i++)
             mAvailableFonts[i]->mIsBadUnderlineFont = aIsBadUnderlineFont;
     }
 
+    // sort available fonts to put less-desirable faces towards the end
+    void SortAvailableFonts();
+
 protected:
     
     // add font entries into array that match specified traits, returned in array listed by weight
     // i.e. aFontsForWeights[4] ==> pointer to the font entry for a 400-weight face on return
     // returns true if one or more faces found
     PRBool FindFontsWithTraits(gfxFontEntry* aFontsForWeights[], PRUint32 aPosTraitsMask, 
                                 PRUint32 aNegTraitsMask);
 
--- a/gfx/thebes/src/gfxQuartzFontCache.mm
+++ b/gfx/thebes/src/gfxQuartzFontCache.mm
@@ -113,19 +113,20 @@ gfxQuartzFontCache::GenerateFontListKey(
     aResult = aKeyName;
     ToLowerCase(aResult);
 }
 
 /* MacOSFontEntry */
 #pragma mark-
 
 MacOSFontEntry::MacOSFontEntry(const nsAString& aPostscriptName, 
-                               PRInt32 aAppleWeight, PRUint32 aTraits, MacOSFamilyEntry *aFamily)
+                               PRInt32 aAppleWeight, PRUint32 aTraits, MacOSFamilyEntry *aFamily,
+                               PRBool aIsStandardFace)
     : gfxFontEntry(aPostscriptName), mTraits(aTraits), mFamily(aFamily), mATSUFontID(0),
-        mATSUIDInitialized(0)
+      mATSUIDInitialized(0), mStandardFace(aIsStandardFace)
 {
     mWeight = gfxQuartzFontCache::AppleWeightToCSSWeight(aAppleWeight) * 100;
 
     mItalic = (mTraits & NSItalicFontMask ? 1 : 0);
     mFixedPitch = (mTraits & NSFixedPitchFontMask ? 1 : 0);
 }
 
 MacOSFontEntry::MacOSFontEntry(const nsAString& aPostscriptName, ATSUFontID aFontID,
@@ -142,25 +143,28 @@ MacOSFontEntry::MacOSFontEntry(const nsA
     mFixedPitch = PR_FALSE; // xxx - do we need this for downloaded fonts?
     mItalic = (aItalicStyle & (FONT_STYLE_ITALIC | FONT_STYLE_OBLIQUE)) != 0;
     
     mTraits = (mItalic ? NSItalicFontMask : NSUnitalicFontMask) |
               (mFixedPitch ? NSFixedPitchFontMask : 0) |
               (mWeight >= 600 ? NSBoldFontMask : NSUnboldFontMask);
 
     mName = aPostscriptName;
+
+    mStandardFace = PR_FALSE;
 }
 
 const nsString& 
 MacOSFontEntry::FamilyName()
 {
     return mFamily->Name();
 }
 
-ATSUFontID MacOSFontEntry::GetFontID() 
+ATSUFontID
+MacOSFontEntry::GetFontID() 
 {
     if (!mATSUIDInitialized) {
         mATSUIDInitialized = PR_TRUE;
         NSString *psname = GetNSStringForString(mName);
         NSFont *font = [NSFont fontWithName:psname size:0.0];
         if (font) mATSUFontID = [font _atsFontID];
     }
     return mATSUFontID; 
@@ -486,16 +490,33 @@ MacOSFamilyEntry::FindWeightsForStyle(gf
     if (!found) {
         found = FindFontsWithTraits(aFontsForWeights, 0, 0);
     }
     NS_ASSERTION(found, "Font family containing no faces");
 
     return found;
 }
 
+class FontEntryStandardFaceComparator {
+  public:
+    PRBool Equals(const nsRefPtr<MacOSFontEntry>& a, const nsRefPtr<MacOSFontEntry>& b) const {
+        return a->mStandardFace == b->mStandardFace;
+    }
+    PRBool LessThan(const nsRefPtr<MacOSFontEntry>& a, const nsRefPtr<MacOSFontEntry>& b) const {
+        return (a->mStandardFace == PR_TRUE && b->mStandardFace == PR_FALSE);
+    }
+};
+
+void
+MacOSFamilyEntry::SortAvailableFonts()
+{
+    mAvailableFonts.Sort(FontEntryStandardFaceComparator());
+}
+
+
 static NSString* CreateNameFromBuffer(const UInt8 *aBuf, ByteCount aLength, 
         FontPlatformCode aPlatformCode, FontScriptCode aScriptCode, FontLanguageCode aLangCode)
 {
     CFStringRef outName = NULL;
 
     if (aPlatformCode == kFontMacintoshPlatform) {
         TextEncoding encoding;
         OSStatus err = GetTextEncodingFromScriptInfo(aScriptCode, aLangCode, 
@@ -730,37 +751,51 @@ gfxQuartzFontCache::InitFontList()
         int faceCount = [fontfaces count];
         int faceIndex;
 
         for (faceIndex = 0; faceIndex < faceCount; faceIndex++) {
             NSArray *face = [fontfaces objectAtIndex:faceIndex];
             NSString *psname = [face objectAtIndex:INDEX_FONT_POSTSCRIPT_NAME];
             PRInt32 weight = [[face objectAtIndex:INDEX_FONT_WEIGHT] unsignedIntValue];
             PRUint32 traits = [[face objectAtIndex:INDEX_FONT_TRAITS] unsignedIntValue];
-            
+            NSString *facename = [face objectAtIndex:INDEX_FONT_FACE_NAME];
+            PRBool isStandardFace = PR_FALSE;
+
             // 10.5 doesn't set NSUnitalicFontMask and NSUnboldFontMask - manually set these for consistency 
             if (!(traits & NSBoldFontMask))
                 traits |= NSUnboldFontMask;
             if (!(traits & NSItalicFontMask))
                 traits |= NSUnitalicFontMask;
             
             PR_LOG(gFontInfoLog, PR_LOG_DEBUG, ("(fontinit) family: %s, psname: %s, face: %s, apple-weight: %d, css-weight: %d, traits: %8.8x\n", 
-                [availableFamily UTF8String], [psname UTF8String], [[face objectAtIndex:INDEX_FONT_FACE_NAME] UTF8String], weight, gfxQuartzFontCache::AppleWeightToCSSWeight(weight), traits));
+                [availableFamily UTF8String], [psname UTF8String], [facename UTF8String], weight, gfxQuartzFontCache::AppleWeightToCSSWeight(weight), traits));
 
             // make a nsString
             GetStringForNSString(psname, postscriptFontName);
-        
+
+            if ([facename isEqualToString:@"Regular"] ||
+                [facename isEqualToString:@"Bold"] ||
+                [facename isEqualToString:@"Italic"] ||
+                [facename isEqualToString:@"Oblique"] ||
+                [facename isEqualToString:@"Bold Italic"] ||
+                [facename isEqualToString:@"Bold Oblique"])
+            {
+                isStandardFace = PR_TRUE;
+            }
+
             // create a font entry
-            MacOSFontEntry *fontEntry = new MacOSFontEntry(postscriptFontName, weight, traits, familyEntry);
+            MacOSFontEntry *fontEntry = new MacOSFontEntry(postscriptFontName, weight, traits, familyEntry, isStandardFace);
             if (!fontEntry) break;            
             
             // insert into font entry array of family
             familyEntry->AddFontEntry(fontEntry);
         }
-        
+
+        familyEntry->SortAvailableFonts();
+
         // add the family entry to the hash table
         ToLowerCase(availableFamilyName);
         mFontFamilies.Put(availableFamilyName, familyEntry);
     }
 
     InitSingleFaceList();
 
     // to avoid full search of font name tables, seed the other names table with localized names from