forked from 1b-agent/opencadstudio-upstream
fix(mtext): size the empty-line caret slot to the text, not the entity
The paragraph-start caret slot used the raw entity height, so a blank line's caret stood entity-tall — many times the visible text when `\H…x;` runs shrink it (5× on budweiser2018.dwg handle 50019). Size it to the line's own text height instead (an empty line inherits the previous line's height, the same rule `per_line_h` already uses for spacing). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
4479ba8c29
commit
ef19f898b0
1 file changed
+34
-2
@@ -1311,6 +1311,34 @@ pub fn layout_mtext(opts: &MTextRenderOpts) -> MTextLayout {
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
// Per-line text height — the tallest Word on the line, an empty line
|
||||
// inheriting the previous line's height (same rule as `per_line_h`). Unlike
|
||||
// `line_max_h` it has no `entity_h` floor, so it reflects the ACTUAL text
|
||||
// size; used to size the empty-line caret slot to the surrounding text
|
||||
// rather than the raw entity height (which can be many times the visible
|
||||
// text when `\H…x;` runs shrink it).
|
||||
let line_text_h: Vec<f32> = {
|
||||
let mut last = entity_h;
|
||||
sub_lines
|
||||
.iter()
|
||||
.map(|s| {
|
||||
let mh = s
|
||||
.atoms
|
||||
.iter()
|
||||
.filter_map(|a| match &a.kind {
|
||||
AtomKind::Word(_) => Some(a.state.height_mul * entity_h),
|
||||
_ => None,
|
||||
})
|
||||
.fold(0.0_f32, f32::max);
|
||||
if mh > 0.0 {
|
||||
last = mh;
|
||||
mh
|
||||
} else {
|
||||
last
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
};
|
||||
let line_y_offset: Vec<f32> = {
|
||||
let mut col_y = vec![0.0_f32; cols.count.max(1)];
|
||||
let mut started = vec![false; cols.count.max(1)];
|
||||
@@ -1444,10 +1472,14 @@ pub fn layout_mtext(opts: &MTextRenderOpts) -> MTextLayout {
|
||||
|
||||
// A paragraph break (explicit `\n` / `\P`) that started this line gets
|
||||
// a zero-width caret slot at the line start, so the MText editor can
|
||||
// place the caret on a fresh/empty line.
|
||||
// place the caret on a fresh/empty line. Size it to the line's own text
|
||||
// height (the surrounding text for an empty line), not the raw entity
|
||||
// height — otherwise a blank line's caret is entity-tall, which is many
|
||||
// times the visible text when `\H…x;` runs shrink it.
|
||||
if opts.want_glyph_boxes && i > 0 && sub.is_first_in_paragraph {
|
||||
let caret_h = line_text_h.get(i).copied().unwrap_or(entity_h);
|
||||
let (ax, ay) = to_world(line_base_x, line_base_y, cursor_start, 0.0);
|
||||
let (_, by) = to_world(line_base_x, line_base_y, cursor_start, entity_h);
|
||||
let (_, by) = to_world(line_base_x, line_base_y, cursor_start, caret_h);
|
||||
glyph_boxes.push(GlyphBox {
|
||||
vis,
|
||||
xmin: ax,
|
||||
|
||||
Reference in new issue
Block a user