0158de3b24233991aab9cb1f5ee45b062ce09d10
[WebKit-https.git] / Source / WebCore / platform / graphics / GlyphBuffer.h
1 /*
2  * Copyright (C) 2006, 2009, 2011 Apple Inc. All rights reserved.
3  * Copyright (C) 2007-2008 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 #ifndef GlyphBuffer_h
31 #define GlyphBuffer_h
32
33 #include "FloatSize.h"
34 #include "Glyph.h"
35 #include <wtf/UnusedParam.h>
36 #include <wtf/Vector.h>
37
38 #if USE(CG) || USE(SKIA_ON_MAC_CHROMIUM)
39 #include <CoreGraphics/CGGeometry.h>
40 #endif
41
42 #if PLATFORM(WX) && OS(DARWIN)
43 #include <ApplicationServices/ApplicationServices.h>
44 #endif
45
46 #if USE(CAIRO) || (PLATFORM(WX) && defined(__WXGTK__))
47 #include <cairo.h>
48 #endif
49
50 namespace WebCore {
51
52 class SimpleFontData;
53
54 #if USE(CAIRO)
55 // FIXME: Why does Cairo use such a huge struct instead of just an offset into an array?
56 typedef cairo_glyph_t GlyphBufferGlyph;
57 #elif OS(WINCE)
58 typedef wchar_t GlyphBufferGlyph;
59 #else
60 typedef Glyph GlyphBufferGlyph;
61 #endif
62
63 // CG uses CGSize instead of FloatSize so that the result of advances()
64 // can be passed directly to CGContextShowGlyphsWithAdvances in FontMac.mm
65 #if USE(CG) || (PLATFORM(WX) && OS(DARWIN)) || USE(SKIA_ON_MAC_CHROMIUM)
66 typedef CGSize GlyphBufferAdvance;
67 #elif OS(WINCE)
68 // There is no cross-platform code that uses the height of GlyphBufferAdvance,
69 // so we can save memory space on embedded devices by storing only the width
70 typedef float GlyphBufferAdvance;
71 #else
72 typedef FloatSize GlyphBufferAdvance;
73 #endif
74
75 class GlyphBuffer {
76 public:
77     bool isEmpty() const { return m_fontData.isEmpty(); }
78     int size() const { return m_fontData.size(); }
79     
80     void clear()
81     {
82         m_fontData.clear();
83         m_glyphs.clear();
84         m_advances.clear();
85 #if PLATFORM(WIN)
86         m_offsets.clear();
87 #endif
88     }
89
90     GlyphBufferGlyph* glyphs(int from) { return m_glyphs.data() + from; }
91     GlyphBufferAdvance* advances(int from) { return m_advances.data() + from; }
92     const GlyphBufferGlyph* glyphs(int from) const { return m_glyphs.data() + from; }
93     const GlyphBufferAdvance* advances(int from) const { return m_advances.data() + from; }
94
95     const SimpleFontData* fontDataAt(int index) const { return m_fontData[index]; }
96     
97     void swap(int index1, int index2)
98     {
99         const SimpleFontData* f = m_fontData[index1];
100         m_fontData[index1] = m_fontData[index2];
101         m_fontData[index2] = f;
102
103         GlyphBufferGlyph g = m_glyphs[index1];
104         m_glyphs[index1] = m_glyphs[index2];
105         m_glyphs[index2] = g;
106
107         GlyphBufferAdvance s = m_advances[index1];
108         m_advances[index1] = m_advances[index2];
109         m_advances[index2] = s;
110
111 #if PLATFORM(WIN)
112         FloatSize offset = m_offsets[index1];
113         m_offsets[index1] = m_offsets[index2];
114         m_offsets[index2] = offset;
115 #endif
116     }
117
118     Glyph glyphAt(int index) const
119     {
120 #if USE(CAIRO)
121         return m_glyphs[index].index;
122 #else
123         return m_glyphs[index];
124 #endif
125     }
126
127     float advanceAt(int index) const
128     {
129 #if USE(CG) || (PLATFORM(WX) && OS(DARWIN)) || USE(SKIA_ON_MAC_CHROMIUM)
130         return m_advances[index].width;
131 #elif OS(WINCE)
132         return m_advances[index];
133 #else
134         return m_advances[index].width();
135 #endif
136     }
137
138     FloatSize offsetAt(int index) const
139     {
140 #if PLATFORM(WIN)
141         return m_offsets[index];
142 #else
143         UNUSED_PARAM(index);
144         return FloatSize();
145 #endif
146     }
147
148     void add(Glyph glyph, const SimpleFontData* font, float width, const FloatSize* offset = 0)
149     {
150         m_fontData.append(font);
151
152 #if USE(CAIRO)
153         cairo_glyph_t cairoGlyph;
154         cairoGlyph.index = glyph;
155         m_glyphs.append(cairoGlyph);
156 #else
157         m_glyphs.append(glyph);
158 #endif
159
160 #if USE(CG) || (PLATFORM(WX) && OS(DARWIN)) || USE(SKIA_ON_MAC_CHROMIUM)
161         CGSize advance = { width, 0 };
162         m_advances.append(advance);
163 #elif OS(WINCE)
164         m_advances.append(width);
165 #else
166         m_advances.append(FloatSize(width, 0));
167 #endif
168
169 #if PLATFORM(WIN)
170         if (offset)
171             m_offsets.append(*offset);
172         else
173             m_offsets.append(FloatSize());
174 #else
175         UNUSED_PARAM(offset);
176 #endif
177     }
178     
179 #if !OS(WINCE)
180     void add(Glyph glyph, const SimpleFontData* font, GlyphBufferAdvance advance)
181     {
182         m_fontData.append(font);
183 #if USE(CAIRO)
184         cairo_glyph_t cairoGlyph;
185         cairoGlyph.index = glyph;
186         m_glyphs.append(cairoGlyph);
187 #else
188         m_glyphs.append(glyph);
189 #endif
190
191         m_advances.append(advance);
192     }
193 #endif
194
195     void expandLastAdvance(float width)
196     {
197         ASSERT(!isEmpty());
198         GlyphBufferAdvance& lastAdvance = m_advances.last();
199 #if USE(CG) || (PLATFORM(WX) && OS(DARWIN)) || USE(SKIA_ON_MAC_CHROMIUM)
200         lastAdvance.width += width;
201 #elif OS(WINCE)
202         lastAdvance += width;
203 #else
204         lastAdvance += FloatSize(width, 0);
205 #endif
206     }
207
208 private:
209     Vector<const SimpleFontData*, 2048> m_fontData;
210     Vector<GlyphBufferGlyph, 2048> m_glyphs;
211     Vector<GlyphBufferAdvance, 2048> m_advances;
212 #if PLATFORM(WIN)
213     Vector<FloatSize, 2048> m_offsets;
214 #endif
215 };
216
217 }
218 #endif