19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "jni.h" 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <android_runtime/AndroidRuntime.h> 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "GraphicsJNI.h" 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkStream.h" 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkTypeface.h" 7b13b9bdad2baf6ad1ec2e56b6b7598fa20f55fc4Mathias Agopian#include <android_runtime/android_util_AssetManager.h> 8b13b9bdad2baf6ad1ec2e56b6b7598fa20f55fc4Mathias Agopian#include <androidfw/AssetManager.h> 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectusing namespace android; 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass AutoJavaStringToUTF8 { 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic: 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AutoJavaStringToUTF8(JNIEnv* env, jstring str) : fEnv(env), fJStr(str) 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fCStr = env->GetStringUTFChars(str, NULL); 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ~AutoJavaStringToUTF8() 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fEnv->ReleaseStringUTFChars(fJStr, fCStr); 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* c_str() const { return fCStr; } 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectprivate: 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project JNIEnv* fEnv; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jstring fJStr; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* fCStr; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic SkTypeface* Typeface_create(JNIEnv* env, jobject, jstring name, 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkTypeface::Style style) { 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkTypeface* face; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (NULL == name) { 354df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project face = SkTypeface::CreateFromName(NULL, (SkTypeface::Style)style); 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else { 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AutoJavaStringToUTF8 str(env, name); 394df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project face = SkTypeface::CreateFromName(str.c_str(), style); 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return face; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic SkTypeface* Typeface_createFromTypeface(JNIEnv* env, jobject, SkTypeface* family, int style) { 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return SkTypeface::CreateFromTypeface(family, (SkTypeface::Style)style); 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 474cb1753ec6e90d7e747880c599dc1c164a568cf3Elliott Hughes 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void Typeface_unref(JNIEnv* env, jobject obj, SkTypeface* face) { 4931a69fdbe1edd8d686043e8ca7d278289f65808eMike Reed SkSafeUnref(face); 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int Typeface_getStyle(JNIEnv* env, jobject obj, SkTypeface* face) { 534df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project return face->style(); 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass AssetStream : public SkStream { 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic: 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AssetStream(Asset* asset, bool hasMemoryBase) : fAsset(asset) 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fMemoryBase = hasMemoryBase ? fAsset->getBuffer(false) : NULL; 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project virtual ~AssetStream() 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete fAsset; 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 674cb1753ec6e90d7e747880c599dc1c164a568cf3Elliott Hughes 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project virtual const void* getMemoryBase() 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return fMemoryBase; 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project virtual bool rewind() 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 75ddb76c4644756b31be948d70aaa8ee541dd94999Kenny Root off64_t pos = fAsset->seek(0, SEEK_SET); 76ddb76c4644756b31be948d70aaa8ee541dd94999Kenny Root return pos != (off64_t)-1; 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 784cb1753ec6e90d7e747880c599dc1c164a568cf3Elliott Hughes 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project virtual size_t read(void* buffer, size_t size) 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t amount; 824cb1753ec6e90d7e747880c599dc1c164a568cf3Elliott Hughes 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (NULL == buffer) 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (0 == size) // caller is asking us for our total length 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return fAsset->getLength(); 874cb1753ec6e90d7e747880c599dc1c164a568cf3Elliott Hughes 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // asset->seek returns new total offset 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we want to return amount that was skipped 904cb1753ec6e90d7e747880c599dc1c164a568cf3Elliott Hughes 91ddb76c4644756b31be948d70aaa8ee541dd94999Kenny Root off64_t oldOffset = fAsset->seek(0, SEEK_CUR); 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (-1 == oldOffset) 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 94ddb76c4644756b31be948d70aaa8ee541dd94999Kenny Root off64_t newOffset = fAsset->seek(size, SEEK_CUR); 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (-1 == newOffset) 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 974cb1753ec6e90d7e747880c599dc1c164a568cf3Elliott Hughes 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project amount = newOffset - oldOffset; 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project amount = fAsset->read(buffer, size); 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1044cb1753ec6e90d7e747880c599dc1c164a568cf3Elliott Hughes 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (amount < 0) 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project amount = 0; 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return amount; 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1094cb1753ec6e90d7e747880c599dc1c164a568cf3Elliott Hughes 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectprivate: 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Asset* fAsset; 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const void* fMemoryBase; 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic SkTypeface* Typeface_createFromAsset(JNIEnv* env, jobject, 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jobject jassetMgr, 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jstring jpath) { 1184cb1753ec6e90d7e747880c599dc1c164a568cf3Elliott Hughes 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NPE_CHECK_RETURN_ZERO(env, jassetMgr); 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NPE_CHECK_RETURN_ZERO(env, jpath); 1214cb1753ec6e90d7e747880c599dc1c164a568cf3Elliott Hughes 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AssetManager* mgr = assetManagerForJavaObject(env, jassetMgr); 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (NULL == mgr) { 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1264cb1753ec6e90d7e747880c599dc1c164a568cf3Elliott Hughes 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AutoJavaStringToUTF8 str(env, jpath); 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Asset* asset = mgr->open(str.c_str(), Asset::ACCESS_BUFFER); 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (NULL == asset) { 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1324cb1753ec6e90d7e747880c599dc1c164a568cf3Elliott Hughes 133a1db574036c9bc2d397b69f8200594027e1fff16Romain Guy SkStream* stream = new AssetStream(asset, true); 134a1db574036c9bc2d397b69f8200594027e1fff16Romain Guy SkTypeface* face = SkTypeface::CreateFromStream(stream); 135a1db574036c9bc2d397b69f8200594027e1fff16Romain Guy // SkTypeFace::CreateFromStream calls ref() on the stream, so we 136a1db574036c9bc2d397b69f8200594027e1fff16Romain Guy // need to unref it here or it won't be freed later on 137a1db574036c9bc2d397b69f8200594027e1fff16Romain Guy stream->unref(); 138a1db574036c9bc2d397b69f8200594027e1fff16Romain Guy 139a1db574036c9bc2d397b69f8200594027e1fff16Romain Guy return face; 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 142a87a132ebf1c2dd733cf52feff6e44525257c961Romain Guystatic SkTypeface* Typeface_createFromFile(JNIEnv* env, jobject, jstring jpath) { 143a87a132ebf1c2dd733cf52feff6e44525257c961Romain Guy NPE_CHECK_RETURN_ZERO(env, jpath); 144a87a132ebf1c2dd733cf52feff6e44525257c961Romain Guy 145a87a132ebf1c2dd733cf52feff6e44525257c961Romain Guy AutoJavaStringToUTF8 str(env, jpath); 146a87a132ebf1c2dd733cf52feff6e44525257c961Romain Guy 147a87a132ebf1c2dd733cf52feff6e44525257c961Romain Guy return SkTypeface::CreateFromFile(str.c_str()); 148a87a132ebf1c2dd733cf52feff6e44525257c961Romain Guy} 149a87a132ebf1c2dd733cf52feff6e44525257c961Romain Guy 150dbade9d6a075b1d5b8ebe10ee8961a5de296c93bMike Reed#define MIN_GAMMA (0.1f) 151dbade9d6a075b1d5b8ebe10ee8961a5de296c93bMike Reed#define MAX_GAMMA (10.0f) 152dbade9d6a075b1d5b8ebe10ee8961a5de296c93bMike Reedstatic float pinGamma(float gamma) { 153dbade9d6a075b1d5b8ebe10ee8961a5de296c93bMike Reed if (gamma < MIN_GAMMA) { 154dbade9d6a075b1d5b8ebe10ee8961a5de296c93bMike Reed gamma = MIN_GAMMA; 155dbade9d6a075b1d5b8ebe10ee8961a5de296c93bMike Reed } else if (gamma > MAX_GAMMA) { 156dbade9d6a075b1d5b8ebe10ee8961a5de296c93bMike Reed gamma = MAX_GAMMA; 157dbade9d6a075b1d5b8ebe10ee8961a5de296c93bMike Reed } 158dbade9d6a075b1d5b8ebe10ee8961a5de296c93bMike Reed return gamma; 159dbade9d6a075b1d5b8ebe10ee8961a5de296c93bMike Reed} 160dbade9d6a075b1d5b8ebe10ee8961a5de296c93bMike Reed 161dbade9d6a075b1d5b8ebe10ee8961a5de296c93bMike Reedextern void skia_set_text_gamma(float, float); 162dbade9d6a075b1d5b8ebe10ee8961a5de296c93bMike Reed 163dbade9d6a075b1d5b8ebe10ee8961a5de296c93bMike Reedstatic void Typeface_setGammaForText(JNIEnv* env, jobject, jfloat blackGamma, 164dbade9d6a075b1d5b8ebe10ee8961a5de296c93bMike Reed jfloat whiteGamma) { 165dbade9d6a075b1d5b8ebe10ee8961a5de296c93bMike Reed // Comment this out for release builds. This is only used during development 166dbade9d6a075b1d5b8ebe10ee8961a5de296c93bMike Reed skia_set_text_gamma(pinGamma(blackGamma), pinGamma(whiteGamma)); 167dbade9d6a075b1d5b8ebe10ee8961a5de296c93bMike Reed} 168dbade9d6a075b1d5b8ebe10ee8961a5de296c93bMike Reed 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod gTypefaceMethods[] = { 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "nativeCreate", "(Ljava/lang/String;I)I", (void*)Typeface_create }, 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "nativeCreateFromTypeface", "(II)I", (void*)Typeface_createFromTypeface }, 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "nativeUnref", "(I)V", (void*)Typeface_unref }, 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "nativeGetStyle", "(I)I", (void*)Typeface_getStyle }, 176a87a132ebf1c2dd733cf52feff6e44525257c961Romain Guy { "nativeCreateFromAsset", "(Landroid/content/res/AssetManager;Ljava/lang/String;)I", 177a87a132ebf1c2dd733cf52feff6e44525257c961Romain Guy (void*)Typeface_createFromAsset }, 1782bb3ea162a58c0f1dddccdbe68b64e02456f11f9Romain Guy { "nativeCreateFromFile", "(Ljava/lang/String;)I", 179dbade9d6a075b1d5b8ebe10ee8961a5de296c93bMike Reed (void*)Typeface_createFromFile }, 180dbade9d6a075b1d5b8ebe10ee8961a5de296c93bMike Reed { "setGammaForText", "(FF)V", (void*)Typeface_setGammaForText }, 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_graphics_Typeface(JNIEnv* env) 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return android::AndroidRuntime::registerNativeMethods(env, 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android/graphics/Typeface", 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gTypefaceMethods, 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SK_ARRAY_COUNT(gTypefaceMethods)); 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 190