#include "pdf/pdfium/pdfium_progressive_searchifier.h"
#include "base/check.h"
#include "base/compiler_specific.h"
#include "pdf/pdfium/pdfium_engine.h"
#include "pdf/pdfium/pdfium_mem_buffer_file_write.h"
#include "pdf/pdfium/pdfium_searchify.h"
#include "services/screen_ai/public/mojom/screen_ai_service.mojom.h"
#include "ui/gfx/codec/jpeg_codec.h"
namespace chrome_pdf {
PdfiumProgressiveSearchifier::ScopedSdkInitializer::ScopedSdkInitializer() {
InitializeSDK(false, false, FontMappingMode::kNoMapping);
}
PdfiumProgressiveSearchifier::ScopedSdkInitializer::~ScopedSdkInitializer() {
ShutdownSDK();
}
PdfiumProgressiveSearchifier::PdfiumProgressiveSearchifier()
: doc_(FPDF_CreateNewDocument()), font_(CreateFont(doc_.get())) {
CHECK(doc_);
CHECK(font_);
}
PdfiumProgressiveSearchifier::~PdfiumProgressiveSearchifier() = default;
void PdfiumProgressiveSearchifier::AddPage(
const SkBitmap& bitmap,
uint32_t page_index,
screen_ai::mojom::VisualAnnotationPtr annotation) {
CHECK(annotation);
DeletePage(page_index);
int width = bitmap.width();
int height = bitmap.height();
ScopedFPDFPage page(FPDFPage_New(doc_.get(), page_index, width, height));
CHECK(page);
ScopedFPDFPageObject image(FPDFPageObj_NewImageObj(doc_.get()));
CHECK(image);
std::optional<std::vector<uint8_t>> encoded =
gfx::JPEGCodec::Encode(bitmap, 100);
CHECK(encoded.has_value());
base::span<const uint8_t> encoded_span(encoded.value());
FPDF_FILEACCESS file_access = {};
file_access.m_FileLen = static_cast<unsigned long>(encoded_span.size());
file_access.m_GetBlock = [](void* param, unsigned long pos,
unsigned char* buf, unsigned long size) {
base::span<const uint8_t>& encoded_span =
*static_cast<base::span<const uint8_t>*>(param);
if (pos + size < pos || pos + size > encoded_span.size()) {
return 0;
}
base::span<uint8_t> UNSAFE_TODO(buf_span(buf, size));
buf_span.copy_from(encoded_span.subspan(pos, size));
return 1;
};
file_access.m_Param = &encoded_span;
CHECK(FPDFImageObj_LoadJpegFileInline(nullptr, 0, image.get(), &file_access));
CHECK(FPDFImageObj_SetMatrix(image.get(), width, 0, 0, height, 0, 0));
AddTextOnImage(doc_.get(), page.get(), font_.get(), image.get(),
std::move(annotation), gfx::Size(width, height));
FPDFPage_InsertObject(page.get(), image.release());
CHECK(FPDFPage_GenerateContent(page.get()));
}
void PdfiumProgressiveSearchifier::DeletePage(uint32_t page_index) {
FPDFPage_Delete(doc_.get(), page_index);
}
std::vector<uint8_t> PdfiumProgressiveSearchifier::Save() {
PDFiumMemBufferFileWrite output_file_write;
CHECK(FPDF_SaveAsCopy(doc_.get(), &output_file_write, 0));
return output_file_write.TakeBuffer();
}
}