10bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch/* 20bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * Copyright (C) 2006, 2007 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 "SimpleFontData.h" 320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "FloatRect.h" 340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "Font.h" 350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "FontCache.h" 360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "FontDescription.h" 370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include <mlang.h> 382fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include <wtf/MathExtras.h> 390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochnamespace WebCore { 410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochextern HDC g_screenDC; 430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid SimpleFontData::platformInit() 450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (!m_platformData.isValid()) 470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return; 480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch const TEXTMETRIC& tm = m_platformData.metrics(); 500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch m_isSystemFont = m_platformData.isSystemFont(); 510bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 522fc2651226baac27029e38c9d6ef883fa32084dbSteve Block float ascent = (tm.tmAscent * m_platformData.size() + 36) / 72.0f; 532fc2651226baac27029e38c9d6ef883fa32084dbSteve Block float descent = (tm.tmDescent * m_platformData.size() + 36) / 72.0f; 542fc2651226baac27029e38c9d6ef883fa32084dbSteve Block float lineGap = (tm.tmExternalLeading * m_platformData.size() + 36) / 72.0f; 552fc2651226baac27029e38c9d6ef883fa32084dbSteve Block m_fontMetrics.setAscent(ascent); 562fc2651226baac27029e38c9d6ef883fa32084dbSteve Block m_fontMetrics.setDescent(descent); 572fc2651226baac27029e38c9d6ef883fa32084dbSteve Block m_fontMetrics.setLineGap(lineGap); 582fc2651226baac27029e38c9d6ef883fa32084dbSteve Block m_fontMetrics.setLineSpacing(lroundf(ascent) + lroundf(descent) + lroundf(lineGap)); 592fc2651226baac27029e38c9d6ef883fa32084dbSteve Block m_fontMetrics.setXHeight(ascent * 0.56f); 600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid SimpleFontData::platformDestroy() 630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 64f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch} 65f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 66f05b935882198ccf7d81675736e3aeb089c5113aBen MurdochSimpleFontData* SimpleFontData::scaledFontData(const FontDescription& fontDescription, float scaleFactor) const 67f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{ 68f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch FontDescription fontDesc(fontDescription); 69f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch fontDesc.setComputedSize(lroundf(scaleFactor * fontDesc.computedSize())); 70f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch fontDesc.setSpecifiedSize(lroundf(scaleFactor * fontDesc.specifiedSize())); 71f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch fontDesc.setKeywordSize(lroundf(scaleFactor * fontDesc.keywordSize())); 72f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch FontPlatformData* result = fontCache()->getCachedFontPlatformData(fontDesc, m_platformData.family()); 73f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return result ? new SimpleFontData(*result) : 0; 740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochSimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const 770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 78f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!m_derivedFontData) 79f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_derivedFontData = DerivedFontData::create(isCustomFont()); 80f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!m_derivedFontData->smallCaps) 81f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_derivedFontData->smallCaps = scaledFontData(fontDescription, .7); 82f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 83f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return m_derivedFontData->smallCaps.get(); 84f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch} 85f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 86f05b935882198ccf7d81675736e3aeb089c5113aBen MurdochSimpleFontData* SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const 87f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{ 88f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!m_derivedFontData) 89f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_derivedFontData = DerivedFontData::create(isCustomFont()); 90f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!m_derivedFontData->emphasisMark) 91f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_derivedFontData->emphasisMark = scaledFontData(fontDescription, .5); 92f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 93f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return m_derivedFontData->emphasisMark.get(); 940bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochDWORD getKnownFontCodePages(const wchar_t* family); 970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochbool SimpleFontData::containsCharacters(const UChar* characters, int length) const 990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 1000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (m_platformData.isDisabled()) 1010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return true; 1020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // FIXME: Microsoft documentation seems to imply that characters can be output using a given font and DC 1040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // merely by testing code page intersection. This seems suspect though. Can't a font only partially 1050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // cover a given code page? 1060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // FIXME: in the case that we failed to get the interface, still use the font. 1080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#if defined(IMLANG_FONT_LINK) && (IMLANG_FONT_LINK == 2) 1090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch IMLangFontLink2* langFontLink = fontCache()->getFontLinkInterface(); 1100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#else 1110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch IMLangFontLink* langFontLink = fontCache()->getFontLinkInterface(); 1120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif 1130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (!langFontLink) 1140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return true; 1150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch DWORD fontCodePages = m_platformData.codePages(); 1170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (!fontCodePages) 1180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return false; 1190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch DWORD acpCodePages = 0; 1210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch langFontLink->CodePageToCodePages(CP_ACP, &acpCodePages); 1220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch DWORD actualCodePages; 1240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch long numCharactersProcessed; 1250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch while (length) { 1260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch langFontLink->GetStrCodePages(characters, length, acpCodePages, &actualCodePages, &numCharactersProcessed); 1270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (actualCodePages && !(actualCodePages & fontCodePages)) 1280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return false; 1290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch length -= numCharactersProcessed; 1310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch characters += numCharactersProcessed; 1320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 1330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return true; 1350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 1360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid SimpleFontData::determinePitch() 1380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 1390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (!m_platformData.isValid()) 1400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return; 1410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch const TEXTMETRIC& tm = m_platformData.metrics(); 1430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // Yes, this looks backwards, but the fixed pitch bit is actually set if the font 1450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // is *not* fixed pitch. Unbelievable but true. 1460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch m_treatAsFixedPitch = !(tm.tmPitchAndFamily & TMPF_FIXED_PITCH); 1470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 1480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 14921939df44de1705786c545cd1bf519d47250322dBen MurdochFloatRect SimpleFontData::platformBoundsForGlyph(Glyph) const 15021939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 15121939df44de1705786c545cd1bf519d47250322dBen Murdoch return FloatRect(); 15221939df44de1705786c545cd1bf519d47250322dBen Murdoch} 15321939df44de1705786c545cd1bf519d47250322dBen Murdoch 1540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochfloat SimpleFontData::platformWidthForGlyph(Glyph glyph) const 1550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 1560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (m_platformData.isDisabled()) 1570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return 0; 1580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch HGDIOBJ hOldFont = SelectObject(g_screenDC, m_platformData.hfont()); 1600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch SIZE fontSize; 1620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch wchar_t c = glyph; 1630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch GetTextExtentPoint32(g_screenDC, &c, 1, &fontSize); 1640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch SelectObject(g_screenDC, hOldFont); 1660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return (float)fontSize.cx * (float)m_platformData.size() / 72.f; 1680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 1690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid SimpleFontData::platformCharWidthInit() 1720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 1730bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (!m_platformData.isValid()) 1740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return; 1750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch const TEXTMETRIC& tm = m_platformData.metrics(); 1770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch m_avgCharWidth = (tm.tmAveCharWidth * m_platformData.size() + 36) / 72; 1780bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch m_maxCharWidth = (tm.tmMaxCharWidth * m_platformData.size() + 36) / 72; 1790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 1800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 18168513a70bcd92384395513322f1b801e7bf9c729Steve Block} // namespace WebCore 182