// File: Ciaxur[P]yagb-emu/include/imgui/imgui_draw.cpp
// Function: ImFont::CalcWordWrapPositionA(float, char const*, char const*, float) const
const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) const
{
    // Simple word-wrapping for English, not full-featured. Please submit failing cases!
    // FIXME: Much possible improvements (don't cut things like "word !", "word!!!" but cut within "word,,,,", more sensible support for punctuations, support for Unicode punctuations, etc.)

    // For references, possible wrap point marked with ^
    //  "aaa bbb, ccc,ddd. eee   fff. ggg!"
    //      ^    ^    ^   ^   ^__    ^    ^

    // List of hardcoded separators: .,;!?'"

    // Skip extra blanks after a line returns (that includes not counting them in width computation)
    // e.g. "Hello    world" --> "Hello" "World"

    // Cut words that cannot possibly fit within one line.
    // e.g.: "The tropical fish" with ~5 characters worth of width --> "The tr" "opical" "fish"

    float line_width = 0.0f;
    float word_width = 0.0f;
    float blank_width = 0.0f;
    wrap_width /= scale; // We work with unscaled widths to avoid scaling every characters

    const char* word_end = text;
    const char* prev_word_end = NULL;
    bool inside_word = true;

    const char* s = text;
    while (s < text_end)
    {
        unsigned int c = (unsigned int)*s;
        const char* next_s;
        if (c < 0x80)
            next_s = s + 1;
        else
            next_s = s + ImTextCharFromUtf8(&c, s, text_end);
        if (c == 0)
            break;

        if (c < 32)
        {
            if (c == '\n')
            {
                line_width = word_width = blank_width = 0.0f;
                inside_word = true;
                s = next_s;
                continue;
            }
            if (c == '\r')
            {
                s = next_s;
                continue;
            }
        }

        const float char_width = ((int)c < IndexAdvanceX.Size ? IndexAdvanceX.Data[c] : FallbackAdvanceX);
        if (ImCharIsBlankW(c))
        {
            if (inside_word)
            {
                line_width += blank_width;
                blank_width = 0.0f;
                word_end = s;
            }
            blank_width += char_width;
            inside_word = false;
        }
        else
        {
            word_width += char_width;
            if (inside_word)
            {
                word_end = next_s;
            }
            else
            {
                prev_word_end = word_end;
                line_width += word_width + blank_width;
                word_width = blank_width = 0.0f;
            }

            // Allow wrapping after punctuation.
            inside_word = (c != '.' && c != ',' && c != ';' && c != '!' && c != '?' && c != '\"');
        }

        // We ignore blank width at the end of the line (they can be skipped)
        if (line_width + word_width > wrap_width)
        {
            // Words that cannot possibly fit within an entire line will be cut anywhere.
            if (word_width < wrap_width)
                s = prev_word_end ? prev_word_end : word_end;
            break;
        }

        s = next_s;
    }

    return s;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x90, %rsp
movq %rdi, -0x8(%rbp)
movss %xmm0, -0xc(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movss %xmm1, -0x24(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x70(%rbp)
xorps %xmm0, %xmm0
movss %xmm0, -0x28(%rbp)
xorps %xmm0, %xmm0
movss %xmm0, -0x2c(%rbp)
xorps %xmm0, %xmm0
movss %xmm0, -0x30(%rbp)
movss -0xc(%rbp), %xmm1
movss -0x24(%rbp), %xmm0
divss %xmm1, %xmm0
movss %xmm0, -0x24(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x38(%rbp)
movq $0x0, -0x40(%rbp)
movb $0x1, -0x41(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rax
cmpq -0x20(%rbp), %rax
jae 0x11c4ce
movq -0x50(%rbp), %rax
movsbl (%rax), %eax
movl %eax, -0x54(%rbp)
cmpl $0x80, -0x54(%rbp)
jae 0x11c2df
movq -0x50(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x60(%rbp)
jmp 0x11c308
movq -0x50(%rbp), %rax
movq %rax, -0x78(%rbp)
movq -0x50(%rbp), %rsi
movq -0x20(%rbp), %rdx
leaq -0x54(%rbp), %rdi
callq 0xc36d0
movl %eax, %ecx
movq -0x78(%rbp), %rax
movslq %ecx, %rcx
addq %rcx, %rax
movq %rax, -0x60(%rbp)
cmpl $0x0, -0x54(%rbp)
jne 0x11c313
jmp 0x11c4ce
cmpl $0x20, -0x54(%rbp)
jae 0x11c35d
cmpl $0xa, -0x54(%rbp)
jne 0x11c348
xorps %xmm0, %xmm0
movss %xmm0, -0x30(%rbp)
xorps %xmm0, %xmm0
movss %xmm0, -0x2c(%rbp)
xorps %xmm0, %xmm0
movss %xmm0, -0x28(%rbp)
movb $0x1, -0x41(%rbp)
movq -0x60(%rbp), %rax
movq %rax, -0x50(%rbp)
jmp 0x11c2b0
cmpl $0xd, -0x54(%rbp)
jne 0x11c35b
movq -0x60(%rbp), %rax
movq %rax, -0x50(%rbp)
jmp 0x11c2b0
jmp 0x11c35d
movq -0x70(%rbp), %rcx
movl -0x54(%rbp), %eax
cmpl (%rcx), %eax
jge 0x11c37f
movq -0x70(%rbp), %rax
movq 0x8(%rax), %rax
movl -0x54(%rbp), %ecx
movss (%rax,%rcx,4), %xmm0
movss %xmm0, -0x7c(%rbp)
jmp 0x11c38d
movq -0x70(%rbp), %rax
movss 0x10(%rax), %xmm0
movss %xmm0, -0x7c(%rbp)
movss -0x7c(%rbp), %xmm0
movss %xmm0, -0x64(%rbp)
movl -0x54(%rbp), %edi
callq 0x11c4e0
testb $0x1, %al
jne 0x11c3a5
jmp 0x11c3e2
testb $0x1, -0x41(%rbp)
je 0x11c3ca
movss -0x30(%rbp), %xmm0
addss -0x28(%rbp), %xmm0
movss %xmm0, -0x28(%rbp)
xorps %xmm0, %xmm0
movss %xmm0, -0x30(%rbp)
movq -0x50(%rbp), %rax
movq %rax, -0x38(%rbp)
movss -0x64(%rbp), %xmm0
addss -0x30(%rbp), %xmm0
movss %xmm0, -0x30(%rbp)
movb $0x0, -0x41(%rbp)
jmp 0x11c476
movss -0x64(%rbp), %xmm0
addss -0x2c(%rbp), %xmm0
movss %xmm0, -0x2c(%rbp)
testb $0x1, -0x41(%rbp)
je 0x11c401
movq -0x60(%rbp), %rax
movq %rax, -0x38(%rbp)
jmp 0x11c42d
movq -0x38(%rbp), %rax
movq %rax, -0x40(%rbp)
movss -0x2c(%rbp), %xmm0
addss -0x30(%rbp), %xmm0
addss -0x28(%rbp), %xmm0
movss %xmm0, -0x28(%rbp)
xorps %xmm0, %xmm0
movss %xmm0, -0x30(%rbp)
xorps %xmm0, %xmm0
movss %xmm0, -0x2c(%rbp)
xorl %eax, %eax
cmpl $0x2e, -0x54(%rbp)
movb %al, -0x7d(%rbp)
je 0x11c46e
xorl %eax, %eax
cmpl $0x2c, -0x54(%rbp)
movb %al, -0x7d(%rbp)
je 0x11c46e
xorl %eax, %eax
cmpl $0x3b, -0x54(%rbp)
movb %al, -0x7d(%rbp)
je 0x11c46e
xorl %eax, %eax
cmpl $0x21, -0x54(%rbp)
movb %al, -0x7d(%rbp)
je 0x11c46e
xorl %eax, %eax
cmpl $0x3f, -0x54(%rbp)
movb %al, -0x7d(%rbp)
je 0x11c46e
cmpl $0x22, -0x54(%rbp)
setne %al
movb %al, -0x7d(%rbp)
movb -0x7d(%rbp), %al
andb $0x1, %al
movb %al, -0x41(%rbp)
movss -0x28(%rbp), %xmm0
addss -0x2c(%rbp), %xmm0
ucomiss -0x24(%rbp), %xmm0
jbe 0x11c4c1
movss -0x2c(%rbp), %xmm1
movss -0x24(%rbp), %xmm0
ucomiss %xmm1, %xmm0
jbe 0x11c4bf
cmpq $0x0, -0x40(%rbp)
je 0x11c4a9
movq -0x40(%rbp), %rax
movq %rax, -0x88(%rbp)
jmp 0x11c4b4
movq -0x38(%rbp), %rax
movq %rax, -0x88(%rbp)
movq -0x88(%rbp), %rax
movq %rax, -0x50(%rbp)
jmp 0x11c4ce
movq -0x60(%rbp), %rax
movq %rax, -0x50(%rbp)
jmp 0x11c2b0
movq -0x50(%rbp), %rax
addq $0x90, %rsp
popq %rbp
retq
nopl (%rax,%rax)