Rose
Texture.h
1 
8 #pragma once
9 
10 #include <filesystem>
11 #include <memory>
12 #include <SDL.h>
13 #include "Font.h"
14 #include "ScreenMetrics.h"
15 #include "Surface.h"
16 
17 
18 namespace rose::sdl {
19 
20  class Renderer;
21 
26  public:
31  void operator()(SDL_Texture *sdlTexture) {
32  SDL_DestroyTexture(sdlTexture);
33  }
34  };
35 
40  class Texture : public std::unique_ptr<SDL_Texture, TextureDestroy> {
41  public:
42  Texture() = default;
43 
44  ~Texture() = default;
45 
46  Texture(const Texture &) = delete;
47 
48  Texture(Texture &&) = default;
49 
50  Texture &operator=(const Texture &) = delete;
51 
52  Texture &operator=(Texture &&texture) = default;
53 
54  explicit Texture(SDL_Texture *texture) : Texture() { reset(texture); }
55 
64  Texture(Renderer &renderer, SDL_PixelFormatEnum format, SDL_TextureAccess access, int width, int height);
65 
73  Texture(Renderer &renderer, Size size);
74 
75  int setBlendMOde(SDL_BlendMode blendMode) {
76  return SDL_SetTextureBlendMode(get(), blendMode);
77  }
78 
79  [[nodiscard]] std::tuple<int, int> getSize() const noexcept {
80  int w, h;
81  SDL_QueryTexture(get(), nullptr, nullptr, &w, &h);
82  return std::make_tuple(w, h);
83  }
84  };
85 
90  class TextureData : public Texture {
91  public:
96  TextureData() = default;
97 
98  TextureData(const TextureData &) = delete;
99  TextureData &operator=(const TextureData &) = delete;
100 
109  TextureData(Renderer &renderer, SDL_PixelFormatEnum format, SDL_TextureAccess access, int width, int height)
110  : Texture(renderer, format, access, width, height) {
111  setMetaData();
112  }
113 
121  TextureData(Renderer &renderer, Size size) : Texture(renderer, size) {
122  setMetaData();
123  }
124 
130  explicit TextureData(Texture &&texture) noexcept: TextureData() {
131  (*this) = texture.release();
132  setMetaData();
133  }
134 
141  explicit TextureData(SDL_Texture *texture) noexcept: Texture(texture) {
142  setMetaData();
143  }
144 
149  TextureData(TextureData &&other) noexcept = default;
150 
156  TextureData &operator=(TextureData &&other) noexcept = default;
157 
164  TextureData &operator=(SDL_Texture *texture) {
165  reset(texture);
166  setMetaData();
167  return *this;
168  }
169 
174  [[nodiscard]] bool expired() const noexcept {
175  return operator bool() && mLife < std::chrono::system_clock::now();
176  }
177 
182  [[nodiscard]] bool dirty() const noexcept { return mDirty; }
183 
188  void setDirty(bool dirty) { mDirty = dirty; }
189 
194  std::string_view getPath() { return mPath; }
195 
200  [[nodiscard]] std::string_view getPath() const { return mPath; }
201 
207  template<typename StringType>
208  void setPath(const StringType path) { mPath = path; }
209 
214  std::string_view getURI() { return mURI; }
215 
220  [[nodiscard]] std::string_view getURI() const { return mURI; }
221 
227  template<typename StringType>
228  void setURI(const StringType URI) { mURI = URI; }
229 
234  std::string_view getName() { return mName; }
235 
240  [[nodiscard]] std::string_view getName() const { return mName; }
241 
247  template<typename StringType>
248  void setName(const StringType Name) { mName = Name; }
249 
254  void setLoadedTime(const std::chrono::time_point<std::chrono::system_clock> loaded) { mLoaded = loaded; }
255 
260  void setScale(int scale) { mScale = scale; }
261 
266  [[nodiscard]] int getScale() const { return mScale; }
267 
272  [[nodiscard]] Size getSize() const { return mSize; }
273 
278  void getRectangle(SDL_Rect &rect) const {
279  rect.x = rect.y = 0;
280  rect.w = mSize.width();
281  rect.h = mSize.height();
282  }
283 
288  [[nodiscard]] Rectangle getRectangle() const {
289  return Rectangle{0, 0, mSize.width(), mSize.height()};
290  }
291 
298  void setSize(Size size) { mSize = size; }
299 
300  protected:
304  void setMetaData() {
305  int w, h;
306  SDL_QueryTexture(get(), &mFormat, &mAccess, &w, &h);
307  mSize = Size{w, h};
308  mDirty = false;
309  }
310 
312  int mScale{
313  1};
314  uint32_t mFormat{};
315  int mAccess{};
316  std::string mPath;
317  std::string mURI;
318 
323  std::string mName;
324  bool mDirty{true};
325 
326  std::chrono::time_point<std::chrono::system_clock> mLoaded{},
327  mLife{};
328  };
329 
336  TextureData CreateTextureFromFile(Renderer &renderer, std::filesystem::path &filePath);
337 
346  template<typename String>
347  TextureData CreateTextureFromFile(Renderer &renderer, std::filesystem::path &dirPath, String fileName) {
348  auto filePath = dirPath;
349  filePath.append(fileName);
350  return CreateTextureFromFile(renderer, filePath);
351  }
352 
353  class GradientTexture;
354 
362  class GradientTexture : public Texture {
363  public:
364  GradientTexture() = default;
365 
366  ~GradientTexture() = default;
367 
368  GradientTexture(const GradientTexture &) = delete;
369 
370  GradientTexture(GradientTexture &&) = default;
371 
372  GradientTexture &operator=(const GradientTexture &) = delete;
373 
374  GradientTexture &operator=(GradientTexture &&) = delete;
375 
376  GradientTexture(Renderer &renderer, const color::RGBA &topLeft, const color::RGBA &topRight,
377  const color::RGBA &bottomLeft, const color::RGBA &bottomRight);
378 
379  GradientTexture(Renderer &renderer, const color::RGBA &start, const color::RGBA &end,
380  Orientation orientation = Orientation::Horizontal);
381 
382  void setColors(const color::RGBA &topLeft, const color::RGBA &topRight, const color::RGBA &bottomLeft,
383  const color::RGBA &bottomRight);
384 
385  void setColors(const color::RGBA &start, const color::RGBA &end,
386  Orientation orientation = Orientation::Horizontal);
387  };
388 
394  class GradientScale : public Texture {
395  protected:
396 
397  public:
398  GradientScale() = default;
399 
400  ~GradientScale() = default;
401 
402  GradientScale(const GradientScale &) = delete;
403 
404  GradientScale(GradientScale &&) = default;
405 
406  GradientScale &operator=(const GradientScale &) = delete;
407 
408  GradientScale &operator=(GradientScale &&) = delete;
409  };
410 
415  public:
420  void operator()(SDL_PixelFormat *sdlPixelFormat) {
421  SDL_FreeFormat(sdlPixelFormat);
422  }
423  };
424 
429  class PixelFormat : public std::unique_ptr<SDL_PixelFormat, PixelFormatDestroy> {
430  public:
431  PixelFormat() = default;
432 
439  explicit PixelFormat(SDL_PixelFormat *sdlPixelFormat)
440  : std::unique_ptr<SDL_PixelFormat, PixelFormatDestroy>(sdlPixelFormat) {}
441 
446  explicit PixelFormat(SDL_PixelFormatEnum format) : PixelFormat(SDL_AllocFormat(format)) {}
447  };
448 
456  uint32_t mapRGBA(SDL_PixelFormatEnum pixelFormat, const color::RGBA &color);
457 
464  uint32_t mapRGBA(PixelFormat &pixelFormat, const color::RGBA &color);
465 
472  uint32_t mapRGBA(SDL_PixelFormat *format, const color::RGBA &color);
473 
474  color::RGBA getRGBA(PixelFormat &pixelFormat, uint32_t pixel);
475 
476  color::RGBA getRGBA(SDL_PixelFormat *format, uint32_t pixel);
477 
487  template<typename Color>
488  inline sdl::Texture
489  renderTextureBlended(sdl::Renderer &renderer, FontPointer &font, const std::string &text, const Color &color) {
490  static_assert(std::is_same_v<Color, ::rose::color::RGBA> ||
491  std::is_same_v<Color, ::rose::color::HSVA> ||
492  std::is_same_v<Color, SDL_Color>,
493  "Color type is not supported.");
494  if constexpr (std::is_same_v<Color, ::rose::color::RGBA>) {
495  auto fg = color.toSdlColor();
496  return renderTextureBlended(renderer, font, text, fg);
497  } else if constexpr (std::is_same_v<Color, ::rose::color::HSVA>) {
498  auto fg = color::RGBA{color}.toSdlColor();
499  return renderTextureBlended(renderer, font, text, fg);
500  } else if constexpr (std::is_same_v<Color, SDL_Color>) {
501  sdl::Surface surface{TTF_RenderText_Blended(font.get(), text.c_str(), color)};
502  return sdl::Texture{SDL_CreateTextureFromSurface(renderer.get(), surface.get())};
503  }
504  }
505 
515  template<typename Color>
517  inline renderTextureBlendedUTF8(sdl::Renderer &renderer, FontPointer &font, const std::string &text,
518  const Color &color) {
519  static_assert(std::is_same_v<Color, ::rose::color::RGBA> ||
520  std::is_same_v<Color, ::rose::color::HSVA> ||
521  std::is_same_v<Color, SDL_Color>,
522  "Color type is not supported.");
523  if constexpr (std::is_same_v<Color, ::rose::color::RGBA>) {
524  auto fg = color.toSdlColor();
525  return renderTextureBlendedUTF8(renderer, font, text, fg);
526  } else if constexpr (std::is_same_v<Color, ::rose::color::HSVA>) {
527  auto fg = color::RGBA{color}.toSdlColor();
528  return renderTextureBlendedUTF8(renderer, font, text, fg);
529  } else if constexpr (std::is_same_v<Color, SDL_Color>) {
530  sdl::Surface surface{TTF_RenderUTF8_Blended(font.get(), text.c_str(), color)};
531  return sdl::Texture{SDL_CreateTextureFromSurface(renderer.get(), surface.get())};
532  }
533  }
534 
535 }
536 
PixelFormat(SDL_PixelFormatEnum format)
Constructor.
Definition: Texture.h:446
An encapsulation of an SDL_PixelFormat.
Definition: Texture.h:429
True Type Fonts and supporting types and functions.
void setDirty(bool dirty)
Set the texture dirty status.
Definition: Texture.h:188
A functor to destroy an SDL_PixelFormat in a std::unique_ptr (rose::sdl::PixelFormat) ...
Definition: Texture.h:414
Rectangle getRectangle() const
Return a Rectangle with the size of the texture and Zero position.
Definition: Texture.h:288
void setMetaData()
Set the class meta data from the texture.
Definition: Texture.h:304
std::string_view getName()
Get the Name member.
Definition: Texture.h:234
bool expired() const noexcept
Determine if the texture has expired.
Definition: Texture.h:174
void setURI(const StringType URI)
Assign a new value to the URI member.
Definition: Texture.h:228
Red Green Blue Alpha representation of a color.
Definition: Color.h:64
A type of texture that if stretch across a destination Rectangle in rendering, will create a gradient...
Definition: Texture.h:394
void setScale(int scale)
Set the scale value associated with the texture.
Definition: Texture.h:260
std::string_view getURI() const
Get the URI member from a const TextureData object.
Definition: Texture.h:220
Size getSize() const
Get the icon size.
Definition: Texture.h:272
std::shared_ptr< TTF_Font > FontPointer
Type for TTF smart pointer.
Definition: Font.h:54
void operator()(SDL_PixelFormat *sdlPixelFormat)
Call the SDL API to free an SDL_PixelFormat.
Definition: Texture.h:420
An encapsulation of the SDL_Texture structure.
Definition: Texture.h:40
Size mSize
The size of the texture.
Definition: Texture.h:311
std::string mName
A name this image may be known by.
Definition: Texture.h:323
TextureData(Renderer &renderer, SDL_PixelFormatEnum format, SDL_TextureAccess access, int width, int height)
Constructor
Definition: Texture.h:109
TextureData(Texture &&texture) noexcept
Move constructor.
Definition: Texture.h:130
std::string_view getPath() const
Get the path member from a const TextureData object.
Definition: Texture.h:200
std::string mPath
The path name to the source of the texture on the local file system.
Definition: Texture.h:316
void setName(const StringType Name)
Assign a new value to the Name member.
Definition: Texture.h:248
bool dirty() const noexcept
Determine if the texture is dirty.
Definition: Texture.h:182
constexpr int & width()
Reference access to width.
Definition: ScreenMetrics.h:332
std::string mURI
The URI of the source of the texture.
Definition: Texture.h:317
TextureData(Renderer &renderer, Size size)
Constructor.
Definition: Texture.h:121
std::string_view getName() const
Get the Name member from a const TextureData object.
Definition: Texture.h:240
Orientation
Possible values for Widget orientation.
Definition: Types.h:41
A functor to destroy an SDL_Texture in a std::unique_ptr (rose::sdl::Texture)
Definition: Texture.h:25
TextureData & operator=(SDL_Texture *texture)
Assign an SDL_Texture pointer to this object.
Definition: Texture.h:164
TextureData CreateTextureFromFile(Renderer &renderer, std::filesystem::path &filePath)
Create texture data from a file system path.
A composite of a Position and a Size.
Definition: Types.h:307
auto get() const
The the underlying SDL_Renderer* for use with the SDL2 API.
Definition: Renderer.h:163
PixelFormat(SDL_PixelFormat *sdlPixelFormat)
Constructor.
Definition: Texture.h:439
int getScale() const
Get the scale value associate with the texture.
Definition: Texture.h:266
void setPath(const StringType path)
Assign a new value to the path member.
Definition: Texture.h:208
std::string_view getPath()
Get the path member.
Definition: Texture.h:194
int pixel(SDL_Renderer *renderer, Sint16 x, Sint16 y)
Draw pixel in currently set color.
Definition: GfxPrimitives.cpp:20
void setSize(Size size)
Set the size of the Texture.
Definition: Texture.h:298
Written as a workaround for an issue in the SDL2 Library.
Definition: Renderer.h:64
Class and functions that are used to access the SDL2 api.
Definition: Renderer.cpp:11
TextureData(SDL_Texture *texture) noexcept
Construct a new TextureData from an SDL_Texture pointer.
Definition: Texture.h:141
A size in integer dimensions.
Definition: Types.h:230
void setLoadedTime(const std::chrono::time_point< std::chrono::system_clock > loaded)
Set the time the texture was loaded.
Definition: Texture.h:254
void getRectangle(SDL_Rect &rect) const
Populate an SDL_Rect with size of the texture with a Zero position.
Definition: Texture.h:278
uint32_t mapRGBA(SDL_PixelFormatEnum pixelFormat, const color::RGBA &color)
Map a color::RGBA to a uint32_t.
Definition: Texture.cpp:95
A Texture with associated meta data.
Definition: Texture.h:90
constexpr SDL_Color toSdlColor() const noexcept
Convert this colour to an SDL_Color.
Definition: Color.h:97
sdl::Texture renderTextureBlendedUTF8(sdl::Renderer &renderer, FontPointer &font, const std::string &text, const Color &color)
Render text to a Texture.
Definition: Texture.h:517
sdl::Texture renderTextureBlended(sdl::Renderer &renderer, FontPointer &font, const std::string &text, const Color &color)
Render text to a Texture.
Definition: Texture.h:489
A gradient rendering kernel.
Definition: Texture.h:362
std::string_view getURI()
Get the URI member.
Definition: Texture.h:214
void operator()(SDL_Texture *sdlTexture)
Call the SDL API to destroy an SDL_Texture.
Definition: Texture.h:31