]> git.lyx.org Git - features.git/commitdiff
Fix alignment of rows when text width is variable
authorJean-Marc Lasgouttes <lasgouttes@lyx.org>
Fri, 11 Jan 2019 14:55:17 +0000 (15:55 +0100)
committerJean-Marc Lasgouttes <lasgouttes@lyx.org>
Fri, 11 Jan 2019 15:23:05 +0000 (16:23 +0100)
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
src/TextMetrics.h
src/insets/InsetSpace.cpp

index a10633842189cae9284d969b4ccdc7b54455bce9..29c81da8bd65c09bf5608abb6532d6973a280e14 100644 (file)
@@ -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;
index 68024884a37212d5f99a475084ccbb1e474b2cc4..a4a1e23740871b933367a3efaf3cecf1f0f9d26c 100644 (file)
@@ -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;
index ddb85b71ea6b4ca69d69a50f06383fc7400a4599..a5fed47fbfec5f27896ac344a847f298e8b22186 100644 (file)
@@ -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;