1 /*
2 * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14 * its contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include "config.h"
30 #include "SimpleFontData.h"
31
32 #include "FontCache.h"
33 #include "FloatRect.h"
34 #include "FontDescription.h"
35 #include <wtf/MathExtras.h>
36 #include <unicode/uchar.h>
37 #include <unicode/unorm.h>
38
39 #if OS(DARWIN)
40 #include "WebCoreSystemInterface.h"
41 #endif
42
43 #include <wx/defs.h>
44 #include <wx/dcscreen.h>
45 #include <wx/string.h>
46 #include "fontprops.h"
47
48 namespace WebCore
49 {
50
platformInit()51 void SimpleFontData::platformInit()
52 {
53 wxFont *font = m_platformData.font();
54 if (font && font->IsOk()) {
55 wxFontProperties props = wxFontProperties(font);
56 m_fontMetrics.setAscent(props.GetAscent());
57 m_fontMetrics.setDescent(props.GetDescent());
58 m_fontMetrics.setXHeight(props.GetXHeight());
59 m_fontMetrics.setUnitsPerEm(1); // FIXME!
60 m_fontMetrics.setLineGap(props.GetLineGap());
61 m_fontMetrics.setLineSpacing(props.GetLineSpacing());
62 }
63
64 m_syntheticBoldOffset = 0.0f;
65
66 #if OS(WINDOWS)
67 m_scriptCache = 0;
68 m_scriptFontProperties = 0;
69 m_isSystemFont = false;
70 #endif
71 }
72
platformCharWidthInit()73 void SimpleFontData::platformCharWidthInit()
74 {
75 m_avgCharWidth = 0.f;
76 m_maxCharWidth = 0.f;
77 initCharWidths();
78 }
79
platformDestroy()80 void SimpleFontData::platformDestroy()
81 {
82 #if OS(WINDOWS)
83 if (m_scriptFontProperties) {
84 delete m_scriptFontProperties;
85 m_scriptFontProperties = 0;
86 }
87
88 if (m_scriptCache)
89 ScriptFreeCache(&m_scriptCache);
90 #endif
91 }
92
scaledFontData(const FontDescription & fontDescription,float scaleFactor) const93 SimpleFontData* SimpleFontData::scaledFontData(const FontDescription& fontDescription, float scaleFactor) const
94 {
95 FontDescription desc = FontDescription(fontDescription);
96 desc.setSpecifiedSize(scaleFactor * fontDescription.computedSize());
97 FontPlatformData platformData(desc, desc.family().family());
98 return new SimpleFontData(platformData, isCustomFont(), false);
99 }
100
smallCapsFontData(const FontDescription & fontDescription) const101 SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
102 {
103 if (!m_derivedFontData)
104 m_derivedFontData = DerivedFontData::create(isCustomFont());
105 if (!m_derivedFontData->smallCaps)
106 m_derivedFontData->smallCaps = scaledFontData(fontDescription, .7);
107
108 return m_derivedFontData->smallCaps.get();
109 }
110
emphasisMarkFontData(const FontDescription & fontDescription) const111 SimpleFontData* SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
112 {
113 if (!m_derivedFontData)
114 m_derivedFontData = DerivedFontData::create(isCustomFont());
115 if (!m_derivedFontData->emphasisMark)
116 m_derivedFontData->emphasisMark = scaledFontData(fontDescription, .5);
117
118 return m_derivedFontData->emphasisMark.get();
119 }
120
containsCharacters(const UChar * characters,int length) const121 bool SimpleFontData::containsCharacters(const UChar* characters, int length) const
122 {
123 // FIXME: We will need to implement this to load non-ASCII encoding sites
124 #if OS(WINDOWS)
125 return wxFontContainsCharacters(m_platformData.hfont(), characters, length);
126 #elif OS(DARWIN)
127 return wxFontContainsCharacters(m_platformData.nsFont(), characters, length);
128 #endif
129 return true;
130 }
131
determinePitch()132 void SimpleFontData::determinePitch()
133 {
134 if (m_platformData.font() && m_platformData.font()->Ok())
135 m_treatAsFixedPitch = m_platformData.font()->IsFixedWidth();
136 else
137 m_treatAsFixedPitch = false;
138 }
139
platformBoundsForGlyph(Glyph) const140 FloatRect SimpleFontData::platformBoundsForGlyph(Glyph) const
141 {
142 return FloatRect();
143 }
144
platformWidthForGlyph(Glyph glyph) const145 float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
146 {
147 #if __WXMSW__
148 // under Windows / wxMSW we currently always use GDI fonts.
149 return widthForGDIGlyph(glyph);
150 #elif OS(DARWIN)
151 float pointSize = m_platformData.size();
152 CGAffineTransform m = CGAffineTransformMakeScale(pointSize, pointSize);
153 CGSize advance;
154 NSFont* nsfont = (NSFont*)m_platformData.nsFont();
155 if (!wkGetGlyphTransformedAdvances(m_platformData.cgFont(), nsfont, &m, &glyph, &advance)) {
156 // LOG_ERROR("Unable to cache glyph widths for %@ %f", [nsfont displayName], pointSize);
157 advance.width = 0;
158 }
159 return advance.width + m_syntheticBoldOffset;
160 #else
161 // TODO: fix this! Make GetTextExtents a method of wxFont in 2.9
162 int width = 10;
163 GetTextExtent(*m_platformData.font(), (wxChar)glyph, &width, NULL);
164 return width;
165 #endif
166 }
167
168 #if OS(WINDOWS)
scriptFontProperties() const169 SCRIPT_FONTPROPERTIES* SimpleFontData::scriptFontProperties() const
170 {
171 // AFAICT this is never called even by the Win port anymore.
172 return 0;
173 }
174
initGDIFont()175 void SimpleFontData::initGDIFont()
176 {
177 // unused by wx port
178 }
179
platformCommonDestroy()180 void SimpleFontData::platformCommonDestroy()
181 {
182 // unused by wx port
183 }
184
widthForGDIGlyph(Glyph glyph) const185 float SimpleFontData::widthForGDIGlyph(Glyph glyph) const
186 {
187 HDC hdc = GetDC(0);
188 HGDIOBJ oldFont = SelectObject(hdc, m_platformData.hfont());
189 int width;
190 GetCharWidthI(hdc, glyph, 1, 0, &width);
191 SelectObject(hdc, oldFont);
192 ReleaseDC(0, hdc);
193 return width;
194 }
195 #endif
196
197 }
198