Reputation: 23
I need the absolute position of the charater. With:editorPane.getFontMetrics(f).getAscent()
I only get a relative distance to the baseline. Maybe there is a way to get the absolute position of the baseline?
EDIT: This is the result of rect.y + rect.height - metrics.getDescent() - metrics.getAscent()
Upvotes: -1
Views: 314
Reputation: 44414
Since all fonts in a line share a baseline*, you can compute a character’s visual position by calling modelToView and subtracting the descent and ascent from the bottom of the rectangle.
Since multiple fonts are involved, obviously the getFont method of JEditorPane is not sufficient. The document’s raw element attributes are also insufficient, as an HTMLDocument’s attributes merely model the HTML elements themselves. However, the actual font for any document position can be obtained from the corresponding View:
static Point getLocation(int pos,
JEditorPane editorPane)
throws BadLocationException {
HTMLDocument doc = (HTMLDocument) editorPane.getDocument();
View view = editorPane.getUI().getRootView(editorPane);
int index;
while ((index = view.getViewIndex(pos, Position.Bias.Backward)) >= 0) {
view = view.getView(index);
}
AttributeSet attr = doc.getStyleSheet().getViewAttributes(view);
Font f = doc.getStyleSheet().getFont(attr);
FontMetrics metrics = editorPane.getFontMetrics(f);
Rectangle rect = editorPane.modelToView(pos);
return new Point(rect.x,
rect.y + rect.height - metrics.getDescent() - metrics.getAscent());
}
* For simplicity, I’m ignoring characters with hanging baselines and vertical baselines.
Edit: Since the RTFEditorKit is rarely used, I incorrectly assumed you were using an HTMLEditorKit. This will work with RTF documents:
static Point getLocation(int pos,
JEditorPane editorPane)
throws BadLocationException {
StyledDocument doc = (StyledDocument) editorPane.getDocument();
View view = editorPane.getUI().getRootView(editorPane);
int index;
while ((index = view.getViewIndex(pos, Position.Bias.Backward)) >= 0) {
view = view.getView(index);
}
AttributeSet attr = view.getAttributes();
Font f = doc.getFont(attr);
FontMetrics metrics = editorPane.getFontMetrics(f);
Rectangle rect = editorPane.modelToView(pos);
return new Point(rect.x,
rect.y + rect.height - metrics.getDescent() - metrics.getAscent());
}
Upvotes: 1
Reputation: 23
I'm using the RTFEditorKit. So I changed the code:
static Point getLocation(int pos,
JEditorPane editorPane)
throws BadLocationException {
View view = editorPane.getUI().getRootView(editorPane);
int index;
while ((index = view.getViewIndex(pos, Position.Bias.Backward)) >= 0) {
view = view.getView(index);
}
AttributeSet set = view.getAttributes();
if (set != null && set.getAttribute(StyleConstants.FontFamily) != null) {
Font f = new Font((String) set.getAttribute(StyleConstants.FontFamily), Font.PLAIN, (Integer) set.getAttribute(StyleConstants.FontSize));
FontMetrics metrics = editorPane.getFontMetrics(f);
Rectangle rect = editorPane.modelToView(pos);
return new Point(rect.x,
rect.y + rect.height - metrics.getDescent() - metrics.getAscent());
}
else {
return new Point(0, 0);
}
}
But I always get the ascent of the current Font and not the ascent of the largest Font.
Upvotes: 0