diff --git a/addons/imgui-godot/ImGuiGodot/ImGuiGD.cs b/addons/imgui-godot/ImGuiGodot/ImGuiGD.cs
index 9e148661..9b45c5fb 100644
--- a/addons/imgui-godot/ImGuiGodot/ImGuiGD.cs
+++ b/addons/imgui-godot/ImGuiGodot/ImGuiGD.cs
@@ -58,9 +58,28 @@ public static void ResetFonts()
_backend.ResetFonts();
}
- public static void AddFont(FontFile fontData, int fontSize, bool merge = false)
+ public static void AddFont(
+ FontFile fontData,
+ int fontSize,
+ bool merge = false,
+ ushort[]? glyphRanges = null)
{
- _backend.AddFont(fontData, fontSize, merge);
+ _backend.AddFont(fontData, fontSize, merge, glyphRanges);
+ }
+
+ ///
+ /// Add a font using glyph ranges from ImGui.GetIO().Fonts.GetGlyphRanges*()
+ ///
+ /// pointer to an array of ushorts terminated by 0
+ public static unsafe void AddFont(FontFile fontData, int fontSize, bool merge, nint glyphRanges)
+ {
+ ushort* p = (ushort*)glyphRanges;
+ int len = 1;
+ while (p[len++] != 0) ;
+ ushort[] gr = new ushort[len];
+ for (int i = 0; i < len; ++i)
+ gr[i] = p[i];
+ _backend.AddFont(fontData, fontSize, merge, gr);
}
public static void AddFontDefault()
diff --git a/addons/imgui-godot/ImGuiGodot/Internal/BackendNative.cs b/addons/imgui-godot/ImGuiGodot/Internal/BackendNative.cs
index 79d6544f..1f581cd0 100644
--- a/addons/imgui-godot/ImGuiGodot/Internal/BackendNative.cs
+++ b/addons/imgui-godot/ImGuiGodot/Internal/BackendNative.cs
@@ -43,9 +43,19 @@ public bool Visible
set => _gd.Set(PropertyName.Visible, value);
}
- public void AddFont(FontFile fontData, int fontSize, bool merge)
+ public void AddFont(FontFile fontData, int fontSize, bool merge, ushort[]? glyphRanges)
{
- _gd.Call(MethodName.AddFont, fontData, fontSize, merge);
+ if (glyphRanges != null)
+ {
+ int[] gr = new int[glyphRanges.Length];
+ for (int i = 0; i < glyphRanges.Length; ++i)
+ gr[i] = glyphRanges[i];
+ _gd.Call(MethodName.AddFont, fontData, fontSize, merge, gr);
+ }
+ else
+ {
+ _gd.Call(MethodName.AddFont, fontData, fontSize, merge);
+ }
}
public void AddFontDefault()
diff --git a/addons/imgui-godot/ImGuiGodot/Internal/BackendNet.cs b/addons/imgui-godot/ImGuiGodot/Internal/BackendNet.cs
index d1ebb4a1..14762afa 100644
--- a/addons/imgui-godot/ImGuiGodot/Internal/BackendNet.cs
+++ b/addons/imgui-godot/ImGuiGodot/Internal/BackendNet.cs
@@ -26,14 +26,14 @@ public bool Visible
set => ImGuiLayer.Instance.Visible = value;
}
- public void AddFont(FontFile fontData, int fontSize, bool merge)
+ public void AddFont(FontFile fontData, int fontSize, bool merge, ushort[]? glyphRanges)
{
- State.Instance.Fonts.AddFont(fontData, fontSize, merge);
+ State.Instance.Fonts.AddFont(fontData, fontSize, merge, glyphRanges);
}
public void AddFontDefault()
{
- State.Instance.Fonts.AddFont(null, 13, false);
+ State.Instance.Fonts.AddFont(null, 13, false, null);
}
public void Connect(Callable callable)
diff --git a/addons/imgui-godot/ImGuiGodot/Internal/Fonts.cs b/addons/imgui-godot/ImGuiGodot/Internal/Fonts.cs
index a361541f..880c35ed 100644
--- a/addons/imgui-godot/ImGuiGodot/Internal/Fonts.cs
+++ b/addons/imgui-godot/ImGuiGodot/Internal/Fonts.cs
@@ -16,6 +16,7 @@ private sealed class FontParams
public FontFile? Font { get; init; }
public int FontSize { get; init; }
public bool Merge { get; init; }
+ public ushort[]? Ranges { get; init; }
}
private readonly List _fontConfiguration = [];
@@ -32,21 +33,30 @@ public void ResetFonts()
_fontConfiguration.Clear();
}
- public void AddFont(FontFile? fontData, int fontSize, bool merge)
+ public void AddFont(FontFile? fontData, int fontSize, bool merge, ushort[]? ranges)
{
_fontConfiguration.Add(
- new FontParams { Font = fontData, FontSize = fontSize, Merge = merge });
+ new FontParams
+ {
+ Font = fontData,
+ FontSize = fontSize,
+ Merge = merge,
+ Ranges = ranges
+ });
}
- private static unsafe void AddFontToAtlas(FontFile? fontData, int fontSize, bool merge)
+ private static unsafe void AddFontToAtlas(FontParams fp, float scale)
{
+ var io = ImGui.GetIO();
+ int fontSize = (int)(fp.FontSize * scale);
ImFontConfig* fc = ImGuiNative.ImFontConfig_ImFontConfig();
- if (merge)
+
+ if (fp.Merge)
{
fc->MergeMode = 1;
}
- if (fontData == null)
+ if (fp.Font == null)
{
// default font
var fcptr = new ImFontConfigPtr(fc)
@@ -56,28 +66,37 @@ private static unsafe void AddFontToAtlas(FontFile? fontData, int fontSize, bool
OversampleV = 1,
PixelSnapH = true
};
- ImGui.GetIO().Fonts.AddFontDefault(fc);
+ io.Fonts.AddFontDefault(fc);
}
else
{
- ImVector ranges = GetRanges(fontData);
- string name = $"{System.IO.Path.GetFileName(fontData.ResourcePath)}, {fontSize}px";
+ string name = $"{System.IO.Path.GetFileName(fp.Font.ResourcePath)}, {fontSize}px";
for (int i = 0; i < name.Length && i < 40; ++i)
{
fc->Name[i] = Convert.ToByte(name[i]);
}
- int len = fontData.Data.Length;
+ int len = fp.Font.Data.Length;
// let ImGui manage this memory
IntPtr p = ImGui.MemAlloc((uint)len);
- Marshal.Copy(fontData.Data, 0, p, len);
- ImGui.GetIO().Fonts.AddFontFromMemoryTTF(p, len, fontSize, fc, ranges.Data);
+ Marshal.Copy(fp.Font.Data, 0, p, len);
+ if (fp.Ranges == null)
+ {
+ ImVector ranges = GetRanges(fp.Font);
+ io.Fonts.AddFontFromMemoryTTF(p, len, fontSize, fc, ranges.Data);
+ }
+ else
+ {
+ fixed (ushort* pranges = fp.Ranges)
+ {
+ io.Fonts.AddFontFromMemoryTTF(p, len, fontSize, fc, (nint)pranges);
+ }
+ }
}
- if (merge)
- {
- ImGui.GetIO().Fonts.Build();
- }
+ if (fp.Merge)
+ io.Fonts.Build();
+
ImGuiNative.ImFontConfig_destroy(fc);
}
@@ -129,6 +148,8 @@ public unsafe void RebuildFontAtlas(float scale)
{
var io = ImGui.GetIO();
int fontIndex = -1;
+
+ // save current font index
if (io.NativePtr->FontDefault != null)
{
for (int i = 0; i < io.Fonts.Fonts.Size; ++i)
@@ -145,7 +166,7 @@ public unsafe void RebuildFontAtlas(float scale)
foreach (var fontParams in _fontConfiguration)
{
- AddFontToAtlas(fontParams.Font, (int)(fontParams.FontSize * scale), fontParams.Merge);
+ AddFontToAtlas(fontParams, scale);
}
io.Fonts.GetTexDataAsRGBA32(
@@ -163,6 +184,7 @@ public unsafe void RebuildFontAtlas(float scale)
io.Fonts.SetTexID((IntPtr)_fontTexture.GetRid().Id);
io.Fonts.ClearTexData();
+ // maintain selected font when rescaling
if (fontIndex != -1 && fontIndex < io.Fonts.Fonts.Size)
{
io.NativePtr->FontDefault = io.Fonts.Fonts[fontIndex].NativePtr;
diff --git a/addons/imgui-godot/ImGuiGodot/Internal/IBackend.cs b/addons/imgui-godot/ImGuiGodot/Internal/IBackend.cs
index 609e5b33..4cc47178 100644
--- a/addons/imgui-godot/ImGuiGodot/Internal/IBackend.cs
+++ b/addons/imgui-godot/ImGuiGodot/Internal/IBackend.cs
@@ -9,7 +9,7 @@ internal interface IBackend
public float JoyAxisDeadZone { get; set; }
public float Scale { get; set; }
public void ResetFonts();
- public void AddFont(FontFile fontData, int fontSize, bool merge);
+ public void AddFont(FontFile fontData, int fontSize, bool merge, ushort[]? glyphRanges);
public void AddFontDefault();
public void RebuildFontAtlas(float scale);
public void Connect(Callable callable);
diff --git a/gdext/include/imgui-godot.h b/gdext/include/imgui-godot.h
index 9921f8b6..ad15d98e 100644
--- a/gdext/include/imgui-godot.h
+++ b/gdext/include/imgui-godot.h
@@ -31,6 +31,7 @@ using godot::InputEvent;
using godot::JoyButton;
using godot::Key;
using godot::Object;
+using godot::PackedInt32Array;
using godot::Ref;
using godot::Resource;
using godot::RID;
@@ -77,17 +78,26 @@ inline bool GET_IMGUIGD()
inline static void GetAtlasUVs(AtlasTexture* tex, ImVec2& uv0, ImVec2& uv1)
{
+ ERR_FAIL_COND(!tex);
Vector2 atlasSize = tex->get_atlas()->get_size();
uv0 = tex->get_region().get_position() / atlasSize;
uv1 = tex->get_region().get_end() / atlasSize;
}
} // namespace detail
-inline void AddFont(const Ref& fontFile, int fontSize, bool merge = false)
+inline void AddFont(const Ref& fontFile, int fontSize, bool merge = false, ImWchar* glyphRanges = nullptr)
{
ERR_FAIL_COND(!detail::GET_IMGUIGD());
static const StringName sn("AddFont");
- detail::ImGuiGD->call(sn, fontSize, merge);
+ PackedInt32Array gr;
+ if (glyphRanges)
+ {
+ do
+ {
+ gr.append(*glyphRanges);
+ } while (*++glyphRanges != 0);
+ }
+ detail::ImGuiGD->call(sn, fontSize, merge, gr);
}
inline void Connect(const Callable& callable)
@@ -153,6 +163,7 @@ inline void SyncImGuiPtrs()
inline ImTextureID BindTexture(Texture2D* tex)
{
+ ERR_FAIL_COND_V(!tex, 0);
return reinterpret_cast(tex->get_rid().get_id());
}
#endif
diff --git a/gdext/src/Context.cpp b/gdext/src/Context.cpp
index da6eec18..2bb0452a 100644
--- a/gdext/src/Context.cpp
+++ b/gdext/src/Context.cpp
@@ -267,9 +267,9 @@ void ResetFonts()
ctx->fonts->Reset();
}
-void AddFont(const Ref& fontFile, int fontSize, bool merge)
+void AddFont(const Ref& fontFile, int fontSize, bool merge, const ImVector& glyphRanges)
{
- ctx->fonts->Add(fontFile, fontSize, merge);
+ ctx->fonts->Add(fontFile, fontSize, merge, glyphRanges);
}
void AddFontDefault()
diff --git a/gdext/src/Context.h b/gdext/src/Context.h
index 47acff38..464688a4 100644
--- a/gdext/src/Context.h
+++ b/gdext/src/Context.h
@@ -72,7 +72,7 @@ void Render();
void Shutdown();
void Connect(const Callable& callable);
void ResetFonts();
-void AddFont(const Ref& fontFile, int fontSize, bool merge = false);
+void AddFont(const Ref& fontFile, int fontSize, bool merge = false, const ImVector& glyphRanges = {});
void AddFontDefault();
void RebuildFontAtlas(float scale = 1.0f);
void SetIniFilename(const String& fn);
diff --git a/gdext/src/Fonts.cpp b/gdext/src/Fonts.cpp
index 959d6f60..8e1fc438 100644
--- a/gdext/src/Fonts.cpp
+++ b/gdext/src/Fonts.cpp
@@ -27,7 +27,7 @@ struct Fonts::Impl
};
std::vector fontConfig;
- void AddFontToAtlas(const Ref& font, int fontSize, bool merge, const ImVector& ranges);
+ void AddFontToAtlas(const FontParams& fp, float scale);
static ImVector GetRanges(const Ref& font)
{
@@ -76,13 +76,16 @@ struct Fonts::Impl
}
};
-void Fonts::Impl::AddFontToAtlas(const Ref& font, int fontSize, bool merge, const ImVector& ranges)
+void Fonts::Impl::AddFontToAtlas(const FontParams& fp, float scale)
{
+ auto& io = ImGui::GetIO();
+ int fontSize = fp.fontSize * scale;
ImFontConfig fc;
- if (merge)
+
+ if (fp.merge)
fc.MergeMode = 1;
- if (font.is_null())
+ if (fp.font.is_null())
{
// default font
fc = {};
@@ -90,29 +93,28 @@ void Fonts::Impl::AddFontToAtlas(const Ref& font, int fontSize, bool m
fc.OversampleH = 1;
fc.OversampleV = 1;
fc.PixelSnapH = true;
- ImGui::GetIO().Fonts->AddFontDefault(&fc);
+ io.Fonts->AddFontDefault(&fc);
}
else
{
- fs::path fontpath = (font->get_path().utf8().get_data());
+ fs::path fontpath = (fp.font->get_path().utf8().get_data());
// no std::format in Clang 14
std::string fontdesc = fontpath.filename().string() + ", "s + std::to_string(fontSize) + "px";
if (fontdesc.length() > 39)
fontdesc.resize(39);
std::copy(fontdesc.begin(), fontdesc.end(), fc.Name);
+ fc.Name[fontdesc.length()] = '\0';
- int64_t len = font->get_data().size();
+ int64_t len = fp.font->get_data().size();
// let ImGui manage this memory
void* p = ImGui::MemAlloc(len);
- memcpy(p, font->get_data().ptr(), len);
- ImGui::GetIO().Fonts->AddFontFromMemoryTTF(p, len, fontSize, &fc, ranges.Data);
+ memcpy(p, fp.font->get_data().ptr(), len);
+ io.Fonts->AddFontFromMemoryTTF(p, len, fontSize, &fc, fp.ranges.Data);
}
- if (merge)
- {
- ImGui::GetIO().Fonts->Build();
- }
+ if (fp.merge)
+ io.Fonts->Build();
}
Fonts::Fonts() : impl(std::make_unique())
@@ -131,9 +133,10 @@ void Fonts::Reset()
impl->fontConfig.clear();
}
-void Fonts::Add(Ref fontData, int fontSize, bool merge)
+void Fonts::Add(Ref fontData, int fontSize, bool merge, const ImVector& glyphRanges)
{
- impl->fontConfig.push_back({fontData, fontSize, merge, Impl::GetRanges(fontData)});
+ impl->fontConfig.push_back(
+ {fontData, fontSize, merge, glyphRanges.size() > 0 ? glyphRanges : Impl::GetRanges(fontData)});
}
void Fonts::RebuildFontAtlas(float scale)
@@ -156,7 +159,7 @@ void Fonts::RebuildFontAtlas(float scale)
for (const auto& fp : impl->fontConfig)
{
- impl->AddFontToAtlas(fp.font, fp.fontSize * scale, fp.merge, fp.ranges);
+ impl->AddFontToAtlas(fp, scale);
}
uint8_t* pixelData;
diff --git a/gdext/src/Fonts.h b/gdext/src/Fonts.h
index e4121597..21772b0b 100644
--- a/gdext/src/Fonts.h
+++ b/gdext/src/Fonts.h
@@ -1,6 +1,6 @@
#pragma once
#include
-
+#include
#include
using namespace godot;
@@ -13,7 +13,7 @@ class Fonts
~Fonts();
void Reset();
- void Add(Ref fontData, int fontSize, bool merge = false);
+ void Add(Ref fontData, int fontSize, bool merge = false, const ImVector& glyphRanges = {});
void RebuildFontAtlas(float scale);
private:
diff --git a/gdext/src/ImGuiGD.cpp b/gdext/src/ImGuiGD.cpp
index d82bcd35..2d469a24 100644
--- a/gdext/src/ImGuiGD.cpp
+++ b/gdext/src/ImGuiGD.cpp
@@ -25,7 +25,10 @@ void ImGuiGD::_bind_methods()
ClassDB::bind_method(D_METHOD("_GetScale"), &ImGuiGD::_GetScale);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "Scale"), "_SetScale", "_GetScale");
- ClassDB::bind_method(D_METHOD("AddFont", "font_file", "font_size", "merge"), &ImGuiGD::AddFont, DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("AddFont", "font_file", "font_size", "merge", "glyph_ranges"),
+ &ImGuiGD::AddFont,
+ DEFVAL(false),
+ DEFVAL(PackedInt32Array()));
ClassDB::bind_method(D_METHOD("AddFontDefault"), &ImGuiGD::AddFontDefault);
ClassDB::bind_method(D_METHOD("Connect", "callable"), &ImGuiGD::Connect);
ClassDB::bind_method(D_METHOD("RebuildFontAtlas", "scale"), &ImGuiGD::RebuildFontAtlas, DEFVAL(1.0f));
@@ -87,9 +90,20 @@ void ImGuiGD::ResetFonts()
ImGui::Godot::ResetFonts();
}
-void ImGuiGD::AddFont(const Ref& fontFile, int fontSize, bool merge)
+void ImGuiGD::AddFont(const Ref& fontFile, int fontSize, bool merge, const PackedInt32Array& glyphRanges)
{
- ImGui::Godot::AddFont(fontFile, fontSize, merge);
+ if (glyphRanges.size() > 0)
+ {
+ ImVector gr;
+ gr.resize(glyphRanges.size() + 1, 0);
+ for (int i = 0; i < glyphRanges.size(); ++i)
+ gr[i] = glyphRanges[i];
+ ImGui::Godot::AddFont(fontFile, fontSize, merge, gr);
+ }
+ else
+ {
+ ImGui::Godot::AddFont(fontFile, fontSize, merge);
+ }
}
void ImGuiGD::AddFontDefault()
diff --git a/gdext/src/ImGuiGD.h b/gdext/src/ImGuiGD.h
index c61e0199..f62e2de3 100644
--- a/gdext/src/ImGuiGD.h
+++ b/gdext/src/ImGuiGD.h
@@ -27,7 +27,8 @@ class ImGuiGD : public Object
void Connect(const Callable& cb);
void ResetFonts();
- void AddFont(const Ref& fontFile, int fontSize, bool merge = false);
+ void AddFont(const Ref& fontFile, int fontSize, bool merge = false,
+ const PackedInt32Array& glyphRanges = {});
void AddFontDefault();
void RebuildFontAtlas(float scale);
diff --git a/src/MySecondNode.cs b/src/MySecondNode.cs
index fb84b4d9..ca1f3754 100644
--- a/src/MySecondNode.cs
+++ b/src/MySecondNode.cs
@@ -42,8 +42,9 @@ public override void _EnterTree()
// use Hack for the default glyphs, M+2 for Japanese
ImGuiGD.AddFont(GD.Load("res://data/Hack-Regular.ttf"), 18);
- ImGuiGD.AddFont(GD.Load("res://data/MPLUS2-Regular.ttf"), 22,
- merge: true);
+ ImGuiGD.AddFont(GD.Load("res://data/MPLUS2-Regular.ttf"), 24,
+ merge: true,
+ glyphRanges: ImGui.GetIO().Fonts.GetGlyphRangesJapanese());
ImGuiGD.AddFontDefault();
ImGuiGD.RebuildFontAtlas();