split LyXText::rowlist_ into individual Paragraph::rows_ chunks

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@7551 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
André Pönitz 2003-08-15 08:03:54 +00:00
parent 65da8b780e
commit 09e0187997
15 changed files with 317 additions and 437 deletions

View File

@ -1,3 +1,17 @@
2003-08-15 André Pönitz <poenitz@gmx.net>
* lyxrow_funcs.[Ch]:
* lyxtext.h:
* paragraph.h:
* paragraph_funcs.C:
* rowpainter.C:
* text.C:
* text2.C:
* text3.C:
* text_funcs.C: split LyXText::rowlist_ into individual
Paragraph::rows_ chunks
2003-08-12 Michael Schmitt <michael.schmitt@teststep.org>
* bufferlist.C: beautify two alerts (shorter text of buttons)

View File

@ -393,7 +393,8 @@ void LyXScreen::drawFromTo(LyXText * text, BufferView * bv,
int const topy = text->top_y();
int y_text = topy + y1;
RowList::iterator rit = text->getRowNearY(y_text);
ParagraphList::iterator dummypit;
RowList::iterator rit = text->getRowNearY(y_text, dummypit);
int y = y_text - topy;
y = paintRows(*bv, *text, rit, xo, y, y, y2, yo);

View File

@ -1,8 +1,12 @@
2003-08-15 André Pönitz <poenitz@gmx.net>
* insettext.[Ch]: adjust after rowlist split
2003-08-12 Michael Schmitt <michael.schmitt@teststep.org>
* insettabular.C: rename M_VALIGN_CENTER to M_VALIGN_MIDDLE;
rename valign-center to valign-middle;
rename VALIGN_CENTER to VALIGN_MIDDLE
* insettabular.C: rename M_VALIGN_CENTER to M_VALIGN_MIDDLE;
rename valign-center to valign-middle;
rename VALIGN_CENTER to VALIGN_MIDDLE
2003-08-11 André Pönitz <poenitz@gmx.net>

View File

@ -289,6 +289,7 @@ void InsetText::draw(PainterInfo & pi, int x, int baseline) const
RowList::iterator rit = text_.firstRow();
RowList::iterator end = text_.endRow();
ParagraphList::iterator pit = paragraphs.begin();
int y_offset = baseline - rit->ascent_of_text();
int y2 = pain.paperHeight();
@ -297,7 +298,7 @@ void InsetText::draw(PainterInfo & pi, int x, int baseline) const
while (rit != end && y + rit->height() <= 0) {
y += rit->height();
first += rit->height();
rit = text_.nextRow(rit);
text_.nextRow(pit, rit);
}
if (y_offset < 0) {
text_.top_y(-y_offset);

View File

@ -202,7 +202,7 @@ public:
return true;
}
///
ParagraphList paragraphs;
mutable ParagraphList paragraphs;
protected:
///
void updateLocal(BufferView *, bool mark_dirty);

View File

@ -14,21 +14,19 @@ using std::max;
using std::min;
bool isParEnd(LyXText const & lt,
ParagraphList::iterator pit, RowList::iterator rit)
bool isParEnd(Paragraph const & par, RowList::iterator rit)
{
return boost::next(rit) == lt.endRow(pit);
return boost::next(rit) == par.rows.end();
}
pos_type lastPos(LyXText const & lt,
ParagraphList::iterator pit, RowList::iterator rit)
pos_type lastPos(Paragraph const & par, RowList::iterator rit)
{
if (pit->empty())
if (par.empty())
return 0;
if (isParEnd(lt, pit, rit))
return pit->size() - 1;
if (isParEnd(par, rit))
return par.size() - 1;
return boost::next(rit)->pos() - 1;
}
@ -37,45 +35,43 @@ pos_type lastPos(LyXText const & lt,
namespace {
bool nextRowIsAllInset(
ParagraphList::iterator pit, RowList::iterator rit, pos_type last)
Paragraph const & par, pos_type last)
{
if (last + 1 >= pit->size())
if (last + 1 >= par.size())
return false;
if (!pit->isInset(last + 1))
if (!par.isInset(last + 1))
return false;
InsetOld const * i = pit->getInset(last + 1);
InsetOld const * i = par.getInset(last + 1);
return i->needFullRow() || i->display();
}
} // anon namespace
pos_type lastPrintablePos(LyXText const & lt,
ParagraphList::iterator pit, RowList::iterator rit)
pos_type lastPrintablePos(Paragraph const & par, RowList::iterator rit)
{
pos_type const last = lastPos(lt, pit, rit);
pos_type const last = lastPos(par, rit);
// if this row is an end of par, just act like lastPos()
if (isParEnd(lt, pit, rit))
if (isParEnd(par, rit))
return last;
if (!nextRowIsAllInset(pit, rit, last) && pit->isSeparator(last))
if (!nextRowIsAllInset(par, last) && par.isSeparator(last))
return last - 1;
return last;
}
int numberOfSeparators(LyXText const & lt,
ParagraphList::iterator pit, RowList::iterator rit)
int numberOfSeparators(Paragraph const & par, RowList::iterator rit)
{
pos_type const last = lastPrintablePos(lt, pit, rit);
pos_type const last = lastPrintablePos(par, rit);
int n = 0;
pos_type p = max(rit->pos(), pit->beginningOfBody());
pos_type p = max(rit->pos(), par.beginningOfBody());
for ( ; p < last; ++p)
if (pit->isSeparator(p))
if (par.isSeparator(p))
++n;
return n;
}
@ -83,67 +79,64 @@ int numberOfSeparators(LyXText const & lt,
// This is called _once_ from LyXText and should at least be moved into
// an anonymous namespace there. (Lgb)
int numberOfHfills(LyXText const & lt,
ParagraphList::iterator pit, RowList::iterator rit)
int numberOfHfills(Paragraph const & par, RowList::iterator rit)
{
pos_type const last = lastPos(lt, pit, rit);
pos_type const last = lastPos(par, rit);
pos_type first = rit->pos();
// hfill *DO* count at the beginning of paragraphs!
if (first) {
while (first < last && pit->isHfill(first))
while (first < last && par.isHfill(first))
++first;
}
first = max(first, pit->beginningOfBody());
first = max(first, par.beginningOfBody());
int n = 0;
// last, because the end is ignored!
for (pos_type p = first; p < last; ++p) {
if (pit->isHfill(p))
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,
ParagraphList::iterator pit, RowList::iterator rit)
int numberOfLabelHfills(Paragraph const & par, RowList::iterator rit)
{
pos_type last = lastPos(lt, pit, rit);
pos_type last = lastPos(par, rit);
pos_type first = rit->pos();
// hfill *DO* count at the beginning of paragraphs!
if (first) {
while (first < last && pit->isHfill(first))
while (first < last && par.isHfill(first))
++first;
}
last = min(last, pit->beginningOfBody());
last = min(last, par.beginningOfBody());
int n = 0;
// last, because the end is ignored!
for (pos_type p = first; p < last; ++p) {
if (pit->isHfill(p))
if (par.isHfill(p))
++n;
}
return n;
}
bool hfillExpansion(LyXText const & lt,
ParagraphList::iterator pit, RowList::iterator rit, pos_type pos)
bool hfillExpansion(Paragraph const & par, RowList::iterator rit, pos_type pos)
{
if (!pit->isHfill(pos))
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, pit, rit))
for (pos_type i = rit->pos(); i < pos && !pit->isHfill(i); ++i)
if (pos >= lastPos(par, rit))
for (pos_type i = rit->pos(); i < pos && !par.isHfill(i); ++i)
return false;
// at the beginning of a row it does not count, if it is not
@ -152,15 +145,15 @@ bool hfillExpansion(LyXText const & lt,
return true;
// in some labels it does not count
if (pit->layout()->margintype != MARGIN_MANUAL
&& pos < pit->beginningOfBody())
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 && (pit->isNewline(i) || pit->isHfill(i)))
while (i < pos && (par.isNewline(i) || par.isHfill(i)))
++i;
return i != pos;

View File

@ -4,31 +4,23 @@
#define LYXROW_FUNCS_H
#include "RowList.h"
#include "ParagraphList.h"
#include "support/types.h"
class LyXText;
class Paragraph;
bool isParEnd(LyXText const & lt,
ParagraphList::iterator pit, RowList::iterator rit);
bool isParEnd(Paragraph const & par, RowList::iterator rit);
lyx::pos_type lastPos(LyXText const & lt,
ParagraphList::iterator pit, RowList::iterator rit);
lyx::pos_type lastPos(Paragraph const & par, RowList::iterator rit);
lyx::pos_type lastPrintablePos(LyXText const & lt,
ParagraphList::iterator pit, RowList::iterator rit);
lyx::pos_type lastPrintablePos(Paragraph const & par, RowList::iterator rit);
int numberOfSeparators(LyXText const & lt,
ParagraphList::iterator pit, RowList::iterator rit);
int numberOfSeparators(Paragraph const & par, RowList::iterator rit);
int numberOfHfills(LyXText const & lt,
ParagraphList::iterator pit, RowList::iterator rit);
int numberOfHfills(Paragraph const & par, RowList::iterator rit);
int numberOfLabelHfills(LyXText const & lt,
ParagraphList::iterator pit, RowList::iterator rit);
int numberOfLabelHfills(Paragraph const & par, RowList::iterator rit);
bool hfillExpansion(LyXText const & lt,
ParagraphList::iterator pit, RowList::iterator rit, lyx::pos_type pos);
bool hfillExpansion(Paragraph const & par, RowList::iterator rit,
lyx::pos_type pos);
#endif

View File

@ -189,7 +189,8 @@ public:
(relative to the whole text). y is set to the real beginning
of this row
*/
RowList::iterator getRowNearY(int & y) const;
RowList::iterator getRowNearY(int & y,
ParagraphList::iterator & pit) const;
/** returns the column near the specified x-coordinate of the row
x is set to the real beginning of this column
@ -203,11 +204,6 @@ public:
RowList::iterator
getRow(ParagraphList::iterator pit, lyx::pos_type pos, int & y) const;
RowList & rows() const {
return rowlist_;
}
/// need the selection cursor:
void setSelection();
///
@ -378,9 +374,6 @@ public:
///
bool bidi_InRange(lyx::pos_type pos) const;
private:
///
mutable RowList rowlist_;
///
float getCursorX(ParagraphList::iterator pit,
RowList::iterator rit, lyx::pos_type pos,
@ -388,28 +381,12 @@ private:
/// used in setlayout
void makeFontEntriesLayoutSpecific(BufferParams const &, Paragraph & par);
/** forces the redrawing of a paragraph. Needed when manipulating a
right address box
*/
void redoDrawingOfParagraph(LyXCursor const & cursor);
/// removes the row and reset the touched counters
void removeRow(RowList::iterator rit);
/// remove all following rows of the paragraph of the specified row.
void removeParagraph(ParagraphList::iterator pit, RowList::iterator rit);
/// insert the specified paragraph behind the specified row
void insertParagraph(ParagraphList::iterator pit,
RowList::iterator rowit);
/// Calculate and set the height of the row
void setHeightOfRow(ParagraphList::iterator, RowList::iterator rit);
// fix the cursor `cur' after a characters has been deleted at `where'
// position. Called by deleteEmptyParagraphMechanism
void fixCursorAfterDelete(LyXCursor & cur,
LyXCursor const & where);
void fixCursorAfterDelete(LyXCursor & cur, LyXCursor const & where);
/// delete double space (false) or empty paragraphs (true) around old_cursor
bool deleteEmptyParagraphMechanism(LyXCursor const & old_cursor);
@ -516,12 +493,6 @@ public:
/// return true if this is owned by an inset.
bool isInInset() const;
/// recreate paragraphlist iterator from rowlist iterator
ParagraphList::iterator getPar(RowList::iterator rit) const;
/// return first row of par
RowList::iterator beginRow(ParagraphList::iterator pit) const;
/// return row "behind" last of par
RowList::iterator endRow(ParagraphList::iterator pit) const;
/// return first row of text
RowList::iterator firstRow() const;
/// return last row of text
@ -529,9 +500,14 @@ public:
/// return row "behind" last row of text
RowList::iterator endRow() const;
/// return next row crossing paragraph boundaries
RowList::iterator nextRow(RowList::iterator rit) const;
void nextRow(ParagraphList::iterator & pit,
RowList::iterator & rit) const;
/// return previous row crossing paragraph boundaries
RowList::iterator previousRow(RowList::iterator rit) const;
void previousRow(ParagraphList::iterator & pit,
RowList::iterator & rit) const;
///
bool noRows() const;
private:
/** Cursor related data.

View File

@ -17,6 +17,7 @@
#include "support/types.h"
#include "changes.h"
#include "RowList.h"
#include "LString.h"
@ -293,6 +294,9 @@ public:
///
InsetList insetlist;
///
mutable RowList rows;
private:
///
LyXLayout_ptr layout_;

View File

@ -235,7 +235,7 @@ ParagraphList::iterator depthHook(ParagraphList::iterator pit,
if (newpit != beg)
--newpit;
while (newpit != beg && newpit->getDepth() > depth) {
while (newpit != beg && newpit->getDepth() > depth) {
--newpit;
}
@ -657,7 +657,7 @@ TeXOnePar(Buffer const * buf,
}
}
if ((in == 0) || !in->forceDefaultParagraphs(in)) {
if (in == 0 || !in->forceDefaultParagraphs(in)) {
further_blank_line = false;
if (pit->params().lineBottom()) {
os << "\\lyxline{\\" << font.latexSize() << '}';

View File

@ -38,6 +38,7 @@
using namespace lyx::support;
using std::max;
using std::endl;
using lyx::pos_type;
extern int PAPER_MARGIN;
@ -255,7 +256,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 = lastPrintablePos(text_, pit_, row_);
pos_type const last = lastPrintablePos(*pit_, row_);
LyXFont orig_font = getFont(pos);
// first character
@ -432,7 +433,7 @@ void RowPainter::paintSelection()
int(x_), row_->height(), LColor::selection);
pos_type const body_pos = pit_->beginningOfBody();
pos_type const last = lastPrintablePos(text_, pit_, row_);
pos_type const last = lastPrintablePos(*pit_, row_);
double tmpx = x_;
for (pos_type vpos = row_->pos(); vpos <= last; ++vpos) {
@ -448,7 +449,7 @@ void RowPainter::paintSelection()
tmpx -= singleWidth(body_pos - 1);
}
if (hfillExpansion(text_, pit_, row_, pos)) {
if (hfillExpansion(*pit_, row_, pos)) {
tmpx += singleWidth(pos);
if (pos >= body_pos)
tmpx += hfill_;
@ -484,7 +485,7 @@ void RowPainter::paintSelection()
void RowPainter::paintChangeBar()
{
pos_type const start = row_->pos();
pos_type const end = lastPrintablePos(text_, pit_, row_);
pos_type const end = lastPrintablePos(*pit_, row_);
if (!pit_->isChanged(start, end))
return;
@ -525,7 +526,7 @@ void RowPainter::paintDepthBar()
Paragraph::depth_type prev_depth = 0;
if (row_ != text_.firstRow()) {
ParagraphList::iterator pit2 = pit_;
if (row_ == text_.beginRow(pit2))
if (row_ == pit2->rows.begin())
--pit2;
prev_depth = pit2->getDepth();
}
@ -533,7 +534,7 @@ void RowPainter::paintDepthBar()
Paragraph::depth_type next_depth = 0;
if (row_ != text_.lastRow()) {
ParagraphList::iterator pit2 = pit_;
if (boost::next(row_) == text_.endRow(pit2))
if (boost::next(row_) == pit2->rows.end())
++pit2;
next_depth = pit2->getDepth();
}
@ -894,7 +895,7 @@ void RowPainter::paintLast()
void RowPainter::paintText()
{
pos_type const last = lastPrintablePos(text_, pit_, row_);
pos_type const last = lastPrintablePos(*pit_, row_);
pos_type body_pos = pit_->beginningOfBody();
if (body_pos > 0 &&
(body_pos - 1 > last || !pit_->isLineSeparator(body_pos - 1))) {
@ -959,7 +960,7 @@ void RowPainter::paintText()
pain_.line(int(x_), y1, int(x_), y0, LColor::added_space);
if (hfillExpansion(text_, pit_, row_, pos)) {
if (hfillExpansion(*pit_, row_, pos)) {
int const y2 = (y0 + y1) / 2;
if (pos >= body_pos) {
@ -1032,7 +1033,7 @@ void RowPainter::paint()
if (row_->isParStart())
paintFirst();
if (isParEnd(text_, pit_, row_))
if (isParEnd(*pit_, row_))
paintLast();
// paint text
@ -1103,18 +1104,32 @@ int paintRows(BufferView const & bv, LyXText const & text,
const_cast<LyXText&>(text).metrics(mi, dim);
#endif
}
const_cast<LyXText&>(text).updateRowPositions();
//lyxerr << "text: " << &text << " y: " << y << " yf: " << yf
// << " y2: " << y2 << " yo: " << yo << "\n";
int yy = yf - y;
RowList::iterator end = text.endRow();
while (rit != end && yy + y < y2) {
//const_cast<LyXText &>(text).setHeightOfRow(rit);
ParagraphList::iterator pit = text.getPar(rit);
paintRow(bv, text, pit, rit, y + yo, xo, y + text.top_y());
y += rit->height();
rit = text.nextRow(rit);
ParagraphList::iterator pit = text.ownerParagraphs().begin();
ParagraphList::iterator end = text.ownerParagraphs().end();
bool active = false;
for ( ; pit != end; ++pit) {
RowList::iterator row = pit->rows.begin();
RowList::iterator rend = pit->rows.end();
for ( ; row != rend; ++row) {
if (row == rit)
active = true;
if (active) {
paintRow(bv, text, pit, row, y + yo, xo, y + text.top_y());
y += row->height();
if (yy + y >= y2)
return y;
} else {
//lyxerr << " paintRows: row: " << &*row << " ignored" << endl;
}
}
}
return y;
}

View File

@ -82,11 +82,15 @@ BufferView * LyXText::bv() const
void LyXText::updateRowPositions()
{
RowList::iterator rit = firstRow();
RowList::iterator rend = endRow();
for (int y = 0; rit != rend ; rit = nextRow(rit)) {
rit->y(y);
y += rit->height();
ParagraphList::iterator pit = ownerParagraphs().begin();
ParagraphList::iterator end = ownerParagraphs().end();
for (int y = 0; pit != end; ++pit) {
RowList::iterator rit = pit->rows.begin();
RowList::iterator rend = pit->rows.end();
for ( ; rit != rend ; rit = ++rit) {
rit->y(y);
y += rit->height();
}
}
}
@ -102,7 +106,7 @@ int LyXText::top_y() const
void LyXText::top_y(int newy)
{
if (rows().empty())
if (ownerParagraphs().begin()->rows.empty())
return;
if (isInInset()) {
@ -114,14 +118,8 @@ void LyXText::top_y(int newy)
lyxerr[Debug::GUI] << "setting top y = " << newy << endl;
int y = newy;
RowList::iterator rit = getRowNearY(y);
if (rit == anchor_row_ && anchor_row_offset_ == newy - y) {
lyxerr[Debug::GUI] << "top_y to same value, skipping update" << endl;
return;
}
anchor_row_ = rit;
ParagraphList::iterator dummypit;
anchor_row_ = getRowNearY(y, dummypit);
anchor_row_offset_ = newy - y;
lyxerr[Debug::GUI] << "changing reference to row: " << &*anchor_row_
<< " offset: " << anchor_row_offset_ << endl;
@ -317,7 +315,7 @@ bool LyXText::bidi_InRange(lyx::pos_type pos) const
}
void LyXText::computeBidiTables(ParagraphList::iterator row_par,
void LyXText::computeBidiTables(ParagraphList::iterator pit,
Buffer const * buf, RowList::iterator row) const
{
bidi_same_direction = true;
@ -326,7 +324,7 @@ void LyXText::computeBidiTables(ParagraphList::iterator row_par,
return;
}
InsetOld * inset = row_par->inInset();
InsetOld * inset = pit->inInset();
if (inset && inset->owner() &&
inset->owner()->lyxCode() == InsetOld::ERT_CODE) {
bidi_start = -1;
@ -334,7 +332,7 @@ void LyXText::computeBidiTables(ParagraphList::iterator row_par,
}
bidi_start = row->pos();
bidi_end = lastPrintablePos(*this, row_par, row);
bidi_end = lastPrintablePos(*pit, row);
if (bidi_start > bidi_end) {
bidi_start = -1;
@ -356,25 +354,25 @@ void LyXText::computeBidiTables(ParagraphList::iterator row_par,
pos_type stack[2];
bool const rtl_par =
row_par->isRightToLeftPar(buf->params);
pit->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 = pit->beginningOfBody();
for (pos_type lpos = bidi_start; lpos <= bidi_end; ++lpos) {
bool is_space = row_par->isLineSeparator(lpos);
bool is_space = pit->isLineSeparator(lpos);
pos_type const pos =
(is_space && lpos + 1 <= bidi_end &&
!row_par->isLineSeparator(lpos + 1) &&
!row_par->isNewline(lpos + 1))
!pit->isLineSeparator(lpos + 1) &&
!pit->isNewline(lpos + 1))
? lpos + 1 : lpos;
LyXFont font = row_par->getFontSettings(buf->params, pos);
LyXFont font = pit->getFontSettings(buf->params, pos);
if (pos != lpos && 0 < lpos && rtl0 && font.isRightToLeft() &&
font.number() == LyXFont::ON &&
row_par->getFontSettings(buf->params, lpos - 1).number()
pit->getFontSettings(buf->params, lpos - 1).number()
== LyXFont::ON) {
font = row_par->getFontSettings(buf->params, lpos);
font = pit->getFontSettings(buf->params, lpos);
is_space = false;
}
@ -480,7 +478,7 @@ bool LyXText::isBoundary(Buffer const * buf, Paragraph const & par,
int LyXText::leftMargin(ParagraphList::iterator pit, Row const & row) const
{
{
InsetOld * ins;
if (row.pos() < pit->size())
@ -605,8 +603,8 @@ int LyXText::leftMargin(ParagraphList::iterator pit, Row const & row) const
// are *NOT* allowed in the LaTeX realisation of this layout.
// find the first row of this paragraph
RowList::iterator rit = beginRow(pit);
RowList::iterator end = endRow(pit);
RowList::iterator rit = pit->rows.begin();
RowList::iterator end = pit->rows.end();
int minfill = rit->fill();
for ( ; rit != end; ++rit)
if (rit->fill() < minfill)
@ -877,7 +875,7 @@ int LyXText::fill(ParagraphList::iterator pit,
int w;
// get the pure distance
pos_type const last = lastPrintablePos(*this, pit, row);
pos_type const last = lastPrintablePos(*pit, row);
LyXLayout_ptr const & layout = pit->layout();
@ -1038,7 +1036,7 @@ void LyXText::setHeightOfRow(ParagraphList::iterator pit, RowList::iterator rit)
int maxdesc = int(font_metrics::maxDescent(font) *
layout->spacing.getValue() * spacing_val);
pos_type const pos_end = lastPos(*this, pit, rit);
pos_type const pos_end = lastPos(*pit, rit);
int labeladdon = 0;
int maxwidth = 0;
@ -1217,8 +1215,8 @@ void LyXText::setHeightOfRow(ParagraphList::iterator pit, RowList::iterator rit)
} else if (rit != firstRow()) {
tmptop = layout->topsep;
if (boost::prior(pit)->getDepth() >= pit->getDepth())
tmptop -= getPar(boost::prior(rit))->layout()->bottomsep;
//if (boost::prior(pit)->getDepth() >= pit->getDepth())
// tmptop -= getPar(previousRow(rit))->layout()->bottomsep;
if (tmptop > 0)
layoutasc = (tmptop * defaultRowHeight());
@ -1243,11 +1241,10 @@ void LyXText::setHeightOfRow(ParagraphList::iterator pit, RowList::iterator rit)
}
// is it a bottom line?
if (boost::next(rit) == endRow(pit)) {
if (boost::next(rit) == pit->rows.end()) {
// the bottom margin
ParagraphList::iterator nextpit = boost::next(pit);
if (nextpit == ownerParagraphs().end() &&
!isInInset())
if (nextpit == ownerParagraphs().end() && !isInInset())
maxdesc += PAPER_MARGIN;
// add the vertical spaces, that the user added
@ -1321,9 +1318,12 @@ void LyXText::setHeightOfRow(ParagraphList::iterator pit, RowList::iterator rit)
width = max(0, workWidth());
RowList::iterator rit = firstRow();
RowList::iterator end = endRow();
for (; rit != end; rit = nextRow(rit))
ParagraphList::iterator it = ownerParagraphs().begin();
while (rit != end) {
if (rit->width() > width)
width = rit->width();
nextRow(it, rit);
}
}
}
@ -1368,6 +1368,12 @@ void LyXText::breakParagraph(ParagraphList & paragraphs, char keep_layout)
::breakParagraph(bv()->buffer()->params, paragraphs, cursor.par(),
cursor.pos(), keep_layout);
#warning Trouble Point! (Lgb)
// When ::breakParagraph is called from within an inset we must
// ensure that the correct ParagraphList is used. Today that is not
// the case and the Buffer::paragraphs is used. Not good. (Lgb)
ParagraphList::iterator next_par = boost::next(cursor.par());
// well this is the caption hack since one caption is really enough
if (layout->labeltype == LABEL_SENSITIVE) {
if (!cursor.pos())
@ -1375,7 +1381,7 @@ void LyXText::breakParagraph(ParagraphList & paragraphs, char keep_layout)
cursor.par()->applyLayout(tclass.defaultLayout());
else
// set to standard-layout
boost::next(cursor.par())->applyLayout(tclass.defaultLayout());
next_par->applyLayout(tclass.defaultLayout());
}
// if the cursor is at the beginning of a row without prior newline,
@ -1388,19 +1394,12 @@ void LyXText::breakParagraph(ParagraphList & paragraphs, char keep_layout)
cursorLeft(bv());
}
removeParagraph(cursor.par(), cursorRow());
#warning Trouble Point! (Lgb)
// When ::breakParagraph is called from within an inset we must
// ensure that the correct ParagraphList is used. Today that is not
// the case and the Buffer::paragraphs is used. Not good. (Lgb)
ParagraphList::iterator next_par = boost::next(cursor.par());
while (!next_par->empty() && next_par->isNewline(0))
next_par->erase(0);
insertParagraph(next_par, boost::next(cursorRow()));
updateCounters();
redoParagraph(cursor.par());
redoParagraph(next_par);
// This check is necessary. Otherwise the new empty paragraph will
// be deleted automatically. And it is more friendly for the user!
@ -1408,8 +1407,6 @@ void LyXText::breakParagraph(ParagraphList & paragraphs, char keep_layout)
setCursor(next_par, 0);
else
setCursor(cursor.par(), 0);
redoParagraph(cursor.par());
}
@ -1568,7 +1565,7 @@ void LyXText::prepareToPrint(ParagraphList::iterator pit,
if (layout->margintype == MARGIN_MANUAL
&& layout->labeltype == LABEL_MANUAL) {
/// We might have real hfills in the label part
int nlh = numberOfLabelHfills(*this, pit, rit);
int nlh = numberOfLabelHfills(*pit, rit);
// A manual label par (e.g. List) has an auto-hfill
// between the label text and the body of the
@ -1584,7 +1581,7 @@ void LyXText::prepareToPrint(ParagraphList::iterator pit,
}
// are there any hfills in the row?
int const nh = numberOfHfills(*this, pit, rit);
int const nh = numberOfHfills(*pit, rit);
if (nh) {
if (w > 0)
@ -1621,10 +1618,10 @@ void LyXText::prepareToPrint(ParagraphList::iterator pit,
switch (align) {
case LYX_ALIGN_BLOCK:
{
int const ns = numberOfSeparators(*this, pit, rit);
int const ns = numberOfSeparators(*pit, rit);
RowList::iterator next_row = boost::next(rit);
if (ns
&& next_row != endRow(pit)
&& next_row != pit->rows.end()
&& !pit->isNewline(next_row->pos() - 1)
&& !(pit->isInset(next_row->pos())
&& pit->getInset(next_row->pos())
@ -1650,7 +1647,7 @@ void LyXText::prepareToPrint(ParagraphList::iterator pit,
computeBidiTables(pit, bv()->buffer(), rit);
if (is_rtl) {
pos_type body_pos = pit->beginningOfBody();
pos_type last = lastPos(*this, pit, rit);
pos_type last = lastPos(*pit, rit);
if (body_pos > 0 &&
(body_pos - 1 > last ||
@ -2074,8 +2071,6 @@ void LyXText::backspace()
}
ParagraphList::iterator tmppit = cursor.par();
RowList::iterator tmprow = cursorRow();
// We used to do cursorLeftIntern() here, but it is
// not a good idea since it triggers the auto-delete
// mechanism. So we do a cursorLeftIntern()-lite,
@ -2098,8 +2093,6 @@ void LyXText::backspace()
&& (cursor.par()->layout() == tmppit->layout()
|| tmppit->layout() == tclass.defaultLayout())
&& cursor.par()->getAlign() == tmppit->getAlign()) {
removeParagraph(cursor.par(), tmprow);
removeRow(tmprow);
mergeParagraph(bv()->buffer()->params,
bv()->buffer()->paragraphs, cursor.par());
@ -2147,8 +2140,8 @@ RowList::iterator LyXText::getRow(LyXCursor const & cur) const
RowList::iterator
LyXText::getRow(ParagraphList::iterator pit, pos_type pos) const
{
RowList::iterator rit = beginRow(pit);
RowList::iterator end = endRow(pit);
RowList::iterator rit = pit->rows.begin();
RowList::iterator end = pit->rows.end();
#warning Why is this next thing needed? (Andre)
while (rit != end
@ -2167,18 +2160,19 @@ LyXText::getRow(ParagraphList::iterator pit, pos_type pos, int & y) const
{
y = 0;
if (rows().empty())
if (noRows())
return firstRow();
RowList::iterator beg = beginRow(pit);
RowList::iterator end = endRow(pit);
RowList::iterator rit;
ParagraphList::iterator it = ownerParagraphs().begin();
for ( ; it != pit; ++it) {
RowList::iterator beg = it->rows.begin();
RowList::iterator end = it->rows.end();
for (RowList::iterator rit = beg; rit != end; ++rit)
y += rit->height();
}
// find the first row of the specified paragraph
for (rit = firstRow(); rit != beg; rit = nextRow(rit))
y += rit->height();
// now find the wanted row
RowList::iterator rit = pit->rows.begin();
RowList::iterator end = pit->rows.end();
while (rit != end
&& rit->pos() < pos
&& boost::next(rit) != end
@ -2199,45 +2193,37 @@ RowList::iterator LyXText::cursorIRow() const
}
RowList::iterator LyXText::getRowNearY(int & y) const
RowList::iterator LyXText::getRowNearY(int & y,
ParagraphList::iterator & pit) const
{
RowList::iterator rit = anchor_row_;
RowList::iterator const beg = firstRow();
RowList::iterator const end = endRow();
ParagraphList::iterator const end = ownerParagraphs().end();
//lyxerr << "getRowNearY: y " << y << endl;
if (rows().empty()) {
y = 0;
return end;
}
if (rit == end)
rit = beg;
for (pit = ownerParagraphs().begin(); pit != end; ++pit) {
RowList::iterator rit = pit->rows.begin();
RowList::iterator rend = pit->rows.end();
int tmpy = rit->y();
if (tmpy <= y) {
while (rit != end && tmpy <= y) {
tmpy += rit->height();
rit = nextRow(rit);
}
if (rit != beg) {
rit = previousRow(rit);
tmpy -= rit->height();
}
} else {
while (rit != beg && tmpy > y) {
rit = previousRow(rit);
tmpy -= rit->height();
for ( ; rit != rend; ++rit) {
//rit->dump();
if (rit->y() >= y) {
if (rit != firstRow())
previousRow(pit, rit);
y = rit->y();
return rit;
}
}
}
if (tmpy < 0 || rit == end) {
tmpy = 0;
rit = beg;
}
// return the rel y
y = tmpy;
return rit;
#if 1
pit = ownerParagraphs().begin();
y = 0;
lyxerr << "row not found near " << y << " pit: " << &*pit << endl;
return firstRow();
#else
pit = boost::prior(ownerParagraphs().end());
lyxerr << "row not found near " << y << " pit: " << &*pit << endl;
return lastRow();
#endif
}
@ -2247,88 +2233,53 @@ int LyXText::getDepth() const
}
#warning Expensive. Remove before 1.4!
// computes a ParagraphList::iterator from RowList::iterator by
// counting zeros in the sequence of pos values.
ParagraphList::iterator LyXText::getPar(RowList::iterator row) const
{
if (row == endRow()) {
lyxerr << "getPar() pit at end " << endl;
Assert(false);
}
if (row == firstRow()) {
return ownerParagraphs().begin();
}
ParagraphList::iterator pit = ownerParagraphs().begin();
RowList::iterator rit = firstRow();
RowList::iterator rend = endRow();
for (++rit ; rit != rend; rit = nextRow(rit)) {
if (rit->pos() == 0) {
++pit;
if (pit == ownerParagraphs().end()) {
lyxerr << "unexpected in LyXText::getPar()" << endl;
Assert(false);
}
}
if (rit == row) {
return pit;
}
}
lyxerr << "LyXText::getPar: row not found " << endl;
Assert(false);
return ownerParagraphs().end(); // shut up compiler
}
RowList::iterator LyXText::beginRow(ParagraphList::iterator pit) const
{
int n = std::distance(ownerParagraphs().begin(), pit);
RowList::iterator rit = rows().begin();
RowList::iterator end = rows().end();
for ( ; rit != end; ++rit)
if (rit->pos() == 0 && n-- == 0)
return rit;
return rit;
}
RowList::iterator LyXText::endRow(ParagraphList::iterator pit) const
{
return beginRow(boost::next(pit));
}
RowList::iterator LyXText::firstRow() const
{
return rowlist_.begin();
return ownerParagraphs().front().rows.begin();
}
RowList::iterator LyXText::lastRow() const
{
return boost::prior(rowlist_.end());
return boost::prior(endRow());
}
RowList::iterator LyXText::endRow() const
{
return rowlist_.end();
return ownerParagraphs().back().rows.end();
}
RowList::iterator LyXText::nextRow(RowList::iterator rit) const
void LyXText::nextRow(ParagraphList::iterator & pit,
RowList::iterator & rit) const
{
return boost::next(rit);
if (boost::next(rit) != pit->rows.end()) {
rit = boost::next(rit);
} else {
++pit;
if (pit == ownerParagraphs().end())
rit = boost::next(rit);
else
rit = pit->rows.begin();
}
}
RowList::iterator LyXText::previousRow(RowList::iterator rit) const
void LyXText::previousRow(ParagraphList::iterator & pit,
RowList::iterator & rit) const
{
return boost::prior(rit);
if (rit != pit->rows.begin())
rit = boost::prior(rit);
else {
Assert(pit != ownerParagraphs().begin());
--pit;
rit = boost::prior(pit->rows.end());
}
}
bool LyXText::noRows() const
{
return ownerParagraphs().begin()->rows.empty();
}

View File

@ -79,17 +79,21 @@ void LyXText::init(BufferView * bview)
{
bv_owner = bview;
rowlist_.clear();
ParagraphList::iterator const beg = ownerParagraphs().begin();
ParagraphList::iterator const end = ownerParagraphs().end();
for (ParagraphList::iterator pit = beg; pit != end; ++pit)
pit->rows.clear();
width = 0;
height = 0;
anchor_row_ = endRow();
anchor_row_offset_ = 0;
current_font = getFont(ownerParagraphs().begin(), 0);
current_font = getFont(beg, 0);
redoParagraphs(ownerParagraphs().begin(), ownerParagraphs().end());
setCursorIntern(ownerParagraphs().begin(), 0);
redoParagraphs(beg, end);
setCursorIntern(beg, 0);
selection.cursor = cursor;
updateCounters();
@ -240,72 +244,6 @@ void LyXText::setCharFont(
}
// removes the row and reset the touched counters
void LyXText::removeRow(RowList::iterator rit)
{
if (anchor_row_ == rit) {
if (rit == firstRow()) {
anchor_row_ = boost::next(rit);
anchor_row_offset_ -= rit->height();
} else {
anchor_row_ = boost::prior(rit);
anchor_row_offset_ += anchor_row_->height();
}
}
// the text becomes smaller
height -= rit->height();
rowlist_.erase(rit);
}
// remove all following rows of the paragraph of the specified row.
void LyXText::removeParagraph(ParagraphList::iterator pit,
RowList::iterator rit)
{
RowList::iterator end = endRow(pit);
for (++rit; rit != end; ) {
RowList::iterator rit2 = boost::next(rit);
removeRow(rit);
rit = rit2;
}
}
void LyXText::insertParagraph(ParagraphList::iterator pit,
RowList::iterator rit)
{
// insert a new row, starting at position 0
rit = rowlist_.insert(rit, Row(0));
// and now append the whole paragraph before the new row
pos_type const last = pit->size();
bool done = false;
do {
pos_type z = rowBreakPoint(pit, *rit);
RowList::iterator tmprow = rit;
if (z < last) {
++z;
rit = rowlist_.insert(boost::next(rit), Row(z));
} else {
done = true;
}
// Set the dimensions of the row
// fixed fill setting now by calling inset->update() in
// singleWidth when needed!
tmprow->fill(fill(pit, tmprow, workWidth()));
setHeightOfRow(pit, tmprow);
} while (!done);
}
InsetOld * LyXText::getInset() const
{
ParagraphList::iterator pit = cursor.par();
@ -617,18 +555,40 @@ void LyXText::redoParagraphs(ParagraphList::iterator start,
void LyXText::redoParagraph(ParagraphList::iterator pit)
{
RowList::iterator first = beginRow(pit);
RowList::iterator last = endRow(pit);
RowList::iterator rit = pit->rows.begin();
RowList::iterator end = pit->rows.end();
// remove paragraph from rowlist
while (first != last) {
RowList::iterator rit2 = first;
++first;
removeRow(rit2);
// remove rows of paragraph
for ( ; rit != end; ++rit) {
if (rit == anchor_row_)
anchor_row_ = endRow();
height -= rit->height();
}
pit->rows.clear();
// rebreak the paragraph
// insert a new row, starting at position 0
pos_type z = 0;
pit->rows.push_back(Row(z));
bool done = false;
while (!done) {
z = rowBreakPoint(pit, pit->rows.back());
RowList::iterator tmprow = boost::prior(pit->rows.end());
if (z >= pit->size())
done = true;
else {
++z;
pit->rows.push_back(Row(z));
}
tmprow->fill(fill(pit, tmprow, workWidth()));
setHeightOfRow(pit, tmprow);
}
// reinsert the paragraph
insertParagraph(pit, last);
//lyxerr << "redoParagraph: " << pit->rows.size() << " rows\n";
}
@ -646,7 +606,6 @@ void LyXText::metrics(MetricsInfo & mi, Dimension & dim)
//Assert(mi.base.textwidth);
// rebuild row cache
rowlist_.clear();
width = 0;
height = 0;
@ -657,6 +616,8 @@ void LyXText::metrics(MetricsInfo & mi, Dimension & dim)
ParagraphList::iterator end = ownerParagraphs().end();
for (; pit != end; ++pit) {
pit->rows.clear();
InsetList::iterator ii = pit->insetlist.begin();
InsetList::iterator iend = pit->insetlist.end();
for (; ii != iend; ++ii) {
@ -717,7 +678,7 @@ void LyXText::cursorEnd()
RowList::iterator next_rit = boost::next(rit);
RowList::iterator end = boost::next(rit);
ParagraphList::iterator pit = cursor.par();
pos_type last_pos = lastPos(*this, pit, rit);
pos_type last_pos = lastPos(*pit, rit);
if (next_rit == end) {
++last_pos;
@ -1391,7 +1352,7 @@ void LyXText::setCursor(LyXCursor & cur, ParagraphList::iterator pit,
cur.par(pit);
cur.pos(pos);
cur.boundary(boundary);
if (rows().empty())
if (noRows())
return;
// get the cursor y position in text
@ -1402,7 +1363,7 @@ void LyXText::setCursor(LyXCursor & cur, ParagraphList::iterator pit,
// same paragraph and there is a previous row then put the cursor on
// the end of the previous row
cur.iy(y + row->baseline());
if (row != beginRow(pit)
if (row != pit->rows.begin()
&& pos
&& pos < pit->size()
&& pit->getChar(pos) == Paragraph::META_INSET) {
@ -1418,7 +1379,7 @@ void LyXText::setCursor(LyXCursor & cur, ParagraphList::iterator pit,
// y is now the cursor baseline
cur.y(y);
pos_type last = lastPrintablePos(*this, pit, old_row);
pos_type last = lastPrintablePos(*pit, old_row);
// None of these should happen, but we're scaredy-cats
if (pos > pit->size()) {
@ -1502,7 +1463,7 @@ float LyXText::getCursorX(ParagraphList::iterator pit, RowList::iterator rit,
x -= singleWidth(pit, body_pos - 1);
}
if (hfillExpansion(*this, pit, rit, pos)) {
if (hfillExpansion(*pit, rit, pos)) {
x += singleWidth(pit, pos);
if (pos >= body_pos)
x += fill_hfill;
@ -1579,7 +1540,7 @@ pos_type LyXText::getColumnNearX(ParagraphList::iterator pit,
prepareToPrint(pit, rit, tmpx, fill_separator, fill_hfill, fill_label_hfill);
pos_type vc = rit->pos();
pos_type last = lastPrintablePos(*this, pit, rit);
pos_type last = lastPrintablePos(*pit, rit);
pos_type c = 0;
LyXLayout_ptr const & layout = pit->layout();
@ -1609,7 +1570,7 @@ pos_type LyXText::getColumnNearX(ParagraphList::iterator pit,
tmpx -= singleWidth(pit, body_pos - 1);
}
if (hfillExpansion(*this, pit, rit, c)) {
if (hfillExpansion(*pit, rit, c)) {
tmpx += singleWidth(pit, c);
if (c >= body_pos)
tmpx += fill_hfill;
@ -1637,7 +1598,7 @@ pos_type LyXText::getColumnNearX(ParagraphList::iterator pit,
// This (rtl_support test) is not needed, but gives
// some speedup if rtl_support == false
bool const lastrow = lyxrc.rtl_support
&& boost::next(rit) == endRow(pit);
&& boost::next(rit) == pit->rows.end();
// If lastrow is false, we don't need to compute
// the value of rtl.
@ -1695,16 +1656,12 @@ namespace {
bool beforeFullRowInset(LyXText & lt, LyXCursor const & cur)
{
RowList::iterator row = lt.getRow(cur);
if (boost::next(row) == lt.endRow())
return false;
RowList::iterator next = boost::next(row);
if (next == lt.endRow(cur.par()) || next->pos() != cur.pos())
if (next == cur.par()->rows.end() || next->pos() != cur.pos())
return false;
if (cur.pos() == cur.par()->size()
|| !cur.par()->isInset(cur.pos()))
if (cur.pos() == cur.par()->size() || !cur.par()->isInset(cur.pos()))
return false;
InsetOld const * inset = cur.par()->getInset(cur.pos());
@ -1719,9 +1676,8 @@ namespace {
void LyXText::setCursorFromCoordinates(LyXCursor & cur, int x, int y)
{
// Get the row first.
RowList::iterator row = getRowNearY(y);
ParagraphList::iterator pit = getPar(row);
ParagraphList::iterator pit;
RowList::iterator row = getRowNearY(y, pit);
bool bound = false;
pos_type const column = getColumnNearX(pit, row, x, bound);
cur.par(pit);
@ -1729,15 +1685,15 @@ void LyXText::setCursorFromCoordinates(LyXCursor & cur, int x, int y)
cur.x(x);
cur.y(y + row->baseline());
if (beforeFullRowInset(*this, cur)) {
pos_type const last = lastPrintablePos(*this, pit, row);
RowList::iterator next_row = boost::next(row);
cur.ix(int(getCursorX(pit, next_row, cur.pos(), last, bound)));
cur.iy(y + row->height() + next_row->baseline());
} else {
// if (beforeFullRowInset(*this, cur)) {
// pos_type const last = lastPrintablePos(*this, pit, row);
// RowList::iterator next_row = nextRow(row);
// cur.ix(int(getCursorX(pit, next_row, cur.pos(), last, bound)));
// cur.iy(y + row->height() + next_row->baseline());
// } else {
cur.iy(cur.y());
cur.ix(cur.x());
}
// }
cur.boundary(bound);
}
@ -1794,8 +1750,10 @@ void LyXText::cursorUp(bool selecting)
}
}
#else
lyxerr << "cursorUp: y " << cursor.y() << " bl: " <<
cursorRow()->baseline() << endl;
setCursorFromCoordinates(cursor.x_fix(),
cursor.y() - cursorRow()->baseline() - 1);
cursor.y() - cursorRow()->baseline() - 1);
#endif
}
@ -1959,45 +1917,19 @@ bool LyXText::deleteEmptyParagraphMechanism(LyXCursor const & old_cursor)
selection.cursor.par() == old_cursor.par()
&& selection.cursor.pos() == old_cursor.pos());
if (getRow(old_cursor) != firstRow()) {
RowList::iterator prevrow = boost::prior(getRow(old_cursor));
tmpcursor = cursor;
cursor = old_cursor; // that undo can restore the right cursor position
#warning FIXME. --end() iterator is usable here
ParagraphList::iterator endpit = boost::next(old_cursor.par());
while (endpit != ownerParagraphs().end() &&
endpit->getDepth()) {
++endpit;
}
tmpcursor = cursor;
cursor = old_cursor; // that undo can restore the right cursor position
recordUndo(bv(), Undo::DELETE, old_cursor.par(),
boost::prior(endpit));
cursor = tmpcursor;
ParagraphList::iterator endpit = boost::next(old_cursor.par());
while (endpit != ownerParagraphs().end() && endpit->getDepth())
++endpit;
recordUndo(bv(), Undo::DELETE, old_cursor.par(), boost::prior(endpit));
cursor = tmpcursor;
// delete old row
removeRow(getRow(old_cursor));
// delete old par
ownerParagraphs().erase(old_cursor.par());
} else {
RowList::iterator nextrow = boost::next(getRow(old_cursor));
tmpcursor = cursor;
cursor = old_cursor; // that undo can restore the right cursor position
#warning FIXME. --end() iterator is usable here
ParagraphList::iterator endpit = boost::next(old_cursor.par());
while (endpit != ownerParagraphs().end() &&
endpit->getDepth()) {
++endpit;
}
recordUndo(bv(), Undo::DELETE, old_cursor.par(), boost::prior(endpit));
cursor = tmpcursor;
// delete old row
removeRow(getRow(old_cursor));
// delete old par
ownerParagraphs().erase(old_cursor.par());
}
// delete old par
ownerParagraphs().erase(old_cursor.par());
redoParagraph();
// correct cursor y
setCursorIntern(cursor.par(), cursor.pos());

View File

@ -275,9 +275,7 @@ void LyXText::cursorPrevious()
LyXCursor cur;
ParagraphList::iterator pit = cursor.par();
if (rit == beginRow(pit))
--pit;
rit = previousRow(rit);
previousRow(pit, rit);
setCursor(cur, pit, rit->pos(), false);
if (cur.y() > top_y())
cursorUp(true);
@ -304,7 +302,8 @@ void LyXText::cursorNext()
+ bv()->theLockingInset()->insetInInsetY());
}
getRowNearY(y);
ParagraphList::iterator dummypit;
getRowNearY(y, dummypit);
setCursorFromCoordinates(cursor.x_fix(), y);
// + bv->workHeight());
@ -332,9 +331,7 @@ void LyXText::cursorNext()
}
ParagraphList::iterator pit = cursor.par();
if (boost::next(rit) == endRow(pit))
++pit;
rit = nextRow(rit);
nextRow(pit, rit);
LyXCursor cur;
setCursor(cur, pit, rit->pos(), false);
if (cur.y() < top_y() + bv()->workHeight())

View File

@ -68,8 +68,8 @@ void cursorLeftOneWord(LyXCursor & cursor, ParagraphList const & pars)
while (pos &&
(pit->isSeparator(pos - 1) ||
pit->isKomma(pos - 1) ||
pit->isNewline(pos - 1)) &&
pit->isKomma(pos - 1) ||
pit->isNewline(pos - 1)) &&
!(pit->isHfill(pos - 1) ||
pit->isInset(pos - 1)))
--pos;