-int LyXText::rightMargin(Paragraph const & par) const
-{
- // FIXME: the correct way is to only call rightMargin() only
- // within the main LyXText. The following test is thus bogus.
- LyXText const & text = bv()->buffer()->text();
- // We do not want rightmargins on inner texts.
- if (&text != this)
- return 0;
-
- BufferParams const & params = bv()->buffer()->params();
- LyXTextClass const & tclass = params.getLyXTextClass();
- string trmarg = tclass.rightmargin();
- docstring dtrmarg(trmarg.begin(), trmarg.end());
- string lrmarg = par.layout()->rightmargin;
- docstring dlrmarg(lrmarg.begin(), lrmarg.end());
- int const r_margin =
- ::rightMargin()
- + font_metrics::signedWidth(dtrmarg,
- params.getFont())
- + font_metrics::signedWidth(dlrmarg,
- params.getFont())
- * 4 / (par.getDepth() + 4);
-
- return r_margin;
-}
-
-
-int LyXText::labelEnd(pit_type const pit) const
-{
- // labelEnd is only needed if the layout fills a flushleft label.
- if (pars_[pit].layout()->margintype != MARGIN_MANUAL)
- return 0;
- // return the beginning of the body
- return leftMargin(pit);
-}
-
-
-namespace {
-
-// this needs special handling - only newlines count as a break point
-pos_type addressBreakPoint(pos_type i, Paragraph const & par)
-{
- pos_type const end = par.size();
-
- for (; i < end; ++i)
- if (par.isNewline(i))
- return i + 1;
-
- return end;
-}
-
-};
-
-
-void LyXText::rowBreakPoint(pit_type const pit, Row & row) const
-{
- Paragraph const & par = pars_[pit];
- pos_type const end = par.size();
- pos_type const pos = row.pos();
- if (pos == end) {
- row.endpos(end);
- return;
- }
-
- // maximum pixel width of a row
- int width = maxwidth_ - rightMargin(par); // - leftMargin(pit, row);
- if (width < 0) {
- row.endpos(end);
- return;
- }
-
- LyXLayout_ptr const & layout = par.layout();
-
- if (layout->margintype == MARGIN_RIGHT_ADDRESS_BOX) {
- row.endpos(addressBreakPoint(pos, par));
- return;
- }
-
- pos_type const body_pos = par.beginOfBody();
-
-
- // Now we iterate through until we reach the right margin
- // or the end of the par, then choose the possible break
- // nearest that.
-
- int const left = leftMargin(pit, pos);
- int x = left;
-
- // pixel width since last breakpoint
- int chunkwidth = 0;
-
- FontIterator fi = FontIterator(*this, par, pos);
- pos_type point = end;
- pos_type i = pos;
- for ( ; i < end; ++i, ++fi) {
- char_type const c = par.getChar(i);
- int thiswidth = singleWidth(par, i, c, *fi);
-
- // add the auto-hfill from label end to the body
- if (body_pos && i == body_pos) {
- string lsep = layout->labelsep;
- docstring dlsep(lsep.begin(), lsep.end());
- int add = font_metrics::width(dlsep, getLabelFont(par));
- if (par.isLineSeparator(i - 1))
- add -= singleWidth(par, i - 1);
-
- add = std::max(add, labelEnd(pit) - x);
- thiswidth += add;
- }
-
- x += thiswidth;
- chunkwidth += thiswidth;
-
- // break before a character that will fall off
- // the right of the row
- if (x >= width) {
- // if no break before, break here
- if (point == end || chunkwidth >= width - left) {
- if (i > pos)
- point = i;
- else
- point = i + 1;
-
- }
- // exit on last registered breakpoint:
- break;
- }
-
- if (par.isNewline(i)) {
- point = i + 1;
- break;
- }
- // Break before...
- if (i + 1 < end) {
- if (par.isInset(i + 1) && par.getInset(i + 1)->display()) {
- point = i + 1;
- break;
- }
- // ...and after.
- if (par.isInset(i) && par.getInset(i)->display()) {
- point = i + 1;
- break;
- }
- }
-
- if (!par.isInset(i) || par.getInset(i)->isChar()) {
- // some insets are line separators too
- if (par.isLineSeparator(i)) {
- // register breakpoint:
- point = i + 1;
- chunkwidth = 0;
- }
- }
- }
-
- // maybe found one, but the par is short enough.
- if (i == end && x < width)
- point = end;
-
- // manual labels cannot be broken in LaTeX. But we
- // want to make our on-screen rendering of footnotes
- // etc. still break
- if (body_pos && point < body_pos)
- point = body_pos;
-
- row.endpos(point);
-}
-
-
-void LyXText::setRowWidth(pit_type const pit, Row & row) const
-{
- // get the pure distance
- pos_type const end = row.endpos();
-
- Paragraph const & par = pars_[pit];
- string const & labelsep = par.layout()->labelsep;
- docstring dlsep(labelsep.begin(), labelsep.end());
- int w = leftMargin(pit, row.pos());
-
- pos_type const body_pos = par.beginOfBody();
- pos_type i = row.pos();
-
- if (i < end) {
- FontIterator fi = FontIterator(*this, par, i);
- for ( ; i < end; ++i, ++fi) {
- if (body_pos > 0 && i == body_pos) {
- w += font_metrics::width(dlsep, getLabelFont(par));
- if (par.isLineSeparator(i - 1))
- w -= singleWidth(par, i - 1);
- w = max(w, labelEnd(pit));
- }
- char_type const c = par.getChar(i);
- w += singleWidth(par, i, c, *fi);
- }
- }
-
- if (body_pos > 0 && body_pos >= end) {
- w += font_metrics::width(dlsep, getLabelFont(par));
- if (end > 0 && par.isLineSeparator(end - 1))
- w -= singleWidth(par, end - 1);
- w = max(w, labelEnd(pit));
- }
-
- row.width(w + rightMargin(par));
-}
-
-
-// returns the minimum space a manual label needs on the screen in pixel
-int LyXText::labelFill(Paragraph const & par, Row const & row) const
-{
- pos_type last = par.beginOfBody();
-
- BOOST_ASSERT(last > 0);
-
- // -1 because a label ends with a space that is in the label
- --last;
-
- // a separator at this end does not count
- if (par.isLineSeparator(last))
- --last;
-
- int w = 0;
- for (pos_type i = row.pos(); i <= last; ++i)
- w += singleWidth(par, i);
-
- string const & label = par.params().labelWidthString();
- if (label.empty())
- return 0;
-
- docstring dlab(label.begin(), label.end());
- return max(0, font_metrics::width(dlab, getLabelFont(par)) - w);
-}
-
-