@@ -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,52 @@ 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  ( //  fixed sized bitmaps
440+         ((bd_font_data->FtFace ->face_flags  & FT_FACE_FLAG_FIXED_SIZES) != 0 ) &&
441+         ((bd_font_data->UserFlags  & ImGuiFreeTypeLoaderFlags_Bitmap) != 0 ) &&
442+         ((bd_font_data->FtFace ->face_flags  & FT_FACE_FLAG_SCALABLE) == 0 )
443+     ) {
444+         IM_ASSERT (bd_font_data->FtFace ->num_fixed_sizes  > 0 );
445+ 
446+         //  loop over sizes and pick the closest, larger (or better equal) size
447+         int  best_index = 0 ;
448+         FT_Short best_height = bd_font_data->FtFace ->available_sizes [best_index].y_ppem  / FT_SCALEFACTOR;
449+         for  (int  i = 1 ; i < bd_font_data->FtFace ->num_fixed_sizes ; i++) {
450+             const  auto  cur_height = bd_font_data->FtFace ->available_sizes [i].y_ppem  / FT_SCALEFACTOR;
451+             //  TODO: is this overkill
452+             //  TODO: is-float-close with epsilon param would be nice, maybe
453+             if  (ImFabs (cur_height - size) < 0 .001f ) {
454+                 best_index = i;
455+                 break ;
456+             } else  if  (cur_height < size) {
457+                 if  (best_height < cur_height) {
458+                     best_index = i;
459+                     best_height = cur_height;
460+                 }
461+             } else  { //  >
462+                 if  (best_height > cur_height) {
463+                     best_index = i;
464+                     best_height = cur_height;
465+                 }
466+             }
467+         }
468+         // fprintf(stderr, "!!!!! selecting bitmap index: %zu, with height %d for size %f\n", best_index, best_height, size);
469+         FT_Select_Size (bd_font_data->FtFace , best_index);
470+     } else  {
471+         //  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'
472+         //  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.
473+         //  FT_Set_Pixel_Sizes() doesn't seem to get us the same result."
474+         //  (FT_Set_Pixel_Sizes() essentially calls FT_Request_Size() with FT_SIZE_REQUEST_TYPE_NOMINAL)
475+ 
476+         FT_Size_RequestRec req;
477+         req.type  = (bd_font_data->UserFlags  & ImGuiFreeTypeLoaderFlags_Bitmap) ? FT_SIZE_REQUEST_TYPE_NOMINAL : FT_SIZE_REQUEST_TYPE_REAL_DIM;
478+         req.width  = 0 ;
479+         req.height  = (uint32_t )(size * FT_SCALEFACTOR * rasterizer_density);
480+         req.horiResolution  = 0 ;
481+         req.vertResolution  = 0 ;
482+         FT_Request_Size (bd_font_data->FtFace , &req);
483+     }
451484
452485    //  Output
453486    if  (src->MergeMode  == false )
@@ -496,7 +529,16 @@ static bool ImGui_ImplFreeType_FontBakedLoadGlyph(ImFontAtlas* atlas, ImFontConf
496529
497530    FT_Face face = bd_font_data->FtFace ;
498531    FT_GlyphSlot slot = face->glyph ;
499-     const  float  rasterizer_density = src->RasterizerDensity  * baked->RasterizerDensity ;
532+     float  bitmap_density = 1 .f ;
533+     if  (
534+         ((face->face_flags  & FT_FACE_FLAG_FIXED_SIZES) != 0 ) &&
535+         ((bd_font_data->UserFlags  & ImGuiFreeTypeLoaderFlags_Bitmap) != 0 ) &&
536+         ((face->face_flags  & FT_FACE_FLAG_SCALABLE) == 0 )
537+     ) {
538+         //  scale fixed size bitmap to target size
539+         bitmap_density = float (bd_font_data->FtFace ->size ->metrics .y_ppem ) / baked->Size ;
540+     }
541+     const  float  rasterizer_density = src->RasterizerDensity  * baked->RasterizerDensity  * bitmap_density;
500542
501543    //  Load metrics only mode
502544    const  float  advance_x = (slot->advance .x  / FT_SCALEFACTOR) / rasterizer_density;
0 commit comments