Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(363)

Unified Diff: webkit/port/platform/graphics/FontUtilsWin.cpp

Issue 10785: Debase our Uniscribe code. This moves FontUtils and all our Uniscribe code fr... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 12 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: webkit/port/platform/graphics/FontUtilsWin.cpp
===================================================================
--- webkit/port/platform/graphics/FontUtilsWin.cpp (revision 5490)
+++ webkit/port/platform/graphics/FontUtilsWin.cpp (working copy)
@@ -2,19 +2,22 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/gfx/font_utils.h"
+#include "config.h"
+#include "FontUtilsWin.h"
+#include "UniscribeHelper.h"
+
#include <limits>
#include <map>
-#include "base/gfx/uniscribe.h"
+
#include "base/logging.h"
#include "base/singleton.h"
#include "base/string_util.h"
#include "unicode/locid.h"
#include "unicode/uchar.h"
-namespace gfx {
+namespace WebCore {
namespace {
@@ -23,82 +26,83 @@
// more scripts are added) and this turns out to be prominent in the profile, we
// may consider switching to hash_map (or just an array if we support all the
// scripts)
-typedef std::map<UScriptCode, const wchar_t*> ScriptToFontMap;
+typedef std::map<UScriptCode, const UChar*> ScriptToFontMap;
struct ScriptToFontMapSingletonTraits
: public DefaultSingletonTraits<ScriptToFontMap> {
- static ScriptToFontMap* New() {
- struct FontMap {
- UScriptCode script;
- const wchar_t* family;
- };
+ static ScriptToFontMap* New() {
+ struct FontMap {
+ UScriptCode script;
+ const UChar* family;
+ };
- const static FontMap font_map[] = {
- {USCRIPT_LATIN, L"times new roman"},
- {USCRIPT_GREEK, L"times new roman"},
- {USCRIPT_CYRILLIC, L"times new roman"},
- {USCRIPT_SIMPLIFIED_HAN, L"simsun"},
- //{USCRIPT_TRADITIONAL_HAN, L"pmingliu"},
- {USCRIPT_HIRAGANA, L"ms pgothic"},
- {USCRIPT_KATAKANA, L"ms pgothic"},
- {USCRIPT_KATAKANA_OR_HIRAGANA, L"ms pgothic"},
- {USCRIPT_HANGUL, L"gulim"},
- {USCRIPT_THAI, L"tahoma"},
- {USCRIPT_HEBREW, L"david"},
- {USCRIPT_ARABIC, L"tahoma"},
- {USCRIPT_DEVANAGARI, L"mangal"},
- {USCRIPT_BENGALI, L"vrinda"},
- {USCRIPT_GURMUKHI, L"raavi"},
- {USCRIPT_GUJARATI, L"shruti"},
- {USCRIPT_ORIYA, L"kalinga"},
- {USCRIPT_TAMIL, L"latha"},
- {USCRIPT_TELUGU, L"gautami"},
- {USCRIPT_KANNADA, L"tunga"},
- {USCRIPT_MALAYALAM, L"kartika"},
- {USCRIPT_LAO, L"dokchampa"},
- {USCRIPT_TIBETAN, L"microsoft himalaya"},
- {USCRIPT_GEORGIAN, L"sylfaen"},
- {USCRIPT_ARMENIAN, L"sylfaen"},
- {USCRIPT_ETHIOPIC, L"nyala"},
- {USCRIPT_CANADIAN_ABORIGINAL, L"euphemia"},
- {USCRIPT_CHEROKEE, L"plantagenet cherokee"},
- {USCRIPT_YI, L"microsoft yi balti"},
- {USCRIPT_SINHALA, L"iskoola pota"},
- {USCRIPT_SYRIAC, L"estrangelo edessa"},
- {USCRIPT_KHMER, L"daunpenh"},
- {USCRIPT_THAANA, L"mv boli"},
- {USCRIPT_MONGOLIAN, L"mongolian balti"},
- {USCRIPT_MYANMAR, L"padauk"},
- // For USCRIPT_COMMON, we map blocks to scripts when
- // that makes sense.
- };
+ const static FontMap font_map[] = {
+ {USCRIPT_LATIN, L"times new roman"},
+ {USCRIPT_GREEK, L"times new roman"},
+ {USCRIPT_CYRILLIC, L"times new roman"},
+ {USCRIPT_SIMPLIFIED_HAN, L"simsun"},
+ //{USCRIPT_TRADITIONAL_HAN, L"pmingliu"},
+ {USCRIPT_HIRAGANA, L"ms pgothic"},
+ {USCRIPT_KATAKANA, L"ms pgothic"},
+ {USCRIPT_KATAKANA_OR_HIRAGANA, L"ms pgothic"},
+ {USCRIPT_HANGUL, L"gulim"},
+ {USCRIPT_THAI, L"tahoma"},
+ {USCRIPT_HEBREW, L"david"},
+ {USCRIPT_ARABIC, L"tahoma"},
+ {USCRIPT_DEVANAGARI, L"mangal"},
+ {USCRIPT_BENGALI, L"vrinda"},
+ {USCRIPT_GURMUKHI, L"raavi"},
+ {USCRIPT_GUJARATI, L"shruti"},
+ {USCRIPT_ORIYA, L"kalinga"},
+ {USCRIPT_TAMIL, L"latha"},
+ {USCRIPT_TELUGU, L"gautami"},
+ {USCRIPT_KANNADA, L"tunga"},
+ {USCRIPT_MALAYALAM, L"kartika"},
+ {USCRIPT_LAO, L"dokchampa"},
+ {USCRIPT_TIBETAN, L"microsoft himalaya"},
+ {USCRIPT_GEORGIAN, L"sylfaen"},
+ {USCRIPT_ARMENIAN, L"sylfaen"},
+ {USCRIPT_ETHIOPIC, L"nyala"},
+ {USCRIPT_CANADIAN_ABORIGINAL, L"euphemia"},
+ {USCRIPT_CHEROKEE, L"plantagenet cherokee"},
+ {USCRIPT_YI, L"microsoft yi balti"},
+ {USCRIPT_SINHALA, L"iskoola pota"},
+ {USCRIPT_SYRIAC, L"estrangelo edessa"},
+ {USCRIPT_KHMER, L"daunpenh"},
+ {USCRIPT_THAANA, L"mv boli"},
+ {USCRIPT_MONGOLIAN, L"mongolian balti"},
+ {USCRIPT_MYANMAR, L"padauk"},
+ // For USCRIPT_COMMON, we map blocks to scripts when
+ // that makes sense.
+ };
- ScriptToFontMap* new_instance = new ScriptToFontMap;
- // Cannot recover from OOM so that there's no need to check.
- for (int i = 0; i < arraysize(font_map); ++i)
- (*new_instance)[font_map[i].script] = font_map[i].family;
+ ScriptToFontMap* new_instance = new ScriptToFontMap;
+ // Cannot recover from OOM so that there's no need to check.
+ for (int i = 0; i < arraysize(font_map); ++i)
+ (*new_instance)[font_map[i].script] = font_map[i].family;
- // Initialize the locale-dependent mapping.
- // Since Chrome synchronizes the ICU default locale with its UI locale,
- // this ICU locale tells the current UI locale of Chrome.
- Locale locale = Locale::getDefault();
- ScriptToFontMap::const_iterator iter;
- if (locale == Locale::getJapanese()) {
- iter = new_instance->find(USCRIPT_HIRAGANA);
- } else if (locale == Locale::getKorean()) {
- iter = new_instance->find(USCRIPT_HANGUL);
- } else {
- // Use Simplified Chinese font for all other locales including
- // Traditional Chinese because Simsun (SC font) has a wider
- // coverage (covering both SC and TC) than PMingLiu (TC font).
- // This also speeds up the TC version of Chrome when rendering SC pages.
- iter = new_instance->find(USCRIPT_SIMPLIFIED_HAN);
+ // Initialize the locale-dependent mapping.
+ // Since Chrome synchronizes the ICU default locale with its UI locale,
+ // this ICU locale tells the current UI locale of Chrome.
+ Locale locale = Locale::getDefault();
+ ScriptToFontMap::const_iterator iter;
+ if (locale == Locale::getJapanese()) {
+ iter = new_instance->find(USCRIPT_HIRAGANA);
+ } else if (locale == Locale::getKorean()) {
+ iter = new_instance->find(USCRIPT_HANGUL);
+ } else {
+ // Use Simplified Chinese font for all other locales including
+ // Traditional Chinese because Simsun (SC font) has a wider
+ // coverage (covering both SC and TC) than PMingLiu (TC font).
+ // This also speeds up the TC version of Chrome when rendering SC
+ // pages.
+ iter = new_instance->find(USCRIPT_SIMPLIFIED_HAN);
+ }
+ if (iter != new_instance->end())
+ (*new_instance)[USCRIPT_HAN] = iter->second;
+
+ return new_instance;
}
- if (iter != new_instance->end())
- (*new_instance)[USCRIPT_HAN] = iter->second;
-
- return new_instance;
- }
};
Singleton<ScriptToFontMap, ScriptToFontMapSingletonTraits> script_font_map;
@@ -108,20 +112,20 @@
// Given an HFONT, return the ascent. If GetTextMetrics fails,
// kUndefinedAscent is returned, instead.
int GetAscent(HFONT hfont) {
- HDC dc = GetDC(NULL);
- HGDIOBJ oldFont = SelectObject(dc, hfont);
- TEXTMETRIC tm;
- BOOL got_metrics = GetTextMetrics(dc, &tm);
- SelectObject(dc, oldFont);
- ReleaseDC(NULL, dc);
- return got_metrics ? tm.tmAscent : kUndefinedAscent;
+ HDC dc = GetDC(NULL);
+ HGDIOBJ oldFont = SelectObject(dc, hfont);
+ TEXTMETRIC tm;
+ BOOL got_metrics = GetTextMetrics(dc, &tm);
+ SelectObject(dc, oldFont);
+ ReleaseDC(NULL, dc);
+ return got_metrics ? tm.tmAscent : kUndefinedAscent;
}
struct FontData {
- FontData() : hfont(NULL), ascent(kUndefinedAscent), script_cache(NULL) {}
- HFONT hfont;
- int ascent;
- mutable SCRIPT_CACHE script_cache;
+ FontData() : hfont(NULL), ascent(kUndefinedAscent), script_cache(NULL) {}
+ HFONT hfont;
+ int ascent;
+ mutable SCRIPT_CACHE script_cache;
};
// Again, using hash_map does not earn us much here.
@@ -132,17 +136,17 @@
typedef std::map<std::wstring, FontData*> FontDataCache;
struct FontDataCacheSingletonTraits
: public DefaultSingletonTraits<FontDataCache> {
- static void Delete(FontDataCache* cache) {
- FontDataCache::iterator iter = cache->begin();
- while (iter != cache->end()) {
- SCRIPT_CACHE script_cache = iter->second->script_cache;
- if (script_cache)
- ScriptFreeCache(&script_cache);
- delete iter->second;
- ++iter;
+ static void Delete(FontDataCache* cache) {
+ FontDataCache::iterator iter = cache->begin();
+ while (iter != cache->end()) {
+ SCRIPT_CACHE script_cache = iter->second->script_cache;
+ if (script_cache)
+ ScriptFreeCache(&script_cache);
+ delete iter->second;
+ ++iter;
+ }
+ delete cache;
}
- delete cache;
- }
};
} // namespace
@@ -162,14 +166,13 @@
// keep track of which character is supported by which font
// - Update script_font_cache in response to WM_FONTCHANGE
-const wchar_t* GetFontFamilyForScript(UScriptCode script,
- GenericFamilyType generic) {
- ScriptToFontMap::const_iterator iter = script_font_map->find(script);
- const wchar_t* family = NULL;
- if (iter != script_font_map->end()) {
- family = iter->second;
- }
- return family;
+const UChar* GetFontFamilyForScript(UScriptCode script,
+ GenericFamilyType generic) {
+ ScriptToFontMap::const_iterator iter = script_font_map->find(script);
+ const UChar* family = NULL;
+ if (iter != script_font_map->end())
+ family = iter->second;
+ return family;
}
// TODO(jungshik)
@@ -180,157 +183,157 @@
// and just return it.
// - All the characters (or characters up to the point a single
// font can cover) need to be taken into account
-const wchar_t* GetFallbackFamily(const wchar_t *characters,
- int length,
- GenericFamilyType generic,
- UChar32 *char_checked,
- UScriptCode *script_checked) {
- DCHECK(characters && characters[0] && length > 0);
- UScriptCode script = USCRIPT_COMMON;
+const UChar* GetFallbackFamily(const UChar *characters,
+ int length,
+ GenericFamilyType generic,
+ UChar32 *char_checked,
+ UScriptCode *script_checked) {
+ DCHECK(characters && characters[0] && length > 0);
+ UScriptCode script = USCRIPT_COMMON;
- // Sometimes characters common to script (e.g. space) is at
- // the beginning of a string so that we need to skip them
- // to get a font required to render the string.
- int i = 0;
- UChar32 ucs4 = 0;
- while (i < length && script == USCRIPT_COMMON ||
- script == USCRIPT_INVALID_CODE) {
- U16_NEXT(characters, i, length, ucs4);
- UErrorCode err = U_ZERO_ERROR;
- script = uscript_getScript(ucs4, &err);
- // silently ignore the error
- }
+ // Sometimes characters common to script (e.g. space) is at
+ // the beginning of a string so that we need to skip them
+ // to get a font required to render the string.
+ int i = 0;
+ UChar32 ucs4 = 0;
+ while (i < length && script == USCRIPT_COMMON ||
+ script == USCRIPT_INVALID_CODE) {
+ U16_NEXT(characters, i, length, ucs4);
+ UErrorCode err = U_ZERO_ERROR;
+ script = uscript_getScript(ucs4, &err);
+ // silently ignore the error
+ }
- // hack for full width ASCII. For the full-width ASCII, use the font
- // for Han (which is locale-dependent).
- if (0xFF00 < ucs4 && ucs4 < 0xFF5F)
- script = USCRIPT_HAN;
+ // hack for full width ASCII. For the full-width ASCII, use the font
+ // for Han (which is locale-dependent).
+ if (0xFF00 < ucs4 && ucs4 < 0xFF5F)
+ script = USCRIPT_HAN;
- // There are a lot of characters in USCRIPT_COMMON that can be covered
- // by fonts for scripts closely related to them.
- // See http://unicode.org/cldr/utility/list-unicodeset.jsp?a=[:Script=Common:]
- // TODO(jungshik): make this more efficient with a wider coverage
- if (script == USCRIPT_COMMON || script == USCRIPT_INHERITED) {
- UBlockCode block = ublock_getCode(ucs4);
- switch (block) {
- case UBLOCK_BASIC_LATIN:
- script = USCRIPT_LATIN;
- break;
- case UBLOCK_CJK_SYMBOLS_AND_PUNCTUATION:
- script = USCRIPT_HAN;
- break;
- case UBLOCK_HIRAGANA:
- case UBLOCK_KATAKANA:
- script = USCRIPT_HIRAGANA;
- break;
- case UBLOCK_ARABIC:
- script = USCRIPT_ARABIC;
- break;
- case UBLOCK_GREEK:
- script = USCRIPT_GREEK;
- break;
- case UBLOCK_DEVANAGARI:
- // For Danda and Double Danda (U+0964, U+0965), use a Devanagari
- // font for now although they're used by other scripts as well.
- // Without a context, we can't do any better.
- script = USCRIPT_DEVANAGARI;
- break;
- case UBLOCK_ARMENIAN:
- script = USCRIPT_ARMENIAN;
- break;
- case UBLOCK_GEORGIAN:
- script = USCRIPT_GEORGIAN;
- break;
- case UBLOCK_KANNADA:
- script = USCRIPT_KANNADA;
- break;
+ // There are a lot of characters in USCRIPT_COMMON that can be covered
+ // by fonts for scripts closely related to them. See
+ // http://unicode.org/cldr/utility/list-unicodeset.jsp?a=[:Script=Common:]
+ // TODO(jungshik): make this more efficient with a wider coverage
+ if (script == USCRIPT_COMMON || script == USCRIPT_INHERITED) {
+ UBlockCode block = ublock_getCode(ucs4);
+ switch (block) {
+ case UBLOCK_BASIC_LATIN:
+ script = USCRIPT_LATIN;
+ break;
+ case UBLOCK_CJK_SYMBOLS_AND_PUNCTUATION:
+ script = USCRIPT_HAN;
+ break;
+ case UBLOCK_HIRAGANA:
+ case UBLOCK_KATAKANA:
+ script = USCRIPT_HIRAGANA;
+ break;
+ case UBLOCK_ARABIC:
+ script = USCRIPT_ARABIC;
+ break;
+ case UBLOCK_GREEK:
+ script = USCRIPT_GREEK;
+ break;
+ case UBLOCK_DEVANAGARI:
+ // For Danda and Double Danda (U+0964, U+0965), use a Devanagari
+ // font for now although they're used by other scripts as well.
+ // Without a context, we can't do any better.
+ script = USCRIPT_DEVANAGARI;
+ break;
+ case UBLOCK_ARMENIAN:
+ script = USCRIPT_ARMENIAN;
+ break;
+ case UBLOCK_GEORGIAN:
+ script = USCRIPT_GEORGIAN;
+ break;
+ case UBLOCK_KANNADA:
+ script = USCRIPT_KANNADA;
+ break;
+ }
}
- }
- // Another lame work-around to cover non-BMP characters.
- const wchar_t* family = GetFontFamilyForScript(script, generic);
- if (!family) {
- int plane = ucs4 >> 16;
- switch (plane) {
- case 1:
- family = L"code2001";
- break;
- case 2:
- family = L"simsun-extb";
- break;
- default:
- family = L"lucida sans unicode";
+ // Another lame work-around to cover non-BMP characters.
+ const UChar* family = GetFontFamilyForScript(script, generic);
+ if (!family) {
+ int plane = ucs4 >> 16;
+ switch (plane) {
+ case 1:
+ family = L"code2001";
+ break;
+ case 2:
+ family = L"simsun-extb";
+ break;
+ default:
+ family = L"lucida sans unicode";
+ }
}
- }
- if (char_checked) *char_checked = ucs4;
- if (script_checked) *script_checked = script;
- return family;
+ if (char_checked) *char_checked = ucs4;
+ if (script_checked) *script_checked = script;
+ return family;
}
// Be aware that this is not thread-safe.
-bool GetDerivedFontData(const wchar_t *family,
+bool GetDerivedFontData(const UChar *family,
int style,
LOGFONT *logfont,
int *ascent,
HFONT *hfont,
SCRIPT_CACHE **script_cache) {
- DCHECK(logfont && family && *family);
- // Using |Singleton| here is not free, but the intl2 page cycler test
- // does not show any noticeable difference with and without it. Leaking
- // the contents of FontDataCache (especially SCRIPT_CACHE) at the end
- // of a renderer process may not be a good idea. We may use
- // atexit(). However, with no noticeable performance difference, |Singleton|
- // is cleaner, I believe.
- FontDataCache* font_data_cache =
- Singleton<FontDataCache, FontDataCacheSingletonTraits>::get();
- // TODO(jungshik) : This comes up pretty high in the profile so that
- // we need to measure whether using SHA256 (after coercing all the
- // fields to char*) is faster than StringPrintf.
- std::wstring font_key = StringPrintf(L"%1d:%d:%ls", style, logfont->lfHeight,
- family);
- FontDataCache::const_iterator iter = font_data_cache->find(font_key);
- FontData *derived;
- if (iter == font_data_cache->end()) {
- DCHECK(wcslen(family) < LF_FACESIZE);
- wcscpy_s(logfont->lfFaceName, LF_FACESIZE, family);
- // TODO(jungshik): CreateFontIndirect always comes up with
- // a font even if there's no font matching the name. Need to
- // check it against what we actually want (as is done in FontCacheWin.cpp)
- derived = new FontData;
- derived->hfont = CreateFontIndirect(logfont);
- // GetAscent may return kUndefinedAscent, but we still want to
- // cache it so that we won't have to call CreateFontIndirect once
- // more for HFONT next time.
- derived->ascent = GetAscent(derived->hfont);
- (*font_data_cache)[font_key] = derived;
- } else {
- derived = iter->second;
- // Last time, GetAscent failed so that only HFONT was
- // cached. Try once more assuming that TryPreloadFont
- // was called by a caller between calls.
- if (kUndefinedAscent == derived->ascent)
- derived->ascent = GetAscent(derived->hfont);
- }
- *hfont = derived->hfont;
- *ascent = derived->ascent;
- *script_cache = &(derived->script_cache);
- return *ascent != kUndefinedAscent;
+ DCHECK(logfont && family && *family);
+ // Using |Singleton| here is not free, but the intl2 page cycler test
+ // does not show any noticeable difference with and without it. Leaking
+ // the contents of FontDataCache (especially SCRIPT_CACHE) at the end
+ // of a renderer process may not be a good idea. We may use
+ // atexit(). However, with no noticeable performance difference, |Singleton|
+ // is cleaner, I believe.
+ FontDataCache* font_data_cache =
+ Singleton<FontDataCache, FontDataCacheSingletonTraits>::get();
+ // TODO(jungshik) : This comes up pretty high in the profile so that
+ // we need to measure whether using SHA256 (after coercing all the
+ // fields to char*) is faster than StringPrintf.
+ std::wstring font_key = StringPrintf(L"%1d:%d:%ls", style,
+ logfont->lfHeight, family);
+ FontDataCache::const_iterator iter = font_data_cache->find(font_key);
+ FontData *derived;
+ if (iter == font_data_cache->end()) {
+ DCHECK(wcslen(family) < LF_FACESIZE);
+ wcscpy_s(logfont->lfFaceName, LF_FACESIZE, family);
+ // TODO(jungshik): CreateFontIndirect always comes up with
+ // a font even if there's no font matching the name. Need to
+ // check it against what we actually want (as is done in
+ // FontCacheWin.cpp)
+ derived = new FontData;
+ derived->hfont = CreateFontIndirect(logfont);
+ // GetAscent may return kUndefinedAscent, but we still want to
+ // cache it so that we won't have to call CreateFontIndirect once
+ // more for HFONT next time.
+ derived->ascent = GetAscent(derived->hfont);
+ (*font_data_cache)[font_key] = derived;
+ } else {
+ derived = iter->second;
+ // Last time, GetAscent failed so that only HFONT was
+ // cached. Try once more assuming that TryPreloadFont
+ // was called by a caller between calls.
+ if (kUndefinedAscent == derived->ascent)
+ derived->ascent = GetAscent(derived->hfont);
+ }
+ *hfont = derived->hfont;
+ *ascent = derived->ascent;
+ *script_cache = &(derived->script_cache);
+ return *ascent != kUndefinedAscent;
}
int GetStyleFromLogfont(const LOGFONT* logfont) {
- // TODO(jungshik) : consider defining UNDEFINED or INVALID for style and
- // returning it when logfont is NULL
- if (!logfont) {
- NOTREACHED();
- return FONT_STYLE_NORMAL;
- }
- return (logfont->lfItalic ? FONT_STYLE_ITALIC : FONT_STYLE_NORMAL) |
- (logfont->lfUnderline ? FONT_STYLE_UNDERLINED : FONT_STYLE_NORMAL) |
- (logfont->lfWeight >= 700 ? FONT_STYLE_BOLD : FONT_STYLE_NORMAL);
+ // TODO(jungshik) : consider defining UNDEFINED or INVALID for style and
+ // returning it when logfont is NULL
+ if (!logfont) {
+ NOTREACHED();
+ return FONT_STYLE_NORMAL;
+ }
+ return (logfont->lfItalic ? FONT_STYLE_ITALIC : FONT_STYLE_NORMAL) |
+ (logfont->lfUnderline ? FONT_STYLE_UNDERLINED : FONT_STYLE_NORMAL) |
+ (logfont->lfWeight >= 700 ? FONT_STYLE_BOLD : FONT_STYLE_NORMAL);
}
-} // namespace gfx
-
+} // namespace WebCore
Property changes on: webkit\port\platform\graphics\FontUtilsWin.cpp
___________________________________________________________________
Added: svn:mergeinfo
Merged /branches/chrome_webkit_merge_branch/base/gfx/font_utils.cc:r69-2775

Powered by Google App Engine
This is Rietveld 408576698