rowlist10

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@6674 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Lars Gullik Bjønnes 2003-04-01 16:55:48 +00:00
parent 383f38d390
commit 0d876bc179
21 changed files with 488 additions and 849 deletions

View File

@ -1,3 +1,36 @@
2003-04-01 Lars Gullik Bjønnes <larsbj@gullik.net>
* lyxtext.h: adjust
* rowpainter.C: adjust
* text.C: adjust
* text2.C: adjust
* text3.C: adjust
* lyxrow_funcs. [Ch]: new files
* lyxrow.[Ch]: remove next and previous pointers
(next,previous): remove accessor functions
(isParEnd): move to lyxrow_funcs
(lastPos): move to lyxrow_funcs
(nextRowIsAllInset): move to lyxrow_funcs
(lastPrintablePos): move to lyxrow_funcs
(numberOfSeparators): move to lyxrow_funcs
(numberOfHfills): move to lyxrow_funcs
(numberOfLabelHfills): move to lyxrow_funcs
(hfillExpansion): move to lyxrow_funcs
* lyxfunc.C: adjust
* bufferview_funcs.C (toggleAndShow): adjust
* RowList.h: Remove class RowList from file leave just a
std::list<Row>.
* RowList.C: delete file
* Makefile.am (lyx_SOURCES): remove RowList.C, add lyxrow_funcs.C
and lyxrow_funcs.h
2003-04-01 Lars Gullik Bjønnes <larsbj@gullik.net>
* text3.C (cursorPrevious): adjust

View File

@ -76,7 +76,6 @@ lyx_SOURCES = \
ParagraphParameters.h \
ParameterStruct.h \
PrinterParams.h \
RowList.C \
RowList.h \
ShareContainer.h \
Spacing.C \
@ -172,6 +171,8 @@ lyx_SOURCES = \
lyxrc.h \
lyxrow.C \
lyxrow.h \
lyxrow_funcs.C \
lyxrow_funcs.h \
lyxserver.C \
lyxserver.h \
lyxtext.h \

View File

@ -1,302 +0,0 @@
#include <config.h>
#include "RowList.h"
#include "lyxrow.h"
////////// The RowList::iterator
RowList::iterator::iterator()
: ptr(0)
{}
RowList::iterator::iterator(Row * p)
: ptr(p)
{}
RowList::iterator::reference
RowList::iterator::operator*()
{
return *ptr;
}
RowList::iterator::pointer
RowList::iterator::operator->()
{
return ptr;
}
RowList::iterator &
RowList::iterator::operator++()
{
ptr = ptr->next();
return *this;
}
RowList::iterator
RowList::iterator::operator++(int)
{
iterator tmp = *this;
++*this;
return tmp;
}
RowList::iterator &
RowList::iterator::operator--()
{
ptr = ptr->previous();
return *this;
}
RowList::iterator
RowList::iterator::operator--(int)
{
iterator tmp = *this;
--*this;
return tmp;
}
bool operator==(RowList::iterator const & i1,
RowList::iterator const & i2)
{
return &(*const_cast<RowList::iterator&>(i1))
== &(*const_cast<RowList::iterator&>(i2));
}
bool operator!=(RowList::iterator const & i1,
RowList::iterator const & i2)
{
return !(i1 == i2);
}
////////// The RowList::const_iterator
RowList::const_iterator::const_iterator()
: ptr(0)
{}
RowList::const_iterator::const_iterator(Row * p)
: ptr(p)
{}
RowList::const_iterator::const_reference
RowList::const_iterator::operator*()
{
return *ptr;
}
RowList::const_iterator::const_pointer
RowList::const_iterator::operator->()
{
return ptr;
}
RowList::const_iterator &
RowList::const_iterator::operator++()
{
ptr = ptr->next();
return *this;
}
RowList::const_iterator
RowList::const_iterator::operator++(int)
{
const_iterator tmp = *this;
++*this;
return tmp;
}
RowList::const_iterator &
RowList::const_iterator::operator--()
{
ptr = ptr->previous();
return *this;
}
RowList::const_iterator
RowList::const_iterator::operator--(int)
{
const_iterator tmp = *this;
--*this;
return tmp;
}
bool operator==(RowList::const_iterator const & i1,
RowList::const_iterator const & i2)
{
return &(*const_cast<RowList::const_iterator&>(i1))
== &(*const_cast<RowList::const_iterator&>(i2));
}
bool operator!=(RowList::const_iterator const & i1,
RowList::const_iterator const & i2)
{
return !(i1 == i2);
}
////////// The RowList proper
RowList::RowList()
: rowlist(0)
{}
RowList::iterator
RowList::insert(RowList::iterator it, Row * row)
{
if (rowlist == 0) {
rowlist = row;
} else if (it != end()) {
Row * prev = it->previous();
row->next(&*it);
row->previous(prev);
if (prev)
prev->next(row);
else
rowlist = row;
it->previous(row);
} else {
// Find last par.
Row * last = rowlist;
while (last->next())
last = last->next();
last->next(row);
row->previous(last);
}
return iterator(row);
}
void RowList::clear()
{
while (rowlist) {
Row * tmp = rowlist->next();
delete rowlist;
rowlist = tmp;
}
}
void RowList::erase(RowList::iterator it)
{
Row * prev = it->previous();
Row * next = it->next();
if (prev)
prev->next(next);
else
rowlist = next;
if (next)
next->previous(prev);
delete &*it;
}
RowList::iterator RowList::begin()
{
return iterator(rowlist);
}
RowList::const_iterator RowList::begin() const
{
return const_iterator(rowlist);
}
RowList::iterator RowList::end()
{
return iterator();
}
RowList::const_iterator RowList::end() const
{
return const_iterator();
}
Row const & RowList::front() const
{
return *rowlist;
}
Row & RowList::front()
{
return *rowlist;
}
Row const & RowList::back() const
{
Row * tmp = rowlist;
while (tmp->next())
tmp = tmp->next();
return *tmp;
}
Row & RowList::back()
{
Row * tmp = rowlist;
while (tmp->next())
tmp = tmp->next();
return *tmp;
}
void RowList::push_back(Row * p)
{
if (!rowlist) {
rowlist = p;
return;
}
Row * pos = rowlist;
while (pos->next())
pos = pos->next();
pos->next(p);
p->previous(pos);
}
int RowList::size() const
{
// When we switch to a std::container this will be O(1)
// instead of O(n). (Lgb)
Row * tmp = rowlist;
int c = 0;
while (tmp) {
++c;
tmp = tmp->next();
}
return c;
}
bool RowList::empty() const
{
return rowlist == 0;
}

View File

@ -3,126 +3,10 @@
#ifndef ROW_LIST_H
#define ROW_LIST_H
#include <iterator>
#include "lyxrow.h"
class Row;
#include <list>
///
class RowList {
public:
///
class iterator {
public:
///
typedef std::bidirectional_iterator_tag iterator_category;
///
typedef Row * value_type;
///
typedef ptrdiff_t difference_type;
///
typedef Row * pointer;
///
typedef Row & reference;
///
iterator();
///
iterator(value_type);
///
reference operator*();
///
pointer operator->();
///
iterator & operator++();
///
iterator operator++(int);
///
iterator & operator--();
///
iterator operator--(int);
private:
///
Row * ptr;
};
///
class const_iterator {
public:
///
typedef std::bidirectional_iterator_tag iterator_category;
///
typedef Row * value_type;
///
typedef ptrdiff_t difference_type;
///
typedef Row const * const_pointer;
///
typedef Row const & const_reference;
///
const_iterator();
///
const_iterator(value_type);
///
const_reference operator*();
///
const_pointer operator->();
///
const_iterator & operator++();
///
const_iterator operator++(int);
///
const_iterator & operator--();
///
const_iterator operator--(int);
private:
///
Row * ptr;
};
///
RowList();
///
iterator insert(iterator it, Row * row);
///
void clear();
///
void erase(iterator it);
///
iterator begin();
///
const_iterator begin() const;
///
iterator end();
///
const_iterator end() const;
///
void push_back(Row *);
///
Row const & front() const;
///
Row & front();
///
Row const & back() const;
///
Row & back();
///
int size() const;
///
bool empty() const;
private:
///
Row * rowlist;
};
///
bool operator==(RowList::iterator const & i1,
RowList::iterator const & i2);
///
bool operator!=(RowList::iterator const & i1,
RowList::iterator const & i2);
///
bool operator==(RowList::const_iterator const & i1,
RowList::const_iterator const & i2);
///
bool operator!=(RowList::const_iterator const & i1,
RowList::const_iterator const & i2);
typedef std::list<Row> RowList;
#endif

