1/*
2 * Copyright (C) 2006, 2010, 2013 Apple Inc. All rights reserved.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB.  If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 *
19 */
20
21#ifndef FontGlyphs_h
22#define FontGlyphs_h
23
24#include "FontSelector.h"
25#include "SimpleFontData.h"
26#include "WidthCache.h"
27#include <wtf/Forward.h>
28#include <wtf/MainThread.h>
29
30#if PLATFORM(IOS)
31#include "WebCoreThread.h"
32#endif
33
34namespace WebCore {
35
36class GlyphPageTreeNode;
37class GraphicsContext;
38class IntRect;
39class FontDescription;
40class FontPlatformData;
41class FontSelector;
42
43const int cAllFamiliesScanned = -1;
44
45class FontGlyphs : public RefCounted<FontGlyphs> {
46    WTF_MAKE_NONCOPYABLE(FontGlyphs);
47public:
48    typedef HashMap<int, GlyphPageTreeNode*, DefaultHash<int>::Hash> GlyphPages;
49
50    class GlyphPagesStateSaver {
51    public:
52        GlyphPagesStateSaver(FontGlyphs& glyphs)
53            : m_glyphs(glyphs)
54            , m_pages(glyphs.m_pages)
55            , m_pageZero(glyphs.m_pageZero)
56        {
57        }
58
59        ~GlyphPagesStateSaver()
60        {
61            m_glyphs.m_pages = m_pages;
62            m_glyphs.m_pageZero = m_pageZero;
63        }
64
65    private:
66        FontGlyphs& m_glyphs;
67        GlyphPages& m_pages;
68        GlyphPageTreeNode* m_pageZero;
69    };
70
71    static PassRef<FontGlyphs> create(PassRefPtr<FontSelector> fontSelector) { return adoptRef(*new FontGlyphs(fontSelector)); }
72    static PassRef<FontGlyphs> createForPlatformFont(const FontPlatformData& platformData) { return adoptRef(*new FontGlyphs(platformData)); }
73
74    ~FontGlyphs() { releaseFontData(); }
75
76    bool isForPlatformFont() const { return m_isForPlatformFont; }
77
78    std::pair<GlyphData, GlyphPage*> glyphDataAndPageForCharacter(const FontDescription&, UChar32, bool mirror, FontDataVariant) const;
79
80    bool isFixedPitch(const FontDescription&) const;
81    void determinePitch(const FontDescription&) const;
82
83    bool loadingCustomFonts() const { return m_loadingCustomFonts; }
84
85    FontSelector* fontSelector() const { return m_fontSelector.get(); }
86    // FIXME: It should be possible to combine fontSelectorVersion and generation.
87    unsigned fontSelectorVersion() const { return m_fontSelectorVersion; }
88    unsigned generation() const { return m_generation; }
89
90    WidthCache& widthCache() const { return m_widthCache; }
91
92    const SimpleFontData* primarySimpleFontData(const FontDescription&) const;
93    const FontData* primaryFontData(const FontDescription& description) const { return realizeFontDataAt(description, 0); }
94    const FontData* realizeFontDataAt(const FontDescription&, unsigned index) const;
95
96private:
97    FontGlyphs(PassRefPtr<FontSelector>);
98    FontGlyphs(const FontPlatformData&);
99
100    void releaseFontData();
101
102    mutable Vector<RefPtr<FontData>, 1> m_realizedFontData;
103    mutable GlyphPages m_pages;
104    mutable GlyphPageTreeNode* m_pageZero;
105    mutable const SimpleFontData* m_cachedPrimarySimpleFontData;
106    RefPtr<FontSelector> m_fontSelector;
107    mutable WidthCache m_widthCache;
108    unsigned m_fontSelectorVersion;
109    mutable int m_familyIndex;
110    unsigned short m_generation;
111    mutable unsigned m_pitch : 3; // Pitch
112    mutable bool m_loadingCustomFonts : 1;
113    bool m_isForPlatformFont : 1;
114};
115
116inline bool FontGlyphs::isFixedPitch(const FontDescription& description) const
117{
118    if (m_pitch == UnknownPitch)
119        determinePitch(description);
120    return m_pitch == FixedPitch;
121};
122
123inline const SimpleFontData* FontGlyphs::primarySimpleFontData(const FontDescription& description) const
124{
125    ASSERT(isMainThread());
126    if (!m_cachedPrimarySimpleFontData)
127        m_cachedPrimarySimpleFontData = primaryFontData(description)->fontDataForCharacter(' ');
128    return m_cachedPrimarySimpleFontData;
129}
130
131}
132
133#endif
134