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