diff --git a/src/qelmt/dynamictext.rs b/src/qelmt/dynamictext.rs index e1636d7..b6148f3 100644 --- a/src/qelmt/dynamictext.rs +++ b/src/qelmt/dynamictext.rs @@ -32,6 +32,8 @@ pub struct DynamicText { keep_visual_rotation: bool, color: HexColor, reference_rectangle_width: f64, + pub align_x: f64, + pub align_y: f64, } impl From<&DynamicText> for XMLElement { @@ -61,9 +63,9 @@ impl From<&DynamicText> for XMLElement { // o.k. ... as long as we do not know the real width: // "guess" the width by number of characters and font-size: // - // let graphene_count = txt.text.graphemes(true).count(); + let graphene_count = txt.text.graphemes(true).count(); let mut cjk_char_count = 0; - let mut graphene_count = 0; + // let mut graphene_count = 0; // for grapheme in txt.text.graphemes(true) { // graphene_count += 1; // if grapheme.chars().any(|c| { @@ -85,40 +87,40 @@ impl From<&DynamicText> for XMLElement { txt.reference_rectangle_width } else { // 不同的字母,宽度与高度的比例并不相同,0.75只是一个平均值 - // (graphene_count as f64) * pt_size * 0.75 + (graphene_count as f64) * pt_size * 0.75 // 根据字符类型计算宽度,考虑不同字符的宽高比例 - let mut total_width = 0.0; - for grapheme in txt.text.graphemes(true) { - let char_width = if grapheme.chars().any(|c| { - // 检查是否为中文字符(包括中日韩统一表意文字) - (c >= '\u{4E00}' && c <= '\u{9FFF}') || // CJK统一表意文字 - (c >= '\u{3400}' && c <= '\u{4DBF}') || // CJK扩展A - (c >= '\u{20000}' && c <= '\u{2A6DF}') || // CJK扩展B - (c >= '\u{2A700}' && c <= '\u{2B73F}') || // CJK扩展C - (c >= '\u{2B740}' && c <= '\u{2B81F}') || // CJK扩展D - (c >= '\u{2B820}' && c <= '\u{2CEAF}') || // CJK扩展E - (c >= '\u{F900}' && c <= '\u{FAFF}') || // CJK兼容表意文字 - (c >= '\u{2F800}' && c <= '\u{2FA1F}') // CJK兼容表意文字补充 - }) { - // 中文字符:宽高比 1:1 - cjk_char_count += 1; - pt_size * 1.5 - } else if grapheme.chars().any(|c| matches!(c, 'i' | 'l' | 'I' | ',' | ';' | ':' | '!')) { - pt_size * 0.3 - } else if grapheme.chars().any(|c| matches!(c, 'W' | 'M' | '@' )) { - pt_size * 1.0 - } else if grapheme.chars().any(|c| matches!(c, 'w' |'m' | '%' )) { - pt_size * 0.9 - }else if grapheme.chars().any(|c| matches!(c, 'f' |'j' | 't' | 'r' | 'J' | 'T' | 'F' | '/' | '\\' | 's' | 'z' )) { - // 其他标点符号:宽高比约 0.4:1 - pt_size * 0.5 - } else { - // 中等宽度字母(默认):宽高比约 0.6:1 - pt_size * 0.7 - }; - total_width += char_width; - } - total_width + // let mut total_width = 0.0; + // for grapheme in txt.text.graphemes(true) { + // let char_width = if grapheme.chars().any(|c| { + // // 检查是否为中文字符(包括中日韩统一表意文字) + // (c >= '\u{4E00}' && c <= '\u{9FFF}') || // CJK统一表意文字 + // (c >= '\u{3400}' && c <= '\u{4DBF}') || // CJK扩展A + // (c >= '\u{20000}' && c <= '\u{2A6DF}') || // CJK扩展B + // (c >= '\u{2A700}' && c <= '\u{2B73F}') || // CJK扩展C + // (c >= '\u{2B740}' && c <= '\u{2B81F}') || // CJK扩展D + // (c >= '\u{2B820}' && c <= '\u{2CEAF}') || // CJK扩展E + // (c >= '\u{F900}' && c <= '\u{FAFF}') || // CJK兼容表意文字 + // (c >= '\u{2F800}' && c <= '\u{2FA1F}') // CJK兼容表意文字补充 + // }) { + // // 中文字符:宽高比 1:1 + // cjk_char_count += 1; + // pt_size * 1.5 + // } else if grapheme.chars().any(|c| matches!(c, 'i' | 'l' | 'I' | ',' | ';' | ':' | '!')) { + // pt_size * 0.3 + // } else if grapheme.chars().any(|c| matches!(c, 'W' | 'M' | '@' )) { + // pt_size * 1.0 + // } else if grapheme.chars().any(|c| matches!(c, 'w' |'m' | '%' )) { + // pt_size * 0.9 + // }else if grapheme.chars().any(|c| matches!(c, 'f' |'j' | 't' | 'r' | 'J' | 'T' | 'F' | '/' | '\\' | 's' | 'z' )) { + // // 其他标点符号:宽高比约 0.4:1 + // pt_size * 0.5 + // } else { + // // 中等宽度字母(默认):宽高比约 0.6:1 + // pt_size * 0.7 + // }; + // total_width += char_width; + // } + // total_width }; // let x_pos = { @@ -146,21 +148,27 @@ impl From<&DynamicText> for XMLElement { println!("对齐方式:{}, {}", txt.h_alignment, txt.v_alignment); println!("文本宽度: {}", txt_width); println!("文本高度:{}", pt_size); - println!("初始位置: x={}, y={}", txt.x, txt.y); + println!("初始位置: x={}, y={}", txt.align_x, txt.align_y); println!("旋转角度: {}", txt.rotation); - println!("cjk_char_count: {}", cjk_char_count); + // println!("cjk_char_count: {}", cjk_char_count); // 计算基础位置(不考虑旋转) // txt.x和txt.y现在是对齐点坐标,需要根据对齐方式计算出左上角位置 // 首先根据水平对齐方式计算左边界的x坐标 let left_x = match txt.h_alignment { - HAlignment::Left => txt.x, - HAlignment::Center => txt.x - txt_width / 2.0, - HAlignment::Right => txt.x - txt_width, + HAlignment::Left => txt.align_x, + HAlignment::Center => txt.align_x - txt_width / 2.0, + HAlignment::Right => txt.align_x - txt_width, }; // 根据垂直对齐方式计算顶部的y坐标 - let top_y = txt.y; + let top_y = match txt.v_alignment { + VAlignment::Top => txt.align_y+pt_size * 1.5, + VAlignment::Center => txt.align_y+pt_size, + VAlignment::Bottom => txt.align_y+pt_size / 2.0, + }; + + println!("左上角位置: x={}, y={}", left_x, top_y); // 根据是否包含中文字符调整字体大小相关的偏移量 let cjk_offset:f64 = (cjk_char_count as f64) * pt_size * 0.75; @@ -173,12 +181,7 @@ impl From<&DynamicText> for XMLElement { // HAlignment::Right => cjk_offset, // }; - let base_y = top_y + 0.5 - (7.0 / 5.0 * pt_size + 26.0 / 5.0) - + match txt.v_alignment { - VAlignment::Top => pt_size * 1.5, - VAlignment::Center => pt_size, - VAlignment::Bottom => pt_size / 2.0, - }; + let base_y = top_y + 0.5 - (7.0 / 5.0 * pt_size + 26.0 / 5.0)+pt_size; // 如果有旋转角度,应用旋转变换 let (x_pos, y_pos) = if txt.rotation != 0.0 { @@ -314,16 +317,19 @@ impl<'a> DTextBuilder<'a> { h_alignment, v_alignment, reference_rectangle_width, + align_x, + align_y, + ) = 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) { - (txt.location.x, -txt.location.y) - } else { - (txt.second_alignment_point.x, -txt.second_alignment_point.y) - }; + // let (x, y) = if txt.horizontal_text_justification == HorizontalTextJustification::Left && (txt.vertical_text_justification == VerticalTextJustification::Bottom || txt.vertical_text_justification == VerticalTextJustification::Baseline) { + // (txt.location.x, -txt.location.y) + // } else { + // (txt.second_alignment_point.x, -txt.second_alignment_point.y) + // }; ( - x, - y, + txt.location.x, + -txt.location.y, txt.location.z, txt.rotation, &txt.text_style_name, @@ -332,6 +338,8 @@ impl<'a> DTextBuilder<'a> { HAlignment::from(txt.horizontal_text_justification), VAlignment::from(txt.vertical_text_justification), 0.0, // as Placeholder: no "reference_rectangle_width" with Text!!! + txt.second_alignment_point.x, + -txt.second_alignment_point.y )}, TextEntity::MText(mtxt) => { // 计算实际的旋转角度,优先使用x_axis_direction向量 @@ -370,19 +378,21 @@ impl<'a> DTextBuilder<'a> { HAlignment::from(mtxt.attachment_point), VAlignment::from(mtxt.attachment_point), mtxt.reference_rectangle_width, + mtxt.insertion_point.x, + -mtxt.insertion_point.y, )}, TextEntity::Attrib(attrib) => { // 根据DXF文本对齐规则,当水平对齐不是Left时,使用second_alignment_point - let (x, y) = if attrib.horizontal_text_justification == HorizontalTextJustification::Left && (attrib.vertical_text_justification == VerticalTextJustification::Bottom || attrib.vertical_text_justification == VerticalTextJustification::Baseline) { - println!("{}",111); - (attrib.location.x, -attrib.location.y) - } else { - println!("{}",222); - (attrib.second_alignment_point.x, -attrib.second_alignment_point.y) - }; + // let (x, y) = if attrib.horizontal_text_justification == HorizontalTextJustification::Left && (attrib.vertical_text_justification == VerticalTextJustification::Bottom || attrib.vertical_text_justification == VerticalTextJustification::Baseline) { + // println!("{}",111); + // (attrib.location.x, -attrib.location.y) + // } else { + // println!("{}",222); + // (attrib.second_alignment_point.x, -attrib.second_alignment_point.y) + // }; ( - x, - y, + attrib.location.x, + -attrib.location.y, attrib.location.z, attrib.rotation, &attrib.text_style_name, @@ -391,6 +401,8 @@ impl<'a> DTextBuilder<'a> { HAlignment::from(attrib.horizontal_text_justification), VAlignment::from(attrib.vertical_text_justification), 0.0, // as Placeholder: not need to check if Attrib has something similar + attrib.second_alignment_point.x, + -attrib.second_alignment_point.y ) }, }; @@ -461,6 +473,9 @@ impl<'a> DTextBuilder<'a> { text: value, keep_visual_rotation: false, info_name: None, + align_x, + align_y, + } } }