diff --git a/src/Text/AbstractFont.cpp b/src/Text/AbstractFont.cpp new file mode 100644 index 000000000..5daef1fa2 --- /dev/null +++ b/src/Text/AbstractFont.cpp @@ -0,0 +1,26 @@ +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License version 3 for more details. +*/ + +#include "Text/AbstractFont.h" + +namespace Magnum { namespace Text { + +AbstractFont::AbstractFont() {} +AbstractFont::~AbstractFont() {} + +AbstractLayouter::AbstractLayouter(): _glyphCount(0) {} +AbstractLayouter::~AbstractLayouter() {} + +}} diff --git a/src/Text/AbstractFont.h b/src/Text/AbstractFont.h new file mode 100644 index 000000000..561133bcc --- /dev/null +++ b/src/Text/AbstractFont.h @@ -0,0 +1,103 @@ +#ifndef Magnum_Text_AbstractFont_h +#define Magnum_Text_AbstractFont_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License version 3 for more details. +*/ + +/** @file + * @brief Class Magnum::Text::AbstractFont, Magnum::Text::AbstractLayouter + */ + +#include +#include + +#include "Magnum.h" +#include "Texture.h" +#include "Text/Text.h" +#include "Text/magnumTextVisibility.h" + +namespace Magnum { namespace Text { + +/** +@brief Base for fonts +*/ +class MAGNUM_TEXT_EXPORT AbstractFont { + AbstractFont(const AbstractFont&) = delete; + AbstractFont(AbstractFont&&) = delete; + AbstractFont& operator=(const AbstractFont&) = delete; + AbstractFont& operator=(const AbstractFont&&) = delete; + + public: + AbstractFont(); + virtual ~AbstractFont() = 0; + + /** @brief %Font texture atlas */ + inline Texture2D& texture() { return _texture; } + + /** + * @brief Layout the text using fon't own layouter + * @param size %Font size + * @param text Text to layout + */ + virtual AbstractLayouter* layout(const Float size, const std::string& text) = 0; + + #ifdef DOXYGEN_GENERATING_OUTPUT + private: + #else + protected: + #endif + Texture2D _texture; +}; + +/** +@brief Base for text layouters + +Returned by AbstractFont::layout(). +*/ +class MAGNUM_TEXT_EXPORT AbstractLayouter { + AbstractLayouter(const AbstractLayouter&) = delete; + AbstractLayouter(AbstractLayouter&&) = delete; + AbstractLayouter& operator=(const AbstractLayouter&) = delete; + AbstractLayouter& operator=(const AbstractLayouter&&) = delete; + + public: + AbstractLayouter(); + virtual ~AbstractLayouter() = 0; + + /** @brief Count of glyphs in laid out text */ + inline UnsignedInt glyphCount() const { + return _glyphCount; + } + + /** + * @brief Render glyph + * @param i Glyph index + * @param cursorPosition Cursor position + * + * Returns quad position, texture coordinates and advance to next + * glyph. + */ + virtual std::tuple renderGlyph(const Vector2& cursorPosition, const UnsignedInt i) = 0; + + #ifdef DOXYGEN_GENERATING_OUTPUT + private: + #else + protected: + #endif + UnsignedInt _glyphCount; +}; + +}} + +#endif diff --git a/src/Text/CMakeLists.txt b/src/Text/CMakeLists.txt index 42d2586d7..dd747e59e 100644 --- a/src/Text/CMakeLists.txt +++ b/src/Text/CMakeLists.txt @@ -7,10 +7,12 @@ if(USE_HARFBUZZ) endif() set(MagnumText_SRCS - Font.cpp + AbstractFont.cpp + FreeTypeFont.cpp TextRenderer.cpp) set(MagnumText_HEADERS - Font.h + AbstractFont.h + FreeTypeFont.h Text.h TextRenderer.h diff --git a/src/Text/Font.cpp b/src/Text/FreeTypeFont.cpp similarity index 80% rename from src/Text/Font.cpp rename to src/Text/FreeTypeFont.cpp index f95802d6b..9444f3bce 100644 --- a/src/Text/Font.cpp +++ b/src/Text/FreeTypeFont.cpp @@ -13,7 +13,7 @@ GNU Lesser General Public License version 3 for more details. */ -#include "Font.h" +#include "FreeTypeFont.h" #include #include @@ -30,27 +30,52 @@ namespace Magnum { namespace Text { -FontRenderer::FontRenderer() { +namespace { + +class FreeTypeLayouter: public AbstractLayouter { + public: + FreeTypeLayouter(FreeTypeFont& font, const Float size, const std::string& text); + ~FreeTypeLayouter(); + + std::tuple renderGlyph(const Vector2& cursorPosition, const UnsignedInt i) override; + + private: + #ifdef MAGNUM_USE_HARFBUZZ + const FreeTypeFont& font; + hb_buffer_t* buffer; + hb_glyph_info_t* glyphInfo; + hb_glyph_position_t* glyphPositions; + #else + FreeTypeFont& font; + std::vector glyphs; + #endif + + const Float size; +}; + +} + +FreeTypeFontRenderer::FreeTypeFontRenderer() { CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Init_FreeType(&_library) == 0); } -FontRenderer::~FontRenderer() { +FreeTypeFontRenderer::~FreeTypeFontRenderer() { FT_Done_FreeType(_library); } -Font::Font(FontRenderer& renderer, const std::string& fontFile, Float size): _size(size) { +FreeTypeFont::FreeTypeFont(FreeTypeFontRenderer& renderer, const std::string& fontFile, Float size): _size(size) { CORRADE_INTERNAL_ASSERT_OUTPUT(FT_New_Face(renderer.library(), fontFile.c_str(), 0, &_ftFont) == 0); finishConstruction(); } -Font::Font(FontRenderer& renderer, const unsigned char* data, std::size_t dataSize, Float size): _size(size) { +FreeTypeFont::FreeTypeFont(FreeTypeFontRenderer& renderer, const unsigned char* data, std::size_t dataSize, Float size): _size(size) { CORRADE_INTERNAL_ASSERT_OUTPUT(FT_New_Memory_Face(renderer.library(), data, dataSize, 0, &_ftFont) == 0); finishConstruction(); } -void Font::finishConstruction() { +void FreeTypeFont::finishConstruction() { CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Set_Char_Size(_ftFont, 0, _size*64, 100, 100) == 0); #ifdef MAGNUM_USE_HARFBUZZ @@ -70,7 +95,7 @@ void Font::finishConstruction() { ->setMagnificationFilter(Texture2D::Filter::Linear); } -void Font::prerenderInternal(const std::string& characters, const Vector2i& atlasSize, const Int radius, Texture2D* output) { +void FreeTypeFont::prerenderInternal(const std::string& characters, const Vector2i& atlasSize, const Int radius, Texture2D* output) { glyphs.clear(); /** @bug Crash when atlas is too small */ @@ -137,11 +162,11 @@ void Font::prerenderInternal(const std::string& characters, const Vector2i& atla #endif } -void Font::prerender(const std::string& characters, const Vector2i& atlasSize) { +void FreeTypeFont::prerender(const std::string& characters, const Vector2i& atlasSize) { prerenderInternal(characters, atlasSize, 0, &_texture); } -void Font::prerenderDistanceField(const std::string& characters, const Vector2i& sourceAtlasSize, const Vector2i& atlasSize, Int radius) { +void FreeTypeFont::prerenderDistanceField(const std::string& characters, const Vector2i& sourceAtlasSize, const Vector2i& atlasSize, Int radius) { MAGNUM_ASSERT_EXTENSION_SUPPORTED(Extensions::GL::ARB::texture_storage); /* Render input texture */ @@ -156,48 +181,14 @@ void Font::prerenderDistanceField(const std::string& characters, const Vector2i& TextureTools::distanceField(&input, &_texture, Rectanglei::fromSize({}, atlasSize), radius); } -void Font::destroy() { - if(!_ftFont) return; - +FreeTypeFont::~FreeTypeFont() { #ifdef MAGNUM_USE_HARFBUZZ hb_font_destroy(_hbFont); #endif FT_Done_Face(_ftFont); } -void Font::move() { - #ifdef MAGNUM_USE_HARFBUZZ - _hbFont = nullptr; - #endif - _ftFont = nullptr; -} - -Font::~Font() { destroy(); } - -Font::Font(Font&& other): glyphs(std::move(other.glyphs)), _texture(std::move(other._texture)), _ftFont(other._ftFont), _size(other._size) - #ifdef MAGNUM_USE_HARFBUZZ - , _hbFont(other._hbFont) - #endif -{ - other.move(); -} - -Font& Font::operator=(Font&& other) { - destroy(); - - glyphs = std::move(other.glyphs); - _texture = std::move(other._texture); - _ftFont = other._ftFont; - #ifdef MAGNUM_USE_HARFBUZZ - _hbFont = other._hbFont; - #endif - _size = other._size; - - other.move(); - return *this; -} - -const std::tuple& Font::operator[](char32_t character) const { +const std::tuple& FreeTypeFont::operator[](char32_t character) const { auto it = glyphs.find(character); if(it == glyphs.end()) @@ -205,7 +196,13 @@ const std::tuple& Font::operator[](char32_t character) con return it->second; } -TextLayouter::TextLayouter(Font& font, const Float size, const std::string& text): font(font), size(size) { +AbstractLayouter* FreeTypeFont::layout(const Float size, const std::string& text) { + return new FreeTypeLayouter(*this, size, text); +} + +namespace { + +FreeTypeLayouter::FreeTypeLayouter(FreeTypeFont& font, const Float size, const std::string& text): font(font), size(size) { #ifdef MAGNUM_USE_HARFBUZZ /* Prepare HarfBuzz buffer */ buffer = hb_buffer_create(); @@ -222,6 +219,7 @@ TextLayouter::TextLayouter(Font& font, const Float size, const std::string& text #else /* Get glyph codes from characters */ glyphs.reserve(text.size()+1); + _glyphCount = text.size(); for(std::size_t i = 0; i != text.size(); ) { UnsignedInt codepoint; std::tie(codepoint, i) = Corrade::Utility::Unicode::nextChar(text, i); @@ -230,14 +228,14 @@ TextLayouter::TextLayouter(Font& font, const Float size, const std::string& text #endif } -TextLayouter::~TextLayouter() { +FreeTypeLayouter::~FreeTypeLayouter() { #ifdef MAGNUM_USE_HARFBUZZ /* Destroy HarfBuzz buffer */ hb_buffer_destroy(buffer); #endif } -std::tuple TextLayouter::renderGlyph(const Vector2& cursorPosition, const UnsignedInt i) { +std::tuple FreeTypeLayouter::renderGlyph(const Vector2& cursorPosition, const UnsignedInt i) { /* Position of the texture in the resulting glyph, texture coordinates */ Rectangle texturePosition, textureCoordinates; #ifdef MAGNUM_USE_HARFBUZZ @@ -269,4 +267,6 @@ std::tuple TextLayouter::renderGlyph(const Vector return std::make_tuple(quadPosition, textureCoordinates, advance); } +} + }} diff --git a/src/Text/Font.h b/src/Text/FreeTypeFont.h similarity index 63% rename from src/Text/Font.h rename to src/Text/FreeTypeFont.h index e14040c33..62da7c0b9 100644 --- a/src/Text/Font.h +++ b/src/Text/FreeTypeFont.h @@ -1,5 +1,5 @@ -#ifndef Magnum_Text_Font_h -#define Magnum_Text_Font_h +#ifndef Magnum_Text_FreeTypeFont_h +#define Magnum_Text_FreeTypeFont_h /* Copyright © 2010, 2011, 2012 Vladimír Vondruš @@ -16,15 +16,15 @@ */ /** @file - * @brief Class Magnum::Text::FontRenderer, Magnum::Text::Font, Magnum::Text::TextLayouter + * @brief Class Magnum::Text::FreeTypeFontRenderer, Magnum::Text::FreeTypeFont */ #include #include "Math/Geometry/Rectangle.h" #include "Texture.h" - -#include "magnumTextVisibility.h" +#include "Text/AbstractFont.h" +#include "Text/magnumTextVisibility.h" #ifndef DOXYGEN_GENERATING_OUTPUT struct FT_LibraryRec_; @@ -40,16 +40,16 @@ struct hb_glyph_position_t; namespace Magnum { namespace Text { /** -@brief %Font renderer +@brief FreeType font renderer -Contains global instance of font renderer. See Font class documentation for -more information. +Contains global instance of font renderer. See FreeTypeFont class documentation +for more information. */ -class MAGNUM_TEXT_EXPORT FontRenderer { +class MAGNUM_TEXT_EXPORT FreeTypeFontRenderer { public: - explicit FontRenderer(); + explicit FreeTypeFontRenderer(); - ~FontRenderer(); + ~FreeTypeFontRenderer(); /** @brief FreeType library handle */ inline FT_Library library() { return _library; } @@ -59,36 +59,33 @@ class MAGNUM_TEXT_EXPORT FontRenderer { }; /** -@brief %Font +@brief FreeType font Contains font with characters prerendered into texture atlas. -@section Font-usage Usage +@section FreeTypeFont-usage Usage -You need to maintain instance of FontRenderer during the lifetime of all Font +You need to maintain instance of FreeTypeFontRenderer during the lifetime of all FreeTypeFont instances. The font can be created either from file or from memory location of format supported by [FreeType](http://www.freetype.org/) library. Next step is to prerender all the glyphs which will be used in text rendering later. @code -Text::FontRenderer fontRenderer; +Text::FreeTypeFontRenderer fontRenderer; -Text::Font font(fontRenderer, "MyFont.ttf", 48.0f); +Text::FreeTypeFont font(fontRenderer, "MyFreeTypeFont.ttf", 48.0f); font.prerender("abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789 ", Vector2i(512)); @endcode See TextRenderer for information about text rendering. -@section Font-extensions Required OpenGL functionality +@section FreeTypeFont-extensions Required OpenGL functionality %Font texture uses one-component internal format, which requires @extension{ARB,texture_rg} (also part of OpenGL ES 3.0 or available as @es_extension{EXT,texture_rg} in ES 2.0). */ -class MAGNUM_TEXT_EXPORT Font { - Font(const Font&) = delete; - Font& operator=(const Font&) = delete; - +class MAGNUM_TEXT_EXPORT FreeTypeFont: public AbstractFont { public: /** * @brief Create font from file @@ -96,7 +93,7 @@ class MAGNUM_TEXT_EXPORT Font { * @param fontFile %Font file * @param size %Font size */ - explicit Font(FontRenderer& renderer, const std::string& fontFile, Float size); + explicit FreeTypeFont(FreeTypeFontRenderer& renderer, const std::string& fontFile, Float size); /** * @brief Create font from memory @@ -105,7 +102,7 @@ class MAGNUM_TEXT_EXPORT Font { * @param dataSize %Font data size * @param size %Font size */ - explicit Font(FontRenderer& renderer, const unsigned char* data, std::size_t dataSize, Float size); + explicit FreeTypeFont(FreeTypeFontRenderer& renderer, const unsigned char* data, std::size_t dataSize, Float size); /** * @brief Prerender given character set @@ -134,13 +131,7 @@ class MAGNUM_TEXT_EXPORT Font { */ void prerenderDistanceField(const std::string& characters, const Vector2i& sourceAtlasSize, const Vector2i& atlasSize, Int radius); - ~Font(); - - /** @brief Move constructor */ - Font(Font&& other); - - /** @brief Move assignment */ - Font& operator=(Font&& other); + ~FreeTypeFont(); /** @brief %Font size */ inline Float size() const { return _size; } @@ -157,24 +148,20 @@ class MAGNUM_TEXT_EXPORT Font { */ const std::tuple& operator[](char32_t character) const; - /** @brief %Font texture atlas */ - inline Texture2D& texture() { return _texture; } - - /** @brief Font handle */ + /** @brief %Font handle */ #ifdef MAGNUM_USE_HARFBUZZ inline hb_font_t* font() { return _hbFont; } #else inline FT_Face font() { return _ftFont; } #endif + AbstractLayouter* layout(const Float size, const std::string& text) override; + private: void MAGNUM_TEXT_LOCAL finishConstruction(); - void MAGNUM_TEXT_LOCAL destroy(); - void MAGNUM_TEXT_LOCAL move(); void MAGNUM_TEXT_LOCAL prerenderInternal(const std::string& characters, const Vector2i& atlasSize, const Int radius, Texture2D* output); std::unordered_map> glyphs; - Texture2D _texture; FT_Face _ftFont; Float _size; #ifdef MAGNUM_USE_HARFBUZZ @@ -182,57 +169,6 @@ class MAGNUM_TEXT_EXPORT Font { #endif }; -/** -@brief %Text layouter - -Provides low-level text rendering using Font, used internally in TextRenderer. -*/ -class TextLayouter { - public: - /** - * @brief Constructor - * @param font %Font - * @param size %Font size - * @param text Text to layout - */ - TextLayouter(Font& font, const Float size, const std::string& text); - - ~TextLayouter(); - - /** @brief Count of glyphs in laid out text */ - inline UnsignedInt glyphCount() { - #ifdef MAGNUM_USE_HARFBUZZ - return _glyphCount; - #else - return glyphs.size(); - #endif - } - - /** - * @brief Render glyph - * @param i Glyph index - * @param cursorPosition Cursor position - * - * Returns quad position, texture coordinates and advance to next - * glyph. - */ - std::tuple renderGlyph(const Vector2& cursorPosition, const UnsignedInt i); - - private: - #ifdef MAGNUM_USE_HARFBUZZ - const Font& font; - hb_buffer_t* buffer; - hb_glyph_info_t* glyphInfo; - hb_glyph_position_t* glyphPositions; - UnsignedInt _glyphCount; - #else - Font& font; - std::vector glyphs; - #endif - - const Float size; -}; - }} #endif diff --git a/src/Text/Text.h b/src/Text/Text.h index 03e126beb..d3ba2db87 100644 --- a/src/Text/Text.h +++ b/src/Text/Text.h @@ -23,9 +23,11 @@ namespace Magnum { namespace Text { -class Font; -class FontRenderer; -class TextLayouter; +class AbstractFont; +class AbstractLayouter; + +class FreeTypeFontRenderer; +class FreeTypeFont; class AbstractTextRenderer; template class TextRenderer; diff --git a/src/Text/TextRenderer.cpp b/src/Text/TextRenderer.cpp index 218fa0a77..5de5724f1 100644 --- a/src/Text/TextRenderer.cpp +++ b/src/Text/TextRenderer.cpp @@ -19,7 +19,7 @@ #include "Extensions.h" #include "Mesh.h" #include "Shaders/AbstractVectorShader.h" -#include "Text/Font.h" +#include "Text/AbstractFont.h" namespace Magnum { namespace Text { @@ -51,10 +51,9 @@ struct Vertex { } -std::tuple, std::vector, std::vector, Rectangle> AbstractTextRenderer::render(Font& font, Float size, const std::string& text) { - TextLayouter layouter(font, size, text); - - const UnsignedInt vertexCount = layouter.glyphCount()*4; +std::tuple, std::vector, std::vector, Rectangle> AbstractTextRenderer::render(AbstractFont& font, Float size, const std::string& text) { + AbstractLayouter* const layouter = font.layout(size, text); + const UnsignedInt vertexCount = layouter->glyphCount()*4; /* Output data */ std::vector positions, texcoords; @@ -63,11 +62,11 @@ std::tuple, std::vector, std::vector, /* Render all glyphs */ Vector2 cursorPosition; - for(UnsignedInt i = 0; i != layouter.glyphCount(); ++i) { + for(UnsignedInt i = 0; i != layouter->glyphCount(); ++i) { /* Position of the texture in the resulting glyph, texture coordinates */ Rectangle quadPosition, textureCoordinates; Vector2 advance; - std::tie(quadPosition, textureCoordinates, advance) = layouter.renderGlyph(cursorPosition, i); + std::tie(quadPosition, textureCoordinates, advance) = layouter->renderGlyph(cursorPosition, i); positions.insert(positions.end(), { quadPosition.topLeft(), @@ -87,21 +86,22 @@ std::tuple, std::vector, std::vector, } /* Create indices */ - std::vector indices(layouter.glyphCount()*6); - createIndices(indices.data(), layouter.glyphCount()); + std::vector indices(layouter->glyphCount()*6); + createIndices(indices.data(), layouter->glyphCount()); /* Rendered rectangle */ Rectangle rectangle; - if(layouter.glyphCount()) rectangle = {positions[1], positions[positions.size()-2]}; + if(layouter->glyphCount()) rectangle = {positions[1], positions[positions.size()-2]}; + delete layouter; return std::make_tuple(std::move(positions), std::move(texcoords), std::move(indices), rectangle); } -std::tuple AbstractTextRenderer::render(Font& font, Float size, const std::string& text, Buffer* vertexBuffer, Buffer* indexBuffer, Buffer::Usage usage) { - TextLayouter layouter(font, size, text); +std::tuple AbstractTextRenderer::render(AbstractFont& font, Float size, const std::string& text, Buffer* vertexBuffer, Buffer* indexBuffer, Buffer::Usage usage) { + AbstractLayouter* const layouter = font.layout(size, text); - const UnsignedInt vertexCount = layouter.glyphCount()*4; - const UnsignedInt indexCount = layouter.glyphCount()*6; + const UnsignedInt vertexCount = layouter->glyphCount()*4; + const UnsignedInt indexCount = layouter->glyphCount()*6; /* Vertex buffer */ std::vector vertices; @@ -109,11 +109,11 @@ std::tuple AbstractTextRenderer::render(Font& font, Float size, /* Render all glyphs */ Vector2 cursorPosition; - for(UnsignedInt i = 0; i != layouter.glyphCount(); ++i) { + for(UnsignedInt i = 0; i != layouter->glyphCount(); ++i) { /* Position of the texture in the resulting glyph, texture coordinates */ Rectangle quadPosition, textureCoordinates; Vector2 advance; - std::tie(quadPosition, textureCoordinates, advance) = layouter.renderGlyph(cursorPosition, i); + std::tie(quadPosition, textureCoordinates, advance) = layouter->renderGlyph(cursorPosition, i); vertices.insert(vertices.end(), { {quadPosition.topLeft(), textureCoordinates.topLeft()}, @@ -135,24 +135,24 @@ std::tuple AbstractTextRenderer::render(Font& font, Float size, indexType = Mesh::IndexType::UnsignedByte; indicesSize = indexCount*sizeof(UnsignedByte); indices = new char[indicesSize]; - createIndices(indices, layouter.glyphCount()); + createIndices(indices, layouter->glyphCount()); } else if(vertexCount < 65535) { indexType = Mesh::IndexType::UnsignedShort; indicesSize = indexCount*sizeof(UnsignedShort); indices = new char[indicesSize]; - createIndices(indices, layouter.glyphCount()); + createIndices(indices, layouter->glyphCount()); } else { indexType = Mesh::IndexType::UnsignedInt; indicesSize = indexCount*sizeof(UnsignedInt); indices = new char[indicesSize]; - createIndices(indices, layouter.glyphCount()); + createIndices(indices, layouter->glyphCount()); } indexBuffer->setData(indicesSize, indices, usage); delete indices; /* Rendered rectangle */ Rectangle rectangle; - if(layouter.glyphCount()) rectangle = {vertices[1].position, vertices[vertices.size()-2].position}; + if(layouter->glyphCount()) rectangle = {vertices[1].position, vertices[vertices.size()-2].position}; /* Configure mesh except for vertex buffer (depends on dimension count, done in subclass) */ @@ -161,10 +161,11 @@ std::tuple AbstractTextRenderer::render(Font& font, Float size, ->setIndexCount(indexCount) ->setIndexBuffer(indexBuffer, 0, indexType, 0, vertexCount); + delete layouter; return std::make_tuple(std::move(mesh), rectangle); } -template std::tuple TextRenderer::render(Font& font, Float size, const std::string& text, Buffer* vertexBuffer, Buffer* indexBuffer, Buffer::Usage usage) { +template std::tuple TextRenderer::render(AbstractFont& font, Float size, const std::string& text, Buffer* vertexBuffer, Buffer* indexBuffer, Buffer::Usage usage) { /* Finalize mesh configuration and return the result */ auto r = AbstractTextRenderer::render(font, size, text, vertexBuffer, indexBuffer, usage); Mesh& mesh = std::get<0>(r); @@ -175,7 +176,7 @@ template std::tuple TextRenderer TextRenderer::TextRenderer(Font& font, const Float size): AbstractTextRenderer(font, size) { +template TextRenderer::TextRenderer(AbstractFont& font, const Float size): AbstractTextRenderer(font, size) { /* Finalize mesh configuration */ _mesh.addInterleavedVertexBuffer(&vertexBuffer, 0, typename Shaders::AbstractVectorShader::Position(Shaders::AbstractVectorShader::Position::Components::Two), @@ -236,23 +237,23 @@ void AbstractTextRenderer::reserve(const uint32_t glyphCount, const Buffer::Usag } void AbstractTextRenderer::render(const std::string& text) { - TextLayouter layouter(font, size, text); + AbstractLayouter* layouter = font.layout(size, text); - CORRADE_ASSERT(layouter.glyphCount() <= _capacity, "Text::TextRenderer::render(): capacity" << _capacity << "too small to render" << layouter.glyphCount() << "glyphs", ); + CORRADE_ASSERT(layouter->glyphCount() <= _capacity, "Text::TextRenderer::render(): capacity" << _capacity << "too small to render" << layouter->glyphCount() << "glyphs", ); /* Render all glyphs */ - Vertex* const vertices = static_cast(vertexBuffer.map(0, layouter.glyphCount()*4*sizeof(Vertex), + Vertex* const vertices = static_cast(vertexBuffer.map(0, layouter->glyphCount()*4*sizeof(Vertex), Buffer::MapFlag::InvalidateBuffer|Buffer::MapFlag::Write)); Vector2 cursorPosition; - for(UnsignedInt i = 0; i != layouter.glyphCount(); ++i) { + for(UnsignedInt i = 0; i != layouter->glyphCount(); ++i) { /* Position of the texture in the resulting glyph, texture coordinates */ Rectangle quadPosition, textureCoordinates; Vector2 advance; - std::tie(quadPosition, textureCoordinates, advance) = layouter.renderGlyph(cursorPosition, i); + std::tie(quadPosition, textureCoordinates, advance) = layouter->renderGlyph(cursorPosition, i); if(i == 0) _rectangle.bottomLeft() = quadPosition.bottomLeft(); - else if(i == layouter.glyphCount()-1) + else if(i == layouter->glyphCount()-1) _rectangle.topRight() = quadPosition.topRight(); const std::size_t vertex = i*4; @@ -267,7 +268,9 @@ void AbstractTextRenderer::render(const std::string& text) { CORRADE_INTERNAL_ASSERT_OUTPUT(vertexBuffer.unmap()); /* Update index count */ - _mesh.setIndexCount(layouter.glyphCount()*6); + _mesh.setIndexCount(layouter->glyphCount()*6); + + delete layouter; } template class TextRenderer<2>; diff --git a/src/Text/TextRenderer.h b/src/Text/TextRenderer.h index f4932fdf2..32d792521 100644 --- a/src/Text/TextRenderer.h +++ b/src/Text/TextRenderer.h @@ -50,14 +50,14 @@ class MAGNUM_TEXT_EXPORT AbstractTextRenderer { * Returns tuple with vertex positions, texture coordinates, indices * and rectangle spanning the rendered text. */ - static std::tuple, std::vector, std::vector, Rectangle> render(Font& font, Float size, const std::string& text); + static std::tuple, std::vector, std::vector, Rectangle> render(AbstractFont& font, Float size, const std::string& text); /** * @brief Constructor * @param font %Font to use * @param size %Font size */ - AbstractTextRenderer(Font& font, Float size); + AbstractTextRenderer(AbstractFont& font, Float size); virtual ~AbstractTextRenderer() = 0; @@ -106,13 +106,13 @@ class MAGNUM_TEXT_EXPORT AbstractTextRenderer { #else private: #endif - static std::tuple MAGNUM_LOCAL render(Font& font, Float size, const std::string& text, Buffer* vertexBuffer, Buffer* indexBuffer, Buffer::Usage usage); + static std::tuple MAGNUM_LOCAL render(AbstractFont& font, Float size, const std::string& text, Buffer* vertexBuffer, Buffer* indexBuffer, Buffer::Usage usage); Mesh _mesh; Buffer vertexBuffer, indexBuffer; private: - Font& font; + AbstractFont& font; Float size; UnsignedInt _capacity; Rectangle _rectangle; @@ -197,14 +197,14 @@ template class MAGNUM_TEXT_EXPORT TextRenderer: public A * Returns mesh prepared for use with Shaders::AbstractVectorShader * subclasses and rectangle spanning the rendered text. */ - static std::tuple render(Font& font, Float size, const std::string& text, Buffer* vertexBuffer, Buffer* indexBuffer, Buffer::Usage usage); + static std::tuple render(AbstractFont& font, Float size, const std::string& text, Buffer* vertexBuffer, Buffer* indexBuffer, Buffer::Usage usage); /** * @brief Constructor * @param font %Font to use * @param size %Font size */ - TextRenderer(Font& font, Float size); + TextRenderer(AbstractFont& font, Float size); using AbstractTextRenderer::render; };