From 24ea920810d13700094b44b08ac737eb613ea1de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Fri, 8 May 2015 20:21:14 +0200 Subject: [PATCH] ignore Transform changes with NaN parameters --- src/mbgl/map/transform.cpp | 38 +++++++++- test/miscellaneous/transform.cpp | 125 +++++++++++++++++++++++++++++++ test/test.gypi | 1 + 3 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 test/miscellaneous/transform.cpp diff --git a/src/mbgl/map/transform.cpp b/src/mbgl/map/transform.cpp index ffe742296..32127fb26 100644 --- a/src/mbgl/map/transform.cpp +++ b/src/mbgl/map/transform.cpp @@ -23,7 +23,7 @@ static double _normalizeAngle(double angle, double anchorAngle) if (std::abs(angle + util::M2PI - anchorAngle) < diff) { angle += util::M2PI; } - + return angle; } @@ -61,6 +61,10 @@ bool Transform::resize(const uint16_t w, const uint16_t h, const float ratio, #pragma mark - Position void Transform::moveBy(const double dx, const double dy, const Duration duration) { + if (std::isnan(dx) || std::isnan(dy)) { + return; + } + std::lock_guard lock(mtx); _moveBy(dx, dy, duration); @@ -104,6 +108,10 @@ void Transform::_moveBy(const double dx, const double dy, const Duration duratio } void Transform::setLatLng(const LatLng latLng, const Duration duration) { + if (std::isnan(latLng.latitude) || std::isnan(latLng.longitude)) { + return; + } + std::lock_guard lock(mtx); const double m = 1 - 1e-15; @@ -116,6 +124,10 @@ void Transform::setLatLng(const LatLng latLng, const Duration duration) { } void Transform::setLatLngZoom(const LatLng latLng, const double zoom, const Duration duration) { + if (std::isnan(latLng.latitude) || std::isnan(latLng.longitude) || std::isnan(zoom)) { + return; + } + std::lock_guard lock(mtx); double new_scale = std::pow(2.0, zoom); @@ -137,6 +149,10 @@ void Transform::setLatLngZoom(const LatLng latLng, const double zoom, const Dura #pragma mark - Zoom void Transform::scaleBy(const double ds, const double cx, const double cy, const Duration duration) { + if (std::isnan(ds) || std::isnan(cx) || std::isnan(cy)) { + return; + } + std::lock_guard lock(mtx); // clamp scale to min/max values @@ -152,12 +168,20 @@ void Transform::scaleBy(const double ds, const double cx, const double cy, const void Transform::setScale(const double scale, const double cx, const double cy, const Duration duration) { + if (std::isnan(scale) || std::isnan(cx) || std::isnan(cy)) { + return; + } + std::lock_guard lock(mtx); _setScale(scale, cx, cy, duration); } void Transform::setZoom(const double zoom, const Duration duration) { + if (std::isnan(zoom)) { + return; + } + std::lock_guard lock(mtx); _setScale(std::pow(2.0, zoom), -1, -1, duration); @@ -287,6 +311,10 @@ void Transform::constrain(double& scale, double& y) const { void Transform::rotateBy(const double start_x, const double start_y, const double end_x, const double end_y, const Duration duration) { + if (std::isnan(start_x) || std::isnan(start_y) || std::isnan(end_x) || std::isnan(end_y)) { + return; + } + std::lock_guard lock(mtx); double center_x = static_cast(current.width) / 2.0, center_y = static_cast(current.height) / 2.0; @@ -317,12 +345,20 @@ void Transform::rotateBy(const double start_x, const double start_y, const doubl } void Transform::setAngle(const double new_angle, const Duration duration) { + if (std::isnan(new_angle)) { + return; + } + std::lock_guard lock(mtx); _setAngle(new_angle, duration); } void Transform::setAngle(const double new_angle, const double cx, const double cy) { + if (std::isnan(new_angle) || std::isnan(cx) || std::isnan(cy)) { + return; + } + std::lock_guard lock(mtx); double dx = 0, dy = 0; diff --git a/test/miscellaneous/transform.cpp b/test/miscellaneous/transform.cpp new file mode 100644 index 000000000..6025cbce4 --- /dev/null +++ b/test/miscellaneous/transform.cpp @@ -0,0 +1,125 @@ +#include "../fixtures/util.hpp" + +#include +#include +#include +#include +#include +#include + +#include + +using namespace mbgl; + +class MockView : public View { +public: + void activate() override { + } + void deactivate() override { + } + void notify() override { + } + void invalidate(std::function) override { + } +}; + +TEST(Transform, InvalidScale) { + MockView view; + Transform transform(view); + + ASSERT_DOUBLE_EQ(0, transform.getLatLng().latitude); + ASSERT_DOUBLE_EQ(0, transform.getLatLng().longitude); + ASSERT_DOUBLE_EQ(1, transform.getScale()); + + transform.setScale(2); + + ASSERT_DOUBLE_EQ(0, transform.getLatLng().latitude); + ASSERT_DOUBLE_EQ(0, transform.getLatLng().longitude); + ASSERT_DOUBLE_EQ(2, transform.getScale()); + + const double invalid = std::nan(""); + transform.setScale(invalid); + + ASSERT_DOUBLE_EQ(0, transform.getLatLng().latitude); + ASSERT_DOUBLE_EQ(0, transform.getLatLng().longitude); + ASSERT_DOUBLE_EQ(2, transform.getScale()); + + transform.scaleBy(invalid); + + ASSERT_DOUBLE_EQ(0, transform.getLatLng().latitude); + ASSERT_DOUBLE_EQ(0, transform.getLatLng().longitude); + ASSERT_DOUBLE_EQ(2, transform.getScale()); + + transform.setZoom(invalid); + + ASSERT_DOUBLE_EQ(0, transform.getLatLng().latitude); + ASSERT_DOUBLE_EQ(0, transform.getLatLng().longitude); + ASSERT_DOUBLE_EQ(2, transform.getScale()); + + transform.setLatLngZoom({ 0, 0 }, invalid); + + ASSERT_DOUBLE_EQ(0, transform.getLatLng().latitude); + ASSERT_DOUBLE_EQ(0, transform.getLatLng().longitude); + ASSERT_DOUBLE_EQ(2, transform.getScale()); +} + +TEST(Transform, InvalidLatLng) { + MockView view; + Transform transform(view); + + ASSERT_DOUBLE_EQ(0, transform.getLatLng().latitude); + ASSERT_DOUBLE_EQ(0, transform.getLatLng().longitude); + ASSERT_DOUBLE_EQ(1, transform.getScale()); + + transform.setScale(2); + transform.setLatLng({ 8, 10 }); + + ASSERT_DOUBLE_EQ(8, transform.getLatLng().latitude); + ASSERT_DOUBLE_EQ(10, transform.getLatLng().longitude); + ASSERT_DOUBLE_EQ(2, transform.getScale()); + + transform.setLatLngZoom({ 10, 8 }, 2); + + ASSERT_DOUBLE_EQ(10, transform.getLatLng().latitude); + ASSERT_DOUBLE_EQ(8, transform.getLatLng().longitude); + ASSERT_DOUBLE_EQ(4, transform.getScale()); + + const double invalid = std::nan(""); + transform.setLatLngZoom({ invalid, 8 }, 2); + + ASSERT_DOUBLE_EQ(10, transform.getLatLng().latitude); + ASSERT_DOUBLE_EQ(8, transform.getLatLng().longitude); + ASSERT_DOUBLE_EQ(4, transform.getScale()); + + transform.setLatLngZoom({ 10, invalid }, 2); + + ASSERT_DOUBLE_EQ(10, transform.getLatLng().latitude); + ASSERT_DOUBLE_EQ(8, transform.getLatLng().longitude); + ASSERT_DOUBLE_EQ(4, transform.getScale()); +} + + +TEST(Transform, InvalidBearing) { + MockView view; + Transform transform(view); + + ASSERT_DOUBLE_EQ(0, transform.getLatLng().latitude); + ASSERT_DOUBLE_EQ(0, transform.getLatLng().longitude); + ASSERT_DOUBLE_EQ(1, transform.getScale()); + + transform.setScale(2); + transform.setAngle(2); + + ASSERT_DOUBLE_EQ(0, transform.getLatLng().latitude); + ASSERT_DOUBLE_EQ(0, transform.getLatLng().longitude); + ASSERT_DOUBLE_EQ(2, transform.getScale()); + ASSERT_DOUBLE_EQ(2, transform.getAngle()); + + const double invalid = std::nan(""); + transform.setAngle(invalid); + + ASSERT_DOUBLE_EQ(0, transform.getLatLng().latitude); + ASSERT_DOUBLE_EQ(0, transform.getLatLng().longitude); + ASSERT_DOUBLE_EQ(2, transform.getScale()); + ASSERT_DOUBLE_EQ(2, transform.getAngle()); +} diff --git a/test/test.gypi b/test/test.gypi index b6afb4fd9..a98137f44 100644 --- a/test/test.gypi +++ b/test/test.gypi @@ -51,6 +51,7 @@ 'miscellaneous/rotation_range.cpp', 'miscellaneous/style_parser.cpp', 'miscellaneous/text_conversions.cpp', + 'miscellaneous/transform.cpp', 'miscellaneous/tile.cpp', 'miscellaneous/variant.cpp', 'miscellaneous/worker.cpp',