Fix Layout initialization in the skipCache path

C++ local var initialization always tricks me.  Previously, Layout
didn't have a constructor, which meant that defining it on the stack
left mAdvance uninitialized.  This was not an issue when we were doing
"new Layout()", since that invokes zero-initialization, but was an
issue for the skipCache path that was allocating layout on stack by
just "Layout l" instead of "Layout l = Layout()".  To avoid surprises,
add a constructors that clears everything.

Also adds reset() method to reset the layout for reuse.

Change-Id: I3e02f00da9dd7d360abe13f63c310f6882292d0a
This commit is contained in:
Behdad Esfahbod
2014-08-21 16:30:03 -04:00
parent a33151e9c7
commit df03550a40
2 changed files with 20 additions and 8 deletions

View File

@@ -64,6 +64,14 @@ class LayoutContext;
// extend through the lifetime of the Layout object.
class Layout {
public:
Layout() : mGlyphs(), mAdvances(), mCollection(0), mFaces(), mAdvance(0), mBounds() {
mBounds.setEmpty();
}
// Clears layout, ready to be used again
void reset();
void dump() const;
void setFontCollection(const FontCollection* collection);
@@ -72,8 +80,7 @@ public:
void draw(Bitmap*, int x0, int y0, float size) const;
// This must be called before any invocations.
// TODO: probably have a factory instead
// Deprecated. Nont needed. Remove when callers are removed.
static void init();
// public accessors

View File

@@ -267,10 +267,18 @@ void MinikinRect::join(const MinikinRect& r) {
}
}
// TODO: the actual initialization is deferred, maybe make this explicit
// Deprecated. Remove when callers are removed.
void Layout::init() {
}
void Layout::reset() {
mGlyphs.clear();
mFaces.clear();
mBounds.setEmpty();
mAdvances.clear();
mAdvance = 0;
}
void Layout::setFontCollection(const FontCollection* collection) {
mCollection = collection;
}
@@ -519,12 +527,9 @@ void Layout::doLayout(const uint16_t* buf, size_t start, size_t count, size_t bu
bool isRtl = (bidiFlags & kDirection_Mask) != 0;
bool doSingleRun = true;
mGlyphs.clear();
mFaces.clear();
mBounds.setEmpty();
mAdvances.clear();
reset();
mAdvances.resize(count, 0);
mAdvance = 0;
if (!(bidiFlags == kBidi_Force_LTR || bidiFlags == kBidi_Force_RTL)) {
UBiDi* bidi = ubidi_open();
if (bidi) {