diff options
-rw-r--r-- | include/mbgl/util/image.hpp | 2 | ||||
-rw-r--r-- | include/mbgl/util/size.hpp | 11 | ||||
-rw-r--r-- | platform/default/mbgl/gl/offscreen_view.cpp | 2 | ||||
-rw-r--r-- | src/mbgl/map/transform.cpp | 10 | ||||
-rw-r--r-- | src/mbgl/map/transform.hpp | 2 | ||||
-rw-r--r-- | src/mbgl/map/transform_state.cpp | 7 | ||||
-rw-r--r-- | src/mbgl/map/transform_state.hpp | 4 | ||||
-rw-r--r-- | src/mbgl/util/offscreen_texture.cpp | 4 | ||||
-rw-r--r-- | src/mbgl/util/tile_cover.cpp | 2 | ||||
-rw-r--r-- | test/map/transform.test.cpp | 81 |
10 files changed, 85 insertions, 40 deletions
diff --git a/include/mbgl/util/image.hpp b/include/mbgl/util/image.hpp index 5d1462e7c4..c019bb949c 100644 --- a/include/mbgl/util/image.hpp +++ b/include/mbgl/util/image.hpp @@ -58,7 +58,7 @@ public: } bool valid() const { - return size && data.get() != nullptr; + return !size.isEmpty() && data.get() != nullptr; } template <typename T = Image> diff --git a/include/mbgl/util/size.hpp b/include/mbgl/util/size.hpp index 79679a92fb..45c303969c 100644 --- a/include/mbgl/util/size.hpp +++ b/include/mbgl/util/size.hpp @@ -7,8 +7,7 @@ namespace mbgl { class Size { public: - constexpr Size() : width(0), height(0) { - } + constexpr Size() = default; constexpr Size(const uint32_t width_, const uint32_t height_) : width(width_), height(height_) { } @@ -17,12 +16,12 @@ public: return width * height; } - constexpr explicit operator bool() const { - return width > 0 && height > 0; + constexpr bool isEmpty() const { + return width == 0 || height == 0; } - uint32_t width; - uint32_t height; + uint32_t width = 0; + uint32_t height = 0; }; constexpr inline bool operator==(const Size& a, const Size& b) { diff --git a/platform/default/mbgl/gl/offscreen_view.cpp b/platform/default/mbgl/gl/offscreen_view.cpp index a517cefad9..5424e03c96 100644 --- a/platform/default/mbgl/gl/offscreen_view.cpp +++ b/platform/default/mbgl/gl/offscreen_view.cpp @@ -12,7 +12,7 @@ namespace mbgl { class OffscreenView::Impl { public: Impl(gl::Context& context_, const Size size_) : context(context_), size(std::move(size_)) { - assert(size); + assert(!size.isEmpty()); } void bind() { diff --git a/src/mbgl/map/transform.cpp b/src/mbgl/map/transform.cpp index c30b8d9687..5104aa0562 100644 --- a/src/mbgl/map/transform.cpp +++ b/src/mbgl/map/transform.cpp @@ -45,9 +45,13 @@ Transform::Transform(MapObserver& observer_, #pragma mark - Map View -bool Transform::resize(const Size size) { +void Transform::resize(const Size size) { + if (size.isEmpty()) { + throw std::runtime_error("failed to resize: size is empty"); + } + if (state.size == size) { - return false; + return; } observer.onCameraWillChange(MapObserver::CameraChangeMode::Immediate); @@ -56,8 +60,6 @@ bool Transform::resize(const Size size) { state.constrain(state.scale, state.x, state.y); observer.onCameraDidChange(MapObserver::CameraChangeMode::Immediate); - - return true; } #pragma mark - Camera diff --git a/src/mbgl/map/transform.hpp b/src/mbgl/map/transform.hpp index f11ac81287..15b97cb198 100644 --- a/src/mbgl/map/transform.hpp +++ b/src/mbgl/map/transform.hpp @@ -25,7 +25,7 @@ public: Transform(const TransformState &state_) : observer(MapObserver::nullObserver()), state(state_) {} // Map view - bool resize(Size size); + void resize(Size size); // Camera /** Returns the current camera options. */ diff --git a/src/mbgl/map/transform_state.cpp b/src/mbgl/map/transform_state.cpp index 3fae7b205c..2e97cc9bc8 100644 --- a/src/mbgl/map/transform_state.cpp +++ b/src/mbgl/map/transform_state.cpp @@ -27,6 +27,9 @@ void TransformState::matrixFor(mat4& matrix, const UnwrappedTileID& tileID) cons } void TransformState::getProjMatrix(mat4& projMatrix) const { + if (size.isEmpty()) { + return; + } // Find the distance from the center point [width/2, height/2] to the // center top point [width/2, 0] in Z units, using the law of sines. @@ -216,7 +219,7 @@ double TransformState::scaleZoom(double s) const { } ScreenCoordinate TransformState::latLngToScreenCoordinate(const LatLng& latLng) const { - if (!size) { + if (size.isEmpty()) { return {}; } @@ -229,7 +232,7 @@ ScreenCoordinate TransformState::latLngToScreenCoordinate(const LatLng& latLng) } LatLng TransformState::screenCoordinateToLatLng(const ScreenCoordinate& point, LatLng::WrapMode wrapMode) const { - if (!size) { + if (size.isEmpty()) { return {}; } diff --git a/src/mbgl/map/transform_state.hpp b/src/mbgl/map/transform_state.hpp index a35aa5a255..d281c31995 100644 --- a/src/mbgl/map/transform_state.hpp +++ b/src/mbgl/map/transform_state.hpp @@ -74,6 +74,10 @@ public: double zoomScale(double zoom) const; double scaleZoom(double scale) const; + bool valid() const { + return !size.isEmpty() && (scale >= min_scale && scale <= max_scale); + } + private: bool rotatedNorth() const; void constrain(double& scale, double& x, double& y) const; diff --git a/src/mbgl/util/offscreen_texture.cpp b/src/mbgl/util/offscreen_texture.cpp index cbe33c8d58..56ef60b15c 100644 --- a/src/mbgl/util/offscreen_texture.cpp +++ b/src/mbgl/util/offscreen_texture.cpp @@ -9,7 +9,7 @@ namespace mbgl { class OffscreenTexture::Impl { public: Impl(gl::Context& context_, const Size size_) : context(context_), size(std::move(size_)) { - assert(size); + assert(!size.isEmpty()); } void bind() { @@ -45,7 +45,7 @@ private: OffscreenTexture::OffscreenTexture(gl::Context& context, const Size size) : impl(std::make_unique<Impl>(context, std::move(size))) { - assert(size); + assert(!size.isEmpty()); } OffscreenTexture::~OffscreenTexture() = default; diff --git a/src/mbgl/util/tile_cover.cpp b/src/mbgl/util/tile_cover.cpp index 7699739588..b53e91162c 100644 --- a/src/mbgl/util/tile_cover.cpp +++ b/src/mbgl/util/tile_cover.cpp @@ -156,6 +156,8 @@ std::vector<UnwrappedTileID> tileCover(const LatLngBounds& bounds_, int32_t z) { } std::vector<UnwrappedTileID> tileCover(const TransformState& state, int32_t z) { + assert(state.valid()); + const double w = state.getSize().width; const double h = state.getSize().height; return tileCover( diff --git a/test/map/transform.test.cpp b/test/map/transform.test.cpp index 40f94e4f7c..a8869b41bf 100644 --- a/test/map/transform.test.cpp +++ b/test/map/transform.test.cpp @@ -461,41 +461,76 @@ TEST(Transform, Camera) { } TEST(Transform, DefaultTransform) { - Transform transform; + struct TransformObserver : public mbgl::MapObserver { + void onCameraWillChange(MapObserver::CameraChangeMode) final { + cameraWillChangeCallback(); + }; + + void onCameraDidChange(MapObserver::CameraChangeMode) final { + cameraDidChangeCallback(); + }; + + std::function<void()> cameraWillChangeCallback; + std::function<void()> cameraDidChangeCallback; + }; + + uint32_t cameraWillChangeCount = 0; + uint32_t cameraDidChangeCount = 0; + + TransformObserver observer; + observer.cameraWillChangeCallback = [&cameraWillChangeCount]() { cameraWillChangeCount++; }; + observer.cameraDidChangeCallback = [&cameraDidChangeCount]() { cameraDidChangeCount++; }; + + Transform transform(observer); const TransformState& state = transform.getState(); + ASSERT_FALSE(state.valid()); LatLng nullIsland, latLng = {}; ScreenCoordinate center, point = {}; const uint32_t min = 0; const uint32_t max = 65535; - auto testConversions = [&](const LatLng& coord, const ScreenCoordinate& screenCoord) { - latLng = state.screenCoordinateToLatLng(center); - ASSERT_NEAR(latLng.latitude(), coord.latitude(), 0.000001); - ASSERT_NEAR(latLng.longitude(), coord.longitude(), 0.000001); - point = state.latLngToScreenCoordinate(nullIsland); - ASSERT_DOUBLE_EQ(point.x, screenCoord.x); - ASSERT_DOUBLE_EQ(point.y, screenCoord.y); - }; - - testConversions(nullIsland, center); + // Cannot assign invalid sizes. + std::vector<Size> invalidSizes = { {}, { min, max }, { max, min } }; + for (const Size& size : invalidSizes) { + ASSERT_TRUE(size.isEmpty()); + bool pass = false; + try { + transform.resize(size); + } catch (...) { + pass = true; + } + ASSERT_TRUE(pass) << "Expected to throw"; + } - // Cannot assign the current size. - ASSERT_FALSE(transform.resize({})); + Size validSize { max, max }; + ASSERT_FALSE(validSize.isEmpty()); - ASSERT_TRUE(transform.resize({ min, max })); - testConversions(nullIsland, center); + try { + transform.resize(validSize); + ASSERT_EQ(cameraWillChangeCount, 1u); + ASSERT_EQ(cameraDidChangeCount, 1u); + } catch (...) { + ASSERT_TRUE(false) << "Should not throw"; + } - ASSERT_TRUE(transform.resize({ max, min })); - testConversions(nullIsland, center); + ASSERT_TRUE(state.valid()); - ASSERT_TRUE(transform.resize({ min, min })); - testConversions(nullIsland, center); + // Double resize + try { + transform.resize(validSize); + ASSERT_EQ(cameraWillChangeCount, 1u); + ASSERT_EQ(cameraDidChangeCount, 1u); + } catch (...) { + ASSERT_TRUE(false) << "Should not throw"; + } center = { max / 2., max / 2. }; + latLng = state.screenCoordinateToLatLng(center); + ASSERT_NEAR(latLng.latitude(), nullIsland.latitude(), 1e-5); + ASSERT_NEAR(latLng.longitude(), nullIsland.longitude(), 1e-5); - // Double resize - ASSERT_TRUE(transform.resize({ max, max })); - ASSERT_FALSE(transform.resize({ max, max })); - testConversions(nullIsland, center); + point = state.latLngToScreenCoordinate(nullIsland); + ASSERT_DOUBLE_EQ(point.x, center.x); + ASSERT_DOUBLE_EQ(point.y, center.y); } |