#[cfg(feature = "embedded_images")]
use image_crate;
use lopdf::content::Operation;
use crate::glob_defines::{
OP_COLOR_SET_FILL_CS_DEVICECMYK, OP_COLOR_SET_FILL_CS_DEVICEGRAY,
OP_COLOR_SET_FILL_CS_DEVICERGB, OP_COLOR_SET_STROKE_CS_DEVICECMYK,
OP_COLOR_SET_STROKE_CS_DEVICEGRAY, OP_COLOR_SET_STROKE_CS_DEVICERGB,
};
use crate::IccProfileRef;
#[derive(Debug, Clone, PartialEq)]
pub enum PdfColor {
FillColor(Color),
OutlineColor(Color),
}
impl From<PdfColor> for Operation {
fn from(val: PdfColor) -> Self {
use lopdf::Object::*;
let (color_identifier, color_vec) = {
use self::PdfColor::*;
match val {
FillColor(fill) => {
let ci = match fill {
Color::Rgb(_) => OP_COLOR_SET_FILL_CS_DEVICERGB,
Color::Cmyk(_) | Color::SpotColor(_) => OP_COLOR_SET_FILL_CS_DEVICECMYK,
Color::Greyscale(_) => OP_COLOR_SET_FILL_CS_DEVICEGRAY,
};
let cvec = fill.into_vec().into_iter().map(Real).collect();
(ci, cvec)
}
OutlineColor(outline) => {
let ci = match outline {
Color::Rgb(_) => OP_COLOR_SET_STROKE_CS_DEVICERGB,
Color::Cmyk(_) | Color::SpotColor(_) => OP_COLOR_SET_STROKE_CS_DEVICECMYK,
Color::Greyscale(_) => OP_COLOR_SET_STROKE_CS_DEVICEGRAY,
};
let cvec = outline.into_vec().into_iter().map(Real).collect();
(ci, cvec)
}
}
};
Operation::new(color_identifier, color_vec)
}
}
#[derive(Debug, Copy, Clone)]
pub enum ColorSpace {
Rgb,
Rgba,
Palette,
Cmyk,
Greyscale,
GreyscaleAlpha,
}
#[cfg(feature = "embedded_images")]
impl From<image_crate::ColorType> for ColorSpace {
fn from(color_type: image_crate::ColorType) -> Self {
use image_crate::ColorType::*;
match color_type {
L8 | L16 => ColorSpace::Greyscale,
La8 | La16 => ColorSpace::GreyscaleAlpha,
Rgb8 | Rgb16 => ColorSpace::Rgb,
Rgba8 | Rgba16 => ColorSpace::Rgba,
_ => ColorSpace::Greyscale, }
}
}
impl From<ColorSpace> for &'static str {
fn from(val: ColorSpace) -> Self {
use self::ColorSpace::*;
match val {
Rgb => "DeviceRGB",
Cmyk => "DeviceCMYK",
Greyscale => "DeviceGray",
Palette => "Indexed",
Rgba | GreyscaleAlpha => "DeviceN",
}
}
}
#[derive(Debug, Copy, Clone)]
pub enum ColorBits {
Bit1,
Bit8,
Bit16,
}
#[cfg(feature = "embedded_images")]
impl From<image_crate::ColorType> for ColorBits {
fn from(color_type: image_crate::ColorType) -> ColorBits {
use image_crate::ColorType::*;
use ColorBits::*;
match color_type {
L8 | La8 | Rgb8 | Rgba8 => Bit8,
L16 | La16 | Rgb16 | Rgba16 => Bit16,
_ => Bit8, }
}
}
impl From<ColorBits> for i64 {
fn from(val: ColorBits) -> Self {
match val {
ColorBits::Bit1 => 1,
ColorBits::Bit8 => 8,
ColorBits::Bit16 => 16,
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum Color {
Rgb(Rgb),
Cmyk(Cmyk),
Greyscale(Greyscale),
SpotColor(SpotColor),
}
impl Color {
pub fn into_vec(self) -> Vec<f32> {
match self {
Color::Rgb(rgb) => {
vec![rgb.r, rgb.g, rgb.b]
}
Color::Cmyk(cmyk) => {
vec![cmyk.c, cmyk.m, cmyk.y, cmyk.k]
}
Color::Greyscale(gs) => {
vec![gs.percent]
}
Color::SpotColor(spot) => {
vec![spot.c, spot.m, spot.y, spot.k]
}
}
}
pub fn get_icc_profile(&self) -> Option<&Option<IccProfileRef>> {
match *self {
Color::Rgb(ref rgb) => Some(&rgb.icc_profile),
Color::Cmyk(ref cmyk) => Some(&cmyk.icc_profile),
Color::Greyscale(ref gs) => Some(&gs.icc_profile),
Color::SpotColor(_) => None,
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct Rgb {
pub r: f32,
pub g: f32,
pub b: f32,
pub icc_profile: Option<IccProfileRef>,
}
impl Rgb {
pub fn new(r: f32, g: f32, b: f32, icc_profile: Option<IccProfileRef>) -> Self {
Self {
r,
g,
b,
icc_profile,
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct Cmyk {
pub c: f32,
pub m: f32,
pub y: f32,
pub k: f32,
pub icc_profile: Option<IccProfileRef>,
}
impl Cmyk {
pub fn new(c: f32, m: f32, y: f32, k: f32, icc_profile: Option<IccProfileRef>) -> Self {
Self {
c,
m,
y,
k,
icc_profile,
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct Greyscale {
pub percent: f32,
pub icc_profile: Option<IccProfileRef>,
}
impl Greyscale {
pub fn new(percent: f32, icc_profile: Option<IccProfileRef>) -> Self {
Self {
percent,
icc_profile,
}
}
}
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct SpotColor {
pub c: f32,
pub m: f32,
pub y: f32,
pub k: f32,
}
impl SpotColor {
pub fn new(c: f32, m: f32, y: f32, k: f32) -> Self {
Self { c, m, y, k }
}
}