From cc845ed2cf82d07c03da6dabf63a54e472b2d16e Mon Sep 17 00:00:00 2001 From: Juergen Spitzmueller Date: Sun, 15 Jul 2018 14:26:29 +0200 Subject: [PATCH] Fix bracket output in RTL languages This is a real mess! Fixes: #11187 (cherry picked from commit 195f62ac9322285bf4c6e16ec5081cc4c216e066) --- src/Paragraph.cpp | 66 ++++++++++++++++++++++++++++------------ src/Paragraph.h | 3 +- src/output_plaintext.cpp | 2 +- status.23x | 3 +- 4 files changed, 51 insertions(+), 23 deletions(-) diff --git a/src/Paragraph.cpp b/src/Paragraph.cpp index 350418c564..b437cde060 100644 --- a/src/Paragraph.cpp +++ b/src/Paragraph.cpp @@ -1181,10 +1181,7 @@ void Paragraph::Private::latexSpecialChar(otexstream & os, pos_type end_pos, unsigned int & column) { - // With polyglossia, brackets and stuff need not be reversed - // in RTL scripts (see bug #8251) - char_type const c = (runparams.use_polyglossia) ? - owner_->getUChar(bparams, i) : text_[i]; + char_type const c = owner_->getUChar(bparams, runparams, i); if (style.pass_thru || runparams.pass_thru || contains(style.pass_thru_chars, c) @@ -1903,32 +1900,60 @@ Font const Paragraph::getLayoutFont } -char_type Paragraph::getUChar(BufferParams const & bparams, pos_type pos) const +char_type Paragraph::getUChar(BufferParams const & bparams, + OutputParams const & rp, + pos_type pos) const { char_type c = d->text_[pos]; + + // Return unchanged character in LTR languages. if (!getFontSettings(bparams, pos).isRightToLeft()) return c; - // FIXME: The arabic special casing is due to the difference of arabic - // round brackets input introduced in r18599. Check if this should be - // unified with Hebrew or at least if all bracket types should be - // handled the same (file format change in either case). + // FIXME This is a complete mess due to all the language-specific + // special cases. We need to unify this eventually, but this + // requires a file format change and some thought. + // We also need to unify the input of parentheses in different RTL + // languages. Currently, some have their own methods (Arabic: + // 18599/lyxsvn, Hebrew: e5f42f67d/lyxgit), some don't (Urdu, Syriac). + // Also note that the representation in the LyX file is probably wrong + // (see FIXME in TextMetrics::breakRow). + // Most likely, we should simply rely on Qt's unicode handling here. string const & lang = getFontSettings(bparams, pos).language()->lang(); - bool const arabic = lang == "arabic_arabtex" || lang == "arabic_arabi" - || lang == "farsi"; + + // With polyglossia, brackets and stuff need not be reversed in RTL scripts + // FIXME: The special casing for Hebrew parens is due to the special + // handling on input (for Hebrew in e5f42f67d/lyxgit); see #8251. char_type uc = c; + if (rp.use_polyglossia) { + switch (c) { + case '(': + if (lang == "hebrew") + uc = ')'; + break; + case ')': + if (lang == "hebrew") + uc = '('; + break; + } + return uc; + } + + // In the following languages, brackets don't need to be reversed. + // Furthermore, in arabic_arabi, they are transformed to Arabic + // Ornate Parentheses (dunno if this is really wanted) + bool const reversebrackets = lang != "arabic_arabtex" + && lang != "arabic_arabi" + && lang != "farsi"; + switch (c) { - case '(': - uc = arabic ? c : ')'; - break; - case ')': - uc = arabic ? c : '('; - break; case '[': - uc = ']'; + if (reversebrackets) + uc = ']'; break; case ']': - uc = '['; + if (reversebrackets) + uc = '['; break; case '{': uc = '}'; @@ -3293,7 +3318,8 @@ docstring Paragraph::simpleLyXHTMLOnePar(Buffer const & buf, retval += inset->xhtml(xs, np); } } else { - char_type c = getUChar(buf.masterBuffer()->params(), i); + char_type c = getUChar(buf.masterBuffer()->params(), + runparams, i); xs << c; } font_old = font.fontInfo(); diff --git a/src/Paragraph.h b/src/Paragraph.h index 0c6c48090f..31157b5ea2 100644 --- a/src/Paragraph.h +++ b/src/Paragraph.h @@ -358,7 +358,8 @@ public: /// char_type getChar(pos_type pos) const; /// Get the char, but mirror all bracket characters if it is right-to-left - char_type getUChar(BufferParams const &, pos_type pos) const; + char_type getUChar(BufferParams const &, OutputParams const &, + pos_type pos) const; /// pos <= size() (there is a dummy font change at the end of each par) void setFont(pos_type pos, Font const & font); /// diff --git a/src/output_plaintext.cpp b/src/output_plaintext.cpp index 15e700eb8f..8c5655d39b 100644 --- a/src/output_plaintext.cpp +++ b/src/output_plaintext.cpp @@ -188,7 +188,7 @@ void writePlaintextParagraph(Buffer const & buf, if (os.str().size() > max_length) break; - char_type c = par.getUChar(buf.params(), i); + char_type c = par.getUChar(buf.params(), runparams, i); if (par.isInset(i) || c == ' ') { if (runparams.linelen > 0 && diff --git a/status.23x b/status.23x index 716556e212..54a9cfd0c0 100644 --- a/status.23x +++ b/status.23x @@ -271,7 +271,8 @@ What's new - Improve warning message dialogs. -- Fix insertion of quotation marks in RTL languages (bug 11188). +- Fix insertion of quotation marks and brackets in RTL languages + (bugs 11188 and 11187). * INTERNALS