maplibre support for Qt6 and MSVC 2019 (#125)

* [qt] Updating CMake project files for Qt6

* [qt] Updating non-test projects for Qt6 and msvc2019

* [qt] Test fixes for Qt6 and msvc2019

* [qt] Link whole test archive for Qt and msvc2019

* [qt] Fixing Qt6 headless backend renderer

* [qt] Fixes for test failures

* [qt] Expression and style parser test fixes

* [qt] Backwards compatibility with Qt5 and Qt6

Minimum version is Qt 5.4 due to use of QOpenGLWidget

* [qt] LLVM is no longer required for a Windows build

* [msvc] msvc2019 fixes for maplibre

* Update test/storage/offline_database.test.cpp

Co-authored-by: Tadej Novak <tadej@tano.si>

* Vector + const is not standard C++

Co-authored-by: Tadej Novak <tadej@tano.si>
This commit is contained in:
Dan Paulat
2021-08-07 10:10:45 -05:00
committed by GitHub
parent 1eee73bdce
commit 8b804a1903
51 changed files with 406 additions and 213 deletions

View File

@@ -86,7 +86,9 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)
if(MBGL_WITH_QT)
find_package(Qt5Core REQUIRED)
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
endif()

View File

@@ -18,7 +18,8 @@ public:
~ResourceOptions();
ResourceOptions(ResourceOptions&&) noexcept;
ResourceOptions& operator=(ResourceOptions& options);
ResourceOptions& operator=(const ResourceOptions& options);
ResourceOptions& operator=(ResourceOptions&& options);
ResourceOptions clone() const;

View File

@@ -78,6 +78,9 @@ public:
Result() = default;
template <typename U>
VARIANT_INLINE Result(U&& val) : variant<EvaluationError, T>(val) {}
explicit operator bool () const {
return this->template is<T>();
}

View File

