Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -2091,23 +2091,7 @@ private Bounds getParagraphBoundsOnScreen(Cell<Paragraph<PS, SEG, S>, ParagraphB
Bounds nodeScreen = cell.getNode().localToScreen(nodeLocal);
Bounds areaLocal = getBoundsInLocal();
Bounds areaScreen = localToScreen(areaLocal);

// use area's minX if scrolled right and paragraph's left is not visible
double minX = nodeScreen.getMinX() < areaScreen.getMinX()
? areaScreen.getMinX()
: nodeScreen.getMinX();
// use area's minY if scrolled down vertically and paragraph's top is not visible
double minY = nodeScreen.getMinY() < areaScreen.getMinY()
? areaScreen.getMinY()
: nodeScreen.getMinY();
// use area's width whether paragraph spans outside of it or not
// so that short or long paragraph takes up the entire space
double width = areaScreen.getWidth();
// use area's maxY if scrolled up vertically and paragraph's bottom is not visible
double maxY = nodeScreen.getMaxY() < areaScreen.getMaxY()
? nodeScreen.getMaxY()
: areaScreen.getMaxY();
return new BoundingBox(minX, minY, width, maxY - minY);
return new ScreenBounds(areaScreen).getParagraphBoundsFrom(nodeScreen);
}

private Optional<Bounds> getRangeBoundsOnScreen(int paragraphIndex, int from, int to) {
Expand Down
29 changes: 29 additions & 0 deletions richtextfx/src/main/java/org/fxmisc/richtext/ScreenBounds.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package org.fxmisc.richtext;

import javafx.geometry.BoundingBox;
import javafx.geometry.Bounds;

class ScreenBounds {
private final Bounds screen;

public ScreenBounds(Bounds screen) {
this.screen = screen;
}

/**
* Evaluate the paragraph node bounds in the area.
* @param paragraph the paragraph bound position on screen
* @return the bounds inside the area of the provided paragraph bounds.
*/
public Bounds getParagraphBoundsFrom(Bounds paragraph) {
// use area's minX,minY if scrolled right/down and paragraph's left/top is not visible
double minX = Math.max(paragraph.getMinX(), screen.getMinX());
double minY = Math.max(paragraph.getMinY(), screen.getMinY());
// use area's width whether paragraph spans outside of it or not
// so that short or long paragraph takes up the entire space
double width = screen.getWidth();
// use area's maxY if scrolled up vertically and paragraph's bottom is not visible
double maxY = Math.min(paragraph.getMaxY(), screen.getMaxY());
return new BoundingBox(minX, minY, width, maxY - minY);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package org.fxmisc.richtext;

import javafx.geometry.BoundingBox;
import javafx.geometry.Bounds;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class BoundsEvaluatorTest {
private void checkBounds(Bounds bounds, double xMin, double yMin, double xMax, double yMax) {
assertEquals(xMin, bounds.getMinX(), "Invalid min X value");
assertEquals(yMin, bounds.getMinY(), "Invalid min Y value");
assertEquals(xMax, bounds.getMaxX(), "Invalid max X value");
assertEquals(yMax, bounds.getMaxY(), "Invalid max Y value");
}

@Test
@DisplayName("Evaluate paragraph bounds on screen")
void evaluateParagraphBoundsOnScreen() {
ScreenBounds boundsEvaluator = new ScreenBounds(new BoundingBox(20, 20, 100, 100));
// Start < Screen ; End < Screen
checkBounds(boundsEvaluator.getParagraphBoundsFrom(new BoundingBox(10, 10, 50, 50)),
20, 20, 120, 60);
// Start < Screen ; End > Screen
checkBounds(boundsEvaluator.getParagraphBoundsFrom(new BoundingBox(10, 10, 111, 111)),
20, 20, 120, 120);
// Start > Screen ; End > Screen
checkBounds(boundsEvaluator.getParagraphBoundsFrom(new BoundingBox(21, 21, 100, 100)),
21, 21, 121, 120);
// Start > Screen ; End < Screen
checkBounds(boundsEvaluator.getParagraphBoundsFrom(new BoundingBox(21, 21, 98, 98)),
21, 21, 121, 119);
// Start = Screen ; End = Screen
checkBounds(boundsEvaluator.getParagraphBoundsFrom(new BoundingBox(20, 20, 100, 100)),
20, 20, 120, 120);
// Miscellaneous
checkBounds(boundsEvaluator.getParagraphBoundsFrom(new BoundingBox(0, 0, 80, 80)),
20, 20, 120, 80);
checkBounds(boundsEvaluator.getParagraphBoundsFrom(new BoundingBox(30, 30, 120, 120)),
30, 30, 130, 120);
checkBounds(boundsEvaluator.getParagraphBoundsFrom(new BoundingBox(110, 110, 130, 130)),
110, 110, 210, 120);
}
}