summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2018-03-25 07:26:59 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2018-03-25 07:26:59 +0000
commitaed679a03b2b4705ed37d4dec92c77e0ce7326d1 (patch)
treecbeec3391bb98477a49d8e0b94a461ba43326de8
parent46bc5275e698f9f6d1e5c4a2c6c142322f1d257a (diff)
parent2adb04f8edb61857a2c53c16ced533df47be67c3 (diff)
downloadminikin-aed679a03b2b4705ed37d4dec92c77e0ce7326d1.tar.gz
Snap for 4677756 from 2adb04f8edb61857a2c53c16ced533df47be67c3 to pi-release
Change-Id: I7f8e0b0fe091407da480dcb6dbb8e1e25716367a
-rw-r--r--libs/minikin/CmapCoverage.cpp22
-rw-r--r--libs/minikin/LineBreakerUtil.h18
-rw-r--r--tests/unittest/CmapCoverageTest.cpp25
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) {