/* This file is part of * ====================================================== * * LyX, The Document Processor * * Copyright (C) 1995 Matthias Ettrich * Copyright (C) 1995-1998 The LyX Team. *
*======================================================*/
} elseif (IsSeparatorChar(c))
c = ' '; elseif (IsNewlineChar(c))
c = 'n'; return font.width(c);
}
/* returns the paragraph position of the last character in the
* specified row */ int LyXText::RowLast(Row *row)
{ if (row->next == NULL) return row->par->Last()-1; elseif (row->next->par != row->par) return row->par->Last()-1; else return row->next->pos - 1;
}
void LyXText::Draw(Row *row, int &pos, LyXScreen &scr, int offset, float &x)
{ char c = row->par->GetChar(pos);
if (IsNewlineChar(c)) {
pos++; // Draw end-of-line marker
// Collect character that we can draw in one command
// This is dirty, but fast. Notice that it will never be too small. // For the record, I'll note that Microsoft Word has a limit // of 768 here. We have none :-) (Asger) staticchar textstring[1024];
int last = RowLast(row); // Prevent crash in the extremely unlikely event // that our array is too small if (last > pos+1020) last = pos + 1020;
// If monochrome and LaTeX mode, provide reverse background if (mono_video && font.latex() == LyXFont::ON) { int a=font.maxAscent(), d=font.maxDescent();
scr.fillRectangle(gc_copy, int(tmpx), offset + row->baseline-a,
font.textWidth(textstring, i), a+d);
}
/* Draw text and set the new x position */
x += scr.drawText(font, textstring, i, offset + row->baseline, int(x)); /* what about underbars? */ if (font.underbar() == LyXFont::ON && font.latex() != LyXFont::ON) {
scr.drawLine(gc_copy, offset + row->baseline + 2, int(tmpx), int(x - tmpx));
}
// If we want ulem.sty support, drawing // routines should go here. (Asger) // Why shouldn't LyXFont::drawText handle it internally?
}
/* Returns the left beginning of the text. * This information cannot be taken from the layouts-objekt, because in * LaTeX the beginning of the text fits in some cases (for example sections)
* exactly the label-width. */ int LyXText::LeftMargin(Row* row)
{ int x;
LyXLayout *layout;
LyXFont labelfont;
LyXParagraph *newpar;
Row dummyrow;
layout = lyxstyle.Style(parameters->textclass, row->par->GetLayout());
x += lyxstyle.TextClass(parameters->textclass)->
defaultfont.signedStringWidth(lyxstyle.TextClass(parameters->textclass)->leftmargin);
if (row->par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE) {
LyXFont font(LyXFont::ALL_SANE);
font.setSize(LyXFont::SIZE_SMALL);
x += font.textWidth("Mwide-figM", 10) + LYX_PAPER_MARGIN/2;
}
/* 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 (!row->par->GetDepth()) { if (!row->par->GetLayout()) { /* find the previous same level paragraph */ if (row->par->FirstPhysicalPar()->Previous()) {
newpar = row->par->DepthHook(row->par->GetDepth()); if (newpar && lyxstyle.Style(parameters->textclass, newpar->GetLayout())->nextnoindent)
parindent.clean();
}
}
} else { /* find the next level paragraph */
/* make a corresponding row. Needed to call LeftMargin() */
/* check wether it is a sufficent paragraph */ if (newpar && newpar->footnoteflag == row->par->footnoteflag
&& lyxstyle.Style(parameters->textclass,
newpar->GetLayout())->isEnvironment()) {
dummyrow.par = newpar;
dummyrow.pos = newpar->Last();
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 */
if (newpar && !row->par->GetLayout()) { if (newpar->FirstPhysicalPar()->noindent)
parindent.clean(); else
parindent = lyxstyle.Style(parameters->textclass,
newpar->GetLayout())->parindent;
}
}
labelfont = GetFont(row->par, -2); switch (layout->margintype) { case MARGIN_DYNAMIC: if (!layout->leftmargin.empty()) {
x += lyxstyle.TextClass(parameters->textclass)->defaultfont.signedStringWidth(layout->leftmargin);
} if (!row->par->GetLabelString().empty()) {
x += labelfont.signedStringWidth(layout->labelindent);
x += labelfont.stringWidth(row->par->GetLabelString());
x += labelfont.stringWidth(layout->labelsep);
} break; case MARGIN_MANUAL:
x += labelfont.signedStringWidth(layout->labelindent); if (row->pos >= BeginningOfMainBody(row->par)) { if (!row->par->GetLabelWidthString().empty()) {
x += labelfont.stringWidth(row->par->GetLabelWidthString());
x += labelfont.stringWidth(layout->labelsep);
}
} break; case MARGIN_STATIC:
x += ( lyxstyle.TextClass(parameters->textclass)->defaultfont.signedStringWidth(layout->leftmargin) * 4
/ (row->par->GetDepth() + 4)); break; case MARGIN_FIRST_DYNAMIC: if (layout->labeltype == LABEL_MANUAL) { if (row->pos >= BeginningOfMainBody(row->par)) {
x += labelfont.signedStringWidth(layout->leftmargin);
} else {
x += labelfont.signedStringWidth(layout->labelindent);
}
} else { if (row->pos // Special case to fix problems with theorems (JMarc)
|| (layout->labeltype == LABEL_STATIC
&& layout->latextype == LATEX_ENVIRONMENT
&& ! row->par->IsFirstInSequence())) {
x += labelfont.signedStringWidth(layout->leftmargin);
} elseif (layout->labeltype != LABEL_TOP_ENVIRONMENT
&& layout->labeltype != LABEL_BIBLIO
&& layout->labeltype != LABEL_CENTERED_TOP_ENVIRONMENT) {
x += labelfont.signedStringWidth(layout->labelindent);
x += labelfont.stringWidth(layout->labelsep);
x += labelfont.stringWidth(row->par->GetLabelString());
}
} break;
case MARGIN_RIGHT_ADDRESS_BOX:
{ /* ok, a terrible hack. The left margin depends on the widest row * in this paragraph. Do not care about footnotes, they are *NOT*
* allowed in the LaTeX realisation of this layout. */
/* find the first row of this paragraph */
Row *tmprow = row; while (tmprow->previous && tmprow->previous->par == row->par)
tmprow = tmprow->previous;
int minfill = tmprow->fill; while (tmprow-> next && tmprow->next->par == row->par) {
tmprow = tmprow->next; if (tmprow->fill < minfill)
minfill = tmprow->fill;
}
x += lyxstyle.TextClass(parameters->textclass)->defaultfont.signedStringWidth(layout->leftmargin);
x += minfill;
} break;
} if (row->par->pextra_type == PEXTRA_INDENT) { if (!row->par->pextra_widthp.empty()) {
x += paperwidth * atoi(row->par->pextra_widthp.c_str()) / 100;
} elseif (!row->par->pextra_width.empty()) { int xx = VSpace(row->par->pextra_width).inPixels();
if (xx > paperwidth)
xx = paperwidth * 80 / 100;
x += xx;
} else { // should not happen
LyXFont font(LyXFont::ALL_SANE);
x += font.stringWidth("XXXXXX");
}
}
int align; if (row->par->FirstPhysicalPar()->align == LYX_ALIGN_LAYOUT)
align = layout->align; else
align = row->par->FirstPhysicalPar()->align;
/* set the correct parindent */ 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
&& ! row->par->IsFirstInSequence()))
&& row->par == row->par->FirstPhysicalPar()
&& align == LYX_ALIGN_BLOCK
&& !row->par->noindent
&& (row->par->layout ||
parameters->paragraph_separation == LYX_PARSEP_INDENT))
x += lyxstyle.TextClass(parameters->textclass)->defaultfont.stringWidth(parindent); else if (layout->labeltype==LABEL_BIBLIO) { // ale970405 Right width for bibitems
x += bibitemMaxWidth(lyxstyle.TextClass(parameters->textclass)->defaultfont);
}
}
return x;
}
int LyXText::RightMargin(Row *row)
{ int x;
LyXLayout* layout;
x += lyxstyle.TextClass(parameters->textclass)->
defaultfont.signedStringWidth(lyxstyle.TextClass(parameters->textclass)->rightmargin); if (row->par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE) {
x += LYX_PAPER_MARGIN/2;
}
/* 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 (row->par->GetDepth()) { /* find the next level paragraph */
newpar = row->par;
do {
newpar = newpar->FirstPhysicalPar()->Previous(); if (newpar)
newpar = newpar->FirstPhysicalPar();
} while (newpar && newpar->GetDepth() >= row->par->GetDepth()
&& newpar->footnoteflag == row->par->footnoteflag);
/* make a corresponding row. Needed to call LeftMargin() */
/* check wether it is a sufficent paragraph */ if (newpar && newpar->footnoteflag == row->par->footnoteflag
&& lyxstyle.Style(parameters->textclass,
newpar->GetLayout())->isEnvironment()) {
dummyrow.par = newpar;
dummyrow.pos = 0;
x = RightMargin(&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 */
int LyXText::LabelEnd (Row *row)
{ if (lyxstyle.Style(parameters->textclass, row->par->GetLayout())->margintype == MARGIN_MANUAL) {
Row tmprow;
tmprow = *row;
tmprow.pos = row->par->Last(); return LeftMargin(&tmprow); /* just the beginning
* of the main body */
} else return 0; /* LabelEnd is only needed, if the * layout fills a flushleft
* label. */
}
/* table stuff -- begin*/ int LyXText::NumberOfCell(LyXParagraph *par, int pos)
{ int cell = 0; int tmp_pos = 0; while (tmp_pos < pos) { if (par->IsNewline(tmp_pos))
cell++;
tmp_pos++;
} return cell;
}
int LyXText::WidthOfCell(LyXParagraph *par, int &pos)
{ int w = 0; while (pos < par->Last() && !par->IsNewline(pos)) {
w += SingleWidth(par, pos);
pos++;
} if (par->IsNewline(pos))
pos++; return w;
}
/* get the next breakpoint in a given paragraph */ int LyXText::NextBreakPoint(Row* row, int width)
{ int x = 0; int last_separator = -1; /* position of the last possible breakpoint
* -1 isn't a suitable value, but a flag */ int i = 0; int left_margin;
left_margin = LabelEnd(row);
width -= RightMargin(row); int main_body = BeginningOfMainBody(par);
LyXLayout* layout = lyxstyle.Style(parameters->textclass, par->GetLayout());
i = pos; char c;
if (layout->margintype == MARGIN_RIGHT_ADDRESS_BOX) { /* special code for right address boxes, only newlines count */ while (i < par->Last()) { if (par->IsNewline(i)) {
last_separator = i;
i = par->Last() - 1;/* this means break */
x = width;
} elseif (par->GetChar(i) == LYX_META_INSET &&
par->GetInset(i) && par->GetInset(i)->Display()){
par->GetInset(i)->SetDisplay(false);
}
i++;
}
} else { // Last position is an invariant intconst last = par->Last(); /* this is the usual handling */
x = LeftMargin(row); while (x < width && i < last) {
c = par->GetChar(i); if (IsNewlineChar(c)) {
last_separator = i;
x = width; /* this means break */
} elseif (c == LYX_META_INSET &&
par->GetInset(i) && par->GetInset(i)->Display()){ /* check wether a Display() inset is valid here .
if not, change it to non-display*/ if (layout->isCommand()
|| (layout->labeltype == LABEL_MANUAL
&& i < BeginningOfMainBody(par))){ /* display istn't allowd */
par->GetInset(i)->SetDisplay(false);
x += SingleWidth(par, i, c);
} else { /* inset is display. So break the line here */ if (i==pos){ if (pos < last-1) {
last_separator = i; if (IsLineSeparatorChar(par->GetChar(i+1)))
last_separator++;
} else
last_separator = last; // to avoid extra rows
} else
last_separator = i - 1;
x = width; /* this means break */
}
} else { if (IsLineSeparatorChar(c))
last_separator = i;
x += SingleWidth(par, i, c);
}
i++; if (i == main_body) {
x += GetFont(par, -2).stringWidth(layout->labelsep); if (par->IsLineSeparator(i - 1))
x-= SingleWidth(par, i - 1); if (x < left_margin)
x = left_margin;
}
} /* end of paragraph is always a suitable separator */ if (i == last && x < width)
last_separator = i;
}
/* well, if last_separator is still 0, the line isn't breakable.
* don't care and cut simply at the end */ if (last_separator < 0) {
last_separator = i;
}
/* manual labels cannot be broken in LaTeX, do not care */ if (main_body && last_separator < main_body)
last_separator = main_body - 1;
return last_separator;
}
/* returns the minimum space a row needs on the screen in pixel */ int LyXText::Fill(Row *row, int paperwidth)
{ int w,i, last, fill, left_margin; /* get the pure distance */
last = RowLast(row);
/* table stuff -- begin*/ if (row->par->table) { /* for tables FILL does calculate the widthes of each cell in
* the row */ int pos = row->pos; int cell = NumberOfCell(row->par, pos);
w = 0; do {
row->par->table->SetWidthOfCell(cell, WidthOfCell(row->par, pos));
cell++;
} while (pos <= last && !row->par->table->IsFirstCell(cell)); /* don't forget the very last table cell without characters */ if (cell == row->par->table->GetNumberOfCells()-1)
row->par->table->SetWidthOfCell(cell, WidthOfCell(row->par, pos));
return 0; /* width of table cannot be returned since * we cannot guarantee its correct value at
* this point. */
} /* table stuff -- end*/
left_margin = LabelEnd(row);
/* if the row ends with newline, this newline will not be relevant */ if (last >= 0 && row->par->IsNewline(last))
last--;
/* if the row ends with a space, this space will not be relevant */ if (last >= 0 && row->par->IsLineSeparator(last))
last--;
/* special handling of the right address boxes */ if (lyxstyle.Style(parameters->textclass, row->par->GetLayout())->margintype == MARGIN_RIGHT_ADDRESS_BOX) { int tmpfill = row->fill;
row->fill = 0; /* the minfill in MarginLeft() */
w = LeftMargin(row);
row->fill = tmpfill;
/* the old way, impossible when using environments: */ /* w = LyXStringWidth(lyxstyle.Style(parameters->textclass, row->par->GetLayout())->font, */ /* lyxstyle.Style(parameters->textclass, row->par->GetLayout())->leftmargin); */
} else
w = LeftMargin(row);
int main_body = BeginningOfMainBody(row->par);
LyXLayout *layout = lyxstyle.Style(parameters->textclass,
row->par->GetLayout());
i = row->pos; while (i<= last) {
w += SingleWidth(row->par, i);
i++; if (i == main_body) {
w += GetFont(row->par, -2).stringWidth(layout->labelsep); if (row->par->IsLineSeparator(i - 1))
w-= SingleWidth(row->par, i - 1); if (w < left_margin)
w = left_margin;
}
}
fill = paperwidth - w - RightMargin(row); return fill;
}
/* returns the minimum space a manual label needs on the screen in pixel */ int LyXText::LabelFill(Row *row)
{ int w,i, last; int fill=0;
last = BeginningOfMainBody(row->par) - 1; /* -1 because a label ends either with a space that is in the label,
* or with the beginning of a footnote that is outside the label. */
// I don't understand this code in depth, but sometimes "last" is less than // 0 and this causes a crash. This fix seems to work correctly, but I // bet the real error is elsewhere. The bug is triggered when you have an // open footnote in a paragraph environment with a manual label. (Asger) if (last<0) last = 0;
if (row->par->IsLineSeparator(last)) /* a sepearator at this end
* does not count */
last--;
w = 0;
i = row->pos; while (i<= last) {
w += SingleWidth(row->par, i);
i++;
}
if (!row->par->labelwidthstring.empty()) {
fill = GetFont(row->par, -2).stringWidth(row->par->labelwidthstring) - w;
}
if (fill < 0)
fill = 0;
return fill;
}
/* returns the number of separators in the specified row. The separator
* on the very last column doesnt count */ int LyXText::NumberOfSeparators(Row *row)
{ int n,p,last;
last = RowLast(row);
n = 0;
p = row->pos; int main_body = BeginningOfMainBody(row->par); if (p < main_body)
p = main_body; for (; p < last; p++) { if (row->par->IsSeparator(p)) {
n++;
}
} return n;
}
/* returns the number of hfills in the specified row. The LyX-Hfill is * a LaTeX \hfill so that the hfills at the beginning and at the end were
* ignored. This is *MUCH* more usefull than not to ignore! */ int LyXText::NumberOfHfills(Row *row)
{ int n,p,last, first;
last = RowLast(row);
first = row->pos; if (first) { /* hfill *DO* count at the beginning
* of paragraphs! */ while(first <= last && row->par->IsHfill(first))
first++;
}
n = 0; int main_body = BeginningOfMainBody(row->par); if (first < main_body)
first = main_body; for (p = first; p <= last; p++) { /* last, because the end is ignored! */ if (row->par->IsHfill(p)) {
n++;
}
} return n;
}
/* like NumberOfHfills, but only those in the manual label! */ int LyXText::NumberOfLabelHfills(Row *row)
{ int n,p,last, first;
last = RowLast(row);
first = row->pos; if (first) { /* hfill *DO* count at the beginning
* of paragraphs! */ while(first < last && row->par->IsHfill(first))
first++;
}
n = 0; int main_body = BeginningOfMainBody(row->par);
if (last > main_body)
last = main_body;
for (p = first; p < last; p++) { /* last, because the end is ignored! */ if (row->par->IsHfill(p)) {
n++;
}
} return n;
}
/* returns true, if a expansion is needed.
* Rules are given by LaTeX */ bool LyXText::HfillExpansion(Row *row_ptr, int pos)
{ /* by the way, is it a hfill? */ if (!row_ptr->par->IsHfill(pos)) returnfalse;
/* at the end of a row it does not count */ if (pos >= RowLast(row_ptr)) returnfalse;
/* at the beginning of a row it does not count, if it is not
* the first row of a paragaph */ if (!row_ptr->pos) returntrue;
/* in some labels it does not count */ if ( lyxstyle.Style(parameters->textclass, row_ptr->par->GetLayout())->margintype != MARGIN_MANUAL &&
pos < BeginningOfMainBody(row_ptr->par)) returnfalse;
/* if there is anything between the first char of the row and * the sepcified position that is not a newline and not a hfill,
* the hfill will count, otherwise not */
int i = row_ptr->pos; while (i < pos && (row_ptr->par->IsNewline(i)
|| row_ptr->par->IsHfill(i)))
i++;
return (i != pos);
}
void LyXText::SetHeightOfRow(Row *row_ptr)
{ /* get the maximum ascent and the maximum descent */ int asc, maxasc, desc, maxdesc, pos_end, pos, labeladdon; float layoutasc = 0; float layoutdesc = 0; float tmptop = 0;
LyXParagraph *par, *firstpar;
LyXFont tmpfont;
Inset *tmpinset;
/* this must not happen before the currentrow for clear reasons.
so the trick is just to set the current row onto this row */ long unused_y;
GetRow(row_ptr->par, row_ptr->pos, unused_y);
/* ok , let us initialize the maxasc and maxdesc value. * This depends in LaTeX of the font of the last character * in the paragraph. The hack below is necessary because
* of the possibility of open footnotes */
/* Correction: only the fontsize count. The other properties
are taken from the layoutfont. Nicer on the screen :) */
par = row_ptr->par->LastPhysicalPar();
firstpar = row_ptr->par->FirstPhysicalPar();
// Check if any insets are larger for (pos = row_ptr->pos; pos <= pos_end; pos++) { if (row_ptr->par->GetChar(pos) == LYX_META_INSET) {
tmpfont = GetFont(row_ptr->par, pos);
tmpinset = row_ptr->par->GetInset(pos); if (tmpinset) {
asc = tmpinset->Ascent(tmpfont);
desc = tmpinset->Descent(tmpfont); if (asc > maxasc)
maxasc = asc; if (desc > maxdesc)
maxdesc = desc;
}
}
}
// Check if any custom fonts are larger (Asger) // This is not completely correct, but we can live with the small, // cosmetic error for now.
LyXFont::FONT_SIZE maxsize = row_ptr->par->HighestFontInRange(row_ptr->pos, pos_end); if (maxsize > font.size()) {
font.setSize(maxsize);
/* table stuff -- begin*/ if (row_ptr->par->table){ // stretch the rows a bit
maxasc += 1;
maxdesc +=1;
} /* table stuff -- end*/
// This is nicer with box insets:
maxasc++;
maxdesc++;
row_ptr->ascent_of_text = maxasc;
/* is it a top line? */ if (row_ptr->pos == 0
&& row_ptr->par == firstpar) {
/* some parksips VERY EASY IMPLEMENTATION */ if (parameters->paragraph_separation == LYX_PARSEP_SKIP) { if (layout->isParagraph()
&& firstpar->GetDepth() == 0
&& firstpar->Previous())
maxasc += parameters->getDefSkip().inPixels(); elseif (firstpar->Previous()
&& lyxstyle.Style(parameters->textclass,
firstpar->Previous()->GetLayout())->isParagraph()
&& firstpar->Previous()->GetDepth() == 0) // is it right to use defskip here too? (AS)
maxasc += parameters->getDefSkip().inPixels();
}
/* the paper margins */ if (!row_ptr->par->previous)
maxasc += LYX_PAPER_MARGIN;
/* add the vertical spaces, that the user added */ if (firstpar->added_space_top.kind() != VSpace::NONE)
maxasc += int(firstpar->added_space_top.inPixels());
/* do not forget the DTP-lines!
* there height depends on the font of the nearest character */ if (firstpar->line_top)
maxasc += 2 * GetFont(firstpar, 0).ascent('x');
/* and now the pagebreaks */ if (firstpar->pagebreak_top)
maxasc += 3 * DefaultHeight();
/* this is special code for the chapter, since the label of this
* layout is printed in an extra row */ if (layout->labeltype == LABEL_COUNTER_CHAPTER
&& parameters->secnumdepth>=0) {
labeladdon = int(labelfont.maxDescent() *
layout->spacing.getValue() *
parameters->spacing.getValue())
+ int(labelfont.maxAscent() *
layout->spacing.getValue() *
parameters->spacing.getValue());
}
/* special code for the top label */ if ((layout->labeltype == LABEL_TOP_ENVIRONMENT
|| layout->labeltype == LABEL_BIBLIO
|| layout->labeltype == LABEL_CENTERED_TOP_ENVIRONMENT)
&& row_ptr->par->IsFirstInSequence()
&& !row_ptr->par->GetLabelString().empty()) {
labeladdon = int(
(labelfont.maxAscent() *
layout->spacing.getValue() *
parameters->spacing.getValue())
+(labelfont.maxDescent() *
layout->spacing.getValue() *
parameters->spacing.getValue())
+ layout->topsep * DefaultHeight()
+ layout->labelbottomsep * DefaultHeight());
}
/* and now the layout spaces, for example before and after a section,
* or between the items of a itemize or enumerate environment */
/* is it a bottom line? */ if (row_ptr->par->ParFromPos(RowLast(row_ptr) + 1) == par
&& (!row_ptr->next || row_ptr->next->par != row_ptr->par)) {
/* the paper margins */ if (!par->next)
maxdesc += LYX_PAPER_MARGIN;
/* add the vertical spaces, that the user added */ if (firstpar->added_space_bottom.kind() != VSpace::NONE)
maxdesc += int(firstpar->added_space_bottom.inPixels());
/* do not forget the DTP-lines!
* there height depends on the font of the nearest character */ if (firstpar->line_bottom)
maxdesc += 2 * (GetFont(par, par->Last()-1).ascent('x'));
/* and now the pagebreaks */ if (firstpar->pagebreak_bottom)
maxdesc += 3 * DefaultHeight();
/* and now the layout spaces, for example before and after a section,
* or between the items of a itemize or enumerate environment */ if (!firstpar->pagebreak_bottom && row_ptr->par->Next()) {
LyXParagraph *nextpar = row_ptr->par->Next();
LyXParagraph *comparepar = row_ptr->par; float usual = 0; float unusual = 0;
/* Appends the implicit specified paragraph behind the specified row,
* start at the implicit given position */ void LyXText::AppendParagraph(Row *row)
{ int z;
Row *tmprow; bool not_ready = true;
// Get the width of the row
z = row->pos;
// The last character position of a paragraph is an invariant so we can // safely get it here. (Asger) int lastposition = row->par->Last();
do { // Get the next breakpoint
z = NextBreakPoint(row, paperwidth);
tmprow = row;
// Insert the new row if (z < lastposition) {
z++;
InsertRow(row, row->par, z);
row = row->next;
row->height = 0;
} else
not_ready = false;
// Set the dimensions of the row
tmprow->fill = Fill(tmprow, paperwidth);
SetHeightOfRow(tmprow);
} while (not_ready);
}
void LyXText::BreakAgain(Row *row)
{ int z; char not_ready;
z = row->pos;
Row *tmprow, *tmprow2;
not_ready = 1;
do { /* get the next breakpoint */
z = NextBreakPoint(row, paperwidth);
tmprow = row;
if (z < row->par->Last() ) { if (!row->next || (row->next && row->next->par != row->par)) { /* insert a new row */
z++;
InsertRow(row, row->par, z);
row = row->next;
row->height = 0;
} else {
row=row->next;
z++; if (row->pos == z)
not_ready = 0; /* the rest will not change */ else {
row->pos = z;
}
}
} else { /* if there are some rows too much, delete them */ /* only if you broke the whole paragraph! */
tmprow2 = row; while (tmprow2->next && tmprow2->next->par == row->par) {
tmprow2 = tmprow2->next;
} while (tmprow2 != row) {
tmprow2 = tmprow2->previous;
RemoveRow(tmprow2->next);
}
not_ready = 0;
}
/* set the dimensions of the row */
tmprow->fill = Fill(tmprow, paperwidth);
SetHeightOfRow(tmprow);
} while (not_ready);
}
/* this is just a little changed version of break again */ void LyXText::BreakAgainOneRow(Row *row)
{ int z; char not_ready;
z = row->pos;
Row *tmprow, *tmprow2;
not_ready = 1;
/* get the next breakpoint */
z = NextBreakPoint(row, paperwidth);
tmprow = row;
if (z < row->par->Last() ) { if (!row->next || (row->next && row->next->par != row->par)) { /* insert a new row */
z++;
InsertRow(row, row->par, z);
row = row->next;
row->height = 0;
} else {
row=row->next;
z++; if (row->pos == z)
not_ready = 0; /* the rest will not change */ else {
row->pos = z;
}
}
} else { /* if there are some rows too much, delete them */ /* only if you broke the whole paragraph! */
tmprow2 = row; while (tmprow2->next && tmprow2->next->par == row->par) {
tmprow2 = tmprow2->next;
} while (tmprow2 != row) {
tmprow2 = tmprow2->previous;
RemoveRow(tmprow2->next);
}
not_ready = 0;
}
/* set the dimensions of the row */
tmprow->fill = Fill(tmprow, paperwidth);
SetHeightOfRow(tmprow);
}
/* table stuff -- begin*/ if (cursor.par->table) { // breaking of tables is only allowed at the beginning or the end */ if (cursor.pos && cursor.pos < cursor.par->last &&
!cursor.par->table->ShouldBeVeryLastCell(NumberOfCell(cursor.par, cursor.pos))) return; /* no breaking of tables allowed */
} /* table stuff -- end*/
/* this is only allowed, if the current paragraph is not empty or caption*/ if ((cursor.par->Last() <= 0 && !cursor.par->IsDummy())
&&
layout->labeltype!=LABEL_SENSITIVE) return;
/* table stuff -- begin*/ if (cursor.par->table) { int cell = NumberOfCell(cursor.par, cursor.pos); if (cursor.par->table->ShouldBeVeryLastCell(cell))
SetCursor(cursor.par,cursor.par->last);
} /* table stuff -- end*/ /* please break alway behind a space */ if (cursor.pos < cursor.par->Last()
&& cursor.par->IsLineSeparator(cursor.pos))
cursor.pos++;
/* break the paragraph */ if (keep_layout)
keep_layout = 2; else
keep_layout = layout->isEnvironment();
cursor.par->BreakParagraph(cursor.pos, keep_layout);
/* table stuff -- begin*/ if (cursor.par->table){ // the table should stay with the contents if (!cursor.pos){
cursor.par->Next()->table = cursor.par->table;
cursor.par->table = NULL;
}
} /* table stuff -- end*/
/* well this is the caption hack since one caption is really enough */ if (layout->labeltype == LABEL_SENSITIVE){ if (!cursor.pos)
cursor.par->SetLayout(0); /* set the new paragraph to standard-layout */ else
cursor.par->Next()->SetLayout(0); /* set the new paragraph to standard-layout */
}
/* if the cursor is at the beginning of a row without prior newline, * move one row up! * This touches only the screen-update. Otherwise we would may have
* an empty row on the screen */ if (cursor.pos && !cursor.row->par->IsNewline(cursor.row->pos -1) &&
cursor.row->pos == cursor.pos) {
CursorLeft();
}
/* Do not forget the special right address boxes */ if (layout->margintype == MARGIN_RIGHT_ADDRESS_BOX) { while (refresh_row->previous &&
refresh_row->previous->par == refresh_row->par) {
refresh_row = refresh_row->previous;
refresh_y -= refresh_row->height;
}
}
RemoveParagraph(cursor.row);
/* set the dimensions of the cursor row */
cursor.row->fill = Fill(cursor.row, paperwidth);
SetHeightOfRow(cursor.row);
while (!cursor.par->Next()->table && cursor.par->Next()->Last()
&& cursor.par->Next()->IsNewline(0))
cursor.par->Next()->Erase(0);
InsertParagraph(cursor.par->Next(), cursor.row);
UpdateCounters(cursor.row->previous);
/* this check is necessary. Otherwise the new empty paragraph will
* be deleted automatically. And it is more friendly for the user! */ if (cursor.pos)
SetCursor(cursor.par->Next(), 0); else
SetCursor(cursor.par, 0);
if (cursor.row->next)
BreakAgain(cursor.row->next);
/* if there is no footnote in this paragraph, just return. */ if (!par->next
|| par->next->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE) return;
/* ok, move the cursor right before the footnote */
/* just a little faster than using CursorRight() */ for (cursor.pos=0; cursor.par->ParFromPos(cursor.pos)!=par; cursor.pos++); /* now the cursor is at the beginning of the physical par */
SetCursor(cursor.par, cursor.pos + cursor.par->ParFromPos(cursor.pos)->last);
/* the cursor must be exactly before the footnote */
par = cursor.par->ParFromPos(cursor.pos);
tmppar->OpenFootnote(cursor.pos);
RemoveParagraph(row); /* set the dimensions of the cursor row */
row->fill = Fill(row, paperwidth);
SetHeightOfRow(row);
tmppar = tmppar->Next();
while (tmppar != endpar) { if (tmppar) {
InsertParagraph(tmppar, row); while (row->next && row->next->par == tmppar)
row = row->next;
tmppar = tmppar->Next();
}
}
SetCursor(par->next, 0);
sel_cursor = cursor;
}
/* table stuff -- begin*/
void LyXText::TableFeatures(int feature, LString val)
{ int
actCell;
if (!cursor.par->table) return; /* this should never happen */
switch (feature){ case LyXTable::ALIGN_LEFT:
setAlign=LYX_ALIGN_LEFT; break; case LyXTable::ALIGN_RIGHT:
setAlign=LYX_ALIGN_RIGHT; break; case LyXTable::ALIGN_CENTER:
setAlign=LYX_ALIGN_CENTER; break; default: break;
} switch (feature){ case LyXTable::APPEND_ROW: { int pos = cursor.pos; /* move to the next row */ int cell_org = actCell; int cell = cell_org;
// if there is a ContRow following this row I have to add // the row after the ContRow's if ((pos < cursor.par->Last()) &&
cursor.par->table->RowHasContRow(cell_org)) { while((pos < cursor.par->Last()) &&
!cursor.par->table->IsContRow(cell)) { while (pos < cursor.par->Last() &&
!cursor.par->IsNewline(pos))
pos++; if (pos < cursor.par->Last())
pos++;
cell++;
} while((pos < cursor.par->Last()) &&
cursor.par->table->IsContRow(cell)) { while (pos < cursor.par->Last() &&
!cursor.par->IsNewline(pos))
pos++; if (pos < cursor.par->Last())
pos++;
cell++;
}
cell_org = --cell; if (pos < cursor.par->Last())
pos--;
} while (pos < cursor.par->Last() &&
(cell == cell_org || !cursor.par->table->IsFirstCell(cell))){ while (pos < cursor.par->Last() && !cursor.par->IsNewline(pos))
pos++; if (pos < cursor.par->Last())
pos++;
cell++;
}
/* insert the new cells */ int number = cursor.par->table->NumberOfCellsInRow(cell_org); int i; for (i=0; i<number; i++)
cursor.par->InsertChar(pos, LYX_META_NEWLINE);
/* append the row into the table */
cursor.par->table->AppendRow(cell_org);
RedoParagraph(); return;
} case LyXTable::APPEND_CONT_ROW: { int pos = cursor.pos; /* move to the next row */ int cell_org = actCell; int cell = cell_org;
// if there is already a controw but not for this cell // the AppendContRow sets only the right values but does // not actually add a row if (cursor.par->table->RowHasContRow(cell_org) &&
(cursor.par->table->CellHasContRow(cell_org)<0)) {
cursor.par->table->AppendContRow(cell_org);
RedoParagraph(); return;
} while (pos < cursor.par->Last() &&
(cell == cell_org
|| !cursor.par->table->IsFirstCell(cell))){ while (pos < cursor.par->Last() && !cursor.par->IsNewline(pos))
pos++; if (pos < cursor.par->Last())
pos++;
cell++;
}
/* insert the new cells */ int number = cursor.par->table->NumberOfCellsInRow(cell_org); int i; for (i=0; i<number; i++)
cursor.par->InsertChar(pos, LYX_META_NEWLINE);
/* append the row into the table */
cursor.par->table->AppendContRow(cell_org);
RedoParagraph(); return;
} case LyXTable::APPEND_COLUMN: { int pos = 0; int cell_org = actCell; int cell = 0; do{ if (pos && (cursor.par->IsNewline(pos-1))){ if (cursor.par->table->AppendCellAfterCell(cell_org, cell)){
cursor.par->InsertChar(pos, LYX_META_NEWLINE); if (pos<=cursor.pos)
cursor.pos++;
pos++;
}
cell++;
}
pos++;
} while (pos<= cursor.par->Last()); /* remember that the very last cell doesn't end with a newline.
This saves one byte memory per table ;-) */ if (cursor.par->table->AppendCellAfterCell(cell_org, cell))
cursor.par->InsertChar(cursor.par->Last(), LYX_META_NEWLINE);
/* append the column into the table */
cursor.par->table->AppendColumn(cell_org);
RedoParagraph(); return;
} case LyXTable::DELETE_ROW: if (current_view->currentBuffer()->the_locking_inset)
UnlockInset(current_view->currentBuffer()->the_locking_inset);
RemoveTableRow(&cursor);
RedoParagraph(); return;
case LyXTable::DELETE_COLUMN: { int pos = 0; int cell_org = actCell; int cell = 0; if (current_view->currentBuffer()->the_locking_inset)
UnlockInset(current_view->currentBuffer()->the_locking_inset); do { if (!pos || (cursor.par->IsNewline(pos-1))){ if (cursor.par->table->DeleteCellIfColumnIsDeleted(cell, cell_org)){ // delete one cell while (pos < cursor.par->Last() && !cursor.par->IsNewline(pos))
cursor.par->Erase(pos); if (pos < cursor.par->Last())
cursor.par->Erase(pos); else
cursor.par->Erase(pos - 1); // the missing newline at the end of a table
pos--; // because of pos++ below
}
cell++;
}
pos++;
} while (pos<= cursor.par->Last());
/* delete the column from the table */
cursor.par->table->DeleteColumn(cell_org);
/* set the cursor to the beginning of the table, where else? */
cursor.pos = 0;
RedoParagraph(); return;
} case LyXTable::TOGGLE_LINE_TOP:
lineSet = !cursor.par->table->TopLine(actCell); if (!selection){
cursor.par->table->SetTopLine(actCell,lineSet);
} else { int i,n=-1,m=-2; for (i=sel_start_cursor.pos; i<=sel_end_cursor.pos; i++){ if ((n=NumberOfCell(sel_start_cursor.par,i)) != m) {
cursor.par->table->SetTopLine(n,lineSet);
m = n;
}
}
}
RedoParagraph(); return;
case LyXTable::TOGGLE_LINE_BOTTOM:
lineSet = !cursor.par->table->BottomLine(actCell); if (!selection){
cursor.par->table->SetBottomLine(actCell,lineSet);
} else { int i,n=-1,m=-2; for (i=sel_start_cursor.pos; i<=sel_end_cursor.pos; i++){ if ((n=NumberOfCell(sel_start_cursor.par,i)) != m) {
cursor.par->table->SetBottomLine(n,lineSet);
m = n;
}
}
}
RedoParagraph(); return;
case LyXTable::TOGGLE_LINE_LEFT:
lineSet = !cursor.par->table->LeftLine(actCell); if (!selection){
cursor.par->table->SetLeftLine(actCell,lineSet);
} else { int i,n=-1,m=-2; for (i=sel_start_cursor.pos; i<=sel_end_cursor.pos; i++){ if ((n=NumberOfCell(sel_start_cursor.par,i)) != m) {
cursor.par->table->SetLeftLine(n,lineSet);
m = n;
}
}
}
RedoParagraph(); return;
case LyXTable::TOGGLE_LINE_RIGHT:
lineSet = !cursor.par->table->RightLine(actCell); if (!selection){
cursor.par->table->SetRightLine(actCell,lineSet);
} else { int i,n=-1,m=-2; for (i=sel_start_cursor.pos; i<=sel_end_cursor.pos; i++){ if ((n=NumberOfCell(sel_start_cursor.par,i)) != m) {
cursor.par->table->SetRightLine(n,lineSet);
m = n;
}
}
}
RedoParagraph(); return;
case LyXTable::ALIGN_LEFT: case LyXTable::ALIGN_RIGHT: case LyXTable::ALIGN_CENTER: if (!selection){
cursor.par->table->SetAlignment(actCell,setAlign);
} else { int i,n=-1,m=-2; for (i=sel_start_cursor.pos; i<=sel_end_cursor.pos; i++){ if ((n=NumberOfCell(sel_start_cursor.par,i)) != m) {
cursor.par->table->SetAlignment(n,setAlign);
m = n;
}
}
}
RedoParagraph(); return;
case LyXTable::DELETE_TABLE:
SetCursorIntern(cursor.par, 0); delete cursor.par->table;
cursor.par->table = NULL; // temporary: Should put table in simple_cut_buffer (with before and after // dummy-paragraph !! // not necessar anymore with UNDO :) int i; for (i = cursor.par->last-1; i>=0; i--)
cursor.par->Erase(i);
RedoParagraph(); return;
case LyXTable::MULTICOLUMN: { int number = 0; // check wether we are completly in a multicol int multicol = cursor.par->table->IsMultiColumn(actCell); if (multicol && selection && sel_start_cursor.row == sel_end_cursor.row){
multicol = NumberOfCell(sel_start_cursor.par, sel_start_cursor.pos)
== NumberOfCell(sel_end_cursor.par, sel_end_cursor.pos);
}
if (multicol){ int newlines = cursor.par->table->UnsetMultiColumn(actCell); int pos = cursor.pos; while (pos<cursor.par->Last() && !cursor.par->IsNewline(pos))
pos++; for (;newlines;newlines--)
cursor.par->InsertChar(pos, LYX_META_NEWLINE);
RedoParagraph(); return;
} else { // selection must be in one row (or no selection) if (!selection){
cursor.par->table->SetMultiColumn(NumberOfCell(cursor.par,
cursor.pos),
1);
RedoParagraph(); return;
} else { if (sel_start_cursor.row == sel_end_cursor.row){ int i;
number = 1; for (i=sel_start_cursor.pos; i<sel_end_cursor.pos; i++){ if (sel_start_cursor.par->IsNewline(i)){
sel_start_cursor.par->Erase(i); // check for double-blanks if ((i && !sel_start_cursor.par->IsLineSeparator(i-1))
&&
(i<sel_start_cursor.par->Last()
&& !sel_start_cursor.par->IsLineSeparator(i)))
sel_start_cursor.par->InsertChar(i, ' '); else {
sel_end_cursor.pos--;
i--;
}
number++;
}
}
cursor.par->table->
SetMultiColumn(NumberOfCell(sel_start_cursor.par,
sel_start_cursor.pos),
number);
cursor.pos = sel_start_cursor.pos;
RedoParagraph(); return;
} else {
WriteAlert(_("Impossible Operation!"),
_("Multicolumns can only be horizontally."),
_("Sorry."));
}
}
} break;
} case LyXTable::SET_ALL_LINES:
setLines = 1; case LyXTable::UNSET_ALL_LINES: if (!selection){
cursor.par->table->SetAllLines(NumberOfCell(cursor.par,
cursor.pos),
setLines);
} else { int i,n=-1,m=-2; for (i=sel_start_cursor.pos; i<=sel_end_cursor.pos; i++){ if ((n=NumberOfCell(sel_start_cursor.par,i)) != m) {
cursor.par->table->SetAllLines(n,setLines);
m = n;
}
}
}
RedoParagraph(); return; case LyXTable::SET_LONGTABLE:
cursor.par->table->SetLongTable(true); return; case LyXTable::UNSET_LONGTABLE:
cursor.par->table->SetLongTable(false); return; case LyXTable::SET_ROTATE_TABLE:
cursor.par->table->SetRotateTable(true); return; case LyXTable::UNSET_ROTATE_TABLE:
cursor.par->table->SetRotateTable(false); return; case LyXTable::SET_ROTATE_CELL: if (!selection){
cursor.par->table->SetRotateCell(actCell,true);
} else { int i,n=-1,m=-2; for (i=sel_start_cursor.pos; i<=sel_end_cursor.pos; i++){ if ((n=NumberOfCell(sel_start_cursor.par,i)) != m) {
cursor.par->table->SetRotateCell(n,true);
m = n;
}
}
} return; case LyXTable::UNSET_ROTATE_CELL: if (!selection){
cursor.par->table->SetRotateCell(actCell,false);
} else { int i,n=-1,m=-2; for (i=sel_start_cursor.pos; i<=sel_end_cursor.pos; i++){ if ((n=NumberOfCell(sel_start_cursor.par,i)) != m) {
cursor.par->table->SetRotateCell(n,false);
m = n;
}
}
} return; case LyXTable::SET_LINEBREAKS:
what = !cursor.par->table->Linebreaks(cursor.par->table->FirstVirtualCell(actCell)); if (!selection){
cursor.par->table->SetLinebreaks(actCell,what);
} else { int i,n=-1,m=-2; for (i=sel_start_cursor.pos; i<=sel_end_cursor.pos; i++){ if ((n=NumberOfCell(sel_start_cursor.par,i)) != m) {
cursor.par->table->SetLinebreaks(n,what);
m = n;
}
}
} return; case LyXTable::SET_LTFIRSTHEAD:
cursor.par->table->SetLTHead(actCell,true); return; case LyXTable::SET_LTHEAD:
cursor.par->table->SetLTHead(actCell,false); return; case LyXTable::SET_LTFOOT:
cursor.par->table->SetLTFoot(actCell,false); return; case LyXTable::SET_LTLASTFOOT:
cursor.par->table->SetLTFoot(actCell,true); return; case LyXTable::SET_LTNEWPAGE:
what = !cursor.par->table->LTNewPage(actCell);
cursor.par->table->SetLTNewPage(actCell,what); return;
}
}
void LyXText::InsertCharInTable(char c)
{
Row *row;
Row *tmprow; long y; bool jumped_over_space;
/* first check, if there will be two blanks together or a blank at * the beginning of a paragraph. * I decided to handle blanks like normal characters, the main * difference are the special checks when calculating the row.fill
* (blank does not count at the end of a row) and the check here */
LyXFont realtmpfont = real_current_font;
LyXFont rawtmpfont = current_font; /* store the current font. * This is because of the use * of cursor movements. The moving * cursor would refresh the
* current font */
// Get the font that is used to calculate the baselineskip intconst lastpos = cursor.par->Last();
LyXFont rawparfont = cursor.par->GetFontSettings(lastpos - 1);
jumped_over_space = false; if (IsLineSeparatorChar(c)) {
/* avoid double blanks but insert the new blank because
* of a possible font change */ if (cursor.pos < lastpos &&
cursor.par->IsLineSeparator(cursor.pos))
{
cursor.par->Erase(cursor.pos);
jumped_over_space = true;
} elseif ((cursor.pos > 0 &&
cursor.par->IsLineSeparator(cursor.pos - 1))
|| (cursor.pos > 0 && cursor.par->IsNewline(cursor.pos - 1))
|| (cursor.pos == 0 &&
!(cursor.par->Previous()
&& cursor.par->Previous()->footnoteflag
== LyXParagraph::OPEN_FOOTNOTE))) return;
} elseif (IsNewlineChar(c)) { if (!IsEmptyTableCell()) {
TableFeatures(LyXTable::APPEND_CONT_ROW);
CursorDown();
} /* the newline character is the separator of the cells */ // cursor.par->InsertChar(cursor.pos, c); // SetCharFont(cursor.par, cursor.pos, rawtmpfont); // RedoParagraphs(cursor, cursor.par->Next()); // SetCursor(cursor.par, cursor.pos+1); return;
}
row = cursor.row;
y = cursor.y - row->baseline; if (c != LYX_META_INSET) /* in this case LyXText::InsertInset
* already inserted the character */
cursor.par->InsertChar(cursor.pos, c);
SetCharFont(cursor.par, cursor.pos, rawtmpfont);
if (!jumped_over_space) { /* refresh the positions */
tmprow = row; while (tmprow->next && tmprow->next->par == row->par) {
tmprow = tmprow->next;
tmprow->pos++;
}
}
/* check, whether the last character's font has changed. */ if (cursor.pos && cursor.pos == cursor.par->Last()
&& rawparfont != rawtmpfont)
RedoHeightOfParagraph(cursor);
}
void LyXText::CheckParagraphInTable(LyXParagraph* par, int pos)
{
Row *row; long y;
if (par->GetChar(pos) == LYX_META_INSET &&
par->GetInset(pos) && par->GetInset(pos)->Display()){
par->GetInset(pos)->SetDisplay(false);
}
row = GetRow(par, pos, y);
int tmpheight = row->height;
SetHeightOfRow(row);
int tmp_pos = pos; /* update the table information */ while (tmp_pos && !par->IsNewline(tmp_pos - 1))
tmp_pos--; if (par->table->SetWidthOfCell(NumberOfCell(par, pos),
WidthOfCell(par, tmp_pos))) {
LyXCursor tmpcursor = cursor;
SetCursorIntern(par, pos); /* make a complete redraw */
RedoDrawingOfParagraph(cursor);
cursor = tmpcursor;
} else { /* redraw only the row */
LyXCursor tmpcursor = cursor;
SetCursorIntern(par, pos);
refresh_y = y;
refresh_x = cursor.x;
refresh_row = row;
refresh_pos = cursor.pos;
cursor = tmpcursor;
if (tmpheight == row->height)
status = LyXText::NEED_VERY_LITTLE_REFRESH; else
status = LyXText::NEED_MORE_REFRESH;
}
SetCursorIntern(cursor.par, cursor.pos);
}
void LyXText::BackspaceInTable()
{
Row *tmprow, *row; long y;
// Get the font that is used to calculate the baselineskip intconst lastpos = cursor.par->Last();
LyXFont rawparfont = cursor.par->GetFontSettings(lastpos - 1);
if (cursor.pos == 0) { /* no pasting of table paragraphs */
CursorLeft();
} else { /* this is the code for a normal backspace, not pasting
* any paragraphs */
SetUndo(Undo::DELETE,
cursor.par->ParFromPos(cursor.pos)->previous,
cursor.par->ParFromPos(cursor.pos)->next);
CursorLeftIntern();
/* some insets are undeletable here */ if (cursor.par->GetChar(cursor.pos)==LYX_META_INSET) { if (!cursor.par->GetInset(cursor.pos)->Deletable()) return;
}
row = cursor.row;
y = cursor.y - row->baseline;
/* some special code when deleting a newline. */ if (cursor.par->IsNewline(cursor.pos)) { /* nothing :-) */ return;
} else {
cursor.par->Erase(cursor.pos);
/* refresh the positions */
tmprow = row; while (tmprow->next && tmprow->next->par == row->par) {
tmprow = tmprow->next;
tmprow->pos--;
}
if (cursor.pos == BeginningOfMainBody(cursor.par)
|| !cursor.pos
|| cursor.par->IsLineSeparator(cursor.pos - 1)) {
cursor.par->Erase(cursor.pos); /* refresh the positions */
tmprow = row; while (tmprow->next &&
tmprow->next->par == row->par) {
tmprow = tmprow->next;
tmprow->pos--;
} if (cursor.pos) /* move one character left */
cursor.pos--;
}
}
}
CheckParagraphInTable(cursor.par, cursor.pos);
/* check, wether the last characters font has changed. */ if (cursor.pos && cursor.pos == cursor.par->Last()
&& rawparfont != rawtmpfont)
RedoHeightOfParagraph(cursor);
/* restore the current font
--> --------------------
--> maximum size reached
--> --------------------
¤ Dauer der Verarbeitung: 0.38 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.