--- lyx-2.0.0/src/frontends/qt4/GuiPainter.cpp.org 2010-10-10 17:32:40.758279893 +0900 +++ lyx-2.0.0/src/frontends/qt4/GuiPainter.cpp 2010-10-10 19:27:33.813963208 +0900 @@ -499,37 +499,37 @@ } -int GuiPainter::preeditText(int x, int y, char_type c, - FontInfo const & font, preedit_style style) -{ - FontInfo temp_font = font; - FontMetrics const & fm = theFontMetrics(font); - int ascent = fm.maxAscent(); - int descent = fm.maxDescent(); - int height = ascent + descent; - int width = fm.width(c); - - switch (style) { - case preedit_default: - // default unselecting mode. - fillRectangle(x, y - height + 1, width, height, Color_background); - dashedUnderline(font, x, y - descent + 1, width); - break; - case preedit_selecting: - // We are in selecting mode: white text on black background. - fillRectangle(x, y - height + 1, width, height, Color_black); - temp_font.setColor(Color_white); - break; - case preedit_cursor: - // The character comes with a cursor. - fillRectangle(x, y - height + 1, width, height, Color_background); - underline(font, x, y - descent + 1, width); - break; - } - text(x, y - descent + 1, c, temp_font); - - return width; -} +//int GuiPainter::preeditText(int x, int y, char_type c, +// FontInfo const & font, preedit_style style) +//{ +// FontInfo temp_font = font; +// FontMetrics const & fm = theFontMetrics(font); +// int ascent = fm.maxAscent(); +// int descent = fm.maxDescent(); +// int height = ascent + descent; +// int width = fm.width(c); +// +// switch (style) { +// case preedit_default: +// // default unselecting mode. +// fillRectangle(x, y - height + 1, width, height, Color_background); +// dashedUnderline(font, x, y - descent + 1, width); +// break; +// case preedit_selecting: +// // We are in selecting mode: white text on black background. +// fillRectangle(x, y - height + 1, width, height, Color_black); +// temp_font.setColor(Color_white); +// break; +// case preedit_cursor: +// // The character comes with a cursor. +// fillRectangle(x, y - height + 1, width, height, Color_background); +// underline(font, x, y - descent + 1, width); +// break; +// } +// text(x, y - descent + 1, c, temp_font); +// +// return width; +//} void GuiPainter::doubleUnderline(FontInfo const & f, int x, int y, int width) @@ -571,19 +571,19 @@ } -void GuiPainter::dashedUnderline(FontInfo const & f, int x, int y, int width) -{ - FontMetrics const & fm = theFontMetrics(f); - - int const below = max(fm.maxDescent() / 2, 2); - int height = max((fm.maxDescent() / 4) - 1, 1); - - if (height >= 2) - height += below; - - for (int n = 0; n != height; ++n) - line(x, y + below + n, x + width, y + below + n, f.realColor(), line_onoffdash); -} +//void GuiPainter::dashedUnderline(FontInfo const & f, int x, int y, int width) +//{ +// FontMetrics const & fm = theFontMetrics(f); +// +// int const below = max(fm.maxDescent() / 2, 2); +// int height = max((fm.maxDescent() / 4) - 1, 1); +// +// if (height >= 2) +// height += below; +// +// for (int n = 0; n != height; ++n) +// line(x, y + below + n, x + width, y + below + n, f.realColor(), line_onoffdash); +//} void GuiPainter::wavyHorizontalLine(int x, int y, int width, ColorCode col) --- lyx-2.0.0/src/frontends/qt4/GuiPainter.h.org 2010-10-10 17:33:10.713081493 +0900 +++ lyx-2.0.0/src/frontends/qt4/GuiPainter.h 2010-10-10 19:20:08.085650162 +0900 @@ -116,8 +116,8 @@ virtual void button(int x, int y, int w, int h, bool mouseHover); /// draw a character of a preedit string for cjk support. - virtual int preeditText(int x, int y, - char_type c, FontInfo const & f, preedit_style style); +// virtual int preeditText(int x, int y, +// char_type c, FontInfo const & f, preedit_style style); void wavyHorizontalLine(int x, int y, int width, ColorCode col); @@ -127,8 +127,8 @@ int x, int y, int width); /// check the font, and if set, draw an dashed underline - void dashedUnderline(FontInfo const & f, - int x, int y, int width); +// void dashedUnderline(FontInfo const & f, +// int x, int y, int width); /// check the font, and if set, draw an strike-through line void strikeoutLine(FontInfo const & f, --- lyx-2.0.0/src/frontends/qt4/GuiWorkArea.cpp.org 2011-05-09 20:53:43.564015152 +0900 +++ lyx-2.0.0/src/frontends/qt4/GuiWorkArea.cpp 2011-05-09 20:55:42.624015000 +0900 @@ -68,8 +68,13 @@ #include #include #include - +#include +#include +#include "GuiFontLoader.h" #include "support/bind.h" +#include +#include +#include "GuiFontLoader.h" #include @@ -1149,138 +1154,84 @@ void GuiWorkArea::inputMethodEvent(QInputMethodEvent * e) { - QString const & commit_string = e->commitString(); - docstring const & preedit_string - = qstring_to_ucs4(e->preeditString()); - - if (!commit_string.isEmpty()) { - - LYXERR(Debug::KEY, "preeditString: " << e->preeditString() - << " commitString: " << e->commitString()); - + // insert commit string + if (!e->commitString().isEmpty()) { int key = 0; // FIXME Iwami 04/01/07: we should take care also of UTF16 surrogates here. - for (int i = 0; i != commit_string.size(); ++i) { - QKeyEvent ev(QEvent::KeyPress, key, Qt::NoModifier, commit_string[i]); + for (int i = 0; i != e->commitString().size(); ++i) { + QKeyEvent ev(QEvent::KeyPress, key, Qt::NoModifier, e->commitString()[i]); keyPressEvent(&ev); } } - // Hide the cursor during the kana-kanji transformation. - if (preedit_string.empty()) - startBlinkingCursor(); - else - stopBlinkingCursor(); - - // last_width : for checking if last preedit string was/wasn't empty. - static bool last_width = false; - if (!last_width && preedit_string.empty()) { - // if last_width is last length of preedit string. - e->accept(); - return; - } - GuiPainter pain(&screen_); buffer_view_->updateMetrics(); buffer_view_->draw(pain); - FontInfo font = buffer_view_->cursor().getFont().fontInfo(); - FontMetrics const & fm = theFontMetrics(font); - int height = fm.maxHeight(); - int cur_x = cursor_->rect().left(); - int cur_y = cursor_->rect().bottom(); - - // redraw area of preedit string. - update(0, cur_y - height, viewport()->width(), - (height + 1) * preedit_lines_); - - if (preedit_string.empty()) { - last_width = false; - preedit_lines_ = 1; + static int redrawHeight = 0; + update(0, cursor_->rect().top(), viewport()->width(), redrawHeight); + + if(e->preeditString().length() == 0) { + startBlinkingCursor(); e->accept(); return; } - last_width = true; - - // att : stores an IM attribute. - QList const & att = e->attributes(); - // get attributes of input method cursor. - // cursor_pos : cursor position in preedit string. - size_t cursor_pos = 0; - bool cursor_is_visible = false; - for (int i = 0; i != att.size(); ++i) { - if (att.at(i).type == QInputMethodEvent::Cursor) { - cursor_pos = att.at(i).start; - cursor_is_visible = att.at(i).length != 0; - break; - } - } - - size_t preedit_length = preedit_string.length(); - - // get position of selection in input method. - // FIXME: isn't there a way to do this simplier? - // rStart : cursor position in selected string in IM. - size_t rStart = 0; - // rLength : selected string length in IM. - size_t rLength = 0; - if (cursor_pos < preedit_length) { - for (int i = 0; i != att.size(); ++i) { - if (att.at(i).type == QInputMethodEvent::TextFormat) { - if (att.at(i).start <= int(cursor_pos) - && int(cursor_pos) < att.at(i).start + att.at(i).length) { - rStart = att.at(i).start; - rLength = att.at(i).length; - if (!cursor_is_visible) - cursor_pos += rLength; - break; + stopBlinkingCursor(); + qDebug("Preedit:%s", e->preeditString().toUtf8().data()); + QTextLayout layout(e->preeditString(), getFont(buffer_view_->cursor().getFont().fontInfo()), &screen_); + layout.setPosition(QPointF(0, cursor_->rect().top())); + QList overrides; + for (int i = 0; i < e->attributes().size(); ++i) { + const QInputMethodEvent::Attribute &a = e->attributes().at(i); + if (a.type == QInputMethodEvent::TextFormat) { + QTextCharFormat f = qvariant_cast(a.value).toCharFormat(); + std::stringstream ss; + qDebug("Fore:%s, Back:%s", f.foreground().color().name().toUtf8().data(), f.background().color().name().toUtf8().data()); + + if (f.isValid()) { + QTextLayout::FormatRange o; + o.start = a.start; + o.length = a.length; + // if background isn't opaque, background brush set to LyX default brush. + if(!f.background().isOpaque()) { + QBrush b(f.background()); + b.setStyle(Qt::SolidPattern); +// b.setColor(guiApp->colorCache().get(Color_background)); + b.setColor(Qt::darkGray); + f.setBackground(b); + b.setColor(Qt::white); + f.setForeground(b); } - } - } - } - else { - rStart = cursor_pos; - rLength = 0; - } - - int const right_margin = buffer_view_->rightMargin(); - Painter::preedit_style ps; - // Most often there would be only one line: - preedit_lines_ = 1; - for (size_t pos = 0; pos != preedit_length; ++pos) { - char_type const typed_char = preedit_string[pos]; - // reset preedit string style - ps = Painter::preedit_default; - - // if we reached the right extremity of the screen, go to next line. - if (cur_x + fm.width(typed_char) > viewport()->width() - right_margin) { - cur_x = right_margin; - cur_y += height + 1; - ++preedit_lines_; - } - // preedit strings are displayed with dashed underline - // and partial strings are displayed white on black indicating - // that we are in selecting mode in the input method. - // FIXME: rLength == preedit_length is not a changing condition - // FIXME: should be put out of the loop. - if (pos >= rStart - && pos < rStart + rLength - && !(cursor_pos < rLength && rLength == preedit_length)) - ps = Painter::preedit_selecting; - - if (pos == cursor_pos - && (cursor_pos < rLength && rLength == preedit_length)) - ps = Painter::preedit_cursor; - - // draw one character and update cur_x. - cur_x += pain.preeditText(cur_x, cur_y, typed_char, font, ps); - } - - // update the preedit string screen area. - update(0, cur_y - preedit_lines_*height, viewport()->width(), - (height + 1) * preedit_lines_); - + // if font color isn't equal background color, forecolor set to font color. + //QColor fontColor = guiApp->colorCache().get(buffer_view_->cursor().getFont().fontInfo().color()); + //if(fontColor != f.background().color()) + // f.setForeground(QBrush(fontColor)); + o.format = f; + overrides.append(o); + } + } + } + layout.setAdditionalFormats(overrides); + + int leading = QFontMetrics(overrides.at(0).format.font()).leading(); + qreal widthOffset = cursor_->rect().x(); + qreal height = 0; + layout.beginLayout(); + for(preedit_lines_ = 0; ; ++preedit_lines_) { + QTextLine line = layout.createLine(); + if(!line.isValid()) + break; + line.setLineWidth(buffer_view_->workWidth() - buffer_view_->leftMargin() - buffer_view_->rightMargin() - widthOffset); + height += leading; + line.setPosition(QPointF(widthOffset, height)); + height += line.height(); + widthOffset = buffer_view_->leftMargin(); + } + layout.endLayout(); + layout.draw(&pain, QPoint()); + redrawHeight = layout.boundingRect().height(); + update(0, cursor_->rect().top(), viewport()->width(), redrawHeight); // Don't forget to accept the event! e->accept(); } @@ -1288,21 +1239,29 @@ QVariant GuiWorkArea::inputMethodQuery(Qt::InputMethodQuery query) const { - QRect cur_r(0, 0, 0, 0); - switch (query) { - // this is the CJK-specific composition window position and - // the context menu position when the menu key is pressed. - case Qt::ImMicroFocus: - cur_r = cursor_->rect(); - if (preedit_lines_ != 1) - cur_r.moveLeft(10); - cur_r.moveBottom(cur_r.bottom() - + cur_r.height() * (preedit_lines_ - 1)); - // return lower right of cursor in LyX. - return cur_r; - default: - return QWidget::inputMethodQuery(query); + // this is the CJK-specific composition window position. + if(query == Qt::ImMicroFocus) { + QRect cur_r(cursor_->rect()); + if (preedit_lines_ != 1) + cur_r.moveLeft(buffer_view_->leftMargin()); + cur_r.moveBottom(cur_r.bottom() + cur_r.height() * preedit_lines_); + // return lower right of cursor in LyX. + return QVariant(cur_r); + } + else if(query == Qt::ImFont) { + return QVariant(getFont(buffer_view_->cursor().getFont().fontInfo())); + } + else if(query == Qt::ImCursorPosition) { + return QVariant(buffer_view_->cursor().pos()); + } + else if(query == Qt::ImSurroundingText) { + return QVariant(toqstr(buffer_view_->cursor().innerParagraph().asString())); } + else if(query == Qt::ImCurrentSelection) { + return QVariant(toqstr(buffer_view_->cursor().selectionAsString(false))); + } + else + return QVariant(); } --- lyx-2.0.0/src/frontends/Painter.h.org 2010-10-10 17:30:18.756320612 +0900 +++ lyx-2.0.0/src/frontends/Painter.h 2010-10-10 19:15:44.943700467 +0900 @@ -67,11 +67,11 @@ /// possible character styles of preedit string. /// This is used for CJK input method support. - enum preedit_style { - preedit_default, //< when unselecting, no cursor and dashed underline. - preedit_selecting, //< when selecting. - preedit_cursor //< with cursor. - }; +// enum preedit_style { +// preedit_default, //< when unselecting, no cursor and dashed underline. +// preedit_selecting, //< when selecting. +// preedit_cursor //< with cursor. +// }; virtual ~Painter() {} @@ -141,8 +141,8 @@ FontInfo const & font, bool mouseHover) = 0; /// draw a character of a preedit string for cjk support. - virtual int preeditText(int x, int y, - char_type c, FontInfo const & f, preedit_style style) = 0; +// virtual int preeditText(int x, int y, +// char_type c, FontInfo const & f, preedit_style style) = 0; /// start monochrome painting mode, i.e. map every color into [min,max] virtual void enterMonochromeMode(Color const & min,