Initial part of native rendering improvement. Will not render icons, introduces only stability

This commit is contained in:
Alexey Pelykh 2012-03-02 18:24:06 +02:00
parent 8160cc5e5b
commit 8153fb8f70
21 changed files with 1377 additions and 1237 deletions

18
.gitmodules vendored Normal file
View file

@ -0,0 +1,18 @@
[submodule "OsmAnd/jni/jpeg/jpeg_library"]
path = OsmAnd/jni/jpeg/jpeg_library
url = https://android.googlesource.com/platform/external/jpeg.git
[submodule "OsmAnd/jni/skia/skia_library"]
path = OsmAnd/jni/skia/skia_library
url = https://android.googlesource.com/platform/external/skia.git
[submodule "OsmAnd/jni/png/png_library"]
path = OsmAnd/jni/png/png_library
url = https://android.googlesource.com/platform/external/libpng.git
[submodule "OsmAnd/jni/freetype/freetype_library"]
path = OsmAnd/jni/freetype/freetype_library
url = https://android.googlesource.com/platform/external/freetype.git
[submodule "OsmAnd/jni/expat/expat_library"]
path = OsmAnd/jni/expat/expat_library
url = https://android.googlesource.com/platform/external/expat.git
[submodule "OsmAnd/jni/gif/gif_library"]
path = OsmAnd/jni/gif/gif_library
url = https://android.googlesource.com/platform/external/giflib.git

@ -0,0 +1 @@
Subproject commit 28304159f2fea1f702929883c634e52755d6e74b

@ -0,0 +1 @@
Subproject commit 15321e16a085b9b5c85cf029aee86bf57b2e65c1

@ -0,0 +1 @@
Subproject commit b2597268aef084202a8c349d1cc072c03c6e22eb

@ -0,0 +1 @@
Subproject commit d4fad7f50f79626455d88523207e05b868819cd8

View file

@ -8,8 +8,8 @@ ifeq ($(PROTOBUF),)
endif endif
# Set 'skia' folder only if it's not externally set # Set 'skia' folder only if it's not externally set
ifeq ($(SKIA_ABS),) ifeq ($(OSMAND_SKIA_ABS),)
SKIA_ABS := $(LOCAL_PATH)/../skia OSMAND_SKIA_ABS := $(LOCAL_PATH)/../skia/skia_library
endif endif
# Name of the local module # Name of the local module
@ -23,14 +23,15 @@ endif
# Include paths # Include paths
LOCAL_C_INCLUDES := $(LOCAL_PATH) \ LOCAL_C_INCLUDES := $(LOCAL_PATH) \
$(PROTOBUF) \ $(PROTOBUF) \
$(SKIA_ABS)/trunk/include/core \ $(LOCAL_PATH)/../skia \
$(SKIA_ABS)/trunk/include/utils \ $(OSMAND_SKIA_ABS)/include/core \
$(SKIA_ABS)/trunk/include/config \ $(OSMAND_SKIA_ABS)/include/images \
$(SKIA_ABS)/trunk/include/effects \ $(OSMAND_SKIA_ABS)/include/utils \
$(SKIA_ABS)/trunk/include/utils/android \ $(OSMAND_SKIA_ABS)/include/config \
$(SKIA_ABS)/trunk/src/core $(OSMAND_SKIA_ABS)/include/effects \
$(OSMAND_SKIA_ABS)/include/utils/android \
$(OSMAND_SKIA_ABS)/src/core
LOCAL_CPP_EXTENSION := .cpp
LOCAL_SRC_FILES := \ LOCAL_SRC_FILES := \
common.cpp \ common.cpp \
mapObjects.cpp \ mapObjects.cpp \
@ -47,6 +48,11 @@ LOCAL_CFLAGS := \
-DSK_RELEASE \ -DSK_RELEASE \
-DGR_RELEASE=1 -DGR_RELEASE=1
ifdef OSMAND_PROFILE_NATIVE_OPERATIONS
LOCAL_CFLAGS += \
-DPROFILE_NATIVE_OPERATIONS
endif
ifneq ($(LOCAL_ARM_NEON),true) ifneq ($(LOCAL_ARM_NEON),true)
LOCAL_STATIC_LIBRARIES := proto skia LOCAL_STATIC_LIBRARIES := proto skia
else else

View file

