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#include "config.h" 31#include "SimpleFontData.h" 32 33#include "FloatRect.h" 34#include "Font.h" 35#include "FontCache.h" 36#include "FontDescription.h" 37#include <mlang.h> 38#include <wtf/MathExtras.h> 39 40namespace WebCore { 41 42extern HDC g_screenDC; 43 44void SimpleFontData::platformInit() 45{ 46 if (!m_platformData.isValid()) 47 return; 48 49 const TEXTMETRIC& tm = m_platformData.metrics(); 50 m_isSystemFont = m_platformData.isSystemFont(); 51 52 float ascent = (tm.tmAscent * m_platformData.size() + 36) / 72.0f; 53 float descent = (tm.tmDescent * m_platformData.size() + 36) / 72.0f; 54 float lineGap = (tm.tmExternalLeading * m_platformData.size() + 36) / 72.0f; 55 m_fontMetrics.setAscent(ascent); 56 m_fontMetrics.setDescent(descent); 57 m_fontMetrics.setLineGap(lineGap); 58 m_fontMetrics.setLineSpacing(lroundf(ascent) + lroundf(descent) + lroundf(lineGap)); 59 m_fontMetrics.setXHeight(ascent * 0.56f); 60} 61 62void SimpleFontData::platformDestroy() 63{ 64} 65 66SimpleFontData* SimpleFontData::scaledFontData(const FontDescription& fontDescription, float scaleFactor) const 67{ 68 FontDescription fontDesc(fontDescription); 69 fontDesc.setComputedSize(lroundf(scaleFactor * fontDesc.computedSize())); 70 fontDesc.setSpecifiedSize(lroundf(scaleFactor * fontDesc.specifiedSize())); 71 fontDesc.setKeywordSize(lroundf(scaleFactor * fontDesc.keywordSize())); 72 FontPlatformData* result = fontCache()->getCachedFontPlatformData(fontDesc, m_platformData.family()); 73 return result ? new SimpleFontData(*result) : 0; 74} 75 76SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const 77{ 78 if (!m_derivedFontData) 79 m_derivedFontData = DerivedFontData::create(isCustomFont()); 80 if (!m_derivedFontData->smallCaps) 81 m_derivedFontData->smallCaps = scaledFontData(fontDescription, .7); 82 83 return m_derivedFontData->smallCaps.get(); 84} 85 86SimpleFontData* SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const 87{ 88 if (!m_derivedFontData) 89 m_derivedFontData = DerivedFontData::create(isCustomFont()); 90 if (!m_derivedFontData->emphasisMark) 91 m_derivedFontData->emphasisMark = scaledFontData(fontDescription, .5); 92 93 return m_derivedFontData->emphasisMark.get(); 94} 95 96DWORD getKnownFontCodePages(const wchar_t* family); 97 98bool SimpleFontData::containsCharacters(const UChar* characters, int length) const 99{ 100 if (m_platformData.isDisabled()) 101 return true; 102 103 // FIXME: Microsoft documentation seems to imply that characters can be output using a given font and DC 104 // merely by testing code page intersection. This seems suspect though. Can't a font only partially 105 // cover a given code page? 106 107 // FIXME: in the case that we failed to get the interface, still use the font. 108#if defined(IMLANG_FONT_LINK) && (IMLANG_FONT_LINK == 2) 109 IMLangFontLink2* langFontLink = fontCache()->getFontLinkInterface(); 110#else 111 IMLangFontLink* langFontLink = fontCache()->getFontLinkInterface(); 112#endif 113 if (!langFontLink) 114 return true; 115 116 DWORD fontCodePages = m_platformData.codePages(); 117 if (!fontCodePages) 118 return false; 119 120 DWORD acpCodePages = 0; 121 langFontLink->CodePageToCodePages(CP_ACP, &acpCodePages); 122 123 DWORD actualCodePages; 124 long numCharactersProcessed; 125 while (length) { 126 langFontLink->GetStrCodePages(characters, length, acpCodePages, &actualCodePages, &numCharactersProcessed); 127 if (actualCodePages && !(actualCodePages & fontCodePages)) 128 return false; 129 130 length -= numCharactersProcessed; 131 characters += numCharactersProcessed; 132 } 133 134 return true; 135} 136 137void SimpleFontData::determinePitch() 138{ 139 if (!m_platformData.isValid()) 140 return; 141 142 const TEXTMETRIC& tm = m_platformData.metrics(); 143 144 // Yes, this looks backwards, but the fixed pitch bit is actually set if the font 145 // is *not* fixed pitch. Unbelievable but true. 146 m_treatAsFixedPitch = !(tm.tmPitchAndFamily & TMPF_FIXED_PITCH); 147} 148 149FloatRect SimpleFontData::platformBoundsForGlyph(Glyph) const 150{ 151 return FloatRect(); 152} 153 154float SimpleFontData::platformWidthForGlyph(Glyph glyph) const 155{ 156 if (m_platformData.isDisabled()) 157 return 0; 158 159 HGDIOBJ hOldFont = SelectObject(g_screenDC, m_platformData.hfont()); 160 161 SIZE fontSize; 162 wchar_t c = glyph; 163 GetTextExtentPoint32(g_screenDC, &c, 1, &fontSize); 164 165 SelectObject(g_screenDC, hOldFont); 166 167 return (float)fontSize.cx * (float)m_platformData.size() / 72.f; 168} 169 170 171void SimpleFontData::platformCharWidthInit() 172{ 173 if (!m_platformData.isValid()) 174 return; 175 176 const TEXTMETRIC& tm = m_platformData.metrics(); 177 m_avgCharWidth = (tm.tmAveCharWidth * m_platformData.size() + 36) / 72; 178 m_maxCharWidth = (tm.tmMaxCharWidth * m_platformData.size() + 36) / 72; 179} 180 181} // namespace WebCore 182