Refactor android.graphics.Picture JNI bindings.
This is the first CL in a series of CLs to refactor the Graphics JNI bindings. bug: 15672762 Change-Id: I1455fa1330c7426407c06eeaad81ad37a57373b1
This commit is contained in:
@@ -801,20 +801,12 @@ class GLES20Canvas extends HardwareCanvas {
|
||||
|
||||
@Override
|
||||
public void drawPicture(Picture picture) {
|
||||
if (picture.createdFromStream) {
|
||||
return;
|
||||
}
|
||||
|
||||
picture.endRecording();
|
||||
// TODO: Implement rendering
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawPicture(Picture picture, Rect dst) {
|
||||
if (picture.createdFromStream) {
|
||||
return;
|
||||
}
|
||||
|
||||
save();
|
||||
translate(dst.left, dst.top);
|
||||
if (picture.getWidth() > 0 && picture.getHeight() > 0) {
|
||||
@@ -826,10 +818,6 @@ class GLES20Canvas extends HardwareCanvas {
|
||||
|
||||
@Override
|
||||
public void drawPicture(Picture picture, RectF dst) {
|
||||
if (picture.createdFromStream) {
|
||||
return;
|
||||
}
|
||||
|
||||
save();
|
||||
translate(dst.left, dst.top);
|
||||
if (picture.getWidth() > 0 && picture.getHeight() > 0) {
|
||||
|
||||
@@ -89,7 +89,7 @@ LOCAL_SRC_FILES:= \
|
||||
android_util_Process.cpp \
|
||||
android_util_StringBlock.cpp \
|
||||
android_util_XmlBlock.cpp \
|
||||
android/graphics/AndroidPicture.cpp \
|
||||
android_graphics_Picture.cpp \
|
||||
android/graphics/AutoDecodeCancel.cpp \
|
||||
android/graphics/Bitmap.cpp \
|
||||
android/graphics/BitmapFactory.cpp \
|
||||
|
||||
@@ -1,112 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 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 "AndroidPicture.h"
|
||||
#include "SkCanvas.h"
|
||||
#include "SkStream.h"
|
||||
|
||||
AndroidPicture::AndroidPicture(const AndroidPicture* src) {
|
||||
if (NULL != src) {
|
||||
mWidth = src->width();
|
||||
mHeight = src->height();
|
||||
if (NULL != src->mPicture.get()) {
|
||||
mPicture.reset(SkRef(src->mPicture.get()));
|
||||
} if (NULL != src->mRecorder.get()) {
|
||||
mPicture.reset(src->makePartialCopy());
|
||||
}
|
||||
} else {
|
||||
mWidth = 0;
|
||||
mHeight = 0;
|
||||
}
|
||||
}
|
||||
|
||||
SkCanvas* AndroidPicture::beginRecording(int width, int height) {
|
||||
mPicture.reset(NULL);
|
||||
mRecorder.reset(new SkPictureRecorder);
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
return mRecorder->beginRecording(width, height, NULL, 0);
|
||||
}
|
||||
|
||||
void AndroidPicture::endRecording() {
|
||||
if (NULL != mRecorder.get()) {
|
||||
mPicture.reset(mRecorder->endRecording());
|
||||
mRecorder.reset(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
int AndroidPicture::width() const {
|
||||
if (NULL != mPicture.get()) {
|
||||
SkASSERT(mPicture->width() == mWidth);
|
||||
SkASSERT(mPicture->height() == mHeight);
|
||||
}
|
||||
|
||||
return mWidth;
|
||||
}
|
||||
|
||||
int AndroidPicture::height() const {
|
||||
if (NULL != mPicture.get()) {
|
||||
SkASSERT(mPicture->width() == mWidth);
|
||||
SkASSERT(mPicture->height() == mHeight);
|
||||
}
|
||||
|
||||
return mHeight;
|
||||
}
|
||||
|
||||
AndroidPicture* AndroidPicture::CreateFromStream(SkStream* stream) {
|
||||
AndroidPicture* newPict = new AndroidPicture;
|
||||
|
||||
newPict->mPicture.reset(SkPicture::CreateFromStream(stream));
|
||||
if (NULL != newPict->mPicture.get()) {
|
||||
newPict->mWidth = newPict->mPicture->width();
|
||||
newPict->mHeight = newPict->mPicture->height();
|
||||
}
|
||||
|
||||
return newPict;
|
||||
}
|
||||
|
||||
void AndroidPicture::serialize(SkWStream* stream) const {
|
||||
if (NULL != mRecorder.get()) {
|
||||
SkAutoTDelete<SkPicture> tempPict(this->makePartialCopy());
|
||||
tempPict->serialize(stream);
|
||||
} else if (NULL != mPicture.get()) {
|
||||
mPicture->serialize(stream);
|
||||
} else {
|
||||
SkPicture empty;
|
||||
empty.serialize(stream);
|
||||
}
|
||||
}
|
||||
|
||||
void AndroidPicture::draw(SkCanvas* canvas) {
|
||||
if (NULL != mRecorder.get()) {
|
||||
this->endRecording();
|
||||
SkASSERT(NULL != mPicture.get());
|
||||
}
|
||||
if (NULL != mPicture.get()) {
|
||||
// TODO: remove this const_cast once pictures are immutable
|
||||
const_cast<SkPicture*>(mPicture.get())->draw(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
SkPicture* AndroidPicture::makePartialCopy() const {
|
||||
SkASSERT(NULL != mRecorder.get());
|
||||
|
||||
SkPictureRecorder reRecorder;
|
||||
|
||||
SkCanvas* canvas = reRecorder.beginRecording(mWidth, mHeight, NULL, 0);
|
||||
mRecorder->partialReplay(canvas);
|
||||
return reRecorder.endRecording();
|
||||
}
|
||||
@@ -3,7 +3,6 @@
|
||||
#include "jni.h"
|
||||
#include "JNIHelp.h"
|
||||
#include "GraphicsJNI.h"
|
||||
#include "AndroidPicture.h"
|
||||
|
||||
#include "SkCanvas.h"
|
||||
#include "SkDevice.h"
|
||||
@@ -346,17 +345,6 @@ android::TypefaceImpl* GraphicsJNI::getNativeTypeface(JNIEnv* env, jobject paint
|
||||
return p;
|
||||
}
|
||||
|
||||
AndroidPicture* GraphicsJNI::getNativePicture(JNIEnv* env, jobject picture)
|
||||
{
|
||||
SkASSERT(env);
|
||||
SkASSERT(picture);
|
||||
SkASSERT(env->IsInstanceOf(picture, gPicture_class));
|
||||
jlong pictureHandle = env->GetLongField(picture, gPicture_nativeInstanceID);
|
||||
AndroidPicture* p = reinterpret_cast<AndroidPicture*>(pictureHandle);
|
||||
SkASSERT(p);
|
||||
return p;
|
||||
}
|
||||
|
||||
SkRegion* GraphicsJNI::getNativeRegion(JNIEnv* env, jobject region)
|
||||
{
|
||||
SkASSERT(env);
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
class SkBitmapRegionDecoder;
|
||||
class SkCanvas;
|
||||
class SkPaint;
|
||||
class AndroidPicture;
|
||||
|
||||
class GraphicsJNI {
|
||||
public:
|
||||
@@ -50,7 +49,6 @@ public:
|
||||
static SkPaint* getNativePaint(JNIEnv*, jobject paint);
|
||||
static android::TypefaceImpl* getNativeTypeface(JNIEnv*, jobject paint);
|
||||
static SkBitmap* getNativeBitmap(JNIEnv*, jobject bitmap);
|
||||
static AndroidPicture* getNativePicture(JNIEnv*, jobject picture);
|
||||
static SkRegion* getNativeRegion(JNIEnv*, jobject region);
|
||||
|
||||
// Given the 'native' long held by the Rasterizer.java object, return a
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
* Copyright (C) 2014 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.
|
||||
@@ -14,123 +14,102 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "jni.h"
|
||||
#include "GraphicsJNI.h"
|
||||
#include <android_runtime/AndroidRuntime.h>
|
||||
#include "AndroidPicture.h"
|
||||
#include "Picture.h"
|
||||
|
||||
#include "SkCanvas.h"
|
||||
#include "SkStream.h"
|
||||
#include "SkTemplates.h"
|
||||
#include "CreateJavaOutputStreamAdaptor.h"
|
||||
|
||||
namespace android {
|
||||
using namespace android;
|
||||
|
||||
class SkPictureGlue {
|
||||
public:
|
||||
static jlong newPicture(JNIEnv* env, jobject, jlong srcHandle) {
|
||||
const AndroidPicture* src = reinterpret_cast<AndroidPicture*>(srcHandle);
|
||||
return reinterpret_cast<jlong>(new AndroidPicture(src));
|
||||
}
|
||||
|
||||
static jlong deserialize(JNIEnv* env, jobject, jobject jstream,
|
||||
jbyteArray jstorage) {
|
||||
AndroidPicture* picture = NULL;
|
||||
SkStream* strm = CreateJavaInputStreamAdaptor(env, jstream, jstorage);
|
||||
if (strm) {
|
||||
picture = AndroidPicture::CreateFromStream(strm);
|
||||
delete strm;
|
||||
Picture::Picture(const Picture* src) {
|
||||
if (NULL != src) {
|
||||
mWidth = src->width();
|
||||
mHeight = src->height();
|
||||
if (NULL != src->mPicture.get()) {
|
||||
mPicture.reset(SkRef(src->mPicture.get()));
|
||||
} if (NULL != src->mRecorder.get()) {
|
||||
mPicture.reset(src->makePartialCopy());
|
||||
}
|
||||
return reinterpret_cast<jlong>(picture);
|
||||
} else {
|
||||
mWidth = 0;
|
||||
mHeight = 0;
|
||||
}
|
||||
|
||||
static void killPicture(JNIEnv* env, jobject, jlong pictureHandle) {
|
||||
AndroidPicture* picture = reinterpret_cast<AndroidPicture*>(pictureHandle);
|
||||
SkASSERT(picture);
|
||||
delete picture;
|
||||
}
|
||||
|
||||
static void draw(JNIEnv* env, jobject, jlong canvasHandle,
|
||||
jlong pictureHandle) {
|
||||
SkCanvas* canvas = GraphicsJNI::getNativeCanvas(canvasHandle);
|
||||
AndroidPicture* picture = reinterpret_cast<AndroidPicture*>(pictureHandle);
|
||||
SkASSERT(canvas);
|
||||
SkASSERT(picture);
|
||||
picture->draw(canvas);
|
||||
}
|
||||
|
||||
static jboolean serialize(JNIEnv* env, jobject, jlong pictureHandle,
|
||||
jobject jstream, jbyteArray jstorage) {
|
||||
AndroidPicture* picture = reinterpret_cast<AndroidPicture*>(pictureHandle);
|
||||
SkWStream* strm = CreateJavaOutputStreamAdaptor(env, jstream, jstorage);
|
||||
|
||||
if (NULL != strm) {
|
||||
picture->serialize(strm);
|
||||
delete strm;
|
||||
return JNI_TRUE;
|
||||
}
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
static jint getWidth(JNIEnv* env, jobject jpic) {
|
||||
NPE_CHECK_RETURN_ZERO(env, jpic);
|
||||
AndroidPicture* pict = GraphicsJNI::getNativePicture(env, jpic);
|
||||
int width = pict->width();
|
||||
return static_cast<jint>(width);
|
||||
}
|
||||
|
||||
static jint getHeight(JNIEnv* env, jobject jpic) {
|
||||
NPE_CHECK_RETURN_ZERO(env, jpic);
|
||||
AndroidPicture* pict = GraphicsJNI::getNativePicture(env, jpic);
|
||||
int height = pict->height();
|
||||
return static_cast<jint>(height);
|
||||
}
|
||||
|
||||
static jlong beginRecording(JNIEnv* env, jobject, jlong pictHandle,
|
||||
jint w, jint h) {
|
||||
AndroidPicture* pict = reinterpret_cast<AndroidPicture*>(pictHandle);
|
||||
// beginRecording does not ref its return value, it just returns it.
|
||||
SkCanvas* canvas = pict->beginRecording(w, h);
|
||||
// the java side will wrap this guy in a Canvas.java, which will call
|
||||
// unref in its finalizer, so we have to ref it here, so that both that
|
||||
// Canvas.java and our picture can both be owners
|
||||
canvas->ref();
|
||||
return reinterpret_cast<jlong>(canvas);
|
||||
}
|
||||
|
||||
static void endRecording(JNIEnv* env, jobject, jlong pictHandle) {
|
||||
AndroidPicture* pict = reinterpret_cast<AndroidPicture*>(pictHandle);
|
||||
pict->endRecording();
|
||||
}
|
||||
};
|
||||
|
||||
static JNINativeMethod gPictureMethods[] = {
|
||||
{"getWidth", "()I", (void*) SkPictureGlue::getWidth},
|
||||
{"getHeight", "()I", (void*) SkPictureGlue::getHeight},
|
||||
{"nativeConstructor", "(J)J", (void*) SkPictureGlue::newPicture},
|
||||
{"nativeCreateFromStream", "(Ljava/io/InputStream;[B)J", (void*)SkPictureGlue::deserialize},
|
||||
{"nativeBeginRecording", "(JII)J", (void*) SkPictureGlue::beginRecording},
|
||||
{"nativeEndRecording", "(J)V", (void*) SkPictureGlue::endRecording},
|
||||
{"nativeDraw", "(JJ)V", (void*) SkPictureGlue::draw},
|
||||
{"nativeWriteToStream", "(JLjava/io/OutputStream;[B)Z", (void*)SkPictureGlue::serialize},
|
||||
{"nativeDestructor","(J)V", (void*) SkPictureGlue::killPicture}
|
||||
};
|
||||
|
||||
#include <android_runtime/AndroidRuntime.h>
|
||||
|
||||
#define REG(env, name, array) \
|
||||
result = android::AndroidRuntime::registerNativeMethods(env, name, array, \
|
||||
SK_ARRAY_COUNT(array)); \
|
||||
if (result < 0) return result
|
||||
|
||||
int register_android_graphics_Picture(JNIEnv* env) {
|
||||
int result;
|
||||
|
||||
REG(env, "android/graphics/Picture", gPictureMethods);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
SkCanvas* Picture::beginRecording(int width, int height) {
|
||||
mPicture.reset(NULL);
|
||||
mRecorder.reset(new SkPictureRecorder);
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
return mRecorder->beginRecording(width, height, NULL, 0);
|
||||
}
|
||||
|
||||
void Picture::endRecording() {
|
||||
if (NULL != mRecorder.get()) {
|
||||
mPicture.reset(mRecorder->endRecording());
|
||||
mRecorder.reset(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
int Picture::width() const {
|
||||
if (NULL != mPicture.get()) {
|
||||
SkASSERT(mPicture->width() == mWidth);
|
||||
SkASSERT(mPicture->height() == mHeight);
|
||||
}
|
||||
|
||||
return mWidth;
|
||||
}
|
||||
|
||||
int Picture::height() const {
|
||||
if (NULL != mPicture.get()) {
|
||||
SkASSERT(mPicture->width() == mWidth);
|
||||
SkASSERT(mPicture->height() == mHeight);
|
||||
}
|
||||
|
||||
return mHeight;
|
||||
}
|
||||
|
||||
Picture* Picture::CreateFromStream(SkStream* stream) {
|
||||
Picture* newPict = new Picture;
|
||||
|
||||
newPict->mPicture.reset(SkPicture::CreateFromStream(stream));
|
||||
if (NULL != newPict->mPicture.get()) {
|
||||
newPict->mWidth = newPict->mPicture->width();
|
||||
newPict->mHeight = newPict->mPicture->height();
|
||||
}
|
||||
|
||||
return newPict;
|
||||
}
|
||||
|
||||
void Picture::serialize(SkWStream* stream) const {
|
||||
if (NULL != mRecorder.get()) {
|
||||
SkAutoTDelete<SkPicture> tempPict(this->makePartialCopy());
|
||||
tempPict->serialize(stream);
|
||||
} else if (NULL != mPicture.get()) {
|
||||
mPicture->serialize(stream);
|
||||
} else {
|
||||
SkPicture empty;
|
||||
empty.serialize(stream);
|
||||
}
|
||||
}
|
||||
|
||||
void Picture::draw(SkCanvas* canvas) {
|
||||
if (NULL != mRecorder.get()) {
|
||||
this->endRecording();
|
||||
SkASSERT(NULL != mPicture.get());
|
||||
}
|
||||
if (NULL != mPicture.get()) {
|
||||
// TODO: remove this const_cast once pictures are immutable
|
||||
const_cast<SkPicture*>(mPicture.get())->draw(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
SkPicture* Picture::makePartialCopy() const {
|
||||
SkASSERT(NULL != mRecorder.get());
|
||||
|
||||
SkPictureRecorder reRecorder;
|
||||
|
||||
SkCanvas* canvas = reRecorder.beginRecording(mWidth, mHeight, NULL, 0);
|
||||
mRecorder->partialReplay(canvas);
|
||||
return reRecorder.endRecording();
|
||||
}
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_PICTURE_H
|
||||
#define ANDROID_PICTURE_H
|
||||
#ifndef ANDROID_GRAPHICS_PICTURE_H
|
||||
#define ANDROID_GRAPHICS_PICTURE_H
|
||||
|
||||
#include "SkPicture.h"
|
||||
#include "SkPictureRecorder.h"
|
||||
@@ -28,13 +28,15 @@ class SkPictureRecorder;
|
||||
class SkStream;
|
||||
class SkWStream;
|
||||
|
||||
namespace android {
|
||||
|
||||
// Skia's SkPicture class has been split into an SkPictureRecorder
|
||||
// and an SkPicture. AndroidPicture recreates the functionality
|
||||
// of the old SkPicture interface by flip-flopping between the two
|
||||
// new classes.
|
||||
class AndroidPicture {
|
||||
class Picture {
|
||||
public:
|
||||
explicit AndroidPicture(const AndroidPicture* src = NULL);
|
||||
explicit Picture(const Picture* src = NULL);
|
||||
|
||||
SkCanvas* beginRecording(int width, int height);
|
||||
|
||||
@@ -44,7 +46,7 @@ public:
|
||||
|
||||
int height() const;
|
||||
|
||||
static AndroidPicture* CreateFromStream(SkStream* stream);
|
||||
static Picture* CreateFromStream(SkStream* stream);
|
||||
|
||||
void serialize(SkWStream* stream) const;
|
||||
|
||||
@@ -60,4 +62,6 @@ private:
|
||||
// resulting picture will have balanced saves and restores.
|
||||
SkPicture* makePartialCopy() const;
|
||||
};
|
||||
#endif // ANDROID_PICTURE_H
|
||||
|
||||
}; // namespace android
|
||||
#endif // ANDROID_GRAPHICS_PICTURE_H
|
||||
117
core/jni/android_graphics_Picture.cpp
Normal file
117
core/jni/android_graphics_Picture.cpp
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright (C) 2008 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 "jni.h"
|
||||
#include "GraphicsJNI.h"
|
||||
#include <android_runtime/AndroidRuntime.h>
|
||||
|
||||
#include "Picture.h"
|
||||
|
||||
#include "SkCanvas.h"
|
||||
#include "SkStream.h"
|
||||
#include "SkTemplates.h"
|
||||
#include "CreateJavaOutputStreamAdaptor.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
static jlong android_graphics_Picture_newPicture(JNIEnv* env, jobject, jlong srcHandle) {
|
||||
const Picture* src = reinterpret_cast<Picture*>(srcHandle);
|
||||
return reinterpret_cast<jlong>(new Picture(src));
|
||||
}
|
||||
|
||||
static jlong android_graphics_Picture_deserialize(JNIEnv* env, jobject, jobject jstream,
|
||||
jbyteArray jstorage) {
|
||||
Picture* picture = NULL;
|
||||
SkStream* strm = CreateJavaInputStreamAdaptor(env, jstream, jstorage);
|
||||
if (strm) {
|
||||
picture = Picture::CreateFromStream(strm);
|
||||
delete strm;
|
||||
}
|
||||
return reinterpret_cast<jlong>(picture);
|
||||
}
|
||||
|
||||
static void android_graphics_Picture_killPicture(JNIEnv* env, jobject, jlong pictureHandle) {
|
||||
Picture* picture = reinterpret_cast<Picture*>(pictureHandle);
|
||||
SkASSERT(picture);
|
||||
delete picture;
|
||||
}
|
||||
|
||||
static void android_graphics_Picture_draw(JNIEnv* env, jobject, jlong canvasHandle,
|
||||
jlong pictureHandle) {
|
||||
SkCanvas* canvas = GraphicsJNI::getNativeCanvas(canvasHandle);
|
||||
Picture* picture = reinterpret_cast<Picture*>(pictureHandle);
|
||||
SkASSERT(canvas);
|
||||
SkASSERT(picture);
|
||||
picture->draw(canvas);
|
||||
}
|
||||
|
||||
static jboolean android_graphics_Picture_serialize(JNIEnv* env, jobject, jlong pictureHandle,
|
||||
jobject jstream, jbyteArray jstorage) {
|
||||
Picture* picture = reinterpret_cast<Picture*>(pictureHandle);
|
||||
SkWStream* strm = CreateJavaOutputStreamAdaptor(env, jstream, jstorage);
|
||||
|
||||
if (NULL != strm) {
|
||||
picture->serialize(strm);
|
||||
delete strm;
|
||||
return JNI_TRUE;
|
||||
}
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
static jint android_graphics_Picture_getWidth(JNIEnv* env, jobject, jlong pictureHandle) {
|
||||
Picture* pict = reinterpret_cast<Picture*>(pictureHandle);
|
||||
return static_cast<jint>(pict->width());
|
||||
}
|
||||
|
||||
static jint android_graphics_Picture_getHeight(JNIEnv* env, jobject, jlong pictureHandle) {
|
||||
Picture* pict = reinterpret_cast<Picture*>(pictureHandle);
|
||||
return static_cast<jint>(pict->height());
|
||||
}
|
||||
|
||||
static jlong android_graphics_Picture_beginRecording(JNIEnv* env, jobject, jlong pictHandle,
|
||||
jint w, jint h) {
|
||||
Picture* pict = reinterpret_cast<Picture*>(pictHandle);
|
||||
// beginRecording does not ref its return value, it just returns it.
|
||||
SkCanvas* canvas = pict->beginRecording(w, h);
|
||||
// the java side will wrap this guy in a Canvas.java, which will call
|
||||
// unref in its finalizer, so we have to ref it here, so that both that
|
||||
// Canvas.java and our picture can both be owners
|
||||
canvas->ref();
|
||||
return reinterpret_cast<jlong>(canvas);
|
||||
}
|
||||
|
||||
static void android_graphics_Picture_endRecording(JNIEnv* env, jobject, jlong pictHandle) {
|
||||
Picture* pict = reinterpret_cast<Picture*>(pictHandle);
|
||||
pict->endRecording();
|
||||
}
|
||||
|
||||
static JNINativeMethod gMethods[] = {
|
||||
{"nativeGetWidth", "(J)I", (void*) android_graphics_Picture_getWidth},
|
||||
{"nativeGetHeight", "(J)I", (void*) android_graphics_Picture_getHeight},
|
||||
{"nativeConstructor", "(J)J", (void*) android_graphics_Picture_newPicture},
|
||||
{"nativeCreateFromStream", "(Ljava/io/InputStream;[B)J", (void*)android_graphics_Picture_deserialize},
|
||||
{"nativeBeginRecording", "(JII)J", (void*) android_graphics_Picture_beginRecording},
|
||||
{"nativeEndRecording", "(J)V", (void*) android_graphics_Picture_endRecording},
|
||||
{"nativeDraw", "(JJ)V", (void*) android_graphics_Picture_draw},
|
||||
{"nativeWriteToStream", "(JLjava/io/OutputStream;[B)Z", (void*)android_graphics_Picture_serialize},
|
||||
{"nativeDestructor","(J)V", (void*) android_graphics_Picture_killPicture}
|
||||
};
|
||||
|
||||
int register_android_graphics_Picture(JNIEnv* env) {
|
||||
return AndroidRuntime::registerNativeMethods(env, "android/graphics/Picture", gMethods, NELEM(gMethods));
|
||||
}
|
||||
|
||||
}; // namespace android
|
||||
@@ -31,18 +31,13 @@ public class Picture {
|
||||
private Canvas mRecordingCanvas;
|
||||
private final long mNativePicture;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public final boolean createdFromStream;
|
||||
|
||||
private static final int WORKING_STREAM_STORAGE = 16 * 1024;
|
||||
|
||||
/**
|
||||
* Creates an empty picture that is ready to record.
|
||||
*/
|
||||
public Picture() {
|
||||
this(nativeConstructor(0), false);
|
||||
this(nativeConstructor(0));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -51,7 +46,23 @@ public class Picture {
|
||||
* changes will not be reflected in this picture.
|
||||
*/
|
||||
public Picture(Picture src) {
|
||||
this(nativeConstructor(src != null ? src.mNativePicture : 0), false);
|
||||
this(nativeConstructor(src != null ? src.mNativePicture : 0));
|
||||
}
|
||||
|
||||
private Picture(long nativePicture) {
|
||||
if (nativePicture == 0) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
mNativePicture = nativePicture;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
nativeDestructor(mNativePicture);
|
||||
} finally {
|
||||
super.finalize();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -85,13 +96,17 @@ public class Picture {
|
||||
* Get the width of the picture as passed to beginRecording. This
|
||||
* does not reflect (per se) the content of the picture.
|
||||
*/
|
||||
public native int getWidth();
|
||||
public int getWidth() {
|
||||
return nativeGetWidth(mNativePicture);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the height of the picture as passed to beginRecording. This
|
||||
* does not reflect (per se) the content of the picture.
|
||||
*/
|
||||
public native int getHeight();
|
||||
public int getHeight() {
|
||||
return nativeGetHeight(mNativePicture);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw this picture on the canvas.
|
||||
@@ -130,7 +145,7 @@ public class Picture {
|
||||
*/
|
||||
@Deprecated
|
||||
public static Picture createFromStream(InputStream stream) {
|
||||
return new Picture(nativeCreateFromStream(stream, new byte[WORKING_STREAM_STORAGE]), true);
|
||||
return new Picture(nativeCreateFromStream(stream, new byte[WORKING_STREAM_STORAGE]));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -159,32 +174,12 @@ public class Picture {
|
||||
}
|
||||
}
|
||||
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
nativeDestructor(mNativePicture);
|
||||
} finally {
|
||||
super.finalize();
|
||||
}
|
||||
}
|
||||
|
||||
final long ni() {
|
||||
return mNativePicture;
|
||||
}
|
||||
|
||||
private Picture(long nativePicture, boolean fromStream) {
|
||||
if (nativePicture == 0) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
mNativePicture = nativePicture;
|
||||
createdFromStream = fromStream;
|
||||
}
|
||||
|
||||
// return empty picture if src is 0, or a copy of the native src
|
||||
private static native long nativeConstructor(long nativeSrcOr0);
|
||||
private static native long nativeCreateFromStream(InputStream stream,
|
||||
byte[] storage);
|
||||
private static native long nativeBeginRecording(long nativeCanvas,
|
||||
int w, int h);
|
||||
private static native long nativeCreateFromStream(InputStream stream, byte[] storage);
|
||||
private static native int nativeGetWidth(long nativePicture);
|
||||
private static native int nativeGetHeight(long nativePicture);
|
||||
private static native long nativeBeginRecording(long nativeCanvas, int w, int h);
|
||||
private static native void nativeEndRecording(long nativeCanvas);
|
||||
private static native void nativeDraw(long nativeCanvas, long nativePicture);
|
||||
private static native boolean nativeWriteToStream(long nativePicture,
|
||||
@@ -201,18 +196,15 @@ public class Picture {
|
||||
|
||||
@Override
|
||||
public void setBitmap(Bitmap bitmap) {
|
||||
throw new RuntimeException(
|
||||
"Cannot call setBitmap on a picture canvas");
|
||||
throw new RuntimeException("Cannot call setBitmap on a picture canvas");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawPicture(Picture picture) {
|
||||
if (mPicture == picture) {
|
||||
throw new RuntimeException(
|
||||
"Cannot draw a picture into its recording canvas");
|
||||
throw new RuntimeException("Cannot draw a picture into its recording canvas");
|
||||
}
|
||||
super.drawPicture(picture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user