commit edb46d2a949c2832ab3b594fd0006f092ec0421c
Author: Jean-Marc Lasgouttes <lasgout...@lyx.org>
Date:   Fri Jan 11 15:55:17 2019 +0100

    Fix alignment of rows when text width is variable
    
    When several lines of text are in the same variable-width tabular
    cell, it is not possible to align properly the rows until the cell
    width is known.
    
    Therefore a parameter is added to redoParagraph to skip this
    computation, so that it can be done later in TextMetrics::metrics.
    Other calls to redoParagraph in the code are not affected. It is not
    clear at this point whether they may create artefacts.
    
    computeRowMetrics has been renamed to setRowAlignment to better
    reflect its use.
    
    Fixes bug #11447.
---
 src/TextMetrics.cpp       |   20 ++++++++++++++------
 src/TextMetrics.h         |    9 ++++-----
 src/insets/InsetSpace.cpp |    2 +-
 3 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp
index a106338..29c81da 100644
--- a/src/TextMetrics.cpp
+++ b/src/TextMetrics.cpp
@@ -182,13 +182,21 @@ bool TextMetrics::metrics(MetricsInfo & mi, Dimension & 
dim, int min_width,
        bool changed = false;
        unsigned int h = 0;
        for (pit_type pit = 0; pit != npar; ++pit) {
-               changed |= redoParagraph(pit);
+               // create rows, but do not set alignment yet
+               changed |= redoParagraph(pit, false);
                ParagraphMetrics const & pm = par_metrics_[pit];
                h += pm.height();
                if (dim_.wid < pm.width())
                        dim_.wid = pm.width();
        }
 
+       // Now set alignment for all rows (the width might not have been known 
before).
+       for (pit_type pit = 0; pit != npar; ++pit) {
+               ParagraphMetrics & pm = par_metrics_[pit];
+               for (Row & row : pm.rows())
+                       setRowAlignment(row, dim_.wid);
+       }
+
        dim_.asc = par_metrics_[0].ascent();
        dim_.des = h - dim_.asc;
        //lyxerr << "dim_.wid " << dim_.wid << endl;
@@ -354,7 +362,7 @@ bool TextMetrics::isRTLBoundary(pit_type pit, pos_type pos,
 }
 
 
-bool TextMetrics::redoParagraph(pit_type const pit)
+bool TextMetrics::redoParagraph(pit_type const pit, bool const align_rows)
 {
        Paragraph & par = text_->getPar(pit);
        // IMPORTANT NOTE: We pass 'false' explicitly in order to not call
@@ -474,14 +482,14 @@ bool TextMetrics::redoParagraph(pit_type const pit)
                        /* If there is more than one row or the row has been
                         * broken by a display inset or a newline, expand the 
text
                         * to the full allowable width. This setting here is
-                        * needed for the computeRowMetrics() below.
+                        * needed for the setRowAlignment() below.
                         * We do nothing when inside a table cell.
                         */
                        if (dim_.wid < max_width_)
                                dim_.wid = max_width_;
                }
-               int const max_row_width = max(dim_.wid, row.width());
-               computeRowMetrics(row, max_row_width);
+               if (align_rows)
+                       setRowAlignment(row, max(dim_.wid, row.width()));
                first = row.endpos();
                ++row_index;
 
@@ -588,7 +596,7 @@ LyXAlignment TextMetrics::getAlign(Paragraph const & par, 
Row const & row) const
 }
 
 
-void TextMetrics::computeRowMetrics(Row & row, int width) const
+void TextMetrics::setRowAlignment(Row & row, int width) const
 {
        row.label_hfill = 0;
        row.separator = 0;
diff --git a/src/TextMetrics.h b/src/TextMetrics.h
index 6802488..a4a1e23 100644
--- a/src/TextMetrics.h
+++ b/src/TextMetrics.h
@@ -97,7 +97,7 @@ public:
        /// Rebreaks the given paragraph.
        /// \retval true if a full screen redraw is needed.
        /// \retval false if a single paragraph redraw is enough.
-       bool redoParagraph(pit_type const pit);
+       bool redoParagraph(pit_type const pit, bool align_rows = true);
        /// Clear cache of paragraph metrics
        void clear() { par_metrics_.clear(); }
        /// Is cache of paragraph metrics empty ?
@@ -145,11 +145,10 @@ private:
        /// \return true when another row is required (after a newline)
        bool breakRow(Row & row, int right_margin) const;
 
-       // Expand the alignment of row \param row in paragraph \param par
+       // Expands the alignment of row \param row in paragraph \param par
        LyXAlignment getAlign(Paragraph const & par, Row const & row) const;
-       /** this calculates the specified parameters. needed when setting
-        * the cursor and when creating a visible row */
-       void computeRowMetrics(Row & row, int width) const;
+       /// Aligns properly the row contents (computes spaces and fills)
+       void setRowAlignment(Row & row, int width) const;
 
        /// Set the height of the row (without space above/below paragraph)
        void setRowHeight(Row & row) const;
diff --git a/src/insets/InsetSpace.cpp b/src/insets/InsetSpace.cpp
index ddb85b7..a5fed47 100644
--- a/src/insets/InsetSpace.cpp
+++ b/src/insets/InsetSpace.cpp
@@ -202,7 +202,7 @@ void InsetSpace::metrics(MetricsInfo & mi, Dimension & dim) 
const
 {
        if (isHfill()) {
                // The width for hfills is calculated externally in
-               // TextMetrics::computeRowMetrics. The value of 5 is the
+               // TextMetrics::setRowAlignment. The value of 5 is the
                // minimal value when the hfill is not active.
                dim = Dimension(5, 10, 10);
                return;

Reply via email to