1 /** 2 * Copyright (c) 2006-2016 LOVE Development Team 3 * 4 * This software is provided 'as-is', without any express or implied 5 * warranty. In no event will the authors be held liable for any damages 6 * arising from the use of this software. 7 * 8 * Permission is granted to anyone to use this software for any purpose, 9 * including commercial applications, and to alter it and redistribute it 10 * freely, subject to the following restrictions: 11 * 12 * 1. The origin of this software must not be misrepresented; you must not 13 * claim that you wrote the original software. If you use this software 14 * in a product, an acknowledgment in the product documentation would be 15 * appreciated but is not required. 16 * 2. Altered source versions must be plainly marked as such, and must not be 17 * misrepresented as being the original software. 18 * 3. This notice may not be removed or altered from any source distribution. 19 **/ 20 21 #ifndef LOVE_GRAPHICS_OPENGL_FONT_H 22 #define LOVE_GRAPHICS_OPENGL_FONT_H 23 24 // STD 25 #include <unordered_map> 26 #include <string> 27 #include <vector> 28 29 // LOVE 30 #include "common/config.h" 31 #include "common/Object.h" 32 #include "common/Matrix.h" 33 #include "common/Vector.h" 34 35 #include "font/Rasterizer.h" 36 #include "graphics/Texture.h" 37 #include "graphics/Volatile.h" 38 #include "GLBuffer.h" 39 40 #include "OpenGL.h" 41 42 namespace love 43 { 44 namespace graphics 45 { 46 namespace opengl 47 { 48 49 class Font : public Object, public Volatile 50 { 51 public: 52 53 typedef std::vector<uint32> Codepoints; 54 55 enum AlignMode 56 { 57 ALIGN_LEFT, 58 ALIGN_CENTER, 59 ALIGN_RIGHT, 60 ALIGN_JUSTIFY, 61 ALIGN_MAX_ENUM 62 }; 63 64 struct ColoredString 65 { 66 std::string str; 67 Color color; 68 }; 69 70 struct IndexedColor 71 { 72 Color color; 73 int index; 74 }; 75 76 struct ColoredCodepoints 77 { 78 std::vector<uint32> cps; 79 std::vector<IndexedColor> colors; 80 }; 81 82 struct GlyphVertex 83 { 84 float x, y; 85 uint16 s, t; 86 Color color; 87 }; 88 89 struct TextInfo 90 { 91 int width; 92 int height; 93 }; 94 95 // Used to determine when to change textures in the generated vertex array. 96 struct DrawCommand 97 { 98 GLuint texture; 99 int startvertex; 100 int vertexcount; 101 }; 102 103 Font(love::font::Rasterizer *r, const Texture::Filter &filter = Texture::getDefaultFilter()); 104 105 virtual ~Font(); 106 107 std::vector<DrawCommand> generateVertices(const ColoredCodepoints &codepoints, std::vector<GlyphVertex> &vertices, float extra_spacing = 0.0f, Vector offset = {}, TextInfo *info = nullptr); 108 std::vector<DrawCommand> generateVertices(const std::string &text, std::vector<GlyphVertex> &vertices, float extra_spacing = 0.0f, Vector offset = Vector(), TextInfo *info = nullptr); 109 110 std::vector<DrawCommand> generateVerticesFormatted(const ColoredCodepoints &text, float wrap, AlignMode align, std::vector<GlyphVertex> &vertices, TextInfo *info = nullptr); 111 112 void drawVertices(const std::vector<DrawCommand> &drawcommands, bool bufferedvertices); 113 114 static void getCodepointsFromString(const std::string &str, Codepoints &codepoints); 115 static void getCodepointsFromString(const std::vector<ColoredString> &strs, ColoredCodepoints &codepoints); 116 117 /** 118 * Prints the text at the designated position with rotation and scaling. 119 * 120 * @param text A string. 121 * @param x The x-coordinate. 122 * @param y The y-coordinate. 123 * @param angle The amount of rotation. 124 * @param sx Scale along the x axis. 125 * @param sy Scale along the y axis. 126 * @param ox The origin offset along the x-axis. 127 * @param oy The origin offset along the y-axis. 128 * @param kx Shear along the x axis. 129 * @param ky Shear along the y axis. 130 **/ 131 void print(const std::vector<ColoredString> &text, float x, float y, float angle = 0.0f, float sx = 1.0f, float sy = 1.0f, float ox = 0.0f, float oy = 0.0f, float kx = 0.0f, float ky = 0.0f); 132 133 void printf(const std::vector<ColoredString> &text, float x, float y, float wrap, AlignMode align, float angle = 0.0f, float sx = 1.0f, float sy = 1.0f, float ox = 0.0f, float oy = 0.0f, float kx = 0.0f, float ky = 0.0f); 134 135 /** 136 * Returns the height of the font. 137 **/ 138 float getHeight() const; 139 140 /** 141 * Returns the width of the passed string. 142 * 143 * @param str A string of text. 144 **/ 145 int getWidth(const std::string &str); 146 147 /** 148 * Returns the width of the passed character. 149 * 150 * @param character A character. 151 **/ 152 int getWidth(char character); 153 154 /** 155 * Returns the maximal width of a wrapped string 156 * and optionally the number of lines 157 * 158 * @param text The input text 159 * @param wraplimit The number of pixels to wrap at 160 * @param max_width Optional output of the maximum width 161 * Returns a vector with the lines. 162 **/ 163 void getWrap(const std::vector<ColoredString> &text, float wraplimit, std::vector<std::string> &lines, std::vector<int> *line_widths = nullptr); 164 void getWrap(const ColoredCodepoints &codepoints, float wraplimit, std::vector<ColoredCodepoints> &lines, std::vector<int> *line_widths = nullptr); 165 166 /** 167 * Sets the line height (which should be a number to multiply the font size by, 168 * example: line height = 1.2 and size = 12 means that rendered line height = 12*1.2) 169 * @param height The new line height. 170 **/ 171 void setLineHeight(float height); 172 173 /** 174 * Returns the line height. 175 **/ 176 float getLineHeight() const; 177 178 void setFilter(const Texture::Filter &f); 179 const Texture::Filter &getFilter(); 180 181 // Implements Volatile. 182 bool loadVolatile(); 183 void unloadVolatile(); 184 185 // Extra font metrics 186 int getAscent() const; 187 int getDescent() const; 188 float getBaseline() const; 189 190 bool hasGlyph(uint32 glyph) const; 191 bool hasGlyphs(const std::string &text) const; 192 193 void setFallbacks(const std::vector<Font *> &fallbacks); 194 195 uint32 getTextureCacheID() const; 196 197 static bool getConstant(const char *in, AlignMode &out); 198 static bool getConstant(AlignMode in, const char *&out); 199 200 static int fontCount; 201 202 private: 203 204 enum FontType 205 { 206 FONT_TRUETYPE, 207 FONT_IMAGE, 208 FONT_UNKNOWN 209 }; 210 211 struct Glyph 212 { 213 GLuint texture; 214 int spacing; 215 GlyphVertex vertices[4]; 216 }; 217 218 struct TextureSize 219 { 220 int width; 221 int height; 222 }; 223 224 TextureSize getNextTextureSize() const; 225 GLenum getTextureFormat(FontType fontType, GLenum *internalformat = nullptr) const; 226 void createTexture(); 227 love::font::GlyphData *getRasterizerGlyphData(uint32 glyph); 228 const Glyph &addGlyph(uint32 glyph); 229 const Glyph &findGlyph(uint32 glyph); 230 float getKerning(uint32 leftglyph, uint32 rightglyph); 231 void printv(const Matrix4 &t, const std::vector<DrawCommand> &drawcommands, const std::vector<GlyphVertex> &vertices); 232 233 std::vector<StrongRef<love::font::Rasterizer>> rasterizers; 234 235 int height; 236 float lineHeight; 237 238 int textureWidth; 239 int textureHeight; 240 241 // vector of packed textures 242 std::vector<GLuint> textures; 243 244 // maps glyphs to glyph texture information 245 std::unordered_map<uint32, Glyph> glyphs; 246 247 // map of left/right glyph pairs to horizontal kerning. 248 std::unordered_map<uint64, float> kerning; 249 250 FontType type; 251 Texture::Filter filter; 252 253 int textureX, textureY; 254 int rowHeight; 255 256 bool useSpacesAsTab; 257 258 // Index buffer used for drawing quads with GL_TRIANGLES. 259 QuadIndices quadIndices; 260 261 // ID which is incremented when the texture cache is invalidated. 262 uint32 textureCacheID; 263 264 size_t textureMemorySize; 265 266 static const int TEXTURE_PADDING = 1; 267 268 // This will be used if the Rasterizer doesn't have a tab character itself. 269 static const int SPACES_PER_TAB = 4; 270 271 static StringMap<AlignMode, ALIGN_MAX_ENUM>::Entry alignModeEntries[]; 272 static StringMap<AlignMode, ALIGN_MAX_ENUM> alignModes; 273 274 }; // Font 275 276 } // opengl 277 } // graphics 278 } // love 279 280 #endif // LOVE_GRAPHICS_OPENGL_FONT_H 281