static jlong nativeOpenPageAndGetSize(JNIEnv* env, jclass thiz, jlong documentPtr,
        jint pageIndex, jobject outSize) {
    FPDF_DOCUMENT document = reinterpret_cast<FPDF_DOCUMENT>(documentPtr);

    FPDF_PAGE page = FPDF_LoadPage(document, pageIndex);

    if (!page) {
        jniThrowException(env, "java/lang/IllegalStateException",
                "cannot load page");
        return -1;
    }

    double width = 0;
    double height = 0;

    const int result = FPDF_GetPageSizeByIndex(document, pageIndex, &width, &height);

    if (!result) {
        jniThrowException(env, "java/lang/IllegalStateException",
                    "cannot get page size");
        return -1;
    }

    env->SetIntField(outSize, gPointClassInfo.x, width);
    env->SetIntField(outSize, gPointClassInfo.y, height);

    return reinterpret_cast<jlong>(page);
}
static void nativeSetTransformAndClip(JNIEnv* env, jclass thiz, jlong documentPtr, jint pageIndex,
        jlong transformPtr, jint clipLeft, jint clipTop, jint clipRight, jint clipBottom) {
    FPDF_DOCUMENT document = reinterpret_cast<FPDF_DOCUMENT>(documentPtr);

    CPDF_Page* page = (CPDF_Page*) FPDF_LoadPage(document, pageIndex);
    if (!page) {
        jniThrowException(env, "java/lang/IllegalStateException",
                "cannot open page");
        return;
    }

    double width = 0;
    double height = 0;

    const int result = FPDF_GetPageSizeByIndex(document, pageIndex, &width, &height);
    if (!result) {
        jniThrowException(env, "java/lang/IllegalStateException",
                    "cannot get page size");
        return;
    }

    CFX_AffineMatrix matrix;

    SkMatrix* skTransform = reinterpret_cast<SkMatrix*>(transformPtr);

    SkScalar transformValues[6];
    if (!skTransform->asAffine(transformValues)) {
        jniThrowException(env, "java/lang/IllegalArgumentException",
                "transform matrix has perspective. Only affine matrices are allowed.");
        return;
    }

    // PDF's coordinate system origin is left-bottom while in graphics it
    // is the top-left. So, translate the PDF coordinates to ours.
    matrix.Set(1, 0, 0, -1, 0, page->GetPageHeight());

    // Apply the transformation what was created in our coordinates.
    matrix.Concat(transformValues[SkMatrix::kAScaleX], transformValues[SkMatrix::kASkewY],
            transformValues[SkMatrix::kASkewX], transformValues[SkMatrix::kAScaleY],
            transformValues[SkMatrix::kATransX], transformValues[SkMatrix::kATransY]);

    // Translate the result back to PDF coordinates.
    matrix.Concat(1, 0, 0, -1, 0, page->GetPageHeight());

    FS_MATRIX transform = {matrix.a, matrix.b, matrix.c, matrix.d, matrix.e, matrix.f};
    FS_RECTF clip = {(float) clipLeft, (float) clipTop, (float) clipRight, (float) clipBottom};

    FPDFPage_TransFormWithClip(page, &transform, &clip);

    FPDF_ClosePage(page);
}