Fix compilation errors for Android run
This commit is contained in:
parent
537d80a27f
commit
b57ef8b0b5
11 changed files with 317 additions and 273 deletions
|
@ -1,4 +1,3 @@
|
|||
ANDROID_BUILD := true
|
||||
OSMAND_MAKEFILES := $(all-subdir-makefiles)
|
||||
|
||||
# By default, include makefiles only once
|
||||
|
|
|
@ -13,6 +13,7 @@ endif
|
|||
|
||||
LOCAL_CFLAGS := \
|
||||
-DGOOGLE_PROTOBUF_NO_RTTI \
|
||||
-DANDROID_BUILD \
|
||||
-DSK_BUILD_FOR_ANDROID \
|
||||
-DSK_BUILD_FOR_ANDROID_NDK \
|
||||
-DSK_ALLOW_STATIC_GLOBAL_INITIALIZERS=0 \
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#include <vector>
|
||||
#include <SkPath.h>
|
||||
#include <SkBitmap.h>
|
||||
#include <SkImageDecoder.h>
|
||||
#include <jni.h>
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
|
@ -12,198 +11,6 @@
|
|||
#include "osmand_log.h"
|
||||
|
||||
|
||||
JavaVM* globalJVM = NULL;
|
||||
// Forward declarations
|
||||
void loadJniCommon(JNIEnv* env);
|
||||
void loadJniRendering(JNIEnv* env);
|
||||
void loadJniRenderingRules(JNIEnv* env);
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
|
||||
{
|
||||
JNIEnv* globalJniEnv;
|
||||
if(vm->GetEnv((void **)&globalJniEnv, JNI_VERSION_1_6))
|
||||
return JNI_ERR; /* JNI version not supported */
|
||||
globalJVM = vm;
|
||||
|
||||
loadJniCommon(globalJniEnv);
|
||||
loadJniRendering(globalJniEnv);
|
||||
loadJniRenderingRules(globalJniEnv);
|
||||
osmand_log_print(LOG_INFO, "JNI_OnLoad completed");
|
||||
|
||||
return JNI_VERSION_1_6;
|
||||
}
|
||||
|
||||
void throwNewException(JNIEnv* env, const char* msg)
|
||||
{
|
||||
osmand_log_print(LOG_ERROR, msg);
|
||||
env->ThrowNew(env->FindClass("java/lang/Exception"), msg);
|
||||
}
|
||||
|
||||
jclass findClass(JNIEnv* env, const char* className, bool mustHave/* = true*/)
|
||||
{
|
||||
jclass javaClass = env->FindClass(className);
|
||||
if(!javaClass && mustHave)
|
||||
throwNewException(env, (std::string("Failed to find class ") + className).c_str());
|
||||
return (jclass)newGlobalRef(env, javaClass);
|
||||
}
|
||||
|
||||
jobject newGlobalRef(JNIEnv* env, jobject o)
|
||||
{
|
||||
return env->NewGlobalRef(o);
|
||||
}
|
||||
|
||||
jfieldID getFid(JNIEnv* env, jclass cls, const char* fieldName, const char* sig)
|
||||
{
|
||||
jfieldID jfield = env->GetFieldID(cls, fieldName, sig);
|
||||
if(!jfield)
|
||||
throwNewException(env, (std::string("Failed to find field ") + fieldName + std::string(" with signature ") + sig).c_str());
|
||||
return jfield;
|
||||
}
|
||||
|
||||
std::string getStringField(JNIEnv* env, jobject o, jfieldID fid)
|
||||
{
|
||||
jstring jstr = (jstring)env->GetObjectField(o, fid);
|
||||
if(!jstr)
|
||||
{
|
||||
throwNewException(env, "Failed to get object from field");
|
||||
return std::string();
|
||||
}
|
||||
const char* utfBytes = env->GetStringUTFChars(jstr, NULL);
|
||||
//TODO: I'm not quite sure that if real unicode will happen here, this will work as expected
|
||||
std::string result(utfBytes);
|
||||
env->ReleaseStringUTFChars(jstr, utfBytes);
|
||||
env->DeleteLocalRef(jstr);
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string getString(JNIEnv* env, jstring jstr)
|
||||
{
|
||||
if(!jstr)
|
||||
{
|
||||
throwNewException(env, "NULL jstring passed in");
|
||||
return std::string();
|
||||
}
|
||||
const char* utfBytes = env->GetStringUTFChars(jstr, NULL);
|
||||
//TODO: I'm not quite sure that if real unicode will happen here, this will work as expected
|
||||
std::string result(utfBytes);
|
||||
env->ReleaseStringUTFChars(jstr, utfBytes);
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string getStringMethod(JNIEnv* env, jobject o, jmethodID fid)
|
||||
{
|
||||
return getString(env, (jstring)env->CallObjectMethod(o, fid));
|
||||
}
|
||||
|
||||
std::string getStringMethod(JNIEnv* env, jobject o, jmethodID fid, int i)
|
||||
{
|
||||
return getString(env, (jstring)env->CallObjectMethod(o, fid, i));
|
||||
}
|
||||
|
||||
jclass jclass_RenderingContext = NULL;
|
||||
jfieldID jfield_RenderingContext_interrupted = NULL;
|
||||
jclass jclass_RenderingIcons = NULL;
|
||||
jmethodID jmethod_RenderingIcons_getIconRawData = NULL;
|
||||
jfieldID jfield_RenderingContext_leftX = NULL;
|
||||
jfieldID jfield_RenderingContext_topY = NULL;
|
||||
jfieldID jfield_RenderingContext_width = NULL;
|
||||
jfieldID jfield_RenderingContext_height = NULL;
|
||||
jfieldID jfield_RenderingContext_zoom = NULL;
|
||||
jfieldID jfield_RenderingContext_rotate = NULL;
|
||||
jfieldID jfield_RenderingContext_tileDivisor = NULL;
|
||||
jfieldID jfield_RenderingContext_pointCount = NULL;
|
||||
jfieldID jfield_RenderingContext_pointInsideCount = NULL;
|
||||
jfieldID jfield_RenderingContext_visible = NULL;
|
||||
jfieldID jfield_RenderingContext_allObjects = NULL;
|
||||
jfieldID jfield_RenderingContext_cosRotateTileSize = NULL;
|
||||
jfieldID jfield_RenderingContext_sinRotateTileSize = NULL;
|
||||
jfieldID jfield_RenderingContext_density = NULL;
|
||||
jfieldID jfield_RenderingContext_highResMode = NULL;
|
||||
jfieldID jfield_RenderingContext_mapTextSize = NULL;
|
||||
jfieldID jfield_RenderingContext_shadowRenderingMode = NULL;
|
||||
jfieldID jfield_RenderingContext_shadowLevelMin = NULL;
|
||||
jfieldID jfield_RenderingContext_shadowLevelMax = NULL;
|
||||
jfieldID jfield_RenderingContext_ctx = NULL;
|
||||
jfieldID jfield_RenderingContext_textRenderingTime = NULL;
|
||||
jfieldID jfield_RenderingContext_lastRenderedKey = NULL;
|
||||
|
||||
void loadJniCommon(JNIEnv* env)
|
||||
{
|
||||
jclass_RenderingContext = findClass(env, "net/osmand/plus/render/OsmandRenderer$RenderingContext");
|
||||
jfield_RenderingContext_interrupted = getFid(env, jclass_RenderingContext, "interrupted", "Z");
|
||||
jfield_RenderingContext_leftX = getFid(env, jclass_RenderingContext, "leftX", "F" );
|
||||
jfield_RenderingContext_topY = getFid(env, jclass_RenderingContext, "topY", "F" );
|
||||
jfield_RenderingContext_width = getFid(env, jclass_RenderingContext, "width", "I" );
|
||||
jfield_RenderingContext_height = getFid(env, jclass_RenderingContext, "height", "I" );
|
||||
jfield_RenderingContext_zoom = getFid(env, jclass_RenderingContext, "zoom", "I" );
|
||||
jfield_RenderingContext_rotate = getFid(env, jclass_RenderingContext, "rotate", "F" );
|
||||
jfield_RenderingContext_tileDivisor = getFid(env, jclass_RenderingContext, "tileDivisor", "F" );
|
||||
jfield_RenderingContext_pointCount = getFid(env, jclass_RenderingContext, "pointCount", "I" );
|
||||
jfield_RenderingContext_pointInsideCount = getFid(env, jclass_RenderingContext, "pointInsideCount", "I" );
|
||||
jfield_RenderingContext_visible = getFid(env, jclass_RenderingContext, "visible", "I" );
|
||||
jfield_RenderingContext_allObjects = getFid(env, jclass_RenderingContext, "allObjects", "I" );
|
||||
jfield_RenderingContext_cosRotateTileSize = getFid(env, jclass_RenderingContext, "cosRotateTileSize", "F" );
|
||||
jfield_RenderingContext_sinRotateTileSize = getFid(env, jclass_RenderingContext, "sinRotateTileSize", "F" );
|
||||
jfield_RenderingContext_density = getFid(env, jclass_RenderingContext, "density", "F" );
|
||||
jfield_RenderingContext_highResMode = getFid(env, jclass_RenderingContext, "highResMode", "Z" );
|
||||
jfield_RenderingContext_mapTextSize = getFid(env, jclass_RenderingContext, "mapTextSize", "F" );
|
||||
jfield_RenderingContext_shadowRenderingMode = getFid(env, jclass_RenderingContext, "shadowRenderingMode", "I" );
|
||||
jfield_RenderingContext_shadowLevelMin = getFid(env, jclass_RenderingContext, "shadowLevelMin", "I" );
|
||||
jfield_RenderingContext_shadowLevelMax = getFid(env, jclass_RenderingContext, "shadowLevelMax", "I" );
|
||||
jfield_RenderingContext_ctx = getFid(env, jclass_RenderingContext, "ctx", "Landroid/content/Context;" );
|
||||
jfield_RenderingContext_textRenderingTime = getFid(env, jclass_RenderingContext, "textRenderingTime", "I" );
|
||||
jfield_RenderingContext_lastRenderedKey = getFid(env, jclass_RenderingContext, "lastRenderedKey", "I" );
|
||||
|
||||
jclass_RenderingIcons = findClass(env, "net/osmand/plus/render/RenderingIcons");
|
||||
jmethod_RenderingIcons_getIconRawData = env->GetStaticMethodID(jclass_RenderingIcons,
|
||||
"getIconRawData",
|
||||
"(Landroid/content/Context;Ljava/lang/String;)[B");
|
||||
}
|
||||
|
||||
void pullFromJavaRenderingContext(JNIEnv* env, jobject jrc, RenderingContext* rc)
|
||||
{
|
||||
rc->env = env;
|
||||
rc->leftX = env->GetFloatField( jrc, jfield_RenderingContext_leftX );
|
||||
rc->topY = env->GetFloatField( jrc, jfield_RenderingContext_topY );
|
||||
rc->width = env->GetIntField( jrc, jfield_RenderingContext_width );
|
||||
rc->height = env->GetIntField( jrc, jfield_RenderingContext_height );
|
||||
|
||||
rc->zoom = env->GetIntField( jrc, jfield_RenderingContext_zoom );
|
||||
rc->rotate = env->GetFloatField( jrc, jfield_RenderingContext_rotate );
|
||||
rc->tileDivisor = env->GetFloatField( jrc, jfield_RenderingContext_tileDivisor );
|
||||
|
||||
rc->pointCount = env->GetIntField( jrc, jfield_RenderingContext_pointCount );
|
||||
rc->pointInsideCount = env->GetIntField( jrc, jfield_RenderingContext_pointInsideCount );
|
||||
rc->visible = env->GetIntField( jrc, jfield_RenderingContext_visible );
|
||||
rc->allObjects = env->GetIntField( jrc, jfield_RenderingContext_allObjects );
|
||||
|
||||
rc->cosRotateTileSize = env->GetFloatField( jrc, jfield_RenderingContext_cosRotateTileSize );
|
||||
rc->sinRotateTileSize = env->GetFloatField( jrc, jfield_RenderingContext_sinRotateTileSize );
|
||||
rc->density = env->GetFloatField( jrc, jfield_RenderingContext_density );
|
||||
rc->highResMode = env->GetBooleanField( jrc, jfield_RenderingContext_highResMode );
|
||||
rc->mapTextSize = env->GetFloatField( jrc, jfield_RenderingContext_mapTextSize );
|
||||
|
||||
rc->shadowRenderingMode = env->GetIntField( jrc, jfield_RenderingContext_shadowRenderingMode );
|
||||
rc->shadowLevelMin = env->GetIntField( jrc, jfield_RenderingContext_shadowLevelMin );
|
||||
rc->shadowLevelMax = env->GetIntField( jrc, jfield_RenderingContext_shadowLevelMax );
|
||||
rc->androidContext = env->GetObjectField(jrc, jfield_RenderingContext_ctx );
|
||||
rc->lastRenderedKey = 0;
|
||||
|
||||
rc->javaRenderingContext = jrc;
|
||||
}
|
||||
|
||||
|
||||
void pushToJavaRenderingContext(JNIEnv* env, jobject jrc, RenderingContext* rc)
|
||||
{
|
||||
env->SetIntField( jrc, jfield_RenderingContext_pointCount, (jint) rc->pointCount);
|
||||
env->SetIntField( jrc, jfield_RenderingContext_pointInsideCount, (jint)rc->pointInsideCount);
|
||||
env->SetIntField( jrc, jfield_RenderingContext_visible, (jint)rc->visible);
|
||||
env->SetIntField( jrc, jfield_RenderingContext_allObjects, rc->allObjects);
|
||||
env->SetIntField( jrc, jfield_RenderingContext_textRenderingTime, rc->textRendering.getElapsedTime());
|
||||
env->SetIntField( jrc, jfield_RenderingContext_lastRenderedKey, rc->lastRenderedKey);
|
||||
|
||||
env->DeleteLocalRef(rc->androidContext);
|
||||
}
|
||||
|
||||
TextDrawInfo::TextDrawInfo(std::string itext)
|
||||
: text(itext)
|
||||
|
@ -225,8 +32,6 @@ IconDrawInfo::IconDrawInfo()
|
|||
}
|
||||
|
||||
RenderingContext::RenderingContext()
|
||||
: javaRenderingContext(NULL)
|
||||
, androidContext(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -239,9 +44,11 @@ RenderingContext::~RenderingContext()
|
|||
|
||||
bool RenderingContext::interrupted()
|
||||
{
|
||||
return env->GetBooleanField(javaRenderingContext, jfield_RenderingContext_interrupted);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
float getDensityValue(RenderingContext* rc, float val)
|
||||
{
|
||||
if (rc->highResMode && rc->density > 1)
|
||||
|
@ -296,10 +103,15 @@ int ElapsedTimer::getElapsedTime()
|
|||
return elapsedTime / 1e6;
|
||||
}
|
||||
|
||||
SkBitmap* RenderingContext::getCachedBitmap(const std::string& bitmapResource) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
HMAP::hash_map<std::string, SkBitmap*> cachedBitmaps;
|
||||
SkBitmap* getCachedBitmap(RenderingContext* rc, const std::string& bitmapResource)
|
||||
{
|
||||
JNIEnv* env = rc->env;
|
||||
|
||||
if(bitmapResource.size() == 0)
|
||||
return NULL;
|
||||
|
||||
|
@ -309,43 +121,18 @@ SkBitmap* getCachedBitmap(RenderingContext* rc, const std::string& bitmapResourc
|
|||
return itPreviouslyCachedBitmap->second;
|
||||
|
||||
rc->nativeOperations.pause();
|
||||
|
||||
jstring jstr = env->NewStringUTF(bitmapResource.c_str());
|
||||
jbyteArray javaIconRawData = (jbyteArray)env->CallStaticObjectMethod(jclass_RenderingIcons, jmethod_RenderingIcons_getIconRawData, rc->androidContext, jstr);
|
||||
if(!javaIconRawData)
|
||||
return NULL;
|
||||
|
||||
jbyte* bitmapBuffer = env->GetByteArrayElements(javaIconRawData, NULL);
|
||||
jint bufferLen = env->GetArrayLength(javaIconRawData);
|
||||
|
||||
// Decode bitmap
|
||||
SkBitmap* iconBitmap = new SkBitmap();
|
||||
//TODO: JPEG is badly supported! At the moment it needs sdcard to be present (sic). Patch that
|
||||
if(!SkImageDecoder::DecodeMemory(bitmapBuffer, bufferLen, iconBitmap))
|
||||
{
|
||||
// Failed to decode
|
||||
delete iconBitmap;
|
||||
|
||||
rc->nativeOperations.start();
|
||||
env->ReleaseByteArrayElements(javaIconRawData, bitmapBuffer, JNI_ABORT);
|
||||
env->DeleteLocalRef(javaIconRawData);
|
||||
env->DeleteLocalRef(jstr);
|
||||
|
||||
throwNewException(env, (std::string("Failed to decode ") + bitmapResource).c_str());
|
||||
|
||||
return NULL;
|
||||
}
|
||||
SkBitmap* iconBitmap = rc->getCachedBitmap(bitmapResource);
|
||||
cachedBitmaps[bitmapResource] = iconBitmap;
|
||||
|
||||
rc->nativeOperations.start();
|
||||
|
||||
env->ReleaseByteArrayElements(javaIconRawData, bitmapBuffer, JNI_ABORT);
|
||||
env->DeleteLocalRef(javaIconRawData);
|
||||
env->DeleteLocalRef(jstr);
|
||||
|
||||
return iconBitmap;
|
||||
}
|
||||
|
||||
std::string RenderingContext::getTranslatedString(const std::string& src) {
|
||||
return src;
|
||||
}
|
||||
|
||||
|
||||
inline double getPowZoom(float zoom){
|
||||
if(zoom >= 0 && zoom - floor(zoom) < 0.05f){
|
||||
return 1 << ((int)zoom);
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#ifndef _OSMAND_COMMON_H
|
||||
#define _OSMAND_COMMON_H
|
||||
|
||||
#include <jni.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
@ -83,19 +82,6 @@ using namespace std;
|
|||
struct RenderingContext;
|
||||
|
||||
|
||||
// JNI Helpers
|
||||
void throwNewException(JNIEnv* env, const char* msg);
|
||||
jclass findClass(JNIEnv* env, const char* className, bool mustHave = true);
|
||||
std::string getString(JNIEnv* env, jstring st);
|
||||
std::string getStringMethod(JNIEnv* env, jobject o, jmethodID fid, int i);
|
||||
std::string getStringMethod(JNIEnv* env, jobject o, jmethodID fid);
|
||||
std::string getStringField(JNIEnv* env, jobject o, jfieldID fid);
|
||||
jobject newGlobalRef(JNIEnv* env, jobject o);
|
||||
jfieldID getFid(JNIEnv* env, jclass cls, const char* fieldName, const char* sig);
|
||||
|
||||
void pullFromJavaRenderingContext(JNIEnv* env, jobject jrc, RenderingContext* rc);
|
||||
void pushToJavaRenderingContext(JNIEnv* env, jobject jrc, RenderingContext* rc);
|
||||
|
||||
class ElapsedTimer
|
||||
{
|
||||
private:
|
||||
|
@ -155,13 +141,11 @@ struct IconDrawInfo
|
|||
struct RenderingContext
|
||||
{
|
||||
RenderingContext();
|
||||
~RenderingContext();
|
||||
bool interrupted();
|
||||
virtual ~RenderingContext();
|
||||
|
||||
jobject javaRenderingContext;
|
||||
|
||||
jobject androidContext;
|
||||
JNIEnv* env;
|
||||
virtual bool interrupted();
|
||||
virtual SkBitmap* getCachedBitmap(const std::string& bitmapResource);
|
||||
virtual std::string getTranslatedString(const std::string& src);
|
||||
bool useEnglishNames;
|
||||
|
||||
std::vector<TextDrawInfo*> textToDraw;
|
||||
|
@ -200,6 +184,7 @@ struct RenderingContext
|
|||
// not expect any shadow
|
||||
int shadowLevelMin;
|
||||
int shadowLevelMax;
|
||||
|
||||
};
|
||||
|
||||
float getDensityValue(RenderingContext* rc, float val);
|
||||
|
|
5
Osmand-kernel/osmand/src/java_common_wrap.h
Normal file
5
Osmand-kernel/osmand/src/java_common_wrap.h
Normal file
|
@ -0,0 +1,5 @@
|
|||
#ifndef _JAVA_COMMON_WRAP_CPP
|
||||
#define _JAVA_COMMON_WRAP_CPP
|
||||
|
||||
|
||||
#endif
|
|
@ -5,8 +5,29 @@
|
|||
#include "java_wrap.h"
|
||||
#include "binaryRead.h"
|
||||
#include "rendering.h"
|
||||
#include <dlfcn.h>
|
||||
#include <SkBitmap.h>
|
||||
#include <SkCanvas.h>
|
||||
#include <SkImageDecoder.h>
|
||||
|
||||
JavaVM* globalJVM = NULL;
|
||||
// Forward declarations
|
||||
void loadJniCommon(JNIEnv* env);
|
||||
void loadJniRenderingRules(JNIEnv* env);
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
|
||||
{
|
||||
JNIEnv* globalJniEnv;
|
||||
if(vm->GetEnv((void **)&globalJniEnv, JNI_VERSION_1_6))
|
||||
return JNI_ERR; /* JNI version not supported */
|
||||
globalJVM = vm;
|
||||
|
||||
loadJniCommon(globalJniEnv);
|
||||
loadJniRenderingRules(globalJniEnv);
|
||||
osmand_log_print(LOG_INFO, "JNI_OnLoad completed");
|
||||
|
||||
return JNI_VERSION_1_6;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL Java_net_osmand_plus_render_NativeOsmandLibrary_deleteSearchResult(JNIEnv* ienv,
|
||||
jobject obj, jint searchResult) {
|
||||
|
@ -128,7 +149,7 @@ extern "C" JNIEXPORT jobject JNICALL Java_net_osmand_plus_render_NativeOsmandLib
|
|||
initObjects.start();
|
||||
|
||||
RenderingRuleSearchRequest* req = initSearchRequest(ienv, renderingRuleSearchRequest);
|
||||
RenderingContext rc;
|
||||
JNIRenderingContext rc;
|
||||
pullFromJavaRenderingContext(ienv, renderingContext, &rc);
|
||||
rc.useEnglishNames = useEnglishNames;
|
||||
ResultPublisher* result = ((ResultPublisher*) searchResult);
|
||||
|
@ -214,7 +235,7 @@ extern "C" JNIEXPORT jobject JNICALL Java_net_osmand_plus_render_NativeOsmandLib
|
|||
initObjects.start();
|
||||
|
||||
RenderingRuleSearchRequest* req = initSearchRequest(ienv, renderingRuleSearchRequest);
|
||||
RenderingContext rc;
|
||||
JNIRenderingContext rc;
|
||||
pullFromJavaRenderingContext(ienv, renderingContext, &rc);
|
||||
rc.useEnglishNames = useEnglishNames;
|
||||
ResultPublisher* result = ((ResultPublisher*) searchResult);
|
||||
|
@ -254,3 +275,166 @@ extern "C" JNIEXPORT jobject JNICALL Java_net_osmand_plus_render_NativeOsmandLib
|
|||
|
||||
return resultObject;
|
||||
}
|
||||
|
||||
|
||||
jclass jclass_JUnidecode;
|
||||
jmethodID jmethod_JUnidecode_unidecode;
|
||||
jclass jclass_RenderingContext = NULL;
|
||||
jfieldID jfield_RenderingContext_interrupted = NULL;
|
||||
jclass jclass_RenderingIcons = NULL;
|
||||
jmethodID jmethod_RenderingIcons_getIconRawData = NULL;
|
||||
jfieldID jfield_RenderingContext_leftX = NULL;
|
||||
jfieldID jfield_RenderingContext_topY = NULL;
|
||||
jfieldID jfield_RenderingContext_width = NULL;
|
||||
jfieldID jfield_RenderingContext_height = NULL;
|
||||
jfieldID jfield_RenderingContext_zoom = NULL;
|
||||
jfieldID jfield_RenderingContext_rotate = NULL;
|
||||
jfieldID jfield_RenderingContext_tileDivisor = NULL;
|
||||
jfieldID jfield_RenderingContext_pointCount = NULL;
|
||||
jfieldID jfield_RenderingContext_pointInsideCount = NULL;
|
||||
jfieldID jfield_RenderingContext_visible = NULL;
|
||||
jfieldID jfield_RenderingContext_allObjects = NULL;
|
||||
jfieldID jfield_RenderingContext_cosRotateTileSize = NULL;
|
||||
jfieldID jfield_RenderingContext_sinRotateTileSize = NULL;
|
||||
jfieldID jfield_RenderingContext_density = NULL;
|
||||
jfieldID jfield_RenderingContext_highResMode = NULL;
|
||||
jfieldID jfield_RenderingContext_mapTextSize = NULL;
|
||||
jfieldID jfield_RenderingContext_shadowRenderingMode = NULL;
|
||||
jfieldID jfield_RenderingContext_shadowLevelMin = NULL;
|
||||
jfieldID jfield_RenderingContext_shadowLevelMax = NULL;
|
||||
jfieldID jfield_RenderingContext_ctx = NULL;
|
||||
jfieldID jfield_RenderingContext_textRenderingTime = NULL;
|
||||
jfieldID jfield_RenderingContext_lastRenderedKey = NULL;
|
||||
|
||||
void loadJniCommon(JNIEnv* env)
|
||||
{
|
||||
jclass_RenderingContext = findClass(env, "net/osmand/plus/render/OsmandRenderer$RenderingContext");
|
||||
jfield_RenderingContext_interrupted = getFid(env, jclass_RenderingContext, "interrupted", "Z");
|
||||
jfield_RenderingContext_leftX = getFid(env, jclass_RenderingContext, "leftX", "F" );
|
||||
jfield_RenderingContext_topY = getFid(env, jclass_RenderingContext, "topY", "F" );
|
||||
jfield_RenderingContext_width = getFid(env, jclass_RenderingContext, "width", "I" );
|
||||
jfield_RenderingContext_height = getFid(env, jclass_RenderingContext, "height", "I" );
|
||||
jfield_RenderingContext_zoom = getFid(env, jclass_RenderingContext, "zoom", "I" );
|
||||
jfield_RenderingContext_rotate = getFid(env, jclass_RenderingContext, "rotate", "F" );
|
||||
jfield_RenderingContext_tileDivisor = getFid(env, jclass_RenderingContext, "tileDivisor", "F" );
|
||||
jfield_RenderingContext_pointCount = getFid(env, jclass_RenderingContext, "pointCount", "I" );
|
||||
jfield_RenderingContext_pointInsideCount = getFid(env, jclass_RenderingContext, "pointInsideCount", "I" );
|
||||
jfield_RenderingContext_visible = getFid(env, jclass_RenderingContext, "visible", "I" );
|
||||
jfield_RenderingContext_allObjects = getFid(env, jclass_RenderingContext, "allObjects", "I" );
|
||||
jfield_RenderingContext_cosRotateTileSize = getFid(env, jclass_RenderingContext, "cosRotateTileSize", "F" );
|
||||
jfield_RenderingContext_sinRotateTileSize = getFid(env, jclass_RenderingContext, "sinRotateTileSize", "F" );
|
||||
jfield_RenderingContext_density = getFid(env, jclass_RenderingContext, "density", "F" );
|
||||
jfield_RenderingContext_highResMode = getFid(env, jclass_RenderingContext, "highResMode", "Z" );
|
||||
jfield_RenderingContext_mapTextSize = getFid(env, jclass_RenderingContext, "mapTextSize", "F" );
|
||||
jfield_RenderingContext_shadowRenderingMode = getFid(env, jclass_RenderingContext, "shadowRenderingMode", "I" );
|
||||
jfield_RenderingContext_shadowLevelMin = getFid(env, jclass_RenderingContext, "shadowLevelMin", "I" );
|
||||
jfield_RenderingContext_shadowLevelMax = getFid(env, jclass_RenderingContext, "shadowLevelMax", "I" );
|
||||
jfield_RenderingContext_ctx = getFid(env, jclass_RenderingContext, "ctx", "Landroid/content/Context;" );
|
||||
jfield_RenderingContext_textRenderingTime = getFid(env, jclass_RenderingContext, "textRenderingTime", "I" );
|
||||
jfield_RenderingContext_lastRenderedKey = getFid(env, jclass_RenderingContext, "lastRenderedKey", "I" );
|
||||
|
||||
jclass_RenderingIcons = findClass(env, "net/osmand/plus/render/RenderingIcons");
|
||||
jmethod_RenderingIcons_getIconRawData = env->GetStaticMethodID(jclass_RenderingIcons,
|
||||
"getIconRawData",
|
||||
"(Landroid/content/Context;Ljava/lang/String;)[B");
|
||||
|
||||
jclass_JUnidecode = findClass(env, "net/sf/junidecode/Junidecode");
|
||||
jmethod_JUnidecode_unidecode = env->GetStaticMethodID(jclass_JUnidecode, "unidecode", "(Ljava/lang/String;)Ljava/lang/String;");
|
||||
}
|
||||
|
||||
void pullFromJavaRenderingContext(JNIEnv* env, jobject jrc, JNIRenderingContext* rc)
|
||||
{
|
||||
rc->env = env;
|
||||
rc->leftX = env->GetFloatField( jrc, jfield_RenderingContext_leftX );
|
||||
rc->topY = env->GetFloatField( jrc, jfield_RenderingContext_topY );
|
||||
rc->width = env->GetIntField( jrc, jfield_RenderingContext_width );
|
||||
rc->height = env->GetIntField( jrc, jfield_RenderingContext_height );
|
||||
|
||||
rc->zoom = env->GetIntField( jrc, jfield_RenderingContext_zoom );
|
||||
rc->rotate = env->GetFloatField( jrc, jfield_RenderingContext_rotate );
|
||||
rc->tileDivisor = env->GetFloatField( jrc, jfield_RenderingContext_tileDivisor );
|
||||
|
||||
rc->pointCount = env->GetIntField( jrc, jfield_RenderingContext_pointCount );
|
||||
rc->pointInsideCount = env->GetIntField( jrc, jfield_RenderingContext_pointInsideCount );
|
||||
rc->visible = env->GetIntField( jrc, jfield_RenderingContext_visible );
|
||||
rc->allObjects = env->GetIntField( jrc, jfield_RenderingContext_allObjects );
|
||||
|
||||
rc->cosRotateTileSize = env->GetFloatField( jrc, jfield_RenderingContext_cosRotateTileSize );
|
||||
rc->sinRotateTileSize = env->GetFloatField( jrc, jfield_RenderingContext_sinRotateTileSize );
|
||||
rc->density = env->GetFloatField( jrc, jfield_RenderingContext_density );
|
||||
rc->highResMode = env->GetBooleanField( jrc, jfield_RenderingContext_highResMode );
|
||||
rc->mapTextSize = env->GetFloatField( jrc, jfield_RenderingContext_mapTextSize );
|
||||
|
||||
rc->shadowRenderingMode = env->GetIntField( jrc, jfield_RenderingContext_shadowRenderingMode );
|
||||
rc->shadowLevelMin = env->GetIntField( jrc, jfield_RenderingContext_shadowLevelMin );
|
||||
rc->shadowLevelMax = env->GetIntField( jrc, jfield_RenderingContext_shadowLevelMax );
|
||||
rc->androidContext = env->GetObjectField(jrc, jfield_RenderingContext_ctx );
|
||||
rc->lastRenderedKey = 0;
|
||||
|
||||
rc->javaRenderingContext = jrc;
|
||||
}
|
||||
|
||||
|
||||
void pushToJavaRenderingContext(JNIEnv* env, jobject jrc, JNIRenderingContext* rc)
|
||||
{
|
||||
env->SetIntField( jrc, jfield_RenderingContext_pointCount, (jint) rc->pointCount);
|
||||
env->SetIntField( jrc, jfield_RenderingContext_pointInsideCount, (jint)rc->pointInsideCount);
|
||||
env->SetIntField( jrc, jfield_RenderingContext_visible, (jint)rc->visible);
|
||||
env->SetIntField( jrc, jfield_RenderingContext_allObjects, rc->allObjects);
|
||||
env->SetIntField( jrc, jfield_RenderingContext_textRenderingTime, rc->textRendering.getElapsedTime());
|
||||
env->SetIntField( jrc, jfield_RenderingContext_lastRenderedKey, rc->lastRenderedKey);
|
||||
|
||||
env->DeleteLocalRef(rc->androidContext);
|
||||
}
|
||||
|
||||
bool JNIRenderingContext::interrupted()
|
||||
{
|
||||
return env->GetBooleanField(javaRenderingContext, jfield_RenderingContext_interrupted);
|
||||
}
|
||||
|
||||
SkBitmap* JNIRenderingContext::getCachedBitmap(const std::string& bitmapResource) {
|
||||
JNIEnv* env = this->env;
|
||||
jstring jstr = env->NewStringUTF(bitmapResource.c_str());
|
||||
jbyteArray javaIconRawData = (jbyteArray)env->CallStaticObjectMethod(jclass_RenderingIcons, jmethod_RenderingIcons_getIconRawData, this->androidContext, jstr);
|
||||
if(!javaIconRawData)
|
||||
return NULL;
|
||||
|
||||
jbyte* bitmapBuffer = env->GetByteArrayElements(javaIconRawData, NULL);
|
||||
jint bufferLen = env->GetArrayLength(javaIconRawData);
|
||||
|
||||
// Decode bitmap
|
||||
SkBitmap* iconBitmap = new SkBitmap();
|
||||
//TODO: JPEG is badly supported! At the moment it needs sdcard to be present (sic). Patch that
|
||||
if(!SkImageDecoder::DecodeMemory(bitmapBuffer, bufferLen, iconBitmap))
|
||||
{
|
||||
// Failed to decode
|
||||
delete iconBitmap;
|
||||
|
||||
this->nativeOperations.start();
|
||||
env->ReleaseByteArrayElements(javaIconRawData, bitmapBuffer, JNI_ABORT);
|
||||
env->DeleteLocalRef(javaIconRawData);
|
||||
env->DeleteLocalRef(jstr);
|
||||
|
||||
throwNewException(env, (std::string("Failed to decode ") + bitmapResource).c_str());
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
env->ReleaseByteArrayElements(javaIconRawData, bitmapBuffer, JNI_ABORT);
|
||||
env->DeleteLocalRef(javaIconRawData);
|
||||
env->DeleteLocalRef(jstr);
|
||||
|
||||
return iconBitmap;
|
||||
}
|
||||
|
||||
std::string JNIRenderingContext::getTranslatedString(const std::string& name) {
|
||||
if (this->useEnglishNames) {
|
||||
jstring n = this->env->NewStringUTF(name.c_str());
|
||||
std::string res = getString(this->env,
|
||||
(jstring) this->env->CallStaticObjectMethod(jclass_JUnidecode, jmethod_JUnidecode_unidecode, n));
|
||||
this->env->DeleteLocalRef(n);
|
||||
return res;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,4 +21,89 @@ struct ResultJNIPublisher : ResultPublisher {
|
|||
}
|
||||
};
|
||||
|
||||
struct JNIRenderingContext : RenderingContext
|
||||
{
|
||||
jobject javaRenderingContext;
|
||||
jobject androidContext;
|
||||
JNIEnv* env;
|
||||
JNIRenderingContext() : javaRenderingContext(NULL), androidContext(NULL) {
|
||||
}
|
||||
|
||||
virtual SkBitmap* getCachedBitmap(const std::string& bitmapResource);
|
||||
virtual std::string getTranslatedString(const std::string& src);
|
||||
virtual bool interrupted();
|
||||
virtual ~JNIRenderingContext(){}
|
||||
};
|
||||
|
||||
void pullFromJavaRenderingContext(JNIEnv* env, jobject jrc, JNIRenderingContext* rc);
|
||||
void pushToJavaRenderingContext(JNIEnv* env, jobject jrc, JNIRenderingContext* rc);
|
||||
|
||||
jobject newGlobalRef(JNIEnv* env, jobject o)
|
||||
{
|
||||
return env->NewGlobalRef(o);
|
||||
}
|
||||
|
||||
void throwNewException(JNIEnv* env, const char* msg)
|
||||
{
|
||||
osmand_log_print(LOG_ERROR, msg);
|
||||
env->ThrowNew(env->FindClass("java/lang/Exception"), msg);
|
||||
}
|
||||
|
||||
jclass findClass(JNIEnv* env, const char* className, bool mustHave = true)
|
||||
{
|
||||
jclass javaClass = env->FindClass(className);
|
||||
if(!javaClass && mustHave)
|
||||
throwNewException(env, (std::string("Failed to find class ") + className).c_str());
|
||||
return (jclass)newGlobalRef(env, javaClass);
|
||||
}
|
||||
|
||||
|
||||
jfieldID getFid(JNIEnv* env, jclass cls, const char* fieldName, const char* sig)
|
||||
{
|
||||
jfieldID jfield = env->GetFieldID(cls, fieldName, sig);
|
||||
if(!jfield)
|
||||
throwNewException(env, (std::string("Failed to find field ") + fieldName + std::string(" with signature ") + sig).c_str());
|
||||
return jfield;
|
||||
}
|
||||
|
||||
std::string getStringField(JNIEnv* env, jobject o, jfieldID fid)
|
||||
{
|
||||
jstring jstr = (jstring)env->GetObjectField(o, fid);
|
||||
if(!jstr)
|
||||
{
|
||||
throwNewException(env, "Failed to get object from field");
|
||||
return std::string();
|
||||
}
|
||||
const char* utfBytes = env->GetStringUTFChars(jstr, NULL);
|
||||
//TODO: I'm not quite sure that if real unicode will happen here, this will work as expected
|
||||
std::string result(utfBytes);
|
||||
env->ReleaseStringUTFChars(jstr, utfBytes);
|
||||
env->DeleteLocalRef(jstr);
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string getString(JNIEnv* env, jstring jstr)
|
||||
{
|
||||
if(!jstr)
|
||||
{
|
||||
throwNewException(env, "NULL jstring passed in");
|
||||
return std::string();
|
||||
}
|
||||
const char* utfBytes = env->GetStringUTFChars(jstr, NULL);
|
||||
//TODO: I'm not quite sure that if real unicode will happen here, this will work as expected
|
||||
std::string result(utfBytes);
|
||||
env->ReleaseStringUTFChars(jstr, utfBytes);
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string getStringMethod(JNIEnv* env, jobject o, jmethodID fid)
|
||||
{
|
||||
return getString(env, (jstring)env->CallObjectMethod(o, fid));
|
||||
}
|
||||
|
||||
std::string getStringMethod(JNIEnv* env, jobject o, jmethodID fid, int i)
|
||||
{
|
||||
return getString(env, (jstring)env->CallObjectMethod(o, fid, i));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,19 +1,23 @@
|
|||
#ifndef _OSMAND_LOG_CPP
|
||||
#define _OSMAND_LOG_CPP
|
||||
#include "osmand_log.h"
|
||||
|
||||
|
||||
#ifdef ANDROID_BUILD
|
||||
#include <android/log.h>
|
||||
|
||||
const char* const LOG_TAG = "net.osmand:native";
|
||||
void osmand_log_print(int type, const char* msg) {
|
||||
void osmand_log_print(int type, const char* msg, ...) {
|
||||
va_list args;
|
||||
va_start( args, msg);
|
||||
if(type == LOG_ERROR) {
|
||||
__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, msg);
|
||||
__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, msg, args);
|
||||
} else if(type == LOG_INFO) {
|
||||
__android_log_print(ANDROID_LOG_INFO, LOG_TAG, msg);
|
||||
__android_log_print(ANDROID_LOG_INFO, LOG_TAG, msg, args);
|
||||
} else {
|
||||
__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, msg);
|
||||
__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, msg, args);
|
||||
}
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -43,6 +43,16 @@ jfieldID RenderingRuleSearchRequest_fvalues;
|
|||
jfieldID RenderingRuleSearchRequest_savedValues;
|
||||
jfieldID RenderingRuleSearchRequest_savedFvalues;
|
||||
|
||||
/// TODO Forward declaration
|
||||
jobject newGlobalRef(JNIEnv* env, jobject o);
|
||||
void throwNewException(JNIEnv* env, const char* msg);
|
||||
jfieldID getFid(JNIEnv* env, jclass cls, const char* fieldName, const char* sig);
|
||||
std::string getStringField(JNIEnv* env, jobject o, jfieldID fid);
|
||||
jclass findClass(JNIEnv* env, const char* className, bool mustHave = true);
|
||||
|
||||
|
||||
|
||||
|
||||
int RenderingRulesStorage::getPropertiesSize() {
|
||||
return properties.size();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#include <jni.h>
|
||||
#include "osmand_log.h"
|
||||
#include <dlfcn.h>
|
||||
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
@ -27,8 +26,6 @@
|
|||
#include "textdraw.cpp"
|
||||
#include "mapObjects.h"
|
||||
|
||||
jclass jclass_JUnidecode;
|
||||
jmethodID jmethod_JUnidecode_unidecode;
|
||||
|
||||
void calcPoint(std::pair<int, int> c, RenderingContext* rc)
|
||||
{
|
||||
|
@ -189,13 +186,7 @@ void renderText(MapDataObject* obj, RenderingRuleSearchRequest* req, RenderingCo
|
|||
while (it != obj->objectNames.end()) {
|
||||
if (it->second.length() > 0) {
|
||||
std::string name = it->second;
|
||||
if (rc->useEnglishNames) {
|
||||
jstring n = rc->env->NewStringUTF(name.c_str());
|
||||
name = getString(rc->env,
|
||||
(jstring) rc->env->CallStaticObjectMethod(jclass_JUnidecode,
|
||||
jmethod_JUnidecode_unidecode, n));
|
||||
rc->env->DeleteLocalRef(n);
|
||||
}
|
||||
name =rc->getTranslatedString(name);
|
||||
req->setInitialTagValueZoom(tag, value, rc->zoom, obj);
|
||||
req->setIntFilter(req->props()->R_TEXT_LENGTH, name.length());
|
||||
std::string tagName = it->first == "name" ? "" : it->first;
|
||||
|
@ -602,9 +593,3 @@ void doRendering(std::vector <MapDataObject* > mapDataObjects, SkCanvas* canvas,
|
|||
delete paint;
|
||||
rc->nativeOperations.pause();
|
||||
}
|
||||
|
||||
void loadJniRendering(JNIEnv* env)
|
||||
{
|
||||
jclass_JUnidecode = findClass(env, "net/sf/junidecode/Junidecode");
|
||||
jmethod_JUnidecode_unidecode = env->GetStaticMethodID(jclass_JUnidecode, "unidecode", "(Ljava/lang/String;)Ljava/lang/String;");
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
#include <algorithm>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
#include <jni.h>
|
||||
#include "SkTypes.h"
|
||||
#include "SkTypeface.h"
|
||||
#include "SkCanvas.h"
|
||||
|
|
Loading…
Reference in a new issue