]> git.lyx.org Git - lyx.git/blobdiff - src/lyxrow.C
Collapse all those LFUN_XYZ_APPLY to a single LFUN_INSET_APPLY.
[lyx.git] / src / lyxrow.C
index 4a90389d9b4c66d517a85ab9811eb8712671409c..e5cb15826f221274a45415b21bebd01d68651b17 100644 (file)
@@ -1,21 +1,26 @@
-/* This file is part of
- * ====================================================== 
- * 
- *           LyX, The Document Processor
- *      
- *           Copyright 1995 Matthias Ettrich
- *           Copyright 1995-2000 The LyX Team.
+/**
+ * \file lyxrow.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
  *
- * ====================================================== */
+ * \author unknown
+ *
+ * Full author contact details are available in file CREDITS
+ *
+ * Metrics for an on-screen text row.
+ */
 
 #include <config.h>
 
-#ifdef __GNUG__
-#pragma implementation
-#endif
-
 #include "lyxrow.h"
+#include "paragraph.h"
+#include "layout.h"
+#include "lyxlayout.h"
+
+using lyx::pos_type;
 
+using std::max;
+using std::min;
 
 Row::Row()
        : par_(0), pos_(0), fill_(0), height_(0), width_(0),
@@ -23,19 +28,19 @@ Row::Row()
 {}
 
 
-void Row::par(LyXParagraph * p)
+void Row::par(Paragraph * p)
 {
        par_ = p;
 }
 
 
-void Row::pos(LyXParagraph::size_type p)
+void Row::pos(pos_type p)
 {
        pos_ = p;
 }
 
 
-LyXParagraph::size_type Row::pos() const
+pos_type Row::pos() const
 {
        return pos_;
 }
@@ -83,6 +88,18 @@ unsigned short Row::ascent_of_text() const
 }
 
 
+void Row::top_of_text(unsigned int top)
+{
+       top_of_text_ = top;
+}
+
+unsigned int Row::top_of_text() const
+{
+       return top_of_text_;
+}
+
 void Row::baseline(unsigned int b)
 {
        baseline_ = b;
@@ -111,3 +128,161 @@ Row * Row::previous() const
 {
        return previous_;
 }
+
+
+bool Row::isParStart() const
+{
+       return !pos();
+}
+
+
+bool Row::isParEnd() const
+{
+       return !next() || next()->par() != par();
+}
+
+
+pos_type Row::lastPos() const
+{
+       if (!par()->size())
+               return 0;
+
+       if (isParEnd()) {
+               return par()->size() - 1;
+       } else {
+               return next()->pos() - 1;
+       }
+}
+
+
+namespace {
+
+bool nextRowIsAllInset(Row const & row, pos_type last)
+{
+       if (!row.par()->isInset(last + 1))
+               return false;
+
+       Inset * i = row.par()->getInset(last + 1);
+       return i->needFullRow() || i->display();
+}
+
+};
+
+
+pos_type Row::lastPrintablePos() const
+{
+       pos_type const last = lastPos();
+
+       // if this row is an end of par, just act like lastPos()
+       if (isParEnd())
+               return last;
+
+       bool const nextrownotinset = !nextRowIsAllInset(*this, last);
+
+       if (nextrownotinset && par()->isSeparator(last))
+               return last - 1;
+
+       return last;
+}
+
+
+int Row::numberOfSeparators() const
+{
+       pos_type const last = lastPrintablePos();
+       pos_type p = max(pos(), par()->beginningOfMainBody());
+
+       int n = 0;
+       for (; p <= last; ++p) {
+               if (par()->isSeparator(p)) {
+                       ++n;
+               }
+       }
+       return n;
+}
+
+
+int Row::numberOfHfills() const
+{
+       pos_type const last = lastPos();
+       pos_type first = pos();
+
+       // hfill *DO* count at the beginning of paragraphs!
+       if (first) {
+               while (first <= last && par()->isHfill(first)) {
+                       ++first;
+               }
+       }
+
+       first = max(first, par()->beginningOfMainBody());
+
+       int n = 0;
+
+       // last, because the end is ignored!
+       for (pos_type p = first; p <= last; ++p) {
+               if (par()->isHfill(p))
+                       ++n;
+       }
+       return n;
+}
+
+
+int Row::numberOfLabelHfills() const
+{
+       pos_type last = lastPos();
+       pos_type first = pos();
+
+       // hfill *DO* count at the beginning of paragraphs!
+       if (first) {
+               while (first < last && par()->isHfill(first))
+                       ++first;
+       }
+
+       last = min(last, par()->beginningOfMainBody());
+       int n = 0;
+
+       // last, because the end is ignored!
+       for (pos_type p = first; p < last; ++p) {
+               if (par()->isHfill(p))
+                       ++n;
+       }
+       return n;
+}
+
+
+bool Row::hfillExpansion(pos_type pos) const
+{
+       if (!par()->isHfill(pos))
+               return false;
+
+       // at the end of a row it does not count
+       // unless another hfill exists on the line
+       if (pos >= lastPos()) {
+               pos_type i = this->pos();
+               while (i < pos && !par()->isHfill(i)) {
+                       ++i;
+               }
+               if (i == pos) {
+                       return false;
+               }
+       }
+
+       // at the beginning of a row it does not count, if it is not
+       // the first row of a paragaph
+       if (isParStart())
+               return true;
+
+       // in some labels  it does not count
+       if (par()->layout()->margintype != MARGIN_MANUAL
+           && pos < par()->beginningOfMainBody())
+               return false;
+
+       // if there is anything between the first char of the row and
+       // the sepcified position that is not a newline and not a hfill,
+       // the hfill will count, otherwise not
+       pos_type i = this->pos();
+       while (i < pos && (par()->isNewline(i)
+                          || par()->isHfill(i)))
+               ++i;
+
+       return i != pos;
+}