|
|
|
@ -64,98 +64,31 @@ impl From<&DynamicText> for XMLElement {
|
|
|
|
// "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 graphene_count = 0;
|
|
|
|
|
|
|
|
// for grapheme in txt.text.graphemes(true) {
|
|
|
|
|
|
|
|
// graphene_count += 1;
|
|
|
|
|
|
|
|
// 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兼容表意文字补充
|
|
|
|
|
|
|
|
// }) {
|
|
|
|
|
|
|
|
// 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 {
|
|
|
|
// 不同的字母,宽度与高度的比例并不相同,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;
|
|
|
|
|
|
|
|
// 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 = txt.x + 0.5 - (pt_size / 8.0) - 4.05;
|
|
|
|
|
|
|
|
// // match txt.h_alignment {
|
|
|
|
|
|
|
|
// // HAlignment::Left => x_pos,
|
|
|
|
|
|
|
|
// // HAlignment::Center => x_pos - txt_width / 2.0,
|
|
|
|
|
|
|
|
// // HAlignment::Right => x_pos - txt_width,
|
|
|
|
|
|
|
|
// // }
|
|
|
|
|
|
|
|
// x_pos // 直接返回基础x_pos,不进行水平对齐调整
|
|
|
|
|
|
|
|
// };
|
|
|
|
|
|
|
|
// // let y_pos = txt.y + 0.5 - (7.0 / 5.0 * pt_size + 26.0 / 5.0) + pt_size;
|
|
|
|
|
|
|
|
// let y_pos = {
|
|
|
|
|
|
|
|
// let base_y_pos = txt.y + 0.5 - (7.0 / 5.0 * pt_size + 26.0 / 5.0) + pt_size;
|
|
|
|
|
|
|
|
// match txt.v_alignment {
|
|
|
|
|
|
|
|
// VAlignment::Top => base_y_pos,
|
|
|
|
|
|
|
|
// VAlignment::Center => base_y_pos - pt_size / 2.0,
|
|
|
|
|
|
|
|
// VAlignment::Bottom => base_y_pos - pt_size,
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// };
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 如果采用计算对齐的方式,可能还要考虑字体宽度的偏差。。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
println!("文本:{}", txt.text);
|
|
|
|
println!("文本:{}", txt.text);
|
|
|
|
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.align_x, txt.align_y);
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 计算基础位置(不考虑旋转)
|
|
|
|
// 计算基础位置(不考虑旋转)
|
|
|
|
// txt.x和txt.y现在是对齐点坐标,需要根据对齐方式计算出左上角位置
|
|
|
|
// txt.x和txt.y现在是左下角位置
|
|
|
|
// 首先根据水平对齐方式计算左边界的x坐标
|
|
|
|
|
|
|
|
let left_x = txt.x;
|
|
|
|
let left_x = txt.x;
|
|
|
|
|
|
|
|
// align_x 是对齐点的x坐标,后面加的数字是考虑到QET中boundingRect的没有完全贴合文本内容
|
|
|
|
|
|
|
|
let mut align_x = match txt.h_alignment {
|
|
|
|
|
|
|
|
HAlignment::Left => txt.align_x - 0.5,
|
|
|
|
|
|
|
|
HAlignment::Center => txt.align_x - 1.0,
|
|
|
|
|
|
|
|
HAlignment::Right => txt.align_x - 2.0
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 根据垂直对齐方式计算顶部的y坐标
|
|
|
|
// 根据垂直对齐方式计算顶部的y坐标
|
|
|
|
let top_y = match txt.v_alignment {
|
|
|
|
let top_y = match txt.v_alignment {
|
|
|
|
@ -164,20 +97,23 @@ impl From<&DynamicText> for XMLElement {
|
|
|
|
VAlignment::Bottom => txt.y - pt_size + pt_size / 2.0,
|
|
|
|
VAlignment::Bottom => txt.y - pt_size + pt_size / 2.0,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
println!("左上角位置: x={}, y={}", left_x, top_y);
|
|
|
|
// align_y 是对齐点的y坐标,后面加的数字是考虑到QET中boundingRect的没有完全贴合文本内容
|
|
|
|
|
|
|
|
let mut align_y = match txt.v_alignment {
|
|
|
|
|
|
|
|
VAlignment::Top => txt.align_y - 0.5,
|
|
|
|
|
|
|
|
VAlignment::Center => txt.align_y + 0.5,
|
|
|
|
|
|
|
|
VAlignment::Bottom => txt.align_y + 1.0
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(txt.h_alignment == HAlignment::Left && txt.v_alignment==VAlignment::Bottom) {
|
|
|
|
|
|
|
|
align_x = txt.x-0.5;
|
|
|
|
|
|
|
|
align_y = txt.y+1.0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 根据是否包含中文字符调整字体大小相关的偏移量
|
|
|
|
|
|
|
|
let cjk_offset:f64 = (cjk_char_count as f64) * pt_size * 0.75;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 左对齐是不需要中文偏移的,居中对齐需要偏移,右对齐要偏移
|
|
|
|
println!("左上角位置: x={}, y={}", left_x, top_y);
|
|
|
|
let base_x = left_x + 0.5 - (pt_size / 8.0) - 4.05;
|
|
|
|
|
|
|
|
// - match txt.h_alignment {
|
|
|
|
|
|
|
|
// HAlignment::Left => 0.0,
|
|
|
|
|
|
|
|
// HAlignment::Center => cjk_offset / 2.0,
|
|
|
|
|
|
|
|
// HAlignment::Right => cjk_offset,
|
|
|
|
|
|
|
|
// };
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let base_y = top_y + 0.5 - (7.0 / 5.0 * pt_size + 26.0 / 5.0) + pt_size;
|
|
|
|
let base_x = left_x;
|
|
|
|
|
|
|
|
let base_y = top_y;
|
|
|
|
|
|
|
|
|
|
|
|
// 如果有旋转角度,应用旋转变换
|
|
|
|
// 如果有旋转角度,应用旋转变换
|
|
|
|
let (x_pos, y_pos) = if txt.rotation != 0.0 {
|
|
|
|
let (x_pos, y_pos) = if txt.rotation != 0.0 {
|
|
|
|
@ -212,6 +148,8 @@ impl From<&DynamicText> for XMLElement {
|
|
|
|
dtxt_xml.add_attribute("frame", txt.frame);
|
|
|
|
dtxt_xml.add_attribute("frame", txt.frame);
|
|
|
|
dtxt_xml.add_attribute("text_width", txt.text_width);
|
|
|
|
dtxt_xml.add_attribute("text_width", txt.text_width);
|
|
|
|
dtxt_xml.add_attribute("color", txt.color.display_rgb());
|
|
|
|
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));
|
|
|
|
|
|
|
|
|
|
|
|
//If I ever add support for other text_from types, element and composite text
|
|
|
|
//If I ever add support for other text_from types, element and composite text
|
|
|
|
//I'll need to add more smarts here, as there may be some other children components
|
|
|
|
//I'll need to add more smarts here, as there may be some other children components
|
|
|
|
@ -244,6 +182,8 @@ impl ScaleEntity for DynamicText {
|
|
|
|
fn scale(&mut self, fact_x: f64, fact_y: f64) {
|
|
|
|
fn scale(&mut self, fact_x: f64, fact_y: f64) {
|
|
|
|
self.x *= fact_x;
|
|
|
|
self.x *= fact_x;
|
|
|
|
self.y *= fact_y;
|
|
|
|
self.y *= fact_y;
|
|
|
|
|
|
|
|
self.align_x *= fact_x;
|
|
|
|
|
|
|
|
self.align_y *= fact_y;
|
|
|
|
//self.font.pixel_size *= fact;
|
|
|
|
//self.font.pixel_size *= fact;
|
|
|
|
self.font.point_size *= fact_x;
|
|
|
|
self.font.point_size *= fact_x;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -332,7 +272,7 @@ impl<'a> DTextBuilder<'a> {
|
|
|
|
txt.text_height,
|
|
|
|
txt.text_height,
|
|
|
|
txt.value.clone(),
|
|
|
|
txt.value.clone(),
|
|
|
|
HAlignment::from(txt.horizontal_text_justification),
|
|
|
|
HAlignment::from(txt.horizontal_text_justification),
|
|
|
|
VAlignment::from(txt.vertical_text_justification),
|
|
|
|
VAlignment::from_text_entity(txt.vertical_text_justification, false),
|
|
|
|
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.x,
|
|
|
|
-txt.second_alignment_point.y
|
|
|
|
-txt.second_alignment_point.y
|
|
|
|
@ -395,7 +335,7 @@ impl<'a> DTextBuilder<'a> {
|
|
|
|
attrib.text_height,
|
|
|
|
attrib.text_height,
|
|
|
|
attrib.text_tag.clone(),
|
|
|
|
attrib.text_tag.clone(),
|
|
|
|
HAlignment::from(attrib.horizontal_text_justification),
|
|
|
|
HAlignment::from(attrib.horizontal_text_justification),
|
|
|
|
VAlignment::from(attrib.vertical_text_justification),
|
|
|
|
VAlignment::from_text_entity(attrib.vertical_text_justification, true),
|
|
|
|
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.x,
|
|
|
|
-attrib.second_alignment_point.y
|
|
|
|
-attrib.second_alignment_point.y
|
|
|
|
|