mirror of https://github.com/mosra/magnum.git
Browse Source
The library uses FreeType for glyph pre-rendering and basic glyph geometry and HarfBuzz for text layouting (i.e. ligatures, kerning, ...). Currently all used glyphs must be prerendered into texture atlas, other glyphs are simply not rendered (although the layouting code handles them like if they are there). Text rendering supports UTF-8, although glyph pre-rendering is currently ASCII only, as I couldn't find any working implementation of Unicode STL function in recent GCC versions. Will be fixed later.pull/7/head
10 changed files with 670 additions and 0 deletions
@ -0,0 +1,23 @@
|
||||
find_package(Freetype REQUIRED) |
||||
find_package(HarfBuzz REQUIRED) |
||||
|
||||
include_directories(${FREETYPE_INCLUDE_DIRS} ${HARFBUZZ_INCLUDE_DIRS}) |
||||
|
||||
set(MagnumText_SRCS |
||||
Font.cpp |
||||
FontRenderer.cpp |
||||
TextRenderer.cpp) |
||||
set(MagnumText_HEADERS |
||||
Font.h |
||||
FontRenderer.h |
||||
Text.h |
||||
TextRenderer.h |
||||
|
||||
magnumTextVisibility.h) |
||||
|
||||
add_library(MagnumText SHARED ${MagnumText_SRCS}) |
||||
|
||||
target_link_libraries(MagnumText Magnum MagnumMeshTools MagnumTextureTools ${FREETYPE_LIBRARIES} ${HARFBUZZ_LIBRARIES}) |
||||
|
||||
install(TARGETS MagnumText DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) |
||||
install(FILES ${MagnumText_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Text) |
||||
@ -0,0 +1,145 @@
|
||||
/*
|
||||
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
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 "Font.h" |
||||
|
||||
#include <ft2build.h> |
||||
#include FT_FREETYPE_H |
||||
#include <hb-ft.h> |
||||
|
||||
#include "Image.h" |
||||
#include "TextureTools/Atlas.h" |
||||
|
||||
namespace Magnum { namespace Text { |
||||
|
||||
Font::Font(FontRenderer& renderer, const std::string& fontFile, GLfloat size): _size(size) { |
||||
/** @todo Use delegating constructor when GCC 4.6 support is dropped */ |
||||
create(renderer, fontFile); |
||||
} |
||||
|
||||
Font::Font(FontRenderer& renderer, const std::string& fontFile, GLfloat size, const std::string& characters, const Vector2i& atlasSize): _size(size) { |
||||
/** @todo Use delegating constructor when GCC 4.6 support is dropped */ |
||||
create(renderer, fontFile); |
||||
|
||||
/** @bug Crash when atlas is too small */ |
||||
/** @todo Get rid of duplicate characters */ |
||||
|
||||
/* Get character codes from string */ |
||||
/** @todo proper UTF-8 decoding */ |
||||
std::vector<std::uint32_t> charCodes(characters.begin(), characters.end()); |
||||
|
||||
/* Get character indices */ |
||||
std::vector<FT_UInt> charIndices; |
||||
charIndices.push_back(0); |
||||
for(std::uint32_t charCode: charCodes) |
||||
charIndices.push_back(FT_Get_Char_Index(_ftFont, charCode)); |
||||
|
||||
/* Sizes of all characters */ |
||||
std::vector<Vector2i> charSizes; |
||||
charSizes.reserve(charIndices.size()); |
||||
for(FT_UInt c: charIndices) { |
||||
CORRADE_INTERNAL_ASSERT(FT_Load_Glyph(_ftFont, c, FT_LOAD_DEFAULT) == 0); |
||||
charSizes.push_back((Vector2i(_ftFont->glyph->metrics.width, _ftFont->glyph->metrics.height))/64); |
||||
} |
||||
|
||||
/* Create texture atlas */ |
||||
std::vector<Rectanglei> charPositions = TextureTools::atlas(atlasSize, charSizes); |
||||
|
||||
/* Render all characters to the atlas and create character map */ |
||||
glyphs.reserve(charPositions.size()); |
||||
unsigned char* pixmap = new unsigned char[atlasSize.product()](); |
||||
Image2D image(atlasSize, Image2D::Format::Red, Image2D::Type::UnsignedByte, pixmap); |
||||
for(std::size_t i = 0; i != charPositions.size(); ++i) { |
||||
/* Load and render glyph */ |
||||
/** @todo B&W only */ |
||||
FT_GlyphSlot glyph = _ftFont->glyph; |
||||
CORRADE_INTERNAL_ASSERT(FT_Load_Glyph(_ftFont, charIndices[i], FT_LOAD_DEFAULT) == 0); |
||||
CORRADE_INTERNAL_ASSERT(FT_Render_Glyph(glyph, FT_RENDER_MODE_NORMAL) == 0); |
||||
|
||||
/* Copy rendered bitmap to texture image */ |
||||
const FT_Bitmap& bitmap = glyph->bitmap; |
||||
CORRADE_INTERNAL_ASSERT(std::abs(bitmap.width-charPositions[i].width()) <= 2); |
||||
CORRADE_INTERNAL_ASSERT(std::abs(bitmap.rows-charPositions[i].height()) <= 2); |
||||
for(std::int32_t yin = 0, yout = charPositions[i].bottom(), ymax = bitmap.rows; yin != ymax; ++yin, ++yout) |
||||
for(std::int32_t xin = 0, xout = charPositions[i].left(), xmax = bitmap.width; xin != xmax; ++xin, ++xout) |
||||
pixmap[yout*atlasSize.x() + xout] = bitmap.buffer[(bitmap.rows-yin-1)*bitmap.width + xin]; |
||||
|
||||
/* Save character texture position and texture coordinates for given character index */ |
||||
glyphs.insert({charIndices[i], std::make_tuple( |
||||
Rectangle::fromSize(Vector2(glyph->bitmap_left, glyph->bitmap_top-charPositions[i].height())/size, |
||||
Vector2::from(charPositions[i].size())/size), |
||||
Rectangle(Vector2::from(charPositions[i].bottomLeft())/atlasSize, |
||||
Vector2::from(charPositions[i].topRight())/atlasSize) |
||||
)}); |
||||
} |
||||
|
||||
/* Set texture data */ |
||||
_texture.setData(0, Texture2D::InternalFormat::R8, &image); |
||||
} |
||||
|
||||
void Font::create(FontRenderer& renderer, const std::string& fontFile) { |
||||
/* Create FreeType font */ |
||||
CORRADE_INTERNAL_ASSERT(FT_New_Face(renderer.library(), fontFile.c_str(), 0, &_ftFont) == 0); |
||||
CORRADE_INTERNAL_ASSERT(FT_Set_Char_Size(_ftFont, 0, _size*64, 100, 100) == 0); |
||||
|
||||
/* Create Harfbuzz font */ |
||||
_hbFont = hb_ft_font_create(_ftFont, nullptr); |
||||
|
||||
/* Set up the texture */ |
||||
_texture.setWrapping(Texture2D::Wrapping::ClampToEdge) |
||||
->setMinificationFilter(Texture2D::Filter::LinearInterpolation) |
||||
->setMagnificationFilter(Texture2D::Filter::LinearInterpolation); |
||||
} |
||||
|
||||
void Font::destroy() { |
||||
if(!_ftFont) return; |
||||
|
||||
hb_font_destroy(_hbFont); |
||||
FT_Done_Face(_ftFont); |
||||
} |
||||
|
||||
void Font::move() { |
||||
_hbFont = nullptr; |
||||
_ftFont = nullptr; |
||||
} |
||||
|
||||
Font::~Font() { destroy(); } |
||||
|
||||
Font::Font(Font&& other): glyphs(std::move(other.glyphs)), _texture(std::move(other._texture)), _ftFont(other._ftFont), _hbFont(other._hbFont), _size(other._size) { |
||||
other.move(); |
||||
} |
||||
|
||||
Font& Font::operator=(Font&& other) { |
||||
destroy(); |
||||
|
||||
glyphs = std::move(other.glyphs); |
||||
_texture = std::move(other._texture); |
||||
_ftFont = other._ftFont; |
||||
_hbFont = other._hbFont; |
||||
_size = other._size; |
||||
|
||||
other.move(); |
||||
return *this; |
||||
} |
||||
|
||||
const std::tuple<Rectangle, Rectangle>& Font::operator[](std::uint32_t character) const { |
||||
auto it = glyphs.find(character); |
||||
|
||||
if(it == glyphs.end()) |
||||
return glyphs.at(0); |
||||
return it->second; |
||||
} |
||||
|
||||
}} |
||||
@ -0,0 +1,111 @@
|
||||
#ifndef Magnum_Text_Font_h |
||||
#define Magnum_Text_Font_h |
||||
/*
|
||||
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
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::Font |
||||
*/ |
||||
|
||||
#include <unordered_map> |
||||
|
||||
#include "Math/Geometry/Rectangle.h" |
||||
#include "Texture.h" |
||||
#include "Text/FontRenderer.h" |
||||
|
||||
#include "magnumTextVisibility.h" |
||||
|
||||
#ifndef DOXYGEN_GENERATING_OUTPUT |
||||
struct FT_FaceRec_; |
||||
typedef FT_FaceRec_* FT_Face; |
||||
struct hb_font_t; |
||||
#endif |
||||
|
||||
namespace Magnum { namespace Text { |
||||
|
||||
/**
|
||||
@brief %Font |
||||
|
||||
Contains font with characters prerendered into texture atlas. |
||||
*/ |
||||
class MAGNUM_TEXT_EXPORT Font { |
||||
Font(const Font&) = delete; |
||||
Font& operator=(const Font&) = delete; |
||||
|
||||
public: |
||||
/**
|
||||
* @brief Empty font constructor |
||||
* @param renderer %Font renderer |
||||
* @param fontFile %Font file |
||||
* @param size %Font size |
||||
* |
||||
* Creates font with no prerendered characters. |
||||
*/ |
||||
Font(FontRenderer& renderer, const std::string& fontFile, GLfloat size); |
||||
|
||||
/**
|
||||
* @brief Create font for given character set |
||||
* @param renderer %Font renderer |
||||
* @param fontFile %Font file |
||||
* @param size %Font size |
||||
* @param characters Characters to render |
||||
* @param atlasSize Size of resulting atlas |
||||
*/ |
||||
Font(FontRenderer& renderer, const std::string& fontFile, GLfloat size, const std::string& characters, const Vector2i& atlasSize); |
||||
|
||||
~Font(); |
||||
|
||||
/** @brief Move constructor */ |
||||
Font(Font&& other); |
||||
|
||||
/** @brief Move assignment */ |
||||
Font& operator=(Font&& other); |
||||
|
||||
/** @brief %Font size */ |
||||
inline GLfloat size() const { return _size; } |
||||
|
||||
/** @brief Count of prerendered glyphs in the font */ |
||||
inline std::size_t glyphCount() const { return glyphs.size(); } |
||||
|
||||
/**
|
||||
* @brief Position of given character in the texture |
||||
* @param character Unicode character code (UTF-32) |
||||
* |
||||
* First returned rectangle is texture position relative to point on |
||||
* baseline, second is position of the texture in texture atlas. |
||||
*/ |
||||
const std::tuple<Rectangle, Rectangle>& operator[](std::uint32_t character) const; |
||||
|
||||
/** @brief %Font texture atlas */ |
||||
inline Texture2D& texture() { return _texture; } |
||||
|
||||
/** @brief HarfBuzz font handle */ |
||||
inline hb_font_t* font() { return _hbFont; } |
||||
|
||||
private: |
||||
void MAGNUM_TEXT_LOCAL create(FontRenderer& renderer, const std::string& fontFile); |
||||
void MAGNUM_TEXT_LOCAL destroy(); |
||||
void MAGNUM_TEXT_LOCAL move(); |
||||
|
||||
std::unordered_map<std::uint32_t, std::tuple<Rectangle, Rectangle>> glyphs; |
||||
Texture2D _texture; |
||||
FT_Face _ftFont; |
||||
hb_font_t* _hbFont; |
||||
GLfloat _size; |
||||
}; |
||||
|
||||
}} |
||||
|
||||
#endif |
||||
@ -0,0 +1,32 @@
|
||||
/*
|
||||
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
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 "FontRenderer.h" |
||||
|
||||
#include <ft2build.h> |
||||
#include FT_FREETYPE_H |
||||
#include <Corrade/Utility/Assert.h> |
||||
|
||||
namespace Magnum { namespace Text { |
||||
|
||||
FontRenderer::FontRenderer() { |
||||
CORRADE_INTERNAL_ASSERT(FT_Init_FreeType(&_library) == 0); |
||||
} |
||||
|
||||
FontRenderer::~FontRenderer() { |
||||
FT_Done_FreeType(_library); |
||||
} |
||||
|
||||
}} |
||||
@ -0,0 +1,51 @@
|
||||
#ifndef Magnum_Text_FontRenderer_h |
||||
#define Magnum_Text_FontRenderer_h |
||||
/*
|
||||
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
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::FontRenderer |
||||
*/ |
||||
|
||||
#include "magnumTextVisibility.h" |
||||
|
||||
#ifndef DOXYGEN_GENERATING_OUTPUT |
||||
struct FT_LibraryRec_; |
||||
typedef FT_LibraryRec_* FT_Library; |
||||
#endif |
||||
|
||||
namespace Magnum { namespace Text { |
||||
|
||||
/**
|
||||
@brief Font renderer |
||||
|
||||
Contains global instance of font renderer used by Font class. |
||||
*/ |
||||
class MAGNUM_TEXT_EXPORT FontRenderer { |
||||
public: |
||||
explicit FontRenderer(); |
||||
|
||||
~FontRenderer(); |
||||
|
||||
/** @brief FreeType library handle */ |
||||
inline FT_Library library() { return _library; } |
||||
|
||||
private: |
||||
FT_Library _library; |
||||
}; |
||||
|
||||
}} |
||||
|
||||
#endif |
||||
@ -0,0 +1,32 @@
|
||||
#ifndef Magnum_Text_Text_h |
||||
#define Magnum_Text_Text_h |
||||
/*
|
||||
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
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 Forward declarations for Magnum::Text namespace |
||||
*/ |
||||
|
||||
#include <cstdint> |
||||
|
||||
namespace Magnum { namespace Text { |
||||
|
||||
class Font; |
||||
class FontRenderer; |
||||
/* TextRenderer used only statically */ |
||||
|
||||
}} |
||||
|
||||
#endif |
||||
@ -0,0 +1,161 @@
|
||||
/*
|
||||
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
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 "TextRenderer.h" |
||||
|
||||
#include <hb.h> |
||||
#include <hb-icu.h> |
||||
|
||||
#include "Math/Point2D.h" |
||||
#include "Math/Point3D.h" |
||||
#include "IndexedMesh.h" |
||||
#include "Swizzle.h" |
||||
#include "MeshTools/CompressIndices.h" |
||||
#include "MeshTools/Interleave.h" |
||||
#include "Shaders/AbstractTextShader.h" |
||||
#include "Text/Font.h" |
||||
|
||||
namespace Magnum { namespace Text { |
||||
|
||||
namespace { |
||||
|
||||
std::tuple<std::vector<Vector2>, std::vector<Vector2>, std::vector<std::uint32_t>> renderInternal(Font& font, GLfloat size, const std::string& text) { |
||||
/* Prepare HarfBuzz buffer */ |
||||
hb_buffer_t *buffer = hb_buffer_create(); |
||||
hb_buffer_set_unicode_funcs(buffer, hb_icu_get_unicode_funcs()); |
||||
hb_buffer_set_direction(buffer, HB_DIRECTION_LTR); |
||||
hb_buffer_set_script(buffer, HB_SCRIPT_LATIN); |
||||
hb_buffer_set_language(buffer, hb_language_from_string("en", 2)); |
||||
|
||||
/* Layout the text */ |
||||
hb_buffer_add_utf8(buffer, text.c_str(), -1, 0, -1); |
||||
hb_shape(font.font(), buffer, nullptr, 0); |
||||
|
||||
std::uint32_t glyphCount; |
||||
hb_glyph_info_t* glyphInfo = hb_buffer_get_glyph_infos(buffer, &glyphCount); |
||||
hb_glyph_position_t* glyphPositions = hb_buffer_get_glyph_positions(buffer, &glyphCount); |
||||
|
||||
/* Output data */ |
||||
std::vector<Vector2> positions, texcoords; |
||||
std::vector<std::uint32_t> indices; |
||||
positions.reserve(glyphCount*4); |
||||
texcoords.reserve(glyphCount*4); |
||||
indices.reserve(glyphCount*6); |
||||
|
||||
/* Starting cursor position */ |
||||
Vector2 cursorPosition; |
||||
|
||||
/* Create quads for all glyphs */ |
||||
for(std::uint32_t i = 0; i != glyphCount; ++i) { |
||||
/* Position of the texture in the resulting glyph, texture coordinates */ |
||||
Rectangle texturePosition, textureCoordinates; |
||||
std::tie(texturePosition, textureCoordinates) = font[glyphInfo[i].codepoint]; |
||||
|
||||
/* Glyph offset and advance to next glyph in normalized coordinates */ |
||||
Vector2 offset = Vector2(glyphPositions[i].x_offset, |
||||
glyphPositions[i].y_offset)/(64*font.size()); |
||||
Vector2 advance = Vector2(glyphPositions[i].x_advance, |
||||
glyphPositions[i].y_advance)/(64*font.size()); |
||||
|
||||
/* Absolute quad position, composed from cursor position, glyph offset
|
||||
and texture position, denormalized to requested text size */ |
||||
Rectangle quadPosition = Rectangle::fromSize( |
||||
(cursorPosition + offset + Vector2(texturePosition.left(), texturePosition.bottom()))*size, |
||||
texturePosition.size()*size); |
||||
|
||||
/* 0---2 2
|
||||
| / /| |
||||
| / / | |
||||
|/ / | |
||||
1 1---3 */ |
||||
|
||||
/* Quad with texture coordinates */ |
||||
indices.insert(indices.end(), { |
||||
std::uint32_t(positions.size()), |
||||
std::uint32_t(positions.size()+1), |
||||
std::uint32_t(positions.size()+2), |
||||
std::uint32_t(positions.size()+1), |
||||
std::uint32_t(positions.size()+3), |
||||
std::uint32_t(positions.size()+2) |
||||
}); |
||||
positions.insert(positions.end(), { |
||||
quadPosition.topLeft(), |
||||
quadPosition.bottomLeft(), |
||||
quadPosition.topRight(), |
||||
quadPosition.bottomRight(), |
||||
}); |
||||
texcoords.insert(texcoords.end(), { |
||||
textureCoordinates.topLeft(), |
||||
textureCoordinates.bottomLeft(), |
||||
textureCoordinates.topRight(), |
||||
textureCoordinates.bottomRight() |
||||
}); |
||||
|
||||
/* Advance cursor position to next character */ |
||||
cursorPosition += advance; |
||||
} |
||||
|
||||
/* Destroy HarfBuzz buffer */ |
||||
hb_buffer_destroy(buffer); |
||||
|
||||
return std::make_tuple(std::move(positions), std::move(texcoords), std::move(indices)); |
||||
} |
||||
|
||||
template<std::uint8_t dimensions> typename DimensionTraits<dimensions>::PointType point(const Vector2& vec); |
||||
|
||||
template<> inline Point2D point<2>(const Vector2& vec) { |
||||
return swizzle<'x', 'y', '1'>(vec); |
||||
} |
||||
|
||||
template<> inline Point3D point<3>(const Vector2& vec) { |
||||
return swizzle<'x', 'y', '0', '1'>(vec); |
||||
} |
||||
|
||||
} |
||||
|
||||
template<std::uint8_t dimensions> std::tuple<std::vector<typename DimensionTraits<dimensions>::PointType>, std::vector<Vector2>, std::vector<std::uint32_t>> TextRenderer<dimensions>::render(Font& font, GLfloat size, const std::string& text) { |
||||
std::vector<Vector2> positions, textureCoordinates; |
||||
std::vector<std::uint32_t> indices; |
||||
std::tie(positions, textureCoordinates, indices) = renderInternal(font, size, text); |
||||
|
||||
/* Create PointXD from Vector2 */ |
||||
std::vector<typename DimensionTraits<dimensions>::PointType> positionsXD; |
||||
positionsXD.reserve(positions.size()); |
||||
for(const Vector2& position: positions) |
||||
positionsXD.push_back(point<dimensions>(position)); |
||||
|
||||
return std::make_tuple(std::move(positionsXD), std::move(textureCoordinates), std::move(indices)); |
||||
} |
||||
|
||||
template<std::uint8_t dimensions> IndexedMesh TextRenderer<dimensions>::render(Font& font, GLfloat size, const std::string& text, Buffer* vertexBuffer, Buffer* indexBuffer, Buffer::Usage usage) { |
||||
IndexedMesh mesh; |
||||
|
||||
std::vector<typename DimensionTraits<dimensions>::PointType> positions; |
||||
std::vector<Vector2> textureCoordinates; |
||||
std::vector<std::uint32_t> indices; |
||||
std::tie(positions, textureCoordinates, indices) = render(font, size, text); |
||||
|
||||
MeshTools::interleave(&mesh, vertexBuffer, usage, positions, textureCoordinates); |
||||
MeshTools::compressIndices(&mesh, indexBuffer, usage, indices); |
||||
mesh.setPrimitive(Mesh::Primitive::Triangles) |
||||
->addInterleavedVertexBuffer(vertexBuffer, 0, typename Shaders::AbstractTextShader<dimensions>::Position(), typename Shaders::AbstractTextShader<dimensions>::TextureCoordinates()); |
||||
|
||||
return mesh; |
||||
} |
||||
|
||||
template class TextRenderer<2>; |
||||
template class TextRenderer<3>; |
||||
|
||||
}} |
||||
@ -0,0 +1,84 @@
|
||||
#ifndef Magnum_Text_TextRenderer_h |
||||
#define Magnum_Text_TextRenderer_h |
||||
/*
|
||||
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
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::TextRenderer |
||||
*/ |
||||
|
||||
#include "Math/Vector2.h" |
||||
#include "Buffer.h" |
||||
#include "DimensionTraits.h" |
||||
#include "Text/Text.h" |
||||
|
||||
#include "magnumTextVisibility.h" |
||||
|
||||
#include <string> |
||||
#include <tuple> |
||||
#include <vector> |
||||
|
||||
namespace Magnum { namespace Text { |
||||
|
||||
/**
|
||||
@brief %Text renderer |
||||
|
||||
Lays out the text into mesh using [HarfBuzz](http://www.freedesktop.org/wiki/Software/HarfBuzz)
|
||||
library. Use of ligatures, kerning etc. depends on features supported by the |
||||
particular font. |
||||
@see TextRenderer2D, TextRenderer3D, Font, Shaders::AbstractTextShader |
||||
*/ |
||||
template<std::uint8_t dimensions> class MAGNUM_TEXT_EXPORT TextRenderer { |
||||
public: |
||||
/**
|
||||
* @brief Render text |
||||
* @param font %Font to use |
||||
* @param size %Font size |
||||
* @param text %Text to render |
||||
* @return Tuple with vertex positions, texture coordinates and indices |
||||
*/ |
||||
static std::tuple<std::vector<typename DimensionTraits<dimensions>::PointType>, std::vector<Vector2>, std::vector<std::uint32_t>> render(Font& font, GLfloat size, const std::string& text); |
||||
|
||||
/**
|
||||
* @brief Render text |
||||
* @param font %Font to use |
||||
* @param size %Font size |
||||
* @param text %Text to render |
||||
* @param vertexBuffer %Buffer where to store vertices |
||||
* @param indexBuffer %Buffer where to store indices |
||||
* @param usage Usage of vertex and index buffer |
||||
* @return Indexed mesh prepared for use with Shaders::AbstractTextShader |
||||
* subclasses |
||||
*/ |
||||
static IndexedMesh render(Font& font, GLfloat size, const std::string& text, Buffer* vertexBuffer, Buffer* indexBuffer, Buffer::Usage usage); |
||||
|
||||
private: |
||||
#ifndef DOXYGEN_GENERATING_OUTPUT |
||||
struct Vertex { |
||||
typename DimensionTraits<dimensions>::PointType position; |
||||
Vector2 textureCoordinates; |
||||
}; |
||||
#endif |
||||
}; |
||||
|
||||
/** @brief Two-dimensional text renderer */ |
||||
typedef TextRenderer<2> TextRenderer2D; |
||||
|
||||
/** @brief Three-dimensional text renderer */ |
||||
typedef TextRenderer<3> TextRenderer3D; |
||||
|
||||
}} |
||||
|
||||
#endif |
||||
@ -0,0 +1,30 @@
|
||||
#ifndef Magnum_Text_magnumTextVisibility_h |
||||
#define Magnum_Text_magnumTextVisibility_h |
||||
/*
|
||||
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
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. |
||||
*/ |
||||
|
||||
#ifdef _WIN32 |
||||
#ifdef MagnumText_EXPORTS |
||||
#define MAGNUM_TEXT_EXPORT __declspec(dllexport) |
||||
#else |
||||
#define MAGNUM_TEXT_EXPORT __declspec(dllimport) |
||||
#endif |
||||
#define MAGNUM_TEXT_LOCAL |
||||
#else |
||||
#define MAGNUM_TEXT_EXPORT __attribute__ ((visibility ("default"))) |
||||
#define MAGNUM_TEXT_LOCAL __attribute__ ((visibility ("hidden"))) |
||||
#endif |
||||
|
||||
#endif |
||||
Loading…
Reference in new issue