refactor: Simplify column rendering logic in AsciiRenderer and SixelRenderer
Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com>
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user