Merge branch 'newNdkBranch'

This commit is contained in:
Victor Shcherb 2012-03-04 13:51:58 +01:00
commit 04dfa4c4cd
42 changed files with 2220 additions and 952 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

View file

@ -276,7 +276,7 @@
<!-- Requires 1) gcc, 2) make, 3) download android sources (skia) - specify branch 4) Define environment variable ANDROID_SRC --> <!-- Requires 1) gcc, 2) make, 3) download android sources (skia) - specify branch 4) Define environment variable ANDROID_SRC -->
<echo>Package helper running: nativeon</echo> <echo>Package helper running: nativeon</echo>
<exec command="${ndk.dir}/ndk-build V=1" failonerror="true"/> <exec command="${ndk.dir}/ndk-build -j 8 V=1" failonerror="true"/>
<apkbuilder <apkbuilder
outfolder="${out.absolute.dir}" outfolder="${out.absolute.dir}"
resourcefile="${resource.package.file.name}" resourcefile="${resource.package.file.name}"

14
OsmAnd/jni/Android.mk Normal file → Executable file
View file

@ -1 +1,13 @@
include $(all-subdir-makefiles) OSMAND_MAKEFILES := $(all-subdir-makefiles)
# By default, include makefiles only once
include $(OSMAND_MAKEFILES)
# If we may support NEON, include them once more
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
OSMAND_NEON := true
include $(OSMAND_MAKEFILES)
endif

9
OsmAnd/jni/Application.mk Normal file → Executable file
View file

@ -1 +1,8 @@
APP_STL := stlport_static APP_STL := stlport_shared
APP_ABI := armeabi armeabi-v7a
APP_CPPFLAGS := -fno-rtti -fno-exceptions
ifndef OSMAND_DEBUG_NATIVE
# Force release compilation in release optimizations, even if application is debuggable by manifest
APP_OPTIM := release
endif

View file

@ -0,0 +1,20 @@
# Do not build for NEON
ifneq ($(OSMAND_NEON),true)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# Name of the local module
LOCAL_MODULE := cpufeatures_proxy
LOCAL_SRC_FILES := \
cpuCheck.cpp
LOCAL_STATIC_LIBRARIES := cpufeatures
include $(BUILD_SHARED_LIBRARY)
$(call import-module,android/cpufeatures)
endif

View file

@ -0,0 +1,18 @@
#include <jni.h>
#include <cpu-features.h>
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT jint JNICALL Java_net_osmand_plus_render_NativeOsmandLibrary_getCpuCount( JNIEnv* ienv, jobject obj) {
return android_getCpuCount();
}
JNIEXPORT jboolean JNICALL Java_net_osmand_plus_render_NativeOsmandLibrary_cpuHasNeonSupport( JNIEnv* ienv, jobject obj) {
return (android_getCpuFamily() == ANDROID_CPU_FAMILY_ARM && (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) == ANDROID_CPU_ARM_FEATURE_NEON) ? JNI_TRUE : JNI_FALSE;
}
#ifdef __cplusplus
}
#endif

30
OsmAnd/jni/expat/Android.mk Executable file
View file

@ -0,0 +1,30 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
ifneq ($(OSMAND_NEON),true)
LOCAL_MODULE := libexpat_static
else
LOCAL_MODULE := libexpat_static_neon
LOCAL_ARM_NEON := true
endif
ifeq ($(OSMAND_EXPAT_LOC),)
OSMAND_EXPAT_LOC := ./expat_library
endif
ifeq ($(OSMAND_EXPAT_ABS),)
OSMAND_EXPAT_ABS := $(LOCAL_PATH)/expat_library
endif
LOCAL_SRC_FILES := \
$(OSMAND_EXPAT_LOC)/lib/xmlparse.c \
$(OSMAND_EXPAT_LOC)/lib/xmlrole.c \
$(OSMAND_EXPAT_LOC)/lib/xmltok.c
LOCAL_CFLAGS += -Wall -Wmissing-prototypes -Wstrict-prototypes -fexceptions -DHAVE_EXPAT_CONFIG_H
LOCAL_C_INCLUDES += \
$(OSMAND_EXPAT_ABS) \
$(OSMAND_EXPAT_ABS)/lib
include $(BUILD_STATIC_LIBRARY)

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

60
OsmAnd/jni/freetype/Android.mk Executable file
View file

@ -0,0 +1,60 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
# compile in ARM mode, since the glyph loader/renderer is a hotspot
# when loading complex pages in the browser
#
LOCAL_ARM_MODE := arm
ifeq ($(OSMAND_FREETYPE_LOC),)
OSMAND_FREETYPE_LOC := ./freetype_library
endif
ifeq ($(OSMAND_FREETYPE_ABS),)
OSMAND_FREETYPE_ABS := $(LOCAL_PATH)/freetype_library
endif
LOCAL_SRC_FILES:= \
$(OSMAND_FREETYPE_LOC)/src/base/ftbbox.c \
$(OSMAND_FREETYPE_LOC)/src/base/ftbitmap.c \
$(OSMAND_FREETYPE_LOC)/src/base/ftfstype.c \
$(OSMAND_FREETYPE_LOC)/src/base/ftglyph.c \
$(OSMAND_FREETYPE_LOC)/src/base/ftlcdfil.c \
$(OSMAND_FREETYPE_LOC)/src/base/ftstroke.c \
$(OSMAND_FREETYPE_LOC)/src/base/fttype1.c \
$(OSMAND_FREETYPE_LOC)/src/base/ftxf86.c \
$(OSMAND_FREETYPE_LOC)/src/base/ftbase.c \
$(OSMAND_FREETYPE_LOC)/src/base/ftsystem.c \
$(OSMAND_FREETYPE_LOC)/src/base/ftinit.c \
$(OSMAND_FREETYPE_LOC)/src/base/ftgasp.c \
$(OSMAND_FREETYPE_LOC)/src/raster/raster.c \
$(OSMAND_FREETYPE_LOC)/src/sfnt/sfnt.c \
$(OSMAND_FREETYPE_LOC)/src/smooth/smooth.c \
$(OSMAND_FREETYPE_LOC)/src/autofit/autofit.c \
$(OSMAND_FREETYPE_LOC)/src/truetype/truetype.c \
$(OSMAND_FREETYPE_LOC)/src/cff/cff.c \
$(OSMAND_FREETYPE_LOC)/src/psnames/psnames.c \
$(OSMAND_FREETYPE_LOC)/src/pshinter/pshinter.c
LOCAL_C_INCLUDES += \
$(OSMAND_FREETYPE_ABS)/builds \
$(OSMAND_FREETYPE_ABS)/include
LOCAL_CFLAGS += -W -Wall
LOCAL_CFLAGS += -fPIC -DPIC
LOCAL_CFLAGS += "-DDARWIN_NO_CARBON"
LOCAL_CFLAGS += "-DFT2_BUILD_LIBRARY"
# the following is for testing only, and should not be used in final builds
# of the product
#LOCAL_CFLAGS += "-DTT_CONFIG_OPTION_BYTECODE_INTERPRETER"
LOCAL_CFLAGS += -O2
ifneq ($(OSMAND_NEON),true)
LOCAL_MODULE := libft2_static
else
LOCAL_MODULE := libft2_static_neon
LOCAL_ARM_NEON := true
endif
include $(BUILD_STATIC_LIBRARY)

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

27
OsmAnd/jni/gif/Android.mk Executable file
View file

@ -0,0 +1,27 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
ifeq ($(OSMAND_GIF_LOC),)
OSMAND_GIF_LOC := ./gif_library
endif
ifeq ($(OSMAND_GIF_ABS),)
OSMAND_GIF_ABS := $(LOCAL_PATH)/gif_library
endif
LOCAL_SRC_FILES := \
$(OSMAND_GIF_LOC)/dgif_lib.c \
$(OSMAND_GIF_LOC)/gifalloc.c \
$(OSMAND_GIF_LOC)/gif_err.c
LOCAL_C_INCLUDES += \
$(OSMAND_GIF_ABS)
LOCAL_CFLAGS += -Wno-format -DHAVE_CONFIG_H
ifneq ($(OSMAND_NEON),true)
LOCAL_MODULE := libgif
else
LOCAL_MODULE := libgif_neon
endif
include $(BUILD_STATIC_LIBRARY)

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

83
OsmAnd/jni/jpeg/Android.mk Executable file
View file

