summaryrefslogtreecommitdiff
path: root/src/mbgl/text
diff options
context:
space:
mode:
authorChris Loer <chris.loer@gmail.com>2017-11-21 15:12:07 -0800
committerChris Loer <chris.loer@mapbox.com>2017-12-11 10:43:00 -0800
commit1661af1cb409505bb362e2274cb61f097ad25864 (patch)
tree184b9000d4b5a2f8760468eaa018adc9d6de24ae /src/mbgl/text
parent730054276ed6a5dc7ba9d19765b8457a818854f7 (diff)
downloadqtlocation-mapboxgl-1661af1cb409505bb362e2274cb61f097ad25864.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
Diffstat (limited to 'src/mbgl/text')
-rw-r--r--src/mbgl/text/glyph_manager.cpp20
-rw-r--r--src/mbgl/text/glyph_manager.hpp9
-rw-r--r--src/mbgl/text/local_glyph_rasterizer.hpp42
3 files changed, 66 insertions, 5 deletions
diff --git a/src/mbgl/text/glyph_manager.cpp b/src/mbgl/text/glyph_manager.cpp
index c79a1938c1..3130418908 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) {
@@ -50,6 +58,12 @@ 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;
+}
+
void GlyphManager::requestRange(GlyphRequest& request, const FontStack& fontStack, const GlyphRange& range) {
if (request.req) {
return;
diff --git a/src/mbgl/text/glyph_manager.hpp b/src/mbgl/text/glyph_manager.hpp
index de2b9cde7b..194f503ff1 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:
void requestRange(GlyphRequest&, 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