diff --git a/yg/glyph_cache.cpp b/yg/glyph_cache.cpp index 72b72021ce..c274b38de1 100644 --- a/yg/glyph_cache.cpp +++ b/yg/glyph_cache.cpp @@ -41,6 +41,40 @@ namespace yg return l.m_color < r.m_color; } + GlyphInfo::GlyphInfo() + {} + + GlyphInfo::~GlyphInfo() + {} + + struct FTGlyphInfo : public GlyphInfo + { + FTC_Node m_node; + FTC_Manager m_manager; + + FTGlyphInfo(FTC_Node node, FTC_Manager manager) + : m_node(node), m_manager(manager) + {} + + ~FTGlyphInfo() + { + FTC_Node_Unref(m_node, m_manager); + } + }; + + struct FTStrokedGlyphInfo : GlyphInfo + { + FT_Glyph m_glyph; + + FTStrokedGlyphInfo(FT_Glyph glyph) : m_glyph(glyph) + {} + + ~FTStrokedGlyphInfo() + { + FT_Done_Glyph(m_glyph); + } + }; + GlyphCache::Params::Params(char const * blocksFile, char const * whiteListFile, char const * blackListFile, size_t maxSize) : m_blocksFile(blocksFile), m_whiteListFile(whiteListFile), m_blackListFile(blackListFile), m_maxSize(maxSize) {} @@ -171,6 +205,9 @@ namespace yg }; FT_Glyph glyph = 0; + FTC_Node node; + + GlyphInfo * info = 0; if (key.m_isMask) { @@ -180,10 +217,12 @@ namespace yg FT_LOAD_DEFAULT, charIDX.second, &glyph, - 0 + &node )); FTCHECK(FT_Glyph_Stroke(&glyph, m_impl->m_stroker, 0)); FTCHECK(FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, 0, 1)); + + info = new FTStrokedGlyphInfo(glyph); } else { @@ -193,12 +232,13 @@ namespace yg FT_LOAD_DEFAULT | FT_LOAD_RENDER, charIDX.second, &glyph, - 0 + &node )); - } - FT_BitmapGlyph bitmapGlyph = (FT_BitmapGlyph)glyph; - shared_ptr info(new GlyphInfo()); + info = new FTGlyphInfo(node, m_impl->m_manager); + } + + FT_BitmapGlyph bitmapGlyph = (FT_BitmapGlyph)glyph; info->m_metrics.m_height = bitmapGlyph ? bitmapGlyph->bitmap.rows : 0; info->m_metrics.m_width = bitmapGlyph ? bitmapGlyph->bitmap.width : 0; @@ -208,18 +248,15 @@ namespace yg info->m_metrics.m_yAdvance = bitmapGlyph ? int(bitmapGlyph->root.advance.y >> 16) : 0; info->m_color = key.m_color; + info->m_bitmapData = 0; + info->m_bitmapPitch = 0; + if ((info->m_metrics.m_width != 0) && (info->m_metrics.m_height != 0)) { - info->m_bitmap.resize(info->m_metrics.m_width * info->m_metrics.m_height * sizeof(DATA_TRAITS::pixel_t)); + info->m_bitmapData = bitmapGlyph->bitmap.buffer; + info->m_bitmapPitch = bitmapGlyph->bitmap.pitch; - DATA_TRAITS::view_t dstView = gil::interleaved_view( - info->m_metrics.m_width, - info->m_metrics.m_height, - (DATA_TRAITS::pixel_t*)&info->m_bitmap[0], - info->m_metrics.m_width * sizeof(DATA_TRAITS::pixel_t) - ); - - gil::gray8c_view_t srcView = gil::interleaved_view( +/* gil::gray8c_view_t srcView = gil::interleaved_view( info->m_metrics.m_width, info->m_metrics.m_height, (gil::gray8_pixel_t*)bitmapGlyph->bitmap.buffer, @@ -238,13 +275,10 @@ namespace yg { gil::get_color(c, gil::alpha_t()) = srcView(x, y) / DATA_TRAITS::channelScaleFactor; dstView(x, y) = c; - } + }*/ } - if (key.m_isMask) - FT_Done_Glyph(glyph); - - return info; + return make_shared_ptr(info); } double GlyphCache::getTextLength(double fontSize, string const & text) @@ -260,12 +294,4 @@ namespace yg return len; } - void GlyphInfo::dump(const char * /*fileName */) - { -/* gil::lodepng_write_view(fileName, - gil::interleaved_view(m_width, - m_height, - (DATA_TRAITS::pixel_t*)&m_bitmap[0], - m_width * sizeof(DATA_TRAITS::pixel_t)));*/ - } } diff --git a/yg/glyph_cache.hpp b/yg/glyph_cache.hpp index f95274b2f2..e0692057fc 100644 --- a/yg/glyph_cache.hpp +++ b/yg/glyph_cache.hpp @@ -11,7 +11,7 @@ namespace yg { - /// glyph metrics + /// metrics of the single glyph struct GlyphMetrics { int m_xAdvance; @@ -25,11 +25,23 @@ namespace yg /// full info about single glyph struct GlyphInfo { + private: + + /// copying is prohibited + GlyphInfo(GlyphInfo const &); + GlyphInfo & operator=(GlyphInfo const &); + + public: + GlyphMetrics m_metrics; yg::Color m_color; - vector m_bitmap; - void dump(char const * fileName); + /// glyph bitmap in 8bpp grayscale format + unsigned char * m_bitmapData; + int m_bitmapPitch; + + GlyphInfo(); + virtual ~GlyphInfo(); }; struct GlyphKey diff --git a/yg/skin_page.cpp b/yg/skin_page.cpp index d4d879f0aa..f3dd63604d 100644 --- a/yg/skin_page.cpp +++ b/yg/skin_page.cpp @@ -645,16 +645,33 @@ namespace yg if ((gi->m_metrics.m_width != 0) && (gi->m_metrics.m_height != 0)) { - TDynamicTexture::const_view_t srcView = gil::interleaved_view( + gil::gray8c_view_t srcView = gil::interleaved_view( + gi->m_metrics.m_width, + gi->m_metrics.m_height, + (gil::gray8_pixel_t*)gi->m_bitmapData, + gi->m_bitmapPitch + ); + +/* TDynamicTexture::const_view_t srcView = gil::interleaved_view( gi->m_metrics.m_width, gi->m_metrics.m_height, (TDynamicTexture::pixel_t*)&gi->m_bitmap[0], gi->m_metrics.m_width * sizeof(TDynamicTexture::pixel_t) - ); + );*/ + + DATA_TRAITS::pixel_t c; + + gil::get_color(c, gil::red_t()) = gi->m_color.r / DATA_TRAITS::channelScaleFactor; + gil::get_color(c, gil::green_t()) = gi->m_color.g / DATA_TRAITS::channelScaleFactor; + gil::get_color(c, gil::blue_t()) = gi->m_color.b / DATA_TRAITS::channelScaleFactor; + gil::get_color(c, gil::alpha_t()) = gi->m_color.a / DATA_TRAITS::channelScaleFactor; for (size_t y = 2; y < rect.SizeY() - 2; ++y) for (size_t x = 2; x < rect.SizeX() - 2; ++x) - v(x, y) = srcView(x - 2, y - 2); + { + gil::get_color(c, gil::alpha_t()) = srcView(x - 2, y - 2) / DATA_TRAITS::channelScaleFactor; + v(x, y) = c; + } } dynTexture->upload(&v(0, 0), rect);