1/*
2 * This file is part of the internal font implementation.
3 *
4 * Copyright (C) 2006, 2008, 2010 Apple Inc. All rights reserved.
5 * Copyright (C) 2007-2008 Torch Mobile, Inc.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public License
18 * along with this library; see the file COPYING.LIB.  If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
21 *
22 */
23
24#ifndef SimpleFontData_h
25#define SimpleFontData_h
26
27#include "FontBaseline.h"
28#include "FontData.h"
29#include "FontMetrics.h"
30#include "FontPlatformData.h"
31#include "FloatRect.h"
32#include "GlyphMetricsMap.h"
33#include "GlyphPageTreeNode.h"
34#include "TypesettingFeatures.h"
35#include <wtf/OwnPtr.h>
36#include <wtf/PassOwnPtr.h>
37
38#if USE(ATSUI)
39typedef struct OpaqueATSUStyle* ATSUStyle;
40#endif
41
42#if PLATFORM(MAC) || USE(CORE_TEXT)
43#include <wtf/RetainPtr.h>
44#endif
45
46#if (PLATFORM(WIN) && !OS(WINCE)) \
47    || (OS(WINDOWS) && PLATFORM(WX))
48#include <usp10.h>
49#endif
50
51#if USE(CAIRO)
52#include <cairo.h>
53#endif
54
55#if PLATFORM(QT)
56#include <QFont>
57#endif
58
59#if PLATFORM(HAIKU)
60#include <Font.h>
61#endif
62
63namespace WebCore {
64
65class FontDescription;
66class SharedBuffer;
67class SVGFontData;
68
69enum FontDataVariant { AutoVariant, NormalVariant, SmallCapsVariant, EmphasisMarkVariant };
70enum Pitch { UnknownPitch, FixedPitch, VariablePitch };
71
72class SimpleFontData : public FontData {
73public:
74    SimpleFontData(const FontPlatformData&, bool isCustomFont = false, bool isLoading = false, bool isTextOrientationFallback = false);
75#if ENABLE(SVG_FONTS)
76    SimpleFontData(PassOwnPtr<SVGFontData>, int size, bool syntheticBold, bool syntheticItalic);
77#endif
78    virtual ~SimpleFontData();
79
80    const FontPlatformData& platformData() const { return m_platformData; }
81
82    SimpleFontData* smallCapsFontData(const FontDescription&) const;
83    SimpleFontData* emphasisMarkFontData(const FontDescription&) const;
84
85    SimpleFontData* variantFontData(const FontDescription& description, FontDataVariant variant) const
86    {
87        switch (variant) {
88        case SmallCapsVariant:
89            return smallCapsFontData(description);
90        case EmphasisMarkVariant:
91            return emphasisMarkFontData(description);
92        case AutoVariant:
93        case NormalVariant:
94            break;
95        }
96        ASSERT_NOT_REACHED();
97        return const_cast<SimpleFontData*>(this);
98    }
99
100    SimpleFontData* verticalRightOrientationFontData() const;
101    SimpleFontData* uprightOrientationFontData() const;
102    SimpleFontData* brokenIdeographFontData() const;
103
104    bool hasVerticalGlyphs() const { return m_hasVerticalGlyphs; }
105    bool isTextOrientationFallback() const { return m_isTextOrientationFallback; }
106
107    const FontMetrics& fontMetrics() const { return m_fontMetrics; }
108    float maxCharWidth() const { return m_maxCharWidth; }
109    float avgCharWidth() const { return m_avgCharWidth; }
110
111    FloatRect boundsForGlyph(Glyph) const;
112    float widthForGlyph(Glyph glyph) const;
113    FloatRect platformBoundsForGlyph(Glyph) const;
114    float platformWidthForGlyph(Glyph) const;
115
116    float spaceWidth() const { return m_spaceWidth; }
117
118#if USE(CG) || USE(CAIRO) || PLATFORM(WX) || USE(SKIA_ON_MAC_CHROME)
119    float syntheticBoldOffset() const { return m_syntheticBoldOffset; }
120#endif
121
122    Glyph spaceGlyph() const { return m_spaceGlyph; }
123    bool isZeroWidthSpaceGlyph(Glyph glyph) const { return glyph == m_zeroWidthSpaceGlyph && glyph; }
124
125    virtual const SimpleFontData* fontDataForCharacter(UChar32) const;
126    virtual bool containsCharacters(const UChar*, int length) const;
127
128    void determinePitch();
129    Pitch pitch() const { return m_treatAsFixedPitch ? FixedPitch : VariablePitch; }
130
131#if ENABLE(SVG_FONTS)
132    SVGFontData* svgFontData() const { return m_svgFontData.get(); }
133    bool isSVGFont() const { return m_svgFontData; }
134#else
135    bool isSVGFont() const { return false; }
136#endif
137
138    virtual bool isCustomFont() const { return m_isCustomFont; }
139    virtual bool isLoading() const { return m_isLoading; }
140    virtual bool isSegmented() const;
141
142    const GlyphData& missingGlyphData() const { return m_missingGlyphData; }
143
144#ifndef NDEBUG
145    virtual String description() const;
146#endif
147
148#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && OS(DARWIN))
149    NSFont* getNSFont() const { return m_platformData.font(); }
150#elif (PLATFORM(WX) && OS(DARWIN))
151    NSFont* getNSFont() const { return m_platformData.nsFont(); }
152#endif
153
154#if PLATFORM(MAC) || USE(CORE_TEXT)
155    CFDictionaryRef getCFStringAttributes(TypesettingFeatures, FontOrientation) const;
156#endif
157
158#if USE(ATSUI)
159    void checkShapesArabic() const;
160    bool shapesArabic() const
161    {
162        if (!m_checkedShapesArabic)
163            checkShapesArabic();
164        return m_shapesArabic;
165    }
166#endif
167
168#if PLATFORM(QT)
169    QFont getQtFont() const { return m_platformData.font(); }
170#endif
171
172#if PLATFORM(WIN) || (OS(WINDOWS) && PLATFORM(WX))
173    bool isSystemFont() const { return m_isSystemFont; }
174#if !OS(WINCE) // disable unused members to save space
175    SCRIPT_FONTPROPERTIES* scriptFontProperties() const;
176    SCRIPT_CACHE* scriptCache() const { return &m_scriptCache; }
177#endif
178    static void setShouldApplyMacAscentHack(bool);
179    static bool shouldApplyMacAscentHack();
180#endif
181
182#if PLATFORM(WX)
183    wxFont* getWxFont() const { return m_platformData.font(); }
184#endif
185
186private:
187    void platformInit();
188    void platformGlyphInit();
189    void platformCharWidthInit();
190    void platformDestroy();
191
192    void initCharWidths();
193
194    void commonInit();
195
196    SimpleFontData* scaledFontData(const FontDescription&, float scaleFactor) const;
197
198#if (PLATFORM(WIN) && !OS(WINCE)) \
199    || (OS(WINDOWS) && PLATFORM(WX))
200    void initGDIFont();
201    void platformCommonDestroy();
202    FloatRect boundsForGDIGlyph(Glyph glyph) const;
203    float widthForGDIGlyph(Glyph glyph) const;
204#endif
205
206    FontMetrics m_fontMetrics;
207    float m_maxCharWidth;
208    float m_avgCharWidth;
209
210    FontPlatformData m_platformData;
211
212    mutable OwnPtr<GlyphMetricsMap<FloatRect> > m_glyphToBoundsMap;
213    mutable GlyphMetricsMap<float> m_glyphToWidthMap;
214
215    bool m_treatAsFixedPitch;
216
217#if ENABLE(SVG_FONTS)
218    OwnPtr<SVGFontData> m_svgFontData;
219#endif
220
221    bool m_isCustomFont;  // Whether or not we are custom font loaded via @font-face
222    bool m_isLoading; // Whether or not this custom font is still in the act of loading.
223
224    bool m_isTextOrientationFallback;
225    bool m_isBrokenIdeographFallback;
226    bool m_hasVerticalGlyphs;
227
228    Glyph m_spaceGlyph;
229    float m_spaceWidth;
230
231    Glyph m_zeroWidthSpaceGlyph;
232
233    GlyphData m_missingGlyphData;
234
235    struct DerivedFontData {
236        static PassOwnPtr<DerivedFontData> create(bool forCustomFont);
237        ~DerivedFontData();
238
239        bool forCustomFont;
240        OwnPtr<SimpleFontData> smallCaps;
241        OwnPtr<SimpleFontData> emphasisMark;
242        OwnPtr<SimpleFontData> brokenIdeograph;
243        OwnPtr<SimpleFontData> verticalRightOrientation;
244        OwnPtr<SimpleFontData> uprightOrientation;
245
246    private:
247        DerivedFontData(bool custom)
248            : forCustomFont(custom)
249        {
250        }
251    };
252
253    mutable OwnPtr<DerivedFontData> m_derivedFontData;
254
255#if USE(CG) || USE(CAIRO) || PLATFORM(WX) || USE(SKIA_ON_MAC_CHROME)
256    float m_syntheticBoldOffset;
257#endif
258
259#ifdef BUILDING_ON_TIGER
260public:
261    void* m_styleGroup;
262
263private:
264#endif
265
266#if USE(ATSUI)
267public:
268    mutable HashMap<unsigned, ATSUStyle> m_ATSUStyleMap;
269    mutable bool m_ATSUMirrors;
270    mutable bool m_checkedShapesArabic;
271    mutable bool m_shapesArabic;
272
273private:
274#endif
275
276#if PLATFORM(MAC) || USE(CORE_TEXT)
277    mutable HashMap<unsigned, RetainPtr<CFDictionaryRef> > m_CFStringAttributes;
278#endif
279
280#if PLATFORM(WIN) || (OS(WINDOWS) && PLATFORM(WX))
281    bool m_isSystemFont;
282#if !OS(WINCE) // disable unused members to save space
283    mutable SCRIPT_CACHE m_scriptCache;
284    mutable SCRIPT_FONTPROPERTIES* m_scriptFontProperties;
285#endif
286#endif
287};
288
289
290#if !PLATFORM(QT)
291ALWAYS_INLINE FloatRect SimpleFontData::boundsForGlyph(Glyph glyph) const
292{
293    if (isZeroWidthSpaceGlyph(glyph))
294        return FloatRect();
295
296    FloatRect bounds;
297    if (m_glyphToBoundsMap) {
298        bounds = m_glyphToBoundsMap->metricsForGlyph(glyph);
299        if (bounds.width() != cGlyphSizeUnknown)
300            return bounds;
301    }
302
303    bounds = platformBoundsForGlyph(glyph);
304    if (!m_glyphToBoundsMap)
305        m_glyphToBoundsMap = adoptPtr(new GlyphMetricsMap<FloatRect>);
306    m_glyphToBoundsMap->setMetricsForGlyph(glyph, bounds);
307    return bounds;
308}
309
310ALWAYS_INLINE float SimpleFontData::widthForGlyph(Glyph glyph) const
311{
312    if (isZeroWidthSpaceGlyph(glyph))
313        return 0;
314
315    float width = m_glyphToWidthMap.metricsForGlyph(glyph);
316    if (width != cGlyphSizeUnknown)
317        return width;
318
319    width = platformWidthForGlyph(glyph);
320    m_glyphToWidthMap.setMetricsForGlyph(glyph, width);
321    return width;
322}
323#endif
324
325} // namespace WebCore
326
327#endif // SimpleFontData_h
328