You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
95 lines
2.8 KiB
Rust
95 lines
2.8 KiB
Rust
//! 旧式 QET `<text>` 图元转换。
|
|
//!
|
|
//! 当前主流程主要使用 [`super::DynamicText`];该类型保留给仍需要静态文本
|
|
//! XML 的路径。它只掌握锚点而没有可靠字形测量,因此右/下边界尚未实现。
|
|
|
|
use super::{two_dec, FontInfo, ScaleEntity};
|
|
use dxf::entities;
|
|
use hex_color::HexColor;
|
|
use simple_xml_builder::XMLElement;
|
|
|
|
#[derive(Debug)]
|
|
/// QET 静态文本的内容、字体、颜色、位置和旋转。
|
|
pub struct Text {
|
|
rotation: f64,
|
|
value: String,
|
|
pub x: f64,
|
|
pub y: f64,
|
|
font: FontInfo,
|
|
color: HexColor,
|
|
}
|
|
|
|
impl From<(&entities::Text, HexColor)> for Text {
|
|
fn from((txt, color): (&entities::Text, HexColor)) -> Self {
|
|
// STANDARD 是 DXF 默认样式,无需在 QET 字体串中重复写出。
|
|
let mut font = FontInfo::default();
|
|
font.apply_height(txt.text_height);
|
|
if !txt.text_style_name.is_empty() && txt.text_style_name != "STANDARD" {
|
|
font.style_name = Some(txt.text_style_name.clone());
|
|
}
|
|
|
|
Text {
|
|
x: txt.location.x,
|
|
y: -txt.location.y,
|
|
rotation: if txt.rotation.abs().round() as i64 % 360 != 0 {
|
|
txt.rotation - 180.0
|
|
} else {
|
|
0.0
|
|
},
|
|
color,
|
|
font,
|
|
value: txt.value.clone(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<&Text> for XMLElement {
|
|
fn from(txt: &Text) -> Self {
|
|
// QET 静态文本把内容保存在 `text` 属性,而不是子节点中。
|
|
let mut txt_xml: XMLElement = XMLElement::new("text");
|
|
txt_xml.add_attribute("x", two_dec(txt.x));
|
|
txt_xml.add_attribute("y", two_dec(txt.y));
|
|
txt_xml.add_attribute("rotation", two_dec(txt.rotation));
|
|
txt_xml.add_attribute("color", txt.color.display_rgb());
|
|
txt_xml.add_attribute("font", &txt.font);
|
|
txt_xml.add_attribute("text", &txt.value);
|
|
txt_xml
|
|
}
|
|
}
|
|
|
|
impl Text {
|
|
/// 围绕块插入支点旋转文本锚点,并叠加文本自身旋转角。
|
|
pub(crate) fn rotate_around(&mut self, pivot_x: f64, pivot_y: f64, angle_deg: f64) {
|
|
let (x, y) = super::rotate_point_around(self.x, self.y, pivot_x, pivot_y, angle_deg);
|
|
self.x = x;
|
|
self.y = y;
|
|
self.rotation = super::normalize_angle(self.rotation + angle_deg);
|
|
}
|
|
}
|
|
|
|
impl ScaleEntity for Text {
|
|
fn scale(&mut self, fact_x: f64, fact_y: f64) {
|
|
self.x *= fact_x;
|
|
self.y *= fact_y;
|
|
self.font.scale(fact_y);
|
|
}
|
|
|
|
fn left_bound(&self) -> f64 {
|
|
self.x
|
|
}
|
|
|
|
fn top_bound(&self) -> f64 {
|
|
self.y
|
|
}
|
|
|
|
fn right_bound(&self) -> f64 {
|
|
// 静态 Text 没有字形布局结果,不能可靠计算右边界。
|
|
todo!()
|
|
}
|
|
|
|
fn bot_bound(&self) -> f64 {
|
|
// 静态 Text 没有字形布局结果,不能可靠计算下边界。
|
|
todo!()
|
|
}
|
|
}
|