mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-12-22 21:21:32 +00:00
Store in the Row object the list of elements it contains
* Row now contains a vector of Elements * replace Row::dump by a proper << operator * the width is updated as elements are added * breakRow is reimplmented to use this infrastructure
This commit is contained in:
parent
8539f756ed
commit
452fb60359
@ -8,18 +8,13 @@ What is done:
|
|||||||
setRowHeight instead of rowBreakPoint and rowHeight.
|
setRowHeight instead of rowBreakPoint and rowHeight.
|
||||||
|
|
||||||
* change breakRow operation to operate on text strings on which
|
* change breakRow operation to operate on text strings on which
|
||||||
metrics are computed. Note that for now
|
metrics are computed. The list of elements is stored in the row object
|
||||||
FontMetrics::width(docstring) still computes the sum of character
|
|
||||||
widths, so that behavior is unchanged.
|
|
||||||
|
|
||||||
* Implement proper string metrics computation (with cache), when
|
* Implement proper string metrics computation (with cache), when
|
||||||
lyxrc.force_paint_single_char is false.
|
lyxrc.force_paint_single_char is false.
|
||||||
|
|
||||||
Next steps:
|
Next steps:
|
||||||
|
|
||||||
* Make breakRow build a list of elements (string, inset,
|
|
||||||
separator,...) in the row. This will be reused by other methods
|
|
||||||
|
|
||||||
* get rid of rowWidth (breakRow does compute this)
|
* get rid of rowWidth (breakRow does compute this)
|
||||||
|
|
||||||
* re-implement getColumnNearX using row elements
|
* re-implement getColumnNearX using row elements
|
||||||
@ -37,4 +32,9 @@ point. This will not be useful anymore with horizontal scrolling.
|
|||||||
actual text, not default font. This will be extended to the other
|
actual text, not default font. This will be extended to the other
|
||||||
methods.
|
methods.
|
||||||
|
|
||||||
The other differences should be considered as bugs.
|
Other differences that should be considered as bugs
|
||||||
|
* there are still some difference in width computation wrt
|
||||||
|
TextMetrics::rowWidth. This happens in particular with Description
|
||||||
|
environment when the row is broken at bodypos. The method rowWidth
|
||||||
|
is kept for now in order to be able to detect row parsing errors,
|
||||||
|
but it could be removed right now.
|
||||||
|
@ -190,8 +190,7 @@ void ParagraphMetrics::dump() const
|
|||||||
{
|
{
|
||||||
lyxerr << "Paragraph::dump: rows.size(): " << rows_.size() << endl;
|
lyxerr << "Paragraph::dump: rows.size(): " << rows_.size() << endl;
|
||||||
for (size_t i = 0; i != rows_.size(); ++i) {
|
for (size_t i = 0; i != rows_.size(); ++i) {
|
||||||
lyxerr << " row " << i << ": ";
|
lyxerr << " row " << i << ": " << rows_[i];
|
||||||
rows_[i].dump();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
154
src/Row.cpp
154
src/Row.cpp
@ -20,8 +20,13 @@
|
|||||||
|
|
||||||
#include "DocIterator.h"
|
#include "DocIterator.h"
|
||||||
|
|
||||||
|
#include "frontends/FontMetrics.h"
|
||||||
|
|
||||||
#include "support/debug.h"
|
#include "support/debug.h"
|
||||||
|
|
||||||
|
#include <ostream>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
namespace lyx {
|
namespace lyx {
|
||||||
|
|
||||||
@ -116,14 +121,151 @@ bool Row::selection() const
|
|||||||
return sel_beg != -1 && sel_end != -1;
|
return sel_beg != -1 && sel_end != -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ostream & operator<<(ostream & os, Row const & row)
|
||||||
void Row::dump(char const * s) const
|
|
||||||
{
|
{
|
||||||
LYXERR0(s << " pos: " << pos_ << " end: " << end_
|
os << " pos: " << row.pos_ << " end: " << row.end_
|
||||||
<< " width: " << dim_.wid
|
<< " width: " << row.dim_.wid
|
||||||
<< " ascent: " << dim_.asc
|
<< " ascent: " << row.dim_.asc
|
||||||
<< " descent: " << dim_.des);
|
<< " descent: " << row.dim_.des << "\n";
|
||||||
|
Row::Elements::const_iterator it = row.elements_.begin();
|
||||||
|
for ( ; it != row.elements_.end() ; ++it) {
|
||||||
|
switch (it->type) {
|
||||||
|
case Row::Element::STRING_ELT:
|
||||||
|
os << "**STRING: " << to_utf8(it->str) << endl;
|
||||||
|
break;
|
||||||
|
case Row::Element::INSET_ELT:
|
||||||
|
os << "**INSET: " << to_utf8(it->inset->layoutName()) << endl;
|
||||||
|
break;
|
||||||
|
case Row::Element::SEPARATOR_ELT:
|
||||||
|
os << "**SEPARATOR: " << endl;
|
||||||
|
break;
|
||||||
|
case Row::Element::SPACE_ELT:
|
||||||
|
os << "**SPACE: " << it->dim.wid << endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Row::sameString(Font const & f, Change const & ch) const
|
||||||
|
{
|
||||||
|
if (elements_.empty())
|
||||||
|
return false;
|
||||||
|
Element const & elt = elements_.back();
|
||||||
|
return elt.type == Element::STRING_ELT && !elt.final
|
||||||
|
&& elt.font == f && elt.change == ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Row::finalizeLast()
|
||||||
|
{
|
||||||
|
if (elements_.empty())
|
||||||
|
return;
|
||||||
|
Element & elt = elements_.back();
|
||||||
|
if (elt.final)
|
||||||
|
return;
|
||||||
|
elt.final = true;
|
||||||
|
|
||||||
|
if (elt.type == Element::STRING_ELT) {
|
||||||
|
elt.dim.wid = theFontMetrics(elt.font).width(elt.str);
|
||||||
|
dim_.wid += elt.dim.wid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Row::add(pos_type const pos, Inset const * ins, Dimension const & dim)
|
||||||
|
{
|
||||||
|
finalizeLast();
|
||||||
|
Element e(Element::INSET_ELT);
|
||||||
|
e.pos = pos;
|
||||||
|
e.inset = ins;
|
||||||
|
e.dim = dim;
|
||||||
|
elements_.push_back(e);
|
||||||
|
dim_.wid += dim.wid;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Row::add(pos_type const pos, docstring const & s,
|
||||||
|
Font const & f, Change const & ch)
|
||||||
|
{
|
||||||
|
if (sameString(f, ch))
|
||||||
|
elements_.back().str += s;
|
||||||
|
else {
|
||||||
|
finalizeLast();
|
||||||
|
Element e(Element::STRING_ELT);
|
||||||
|
e.pos = pos;
|
||||||
|
e.str = s;
|
||||||
|
e.font = f;
|
||||||
|
e.change = ch;
|
||||||
|
elements_.push_back(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Row::add(pos_type const pos, char_type const c,
|
||||||
|
Font const & f, Change const & ch)
|
||||||
|
{
|
||||||
|
add(pos, docstring(1,c), f, ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Row::addSeparator(pos_type const pos, char_type const c,
|
||||||
|
Font const & f, Change const & ch)
|
||||||
|
{
|
||||||
|
finalizeLast();
|
||||||
|
Element e(Element::SEPARATOR_ELT);
|
||||||
|
e.pos = pos;
|
||||||
|
e.str += c;
|
||||||
|
e.font = f;
|
||||||
|
e.change = ch;
|
||||||
|
e.dim.wid = theFontMetrics(f).width(c);
|
||||||
|
elements_.push_back(e);
|
||||||
|
dim_.wid += e.dim.wid;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Row::addSpace(pos_type pos, int width)
|
||||||
|
{
|
||||||
|
finalizeLast();
|
||||||
|
Element e(Element::SEPARATOR_ELT);
|
||||||
|
e.pos = pos;
|
||||||
|
e.dim.wid = width;
|
||||||
|
elements_.push_back(e);
|
||||||
|
dim_.wid += e.dim.wid;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Row::pop_back()
|
||||||
|
{
|
||||||
|
dim_.wid -= elements_.back().dim.wid;
|
||||||
|
elements_.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Row::separate_back(pos_type const keep)
|
||||||
|
{
|
||||||
|
if (empty())
|
||||||
|
return;
|
||||||
|
int i = elements_.size();
|
||||||
|
int new_end = end_;
|
||||||
|
int new_wid = dim_.wid;
|
||||||
|
if (i > 0 && elements_[i - 1].isLineSeparator() && new_end > keep) {
|
||||||
|
--i;
|
||||||
|
new_end = elements_[i].pos;
|
||||||
|
new_wid -= elements_[i].dim.wid;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (i > 0 && !elements_[i - 1].isLineSeparator() && new_end > keep) {
|
||||||
|
--i;
|
||||||
|
new_end = elements_[i].pos;
|
||||||
|
new_wid -= elements_[i].dim.wid;
|
||||||
|
}
|
||||||
|
if (i == 0)
|
||||||
|
return;
|
||||||
|
end_ = new_end;
|
||||||
|
dim_.wid = new_wid;
|
||||||
|
elements_.erase(elements_.begin() + i, elements_.end());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace lyx
|
} // namespace lyx
|
||||||
|
98
src/Row.h
98
src/Row.h
@ -15,14 +15,19 @@
|
|||||||
#ifndef ROW_H
|
#ifndef ROW_H
|
||||||
#define ROW_H
|
#define ROW_H
|
||||||
|
|
||||||
|
#include "Changes.h"
|
||||||
|
#include "Dimension.h"
|
||||||
|
#include "Font.h"
|
||||||
|
|
||||||
|
#include "support/docstring.h"
|
||||||
#include "support/types.h"
|
#include "support/types.h"
|
||||||
|
|
||||||
#include "Dimension.h"
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
namespace lyx {
|
namespace lyx {
|
||||||
|
|
||||||
class DocIterator;
|
class DocIterator;
|
||||||
|
class Inset;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An on-screen row of text. A paragraph is broken into a
|
* An on-screen row of text. A paragraph is broken into a
|
||||||
@ -31,6 +36,45 @@ class DocIterator;
|
|||||||
*/
|
*/
|
||||||
class Row {
|
class Row {
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* One element of a Row. It has a set of attributes that can be used
|
||||||
|
* by other methods that need to parse the Row contents.
|
||||||
|
*/
|
||||||
|
struct Element {
|
||||||
|
enum Type {
|
||||||
|
STRING_ELT,
|
||||||
|
SEPARATOR_ELT,
|
||||||
|
INSET_ELT,
|
||||||
|
SPACE_ELT
|
||||||
|
};
|
||||||
|
|
||||||
|
Element(Type const t) : type(t), pos(0), inset(0),
|
||||||
|
final(false) {}
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isLineSeparator() const { return type == SEPARATOR_ELT; }
|
||||||
|
|
||||||
|
// The kind of row element
|
||||||
|
Type type;
|
||||||
|
// position of the element in the paragraph
|
||||||
|
pos_type pos;
|
||||||
|
// The dimension of the chunk (only width for strings)
|
||||||
|
Dimension dim;
|
||||||
|
|
||||||
|
// Non-zero if element is an inset
|
||||||
|
Inset const * inset;
|
||||||
|
|
||||||
|
// Non-empty if element is a string or separator
|
||||||
|
docstring str;
|
||||||
|
// is it possible to add contents to this element?
|
||||||
|
bool final;
|
||||||
|
//
|
||||||
|
Font font;
|
||||||
|
//
|
||||||
|
Change change;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
Row();
|
Row();
|
||||||
///
|
///
|
||||||
@ -73,6 +117,44 @@ public:
|
|||||||
///
|
///
|
||||||
int descent() const { return dim_.des; }
|
int descent() const { return dim_.des; }
|
||||||
|
|
||||||
|
///
|
||||||
|
void add(pos_type pos, Inset const * ins, Dimension const & dim);
|
||||||
|
///
|
||||||
|
void add(pos_type pos, docstring const & s,
|
||||||
|
Font const & f, Change const & ch);
|
||||||
|
///
|
||||||
|
void add(pos_type pos, char_type const c,
|
||||||
|
Font const & f, Change const & ch);
|
||||||
|
///
|
||||||
|
void addSeparator(pos_type pos, char_type const c,
|
||||||
|
Font const & f, Change const & ch);
|
||||||
|
///
|
||||||
|
void addSpace(pos_type pos, int width);
|
||||||
|
///
|
||||||
|
bool empty() const { return elements_.empty(); }
|
||||||
|
///
|
||||||
|
Element & back() { return elements_.back(); }
|
||||||
|
///
|
||||||
|
Element const & back() const { return elements_.back(); }
|
||||||
|
/// remove last element
|
||||||
|
void pop_back();
|
||||||
|
/// remove all row elements
|
||||||
|
void clear() { elements_.clear(); }
|
||||||
|
/**
|
||||||
|
* remove all elements after last separator and update endpos
|
||||||
|
* if necessary.
|
||||||
|
* \param keep is the minimum amount of text to keep.
|
||||||
|
*/
|
||||||
|
void separate_back(pos_type keep);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If last element of the row is a string, compute its width
|
||||||
|
* and mark it final.
|
||||||
|
*/
|
||||||
|
void finalizeLast();
|
||||||
|
|
||||||
|
friend std::ostream & operator<<(std::ostream & os, Row const & row);
|
||||||
|
|
||||||
/// current debugging only
|
/// current debugging only
|
||||||
void dump(char const * = "") const;
|
void dump(char const * = "") const;
|
||||||
|
|
||||||
@ -101,6 +183,18 @@ private:
|
|||||||
bool isMarginSelected(bool left_margin, DocIterator const & beg,
|
bool isMarginSelected(bool left_margin, DocIterator const & beg,
|
||||||
DocIterator const & end) const;
|
DocIterator const & end) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if a char or string with font \c f and change
|
||||||
|
* type \c ch can be added to the current last element of the
|
||||||
|
* row.
|
||||||
|
*/
|
||||||
|
bool sameString(Font const & f, Change const & ch) const;
|
||||||
|
|
||||||
|
///
|
||||||
|
typedef std::vector<Element> Elements;
|
||||||
|
///
|
||||||
|
Elements elements_;
|
||||||
|
|
||||||
/// has the Row appearance changed since last drawing?
|
/// has the Row appearance changed since last drawing?
|
||||||
mutable bool changed_;
|
mutable bool changed_;
|
||||||
/// CRC of row contents.
|
/// CRC of row contents.
|
||||||
|
@ -467,7 +467,12 @@ bool TextMetrics::redoParagraph(pit_type const pit)
|
|||||||
row.pos(first);
|
row.pos(first);
|
||||||
breakRow(row, right_margin, pit);
|
breakRow(row, right_margin, pit);
|
||||||
setRowHeight(row, pit);
|
setRowHeight(row, pit);
|
||||||
|
int w = row.width();
|
||||||
row.dimension().wid = rowWidth(right_margin, pit, first, row.endpos());
|
row.dimension().wid = rowWidth(right_margin, pit, first, row.endpos());
|
||||||
|
if (row.width() != w) {
|
||||||
|
lyxerr << w << " => " << row.width() << ", body=" << par.beginOfBody() << ", size=" << par.size()<< ", inset=" << par.inInset().layoutName()<< endl;
|
||||||
|
lyxerr << row;
|
||||||
|
}
|
||||||
row.setChanged(false);
|
row.setChanged(false);
|
||||||
if (row_index || row.endpos() < par.size())
|
if (row_index || row.endpos() < par.size())
|
||||||
// If there is more than one row, expand the text to
|
// If there is more than one row, expand the text to
|
||||||
@ -800,9 +805,13 @@ void TextMetrics::breakRow(Row & row, int const right_margin, pit_type const pit
|
|||||||
Paragraph const & par = text_->getPar(pit);
|
Paragraph const & par = text_->getPar(pit);
|
||||||
pos_type const end = par.size();
|
pos_type const end = par.size();
|
||||||
pos_type const pos = row.pos();
|
pos_type const pos = row.pos();
|
||||||
int const left = leftMargin(max_width_, pit, pos);
|
|
||||||
int const width = max_width_ - right_margin;
|
int const width = max_width_ - right_margin;
|
||||||
if (pos == end || width < 0) {
|
pos_type const body_pos = par.beginOfBody();
|
||||||
|
row.clear();
|
||||||
|
row.dimension().wid = leftMargin(max_width_, pit, pos);
|
||||||
|
|
||||||
|
if (pos >= end || row.width() > width) {
|
||||||
|
row.dimension().wid += right_margin;
|
||||||
row.endpos(end);
|
row.endpos(end);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -818,7 +827,6 @@ void TextMetrics::breakRow(Row & row, int const right_margin, pit_type const pit
|
|||||||
return addressBreakPoint(pos, par);
|
return addressBreakPoint(pos, par);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// check for possible inline completion
|
// check for possible inline completion
|
||||||
DocIterator const & inlineCompletionPos = bv_->inlineCompletionPos();
|
DocIterator const & inlineCompletionPos = bv_->inlineCompletionPos();
|
||||||
pos_type inlineCompletionLPos = -1;
|
pos_type inlineCompletionLPos = -1;
|
||||||
@ -829,115 +837,106 @@ void TextMetrics::breakRow(Row & row, int const right_margin, pit_type const pit
|
|||||||
inlineCompletionLPos = inlineCompletionPos.pos() - 1;
|
inlineCompletionLPos = inlineCompletionPos.pos() - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pos_type const body_pos = par.beginOfBody();
|
|
||||||
int x = left;
|
|
||||||
pos_type point = end;
|
|
||||||
|
|
||||||
FontIterator fi = FontIterator(*this, par, pit, pos);
|
|
||||||
// Accumulator for character strings
|
|
||||||
docstring chunkstr;
|
|
||||||
Font chunkfont = *fi;
|
|
||||||
|
|
||||||
// Now we iterate through until we reach the right margin
|
// Now we iterate through until we reach the right margin
|
||||||
// or the end of the par, then choose the possible break
|
// or the end of the par, then build a representation of the row.
|
||||||
// nearest that.
|
|
||||||
|
|
||||||
pos_type i = pos;
|
pos_type i = pos;
|
||||||
for ( ; i < end; ++i, ++fi) {
|
FontIterator fi = FontIterator(*this, par, pit, pos);
|
||||||
// Add the chunk width when it is finished
|
while (i < end && row.width() < width) {
|
||||||
if (par.isInset(i) || *fi != chunkfont
|
|
||||||
|| (body_pos && i == body_pos)) {
|
|
||||||
x += theFontMetrics(chunkfont).width(chunkstr);
|
|
||||||
chunkstr.clear();
|
|
||||||
chunkfont = *fi;
|
|
||||||
}
|
|
||||||
|
|
||||||
char_type c = par.getChar(i);
|
char_type c = par.getChar(i);
|
||||||
Language const * language = fi->language();
|
Language const * language = fi->language();
|
||||||
// The most special cases are handled first.
|
// The most special cases are handled first.
|
||||||
if (par.isInset(i)) {
|
if (par.isInset(i)) {
|
||||||
x += pm.insetDimension(par.getInset(i)).wid;
|
Inset const * ins = par.getInset(i);
|
||||||
|
Dimension dim = pm.insetDimension(ins);
|
||||||
|
row.add(i, ins, dim);
|
||||||
|
} else if (par.isLineSeparator(i)) {
|
||||||
|
// In theory, no inset has this property. If
|
||||||
|
// this is done, a new addSeparator which
|
||||||
|
// takes an inset as parameter should be
|
||||||
|
// added.
|
||||||
|
LATTEST(!par.isInset(i));
|
||||||
|
row.addSeparator(i, c, *fi, par.lookupChange(i));
|
||||||
} else if (c == '\t')
|
} else if (c == '\t')
|
||||||
chunkstr += " ";
|
row.add(i, from_ascii(" "), *fi, par.lookupChange(i));
|
||||||
else if (language->rightToLeft()) {
|
else if (language->rightToLeft()) {
|
||||||
if (language->lang() == "arabic_arabtex" ||
|
if (language->lang() == "arabic_arabtex" ||
|
||||||
language->lang() == "arabic_arabi" ||
|
language->lang() == "arabic_arabi" ||
|
||||||
language->lang() == "farsi") {
|
language->lang() == "farsi") {
|
||||||
if (!Encodings::isArabicComposeChar(c))
|
if (!Encodings::isArabicComposeChar(c))
|
||||||
chunkstr += par.transformChar(c, i);
|
row.add(i, par.transformChar(c, i),
|
||||||
|
*fi, par.lookupChange(i));
|
||||||
} else if (language->lang() == "hebrew" &&
|
} else if (language->lang() == "hebrew" &&
|
||||||
!Encodings::isHebrewComposeChar(c)) {
|
!Encodings::isHebrewComposeChar(c)) {
|
||||||
chunkstr+= c;
|
row.add(i, c, *fi, par.lookupChange(i));
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
chunkstr += c;
|
row.add(i, c, *fi, par.lookupChange(i));
|
||||||
|
|
||||||
|
// end of paragraph marker
|
||||||
if (lyxrc.paragraph_markers
|
if (lyxrc.paragraph_markers
|
||||||
&& i == end - 1 && size_type(pit + 1) < pars.size())
|
&& i == end - 1 && size_type(pit + 1) < pars.size()) {
|
||||||
// enlarge the last character to hold the end-of-par marker
|
// enlarge the last character to hold the end-of-par marker
|
||||||
chunkstr += char_type(0x00B6);
|
Font f(text_->layoutFont(pit));
|
||||||
|
f.fontInfo().setColor(Color_paragraphmarker);
|
||||||
|
row.add(i, char_type(0x00B6), f, Change());
|
||||||
|
}
|
||||||
|
|
||||||
// add inline completion width
|
// add inline completion width
|
||||||
if (inlineCompletionLPos == i)
|
if (inlineCompletionLPos == i) {
|
||||||
chunkstr += bv_->inlineCompletion();
|
Font f = *fi;
|
||||||
|
f.fontInfo().setColor(Color_inlinecompletion);
|
||||||
|
row.add(i, bv_->inlineCompletion(), f, Change());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle some situations that abruptly terminate the row
|
||||||
|
// - A newline inset
|
||||||
|
// - Before a display inset
|
||||||
|
// - After a display inset
|
||||||
|
Inset const * inset = 0;
|
||||||
|
if (par.isNewline(i)
|
||||||
|
|| (i + 1 < end && (inset = par.getInset(i + 1))
|
||||||
|
&& inset->display())
|
||||||
|
|| (!row.empty() && row.back().inset
|
||||||
|
&& row.back().inset->display())) {
|
||||||
|
++i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
++i;
|
||||||
|
++fi;
|
||||||
|
|
||||||
// add the auto-hfill from label end to the body
|
// add the auto-hfill from label end to the body
|
||||||
if (body_pos && i == body_pos) {
|
if (body_pos && i == body_pos) {
|
||||||
FontMetrics const & fm = theFontMetrics(
|
FontMetrics const & fm = theFontMetrics(
|
||||||
text_->labelFont(par));
|
text_->labelFont(par));
|
||||||
int add = fm.width(par.layout().labelsep);
|
if (!row.empty() && row.back().isLineSeparator())
|
||||||
//if (par.isLineSeparator(i - 1))
|
row.pop_back();
|
||||||
// add -= singleWidth(pit, i - 1);
|
int const add = max(fm.width(par.layout().labelsep),
|
||||||
|
labelEnd(pit) - row.width());
|
||||||
add = max(add, labelEnd(pit) - x);
|
row.addSpace(i, add);
|
||||||
x += add;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (par.isNewline(i)) {
|
|
||||||
point = i + 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
Inset const * inset = 0;
|
|
||||||
// Break before...
|
|
||||||
if (i + 1 < end) {
|
|
||||||
if ((inset = par.getInset(i + 1)) && inset->display()) {
|
|
||||||
point = i + 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// ...and after.
|
|
||||||
if ((inset = par.getInset(i)) && inset->display()) {
|
|
||||||
point = i + 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (par.isLineSeparator(i)) {
|
|
||||||
x += theFontMetrics(chunkfont).width(chunkstr);
|
|
||||||
chunkstr.clear();
|
|
||||||
chunkfont = *fi;
|
|
||||||
if (x >= width) {
|
|
||||||
// exit on last registered breakpoint:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// register breakpoint:
|
|
||||||
point = i + 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == end) {
|
row.finalizeLast();
|
||||||
x += theFontMetrics(chunkfont).width(chunkstr);
|
row.endpos(i);
|
||||||
// maybe found one, but the par is short enough.
|
// if the row is too large, try to cut at last separator.
|
||||||
if (x < width)
|
if (row.width() >= width)
|
||||||
point = end;
|
row.separate_back(body_pos);
|
||||||
}
|
|
||||||
|
// if the row ends with a separator that is not at end of
|
||||||
|
// paragraph, remove it
|
||||||
|
if (!row.empty() && row.back().isLineSeparator()
|
||||||
|
&& row.endpos() < par.size())
|
||||||
|
row.pop_back();
|
||||||
|
|
||||||
|
row.dimension().wid += right_margin;
|
||||||
|
|
||||||
// manual labels cannot be broken in LaTeX. But we
|
// manual labels cannot be broken in LaTeX. But we
|
||||||
// want to make our on-screen rendering of footnotes
|
// want to make our on-screen rendering of footnotes
|
||||||
// etc. still break
|
// etc. still break
|
||||||
if (body_pos && point < body_pos)
|
// if (body_pos && point < body_pos)
|
||||||
point = body_pos;
|
// point = body_pos;
|
||||||
|
|
||||||
row.endpos(point);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user