Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to load fonts with specific glyph ranges (e.g., Chinese, Japanese, Korean) using hello_imgui.load_font #196

Open
inkydragon opened this issue Mar 29, 2024 · 2 comments
Labels
faq A frequent issue, remaining opened to facilitate discoverability

Comments

@inkydragon
Copy link

env:

  • Python imgui-bundle 1.3.0

# ImVec2 GlyphExtraSpacing; /* original C++ signature */
glyph_extra_spacing: (
ImVec2 # 0, 0 // Extra spacing (in pixels) between glyphs. Only X axis is supported for now.
)
# ImVec2 GlyphOffset; /* original C++ signature */
glyph_offset: ImVec2 # 0, 0 // Offset all glyphs from this font input.
# float GlyphMinAdvanceX; /* original C++ signature */
glyph_min_advance_x: float # 0 // Minimum AdvanceX for glyphs, set Min to align font icons, set both Min/Max to enforce mono-space font
# float GlyphMaxAdvanceX; /* original C++ signature */
glyph_max_advance_x: float # FLT_MAX // Maximum AdvanceX for glyphs

struct ImFontConfig
{
	// ...

    ImVec2          GlyphExtraSpacing;      // 0, 0     // Extra spacing (in pixels) between glyphs. Only X axis is supported for now.
    ImVec2          GlyphOffset;            // 0, 0     // Offset all glyphs from this font input.
    const ImWchar*  GlyphRanges;            // NULL     // THE ARRAY DATA NEEDS TO PERSIST AS LONG AS THE FONT IS ALIVE. Pointer to a user-provided list of Unicode range (2 value per range, values are inclusive, zero-terminated list).
    float           GlyphMinAdvanceX;       // 0        // Minimum AdvanceX for glyphs, set Min to align font icons, set both Min/Max to enforce mono-space font
    float           GlyphMaxAdvanceX;       // FLT_MAX  // Maximum AdvanceX for glyphs

	// ...
};

https://github.com/ocornut/imgui/blame/d3c3514a59bb31406c954c2b525f330e9d167845/imgui.h#L2889

Context

I want to load Chinese fonts and specify glyph_range.

test code
void LoadDefaultFont_WithFontAwesomeIcons()
{
    std::string fontFilename = "fonts/SarasaUiSC-Regular.ttf";
    if (HelloImGui::AssetExists(fontFilename))
    {
        HelloImGui::FontLoadingParams fontLoadingParams;
        fontLoadingParams.mergeFontAwesome = true;
        // NOTE
        fontLoadingParams.fontConfig.GlyphRanges =
            ImGui::GetIO().Fonts->GetGlyphRangesChineseSimplifiedCommon();
        ImFont* font = LoadFont(fontFilename, 15.f, fontLoadingParams);
        (void) font;
    }
    else
    {
        ImGui::GetIO().Fonts->AddFontDefault();
    }
}
def load_default_font_with_fa_icon():
    font_filename = "fonts/SarasaUiSC-Regular.ttf"
    if hello_imgui.asset_exists(font_filename):
        font_loading_params = hello_imgui.FontLoadingParams()
        font_loading_params.merge_font_awesome = True
        sc_cn_range = imgui.get_io().fonts.get_glyph_ranges_chinese_simplified_common()
        # font_loading_params.font_config.??? = sc_cn_range
        hello_imgui.load_font(font_filename, 15.0, font_loading_params)
        logger.info(f"Loaded font: {font_filename}")
    else:
        imgui.get_io().fonts.add_font_default()
        logger.info(f"Loaded default font.")
