Browse Source

Text: simplified font layouters, removed remaining public API.

Now the font classes are prepared to be plugins.
pull/278/head
Vladimír Vondruš 13 years ago
parent
commit
e222fc5eb8
  1. 46
      src/Text/FreeTypeFont.cpp
  2. 5
      src/Text/FreeTypeFont.h
  3. 28
      src/Text/HarfBuzzFont.cpp
  4. 5
      src/Text/HarfBuzzFont.h

46
src/Text/FreeTypeFont.cpp

@ -41,14 +41,14 @@ namespace {
class FreeTypeLayouter: public AbstractLayouter {
public:
explicit FreeTypeLayouter(FreeTypeFont& font, const GlyphCache* const cache, const Float size, const std::string& text);
explicit FreeTypeLayouter(FT_Face ftFont, const GlyphCache* const cache, const Float fontSize, const Float textSize, const std::string& text);
std::tuple<Rectangle, Rectangle, Vector2> renderGlyph(const Vector2& cursorPosition, const UnsignedInt i) override;
private:
FreeTypeFont& font;
FT_Face font;
const GlyphCache* const cache;
const Float size;
const Float fontSize, textSize;
std::vector<FT_UInt> glyphs;
};
@ -63,13 +63,13 @@ FreeTypeFontRenderer::~FreeTypeFontRenderer() {
}
FreeTypeFont::FreeTypeFont(FreeTypeFontRenderer& renderer, const std::string& fontFile, Float size): AbstractFont(size) {
CORRADE_INTERNAL_ASSERT_OUTPUT(FT_New_Face(renderer.library(), fontFile.c_str(), 0, &_ftFont) == 0);
CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Set_Char_Size(_ftFont, 0, size*64, 100, 100) == 0);
CORRADE_INTERNAL_ASSERT_OUTPUT(FT_New_Face(renderer.library(), fontFile.c_str(), 0, &ftFont) == 0);
CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Set_Char_Size(ftFont, 0, size*64, 100, 100) == 0);
}
FreeTypeFont::FreeTypeFont(FreeTypeFontRenderer& renderer, const unsigned char* data, std::size_t dataSize, Float size): AbstractFont(size) {
CORRADE_INTERNAL_ASSERT_OUTPUT(FT_New_Memory_Face(renderer.library(), data, dataSize, 0, &_ftFont) == 0);
CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Set_Char_Size(_ftFont, 0, size*64, 100, 100) == 0);
CORRADE_INTERNAL_ASSERT_OUTPUT(FT_New_Memory_Face(renderer.library(), data, dataSize, 0, &ftFont) == 0);
CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Set_Char_Size(ftFont, 0, size*64, 100, 100) == 0);
}
void FreeTypeFont::createGlyphCache(GlyphCache* const cache, const std::string& characters) {
@ -82,7 +82,7 @@ void FreeTypeFont::createGlyphCache(GlyphCache* const cache, const std::string&
for(std::size_t i = 0; i != characters.size(); ) {
UnsignedInt codepoint;
std::tie(codepoint, i) = Corrade::Utility::Unicode::nextChar(characters, i);
charIndices.push_back(FT_Get_Char_Index(_ftFont, codepoint));
charIndices.push_back(FT_Get_Char_Index(ftFont, codepoint));
}
/* Remove duplicates (e.g. uppercase and lowercase mapped to same glyph) */
@ -93,8 +93,8 @@ void FreeTypeFont::createGlyphCache(GlyphCache* const cache, const std::string&
std::vector<Vector2i> charSizes;
charSizes.reserve(charIndices.size());
for(FT_UInt c: charIndices) {
CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Load_Glyph(_ftFont, c, FT_LOAD_DEFAULT) == 0);
charSizes.push_back(Vector2i(_ftFont->glyph->metrics.width, _ftFont->glyph->metrics.height)/64);
CORRADE_INTERNAL_ASSERT_OUTPUT(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 */
@ -106,8 +106,8 @@ void FreeTypeFont::createGlyphCache(GlyphCache* const cache, const std::string&
for(std::size_t i = 0; i != charPositions.size(); ++i) {
/* Load and render glyph */
/** @todo B&W only if radius != 0 */
FT_GlyphSlot glyph = _ftFont->glyph;
CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Load_Glyph(_ftFont, charIndices[i], FT_LOAD_DEFAULT) == 0);
FT_GlyphSlot glyph = ftFont->glyph;
CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Load_Glyph(ftFont, charIndices[i], FT_LOAD_DEFAULT) == 0);
CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Render_Glyph(glyph, FT_RENDER_MODE_NORMAL) == 0);
/* Copy rendered bitmap to texture image */
@ -129,22 +129,22 @@ void FreeTypeFont::createGlyphCache(GlyphCache* const cache, const std::string&
}
FreeTypeFont::~FreeTypeFont() {
CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Done_Face(_ftFont) == 0);
CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Done_Face(ftFont) == 0);
}
AbstractLayouter* FreeTypeFont::layout(const GlyphCache* const cache, const Float size, const std::string& text) {
return new FreeTypeLayouter(*this, cache, size, text);
return new FreeTypeLayouter(ftFont, cache, this->size(), size, text);
}
namespace {
FreeTypeLayouter::FreeTypeLayouter(FreeTypeFont& font, const GlyphCache* const cache, const Float size, const std::string& text): font(font), cache(cache), size(size) {
FreeTypeLayouter::FreeTypeLayouter(FT_Face font, const GlyphCache* const cache, const Float fontSize, const Float textSize, const std::string& text): font(font), cache(cache), fontSize(fontSize), textSize(textSize) {
/* Get glyph codes from characters */
glyphs.reserve(text.size());
for(std::size_t i = 0; i != text.size(); ) {
UnsignedInt codepoint;
std::tie(codepoint, i) = Corrade::Utility::Unicode::nextChar(text, i);
glyphs.push_back(FT_Get_Char_Index(font.font(), codepoint));
glyphs.push_back(FT_Get_Char_Index(font, codepoint));
}
_glyphCount = glyphs.size();
}
@ -155,22 +155,22 @@ std::tuple<Rectangle, Rectangle, Vector2> FreeTypeLayouter::renderGlyph(const Ve
Rectanglei rectangle;
std::tie(position, rectangle) = (*cache)[glyphs[i]];
Rectangle texturePosition = Rectangle::fromSize(Vector2(position)/font.size(),
Vector2(rectangle.size())/font.size());
Rectangle texturePosition = Rectangle::fromSize(Vector2(position)/fontSize,
Vector2(rectangle.size())/fontSize);
Rectangle textureCoordinates(Vector2(rectangle.bottomLeft())/cache->textureSize(),
Vector2(rectangle.topRight())/cache->textureSize());
/* Load glyph */
CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Load_Glyph(font.font(), glyphs[i], FT_LOAD_DEFAULT) == 0);
const FT_GlyphSlot slot = font.font()->glyph;
CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Load_Glyph(font, glyphs[i], FT_LOAD_DEFAULT) == 0);
const FT_GlyphSlot slot = font->glyph;
Vector2 offset = Vector2(0, 0); /** @todo really? */
Vector2 advance = Vector2(slot->advance.x, slot->advance.y)/(64*font.size());
Vector2 advance = Vector2(slot->advance.x, slot->advance.y)/(64*fontSize);
/* 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);
(cursorPosition + offset + Vector2(texturePosition.left(), texturePosition.bottom()))*textSize,
texturePosition.size()*textSize);
return std::make_tuple(quadPosition, textureCoordinates, advance);
}

5
src/Text/FreeTypeFont.h

@ -102,9 +102,6 @@ class MAGNUM_TEXT_EXPORT FreeTypeFont: public AbstractFont {
~FreeTypeFont();
/** @brief FreeType font handle */
inline FT_Face font() { return _ftFont; }
void createGlyphCache(GlyphCache* const cache, const std::string& characters) override;
AbstractLayouter* layout(const GlyphCache* const cache, const Float size, const std::string& text) override;
@ -113,7 +110,7 @@ class MAGNUM_TEXT_EXPORT FreeTypeFont: public AbstractFont {
#else
protected:
#endif
FT_Face _ftFont;
FT_Face ftFont;
};
}}

