summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Loer <chris.loer@gmail.com>2017-12-15 09:08:20 -0800
committerChris Loer <chris.loer@mapbox.com>2017-12-18 12:17:22 -0800
commita53818a10b821218b86478e048a3884db93f7c00 (patch)
tree9de0e83b67c163a4c8ed6f02736b2ad2ca2e8d15
parent2e3e88f0276bb6b6ade009549d8927f4af96bdd9 (diff)
downloadqtlocation-mapboxgl-a53818a10b821218b86478e048a3884db93f7c00.tar.gz
[core] Enable local glyph generation using TinySDF.
- Platform-specific LocalGlyphRasterizer is responsible for deciding which glyphs to rasterize locally and for implementing the rasterization. - Default platform implementation doesn't locally generate any glyphs -> no behavior change - Unit test uses StubLocalGlyphRasterizer, which returns a single fixed bitmap for all CJK glyphs - Rename glyph_loader.test to glyph_manager.test
-rw-r--r--cmake/core-files.cmake1
-rw-r--r--platform/android/config.cmake1
-rw-r--r--platform/default/local_glyph_rasterizer.cpp13
-rw-r--r--platform/ios/config.cmake1
-rw-r--r--platform/linux/config.cmake1
-rw-r--r--platform/macos/config.cmake1
-rw-r--r--platform/qt/config.cmake2
-rw-r--r--src/mbgl/text/glyph_manager.cpp21
-rw-r--r--src/mbgl/text/glyph_manager.hpp9
-rw-r--r--src/mbgl/text/local_glyph_rasterizer.hpp42
10 files changed, 86 insertions, 6 deletions
diff --git a/cmake/core-files.cmake b/cmake/core-files.cmake
index 00d8d8af10..33b3072f3a 100644
--- a/cmake/core-files.cmake
+++ b/cmake/core-files.cmake
@@ -481,6 +481,7 @@ set(MBGL_CORE_FILES
src/mbgl/text/glyph_pbf.cpp
src/mbgl/text/glyph_pbf.hpp
src/mbgl/text/glyph_range.hpp
+ src/mbgl/text/local_glyph_rasterizer.hpp
src/mbgl/text/placement_config.hpp
src/mbgl/text/quads.cpp
src/mbgl/text/quads.hpp
diff --git a/platform/android/config.cmake b/platform/android/config.cmake
index 47f894f7b9..c7609f1644 100644
--- a/platform/android/config.cmake
+++ b/platform/android/config.cmake
@@ -36,6 +36,7 @@ macro(mbgl_platform_core)
PRIVATE platform/android/src/thread.cpp
PRIVATE platform/default/string_stdlib.cpp
PRIVATE platform/default/bidi.cpp
+ PRIVATE platform/default/local_glyph_rasterizer.cpp
PRIVATE platform/default/thread_local.cpp
PRIVATE platform/default/utf.cpp
diff --git a/platform/default/local_glyph_rasterizer.cpp b/platform/default/local_glyph_rasterizer.cpp
new file mode 100644
index 0000000000..7ace6cbfb1
--- /dev/null
+++ b/platform/default/local_glyph_rasterizer.cpp
@@ -0,0 +1,13 @@
+#include <mbgl/text/local_glyph_rasterizer.hpp>
+
+namespace mbgl {
+
+bool LocalGlyphRasterizer::canRasterizeGlyph(const FontStack&, GlyphID) {
+ return false;
+}
+
+Glyph LocalGlyphRasterizer::rasterizeGlyph(const FontStack&, GlyphID) {
+ return Glyph();
+}
+
+} // namespace mbgl
diff --git a/platform/ios/config.cmake b/platform/ios/config.cmake
index c3db194988..3b99211299 100644
--- a/platform/ios/config.cmake
+++ b/platform/ios/config.cmake
@@ -32,6 +32,7 @@ macro(mbgl_platform_core)
PRIVATE platform/darwin/src/nsthread.mm
PRIVATE platform/darwin/src/string_nsstring.mm
PRIVATE platform/default/bidi.cpp
+ PRIVATE platform/default/local_glyph_rasterizer.cpp
PRIVATE platform/default/thread_local.cpp
PRIVATE platform/default/utf.cpp
diff --git a/platform/linux/config.cmake b/platform/linux/config.cmake
index 47c4c68806..fddcf90278 100644
--- a/platform/linux/config.cmake
+++ b/platform/linux/config.cmake
@@ -51,6 +51,7 @@ macro(mbgl_platform_core)
PRIVATE platform/default/string_stdlib.cpp
PRIVATE platform/default/thread.cpp
PRIVATE platform/default/bidi.cpp
+ PRIVATE platform/default/local_glyph_rasterizer.cpp
PRIVATE platform/default/thread_local.cpp
PRIVATE platform/default/utf.cpp
diff --git a/platform/macos/config.cmake b/platform/macos/config.cmake
index aca99f9b40..3e7f548bab 100644
--- a/platform/macos/config.cmake
+++ b/platform/macos/config.cmake
@@ -18,6 +18,7 @@ macro(mbgl_platform_core)
PRIVATE platform/darwin/src/nsthread.mm
PRIVATE platform/darwin/src/string_nsstring.mm
PRIVATE platform/default/bidi.cpp
+ PRIVATE platform/default/local_glyph_rasterizer.cpp
PRIVATE platform/default/thread_local.cpp
PRIVATE platform/default/utf.cpp
diff --git a/platform/qt/config.cmake b/platform/qt/config.cmake
index a7fdbf3542..57e586d7c3 100644
--- a/platform/qt/config.cmake
+++ b/platform/qt/config.cmake
@@ -48,6 +48,8 @@ macro(mbgl_platform_core)
target_sources(mbgl-core PRIVATE platform/qt/src/bidi.cpp)
endif()
+ target_sources(mbgl-core PRIVATE platform/default/local_glyph_rasterizer.cpp)
+
endmacro()
diff --git a/src/mbgl/text/glyph_manager.cpp b/src/mbgl/text/glyph_manager.cpp
index 916d39ae62..59b019b547 100644
--- a/src/mbgl/text/glyph_manager.cpp
+++ b/src/mbgl/text/glyph_manager.cpp
@@ -4,14 +4,16 @@
#include <mbgl/storage/file_source.hpp>
#include <mbgl/storage/resource.hpp>
#include <mbgl/storage/response.hpp>
+#include <mbgl/util/tiny_sdf.hpp>
namespace mbgl {
static GlyphManagerObserver nullObserver;
-GlyphManager::GlyphManager(FileSource& fileSource_)
+GlyphManager::GlyphManager(FileSource& fileSource_, std::unique_ptr<LocalGlyphRasterizer> localGlyphRasterizer_)
: fileSource(fileSource_),
- observer(&nullObserver) {
+ observer(&nullObserver),
+ localGlyphRasterizer(std::move(localGlyphRasterizer_)) {
}
GlyphManager::~GlyphManager() = default;
@@ -30,7 +32,13 @@ void GlyphManager::getGlyphs(GlyphRequestor& requestor, GlyphDependencies glyphD
const GlyphIDs& glyphIDs = dependency.second;
GlyphRangeSet ranges;
for (const auto& glyphID : glyphIDs) {
- ranges.insert(getGlyphRange(glyphID));
+ if (localGlyphRasterizer->canRasterizeGlyph(fontStack, glyphID)) {
+ if (entry.glyphs.find(glyphID) == entry.glyphs.end()) {
+ entry.glyphs.emplace(glyphID, makeMutable<Glyph>(generateLocalSDF(fontStack, glyphID)));
+ }
+ } else {
+ ranges.insert(getGlyphRange(glyphID));
+ }
}
for (const auto& range : ranges) {
@@ -49,9 +57,14 @@ void GlyphManager::getGlyphs(GlyphRequestor& requestor, GlyphDependencies glyphD
}
}
+Glyph GlyphManager::generateLocalSDF(const FontStack& fontStack, GlyphID glyphID) {
+ Glyph local = localGlyphRasterizer->rasterizeGlyph(fontStack, glyphID);
+ local.bitmap = util::transformRasterToSDF(local.bitmap, 8, .25);
+ return local;
+}
+
GlyphManager::GlyphRequest& GlyphManager::requestRange(Entry& entry, const FontStack& fontStack, const GlyphRange& range) {
GlyphRequest& request = entry.ranges[range];
-
if (request.req) {
return request;
}
diff --git a/src/mbgl/text/glyph_manager.hpp b/src/mbgl/text/glyph_manager.hpp
index 00df079462..13a8c07429 100644
--- a/src/mbgl/text/glyph_manager.hpp
+++ b/src/mbgl/text/glyph_manager.hpp
@@ -3,6 +3,7 @@
#include <mbgl/text/glyph.hpp>
#include <mbgl/text/glyph_manager_observer.hpp>
#include <mbgl/text/glyph_range.hpp>
+#include <mbgl/text/local_glyph_rasterizer.hpp>
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/util/font_stack.hpp>
#include <mbgl/util/immutable.hpp>
@@ -24,7 +25,7 @@ public:
class GlyphManager : public util::noncopyable {
public:
- GlyphManager(FileSource&);
+ GlyphManager(FileSource&, std::unique_ptr<LocalGlyphRasterizer> = std::make_unique<LocalGlyphRasterizer>());
~GlyphManager();
// Workers send a `getGlyphs` message to the main thread once they have determined
@@ -42,6 +43,8 @@ public:
void setObserver(GlyphManagerObserver*);
private:
+ Glyph generateLocalSDF(const FontStack& fontStack, GlyphID glyphID);
+
FileSource& fileSource;
std::string glyphURL;
@@ -61,8 +64,10 @@ private:
GlyphRequest& requestRange(Entry&, const FontStack&, const GlyphRange&);
void processResponse(const Response&, const FontStack&, const GlyphRange&);
void notify(GlyphRequestor&, const GlyphDependencies&);
-
+
GlyphManagerObserver* observer = nullptr;
+
+ std::unique_ptr<LocalGlyphRasterizer> localGlyphRasterizer;
};
} // namespace mbgl
diff --git a/src/mbgl/text/local_glyph_rasterizer.hpp b/src/mbgl/text/local_glyph_rasterizer.hpp
new file mode 100644
index 0000000000..c2bdbd2840
--- /dev/null
+++ b/src/mbgl/text/local_glyph_rasterizer.hpp
@@ -0,0 +1,42 @@
+#pragma once
+
+#include <mbgl/text/glyph.hpp>
+
+namespace mbgl {
+
+/*
+ Given a font stack and a glyph ID, platform-specific implementations of
+ LocalGlyphRasterizer will decide which, if any, local fonts to use and
+ then generate a matching glyph object with a greyscale rasterization of
+ the glyph and appropriate metrics. GlyphManager will then use TinySDF to
+ transform the rasterized bitmap into an SDF.
+
+ The JS equivalent of this functionality will only generate glyphs in the
+ 'CJK Unified Ideographs' and 'Hangul Syllables' ranges, for which it can
+ get away with rendering a fixed 30px square image and GlyphMetrics of:
+
+ width: 24,
+ height: 24,
+ left: 0,
+ top: -8,
+ advance: 24
+
+ The JS equivalent also uses heuristic evaluation of the font stack name
+ to control the font-weight it uses during rasterization.
+
+ It is left to platform-specific implementation to decide how best to
+ map a FontStack to a particular rasterization.
+
+ The default implementation simply refuses to rasterize any glyphs.
+*/
+
+class LocalGlyphRasterizer {
+public:
+ virtual ~LocalGlyphRasterizer() = default;
+
+ // virtual so that test harness can override platform-specific behavior
+ virtual bool canRasterizeGlyph(const FontStack&, GlyphID);
+ virtual Glyph rasterizeGlyph(const FontStack&, GlyphID);
+};
+
+} // namespace mbgl