--- 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 <QToolButton>
 #include <QToolTip>
 #include <QMenuBar>
-
+#include <QTextFormat>
+#include <QTextLayout>
+#include "GuiFontLoader.h"
 #include "support/bind.h"
+#include <QTextFormat>
+#include <QTextLayout>
+#include "GuiFontLoader.h"
 
 #include <cmath>
 
@@ -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<QInputMethodEvent::Attribute> 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<QTextLayout::FormatRange> 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<QTextFormat>(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,