标签:chromium skia typeface android jni 浏览器开发
这也就是说,Java Activity层的用户自定义默认字体通过标准framework/JNI的途径是无法传递应用到Chromium内核的。
本来的基本想法是:通过Typeface.DEFAULT获得Java层的系统当前默认字体设置,通过Java动态反射调用获得native_instance句柄,然后尝试用JNI C++代码获得SkTypeface*指针,调用SkTypeface::serialize序列化到一个临时字体文件,然后将此路径回传Java,再重新传到Chromium内核代码。
帖2段核心demo代码:
AwSettings.java:
//#if ENABLE_USER_OVERRIDES_FONTFALLBACK
//hacker techniques to get current system's default typeface and apply it to chromium/skia kernel code:
@CalledByNative
private static long getDefaultTypefaceNativePointer() {
try{
android.graphics.Typeface defaultTypeface = android.graphics.Typeface.DEFAULT;
java.lang.reflect.Field field = null;
field = android.graphics.Typeface.class.getDeclaredField("native_instance");
long ret = 0;
if (android.os.Build.VERSION.SDK_INT>=21) {
//5.0+
ret = field.getLong(defaultTypeface);
}else{
//4.4-
ret = field.getInt(defaultTypeface);//boost to long
}
Log.i(TAG, "android.graphics.Typeface.DEFAULT.native_instance="+ret);
return ret;
}catch(Exception e){
Log.e(TAG, e.getMessage(), e);
return 0;
}
}
//private boolean sUserOverridesFontFallbackEnabled = false;
private static native String nativeGetTempUserOverridesFontFallbackPath();
public void setUserOverridesFontFallbackEnabled(boolean enable) {
if (enable) {
String path = AwSettings.nativeGetTempUserOverridesFontFallbackPath();
setUserOverridesFontFallback(true, path);
}else{
setUserOverridesFontFallback(false, "");
}
}
//#ifaw_settings.cc:
#if ENABLE_USER_OVERRIDES_FONTFALLBACK
static jstring GetTempUserOverridesFontFallbackPath(JNIEnv* env, jclass clazz) {
VLOG(0)<<"GetTempUserOverridesFontFallbackPath enter";
jlong native_instance_pointer = Java_AwSettings_getDefaultTypefaceNativePointer(env);
if(native_instance_pointer==0){
VLOG(0)<<"GetTempUserOverridesFontFallbackPath getDefaultTypefaceNativePointer failed!";
return 0;
}
//SkTypeface* typeface = (SkTypeface*)(int)native_instance_pointer;
// //ALERT: this C++ SkTypeface is got from framework layer, it may not have the same ABI compatibility with chromioum's internal skia library
TypefaceImpl* typefaceImpl = (TypefaceImpl*)native_instance_pointer;
SkTypeface* typeface = 0; //TODO: cannot get SkTypeface* from TypefaceImpl*
//i need a writable path!
FilePath cache_dir_filepath;
/*bool ret = */base::android::GetCacheDirectory(&cache_dir_filepath);
FilePath temp_filepath = cache_dir_filepath.Append( FilePath("test.ttf.ser") ); //<-- TODO: generate this
std::string gen_temp_path = temp_filepath.AsUTF8Unsafe();
const char* temp_path = gen_temp_path.c_str(); //"/data/local/test.ttf.ser";
VLOG(0)<<"GetTempUserOverridesFontFallbackPath gen_temp_path="<<temp_path;
SkFILEWStream wstream(temp_path);
typeface->serialize(&wstream);//may fail, but we don't know!
ScopedJavaLocalRef<jstring> jpath = ConvertUTF8ToJavaString(env, temp_path);
return jpath.Release();
}
#endifAndroid Chromium:不成功的尝试,无法从Typeface.java类获得C++ SkTypeface对象
标签:chromium skia typeface android jni 浏览器开发
原文地址:http://blog.csdn.net/cteng/article/details/43085097