diff options
Diffstat (limited to 'WebKit')
-rw-r--r-- | WebKit/Android.mk | 1 | ||||
-rw-r--r-- | WebKit/android/RenderSkinAndroid.cpp | 13 | ||||
-rw-r--r-- | WebKit/android/RenderSkinAndroid.h | 31 | ||||
-rw-r--r-- | WebKit/android/RenderSkinButton.cpp | 73 | ||||
-rw-r--r-- | WebKit/android/RenderSkinButton.h | 12 | ||||
-rw-r--r-- | WebKit/android/RenderSkinMediaButton.cpp | 28 | ||||
-rw-r--r-- | WebKit/android/RenderSkinMediaButton.h | 4 | ||||
-rw-r--r-- | WebKit/android/RenderSkinNinePatch.cpp | 89 | ||||
-rw-r--r-- | WebKit/android/RenderSkinNinePatch.h | 48 | ||||
-rw-r--r-- | WebKit/android/jni/WebCoreFrameBridge.cpp | 4 | ||||
-rw-r--r-- | WebKit/android/jni/WebCoreFrameBridge.h | 4 | ||||
-rw-r--r-- | WebKit/android/nav/WebView.cpp | 23 |
12 files changed, 224 insertions, 106 deletions
diff --git a/WebKit/Android.mk b/WebKit/Android.mk index 88defda..5998227 100644 --- a/WebKit/Android.mk +++ b/WebKit/Android.mk @@ -53,6 +53,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ android/RenderSkinButton.cpp \ android/RenderSkinCombo.cpp \ android/RenderSkinMediaButton.cpp \ + android/RenderSkinNinePatch.cpp \ android/RenderSkinRadio.cpp \ android/TimeCounter.cpp \ \ diff --git a/WebKit/android/RenderSkinAndroid.cpp b/WebKit/android/RenderSkinAndroid.cpp index 00f2b96..9383a9c 100644 --- a/WebKit/android/RenderSkinAndroid.cpp +++ b/WebKit/android/RenderSkinAndroid.cpp @@ -37,15 +37,14 @@ #include "utils/Asset.h" namespace WebCore { - -RenderSkinAndroid::RenderSkinAndroid() - : m_height(0) - , m_width(0) -{} -void RenderSkinAndroid::Init(android::AssetManager* am, String drawableDirectory) +RenderSkinAndroid::~RenderSkinAndroid() { - RenderSkinButton::Init(am, drawableDirectory); + delete m_button; +} +RenderSkinAndroid::RenderSkinAndroid(android::AssetManager* am, String drawableDirectory) +{ + m_button = new RenderSkinButton(am, drawableDirectory); RenderSkinCombo::Init(am, drawableDirectory); RenderSkinMediaButton::Init(am, drawableDirectory); RenderSkinRadio::Init(am, drawableDirectory); diff --git a/WebKit/android/RenderSkinAndroid.h b/WebKit/android/RenderSkinAndroid.h index b877ff2..73773ea 100644 --- a/WebKit/android/RenderSkinAndroid.h +++ b/WebKit/android/RenderSkinAndroid.h @@ -36,17 +36,11 @@ class SkBitmap; namespace WebCore { class Node; -class PlatformGraphicsContext; +class RenderSkinButton; -/* RenderSkinAndroid is the base class for all RenderSkins. Form elements each have a - * subclass for drawing themselves. - */ class RenderSkinAndroid { public: - RenderSkinAndroid(); - virtual ~RenderSkinAndroid() {} - enum State { kDisabled, kNormal, @@ -60,7 +54,8 @@ public: * Initialize the Android skinning system. The AssetManager may be used to find resources used * in rendering. */ - static void Init(android::AssetManager*, String drawableDirectory); + RenderSkinAndroid(android::AssetManager*, String drawableDirectory); + ~RenderSkinAndroid(); /* DecodeBitmap determines which file to use, with the given fileName of the form * "images/bitmap.png", and uses the asset manager to select the exact one. It @@ -68,24 +63,10 @@ public: */ static bool DecodeBitmap(android::AssetManager* am, const char* fileName, SkBitmap* bitmap); - /* draw() tells the skin to draw itself, and returns true if the skin needs - * a redraw to animations, false otherwise - */ - virtual bool draw(PlatformGraphicsContext*) { return false; } - - /* notifyState() checks to see if the element is checked, focused, and enabled - * it must be implemented in the subclass - */ - virtual void notifyState(Node* element) { } - - /* setDim() tells the skin its width and height - */ - virtual void setDim(int width, int height) { m_width = width; m_height = height; } - -protected: - int m_height; - int m_width; + const RenderSkinButton* renderSkinButton() const { return m_button; } +private: + RenderSkinButton* m_button; }; } // WebCore diff --git a/WebKit/android/RenderSkinButton.cpp b/WebKit/android/RenderSkinButton.cpp index 1dc6560..6a0ae54 100644 --- a/WebKit/android/RenderSkinButton.cpp +++ b/WebKit/android/RenderSkinButton.cpp @@ -31,47 +31,36 @@ #include "IntRect.h" #include "Node.h" #include "RenderSkinButton.h" +#include "RenderSkinNinePatch.h" #include "SkCanvas.h" #include "SkNinePatch.h" #include "SkRect.h" +#include <utils/Asset.h> +#include <utils/AssetManager.h> #include <utils/Debug.h> #include <utils/Log.h> +#include <utils/ResourceTypes.h> #include <wtf/text/CString.h> -struct PatchData { - const char* name; - int8_t outset, margin; -}; - -static const PatchData gFiles[] = - { - { "btn_default_disabled_holo.9.png", 2, 7 }, - { "btn_default_normal_holo.9.png", 2, 7 }, - { "btn_default_focused_holo.9.png", 2, 7 }, - { "btn_default_pressed_holo.9.png", 2, 7 } +static const char* gFiles[] = { + "btn_default_disabled_holo.9.png", + "btn_default_normal_holo.9.png", + "btn_default_focused_holo.9.png", + "btn_default_pressed_holo.9.png" }; -static SkBitmap gButton[sizeof(gFiles)/sizeof(gFiles[0])]; -static bool gDecoded; -static bool gHighRes; - namespace WebCore { -void RenderSkinButton::Init(android::AssetManager* am, String drawableDirectory) +RenderSkinButton::RenderSkinButton(android::AssetManager* am, String drawableDirectory) { - static bool gInited; - if (gInited) - return; - - gInited = true; - gDecoded = true; - gHighRes = drawableDirectory[drawableDirectory.length() - 5] == 'h'; - for (size_t i = 0; i < sizeof(gFiles)/sizeof(gFiles[0]); i++) { - String path = drawableDirectory + gFiles[i].name; - if (!RenderSkinAndroid::DecodeBitmap(am, path.utf8().data(), &gButton[i])) { - gDecoded = false; - LOGD("RenderSkinButton::Init: button assets failed to decode\n\tBrowser buttons will not draw"); - break; + m_decoded = true; + for (size_t i = 0; i < 4; i++) { + String path = String(drawableDirectory.impl()); + path.append(String(gFiles[i])); + if (!RenderSkinNinePatch::decodeAsset(am, path.utf8().data(), &m_buttons[i])) { + m_decoded = false; + LOGE("RenderSkinButton::Init: button assets failed to decode\n\tBrowser buttons will not draw"); + return; } } @@ -82,11 +71,12 @@ void RenderSkinButton::Init(android::AssetManager* am, String drawableDirectory) android::CompileTimeAssert<(RenderSkinAndroid::kPressed == 3)> a4; } -void RenderSkinButton::Draw(SkCanvas* canvas, const IntRect& r, RenderSkinAndroid::State newState) +void RenderSkinButton::draw(SkCanvas* canvas, const IntRect& r, + RenderSkinAndroid::State newState) const { // If we failed to decode, do nothing. This way the browser still works, // and webkit will still draw the label and layout space for us. - if (!gDecoded) { + if (!m_decoded) { return; } @@ -94,26 +84,7 @@ void RenderSkinButton::Draw(SkCanvas* canvas, const IntRect& r, RenderSkinAndroi SkASSERT(static_cast<unsigned>(newState) < static_cast<unsigned>(RenderSkinAndroid::kNumStates)); - // Set up the ninepatch information for drawing. - SkRect bounds(r); - const PatchData& pd = gFiles[newState]; - int marginValue = pd.margin + pd.outset; - - SkIRect margin; - - margin.set(marginValue, marginValue, marginValue, marginValue); - if (gHighRes) { - /* FIXME: it shoudn't be necessary to offset the button here, - but gives the right results. */ - bounds.offset(0, SK_Scalar1 * 2); - /* FIXME: This temporarily gets around the fact that the margin values and - positioning were created for a low res asset, which was used on - g1-like devices. A better fix would be to read the offset information - out of the png. */ - margin.set(10, 9, 10, 14); - } - // Draw to the canvas. - SkNinePatch::DrawNine(canvas, bounds, gButton[newState], margin); + RenderSkinNinePatch::DrawNinePatch(canvas, SkRect(r), m_buttons[newState]); } } //WebCore diff --git a/WebKit/android/RenderSkinButton.h b/WebKit/android/RenderSkinButton.h index e9cf0ec..e9db74c 100644 --- a/WebKit/android/RenderSkinButton.h +++ b/WebKit/android/RenderSkinButton.h @@ -27,24 +27,28 @@ #define RenderSkinButton_h #include "RenderSkinAndroid.h" +#include "RenderSkinNinePatch.h" class SkCanvas; namespace WebCore { class IntRect; -class RenderSkinButton -{ + +class RenderSkinButton { public: /** * Initialize the class before use. Uses the AssetManager to initialize any * bitmaps the class may use. */ - static void Init(android::AssetManager*, String drawableDirectory); + RenderSkinButton(android::AssetManager*, String drawableDirectory); /** * Draw the skin to the canvas, using the rectangle for its bounds and the * State to determine which skin to use, i.e. focused or not focused. */ - static void Draw(SkCanvas* , const IntRect& , RenderSkinAndroid::State); + void draw(SkCanvas* , const IntRect& , RenderSkinAndroid::State) const; +private: + bool m_decoded; + NinePatch m_buttons[4]; }; } // WebCore diff --git a/WebKit/android/RenderSkinMediaButton.cpp b/WebKit/android/RenderSkinMediaButton.cpp index 6a11eda..9969763 100644 --- a/WebKit/android/RenderSkinMediaButton.cpp +++ b/WebKit/android/RenderSkinMediaButton.cpp @@ -55,8 +55,8 @@ static const PatchData gFiles[] = { "ic_media_ff.png", 0, 0 }, // FORWARD { "ic_media_fullscreen.png", 0, 0 }, // FULLSCREEN { "btn_media_player_disabled.9.png", 0, 0 }, // BACKGROUND_SLIDER - { "scrubber_track_holo_dark.9.png", 0, 0 }, // SLIDER_TRACK - { "scrubber_control_holo.png", 0, 0 } // SLIDER_THUMB + { "btn_media_player_pressed.9.png", 0, 0 }, // SLIDER_TRACK + { "btn_media_player.9.png", 0, 0 } // SLIDER_THUMB }; static SkBitmap gButton[sizeof(gFiles)/sizeof(gFiles[0])]; @@ -93,9 +93,9 @@ void RenderSkinMediaButton::Draw(SkCanvas* canvas, const IntRect& r, int buttonT return; } - bool drawsNinePatch = false; + bool drawsNinePatch = true; bool drawsImage = true; - bool drawsBackgroundColor = true; + bool drawsBackgroundColor = false; int ninePatchIndex = 0; int imageIndex = 0; @@ -109,6 +109,7 @@ void RenderSkinMediaButton::Draw(SkCanvas* canvas, const IntRect& r, int buttonT alpha = 190; SkColor backgroundColor = SkColorSetARGB(alpha, 34, 34, 34); + SkColor trackBackgroundColor = SkColorSetARGB(255, 100, 100, 100); paint.setColor(backgroundColor); paint.setFlags(SkPaint::kFilterBitmap_Flag); @@ -121,6 +122,7 @@ void RenderSkinMediaButton::Draw(SkCanvas* canvas, const IntRect& r, int buttonT case FULLSCREEN: { imageIndex = buttonType + 1; + drawsBackgroundColor = true; paint.setColor(backgroundColor); break; } @@ -128,24 +130,30 @@ void RenderSkinMediaButton::Draw(SkCanvas* canvas, const IntRect& r, int buttonT { drawsBackgroundColor = false; drawsImage = false; + drawsNinePatch = false; + drawsBackgroundColor = true; + paint.setColor(backgroundColor); break; } case SLIDER_TRACK: { - drawsNinePatch = true; drawsImage = false; - ninePatchIndex = buttonType + 1; + drawsNinePatch = false; + drawsBackgroundColor = true; + paint.setColor(trackBackgroundColor); + bounds.fTop += 8; + bounds.fBottom -= 8; break; } case SLIDER_THUMB: { - drawsBackgroundColor = false; - imageMargin = 0; - imageIndex = buttonType + 1; + drawsImage = false; + ninePatchIndex = buttonType + 1; break; } default: - return; + drawsImage = false; + drawsNinePatch = false; } if (drawsBackgroundColor) { diff --git a/WebKit/android/RenderSkinMediaButton.h b/WebKit/android/RenderSkinMediaButton.h index 026f538..f1b87b1 100644 --- a/WebKit/android/RenderSkinMediaButton.h +++ b/WebKit/android/RenderSkinMediaButton.h @@ -55,8 +55,8 @@ public: /** * Slider dimensions */ - static int sliderThumbWidth() { return 32; } - static int sliderThumbHeight() { return 32; } + static int sliderThumbWidth() { return 10; } + static int sliderThumbHeight() { return 30; } }; diff --git a/WebKit/android/RenderSkinNinePatch.cpp b/WebKit/android/RenderSkinNinePatch.cpp new file mode 100644 index 0000000..0c915c0 --- /dev/null +++ b/WebKit/android/RenderSkinNinePatch.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "config.h" + +#include "RenderSkinNinePatch.h" +#include "NinePatchPeeker.h" +#include "SkCanvas.h" +#include "SkImageDecoder.h" +#include "SkRect.h" +#include "SkStream.h" +#include "SkTemplates.h" +#include <utils/Asset.h> +#include <utils/AssetManager.h> +#include <utils/Log.h> +#include <utils/ResourceTypes.h> + +class SkPaint; +class SkRegion; + +using namespace android; + +extern void NinePatch_Draw(SkCanvas* canvas, const SkRect& bounds, + const SkBitmap& bitmap, const Res_png_9patch& chunk, + const SkPaint* paint, SkRegion** outRegion); + +bool RenderSkinNinePatch::decodeAsset(AssetManager* am, const char* filename, NinePatch* ninepatch) { + Asset* asset = am->open(filename, android::Asset::ACCESS_BUFFER); + if (!asset) { + asset = am->openNonAsset(filename, android::Asset::ACCESS_BUFFER); + if (!asset) { + return false; + } + } + + SkImageDecoder::Mode mode = SkImageDecoder::kDecodePixels_Mode; + SkBitmap::Config prefConfig = SkBitmap::kNo_Config; + SkStream* stream = new SkMemoryStream(asset->getBuffer(false), asset->getLength()); + SkImageDecoder* decoder = SkImageDecoder::Factory(stream); + if (!decoder) { + asset->close(); + LOGE("RenderSkinNinePatch::Failed to create an image decoder"); + return false; + } + + decoder->setSampleSize(1); + decoder->setDitherImage(true); + decoder->setPreferQualityOverSpeed(false); + + NinePatchPeeker peeker(decoder); + + SkAutoTDelete<SkImageDecoder> add(decoder); + + decoder->setPeeker(&peeker); + if (!decoder->decode(stream, &ninepatch->m_bitmap, prefConfig, mode, true)) { + asset->close(); + LOGE("RenderSkinNinePatch::Failed to decode nine patch asset"); + return false; + } + + asset->close(); + if (!peeker.fPatchIsValid) { + LOGE("RenderSkinNinePatch::Patch data not valid"); + return false; + } + void** data = &ninepatch->m_serializedPatchData; + *data = malloc(peeker.fPatch->serializedSize()); + peeker.fPatch->serialize(*data); + return true; +} + +void RenderSkinNinePatch::DrawNinePatch(SkCanvas* canvas, const SkRect& bounds, + const NinePatch& patch) { + Res_png_9patch* data = Res_png_9patch::deserialize(patch.m_serializedPatchData); + NinePatch_Draw(canvas, bounds, patch.m_bitmap, *data, 0, 0); +} diff --git a/WebKit/android/RenderSkinNinePatch.h b/WebKit/android/RenderSkinNinePatch.h new file mode 100644 index 0000000..e4db260 --- /dev/null +++ b/WebKit/android/RenderSkinNinePatch.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef RenderSkinNinePatch_h +#define RenderSkinNinePatch_h + +#include "SkBitmap.h" +#include "utils/Asset.h" + +namespace android { + class AssetManager; +} + +class SkCanvas; +class SkRect; + +struct NinePatch { + SkBitmap m_bitmap; + void* m_serializedPatchData; + NinePatch() { + m_serializedPatchData = 0; + } + ~NinePatch() { + if (m_serializedPatchData) + free(m_serializedPatchData); + } +}; + +class RenderSkinNinePatch { +public: + static bool decodeAsset(android::AssetManager*, const char* fileName, NinePatch*); + static void DrawNinePatch(SkCanvas*, const SkRect&, const NinePatch&); +}; + +#endif // RenderSkinNinePatch_h diff --git a/WebKit/android/jni/WebCoreFrameBridge.cpp b/WebKit/android/jni/WebCoreFrameBridge.cpp index 49eac3c..dabde03 100644 --- a/WebKit/android/jni/WebCoreFrameBridge.cpp +++ b/WebKit/android/jni/WebCoreFrameBridge.cpp @@ -334,6 +334,7 @@ WebFrame::WebFrame(JNIEnv* env, jobject obj, jobject historyList, WebCore::Page* mUserAgent = WTF::String(); mUserInitiatedAction = false; mBlockNetworkLoads = false; + m_renderSkins = 0; } WebFrame::~WebFrame() @@ -345,6 +346,7 @@ WebFrame::~WebFrame() mJavaFrame->mObj = 0; } delete mJavaFrame; + delete m_renderSkins; } WebFrame* WebFrame::getWebFrame(const WebCore::Frame* frame) @@ -1264,7 +1266,7 @@ static void CreateFrame(JNIEnv* env, jobject obj, jobject javaview, jobject jAss // Setup the asset manager. AssetManager* am = assetManagerForJavaObject(env, jAssetManager); // Initialize our skinning classes - WebCore::RenderSkinAndroid::Init(am, directory); + webFrame->setRenderSkins(new WebCore::RenderSkinAndroid(am, directory)); } for (int i = WebCore::PlatformBridge::FileUploadLabel; i <= WebCore::PlatformBridge::FileUploadNoFileChosenLabel; i++) diff --git a/WebKit/android/jni/WebCoreFrameBridge.h b/WebKit/android/jni/WebCoreFrameBridge.h index 25232e4..6522a5f 100644 --- a/WebKit/android/jni/WebCoreFrameBridge.h +++ b/WebKit/android/jni/WebCoreFrameBridge.h @@ -43,6 +43,7 @@ namespace WebCore { class Image; class Page; class RenderPart; + class RenderSkinAndroid; class ResourceHandle; class ResourceLoaderAndroid; class ResourceRequest; @@ -155,6 +156,8 @@ class WebFrame : public WebCoreRefObject { bool shouldSaveFormData(); void saveFormData(WebCore::HTMLFormElement*); + const WebCore::RenderSkinAndroid* renderSkins() const { return m_renderSkins; } + void setRenderSkins(const WebCore::RenderSkinAndroid* skins) { m_renderSkins = skins; } private: struct JavaBrowserFrame; JavaBrowserFrame* mJavaFrame; @@ -162,6 +165,7 @@ private: WTF::String mUserAgent; bool mBlockNetworkLoads; bool mUserInitiatedAction; + const WebCore::RenderSkinAndroid* m_renderSkins; }; } // namespace android diff --git a/WebKit/android/nav/WebView.cpp b/WebKit/android/nav/WebView.cpp index 3a156de..053f2a9 100644 --- a/WebKit/android/nav/WebView.cpp +++ b/WebKit/android/nav/WebView.cpp @@ -71,7 +71,9 @@ #include <JNIUtility.h> #include <JNIHelp.h> #include <jni.h> +#include <android_runtime/android_util_AssetManager.h> #include <ui/KeycodeLabels.h> +#include <utils/AssetManager.h> #include <wtf/text/AtomicString.h> #include <wtf/text/CString.h> @@ -138,7 +140,7 @@ struct JavaGlue { } } m_javaGlue; -WebView(JNIEnv* env, jobject javaWebView, int viewImpl) : +WebView(JNIEnv* env, jobject javaWebView, int viewImpl, WTF::String drawableDir, AssetManager* am) : m_ring((WebViewCore*) viewImpl) { jclass clazz = env->FindClass("android/webkit/WebView"); @@ -190,6 +192,10 @@ WebView(JNIEnv* env, jobject javaWebView, int viewImpl) : m_ringAnimationEnd = 0; m_baseLayer = 0; m_glDrawFunctor = 0; + if (drawableDir.isEmpty()) + m_buttonSkin = 0; + else + m_buttonSkin = new RenderSkinButton(am, drawableDir); #if USE(ACCELERATED_COMPOSITING) m_glWebViewState = 0; #endif @@ -213,6 +219,7 @@ WebView(JNIEnv* env, jobject javaWebView, int viewImpl) : delete m_navPictureUI; SkSafeUnref(m_baseLayer); delete m_glDrawFunctor; + delete m_buttonSkin; } void stopGL() @@ -279,7 +286,7 @@ void nativeRecordButtons(bool hasFocus, bool pressed, bool invalidate) const CachedNode* cachedCursor = 0; // Lock the mutex, since we now share with the WebCore thread. m_viewImpl->gButtonMutex.lock(); - if (m_viewImpl->m_buttons.size()) { + if (m_viewImpl->m_buttons.size() && m_buttonSkin) { // FIXME: In a future change, we should keep track of whether the selection // has changed to short circuit (note that we would still need to update // if we received new buttons from the WebCore thread). @@ -308,7 +315,7 @@ void nativeRecordButtons(bool hasFocus, bool pressed, bool invalidate) state = RenderSkinAndroid::kFocused; } } - ptr->updateFocusState(state); + ptr->updateFocusState(state, m_buttonSkin); } } m_viewImpl->gButtonMutex.unlock(); @@ -1463,6 +1470,7 @@ private: // local state for WebView #if USE(ACCELERATED_COMPOSITING) GLWebViewState* m_glWebViewState; #endif + const RenderSkinButton* m_buttonSkin; }; // end of WebView class @@ -1573,9 +1581,12 @@ static void nativeClearCursor(JNIEnv *env, jobject obj) view->clearCursor(); } -static void nativeCreate(JNIEnv *env, jobject obj, int viewImpl) +static void nativeCreate(JNIEnv *env, jobject obj, int viewImpl, jstring drawableDir, + jobject jAssetManager) { - WebView* webview = new WebView(env, obj, viewImpl); + AssetManager* am = assetManagerForJavaObject(env, jAssetManager); + WTF::String dir = jstringToWtfString(env, drawableDir); + WebView* webview = new WebView(env, obj, viewImpl, dir, am); // NEED THIS OR SOMETHING LIKE IT! //Release(obj); } @@ -2489,7 +2500,7 @@ static JNINativeMethod gJavaWebViewMethods[] = { (void*) nativeCacheHitNodePointer }, { "nativeClearCursor", "()V", (void*) nativeClearCursor }, - { "nativeCreate", "(I)V", + { "nativeCreate", "(ILjava/lang/String;Landroid/content/res/AssetManager;)V", (void*) nativeCreate }, { "nativeCursorFramePointer", "()I", (void*) nativeCursorFramePointer }, |