bug 627840 - (DirectWrite) only check for bitmaps in CJK fonts. r=masayuki a=joe
authorJonathan Kew <jfkthame@gmail.com>
Tue, 25 Jan 2011 09:17:18 +0000
changeset 61260 c93381b53df3c59c3be379d247d5663bc796db99
parent 61259 4568082aec55e3d6798526563ba2294b3f7b0d2e
child 61261 fa9b50ad86a60ae7fc4e2ccfd18a27f9d20010bf
push id18280
push userjkew@mozilla.com
push dateTue, 25 Jan 2011 09:18:57 +0000
treeherdermozilla-central@c93381b53df3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmasayuki, joe
bugs627840
milestone2.0b10pre
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 627840 - (DirectWrite) only check for bitmaps in CJK fonts. r=masayuki a=joe
gfx/thebes/gfxDWriteFontList.cpp
gfx/thebes/gfxDWriteFontList.h
gfx/thebes/gfxDWriteFonts.cpp
--- a/gfx/thebes/gfxDWriteFontList.cpp
+++ b/gfx/thebes/gfxDWriteFontList.cpp
@@ -45,16 +45,18 @@
 #include "nsIPrefService.h"
 #include "nsIPrefBranch2.h"
 #include "nsServiceManagerUtils.h"
 
 #include "gfxGDIFontList.h"
 
 #include "nsIWindowsRegKey.h"
 
+using namespace mozilla;
+
 #ifdef PR_LOGGING
 
 #define LOG_FONTLIST(args) PR_LOG(gfxPlatform::GetLog(eGfxLog_fontlist), \
                                PR_LOG_DEBUG, args)
 #define LOG_FONTLIST_ENABLED() PR_LOG_TEST( \
                                    gfxPlatform::GetLog(eGfxLog_fontlist), \
                                    PR_LOG_DEBUG)
 
@@ -428,16 +430,51 @@ gfxDWriteFontEntry::InitLogFont(IDWriteF
 
     BOOL isInSystemCollection;
     IDWriteGdiInterop *gdi = 
         gfxDWriteFontList::PlatformFontList()->GetGDIInterop();
     hr = gdi->ConvertFontToLOGFONT(aFont, aLogFont, &isInSystemCollection);
     return (FAILED(hr) ? PR_FALSE : PR_TRUE);
 }
 
