Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Preliminary Bindings for Skia's PDF Backend #40

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ file(GLOB SOURCES ${CMAKE_SOURCE_DIR}/src/main/cc/*.cc)
file(GLOB IMPL_SOURCES ${CMAKE_SOURCE_DIR}/src/main/cc/impl/*.cc)
file(GLOB SHAPER_SOURCES ${CMAKE_SOURCE_DIR}/src/main/cc/shaper/*.cc)
file(GLOB PARAGRAPH_SOURCES ${CMAKE_SOURCE_DIR}/src/main/cc/paragraph/*.cc)
file(GLOB PDF_SOURCES ${CMAKE_SOURCE_DIR}/src/main/cc/pdf/*.cc)
add_definitions(-DSK_GL -DSK_SHAPER_HARFBUZZ_AVAILABLE)
add_library(skija SHARED ${SOURCES} ${IMPL_SOURCES} ${SHAPER_SOURCES} ${PARAGRAPH_SOURCES})
add_library(skija SHARED ${SOURCES} ${IMPL_SOURCES} ${SHAPER_SOURCES} ${PARAGRAPH_SOURCES} ${PDF_SOURCES})

# JNI
if(APPLE)
Expand Down
11 changes: 11 additions & 0 deletions src/main/cc/Font.cc
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,17 @@ extern "C" JNIEXPORT jobject JNICALL Java_org_jetbrains_skija_Font__1nMeasureTex
return skija::Rect::fromSkRect(env, bounds);
}

extern "C" JNIEXPORT jfloat JNICALL Java_org_jetbrains_skija_Font__1nMeasureTextWidth
(JNIEnv* env, jclass jclass, jlong ptr, jstring str, jlong paintPtr) {
SkFont* instance = reinterpret_cast<SkFont*>(static_cast<uintptr_t>(ptr));
SkPaint* paint = reinterpret_cast<SkPaint*>(static_cast<uintptr_t>(paintPtr));
jsize len = env->GetStringLength(str);
const jchar* chars = env->GetStringChars(str, nullptr);
float width = instance->measureText(chars, len * sizeof(jchar), SkTextEncoding::kUTF16, nullptr, paint);
env->ReleaseStringChars(str, chars);
return width;
}

extern "C" JNIEXPORT jfloatArray JNICALL Java_org_jetbrains_skija_Font__1nGetWidths
(JNIEnv* env, jclass jclass, jlong ptr, jshortArray glyphsArr) {
SkFont* instance = reinterpret_cast<SkFont*>(static_cast<uintptr_t>(ptr));
Expand Down
108 changes: 108 additions & 0 deletions src/main/cc/pdf/Document.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
#include <iostream>
#include <jni.h>
#include "include/docs/SkPDFDocument.h"
#include "SkCanvas.h"
#include "SkStream.h"
#include "SkRect.h"
#include "SkPictureRecorder.h"

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 Document {
public:
Document() {
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:
~Document() {
close();
}
std::vector<PageRecord*> mPages;
PageRecord* mCurrentPage;
};

extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skija_pdf_Document__1nMake(JNIEnv* env, jclass jclass) {
return reinterpret_cast<jlong>(new Document());
}

extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skija_pdf_Document__1nBeginPage
(JNIEnv* env, jclass jclass, jlong ptr, jfloat width, jfloat height/*, jfloat left, jfloat top, jfloat right, jfloat bottom*/) {
Document* instance = reinterpret_cast<Document*>(static_cast<uintptr_t>(ptr));
SkCanvas* canvas = instance->startPage(width, height, 0, 0, width, height);
return reinterpret_cast<jlong>(canvas);
}

extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skija_pdf_Document__1nWrite(JNIEnv* env, jclass jclass, jlong ptr, jstring pathStr) {
Document* document = reinterpret_cast<Document*>(ptr);
const char* path = env->GetStringUTFChars(pathStr, nullptr);
SkFILEWStream out(path);
env->ReleaseStringUTFChars(pathStr, path);
document->write(&out);
}

extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skija_pdf_Document__1nEndPage(JNIEnv* env, jclass jclass, jlong ptr) {
Document* document = reinterpret_cast<Document*>(ptr);
document->finishPage();
}
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skija_pdf_Document__1nClose(JNIEnv* env, jclass jclass, jlong ptr) {
Document* document = reinterpret_cast<Document*>(ptr);
document->close();
}

11 changes: 11 additions & 0 deletions src/main/java/org/jetbrains/skija/Font.java
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,16 @@ public Rect measureText(String s, Paint p) {
return _nMeasureText(_ptr, s, Native.getPtr(p));
}

public float measureTextWidth(String s) {
Stats.onNativeCall();
return measureTextWidth(s, null);
}

public float measureTextWidth(String s, Paint p) {
Stats.onNativeCall();
return _nMeasureTextWidth(_ptr, s, Native.getPtr(p));
}

/**
* Retrieves the advances for each glyph
*/
Expand Down Expand Up @@ -502,6 +512,7 @@ public TextBlob shape(String str, float width) {
@ApiStatus.Internal public static native short[] _nGetUTF32GlyphIds(long ptr, int[] uni);
@ApiStatus.Internal public static native int _nGetStringGlyphsCount(long ptr, String str);
@ApiStatus.Internal public static native Rect _nMeasureText(long ptr, String str, long paintPtr);
@ApiStatus.Internal public static native float _nMeasureTextWidth(long ptr, String str, long paintPtr);
@ApiStatus.Internal public static native float[] _nGetWidths(long ptr, short[] glyphs);
@ApiStatus.Internal public static native Rect[] _nGetBounds(long ptr, short[] glyphs, long paintPtr);
@ApiStatus.Internal public static native Point[] _nGetPositions(long ptr, short[] glyphs, float x, float y);
Expand Down
48 changes: 48 additions & 0 deletions src/main/java/org/jetbrains/skija/pdf/Document.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package org.jetbrains.skija.pdf;

import org.jetbrains.skija.Canvas;
import org.jetbrains.skija.impl.Native;
import org.jetbrains.skija.impl.Stats;

public class Document extends Native {
public Document() {
this(_nMake());
Stats.onNativeCall();
}

public Document(long ptr) {
super(ptr);
}

public Canvas beginPage(float width, float height) {
Stats.onNativeCall();
return new Canvas(_nBeginPage(_ptr, width, height));
}

public void endPage() {
Stats.onNativeCall();
_nEndPage(_ptr);
}

public void writeTo(String path) {
Stats.onNativeCall();
_nWrite(_ptr, path);
}

public void close() {
Stats.onNativeCall();
_nClose(_ptr);
}

public static native long _nMake();

public static native long _nGetFinalizer();

public static native long _nBeginPage(long ptr, float width, float height);

public static native void _nEndPage(long ptr);

public static native void _nWrite(long ptr, String path);

public static native void _nClose(long ptr);
}