pdfium源码包含了pdf的所有操作。这里基于PdfiumAndroid做个扩展,提供合并和分割PDF操作API
PdfWriter
修改后的pdf文档需要保存,首先需要提供写入文件操作
public class PdfWriter {
private ParcelFileDescriptor mOutput;
public PdfWriter(ParcelFileDescriptor output) {
mOutput = output;
}
public void write(PdfDocument doc) throws IOException {
synchronized (PdfiumCore.sPdfiumLock) {
throwIfClosed();
nativeWrite(doc.mNativeDocPtr, mOutput.getFd());
}
}
private static native boolean nativeWrite(long docPtr, int fd);
private void throwIfClosed() {
if (mOutput == null) {
throw new IllegalStateException("Already closed");
}
}
}
对应JNI实现如下:
//
// Created by svenj on 2019/2/3.
//
extern "C" {
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <string.h>
#include <stdio.h>
}
#include <fpdfview.h>
#include <fpdf_save.h>
#include "util.hpp"
struct PdfToFdWriter : FPDF_FILEWRITE {
int dstFd;
};
static bool writeAllBytes(const int fd, const void *buffer, const size_t byteCount) {
char *writeBuffer = static_cast<char *>(const_cast<void *>(buffer));
size_t remainingBytes = byteCount;
while (remainingBytes > 0) {
ssize_t writtenByteCount = write(fd, writeBuffer, remainingBytes);
if (writtenByteCount == -1) {
if (errno == EINTR) {
continue;
}
LOGE("Error writing to buffer: %d", errno);
return false;
}
remainingBytes -= writtenByteCount;
writeBuffer += writtenByteCount;
}
return true;
}
static int writeBlock(FPDF_FILEWRITE* owner, const void* buffer, unsigned long size) {
const PdfToFdWriter* writer = reinterpret_cast<PdfToFdWriter*>(owner);
const bool success = writeAllBytes(writer->dstFd, buffer, size);
if (success < 0) {
LOGE("Cannot write to file descriptor. Error:%d", errno);
return 0;
}
return 1;
}
JNI_FUNC(jboolean, PdfWriter, nativeWrite)(JNI_ARGS, jlong docPtr, jint fd) {
auto document = reinterpret_cast<FPDF_DOCUMENT>(docPtr);
PdfToFdWriter writer;
writer.dstFd = fd;
writer.WriteBlock = &writeBlock;
FPDF_BOOL success = FPDF_SaveAsCopy(document, &writer, FPDF_NO_INCREMENTAL);
if (!success) {
jniThrowExceptionFmt(env, "java/io/IOException",
"cannot write to fd. Error: %d", errno);
}
}
网友评论