#include "Brushstroke.h" Brushstroke::~Brushstroke() { delete strokeContext->RenderQueued(&boundingBox); // delete associated texture delete strokeContext; delete previousTarget; } Brushstroke::Brushstroke(StrokeRenderingContext* strokeContext, PaintLayerNode* target, bool isEraser, Brush* brushCopy) { this->strokeContext = strokeContext; this->target = target; this->isEraser = isEraser; this->brushCopy = brushCopy; // this is probably gonna go horribly wrong once users can reload brushes and remove WHICH THEY KINDOF actualy no they can't yet BUT TODO: watch out for this } void Brushstroke::Execute() { strokeContext->RenderQueued(&boundingBox); assert(boundingBox.w > 0.0f); SDL_GPUTextureCreateInfo createInfo = {}; createInfo.width = (int)boundingBox.w; createInfo.height = (int)boundingBox.h; createInfo.format = SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM; createInfo.usage = SDL_GPU_TEXTUREUSAGE_COLOR_TARGET | SDL_GPU_TEXTUREUSAGE_SAMPLER; createInfo.layer_count_or_depth = 1; createInfo.num_levels = 1; createInfo.sample_count = SDL_GPU_SAMPLECOUNT_1; previousTarget = new Texture(createInfo); // copy from canvas the current state before we apply target->Target->CopyTo(previousTarget, { (int)boundingBox.x, (int)boundingBox.y }, { 0, 0 }, { (int)boundingBox.w, (int)boundingBox.h }); // apply strokeContext->RenderResultOnto(target->Target, isEraser); strokeContext->Minimize(); timestamp = std::chrono::system_clock::now(); } json Brushstroke::SerializeArgs() { json j = json::object(); // TODO: this command is stateless, meaning things like color, opacity, brush picking needs separate commands, otherwise we have nothing to reconstruct brushstroke fully json arr = json::array(); std::list inputs = strokeContext->GetCompleteInputs(); for (const PointerEvent& input : inputs) { json event = json::array(); event.push_back(input.timestampNanos); event.push_back(input.canvasX); event.push_back(input.canvasY); event.push_back(input.pressure); arr.push_back(event); } j["inputs"] = arr; return j; } std::string Brushstroke::GetTitle() { return "Brushstroke"; } void Brushstroke::Undo() { previousTarget->CopyTo(target->Target, { 0, 0 }, { (int)boundingBox.x, (int)boundingBox.y }, { (int)boundingBox.w, (int)boundingBox.h }); } const char* Brushstroke::GetIdentity() const { return "brushstroke"; }