📄 textlayout.java
字号:
// at offset is at the given caret. return textLine.caretAtOffsetIsValid(offset); } /** * Returns the hit for the next caret to the right (bottom); if there * is no such hit, returns <code>null</code>. * If the hit character index is out of bounds, an * {@link IllegalArgumentException} is thrown. * @param hit a hit on a character in this layout * @return a hit whose caret appears at the next position to the * right (bottom) of the caret of the provided hit or <code>null</code>. */ public TextHitInfo getNextRightHit(TextHitInfo hit) { ensureCache(); checkTextHit(hit); int caret = hitToCaret(hit); if (caret == characterCount) { return null; } do { ++caret; } while (!caretIsValid(caret)); return caretToHit(caret); } /** * Returns the hit for the next caret to the right (bottom); if no * such hit, returns <code>null</code>. The hit is to the right of * the strong caret at the specified offset, as determined by the * specified policy. * The returned hit is the stronger of the two possible * hits, as determined by the specified policy. * @param offset an insertion offset in this <code>TextLayout</code>. * Cannot be less than 0 or greater than this <code>TextLayout</code> * object's character count. * @param policy the policy used to select the strong caret * @return a hit whose caret appears at the next position to the * right (bottom) of the caret of the provided hit, or <code>null</code>. */ public TextHitInfo getNextRightHit(int offset, CaretPolicy policy) { if (offset < 0 || offset > characterCount) { throw new IllegalArgumentException("Offset out of bounds in TextLayout.getNextRightHit()"); } if (policy == null) { throw new IllegalArgumentException("Null CaretPolicy passed to TextLayout.getNextRightHit()"); } TextHitInfo hit1 = TextHitInfo.afterOffset(offset); TextHitInfo hit2 = hit1.getOtherHit(); TextHitInfo nextHit = getNextRightHit(policy.getStrongCaret(hit1, hit2, this)); if (nextHit != null) { TextHitInfo otherHit = getVisualOtherHit(nextHit); return policy.getStrongCaret(otherHit, nextHit, this); } else { return null; } } /** * Returns the hit for the next caret to the right (bottom); if no * such hit, returns <code>null</code>. The hit is to the right of * the strong caret at the specified offset, as determined by the * default policy. * The returned hit is the stronger of the two possible * hits, as determined by the default policy. * @param offset an insertion offset in this <code>TextLayout</code>. * Cannot be less than 0 or greater than the <code>TextLayout</code> * object's character count. * @return a hit whose caret appears at the next position to the * right (bottom) of the caret of the provided hit, or <code>null</code>. */ public TextHitInfo getNextRightHit(int offset) { return getNextRightHit(offset, DEFAULT_CARET_POLICY); } /** * Returns the hit for the next caret to the left (top); if no such * hit, returns <code>null</code>. * If the hit character index is out of bounds, an * <code>IllegalArgumentException</code> is thrown. * @param hit a hit on a character in this <code>TextLayout</code>. * @return a hit whose caret appears at the next position to the * left (top) of the caret of the provided hit, or <code>null</code>. */ public TextHitInfo getNextLeftHit(TextHitInfo hit) { ensureCache(); checkTextHit(hit); int caret = hitToCaret(hit); if (caret == 0) { return null; } do { --caret; } while(!caretIsValid(caret)); return caretToHit(caret); } /** * Returns the hit for the next caret to the left (top); if no * such hit, returns <code>null</code>. The hit is to the left of * the strong caret at the specified offset, as determined by the * specified policy. * The returned hit is the stronger of the two possible * hits, as determined by the specified policy. * @param offset an insertion offset in this <code>TextLayout</code>. * Cannot be less than 0 or greater than this <code>TextLayout</code> * object's character count. * @param policy the policy used to select the strong caret * @return a hit whose caret appears at the next position to the * left (top) of the caret of the provided hit, or <code>null</code>. */ public TextHitInfo getNextLeftHit(int offset, CaretPolicy policy) { if (policy == null) { throw new IllegalArgumentException("Null CaretPolicy passed to TextLayout.getNextLeftHit()"); } if (offset < 0 || offset > characterCount) { throw new IllegalArgumentException("Offset out of bounds in TextLayout.getNextLeftHit()"); } TextHitInfo hit1 = TextHitInfo.afterOffset(offset); TextHitInfo hit2 = hit1.getOtherHit(); TextHitInfo nextHit = getNextLeftHit(policy.getStrongCaret(hit1, hit2, this)); if (nextHit != null) { TextHitInfo otherHit = getVisualOtherHit(nextHit); return policy.getStrongCaret(otherHit, nextHit, this); } else { return null; } } /** * Returns the hit for the next caret to the left (top); if no * such hit, returns <code>null</code>. The hit is to the left of * the strong caret at the specified offset, as determined by the * default policy. * The returned hit is the stronger of the two possible * hits, as determined by the default policy. * @param offset an insertion offset in this <code>TextLayout</code>. * Cannot be less than 0 or greater than this <code>TextLayout</code> * object's character count. * @return a hit whose caret appears at the next position to the * left (top) of the caret of the provided hit, or <code>null</code>. */ public TextHitInfo getNextLeftHit(int offset) { return getNextLeftHit(offset, DEFAULT_CARET_POLICY); } /** * Returns the hit on the opposite side of the specified hit's caret. * @param hit the specified hit * @return a hit that is on the opposite side of the specified hit's * caret. */ public TextHitInfo getVisualOtherHit(TextHitInfo hit) { ensureCache(); checkTextHit(hit); int hitCharIndex = hit.getCharIndex(); int charIndex; boolean leading; if (hitCharIndex == -1 || hitCharIndex == characterCount) { int visIndex; if (textLine.isDirectionLTR() == (hitCharIndex == -1)) { visIndex = 0; } else { visIndex = characterCount-1; } charIndex = textLine.visualToLogical(visIndex); if (textLine.isDirectionLTR() == (hitCharIndex == -1)) { // at left end leading = textLine.isCharLTR(charIndex); } else { // at right end leading = !textLine.isCharLTR(charIndex); } } else { int visIndex = textLine.logicalToVisual(hitCharIndex); boolean movedToRight; if (textLine.isCharLTR(hitCharIndex) == hit.isLeadingEdge()) { --visIndex; movedToRight = false; } else { ++visIndex; movedToRight = true; } if (visIndex > -1 && visIndex < characterCount) { charIndex = textLine.visualToLogical(visIndex); leading = movedToRight == textLine.isCharLTR(charIndex); } else { charIndex = (movedToRight == textLine.isDirectionLTR())? characterCount : -1; leading = charIndex == characterCount; } } return leading? TextHitInfo.leading(charIndex) : TextHitInfo.trailing(charIndex); } /** * Return an array of four floats corresponding the endpoints of the caret * x0, y0, x1, y1. * * This creates a line along the slope of the caret intersecting the * baseline at the caret * position, and extending from ascent above the baseline to descent below * it. */ private double[] getCaretPath(int caret, Rectangle2D bounds, boolean clipToBounds) { float[] info = getCaretInfo(caret, bounds, null); double pos = info[0]; double slope = info[1]; double x0, y0, x1, y1; double x2 = -3141.59, y2 = -2.7; // values are there to make compiler happy double left = bounds.getX(); double right = left + bounds.getWidth(); double top = bounds.getY(); double bottom = top + bounds.getHeight(); boolean threePoints = false; if (isVerticalLine) { if (slope >= 0) { x0 = left; x1 = right; } else { x1 = left; x0 = right; } y0 = pos + x0 * slope; y1 = pos + x1 * slope; // y0 <= y1, always if (clipToBounds) { if (y0 < top) { if (slope <= 0 || y1 <= top) { y0 = y1 = top; } else { threePoints = true; y0 = top; y2 = top; x2 = x1 + (top-y1)/slope; if (y1 > bottom) { y1 = bottom; } } } else if (y1 > bottom) { if (slope >= 0 || y0 >= bottom) { y0 = y1 = bottom; } else { threePoints = true; y1 = bottom; y2 = bottom; x2 = x0 + (bottom-x1)/slope; } } } } else { if (slope >= 0) { y0 = bottom; y1 = top; } else { y1 = bottom; y0 = top; } x0 = pos - y0 * slope; x1 = pos - y1 * slope; // x0 <= x1, always if (clipToBounds) { if (x0 < left) { if (slope <= 0 || x1 <= left) { x0 = x1 = left; } else { threePoints = true; x0 = left; x2 = left; y2 = y1 - (left-x1)/slope; if (x1 > right) { x1 = right; } } } else if (x1 > right) { if (slope >= 0 || x0 >= right) { x0 = x1 = right; } else { threePoints = true; x1 = right; x2 = right; y2 = y0 - (right-x0)/slope; } } } } return threePoints?
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -