+
+bool TexRow::sameParOrInsetMath(RowEntry const & entry1,
+ RowEntry const & entry2)
+{
+ return entry1.is_math == entry2.is_math
+ && (entry1.is_math
+ ? (entry1.math.id == entry2.math.id)
+ : (entry1.text.id == entry2.text.id));
+}
+
+
+// assumes it is sameParOrInsetMath
+int TexRow::comparePos(RowEntry const & entry1,
+ RowEntry const & entry2)
+{
+ if (entry1.is_math)
+ return entry2.math.cell - entry1.math.cell;
+ else
+ return entry2.text.pos - entry1.text.pos;
+}
+
+
+// An iterator on RowList that goes top-down, left-right
+//
+// We assume that the end of RowList does not change, which makes things simpler
+//
+// Records a pair of iterators on the RowEntryList (row_it_, row_end_) and a
+// pair of iterators on the current row (it_, it_end_).
+//
+// it_ always points to a valid position unless row_it_ == row_end_.
+//
+// We could turn this into a proper bidirectional iterator, but we don't need as
+// much.
+//
+class TexRow::RowListIterator
+{
+public:
+ RowListIterator(RowList::const_iterator r,
+ RowList::const_iterator r_end)
+ : row_it_(r), row_end_(r_end),
+ it_(r == r_end ? RowEntryList::const_iterator() : r->begin()),
+ it_end_(r == r_end ? RowEntryList::const_iterator() : r->end())
+ {
+ normalize();
+ }
+
+
+ RowListIterator() :
+ row_it_(RowList::const_iterator()),
+ row_end_(RowList::const_iterator()),
+ it_(RowEntryList::const_iterator()),
+ it_end_(RowEntryList::const_iterator()) { }
+
+
+ RowEntry const & operator*()
+ {
+ return *it_;
+ }
+
+
+ RowListIterator & operator++()
+ {
+ ++it_;
+ normalize();
+ return *this;
+ }
+
+
+ bool atEnd() const
+ {
+ return row_it_ == row_end_;
+ }
+
+
+ bool operator==(RowListIterator const & a) const
+ {
+ return row_it_ == a.row_it_ && ((atEnd() && a.atEnd()) || it_ == a.it_);
+ }
+
+
+ bool operator!=(RowListIterator const & a) const { return !operator==(a); }
+
+
+ // Current row.
+ RowList::const_iterator const & row() const
+ {
+ return row_it_;
+ }
+private:
+ // ensures that it_ points to a valid value unless row_it_ == row_end_
+ void normalize()
+ {
+ if (row_it_ == row_end_)
+ return;
+ while (it_ == it_end_) {
+ ++row_it_;
+ if (row_it_ != row_end_) {
+ it_ = row_it_->begin();
+ it_end_ = row_it_->end();
+ } else
+ return;
+ }
+ }
+ //
+ RowList::const_iterator row_it_;
+ //
+ RowList::const_iterator row_end_;
+ //
+ RowEntryList::const_iterator it_;
+ //
+ RowEntryList::const_iterator it_end_;
+};
+
+
+TexRow::RowListIterator TexRow::begin() const
+{
+ return RowListIterator(rowlist_.begin(), rowlist_.end());
+}
+
+
+TexRow::RowListIterator TexRow::end() const
+{
+ return RowListIterator(rowlist_.end(), rowlist_.end());