snap repaint clear/fill to integer pixels to kill seam bars
cellWidth is fractional, so in repaintColumns the clearRect cleared a run's edge pixel to full transparency while the background fillRect covered that same pixel only partially (antialiased), leaving a ~1px part-transparent column that showed the near-black pane background as a thin bar 1-2 cells before the cursor. Full-row repaint hid it because the highlighted line is then one contiguous fill with no internal junction. Route the clear and the background fills through a shared columnX() that rounds each column boundary to a whole device pixel, so run edges land on integer pixels with full single coverage and adjacent runs tile seamlessly. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -825,6 +825,14 @@ final class TerminalPaneNode extends Region {
|
||||
return Math.ceil(TerminalMetrics.PADDING + (row + 1) * metrics.lineHeight());
|
||||
}
|
||||
|
||||
// Left edge of a column, snapped to a whole device pixel. Both the clearRect and the
|
||||
// background fillRect go through this so a run's edges land on integer pixels: at a
|
||||
// fractional boundary clearRect clears the edge pixel fully while fillRect would only
|
||||
// cover it partially, leaving a thin transparent (black) seam through the line.
|
||||
private double columnX(int column) {
|
||||
return Math.round(TerminalMetrics.PADDING + column * metrics.cellWidth());
|
||||
}
|
||||
|
||||
private void repaintColumns(GraphicsContext gc, RenderRow row, int startColumn, int endColumn) {
|
||||
if (endColumn < startColumn) {
|
||||
return;
|
||||
@@ -836,8 +844,8 @@ final class TerminalPaneNode extends Region {
|
||||
double contentTop = TerminalMetrics.PADDING + row.row() * lineHeight;
|
||||
double localCellTop = contentTop - rowTop;
|
||||
double baseline = TerminalMetrics.PADDING + metrics.baselineOffset() + row.row() * lineHeight - rowTop;
|
||||
double x = TerminalMetrics.PADDING + startColumn * cellWidth;
|
||||
double width = (endColumn - startColumn + 1) * cellWidth;
|
||||
double x = columnX(startColumn);
|
||||
double width = columnX(endColumn + 1) - x;
|
||||
|
||||
gc.clearRect(x, 0.0, width, canvas.getHeight());
|
||||
if (startColumn == 0) {
|
||||
@@ -845,7 +853,7 @@ final class TerminalPaneNode extends Region {
|
||||
gc.fillRect(0.0, 0.0, TerminalMetrics.PADDING, canvas.getHeight());
|
||||
}
|
||||
if (endColumn >= row.cells().size() - 1) {
|
||||
double contentRight = TerminalMetrics.PADDING + row.cells().size() * cellWidth;
|
||||
double contentRight = columnX(row.cells().size());
|
||||
gc.setFill(rowEdgeBackground(row, false));
|
||||
gc.fillRect(contentRight, 0.0, canvas.getWidth() - contentRight, canvas.getHeight());
|
||||
}
|
||||
@@ -860,7 +868,7 @@ final class TerminalPaneNode extends Region {
|
||||
return;
|
||||
}
|
||||
double contentLeft = TerminalMetrics.PADDING;
|
||||
double contentRight = contentLeft + columns * metrics.cellWidth();
|
||||
double contentRight = columnX(columns);
|
||||
gc.setFill(rowEdgeBackground(row, true));
|
||||
gc.fillRect(0.0, 0.0, contentLeft, bandHeight);
|
||||
gc.setFill(rowEdgeBackground(row, false));
|
||||
@@ -914,11 +922,12 @@ final class TerminalPaneNode extends Region {
|
||||
if (background == null || endColumn < startColumn) {
|
||||
return;
|
||||
}
|
||||
double left = columnX(startColumn);
|
||||
gc.setFill(background);
|
||||
gc.fillRect(
|
||||
TerminalMetrics.PADDING + startColumn * cellWidth,
|
||||
left,
|
||||
localCellTop,
|
||||
(endColumn - startColumn + 1) * cellWidth,
|
||||
columnX(endColumn + 1) - left,
|
||||
lineHeight);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user