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

Commit

Permalink
[core] Enable local glyph generation using TinySDF.
Browse files Browse the repository at this point in the history
 - 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
  • Loading branch information
ChrisLoer committed Nov 27, 2017
1 parent 9910e8c commit e4e6aaa
Show file tree
Hide file tree
Showing 13 changed files with 428 additions and 271 deletions.
1 change: 1 addition & 0 deletions cmake/core-files.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,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.cpp
src/mbgl/text/placement.hpp
src/mbgl/text/quads.cpp
Expand Down
2 changes: 1 addition & 1 deletion cmake/test-files.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ set(MBGL_TEST_FILES

# text
test/text/cross_tile_symbol_index.test.cpp
test/text/glyph_loader.test.cpp
test/text/glyph_manager.test.cpp
test/text/glyph_pbf.test.cpp
test/text/quads.test.cpp

Expand Down
1 change: 1 addition & 0 deletions platform/android/config.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,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

Expand Down
13 changes: 13 additions & 0 deletions platform/default/local_glyph_rasterizer.cpp
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions platform/ios/config.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
1 change: 1 addition & 0 deletions platform/linux/config.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
1 change: 1 addition & 0 deletions platform/macos/config.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 2 additions & 0 deletions platform/qt/config.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,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()


Expand Down
20 changes: 17 additions & 3 deletions src/mbgl/text/glyph_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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) {
Expand All @@ -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;
Expand Down
9 changes: 7 additions & 2 deletions src/mbgl/text/glyph_manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -24,7 +25,7 @@ class GlyphRequestor {

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
Expand All @@ -42,6 +43,8 @@ class GlyphManager : public util::noncopyable {
void setObserver(GlyphManagerObserver*);

private:
Glyph generateLocalSDF(const FontStack& fontStack, GlyphID glyphID);

FileSource& fileSource;
std::string glyphURL;

Expand All @@ -61,8 +64,10 @@ class GlyphManager : public util::noncopyable {
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
42 changes: 42 additions & 0 deletions src/mbgl/text/local_glyph_rasterizer.hpp
Original file line number Diff line number Diff line change
@@ -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
Loading

0 comments on commit e4e6aaa

Please sign in to comment.