Additional loading methods for fonts and a3d files.
Cleaned up error messages.

Change-Id: Id33b7149671df23c37cc11375d844a7837dac750

Change-Id: I6663ce54f7b9bbaf285935ca658d93ba417f8179
diff --git a/libs/rs/RenderScript.h b/libs/rs/RenderScript.h
index 87758e5..f160ef1 100644
--- a/libs/rs/RenderScript.h
+++ b/libs/rs/RenderScript.h
@@ -334,7 +334,9 @@
 // A3D loading and object update code.
 // Should only be called at object creation, not thread safe
 RsObjectBase rsaFileA3DGetEntryByIndex(RsContext, uint32_t idx, RsFile);
-RsFile rsaFileA3DCreateFromAssetStream(RsContext, const void *data, uint32_t len);
+RsFile rsaFileA3DCreateFromMemory(RsContext, const void *data, uint32_t len);
+RsFile rsaFileA3DCreateFromAsset(RsContext, void *asset);
+RsFile rsaFileA3DCreateFromFile(RsContext, const char *path);
 void rsaFileA3DGetNumIndexEntries(RsContext, int32_t *numEntries, RsFile);
 void rsaFileA3DGetIndexEntries(RsContext, RsFileIndexEntry *fileEntries,uint32_t numEntries, RsFile);
 void rsaGetName(RsContext, void * obj, const char **name);
diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec
index 3483a5d..33ac2f0 100644
--- a/libs/rs/rs.spec
+++ b/libs/rs/rs.spec
@@ -346,12 +346,6 @@
 	ret RsProgramVertex
 	}
 
-FileOpen {
-	ret RsFile
-	param const char *name
-	param size_t len
-	}
-
 FontCreateFromFile {
 	param const char *name
 	param float fontSize
@@ -359,6 +353,15 @@
 	ret RsFont
 	}
 
+FontCreateFromMemory {
+	param const char *name
+	param float fontSize
+	param uint32_t dpi
+    param const void *data
+    param uint32_t dataLen
+	ret RsFont
+	}
+
 MeshCreate {
 	ret RsMesh
 	param uint32_t vtxCount
diff --git a/libs/rs/rsFileA3D.cpp b/libs/rs/rsFileA3D.cpp
index 0c8692d..d34ddd6 100644
--- a/libs/rs/rsFileA3D.cpp
+++ b/libs/rs/rsFileA3D.cpp
@@ -35,6 +35,7 @@
     mData = NULL;
     mWriteStream = NULL;
     mReadStream = NULL;
+    mAsset = NULL;
 
     mMajorVersion = 0;
     mMinorVersion = 1;
@@ -57,6 +58,9 @@
     if (mAlloc) {
         free(mAlloc);
     }
+    if (mAsset) {
+        delete mAsset;
+    }
 }
 
 void FileA3D::parseHeader(IStream *headerStream) {
@@ -83,6 +87,11 @@
     }
 }
 
+bool FileA3D::load(Asset *asset) {
+    mAsset = asset;
+    return load(asset->getBuffer(false), asset->getLength());
+}
+
 bool FileA3D::load(const void *data, size_t length) {
     const uint8_t *localData = (const uint8_t *)data;
 
@@ -357,26 +366,6 @@
     mWriteStream->align(4);
 }
 
-namespace android {
-namespace renderscript {
-
-RsFile rsi_FileOpen(Context *rsc, char const *path, unsigned int len) {
-    FileA3D *fa3d = new FileA3D(rsc);
-
-    FILE *f = fopen("/sdcard/test.a3d", "rb");
-    if (f) {
-        fa3d->load(f);
-        fclose(f);
-        fa3d->incUserRef();
-        return fa3d;
-    }
-    delete fa3d;
-    return NULL;
-}
-
-}
-}
-
 RsObjectBase rsaFileA3DGetEntryByIndex(RsContext con, uint32_t index, RsFile file) {
     FileA3D *fa3d = static_cast<FileA3D *>(file);
     if (!fa3d) {
@@ -422,7 +411,7 @@
     }
 }
 
-RsFile rsaFileA3DCreateFromAssetStream(RsContext con, const void *data, uint32_t len) {
+RsFile rsaFileA3DCreateFromMemory(RsContext con, const void *data, uint32_t len) {
     if (data == NULL) {
         LOGE("File load failed. Asset stream is NULL");
         return NULL;
@@ -435,3 +424,35 @@
     fa3d->load(data, len);
     return fa3d;
 }
+
+RsFile rsaFileA3DCreateFromAsset(RsContext con, void *_asset) {
+    Context *rsc = static_cast<Context *>(con);
+    Asset *asset = static_cast<Asset *>(_asset);
+    FileA3D *fa3d = new FileA3D(rsc);
+    fa3d->incUserRef();
+
+    fa3d->load(asset);
+    return fa3d;
+}
+
+RsFile rsaFileA3DCreateFromFile(RsContext con, const char *path) {
+    if (path == NULL) {
+        LOGE("File load failed. Path is NULL");
+        return NULL;
+    }
+
+    Context *rsc = static_cast<Context *>(con);
+    FileA3D *fa3d = NULL;
+
+    FILE *f = fopen(path, "rb");
+    if (f) {
+        fa3d = new FileA3D(rsc);
+        fa3d->incUserRef();
+        fa3d->load(f);
+        fclose(f);
+    } else {
+        LOGE("Could not open file %s", path);
+    }
+
+    return fa3d;
+}
diff --git a/libs/rs/rsFileA3D.h b/libs/rs/rsFileA3D.h
index 3ece4c9..056b5af 100644
--- a/libs/rs/rsFileA3D.h
+++ b/libs/rs/rsFileA3D.h
@@ -21,6 +21,7 @@
 #include "rsMesh.h"
 
 #include <utils/String8.h>
+#include <utils/Asset.h>
 #include "rsStream.h"
 #include <stdio.h>
 
@@ -59,6 +60,7 @@
     };
 
     bool load(FILE *f);
+    bool load(Asset *asset);
     bool load(const void *data, size_t length);
 
     size_t getNumIndexEntries() const;
@@ -83,6 +85,7 @@
     const uint8_t * mData;
     void * mAlloc;
     uint64_t mDataSize;
+    Asset *mAsset;
 
     OStream *mWriteStream;
     Vector<A3DIndexEntry*> mWriteIndex;
diff --git a/libs/rs/rsFont.cpp b/libs/rs/rsFont.cpp
index 3dcf743..8571c32 100644
--- a/libs/rs/rsFont.cpp
+++ b/libs/rs/rsFont.cpp
@@ -40,13 +40,19 @@
     mFace = NULL;
 }
 
