Home | History | Annotate | Download | only in graphics
      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:
     73     bool isEmpty() const { return m_fontData.isEmpty(); }
     74     int size() const { return m_fontData.size(); }
     75 
     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 
     86     GlyphBufferGlyph* glyphs(int from) { return m_glyphs.data() + from; }
     87     GlyphBufferAdvance* advances(int from) { return m_advances.data() + from; }
     88     const GlyphBufferGlyph* glyphs(int from) const { return m_glyphs.data() + from; }
     89     const GlyphBufferAdvance* advances(int from) const { return m_advances.data() + from; }
     90 
     91     const SimpleFontData* fontDataAt(int index) const { return m_fontData[index]; }
     92 
     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 
    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 
    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 
    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)
    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 
    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