[aseprite] 61/196: Add a simple cache system for glyphs
Tobias Hansen
thansen at moszumanska.debian.org
Wed Apr 20 18:50:01 UTC 2016
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 <davidcapello at gmail.com>
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
More information about the Pkg-games-commits
mailing list