This is an automated email from the git hooks/post-receive script. thansen pushed a commit to branch master in repository aseprite.
commit 2fd94ed884250a837a846d5323f475dabbc01217 Author: David Capello <[email protected]> Date: Tue Mar 15 15:15:37 2016 -0300 Simplify ft::Face API Changes: * Added ft::FaceBase to create a future Face impl with HarfBuzz as text shaping engine * Define ft::FaceBase::Glyph as the parameter given to the forEachGlyph parameter * forEachGlyph and calcTextBounds * Remove operator FT_Face (we can use FaceBase::isValid() to know if the face isn't null) --- src/app/util/freetype_utils.cpp | 20 ++++----- src/ft/face.h | 93 +++++++++++++++++++++++++--------------- src/she/common/freetype_font.cpp | 10 +++-- src/she/common/generic_surface.h | 56 +++++++++++++++--------- 4 files changed, 109 insertions(+), 70 deletions(-) diff --git a/src/app/util/freetype_utils.cpp b/src/app/util/freetype_utils.cpp index 69c4b66..ca095a8 100644 --- a/src/app/util/freetype_utils.cpp +++ b/src/app/util/freetype_utils.cpp @@ -11,7 +11,6 @@ #include "app/util/freetype_utils.h" -#include "base/string.h" #include "base/unique_ptr.h" #include "doc/blend_funcs.h" #include "doc/blend_internals.h" @@ -34,14 +33,13 @@ doc::Image* render_text(const std::string& fontfile, int fontsize, ft::Lib ft; ft::Face face(ft.open(fontfile)); - if (face) { + if (face.isValid()) { // Set font size face.setSize(fontsize); face.setAntialias(antialias); // Calculate text size - base::utf8_const_iterator begin(text.begin()), end(text.end()); - gfx::Rect bounds = face.calcTextBounds(begin, end); + gfx::Rect bounds = face.calcTextBounds(text); // Render the image and copy it to the clipboard if (!bounds.isEmpty()) { @@ -49,16 +47,16 @@ doc::Image* render_text(const std::string& fontfile, int fontsize, doc::clear_image(image, 0); face.forEachGlyph( - begin, end, - [&bounds, &image, color, antialias](FT_BitmapGlyph glyph, int x) { - int t, yimg = - bounds.y - glyph->top; + text, + [&bounds, &image, color, antialias](const ft::Face::Glyph& glyph) { + int t, yimg = - bounds.y + int(glyph.y); - 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->left; + for (int v=0; v<int(glyph.bitmap->rows); ++v, ++yimg) { + const uint8_t* p = glyph.bitmap->buffer + v*glyph.bitmap->pitch; + int ximg = - bounds.x + int(glyph.x); int bit = 0; - for (int u=0; u<(int)glyph->bitmap.width; ++u, ++ximg) { + for (int u=0; u<int(glyph.bitmap->width); ++u, ++ximg) { int alpha; if (antialias) { diff --git a/src/ft/face.h b/src/ft/face.h index 0abfed4..437e85b 100644 --- a/src/ft/face.h +++ b/src/ft/face.h @@ -9,6 +9,7 @@ #pragma once #include "base/disable_copying.h" +#include "base/string.h" #include "ft/freetype_headers.h" #include "gfx/rect.h" @@ -17,19 +18,23 @@ namespace ft { template<typename Cache> - class FaceT { + class FaceBase { public: - FaceT(FT_Face face = nullptr) : m_face(face) { + struct Glyph { + FT_UInt glyph_index; + FT_Bitmap* bitmap; + double x; + double y; + }; + + FaceBase(FT_Face face) : m_face(face) { } - ~FaceT() { + ~FaceBase() { if (m_face) FT_Done_Face(m_face); } - operator FT_Face() { return m_face; } - FT_Face operator->() { return m_face; } - bool isValid() const { return (m_face != nullptr); } @@ -48,56 +53,74 @@ namespace ft { m_cache.invalidate(); } - template<typename Iterator, - typename Callback> - void forEachGlyph(Iterator first, Iterator end, Callback callback) { - bool use_kerning = (FT_HAS_KERNING(m_face) ? true: false); + protected: + FT_Face m_face; + bool m_antialias; + Cache m_cache; + + private: + DISABLE_COPYING(FaceBase); + }; + + template<typename Cache> + class FaceFT : public FaceBase<Cache> { + public: + FaceFT(FT_Face face) + : FaceBase<Cache>(face) { + } + template<typename Callback> + void forEachGlyph(const std::string& str, Callback callback) { + bool use_kerning = (FT_HAS_KERNING(m_face) ? true: false); FT_UInt prev_glyph = 0; - int x = 0; - for (; first != end; ++first) { - FT_UInt glyph_index = m_cache.getGlyphIndex(m_face, *first); + double x = 0, y = 0; + + auto it = base::utf8_const_iterator(str.begin()); + auto end = base::utf8_const_iterator(str.end()); + for (; it != end; ++it) { + FT_UInt glyph_index = m_cache.getGlyphIndex(m_face, *it); if (use_kerning && prev_glyph && glyph_index) { FT_Vector kerning; FT_Get_Kerning(m_face, prev_glyph, glyph_index, FT_KERNING_DEFAULT, &kerning); - x += kerning.x >> 6; + x += kerning.x / 64.0; } - FT_Glyph glyph = m_cache.loadGlyph(m_face, glyph_index, m_antialias); - if (glyph) { - callback((FT_BitmapGlyph)glyph, x); - x += glyph->advance.x >> 16; - m_cache.doneGlyph(glyph); + FT_Glyph bitmapGlyph = m_cache.loadGlyph(m_face, glyph_index, m_antialias); + if (bitmapGlyph) { + Glyph glyph; + glyph.glyph_index = glyph_index; + glyph.bitmap = &FT_BitmapGlyph(bitmapGlyph)->bitmap; + glyph.x = x + FT_BitmapGlyph(bitmapGlyph)->left; + glyph.y = y - FT_BitmapGlyph(bitmapGlyph)->top; + + callback(glyph); + + x += bitmapGlyph->advance.x / double(1 << 16); + y += bitmapGlyph->advance.y / double(1 << 16); + + m_cache.doneGlyph(bitmapGlyph); } prev_glyph = glyph_index; } } - template<typename Iterator> - gfx::Rect calcTextBounds(Iterator first, Iterator end) { + gfx::Rect calcTextBounds(const std::string& str) { gfx::Rect bounds(0, 0, 0, 0); forEachGlyph( - first, end, - [&bounds](FT_BitmapGlyph glyph, int x) { - bounds |= gfx::Rect(x + glyph->left, - -glyph->top, - glyph->bitmap.width, - glyph->bitmap.rows); + str, + [&bounds](Glyph& glyph) { + bounds |= gfx::Rect(int(glyph.x), + int(glyph.y), + glyph.bitmap->width, + glyph.bitmap->rows); }); return bounds; } - - private: - FT_Face m_face; - bool m_antialias; - Cache m_cache; - - DISABLE_COPYING(FaceT); }; class NoCache { @@ -180,7 +203,7 @@ namespace ft { std::map<FT_UInt, FT_Glyph> m_glyphMap; }; - typedef FaceT<SimpleCache> Face; + typedef FaceFT<SimpleCache> Face; } // namespace ft diff --git a/src/she/common/freetype_font.cpp b/src/she/common/freetype_font.cpp index ca9d3c5..0ed2662 100644 --- a/src/she/common/freetype_font.cpp +++ b/src/she/common/freetype_font.cpp @@ -10,6 +10,7 @@ #include "she/common/freetype_font.h" +#include "base/string.h" #include "gfx/point.h" #include "gfx/size.h" @@ -45,17 +46,20 @@ FontType FreeTypeFont::type() int FreeTypeFont::height() const { static std::string str = "Tgjp"; - return m_face.calcTextBounds(str.begin(), str.end()).h; + return m_face.calcTextBounds(str).h; } int FreeTypeFont::charWidth(int chr) const { - return m_face.calcTextBounds(&chr, (&chr)+1).w; + // TODO avoid creating a temporary string + std::wstring tmp; + tmp.push_back(chr); + return m_face.calcTextBounds(base::to_utf8(tmp)).w; } int FreeTypeFont::textLength(const std::string& str) const { - return m_face.calcTextBounds(str.begin(), str.end()).w; + return m_face.calcTextBounds(str).w; } bool FreeTypeFont::isScalable() const diff --git a/src/she/common/generic_surface.h b/src/she/common/generic_surface.h index 69c5a22..051e7a6 100644 --- a/src/she/common/generic_surface.h +++ b/src/she/common/generic_surface.h @@ -140,34 +140,52 @@ public: bool antialias = ttFont->face().antialias(); int fg_alpha = gfx::geta(fg); - gfx::Rect bounds = - ttFont->face().calcTextBounds(str.begin(), str.end()); + gfx::Rect bounds = ttFont->face().calcTextBounds(str); + gfx::Rect clipBounds = static_cast<Base*>(this)->getClipBounds(); she::SurfaceFormatData fd; static_cast<Base*>(this)->getFormat(&fd); - gfx::Rect clip = static_cast<Base*>(this)->getClipBounds(); - ttFont->face().forEachGlyph( - str.begin(), str.end(), - [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; + str, + [this, x, y, fg, fg_alpha, bg, antialias, &clipBounds, &bounds, &fd](const ft::Face::Glyph& glyph) { + gfx::Rect origDstBounds(x - bounds.x + int(glyph.x), + y - bounds.y + int(glyph.y), + int(glyph.bitmap->width), + int(glyph.bitmap->rows)); + gfx::Rect dstBounds = origDstBounds; + dstBounds &= clipBounds; + if (dstBounds.isEmpty()) + return; + + int clippedRows = dstBounds.y - origDstBounds.y; + int dst_y = dstBounds.y; int t; - - for (int v=0; v<(int)glyph->bitmap.rows; ++v, ++dst_y) { - const uint8_t* p = glyph->bitmap.buffer + v*glyph->bitmap.pitch; + for (int v=0; v<dstBounds.h; ++v, ++dst_y) { int bit = 0; - int dst_x = x + local_x - bounds.x + glyph->left; - - if (!clip.contains(gfx::Point(dst_x, dst_y))) - break; - + const uint8_t* p = glyph.bitmap->buffer + + (v+clippedRows)*glyph.bitmap->pitch; + int dst_x = dstBounds.x; uint32_t* dst_address = (uint32_t*)static_cast<Base*>(this)->getData(dst_x, dst_y); - for (int u=0; u<(int)glyph->bitmap.width; ++u) { - int alpha; + // Skip first clipped pixels + for (int u=0; u<dstBounds.x-origDstBounds.x; ++u) { + if (antialias) { + ++p; + } + else { + if (bit == 8) { + bit = 0; + ++p; + } + } + } + + for (int u=0; u<dstBounds.w; ++u, ++dst_x) { + ASSERT(clipBounds.contains(gfx::Point(dst_x, dst_y))); + int alpha; if (antialias) { alpha = *(p++); } @@ -202,10 +220,6 @@ public: ((gfx::getb(output) << fd.blueShift ) & fd.blueMask ) | ((gfx::geta(output) << fd.alphaShift) & fd.alphaMask); - ++dst_x; - if (dst_x >= clip.x2()) - break; - ++dst_address; } } -- 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

