2 * Copyright (C) 2006, 2009, 2011 Apple Inc. All rights reserved.
3 * Copyright (C) 2007-2008 Torch Mobile Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
33 #include "platform/fonts/Glyph.h"
34 #include "platform/geometry/FloatPoint.h"
35 #include "platform/heap/Heap.h"
36 #include "wtf/Vector.h"
45 bool isEmpty() const { return m_fontData
.isEmpty(); }
48 ASSERT(m_fontData
.size() == m_glyphs
.size());
49 ASSERT(m_fontData
.size() == m_offsets
.size() || 2 * m_fontData
.size() == m_offsets
.size());
50 return m_fontData
.size();
53 bool hasVerticalOffsets() const
55 // We exclusively store either horizontal/x-only ofssets -- in which case m_offsets.size == size,
56 // or vertical/xy offsets -- in which case m_offsets.size == size * 2.
57 return size() != m_offsets
.size();
60 const Glyph
* glyphs(unsigned from
) const
62 ASSERT(from
< size());
63 return m_glyphs
.data() + from
;
66 // Depending on the GlyphBuffer-wide positioning mode, this either points to an array of
67 // x-only offsets for horizontal positioning ([x1, x2, ... xn]), or interleaved x,y offsets
68 // for full positioning ([x1, y1, x2, y2, ... xn, yn]).
69 const float* offsets(unsigned from
) const
71 ASSERT(from
< size());
72 return m_offsets
.data() + (hasVerticalOffsets() ? from
* 2 : from
);
75 const SimpleFontData
* fontDataAt(unsigned index
) const
77 ASSERT(index
< size());
78 return m_fontData
[index
];
81 Glyph
glyphAt(unsigned index
) const
83 ASSERT(index
< size());
84 return m_glyphs
[index
];
87 float xOffsetAt(unsigned index
) const
89 ASSERT(index
< size());
90 return hasVerticalOffsets() ? m_offsets
[index
* 2] : m_offsets
[index
];
94 float yOffsetAt(unsigned index
) const
96 ASSERT(index
< size());
97 ASSERT(hasVerticalOffsets());
98 return m_offsets
[index
* 2 + 1];
101 void add(Glyph glyph
, const SimpleFontData
* font
, float x
)
103 // cannot mix x-only/xy offsets
104 ASSERT(!hasVerticalOffsets());
106 m_fontData
.append(font
);
107 m_glyphs
.append(glyph
);
111 void add(Glyph glyph
, const SimpleFontData
* font
, const FloatPoint
& offset
)
113 // cannot mix x-only/xy offsets
114 ASSERT(isEmpty() || hasVerticalOffsets());
116 m_fontData
.append(font
);
117 m_glyphs
.append(glyph
);
118 m_offsets
.append(offset
.x());
119 m_offsets
.append(offset
.y());
122 void reverseForSimpleRTL(float afterOffset
, float totalWidth
)
124 ASSERT(!hasVerticalOffsets());
129 m_fontData
.reverse();
132 // | .. [X0 X1 .. Xn] .. |
134 // 0 afterOffset totalWidth
136 // The input buffer is shaped using RTL advances, but since the right edge is unknown at
137 // that time, offsets are computed as if the advances were LTR. This method performs the
138 // required adjustments by reconstructing advances and positioning offsets in an RTL
141 // FIXME: we should get rid of this (idea: store negative offsets while shaping,
142 // and adjust the initial advance accordingly -> should yield correctly positioned
143 // RTL glyphs without any post-shape munging).
144 ASSERT_WITH_SECURITY_IMPLICATION(!m_offsets
.isEmpty());
145 for (unsigned i
= 0; i
+ 1 < m_offsets
.size(); ++i
)
146 m_offsets
[i
] = totalWidth
- m_offsets
[i
+ 1];
147 m_offsets
.last() = totalWidth
- afterOffset
;
153 Vector
<const SimpleFontData
*, 2048> m_fontData
;
154 Vector
<Glyph
, 2048> m_glyphs
;
156 // Glyph positioning: either x-only offsets, or interleaved x,y offsets
157 // (depending on the buffer-wide positioning mode). This matches the
158 // glyph positioning format used by Skia.
159 Vector
<float, 2048> m_offsets
;