diff options
| author | Gabriel Schneider <[email protected]> | 2026-08-02 17:17:35 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-08-10 09:17:07 -0300 |
| commit | 5961587b227e5fa097fb033e32c29da08a23fb18 (patch) | |
| tree | 359883d5531e595d47f75824a77a0c1323973e2e /src/pdf_bridge.h | |
| parent | 487434a0b55fa7cf479f39481b51da0a7eda79e1 (diff) | |
| download | pardes-5961587b227e5fa097fb033e32c29da08a23fb18.tar.gz pardes-5961587b227e5fa097fb033e32c29da08a23fb18.zip | |
tty/image: big harness + golden coverage pass
Diffstat (limited to 'src/pdf_bridge.h')
| -rw-r--r-- | src/pdf_bridge.h | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/src/pdf_bridge.h b/src/pdf_bridge.h new file mode 100644 index 00000000..85f477d0 --- /dev/null +++ b/src/pdf_bridge.h @@ -0,0 +1,171 @@ +#ifndef PARDES_PDF_BRIDGE_H +#define PARDES_PDF_BRIDGE_H + +#include <stddef.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * MuPDF reports failures with setjmp/longjmp through fz_try/fz_catch. Those + * jumps must never cross Zig frames, so every operation that can throw lives + * behind this deliberately small C boundary. + */ +typedef struct pardes_pdf_document pardes_pdf_document; + +typedef struct pardes_pdf_pixmap { + void *handle; + const unsigned char *samples; + int width; + int height; + int stride; + int components; +} pardes_pdf_pixmap; + +typedef struct pardes_pdf_text { + void *handle; + const unsigned char *data; + size_t len; +} pardes_pdf_text; + +/* + * All geometry crossing this boundary is normalized to the cached page's + * bounds. (0,0) is the page's top-left and (1,1) its bottom-right, regardless + * of the DPI used for a particular render. Corner names retain MuPDF's quad + * orientation; callers must not collapse them to an axis-aligned rectangle. + */ +typedef struct pardes_pdf_point { + float x; + float y; +} pardes_pdf_point; + +typedef struct pardes_pdf_quad { + pardes_pdf_point ul; + pardes_pdf_point ur; + pardes_pdf_point ll; + pardes_pdf_point lr; +} pardes_pdf_quad; + +typedef enum pardes_pdf_highlight_kind { + PARDES_PDF_HIGHLIGHT_CUSTOM = 0, + PARDES_PDF_HIGHLIGHT_SEARCH = 1, + PARDES_PDF_HIGHLIGHT_SELECTION = 2 +} pardes_pdf_highlight_kind; + +typedef struct pardes_pdf_highlight { + pardes_pdf_quad quad; + unsigned char rgba[4]; + int kind; +} pardes_pdf_highlight; + +typedef struct pardes_pdf_search_quad { + pardes_pdf_quad quad; + size_t hit; +} pardes_pdf_search_quad; + +typedef struct pardes_pdf_search_result { + void *handle; + const pardes_pdf_search_quad *quads; + size_t quad_count; + size_t hit_count; +} pardes_pdf_search_result; + +typedef struct pardes_pdf_selection { + void *handle; + const pardes_pdf_quad *quads; + size_t quad_count; + pardes_pdf_point start; + pardes_pdf_point end; +} pardes_pdf_selection; + +typedef struct pardes_pdf_owned_text { + void *handle; + const unsigned char *data; + size_t len; +} pardes_pdf_owned_text; + +enum { + PARDES_PDF_OK = 0, + PARDES_PDF_ERROR = -1, + PARDES_PDF_LIMIT_EXCEEDED = -2, + + /* Per-document MuPDF eviction cache; render buffers are separate. */ + PARDES_PDF_STORE_LIMIT_BYTES = 64 * 1024 * 1024, + + /* + * Search grows geometrically up to this aggregate count and then fails + * atomically with PARDES_PDF_LIMIT_EXCEEDED; it never returns a silently + * truncated result. Selection uses one extra private probe slot so an + * exact-at-the-limit result remains distinguishable from truncation. + */ + PARDES_PDF_MAX_RESULT_QUADS = 65536 +}; + +pardes_pdf_document *pardes_pdf_open(const char *path, int *page_count); +void pardes_pdf_close(pardes_pdf_document *document); + +int pardes_pdf_render( + pardes_pdf_document *document, + int page, + int max_dimension, + pardes_pdf_pixmap *out +); + +int pardes_pdf_render_with_highlights( + pardes_pdf_document *document, + int page, + int max_dimension, + const pardes_pdf_highlight *highlights, + size_t highlight_count, + pardes_pdf_pixmap *out +); +void pardes_pdf_drop_pixmap(pardes_pdf_document *document, void *pixmap); + +int pardes_pdf_page_text( + pardes_pdf_document *document, + int page, + pardes_pdf_text *out +); +void pardes_pdf_drop_text(pardes_pdf_document *document, void *buffer); + +/* Case-insensitive, single-page search using MuPDF 1.27's iterative API. */ +int pardes_pdf_search_page( + pardes_pdf_document *document, + int page, + const char *needle, + pardes_pdf_search_result *out +); +void pardes_pdf_drop_search_result(pardes_pdf_document *document, void *result); + +/* Word-snap two normalized points and return oriented highlight quads. */ +int pardes_pdf_select( + pardes_pdf_document *document, + int page, + pardes_pdf_point start, + pardes_pdf_point end, + pardes_pdf_selection *out +); +void pardes_pdf_drop_selection(pardes_pdf_document *document, void *selection); + +/* Pure/no-throw oriented-quad hit test in normalized page space. */ +int pardes_pdf_point_inside_quad( + pardes_pdf_point point, + pardes_pdf_quad quad +); + +/* The input endpoints are normally the snapped points returned above. */ +int pardes_pdf_copy_selection( + pardes_pdf_document *document, + int page, + pardes_pdf_point start, + pardes_pdf_point end, + pardes_pdf_owned_text *out +); +void pardes_pdf_drop_owned_text(pardes_pdf_document *document, void *text); + +#ifdef __cplusplus +} +#endif + +#endif |