@ -0,0 +1,83 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_ARM_MODE := arm
ifeq ($(OSMAND_JPEG_LOC),)
OSMAND_JPEG_LOC := ./jpeg_library
endif
ifeq ($(OSMAND_JPEG_ABS),)
OSMAND_JPEG_ABS := $(LOCAL_PATH)/jpeg_library
endif
LOCAL_SRC_FILES := \
$(OSMAND_JPEG_LOC)/jcapimin.c \
$(OSMAND_JPEG_LOC)/jcapistd.c \
$(OSMAND_JPEG_LOC)/jccoefct.c \
$(OSMAND_JPEG_LOC)/jccolor.c \
$(OSMAND_JPEG_LOC)/jcdctmgr.c \
$(OSMAND_JPEG_LOC)/jchuff.c \
$(OSMAND_JPEG_LOC)/jcinit.c \
$(OSMAND_JPEG_LOC)/jcmainct.c \
$(OSMAND_JPEG_LOC)/jcmarker.c \
$(OSMAND_JPEG_LOC)/jcmaster.c \
$(OSMAND_JPEG_LOC)/jcomapi.c \
$(OSMAND_JPEG_LOC)/jcparam.c \
$(OSMAND_JPEG_LOC)/jcphuff.c \
$(OSMAND_JPEG_LOC)/jcprepct.c \
$(OSMAND_JPEG_LOC)/jcsample.c \
$(OSMAND_JPEG_LOC)/jctrans.c \
$(OSMAND_JPEG_LOC)/jdapimin.c \
$(OSMAND_JPEG_LOC)/jdapistd.c \
$(OSMAND_JPEG_LOC)/jdatadst.c \
$(OSMAND_JPEG_LOC)/jdatasrc.c \
$(OSMAND_JPEG_LOC)/jdcoefct.c \
$(OSMAND_JPEG_LOC)/jdcolor.c \
$(OSMAND_JPEG_LOC)/jddctmgr.c \
$(OSMAND_JPEG_LOC)/jdhuff.c \
$(OSMAND_JPEG_LOC)/jdinput.c \
$(OSMAND_JPEG_LOC)/jdmainct.c \
$(OSMAND_JPEG_LOC)/jdmarker.c \
$(OSMAND_JPEG_LOC)/jdmaster.c \
$(OSMAND_JPEG_LOC)/jdmerge.c \
$(OSMAND_JPEG_LOC)/jdphuff.c \
$(OSMAND_JPEG_LOC)/jdpostct.c \
$(OSMAND_JPEG_LOC)/jdsample.c \
$(OSMAND_JPEG_LOC)/jdtrans.c \
$(OSMAND_JPEG_LOC)/jerror.c \
$(OSMAND_JPEG_LOC)/jfdctflt.c \
$(OSMAND_JPEG_LOC)/jfdctfst.c \
$(OSMAND_JPEG_LOC)/jfdctint.c \
$(OSMAND_JPEG_LOC)/jidctflt.c \
$(OSMAND_JPEG_LOC)/jidctfst.c \
$(OSMAND_JPEG_LOC)/jidctint.c \
$(OSMAND_JPEG_LOC)/jidctred.c \
$(OSMAND_JPEG_LOC)/jquant1.c \
$(OSMAND_JPEG_LOC)/jquant2.c \
$(OSMAND_JPEG_LOC)/jutils.c \
$(OSMAND_JPEG_LOC)/jmemmgr.c \
$(OSMAND_JPEG_LOC)/armv6_idct.S
# the original android memory manager.
# use sdcard as libjpeg decoder's backing store
LOCAL_SRC_FILES += \
$(OSMAND_JPEG_LOC)/jmem-android.c
LOCAL_CFLAGS += -DAVOID_TABLES
LOCAL_CFLAGS += -O3 -fstrict-aliasing -fprefetch-loop-arrays
# enable tile based decode
LOCAL_CFLAGS += -DANDROID_TILE_BASED_DECODE
# enable armv6 idct assembly
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
LOCAL_CFLAGS += -DANDROID_ARMV6_IDCT
endif
ifneq ($(OSMAND_NEON),true)
LOCAL_MODULE := libjpeg
else
LOCAL_MODULE := libjpeg_neon
endif
include $(BUILD_STATIC_LIBRARY)

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

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -1,75 +1,78 @@
LOCAL_PATH := $(call my-dir) LOCAL_PATH := $(call my-dir)
#include $(CLEAR_VARS)
#LOCAL_MODULE := skia2.2
#NDK_MODULE_PATH := $(LOCAL_PATH)
#LOCAL_SRC_FILES := ../libskia2.2.so
#LOCAL_PRELINK_MODULE := false
#
#include $(PREBUILT_SHARED_LIBRARY)
#include $(CLEAR_VARS)
#LOCAL_MODULE := skia_built
#NDK_MODULE_PATH := $(LOCAL_PATH)
#LOCAL_SRC_FILES := ../skia_built.a
#include $(PREBUILT_STATIC_LIBRARY)
#
#include $(CLEAR_VARS)
#LOCAL_MODULE := png
#NDK_MODULE_PATH := $(LOCAL_PATH)
#LOCAL_SRC_FILES := ../libpng.a
#include $(PREBUILT_STATIC_LIBRARY)
#
#include $(CLEAR_VARS)
#LOCAL_MODULE := gif
#NDK_MODULE_PATH := $(LOCAL_PATH)
#LOCAL_SRC_FILES := ../libgif.a
#include $(PREBUILT_STATIC_LIBRARY)
#
#include $(CLEAR_VARS)
#LOCAL_MODULE := ft2
#NDK_MODULE_PATH := $(LOCAL_PATH)
#LOCAL_SRC_FILES := ../libft2.a
#include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS) include $(CLEAR_VARS)
ifeq ($(ANDROID_SRC),)
ANDROID_SRC := /home/victor/projects/android/ # Set 'protobuf' folder only if it's not externally set
ifeq ($(PROTOBUF),)
PROTOBUF := $(LOCAL_PATH)/../protobuf
endif endif
#PROTOBUF_FOLDER := /home/victor/projects/OsmAnd/libs/protobuf-2.3.0/src # Set 'skia' folder only if it's not externally set
PROTOBUF_FOLDER := $(LOCAL_PATH)/../protobuf ifeq ($(OSMAND_SKIA_ABS),)
OSMAND_SKIA_ABS := $(LOCAL_PATH)/../skia/skia_library
SKIA_FOLDER := $(ANDROID_SRC)/external/skia endif
SKIA_SRC := skia
# Name of the local module
ifneq ($(OSMAND_NEON),true)
LOCAL_MODULE := osmand LOCAL_MODULE := osmand
else
LOCAL_MODULE := osmand_neon
LOCAL_ARM_NEON := true
endif
# Include paths
LOCAL_C_INCLUDES := $(LOCAL_PATH) \ LOCAL_C_INCLUDES := $(LOCAL_PATH) \
$(PROTOBUF_FOLDER) \ $(PROTOBUF) \
$(SKIA_FOLDER)/include/core \ $(LOCAL_PATH)/../skia \
$(SKIA_FOLDER)/include/utils \ $(OSMAND_SKIA_ABS)/include/core \
$(SKIA_FOLDER)/include/config \ $(OSMAND_SKIA_ABS)/include/images \
$(SKIA_FOLDER)/include/effects \ $(OSMAND_SKIA_ABS)/include/utils \
$(SKIA_FOLDER)/include/utils/android \ $(OSMAND_SKIA_ABS)/include/config \
$(SKIA_FOLDER)/src/core \ $(OSMAND_SKIA_ABS)/include/effects \
$(ANDROID_SRC)/system/core/include \ $(OSMAND_SKIA_ABS)/include/utils/android \
$(ANDROID_SRC)/frameworks/base/include $(OSMAND_SKIA_ABS)/src/core
LOCAL_CPP_EXTENSION := .cpp
LOCAL_SRC_FILES := common.cpp mapObjects.cpp \
renderRules.cpp rendering.cpp \
binaryRead.cpp
LOCAL_CFLAGS := -Wall -g -DGOOGLE_PROTOBUF_NO_RTTI LOCAL_SRC_FILES := \
# in that case libskia_2.2.so should be in NDK folder to be properly built common.cpp \
LOCAL_LDLIBS := -llog -lcutils -lskia_2.2 mapObjects.cpp \
##LOCAL_LDLIBS := -ldl -llog -lcutils renderRules.cpp \
rendering.cpp \
binaryRead.cpp
LOCAL_CFLAGS := \
-DGOOGLE_PROTOBUF_NO_RTTI \
-DSK_BUILD_FOR_ANDROID \
-DSK_BUILD_FOR_ANDROID_NDK \
-DSK_ALLOW_STATIC_GLOBAL_INITIALIZERS=0 \
-DSK_USE_POSIX_THREADS \
-DSK_RELEASE \
-DGR_RELEASE=1
ifdef OSMAND_PROFILE_NATIVE_OPERATIONS
LOCAL_CFLAGS += \
-DPROFILE_NATIVE_OPERATIONS
endif
LOCAL_STATIC_LIBRARIES := proto ifneq ($(LOCAL_ARM_NEON),true)
#LOCAL_STATIC_LIBRARIES := skia_built gif png ft2 LOCAL_STATIC_LIBRARIES := \
#LOCAL_SHARED_LIBRARIES := skia2.2 proto \
libjpeg \
libft2_static \
libpng \
libgif \
libexpat_static
LOCAL_WHOLE_STATIC_LIBRARIES := skia
else
LOCAL_STATIC_LIBRARIES := \
proto_neon \
libjpeg_neon \
libft2_static_neon \
libpng_neon \
libgif_neon \
libexpat_static_neon
LOCAL_WHOLE_STATIC_LIBRARIES := skia_neon
endif
#LOCAL_PRELINK_MODULE := false LOCAL_LDLIBS := -lz -llog -ljnigraphics
include $(BUILD_SHARED_LIBRARY) include $(BUILD_SHARED_LIBRARY)

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,375 @@
#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(){
return globalE;
}
JNIEnv* setGlobalEnv(JNIEnv* e) { const char* const LOG_TAG = "net.osmand:native";
globalVM->GetEnv((void**)&globalE, JNI_VERSION_1_4);
// try to avoid problem with different thread attach
// globalE = e;
return globalE;
}
extern void loadJniCommon(); JavaVM* globalJVM = NULL;
extern void loadJNIRenderingRules(); JNIEnv* globalJniEnv = NULL;
extern void loadJNIRendering();
extern void loadJniMapObjects();
extern void loadJniBinaryRead();
extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { JNIEnv* getGlobalJniEnv()
if(vm->GetEnv((void **)&globalE, JNI_VERSION_1_4)){
return JNI_ERR; /* JNI version not supported */
}
globalVM = vm;
loadJniCommon();
loadJNIRendering();
loadJNIRenderingRules();
loadJniMapObjects();
loadJniBinaryRead();
return JNI_VERSION_1_4;
}
//extern "C" JNIEXPORT jboolean JNICALL Java_net_osmand_plus_render_NativeOsmandLibrary_loadLibrary(JNIEnv* ienv) {}
jclass RenderingContextClass;
jfieldID RenderingContext_interrupted;
jclass RenderingIconsClass;
jmethodID RenderingIcons_getIcon;
jclass globalRef(jobject o)
{ {
return (jclass) globalEnv()->NewGlobalRef( o); return globalJniEnv;
} }
JNIEnv* setGlobalJniEnv(JNIEnv* e)
jfieldID getFid(jclass cls,const char* fieldName, const char* sig )
{ {
return globalEnv()->GetFieldID( cls, fieldName, sig); if(!globalJVM)
__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "No globalJVM set");
globalJVM->GetEnv((void**)&globalJniEnv, JNI_VERSION_1_6);
return globalJniEnv;
} }
watcher::watcher() { // Forward declarations
elapsedTime = 0; void loadJniCommon();
enableFlag = true; void loadJniRendering();
run = false; void loadJniRenderingRules();
} void loadJniMapObjects();
void watcher::enable() { void loadJniBinaryRead();
enableFlag = true; extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
} {
void watcher::disable() { if(vm->GetEnv((void **)&globalJniEnv, JNI_VERSION_1_6))
pause(); return JNI_ERR; /* JNI version not supported */
enableFlag = false; globalJVM = vm;
}
void watcher::start() { loadJniCommon();
if (!enableFlag) { loadJniRendering();
return; loadJniRenderingRules();
} loadJniMapObjects();
if (!run) { loadJniBinaryRead();
clock_gettime(CLOCK_MONOTONIC, &startInit);
// gettimeofday(&startInit, NULL); __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "JNI_OnLoad completed");
}
run = true; return JNI_VERSION_1_6;
}
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;
} }
void throwNewException(const char* msg)
{
__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 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;
}
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;
return val * rc -> density * rc -> mapTextSize; jclass jclass_RenderingIcons = NULL;
} else { jmethodID jmethod_RenderingIcons_getIconRawData = NULL;
return val * rc -> mapTextSize; 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_getIconRawData = getGlobalJniEnv()->GetStaticMethodID(jclass_RenderingIcons,
"getIconRawData",
"(Landroid/content/Context;Ljava/lang/String;)[B");
} }
SkBitmap* getNativeBitmap(jobject bmpObj){ //TODO: Dead code
if(bmpObj == NULL){ /*
return NULL; void unloadJniCommon() {
} getGlobalJniEnv()->DeleteGlobalRef(jclass_RenderingIcons);
jclass bmpClass = globalEnv()->GetObjectClass(bmpObj); getGlobalJniEnv()->DeleteGlobalRef(jclass_RenderingContext);
SkBitmap* bmp = (SkBitmap*)globalEnv()->CallIntMethod(bmpObj, globalEnv()->GetMethodID(bmpClass, "ni", "()I")); }
globalEnv()->DeleteLocalRef(bmpClass); */
return bmp;
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;
else
return val * rc->mapTextSize;
}
ElapsedTimer::ElapsedTimer()
: elapsedTime(0)
, enableFlag(true)
, run(false)
{
}
void ElapsedTimer::enable()
{
enableFlag = true;
}
void ElapsedTimer::disable()
{
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, const std::string& bitmapResource)
{ {
if (cachedBitmaps.find(js) != cachedBitmaps.end()) { if(bitmapResource.size() == 0)
return cachedBitmaps[js]; return NULL;
}
// Try to find previously cached
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); __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "getCachedBitmap : %s", bitmapResource.c_str());
SkBitmap* res = getNativeBitmap(bmp);
jstring jstr = getGlobalJniEnv()->NewStringUTF(bitmapResource.c_str());
jbyteArray javaIconRawData = (jbyteArray)getGlobalJniEnv()->CallStaticObjectMethod(jclass_RenderingIcons, jmethod_RenderingIcons_getIconRawData, rc->androidContext, jstr);
if(!javaIconRawData)
return NULL;
jbyte* bitmapBuffer = getGlobalJniEnv()->GetByteArrayElements(javaIconRawData, NULL);
size_t bufferLen = getGlobalJniEnv()->GetArrayLength(javaIconRawData);
__android_log_print(ANDROID_LOG_INFO, LOG_TAG, "getCachedBitmap : bitmap buffer len %d at %p", bufferLen, bitmapBuffer);
// Decode bitmap
SkBitmap* iconBitmap = new SkBitmap();
//TODO: JPEG is badly supported! At the moment it needs sdcard to be present (sic). Patch that
if(!SkImageDecoder::DecodeMemory(bitmapBuffer, bufferLen, iconBitmap))
{
// Failed to decode
delete iconBitmap;
rc->nativeOperations.start();
getGlobalJniEnv()->ReleaseByteArrayElements(javaIconRawData, bitmapBuffer, JNI_ABORT);
getGlobalJniEnv()->DeleteLocalRef(javaIconRawData);
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()->ReleaseByteArrayElements(javaIconRawData, bitmapBuffer, JNI_ABORT);
globalEnv()->DeleteLocalRef(jstr); getGlobalJniEnv()->DeleteLocalRef(javaIconRawData);
if(res != NULL){ getGlobalJniEnv()->DeleteLocalRef(jstr);
res = new SkBitmap(*res);
} return iconBitmap;
cachedBitmaps[js] = res;
return res;
} }
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,107 +5,101 @@
#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;
float textSize ; float textSize;
float minDistance ; float minDistance;
int textColor; int textColor;
int textShadow ; int textShadow;
uint textWrap ; uint textWrap;
bool bold ; bool bold;
std::string shieldRes; std::string shieldRes;
int textOrder; int textOrder;
bool drawOnPath; bool drawOnPath;
SkPath* path; SkPath* path;
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, const 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()->GetIntField(rulePrope, RenderingRuleProperty_input); 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);
} }

