Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the ability to write Devices in Rust #105

Merged
merged 11 commits into from
Feb 19, 2025
4 changes: 2 additions & 2 deletions mupdf-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,8 @@ fn build_libmupdf() {
];

// this may be unused if none of the features below are enabled
#[allow(unused_variables)]
let add_lib = |cflags_name: &'static str, pkgcfg_name: &'static str| {
#[allow(unused_variables, unused_mut)]
let mut add_lib = |cflags_name: &'static str, pkgcfg_name: &'static str| {
make_flags.push(format!(
"SYS_{cflags_name}_CFLAGS={}",
pkg_config::probe_library(pkgcfg_name)
Expand Down
46 changes: 46 additions & 0 deletions mupdf-sys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,49 @@
#![allow(clippy::all)]

include!(concat!(env!("OUT_DIR"), "/bindings.rs"));

use core::ffi::{c_int, CStr};

/// This function allocates a new device and returns a pointer to it if no error occured. For the
/// required structure of `T` check the example below. If an error occurs the pointer `errptr` points
/// to will be set to to a pointer pointing to the error and null returned from this function.
///
/// # Safety
///
/// The caller must ensure `ctx` and `errptr` to be a valid pointers.
///
/// It must also ensure `T` to be a type that starts with `fz_device`. Memory will be allocated for
/// a new instance of `T`, but only the `fz_device` portion will be initialized. The rest is
/// currently being zero-initialized, but this might change in the future.
///
/// # Example
///
/// This is how a compliant `T` might look like. The `repr(C)` is necessary as `repr(Rust)` does
/// not guarantee stable field orderings.
///
/// ```rust
/// use mupdf_sys::fz_device;
///
/// #[repr(C)]
/// struct MyDevice {
/// base: fz_device,
/// foo: u32,
/// }
/// ```
pub unsafe fn mupdf_new_derived_device<T>(
ctx: *mut fz_context,
label: &'static CStr,
errptr: *mut *mut mupdf_error_t,
) -> *mut T {
let SIZE: c_int = const {
if (c_int::MAX as usize) < size_of::<T>() {
panic!("device too big")
} else {
size_of::<T>() as c_int
}
};

let device = mupdf_new_device_of_size(ctx, SIZE, errptr);
let label = Memento_label(device.cast(), label.as_ptr());
label.cast()
}
66 changes: 64 additions & 2 deletions mupdf-sys/wrapper.c
Original file line number Diff line number Diff line change
Expand Up @@ -2640,6 +2640,20 @@ fz_device *mupdf_new_draw_device(fz_context *ctx, fz_pixmap *pixmap, fz_irect cl
return device;
}

fz_device *mupdf_new_device_of_size(fz_context *ctx, int size, mupdf_error_t **errptr)
{
fz_device *device = NULL;
fz_try(ctx)
{
device = fz_new_device_of_size(ctx, size);
}
fz_catch(ctx)
{
mupdf_save_error(ctx, errptr);
}
return device;
}

fz_device *mupdf_new_display_list_device(fz_context *ctx, fz_display_list *list, mupdf_error_t **errptr)
{
fz_device *device = NULL;
Expand Down Expand Up @@ -2863,6 +2877,54 @@ void mupdf_end_layer(fz_context *ctx, fz_device *device, mupdf_error_t **errptr)
}
}

void mupdf_begin_structure(fz_context *ctx, fz_device *device, fz_structure standard, const char *raw, int idx, mupdf_error_t **errptr)
{
fz_try(ctx)
{
fz_begin_structure(ctx, device, standard, raw, idx);
}
fz_catch(ctx)
{
mupdf_save_error(ctx, errptr);
}
}

void mupdf_end_structure(fz_context *ctx, fz_device *device, mupdf_error_t **errptr)
{
fz_try(ctx)
{
fz_end_structure(ctx, device);
}
fz_catch(ctx)
{
mupdf_save_error(ctx, errptr);
}
}

void mupdf_begin_metatext(fz_context *ctx, fz_device *device, fz_metatext meta, const char *text, mupdf_error_t **errptr)
{
fz_try(ctx)
{
fz_begin_metatext(ctx, device, meta, text);
}
fz_catch(ctx)
{
mupdf_save_error(ctx, errptr);
}
}

void mupdf_end_metatext(fz_context *ctx, fz_device *device, mupdf_error_t **errptr)
{
fz_try(ctx)
{
fz_end_metatext(ctx, device);
}
fz_catch(ctx)
{
mupdf_save_error(ctx, errptr);
}
}

void mupdf_begin_mask(fz_context *ctx, fz_device *device, fz_rect area, bool luminosity, fz_colorspace *cs, const float *color, fz_color_params cp, mupdf_error_t **errptr)
{
fz_try(ctx)
Expand All @@ -2875,11 +2937,11 @@ void mupdf_begin_mask(fz_context *ctx, fz_device *device, fz_rect area, bool lum
}
}

void mupdf_end_mask(fz_context *ctx, fz_device *device, mupdf_error_t **errptr)
void mupdf_end_mask(fz_context *ctx, fz_device *device, fz_function *fn, mupdf_error_t **errptr)
{
fz_try(ctx)
{
fz_end_mask(ctx, device);
fz_end_mask_tr(ctx, device, fn);
}
fz_catch(ctx)
{
Expand Down
Loading