Add a function for reading a sprite's translation. Add functions for reading a text object's foreground, background, and font. Log a warning when the draw function of a sprite containing textures is called but the currently active texture will not be drawn because it has not been generated yet. Line-length linting.
197 lines
7.4 KiB
C++
197 lines
7.4 KiB
C++
/* +=======================================================+
|
|
____/ \____ /: 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 <optional>
|
|
#include <stdexcept>
|
|
|
|
#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<TTF_Font> _font;
|
|
std::optional<glm::ivec2> _dimensions;
|
|
GLint _scaling_quality = GL_LINEAR;
|
|
std::optional<int> _wrap;
|
|
glm::vec2 _offset = {0.0f, 0.0f};
|
|
|
|
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<TTF_Font> font, const std::string& content = "", const sb::Color& foreground = DEFAULT_FG,
|
|
const sb::Color& background = DEFAULT_BG, std::optional<glm::ivec2> 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 character Single 8-bit character to be rendered
|
|
*/
|
|
void content(char character);
|
|
|
|
/*!
|
|
* @return Text to be rendered
|
|
*/
|
|
const std::string& content() const;
|
|
|
|
/*!
|
|
* @param foreground Text color
|
|
*/
|
|
void foreground(const sb::Color& foreground);
|
|
|
|
/*!
|
|
* @return Foreground color of text
|
|
*/
|
|
const sb::Color& foreground() const;
|
|
|
|
/*!
|
|
* @param background Text background color
|
|
*/
|
|
void background(const sb::Color& background);
|
|
|
|
/*!
|
|
* @param Background color of text
|
|
*/
|
|
const sb::Color& background() const;
|
|
|
|
/*!
|
|
* @param font Shared pointer to a TTF_Font to use for rendering text
|
|
*/
|
|
void font(std::shared_ptr<TTF_Font> font);
|
|
|
|
/*!
|
|
* @return Shared pointer to a TTF_Font to use for rendering text
|
|
*/
|
|
const std::shared_ptr<TTF_Font> font() const;
|
|
|
|
/*!
|
|
* @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::ivec2& dimensions);
|
|
|
|
/*!
|
|
* Get the width and height in pixels of the rendered text without rendering it. If dimensions have been set to
|
|
* a specific value, this returns the specified dimensions.
|
|
*
|
|
* If the content string is empty, the width will be 0, but the height will be the height of the font.
|
|
*
|
|
* If there is an error in the SDL call, an error message will be logged and the return value will be {0, 0}.
|
|
*
|
|
* @warning Even if wrapping is set, this returns the dimensions of the text without wrapping. This will be able
|
|
* to be fixed after upgrading to SDL3.
|
|
*
|
|
* @return A 2D vector containing the width and height without wrapping
|
|
*/
|
|
glm::ivec2 dimensions() const;
|
|
|
|
/*!
|
|
* 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.
|
|
*
|
|
* If the width is 0, the text will wrap at every newline character.
|
|
*
|
|
* @param wrap Pixel width where the text will wrap when rendered to a texture
|
|
*/
|
|
void wrap(int width);
|
|
|
|
/*!
|
|
* Set the offset of the text within the container. This can be useful if the text centering appears off, for
|
|
* example because of letters that draw below the baseline.
|
|
*
|
|
* This will not regenerate the texture. Call sb::Text::refresh() afterward for that.
|
|
*
|
|
* @param amount Amount in pixels to offset the text within the container
|
|
*/
|
|
void offset(const glm::vec2& amount);
|
|
|
|
/*!
|
|
* 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"
|