recover abstract terminal renderer
This commit is contained in:
60
src/main/java/com/gregor/jprototerm/TerminalRenderer.java
Normal file
60
src/main/java/com/gregor/jprototerm/TerminalRenderer.java
Normal file
@@ -0,0 +1,60 @@
|
||||
package com.gregor.jprototerm;
|
||||
|
||||
import javafx.scene.canvas.GraphicsContext;
|
||||
import javafx.scene.shape.ClosePath;
|
||||
import javafx.scene.shape.LineTo;
|
||||
import javafx.scene.shape.MoveTo;
|
||||
import javafx.scene.shape.Path;
|
||||
import javafx.scene.shape.PathElement;
|
||||
import javafx.scene.shape.Shape;
|
||||
|
||||
/**
|
||||
* Draws a {@link RenderTarget} onto a JavaFX canvas. The {@link Compositor} owns positioning
|
||||
* and z-order; a renderer only fills the target's rect, clipped to the target's {@link
|
||||
* RenderTarget#clip() clip region} so a repaint can never bleed over a pane on top.
|
||||
* Implementations can change the look entirely — {@link GhosttyTerminalRenderer} is the real
|
||||
* terminal renderer; a debug renderer could outline pane bounds instead.
|
||||
*
|
||||
* <p>A renderer may hold per-target state (e.g. a decoded-image cache), so an instance belongs
|
||||
* to a single {@link TerminalPane}.
|
||||
*/
|
||||
abstract class TerminalRenderer {
|
||||
/** Paint the whole target into its rect, clipped to its clip region. */
|
||||
abstract void paintFull(GraphicsContext gc, RenderTarget target, boolean active);
|
||||
|
||||
/** Repaint only what changed since the last frame, clipped to the target's clip region. */
|
||||
abstract void paintIncremental(GraphicsContext gc, RenderTarget target, boolean active);
|
||||
|
||||
protected static void clipRect(GraphicsContext gc, double x, double y, double width, double height) {
|
||||
gc.beginPath();
|
||||
gc.rect(x, y, width, height);
|
||||
gc.clip();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clip to {@code region} if given (the pane's rect minus the panes covering it, computed by
|
||||
* {@code Shape.subtract} at layout), otherwise to the plain rect. The region is a rectilinear
|
||||
* path, so it replays onto the canvas as move/line/close segments.
|
||||
*/
|
||||
protected static void clip(GraphicsContext gc, double x, double y, double width, double height, Shape region) {
|
||||
if (region == null) {
|
||||
clipRect(gc, x, y, width, height);
|
||||
return;
|
||||
}
|
||||
var elements = ((Path) region).getElements();
|
||||
gc.beginPath();
|
||||
if (elements.isEmpty()) {
|
||||
gc.rect(x, y, 0.0, 0.0); // fully covered: clip to nothing
|
||||
}
|
||||
for (PathElement element : elements) {
|
||||
if (element instanceof MoveTo moveTo) {
|
||||
gc.moveTo(moveTo.getX(), moveTo.getY());
|
||||
} else if (element instanceof LineTo lineTo) {
|
||||
gc.lineTo(lineTo.getX(), lineTo.getY());
|
||||
} else if (element instanceof ClosePath) {
|
||||
gc.closePath();
|
||||
}
|
||||
}
|
||||
gc.clip();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user