10bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch/* 20bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch* Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. 30bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch* Copyright (C) 2007-2009 Torch Mobile, Inc. 40bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch* 50bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch* Redistribution and use in source and binary forms, with or without 60bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch* modification, are permitted provided that the following conditions 70bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch* are met: 80bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch* 90bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch* 1. Redistributions of source code must retain the above copyright 100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch* notice, this list of conditions and the following disclaimer. 110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch* 2. Redistributions in binary form must reproduce the above copyright 120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch* notice, this list of conditions and the following disclaimer in the 130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch* documentation and/or other materials provided with the distribution. 140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch* its contributors may be used to endorse or promote products derived 160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch* from this software without specific prior written permission. 170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch* 180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch*/ 290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "config.h" 310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "FontCache.h" 320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "Font.h" 340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "FontData.h" 350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "SimpleFontData.h" 360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "UnicodeRange.h" 370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "wtf/OwnPtr.h" 380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include <windows.h> 400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include <mlang.h> 410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochnamespace WebCore { 430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochextern HDC g_screenDC; 450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic IMultiLanguage *multiLanguage = 0; 470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#if defined(IMLANG_FONT_LINK) && (IMLANG_FONT_LINK == 2) 490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic IMLangFontLink2* langFontLink = 0; 500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#else 510bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic IMLangFontLink* langFontLink = 0; 520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif 530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 5406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian MonsenIMultiLanguage* FontCache::getMultiLanguageInterface() 550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (!multiLanguage) 570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch CoCreateInstance(CLSID_CMultiLanguage, 0, CLSCTX_INPROC_SERVER, IID_IMultiLanguage, (void**)&multiLanguage); 580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return multiLanguage; 600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#if defined(IMLANG_FONT_LINK) && (IMLANG_FONT_LINK == 2) 630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochIMLangFontLink2* FontCache::getFontLinkInterface() 640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#else 650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochIMLangFontLink* FontCache::getFontLinkInterface() 660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif 670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (!langFontLink) { 690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (IMultiLanguage* mli = getMultiLanguageInterface()) 700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch mli->QueryInterface(&langFontLink); 710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 730bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return langFontLink; 740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#if defined(IMLANG_FONT_LINK) && (IMLANG_FONT_LINK == 2) 770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic bool currentFontContainsCharacter(IMLangFontLink2* langFontLink, HDC hdc, UChar character) 780bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch UINT unicodeRanges; 800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (S_OK != langFontLink->GetFontUnicodeRanges(hdc, &unicodeRanges, 0)) 810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return false; 820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch static Vector<UNICODERANGE, 64> glyphsetBuffer; 840bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch glyphsetBuffer.resize(unicodeRanges); 850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (S_OK != langFontLink->GetFontUnicodeRanges(hdc, &unicodeRanges, glyphsetBuffer.data())) 870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return false; 880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // FIXME: Change this to a binary search. (Yong Li: That's easy. But, is it guaranteed that the ranges are sorted?) 900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch for (Vector<UNICODERANGE, 64>::const_iterator i = glyphsetBuffer.begin(); i != glyphsetBuffer.end(); ++i) { 910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (i->wcTo >= character) 920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return i->wcFrom <= character; 930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 940bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return false; 960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#else 980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic bool currentFontContainsCharacter(IMLangFontLink* langFontLink, HDC hdc, HFONT hfont, UChar character, const wchar_t* faceName) 990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 1000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch DWORD fontCodePages = 0, charCodePages = 0; 1010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch HRESULT result = langFontLink->GetFontCodePages(hdc, hfont, &fontCodePages); 1020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (result != S_OK) 1030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return false; 1040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch result = langFontLink->GetCharCodePages(character, &charCodePages); 1050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (result != S_OK) 1060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return false; 1070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch fontCodePages |= FontPlatformData::getKnownFontCodePages(faceName); 1090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (fontCodePages & charCodePages) 1100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return true; 1110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return false; 1130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 1140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif 1150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#if defined(IMLANG_FONT_LINK) && (IMLANG_FONT_LINK == 2) 1170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic HFONT createMLangFont(IMLangFontLink2* langFontLink, HDC hdc, DWORD codePageMask, UChar character = 0) 1180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 1190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch HFONT mlangFont; 1200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (SUCCEEDED(langFontLink->MapFont(hdc, codePageMask, character, &mlangFont))) 1210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return mlangFont; 1220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return 0; 1240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 1250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#else 1260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic HFONT createMLangFont(IMLangFontLink* langFontLink, HDC hdc, const FontPlatformData& refFont, DWORD codePageMask) 1270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 1280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch HFONT mlangFont; 1290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch LRESULT result = langFontLink->MapFont(hdc, codePageMask, refFont.hfont(), &mlangFont); 1300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return result == S_OK ? mlangFont : 0; 1320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 1330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif 1340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic const Vector<DWORD, 4>& getCJKCodePageMasks() 1360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 1370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // The default order in which we look for a font for a CJK character. If the user's default code page is 1380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // one of these, we will use it first. 1390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch static const UINT CJKCodePages[] = { 1400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 932, /* Japanese */ 1410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 936, /* Simplified Chinese */ 1420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 950, /* Traditional Chinese */ 1430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 949 /* Korean */ 1440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch }; 1450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch static Vector<DWORD, 4> codePageMasks; 1470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch static bool initialized; 1480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (!initialized) { 1490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch initialized = true; 1500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#if defined(IMLANG_FONT_LINK) && (IMLANG_FONT_LINK == 2) 1510bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch IMLangFontLink2* langFontLink = fontCache()->getFontLinkInterface(); 1520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#else 1530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch IMLangFontLink* langFontLink = fontCache()->getFontLinkInterface(); 1540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif 1550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (!langFontLink) 1560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return codePageMasks; 1570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch UINT defaultCodePage; 1590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch DWORD defaultCodePageMask = 0; 1600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_RETURN_NUMBER | LOCALE_IDEFAULTANSICODEPAGE, reinterpret_cast<LPWSTR>(&defaultCodePage), sizeof(defaultCodePage))) 1610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch langFontLink->CodePageToCodePages(defaultCodePage, &defaultCodePageMask); 1620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (defaultCodePage == CJKCodePages[0] || defaultCodePage == CJKCodePages[1] || defaultCodePage == CJKCodePages[2] || defaultCodePage == CJKCodePages[3]) 1640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch codePageMasks.append(defaultCodePageMask); 1650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch for (unsigned i = 0; i < 4; ++i) { 1660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (defaultCodePage != CJKCodePages[i]) { 1670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch DWORD codePageMask; 1680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch langFontLink->CodePageToCodePages(CJKCodePages[i], &codePageMask); 1690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch codePageMasks.append(codePageMask); 1700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 1710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 1720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 1730bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return codePageMasks; 1740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 1750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstruct TraitsInFamilyProcData { 1780bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch TraitsInFamilyProcData(const AtomicString& familyName) 1790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch : m_familyName(familyName) 1800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch { 1810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 1820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch const AtomicString& m_familyName; 1840bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch HashSet<unsigned> m_traitsMasks; 1850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}; 1860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic int CALLBACK traitsInFamilyEnumProc(CONST LOGFONT* logFont, CONST TEXTMETRIC* metrics, DWORD fontType, LPARAM lParam) 1880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 1890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch TraitsInFamilyProcData* procData = reinterpret_cast<TraitsInFamilyProcData*>(lParam); 1900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch unsigned traitsMask = 0; 1920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch traitsMask |= logFont->lfItalic ? FontStyleItalicMask : FontStyleNormalMask; 1930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch traitsMask |= FontVariantNormalMask; 1940bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch LONG weight = FontPlatformData::adjustedGDIFontWeight(logFont->lfWeight, procData->m_familyName); 1950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch traitsMask |= weight == FW_THIN ? FontWeight100Mask : 1960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch weight == FW_EXTRALIGHT ? FontWeight200Mask : 1970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch weight == FW_LIGHT ? FontWeight300Mask : 1980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch weight == FW_NORMAL ? FontWeight400Mask : 1990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch weight == FW_MEDIUM ? FontWeight500Mask : 2000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch weight == FW_SEMIBOLD ? FontWeight600Mask : 2010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch weight == FW_BOLD ? FontWeight700Mask : 2020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch weight == FW_EXTRABOLD ? FontWeight800Mask : 2030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch FontWeight900Mask; 2040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch procData->m_traitsMasks.add(traitsMask); 2050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return 1; 2060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 2070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 2080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid FontCache::platformInit() 2090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 2100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 2110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 2120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid FontCache::comInitialize() 2130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 2140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 2150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 2160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid FontCache::comUninitialize() 2170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 2180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (langFontLink) { 2190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch langFontLink->Release(); 2200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch langFontLink = 0; 2210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 2220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (multiLanguage) { 2230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch multiLanguage->Release(); 2240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch multiLanguage = 0; 2250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 2260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 2270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 2280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochconst SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, const UChar* characters, int length) 2290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 2300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch String familyName; 2310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch WCHAR name[LF_FACESIZE]; 2320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 2330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch UChar character = characters[0]; 2340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch const FontPlatformData& origFont = font.primaryFont()->fontDataForCharacter(character)->platformData(); 2350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch unsigned unicodeRange = findCharUnicodeRange(character); 2360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 2370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#if defined(IMLANG_FONT_LINK) && (IMLANG_FONT_LINK == 2) 2380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (IMLangFontLink2* langFontLink = getFontLinkInterface()) { 2390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#else 2400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (IMLangFontLink* langFontLink = getFontLinkInterface()) { 2410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif 2420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch HGDIOBJ oldFont = GetCurrentObject(g_screenDC, OBJ_FONT); 2430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch HFONT hfont = 0; 2440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch DWORD codePages = 0; 2450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch UINT codePage = 0; 2460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // Try MLang font linking first. 2470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch langFontLink->GetCharCodePages(character, &codePages); 2480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (codePages && unicodeRange == cRangeSetCJK) { 2490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // The CJK character may belong to multiple code pages. We want to 2500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // do font linking against a single one of them, preferring the default 2510bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // code page for the user's locale. 2520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch const Vector<DWORD, 4>& CJKCodePageMasks = getCJKCodePageMasks(); 2530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch unsigned numCodePages = CJKCodePageMasks.size(); 2540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch for (unsigned i = 0; i < numCodePages; ++i) { 2550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#if defined(IMLANG_FONT_LINK) && (IMLANG_FONT_LINK == 2) 2560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch hfont = createMLangFont(langFontLink, g_screenDC, CJKCodePageMasks[i]); 2570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#else 2580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch hfont = createMLangFont(langFontLink, g_screenDC, origFont, CJKCodePageMasks[i]); 2590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif 2600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (!hfont) 2610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch continue; 2620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 2630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch SelectObject(g_screenDC, hfont); 2640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch GetTextFace(g_screenDC, LF_FACESIZE, name); 2650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 2660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (hfont && !(codePages & CJKCodePageMasks[i])) { 2670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // We asked about a code page that is not one of the code pages 2680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // returned by MLang, so the font might not contain the character. 2690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#if defined(IMLANG_FONT_LINK) && (IMLANG_FONT_LINK == 2) 2700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (!currentFontContainsCharacter(langFontLink, g_screenDC, character)) { 2710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#else 2720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (!currentFontContainsCharacter(langFontLink, g_screenDC, hfont, character, name)) { 2730bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif 2740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch SelectObject(g_screenDC, oldFont); 2750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch langFontLink->ReleaseFont(hfont); 2760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch hfont = 0; 2770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch continue; 2780bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 2790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 2800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch break; 2810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 2820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } else { 2830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#if defined(IMLANG_FONT_LINK) && (IMLANG_FONT_LINK == 2) 2840bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch hfont = createMLangFont(langFontLink, g_screenDC, codePages, character); 2850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#else 2860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch hfont = createMLangFont(langFontLink, g_screenDC, origFont, codePages); 2870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif 2880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch SelectObject(g_screenDC, hfont); 2890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch GetTextFace(g_screenDC, LF_FACESIZE, name); 2900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 2910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch SelectObject(g_screenDC, oldFont); 2920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 2930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (hfont) { 2940bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch familyName = name; 2950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch langFontLink->ReleaseFont(hfont); 2960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } else 2970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch FontPlatformData::mapKnownFont(codePages, familyName); 2980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 2990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 3000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (familyName.isEmpty()) 3010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch familyName = FontPlatformData::defaultFontFamily(); 3020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 3030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (!familyName.isEmpty()) { 3040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // FIXME: temporary workaround for Thai font problem 3050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch FontDescription fontDescription(font.fontDescription()); 3060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (unicodeRange == cRangeThai && fontDescription.weight() > FontWeightNormal) 3070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch fontDescription.setWeight(FontWeightNormal); 3080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 3090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch FontPlatformData* result = getCachedFontPlatformData(fontDescription, familyName); 3100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (result && result->hash() != origFont.hash()) { 3110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (SimpleFontData* fontData = getCachedFontData(result)) 3120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return fontData; 3130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 3140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 3150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 3160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return 0; 3170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 3180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 3198a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve BlockSimpleFontData* FontCache::getSimilarFontPlatformData(const Font& font) 3200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 3210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return 0; 3220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 3230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 3248a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve BlockSimpleFontData* FontCache::getLastResortFallbackFont(const FontDescription& fontDesc) 3250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 3260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // FIXME: Would be even better to somehow get the user's default font here. For now we'll pick 3270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // the default that the user would get without changing any prefs. 3288a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block return getCachedFontData(fontDesc, FontPlatformData::defaultFontFamily()); 3290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 3300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 3310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochFontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomicString& family) 3320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 3330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch FontPlatformData* result = new FontPlatformData(fontDescription, family); 3340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return result; 3350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 3360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 3370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid FontCache::getTraitsInFamily(const AtomicString& familyName, Vector<unsigned>& traitsMasks) 3380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 3390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch LOGFONT logFont; 3400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch logFont.lfCharSet = DEFAULT_CHARSET; 3410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch unsigned familyLength = std::min(familyName.length(), static_cast<unsigned>(LF_FACESIZE - 1)); 3420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch memcpy(logFont.lfFaceName, familyName.characters(), familyLength * sizeof(UChar)); 3430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch logFont.lfFaceName[familyLength] = 0; 3440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch logFont.lfPitchAndFamily = 0; 3450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 3460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch TraitsInFamilyProcData procData(familyName); 3470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch EnumFontFamiliesEx(g_screenDC, &logFont, traitsInFamilyEnumProc, reinterpret_cast<LPARAM>(&procData), 0); 3480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch copyToVector(procData.m_traitsMasks, traitsMasks); 3490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 3500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 35168513a70bcd92384395513322f1b801e7bf9c729Steve Block} // namespace WebCore 352