2020-08-26 15:38:01 +08:00
|
|
|
#pragma once
|
2021-05-10 08:23:02 +08:00
|
|
|
#include <blah/common.h>
|
2020-08-26 15:38:01 +08:00
|
|
|
#include <blah/containers/str.h>
|
2020-10-25 06:21:36 +08:00
|
|
|
#include <blah/containers/vector.h>
|
2021-03-23 07:53:27 +08:00
|
|
|
#include <blah/graphics/subtexture.h>
|
2021-12-13 12:41:23 +08:00
|
|
|
#include <blah/numerics/spatial.h>
|
2021-05-10 08:23:02 +08:00
|
|
|
#include <blah/filesystem.h>
|
2020-10-19 15:50:16 +08:00
|
|
|
#include <unordered_map>
|
2020-08-26 15:38:01 +08:00
|
|
|
|
|
|
|
namespace Blah
|
|
|
|
{
|
|
|
|
class Font;
|
|
|
|
|
2021-03-21 17:08:28 +08:00
|
|
|
// Sprite Font is a bitmap font implementation for font rendering.
|
|
|
|
// It can be constructed from a Font (ttf) and will automatically create
|
|
|
|
// texture atlases for rendering. You can add your own characters
|
|
|
|
// and textures to it.
|
|
|
|
class SpriteFont
|
2021-03-21 14:24:18 +08:00
|
|
|
{
|
2021-03-21 17:08:28 +08:00
|
|
|
public:
|
|
|
|
|
|
|
|
// Spritefont uses u32 codepoints
|
|
|
|
using Codepoint = u32;
|
2021-03-21 14:24:18 +08:00
|
|
|
|
2021-03-21 17:08:28 +08:00
|
|
|
// CharSet is a Vector of Character Ranges
|
|
|
|
struct CharRange;
|
|
|
|
using CharSet = Vector<CharRange>;
|
2021-03-21 14:24:18 +08:00
|
|
|
|
2021-03-21 17:08:28 +08:00
|
|
|
// Character range, used for building the Sprite Font
|
|
|
|
struct CharRange
|
|
|
|
{
|
|
|
|
Codepoint from;
|
|
|
|
Codepoint to;
|
2021-03-21 14:24:18 +08:00
|
|
|
|
2021-03-21 17:08:28 +08:00
|
|
|
CharRange();
|
|
|
|
CharRange(Codepoint single);
|
|
|
|
CharRange(Codepoint from, Codepoint to);
|
|
|
|
|
|
|
|
static const CharSet ASCII;
|
|
|
|
};
|
|
|
|
|
|
|
|
// Character Entry
|
2020-08-26 15:38:01 +08:00
|
|
|
struct Character
|
|
|
|
{
|
|
|
|
Subtexture subtexture;
|
|
|
|
float advance = 0;
|
2021-12-13 12:41:23 +08:00
|
|
|
Vec2f offset;
|
2020-08-26 15:38:01 +08:00
|
|
|
};
|
|
|
|
|
2021-03-21 17:08:28 +08:00
|
|
|
// SpriteFont name
|
2020-09-21 15:36:19 +08:00
|
|
|
String name;
|
2021-03-21 17:08:28 +08:00
|
|
|
|
|
|
|
// Height, in pixels
|
2020-09-21 15:36:19 +08:00
|
|
|
float size;
|
2021-03-21 17:08:28 +08:00
|
|
|
|
|
|
|
// Ascent, in pixels
|
2020-09-21 15:36:19 +08:00
|
|
|
float ascent;
|
2021-03-21 17:08:28 +08:00
|
|
|
|
|
|
|
// Descent, in pixels
|
2020-09-21 15:36:19 +08:00
|
|
|
float descent;
|
2021-03-21 17:08:28 +08:00
|
|
|
|
|
|
|
// Line Gap, in pixels
|
2020-09-21 15:36:19 +08:00
|
|
|
float line_gap;
|
|
|
|
|
2020-08-26 15:38:01 +08:00
|
|
|
SpriteFont();
|
2021-03-21 17:08:28 +08:00
|
|
|
SpriteFont(const FilePath& file, float size);
|
|
|
|
SpriteFont(const FilePath& file, float size, const CharSet& charset);
|
2020-08-26 15:38:01 +08:00
|
|
|
SpriteFont(const Font& font, float size);
|
2021-03-21 17:08:28 +08:00
|
|
|
SpriteFont(const Font& font, float size, const CharSet& charset);
|
2020-08-26 15:38:01 +08:00
|
|
|
SpriteFont(const SpriteFont&) = delete;
|
2021-03-21 17:08:28 +08:00
|
|
|
SpriteFont& operator=(const SpriteFont&) = delete;
|
2020-08-26 15:38:01 +08:00
|
|
|
SpriteFont(SpriteFont&& src) noexcept;
|
2021-03-21 17:08:28 +08:00
|
|
|
SpriteFont& operator=(SpriteFont&& src) noexcept;
|
2020-08-26 15:38:01 +08:00
|
|
|
~SpriteFont();
|
|
|
|
|
2021-03-21 17:08:28 +08:00
|
|
|
// releases all assets used by the spritefont
|
2020-08-26 15:38:01 +08:00
|
|
|
void dispose();
|
|
|
|
|
2021-03-21 17:08:28 +08:00
|
|
|
// gets the height of the sprite font
|
2020-09-21 15:36:19 +08:00
|
|
|
float height() const { return ascent - descent; }
|
2021-03-21 17:08:28 +08:00
|
|
|
|
|
|
|
// gets the line height of the sprite font (height + line gap)
|
2020-09-21 15:36:19 +08:00
|
|
|
float line_height() const { return ascent - descent + line_gap; }
|
2020-08-26 15:38:01 +08:00
|
|
|
|
2021-03-21 17:08:28 +08:00
|
|
|
// returns a list of all texture atlases
|
2020-10-25 06:21:36 +08:00
|
|
|
const Vector<TextureRef>& textures() { return m_atlas; }
|
2020-08-26 15:38:01 +08:00
|
|
|
|
2021-03-21 17:08:28 +08:00
|
|
|
// calculates the width of the given string
|
2020-08-26 15:38:01 +08:00
|
|
|
float width_of(const String& text) const;
|
2021-03-21 17:08:28 +08:00
|
|
|
|
|
|
|
// calculates the width of the next line
|
2020-08-26 15:38:01 +08:00
|
|
|
float width_of_line(const String& text, int start = 0) const;
|
2021-03-21 17:08:28 +08:00
|
|
|
|
|
|
|
// calculates the height of the given string
|
2020-08-26 15:38:01 +08:00
|
|
|
float height_of(const String& text) const;
|
|
|
|
|
2021-03-21 17:08:28 +08:00
|
|
|
// disposes the existing spritefont data and rebuilds from the given font file
|
|
|
|
void rebuild(const FilePath& file, float size, const CharSet& charset);
|
|
|
|
|
|
|
|
// disposes the existing spritefont data and rebuilds from the given font
|
|
|
|
void rebuild(const Font& font, float size, const CharSet& charset);
|
|
|
|
|
|
|
|
// gets the kerning between two characters
|
|
|
|
float get_kerning(Codepoint codepoint0, Codepoint codepoint1) const;
|
2020-08-26 15:38:01 +08:00
|
|
|
|
2021-03-21 17:08:28 +08:00
|
|
|
// sets the kerning between two characters
|
|
|
|
void set_kerning(Codepoint codepoint0, Codepoint codepoint1, float kerning);
|
2020-08-26 15:38:01 +08:00
|
|
|
|
2021-03-21 17:08:28 +08:00
|
|
|
// gets the character at the given codepoint
|
|
|
|
Character& get_character(Codepoint codepoint);
|
|
|
|
|
|
|
|
// gets the character at the given codepoint
|
|
|
|
const Character& get_character(Codepoint codepoint) const;
|
|
|
|
|
|
|
|
// gets the character at the given codepoint
|
|
|
|
Character& operator[](Codepoint codepoint);
|
|
|
|
|
|
|
|
// gets the character at the given codepoint
|
|
|
|
const Character& operator[](Codepoint codepoint) const;
|
|
|
|
|
|
|
|
private:
|
|
|
|
// character set
|
|
|
|
std::unordered_map<Codepoint, Character> m_characters;
|
|
|
|
|
|
|
|
// kerning
|
|
|
|
// key is 2 codepoints combined ((first << 32) | second)
|
|
|
|
std::unordered_map<u64, float> m_kerning;
|
|
|
|
|
|
|
|
// built texture
|
|
|
|
Vector<TextureRef> m_atlas;
|
2020-08-26 15:38:01 +08:00
|
|
|
};
|
|
|
|
}
|