From 4dfebbe9da27ff500b8245858322f1baeb00100b Mon Sep 17 00:00:00 2001 From: Jean-Marc Lasgouttes Date: Fri, 14 Jul 2023 02:13:18 +0200 Subject: [PATCH] Fix display of a math hull inset in a tight inset This is a kind of hack. This allows InsetMathHull to state that it needs some elbow room beyond its width, in order to fit the numbering and/or the left margin (with left alignment), which are outside of the inset itself. To this end, InsetMathHull::metrics() sets a value in MetricsInfo::extrawidth and this value is added later to the width of the row that contains the inset (when this row is tight or shorter than the max allowed width). Fixes bug #12320. --- src/MetricsInfo.cpp | 3 ++- src/MetricsInfo.h | 2 ++ src/TextMetrics.cpp | 21 +++++++++++++++++++++ src/mathed/InsetMathHull.cpp | 9 +++++++-- 4 files changed, 32 insertions(+), 3 deletions(-) diff --git a/src/MetricsInfo.cpp b/src/MetricsInfo.cpp index d663c9a77d..844c1c13f3 100644 --- a/src/MetricsInfo.cpp +++ b/src/MetricsInfo.cpp @@ -152,7 +152,8 @@ int MetricsBase::inPixels(Length const & len) const MetricsInfo::MetricsInfo(BufferView * bv, FontInfo font, int textwidth, MacroContext const & mc, bool vm, bool tight) - : base(bv, font, textwidth), macrocontext(mc), vmode(vm), tight_insets(tight) + : base(bv, font, textwidth), macrocontext(mc), vmode(vm), tight_insets(tight), + extrawidth(0) {} diff --git a/src/MetricsInfo.h b/src/MetricsInfo.h index 176eabfea8..6f1d404822 100644 --- a/src/MetricsInfo.h +++ b/src/MetricsInfo.h @@ -109,6 +109,8 @@ public: bool vmode; /// if true, do not expand insets to max width artificially bool tight_insets; + /// Extra width required by an inset, in addition to its dimension + int extrawidth; }; diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp index 4692918e8e..6968279c23 100644 --- a/src/TextMetrics.cpp +++ b/src/TextMetrics.cpp @@ -485,6 +485,7 @@ bool TextMetrics::redoParagraph(pit_type const pit, bool const align_rows) par.setBeginOfBody(); Font const bufferfont = buffer.params().getFont(); CoordCache::Insets & insetCache = bv_->coordCache().insets(); + map extrawidths; for (auto const & e : par.insetList()) { // FIXME Doesn't this HAVE to be non-empty? // position already initialized? @@ -521,6 +522,20 @@ bool TextMetrics::redoParagraph(pit_type const pit, bool const align_rows) MetricsInfo mi(bv_, font.fontInfo(), w, mc, e.pos == 0, tight_); mi.base.outer_font = displayFont(pit, e.pos).fontInfo(); e.inset->metrics(mi, dim); + /* FIXME: This is a hack. This allows InsetMathHull to state + * that it needs some elbow room beyond its width, in order to + * fit the numbering and/or the left margin (with left + * alignment), which are outside of the inset itself. + * + * To this end, InsetMathHull::metrics() sets a value in + * MetricsInfo::extrawidth and this value is added later to + * the width of the row that contains the inset (when this row + * is tight or shorter than the max allowed width). + * + * See ticket #12320 for details. + */ + extrawidths[e.inset] = mi.extrawidth; + if (!insetCache.has(e.inset) || insetCache.dim(e.inset) != dim) { insetCache.add(e.inset, dim); changed = true; @@ -532,6 +547,12 @@ bool TextMetrics::redoParagraph(pit_type const pit, bool const align_rows) // Split the row in several rows fitting in available width pm.rows() = breakParagraph(bigrow); + // Add the needed extra width to the rows that contain the insets that request it + for (Row & row : pm.rows()) + for (Row::Element & e : row) + if (e.type == Row::INSET && (row.width() < max_width_ || tight_)) + row.dim().wid += extrawidths[e.inset]; + /* If there is more than one row, expand the text to the full * allowable width. This setting here is needed for the * setRowAlignment() below. We do nothing when tight insets are diff --git a/src/mathed/InsetMathHull.cpp b/src/mathed/InsetMathHull.cpp index 30ec93a14f..94d293870d 100644 --- a/src/mathed/InsetMathHull.cpp +++ b/src/mathed/InsetMathHull.cpp @@ -523,6 +523,9 @@ void InsetMathHull::metrics(MetricsInfo & mi, Dimension & dim) const if (mi.vmode) top_display_margin += theFontMetrics(mi.base.font).maxHeight() + 2; + int const ind = indent(*mi.base.bv); + mi.extrawidth = ind; + if (previewState(mi.base.bv)) { preview_->metrics(mi, dim); if (previewTooSmall(dim)) { @@ -554,6 +557,7 @@ void InsetMathHull::metrics(MetricsInfo & mi, Dimension & dim) const if (numberedType()) { BufferParams::MathNumber const math_number = buffer().params().getMathNumber(); int extra_offset = 0; + int max_nlwid = 0; for (row_type row = 0; row < nrows(); ++row) { rowinfo(row).offset[mi.base.bv] += extra_offset; docstring const nl = nicelabel(row); @@ -561,7 +565,6 @@ void InsetMathHull::metrics(MetricsInfo & mi, Dimension & dim) const continue; Dimension dimnl; mathed_string_dim(mi.base.font, nl, dimnl); - int const ind = indent(*mi.base.bv); int const x = ind ? ind : (mi.base.textwidth - dim.wid) / 2; // for some reason metrics does not trigger at the // same point as draw, and therefore we use >= instead of > @@ -569,8 +572,10 @@ void InsetMathHull::metrics(MetricsInfo & mi, Dimension & dim) const || (math_number == BufferParams::RIGHT && dimnl.wid >= mi.base.textwidth - x - dim.wid)) { extra_offset += dimnl.height(); - } + } else if (dimnl.wid > max_nlwid) + max_nlwid = dimnl.wid; } + mi.extrawidth += max_nlwid; dim.des += extra_offset; }