X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Ftext.C;h=c81fae1f9b3af9e3315795c7f73349b769992667;hb=91a2ea274e9c27f571a3cd4798d2e8ecc1b982a7;hp=4aa3d1e65bbf76be7b242e1921d86b826498ec5b;hpb=722d679779a28fb8cef1b98138d7524631fb9429;p=lyx.git diff --git a/src/text.C b/src/text.C index 4aa3d1e65b..c81fae1f9b 100644 --- a/src/text.C +++ b/src/text.C @@ -4,7 +4,7 @@ * LyX, The Document Processor * * Copyright 1995 Matthias Ettrich - * Copyright 1995-1999 The LyX Team. + * Copyright 1995-2000 The LyX Team. * * ====================================================== */ @@ -20,31 +20,143 @@ #include "lyxparagraph.h" #include "lyxtext.h" #include "support/textutils.h" +#include "insets/insetbib.h" #include "lyx_gui_misc.h" -#include "lyxdraw.h" #include "gettext.h" #include "bufferparams.h" #include "buffer.h" -#include "lyxscreen.h" #include "minibuffer.h" #include "debug.h" +#include "lyxrc.h" #include "LyXView.h" +#include "lyxrow.h" +#include "Painter.h" +#include "tracer.h" using std::max; using std::min; static const int LYX_PAPER_MARGIN = 20; -extern int mono_video; -extern int reverse_video; -extern int fast_selection; -extern BufferView * current_view; // ale070405 -extern int bibitemMaxWidth(LyXFont const &); +extern int bibitemMaxWidth(Painter &, LyXFont const &); #define FIX_DOUBLE_SPACE 1 +static int iso885968x[] = { + 0xbc, // 0xa8 = fathatan + 0xbd, // 0xa9 = dammatan + 0xbe, // 0xaa = kasratan + 0xdb, // 0xab = fatha + 0xdc, // 0xac = damma + 0xdd, // 0xad = kasra + 0xde, // 0xae = shadda + 0xdf, // 0xaf = sukun + + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0xb0-0xbf + + 0, // 0xc0 + 0xc1, // 0xc1 = hamza + 0xc2, // 0xc2 = ligature madda + 0xc3, // 0xc3 = ligature hamza on alef + 0xc4, // 0xc4 = ligature hamza on waw + 0xc5, // 0xc5 = ligature hamza under alef + 0xc0, // 0xc6 = ligature hamza on ya + 0xc7, // 0xc7 = alef + 0xeb, // 0xc8 = baa + 0xc9, // 0xc9 = taa marbuta + 0xec, // 0xca = taa + 0xed, // 0xcb = thaa + 0xee, // 0xcc = jeem + 0xef, // 0xcd = haa + 0xf0, // 0xce = khaa + 0xcf, // 0xcf = dal + + 0xd0, // 0xd0 = thal + 0xd1, // 0xd1 = ra + 0xd2, // 0xd2 = zain + 0xf1, // 0xd3 = seen + 0xf2, // 0xd4 = sheen + 0xf3, // 0xd5 = sad + 0xf4, // 0xd6 = dad + 0xd7, // 0xd7 = tah + 0xd8, // 0xd8 = zah + 0xf5, // 0xd9 = ain + 0xf6, // 0xda = ghain + 0,0,0,0,0, // 0xdb- 0xdf + + 0, // 0xe0 + 0xf7, // 0xe1 = fa + 0xf8, // 0xe2 = qaf + 0xf9, // 0xe3 = kaf + 0xfa, // 0xe4 = lam + 0xfb, // 0xe5 = meem + 0xfc, // 0xe6 = noon + 0xfd, // 0xe7 = ha + 0xe8, // 0xe8 = waw + 0xe9, // 0xe9 = alef maksura + 0xfe // 0xea = ya +}; + +bool is_arabic(unsigned char c) +{ + return 0xa8 <= c && c <= 0xea && iso885968x[c-0xa8]; +} + +unsigned char LyXText::TransformChar(unsigned char c, Letter_Form form) const +{ + if (is_arabic(c) && + (form == FORM_INITIAL || form == FORM_MEDIAL) ) + return iso885968x[c-0xa8]; + else + return c; +} + +unsigned char LyXText::TransformChar(unsigned char c, LyXParagraph * par, + LyXParagraph::size_type pos) const +{ + if (!is_arabic(c)) + return c; + + bool not_first = (pos > 0 && is_arabic(par->GetChar(pos-1))); + if (pos < par->Last()-1 && is_arabic(par->GetChar(pos+1))) + if (not_first) + return TransformChar(c,FORM_MEDIAL); + else + return TransformChar(c,FORM_INITIAL); + else + if (not_first) + return TransformChar(c,FORM_FINAL); + else + return TransformChar(c,FORM_ISOLATED); +} + +// This is the comments that some of the warnings below refers to. +// There are some issues in this file and I don't think they are +// really related to the FIX_DOUBLE_SPACE patch. I'd rather think that +// this is a problem that has been here almost from day one and that a +// larger userbase with differenct access patters triggers the bad +// behaviour. (segfaults.) What I think happen is: In several places +// we store the paragraph in the current cursor and then moves the +// cursor. This movement of the cursor will delete paragraph at the +// old position if it is now empty. This will make the temporary +// pointer to the old cursor paragraph invalid and dangerous to use. +// And is some cases this will trigger a segfault. I have marked some +// of the cases where this happens with a warning, but I am sure there +// are others in this file and in text2.C. There is also a note in +// Delete() that you should read. In Delete I store the paragraph->id +// instead of a pointer to the paragraph. I am pretty sure this faulty +// use of temporary pointers to paragraphs that might have gotten +// invalidated (through a cursor movement) before they are used, are +// the cause of the strange crashes we get reported often. +// +// It is very tiresom to change this code, especially when it is as +// hard to read as it is. Help to fix all the cases where this is done +// would be greately appreciated. +// +// Lgb + int LyXText::SingleWidth(LyXParagraph * par, LyXParagraph::size_type pos) const { @@ -60,20 +172,20 @@ int LyXText::SingleWidth(LyXParagraph * par, // The most common case is handled first (Asger) if (IsPrintable(c)) { + if (lyxrc.rtl_support && lyxrc.font_norm == "iso8859-6.8x") + c = TransformChar(c, par, pos); return font.width(c); } else if (IsHfillChar(c)) { return 3; /* Because of the representation * as vertical lines */ - } else if (c == LyXParagraph::META_FOOTNOTE || c == LyXParagraph::META_MARGIN || c == LyXParagraph::META_FIG || c == LyXParagraph::META_TAB || c == LyXParagraph::META_WIDE_FIG || c == LyXParagraph::META_WIDE_TAB || - c == LyXParagraph::META_ALGORITHM) - { + c == LyXParagraph::META_ALGORITHM) { string fs; switch (c) { case LyXParagraph::META_MARGIN: @@ -101,12 +213,11 @@ int LyXText::SingleWidth(LyXParagraph * par, font.decSize(); font.decSize(); return font.stringWidth(fs); - } - - else if (c == LyXParagraph::META_INSET) { - Inset *tmpinset= par->GetInset(pos); + } else if (c == LyXParagraph::META_INSET) { + Inset * tmpinset= par->GetInset(pos); if (tmpinset) - return par->GetInset(pos)->Width(font); + return par->GetInset(pos)->width(owner_->painter(), + font); else return 0; @@ -130,29 +241,185 @@ LyXParagraph::size_type LyXText::RowLast(Row const * row) const } -void LyXText::Draw(Row const * row, LyXParagraph::size_type & pos, - LyXScreen & scr, int offset, float & x) + + + +void LyXText::ComputeBidiTables(Row * row) const { + + if (!lyxrc.rtl_support) { + bidi_start = -1; + return; + } + LyXParagraph::size_type last = RowLast(row); + bidi_start = row->pos; + + if (bidi_start > last) { + bidi_start = -1; + return; + } + + if (last + 2 - bidi_start > + static_cast(log2vis_list.size())) { + LyXParagraph::size_type new_size = + (last + 2 - bidi_start < 500) ? + 500 : 2 * (last + 2 - bidi_start); + log2vis_list.resize(new_size); + vis2log_list.resize(new_size); + } + + vis2log_list[last + 1 - bidi_start] = -1; + log2vis_list[last + 1 - bidi_start] = -1; + + LyXParagraph::size_type main_body = BeginningOfMainBody(row->par); + if (main_body > 0 && row->pos < main_body - 1 && main_body - 1 <= last + && row->par->IsLineSeparator(main_body - 1)) { + // This is needed in case there is a direction change in + // the label which is continued into the main body + if (row->par->getParDirection() == LYX_DIR_LEFT_TO_RIGHT) { + ComputeBidiTablesFromTo(row, bidi_start, + main_body - 2, 0); + log2vis_list[main_body - 1 - bidi_start] = + main_body - 1; + vis2log_list[main_body - 1 - bidi_start] = + main_body - 1; + if (main_body <= last) + ComputeBidiTablesFromTo(row, + main_body,last, 0); + } else { + ComputeBidiTablesFromTo(row, bidi_start, + main_body - 2, + last - main_body + 2); + log2vis_list[main_body - 1 - bidi_start] = + last - main_body + 1 + bidi_start; + vis2log_list[last - main_body + 1 - bidi_start] = + main_body - 1; + if (main_body <= last) + ComputeBidiTablesFromTo(row, main_body, + last, -main_body); + } + } else + ComputeBidiTablesFromTo(row, bidi_start, last, 0); +} + + +void LyXText::ComputeBidiTablesFromTo(Row * row, + LyXParagraph::size_type from, + LyXParagraph::size_type to, + LyXParagraph::size_type offset) const +{ + LyXParagraph::size_type vpos, old_lpos, stack[2]; + LyXDirection par_direction = row->par->getParDirection(); + LyXDirection direction = par_direction; + LyXParagraph::size_type lpos = from; + int level = 0; + + while (lpos <= to) { + if (row->par->getLetterDirection(lpos) == direction) { + log2vis_list[lpos - bidi_start] = direction; + ++lpos; + } else { + if (level == 0 || + (level == 1 && direction == LYX_DIR_RIGHT_TO_LEFT + && row->par->getFont(lpos).isRightToLeft() + && row->par->getFont(lpos).latex() == LyXFont::ON + ) ) { + // The last check is needed when the + // char is a space + stack[level++] = lpos; + } else { + old_lpos = stack[--level]; + log2vis_list[old_lpos - bidi_start] = + log2vis_list[lpos - bidi_start] = + (old_lpos - lpos) * direction; + ++lpos; + } + direction = static_cast(-direction); + } + } + + while (level > 0) { + old_lpos = stack[--level]; + log2vis_list[old_lpos - bidi_start] = + (old_lpos - (to + 1)) * direction; + direction = static_cast(-direction); + } + + vpos = (par_direction == LYX_DIR_LEFT_TO_RIGHT) + ? from - 1 : to + 1; + vpos += offset; + for (lpos = from; lpos <= to; ++lpos) { + vpos += log2vis_list[lpos - bidi_start]; + vis2log_list[vpos - bidi_start] = lpos; + log2vis_list[lpos - bidi_start] = vpos; + } +} + + +void LyXText::draw(Row const * row, + LyXParagraph::size_type & vpos, + int offset, float & x) +{ + Painter & pain = owner_->painter(); + + LyXParagraph::size_type pos = vis2log(vpos); char c = row->par->GetChar(pos); if (IsNewlineChar(c)) { - ++pos; + ++vpos; // Draw end-of-line marker - LyXFont font = GetFont(row->par, pos); - int asc = font.maxAscent(); int wid = font.width('n'); - int y = (offset + row->baseline); - XPoint p[3]; - p[0].x = int(x + wid*0.375); p[0].y = int(y - 0.875*asc*0.75); - p[1].x = int(x); p[1].y = int(y - 0.500*asc*0.75); - p[2].x = int(x + wid*0.375); p[2].y = int(y - 0.125*asc*0.75); - scr.drawLines(::getGC(gc_new_line), p, 3); + int asc = font.maxAscent(); + int y = offset + row->baseline; + int xp[3], yp[3]; - p[0].x = int(x); p[0].y = int(y - 0.500*asc*0.75); - p[1].x = int(x + wid); p[1].y = int(y - 0.500*asc*0.75); - p[2].x = int(x + wid); p[2].y = int(y - asc*0.75); - scr.drawLines(::getGC(gc_new_line), p, 3); + if (row->par->getLetterDirection(pos) == LYX_DIR_LEFT_TO_RIGHT) { + xp[0] = int(x + wid * 0.375); + yp[0] = int(y - 0.875 * asc * 0.75); + + xp[1] = int(x); + yp[1] = int(y - 0.500 * asc * 0.75); + + xp[2] = int(x + wid * 0.375); + yp[2] = int(y - 0.125 * asc * 0.75); + + pain.lines(xp, yp, 3, LColor::eolmarker); + + xp[0] = int(x); + yp[0] = int(y - 0.500 * asc * 0.75); + + xp[1] = int(x + wid); + yp[1] = int(y - 0.500 * asc * 0.75); + + xp[2] = int(x + wid); + yp[2] = int(y - asc * 0.75); + + pain.lines(xp, yp, 3, LColor::eolmarker); + } else { + xp[0] = int(x + wid * 0.625); + yp[0] = int(y - 0.875 * asc * 0.75); + + xp[1] = int(x + wid); + yp[1] = int(y - 0.500 * asc * 0.75); + + xp[2] = int(x + wid * 0.625); + yp[2] = int(y - 0.125 * asc * 0.75); + + pain.lines(xp, yp, 3, LColor::eolmarker); + + xp[0] = int(x + wid); + yp[0] = int(y - 0.500 * asc * 0.75); + + xp[1] = int(x); + yp[1] = int(y - 0.500 * asc * 0.75); + + xp[2] = int(x); + yp[2] = int(y - asc * 0.75); + + pain.lines(xp, yp, 3, LColor::eolmarker); + } + x += wid; return; } @@ -170,9 +437,10 @@ void LyXText::Draw(Row const * row, LyXParagraph::size_type & pos, switch (c) { case LyXParagraph::META_MARGIN: fs = "margin"; - // Draw a sign at the left margin! - scr.drawText(font, "!", 1, offset + row->baseline, - (LYX_PAPER_MARGIN - font.width('!'))/2); + // Draw a sign at the left margin! + owner_->painter() + .text((LYX_PAPER_MARGIN - font.width('!'))/2, + offset + row->baseline, "!", 1, font); break; case LyXParagraph::META_FIG: fs = "fig"; @@ -200,23 +468,27 @@ void LyXText::Draw(Row const * row, LyXParagraph::size_type & pos, int y = (row->baseline - font2.maxAscent() + font.maxAscent()); - font.setColor(LyXFont::INSET); + font.setColor(LColor::footnote); float tmpx = x; // draw it and set new x position - x += scr.drawString(font, fs, offset + y, int(x)); + + pain.text(int(x), offset + y, fs, font); + x += pain.width(fs, font); + pain.line(int(tmpx), offset + row->baseline, + int(x), offset + row->baseline, + LColor::footnote); - scr.drawLine(gc_foot, offset + row->baseline, - int(tmpx), int(x - tmpx)); - - pos++; + ++vpos; return; } else if (c == LyXParagraph::META_INSET) { Inset * tmpinset = row->par->GetInset(pos); - if (tmpinset) - tmpinset->Draw(font, scr, offset + row->baseline, x); - ++pos; + if (tmpinset) { + tmpinset->draw(owner_->painter(), font, + offset + row->baseline, x); + } + ++vpos; return; } @@ -233,40 +505,35 @@ void LyXText::Draw(Row const * row, LyXParagraph::size_type & pos, // So IMHO we should go with the easier and clearer implementation. // And even if 1024 is a large number here it might overflow, string // will only overflow if the machine is out of memory... + bool do_transform = (lyxrc.rtl_support && lyxrc.font_norm == "iso8859-6.8x"); + if (do_transform) + c = TransformChar(c, row->par, pos); static string textstring; textstring = c; - ++pos; + ++vpos; LyXParagraph::size_type last = RowLast(row); - while (pos <= last - && static_cast(c = row->par->GetChar(pos)) > ' ' + while (vpos <= last && + (pos = vis2log(vpos)) >= 0 + && static_cast(c = row->par->GetChar(pos)) > ' ' && font2 == GetFont(row->par, pos)) { + if (do_transform) + c = TransformChar(c, row->par, pos); textstring += c; - ++pos; + ++vpos; } float tmpx = x; - // If monochrome and LaTeX mode, provide reverse background - if (mono_video && - font.latex() == LyXFont::ON) { - int a = font.maxAscent(); - int d = font.maxDescent(); - scr.fillRectangle(gc_copy, int(tmpx), - offset + row->baseline - a, - font.textWidth(textstring.c_str(), - textstring.length()), a + d); - } - // Draw text and set the new x position - x += scr.drawText(font, textstring.c_str(), textstring.length(), - offset + row->baseline, - int(x)); + pain.text(int(x), offset + row->baseline, textstring, font); + x += pain.width(textstring, font); // 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)); + pain.line(tmpx, offset + row->baseline + 2, + x, offset + row->baseline + 2); + } // If we want ulem.sty support, drawing @@ -281,9 +548,6 @@ void LyXText::Draw(Row const * row, LyXParagraph::size_type & pos, // exactly the label-width. int LyXText::LeftMargin(Row const * row) const { - LyXFont labelfont; - LyXParagraph * newpar; - Row dummyrow; LyXLayout const & layout = textclasslist.Style(parameters->textclass, row->par->GetLayout()); @@ -315,7 +579,7 @@ int LyXText::LeftMargin(Row const * row) const if (!row->par->GetLayout()) { // find the previous same level paragraph if (row->par->FirstPhysicalPar()->Previous()) { - newpar = row->par + LyXParagraph * newpar = row->par ->DepthHook(row->par->GetDepth()); if (newpar && textclasslist.Style(parameters->textclass, @@ -327,7 +591,7 @@ int LyXText::LeftMargin(Row const * row) const } else { // find the next level paragraph - newpar = row->par->DepthHook(row->par->GetDepth()-1); + LyXParagraph * newpar = row->par->DepthHook(row->par->GetDepth()-1); // make a corresponding row. Needed to call LeftMargin() @@ -336,6 +600,7 @@ int LyXText::LeftMargin(Row const * row) const && textclasslist .Style(parameters->textclass, newpar->GetLayout()).isEnvironment()) { + Row dummyrow; dummyrow.par = newpar; dummyrow.pos = newpar->Last(); x = LeftMargin(&dummyrow); @@ -358,7 +623,7 @@ int LyXText::LeftMargin(Row const * row) const } - labelfont = GetFont(row->par, -2); + LyXFont labelfont = GetFont(row->par, -2); switch (layout.margintype) { case MARGIN_DYNAMIC: if (!layout.leftmargin.empty()) { @@ -427,7 +692,7 @@ int LyXText::LeftMargin(Row const * row) const tmprow = tmprow->previous; int minfill = tmprow->fill; - while (tmprow-> next && tmprow->next->par == row->par) { + while (tmprow->next && tmprow->next->par == row->par) { tmprow = tmprow->next; if (tmprow->fill < minfill) minfill = tmprow->fill; @@ -444,7 +709,7 @@ int LyXText::LeftMargin(Row const * row) const x += paperwidth * atoi(row->par->pextra_widthp.c_str()) / 100; } else if (!row->par->pextra_width.empty()) { - int xx = VSpace(row->par->pextra_width).inPixels(); + int xx = VSpace(row->par->pextra_width).inPixels(owner_); if (xx > paperwidth) xx = paperwidth * 80 / 100; @@ -455,7 +720,7 @@ int LyXText::LeftMargin(Row const * row) const } } - int align; + int align; // wrong type if (row->par->FirstPhysicalPar()->align == LYX_ALIGN_LAYOUT) align = layout.align; else @@ -476,17 +741,16 @@ int LyXText::LeftMargin(Row const * row) const parameters->paragraph_separation == BufferParams::PARSEP_INDENT)) x += textclasslist.TextClass(parameters->textclass) - .defaultfont().stringWidth(parindent); - else - if (layout.labeltype == LABEL_BIBLIO) { - // ale970405 Right width for bibitems - x += bibitemMaxWidth(textclasslist - .TextClass(parameters - ->textclass) - .defaultfont()); - } + .defaultfont().signedStringWidth(parindent); + else if (layout.labeltype == LABEL_BIBLIO) { + // ale970405 Right width for bibitems + x += bibitemMaxWidth(owner_->painter(), + textclasslist + .TextClass(parameters + ->textclass) + .defaultfont()); + } } - return x; } @@ -578,8 +842,8 @@ int LyXText::NumberOfCell(LyXParagraph * par, LyXParagraph::size_type tmp_pos = 0; while (tmp_pos < pos) { if (par->IsNewline(tmp_pos)) - cell++; - tmp_pos++; + ++cell; + ++tmp_pos; } return cell; } @@ -591,10 +855,10 @@ int LyXText::WidthOfCell(LyXParagraph * par, int w = 0; while (pos < par->Last() && !par->IsNewline(pos)) { w += SingleWidth(par, pos); - pos++; + ++pos; } if (par->IsNewline(pos)) - pos++; + ++pos; return w; } @@ -606,7 +870,7 @@ bool LyXText::HitInTable(Row * row, int x) const if (!row->par->table) return false; PrepareToPrint(row, tmpx, fill_separator, - fill_hfill, fill_label_hfill); + fill_hfill, fill_label_hfill, false); return (x > tmpx && x < tmpx + row->par->table->WidthOfTable()); } @@ -646,7 +910,6 @@ LyXText::NextBreakPoint(Row const * row, int width) const // position of the last possible breakpoint // -1 isn't a suitable value, but a flag LyXParagraph::size_type last_separator = -1; - int left_margin = LabelEnd(row); width -= RightMargin(row); LyXParagraph::size_type main_body = BeginningOfMainBody(par); @@ -695,7 +958,7 @@ LyXText::NextBreakPoint(Row const * row, int width) const if (pos < last-1) { last_separator = i; if (IsLineSeparatorChar(par->GetChar(i+1))) - last_separator++; + ++last_separator; } else last_separator = last; // to avoid extra rows } else @@ -712,6 +975,7 @@ LyXText::NextBreakPoint(Row const * row, int width) const x += GetFont(par, -2).stringWidth(layout.labelsep); if (par->IsLineSeparator(i - 1)) x-= SingleWidth(par, i - 1); + int left_margin = LabelEnd(row); if (x < left_margin) x = left_margin; } @@ -765,12 +1029,10 @@ int LyXText::Fill(Row const * row, int paper_width) const * this point. */ } /* table stuff -- end*/ - - int 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 (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)) @@ -792,17 +1054,27 @@ int LyXText::Fill(Row const * row, int paper_width) const LyXParagraph::size_type main_body = BeginningOfMainBody(row->par); LyXParagraph::size_type 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 (main_body > 0 && i == main_body) { + w += GetFont(row->par, -2). + stringWidth(layout.labelsep); if (row->par->IsLineSeparator(i - 1)) w -= SingleWidth(row->par, i - 1); + int left_margin = LabelEnd(row); if (w < left_margin) w = left_margin; } + w += SingleWidth(row->par, i); + ++i; + } + if (main_body > 0 && main_body > last) { + w += GetFont(row->par, -2).stringWidth(layout.labelsep); + if (last >= 0 && row->par->IsLineSeparator(last)) + w -= SingleWidth(row->par, last); + int left_margin = LabelEnd(row); + if (w < left_margin) + w = left_margin; } fill = paper_width - w - RightMargin(row); @@ -853,11 +1125,6 @@ int LyXText::LabelFill(Row const * row) const int LyXText::NumberOfSeparators(Row const * row) const { int last = RowLast(row); - //int p = row->pos; - //int main_body = BeginningOfMainBody(row->par); - //if (p < main_body) - // p = main_body; - // I think this is equivalent to the above. (Lgb) int p = max(row->pos, BeginningOfMainBody(row->par)); int n = 0; for (; p < last; ++p) { @@ -882,10 +1149,6 @@ int LyXText::NumberOfHfills(Row const * row) const ++first; } - //int main_body = BeginningOfMainBody(row->par); - //if (first < main_body) - // first = main_body; - // I think this is equivalent to the above. (Lgb) first = max(first, BeginningOfMainBody(row->par)); int n = 0; for (int p = first; p <= last; ++p) { // last, because the end is ignored! @@ -907,11 +1170,7 @@ int LyXText::NumberOfLabelHfills(Row const * row) const while(first < last && row->par->IsHfill(first)) ++first; } - //LyXParagraph::size_type main_body = - //BeginningOfMainBody(row->par); - //if (last > main_body) - //last = main_body; - // I think this is eqvialent to the above. (Lgb) + last = min(last, BeginningOfMainBody(row->par)); int n = 0; for (LyXParagraph::size_type p = first; @@ -964,7 +1223,7 @@ bool LyXText::HfillExpansion(Row const * row_ptr, void LyXText::SetHeightOfRow(Row * row_ptr) const { /* get the maximum ascent and the maximum descent */ - int asc, maxasc, desc, maxdesc, pos_end, pos, labeladdon; + int asc, desc, pos; float layoutasc = 0; float layoutdesc = 0; float tmptop = 0; @@ -987,7 +1246,8 @@ void LyXText::SetHeightOfRow(Row * row_ptr) const LyXParagraph * par = row_ptr->par->LastPhysicalPar(); LyXParagraph * firstpar = row_ptr->par->FirstPhysicalPar(); - LyXLayout const & layout = textclasslist.Style(parameters->textclass, firstpar->GetLayout()); + LyXLayout const & layout = textclasslist.Style(parameters->textclass, + firstpar->GetLayout()); LyXFont font = GetFont(par, par->Last()-1); LyXFont::FONT_SIZE size = font.size(); @@ -996,25 +1256,25 @@ void LyXText::SetHeightOfRow(Row * row_ptr) const LyXFont labelfont = GetFont(par, -2); - maxasc = int(font.maxAscent() * + int maxasc = int(font.maxAscent() * layout.spacing.getValue() * parameters->spacing.getValue()); - maxdesc = int(font.maxDescent() * + int maxdesc = int(font.maxDescent() * layout.spacing.getValue() * parameters->spacing.getValue()); - pos_end = RowLast(row_ptr); + int pos_end = RowLast(row_ptr); - labeladdon = 0; + int labeladdon = 0; // Check if any insets are larger - for (pos = row_ptr->pos; pos <= pos_end; pos++) { + for (pos = row_ptr->pos; pos <= pos_end; ++pos) { if (row_ptr->par->GetChar(pos) == LyXParagraph::META_INSET) { tmpfont = GetFont(row_ptr->par, pos); tmpinset = row_ptr->par->GetInset(pos); if (tmpinset) { - asc = tmpinset->Ascent(tmpfont); - desc = tmpinset->Descent(tmpfont); + asc = tmpinset->ascent(owner_->painter(), tmpfont); + desc = tmpinset->descent(owner_->painter(), tmpfont); if (asc > maxasc) maxasc = asc; if (desc > maxdesc) @@ -1026,7 +1286,8 @@ void LyXText::SetHeightOfRow(Row * row_ptr) const // 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); + LyXFont::FONT_SIZE maxsize = row_ptr->par->HighestFontInRange(row_ptr->pos, + pos_end); if (maxsize > font.size()) { font.setSize(maxsize); @@ -1047,8 +1308,8 @@ void LyXText::SetHeightOfRow(Row * row_ptr) const /* table stuff -- end*/ // This is nicer with box insets: - maxasc++; - maxdesc++; + ++maxasc; + ++maxdesc; row_ptr->ascent_of_text = maxasc; @@ -1061,13 +1322,13 @@ void LyXText::SetHeightOfRow(Row * row_ptr) const if (layout.isParagraph() && firstpar->GetDepth() == 0 && firstpar->Previous()) - maxasc += parameters->getDefSkip().inPixels(); + maxasc += parameters->getDefSkip().inPixels(owner_); else if (firstpar->Previous() && textclasslist.Style(parameters->textclass, firstpar->Previous()->GetLayout()).isParagraph() && firstpar->Previous()->GetDepth() == 0) // is it right to use defskip here too? (AS) - maxasc += parameters->getDefSkip().inPixels(); + maxasc += parameters->getDefSkip().inPixels(owner_); } /* the paper margins */ @@ -1076,7 +1337,7 @@ void LyXText::SetHeightOfRow(Row * row_ptr) const /* add the vertical spaces, that the user added */ if (firstpar->added_space_top.kind() != VSpace::NONE) - maxasc += int(firstpar->added_space_top.inPixels()); + maxasc += int(firstpar->added_space_top.inPixels(owner_)); /* do not forget the DTP-lines! * there height depends on the font of the nearest character */ @@ -1120,7 +1381,7 @@ void LyXText::SetHeightOfRow(Row * row_ptr) const * or between the items of a itemize or enumerate environment */ if (!firstpar->pagebreak_top) { - LyXParagraph *prev = row_ptr->par->Previous(); + LyXParagraph * prev = row_ptr->par->Previous(); if (prev) prev = row_ptr->par->DepthHook(row_ptr->par->GetDepth()); if (prev && prev->GetLayout() == firstpar->GetLayout() @@ -1173,7 +1434,7 @@ void LyXText::SetHeightOfRow(Row * row_ptr) const /* add the vertical spaces, that the user added */ if (firstpar->added_space_bottom.kind() != VSpace::NONE) - maxdesc += int(firstpar->added_space_bottom.inPixels()); + maxdesc += int(firstpar->added_space_bottom.inPixels(owner_)); /* do not forget the DTP-lines! * there height depends on the font of the nearest character */ @@ -1187,8 +1448,8 @@ void LyXText::SetHeightOfRow(Row * row_ptr) const /* 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; + LyXParagraph * nextpar = row_ptr->par->Next(); + LyXParagraph * comparepar = row_ptr->par; float usual = 0; float unusual = 0; @@ -1229,8 +1490,8 @@ void LyXText::SetHeightOfRow(Row * row_ptr) const /* calculate the new height of the text */ height -= row_ptr->height; - row_ptr->height= maxasc+maxdesc+labeladdon; - row_ptr->baseline= maxasc+labeladdon; + row_ptr->height = maxasc + maxdesc + labeladdon; + row_ptr->baseline = maxasc + labeladdon; height += row_ptr->height; } @@ -1254,7 +1515,7 @@ void LyXText::AppendParagraph(Row * row) const // Insert the new row if (z < lastposition) { - z++; + ++z; InsertRow(row, row->par, z); row = row->next; @@ -1289,7 +1550,7 @@ void LyXText::BreakAgain(Row * row) const row->height = 0; } else { row = row->next; - z++; + ++z; if (row->pos == z) not_ready = false; // the rest will not change else { @@ -1327,14 +1588,14 @@ void LyXText::BreakAgainOneRow(Row * row) if (z < row->par->Last() ) { if (!row->next || (row->next && row->next->par != row->par)) { /* insert a new row */ - z++; + ++z; InsertRow(row, row->par, z); row = row->next; row->height = 0; } else { row= row->next; - z++; + ++z; if (row->pos != z) row->pos = z; } @@ -1386,7 +1647,7 @@ void LyXText::BreakParagraph(char keep_layout) if (cursor.par->table) { int cell = NumberOfCell(cursor.par, cursor.pos); if (cursor.par->table->ShouldBeVeryLastCell(cell)) - SetCursor(cursor.par, cursor.par->text.size()); + SetCursor(cursor.par, cursor.par->size()); } /* table stuff -- end */ @@ -1485,10 +1746,11 @@ void LyXText::OpenFootnote() /* 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++); + 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)->text.size()); + cursor.pos + cursor.par->ParFromPos(cursor.pos)->size()); /* the cursor must be exactly before the footnote */ par = cursor.par->ParFromPos(cursor.pos); @@ -1506,6 +1768,7 @@ void LyXText::OpenFootnote() /* set the dimensions of the cursor row */ row->fill = Fill(row, paperwidth); SetHeightOfRow(row); +#warning See comment on top of text.C tmppar = tmppar->Next(); while (tmppar != endpar) { @@ -1592,37 +1855,41 @@ void LyXText::TableFeatures(int feature) const !cursor.par->table->IsContRow(cell)) { while (pos < cursor.par->Last() && !cursor.par->IsNewline(pos)) - pos++; + ++pos; if (pos < cursor.par->Last()) - pos++; - cell++; + ++pos; + ++cell; } while((pos < cursor.par->Last()) && cursor.par->table->IsContRow(cell)) { while (pos < cursor.par->Last() && !cursor.par->IsNewline(pos)) - pos++; + ++pos; if (pos < cursor.par->Last()) - pos++; - cell++; + ++pos; + ++cell; } cell_org = --cell; if (pos < cursor.par->Last()) - pos--; + --pos; } while (pos < cursor.par->Last() && (cell == cell_org || !cursor.par->table->IsFirstCell(cell))){ while (pos < cursor.par->Last() && !cursor.par->IsNewline(pos)) - pos++; + ++pos; if (pos < cursor.par->Last()) - pos++; - cell++; + ++pos; + ++cell; } /* insert the new cells */ int number = cursor.par->table->NumberOfCellsInRow(cell_org); - for (int i = 0; i < number; ++i) + Language const * lang = cursor.par->getParLanguage(); + LyXFont font(LyXFont::ALL_INHERIT,lang); + for (int i = 0; i < number; ++i) { cursor.par->InsertChar(pos, LyXParagraph::META_NEWLINE); + cursor.par->SetFont(pos, font); + } /* append the row into the table */ cursor.par->table->AppendRow(cell_org); @@ -1648,18 +1915,21 @@ void LyXText::TableFeatures(int feature) const (cell == cell_org || !cursor.par->table->IsFirstCell(cell))){ while (pos < cursor.par->Last() && !cursor.par->IsNewline(pos)) - pos++; + ++pos; if (pos < cursor.par->Last()) - pos++; - cell++; + ++pos; + ++cell; } /* insert the new cells */ int number = cursor.par->table->NumberOfCellsInRow(cell_org); - int i; - for (i= 0; igetParLanguage(); + LyXFont font(LyXFont::ALL_INHERIT,lang); + for (int i = 0; i < number; ++i) { cursor.par->InsertChar(pos, LyXParagraph::META_NEWLINE); - + cursor.par->SetFont(pos, font); + } + /* append the row into the table */ cursor.par->table->AppendContRow(cell_org); RedoParagraph(); @@ -1669,10 +1939,13 @@ void LyXText::TableFeatures(int feature) const LyXParagraph::size_type pos = 0; int cell_org = actCell; int cell = 0; + Language const * lang = cursor.par->getParLanguage(); + LyXFont font(LyXFont::ALL_INHERIT,lang); do{ if (pos && (cursor.par->IsNewline(pos-1))){ - if (cursor.par->table->AppendCellAfterCell(cell_org, cell)){ + if (cursor.par->table->AppendCellAfterCell(cell_org, cell)) { cursor.par->InsertChar(pos, LyXParagraph::META_NEWLINE); + cursor.par->SetFont(pos, font); if (pos <= cursor.pos) cursor.pos++; ++pos; @@ -1682,9 +1955,12 @@ void LyXText::TableFeatures(int feature) const ++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(), LyXParagraph::META_NEWLINE); + This saves one byte memory per table ;-) */ + if (cursor.par->table->AppendCellAfterCell(cell_org, cell)) { + LyXParagraph::size_type last = cursor.par->Last(); + cursor.par->InsertChar(last, LyXParagraph::META_NEWLINE); + cursor.par->SetFont(last, font); + } /* append the column into the table */ cursor.par->table->AppendColumn(cell_org); @@ -1693,8 +1969,8 @@ void LyXText::TableFeatures(int feature) const return; } case LyXTable::DELETE_ROW: - if (current_view->the_locking_inset) - current_view->unlockInset(current_view->the_locking_inset); + if (owner_->the_locking_inset) + owner_->unlockInset(owner_->the_locking_inset); RemoveTableRow(&cursor); RedoParagraph(); return; @@ -1703,8 +1979,8 @@ void LyXText::TableFeatures(int feature) const LyXParagraph::size_type pos = 0; int cell_org = actCell; int cell = 0; - if (current_view->the_locking_inset) - current_view->unlockInset(current_view->the_locking_inset); + if (owner_->the_locking_inset) + owner_->unlockInset(owner_->the_locking_inset); do { if (!pos || (cursor.par->IsNewline(pos-1))){ if (cursor.par->table->DeleteCellIfColumnIsDeleted(cell, cell_org)){ @@ -1786,9 +2062,9 @@ void LyXText::TableFeatures(int feature) const if (!selection){ cursor.par->table->SetRightLine(actCell, lineSet); } else { - LyXParagraph::size_type i; int n = -1, m = -2; - for (i= sel_start_cursor.pos; i<= sel_end_cursor.pos; i++){ + LyXParagraph::size_type i = sel_start_cursor.pos; + for (; i <= sel_end_cursor.pos; ++i) { if ((n= NumberOfCell(sel_start_cursor.par, i)) != m) { cursor.par->table->SetRightLine(n, lineSet); m = n; @@ -1804,9 +2080,9 @@ void LyXText::TableFeatures(int feature) const if (!selection){ cursor.par->table->SetAlignment(actCell, setAlign); } else { - LyXParagraph::size_type i; int n = -1, m = -2; - for (i= sel_start_cursor.pos; i<= sel_end_cursor.pos; i++){ + LyXParagraph::size_type i = sel_start_cursor.pos; + for (; i <= sel_end_cursor.pos; ++i) { if ((n= NumberOfCell(sel_start_cursor.par, i)) != m) { cursor.par->table->SetAlignment(n, setAlign); m = n; @@ -1824,7 +2100,7 @@ void LyXText::TableFeatures(int feature) const // dummy-paragraph !! // not necessar anymore with UNDO :) for (LyXParagraph::size_type i = - cursor.par->text.size() - 1; i >= 0; --i) + cursor.par->size() - 1; i >= 0; --i) cursor.par->Erase(i); RedoParagraph(); return; @@ -1842,8 +2118,8 @@ void LyXText::TableFeatures(int feature) const int newlines = cursor.par->table->UnsetMultiColumn(actCell); LyXParagraph::size_type pos = cursor.pos; while (pos < cursor.par->Last() && !cursor.par->IsNewline(pos)) - pos++; - for (;newlines;newlines--) + ++pos; + for (; newlines; --newlines) cursor.par->InsertChar(pos, LyXParagraph::META_NEWLINE); RedoParagraph(); return; @@ -1873,9 +2149,9 @@ void LyXText::TableFeatures(int feature) const sel_start_cursor.par->InsertChar(i, ' '); else { sel_end_cursor.pos--; - i--; + --i; } - number++; + ++number; } } cursor.par->table-> @@ -1944,9 +2220,9 @@ void LyXText::TableFeatures(int feature) const if (!selection){ cursor.par->table->SetRotateCell(actCell, false); } else { - LyXParagraph::size_type i; int n = -1, m = -2; - for (i= sel_start_cursor.pos; i<= sel_end_cursor.pos; i++){ + LyXParagraph::size_type i = sel_start_cursor.pos; + for (; i <= sel_end_cursor.pos; ++i) { if ((n= NumberOfCell(sel_start_cursor.par, i)) != m) { cursor.par->table->SetRotateCell(n, false); m = n; @@ -2016,16 +2292,17 @@ void LyXText::InsertCharInTable(char c) jumped_over_space = false; if (IsLineSeparatorChar(c)) { - + +#ifndef FIX_DOUBLE_SPACE /* 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->IsLineSeparator(cursor.pos)) { cursor.par->Erase(cursor.pos); jumped_over_space = true; - } - else if ((cursor.pos > 0 && + } else +#endif + if ((cursor.pos > 0 && cursor.par->IsLineSeparator(cursor.pos - 1)) || (cursor.pos > 0 && cursor.par->IsNewline(cursor.pos - 1)) || (cursor.pos == 0 && @@ -2033,8 +2310,7 @@ void LyXText::InsertCharInTable(char c) && cursor.par->Previous()->footnoteflag == LyXParagraph::OPEN_FOOTNOTE))) return; - } - else if (IsNewlineChar(c)) { + } else if (IsNewlineChar(c)) { if (!IsEmptyTableCell()) { TableFeatures(LyXTable::APPEND_CONT_ROW); CursorDown(); @@ -2090,7 +2366,7 @@ void LyXText::CheckParagraphInTable(LyXParagraph * par, LyXParagraph::size_type tmp_pos = pos; /* update the table information */ while (tmp_pos && !par->IsNewline(tmp_pos - 1)) - tmp_pos--; + --tmp_pos; if (par->table->SetWidthOfCell(NumberOfCell(par, pos), WidthOfCell(par, tmp_pos))) { LyXCursor tmpcursor = cursor; @@ -2103,6 +2379,7 @@ void LyXText::CheckParagraphInTable(LyXParagraph * par, /* redraw only the row */ LyXCursor tmpcursor = cursor; SetCursorIntern(par, pos); +#warning See comment on top of text.C refresh_y = y; refresh_x = cursor.x; refresh_row = row; @@ -2134,13 +2411,12 @@ void LyXText::BackspaceInTable() /* no pasting of table paragraphs */ CursorLeft(); - } - else { + } 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); + SetUndo(Undo::DELETE, + cursor.par->ParFromPos(cursor.pos)->previous, + cursor.par->ParFromPos(cursor.pos)->next); CursorLeftIntern(); @@ -2167,7 +2443,8 @@ void LyXText::BackspaceInTable() tmprow = tmprow->next; tmprow->pos--; } - + +#ifndef FIX_DOUBLE_SPACE /* delete superfluous blanks */ if (cursor.pos < cursor.par->Last() - 1 && (cursor.par->IsLineSeparator(cursor.pos))) { @@ -2187,6 +2464,7 @@ void LyXText::BackspaceInTable() cursor.pos--; } } +#endif } CheckParagraphInTable(cursor.par, cursor.pos); @@ -2227,22 +2505,19 @@ void LyXText::RedoParagraph() const /* insert a character, moves all the following breaks in the * same Paragraph one to the right and make a rebreak */ -void LyXText::InsertChar(char c) +void LyXText::InsertChar(char c) { SetUndo(Undo::INSERT, cursor.par->ParFromPos(cursor.pos)->previous, cursor.par->ParFromPos(cursor.pos)->next); /* When the free-spacing option is set for the current layout, - * all spaces are converted to protected spaces. */ - bool freeSpacingBo = + * disable the double-space checking */ + + bool freeSpacing = textclasslist.Style(parameters->textclass, cursor.row->par->GetLayout()).free_spacing; - - if (freeSpacingBo && IsLineSeparatorChar(c) - && (!cursor.pos || cursor.par->IsLineSeparator(cursor.pos - 1))) - c = LyXParagraph::META_PROTECTED_SEPARATOR; - + /* table stuff -- begin*/ if (cursor.par->table) { InsertCharInTable(c); @@ -2277,7 +2552,7 @@ void LyXText::InsertChar(char c) bool jumped_over_space = false; - if (IsLineSeparatorChar(c)) { + if (!freeSpacing && IsLineSeparatorChar(c)) { #ifndef FIX_DOUBLE_SPACE if (cursor.pos < lastpos && cursor.par->IsLineSeparator(cursor.pos)) { @@ -2288,7 +2563,7 @@ void LyXText::InsertChar(char c) * blank at the end of a row we have to force * a rebreak.*/ - current_view->owner()->getMiniBuffer() + owner_->owner()->getMiniBuffer() ->Set(_("You cannot type two spaces this way. " " Please read the Tutorial.")); #if 1 @@ -2315,9 +2590,9 @@ void LyXText::InsertChar(char c) && cursor.par->Previous()->footnoteflag == LyXParagraph::OPEN_FOOTNOTE))) { if (cursor.pos == 0 ) - current_view->owner()->getMiniBuffer()->Set(_("You cannot insert a space at the beginning of a paragraph. Please read the Tutorial.")); + owner_->owner()->getMiniBuffer()->Set(_("You cannot insert a space at the beginning of a paragraph. Please read the Tutorial.")); else - current_view->owner()->getMiniBuffer()->Set(_("You cannot type two spaces this way. Please read the Tutorial.")); + owner_->owner()->getMiniBuffer()->Set(_("You cannot type two spaces this way. Please read the Tutorial.")); charInserted(); return; } @@ -2381,16 +2656,16 @@ void LyXText::InsertChar(char c) status = LyXText::NEED_MORE_REFRESH; BreakAgainOneRow(row); - SetCursor(cursor.par, cursor.pos + 1); + + current_font = rawtmpfont; + real_current_font = realtmpfont; + SetCursor(cursor.par, cursor.pos + 1, false); /* cursor MUST be in row now */ if (row->next && row->next->par == row->par) need_break_row = row->next; else need_break_row = 0; - - current_font = rawtmpfont; - real_current_font = realtmpfont; // check, wether the last characters font has changed. if (cursor.pos && cursor.pos == cursor.par->Last() @@ -2422,14 +2697,13 @@ void LyXText::InsertChar(char c) row = row->next; BreakAgainOneRow(row); } - SetCursor(cursor.par, cursor.pos + 1); + current_font = rawtmpfont; + real_current_font = realtmpfont; + SetCursor(cursor.par, cursor.pos + 1, false); if (row->next && row->next->par == row->par) need_break_row = row->next; else - need_break_row = 0; - - current_font = rawtmpfont; - real_current_font = realtmpfont; + need_break_row = 0; } else { refresh_y = y; refresh_x = cursor.x; @@ -2443,9 +2717,9 @@ void LyXText::InsertChar(char c) else status = LyXText::NEED_MORE_REFRESH; - SetCursor(cursor.par, cursor.pos + 1); current_font = rawtmpfont; real_current_font = realtmpfont; + SetCursor(cursor.par, cursor.pos + 1, false); } /* check, wether the last characters font has changed. */ @@ -2478,11 +2752,11 @@ void LyXText::charInserted() } } - void LyXText::PrepareToPrint(Row * row, float & x, float & fill_separator, float & fill_hfill, - float & fill_label_hfill) const + float & fill_label_hfill, + bool bidi) const { float nh, nlh, ns; @@ -2491,8 +2765,19 @@ void LyXText::PrepareToPrint(Row * row, float & x, fill_label_hfill = 0; fill_separator = 0; fill_label_hfill = 0; - - x = LeftMargin(row); + + LyXDirection direction = row->par->getParDirection(); + + if (direction == LYX_DIR_RIGHT_TO_LEFT) { + x = RightMargin(row); + if (row->par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE) { + LyXFont font(LyXFont::ALL_SANE); + font.setSize(LyXFont::SIZE_SMALL); + x += font.textWidth("Mwide-figM", 10); + } + } + else + x = LeftMargin(row); /* is there a manual margin with a manual label */ if (textclasslist.Style(parameters->textclass, @@ -2523,11 +2808,11 @@ void LyXText::PrepareToPrint(Row * row, float & x, else { /* is it block, flushleft or flushright? * set x how you need it */ - int align; - if (row->par->FirstPhysicalPar()->align == LYX_ALIGN_LAYOUT) - align = textclasslist.Style(parameters->textclass, row->par->GetLayout()).align; - else - align = row->par->FirstPhysicalPar()->align; + int align; + if (row->par->FirstPhysicalPar()->align == LYX_ALIGN_LAYOUT) + align = textclasslist.Style(parameters->textclass, row->par->GetLayout()).align; + else + align = row->par->FirstPhysicalPar()->align; /* center displayed insets */ if (row->par->GetChar(row->pos) == LyXParagraph::META_INSET @@ -2545,6 +2830,8 @@ void LyXText::PrepareToPrint(Row * row, float & x, && row->next->par->GetInset(row->next->pos)->display()) ) fill_separator = w / ns; + else if (direction == LYX_DIR_RIGHT_TO_LEFT) + x += w; break; case LYX_ALIGN_RIGHT: x += w; @@ -2554,8 +2841,32 @@ void LyXText::PrepareToPrint(Row * row, float & x, break; } } - } + if (!bidi) + return; + ComputeBidiTables(row); + if (direction == LYX_DIR_RIGHT_TO_LEFT) { + LyXParagraph::size_type main_body = + BeginningOfMainBody(row->par); + LyXParagraph::size_type last = RowLast(row); + + if (row->pos <= last + && !row->par->table + && last != vis2log(last) + && row->par->IsLineSeparator(last)) { + if (!(main_body > 0 && main_body-1 == last)) + x -= fill_separator+SingleWidth(row->par,last); + } else if (main_body > 0 && + (main_body-1 > last || + !row->par->IsLineSeparator(main_body-1))) { + LyXLayout const & layout = textclasslist.Style(parameters->textclass, + row->par->GetLayout()); + x += GetFont(row->par, -2).stringWidth(layout.labelsep); + if (main_body-1 <= last) + x += fill_label_hfill; + } + } +} /* important for the screen */ @@ -2568,6 +2879,7 @@ void LyXText::CursorRightOneWord() const { // treat floats, HFills and Insets as words LyXCursor tmpcursor = cursor; +#warning See comment on top of text.C if (tmpcursor.pos == tmpcursor.par->Last() && tmpcursor.par->Next()) @@ -2583,7 +2895,7 @@ void LyXText::CursorRightOneWord() const { // printf("Current pos1 %d", tmpcursor.pos) ; tmpcursor.pos++; - steps++; + ++steps; } // Advance through word. while ( tmpcursor.pos < tmpcursor.par->Last() && @@ -2591,7 +2903,7 @@ void LyXText::CursorRightOneWord() const { // printf("Current pos2 %d", tmpcursor.pos) ; tmpcursor.pos++; - steps++; + ++steps; } } SetCursor(tmpcursor.par, tmpcursor.pos); @@ -2762,18 +3074,29 @@ char * LyXText::SelectNextWord(float & value) /* Start the selection from here */ sel_cursor = cursor; - string latex; - +#ifdef HAVE_SSTREAM + ostringstream latex; +#else + ostrstream latex; +#endif /* and find the end of the word (optional hyphens are part of a word) */ while (cursor.pos < cursor.par->Last() && (cursor.par->IsLetter(cursor.pos)) - || (cursor.par->GetChar(cursor.pos) == LyXParagraph::META_INSET && - cursor.par->GetInset(cursor.pos) != 0 && - cursor.par->GetInset(cursor.pos)->Latex(latex, 0) == 0 && - latex == "\\-")) + || (cursor.par->GetChar(cursor.pos) == LyXParagraph::META_INSET + && cursor.par->GetInset(cursor.pos) != 0 + && cursor.par->GetInset(cursor.pos)->Latex(latex, 0, false) == 0 +#ifdef HAVE_SSTREAM + && latex.str() == "\\-" +#else + && string(latex.str(), 3) == "\\-" // this is not nice at all +#endif + )) cursor.pos++; +#ifndef HAVE_SSTREAM + delete [] latex.str(); +#endif // Finally, we copy the word to a string and return it char * str = 0; @@ -2799,17 +3122,29 @@ void LyXText::SelectSelectedWord() /* set the sel cursor */ sel_cursor = cursor; - string latex; +#ifdef HAVE_SSTREAM + ostringstream latex; +#else + ostrstream latex; +#endif /* now find the end of the word */ while (cursor.pos < cursor.par->Last() && (cursor.par->IsLetter(cursor.pos) - || (cursor.par->GetChar(cursor.pos) == LyXParagraph::META_INSET && - cursor.par->GetInset(cursor.pos) != 0 && - cursor.par->GetInset(cursor.pos)->Latex(latex, 0) == 0 && - latex == "\\-"))) + || (cursor.par->GetChar(cursor.pos) == LyXParagraph::META_INSET + && cursor.par->GetInset(cursor.pos) != 0 + && cursor.par->GetInset(cursor.pos)->Latex(latex, 0, false) == 0 +#ifdef HAVE_SSTREAM + && latex.str() == "\\-" +#else + && string(latex.str(), 3) == "\\-" +#endif + ))) cursor.pos++; +#ifndef HAVE_SSTREAM + delete [] latex.str(); +#endif SetCursor(cursor.par, cursor.pos); /* finally set the selection */ @@ -2824,6 +3159,7 @@ void LyXText::DeleteWordForward() if (!cursor.par->Last()) CursorRight(); +#warning See comment on top of text.C else { /* -------> Skip initial non-word stuff. */ while ( cursor.pos < cursor.par->Last() @@ -2850,6 +3186,7 @@ void LyXText::DeleteWordBackward() LyXCursor tmpcursor = cursor; if (!cursor.par->Last()) CursorLeft(); +#warning See comment on top of text.C else{ selection = true; // to avoid deletion CursorLeftOneWord(); @@ -2867,6 +3204,7 @@ void LyXText::DeleteLineForward() LyXCursor tmpcursor = cursor; if (!cursor.par->Last()) CursorRight(); +#warning See comment on top of text.C else { CursorEnd(); sel_cursor = cursor; @@ -2901,7 +3239,8 @@ void LyXText::ChangeWordCase(LyXText::TextCase action) LyXParagraph::size_type tmppos = cursor.par->PositionInParFromPos(cursor.pos); while (tmppos < tmppar->size()) { - unsigned char c = tmppar->text[tmppos]; + //unsigned char c = tmppar->text[tmppos]; + unsigned char c = tmppar->GetChar(tmppos); if (IsKommaChar(c) || IsLineSeparatorChar(c)) break; if (c != LyXParagraph::META_INSET) { @@ -2919,7 +3258,8 @@ void LyXText::ChangeWordCase(LyXText::TextCase action) } } - tmppar->text[tmppos] = c; + //tmppar->text[tmppos] = c; + tmppar->SetChar(tmppos, c); ++tmppos; } CheckParagraph(tmppar, tmppos); @@ -2932,14 +3272,29 @@ void LyXText::Delete() // this is a very easy implementation LyXCursor old_cursor = cursor; + int old_cur_par_id = old_cursor.par->id(); + int old_cur_par_prev_id = old_cursor.par->previous ? + old_cursor.par->previous->id() : 0; // just move to the right CursorRightIntern(); - + +#warning Look at the comment here. + // This check is not very good... + // The CursorRightIntern calls DeleteEmptyParagrapgMechanism + // and that can very well delete the par or par->previous in + // old_cursor. Will a solution where we compare paragraph id's + //work better? +#if 1 + if ((cursor.par->previous ? cursor.par->previous->id() : 0) + == old_cur_par_prev_id + && cursor.par->id() != old_cur_par_id) + return; // delete-empty-paragraph-mechanism has done it +#else if (cursor.par->previous == old_cursor.par->previous && cursor.par != old_cursor.par) - return; // delete-emty-paragraph-mechanism has done it - + return; // delete-empty-paragraph-mechanism has done it +#endif // if you had success make a backspace if (old_cursor.par != cursor.par || old_cursor.pos != cursor.pos) { LyXCursor tmpcursor = cursor; @@ -2953,13 +3308,10 @@ void LyXText::Delete() } -void LyXText::Backspace() +void LyXText::Backspace() { - LyXParagraph * tmppar; - Row * tmprow, * row; - long y; - int tmpheight; - + DebugTracer trc1("LyXText::Backspace"); + /* table stuff -- begin */ if (cursor.par->table) { BackspaceInTable(); @@ -2975,6 +3327,11 @@ void LyXText::Backspace() LyXFont rawparfont = cursor.par->GetFontSettings(lastpos - 1); if (cursor.pos == 0) { + DebugTracer trc("LyXText::Backspace cursor.pos == 0"); + + // The cursor is at the beginning of a paragraph, so the the backspace + // will collapse two paragraphs into one. + // we may paste some paragraphs // is it an empty paragraph? @@ -2982,17 +3339,19 @@ void LyXText::Backspace() if ((lastpos == 0 || (lastpos == 1 && cursor.par->IsSeparator(0))) && !(cursor.par->Next() - && cursor.par->footnoteflag == - LyXParagraph::NO_FOOTNOTE - && cursor.par->Next()->footnoteflag == - LyXParagraph::OPEN_FOOTNOTE)) { + && cursor.par->footnoteflag == LyXParagraph::NO_FOOTNOTE + && cursor.par->Next()->footnoteflag == LyXParagraph::OPEN_FOOTNOTE)) { + // This is an empty paragraph and we delete it just by moving the curosr one step + // left and let the DeleteEmptyParagraphMechanism handle the actual deleteion + // of the paragraph. if (cursor.par->previous) { - tmppar = cursor.par->previous->FirstPhysicalPar(); + LyXParagraph * tmppar = cursor.par->previous->FirstPhysicalPar(); if (cursor.par->GetLayout() == tmppar->GetLayout() && cursor.par->footnoteflag == tmppar->footnoteflag && cursor.par->GetAlign() == tmppar->GetAlign()) { - + // Inherit botom DTD from the paragraph below. + // (the one we are deleting) tmppar->line_bottom = cursor.par->line_bottom; tmppar->added_space_bottom = cursor.par->added_space_bottom; tmppar->pagebreak_bottom = cursor.par->pagebreak_bottom; @@ -3001,7 +3360,7 @@ void LyXText::Backspace() CursorLeftIntern(); // the layout things can change the height of a row ! - tmpheight = cursor.row->height; + int tmpheight = cursor.row->height; SetHeightOfRow(cursor.row); if (cursor.row->height != tmpheight) { refresh_y = cursor.y - cursor.row->baseline; @@ -3011,14 +3370,17 @@ void LyXText::Backspace() return; } } + if (cursor.par->ParFromPos(cursor.pos)->previous){ SetUndo(Undo::DELETE, cursor.par->ParFromPos(cursor.pos)->previous->previous, cursor.par->ParFromPos(cursor.pos)->next); } - tmppar = cursor.par; - tmprow = cursor.row; + + LyXParagraph * tmppar = cursor.par; + Row * tmprow = cursor.row; CursorLeftIntern(); +#warning See comment on top of text.C /* Pasting is not allowed, if the paragraphs have different layout. I think it is a real bug of all other word processors to allow it. It confuses the user. @@ -3031,18 +3393,22 @@ void LyXText::Backspace() */ if (cursor.par != tmppar && (cursor.par->GetLayout() == tmppar->GetLayout() - || !tmppar->GetLayout()) + || tmppar->GetLayout() == 0 /*standard*/) && cursor.par->footnoteflag == tmppar->footnoteflag /* table stuff -- begin*/ && !cursor.par->table /* no pasting of tables */ /* table stuff -- end*/ && cursor.par->GetAlign() == tmppar->GetAlign()) { - + + RemoveParagraph(tmprow); + RemoveRow(tmprow); cursor.par->PasteParagraph(); - if (!(cursor.pos && - cursor.par->IsSeparator(cursor.pos - 1))) - cursor.par->InsertChar(cursor.pos, ' '); + if (!cursor.pos || !cursor.par->IsSeparator(cursor.pos - 1)) + ; //cursor.par->InsertChar(cursor.pos, ' '); + // strangely enough it seems that commenting out the line above removes + // most or all of the segfaults. I will however also try to move the + // two Remove... lines in front of the PasteParagraph too. else if (cursor.pos) cursor.pos--; @@ -3052,16 +3418,22 @@ void LyXText::Backspace() refresh_y = cursor.y - cursor.row->baseline; // remove the lost paragraph - RemoveParagraph(tmprow); - RemoveRow(tmprow); + // This one is not safe, since the paragraph that the tmprow and the + // following rows belong to has been deleted by the PasteParagraph + // above. The question is... could this be moved in front of the + // PasteParagraph? + //RemoveParagraph(tmprow); + //RemoveRow(tmprow); - AppendParagraph(cursor.row); + AppendParagraph(cursor.row); // This rebuilds the rows. UpdateCounters(cursor.row); // the row may have changed, block, hfills etc. SetCursor(cursor.par, cursor.pos); } } else { + DebugTracer trc("LyXText::Backspace normal backspace"); + /* this is the code for a normal backspace, not pasting * any paragraphs */ SetUndo(Undo::DELETE, @@ -3082,8 +3454,8 @@ void LyXText::Backspace() } } - row = cursor.row; - y = cursor.y - row->baseline; + Row * row = cursor.row; + long y = cursor.y - row->baseline; LyXParagraph::size_type z; /* remember that a space at the end of a row doesnt count * when calculating the fill */ @@ -3097,7 +3469,7 @@ void LyXText::Backspace() if (cursor.pos && cursor.par->IsNewline(cursor.pos)) { cursor.par->Erase(cursor.pos); // refresh the positions - tmprow = row; + Row * tmprow = row; while (tmprow->next && tmprow->next->par == row->par) { tmprow = tmprow->next; tmprow->pos--; @@ -3118,7 +3490,7 @@ void LyXText::Backspace() cursor.par->Erase(cursor.pos); // refresh the positions - tmprow = row; + Row * tmprow = row; while (tmprow->next && tmprow->next->par == row->par) { tmprow = tmprow->next; tmprow->pos--; @@ -3167,7 +3539,7 @@ void LyXText::Backspace() if ( z >= row->pos) { row->pos = z + 1; - tmprow = row->previous; + Row * tmprow = row->previous; // maybe the current row is now empty if (row->pos >= row->par->Last()) { @@ -3190,9 +3562,9 @@ void LyXText::Backspace() refresh_y = y; refresh_row = tmprow; status = LyXText::NEED_MORE_REFRESH; - SetCursor(cursor.par, cursor.pos); current_font = rawtmpfont; real_current_font = realtmpfont; + SetCursor(cursor.par, cursor.pos, false); // check, whether the last character's font has changed. rawtmpfont = cursor.par->GetFontSettings(cursor.par->Last() - 1); if (rawparfont != rawtmpfont) @@ -3221,8 +3593,9 @@ void LyXText::Backspace() status = LyXText::NEED_MORE_REFRESH; BreakAgainOneRow(row); - - SetCursor(cursor.par, cursor.pos); + current_font = rawtmpfont; + real_current_font = realtmpfont; + SetCursor(cursor.par, cursor.pos, false); // cursor MUST be in row now if (row->next && row->next->par == row->par) @@ -3240,10 +3613,13 @@ void LyXText::Backspace() status = LyXText::NEED_MORE_REFRESH; refresh_y = y; refresh_row = row; - SetCursor(cursor.par, cursor.pos); + current_font = rawtmpfont; + real_current_font = realtmpfont; + SetCursor(cursor.par, cursor.pos, false); } } - + DebugTracer trc2("LyXText::Backspace wrap up"); + // restore the current font // That is what a user expects! current_font = rawtmpfont; @@ -3263,63 +3639,84 @@ void LyXText::Backspace() } -void LyXText::GetVisibleRow(LyXScreen & scr, int offset, +void LyXText::GetVisibleRow(int offset, Row * row_ptr, long y) { /* returns a printed row */ - LyXParagraph::size_type pos, pos_end; + Painter & pain = owner_->painter(); + + LyXDirection direction = row_ptr->par->getParDirection(); + LyXParagraph::size_type vpos, pos, pos_end; float x, tmpx; int y_top, y_bottom; float fill_separator, fill_hfill, fill_label_hfill; LyXParagraph * par, * firstpar; - int left_margin; LyXFont font; int maxdesc; if (row_ptr->height <= 0) { lyxerr << "LYX_ERROR: row.height: " << row_ptr->height << endl; return; } - left_margin = LabelEnd(row_ptr); PrepareToPrint(row_ptr, x, fill_separator, fill_hfill, fill_label_hfill); - - LyXParagraph::size_type main_body = - BeginningOfMainBody(row_ptr->par); + /* initialize the pixmap */ - scr.fillRectangle(gc_clear, - 0, offset, paperwidth, row_ptr->height); - // check for NOT FAST SELECTION - if (!fast_selection && !mono_video && selection) { + pain.fillRectangle(0, offset, paperwidth, row_ptr->height); + + if (selection) { /* selection code */ if (sel_start_cursor.row == row_ptr && sel_end_cursor.row == row_ptr) { - scr.fillRectangle(gc_selection, sel_start_cursor.x, - offset, - sel_end_cursor.x - - sel_start_cursor.x, - row_ptr->height); - } - else if (sel_start_cursor.row == row_ptr) { - scr.fillRectangle(gc_selection, sel_start_cursor.x, - offset, - paperwidth - sel_start_cursor.x, - row_ptr->height); + if (sel_start_cursor.x < sel_end_cursor.x) + pain.fillRectangle(sel_start_cursor.x, offset, + sel_end_cursor.x - sel_start_cursor.x, + row_ptr->height, + LColor::selection); + else + pain.fillRectangle(sel_end_cursor.x, offset, + sel_start_cursor.x - sel_end_cursor.x, + row_ptr->height, + LColor::selection); + } else if (sel_start_cursor.row == row_ptr) { + if (direction == LYX_DIR_LEFT_TO_RIGHT) + pain.fillRectangle(sel_start_cursor.x, offset, + paperwidth - sel_start_cursor.x, + row_ptr->height, + LColor::selection); + else + pain.fillRectangle(0, offset, + sel_start_cursor.x, + row_ptr->height, + LColor::selection); } else if (sel_end_cursor.row == row_ptr) { - scr.fillRectangle(gc_selection, 0, offset, - sel_end_cursor.x, row_ptr->height); - } else if (y > sel_start_cursor.y && y < sel_end_cursor.y) { - scr.fillRectangle(gc_selection, 0, offset, - paperwidth, row_ptr->height); + if (direction == LYX_DIR_LEFT_TO_RIGHT) + pain.fillRectangle(0, offset, + sel_end_cursor.x, + row_ptr->height, + LColor::selection); + else + pain.fillRectangle(sel_end_cursor.x, offset, + paperwidth - sel_end_cursor.x, + row_ptr->height, + LColor::selection); + } else if (y > sel_start_cursor.y && y < sel_end_cursor.y) { + pain.fillRectangle(0, offset, + paperwidth, row_ptr->height, + LColor::selection); } - } // end of NOT FAST SELECTION code + } if (row_ptr->par->appendix){ - scr.drawVerticalLine(gc_math, 1, offset, offset+row_ptr->height); - scr.drawVerticalLine(gc_math, paperwidth-2 , offset, offset+row_ptr->height); + pain.line(1, offset, + 1, offset + row_ptr->height, + LColor::appendixline); + pain.line(paperwidth - 2, offset, + paperwidth - 2, offset + row_ptr->height, + LColor::appendixline); } - + if (row_ptr->par->pextra_type == LyXParagraph::PEXTRA_MINIPAGE) { /* draw a marker at the left margin! */ LyXFont font = GetFont(row_ptr->par, 0); @@ -3327,13 +3724,12 @@ void LyXText::GetVisibleRow(LyXScreen & scr, int offset, int x = (LYX_PAPER_MARGIN - font.width('|')) / 2; int y1 = (offset + row_ptr->baseline); int y2 = (offset + row_ptr->baseline) - asc; - - scr.drawVerticalLine(gc_minipage, x, y1, y2); + pain.line(x, y1, x, y2, LColor::minipageline); } if (row_ptr->par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE) { LyXFont font(LyXFont::ALL_SANE); font.setSize(LyXFont::SIZE_FOOTNOTE); - font.setColor(LyXFont::RED); + font.setColor(LColor::footnote); int box_x = LYX_PAPER_MARGIN; box_x += font.textWidth(" wide-tab ", 10); @@ -3364,67 +3760,64 @@ void LyXText::GetVisibleRow(LyXScreen & scr, int offset, break; } - // Determine background color. - gc_type back = gc_lighted; - if (mono_video) { - back = gc_clear; - } - scr.fillRectangle(back, LYX_PAPER_MARGIN, offset+1, - box_x - LYX_PAPER_MARGIN, - int(font.maxAscent())+ - int(font.maxDescent())); + pain.fillRectangle(LYX_PAPER_MARGIN, + offset + 1, + box_x - LYX_PAPER_MARGIN, + int(font.maxAscent() + + font.maxDescent()), + LColor::footnotebg); + + pain.line(LYX_PAPER_MARGIN, offset, + paperwidth - LYX_PAPER_MARGIN, offset, + LColor::footnoteframe); + + pain.text(LYX_PAPER_MARGIN, + offset + int(font.maxAscent()) + 1, + fs, font); - scr.drawLine(gc_foot, - offset, - LYX_PAPER_MARGIN, - paperwidth - 2*LYX_PAPER_MARGIN); + pain.line(LYX_PAPER_MARGIN, offset, + LYX_PAPER_MARGIN, + offset + int(font.maxAscent() + + font.maxDescent()), + LColor::footnoteframe); - scr.drawString(font, fs, - offset + int(font.maxAscent())+1, - LYX_PAPER_MARGIN); - scr.drawVerticalLine(gc_foot, - LYX_PAPER_MARGIN, - offset, - offset - + int(font.maxAscent())+ - int(font.maxDescent())); + pain.line(LYX_PAPER_MARGIN, + offset + int(font.maxAscent() + + font.maxDescent()) + 1, + box_x, + offset + int(font.maxAscent() + + font.maxDescent()) + 1, + LColor::footnoteframe); - scr.drawLine(gc_foot, - offset - + int(font.maxAscent()) - + int(font.maxDescent()) + 1, - LYX_PAPER_MARGIN, box_x - LYX_PAPER_MARGIN); } /* draw the open floats in a red box */ - scr.drawVerticalLine(gc_foot, - box_x, - offset, offset + row_ptr->height); + pain.line(box_x, offset, + box_x, offset + row_ptr->height, + LColor::footnoteframe); - scr.drawVerticalLine(gc_foot, - paperwidth - LYX_PAPER_MARGIN, - offset, - offset + row_ptr->height); - + pain.line(paperwidth - LYX_PAPER_MARGIN, + offset, + paperwidth - LYX_PAPER_MARGIN, + offset + row_ptr->height, + LColor::footnoteframe); + } else if (row_ptr->previous && + row_ptr->previous->par->footnoteflag + == LyXParagraph::OPEN_FOOTNOTE) { + LyXFont font(LyXFont::ALL_SANE); + font.setSize(LyXFont::SIZE_FOOTNOTE); - } else { - if (row_ptr->previous && - row_ptr->previous->par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE) { - LyXFont font(LyXFont::ALL_SANE); - font.setSize(LyXFont::SIZE_FOOTNOTE); - - int box_x = LYX_PAPER_MARGIN; - box_x += font.textWidth(" wide-tab ", 10); - - scr.drawLine(gc_foot, - offset, - box_x, - paperwidth - LYX_PAPER_MARGIN - box_x); - } + int box_x = LYX_PAPER_MARGIN; + box_x += font.textWidth(" wide-tab ", 10); + + pain.line(box_x, offset, + paperwidth - LYX_PAPER_MARGIN, + offset, LColor::footnote); } - LyXLayout const & layout = textclasslist.Style(parameters->textclass, - row_ptr->par->GetLayout()); + LyXLayout const & layout = + textclasslist.Style(parameters->textclass, + row_ptr->par->GetLayout()); firstpar = row_ptr->par->FirstPhysicalPar(); y_top = 0; @@ -3434,41 +3827,69 @@ void LyXText::GetVisibleRow(LyXScreen & scr, int offset, if (row_ptr->pos == 0 && row_ptr->par == firstpar) { - /* start of appendix? */ + /* start of appendix? */ if (row_ptr->par->start_of_appendix){ - scr.drawLine(gc_math, - offset, - 1, paperwidth-2); + pain.line(1, offset, + paperwidth - 2, offset, + LColor::appendixline); } - + /* think about the margins */ if (!row_ptr->previous) y_top += LYX_PAPER_MARGIN; if (row_ptr->par->pagebreak_top){ /* draw a top pagebreak */ - scr.drawOnOffLine(offset + y_top + 2 * DefaultHeight(), - 0, paperwidth); +#if 0 + pain.line(0, offset + y_top + 2 * DefaultHeight(), + paperwidth, + offset + y_top + 2 * DefaultHeight(), + LColor::pagebreak, Painter::line_onoffdash); +#else + LyXFont pb_font; + pb_font.setColor(LColor::pagebreak).decSize(); + int w = 0, a = 0, d = 0; + pain.line(0, offset + y_top + 2*DefaultHeight(), + paperwidth, + offset + y_top + 2*DefaultHeight(), + LColor::pagebreak, + Painter::line_onoffdash) + .rectText(0, + 0, + _("Page Break (top)"), + pb_font, + LColor::background, + LColor::background, false, w, a, d); + pain.rectText((paperwidth - w)/2, + offset +y_top + 2*DefaultHeight() +d, + _("Page Break (top)"), + pb_font, + LColor::background, + LColor::background); +#endif y_top += 3 * DefaultHeight(); } if (row_ptr->par->added_space_top.kind() == VSpace::VFILL) { /* draw a vfill top */ - scr.drawLine(gc_fill, - offset + 2 + y_top, - 0, LYX_PAPER_MARGIN); - scr.drawLine(gc_fill, - offset + y_top + 3 * DefaultHeight(), - 0, LYX_PAPER_MARGIN); - scr.drawVerticalOnOffLine(LYX_PAPER_MARGIN / 2, - offset + 2 + y_top, - offset + y_top + 3 * - DefaultHeight()); + pain.line(0, offset + 2 + y_top, + LYX_PAPER_MARGIN, offset + 2 + y_top, + LColor::vfillline); + + pain.line(0, offset + y_top + 3 * DefaultHeight(), + LYX_PAPER_MARGIN, + offset + y_top + 3 * DefaultHeight(), + LColor::vfillline); + + pain.line(LYX_PAPER_MARGIN / 2, offset + 2 + y_top, + LYX_PAPER_MARGIN / 2, + offset + y_top + 3 * DefaultHeight(), + LColor::vfillline); y_top += 3 * DefaultHeight(); } /* think about user added space */ - y_top += int(row_ptr->par->added_space_top.inPixels()); + y_top += int(row_ptr->par->added_space_top.inPixels(owner_)); /* think about the parskip */ /* some parskips VERY EASY IMPLEMENTATION */ @@ -3476,20 +3897,24 @@ void LyXText::GetVisibleRow(LyXScreen & scr, int offset, if (layout.latextype == LATEX_PARAGRAPH && firstpar->GetDepth() == 0 && firstpar->Previous()) - y_top += parameters->getDefSkip().inPixels(); + y_top += parameters->getDefSkip().inPixels(owner_); else if (firstpar->Previous() && textclasslist.Style(parameters->textclass, - firstpar->Previous()->GetLayout()).latextype == LATEX_PARAGRAPH + firstpar->Previous()->GetLayout()).latextype == LATEX_PARAGRAPH && firstpar->Previous()->GetDepth() == 0) // is it right to use defskip here, too? (AS) - y_top += parameters->getDefSkip().inPixels(); + y_top += parameters->getDefSkip().inPixels(owner_); } if (row_ptr->par->line_top) { /* draw a top line */ y_top += GetFont(row_ptr->par, 0).ascent('x'); - - scr.drawThickLine(offset + y_top, - 0, paperwidth); + + pain.line(0, offset + y_top, + paperwidth, offset + y_top, + LColor::topline, + Painter::line_solid, + Painter::line_thick); + y_top += GetFont(row_ptr->par, 0).ascent('x'); } @@ -3509,19 +3934,31 @@ void LyXText::GetVisibleRow(LyXScreen & scr, int offset, * an extra row and has a pagebreak at the top. */ maxdesc = int(font.maxDescent() * layout.spacing.getValue() * parameters->spacing.getValue()) + int(layout.parsep) * DefaultHeight(); - scr.drawString(font, tmpstring, - offset + row_ptr->baseline - - row_ptr->ascent_of_text - maxdesc, - int(x)); + if (direction == LYX_DIR_RIGHT_TO_LEFT) + tmpx = paperwidth - LeftMargin(row_ptr) - + font.stringWidth(tmpstring); + pain.text(int(tmpx), + offset + row_ptr->baseline - row_ptr->ascent_of_text - maxdesc, + tmpstring, font); } } else { - x -= font.stringWidth( layout.labelsep); - x -= font.stringWidth( tmpstring); + if (direction == LYX_DIR_LEFT_TO_RIGHT) + tmpx = x - font.stringWidth(layout.labelsep) + - font.stringWidth(tmpstring); + else { + tmpx = paperwidth - LeftMargin(row_ptr) + + font.stringWidth(layout.labelsep); + if (row_ptr->par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE) { + LyXFont font(LyXFont::ALL_SANE); + font.setSize(LyXFont::SIZE_SMALL); + tmpx += font.textWidth("Mwide-figM", 10); + } + } /* draw it! */ - scr.drawString(font, tmpstring, - offset + row_ptr->baseline, int(x)); + pain.text(int(tmpx), + offset + row_ptr->baseline, + tmpstring, font); } - x = tmpx; } /* the labels at the top of an environment. More or less for bibliography */ } else if (layout.labeltype == LABEL_TOP_ENVIRONMENT || @@ -3533,33 +3970,38 @@ void LyXText::GetVisibleRow(LyXScreen & scr, int offset, string tmpstring = row_ptr->par->GetLabestring(); maxdesc = int(font.maxDescent() * layout.spacing.getValue() * parameters->spacing.getValue() - + (layout.labelbottomsep * DefaultHeight())); + + (layout.labelbottomsep * DefaultHeight())); - int top_label_x = int(x); + tmpx = x; if (layout.labeltype == LABEL_CENTERED_TOP_ENVIRONMENT){ - top_label_x = int(x + (paperwidth - RightMargin(row_ptr) - x) / 2); - top_label_x -= (font.stringWidth( tmpstring)/2); - } - - scr.drawString(font, tmpstring, - offset + row_ptr->baseline - - row_ptr->ascent_of_text - maxdesc, - top_label_x); + tmpx = ( ((direction == LYX_DIR_LEFT_TO_RIGHT) + ? x : LeftMargin(row_ptr) ) + + paperwidth - RightMargin(row_ptr) ) / 2; + tmpx -= (font.stringWidth(tmpstring)/2); + } else if (direction == LYX_DIR_RIGHT_TO_LEFT) + tmpx = paperwidth - LeftMargin(row_ptr) - + font.stringWidth(tmpstring); + pain.text(int(tmpx), + offset + row_ptr->baseline + - row_ptr->ascent_of_text + - maxdesc, + tmpstring, font); } } } - if (layout.labeltype == LABEL_BIBLIO) { // ale970302 - if (row_ptr->par->bibkey) { - tmpx = x; - x -= font.stringWidth(layout.labelsep); - font = GetFont(row_ptr->par, -1); - x -= row_ptr->par->bibkey->Width(font); - row_ptr->par->bibkey->Draw(font, scr, - offset + row_ptr->baseline, - x); - x = tmpx; - } - } + if (layout.labeltype == LABEL_BIBLIO && row_ptr->par->bibkey) { + font = GetFont(row_ptr->par, -1); + if (direction == LYX_DIR_LEFT_TO_RIGHT) + tmpx = x - font.stringWidth(layout.labelsep) + - row_ptr->par->bibkey->width(owner_->painter(), font); + else + tmpx = paperwidth - LeftMargin(row_ptr) + + font.stringWidth(layout.labelsep); + row_ptr->par->bibkey->draw(owner_->painter(), + font, + offset + row_ptr->baseline, + tmpx); + } } /* is it a last row? */ @@ -3573,43 +4015,107 @@ void LyXText::GetVisibleRow(LyXScreen & scr, int offset, /* draw a bottom pagebreak */ if (firstpar->pagebreak_bottom) { - scr.drawOnOffLine(offset + y_bottom - 2 * - DefaultHeight(), - 0, paperwidth); +#if 0 + pain.line(0, offset + y_bottom - 2 * DefaultHeight(), + paperwidth, + offset + y_bottom - 2 * DefaultHeight(), + LColor::pagebreak, Painter::line_onoffdash); +#else + LyXFont pb_font; + pb_font.setColor(LColor::pagebreak).decSize(); + int w = 0, a = 0, d = 0; + pain.line(0, + offset + y_bottom - 2 * DefaultHeight(), + paperwidth, + offset + y_bottom - 2 * DefaultHeight(), + LColor::pagebreak, + Painter::line_onoffdash) + .rectText(0, + 0, + _("Page Break (bottom)"), + pb_font, + LColor::background, + LColor::background, false, w, a, d); + pain.rectText((paperwidth - w)/2, + offset +y_top + 2*DefaultHeight() +d, + _("Page Break (bottom)"), + pb_font, + LColor::background, + LColor::background); +#endif y_bottom -= 3 * DefaultHeight(); } if (firstpar->added_space_bottom.kind() == VSpace::VFILL) { /* draw a vfill bottom */ - scr.drawLine(gc_fill, - offset + y_bottom - 3 * DefaultHeight(), - 0, LYX_PAPER_MARGIN); - scr.drawLine(gc_fill, offset + y_bottom - 2, - 0, LYX_PAPER_MARGIN); - scr.drawVerticalOnOffLine(LYX_PAPER_MARGIN / 2, - offset + y_bottom - 3 * DefaultHeight(), - offset + y_bottom - 2 - ); + pain.line(0, offset + y_bottom - 3 * DefaultHeight(), + LYX_PAPER_MARGIN, + offset + y_bottom - 3 * DefaultHeight(), + LColor::vfillline); + pain.line(0, offset + y_bottom - 2, + LYX_PAPER_MARGIN, + offset + y_bottom - 2, + LColor::vfillline); + pain.line(LYX_PAPER_MARGIN / 2, + offset + y_bottom - 3 * DefaultHeight(), + LYX_PAPER_MARGIN / 2, + offset + y_bottom - 2, + LColor::vfillline); y_bottom -= 3* DefaultHeight(); } /* think about user added space */ - y_bottom -= int(firstpar->added_space_bottom.inPixels()); + y_bottom -= int(firstpar->added_space_bottom.inPixels(owner_)); if (firstpar->line_bottom) { /* draw a bottom line */ y_bottom -= GetFont(par, par->Last() - 1).ascent('x'); - - scr.drawThickLine(offset + y_bottom, - 0, paperwidth); + pain.line(0, offset + y_bottom, + paperwidth, offset + y_bottom, + LColor::topline, Painter::line_solid, + Painter::line_thick); y_bottom -= GetFont(par, par->Last() - 1).ascent('x'); } + + // draw an endlabel + int endlabel = row_ptr->par->GetEndLabel(); + if (endlabel == END_LABEL_BOX || + endlabel == END_LABEL_FILLED_BOX) { + LyXFont font = GetFont(row_ptr->par, RowLast(row_ptr)); + int size = int(0.75*font.maxAscent()); + int y = (offset + row_ptr->baseline) - size; + int x = (direction == LYX_DIR_LEFT_TO_RIGHT) + ? paperwidth - LYX_PAPER_MARGIN - size + : LYX_PAPER_MARGIN; + if (row_ptr->par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE) + if (direction == LYX_DIR_LEFT_TO_RIGHT) + x -= LYX_PAPER_MARGIN/2; + else { + LyXFont font(LyXFont::ALL_SANE); + font.setSize(LyXFont::SIZE_SMALL); + x += font.textWidth("Mwide-figM", 10); + } + if (row_ptr->fill <= size) + x += (size - row_ptr->fill + 1) * direction; + if (endlabel == END_LABEL_BOX) { + pain.line(x, y, x, y + size, + LColor::eolmarker); + pain.line(x + size, y, x + size , y + size, + LColor::eolmarker); + pain.line(x, y, x + size, y, + LColor::eolmarker); + pain.line(x, y + size, x + size, y + size, + LColor::eolmarker); + } else + pain.fillRectangle(x, y, size, size, + LColor::eolmarker); + } } /* draw the text in the pixmap */ pos_end = RowLast(row_ptr); - pos = row_ptr->pos; + vpos = row_ptr->pos; /* table stuff -- begin*/ if (row_ptr->par->table) { bool on_off; @@ -3617,7 +4123,8 @@ void LyXText::GetVisibleRow(LyXScreen & scr, int offset, float x_old = x; x += row_ptr->par->table->GetBeginningOfTextInCell(cell); - while (pos <= pos_end) { + while (vpos <= pos_end) { + pos = vis2log(vpos); if (row_ptr->par->IsNewline(pos)) { x = x_old + row_ptr->par->table->WidthOfColumn(cell); @@ -3626,76 +4133,100 @@ void LyXText::GetVisibleRow(LyXScreen & scr, int offset, if ((!on_off || !row_ptr->par->table->TopAlreadyDrawed(cell)) && !row_ptr->par->table->IsContRow(cell)) - scr.drawTableLine(offset + row_ptr->baseline - - row_ptr->ascent_of_text, - int(x_old), int(x - x_old), on_off); + pain.line(int(x_old), + offset + row_ptr->baseline - row_ptr->ascent_of_text, + int(x), + offset + row_ptr->baseline - row_ptr->ascent_of_text, + LColor::tableline, + on_off ? Painter::line_onoffdash : Painter::line_solid); + on_off = !row_ptr->par->table->BottomLine(cell); if ((!on_off && !row_ptr->par->table->RowHasContRow(cell)) || row_ptr->par->table->VeryLastRow(cell)) - scr.drawTableLine(offset + y_bottom - 1, - int(x_old), int(x - x_old), on_off); + + pain.line(int(x_old), + offset + y_bottom - 1, + int(x), + offset + y_bottom - 1, + LColor::tableline, + on_off ? Painter::line_onoffdash : Painter::line_solid); + on_off = !row_ptr->par->table->LeftLine(cell); - scr.drawVerticalTableLine(int(x_old), - offset + row_ptr->baseline - - row_ptr->ascent_of_text, - offset + y_bottom - 1, - on_off); + pain.line(int(x_old), + offset + row_ptr->baseline - row_ptr->ascent_of_text, + int(x_old), + offset + y_bottom - 1, + LColor::tableline, + on_off ? Painter::line_onoffdash : Painter::line_solid); + on_off = !row_ptr->par->table->RightLine(cell); - scr.drawVerticalTableLine(int(x) - - row_ptr->par->table->AdditionalWidth(cell), - offset + row_ptr->baseline - - row_ptr->ascent_of_text, - offset + y_bottom - 1, - on_off); + pain.line(int(x) - row_ptr->par->table->AdditionalWidth(cell), + offset + row_ptr->baseline - row_ptr->ascent_of_text, + int(x) - row_ptr->par->table->AdditionalWidth(cell), + offset + y_bottom - 1, + LColor::tableline, + on_off ? Painter::line_onoffdash : Painter::line_solid); + x_old = x; - /* take care about the alignment and other spaces */ - cell++; + /* take care about the alignment and other spaces */ + ++cell; x += row_ptr->par->table->GetBeginningOfTextInCell(cell); if (row_ptr->par->table->IsFirstCell(cell)) - cell--; // little hack, sorry - pos++; + --cell; // little hack, sorry + ++vpos; } else if (row_ptr->par->IsHfill(pos)) { x += 1; - scr.drawVerticalLine(gc_fill, int(x), - offset + row_ptr->baseline - DefaultHeight()/2, - offset + row_ptr->baseline); + pain.line(int(x), + offset + row_ptr->baseline - DefaultHeight() / 2, + int(x), + offset + row_ptr->baseline, + LColor::vfillline); + x += 2; - pos++; - } else { - if (row_ptr->par->IsSeparator(pos)) { - tmpx = x; - x+= SingleWidth(row_ptr->par, pos); - /* -------> Only draw protected spaces when not in - * free-spacing mode. */ - if (row_ptr->par->GetChar(pos) == LyXParagraph::META_PROTECTED_SEPARATOR && !layout.free_spacing) { - scr.drawVerticalLine(gc_fill, int(tmpx), - offset + row_ptr->baseline - 3, - offset + row_ptr->baseline - 1); - scr.drawLine(gc_fill, - offset + row_ptr->baseline - 1, - int(tmpx), - int(x-tmpx-2)); - scr.drawVerticalLine(gc_fill, int(x-2), - offset + row_ptr->baseline - 3, - offset + row_ptr->baseline - 1); - /* what about underbars? */ - font = GetFont(row_ptr->par, pos); - if (font.underbar() == LyXFont::ON - && font.latex() != LyXFont::ON) { - scr.drawLine(gc_copy, - offset + - row_ptr->baseline + 2, - int(tmpx), - int(x - tmpx)); - } + ++vpos; + } else if (row_ptr->par->IsSeparator(pos)) { + tmpx = x; + x+= SingleWidth(row_ptr->par, pos); +#warning Think about this. +#if 0 + /* -------> Only draw protected spaces when + * not in free-spacing mode. */ + if (row_ptr->par->GetChar(pos) == LyXParagraph::META_PROTECTED_SEPARATOR && !layout.free_spacing) { + pain.line(int(tmpx), + offset + row_ptr->baseline - 3, + int(tmpx), + offset + row_ptr->baseline - 1, + LColor::vfillline); + + pain.line(int(tmpx), + offset + row_ptr->baseline - 1, + int(x - 2), + offset + row_ptr->baseline - 1, + LColor::vfillline); + + pain.line(int(x - 2), + offset + row_ptr->baseline - 3, + int(x - 2), + offset + row_ptr->baseline - 1, + LColor::vfillline); + + /* what about underbars? */ + font = GetFont(row_ptr->par, pos); + if (font.underbar() == LyXFont::ON + && font.latex() != LyXFont::ON) { + pain.line(int(tmpx), + offset + row_ptr->baseline + 2, + int(x - tmpx), + offset + row_ptr->baseline + 2); } - pos++; - } else - Draw(row_ptr, pos, scr, offset, x); - } + } +#endif + ++vpos; + } else + draw(row_ptr, vpos, offset, x); } /* do not forget the very last cell. This has no NEWLINE so @@ -3707,132 +4238,138 @@ void LyXText::GetVisibleRow(LyXScreen & scr, int offset, !row_ptr->par->table->TopAlreadyDrawed(cell)) && !row_ptr->par->table->IsContRow(cell)) - scr.drawTableLine(offset + row_ptr->baseline - - row_ptr->ascent_of_text, - int(x_old), int(x - x_old), on_off); + pain.line(int(x_old), + offset + row_ptr->baseline - row_ptr->ascent_of_text, + int(x), + offset + row_ptr->baseline - row_ptr->ascent_of_text, + LColor::tableline, + on_off ? Painter::line_onoffdash : Painter::line_solid); on_off = !row_ptr->par->table->BottomLine(cell); if ((!on_off && !row_ptr->par->table->RowHasContRow(cell)) || row_ptr->par->table->VeryLastRow(cell)) - scr.drawTableLine(offset + y_bottom - 1, - int(x_old), int(x - x_old), on_off); + pain.line(int(x_old), + offset + y_bottom - 1, + int(x), + offset + y_bottom - 1, + LColor::tableline, + on_off ? Painter::line_onoffdash : Painter::line_solid); + on_off = !row_ptr->par->table->LeftLine(cell); - scr.drawVerticalTableLine(int(x_old), - offset + row_ptr->baseline - - row_ptr->ascent_of_text, - offset + y_bottom - 1, - on_off); + pain.line(int(x_old), + offset + row_ptr->baseline - row_ptr->ascent_of_text, + int(x_old), + offset + y_bottom - 1, + LColor::tableline, + on_off ? Painter::line_onoffdash : Painter::line_solid); + on_off = !row_ptr->par->table->RightLine(cell); - scr.drawVerticalTableLine(int(x) - - row_ptr->par->table->AdditionalWidth(cell), - offset + row_ptr->baseline - - row_ptr->ascent_of_text, - offset + y_bottom - 1, - on_off); + pain.line(int(x) - row_ptr->par->table->AdditionalWidth(cell), + offset + row_ptr->baseline - row_ptr->ascent_of_text, + int(x) - row_ptr->par->table->AdditionalWidth(cell), + offset + y_bottom - 1, + LColor::tableline, + on_off ? Painter::line_onoffdash : Painter::line_solid); } } else { /* table stuff -- end*/ + LyXParagraph::size_type main_body = + BeginningOfMainBody(row_ptr->par); + if (main_body > 0 && + (main_body-1 > pos_end || + !row_ptr->par->IsLineSeparator(main_body-1))) + main_body = 0; - while (pos <= pos_end) { + while (vpos <= pos_end) { + pos = vis2log(vpos); + if (main_body > 0 && pos == main_body-1) { + x += fill_label_hfill + + GetFont(row_ptr->par, -2).stringWidth(layout.labelsep) + - SingleWidth(row_ptr->par, main_body-1); + } if (row_ptr->par->IsHfill(pos)) { x += 1; - scr.drawVerticalLine(gc_fill, int(x), - offset + row_ptr->baseline - DefaultHeight()/2, - offset + row_ptr->baseline); + pain.line(int(x), + offset + row_ptr->baseline - DefaultHeight() / 2, + int(x), + offset + row_ptr->baseline, + LColor::vfillline); + if (HfillExpansion(row_ptr, pos)) { if (pos >= main_body) { - scr.drawOnOffLine(offset + row_ptr->baseline - - DefaultHeight()/4, - int(x), - int(fill_hfill)); + pain.line(int(x), + offset + row_ptr->baseline - DefaultHeight() / 4, + int(x + fill_hfill), + offset + row_ptr->baseline - DefaultHeight() / 4, + LColor::vfillline, + Painter::line_onoffdash); x += fill_hfill; - } else { - scr.drawOnOffLine(offset + row_ptr->baseline - - DefaultHeight()/4, - int(x), - int(fill_label_hfill)); - x += fill_label_hfill; - } - scr.drawVerticalLine(gc_fill, int(x), - offset + row_ptr->baseline - - DefaultHeight()/2, - offset + row_ptr->baseline); + } else { + pain.line(int(x), + offset + row_ptr->baseline - DefaultHeight() / 4, + int(x + fill_label_hfill), + offset + row_ptr->baseline - DefaultHeight() / 4, + LColor::vfillline, + Painter::line_onoffdash); + + x += fill_label_hfill; + } + pain.line(int(x), + offset + row_ptr->baseline - DefaultHeight() / 2, + int(x), + offset + row_ptr->baseline, + LColor::vfillline); } x += 2; - pos++; - } else { - if (row_ptr->par->IsSeparator(pos)) { - tmpx = x; - x+= SingleWidth(row_ptr->par, pos); - if (pos >= main_body) - x+= fill_separator; - /* -------> Only draw protected spaces when not in - * free-spacing mode. */ - if (row_ptr->par->GetChar(pos) == LyXParagraph::META_PROTECTED_SEPARATOR && !layout.free_spacing) { - - scr.drawVerticalLine(gc_fill, int(tmpx), - offset + row_ptr->baseline - 3, - offset + row_ptr->baseline - 1); - scr.drawLine(gc_fill, - offset + row_ptr->baseline - 1, - int(tmpx), - int(x-tmpx-2)); - scr.drawVerticalLine(gc_fill, int(x-2), - offset + row_ptr->baseline - 3, - offset + row_ptr->baseline - 1); - /* what about underbars? */ - font = GetFont(row_ptr->par, pos); - if (font.underbar() == LyXFont::ON - && font.latex() != LyXFont::ON) { - scr.drawLine(gc_copy, - offset + row_ptr->baseline + 2, - int(tmpx), - int(x - tmpx)); - } + ++vpos; + } else if (row_ptr->par->IsSeparator(pos)) { + tmpx = x; + x+= SingleWidth(row_ptr->par, pos); + if (pos >= main_body) + x+= fill_separator; +#warning Think about this +#if 0 + /* -------> Only draw protected spaces when + * not in free-spacing mode. */ + if (row_ptr->par->GetChar(pos) == LyXParagraph::META_PROTECTED_SEPARATOR && !layout.free_spacing) { + + pain.line(int(tmpx), + offset + row_ptr->baseline - 3, + int(tmpx), + offset + row_ptr->baseline - 1, + LColor::vfillline); + + pain.line(int(tmpx), + offset + row_ptr->baseline - 1, + int(x - 2), + offset + row_ptr->baseline - 1, + LColor::vfillline); + + pain.line(int(x - 2), + offset + row_ptr->baseline - 3, + int(x - 2), + offset + row_ptr->baseline - 1, + LColor::vfillline); + + /* what about underbars? */ + font = GetFont(row_ptr->par, pos); + if (font.underbar() == LyXFont::ON + && font.latex() != LyXFont::ON) { + pain.line(int(tmpx), + offset + row_ptr->baseline + 2, + int(x - tmpx), + offset + row_ptr->baseline + 2); } - pos++; - } else - Draw(row_ptr, pos, scr, offset, x); - } - if (pos == main_body) { - x += GetFont(row_ptr->par, -2).stringWidth( - layout.labelsep); - if (row_ptr->par->IsLineSeparator(pos - 1)) - x-= SingleWidth(row_ptr->par, pos - 1); - if (x < left_margin) - x = left_margin; - } - } - } - // check for FAST SELECTION - if (fast_selection || mono_video) { - if (selection) { - - /* selection code */ - if (sel_start_cursor.row == row_ptr && sel_end_cursor.row == row_ptr) { - scr.fillRectangle(gc_select, sel_start_cursor.x, offset, - sel_end_cursor.x - sel_start_cursor.x, - row_ptr->height); - } else if (sel_start_cursor.row == row_ptr) { - scr.fillRectangle(gc_select, sel_start_cursor.x, offset, - paperwidth - sel_start_cursor.x, - row_ptr->height); - } else if (sel_end_cursor.row == row_ptr) { - scr.fillRectangle(gc_select, 0, offset, - sel_end_cursor.x, - row_ptr->height); - } else if (y > sel_start_cursor.y && y < sel_end_cursor.y) { - scr.fillRectangle(gc_select, 0, offset, - paperwidth, row_ptr->height); - - } + } +#endif + ++vpos; + } else + draw(row_ptr, vpos, offset, x); } } -// end of FAST SELECTION code - /* thats it */ } @@ -3850,56 +4387,61 @@ int LyXText::GetColumnNearX(Row * row, int & x) const float tmpx = 0.0; float fill_separator, fill_hfill, fill_label_hfill; - int left_margin = LabelEnd(row); PrepareToPrint(row, tmpx, fill_separator, fill_hfill, fill_label_hfill); - int main_body = BeginningOfMainBody(row->par); - - int c = row->pos; - int last = RowLast(row); - if (row->par->IsNewline(last)) - last--; - + LyXDirection direction = row->par->getParDirection(); + LyXParagraph::size_type vc = row->pos; + LyXParagraph::size_type last = RowLast(row); + LyXParagraph::size_type c = 0; + LyXLayout const & layout = textclasslist.Style(parameters->textclass, - row->par->GetLayout()); + row->par->GetLayout()); /* table stuff -- begin */ if (row->par->table) { - if (!row->next || row->next->par != row->par) - last = RowLast(row); /* the last row doesn't need a newline at the end*/ + if (row->next && row->next->par == row->par //the last row doesn't need a newline at the end + && row->par->IsNewline(last)) + last--; int cell = NumberOfCell(row->par, row->pos); float x_old = tmpx; bool ready = false; tmpx += row->par->table->GetBeginningOfTextInCell(cell); - while (c <= last + while (vc <= last + && (c = vis2log(vc)) >= 0 && tmpx + (SingleWidth(row->par, c)/2) <= x && !ready){ if (row->par->IsNewline(c)) { if (x_old + row->par->table->WidthOfColumn(cell) <= x){ tmpx = x_old + row->par->table->WidthOfColumn(cell); x_old = tmpx; - cell++; + ++cell; tmpx += row->par->table->GetBeginningOfTextInCell(cell); - ++c; + ++vc; } else ready = true; } else { tmpx += SingleWidth(row->par, c); - ++c; + ++vc; } } - } else + } else { /* table stuff -- end*/ - - while (c <= last - && tmpx + (SingleWidth(row->par, c)/2) <= x) { - - if (c && c == main_body - && !row->par->IsLineSeparator(c - 1)) { - tmpx += GetFont(row->par, -2) - .stringWidth(layout.labelsep); - if (tmpx < left_margin) - tmpx = left_margin; + LyXParagraph::size_type main_body = BeginningOfMainBody(row->par); + float last_tmpx = tmpx; + + if (main_body > 0 && + (main_body-1 > last || + !row->par->IsLineSeparator(main_body-1))) + main_body = 0; + + while (vc <= last && tmpx <= x) { + c = vis2log(vc); + last_tmpx = tmpx; + if (main_body > 0 && c == main_body-1) { + tmpx += fill_label_hfill + + GetFont(row->par, -2).stringWidth(layout.labelsep); + if (row->par->IsLineSeparator(main_body-1)) + tmpx -= SingleWidth(row->par, main_body-1); } tmpx += SingleWidth(row->par, c); @@ -3913,25 +4455,55 @@ int LyXText::GetColumnNearX(Row * row, int & x) const && row->par->IsSeparator(c)) { tmpx+= fill_separator; } - c++; - if (c == main_body - && row->par->IsLineSeparator(c - 1)) { - tmpx += GetFont(row->par, -2) - .stringWidth(layout.labelsep); - tmpx-= SingleWidth(row->par, c - 1); - if (tmpx < left_margin) - tmpx = left_margin; - } + ++vc; } + + if (vc > row->pos && (tmpx+last_tmpx)/2 > x) { + vc--; + tmpx = last_tmpx; + } + } /* make sure that a last space in a row doesnt count */ - if (c > 0 && c >= last - && row->par->IsLineSeparator(c - 1) - && !(!row->next || row->next->par != row->par)) { - tmpx -= SingleWidth(row->par, c - 1); - tmpx -= fill_separator; + if (row->pos <= last + && !(!row->next || row->next->par != row->par)) + if (direction == LYX_DIR_LEFT_TO_RIGHT && vc > last + && row->par->IsLineSeparator(vis2log(last)) ) { + vc = last; + tmpx -= fill_separator+SingleWidth(row->par, vis2log(last)); + } else if (direction == LYX_DIR_RIGHT_TO_LEFT + && vc == row->pos + && row->par->IsLineSeparator(vis2log(row->pos)) ) { + vc = row->pos+1; + tmpx += fill_separator+SingleWidth(row->par, vis2log(row->pos)); + } + if (row->pos > last) // Row is empty? + c = row->pos; + else if (vc > last || + (row->par->table && vc > row->pos && row->par->IsNewline(vc)) ){ + int pos = (vc > last+1) ? last : vc - 1; + c = vis2log(pos); + if (row->par->getLetterDirection(c) == LYX_DIR_LEFT_TO_RIGHT) + ++c; + } else { + c = vis2log(vc); + LyXDirection direction = row->par->getLetterDirection(c); + if (vc > row->pos && row->par->IsLineSeparator(c) + && row->par->getLetterDirection(vis2log(vc - 1)) != direction) + c = vis2log(vc-1); + if (direction == LYX_DIR_RIGHT_TO_LEFT) + ++c; } - c-= row->pos; - + + if (!row->par->table && row->pos <= last && c > last + && row->par->IsNewline(last)) { + if (row->par->getLetterDirection(last) == LYX_DIR_LEFT_TO_RIGHT) + tmpx -= SingleWidth(row->par, last); + else + tmpx += SingleWidth(row->par, last); + c = last; + } + + c -= row->pos; x = int(tmpx); return c; } @@ -4039,11 +4611,17 @@ void LyXText::InsertFootnoteEnvironment(LyXParagraph::footnote_kind kind) || kind == LyXParagraph::WIDE_TAB || kind == LyXParagraph::WIDE_FIG || kind == LyXParagraph::ALGORITHM) { - int lay = textclasslist.NumberOfLayout(parameters->textclass, - "Caption").second; - if (lay == -1) // layout not found - // use default layout "Standard" (0) - lay = 0; + pair lres = + textclasslist.NumberOfLayout(parameters->textclass, + "Caption"); + LyXTextClass::size_type lay; + if (lres.first) { + // layout fount + lay = lres.second; + } else { + // layout not found + lay = 0; // use default layout "Standard" (0) + } tmppar->SetLayout(lay); } } @@ -4079,32 +4657,44 @@ Row * LyXText::GetRow(LyXParagraph * par, LyXParagraph::size_type pos, long & y) const { Row * tmprow; - + if (currentrow) { - if (par == currentrow->par || par == currentrow->par->Previous()) { + if (par == currentrow->par + || par == currentrow->par->Previous()) { // do not dereference par, it may have been deleted - // already! (Matthias) - while (currentrow->previous && currentrow->previous->par != par) { + // already! (Matthias) + + // Walk backwards as long as the previous + // rows par is not par + while (currentrow->previous + && currentrow->previous->par != par) { currentrow = currentrow->previous; currentrow_y -= currentrow->height; } - while (currentrow->previous && currentrow->previous->par == par) { + // Walk backwards as long as the previous + // rows par _is_ par + while (currentrow->previous + && currentrow->previous->par == par) { currentrow = currentrow->previous; currentrow_y -= currentrow->height; } } + tmprow = currentrow; y = currentrow_y; // find the first row of the specified paragraph - while (tmprow->next && (tmprow->par != par)) { + while (tmprow->next + && tmprow->par != par) { y += tmprow->height; tmprow = tmprow->next; } if (tmprow->par == par){ // now find the wanted row - while (tmprow->pos < pos && tmprow->next && tmprow->next->par == par && - tmprow->next->pos <= pos) { + while (tmprow->pos < pos + && tmprow->next + && tmprow->next->par == par + && tmprow->next->pos <= pos) { y += tmprow->height; tmprow = tmprow->next; } @@ -4113,17 +4703,20 @@ Row * LyXText::GetRow(LyXParagraph * par, return tmprow; } } + tmprow = firstrow; y = 0; // find the first row of the specified paragraph - while (tmprow->next && (tmprow->par != par)) { + while (tmprow->next && tmprow->par != par) { y += tmprow->height; tmprow = tmprow->next; } // now find the wanted row - while (tmprow->pos < pos && tmprow->next && tmprow->next->par == par && - tmprow->next->pos <= pos) { + while (tmprow->pos < pos + && tmprow->next + && tmprow->next->par == par + && tmprow->next->pos <= pos) { y += tmprow->height; tmprow = tmprow->next; }