forked from 1b-agent/opencadstudio-upstream
DGNIMPORT: V8 text styles; 3D text ends at its byte count
A V8 file's text style table comes in as text styles (a style the drawing has keeps its own; Standard stays Standard), and each text or text node takes the style its text style linkage names. A 3D text's characters end at the byte count the element gives, so a byte after them is no longer read as a character. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
952cc0326d
commit
b686d5cbe8
4 files changed
+74
-12
No files matched your search
@@ -362,10 +362,20 @@ fn color_code(color: By<crate::scene::model::underlay_vector::DgnColor>) -> u16
|
||||
}
|
||||
}
|
||||
|
||||
/// The text style of a line of text (V7: one per font number, "dgnNNN"),
|
||||
/// added to `styles` with its font file the first time.
|
||||
fn text_style(geom: &DgnGeom, styles: &mut Vec<(String, String)>) -> String {
|
||||
/// The text style of a line of text (V7: one per font number, "dgnNNN";
|
||||
/// V8: the style the text names), added to `styles` with its font file
|
||||
/// the first time.
|
||||
fn text_style(geom: &DgnGeom, import: &DgnImport, styles: &mut Vec<(String, String)>) -> String {
|
||||
match geom {
|
||||
DgnGeom::Text { style: Some(id), .. } => match import.text_styles.iter().find(|(i, _)| i == id) {
|
||||
Some((_, name)) if !name.eq_ignore_ascii_case("Standard") => {
|
||||
if !styles.iter().any(|s| s.0 == *name) {
|
||||
styles.push((name.clone(), "txt.shx".to_string()));
|
||||
}
|
||||
name.clone()
|
||||
}
|
||||
_ => "Standard".to_string(),
|
||||
},
|
||||
DgnGeom::Text {
|
||||
font: Some(font), ..
|
||||
} => {
|
||||
@@ -435,7 +445,7 @@ fn text_line(g: &DgnGeom) -> Option<(&str, P3, f64, f64, f64)> {
|
||||
/// attached at its bottom left a third of the height below the baseline
|
||||
/// (exact line spacing 0.8), any other at its justification point; its
|
||||
/// contents carry its colour (and width factor).
|
||||
fn mtext_of_text(geom: &DgnGeom, color: u16) -> Option<EntityType> {
|
||||
fn mtext_of_text(geom: &DgnGeom, color: u16, style: &str) -> Option<EntityType> {
|
||||
let DgnGeom::Text {
|
||||
text,
|
||||
origin,
|
||||
@@ -477,7 +487,7 @@ fn mtext_of_text(geom: &DgnGeom, color: u16) -> Option<EntityType> {
|
||||
m.rotation = rotation.rem_euclid(std::f64::consts::TAU);
|
||||
m.rectangle_width = 0.0;
|
||||
m.drawing_direction = DrawingDirection::ByStyle;
|
||||
m.style = "Standard".to_string();
|
||||
m.style = style.to_string();
|
||||
Some(EntityType::MText(Box::new(m)))
|
||||
}
|
||||
|
||||
@@ -768,12 +778,15 @@ impl<'a> Converter<'a> {
|
||||
}
|
||||
// V7 text is TEXT, V8 text an MTEXT.
|
||||
DgnGeom::Text { font: Some(_), .. } => {
|
||||
let style = text_style(geom, &mut self.out.styles);
|
||||
let style = text_style(geom, self.import, &mut self.out.styles);
|
||||
text_entity(geom, &style).into_iter().collect()
|
||||
}
|
||||
DgnGeom::Text { .. } => mtext_of_text(geom, color_code(element.color))
|
||||
.into_iter()
|
||||
.collect(),
|
||||
DgnGeom::Text { .. } => {
|
||||
let style = text_style(geom, self.import, &mut self.out.styles);
|
||||
mtext_of_text(geom, color_code(element.color), &style)
|
||||
.into_iter()
|
||||
.collect()
|
||||
}
|
||||
// Exploded, each line converts as a text element of its own.
|
||||
DgnGeom::TextNode { lines, .. } if self.explode_text_nodes => lines
|
||||
.iter()
|
||||
@@ -788,7 +801,7 @@ impl<'a> Converter<'a> {
|
||||
let Some(first) = lines.first() else {
|
||||
return Vec::new();
|
||||
};
|
||||
let style = text_style(first, &mut self.out.styles);
|
||||
let style = text_style(first, self.import, &mut self.out.styles);
|
||||
let color = (!self.import.v7).then(|| color_code(element.color));
|
||||
mtext_of_node(lines, *origin, *just, *line_spacing, style, color)
|
||||
.into_iter()
|
||||
@@ -905,6 +918,12 @@ pub fn convert(import: &DgnImport, sub_units: bool, explode_text_nodes: bool) ->
|
||||
c.layer(&element, false);
|
||||
}
|
||||
}
|
||||
// Every text style of the file's table comes in, used or not.
|
||||
for (_, name) in &import.text_styles {
|
||||
if !name.eq_ignore_ascii_case("Standard") && !c.out.styles.iter().any(|s| s.0 == *name) {
|
||||
c.out.styles.push((name.clone(), "txt.shx".to_string()));
|
||||
}
|
||||
}
|
||||
c.in_definition = true;
|
||||
for (name, elements) in &cells {
|
||||
let entities = c.elements(elements, true, CellCopy::default(), 0);
|
||||
|
||||
Reference in new issue
Block a user