File diff suppressed because it is too large Load diff

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();

61
OsmAnd/jni/png/Android.mk Executable file
View file

@ -0,0 +1,61 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
ifeq ($(OSMAND_PNG_LOC),)
OSMAND_PNG_LOC := ./png_library
endif
ifeq ($(OSMAND_PNG_ABS),)
OSMAND_PNG_ABS := $(LOCAL_PATH)/png_library
endif
common_SRC_FILES := \
$(OSMAND_PNG_LOC)/png.c \
$(OSMAND_PNG_LOC)/pngerror.c \
$(OSMAND_PNG_LOC)/pnggccrd.c \
$(OSMAND_PNG_LOC)/pngget.c \
$(OSMAND_PNG_LOC)/pngmem.c \
$(OSMAND_PNG_LOC)/pngpread.c \
$(OSMAND_PNG_LOC)/pngread.c \
$(OSMAND_PNG_LOC)/pngrio.c \
$(OSMAND_PNG_LOC)/pngrtran.c \
$(OSMAND_PNG_LOC)/pngrutil.c \
$(OSMAND_PNG_LOC)/pngset.c \
$(OSMAND_PNG_LOC)/pngtrans.c \
$(OSMAND_PNG_LOC)/pngvcrd.c \
$(OSMAND_PNG_LOC)/pngwio.c \
$(OSMAND_PNG_LOC)/pngwrite.c \
$(OSMAND_PNG_LOC)/pngwtran.c \
$(OSMAND_PNG_LOC)/pngwutil.c
common_CFLAGS := -fvisibility=hidden ## -fomit-frame-pointer
ifeq ($(HOST_OS),windows)
ifeq ($(USE_MINGW),)
# Case where we're building windows but not under linux (so it must be cygwin)
# In this case, gcc cygwin doesn't recognize -fvisibility=hidden
$(info libpng: Ignoring gcc flag $(common_CFLAGS) on Cygwin)
common_CFLAGS :=
endif
endif
common_C_INCLUDES +=
common_COPY_HEADERS_TO := libpng
common_COPY_HEADERS := png.h pngconf.h pngusr.h
LOCAL_SRC_FILES := $(common_SRC_FILES)
LOCAL_CFLAGS += $(common_CFLAGS)
LOCAL_C_INCLUDES += $(common_C_INCLUDES) \
external/zlib
LOCAL_SHARED_LIBRARIES := \
libz
ifneq ($(OSMAND_NEON),true)
LOCAL_MODULE := libpng
else
LOCAL_MODULE := libpng_neon
endif
include $(BUILD_STATIC_LIBRARY)

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

