Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
285db28
draft api
andy-goryachev-oracle Oct 8, 2024
43ac0e1
bounds
andy-goryachev-oracle Oct 8, 2024
21dbe6c
review comments
andy-goryachev-oracle Oct 9, 2024
04c4abb
javadoc
andy-goryachev-oracle Oct 9, 2024
6869c76
clarify
andy-goryachev-oracle Oct 9, 2024
2009a7e
convert to wrapper
andy-goryachev-oracle Oct 9, 2024
6b7b079
Merge remote-tracking branch 'origin/master' into ag.text.layout.api
andy-goryachev-oracle Oct 11, 2024
c2e26d5
text line info
andy-goryachev-oracle Oct 11, 2024
88e9ee1
caret info
andy-goryachev-oracle Oct 14, 2024
17dcdd4
whitespace
andy-goryachev-oracle Oct 14, 2024
fd84f30
tests
andy-goryachev-oracle Oct 14, 2024
466bba7
remove line spacing
andy-goryachev-oracle Oct 14, 2024
5ab4f47
Merge remote-tracking branch 'origin/master' into ag.text.layout.api
andy-goryachev-oracle Oct 14, 2024
eb99008
Merge remote-tracking branch 'origin/master' into ag.text.layout.api
andy-goryachev-oracle Oct 24, 2024
6776d97
review comments
andy-goryachev-oracle Oct 25, 2024
9b1f99a
Merge remote-tracking branch 'origin/master' into ag.text.layout.api
andy-goryachev-oracle Oct 30, 2024
4f4e659
include line spacing
andy-goryachev-oracle Oct 31, 2024
dd34810
Merge remote-tracking branch 'origin/master' into ag.text.layout.api
andy-goryachev-oracle Oct 31, 2024
a716e57
Merge remote-tracking branch 'origin/master' into ag.text.layout.api
andy-goryachev-oracle Nov 1, 2024
75b171f
caret and range
andy-goryachev-oracle Nov 1, 2024
029bbe6
for text
andy-goryachev-oracle Nov 1, 2024
3925c02
Merge remote-tracking branch 'origin/master' into ag.text.layout.api
andy-goryachev-oracle Nov 4, 2024
e139484
Merge remote-tracking branch 'origin/master' into ag.text.layout.api
andy-goryachev-oracle Nov 6, 2024
8a5b904
Merge remote-tracking branch 'origin/master' into ag.text.layout.api
andy-goryachev-oracle Nov 8, 2024
a0e59fb
Merge remote-tracking branch 'origin/master' into ag.text.layout.api
andy-goryachev-oracle Nov 15, 2024
3c2976b
line spacing
andy-goryachev-oracle Nov 15, 2024
5076f36
shorter array
andy-goryachev-oracle Nov 18, 2024
4479f0b
text flow test
andy-goryachev-oracle Nov 19, 2024
c05c790
text layout test
andy-goryachev-oracle Nov 19, 2024
7c86978
note
andy-goryachev-oracle Nov 19, 2024
366ae4b
coordinates
andy-goryachev-oracle Nov 19, 2024
d31eb2b
Merge remote-tracking branch 'origin/master' into ag.text.layout.api
andy-goryachev-oracle Nov 19, 2024
7ea4e3b
Merge remote-tracking branch 'origin/master' into ag.text.layout.api
andy-goryachev-oracle Nov 22, 2024
944bd0d
segments
andy-goryachev-oracle Nov 22, 2024
1dd2b0c
Merge branch 'master' into ag.text.layout.api
andy-goryachev-oracle Dec 4, 2024
2a3a754
Merge remote-tracking branch 'origin/master' into ag.text.layout.api
andy-goryachev-oracle Dec 10, 2024
c1c46ab
Merge remote-tracking branch 'origin/master' into ag.text.layout.api
andy-goryachev-oracle Dec 20, 2024
7d656df
Merge branch 'master' into ag.text.layout.api
andy-goryachev-oracle Jan 16, 2025
0ab5890
25 25
andy-goryachev-oracle Jan 16, 2025
d81f65d
Merge remote-tracking branch 'origin/master' into ag.text.layout.api
andy-goryachev-oracle Feb 5, 2025
d688d74
review comments
andy-goryachev-oracle Feb 5, 2025
0f94efd
Merge remote-tracking branch 'origin/master' into ag.text.layout.api
andy-goryachev-oracle Mar 5, 2025
3260b8e
Merge remote-tracking branch 'origin/master' into ag.text.layout.api
andy-goryachev-oracle Mar 10, 2025
0ad6f66
review comments
andy-goryachev-oracle Mar 10, 2025
9d499c1
tests
andy-goryachev-oracle Mar 10, 2025
b7033cf
twice
andy-goryachev-oracle Mar 10, 2025
9cee2dc
Merge remote-tracking branch 'origin/master' into ag.text.layout.api
andy-goryachev-oracle Mar 26, 2025
33cf88d
Merge remote-tracking branch 'origin/master' into ag.text.layout.api
andy-goryachev-oracle Apr 4, 2025
a5899aa
Merge remote-tracking branch 'origin/master' into ag.text.layout.api
andy-goryachev-oracle Apr 7, 2025
fa23f09
indent
andy-goryachev-oracle Apr 7, 2025
4d2bdf5
sealed
andy-goryachev-oracle Apr 7, 2025
6782658
Merge remote-tracking branch 'origin/master' into ag.text.layout.api
andy-goryachev-oracle May 2, 2025
982ef1f
review comments
andy-goryachev-oracle May 2, 2025
f5781cd
Merge remote-tracking branch 'origin/master' into ag.text.layout.api
andy-goryachev-oracle May 21, 2025
0ac75da
review comments
andy-goryachev-oracle May 21, 2025
c885173
caret geometry
andy-goryachev-oracle May 22, 2025
0f02fe9
removed getStrikeThroughShape
andy-goryachev-oracle May 22, 2025
34b0646
cleanup
andy-goryachev-oracle May 22, 2025
ab8bd9c
Merge remote-tracking branch 'origin/master' into ag.text.layout.api
andy-goryachev-oracle May 22, 2025
5add130
Merge remote-tracking branch 'origin/master' into 8341438.text.shapes…
andy-goryachev-oracle May 22, 2025
46b48bf
corrected api
andy-goryachev-oracle May 23, 2025
662f699
Merge remote-tracking branch 'origin/master' into 8341438.text.shapes…
andy-goryachev-oracle May 27, 2025
f4fb845
Merge remote-tracking branch 'origin/master' into ag.text.layout.api
andy-goryachev-oracle May 27, 2025
de1016b
cleanup
andy-goryachev-oracle May 27, 2025
c845aee
Merge remote-tracking branch 'origin/ag.text.layout.api' into 8341438…
andy-goryachev-oracle May 27, 2025
266eb9f
tests
andy-goryachev-oracle May 27, 2025
03c66a4
layout info
andy-goryachev-oracle May 28, 2025
5c2a5ad
Merge branch 'master' into 8341438.text.shapes.insets
andy-goryachev-oracle Jun 17, 2025
c1d7029
cleanup
andy-goryachev-oracle Jun 17, 2025
236c6af
Merge branch 'master' into 8341438.text.shapes.insets
andy-goryachev-oracle Jun 27, 2025
20c8190
Merge remote-tracking branch 'origin/master' into 8341438.text.shapes…
andy-goryachev-oracle Jul 9, 2025
16ed27e
review comments
andy-goryachev-oracle Jul 9, 2025
d466ebc
link
andy-goryachev-oracle Jul 9, 2025
a2099f0
javadoc
andy-goryachev-oracle Jul 9, 2025
6ca8ab7
Merge branch 'master' into 8341438.text.shapes.insets
andy-goryachev-oracle Jul 11, 2025
a283479
if
andy-goryachev-oracle Jul 11, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,16 @@ public final class TextUtils {
* @param type the type of geometry to query
* @param dx the x offset to add to each path element
* @param dy the y offset to add to each path element
* @param lineSpacing the line spacing (applies only to TYPE_TEXT)
* @return the array of {@code PathElement}s
*/
public static PathElement[] getRange(TextLayout layout, int start, int end, int type, double dx, double dy) {
public static PathElement[] getRange(TextLayout layout, int start, int end, int type, double dx, double dy, double lineSpacing) {
ArrayList<PathElement> a = new ArrayList<>();
layout.getRange(start, end, type, (left, top, right, bottom) -> {
double leftEdge = left + dx;
double rightEdge = right + dx;
double topEdge = top + dy;
double bottomEdge = bottom + dy;
double bottomEdge = bottom + dy + lineSpacing;
a.add(new MoveTo(leftEdge, topEdge));
a.add(new LineTo(rightEdge, topEdge));
a.add(new LineTo(rightEdge, bottomEdge));
Expand Down
39 changes: 34 additions & 5 deletions modules/javafx.graphics/src/main/java/javafx/scene/text/Text.java
Original file line number Diff line number Diff line change
Expand Up @@ -1056,13 +1056,13 @@ private int findFirstRunStart() {
return start;
}

private PathElement[] getRange(int start, int end, int type) {
private PathElement[] getRange(int start, int end, int type, double lineSpacing) {
int length = getTextInternal().length();
if (0 <= start && start < end && end <= length) {
TextLayout layout = getTextLayout();
double dx = getX();
double dy = getY() - getYRendering();
return TextUtils.getRange(layout, start, end, type, dx, dy);
return TextUtils.getRange(layout, start, end, type, dx, dy, lineSpacing);
}
return EMPTY_PATH_ELEMENT_ARRAY;
}
Expand All @@ -1088,14 +1088,31 @@ public final PathElement[] caretShape(int charIndex, boolean caretBias) {

/**
* Returns the shape for the range of the text in local coordinates.
* The returned value does not include line spacing.
*
* @param start the beginning character index for the range
* @param end the end character index (non-inclusive) for the range
* @return an array of {@code PathElement} which can be used to create a {@code Shape}
* @since 9
* @see #getRangeShape(int, int, boolean)
*/
public final PathElement[] rangeShape(int start, int end) {
return getRange(start, end, TextLayout.TYPE_TEXT);
return getRange(start, end, TextLayout.TYPE_TEXT, 0.0);
}

/**
* Returns the shape for the range of the text in local coordinates,
* with or without line spacing.
*
* @param start the beginning character index for the range
* @param end the end character index (non-inclusive) for the range
* @param includeLineSpacing whether the shapes include line spacing
* @return an array of {@code PathElement} which can be used to create a {@code Shape}
* @since 25
*/
public final PathElement[] getRangeShape(int start, int end, boolean includeLineSpacing) {
double lineSpacing = includeLineSpacing ? getLineSpacing() : 0.0;
return getRange(start, end, TextLayout.TYPE_TEXT, lineSpacing);
}

/**
Expand All @@ -1107,7 +1124,19 @@ public final PathElement[] rangeShape(int start, int end) {
* @since 9
*/
public final PathElement[] underlineShape(int start, int end) {
return getRange(start, end, TextLayout.TYPE_UNDERLINE);
return getRange(start, end, TextLayout.TYPE_UNDERLINE, 0.0);
}

/**
* Returns the shape for the strike-through in local coordinates.
*
* @param start the beginning character index for the range
* @param end the end character index (non-inclusive) for the range
* @return an array of {@code PathElement} which can be used to create a {@code Shape}
* @since 25
*/
public final PathElement[] getStrikeThroughShape(int start, int end) {
return getRange(start, end, TextLayout.TYPE_STRIKETHROUGH, 0.0);
}

private float getYAdjustment(BaseBounds bounds) {
Expand Down Expand Up @@ -1769,7 +1798,7 @@ final ReadOnlyObjectProperty<PathElement[]> selectionShapeProperty() {
@Override protected PathElement[] computeValue() {
int start = getSelectionStart();
int end = getSelectionEnd();
return getRange(start, end, TextLayout.TYPE_TEXT);
return getRange(start, end, TextLayout.TYPE_TEXT, 0.0);
}
};
selectionShape = new SimpleObjectProperty<>(Text.this, "selectionShape");
Expand Down
113 changes: 108 additions & 5 deletions modules/javafx.graphics/src/main/java/javafx/scene/text/TextFlow.java
Original file line number Diff line number Diff line change
Expand Up @@ -193,11 +193,15 @@ private void checkOrientation() {

/**
* Maps local point to {@link HitInfo} in the content.
* <p>
* NOTE: this method does not take border or padding into account.
*
* @param point the specified point to be tested
* @return a {@code HitInfo} representing the character index found
* @since 9
* @deprecated replaced by {@link #getHitInfo(javafx.geometry.Point2D)}
*/
@Deprecated(since="25")
public final HitInfo hitTest(javafx.geometry.Point2D point) {
if (point != null) {
TextLayout layout = getTextLayout();
Expand All @@ -210,42 +214,132 @@ public final HitInfo hitTest(javafx.geometry.Point2D point) {
}
}

/**
* Maps local point to {@link HitInfo} in the content.
*
* @param point the specified point to be tested
* @return a {@code HitInfo} representing the character index found
* @since 25
*/
public final HitInfo getHitInfo(javafx.geometry.Point2D point) {
if (point != null) {
TextLayout layout = getTextLayout();
double x = point.getX() - snappedLeftInset();
double y = point.getY() - snappedTopInset();
TextLayout.Hit h = layout.getHitInfo((float)x, (float)y);
return new HitInfo(h.getCharIndex(), h.getInsertionIndex(), h.isLeading());
} else {
return null;
}
}

/**
* Returns shape of caret in local coordinates.
* <p>
* NOTE: this method does not take border or padding into account.
*
* @param charIndex the character index for the caret
* @param leading whether the caret is biased on the leading edge of the character
* @return an array of {@code PathElement} which can be used to create a {@code Shape}
* @since 9
* @deprecated replaced by {@link #getCaretShape(int, boolean)}
*/
@Deprecated(since="25")
public PathElement[] caretShape(int charIndex, boolean leading) {
TextLayout.CaretGeometry g = getTextLayout().getCaretGeometry(charIndex, leading);
// TODO padding JDK-8341438?
return TextUtils.getCaretPathElements(g, 0.0, 0.0);
}

/**
* Returns shape of caret in local coordinates.
*
* @param charIndex the character index for the caret
* @param leading whether the caret is biased on the leading edge of the character
* @return an array of {@code PathElement} which can be used to create a {@code Shape}
* @since 25
*/
public PathElement[] getCaretShape(int charIndex, boolean leading) {
TextLayout.CaretGeometry g = getTextLayout().getCaretGeometry(charIndex, leading);
double dx = snappedLeftInset();
double dy = snappedTopInset();
return TextUtils.getCaretPathElements(g, dx, dy);
}

/**
* Returns shape for the range of the text in local coordinates.
* <p>
* NOTES:
* <ul>
* <li>this method does not take border or padding into account
* <li>the shapes returned do not include line spacing
* </ul>
*
* @param start the beginning character index for the range
* @param end the end character index (non-inclusive) for the range
* @return an array of {@code PathElement} which can be used to create a {@code Shape}
* @since 9
* @deprecated replaced by {@link #getRangeShape(int, int, boolean)}
*/
@Deprecated(since="25")
public final PathElement[] rangeShape(int start, int end) {
return getRange(start, end, TextLayout.TYPE_TEXT);
return getRange(start, end, TextLayout.TYPE_TEXT, false, 0.0);
}

/**
* Returns shape for the range of the text in local coordinates.
*
* @param start the beginning character index for the range
* @param end the end character index (non-inclusive) for the range
* @param includeLineSpacing determines whether the result includes the line spacing
* @return an array of {@code PathElement} which can be used to create a {@code Shape}
* @since 25
* @see LayoutInfo#getSelectionGeometry(int, int, boolean)
*/
public final PathElement[] getRangeShape(int start, int end, boolean includeLineSpacing) {
double lineSpacing = includeLineSpacing ? getLineSpacing() : 0.0;
return getRange(start, end, TextLayout.TYPE_TEXT, true, lineSpacing);
}

/**
* Returns the shape for the underline in local coordinates.
* <p>
* NOTE: this method does not take border or padding into account.
*
* @param start the beginning character index for the range
* @param end the end character index (non-inclusive) for the range
* @return an array of {@code PathElement} which can be used to create a {@code Shape}
* @since 21
* @deprecated replaced by {@link #getUnderlineShape(int, int)}
*/
@Deprecated(since="25")
public final PathElement[] underlineShape(int start, int end) {
return getRange(start, end, TextLayout.TYPE_UNDERLINE);
return getRange(start, end, TextLayout.TYPE_UNDERLINE, false, 0.0);
}

/**
* Returns the shape for the underline in local coordinates.
*
* @param start the beginning character index for the range
* @param end the end character index (non-inclusive) for the range
* @return an array of {@code PathElement} which can be used to create a {@code Shape}
* @since 25
* @see LayoutInfo#getUnderlineGeometry(int, int)
*/
public final PathElement[] getUnderlineShape(int start, int end) {
return getRange(start, end, TextLayout.TYPE_UNDERLINE, true, 0.0);
}

/**
* Returns the shape for the strike-through in local coordinates.
*
* @param start the beginning character index for the range
* @param end the end character index (non-inclusive) for the range
* @return an array of {@code PathElement} which can be used to create a {@code Shape}
* @since 25
* @see LayoutInfo#getStrikeThroughGeometry(int, int)
*/
public final PathElement[] getStrikeThroughShape(int start, int end) {
return getRange(start, end, TextLayout.TYPE_STRIKETHROUGH, true, 0.0);
}

@Override
Expand Down Expand Up @@ -368,9 +462,18 @@ public boolean usesMirroring() {
inLayout = false;
}

private PathElement[] getRange(int start, int end, int type) {
private PathElement[] getRange(int start, int end, int type, boolean accountForInsets, double lineSpacing) {
double dx;
double dy;
if (accountForInsets) {
dx = snappedLeftInset();
dy = snappedTopInset();
} else {
dx = 0.0;
dy = 0.0;
}
TextLayout layout = getTextLayout();
return TextUtils.getRange(layout, start, end, type, 0, 0);
return TextUtils.getRange(layout, start, end, type, dx, dy, lineSpacing);
}

private static class EmbeddedSpan implements TextSpan {
Expand Down
Loading