Workaround
def load_default_font_with_fa_icon():
    font_filename = "fonts/SarasaUiSC-Regular.ttf"
    if hello_imgui.asset_exists(font_filename):
        sc_cn_range = imgui.get_io().fonts.get_glyph_ranges_chinese_simplified_common()
        imgui.get_io().fonts.add_font_from_file_ttf(
            hello_imgui.asset_file_full_path(font_filename),
            24.0,
            glyph_ranges_as_int_list=sc_cn_range)

        # font_loading_params = hello_imgui.FontLoadingParams()
        # font_loading_params.merge_font_awesome = True
        # # font_loading_params.font_config.??? = sc_cn_range
        # hello_imgui.load_font(font_filename, 15.0, font_loading_params)
        logger.info(f"Loaded font: {font_filename}")
    else:
        imgui.get_io().fonts.add_font_default()
        logger.info(f"Loaded default font.")
@pthom
Copy link
Owner

pthom commented Mar 29, 2024

I don't understand your question (there is none in your message, in fact). Does your work around work?

@pthom pthom changed the title Missing fields ImFontConfig.GlyphRanges in python binding How to load chinese font with hello_imgui.load_font and set the glyph range (Python) Jul 6, 2024
@pthom
Copy link
Owner

pthom commented Jul 6, 2024

Hello,

I come back to this question after a few months, sorry for the delay.

I understand that you needed a way to translate the glyph ranges coming from Dear ImGui, into ranges used by hello_imgui.load_font.

This commit adds support for this.

Example usage:

"""Demonstrates how to load a font with Chinese characters and display them in the GUI,
using the common glyph ranges defined in by ImGui.
"""
from imgui_bundle import imgui, hello_imgui, imgui_ctx
from imgui_bundle.demos_python import demo_utils


demo_utils.set_hello_imgui_demo_assets_folder()


font_cn: imgui.ImFont = None


def load_font():
    global font_cn
    if not hello_imgui.asset_exists("fonts/NotoSerifSC-VariableFont_wght.ttf"):
        return

    # Note: this font is not provided with the ImGui bundle (too large).
    # You will need to provide it yourself, or use another font.
    font_filename = "fonts/NotoSerifSC-VariableFont_wght.ttf"

    # The range of Chinese characters is defined by ImGui as a single list of characters (List[ImWchar]), with a terminating 0.
    # (each range is a pair of successive characters in this list, with the second character being the last one in the range)
    cn_glyph_ranges_imgui = imgui.get_io().fonts.get_glyph_ranges_chinese_simplified_common()
    # We need to convert this list into a list of pairs (List[ImWcharPair]), where each pair is a range of characters.
    cn_glyph_ranges_pair = hello_imgui.translate_common_glyph_ranges(cn_glyph_ranges_imgui)

    font_loading_params = hello_imgui.FontLoadingParams()
    font_loading_params.glyph_ranges = cn_glyph_ranges_pair
    font_cn = hello_imgui.load_font(font_filename, 40.0, font_loading_params)


def gui():
    if font_cn is not None:
        with imgui_ctx.push_font(font_cn):
            imgui.text("Hello world")
            imgui.text("你好,世界")
    else:
        imgui.text("Font file not found")
        imgui.text_wrapped("""
        This font is not provided with the ImGui bundle (too large).
        You will need to provide it yourself, or use another font.
        """)


runner_params = hello_imgui.RunnerParams()
runner_params.callbacks.load_additional_fonts = load_font
runner_params.callbacks.show_gui = gui
hello_imgui.run(runner_params)
image

@pthom pthom changed the title How to load chinese font with hello_imgui.load_font and set the glyph range (Python) How to load chinese font with hello_imgui.load_font and set the glyph range from get_glyph_ranges_chinese_simplified_common() Jul 6, 2024
@pthom pthom changed the title How to load chinese font with hello_imgui.load_font and set the glyph range from get_glyph_ranges_chinese_simplified_common() How to load fonts with specific glyph ranges (e.g., Chinese, Japanese, Korean) using hello_imgui.load_font Jul 6, 2024
@pthom pthom added the faq A frequent issue, remaining opened to facilitate discoverability label Jul 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
faq A frequent issue, remaining opened to facilitate discoverability
Projects
None yet
Development

No branches or pull requests

2 participants