Color alpha support. (#884)

This commit is contained in:
Arthur Sonzogni
2024-06-13 18:43:14 +02:00
committed by GitHub
parent d6a2049483
commit ff305147ca
8 changed files with 162 additions and 33 deletions

View File

@@ -23,6 +23,7 @@ class ClearUnder : public NodeDecorator {
for (int y = box_.y_min; y <= box_.y_max; ++y) {
for (int x = box_.x_min; x <= box_.x_max; ++x) {
screen.PixelAt(x, y) = Pixel();
screen.PixelAt(x, y).character = " "; // Consider the pixel written.
}
}
Node::Render(screen);

View File

@@ -19,9 +19,18 @@ class BgColor : public NodeDecorator {
: NodeDecorator(std::move(child)), color_(color) {}
void Render(Screen& screen) override {
for (int y = box_.y_min; y <= box_.y_max; ++y) {
for (int x = box_.x_min; x <= box_.x_max; ++x) {
screen.PixelAt(x, y).background_color = color_;
if (color_.IsOpaque()) {
for (int y = box_.y_min; y <= box_.y_max; ++y) {
for (int x = box_.x_min; x <= box_.x_max; ++x) {
screen.PixelAt(x, y).background_color = color_;
}
}
} else {
for (int y = box_.y_min; y <= box_.y_max; ++y) {
for (int x = box_.x_min; x <= box_.x_max; ++x) {
Color& color = screen.PixelAt(x, y).background_color;
color = Color::Blend(color, color_);
}
}
}
NodeDecorator::Render(screen);
@@ -36,9 +45,18 @@ class FgColor : public NodeDecorator {
: NodeDecorator(std::move(child)), color_(color) {}
void Render(Screen& screen) override {
for (int y = box_.y_min; y <= box_.y_max; ++y) {
for (int x = box_.x_min; x <= box_.x_max; ++x) {
screen.PixelAt(x, y).foreground_color = color_;
if (color_.IsOpaque()) {
for (int y = box_.y_min; y <= box_.y_max; ++y) {
for (int x = box_.x_min; x <= box_.x_max; ++x) {
screen.PixelAt(x, y).foreground_color = color_;
}
}
} else {
for (int y = box_.y_min; y <= box_.y_max; ++y) {
for (int x = box_.x_min; x <= box_.x_max; ++x) {
Color& color = screen.PixelAt(x, y).foreground_color;
color = Color::Blend(color, color_);
}
}
}
NodeDecorator::Render(screen);
@@ -46,6 +64,7 @@ class FgColor : public NodeDecorator {
Color color_;
};
} // namespace
/// @brief Set the foreground color of an element.

View File

@@ -46,6 +46,57 @@ class DBox : public Node {
child->SetBox(box);
}
}
void Render(Screen& screen) override {
if (children_.size() <= 1) {
return Node::Render(screen);
}
const int width = box_.x_max - box_.x_min + 1;
const int height = box_.y_max - box_.y_min + 1;
std::vector<Pixel> pixels(size_t(width * height));
for (auto& child : children_) {
child->Render(screen);
// Accumulate the pixels
Pixel* acc = pixels.data();
for (int x = 0; x < width; ++x) {
for (int y = 0; y < height; ++y) {
auto& pixel = screen.PixelAt(x + box_.x_min, y + box_.y_min);
acc->background_color =
Color::Blend(acc->background_color, pixel.background_color);
acc->automerge = pixel.automerge || acc->automerge;
if (pixel.character == "") {
acc->foreground_color =
Color::Blend(acc->foreground_color, pixel.background_color);
} else {
acc->blink = pixel.blink;
acc->bold = pixel.bold;
acc->dim = pixel.dim;
acc->inverted = pixel.inverted;
acc->underlined = pixel.underlined;
acc->underlined_double = pixel.underlined_double;
acc->strikethrough = pixel.strikethrough;
acc->hyperlink = pixel.hyperlink;
acc->character = pixel.character;
acc->foreground_color = pixel.foreground_color;
}
++acc;
pixel = Pixel();
}
}
}
// Render the accumulated pixels:
Pixel* acc = pixels.data();
for (int x = 0; x < width; ++x) {
for (int y = 0; y < height; ++y) {
screen.PixelAt(x + box_.x_min, y + box_.y_min) = *acc++;
}
}
}
};
} // namespace