]> git.lyx.org Git - features.git/commitdiff
Add empty rows to grid insets when numbers are too wide
authorJean-Marc Lasgouttes <lasgouttes@lyx.org>
Sun, 14 Jul 2019 19:04:45 +0000 (21:04 +0200)
committerJean-Marc Lasgouttes <lasgouttes@lyx.org>
Sun, 14 Jul 2019 21:27:44 +0000 (23:27 +0200)
This is done to ensure that numbering never overlaps equations. The
result can be different according to the bufferview, which is why
RowInfo::offset is now a std:map.

Remaing issues (how bad are theese ?):

- the numbering is considered too large when it overlaps the inset
  rect, whereas one could consider the width if the current row
  instead.

- previews may need to be adapted similarly to fit the whole screen width

src/mathed/InsetMathGrid.cpp
src/mathed/InsetMathGrid.h
src/mathed/InsetMathHull.cpp

index 496ba36bb57dab70090113e072d80e6bfada6c98..9ba2dda197e45fdf3fffdd06c441f2aa8fe6d973 100644 (file)
@@ -92,7 +92,7 @@ InsetMathGrid::CellInfo::CellInfo()
 
 
 InsetMathGrid::RowInfo::RowInfo()
-       : descent(0), ascent(0), offset(0), lines(0), skip(0),
+       : descent(0), ascent(0), lines(0), skip(0),
          allow_newpage(true)
 {}
 
@@ -424,10 +424,10 @@ void InsetMathGrid::metrics(MetricsInfo & mi, Dimension & dim) const
        rowinfo_[nrows()].descent = 0;
 
        // compute vertical offsets
-       rowinfo_[0].offset = 0;
+       rowinfo_[0].offset[&bv] = 0;
        for (row_type row = 1; row <= nrows(); ++row) {
-               rowinfo_[row].offset =
-                       rowinfo_[row - 1].offset +
+               rowinfo_[row].offset[&bv] =
+                       rowinfo_[row - 1].offset[&bv] +
                        rowinfo_[row - 1].descent +
                        rowinfo_[row - 1].skipPixels(mi) +
                        rowsep() +
@@ -442,13 +442,13 @@ void InsetMathGrid::metrics(MetricsInfo & mi, Dimension & dim) const
                        h = 0;
                        break;
                case 'b':
-                       h = rowinfo_[nrows() - 1].offset;
+                       h = rowinfo_[nrows() - 1].offset[&bv];
                        break;
                default:
-                       h = rowinfo_[nrows() - 1].offset / 2;
+                       h = rowinfo_[nrows() - 1].offset[&bv] / 2;
        }
        for (row_type row = 0; row <= nrows(); ++row)
-               rowinfo_[row].offset -= h;
+               rowinfo_[row].offset[&bv] -= h;
 
 
        // multicolumn cell widths, as a map from first column to width in a
@@ -528,12 +528,12 @@ void InsetMathGrid::metrics(MetricsInfo & mi, Dimension & dim) const
                + vlinesep() * colinfo_[ncols()].lines
                + border();
 
-       dim.asc = - rowinfo_[0].offset
+       dim.asc = - rowinfo_[0].offset[&bv]
                + rowinfo_[0].ascent
                + hlinesep() * rowinfo_[0].lines
                + border();
 
-       dim.des = rowinfo_[nrows() - 1].offset
+       dim.des = rowinfo_[nrows() - 1].offset[&bv]
                + rowinfo_[nrows() - 1].descent
                + hlinesep() * rowinfo_[nrows()].lines
                + border() + 1;
@@ -608,9 +608,10 @@ int InsetMathGrid::vLineHOffset(col_type col, unsigned int line) const
 }
 
 
