#[allow(non_camel_case_types)]
#[derive(Debug, Clone)]
pub struct CT_CGTransform {
pub code_position: Option<u32>,
pub code_count: Option<u32>,
pub glyph_count: Option<u32>,
pub glyphs: Vec<u32>,
}
impl CT_CGTransform {
#[must_use]
pub fn new() -> Self {
Self {
code_position: None,
code_count: None,
glyph_count: None,
glyphs: Vec::new(),
}
}
#[must_use]
pub fn code_position(mut self, pos: u32) -> Self {
self.code_position = Some(pos);
self
}
#[must_use]
pub fn code_count(mut self, count: u32) -> Self {
self.code_count = Some(count);
self
}
#[must_use]
pub fn glyph_count(mut self, count: u32) -> Self {
self.glyph_count = Some(count);
self
}
#[must_use]
pub fn glyphs(mut self, glyphs: Vec<u32>) -> Self {
self.glyphs = glyphs;
self
}
pub fn add_glyph(&mut self, glyph: u32) {
self.glyphs.push(glyph);
}
#[must_use]
pub fn get_code_position(&self) -> Option<u32> {
self.code_position
}
#[must_use]
pub fn get_code_count(&self) -> Option<u32> {
self.code_count
}
#[must_use]
pub fn get_glyph_count(&self) -> Option<u32> {
self.glyph_count
}
#[must_use]
pub fn get_glyphs(&self) -> &[u32] {
&self.glyphs
}
#[must_use]
pub fn to_xml_string(&self) -> String {
use std::fmt::Write;
let mut xml = String::from("<ofd:CGTransform");
if let Some(cp) = self.code_position {
write!(xml, " CodePosition=\"{cp}\"").expect("写入内存缓冲区不会失败");
}
if let Some(cc) = self.code_count {
write!(xml, " CodeCount=\"{cc}\"").expect("写入内存缓冲区不会失败");
}
if let Some(gc) = self.glyph_count {
write!(xml, " GlyphCount=\"{gc}\"").expect("写入内存缓冲区不会失败");
}
if !self.glyphs.is_empty() {
xml.push_str(" Glyphs=\"");
for (i, g) in self.glyphs.iter().enumerate() {
if i > 0 {
xml.push(' ');
}
write!(xml, "{g}").expect("写入内存缓冲区不会失败");
}
xml.push('"');
}
xml.push_str(" />");
xml
}
}
impl Default for CT_CGTransform {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_ct_cg_transform_new() {
let t = CT_CGTransform::new();
assert!(t.code_position.is_none());
assert!(t.code_count.is_none());
assert!(t.glyph_count.is_none());
assert!(t.glyphs.is_empty());
}
#[test]
fn test_ct_cg_transform_builder() {
let t = CT_CGTransform::new()
.code_position(0)
.code_count(2)
.glyph_count(2)
.glyphs(vec![100, 200]);
assert_eq!(t.get_code_position(), Some(0));
assert_eq!(t.get_code_count(), Some(2));
assert_eq!(t.get_glyph_count(), Some(2));
assert_eq!(t.get_glyphs(), &[100, 200]);
}
#[test]
fn test_ct_cg_transform_add_glyph() {
let mut t = CT_CGTransform::new();
t.add_glyph(50);
t.add_glyph(60);
t.add_glyph(70);
assert_eq!(t.get_glyphs().len(), 3);
}
#[test]
fn test_ct_cg_transform_to_xml_minimal() {
let t = CT_CGTransform::new();
let xml = t.to_xml_string();
assert!(xml.contains("<ofd:CGTransform"));
assert!(xml.ends_with(" />"));
}
#[test]
fn test_ct_cg_transform_to_xml_full() {
let t = CT_CGTransform::new()
.code_position(3)
.code_count(1)
.glyph_count(2)
.glyphs(vec![101, 202]);
let xml = t.to_xml_string();
assert!(xml.contains("CodePosition=\"3\""));
assert!(xml.contains("CodeCount=\"1\""));
assert!(xml.contains("GlyphCount=\"2\""));
assert!(xml.contains("Glyphs=\"101 202\""));
}
#[test]
fn test_ct_cg_transform_clone_debug() {
let t = CT_CGTransform::new().code_position(1);
let t2 = t.clone();
assert_eq!(t2.get_code_position(), Some(1));
assert!(format!("{t:?}").contains("CT_CGTransform"));
}
}