Files
cadcraft/crates/render/src/text_entity.rs
T
Dylan M. Taylor 2721aa8982 Enforce Rust coding standards via Clippy (#2239)
* chore(clippy): enforce workspace Rust quality gates

* refactor(doc): use explicit entity imports

* refactor(constraints): split residual evaluation

* refactor(fonts): split mtext layout

* refactor(render): use explicit entity imports

* fix(fonts): retain height for empty paragraphs

* fix(doc): repair dimension and dynamic block links

* refactor(render): split entity drawing helpers

* docs: document workspace lint inheritance

* refactor(render): isolate dimension geometry

* refactor(engine): use explicit imports

* refactor(engine): split complex edit paths into helpers

* refactor(io): split DXF read and write helpers

* refactor(ui): split canvas interaction and drawing

* refactor(ui): split command and drawing helpers

* test(i18n): split locale preference checks

* fix(ui): use current egui scope id API

* fix(dim): preserve text offset and ellipse grip behavior
2026-10-27 15:55:09 -04:00

96 lines
3.7 KiB
Rust

use super::{Bounds2, Builder, Color, Ctx, Drawing, Ink, Rgb, ink};
/// The text style of an entity (Standard defaults when missing).
pub(crate) fn text_style(d: &Drawing, name: &str) -> cadcraft_doc::TextStyle {
d.text_style(name).cloned().unwrap_or_default()
}
/// Shape a TEXT / ATTRIB / ATTDEF with its style's font and generation flags.
pub fn place_text_entity(d: &Drawing, t: &cadcraft_doc::Text, value: &str) -> (cadcraft_fonts::Shaped, Bounds2) {
let ts = text_style(d, &t.style);
let font = cadcraft_fonts::TextFont::resolve(&ts.font);
let (h, v) = align(t.halign, t.valign);
let p = cadcraft_fonts::TextParams {
insert: t.insert.xy(),
align_pt: t.align_pt.map(|p| p.xy()),
height: t.height,
rotation: t.rotation,
width_factor: t.width_factor,
oblique: t.oblique,
h,
v,
backwards: ts.backwards,
upside_down: ts.upside_down,
};
cadcraft_fonts::place(&font, value, &p)
}
/// Lay out an MTEXT with its style's font.
pub fn layout_mtext_entity(d: &Drawing, t: &cadcraft_doc::MText) -> cadcraft_fonts::MTextLayout {
let ts = text_style(d, &t.style);
let params = cadcraft_fonts::MTextParams {
insert: t.insert.xy(),
height: t.height,
width: t.width,
attach: t.attach,
rotation: t.rotation,
line_spacing: t.line_spacing,
line_spacing_exact: t.line_spacing_exact,
font: cadcraft_fonts::TextFont::resolve(&ts.font),
width_factor: ts.width_factor,
oblique: ts.oblique,
columns: t.columns.as_ref().map(|c| cadcraft_fonts::MTextColumnSpec {
dynamic: c.kind == cadcraft_doc::MTextColumnType::Dynamic,
count: usize::from(c.count.max(1)),
gutter: c.gutter,
height: c.height,
heights: if c.kind == cadcraft_doc::MTextColumnType::Dynamic && !c.auto_height { c.heights.clone() } else { Vec::new() },
reversed: c.flow_reversed,
}),
};
cadcraft_fonts::layout_mtext_with(&t.contents, &params)
}
fn mtext_color(c: Option<cadcraft_fonts::MTextColor>, rgb: Ink) -> Ink {
match c {
Some(cadcraft_fonts::MTextColor::Aci(i)) => {
u8::try_from(i).ok().filter(|i| *i > 0).map(|i| ink(Color::Index(i), Color::Index(7), Color::Index(7))).unwrap_or(rgb)
}
Some(cadcraft_fonts::MTextColor::Rgb(v)) => {
Ink { rgb: Rgb(((v >> 16) & 0xFF) as u8, ((v >> 8) & 0xFF) as u8, (v & 0xFF) as u8), aci7: false, aci: 0 }
}
None => rgb,
}
}
pub(crate) fn mtext(b: &mut Builder, ctx: &Ctx, t: &cadcraft_doc::MText, rgb: Ink, lw: f32) {
let l = layout_mtext_entity(ctx.d, t);
for p in &l.pieces {
b.shaped(ctx, mtext_color(p.color, rgb), lw, &p.shaped);
}
}
/// A TEXT's justification as the fonts' alignment (used where text is placed outside a build).
pub fn text_align(h: cadcraft_doc::HAlign, v: cadcraft_doc::VAlign) -> (cadcraft_fonts::Align, cadcraft_fonts::VAlign) {
align(h, v)
}
fn align(h: cadcraft_doc::HAlign, v: cadcraft_doc::VAlign) -> (cadcraft_fonts::Align, cadcraft_fonts::VAlign) {
use cadcraft_fonts::{Align as A, VAlign as V};
let ha = match h {
cadcraft_doc::HAlign::Left => A::Left,
cadcraft_doc::HAlign::Center => A::Center,
cadcraft_doc::HAlign::Right => A::Right,
cadcraft_doc::HAlign::Aligned => A::Aligned,
cadcraft_doc::HAlign::Middle => A::Middle,
cadcraft_doc::HAlign::Fit => A::Fit,
};
let va = match v {
cadcraft_doc::VAlign::Baseline => V::Baseline,
cadcraft_doc::VAlign::Bottom => V::Bottom,
cadcraft_doc::VAlign::Middle => V::Middle,
cadcraft_doc::VAlign::Top => V::Top,
};
(ha, va)
}