bool tmp = refreshInside;
if (!in || !in->wide()) {
refreshInside = true;
- if (lyxerr.debugging(Debug::PAINTING)) {
- lyxerr << endl << "Paint inset fully" << endl;
- }
+ LYXERR(Debug::PAINTING) << endl << "Paint inset fully" << endl;
}
if (refreshInside)
inset->drawSelection(pi, int(x_), yo_);
if (isPrintableNonspace(c)) {
int const width2 = text_.singleWidth(par_, i, c,
text_.getFont(*bv_.buffer(), par_, i));
- // FIXME UNICODE
- // This does not work anymore, and non-ascii
- // characters in source files are forbidden
- // anyway.
- // dalet / resh
- dx = (c == 'ø' || c == 'ã')
+ dx = (c == 0x05e8 || // resh
+ c == 0x05d3) // dalet
? width2 - width
: (width2 - width) / 2;
}
}
// Draw nikud
- // FIXME UNICODE
pain_.text(int(x_) + dx, yo_, str, font);
}
pain_.text(int(x_) + dx, yo_, str, font);
}
+
void RowPainter::paintChars(pos_type & vpos, LyXFont const & font,
bool hebrew, bool arabic)
{
if (!isPrintableNonspace(c))
break;
+ /* Because we do our own bidi, at this point the strings are
+ * already in visual order. However, Qt also applies its own
+ * bidi algorithm to strings that it paints to the screen.
+ * Therefore, if we were to paint Hebrew/Arabic words as a
+ * single string, the letters in the words would get reversed
+ * again. In order to avoid that, we don't collect Hebrew/
+ * Arabic characters, but rather paint them one at a time.
+ * See also http://thread.gmane.org/gmane.editors.lyx.devel/79740
+ */
+ if (hebrew)
+ break;
+
+ /* FIXME: these checks are irrelevant, since 'arabic' and
+ * 'hebrew' alone are already going to trigger a break.
+ * However, this should not be removed completely, because
+ * if an alternative solution is found which allows grouping
+ * of arabic and hebrew characters, then these breaks may have
+ * to be re-applied.
+
if (arabic && Encodings::isComposeChar_arabic(c))
break;
if (hebrew && Encodings::isComposeChar_hebrew(c))
break;
+ */
- if (arabic)
+ if (arabic) {
c = par_.transformChar(c, pos);
+ /* see comment in hebrew, explaining why we break */
+ break;
+ }
str.push_back(c);
}
+ docstring s(&str[0], str.size());
+
if (prev_change != Change::UNCHANGED) {
LyXFont copy(font);
if (prev_change == Change::DELETED) {
} else if (prev_change == Change::INSERTED) {
copy.setColor(LColor::newtext);
}
- x_ += pain_.text(int(x_), yo_, &str[0], str.size(), copy);
+ x_ += pain_.text(int(x_), yo_, s, copy);
} else {
- x_ += pain_.text(int(x_), yo_, &str[0], str.size(), font);
+ x_ += pain_.text(int(x_), yo_, s, font);
}
}
// special case languages
std::string const & lang = orig_font.language()->lang();
bool const hebrew = lang == "hebrew";
- bool const arabic = lang == "arabic" &&
- (lyxrc.font_norm_type == LyXRC::ISO_8859_6_8 ||
- lyxrc.font_norm_type == LyXRC::ISO_10646_1);
+ bool const arabic = lang == "arabic";
// draw as many chars as we can
if ((!hebrew && !arabic)
}
+// FIXME: once wide() is obsolete, remove this as well!
+bool inNarrowInset(PainterInfo & pi)
+{
+ // check whether the current inset is nested in a non-wide inset
+ LCursor & cur = pi.base.bv->cursor();
+ for (int i = cur.depth() - 1; --i >= 0; ) {
+ InsetBase * const in = &cur[i].inset();
+ if (in) {
+ InsetText * t =
+ const_cast<InsetText *>(in->asTextInset());
+ if (t)
+ return !t->wide();
+ }
+ }
+ return false;
+}
+
+
void paintPar
(PainterInfo & pi, LyXText const & text, pit_type pit, int x, int y,
bool repaintAll)
bool row_has_changed = pm.rowChangeStatus()[rowno];
bool cursor_on_row = CursorOnRow(pi, pit, rit, text);
- bool in_inset_alone_on_row = innerCursorOnRow(pi, pit, rit,
- text);
+ bool in_inset_alone_on_row =
+ innerCursorOnRow(pi, pit, rit, text);
bool leftEdgeFixed =
(par.getAlign() == LYX_ALIGN_LEFT ||
par.getAlign() == LYX_ALIGN_BLOCK);
+ bool inNarrowIns = inNarrowInset(pi);
// If this is the only object on the row, we can make it wide
//
// to touch the paragraph contents. So either we move this "wide"
// property out of InsetText or we localize the feature to the painting
// done here.
+ // JSpitzm: We should aim at removing wide() altogether while retaining
+ // typing speed within insets.
for (pos_type i = rit->pos() ; i != rit->endpos(); ++i) {
InsetBase const * const in = par.getInset(i);
if (in) {
InsetText * t = const_cast<InsetText *>(in->asTextInset());
if (t)
- t->setWide(in_inset_alone_on_row && leftEdgeFixed);
+ t->setWide(in_inset_alone_on_row
+ && leftEdgeFixed
+ && !inNarrowIns);
}
}
// 12 lines lower):
if (lyxerr.debugging(Debug::PAINTING)) {
if (text.isMainText(*pi.base.bv->buffer()))
- lyxerr[Debug::PAINTING] << "#";
+ LYXERR(Debug::PAINTING) << "#";
else
- lyxerr[Debug::PAINTING] << "[" <<
+ LYXERR(Debug::PAINTING) << "[" <<
repaintAll << row_has_changed <<
cursor_on_row << "]";
}
// Re-enable screen drawing for future use of the painter.
pi.pain.setDrawingEnabled(true);
- if (lyxerr.debugging(Debug::PAINTING)) {
- lyxerr[Debug::PAINTING] << "." << endl;
- }
+ LYXERR(Debug::PAINTING) << "." << endl;
}
} // namespace anon
PainterInfo pi(const_cast<BufferView *>(&bv), pain);
// Should the whole screen, including insets, be refreshed?
- bool repaintAll = select || !vi.singlepar;
+ // FIXME: We should also distinguish DecorationUpdate to avoid text
+ // drawing if possible. This is not possible to do easily right now
+ // because of the single backing pixmap.
+ bool repaintAll = select || vi.update_strategy != SingleParUpdate;
if (repaintAll) {
// Clear background (if not delegated to rows)
// and grey out above (should not happen later)
// lyxerr << "par ascent: " << text.getPar(vi.p1).ascent() << endl;
- if (vi.y1 > 0 && !vi.singlepar)
+ if (vi.y1 > 0 && vi.update_strategy != SingleParUpdate)
pain.fillRectangle(0, 0, bv.workWidth(), vi.y1, LColor::bottomarea);
// and possibly grey out below
// lyxerr << "par descent: " << text.getPar(vi.p1).ascent() << endl;
- if (vi.y2 < bv.workHeight() && !vi.singlepar)
+ if (vi.y2 < bv.workHeight() && vi.update_strategy != SingleParUpdate)
pain.fillRectangle(0, vi.y2, bv.workWidth(), bv.workHeight() - vi.y2, LColor::bottomarea);
}