@ -2285,8 +2285,11 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
if ( src_tmp . GlyphsCount = = 0 )
if ( src_tmp . GlyphsCount = = 0 )
continue ;
continue ;
// When merging fonts with MergeMode=true:
// - We can have multiple input fonts writing into a same destination font.
// - dst_font->ConfigData is != from cfg which is our source configuration.
ImFontConfig & cfg = atlas - > ConfigData [ src_i ] ;
ImFontConfig & cfg = atlas - > ConfigData [ src_i ] ;
ImFont * dst_font = cfg . DstFont ; // We can have multiple input fonts writing into a same destination font (when using MergeMode=true)
ImFont * dst_font = cfg . DstFont ;
const float font_scale = stbtt_ScaleForPixelHeight ( & src_tmp . FontInfo , cfg . SizePixels ) ;
const float font_scale = stbtt_ScaleForPixelHeight ( & src_tmp . FontInfo , cfg . SizePixels ) ;
int unscaled_ascent , unscaled_descent , unscaled_line_gap ;
int unscaled_ascent , unscaled_descent , unscaled_line_gap ;
@ -2300,20 +2303,13 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
for ( int glyph_i = 0 ; glyph_i < src_tmp . GlyphsCount ; glyph_i + + )
for ( int glyph_i = 0 ; glyph_i < src_tmp . GlyphsCount ; glyph_i + + )
{
{
// Register glyph
const int codepoint = src_tmp . GlyphsList [ glyph_i ] ;
const int codepoint = src_tmp . GlyphsList [ glyph_i ] ;
const stbtt_packedchar & pc = src_tmp . PackedChars [ glyph_i ] ;
const stbtt_packedchar & pc = src_tmp . PackedChars [ glyph_i ] ;
const float char_advance_x_org = pc . xadvance ;
const float char_advance_x_mod = ImClamp ( char_advance_x_org , cfg . GlyphMinAdvanceX , cfg . GlyphMaxAdvanceX ) ;
float char_off_x = font_off_x ;
if ( char_advance_x_org ! = char_advance_x_mod )
char_off_x + = cfg . PixelSnapH ? ImFloor ( ( char_advance_x_mod - char_advance_x_org ) * 0.5f ) : ( char_advance_x_mod - char_advance_x_org ) * 0.5f ;
// Register glyph
stbtt_aligned_quad q ;
stbtt_aligned_quad q ;
float dummy_x = 0.0f , dummy_y = 0.0f ;
float dummy_x = 0.0f , dummy_y = 0.0f ;
stbtt_GetPackedQuad ( src_tmp . PackedChars , atlas - > TexWidth , atlas - > TexHeight , glyph_i , & dummy_x , & dummy_y , & q , 0 ) ;
stbtt_GetPackedQuad ( src_tmp . PackedChars , atlas - > TexWidth , atlas - > TexHeight , glyph_i , & dummy_x , & dummy_y , & q , 0 ) ;
dst_font - > AddGlyph ( ( ImWchar ) codepoint , q . x0 + char _off_x, q . y0 + font_off_y , q . x1 + char _off_x, q . y1 + font_off_y , q . s0 , q . t0 , q . s1 , q . t1 , char_advance_x_mod ) ;
dst_font - > AddGlyph ( & cfg , ( ImWchar ) codepoint , q . x0 + font_off_x , q . y0 + font_off_y , q . x1 + font_off_x , q . y1 + font_off_y , q . s0 , q . t0 , q . s1 , q . t1 , pc . xadvance ) ;
}
}
}
}
@ -2468,10 +2464,11 @@ void ImFontAtlasBuildFinish(ImFontAtlas* atlas)
if ( r - > Font = = NULL | | r - > GlyphID = = 0 )
if ( r - > Font = = NULL | | r - > GlyphID = = 0 )
continue ;
continue ;
// Will ignore ImFontConfig settings: GlyphMinAdvanceX, GlyphMinAdvanceY, GlyphExtraSpacing, PixelSnapH
IM_ASSERT ( r - > Font - > ContainerAtlas = = atlas ) ;
IM_ASSERT ( r - > Font - > ContainerAtlas = = atlas ) ;
ImVec2 uv0 , uv1 ;
ImVec2 uv0 , uv1 ;
atlas - > CalcCustomRectUV ( r , & uv0 , & uv1 ) ;
atlas - > CalcCustomRectUV ( r , & uv0 , & uv1 ) ;
r - > Font - > AddGlyph ( ( ImWchar ) r - > GlyphID , r - > GlyphOffset . x , r - > GlyphOffset . y , r - > GlyphOffset . x + r - > Width , r - > GlyphOffset . y + r - > Height , uv0 . x , uv0 . y , uv1 . x , uv1 . y , r - > GlyphAdvanceX ) ;
r - > Font - > AddGlyph ( NULL , ( ImWchar ) r - > GlyphID , r - > GlyphOffset . x , r - > GlyphOffset . y , r - > GlyphOffset . x + r - > Width , r - > GlyphOffset . y + r - > Height , uv0 . x , uv0 . y , uv1 . x , uv1 . y , r - > GlyphAdvanceX ) ;
}
}
// Build all fonts lookup tables
// Build all fonts lookup tables
@ -2881,8 +2878,29 @@ void ImFont::GrowIndex(int new_size)
// x0/y0/x1/y1 are offset from the character upper-left layout position, in pixels. Therefore x0/y0 are often fairly close to zero.
// x0/y0/x1/y1 are offset from the character upper-left layout position, in pixels. Therefore x0/y0 are often fairly close to zero.
// Not to be mistaken with texture coordinates, which are held by u0/v0/u1/v1 in normalized format (0.0..1.0 on each texture axis).
// Not to be mistaken with texture coordinates, which are held by u0/v0/u1/v1 in normalized format (0.0..1.0 on each texture axis).
void ImFont : : AddGlyph ( ImWchar codepoint , float x0 , float y0 , float x1 , float y1 , float u0 , float v0 , float u1 , float v1 , float advance_x )
// 'cfg' is not necessarily == 'this->ConfigData' because multiple source fonts+configs can be used to build one target font.
void ImFont : : AddGlyph ( ImFontConfig * cfg , ImWchar codepoint , float x0 , float y0 , float x1 , float y1 , float u0 , float v0 , float u1 , float v1 , float advance_x )
{
{
if ( cfg ! = NULL )
{
// Clamp & recenter if needed
const float advance_x_original = advance_x ;
advance_x = ImClamp ( advance_x , cfg - > GlyphMinAdvanceX , cfg - > GlyphMaxAdvanceX ) ;
if ( advance_x ! = advance_x_original )
{
float char_off_x = cfg - > PixelSnapH ? ImFloor ( ( advance_x - advance_x_original ) * 0.5f ) : ( advance_x - advance_x_original ) * 0.5f ;
x0 + = char_off_x ;
x1 + = char_off_x ;
}
// Snap to pixel
if ( cfg - > PixelSnapH )
advance_x = IM_ROUND ( advance_x ) ;
// Bake spacing
advance_x + = cfg - > GlyphExtraSpacing . x ;
}
Glyphs . resize ( Glyphs . Size + 1 ) ;
Glyphs . resize ( Glyphs . Size + 1 ) ;
ImFontGlyph & glyph = Glyphs . back ( ) ;
ImFontGlyph & glyph = Glyphs . back ( ) ;
glyph . Codepoint = ( unsigned int ) codepoint ;
glyph . Codepoint = ( unsigned int ) codepoint ;
@ -2895,14 +2913,13 @@ void ImFont::AddGlyph(ImWchar codepoint, float x0, float y0, float x1, float y1,
glyph . V0 = v0 ;
glyph . V0 = v0 ;
glyph . U1 = u1 ;
glyph . U1 = u1 ;
glyph . V1 = v1 ;
glyph . V1 = v1 ;
glyph . AdvanceX = advance_x + ConfigData - > GlyphExtraSpacing . x ; // Bake spacing into AdvanceX
glyph . AdvanceX = advance_x ;
if ( ConfigData - > PixelSnapH )
glyph . AdvanceX = IM_ROUND ( glyph . AdvanceX ) ;
// Compute rough surface usage metrics (+1 to account for average padding, +0.99 to round)
// Compute rough surface usage metrics (+1 to account for average padding, +0.99 to round)
// We use (U1-U0)*TexWidth instead of X1-X0 to account for oversampling.
float pad = ContainerAtlas - > TexGlyphPadding + 0.99f ;
DirtyLookupTables = true ;
DirtyLookupTables = true ;
MetricsTotalSurface + = ( int ) ( ( glyph . U1 - glyph . U0 ) * ContainerAtlas - > TexWidth + 1.99f ) * ( int ) ( ( glyph . V1 - glyph . V0 ) * ContainerAtlas - > TexHeight + 1.99f ) ;
MetricsTotalSurface + = ( int ) ( ( glyph . U1 - glyph . U0 ) * ContainerAtlas - > TexWidth + pad ) * ( int ) ( ( glyph . V1 - glyph . V0 ) * ContainerAtlas - > TexHeight + pad ) ;
}
}
void ImFont : : AddRemapChar ( ImWchar dst , ImWchar src , bool overwrite_dst )
void ImFont : : AddRemapChar ( ImWchar dst , ImWchar src , bool overwrite_dst )