28
src/Text/HarfBuzzFont.cpp

@ -34,18 +34,18 @@ namespace {
class HarfBuzzLayouter: public AbstractLayouter {
public:
explicit HarfBuzzLayouter(HarfBuzzFont& font, const GlyphCache* const cache, const Float size, const std::string& text);
explicit HarfBuzzLayouter(hb_font_t* const font, const GlyphCache* const cache, const Float fontSize, const Float textSize, const std::string& text);
~HarfBuzzLayouter();
std::tuple<Rectangle, Rectangle, Vector2> renderGlyph(const Vector2& cursorPosition, const UnsignedInt i) override;
private:
const HarfBuzzFont& font;
const hb_font_t* const font;
const GlyphCache* const cache;
const Float fontSize, textSize;
hb_buffer_t* buffer;
hb_glyph_info_t* glyphInfo;
hb_glyph_position_t* glyphPositions;
const Float size;
};
}
@ -60,20 +60,20 @@ HarfBuzzFont::HarfBuzzFont(FreeTypeFontRenderer& renderer, const unsigned char*
void HarfBuzzFont::finishConstruction() {
/* Create Harfbuzz font */
_hbFont = hb_ft_font_create(_ftFont, nullptr);
hbFont = hb_ft_font_create(ftFont, nullptr);
}
HarfBuzzFont::~HarfBuzzFont() {
hb_font_destroy(_hbFont);
hb_font_destroy(hbFont);
}
AbstractLayouter* HarfBuzzFont::layout(const GlyphCache* const cache, const Float size, const std::string& text) {
return new HarfBuzzLayouter(*this, cache, size, text);
return new HarfBuzzLayouter(hbFont, cache, this->size(), size, text);
}
namespace {
HarfBuzzLayouter::HarfBuzzLayouter(HarfBuzzFont& font, const GlyphCache* const cache, const Float size, const std::string& text): font(font), cache(cache), size(size) {
HarfBuzzLayouter::HarfBuzzLayouter(hb_font_t* const font, const GlyphCache* const cache, const Float fontSize, const Float textSize, const std::string& text): font(font), cache(cache), fontSize(fontSize), textSize(textSize) {
/* Prepare HarfBuzz buffer */
buffer = hb_buffer_create();
hb_buffer_set_direction(buffer, HB_DIRECTION_LTR);
@ -82,7 +82,7 @@ HarfBuzzLayouter::HarfBuzzLayouter(HarfBuzzFont& font, const GlyphCache* const c
/* Layout the text */
hb_buffer_add_utf8(buffer, text.c_str(), -1, 0, -1);
hb_shape(font.font(), buffer, nullptr, 0);
hb_shape(font, buffer, nullptr, 0);
glyphInfo = hb_buffer_get_glyph_infos(buffer, &_glyphCount);
glyphPositions = hb_buffer_get_glyph_positions(buffer, &_glyphCount);
@ -99,22 +99,22 @@ std::tuple<Rectangle, Rectangle, Vector2> HarfBuzzLayouter::renderGlyph(const Ve
Rectanglei rectangle;
std::tie(position, rectangle) = (*cache)[glyphInfo[i].codepoint];
Rectangle texturePosition = Rectangle::fromSize(Vector2(position)/font.size(),
Vector2(rectangle.size())/font.size());
Rectangle texturePosition = Rectangle::fromSize(Vector2(position)/fontSize,
Vector2(rectangle.size())/fontSize);
Rectangle textureCoordinates(Vector2(rectangle.bottomLeft())/cache->textureSize(),
Vector2(rectangle.topRight())/cache->textureSize());
/* Glyph offset and advance to next glyph in normalized coordinates */
Vector2 offset = Vector2(glyphPositions[i].x_offset,
glyphPositions[i].y_offset)/(64*font.size());
glyphPositions[i].y_offset)/(64*fontSize);
Vector2 advance = Vector2(glyphPositions[i].x_advance,
glyphPositions[i].y_advance)/(64*font.size());
glyphPositions[i].y_advance)/(64*fontSize);
/* 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);
(cursorPosition + offset + Vector2(texturePosition.left(), texturePosition.bottom()))*textSize,
texturePosition.size()*textSize);
return std::make_tuple(quadPosition, textureCoordinates, advance);
}

5
src/Text/HarfBuzzFont.h

@ -68,15 +68,12 @@ class MAGNUM_TEXT_EXPORT HarfBuzzFont: public FreeTypeFont {
~HarfBuzzFont();
/** @brief HarfBuzz font handle */
inline hb_font_t* font() { return _hbFont; }
AbstractLayouter* layout(const GlyphCache* const cache, const Float size, const std::string& text) override;
private:
void MAGNUM_TEXT_LOCAL finishConstruction();
hb_font_t* _hbFont;
hb_font_t* hbFont;
};
}}

Loading…
Cancel
Save