This is an automated email from the git hooks/post-receive script. thansen pushed a commit to branch master in repository aseprite.
commit dbf5d69219403341dd549a19ed47322d8650c5b7 Author: David Capello <[email protected]> Date: Mon Mar 14 12:09:45 2016 -0300 Add a simple cache system for glyphs --- src/app/util/freetype_utils.cpp | 6 +-- src/ft/face.h | 86 +++++++++++++++++++++++++++++++++------- src/ft/freetype_headers.h | 1 + src/she/common/generic_surface.h | 8 ++-- 4 files changed, 80 insertions(+), 21 deletions(-) diff --git a/src/app/util/freetype_utils.cpp b/src/app/util/freetype_utils.cpp index 6187ba0..69c4b66 100644 --- a/src/app/util/freetype_utils.cpp +++ b/src/app/util/freetype_utils.cpp @@ -50,12 +50,12 @@ doc::Image* render_text(const std::string& fontfile, int fontsize, face.forEachGlyph( begin, end, - [&bounds, &image, color, antialias](FT_GlyphSlot glyph, int x) { - int t, yimg = - bounds.y - glyph->bitmap_top; + [&bounds, &image, color, antialias](FT_BitmapGlyph glyph, int x) { + int t, yimg = - bounds.y - glyph->top; for (int v=0; v<(int)glyph->bitmap.rows; ++v, ++yimg) { const uint8_t* p = glyph->bitmap.buffer + v*glyph->bitmap.pitch; - int ximg = x - bounds.x + glyph->bitmap_left; + int ximg = x - bounds.x + glyph->left; int bit = 0; for (int u=0; u<(int)glyph->bitmap.width; ++u, ++ximg) { diff --git a/src/ft/face.h b/src/ft/face.h index 19657bb..0abfed4 100644 --- a/src/ft/face.h +++ b/src/ft/face.h @@ -12,6 +12,8 @@ #include "ft/freetype_headers.h" #include "gfx/rect.h" +#include <map> + namespace ft { template<typename Cache> @@ -63,10 +65,11 @@ namespace ft { x += kerning.x >> 6; } - FT_GlyphSlot glyph = m_cache.loadGlyph(m_face, glyph_index, m_antialias); + FT_Glyph glyph = m_cache.loadGlyph(m_face, glyph_index, m_antialias); if (glyph) { - callback(glyph, x); - x += glyph->advance.x >> 6; + callback((FT_BitmapGlyph)glyph, x); + x += glyph->advance.x >> 16; + m_cache.doneGlyph(glyph); } prev_glyph = glyph_index; @@ -79,11 +82,11 @@ namespace ft { forEachGlyph( first, end, - [&bounds](FT_GlyphSlot glyph, int x) { - bounds |= gfx::Rect(x + glyph->bitmap_left, - -glyph->bitmap_top, - (int)glyph->bitmap.width, - (int)glyph->bitmap.rows); + [&bounds](FT_BitmapGlyph glyph, int x) { + bounds |= gfx::Rect(x + glyph->left, + -glyph->top, + glyph->bitmap.width, + glyph->bitmap.rows); }); return bounds; @@ -107,22 +110,77 @@ namespace ft { return FT_Get_Char_Index(face, charCode); } - FT_GlyphSlot loadGlyph(FT_Face face, FT_UInt glyphIndex, bool antialias) { + FT_Glyph loadGlyph(FT_Face face, FT_UInt glyphIndex, bool antialias) { FT_Error err = FT_Load_Glyph( face, glyphIndex, FT_LOAD_RENDER | - FT_LOAD_NO_BITMAP | (antialias ? FT_LOAD_TARGET_NORMAL: FT_LOAD_TARGET_MONO)); - if (!err) - return face->glyph; - else + if (err) + return nullptr; + + FT_Glyph glyph; + err = FT_Get_Glyph(face->glyph, &glyph); + if (err) return nullptr; + + if (glyph->format != FT_GLYPH_FORMAT_BITMAP) { + err = FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, 0, 1); + if (!err) { + FT_Done_Glyph(glyph); + return nullptr; + } + } + + return glyph; + } + + void doneGlyph(FT_Glyph glyph) { + FT_Done_Glyph(glyph); + } + + }; + + class SimpleCache : public NoCache { + public: + ~SimpleCache() { + invalidate(); } + void invalidate() { + for (auto& it : m_glyphMap) + FT_Done_Glyph(it.second); + + m_glyphMap.clear(); + } + + FT_Glyph loadGlyph(FT_Face face, FT_UInt glyphIndex, bool antialias) { + auto it = m_glyphMap.find(glyphIndex); + if (it != m_glyphMap.end()) + return it->second; + + FT_Glyph glyph = NoCache::loadGlyph(face, glyphIndex, antialias); + if (glyph) { + FT_Glyph newGlyph = nullptr; + FT_Glyph_Copy(glyph, &newGlyph); + if (newGlyph) { + m_glyphMap[glyphIndex] = newGlyph; + FT_Done_Glyph(glyph); + return newGlyph; + } + } + return glyph; + } + + void doneGlyph(FT_Glyph glyph) { + // Do nothing + } + + private: + std::map<FT_UInt, FT_Glyph> m_glyphMap; }; - typedef FaceT<NoCache> Face; + typedef FaceT<SimpleCache> Face; } // namespace ft diff --git a/src/ft/freetype_headers.h b/src/ft/freetype_headers.h index eeb196b..b7a5147 100644 --- a/src/ft/freetype_headers.h +++ b/src/ft/freetype_headers.h @@ -8,6 +8,7 @@ #define FT_FREETYPE_HEADERS_H_INCLUDED #pragma once +#include "freetype/ftglyph.h" #include "ft2build.h" #include FT_FREETYPE_H diff --git a/src/she/common/generic_surface.h b/src/she/common/generic_surface.h index cafd1fd..ff2f195 100644 --- a/src/she/common/generic_surface.h +++ b/src/she/common/generic_surface.h @@ -149,14 +149,14 @@ public: ttFont->face().forEachGlyph( str.begin(), str.end(), - [&](FT_GlyphSlot glyph, int local_x) { + [this, x, y, fg, fg_alpha, bg, antialias, &clip, &bounds, &fd](FT_BitmapGlyph glyph, int local_x) { + int dst_y = y - bounds.y - glyph->top; int t; - for (int v=0; v<(int)glyph->bitmap.rows; ++v) { + for (int v=0; v<(int)glyph->bitmap.rows; ++v, ++dst_y) { const uint8_t* p = glyph->bitmap.buffer + v*glyph->bitmap.pitch; int bit = 0; - int dst_x = x + local_x - bounds.x + glyph->bitmap_left; - int dst_y = y - bounds.y - glyph->bitmap_top + v; + int dst_x = x + local_x - bounds.x + glyph->left; if (!clip.contains(gfx::Point(dst_x, dst_y))) break; -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/aseprite.git _______________________________________________ Pkg-games-commits mailing list [email protected] http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-games-commits

