forked from organicmaps/organicmaps
added getGlyphMetrics function.
This commit is contained in:
parent
60ad2be527
commit
b301b209c1
7 changed files with 111 additions and 25 deletions
|
@ -37,10 +37,12 @@ namespace yg
|
|||
m_impl->m_fonts.push_back(make_shared_ptr(new Font(fileName)));
|
||||
}
|
||||
|
||||
shared_ptr<GlyphInfo> const GlyphCache::getGlyph(GlyphKey const & key)
|
||||
int GlyphCache::getCharIDX(GlyphKey const & key)
|
||||
{
|
||||
Font * font = m_impl->m_fonts.back().get();
|
||||
|
||||
FTC_FaceID faceID = reinterpret_cast<FTC_FaceID>(font);
|
||||
|
||||
FTC_ScalerRec fontScaler =
|
||||
{
|
||||
faceID,
|
||||
|
@ -75,6 +77,67 @@ namespace yg
|
|||
);
|
||||
}
|
||||
|
||||
return charIDX;
|
||||
}
|
||||
|
||||
GlyphMetrics const GlyphCache::getGlyphMetrics(GlyphKey const & key)
|
||||
{
|
||||
Font * font = m_impl->m_fonts.back().get();
|
||||
|
||||
FTC_FaceID faceID = reinterpret_cast<FTC_FaceID>(font);
|
||||
|
||||
FTC_ScalerRec fontScaler =
|
||||
{
|
||||
faceID,
|
||||
key.m_fontSize,
|
||||
key.m_fontSize,
|
||||
1,
|
||||
0,
|
||||
0
|
||||
};
|
||||
|
||||
int charIDX = getCharIDX(key);
|
||||
|
||||
FT_Glyph glyph = 0;
|
||||
|
||||
FTCHECK(FTC_ImageCache_LookupScaler(
|
||||
m_impl->m_glyphMetricsCache,
|
||||
&fontScaler,
|
||||
FT_LOAD_DEFAULT,
|
||||
charIDX,
|
||||
&glyph,
|
||||
0));
|
||||
|
||||
FT_BBox cbox;
|
||||
FT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_PIXELS, &cbox);
|
||||
|
||||
GlyphMetrics m =
|
||||
{
|
||||
glyph->advance.x >> 16,
|
||||
glyph->advance.y >> 16,
|
||||
cbox.xMin, cbox.yMin,
|
||||
cbox.xMax - cbox.xMin, cbox.yMax - cbox.yMin
|
||||
};
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
shared_ptr<GlyphInfo> const GlyphCache::getGlyph(GlyphKey const & key)
|
||||
{
|
||||
Font * font = m_impl->m_fonts.back().get();
|
||||
FTC_FaceID faceID = reinterpret_cast<FTC_FaceID>(font);
|
||||
FTC_ScalerRec fontScaler =
|
||||
{
|
||||
faceID,
|
||||
key.m_fontSize,
|
||||
key.m_fontSize,
|
||||
1,
|
||||
0,
|
||||
0
|
||||
};
|
||||
|
||||
int charIDX = getCharIDX(key);
|
||||
|
||||
FT_Glyph glyph = 0;
|
||||
//FTC_Node glyphNode;
|
||||
|
||||
|
@ -97,31 +160,37 @@ namespace yg
|
|||
0
|
||||
));
|
||||
|
||||
/// glyph could appear in cache from getGlyphMetrics method,
|
||||
/// so we should explicitly check this situation
|
||||
// if (glyph.format == FT_GLYPH_FORMAT_OUTLINE)
|
||||
// FTCHECK(FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, 0, 1));
|
||||
|
||||
FT_BitmapGlyph bitmapGlyph = (FT_BitmapGlyph)glyph;
|
||||
|
||||
shared_ptr<GlyphInfo> info(new GlyphInfo());
|
||||
|
||||
info->m_height = bitmapGlyph ? bitmapGlyph->bitmap.rows : 0;
|
||||
info->m_width = bitmapGlyph ? bitmapGlyph->bitmap.width : 0;
|
||||
info->m_xOffset = bitmapGlyph ? bitmapGlyph->left : 0;
|
||||
info->m_yOffset = bitmapGlyph ? bitmapGlyph->top - info->m_height : 0;
|
||||
info->m_xAdvance = bitmapGlyph ? int(bitmapGlyph->root.advance.x >> 16) : 0;
|
||||
info->m_metrics.m_height = bitmapGlyph ? bitmapGlyph->bitmap.rows : 0;
|
||||
info->m_metrics.m_width = bitmapGlyph ? bitmapGlyph->bitmap.width : 0;
|
||||
info->m_metrics.m_xOffset = bitmapGlyph ? bitmapGlyph->left : 0;
|
||||
info->m_metrics.m_yOffset = bitmapGlyph ? bitmapGlyph->top - info->m_metrics.m_height : 0;
|
||||
info->m_metrics.m_xAdvance = bitmapGlyph ? int(bitmapGlyph->root.advance.x >> 16) : 0;
|
||||
info->m_metrics.m_yAdvance = bitmapGlyph ? int(bitmapGlyph->root.advance.y >> 16) : 0;
|
||||
info->m_color = key.m_isMask ? yg::Color(255, 255, 255, 0) : yg::Color(0, 0, 0, 0);
|
||||
|
||||
if ((info->m_width != 0) && (info->m_height != 0))
|
||||
if ((info->m_metrics.m_width != 0) && (info->m_metrics.m_height != 0))
|
||||
{
|
||||
info->m_bitmap.resize(info->m_width * info->m_height * sizeof(DATA_TRAITS::pixel_t));
|
||||
info->m_bitmap.resize(info->m_metrics.m_width * info->m_metrics.m_height * sizeof(DATA_TRAITS::pixel_t));
|
||||
|
||||
DATA_TRAITS::view_t dstView = gil::interleaved_view(
|
||||
info->m_width,
|
||||
info->m_height,
|
||||
info->m_metrics.m_width,
|
||||
info->m_metrics.m_height,
|
||||
(DATA_TRAITS::pixel_t*)&info->m_bitmap[0],
|
||||
info->m_width * sizeof(DATA_TRAITS::pixel_t)
|
||||
info->m_metrics.m_width * sizeof(DATA_TRAITS::pixel_t)
|
||||
);
|
||||
|
||||
gil::gray8c_view_t srcView = gil::interleaved_view(
|
||||
info->m_width,
|
||||
info->m_height,
|
||||
info->m_metrics.m_width,
|
||||
info->m_metrics.m_height,
|
||||
(gil::gray8_pixel_t*)bitmapGlyph->bitmap.buffer,
|
||||
bitmapGlyph->bitmap.pitch
|
||||
);
|
||||
|
|
|
@ -5,15 +5,20 @@
|
|||
|
||||
namespace yg
|
||||
{
|
||||
struct GlyphInfo
|
||||
struct GlyphMetrics
|
||||
{
|
||||
int m_xAdvance;
|
||||
int m_yAdvance;
|
||||
int m_xOffset;
|
||||
int m_yOffset;
|
||||
int m_width;
|
||||
int m_height;
|
||||
yg::Color m_color;
|
||||
};
|
||||
|
||||
struct GlyphInfo
|
||||
{
|
||||
GlyphMetrics m_metrics;
|
||||
yg::Color m_color;
|
||||
vector<unsigned char> m_bitmap;
|
||||
|
||||
void dump(char const * fileName);
|
||||
|
@ -44,6 +49,10 @@ namespace yg
|
|||
void reset();
|
||||
void addFont(char const * fileName);
|
||||
|
||||
int getCharIDX(GlyphKey const & key);
|
||||
|
||||
shared_ptr<GlyphInfo> const getGlyph(GlyphKey const & key);
|
||||
/// return control box(could be slightly larger than the precise bound box).
|
||||
GlyphMetrics const getGlyphMetrics(GlyphKey const & key);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ namespace yg
|
|||
FTCHECK(FTC_Manager_New(m_lib, 3, 10, maxSize, &RequestFace, 0, &m_manager));
|
||||
|
||||
FTCHECK(FTC_ImageCache_New(m_manager, &m_normalGlyphCache));
|
||||
FTCHECK(FTC_ImageCache_New(m_manager, &m_glyphMetricsCache));
|
||||
|
||||
/// Initializing stroker
|
||||
FTCHECK(FT_Stroker_New(m_lib, &m_stroker));
|
||||
|
|
|
@ -29,6 +29,7 @@ namespace yg
|
|||
|
||||
FTC_Manager m_manager;
|
||||
|
||||
FTC_ImageCache m_glyphMetricsCache;
|
||||
FTC_ImageCache m_strokedGlyphCache;
|
||||
FTC_ImageCache m_normalGlyphCache;
|
||||
|
||||
|
|
|
@ -151,6 +151,11 @@ namespace yg
|
|||
return m_glyphCache.getGlyph(key);
|
||||
}
|
||||
|
||||
GlyphMetrics const ResourceManager::getGlyphMetrics(GlyphKey const & key)
|
||||
{
|
||||
return m_glyphCache.getGlyphMetrics(key);
|
||||
}
|
||||
|
||||
void ResourceManager::addFont(char const * fileName)
|
||||
{
|
||||
m_glyphCache.addFont(fileName);
|
||||
|
|
|
@ -61,6 +61,7 @@ namespace yg
|
|||
void freeTexture(shared_ptr<gl::BaseTexture> const & texture, bool doSignal = false);
|
||||
|
||||
shared_ptr<GlyphInfo> const getGlyph(GlyphKey const & key);
|
||||
GlyphMetrics const getGlyphMetrics(GlyphKey const & key);
|
||||
void addFont(char const * fileName);
|
||||
};
|
||||
|
||||
|
|
|
@ -178,8 +178,8 @@ namespace yg
|
|||
|
||||
shared_ptr<GlyphInfo> gi = m_resourceManager->getGlyph(g);
|
||||
|
||||
m2::Packer::handle_t handle = m_packer.pack(gi->m_width + 4,
|
||||
gi->m_height + 4);
|
||||
m2::Packer::handle_t handle = m_packer.pack(gi->m_metrics.m_width + 4,
|
||||
gi->m_metrics.m_height + 4);
|
||||
|
||||
m2::RectU texRect = m_packer.find(handle).second;
|
||||
m_glyphUploadCommands.push_back(GlyphUploadCmd(gi, texRect));
|
||||
|
@ -188,9 +188,9 @@ namespace yg
|
|||
m_styles[handle] = boost::shared_ptr<ResourceStyle>(
|
||||
new CharStyle(texRect,
|
||||
m_pageID,
|
||||
gi->m_xOffset,
|
||||
gi->m_yOffset,
|
||||
gi->m_xAdvance));
|
||||
gi->m_metrics.m_xOffset,
|
||||
gi->m_metrics.m_yOffset,
|
||||
gi->m_metrics.m_xAdvance));
|
||||
|
||||
return m_glyphMap[g];
|
||||
}
|
||||
|
@ -198,7 +198,7 @@ namespace yg
|
|||
bool SkinPage::hasRoom(GlyphKey const & gk) const
|
||||
{
|
||||
shared_ptr<GlyphInfo> gi = m_resourceManager->getGlyph(gk);
|
||||
return m_packer.hasRoom(gi->m_width + 4, gi->m_height + 4);
|
||||
return m_packer.hasRoom(gi->m_metrics.m_width + 4, gi->m_metrics.m_height + 4);
|
||||
}
|
||||
|
||||
|
||||
|
@ -379,13 +379,13 @@ namespace yg
|
|||
v(rect.SizeX() - 1, y) = pxTranslucent;
|
||||
}
|
||||
|
||||
if ((gi->m_width != 0) && (gi->m_height != 0))
|
||||
if ((gi->m_metrics.m_width != 0) && (gi->m_metrics.m_height != 0))
|
||||
{
|
||||
TDynamicTexture::const_view_t srcView = gil::interleaved_view(
|
||||
gi->m_width,
|
||||
gi->m_height,
|
||||
gi->m_metrics.m_width,
|
||||
gi->m_metrics.m_height,
|
||||
(TDynamicTexture::pixel_t*)&gi->m_bitmap[0],
|
||||
gi->m_width * sizeof(TDynamicTexture::pixel_t)
|
||||
gi->m_metrics.m_width * sizeof(TDynamicTexture::pixel_t)
|
||||
);
|
||||
|
||||
for (size_t y = 2; y < rect.SizeY() - 2; ++y)
|
||||
|
|
Loading…
Add table
Reference in a new issue