From ee0bd36a867a1e9a596571c14cfc6c3a46dc492d Mon Sep 17 00:00:00 2001 From: Jean-Marc Lasgouttes Date: Sun, 14 Jul 2019 21:04:45 +0200 Subject: [PATCH] Add empty rows to grid insets when numbers are too wide 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 | 45 ++++++++++++++++------------- src/mathed/InsetMathGrid.h | 11 +++---- src/mathed/InsetMathHull.cpp | 56 ++++++++++++++++++++++++++++++------ 3 files changed, 78 insertions(+), 34 deletions(-) diff --git a/src/mathed/InsetMathGrid.cpp b/src/mathed/InsetMathGrid.cpp index 496ba36bb5..9ba2dda197 100644 --- a/src/mathed/InsetMathGrid.cpp +++ b/src/mathed/InsetMathGrid.cpp @@ -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]; } diff --git a/src/mathed/InsetMathGrid.h b/src/mathed/InsetMathGrid.h index 29f00fa179..a61439cfcd 100644 --- a/src/mathed/InsetMathGrid.h +++ b/src/mathed/InsetMathGrid.h @@ -15,11 +15,12 @@ #include "InsetMathNest.h" #include "Length.h" +#include 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 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; } diff --git a/src/mathed/InsetMathHull.cpp b/src/mathed/InsetMathHull.cpp index 79a56be6dd..f95859bfe4 100644 --- a/src/mathed/InsetMathHull.cpp +++ b/src/mathed/InsetMathHull.cpp @@ -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 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); } } } -- 2.39.2