diff --git a/include/minikin/Layout.h b/include/minikin/Layout.h index e9849c382c3..8a6e7725d0a 100644 --- a/include/minikin/Layout.h +++ b/include/minikin/Layout.h @@ -75,8 +75,7 @@ enum { class Layout { public: - Layout(const std::shared_ptr& collection) - : mGlyphs(), mAdvances(), mCollection(collection), mFaces(), mAdvance(0), mBounds() { + Layout() : mGlyphs(), mAdvances(), mFaces(), mAdvance(0), mBounds() { mBounds.setEmpty(); } @@ -89,7 +88,8 @@ public: void dump() const; void doLayout(const uint16_t* buf, size_t start, size_t count, size_t bufSize, - int bidiFlags, const FontStyle &style, const MinikinPaint &paint); + int bidiFlags, const FontStyle &style, const MinikinPaint &paint, + const std::shared_ptr& collection); static float measureText(const uint16_t* buf, size_t start, size_t count, size_t bufSize, int bidiFlags, const FontStyle &style, const MinikinPaint &paint, @@ -143,7 +143,7 @@ private: // Lay out a single bidi run void doLayoutRun(const uint16_t* buf, size_t start, size_t count, size_t bufSize, - bool isRtl, LayoutContext* ctx); + bool isRtl, LayoutContext* ctx, const std::shared_ptr& collection); // Append another layout (for example, cached value) into this one void appendLayout(Layout* src, size_t start, float extraAdvance); @@ -151,7 +151,6 @@ private: std::vector mGlyphs; std::vector mAdvances; - std::shared_ptr mCollection; std::vector mFaces; float mAdvance; MinikinRect mBounds; diff --git a/libs/minikin/Layout.cpp b/libs/minikin/Layout.cpp index 743cb763aea..4032d4c9432 100644 --- a/libs/minikin/Layout.cpp +++ b/libs/minikin/Layout.cpp @@ -131,10 +131,11 @@ public: mChars = NULL; } - void doLayout(Layout* layout, LayoutContext* ctx) const { + void doLayout(Layout* layout, LayoutContext* ctx, + const std::shared_ptr& collection) const { layout->mAdvances.resize(mCount, 0); ctx->clearHbFonts(); - layout->doLayoutRun(mChars, mStart, mCount, mNchars, mIsRtl, ctx); + layout->doLayoutRun(mChars, mStart, mCount, mNchars, mIsRtl, ctx, collection); } private: @@ -173,8 +174,8 @@ public: Layout* layout = mCache.get(key); if (layout == NULL) { key.copyText(); - layout = new Layout(collection); - key.doLayout(layout, ctx); + layout = new Layout(); + key.doLayout(layout, ctx, collection); mCache.put(key, layout); } return layout; @@ -584,7 +585,8 @@ BidiText::BidiText(const uint16_t* buf, size_t start, size_t count, size_t bufSi } void Layout::doLayout(const uint16_t* buf, size_t start, size_t count, size_t bufSize, - int bidiFlags, const FontStyle &style, const MinikinPaint &paint) { + int bidiFlags, const FontStyle &style, const MinikinPaint &paint, + const std::shared_ptr& collection) { android::AutoMutex _l(gMinikinLock); LayoutContext ctx; @@ -596,7 +598,7 @@ void Layout::doLayout(const uint16_t* buf, size_t start, size_t count, size_t bu for (const BidiText::Iter::RunInfo& runInfo : BidiText(buf, start, count, bufSize, bidiFlags)) { doLayoutRunCached(buf, runInfo.mRunStart, runInfo.mRunLength, bufSize, runInfo.mIsRtl, &ctx, - start, mCollection, this, NULL); + start, collection, this, NULL); } ctx.clearHbFonts(); } @@ -684,8 +686,8 @@ float Layout::doLayoutWord(const uint16_t* buf, size_t start, size_t count, size float advance; if (ctx->paint.skipCache()) { - Layout layoutForWord(collection); - key.doLayout(&layoutForWord, ctx); + Layout layoutForWord; + key.doLayout(&layoutForWord, ctx, collection); if (layout) { layout->appendLayout(&layoutForWord, bufStart, wordSpacing); } @@ -863,10 +865,10 @@ static inline uint32_t addToHbBuffer(hb_buffer_t* buffer, void Layout::doLayoutRun(const uint16_t* buf, size_t start, size_t count, size_t bufSize, - bool isRtl, LayoutContext* ctx) { + bool isRtl, LayoutContext* ctx, const std::shared_ptr& collection) { hb_buffer_t* buffer = LayoutEngine::getInstance().hbBuffer; vector items; - mCollection->itemize(buf + start, count, ctx->style, &items); + collection->itemize(buf + start, count, ctx->style, &items); vector features; // Disable default-on non-required ligature features if letter-spacing diff --git a/tests/unittest/LayoutTest.cpp b/tests/unittest/LayoutTest.cpp index ed41ca45742..1770d3ac5e2 100644 --- a/tests/unittest/LayoutTest.cpp +++ b/tests/unittest/LayoutTest.cpp @@ -70,14 +70,15 @@ TEST_F(LayoutTest, doLayoutTest) { float advances[kMaxAdvanceLength]; std::vector expectedValues; - Layout layout(mCollection); + Layout layout; std::vector text; // The mock implementation returns 10.0f advance and 0,0-10x10 bounds for all glyph. { SCOPED_TRACE("one word"); text = utf8ToUtf16("oneword"); - layout.doLayout(text.data(), 0, text.size(), text.size(), kBidi_LTR, FontStyle(), paint); + layout.doLayout(text.data(), 0, text.size(), text.size(), kBidi_LTR, FontStyle(), paint, + mCollection); EXPECT_EQ(70.0f, layout.getAdvance()); layout.getBounds(&rect); EXPECT_EQ(0.0f, rect.mLeft); @@ -95,7 +96,8 @@ TEST_F(LayoutTest, doLayoutTest) { { SCOPED_TRACE("two words"); text = utf8ToUtf16("two words"); - layout.doLayout(text.data(), 0, text.size(), text.size(), kBidi_LTR, FontStyle(), paint); + layout.doLayout(text.data(), 0, text.size(), text.size(), kBidi_LTR, FontStyle(), paint, + mCollection); EXPECT_EQ(90.0f, layout.getAdvance()); layout.getBounds(&rect); EXPECT_EQ(0.0f, rect.mLeft); @@ -113,7 +115,8 @@ TEST_F(LayoutTest, doLayoutTest) { { SCOPED_TRACE("three words"); text = utf8ToUtf16("three words test"); - layout.doLayout(text.data(), 0, text.size(), text.size(), kBidi_LTR, FontStyle(), paint); + layout.doLayout(text.data(), 0, text.size(), text.size(), kBidi_LTR, FontStyle(), paint, + mCollection); EXPECT_EQ(160.0f, layout.getAdvance()); layout.getBounds(&rect); EXPECT_EQ(0.0f, rect.mLeft); @@ -131,7 +134,8 @@ TEST_F(LayoutTest, doLayoutTest) { { SCOPED_TRACE("two spaces"); text = utf8ToUtf16("two spaces"); - layout.doLayout(text.data(), 0, text.size(), text.size(), kBidi_LTR, FontStyle(), paint); + layout.doLayout(text.data(), 0, text.size(), text.size(), kBidi_LTR, FontStyle(), paint, + mCollection); EXPECT_EQ(110.0f, layout.getAdvance()); layout.getBounds(&rect); EXPECT_EQ(0.0f, rect.mLeft); @@ -156,7 +160,7 @@ TEST_F(LayoutTest, doLayoutTest_wordSpacing) { std::vector expectedValues; std::vector text; - Layout layout(mCollection); + Layout layout; paint.wordSpacing = 5.0f; @@ -164,7 +168,8 @@ TEST_F(LayoutTest, doLayoutTest_wordSpacing) { { SCOPED_TRACE("one word"); text = utf8ToUtf16("oneword"); - layout.doLayout(text.data(), 0, text.size(), text.size(), kBidi_LTR, FontStyle(), paint); + layout.doLayout(text.data(), 0, text.size(), text.size(), kBidi_LTR, FontStyle(), paint, + mCollection); EXPECT_EQ(70.0f, layout.getAdvance()); layout.getBounds(&rect); EXPECT_EQ(0.0f, rect.mLeft); @@ -182,7 +187,8 @@ TEST_F(LayoutTest, doLayoutTest_wordSpacing) { { SCOPED_TRACE("two words"); text = utf8ToUtf16("two words"); - layout.doLayout(text.data(), 0, text.size(), text.size(), kBidi_LTR, FontStyle(), paint); + layout.doLayout(text.data(), 0, text.size(), text.size(), kBidi_LTR, FontStyle(), paint, + mCollection); EXPECT_EQ(95.0f, layout.getAdvance()); layout.getBounds(&rect); EXPECT_EQ(0.0f, rect.mLeft); @@ -204,7 +210,8 @@ TEST_F(LayoutTest, doLayoutTest_wordSpacing) { { SCOPED_TRACE("three words test"); text = utf8ToUtf16("three words test"); - layout.doLayout(text.data(), 0, text.size(), text.size(), kBidi_LTR, FontStyle(), paint); + layout.doLayout(text.data(), 0, text.size(), text.size(), kBidi_LTR, FontStyle(), paint, + mCollection); EXPECT_EQ(170.0f, layout.getAdvance()); layout.getBounds(&rect); EXPECT_EQ(0.0f, rect.mLeft); @@ -224,7 +231,8 @@ TEST_F(LayoutTest, doLayoutTest_wordSpacing) { { SCOPED_TRACE("two spaces"); text = utf8ToUtf16("two spaces"); - layout.doLayout(text.data(), 0, text.size(), text.size(), kBidi_LTR, FontStyle(), paint); + layout.doLayout(text.data(), 0, text.size(), text.size(), kBidi_LTR, FontStyle(), paint, + mCollection); EXPECT_EQ(120.0f, layout.getAdvance()); layout.getBounds(&rect); EXPECT_EQ(0.0f, rect.mLeft); @@ -250,7 +258,7 @@ TEST_F(LayoutTest, doLayoutTest_negativeWordSpacing) { float advances[kMaxAdvanceLength]; std::vector expectedValues; - Layout layout(mCollection); + Layout layout; std::vector text; // Negative word spacing also should work. @@ -259,7 +267,8 @@ TEST_F(LayoutTest, doLayoutTest_negativeWordSpacing) { { SCOPED_TRACE("one word"); text = utf8ToUtf16("oneword"); - layout.doLayout(text.data(), 0, text.size(), text.size(), kBidi_LTR, FontStyle(), paint); + layout.doLayout(text.data(), 0, text.size(), text.size(), kBidi_LTR, FontStyle(), paint, + mCollection); EXPECT_EQ(70.0f, layout.getAdvance()); layout.getBounds(&rect); EXPECT_EQ(0.0f, rect.mLeft); @@ -277,7 +286,8 @@ TEST_F(LayoutTest, doLayoutTest_negativeWordSpacing) { { SCOPED_TRACE("two words"); text = utf8ToUtf16("two words"); - layout.doLayout(text.data(), 0, text.size(), text.size(), kBidi_LTR, FontStyle(), paint); + layout.doLayout(text.data(), 0, text.size(), text.size(), kBidi_LTR, FontStyle(), paint, + mCollection); EXPECT_EQ(85.0f, layout.getAdvance()); layout.getBounds(&rect); EXPECT_EQ(0.0f, rect.mLeft); @@ -296,7 +306,8 @@ TEST_F(LayoutTest, doLayoutTest_negativeWordSpacing) { { SCOPED_TRACE("three words"); text = utf8ToUtf16("three word test"); - layout.doLayout(text.data(), 0, text.size(), text.size(), kBidi_LTR, FontStyle(), paint); + layout.doLayout(text.data(), 0, text.size(), text.size(), kBidi_LTR, FontStyle(), paint, + mCollection); EXPECT_EQ(140.0f, layout.getAdvance()); layout.getBounds(&rect); EXPECT_EQ(0.0f, rect.mLeft); @@ -316,7 +327,8 @@ TEST_F(LayoutTest, doLayoutTest_negativeWordSpacing) { { SCOPED_TRACE("two spaces"); text = utf8ToUtf16("two spaces"); - layout.doLayout(text.data(), 0, text.size(), text.size(), kBidi_LTR, FontStyle(), paint); + layout.doLayout(text.data(), 0, text.size(), text.size(), kBidi_LTR, FontStyle(), paint, + mCollection); EXPECT_EQ(100.0f, layout.getAdvance()); layout.getBounds(&rect); EXPECT_EQ(0.0f, rect.mLeft); @@ -340,11 +352,13 @@ TEST_F(LayoutTest, doLayoutTest_rtlTest) { std::vector text = parseUnicodeString("'a' 'b' U+3042 U+3043 'c' 'd'"); - Layout ltrLayout(mCollection); - ltrLayout.doLayout(text.data(), 0, text.size(), text.size(), kBidi_LTR, FontStyle(), paint); + Layout ltrLayout; + ltrLayout.doLayout(text.data(), 0, text.size(), text.size(), kBidi_LTR, FontStyle(), paint, + mCollection); - Layout rtlLayout(mCollection); - rtlLayout.doLayout(text.data(), 0, text.size(), text.size(), kBidi_RTL, FontStyle(), paint); + Layout rtlLayout; + rtlLayout.doLayout(text.data(), 0, text.size(), text.size(), kBidi_RTL, FontStyle(), paint, + mCollection); ASSERT_EQ(ltrLayout.nGlyphs(), rtlLayout.nGlyphs()); ASSERT_EQ(6u, ltrLayout.nGlyphs()); @@ -357,7 +371,7 @@ TEST_F(LayoutTest, doLayoutTest_rtlTest) { } TEST_F(LayoutTest, hyphenationTest) { - Layout layout(mCollection); + Layout layout; std::vector text; // The mock implementation returns 10.0f advance for all glyphs. @@ -366,7 +380,8 @@ TEST_F(LayoutTest, hyphenationTest) { text = utf8ToUtf16("oneword"); MinikinPaint paint; paint.hyphenEdit = HyphenEdit::NO_EDIT; - layout.doLayout(text.data(), 0, text.size(), text.size(), kBidi_LTR, FontStyle(), paint); + layout.doLayout(text.data(), 0, text.size(), text.size(), kBidi_LTR, FontStyle(), paint, + mCollection); EXPECT_EQ(70.0f, layout.getAdvance()); } { @@ -374,7 +389,8 @@ TEST_F(LayoutTest, hyphenationTest) { text = utf8ToUtf16("oneword"); MinikinPaint paint; paint.hyphenEdit = HyphenEdit::INSERT_HYPHEN_AT_END; - layout.doLayout(text.data(), 0, text.size(), text.size(), kBidi_LTR, FontStyle(), paint); + layout.doLayout(text.data(), 0, text.size(), text.size(), kBidi_LTR, FontStyle(), paint, + mCollection); EXPECT_EQ(80.0f, layout.getAdvance()); } { @@ -382,7 +398,8 @@ TEST_F(LayoutTest, hyphenationTest) { text = utf8ToUtf16("oneword"); MinikinPaint paint; paint.hyphenEdit = HyphenEdit::REPLACE_WITH_HYPHEN_AT_END; - layout.doLayout(text.data(), 0, text.size(), text.size(), kBidi_LTR, FontStyle(), paint); + layout.doLayout(text.data(), 0, text.size(), text.size(), kBidi_LTR, FontStyle(), paint, + mCollection); EXPECT_EQ(70.0f, layout.getAdvance()); } { @@ -390,7 +407,8 @@ TEST_F(LayoutTest, hyphenationTest) { text = utf8ToUtf16("oneword"); MinikinPaint paint; paint.hyphenEdit = HyphenEdit::INSERT_HYPHEN_AT_START; - layout.doLayout(text.data(), 0, text.size(), text.size(), kBidi_LTR, FontStyle(), paint); + layout.doLayout(text.data(), 0, text.size(), text.size(), kBidi_LTR, FontStyle(), paint, + mCollection); EXPECT_EQ(80.0f, layout.getAdvance()); } { @@ -398,7 +416,8 @@ TEST_F(LayoutTest, hyphenationTest) { text = utf8ToUtf16("oneword"); MinikinPaint paint; paint.hyphenEdit = HyphenEdit::INSERT_HYPHEN_AT_START | HyphenEdit::INSERT_HYPHEN_AT_END; - layout.doLayout(text.data(), 0, text.size(), text.size(), kBidi_LTR, FontStyle(), paint); + layout.doLayout(text.data(), 0, text.size(), text.size(), kBidi_LTR, FontStyle(), paint, + mCollection); EXPECT_EQ(90.0f, layout.getAdvance()); } }