summaryrefslogtreecommitdiff
path: root/libs/hwui/jni/pdf/PdfDocument.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/hwui/jni/pdf/PdfDocument.cpp')
-rw-r--r--libs/hwui/jni/pdf/PdfDocument.cpp163
1 files changed, 163 insertions, 0 deletions
diff --git a/libs/hwui/jni/pdf/PdfDocument.cpp b/libs/hwui/jni/pdf/PdfDocument.cpp
new file mode 100644
index 000000000000..d21eb3f6a208
--- /dev/null
+++ b/libs/hwui/jni/pdf/PdfDocument.cpp
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2013 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 "GraphicsJNI.h"
+#include <vector>
+
+#include "CreateJavaOutputStreamAdaptor.h"
+
+#include "SkPDFDocument.h"
+#include "SkPicture.h"
+#include "SkPictureRecorder.h"
+#include "SkRect.h"
+#include "SkStream.h"
+
+#include <hwui/Canvas.h>
+
+namespace android {
+
+struct PageRecord {
+
+ PageRecord(int width, int height, const SkRect& contentRect)
+ : mPictureRecorder(new SkPictureRecorder())
+ , mPicture(NULL)
+ , mWidth(width)
+ , mHeight(height) {
+ mContentRect = contentRect;
+ }
+
+ ~PageRecord() {
+ delete mPictureRecorder;
+ if (NULL != mPicture) {
+ mPicture->unref();
+ }
+ }
+
+ SkPictureRecorder* mPictureRecorder;
+ SkPicture* mPicture;
+ const int mWidth;
+ const int mHeight;
+ SkRect mContentRect;
+};
+
+class PdfDocument {
+public:
+ PdfDocument() {
+ mCurrentPage = NULL;
+ }
+
+ SkCanvas* startPage(int width, int height,
+ int contentLeft, int contentTop, int contentRight, int contentBottom) {
+ assert(mCurrentPage == NULL);
+
+ SkRect contentRect = SkRect::MakeLTRB(
+ contentLeft, contentTop, contentRight, contentBottom);
+ PageRecord* page = new PageRecord(width, height, contentRect);
+ mPages.push_back(page);
+ mCurrentPage = page;
+
+ SkCanvas* canvas = page->mPictureRecorder->beginRecording(
+ SkRect::MakeWH(contentRect.width(), contentRect.height()));
+
+ return canvas;
+ }
+
+ void finishPage() {
+ assert(mCurrentPage != NULL);
+ assert(mCurrentPage->mPictureRecorder != NULL);
+ assert(mCurrentPage->mPicture == NULL);
+ mCurrentPage->mPicture = mCurrentPage->mPictureRecorder->finishRecordingAsPicture().release();
+ delete mCurrentPage->mPictureRecorder;
+ mCurrentPage->mPictureRecorder = NULL;
+ mCurrentPage = NULL;
+ }
+
+ void write(SkWStream* stream) {
+ sk_sp<SkDocument> document = SkPDF::MakeDocument(stream);
+ for (unsigned i = 0; i < mPages.size(); i++) {
+ PageRecord* page = mPages[i];
+
+ SkCanvas* canvas = document->beginPage(page->mWidth, page->mHeight,
+ &(page->mContentRect));
+ canvas->drawPicture(page->mPicture);
+
+ document->endPage();
+ }
+ document->close();
+ }
+
+ void close() {
+ assert(NULL == mCurrentPage);
+ for (unsigned i = 0; i < mPages.size(); i++) {
+ delete mPages[i];
+ }
+ }
+
+private:
+ ~PdfDocument() {
+ close();
+ }
+
+ std::vector<PageRecord*> mPages;
+ PageRecord* mCurrentPage;
+};
+
+static jlong nativeCreateDocument(JNIEnv* env, jobject thiz) {
+ return reinterpret_cast<jlong>(new PdfDocument());
+}
+
+static jlong nativeStartPage(JNIEnv* env, jobject thiz, jlong documentPtr,
+ jint pageWidth, jint pageHeight,
+ jint contentLeft, jint contentTop, jint contentRight, jint contentBottom) {
+ PdfDocument* document = reinterpret_cast<PdfDocument*>(documentPtr);
+ SkCanvas* canvas = document->startPage(pageWidth, pageHeight,
+ contentLeft, contentTop, contentRight, contentBottom);
+ return reinterpret_cast<jlong>(Canvas::create_canvas(canvas));
+}
+
+static void nativeFinishPage(JNIEnv* env, jobject thiz, jlong documentPtr) {
+ PdfDocument* document = reinterpret_cast<PdfDocument*>(documentPtr);
+ document->finishPage();
+}
+
+static void nativeWriteTo(JNIEnv* env, jobject thiz, jlong documentPtr, jobject out,
+ jbyteArray chunk) {
+ PdfDocument* document = reinterpret_cast<PdfDocument*>(documentPtr);
+ SkWStream* skWStream = CreateJavaOutputStreamAdaptor(env, out, chunk);
+ document->write(skWStream);
+ delete skWStream;
+}
+
+static void nativeClose(JNIEnv* env, jobject thiz, jlong documentPtr) {
+ PdfDocument* document = reinterpret_cast<PdfDocument*>(documentPtr);
+ document->close();
+}
+
+static const JNINativeMethod gPdfDocument_Methods[] = {
+ {"nativeCreateDocument", "()J", (void*) nativeCreateDocument},
+ {"nativeStartPage", "(JIIIIII)J", (void*) nativeStartPage},
+ {"nativeFinishPage", "(J)V", (void*) nativeFinishPage},
+ {"nativeWriteTo", "(JLjava/io/OutputStream;[B)V", (void*) nativeWriteTo},
+ {"nativeClose", "(J)V", (void*) nativeClose}
+};
+
+int register_android_graphics_pdf_PdfDocument(JNIEnv* env) {
+ return RegisterMethodsOrDie(
+ env, "android/graphics/pdf/PdfDocument", gPdfDocument_Methods,
+ NELEM(gPdfDocument_Methods));
+}
+
+};