Fix computation of LABEL_MANUAL label separation

The spacing of Labeling, Description and friends shall be computed
when breaking the row, not when tokenizing it. Indeed, this is the
right place to determine its correct value.

To this end add a new MARGINSPACE row element type.

This allows to remove TextMetrics::labelEnd, which is not used anymore.
This commit is contained in:
Jean-Marc Lasgouttes 2022-01-17 11:58:49 +01:00
parent c638caddd8
commit 4f158ecfc8
5 changed files with 31 additions and 23 deletions

View File

@ -114,6 +114,7 @@ pos_type Row::Element::x2pos(int &x) const
break;
case INSET:
case SPACE:
case MARGINSPACE:
// those elements contain only one position. Round to
// the closest side.
if (x > (full_width() + 1) / 2) {
@ -313,6 +314,9 @@ ostream & operator<<(ostream & os, Row::Element const & e)
break;
case Row::SPACE:
os << "SPACE: ";
break;
case Row::MARGINSPACE:
os << "MARGINSPACE: ";
}
os << "width=" << e.full_width() << ", row_flags=" << e.row_flags;
return os;
@ -498,6 +502,18 @@ void Row::addSpace(pos_type const pos, int const width,
}
void Row::addMarginSpace(pos_type const pos, int const width,
Font const & f, Change const & ch)
{
finalizeLast();
Element e(MARGINSPACE, pos, f, ch);
e.dim.wid = width;
e.row_flags = NoBreakBefore;
elements_.push_back(e);
dim_.wid += e.dim.wid;
}
void Row::push_back(Row::Element const & e)
{
dim_.wid += e.dim.wid;

View File

@ -50,7 +50,10 @@ public:
// An inset
INSET,
// Some spacing described by its width, not a string
SPACE
SPACE,
// Spacing until the left margin, with a minimal value given
// by the initial width
MARGINSPACE
};
/**
@ -253,6 +256,8 @@ public:
Font const & f, Change const & ch);
///
void addSpace(pos_type pos, int width, Font const & f, Change const & ch);
///
void addMarginSpace(pos_type pos, int width, Font const & f, Change const & ch);
///
typedef std::vector<Element> Elements;

View File

@ -564,6 +564,7 @@ void RowPainter::paintText()
break;
case Row::SPACE:
case Row::MARGINSPACE:
paintTextDecoration(e);
}

View File

@ -786,15 +786,6 @@ int TextMetrics::labelFill(Row const & row) const
}
int TextMetrics::labelEnd(pit_type const pit) const
{
// labelEnd is only needed if the layout fills a flushleft label.
if (text_->getPar(pit).layout().margintype != MARGIN_MANUAL)
return 0;
// return the beginning of the body
return leftMargin(pit);
}
namespace {
/**
@ -901,16 +892,12 @@ Row TextMetrics::tokenizeParagraph(pit_type const pit) const
Dimension dim = bv_->coordCache().insets().dim(ins);
row.add(i, ins, dim, *fi, par.lookupChange(i));
} else if (c == ' ' && i + 1 == body_pos) {
// There is a space at i, but it should not be
// added as a separator, because it is just
// before body_pos. Instead, insert some spacing to
// align text
// This space is an \item separator. Represent it with a
// special space element, which dimension will be computed
// in breakRow.
FontMetrics const & fm = theFontMetrics(text_->labelFont(par));
// this is needed to make sure that the row width is correct
row.finalizeLast();
int const add = max(fm.width(par.layout().labelsep),
labelEnd(pit) - row.width());
row.addSpace(i, add, *fi, par.lookupChange(i));
int const wid = fm.width(par.layout().labelsep);
row.addMarginSpace(i, wid, *fi, par.lookupChange(i));
} else if (c == '\t')
row.addSpace(i, theFontMetrics(*fi).width(from_ascii(" ")),
*fi, par.lookupChange(i));
@ -920,7 +907,7 @@ Row TextMetrics::tokenizeParagraph(pit_type const pit) const
* U+2029 PARAGRAPH SEPARATOR
* These are special unicode characters that break
* lines/pragraphs. Not handling them lead to trouble wrt
* lines/pragraphs. Not handling them leads to trouble wrt
* Qt QTextLayout formatting. We add a visible character
* on screen so that the user can see that something is
* happening.
@ -1139,6 +1126,8 @@ RowList TextMetrics::breakParagraph(Row const & bigrow) const
Row::Elements tail;
elt.splitAt(width - rows.back().width(), next_width, false, tail);
Row & rb = rows.back();
if (elt.type == Row::MARGINSPACE)
elt.dim.wid = max(elt.dim.wid, leftMargin(bigrow.pit()) - rb.width());
rb.push_back(elt);
rb.finalizeLast();
if (rb.width() > width) {

View File

@ -148,9 +148,6 @@ private:
/// the minimum space a manual label needs on the screen in pixels
int labelFill(Row const & row) const;
/// FIXME??
int labelEnd(pit_type const pit) const;
// Turn paragraph oh index \c pit into a single row
Row tokenizeParagraph(pit_type pit) const;