27 #include "sdl_widget.hpp"
28 #include "../sdl_utils.hpp"
30 #include "res/sdl2_resource_manager.hpp"
32 #include <freerdp/log.h>
34 #if defined(WITH_SDL_IMAGE_DIALOGS)
35 #include <SDL_image.h>
38 #define TAG CLIENT_TAG("SDL.widget")
40 static const SDL_Color backgroundcolor = { 0x38, 0x36, 0x35, 0xff };
42 static const Uint32 hpadding = 10;
44 SdlWidget::SdlWidget(SDL_Renderer* renderer, SDL_Rect rect,
bool input) : _rect(rect), _input(input)
49 "OpenSans-VariableFont_wdth,wght.ttf");
51 widget_log_error(-1,
"SDLResourceManager::get");
54 _font = TTF_OpenFontRW(ops, 1, 64);
56 widget_log_error(-1,
"TTF_OpenFontRW");
60 #if defined(WITH_SDL_IMAGE_DIALOGS)
61 SdlWidget::SdlWidget(SDL_Renderer* renderer, SDL_Rect rect, SDL_RWops* ops) : _rect(rect)
65 _image = IMG_LoadTexture_RW(renderer, ops, 1);
67 widget_log_error(-1,
"IMG_LoadTextureTyped_RW");
72 SdlWidget::SdlWidget(
SdlWidget&& other) noexcept
73 : _font(other._font), _image(other._image), _rect(other._rect), _input(other._input),
74 _wrap(other._wrap), _text_width(other._text_width)
76 other._font =
nullptr;
77 other._image =
nullptr;
80 SDL_Texture* SdlWidget::render_text(SDL_Renderer* renderer,
const std::string& text,
81 SDL_Color fgcolor, SDL_Rect& src, SDL_Rect& dst)
83 auto surface = TTF_RenderUTF8_Blended(_font, text.c_str(), fgcolor);
86 widget_log_error(-1,
"TTF_RenderText_Blended");
90 auto texture = SDL_CreateTextureFromSurface(renderer, surface);
91 SDL_FreeSurface(surface);
94 widget_log_error(-1,
"SDL_CreateTextureFromSurface");
98 TTF_SizeUTF8(_font, text.c_str(), &src.w, &src.h);
107 dst.w -= 2 * hpadding;
108 const auto scale =
static_cast<float>(dst.h) /
static_cast<float>(src.h);
109 const auto sws =
static_cast<float>(src.w) * scale;
110 const auto dws =
static_cast<float>(dst.w) / scale;
111 if (
static_cast<float>(dst.w) > sws)
112 dst.w =
static_cast<int>(sws);
113 if (
static_cast<float>(src.w) > dws)
115 src.x = src.w -
static_cast<int>(dws);
116 src.w =
static_cast<int>(dws);
121 static int scale(
int w,
int h)
123 const auto dw =
static_cast<double>(w);
124 const auto dh =
static_cast<double>(h);
125 const auto scale = dh / dw;
126 const auto dr = dh * scale;
127 return static_cast<int>(dr);
130 SDL_Texture* SdlWidget::render_text_wrapped(SDL_Renderer* renderer,
const std::string& text,
131 SDL_Color fgcolor, SDL_Rect& src, SDL_Rect& dst)
135 TTF_SizeUTF8(_font,
" ", &w, &h);
137 assert(_text_width <= UINT32_MAX);
138 auto surface = TTF_RenderUTF8_Blended_Wrapped(_font, text.c_str(), fgcolor,
139 static_cast<Uint32
>(_text_width));
142 widget_log_error(-1,
"TTF_RenderText_Blended");
149 auto texture = SDL_CreateTextureFromSurface(renderer, surface);
150 SDL_FreeSurface(surface);
153 widget_log_error(-1,
"SDL_CreateTextureFromSurface");
164 dst.w -= 2 * hpadding;
165 auto dh = scale(src.w, src.h);
172 SdlWidget::~SdlWidget()
174 TTF_CloseFont(_font);
176 SDL_DestroyTexture(_image);
179 bool SdlWidget::error_ex(Uint32 res,
const char* what,
const char* file,
size_t line,
182 static wLog* log =
nullptr;
185 return sdl_log_error_ex(res, log, what, file, line, fkt);
188 static bool draw_rect(SDL_Renderer* renderer,
const SDL_Rect* rect, SDL_Color color)
190 const int drc = SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, color.a);
191 if (widget_log_error(drc,
"SDL_SetRenderDrawColor"))
194 const int rc = SDL_RenderFillRect(renderer, rect);
195 return !widget_log_error(rc,
"SDL_RenderFillRect");
198 bool SdlWidget::fill(SDL_Renderer* renderer, SDL_Color color)
200 std::vector<SDL_Color> colors = { color };
201 return fill(renderer, colors);
204 bool SdlWidget::fill(SDL_Renderer* renderer,
const std::vector<SDL_Color>& colors)
207 SDL_BlendMode mode = SDL_BLENDMODE_INVALID;
208 SDL_GetRenderDrawBlendMode(renderer, &mode);
209 SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE);
210 for (
auto color : colors)
212 draw_rect(renderer, &_rect, color);
213 SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_ADD);
215 SDL_SetRenderDrawBlendMode(renderer, mode);
219 bool SdlWidget::update_text(SDL_Renderer* renderer,
const std::string& text, SDL_Color fgcolor,
224 if (!fill(renderer, bgcolor))
226 return update_text(renderer, text, fgcolor);
229 bool SdlWidget::wrap()
const
234 bool SdlWidget::set_wrap(
bool wrap,
size_t width)
241 const SDL_Rect& SdlWidget::rect()
const
246 bool SdlWidget::update_text(SDL_Renderer* renderer,
const std::string& text, SDL_Color fgcolor)
255 SDL_Texture* texture =
nullptr;
260 auto rc = SDL_QueryTexture(_image,
nullptr,
nullptr, &src.w, &src.h);
262 widget_log_error(rc,
"SDL_QueryTexture");
265 texture = render_text_wrapped(renderer, text, fgcolor, src, dst);
267 texture = render_text(renderer, text, fgcolor, src, dst);
271 const int rc = SDL_RenderCopy(renderer, texture, &src, &dst);
273 SDL_DestroyTexture(texture);
275 return !widget_log_error(rc,
"SDL_RenderCopy");
279 bool clear_window(SDL_Renderer* renderer)
283 const int drc = SDL_SetRenderDrawColor(renderer, backgroundcolor.r, backgroundcolor.g,
284 backgroundcolor.b, backgroundcolor.a);
285 if (widget_log_error(drc,
"SDL_SetRenderDrawColor"))
288 const int rcls = SDL_RenderClear(renderer);
289 return !widget_log_error(rcls,
"SDL_RenderClear");
static SDL_RWops * get(const std::string &type, const std::string &id)
static std::string typeFonts()