use VerticalRange arithmetics where possible
Signed-off-by: Florian Thienel <florian@thienel.org>
diff --git a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/DocumentTest.java b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/DocumentTest.java
index b6720a7..6b8305c 100644
--- a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/DocumentTest.java
+++ b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/DocumentTest.java
@@ -59,7 +59,7 @@
document.insertText(childElement.getStartOffset(), "Hello ");
document.insertText(childElement.getEndOffset(), "Child");
document.insertText(childElement.getEndOffset() + 1, " World");
- final ContentRange range = childElement.getRange().resize(-2, 2);
+ final ContentRange range = childElement.getRange().resizeBy(-2, 2);
final DocumentFragment fragment = document.getFragment(range);
assertEquals(11, fragment.getLength());
assertNodesEqual(document.getNodes(range), fragment.getNodes());
diff --git a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/NodeTest.java b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/NodeTest.java
index 9e4c4bd..6c5b967 100644
--- a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/NodeTest.java
+++ b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/NodeTest.java
@@ -131,13 +131,13 @@
content.insertText(0, "prefix");
content.insertText(content.length(), "suffix");
- assertTrue(node.isInRange(node.getRange().resize(-1, 0)));
+ assertTrue(node.isInRange(node.getRange().resizeBy(-1, 0)));
assertTrue(node.isInRange(node.getRange()));
- assertFalse(node.isInRange(node.getRange().resize(1, 0)));
- assertTrue(node.isInRange(node.getRange().resize(0, 1)));
- assertFalse(node.isInRange(node.getRange().resize(0, -1)));
- assertTrue(node.isInRange(node.getRange().resize(-1, 1)));
- assertFalse(node.isInRange(node.getRange().resize(1, -1)));
+ assertFalse(node.isInRange(node.getRange().resizeBy(1, 0)));
+ assertTrue(node.isInRange(node.getRange().resizeBy(0, 1)));
+ assertFalse(node.isInRange(node.getRange().resizeBy(0, -1)));
+ assertTrue(node.isInRange(node.getRange().resizeBy(-1, 1)));
+ assertFalse(node.isInRange(node.getRange().resizeBy(1, -1)));
}
@Test
diff --git a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/ParentTest.java b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/ParentTest.java
index cd24af6..57ad29d 100644
--- a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/ParentTest.java
+++ b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/ParentTest.java
@@ -171,7 +171,7 @@
content.insertText(child1.getStartOffset(), "Hello");
content.insertText(child2.getStartOffset(), "World!");
- final List<Node> childNodes = parent.getChildNodes(child1.getRange().resize(-2, 2));
+ final List<Node> childNodes = parent.getChildNodes(child1.getRange().resizeBy(-2, 2));
assertEquals(3, childNodes.size());
assertTrue(childNodes.get(0) instanceof Text);
assertSame(child1, childNodes.get(1));
@@ -358,7 +358,7 @@
public void shouldHandleSmallerStartOffset() throws Exception {
setUpChildNodes();
content.insertText(parent.getStartOffset(), "prefix");
- final List<Node> childNodes = parent.getChildNodes(parent.getRange().resize(-2, 0));
+ final List<Node> childNodes = parent.getChildNodes(parent.getRange().resizeBy(-2, 0));
assertTextNodeEquals("Hello ", 7, 12, childNodes.get(0));
assertChildNodeEquals("Child1", 13, 20, childNodes.get(1));
assertChildNodeEquals("Child2", 21, 28, childNodes.get(2));
diff --git a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/RangeTest.java b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/RangeTest.java
index 4171924..b77910d 100644
--- a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/RangeTest.java
+++ b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/RangeTest.java
@@ -59,7 +59,7 @@
@Test
public void canMoveBounds() throws Exception {
- assertEquals(new ContentRange(1, 8), new ContentRange(3, 5).resize(-2, 3));
+ assertEquals(new ContentRange(1, 8), new ContentRange(3, 5).resizeBy(-2, 3));
}
@Test
diff --git a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/widget/L2SelectionTest.java b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/widget/L2SelectionTest.java
index ebe2bdd..73aa374 100644
--- a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/widget/L2SelectionTest.java
+++ b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/widget/L2SelectionTest.java
@@ -41,7 +41,7 @@
final Element titleElement = widget.insertElement(TITLE);
widget.moveBy(-1, true);
assertTrue(widget.hasSelection());
- assertEquals(titleElement.getRange().resize(0, -1), widget.getSelectedRange());
+ assertEquals(titleElement.getRange().resizeBy(0, -1), widget.getSelectedRange());
}
@Test
@@ -51,7 +51,7 @@
widget.moveBy(-5, false);
widget.moveTo(titleElement.getStartOffset(), true);
assertTrue(widget.hasSelection());
- assertEquals(titleElement.getRange().resize(0, -1), widget.getSelectedRange());
+ assertEquals(titleElement.getRange().resizeBy(0, -1), widget.getSelectedRange());
}
@Test
@@ -68,6 +68,6 @@
final Element titleElement = widget.insertElement(TITLE);
widget.insertText("Hello World");
widget.moveTo(titleElement.getStartOffset() + 1, true);
- assertEquals(titleElement.getRange().resize(1, -1), widget.getSelectedRange());
+ assertEquals(titleElement.getRange().resizeBy(1, -1), widget.getSelectedRange());
}
}
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/ContentRange.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/ContentRange.java
index d8cb81c..79bc33a 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/ContentRange.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/ContentRange.java
@@ -61,10 +61,10 @@
}
public ContentRange moveBy(final int delta) {
- return resize(delta, delta);
+ return resizeBy(delta, delta);
}
- public ContentRange resize(final int deltaStart, final int deltaEnd) {
+ public ContentRange resizeBy(final int deltaStart, final int deltaEnd) {
return new ContentRange(startOffset + deltaStart, endOffset + deltaEnd);
}
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/GapContent.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/GapContent.java
index 91149fb..21a8ac3 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/GapContent.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/GapContent.java
@@ -187,7 +187,7 @@
if (range.getEndOffset() < gapStart) {
appendPlainText(result, range);
} else if (range.getStartOffset() >= gapStart) {
- appendPlainText(result, range.resize(delta, delta));
+ appendPlainText(result, range.moveBy(delta));
} else {
appendPlainText(result, new ContentRange(range.getStartOffset(), gapStart - 1));
appendPlainText(result, new ContentRange(gapEnd, range.getEndOffset() + delta));
@@ -216,7 +216,7 @@
if (range.getEndOffset() < gapStart) {
appendRawText(result, range);
} else if (range.getStartOffset() >= gapStart) {
- appendRawText(result, range.resize(delta, delta));
+ appendRawText(result, range.moveBy(delta));
} else {
appendRawText(result, new ContentRange(range.getStartOffset(), gapStart - 1));
appendRawText(result, new ContentRange(gapEnd, range.getEndOffset() + delta));
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/layout/AbstractBlockBox.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/layout/AbstractBlockBox.java
index b2f62ea..d8c28f5 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/layout/AbstractBlockBox.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/layout/AbstractBlockBox.java
@@ -559,8 +559,7 @@
public VerticalRange layout(final LayoutContext context, final int top, final int bottom) {
- int repaintStart = Integer.MAX_VALUE;
- int repaintEnd = 0;
+ VerticalRange repaintRange = null;
boolean repaintToBottom = false;
final int originalHeight = getHeight();
@@ -583,7 +582,7 @@
// repaint everything
repaintToBottom = true;
- repaintStart = 0;
+ repaintRange = new VerticalRange(0, 0);
}
final Box[] children = getChildren();
@@ -592,10 +591,13 @@
final BlockBox child = (BlockBox) element2;
if (top <= child.getY() + child.getHeight() && bottom >= child.getY()) {
- final VerticalRange repaintRange = child.layout(context, top - child.getY(), bottom - child.getY());
- if (repaintRange != null) {
- repaintStart = Math.min(repaintStart, repaintRange.getStart() + child.getY());
- repaintEnd = Math.max(repaintEnd, repaintRange.getEnd() + child.getY());
+ final VerticalRange layoutRange = child.layout(context, top - child.getY(), bottom - child.getY());
+ if (layoutRange != null) {
+ if (repaintRange == null) {
+ repaintRange = layoutRange.moveBy(child.getY());
+ } else {
+ repaintRange = repaintRange.union(layoutRange.moveBy(child.getY()));
+ }
}
}
}
@@ -604,20 +606,20 @@
final int childRepaintStart = positionChildren(context);
if (childRepaintStart != -1) {
repaintToBottom = true;
- repaintStart = Math.min(repaintStart, childRepaintStart);
+ repaintRange = new VerticalRange(Math.min(repaintRange.getStart(), childRepaintStart), repaintRange.getEnd());
}
layoutState = LAYOUT_OK;
if (repaintToBottom) {
- repaintEnd = Math.max(originalHeight, getHeight());
+ repaintRange = new VerticalRange(repaintRange.getStart(), Math.max(originalHeight, getHeight()));
}
- if (repaintStart < repaintEnd) {
- return new VerticalRange(repaintStart, repaintEnd);
- } else {
+ if (repaintRange == null || repaintRange.isEmpty()) {
return null;
}
+
+ return repaintRange;
}
protected abstract List<Box> createChildren(LayoutContext context);
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/layout/RootBox.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/layout/RootBox.java
index 7d57c90..7a58528 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/layout/RootBox.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/layout/RootBox.java
@@ -154,7 +154,7 @@
setHeight(childBox.getHeight() + insets.getTop() + insets.getBottom());
if (repaintRange != null) {
- return new VerticalRange(repaintRange.getStart() + childBox.getY(), repaintRange.getEnd() + childBox.getY());
+ return repaintRange.moveBy(childBox.getY());
} else {
return null;
}
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/layout/VerticalRange.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/layout/VerticalRange.java
index 8669f70..5058eb8 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/layout/VerticalRange.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/layout/VerticalRange.java
@@ -51,6 +51,25 @@
return end;
}
+ public int getHeight() {
+ return end - start;
+ }
+
+ /**
+ * Returns true if start and end are equal.
+ */
+ public boolean isEmpty() {
+ return getHeight() == 0;
+ }
+
+ public boolean contains(final VerticalRange other) {
+ return start <= other.start && end >= other.end;
+ }
+
+ public boolean contains(final int y) {
+ return start <= y && y <= end;
+ }
+
/**
* Returns true if this range intersects the given range, even if the result would be an empty range.
*
@@ -88,11 +107,12 @@
return new VerticalRange(Math.min(start, range.start), Math.min(end, range.end));
}
- /**
- * Returns true if start and end are equal.
- */
- public boolean isEmpty() {
- return start == end;
+ public VerticalRange moveBy(final int delta) {
+ return resizeBy(delta, delta);
+ }
+
+ public VerticalRange resizeBy(final int deltaStart, final int deltaEnd) {
+ return new VerticalRange(start + deltaStart, end + deltaEnd);
}
@Override
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/undo/InsertFragmentEdit.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/undo/InsertFragmentEdit.java
index 7d29813..f34a735 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/undo/InsertFragmentEdit.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/undo/InsertFragmentEdit.java
@@ -22,7 +22,7 @@
public void undo() throws CannotUndoException {
try {
- document.delete(fragment.getContent().getRange().resize(offset, offset));
+ document.delete(fragment.getContent().getRange().moveBy(offset));
} catch (final DocumentValidationException ex) {
throw new CannotUndoException();
}
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/VexWidgetImpl.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/VexWidgetImpl.java
index 3bcf8d0..a5c46a8 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/VexWidgetImpl.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/VexWidgetImpl.java
@@ -34,6 +34,7 @@
import org.eclipse.vex.core.internal.css.StyleSheet;
import org.eclipse.vex.core.internal.css.StyleSheetReader;
import org.eclipse.vex.core.internal.css.Styles;
+import org.eclipse.vex.core.internal.dom.ContentRange;
import org.eclipse.vex.core.internal.dom.Document;
import org.eclipse.vex.core.internal.dom.DocumentEvent;
import org.eclipse.vex.core.internal.dom.DocumentFragment;
@@ -42,15 +43,14 @@
import org.eclipse.vex.core.internal.dom.Element;
import org.eclipse.vex.core.internal.dom.Node;
import org.eclipse.vex.core.internal.dom.Position;
-import org.eclipse.vex.core.internal.dom.ContentRange;
import org.eclipse.vex.core.internal.dom.Validator;
import org.eclipse.vex.core.internal.layout.BlockBox;
import org.eclipse.vex.core.internal.layout.Box;
import org.eclipse.vex.core.internal.layout.BoxFactory;
import org.eclipse.vex.core.internal.layout.CssBoxFactory;
-import org.eclipse.vex.core.internal.layout.VerticalRange;
import org.eclipse.vex.core.internal.layout.LayoutContext;
import org.eclipse.vex.core.internal.layout.RootBox;
+import org.eclipse.vex.core.internal.layout.VerticalRange;
import org.eclipse.vex.core.internal.undo.CannotRedoException;
import org.eclipse.vex.core.internal.undo.CannotUndoException;
import org.eclipse.vex.core.internal.undo.ChangeAttributeEdit;
@@ -1439,19 +1439,20 @@
*/
private void iterateLayout(final int offset) {
- int repaintStart = Integer.MAX_VALUE;
- int repaintEnd = 0;
+ VerticalRange repaintRange = null;
final Graphics g = hostComponent.createDefaultGraphics();
final LayoutContext context = createLayoutContext(g);
int layoutY = rootBox.getCaret(context, offset).getY();
while (true) {
-
final int oldLayoutY = layoutY;
- final VerticalRange repaintRange = rootBox.layout(context, layoutY - LAYOUT_WINDOW / 2, layoutY + LAYOUT_WINDOW / 2);
- if (repaintRange != null) {
- repaintStart = Math.min(repaintStart, repaintRange.getStart());
- repaintEnd = Math.max(repaintEnd, repaintRange.getEnd());
+ final VerticalRange layoutRange = rootBox.layout(context, layoutY - LAYOUT_WINDOW / 2, layoutY + LAYOUT_WINDOW / 2);
+ if (layoutRange != null) {
+ if (repaintRange == null) {
+ repaintRange = layoutRange;
+ } else {
+ repaintRange = repaintRange.union(layoutRange);
+ }
}
layoutY = rootBox.getCaret(context, offset).getY();
@@ -1461,13 +1462,15 @@
}
g.dispose();
- if (repaintStart < repaintEnd) {
- final Rectangle viewport = hostComponent.getViewport();
- if (repaintStart < viewport.getY() + viewport.getHeight() && repaintEnd > viewport.getY()) {
- final int start = Math.max(repaintStart, viewport.getY());
- final int end = Math.min(repaintEnd, viewport.getY() + viewport.getHeight());
- hostComponent.repaint(viewport.getX(), start, viewport.getWidth(), end - start);
- }
+ if (repaintRange == null || repaintRange.isEmpty()) {
+ return;
+ }
+
+ final Rectangle viewport = hostComponent.getViewport();
+ final VerticalRange viewportRange = new VerticalRange(viewport.getY(), viewport.getY() + viewport.getHeight());
+ if (repaintRange.intersects(viewportRange)) {
+ final VerticalRange intersection = repaintRange.intersection(viewportRange);
+ hostComponent.repaint(viewport.getX(), intersection.getStart(), viewport.getWidth(), intersection.getHeight());
}
}