Hello,
FYI, I've committed this first step toward true MV separation of the
Paragraph class (and also a small cleanup of DocIterator). I did not
request a review of the patch because it was straight forward (just
moving of code) and very safe.
As indicated in the comments, the next step is to let BufferView handles
these ParagraphMetrics objects. I don't know if I'll have time to do it
but at least the path to completion is clear from this point for anyone
who wants to continue the work. If not, then this will wait for 1.6.
I believe nevertheless that completing this model/view separation will
get rid of most the bugs related to metrics. It will also simplify the
code in a number of place (by transferring for example
LyXText::redoParagraph() to BufferView or even to ParagraphMetrics).
Abdel.
URL: http://www.lyx.org/trac/changeset/16335
Log:
First step towards model/view separation of Paragraph class.
- ParagraphMetrics: new class gathering everything related to metrics.
- Paragraph: now derives from ParagraphMetrics.
Modified:
lyx-devel/trunk/src/paragraph.C
lyx-devel/trunk/src/paragraph.h
Modified: lyx-devel/trunk/src/paragraph.C
URL: http://www.lyx.org/trac/file/lyx-devel/trunk/src/paragraph.C?rev=16335
==============================================================================
--- lyx-devel/trunk/src/paragraph.C (original)
+++ lyx-devel/trunk/src/paragraph.C Tue Dec 19 15:27:38 2006
@@ -69,6 +69,88 @@
using std::ostringstream;
+ParagraphMetrics::ParagraphMetrics()
+{
+}
+
+
+ParagraphMetrics::ParagraphMetrics(ParagraphMetrics const & pm)
+ : dim_(pm.dim_), rows_(pm.rows_), rowSignature_(pm.rowSignature_)
+{
+}
+
+
+ParagraphMetrics & ParagraphMetrics::operator=(ParagraphMetrics const & pm)
+{
+ rows_ = pm.rows_;
+ dim_ = pm.dim_;
+ rowSignature_ = pm.rowSignature_;
+ return *this;
+}
+
+
+Row & ParagraphMetrics::getRow(pos_type pos, bool boundary)
+{
+ BOOST_ASSERT(!rows().empty());
+
+ // If boundary is set we should return the row on which
+ // the character before is inside.
+ if (pos > 0 && boundary)
+ --pos;
+
+ RowList::iterator rit = rows_.end();
+ RowList::iterator const begin = rows_.begin();
+
+ for (--rit; rit != begin && rit->pos() > pos; --rit)
+ ;
+
+ return *rit;
+}
+
+
+Row const & ParagraphMetrics::getRow(pos_type pos, bool boundary) const
+{
+ BOOST_ASSERT(!rows().empty());
+
+ // If boundary is set we should return the row on which
+ // the character before is inside.
+ if (pos > 0 && boundary)
+ --pos;
+
+ RowList::const_iterator rit = rows_.end();
+ RowList::const_iterator const begin = rows_.begin();
+
+ for (--rit; rit != begin && rit->pos() > pos; --rit)
+ ;
+
+ return *rit;
+}
+
+
+size_t ParagraphMetrics::pos2row(pos_type pos) const
+{
+ BOOST_ASSERT(!rows().empty());
+
+ RowList::const_iterator rit = rows_.end();
+ RowList::const_iterator const begin = rows_.begin();
+
+ for (--rit; rit != begin && rit->pos() > pos; --rit)
+ ;
+
+ return rit - begin;
+}
+
+
+void ParagraphMetrics::dump() const
+{
+ lyxerr << "Paragraph::dump: rows.size(): " << rows_.size() << endl;
+ for (size_t i = 0; i != rows_.size(); ++i) {
+ lyxerr << " row " << i << ": ";
+ rows_[i].dump();
+ }
+}
+
+
Paragraph::Paragraph()
: begin_of_body_(0), pimpl_(new Paragraph::Pimpl(this))
{
@@ -78,12 +160,11 @@
Paragraph::Paragraph(Paragraph const & par)
- : itemdepth(par.itemdepth), insetlist(par.insetlist),
- dim_(par.dim_),
- rows_(par.rows_), rowSignature_(par.rowSignature_),
- layout_(par.layout_),
- text_(par.text_), begin_of_body_(par.begin_of_body_),
- pimpl_(new Paragraph::Pimpl(*par.pimpl_, this))
+ : ParagraphMetrics(par),
+ itemdepth(par.itemdepth), insetlist(par.insetlist),
+ layout_(par.layout_),
+ text_(par.text_), begin_of_body_(par.begin_of_body_),
+ pimpl_(new Paragraph::Pimpl(*par.pimpl_, this))
{
//lyxerr << "Paragraph::Paragraph(Paragraph const&)" << endl;
InsetList::iterator it = insetlist.begin();
@@ -105,15 +186,14 @@
for (; it != end; ++it)
it->inset = it->inset->clone().release();
- rows_ = par.rows_;
- dim_ = par.dim_;
- rowSignature_ = par.rowSignature_;
layout_ = par.layout();
text_ = par.text_;
begin_of_body_ = par.begin_of_body_;
delete pimpl_;
pimpl_ = new Pimpl(*par.pimpl_, this);
+
+ ParagraphMetrics::operator=(par);
}
return *this;
}
@@ -1538,58 +1618,6 @@
}
-Row & Paragraph::getRow(pos_type pos, bool boundary)
-{
- BOOST_ASSERT(!rows().empty());
-
- // If boundary is set we should return the row on which
- // the character before is inside.
- if (pos > 0 && boundary)
- --pos;
-
- RowList::iterator rit = rows_.end();
- RowList::iterator const begin = rows_.begin();
-
- for (--rit; rit != begin && rit->pos() > pos; --rit)
- ;
-
- return *rit;
-}
-
-
-Row const & Paragraph::getRow(pos_type pos, bool boundary) const
-{
- BOOST_ASSERT(!rows().empty());
-
- // If boundary is set we should return the row on which
- // the character before is inside.
- if (pos > 0 && boundary)
- --pos;
-
- RowList::const_iterator rit = rows_.end();
- RowList::const_iterator const begin = rows_.begin();
-
- for (--rit; rit != begin && rit->pos() > pos; --rit)
- ;
-
- return *rit;
-}
-
-
-size_t Paragraph::pos2row(pos_type pos) const
-{
- BOOST_ASSERT(!rows().empty());
-
- RowList::const_iterator rit = rows_.end();
- RowList::const_iterator const begin = rows_.begin();
-
- for (--rit; rit != begin && rit->pos() > pos; --rit)
- ;
-
- return rit - begin;
-}
-
-
char_type Paragraph::transformChar(char_type c, pos_type pos) const
{
if (!Encodings::is_arabic(c))
@@ -1626,16 +1654,6 @@
}
-void Paragraph::dump() const
-{
- lyxerr << "Paragraph::dump: rows.size(): " << rows_.size() << endl;
- for (size_t i = 0; i != rows_.size(); ++i) {
- lyxerr << " row " << i << ": ";
- rows_[i].dump();
- }
-}
-
-
bool Paragraph::hfillExpansion(Row const & row, pos_type pos) const
{
if (!isHfill(pos))
Modified: lyx-devel/trunk/src/paragraph.h
URL: http://www.lyx.org/trac/file/lyx-devel/trunk/src/paragraph.h?rev=16335
==============================================================================
--- lyx-devel/trunk/src/paragraph.h (original)
+++ lyx-devel/trunk/src/paragraph.h Tue Dec 19 15:27:38 2006
@@ -58,9 +58,56 @@
pos_type first, last;
};
+/// Helper class for Paragraph Metrics.
+/// \todo FIXME: this class deserves its own .[Ch] files.
+/// Then, the storage of such object should be done in \c BufferView
+/// (most probably in the \c CoordCache class along \c Point objects).
+class ParagraphMetrics {
+public:
+ ParagraphMetrics();
+ ParagraphMetrics(ParagraphMetrics const & pm);
+ ParagraphMetrics & operator=(ParagraphMetrics const & pm);
+ ///
+ Row & getRow(pos_type pos, bool boundary);
+ ///
+ Row const & getRow(pos_type pos, bool boundary) const;
+ ///
+ size_t pos2row(pos_type pos) const;
+
+ /// LyXText::redoParagraph updates this
+ Dimension & dim() { return dim_; }
+ /// total height of paragraph
+ unsigned int height() const { return dim_.height(); }
+ /// total width of paragraph, may differ from workwidth
+ unsigned int width() const { return dim_.width(); }
+ /// ascend of paragraph above baseline
+ unsigned int ascent() const { return dim_.ascent(); }
+ /// descend of paragraph below baseline
+ unsigned int descent() const { return dim_.descent(); }
+ /// LyXText updates the rows using this access point
+ RowList & rows() { return rows_; }
+ /// The painter and others use this
+ RowList const & rows() const { return rows_; }
+ ///
+ RowSignature & rowSignature() const { return rowSignature_; }
+
+ /// dump some information to lyxerr
+ void dump() const;
+
+private:
+ ///
+ mutable RowList rows_;
+ ///
+ mutable RowSignature rowSignature_;
+ /// cached dimensions of paragraph
+ Dimension dim_;
+};
+
/// A Paragraph holds all text, attributes and insets in a text paragraph
-class Paragraph {
+/// \todo FIXME: any reference to ParagraphMetrics (including inheritance)
+/// should go in order to complete the Model/View separation of this class.
+class Paragraph: public ParagraphMetrics {
public:
///
enum {
@@ -359,49 +406,14 @@
ParagraphParameters & params();
///
ParagraphParameters const & params() const;
-
- ///
- Row & getRow(pos_type pos, bool boundary);
- ///
- Row const & getRow(pos_type pos, bool boundary) const;
- ///
- size_t pos2row(pos_type pos) const;
-
- /// total height of paragraph
- unsigned int height() const { return dim_.height(); }
- /// total width of paragraph, may differ from workwidth
- unsigned int width() const { return dim_.width(); }
- /// ascend of paragraph above baseline
- unsigned int ascent() const { return dim_.ascent(); }
- /// descend of paragraph below baseline
- unsigned int descent() const { return dim_.descent(); }
- /// LyXText updates the rows using this access point
- RowList & rows() { return rows_; }
- /// The painter and others use this
- RowList const & rows() const { return rows_; }
- ///
- RowSignature & rowSignature() const { return rowSignature_; }
///
bool hfillExpansion(Row const & row, pos_type pos) const;
- /// LyXText::redoParagraph updates this
- Dimension & dim() { return dim_; }
-
- /// dump some information to lyxerr
- void dump() const;
-
public:
///
InsetList insetlist;
private:
- /// cached dimensions of paragraph
- Dimension dim_;
-
- ///
- mutable RowList rows_;
- ///
- mutable RowSignature rowSignature_;
///
LyXLayout_ptr layout_;
@@ -421,7 +433,6 @@
Pimpl * pimpl_;
};
-
} // namespace lyx
#endif // PARAGRAPH_H