From b38ec8152bd7c3400b1961ef74749477b418d02f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Thu, 21 Feb 2013 11:35:50 +0100 Subject: [PATCH] Text: ability to compile the library without HarfBuzz support. The text will be rendered without all the nifty features like kerning and it will most probably fail on everything non-latin, but HarfBuzz is currently PITA on some systems. HarfBuzz usage can be configured using USE_HARFBUZZ CMake option. --- CMakeLists.txt | 6 +++++ modules/FindMagnum.cmake | 2 +- src/Text/CMakeLists.txt | 12 +++++++--- src/Text/Font.cpp | 16 ++++++++++++- src/Text/Font.h | 10 ++++++-- src/Text/TextRenderer.cpp | 46 +++++++++++++++++++++++++++++++++++-- src/magnumConfigure.h.cmake | 1 + 7 files changed, 84 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b24e7f526..94132ebeb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,6 +21,9 @@ cmake_dependent_option(WITH_TEXTURETOOLS "Build TextureTools library" OFF "NOT W cmake_dependent_option(WITH_MAGNUMINFO "Build magnum-info utility" OFF "NOT WITH_EVERYTHING" ON) +# Library features +cmake_dependent_option(USE_HARFBUZZ "Use HarfBuzz in Text library" ON "WITH_TEXT" OFF) + if(${CMAKE_SYSTEM_NAME} STREQUAL NaCl) option(WITH_NACLAPPLICATION "Build NaClApplication library" OFF) else() @@ -66,6 +69,9 @@ endif() if(TARGET_DESKTOP_GLES) set(MAGNUM_TARGET_DESKTOP_GLES 1) endif() +if(USE_HARFBUZZ) + set(MAGNUM_USE_HARFBUZZ 1) +endif() # Installation paths set(MAGNUM_BINARY_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/bin) diff --git a/modules/FindMagnum.cmake b/modules/FindMagnum.cmake index 0774bc391..51f01af9b 100644 --- a/modules/FindMagnum.cmake +++ b/modules/FindMagnum.cmake @@ -23,7 +23,7 @@ # SceneGraph - Scene graph library # Shaders - Library with stock shaders # Text - Text rendering library (depends on TextureTools component, -# HarfBuzz and FreeType library) +# FreeType library and possibly HarfBuzz library) # TextureTools - TextureTools library # GlxApplication - GLX application (depends on X11 libraries) # XEglApplication - X/EGL application (depends on EGL and X11 libraries) diff --git a/src/Text/CMakeLists.txt b/src/Text/CMakeLists.txt index 26f254e3f..c97dcaed0 100644 --- a/src/Text/CMakeLists.txt +++ b/src/Text/CMakeLists.txt @@ -1,7 +1,10 @@ find_package(Freetype REQUIRED) -find_package(HarfBuzz REQUIRED) +include_directories(${FREETYPE_INCLUDE_DIRS}) -include_directories(${FREETYPE_INCLUDE_DIRS} ${HARFBUZZ_INCLUDE_DIRS}) +if(USE_HARFBUZZ) + find_package(HarfBuzz REQUIRED) + include_directories(${HARFBUZZ_INCLUDE_DIRS}) +endif() set(MagnumText_SRCS Font.cpp @@ -17,7 +20,10 @@ set(MagnumText_HEADERS add_library(MagnumText SHARED ${MagnumText_SRCS}) -target_link_libraries(MagnumText Magnum MagnumTextureTools ${FREETYPE_LIBRARIES} ${HARFBUZZ_LIBRARIES}) +target_link_libraries(MagnumText Magnum MagnumTextureTools ${FREETYPE_LIBRARIES}) +if(USE_HARFBUZZ) + target_link_libraries(MagnumText ${HARFBUZZ_LIBRARIES}) +endif() install(TARGETS MagnumText DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) install(FILES ${MagnumText_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Text) diff --git a/src/Text/Font.cpp b/src/Text/Font.cpp index fccfc62e3..1b77e1442 100644 --- a/src/Text/Font.cpp +++ b/src/Text/Font.cpp @@ -18,7 +18,9 @@ #include #include #include FT_FREETYPE_H +#ifdef MAGNUM_USE_HARFBUZZ #include +#endif #include #include "Extensions.h" @@ -42,8 +44,10 @@ Font::Font(FontRenderer& renderer, const unsigned char* data, std::size_t dataSi void Font::finishConstruction() { CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Set_Char_Size(_ftFont, 0, _size*64, 100, 100) == 0); + #ifdef MAGNUM_USE_HARFBUZZ /* Create Harfbuzz font */ _hbFont = hb_ft_font_create(_ftFont, nullptr); + #endif #ifndef MAGNUM_TARGET_GLES MAGNUM_ASSERT_EXTENSION_SUPPORTED(Extensions::GL::ARB::texture_rg); @@ -126,18 +130,26 @@ void Font::prerender(const std::string& characters, const Vector2i& atlasSize) { void Font::destroy() { if(!_ftFont) return; + #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), _hbFont(other._hbFont), _size(other._size) { +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(); } @@ -147,7 +159,9 @@ Font& Font::operator=(Font&& other) { 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(); diff --git a/src/Text/Font.h b/src/Text/Font.h index 1c12d55f2..208b6d0db 100644 --- a/src/Text/Font.h +++ b/src/Text/Font.h @@ -122,8 +122,12 @@ class MAGNUM_TEXT_EXPORT Font { /** @brief %Font texture atlas */ inline Texture2D& texture() { return _texture; } - /** @brief HarfBuzz font handle */ + /** @brief Font handle */ + #ifdef MAGNUM_USE_HARFBUZZ inline hb_font_t* font() { return _hbFont; } + #else + inline FT_Face font() { return _ftFont; } + #endif private: void MAGNUM_TEXT_LOCAL finishConstruction(); @@ -133,8 +137,10 @@ class MAGNUM_TEXT_EXPORT Font { std::unordered_map> glyphs; Texture2D _texture; FT_Face _ftFont; - hb_font_t* _hbFont; GLfloat _size; + #ifdef MAGNUM_USE_HARFBUZZ + hb_font_t* _hbFont; + #endif }; }} diff --git a/src/Text/TextRenderer.cpp b/src/Text/TextRenderer.cpp index 355043860..4e54b86d7 100644 --- a/src/Text/TextRenderer.cpp +++ b/src/Text/TextRenderer.cpp @@ -15,7 +15,13 @@ #include "TextRenderer.h" +#ifdef MAGNUM_USE_HARFBUZZ #include +#else +#include +#include FT_FREETYPE_H +#include +#endif #include "Math/Point2D.h" #include "Math/Point3D.h" @@ -36,20 +42,33 @@ class TextLayouter { ~TextLayouter(); - inline std::uint32_t glyphCount() { return _glyphCount; } + inline std::uint32_t glyphCount() { + #ifdef MAGNUM_USE_HARFBUZZ + return _glyphCount; + #else + return glyphs.size(); + #endif + } std::tuple renderGlyph(const Vector2& cursorPosition, const std::uint32_t i); private: + #ifdef MAGNUM_USE_HARFBUZZ const Font& font; - const GLfloat size; hb_buffer_t* buffer; hb_glyph_info_t* glyphInfo; hb_glyph_position_t* glyphPositions; std::uint32_t _glyphCount; + #else + Font& font; + std::vector glyphs; + #endif + + const GLfloat size; }; TextLayouter::TextLayouter(Font& font, const GLfloat size, const std::string& text): font(font), size(size) { + #ifdef MAGNUM_USE_HARFBUZZ /* Prepare HarfBuzz buffer */ buffer = hb_buffer_create(); hb_buffer_set_direction(buffer, HB_DIRECTION_LTR); @@ -62,23 +81,46 @@ TextLayouter::TextLayouter(Font& font, const GLfloat size, const std::string& te glyphInfo = hb_buffer_get_glyph_infos(buffer, &_glyphCount); glyphPositions = hb_buffer_get_glyph_positions(buffer, &_glyphCount); + #else + /* Get glyph codes from characters */ + glyphs.reserve(text.size()+1); + for(std::size_t i = 0; i != text.size(); ) { + std::uint32_t codepoint; + std::tie(codepoint, i) = Corrade::Utility::Unicode::nextChar(text, i); + glyphs.push_back(FT_Get_Char_Index(font.font(), codepoint)); + } + #endif } TextLayouter::~TextLayouter() { + #ifdef MAGNUM_USE_HARFBUZZ /* Destroy HarfBuzz buffer */ hb_buffer_destroy(buffer); + #endif } std::tuple TextLayouter::renderGlyph(const Vector2& cursorPosition, const std::uint32_t i) { /* Position of the texture in the resulting glyph, texture coordinates */ Rectangle texturePosition, textureCoordinates; + #ifdef MAGNUM_USE_HARFBUZZ std::tie(texturePosition, textureCoordinates) = font[glyphInfo[i].codepoint]; + #else + std::tie(texturePosition, textureCoordinates) = font[glyphs[i]]; + #endif + #ifdef MAGNUM_USE_HARFBUZZ /* 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()); + #else + /* Load glyph */ + CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Load_Glyph(font.font(), glyphs[i], FT_LOAD_DEFAULT) == 0); + const FT_GlyphSlot slot = font.font()->glyph; + Vector2 offset = Vector2(0, 0); /** @todo really? */ + Vector2 advance = Vector2(slot->advance.x, slot->advance.y)/(64*font.size()); + #endif /* Absolute quad position, composed from cursor position, glyph offset and texture position, denormalized to requested text size */ diff --git a/src/magnumConfigure.h.cmake b/src/magnumConfigure.h.cmake index 18f0ef842..61279ff38 100644 --- a/src/magnumConfigure.h.cmake +++ b/src/magnumConfigure.h.cmake @@ -2,3 +2,4 @@ #cmakedefine MAGNUM_TARGET_GLES2 #cmakedefine MAGNUM_TARGET_DESKTOP_GLES #cmakedefine MAGNUM_TARGET_NACL +#cmakedefine MAGNUM_USE_HARFBUZZ