This patch is part of ticket:
http://www.lyx.org/trac/ticket/9860

Consider the file newfile1.lyx in attachment.

The length of hfills is not computed correctly, since the minimal size of each hfill is forgotten. Basically, a 'wid = hfill' has to be replaced by a 'wid += hfill'. The rest of the patch is refactoring and also taking care of good rounding.

There are other problems in ticket 9860, but I think they'll have to wait until after 2.2 is out.

Can I commit this first patch?

JMarc
>From 91b5414ad4beaf5cb85b501689cd591ba62219d1 Mon Sep 17 00:00:00 2001
From: Jean-Marc Lasgouttes <lasgout...@lyx.org>
Date: Fri, 13 Nov 2015 10:57:26 +0100
Subject: [PATCH] Fix length of hfills

The computation of the legth of expanded hfills did not take into account their unexpanded size. This is done now by increasing the dimension (+=) instead of merely setting it.

Moreover, since the insets sizes are integer number, rounding effects have to be taken in account. To this end, the extra number of pixels is added to the last hfill in the row.

This fixes part of bug #9860.

Note not everything is fixed by this patch: the logic of ParagraphMetrics::hfillExpansion seems bogus to me. I do not see why consecutive hfills at the beginning of a row should not be all expanded. Since I do not know what are the peculiarities of hfill handling in LaTeX, I did not change it (yet).

I did not either try to investigate the label hfill part, because I do not even know what is so special about it. I think there is a lot of old logic that nobody ever tried to question.
---
 src/ParagraphMetrics.cpp  |    1 +
 src/TextMetrics.cpp       |   34 +++++++++++++++++++++-------------
 src/insets/InsetSpace.cpp |    2 +-
 3 files changed, 23 insertions(+), 14 deletions(-)

diff --git a/src/ParagraphMetrics.cpp b/src/ParagraphMetrics.cpp
index 9a9ecf0..ad217cf 100644
--- a/src/ParagraphMetrics.cpp
+++ b/src/ParagraphMetrics.cpp
@@ -194,6 +194,7 @@ int ParagraphMetrics::rightMargin(BufferView const & bv) const
 }
 
 
+// FIXME: this code seems bogus. Audit and rewrite (see bug #9860).
 bool ParagraphMetrics::hfillExpansion(Row const & row, pos_type pos) const
 {
 	if (!par_->isHfill(pos))
diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp
index 1a033d5..ee101b3 100644
--- a/src/TextMetrics.cpp
+++ b/src/TextMetrics.cpp
@@ -584,15 +584,19 @@ void TextMetrics::computeRowMetrics(pit_type const pit,
 			row.label_hfill = labelFill(pit, row) / double(nlh);
 	}
 
-	double hfill = 0;
 	// are there any hfills in the row?
-	if (int const nh = numberOfHfills(row, par.beginOfBody())) {
-		if (w > 0)
-			hfill = double(w) / nh;
-	// we don't have to look at the alignment if it is ALIGN_LEFT and
-	// if the row is already larger then the permitted width as then
-	// we force the LEFT_ALIGN'edness!
-	} else if (int(row.width()) < max_width_) {
+	int nh = numberOfHfills(row, par.beginOfBody());
+	int hfill = 0;
+	int hfill_rem = 0;
+
+	// We don't have to look at the alignment if
+	// * we use hfills, or
+	// * the row is already larger then the permitted width as then we
+	//   force the LEFT_ALIGN'edness!
+	if (nh > 0) {
+		hfill = w / nh;
+		hfill_rem = w % nh;
+	} else if (nh == 0 && int(row.width()) < max_width_) {
 		// is it block, flushleft or flushright?
 		// set x how you need it
 		switch (getAlign(par, row)) {
@@ -641,11 +645,15 @@ void TextMetrics::computeRowMetrics(pit_type const pit,
 			cit->dim.wid -= int(row.label_hfill * (nlh - 1));
 		if (!cit->inset || !cit->inset->isHfill())
 			continue;
-		if (pm.hfillExpansion(row, cit->pos))
-			cit->dim.wid = int(cit->pos >= body_pos ?
-					   max(hfill, 5.0) : row.label_hfill);
-		else
-			cit->dim.wid = 5;
+		if (pm.hfillExpansion(row, cit->pos)) {
+			if (cit->pos >= body_pos) {
+				cit->dim.wid += hfill;
+				--nh;
+				if (nh == 0)
+					cit->dim.wid += hfill_rem;
+			} else
+				cit->dim.wid += int(row.label_hfill);
+		}
 		// Cache the inset dimension.
 		insetCache.add(cit->inset, cit->dim);
 	}
diff --git a/src/insets/InsetSpace.cpp b/src/insets/InsetSpace.cpp
index b8cab16..1df121b 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 metrics for this kinds are calculated externally in
 		// \c TextMetrics::computeRowMetrics. Those are dummy value:
-		dim = Dimension(10, 10, 10);
+		dim = Dimension(5, 10, 10);
 		return;
 	}
 
-- 
1.7.9.5

Attachment: newfile1.lyx
Description: application/lyx

Reply via email to