use std::sync::{Arc, Mutex};
use crate::device::{
AxialShadingParams, ClipParams, FillParams, ImageParams, MeshShadingParams, PatchShadingParams,
PatternFillParams, RadialShadingParams, StrokeParams, TextParams,
};
use stet_fonts::geometry::PsPath;
#[derive(Clone, Debug)]
pub struct MaskRaster {
pub data: Vec<u8>,
pub width: u32,
pub height: u32,
pub origin_x: i32,
pub origin_y: i32,
pub scale_x: f32,
pub scale_y: f32,
}
#[derive(Clone, Debug, PartialEq)]
pub enum SoftMaskSubtype {
Alpha,
Luminosity,
}
#[derive(Clone)]
pub struct SoftMaskParams {
pub subtype: SoftMaskSubtype,
pub bbox: [f64; 4],
pub backdrop_color: Option<[f64; 3]>,
pub transfer_invert: bool,
pub has_nested_mask_scope: bool,
pub parent_clip_bbox: Option<[f64; 4]>,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum GroupColorSpace {
Inherited,
DeviceGray,
DeviceRGB,
DeviceCMYK,
}
#[derive(Clone)]
pub struct GroupParams {
pub bbox: [f64; 4],
pub isolated: bool,
pub knockout: bool,
pub blend_mode: u8,
pub alpha: f64,
pub color_space: GroupColorSpace,
}
#[derive(Clone)]
pub enum DisplayElement {
Fill { path: PsPath, params: FillParams },
Stroke { path: PsPath, params: StrokeParams },
Clip { path: PsPath, params: ClipParams },
InitClip,
Image {
sample_data: Arc<Vec<u8>>,
params: ImageParams,
},
ErasePage,
AxialShading { params: AxialShadingParams },
RadialShading { params: RadialShadingParams },
MeshShading { params: MeshShadingParams },
PatchShading { params: PatchShadingParams },
PatternFill { params: PatternFillParams },
Text { params: TextParams },
Group {
elements: DisplayList,
params: GroupParams,
},
OcgGroup {
elements: DisplayList,
ocg_id: u32,
default_visible: bool,
},
SoftMasked {
mask: DisplayList,
content: DisplayList,
params: SoftMaskParams,
mask_cache: Arc<Mutex<Option<Option<MaskRaster>>>>,
},
}
#[derive(Clone)]
pub struct DisplayList {
elements: Vec<DisplayElement>,
page_group_color_space: GroupColorSpace,
}
impl DisplayList {
pub fn new() -> Self {
Self {
elements: Vec::new(),
page_group_color_space: GroupColorSpace::Inherited,
}
}
pub fn page_group_color_space(&self) -> GroupColorSpace {
self.page_group_color_space
}
pub fn set_page_group_color_space(&mut self, cs: GroupColorSpace) {
self.page_group_color_space = cs;
}
pub fn push(&mut self, element: DisplayElement) {
self.elements.push(element);
}
pub fn elements(&self) -> &[DisplayElement] {
&self.elements
}
pub fn clear(&mut self) {
self.elements.clear();
}
pub fn is_empty(&self) -> bool {
self.elements.is_empty()
}
pub fn len(&self) -> usize {
self.elements.len()
}
pub fn elements_from(&self, start: usize) -> &[DisplayElement] {
&self.elements[start..]
}
pub fn split_off(&mut self, start: usize) -> DisplayList {
let drained: Vec<DisplayElement> = self.elements.drain(start..).collect();
DisplayList {
elements: drained,
page_group_color_space: GroupColorSpace::Inherited,
}
}
pub fn into_elements(self) -> Vec<DisplayElement> {
self.elements
}
}
impl Default for DisplayList {
fn default() -> Self {
Self::new()
}
}