-
Notifications
You must be signed in to change notification settings - Fork 493
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
8341670: [Text,TextFlow] Public API for Text Layout Info #1596
base: master
Are you sure you want to change the base?
Changes from 14 commits
285db28
43ac0e1
21dbe6c
04c4abb
6869c76
2009a7e
6b7b079
c2e26d5
88e9ee1
17dcdd4
fd84f30
466bba7
5ab4f47
eb99008
6776d97
9b1f99a
4f4e659
dd34810
a716e57
75b171f
029bbe6
3925c02
e139484
8a5b904
a0e59fb
3c2976b
5076f36
4479f0b
c05c790
7c86978
366ae4b
d31eb2b
7ea4e3b
944bd0d
1dd2b0c
2a3a754
c1c46ab
7d656df
0ab5890
d81f65d
d688d74
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,12 +25,10 @@ | |
|
||
package com.sun.javafx.scene.text; | ||
|
||
import javafx.scene.shape.PathElement; | ||
import java.util.Objects; | ||
import com.sun.javafx.geom.BaseBounds; | ||
import com.sun.javafx.geom.Shape; | ||
|
||
import java.util.Objects; | ||
|
||
public interface TextLayout { | ||
|
||
/* Internal flags Flags */ | ||
|
@@ -79,6 +77,12 @@ public interface TextLayout { | |
|
||
public static final int DEFAULT_TAB_SIZE = 8; | ||
|
||
/** Callback to be called for each rectangular shape */ | ||
@FunctionalInterface | ||
public static interface GeometryCallback { | ||
public void addRectangle(float left, float top, float right, float bottom); | ||
} | ||
|
||
public static class Hit { | ||
int charIndex; | ||
int insertionIndex; | ||
|
@@ -233,8 +237,36 @@ public String toString() { | |
*/ | ||
public Hit getHitInfo(float x, float y); | ||
|
||
public PathElement[] getCaretShape(int offset, boolean isLeading, | ||
float x, float y); | ||
public PathElement[] getRange(int start, int end, int type, | ||
float x, float y); | ||
/** | ||
* Queries the caret geometry and associated information at the specified text position. | ||
* <p> | ||
* The geometry is encoded as a sequence of coordinates using two different formats, | ||
* depending on whether the caret is drawn as a single vertical line or as two separate | ||
* lines (a "split" caret). | ||
* <ul> | ||
* <li>{@code x, ymin, ymax} - corresponds to a single line from (x, ymin) tp (x, ymax) | ||
* <li>{@code x, ymin, y2, x2, ymax} - corresponds to a split caret drawn as two lines, the first line | ||
* drawn from (x,ymin) to (x, y2), the second line drawn from (x2, y2) to (x2, ymax). | ||
* </ul> | ||
* | ||
* @param offset the character offset | ||
* @param leading whether the caret is biased on the leading edge of the character | ||
* @return the caret geometry | ||
*/ | ||
public float[] getCaretInf(int offset, boolean leading); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this a typo or is there a reason for naming this method |
||
|
||
/** | ||
* Queries the range geometry of the range of text within the text layout for one of the three possible types: | ||
* <ul> | ||
* <li>{@link #TYPE_STRIKETHROUGH} - strike-through shape | ||
* <li>{@link #TYPE_TEXT} - text selection shape | ||
* <li>{@link #TYPE_UNDERLINE} - underline shape | ||
* </ul> | ||
* | ||
* @param start the start offset | ||
* @param end the end offset | ||
* @param the type of the geometry | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. missing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. eagle eye! |
||
* @param client the callback to invoke for each rectangular shape | ||
*/ | ||
public void getRange(int start, int end, int type, GeometryCallback client); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
/* | ||
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. | ||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
* | ||
* This code is free software; you can redistribute it and/or modify it | ||
* under the terms of the GNU General Public License version 2 only, as | ||
* published by the Free Software Foundation. Oracle designates this | ||
* particular file as subject to the "Classpath" exception as provided | ||
* by Oracle in the LICENSE file that accompanied this code. | ||
* | ||
* This code is distributed in the hope that it will be useful, but WITHOUT | ||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
* version 2 for more details (a copy is included in the LICENSE file that | ||
* accompanied this code). | ||
* | ||
* You should have received a copy of the GNU General Public License version | ||
* 2 along with this work; if not, write to the Free Software Foundation, | ||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
* | ||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
* or visit www.oracle.com if you need additional information or have any | ||
* questions. | ||
*/ | ||
package com.sun.javafx.text; | ||
|
||
import javafx.scene.text.CaretInfo; | ||
|
||
/** | ||
* CaretInfo as reported by the PrismTextLayout. | ||
*/ | ||
public final class PrismCaretInfo extends CaretInfo { | ||
private final double[][] lines; | ||
|
||
public PrismCaretInfo(double[][] lines) { | ||
this.lines = lines; | ||
} | ||
|
||
@Override | ||
public int getLineCount() { | ||
return lines.length; | ||
} | ||
|
||
@Override | ||
public double[] getLineAt(int index) { | ||
return lines[index]; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
/* | ||
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. | ||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
* | ||
* This code is free software; you can redistribute it and/or modify it | ||
* under the terms of the GNU General Public License version 2 only, as | ||
* published by the Free Software Foundation. Oracle designates this | ||
* particular file as subject to the "Classpath" exception as provided | ||
* by Oracle in the LICENSE file that accompanied this code. | ||
* | ||
* This code is distributed in the hope that it will be useful, but WITHOUT | ||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
* version 2 for more details (a copy is included in the LICENSE file that | ||
* accompanied this code). | ||
* | ||
* You should have received a copy of the GNU General Public License version | ||
* 2 along with this work; if not, write to the Free Software Foundation, | ||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
* | ||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
* or visit www.oracle.com if you need additional information or have any | ||
* questions. | ||
*/ | ||
package com.sun.javafx.text; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import javafx.geometry.Rectangle2D; | ||
import javafx.scene.text.CaretInfo; | ||
import javafx.scene.text.LayoutInfo; | ||
import javafx.scene.text.TextLineInfo; | ||
import com.sun.javafx.scene.text.TextLayout; | ||
import com.sun.javafx.scene.text.TextLine; | ||
|
||
/** | ||
* Layout information as reported by PrismLayout. | ||
*/ | ||
public final class PrismLayoutInfo extends LayoutInfo { | ||
private final TextLayout layout; | ||
|
||
public PrismLayoutInfo(TextLayout layout) { | ||
this.layout = layout; | ||
} | ||
|
||
@Override | ||
public Rectangle2D getBounds() { | ||
return TextUtils.toRectangle2D(layout.getBounds()); | ||
} | ||
|
||
@Override | ||
public int getTextLineCount() { | ||
return layout.getLines().length; | ||
} | ||
|
||
@Override | ||
public List<TextLineInfo> getTextLines() { | ||
TextLine[] lines = layout.getLines(); | ||
int sz = lines.length; | ||
ArrayList<TextLineInfo> rv = new ArrayList<>(sz); | ||
for (int i = 0; i < sz; i++) { | ||
rv.add(TextUtils.toLineInfo(lines[i])); | ||
} | ||
return rv; | ||
} | ||
|
||
@Override | ||
public TextLineInfo getTextLine(int index) { | ||
return TextUtils.toLineInfo(layout.getLines()[index]); | ||
} | ||
|
||
@Override | ||
public List<Rectangle2D> selectionShape(int start, int end) { | ||
return getGeometry(start, end, TextLayout.TYPE_TEXT); | ||
} | ||
|
||
@Override | ||
public List<Rectangle2D> strikeThroughShape(int start, int end) { | ||
return getGeometry(start, end, TextLayout.TYPE_STRIKETHROUGH); | ||
} | ||
|
||
@Override | ||
public List<Rectangle2D> underlineShape(int start, int end) { | ||
return getGeometry(start, end, TextLayout.TYPE_UNDERLINE); | ||
} | ||
|
||
private List<Rectangle2D> getGeometry(int start, int end, int type) { | ||
ArrayList<Rectangle2D> rv = new ArrayList<>(); | ||
// TODO padding/border JDK-8341438? | ||
layout.getRange(start, end, type, (left, top, right, bottom) -> { | ||
if (left < right) { | ||
rv.add(new Rectangle2D(left, top, right - left, bottom - top)); | ||
} else { | ||
rv.add(new Rectangle2D(right, top, left - right, bottom - top)); | ||
} | ||
}); | ||
return rv; | ||
} | ||
|
||
private TextLine line(int ix) { | ||
return layout.getLines()[ix]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. bound check? In any case, this private method is not used. |
||
} | ||
|
||
@Override | ||
public CaretInfo caretInfo(int charIndex, boolean leading) { | ||
float[] c = layout.getCaretInf(charIndex, leading); | ||
|
||
// TODO padding/border JDK-8341438? | ||
double[][] lines; | ||
if (c.length == 3) { | ||
// {x, ymin, ymax} - corresponds to a single line from (x, ymin) tp (x, ymax) | ||
lines = new double[][] { | ||
new double[] { | ||
c[0], c[1], c[2] | ||
} | ||
}; | ||
} else { | ||
// {x, y, y2, x2, ymax} - corresponds to a split caret drawn as two lines, the first line | ||
// drawn from (x,y) to (x, y2), the second line drawn from (x2, y2) to (x2, ymax). | ||
double y2 = c[2]; | ||
lines = new double[][] { | ||
new double[] { | ||
c[0], c[1], y2 | ||
}, | ||
new double[] { | ||
c[3], y2, c[4] | ||
} | ||
}; | ||
} | ||
return new PrismCaretInfo(lines); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand that you use
float
here because all the calculations inPrismTextLayout::getRange
use floats (fromTextRun
).However, the calculations down the line to generate the
Rectangle2D
mix floats and doubles without any casting (TextUtils::getRange
with implicit casts from double to float,PrismLayoutInfo::getGeometry
with float and double sums).Do you think we could use doubles here instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the use of float in this interface is correct, but the code in TextUtils::getRange is bad, and i should feel bad. good catch!