Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(181)

Unified Diff: Source/platform/fonts/GlyphBuffer.h

Issue 676523003: Offset-only GlyphBuffer (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: review comments Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: Source/platform/fonts/GlyphBuffer.h
diff --git a/Source/platform/fonts/GlyphBuffer.h b/Source/platform/fonts/GlyphBuffer.h
index 9ccd92ab1c360e70a8bd603f02ea2b9397178215..606a5f5b88160958b16b7764b104754d706119f5 100644
--- a/Source/platform/fonts/GlyphBuffer.h
+++ b/Source/platform/fonts/GlyphBuffer.h
@@ -31,7 +31,7 @@
#define GlyphBuffer_h
#include "platform/fonts/Glyph.h"
-#include "platform/geometry/FloatSize.h"
+#include "platform/geometry/FloatPoint.h"
#include "platform/heap/Heap.h"
#include "wtf/Vector.h"
@@ -43,68 +43,120 @@ class GlyphBuffer {
STACK_ALLOCATED();
public:
bool isEmpty() const { return m_fontData.isEmpty(); }
- bool hasOffsets() const { return !m_offsets.isEmpty(); }
- unsigned size() const { return m_fontData.size(); }
+ unsigned size() const
+ {
+ ASSERT(m_fontData.size() == m_glyphs.size());
+ ASSERT(m_fontData.size() == m_offsets.size() || 2 * m_fontData.size() == m_offsets.size());
+ return m_fontData.size();
+ }
+
+ bool hasVerticalOffsets() const
+ {
+ // We exclusively store either horizontal/x-only ofssets -- in which case m_offsets.size == size,
+ // or vertical/xy offsets -- in which case m_offsets.size == size * 2.
+ return size() != m_offsets.size();
+ }
- const Glyph* glyphs(unsigned from) const { return m_glyphs.data() + from; }
- const float* advances(unsigned from) const { return m_advances.data() + from; }
- const FloatSize* offsets(unsigned from) const { return m_offsets.data() + from; }
+ const Glyph* glyphs(unsigned from) const
+ {
+ ASSERT(from < size());
+ return m_glyphs.data() + from;
+ }
+
+ const float* offsets(unsigned from) const
+ {
+ ASSERT(from < size());
+ return m_offsets.data() + (hasVerticalOffsets() ? from * 2 : from);
+ }
const SimpleFontData* fontDataAt(unsigned index) const
{
+ ASSERT(index < size());
return m_fontData[index];
}
Glyph glyphAt(unsigned index) const
{
+ ASSERT(index < size());
return m_glyphs[index];
}
- float advanceAt(unsigned index) const
+ float xOffsetAt(unsigned index) const
+ {
+ ASSERT(index < size());
+ return hasVerticalOffsets() ? m_offsets[index * 2] : m_offsets[index];
+
+ }
+
+ float yOffsetAt(unsigned index) const
{
- return m_advances[index];
+ ASSERT(index < size());
+ ASSERT(hasVerticalOffsets());
+ return m_offsets[index * 2 + 1];
}
- void add(Glyph glyph, const SimpleFontData* font, float width)
+ void add(Glyph glyph, const SimpleFontData* font, float x)
{
- // should not mix offset/advance-only glyphs
- ASSERT(!hasOffsets());
+ // cannot mix x-only/xy offsets
+ ASSERT(!hasVerticalOffsets());
m_fontData.append(font);
m_glyphs.append(glyph);
- m_advances.append(width);
+ m_offsets.append(x);
}
- void add(Glyph glyph, const SimpleFontData* font, const FloatSize& offset, float advance)
+ void add(Glyph glyph, const SimpleFontData* font, const FloatPoint& offset)
{
- // should not mix offset/advance-only glyphs
- ASSERT(size() == m_offsets.size());
+ // cannot mix x-only/xy offsets
+ ASSERT(isEmpty() || hasVerticalOffsets());
m_fontData.append(font);
m_glyphs.append(glyph);
- m_offsets.append(offset);
- m_advances.append(advance);
+ m_offsets.append(offset.x());
+ m_offsets.append(offset.y());
}
- void reverse()
+ void reverseForSimpleRTL(float afterOffset, float totalWidth)
{
+ ASSERT(!hasVerticalOffsets());
+
+ if (isEmpty())
+ return;
+
m_fontData.reverse();
m_glyphs.reverse();
- m_advances.reverse();
- }
- void expandLastAdvance(float width)
- {
- ASSERT(!isEmpty());
- float& lastAdvance = m_advances.last();
- lastAdvance += width;
+ // | .. [X0 X1 .. Xn] .. |
+ // ^ ^ ^
+ // 0 afterOffset totalWidth
+ //
+ // The input buffer is shaped using RTL advances, but since the right edge is unknown at
+ // that time, offsets are computed as if the advances were LTR. This method performs the
+ // required adjustments by reconstructing advances and positioning offsets in an RTL
+ // progression.
+
+ // FIXME: we should get rid of this (idea: store negative offsets while shaping,
+ // and adjust the initial advance accordingly -> should yield correctly positioned
+ // RTL glyphs without any post-shape munging).
+ ASSERT_WITH_SECURITY_IMPLICATION(!m_offsets.isEmpty());
+ float x = totalWidth - m_offsets[0];
+ for (unsigned i = 0; i + 1 < m_offsets.size(); ++i) {
+ float advance = m_offsets[i + 1] - m_offsets[i];
+ ASSERT(advance >= 0);
+ x -= advance;
+ m_offsets[i] = x;
+ }
+ float lastAdvance = afterOffset - m_offsets.last();
+ ASSERT(lastAdvance >= 0);
+ m_offsets.last() = x - lastAdvance;
+
+ m_offsets.reverse();
}
protected:
Vector<const SimpleFontData*, 2048> m_fontData;
Vector<Glyph, 2048> m_glyphs;
- Vector<float, 2048> m_advances;
- Vector<FloatSize, 1024> m_offsets;
+ Vector<float, 2048> m_offsets;
};
} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698