void RebuildFonts() { ImGuiIOPtr io = ImGui.GetIO(); // Default font ImFontAtlasPtr fonts = io.Fonts; fonts.Clear(); using (ImFontConfig config = new ImFontConfig()) { config.SizePixels = 13.0f * uiScale; // ImGui default font size is 13 pixels config.OversampleH = 1; fonts.AddFontDefault(config); } #if !UNITY_ANDROID // Icon font if (iconFont.Length > 0) { using (ImFontConfig config = new ImFontConfig()) { config.MergeMode = true; if (iconFontMinAdvanceX > 0) { config.GlyphMinAdvanceX = iconFontMinAdvanceX; config.GlyphMaxAdvanceX = iconFontMinAdvanceX; } config.PixelSnapH = true; config.OversampleH = 1; ushort rangeMin = ushort.Parse(iconRangeMin, NumberStyles.HexNumber); ushort rangeMax = ushort.Parse(iconRangeMax, NumberStyles.HexNumber); if (rangeMin != 0 && rangeMax != 0) { ushort[] icon_ranges = { rangeMin, rangeMax, 0 }; ImGui.AddFontFromFileTTF(fonts, Application.streamingAssetsPath + "/" + iconFont, iconFontPixelSize * uiScale, config, icon_ranges); } } } // Custom fonts imFonts = new ImFontPtr[customFonts.Length]; for (int i = 0; i < customFonts.Length; i++) { using (ImFontConfig config = new ImFontConfig()) { config.OversampleH = 1; config.OversampleV = 1; imFonts[i] = fonts.AddFontFromFileTTF(Application.streamingAssetsPath + "/" + customFonts[i], customFontPixelSize * uiScale, config); } } #endif if (useFreetype) { // Freetype rasterizer ImGui.BuildFontAtlas(fonts, freetype_flags); } else { fonts.Build(); } RecreateFontTexture(); }
public unsafe IconFont(GraphicsDevice device, Action <ImFontAtlasPtr> addFontToAtlas) { var atlas = new ImFontAtlasPtr(ImGuiNative.ImFontAtlas_ImFontAtlas()); addFontToAtlas(atlas); atlas.Flags = ImFontAtlasFlags.NoMouseCursors; if (!atlas.Build()) { throw new InvalidProgramException("Building ImFontAtlas failed"); } if (atlas.Fonts.Size != 1) { throw new InvalidProgramException("ImFontAtlas does not contain a font after building"); } var font = *(ImFont **)atlas.Fonts.Data.ToPointer(); if (font->Glyphs.Size <= 0) { throw new InvalidProgramException("ImFont does not contain at least one glyph after building"); } IntPtr texPixels; int texWidth, texHeight; atlas.GetTexDataAsAlpha8(out texPixels, out texWidth, out texHeight); Texture = device.ResourceFactory.CreateTexture(new TextureDescription( width: (uint)texWidth, height: (uint)texHeight, format: PixelFormat.R8_UNorm, usage: TextureUsage.Sampled, type: TextureType.Texture2D, depth: 1, mipLevels: 1, arrayLayers: 1)); Texture.Name = "IconFontTexture"; device.UpdateTexture(Texture, texPixels, (uint)(texWidth * texHeight * 1), 0, 0, 0, (uint)texWidth, (uint)texHeight, 1, 0, 0); var glyphsPtr = (ImFontGlyph *)font->Glyphs.Data.ToPointer(); var glyphs = new Dictionary <string, Rect>(); for (int i = 0; i < font->Glyphs.Size; i++) { var glyph = new ImFontGlyphPtr(glyphsPtr + i); var uvMin = new Vector2(glyph.U0, glyph.V1); // switch v to prevent vflip var uvMax = new Vector2(glyph.U1, glyph.V0); var codepoint = (int)(glyph.Codepoint); glyphs[char.ConvertFromUtf32(codepoint)] = new Rect((uvMin + uvMax) / 2, uvMax - uvMin); } Glyphs = glyphs; atlas.Destroy(); Sampler = device.ResourceFactory.CreateSampler(new SamplerDescription( addressModeU: SamplerAddressMode.Border, addressModeV: SamplerAddressMode.Border, addressModeW: SamplerAddressMode.Border, filter: SamplerFilter.MinLinear_MagLinear_MipLinear, comparisonKind: null, maximumAnisotropy: 0, minimumLod: 0, maximumLod: 1, lodBias: 0, borderColor: SamplerBorderColor.TransparentBlack )); }