diff options
author | Chris Loer <chris.loer@gmail.com> | 2017-11-30 12:38:06 -0800 |
---|---|---|
committer | Chris Loer <chris.loer@gmail.com> | 2017-11-30 12:38:06 -0800 |
commit | 6f26d2ce4b78d9f52becf28fef275ef25f566cae (patch) | |
tree | ecc325f1c50a6142b9cc1bc354254df7fed61def | |
parent | ac8c89085f5e3585e96523f7ba1e183d62cdd2c7 (diff) | |
download | qtlocation-mapboxgl-6f26d2ce4b78d9f52becf28fef275ef25f566cae.tar.gz |
Initial implementation of local CJK glyph rendering on Android.
5 files changed, 137 insertions, 1 deletions
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/text/LocalGlyphRasterizer.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/text/LocalGlyphRasterizer.java new file mode 100644 index 0000000000..cb502c2725 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/text/LocalGlyphRasterizer.java @@ -0,0 +1,24 @@ +package com.mapbox.mapboxsdk.text; + +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Bitmap; +import android.graphics.Color; +import android.graphics.Typeface; + +public class LocalGlyphRasterizer { + + public static Bitmap drawGlyphBitmap(char glyphID) { + Bitmap bitmap = Bitmap.createBitmap(35, 35, Bitmap.Config.ARGB_8888); + + Paint paint = new Paint(); + paint.setTextSize(24); + paint.setTypeface(Typeface.create("Noto Sans", Typeface.NORMAL)); + + Canvas canvas = new Canvas(); + canvas.setBitmap(bitmap); + canvas.drawText(String.valueOf(glyphID), 0, 20, paint); + + return bitmap; + } +} diff --git a/platform/android/config.cmake b/platform/android/config.cmake index a915f1d93d..3ef1b8f830 100644 --- a/platform/android/config.cmake +++ b/platform/android/config.cmake @@ -37,11 +37,12 @@ macro(mbgl_platform_core) PRIVATE platform/android/src/timer.cpp # Misc + PRIVATE platform/android/src/text/local_glyph_rasterizer_impl.hpp + PRIVATE platform/android/src/text/local_glyph_rasterizer.cpp PRIVATE platform/android/src/logging_android.cpp 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/android/src/jni.cpp b/platform/android/src/jni.cpp index 63566e1772..354c7594c2 100755 --- a/platform/android/src/jni.cpp +++ b/platform/android/src/jni.cpp @@ -51,6 +51,7 @@ #include "style/light.hpp" #include "snapshotter/map_snapshotter.hpp" #include "snapshotter/map_snapshot.hpp" +#include "text/local_glyph_rasterizer_impl.hpp" namespace mbgl { namespace android { @@ -188,6 +189,9 @@ void registerNatives(JavaVM *vm) { // Snapshotter MapSnapshotter::registerNative(env); MapSnapshot::registerNative(env); + + // text + AndroidLocalGlyphRasterizer::registerNative(env); } } // namespace android diff --git a/platform/android/src/text/local_glyph_rasterizer.cpp b/platform/android/src/text/local_glyph_rasterizer.cpp new file mode 100644 index 0000000000..dd58ee2228 --- /dev/null +++ b/platform/android/src/text/local_glyph_rasterizer.cpp @@ -0,0 +1,84 @@ +#include <mbgl/text/local_glyph_rasterizer.hpp> +#include <mbgl/util/i18n.hpp> + +#include <jni/jni.hpp> + +#include "../attach_env.hpp" +#include "../bitmap.hpp" + +#include "local_glyph_rasterizer_impl.hpp" // Actually AndroidLocalGlyphRasterizer + +namespace mbgl { + +namespace android { + +PremultipliedImage AndroidLocalGlyphRasterizer::drawGlyphBitmap(const FontStack&, unsigned short glyphID, Size) { + UniqueEnv env { AttachEnv() }; // TODO: How should this be hooked up? + + // TODO: Pass in font stack and size (and configuration) + // For now, just try to hard-wire any rendering at all + using Signature = jni::Object<Bitmap>(jni::jchar); + auto method = javaClass.GetStaticMethod<Signature>(*env, "drawGlyphBitmap"); + auto result = javaClass.Call(*env, method, glyphID); + + return Bitmap::GetImage(*env, result); +} + +void AndroidLocalGlyphRasterizer::registerNative(jni::JNIEnv& env) { + javaClass = *jni::Class<AndroidLocalGlyphRasterizer>::Find(env).NewGlobalRef(env).release(); +} + +jni::Class<AndroidLocalGlyphRasterizer> AndroidLocalGlyphRasterizer::javaClass; + +} // namespace android + +class LocalGlyphRasterizer::Impl { +public: + bool hasFont(const FontStack&) const { + return true; + } + + PremultipliedImage drawGlyphBitmap(const FontStack& fontStack, GlyphID glyphID, Size size) { + return android::AndroidLocalGlyphRasterizer::drawGlyphBitmap(fontStack, (unsigned short)glyphID, size); + } +}; + +LocalGlyphRasterizer::LocalGlyphRasterizer(const optional<std::string>) + : impl(std::make_unique<Impl>()) +{} + +LocalGlyphRasterizer::~LocalGlyphRasterizer() +{} + +bool LocalGlyphRasterizer::canRasterizeGlyph(const FontStack& fontStack, GlyphID glyphID) { + return util::i18n::allowsFixedWidthGlyphGeneration(glyphID) && impl->hasFont(fontStack); +} + +Glyph LocalGlyphRasterizer::rasterizeGlyph(const FontStack& fontStack, GlyphID glyphID) { + Glyph fixedMetrics; + if (!impl->hasFont(fontStack)) { + return fixedMetrics; + } + + fixedMetrics.id = glyphID; + + Size size(35, 35); + + fixedMetrics.metrics.width = size.width; + fixedMetrics.metrics.height = size.height; + fixedMetrics.metrics.left = 3; + fixedMetrics.metrics.top = -10; + fixedMetrics.metrics.advance = 24; + + PremultipliedImage rgbaBitmap = impl->drawGlyphBitmap(fontStack, glyphID, size); + + // 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] = rgbaBitmap.data[4 * i + 3]; + } + + return fixedMetrics; +} + +} // namespace mbgl diff --git a/platform/android/src/text/local_glyph_rasterizer_impl.hpp b/platform/android/src/text/local_glyph_rasterizer_impl.hpp new file mode 100644 index 0000000000..2e14f87e34 --- /dev/null +++ b/platform/android/src/text/local_glyph_rasterizer_impl.hpp @@ -0,0 +1,23 @@ +#pragma once + +#include <mbgl/util/image.hpp> + +#include <jni/jni.hpp> + +namespace mbgl { +namespace android { + +class AndroidLocalGlyphRasterizer { +public: + static PremultipliedImage drawGlyphBitmap(const FontStack&, unsigned short glyphID, Size size); + + static constexpr auto Name() { return "com/mapbox/mapboxsdk/text/LocalGlyphRasterizer"; }; + + static jni::Class<AndroidLocalGlyphRasterizer> javaClass; + + static void registerNative(jni::JNIEnv&); + +}; + +} // namespace android +} // namespace mbgl |