View file

@ -4,23 +4,23 @@ CC_LITE_SRC_FILES := \
google/protobuf/stubs/common.cc \ google/protobuf/stubs/common.cc \
google/protobuf/stubs/once.cc \ google/protobuf/stubs/once.cc \
google/protobuf/stubs/hash.cc \ google/protobuf/stubs/hash.cc \
google/protobuf/stubs/hash.h \
google/protobuf/stubs/map-util.h \
google/protobuf/stubs/stl_util-inl.h \
google/protobuf/extension_set.cc \ google/protobuf/extension_set.cc \
google/protobuf/generated_message_util.cc \ google/protobuf/generated_message_util.cc \
google/protobuf/message_lite.cc \ google/protobuf/message_lite.cc \
google/protobuf/repeated_field.cc \ google/protobuf/repeated_field.cc \
google/protobuf/wire_format_lite.cc \ google/protobuf/wire_format_lite.cc \
google/protobuf/io/coded_stream.cc \ google/protobuf/io/coded_stream.cc \
google/protobuf/io/coded_stream_inl.h \
google/protobuf/io/zero_copy_stream.cc \ google/protobuf/io/zero_copy_stream.cc \
google/protobuf/io/zero_copy_stream_impl_lite.cc google/protobuf/io/zero_copy_stream_impl_lite.cc
include $(CLEAR_VARS) include $(CLEAR_VARS)
ifneq ($(OSMAND_NEON),true)
LOCAL_MODULE := proto LOCAL_MODULE := proto
else
LOCAL_MODULE := proto_neon
LOCAL_ARM_NEON := true
endif
LOCAL_MODULE_TAGS := optional LOCAL_MODULE_TAGS := optional
LOCAL_CPP_EXTENSION := .cc LOCAL_CPP_EXTENSION := .cc

View file

@ -1,3 +0,0 @@
android
trunk
.gclient_entries

326
OsmAnd/jni/skia/Android.mk Executable file
View file

