use super::document::{CPDF_DOCS, CPDF_RANGES};
use super::{clear_error, set_error};
use crate::cpdf::pages;
use crate::ffi::Handle;
use std::ffi::{CStr, c_char, c_int};
macro_rules! get_doc_clone {
($handle:expr) => {
match CPDF_DOCS.get($handle) {
Some(arc) => arc.lock().unwrap().clone(),
None => {
set_error(1, &format!("invalid document handle: {}", $handle));
return 0;
}
}
};
}
macro_rules! get_range {
($handle:expr) => {
match CPDF_RANGES.get($handle) {
Some(arc) => arc.lock().unwrap().clone(),
None => {
set_error(1, &format!("invalid range handle: {}", $handle));
return 0;
}
}
};
}
macro_rules! ok_or_error {
($result:expr) => {
match $result {
Ok(doc) => CPDF_DOCS.insert(doc),
Err(e) => {
set_error(1, &e.to_string());
0
}
}
};
}
#[unsafe(no_mangle)]
pub extern "C" fn cpdf_rotate(doc: Handle, range: Handle, degrees: c_int) -> Handle {
clear_error();
let d = get_doc_clone!(doc);
let r = get_range!(range);
ok_or_error!(pages::rotate_pages(d, &r, degrees))
}
#[unsafe(no_mangle)]
pub extern "C" fn cpdf_rotateBy(doc: Handle, range: Handle, degrees: c_int) -> Handle {
clear_error();
let d = get_doc_clone!(doc);
let r = get_range!(range);
ok_or_error!(pages::rotate_pages_by(d, &r, degrees))
}
#[unsafe(no_mangle)]
pub extern "C" fn cpdf_rotateContents(doc: Handle, range: Handle, angle: f64) -> Handle {
clear_error();
let d = get_doc_clone!(doc);
let r = get_range!(range);
ok_or_error!(pages::rotate_contents(d, &r, angle))
}
#[unsafe(no_mangle)]
pub extern "C" fn cpdf_upright(doc: Handle, range: Handle) -> Handle {
clear_error();
let d = get_doc_clone!(doc);
let r = get_range!(range);
ok_or_error!(pages::upright(d, &r))
}
#[unsafe(no_mangle)]
pub extern "C" fn cpdf_scale(doc: Handle, range: Handle, sx: f64, sy: f64) -> Handle {
clear_error();
let d = get_doc_clone!(doc);
let r = get_range!(range);
ok_or_error!(pages::scale_pages(d, &r, sx, sy))
}
#[unsafe(no_mangle)]
pub extern "C" fn cpdf_scaleToFit(
doc: Handle,
range: Handle,
w: f64,
h: f64,
scale_factor: f64,
) -> Handle {
clear_error();
let d = get_doc_clone!(doc);
let r = get_range!(range);
ok_or_error!(pages::scale_to_fit(d, &r, w, h, scale_factor))
}
#[unsafe(no_mangle)]
pub extern "C" fn cpdf_scaleToFitPaper(
doc: Handle,
range: Handle,
papersize_code: c_int,
) -> Handle {
clear_error();
let (w, h) = match papersize_code {
0 => (595.0, 842.0), 1 => (612.0, 792.0), 2 => (612.0, 1008.0), 3 => (420.0, 595.0), 4 => (842.0, 1190.0), _ => {
set_error(1, &format!("unknown paper size code: {papersize_code}"));
return 0;
}
};
let d = get_doc_clone!(doc);
let r = get_range!(range);
ok_or_error!(pages::scale_to_fit(d, &r, w, h, 1.0))
}
#[unsafe(no_mangle)]
pub extern "C" fn cpdf_stretch(doc: Handle, range: Handle, w: f64, h: f64) -> Handle {
clear_error();
let d = get_doc_clone!(doc);
let r = get_range!(range);
ok_or_error!(pages::stretch_pages(d, &r, w, h))
}
#[unsafe(no_mangle)]
pub extern "C" fn cpdf_shift(doc: Handle, range: Handle, dx: f64, dy: f64) -> Handle {
clear_error();
let d = get_doc_clone!(doc);
let r = get_range!(range);
ok_or_error!(pages::shift_pages(d, &r, dx, dy))
}
#[unsafe(no_mangle)]
pub extern "C" fn cpdf_vflip(doc: Handle, range: Handle) -> Handle {
clear_error();
let d = get_doc_clone!(doc);
let r = get_range!(range);
ok_or_error!(pages::vflip_pages(d, &r))
}
#[unsafe(no_mangle)]
pub extern "C" fn cpdf_hflip(doc: Handle, range: Handle) -> Handle {
clear_error();
let d = get_doc_clone!(doc);
let r = get_range!(range);
ok_or_error!(pages::hflip_pages(d, &r))
}
#[unsafe(no_mangle)]
pub extern "C" fn cpdf_crop(doc: Handle, range: Handle, x: f64, y: f64, w: f64, h: f64) -> Handle {
clear_error();
let d = get_doc_clone!(doc);
let r = get_range!(range);
ok_or_error!(pages::crop_pages(d, &r, x, y, w, h))
}
#[unsafe(no_mangle)]
pub extern "C" fn cpdf_setMediaBox(
doc: Handle,
range: Handle,
x: f64,
y: f64,
w: f64,
h: f64,
) -> Handle {
clear_error();
let d = get_doc_clone!(doc);
let r = get_range!(range);
ok_or_error!(pages::set_mediabox(d, &r, x, y, w, h))
}
#[unsafe(no_mangle)]
pub extern "C" fn cpdf_setCropBox(
doc: Handle,
range: Handle,
x: f64,
y: f64,
w: f64,
h: f64,
) -> Handle {
clear_error();
let d = get_doc_clone!(doc);
let r = get_range!(range);
ok_or_error!(pages::set_cropbox(d, &r, x, y, w, h))
}
#[unsafe(no_mangle)]
pub extern "C" fn cpdf_setTrimBox(
doc: Handle,
range: Handle,
x: f64,
y: f64,
w: f64,
h: f64,
) -> Handle {
clear_error();
let d = get_doc_clone!(doc);
let r = get_range!(range);
ok_or_error!(pages::set_trimbox(d, &r, x, y, w, h))
}
#[unsafe(no_mangle)]
pub extern "C" fn cpdf_setBleedBox(
doc: Handle,
range: Handle,
x: f64,
y: f64,
w: f64,
h: f64,
) -> Handle {
clear_error();
let d = get_doc_clone!(doc);
let r = get_range!(range);
ok_or_error!(pages::set_bleedbox(d, &r, x, y, w, h))
}
#[unsafe(no_mangle)]
pub extern "C" fn cpdf_setArtBox(
doc: Handle,
range: Handle,
x: f64,
y: f64,
w: f64,
h: f64,
) -> Handle {
clear_error();
let d = get_doc_clone!(doc);
let r = get_range!(range);
ok_or_error!(pages::set_artbox(d, &r, x, y, w, h))
}
#[unsafe(no_mangle)]
pub extern "C" fn cpdf_removeCropBox(doc: Handle, range: Handle) -> Handle {
clear_error();
let d = get_doc_clone!(doc);
let r = get_range!(range);
ok_or_error!(pages::remove_cropbox(d, &r))
}
#[unsafe(no_mangle)]
pub extern "C" fn cpdf_removeTrimBox(doc: Handle, range: Handle) -> Handle {
clear_error();
let d = get_doc_clone!(doc);
let r = get_range!(range);
ok_or_error!(pages::remove_trimbox(d, &r))
}
#[unsafe(no_mangle)]
pub extern "C" fn cpdf_removeBleedBox(doc: Handle, range: Handle) -> Handle {
clear_error();
let d = get_doc_clone!(doc);
let r = get_range!(range);
ok_or_error!(pages::remove_bleedbox(d, &r))
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn cpdf_copyBox(
doc: Handle,
range: Handle,
from_name: *const c_char,
to_name: *const c_char,
) -> Handle {
clear_error();
if from_name.is_null() || to_name.is_null() {
set_error(1, "cpdf_copyBox: null name");
return 0;
}
let from = unsafe { CStr::from_ptr(from_name) }.to_string_lossy();
let to = unsafe { CStr::from_ptr(to_name) }.to_string_lossy();
let d = get_doc_clone!(doc);
let r = get_range!(range);
ok_or_error!(pages::copy_box(d, &r, &from, &to))
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn cpdf_hardBox(
doc: Handle,
range: Handle,
box_name: *const c_char,
) -> Handle {
clear_error();
if box_name.is_null() {
set_error(1, "cpdf_hardBox: null name");
return 0;
}
let name = unsafe { CStr::from_ptr(box_name) }.to_string_lossy();
let d = get_doc_clone!(doc);
let r = get_range!(range);
ok_or_error!(pages::hard_box(d, &r, &name))
}
#[unsafe(no_mangle)]
pub extern "C" fn cpdf_chop(
doc: Handle,
range: Handle,
x_pieces: c_int,
y_pieces: c_int,
columns: c_int,
btt: c_int,
rtl: c_int,
) -> Handle {
clear_error();
let d = get_doc_clone!(doc);
let r = get_range!(range);
ok_or_error!(pages::chop(
d,
&r,
x_pieces as usize,
y_pieces as usize,
columns != 0,
btt != 0,
rtl != 0,
))
}
#[unsafe(no_mangle)]
pub extern "C" fn cpdf_chopHV(doc: Handle, range: Handle, is_h: c_int, line: f64) -> Handle {
clear_error();
let d = get_doc_clone!(doc);
let r = get_range!(range);
ok_or_error!(pages::chop_hv(d, &r, is_h != 0, line))
}
#[unsafe(no_mangle)]
pub extern "C" fn cpdf_twoUp(doc: Handle) -> Handle {
clear_error();
let d = get_doc_clone!(doc);
ok_or_error!(pages::twoup(d))
}
#[unsafe(no_mangle)]
pub extern "C" fn cpdf_twoUpStack(doc: Handle) -> Handle {
clear_error();
let d = get_doc_clone!(doc);
ok_or_error!(pages::twoup_stack(d))
}