16
16
17
17
NS_AX_EXT_BEGIN
18
18
19
+
19
20
namespace
20
21
{
21
22
uint32_t fourccValue (std::string_view str)
@@ -367,17 +368,13 @@ void ImGuiPresenter::loadCustomFonts(void* ud)
367
368
auto contentZoomFactor = thiz->_contentZoomFactor ;
368
369
for (auto & fontInfo : thiz->_fontsInfoMap )
369
370
{
370
- const ImWchar* imChars = nullptr ;
371
- switch (fontInfo.second .glyphRange )
372
- {
373
- case CHS_GLYPH_RANGE::GENERAL:
374
- imChars = imFonts->GetGlyphRangesChineseSimplifiedCommon ();
375
- break ;
376
- case CHS_GLYPH_RANGE::FULL:
377
- imChars = imFonts->GetGlyphRangesChineseFull ();
378
- break ;
379
- default :;
380
- }
371
+ auto & imChars = fontInfo.second .glyphRanges ;
372
+ // if the user has explicitly called `removeGlyphRanges` or replaced with new ranges
373
+ if (imChars && !thiz->_usedGlyphRanges .contains ((uintptr_t )imChars))
374
+ imChars = nullptr ;
375
+
376
+ if (imChars == nullptr && thiz->_glyphRanges .contains (fontInfo.second .glyphRangesId ))
377
+ imChars = thiz->_glyphRanges .at (fontInfo.second .glyphRangesId ).data ();
381
378
382
379
auto fontData = FileUtils::getInstance ()->getDataFromFile (fontInfo.first );
383
380
AXASSERT (!fontData.isNull (), " Cannot load font for IMGUI" );
@@ -388,6 +385,8 @@ void ImGuiPresenter::loadCustomFonts(void* ud)
388
385
imFonts->AddFontFromMemoryTTF (buffer, bufferSize, fontInfo.second .fontSize * contentZoomFactor, nullptr ,
389
386
imChars);
390
387
}
388
+ // the temporary bucket gets emptied out
389
+ thiz->_eraseGlyphRanges .clear ();
391
390
}
392
391
393
392
float ImGuiPresenter::enableDPIScale (float userScale)
@@ -424,11 +423,54 @@ void ImGuiPresenter::setViewResolution(float width, float height)
424
423
ImGui_ImplAx_SetViewResolution (width, height);
425
424
}
426
425
427
- void ImGuiPresenter::addFont (std::string_view fontFile, float fontSize, CHS_GLYPH_RANGE glyphRange)
426
+ void ImGuiPresenter::addFont (std::string_view fontFile, float fontSize, GLYPH_RANGES glyphRange)
427
+ {
428
+ addGlyphRanges (glyphRange);
429
+ std::string_view glyphId = getGlyphRangesId (glyphRange);
430
+ addFont (fontFile, fontSize, glyphId);
431
+ }
432
+
433
+ void ImGuiPresenter::addFont (std::string_view fontFile, float fontSize, std::string_view glyphRangeId)
434
+ {
435
+ auto it = _glyphRanges.find (glyphRangeId);
436
+ if (it == _glyphRanges.end ())
437
+ {
438
+ addFont (fontFile, fontSize, std::vector<ImWchar>(0 ));
439
+ return ;
440
+ }
441
+
442
+ if (FileUtils::getInstance ()->isFileExistInternal (fontFile))
443
+ {
444
+ ImWchar* imChars = it->second .data ();
445
+
446
+ bool isDirty = _fontsInfoMap.emplace (fontFile, FontInfo{fontSize, imChars, std::string (glyphRangeId)}).second ;
447
+ isDirty |=
448
+ _usedGlyphRanges.emplace ((uintptr_t )imChars).second || _fontsInfoMap.at (fontFile).glyphRanges != imChars;
449
+ if (isDirty)
450
+ ImGui_ImplAx_SetDeviceObjectsDirty ();
451
+ }
452
+ }
453
+
454
+ void ImGuiPresenter::addFont (std::string_view fontFile, float fontSize, const std::vector<ImWchar>& glyphRanges)
455
+ {
456
+ addFont (fontFile, fontSize, fontFile, glyphRanges);
457
+ }
458
+
459
+ void ImGuiPresenter::addFont (std::string_view fontFile,
460
+ float fontSize,
461
+ std::string_view glyphRangesId,
462
+ const std::vector<ImWchar>& glyphRanges)
428
463
{
429
464
if (FileUtils::getInstance ()->isFileExistInternal (fontFile))
430
465
{
431
- if (_fontsInfoMap.emplace (fontFile, FontInfo{fontSize, glyphRange}).second )
466
+ ImWchar* imChars = nullptr ;
467
+ if (!glyphRanges.empty ())
468
+ imChars = addGlyphRanges (glyphRangesId, glyphRanges);
469
+
470
+ bool isDirty = _fontsInfoMap.emplace (fontFile, FontInfo{fontSize, imChars, std::string (glyphRangesId)}).second ;
471
+ isDirty |= imChars && (_usedGlyphRanges.emplace ((uintptr_t )imChars).second ||
472
+ _fontsInfoMap.at (fontFile).glyphRanges != imChars);
473
+ if (isDirty)
432
474
ImGui_ImplAx_SetDeviceObjectsDirty ();
433
475
}
434
476
}
@@ -853,18 +895,110 @@ void ImGuiPresenter::setLabelColor(Label* label, ImGuiCol col)
853
895
setLabelColor (label, ImGui::GetStyleColorVec4 (col));
854
896
}
855
897
898
+ ImWchar* ImGuiPresenter::addGlyphRanges (GLYPH_RANGES glyphRange)
899
+ {
900
+ static std::unordered_map<GLYPH_RANGES, size_t > _glyph_ranges_size;
901
+ auto imFonts = ImGui::GetIO ().Fonts ;
902
+ const ImWchar* imChars;
903
+
904
+ switch (glyphRange)
905
+ {
906
+ case GLYPH_RANGES::DEFAULT:
907
+ imChars = imFonts->GetGlyphRangesDefault ();
908
+ break ;
909
+ case GLYPH_RANGES::GREEK:
910
+ imChars = imFonts->GetGlyphRangesGreek ();
911
+ break ;
912
+ case GLYPH_RANGES::KOREAN:
913
+ imChars = imFonts->GetGlyphRangesKorean ();
914
+ break ;
915
+ case GLYPH_RANGES::CHINESE_GENERAL:
916
+ imChars = imFonts->GetGlyphRangesChineseSimplifiedCommon ();
917
+ break ;
918
+ case GLYPH_RANGES::CHINESE_FULL:
919
+ imChars = imFonts->GetGlyphRangesChineseFull ();
920
+ break ;
921
+ case GLYPH_RANGES::JAPANESE:
922
+ imChars = imFonts->GetGlyphRangesJapanese ();
923
+ break ;
924
+ case GLYPH_RANGES::CYRILLIC:
925
+ imChars = imFonts->GetGlyphRangesCyrillic ();
926
+ break ;
927
+ case GLYPH_RANGES::THAI:
928
+ imChars = imFonts->GetGlyphRangesThai ();
929
+ break ;
930
+ case GLYPH_RANGES::VIETNAMESE:
931
+ imChars = imFonts->GetGlyphRangesVietnamese ();
932
+ break ;
933
+ default :
934
+ return nullptr ;
935
+ }
936
+
937
+ size_t imCharsSize = 0 ;
938
+ if (_glyph_ranges_size.contains (glyphRange))
939
+ imCharsSize = _glyph_ranges_size[glyphRange];
940
+ else
941
+ {
942
+ // must always end with 0
943
+ while (imChars[imCharsSize] != 0 )
944
+ imCharsSize++;
945
+ imCharsSize += 1 ;
946
+ _glyph_ranges_size[glyphRange] = imCharsSize;
947
+ }
948
+ auto glyphId = getGlyphRangesId (glyphRange);
949
+
950
+ return addGlyphRanges (glyphId, std::vector<ImWchar>(imChars, imChars + imCharsSize));
951
+ }
952
+
856
953
ImWchar* ImGuiPresenter::addGlyphRanges (std::string_view key, const std::vector<ImWchar>& ranges)
857
954
{
858
- auto it = glyphRanges.find (key);
859
- // the pointer must be persistant, do not replace
860
- if (it != glyphRanges.end ())
861
- return it->second .data ();
862
- it = glyphRanges.emplace (key, ranges).first ; // glyphRanges[key] = ranges;
955
+ auto it = _glyphRanges.find (key);
956
+ // store in our temporary bucket if already exists...
957
+ if (it != _glyphRanges.end ())
958
+ {
959
+ // so that `loadCustomFonts` can look for the new "replaced" glyph ranges
960
+ _usedGlyphRanges.erase ((uintptr_t )it->second .data ());
961
+ // probably automatically gets *moved* but to make our intention more clear
962
+ _eraseGlyphRanges.push_back (std::move (it->second ));
963
+ }
964
+ it = _glyphRanges.emplace (key, ranges).first ; // _glyphRanges[key] = ranges;
863
965
if (ranges.empty ())
864
966
it->second .push_back (0 );
967
+ // the `addFont` will call `ImGui_ImplAx_SetDeviceObjectsDirty` if everything is okay,
968
+ // no need to call it if no font is using the glyph ranges...
865
969
return it->second .data ();
866
970
}
867
971
972
+ void ImGuiPresenter::removeGlyphRanges (std::string_view key)
973
+ {
974
+ auto removeGlyphRange = _glyphRanges.find (key);
975
+ if (removeGlyphRange == _glyphRanges.end ())
976
+ return ;
977
+
978
+ auto usedCount = _usedGlyphRanges.size ();
979
+ _usedGlyphRanges.erase ((uintptr_t )removeGlyphRange->second .data ());
980
+ _eraseGlyphRanges.push_back (std::move (removeGlyphRange->second ));
981
+ _glyphRanges.erase (key);
982
+
983
+ // update the fonts to not use the glyph ranges since user wants to remove it for some reason..
984
+ if (_usedGlyphRanges.size () != usedCount)
985
+ ImGui_ImplAx_SetDeviceObjectsDirty ();
986
+ }
987
+
988
+ void ImGuiPresenter::clearGlyphRanges ()
989
+ {
990
+ auto usedCount = _usedGlyphRanges.size ();
991
+ for (auto & glyphRange : _glyphRanges)
992
+ {
993
+ _usedGlyphRanges.erase ((uintptr_t )glyphRange.second .data ());
994
+ _eraseGlyphRanges.push_back (std::move (glyphRange.second ));
995
+ }
996
+ _glyphRanges.clear ();
997
+
998
+ if (_usedGlyphRanges.size () != usedCount)
999
+ ImGui_ImplAx_SetDeviceObjectsDirty ();
1000
+ }
1001
+
868
1002
void ImGuiPresenter::mergeFontGlyphs (ImFont* dst, ImFont* src, ImWchar start, ImWchar end)
869
1003
{
870
1004
if (!dst || !src || start > end)
@@ -901,4 +1035,31 @@ int ImGuiPresenter::getCCRefId(Object* p)
901
1035
return (int )hash;
902
1036
}
903
1037
1038
+ std::string_view ImGuiPresenter::getGlyphRangesId (GLYPH_RANGES glyphRanges)
1039
+ {
1040
+ switch (glyphRanges)
1041
+ {
1042
+ case GLYPH_RANGES::DEFAULT:
1043
+ return GLYPH_RANGES_DEFAULT_ID;
1044
+ case GLYPH_RANGES::GREEK:
1045
+ return GLYPH_RANGES_GREEK_ID;
1046
+ case GLYPH_RANGES::KOREAN:
1047
+ return GLYPH_RANGES_KOREAN_ID;
1048
+ case GLYPH_RANGES::CHINESE_GENERAL:
1049
+ return GLYPH_RANGES_CHINESE_GENERAL_ID;
1050
+ case GLYPH_RANGES::CHINESE_FULL:
1051
+ return GLYPH_RANGES_CHINESE_FULL_ID;
1052
+ case GLYPH_RANGES::JAPANESE:
1053
+ return GLYPH_RANGES_JAPANESE_ID;
1054
+ case GLYPH_RANGES::CYRILLIC:
1055
+ return GLYPH_RANGES_CYRILLIC_ID;
1056
+ case GLYPH_RANGES::THAI:
1057
+ return GLYPH_RANGES_THAI_ID;
1058
+ case GLYPH_RANGES::VIETNAMESE:
1059
+ return GLYPH_RANGES_VIETNAMESE_ID;
1060
+ default :
1061
+ return " " ;
1062
+ }
1063
+ }
1064
+
904
1065
NS_AX_EXT_END
0 commit comments