diff options
author | Mikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com> | 2020-03-27 02:06:41 +0200 |
---|---|---|
committer | Mikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com> | 2020-04-06 19:18:06 +0300 |
commit | b2ab0804f86f649df1c4d07b246c2009d257ca27 (patch) | |
tree | c8e89e3ef4ac4a7b4edc6e9759b6968c5b299e25 | |
parent | c829ea7e9243319b802a0984b37dbda1ba1ae536 (diff) | |
download | qtlocation-mapboxgl-b2ab0804f86f649df1c4d07b246c2009d257ca27.tar.gz |
[render tests][tile mode] Enable automatic labels cut-off detection
-rw-r--r-- | render-test/metadata.hpp | 1 | ||||
-rw-r--r-- | render-test/parser.cpp | 6 | ||||
-rw-r--r-- | render-test/render_test.cpp | 2 | ||||
-rw-r--r-- | render-test/runner.cpp | 63 |
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; |