28#include "sdl_widget.hpp" 
   29#include "../sdl_utils.hpp" 
   31#include "res/sdl2_resource_manager.hpp" 
   33#include <freerdp/log.h> 
   35#if defined(WITH_SDL_IMAGE_DIALOGS) 
   39#define TAG CLIENT_TAG("SDL.widget") 
   41static const SDL_Color backgroundcolor = { 0x38, 0x36, 0x35, 0xff };
 
   43static const Uint32 hpadding = 10;
 
   45SdlWidget::SdlWidget([[maybe_unused]] SDL_Renderer* renderer, SDL_Rect rect, 
bool input)
 
   46    : _rect(rect), _input(input)
 
   51                                      "OpenSans-VariableFont_wdth,wght.ttf");
 
   53    widget_log_error(-1, 
"SDLResourceManager::get");
 
   56    _font = TTF_OpenFontRW(ops, 1, 64);
 
   58      widget_log_error(-1, 
"TTF_OpenFontRW");
 
   62#if defined(WITH_SDL_IMAGE_DIALOGS) 
   63SdlWidget::SdlWidget(SDL_Renderer* renderer, SDL_Rect rect, SDL_RWops* ops) : _rect(rect)
 
   67    _image = IMG_LoadTexture_RW(renderer, ops, 1);
 
   69      widget_log_error(-1, 
"IMG_LoadTextureTyped_RW");
 
   74SdlWidget::SdlWidget(
SdlWidget&& other) noexcept
 
   75    : _font(other._font), _image(other._image), _rect(other._rect), _input(other._input),
 
   76      _wrap(other._wrap), _text_width(other._text_width)
 
   78  other._font = 
nullptr;
 
   79  other._image = 
nullptr;
 
   82SDL_Texture* SdlWidget::render_text(SDL_Renderer* renderer, 
const std::string& text,
 
   83                                    SDL_Color fgcolor, SDL_Rect& src, SDL_Rect& dst)
 
   85  auto surface = TTF_RenderUTF8_Blended(_font, text.c_str(), fgcolor);
 
   88    widget_log_error(-1, 
"TTF_RenderText_Blended");
 
   92  auto texture = SDL_CreateTextureFromSurface(renderer, surface);
 
   93  SDL_FreeSurface(surface);
 
   96    widget_log_error(-1, 
"SDL_CreateTextureFromSurface");
 
  100  TTF_SizeUTF8(_font, text.c_str(), &src.w, &src.h);
 
  109  dst.w -= 2 * hpadding;
 
  110  const auto scale = 
static_cast<float>(dst.h) / 
static_cast<float>(src.h);
 
  111  const auto sws = 
static_cast<float>(src.w) * scale;
 
  112  const auto dws = 
static_cast<float>(dst.w) / scale;
 
  113  if (
static_cast<float>(dst.w) > sws)
 
  114    dst.w = 
static_cast<int>(sws);
 
  115  if (
static_cast<float>(src.w) > dws)
 
  117    src.x = src.w - 
static_cast<int>(dws);
 
  118    src.w = 
static_cast<int>(dws);
 
  123static int scale(
int w, 
int h)
 
  125  const auto dw = 
static_cast<double>(w);
 
  126  const auto dh = 
