/* Crafter®.Graphics Copyright (C) 2026 Catcrafts® catcrafts.net This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License version 3.0 as published by the Free Software Foundation; This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ export module Crafter.Graphics:RenderingElement2DBase; import Crafter.Asset; import Crafter.Math; import std; import :Transform2D; export namespace Crafter { enum class TextAlignment { Left, Center, Right }; enum class TextVerticalAlignment { Top, Center, Bottom }; enum class TextOverflowMode { Clip, Wrap }; enum class TextScaleMode { None, Font, Element, Buffer }; template struct RenderElement2DScalingOwning { std::vector> scalingBuffer; std::uint32_t bufferWidth; std::uint32_t bufferHeight; RenderElement2DScalingOwning() = default; RenderElement2DScalingOwning(std::uint32_t bufferWidth, std::uint32_t bufferHeight) : scalingBuffer(bufferWidth*bufferHeight), bufferWidth(bufferWidth), bufferHeight(bufferHeight) { } }; template struct RenderElement2DScalingNonOwning { Vector* scalingBuffer; std::uint32_t bufferWidth; std::uint32_t bufferHeight; RenderElement2DScalingNonOwning() = default; RenderElement2DScalingNonOwning(Vector* scalingBuffer, std::uint32_t bufferWidth, std::uint32_t bufferHeight) : scalingBuffer(scalingBuffer), bufferWidth(bufferWidth), bufferHeight(bufferHeight) { } }; struct RenderElement2DRotating { float rotation; RenderElement2DRotating() = default; RenderElement2DRotating(float rotation) : rotation(rotation) { } }; struct EmptyScalingBase {}; struct EmptyRotatingBase {}; template using ScalingBase = std::conditional_t< Scaling, std::conditional_t, RenderElement2DScalingNonOwning>, EmptyScalingBase >; template using RotatingBase = std::conditional_t< Rotating, RenderElement2DRotating, EmptyRotatingBase >; template struct RenderingElement2DBase : Transform2D { ScaleData2D oldScale[Frames]; bool redraw[Frames]; std::vector> buffer; OpaqueType opaque; RenderingElement2DBase(Anchor2D anchor) : Transform2D(anchor) { for(std::uint8_t i = 0; i < Frames; i++) { this->scaled.size.x = 0; } } RenderingElement2DBase(Anchor2D anchor, OpaqueType opaque) : Transform2D(anchor), opaque(opaque) { for(std::uint8_t i = 0; i < Frames; i++) { this->scaled.size.x = 0; } } void Redraw() { for(std::uint8_t i = 0; i < Frames; i++) { redraw[i] = true; } } void CopyNearestNeighbor(Vector* dst, std::uint16_t dstSizeX, std::uint16_t dstScaledSizeX, std::uint16_t dstScaledSizeY, std::uint16_t offsetX, std::uint16_t offsetY) { for (std::uint16_t y = 0; y < dstScaledSizeY; y++) { std::uint16_t srcY = y * scaled.size.y / dstScaledSizeY; std::uint16_t dstY = y + offsetY; for (std::uint16_t x = 0; x < dstScaledSizeX; x++) { std::uint16_t srcX = x * scaled.size.x / dstScaledSizeX; std::uint16_t dstX = x + offsetX; dst[dstY * dstSizeX + dstX] = buffer[srcY * this->scaled.size.x + srcX]; } } } }; }