#ifndef PDF_PDFIUM_PDFIUM_ON_DEMAND_SEARCHIFIER_H_
#define PDF_PDFIUM_PDFIUM_ON_DEMAND_SEARCHIFIER_H_
#include <stdint.h>
#include <optional>
#include <vector>
#include "base/containers/circular_deque.h"
#include "base/functional/callback_forward.h"
#include "base/memory/raw_ref.h"
#include "base/memory/weak_ptr.h"
#include "pdf/pdfium/pdfium_engine.h"
#include "services/screen_ai/public/mojom/screen_ai_service.mojom.h"
#include "third_party/pdfium/public/cpp/fpdf_scopers.h"
#include "third_party/skia/include/core/SkBitmap.h"
namespace chrome_pdf {
class PDFiumOnDemandSearchifier {
public:
explicit PDFiumOnDemandSearchifier(PDFiumEngine* engine);
~PDFiumOnDemandSearchifier();
void Start(GetOcrMaxImageDimensionCallbackAsync get_max_dimension_callback,
PerformOcrCallbackAsync perform_ocr_callback);
void OnOcrDisconnected();
bool IsPageScheduled(uint32_t page_index) const;
void SchedulePage(uint32_t page_index);
bool HasFailed() const { return state_ == State::kFailed; }
bool PerformedOCR() const { return performed_ocr_; }
private:
friend class PDFiumOnDemandSearchifierTest;
enum class State {
kIdle,
kWaitingForResults,
kWaitingForPageAvailability,
kFailed
};
void SearchifyNextPage();
void SearchifyNextImage();
void CommitResultsToPage();
void ClearCurrentPage();
struct BitmapResult {
SkBitmap bitmap;
int image_index;
};
struct OcrResult {
OcrResult(int image_index,
screen_ai::mojom::VisualAnnotationPtr annotation,
const gfx::Size& image_size);
OcrResult(const OcrResult& other) = delete;
OcrResult(OcrResult&& other) noexcept;
~OcrResult();
int image_index = 0;
screen_ai::mojom::VisualAnnotationPtr annotation;
gfx::Size image_size;
};
void OnGotOcrMaxImageDimension(uint32_t max_image_dimension);
std::optional<BitmapResult> GetNextBitmap();
void OnGotOcrResult(int image_index,
const gfx::Size& image_size,
screen_ai::mojom::VisualAnnotationPtr annotation);
const raw_ref<PDFiumEngine> engine_;
ScopedFPDFFont font_;
GetOcrMaxImageDimensionCallbackAsync get_max_dimension_callback_;
PerformOcrCallbackAsync perform_ocr_callback_;
uint32_t max_image_dimension_ = 0;
raw_ptr<PDFiumPage> current_page_ = nullptr;
bool current_page_was_loaded_ = false;
std::vector<int> current_page_image_object_indices_;
std::vector<OcrResult> current_page_ocr_results_;
bool performed_ocr_ = false;
base::circular_deque<uint32_t> pages_queue_;
State state_ = State::kIdle;
base::WeakPtrFactory<PDFiumOnDemandSearchifier> weak_factory_{this};
};
}
#endif