static_cast<double>(h);
 
  127  const auto scale = dh / dw;
 
  128  const auto dr = dh * scale;
 
  129  return static_cast<int>(dr);
 
  132SDL_Texture* SdlWidget::render_text_wrapped(SDL_Renderer* renderer, 
const std::string& text,
 
  133                                            SDL_Color fgcolor, SDL_Rect& src, SDL_Rect& dst)
 
  137  TTF_SizeUTF8(_font, 
" ", &w, &h);
 
  139  assert(_text_width <= UINT32_MAX);
 
  140  auto surface = TTF_RenderUTF8_Blended_Wrapped(_font, text.c_str(), fgcolor,
 
  141                                                static_cast<Uint32
>(_text_width));
 
  144    widget_log_error(-1, 
"TTF_RenderText_Blended");
 
  151  auto texture = SDL_CreateTextureFromSurface(renderer, surface);
 
  152  SDL_FreeSurface(surface);
 
  155    widget_log_error(-1, 
"SDL_CreateTextureFromSurface");
 
  166  dst.w -= 2 * hpadding;
 
  167  auto dh = scale(src.w, src.h);
 
  168  dst.h = std::min<int>(dh, dst.h);
 
  173SdlWidget::~SdlWidget()
 
  175  TTF_CloseFont(_font);
 
  177    SDL_DestroyTexture(_image);
 
  180bool SdlWidget::error_ex(Sint32 res, 
const char* what, 
const char* file, 
size_t line,
 
  183  static wLog* log = 
nullptr;
 
  186  return sdl_log_error_ex(res, log, what, file, line, fkt);
 
  189static bool draw_rect(SDL_Renderer* renderer, 
const SDL_Rect* rect, SDL_Color color)
 
  191  const int drc = SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, color.a);
 
  192  if (widget_log_error(drc, 
"SDL_SetRenderDrawColor"))
 
  195  const int rc = SDL_RenderFillRect(renderer, rect);
 
  196  return !widget_log_error(rc, 
"SDL_RenderFillRect");
 
  199bool SdlWidget::fill(SDL_Renderer* renderer, SDL_Color color)
 
  201  std::vector<SDL_Color> colors = { color };
 
  202  return fill(renderer, colors);
 
  205bool SdlWidget::fill(SDL_Renderer* renderer, 
const std::vector<SDL_Color>& colors)
 
  208  SDL_BlendMode mode = SDL_BLENDMODE_INVALID;
 
  209  SDL_GetRenderDrawBlendMode(renderer, &mode);
 
  210  SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE);
 
  211  for (
auto color : colors)
 
  213    draw_rect(renderer, &_rect, color);
 
  214    SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_ADD);
 
  216  SDL_SetRenderDrawBlendMode(renderer, mode);
 
  220bool SdlWidget::update_text(SDL_Renderer* renderer, 
const std::string& text, SDL_Color fgcolor,
 
  225  if (!fill(renderer, bgcolor))
 
  227  return update_text(renderer, text, fgcolor);
 
  230bool SdlWidget::wrap()
 const 
  235bool SdlWidget::set_wrap(
bool wrap, 
size_t width)
 
  242const SDL_Rect& SdlWidget::rect()
 const 
  247bool SdlWidget::update_text(SDL_Renderer* renderer, 
const std::string& text, SDL_Color fgcolor)
 
  256  SDL_Texture* texture = 
nullptr;
 
  261    auto rc = SDL_QueryTexture(_image, 
nullptr, 
nullptr, &src.w, &src.h);
 
  263      widget_log_error(rc, 
"SDL_QueryTexture");
 
  266    texture = render_text_wrapped(renderer, text, fgcolor, src, dst);
 
  268    texture = render_text(renderer, text, fgcolor, src, dst);
 
  272  const int rc = SDL_RenderCopy(renderer, texture, &src, &dst);
 
  274    SDL_DestroyTexture(texture);
 
  276    return !widget_log_error(rc, 
"SDL_RenderCopy");
 
  280bool clear_window(SDL_Renderer* renderer)
 
  284  const int drc = SDL_SetRenderDrawColor(renderer, backgroundcolor.r, backgroundcolor.g,
 
  285                                         backgroundcolor.b, backgroundcolor.a);
 
  286  if (widget_log_error(drc, 
"SDL_SetRenderDrawColor"))
 
  289  const int rcls = SDL_RenderClear(renderer);
 
  290  return !widget_log_error(rcls, 
"SDL_RenderClear");
 
static SDL_RWops * get(const std::string &type, const std::string &id)
 
static std::string typeFonts()