-bool Font::init(const char *name, float fontSize, uint32_t dpi) {
+bool Font::init(const char *name, float fontSize, uint32_t dpi, const void *data, uint32_t dataLen) {
     if (mInitialized) {
         LOGE("Reinitialization of fonts not supported");
         return false;
     }
 
-    FT_Error error = FT_New_Face(mRSC->mStateFont.getLib(), name, 0, &mFace);
+    FT_Error error = 0;
+    if (data != NULL && dataLen > 0) {
+        error = FT_New_Memory_Face(mRSC->mStateFont.getLib(), (const FT_Byte*)data, dataLen, 0, &mFace);
+    } else {
+        error = FT_New_Face(mRSC->mStateFont.getLib(), name, 0, &mFace);
+    }
+
     if (error) {
         LOGE("Unable to initialize font %s", name);
         return false;
@@ -127,7 +133,8 @@
     int32_t width = (int32_t) glyph->mBitmapWidth;
     int32_t height = (int32_t) glyph->mBitmapHeight;
 
-    if (bounds->bottom > nPenY) {
+    // 0, 0 is top left, so bottom is a positive number
+    if (bounds->bottom < nPenY) {
         bounds->bottom = nPenY;
     }
     if (bounds->left > nPenX) {
@@ -136,8 +143,8 @@
     if (bounds->right < nPenX + width) {
         bounds->right = nPenX + width;
     }
-    if (bounds->top < nPenY + height) {
-        bounds->top = nPenY + height;
+    if (bounds->top > nPenY - height) {
+        bounds->top = nPenY - height;
     }
 }
 
@@ -155,7 +162,7 @@
             return;
         }
         // Reset min and max of the bounding box to something large
-        bounds->set(1e6, -1e6, -1e6, 1e6);
+        bounds->set(1e6, -1e6, 1e6, -1e6);
     }
 
     int32_t penX = x, penY = y;
@@ -273,7 +280,8 @@
     return newGlyph;
 }
 
-Font * Font::create(Context *rsc, const char *name, float fontSize, uint32_t dpi) {
+Font * Font::create(Context *rsc, const char *name, float fontSize, uint32_t dpi,
+                    const void *data, uint32_t dataLen) {
     rsc->mStateFont.checkInit();
     Vector<Font*> &activeFonts = rsc->mStateFont.mActiveFonts;
 
@@ -285,7 +293,7 @@
     }
 
     Font *newFont = new Font(rsc);
-    bool isInitialized = newFont->init(name, fontSize, dpi);
+    bool isInitialized = newFont->init(name, fontSize, dpi, data, dataLen);
     if (isInitialized) {
         activeFonts.push(newFont);
         rsc->mStateFont.precacheLatin(newFont);
@@ -743,6 +751,8 @@
 
 void FontState::measureText(const char *text, uint32_t len, Font::Rect *bounds) {
     renderText(text, len, 0, 0, 0, -1, Font::MEASURE, bounds);
+    bounds->bottom = - bounds->bottom;
+    bounds->top = - bounds->top;
 }
 
 void FontState::setFontColor(float r, float g, float b, float a) {
@@ -811,5 +821,13 @@
     return newFont;
 }
 
+RsFont rsi_FontCreateFromMemory(Context *rsc, char const *name, float fontSize, uint32_t dpi, const void *data, uint32_t dataLen) {
+    Font *newFont = Font::create(rsc, name, fontSize, dpi, data, dataLen);
+    if (newFont) {
+        newFont->incUserRef();
+    }
+    return newFont;
+}
+
 } // renderscript
 } // android
diff --git a/libs/rs/rsFont.h b/libs/rs/rsFont.h
index c24c9f1..00d77c8 100644
--- a/libs/rs/rsFont.h
+++ b/libs/rs/rsFont.h
@@ -73,7 +73,8 @@
         return RS_A3D_CLASS_ID_UNKNOWN;
     }
 
-    static Font * create(Context *rsc, const char *name, float fontSize, uint32_t dpi);
+    static Font * create(Context *rsc, const char *name, float fontSize, uint32_t dpi,
+                         const void *data = NULL, uint32_t dataLen = 0);
 
 protected:
 
@@ -116,7 +117,7 @@
     uint32_t mDpi;
 
     Font(Context *rsc);
-    bool init(const char *name, float fontSize, uint32_t dpi);
+    bool init(const char *name, float fontSize, uint32_t dpi, const void *data = NULL, uint32_t dataLen = 0);
 
     FT_Face mFace;
     bool mInitialized;