View File

@ -393,7 +393,7 @@ void toggleAndShow(BufferView * bv, LyXFont const & font, bool toggleall)
if (font.language() != ignore_language ||
font.number() != LyXFont::IGNORE) {
LyXCursor & cursor = text->cursor;
text->computeBidiTables(bv->buffer(), *cursor.row());
text->computeBidiTables(bv->buffer(), cursor.row());
if (cursor.boundary() !=
text->isBoundary(bv->buffer(), cursor.par(), cursor.pos(),
text->real_current_font))

View File

@ -1,3 +1,7 @@
2003-04-01 Lars Gullik Bjønnes <larsbj@gullik.net>
screen.[Ch]: adjust
2003-04-01 Lars Gullik Bjønnes <larsbj@gullik.net>
* screen.C (topCursorVisible): adjust

View File

@ -265,7 +265,7 @@ void LyXScreen::update(BufferView & bv, int yo, int xo)
case LyXText::REFRESH_ROW:
{
// ok I will update the current cursor row
drawOneRow(text, &bv, &*text->refresh_row, text->refresh_y,
drawOneRow(text, &bv, text->refresh_row, text->refresh_y,
yo, xo);
// this because if we had a major update the refresh_row could
// have been set to 0!
@ -439,7 +439,8 @@ void LyXScreen::drawFromTo(LyXText * text, BufferView * bv,
}
void LyXScreen::drawOneRow(LyXText * text, BufferView * bv, Row * row,
void LyXScreen::drawOneRow(LyXText * text, BufferView * bv,
RowList::iterator row,
int y_text, int yo, int xo)
{
int const y = y_text - text->top_y() + yo;

View File

@ -13,12 +13,12 @@
#ifndef SCREEN_H
#define SCREEN_H
#include "RowList.h"
class LyXText;
class LyXCursor;
class WorkArea;
class BufferView;
struct Row;
/**
* LyXScreen - document rendering management
@ -150,8 +150,9 @@ protected:
int y_offset = 0, int x_offset = 0);
/// y is a coordinate of the text
void drawOneRow(LyXText *, BufferView *, Row * row,
int y_text, int y_offset = 0, int x_offset = 0);
void drawOneRow(LyXText *, BufferView *,
RowList::iterator row,
int y_text, int y_offset = 0, int x_offset = 0);
/// is the blinking cursor currently drawn
bool cursor_visible_;

View File

@ -1,3 +1,7 @@
2003-04-01 Lars Gullik Bjønnes <larsbj@gullik.net>
* insettext.C: adjust
2003-04-01 Lars Gullik Bjønnes <larsbj@gullik.net>
* insettext.C (draw): adjust

View File

@ -1210,7 +1210,7 @@ Inset::RESULT InsetText::localDispatch(FuncRequest const & ev)
break;
case LFUN_PRIOR:
if (!crow(bv)->previous())
if (crow(bv) == lt->rows().begin())
result = FINISHED_UP;
else {
lt->cursorPrevious();
@ -1221,7 +1221,7 @@ Inset::RESULT InsetText::localDispatch(FuncRequest const & ev)
break;
case LFUN_NEXT:
if (!crow(bv)->next())
if (boost::next(crow(bv)) == lt->rows().end())
result = FINISHED_DOWN;
else {
lt->cursorNext();
@ -1805,7 +1805,7 @@ InsetText::moveLeftIntern(BufferView * bv, bool front,
Inset::RESULT InsetText::moveUp(BufferView * bv)
{
if (!crow(bv)->previous())
if (crow(bv) == getLyXText(bv)->rows().begin())
return FINISHED_UP;
getLyXText(bv)->cursorUp(bv);
getLyXText(bv)->clearSelection();
@ -1815,7 +1815,7 @@ Inset::RESULT InsetText::moveUp(BufferView * bv)
Inset::RESULT InsetText::moveDown(BufferView * bv)
{
if (!crow(bv)->next())
if (boost::next(crow(bv)) == getLyXText(bv)->rows().end())
return FINISHED_DOWN;
getLyXText(bv)->cursorDown(bv);
getLyXText(bv)->clearSelection();

View File

@ -821,7 +821,7 @@ void LyXFunc::dispatch(FuncRequest const & ev, bool verbose)
owner->view_state_changed();
goto exit_with_message;
} else if (result == FINISHED_UP) {
if (TEXT()->cursor.irow()->previous()) {
if (TEXT()->cursor.irow() != TEXT()->rows().begin()) {
#if 1
TEXT()->setCursorFromCoordinates(
TEXT()->cursor.ix() + inset_x,
@ -838,7 +838,7 @@ void LyXFunc::dispatch(FuncRequest const & ev, bool verbose)
}
goto exit_with_message;
} else if (result == FINISHED_DOWN) {
if (TEXT()->cursor.irow()->next()) {
if (boost::next(TEXT()->cursor.irow()) != TEXT()->rows().end()) {
#if 1
TEXT()->setCursorFromCoordinates(
TEXT()->cursor.ix() + inset_x,
@ -882,7 +882,7 @@ void LyXFunc::dispatch(FuncRequest const & ev, bool verbose)
}
goto exit_with_message;
case LFUN_DOWN:
if (TEXT()->cursor.row()->next())
if (boost::next(TEXT()->cursor.row()) != TEXT()->rows().end())
TEXT()->cursorDown(view());
else
TEXT()->cursorRight(view());

View File

@ -24,13 +24,13 @@ using std::min;
Row::Row()
: par_(0), pos_(0), fill_(0), height_(0), width_(0),
ascent_of_text_(0), baseline_(0), next_(0), previous_(0)
ascent_of_text_(0), baseline_(0)
{}
Row::Row(Paragraph * pa, pos_type po)
: par_(pa), pos_(po), fill_(0), height_(0), width_(0),
ascent_of_text_(0), baseline_(0), next_(0), previous_(0)
ascent_of_text_(0), baseline_(0)
{}
@ -52,12 +52,6 @@ unsigned short Row::height() const
}
Row * Row::next() const
{
return next_;
}
void Row::par(Paragraph * p)
{
par_ = p;
@ -142,179 +136,7 @@ unsigned int Row::baseline() const
}
void Row::next(Row * r)
{
next_ = r;
}
void Row::previous(Row * r)
{
previous_ = r;
}
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()->empty())
return 0;
if (isParEnd()) {
return par()->size() - 1;
} else {
return next()->pos() - 1;
}
}
namespace {
bool nextRowIsAllInset(Row const & row, pos_type last)
{
if (last + 1 >= row.par()->size())
return false;
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()->beginningOfBody());
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()->beginningOfBody());
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()->beginningOfBody());
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()->beginningOfBody())
return false;
// if there is anything between the first char of the row and
// the specified 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;
}

View File

@ -4,7 +4,8 @@
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
* \author unknown
* \author Matthias Ettrich
* \author Lars Gullik Bjønnes
*
* Full author contact details are available in file CREDITS
*
@ -59,48 +60,8 @@ public:
void baseline(unsigned int b);
///
unsigned int baseline() const;
///
void next(Row * r);
///
Row * next() const;
///
void previous(Row * r);
///
Row * previous() const;
/// return true if this row is the start of a paragraph
bool isParStart() const;
/// return true if this row is the end of a paragraph
bool isParEnd() const;
/// return the position of the last character in this row
lyx::pos_type lastPos() const;
/// return the position of the last normal, printable character in this row
lyx::pos_type lastPrintablePos() const;
/**
* Returns the number of separators.
* The separator on the very last column doesnt count.
*/
int numberOfSeparators() const;
/**
* Returns the number of hfills. It works like a LaTeX \hfill:
* the hfills at the beginning and at the end are ignored.
* This is much more useful than not to ignore!
*/
int numberOfHfills() const;
/// Returns the number of hfills in the manual label. See numberOfHfills().
int numberOfLabelHfills() const;
/**
* Returns true if a expansion is needed at the given position.
* Rules are given by LaTeX
*/
bool hfillExpansion(lyx::pos_type pos) const;
private:
///
Paragraph * par_;
@ -119,10 +80,6 @@ private:
unsigned int top_of_text_;
///
unsigned int baseline_;
///
Row * next_;
///
Row * previous_;
};
#endif

184
src/lyxrow_funcs.C Normal file
View File

@ -0,0 +1,184 @@
#include <config.h>
#include "lyxrow_funcs.h"
#include "lyxtext.h"
#include "paragraph.h"
#include "lyxlayout.h"
#include <boost/next_prior.hpp>
#include <algorithm>
using lyx::pos_type;
using std::max;
using std::min;
bool isParEnd(LyXText const & lt, RowList::iterator rit)
{
RowList::iterator next_row = boost::next(rit);
return next_row == lt.rows().end() ||
next_row->par() != rit->par();
}
// It seems that this is only used in LyXText, it
// perhaps this function should be moved into LyXText. (Lgb)
pos_type lastPos(LyXText const & lt, RowList::iterator rit)
{
if (rit->par()->empty())
return 0;
if (isParEnd(lt, rit)) {
return rit->par()->size() - 1;
} else {
return boost::next(rit)->pos() - 1;
}
}
namespace {
bool nextRowIsAllInset(Row const & row, pos_type last)
{
Paragraph const * par = row.par();
if (last + 1 >= par->size())
return false;
if (!par->isInset(last + 1))
return false;
Inset const * i = par->getInset(last + 1);
return i->needFullRow() || i->display();
}
} // anon namespace
pos_type lastPrintablePos(LyXText const & lt, RowList::iterator rit)
{
pos_type const last = lastPos(lt, rit);
// if this row is an end of par, just act like lastPos()
if (isParEnd(lt, rit))
return last;
bool const nextrownotinset = !nextRowIsAllInset(*rit, last);
if (nextrownotinset && rit->par()->isSeparator(last))
return last - 1;
return last;
}
int numberOfSeparators(LyXText const & lt, RowList::iterator rit)
{
pos_type const last = lastPrintablePos(lt, rit);
Paragraph const * par = rit->par();
int n = 0;
pos_type p = max(rit->pos(), par->beginningOfBody());
for (; p < last; ++p) {
if (par->isSeparator(p)) {
++n;
}
}
return n;
}
// This is called _once_ from LyXText and should at least be moved into
// an anonymous namespace there. (Lgb)
int numberOfHfills(LyXText const & lt, RowList::iterator rit)
{
pos_type const last = lastPos(lt, rit);
pos_type first = rit->pos();
Paragraph const * par = rit->par();
// hfill *DO* count at the beginning of paragraphs!
if (first) {
while (first < last && par->isHfill(first)) {
++first;
}
}
first = max(first, par->beginningOfBody());
int n = 0;
// last, because the end is ignored!
for (pos_type p = first; p < last; ++p) {
if (par->isHfill(p))
++n;
}
return n;
}
// This is called _once_ from LyXText and should at least be moved into
// an anonymous namespace there. (Lgb)
int numberOfLabelHfills(LyXText const & lt, RowList::iterator rit)
{
pos_type last = lastPos(lt, rit);
pos_type first = rit->pos();
Paragraph const * par = rit->par();
// hfill *DO* count at the beginning of paragraphs!
if (first) {
while (first < last && par->isHfill(first))
++first;
}
last = min(last, par->beginningOfBody());
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 hfillExpansion(LyXText const & lt, RowList::iterator rit, pos_type pos)
{
Paragraph const * par = rit->par();
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(lt, rit)) {
pos_type i = rit->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 (rit->isParStart())
return true;
// in some labels it does not count
if (par->layout()->margintype != MARGIN_MANUAL
&& pos < par->beginningOfBody())
return false;
// if there is anything between the first char of the row and
// the specified position that is not a newline and not a hfill,
// the hfill will count, otherwise not
pos_type i = rit->pos();
while (i < pos && (par->isNewline(i) || par->isHfill(i)))
++i;
return i != pos;
}

25
src/lyxrow_funcs.h Normal file
View File

@ -0,0 +1,25 @@
// -*- C++ -*-
#ifndef LYXROW_FUNCS_H
#define LYXROW_FUNCS_H
#include "RowList.h"
#include "support/types.h"
class LyXText;
bool isParEnd(LyXText const & lt, RowList::iterator rit);
lyx::pos_type lastPos(LyXText const & lt, RowList::iterator rit);
lyx::pos_type lastPrintablePos(LyXText const & lt, RowList::iterator rit);
int numberOfSeparators(LyXText const & lt, RowList::iterator rit);
int numberOfHfills(LyXText const & lt, RowList::iterator rit);
int numberOfLabelHfills(LyXText const & lt, RowList::iterator rit);
bool hfillExpansion(LyXText const & lt, RowList::iterator rit, lyx::pos_type pos);
#endif

View File

@ -476,7 +476,7 @@ public:
int workWidth(Inset * inset) const;
///
void computeBidiTables(Buffer const *, Row const & row) const;
void computeBidiTables(Buffer const *, RowList::iterator row) const;
/// Maps positions in the visual string to positions in logical string.
lyx::pos_type log2vis(lyx::pos_type pos) const;
/// Maps positions in the logical string to positions in visual string.
@ -568,13 +568,13 @@ public:
* in LaTeX the beginning of the text fits in some cases
* (for example sections) exactly the label-width.
*/
int leftMargin(RowList::iterator rit) const;
int leftMargin(Row const & row) const;
///
int rightMargin(Buffer const &, Row const & row) const;
/** this calculates the specified parameters. needed when setting
* the cursor and when creating a visible row */
void prepareToPrint(RowList::iterator rit, float & x,
void prepareToPrint(RowList::iterator row, float & x,
float & fill_separator,
float & fill_hfill,
float & fill_label_hfill,
@ -600,7 +600,7 @@ private:
lyx::pos_type rowBreakPoint(Row const & row) const;
/// returns the minimum space a row needs on the screen in pixel
int fill(Row & row, int workwidth) const;
int fill(RowList::iterator row, int workwidth) const;
/**
* returns the minimum space a manual label needs on the

View File

@ -31,7 +31,7 @@
#include "lyxrow.h"
#include "rowpainter.h"
#include "lyxrc.h"
#include "lyxrow_funcs.h"
using std::max;
using lyx::pos_type;
@ -53,10 +53,10 @@ BufferView * perv(BufferView const & bv)
} // namespace anon
RowPainter::RowPainter(BufferView const & bv, LyXText const & text, RowList::iterator rit)
RowPainter::RowPainter(BufferView const & bv,
LyXText const & text, RowList::iterator rit)
: bv_(bv), pain_(bv_.painter()), text_(text), row_(rit), par_(*rit->par())
{
}
{}
/// "temporary"
@ -97,7 +97,7 @@ char const RowPainter::transformChar(char c, lyx::pos_type pos) const
int RowPainter::leftMargin() const
{
return text_.leftMargin(row_);
return text_.leftMargin(*row_);
}
@ -185,7 +185,7 @@ void RowPainter::paintArabicComposeChar(pos_type & vpos)
void RowPainter::paintChars(pos_type & vpos, bool hebrew, bool arabic)
{
pos_type pos = text_.vis2log(vpos);
pos_type const last = row_->lastPrintablePos();
pos_type const last = lastPrintablePos(text_, row_);
LyXFont orig_font(getFont(pos));
// first character
@ -359,7 +359,7 @@ void RowPainter::paintSelection()
pain_.fillRectangle(xo_, yo_, int(x_), row_->height(), LColor::selection);
pos_type const body_pos = par_.beginningOfBody();
pos_type const last = row_->lastPrintablePos();
pos_type const last = lastPrintablePos(text_, row_);
float tmpx = x_;
for (pos_type vpos = row_->pos(); vpos <= last; ++vpos) {
@ -375,7 +375,7 @@ void RowPainter::paintSelection()
tmpx -= singleWidth(body_pos - 1);
}
if (row_->hfillExpansion(pos)) {
if (hfillExpansion(text_, row_, pos)) {
tmpx += singleWidth(pos);
if (pos >= body_pos)
tmpx += hfill_;
@ -411,13 +411,13 @@ void RowPainter::paintSelection()
void RowPainter::paintChangeBar()
{
pos_type const start = row_->pos();
pos_type const end = row_->lastPrintablePos();
pos_type const end = lastPrintablePos(text_, row_);
if (!par_.isChanged(start, end))
return;
int const height = (row_->next()
? row_->height() + row_->next()->top_of_text()
int const height = (boost::next(row_) != text_.rows().end()
? row_->height() + boost::next(row_)->top_of_text()
: row_->baseline());
pain_.fillRectangle(4, yo_, 5, height, LColor::changebar);
@ -450,11 +450,11 @@ void RowPainter::paintDepthBar()
return;
Paragraph::depth_type prev_depth = 0;
if (row_->previous())
prev_depth = row_->previous()->par()->getDepth();
if (row_ != text_.rows().begin())
prev_depth = boost::prior(row_)->par()->getDepth();
Paragraph::depth_type next_depth = 0;
if (row_->next())
next_depth = row_->next()->par()->getDepth();
if (boost::next(row_) != text_.rows().end())
next_depth = boost::next(row_)->par()->getDepth();
for (Paragraph::depth_type i = 1; i <= depth; ++i) {
int x = (PAPER_MARGIN / 5) * i + xo_;
@ -620,7 +620,7 @@ void RowPainter::paintFirst()
}
// the top margin
if (!row_->previous() && !text_.isInInset())
if (row_ == text_.rows().begin() && !text_.isInInset())
y_top += PAPER_MARGIN;
// draw a top pagebreak
@ -767,7 +767,7 @@ void RowPainter::paintLast()
int y_bottom = row_->height() - 1;
// the bottom margin
if (!row_->next() && !text_.isInInset())
if (boost::next(row_) == text_.rows().end() && !text_.isInInset())
y_bottom -= PAPER_MARGIN;
int const ww = bv_.workWidth();
@ -846,7 +846,7 @@ void RowPainter::paintLast()
void RowPainter::paintText()
{
pos_type const last = row_->lastPrintablePos();
pos_type const last = lastPrintablePos(text_, row_);
pos_type body_pos = par_.beginningOfBody();
if (body_pos > 0 &&
(body_pos - 1 > last ||
@ -914,7 +914,7 @@ void RowPainter::paintText()
pain_.line(int(x_), y1, int(x_), y0,
LColor::added_space);
if (row_->hfillExpansion(pos)) {
if (hfillExpansion(text_, row_, pos)) {
int const y2 = (y0 + y1) / 2;
if (pos >= body_pos) {
@ -998,7 +998,7 @@ void RowPainter::paint(int y_offset, int x_offset, int y)
paintFirst();
}
if (row_->isParEnd()) {
if (isParEnd(text_, row_)) {
paintLast();
}

View File

@ -1,3 +1,4 @@
// -** C++ -*-
/**
* \file rowpainter.h
* This file is part of LyX, the document processor.

View File

@ -33,6 +33,7 @@
#include "WordLangTuple.h"
#include "paragraph_funcs.h"
#include "rowpainter.h"
#include "lyxrow_funcs.h"
#include "insets/insettext.h"
@ -149,7 +150,7 @@ int LyXText::workWidth(Inset * inset) const
Row dummyrow;
dummyrow.par(par);
dummyrow.pos(pos);
return workWidth() - leftMargin(&dummyrow);
return workWidth() - leftMargin(dummyrow);
} else {
int dummy_y;
RowList::iterator row = getRow(par, pos, dummy_y);
@ -162,7 +163,7 @@ int LyXText::workWidth(Inset * inset) const
// FIXME: I don't understand this code - jbl
unsigned int maxw = 0;
while (!frow->isParEnd()) {
while (!isParEnd(*this, frow)) {
if ((frow != row) && (maxw < frow->width()))
maxw = frow->width();
++frow;
@ -339,7 +340,7 @@ bool LyXText::bidi_InRange(lyx::pos_type pos) const
void LyXText::computeBidiTables(Buffer const * buf,
Row const & row) const
RowList::iterator row) const
{
bidi_same_direction = true;
if (!lyxrc.rtl_support) {
@ -347,15 +348,15 @@ void LyXText::computeBidiTables(Buffer const * buf,
return;
}
Inset * inset = row.par()->inInset();
Inset * inset = row->par()->inInset();
if (inset && inset->owner() &&
inset->owner()->lyxCode() == Inset::ERT_CODE) {
bidi_start = -1;
return;
}
bidi_start = row.pos();
bidi_end = row.lastPrintablePos();
bidi_start = row->pos();
bidi_end = lastPrintablePos(*this, row);
if (bidi_start > bidi_end) {
bidi_start = -1;
@ -377,25 +378,25 @@ void LyXText::computeBidiTables(Buffer const * buf,
pos_type stack[2];
bool const rtl_par =
row.par()->isRightToLeftPar(buf->params);
row->par()->isRightToLeftPar(buf->params);
int level = 0;
bool rtl = false;
bool rtl0 = false;
pos_type const body_pos = row.par()->beginningOfBody();
pos_type const body_pos = row->par()->beginningOfBody();
for (pos_type lpos = bidi_start; lpos <= bidi_end; ++lpos) {
bool is_space = row.par()->isLineSeparator(lpos);
bool is_space = row->par()->isLineSeparator(lpos);
pos_type const pos =
(is_space && lpos + 1 <= bidi_end &&
!row.par()->isLineSeparator(lpos + 1) &&
!row.par()->isNewline(lpos + 1))
!row->par()->isLineSeparator(lpos + 1) &&
!row->par()->isNewline(lpos + 1))
? lpos + 1 : lpos;
LyXFont font = row.par()->getFontSettings(buf->params, pos);
LyXFont font = row->par()->getFontSettings(buf->params, pos);
if (pos != lpos && 0 < lpos && rtl0 && font.isRightToLeft() &&
font.number() == LyXFont::ON &&
row.par()->getFontSettings(buf->params, lpos - 1).number()
row->par()->getFontSettings(buf->params, lpos - 1).number()
== LyXFont::ON) {
font = row.par()->getFontSettings(buf->params, lpos);
font = row->par()->getFontSettings(buf->params, lpos);
is_space = false;
}
@ -405,7 +406,7 @@ void LyXText::computeBidiTables(Buffer const * buf,
int new_level;
if (lpos == body_pos - 1
&& row.pos() < body_pos - 1
&& row->pos() < body_pos - 1
&& is_space) {
new_level = (rtl_par) ? 1 : 0;
new_rtl = new_rtl0 = rtl_par;
@ -500,19 +501,19 @@ bool LyXText::isBoundary(Buffer const * buf, Paragraph * par,
}
int LyXText::leftMargin(RowList::iterator rit) const
int LyXText::leftMargin(Row const & row) const
{
Inset * ins;
if (rit->pos() < rit->par()->size())
if ((rit->par()->getChar(rit->pos()) == Paragraph::META_INSET) &&
(ins = rit->par()->getInset(rit->pos())) &&
if (row.pos() < row.par()->size())
if ((row.par()->getChar(row.pos()) == Paragraph::META_INSET) &&
(ins = row.par()->getInset(row.pos())) &&
(ins->needFullRow() || ins->display()))
return LEFT_MARGIN;
LyXTextClass const & tclass =
bv()->buffer()->params.getLyXTextClass();
LyXLayout_ptr const & layout = rit->par()->layout();
LyXLayout_ptr const & layout = row.par()->layout();
string parindent = layout->parindent;
@ -523,12 +524,12 @@ int LyXText::leftMargin(RowList::iterator rit) const
// this is the way, LyX handles the LaTeX-Environments.
// I have had this idea very late, so it seems to be a
// later added hack and this is true
if (!rit->par()->getDepth()) {
if (rit->par()->layout() == tclass.defaultLayout()) {
if (!row.par()->getDepth()) {
if (row.par()->layout() == tclass.defaultLayout()) {
// find the previous same level paragraph
if (rit->par()->previous()) {
Paragraph * newpar = rit->par()
->depthHook(rit->par()->getDepth());
if (row.par()->previous()) {
Paragraph * newpar = row.par()
->depthHook(row.par()->getDepth());
if (newpar &&
newpar->layout()->nextnoindent)
parindent.erase();
@ -537,7 +538,7 @@ int LyXText::leftMargin(RowList::iterator rit) const
} else {
// find the next level paragraph
Paragraph * newpar = rit->par()->outerHook();
Paragraph * newpar = row.par()->outerHook();
// make a corresponding row. Needed to call LeftMargin()
@ -546,16 +547,16 @@ int LyXText::leftMargin(RowList::iterator rit) const
Row dummyrow;
dummyrow.par(newpar);
dummyrow.pos(newpar->size());
x = leftMargin(&dummyrow);
x = leftMargin(dummyrow);
} else {
// this is no longer an error, because this function
// is used to clear impossible depths after changing
// a layout. Since there is always a redo,
// LeftMargin() is always called
rit->par()->params().depth(0);
row.par()->params().depth(0);
}
if (newpar && rit->par()->layout() == tclass.defaultLayout()) {
if (newpar && row.par()->layout() == tclass.defaultLayout()) {
if (newpar->params().noindent())
parindent.erase();
else {
@ -565,17 +566,17 @@ int LyXText::leftMargin(RowList::iterator rit) const
}
}
LyXFont const labelfont = getLabelFont(bv()->buffer(), rit->par());
LyXFont const labelfont = getLabelFont(bv()->buffer(), row.par());
switch (layout->margintype) {
case MARGIN_DYNAMIC:
if (!layout->leftmargin.empty()) {
x += font_metrics::signedWidth(layout->leftmargin,
tclass.defaultfont());
}
if (!rit->par()->getLabelstring().empty()) {
if (!row.par()->getLabelstring().empty()) {
x += font_metrics::signedWidth(layout->labelindent,
labelfont);
x += font_metrics::width(rit->par()->getLabelstring(),
x += font_metrics::width(row.par()->getLabelstring(),
labelfont);
x += font_metrics::width(layout->labelsep, labelfont);
}
@ -583,9 +584,9 @@ int LyXText::leftMargin(RowList::iterator rit) const
case MARGIN_MANUAL:
x += font_metrics::signedWidth(layout->labelindent, labelfont);
// The width of an empty par, even with manual label, should be 0
if (!rit->par()->empty() && rit->pos() >= rit->par()->beginningOfBody()) {
if (!rit->par()->getLabelWidthString().empty()) {
x += font_metrics::width(rit->par()->getLabelWidthString(),
if (!row.par()->empty() && row.pos() >= row.par()->beginningOfBody()) {
if (!row.par()->getLabelWidthString().empty()) {
x += font_metrics::width(row.par()->getLabelWidthString(),
labelfont);
x += font_metrics::width(layout->labelsep, labelfont);
}
@ -593,23 +594,23 @@ int LyXText::leftMargin(RowList::iterator rit) const
break;
case MARGIN_STATIC:
x += font_metrics::signedWidth(layout->leftmargin, tclass.defaultfont()) * 4
/ (rit->par()->getDepth() + 4);
/ (row.par()->getDepth() + 4);
break;
case MARGIN_FIRST_DYNAMIC:
if (layout->labeltype == LABEL_MANUAL) {
if (rit->pos() >= rit->par()->beginningOfBody()) {
if (row.pos() >= row.par()->beginningOfBody()) {
x += font_metrics::signedWidth(layout->leftmargin,
labelfont);
} else {
x += font_metrics::signedWidth(layout->labelindent,
labelfont);
}
} else if (rit->pos()
} else if (row.pos()
// Special case to fix problems with
// theorems (JMarc)
|| (layout->labeltype == LABEL_STATIC
&& layout->latextype == LATEX_ENVIRONMENT
&& ! rit->par()->isFirstInSequence())) {
&& ! row.par()->isFirstInSequence())) {
x += font_metrics::signedWidth(layout->leftmargin,
labelfont);
} else if (layout->labeltype != LABEL_TOP_ENVIRONMENT
@ -619,7 +620,7 @@ int LyXText::leftMargin(RowList::iterator rit) const
x += font_metrics::signedWidth(layout->labelindent,
labelfont);
x += font_metrics::width(layout->labelsep, labelfont);
x += font_metrics::width(rit->par()->getLabelstring(),
x += font_metrics::width(row.par()->getLabelstring(),
labelfont);
}
break;
@ -631,14 +632,14 @@ int LyXText::leftMargin(RowList::iterator rit) const
// are *NOT* allowed in the LaTeX realisation of this layout.
// find the first row of this paragraph
RowList::iterator tmprit = rit;
while (tmprit != rowlist_.begin()
&& boost::prior(tmprit)->par() == rit->par())
--tmprit;
RowList::iterator tmprit = rowlist_.begin();
while (tmprit != rowlist_.end()
&& tmprit->par() != row.par())
++tmprit;
int minfill = tmprit->fill();
while (boost::next(tmprit) != rowlist_.end() &&
boost::next(tmprit)->par() == rit->par()) {
boost::next(tmprit)->par() == row.par()) {
++tmprit;
if (tmprit->fill() < minfill)
minfill = tmprit->fill();
@ -652,9 +653,9 @@ int LyXText::leftMargin(RowList::iterator rit) const
}
if ((workWidth() > 0) &&
!rit->par()->params().leftIndent().zero())
!row.par()->params().leftIndent().zero())
{
LyXLength const len = rit->par()->params().leftIndent();
LyXLength const len = row.par()->params().leftIndent();
int const tw = inset_owner ?
inset_owner->latexTextWidth(bv()) : workWidth();
x += len.inPixels(tw);
@ -662,26 +663,26 @@ int LyXText::leftMargin(RowList::iterator rit) const
LyXAlignment align; // wrong type
if (rit->par()->params().align() == LYX_ALIGN_LAYOUT)
if (row.par()->params().align() == LYX_ALIGN_LAYOUT)
align = layout->align;
else
align = rit->par()->params().align();
align = row.par()->params().align();
// set the correct parindent
if (rit->pos() == 0) {
if (row.pos() == 0) {
if ((layout->labeltype == LABEL_NO_LABEL
|| layout->labeltype == LABEL_TOP_ENVIRONMENT
|| layout->labeltype == LABEL_CENTERED_TOP_ENVIRONMENT
|| (layout->labeltype == LABEL_STATIC
&& layout->latextype == LATEX_ENVIRONMENT
&& ! rit->par()->isFirstInSequence()))
&& ! row.par()->isFirstInSequence()))
&& align == LYX_ALIGN_BLOCK
&& !rit->par()->params().noindent()
&& !row.par()->params().noindent()
// in tabulars and ert paragraphs are never indented!
&& (!rit->par()->inInset() || !rit->par()->inInset()->owner() ||
(rit->par()->inInset()->owner()->lyxCode() != Inset::TABULAR_CODE &&
rit->par()->inInset()->owner()->lyxCode() != Inset::ERT_CODE))
&& (rit->par()->layout() != tclass.defaultLayout() ||
&& (!row.par()->inInset() || !row.par()->inInset()->owner() ||
(row.par()->inInset()->owner()->lyxCode() != Inset::TABULAR_CODE &&
row.par()->inInset()->owner()->lyxCode() != Inset::ERT_CODE))
&& (row.par()->layout() != tclass.defaultLayout() ||
bv()->buffer()->params.paragraph_separation ==
BufferParams::PARSEP_INDENT)) {
x += font_metrics::signedWidth(parindent,
@ -757,7 +758,7 @@ int LyXText::labelEnd(Row const & row) const
Row tmprow = row;
tmprow.pos(row.par()->size());
// return the beginning of the body
return leftMargin(&tmprow);
return leftMargin(tmprow);
}
// LabelEnd is only needed if the layout
@ -812,7 +813,7 @@ LyXText::rowBreakPoint(Row const & row) const
// or the end of the par, then choose the possible break
// nearest that.
int const left = leftMargin(const_cast<Row*>(&row));
int const left = leftMargin(const_cast<Row&>(row));
int x = left;
// pixel width since last breakpoint
@ -907,36 +908,36 @@ LyXText::rowBreakPoint(Row const & row) const
// returns the minimum space a row needs on the screen in pixel
int LyXText::fill(Row & row, int paper_width) const
int LyXText::fill(RowList::iterator row, int paper_width) const
{
if (paper_width < 0)
return 0;
int w;
// get the pure distance
pos_type const last = row.lastPrintablePos();
pos_type const last = lastPrintablePos(*this, row);
// special handling of the right address boxes
if (row.par()->layout()->margintype == MARGIN_RIGHT_ADDRESS_BOX) {
int const tmpfill = row.fill();
row.fill(0); // the minfill in MarginLeft()
w = leftMargin(&row);
row.fill(tmpfill);
if (row->par()->layout()->margintype == MARGIN_RIGHT_ADDRESS_BOX) {
int const tmpfill = row->fill();
row->fill(0); // the minfill in MarginLeft()
w = leftMargin(*row);
row->fill(tmpfill);
} else
w = leftMargin(&row);
w = leftMargin(*row);
Paragraph * par = row.par();
Paragraph * par = row->par();
LyXLayout_ptr const & layout = par->layout();
pos_type const body_pos = par->beginningOfBody();
pos_type i = row.pos();
pos_type i = row->pos();
while (i <= last) {
if (body_pos > 0 && i == body_pos) {
w += font_metrics::width(layout->labelsep, getLabelFont(bv()->buffer(), par));
if (par->isLineSeparator(i - 1))
w -= singleWidth(par, i - 1);
int left_margin = labelEnd(row);
int left_margin = labelEnd(*row);
if (w < left_margin)
w = left_margin;
}
@ -947,12 +948,12 @@ int LyXText::fill(Row & row, int paper_width) const
w += font_metrics::width(layout->labelsep, getLabelFont(bv()->buffer(), par));
if (last >= 0 && par->isLineSeparator(last))
w -= singleWidth(par, last);
int const left_margin = labelEnd(row);
int const left_margin = labelEnd(*row);
if (w < left_margin)
w = left_margin;
}
int const fill = paper_width - w - rightMargin(*bv()->buffer(), row);
int const fill = paper_width - w - rightMargin(*bv()->buffer(), *row);
return fill;
}
@ -1002,6 +1003,10 @@ LColor::color LyXText::backgroundColor() const
void LyXText::setHeightOfRow(RowList::iterator rit)
{
// No need to do anything then...
if (rit == rows().end())
return;
// get the maximum ascent and the maximum descent
int asc = 0;
int desc = 0;
@ -1049,7 +1054,7 @@ void LyXText::setHeightOfRow(RowList::iterator rit)
layout->spacing.getValue() *
spacing_val);
pos_type const pos_end = rit->lastPos();
pos_type const pos_end = lastPos(*this, rit);
int labeladdon = 0;
int maxwidth = 0;
@ -1334,8 +1339,8 @@ void LyXText::appendParagraph(RowList::iterator rowit)
if (z < last) {
++z;
rowit = rowlist_.insert(rowit->next(),
new Row(rowit->par(), z));
Row newrow(rowit->par(), z);
rowit = rowlist_.insert(boost::next(rowit), newrow);
} else {
done = true;
}
@ -1343,8 +1348,8 @@ void LyXText::appendParagraph(RowList::iterator rowit)
// Set the dimensions of the row
// fixed fill setting now by calling inset->update() in
// SingleWidth when needed!
tmprow->fill(fill(*tmprow, workWidth()));
setHeightOfRow(&*tmprow);
tmprow->fill(fill(tmprow, workWidth()));
setHeightOfRow(tmprow);
} while (!done);
}
@ -1367,7 +1372,8 @@ void LyXText::breakAgain(RowList::iterator rit)
boost::next(rit)->par() != rit->par())) {
// insert a new row
++z;
rit = rowlist_.insert(boost::next(rit), new Row(rit->par(), z));
Row newrow(rit->par(), z);
rit = rowlist_.insert(boost::next(rit), newrow);
} else {
++rit;
++z;
@ -1381,7 +1387,8 @@ void LyXText::breakAgain(RowList::iterator rit)
// if there are some rows too much, delete them
// only if you broke the whole paragraph!
RowList::iterator tmprit2 = rit;
while (boost::next(tmprit2) != end && boost::next(tmprit2)->par() == rit->par()) {
while (boost::next(tmprit2) != end
&& boost::next(tmprit2)->par() == rit->par()) {
++tmprit2;
}
while (tmprit2 != rit) {
@ -1392,7 +1399,7 @@ void LyXText::breakAgain(RowList::iterator rit)
}
// set the dimensions of the row
tmprit->fill(fill(*tmprit, workWidth()));
tmprit->fill(fill(tmprit, workWidth()));
setHeightOfRow(tmprit);
} while (not_ready);
}
@ -1405,13 +1412,16 @@ void LyXText::breakAgainOneRow(RowList::iterator rit)
pos_type z = rowBreakPoint(*rit);
RowList::iterator tmprit = rit;
RowList::iterator end = rows().end();
if (z < rit->par()->size()) {
if (boost::next(rit) == rows().end()
|| (boost::next(rit) != rows().end() && boost::next(rit)->par() != rit->par())) {
if (boost::next(rit) == end ||
(boost::next(rit) != end &&
boost::next(rit)->par() != rit->par())) {
// insert a new row
++z;
rit = rowlist_.insert(boost::next(rit), new Row(rit->par(), z));
Row newrow(rit->par(), z);
rit = rowlist_.insert(boost::next(rit), newrow);
} else {
++rit;
++z;
@ -1422,7 +1432,7 @@ void LyXText::breakAgainOneRow(RowList::iterator rit)
// if there are some rows too much, delete them
// only if you broke the whole paragraph!
RowList::iterator tmprit2 = rit;
while (boost::next(tmprit2) != rows().end()
while (boost::next(tmprit2) != end
&& boost::next(tmprit2)->par() == rit->par()) {
++tmprit2;
}
@ -1433,7 +1443,7 @@ void LyXText::breakAgainOneRow(RowList::iterator rit)
}
// set the dimensions of the row
tmprit->fill(fill(*tmprit, workWidth()));
tmprit->fill(fill(tmprit, workWidth()));
setHeightOfRow(tmprit);
}
@ -1516,7 +1526,7 @@ void LyXText::breakParagraph(ParagraphList & paragraphs, char keep_layout)
removeParagraph(cursor.row());
// set the dimensions of the cursor row
cursor.row()->fill(fill(*cursor.row(), workWidth()));
cursor.row()->fill(fill(cursor.row(), workWidth()));
setHeightOfRow(cursor.row());
@ -1528,7 +1538,7 @@ void LyXText::breakParagraph(ParagraphList & paragraphs, char keep_layout)
&& cursor.par()->next()->isNewline(0))
cursor.par()->next()->erase(0);
insertParagraph(cursor.par()->next(), cursor.row()->next());
insertParagraph(cursor.par()->next(), boost::next(cursor.row()));
updateCounters();
// This check is necessary. Otherwise the new empty paragraph will
@ -1538,8 +1548,8 @@ void LyXText::breakParagraph(ParagraphList & paragraphs, char keep_layout)
else
setCursor(cursor.par(), 0);
if (cursor.row()->next())
breakAgain(cursor.row()->next());
if (boost::next(cursor.row()) != rows().end())
breakAgain(boost::next(cursor.row()));
need_break_row = rows().end();
}
@ -1687,26 +1697,27 @@ void LyXText::insertChar(char c)
}
// Is there a break one row above
if (row->previous() && row->previous()->par() == row->par()
if (row != rows().begin() &&
boost::prior(row)->par() == row->par()
&& (cursor.par()->isLineSeparator(cursor.pos())
|| cursor.par()->isNewline(cursor.pos())
|| ((cursor.pos() + 1 < cursor.par()->size()) &&
cursor.par()->isInset(cursor.pos() + 1))
|| cursor.row()->fill() == -1))
{
pos_type z = rowBreakPoint(*row->previous());
pos_type z = rowBreakPoint(*boost::prior(row));
if (z >= row->pos()) {
row->pos(z + 1);
// set the dimensions of the row above
row->previous()->fill(fill(
*row->previous(),
boost::prior(row)->fill(fill(
boost::prior(row),
workWidth()));
setHeightOfRow(row->previous());
setHeightOfRow(boost::prior(row));
y -= row->previous()->height();
y -= boost::prior(row)->height();
postPaint(y);
@ -1718,8 +1729,9 @@ void LyXText::insertChar(char c)
false, cursor.boundary());
// cursor MUST be in row now.
if (row->next() && row->next()->par() == row->par())
need_break_row = row->next();
if (boost::next(row) != rows().end() &&
boost::next(row)->par() == row->par())
need_break_row = boost::next(row);
else
need_break_row = rows().end();
@ -1737,17 +1749,19 @@ void LyXText::insertChar(char c)
if (row->fill() >= 0) {
// needed because a newline will set fill to -1. Otherwise
// we would not get a rebreak!
row->fill(fill(*row, workWidth()));
row->fill(fill(row, workWidth()));
}
if (c == Paragraph::META_INSET || row->fill() < 0) {
postPaint(y);
breakAgainOneRow(row);
// will the cursor be in another row now?
if (row->lastPos() <= cursor.pos() + 1 && row->next()) {
if (row->next() && row->next()->par() == row->par())
if (lastPos(*this, row) <= cursor.pos() + 1 &&
boost::next(row) != rows().end()) {
if (boost::next(row) != rows().end() &&
boost::next(row)->par() == row->par())
// this should always be true
row = row->next();
++row;
breakAgainOneRow(row);
}
current_font = rawtmpfont;
@ -1759,8 +1773,9 @@ void LyXText::insertChar(char c)
!= cursor.boundary())
setCursor(cursor.par(), cursor.pos(), false,
!cursor.boundary());
if (row->next() && row->next()->par() == row->par())
need_break_row = row->next();
if (boost::next(row) != rows().end() &&
boost::next(row)->par() == row->par())
need_break_row = boost::next(row);
else
need_break_row = rows().end();
} else {
@ -1818,7 +1833,6 @@ void LyXText::prepareToPrint(RowList::iterator rit, float & x,
bool bidi) const
{
float nlh;
float ns;
float w = rit->fill();
fill_hfill = 0;
@ -1833,7 +1847,7 @@ void LyXText::prepareToPrint(RowList::iterator rit, float & x,
? rightMargin(*bv()->buffer(), *rit) : 0;
} else
x = (workWidth() > 0)
? leftMargin(rit) : 0;
? leftMargin(*rit) : 0;
// is there a manual margin with a manual label
LyXLayout_ptr const & layout = rit->par()->layout();
@ -1841,7 +1855,7 @@ void LyXText::prepareToPrint(RowList::iterator rit, float & x,
if (layout->margintype == MARGIN_MANUAL
&& layout->labeltype == LABEL_MANUAL) {
/// We might have real hfills in the label part
nlh = rit->numberOfLabelHfills();
nlh = numberOfLabelHfills(*this, rit);
// A manual label par (e.g. List) has an auto-hfill
// between the label text and the body of the
@ -1857,7 +1871,7 @@ void LyXText::prepareToPrint(RowList::iterator rit, float & x,
}
// are there any hfills in the row?
float const nh = rit->numberOfHfills();
float const nh = numberOfHfills(*this, rit);
if (nh) {
if (w > 0)
@ -1894,16 +1908,16 @@ void LyXText::prepareToPrint(RowList::iterator rit, float & x,
switch (align) {
case LYX_ALIGN_BLOCK:
{
ns = rit->numberOfSeparators();
float const ns = numberOfSeparators(*this, rit);
RowList::iterator next_row = boost::next(rit);
if (ns && next_row != rowlist_.end() &&
next_row->par() == rit->par() &&
!(next_row->par()->isNewline(next_row->pos() - 1))
&& !(next_row->par()->isInset(next_row->pos()) &&
next_row->par()->getInset(next_row->pos()) &&
next_row->par()->getInset(next_row->pos())->display())
)
{
) {
fill_separator = w / ns;
} else if (is_rtl) {
x += w;
@ -1921,10 +1935,10 @@ void LyXText::prepareToPrint(RowList::iterator rit, float & x,
if (!bidi)
return;
computeBidiTables(bv()->buffer(), *rit);
computeBidiTables(bv()->buffer(), rit);
if (is_rtl) {
pos_type body_pos = rit->par()->beginningOfBody();
pos_type last = rit->lastPos();
pos_type last = lastPos(*this, rit);
if (body_pos > 0 &&
(body_pos - 1 > last ||
@ -2612,7 +2626,7 @@ void LyXText::backspace()
pos_type z;
// remember that a space at the end of a row doesnt count
// when calculating the fill
if (cursor.pos() < row->lastPos() ||
if (cursor.pos() < lastPos(*this, row) ||
!cursor.par()->isLineSeparator(cursor.pos())) {
row->fill(row->fill() + singleWidth(
cursor.par(),
@ -2697,7 +2711,7 @@ void LyXText::backspace()
// set the dimensions of the row above
y -= tmprow->height();
tmprow->fill(fill(*tmprow, workWidth()));
tmprow->fill(fill(tmprow, workWidth()));
setHeightOfRow(tmprow);
postPaint(y);
@ -2718,14 +2732,14 @@ void LyXText::backspace()
// break the cursor row again
if (boost::next(row) != rows().end() &&
boost::next(row)->par() == row->par() &&
(row->lastPos() == row->par()->size() - 1 ||
rowBreakPoint(*row) != row->lastPos())) {
(lastPos(*this, row) == row->par()->size() - 1 ||
rowBreakPoint(*row) != lastPos(*this, row))) {
// it can happen that a paragraph loses one row
// without a real breakup. This is when a word
// is to long to be broken. Well, I don t care this
// hack ;-)
if (row->lastPos() == row->par()->size() - 1)
if (lastPos(*this, row) == row->par()->size() - 1)
removeRow(boost::next(row));
postPaint(y);
@ -2734,7 +2748,7 @@ void LyXText::backspace()
// will the cursor be in another row now?
if (boost::next(row) != rows().end() &&
boost::next(row)->par() == row->par() &&
row->lastPos() <= cursor.pos()) {
lastPos(*this, row) <= cursor.pos()) {
++row;
breakAgainOneRow(row);
}
@ -2748,7 +2762,7 @@ void LyXText::backspace()
need_break_row = rows().end();
} else {
// set the dimensions of the row
row->fill(fill(*row, workWidth()));
row->fill(fill(row, workWidth()));
int const tmpheight = row->height();
setHeightOfRow(row);
if (tmpheight == row->height()) {

View File

@ -29,6 +29,7 @@
#include "language.h"
#include "ParagraphParameters.h"
#include "counters.h"
#include "lyxrow_funcs.h"
#include "insets/inseterror.h"
#include "insets/insetbibitem.h"
@ -58,6 +59,7 @@ LyXText::LyXText(BufferView * bv)
anchor_row_ = rows().end();
need_break_row = rows().end();
refresh_row = rows().end();
clearPaint();
}
@ -69,6 +71,7 @@ LyXText::LyXText(BufferView * bv, InsetText * inset)
anchor_row_ = rows().end();
need_break_row = rows().end();
refresh_row = rows().end();
clearPaint();
}
@ -308,7 +311,8 @@ void LyXText::removeParagraph(RowList::iterator rit)
void LyXText::insertParagraph(Paragraph * par, RowList::iterator rowit)
{
// insert a new row, starting at position 0
RowList::iterator rit = rowlist_.insert(rowit, new Row(par, 0));
Row newrow(par, 0);
RowList::iterator rit = rowlist_.insert(rowit, newrow);
// and now append the whole paragraph before the new row
appendParagraph(rit);
@ -889,18 +893,22 @@ void LyXText::cursorEnd()
{
if (cursor.par()->empty())
return;
#warning FIXME
// There is a lot of unneeded recalculation going on here:
// - boost::next(curosr.row())
// - lastPost(*this, cursor.row())
if (!cursor.row()->next()
|| cursor.row()->next()->par() != cursor.row()->par()) {
setCursor(cursor.par(), cursor.row()->lastPos() + 1);
if (boost::next(cursor.row()) == rows().end()
|| boost::next(cursor.row())->par() != cursor.row()->par()) {
setCursor(cursor.par(), lastPos(*this, cursor.row()) + 1);
} else {
if (!cursor.par()->empty() &&
(cursor.par()->getChar(cursor.row()->lastPos()) == ' '
|| cursor.par()->isNewline(cursor.row()->lastPos()))) {
setCursor(cursor.par(), cursor.row()->lastPos());
(cursor.par()->getChar(lastPos(*this, cursor.row())) == ' '
|| cursor.par()->isNewline(lastPos(*this, cursor.row())))) {
setCursor(cursor.par(), lastPos(*this, cursor.row()));
} else {
setCursor(cursor.par(),
cursor.row()->lastPos() + 1);
lastPos(*this, cursor.row()) + 1);
}
}
}
@ -1579,11 +1587,11 @@ void LyXText::checkParagraph(Paragraph * par, pos_type pos)
}
int const tmpheight = row->height();
pos_type const tmplast = row->lastPos();
pos_type const tmplast = lastPos(*this, row);
breakAgain(&*row);
if (row->height() == tmpheight && row->lastPos() == tmplast) {
postRowPaint(&*row, y);
breakAgain(row);
if (row->height() == tmpheight && lastPos(*this, row) == tmplast) {
postRowPaint(row, y);
} else {
postPaint(y);
}
@ -1591,7 +1599,7 @@ void LyXText::checkParagraph(Paragraph * par, pos_type pos)
// check the special right address boxes
if (par->layout()->margintype == MARGIN_RIGHT_ADDRESS_BOX) {
tmpcursor.par(par);
tmpcursor.row(&*row);
tmpcursor.row(row);
tmpcursor.y(y);
tmpcursor.x(0);
tmpcursor.x_fix(0);
@ -1693,13 +1701,13 @@ void LyXText::setCursor(LyXCursor & cur, Paragraph * par,
y -= row->height();
}
cur.row(&*row);
cur.row(row);
// y is now the beginning of the cursor row
y += row->baseline();
// y is now the cursor baseline
cur.y(y);
pos_type last = old_row->lastPrintablePos();
pos_type last = lastPrintablePos(*this, old_row);
// None of these should happen, but we're scaredy-cats
if (pos > par->size()) {
@ -1718,18 +1726,18 @@ void LyXText::setCursor(LyXCursor & cur, Paragraph * par,
}
// now get the cursors x position
float x = getCursorX(&*row, pos, last, boundary);
float x = getCursorX(row, pos, last, boundary);
cur.x(int(x));
cur.x_fix(cur.x());
if (old_row != row) {
x = getCursorX(&*old_row, pos, last, boundary);
x = getCursorX(old_row, pos, last, boundary);
cur.ix(int(x));
} else
cur.ix(cur.x());
//if the cursor is in a visible row, anchor to it
int topy = top_y();
if (topy < y && y < topy + bv()->workHeight())
anchor_row(&*row);
anchor_row(row);
}
@ -1777,7 +1785,8 @@ float LyXText::getCursorX(RowList::iterator rit,
if (rit->par()->isLineSeparator(body_pos - 1))
x -= singleWidth(rit->par(), body_pos - 1);
}
if (rit->hfillExpansion(pos)) {
if (hfillExpansion(*this, rit, pos)) {
x += singleWidth(rit->par(), pos);
if (pos >= body_pos)
x += fill_hfill;
@ -1880,7 +1889,7 @@ LyXText::getColumnNearX(RowList::iterator rit, int & x, bool & boundary) const
fill_hfill, fill_label_hfill);
pos_type vc = rit->pos();
pos_type last = rit->lastPrintablePos();
pos_type last = lastPrintablePos(*this, rit);
pos_type c = 0;
LyXLayout_ptr const & layout = rit->par()->layout();
@ -1912,7 +1921,7 @@ LyXText::getColumnNearX(RowList::iterator rit, int & x, bool & boundary) const
tmpx -= singleWidth(rit->par(), body_pos - 1);
}
if (rit->hfillExpansion(c)) {
if (hfillExpansion(*this, rit, c)) {
tmpx += singleWidth(rit->par(), c);
if (c >= body_pos)
tmpx += fill_hfill;
@ -1996,10 +2005,11 @@ namespace {
* and the next row is filled by an inset that spans an entire
* row.
*/
bool beforeFullRowInset(Row & row, LyXCursor & cur) {
if (!row.next())
bool beforeFullRowInset(LyXText & lt, RowList::iterator row,
LyXCursor & cur) {
if (boost::next(row) == lt.rows().end())
return false;
Row const & next = *row.next();
Row const & next = *boost::next(row);
if (next.pos() != cur.pos() || next.par() != cur.par())
return false;
@ -2019,23 +2029,23 @@ void LyXText::setCursorFromCoordinates(LyXCursor & cur, int x, int y)
RowList::iterator row = getRowNearY(y);
bool bound = false;
pos_type const column = getColumnNearX(&*row, x, bound);
pos_type const column = getColumnNearX(row, x, bound);
cur.par(row->par());
cur.pos(row->pos() + column);
cur.x(x);
cur.y(y + row->baseline());
cur.row(&*row);
cur.row(row);
if (beforeFullRowInset(*row, cur)) {
pos_type last = row->lastPrintablePos();
float x = getCursorX(row->next(), cur.pos(), last, bound);
if (beforeFullRowInset(*this, row, cur)) {
pos_type last = lastPrintablePos(*this, row);
float x = getCursorX(boost::next(row), cur.pos(), last, bound);
cur.ix(int(x));
cur.iy(y + row->height() + row->next()->baseline());
cur.irow(row->next());
cur.iy(y + row->height() + boost::next(row)->baseline());
cur.irow(boost::next(row));
} else {
cur.iy(cur.y());
cur.ix(cur.x());
cur.irow(&*row);
cur.irow(row);
}
cur.boundary(bound);
}
@ -2257,9 +2267,9 @@ bool LyXText::deleteEmptyParagraphMechanism(LyXCursor const & old_cursor)
deleted = true;
if (old_cursor.row()->previous()) {
if (old_cursor.row() != rows().begin()) {
const_cast<LyXText *>(this)->postPaint(old_cursor.y() - old_cursor.row()->baseline()
- old_cursor.row()->previous()->height());
- boost::prior(old_cursor.row())->height());
tmpcursor = cursor;
cursor = old_cursor; // that undo can restore the right cursor position
Paragraph * endpar = old_cursor.par()->next();
@ -2284,14 +2294,14 @@ bool LyXText::deleteEmptyParagraphMechanism(LyXCursor const & old_cursor)
* The next row can change its height, if
* there is another layout before */
if (refresh_row != rows().end()) {
if (refresh_row->next()) {
breakAgain(refresh_row->next());
if (boost::next(refresh_row) != rows().end()) {
breakAgain(boost::next(refresh_row));
updateCounters();
}
setHeightOfRow(refresh_row);
}
} else {
Row * nextrow = old_cursor.row()->next();
RowList::iterator nextrow = boost::next(old_cursor.row());
const_cast<LyXText *>(this)->postPaint(
old_cursor.y() - old_cursor.row()->baseline());
@ -2319,7 +2329,7 @@ bool LyXText::deleteEmptyParagraphMechanism(LyXCursor const & old_cursor)
the parindent that can occur or dissappear.
The next row can change its height, if
there is another layout before */
if (nextrow) {
if (nextrow != rows().end()) {
breakAgain(nextrow);
updateCounters();
}

View File

@ -240,7 +240,7 @@ void LyXText::cursorPrevious()
{
int y = top_y();
if (!cursor.row()->previous()) {
if (cursor.row() == rows().begin()) {
if (y > 0) {
int new_y = bv()->text->top_y() - bv()->workHeight();
bv()->screen().draw(bv()->text, bv(), new_y < 0 ? 0 : new_y);
@ -279,10 +279,10 @@ void LyXText::cursorPrevious()
}
}
bv()->screen().draw(bv()->text, bv(), new_y < 0 ? 0 : new_y);
if (cursor.row()->previous()) {
if (cursor.row() != rows().begin()) {
LyXCursor cur;
setCursor(cur, cursor.row()->previous()->par(),
cursor.row()->previous()->pos(), false);
setCursor(cur, boost::prior(cursor.row())->par(),
boost::prior(cursor.row())->pos(), false);
if (cur.y() > top_y()) {
cursorUp(true);
}
@ -295,7 +295,7 @@ void LyXText::cursorNext()
{
int topy = top_y();
if (!cursor.row()->next()) {
if (boost::next(cursor.row()) == rows().end()) {
int y = cursor.y() - cursor.row()->baseline() +
cursor.row()->height();
if (y > topy + bv()->workHeight()) {
@ -340,10 +340,10 @@ void LyXText::cursorNext()
}
}
bv()->screen().draw(bv()->text, bv(), new_y);
if (cursor.row()->next()) {
if (boost::next(cursor.row()) != rows().end()) {
LyXCursor cur;
setCursor(cur, cursor.row()->next()->par(),
cursor.row()->next()->pos(), false);
setCursor(cur, boost::next(cursor.row())->par(),
boost::next(cursor.row())->pos(), false);
if (cur.y() < top_y() + bv()->workHeight()) {
cursorDown(true);
}
@ -416,7 +416,7 @@ Inset::RESULT LyXText::dispatch(FuncRequest const & cmd)
setUndo(bv, Undo::EDIT, tmp, tmp->next());
tmp->params().startOfAppendix(false);
int tmpy;
setHeightOfRow(&*getRow(tmp, 0, tmpy));
setHeightOfRow(getRow(tmp, 0, tmpy));
break;
}
}