@ -0,0 +1,326 @@
# This file is based on external/skia/Android.mk from Android sources
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
ifneq ($(OSMAND_NEON),true)
LOCAL_MODULE := skia
else
LOCAL_MODULE := skia_neon
LOCAL_ARM_NEON := true
endif
ifeq ($(OSMAND_SKIA_LOC),)
OSMAND_SKIA_LOC := ./skia_library
endif
ifeq ($(OSMAND_SKIA_ABS),)
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
LOCAL_ARM_MODE := arm
# need a flag to tell the C side when we're on devices with large memory
# budgets (i.e. larger than the low-end devices that initially shipped)
ifeq ($(ARCH_ARM_HAVE_VFP),true)
LOCAL_CFLAGS += -DANDROID_LARGE_MEMORY_DEVICE
endif
ifneq ($(ARCH_ARM_HAVE_VFP),true)
LOCAL_CFLAGS += -DSK_SOFTWARE_FLOAT
endif
ifeq ($(LOCAL_ARM_NEON),true)
LOCAL_CFLAGS += -D__ARM_HAVE_NEON
endif
LOCAL_SRC_FILES := \
$(OSMAND_SKIA_LOC)/src/core/Sk64.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkAAClip.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkAdvancedTypefaceMetrics.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkAlphaRuns.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkBitmap.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkBitmapProcShader.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkBitmapProcState.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkBitmapProcState_matrixProcs.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkBitmapSampler.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkBitmap_scroll.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkBlitMask_D32.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkBlitRow_D16.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkBlitRow_D32.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkBlitRow_D4444.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkBlitter.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkBlitter_4444.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkBlitter_A1.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkBlitter_A8.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkBlitter_ARGB32.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkBlitter_RGB16.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkBlitter_Sprite.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkBuffer.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkCanvas.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkChunkAlloc.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkClampRange.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkClipStack.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkColor.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkColorFilter.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkColorTable.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkComposeShader.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkConcaveToTriangles.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkCordic.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkCubicClipper.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkData.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkDebug.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkDeque.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkDevice.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkDither.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkDraw.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkEdgeBuilder.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkEdgeClipper.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkEdge.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkFilterProc.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkFlattenable.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkFloat.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkFloatBits.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkFontHost.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkGeometry.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkGlyphCache.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkGraphics.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkLineClipper.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkMallocPixelRef.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkMask.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkMaskFilter.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkMath.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkMatrix.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkMetaData.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkMMapStream.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkPackBits.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkPaint.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkPath.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkPathEffect.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkPathHeap.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkPathMeasure.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkPicture.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkPictureFlat.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkPicturePlayback.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkPictureRecord.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkPixelRef.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkPoint.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkProcSpriteBlitter.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkPtrRecorder.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkQuadClipper.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkRasterClip.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkRasterizer.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkRect.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkRefDict.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkRegion.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkRegion_path.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkScalar.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkScalerContext.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkScan.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkScan_AntiPath.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkScan_Antihair.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkScan_Hairline.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkScan_Path.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkShader.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkShape.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkSpriteBlitter_ARGB32.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkSpriteBlitter_RGB16.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkStream.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkString.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkStroke.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkStrokerPriv.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkTSearch.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkTypeface.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkTypefaceCache.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkUnPreMultiply.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkUtils.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkFlate.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkWriter32.cpp \
$(OSMAND_SKIA_LOC)/src/core/SkXfermode.cpp \
$(OSMAND_SKIA_LOC)/src/effects/Sk1DPathEffect.cpp \
$(OSMAND_SKIA_LOC)/src/effects/Sk2DPathEffect.cpp \
$(OSMAND_SKIA_LOC)/src/effects/SkAvoidXfermode.cpp \
$(OSMAND_SKIA_LOC)/src/effects/SkArithmeticMode.cpp \
$(OSMAND_SKIA_LOC)/src/effects/SkBitmapCache.cpp \
$(OSMAND_SKIA_LOC)/src/effects/SkBlurDrawLooper.cpp \
$(OSMAND_SKIA_LOC)/src/effects/SkBlurImageFilter.cpp \
$(OSMAND_SKIA_LOC)/src/effects/SkBlurMask.cpp \
$(OSMAND_SKIA_LOC)/src/effects/SkBlurMaskFilter.cpp \
$(OSMAND_SKIA_LOC)/src/effects/SkColorFilters.cpp \
$(OSMAND_SKIA_LOC)/src/effects/SkColorMatrixFilter.cpp \
$(OSMAND_SKIA_LOC)/src/effects/SkCornerPathEffect.cpp \
$(OSMAND_SKIA_LOC)/src/effects/SkDashPathEffect.cpp \
$(OSMAND_SKIA_LOC)/src/effects/SkDiscretePathEffect.cpp \
$(OSMAND_SKIA_LOC)/src/effects/SkEffects.cpp \
$(OSMAND_SKIA_LOC)/src/effects/SkEmbossMask.cpp \
$(OSMAND_SKIA_LOC)/src/effects/SkEmbossMaskFilter.cpp \
$(OSMAND_SKIA_LOC)/src/effects/SkGradientShader.cpp \
$(OSMAND_SKIA_LOC)/src/effects/SkGroupShape.cpp \
$(OSMAND_SKIA_LOC)/src/effects/SkKernel33MaskFilter.cpp \
$(OSMAND_SKIA_LOC)/src/effects/SkLayerDrawLooper.cpp \
$(OSMAND_SKIA_LOC)/src/effects/SkLayerRasterizer.cpp \
$(OSMAND_SKIA_LOC)/src/effects/SkPaintFlagsDrawFilter.cpp \
$(OSMAND_SKIA_LOC)/src/effects/SkPixelXorXfermode.cpp \
$(OSMAND_SKIA_LOC)/src/effects/SkPorterDuff.cpp \
$(OSMAND_SKIA_LOC)/src/effects/SkRectShape.cpp \
$(OSMAND_SKIA_LOC)/src/effects/SkTableColorFilter.cpp \
$(OSMAND_SKIA_LOC)/src/effects/SkTableMaskFilter.cpp \
$(OSMAND_SKIA_LOC)/src/effects/SkTestImageFilters.cpp \
$(OSMAND_SKIA_LOC)/src/effects/SkTransparentShader.cpp \
$(OSMAND_SKIA_LOC)/src/images/bmpdecoderhelper.cpp \
$(OSMAND_SKIA_LOC)/src/images/SkCreateRLEPixelRef.cpp \
$(OSMAND_SKIA_LOC)/src/images/SkFDStream.cpp \
$(OSMAND_SKIA_LOC)/src/images/SkFlipPixelRef.cpp \
$(OSMAND_SKIA_LOC)/src/images/SkImageDecoder.cpp \
$(OSMAND_SKIA_LOC)/src/images/SkImageDecoder_Factory.cpp \
$(OSMAND_SKIA_LOC)/src/images/SkImageDecoder_libbmp.cpp \
$(OSMAND_SKIA_LOC)/src/images/SkImageDecoder_libgif.cpp \
$(OSMAND_SKIA_LOC)/src/images/SkImageDecoder_libico.cpp \
$(OSMAND_SKIA_LOC)/src/images/SkImageDecoder_libjpeg.cpp \
$(OSMAND_SKIA_LOC)/src/images/SkImageDecoder_libpng.cpp \
$(OSMAND_SKIA_LOC)/src/images/SkImageDecoder_wbmp.cpp \
$(OSMAND_SKIA_LOC)/src/images/SkImageEncoder.cpp \
$(OSMAND_SKIA_LOC)/src/images/SkImageEncoder_Factory.cpp \
$(OSMAND_SKIA_LOC)/src/images/SkImageRef.cpp \
$(OSMAND_SKIA_LOC)/src/images/SkImageRefPool.cpp \
$(OSMAND_SKIA_LOC)/src/images/SkImageRef_GlobalPool.cpp \
$(OSMAND_SKIA_LOC)/src/images/SkJpegUtility.cpp \
$(OSMAND_SKIA_LOC)/src/images/SkMovie.cpp \
$(OSMAND_SKIA_LOC)/src/images/SkMovie_gif.cpp \
$(OSMAND_SKIA_LOC)/src/images/SkPageFlipper.cpp \
$(OSMAND_SKIA_LOC)/src/images/SkScaledBitmapSampler.cpp \
$(OSMAND_SKIA_LOC)/src/ports/SkDebug_android.cpp \
$(OSMAND_SKIA_LOC)/src/ports/SkGlobalInitialization_default.cpp \
$(OSMAND_SKIA_LOC)/src/ports/SkFontHost_FreeType.cpp \
$(OSMAND_SKIA_LOC)/src/ports/SkFontHost_sandbox_none.cpp \
$(OSMAND_SKIA_LOC)/src/ports/SkFontHost_android.cpp \
$(OSMAND_SKIA_LOC)/src/ports/SkFontHost_gamma.cpp \
$(OSMAND_SKIA_LOC)/src/ports/SkFontHost_tables.cpp \
$(OSMAND_SKIA_LOC)/src/ports/SkMemory_malloc.cpp \
$(OSMAND_SKIA_LOC)/src/ports/SkOSFile_stdio.cpp \
$(OSMAND_SKIA_LOC)/src/ports/SkTime_Unix.cpp \
$(OSMAND_SKIA_LOC)/src/ports/SkThread_pthread.cpp \
$(OSMAND_SKIA_LOC)/src/utils/SkBoundaryPatch.cpp \
$(OSMAND_SKIA_LOC)/src/utils/SkCamera.cpp \
$(OSMAND_SKIA_LOC)/src/utils/SkColorMatrix.cpp \
$(OSMAND_SKIA_LOC)/src/utils/SkCubicInterval.cpp \
$(OSMAND_SKIA_LOC)/src/utils/SkCullPoints.cpp \
$(OSMAND_SKIA_LOC)/src/utils/SkDumpCanvas.cpp \
$(OSMAND_SKIA_LOC)/src/utils/SkInterpolator.cpp \
$(OSMAND_SKIA_LOC)/src/utils/SkLayer.cpp \
$(OSMAND_SKIA_LOC)/src/utils/SkMatrix44.cpp \
$(OSMAND_SKIA_LOC)/src/utils/SkMeshUtils.cpp \
$(OSMAND_SKIA_LOC)/src/utils/SkNinePatch.cpp \
$(OSMAND_SKIA_LOC)/src/utils/SkNWayCanvas.cpp \
$(OSMAND_SKIA_LOC)/src/utils/SkOSFile.cpp \
$(OSMAND_SKIA_LOC)/src/utils/SkParse.cpp \
$(OSMAND_SKIA_LOC)/src/utils/SkParseColor.cpp \
$(OSMAND_SKIA_LOC)/src/utils/SkParsePath.cpp \
$(OSMAND_SKIA_LOC)/src/utils/SkProxyCanvas.cpp \
$(OSMAND_SKIA_LOC)/src/utils/SkSfntUtils.cpp \
$(OSMAND_SKIA_LOC)/src/utils/SkUnitMappers.cpp
# This file is replacement of $(OSMAND_SKIA_LOC)/src/ports/FontHostConfiguration_android.cpp
LOCAL_SRC_FILES += \
FontHostConfiguration_android.cpp
LOCAL_C_INCLUDES += \
$(OSMAND_SKIA_ABS)/src/ports
ifeq ($(TARGET_ARCH),arm)
ifeq ($(LOCAL_ARM_NEON),true)
LOCAL_SRC_FILES += \
$(OSMAND_SKIA_LOC)/src/opts/memset16_neon.S \
$(OSMAND_SKIA_LOC)/src/opts/memset32_neon.S
endif
LOCAL_SRC_FILES += \
$(OSMAND_SKIA_LOC)/src/opts/opts_check_arm.cpp \
$(OSMAND_SKIA_LOC)/src/opts/memset.arm.S \
$(OSMAND_SKIA_LOC)/src/opts/SkBitmapProcState_opts_arm.cpp \
$(OSMAND_SKIA_LOC)/src/opts/SkBlitRow_opts_arm.cpp
else
LOCAL_SRC_FILES += \
$(OSMAND_SKIA_LOC)/src/opts/SkBlitRow_opts_none.cpp \
$(OSMAND_SKIA_LOC)/src/opts/SkBitmapProcState_opts_none.cpp \
$(OSMAND_SKIA_LOC)/src/opts/SkUtils_opts_none.cpp
endif
LOCAL_SHARED_LIBRARIES := \
libutils \
libz
ifeq ($(LOCAL_ARM_NEON),true)
LOCAL_STATIC_LIBRARIES += \
libjpeg_neon \
libft2_static_neon \
libpng_neon \
libgif_neon \
libexpat_static_neon
else
LOCAL_STATIC_LIBRARIES += \
libjpeg \
libft2_static \
libpng \
libgif \
libexpat_static
endif
LOCAL_C_INCLUDES += \
$(LOCAL_PATH) \
$(OSMAND_SKIA_ABS)/src/core \
$(OSMAND_SKIA_ABS)/include/core \
$(OSMAND_SKIA_ABS)/include/config \
$(OSMAND_SKIA_ABS)/include/effects \
$(OSMAND_SKIA_ABS)/include/images \
$(OSMAND_SKIA_ABS)/include/utils \
$(OSMAND_SKIA_ABS)/include/xml \
$(OSMAND_FREETYPE_ABS)/include \
$(OSMAND_PNG_ABS) \
$(OSMAND_GIF_ABS) \
$(OSMAND_EXPAT_ABS)/lib \
$(OSMAND_JPEG_ABS)
ifeq ($(NO_FALLBACK_FONT),true)
LOCAL_CFLAGS += -DNO_FALLBACK_FONT
endif
LOCAL_CFLAGS += \
-DSK_BUILD_FOR_ANDROID \
-DSK_BUILD_FOR_ANDROID_NDK \
-DSK_ALLOW_STATIC_GLOBAL_INITIALIZERS=0 \
-DSK_USE_POSIX_THREADS \
-DSK_RELEASE \
-DGR_RELEASE=1 \
-DNDEBUG
LOCAL_CPPFLAGS := \
-fno-rtti \
-fno-exceptions
LOCAL_LDLIBS += -lz -llog
include $(BUILD_STATIC_LIBRARY)
# Fix some errors
BUILD_HOST_EXECUTABLE := $(LOCAL_PATH)/FakeHost.mk
BUILD_HOST_STATIC_LIBRARY := $(LOCAL_PATH)/FakeHost.mk

