Browse Source

Text: using new type aliases in whole Text namespace.

pull/278/head
Vladimír Vondruš 13 years ago
parent
commit
a7a4d3eeb8
  1. 12
      src/Text/Font.cpp
  2. 12
      src/Text/Font.h
  3. 4
      src/Text/Text.h
  4. 78
      src/Text/TextRenderer.cpp
  5. 20
      src/Text/TextRenderer.h

12
src/Text/Font.cpp

@ -29,13 +29,13 @@
namespace Magnum { namespace Text {
Font::Font(FontRenderer& renderer, const std::string& fontFile, GLfloat size): _size(size) {
Font::Font(FontRenderer& 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, GLfloat size): _size(size) {
Font::Font(FontRenderer& 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();
@ -71,7 +71,7 @@ void Font::prerender(const std::string& characters, const Vector2i& atlasSize) {
charIndices.reserve(characters.size()+1);
charIndices.push_back(0);
for(std::size_t i = 0; i != characters.size(); ) {
std::uint32_t codepoint;
UnsignedInt codepoint;
std::tie(codepoint, i) = Corrade::Utility::Unicode::nextChar(characters, i);
charIndices.push_back(FT_Get_Char_Index(_ftFont, codepoint));
}
@ -106,8 +106,8 @@ void Font::prerender(const std::string& characters, const Vector2i& atlasSize) {
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)
for(Int yin = 0, yout = charPositions[i].bottom(), ymax = bitmap.rows; yin != ymax; ++yin, ++yout)
for(Int 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 */
@ -168,7 +168,7 @@ Font& Font::operator=(Font&& other) {
return *this;
}
const std::tuple<Rectangle, Rectangle>& Font::operator[](std::uint32_t character) const {
const std::tuple<Rectangle, Rectangle>& Font::operator[](char32_t character) const {
auto it = glyphs.find(character);
if(it == glyphs.end())

12
src/Text/Font.h

@ -73,7 +73,7 @@ class MAGNUM_TEXT_EXPORT Font {
* @param fontFile %Font file
* @param size %Font size
*/
explicit Font(FontRenderer& renderer, const std::string& fontFile, GLfloat size);
explicit Font(FontRenderer& renderer, const std::string& fontFile, Float size);
/**
* @brief Create font from memory
@ -82,7 +82,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, GLfloat size);
explicit Font(FontRenderer& renderer, const unsigned char* data, std::size_t dataSize, Float size);
/**
* @brief Prerender given character set
@ -105,7 +105,7 @@ class MAGNUM_TEXT_EXPORT Font {
Font& operator=(Font&& other);
/** @brief %Font size */
inline GLfloat size() const { return _size; }
inline Float size() const { return _size; }
/** @brief Count of prerendered glyphs in the font */
inline std::size_t glyphCount() const { return glyphs.size(); }
@ -117,7 +117,7 @@ class MAGNUM_TEXT_EXPORT Font {
* 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;
const std::tuple<Rectangle, Rectangle>& operator[](char32_t character) const;
/** @brief %Font texture atlas */
inline Texture2D& texture() { return _texture; }
@ -134,10 +134,10 @@ class MAGNUM_TEXT_EXPORT Font {
void MAGNUM_TEXT_LOCAL destroy();
void MAGNUM_TEXT_LOCAL move();
std::unordered_map<std::uint32_t, std::tuple<Rectangle, Rectangle>> glyphs;
std::unordered_map<char32_t, std::tuple<Rectangle, Rectangle>> glyphs;
Texture2D _texture;
FT_Face _ftFont;
GLfloat _size;
Float _size;
#ifdef MAGNUM_USE_HARFBUZZ
hb_font_t* _hbFont;
#endif

4
src/Text/Text.h

@ -19,14 +19,14 @@
* @brief Forward declarations for Magnum::Text namespace
*/
#include <cstdint>
#include "Types.h"
namespace Magnum { namespace Text {
class Font;
class FontRenderer;
template<std::uint8_t> class TextRenderer;
template<UnsignedInt> class TextRenderer;
typedef TextRenderer<2> TextRenderer2D;
typedef TextRenderer<3> TextRenderer3D;

78
src/Text/TextRenderer.cpp

@ -36,11 +36,11 @@ namespace {
class TextLayouter {
public:
TextLayouter(Font& font, const GLfloat size, const std::string& text);
TextLayouter(Font& font, const Float size, const std::string& text);
~TextLayouter();
inline std::uint32_t glyphCount() {
inline UnsignedInt glyphCount() {
#ifdef MAGNUM_USE_HARFBUZZ
return _glyphCount;
#else
@ -48,7 +48,7 @@ class TextLayouter {
#endif
}
std::tuple<Rectangle, Rectangle, Vector2> renderGlyph(const Vector2& cursorPosition, const std::uint32_t i);
std::tuple<Rectangle, Rectangle, Vector2> renderGlyph(const Vector2& cursorPosition, const UnsignedInt i);
private:
#ifdef MAGNUM_USE_HARFBUZZ
@ -56,16 +56,16 @@ class TextLayouter {
hb_buffer_t* buffer;
hb_glyph_info_t* glyphInfo;
hb_glyph_position_t* glyphPositions;
std::uint32_t _glyphCount;
UnsignedInt _glyphCount;
#else
Font& font;
std::vector<FT_UInt> glyphs;
#endif
const GLfloat size;
const Float size;
};
TextLayouter::TextLayouter(Font& font, const GLfloat size, const std::string& text): font(font), size(size) {
TextLayouter::TextLayouter(Font& font, const Float size, const std::string& text): font(font), size(size) {
#ifdef MAGNUM_USE_HARFBUZZ
/* Prepare HarfBuzz buffer */
buffer = hb_buffer_create();
@ -83,7 +83,7 @@ TextLayouter::TextLayouter(Font& font, const GLfloat size, const std::string& te
/* Get glyph codes from characters */
glyphs.reserve(text.size()+1);
for(std::size_t i = 0; i != text.size(); ) {
std::uint32_t codepoint;
UnsignedInt codepoint;
std::tie(codepoint, i) = Corrade::Utility::Unicode::nextChar(text, i);
glyphs.push_back(FT_Get_Char_Index(font.font(), codepoint));
}
@ -97,7 +97,7 @@ TextLayouter::~TextLayouter() {
#endif
}
std::tuple<Rectangle, Rectangle, Vector2> TextLayouter::renderGlyph(const Vector2& cursorPosition, const std::uint32_t i) {
std::tuple<Rectangle, Rectangle, Vector2> TextLayouter::renderGlyph(const Vector2& cursorPosition, const UnsignedInt i) {
/* Position of the texture in the resulting glyph, texture coordinates */
Rectangle texturePosition, textureCoordinates;
#ifdef MAGNUM_USE_HARFBUZZ
@ -129,9 +129,9 @@ std::tuple<Rectangle, Rectangle, Vector2> TextLayouter::renderGlyph(const Vector
return std::make_tuple(quadPosition, textureCoordinates, advance);
}
template<class T> void createIndices(void* output, const std::uint32_t glyphCount) {
template<class T> void createIndices(void* output, const UnsignedInt glyphCount) {
T* const out = reinterpret_cast<T*>(output);
for(std::uint32_t i = 0; i != glyphCount; ++i) {
for(UnsignedInt i = 0; i != glyphCount; ++i) {
/* 0---2 2
| / /|
| / / |
@ -149,7 +149,7 @@ template<class T> void createIndices(void* output, const std::uint32_t glyphCoun
}
}
template<std::uint8_t dimensions> typename DimensionTraits<dimensions>::VectorType point(const Vector2& vec);
template<UnsignedInt dimensions> typename DimensionTraits<dimensions>::VectorType point(const Vector2& vec);
template<> inline Vector2 point<2>(const Vector2& vec) {
return vec;
@ -159,17 +159,17 @@ template<> inline Vector3 point<3>(const Vector2& vec) {
return {vec, 1.0f};
}
template<std::uint8_t dimensions> struct Vertex {
template<UnsignedInt dimensions> struct Vertex {
typename DimensionTraits<dimensions>::VectorType position;
Vector2 texcoords;
};
}
template<std::uint8_t dimensions> std::tuple<std::vector<typename DimensionTraits<dimensions>::VectorType>, std::vector<Vector2>, std::vector<std::uint32_t>, Rectangle> TextRenderer<dimensions>::render(Font& font, GLfloat size, const std::string& text) {
template<UnsignedInt dimensions> std::tuple<std::vector<typename DimensionTraits<dimensions>::VectorType>, std::vector<Vector2>, std::vector<UnsignedInt>, Rectangle> TextRenderer<dimensions>::render(Font& font, Float size, const std::string& text) {
TextLayouter layouter(font, size, text);
const std::uint32_t vertexCount = layouter.glyphCount()*4;
const UnsignedInt vertexCount = layouter.glyphCount()*4;
/* Output data */
std::vector<typename DimensionTraits<dimensions>::VectorType> positions;
@ -179,7 +179,7 @@ template<std::uint8_t dimensions> std::tuple<std::vector<typename DimensionTrait
/* Render all glyphs */
Vector2 cursorPosition;
for(std::uint32_t 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;
@ -203,8 +203,8 @@ template<std::uint8_t dimensions> std::tuple<std::vector<typename DimensionTrait
}
/* Create indices */
std::vector<std::uint32_t> indices(layouter.glyphCount()*6);
createIndices<std::uint32_t>(indices.data(), layouter.glyphCount());
std::vector<UnsignedInt> indices(layouter.glyphCount()*6);
createIndices<UnsignedInt>(indices.data(), layouter.glyphCount());
/* Rendered rectangle */
Rectangle rectangle;
@ -214,11 +214,11 @@ template<std::uint8_t dimensions> std::tuple<std::vector<typename DimensionTrait
return std::make_tuple(std::move(positions), std::move(texcoords), std::move(indices), rectangle);
}
template<std::uint8_t dimensions> std::tuple<Mesh, Rectangle> TextRenderer<dimensions>::render(Font& font, GLfloat size, const std::string& text, Buffer* vertexBuffer, Buffer* indexBuffer, Buffer::Usage usage) {
template<UnsignedInt dimensions> std::tuple<Mesh, Rectangle> TextRenderer<dimensions>::render(Font& font, Float size, const std::string& text, Buffer* vertexBuffer, Buffer* indexBuffer, Buffer::Usage usage) {
TextLayouter layouter(font, size, text);
const std::uint32_t vertexCount = layouter.glyphCount()*4;
const std::uint32_t indexCount = layouter.glyphCount()*6;
const UnsignedInt vertexCount = layouter.glyphCount()*4;
const UnsignedInt indexCount = layouter.glyphCount()*6;
/* Vertex buffer */
std::vector<Vertex<dimensions>> vertices;
@ -226,7 +226,7 @@ template<std::uint8_t dimensions> std::tuple<Mesh, Rectangle> TextRenderer<dimen
/* Render all glyphs */
Vector2 cursorPosition;
for(std::uint32_t 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;
@ -250,19 +250,19 @@ template<std::uint8_t dimensions> std::tuple<Mesh, Rectangle> TextRenderer<dimen
char* indices;
if(vertexCount < 255) {
indexType = Mesh::IndexType::UnsignedByte;
indicesSize = indexCount*sizeof(GLushort);
indicesSize = indexCount*sizeof(UnsignedByte);
indices = new char[indicesSize];
createIndices<GLubyte>(indices, layouter.glyphCount());
createIndices<UnsignedByte>(indices, layouter.glyphCount());
} else if(vertexCount < 65535) {
indexType = Mesh::IndexType::UnsignedShort;
indicesSize = indexCount*sizeof(GLushort);
indicesSize = indexCount*sizeof(UnsignedShort);
indices = new char[indicesSize];
createIndices<GLushort>(indices, layouter.glyphCount());
createIndices<UnsignedShort>(indices, layouter.glyphCount());
} else {
indexType = Mesh::IndexType::UnsignedInt;
indicesSize = indexCount*sizeof(GLuint);
indicesSize = indexCount*sizeof(UnsignedInt);
indices = new char[indicesSize];
createIndices<GLuint>(indices, layouter.glyphCount());
createIndices<UnsignedInt>(indices, layouter.glyphCount());
}
indexBuffer->setData(indicesSize, indices, usage);
delete indices;
@ -284,7 +284,7 @@ template<std::uint8_t dimensions> std::tuple<Mesh, Rectangle> TextRenderer<dimen
return std::make_tuple(std::move(mesh), rectangle);
}
template<std::uint8_t dimensions> TextRenderer<dimensions>::TextRenderer(Font& font, const GLfloat size): font(font), size(size), _capacity(0), vertexBuffer(Buffer::Target::Array), indexBuffer(Buffer::Target::ElementArray) {
template<UnsignedInt dimensions> TextRenderer<dimensions>::TextRenderer(Font& font, const Float size): font(font), size(size), _capacity(0), vertexBuffer(Buffer::Target::Array), indexBuffer(Buffer::Target::ElementArray) {
#ifndef MAGNUM_TARGET_GLES
MAGNUM_ASSERT_EXTENSION_SUPPORTED(Extensions::GL::ARB::map_buffer_range);
#else
@ -299,11 +299,11 @@ template<std::uint8_t dimensions> TextRenderer<dimensions>::TextRenderer(Font& f
typename Shaders::AbstractTextShader<dimensions>::TextureCoordinates());
}
template<std::uint8_t dimensions> void TextRenderer<dimensions>::reserve(const uint32_t glyphCount, const Buffer::Usage vertexBufferUsage, const Buffer::Usage indexBufferUsage) {
template<UnsignedInt dimensions> void TextRenderer<dimensions>::reserve(const uint32_t glyphCount, const Buffer::Usage vertexBufferUsage, const Buffer::Usage indexBufferUsage) {
_capacity = glyphCount;
const std::uint32_t vertexCount = glyphCount*4;
const std::uint32_t indexCount = glyphCount*6;
const UnsignedInt vertexCount = glyphCount*4;
const UnsignedInt indexCount = glyphCount*6;
/* Allocate vertex buffer, reset vertex count */
vertexBuffer.setData(vertexCount*sizeof(Vertex<dimensions>), nullptr, vertexBufferUsage);
@ -314,13 +314,13 @@ template<std::uint8_t dimensions> void TextRenderer<dimensions>::reserve(const u
std::size_t indicesSize;
if(vertexCount < 255) {
indexType = Mesh::IndexType::UnsignedByte;
indicesSize = indexCount*sizeof(GLushort);
indicesSize = indexCount*sizeof(UnsignedByte);
} else if(vertexCount < 65535) {
indexType = Mesh::IndexType::UnsignedShort;
indicesSize = indexCount*sizeof(GLushort);
indicesSize = indexCount*sizeof(UnsignedShort);
} else {
indexType = Mesh::IndexType::UnsignedInt;
indicesSize = indexCount*sizeof(GLuint);
indicesSize = indexCount*sizeof(UnsignedInt);
}
indexBuffer.setData(indicesSize, nullptr, indexBufferUsage);
_mesh.setIndexCount(0)
@ -329,15 +329,15 @@ template<std::uint8_t dimensions> void TextRenderer<dimensions>::reserve(const u
/* Prefill index buffer */
void* indices = indexBuffer.map(0, indicesSize, Buffer::MapFlag::InvalidateBuffer|Buffer::MapFlag::Write);
if(vertexCount < 255)
createIndices<GLubyte>(indices, glyphCount);
createIndices<UnsignedByte>(indices, glyphCount);
else if(vertexCount < 65535)
createIndices<GLushort>(indices, glyphCount);
createIndices<UnsignedShort>(indices, glyphCount);
else
createIndices<GLuint>(indices, glyphCount);
createIndices<UnsignedInt>(indices, glyphCount);
CORRADE_INTERNAL_ASSERT_OUTPUT(indexBuffer.unmap());
}
template<std::uint8_t dimensions> void TextRenderer<dimensions>::render(const std::string& text) {
template<UnsignedInt dimensions> void TextRenderer<dimensions>::render(const std::string& text) {
TextLayouter layouter(font, size, text);
CORRADE_ASSERT(layouter.glyphCount() <= _capacity, "Text::TextRenderer::render(): capacity" << _capacity << "too small to render" << layouter.glyphCount() << "glyphs", );
@ -346,7 +346,7 @@ template<std::uint8_t dimensions> void TextRenderer<dimensions>::render(const st
Vertex<dimensions>* const vertices = static_cast<Vertex<dimensions>*>(vertexBuffer.map(0, layouter.glyphCount()*4*sizeof(Vertex<dimensions>),
Buffer::MapFlag::InvalidateBuffer|Buffer::MapFlag::Write));
Vector2 cursorPosition;
for(std::uint32_t 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;

20
src/Text/TextRenderer.h

@ -64,8 +64,8 @@ shader.setTransformationProjectionMatrix(projection*Matrix3::translation(-rectan
font.texture()->bind(Shaders::TextShader2D::FontTextureLayer);
mesh.draw();
@endcode
See render(Font&, GLfloat, const std::string&) and
render(Font&, GLfloat, const std::string&, Buffer*, Buffer*, Buffer::Usage)
See render(Font&, Float, const std::string&) and
render(Font&, Float, const std::string&, Buffer*, Buffer*, Buffer::Usage)
for more information.
While this method is sufficient for one-shot rendering of static texts, for
@ -98,7 +98,7 @@ for asynchronous buffer updates.
@see TextRenderer2D, TextRenderer3D, Font, Shaders::AbstractTextShader
*/
template<std::uint8_t dimensions> class MAGNUM_TEXT_EXPORT TextRenderer {
template<UnsignedInt dimensions> class MAGNUM_TEXT_EXPORT TextRenderer {
public:
/**
* @brief Render text
@ -109,7 +109,7 @@ template<std::uint8_t dimensions> class MAGNUM_TEXT_EXPORT TextRenderer {
* Returns tuple with vertex positions, texture coordinates, indices
* and rectangle spanning the rendered text.
*/
static std::tuple<std::vector<typename DimensionTraits<dimensions>::VectorType>, std::vector<Vector2>, std::vector<std::uint32_t>, Rectangle> render(Font& font, GLfloat size, const std::string& text);
static std::tuple<std::vector<typename DimensionTraits<dimensions>::VectorType>, std::vector<Vector2>, std::vector<UnsignedInt>, Rectangle> render(Font& font, Float size, const std::string& text);
/**
* @brief Render text
@ -123,21 +123,21 @@ template<std::uint8_t dimensions> class MAGNUM_TEXT_EXPORT TextRenderer {
* Returns mesh prepared for use with Shaders::AbstractTextShader
* subclasses and rectangle spanning the rendered text.
*/
static std::tuple<Mesh, Rectangle> render(Font& font, GLfloat size, const std::string& text, Buffer* vertexBuffer, Buffer* indexBuffer, Buffer::Usage usage);
static std::tuple<Mesh, Rectangle> render(Font& 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, GLfloat size);
TextRenderer(Font& font, Float size);
/**
* @brief Capacity for rendered glyphs
*
* @see reserve()
*/
inline std::uint32_t capacity() const { return _capacity; }
inline UnsignedInt capacity() const { return _capacity; }
/** @brief Rectangle spanning the rendered text */
inline Rectangle rectangle() const { return _rectangle; }
@ -157,7 +157,7 @@ template<std::uint8_t dimensions> class MAGNUM_TEXT_EXPORT TextRenderer {
* Initially zero capacity is reserved.
* @see capacity()
*/
void reserve(const std::uint32_t glyphCount, const Buffer::Usage vertexBufferUsage, const Buffer::Usage indexBufferUsage);
void reserve(const UnsignedInt glyphCount, const Buffer::Usage vertexBufferUsage, const Buffer::Usage indexBufferUsage);
/**
* @brief Render text
@ -174,8 +174,8 @@ template<std::uint8_t dimensions> class MAGNUM_TEXT_EXPORT TextRenderer {
private:
Font& font;
GLfloat size;
std::uint32_t _capacity;
Float size;
UnsignedInt _capacity;
Rectangle _rectangle;
Buffer vertexBuffer, indexBuffer;
Mesh _mesh;

Loading…
Cancel
Save