// File: Ciaxur[P]yagb-emu/include/imgui/imgui_demo.cpp
// Function: NodeFont(ImFont*)
static void NodeFont(ImFont* font)
{
    ImGuiIO& io = ImGui::GetIO();
    ImGuiStyle& style = ImGui::GetStyle();
    bool font_details_opened = ImGui::TreeNode(font, "Font: \"%s\"\n%.2f px, %d glyphs, %d file(s)",
        font->ConfigData ? font->ConfigData[0].Name : "", font->FontSize, font->Glyphs.Size, font->ConfigDataCount);
    ImGui::SameLine(); if (ImGui::SmallButton("Set as default")) { io.FontDefault = font; }
    if (!font_details_opened)
        return;

    ImGui::PushFont(font);
    ImGui::Text("The quick brown fox jumps over the lazy dog");
    ImGui::PopFont();
    ImGui::DragFloat("Font scale", &font->Scale, 0.005f, 0.3f, 2.0f, "%.1f");   // Scale only this font
    ImGui::SameLine(); HelpMarker(
        "Note than the default embedded font is NOT meant to be scaled.\n\n"
        "Font are currently rendered into bitmaps at a given size at the time of building the atlas. "
        "You may oversample them to get some flexibility with scaling. "
        "You can also render at multiple sizes and select which one to use at runtime.\n\n"
        "(Glimmer of hope: the atlas system will be rewritten in the future to make scaling more flexible.)");
    ImGui::Text("Ascent: %f, Descent: %f, Height: %f", font->Ascent, font->Descent, font->Ascent - font->Descent);
    ImGui::Text("Fallback character: '%c' (U+%04X)", font->FallbackChar, font->FallbackChar);
    ImGui::Text("Ellipsis character: '%c' (U+%04X)", font->EllipsisChar, font->EllipsisChar);
    const int surface_sqrt = (int)sqrtf((float)font->MetricsTotalSurface);
    ImGui::Text("Texture Area: about %d px ~%dx%d px", font->MetricsTotalSurface, surface_sqrt, surface_sqrt);
    for (int config_i = 0; config_i < font->ConfigDataCount; config_i++)
        if (font->ConfigData)
            if (const ImFontConfig* cfg = &font->ConfigData[config_i])
                ImGui::BulletText("Input %d: \'%s\', Oversample: (%d,%d), PixelSnapH: %d, Offset: (%.1f,%.1f)",
                    config_i, cfg->Name, cfg->OversampleH, cfg->OversampleV, cfg->PixelSnapH, cfg->GlyphOffset.x, cfg->GlyphOffset.y);
    if (ImGui::TreeNode("Glyphs", "Glyphs (%d)", font->Glyphs.Size))
    {
        // Display all glyphs of the fonts in separate pages of 256 characters
        const ImU32 glyph_col = ImGui::GetColorU32(ImGuiCol_Text);
        for (unsigned int base = 0; base <= IM_UNICODE_CODEPOINT_MAX; base += 256)
        {
            // Skip ahead if a large bunch of glyphs are not present in the font (test in chunks of 4k)
            // This is only a small optimization to reduce the number of iterations when IM_UNICODE_MAX_CODEPOINT
            // is large // (if ImWchar==ImWchar32 we will do at least about 272 queries here)
            if (!(base & 4095) && font->IsGlyphRangeUnused(base, base + 4095))
            {
                base += 4096 - 256;
                continue;
            }

            int count = 0;
            for (unsigned int n = 0; n < 256; n++)
                if (font->FindGlyphNoFallback((ImWchar)(base + n)))
                    count++;
            if (count <= 0)
                continue;
            if (!ImGui::TreeNode((void*)(intptr_t)base, "U+%04X..U+%04X (%d %s)", base, base + 255, count, count > 1 ? "glyphs" : "glyph"))
                continue;
            float cell_size = font->FontSize * 1;
            float cell_spacing = style.ItemSpacing.y;
            ImVec2 base_pos = ImGui::GetCursorScreenPos();
            ImDrawList* draw_list = ImGui::GetWindowDrawList();
            for (unsigned int n = 0; n < 256; n++)
            {
                // We use ImFont::RenderChar as a shortcut because we don't have UTF-8 conversion functions
                // available here and thus cannot easily generate a zero-terminated UTF-8 encoded string.
                ImVec2 cell_p1(base_pos.x + (n % 16) * (cell_size + cell_spacing), base_pos.y + (n / 16) * (cell_size + cell_spacing));
                ImVec2 cell_p2(cell_p1.x + cell_size, cell_p1.y + cell_size);
                const ImFontGlyph* glyph = font->FindGlyphNoFallback((ImWchar)(base + n));
                draw_list->AddRect(cell_p1, cell_p2, glyph ? IM_COL32(255, 255, 255, 100) : IM_COL32(255, 255, 255, 50));
                if (glyph)
                    font->RenderChar(draw_list, cell_size, cell_p1, glyph_col, (ImWchar)(base + n));
                if (glyph && ImGui::IsMouseHoveringRect(cell_p1, cell_p2))
                {
                    ImGui::BeginTooltip();
                    ImGui::Text("Codepoint: U+%04X", base + n);
                    ImGui::Separator();
                    ImGui::Text("Visible: %d", glyph->Visible);
                    ImGui::Text("AdvanceX: %.1f", glyph->AdvanceX);
                    ImGui::Text("Pos: (%.2f,%.2f)->(%.2f,%.2f)", glyph->X0, glyph->Y0, glyph->X1, glyph->Y1);
                    ImGui::Text("UV: (%.3f,%.3f)->(%.3f,%.3f)", glyph->U0, glyph->V0, glyph->U1, glyph->V1);
                    ImGui::EndTooltip();
                }
            }
            ImGui::Dummy(ImVec2((cell_size + cell_spacing) * 16, (cell_size + cell_spacing) * 16));
            ImGui::TreePop();
        }
        ImGui::TreePop();
    }
    ImGui::TreePop();
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xa0, %rsp
movq %rdi, -0x8(%rbp)
callq 0xcb1a0
movq %rax, -0x10(%rbp)
callq 0xc7680
movq %rax, -0x18(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x90(%rbp)
movq -0x8(%rbp), %rax
cmpq $0x0, 0x48(%rax)
je 0x106e5c
movq -0x8(%rbp), %rax
movq 0x48(%rax), %rax
addq $0x56, %rax
movq %rax, -0x98(%rbp)
jmp 0x106e6c
leaq 0x6b0a6(%rip), %rax     # 0x171f09
movq %rax, -0x98(%rbp)
jmp 0x106e6c
movq -0x90(%rbp), %rdi
movq -0x98(%rbp), %rdx
movq -0x8(%rbp), %rax
movss 0x14(%rax), %xmm0
cvtss2sd %xmm0, %xmm0
movq -0x8(%rbp), %rax
movl 0x28(%rax), %ecx
movq -0x8(%rbp), %rax
movswl 0x50(%rax), %r8d
leaq 0x7b670(%rip), %rsi     # 0x18250e
movb $0x1, %al
callq 0x150f40
andb $0x1, %al
movb %al, -0x19(%rbp)
xorps %xmm0, %xmm0
movss 0x6b0cb(%rip), %xmm1    # 0x171f80
callq 0xdc1c0
leaq 0x7b677(%rip), %rdi     # 0x182538
callq 0x13a960
testb $0x1, %al
jne 0x106ecc
jmp 0x106edb
movq -0x8(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0xb0(%rax)
testb $0x1, -0x19(%rbp)
jne 0x106ee6
jmp 0x10745c
movq -0x8(%rbp), %rdi
callq 0xd9ff0
leaq 0x7c198(%rip), %rdi     # 0x18308e
movb $0x0, %al
callq 0x139160
callq 0xda060
movq -0x8(%rbp), %rsi
addq $0x58, %rsi
leaq 0x7b636(%rip), %rdi     # 0x182547
movss 0x7169f(%rip), %xmm0    # 0x1785b8
movss 0x6b82b(%rip), %xmm1    # 0x17274c
movss 0x6b0a3(%rip), %xmm2    # 0x171fcc
leaq 0x79079(%rip), %rdx     # 0x17ffa9
xorl %ecx, %ecx
callq 0x142f00
xorps %xmm0, %xmm0
movss 0x6b03e(%rip), %xmm1    # 0x171f80
callq 0xdc1c0
leaq 0x7b604(%rip), %rdi     # 0x182552
callq 0xf6290
movq -0x8(%rbp), %rax
movss 0x5c(%rax), %xmm0
cvtss2sd %xmm0, %xmm0
movq -0x8(%rbp), %rax
movss 0x60(%rax), %xmm1
cvtss2sd %xmm1, %xmm1
movq -0x8(%rbp), %rax
movss 0x5c(%rax), %xmm2
movq -0x8(%rbp), %rax
subss 0x60(%rax), %xmm2
cvtss2sd %xmm2, %xmm2
leaq 0x7b754(%rip), %rdi     # 0x1826de
movb $0x3, %al
callq 0x139160
movq -0x8(%rbp), %rax
movzwl 0x52(%rax), %esi
movq -0x8(%rbp), %rax
movzwl 0x52(%rax), %edx
leaq 0x7b75a(%rip), %rdi     # 0x182702
movb $0x0, %al
callq 0x139160
movq -0x8(%rbp), %rax
movzwl 0x54(%rax), %esi
movq -0x8(%rbp), %rax
movzwl 0x54(%rax), %edx
leaq 0x7b75e(%rip), %rdi     # 0x182724
movb $0x0, %al
callq 0x139160
movq -0x8(%rbp), %rax
cvtsi2ssl 0x64(%rax), %xmm0
callq 0xd960
cvttss2si %xmm0, %eax
movl %eax, -0x20(%rbp)
movq -0x8(%rbp), %rax
movl 0x64(%rax), %esi
movl -0x20(%rbp), %edx
movl -0x20(%rbp), %ecx
leaq 0x7b750(%rip), %rdi     # 0x182746
movb $0x0, %al
callq 0x139160
movl $0x0, -0x24(%rbp)
movl -0x24(%rbp), %eax
movq -0x8(%rbp), %rcx
movswl 0x50(%rcx), %ecx
cmpl %ecx, %eax
jge 0x1070a4
movq -0x8(%rbp), %rax
cmpq $0x0, 0x48(%rax)
je 0x107094
movq -0x8(%rbp), %rax
movq 0x48(%rax), %rax
movslq -0x24(%rbp), %rcx
imulq $0x88, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
je 0x107092
movl -0x24(%rbp), %esi
movq -0x30(%rbp), %rdx
addq $0x56, %rdx
movq -0x30(%rbp), %rax
movl 0x18(%rax), %ecx
movq -0x30(%rbp), %rax
movl 0x1c(%rax), %r8d
movq -0x30(%rbp), %rax
movb 0x20(%rax), %al
andb $0x1, %al
movzbl %al, %r9d
movq -0x30(%rbp), %rax
movss 0x2c(%rax), %xmm0
cvtss2sd %xmm0, %xmm0
movq -0x30(%rbp), %rax
movss 0x30(%rax), %xmm1
cvtss2sd %xmm1, %xmm1
leaq 0x7b6df(%rip), %rdi     # 0x18276a
movb $0x2, %al
callq 0x139ab0
jmp 0x107094
jmp 0x107096
movl -0x24(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
jmp 0x107004
movq -0x8(%rbp), %rax
movl 0x28(%rax), %edx
leaq 0x7b701(%rip), %rdi     # 0x1827b3
leaq 0x7b701(%rip), %rsi     # 0x1827ba
movb $0x0, %al
callq 0x150dd0
testb $0x1, %al
jne 0x1070c9
jmp 0x107457
xorl %edi, %edi
movss 0x69b69(%rip), %xmm0    # 0x170c3c
callq 0xc76e0
movl %eax, -0x34(%rbp)
movl $0x0, -0x38(%rbp)
cmpl $0xffff, -0x38(%rbp)    # imm = 0xFFFF
ja 0x107452
movl -0x38(%rbp), %eax
andl $0xfff, %eax            # imm = 0xFFF
cmpl $0x0, %eax
jne 0x107127
movq -0x8(%rbp), %rdi
movl -0x38(%rbp), %esi
movl -0x38(%rbp), %edx
addl $0xfff, %edx            # imm = 0xFFF
callq 0x11c030
testb $0x1, %al
jne 0x107117
jmp 0x107127
movl -0x38(%rbp), %eax
addl $0xf00, %eax            # imm = 0xF00
movl %eax, -0x38(%rbp)
jmp 0x107442
movl $0x0, -0x3c(%rbp)
movl $0x0, -0x40(%rbp)
cmpl $0x100, -0x40(%rbp)     # imm = 0x100
jae 0x10716c
movq -0x8(%rbp), %rdi
movl -0x38(%rbp), %eax
addl -0x40(%rbp), %eax
movzwl %ax, %esi
callq 0x11b920
cmpq $0x0, %rax
je 0x10715f
movl -0x3c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3c(%rbp)
jmp 0x107161
movl -0x40(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x40(%rbp)
jmp 0x107135
cmpl $0x0, -0x3c(%rbp)
jg 0x107177
jmp 0x107442
movl -0x38(%rbp), %eax
movl %eax, %edi
movl -0x38(%rbp), %edx
movl -0x38(%rbp), %ecx
addl $0xff, %ecx
movl -0x3c(%rbp), %r8d
movl -0x3c(%rbp), %esi
leaq 0x7b64e(%rip), %r9      # 0x1827e4
leaq 0x7b640(%rip), %rax     # 0x1827dd
cmpl $0x1, %esi
cmovgq %rax, %r9
leaq 0x7b61b(%rip), %rsi     # 0x1827c6
movb $0x0, %al
callq 0x150f40
testb $0x1, %al
jne 0x1071bb
jmp 0x107442
movq -0x8(%rbp), %rax
movss 0x14(%rax), %xmm0
movss %xmm0, -0x44(%rbp)
movq -0x18(%rbp), %rax
movss 0x4c(%rax), %xmm0
movss %xmm0, -0x48(%rbp)
callq 0xdc6c0
movlpd %xmm0, -0x50(%rbp)
callq 0xdae40
movq %rax, -0x58(%rbp)
movl $0x0, -0x5c(%rbp)
cmpl $0x100, -0x5c(%rbp)     # imm = 0x100
jae 0x1073f9
movl -0x5c(%rbp), %eax
movl %eax, %ecx
andl $0xf, %ecx
cvtsi2ss %ecx, %xmm0
movss -0x44(%rbp), %xmm1
movss -0x48(%rbp), %xmm2
addss %xmm2, %xmm1
mulss %xmm1, %xmm0
movss -0x50(%rbp), %xmm1
movss -0x4c(%rbp), %xmm2
addss %xmm1, %xmm0
shrl $0x4, %eax
cvtsi2ss %eax, %xmm1
movss -0x44(%rbp), %xmm3
addss -0x48(%rbp), %xmm3
mulss %xmm3, %xmm1
addss %xmm2, %xmm1
leaq -0x64(%rbp), %rdi
callq 0xbf4c0
movss -0x64(%rbp), %xmm0
addss -0x44(%rbp), %xmm0
movss -0x60(%rbp), %xmm1
addss -0x44(%rbp), %xmm1
leaq -0x6c(%rbp), %rdi
callq 0xbf4c0
movq -0x8(%rbp), %rdi
movl -0x38(%rbp), %eax
addl -0x5c(%rbp), %eax
movzwl %ax, %esi
callq 0x11b920
movq %rax, -0x78(%rbp)
movq -0x58(%rbp), %rdi
movq -0x78(%rbp), %rdx
movl $0x32ffffff, %ecx       # imm = 0x32FFFFFF
movl $0x64ffffff, %eax       # imm = 0x64FFFFFF
cmpq $0x0, %rdx
cmovnel %eax, %ecx
leaq -0x64(%rbp), %rsi
leaq -0x6c(%rbp), %rdx
xorps %xmm0, %xmm0
movl $0xf, %r8d
movss 0x6998b(%rip), %xmm1    # 0x170c3c
callq 0x112ef0
cmpq $0x0, -0x78(%rbp)
je 0x1072ea
movq -0x8(%rbp), %rdi
movq -0x58(%rbp), %rsi
movss -0x44(%rbp), %xmm0
movq -0x64(%rbp), %rax
movq %rax, -0x80(%rbp)
movl -0x34(%rbp), %edx
movl -0x38(%rbp), %eax
movl -0x5c(%rbp), %ecx
addl %ecx, %eax
movsd -0x80(%rbp), %xmm1
movzwl %ax, %ecx
callq 0x11c870
cmpq $0x0, -0x78(%rbp)
je 0x1073e9
leaq -0x64(%rbp), %rdi
leaq -0x6c(%rbp), %rsi
movl $0x1, %edx
callq 0xca5f0
testb $0x1, %al
jne 0x107310
jmp 0x1073e9
callq 0xddb50
movl -0x38(%rbp), %esi
addl -0x5c(%rbp), %esi
leaq 0x7b4c8(%rip), %rdi     # 0x1827ea
movb $0x0, %al
callq 0x139160
callq 0x13dec0
movq -0x78(%rbp), %rax
movl (%rax), %esi
shrl $0x1f, %esi
leaq 0x6ecbc(%rip), %rdi     # 0x175ffa
movb $0x0, %al
callq 0x139160
movq -0x78(%rbp), %rax
movss 0x4(%rax), %xmm0
cvtss2sd %xmm0, %xmm0
leaq 0x7b4a3(%rip), %rdi     # 0x1827fc
movb $0x1, %al
callq 0x139160
movq -0x78(%rbp), %rax
movss 0x8(%rax), %xmm0
cvtss2sd %xmm0, %xmm0
movq -0x78(%rbp), %rax
movss 0xc(%rax), %xmm1
cvtss2sd %xmm1, %xmm1
movq -0x78(%rbp), %rax
movss 0x10(%rax), %xmm2
cvtss2sd %xmm2, %xmm2
movq -0x78(%rbp), %rax
movss 0x14(%rax), %xmm3
cvtss2sd %xmm3, %xmm3
leaq 0x7b470(%rip), %rdi     # 0x18280b
movb $0x4, %al
callq 0x139160
movq -0x78(%rbp), %rax
movss 0x18(%rax), %xmm0
cvtss2sd %xmm0, %xmm0
movq -0x78(%rbp), %rax
movss 0x1c(%rax), %xmm1
cvtss2sd %xmm1, %xmm1
movq -0x78(%rbp), %rax
movss 0x20(%rax), %xmm2
cvtss2sd %xmm2, %xmm2
movq -0x78(%rbp), %rax
movss 0x24(%rax), %xmm3
cvtss2sd %xmm3, %xmm3
leaq 0x7b44c(%rip), %rdi     # 0x182829
movb $0x4, %al
callq 0x139160
callq 0xddce0
jmp 0x1073eb
movl -0x5c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5c(%rbp)
jmp 0x1071f1
movss -0x44(%rbp), %xmm0
addss -0x48(%rbp), %xmm0
movss 0x6b385(%rip), %xmm1    # 0x172790
mulss %xmm1, %xmm0
movss -0x44(%rbp), %xmm1
addss -0x48(%rbp), %xmm1
movss 0x6b36f(%rip), %xmm2    # 0x172790
mulss %xmm2, %xmm1
leaq -0x88(%rbp), %rdi
callq 0xbf4c0
leaq -0x88(%rbp), %rdi
callq 0x13d8d0
callq 0x1523d0
movl -0x38(%rbp), %eax
addl $0x100, %eax            # imm = 0x100
movl %eax, -0x38(%rbp)
jmp 0x1070e2
callq 0x1523d0
callq 0x1523d0
addq $0xa0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)