2003-02-14 00:41:44 +00:00
|
|
|
/**
|
|
|
|
* \file lyxrow.C
|
|
|
|
* This file is part of LyX, the document processor.
|
|
|
|
* Licence details can be found in the file COPYING.
|
2002-03-21 17:27:08 +00:00
|
|
|
*
|
2003-02-14 00:41:44 +00:00
|
|
|
* \author unknown
|
2002-03-21 17:27:08 +00:00
|
|
|
*
|
2003-02-14 00:41:44 +00:00
|
|
|
* Full author contact details are available in file CREDITS
|
2000-06-08 23:16:16 +00:00
|
|
|
*
|
2003-02-14 00:41:44 +00:00
|
|
|
* Metrics for an on-screen text row.
|
|
|
|
*/
|
2000-06-08 23:16:16 +00:00
|
|
|
|
2000-06-15 15:54:05 +00:00
|
|
|
#include <config.h>
|
|
|
|
|
2000-06-08 23:16:16 +00:00
|
|
|
#include "lyxrow.h"
|
2003-02-14 00:41:44 +00:00
|
|
|
#include "paragraph.h"
|
|
|
|
#include "layout.h"
|
|
|
|
#include "lyxlayout.h"
|
2000-06-08 23:16:16 +00:00
|
|
|
|
2003-02-14 00:41:44 +00:00
|
|
|
using lyx::pos_type;
|
|
|
|
|
|
|
|
using std::max;
|
|
|
|
using std::min;
|
2000-06-08 23:16:16 +00:00
|
|
|
|
|
|
|
Row::Row()
|
2000-06-26 15:10:49 +00:00
|
|
|
: par_(0), pos_(0), fill_(0), height_(0), width_(0),
|
2000-06-08 23:16:16 +00:00
|
|
|
ascent_of_text_(0), baseline_(0), next_(0), previous_(0)
|
|
|
|
{}
|
|
|
|
|
|
|
|
|
2003-03-21 14:20:48 +00:00
|
|
|
Paragraph * Row::par()
|
|
|
|
{
|
|
|
|
return par_;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Paragraph * Row::par() const
|
|
|
|
{
|
|
|
|
return par_;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
unsigned short Row::height() const
|
|
|
|
{
|
|
|
|
return height_;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Row * Row::next() const
|
|
|
|
{
|
|
|
|
return next_;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-06-25 00:06:33 +00:00
|
|
|
void Row::par(Paragraph * p)
|
2000-06-08 23:16:16 +00:00
|
|
|
{
|
|
|
|
par_ = p;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-02-14 00:41:44 +00:00
|
|
|
void Row::pos(pos_type p)
|
2000-06-08 23:16:16 +00:00
|
|
|
{
|
|
|
|
pos_ = p;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-02-14 00:41:44 +00:00
|
|
|
pos_type Row::pos() const
|
2000-06-08 23:16:16 +00:00
|
|
|
{
|
|
|
|
return pos_;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Row::fill(int f)
|
|
|
|
{
|
|
|
|
fill_ = f;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int Row::fill() const
|
|
|
|
{
|
|
|
|
return fill_;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Row::height(unsigned short h)
|
|
|
|
{
|
|
|
|
height_ = h;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-06-26 15:10:49 +00:00
|
|
|
void Row::width(unsigned int w)
|
|
|
|
{
|
|
|
|
width_ = w;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
unsigned int Row::width() const
|
|
|
|
{
|
|
|
|
return width_;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-06-08 23:16:16 +00:00
|
|
|
void Row::ascent_of_text(unsigned short a)
|
|
|
|
{
|
|
|
|
ascent_of_text_ = a;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
unsigned short Row::ascent_of_text() const
|
|
|
|
{
|
|
|
|
return ascent_of_text_;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-02-08 19:18:01 +00:00
|
|
|
void Row::top_of_text(unsigned int top)
|
|
|
|
{
|
|
|
|
top_of_text_ = top;
|
|
|
|
}
|
|
|
|
|
2003-03-04 09:27:27 +00:00
|
|
|
|
2003-02-08 19:18:01 +00:00
|
|
|
unsigned int Row::top_of_text() const
|
|
|
|
{
|
|
|
|
return top_of_text_;
|
|
|
|
}
|
|
|
|
|
2003-03-04 09:27:27 +00:00
|
|
|
|
2000-06-08 23:16:16 +00:00
|
|
|
void Row::baseline(unsigned int b)
|
|
|
|
{
|
|
|
|
baseline_ = b;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
unsigned int Row::baseline() const
|
|
|
|
{
|
|
|
|
return baseline_;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Row::next(Row * r)
|
|
|
|
{
|
|
|
|
next_ = r;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Row::previous(Row * r)
|
|
|
|
{
|
|
|
|
previous_ = r;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Row * Row::previous() const
|
|
|
|
{
|
|
|
|
return previous_;
|
|
|
|
}
|
2003-02-14 00:41:44 +00:00
|
|
|
|
|
|
|
|
2003-02-26 17:04:10 +00:00
|
|
|
bool Row::isParStart() const
|
|
|
|
{
|
|
|
|
return !pos();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool Row::isParEnd() const
|
|
|
|
{
|
|
|
|
return !next() || next()->par() != par();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-02-14 00:41:44 +00:00
|
|
|
pos_type Row::lastPos() const
|
|
|
|
{
|
2003-03-27 12:41:47 +00:00
|
|
|
if (par()->empty())
|
2003-02-14 00:41:44 +00:00
|
|
|
return 0;
|
|
|
|
|
2003-02-26 17:04:10 +00:00
|
|
|
if (isParEnd()) {
|
2003-02-14 00:41:44 +00:00
|
|
|
return par()->size() - 1;
|
|
|
|
} else {
|
|
|
|
return next()->pos() - 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
bool nextRowIsAllInset(Row const & row, pos_type last)
|
|
|
|
{
|
2003-03-13 10:30:28 +00:00
|
|
|
if (last + 1 >= row.par()->size())
|
|
|
|
return false;
|
|
|
|
|
2003-02-14 00:41:44 +00:00
|
|
|
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();
|
|
|
|
|
2003-02-17 01:53:13 +00:00
|
|
|
// if this row is an end of par, just act like lastPos()
|
2003-02-26 17:04:10 +00:00
|
|
|
if (isParEnd())
|
2003-02-17 01:53:13 +00:00
|
|
|
return last;
|
|
|
|
|
|
|
|
bool const nextrownotinset = !nextRowIsAllInset(*this, last);
|
|
|
|
|
|
|
|
if (nextrownotinset && par()->isSeparator(last))
|
2003-02-14 00:41:44 +00:00
|
|
|
return last - 1;
|
|
|
|
|
|
|
|
return last;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int Row::numberOfSeparators() const
|
|
|
|
{
|
|
|
|
pos_type const last = lastPrintablePos();
|
2003-03-09 12:37:22 +00:00
|
|
|
pos_type p = max(pos(), par()->beginningOfBody());
|
2003-02-14 00:41:44 +00:00
|
|
|
|
|
|
|
int n = 0;
|
2003-03-13 10:30:28 +00:00
|
|
|
for (; p < last; ++p) {
|
2003-02-14 00:41:44 +00:00
|
|
|
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) {
|
2003-03-13 10:30:28 +00:00
|
|
|
while (first < last && par()->isHfill(first)) {
|
2003-02-14 00:41:44 +00:00
|
|
|
++first;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-03-09 12:37:22 +00:00
|
|
|
first = max(first, par()->beginningOfBody());
|
2003-02-14 00:41:44 +00:00
|
|
|
|
|
|
|
int n = 0;
|
|
|
|
|
|
|
|
// last, because the end is ignored!
|
2003-03-13 10:30:28 +00:00
|
|
|
for (pos_type p = first; p < last; ++p) {
|
2003-02-14 00:41:44 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2003-03-09 12:37:22 +00:00
|
|
|
last = min(last, par()->beginningOfBody());
|
2003-02-14 00:41:44 +00:00
|
|
|
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
|
2003-02-26 17:04:10 +00:00
|
|
|
if (isParStart())
|
2003-02-14 00:41:44 +00:00
|
|
|
return true;
|
|
|
|
|
2003-03-11 11:52:05 +00:00
|
|
|
// in some labels it does not count
|
2003-02-14 00:41:44 +00:00
|
|
|
if (par()->layout()->margintype != MARGIN_MANUAL
|
2003-03-09 12:37:22 +00:00
|
|
|
&& pos < par()->beginningOfBody())
|
2003-02-14 00:41:44 +00:00
|
|
|
return false;
|
|
|
|
|
|
|
|
// if there is anything between the first char of the row and
|
2003-03-11 11:52:05 +00:00
|
|
|
// the specified position that is not a newline and not a hfill,
|
2003-02-14 00:41:44 +00:00
|
|
|
// the hfill will count, otherwise not
|
|
|
|
pos_type i = this->pos();
|
2003-03-11 11:52:05 +00:00
|
|
|
while (i < pos && (par()->isNewline(i) || par()->isHfill(i)))
|
2003-02-14 00:41:44 +00:00
|
|
|
++i;
|
|
|
|
|
|
|
|
return i != pos;
|
|
|
|
}
|