1/* 2 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. 3 * Copyright (C) 2007-2009 Torch Mobile, Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 15 * its contributors may be used to endorse or promote products derived 16 * from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 31#include "config.h" 32#include "SimpleFontData.h" 33 34#include "FloatRect.h" 35#include "Font.h" 36#include "FontCache.h" 37#include "FontDescription.h" 38#include <wtf/MathExtras.h> 39#include <mlang.h> 40#include <tchar.h> 41 42namespace WebCore { 43 44extern HDC g_screenDC; 45 46void SimpleFontData::platformInit() 47{ 48 if (!m_platformData.isValid()) 49 return; 50 51 const TEXTMETRIC& tm = m_platformData.metrics(); 52 m_isSystemFont = m_platformData.isSystemFont(); 53 54 m_ascent = (tm.tmAscent * m_platformData.size() + 36) / 72; 55 m_descent = (tm.tmDescent * m_platformData.size() + 36) / 72; 56 m_lineGap = (tm.tmExternalLeading * m_platformData.size() + 36) / 72; 57 m_lineSpacing = m_ascent + m_descent + m_lineGap; 58 m_xHeight = m_ascent * 0.56f; 59} 60 61void SimpleFontData::platformDestroy() 62{ 63 delete m_smallCapsFontData; 64 m_smallCapsFontData = 0; 65} 66 67SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const 68{ 69 if (!m_smallCapsFontData) { 70 FontDescription fontDesc(fontDescription); 71 fontDesc.setComputedSize(lroundf(0.70f * fontDesc.computedSize())); 72 fontDesc.setSpecifiedSize(lroundf(0.70f * fontDesc.specifiedSize())); 73 fontDesc.setKeywordSize(lroundf(0.70f * fontDesc.keywordSize())); 74 FontPlatformData* result = fontCache()->getCachedFontPlatformData(fontDesc, m_platformData.family()); 75 if (result) 76 m_smallCapsFontData = new SimpleFontData(*result); 77 } 78 return m_smallCapsFontData; 79} 80 81DWORD getKnownFontCodePages(const wchar_t* family); 82 83bool SimpleFontData::containsCharacters(const UChar* characters, int length) const 84{ 85 if (m_platformData.isDisabled()) 86 return true; 87 88 // FIXME: Microsoft documentation seems to imply that characters can be output using a given font and DC 89 // merely by testing code page intersection. This seems suspect though. Can't a font only partially 90 // cover a given code page? 91 92 // FIXME: in the case that we failed to get the interface, still use the font. 93#if defined(IMLANG_FONT_LINK) && (IMLANG_FONT_LINK == 2) 94 IMLangFontLink2* langFontLink = fontCache()->getFontLinkInterface(); 95#else 96 IMLangFontLink* langFontLink = fontCache()->getFontLinkInterface(); 97#endif 98 if (!langFontLink) 99 return true; 100 101 DWORD fontCodePages = m_platformData.codePages(); 102 if (!fontCodePages) 103 return false; 104 105 DWORD acpCodePages = 0; 106 langFontLink->CodePageToCodePages(CP_ACP, &acpCodePages); 107 108 DWORD actualCodePages; 109 long numCharactersProcessed; 110 while (length) { 111 langFontLink->GetStrCodePages(characters, length, acpCodePages, &actualCodePages, &numCharactersProcessed); 112 if (actualCodePages && !(actualCodePages & fontCodePages)) 113 return false; 114 115 length -= numCharactersProcessed; 116 characters += numCharactersProcessed; 117 } 118 119 return true; 120} 121 122void SimpleFontData::determinePitch() 123{ 124 if (!m_platformData.isValid()) 125 return; 126 127 const TEXTMETRIC& tm = m_platformData.metrics(); 128 129 // Yes, this looks backwards, but the fixed pitch bit is actually set if the font 130 // is *not* fixed pitch. Unbelievable but true. 131 m_treatAsFixedPitch = !(tm.tmPitchAndFamily & TMPF_FIXED_PITCH); 132} 133 134float SimpleFontData::platformWidthForGlyph(Glyph glyph) const 135{ 136 if (m_platformData.isDisabled()) 137 return 0; 138 139 HGDIOBJ hOldFont = SelectObject(g_screenDC, m_platformData.hfont()); 140 141 SIZE fontSize; 142 wchar_t c = glyph; 143 GetTextExtentPoint32(g_screenDC, &c, 1, &fontSize); 144 145 SelectObject(g_screenDC, hOldFont); 146 147 return (float)fontSize.cx * (float)m_platformData.size() / 72.f; 148} 149 150 151void SimpleFontData::platformCharWidthInit() 152{ 153 if (!m_platformData.isValid()) 154 return; 155 156 const TEXTMETRIC& tm = m_platformData.metrics(); 157 m_avgCharWidth = (tm.tmAveCharWidth * m_platformData.size() + 36) / 72; 158 m_maxCharWidth = (tm.tmMaxCharWidth * m_platformData.size() + 36) / 72; 159} 160 161} 162