• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
40 namespace WebCore {
41 
42 extern HDC g_screenDC;
43 
platformInit()44 void 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 
platformDestroy()62 void SimpleFontData::platformDestroy()
63 {
64 }
65 
scaledFontData(const FontDescription & fontDescription,float scaleFactor) const66 SimpleFontData* 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 
smallCapsFontData(const FontDescription & fontDescription) const76 SimpleFontData* 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 
emphasisMarkFontData(const FontDescription & fontDescription) const86 SimpleFontData* 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 
96 DWORD getKnownFontCodePages(const wchar_t* family);
97 
containsCharacters(const UChar * characters,int length) const98 bool 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 
determinePitch()137 void 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 
platformBoundsForGlyph(Glyph) const149 FloatRect SimpleFontData::platformBoundsForGlyph(Glyph) const
150 {
151     return FloatRect();
152 }
153 
platformWidthForGlyph(Glyph glyph) const154 float 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 
platformCharWidthInit()171 void 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