diff --git a/gfx/thebes/gfxDWriteFontList.cpp b/gfx/thebes/gfxDWriteFontList.cpp index 88d7af7f0041..851faf6d9430 100644 --- a/gfx/thebes/gfxDWriteFontList.cpp +++ b/gfx/thebes/gfxDWriteFontList.cpp @@ -50,6 +50,8 @@ #include "nsIWindowsRegKey.h" +using namespace mozilla; + #ifdef PR_LOGGING #define LOG_FONTLIST(args) PR_LOG(gfxPlatform::GetLog(eGfxLog_fontlist), \ @@ -433,6 +435,41 @@ gfxDWriteFontEntry::InitLogFont(IDWriteFont *aFont, LOGFONTW *aLogFont) 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 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(buffer.Elements()); + if ((PRUint32(os2->codePageRange1) & CJK_CODEPAGE_BITS) != 0) { + mIsCJK = PR_TRUE; + } + } + + return mIsCJK; +} + //////////////////////////////////////////////////////////////////////////////// // gfxDWriteFontList diff --git a/gfx/thebes/gfxDWriteFontList.h b/gfx/thebes/gfxDWriteFontList.h index f07d7d29d99f..ad2ae5362c84 100644 --- a/gfx/thebes/gfxDWriteFontList.h +++ b/gfx/thebes/gfxDWriteFontList.h @@ -103,8 +103,9 @@ public: weight = NS_MAX(100, weight); weight = NS_MIN(900, weight); - mWeight = weight; + + mIsCJK = UNINITIALIZED_VALUE; } /** @@ -130,6 +131,7 @@ public: mItalic = aItalic; mIsUserFont = PR_TRUE; mIsLocalUserFont = PR_TRUE; + mIsCJK = UNINITIALIZED_VALUE; } /** @@ -152,6 +154,7 @@ public: mStretch = aStretch; mItalic = aItalic; mIsUserFont = PR_TRUE; + mIsCJK = UNINITIALIZED_VALUE; } virtual ~gfxDWriteFontEntry(); @@ -162,6 +165,9 @@ public: FallibleTArray& aBuffer); nsresult ReadCMAP(); + + PRBool IsCJKFont(); + protected: friend class gfxDWriteFont; friend class gfxDWriteFontList; @@ -182,6 +188,8 @@ protected: nsRefPtr mFont; nsRefPtr mFontFile; DWRITE_FONT_FACE_TYPE mFaceType; + + PRBool mIsCJK; }; diff --git a/gfx/thebes/gfxDWriteFonts.cpp b/gfx/thebes/gfxDWriteFonts.cpp index daac42153d6a..ba0ade37c7c1 100644 --- a/gfx/thebes/gfxDWriteFonts.cpp +++ b/gfx/thebes/gfxDWriteFonts.cpp @@ -225,7 +225,9 @@ gfxDWriteFont::ComputeMetrics() mAdjustedSize = mStyle.size; } - if (HasBitmapStrikeForSize(NS_lround(mAdjustedSize))) { + gfxDWriteFontEntry *fe = + static_cast(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,