尝试解决字符宽度对文本位置的影响、高度偏移问题

master
liaoxianglian 4 months ago
parent dae0c20a18
commit 5ef910c7b1

@ -108,9 +108,11 @@ fn main() -> Result<()> {
.file_stem() .file_stem()
.unwrap_or_else(|| file_name.as_os_str()) .unwrap_or_else(|| file_name.as_os_str())
.to_string_lossy(); .to_string_lossy();
// 加载dxf文件获取dxf解析对象drawing
let drawing: Drawing = Drawing::load_file(&file_name).context(format!( let drawing: Drawing = Drawing::load_file(&file_name).context(format!(
"Failed to load {friendly_file_name}...\n\tMake sure the file is a valid .dxf file.", "Failed to load {friendly_file_name}...\n\tMake sure the file is a valid .dxf file.",
))?; ))?;
// 传入文件名、步长、dxf解析对象drawing创建elmt的definition标签
let q_elmt = Definition::new(friendly_file_name.clone(), args.spline_step, &drawing); let q_elmt = Definition::new(friendly_file_name.clone(), args.spline_step, &drawing);
if !args.verbose && args.info { if !args.verbose && args.info {
println!("{friendly_file_name} loaded..."); println!("{friendly_file_name} loaded...");

@ -64,27 +64,61 @@ impl From<&DynamicText> for XMLElement {
// 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| {
// 检查是否为中文字符(包括中日韩统一表意文字) // // 检查是否为中文字符(包括中日韩统一表意文字)
(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兼容表意文字补充
}) { // }) {
cjk_char_count += 1; // cjk_char_count += 1;
} // }
} // }
let txt_width = if txt.reference_rectangle_width > 2.0 { let txt_width = if txt.reference_rectangle_width > 2.0 {
txt.reference_rectangle_width txt.reference_rectangle_width
} else { } else {
(graphene_count as f64) * pt_size * 0.75 // 不同的字母宽度与高度的比例并不相同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 x_pos = { // let x_pos = {
@ -132,16 +166,16 @@ impl From<&DynamicText> for XMLElement {
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;
// 左对齐是不需要中文偏移的,居中对齐需要偏移,右对齐要偏移 // 左对齐是不需要中文偏移的,居中对齐需要偏移,右对齐要偏移
let base_x = left_x + 0.5 - (pt_size / 8.0) - 4.05 let base_x = left_x + 0.5 - (pt_size / 8.0) - 4.05;
- match txt.h_alignment { // - match txt.h_alignment {
HAlignment::Left => 0.0, // HAlignment::Left => 0.0,
HAlignment::Center => cjk_offset / 2.0, // HAlignment::Center => cjk_offset / 2.0,
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)
+ match txt.v_alignment { + match txt.v_alignment {
VAlignment::Top => pt_size / 2.0, VAlignment::Top => pt_size * 1.5,
VAlignment::Center => pt_size, VAlignment::Center => pt_size,
VAlignment::Bottom => pt_size / 2.0, VAlignment::Bottom => pt_size / 2.0,
}; };

@ -201,7 +201,7 @@ impl Circularity for LwPolyline {
} }
// 实现Definition的方法 // 实现Definition的方法
// 最后返回文本的definition标签 // 最后返回文本的definition标签
impl Definition { impl Definition {
// 创建新的 Definition 实例对应elmt的<definition>标签 传入参数:文件名, 步长, dxf图纸 // 创建新的 Definition 实例对应elmt的<definition>标签 传入参数:文件名, 步长, dxf图纸
pub fn new(name: impl Into<String>, spline_step: u32, drw: &Drawing) -> Self { pub fn new(name: impl Into<String>, spline_step: u32, drw: &Drawing) -> Self {
@ -217,7 +217,7 @@ impl Definition {
description description
}; };
// 计算宽度x热点坐标 // 计算图纸的宽度x热点坐标
//The below calculation for width and hotspot_x are taken from the qet source code //The below calculation for width and hotspot_x are taken from the qet source code
let (width, hotspot_x) = { let (width, hotspot_x) = {
let tmp_width = description.right_bound() - description.left_bound(); let tmp_width = description.right_bound() - description.left_bound();
@ -237,7 +237,7 @@ impl Definition {
) )
}; };
// 计算高度y热点坐标 // 计算图纸的高度y热点坐标
//The below calculation for height and hotspot_y are taken from the qet source code //The below calculation for height and hotspot_y are taken from the qet source code
let (height, hotspot_y) = { let (height, hotspot_y) = {
let tmp_height = description.bot_bound() - description.top_bound(); let tmp_height = description.bot_bound() - description.top_bound();
@ -257,7 +257,7 @@ impl Definition {
) )
}; };
// 结构体初始化 设置所有必要字段包括类型、版本、UUID等 // Definition结构体初始化 设置所有必要字段包括类型、版本、UUID等
Definition { Definition {
r#type: ItemType::Element, r#type: ItemType::Element,
width, width,
@ -612,7 +612,7 @@ impl<'a> ObjectsBuilder<'a> {
// 通用样式修改函数根据line_type_name修改现有style中的line-style // 通用样式修改函数根据line_type_name修改现有style中的line-style
let update_line_style = |style: &mut String| { let update_line_style = |style: &mut String| {
// 只有当line_type_name需要虚线样式时才进行修改提高性能 // 只有当line_type_name需要虚线样式时才进行修改提高性能
if line_type_name.contains("DASH") || line_type_name == "BORDURE" { if line_type_name.contains("DASH") || line_type_name == "BORDURE" || line_type_name == "INTERROMPUx2" {
// 使用正则表达式替换line-style部分 // 使用正则表达式替换line-style部分
if style.contains("line-style:") { if style.contains("line-style:") {
*style = style.replace( *style = style.replace(
@ -662,9 +662,7 @@ impl<'a> ObjectsBuilder<'a> {
line.x2 += self.offset.x; line.x2 += self.offset.x;
line.y2 -= self.offset.y; line.y2 -= self.offset.y;
println!("Line: x1: {}, y1: {}, x2: {}, y2: {}", line.x1, line.y1, line.x2, line.y2);
Ok(Objects::Line(line)) Ok(Objects::Line(line))
} }
@ -1669,6 +1667,7 @@ impl Default for FontInfo {
//but I'll put something in for now //but I'll put something in for now
Self { Self {
family: "宋体".into(), family: "宋体".into(),
// 字号12
point_size: 12.0, point_size: 12.0,
pixel_size: i32::default(), pixel_size: i32::default(),
style_hint: FontStyleHint::Helvetica, style_hint: FontStyleHint::Helvetica,

Loading…
Cancel
Save