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:
parent
4479ba8c29
commit
ef19f898b0
1 changed files with 34 additions and 2 deletions
|
|
@ -1311,6 +1311,34 @@ pub fn layout_mtext(opts: &MTextRenderOpts) -> MTextLayout {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect();
|
.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 line_y_offset: Vec<f32> = {
|
||||||
let mut col_y = vec![0.0_f32; cols.count.max(1)];
|
let mut col_y = vec![0.0_f32; cols.count.max(1)];
|
||||||
let mut started = vec![false; 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 paragraph break (explicit `\n` / `\P`) that started this line gets
|
||||||
// a zero-width caret slot at the line start, so the MText editor can
|
// 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 {
|
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 (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 {
|
glyph_boxes.push(GlyphBox {
|
||||||
vis,
|
vis,
|
||||||
xmin: ax,
|
xmin: ax,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue