[LyX/master] Fix display of a math hull inset in a tight inset

2024-03-22 Thread Jean-Marc Lasgouttes
commit 4dfebbe9da27ff500b8245858322f1baeb00100b
Author: Jean-Marc Lasgouttes 
Date:   Fri Jul 14 02:13:18 2023 +0200

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 

[LyX/master] Fix display of a math hull inset in a tight inset

2023-07-14 Thread Jean-Marc Lasgouttes
commit 4bbd4a45e7494363903801540102150886fa2c6b
Author: Jean-Marc Lasgouttes 
Date:   Fri Jul 14 02:13:18 2023 +0200

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 recorded later in the
corresponding row element's `extra' field.

The code could be reorganized to be simpler, in particular by
computing metrics in tokenizeRow, or after tokenizeRow. However the
choice here is to produce a simple patch, fit for 2.4.0.

Fixes bug #12320.
---
 src/MetricsInfo.cpp  |3 ++-
 src/MetricsInfo.h|2 ++
 src/Row.cpp  |5 +++--
 src/RowPainter.cpp   |9 +++--
 src/TextMetrics.cpp  |   18 +-
 src/mathed/InsetMathHull.cpp |9 +++--
 6 files changed, 38 insertions(+), 8 deletions(-)

diff --git a/src/MetricsInfo.cpp b/src/MetricsInfo.cpp
index 89196f3..8fe03ba 100644
--- a/src/MetricsInfo.cpp
+++ b/src/MetricsInfo.cpp
@@ -123,7 +123,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 94f8670..09c5b63 100644
--- a/src/MetricsInfo.h
+++ b/src/MetricsInfo.h
@@ -105,6 +105,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/Row.cpp b/src/Row.cpp
index c39d63b..7e70ca2 100644
--- a/src/Row.cpp
+++ b/src/Row.cpp
@@ -509,14 +509,15 @@ void Row::addMarginSpace(pos_type const pos, int const 
width,
 
 void Row::push_back(Row::Element const & e)
 {
-   dim_.wid += e.dim.wid;
+   dim_.wid += e.dim.wid + ((e.type == INSET) ? e.extra : 0);
elements_.push_back(e);
 }
 
 
 void Row::pop_back()
 {
-   dim_.wid -= elements_.back().dim.wid;
+   Element const & e = elements_.back();
+   dim_.wid -= e.dim.wid + ((e.type == INSET) ? e.extra : 0);
elements_.pop_back();
 }
 
diff --git a/src/RowPainter.cpp b/src/RowPainter.cpp
index b8db1aa..6798d91 100644
--- a/src/RowPainter.cpp
+++ b/src/RowPainter.cpp
@@ -100,12 +100,14 @@ void RowPainter::paintInset(Row::Element const & e) const
bool const pi_full_repaint = pi_.full_repaint;
bool const pi_do_spellcheck = pi_.do_spellcheck;
Change const pi_change = pi_.change;
+   int const pi_textwidth = pi_.base.textwidth;
 
pi_.base.font = e.inset->inheritFont() ? e.font.fontInfo() :
pi_.base.bv->buffer().params().getFont().fontInfo();
pi_.ltr_pos = !e.font.isVisibleRightToLeft();
pi_.change = pi_.change.changed() ? pi_.change : e.change;
pi_.do_spellcheck &= e.inset->allowSpellCheck();
+   pi_.base.textwidth += e.extra;
 
int const x1 = int(x_);
pi_.base.bv->coordCache().insets().add(e.inset, x1, yo_);
@@ -122,6 +124,7 @@ void RowPainter::paintInset(Row::Element const & e) const
pi_.change = pi_change;
pi_.do_spellcheck = pi_do_spellcheck;
pi_.selected = pi_selected;
+   pi_.base.textwidth = pi_textwidth;
 
 #ifdef DEBUG_METRICS
Dimension const & dim = pi_.base.bv->coordCache().insets().dim(e.inset);
@@ -555,7 +558,8 @@ void RowPainter::paintOnlyInsets()
paintChange(e);
}
 
-   x_ += e.full_width();
+   // extra is the extrawidth band-aid described in redoParagraphs
+   x_ +=  e.full_width() + ((e.type == Row::INSET) ? e.extra : 0);
}
 }
 
@@ -590,7 +594,8 @@ void RowPainter::paintText()
if (e.type != Row::INSET || ! 
e.inset->canPaintChange(*pi_.base.bv))
paintChange(e);
 
-   x_ += e.full_width();
+   // extra is the extrawidth band-aid described in redoParagraphs
+   x_ +=  e.full_width() + ((e.type == Row::INSET) ? e.extra : 0);
}
 }
 
diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp
index 88c8e81..6fdcfe5 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 &