diff --git a/src/qelmt/dynamictext.rs b/src/qelmt/dynamictext.rs index c186e6f..2b1b70b 100644 --- a/src/qelmt/dynamictext.rs +++ b/src/qelmt/dynamictext.rs @@ -30,6 +30,7 @@ pub struct DynamicText { frame: bool, text_height: f64, text_width: f64, + pub relative_x_scale_factor: f64, keep_visual_rotation: bool, color: HexColor, reference_rectangle_width: f64, @@ -59,6 +60,7 @@ impl From<&DynamicText> for XMLElement { println!("文本:{}", txt.text); println!("对齐方式:{}, {}", txt.h_alignment, txt.v_alignment); println!("文本宽度: {}", txt.text_width); + println!("relative_x_scale_factor: {}", txt.relative_x_scale_factor); println!("文本高度:{}", pt_size); println!("初始左下角位置: x={}, y={}", txt.x, txt.y); println!("初始对齐位置: x={}, y={}", txt.align_x, txt.align_y); @@ -132,6 +134,7 @@ impl From<&DynamicText> for XMLElement { dtxt_xml.add_attribute("frame", txt.frame); dtxt_xml.add_attribute("text_height", txt.text_height); dtxt_xml.add_attribute("text_width", txt.text_width); + dtxt_xml.add_attribute("relative_x_scale_factor", two_dec(txt.relative_x_scale_factor)); dtxt_xml.add_attribute("color", txt.color.display_rgb()); dtxt_xml.add_attribute("align_x", two_dec(align_x)); dtxt_xml.add_attribute("align_y", two_dec(align_y)); @@ -239,7 +242,7 @@ impl<'a> DTextBuilder<'a> { reference_rectangle_width, align_x, align_y, - + relative_x_scale_factor, ) = match self.text { TextEntity::Text(txt) => { // let (x, y) = if txt.horizontal_text_justification == HorizontalTextJustification::Left && (txt.vertical_text_justification == VerticalTextJustification::Bottom || txt.vertical_text_justification == VerticalTextJustification::Baseline) { @@ -259,7 +262,8 @@ impl<'a> DTextBuilder<'a> { VAlignment::from_text_entity(txt.vertical_text_justification, false), 0.0, // as Placeholder: no "reference_rectangle_width" with Text!!! txt.second_alignment_point.x, - -txt.second_alignment_point.y + -txt.second_alignment_point.y, + txt.width_factor, )}, TextEntity::MText(mtxt) => { // 计算实际的旋转角度,优先使用x_axis_direction向量 @@ -300,6 +304,7 @@ impl<'a> DTextBuilder<'a> { mtxt.reference_rectangle_width, mtxt.insertion_point.x, -mtxt.insertion_point.y, + 1.0, )}, TextEntity::Attrib(attrib) => { // 根据DXF文本对齐规则,当水平对齐不是Left时,使用second_alignment_point @@ -322,7 +327,8 @@ impl<'a> DTextBuilder<'a> { VAlignment::from_text_entity(attrib.vertical_text_justification, true), 0.0, // as Placeholder: not need to check if Attrib has something similar attrib.second_alignment_point.x, - -attrib.second_alignment_point.y + -attrib.second_alignment_point.y, + attrib.width_factor, ) }, }; @@ -358,8 +364,14 @@ impl<'a> DTextBuilder<'a> { dbg!(&y); dbg!(&self.text);*/ let value = super::strip_mtext_control_sequences(&value); - // 将 DXF 中读取到的 text_height 放大 2 倍(用户要求) + // 将 DXF 中读取到的 text_height 放大 2 倍(用户要求) let text_height = text_height * 2.0; + let text_width = if reference_rectangle_width > 0.0 { + reference_rectangle_width + } else { + estimate_text_width(&value, text_height, relative_x_scale_factor) + }; + DynamicText { //x: x - (calc_width as f64/2.0), x, @@ -387,7 +399,8 @@ impl<'a> DTextBuilder<'a> { text_from: "UserText".into(), frame: false, text_height, - text_width: -1.0, // for now, until I figure out what this should be + text_width, + relative_x_scale_factor, color: self.color.unwrap_or(HexColor::BLACK), text: value, @@ -482,3 +495,29 @@ pub fn adjust_mtext_coordinates( (adjusted_x, adjusted_y) } + +fn estimate_text_width(text: &str, line_height: f64, relative_x_scale_factor: f64) -> f64 { + let effective_height = line_height.abs(); + if effective_height == 0.0 { + return 0.0; + } + + let base_width = text + .lines() + .map(|line| line.graphemes(true).count() as f64) + .fold(0.0, f64::max); + + let base_width = if base_width > 0.0 { + base_width * effective_height * 0.75 + } else { + effective_height + }; + + let scale = if relative_x_scale_factor.abs() <= f64::EPSILON { + 1.0 + } else { + relative_x_scale_factor + }; + + base_width * scale +}