+PRBool
+gfxDWriteFontEntry::IsCJKFont()
+{
+    if (mIsCJK != UNINITIALIZED_VALUE) {
+        return mIsCJK;
+    }
+
+    mIsCJK = PR_FALSE;
+
+    const PRUint32 kOS2Tag = TRUETYPE_TAG('O','S','/','2');
+    AutoFallibleTArray<PRUint8,128> buffer;
+    if (GetFontTable(kOS2Tag, buffer) != NS_OK) {
+        return mIsCJK;
+    }
+
+    // ulCodePageRange bit definitions for the CJK codepages,
+    // from http://www.microsoft.com/typography/otspec/os2.htm#cpr
+    const PRUint32 CJK_CODEPAGE_BITS =
+        (1 << 17) | // codepage 932 - JIS/Japan
+        (1 << 18) | // codepage 936 - Chinese (simplified)
+        (1 << 19) | // codepage 949 - Korean Wansung
+        (1 << 20) | // codepage 950 - Chinese (traditional)
+        (1 << 21);  // codepage 1361 - Korean Johab
+
+    if (buffer.Length() >= offsetof(OS2Table, sxHeight)) {
+        const OS2Table* os2 =
+            reinterpret_cast<const OS2Table*>(buffer.Elements());
+        if ((PRUint32(os2->codePageRange1) & CJK_CODEPAGE_BITS) != 0) {
+            mIsCJK = PR_TRUE;
+        }
+    }
+
+    return mIsCJK;
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // gfxDWriteFontList
 
 gfxDWriteFontList::gfxDWriteFontList()
     : mInitialized(PR_FALSE)
 {
     mFontSubstitutes.Init();
 }
--- a/gfx/thebes/gfxDWriteFontList.h
+++ b/gfx/thebes/gfxDWriteFontList.h
@@ -98,18 +98,19 @@ public:
     {
         mItalic = (aFont->GetStyle() == DWRITE_FONT_STYLE_ITALIC ||
                    aFont->GetStyle() == DWRITE_FONT_STYLE_OBLIQUE);
         mStretch = FontStretchFromDWriteStretch(aFont->GetStretch());
         PRUint16 weight = PR_ROUNDUP(aFont->GetWeight() - 50, 100);
 
         weight = NS_MAX<PRUint16>(100, weight);
         weight = NS_MIN<PRUint16>(900, weight);
+        mWeight = weight;
 
-        mWeight = weight;
+        mIsCJK = UNINITIALIZED_VALUE;
     }
 
     /**
      * Constructs a font entry using a font. But with custom font values.
      * This is used for creating correct font entries for @font-face with local
      * font source.
      *
      * \param aFaceName The name of the corresponding font face.
@@ -125,16 +126,17 @@ public:
                               PRBool aItalic)
       : gfxFontEntry(aFaceName), mFont(aFont), mFontFile(nsnull)
     {
         mWeight = aWeight;
         mStretch = aStretch;
         mItalic = aItalic;
         mIsUserFont = PR_TRUE;
         mIsLocalUserFont = PR_TRUE;
+        mIsCJK = UNINITIALIZED_VALUE;
     }
 
     /**
      * Constructs a font entry using a font file.
      *
      * \param aFaceName The name of the corresponding font face.
      * \param aFontFile DirectWrite fontfile object
      * \param aWeight Weight of the font
@@ -147,26 +149,30 @@ public:
                               PRInt16 aStretch,
                               PRBool aItalic)
       : gfxFontEntry(aFaceName), mFont(nsnull), mFontFile(aFontFile)
     {
         mWeight = aWeight;
         mStretch = aStretch;
         mItalic = aItalic;
         mIsUserFont = PR_TRUE;
+        mIsCJK = UNINITIALIZED_VALUE;
     }
 
     virtual ~gfxDWriteFontEntry();
 
     virtual PRBool IsSymbolFont();
 
     virtual nsresult GetFontTable(PRUint32 aTableTag,
                                   FallibleTArray<PRUint8>& aBuffer);
 
     nsresult ReadCMAP();
+
+    PRBool IsCJKFont();
+
 protected:
     friend class gfxDWriteFont;
     friend class gfxDWriteFontList;
 
     virtual gfxFont *CreateFontInstance(const gfxFontStyle *aFontStyle,
                                         PRBool aNeedsBold);
     
     nsresult CreateFontFace(
@@ -177,16 +183,18 @@ protected:
 
     /**
      * A fontentry only needs to have either of these. If it has both only
      * the IDWriteFont will be used.
      */
     nsRefPtr<IDWriteFont> mFont;
     nsRefPtr<IDWriteFontFile> mFontFile;
     DWRITE_FONT_FACE_TYPE mFaceType;
+
+    PRBool mIsCJK;
 };
 
 
 class gfxDWriteFontList : public gfxPlatformFontList {
 public:
     gfxDWriteFontList();
 
     static gfxDWriteFontList* PlatformFontList() {
--- a/gfx/thebes/gfxDWriteFonts.cpp
+++ b/gfx/thebes/gfxDWriteFonts.cpp
@@ -220,17 +220,19 @@ gfxDWriteFont::ComputeMetrics()
     if (mStyle.sizeAdjust != 0.0) {
         gfxFloat aspect = (gfxFloat)fontMetrics.xHeight /
                    fontMetrics.designUnitsPerEm;
         mAdjustedSize = mStyle.GetAdjustedSize(aspect);
     } else {
         mAdjustedSize = mStyle.size;
     }
 
-    if (HasBitmapStrikeForSize(NS_lround(mAdjustedSize))) {
+    gfxDWriteFontEntry *fe =
+        static_cast<gfxDWriteFontEntry*>(mFontEntry.get());
+    if (fe->IsCJKFont() && HasBitmapStrikeForSize(NS_lround(mAdjustedSize))) {
         mAdjustedSize = NS_lround(mAdjustedSize);
         mUseSubpixelPositions = PR_FALSE;
         // if we have bitmaps, we need to tell Cairo NOT to use subpixel AA,
         // to avoid the manual-subpixel codepath in cairo-d2d-surface.cpp
         // which fails to render bitmap glyphs (see bug 626299)
         if (mAntialiasOption == kAntialiasDefault && UsingClearType()) {
             mAntialiasOption = kAntialiasGrayscale;
         }