diff options
author | Chris Loer <chris.loer@gmail.com> | 2017-12-15 09:08:20 -0800 |
---|---|---|
committer | Chris Loer <chris.loer@mapbox.com> | 2017-12-18 12:17:22 -0800 |
commit | a53818a10b821218b86478e048a3884db93f7c00 (patch) | |
tree | 9de0e83b67c163a4c8ed6f02736b2ad2ca2e8d15 | |
parent | 2e3e88f0276bb6b6ade009549d8927f4af96bdd9 (diff) | |
download | qtlocation-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.cmake | 1 | ||||
-rw-r--r-- | platform/android/config.cmake | 1 | ||||
-rw-r--r-- | platform/default/local_glyph_rasterizer.cpp | 13 | ||||
-rw-r--r-- | platform/ios/config.cmake | 1 | ||||
-rw-r--r-- | platform/linux/config.cmake | 1 | ||||
-rw-r--r-- | platform/macos/config.cmake | 1 | ||||
-rw-r--r-- | platform/qt/config.cmake | 2 | ||||
-rw-r--r-- | src/mbgl/text/glyph_manager.cpp | 21 | ||||
-rw-r--r-- | src/mbgl/text/glyph_manager.hpp | 9 | ||||
-rw-r--r-- | src/mbgl/text/local_glyph_rasterizer.hpp | 42 |
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 |