@ -83,7 +83,7 @@ struct SearchQuery {
} }
bool isCancelled(){ bool isCancelled(){
return globalEnv()->GetBooleanField(o, interruptedField); return getGlobalJniEnv()->GetBooleanField(o, interruptedField);
} }
}; };
@ -361,7 +361,7 @@ void loadJniBinaryRead() {
extern "C" JNIEXPORT void JNICALL Java_net_osmand_plus_render_NativeOsmandLibrary_deleteSearchResult(JNIEnv* ienv, extern "C" JNIEXPORT void JNICALL Java_net_osmand_plus_render_NativeOsmandLibrary_deleteSearchResult(JNIEnv* ienv,
jobject obj, jint searchResult) { jobject obj, jint searchResult) {
// DO NOT DO IT it can leads to messing thread that is not allowed // DO NOT DO IT it can leads to messing thread that is not allowed
// setGlobalEnv(ienv); // setGlobalJniEnv(ienv);
SearchResult* result = (SearchResult*) searchResult; SearchResult* result = (SearchResult*) searchResult;
if(result != NULL){ if(result != NULL){
delete result; delete result;
@ -690,7 +690,7 @@ extern "C" JNIEXPORT jint JNICALL Java_net_osmand_plus_render_NativeOsmandLibrar
jobject obj, jint sleft, jint sright, jint stop, jint sbottom, jint zoom, jstring mapName, jobject obj, jint sleft, jint sright, jint stop, jint sbottom, jint zoom, jstring mapName,
jobject renderingRuleSearchRequest, bool skipDuplicates, jint searchResult, jobject objInterrupted) { jobject renderingRuleSearchRequest, bool skipDuplicates, jint searchResult, jobject objInterrupted) {
// TODO skipDuplicates not supported // TODO skipDuplicates not supported
setGlobalEnv(ienv); setGlobalJniEnv(ienv);
SearchResult* result = (SearchResult*) searchResult; SearchResult* result = (SearchResult*) searchResult;
if(result == NULL) { if(result == NULL) {
result = new SearchResult(); result = new SearchResult();
@ -702,9 +702,9 @@ extern "C" JNIEXPORT jint JNICALL Java_net_osmand_plus_render_NativeOsmandLibrar
} }
BinaryMapFile* file = i->second; BinaryMapFile* file = i->second;
RenderingRuleSearchRequest* req = initSearchRequest(renderingRuleSearchRequest); RenderingRuleSearchRequest* req = initSearchRequest(renderingRuleSearchRequest);
jclass clObjInterrupted = globalEnv()->GetObjectClass(objInterrupted); jclass clObjInterrupted = getGlobalJniEnv()->GetObjectClass(objInterrupted);
jfieldID interruptedField = getFid(clObjInterrupted, "interrupted", "Z"); jfieldID interruptedField = getFid(clObjInterrupted, "interrupted", "Z");
globalEnv()->DeleteLocalRef(clObjInterrupted); getGlobalJniEnv()->DeleteLocalRef(clObjInterrupted);
SearchQuery q(sleft,sright, stop, sbottom, req, objInterrupted, interruptedField); SearchQuery q(sleft,sright, stop, sbottom, req, objInterrupted, interruptedField);
fseek(file->f, 0, 0); fseek(file->f, 0, 0);
@ -757,7 +757,7 @@ extern "C" JNIEXPORT jint JNICALL Java_net_osmand_plus_render_NativeOsmandLibrar
extern "C" JNIEXPORT jboolean JNICALL Java_net_osmand_plus_render_NativeOsmandLibrary_initBinaryMapFile(JNIEnv* ienv, extern "C" JNIEXPORT jboolean JNICALL Java_net_osmand_plus_render_NativeOsmandLibrary_initBinaryMapFile(JNIEnv* ienv,
jobject obj, jobject path) { jobject obj, jobject path) {
// Verify that the version of the library that we linked against is // Verify that the version of the library that we linked against is
setGlobalEnv(ienv); setGlobalJniEnv(ienv);
const char* utf = ienv->GetStringUTFChars((jstring) path, NULL); const char* utf = ienv->GetStringUTFChars((jstring) path, NULL);
std::string inputName(utf); std::string inputName(utf);
ienv->ReleaseStringUTFChars((jstring) path, utf); ienv->ReleaseStringUTFChars((jstring) path, utf);

View file

@ -1,252 +1,366 @@
#ifndef _OSMAND_COMMON
#define _OSMAND_COMMON
#include <common.h>
#include <android/log.h> #include <android/log.h>
#include <string> #include <string>
#include <vector> #include <vector>
#include <hash_map> #include <hash_map>
#include <SkPath.h> #include <SkPath.h>
#include <SkBitmap.h> #include <SkBitmap.h>
#include <SkImageDecoder.h>
JNIEnv* globalE; #include "common.h"
JavaVM* globalVM;
JNIEnv* globalEnv(){ const char* const LOG_TAG = "net.osmand:native";
return globalE;
JavaVM* globalJVM = NULL;
JNIEnv* globalJniEnv = NULL;
JNIEnv* getGlobalJniEnv()
{
return globalJniEnv;
} }
JNIEnv* setGlobalEnv(JNIEnv* e) { JNIEnv* setGlobalJniEnv(JNIEnv* e)
globalVM->GetEnv((void**)&globalE, JNI_VERSION_1_4); {
// try to avoid problem with different thread attach if(!globalJVM)
// globalE = e; __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "No globalJVM set");
return globalE; globalJVM->GetEnv((void**)&globalJniEnv, JNI_VERSION_1_6);
return globalJniEnv;
} }
extern void loadJniCommon(); // Forward declarations
extern void loadJNIRenderingRules(); void loadJniCommon();
extern void loadJNIRendering(); void loadJniRendering();
extern void loadJniMapObjects(); void loadJniRenderingRules();
extern void loadJniBinaryRead(); void loadJniMapObjects();
void loadJniBinaryRead();
extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
if(vm->GetEnv((void **)&globalE, JNI_VERSION_1_4)){ {
if(vm->GetEnv((void **)&globalJniEnv, JNI_VERSION_1_6))
return JNI_ERR; /* JNI version not supported */ return JNI_ERR; /* JNI version not supported */
} globalJVM = vm;
globalVM = vm;
loadJniCommon(); loadJniCommon();
loadJNIRendering(); loadJniRendering();
loadJNIRenderingRules(); loadJniRenderingRules();
loadJniMapObjects(); loadJniMapObjects();
loadJniBinaryRead(); loadJniBinaryRead();
return JNI_VERSION_1_4;
__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "JNI_OnLoad completed");
return JNI_VERSION_1_6;
} }
//extern "C" JNIEXPORT jboolean JNICALL Java_net_osmand_plus_render_NativeOsmandLibrary_loadLibrary(JNIEnv* ienv) {} void throwNewException(const char* msg)
jclass RenderingContextClass;
jfieldID RenderingContext_interrupted;
jclass RenderingIconsClass;
jmethodID RenderingIcons_getIcon;
jclass globalRef(jobject o)
{ {
return (jclass) globalEnv()->NewGlobalRef( o); __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, msg);
getGlobalJniEnv()->ThrowNew(getGlobalJniEnv()->FindClass("java/lang/Exception"), msg);
} }
jclass findClass(const char* className, bool mustHave/* = true*/)
{
jclass javaClass = getGlobalJniEnv()->FindClass(className);
if(!javaClass && mustHave)
throwNewException((std::string("Failed to find class ") + className).c_str());
return (jclass)newGlobalRef(javaClass);
}
jobject newGlobalRef(jobject o)
{
return getGlobalJniEnv()->NewGlobalRef(o);
}
jfieldID getFid(jclass cls, const char* fieldName, const char* sig) jfieldID getFid(jclass cls, const char* fieldName, const char* sig)
{ {
return globalEnv()->GetFieldID( cls, fieldName, sig); jfieldID jfield = getGlobalJniEnv()->GetFieldID(cls, fieldName, sig);
if(!jfield)
throwNewException((std::string("Failed to find field ") + fieldName + std::string(" with signature ") + sig).c_str());
return jfield;
} }
watcher::watcher() {
elapsedTime = 0;
enableFlag = true;
run = false;
}
void watcher::enable() {
enableFlag = true;
}
void watcher::disable() {
pause();
enableFlag = false;
}
void watcher::start() {
if (!enableFlag) {
return;
}
if (!run) {
clock_gettime(CLOCK_MONOTONIC, &startInit);
// gettimeofday(&startInit, NULL);
}
run = true;
}
void watcher::pause() {
if (!run) {
return;
}
clock_gettime(CLOCK_MONOTONIC, &endInit);
// gettimeofday(&endInit, NULL);
int sec = endInit.tv_sec - startInit.tv_sec;
if (sec > 0) {
elapsedTime += 1e9 * sec;
}
elapsedTime += endInit.tv_nsec - startInit.tv_nsec;
// elapsedTime += (endInit.tv_sec * 1000 + endInit.tv_usec / 1000)
// - (startInit.tv_sec * 1000 + startInit.tv_usec / 1000);
run = false;
}
int watcher::getElapsedTime() {
pause();
return elapsedTime / 1e6;
}
std::string getStringField(jobject o, jfieldID fid) std::string getStringField(jobject o, jfieldID fid)
{ {
jstring st = (jstring) globalEnv()->GetObjectField(o, fid); jstring jstr = (jstring)getGlobalJniEnv()->GetObjectField(o, fid);
if(st == NULL) if(!jstr)
{ {
throwNewException("Failed to get object from field");
return std::string(); return std::string();
} }
const char* utf = globalEnv()->GetStringUTFChars(st, NULL); const char* utfBytes = getGlobalJniEnv()->GetStringUTFChars(jstr, NULL);
std::string res(utf); //TODO: I'm not quite sure that if real unicode will happen here, this will work as expected
globalEnv()->ReleaseStringUTFChars(st, utf); std::string result(utfBytes);
globalEnv()->DeleteLocalRef(st); getGlobalJniEnv()->ReleaseStringUTFChars(jstr, utfBytes);
return res; getGlobalJniEnv()->DeleteLocalRef(jstr);
return result;
} }
std::string getString(jstring st) { std::string getString(jstring jstr)
if (st == NULL) { {
return EMPTY_STRING; if(!jstr)
{
throwNewException("NULL jstring passed in");
return std::string();
} }
const char* utf = globalEnv()->GetStringUTFChars(st, NULL); const char* utfBytes = getGlobalJniEnv()->GetStringUTFChars(jstr, NULL);
std::string res(utf); //TODO: I'm not quite sure that if real unicode will happen here, this will work as expected
globalEnv()->ReleaseStringUTFChars(st, utf); std::string result(utfBytes);
return res; getGlobalJniEnv()->ReleaseStringUTFChars(jstr, utfBytes);
return result;
} }
std::string getStringMethod(jobject o, jmethodID fid) std::string getStringMethod(jobject o, jmethodID fid)
{ {
return getString((jstring) globalEnv()->CallObjectMethod(o, fid)); return getString((jstring)getGlobalJniEnv()->CallObjectMethod(o, fid));
} }
std::string getStringMethod(jobject o, jmethodID fid, int i) std::string getStringMethod(jobject o, jmethodID fid, int i)
{ {
return getString((jstring) globalEnv()->CallObjectMethod(o, fid, i)); return getString((jstring)getGlobalJniEnv()->CallObjectMethod(o, fid, i));
} }
float getDensityValue(RenderingContext* rc, float val) { jclass jclass_RenderingContext = NULL;
if (rc -> highResMode && rc -> density > 1) { jfieldID jfield_RenderingContext_interrupted = NULL;
jclass jclass_RenderingIcons = NULL;
jmethodID jmethod_RenderingIcons_getIconAsByteBuffer = 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()
{
jclass_RenderingContext = findClass("net/osmand/plus/render/OsmandRenderer$RenderingContext");
jfield_RenderingContext_interrupted = getFid(jclass_RenderingContext, "interrupted", "Z");
jfield_RenderingContext_leftX = getFid( jclass_RenderingContext, "leftX", "F" );
jfield_RenderingContext_topY = getFid( jclass_RenderingContext, "topY", "F" );
jfield_RenderingContext_width = getFid( jclass_RenderingContext, "width", "I" );
jfield_RenderingContext_height = getFid( jclass_RenderingContext, "height", "I" );
jfield_RenderingContext_zoom = getFid( jclass_RenderingContext, "zoom", "I" );
jfield_RenderingContext_rotate = getFid( jclass_RenderingContext, "rotate", "F" );
jfield_RenderingContext_tileDivisor = getFid( jclass_RenderingContext, "tileDivisor", "F" );
jfield_RenderingContext_pointCount = getFid( jclass_RenderingContext, "pointCount", "I" );
jfield_RenderingContext_pointInsideCount = getFid( jclass_RenderingContext, "pointInsideCount", "I" );
jfield_RenderingContext_visible = getFid( jclass_RenderingContext, "visible", "I" );
jfield_RenderingContext_allObjects = getFid( jclass_RenderingContext, "allObjects", "I" );
jfield_RenderingContext_cosRotateTileSize = getFid( jclass_RenderingContext, "cosRotateTileSize", "F" );
jfield_RenderingContext_sinRotateTileSize = getFid( jclass_RenderingContext, "sinRotateTileSize", "F" );
jfield_RenderingContext_density = getFid( jclass_RenderingContext, "density", "F" );
jfield_RenderingContext_highResMode = getFid( jclass_RenderingContext, "highResMode", "Z" );
jfield_RenderingContext_mapTextSize = getFid( jclass_RenderingContext, "mapTextSize", "F" );
jfield_RenderingContext_shadowRenderingMode = getFid( jclass_RenderingContext, "shadowRenderingMode", "I" );
jfield_RenderingContext_shadowLevelMin = getFid( jclass_RenderingContext, "shadowLevelMin", "I" );
jfield_RenderingContext_shadowLevelMax = getFid( jclass_RenderingContext, "shadowLevelMax", "I" );
jfield_RenderingContext_ctx = getFid( jclass_RenderingContext, "ctx", "Landroid/content/Context;" );
jfield_RenderingContext_textRenderingTime = getFid( jclass_RenderingContext, "textRenderingTime", "I" );
jfield_RenderingContext_lastRenderedKey = getFid( jclass_RenderingContext, "lastRenderedKey", "I" );
jclass_RenderingIcons = findClass("net/osmand/plus/render/RenderingIcons");
jmethod_RenderingIcons_getIconAsByteBuffer = getGlobalJniEnv()->GetStaticMethodID(jclass_RenderingIcons,
"getIconAsByteBuffer",
"(Landroid/content/Context;Ljava/lang/String;)Ljava/nio/ByteBuffer;");
}
//TODO: Dead code
/*
void unloadJniCommon() {
getGlobalJniEnv()->DeleteGlobalRef(jclass_RenderingIcons);
getGlobalJniEnv()->DeleteGlobalRef(jclass_RenderingContext);
}
*/
void pullFromJavaRenderingContext(jobject jrc, RenderingContext* rc)
{
rc->leftX = getGlobalJniEnv()->GetFloatField( jrc, jfield_RenderingContext_leftX );
rc->topY = getGlobalJniEnv()->GetFloatField( jrc, jfield_RenderingContext_topY );
rc->width = getGlobalJniEnv()->GetIntField( jrc, jfield_RenderingContext_width );
rc->height = getGlobalJniEnv()->GetIntField( jrc, jfield_RenderingContext_height );
rc->zoom = getGlobalJniEnv()->GetIntField( jrc, jfield_RenderingContext_zoom );
rc->rotate = getGlobalJniEnv()->GetFloatField( jrc, jfield_RenderingContext_rotate );
rc->tileDivisor = getGlobalJniEnv()->GetFloatField( jrc, jfield_RenderingContext_tileDivisor );
rc->pointCount = getGlobalJniEnv()->GetIntField( jrc, jfield_RenderingContext_pointCount );
rc->pointInsideCount = getGlobalJniEnv()->GetIntField( jrc, jfield_RenderingContext_pointInsideCount );
rc->visible = getGlobalJniEnv()->GetIntField( jrc, jfield_RenderingContext_visible );
rc->allObjects = getGlobalJniEnv()->GetIntField( jrc, jfield_RenderingContext_allObjects );
rc->cosRotateTileSize = getGlobalJniEnv()->GetFloatField( jrc, jfield_RenderingContext_cosRotateTileSize );
rc->sinRotateTileSize = getGlobalJniEnv()->GetFloatField( jrc, jfield_RenderingContext_sinRotateTileSize );
rc->density = getGlobalJniEnv()->GetFloatField( jrc, jfield_RenderingContext_density );
rc->highResMode = getGlobalJniEnv()->GetBooleanField( jrc, jfield_RenderingContext_highResMode );
rc->mapTextSize = getGlobalJniEnv()->GetFloatField( jrc, jfield_RenderingContext_mapTextSize );
rc->shadowRenderingMode = getGlobalJniEnv()->GetIntField( jrc, jfield_RenderingContext_shadowRenderingMode );
rc->shadowLevelMin = getGlobalJniEnv()->GetIntField( jrc, jfield_RenderingContext_shadowLevelMin );
rc->shadowLevelMax = getGlobalJniEnv()->GetIntField( jrc, jfield_RenderingContext_shadowLevelMax );
rc->androidContext = getGlobalJniEnv()->GetObjectField(jrc, jfield_RenderingContext_ctx );
rc->lastRenderedKey = 0;
rc->javaRenderingContext = jrc;
}
void pushToJavaRenderingContext(jobject jrc, RenderingContext* rc)
{
getGlobalJniEnv()->SetIntField( jrc, jfield_RenderingContext_pointCount, rc->pointCount);
getGlobalJniEnv()->SetIntField( jrc, jfield_RenderingContext_pointInsideCount, rc->pointInsideCount);
getGlobalJniEnv()->SetIntField( jrc, jfield_RenderingContext_visible, rc->visible);
getGlobalJniEnv()->SetIntField( jrc, jfield_RenderingContext_allObjects, rc->allObjects);
getGlobalJniEnv()->SetIntField( jrc, jfield_RenderingContext_textRenderingTime, rc->textRendering.getElapsedTime());
getGlobalJniEnv()->SetIntField( jrc, jfield_RenderingContext_lastRenderedKey, rc->lastRenderedKey);
getGlobalJniEnv()->DeleteLocalRef(rc->androidContext);
}
TextDrawInfo::TextDrawInfo(std::string itext)
: text(itext)
, drawOnPath(false)
, path(NULL)
, pathRotate(0)
{
}
TextDrawInfo::~TextDrawInfo()
{
if (path)
delete path;
}
IconDrawInfo::IconDrawInfo()
: bmp(NULL)
{
}
RenderingContext::RenderingContext()
: javaRenderingContext(NULL)
, androidContext(NULL)
{
}
RenderingContext::~RenderingContext()
{
std::vector<TextDrawInfo*>::iterator itTextToDraw;
for(itTextToDraw = textToDraw.begin(); itTextToDraw != textToDraw.end(); ++itTextToDraw)
delete (*itTextToDraw);
}
bool RenderingContext::interrupted()
{
return getGlobalJniEnv()->GetBooleanField(javaRenderingContext, jfield_RenderingContext_interrupted);
}
float getDensityValue(RenderingContext* rc, float val)
{
if (rc->highResMode && rc->density > 1)
return val * rc->density * rc->mapTextSize; return val * rc->density * rc->mapTextSize;
} else { else
return val * rc->mapTextSize; return val * rc->mapTextSize;
} }
ElapsedTimer::ElapsedTimer()
: elapsedTime(0)
, enableFlag(true)
, run(false)
{
} }
SkBitmap* getNativeBitmap(jobject bmpObj){ void ElapsedTimer::enable()
if(bmpObj == NULL){ {
return NULL; enableFlag = true;
} }
jclass bmpClass = globalEnv()->GetObjectClass(bmpObj);
SkBitmap* bmp = (SkBitmap*)globalEnv()->CallIntMethod(bmpObj, globalEnv()->GetMethodID(bmpClass, "ni", "()I")); void ElapsedTimer::disable()
globalEnv()->DeleteLocalRef(bmpClass); {
return bmp; pause();
enableFlag = false;
}
void ElapsedTimer::start()
{
if (!enableFlag)
return;
if (!run)
clock_gettime(CLOCK_MONOTONIC, &startInit);
run = true;
}
void ElapsedTimer::pause()
{
if (!run)
return;
clock_gettime(CLOCK_MONOTONIC, &endInit);
int sec = endInit.tv_sec - startInit.tv_sec;
if (sec > 0)
elapsedTime += 1e9 * sec;
elapsedTime += endInit.tv_nsec - startInit.tv_nsec;
run = false;
}
int ElapsedTimer::getElapsedTime()
{
pause();
return elapsedTime / 1e6;
} }
std::hash_map<std::string, SkBitmap*> cachedBitmaps; std::hash_map<std::string, SkBitmap*> cachedBitmaps;
SkBitmap* getCachedBitmap(RenderingContext* rc, std::string js)
SkBitmap* getCachedBitmap(RenderingContext* rc, std::string bitmapResource)
{ {
if (cachedBitmaps.find(js) != cachedBitmaps.end()) { // Try to find previously cached
return cachedBitmaps[js]; std::hash_map<std::string, SkBitmap*>::iterator itPreviouslyCachedBitmap = cachedBitmaps.find(bitmapResource);
} if (itPreviouslyCachedBitmap != cachedBitmaps.end())
return itPreviouslyCachedBitmap->second;
rc->nativeOperations.pause(); rc->nativeOperations.pause();
jstring jstr = globalEnv()->NewStringUTF(js.c_str());
jobject bmp = globalEnv()->CallStaticObjectMethod(RenderingIconsClass, RenderingIcons_getIcon, rc->androidContext, jstr); jstring jstr = getGlobalJniEnv()->NewStringUTF(bitmapResource.c_str());
SkBitmap* res = getNativeBitmap(bmp); jobject javaIconByteBuffer = getGlobalJniEnv()->CallStaticObjectMethod(jclass_RenderingIcons, jmethod_RenderingIcons_getIconAsByteBuffer, rc->androidContext, jstr);
if(!javaIconByteBuffer)
return NULL;
// Decode bitmap
SkBitmap* iconBitmap = new SkBitmap();
void* bitmapBuffer = getGlobalJniEnv()->GetDirectBufferAddress(javaIconByteBuffer);
size_t bufferLen = getGlobalJniEnv()->GetDirectBufferCapacity(javaIconByteBuffer);
//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();
getGlobalJniEnv()->DeleteLocalRef(javaIconByteBuffer);
getGlobalJniEnv()->DeleteLocalRef(jstr);
throwNewException((std::string("Failed to decode ") + bitmapResource).c_str());
return NULL;
}
cachedBitmaps[bitmapResource] = iconBitmap;
rc->nativeOperations.start(); rc->nativeOperations.start();
globalEnv()->DeleteLocalRef(bmp); getGlobalJniEnv()->DeleteLocalRef(javaIconByteBuffer);
globalEnv()->DeleteLocalRef(jstr); getGlobalJniEnv()->DeleteLocalRef(jstr);
if(res != NULL){
res = new SkBitmap(*res);
}
cachedBitmaps[js] = res;
return res; return iconBitmap;
} }
void loadJniCommon() {
RenderingContextClass = globalRef(globalEnv()->FindClass("net/osmand/plus/render/OsmandRenderer$RenderingContext"));
RenderingContext_interrupted = getFid(RenderingContextClass, "interrupted", "Z");
RenderingIconsClass = globalRef(globalEnv()->FindClass("net/osmand/render/RenderingRule"));
RenderingIconsClass = globalRef(globalEnv()->FindClass("net/osmand/plus/render/RenderingIcons"));
RenderingIcons_getIcon = globalEnv()->GetStaticMethodID(RenderingIconsClass, "getIcon",
"(Landroid/content/Context;Ljava/lang/String;)Landroid/graphics/Bitmap;");
}
void unloadJniCommon() {
globalEnv()->DeleteGlobalRef(RenderingContextClass);
globalEnv()->DeleteGlobalRef(RenderingIconsClass);
}
void copyRenderingContext(jobject orc, RenderingContext* rc)
{
rc->leftX = globalEnv()->GetFloatField( orc, getFid( RenderingContextClass, "leftX", "F" ) );
rc->topY = globalEnv()->GetFloatField( orc, getFid( RenderingContextClass, "topY", "F" ) );
rc->width = globalEnv()->GetIntField( orc, getFid( RenderingContextClass, "width", "I" ) );
rc->height = globalEnv()->GetIntField( orc, getFid( RenderingContextClass, "height", "I" ) );
rc->zoom = globalEnv()->GetIntField( orc, getFid( RenderingContextClass, "zoom", "I" ) );
rc->rotate = globalEnv()->GetFloatField( orc, getFid( RenderingContextClass, "rotate", "F" ) );
rc->tileDivisor = globalEnv()->GetFloatField( orc, getFid( RenderingContextClass, "tileDivisor", "F" ) );
rc->pointCount = globalEnv()->GetIntField( orc, getFid( RenderingContextClass, "pointCount", "I" ) );
rc->pointInsideCount = globalEnv()->GetIntField( orc, getFid( RenderingContextClass, "pointInsideCount", "I" ) );
rc->visible = globalEnv()->GetIntField( orc, getFid( RenderingContextClass, "visible", "I" ) );
rc->allObjects = globalEnv()->GetIntField( orc, getFid( RenderingContextClass, "allObjects", "I" ) );
rc->cosRotateTileSize = globalEnv()->GetFloatField( orc, getFid( RenderingContextClass, "cosRotateTileSize", "F" ) );
rc->sinRotateTileSize = globalEnv()->GetFloatField( orc, getFid( RenderingContextClass, "sinRotateTileSize", "F" ) );
rc->density = globalEnv()->GetFloatField( orc, getFid( RenderingContextClass, "density", "F" ) );
rc->highResMode = globalEnv()->GetBooleanField( orc, getFid( RenderingContextClass, "highResMode", "Z" ) );
rc->mapTextSize = globalEnv()->GetFloatField( orc, getFid( RenderingContextClass, "mapTextSize", "F" ) );
rc->shadowRenderingMode = globalEnv()->GetIntField( orc, getFid( RenderingContextClass, "shadowRenderingMode", "I" ) );
rc->shadowLevelMin = globalEnv()->GetIntField( orc, getFid( RenderingContextClass, "shadowLevelMin", "I" ) );
rc->shadowLevelMax = globalEnv()->GetIntField( orc, getFid( RenderingContextClass, "shadowLevelMax", "I" ) );
rc->androidContext = globalEnv()->GetObjectField(orc, getFid( RenderingContextClass, "ctx", "Landroid/content/Context;"));
rc->lastRenderedKey = 0;
rc->originalRC = orc;
}
void mergeRenderingContext(jobject orc, RenderingContext* rc)
{
globalEnv()->SetIntField( orc, getFid(RenderingContextClass, "pointCount", "I" ) , rc->pointCount);
globalEnv()->SetIntField( orc, getFid(RenderingContextClass, "pointInsideCount", "I" ) , rc->pointInsideCount);
globalEnv()->SetIntField( orc, getFid(RenderingContextClass, "visible", "I" ) , rc->visible);
globalEnv()->SetIntField( orc, getFid(RenderingContextClass, "allObjects", "I" ) , rc->allObjects);
globalEnv()->SetIntField( orc, getFid(RenderingContextClass, "textRenderingTime", "I" ) , rc->textRendering.getElapsedTime());
globalEnv()->SetIntField( orc, getFid(RenderingContextClass, "lastRenderedKey", "I" ) , rc->lastRenderedKey);
globalEnv()->DeleteLocalRef(rc->androidContext);
}
#endif

View file

@ -5,72 +5,64 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <hash_map> #include <hash_map>
#include <SkPath.h> #include <SkPath.h>
#include <SkBitmap.h> #include <SkBitmap.h>
// Constants #ifdef PROFILE_NATIVE_OPERATIONS
#define DEBUG_NAT_OPERATIONS #define PROFILE_NATIVE_OPERATION(rc, op) rc->nativeOperations.pause(); op; rc->nativeOperations.start()
#ifdef DEBUG_NAT_OPERATIONS
#define NAT_COUNT(rc, op) rc->nativeOperations.pause(); op; rc->nativeOperations.start()
#else #else
#define NAT_COUNT(rc, op) op; #define PROFILE_NATIVE_OPERATION(rc, op) op;
#endif #endif
const std::string EMPTY_STRING; struct RenderingContext;
const int WHITE_COLOR = -1;
const int BLACK_COLOR = 0xff000000;
JNIEnv* globalEnv(); JNIEnv* getGlobalJniEnv();
JNIEnv* setGlobalJniEnv(JNIEnv*);
JNIEnv* setGlobalEnv(JNIEnv* e); // Android helpers
extern const char* const LOG_TAG;
// JNI Helpers // JNI Helpers
//extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved); void throwNewException(const char* msg);
jclass findClass(const char* className, bool mustHave = true);
std::string getString(jstring st); std::string getString(jstring st);
std::string getStringMethod(jobject o, jmethodID fid, int i); std::string getStringMethod(jobject o, jmethodID fid, int i);
std::string getStringMethod(jobject o, jmethodID fid); std::string getStringMethod(jobject o, jmethodID fid);
std::string getStringField(jobject o, jfieldID fid); std::string getStringField(jobject o, jfieldID fid);
jclass globalRef(jobject o); jobject newGlobalRef(jobject o);
jfieldID getFid(jclass cls, const char* fieldName, const char* sig); jfieldID getFid(jclass cls, const char* fieldName, const char* sig);
void pullFromJavaRenderingContext(jobject jrc, RenderingContext* rc);
void pushToJavaRenderingContext(jobject jrc, RenderingContext* rc);
class watcher { class ElapsedTimer
{
private: private:
long elapsedTime; long elapsedTime;
bool enableFlag; bool enableFlag;
// timeval startInit;
// timeval endInit;
timespec startInit; timespec startInit;
timespec endInit; timespec endInit;
bool run; bool run;
public: public:
watcher(); ElapsedTimer();
void enable(); void enable();
void disable(); void disable();
void start(); void start();
void pause(); void pause();
int getElapsedTime(); int getElapsedTime();
}; };
// Rendering context methods struct TextDrawInfo {
class TextDrawInfo { TextDrawInfo(std::string);
public : ~TextDrawInfo();
std::string text; std::string text;
TextDrawInfo(std::string itext) {
text = itext;
drawOnPath = false;
path = NULL;
pathRotate = 0;
}
SkRect bounds; SkRect bounds;
float centerX; float centerX;
float centerY; float centerY;
@ -89,23 +81,25 @@ public :
float pathRotate; float pathRotate;
float vOffset; float vOffset;
float hOffset; float hOffset;
~TextDrawInfo() {
if (path != NULL) {
delete path;
}
}
}; };
struct IconDrawInfo { struct IconDrawInfo
{
IconDrawInfo();
SkBitmap* bmp; SkBitmap* bmp;
float x; float x;
float y; float y;
}; };
extern jfieldID RenderingContext_interrupted; struct RenderingContext
struct RenderingContext { {
jobject originalRC; RenderingContext();
~RenderingContext();
bool interrupted();
jobject javaRenderingContext;
jobject androidContext; jobject androidContext;
bool useEnglishNames; bool useEnglishNames;
@ -130,9 +124,8 @@ struct RenderingContext {
int visible; int visible;
int allObjects; int allObjects;
int lastRenderedKey; int lastRenderedKey;
watcher textRendering; class ElapsedTimer textRendering;
watcher nativeOperations; class ElapsedTimer nativeOperations;
// use to calculate points // use to calculate points
float calcX; float calcX;
@ -146,23 +139,10 @@ struct RenderingContext {
// not expect any shadow // not expect any shadow
int shadowLevelMin; int shadowLevelMin;
int shadowLevelMax; int shadowLevelMax;
bool interrupted() {
return globalEnv()->GetBooleanField(originalRC, RenderingContext_interrupted);
}
~RenderingContext() {
for (uint i = 0; i < textToDraw.size(); i++) {
delete textToDraw.at(i);
}
}
}; };
void copyRenderingContext(jobject orc, RenderingContext* rc);
void mergeRenderingContext(jobject orc, RenderingContext* rc);
float getDensityValue(RenderingContext* rc, float val); float getDensityValue(RenderingContext* rc, float val);
SkBitmap* getCachedBitmap(RenderingContext* rc, std::string js); SkBitmap* getCachedBitmap(RenderingContext* rc, std::string bitmapResource);
SkBitmap* getNativeBitmap(jobject bmpObj);
#endif /*_OSMAND_COMMON_H*/ #endif /*_OSMAND_COMMON_H*/

View file

@ -36,24 +36,24 @@ std::vector <BaseMapDataObject* > marshalObjects(jobjectArray binaryMapDataObjec
{ {
std::vector<BaseMapDataObject*> v; std::vector<BaseMapDataObject*> v;
const size_t size = globalEnv()->GetArrayLength(binaryMapDataObjects); const size_t size = getGlobalJniEnv()->GetArrayLength(binaryMapDataObjects);
size_t i = 0; size_t i = 0;
for (; i < size; i++) { for (; i < size; i++) {
jobject binaryMapDataObject = (jobject) globalEnv()->GetObjectArrayElement(binaryMapDataObjects, i); jobject binaryMapDataObject = (jobject) getGlobalJniEnv()->GetObjectArrayElement(binaryMapDataObjects, i);
if (globalEnv()->IsInstanceOf(binaryMapDataObject, MultiPolygonClass)) { if (getGlobalJniEnv()->IsInstanceOf(binaryMapDataObject, MultiPolygonClass)) {
MultiPolygonObject* o = new MultiPolygonObject(); MultiPolygonObject* o = new MultiPolygonObject();
v.push_back((BaseMapDataObject* )o); v.push_back((BaseMapDataObject* )o);
o->layer = globalEnv()->CallIntMethod(binaryMapDataObject, MultiPolygon_getLayer); o->layer = getGlobalJniEnv()->CallIntMethod(binaryMapDataObject, MultiPolygon_getLayer);
o->tag = getStringMethod(binaryMapDataObject, MultiPolygon_getTag); o->tag = getStringMethod(binaryMapDataObject, MultiPolygon_getTag);
o->value = getStringMethod(binaryMapDataObject, MultiPolygon_getValue); o->value = getStringMethod(binaryMapDataObject, MultiPolygon_getValue);
int boundsCount = globalEnv()->CallIntMethod(binaryMapDataObject, MultiPolygon_getBoundsCount); int boundsCount = getGlobalJniEnv()->CallIntMethod(binaryMapDataObject, MultiPolygon_getBoundsCount);
for (int ji = 0; ji < boundsCount; ji++) { for (int ji = 0; ji < boundsCount; ji++) {
int cnt = globalEnv()->CallIntMethod(binaryMapDataObject, MultiPolygon_getBoundPointsCount, ji); int cnt = getGlobalJniEnv()->CallIntMethod(binaryMapDataObject, MultiPolygon_getBoundPointsCount, ji);
std::vector<std::pair<int, int> > vs; std::vector<std::pair<int, int> > vs;
for (int js = 0; js < cnt; js++) { for (int js = 0; js < cnt; js++) {
int xt = globalEnv()->CallIntMethod(binaryMapDataObject, MultiPolygon_getPoint31XTile, js, ji); int xt = getGlobalJniEnv()->CallIntMethod(binaryMapDataObject, MultiPolygon_getPoint31XTile, js, ji);
int yt = globalEnv()->CallIntMethod(binaryMapDataObject, MultiPolygon_getPoint31YTile, js, ji); int yt = getGlobalJniEnv()->CallIntMethod(binaryMapDataObject, MultiPolygon_getPoint31YTile, js, ji);
vs.push_back( std::pair<int, int> (xt, yt) ); vs.push_back( std::pair<int, int> (xt, yt) );
} }
@ -64,40 +64,40 @@ std::vector <BaseMapDataObject* > marshalObjects(jobjectArray binaryMapDataObjec
} else { } else {
jintArray types = (jintArray) globalEnv()->CallObjectMethod(binaryMapDataObject, BinaryMapDataObject_getTypes); jintArray types = (jintArray) getGlobalJniEnv()->CallObjectMethod(binaryMapDataObject, BinaryMapDataObject_getTypes);
if (types != NULL) { if (types != NULL) {
MapDataObject* o = new MapDataObject(); MapDataObject* o = new MapDataObject();
jint sizeTypes = globalEnv()->GetArrayLength(types); jint sizeTypes = getGlobalJniEnv()->GetArrayLength(types);
jint* els = globalEnv()->GetIntArrayElements(types, NULL); jint* els = getGlobalJniEnv()->GetIntArrayElements(types, NULL);
int j = 0; int j = 0;
for (; j < sizeTypes; j++) { for (; j < sizeTypes; j++) {
int wholeType = els[j]; int wholeType = els[j];
o->types.push_back(wholeType); o->types.push_back(wholeType);
jobject pair = globalEnv()->CallObjectMethod(binaryMapDataObject, BinaryMapDataObject_getTagValue, j); jobject pair = getGlobalJniEnv()->CallObjectMethod(binaryMapDataObject, BinaryMapDataObject_getTagValue, j);
if (pair != NULL) { if (pair != NULL) {
std::string tag = getStringField(pair, TagValuePair_tag); std::string tag = getStringField(pair, TagValuePair_tag);
std::string value = getStringField(pair, TagValuePair_value); std::string value = getStringField(pair, TagValuePair_value);
o->tagValues.push_back( std::pair<std:: string, std::string>(tag, value)); o->tagValues.push_back( std::pair<std:: string, std::string>(tag, value));
globalEnv()->DeleteLocalRef(pair); getGlobalJniEnv()->DeleteLocalRef(pair);
} else { } else {
o->tagValues.push_back( std::pair<std:: string, std::string>(EMPTY_STRING, EMPTY_STRING)); o->tagValues.push_back( std::pair<std:: string, std::string>(std::string(), std::string()));
} }
} }
jint sizePoints = globalEnv()->CallIntMethod(binaryMapDataObject, BinaryMapDataObject_getPointsLength); jint sizePoints = getGlobalJniEnv()->CallIntMethod(binaryMapDataObject, BinaryMapDataObject_getPointsLength);
for (j = 0; j < sizePoints; j++) { for (j = 0; j < sizePoints; j++) {
int tx = globalEnv()->CallIntMethod(binaryMapDataObject, BinaryMapDataObject_getPoint31XTile, j); int tx = getGlobalJniEnv()->CallIntMethod(binaryMapDataObject, BinaryMapDataObject_getPoint31XTile, j);
int ty = globalEnv()->CallIntMethod(binaryMapDataObject, BinaryMapDataObject_getPoint31YTile, j); int ty = getGlobalJniEnv()->CallIntMethod(binaryMapDataObject, BinaryMapDataObject_getPoint31YTile, j);
o->points.push_back(std::pair<int, int>(tx, ty)); o->points.push_back(std::pair<int, int>(tx, ty));
} }
o->name = getStringMethod(binaryMapDataObject, BinaryMapDataObject_getName); o->name = getStringMethod(binaryMapDataObject, BinaryMapDataObject_getName);
o->highwayAttributes = globalEnv()->CallIntMethod(binaryMapDataObject, BinaryMapDataObject_getHighwayAttributes); o->highwayAttributes = getGlobalJniEnv()->CallIntMethod(binaryMapDataObject, BinaryMapDataObject_getHighwayAttributes);
globalEnv()->ReleaseIntArrayElements(types, els, JNI_ABORT); getGlobalJniEnv()->ReleaseIntArrayElements(types, els, JNI_ABORT);
globalEnv()->DeleteLocalRef(types); getGlobalJniEnv()->DeleteLocalRef(types);
v.push_back((BaseMapDataObject* )o); v.push_back((BaseMapDataObject* )o);
} }
} }
globalEnv()->DeleteLocalRef(binaryMapDataObject); getGlobalJniEnv()->DeleteLocalRef(binaryMapDataObject);
} }
return v; return v;
@ -115,38 +115,38 @@ void deleteObjects(std::vector <BaseMapDataObject* > & v)
void loadJniMapObjects() void loadJniMapObjects()
{ {
MultiPolygonClass = globalRef(globalEnv()->FindClass("net/osmand/osm/MultyPolygon")); MultiPolygonClass = findClass("net/osmand/osm/MultyPolygon");
MultiPolygon_getTag = globalEnv()->GetMethodID(MultiPolygonClass, "getTag", "()Ljava/lang/String;"); MultiPolygon_getTag = getGlobalJniEnv()->GetMethodID(MultiPolygonClass, "getTag", "()Ljava/lang/String;");
MultiPolygon_getValue = globalEnv()->GetMethodID(MultiPolygonClass, "getValue", "()Ljava/lang/String;"); MultiPolygon_getValue = getGlobalJniEnv()->GetMethodID(MultiPolygonClass, "getValue", "()Ljava/lang/String;");
MultiPolygon_getName = globalEnv()->GetMethodID(MultiPolygonClass, "getName", "(I)Ljava/lang/String;"); MultiPolygon_getName = getGlobalJniEnv()->GetMethodID(MultiPolygonClass, "getName", "(I)Ljava/lang/String;");
MultiPolygon_getLayer = globalEnv()->GetMethodID(MultiPolygonClass, "getLayer", "()I"); MultiPolygon_getLayer = getGlobalJniEnv()->GetMethodID(MultiPolygonClass, "getLayer", "()I");
MultiPolygon_getPoint31XTile = globalEnv()->GetMethodID(MultiPolygonClass, "getPoint31XTile", "(II)I"); MultiPolygon_getPoint31XTile = getGlobalJniEnv()->GetMethodID(MultiPolygonClass, "getPoint31XTile", "(II)I");
MultiPolygon_getPoint31YTile = globalEnv()->GetMethodID(MultiPolygonClass, "getPoint31YTile", "(II)I"); MultiPolygon_getPoint31YTile = getGlobalJniEnv()->GetMethodID(MultiPolygonClass, "getPoint31YTile", "(II)I");
MultiPolygon_getBoundsCount = globalEnv()->GetMethodID(MultiPolygonClass, "getBoundsCount", "()I"); MultiPolygon_getBoundsCount = getGlobalJniEnv()->GetMethodID(MultiPolygonClass, "getBoundsCount", "()I");
MultiPolygon_getBoundPointsCount = globalEnv()->GetMethodID(MultiPolygonClass, "getBoundPointsCount", "(I)I"); MultiPolygon_getBoundPointsCount = getGlobalJniEnv()->GetMethodID(MultiPolygonClass, "getBoundPointsCount", "(I)I");
BinaryMapDataObjectClass = globalRef(globalEnv()->FindClass("net/osmand/binary/BinaryMapDataObject")); BinaryMapDataObjectClass = findClass("net/osmand/binary/BinaryMapDataObject");
BinaryMapDataObject_getPointsLength = globalEnv()->GetMethodID(BinaryMapDataObjectClass, "getPointsLength", "()I"); BinaryMapDataObject_getPointsLength = getGlobalJniEnv()->GetMethodID(BinaryMapDataObjectClass, "getPointsLength", "()I");
BinaryMapDataObject_getPoint31YTile = globalEnv()->GetMethodID(BinaryMapDataObjectClass, "getPoint31YTile", "(I)I"); BinaryMapDataObject_getPoint31YTile = getGlobalJniEnv()->GetMethodID(BinaryMapDataObjectClass, "getPoint31YTile", "(I)I");
BinaryMapDataObject_getPoint31XTile = globalEnv()->GetMethodID(BinaryMapDataObjectClass, "getPoint31XTile", "(I)I"); BinaryMapDataObject_getPoint31XTile = getGlobalJniEnv()->GetMethodID(BinaryMapDataObjectClass, "getPoint31XTile", "(I)I");
BinaryMapDataObject_getHighwayAttributes = globalEnv()->GetMethodID(BinaryMapDataObjectClass, "getHighwayAttributes", "()I"); BinaryMapDataObject_getHighwayAttributes = getGlobalJniEnv()->GetMethodID(BinaryMapDataObjectClass, "getHighwayAttributes", "()I");
BinaryMapDataObject_getTypes = globalEnv()->GetMethodID(BinaryMapDataObjectClass, "getTypes", "()[I"); BinaryMapDataObject_getTypes = getGlobalJniEnv()->GetMethodID(BinaryMapDataObjectClass, "getTypes", "()[I");
BinaryMapDataObject_getName = globalEnv()->GetMethodID(BinaryMapDataObjectClass, "getName", "()Ljava/lang/String;"); BinaryMapDataObject_getName = getGlobalJniEnv()->GetMethodID(BinaryMapDataObjectClass, "getName", "()Ljava/lang/String;");
BinaryMapDataObject_getTagValue = globalEnv()->GetMethodID(BinaryMapDataObjectClass, "getTagValue", BinaryMapDataObject_getTagValue = getGlobalJniEnv()->GetMethodID(BinaryMapDataObjectClass, "getTagValue",
"(I)Lnet/osmand/binary/BinaryMapIndexReader$TagValuePair;"); "(I)Lnet/osmand/binary/BinaryMapIndexReader$TagValuePair;");
TagValuePairClass = globalRef(globalEnv()->FindClass("net/osmand/binary/BinaryMapIndexReader$TagValuePair")); TagValuePairClass = findClass("net/osmand/binary/BinaryMapIndexReader$TagValuePair");
TagValuePair_tag = globalEnv()->GetFieldID(TagValuePairClass, "tag", "Ljava/lang/String;"); TagValuePair_tag = getGlobalJniEnv()->GetFieldID(TagValuePairClass, "tag", "Ljava/lang/String;");
TagValuePair_value = globalEnv()->GetFieldID(TagValuePairClass, "value", "Ljava/lang/String;"); TagValuePair_value = getGlobalJniEnv()->GetFieldID(TagValuePairClass, "value", "Ljava/lang/String;");
} }
void unloadJniMapObjects() void unloadJniMapObjects()
{ {
globalEnv()->DeleteGlobalRef( MultiPolygonClass ); getGlobalJniEnv()->DeleteGlobalRef( MultiPolygonClass );
globalEnv()->DeleteGlobalRef( BinaryMapDataObjectClass ); getGlobalJniEnv()->DeleteGlobalRef( BinaryMapDataObjectClass );
globalEnv()->DeleteGlobalRef( TagValuePairClass ); getGlobalJniEnv()->DeleteGlobalRef( TagValuePairClass );
} }
int getNegativeWayLayer(int type) { int getNegativeWayLayer(int type) {

View file

@ -69,7 +69,7 @@ RenderingRuleProperty* RenderingRulesStorage::getProperty(const char* st) {
std::string RenderingRulesStorage::getDictionaryValue(int i) { std::string RenderingRulesStorage::getDictionaryValue(int i) {
if (i < 0) { if (i < 0) {
return EMPTY_STRING; return std::string();
} }
return dictionary.at(i); return dictionary.at(i);
} }
@ -79,54 +79,54 @@ int RenderingRulesStorage::getDictionaryValue(std::string s) {
} }
void RenderingRulesStorage::initDictionary() { void RenderingRulesStorage::initDictionary() {
jobject listDictionary = globalEnv()->GetObjectField(javaStorage, RenderingRulesStorageClass_dictionary); jobject listDictionary = getGlobalJniEnv()->GetObjectField(javaStorage, RenderingRulesStorageClass_dictionary);
uint sz = globalEnv()->CallIntMethod(listDictionary, List_size); uint sz = getGlobalJniEnv()->CallIntMethod(listDictionary, List_size);
uint i = 0; uint i = 0;
for (; i < sz; i++) { for (; i < sz; i++) {
jstring st = (jstring) globalEnv()->CallObjectMethod(listDictionary, List_get, i); jstring st = (jstring) getGlobalJniEnv()->CallObjectMethod(listDictionary, List_get, i);
// if(st != NULL) // if(st != NULL)
// { // {
const char* utf = globalEnv()->GetStringUTFChars(st, NULL); const char* utf = getGlobalJniEnv()->GetStringUTFChars(st, NULL);
std::string d = std::string(utf); std::string d = std::string(utf);
globalEnv()->ReleaseStringUTFChars(st, utf); getGlobalJniEnv()->ReleaseStringUTFChars(st, utf);
globalEnv()->DeleteLocalRef(st); getGlobalJniEnv()->DeleteLocalRef(st);
dictionary.push_back(d); dictionary.push_back(d);
dictionaryMap[d] = i; dictionaryMap[d] = i;
// } // }
} }
globalEnv()->DeleteLocalRef(listDictionary); getGlobalJniEnv()->DeleteLocalRef(listDictionary);
} }
void RenderingRulesStorage::initProperties() { void RenderingRulesStorage::initProperties() {
jobject props = globalEnv()->GetObjectField(javaStorage, RenderingRulesStorage_PROPS); jobject props = getGlobalJniEnv()->GetObjectField(javaStorage, RenderingRulesStorage_PROPS);
jobject listProps = globalEnv()->GetObjectField(props, RenderingRuleStorageProperties_rules); jobject listProps = getGlobalJniEnv()->GetObjectField(props, RenderingRuleStorageProperties_rules);
uint sz = globalEnv()->CallIntMethod(listProps, List_size); uint sz = getGlobalJniEnv()->CallIntMethod(listProps, List_size);
uint i = 0; uint i = 0;
for (; i < sz; i++) { for (; i < sz; i++) {
jobject rulePrope = globalEnv()->CallObjectMethod(listProps, List_get, i); jobject rulePrope = getGlobalJniEnv()->CallObjectMethod(listProps, List_get, i);
bool input = (globalEnv()->GetBooleanField(rulePrope, RenderingRuleProperty_input) == JNI_TRUE); bool input = (getGlobalJniEnv()->GetBooleanField(rulePrope, RenderingRuleProperty_input) == JNI_TRUE);
int type = globalEnv()->GetIntField(rulePrope, RenderingRuleProperty_type); int type = getGlobalJniEnv()->GetIntField(rulePrope, RenderingRuleProperty_type);
std::string name = getStringField(rulePrope, RenderingRuleProperty_attrName); std::string name = getStringField(rulePrope, RenderingRuleProperty_attrName);
RenderingRuleProperty* prop = new RenderingRuleProperty(type, input, name, i); RenderingRuleProperty* prop = new RenderingRuleProperty(type, input, name, i);
properties.push_back(*prop); properties.push_back(*prop);
propertyMap[name] = prop; propertyMap[name] = prop;
globalEnv()->DeleteLocalRef(rulePrope); getGlobalJniEnv()->DeleteLocalRef(rulePrope);
} }
globalEnv()->DeleteLocalRef(props); getGlobalJniEnv()->DeleteLocalRef(props);
globalEnv()->DeleteLocalRef(listProps); getGlobalJniEnv()->DeleteLocalRef(listProps);
} }
void RenderingRulesStorage::initRules() { void RenderingRulesStorage::initRules() {
for (int i = 1; i < SIZE_STATES; i++) { for (int i = 1; i < SIZE_STATES; i++) {
jobjectArray rules = (jobjectArray) globalEnv()->CallObjectMethod(javaStorage, RenderingRulesStorage_getRules, jobjectArray rules = (jobjectArray) getGlobalJniEnv()->CallObjectMethod(javaStorage, RenderingRulesStorage_getRules,
i); i);
jsize len = globalEnv()->GetArrayLength(rules); jsize len = getGlobalJniEnv()->GetArrayLength(rules);
for (jsize j = 0; j < len; j++) { for (jsize j = 0; j < len; j++) {
jobject rRule = globalEnv()->GetObjectArrayElement(rules, j); jobject rRule = getGlobalJniEnv()->GetObjectArrayElement(rules, j);
RenderingRule* rule = createRenderingRule(rRule); RenderingRule* rule = createRenderingRule(rRule);
globalEnv()->DeleteLocalRef(rRule); getGlobalJniEnv()->DeleteLocalRef(rRule);
if (rule != NULL) { if (rule != NULL) {
jsize psz = rule->properties.size(); jsize psz = rule->properties.size();
@ -145,69 +145,69 @@ void RenderingRulesStorage::initRules() {
} }
} }
} }
globalEnv()->DeleteLocalRef(rules); getGlobalJniEnv()->DeleteLocalRef(rules);
} }
} }
RenderingRule* RenderingRulesStorage::createRenderingRule(jobject rRule) { RenderingRule* RenderingRulesStorage::createRenderingRule(jobject rRule) {
RenderingRule* rule = new RenderingRule; RenderingRule* rule = new RenderingRule;
jobjectArray props = (jobjectArray) globalEnv()->GetObjectField(rRule, RenderingRule_properties); jobjectArray props = (jobjectArray) getGlobalJniEnv()->GetObjectField(rRule, RenderingRule_properties);
jintArray intProps = (jintArray) globalEnv()->GetObjectField(rRule, RenderingRule_intProperties); jintArray intProps = (jintArray) getGlobalJniEnv()->GetObjectField(rRule, RenderingRule_intProperties);
jfloatArray floatProps = (jfloatArray) globalEnv()->GetObjectField(rRule, RenderingRule_floatProperties); jfloatArray floatProps = (jfloatArray) getGlobalJniEnv()->GetObjectField(rRule, RenderingRule_floatProperties);
jobject ifChildren = globalEnv()->GetObjectField(rRule, RenderingRule_ifChildren); jobject ifChildren = getGlobalJniEnv()->GetObjectField(rRule, RenderingRule_ifChildren);
jobject ifElseChildren = globalEnv()->GetObjectField(rRule, RenderingRule_ifElseChildren); jobject ifElseChildren = getGlobalJniEnv()->GetObjectField(rRule, RenderingRule_ifElseChildren);
jsize sz = globalEnv()->GetArrayLength(props); jsize sz = getGlobalJniEnv()->GetArrayLength(props);
if (floatProps != NULL) { if (floatProps != NULL) {
jfloat* fe = globalEnv()->GetFloatArrayElements(floatProps, NULL); jfloat* fe = getGlobalJniEnv()->GetFloatArrayElements(floatProps, NULL);
for (int j = 0; j < sz; j++) { for (int j = 0; j < sz; j++) {
rule->floatProperties.push_back(fe[j]); rule->floatProperties.push_back(fe[j]);
} }
globalEnv()->ReleaseFloatArrayElements(floatProps, fe, JNI_ABORT); getGlobalJniEnv()->ReleaseFloatArrayElements(floatProps, fe, JNI_ABORT);
globalEnv()->DeleteLocalRef(floatProps); getGlobalJniEnv()->DeleteLocalRef(floatProps);
} else { } else {
rule->floatProperties.assign(sz, 0); rule->floatProperties.assign(sz, 0);
} }
if (intProps != NULL) { if (intProps != NULL) {
jint* ie = globalEnv()->GetIntArrayElements(intProps, NULL); jint* ie = getGlobalJniEnv()->GetIntArrayElements(intProps, NULL);
for (int j = 0; j < sz; j++) { for (int j = 0; j < sz; j++) {
rule->intProperties.push_back(ie[j]); rule->intProperties.push_back(ie[j]);
} }
globalEnv()->ReleaseIntArrayElements(intProps, ie, JNI_ABORT); getGlobalJniEnv()->ReleaseIntArrayElements(intProps, ie, JNI_ABORT);
globalEnv()->DeleteLocalRef(intProps); getGlobalJniEnv()->DeleteLocalRef(intProps);
} else { } else {
rule->intProperties.assign(sz, -1); rule->intProperties.assign(sz, -1);
} }
for (jsize i = 0; i < sz; i++) { for (jsize i = 0; i < sz; i++) {
jobject prop = globalEnv()->GetObjectArrayElement(props, i); jobject prop = getGlobalJniEnv()->GetObjectArrayElement(props, i);
std::string attr = getStringField(prop, RenderingRuleProperty_attrName); std::string attr = getStringField(prop, RenderingRuleProperty_attrName);
RenderingRuleProperty* p = getProperty(attr.c_str()); RenderingRuleProperty* p = getProperty(attr.c_str());
rule->properties.push_back(p); rule->properties.push_back(p);
globalEnv()->DeleteLocalRef(prop); getGlobalJniEnv()->DeleteLocalRef(prop);
} }
globalEnv()->DeleteLocalRef(props); getGlobalJniEnv()->DeleteLocalRef(props);
if (ifChildren != NULL) { if (ifChildren != NULL) {
sz = globalEnv()->CallIntMethod(ifChildren, List_size); sz = getGlobalJniEnv()->CallIntMethod(ifChildren, List_size);
for (jsize i = 0; i < sz; i++) { for (jsize i = 0; i < sz; i++) {
jobject o = globalEnv()->CallObjectMethod(ifChildren, List_get, i); jobject o = getGlobalJniEnv()->CallObjectMethod(ifChildren, List_get, i);
rule->ifChildren.push_back(*createRenderingRule(o)); rule->ifChildren.push_back(*createRenderingRule(o));
globalEnv()->DeleteLocalRef(o); getGlobalJniEnv()->DeleteLocalRef(o);
} }
globalEnv()->DeleteLocalRef(ifChildren); getGlobalJniEnv()->DeleteLocalRef(ifChildren);
} }
if (ifElseChildren != NULL) { if (ifElseChildren != NULL) {
sz = globalEnv()->CallIntMethod(ifElseChildren, List_size); sz = getGlobalJniEnv()->CallIntMethod(ifElseChildren, List_size);
for (jsize i = 0; i < sz; i++) { for (jsize i = 0; i < sz; i++) {
jobject o = globalEnv()->CallObjectMethod(ifElseChildren, List_get, i); jobject o = getGlobalJniEnv()->CallObjectMethod(ifElseChildren, List_get, i);
rule->ifElseChildren.push_back(*createRenderingRule(o)); rule->ifElseChildren.push_back(*createRenderingRule(o));
globalEnv()->DeleteLocalRef(o); getGlobalJniEnv()->DeleteLocalRef(o);
} }
globalEnv()->DeleteLocalRef(ifElseChildren); getGlobalJniEnv()->DeleteLocalRef(ifElseChildren);
} }
return rule; return rule;
@ -218,67 +218,67 @@ RenderingRulesStorage* defaultStorage = NULL;
void RenderingRuleSearchRequest::initObject(jobject rrs) { void RenderingRuleSearchRequest::initObject(jobject rrs) {
jsize sz; jsize sz;
jobjectArray oa = (jobjectArray) globalEnv()->GetObjectField(rrs, RenderingRuleSearchRequest_props); jobjectArray oa = (jobjectArray) getGlobalJniEnv()->GetObjectField(rrs, RenderingRuleSearchRequest_props);
sz = globalEnv()->GetArrayLength(oa); sz = getGlobalJniEnv()->GetArrayLength(oa);
std::vector<RenderingRuleProperty*> requestProps; std::vector<RenderingRuleProperty*> requestProps;
for (jsize i = 0; i < sz; i++) { for (jsize i = 0; i < sz; i++) {
jobject prop = globalEnv()->GetObjectArrayElement(oa, i); jobject prop = getGlobalJniEnv()->GetObjectArrayElement(oa, i);
std::string attr = getStringField(prop, RenderingRuleProperty_attrName); std::string attr = getStringField(prop, RenderingRuleProperty_attrName);
RenderingRuleProperty* p = storage->getProperty(attr.c_str()); RenderingRuleProperty* p = storage->getProperty(attr.c_str());
requestProps.push_back(p); requestProps.push_back(p);
globalEnv()->DeleteLocalRef(prop); getGlobalJniEnv()->DeleteLocalRef(prop);
} }
globalEnv()->DeleteLocalRef(oa); getGlobalJniEnv()->DeleteLocalRef(oa);
sz = storage->getPropertiesSize(); sz = storage->getPropertiesSize();
{ {
values = new int[sz]; values = new int[sz];
jintArray ia = (jintArray) globalEnv()->GetObjectField(rrs, RenderingRuleSearchRequest_values); jintArray ia = (jintArray) getGlobalJniEnv()->GetObjectField(rrs, RenderingRuleSearchRequest_values);
jint* ie = globalEnv()->GetIntArrayElements(ia, NULL); jint* ie = getGlobalJniEnv()->GetIntArrayElements(ia, NULL);
for (int i = 0; i < sz; i++) { for (int i = 0; i < sz; i++) {
values[requestProps.at(i)->id] = ie[i]; values[requestProps.at(i)->id] = ie[i];
} }
globalEnv()->ReleaseIntArrayElements(ia, ie, JNI_ABORT); getGlobalJniEnv()->ReleaseIntArrayElements(ia, ie, JNI_ABORT);
globalEnv()->DeleteLocalRef(ia); getGlobalJniEnv()->DeleteLocalRef(ia);
} }
{ {
fvalues = new float[sz]; fvalues = new float[sz];
jfloatArray ia = (jfloatArray) globalEnv()->GetObjectField(rrs, RenderingRuleSearchRequest_fvalues); jfloatArray ia = (jfloatArray) getGlobalJniEnv()->GetObjectField(rrs, RenderingRuleSearchRequest_fvalues);
jfloat* ie = globalEnv()->GetFloatArrayElements(ia, NULL); jfloat* ie = getGlobalJniEnv()->GetFloatArrayElements(ia, NULL);
for (int i = 0; i < sz; i++) { for (int i = 0; i < sz; i++) {
fvalues[requestProps.at(i)->id] = ie[i]; fvalues[requestProps.at(i)->id] = ie[i];
} }
globalEnv()->ReleaseFloatArrayElements(ia, ie, JNI_ABORT); getGlobalJniEnv()->ReleaseFloatArrayElements(ia, ie, JNI_ABORT);
globalEnv()->DeleteLocalRef(ia); getGlobalJniEnv()->DeleteLocalRef(ia);
} }
{ {
savedValues = new int[sz]; savedValues = new int[sz];
jintArray ia = (jintArray) globalEnv()->GetObjectField(rrs, RenderingRuleSearchRequest_values); jintArray ia = (jintArray) getGlobalJniEnv()->GetObjectField(rrs, RenderingRuleSearchRequest_values);
jint* ie = globalEnv()->GetIntArrayElements(ia, NULL); jint* ie = getGlobalJniEnv()->GetIntArrayElements(ia, NULL);
for (int i = 0; i < sz; i++) { for (int i = 0; i < sz; i++) {
savedValues[requestProps.at(i)->id] = ie[i]; savedValues[requestProps.at(i)->id] = ie[i];
} }
globalEnv()->ReleaseIntArrayElements(ia, ie, JNI_ABORT); getGlobalJniEnv()->ReleaseIntArrayElements(ia, ie, JNI_ABORT);
globalEnv()->DeleteLocalRef(ia); getGlobalJniEnv()->DeleteLocalRef(ia);
} }
{ {
savedFvalues = new float[sz]; savedFvalues = new float[sz];
jfloatArray ia = (jfloatArray) globalEnv()->GetObjectField(rrs, RenderingRuleSearchRequest_fvalues); jfloatArray ia = (jfloatArray) getGlobalJniEnv()->GetObjectField(rrs, RenderingRuleSearchRequest_fvalues);
jfloat* ie = globalEnv()->GetFloatArrayElements(ia, NULL); jfloat* ie = getGlobalJniEnv()->GetFloatArrayElements(ia, NULL);
for (int i = 0; i < sz; i++) { for (int i = 0; i < sz; i++) {
savedFvalues[requestProps.at(i)->id] = ie[i]; savedFvalues[requestProps.at(i)->id] = ie[i];
} }
globalEnv()->ReleaseFloatArrayElements(ia, ie, JNI_ABORT); getGlobalJniEnv()->ReleaseFloatArrayElements(ia, ie, JNI_ABORT);
globalEnv()->DeleteLocalRef(ia); getGlobalJniEnv()->DeleteLocalRef(ia);
} }
} }
extern "C" JNIEXPORT void JNICALL Java_net_osmand_plus_render_NativeOsmandLibrary_initRenderingRulesStorage(JNIEnv* ienv, extern "C" JNIEXPORT void JNICALL Java_net_osmand_plus_render_NativeOsmandLibrary_initRenderingRulesStorage(JNIEnv* ienv,
jobject obj, jobject storage) { jobject obj, jobject storage) {
setGlobalEnv(ienv); setGlobalJniEnv(ienv);
if (defaultStorage == NULL || defaultStorage->javaStorage != storage) { if (defaultStorage == NULL || defaultStorage->javaStorage != storage) {
// multi thread will not work? // multi thread will not work?
if (defaultStorage != NULL) { if (defaultStorage != NULL) {
@ -291,7 +291,7 @@ extern "C" JNIEXPORT void JNICALL Java_net_osmand_plus_render_NativeOsmandLibrar
RenderingRuleSearchRequest::RenderingRuleSearchRequest(jobject rrs) : RenderingRuleSearchRequest::RenderingRuleSearchRequest(jobject rrs) :
renderingRuleSearch(rrs) { renderingRuleSearch(rrs) {
jobject storage = globalEnv()->GetObjectField(rrs, RenderingRuleSearchRequest_storage); jobject storage = getGlobalJniEnv()->GetObjectField(rrs, RenderingRuleSearchRequest_storage);
if (defaultStorage == NULL || defaultStorage->javaStorage != storage) { if (defaultStorage == NULL || defaultStorage->javaStorage != storage) {
// multi thread will not work? // multi thread will not work?
if (defaultStorage != NULL) { if (defaultStorage != NULL) {
@ -299,7 +299,7 @@ RenderingRuleSearchRequest::RenderingRuleSearchRequest(jobject rrs) :
} }
defaultStorage = new RenderingRulesStorage(storage); defaultStorage = new RenderingRulesStorage(storage);
} }
globalEnv()->DeleteLocalRef(storage); getGlobalJniEnv()->DeleteLocalRef(storage);
this->storage = defaultStorage; this->storage = defaultStorage;
PROPS = new RenderingRulesStorageProperties(this->storage); PROPS = new RenderingRulesStorageProperties(this->storage);
initObject(rrs); initObject(rrs);
@ -330,7 +330,7 @@ int RenderingRuleSearchRequest::getIntPropertyValue(RenderingRuleProperty* prop,
std::string RenderingRuleSearchRequest::getStringPropertyValue(RenderingRuleProperty* prop) { std::string RenderingRuleSearchRequest::getStringPropertyValue(RenderingRuleProperty* prop) {
if (prop == NULL) { if (prop == NULL) {
return EMPTY_STRING; return std::string();
} }
int s = values[prop->id]; int s = values[prop->id];
return storage->getDictionaryValue(s); return storage->getDictionaryValue(s);
@ -486,59 +486,58 @@ RenderingRuleSearchRequest* initSearchRequest(jobject renderingRuleSearchRequest
return new RenderingRuleSearchRequest(renderingRuleSearchRequest); return new RenderingRuleSearchRequest(renderingRuleSearchRequest);
} }
void loadJNIRenderingRules() { void loadJniRenderingRules() {
RenderingRuleClass = globalRef(globalEnv()->FindClass("net/osmand/render/RenderingRule")); RenderingRuleClass = findClass("net/osmand/render/RenderingRule");
RenderingRule_properties = globalEnv()->GetFieldID(RenderingRuleClass, "properties", RenderingRule_properties = getGlobalJniEnv()->GetFieldID(RenderingRuleClass, "properties",
"[Lnet/osmand/render/RenderingRuleProperty;"); "[Lnet/osmand/render/RenderingRuleProperty;");
RenderingRule_intProperties = globalEnv()->GetFieldID(RenderingRuleClass, "intProperties", "[I"); RenderingRule_intProperties = getGlobalJniEnv()->GetFieldID(RenderingRuleClass, "intProperties", "[I");
RenderingRule_floatProperties = globalEnv()->GetFieldID(RenderingRuleClass, "floatProperties", "[F"); RenderingRule_floatProperties = getGlobalJniEnv()->GetFieldID(RenderingRuleClass, "floatProperties", "[F");
RenderingRule_ifElseChildren = globalEnv()->GetFieldID(RenderingRuleClass, "ifElseChildren", "Ljava/util/List;"); RenderingRule_ifElseChildren = getGlobalJniEnv()->GetFieldID(RenderingRuleClass, "ifElseChildren", "Ljava/util/List;");
RenderingRule_ifChildren = globalEnv()->GetFieldID(RenderingRuleClass, "ifChildren", "Ljava/util/List;"); RenderingRule_ifChildren = getGlobalJniEnv()->GetFieldID(RenderingRuleClass, "ifChildren", "Ljava/util/List;");
RenderingRuleStoragePropertiesClass = globalRef( RenderingRuleStoragePropertiesClass = findClass("net/osmand/render/RenderingRuleStorageProperties");
globalEnv()->FindClass("net/osmand/render/RenderingRuleStorageProperties")); RenderingRuleStorageProperties_rules = getGlobalJniEnv()->GetFieldID(RenderingRuleStoragePropertiesClass, "rules",
RenderingRuleStorageProperties_rules = globalEnv()->GetFieldID(RenderingRuleStoragePropertiesClass, "rules",
"Ljava/util/List;"); "Ljava/util/List;");
RenderingRulePropertyClass = globalRef(globalEnv()->FindClass("net/osmand/render/RenderingRuleProperty")); RenderingRulePropertyClass = findClass("net/osmand/render/RenderingRuleProperty");
RenderingRuleProperty_type = globalEnv()->GetFieldID(RenderingRulePropertyClass, "type", "I"); RenderingRuleProperty_type = getGlobalJniEnv()->GetFieldID(RenderingRulePropertyClass, "type", "I");
RenderingRuleProperty_input = globalEnv()->GetFieldID(RenderingRulePropertyClass, "input", "Z"); RenderingRuleProperty_input = getGlobalJniEnv()->GetFieldID(RenderingRulePropertyClass, "input", "Z");
RenderingRuleProperty_attrName = globalEnv()->GetFieldID(RenderingRulePropertyClass, "attrName", RenderingRuleProperty_attrName = getGlobalJniEnv()->GetFieldID(RenderingRulePropertyClass, "attrName",
"Ljava/lang/String;"); "Ljava/lang/String;");
RenderingRulesStorageClass = globalRef(globalEnv()->FindClass("net/osmand/render/RenderingRulesStorage")); RenderingRulesStorageClass = findClass("net/osmand/render/RenderingRulesStorage");
RenderingRulesStorageClass_dictionary = globalEnv()->GetFieldID(RenderingRulesStorageClass, "dictionary", RenderingRulesStorageClass_dictionary = getGlobalJniEnv()->GetFieldID(RenderingRulesStorageClass, "dictionary",
"Ljava/util/List;"); "Ljava/util/List;");
RenderingRulesStorage_PROPS = globalEnv()->GetFieldID(RenderingRulesStorageClass, "PROPS", RenderingRulesStorage_PROPS = getGlobalJniEnv()->GetFieldID(RenderingRulesStorageClass, "PROPS",
"Lnet/osmand/render/RenderingRuleStorageProperties;"); "Lnet/osmand/render/RenderingRuleStorageProperties;");
RenderingRulesStorage_getRules = globalEnv()->GetMethodID(RenderingRulesStorageClass, "getRules", RenderingRulesStorage_getRules = getGlobalJniEnv()->GetMethodID(RenderingRulesStorageClass, "getRules",
"(I)[Lnet/osmand/render/RenderingRule;"); "(I)[Lnet/osmand/render/RenderingRule;");
ListClass = globalRef(globalEnv()->FindClass("java/util/List")); ListClass = findClass("java/util/List");
List_size = globalEnv()->GetMethodID(ListClass, "size", "()I"); List_size = getGlobalJniEnv()->GetMethodID(ListClass, "size", "()I");
List_get = globalEnv()->GetMethodID(ListClass, "get", "(I)Ljava/lang/Object;"); List_get = getGlobalJniEnv()->GetMethodID(ListClass, "get", "(I)Ljava/lang/Object;");
RenderingRuleSearchRequestClass = globalRef(globalEnv()->FindClass("net/osmand/render/RenderingRuleSearchRequest")); RenderingRuleSearchRequestClass = findClass("net/osmand/render/RenderingRuleSearchRequest");
RenderingRuleSearchRequest_storage = globalEnv()->GetFieldID(RenderingRuleSearchRequestClass, "storage", RenderingRuleSearchRequest_storage = getGlobalJniEnv()->GetFieldID(RenderingRuleSearchRequestClass, "storage",
"Lnet/osmand/render/RenderingRulesStorage;"); "Lnet/osmand/render/RenderingRulesStorage;");
RenderingRuleSearchRequest_props = globalEnv()->GetFieldID(RenderingRuleSearchRequestClass, "props", RenderingRuleSearchRequest_props = getGlobalJniEnv()->GetFieldID(RenderingRuleSearchRequestClass, "props",
"[Lnet/osmand/render/RenderingRuleProperty;"); "[Lnet/osmand/render/RenderingRuleProperty;");
RenderingRuleSearchRequest_values = globalEnv()->GetFieldID(RenderingRuleSearchRequestClass, "values", "[I"); RenderingRuleSearchRequest_values = getGlobalJniEnv()->GetFieldID(RenderingRuleSearchRequestClass, "values", "[I");
RenderingRuleSearchRequest_fvalues = globalEnv()->GetFieldID(RenderingRuleSearchRequestClass, "fvalues", "[F"); RenderingRuleSearchRequest_fvalues = getGlobalJniEnv()->GetFieldID(RenderingRuleSearchRequestClass, "fvalues", "[F");
RenderingRuleSearchRequest_savedValues = globalEnv()->GetFieldID(RenderingRuleSearchRequestClass, "savedValues", RenderingRuleSearchRequest_savedValues = getGlobalJniEnv()->GetFieldID(RenderingRuleSearchRequestClass, "savedValues",
"[I"); "[I");
RenderingRuleSearchRequest_savedFvalues = globalEnv()->GetFieldID(RenderingRuleSearchRequestClass, "savedFvalues", RenderingRuleSearchRequest_savedFvalues = getGlobalJniEnv()->GetFieldID(RenderingRuleSearchRequestClass, "savedFvalues",
"[F"); "[F");
} }
void unloadJniRenderRules() { void unloadJniRenderRules() {
globalEnv()->DeleteGlobalRef(RenderingRuleSearchRequestClass); getGlobalJniEnv()->DeleteGlobalRef(RenderingRuleSearchRequestClass);
globalEnv()->DeleteGlobalRef(RenderingRuleClass); getGlobalJniEnv()->DeleteGlobalRef(RenderingRuleClass);
globalEnv()->DeleteGlobalRef(RenderingRulePropertyClass); getGlobalJniEnv()->DeleteGlobalRef(RenderingRulePropertyClass);
globalEnv()->DeleteGlobalRef(RenderingRuleStoragePropertiesClass); getGlobalJniEnv()->DeleteGlobalRef(RenderingRuleStoragePropertiesClass);
globalEnv()->DeleteGlobalRef(RenderingRulesStorageClass); getGlobalJniEnv()->DeleteGlobalRef(RenderingRulesStorageClass);
globalEnv()->DeleteGlobalRef(ListClass); getGlobalJniEnv()->DeleteGlobalRef(ListClass);
} }

View file

@ -1,38 +1,36 @@
#ifndef _OSMAND_RENDERING
#define _OSMAND_RENDERING
#include <jni.h> #include <jni.h>
#include <math.h>
#include <android/log.h> #include <android/log.h>
#include <android/bitmap.h> #include <android/bitmap.h>
#include <math.h>
#include <stdio.h> #include <stdio.h>
#include <vector> #include <vector>
#include <set> #include <set>
#include <hash_map> #include <hash_map>
#include <time.h> #include <time.h>
#include "SkTypes.h"
#include "SkBitmap.h" #include <SkTypes.h>
#include "SkColorFilter.h" #include <SkBitmap.h>
#include "SkShader.h" #include <SkColorFilter.h>
#include "SkBitmapProcShader.h" #include <SkShader.h>
#include "SkPathEffect.h" #include <SkBitmapProcShader.h>
#include "SkBlurDrawLooper.h" #include <SkPathEffect.h>
#include "SkDashPathEffect.h" #include <SkBlurDrawLooper.h>
#include "SkCanvas.h" #include <SkDashPathEffect.h>
#include "SkPaint.h" #include <SkCanvas.h>
#include "SkPath.h" #include <SkPaint.h>
#include <SkPath.h>
#include "common.h" #include "common.h"
#include "renderRules.h" #include "renderRules.h"
#include "textdraw.cpp" #include "textdraw.cpp"
#include "mapObjects.h" #include "mapObjects.h"
extern JNIEnv* globalEnv(); jclass jclass_JUnidecode;
char debugMessage[1024]; jmethodID jmethod_JUnidecode_unidecode;
jclass JUnidecodeClass;
jmethodID JUnidecode_unidecode;
void calcPoint(MapDataObject* mObj, jint ind, RenderingContext* rc) { void calcPoint(MapDataObject* mObj, jint ind, RenderingContext* rc)
{
rc->pointCount++; rc->pointCount++;
float tx = mObj->points.at(ind).first/ (rc->tileDivisor); float tx = mObj->points.at(ind).first/ (rc->tileDivisor);
@ -43,12 +41,12 @@ jmethodID JUnidecode_unidecode;
rc->calcX = rc->cosRotateTileSize * dTileX - rc->sinRotateTileSize * dTileY; rc->calcX = rc->cosRotateTileSize * dTileX - rc->sinRotateTileSize * dTileY;
rc->calcY = rc->sinRotateTileSize * dTileX + rc->cosRotateTileSize * dTileY; rc->calcY = rc->sinRotateTileSize * dTileX + rc->cosRotateTileSize * dTileY;
if (rc->calcX >= 0 && rc->calcX < rc->width && rc->calcY >= 0 && rc->calcY < rc->height) { if (rc->calcX >= 0 && rc->calcX < rc->width && rc->calcY >= 0 && rc->calcY < rc->height)
rc->pointInsideCount++; rc->pointInsideCount++;
} }
}
void calcMultipolygonPoint(int xt, int yt, jint ind, jint b, RenderingContext* rc) { void calcMultipolygonPoint(int xt, int yt, jint ind, jint b, RenderingContext* rc)
{
rc->pointCount++; rc->pointCount++;
float tx = xt/ (rc->tileDivisor); float tx = xt/ (rc->tileDivisor);
float ty = yt / (rc->tileDivisor); float ty = yt / (rc->tileDivisor);
@ -58,16 +56,16 @@ jmethodID JUnidecode_unidecode;
rc->calcX = rc->cosRotateTileSize * dTileX - rc->sinRotateTileSize * dTileY; rc->calcX = rc->cosRotateTileSize * dTileX - rc->sinRotateTileSize * dTileY;
rc->calcY = rc->sinRotateTileSize * dTileX + rc->cosRotateTileSize * dTileY; rc->calcY = rc->sinRotateTileSize * dTileX + rc->cosRotateTileSize * dTileY;
if (rc->calcX >= 0 && rc->calcX < rc->width && rc->calcY >= 0 && rc->calcY < rc->height) { if (rc->calcX >= 0 && rc->calcX < rc->width && rc->calcY >= 0 && rc->calcY < rc->height)
rc->pointInsideCount++; rc->pointInsideCount++;
} }
}
std::hash_map<std::string, SkPathEffect*> pathEffects; std::hash_map<std::string, SkPathEffect*> pathEffects;
SkPathEffect* getDashEffect(std::string input){ SkPathEffect* getDashEffect(std::string input)
if(pathEffects.find(input) != pathEffects.end()) { {
if(pathEffects.find(input) != pathEffects.end())
return pathEffects[input]; return pathEffects[input];
}
const char* chars = input.c_str(); const char* chars = input.c_str();
int i = 0; int i = 0;
char fval[10]; char fval[10];
@ -88,9 +86,14 @@ SkPathEffect* getDashEffect(std::string input){
{ {
// suppose it is a character // suppose it is a character
fval[flength++] = chars[i]; fval[flength++] = chars[i];
} else { }
if(flength > 0) { fval[flength] = 0; else
primFloats[floatLen++] = atof(fval); flength = 0;} {
if(flength > 0)
{
fval[flength] = 0;
primFloats[floatLen++] = atof(fval); flength = 0;
}
} }
} }
} }
@ -99,25 +102,28 @@ SkPathEffect* getDashEffect(std::string input){
return r; return r;
} }
int updatePaint(RenderingRuleSearchRequest* req, SkPaint* paint, int ind, int area, RenderingContext* rc)
{
int updatePaint(RenderingRuleSearchRequest* req, SkPaint* paint, int ind, int area, RenderingContext* rc) {
RenderingRuleProperty* rColor; RenderingRuleProperty* rColor;
RenderingRuleProperty* rStrokeW; RenderingRuleProperty* rStrokeW;
RenderingRuleProperty* rCap; RenderingRuleProperty* rCap;
RenderingRuleProperty* rPathEff; RenderingRuleProperty* rPathEff;
if (ind == 0) { if (ind == 0)
{
rColor = req->props()->R_COLOR; rColor = req->props()->R_COLOR;
rStrokeW = req->props()->R_STROKE_WIDTH; rStrokeW = req->props()->R_STROKE_WIDTH;
rCap = req->props()->R_CAP; rCap = req->props()->R_CAP;
rPathEff = req->props()->R_PATH_EFFECT; rPathEff = req->props()->R_PATH_EFFECT;
} else if (ind == 1) { }
else if (ind == 1)
{
rColor = req->props()->R_COLOR_2; rColor = req->props()->R_COLOR_2;
rStrokeW = req->props()->R_STROKE_WIDTH_2; rStrokeW = req->props()->R_STROKE_WIDTH_2;
rCap = req->props()->R_CAP_2; rCap = req->props()->R_CAP_2;
rPathEff = req->props()->R_PATH_EFFECT_2; rPathEff = req->props()->R_PATH_EFFECT_2;
} else { }
else
{
rColor = req->props()->R_COLOR_3; rColor = req->props()->R_COLOR_3;
rStrokeW = req->props()->R_STROKE_WIDTH_3; rStrokeW = req->props()->R_STROKE_WIDTH_3;
rCap = req->props()->R_CAP_3; rCap = req->props()->R_CAP_3;
@ -126,34 +132,38 @@ int updatePaint(RenderingRuleSearchRequest* req, SkPaint* paint, int ind, int ar
paint->setColorFilter(NULL); paint->setColorFilter(NULL);
paint->setShader(NULL); paint->setShader(NULL);
paint->setLooper(NULL); paint->setLooper(NULL);
if (area) { if (area)
{
paint->setStyle(SkPaint::kStrokeAndFill_Style); paint->setStyle(SkPaint::kStrokeAndFill_Style);
paint->setStrokeWidth(0); paint->setStrokeWidth(0);
} else {
float stroke = req->getFloatPropertyValue(rStrokeW);
if (!(stroke > 0)) {
return 0;
} }
else
{
float stroke = req->getFloatPropertyValue(rStrokeW);
if (!(stroke > 0))
return 0;
paint->setStyle(SkPaint::kStroke_Style); paint->setStyle(SkPaint::kStroke_Style);
paint->setStrokeWidth(stroke); paint->setStrokeWidth(stroke);
std::string cap = req->getStringPropertyValue(rCap); std::string cap = req->getStringPropertyValue(rCap);
std::string pathEff = req->getStringPropertyValue(rPathEff); std::string pathEff = req->getStringPropertyValue(rPathEff);
if (cap == "BUTT" || cap == "") { if (cap == "BUTT" || cap == "")
paint->setStrokeCap(SkPaint::kButt_Cap); paint->setStrokeCap(SkPaint::kButt_Cap);
} else if (cap == "ROUND") { else if (cap == "ROUND")
paint->setStrokeCap(SkPaint::kRound_Cap); paint->setStrokeCap(SkPaint::kRound_Cap);
} else if (cap == "SQUARE") { else if (cap == "SQUARE")
paint->setStrokeCap(SkPaint::kSquare_Cap); paint->setStrokeCap(SkPaint::kSquare_Cap);
} else { else
paint->setStrokeCap(SkPaint::kButt_Cap); paint->setStrokeCap(SkPaint::kButt_Cap);
}
if (pathEff.size() > 0) { if (pathEff.size() > 0)
{
SkPathEffect* p = getDashEffect(pathEff); SkPathEffect* p = getDashEffect(pathEff);
paint->setPathEffect(p); paint->setPathEffect(p);
} else { }
else
{
paint->setPathEffect(NULL); paint->setPathEffect(NULL);
} }
} }
@ -161,62 +171,70 @@ int updatePaint(RenderingRuleSearchRequest* req, SkPaint* paint, int ind, int ar
int color = req->getIntPropertyValue(rColor); int color = req->getIntPropertyValue(rColor);
paint->setColor(color); paint->setColor(color);
if (ind == 0)
if (ind == 0) { {
std::string shader = req->getStringPropertyValue(req->props()->R_SHADER); std::string shader = req->getStringPropertyValue(req->props()->R_SHADER);
if (shader.size() > 0) { if (shader.size() > 0)
{
SkBitmap* bmp = getCachedBitmap(rc, shader); SkBitmap* bmp = getCachedBitmap(rc, shader);
if (bmp != NULL) { if (bmp != NULL)
paint->setShader(new SkBitmapProcShader(*bmp, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode))->unref(); paint->setShader(new SkBitmapProcShader(*bmp, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode))->unref();
} }
} }
}
// do not check shadow color here // do not check shadow color here
if (rc->shadowRenderingMode == 1 && ind == 0) { if (rc->shadowRenderingMode == 1 && ind == 0)
{
int shadowColor = req->getIntPropertyValue(req->props()->R_SHADOW_COLOR); int shadowColor = req->getIntPropertyValue(req->props()->R_SHADOW_COLOR);
int shadowLayer = req->getIntPropertyValue(req->props()->R_SHADOW_RADIUS); int shadowLayer = req->getIntPropertyValue(req->props()->R_SHADOW_RADIUS);
if (shadowColor == 0) { if (shadowColor == 0)
shadowLayer = 0; shadowLayer = 0;
}
if (shadowLayer > 0) { if (shadowLayer > 0)
paint->setLooper(new SkBlurDrawLooper(shadowLayer, 0, 0, shadowColor))->unref(); paint->setLooper(new SkBlurDrawLooper(shadowLayer, 0, 0, shadowColor))->unref();
} }
}
return 1; return 1;
} }
void drawPointText(RenderingRuleSearchRequest* req, RenderingContext* rc, std::string tag, std::string value, void drawPointText(RenderingRuleSearchRequest* req, RenderingContext* rc, std::string tag, std::string value, float xText, float yText, std::string name, SkPath* path)
float xText, float yText, std::string name, SkPath* path)
{ {
if(rc->useEnglishNames){ if(rc->useEnglishNames)
jstring n = globalEnv()->NewStringUTF(name.c_str()); {
name = getString((jstring) globalEnv()->CallStaticObjectMethod(JUnidecodeClass, JUnidecode_unidecode, n)); jstring n = getGlobalJniEnv()->NewStringUTF(name.c_str());
globalEnv()->DeleteLocalRef(n); name = getString((jstring) getGlobalJniEnv()->CallStaticObjectMethod(jclass_JUnidecode, jmethod_JUnidecode_unidecode, n));
getGlobalJniEnv()->DeleteLocalRef(n);
} }
if (name.at(0) == REF_CHAR) {
if (name.at(0) == REF_CHAR)
{
std::string ref = name.substr(1); std::string ref = name.substr(1);
name = ""; //$NON-NLS-1$ name = "";
for (uint k = 0; k < ref.length(); k++) { for (uint k = 0; k < ref.length(); k++)
if (ref.at(k) == REF_CHAR) { {
if (k < ref.length() - 1) { if (ref.at(k) == REF_CHAR)
{
if (k < ref.length() - 1)
{
name = ref.substr(k + 1); name = ref.substr(k + 1);
} }
ref = ref.substr(0, k); ref = ref.substr(0, k);
break; break;
} }
} }
if (ref.length() > 0) { if (ref.length() > 0)
{
req->setInitialTagValueZoom(tag, value, rc->zoom); req->setInitialTagValueZoom(tag, value, rc->zoom);
req->setIntFilter(req->props()->R_TEXT_LENGTH, ref.length()); req->setIntFilter(req->props()->R_TEXT_LENGTH, ref.length());
req->setBooleanFilter(req->props()->R_REF, true); req->setBooleanFilter(req->props()->R_REF, true);
if (req->searchRule(RenderingRulesStorage::TEXT_RULES)) { if (req->searchRule(RenderingRulesStorage::TEXT_RULES))
if (req->getIntPropertyValue(req->props()->R_TEXT_SIZE) > 0) { {
if (req->getIntPropertyValue(req->props()->R_TEXT_SIZE) > 0)
{
TextDrawInfo* text = new TextDrawInfo(ref); TextDrawInfo* text = new TextDrawInfo(ref);
fillTextProperties(text, req, xText, yText); fillTextProperties(text, req, xText, yText);
if (path != NULL) { if (path != NULL)
text->path = new SkPath(*path); text->path = new SkPath(*path);
}
rc->textToDraw.push_back(text); rc->textToDraw.push_back(text);
} }
} }
@ -227,26 +245,26 @@ void drawPointText(RenderingRuleSearchRequest* req, RenderingContext* rc, std::s
req->setIntFilter(req->props()->R_TEXT_LENGTH, name.length()); req->setIntFilter(req->props()->R_TEXT_LENGTH, name.length());
req->setBooleanFilter(req->props()->R_REF, false); req->setBooleanFilter(req->props()->R_REF, false);
if (req->searchRule(RenderingRulesStorage::TEXT_RULES) && if (req->searchRule(RenderingRulesStorage::TEXT_RULES) &&
req->getIntPropertyValue(req->props()->R_TEXT_SIZE) > 0) { req->getIntPropertyValue(req->props()->R_TEXT_SIZE) > 0)
{
TextDrawInfo* info = new TextDrawInfo(name); TextDrawInfo* info = new TextDrawInfo(name);
info->drawOnPath = (path != NULL) && (req->getIntPropertyValue(req->props()->R_TEXT_ON_PATH, 0) > 0); info->drawOnPath = (path != NULL) && (req->getIntPropertyValue(req->props()->R_TEXT_ON_PATH, 0) > 0);
if (path != NULL) { if (path != NULL)
info->path = new SkPath(*path); info->path = new SkPath(*path);
}
fillTextProperties(info, req, xText, yText); fillTextProperties(info, req, xText, yText);
rc->textToDraw.push_back(info); rc->textToDraw.push_back(info);
} }
} }
void drawPolylineShadow(SkCanvas* cv, SkPaint* paint, RenderingContext* rc, SkPath* path, int shadowColor, int shadowRadius)
void drawPolylineShadow(SkCanvas* cv, SkPaint* paint, RenderingContext* rc, SkPath* path, int shadowColor, {
int shadowRadius) {
// blurred shadows // blurred shadows
if (rc->shadowRenderingMode == 2 && shadowRadius > 0) { if (rc->shadowRenderingMode == 2 && shadowRadius > 0) {
// simply draw shadow? difference from option 3 ? // simply draw shadow? difference from option 3 ?
// paint->setColor(0xffffffff); // paint->setColor(0xffffffff);
paint->setLooper(new SkBlurDrawLooper(shadowRadius, 0, 0, shadowColor))->unref(); paint->setLooper(new SkBlurDrawLooper(shadowRadius, 0, 0, shadowColor))->unref();
NAT_COUNT(rc, cv->drawPath(*path, *paint)); PROFILE_NATIVE_OPERATION(rc, cv->drawPath(*path, *paint));
} }
// option shadow = 3 with solid border // option shadow = 3 with solid border
@ -256,7 +274,7 @@ void drawPolylineShadow(SkCanvas* cv, SkPaint* paint, RenderingContext* rc, SkPa
// paint->setColor(0xffbababa); // paint->setColor(0xffbababa);
paint->setColorFilter(SkColorFilter::CreateModeFilter(shadowColor, SkXfermode::kSrcIn_Mode))->unref(); paint->setColorFilter(SkColorFilter::CreateModeFilter(shadowColor, SkXfermode::kSrcIn_Mode))->unref();
// paint->setColor(shadowColor); // paint->setColor(shadowColor);
NAT_COUNT(rc, cv->drawPath(*path, *paint)); PROFILE_NATIVE_OPERATION(rc, cv->drawPath(*path, *paint));
} }
} }
@ -297,7 +315,7 @@ void drawOneWayPaints(RenderingContext* rc, SkCanvas* cv, SkPath* p) {
} }
for (size_t i = 0; i < oneWayPaints.size(); i++) { for (size_t i = 0; i < oneWayPaints.size(); i++) {
NAT_COUNT(rc, cv->drawPath(*p, oneWayPaints.at(i))); PROFILE_NATIVE_OPERATION(rc, cv->drawPath(*p, oneWayPaints.at(i)));
} }
} }
@ -352,11 +370,11 @@ void drawPolyline(MapDataObject* mObj, RenderingRuleSearchRequest* req, SkCanvas
int shadowRadius = req->getIntPropertyValue(req->props()->R_SHADOW_RADIUS); int shadowRadius = req->getIntPropertyValue(req->props()->R_SHADOW_RADIUS);
drawPolylineShadow(cv, paint, rc, &path, shadowColor, shadowRadius); drawPolylineShadow(cv, paint, rc, &path, shadowColor, shadowRadius);
} else { } else {
NAT_COUNT(rc, cv->drawPath(path, *paint)); PROFILE_NATIVE_OPERATION(rc, cv->drawPath(path, *paint));
if (updatePaint(req, paint, 1, 0, rc)) { if (updatePaint(req, paint, 1, 0, rc)) {
NAT_COUNT(rc, cv->drawPath(path, *paint)); PROFILE_NATIVE_OPERATION(rc, cv->drawPath(path, *paint));
if (updatePaint(req, paint, 2, 0, rc)) { if (updatePaint(req, paint, 2, 0, rc)) {
NAT_COUNT(rc, cv->drawPath(path, *paint)); PROFILE_NATIVE_OPERATION(rc, cv->drawPath(path, *paint));
} }
} }
if (oneway && !drawOnlyShadow) { if (oneway && !drawOnlyShadow) {
@ -409,15 +427,15 @@ void drawMultiPolygon(MultiPolygonObject* mapObject,RenderingRuleSearchRequest*
} }
} }
NAT_COUNT(rc, cv->drawPath(path, *paint)); PROFILE_NATIVE_OPERATION(rc, cv->drawPath(path, *paint));
// for test purpose // for test purpose
// paint->setStyle(SkPaint::kStroke_Style); // paint->setStyle(SkPaint::kStroke_Style);
// paint->setStrokeWidth(2); // paint->setStrokeWidth(2);
// paint->setPathEffect(NULL); // paint->setPathEffect(NULL);
// paint->setColor(BLACK_COLOR); // paint->setColor(BLACK_COLOR);
// NAT_COUNT(rc, cv->drawPath(path, *paint)); // PROFILE_NATIVE_OPERATION(rc, cv->drawPath(path, *paint));
if (updatePaint(req, paint, 1, 0, rc)) { if (updatePaint(req, paint, 1, 0, rc)) {
NAT_COUNT(rc, cv->drawPath(path, *paint)); PROFILE_NATIVE_OPERATION(rc, cv->drawPath(path, *paint));
} }
} }
@ -454,9 +472,9 @@ void drawPolygon(MapDataObject* mObj, RenderingRuleSearchRequest* req, SkCanvas*
yText += rc->calcY; yText += rc->calcY;
} }
NAT_COUNT(rc, cv->drawPath(path, *paint)); PROFILE_NATIVE_OPERATION(rc, cv->drawPath(path, *paint));
if (updatePaint(req, paint, 1, 0, rc)) { if (updatePaint(req, paint, 1, 0, rc)) {
NAT_COUNT(rc, cv->drawPath(path, *paint)); PROFILE_NATIVE_OPERATION(rc, cv->drawPath(path, *paint));
} }
std::string name = mObj->name; std::string name = mObj->name;
if (name.length() > 0) { if (name.length() > 0) {
@ -474,7 +492,7 @@ void drawPoint(MapDataObject* mObj, RenderingRuleSearchRequest* req, SkCanvas* c
req->searchRule(1); req->searchRule(1);
std::string resId = req->getStringPropertyValue(req-> props()-> R_ICON); std::string resId = req->getStringPropertyValue(req-> props()-> R_ICON);
SkBitmap* bmp = getCachedBitmap(rc, resId); SkBitmap* bmp = getCachedBitmap(rc, resId);
std::string name = EMPTY_STRING; std::string name;
if (renderText) { if (renderText) {
name = mObj->name; name = mObj->name;
} }
@ -532,7 +550,7 @@ void drawObject(RenderingContext* rc, BaseMapDataObject* mapObject, SkCanvas* cv
} else if (t == 2) { } else if (t == 2) {
// polyline // polyline
int layer = getNegativeWayLayer(mainType); int layer = getNegativeWayLayer(mainType);
// __android_log_print(ANDROID_LOG_WARN, "net.osmand", "Draw polyline"); // __android_log_print(ANDROID_LOG_WARN, LOG_TAG, "Draw polyline");
drawPolyline(mObj, req, cv, paint, rc, pair, layer, drawOnlyShadow); drawPolyline(mObj, req, cv, paint, rc, pair, layer, drawOnlyShadow);
} else if (t == 3 && !drawOnlyShadow) { } else if (t == 3 && !drawOnlyShadow) {
// polygon // polygon
@ -568,7 +586,7 @@ void drawIconsOverCanvas(RenderingContext* rc, SkCanvas* canvas)
if (((ind >> b) & 1) == 0) { if (((ind >> b) & 1) == 0) {
alreadyDrawnIcons[i] = ind | (1 << b); alreadyDrawnIcons[i] = ind | (1 << b);
SkBitmap* ico = icon.bmp; SkBitmap* ico = icon.bmp;
NAT_COUNT(rc, canvas->drawBitmap(*ico, icon.x - ico->width() / 2, icon.y - ico->height() / 2, &p)); PROFILE_NATIVE_OPERATION(rc, canvas->drawBitmap(*ico, icon.x - ico->width() / 2, icon.y - ico->height() / 2, &p));
} }
} }
if(rc->interrupted()){ if(rc->interrupted()){
@ -690,51 +708,43 @@ void doRendering(std::vector <BaseMapDataObject* > mapDataObjects, SkCanvas* can
rc->textRendering.pause(); rc->textRendering.pause();
} }
void loadJNIRendering(){ void loadJniRendering()
JUnidecodeClass = globalRef(globalEnv()->FindClass("net/sf/junidecode/Junidecode")); {
JUnidecode_unidecode = globalEnv()->GetStaticMethodID(JUnidecodeClass, "unidecode", "(Ljava/lang/String;)Ljava/lang/String;"); jclass_JUnidecode = findClass("net/sf/junidecode/Junidecode");
jmethod_JUnidecode_unidecode = getGlobalJniEnv()->GetStaticMethodID(jclass_JUnidecode, "unidecode", "(Ljava/lang/String;)Ljava/lang/String;");
} }
#ifdef __cplusplus extern "C" JNIEXPORT jobject JNICALL Java_net_osmand_plus_render_NativeOsmandLibrary_generateRendering_1Direct( JNIEnv* ienv, jobject obj,
extern "C" {
#endif
JNIEXPORT jobject JNICALL Java_net_osmand_plus_render_NativeOsmandLibrary_generateRendering_1Direct( JNIEnv* ienv, jobject obj,
jobject renderingContext, jint searchResult, jobject renderingContext, jint searchResult,
jobject targetBitmap, jobject targetBitmap,
jboolean useEnglishNames, jobject renderingRuleSearchRequest, jint defaultColor) { jboolean useEnglishNames, jobject renderingRuleSearchRequest, jint defaultColor) {
setGlobalEnv(ienv); setGlobalJniEnv(ienv);
// Gain information about bitmap // Gain information about bitmap
AndroidBitmapInfo bitmapInfo; AndroidBitmapInfo bitmapInfo;
if(AndroidBitmap_getInfo(ienv, targetBitmap, &bitmapInfo) != ANDROID_BITMAP_RESUT_SUCCESS) { if(AndroidBitmap_getInfo(getGlobalJniEnv(), targetBitmap, &bitmapInfo) != ANDROID_BITMAP_RESUT_SUCCESS)
__android_log_print(ANDROID_LOG_ERROR, "net.osmand", "Failed to execute AndroidBitmap_getInfo"); __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "Failed to execute AndroidBitmap_getInfo");
}
sprintf(debugMessage, "Creating SkBitmap in native w:%d h:%d s:%d f:%d!", bitmapInfo.width, bitmapInfo.height, bitmapInfo.stride, bitmapInfo.format); __android_log_print(ANDROID_LOG_WARN, LOG_TAG, "Creating SkBitmap in native w:%d h:%d s:%d f:%d!", bitmapInfo.width, bitmapInfo.height, bitmapInfo.stride, bitmapInfo.format);
__android_log_print(ANDROID_LOG_WARN, "net.osmand", debugMessage);
SkBitmap* bitmap = new SkBitmap(); SkBitmap* bitmap = new SkBitmap();
if(bitmapInfo.format == ANDROID_BITMAP_FORMAT_RGBA_8888) { if(bitmapInfo.format == ANDROID_BITMAP_FORMAT_RGBA_8888) {
int rowBytes = bitmapInfo.stride; int rowBytes = bitmapInfo.stride;
sprintf(debugMessage, "Row bytes for RGBA_8888 is %d", rowBytes); __android_log_print(ANDROID_LOG_WARN, LOG_TAG, "Row bytes for RGBA_8888 is %d", rowBytes);
__android_log_print(ANDROID_LOG_WARN, "net.osmand", debugMessage);
bitmap->setConfig(SkBitmap::kARGB_8888_Config, bitmapInfo.width, bitmapInfo.height, rowBytes); bitmap->setConfig(SkBitmap::kARGB_8888_Config, bitmapInfo.width, bitmapInfo.height, rowBytes);
} else if(bitmapInfo.format == ANDROID_BITMAP_FORMAT_RGB_565) { } else if(bitmapInfo.format == ANDROID_BITMAP_FORMAT_RGB_565) {
int rowBytes = bitmapInfo.stride; int rowBytes = bitmapInfo.stride;
sprintf(debugMessage, "Row bytes for RGB_565 is %d", rowBytes); __android_log_print(ANDROID_LOG_WARN, LOG_TAG, "Row bytes for RGB_565 is %d", rowBytes);
__android_log_print(ANDROID_LOG_WARN, "net.osmand", debugMessage);
bitmap->setConfig(SkBitmap::kRGB_565_Config, bitmapInfo.width, bitmapInfo.height, rowBytes); bitmap->setConfig(SkBitmap::kRGB_565_Config, bitmapInfo.width, bitmapInfo.height, rowBytes);
} else { } else {
__android_log_print(ANDROID_LOG_ERROR, "net.osmand", "Unknown target bitmap format"); __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "Unknown target bitmap format");
} }
void* lockedBitmapData = NULL; void* lockedBitmapData = NULL;
if(AndroidBitmap_lockPixels(ienv, targetBitmap, &lockedBitmapData) != ANDROID_BITMAP_RESUT_SUCCESS || !lockedBitmapData) { if(AndroidBitmap_lockPixels(getGlobalJniEnv(), targetBitmap, &lockedBitmapData) != ANDROID_BITMAP_RESUT_SUCCESS || !lockedBitmapData) {
__android_log_print(ANDROID_LOG_ERROR, "net.osmand", "Failed to execute AndroidBitmap_lockPixels"); __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "Failed to execute AndroidBitmap_lockPixels");
} }
sprintf(debugMessage, "Locked %d bytes at %p", bitmap->getSize(), lockedBitmapData); __android_log_print(ANDROID_LOG_WARN, LOG_TAG, "Locked %d bytes at %p", bitmap->getSize(), lockedBitmapData);
__android_log_print(ANDROID_LOG_WARN, "net.osmand", debugMessage);
bitmap->setPixels(lockedBitmapData); bitmap->setPixels(lockedBitmapData);
@ -743,18 +753,18 @@ JNIEXPORT jobject JNICALL Java_net_osmand_plus_render_NativeOsmandLibrary_genera
SkPaint* paint = new SkPaint; SkPaint* paint = new SkPaint;
paint->setAntiAlias(true); paint->setAntiAlias(true);
__android_log_print(ANDROID_LOG_WARN, "net.osmand", "Initializing rendering"); __android_log_print(ANDROID_LOG_WARN, LOG_TAG, "Initializing rendering");
watcher initObjects; ElapsedTimer initObjects;
initObjects.start(); initObjects.start();
RenderingRuleSearchRequest* req = initSearchRequest(renderingRuleSearchRequest); RenderingRuleSearchRequest* req = initSearchRequest(renderingRuleSearchRequest);
RenderingContext rc; RenderingContext rc;
copyRenderingContext(renderingContext, &rc); pullFromJavaRenderingContext(renderingContext, &rc);
rc.useEnglishNames = useEnglishNames; rc.useEnglishNames = useEnglishNames;
SearchResult* result = ((SearchResult*) searchResult); SearchResult* result = ((SearchResult*) searchResult);
// std::vector <BaseMapDataObject* > mapDataObjects = marshalObjects(binaryMapDataObjects); // std::vector <BaseMapDataObject* > mapDataObjects = marshalObjects(binaryMapDataObjects);
__android_log_print(ANDROID_LOG_WARN, "net.osmand", "Rendering image"); __android_log_print(ANDROID_LOG_WARN, LOG_TAG, "Rendering image");
initObjects.pause(); initObjects.pause();
@ -765,10 +775,10 @@ JNIEXPORT jobject JNICALL Java_net_osmand_plus_render_NativeOsmandLibrary_genera
} }
rc.nativeOperations.pause(); rc.nativeOperations.pause();
mergeRenderingContext(renderingContext, &rc); pushToJavaRenderingContext(renderingContext, &rc);
__android_log_print(ANDROID_LOG_WARN, "net.osmand", "End Rendering image"); __android_log_print(ANDROID_LOG_WARN, LOG_TAG, "End Rendering image");
if(AndroidBitmap_unlockPixels(ienv, targetBitmap) != ANDROID_BITMAP_RESUT_SUCCESS) { if(AndroidBitmap_unlockPixels(ienv, targetBitmap) != ANDROID_BITMAP_RESUT_SUCCESS) {
__android_log_print(ANDROID_LOG_ERROR, "net.osmand", "Failed to execute AndroidBitmap_unlockPixels"); __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "Failed to execute AndroidBitmap_unlockPixels");
} }
// delete variables // delete variables
@ -778,43 +788,31 @@ JNIEXPORT jobject JNICALL Java_net_osmand_plus_render_NativeOsmandLibrary_genera
delete bitmap; delete bitmap;
// deleteObjects(mapDataObjects); // deleteObjects(mapDataObjects);
jclass resultClass = ienv->FindClass("net/osmand/plus/render/NativeOsmandLibrary$RenderingGenerationResult"); jclass resultClass = findClass("net/osmand/plus/render/NativeOsmandLibrary$RenderingGenerationResult");
if(!resultClass)
resultClass = ienv->FindClass("net/osmand/render/NativeOsmandLibrary$RenderingGenerationResult");
sprintf(debugMessage, "Result class = %p", resultClass);
__android_log_print(ANDROID_LOG_WARN, "net.osmand", debugMessage);
jmethodID resultClassCtorId = ienv->GetMethodID(resultClass, "<init>", "(Ljava/nio/ByteBuffer;Ljava/lang/String;)V"); jmethodID resultClassCtorId = getGlobalJniEnv()->GetMethodID(resultClass, "<init>", "(Ljava/nio/ByteBuffer;)V");
sprintf(debugMessage, "Result class ctor = %p", resultClassCtorId);
__android_log_print(ANDROID_LOG_WARN, "net.osmand", debugMessage);
#ifdef DEBUG_NAT_OPERATIONS #ifdef DEBUG_NAT_OPERATIONS
sprintf(debugMessage, "Native ok (init %d, native op %d) ", initObjects.getElapsedTime(), rc.nativeOperations.getElapsedTime()); __android_log_print(ANDROID_LOG_WARN, LOG_TAG,"Native ok (init %d, native op %d) ", initObjects.getElapsedTime(), rc.nativeOperations.getElapsedTime());
#else #else
sprintf(debugMessage, "Native ok (init %d, rendering %d) ", initObjects.getElapsedTime(), rc.nativeOperations.getElapsedTime()); __android_log_print(ANDROID_LOG_WARN, LOG_TAG, "Native ok (init %d, rendering %d) ", initObjects.getElapsedTime(), rc.nativeOperations.getElapsedTime());
#endif #endif
__android_log_print(ANDROID_LOG_WARN, "net.osmand", debugMessage);
// Allocate ctor paramters
jstring message = globalEnv()->NewStringUTF(debugMessage);
/* Construct a result object */ /* Construct a result object */
jobject resultObject = ienv->NewObject(resultClass, resultClassCtorId, NULL, message); jobject resultObject = getGlobalJniEnv()->NewObject(resultClass, resultClassCtorId, NULL);
return resultObject; return resultObject;
} }
void* bitmapData = NULL; void* bitmapData = NULL;
size_t bitmapDataSize = 0; size_t bitmapDataSize = 0;
JNIEXPORT jobject JNICALL Java_net_osmand_plus_render_NativeOsmandLibrary_generateRendering_1Indirect( JNIEnv* ienv, jobject obj, extern "C" JNIEXPORT jobject JNICALL Java_net_osmand_plus_render_NativeOsmandLibrary_generateRendering_1Indirect( JNIEnv* ienv, jobject obj,
jobject renderingContext, jint searchResult, jobject renderingContext, jint searchResult,
jint requestedBitmapWidth, jint requestedBitmapHeight, jint rowBytes, jboolean isTransparent, jint requestedBitmapWidth, jint requestedBitmapHeight, jint rowBytes, jboolean isTransparent,
jboolean useEnglishNames, jobject renderingRuleSearchRequest, jint defaultColor) { jboolean useEnglishNames, jobject renderingRuleSearchRequest, jint defaultColor) {
setGlobalEnv(ienv); setGlobalJniEnv(ienv);
sprintf(debugMessage, "Creating SkBitmap in native w:%d h:%d!", requestedBitmapWidth, requestedBitmapHeight); __android_log_print(ANDROID_LOG_WARN, LOG_TAG, "Creating SkBitmap in native w:%d h:%d!", requestedBitmapWidth, requestedBitmapHeight);
__android_log_print(ANDROID_LOG_WARN, "net.osmand", debugMessage);
SkBitmap* bitmap = new SkBitmap(); SkBitmap* bitmap = new SkBitmap();
if(isTransparent == JNI_TRUE) if(isTransparent == JNI_TRUE)
@ -831,8 +829,7 @@ JNIEXPORT jobject JNICALL Java_net_osmand_plus_render_NativeOsmandLibrary_genera
bitmapDataSize = bitmap->getSize(); bitmapDataSize = bitmap->getSize();
bitmapData = malloc(bitmapDataSize); bitmapData = malloc(bitmapDataSize);
sprintf(debugMessage, "Allocated %d bytes at %p", bitmapDataSize, bitmapData); __android_log_print(ANDROID_LOG_WARN, LOG_TAG, "Allocated %d bytes at %p", bitmapDataSize, bitmapData);
__android_log_print(ANDROID_LOG_WARN, "net.osmand", debugMessage);
} }
bitmap->setPixels(bitmapData); bitmap->setPixels(bitmapData);
@ -842,18 +839,18 @@ JNIEXPORT jobject JNICALL Java_net_osmand_plus_render_NativeOsmandLibrary_genera
SkPaint* paint = new SkPaint; SkPaint* paint = new SkPaint;
paint->setAntiAlias(true); paint->setAntiAlias(true);
__android_log_print(ANDROID_LOG_WARN, "net.osmand", "Initializing rendering"); __android_log_print(ANDROID_LOG_WARN, LOG_TAG, "Initializing rendering");
watcher initObjects; ElapsedTimer initObjects;
initObjects.start(); initObjects.start();
RenderingRuleSearchRequest* req = initSearchRequest(renderingRuleSearchRequest); RenderingRuleSearchRequest* req = initSearchRequest(renderingRuleSearchRequest);
RenderingContext rc; RenderingContext rc;
copyRenderingContext(renderingContext, &rc); pullFromJavaRenderingContext(renderingContext, &rc);
rc.useEnglishNames = useEnglishNames; rc.useEnglishNames = useEnglishNames;
SearchResult* result = ((SearchResult*) searchResult); SearchResult* result = ((SearchResult*) searchResult);
// std::vector <BaseMapDataObject* > mapDataObjects = marshalObjects(binaryMapDataObjects); // std::vector <BaseMapDataObject* > mapDataObjects = marshalObjects(binaryMapDataObjects);
__android_log_print(ANDROID_LOG_WARN, "net.osmand", "Rendering image"); __android_log_print(ANDROID_LOG_WARN, LOG_TAG, "Rendering image");
initObjects.pause(); initObjects.pause();
@ -864,8 +861,8 @@ JNIEXPORT jobject JNICALL Java_net_osmand_plus_render_NativeOsmandLibrary_genera
} }
rc.nativeOperations.pause(); rc.nativeOperations.pause();
mergeRenderingContext(renderingContext, &rc); pushToJavaRenderingContext(renderingContext, &rc);
__android_log_print(ANDROID_LOG_WARN, "net.osmand", "End Rendering image"); __android_log_print(ANDROID_LOG_WARN, LOG_TAG, "End Rendering image");
// delete variables // delete variables
delete paint; delete paint;
@ -874,35 +871,21 @@ JNIEXPORT jobject JNICALL Java_net_osmand_plus_render_NativeOsmandLibrary_genera
delete bitmap; delete bitmap;
// deleteObjects(mapDataObjects); // deleteObjects(mapDataObjects);
jclass resultClass = ienv->FindClass("net/osmand/plus/render/NativeOsmandLibrary$RenderingGenerationResult"); jclass resultClass = findClass("net/osmand/plus/render/NativeOsmandLibrary$RenderingGenerationResult");
if(!resultClass)
resultClass = ienv->FindClass("net/osmand/render/NativeOsmandLibrary$RenderingGenerationResult");
sprintf(debugMessage, "Result class = %p", resultClass);
__android_log_print(ANDROID_LOG_WARN, "net.osmand", debugMessage);
jmethodID resultClassCtorId = ienv->GetMethodID(resultClass, "<init>", "(Ljava/nio/ByteBuffer;Ljava/lang/String;)V"); jmethodID resultClassCtorId = ienv->GetMethodID(resultClass, "<init>", "(Ljava/nio/ByteBuffer;)V");
sprintf(debugMessage, "Result class ctor = %p", resultClassCtorId);
__android_log_print(ANDROID_LOG_WARN, "net.osmand", debugMessage);
#ifdef DEBUG_NAT_OPERATIONS #ifdef DEBUG_NAT_OPERATIONS
sprintf(debugMessage, "Native ok (init %d, native op %d) ", initObjects.getElapsedTime(), rc.nativeOperations.getElapsedTime()); __android_log_print(ANDROID_LOG_WARN, LOG_TAG, "Native ok (init %d, native op %d) ", initObjects.getElapsedTime(), rc.nativeOperations.getElapsedTime());
#else #else
sprintf(debugMessage, "Native ok (init %d, rendering %d) ", initObjects.getElapsedTime(), rc.nativeOperations.getElapsedTime()); __android_log_print(ANDROID_LOG_WARN, LOG_TAG, "Native ok (init %d, rendering %d) ", initObjects.getElapsedTime(), rc.nativeOperations.getElapsedTime());
#endif #endif
__android_log_print(ANDROID_LOG_WARN, "net.osmand", debugMessage);
// Allocate ctor paramters // Allocate ctor paramters
jobject bitmapBuffer = ienv->NewDirectByteBuffer(bitmapData, bitmap->getSize()); jobject bitmapBuffer = ienv->NewDirectByteBuffer(bitmapData, bitmap->getSize());
jstring message = globalEnv()->NewStringUTF(debugMessage);
/* Construct a result object */ /* Construct a result object */
jobject resultObject = ienv->NewObject(resultClass, resultClassCtorId, bitmapBuffer, message); jobject resultObject = ienv->NewObject(resultClass, resultClassCtorId, bitmapBuffer);
return resultObject; return resultObject;
} }
#ifdef __cplusplus
}
#endif
#endif /**/

View file

@ -193,10 +193,10 @@ void drawWrappedText(RenderingContext* rc, SkCanvas* cv, TextDrawInfo* text, flo
pos++; pos++;
} }
if(lastSpace == -1) { if(lastSpace == -1) {
NAT_COUNT(rc, drawTextOnCanvas(cv, text->text.substr(start, pos), text->centerX, text->centerY + line * (textSize + 2), paintText, text->textShadow)); PROFILE_NATIVE_OPERATION(rc, drawTextOnCanvas(cv, text->text.substr(start, pos), text->centerX, text->centerY + line * (textSize + 2), paintText, text->textShadow));
start = pos; start = pos;
} else { } else {
NAT_COUNT(rc, drawTextOnCanvas(cv, text->text.substr(start, lastSpace), text->centerX, text->centerY + line * (textSize + 2), paintText, text->textShadow)); PROFILE_NATIVE_OPERATION(rc, drawTextOnCanvas(cv, text->text.substr(start, lastSpace), text->centerX, text->centerY + line * (textSize + 2), paintText, text->textShadow));
start = lastSpace + 1; start = lastSpace + 1;
limit += (start - pos) - 1; limit += (start - pos) - 1;
} }
@ -204,7 +204,7 @@ void drawWrappedText(RenderingContext* rc, SkCanvas* cv, TextDrawInfo* text, flo
} }
} else { } else {
NAT_COUNT(rc, drawTextOnCanvas(cv, text->text, text->centerX, text->centerY, paintText, text->textShadow)); PROFILE_NATIVE_OPERATION(rc, drawTextOnCanvas(cv, text->text, text->centerX, text->centerY, paintText, text->textShadow));
} }
} }
@ -514,7 +514,7 @@ void drawTextOverCanvas(RenderingContext* rc, SkCanvas* cv) {
} }
if (text->drawOnPath && text->path != NULL) { if (text->drawOnPath && text->path != NULL) {
if (text->textShadow > 0) { if (text->textShadow > 0) {
paintText.setColor(WHITE_COLOR); paintText.setColor(0xFFFFFFFF);
paintText.setStyle(SkPaint::kStroke_Style); paintText.setStyle(SkPaint::kStroke_Style);
paintText.setStrokeWidth(2 + text->textShadow); paintText.setStrokeWidth(2 + text->textShadow);
rc->nativeOperations.pause(); rc->nativeOperations.pause();

@ -0,0 +1 @@
Subproject commit 17b24482db9fb75020b91a9c17f2014beebc86ed

View file

@ -1,13 +0,0 @@
# To develop Skia targeting Android,
# copy this file to your root development directory as ".gclient"
# and then run "gclient sync".
solutions = [
{
"name" : "android",
"url" : "https://skia.googlecode.com/svn/android",
},
{
"name" : "trunk",
"url" : "https://skia.googlecode.com/svn/trunk",
},
]

View file

@ -1,6 +0,0 @@
*
!.gitignore
!.gclient
!Android.mk
!FakeHost.mk
!FontHostConfiguration_android.cpp

View file

@ -11,11 +11,27 @@ LOCAL_MODULE := skia_neon
LOCAL_ARM_NEON := true LOCAL_ARM_NEON := true
endif endif
ifeq ($(SKIA_LOC),) ifeq ($(OSMAND_SKIA_LOC),)
SKIA_LOC := . OSMAND_SKIA_LOC := ./skia_library
endif endif
ifeq ($(SKIA_ABS),) ifeq ($(OSMAND_SKIA_ABS),)
SKIA_ABS := $(LOCAL_PATH) OSMAND_SKIA_ABS := $(LOCAL_PATH)/skia_library
endif
ifeq ($(OSMAND_FREETYPE_ABS),)
OSMAND_FREETYPE_ABS := $(LOCAL_PATH)/../freetype/freetype_library
endif
ifeq ($(OSMAND_PNG_ABS),)
OSMAND_PNG_ABS := $(LOCAL_PATH)/../png/png_library
endif
ifeq ($(OSMAND_GIF_ABS),)
OSMAND_GIF_ABS := $(LOCAL_PATH)/../gif/gif_library
endif
ifeq ($(OSMAND_EXPAT_ABS),)
OSMAND_EXPAT_ABS := $(LOCAL_PATH)/../expat/expat_library
endif
ifeq ($(OSMAND_JPEG_ABS),)
OSMAND_JPEG_ABS := $(LOCAL_PATH)/../jpeg/jpeg_library
endif endif
LOCAL_ARM_MODE := arm LOCAL_ARM_MODE := arm
@ -35,251 +51,259 @@ ifeq ($(LOCAL_ARM_NEON),true)
endif endif
LOCAL_SRC_FILES := \ LOCAL_SRC_FILES := \
$(SKIA_LOC)/trunk/src/core/Sk64.cpp \ $(OSMAND_SKIA_LOC)/src/core/Sk64.cpp \
$(SKIA_LOC)/trunk/src/core/SkAAClip.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkAAClip.cpp \
$(SKIA_LOC)/trunk/src/core/SkAdvancedTypefaceMetrics.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkAdvancedTypefaceMetrics.cpp \
$(SKIA_LOC)/trunk/src/core/SkAlphaRuns.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkAlphaRuns.cpp \
$(SKIA_LOC)/trunk/src/core/SkBitmap.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkBitmap.cpp \
$(SKIA_LOC)/trunk/src/core/SkBitmapProcShader.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkBitmapProcShader.cpp \
$(SKIA_LOC)/trunk/src/core/SkBitmapProcState.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkBitmapProcState.cpp \
$(SKIA_LOC)/trunk/src/core/SkBitmapProcState_matrixProcs.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkBitmapProcState_matrixProcs.cpp \
$(SKIA_LOC)/trunk/src/core/SkBitmapSampler.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkBitmapSampler.cpp \
$(SKIA_LOC)/trunk/src/core/SkBitmap_scroll.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkBitmap_scroll.cpp \
$(SKIA_LOC)/trunk/src/core/SkBlitMask_D32.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkBlitMask_D32.cpp \
$(SKIA_LOC)/trunk/src/core/SkBlitRow_D16.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkBlitRow_D16.cpp \
$(SKIA_LOC)/trunk/src/core/SkBlitRow_D32.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkBlitRow_D32.cpp \
$(SKIA_LOC)/trunk/src/core/SkBlitRow_D4444.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkBlitRow_D4444.cpp \
$(SKIA_LOC)/trunk/src/core/SkBlitter.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkBlitter.cpp \
$(SKIA_LOC)/trunk/src/core/SkBlitter_4444.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkBlitter_4444.cpp \
$(SKIA_LOC)/trunk/src/core/SkBlitter_A1.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkBlitter_A1.cpp \
$(SKIA_LOC)/trunk/src/core/SkBlitter_A8.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkBlitter_A8.cpp \
$(SKIA_LOC)/trunk/src/core/SkBlitter_ARGB32.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkBlitter_ARGB32.cpp \
$(SKIA_LOC)/trunk/src/core/SkBlitter_RGB16.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkBlitter_RGB16.cpp \
$(SKIA_LOC)/trunk/src/core/SkBlitter_Sprite.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkBlitter_Sprite.cpp \
$(SKIA_LOC)/trunk/src/core/SkBuffer.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkBuffer.cpp \
$(SKIA_LOC)/trunk/src/core/SkCanvas.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkCanvas.cpp \
$(SKIA_LOC)/trunk/src/core/SkChunkAlloc.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkChunkAlloc.cpp \
$(SKIA_LOC)/trunk/src/core/SkClampRange.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkClampRange.cpp \
$(SKIA_LOC)/trunk/src/core/SkClipStack.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkClipStack.cpp \
$(SKIA_LOC)/trunk/src/core/SkColor.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkColor.cpp \
$(SKIA_LOC)/trunk/src/core/SkColorFilter.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkColorFilter.cpp \
$(SKIA_LOC)/trunk/src/core/SkColorTable.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkColorTable.cpp \
$(SKIA_LOC)/trunk/src/core/SkConfig8888.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkComposeShader.cpp \
$(SKIA_LOC)/trunk/src/core/SkComposeShader.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkConcaveToTriangles.cpp \
$(SKIA_LOC)/trunk/src/core/SkConcaveToTriangles.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkCordic.cpp \
$(SKIA_LOC)/trunk/src/core/SkCordic.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkCubicClipper.cpp \
$(SKIA_LOC)/trunk/src/core/SkCubicClipper.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkData.cpp \
$(SKIA_LOC)/trunk/src/core/SkData.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkDebug.cpp \
$(SKIA_LOC)/trunk/src/core/SkDebug.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkDeque.cpp \
$(SKIA_LOC)/trunk/src/core/SkDeque.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkDevice.cpp \
$(SKIA_LOC)/trunk/src/core/SkDevice.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkDither.cpp \
$(SKIA_LOC)/trunk/src/core/SkDither.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkDraw.cpp \
$(SKIA_LOC)/trunk/src/core/SkDraw.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkEdgeBuilder.cpp \
$(SKIA_LOC)/trunk/src/core/SkEdgeBuilder.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkEdgeClipper.cpp \
$(SKIA_LOC)/trunk/src/core/SkEdgeClipper.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkEdge.cpp \
$(SKIA_LOC)/trunk/src/core/SkEdge.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkFilterProc.cpp \
$(SKIA_LOC)/trunk/src/core/SkFilterProc.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkFlattenable.cpp \
$(SKIA_LOC)/trunk/src/core/SkFlattenable.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkFloat.cpp \
$(SKIA_LOC)/trunk/src/core/SkFloat.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkFloatBits.cpp \
$(SKIA_LOC)/trunk/src/core/SkFloatBits.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkFontHost.cpp \
$(SKIA_LOC)/trunk/src/core/SkFontHost.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkGeometry.cpp \
$(SKIA_LOC)/trunk/src/core/SkGeometry.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkGlyphCache.cpp \
$(SKIA_LOC)/trunk/src/core/SkGlyphCache.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkGraphics.cpp \
$(SKIA_LOC)/trunk/src/core/SkGraphics.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkLineClipper.cpp \
$(SKIA_LOC)/trunk/src/core/SkLineClipper.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkMallocPixelRef.cpp \
$(SKIA_LOC)/trunk/src/core/SkMallocPixelRef.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkMask.cpp \
$(SKIA_LOC)/trunk/src/core/SkMask.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkMaskFilter.cpp \
$(SKIA_LOC)/trunk/src/core/SkMaskFilter.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkMath.cpp \
$(SKIA_LOC)/trunk/src/core/SkMath.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkMatrix.cpp \
$(SKIA_LOC)/trunk/src/core/SkMatrix.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkMetaData.cpp \
$(SKIA_LOC)/trunk/src/core/SkMetaData.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkMMapStream.cpp \
$(SKIA_LOC)/trunk/src/core/SkMMapStream.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkPackBits.cpp \
$(SKIA_LOC)/trunk/src/core/SkPackBits.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkPaint.cpp \
$(SKIA_LOC)/trunk/src/core/SkPaint.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkPath.cpp \
$(SKIA_LOC)/trunk/src/core/SkPath.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkPathEffect.cpp \
$(SKIA_LOC)/trunk/src/core/SkPathEffect.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkPathHeap.cpp \
$(SKIA_LOC)/trunk/src/core/SkPathHeap.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkPathMeasure.cpp \
$(SKIA_LOC)/trunk/src/core/SkPathMeasure.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkPicture.cpp \
$(SKIA_LOC)/trunk/src/core/SkPicture.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkPictureFlat.cpp \
$(SKIA_LOC)/trunk/src/core/SkPictureFlat.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkPicturePlayback.cpp \
$(SKIA_LOC)/trunk/src/core/SkPicturePlayback.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkPictureRecord.cpp \
$(SKIA_LOC)/trunk/src/core/SkPictureRecord.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkPixelRef.cpp \
$(SKIA_LOC)/trunk/src/core/SkPixelRef.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkPoint.cpp \
$(SKIA_LOC)/trunk/src/core/SkPoint.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkProcSpriteBlitter.cpp \
$(SKIA_LOC)/trunk/src/core/SkProcSpriteBlitter.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkPtrRecorder.cpp \
$(SKIA_LOC)/trunk/src/core/SkPtrRecorder.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkQuadClipper.cpp \
$(SKIA_LOC)/trunk/src/core/SkQuadClipper.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkRasterClip.cpp \
$(SKIA_LOC)/trunk/src/core/SkRasterClip.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkRasterizer.cpp \
$(SKIA_LOC)/trunk/src/core/SkRasterizer.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkRect.cpp \
$(SKIA_LOC)/trunk/src/core/SkRect.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkRefDict.cpp \
$(SKIA_LOC)/trunk/src/core/SkRefDict.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkRegion.cpp \
$(SKIA_LOC)/trunk/src/core/SkRegion.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkRegion_path.cpp \
$(SKIA_LOC)/trunk/src/core/SkRegion_path.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkScalar.cpp \
$(SKIA_LOC)/trunk/src/core/SkScalar.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkScalerContext.cpp \
$(SKIA_LOC)/trunk/src/core/SkScalerContext.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkScan.cpp \
$(SKIA_LOC)/trunk/src/core/SkScan.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkScan_AntiPath.cpp \
$(SKIA_LOC)/trunk/src/core/SkScan_AntiPath.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkScan_Antihair.cpp \
$(SKIA_LOC)/trunk/src/core/SkScan_Antihair.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkScan_Hairline.cpp \
$(SKIA_LOC)/trunk/src/core/SkScan_Hairline.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkScan_Path.cpp \
$(SKIA_LOC)/trunk/src/core/SkScan_Path.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkShader.cpp \
$(SKIA_LOC)/trunk/src/core/SkShader.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkShape.cpp \
$(SKIA_LOC)/trunk/src/core/SkShape.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkSpriteBlitter_ARGB32.cpp \
$(SKIA_LOC)/trunk/src/core/SkSpriteBlitter_ARGB32.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkSpriteBlitter_RGB16.cpp \
$(SKIA_LOC)/trunk/src/core/SkSpriteBlitter_RGB16.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkStream.cpp \
$(SKIA_LOC)/trunk/src/core/SkStream.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkString.cpp \
$(SKIA_LOC)/trunk/src/core/SkString.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkStroke.cpp \
$(SKIA_LOC)/trunk/src/core/SkStroke.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkStrokerPriv.cpp \
$(SKIA_LOC)/trunk/src/core/SkStrokerPriv.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkTSearch.cpp \
$(SKIA_LOC)/trunk/src/core/SkTSearch.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkTypeface.cpp \
$(SKIA_LOC)/trunk/src/core/SkTypeface.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkTypefaceCache.cpp \
$(SKIA_LOC)/trunk/src/core/SkTypefaceCache.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkUnPreMultiply.cpp \
$(SKIA_LOC)/trunk/src/core/SkUnPreMultiply.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkUtils.cpp \
$(SKIA_LOC)/trunk/src/core/SkUtils.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkFlate.cpp \
$(SKIA_LOC)/trunk/src/core/SkFlate.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkWriter32.cpp \
$(SKIA_LOC)/trunk/src/core/SkWriter32.cpp \ $(OSMAND_SKIA_LOC)/src/core/SkXfermode.cpp \
$(SKIA_LOC)/trunk/src/core/SkXfermode.cpp \ $(OSMAND_SKIA_LOC)/src/effects/Sk1DPathEffect.cpp \
$(SKIA_LOC)/trunk/src/effects/Sk1DPathEffect.cpp \ $(OSMAND_SKIA_LOC)/src/effects/Sk2DPathEffect.cpp \
$(SKIA_LOC)/trunk/src/effects/Sk2DPathEffect.cpp \ $(OSMAND_SKIA_LOC)/src/effects/SkAvoidXfermode.cpp \
$(SKIA_LOC)/trunk/src/effects/SkAvoidXfermode.cpp \ $(OSMAND_SKIA_LOC)/src/effects/SkArithmeticMode.cpp \
$(SKIA_LOC)/trunk/src/effects/SkArithmeticMode.cpp \ $(OSMAND_SKIA_LOC)/src/effects/SkBitmapCache.cpp \
$(SKIA_LOC)/trunk/src/effects/SkBitmapCache.cpp \ $(OSMAND_SKIA_LOC)/src/effects/SkBlurDrawLooper.cpp \
$(SKIA_LOC)/trunk/src/effects/SkBlurDrawLooper.cpp \ $(OSMAND_SKIA_LOC)/src/effects/SkBlurImageFilter.cpp \
$(SKIA_LOC)/trunk/src/effects/SkBlurImageFilter.cpp \ $(OSMAND_SKIA_LOC)/src/effects/SkBlurMask.cpp \
$(SKIA_LOC)/trunk/src/effects/SkBlurMask.cpp \ $(OSMAND_SKIA_LOC)/src/effects/SkBlurMaskFilter.cpp \
$(SKIA_LOC)/trunk/src/effects/SkBlurMaskFilter.cpp \ $(OSMAND_SKIA_LOC)/src/effects/SkColorFilters.cpp \
$(SKIA_LOC)/trunk/src/effects/SkColorFilters.cpp \ $(OSMAND_SKIA_LOC)/src/effects/SkColorMatrixFilter.cpp \
$(SKIA_LOC)/trunk/src/effects/SkColorMatrixFilter.cpp \ $(OSMAND_SKIA_LOC)/src/effects/SkCornerPathEffect.cpp \
$(SKIA_LOC)/trunk/src/effects/SkCornerPathEffect.cpp \ $(OSMAND_SKIA_LOC)/src/effects/SkDashPathEffect.cpp \
$(SKIA_LOC)/trunk/src/effects/SkDashPathEffect.cpp \ $(OSMAND_SKIA_LOC)/src/effects/SkDiscretePathEffect.cpp \
$(SKIA_LOC)/trunk/src/effects/SkDiscretePathEffect.cpp \ $(OSMAND_SKIA_LOC)/src/effects/SkEffects.cpp \
$(SKIA_LOC)/trunk/src/effects/SkEffects.cpp \ $(OSMAND_SKIA_LOC)/src/effects/SkEmbossMask.cpp \
$(SKIA_LOC)/trunk/src/effects/SkEmbossMask.cpp \ $(OSMAND_SKIA_LOC)/src/effects/SkEmbossMaskFilter.cpp \
$(SKIA_LOC)/trunk/src/effects/SkEmbossMaskFilter.cpp \ $(OSMAND_SKIA_LOC)/src/effects/SkGradientShader.cpp \
$(SKIA_LOC)/trunk/src/effects/SkGradientShader.cpp \ $(OSMAND_SKIA_LOC)/src/effects/SkGroupShape.cpp \
$(SKIA_LOC)/trunk/src/effects/SkGroupShape.cpp \ $(OSMAND_SKIA_LOC)/src/effects/SkKernel33MaskFilter.cpp \
$(SKIA_LOC)/trunk/src/effects/SkKernel33MaskFilter.cpp \ $(OSMAND_SKIA_LOC)/src/effects/SkLayerDrawLooper.cpp \
$(SKIA_LOC)/trunk/src/effects/SkLayerDrawLooper.cpp \ $(OSMAND_SKIA_LOC)/src/effects/SkLayerRasterizer.cpp \
$(SKIA_LOC)/trunk/src/effects/SkLayerRasterizer.cpp \ $(OSMAND_SKIA_LOC)/src/effects/SkPaintFlagsDrawFilter.cpp \
$(SKIA_LOC)/trunk/src/effects/SkPaintFlagsDrawFilter.cpp \ $(OSMAND_SKIA_LOC)/src/effects/SkPixelXorXfermode.cpp \
$(SKIA_LOC)/trunk/src/effects/SkPixelXorXfermode.cpp \ $(OSMAND_SKIA_LOC)/src/effects/SkPorterDuff.cpp \
$(SKIA_LOC)/trunk/src/effects/SkPorterDuff.cpp \ $(OSMAND_SKIA_LOC)/src/effects/SkRectShape.cpp \
$(SKIA_LOC)/trunk/src/effects/SkRectShape.cpp \ $(OSMAND_SKIA_LOC)/src/effects/SkTableColorFilter.cpp \
$(SKIA_LOC)/trunk/src/effects/SkTableColorFilter.cpp \ $(OSMAND_SKIA_LOC)/src/effects/SkTableMaskFilter.cpp \
$(SKIA_LOC)/trunk/src/effects/SkTableMaskFilter.cpp \ $(OSMAND_SKIA_LOC)/src/effects/SkTestImageFilters.cpp \
$(SKIA_LOC)/trunk/src/effects/SkTestImageFilters.cpp \ $(OSMAND_SKIA_LOC)/src/effects/SkTransparentShader.cpp \
$(SKIA_LOC)/trunk/src/effects/SkTransparentShader.cpp \ $(OSMAND_SKIA_LOC)/src/images/bmpdecoderhelper.cpp \
$(SKIA_LOC)/trunk/src/images/bmpdecoderhelper.cpp \ $(OSMAND_SKIA_LOC)/src/images/SkCreateRLEPixelRef.cpp \
$(SKIA_LOC)/trunk/src/images/SkCreateRLEPixelRef.cpp \ $(OSMAND_SKIA_LOC)/src/images/SkFDStream.cpp \
$(SKIA_LOC)/trunk/src/images/SkFDStream.cpp \ $(OSMAND_SKIA_LOC)/src/images/SkFlipPixelRef.cpp \
$(SKIA_LOC)/trunk/src/images/SkFlipPixelRef.cpp \ $(OSMAND_SKIA_LOC)/src/images/SkImageDecoder.cpp \
$(SKIA_LOC)/trunk/src/images/SkImageDecoder.cpp \ $(OSMAND_SKIA_LOC)/src/images/SkImageDecoder_Factory.cpp \
$(SKIA_LOC)/trunk/src/images/SkImageDecoder_Factory.cpp \ $(OSMAND_SKIA_LOC)/src/images/SkImageDecoder_libbmp.cpp \
$(SKIA_LOC)/trunk/src/images/SkImageDecoder_libbmp.cpp \ $(OSMAND_SKIA_LOC)/src/images/SkImageDecoder_libgif.cpp \
$(SKIA_LOC)/trunk/src/images/SkImageDecoder_libgif.cpp \ $(OSMAND_SKIA_LOC)/src/images/SkImageDecoder_libico.cpp \
$(SKIA_LOC)/trunk/src/images/SkImageDecoder_libico.cpp \ $(OSMAND_SKIA_LOC)/src/images/SkImageDecoder_libjpeg.cpp \
$(SKIA_LOC)/trunk/src/images/SkImageDecoder_libpng.cpp \ $(OSMAND_SKIA_LOC)/src/images/SkImageDecoder_libpng.cpp \
$(SKIA_LOC)/trunk/src/images/SkImageDecoder_wbmp.cpp \ $(OSMAND_SKIA_LOC)/src/images/SkImageDecoder_wbmp.cpp \
$(SKIA_LOC)/trunk/src/images/SkImageEncoder.cpp \ $(OSMAND_SKIA_LOC)/src/images/SkImageEncoder.cpp \
$(SKIA_LOC)/trunk/src/images/SkImageEncoder_Factory.cpp \ $(OSMAND_SKIA_LOC)/src/images/SkImageEncoder_Factory.cpp \
$(SKIA_LOC)/trunk/src/images/SkImageRef.cpp \ $(OSMAND_SKIA_LOC)/src/images/SkImageRef.cpp \
$(SKIA_LOC)/trunk/src/images/SkImageRefPool.cpp \ $(OSMAND_SKIA_LOC)/src/images/SkImageRefPool.cpp \
$(SKIA_LOC)/trunk/src/images/SkImageRef_GlobalPool.cpp \ $(OSMAND_SKIA_LOC)/src/images/SkImageRef_GlobalPool.cpp \
$(SKIA_LOC)/trunk/src/images/SkMovie.cpp \ $(OSMAND_SKIA_LOC)/src/images/SkMovie.cpp \
$(SKIA_LOC)/trunk/src/images/SkMovie_gif.cpp \ $(OSMAND_SKIA_LOC)/src/images/SkMovie_gif.cpp \
$(SKIA_LOC)/trunk/src/images/SkPageFlipper.cpp \ $(OSMAND_SKIA_LOC)/src/images/SkPageFlipper.cpp \
$(SKIA_LOC)/trunk/src/images/SkScaledBitmapSampler.cpp \ $(OSMAND_SKIA_LOC)/src/images/SkScaledBitmapSampler.cpp \
$(SKIA_LOC)/trunk/src/ports/SkDebug_android.cpp \ $(OSMAND_SKIA_LOC)/src/ports/SkDebug_android.cpp \
$(SKIA_LOC)/trunk/src/ports/SkGlobalInitialization_default.cpp \ $(OSMAND_SKIA_LOC)/src/ports/SkGlobalInitialization_default.cpp \
$(SKIA_LOC)/trunk/src/ports/SkFontHost_FreeType.cpp \ $(OSMAND_SKIA_LOC)/src/ports/SkFontHost_FreeType.cpp \
$(SKIA_LOC)/trunk/src/ports/SkFontHost_sandbox_none.cpp \ $(OSMAND_SKIA_LOC)/src/ports/SkFontHost_sandbox_none.cpp \
$(SKIA_LOC)/trunk/src/ports/SkFontHost_android.cpp \ $(OSMAND_SKIA_LOC)/src/ports/SkFontHost_android.cpp \
$(SKIA_LOC)/trunk/src/ports/SkFontHost_gamma.cpp \ $(OSMAND_SKIA_LOC)/src/ports/SkFontHost_gamma.cpp \
$(SKIA_LOC)/trunk/src/ports/SkFontHost_tables.cpp \ $(OSMAND_SKIA_LOC)/src/ports/SkFontHost_tables.cpp \
$(SKIA_LOC)/trunk/src/ports/SkMemory_malloc.cpp \ $(OSMAND_SKIA_LOC)/src/ports/SkMemory_malloc.cpp \
$(SKIA_LOC)/trunk/src/ports/SkOSFile_stdio.cpp \ $(OSMAND_SKIA_LOC)/src/ports/SkOSFile_stdio.cpp \
$(SKIA_LOC)/trunk/src/ports/SkTime_Unix.cpp \ $(OSMAND_SKIA_LOC)/src/ports/SkTime_Unix.cpp \
$(SKIA_LOC)/trunk/src/ports/SkThread_pthread.cpp \ $(OSMAND_SKIA_LOC)/src/ports/SkThread_pthread.cpp \
$(SKIA_LOC)/trunk/src/utils/SkBoundaryPatch.cpp \ $(OSMAND_SKIA_LOC)/src/utils/SkBoundaryPatch.cpp \
$(SKIA_LOC)/trunk/src/utils/SkCamera.cpp \ $(OSMAND_SKIA_LOC)/src/utils/SkCamera.cpp \
$(SKIA_LOC)/trunk/src/utils/SkColorMatrix.cpp \ $(OSMAND_SKIA_LOC)/src/utils/SkColorMatrix.cpp \
$(SKIA_LOC)/trunk/src/utils/SkCubicInterval.cpp \ $(OSMAND_SKIA_LOC)/src/utils/SkCubicInterval.cpp \
$(SKIA_LOC)/trunk/src/utils/SkCullPoints.cpp \ $(OSMAND_SKIA_LOC)/src/utils/SkCullPoints.cpp \
$(SKIA_LOC)/trunk/src/utils/SkDumpCanvas.cpp \ $(OSMAND_SKIA_LOC)/src/utils/SkDumpCanvas.cpp \
$(SKIA_LOC)/trunk/src/utils/SkInterpolator.cpp \ $(OSMAND_SKIA_LOC)/src/utils/SkInterpolator.cpp \
$(SKIA_LOC)/trunk/src/utils/SkLayer.cpp \ $(OSMAND_SKIA_LOC)/src/utils/SkLayer.cpp \
$(SKIA_LOC)/trunk/src/utils/SkMatrix44.cpp \ $(OSMAND_SKIA_LOC)/src/utils/SkMatrix44.cpp \
$(SKIA_LOC)/trunk/src/utils/SkMeshUtils.cpp \ $(OSMAND_SKIA_LOC)/src/utils/SkMeshUtils.cpp \
$(SKIA_LOC)/trunk/src/utils/SkNinePatch.cpp \ $(OSMAND_SKIA_LOC)/src/utils/SkNinePatch.cpp \
$(SKIA_LOC)/trunk/src/utils/SkNWayCanvas.cpp \ $(OSMAND_SKIA_LOC)/src/utils/SkNWayCanvas.cpp \
$(SKIA_LOC)/trunk/src/utils/SkOSFile.cpp \ $(OSMAND_SKIA_LOC)/src/utils/SkOSFile.cpp \
$(SKIA_LOC)/trunk/src/utils/SkParse.cpp \ $(OSMAND_SKIA_LOC)/src/utils/SkParse.cpp \
$(SKIA_LOC)/trunk/src/utils/SkParseColor.cpp \ $(OSMAND_SKIA_LOC)/src/utils/SkParseColor.cpp \
$(SKIA_LOC)/trunk/src/utils/SkParsePath.cpp \ $(OSMAND_SKIA_LOC)/src/utils/SkParsePath.cpp \
$(SKIA_LOC)/trunk/src/utils/SkProxyCanvas.cpp \ $(OSMAND_SKIA_LOC)/src/utils/SkProxyCanvas.cpp \
$(SKIA_LOC)/trunk/src/utils/SkSfntUtils.cpp \ $(OSMAND_SKIA_LOC)/src/utils/SkSfntUtils.cpp \
$(SKIA_LOC)/trunk/src/utils/SkUnitMappers.cpp $(OSMAND_SKIA_LOC)/src/utils/SkUnitMappers.cpp
# This file is replacement of $(SKIA_LOC)/trunk/src/ports/FontHostConfiguration_android.cpp # This file is replacement of $(OSMAND_SKIA_LOC)/src/ports/FontHostConfiguration_android.cpp
LOCAL_SRC_FILES += \ LOCAL_SRC_FILES += \
FontHostConfiguration_android.cpp FontHostConfiguration_android.cpp
LOCAL_C_INCLUDES += \ LOCAL_C_INCLUDES += \
$(SKIA_ABS)/trunk/src/ports $(OSMAND_SKIA_ABS)/src/ports
ifeq ($(TARGET_ARCH),arm) ifeq ($(TARGET_ARCH),arm)
ifeq ($(LOCAL_ARM_NEON),true) ifeq ($(LOCAL_ARM_NEON),true)
LOCAL_SRC_FILES += \ LOCAL_SRC_FILES += \
$(SKIA_LOC)/trunk/src/opts/memset16_neon.S \ $(OSMAND_SKIA_LOC)/src/opts/memset16_neon.S \
$(SKIA_LOC)/trunk/src/opts/memset32_neon.S $(OSMAND_SKIA_LOC)/src/opts/memset32_neon.S
endif endif
LOCAL_SRC_FILES += \ LOCAL_SRC_FILES += \
$(SKIA_LOC)/trunk/src/opts/opts_check_arm.cpp \ $(OSMAND_SKIA_LOC)/src/opts/opts_check_arm.cpp \
$(SKIA_LOC)/trunk/src/opts/memset.arm.S \ $(OSMAND_SKIA_LOC)/src/opts/memset.arm.S \
$(SKIA_LOC)/trunk/src/opts/SkBitmapProcState_opts_arm.cpp \ $(OSMAND_SKIA_LOC)/src/opts/SkBitmapProcState_opts_arm.cpp \
$(SKIA_LOC)/trunk/src/opts/SkBlitRow_opts_arm.cpp $(OSMAND_SKIA_LOC)/src/opts/SkBlitRow_opts_arm.cpp
else else
LOCAL_SRC_FILES += \ LOCAL_SRC_FILES += \
$(SKIA_LOC)/trunk/src/opts/SkBlitRow_opts_none.cpp \ $(OSMAND_SKIA_LOC)/src/opts/SkBlitRow_opts_none.cpp \
$(SKIA_LOC)/trunk/src/opts/SkBitmapProcState_opts_none.cpp \ $(OSMAND_SKIA_LOC)/src/opts/SkBitmapProcState_opts_none.cpp \
$(SKIA_LOC)/trunk/src/opts/SkUtils_opts_none.cpp $(OSMAND_SKIA_LOC)/src/opts/SkUtils_opts_none.cpp
endif endif
LOCAL_SHARED_LIBRARIES := \ LOCAL_SHARED_LIBRARIES := \
libcutils \
libjpeg \
libutils \ libutils \
libz libz
LOCAL_STATIC_LIBRARIES := \ ifeq ($(LOCAL_ARM_NEON),true)
libft2 \ LOCAL_STATIC_LIBRARIES += \
libjpeg_neon \
libft2_static_neon \
libpng_neon \
libgif_neon \
libexpat_static_neon
else
LOCAL_STATIC_LIBRARIES += \
libjpeg \
libft2_static \
libpng \ libpng \
libgif \ libgif \
libexpat_static libexpat_static
endif
LOCAL_C_INCLUDES += \ LOCAL_C_INCLUDES += \
$(SKIA_ABS)/trunk/src/core \ $(LOCAL_PATH) \
$(SKIA_ABS)/trunk/include/core \ $(OSMAND_SKIA_ABS)/src/core \
$(SKIA_ABS)/trunk/include/config \ $(OSMAND_SKIA_ABS)/include/core \
$(SKIA_ABS)/trunk/include/effects \ $(OSMAND_SKIA_ABS)/include/config \
$(SKIA_ABS)/trunk/include/images \ $(OSMAND_SKIA_ABS)/include/effects \
$(SKIA_ABS)/trunk/include/utils \ $(OSMAND_SKIA_ABS)/include/images \
$(SKIA_ABS)/trunk/include/xml \ $(OSMAND_SKIA_ABS)/include/utils \
$(SKIA_ABS)/android/third_party/externals/freetype/include \ $(OSMAND_SKIA_ABS)/include/xml \
$(SKIA_ABS)/android/third_party/externals/png \ $(OSMAND_FREETYPE_ABS)/include \
$(SKIA_ABS)/android/third_party/externals/gif \ $(OSMAND_PNG_ABS) \
$(SKIA_ABS)/android/third_party/externals/expat/lib $(OSMAND_GIF_ABS) \
$(OSMAND_EXPAT_ABS)/lib \
$(OSMAND_JPEG_ABS)
ifeq ($(NO_FALLBACK_FONT),true) ifeq ($(NO_FALLBACK_FONT),true)
LOCAL_CFLAGS += -DNO_FALLBACK_FONT LOCAL_CFLAGS += -DNO_FALLBACK_FONT
endif endif
LOCAL_CFLAGS += \ LOCAL_CFLAGS += \
-DSK_SCALAR_IS_FLOAT \
-DSK_CAN_USE_FLOAT \
-DSK_BUILD_FOR_ANDROID \ -DSK_BUILD_FOR_ANDROID \
-DSK_BUILD_FOR_ANDROID_NDK \ -DSK_BUILD_FOR_ANDROID_NDK \
-DSK_ALLOW_STATIC_GLOBAL_INITIALIZERS=0 \ -DSK_ALLOW_STATIC_GLOBAL_INITIALIZERS=0 \
@ -299,10 +323,3 @@ include $(BUILD_STATIC_LIBRARY)
# Fix some errors # Fix some errors
BUILD_HOST_EXECUTABLE := $(LOCAL_PATH)/FakeHost.mk BUILD_HOST_EXECUTABLE := $(LOCAL_PATH)/FakeHost.mk
BUILD_HOST_STATIC_LIBRARY := $(LOCAL_PATH)/FakeHost.mk BUILD_HOST_STATIC_LIBRARY := $(LOCAL_PATH)/FakeHost.mk
# Import skia externals
$(call import-add-path,$(SKIA_ABS)/android/third_party/externals)
$(call import-module,expat)
$(call import-module,freetype)
$(call import-module,gif)
$(call import-module,png)

@ -0,0 +1 @@
Subproject commit 1cab2921ab279367f8206cdadc9259d12e603548

View file

@ -73,7 +73,8 @@ public class NativeOsmandLibrary {
Bitmap bitmap, int requestedBitmapWidth, int requestedBitmapHeight, int rowBytes, boolean isTransparent, Bitmap bitmap, int requestedBitmapWidth, int requestedBitmapHeight, int rowBytes, boolean isTransparent,
boolean useEnglishNames, RenderingRuleSearchRequest render, int defaultColor) { boolean useEnglishNames, RenderingRuleSearchRequest render, int defaultColor) {
if (searchResultHandler == null) { if (searchResultHandler == null) {
return new RenderingGenerationResult(null, "Error searchresult = null"); log.error("Error searchresult = null"); //$NON-NLS-1$
return new RenderingGenerationResult(null);
} }
if(android.os.Build.VERSION.SDK_INT >= 8) // Android 2.2+ if(android.os.Build.VERSION.SDK_INT >= 8) // Android 2.2+
@ -131,14 +132,11 @@ public class NativeOsmandLibrary {
} }
public static class RenderingGenerationResult { public static class RenderingGenerationResult {
public RenderingGenerationResult(ByteBuffer bitmap, String msg) { public RenderingGenerationResult(ByteBuffer bitmap) {
bitmapBuffer = bitmap; bitmapBuffer = bitmap;
debugMessage = msg;
} }
public final ByteBuffer bitmapBuffer; public final ByteBuffer bitmapBuffer;
public final String debugMessage;
} }
private static native void deleteSearchResult(int searchResultHandle); private static native void deleteSearchResult(int searchResultHandle);

View file

@ -226,7 +226,7 @@ public class OsmandRenderer {
notifyListeners(notifyList); notifyListeners(notifyList);
long time = System.currentTimeMillis() - now; long time = System.currentTimeMillis() - now;
rc.renderingDebugInfo = String.format("Rendering: %s ms (%s text)\n" rc.renderingDebugInfo = String.format("Rendering: %s ms (%s text)\n"
+ "(%s points, %s points inside, %s of %s objects visible)\n" + res.debugMessage,//$NON-NLS-1$ + "(%s points, %s points inside, %s of %s objects visible)\n",//$NON-NLS-1$
time, rc.textRenderingTime, rc.pointCount, rc.pointInsideCount, rc.visible, rc.allObjects); time, rc.textRenderingTime, rc.pointCount, rc.pointInsideCount, rc.visible, rc.allObjects);
// See upper note // See upper note

View file

@ -3,16 +3,23 @@ package net.osmand.plus.render;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import java.nio.ByteBuffer;
import java.io.InputStream;
import org.apache.commons.logging.Log;
import android.content.Context; import android.content.Context;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.view.WindowManager; import android.view.WindowManager;
import android.content.res.AssetFileDescriptor;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.R.drawable; import net.osmand.plus.R.drawable;
import net.osmand.LogUtil;
public class RenderingIcons { public class RenderingIcons {
private static final Log log = LogUtil.getLog(RenderingIcons.class);
private static Map<String, Integer> icons = new LinkedHashMap<String, Integer>(); private static Map<String, Integer> icons = new LinkedHashMap<String, Integer>();
private static Map<String, Bitmap> iconsBmp = new LinkedHashMap<String, Bitmap>(); private static Map<String, Bitmap> iconsBmp = new LinkedHashMap<String, Bitmap>();
@ -22,6 +29,37 @@ public class RenderingIcons {
return icons.containsKey(s); return icons.containsKey(s);
} }
public static ByteBuffer getIconAsByteBuffer(Context ctx, String s) {
Integer resId = icons.get(s);
// Quite bad error
if(resId == null)
return null;
try {
final AssetFileDescriptor iconAssetFd = ctx.getResources().openRawResourceFd(resId.intValue());
if(iconAssetFd == null)
return null;
final long iconAssetLen = iconAssetFd.getLength();
final ByteBuffer iconByteBuffer = ByteBuffer.allocate((int)iconAssetLen);
final InputStream inputStream = iconAssetFd.createInputStream();
if(inputStream == null)
return null;
long consumedBytes = 0;
while(consumedBytes < iconAssetLen) {
consumedBytes += inputStream.read(iconByteBuffer.array(), (int)(iconByteBuffer.arrayOffset() + consumedBytes), (int)(iconAssetLen - consumedBytes));
}
iconAssetFd.close();
return iconByteBuffer;
} catch(Throwable e) {
log.error("Failed to get byte stream from icon", e); //$NON-NLS-1$
return null;
}
}
public static Bitmap getIcon(Context ctx, String s){ public static Bitmap getIcon(Context ctx, String s){
if(!iconsBmp.containsKey(s)){ if(!iconsBmp.containsKey(s)){
Integer resId = icons.get(s); Integer resId = icons.get(s);