1
OsmAnd/jni/skia/FakeHost.mk Executable file
View file

@ -0,0 +1 @@
include $(CLEAR_VARS)

View file

@ -0,0 +1,262 @@
/* FontHostConfiguration_android.cpp
**
** Based on file from SKIA
*/
#include "FontHostConfiguration_android.h"
#include <expat.h>
#include "SkTDArray.h"
#define SYSTEM_FONTS_FILE "/system/etc/system_fonts.xml"
#define FALLBACK_FONTS_FILE "/system/etc/fallback_fonts.xml"
#define VENDOR_FONTS_FILE "/vendor/etc/fallback_fonts.xml"
// These defines are used to determine the kind of tag that we're currently
// populating with data. We only care about the sibling tags nameset and fileset
// for now.
#define NO_TAG 0
#define NAMESET_TAG 1
#define FILESET_TAG 2
/**
* The FamilyData structure is passed around by the parser so that each handler
* can read these variables that are relevant to the current parsing.
*/
struct FamilyData {
FamilyData(XML_Parser *parserRef, SkTDArray<FontFamily*> &familiesRef) :
parser(parserRef), families(familiesRef), currentTag(NO_TAG) {};
XML_Parser *parser; // The expat parser doing the work
SkTDArray<FontFamily*> &families; // The array that each family is put into as it is parsed
FontFamily *currentFamily; // The current family being created
int currentTag; // A flag to indicate whether we're in nameset/fileset tags
};
/**
* Handler for arbitrary text. This is used to parse the text inside each name
* or file tag. The resulting strings are put into the fNames or fFileNames arrays.
*/
void textHandler(void *data, const char *s, int len) {
FamilyData *familyData = (FamilyData*) data;
// Make sure we're in the right state to store this name information
if (familyData->currentFamily &&
(familyData->currentTag == NAMESET_TAG || familyData->currentTag == FILESET_TAG)) {
// Malloc new buffer to store the string
char *buff;
buff = (char*) malloc((len + 1) * sizeof(char));
strncpy(buff, s, len);
buff[len] = '\0';
switch (familyData->currentTag) {
case NAMESET_TAG:
*(familyData->currentFamily->fNames.append()) = buff;
break;
case FILESET_TAG:
*(familyData->currentFamily->fFileNames.append()) = buff;
break;
default:
// Noop - don't care about any text that's not in the Fonts or Names list
break;
}
}
}
/**
* Handler for the start of a tag. The only tags we expect are family, nameset,
* fileset, name, and file.
*/
void startElementHandler(void *data, const char *tag, const char **atts) {
FamilyData *familyData = (FamilyData*) data;
int len = strlen(tag);
if (strncmp(tag, "family", len)== 0) {
familyData->currentFamily = new FontFamily();
familyData->currentFamily->order = -1;
// The Family tag has an optional "order" attribute with an integer value >= 0
// If this attribute does not exist, the default value is -1
for (int i = 0; atts[i] != NULL; i += 2) {
const char* attribute = atts[i];
const char* valueString = atts[i+1];
int value;
int len = sscanf(valueString, "%d", &value);
if (len > 0) {
familyData->currentFamily->order = value;
}
}
} else if (len == 7 && strncmp(tag, "nameset", len)== 0) {
familyData->currentTag = NAMESET_TAG;
} else if (len == 7 && strncmp(tag, "fileset", len) == 0) {
familyData->currentTag = FILESET_TAG;
} else if ((strncmp(tag, "name", len) == 0 && familyData->currentTag == NAMESET_TAG) ||
(strncmp(tag, "file", len) == 0 && familyData->currentTag == FILESET_TAG)) {
// If it's a Name, parse the text inside
XML_SetCharacterDataHandler(*familyData->parser, textHandler);
}
}
/**
* Handler for the end of tags. We only care about family, nameset, fileset,
* name, and file.
*/
void endElementHandler(void *data, const char *tag) {
FamilyData *familyData = (FamilyData*) data;
int len = strlen(tag);
if (strncmp(tag, "family", len)== 0) {
// Done parsing a Family - store the created currentFamily in the families array
*familyData->families.append() = familyData->currentFamily;
familyData->currentFamily = NULL;
} else if (len == 7 && strncmp(tag, "nameset", len)== 0) {
familyData->currentTag = NO_TAG;
} else if (len == 7 && strncmp(tag, "fileset", len)== 0) {
familyData->currentTag = NO_TAG;
} else if ((strncmp(tag, "name", len) == 0 && familyData->currentTag == NAMESET_TAG) ||
(strncmp(tag, "file", len) == 0 && familyData->currentTag == FILESET_TAG)) {
// Disable the arbitrary text handler installed to load Name data
XML_SetCharacterDataHandler(*familyData->parser, NULL);
}
}
/**
* This function parses the given filename and stores the results in the given
* families array.
*/
void parseConfigFile(const char *filename, SkTDArray<FontFamily*> &families) {
XML_Parser parser = XML_ParserCreate(NULL);
FamilyData *familyData = new FamilyData(&parser, families);
XML_SetUserData(parser, familyData);
XML_SetElementHandler(parser, startElementHandler, endElementHandler);
FILE *file = fopen(filename, "r");
// Some of the files we attempt to parse (in particular, /vendor/etc/fallback_fonts.xml)
// are optional - failure here is okay because one of these optional files may not exist.
if (file == NULL) {
return;
}
char buffer[512];
bool done = false;
while (!done) {
fgets(buffer, sizeof(buffer), file);
int len = strlen(buffer);
if (feof(file) != 0) {
done = true;
}
XML_Parse(parser, buffer, len, done);
}
}
/**
* Loads data on font families from various expected configuration files. The
* resulting data is returned in the given fontFamilies array.
*/
void getFontFamilies(SkTDArray<FontFamily*> &fontFamilies) {
SkTDArray<FontFamily*> fallbackFonts;
SkTDArray<FontFamily*> vendorFonts;
parseConfigFile(SYSTEM_FONTS_FILE, fontFamilies);
parseConfigFile(FALLBACK_FONTS_FILE, fallbackFonts);
parseConfigFile(VENDOR_FONTS_FILE, vendorFonts);
// This loop inserts the vendor fallback fonts in the correct order in the
// overall fallbacks list.
int currentOrder = -1;
for (int i = 0; i < vendorFonts.count(); ++i) {
FontFamily* family = vendorFonts[i];
int order = family->order;
if (order < 0) {
if (currentOrder < 0) {
// Default case - just add it to the end of the fallback list
*fallbackFonts.append() = family;
} else {
// no order specified on this font, but we're incrementing the order
// based on an earlier order insertion request
*fallbackFonts.insert(currentOrder++) = family;
}
} else {
// Add the font into the fallback list in the specified order. Set
// currentOrder for correct placement of other fonts in the vendor list.
*fallbackFonts.insert(order) = family;
currentOrder = order + 1;
}
}
// Append all fallback fonts to system fonts
for (int i = 0; i < fallbackFonts.count(); ++i) {
*fontFamilies.append() = fallbackFonts[i];
}
//===============================================================================
// Below is addition to use new SKIA library on old Android systems
// Used code from latest SKIA in Android 2.x branch
//===============================================================================
if( fontFamilies.count() == 0 ) {
struct FontInitRec {
const char* fFileName;
const char* const* fNames; // null-terminated list
};
static const char* gSansNames[] = {
"sans-serif", "arial", "helvetica", "tahoma", "verdana", NULL
};
static const char* gSerifNames[] = {
"serif", "times", "times new roman", "palatino", "georgia", "baskerville",
"goudy", "fantasy", "cursive", "ITC Stone Serif", NULL
};
static const char* gMonoNames[] = {
"monospace", "courier", "courier new", "monaco", NULL
};
// deliberately empty, but we use the address to identify fallback fonts
static const char* gFBNames[] = { NULL };
/* Fonts must be grouped by family, with the first font in a family having the
list of names (even if that list is empty), and the following members having
null for the list. The names list must be NULL-terminated
*/
static const FontInitRec gSystemFonts[] = {
{ "DroidSans.ttf", gSansNames },
{ "DroidSans-Bold.ttf", NULL },
{ "DroidSerif-Regular.ttf", gSerifNames },
{ "DroidSerif-Bold.ttf", NULL },
{ "DroidSerif-Italic.ttf", NULL },
{ "DroidSerif-BoldItalic.ttf", NULL },
{ "DroidSansMono.ttf", gMonoNames },
/* These are optional, and can be ignored if not found in the file system.
These are appended to gFallbackFonts[] as they are seen, so we list
them in the order we want them to be accessed by NextLogicalFont().
*/
{ "DroidSansArabic.ttf", gFBNames },
{ "DroidSansHebrew.ttf", gFBNames },
{ "DroidSansThai.ttf", gFBNames },
{ "MTLmr3m.ttf", gFBNames }, // Motoya Japanese Font
{ "MTLc3m.ttf", gFBNames }, // Motoya Japanese Font
{ "DroidSansJapanese.ttf", gFBNames },
{ "DroidSansFallback.ttf", gFBNames }
};
const FontInitRec* rec = gSystemFonts;
FontFamily* newFontFamily = NULL;
for (size_t i = 0; i < SK_ARRAY_COUNT(gSystemFonts); i++) {
// Marker that we're in the beginning of a new family
if (rec[i].fNames != NULL) {
if(newFontFamily != NULL)
*fontFamilies.append() = newFontFamily;
newFontFamily = new FontFamily();
newFontFamily->order = -1;
}
// Append file name
*(newFontFamily->fFileNames.append()) = rec[i].fFileName;
// Append names
if(rec[i].fNames != NULL) {
const char* const* names = rec[i].fNames;
while (*names) {
*(newFontFamily->fNames.append()) = *names;
names += 1;
}
}
}
}
//===============================================================================
// End of addition
//===============================================================================
}

