]> git.lyx.org Git - lyx.git/commitdiff
Fix display of a math hull inset in a tight inset
authorJean-Marc Lasgouttes <lasgouttes@lyx.org>
Fri, 14 Jul 2023 00:13:18 +0000 (02:13 +0200)
committerJean-Marc Lasgouttes <lasgouttes@lyx.org>
Fri, 14 Jul 2023 15:17:23 +0000 (17:17 +0200)
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
src/MetricsInfo.h
src/Row.cpp
src/RowPainter.cpp
src/TextMetrics.cpp
src/mathed/InsetMathHull.cpp

index 89196f3fb3be765fd000b1a18ace026a16054f47..8fe03ba441fbf4f8ae303b64168948def0fad6a8 100644 (file)
@@ -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)
 {}
 
 
index 94f86706a7fe1902548b208c0e89f5d40b0f6ef9..09c5b6331b466849650ea029f9958ef079cfce17 100644 (file)
@@ -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;
 };
 
 
index c39d63bd20e66025ad4ac9f8e85bfbc9c40f8260..7e70ca274bc640d61e5c7eabe16819cb1567702f 100644 (file)
@@ -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();
 }
 
index b8db1aac2ea79e17ff881b36755f0e7e8fef7557..6798d917ecc7b9d6acf6482d37bb2c78c3162127 100644 (file)
@@ -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);
        }
 }
 
index 88c8e81c1e95e6d7cc904a8089a2034c5616bd34..6fdcfe5aaf83ede405f4c43ef5fe8ed6c5dd089b 100644 (file)
@@ -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 <Inset const *, int> extrawidths;
        for (auto const & e : par.insetList()) {
                // FIXME Doesn't this HAVE to be non-empty?
                // position already initialized?
@@ -520,6 +521,17 @@ bool TextMetrics::redoParagraph(pit_type const pit, bool const align_rows)
                MacroContext mc(&buffer, parPos);
                MetricsInfo mi(bv_, font.fontInfo(), w, mc, e.pos == 0, tight_);
                e.inset->metrics(mi, dim);
+               /* FIXME: 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. 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;
@@ -527,7 +539,11 @@ bool TextMetrics::redoParagraph(pit_type const pit, bool const align_rows)
        }
 
        // Transform the paragraph into a single row containing all the elements.
-       Row const bigrow = tokenizeParagraph(pit);
+       Row bigrow = tokenizeParagraph(pit);
+       // Add the needed extra width to the row elements of the insets
+       for (auto & e : bigrow)
+               if (e.type == Row::INSET)
+                       e.extra = extrawidths[e.inset];
        // Split the row in several rows fitting in available width
        pm.rows() = breakParagraph(bigrow);
 
index bdac94fcaef38a58d014a8b31df1624a24671f4f..b33bb0d7114828b8ac3e54f1ac990a611be8b8b1 100644 (file)
@@ -476,6 +476,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)) {
@@ -507,6 +510,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);
@@ -514,7 +518,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 >
@@ -522,8 +525,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;
        }