Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Qt6 and MSVC 2019 Support #16611

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
3 changes: 3 additions & 0 deletions include/mbgl/style/expression/expression.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ class Result : private variant<EvaluationError, T> {

Result() = default;

template <typename U>
VARIANT_INLINE Result(U&& val) : variant<EvaluationError, T>(val) {}

explicit operator bool () const {
return this->template is<T>();
}
Expand Down
3 changes: 3 additions & 0 deletions include/mbgl/style/expression/value.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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; }

Expand Down
32 changes: 16 additions & 16 deletions include/mbgl/util/enum.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,22 @@ class Enum {
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
2 changes: 2 additions & 0 deletions platform/default/src/mbgl/gl/headless_backend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ class HeadlessRenderableResource final : public gl::RenderableResource {
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;
Expand Down
8 changes: 6 additions & 2 deletions platform/default/src/mbgl/storage/sqlite3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

Expand Down Expand Up @@ -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,
Expand Down
8 changes: 7 additions & 1 deletion platform/default/src/mbgl/util/compression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down
4 changes: 2 additions & 2 deletions platform/qt/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand Down
11 changes: 8 additions & 3 deletions platform/qt/app/mapwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -448,16 +448,21 @@ void MapWindow::mouseMoveEvent(QMouseEvent *ev)

void MapWindow::wheelEvent(QWheelEvent *ev)
{
if (ev->orientation() == Qt::Horizontal) {
if (ev->angleDelta().y() == 0) {
return;
}

float factor = ev->delta() / 1200.;
if (ev->delta() < 0) {
float factor = ev->angleDelta().y() / 1200.;
if (ev->angleDelta().y() < 0) {
factor = factor > -1 ? factor : 1 / factor;
}

#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
m_map->scaleBy(1 + factor, ev->position());
#else
m_map->scaleBy(1 + factor, ev->pos());
#endif

ev->accept();
}

Expand Down
72 changes: 50 additions & 22 deletions platform/qt/qt.cmake
Original file line number Diff line number Diff line change
@@ -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)

if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
find_package(Qt${QT_VERSION_MAJOR}
COMPONENTS Gui
Network
OpenGL
OpenGLWidgets
Widgets
REQUIRED)

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")
Expand Down Expand Up @@ -88,10 +94,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
)
Expand Down Expand Up @@ -135,8 +141,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
)
Expand All @@ -155,8 +161,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
)
Expand All @@ -176,20 +183,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
Expand Down
10 changes: 6 additions & 4 deletions platform/qt/src/bidi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
15 changes: 11 additions & 4 deletions platform/qt/src/headless_backend_qt.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include <mbgl/gl/headless_backend.hpp>

#include <QGLWidget>
#include <QOffscreenSurface>
#include <QOpenGLContext>

#include <cassert>
Expand All @@ -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) {
Expand All @@ -18,15 +24,16 @@ class QtBackendImpl final : public HeadlessBackend::Impl {
}

void activateContext() {
widget.makeCurrent();
context.makeCurrent(&surface);
}

void deactivateContext() {
widget.doneCurrent();
context.doneCurrent();
}

private:
QGLWidget widget;
QOpenGLContext context;
QOffscreenSurface surface;
};

void HeadlessBackend::createImpl() {
Expand Down
6 changes: 6 additions & 0 deletions platform/qt/src/http_file_source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,17 @@ void HTTPFileSource::Impl::request(HTTPRequest* req)
}

QNetworkRequest networkRequest = req->networkRequest();
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) // Not needed in Qt6 due to default redirect policy
networkRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
#endif

data.first = m_manager->get(networkRequest);
connect(data.first, SIGNAL(finished()), this, SLOT(onReplyFinished()));
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
connect(data.first, SIGNAL(errorOccurred(QNetworkReply::NetworkError)), this, SLOT(onReplyFinished()));
#else
connect(data.first, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onReplyFinished()));
#endif
}

void HTTPFileSource::Impl::cancel(HTTPRequest* req)
Expand Down
10 changes: 10 additions & 0 deletions platform/qt/src/local_glyph_rasterizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,12 @@ Glyph LocalGlyphRasterizer::rasterizeGlyph(const FontStack&, GlyphID glyphID) {
return glyph;
}

#if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)
glyph.metrics.width = impl->metrics->horizontalAdvance(glyphID);
#else
glyph.metrics.width = impl->metrics->width(glyphID);
#endif

glyph.metrics.height = impl->metrics->height();
glyph.metrics.left = 3;
glyph.metrics.top = -8;
Expand All @@ -68,8 +73,13 @@ Glyph LocalGlyphRasterizer::rasterizeGlyph(const FontStack&, GlyphID glyphID) {
// Render at constant baseline, to align with glyphs that are rendered by node-fontnik.
painter.drawText(QPointF(0, 20), QString(QChar(glyphID)));

#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
auto img = std::make_unique<uint8_t[]>(image.sizeInBytes());
memcpy(img.get(), image.constBits(), image.sizeInBytes());
#else
auto img = std::make_unique<uint8_t[]>(image.byteCount());
memcpy(img.get(), image.constBits(), image.byteCount());
#endif

glyph.bitmap = AlphaImage { size, std::move(img) };

Expand Down
5 changes: 5 additions & 0 deletions platform/qt/src/qmapboxgl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,13 @@ std::unique_ptr<mbgl::style::Image> toStyleImage(const QString &id, const QImage
.rgbSwapped()
.convertToFormat(QImage::Format_ARGB32_Premultiplied);

#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
auto img = std::make_unique<uint8_t[]>(swapped.sizeInBytes());
memcpy(img.get(), swapped.constBits(), swapped.sizeInBytes());
#else
auto img = std::make_unique<uint8_t[]>(swapped.byteCount());
memcpy(img.get(), swapped.constBits(), swapped.byteCount());
#endif

return std::make_unique<mbgl::style::Image>(
id.toStdString(),
Expand Down
5 changes: 5 additions & 0 deletions platform/qt/src/qt_image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,13 @@ PremultipliedImage decodeImage(const std::string& string) {
throw std::runtime_error("Unsupported image type");
}

#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
auto img = std::make_unique<uint8_t[]>(image.sizeInBytes());
memcpy(img.get(), image.constBits(), image.sizeInBytes());
#else
auto img = std::make_unique<uint8_t[]>(image.byteCount());
memcpy(img.get(), image.constBits(), image.byteCount());
#endif

return { { static_cast<uint32_t>(image.width()), static_cast<uint32_t>(image.height()) },
std::move(img) };
Expand Down
Loading