provide access to the rectangular area of the current caret

Signed-off-by: Florian Thienel <florian@thienel.org>
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/Cursor.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/Cursor.java
index 4d38865..f0bb9d2 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/Cursor.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/Cursor.java
@@ -34,11 +34,67 @@
 
 	private int offset;
 	private final ContentMap contentMap;
+	private Caret caret;
 
 	public Cursor(final ContentMap contentMap) {
 		this.contentMap = contentMap;
 	}
 
+	public void setPosition(final int offset) {
+		this.offset = offset;
+	}
+
+	public int getPosition() {
+		return offset;
+	}
+
+	public Rectangle getCaretArea() {
+		if (caret == null) {
+			return Rectangle.NULL;
+		}
+		return caret.getArea();
+	}
+
+	public void paint(final Graphics graphics) {
+		final IContentBox box = contentMap.findBoxForPosition(offset);
+		if (box == null) {
+			return;
+		}
+		caret = getCaretForBox(graphics, box, offset);
+
+		if (caret == null) {
+			return;
+		}
+		caret.paint(graphics);
+	}
+
+	private Caret getCaretForBox(final Graphics graphics, final IContentBox box, final int offset) {
+		return box.accept(new BaseBoxVisitorWithResult<Caret>() {
+			@Override
+			public Caret visit(final NodeReference box) {
+				return getCaretForNode(graphics, box, offset);
+			}
+
+			@Override
+			public Caret visit(final TextContent box) {
+				return getCaretForText(graphics, box, offset);
+			}
+		});
+	}
+
+	private Caret getCaretForNode(final Graphics graphics, final NodeReference box, final int offset) {
+		final Rectangle area = getAbsolutePositionArea(graphics, box, offset);
+		if (box.isAtStart(offset)) {
+			return new InsertBeforeNodeCaret(area, box.getNode());
+		} else if (box.isAtEnd(offset) && box.canContainText()) {
+			return new AppendNodeWithTextCaret(area, box.getNode(), box.isEmpty());
+		} else if (box.isAtEnd(offset) && !box.canContainText()) {
+			return new AppendStructuralNodeCaret(area, box.getNode());
+		} else {
+			return null;
+		}
+	}
+
 	private Rectangle getAbsolutePositionArea(final Graphics graphics, final IContentBox box, final int offset) {
 		if (box == null) {
 			return Rectangle.NULL;
@@ -66,24 +122,11 @@
 		});
 	}
 
-	private Rectangle makeAbsolute(final Rectangle rectangle, final IBox box) {
+	private static Rectangle makeAbsolute(final Rectangle rectangle, final IBox box) {
 		return new Rectangle(rectangle.getX() + box.getAbsoluteLeft(), rectangle.getY() + box.getAbsoluteTop(), rectangle.getWidth(), rectangle.getHeight());
 	}
 
-	private Caret getCaretForNode(final Graphics graphics, final NodeReference box) {
-		final Rectangle area = getAbsolutePositionArea(graphics, box, offset);
-		if (box.isAtStart(offset)) {
-			return new InsertBeforeNodeCaret(area, box.getNode());
-		} else if (box.isAtEnd(offset) && box.canContainText()) {
-			return new AppendNodeWithTextCaret(area, box.getNode(), box.isEmpty());
-		} else if (box.isAtEnd(offset) && !box.canContainText()) {
-			return new AppendStructuralNodeCaret(area, box.getNode());
-		} else {
-			return null;
-		}
-	}
-
-	private Caret getCaretForText(final Graphics graphics, final TextContent box) {
+	private Caret getCaretForText(final Graphics graphics, final TextContent box, final int offset) {
 		if (box.getStartOffset() > offset || box.getEndOffset() < offset) {
 			return null;
 		}
@@ -94,37 +137,6 @@
 		return new TextCaret(area, font, character, false);
 	}
 
-	public void paint(final Graphics graphics) {
-		final IContentBox box = contentMap.findBoxForPosition(offset);
-		if (box == null) {
-			return;
-		}
-		final Caret caret = box.accept(new BaseBoxVisitorWithResult<Caret>() {
-			@Override
-			public Caret visit(final NodeReference box) {
-				return getCaretForNode(graphics, box);
-			}
-
-			@Override
-			public Caret visit(final TextContent box) {
-				return getCaretForText(graphics, box);
-			}
-		});
-
-		if (caret == null) {
-			return;
-		}
-		caret.paint(graphics);
-	}
-
-	public void setPosition(final int offset) {
-		this.offset = offset;
-	}
-
-	public int getPosition() {
-		return offset;
-	}
-
 	private static String getNodeStartMarker(final INode node) {
 		return node.accept(new BaseNodeVisitorWithResult<String>() {
 			@Override
@@ -198,6 +210,8 @@
 	}
 
 	private static interface Caret {
+		Rectangle getArea();
+
 		void paint(Graphics graphics);
 	}
 
@@ -211,6 +225,11 @@
 		}
 
 		@Override
+		public Rectangle getArea() {
+			return area;
+		}
+
+		@Override
 		public void paint(final Graphics graphics) {
 			if (area == Rectangle.NULL) {
 				return;
@@ -246,6 +265,11 @@
 		}
 
 		@Override
+		public Rectangle getArea() {
+			return area;
+		}
+
+		@Override
 		public void paint(final Graphics graphics) {
 			if (area == Rectangle.NULL) {
 				return;
@@ -278,6 +302,11 @@
 		}
 
 		@Override
+		public Rectangle getArea() {
+			return area;
+		}
+
+		@Override
 		public void paint(final Graphics graphics) {
 			if (area == Rectangle.NULL) {
 				return;
@@ -314,6 +343,11 @@
 		}
 
 		@Override
+		public Rectangle getArea() {
+			return area;
+		}
+
+		@Override
 		public void paint(final Graphics graphics) {
 			if (area == Rectangle.NULL) {
 				return;