@@ -34,6 +34,9 @@ using ValueBase = variant<NullValue,
struct Value : ValueBase {
using ValueBase::ValueBase;
template <typename T>
VARIANT_INLINE Value(T&& val) : ValueBase(val) {}
// Javascript's Number.MAX_SAFE_INTEGER
static uint64_t maxSafeInteger() { return 9007199254740991ULL; }

View File

@@ -16,22 +16,22 @@ public:
static optional<T> toEnum(const std::string&);
};
#define MBGL_DEFINE_ENUM(T, values...) \
\
static const constexpr std::pair<const T, const char *> T##_names[] = values; \
\
template <> \
const char * Enum<T>::toString(T t) { \
auto it = std::find_if(std::begin(T##_names), std::end(T##_names), \
[&] (const auto& v) { return t == v.first; }); \
assert(it != std::end(T##_names)); return it->second; \
} \
\
template <> \
optional<T> Enum<T>::toEnum(const std::string& s) { \
auto it = std::find_if(std::begin(T##_names), std::end(T##_names), \
[&] (const auto& v) { return s == v.second; }); \
return it == std::end(T##_names) ? optional<T>() : it->first; \
#define MBGL_DEFINE_ENUM(T, ...) \
\
static const constexpr std::pair<const T, const char *> T##_names[] = __VA_ARGS__; \
\
template <> \
const char * Enum<T>::toString(T t) { \
auto it = std::find_if(std::begin(T##_names), std::end(T##_names), \
[&] (const auto& v) { return t == v.first; }); \
assert(it != std::end(T##_names)); return it->second; \
} \
\
template <> \
optional<T> Enum<T>::toEnum(const std::string& s) { \
auto it = std::find_if(std::begin(T##_names), std::end(T##_names), \
[&] (const auto& v) { return s == v.second; }); \
return it == std::end(T##_names) ? optional<T>() : it->first; \
}
} // namespace mbgl

View File

@@ -237,7 +237,7 @@ namespace mbgl {
/**
* @brief Gets the default styles.
*/
const std::vector<const mbgl::util::DefaultStyle> defaultStyles() const;
const std::vector<mbgl::util::DefaultStyle> defaultStyles() const;
/**
* @brief Sets the collection default styles.
@@ -245,7 +245,7 @@ namespace mbgl {
* @param styles The style set.
* @return TileServerOptions for chaining options together.
*/
TileServerOptions& withDefaultStyles(std::vector<const mbgl::util::DefaultStyle> styles);
TileServerOptions& withDefaultStyles(std::vector<mbgl::util::DefaultStyle> styles);
/**
* @brief Sets the default style by name. The style name must exists in defaultStyles collection

View File

@@ -42,7 +42,7 @@ jni::Local<jni::Object<TileServerOptions>> TileServerOptions::New(jni::JNIEnv& e
);
}
jni::Local<jni::Array<jni::Object<DefaultStyle>>> TileServerOptions::NewStyles(jni::JNIEnv& env, const std::vector<const mbgl::util::DefaultStyle> nativeStyles) {
jni::Local<jni::Array<jni::Object<DefaultStyle>>> TileServerOptions::NewStyles(jni::JNIEnv& env, const std::vector<mbgl::util::DefaultStyle> &nativeStyles) {
auto retVal = jni::Array<jni::Object<DefaultStyle>>::New(env, nativeStyles.size());
for (auto it = begin(nativeStyles); it != end(nativeStyles); ++it) {
@@ -107,7 +107,7 @@ mbgl::TileServerOptions TileServerOptions::getTileServerOptions(jni::JNIEnv& env
static auto defaultStyleField = javaClass.GetField<jni::String>(env, "defaultStyle");
static auto defaultStylesField = javaClass.GetField<jni::Array<jni::Object<DefaultStyle>>>(env, "defaultStyles");
std::vector<const mbgl::util::DefaultStyle> defaultStyles = TileServerOptions::getDefaultStyles(env, options.Get(env, defaultStylesField));
std::vector<mbgl::util::DefaultStyle> defaultStyles = TileServerOptions::getDefaultStyles(env, options.Get(env, defaultStylesField));
auto retVal = mbgl::TileServerOptions()
.withBaseURL(jni::Make<std::string>(env, options.Get(env, baseURLField)))
@@ -151,13 +151,13 @@ mbgl::TileServerOptions TileServerOptions::getTileServerOptions(jni::JNIEnv& env
return retVal;
}
std::vector<const mbgl::util::DefaultStyle> TileServerOptions::getDefaultStyles(jni::JNIEnv& env, const jni::Array<jni::Object<DefaultStyle>>& styles_) {
std::vector<mbgl::util::DefaultStyle> TileServerOptions::getDefaultStyles(jni::JNIEnv& env, const jni::Array<jni::Object<DefaultStyle>>& styles_) {
std::size_t length = styles_.Length(env);
std::vector<const mbgl::util::DefaultStyle> convertedStyles;
std::vector<mbgl::util::DefaultStyle> convertedStyles;
//convertedStyles.reserve(length);
for (std::size_t i = 0; i < length; i++) {
const mbgl::util::DefaultStyle converted = DefaultStyle::getDefaultStyle(env, styles_.Get(env, i));
mbgl::util::DefaultStyle converted = DefaultStyle::getDefaultStyle(env, styles_.Get(env, i));
convertedStyles.push_back(converted);
}
@@ -175,4 +175,4 @@ void TileServerOptions::registerNative(jni::JNIEnv& env) {
}
} // namespace android
} // namespace mbgl
} // namespace mbgl

View File

@@ -27,12 +27,12 @@ public:
static void registerNative(jni::JNIEnv&);
static jni::Local<jni::Array<jni::Object<DefaultStyle>>> NewStyles(jni::JNIEnv& env, const std::vector<const mbgl::util::DefaultStyle>);
static std::vector<const mbgl::util::DefaultStyle> getDefaultStyles(jni::JNIEnv& env, const jni::Array<jni::Object<DefaultStyle>>& styles_);
static jni::Local<jni::Array<jni::Object<DefaultStyle>>> NewStyles(jni::JNIEnv& env, const std::vector<mbgl::util::DefaultStyle> &);
static std::vector<mbgl::util::DefaultStyle> getDefaultStyles(jni::JNIEnv& env, const jni::Array<jni::Object<DefaultStyle>>& styles_);
};
} // namespace android
} // namespace mbgl
} // namespace mbgl

View File

@@ -19,6 +19,8 @@ public:
depthStencil(context.createRenderbuffer<gfx::RenderbufferPixelType::DepthStencil>(size_)),
framebuffer(context.createFramebuffer(color, depthStencil)) {}
~HeadlessRenderableResource() noexcept override = default;
void bind() override {
context.bindFramebuffer = framebuffer.framebuffer;
context.scissorTest = false;

View File

@@ -73,7 +73,7 @@ public:
// Some Mbtiles store GZIP-ed tile data, this function is used for decompression
std::string decompress_string(const std::string &data) {
uint32_t OUT_SIZE = 8192;
constexpr uint32_t OUT_SIZE = 8192;
int ret;
char outbuffer[OUT_SIZE];

View File

@@ -11,6 +11,11 @@
#include <mbgl/util/logging.hpp>
#include <mbgl/util/optional.hpp>
#define MBGL_CONSTRUCTOR(f) \
static void f(void); \
struct f##_t_ { f##_t_(void) { f(); } }; static f##_t_ f##_; \
static void f(void)
namespace mapbox {
namespace sqlite {
@@ -102,8 +107,7 @@ void logSqlMessage(void *, const int err, const char *msg) {
}
#endif
__attribute__((constructor))
static void initalize() {
MBGL_CONSTRUCTOR(initialize) {
if (sqlite3_libversion_number() / 1000000 != SQLITE_VERSION_NUMBER / 1000000) {
char message[96];
snprintf(message, 96,

View File

@@ -10,8 +10,14 @@
#include <cstring>
#include <stdexcept>
#if defined(__GNUC__)
#define MBGL_UNUSED __attribute__((unused))
#else
#define MBGL_UNUSED
#endif
// Check zlib library version.
const static bool zlibVersionCheck __attribute__((unused)) = []() {
const static bool zlibVersionCheck MBGL_UNUSED = []() {
const char *const version = zlibVersion();
if (version[0] != ZLIB_VERSION[0]) {
char message[96];

View File

@@ -156,7 +156,7 @@
std::string([options.tileDomainName UTF8String]),
options.tileVersionPrefix ? std::string([options.tileVersionPrefix UTF8String]) : mbgl::optional<std::string>{});
std::vector<const mbgl::util::DefaultStyle> defaultStyles;
std::vector<mbgl::util::DefaultStyle> defaultStyles;
if (options.defaultStyles) {
for (MGLDefaultStyle* objCStyle in options.defaultStyles) {
mbgl::util::DefaultStyle cppStyle(
@@ -202,7 +202,7 @@
retVal.tileDomainName = [NSString stringWithUTF8String:cppOpts->tileDomainName().c_str()];
retVal.tileVersionPrefix = cppOpts->styleVersionPrefix().has_value() ? [NSString stringWithUTF8String:cppOpts->tileVersionPrefix().value().c_str()] : nil;
std::vector<const mbgl::util::DefaultStyle> cppDefaultStyles = cppOpts->defaultStyles();
std::vector<mbgl::util::DefaultStyle> cppDefaultStyles = cppOpts->defaultStyles();
NSMutableArray<MGLDefaultStyle*>* mglStyles = [[NSMutableArray<MGLDefaultStyle*> alloc] init];

View File

@@ -43,8 +43,8 @@ The Windows build will assume you have installed and on the default path:
- Microsoft Visual Studio 2015
- [CMake 3.10.1+](https://cmake.org/download/)
- [LLVM 5.0.0+](https://releases.llvm.org/download.html)
- [Qt 5+](https://www.qt.io/download) with "msvc2015" support.
- [LLVM 5.0.0+](https://releases.llvm.org/download.html) (optional)
- [Qt 5.4+](https://www.qt.io/download) with "msvc2015" (or later) support.
At runtime, you will also need installed:

View File

@@ -1,11 +1,17 @@
# Note: Using Sqlite instead of QSqlDatabase for better compatibility.
find_package(Qt5Gui REQUIRED)
find_package(Qt5Network REQUIRED)
find_package(Qt5OpenGL REQUIRED)
find_package(Qt5Widgets REQUIRED)
find_package(Qt${QT_VERSION_MAJOR}
COMPONENTS Gui
Network
OpenGL
OpenGLWidgets
Widgets
REQUIRED)
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
if(MSVC)
add_definitions("/DQT_COMPILING_QIMAGE_COMPAT_CPP")
add_definitions("/D_USE_MATH_DEFINES")
elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
add_definitions("-DQT_COMPILING_QIMAGE_COMPAT_CPP")
add_definitions("-D_USE_MATH_DEFINES")
add_definitions("-Wno-deprecated-declarations")
@@ -89,10 +95,10 @@ target_link_libraries(
PRIVATE
$<$<NOT:$<PLATFORM_ID:Windows>>:z>
$<$<NOT:$<PLATFORM_ID:Windows>>:mbgl-vendor-icu>
Qt5::Core
Qt5::Gui
Qt5::Network
Qt5::OpenGL
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Network
Qt${QT_VERSION_MAJOR}::OpenGL
mbgl-vendor-nunicode
mbgl-vendor-sqlite
)
@@ -136,8 +142,8 @@ target_compile_definitions(
target_link_libraries(
qmapboxgl
PRIVATE
Qt5::Core
Qt5::Gui
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
mbgl-compiler-options
mbgl-core
)
@@ -156,8 +162,9 @@ set_property(TARGET mbgl-qt PROPERTY CXX_STANDARD 98)
target_link_libraries(
mbgl-qt
PRIVATE
Qt5::Widgets
Qt5::Gui
Qt${QT_VERSION_MAJOR}::Widgets
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::OpenGLWidgets
mbgl-compiler-options
qmapboxgl
)
@@ -177,20 +184,41 @@ target_compile_definitions(
PRIVATE WORK_DIRECTORY=${PROJECT_SOURCE_DIR}
)
target_link_libraries(
mbgl-test-runner
PRIVATE
Qt5::Gui
Qt5::OpenGL
mbgl-compiler-options
pthread
)
if (MSVC)
target_link_libraries(
mbgl-test-runner
PRIVATE
Qt${QT_VERSION_MAJOR}::Widgets
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::OpenGL
mbgl-compiler-options
)
else()
target_link_libraries(
mbgl-test-runner
PRIVATE
Qt${QT_VERSION_MAJOR}::Widgets
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::OpenGL
mbgl-compiler-options
pthread
)
endif()
if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
target_link_libraries(
mbgl-test-runner
PRIVATE -Wl,-force_load mbgl-test
)
elseif(MSVC)
target_link_options(
mbgl-test-runner
PRIVATE /WHOLEARCHIVE:../../lib/mbgl-test.lib
)
target_link_libraries(
mbgl-test-runner
PRIVATE mbgl-test
)
else()
target_link_libraries(
mbgl-test-runner

View File

@@ -39,10 +39,12 @@ std::vector<StyledText> BiDi::processStyledText(const StyledText& input, std::se
std::vector<StyledText> transformedLines;
std::size_t start = 0;
for (std::size_t lineBreakPoint : lineBreakPoints) {
transformedLines.emplace_back(
input.first.substr(start, lineBreakPoint - start),
std::vector<uint8_t>(input.second.begin() + start, input.second.begin() + lineBreakPoint));
start = lineBreakPoint;
if (lineBreakPoint <= input.second.size()) {
transformedLines.emplace_back(
input.first.substr(start, lineBreakPoint - start),
std::vector<uint8_t>(input.second.begin() + start, input.second.begin() + lineBreakPoint));
start = lineBreakPoint;
}
}
return transformedLines;

View File

@@ -1,6 +1,6 @@
#include <mbgl/gl/headless_backend.hpp>
#include <QGLWidget>
#include <QOffscreenSurface>
#include <QOpenGLContext>
#include <cassert>
@@ -10,6 +10,12 @@ namespace gl {
class QtBackendImpl final : public HeadlessBackend::Impl {
public:
QtBackendImpl() {
// QtBackendImpl must be created in the main/GUI thread on platforms
// that have a QWindow-based QOffscreenSurface.
surface.create();
context.create();
}
~QtBackendImpl() = default;
gl::ProcAddress getExtensionFunctionPointer(const char* name) {
@@ -18,15 +24,16 @@ public:
}
void activateContext() {
widget.makeCurrent();
context.makeCurrent(&surface);
}
void deactivateContext() {
widget.doneCurrent();
context.doneCurrent();
}
private:
QGLWidget widget;
QOpenGLContext context;
QOffscreenSurface surface;
};
void HeadlessBackend::createImpl() {

View File

@@ -1,11 +1,16 @@
#include <QApplication>
#include <mbgl/test.hpp>
#include <unistd.h>
#include <cstring>
#include <cerrno>
#include <cstdio>
#if defined(_MSC_VER) && !defined(__clang__)
#include <direct.h>
#else
#include <unistd.h>
#endif
#define xstr(s) str(s)
#define str(s) #s

View File

@@ -19,7 +19,11 @@
} \
}
#if defined(_MSC_VER) && !defined(__clang__)
#define MBGL_VERTEX_ALIGN __declspec(align(4))
#else
#define MBGL_VERTEX_ALIGN __attribute__((aligned(4)))
#endif
namespace mbgl {
namespace gfx {
@@ -106,44 +110,44 @@ template <class...>
struct VertexType;
template <class A1>
struct VertexType<A1> {
struct MBGL_VERTEX_ALIGN VertexType<A1> {
using Type = VertexType<A1>;
typename A1::Value a1;
} MBGL_VERTEX_ALIGN;
};
template <class A1, class A2>
struct VertexType<A1, A2> {
struct MBGL_VERTEX_ALIGN VertexType<A1, A2> {
using Type = VertexType<A1, A2>;
typename A1::Value a1;
typename A2::Value a2;
} MBGL_VERTEX_ALIGN;
};
template <class A1, class A2, class A3>
struct VertexType<A1, A2, A3> {
struct MBGL_VERTEX_ALIGN VertexType<A1, A2, A3> {
using Type = VertexType<A1, A2, A3>;
typename A1::Value a1;
typename A2::Value a2;
typename A3::Value a3;
} MBGL_VERTEX_ALIGN;
};
template <class A1, class A2, class A3, class A4>
struct VertexType<A1, A2, A3, A4> {
struct MBGL_VERTEX_ALIGN VertexType<A1, A2, A3, A4> {
using Type = VertexType<A1, A2, A3, A4>;
typename A1::Value a1;
typename A2::Value a2;
typename A3::Value a3;
typename A4::Value a4;
} MBGL_VERTEX_ALIGN;
};
template <class A1, class A2, class A3, class A4, class A5>
struct VertexType<A1, A2, A3, A4, A5> {
struct MBGL_VERTEX_ALIGN VertexType<A1, A2, A3, A4, A5> {
using Type = VertexType<A1, A2, A3, A4, A5>;
typename A1::Value a1;
typename A2::Value a2;
typename A3::Value a3;
typename A4::Value a4;
typename A5::Value a5;
} MBGL_VERTEX_ALIGN;
};
template <class>
struct Descriptor;

View File

@@ -14,6 +14,7 @@
#include <mbgl/util/logging.hpp>
#include <cstring>
#include <iterator>
namespace mbgl {
namespace gl {
@@ -58,7 +59,7 @@ Context::Context(RendererBackend& backend_)
backend(backend_),
stats() {}
Context::~Context() {
Context::~Context() noexcept {
if (cleanupOnDestruction) {
reset();
assert(stats.isZero());

View File

@@ -37,7 +37,7 @@ class Debugging;
class Context final : public gfx::Context {
public:
Context(RendererBackend&);
~Context() override;
~Context() noexcept override;
Context(const Context&) = delete;
Context& operator=(const Context& other) = delete;
@@ -149,7 +149,7 @@ public:
State<value::BindVertexBuffer> vertexBuffer;
State<value::BindVertexArray, const Context&> bindVertexArray { *this };
VertexArrayState globalVertexArrayState { UniqueVertexArray(0, { this }) };
VertexArrayState globalVertexArrayState { UniqueVertexArray(0, { const_cast<Context*>(this) }) };
State<value::PixelStorePack> pixelStorePack;
State<value::PixelStoreUnpack> pixelStoreUnpack;

View File

@@ -4,7 +4,7 @@
namespace mbgl {
namespace gl {
IndexBufferResource::~IndexBufferResource() {
IndexBufferResource::~IndexBufferResource() noexcept {
auto& stats = buffer.get_deleter().context.renderingStats();
stats.memIndexBuffers -= byteSize;
assert(stats.memIndexBuffers >= 0);

View File

@@ -9,7 +9,7 @@ namespace gl {
class IndexBufferResource : public gfx::IndexBufferResource {
public:
IndexBufferResource(UniqueBuffer&& buffer_, int byteSize_) : buffer(std::move(buffer_)), byteSize(byteSize_) {}
~IndexBufferResource() override;
~IndexBufferResource() noexcept override;
UniqueBuffer buffer;
int byteSize;

View File

@@ -15,6 +15,8 @@ public:
assert(!size.isEmpty());
}
~OffscreenTextureResource() noexcept override = default;
void bind() override {
if (!framebuffer) {
assert(!texture);

View File

@@ -12,6 +12,8 @@ public:
: renderbuffer(std::move(renderbuffer_)) {
}
~RenderbufferResource() noexcept override = default;
UniqueRenderbuffer renderbuffer;
};

View File

@@ -31,7 +31,7 @@ static int channelStorageSize(gfx::TextureChannelDataType type) {
}
}
TextureResource::~TextureResource() {
TextureResource::~TextureResource() noexcept {
auto& stats = texture.get_deleter().context->renderingStats();
stats.memTextures -= byteSize;
assert(stats.memTextures >= 0);

View File

@@ -9,7 +9,7 @@ namespace gl {
class TextureResource : public gfx::TextureResource {
public:
TextureResource(UniqueTexture&& texture_, int byteSize_) : texture(std::move(texture_)), byteSize(byteSize_) {}
~TextureResource() override;
~TextureResource() noexcept override;
static int getStorageSize(const Size& size, gfx::TexturePixelType format, gfx::TextureChannelDataType type);

View File

@@ -4,7 +4,7 @@
namespace mbgl {
namespace gl {
VertexBufferResource::~VertexBufferResource() {
VertexBufferResource::~VertexBufferResource() noexcept {
auto& stats = buffer.get_deleter().context.renderingStats();
stats.memVertexBuffers -= byteSize;
assert(stats.memVertexBuffers >= 0);

View File

@@ -9,7 +9,7 @@ namespace gl {
class VertexBufferResource : public gfx::VertexBufferResource {
public:
VertexBufferResource(UniqueBuffer&& buffer_, int byteSize_) : buffer(std::move(buffer_)), byteSize(byteSize_) {}
~VertexBufferResource() override;
~VertexBufferResource() noexcept override;
UniqueBuffer buffer;
int byteSize;

View File

@@ -645,8 +645,8 @@ void SymbolLayout::addFeature(const std::size_t layoutFeatureIndex,
Anchors anchors = getAnchors(line,
symbolSpacing,
textMaxAngle,
(shapedTextOrientations.vertical ?: getDefaultHorizontalShaping(shapedTextOrientations)).left,
(shapedTextOrientations.vertical ?: getDefaultHorizontalShaping(shapedTextOrientations)).right,
(shapedTextOrientations.vertical ? shapedTextOrientations.vertical : getDefaultHorizontalShaping(shapedTextOrientations)).left,
(shapedTextOrientations.vertical ? shapedTextOrientations.vertical : getDefaultHorizontalShaping(shapedTextOrientations)).right,
(shapedIcon ? shapedIcon->left() : 0),
(shapedIcon ? shapedIcon->right() : 0),
glyphSize,
@@ -666,8 +666,8 @@ void SymbolLayout::addFeature(const std::size_t layoutFeatureIndex,
if (line.size() > 1) {
optional<Anchor> anchor = getCenterAnchor(line,
textMaxAngle,
(shapedTextOrientations.vertical ?: getDefaultHorizontalShaping(shapedTextOrientations)).left,
(shapedTextOrientations.vertical ?: getDefaultHorizontalShaping(shapedTextOrientations)).right,
(shapedTextOrientations.vertical ? shapedTextOrientations.vertical : getDefaultHorizontalShaping(shapedTextOrientations)).left,
(shapedTextOrientations.vertical ? shapedTextOrientations.vertical : getDefaultHorizontalShaping(shapedTextOrientations)).right,
(shapedIcon ? shapedIcon->left() : 0),
(shapedIcon ? shapedIcon->right() : 0),
glyphSize,

View File

@@ -95,7 +95,7 @@ namespace mbgl {
PointAndCameraDistance project(const Point<float>& point, const mat4& matrix) {
vec4 pos = {{ point.x, point.y, 0, 1 }};
matrix::transformMat4(pos, pos, matrix);
return {{ static_cast<float>(pos[0] / pos[3]), static_cast<float>(pos[1] / pos[3]) }, pos[3] };
return {{ static_cast<float>(pos[0] / pos[3]), static_cast<float>(pos[1] / pos[3]) }, static_cast<float>(pos[3]) };
}
float evaluateSizeForFeature(const ZoomEvaluatedSize& zoomEvaluatedSize, const PlacedSymbol& placedSymbol) {

View File

@@ -19,7 +19,8 @@ ResourceOptions::ResourceOptions() : impl_(std::make_unique<Impl>()) {}
ResourceOptions::~ResourceOptions() = default;
ResourceOptions::ResourceOptions(ResourceOptions&&) noexcept = default;
ResourceOptions::ResourceOptions(const ResourceOptions& other) : impl_(std::make_unique<Impl>(*other.impl_)) {}
ResourceOptions& ResourceOptions::operator=(ResourceOptions& options) {swap(impl_, options.impl_); return *this; }
ResourceOptions& ResourceOptions::operator=(const ResourceOptions& other) {impl_ = std::make_unique<Impl>(*other.impl_); return *this; }
ResourceOptions& ResourceOptions::operator=(ResourceOptions&& options) {swap(impl_, options.impl_); return *this; }
ResourceOptions ResourceOptions::clone() const {
return ResourceOptions(*this);

View File

@@ -53,9 +53,9 @@ EvaluationResult toColor(const Value& colorValue) {
};
}
},
[&](const std::vector<Value>& components) -> EvaluationResult {
[&colorValue](const std::vector<Value>& components) -> EvaluationResult {
std::size_t len = components.size();
bool isNumeric = std::all_of(components.begin(), components.end(), [](const Value& item) {
bool isNumeric = std::all_of(components.begin(), components.end(), [](const Value& item) -> bool {
return item.template is<double>();
});
if ((len == 3 || len == 4) && isNumeric) {

View File

@@ -225,7 +225,7 @@ Value featureIdAsExpressionValue(const EvaluationContext& params) {
optional<Value> featurePropertyAsExpressionValue(const EvaluationContext& params, const std::string& key) {
assert(params.feature);
auto property = params.feature->getValue(key);
return property ? toExpressionValue(*property) : optional<Value>();
return property ? optional<Value>(toExpressionValue(*property)) : optional<Value>();
};
optional<std::string> featureTypeAsString(FeatureType type) {

View File

@@ -149,10 +149,10 @@ template bool pointOnBoundary(const Point<int64_t>& p, const Point<int64_t>& p1,
template bool lineIntersectPolygon(const Point<int64_t>& p1, const Point<int64_t>& p2, const Polygon<int64_t>& polygon);
template bool pointWithinPolygon(const Point<int64_t>& point,
const Polygon<int64_t>& polygon,
bool trueOnBoundary = false);
bool trueOnBoundary);
template bool pointWithinPolygons(const Point<int64_t>& point,
const MultiPolygon<int64_t>& polygons,
bool trueOnBoundary = false);
bool trueOnBoundary);
template bool lineStringWithinPolygon(const LineString<int64_t>& line, const Polygon<int64_t>& polygon);
template bool lineStringWithinPolygons(const LineString<int64_t>& line, const MultiPolygon<int64_t>& polygons);
@@ -164,6 +164,6 @@ template bool segmentIntersectSegment(const Point<double>& a,
const Point<double>& d);
template bool pointWithinPolygon(const Point<double>& point,
const Polygon<double>& polygon,
bool trueOnBoundary = false);
bool trueOnBoundary);
} // namespace mbgl

View File

@@ -7,6 +7,12 @@
#include <sstream>
#include <fstream>
#ifdef __GNUC__
#define MBGL_FOPEN_MODE_WBE "wbe"
#else
#define MBGL_FOPEN_MODE_WBE "wb"
#endif
namespace mbgl {
namespace util {
@@ -15,7 +21,7 @@ IOException::IOException(int err, const std::string& msg)
}
void write_file(const std::string &filename, const std::string &data) {
FILE *fd = fopen(filename.c_str(), "wbe");
FILE *fd = fopen(filename.c_str(), MBGL_FOPEN_MODE_WBE);
if (fd) {
fwrite(data.data(), sizeof(std::string::value_type), data.size(), fd);
fclose(fd);

View File

@@ -6,6 +6,7 @@
#include <cassert>
#include <climits>
#include <algorithm>
#include <iterator>
namespace mbgl {
namespace util {

View File

@@ -33,7 +33,7 @@ namespace mbgl {
std::string apiKeyParameterName;
bool apiKeyRequired;
std::vector<const mbgl::util::DefaultStyle> defaultStyles;
std::vector<mbgl::util::DefaultStyle> defaultStyles;
std::string defaultStyle;
};
@@ -184,11 +184,11 @@ namespace mbgl {
return impl_->apiKeyRequired;
}
const std::vector<const mbgl::util::DefaultStyle> TileServerOptions::defaultStyles() const {
const std::vector<mbgl::util::DefaultStyle> TileServerOptions::defaultStyles() const {
return impl_->defaultStyles;
}
TileServerOptions& TileServerOptions::withDefaultStyles(std::vector<const mbgl::util::DefaultStyle> styles) {
TileServerOptions& TileServerOptions::withDefaultStyles(std::vector<mbgl::util::DefaultStyle> styles) {
impl_->defaultStyles = std::move(styles);
return *this;
}
@@ -207,7 +207,7 @@ namespace mbgl {
}
TileServerOptions TileServerOptions::MapLibreConfiguration() {
std::vector<const mbgl::util::DefaultStyle> styles {
std::vector<mbgl::util::DefaultStyle> styles {
// https://demotiles.maplibre.org/style.json
mbgl::util::DefaultStyle("maplibre://maps/style", "Basic", 1)
};
@@ -230,7 +230,7 @@ namespace mbgl {
//
TileServerOptions TileServerOptions::MapboxConfiguration() {
std::vector<const mbgl::util::DefaultStyle> styles {
std::vector<mbgl::util::DefaultStyle> styles {
mbgl::util::DefaultStyle("mapbox://styles/mapbox/streets-v11", "Streets", 11),
mbgl::util::DefaultStyle("mapbox://styles/mapbox/outdoors-v11", "Outdoors", 11),
mbgl::util::DefaultStyle("mapbox://styles/mapbox/light-v10", "Light", 10),
@@ -257,7 +257,7 @@ namespace mbgl {
TileServerOptions TileServerOptions::MapTilerConfiguration() {
std::vector<const mbgl::util::DefaultStyle> styles{
std::vector<mbgl::util::DefaultStyle> styles{
mbgl::util::DefaultStyle("maptiler://maps/streets", "Streets", 1),
mbgl::util::DefaultStyle("maptiler://maps/outdoor", "Outdoor", 1),
mbgl::util::DefaultStyle("maptiler://maps/basic", "Basic", 1),

View File

@@ -59,7 +59,7 @@ add_library(
${PROJECT_SOURCE_DIR}/test/style/style_image.test.cpp
${PROJECT_SOURCE_DIR}/test/style/style_layer.test.cpp
${PROJECT_SOURCE_DIR}/test/style/style_parser.test.cpp
${PROJECT_SOURCE_DIR}/test/text/bidi.test.cpp
$<$<NOT:$<PLATFORM_ID:Windows>>:${PROJECT_SOURCE_DIR}/test/text/bidi.test.cpp>
${PROJECT_SOURCE_DIR}/test/text/calculate_tile_distances.test.cpp
${PROJECT_SOURCE_DIR}/test/text/cross_tile_symbol_index.test.cpp
${PROJECT_SOURCE_DIR}/test/text/formatted.test.cpp

View File

@@ -874,7 +874,7 @@ TEST(Transform, MinMaxPitch) {
static const double abs_double_error = 1e-5;
MATCHER_P(Vec3NearEquals, vec, "") {
MATCHER_P(Vec3NearEquals1E5, vec, "") {
return std::fabs(vec[0] - arg[0]) <= abs_double_error && std::fabs(vec[1] - arg[1]) <= abs_double_error &&
std::fabs(vec[2] - arg[2]) <= abs_double_error;
}
@@ -895,7 +895,7 @@ TEST(Transform, FreeCameraOptionsInvalidSize) {
EXPECT_DOUBLE_EQ(0.0, updatedOrientation[2]);
EXPECT_DOUBLE_EQ(1.0, updatedOrientation[3]);
EXPECT_THAT(updatedPosition, Vec3NearEquals(vec3{{0.0, 0.0, 0.0}}));
EXPECT_THAT(updatedPosition, Vec3NearEquals1E5(vec3{{0.0, 0.0, 0.0}}));
}
TEST(Transform, FreeCameraOptionsNanInput) {
@@ -914,7 +914,7 @@ TEST(Transform, FreeCameraOptionsNanInput) {
options.position = vec3{{0.3, 0.1, 0.2}};
options.orientation = vec4{{NAN, 0.0, NAN, 0.0}};
transform.setFreeCameraOptions(options);
EXPECT_THAT(transform.getFreeCameraOptions().position.value(), Vec3NearEquals(vec3{{0.3, 0.1, 0.2}}));
EXPECT_THAT(transform.getFreeCameraOptions().position.value(), Vec3NearEquals1E5(vec3{{0.3, 0.1, 0.2}}));
EXPECT_EQ(Quaternion::identity.m, transform.getFreeCameraOptions().orientation.value());
}
@@ -1008,9 +1008,9 @@ TEST(Transform, FreeCameraOptionsClampPitch) {
transform.setFreeCameraOptions(options);
EXPECT_DOUBLE_EQ(util::PITCH_MAX, transform.getState().getPitch());
std::tie(right, up, forward) = rotatedFrame(transform.getFreeCameraOptions().orientation.value());
EXPECT_THAT(right, Vec3NearEquals(vec3{{1.0, 0.0, 0.0}}));
EXPECT_THAT(up, Vec3NearEquals(vec3{{0, -0.5, 0.866025}}));
EXPECT_THAT(forward, Vec3NearEquals(vec3{{0, -0.866025, -0.5}}));
EXPECT_THAT(right, Vec3NearEquals1E5(vec3{{1.0, 0.0, 0.0}}));
EXPECT_THAT(up, Vec3NearEquals1E5(vec3{{0, -0.5, 0.866025}}));
EXPECT_THAT(forward, Vec3NearEquals1E5(vec3{{0, -0.866025, -0.5}}));
}
TEST(Transform, FreeCameraOptionsClampToBounds) {
@@ -1034,10 +1034,10 @@ TEST(Transform, FreeCameraOptionsClampToBounds) {
vec3 right, up, forward;
std::tie(right, up, forward) = rotatedFrame(transform.getFreeCameraOptions().orientation.value());
EXPECT_THAT(transform.getFreeCameraOptions().position.value(),
Vec3NearEquals(vec3{{0.0976562, 0.304816, 0.20716}}));
EXPECT_THAT(right, Vec3NearEquals(vec3{{1.0, 0.0, 0.0}}));
EXPECT_THAT(up, Vec3NearEquals(vec3{{0, -0.707107, 0.707107}}));
EXPECT_THAT(forward, Vec3NearEquals(vec3{{0, -0.707107, -0.707107}}));
Vec3NearEquals1E5(vec3{{0.0976562, 0.304816, 0.20716}}));
EXPECT_THAT(right, Vec3NearEquals1E5(vec3{{1.0, 0.0, 0.0}}));
EXPECT_THAT(up, Vec3NearEquals1E5(vec3{{0, -0.707107, 0.707107}}));
EXPECT_THAT(forward, Vec3NearEquals1E5(vec3{{0, -0.707107, -0.707107}}));
}
TEST(Transform, FreeCameraOptionsInvalidState) {
@@ -1050,7 +1050,7 @@ TEST(Transform, FreeCameraOptionsInvalidState) {
EXPECT_DOUBLE_EQ(0.0, transform.getState().getPitch());
const auto options = transform.getFreeCameraOptions();
EXPECT_THAT(options.position.value(), Vec3NearEquals(vec3{{0.0, 0.0, 0.0}}));
EXPECT_THAT(options.position.value(), Vec3NearEquals1E5(vec3{{0.0, 0.0, 0.0}}));
}
TEST(Transform, FreeCameraOptionsOrientationRoll) {
@@ -1083,31 +1083,31 @@ TEST(Transform, FreeCameraOptionsStateSynchronization) {
transform.jumpTo(CameraOptions().withPitch(0.0).withBearing(0.0));
std::tie(right, up, forward) = rotatedFrame(transform.getFreeCameraOptions().orientation.value());
EXPECT_THAT(transform.getFreeCameraOptions().position.value(), Vec3NearEquals(vec3{{0.5, 0.5, 0.29296875}}));
EXPECT_THAT(right, Vec3NearEquals(vec3{{1.0, 0.0, 0.0}}));
EXPECT_THAT(up, Vec3NearEquals(vec3{{0.0, -1.0, 0.0}}));
EXPECT_THAT(forward, Vec3NearEquals(vec3{{0.0, 0.0, -1.0}}));
EXPECT_THAT(transform.getFreeCameraOptions().position.value(), Vec3NearEquals1E5(vec3{{0.5, 0.5, 0.29296875}}));
EXPECT_THAT(right, Vec3NearEquals1E5(vec3{{1.0, 0.0, 0.0}}));
EXPECT_THAT(up, Vec3NearEquals1E5(vec3{{0.0, -1.0, 0.0}}));
EXPECT_THAT(forward, Vec3NearEquals1E5(vec3{{0.0, 0.0, -1.0}}));
transform.jumpTo(CameraOptions().withCenter(LatLng{60.1699, 24.9384}));
EXPECT_THAT(transform.getFreeCameraOptions().position.value(),
Vec3NearEquals(vec3{{0.569273, 0.289453, 0.292969}}));
Vec3NearEquals1E5(vec3{{0.569273, 0.289453, 0.292969}}));
transform.jumpTo(CameraOptions().withPitch(20.0).withBearing(77.0).withCenter(LatLng{-20.0, 20.0}));
EXPECT_THAT(transform.getFreeCameraOptions().position.value(), Vec3NearEquals(vec3{{0.457922, 0.57926, 0.275301}}));
EXPECT_THAT(transform.getFreeCameraOptions().position.value(), Vec3NearEquals1E5(vec3{{0.457922, 0.57926, 0.275301}}));
// Invalid pitch
transform.jumpTo(CameraOptions().withPitch(-10.0).withBearing(0.0));
std::tie(right, up, forward) = rotatedFrame(transform.getFreeCameraOptions().orientation.value());
EXPECT_THAT(transform.getFreeCameraOptions().position.value(),
Vec3NearEquals(vec3{{0.555556, 0.556719, 0.292969}}));
EXPECT_THAT(right, Vec3NearEquals(vec3{{1.0, 0.0, 0.0}}));
EXPECT_THAT(up, Vec3NearEquals(vec3{{0.0, -1.0, 0.0}}));
EXPECT_THAT(forward, Vec3NearEquals(vec3{{0.0, 0.0, -1.0}}));
Vec3NearEquals1E5(vec3{{0.555556, 0.556719, 0.292969}}));
EXPECT_THAT(right, Vec3NearEquals1E5(vec3{{1.0, 0.0, 0.0}}));
EXPECT_THAT(up, Vec3NearEquals1E5(vec3{{0.0, -1.0, 0.0}}));
EXPECT_THAT(forward, Vec3NearEquals1E5(vec3{{0.0, 0.0, -1.0}}));
transform.jumpTo(CameraOptions().withPitch(85.0).withBearing(0.0).withCenter(LatLng{-80.0, 0.0}));
std::tie(right, up, forward) = rotatedFrame(transform.getFreeCameraOptions().orientation.value());
EXPECT_THAT(transform.getFreeCameraOptions().position.value(), Vec3NearEquals(vec3{{0.5, 1.14146, 0.146484}}));
EXPECT_THAT(right, Vec3NearEquals(vec3{{1.0, 0.0, 0.0}}));
EXPECT_THAT(up, Vec3NearEquals(vec3{{0, -0.5, 0.866025}}));
EXPECT_THAT(forward, Vec3NearEquals(vec3{{0, -0.866025, -0.5}}));
EXPECT_THAT(transform.getFreeCameraOptions().position.value(), Vec3NearEquals1E5(vec3{{0.5, 1.14146, 0.146484}}));
EXPECT_THAT(right, Vec3NearEquals1E5(vec3{{1.0, 0.0, 0.0}}));
EXPECT_THAT(up, Vec3NearEquals1E5(vec3{{0, -0.5, 0.866025}}));
EXPECT_THAT(forward, Vec3NearEquals1E5(vec3{{0, -0.866025, -0.5}}));
}

View File

@@ -56,13 +56,15 @@ public:
return fakeRequest->resource.kind == kind;
});
if (it != requests.end()) {
const bool requestFound = (it != requests.end());
if (requestFound) {
// Copy the callback, in case calling it deallocates the AsyncRequest.
Callback callback_ = (*it)->callback;
callback_(response);
}
return it != requests.end();
return requestFound;
}
std::list<FakeFileRequest*> requests;

View File

@@ -4,10 +4,18 @@
#include <mbgl/util/platform.hpp>
#include <mbgl/util/run_loop.hpp>
#include <unistd.h>
#include <climits>
#include <gtest/gtest.h>
#if defined(WIN32)
#include <Windows.h>
#ifndef PATH_MAX
#define PATH_MAX MAX_PATH
#endif /* PATH_MAX */
#else
#include <unistd.h>
#endif
namespace {
std::string toAbsoluteURL(const std::string& fileName) {
@@ -136,15 +144,22 @@ TEST(LocalFileSource, URLLimit) {
size_t length = PATH_MAX - toAbsoluteURL("").size();
LocalFileSource fs(ResourceOptions::Default());
char filename[length];
char* filename = new char[length];
memset(filename, 'x', length);
std::string url(filename, length);
delete[] filename;
std::unique_ptr<AsyncRequest> req = fs.request({ Resource::Unknown, toAbsoluteURL(url) }, [&](Response res) {
req.reset();
ASSERT_NE(nullptr, res.error);
#if defined(_MSC_VER) && !defined(__clang__)
// Microsoft Visual Studio defines PATH_MAX as 260, less than the limit to trigger an error with reason "Other"
EXPECT_EQ(Response::Error::Reason::NotFound, res.error->reason);
#else
EXPECT_EQ(Response::Error::Reason::Other, res.error->reason);
#endif
ASSERT_FALSE(res.data.get());
loop.stop();
});

View File

@@ -12,6 +12,12 @@
#include <thread>
#include <random>
#if defined(__GNUC__)
#define MBGL_UNUSED __attribute__((unused))
#else
#define MBGL_UNUSED
#endif
using namespace std::literals::string_literals;
using namespace mbgl;
using mapbox::sqlite::ResultCode;
@@ -44,7 +50,7 @@ static FixtureLog::Message error(ResultCode code, const char* message) {
return { EventSeverity::Error, Event::Database, static_cast<int64_t>(code), message };
}
static __attribute__((unused)) FixtureLog::Message warning(ResultCode code, const char* message) {
static MBGL_UNUSED FixtureLog::Message warning(ResultCode code, const char* message) {
return { EventSeverity::Warning, Event::Database, static_cast<int64_t>(code), message };
}
@@ -1857,6 +1863,7 @@ TEST(OfflineDatabase, MergeDatabaseWithSingleRegionTooManyExistingTiles) {
EXPECT_EQ(0u, log.uncheckedCount());
}
#ifndef WIN32 // Windows cannot copy a folder as a file
TEST(OfflineDatabase, MergeDatabaseWithInvalidPath) {
FixtureLog log;
@@ -1871,6 +1878,7 @@ TEST(OfflineDatabase, MergeDatabaseWithInvalidPath) {
EXPECT_EQ(1u, log.count({ EventSeverity::Error, Event::Database, -1, "Merge database has incorrect user_version" }));
EXPECT_EQ(0u, log.uncheckedCount());
}
#endif
TEST(OfflineDatabase, MergeDatabaseWithInvalidDb) {
FixtureLog log;
@@ -1914,7 +1922,9 @@ TEST(OfflineDatabase, ChangePath) {
OfflineDatabase db(":memory:", fixture::tileServerOptions);
db.changePath(newPath);
mapbox::sqlite::Database::open(newPath, mapbox::sqlite::ReadOnly);
#ifndef WIN32 // Windows will fail to delete an open file
util::deleteFile(newPath);
#endif
}
TEST(OfflineDatabase, ResetDatabase) {

View File

@@ -9,7 +9,15 @@
#include <iostream>
#include <fstream>
#if defined(_MSC_VER) && !defined(__clang__)
#include <Windows.h>
#ifdef GetObject
#undef GetObject
#endif
#else
#include <dirent.h>
#endif
using namespace mbgl;
@@ -79,29 +87,50 @@ TEST_P(ExpressionEqualityTest, ExpressionEquality) {
EXPECT_TRUE(*expression_a1 != *expression_b);
}
static void populateNames(std::vector<std::string>& names) {
const std::string ending = ".a.json";
std::string style_directory = "test/fixtures/expression_equality";
auto testName = [&](const std::string& name) {
if (name.length() >= ending.length() &&
name.compare(name.length() - ending.length(), ending.length(), ending) == 0) {
names.push_back(name.substr(0, name.length() - ending.length()));
}
};
#if defined(_MSC_VER) && !defined(__clang__)
style_directory += "/*";
WIN32_FIND_DATAA ffd;
HANDLE hFind = FindFirstFileA(style_directory.c_str(), &ffd);
if (hFind != INVALID_HANDLE_VALUE) {
do {
const std::string name = ffd.cFileName;
testName(name);
} while (FindNextFileA(hFind, &ffd) != 0);
FindClose(hFind);
}
#else
DIR* dir = opendir(style_directory.c_str());
if (dir != nullptr) {
for (dirent* dp = nullptr; (dp = readdir(dir)) != nullptr;) {
const std::string name = dp->d_name;
#if ANDROID
// Android unit test uses number-format stub implementation so skip the tests
if (name.find("number-format") != std::string::npos) {
continue;
}
#endif
testName(name);
}
closedir(dir);
}
#endif
}
INSTANTIATE_TEST_SUITE_P(Expression, ExpressionEqualityTest, ::testing::ValuesIn([] {
std::vector<std::string> names;
const std::string ending = ".a.json";
const std::string style_directory = "test/fixtures/expression_equality";
DIR* dir = opendir(style_directory.c_str());
if (dir != nullptr) {
for (dirent* dp = nullptr; (dp = readdir(dir)) != nullptr;) {
const std::string name = dp->d_name;
#if ANDROID
// Android unit test uses number-format stub implementation so skip the tests
if (name.find("number-format") != std::string::npos) {
continue;
}
#endif
if (name.length() >= ending.length() &&
name.compare(name.length() - ending.length(), ending.length(), ending) == 0) {
names.push_back(name.substr(0, name.length() - ending.length()));
}
}
closedir(dir);
}
populateNames(names);
EXPECT_GT(names.size(), 0u);
return names;
}()));

View File

@@ -12,6 +12,10 @@
#include <memory>
#ifdef WIN32
#include <Windows.h>
#endif
using namespace mbgl;
using namespace mbgl::style;
@@ -101,6 +105,10 @@ TEST(Style, RemoveSourceInUse) {
"Source 'sourceId' is in use, cannot remove",
};
#if defined(WIN32)
Sleep(1000);
#endif
EXPECT_EQ(log->count(logMessage), 1u);
}

View File

@@ -13,7 +13,14 @@
#include <fstream>
#include <set>
#if defined(_MSC_VER) && !defined(__clang__)
#include <Windows.h>
#ifdef GetObject
#undef GetObject
#endif
#else
#include <dirent.h>
#endif
using namespace mbgl;
@@ -61,6 +68,10 @@ TEST_P(StyleParserTest, ParseStyle) {
js_entry[rapidjson::SizeType(3)].GetString()
};
#if defined(WIN32)
Sleep(10);
#endif
EXPECT_EQ(count, observer->count(message)) << "Message: " << message << std::endl;
}
}
@@ -74,23 +85,44 @@ TEST_P(StyleParserTest, ParseStyle) {
}
}
static void populateNames(std::vector<std::string>& names) {
const std::string ending = ".info.json";
std::string style_directory = "test/fixtures/style_parser";
auto testName = [&](const std::string& name) {
if (name.length() >= ending.length() &&
name.compare(name.length() - ending.length(), ending.length(), ending) == 0) {
names.push_back(name.substr(0, name.length() - ending.length()));
}
};
#if defined(_MSC_VER) && !defined(__clang__)
style_directory += "/*";
WIN32_FIND_DATAA ffd;
HANDLE hFind = FindFirstFileA(style_directory.c_str(), &ffd);
if (hFind != INVALID_HANDLE_VALUE) {
do {
const std::string name = ffd.cFileName;
testName(name);
} while (FindNextFileA(hFind, &ffd) != 0);
FindClose(hFind);
}
#else
DIR *dir = opendir(style_directory.c_str());
if (dir != nullptr) {
for (dirent *dp = nullptr; (dp = readdir(dir)) != nullptr;) {
const std::string name = dp->d_name;
testName(name);
}
closedir(dir);
}
#endif
}
INSTANTIATE_TEST_SUITE_P(StyleParser, StyleParserTest, ::testing::ValuesIn([] {
std::vector<std::string> names;
const std::string ending = ".info.json";
const std::string style_directory = "test/fixtures/style_parser";
DIR *dir = opendir(style_directory.c_str());
if (dir != nullptr) {
for (dirent *dp = nullptr; (dp = readdir(dir)) != nullptr;) {
const std::string name = dp->d_name;
if (name.length() >= ending.length() &&
name.compare(name.length() - ending.length(), ending.length(), ending) == 0) {
names.push_back(name.substr(0, name.length() - ending.length()));
}
}
closedir(dir);
}
populateNames(names);
EXPECT_GT(names.size(), 0u);
return names;
}()));

View File

@@ -10,7 +10,7 @@ using namespace mbgl;
static const double abs_double_error = 1e-7;
MATCHER_P(Vec3NearEquals, vec, "") {
MATCHER_P(Vec3NearEquals1E7, vec, "") {
return std::fabs(vec[0] - arg[0]) <= abs_double_error && std::fabs(vec[1] - arg[1]) <= abs_double_error &&
std::fabs(vec[2] - arg[2]) <= abs_double_error;
}
@@ -20,21 +20,21 @@ TEST(FreeCameraOptions, SetLocation) {
options.setLocation({{0.0, 0.0}, util::EARTH_RADIUS_M * M_PI});
ASSERT_TRUE(options.position);
ASSERT_THAT(options.position.value(), Vec3NearEquals(vec3{{0.5, 0.5, 0.5}}));
ASSERT_THAT(options.position.value(), Vec3NearEquals1E7(vec3{{0.5, 0.5, 0.5}}));
options.setLocation({{25.0, -180.0}, 1000.0});
ASSERT_TRUE(options.position);
ASSERT_THAT(options.position.value(), Vec3NearEquals(vec3{{0.0, 0.4282409625, 0.000027532812465}}));
ASSERT_THAT(options.position.value(), Vec3NearEquals1E7(vec3{{0.0, 0.4282409625, 0.000027532812465}}));
options.setLocation(
{{util::LATITUDE_MAX, 0.0}, util::EARTH_RADIUS_M * M_PI * std::cos(util::LATITUDE_MAX * util::DEG2RAD)});
ASSERT_TRUE(options.position);
ASSERT_THAT(options.position.value(), Vec3NearEquals(vec3{{0.5, 0.0, 0.5}}));
ASSERT_THAT(options.position.value(), Vec3NearEquals1E7(vec3{{0.5, 0.0, 0.5}}));
options.setLocation(
{{-util::LATITUDE_MAX, 0.0}, util::EARTH_RADIUS_M * M_PI * std::cos(-util::LATITUDE_MAX * util::DEG2RAD)});
ASSERT_TRUE(options.position);
ASSERT_THAT(options.position.value(), Vec3NearEquals(vec3{{0.5, 1.0, 0.5}}));
ASSERT_THAT(options.position.value(), Vec3NearEquals1E7(vec3{{0.5, 1.0, 0.5}}));
}
TEST(FreeCameraOptions, SetLocationNegativeAltitude) {
@@ -49,7 +49,7 @@ TEST(FreeCameraOptions, SetLocationUnwrappedLocation) {
options.setLocation({{0.0, -540.0}, 0.0});
ASSERT_TRUE(options.position);
ASSERT_THAT(options.position.value(), Vec3NearEquals(vec3{{-1.0, 0.5, 0.0}}));
ASSERT_THAT(options.position.value(), Vec3NearEquals1E7(vec3{{-1.0, 0.5, 0.0}}));
}
TEST(FreeCameraOptions, GetLocation) {
@@ -126,9 +126,9 @@ TEST(FreeCameraOptions, LookAtPoint) {
ASSERT_TRUE(options.orientation);
std::tie(right, up, forward) = rotatedFrame(options.orientation.value());
ASSERT_THAT(right, Vec3NearEquals(vec3{{1.0, 0.0, 0.0}}));
ASSERT_THAT(up, Vec3NearEquals(vec3{{0.0, -cosPi4, cosPi4}}));
ASSERT_THAT(forward, Vec3NearEquals(vec3{{0.0, -cosPi4, -cosPi4}}));
ASSERT_THAT(right, Vec3NearEquals1E7(vec3{{1.0, 0.0, 0.0}}));
ASSERT_THAT(up, Vec3NearEquals1E7(vec3{{0.0, -cosPi4, cosPi4}}));
ASSERT_THAT(forward, Vec3NearEquals1E7(vec3{{0.0, -cosPi4, -cosPi4}}));
// Look directly to east
options.position = vec3{{0.5, 0.5, 0.0}};
@@ -136,9 +136,9 @@ TEST(FreeCameraOptions, LookAtPoint) {
ASSERT_TRUE(options.orientation);
std::tie(right, up, forward) = rotatedFrame(options.orientation.value());
ASSERT_THAT(right, Vec3NearEquals(vec3{{0.0, 1.0, 0.0}}));
ASSERT_THAT(up, Vec3NearEquals(vec3{{0.0, 0.0, 1.0}}));
ASSERT_THAT(forward, Vec3NearEquals(vec3{{1.0, 0.0, 0.0}}));
ASSERT_THAT(right, Vec3NearEquals1E7(vec3{{0.0, 1.0, 0.0}}));
ASSERT_THAT(up, Vec3NearEquals1E7(vec3{{0.0, 0.0, 1.0}}));
ASSERT_THAT(forward, Vec3NearEquals1E7(vec3{{1.0, 0.0, 0.0}}));
// Pitch: 0, bearing: 0
options.setLocation({{60.1699, 24.9384}, 100.0});
@@ -146,9 +146,9 @@ TEST(FreeCameraOptions, LookAtPoint) {
ASSERT_TRUE(options.orientation);
std::tie(right, up, forward) = rotatedFrame(options.orientation.value());
ASSERT_THAT(right, Vec3NearEquals(vec3{{1.0, 0.0, 0.0}}));
ASSERT_THAT(up, Vec3NearEquals(vec3{{0.0, -1.0, 0.0}}));
ASSERT_THAT(forward, Vec3NearEquals(vec3{{0.0, 0.0, -1.0}}));
ASSERT_THAT(right, Vec3NearEquals1E7(vec3{{1.0, 0.0, 0.0}}));
ASSERT_THAT(up, Vec3NearEquals1E7(vec3{{0.0, -1.0, 0.0}}));
ASSERT_THAT(forward, Vec3NearEquals1E7(vec3{{0.0, 0.0, -1.0}}));
// Pitch: 0, bearing: 45
options.setLocation({{60.1699, 24.9384}, 100.0});
@@ -156,9 +156,9 @@ TEST(FreeCameraOptions, LookAtPoint) {
ASSERT_TRUE(options.orientation);
std::tie(right, up, forward) = rotatedFrame(options.orientation.value());
ASSERT_THAT(right, Vec3NearEquals(vec3{{cosPi4, -cosPi4, 0.0}}));
ASSERT_THAT(up, Vec3NearEquals(vec3{{-cosPi4, -cosPi4, 0.0}}));
ASSERT_THAT(forward, Vec3NearEquals(vec3{{0.0, 0.0, -1.0}}));
ASSERT_THAT(right, Vec3NearEquals1E7(vec3{{cosPi4, -cosPi4, 0.0}}));
ASSERT_THAT(up, Vec3NearEquals1E7(vec3{{-cosPi4, -cosPi4, 0.0}}));
ASSERT_THAT(forward, Vec3NearEquals1E7(vec3{{0.0, 0.0, -1.0}}));
// Looking south, up vector almost same as forward vector
options.setLocation({{37.7749, 122.4194}, 0.0});
@@ -166,9 +166,9 @@ TEST(FreeCameraOptions, LookAtPoint) {
ASSERT_TRUE(options.orientation);
std::tie(right, up, forward) = rotatedFrame(options.orientation.value());
ASSERT_THAT(right, Vec3NearEquals(vec3{{-1.0, 0.0, 0.0}}));
ASSERT_THAT(up, Vec3NearEquals(vec3{{0.0, 0.0, 1.0}}));
ASSERT_THAT(forward, Vec3NearEquals(vec3{{0.0, 1.0, 0.0}}));
ASSERT_THAT(right, Vec3NearEquals1E7(vec3{{-1.0, 0.0, 0.0}}));
ASSERT_THAT(up, Vec3NearEquals1E7(vec3{{0.0, 0.0, 1.0}}));
ASSERT_THAT(forward, Vec3NearEquals1E7(vec3{{0.0, 1.0, 0.0}}));
// Orientation with roll-component
options.setLocation({{-33.8688, 151.2093}, 0.0});
@@ -176,9 +176,9 @@ TEST(FreeCameraOptions, LookAtPoint) {
ASSERT_TRUE(options.orientation);
std::tie(right, up, forward) = rotatedFrame(options.orientation.value());
ASSERT_THAT(right, Vec3NearEquals(vec3{{0.0, 1.0, 0.0}}));
ASSERT_THAT(up, Vec3NearEquals(vec3{{0.0, 0.0, 1.0}}));
ASSERT_THAT(forward, Vec3NearEquals(vec3{{1.0, 0.0, 0.0}}));
ASSERT_THAT(right, Vec3NearEquals1E7(vec3{{0.0, 1.0, 0.0}}));
ASSERT_THAT(up, Vec3NearEquals1E7(vec3{{0.0, 0.0, 1.0}}));
ASSERT_THAT(forward, Vec3NearEquals1E7(vec3{{1.0, 0.0, 0.0}}));
// Up vector pointing downwards
options.position = vec3{{0.5, 0.5, 0.5}};
@@ -186,9 +186,9 @@ TEST(FreeCameraOptions, LookAtPoint) {
ASSERT_TRUE(options.orientation);
std::tie(right, up, forward) = rotatedFrame(options.orientation.value());
ASSERT_THAT(right, Vec3NearEquals(vec3{{1.0, 0.0, 0.0}}));
ASSERT_THAT(up, Vec3NearEquals(vec3{{0.0, -cosPi4, cosPi4}}));
ASSERT_THAT(forward, Vec3NearEquals(vec3{{0.0, -cosPi4, -cosPi4}}));
ASSERT_THAT(right, Vec3NearEquals1E7(vec3{{1.0, 0.0, 0.0}}));
ASSERT_THAT(up, Vec3NearEquals1E7(vec3{{0.0, -cosPi4, cosPi4}}));
ASSERT_THAT(forward, Vec3NearEquals1E7(vec3{{0.0, -cosPi4, -cosPi4}}));
}
TEST(FreeCameraOptions, LookAtPointInvalidInput) {
@@ -229,16 +229,16 @@ TEST(FreeCameraOptions, SetPitchBearing) {
options.setPitchBearing(0.0, 0.0);
ASSERT_TRUE(options.orientation);
std::tie(right, up, forward) = rotatedFrame(options.orientation.value());
ASSERT_THAT(right, Vec3NearEquals(vec3{{1.0, 0.0, 0.0}}));
ASSERT_THAT(up, Vec3NearEquals(vec3{{0.0, -1.0, 0.0}}));
ASSERT_THAT(forward, Vec3NearEquals(vec3{{0.0, 0.0, -1.0}}));
ASSERT_THAT(right, Vec3NearEquals1E7(vec3{{1.0, 0.0, 0.0}}));
ASSERT_THAT(up, Vec3NearEquals1E7(vec3{{0.0, -1.0, 0.0}}));
ASSERT_THAT(forward, Vec3NearEquals1E7(vec3{{0.0, 0.0, -1.0}}));
options.setPitchBearing(0.0, 180.0);
ASSERT_TRUE(options.orientation);
std::tie(right, up, forward) = rotatedFrame(options.orientation.value());
ASSERT_THAT(right, Vec3NearEquals(vec3{{-1.0, 0.0, 0.0}}));
ASSERT_THAT(up, Vec3NearEquals(vec3{{0.0, 1.0, 0.0}}));
ASSERT_THAT(forward, Vec3NearEquals(vec3{{0.0, 0.0, -1.0}}));
ASSERT_THAT(right, Vec3NearEquals1E7(vec3{{-1.0, 0.0, 0.0}}));
ASSERT_THAT(up, Vec3NearEquals1E7(vec3{{0.0, 1.0, 0.0}}));
ASSERT_THAT(forward, Vec3NearEquals1E7(vec3{{0.0, 0.0, -1.0}}));
const double cos60 = std::cos(60.0 * util::DEG2RAD);
const double sin60 = std::sin(60.0 * util::DEG2RAD);
@@ -246,14 +246,14 @@ TEST(FreeCameraOptions, SetPitchBearing) {
options.setPitchBearing(60.0, 0.0);
ASSERT_TRUE(options.orientation);
std::tie(right, up, forward) = rotatedFrame(options.orientation.value());
ASSERT_THAT(right, Vec3NearEquals(vec3{{1.0, 0.0, 0.0}}));
ASSERT_THAT(up, Vec3NearEquals(vec3{{0.0, -cos60, sin60}}));
ASSERT_THAT(forward, Vec3NearEquals(vec3{{0.0, -sin60, -cos60}}));
ASSERT_THAT(right, Vec3NearEquals1E7(vec3{{1.0, 0.0, 0.0}}));
ASSERT_THAT(up, Vec3NearEquals1E7(vec3{{0.0, -cos60, sin60}}));
ASSERT_THAT(forward, Vec3NearEquals1E7(vec3{{0.0, -sin60, -cos60}}));
options.setPitchBearing(60.0, -450);
ASSERT_TRUE(options.orientation);
std::tie(right, up, forward) = rotatedFrame(options.orientation.value());
ASSERT_THAT(right, Vec3NearEquals(vec3{{0.0, 1.0, 0.0}}));
ASSERT_THAT(up, Vec3NearEquals(vec3{{cos60, 0.0, sin60}}));
ASSERT_THAT(forward, Vec3NearEquals(vec3{{sin60, 0.0, -cos60}}));
ASSERT_THAT(right, Vec3NearEquals1E7(vec3{{0.0, 1.0, 0.0}}));
ASSERT_THAT(up, Vec3NearEquals1E7(vec3{{cos60, 0.0, sin60}}));
ASSERT_THAT(forward, Vec3NearEquals1E7(vec3{{sin60, 0.0, -cos60}}));
}

View File

@@ -1,3 +1,5 @@
#define NOMINMAX
#include <mbgl/test/stub_file_source.hpp>
#include <mbgl/test/getrss.hpp>
#include <mbgl/test/util.hpp>
@@ -18,7 +20,10 @@
#include <memory>
#include <cstdlib>
#if !defined(_MSC_VER) || defined(__clang__)
#include <unistd.h>
#endif
using namespace mbgl;
using namespace std::literals::string_literals;

View File

@@ -9,6 +9,10 @@
#include <atomic>
#include <memory>
#if defined(WIN32)
#include <Windows.h>
#endif
using namespace mbgl;
using namespace mbgl::util;
@@ -198,7 +202,11 @@ TEST(Thread, ReferenceCanOutliveThread) {
worker.invoke(&TestWorker::send, [&] { ADD_FAILURE() << "Should never happen"; });
}
#if defined(WIN32)
Sleep(10);
#else
usleep(10000);
#endif
}
TEST(Thread, DeletePausedThread) {

4
vendor/icu.cmake vendored
View File

@@ -33,7 +33,9 @@ target_compile_definitions(
_REENTRANT
)
target_compile_options(mbgl-vendor-icu PRIVATE -Wno-error -Wno-shorten-64-to-32)
if(NOT MSVC)
target_compile_options(mbgl-vendor-icu PRIVATE -Wno-error -Wno-shorten-64-to-32)
endif()
target_include_directories(
mbgl-vendor-icu SYSTEM

View File

@@ -18,7 +18,9 @@ target_compile_definitions(
PRIVATE NU_BUILD_STATIC
)
target_compile_options(mbgl-vendor-nunicode PRIVATE -Wno-error)
if(NOT MSVC)
target_compile_options(mbgl-vendor-nunicode PRIVATE -Wno-error)
endif()
target_include_directories(
mbgl-vendor-nunicode SYSTEM