/** * Get real allocation (possibly not rectangular) of a part of layout. * <br> * It's used when rendering the text layout for filling background highlights of the view. * * @param length Total number of characters for which the allocation is computed. * @param alloc Allocation given by a parent view. * @return */ public static Shape getRealAlloc(TextLayout textLayout, Rectangle2D textLayoutRect, TextHitInfo startHit, TextHitInfo endHit) { // Quick-fix to eliminate missing line in rendering italic "d" - more elaborate fix is needed textLayoutRect = new Rectangle2D.Double(textLayoutRect.getX(), textLayoutRect.getY(), textLayoutRect.getWidth() + 2, textLayoutRect.getHeight()); Rectangle2D.Double zeroBasedRect = ViewUtils.shape2Bounds(textLayoutRect); zeroBasedRect.x = 0; zeroBasedRect.y = 0; Shape ret = textLayout.getVisualHighlightShape(startHit, endHit, zeroBasedRect); AffineTransform transform = AffineTransform.getTranslateInstance( textLayoutRect.getX(), textLayoutRect.getY() ); ret = transform.createTransformedShape(ret); // The following gives bad result for some reason (works for layout but not for caret modelToView()) // Shape ret2 = textLayout.getVisualHighlightShape(startHit.getCharIndex(), endHit.getCharIndex(), textLayoutRect); return ret; }
public void runTest(Object ctx, int numReps) { TLExContext tlctx = (TLExContext)ctx; TextLayout tl = tlctx.tl; TextHitInfo[] hits = tlctx.hits; Rectangle2D lb = tlctx.lb; Shape s; if (hits.length < 3) { do { s = tl.getVisualHighlightShape(hits[0], hits[hits.length - 1], lb); } while (--numReps >= 0); } else { do { for (int i = 3; i < hits.length; ++i) { s = tl.getVisualHighlightShape(hits[i-3], hits[i], lb); } } while (--numReps >= 0); } }
/** * Move the insertion point one position to the left in the composed text. * Do not let the caret move to the left of the "\\u" or "\\U". */ private void moveCaretLeft() { int len = buffer.length(); if (--insertionPoint < 2) { insertionPoint++; beep(); } else if (format == SURROGATE_PAIR && insertionPoint == 7) { insertionPoint = 8; beep(); } context.dispatchInputMethodEvent( InputMethodEvent.CARET_POSITION_CHANGED, null, 0, TextHitInfo.leading(insertionPoint), null); }
private Rectangle getCaretRectangle(TextHitInfo caret) { int caretLocation = 0; TextLayout layout = composedTextLayout; if (layout != null) { caretLocation = Math.round(layout.getCaretInfo(caret)[0]); } Graphics g = getGraphics(); FontMetrics metrics = null; try { metrics = g.getFontMetrics(); } finally { g.dispose(); } return new Rectangle(TEXT_ORIGIN_X + caretLocation, TEXT_ORIGIN_Y - metrics.getAscent(), 0, metrics.getAscent() + metrics.getDescent()); }
public Rectangle getTextLocation(TextHitInfo offset) { synchronized (compositionAreaLock) { if (compositionAreaOwner == this && isCompositionAreaVisible()) { return compositionArea.getTextLocation(offset); } else if (composedText != null) { // there's composed text, but it's not displayed, so fake a rectangle return new Rectangle(0, 0, 0, 10); } else { InputMethodRequests requests = getClientInputMethodRequests(); if (requests != null) { return requests.getTextLocation(offset); } else { // passive client, no composed text, so fake a rectangle return new Rectangle(0, 0, 0, 10); } } } }
public void dispatchInputMethodEvent(int id, AttributedCharacterIterator text, int committedCharacterCount, TextHitInfo caret, TextHitInfo visiblePosition) { // We need to record the client component as the source so // that we have correct information if we later have to break up this // event into key events. Component source; source = getClientComponent(); if (source != null) { InputMethodEvent event = new InputMethodEvent(source, id, text, committedCharacterCount, caret, visiblePosition); if (haveActiveClient() && !useBelowTheSpotInput()) { source.dispatchEvent(event); } else { getCompositionAreaHandler(true).processInputMethodEvent(event); } } }
public TextHitInfo getLocationOffset(int x, int y) { if (composedTextAttribute == null) { return null; } else { Point p = getLocationOnScreen(); p.x = x - p.x; p.y = y - p.y; int pos = viewToModel(p); if ((pos >= composedTextStart.getOffset()) && (pos <= composedTextEnd.getOffset())) { return TextHitInfo.leading(pos - composedTextStart.getOffset()); } else { return null; } } }
public Rectangle getTextLocation(TextHitInfo offset) { Rectangle r; try { r = modelToView(getCaretPosition()); if (r != null) { Point p = getLocationOnScreen(); r.translate(p.x, p.y); } } catch (BadLocationException ble) { r = null; } if (r == null) r = new Rectangle(); return r; }
static TextHitInfo x2RelOffset(TextLayout textLayout, float x) { TextHitInfo hit; x -= EXTRA_MARGIN_WIDTH; if (x >= textLayout.getAdvance()) { hit = TextHitInfo.trailing(textLayout.getCharacterCount()); } else { hit = textLayout.hitTestChar(x, 0); // What about backward bias -> with higher offsets it may go back visually } return hit; }
static int viewToIndex(TextLayout textLayout, double x, Shape alloc, Position.Bias[] biasReturn) { Rectangle2D bounds = ViewUtils.shapeAsRect(alloc); TextHitInfo hitInfo = x2Index(textLayout, (float)(x - bounds.getX())); if (biasReturn != null) { biasReturn[0] = hitInfo.isLeadingEdge() ? Position.Bias.Forward : Position.Bias.Backward; } return hitInfo.getInsertionIndex(); }
static TextHitInfo x2Index(TextLayout textLayout, float x) { TextHitInfo hit; hit = textLayout.hitTestChar(x, 0); // Use forward bias only since BaseCaret and other code is not sensitive to backward bias yet if (!hit.isLeadingEdge()) { hit = TextHitInfo.leading(hit.getInsertionIndex()); } return hit; }
public void init(TestEnvironment env, Result results) { super.init(env, results); ArrayList list = new ArrayList(text.length() * 2 + 2); TextHitInfo hit = TextHitInfo.trailing(-1); do { list.add(hit); hit = tl.getNextRightHit(hit); } while (hit != null); hits = (TextHitInfo[])list.toArray(new TextHitInfo[list.size()]); lb = tl.getBounds(); lb.setRect(lb.getMinX() - 10, lb.getMinY(), lb.getWidth() + 20, lb.getHeight()); }
public void runTest(Object ctx, int numReps) { TLExContext tlctx = (TLExContext)ctx; TextLayout tl = tlctx.tl; TextHitInfo[] hits = tlctx.hits; do { for (int i = 0; i < hits.length; ++i) { tl.getCaretInfo(hits[i]); } } while (--numReps >= 0); }
public void runTest(Object ctx, int numReps) { TLExContext tlctx = (TLExContext)ctx; TextLayout tl = tlctx.tl; TextHitInfo[] hits = tlctx.hits; TextHitInfo hit; do { for (int i = 0; i < hits.length; ++i) { hit = tl.getNextLeftHit(hits[i]); } } while (--numReps >= 0); }
public void runTest(Object ctx, int numReps) { TLExContext tlctx = (TLExContext)ctx; TextLayout tl = tlctx.tl; TextHitInfo[] hits = tlctx.hits; Shape s; do { for (int i = 0; i < hits.length; ++i) { s = tl.getCaretShape(hits[i]); } } while (--numReps >= 0); }
public void runTest(Object ctx, int numReps) { TLExContext tlctx = (TLExContext)ctx; TextLayout tl = tlctx.tl; int numhits = tlctx.hits.length; Rectangle2D lb = tlctx.lb; TextHitInfo hit; for (int i = 0; i <= numhits; ++i) { float x = (float)(lb.getMinX() + lb.getWidth() * i / numhits); float y = (float)(lb.getMinY() + lb.getHeight() * i / numhits); hit = tl.hitTestChar(x, y, lb); } }
/** * Send the composed text to the client. */ private void sendComposedText() { AttributedString as = new AttributedString(buffer.toString()); as.addAttribute(TextAttribute.INPUT_METHOD_HIGHLIGHT, InputMethodHighlight.SELECTED_RAW_TEXT_HIGHLIGHT); context.dispatchInputMethodEvent( InputMethodEvent.INPUT_METHOD_TEXT_CHANGED, as.getIterator(), 0, TextHitInfo.leading(insertionPoint), null); }
/** * Send the committed text to the client. */ private void sendCommittedText() { AttributedString as = new AttributedString(buffer.toString()); context.dispatchInputMethodEvent( InputMethodEvent.INPUT_METHOD_TEXT_CHANGED, as.getIterator(), buffer.length(), TextHitInfo.leading(insertionPoint), null); buffer.setLength(0); insertionPoint = 0; format = UNSET; }
/** * Move the insertion point one position to the right in the composed text. */ private void moveCaretRight() { int len = buffer.length(); if (++insertionPoint > len) { insertionPoint = len; beep(); } context.dispatchInputMethodEvent( InputMethodEvent.CARET_POSITION_CHANGED, null, 0, TextHitInfo.leading(insertionPoint), null); }
/** * Sets the caret to be displayed in this composition area. * The text is not changed. */ void setCaret(TextHitInfo caret) { this.caret = caret; if (compositionWindow.isVisible()) { Graphics g = getGraphics(); try { paint(g); } finally { g.dispose(); } } }
TextHitInfo getLocationOffset(int x, int y) { TextLayout layout = composedTextLayout; if (layout == null) { return null; } else { Point location = getLocationOnScreen(); x -= location.x + TEXT_ORIGIN_X; y -= location.y + TEXT_ORIGIN_Y; if (layout.getBounds().contains(x, y)) { return layout.hitTestChar(x, y); } else { return null; } } }
public TextHitInfo getLocationOffset(int x, int y) { synchronized (compositionAreaLock) { if (compositionAreaOwner == this && isCompositionAreaVisible()) { return compositionArea.getLocationOffset(x, y); } else { return null; } } }
private void setInputMethodCaretPosition(InputMethodEvent e) { int dot; if (composedTextExists()) { dot = composedTextStart.getOffset(); if (!(caret instanceof ComposedTextCaret)) { if (composedTextCaret == null) { composedTextCaret = new ComposedTextCaret(); } originalCaret = caret; // Sets composed text caret exchangeCaret(originalCaret, composedTextCaret); } TextHitInfo caretPos = e.getCaret(); if (caretPos != null) { int index = caretPos.getInsertionIndex(); dot += index; if (index == 0) { // Scroll the component if needed so that the composed text // becomes visible. try { Rectangle d = modelToView(dot); Rectangle end = modelToView(composedTextEnd.getOffset()); Rectangle b = getBounds(); d.x += Math.min(end.x - d.x, b.width); scrollRectToVisible(d); } catch (BadLocationException ble) {} } } caret.setDot(dot); } else if (caret instanceof ComposedTextCaret) { dot = caret.getDot(); // Restores original caret exchangeCaret(caret, originalCaret); caret.setDot(dot); } }
/** * Creates an input method event from the arguments given * and posts it on the AWT event queue. For arguments, * see InputMethodEvent. Called by input method. * * @see java.awt.event.InputMethodEvent#InputMethodEvent */ private void postInputMethodEvent(int id, AttributedCharacterIterator text, int committedCharacterCount, TextHitInfo caret, TextHitInfo visiblePosition, long when) { Component source = getClientComponent(); if (source != null) { InputMethodEvent event = new InputMethodEvent(source, id, when, text, committedCharacterCount, caret, visiblePosition); SunToolkit.postEvent(SunToolkit.targetToAppContext(source), (AWTEvent)event); } }
private void postInputMethodEvent(int id, AttributedCharacterIterator text, int committedCharacterCount, TextHitInfo caret, TextHitInfo visiblePosition) { postInputMethodEvent(id, text, committedCharacterCount, caret, visiblePosition, EventQueue.getMostRecentEventTime()); }