#include #include "font.hh" #include "TextWidget.hh" TextWidget::TextWidget(Font& font, std::string text, int width, int height) : Widget(width, height), text_(std::move(text)), font_(font), textSurf_(nullptr) { layout(); } TextWidget::~TextWidget() { } void TextWidget::setText(std::string text) { if (text != text_) { text_ = std::move(text); invalidateGL(); layout(); } } void TextWidget::setForegroundColor(SDL_Color fg) { Widget::setForegroundColor(fg); // Trigger text rerender layout(); } void TextWidget::layout() { // Determine text size int width, height; if(TTF_SizeUTF8(font_.getFont(), text_.c_str(), &width, &height) != 0) throw TTFException{}; if ((width > (width_ - padLeft_ - padRight_)) && (width_ != WRAP_CONTENT)) { textSurf_.reset(TTF_RenderUTF8_Blended_Wrapped(font_.getFont(), text_.c_str(), fg_, width_- padLeft_ - padRight_)); if (!textSurf_) throw TTFException{}; if (height_ == WRAP_CONTENT) // TODO: Get proper tight bounding box for multiline text if (realHeight_ != (textSurf_->h - // TTF_FontLineSkip(font_.getFont()) + padTop_ + padBottom_)) { realHeight_ = textSurf_->h - // TTF_FontLineSkip(font_.getFont()) + padTop_ + padBottom_; invalidateGL(); } } else { textSurf_.reset(TTF_RenderUTF8_Blended(font_.getFont(), text_.c_str(), fg_)); if (!textSurf_) throw TTFException{}; if (width_ == WRAP_CONTENT) if (realWidth_ != (textSurf_->w + padLeft_ + padRight_)) { realWidth_ = textSurf_->w + padLeft_ + padRight_; invalidateGL(); } if (height_ == WRAP_CONTENT) if (realHeight_ != (textSurf_->h + padTop_ + padBottom_)) { realHeight_ = textSurf_->h + padTop_ + padBottom_; invalidateGL(); } } } void TextWidget::render(SDL_Surface *dst, SDL_Rect *dstRect) const { Widget::render(dst, dstRect); SDL_Rect rect = calcContentRect(dst, dstRect, textSurf_->clip_rect); if (SDL_BlitSurface(textSurf_.get(), nullptr, dst, &rect) != 0) throw SDLException{}; }