@@ -108,7 +108,7 @@ static FT_Error ImGuiLunasvgPortPresetSlot(FT_GlyphSlot slot, FT_Bool cache, FT_
108108// -------------------------------------------------------------------------
109109
110110#define  FT_CEIL (X )      (((X + 63 ) & -64 ) / 64 ) //  From SDL_ttf: Handy routines for converting from fixed point
111- #define  FT_SCALEFACTOR   64 .0f 
111+ #define  FT_SCALEFACTOR   64 .0f                     //  For converting from/to 26.6 factionals 
112112
113113//  Glyph metrics:
114114//  --------------
@@ -435,19 +435,58 @@ static bool ImGui_ImplFreeType_FontBakedInit(ImFontAtlas* atlas, ImFontConfig* s
435435
436436    FT_New_Size (bd_font_data->FtFace , &bd_baked_data->FtSize );
437437    FT_Activate_Size (bd_baked_data->FtSize );
438- 
439-     //  Vuhdo 2017: "I'm not sure how to deal with font sizes properly. As far as I understand, currently ImGui assumes that the 'pixel_height'
440-     //  is a maximum height of an any given glyph, i.e. it's the sum of font's ascender and descender. Seems strange to me.
441-     //  FT_Set_Pixel_Sizes() doesn't seem to get us the same result."
442-     //  (FT_Set_Pixel_Sizes() essentially calls FT_Request_Size() with FT_SIZE_REQUEST_TYPE_NOMINAL)
443438    const  float  rasterizer_density = src->RasterizerDensity  * baked->RasterizerDensity ;
444-     FT_Size_RequestRec req;
445-     req.type  = (bd_font_data->UserFlags  & ImGuiFreeTypeLoaderFlags_Bitmap) ? FT_SIZE_REQUEST_TYPE_NOMINAL : FT_SIZE_REQUEST_TYPE_REAL_DIM;
446-     req.width  = 0 ;
447-     req.height  = (uint32_t )(size * 64  * rasterizer_density);
448-     req.horiResolution  = 0 ;
449-     req.vertResolution  = 0 ;
450-     FT_Request_Size (bd_font_data->FtFace , &req);
439+     if  (((bd_font_data->FtFace ->face_flags  & FT_FACE_FLAG_FIXED_SIZES) != 0 ) && ((bd_font_data->FtFace ->face_flags  & FT_FACE_FLAG_SCALABLE) == 0 ) && ((bd_font_data->UserFlags  & ImGuiFreeTypeLoaderFlags_Bitmap) != 0 ))
440+     {
441+         IM_ASSERT (bd_font_data->FtFace ->num_fixed_sizes  > 0 );
442+ 
443+         //  Loop over sizes and pick the closest, larger (or better equal) size.
444+         int  best_index = 0 ;
445+         float  best_height = bd_font_data->FtFace ->available_sizes [best_index].y_ppem  / FT_SCALEFACTOR;
446+         for  (int  i = 1 ; i < bd_font_data->FtFace ->num_fixed_sizes ; i++)
447+         {
448+             const  float  cur_height = bd_font_data->FtFace ->available_sizes [i].y_ppem  / FT_SCALEFACTOR;
449+             //  TODO: is this overkill?
450+             //  TODO: is-float-close with epsilon param would be nice, maybe
451+             if  (ImFabs (cur_height - size) < 0 .001f )
452+             {
453+                 best_index = i;
454+                 break ;
455+             }
456+             else  if  (cur_height < size)
457+             {
458+                 if  (best_height < cur_height)
459+                 {
460+                     best_index = i;
461+                     best_height = cur_height;
462+                 }
463+             }
464+             else 
465+             {
466+                 if  (best_height > cur_height)
467+                 {
468+                     best_index = i;
469+                     best_height = cur_height;
470+                 }
471+             }
472+         }
473+         FT_Select_Size (bd_font_data->FtFace , best_index);
474+     }
475+     else 
476+     {
477+         //  Vuhdo 2017: "I'm not sure how to deal with font sizes properly. As far as I understand, currently ImGui assumes that the 'pixel_height'
478+         //  is a maximum height of an any given glyph, i.e. it's the sum of font's ascender and descender. Seems strange to me.
479+         //  FT_Set_Pixel_Sizes() doesn't seem to get us the same result."
480+         //  (FT_Set_Pixel_Sizes() essentially calls FT_Request_Size() with FT_SIZE_REQUEST_TYPE_NOMINAL)
481+ 
482+         FT_Size_RequestRec req;
483+         req.type  = (bd_font_data->UserFlags  & ImGuiFreeTypeLoaderFlags_Bitmap) ? FT_SIZE_REQUEST_TYPE_NOMINAL : FT_SIZE_REQUEST_TYPE_REAL_DIM;
484+         req.width  = 0 ;
485+         req.height  = (uint32_t )(size * FT_SCALEFACTOR * rasterizer_density);
486+         req.horiResolution  = 0 ;
487+         req.vertResolution  = 0 ;
488+         FT_Request_Size (bd_font_data->FtFace , &req);
489+     }
451490
452491    //  Output
453492    if  (src->MergeMode  == false )
@@ -496,7 +535,13 @@ static bool ImGui_ImplFreeType_FontBakedLoadGlyph(ImFontAtlas* atlas, ImFontConf
496535
497536    FT_Face face = bd_font_data->FtFace ;
498537    FT_GlyphSlot slot = face->glyph ;
499-     const  float  rasterizer_density = src->RasterizerDensity  * baked->RasterizerDensity ;
538+     float  bitmap_density = 1 .f ;
539+     if  (((face->face_flags  & FT_FACE_FLAG_FIXED_SIZES) != 0 ) && ((face->face_flags  & FT_FACE_FLAG_SCALABLE) == 0 ) && ((bd_font_data->UserFlags  & ImGuiFreeTypeLoaderFlags_Bitmap) != 0 ))
540+     {
541+         //  scale fixed size bitmap to target size
542+         bitmap_density = (float )bd_font_data->FtFace ->size ->metrics .y_ppem  / baked->Size ;
543+     }
544+     const  float  rasterizer_density = src->RasterizerDensity  * baked->RasterizerDensity  * bitmap_density;
500545
501546    //  Load metrics only mode
502547    const  float  advance_x = (slot->advance .x  / FT_SCALEFACTOR) / rasterizer_density;
0 commit comments