pub mod blip_fill;
pub mod fill_rectangle;
pub mod gradient_fill;
pub mod pattern_fill;
pub mod preset_pattern_values;
pub mod tile;
pub mod tile_flip;
#[cfg(feature = "serde")]
use serde::Serialize;
use std::collections::BTreeMap;
use crate::{
common_types::HexColor,
packaging::relationship::XlsxRelationships,
raw::drawing::{
fill::XlsxFillStyleEnum,
line::outline::XlsxOutline,
scheme::color_scheme::XlsxColorScheme,
shape::{
shape_properties::XlsxShapeProperties,
visual_group_shape_properties::XlsxVisualGroupShapeProperties,
},
text::default_text_run_properties::XlsxTextRunProperties,
},
};
use super::text::text_run_properties::TextRunProperties;
use blip_fill::BlipFill;
use gradient_fill::GradientFill;
use pattern_fill::PatternFill;
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
pub enum Fill {
SolidFill(HexColor),
GradientFill(GradientFill),
NoFill,
PatternFill(PatternFill),
BlipFill(BlipFill),
}
impl Fill {
pub(crate) fn from_raw(
raw: Option<XlsxFillStyleEnum>,
parent_group_fill: Option<Self>,
drawing_relationship: XlsxRelationships,
image_bytes: BTreeMap<String, Vec<u8>>,
color_scheme: Option<XlsxColorScheme>,
ref_color: Option<HexColor>,
) -> Option<Self> {
let Some(raw) = raw else { return None };
Some(match raw {
XlsxFillStyleEnum::SolidFill(fill) => {
if let Some(hex) = fill.to_hex(color_scheme.clone(), ref_color.clone()) {
Self::SolidFill(hex)
} else {
return None;
}
}
XlsxFillStyleEnum::GradientFill(fill) => {
if let Some(gradient) =
GradientFill::from_raw(Some(fill), color_scheme.clone(), ref_color.clone())
{
Self::GradientFill(gradient)
} else {
Self::NoFill
}
}
XlsxFillStyleEnum::GroupFill(_) => parent_group_fill.unwrap_or(Self::NoFill),
XlsxFillStyleEnum::NoFill(_) => Self::NoFill,
XlsxFillStyleEnum::PatternFill(fill) => {
if let Some(pattern) =
PatternFill::from_raw(Some(fill), color_scheme.clone(), ref_color.clone())
{
Self::PatternFill(pattern)
} else {
Self::NoFill
}
}
XlsxFillStyleEnum::BlipFill(fill) => {
if let Some(blip) = BlipFill::from_raw(
Some(fill),
drawing_relationship,
image_bytes,
color_scheme.clone(),
ref_color.clone(),
) {
Self::BlipFill(blip)
} else {
Self::NoFill
}
}
})
}
pub(crate) fn from_shape_properties(
raw: XlsxShapeProperties,
parent_group_fill: Option<Self>,
drawing_relationship: XlsxRelationships,
image_bytes: BTreeMap<String, Vec<u8>>,
color_scheme: Option<XlsxColorScheme>,
) -> Option<Self> {
if let Some(fill) = raw.solid_fill {
if let Some(hex) = fill.to_hex(color_scheme.clone(), None) {
return Some(Self::SolidFill(hex));
} else {
return None;
}
}
if let Some(fill) = raw.gradient_fill {
if let Some(gradient) = GradientFill::from_raw(Some(fill), color_scheme.clone(), None) {
return Some(Self::GradientFill(gradient));
}
}
if let Some(_) = raw.group_fill {
return parent_group_fill;
}
if let Some(_) = raw.no_fill {
return Some(Self::NoFill);
}
if let Some(fill) = raw.pattern_fill {
if let Some(pattern) = PatternFill::from_raw(Some(fill), color_scheme.clone(), None) {
return Some(Self::PatternFill(pattern));
}
}
if let Some(fill) = raw.blip_fill {
if let Some(blip) = BlipFill::from_raw(
Some(fill),
drawing_relationship.clone(),
image_bytes.clone(),
color_scheme.clone(),
None,
) {
return Some(Self::BlipFill(blip));
}
}
return None;
}
pub(crate) fn from_group_shape_properties(
raw: XlsxVisualGroupShapeProperties,
drawing_relationship: XlsxRelationships,
image_bytes: BTreeMap<String, Vec<u8>>,
color_scheme: Option<XlsxColorScheme>,
) -> Option<Self> {
if let Some(fill) = raw.solid_fill {
if let Some(hex) = fill.to_hex(color_scheme.clone(), None) {
return Some(Self::SolidFill(hex));
} else {
return None;
}
}
if let Some(fill) = raw.gradient_fill {
if let Some(gradient) = GradientFill::from_raw(Some(fill), color_scheme.clone(), None) {
return Some(Self::GradientFill(gradient));
}
}
if let Some(_) = raw.no_fill {
return Some(Self::NoFill);
}
if let Some(fill) = raw.pattern_fill {
if let Some(pattern) = PatternFill::from_raw(Some(fill), color_scheme.clone(), None) {
return Some(Self::PatternFill(pattern));
}
}
if let Some(fill) = raw.blip_fill {
if let Some(blip) = BlipFill::from_raw(
Some(fill),
drawing_relationship,
image_bytes,
color_scheme.clone(),
None,
) {
return Some(Self::BlipFill(blip));
}
}
return None;
}
pub(crate) fn from_outline(
raw: XlsxOutline,
color_scheme: Option<XlsxColorScheme>,
ref_color: Option<HexColor>,
) -> Self {
let default = Self::SolidFill("020b0fff".to_string());
if let Some(fill) = raw.solid_fill {
if let Some(hex) = fill.to_hex(color_scheme.clone(), ref_color.clone()) {
return Self::SolidFill(hex);
} else {
return default;
}
}
if let Some(fill) = raw.gradient_fill {
if let Some(gradient) =
GradientFill::from_raw(Some(fill), color_scheme.clone(), ref_color.clone())
{
return Self::GradientFill(gradient);
}
}
if let Some(_) = raw.no_fill {
return Self::NoFill;
}
if let Some(fill) = raw.pattern_fill {
if let Some(pattern) = PatternFill::from_raw(Some(fill), color_scheme.clone(), None) {
return Self::PatternFill(pattern);
}
}
return default;
}
pub(crate) fn from_text_run_properties(
raw: XlsxTextRunProperties,
default_properties: Option<TextRunProperties>,
drawing_relationship: XlsxRelationships,
image_bytes: BTreeMap<String, Vec<u8>>,
color_scheme: Option<XlsxColorScheme>,
ref_color: Option<HexColor>,
) -> Self {
let default = Self::SolidFill(ref_color.clone().unwrap_or("000000ff".to_string()));
if let Some(fill) = raw.blip_fill {
if let Some(blip) = BlipFill::from_raw(
Some(fill),
drawing_relationship.clone(),
image_bytes.clone(),
color_scheme.clone(),
ref_color.clone(),
) {
return Self::BlipFill(blip);
}
}
if let Some(fill) = raw.gradient_fill {
if let Some(gradient) =
GradientFill::from_raw(Some(fill), color_scheme.clone(), ref_color.clone())
{
return Self::GradientFill(gradient);
}
}
if let Some(_) = raw.no_fill {
return Self::NoFill;
}
if let Some(fill) = raw.pattern_fill {
if let Some(pattern) = PatternFill::from_raw(Some(fill), color_scheme.clone(), None) {
return Self::PatternFill(pattern);
}
}
if let Some(fill) = raw.solid_fill {
if let Some(hex) = fill.to_hex(color_scheme.clone(), ref_color.clone()) {
return Self::SolidFill(hex);
} else {
return default;
}
}
if let Some(default_properties) = default_properties {
return default_properties.fill;
}
return default;
}
}