From 64b1e11538a6983c2411c85289cf4769d91da140 Mon Sep 17 00:00:00 2001 From: "pavlov@pavlov.net" Date: Fri, 14 Mar 2008 16:02:32 -0700 Subject: [PATCH] bug 396315. Fixing type1 fonts on Windows. r=vlad --- gfx/thebes/public/gfxWindowsFonts.h | 2 +- gfx/thebes/src/gfxWindowsFonts.cpp | 50 +++++++++++++++++++++++---- gfx/thebes/src/gfxWindowsPlatform.cpp | 8 +++-- 3 files changed, 50 insertions(+), 10 deletions(-) diff --git a/gfx/thebes/public/gfxWindowsFonts.h b/gfx/thebes/public/gfxWindowsFonts.h index 7a698191e10..7b284da9b0c 100644 --- a/gfx/thebes/public/gfxWindowsFonts.h +++ b/gfx/thebes/public/gfxWindowsFonts.h @@ -71,7 +71,7 @@ public: PRBool IsCrappyFont() const { /* return if it is a bitmap not a unicode font */ - return (!mUnicodeFont || mSymbolFont); + return (!mUnicodeFont || mSymbolFont || mIsType1); } PRBool MatchesGenericFamily(const nsACString& aGeneric) const { diff --git a/gfx/thebes/src/gfxWindowsFonts.cpp b/gfx/thebes/src/gfxWindowsFonts.cpp index 7d8119b6656..bf50cbb4c44 100644 --- a/gfx/thebes/src/gfxWindowsFonts.cpp +++ b/gfx/thebes/src/gfxWindowsFonts.cpp @@ -1035,9 +1035,16 @@ public: } PRBool IsGlyphMissing(SCRIPT_FONTPROPERTIES *aSFP, PRUint32 aGlyphIndex) { - if (mGlyphs[aGlyphIndex] == aSFP->wgDefault) - return PR_TRUE; - return PR_FALSE; + PRBool missing = PR_FALSE; + if (GetCurrentFont()->GetFontEntry()->mIsType1) { + // Missing glyphs for type1 fonts will be marked as 0xFFFF. So + // just look for that. aSFP->wgDefault isn't reliable for them. + if (mGlyphs[aGlyphIndex] == 0xFFFF) + missing = PR_TRUE; + } else if (mGlyphs[aGlyphIndex] == aSFP->wgDefault) { + missing = PR_TRUE; + } + return missing; } @@ -1286,10 +1293,39 @@ public: mRangeLength = mRanges[i].Length(); } - static inline FontEntry *WhichFontSupportsChar(const nsTArray >& fonts, PRUint32 ch) { + PRBool HasCharacter(FontEntry *aFontEntry, PRUint32 ch) { + if (aFontEntry->mCharacterMap.test(ch)) + return PR_TRUE; + + if (aFontEntry->mIsType1) { + if (ch > 0xFFFF) + return PR_FALSE; + + nsRefPtr font = GetOrMakeFont(aFontEntry, mGroup->GetStyle()); + + HDC dc = GetDC((HWND)nsnull); + HFONT hfont = font->GetHFONT(); + SelectObject(dc, hfont); + + PRUnichar str[1] = { (PRUnichar)ch }; + WORD glyph[1]; + + DWORD ret = GetGlyphIndicesW(dc, str, 1, glyph, GGI_MARK_NONEXISTING_GLYPHS); + + ReleaseDC(NULL, dc); + if (ret != GDI_ERROR && glyph[0] != 0xFFFF) { + aFontEntry->mCharacterMap.set(ch); + return PR_TRUE; + } + } + + return PR_FALSE; + } + + inline FontEntry *WhichFontSupportsChar(const nsTArray >& fonts, PRUint32 ch) { for (PRUint32 i = 0; i < fonts.Length(); i++) { nsRefPtr fe = fonts[i]; - if (fe->mCharacterMap.test(ch)) + if (HasCharacter(fe, ch)) return fe; } return nsnull; @@ -1308,7 +1344,7 @@ public: // if this character or the next one is a joiner use the // same font as the previous range if we can if (IsJoiner(ch) || IsJoiner(prevCh) || IsJoiner(nextCh)) { - if (aFont && aFont->mCharacterMap.test(ch)) + if (aFont && HasCharacter(aFont, ch)) return aFont; } @@ -1359,7 +1395,7 @@ public: } // before searching for something else check the font used for the previous character - if (!selectedFont && aFont && aFont->mCharacterMap.test(ch)) + if (!selectedFont && aFont && HasCharacter(aFont, ch)) selectedFont = aFont; // otherwise look for other stuff diff --git a/gfx/thebes/src/gfxWindowsPlatform.cpp b/gfx/thebes/src/gfxWindowsPlatform.cpp index e75951fe074..6c8250a1912 100644 --- a/gfx/thebes/src/gfxWindowsPlatform.cpp +++ b/gfx/thebes/src/gfxWindowsPlatform.cpp @@ -211,9 +211,13 @@ gfxWindowsPlatform::FontGetCMapDataProc(nsStringHashKey::KeyType aKey, nsresult rv = ReadCMAP(hdc, aFontEntry); if (NS_FAILED(rv)) { + // Type1 fonts aren't necessarily Unicode but + // this is the best guess we can make here if (aFontEntry->mIsType1) - aFontEntry->mSymbolFont = PR_TRUE; - aFontEntry->mUnicodeFont = PR_FALSE; + aFontEntry->mUnicodeFont = PR_TRUE; + else + aFontEntry->mUnicodeFont = PR_FALSE; + //printf("%d, %s failed to get cmap\n", aFontEntry->mIsType1, NS_ConvertUTF16toUTF8(aFontEntry->mName).get()); }