/* +-------------------------------------------------------+ ____/ \____ /| Open source game framework licensed to freely use, | \ / / | copy, and modify, created for dank.game | +--\ ^__^ /--+ | | | ~/ \~ | | Download at https://open.shampoo.ooo/shampoo/spacebox | | ~~~~~~~~~~~~ | +-------------------------------------------------------+ | SPACE ~~~~~ | / | ~~~~~~~ BOX |/ +-------------*/ #include #include #include "SDL.h" #include "SDL_ttf.h" #include "sdl2-gfx/SDL2_rotozoom.h" #include "Model.hpp" #include "Color.hpp" #include "Log.hpp" #include "Texture.hpp" namespace sb { class Text : public sb::Plane { private: inline static const sb::Color DEFAULT_FG {0.0f, 0.0f, 0.0f, 255.0f}; inline static const sb::Color DEFAULT_BG {0.0f, 0.0f, 0.0f, 0.0f}; std::string _content; sb::Color _foreground, _background; std::shared_ptr _font; std::optional _dimensions; GLint _scaling_quality = GL_LINEAR; std::optional _wrap; public: /*! * Construct a sb::Text object from a font, string, and background and foreground colors. A texture will be created and attached * at texture index 0. The texture is not generated or rendered. Text::refresh() must be called afterward with the GL context * loaded to render the text to the constructed texture. * * The font must be wrapped in a shared pointer. A default loaded font is available from Game::font(). * * Dimensions can be given in pixels, in which case the text will be rendered at the center of a texture in exactly the given * dimensions, regardless of the length of the text. If the given dimensions are larger than the text, the resulting texture will * have padding around the text. This can be useful, for example, for creating identically sized text buttons. * * @param font a TTF_Font object wrapped in a shared pointer * @param content text content * @param foreground text color * @param background background color * @param dimensions force the texture to be a certain size in pixels, extra area is filled with the background color */ Text(std::shared_ptr font, const std::string& content = "", const sb::Color& foreground = DEFAULT_FG, const sb::Color& background = DEFAULT_BG, std::optional dimensions = std::nullopt) : _content(content), _foreground(foreground), _background(background), _font(font), _dimensions(dimensions) { /* Add an empty Texture object */ texture(sb::Texture()); } /*! * Bind textures attached to this model. */ void bind_textures() const; /*! * @param content Text to be rendered */ void content(const std::string& content); /*! * @param content Single character to be rendered */ void content(char content); /*! * @return Text to be rendered */ const std::string& content() const; /*! * @param foreground Text color */ void foreground(const sb::Color& foreground); /*! * @param background Text background color */ void background(const sb::Color& background); /*! * @param font Shared pointer to a TTF_Font to use for rendering text */ void font(std::shared_ptr font); /*! * @param dimensions Force the generated texture to be a certain size in pixels. Extra area is filled with the background color. */ void dimensions(const glm::vec2& dimensions); /*! * This GL parameter will be passed to `glTexParameter` for `GL_TEXTURE_MIN_FILTER` and `GL_TEXTURE_MAG_FILTER`. * * @param quality Quality of texture scaling passed to `glTexParameter` */ void scaling_quality(GLint quality); /*! * By default, there is no wrapping on the text added to this object. If this is set, however, the text will be rendered to a * texture that is limited to the given pixel width. Any text that would exceed that width is moved to a new line in the * rendering. * * @param wrap Pixel width where the text will wrap when rendered to a texture */ void wrap(int width); /*! * Generate and load the texture at index 0. Render text to it using SDL_Surface pixels created by the SDL TTF library. * * The text must be set to a non-zero length string using Text::content(const std::string&) or it will fail to render with an * error logged. */ void refresh(); /*! * Convert the text object to a string with some debugging information. */ operator std::string() const; /*! * Overload the stream operator to support text objects. Add a string representation of the text object to the output stream. Since * this is defined as a friend function and isn't in the global scope, it should prevent it being looked up with arguments other * than text objects. * * @param out output stream * @param text text object to print * @return edited output stream */ friend std::ostream& operator<<(std::ostream& out, const Text& text); }; } #include "Game.hpp"