summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com>2020-03-27 02:06:41 +0200
committerMikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com>2020-04-06 19:18:06 +0300
commitb2ab0804f86f649df1c4d07b246c2009d257ca27 (patch)
treec8e89e3ef4ac4a7b4edc6e9759b6968c5b299e25
parentc829ea7e9243319b802a0984b37dbda1ba1ae536 (diff)
downloadqtlocation-mapboxgl-b2ab0804f86f649df1c4d07b246c2009d257ca27.tar.gz
[render tests][tile mode] Enable automatic labels cut-off detection
-rw-r--r--render-test/metadata.hpp1
-rw-r--r--render-test/parser.cpp6
-rw-r--r--render-test/render_test.cpp2
-rw-r--r--render-test/runner.cpp63
4 files changed, 68 insertions, 4 deletions
diff --git a/render-test/metadata.hpp b/render-test/metadata.hpp
index e64e07ffc3..e40d3773b0 100644
--- a/render-test/metadata.hpp
+++ b/render-test/metadata.hpp
@@ -175,6 +175,7 @@ struct TestMetadata {
unsigned metricsFailed = 0;
unsigned renderErrored = 0;
unsigned renderFailed = 0;
+ unsigned labelCutOffFound = 0;
std::string errorMessage;
double difference = 0.0;
diff --git a/render-test/parser.cpp b/render-test/parser.cpp
index e5c5a1edc9..4e2a1aa98c 100644
--- a/render-test/parser.cpp
+++ b/render-test/parser.cpp
@@ -43,6 +43,7 @@
namespace {
const char* resultsStyle = R"HTML(
+<meta charset="UTF-8">
<style>
body { font: 18px/1.2 -apple-system, BlinkMacSystemFont, "Helvetica Neue", Helvetica, Arial, sans-serif; padding: 10px; }
h1 { font-size: 32px; margin-bottom: 0; }
@@ -1336,8 +1337,9 @@ std::string createResultItem(const TestMetadata& metadata, bool hasFailedTests)
html.append("<p style=\"color: red\"><strong>Error:</strong> " + metadata.errorMessage + "</p>\n");
}
- if (metadata.metricsFailed || metadata.metricsErrored) {
- html.append("<p style=\"color: red\"><strong>Error:</strong> " + metadata.errorMessage + "</p>\n");
+ if (metadata.metricsFailed || metadata.metricsErrored || metadata.labelCutOffFound) {
+ html.append("<p style=\"color: red\"><strong>Error:</strong> " +
+ std::regex_replace(metadata.errorMessage, std::regex{"\n"}, "<br>") + "</p>\n");
}
if (metadata.difference != 0.0) {
diff --git a/render-test/render_test.cpp b/render-test/render_test.cpp
index c4ea7e64ab..a6a372d236 100644
--- a/render-test/render_test.cpp
+++ b/render-test/render_test.cpp
@@ -190,7 +190,7 @@ int runRenderTests(int argc, char** argv, std::function<void()> testStatus) {
runner.run(metadata);
}
- bool errored = metadata.metricsErrored || metadata.renderErrored;
+ bool errored = metadata.metricsErrored || metadata.renderErrored || metadata.labelCutOffFound;
bool passed = !errored && !metadata.metricsFailed && !metadata.renderFailed;
if (shouldIgnore) {
diff --git a/render-test/runner.cpp b/render-test/runner.cpp
index de43e5ddd8..fe006f3a90 100644
--- a/render-test/runner.cpp
+++ b/render-test/runner.cpp
@@ -30,6 +30,9 @@
#include <utility>
#include <sstream>
+#include <codecvt>
+#include <locale>
+
using namespace mbgl;
using namespace TestOperationNames;
@@ -746,6 +749,9 @@ void TestRunner::run(TestMetadata& metadata) {
auto camera = map.getStyle().getDefaultCamera();
HeadlessFrontend::RenderResult result{};
+ std::string cutOffLabelsReport;
+ std::string duplicationsReport;
+ std::size_t duplicationsCount = 0u;
if (metadata.mapMode == MapMode::Tile) {
assert(camera.zoom);
@@ -754,6 +760,12 @@ void TestRunner::run(TestMetadata& metadata) {
assert(!tileIds.empty());
std::set<uint32_t> xDims;
std::set<uint32_t> yDims;
+ struct SymbolLocationAndStatus {
+ UnwrappedTileID tileId;
+ mapbox::geometry::box<float> location;
+ bool placed;
+ };
+ std::map<std::u16string, std::vector<SymbolLocationAndStatus>> symbolIndex;
for (const auto& tileId : tileIds) {
xDims.insert(tileId.canonical.x);
@@ -766,6 +778,7 @@ void TestRunner::run(TestMetadata& metadata) {
PremultipliedImage({uint32_t(xDims.size()) * tileScreenSize, uint32_t(yDims.size()) * tileScreenSize});
for (const auto& tileId : tileIds) {
resetContext(metadata, ctx);
+ ctx.getFrontend().getRenderer()->collectPlacedSymbolData(true);
auto cameraForTile{camera};
cameraForTile.withCenter(getTileCenterCoordinates(tileId));
map.jumpTo(cameraForTile);
@@ -775,9 +788,49 @@ void TestRunner::run(TestMetadata& metadata) {
metadata.errorMessage = "Failed rendering tile: " + util::toString(tileId);
return;
}
-
auto xOffset = getImageTileOffset(xDims, tileId.canonical.x, metadata.pixelRatio);
auto yOffset = getImageTileOffset(yDims, tileId.canonical.y, metadata.pixelRatio);
+
+ const auto& placedSymbols = ctx.getFrontend().getRenderer()->getPlacedSymbolsData();
+ for (const auto& placedSymbol : placedSymbols) {
+ if (placedSymbol.intersectsTileBorder) {
+ if (placedSymbol.textCollisionBox) {
+ mapbox::geometry::box<float> box = *placedSymbol.textCollisionBox;
+ box.min.x += xOffset - placedSymbol.viewportPadding;
+ box.max.x += xOffset - placedSymbol.viewportPadding;
+ box.min.y += yOffset - placedSymbol.viewportPadding;
+ box.max.y += yOffset - placedSymbol.viewportPadding;
+
+ auto& symbols = symbolIndex[placedSymbol.key];
+ auto it = std::find_if(symbols.begin(), symbols.end(), [box](const auto& a) {
+ return a.location.min == box.min && a.location.max == box.max;
+ });
+
+ static std::wstring_convert<std::codecvt_utf8<char16_t>, char16_t> cv;
+ if (it == symbols.end()) {
+ symbols.push_back({tileId, box, placedSymbol.textPlaced});
+ } else if (tileId == it->tileId) {
+ std::stringstream ss;
+ ss << std::endl
+ << ++duplicationsCount << ". \"" << cv.to_bytes(placedSymbol.key) << "\" ((" << box.min.x
+ << ", " << box.min.y << "), (" << box.max.x << ", " << box.max.y << ")) "
+ << "at " << util::toString(tileId);
+ duplicationsReport += ss.str();
+ continue;
+ } else if (it->placed != placedSymbol.textPlaced) {
+ std::stringstream ss;
+ ss << std::endl
+ << ++metadata.labelCutOffFound << ". \"" << cv.to_bytes(placedSymbol.key) << "\" (("
+ << box.min.x << ", " << box.min.y << "), (" << box.max.x << ", " << box.max.y << "))"
+ << (placedSymbol.textPlaced ? " is placed at " : " is not placed at ")
+ << util::toString(tileId) << " and" << (it->placed ? " placed at " : " not placed at ")
+ << util::toString(it->tileId);
+ cutOffLabelsReport += ss.str();
+ }
+ }
+ }
+ }
+
PremultipliedImage::copy(
resultForTile.image, result.image, {0, 0}, {xOffset, yOffset}, resultForTile.image.size);
result.stats += resultForTile.stats;
@@ -796,6 +849,14 @@ void TestRunner::run(TestMetadata& metadata) {
if (metadata.renderTest) {
checkProbingResults(metadata);
+ if (metadata.labelCutOffFound) { // Append label cut-off statistics.
+ metadata.errorMessage += "\n Label cut-offs:";
+ metadata.errorMessage += cutOffLabelsReport;
+ if (duplicationsCount) {
+ metadata.errorMessage += "\n\n Label duplications:";
+ metadata.errorMessage += duplicationsReport;
+ }
+ }
checkRenderTestResults(std::move(result.image), metadata);
} else {
std::vector<mbgl::Feature> features;