View file

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

0
OsmAnd/jni/skia/utils/misc.h Executable file
View file

Binary file not shown.

View file

@ -1077,69 +1077,78 @@ public class MapActivity extends TrackedActivity implements IMapLocationListener
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) { final int itemId = item.getItemId();
case R.id.map_show_settings: if (itemId == R.id.map_show_settings) {
final Intent intentSettings = new Intent(MapActivity.this, final Intent intentSettings = new Intent(MapActivity.this,
SettingsActivity.class); SettingsActivity.class);
startActivity(intentSettings); startActivity(intentSettings);
return true; return true;
case R.id.map_where_am_i: } else if (itemId == R.id.map_where_am_i) {
backToLocationImpl(); backToLocationImpl();
return true; return true;
case R.id.map_show_gps_status: } else if (itemId == R.id.map_show_gps_status) {
startGpsStatusIntent(); startGpsStatusIntent();
return true; return true;
case R.id.map_get_directions: } else if (itemId == R.id.map_get_directions) {
if(routingHelper.isRouteCalculated()){ if (routingHelper.isRouteCalculated()) {
mapActions.aboutRoute(); mapActions.aboutRoute();
} else { } else {
Location loc = getLastKnownLocation(); Location loc = getLastKnownLocation();
if (loc != null) { if (loc != null) {
mapActions.getDirections(loc.getLatitude(), loc.getLongitude(), true); mapActions.getDirections(loc.getLatitude(),
loc.getLongitude(), true);
} else { } else {
mapActions.getDirections(mapView.getLatitude(), mapView.getLongitude(), true); mapActions.getDirections(mapView.getLatitude(),
mapView.getLongitude(), true);
} }
} }
return true; return true;
case R.id.map_layers: } else if (itemId == R.id.map_layers) {
mapLayers.openLayerSelectionDialog(mapView); mapLayers.openLayerSelectionDialog(mapView);
return true; return true;
case R.id.map_specify_point: } else if (itemId == R.id.map_specify_point) {
// next 2 lines replaced for Issue 493, replaced by new 3 lines // next 2 lines replaced for Issue 493, replaced by new 3 lines
// NavigatePointActivity dlg = new NavigatePointActivity(this); // NavigatePointActivity dlg = new NavigatePointActivity(this);
// dlg.showDialog(); // dlg.showDialog();
Intent newIntent = new Intent(MapActivity.this, SearchActivity.class); Intent newIntent = new Intent(MapActivity.this,
// causes wrong position caching: newIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); SearchActivity.class);
// causes wrong position caching:
// newIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
LatLon mapLoc = getMapLocation(); LatLon mapLoc = getMapLocation();
newIntent.putExtra(SearchActivity.SEARCH_LAT, mapLoc.getLatitude()); newIntent.putExtra(SearchActivity.SEARCH_LAT, mapLoc.getLatitude());
newIntent.putExtra(SearchActivity.SEARCH_LON, mapLoc.getLongitude()); newIntent
.putExtra(SearchActivity.SEARCH_LON, mapLoc.getLongitude());
newIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); newIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(newIntent); startActivity(newIntent);
return true; return true;
case R.id.map_mute: } else if (itemId == R.id.map_mute) {
routingHelper.getVoiceRouter().setMute( routingHelper.getVoiceRouter().setMute(
!routingHelper.getVoiceRouter().isMute()); !routingHelper.getVoiceRouter().isMute());
return true; return true;
case R.id.map_navigate_to_point: } else if (itemId == R.id.map_navigate_to_point) {
if (mapLayers.getNavigationLayer().getPointToNavigate() != null) { if (mapLayers.getNavigationLayer().getPointToNavigate() != null) {
if(routingHelper.isRouteCalculated() || routingHelper.isFollowingMode() || routingHelper.isRouteBeingCalculated()){ if (routingHelper.isRouteCalculated()
routingHelper.setFinalAndCurrentLocation(null, routingHelper.getCurrentLocation(), routingHelper.getCurrentGPXRoute()); || routingHelper.isFollowingMode()
|| routingHelper.isRouteBeingCalculated()) {
routingHelper.setFinalAndCurrentLocation(null,
routingHelper.getCurrentLocation(),
routingHelper.getCurrentGPXRoute());
} else { } else {
navigateToPoint(null); navigateToPoint(null);
} }
} else { } else {
navigateToPoint(new LatLon(mapView.getLatitude(), mapView.getLongitude())); navigateToPoint(new LatLon(mapView.getLatitude(), mapView.getLongitude()));
} }
mapView.refreshMap(); mapView.refreshMap();
return true; return true;
case R.id.map_show_point_options: } else if (itemId == R.id.map_show_point_options) {
contextMenuPoint(mapView.getLatitude(), mapView.getLongitude()); contextMenuPoint(mapView.getLatitude(), mapView.getLongitude());
return true; return true;
case R.id.map_animate_route: } else if (itemId == R.id.map_animate_route) {
//animate moving on route // animate moving on route
routeAnimation.startStopRouteAnimation(routingHelper, this); routeAnimation.startStopRouteAnimation(routingHelper, this);
return true; return true;
default: } else {
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
} }
} }

View file

