Delete OpaqueStruct and use directly fancy pointers now that I know
how to set the deleter correctly.
This commit is contained in:
parent
5f341149fa
commit
d8f56e0e5f
11 changed files with 139 additions and 135 deletions
|
@ -4,6 +4,7 @@
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <basic_widgets/core/type/deleter.hpp>
|
||||||
#include <basic_widgets/w/widget_factory.hpp>
|
#include <basic_widgets/w/widget_factory.hpp>
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -26,14 +27,15 @@ void run_example(
|
||||||
auto font =
|
auto font =
|
||||||
std::make_shared<bwidgets::Font>(bwidgets::Font::find("Monospace"),
|
std::make_shared<bwidgets::Font>(bwidgets::Font::find("Monospace"),
|
||||||
16); // NOLINT(readability-magic-numbers)
|
16); // NOLINT(readability-magic-numbers)
|
||||||
auto win = bwidgets::OpaqueStruct<SDL_Window>(
|
|
||||||
|
auto win = std::unique_ptr<SDL_Window, bwidgets::Deleter>(
|
||||||
bwidgets::ptr_or_throw<bwidgets::SDLError>(SDL_CreateWindow(
|
bwidgets::ptr_or_throw<bwidgets::SDLError>(SDL_CreateWindow(
|
||||||
"basic_widgets example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
|
"basic_widgets example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
|
||||||
size_init.w, size_init.h,
|
size_init.w, size_init.h,
|
||||||
SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_UTILITY)),
|
SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_UTILITY)));
|
||||||
[](auto ptr) noexcept { SDL_DestroyWindow(ptr); });
|
|
||||||
auto renderer =
|
auto renderer =
|
||||||
std::make_shared<bwidgets::Renderer>(win(), -1, SDL_RENDERER_ACCELERATED);
|
std::make_shared<bwidgets::Renderer>(win.get(), -1, SDL_RENDERER_ACCELERATED);
|
||||||
renderer->blend_mode(SDL_BLENDMODE_BLEND);
|
renderer->blend_mode(SDL_BLENDMODE_BLEND);
|
||||||
|
|
||||||
auto layout = bwidgets::create_horizontal_layout();
|
auto layout = bwidgets::create_horizontal_layout();
|
||||||
|
|
|
@ -1,19 +1,22 @@
|
||||||
#ifndef BWIDGETS_FONT_HPP
|
#ifndef BWIDGETS_FONT_HPP
|
||||||
#define BWIDGETS_FONT_HPP
|
#define BWIDGETS_FONT_HPP
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <SDL_ttf.h>
|
#include <SDL_ttf.h>
|
||||||
|
|
||||||
#include <basic_widgets/core/type/color.hpp>
|
#include <basic_widgets/core/type/color.hpp>
|
||||||
#include <basic_widgets/core/type/opaque_struct.hpp>
|
#include <basic_widgets/core/type/deleter.hpp>
|
||||||
#include <basic_widgets/core/type/size.hpp>
|
#include <basic_widgets/core/type/size.hpp>
|
||||||
|
|
||||||
namespace bwidgets
|
namespace bwidgets
|
||||||
{
|
{
|
||||||
// Wrap TTF_Font from SDL_ttf and provide a font finding function.
|
// Wrap TTF_Font from SDL_ttf and provide a font finding function.
|
||||||
class Font final : OpaqueStruct<TTF_Font>::Wrapper
|
class Font final
|
||||||
{
|
{
|
||||||
|
const std::unique_ptr<TTF_Font, Deleter> _data;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum struct Hinting
|
enum struct Hinting
|
||||||
{
|
{
|
||||||
|
@ -67,7 +70,8 @@ namespace bwidgets
|
||||||
[[nodiscard]] auto outline() const noexcept -> int;
|
[[nodiscard]] auto outline() const noexcept -> int;
|
||||||
auto outline(int) noexcept -> Font*;
|
auto outline(int) noexcept -> Font*;
|
||||||
auto render(RenderMode, std::string_view, Color fg = default_color_fg,
|
auto render(RenderMode, std::string_view, Color fg = default_color_fg,
|
||||||
Color bg = default_color_bg) -> OpaqueStruct<SDL_Surface>;
|
Color bg = default_color_bg)
|
||||||
|
-> std::unique_ptr<SDL_Surface, Deleter>;
|
||||||
[[nodiscard]] auto style() const noexcept -> uint8_t;
|
[[nodiscard]] auto style() const noexcept -> uint8_t;
|
||||||
auto style(uint8_t) noexcept -> Font*;
|
auto style(uint8_t) noexcept -> Font*;
|
||||||
[[nodiscard]] auto text_size(std::string_view) const noexcept -> Size;
|
[[nodiscard]] auto text_size(std::string_view) const noexcept -> Size;
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
#ifndef BWIDGETS_RENDERER_HPP
|
#ifndef BWIDGETS_RENDERER_HPP
|
||||||
#define BWIDGETS_RENDERER_HPP
|
#define BWIDGETS_RENDERER_HPP
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include <span>
|
#include <span>
|
||||||
|
|
||||||
#include <SDL_render.h>
|
#include <SDL_render.h>
|
||||||
|
|
||||||
#include <basic_widgets/core/error_helper.hpp>
|
#include <basic_widgets/core/error_helper.hpp>
|
||||||
#include <basic_widgets/core/type/color.hpp>
|
#include <basic_widgets/core/type/color.hpp>
|
||||||
#include <basic_widgets/core/type/opaque_struct.hpp>
|
#include <basic_widgets/core/type/deleter.hpp>
|
||||||
#include <basic_widgets/core/type/size.hpp>
|
#include <basic_widgets/core/type/size.hpp>
|
||||||
|
|
||||||
namespace bwidgets
|
namespace bwidgets
|
||||||
|
@ -15,10 +16,12 @@ namespace bwidgets
|
||||||
class Texture;
|
class Texture;
|
||||||
|
|
||||||
// Wrap some of SDL's 2D accelerated rendering API.
|
// Wrap some of SDL's 2D accelerated rendering API.
|
||||||
class Renderer final : OpaqueStruct<SDL_Renderer>::Wrapper
|
class Renderer final
|
||||||
{
|
{
|
||||||
friend Texture;
|
friend Texture;
|
||||||
|
|
||||||
|
const std::unique_ptr<SDL_Renderer, Deleter> _data;
|
||||||
|
|
||||||
static auto _info(SDL_Renderer* r) -> SDL_RendererInfo
|
static auto _info(SDL_Renderer* r) -> SDL_RendererInfo
|
||||||
{
|
{
|
||||||
SDL_RendererInfo info;
|
SDL_RendererInfo info;
|
||||||
|
|
|
@ -1,19 +1,21 @@
|
||||||
#ifndef BWIDGETS_TEXTURE_HPP
|
#ifndef BWIDGETS_TEXTURE_HPP
|
||||||
#define BWIDGETS_TEXTURE_HPP
|
#define BWIDGETS_TEXTURE_HPP
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include <SDL_pixels.h>
|
#include <SDL_pixels.h>
|
||||||
#include <SDL_render.h>
|
#include <SDL_render.h>
|
||||||
|
|
||||||
#include <basic_widgets/core/error_helper.hpp>
|
#include <basic_widgets/core/error_helper.hpp>
|
||||||
#include <basic_widgets/core/type/color.hpp>
|
#include <basic_widgets/core/type/color.hpp>
|
||||||
#include <basic_widgets/core/type/opaque_struct.hpp>
|
#include <basic_widgets/core/type/deleter.hpp>
|
||||||
|
|
||||||
namespace bwidgets
|
namespace bwidgets
|
||||||
{
|
{
|
||||||
class Renderer;
|
class Renderer;
|
||||||
|
|
||||||
// Wrap most of the texture functions of SDL 2D rendering API.
|
// Wrap most of the texture functions of SDL 2D rendering API.
|
||||||
class Texture final : OpaqueStruct<SDL_Texture>::Wrapper
|
class Texture final
|
||||||
{
|
{
|
||||||
friend Renderer;
|
friend Renderer;
|
||||||
|
|
||||||
|
@ -26,6 +28,7 @@ namespace bwidgets
|
||||||
};
|
};
|
||||||
|
|
||||||
const Attr _attributes;
|
const Attr _attributes;
|
||||||
|
const std::unique_ptr<SDL_Texture, Deleter> _data;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Texture(SDL_Texture*);
|
explicit Texture(SDL_Texture*);
|
||||||
|
|
51
inc/basic_widgets/core/type/deleter.hpp
Normal file
51
inc/basic_widgets/core/type/deleter.hpp
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
#ifndef BWIDGETS_OPAQUE_STRUCT_HPP
|
||||||
|
#define BWIDGETS_OPAQUE_STRUCT_HPP
|
||||||
|
|
||||||
|
#include <fontconfig/fontconfig.h>
|
||||||
|
#include <SDL_render.h>
|
||||||
|
#include <SDL_surface.h>
|
||||||
|
#include <SDL_ttf.h>
|
||||||
|
|
||||||
|
namespace bwidgets
|
||||||
|
{
|
||||||
|
// Deleter type for fancy pointers.
|
||||||
|
struct Deleter
|
||||||
|
{
|
||||||
|
void operator()(FcConfig* ptr)
|
||||||
|
{
|
||||||
|
FcConfigDestroy(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator()(FcPattern* ptr)
|
||||||
|
{
|
||||||
|
FcPatternDestroy(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator()(SDL_Renderer* ptr)
|
||||||
|
{
|
||||||
|
SDL_DestroyRenderer(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator()(SDL_Surface* ptr)
|
||||||
|
{
|
||||||
|
SDL_FreeSurface(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator()(SDL_Texture* ptr)
|
||||||
|
{
|
||||||
|
SDL_DestroyTexture(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator()(SDL_Window* ptr)
|
||||||
|
{
|
||||||
|
SDL_DestroyWindow(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator()(TTF_Font* ptr)
|
||||||
|
{
|
||||||
|
TTF_CloseFont(ptr);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,53 +0,0 @@
|
||||||
#ifndef BWIDGETS_OPAQUE_STRUCT_HPP
|
|
||||||
#define BWIDGETS_OPAQUE_STRUCT_HPP
|
|
||||||
|
|
||||||
#include <functional>
|
|
||||||
|
|
||||||
namespace bwidgets
|
|
||||||
{
|
|
||||||
// Wrap opaque structures to be able to use a destructor to free them.
|
|
||||||
template<typename T>
|
|
||||||
class OpaqueStruct
|
|
||||||
{
|
|
||||||
using Deleter = std::function<void(T*)>;
|
|
||||||
|
|
||||||
const Deleter _deleter;
|
|
||||||
|
|
||||||
T* const _c_pod;
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Construct an instance managing resource pointed by ptr using Deleter d to free
|
|
||||||
// it on wrapper destruction.
|
|
||||||
OpaqueStruct(T* ptr, Deleter d) : _deleter {std::move(d)}, _c_pod {ptr} {}
|
|
||||||
|
|
||||||
OpaqueStruct(const OpaqueStruct&) = delete;
|
|
||||||
OpaqueStruct(OpaqueStruct&&) = delete;
|
|
||||||
|
|
||||||
virtual ~OpaqueStruct() noexcept
|
|
||||||
{
|
|
||||||
_deleter(_c_pod);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Get the pointer to the wrapped opaque struct.
|
|
||||||
[[nodiscard]] auto* operator()() const
|
|
||||||
{
|
|
||||||
return _c_pod;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto operator=(const OpaqueStruct&) = delete;
|
|
||||||
auto operator=(OpaqueStruct&&) = delete;
|
|
||||||
|
|
||||||
// Base class for defining custom wrappers.
|
|
||||||
class Wrapper
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// Forward args to OpaqueStruct ctor.
|
|
||||||
Wrapper(T* ptr, Deleter d) : _data(ptr, std::move(d)) {}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
OpaqueStruct _data;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -12,7 +12,6 @@ namespace bwidgets
|
||||||
SDL_ALPHA_OPAQUE};
|
SDL_ALPHA_OPAQUE};
|
||||||
inline static const Color default_font_color_fg {0, 0, 0, SDL_ALPHA_OPAQUE};
|
inline static const Color default_font_color_fg {0, 0, 0, SDL_ALPHA_OPAQUE};
|
||||||
|
|
||||||
FontHandler() noexcept = default;
|
|
||||||
FontHandler(const FontHandler&) = delete;
|
FontHandler(const FontHandler&) = delete;
|
||||||
FontHandler(FontHandler&&) = delete;
|
FontHandler(FontHandler&&) = delete;
|
||||||
auto operator=(const FontHandler&) = delete;
|
auto operator=(const FontHandler&) = delete;
|
||||||
|
@ -26,6 +25,9 @@ namespace bwidgets
|
||||||
virtual void font_color_bg(Color c) = 0;
|
virtual void font_color_bg(Color c) = 0;
|
||||||
// Set font foreground (text) color.
|
// Set font foreground (text) color.
|
||||||
virtual void font_color_fg(Color c) = 0;
|
virtual void font_color_fg(Color c) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
FontHandler() noexcept = default;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ const Color Font::default_color_bg {255, 255, 255, SDL_ALPHA_OPAQUE};
|
||||||
const Color Font::default_color_fg {0, 0, 0, SDL_ALPHA_OPAQUE};
|
const Color Font::default_color_fg {0, 0, 0, SDL_ALPHA_OPAQUE};
|
||||||
|
|
||||||
Font::Font(TTF_Font* f)
|
Font::Font(TTF_Font* f)
|
||||||
: Wrapper {ptr_or_throw<SDLError>(f), [f](TTF_Font*) noexcept { TTF_CloseFont(f); }},
|
: _data {ptr_or_throw<SDLError>(f)},
|
||||||
ascent {TTF_FontAscent(f)},
|
ascent {TTF_FontAscent(f)},
|
||||||
descent {TTF_FontDescent(f)},
|
descent {TTF_FontDescent(f)},
|
||||||
faces {TTF_FontFaces(f)},
|
faces {TTF_FontFaces(f)},
|
||||||
|
@ -32,115 +32,110 @@ Font::Font(const std::string_view file, const int size)
|
||||||
|
|
||||||
auto Font::hinting() const noexcept -> Font::Hinting
|
auto Font::hinting() const noexcept -> Font::Hinting
|
||||||
{
|
{
|
||||||
return static_cast<Hinting>(TTF_GetFontHinting(_data()));
|
return static_cast<Hinting>(TTF_GetFontHinting(_data.get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Font::hinting(const Font::Hinting h) noexcept -> Font*
|
auto Font::hinting(const Font::Hinting h) noexcept -> Font*
|
||||||
{
|
{
|
||||||
TTF_SetFontHinting(_data(), static_cast<int>(h));
|
TTF_SetFontHinting(_data.get(), static_cast<int>(h));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Font::kerning() const noexcept -> bool
|
auto Font::kerning() const noexcept -> bool
|
||||||
{
|
{
|
||||||
return TTF_GetFontKerning(_data()) != 0;
|
return TTF_GetFontKerning(_data.get()) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Font::kerning(const bool allowed) noexcept -> Font*
|
auto Font::kerning(const bool allowed) noexcept -> Font*
|
||||||
{
|
{
|
||||||
TTF_SetFontKerning(_data(), static_cast<int>(allowed));
|
TTF_SetFontKerning(_data.get(), static_cast<int>(allowed));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Font::outline() const noexcept -> int
|
auto Font::outline() const noexcept -> int
|
||||||
{
|
{
|
||||||
return TTF_GetFontOutline(_data());
|
return TTF_GetFontOutline(_data.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Font::outline(const int size) noexcept -> Font*
|
auto Font::outline(const int size) noexcept -> Font*
|
||||||
{
|
{
|
||||||
TTF_SetFontOutline(_data(), size);
|
TTF_SetFontOutline(_data.get(), size);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Font::render(const RenderMode m, const std::string_view str, const Color fg,
|
auto Font::render(const RenderMode m, const std::string_view str, const Color fg,
|
||||||
const Color bg) -> OpaqueStruct<SDL_Surface>
|
const Color bg) -> std::unique_ptr<SDL_Surface, Deleter>
|
||||||
{
|
{
|
||||||
const char* const c_str = str.empty() ? " " : str.data();
|
const char* const c_str = str.empty() ? " " : str.data();
|
||||||
auto renderer = [bg, c_str, fg, m, this]() -> std::function<SDL_Surface*()> {
|
auto renderer = [bg, c_str, fg, m, this]() -> std::function<SDL_Surface*()> {
|
||||||
switch (m) {
|
switch (m) {
|
||||||
case RenderMode::BLENDED:
|
case RenderMode::BLENDED:
|
||||||
return [fg, c_str, this]() {
|
return [fg, c_str, this]() {
|
||||||
return TTF_RenderUTF8_Blended(_data(), c_str, fg());
|
return TTF_RenderUTF8_Blended(_data.get(), c_str, fg());
|
||||||
};
|
};
|
||||||
case RenderMode::SHADED:
|
case RenderMode::SHADED:
|
||||||
return [bg, fg, c_str, this]() {
|
return [bg, fg, c_str, this]() {
|
||||||
return TTF_RenderUTF8_Shaded(_data(), c_str, fg(), bg());
|
return TTF_RenderUTF8_Shaded(_data.get(), c_str, fg(), bg());
|
||||||
};
|
};
|
||||||
case RenderMode::SOLID:
|
case RenderMode::SOLID:
|
||||||
return [fg, c_str, this]() {
|
return [fg, c_str, this]() {
|
||||||
return TTF_RenderUTF8_Solid(_data(), c_str, fg());
|
return TTF_RenderUTF8_Solid(_data.get(), c_str, fg());
|
||||||
};
|
};
|
||||||
default:
|
default:
|
||||||
throw std::logic_error("missing switch case.");
|
throw std::logic_error("missing switch case.");
|
||||||
}
|
}
|
||||||
}();
|
}();
|
||||||
|
|
||||||
return {ptr_or_throw<SDLError>(renderer()), [](auto* ptr) { SDL_FreeSurface(ptr); }};
|
return std::unique_ptr<SDL_Surface, Deleter>(ptr_or_throw<SDLError>(renderer()));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Font::style() const noexcept -> uint8_t
|
auto Font::style() const noexcept -> uint8_t
|
||||||
{
|
{
|
||||||
return TTF_GetFontStyle(_data());
|
return TTF_GetFontStyle(_data.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Font::style(const uint8_t s) noexcept -> Font*
|
auto Font::style(const uint8_t s) noexcept -> Font*
|
||||||
{
|
{
|
||||||
TTF_SetFontStyle(_data(), s);
|
TTF_SetFontStyle(_data.get(), s);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Font::text_size(const std::string_view str) const noexcept -> Size
|
auto Font::text_size(const std::string_view str) const noexcept -> Size
|
||||||
{
|
{
|
||||||
Size s {};
|
Size s {};
|
||||||
TTF_SizeUTF8(_data(), str.data(), &s.w, &s.h);
|
TTF_SizeUTF8(_data.get(), str.data(), &s.w, &s.h);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Font::find(const std::string_view pat) -> std::string
|
auto Font::find(const std::string_view pat) -> std::string
|
||||||
{
|
{
|
||||||
const auto conf = std::make_unique<OpaqueStruct<FcConfig>>(
|
const auto conf = std::unique_ptr<FcConfig, Deleter>(
|
||||||
ptr_or_throw<FCError>(FcInitLoadConfigAndFonts(), "init failed"),
|
ptr_or_throw<FCError>(FcInitLoadConfigAndFonts(), "fontconfig init failed."));
|
||||||
[](auto* ptr) { FcConfigDestroy(ptr); });
|
|
||||||
|
|
||||||
const auto pattern = [&conf, pat]() {
|
const auto pattern = [&conf, pat]() {
|
||||||
auto pattern = std::make_unique<OpaqueStruct<FcPattern>>(
|
auto pattern = std::unique_ptr<FcPattern, Deleter>(ptr_or_throw<FCError>(
|
||||||
ptr_or_throw<FCError>(
|
|
||||||
FcNameParse(reinterpret_cast<const FcChar8*>(pat.data())),
|
FcNameParse(reinterpret_cast<const FcChar8*>(pat.data())),
|
||||||
"pattern parsing failed"),
|
"pattern parsing failed"));
|
||||||
[](auto* ptr) { FcPatternDestroy(ptr); });
|
|
||||||
|
|
||||||
success_or_throw<FCError, FcBool>(
|
success_or_throw<FCError, FcBool>(
|
||||||
FcConfigSubstitute((*conf)(), (*pattern)(), FcMatchPattern),
|
FcConfigSubstitute(conf.get(), pattern.get(), FcMatchPattern),
|
||||||
"FcConfigSubstitute failed", [](auto code) { return code == FcTrue; });
|
"FcConfigSubstitute failed", [](auto code) { return code == FcTrue; });
|
||||||
return pattern;
|
return pattern;
|
||||||
}();
|
}();
|
||||||
|
|
||||||
FcDefaultSubstitute((*pattern)());
|
FcDefaultSubstitute(pattern.get());
|
||||||
|
|
||||||
std::string file_path = [&conf, &pattern]() {
|
std::string file_path = [&conf, &pattern]() {
|
||||||
FcResult res {};
|
FcResult res {};
|
||||||
const auto font = std::make_unique<OpaqueStruct<FcPattern>>(
|
const auto font = std::unique_ptr<FcPattern, Deleter>(ptr_or_throw<FCError>(
|
||||||
ptr_or_throw<FCError>(FcFontMatch((*conf)(), (*pattern)(), &res),
|
FcFontMatch(conf.get(), pattern.get(), &res), "no font found."));
|
||||||
"no font found."),
|
|
||||||
[](auto* ptr) { FcPatternDestroy(ptr); });
|
|
||||||
|
|
||||||
if (FcChar8* file = nullptr;
|
if (FcChar8* file = nullptr;
|
||||||
FcPatternGetString((*font)(), FC_FILE, 0, &file) == FcResultMatch)
|
FcPatternGetString(font.get(), FC_FILE, 0, &file) == FcResultMatch)
|
||||||
{
|
{
|
||||||
// "I know what I'm doing"
|
// "I know what I'm doing"
|
||||||
|
// NOLINTNEXTLINE
|
||||||
std::string _file_path {reinterpret_cast<char*>(file)};
|
std::string _file_path {reinterpret_cast<char*>(file)};
|
||||||
FcPatternDestroy((*font)());
|
|
||||||
return _file_path;
|
return _file_path;
|
||||||
}
|
}
|
||||||
throw FCError("no font found.");
|
throw FCError("no font found.");
|
||||||
|
|
|
@ -3,34 +3,31 @@
|
||||||
|
|
||||||
using namespace bwidgets;
|
using namespace bwidgets;
|
||||||
|
|
||||||
Renderer::Renderer(SDL_Renderer* r)
|
Renderer::Renderer(SDL_Renderer* r) : _data {ptr_or_throw<SDLError>(r)}, info {_info(r)}
|
||||||
: Wrapper {ptr_or_throw<SDLError>(r),
|
|
||||||
[r](SDL_Renderer*) noexcept { SDL_DestroyRenderer(r); }},
|
|
||||||
info {_info(r)}
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Renderer::Renderer(SDL_Window* w, const int index, const uint32_t flags = 0)
|
Renderer::Renderer(SDL_Window* w, const int index, const uint32_t flags = 0)
|
||||||
: Renderer {ptr_or_throw<SDLError>(SDL_CreateRenderer(w, index, flags))}
|
: Renderer {SDL_CreateRenderer(w, index, flags)}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
auto Renderer::blend_mode() -> SDL_BlendMode
|
auto Renderer::blend_mode() -> SDL_BlendMode
|
||||||
{
|
{
|
||||||
SDL_BlendMode mode {};
|
SDL_BlendMode mode {};
|
||||||
success_or_throw<SDLError>(SDL_GetRenderDrawBlendMode(_data(), &mode));
|
success_or_throw<SDLError>(SDL_GetRenderDrawBlendMode(_data.get(), &mode));
|
||||||
|
|
||||||
return mode;
|
return mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Renderer::blend_mode(const SDL_BlendMode mode) -> Renderer*
|
auto Renderer::blend_mode(const SDL_BlendMode mode) -> Renderer*
|
||||||
{
|
{
|
||||||
success_or_throw<SDLError>(SDL_SetRenderDrawBlendMode(_data(), mode));
|
success_or_throw<SDLError>(SDL_SetRenderDrawBlendMode(_data.get(), mode));
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Renderer::clear() -> Renderer*
|
auto Renderer::clear() -> Renderer*
|
||||||
{
|
{
|
||||||
success_or_throw<SDLError>(SDL_RenderClear(_data()));
|
success_or_throw<SDLError>(SDL_RenderClear(_data.get()));
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -38,7 +35,7 @@ auto Renderer::clear() -> Renderer*
|
||||||
auto Renderer::copy(const Texture& t, const SDL_Rect* const src,
|
auto Renderer::copy(const Texture& t, const SDL_Rect* const src,
|
||||||
const SDL_Rect* const dst) -> Renderer*
|
const SDL_Rect* const dst) -> Renderer*
|
||||||
{
|
{
|
||||||
success_or_throw<SDLError>(SDL_RenderCopy(_data(), t._data(), src, dst));
|
success_or_throw<SDLError>(SDL_RenderCopy(_data.get(), t._data.get(), src, dst));
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -47,7 +44,7 @@ auto Renderer::draw_color() -> Color
|
||||||
{
|
{
|
||||||
Color c;
|
Color c;
|
||||||
success_or_throw<SDLError>(
|
success_or_throw<SDLError>(
|
||||||
SDL_GetRenderDrawColor(_data(), &c().r, &c().g, &c().b, &c().a));
|
SDL_GetRenderDrawColor(_data.get(), &c().r, &c().g, &c().b, &c().a));
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
@ -55,14 +52,14 @@ auto Renderer::draw_color() -> Color
|
||||||
auto Renderer::draw_color(const Color c) -> Renderer*
|
auto Renderer::draw_color(const Color c) -> Renderer*
|
||||||
{
|
{
|
||||||
success_or_throw<SDLError>(
|
success_or_throw<SDLError>(
|
||||||
SDL_SetRenderDrawColor(_data(), c().r, c().g, c().b, c().a));
|
SDL_SetRenderDrawColor(_data.get(), c().r, c().g, c().b, c().a));
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Renderer::draw_line(const SDL_Point a, const SDL_Point b) -> Renderer*
|
auto Renderer::draw_line(const SDL_Point a, const SDL_Point b) -> Renderer*
|
||||||
{
|
{
|
||||||
success_or_throw<SDLError>(SDL_RenderDrawLine(_data(), a.x, a.y, b.x, b.y));
|
success_or_throw<SDLError>(SDL_RenderDrawLine(_data.get(), a.x, a.y, b.x, b.y));
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -70,14 +67,14 @@ auto Renderer::draw_line(const SDL_Point a, const SDL_Point b) -> Renderer*
|
||||||
auto Renderer::draw_lines(const std::span<SDL_Point> pts) -> Renderer*
|
auto Renderer::draw_lines(const std::span<SDL_Point> pts) -> Renderer*
|
||||||
{
|
{
|
||||||
success_or_throw<SDLError>(
|
success_or_throw<SDLError>(
|
||||||
SDL_RenderDrawLines(_data(), pts.data(), (int)pts.size()));
|
SDL_RenderDrawLines(_data.get(), pts.data(), (int)pts.size()));
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Renderer::draw_point(const SDL_Point p) -> Renderer*
|
auto Renderer::draw_point(const SDL_Point p) -> Renderer*
|
||||||
{
|
{
|
||||||
success_or_throw<SDLError>(SDL_RenderDrawPoint(_data(), p.x, p.y));
|
success_or_throw<SDLError>(SDL_RenderDrawPoint(_data.get(), p.x, p.y));
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -85,7 +82,7 @@ auto Renderer::draw_point(const SDL_Point p) -> Renderer*
|
||||||
auto Renderer::draw_points(const std::span<SDL_Point> pts) -> Renderer*
|
auto Renderer::draw_points(const std::span<SDL_Point> pts) -> Renderer*
|
||||||
{
|
{
|
||||||
success_or_throw<SDLError>(
|
success_or_throw<SDLError>(
|
||||||
SDL_RenderDrawPoints(_data(), pts.data(), (int)pts.size()));
|
SDL_RenderDrawPoints(_data.get(), pts.data(), (int)pts.size()));
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -98,7 +95,7 @@ auto Renderer::draw_rect(const SDL_Rect* const r) -> Renderer*
|
||||||
// The second corner is missing a pixel.
|
// The second corner is missing a pixel.
|
||||||
if (r != nullptr)
|
if (r != nullptr)
|
||||||
viewport({vp.x + r->x, vp.y + r->y, r->w - 1, r->h - 1}); // crop extra pixel
|
viewport({vp.x + r->x, vp.y + r->y, r->w - 1, r->h - 1}); // crop extra pixel
|
||||||
success_or_throw<SDLError>(SDL_RenderDrawRect(_data(), nullptr));
|
success_or_throw<SDLError>(SDL_RenderDrawRect(_data.get(), nullptr));
|
||||||
// add missing pixel. works sometimes…
|
// add missing pixel. works sometimes…
|
||||||
if (r != nullptr) draw_point({r->w - 1, r->h - 1});
|
if (r != nullptr) draw_point({r->w - 1, r->h - 1});
|
||||||
else draw_point({vp.w - 1, vp.h - 1});
|
else draw_point({vp.w - 1, vp.h - 1});
|
||||||
|
@ -110,21 +107,23 @@ auto Renderer::draw_rect(const SDL_Rect* const r) -> Renderer*
|
||||||
|
|
||||||
auto Renderer::draw_rects(const std::span<SDL_Rect> rs) -> Renderer*
|
auto Renderer::draw_rects(const std::span<SDL_Rect> rs) -> Renderer*
|
||||||
{
|
{
|
||||||
success_or_throw<SDLError>(SDL_RenderDrawRects(_data(), rs.data(), (int)rs.size()));
|
success_or_throw<SDLError>(
|
||||||
|
SDL_RenderDrawRects(_data.get(), rs.data(), (int)rs.size()));
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Renderer::fill_rect(const SDL_Rect* const r) -> Renderer*
|
auto Renderer::fill_rect(const SDL_Rect* const r) -> Renderer*
|
||||||
{
|
{
|
||||||
success_or_throw<SDLError>(SDL_RenderFillRect(_data(), r));
|
success_or_throw<SDLError>(SDL_RenderFillRect(_data.get(), r));
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Renderer::fill_rects(const std::span<SDL_Rect> rs) -> Renderer*
|
auto Renderer::fill_rects(const std::span<SDL_Rect> rs) -> Renderer*
|
||||||
{
|
{
|
||||||
success_or_throw<SDLError>(SDL_RenderFillRects(_data(), rs.data(), (int)rs.size()));
|
success_or_throw<SDLError>(
|
||||||
|
SDL_RenderFillRects(_data.get(), rs.data(), (int)rs.size()));
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -132,27 +131,27 @@ auto Renderer::fill_rects(const std::span<SDL_Rect> rs) -> Renderer*
|
||||||
auto Renderer::output_size() -> Size
|
auto Renderer::output_size() -> Size
|
||||||
{
|
{
|
||||||
Size s {};
|
Size s {};
|
||||||
success_or_throw<SDLError>(SDL_GetRendererOutputSize(_data(), &s.w, &s.h));
|
success_or_throw<SDLError>(SDL_GetRendererOutputSize(_data.get(), &s.w, &s.h));
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::present() noexcept
|
void Renderer::present() noexcept
|
||||||
{
|
{
|
||||||
SDL_RenderPresent(_data());
|
SDL_RenderPresent(_data.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Renderer::viewport() noexcept -> SDL_Rect
|
auto Renderer::viewport() noexcept -> SDL_Rect
|
||||||
{
|
{
|
||||||
SDL_Rect vp;
|
SDL_Rect vp;
|
||||||
SDL_RenderGetViewport(_data(), &vp);
|
SDL_RenderGetViewport(_data.get(), &vp);
|
||||||
|
|
||||||
return vp;
|
return vp;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Renderer::viewport(const SDL_Rect* const vp) -> Renderer*
|
auto Renderer::viewport(const SDL_Rect* const vp) -> Renderer*
|
||||||
{
|
{
|
||||||
success_or_throw<SDLError>(SDL_RenderSetViewport(_data(), vp));
|
success_or_throw<SDLError>(SDL_RenderSetViewport(_data.get(), vp));
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,18 +4,16 @@
|
||||||
using namespace bwidgets;
|
using namespace bwidgets;
|
||||||
|
|
||||||
Texture::Texture(SDL_Texture* t)
|
Texture::Texture(SDL_Texture* t)
|
||||||
: Wrapper {ptr_or_throw<SDLError>(t),
|
: _attributes(attributes(t)), _data {ptr_or_throw<SDLError>(t)}
|
||||||
[t](SDL_Texture*) noexcept { SDL_DestroyTexture(t); }},
|
|
||||||
_attributes(attributes(t))
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Texture::Texture(const Renderer& r, const SDL_PixelFormatEnum f,
|
Texture::Texture(const Renderer& r, const SDL_PixelFormatEnum f,
|
||||||
const SDL_TextureAccess a, int w, int h)
|
const SDL_TextureAccess a, int w, int h)
|
||||||
: Texture {SDL_CreateTexture(r._data(), f, a, w, h)}
|
: Texture {SDL_CreateTexture(r._data.get(), f, a, w, h)}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Texture::Texture(const Renderer& r, SDL_Surface* const s)
|
Texture::Texture(const Renderer& r, SDL_Surface* const s)
|
||||||
: Texture {SDL_CreateTextureFromSurface(r._data(), s)}
|
: Texture {SDL_CreateTextureFromSurface(r._data.get(), s)}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Texture::~Texture() noexcept
|
Texture::~Texture() noexcept
|
||||||
|
@ -27,14 +25,14 @@ Texture::~Texture() noexcept
|
||||||
auto Texture::alpha_mode() -> uint8_t
|
auto Texture::alpha_mode() -> uint8_t
|
||||||
{
|
{
|
||||||
uint8_t mode = 0;
|
uint8_t mode = 0;
|
||||||
success_or_throw<SDLError>(SDL_GetTextureAlphaMod(_data(), &mode));
|
success_or_throw<SDLError>(SDL_GetTextureAlphaMod(_data.get(), &mode));
|
||||||
|
|
||||||
return mode;
|
return mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Texture::alpha_mode(const uint8_t m) -> Texture*
|
auto Texture::alpha_mode(const uint8_t m) -> Texture*
|
||||||
{
|
{
|
||||||
success_or_throw<SDLError>(SDL_SetTextureAlphaMod(_data(), m));
|
success_or_throw<SDLError>(SDL_SetTextureAlphaMod(_data.get(), m));
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -42,14 +40,14 @@ auto Texture::alpha_mode(const uint8_t m) -> Texture*
|
||||||
auto Texture::blend_mode() -> SDL_BlendMode
|
auto Texture::blend_mode() -> SDL_BlendMode
|
||||||
{
|
{
|
||||||
SDL_BlendMode mode {};
|
SDL_BlendMode mode {};
|
||||||
success_or_throw<SDLError>(SDL_GetTextureBlendMode(_data(), &mode));
|
success_or_throw<SDLError>(SDL_GetTextureBlendMode(_data.get(), &mode));
|
||||||
|
|
||||||
return mode;
|
return mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Texture::blend_mode(const SDL_BlendMode m) -> Texture*
|
auto Texture::blend_mode(const SDL_BlendMode m) -> Texture*
|
||||||
{
|
{
|
||||||
success_or_throw<SDLError>(SDL_SetTextureBlendMode(_data(), m));
|
success_or_throw<SDLError>(SDL_SetTextureBlendMode(_data.get(), m));
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -58,14 +56,14 @@ auto Texture::color_mode() -> Color
|
||||||
{
|
{
|
||||||
Color mode;
|
Color mode;
|
||||||
success_or_throw<SDLError>(
|
success_or_throw<SDLError>(
|
||||||
SDL_GetTextureColorMod(_data(), &mode().r, &mode().g, &mode().b));
|
SDL_GetTextureColorMod(_data.get(), &mode().r, &mode().g, &mode().b));
|
||||||
|
|
||||||
return mode;
|
return mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Texture::color_mode(Color m) -> Texture*
|
auto Texture::color_mode(Color m) -> Texture*
|
||||||
{
|
{
|
||||||
success_or_throw<SDLError>(SDL_SetTextureColorMod(_data(), m().r, m().g, m().b));
|
success_or_throw<SDLError>(SDL_SetTextureColorMod(_data.get(), m().r, m().g, m().b));
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -73,14 +71,14 @@ auto Texture::color_mode(Color m) -> Texture*
|
||||||
auto Texture::scale_mode() -> SDL_ScaleMode
|
auto Texture::scale_mode() -> SDL_ScaleMode
|
||||||
{
|
{
|
||||||
SDL_ScaleMode mode {};
|
SDL_ScaleMode mode {};
|
||||||
success_or_throw<SDLError>(SDL_GetTextureScaleMode(_data(), &mode));
|
success_or_throw<SDLError>(SDL_GetTextureScaleMode(_data.get(), &mode));
|
||||||
|
|
||||||
return mode;
|
return mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Texture::scale_mode(const SDL_ScaleMode m) -> Texture*
|
auto Texture::scale_mode(const SDL_ScaleMode m) -> Texture*
|
||||||
{
|
{
|
||||||
success_or_throw<SDLError>(SDL_SetTextureScaleMode(_data(), m));
|
success_or_throw<SDLError>(SDL_SetTextureScaleMode(_data.get(), m));
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -88,7 +86,7 @@ auto Texture::scale_mode(const SDL_ScaleMode m) -> Texture*
|
||||||
auto Texture::update(const SDL_Rect* const r, const void* const pixels, const int pitch)
|
auto Texture::update(const SDL_Rect* const r, const void* const pixels, const int pitch)
|
||||||
-> Texture*
|
-> Texture*
|
||||||
{
|
{
|
||||||
success_or_throw<SDLError>(SDL_UpdateTexture(_data(), r, pixels, pitch));
|
success_or_throw<SDLError>(SDL_UpdateTexture(_data.get(), r, pixels, pitch));
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,5 +118,5 @@ void CaptionImpl::_handle_texture_update()
|
||||||
return _font->render(_render_mode, _text, _font_color_fg);
|
return _font->render(_render_mode, _text, _font_color_fg);
|
||||||
}
|
}
|
||||||
}();
|
}();
|
||||||
_text_texture = std::make_shared<Texture>(*_renderer, s());
|
_text_texture = std::make_shared<Texture>(*_renderer, s.get());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue