/** * Calls layout() on the rootBox until the y-coordinate of a caret at the given offset converges, * i.e. is less than LAYOUT_TOLERANCE pixels from the last call. * * @param offset Offset around which we should lay out boxes. */ private void iterateLayout(int offset) { int repaintStart = Integer.MAX_VALUE; int repaintEnd = 0; Graphics g = this.hostComponent.createDefaultGraphics(); LayoutContext context = this.createLayoutContext(g); int layoutY = this.rootBox.getCaret(context, offset).getY(); while (true) { int oldLayoutY = layoutY; IntRange repaintRange = this.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()); } layoutY = this.rootBox.getCaret(context, offset).getY(); if (Math.abs(layoutY - oldLayoutY) < LAYOUT_TOLERANCE) { break; } } g.dispose(); if (repaintStart < repaintEnd) { Rectangle viewport = this.hostComponent.getViewport(); if (repaintStart < viewport.getY() + viewport.getHeight() && repaintEnd > viewport.getY()) { int start = Math.max(repaintStart, viewport.getY()); int end = Math.min(repaintEnd, viewport.getY() + viewport.getHeight()); this.hostComponent.repaint(viewport.getX(), start, viewport.getWidth(), end - start); } } }
/** Repaints the area of the caret. */ private void repaintCaret() { if (this.caret != null) { // caret may be null when document is first set Rectangle bounds = this.caret.getBounds(); this.hostComponent.repaint( bounds.getX(), bounds.getY(), bounds.getWidth(), bounds.getHeight()); } }