-int InsetMathGrid::hLineVOffset(row_type row, unsigned int line) const
+int InsetMathGrid::hLineVOffset(BufferView const & bv, row_type row,
+                                unsigned int line) const
 {
-       return rowinfo_[row].offset
+       return rowinfo_[row].offset[&bv]
                - rowinfo_[row].ascent
                - line * hlinesep()
                - hlinesep()/2 - rowsep()/2;
@@ -625,11 +626,11 @@ void InsetMathGrid::draw(PainterInfo & pi, int x, int y) const
                if (cellinfo_[idx].multi != CELL_PART_OF_MULTICOLUMN) {
                        cell(idx).draw(pi,
                                       x + leftMargin() + cellXOffset(bv, idx),
-                                      y + cellYOffset(idx));
+                                      y + cellYOffset(bv, idx));
 
                        row_type r = row(idx);
-                       int const yy1 = y + hLineVOffset(r, 0);
-                       int const yy2 = y + hLineVOffset(r + 1, rowinfo_[r + 1].lines - 1);
+                       int const yy1 = y + hLineVOffset(bv, r, 0);
+                       int const yy2 = y + hLineVOffset(bv, r + 1, rowinfo_[r + 1].lines - 1);
                        auto draw_left_borders = [&](col_type c) {
                                for (unsigned int i = 0; i < colinfo_[c].lines; ++i) {
                                        int const xx = x + vLineHOffset(c, i);
@@ -650,15 +651,18 @@ void InsetMathGrid::draw(PainterInfo & pi, int x, int y) const
                int const xx1 = x + vLineHOffset(0, 0);
                int const xx2 = x + vLineHOffset(ncols(), colinfo_[ncols()].lines - 1);
                for (unsigned int i = 0; i < rowinfo_[r].lines; ++i) {
-                       int const yy = y + hLineVOffset(r, i);
+                       int const yy = y + hLineVOffset(bv, r, i);
                        pi.pain.line(xx1, yy, xx2, yy, Color_foreground);
                }
        }
 }
 
 
-void InsetMathGrid::metricsT(TextMetricsInfo const & mi, Dimension & dim) const
+void InsetMathGrid::metricsT(TextMetricsInfo const & /*mi*/, Dimension & /*dim*/) const
 {
+// FIXME: this does not compile anymore with offset being a map
+// It is not worth fixing it at this point since the code is basically dead.
+#if 0
        // let the cells adjust themselves
        for (idx_type i = 0; i < nargs(); ++i)
                if (cellinfo_[i].multi != CELL_PART_OF_MULTICOLUMN)
@@ -685,9 +689,9 @@ void InsetMathGrid::metricsT(TextMetricsInfo const & mi, Dimension & dim) const
        rowinfo_[nrows()].descent = 0;
 
        // compute vertical offsets
-       rowinfo_[0].offset = 0;
+       rowinfo_[0].offset[&bv] = 0;
        for (row_type row = 1; row <= nrows(); ++row) {
-               rowinfo_[row].offset  =
+               rowinfo_[row].offset[&bv]  =
                        rowinfo_[row - 1].offset  +
                        rowinfo_[row - 1].descent +
                        //rowinfo_[row - 1].skipPixels(mi) +
@@ -751,6 +755,7 @@ void InsetMathGrid::metricsT(TextMetricsInfo const & mi, Dimension & dim) const
                       + rowinfo_[nrows() - 1].descent
                 //+ hlinesep() * rowinfo_[nrows()].lines
                       + 1;
+#endif
 }
 
 
@@ -935,9 +940,9 @@ int InsetMathGrid::cellXOffset(BufferView const & bv, idx_type idx) const
 }
 
 
-int InsetMathGrid::cellYOffset(idx_type idx) const
+int InsetMathGrid::cellYOffset(BufferView const & bv, idx_type idx) const
 {
-       return rowinfo_[row(idx)].offset;
+       return rowinfo_[row(idx)].offset[&bv];
 }
 
 
index 29f00fa179c58af01c8577c99a090de727742afa..a61439cfcd568bf685738ff730547e7ed666ff1f 100644 (file)
 #include "InsetMathNest.h"
 #include "Length.h"
 
+#include <map>
 
 namespace lyx {
 
 class BufferParams;
-
+class BufferView;
 
 /** Gridded math inset base class.
  *  This is the base to all grid-like editable math objects
@@ -59,8 +60,8 @@ public:
                mutable int descent;
                /// cached ascent
                mutable int ascent;
-               /// cached offset
-               mutable int offset;
+               /// cached offset for each bufferview
+               mutable std::map<BufferView const *, int> offset;
                /// how many hlines above this row?
                unsigned int lines;
                /// parameter to the line break
@@ -245,7 +246,7 @@ protected:
        /// returns x offset of cell compared to inset
        int cellXOffset(BufferView const &, idx_type idx) const;
        /// returns y offset of cell compared to inset
-       int cellYOffset(idx_type idx) const;
+       int cellYOffset(BufferView const &, idx_type idx) const;
        /// Width of cell, taking combined columns into account
        int cellWidth(idx_type idx) const;
        ///
@@ -277,7 +278,7 @@ protected:
 
        /// positions of vertical and horizontal lines
        int vLineHOffset(col_type col, unsigned int line) const;
-       int hLineVOffset(row_type row, unsigned int line) const;
+       int hLineVOffset(BufferView const &, row_type row, unsigned int line) const;
 
        ///
        InsetCode lyxCode() const { return MATH_GRID_CODE; }
index 79a56be6dd8dd30929b2fcbdfac07795d6da53c1..f95859bfe476a935542f3f9c54b797ea4037160f 100644 (file)
@@ -548,12 +548,39 @@ void InsetMathHull::metrics(MetricsInfo & mi, Dimension & dim) const
                return;
        }
 
-       Changer dummy1 = mi.base.changeFontSet(standardFont());
-       Changer dummy2 = mi.base.font.changeStyle(display() ? DISPLAY_STYLE
-                                                           : TEXT_STYLE);
+       {
+               Changer dummy1 = mi.base.changeFontSet(standardFont());
+               Changer dummy2 = mi.base.font.changeStyle(display() ? DISPLAY_STYLE
+                                                                                                 : TEXT_STYLE);
+
+               // let the cells adjust themselves
+               InsetMathGrid::metrics(mi, dim);
+       }
+
+       // Check whether the numbering interferes with the equations
+       if (numberedType()) {
+               BufferParams::MathNumber const math_number = buffer().params().getMathNumber();
+               int extra_offset = 0;
+               for (row_type row = 0; row < nrows(); ++row) {
+                       rowinfo(row).offset[mi.base.bv] += extra_offset;
+                       if (!numbered(row))
+                               continue;
+                       docstring const nl = nicelabel(row);
+                       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 >
+                       if ((math_number == BufferParams::LEFT && dimnl.wid >= x)
+                           || (math_number == BufferParams::RIGHT
+                               && dimnl.wid >= mi.base.textwidth - x - dim.wid)) {
+                               extra_offset += dimnl.height();
+                       }
+               }
+               dim.des += extra_offset;
+       }
 
-       // let the cells adjust themselves
-       InsetMathGrid::metrics(mi, dim);
 
        if (display()) {
                dim.asc += display_margin;
@@ -637,21 +664,32 @@ void InsetMathHull::draw(PainterInfo & pi, int x, int y) const
        }
 
        // First draw the numbers
+       if (!pi.full_repaint)
+               pi.pain.fillRectangle(pi.leftx, y - dim.asc,
+                                                         pi.rightx - pi.leftx, dim.height(),
+                                                         pi.background_color);
+
        ColorCode color = pi.selected && lyxrc.use_system_colors
                                ? Color_selectiontext : standardColor();
        bool const really_change_color = pi.base.font.color() == Color_none;
        Changer dummy0 = really_change_color ? pi.base.font.changeColor(color)
                : Changer();
-       if (pi.full_repaint && numberedType()) {
+       if (numberedType()) {
+               LATTEST(pi.leftx <pi.rightx);
                BufferParams::MathNumber const math_number = buffer().params().getMathNumber();
                for (row_type row = 0; row < nrows(); ++row) {
-                       int const yy = y + rowinfo(row).offset;
+                       int yy = y + rowinfo(row).offset[bv];
                        docstring const nl = nicelabel(row);
+                       Dimension dimnl;
+                       mathed_string_dim(pi.base.font, nl, dimnl);
                        if (math_number == BufferParams::LEFT) {
+                               if (dimnl.wid > x - pi.leftx)
+                                       yy += rowinfo(row).descent + dimnl.asc;
                                pi.draw(pi.leftx, yy, nl);
                        } else {
-                               int const l = mathed_string_width(pi.base.font, nl);
-                               pi.draw(pi.rightx - l, yy, nl);
+                               if (dimnl.wid > pi.rightx - x - dim.wid)
+                                       yy += rowinfo(row).descent + dimnl.asc;
+                               pi.draw(pi.rightx - dimnl.wid, yy, nl);
                        }
                }
        }