use std::collections::HashMap;
#[derive(Debug, Clone, Default)]
pub struct XForm {
pub pin_x: f64,
pub pin_y: f64,
pub width: f64,
pub height: f64,
pub loc_pin_x: f64,
pub loc_pin_y: f64,
pub angle: f64,
pub flip_x: bool,
pub flip_y: bool,
}
#[derive(Debug, Clone, Default)]
pub struct TextXForm {
pub txt_pin_x: f64,
pub txt_pin_y: f64,
pub txt_width: f64,
pub txt_height: f64,
pub txt_loc_pin_x: f64,
pub txt_loc_pin_y: f64,
pub txt_angle: f64,
}
#[derive(Debug, Clone, Default)]
pub struct XForm1D {
pub begin_x: f64,
pub begin_y: f64,
pub end_x: f64,
pub end_y: f64,
}
#[derive(Debug, Clone, Default)]
pub struct CellValue {
pub v: String,
pub f: String,
}
impl CellValue {
pub fn new(v: impl Into<String>, f: impl Into<String>) -> Self {
Self { v: v.into(), f: f.into() }
}
pub fn val(v: impl Into<String>) -> Self {
Self { v: v.into(), f: String::new() }
}
pub fn as_f64(&self) -> f64 {
self.v.parse().unwrap_or(0.0)
}
pub fn as_f64_or(&self, default: f64) -> f64 {
self.v.parse().unwrap_or(default)
}
pub fn is_empty(&self) -> bool {
self.v.is_empty() && self.f.is_empty()
}
}
#[derive(Debug, Clone)]
pub struct GeomRow {
pub row_type: String,
pub ix: String,
pub cells: HashMap<String, CellValue>,
}
impl GeomRow {
pub fn new(row_type: &str) -> Self {
Self {
row_type: row_type.to_string(),
ix: String::new(),
cells: HashMap::new(),
}
}
pub fn cell_f64(&self, name: &str) -> f64 {
self.cells.get(name).map(|c| c.as_f64()).unwrap_or(0.0)
}
}
#[derive(Debug, Clone, Default)]
pub struct GeomSection {
pub no_fill: bool,
pub no_line: bool,
pub no_show: bool,
pub ix: String,
pub rows: Vec<GeomRow>,
}
#[derive(Debug, Clone)]
pub struct CharFormat {
pub size: String,
pub color: String,
pub style: String,
pub font: String,
}
impl Default for CharFormat {
fn default() -> Self {
Self {
size: "0.1111".to_string(),
color: String::new(),
style: "0".to_string(),
font: String::new(),
}
}
}
#[derive(Debug, Clone, Default)]
pub struct ParaFormat {
pub horiz_align: String,
pub indent_first: String,
pub indent_left: String,
pub indent_right: String,
pub bullet: String,
pub bullet_str: String,
pub sp_line: String,
pub sp_before: String,
pub sp_after: String,
}
#[derive(Debug, Clone)]
pub struct TextPart {
pub text: String,
pub cp: String,
pub pp: String,
}
#[derive(Debug, Clone, Default)]
pub struct ForeignDataInfo {
pub foreign_type: String,
pub compression: String,
pub data: Option<String>,
pub rel_id: Option<String>,
}
#[derive(Debug, Clone, Default)]
pub struct Hyperlink {
pub description: String,
pub address: String,
pub sub_address: String,
pub frame: String,
}
#[derive(Debug, Clone)]
pub struct GradientStop {
pub position: f64,
pub color: String,
}
#[derive(Debug, Clone)]
pub struct GradientDef {
pub id: String,
pub start: String,
pub end: String,
pub mid: Option<String>,
pub dir: f64,
pub radial: bool,
pub stops: Vec<GradientStop>,
pub cx: f64,
pub cy: f64,
pub fx: f64,
pub fy: f64,
pub r: f64,
}
impl Default for GradientDef {
fn default() -> Self {
Self {
id: String::new(),
start: "#FFFFFF".to_string(),
end: "#000000".to_string(),
mid: None,
dir: 0.0,
radial: false,
stops: Vec::new(),
cx: 50.0, cy: 50.0,
fx: 50.0, fy: 50.0,
r: 50.0,
}
}
}
#[derive(Debug, Clone)]
pub struct FillPatternDef {
pub id: String,
pub fg: String,
pub bg: String,
pub pattern_type: i32,
}
#[derive(Debug, Clone)]
pub struct Shape {
pub id: String,
pub name: String,
pub name_u: String,
pub shape_type: String,
pub master: String,
pub master_shape: String,
pub cells: HashMap<String, CellValue>,
pub geometry: Vec<GeomSection>,
pub text: String,
pub text_parts: Vec<TextPart>,
pub char_formats: HashMap<String, CharFormat>,
pub para_formats: HashMap<String, ParaFormat>,
pub sub_shapes: Vec<Shape>,
pub controls: HashMap<String, HashMap<String, String>>,
pub connections: HashMap<String, HashMap<String, CellValue>>,
pub user: HashMap<String, HashMap<String, String>>,
pub foreign_data: Option<ForeignDataInfo>,
pub hyperlinks: Vec<Hyperlink>,
pub line_style: String,
pub fill_style: String,
pub text_style: String,
pub gradient_stops: Vec<Vec<GradientStop>>,
pub has_text_elem: bool,
pub master_w: f64,
pub master_h: f64,
pub has_own_geometry: bool,
pub theme_text_color: Option<String>,
}
impl Default for Shape {
fn default() -> Self {
Self {
id: String::new(),
name: String::new(),
name_u: String::new(),
shape_type: "Shape".to_string(),
master: String::new(),
master_shape: String::new(),
cells: HashMap::new(),
geometry: Vec::new(),
text: String::new(),
text_parts: Vec::new(),
char_formats: HashMap::new(),
para_formats: HashMap::new(),
sub_shapes: Vec::new(),
controls: HashMap::new(),
connections: HashMap::new(),
user: HashMap::new(),
foreign_data: None,
hyperlinks: Vec::new(),
line_style: String::new(),
fill_style: String::new(),
text_style: String::new(),
gradient_stops: Vec::new(),
has_text_elem: false,
master_w: 0.0,
master_h: 0.0,
has_own_geometry: false,
theme_text_color: None,
}
}
}
impl Shape {
pub fn cell_val(&self, name: &str) -> &str {
self.cells.get(name).map(|c| c.v.as_str()).unwrap_or("")
}
pub fn cell_f64(&self, name: &str) -> f64 {
self.cells.get(name).map(|c| c.as_f64()).unwrap_or(0.0)
}
pub fn cell_f64_or(&self, name: &str, default: f64) -> f64 {
self.cells.get(name).map(|c| c.as_f64_or(default)).unwrap_or(default)
}
}
#[derive(Debug, Clone)]
pub struct Connect {
pub from_sheet: String,
pub from_cell: String,
pub to_sheet: String,
pub to_cell: String,
}
#[derive(Debug, Clone)]
pub struct LayerDef {
pub name: String,
pub visible: bool,
}
#[derive(Debug, Clone)]
pub struct Page {
pub name: String,
pub index: usize,
pub width: f64,
pub height: f64,
pub shapes: Vec<Shape>,
pub connects: Vec<Connect>,
pub layers: HashMap<String, LayerDef>,
pub background: bool,
}
impl Default for Page {
fn default() -> Self {
Self {
name: String::new(),
index: 0,
width: 8.5,
height: 11.0,
shapes: Vec::new(),
connects: Vec::new(),
layers: HashMap::new(),
background: false,
}
}
}
#[derive(Debug, Clone, Default)]
pub struct StyleSheet {
pub cells: HashMap<String, CellValue>,
pub line_style: String,
pub fill_style: String,
pub text_style: String,
}
#[derive(Debug, Clone, Default)]
pub struct Document {
pub pages: Vec<Page>,
pub masters: HashMap<String, HashMap<String, Shape>>,
pub theme_colors: HashMap<String, String>,
pub media: HashMap<String, Vec<u8>>,
pub stylesheets: HashMap<String, StyleSheet>,
pub background_map: HashMap<usize, usize>,
}
#[derive(Debug, Clone)]
pub struct PageInfo {
pub name: String,
pub index: usize,
pub width: f64,
pub height: f64,
}