改回以左下角为基准计算坐标前

master
liaoxianglian 8 months ago
parent 5ef910c7b1
commit a925e454f0

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

Loading…
Cancel
Save