forked from 1b-agent/opencadstudio-upstream
fix(mtext): sync wrap width ruler
This commit is contained in:
1 parent
325cd2474c
commit
325beaea44
5 files changed
+109
-45
No files matched your search
@@ -177,6 +177,38 @@ impl MTextEditorState {
|
||||
self.height.trim().parse::<f64>().ok().filter(|h| *h > 0.0).unwrap_or(0.25)
|
||||
}
|
||||
|
||||
/// Pixels per drawing unit used by the editor preview. The dominant glyph
|
||||
/// height is always displayed at the same screen size; wrapping width must
|
||||
/// never participate in this calculation.
|
||||
pub(in crate::app) fn preview_scale(&self) -> f32 {
|
||||
let mut heights: Vec<f32> = self
|
||||
.glyph_boxes
|
||||
.iter()
|
||||
.filter(|b| b.xmax - b.xmin > 1e-6)
|
||||
.map(|b| b.ymax - b.ymin)
|
||||
.filter(|height| height.is_finite() && *height > 1e-6)
|
||||
.collect();
|
||||
let unit = if heights.is_empty() {
|
||||
self.height_value() as f32
|
||||
} else {
|
||||
heights.sort_by(|a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal));
|
||||
let (mut best_height, mut best_count, mut index) = (heights[0], 0usize, 0usize);
|
||||
while index < heights.len() {
|
||||
let mut end = index;
|
||||
while end < heights.len() && heights[end] <= heights[index] * 1.05 {
|
||||
end += 1;
|
||||
}
|
||||
if end - index > best_count {
|
||||
best_count = end - index;
|
||||
best_height = heights[(index + end - 1) / 2];
|
||||
}
|
||||
index = end;
|
||||
}
|
||||
best_height
|
||||
};
|
||||
(super::view::overlay::MTEXT_PREVIEW_EM_PX / unit.max(1e-6)).clamp(1e-4, 1e6)
|
||||
}
|
||||
|
||||
/// Fold the toolbar's global defaults (font / colour / oblique / width /
|
||||
/// char-spacing) onto every span that does not already override them. This
|
||||
/// replaces the old hand-built `\f;\C;…` prefix so the value is produced
|
||||
@@ -565,6 +597,18 @@ impl super::OpenCADStudio {
|
||||
self.modal_offset = iced::Vector::ZERO;
|
||||
self.modal_resize = iced::Vector::ZERO;
|
||||
self.rebuild_mtext_preview();
|
||||
// The preview uses a fixed on-screen text size. Therefore the initial
|
||||
// wrap width is the drawing-unit span that exactly reaches the right
|
||||
// edge of the editor, placing both ruler and slider at their maximum.
|
||||
if handle.is_none() {
|
||||
let initial_width = self.mtext_editor.as_ref().map(|ed| {
|
||||
super::view::overlay::MTEXT_EDITOR_WRITING_WIDTH / ed.preview_scale()
|
||||
});
|
||||
if let (Some(ed), Some(width)) = (self.mtext_editor.as_mut(), initial_width) {
|
||||
ed.rect_width = f64::from(width.max(1e-6));
|
||||
}
|
||||
self.rebuild_mtext_preview();
|
||||
}
|
||||
// Place the caret at the end so typing works without a click first.
|
||||
let end = self.mtext_vis_count();
|
||||
if let Some(ed) = self.mtext_editor.as_mut() {
|
||||
|
||||
Reference in new issue
Block a user