return n;
}
-
-int numberOfHfills(Row const & row, pos_type const body_pos)
+// FIXME: this needs to be rewritten, probably by merging it into some
+// code that, besides counting, sets the active status of the space
+// inset in the row element.
+int numberOfHfills(Row const & row, ParagraphMetrics const & pm,
+ pos_type const body_pos)
{
int n = 0;
Row::const_iterator cit = row.begin();
Row::const_iterator const end = row.end();
for ( ; cit != end ; ++cit)
if (cit->pos >= body_pos
- && cit->inset && cit->inset->isHfill())
+ && cit->inset && pm.hfillExpansion(row, cit->pos))
++n;
return n;
}
}
-LyXAlignment TextMetrics::getAlign(Paragraph const & par, pos_type const pos) const
+LyXAlignment TextMetrics::getAlign(Paragraph const & par, Row const & row) const
{
Layout const & layout = par.layout();
// handle alignment inside tabular cells
Inset const & owner = text_->inset();
+ bool forced_block = false;
switch (owner.contentAlignment()) {
+ case LYX_ALIGN_BLOCK:
+ // In general block align is the default state, but here it is
+ // an explicit choice. Therefore it should not be overridden
+ // later.
+ forced_block = true;
+ // fall through
case LYX_ALIGN_CENTER:
case LYX_ALIGN_LEFT:
case LYX_ALIGN_RIGHT:
}
// Display-style insets should always be on a centered row
- if (Inset const * inset = par.getInset(pos)) {
+ if (Inset const * inset = par.getInset(row.pos())) {
switch (inset->display()) {
case Inset::AlignLeft:
align = LYX_ALIGN_BLOCK;
}
}
- // Has the user requested we not justify stuff?
- if (!bv_->buffer().params().justification
- && align == LYX_ALIGN_BLOCK)
- align = LYX_ALIGN_LEFT;
+ if (align == LYX_ALIGN_BLOCK) {
+ // If this row has been broken abruptly by a display inset, or
+ // it is the end of the paragraph, or the user requested we
+ // not justify stuff, then don't stretch.
+ // A forced block alignment can only be overridden the 'no
+ // justification on screen' setting.
+ if (((row.right_boundary() || row.endpos() == par.size())
+ && !forced_block)
+ || !bv_->buffer().params().justification)
+ align = text_->isRTL(par) ? LYX_ALIGN_RIGHT : LYX_ALIGN_LEFT;
+ }
return align;
}
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_) {
- // is it block, flushleft or flushright?
- // set x how you need it
- switch (getAlign(par, row.pos())) {
+ ParagraphMetrics & pm = par_metrics_[pit];
+ int nh = numberOfHfills(row, pm, par.beginOfBody());
+ int hfill = 0;
+ int hfill_rem = 0;
+
+ // We don't have to look at the alignment if the row is already
+ // larger then the permitted width as then we force the
+ // LEFT_ALIGN'edness!
+ if (int(row.width()) >= max_width_)
+ return;
+
+ if (nh == 0) {
+ // Common case : there is no hfill, and the alignment will be
+ // meaningful
+ switch (getAlign(par, row)) {
case LYX_ALIGN_BLOCK: {
int const ns = row.countSeparators();
- /** If we have separators, and this row has
- * not be broken abruptly by a display inset
- * or newline, then stretch it */
- if (ns && !row.right_boundary()
- && row.endpos() != par.size()) {
+ // If we have separators, then stretch the row
+ if (ns) {
row.setSeparatorExtraWidth(double(w) / ns);
- row.dimension().wid = width;
+ row.dimension().wid += w;
} else if (text_->isRTL(par)) {
- row.dimension().wid = width;
row.left_margin += w;
+ row.dimension().wid += w;
}
break;
}
row.dimension().wid += w;
break;
case LYX_ALIGN_CENTER:
- row.dimension().wid = width - w / 2;
+ row.dimension().wid += w / 2;
row.left_margin += w / 2;
break;
case LYX_ALIGN_LEFT:
case LYX_ALIGN_DECIMAL:
break;
}
+ return;
}
- // Finally, handle hfill insets
+ hfill = w / nh;
+ hfill_rem = w % nh;
+ row.dimension().wid += w;
+ // Set size of hfill insets
pos_type const endpos = row.endpos();
pos_type body_pos = par.beginOfBody();
if (body_pos > 0
&& (body_pos > endpos || !par.isLineSeparator(body_pos - 1)))
body_pos = 0;
- ParagraphMetrics & pm = par_metrics_[pit];
+
CoordCache::Insets & insetCache = bv_->coordCache().insets();
Row::iterator cit = row.begin();
Row::iterator const cend = row.end();
if (row.label_hfill && cit->endpos == body_pos
&& cit->type == Row::SPACE)
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;
- // Cache the inset dimension.
- insetCache.add(cit->inset, cit->dim);
+ if (cit->inset && 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);
+ }
}
}
rp.paintLast();
if (i == 0 && is_rtl)
rp.paintFirst();
- rp.paintTooLargeMarks(row_x < 0,
- row_x + row.width() > bv_->workWidth());
+ rp.paintTooLargeMarks(row_x + row.left_x() < 0,
+ row_x + row.right_x() > bv_->workWidth());
y += row.descent();
// Restore full_repaint status.