--- old/modules/graphics/src/main/java/com/sun/glass/ui/gtk/GtkView.java 2014-11-13 20:25:28.564977483 +0300 +++ new/modules/graphics/src/main/java/com/sun/glass/ui/gtk/GtkView.java 2014-11-13 20:25:28.460977482 +0300 @@ -29,6 +29,7 @@ import java.nio.Buffer; import java.nio.ByteBuffer; import java.nio.IntBuffer; +import java.util.ArrayList; import java.util.Map; final class GtkView extends View { @@ -36,6 +37,7 @@ private boolean imEnabled = false; private boolean isInPreeditMode = false; private final StringBuilder preedit = new StringBuilder(); + private ByteBuffer attributes; private int lastCaret; private native void enableInputMethodEventsImpl(long ptr, boolean enable); @@ -117,13 +119,76 @@ isInPreeditMode = enabled; } - protected void notifyInputMethodDraw(String text, int first, int length, int caret) { + + protected void notifyInputMethodDraw(String text, int first, int length, int caret, byte[] attr) { + int[] boundary = null; + byte[] values = null; + + if (attributes == null ) { + attributes = ByteBuffer.allocate(32); + } + + if (length > 0) { + preedit.replace(first, first + length, ""); + } + if (text != null) { - preedit.replace(first, first + length, text); + preedit.insert(first, text); } else { - preedit.setLength(0); + if (attr == null) { + preedit.setLength(0); + } } - notifyInputMethod(preedit.toString(), null, null, null, 0, caret, 0); + + if (attributes.capacity() < preedit.length()) { + ByteBuffer tmp = ByteBuffer.allocate((int) (preedit.length() * 1.5)); + tmp.put(attributes); + attributes = tmp; + } + + attributes.limit(preedit.length()); + + if (attr != null && attributes.limit() >= (first + attr.length)) { + attributes.position(first); + attributes.put(attr); + } + + if (attributes.limit() > 0) { + ArrayList boundaryList = new ArrayList<>(); + ArrayList valuesList = new ArrayList<>(); + attributes.rewind(); + byte lastAttribute = attributes.get(); + + boundaryList.add(0); + valuesList.add(lastAttribute); + + int i = 1; + while (attributes.hasRemaining()) { + byte a = attributes.get(); + if (lastAttribute != a) { + boundaryList.add(i); + valuesList.add(a); + } + lastAttribute = a; + i++; + } + + boundaryList.add(attributes.limit()); + + boundary = new int[boundaryList.size()]; + i = 0; + for (Integer e : boundaryList) { + boundary[i++] = e; + } + + values = new byte[valuesList.size()]; + i = 0; + for (Byte e: valuesList) { + values[i++] = e; + } + } + + notifyInputMethod(preedit.toString(), boundary, boundary, values, 0, caret, 0); lastCaret = caret; }