FuncDoodle
Loading...
Searching...
No Matches
Frame.h
Go to the documentation of this file.
1
17
18#pragma once
19
28
29#include <cmath>
30#include <iostream>
31#include <utility>
32#include <vector>
33
34#include "Action/Direction.h"
35
36#include "Conf/Constants.h"
37#include "Selection/Selection.h"
38#include "Util/Ptr.h"
39
40#include "stb_image_write.h"
41
42namespace FuncDoodle {
47 struct Col {
48 public:
49 unsigned char r = 255;
50 unsigned char g = 255;
51 unsigned char b = 255;
52
60 static Col FromFloat3(const float* f) {
61 Col col;
62
63 col.r = (unsigned char)((f[0] * 255.0f) + 0.5f);
64 col.g = (unsigned char)((f[1] * 255.0f) + 0.5f);
65 col.b = (unsigned char)((f[2] * 255.0f) + 0.5f);
66
67 return col;
68 }
69
76 bool operator==(const Col& other) const {
77 return r == other.r && g == other.g && b == other.b;
78 }
79
85 bool operator!=(const Col& other) const { return !(*this == other); }
92 bool operator<(const Col& other) const {
93 if (r != other.r)
94 return r < other.r;
95 if (g != other.g)
96 return g < other.g;
97 return b < other.b;
98 }
99
107 friend std::ostream& operator<<(std::ostream& stream, const Col& col) {
108 stream << "Col{" << (unsigned int)col.r << ", "
109 << (unsigned int)col.g << ", " << (unsigned int)col.b << "}";
110 return stream;
111 }
112 };
113
127 public:
129 ImageArray& operator=(const ImageArray&) = default;
133 ImageArray(const ImageArray&) = default;
135 ImageArray(ImageArray&&) = default;
136
144 ImageArray(int width, int height, Col bgCol);
145 ~ImageArray();
146
154 void RedoColorAdjustment(Col bgCol);
159 void Resize();
168 void Set(int x, int y, const Col& color);
177 [[nodiscard]] Col Get(int x, int y) const;
178
185 [[nodiscard]] int Width() const { return m_Width; }
193 void SetWidth(int width, bool clear = false) { m_Width = width; }
200 [[nodiscard]] int Height() const { return m_Height; }
208 void SetHeight(int height, bool clear = false) { m_Height = height; }
215 void SetData(const std::vector<Col>& data) { this->m_Data = data; }
222 [[nodiscard]] const std::vector<Col>& Data() const { return m_Data; }
229 [[nodiscard]] Col BgCol() const { return m_BG; }
236 void SetBG(const Col bgCol) { m_BG = bgCol; }
237
238 private:
241 std::vector<Col> m_Data;
243 };
244
248 class Frame {
249 public:
250 Frame() : m_Pixels(1, 1, Col()) {}
252 Frame(const Frame& other) = default;
256 Frame(int width, int height, Col bgCol)
257 : m_Pixels(width, height, bgCol) {}
258
260 Frame(ImageArray arr) : m_Pixels(std::move(arr)) {}
263 Frame(const ImageArray* arr)
264 : m_Pixels(arr ? *arr : ImageArray(1, 1, Col())) {}
265
266 ~Frame() = default;
267
277 void ReInit(int width, int height, Col bgCol) {
278 m_Pixels = ImageArray(width, height, bgCol);
279 }
280
282 Frame& operator=(const Frame& other);
286 bool operator==(const Frame& other) const;
294 void SetWidth(int width, bool clear = false);
302 void SetHeight(int height, bool clear = false);
303
310 void Rotate(int deg) {
311 float rad = deg * M_PI / 180.0f;
312 float cos_r = cos(rad);
313 float sin_r = sin(rad);
314
315 int w = m_Pixels.Width();
316 int h = m_Pixels.Height();
317 int newW = m_Pixels.Width();
318 int newH = m_Pixels.Height(); // or calculate bounding box
319 std::vector<Col> result(newW * newH);
320
321 float cx = (w - 1) / 2.0f;
322 float cy = (h - 1) / 2.0f;
323 float ncx = (newW - 1) / 2.0f;
324 float ncy = (newH - 1) / 2.0f;
325
326 for (int y = 0; y < newH; y++) {
327 for (int x = 0; x < newW; x++) {
328 // Map output pixel to input coordinates
329 float dx = x - ncx;
330 float dy = y - ncy;
331 float sx = (dx * cos_r) + (dy * sin_r) + cx;
332 float sy = (-dx * sin_r) + (dy * cos_r) + cy;
333
334 // Nearest neighbor
335 auto isx = static_cast<int>(std::lround(sx));
336 auto isy = static_cast<int>(std::lround(sy));
337 if (isx >= 0 && isx < w && isy >= 0 && isy < h) {
338 result[(y * newW) + x] =
339 m_Pixels.Data()[(isy * w) + isx];
340 }
341 }
342 }
343 m_Pixels.SetData(result);
344 }
345
353 void RotateSelection(WeakPtr<Selection> sel, int deg);
370 void MoveSelection(WeakPtr<Selection> sel, Direction moveDir, Col bg);
371
376 void CopyToClipboard();
383 static Frame* PastedFrame();
390 void Export(const char* filePath) const;
391
398 [[nodiscard]] const ImageArray* Pixels() const { return &m_Pixels; }
414 void SetPixel(int x, int y, Col px) { m_Pixels.Set(x, y, px); }
421 [[nodiscard]] int Width() const { return m_Pixels.Width(); }
428 [[nodiscard]] int Height() const { return m_Pixels.Height(); }
435 [[nodiscard]] std::vector<Col> Data() const { return m_Pixels.Data(); }
436
437 private:
439 };
440} // namespace FuncDoodle
Global constants used throughout FuncDoodle.
Defines direction enum and context for selection movement actions.
Convenience type aliases for standard smart pointers.
std::weak_ptr< T > WeakPtr
Alias for a non-owning observer of a SharedPtr.
Definition Ptr.h:34
Defines selection primitives for editing regions of pixels.
Wraps an ImageArray with higher-level frame editing operations.
Definition Frame.h:248
void SetPixel(int x, int y, Col px)
Sets a single frame pixel.
Definition Frame.h:414
static Frame * PastedFrame()
Returns a frame created from clipboard image data.
Definition Frame.cc:153
std::vector< Col > Data() const
Returns a copy of the frame pixel buffer.
Definition Frame.h:435
Frame()
Definition Frame.h:250
void SetHeight(int height, bool clear=false)
Sets the frame height.
Definition Frame.cc:91
void SetWidth(int width, bool clear=false)
Sets the frame width.
Definition Frame.cc:66
void Export(const char *filePath) const
Writes the frame to an image file.
Definition Frame.cc:241
Frame(int width, int height, Col bgCol)
Creates a frame with explicit dimensions and background color.
Definition Frame.h:256
ImageArray * PixelsMut()
Returns mutable access to the backing pixel array.
Definition Frame.h:405
int Height() const
Returns the frame height in pixels.
Definition Frame.h:428
ImageArray m_Pixels
Definition Frame.h:438
void CopyToClipboard()
Copies the frame image to the system clipboard.
Definition Frame.cc:119
void ReInit(int width, int height, Col bgCol)
Reinitializes the frame with new dimensions and background color.
Definition Frame.h:277
Frame & operator=(const Frame &other)
Copies another frame into this one.
Definition Frame.cc:245
int Width() const
Returns the frame width in pixels.
Definition Frame.h:421
const ImageArray * Pixels() const
Returns immutable access to the backing pixel array.
Definition Frame.h:398
bool operator==(const Frame &other) const
Returns whether two frames contain identical pixel data.
Definition Frame.cc:251
void Rotate(int deg)
Rotates the frame contents around the frame center.
Definition Frame.h:310
void MoveSelection(WeakPtr< Selection > sel, Direction moveDir, Col bg)
Moves the selected region by one step.
Definition Frame.cc:328
Frame(const Frame &other)=default
Copies an existing frame.
Frame(ImageArray arr)
Creates a frame from an image array copy.
Definition Frame.h:260
void DeleteSelection(WeakPtr< Selection > sel, Col bg)
Replaces the selected region with background color.
Definition Frame.cc:318
Frame(const ImageArray *arr)
Creates a frame from an optional image array pointer.
Definition Frame.h:263
void RotateSelection(WeakPtr< Selection > sel, int deg)
Rotates only the selected region.
Definition Frame.cc:266
2D array of RGB8 color pixels.
Definition Frame.h:126
ImageArray & operator=(const ImageArray &)=default
Copies pixel data from another image array.
Col m_BG
Definition Frame.h:242
void Set(int x, int y, const Col &color)
Sets a pixel color.
Definition Frame.cc:49
Col Get(int x, int y) const
Returns a pixel color.
Definition Frame.cc:58
int Width() const
Returns the image width in pixels.
Definition Frame.h:185
int Height() const
Returns the image height in pixels.
Definition Frame.h:200
Col BgCol() const
Returns the image background color.
Definition Frame.h:229
void SetHeight(int height, bool clear=false)
Sets the image height.
Definition Frame.h:208
ImageArray(ImageArray &&)=default
Moves an existing image array.
void RedoColorAdjustment(Col bgCol)
Reapplies background-color dependent adjustments after a color change.
Definition Frame.cc:35
~ImageArray()
Definition Frame.cc:30
int m_Height
Definition Frame.h:240
ImageArray & operator=(ImageArray &&)=default
Moves pixel data from another image array.
void SetBG(const Col bgCol)
Sets the background color.
Definition Frame.h:236
std::vector< Col > m_Data
Definition Frame.h:241
ImageArray(const ImageArray &)=default
Copies an existing image array.
void SetWidth(int width, bool clear=false)
Sets the image width.
Definition Frame.h:193
void Resize()
Resizes the backing pixel buffer to match current dimensions.
Definition Frame.cc:44
void SetData(const std::vector< Col > &data)
Replaces the raw pixel buffer.
Definition Frame.h:215
int m_Width
Definition Frame.h:239
const std::vector< Col > & Data() const
Returns the raw pixel buffer.
Definition Frame.h:222
The FuncDoodle C++ namespace.
Definition Common.h:12
constexpr int g_DefaultCanvasHeight
Default canvas height in pixels.
Definition Constants.h:51
constexpr int g_DefaultCanvasWidth
Default canvas width in pixels.
Definition Constants.h:46
Direction
Direction used for moving a selection.
Definition Direction.h:23
A struct holding an RGB8 color.
Definition Frame.h:47
bool operator!=(const Col &other) const
Returns whether two colors differ.
Definition Frame.h:85
static Col FromFloat3(const float *f)
Converts a normalized RGB float triplet into an 8-bit color.
Definition Frame.h:60
unsigned char r
Red channel in 8-bit RGB space.
Definition Frame.h:49
unsigned char g
Green channel in 8-bit RGB space.
Definition Frame.h:50
bool operator==(const Col &other) const
Returns whether two colors are identical.
Definition Frame.h:76
friend std::ostream & operator<<(std::ostream &stream, const Col &col)
Streams a color in human-readable form.
Definition Frame.h:107
unsigned char b
Blue channel in 8-bit RGB space.
Definition Frame.h:51
bool operator<(const Col &other) const
Orders colors lexicographically by RGB channels.
Definition Frame.h:92