two patches from Dekel

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@780 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Lars Gullik Bjønnes 2000-05-30 19:31:11 +00:00
parent aa25dde22d
commit 73b9ca2a4b
13 changed files with 340 additions and 182 deletions

View File

@ -1,3 +1,22 @@
2000-05-27 Dekel Tsur <dekel@math.tau.ac.il>
* src/text.C (draw): draw bars under foreign language words.
* src/LColor.[Ch]: add LColor::language
2000-05-27 Dekel Tsur <dekel@math.tau.ac.il>
* src/lyxcursor.h (boundary): New member variable
* src/text.C (IsBoundary): New methods
* src/text.C: Use the above for currect cursor movement when there
is both RTL & LTR text.
* src/text2.C: ditto
* src/bufferview_funcs.C (ToggleAndShow): ditto
2000-05-30 Jean-Marc Lasgouttes <Jean-Marc.Lasgouttes@inria.fr> 2000-05-30 Jean-Marc Lasgouttes <Jean-Marc.Lasgouttes@inria.fr>
* src/text.C (DeleteLineForward): set selection to true to avoid * src/text.C (DeleteLineForward): set selection to true to avoid

View File

@ -659,6 +659,11 @@
# the document. Default is true. # the document. Default is true.
#\language_auto_end false #\language_auto_end false
# Set mark_foreign_language to "false" to disable the highlighting of words
# with a foreign language to the language of the documet.
# Default is "true"
#\mark_foreign_language false
# #
# HEBREW SUPPORT SECTION #################################################### # HEBREW SUPPORT SECTION ####################################################
# #
@ -675,6 +680,9 @@
# For example, # For example,
#\bind "F12" "language hebrew" #\bind "F12" "language hebrew"
# You might want ot disable the foreign language marking:
#\mark_foreign_language false
# Finally, you need to select iso8859-8 font encoding, and select screen fonts # Finally, you need to select iso8859-8 font encoding, and select screen fonts
# (below are the default fonts. You need to replace them by Hebrew fonts) # (below are the default fonts. You need to replace them by Hebrew fonts)
#\screen_font_encoding iso8859-8 #\screen_font_encoding iso8859-8

View File

@ -66,6 +66,7 @@ LColor::LColor()
{ notebg, N_("note background"), "notebg", "yellow", "notebg" }, { notebg, N_("note background"), "notebg", "yellow", "notebg" },
{ noteframe, N_("note frame"), "noteframe", "black", "noteframe" }, { noteframe, N_("note frame"), "noteframe", "black", "noteframe" },
{ depthbar, N_("depth bar"), "depthbar", "IndianRed", "depthbar" }, { depthbar, N_("depth bar"), "depthbar", "IndianRed", "depthbar" },
{ language, N_("language"), "language", "Blue", "language" },
{ command, N_("command-inset"), "command", "black", "command" }, { command, N_("command-inset"), "command", "black", "command" },
{ commandbg, N_("command-inset background"), "commandbg", "grey80", "commandbg" }, { commandbg, N_("command-inset background"), "commandbg", "grey80", "commandbg" },
{ commandframe, N_("inset frame"), "commandframe", "black", "commandframe" }, { commandframe, N_("inset frame"), "commandframe", "black", "commandframe" },

View File

@ -78,6 +78,8 @@ public:
/// Color for the depth bars in the margin /// Color for the depth bars in the margin
depthbar, depthbar,
/// Color for marking foreign language words
language,
/// Text color for command insets /// Text color for command insets
command, command,

View File

@ -293,5 +293,17 @@ void ToggleAndShow(BufferView * bv, LyXFont const & font)
else else
bv->text->ToggleFree(font, toggleall); bv->text->ToggleFree(font, toggleall);
bv->update(1); bv->update(1);
if (font.language() != ignore_language ||
font.latex() != LyXFont::IGNORE) {
LyXText * text = bv->text;
LyXCursor & cursor = text->cursor;
text->ComputeBidiTables(cursor.row);
if (cursor.boundary !=
text->IsBoundary(cursor.par, cursor.pos,
text->real_current_font) )
text->SetCursor(cursor.par, cursor.pos,
false, !cursor.boundary);
}
} }
} }

View File

@ -2377,10 +2377,12 @@ extern "C" void DocumentApplyCB(FL_OBJECT *, long)
if (current_view->available()) { if (current_view->available()) {
if (old_language != new_language && if (old_language != new_language &&
old_language->RightToLeft == new_language->RightToLeft && old_language->RightToLeft == new_language->RightToLeft &&
! current_view->buffer()->isMultiLingual() ) { ! current_view->buffer()->isMultiLingual() )
current_view->buffer()->ChangeLanguage(old_language, current_view->buffer()->ChangeLanguage(old_language,
new_language); new_language);
current_view->buffer()->redraw(); if (old_language != new_language) {
//current_view->buffer()->redraw();
redo = true;
} }
} }
params->language_info = new_language; params->language_info = new_language;

View File

@ -24,6 +24,8 @@ struct LyXCursor {
/// ///
LyXParagraph::size_type pos; LyXParagraph::size_type pos;
/// ///
bool boundary;
///
int x; int x;
/// ///
int x_fix; int x_fix;
@ -33,9 +35,9 @@ struct LyXCursor {
Row * row; Row * row;
/// ///
inline bool operator==(const LyXCursor &a) const inline bool operator==(const LyXCursor &a) const
{ return (a.par == par) && (a.pos == pos); } { return a.par == par && a.pos == pos && a.boundary == boundary ; }
inline bool operator!=(const LyXCursor &a) const inline bool operator!=(const LyXCursor &a) const
{ return (a.par != par) || (a.pos != pos); } { return a.par != par || a.pos != pos || a.boundary != boundary; }
}; };
#endif #endif

View File

