Skip to content

Commit

Permalink
Cleanup platform dependent code in FontContext (#918)
Browse files Browse the repository at this point in the history
* Make font bundle path configurable

* Check for UI font in Java code

Remove ANDROID_FONT_PATH define

* Remove dependent platform code from FontContext

* Don't load font resources at shared_ptr creation

* Cleanup

* Adressing comments
  • Loading branch information
karimnaaji authored and tallytalwar committed Aug 18, 2016
1 parent 6ea22a6 commit 6b0e512
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 88 deletions.
26 changes: 17 additions & 9 deletions android/tangram/src/com/mapzen/tangram/FontFileParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ class FontFileParser {
private Map<String, String> fontDict = new HashMap<String, String>();
private Map<Integer, Vector<String>> fallbackFontDict = new HashMap<Integer, Vector<String>>();

private static String systemFontPath = "/system/fonts/";
// Android version >= 5.0
private static String fontXMLPath = "/system/etc/fonts.xml";
// Android version < 5.0
private static String fontXMLFallbackPath = "/etc/system_fonts.xml";

private void processDocumentFallback(XmlPullParser parser) throws XmlPullParserException, IOException {
parser.nextTag();
parser.require(XmlPullParser.START_TAG, null, "familyset");
Expand Down Expand Up @@ -69,7 +75,7 @@ private void processDocumentFallback(XmlPullParser parser) throws XmlPullParserE

for (String file : filesets) {
for (String name : namesets) {
String fullFilename = "/system/fonts/" + file;
String fullFilename = systemFontPath + file;
String style = "normal";

// The file structure in `/etc/system_fonts.xml` is quite undescriptive
Expand Down Expand Up @@ -135,7 +141,14 @@ private void processDocument(XmlPullParser parser) throws XmlPullParserException
fallbackFontDict.put(weight, new Vector<String>());
}

fallbackFontDict.get(weight).add(filename);
// Don't use UI fonts
if (filename.indexOf("UI-") >= 0) {
continue;
}

String fullFileName = systemFontPath + filename;

fallbackFontDict.get(weight).add(fullFileName);
} else {
skip(parser);
}
Expand All @@ -156,10 +169,10 @@ private void processDocument(XmlPullParser parser) throws XmlPullParserException
styleStr = (styleStr == null) ? "normal" : styleStr;

String filename = parser.nextText();
String fullFilename = "/system/fonts/" + filename;
String fullFileName = systemFontPath + filename;

String key = name + "_" + weightStr + "_" + styleStr;
fontDict.put(key, fullFilename);
fontDict.put(key, fullFileName);
} else {
skip(parser);
}
Expand Down Expand Up @@ -208,11 +221,6 @@ private void skip(XmlPullParser parser) throws XmlPullParserException, IOExcepti
}

public void parse() {
// Android version >= 5.0
String fontXMLPath = "/system/etc/fonts.xml";
// Android version < 5.0
String fontXMLFallbackPath = "/etc/system_fonts.xml";

InputStream in = null;
boolean fallbackXML = false;
final File fontFile = new File(fontXMLPath);
Expand Down
2 changes: 2 additions & 0 deletions bench/src/tileLoading.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ struct TestContext {
}
SceneLoader::applyConfig(sceneNode, scene);

scene->fontContext()->loadFonts();

styleContext.initFunctions(*scene);
styleContext.setKeywordZoom(0);

Expand Down
3 changes: 3 additions & 0 deletions core/src/scene/sceneLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ bool SceneLoader::loadScene(std::shared_ptr<Scene> _scene) {
if ((root = sceneImporter.applySceneImports(_scene->path(), _scene->resourceRoot())) ) {
applyConfig(root, _scene);

// Load font resources
_scene->fontContext()->loadFonts();

return true;
}
return false;
Expand Down
151 changes: 72 additions & 79 deletions core/src/text/fontContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,98 +14,95 @@
#define FONT_JA "fonts/DroidSansJapanese.ttf"
#define FALLBACK "fonts/DroidSansFallback.ttf"

#if defined(PLATFORM_ANDROID)
#define ANDROID_FONT_PATH "/system/fonts/"
#endif
#define BASE_SIZE 16
#define STEP_SIZE 12
#define MAX_STEPS 3

#define SDF_WIDTH 6
#define BASE_SIZE 16
#define STEP_SIZE 12
#define MAX_STEPS 3
#define DEFAULT_BOLDNESS 400
#define SDF_WIDTH 6

#define MIN_LINE_WIDTH 4

// TODO: more flexibility on this
#define BUNDLE_FONT_PATH "fonts/"

namespace Tangram {

FontContext::FontContext() :
resourceLoad(0),
m_sdfRadius(SDF_WIDTH),
m_atlas(*this, GlyphTexture::size, m_sdfRadius),
m_batch(m_atlas, m_scratch) {
m_batch(m_atlas, m_scratch) {}

resourceLoad = 0;
void FontContext::loadFonts() {

// TODO: make this platform independent
#if defined(PLATFORM_ANDROID)
auto fontPath = systemFontPath("sans-serif", "400", "normal");
LOGD("FONT %s", fontPath.c_str());
// Load default fonts
{
std::string systemFont = systemFontPath("sans-serif", std::to_string(DEFAULT_BOLDNESS), "normal");

int size = BASE_SIZE;
for (int i = 0; i < MAX_STEPS; i++, size += STEP_SIZE) {
m_font[i] = m_alfons.addFont("default", alfons::InputSource(fontPath), size);
}
if (!systemFont.empty()) {
LOG("Adding default system font");

std::string fallback = "";
int importance = 0;
for (int i = 0, size = BASE_SIZE; i < MAX_STEPS; i++, size += STEP_SIZE) {
m_font[i] = m_alfons.addFont("default", alfons::InputSource(systemFont), size);
}
} else {
size_t dataSize;
char* data = reinterpret_cast<char*>(bytesFromFile(DEFAULT, dataSize));

while (importance < 100) {
fallback = systemFontFallbackPath(importance++, 400);
if (fallback.empty()) { break; }
if (data) {
LOG("Loading default font file %s", DEFAULT);

if (fallback.find("UI-") != std::string::npos) {
continue;
}
fontPath = ANDROID_FONT_PATH;
fontPath += fallback;
LOGD("FALLBACK %s", fontPath.c_str());
for (int i = 0, size = BASE_SIZE; i < MAX_STEPS; i++, size += STEP_SIZE) {
m_font[i] = m_alfons.addFont("default", alfons::InputSource(data, dataSize), size);
}

int size = BASE_SIZE;
for (int i = 0; i < MAX_STEPS; i++, size += STEP_SIZE) {
m_font[i]->addFace(m_alfons.addFontFace(alfons::InputSource(fontPath), size));
}
}
#elif defined(PLATFORM_IOS)

int size = BASE_SIZE;
auto loadFonts = [&](const char* path) {
size_t dataSize;
char* data = reinterpret_cast<char*>(bytesFromFile(path, dataSize));
if (data) {
for (int i = 0; i < MAX_STEPS; i++, size += STEP_SIZE) {
m_font[i] = m_alfons.addFont("default", alfons::InputSource(data, dataSize), size);
free(data);
} else {
LOGW("Default font %s not found", DEFAULT);
}
free(data);
}
};
auto addFaces = [&](const char* path) {
size_t dataSize;
char* data = reinterpret_cast<char*>(bytesFromFile(path, dataSize));
if (data) {
for (int i = 0; i < MAX_STEPS; i++, size += STEP_SIZE) {
m_font[i]->addFace(m_alfons.addFontFace(alfons::InputSource(data, dataSize), size));
}

// Treat fallback fonts
{
std::string fallback = "";
int importance = 0;
fallback = systemFontFallbackPath(importance++, DEFAULT_BOLDNESS);

if (fallback.empty()) {
LOGW("No system font fallback, loading bundled fonts");

auto addFaces = [&](const char* path) {
size_t dataSize;
char* data = reinterpret_cast<char*>(bytesFromFile(path, dataSize));

if (data) {
LOG("Adding bundled font at path %s", path);

for (int i = 0, size = BASE_SIZE; i < MAX_STEPS; i++, size += STEP_SIZE) {
m_font[i]->addFace(m_alfons.addFontFace(alfons::InputSource(data, dataSize), size));
}

free(data);
} else {
LOGW("Bundle font %s not found", path);
}
};

addFaces(FONT_AR);
addFaces(FONT_HE);
addFaces(FONT_JA);
addFaces(FALLBACK);
} else {
// Add fallback system fonts faces paths
while (!fallback.empty()) {
LOG("Font fallback at path %s", fallback.c_str());

for (int i = 0, size = BASE_SIZE; i < MAX_STEPS; i++, size += STEP_SIZE) {
m_font[i]->addFace(m_alfons.addFontFace(alfons::InputSource(fallback), size));
}

fallback = systemFontFallbackPath(importance++, DEFAULT_BOLDNESS);
}
free(data);
}
};

loadFonts(DEFAULT);
addFaces(FONT_AR);
addFaces(FONT_HE);
addFaces(FONT_JA);
addFaces(FALLBACK);

#else
int size = BASE_SIZE;
for (int i = 0; i < MAX_STEPS; i++, size += STEP_SIZE) {
m_font[i] = m_alfons.addFont("default", alfons::InputSource(DEFAULT), size);
m_font[i]->addFace(m_alfons.addFontFace(alfons::InputSource(FONT_AR), size));
m_font[i]->addFace(m_alfons.addFontFace(alfons::InputSource(FONT_HE), size));
m_font[i]->addFace(m_alfons.addFontFace(alfons::InputSource(FONT_JA), size));
m_font[i]->addFace(m_alfons.addFontFace(alfons::InputSource(FALLBACK), size));
}
#endif
}

// Synchronized on m_mutex in layoutText(), called on tile-worker threads
Expand Down Expand Up @@ -306,8 +303,7 @@ void FontContext::fetch(const FontDescription& _ft) {
std::lock_guard<std::mutex> lock(m_mutex);
char* data = reinterpret_cast<char*>(rawData.data());

int size = BASE_SIZE;
for (int i = 0; i < MAX_STEPS; i++, size += STEP_SIZE) {
for (int i = 0, size = BASE_SIZE; i < MAX_STEPS; i++, size += STEP_SIZE) {
auto font = m_alfons.getFont(_ft.alias, size);
font->addFace(m_alfons.addFontFace(alfons::InputSource(data, rawData.size()), size));
}
Expand All @@ -323,9 +319,7 @@ void FontContext::fetch(const FontDescription& _ft) {
if (loadFontAlloc(_ft.bundleAlias, data, dataSize)) {
const char* rdata = reinterpret_cast<const char*>(data);

int size = BASE_SIZE;

for (int i = 0; i < MAX_STEPS; i++, size += STEP_SIZE) {
for (int i = 0, size = BASE_SIZE; i < MAX_STEPS; i++, size += STEP_SIZE) {
auto font = m_alfons.getFont(_ft.alias, size);
font->addFace(m_alfons.addFontFace(alfons::InputSource(rdata, dataSize), size));
}
Expand Down Expand Up @@ -354,7 +348,6 @@ bool FontContext::loadFontAlloc(const std::string& _bundleFontPath, unsigned cha
return true;
}


return false;
}

Expand Down Expand Up @@ -394,7 +387,7 @@ std::shared_ptr<alfons::Font> FontContext::getFont(const std::string& _family, c
unsigned char* data = nullptr;

// Assuming bundled ttf file follows this convention
std::string bundleFontPath = BUNDLE_FONT_PATH + FontDescription::BundleAlias(_family, _weight, _style);
std::string bundleFontPath = m_bundlePath + FontDescription::BundleAlias(_family, _weight, _style);

if (!loadFontAlloc(bundleFontPath, data, dataSize)) {

Expand Down
6 changes: 6 additions & 0 deletions core/src/text/fontContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ class FontContext : public alfons::TextureCallback {

FontContext();

void loadFonts();

/* Synchronized on m_mutex on tile-worker threads
* Called from alfons when a texture atlas needs to be created
* Triggered from TextStyleBuilder::prepareLabel
Expand Down Expand Up @@ -116,6 +118,8 @@ class FontContext : public alfons::TextureCallback {

void setSceneResourceRoot(const std::string& sceneResourceRoot) { m_sceneResourceRoot = sceneResourceRoot; }

void setBundlePath(const std::string& _bundlePath) { m_bundlePath = _bundlePath; }

void fetch(const FontDescription& _ft);

std::atomic_ushort resourceLoad;
Expand Down Expand Up @@ -147,6 +151,8 @@ class FontContext : public alfons::TextureCallback {
TextWrapper m_textWrapper;
std::string m_sceneResourceRoot = "";

std::string m_bundlePath = "fonts/";

};

}

0 comments on commit 6b0e512

Please sign in to comment.