From d8f56e0e5ff247911749061829b91c55da5a4b8a Mon Sep 17 00:00:00 2001 From: Andrea Blankenstijn Date: Thu, 26 Aug 2021 18:59:52 +0200 Subject: [PATCH] Delete OpaqueStruct and use directly fancy pointers now that I know how to set the deleter correctly. --- examples/run.hpp | 10 ++-- inc/basic_widgets/core/font.hpp | 10 +++- inc/basic_widgets/core/renderer.hpp | 7 ++- inc/basic_widgets/core/texture.hpp | 9 ++- inc/basic_widgets/core/type/deleter.hpp | 51 +++++++++++++++++ inc/basic_widgets/core/type/opaque_struct.hpp | 53 ----------------- inc/basic_widgets/w/feat/font_handler.hpp | 4 +- src/core/font.cpp | 57 +++++++++---------- src/core/renderer.cpp | 45 +++++++-------- src/core/texture.cpp | 26 ++++----- src/w/caption_impl.cpp | 2 +- 11 files changed, 139 insertions(+), 135 deletions(-) create mode 100644 inc/basic_widgets/core/type/deleter.hpp delete mode 100644 inc/basic_widgets/core/type/opaque_struct.hpp diff --git a/examples/run.hpp b/examples/run.hpp index 13ffea9..796f283 100644 --- a/examples/run.hpp +++ b/examples/run.hpp @@ -4,6 +4,7 @@ #include #include +#include #include template @@ -26,14 +27,15 @@ void run_example( auto font = std::make_shared(bwidgets::Font::find("Monospace"), 16); // NOLINT(readability-magic-numbers) - auto win = bwidgets::OpaqueStruct( + + auto win = std::unique_ptr( bwidgets::ptr_or_throw(SDL_CreateWindow( "basic_widgets example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, size_init.w, size_init.h, - SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_UTILITY)), - [](auto ptr) noexcept { SDL_DestroyWindow(ptr); }); + SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_UTILITY))); + auto renderer = - std::make_shared(win(), -1, SDL_RENDERER_ACCELERATED); + std::make_shared(win.get(), -1, SDL_RENDERER_ACCELERATED); renderer->blend_mode(SDL_BLENDMODE_BLEND); auto layout = bwidgets::create_horizontal_layout(); diff --git a/inc/basic_widgets/core/font.hpp b/inc/basic_widgets/core/font.hpp index 506fb26..a923dc6 100644 --- a/inc/basic_widgets/core/font.hpp +++ b/inc/basic_widgets/core/font.hpp @@ -1,19 +1,22 @@ #ifndef BWIDGETS_FONT_HPP #define BWIDGETS_FONT_HPP +#include #include #include #include -#include +#include #include namespace bwidgets { // Wrap TTF_Font from SDL_ttf and provide a font finding function. - class Font final : OpaqueStruct::Wrapper + class Font final { + const std::unique_ptr _data; + public: enum struct Hinting { @@ -67,7 +70,8 @@ namespace bwidgets [[nodiscard]] auto outline() const noexcept -> int; auto outline(int) noexcept -> Font*; auto render(RenderMode, std::string_view, Color fg = default_color_fg, - Color bg = default_color_bg) -> OpaqueStruct; + Color bg = default_color_bg) + -> std::unique_ptr; [[nodiscard]] auto style() const noexcept -> uint8_t; auto style(uint8_t) noexcept -> Font*; [[nodiscard]] auto text_size(std::string_view) const noexcept -> Size; diff --git a/inc/basic_widgets/core/renderer.hpp b/inc/basic_widgets/core/renderer.hpp index d04cb48..b81d079 100644 --- a/inc/basic_widgets/core/renderer.hpp +++ b/inc/basic_widgets/core/renderer.hpp @@ -1,13 +1,14 @@ #ifndef BWIDGETS_RENDERER_HPP #define BWIDGETS_RENDERER_HPP +#include #include #include #include #include -#include +#include #include namespace bwidgets @@ -15,10 +16,12 @@ namespace bwidgets class Texture; // Wrap some of SDL's 2D accelerated rendering API. - class Renderer final : OpaqueStruct::Wrapper + class Renderer final { friend Texture; + const std::unique_ptr _data; + static auto _info(SDL_Renderer* r) -> SDL_RendererInfo { SDL_RendererInfo info; diff --git a/inc/basic_widgets/core/texture.hpp b/inc/basic_widgets/core/texture.hpp index 443f331..4870f02 100644 --- a/inc/basic_widgets/core/texture.hpp +++ b/inc/basic_widgets/core/texture.hpp @@ -1,19 +1,21 @@ #ifndef BWIDGETS_TEXTURE_HPP #define BWIDGETS_TEXTURE_HPP +#include + #include #include #include #include -#include +#include namespace bwidgets { class Renderer; // Wrap most of the texture functions of SDL 2D rendering API. - class Texture final : OpaqueStruct::Wrapper + class Texture final { friend Renderer; @@ -25,7 +27,8 @@ namespace bwidgets int w, h; }; - const Attr _attributes; + const Attr _attributes; + const std::unique_ptr _data; public: explicit Texture(SDL_Texture*); diff --git a/inc/basic_widgets/core/type/deleter.hpp b/inc/basic_widgets/core/type/deleter.hpp new file mode 100644 index 0000000..08e5c05 --- /dev/null +++ b/inc/basic_widgets/core/type/deleter.hpp @@ -0,0 +1,51 @@ +#ifndef BWIDGETS_OPAQUE_STRUCT_HPP +#define BWIDGETS_OPAQUE_STRUCT_HPP + +#include +#include +#include +#include + +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 diff --git a/inc/basic_widgets/core/type/opaque_struct.hpp b/inc/basic_widgets/core/type/opaque_struct.hpp deleted file mode 100644 index 1b16592..0000000 --- a/inc/basic_widgets/core/type/opaque_struct.hpp +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef BWIDGETS_OPAQUE_STRUCT_HPP -#define BWIDGETS_OPAQUE_STRUCT_HPP - -#include - -namespace bwidgets -{ - // Wrap opaque structures to be able to use a destructor to free them. - template - class OpaqueStruct - { - using Deleter = std::function; - - 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 diff --git a/inc/basic_widgets/w/feat/font_handler.hpp b/inc/basic_widgets/w/feat/font_handler.hpp index 66bdc95..2fa09fc 100644 --- a/inc/basic_widgets/w/feat/font_handler.hpp +++ b/inc/basic_widgets/w/feat/font_handler.hpp @@ -12,7 +12,6 @@ namespace bwidgets 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(FontHandler&&) = delete; auto operator=(const FontHandler&) = delete; @@ -26,6 +25,9 @@ namespace bwidgets virtual void font_color_bg(Color c) = 0; // Set font foreground (text) color. virtual void font_color_fg(Color c) = 0; + + protected: + FontHandler() noexcept = default; }; } diff --git a/src/core/font.cpp b/src/core/font.cpp index 669466b..a7a6bed 100644 --- a/src/core/font.cpp +++ b/src/core/font.cpp @@ -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}; Font::Font(TTF_Font* f) - : Wrapper {ptr_or_throw(f), [f](TTF_Font*) noexcept { TTF_CloseFont(f); }}, + : _data {ptr_or_throw(f)}, ascent {TTF_FontAscent(f)}, descent {TTF_FontDescent(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 { - return static_cast(TTF_GetFontHinting(_data())); + return static_cast(TTF_GetFontHinting(_data.get())); } auto Font::hinting(const Font::Hinting h) noexcept -> Font* { - TTF_SetFontHinting(_data(), static_cast(h)); + TTF_SetFontHinting(_data.get(), static_cast(h)); return this; } 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* { - TTF_SetFontKerning(_data(), static_cast(allowed)); + TTF_SetFontKerning(_data.get(), static_cast(allowed)); return this; } auto Font::outline() const noexcept -> int { - return TTF_GetFontOutline(_data()); + return TTF_GetFontOutline(_data.get()); } auto Font::outline(const int size) noexcept -> Font* { - TTF_SetFontOutline(_data(), size); + TTF_SetFontOutline(_data.get(), size); return this; } auto Font::render(const RenderMode m, const std::string_view str, const Color fg, - const Color bg) -> OpaqueStruct + const Color bg) -> std::unique_ptr { const char* const c_str = str.empty() ? " " : str.data(); auto renderer = [bg, c_str, fg, m, this]() -> std::function { switch (m) { case RenderMode::BLENDED: 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: 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: return [fg, c_str, this]() { - return TTF_RenderUTF8_Solid(_data(), c_str, fg()); + return TTF_RenderUTF8_Solid(_data.get(), c_str, fg()); }; default: throw std::logic_error("missing switch case."); } }(); - return {ptr_or_throw(renderer()), [](auto* ptr) { SDL_FreeSurface(ptr); }}; + return std::unique_ptr(ptr_or_throw(renderer())); } 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* { - TTF_SetFontStyle(_data(), s); + TTF_SetFontStyle(_data.get(), s); return this; } auto Font::text_size(const std::string_view str) const noexcept -> Size { Size s {}; - TTF_SizeUTF8(_data(), str.data(), &s.w, &s.h); + TTF_SizeUTF8(_data.get(), str.data(), &s.w, &s.h); return s; } auto Font::find(const std::string_view pat) -> std::string { - const auto conf = std::make_unique>( - ptr_or_throw(FcInitLoadConfigAndFonts(), "init failed"), - [](auto* ptr) { FcConfigDestroy(ptr); }); + const auto conf = std::unique_ptr( + ptr_or_throw(FcInitLoadConfigAndFonts(), "fontconfig init failed.")); const auto pattern = [&conf, pat]() { - auto pattern = std::make_unique>( - ptr_or_throw( - FcNameParse(reinterpret_cast(pat.data())), - "pattern parsing failed"), - [](auto* ptr) { FcPatternDestroy(ptr); }); + auto pattern = std::unique_ptr(ptr_or_throw( + FcNameParse(reinterpret_cast(pat.data())), + "pattern parsing failed")); success_or_throw( - FcConfigSubstitute((*conf)(), (*pattern)(), FcMatchPattern), + FcConfigSubstitute(conf.get(), pattern.get(), FcMatchPattern), "FcConfigSubstitute failed", [](auto code) { return code == FcTrue; }); return pattern; }(); - FcDefaultSubstitute((*pattern)()); + FcDefaultSubstitute(pattern.get()); std::string file_path = [&conf, &pattern]() { FcResult res {}; - const auto font = std::make_unique>( - ptr_or_throw(FcFontMatch((*conf)(), (*pattern)(), &res), - "no font found."), - [](auto* ptr) { FcPatternDestroy(ptr); }); + const auto font = std::unique_ptr(ptr_or_throw( + FcFontMatch(conf.get(), pattern.get(), &res), "no font found.")); 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" + // NOLINTNEXTLINE std::string _file_path {reinterpret_cast(file)}; - FcPatternDestroy((*font)()); return _file_path; } throw FCError("no font found."); diff --git a/src/core/renderer.cpp b/src/core/renderer.cpp index bb6b5dd..bda2961 100644 --- a/src/core/renderer.cpp +++ b/src/core/renderer.cpp @@ -3,34 +3,31 @@ using namespace bwidgets; -Renderer::Renderer(SDL_Renderer* r) - : Wrapper {ptr_or_throw(r), - [r](SDL_Renderer*) noexcept { SDL_DestroyRenderer(r); }}, - info {_info(r)} +Renderer::Renderer(SDL_Renderer* r) : _data {ptr_or_throw(r)}, info {_info(r)} {} Renderer::Renderer(SDL_Window* w, const int index, const uint32_t flags = 0) - : Renderer {ptr_or_throw(SDL_CreateRenderer(w, index, flags))} + : Renderer {SDL_CreateRenderer(w, index, flags)} {} auto Renderer::blend_mode() -> SDL_BlendMode { SDL_BlendMode mode {}; - success_or_throw(SDL_GetRenderDrawBlendMode(_data(), &mode)); + success_or_throw(SDL_GetRenderDrawBlendMode(_data.get(), &mode)); return mode; } auto Renderer::blend_mode(const SDL_BlendMode mode) -> Renderer* { - success_or_throw(SDL_SetRenderDrawBlendMode(_data(), mode)); + success_or_throw(SDL_SetRenderDrawBlendMode(_data.get(), mode)); return this; } auto Renderer::clear() -> Renderer* { - success_or_throw(SDL_RenderClear(_data())); + success_or_throw(SDL_RenderClear(_data.get())); return this; } @@ -38,7 +35,7 @@ auto Renderer::clear() -> Renderer* auto Renderer::copy(const Texture& t, const SDL_Rect* const src, const SDL_Rect* const dst) -> Renderer* { - success_or_throw(SDL_RenderCopy(_data(), t._data(), src, dst)); + success_or_throw(SDL_RenderCopy(_data.get(), t._data.get(), src, dst)); return this; } @@ -47,7 +44,7 @@ auto Renderer::draw_color() -> Color { Color c; success_or_throw( - 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; } @@ -55,14 +52,14 @@ auto Renderer::draw_color() -> Color auto Renderer::draw_color(const Color c) -> Renderer* { success_or_throw( - 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; } auto Renderer::draw_line(const SDL_Point a, const SDL_Point b) -> Renderer* { - success_or_throw(SDL_RenderDrawLine(_data(), a.x, a.y, b.x, b.y)); + success_or_throw(SDL_RenderDrawLine(_data.get(), a.x, a.y, b.x, b.y)); 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 pts) -> Renderer* { success_or_throw( - SDL_RenderDrawLines(_data(), pts.data(), (int)pts.size())); + SDL_RenderDrawLines(_data.get(), pts.data(), (int)pts.size())); return this; } auto Renderer::draw_point(const SDL_Point p) -> Renderer* { - success_or_throw(SDL_RenderDrawPoint(_data(), p.x, p.y)); + success_or_throw(SDL_RenderDrawPoint(_data.get(), p.x, p.y)); return this; } @@ -85,7 +82,7 @@ auto Renderer::draw_point(const SDL_Point p) -> Renderer* auto Renderer::draw_points(const std::span pts) -> Renderer* { success_or_throw( - SDL_RenderDrawPoints(_data(), pts.data(), (int)pts.size())); + SDL_RenderDrawPoints(_data.get(), pts.data(), (int)pts.size())); return this; } @@ -98,7 +95,7 @@ auto Renderer::draw_rect(const SDL_Rect* const r) -> Renderer* // The second corner is missing a pixel. if (r != nullptr) viewport({vp.x + r->x, vp.y + r->y, r->w - 1, r->h - 1}); // crop extra pixel - success_or_throw(SDL_RenderDrawRect(_data(), nullptr)); + success_or_throw(SDL_RenderDrawRect(_data.get(), nullptr)); // add missing pixel. works sometimes… if (r != nullptr) draw_point({r->w - 1, r->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 rs) -> Renderer* { - success_or_throw(SDL_RenderDrawRects(_data(), rs.data(), (int)rs.size())); + success_or_throw( + SDL_RenderDrawRects(_data.get(), rs.data(), (int)rs.size())); return this; } auto Renderer::fill_rect(const SDL_Rect* const r) -> Renderer* { - success_or_throw(SDL_RenderFillRect(_data(), r)); + success_or_throw(SDL_RenderFillRect(_data.get(), r)); return this; } auto Renderer::fill_rects(const std::span rs) -> Renderer* { - success_or_throw(SDL_RenderFillRects(_data(), rs.data(), (int)rs.size())); + success_or_throw( + SDL_RenderFillRects(_data.get(), rs.data(), (int)rs.size())); return this; } @@ -132,27 +131,27 @@ auto Renderer::fill_rects(const std::span rs) -> Renderer* auto Renderer::output_size() -> Size { Size s {}; - success_or_throw(SDL_GetRendererOutputSize(_data(), &s.w, &s.h)); + success_or_throw(SDL_GetRendererOutputSize(_data.get(), &s.w, &s.h)); return s; } void Renderer::present() noexcept { - SDL_RenderPresent(_data()); + SDL_RenderPresent(_data.get()); } auto Renderer::viewport() noexcept -> SDL_Rect { SDL_Rect vp; - SDL_RenderGetViewport(_data(), &vp); + SDL_RenderGetViewport(_data.get(), &vp); return vp; } auto Renderer::viewport(const SDL_Rect* const vp) -> Renderer* { - success_or_throw(SDL_RenderSetViewport(_data(), vp)); + success_or_throw(SDL_RenderSetViewport(_data.get(), vp)); return this; } diff --git a/src/core/texture.cpp b/src/core/texture.cpp index 4e7d7ae..07aa213 100644 --- a/src/core/texture.cpp +++ b/src/core/texture.cpp @@ -4,18 +4,16 @@ using namespace bwidgets; Texture::Texture(SDL_Texture* t) - : Wrapper {ptr_or_throw(t), - [t](SDL_Texture*) noexcept { SDL_DestroyTexture(t); }}, - _attributes(attributes(t)) + : _attributes(attributes(t)), _data {ptr_or_throw(t)} {} Texture::Texture(const Renderer& r, const SDL_PixelFormatEnum f, 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 {SDL_CreateTextureFromSurface(r._data(), s)} + : Texture {SDL_CreateTextureFromSurface(r._data.get(), s)} {} Texture::~Texture() noexcept @@ -27,14 +25,14 @@ Texture::~Texture() noexcept auto Texture::alpha_mode() -> uint8_t { uint8_t mode = 0; - success_or_throw(SDL_GetTextureAlphaMod(_data(), &mode)); + success_or_throw(SDL_GetTextureAlphaMod(_data.get(), &mode)); return mode; } auto Texture::alpha_mode(const uint8_t m) -> Texture* { - success_or_throw(SDL_SetTextureAlphaMod(_data(), m)); + success_or_throw(SDL_SetTextureAlphaMod(_data.get(), m)); return this; } @@ -42,14 +40,14 @@ auto Texture::alpha_mode(const uint8_t m) -> Texture* auto Texture::blend_mode() -> SDL_BlendMode { SDL_BlendMode mode {}; - success_or_throw(SDL_GetTextureBlendMode(_data(), &mode)); + success_or_throw(SDL_GetTextureBlendMode(_data.get(), &mode)); return mode; } auto Texture::blend_mode(const SDL_BlendMode m) -> Texture* { - success_or_throw(SDL_SetTextureBlendMode(_data(), m)); + success_or_throw(SDL_SetTextureBlendMode(_data.get(), m)); return this; } @@ -58,14 +56,14 @@ auto Texture::color_mode() -> Color { Color mode; success_or_throw( - SDL_GetTextureColorMod(_data(), &mode().r, &mode().g, &mode().b)); + SDL_GetTextureColorMod(_data.get(), &mode().r, &mode().g, &mode().b)); return mode; } auto Texture::color_mode(Color m) -> Texture* { - success_or_throw(SDL_SetTextureColorMod(_data(), m().r, m().g, m().b)); + success_or_throw(SDL_SetTextureColorMod(_data.get(), m().r, m().g, m().b)); return this; } @@ -73,14 +71,14 @@ auto Texture::color_mode(Color m) -> Texture* auto Texture::scale_mode() -> SDL_ScaleMode { SDL_ScaleMode mode {}; - success_or_throw(SDL_GetTextureScaleMode(_data(), &mode)); + success_or_throw(SDL_GetTextureScaleMode(_data.get(), &mode)); return mode; } auto Texture::scale_mode(const SDL_ScaleMode m) -> Texture* { - success_or_throw(SDL_SetTextureScaleMode(_data(), m)); + success_or_throw(SDL_SetTextureScaleMode(_data.get(), m)); 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) -> Texture* { - success_or_throw(SDL_UpdateTexture(_data(), r, pixels, pitch)); + success_or_throw(SDL_UpdateTexture(_data.get(), r, pixels, pitch)); return this; } diff --git a/src/w/caption_impl.cpp b/src/w/caption_impl.cpp index 28232de..f97ec19 100644 --- a/src/w/caption_impl.cpp +++ b/src/w/caption_impl.cpp @@ -118,5 +118,5 @@ void CaptionImpl::_handle_texture_update() return _font->render(_render_mode, _text, _font_color_fg); } }(); - _text_texture = std::make_shared(*_renderer, s()); + _text_texture = std::make_shared(*_renderer, s.get()); }