Rename Gradle targets Android (#2226)
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
#include <mbgl/text/local_glyph_rasterizer.hpp>
|
||||
#include <mbgl/util/i18n.hpp>
|
||||
#include <mbgl/util/platform.hpp>
|
||||
|
||||
#include <jni/jni.hpp>
|
||||
|
||||
#include "attach_env.hpp"
|
||||
#include "bitmap.hpp"
|
||||
|
||||
#include "local_glyph_rasterizer_jni.hpp"
|
||||
|
||||
/*
|
||||
Android implementation of LocalGlyphRasterizer:
|
||||
Draws CJK glyphs using locally available fonts.
|
||||
|
||||
Follows pattern of GL JS implementation in that:
|
||||
- Only CJK glyphs are drawn locally (because we can guess their metrics effectively)
|
||||
* Render size/metrics determined experimentally using Noto Sans
|
||||
- Configuration is done at map creation time by setting a "font family"
|
||||
* JS uses a CSS font-family, this uses android.graphics.Typeface
|
||||
https://developer.android.com/reference/android/graphics/Typeface.html
|
||||
- We use heuristics to extract a font-weight based on the incoming font stack
|
||||
* JS tries to extract multiple weights, this implementation only looks for
|
||||
"bold"
|
||||
|
||||
mbgl::LocalGlyphRasterizer is the portable interface
|
||||
mbgl::LocalGlyphRasterizer::Impl stores platform-specific configuration data
|
||||
mbgl::android::LocalGlyphRasterizer is the JNI wrapper
|
||||
com.mapbox.mapboxsdk.text.LocalGlyphRasterizer is the Java implementation that
|
||||
actually does the drawing
|
||||
*/
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
LocalGlyphRasterizer::LocalGlyphRasterizer() {
|
||||
UniqueEnv env{AttachEnv()};
|
||||
|
||||
static auto& javaClass = jni::Class<LocalGlyphRasterizer>::Singleton(*env);
|
||||
static auto constructor = javaClass.GetConstructor(*env);
|
||||
|
||||
javaObject = jni::NewGlobal(*env, javaClass.New(*env, constructor));
|
||||
}
|
||||
|
||||
PremultipliedImage LocalGlyphRasterizer::drawGlyphBitmap(const std::string& fontFamily,
|
||||
const bool bold,
|
||||
const GlyphID glyphID) {
|
||||
UniqueEnv env{AttachEnv()};
|
||||
|
||||
static auto& javaClass = jni::Class<LocalGlyphRasterizer>::Singleton(*env);
|
||||
static auto drawGlyphBitmap = javaClass.GetMethod<jni::Object<Bitmap>(jni::String, jni::jboolean, jni::jchar)>(
|
||||
*env, "drawGlyphBitmap");
|
||||
|
||||
return Bitmap::GetImage(*env,
|
||||
javaObject.Call(*env,
|
||||
drawGlyphBitmap,
|
||||
jni::Make<jni::String>(*env, fontFamily),
|
||||
static_cast<jni::jboolean>(bold),
|
||||
static_cast<jni::jchar>(glyphID)));
|
||||
}
|
||||
|
||||
void LocalGlyphRasterizer::registerNative(jni::JNIEnv& env) {
|
||||
jni::Class<LocalGlyphRasterizer>::Singleton(env);
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
|
||||
class LocalGlyphRasterizer::Impl {
|
||||
public:
|
||||
Impl(const std::optional<std::string> fontFamily_)
|
||||
: fontFamily(fontFamily_) {}
|
||||
|
||||
bool isConfigured() const { return bool(fontFamily); }
|
||||
|
||||
PremultipliedImage drawGlyphBitmap(const FontStack& fontStack, GlyphID glyphID) {
|
||||
bool bold = false;
|
||||
for (auto font : fontStack) {
|
||||
std::string lowercaseFont = platform::lowercase(font);
|
||||
if (lowercaseFont.find("bold") != std::string::npos) {
|
||||
bold = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return androidLocalGlyphRasterizer.drawGlyphBitmap(*fontFamily, bold, glyphID);
|
||||
}
|
||||
|
||||
private:
|
||||
std::optional<std::string> fontFamily;
|
||||
android::LocalGlyphRasterizer androidLocalGlyphRasterizer;
|
||||
};
|
||||
|
||||
LocalGlyphRasterizer::LocalGlyphRasterizer(const std::optional<std::string>& fontFamily)
|
||||
: impl(std::make_unique<Impl>(fontFamily)) {}
|
||||
|
||||
LocalGlyphRasterizer::~LocalGlyphRasterizer() {}
|
||||
|
||||
bool LocalGlyphRasterizer::canRasterizeGlyph(const FontStack&, GlyphID glyphID) {
|
||||
return util::i18n::allowsFixedWidthGlyphGeneration(glyphID) && impl->isConfigured();
|
||||
}
|
||||
|
||||
Glyph LocalGlyphRasterizer::rasterizeGlyph(const FontStack& fontStack, GlyphID glyphID) {
|
||||
Glyph fixedMetrics;
|
||||
if (!impl->isConfigured()) {
|
||||
return fixedMetrics;
|
||||
}
|
||||
|
||||
fixedMetrics.id = glyphID;
|
||||
|
||||
Size size(35, 35);
|
||||
|
||||
fixedMetrics.metrics.width = size.width;
|
||||
fixedMetrics.metrics.height = size.height;
|
||||
fixedMetrics.metrics.left = -2;
|
||||
fixedMetrics.metrics.top = -5;
|
||||
fixedMetrics.metrics.advance = 24;
|
||||
|
||||
PremultipliedImage rgbaBitmap = impl->drawGlyphBitmap(fontStack, glyphID);
|
||||
|
||||
// Copy alpha values from RGBA bitmap into the AlphaImage output
|
||||
fixedMetrics.bitmap = AlphaImage(size);
|
||||
for (uint32_t i = 0; i < size.width * size.height; i++) {
|
||||
fixedMetrics.bitmap.data[i] = 0xff -
|
||||
round(0.2126 * rgbaBitmap.data[4 * i] + 0.7152 * rgbaBitmap.data[4 * i + 1] +
|
||||
0.0722 * rgbaBitmap.data[4 * i + 2]);
|
||||
}
|
||||
|
||||
return fixedMetrics;
|
||||
}
|
||||
|
||||
} // namespace mbgl
|
||||
@@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/util/image.hpp>
|
||||
|
||||
#include <jni/jni.hpp>
|
||||
|
||||
/*
|
||||
android::LocalGlyphRasterizer is the JNI wrapper of
|
||||
org/maplibre/android/text/LocalGlyphRasterizer
|
||||
|
||||
mbgl::LocalGlyphRasterizer is the portable interface
|
||||
Both implementations are in local_glyph_rasterizer.cpp
|
||||
*/
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
class LocalGlyphRasterizer {
|
||||
public:
|
||||
static constexpr auto Name() { return "org/maplibre/android/text/LocalGlyphRasterizer"; };
|
||||
|
||||
static void registerNative(jni::JNIEnv&);
|
||||
|
||||
LocalGlyphRasterizer();
|
||||
|
||||
PremultipliedImage drawGlyphBitmap(const std::string& fontFamily, const bool bold, const char16_t glyphID);
|
||||
|
||||
private:
|
||||
jni::Global<jni::Object<LocalGlyphRasterizer>> javaObject;
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
Reference in New Issue
Block a user