@ -1222,18 +1222,16 @@ string LyXFunc::Dispatch(int ac,
break; break;
case LFUN_LANGUAGE: case LFUN_LANGUAGE:
{
Lang(owner->view(), argument); Lang(owner->view(), argument);
owner->view()->setState(); owner->view()->setState();
owner->getMiniBuffer()->Set(CurrentState(owner->view())); owner->getMiniBuffer()->Set(CurrentState(owner->view()));
}
break; break;
case LFUN_EMPH: case LFUN_EMPH:
Emph(owner->view()); Emph(owner->view());
owner->getMiniBuffer()->Set(CurrentState(owner->view())); owner->getMiniBuffer()->Set(CurrentState(owner->view()));
break; break;
case LFUN_BOLD: case LFUN_BOLD:
Bold(owner->view()); Bold(owner->view());
owner->getMiniBuffer()->Set(CurrentState(owner->view())); owner->getMiniBuffer()->Set(CurrentState(owner->view()));
@ -1367,7 +1365,7 @@ string LyXFunc::Dispatch(int ac,
owner->view()->beforeChange(); owner->view()->beforeChange();
owner->view()->update(-2); owner->view()->update(-2);
if (is_rtl) if (is_rtl)
tmptext->CursorLeft(); tmptext->CursorLeft(false);
if (tmptext->cursor.pos < tmptext->cursor.par->Last() if (tmptext->cursor.pos < tmptext->cursor.par->Last()
&& tmptext->cursor.par->GetChar(tmptext->cursor.pos) && tmptext->cursor.par->GetChar(tmptext->cursor.pos)
== LyXParagraph::META_INSET == LyXParagraph::META_INSET
@ -1379,7 +1377,7 @@ string LyXFunc::Dispatch(int ac,
break; break;
} }
if (!is_rtl) if (!is_rtl)
tmptext->CursorRight(); tmptext->CursorRight(false);
owner->view()->text->FinishUndo(); owner->view()->text->FinishUndo();
moveCursorUpdate(false); moveCursorUpdate(false);
owner->getMiniBuffer()->Set(CurrentState(owner->view())); owner->getMiniBuffer()->Set(CurrentState(owner->view()));
@ -1395,7 +1393,7 @@ string LyXFunc::Dispatch(int ac,
if(!txt->mark_set) owner->view()->beforeChange(); if(!txt->mark_set) owner->view()->beforeChange();
owner->view()->update(-2); owner->view()->update(-2);
if (!is_rtl) if (!is_rtl)
txt->CursorLeft(); txt->CursorLeft(false);
if (txt->cursor.pos < txt->cursor.par->Last() if (txt->cursor.pos < txt->cursor.par->Last()
&& txt->cursor.par->GetChar(txt->cursor.pos) && txt->cursor.par->GetChar(txt->cursor.pos)
== LyXParagraph::META_INSET == LyXParagraph::META_INSET
@ -1412,7 +1410,7 @@ string LyXFunc::Dispatch(int ac,
break; break;
} }
if (is_rtl) if (is_rtl)
txt->CursorRight(); txt->CursorRight(false);
owner->view()->text->FinishUndo(); owner->view()->text->FinishUndo();
moveCursorUpdate(false); moveCursorUpdate(false);

View File

@ -137,6 +137,7 @@ enum LyXRCTags {
RC_BACKUPDIR_PATH, RC_BACKUPDIR_PATH,
RC_RTL_SUPPORT, RC_RTL_SUPPORT,
RC_AUTO_NUMBER, RC_AUTO_NUMBER,
RC_MARK_FOREIGN_LANGUAGE,
RC_LANGUAGE_PACKAGE, RC_LANGUAGE_PACKAGE,
RC_LANGUAGE_AUTO_BEGIN, RC_LANGUAGE_AUTO_BEGIN,
RC_LANGUAGE_AUTO_END, RC_LANGUAGE_AUTO_END,
@ -213,6 +214,7 @@ keyword_item lyxrcTags[] = {
{ "\\literate_error_filter", RC_LITERATE_ERROR_FILTER }, { "\\literate_error_filter", RC_LITERATE_ERROR_FILTER },
{ "\\literate_extension", RC_LITERATE_EXTENSION }, { "\\literate_extension", RC_LITERATE_EXTENSION },
{ "\\make_backup", RC_MAKE_BACKUP }, { "\\make_backup", RC_MAKE_BACKUP },
{ "\\mark_foreign_language", RC_MARK_FOREIGN_LANGUAGE },
{ "\\num_lastfiles", RC_NUMLASTFILES }, { "\\num_lastfiles", RC_NUMLASTFILES },
{ "\\override_x_deadkeys", RC_OVERRIDE_X_DEADKEYS }, { "\\override_x_deadkeys", RC_OVERRIDE_X_DEADKEYS },
{ "\\pdf_mode", RC_PDF_MODE }, { "\\pdf_mode", RC_PDF_MODE },
@ -367,6 +369,7 @@ void LyXRC::setDefaults() {
hasBindFile = false; hasBindFile = false;
rtl_support = false; rtl_support = false;
auto_number = true; auto_number = true;
mark_foreign_language = true;
language_package = "\\usepackage{babel}"; language_package = "\\usepackage{babel}";
language_auto_begin = true; language_auto_begin = true;
language_auto_end = true; language_auto_end = true;
@ -1011,6 +1014,9 @@ int LyXRC::read(string const & filename)
if (lexrc.next()) if (lexrc.next())
auto_number = lexrc.GetBool(); auto_number = lexrc.GetBool();
break; break;
case RC_MARK_FOREIGN_LANGUAGE:
if (lexrc.next())
mark_foreign_language = lexrc.GetBool();
case RC_SHOW_BANNER: case RC_SHOW_BANNER:
if (lexrc.next()) if (lexrc.next())
show_banner = lexrc.GetBool(); show_banner = lexrc.GetBool();
@ -1337,6 +1343,9 @@ void LyXRC::output(ostream & os) const
os << "\\rtl " << tostr(rtl_support) << "\n"; os << "\\rtl " << tostr(rtl_support) << "\n";
case RC_AUTO_NUMBER: case RC_AUTO_NUMBER:
os << "\\auto_number" << tostr(auto_number) << "\n"; os << "\\auto_number" << tostr(auto_number) << "\n";
case RC_MARK_FOREIGN_LANGUAGE:
os << "\\mark_foreign_language " <<
tostr(mark_foreign_language) << "\n";
case RC_LANGUAGE_AUTO_BEGIN: case RC_LANGUAGE_AUTO_BEGIN:
os << "\\language_auto_begin " os << "\\language_auto_begin "
<< tostr(language_auto_begin) << "\n"; << tostr(language_auto_begin) << "\n";

View File

@ -221,6 +221,8 @@ public:
/// ///
bool auto_number; bool auto_number;
/// ///
bool mark_foreign_language;
///
bool show_banner; bool show_banner;
/// Do we have to use a GUI? /// Do we have to use a GUI?
bool use_gui; bool use_gui;

View File

@ -182,7 +182,7 @@ public:
/** returns the column near the specified x-coordinate of the row /** returns the column near the specified x-coordinate of the row
x is set to the real beginning of this column x is set to the real beginning of this column
*/ */
int GetColumnNearX(Row * row, int & x) const; int GetColumnNearX(Row * row, int & x, bool & boundary) const;
/** returns a pointer to a specified row. y is set to the beginning /** returns a pointer to a specified row. y is set to the beginning
of the row of the row
@ -244,13 +244,28 @@ public:
/// ///
void SetCursor(LyXParagraph * par, void SetCursor(LyXParagraph * par,
LyXParagraph::size_type pos, LyXParagraph::size_type pos,
bool setfont = true) const; bool setfont = true,
bool boundary = false) const;
void SetCursor(LyXCursor &, LyXParagraph * par, void SetCursor(LyXCursor &, LyXParagraph * par,
LyXParagraph::size_type pos) const; LyXParagraph::size_type pos,
bool boundary = false) const;
/// ///
void SetCursorIntern(LyXParagraph * par, void SetCursorIntern(LyXParagraph * par,
LyXParagraph::size_type pos, LyXParagraph::size_type pos,
bool setfont = true) const; bool setfont = true,
bool boundary = false) const;
///
void SetCurrentFont() const;
///
bool IsBoundary(LyXParagraph * par,
LyXParagraph::size_type pos) const;
///
bool IsBoundary(LyXParagraph * par,
LyXParagraph::size_type pos,
LyXFont const & font) const;
/// ///
void SetCursorFromCoordinates(int x, long y) const; void SetCursorFromCoordinates(int x, long y) const;
void SetCursorFromCoordinates(LyXCursor &, int x, long y) const; void SetCursorFromCoordinates(LyXCursor &, int x, long y) const;
@ -259,9 +274,13 @@ public:
/// ///
void CursorDown() const; void CursorDown() const;
/// ///
void CursorLeft() const; void CursorLeft(bool internal = true) const;
/// ///
void CursorRight() const; void CursorRight(bool internal = true) const;
///
void CursorLeftIntern(bool internal = true) const;
///
void CursorRightIntern(bool internal = true) const;
/// ///
void CursorLeftOneWord() const; void CursorLeftOneWord() const;
/// ///
@ -469,10 +488,6 @@ public:
/// for external use in lyx_cb.C /// for external use in lyx_cb.C
void SetCursorParUndo(); void SetCursorParUndo();
/// ///
void CursorLeftIntern() const;
///
void CursorRightIntern() const;
///
void RemoveTableRow(LyXCursor * cursor) const; void RemoveTableRow(LyXCursor * cursor) const;
/// ///
bool IsEmptyTableCell() const; bool IsEmptyTableCell() const;
@ -480,6 +495,41 @@ public:
void toggleAppendix(); void toggleAppendix();
/// ///
unsigned short paperWidth() const { return paperwidth; } unsigned short paperWidth() const { return paperwidth; }
///
void ComputeBidiTables(Row *row) const;
/// Maps positions in the visual string to positions in logical string.
inline
LyXParagraph::size_type log2vis(LyXParagraph::size_type pos) const {
if (bidi_start == -1)
return pos;
else
return log2vis_list[pos-bidi_start];
}
/// Maps positions in the logical string to positions in visual string.
inline
LyXParagraph::size_type vis2log(LyXParagraph::size_type pos) const {
if (bidi_start == -1)
return pos;
else
return vis2log_list[pos-bidi_start];
}
inline
int bidi_level(LyXParagraph::size_type pos) const {
if (bidi_start == -1)
return 0;
else
return bidi_levels[pos-bidi_start];
}
inline
bool bidi_InRange(LyXParagraph::size_type pos) const {
return bidi_start == -1 ||
(bidi_start <= pos && pos <= bidi_end);
}
private: private:
/// ///
BufferView * owner_; BufferView * owner_;
@ -612,36 +662,10 @@ private:
mutable LyXParagraph::size_type bidi_start; mutable LyXParagraph::size_type bidi_start;
/// ///
mutable bool bidi_same_direction; mutable LyXParagraph::size_type bidi_end;
/// ///
void ComputeBidiTables(Row *row) const; mutable bool bidi_same_direction;
/// Maps positions in the visual string to positions in logical string.
inline
LyXParagraph::size_type log2vis(LyXParagraph::size_type pos) const {
if (bidi_start == -1)
return pos;
else
return log2vis_list[pos-bidi_start];
}
/// Maps positions in the logical string to positions in visual string.
inline
LyXParagraph::size_type vis2log(LyXParagraph::size_type pos) const {
if (bidi_start == -1)
return pos;
else
return vis2log_list[pos-bidi_start];
}
inline
int bidi_level(LyXParagraph::size_type pos) const {
if (bidi_start == -1)
return 0;
else
return bidi_levels[pos-bidi_start];
}
/// ///
unsigned char TransformChar(unsigned char c, Letter_Form form) const; unsigned char TransformChar(unsigned char c, Letter_Form form) const;

View File

@ -280,26 +280,26 @@ void LyXText::ComputeBidiTables(Row * row) const
bidi_start = -1; bidi_start = -1;
return; return;
} }
LyXParagraph::size_type last = RowLastPrintable(row);
bidi_start = row->pos; bidi_start = row->pos;
bidi_end = RowLastPrintable(row);
if (bidi_start > last) { if (bidi_start > bidi_end) {
bidi_start = -1; bidi_start = -1;
return; return;
} }
if (last + 2 - bidi_start > if (bidi_end + 2 - bidi_start >
static_cast<LyXParagraph::size_type>(log2vis_list.size())) { static_cast<LyXParagraph::size_type>(log2vis_list.size())) {
LyXParagraph::size_type new_size = LyXParagraph::size_type new_size =
(last + 2 - bidi_start < 500) ? (bidi_end + 2 - bidi_start < 500) ?
500 : 2 * (last + 2 - bidi_start); 500 : 2 * (bidi_end + 2 - bidi_start);
log2vis_list.resize(new_size); log2vis_list.resize(new_size);
vis2log_list.resize(new_size); vis2log_list.resize(new_size);
bidi_levels.resize(new_size); bidi_levels.resize(new_size);
} }
vis2log_list[last + 1 - bidi_start] = -1; vis2log_list[bidi_end + 1 - bidi_start] = -1;
log2vis_list[last + 1 - bidi_start] = -1; log2vis_list[bidi_end + 1 - bidi_start] = -1;
LyXParagraph::size_type stack[2]; LyXParagraph::size_type stack[2];
bool rtl_par = row->par->getParLanguage()->RightToLeft; bool rtl_par = row->par->getParLanguage()->RightToLeft;
@ -308,10 +308,11 @@ void LyXText::ComputeBidiTables(Row * row) const
bool rtl0 = false; bool rtl0 = false;
LyXParagraph::size_type main_body = BeginningOfMainBody(row->par); LyXParagraph::size_type main_body = BeginningOfMainBody(row->par);
for (LyXParagraph::size_type lpos = bidi_start; lpos <= last; ++lpos) { for (LyXParagraph::size_type lpos = bidi_start; lpos <= bidi_end; ++lpos) {
bool is_space = row->par->IsLineSeparator(lpos); bool is_space = row->par->IsLineSeparator(lpos);
LyXParagraph::size_type pos = LyXParagraph::size_type pos =
(is_space && lpos+1 <= last && (is_space && lpos+1 <= bidi_end &&
!row->par->IsLineSeparator(lpos+1) &&
(!row->par->table || !row->par->IsNewline(lpos+1)) ) (!row->par->table || !row->par->IsNewline(lpos+1)) )
? lpos + 1 : lpos; ? lpos + 1 : lpos;
LyXFont font = row->par->GetFontSettings(pos); LyXFont font = row->par->GetFontSettings(pos);
@ -367,14 +368,14 @@ void LyXText::ComputeBidiTables(Row * row) const
while (level > 0) { while (level > 0) {
LyXParagraph::size_type old_lpos = stack[--level]; LyXParagraph::size_type old_lpos = stack[--level];
int delta = last - old_lpos; int delta = bidi_end - old_lpos;
if (level % 2) if (level % 2)
delta = -delta; delta = -delta;
log2vis_list[old_lpos - bidi_start] += delta; log2vis_list[old_lpos - bidi_start] += delta;
} }
LyXParagraph::size_type vpos = bidi_start - 1; LyXParagraph::size_type vpos = bidi_start - 1;
for (LyXParagraph::size_type lpos = bidi_start; lpos <= last; ++lpos) { for (LyXParagraph::size_type lpos = bidi_start; lpos <= bidi_end; ++lpos) {
vpos += log2vis_list[lpos - bidi_start]; vpos += log2vis_list[lpos - bidi_start];
vis2log_list[vpos - bidi_start] = lpos; vis2log_list[vpos - bidi_start] = lpos;
log2vis_list[lpos - bidi_start] = vpos; log2vis_list[lpos - bidi_start] = vpos;
@ -382,6 +383,43 @@ void LyXText::ComputeBidiTables(Row * row) const
} }
// This method requires a previous call to ComputeBidiTables()
bool LyXText::IsBoundary(LyXParagraph * par, LyXParagraph::size_type pos) const
{
if (!lyxrc.rtl_support)
return false; // This is just for speedup
if (!bidi_InRange(pos - 1) ||
(par->table && par->IsNewline(pos-1)) )
return false;
bool rtl = bidi_level(pos - 1) % 2;
bool rtl2 = rtl;
if (pos == par->Last() ||
(par->table && par->IsNewline(pos)))
rtl2 = par->isRightToLeftPar();
else if (bidi_InRange(pos))
rtl2 = bidi_level(pos) % 2;
return rtl != rtl2;
}
bool LyXText::IsBoundary(LyXParagraph * par, LyXParagraph::size_type pos,
LyXFont const & font) const
{
if (!lyxrc.rtl_support)
return false; // This is just for speedup
bool rtl = font.isVisibleRightToLeft();
bool rtl2 = rtl;
if (pos == par->Last() ||
(par->table && par->IsNewline(pos)))
rtl2 = par->isRightToLeftPar();
else if (bidi_InRange(pos))
rtl2 = bidi_level(pos) % 2;
return rtl != rtl2;
}
void LyXText::draw(Row const * row, void LyXText::draw(Row const * row,
LyXParagraph::size_type & vpos, LyXParagraph::size_type & vpos,
int offset, float & x) int offset, float & x)
@ -390,6 +428,7 @@ void LyXText::draw(Row const * row,
LyXParagraph::size_type pos = vis2log(vpos); LyXParagraph::size_type pos = vis2log(vpos);
char c = row->par->GetChar(pos); char c = row->par->GetChar(pos);
float tmpx = x;
if (IsNewlineChar(c)) { if (IsNewlineChar(c)) {
++vpos; ++vpos;
@ -492,8 +531,6 @@ void LyXText::draw(Row const * row,
font.setColor(LColor::footnote); font.setColor(LColor::footnote);
float tmpx = x;
// draw it and set new x position // draw it and set new x position
pain.text(int(x), offset + y, fs, font); pain.text(int(x), offset + y, fs, font);
@ -511,6 +548,14 @@ void LyXText::draw(Row const * row,
offset + row->baseline, x); offset + row->baseline, x);
} }
++vpos; ++vpos;
if (lyxrc.mark_foreign_language &&
font.language() != buffer->params.language_info) {
int y = offset + row->baseline + 2;
pain.line(int(tmpx), y, int(x), y,
LColor::language);
}
return; return;
} }
@ -532,7 +577,6 @@ void LyXText::draw(Row const * row,
++vpos; ++vpos;
LyXParagraph::size_type last = RowLastPrintable(row); LyXParagraph::size_type last = RowLastPrintable(row);
float tmpx = x;
if (font.language()->lang == "hebrew") { if (font.language()->lang == "hebrew") {
if (is_nikud(c)) { if (is_nikud(c)) {
@ -597,6 +641,11 @@ void LyXText::draw(Row const * row,
pain.line(int(tmpx), offset + row->baseline + 2, pain.line(int(tmpx), offset + row->baseline + 2,
int(x), offset + row->baseline + 2); int(x), offset + row->baseline + 2);
} else if (lyxrc.mark_foreign_language &&
font.language() != buffer->params.language_info) {
int y = offset + row->baseline + 2;
pain.line(int(tmpx), y, int(x), y,
LColor::language);
} }
// If we want ulem.sty support, drawing // If we want ulem.sty support, drawing
@ -2403,7 +2452,7 @@ void LyXText::InsertCharInTable(char c)
} }
} }
cursor.pos++; ++cursor.pos;
CheckParagraphInTable(cursor.par, cursor.pos); CheckParagraphInTable(cursor.par, cursor.pos);
@ -2439,7 +2488,7 @@ void LyXText::CheckParagraphInTable(LyXParagraph * par,
if (par->table->SetWidthOfCell(NumberOfCell(par, pos), if (par->table->SetWidthOfCell(NumberOfCell(par, pos),
WidthOfCell(par, tmp_pos))) { WidthOfCell(par, tmp_pos))) {
LyXCursor tmpcursor = cursor; LyXCursor tmpcursor = cursor;
SetCursorIntern(par, pos); SetCursorIntern(par, pos, false);
/* make a complete redraw */ /* make a complete redraw */
RedoDrawingOfParagraph(cursor); RedoDrawingOfParagraph(cursor);
cursor = tmpcursor; cursor = tmpcursor;
@ -2460,7 +2509,7 @@ void LyXText::CheckParagraphInTable(LyXParagraph * par,
else else
status = LyXText::NEED_MORE_REFRESH; status = LyXText::NEED_MORE_REFRESH;
} }
SetCursorIntern(cursor.par, cursor.pos); SetCursorIntern(cursor.par, cursor.pos, false, cursor.boundary);
} }
@ -2525,7 +2574,9 @@ void LyXText::BackspaceInTable()
current_font = rawtmpfont; current_font = rawtmpfont;
real_current_font = realtmpfont; real_current_font = realtmpfont;
} }
SetCursorIntern(cursor.par, cursor.pos); SetCursorIntern(cursor.par, cursor.pos, true, cursor.boundary);
if (IsBoundary(cursor.par, cursor.pos) != cursor.boundary)
SetCursor(cursor.par, cursor.pos, false, !cursor.boundary);
} }
/* table stuff -- end*/ /* table stuff -- end*/
@ -2666,7 +2717,7 @@ void LyXText::InsertChar(char c)
current_font = rawtmpfont; current_font = rawtmpfont;
real_current_font = realtmpfont; real_current_font = realtmpfont;
SetCursor(cursor.par, cursor.pos + 1, false); SetCursor(cursor.par, cursor.pos + 1, false, cursor.boundary);
/* cursor MUST be in row now */ /* cursor MUST be in row now */
if (row->next && row->next->par == row->par) if (row->next && row->next->par == row->par)
@ -2706,7 +2757,7 @@ void LyXText::InsertChar(char c)
} }
current_font = rawtmpfont; current_font = rawtmpfont;
real_current_font = realtmpfont; real_current_font = realtmpfont;
SetCursor(cursor.par, cursor.pos + 1, false); SetCursor(cursor.par, cursor.pos + 1, false, cursor.boundary);
if (row->next && row->next->par == row->par) if (row->next && row->next->par == row->par)
need_break_row = row->next; need_break_row = row->next;
else else
@ -2726,7 +2777,7 @@ void LyXText::InsertChar(char c)
current_font = rawtmpfont; current_font = rawtmpfont;
real_current_font = realtmpfont; real_current_font = realtmpfont;
SetCursor(cursor.par, cursor.pos + 1, false); SetCursor(cursor.par, cursor.pos + 1, false, cursor.boundary);
} }
/* check, wether the last characters font has changed. */ /* check, wether the last characters font has changed. */
@ -3298,12 +3349,14 @@ void LyXText::Backspace()
return; return;
} }
/* table stuff -- end */ /* table stuff -- end */
// LyXFont rawtmpfont = current_font;
// LyXFont realtmpfont = real_current_font;
// We don't need the above variables as calling to SetCursor() with third
// argument eqaul to false, will not change current_font & real_current_font
LyXFont rawtmpfont = current_font;
LyXFont realtmpfont = real_current_font;
// Get the font that is used to calculate the baselineskip // Get the font that is used to calculate the baselineskip
int const lastpos = cursor.par->Last(); LyXParagraph::size_type lastpos = cursor.par->Last();
LyXFont rawparfont = cursor.par->GetFontSettings(lastpos - 1); LyXFont rawparfont = cursor.par->GetFontSettings(lastpos - 1);
if (cursor.pos == 0) { if (cursor.pos == 0) {
@ -3365,7 +3418,7 @@ void LyXText::Backspace()
if (cursor.par->Previous()) { if (cursor.par->Previous()) {
// steps into the above paragraph. // steps into the above paragraph.
SetCursorIntern(cursor.par->Previous(), SetCursorIntern(cursor.par->Previous(),
cursor.par->Previous()->Last()); cursor.par->Previous()->Last(), false);
} }
/* Pasting is not allowed, if the paragraphs have different /* Pasting is not allowed, if the paragraphs have different
@ -3416,7 +3469,7 @@ void LyXText::Backspace()
UpdateCounters(cursor.row); UpdateCounters(cursor.row);
// the row may have changed, block, hfills etc. // the row may have changed, block, hfills etc.
SetCursor(cursor.par, cursor.pos); SetCursor(cursor.par, cursor.pos, false);
} }
} else { } else {
/* this is the code for a normal backspace, not pasting /* this is the code for a normal backspace, not pasting
@ -3428,7 +3481,7 @@ void LyXText::Backspace()
// not a good idea since it triggers the auto-delete // not a good idea since it triggers the auto-delete
// mechanism. So we do a CursorLeftIntern()-lite, // mechanism. So we do a CursorLeftIntern()-lite,
// without the dreaded mechanism. (JMarc) // without the dreaded mechanism. (JMarc)
SetCursorIntern(cursor.par, cursor.pos - 1); SetCursorIntern(cursor.par, cursor.pos - 1, false, cursor.boundary);
// some insets are undeletable here // some insets are undeletable here
if (cursor.par->GetChar(cursor.pos) == LyXParagraph::META_INSET) { if (cursor.par->GetChar(cursor.pos) == LyXParagraph::META_INSET) {
@ -3529,12 +3582,12 @@ void LyXText::Backspace()
refresh_y = y; refresh_y = y;
refresh_row = tmprow; refresh_row = tmprow;
status = LyXText::NEED_MORE_REFRESH; status = LyXText::NEED_MORE_REFRESH;
current_font = rawtmpfont; SetCursor(cursor.par, cursor.pos, false, cursor.boundary);
real_current_font = realtmpfont; //current_font = rawtmpfont;
SetCursor(cursor.par, cursor.pos, false); //real_current_font = realtmpfont;
// check, whether the last character's font has changed. // check, whether the last character's font has changed.
rawtmpfont = cursor.par->GetFontSettings(cursor.par->Last() - 1); if (rawparfont !=
if (rawparfont != rawtmpfont) cursor.par->GetFontSettings(cursor.par->Last() - 1))
RedoHeightOfParagraph(cursor); RedoHeightOfParagraph(cursor);
return; return;
} }
@ -3560,9 +3613,7 @@ void LyXText::Backspace()
status = LyXText::NEED_MORE_REFRESH; status = LyXText::NEED_MORE_REFRESH;
BreakAgainOneRow(row); BreakAgainOneRow(row);
current_font = rawtmpfont; SetCursor(cursor.par, cursor.pos, false, cursor.boundary);
real_current_font = realtmpfont;
SetCursor(cursor.par, cursor.pos, false);
// cursor MUST be in row now // cursor MUST be in row now
if (row->next && row->next->par == row->par) if (row->next && row->next->par == row->par)
@ -3580,19 +3631,23 @@ void LyXText::Backspace()
status = LyXText::NEED_MORE_REFRESH; status = LyXText::NEED_MORE_REFRESH;
refresh_y = y; refresh_y = y;
refresh_row = row; refresh_row = row;
current_font = rawtmpfont; SetCursor(cursor.par, cursor.pos, false, cursor.boundary);
real_current_font = realtmpfont;
SetCursor(cursor.par, cursor.pos, false);
} }
} }
// restore the current font
// That is what a user expects! // current_font = rawtmpfont;
current_font = rawtmpfont; // real_current_font = realtmpfont;
real_current_font = realtmpfont;
lastpos = cursor.par->Last();
if (cursor.pos == lastpos) {
SetCurrentFont();
if (IsBoundary(cursor.par, cursor.pos) != cursor.boundary)
SetCursor(cursor.par, cursor.pos, false, !cursor.boundary);
}
// check, wether the last characters font has changed. // check, wether the last characters font has changed.
rawtmpfont = cursor.par->GetFontSettings(cursor.par->Last() - 1); if (rawparfont !=
if (rawparfont != rawtmpfont) { cursor.par->GetFontSettings(lastpos - 1)) {
RedoHeightOfParagraph(cursor); RedoHeightOfParagraph(cursor);
} else { } else {
// now the special right address boxes // now the special right address boxes
@ -4444,7 +4499,7 @@ int LyXText::DefaultHeight() const
/* returns the column near the specified x-coordinate of the row /* returns the column near the specified x-coordinate of the row
* x is set to the real beginning of this column */ * x is set to the real beginning of this column */
int LyXText::GetColumnNearX(Row * row, int & x) const int LyXText::GetColumnNearX(Row * row, int & x, bool & boundary) const
{ {
float tmpx = 0.0; float tmpx = 0.0;
float fill_separator, fill_hfill, fill_label_hfill; float fill_separator, fill_hfill, fill_label_hfill;
@ -4457,6 +4512,8 @@ int LyXText::GetColumnNearX(Row * row, int & x) const
LyXParagraph::size_type c = 0; LyXParagraph::size_type c = 0;
LyXLayout const & layout = textclasslist.Style(buffer->params.textclass, LyXLayout const & layout = textclasslist.Style(buffer->params.textclass,
row->par->GetLayout()); row->par->GetLayout());
bool left_side = false;
/* table stuff -- begin */ /* table stuff -- begin */
if (row->par->table) { if (row->par->table) {
//the last row doesn't need a newline at the end //the last row doesn't need a newline at the end
@ -4464,26 +4521,29 @@ int LyXText::GetColumnNearX(Row * row, int & x) const
&& row->par->IsNewline(last)) && row->par->IsNewline(last))
last--; last--;
int cell = NumberOfCell(row->par, row->pos); int cell = NumberOfCell(row->par, row->pos);
float x_old = tmpx; float cell_x = tmpx + row->par->table->WidthOfColumn(cell);
bool ready = false;
tmpx += row->par->table->GetBeginningOfTextInCell(cell); tmpx += row->par->table->GetBeginningOfTextInCell(cell);
while (vc <= last float last_tmpx = tmpx;
&& (c = vis2log(vc)) >= 0 while (vc <= last && tmpx <= x) {
&& tmpx + (SingleWidth(row->par, c)/2) <= x c = vis2log(vc);
&& !ready){ last_tmpx = tmpx;
if (row->par->IsNewline(c)) { if (row->par->IsNewline(c)) {
if (x_old + row->par->table->WidthOfColumn(cell) <= x){ if (cell_x <= x){
tmpx = x_old + row->par->table->WidthOfColumn(cell); ++cell;
x_old = tmpx; tmpx = cell_x + row->par->table->GetBeginningOfTextInCell(cell);
++cell; cell_x += row->par->table->WidthOfColumn(cell);
tmpx += row->par->table->GetBeginningOfTextInCell(cell); ++vc;
++vc; } else
} else break;
ready = true; } else {
} else { tmpx += SingleWidth(row->par, c);
tmpx += SingleWidth(row->par, c); ++vc;
++vc; }
} }
if (vc > row->pos && !row->par->IsNewline(c) &&
(tmpx+last_tmpx)/2 > x) {
tmpx = last_tmpx;
left_side = true;
} }
} else { } else {
/* table stuff -- end*/ /* table stuff -- end*/
@ -4523,28 +4583,31 @@ int LyXText::GetColumnNearX(Row * row, int & x) const
} }
if (vc > row->pos && (tmpx+last_tmpx)/2 > x) { if (vc > row->pos && (tmpx+last_tmpx)/2 > x) {
vc--;
tmpx = last_tmpx; tmpx = last_tmpx;
left_side = true;
} }
} }
if (vc > last + 1) // This shouldn't happen. if (vc > last + 1) // This shouldn't happen.
vc = last+1; vc = last+1;
boundary = false;
if (row->pos > last) // Row is empty? if (row->pos > last) // Row is empty?
c = row->pos; c = row->pos;
else if (vc > last || else if (vc == row->pos ||
(vc - 1 >= row->pos && (row->par->table && vc <= last && row->par->IsNewline(vc-1)) ) {
( (row->par->IsSeparator(vis2log(vc)) && vis2log(vc) != last)
|| (row->par->table && row->par->IsNewline(vc) )
))) {
c = vis2log(vc - 1);
if (bidi_level(c) % 2 == 0)
++c;
} else {
c = vis2log(vc); c = vis2log(vc);
if (bidi_level(c) % 2 == 1) if (bidi_level(c) % 2 == 1)
++c; ++c;
} else {
c = vis2log(vc - 1);
bool rtl = (bidi_level(c) % 2 == 1);
if (left_side == rtl) {
++c;
boundary = IsBoundary(row->par, c);
}
} }
if (!row->par->table && row->pos <= last && c > last if (!row->par->table && row->pos <= last && c > last

View File

@ -846,7 +846,7 @@ void LyXText::SetFont(LyXFont const & font, bool toggleall)
SetCursor(sel_end_cursor.par, sel_end_cursor.pos); SetCursor(sel_end_cursor.par, sel_end_cursor.pos);
ClearSelection(); ClearSelection();
SetSelection(); SetSelection();
SetCursor(tmpcursor.par, tmpcursor.pos); SetCursor(tmpcursor.par, tmpcursor.pos, true, tmpcursor.boundary);
} }
@ -875,7 +875,7 @@ void LyXText::RedoHeightOfParagraph(LyXCursor const & cur)
status = LyXText::NEED_MORE_REFRESH; status = LyXText::NEED_MORE_REFRESH;
refresh_y = y; refresh_y = y;
refresh_row = tmprow; refresh_row = tmprow;
SetCursor(cur.par, cur.pos); SetCursor(cur.par, cur.pos, false, cursor.boundary);
} }
@ -1054,8 +1054,8 @@ void LyXText::SetSelection()
} }
// a selection with no contents is not a selection // a selection with no contents is not a selection
if (sel_start_cursor.x == sel_end_cursor.x && if (sel_start_cursor.par == sel_end_cursor.par &&
sel_start_cursor.y == sel_end_cursor.y) sel_start_cursor.pos == sel_end_cursor.pos)
selection = false; selection = false;
// Stuff what we got on the clipboard. Even if there is no selection. // Stuff what we got on the clipboard. Even if there is no selection.
@ -3115,16 +3115,17 @@ int LyXText::UpdateInset(Inset * inset)
void LyXText::SetCursor(LyXParagraph * par, void LyXText::SetCursor(LyXParagraph * par,
LyXParagraph::size_type pos, bool setfont) const LyXParagraph::size_type pos,
bool setfont, bool boundary) const
{ {
LyXCursor old_cursor = cursor; LyXCursor old_cursor = cursor;
SetCursorIntern(par, pos, setfont); SetCursorIntern(par, pos, setfont, boundary);
DeleteEmptyParagraphMechanism(old_cursor); DeleteEmptyParagraphMechanism(old_cursor);
} }
void LyXText::SetCursor(LyXCursor & cur, LyXParagraph * par, void LyXText::SetCursor(LyXCursor & cur, LyXParagraph * par,
LyXParagraph::size_type pos) const LyXParagraph::size_type pos, bool boundary) const
{ {
// correct the cursor position if impossible // correct the cursor position if impossible
if (pos > par->Last()){ if (pos > par->Last()){
@ -3154,6 +3155,7 @@ void LyXText::SetCursor(LyXCursor & cur, LyXParagraph * par,
cur.par = par; cur.par = par;
cur.pos = pos; cur.pos = pos;
cur.boundary = boundary;
/* get the cursor y position in text */ /* get the cursor y position in text */
long y = 0; long y = 0;
@ -3175,16 +3177,18 @@ void LyXText::SetCursor(LyXCursor & cur, LyXParagraph * par,
if (last < row->pos) if (last < row->pos)
cursor_vpos = 0; cursor_vpos = 0;
else if ((pos > last) || else if (pos > last && !boundary)
((pos - 1 >= row->pos) && cursor_vpos = (row->par->isRightToLeftPar())
(row->par->IsSeparator(pos) || ? row->pos : last+1;
(row->par->table && row->par->IsNewline(pos))))) else if (pos > row->pos &&
(pos > last || boundary ||
(row->par->table && row->par->IsNewline(pos))))
/// Place cursor after char at (logical) position pos-1 /// Place cursor after char at (logical) position pos-1
cursor_vpos = !(bidi_level(pos-1) % 2) cursor_vpos = (bidi_level(pos-1) % 2 == 0)
? log2vis(pos-1) + 1 : log2vis(pos-1); ? log2vis(pos-1) + 1 : log2vis(pos-1);
else else
/// Place cursor before char at (logical) position pos /// Place cursor before char at (logical) position pos
cursor_vpos = !(bidi_level(pos) % 2) cursor_vpos = (bidi_level(pos) % 2 == 0)
? log2vis(pos) : log2vis(pos) + 1; ? log2vis(pos) : log2vis(pos) + 1;
/* table stuff -- begin*/ /* table stuff -- begin*/
@ -3248,9 +3252,10 @@ void LyXText::SetCursor(LyXCursor & cur, LyXParagraph * par,
void LyXText::SetCursorIntern(LyXParagraph * par, void LyXText::SetCursorIntern(LyXParagraph * par,
LyXParagraph::size_type pos, bool setfont) const LyXParagraph::size_type pos,
bool setfont, bool boundary) const
{ {
SetCursor(cursor, par, pos); SetCursor(cursor, par, pos, boundary);
// #warning Remove this when verified working (Jug 20000413) // #warning Remove this when verified working (Jug 20000413)
#if 0 #if 0
// correct the cursor position if impossible // correct the cursor position if impossible
@ -3369,18 +3374,32 @@ void LyXText::SetCursorIntern(LyXParagraph * par,
cursor.x_fix = cursor.x; cursor.x_fix = cursor.x;
cursor.row = row; cursor.row = row;
#endif #endif
if (setfont) { if (setfont)
if (cursor.pos && SetCurrentFont();
(cursor.pos == cursor.par->Last() || cursor.par->IsSeparator(cursor.pos) }
|| (cursor.par->table && cursor.par->IsNewline(cursor.pos))
)) { void LyXText::SetCurrentFont() const
current_font = cursor.par->GetFontSettings(cursor.pos - 1); {
real_current_font = GetFont(cursor.par, cursor.pos - 1); LyXParagraph::size_type pos = cursor.pos;
} else { if (cursor.boundary && pos > 0)
current_font = cursor.par->GetFontSettings(cursor.pos); --pos;
real_current_font = GetFont(cursor.par, cursor.pos);
if (pos > 0) {
if (pos == cursor.par->Last() ||
(cursor.par->table && cursor.par->IsNewline(pos)))
--pos;
else if (cursor.par->IsSeparator(pos)) {
if (pos > cursor.row->pos &&
bidi_level(pos) % 2 ==
bidi_level(pos - 1) % 2)
--pos;
else if (pos + 1 < cursor.par->Last())
++pos;
} }
} }
current_font = cursor.par->GetFontSettings(pos);
real_current_font = GetFont(cursor.par, pos);
} }
@ -3391,29 +3410,14 @@ void LyXText::SetCursorFromCoordinates(int x, long y) const
/* get the row first */ /* get the row first */
Row * row = GetRowNearY(y); Row * row = GetRowNearY(y);
cursor.par = row->par; cursor.par = row->par;
int column = GetColumnNearX(row, x); int column = GetColumnNearX(row, x, cursor.boundary);
cursor.pos = row->pos + column; cursor.pos = row->pos + column;
cursor.x = x; cursor.x = x;
cursor.y = y + row->baseline; cursor.y = y + row->baseline;
cursor.row = row; cursor.row = row;
SetCurrentFont();
if (cursor.pos &&
(cursor.pos == cursor.par->Last()
|| cursor.par->IsSeparator(cursor.pos)
|| (cursor.pos && cursor.pos == BeginningOfMainBody(cursor.par)
&& !cursor.par->IsSeparator(cursor.pos))
|| (cursor.par->table && cursor.par->IsNewline(cursor.pos))
)) {
current_font = cursor.par->GetFontSettings(cursor.pos - 1);
real_current_font = GetFont(cursor.par, cursor.pos - 1);
} else {
current_font = cursor.par->GetFontSettings(cursor.pos);
real_current_font = GetFont(cursor.par, cursor.pos);
}
DeleteEmptyParagraphMechanism(old_cursor); DeleteEmptyParagraphMechanism(old_cursor);
} }
@ -3422,7 +3426,7 @@ void LyXText::SetCursorFromCoordinates(LyXCursor & cur, int x, long y) const
/* get the row first */ /* get the row first */
Row * row = GetRowNearY(y); Row * row = GetRowNearY(y);
int column = GetColumnNearX(row, x); int column = GetColumnNearX(row, x, cur.boundary);
cur.par = row->par; cur.par = row->par;
cur.pos = row->pos + column; cur.pos = row->pos + column;
@ -3432,9 +3436,9 @@ void LyXText::SetCursorFromCoordinates(LyXCursor & cur, int x, long y) const
} }
void LyXText::CursorLeft() const void LyXText::CursorLeft(bool internal) const
{ {
CursorLeftIntern(); CursorLeftIntern(internal);
if (cursor.par->table) { if (cursor.par->table) {
int cell = NumberOfCell(cursor.par, cursor.pos); int cell = NumberOfCell(cursor.par, cursor.pos);
if (cursor.par->table->IsContRow(cell) && if (cursor.par->table->IsContRow(cell) &&
@ -3445,20 +3449,27 @@ void LyXText::CursorLeft() const
} }
void LyXText::CursorLeftIntern() const void LyXText::CursorLeftIntern(bool internal) const
{ {
if (cursor.pos > 0) { if (cursor.pos > 0) {
SetCursor(cursor.par, cursor.pos - 1); bool boundary = cursor.boundary;
} SetCursor(cursor.par, cursor.pos - 1, true, false);
else if (cursor.par->Previous()) { // steps into the above paragraph. if (!internal && !boundary &&
SetCursor(cursor.par->Previous(), cursor.par->Previous()->Last()); IsBoundary(cursor.par, cursor.pos + 1))
SetCursor(cursor.par, cursor.pos + 1, true, true);
} else if (cursor.par->Previous()) { // steps into the above paragraph.
LyXParagraph * par = cursor.par->Previous();
LyXParagraph::size_type pos = par->Last();
SetCursor(par, pos);
if (IsBoundary(par, pos))
SetCursor(par, pos, false, true);
} }
} }
void LyXText::CursorRight() const void LyXText::CursorRight(bool internal) const
{ {
CursorRightIntern(); CursorRightIntern(internal);
if (cursor.par->table) { if (cursor.par->table) {
int cell = NumberOfCell(cursor.par, cursor.pos); int cell = NumberOfCell(cursor.par, cursor.pos);
if (cursor.par->table->IsContRow(cell) && if (cursor.par->table->IsContRow(cell) &&
@ -3469,14 +3480,19 @@ void LyXText::CursorRight() const
} }
void LyXText::CursorRightIntern() const void LyXText::CursorRightIntern(bool internal) const
{ {
if (cursor.pos < cursor.par->Last()) { if (cursor.pos < cursor.par->Last()) {
SetCursor(cursor.par, cursor.pos + 1); if (!internal && cursor.boundary &&
} (!cursor.par->table || !cursor.par->IsNewline(cursor.pos)))
else if (cursor.par->Next()) { SetCursor(cursor.par, cursor.pos, true, false);
else {
SetCursor(cursor.par, cursor.pos + 1, true, false);
if (!internal && IsBoundary(cursor.par, cursor.pos))
SetCursor(cursor.par, cursor.pos, true, true);
}
} else if (cursor.par->Next())
SetCursor(cursor.par->Next(), 0); SetCursor(cursor.par->Next(), 0);
}
} }