diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2018-03-25 07:26:59 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2018-03-25 07:26:59 +0000 |
commit | aed679a03b2b4705ed37d4dec92c77e0ce7326d1 (patch) | |
tree | cbeec3391bb98477a49d8e0b94a461ba43326de8 | |
parent | 46bc5275e698f9f6d1e5c4a2c6c142322f1d257a (diff) | |
parent | 2adb04f8edb61857a2c53c16ced533df47be67c3 (diff) | |
download | minikin-aed679a03b2b4705ed37d4dec92c77e0ce7326d1.tar.gz |
Snap for 4677756 from 2adb04f8edb61857a2c53c16ced533df47be67c3 to pi-release
Change-Id: I7f8e0b0fe091407da480dcb6dbb8e1e25716367a
-rw-r--r-- | libs/minikin/CmapCoverage.cpp | 22 | ||||
-rw-r--r-- | libs/minikin/LineBreakerUtil.h | 18 | ||||
-rw-r--r-- | tests/unittest/CmapCoverageTest.cpp | 25 |
3 files changed, 54 insertions, 11 deletions
diff --git a/libs/minikin/CmapCoverage.cpp b/libs/minikin/CmapCoverage.cpp index c00cec7..f6143d3 100644 --- a/libs/minikin/CmapCoverage.cpp +++ b/libs/minikin/CmapCoverage.cpp @@ -61,6 +61,22 @@ static bool addRange(std::vector<uint32_t>& coverage, uint32_t start, uint32_t e } } +// Returns true if the range is appended. Otherwise returns false as an error. +static bool addRangeCmap4(std::vector<uint32_t>& coverage, uint32_t start, uint32_t end) { + if (!coverage.empty() && coverage.back() > end) { + // Reject unordered end code points. + return false; + } + if (coverage.empty() || coverage.back() < start) { + coverage.push_back(start); + coverage.push_back(end); + return true; + } else { + coverage.back() = end; + return true; + } +} + // Returns Range from given ranges vector. Returns invalidRange if i is out of range. static inline Range getRange(const std::vector<uint32_t>& r, size_t i) { return i + 1 < r.size() ? Range({r[i], r[i + 1]}) : Range::invalidRange(); @@ -157,13 +173,13 @@ static bool getCoverageFormat4(std::vector<uint32_t>& coverage, const uint8_t* d if (rangeOffset == 0) { uint32_t delta = readU16(data, kHeaderSize + 2 * (2 * segCount + i)); if (((end + delta) & 0xffff) > end - start) { - if (!addRange(coverage, start, end + 1)) { + if (!addRangeCmap4(coverage, start, end + 1)) { return false; } } else { for (uint32_t j = start; j < end + 1; j++) { if (((j + delta) & 0xffff) != 0) { - if (!addRange(coverage, j, j + 1)) { + if (!addRangeCmap4(coverage, j, j + 1)) { return false; } } @@ -179,7 +195,7 @@ static bool getCoverageFormat4(std::vector<uint32_t>& coverage, const uint8_t* d } uint32_t glyphId = readU16(data, actualRangeOffset); if (glyphId != 0) { - if (!addRange(coverage, j, j + 1)) { + if (!addRangeCmap4(coverage, j, j + 1)) { return false; } } diff --git a/libs/minikin/LineBreakerUtil.h b/libs/minikin/LineBreakerUtil.h index 406de7b..64f4371 100644 --- a/libs/minikin/LineBreakerUtil.h +++ b/libs/minikin/LineBreakerUtil.h @@ -87,14 +87,16 @@ inline void populateHyphenationPoints( } auto hyphenPart = contextRange.split(i); - const float first = run.measureHyphenPiece( - textBuf /* text */, hyphenPart.first /* hyphenated piece range */, - StartHyphenEdit::NO_EDIT /* start hyphen edit */, - editForThisLine(hyph) /* end hyphen edit */, nullptr /* advances */, pieces); - const float second = run.measureHyphenPiece( - textBuf /* text */, hyphenPart.second /* hyphenated piece range */, - editForNextLine(hyph) /* start hyphen edit */, - EndHyphenEdit::NO_EDIT /* end hyphen edit */, nullptr /* advances */, pieces); + U16StringPiece firstText = textBuf.substr(hyphenPart.first); + U16StringPiece secondText = textBuf.substr(hyphenPart.second); + const float first = run.measureHyphenPiece(firstText, Range(0, firstText.size()), + StartHyphenEdit::NO_EDIT /* start hyphen edit */, + editForThisLine(hyph) /* end hyphen edit */, + nullptr /* advances */, pieces); + const float second = run.measureHyphenPiece(secondText, Range(0, secondText.size()), + editForNextLine(hyph) /* start hyphen edit */, + EndHyphenEdit::NO_EDIT /* end hyphen edit */, + nullptr /* advances */, pieces); out->emplace_back(i, hyph, first, second); } diff --git a/tests/unittest/CmapCoverageTest.cpp b/tests/unittest/CmapCoverageTest.cpp index febfc37..9dba583 100644 --- a/tests/unittest/CmapCoverageTest.cpp +++ b/tests/unittest/CmapCoverageTest.cpp @@ -490,6 +490,31 @@ TEST(CmapCoverageTest, brokenFormat4Table) { EXPECT_EQ(0U, coverage.length()); EXPECT_TRUE(vsTables.empty()); } + { + SCOPED_TRACE("Reversed end code points"); + std::vector<uint8_t> table = + buildCmapFormat4Table(std::vector<uint16_t>({'b', 'b', 'a', 'a'})); + CmapBuilder builder(1); + builder.appendTable(0, 0, table); + std::vector<uint8_t> cmap = builder.build(); + + SparseBitSet coverage = CmapCoverage::getCoverage(cmap.data(), cmap.size(), &vsTables); + EXPECT_EQ(0U, coverage.length()); + EXPECT_TRUE(vsTables.empty()); + } +} + +TEST(CmapCoverageTest, duplicatedCmap4EntryTest) { + std::vector<std::unique_ptr<SparseBitSet>> vsTables; + std::vector<uint8_t> table = buildCmapFormat4Table(std::vector<uint16_t>({'a', 'b', 'b', 'b'})); + CmapBuilder builder(1); + builder.appendTable(0, 0, table); + std::vector<uint8_t> cmap = builder.build(); + + SparseBitSet coverage = CmapCoverage::getCoverage(cmap.data(), cmap.size(), &vsTables); + EXPECT_TRUE(coverage.get('a')); + EXPECT_TRUE(coverage.get('b')); + EXPECT_TRUE(vsTables.empty()); } TEST(CmapCoverageTest, brokenFormat12Table) { |