60 lines
1.7 KiB
C++
60 lines
1.7 KiB
C++
#include "core/rendering/canvas.hpp"
|
|
|
|
#include <algorithm>
|
|
#include <vector>
|
|
|
|
#include "core/rendering/screen.hpp"
|
|
|
|
namespace Rendering {
|
|
|
|
namespace {
|
|
|
|
// Pila de clips en un namespace anònim perquè no siga accessible des
|
|
// de fora. L'app és single-threaded; si algun dia hi ha threads de
|
|
// render, s'ha de fer thread_local o passar-la explícitament.
|
|
auto clipStack() -> std::vector<Clip>& {
|
|
static std::vector<Clip> stack_;
|
|
return stack_;
|
|
}
|
|
|
|
} // namespace
|
|
|
|
auto activeCanvas() -> Canvas {
|
|
auto& screen = Screen::get();
|
|
return {
|
|
.pixels = screen.getCanvasArgb(),
|
|
.width = screen.getCanvasWidth(),
|
|
.height = screen.getCanvasHeight(),
|
|
};
|
|
}
|
|
|
|
auto activeClip() -> Clip {
|
|
const auto& stack = clipStack();
|
|
if (!stack.empty()) { return stack.back(); }
|
|
const auto CANVAS = activeCanvas();
|
|
return {.x = 0, .y = 0, .w = CANVAS.width, .h = CANVAS.height};
|
|
}
|
|
|
|
void pushClip(Clip rect) {
|
|
// Retall contra el canvas per garantir que els blitters no s'han
|
|
// de preocupar de coordenades negatives o més grans que el canvas.
|
|
const auto CANVAS = activeCanvas();
|
|
const int X0 = std::max(rect.x, 0);
|
|
const int Y0 = std::max(rect.y, 0);
|
|
const int X1 = std::min(rect.x + rect.w, CANVAS.width);
|
|
const int Y1 = std::min(rect.y + rect.h, CANVAS.height);
|
|
clipStack().push_back({
|
|
.x = X0,
|
|
.y = Y0,
|
|
.w = std::max(0, X1 - X0),
|
|
.h = std::max(0, Y1 - Y0),
|
|
});
|
|
}
|
|
|
|
void popClip() {
|
|
auto& stack = clipStack();
|
|
if (!stack.empty()) { stack.pop_back(); }
|
|
}
|
|
|
|
} // namespace Rendering
|