1 /* 2 * Copyright (C) 2006, 2009 Apple 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 #ifndef GlyphBuffer_h 30 #define GlyphBuffer_h 31 32 #include "FloatSize.h" 33 #include <wtf/UnusedParam.h> 34 #include <wtf/Vector.h> 35 36 #if PLATFORM(CG) 37 #include <ApplicationServices/ApplicationServices.h> 38 #endif 39 40 #if PLATFORM(CAIRO) 41 #include <cairo.h> 42 #endif 43 44 namespace WebCore { 45 46 typedef unsigned short Glyph; 47 class SimpleFontData; 48 49 #if PLATFORM(CAIRO) 50 // FIXME: Why does Cairo use such a huge struct instead of just an offset into an array? 51 typedef cairo_glyph_t GlyphBufferGlyph; 52 #else 53 typedef Glyph GlyphBufferGlyph; 54 #endif 55 56 // CG uses CGSize instead of FloatSize so that the result of advances() 57 // can be passed directly to CGContextShowGlyphsWithAdvances in FontMac.mm 58 #if PLATFORM(CG) 59 typedef CGSize GlyphBufferAdvance; 60 #else 61 typedef FloatSize GlyphBufferAdvance; 62 #endif 63 64 class GlyphBuffer { 65 public: isEmpty()66 bool isEmpty() const { return m_fontData.isEmpty(); } size()67 int size() const { return m_fontData.size(); } 68 clear()69 void clear() 70 { 71 m_fontData.clear(); 72 m_glyphs.clear(); 73 m_advances.clear(); 74 #if PLATFORM(WIN) 75 m_offsets.clear(); 76 #endif 77 } 78 glyphs(int from)79 GlyphBufferGlyph* glyphs(int from) { return m_glyphs.data() + from; } advances(int from)80 GlyphBufferAdvance* advances(int from) { return m_advances.data() + from; } glyphs(int from)81 const GlyphBufferGlyph* glyphs(int from) const { return m_glyphs.data() + from; } advances(int from)82 const GlyphBufferAdvance* advances(int from) const { return m_advances.data() + from; } 83 fontDataAt(int index)84 const SimpleFontData* fontDataAt(int index) const { return m_fontData[index]; } 85 swap(int index1,int index2)86 void swap(int index1, int index2) 87 { 88 const SimpleFontData* f = m_fontData[index1]; 89 m_fontData[index1] = m_fontData[index2]; 90 m_fontData[index2] = f; 91 92 GlyphBufferGlyph g = m_glyphs[index1]; 93 m_glyphs[index1] = m_glyphs[index2]; 94 m_glyphs[index2] = g; 95 96 GlyphBufferAdvance s = m_advances[index1]; 97 m_advances[index1] = m_advances[index2]; 98 m_advances[index2] = s; 99 100 #if PLATFORM(WIN) 101 FloatSize offset = m_offsets[index1]; 102 m_offsets[index1] = m_offsets[index2]; 103 m_offsets[index2] = offset; 104 #endif 105 } 106 glyphAt(int index)107 Glyph glyphAt(int index) const 108 { 109 #if PLATFORM(CAIRO) 110 return m_glyphs[index].index; 111 #else 112 return m_glyphs[index]; 113 #endif 114 } 115 advanceAt(int index)116 float advanceAt(int index) const 117 { 118 #if PLATFORM(CG) 119 return m_advances[index].width; 120 #else 121 return m_advances[index].width(); 122 #endif 123 } 124 offsetAt(int index)125 FloatSize offsetAt(int index) const 126 { 127 #if PLATFORM(WIN) 128 return m_offsets[index]; 129 #else 130 UNUSED_PARAM(index); 131 return FloatSize(); 132 #endif 133 } 134 135 void add(Glyph glyph, const SimpleFontData* font, float width, const FloatSize* offset = 0) 136 { 137 m_fontData.append(font); 138 139 #if PLATFORM(CAIRO) 140 cairo_glyph_t cairoGlyph; 141 cairoGlyph.index = glyph; 142 m_glyphs.append(cairoGlyph); 143 #else 144 m_glyphs.append(glyph); 145 #endif 146 147 #if PLATFORM(CG) 148 CGSize advance = { width, 0 }; 149 m_advances.append(advance); 150 #else 151 m_advances.append(FloatSize(width, 0)); 152 #endif 153 154 #if PLATFORM(WIN) 155 if (offset) 156 m_offsets.append(*offset); 157 else 158 m_offsets.append(FloatSize()); 159 #else 160 UNUSED_PARAM(offset); 161 #endif 162 } 163 add(Glyph glyph,const SimpleFontData * font,GlyphBufferAdvance advance)164 void add(Glyph glyph, const SimpleFontData* font, GlyphBufferAdvance advance) 165 { 166 m_fontData.append(font); 167 #if PLATFORM(CAIRO) 168 cairo_glyph_t cairoGlyph; 169 cairoGlyph.index = glyph; 170 m_glyphs.append(cairoGlyph); 171 #else 172 m_glyphs.append(glyph); 173 #endif 174 175 m_advances.append(advance); 176 } 177 178 private: 179 Vector<const SimpleFontData*, 2048> m_fontData; 180 Vector<GlyphBufferGlyph, 2048> m_glyphs; 181 Vector<GlyphBufferAdvance, 2048> m_advances; 182 #if PLATFORM(WIN) 183 Vector<FloatSize, 2048> m_offsets; 184 #endif 185 }; 186 187 } 188 #endif 189