-/* 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),
{}
-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_;
}
}
+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;
{
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;
+}