@ -1,13 +1,19 @@
package net.osmand.plus.render; package net.osmand.plus.render;
import org.apache.commons.logging.Log;
import java.nio.ByteBuffer;
import net.osmand.LogUtil;
import net.osmand.plus.render.OsmandRenderer.RenderingContext; import net.osmand.plus.render.OsmandRenderer.RenderingContext;
import net.osmand.render.RenderingRuleSearchRequest; import net.osmand.render.RenderingRuleSearchRequest;
import net.osmand.render.RenderingRulesStorage; import net.osmand.render.RenderingRulesStorage;
import android.graphics.Bitmap; import android.graphics.Bitmap;
public class NativeOsmandLibrary { public class NativeOsmandLibrary {
private static final Log log = LogUtil.getLog(NativeOsmandLibrary.class);
private static NativeOsmandLibrary library; private static NativeOsmandLibrary library;
private static Boolean isNativeSupported = null; private static Boolean isNativeSupported = null;
@ -16,14 +22,31 @@ public class NativeOsmandLibrary {
synchronized (NativeOsmandLibrary.class) { synchronized (NativeOsmandLibrary.class) {
if (!isLoaded()) { if (!isLoaded()) {
try { try {
System.loadLibrary("osmand"); log.debug("Loading native stlport_shared..."); //$NON-NLS-1$
System.loadLibrary("stlport_shared");
log.debug("Loading native cpufeatures_proxy..."); //$NON-NLS-1$
System.loadLibrary("cpufeatures_proxy");
if(android.os.Build.VERSION.SDK_INT >= 8) {
log.debug("Loading jnigraphics, since Android >= 2.2 ..."); //$NON-NLS-1$
System.loadLibrary("jnigraphics");
}
if(!cpuHasNeonSupport()) {
log.debug("Loading native osmand..."); //$NON-NLS-1$
System.loadLibrary("osmand");
} else {
log.debug("Loading native osmand with NEON..."); //$NON-NLS-1$
System.loadLibrary("osmand_neon");
}
log.debug("Creating NativeOsmandLibrary instance..."); //$NON-NLS-1$
library = new NativeOsmandLibrary(); library = new NativeOsmandLibrary();
log.debug("Initializing rendering rules storage..."); //$NON-NLS-1$
NativeOsmandLibrary.initRenderingRulesStorage(storage); NativeOsmandLibrary.initRenderingRulesStorage(storage);
isNativeSupported = true; isNativeSupported = true;
log.debug("Native library loaded successfully"); //$NON-NLS-1$
} catch (Throwable e) { } catch (Throwable e) {
log.error("Failed to load native library", e); //$NON-NLS-1$
isNativeSupported = false; isNativeSupported = false;
} }
} }
} }
} }
@ -46,12 +69,18 @@ public class NativeOsmandLibrary {
return isSupported(); return isSupported();
} }
public String generateRendering(RenderingContext rc, NativeSearchResult searchResultHandler, Bitmap bmp, public RenderingGenerationResult generateRendering(RenderingContext rc, NativeSearchResult searchResultHandler,
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 "Error searchresult = null"; log.error("Error searchresult = null"); //$NON-NLS-1$
return new RenderingGenerationResult(null);
} }
return generateRendering(rc, searchResultHandler.nativeHandler, bmp, useEnglishNames, render, defaultColor);
if(android.os.Build.VERSION.SDK_INT >= 8) // Android 2.2+
return generateRendering_Direct(rc, searchResultHandler.nativeHandler, bitmap, useEnglishNames, render, defaultColor);
else
return generateRendering_Indirect(rc, searchResultHandler.nativeHandler, requestedBitmapWidth, requestedBitmapHeight, rowBytes, isTransparent, useEnglishNames, render, defaultColor);
} }
/** /**
@ -101,16 +130,31 @@ public class NativeOsmandLibrary {
deleteSearchResult(nativeHandler); deleteSearchResult(nativeHandler);
} }
} }
public static class RenderingGenerationResult {
public RenderingGenerationResult(ByteBuffer bitmap) {
bitmapBuffer = bitmap;
}
public final ByteBuffer bitmapBuffer;
}
private static native void deleteSearchResult(int searchResultHandle); private static native void deleteSearchResult(int searchResultHandle);
private static native boolean initBinaryMapFile(String filePath); private static native boolean initBinaryMapFile(String filePath);
private static native boolean initRenderingRulesStorage(RenderingRulesStorage storage); private static native void initRenderingRulesStorage(RenderingRulesStorage storage);
private static native String generateRendering(RenderingContext rc, int searchResultHandler, Bitmap bmp, boolean useEnglishNames, private static native RenderingGenerationResult generateRendering_Indirect(RenderingContext rc, int searchResultHandler,
int requestedBitmapWidth, int requestedBitmapHeight, int rowBytes, boolean isTransparent, boolean useEnglishNames,
RenderingRuleSearchRequest render, int defaultColor);
private static native RenderingGenerationResult generateRendering_Direct(RenderingContext rc, int searchResultHandler,
Bitmap bitmap, boolean useEnglishNames,
RenderingRuleSearchRequest render, int defaultColor); RenderingRuleSearchRequest render, int defaultColor);
private static native int searchObjectsForRendering(int sleft, int sright, int stop, int sbottom, int zoom, String mapnaem, private static native int searchObjectsForRendering(int sleft, int sright, int stop, int sbottom, int zoom, String mapnaem,
RenderingRuleSearchRequest request, boolean skipDuplicates, int searchResultHandler, Object objectWithInterruptedField); RenderingRuleSearchRequest request, boolean skipDuplicates, int searchResultHandler, Object objectWithInterruptedField);
public static native int getCpuCount();
public static native boolean cpuHasNeonSupport();
} }

View file

@ -199,7 +199,8 @@ public class OsmandRenderer {
* @return if map could be replaced * @return if map could be replaced
*/ */
public void generateNewBitmapNative(RenderingContext rc, NativeOsmandLibrary library, public void generateNewBitmapNative(RenderingContext rc, NativeOsmandLibrary library,
NativeSearchResult searchResultHandler, Bitmap bmp, boolean useEnglishNames, NativeSearchResult searchResultHandler,
Bitmap bmp, boolean useEnglishNames,
RenderingRuleSearchRequest render, final List<IMapDownloaderCallback> notifyList, int defaultColor) { RenderingRuleSearchRequest render, final List<IMapDownloaderCallback> notifyList, int defaultColor) {
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
if (rc.width > 0 && rc.height > 0 && searchResultHandler != null) { if (rc.width > 0 && rc.height > 0 && searchResultHandler != null) {
@ -213,13 +214,25 @@ public class OsmandRenderer {
final Handler h = new Handler(Looper.getMainLooper()); final Handler h = new Handler(Looper.getMainLooper());
notifyListenersWithDelay(rc, notifyList, h); notifyListenersWithDelay(rc, notifyList, h);
} }
String res = library.generateRendering(rc, searchResultHandler, bmp, useEnglishNames, render, defaultColor);
// Native library will decide on it's own best way of rendering
// If res.bitmapBuffer is null, it indicates that rendering was done directly to
// memory of passed bitmap, but this is supported only on Android >= 2.2
final NativeOsmandLibrary.RenderingGenerationResult res = library.generateRendering(
rc, searchResultHandler,
bmp, bmp.getWidth(), bmp.getHeight(), bmp.getRowBytes(), bmp.hasAlpha(),
useEnglishNames, render, defaultColor);
rc.ended = true; rc.ended = true;
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,//$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
if(res.bitmapBuffer != null) {
bmp.copyPixelsFromBuffer(res.bitmapBuffer);
}
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }

View file

@ -3,16 +3,24 @@ 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 java.io.ByteArrayOutputStream;
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 +30,34 @@ public class RenderingIcons {
return icons.containsKey(s); return icons.containsKey(s);
} }
public static byte[] getIconRawData(Context ctx, String s) {
Integer resId = icons.get(s);
// Quite bad error
if(resId == null)
return null;
try {
final InputStream inputStream = ctx.getResources().openRawResource(resId.intValue());
final ByteArrayOutputStream proxyOutputStream = new ByteArrayOutputStream(1024);
final byte[] ioBuffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(ioBuffer)) >= 0) {
proxyOutputStream.write(ioBuffer, 0, bytesRead);
}
inputStream.close();
final byte[] bitmapData = proxyOutputStream.toByteArray();
log.info("Icon data length is " + bitmapData.length); //$NON-NLS-1$
//if(android.graphics.BitmapFactory.decodeByteArray(bitmapData, 0, bitmapData.length) == null)
// throw new Exception();
return bitmapData;
} 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);