refactor: Simplify column rendering logic in AsciiRenderer and SixelRenderer

Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com>
This commit is contained in:
2026-03-20 15:37:15 +01:00
parent 4d5b30f007
commit ed1e480555
2 changed files with 73 additions and 54 deletions

View File

@@ -861,12 +861,7 @@ class AsciiRenderer extends CliRendererBackend<dynamic> {
}) {
final List<int>? cachedColumn = _mainMenuBandFirstColumn;
if (cachedColumn != null && cachedColumn.isNotEmpty) {
final int bandHeight = cachedColumn.length.clamp(0, 200);
for (int y = 0; y < bandHeight; y++) {
final int paletteIndex = cachedColumn[y];
final int fillIndex = paletteIndex == 0 ? 0 : paletteIndex;
_fillRect320(0, y, 320, 1, ColorPalette.vga32Bit[fillIndex]);
}
_drawScaledColumnBand(cachedColumn);
return;
}
@@ -888,12 +883,7 @@ class AsciiRenderer extends CliRendererBackend<dynamic> {
void _drawMainMenuOptionsSideBars(VgaImage optionsLabel, int optionsX320) {
_mainMenuBandFirstColumn = _cacheFirstColumn(optionsLabel);
final List<int> firstColumn = _mainMenuBandFirstColumn!;
for (int y = 0; y < optionsLabel.height; y++) {
final int paletteIndex = firstColumn[y];
final int fillIndex = paletteIndex == 0 ? 0 : paletteIndex;
_fillRect320(0, y, 320, 1, ColorPalette.vga32Bit[fillIndex]);
}
_drawScaledColumnBand(_mainMenuBandFirstColumn!);
}
List<int> _cacheFirstColumn(VgaImage image) {
@@ -904,6 +894,40 @@ class AsciiRenderer extends CliRendererBackend<dynamic> {
return column;
}
void _drawScaledColumnBand(List<int> column) {
if (column.isEmpty) {
return;
}
final int maxDrawHeight = _usesTerminalLayout
? _terminalPixelHeight
: height;
final double scaleY = maxDrawHeight / 200.0;
final int destHeight = math.max(1, (column.length * scaleY).toInt());
for (int dy = 0; dy < destHeight; dy++) {
final int srcY = (dy / scaleY).toInt().clamp(0, column.length - 1);
final int fillColor = ColorPalette.vga32Bit[column[srcY]];
if (_usesTerminalLayout) {
if (dy < 0 || dy >= _terminalPixelHeight) {
continue;
}
for (int drawX = 0; drawX < _terminalSceneWidth; drawX++) {
_scenePixels[dy][drawX] = fillColor;
}
} else {
if (dy < 0 || dy >= height) {
continue;
}
final List<ColoredChar> row = _screen[dy];
for (int drawX = 0; drawX < width; drawX++) {
row[drawX] = ColoredChar(activeTheme.solid, fillColor);
}
}
}
}
void _applyMenuFade(double alpha, int fadeColor) {
if (alpha <= 0.0) {
return;

View File

@@ -698,39 +698,17 @@ class SixelRenderer extends CliRendererBackend<String> {
}) {
final List<int>? cachedColumn = _mainMenuBandFirstColumn;
if (cachedColumn != null && cachedColumn.isNotEmpty) {
final int bandHeight = cachedColumn.length.clamp(0, 200);
for (int y = 0; y < bandHeight; y++) {
final int paletteIndex = cachedColumn[y];
final int fillIndex = paletteIndex == 0 ? 0 : paletteIndex;
_fillRect320(0, y, 320, 1, fillIndex);
}
_drawScaledColumnBand(cachedColumn);
return;
}
final int mainBarTop = (headingY200 - 4).clamp(0, 199);
_fillRect320(0, mainBarTop, 320, 18, barColor);
int stripeY = mainBarTop + 18;
for (int i = 0; i < 4; i++) {
_fillRect320(
0,
(stripeY + i).clamp(0, 199),
320,
1,
i.isEven ? barColor : backgroundColor,
);
}
_fillRect320(0, mainBarTop, 320, 22, barColor);
}
void _drawMainMenuOptionsSideBars(VgaImage optionsLabel, int optionsX320) {
_mainMenuBandFirstColumn = _cacheFirstColumn(optionsLabel);
final List<int> firstColumn = _mainMenuBandFirstColumn!;
for (int y = 0; y < optionsLabel.height; y++) {
final int paletteIndex = firstColumn[y];
final int fillIndex = paletteIndex == 0 ? 0 : paletteIndex;
_fillRect320(0, y, 320, 1, fillIndex);
}
_drawScaledColumnBand(_mainMenuBandFirstColumn!);
}
List<int> _cacheFirstColumn(VgaImage image) {
@@ -741,6 +719,33 @@ class SixelRenderer extends CliRendererBackend<String> {
return column;
}
void _drawScaledColumnBand(List<int> column) {
if (column.isEmpty) {
return;
}
final double scaleY = height / 200.0;
final int destHeight = math.max(1, (column.length * scaleY).toInt());
for (int dy = 0; dy < destHeight; dy++) {
final int drawY = dy;
if (drawY < 0 || drawY >= height) {
continue;
}
final int srcY = ((dy / destHeight) * column.length).toInt().clamp(
0,
column.length - 1,
);
final int paletteIndex = column[srcY];
final int fillIndex = paletteIndex == 0 ? 0 : paletteIndex;
final int rowStart = drawY * width;
for (int drawX = 0; drawX < width; drawX++) {
_screen[rowStart + drawX] = fillIndex;
}
}
}
bool get _useCompactMenuLayout =>
width < _compactMenuMinWidthPx || height < _compactMenuMinHeightPx;
@@ -782,9 +787,6 @@ class SixelRenderer extends CliRendererBackend<String> {
int colorIndex, {
int scale = 1,
}) {
final double scaleX = width / 320.0;
final double scaleY = height / 200.0;
int x320 = startX;
for (final rune in text.runes) {
final char = String.fromCharCode(rune).toUpperCase();
@@ -799,12 +801,7 @@ class SixelRenderer extends CliRendererBackend<String> {
for (int sx = 0; sx < scale; sx++) {
final int px320 = x320 + (col * scale) + sx;
final int py200 = startY + (row * scale) + sy;
final int drawX = (px320 * scaleX).toInt();
final int drawY = (py200 * scaleY).toInt();
if (drawX >= 0 && drawX < width && drawY >= 0 && drawY < height) {
_screen[drawY * width + drawX] = colorIndex;
}
_fillRect320(px320, py200, 1, 1, colorIndex);
}
}
}
@@ -1088,15 +1085,13 @@ class SixelRenderer extends CliRendererBackend<String> {
final double scaleX = width / 320.0;
final double scaleY = height / 200.0;
final int destStartX = (startX * scaleX).toInt();
final int destStartY = (startY * scaleY).toInt();
final int destWidth = math.max(1, (w * scaleX).toInt());
final int destHeight = math.max(1, (h * scaleY).toInt());
final int destStartX = (startX * scaleX).floor();
final int destEndX = ((startX + w) * scaleX).ceil();
final int destStartY = (startY * scaleY).floor();
final int destEndY = ((startY + h) * scaleY).ceil();
for (int dy = 0; dy < destHeight; dy++) {
for (int dx = 0; dx < destWidth; dx++) {
final int drawX = destStartX + dx;
final int drawY = destStartY + dy;
for (int drawY = destStartY; drawY < destEndY; drawY++) {
for (int drawX = destStartX; drawX < destEndX; drawX++) {
if (drawX >= 0 && drawX < width && drawY >= 0 && drawY < height) {
_screen[drawY * width + drawX] = colorIndex;
}