// File: /workspace/github_c_makefile_star2_O2/ggerganov[P]font-rasterizer/./stb_truetype.h
// Function: stbtt_FindGlyphIndex
STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codepoint)
{
   stbtt_uint8 *data = info->data;
   stbtt_uint32 index_map = info->index_map;

   stbtt_uint16 format = ttUSHORT(data + index_map + 0);
   if (format == 0) { // apple byte encoding
      stbtt_int32 bytes = ttUSHORT(data + index_map + 2);
      if (unicode_codepoint < bytes-6)
         return ttBYTE(data + index_map + 6 + unicode_codepoint);
      return 0;
   } else if (format == 6) {
      stbtt_uint32 first = ttUSHORT(data + index_map + 6);
      stbtt_uint32 count = ttUSHORT(data + index_map + 8);
      if ((stbtt_uint32) unicode_codepoint >= first && (stbtt_uint32) unicode_codepoint < first+count)
         return ttUSHORT(data + index_map + 10 + (unicode_codepoint - first)*2);
      return 0;
   } else if (format == 2) {
      STBTT_assert(0); // @TODO: high-byte mapping for japanese/chinese/korean
      return 0;
   } else if (format == 4) { // standard mapping for windows fonts: binary search collection of ranges
      stbtt_uint16 segcount = ttUSHORT(data+index_map+6) >> 1;
      stbtt_uint16 searchRange = ttUSHORT(data+index_map+8) >> 1;
      stbtt_uint16 entrySelector = ttUSHORT(data+index_map+10);
      stbtt_uint16 rangeShift = ttUSHORT(data+index_map+12) >> 1;

      // do a binary search of the segments
      stbtt_uint32 endCount = index_map + 14;
      stbtt_uint32 search = endCount;

      if (unicode_codepoint > 0xffff)
         return 0;

      // they lie from endCount .. endCount + segCount
      // but searchRange is the nearest power of two, so...
      if (unicode_codepoint >= ttUSHORT(data + search + rangeShift*2))
         search += rangeShift*2;

      // now decrement to bias correctly to find smallest
      search -= 2;
      while (entrySelector) {
         stbtt_uint16 end;
         searchRange >>= 1;
         end = ttUSHORT(data + search + searchRange*2);
         if (unicode_codepoint > end)
            search += searchRange*2;
         --entrySelector;
      }
      search += 2;

      {
         stbtt_uint16 offset, start;
         stbtt_uint16 item = (stbtt_uint16) ((search - endCount) >> 1);

         STBTT_assert(unicode_codepoint <= ttUSHORT(data + endCount + 2*item));
         start = ttUSHORT(data + index_map + 14 + segcount*2 + 2 + 2*item);
         if (unicode_codepoint < start)
            return 0;

         offset = ttUSHORT(data + index_map + 14 + segcount*6 + 2 + 2*item);
         if (offset == 0)
            return (stbtt_uint16) (unicode_codepoint + ttSHORT(data + index_map + 14 + segcount*4 + 2 + 2*item));

         return ttUSHORT(data + offset + (unicode_codepoint-start)*2 + index_map + 14 + segcount*6 + 2 + 2*item);
      }
   } else if (format == 12 || format == 13) {
      stbtt_uint32 ngroups = ttULONG(data+index_map+12);
      stbtt_int32 low,high;
      low = 0; high = (stbtt_int32)ngroups;
      // Binary search the right group.
      while (low < high) {
         stbtt_int32 mid = low + ((high-low) >> 1); // rounds down, so low <= mid < high
         stbtt_uint32 start_char = ttULONG(data+index_map+16+mid*12);
         stbtt_uint32 end_char = ttULONG(data+index_map+16+mid*12+4);
         if ((stbtt_uint32) unicode_codepoint < start_char)
            high = mid;
         else if ((stbtt_uint32) unicode_codepoint > end_char)
            low = mid+1;
         else {
            stbtt_uint32 start_glyph = ttULONG(data+index_map+16+mid*12+8);
            if (format == 12)
               return start_glyph + unicode_codepoint-start_char;
            else // format == 13
               return start_glyph;
         }
      }
      return 0; // not found
   }
   // @TODO
   STBTT_assert(0);
   return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq 0x8(%rdi), %rcx
movl 0x34(%rdi), %eax
leaq (%rcx,%rax), %r15
movzwl (%rcx,%rax), %r8d
rolw $0x8, %r8w
cmpw $0x6, %r8w
ja 0x3521
movzwl %r8w, %edx
leaq 0x8b4d(%rip), %rdi      # 0xc040
movslq (%rdi,%rdx,4), %rdx
addq %rdi, %rdx
jmpq *%rdx
movzwl 0x2(%r15), %eax
rolw $0x8, %ax
movzwl %ax, %eax
addl $-0x6, %eax
cmpl %esi, %eax
jle 0x359e
movslq %esi, %rax
movzbl 0x6(%r15,%rax), %eax
jmp 0x3725
movl %esi, -0x2c(%rbp)
movl %r8d, -0x30(%rbp)
movl %r8d, %eax
andl $0xfffe, %eax           # imm = 0xFFFE
cmpw $0xc, %ax
jne 0x3750
leaq 0xc(%r15), %rdi
callq 0x37ad
movl %eax, %r12d
addq $0x10, %r15
movq %r15, -0x38(%rbp)
xorl %r13d, %r13d
movl %r12d, %r14d
movl %r14d, %r12d
subl %r13d, %r14d
jle 0x359e
sarl %r14d
addl %r13d, %r14d
imull $0xc, %r14d, %eax
movslq %eax, %r15
addq -0x38(%rbp), %r15
movq %r15, %rdi
callq 0x37ad
movl -0x2c(%rbp), %ebx
subl %eax, %ebx
jb 0x3554
leaq 0x4(%r15), %rdi
callq 0x37ad
cmpl -0x2c(%rbp), %eax
jae 0x3734
incl %r14d
movl %r14d, %r13d
jmp 0x3551
cmpl $0xffff, %esi           # imm = 0xFFFF
jle 0x35e7
xorl %eax, %eax
jmp 0x3725
movzwl 0x6(%r15), %eax
rolw $0x8, %ax
movzwl %ax, %edx
xorl %eax, %eax
movl %esi, %ecx
subl %edx, %ecx
jb 0x3725
movzwl 0x8(%r15), %edi
rolw $0x8, %di
movzwl %di, %edi
addl %edx, %edi
cmpl %esi, %edi
jbe 0x3725
addl %ecx, %ecx
movzwl 0xa(%r15,%rcx), %eax
rolw $0x8, %ax
movzwl %ax, %eax
jmp 0x3725
movzwl 0x6(%r15), %edx
rolw $0x8, %dx
movzwl %dx, %edi
movl %edi, %edx
shrl %edx
leal 0xe(%rax), %r8d
movzbl 0xc(%rcx,%rax), %ebx
shll $0x8, %ebx
movzwl 0xa(%rcx,%rax), %r9d
rolw $0x8, %r9w
movzwl 0x8(%rcx,%rax), %r10d
rolw $0x8, %r10w
movzbl 0xd(%rcx,%rax), %r11d
andl $-0x2, %r11d
orq %rbx, %r11
addq %rcx, %r8
movzwl (%r8,%r11), %ebx
rolw $0x8, %bx
movzwl %bx, %r14d
xorl %ebx, %ebx
cmpl %esi, %r14d
cmovgl %ebx, %r11d
leal (%rax,%r11), %r14d
addl $0xc, %r14d
subw $0x1, %r9w
jb 0x367d
movzwl %r10w, %r10d
shrl %r10d
movl %r14d, %ebx
addq %rcx, %rbx
movl %r10d, %r11d
andl $-0x2, %r11d
movzwl (%r11,%rbx), %ebx
rolw $0x8, %bx
movzwl %bx, %ebx
cmpl %esi, %ebx
jl 0x3675
xorl %r11d, %r11d
addl %r14d, %r11d
movl %r11d, %r14d
jmp 0x3647
subl %eax, %r14d
addl $0x1fff4, %r14d         # imm = 0x1FFF4
andl $0x1fffe, %r14d         # imm = 0x1FFFE
movzwl (%r8,%r14), %r8d
rolw $0x8, %r8w
movzwl %r8w, %r8d
cmpl %esi, %r8d
jl 0x378e
andl $-0x2, %edi
addq %r15, %rdi
addq $0xe, %rdi
movzwl 0x2(%r14,%rdi), %edi
rolw $0x8, %di
movzwl %di, %r9d
xorl %r8d, %r8d
movl %esi, %edi
subl %r9d, %edi
jl 0x3721
addq $0xe, %r15
movl %edx, %r8d
imulq $0x6, %r8, %rdx
leaq (%r15,%rdx), %r9
movzwl 0x2(%r14,%r9), %r9d
rolw $0x8, %r9w
testw %r9w, %r9w
je 0x370c
movzwl %r9w, %r8d
addq %r8, %rcx
addl %edi, %edi
movslq %edi, %rdi
addq %rcx, %rdi
addq %rdx, %rax
addq %rdi, %rax
movzwl 0x10(%r14,%rax), %eax
rolw $0x8, %ax
movzwl %ax, %r8d
jmp 0x3721
leaq (%r15,%r8,4), %rax
movzwl 0x2(%r14,%rax), %eax
rolw $0x8, %ax
movzwl %ax, %r8d
addl %esi, %r8d
movzwl %r8w, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
addq $0x8, %r15
movq %r15, %rdi
callq 0x37ad
movl %eax, %ecx
xorl %eax, %eax
cmpw $0xc, -0x30(%rbp)
cmovel %ebx, %eax
addl %ecx, %eax
jmp 0x3725
leaq 0xa60f(%rip), %rdi      # 0xdd66
leaq 0xa50a(%rip), %rsi      # 0xdc68
leaq 0xa514(%rip), %rcx      # 0xdc79
movl $0x5fd, %edx            # imm = 0x5FD
callq 0x10c0
leaq 0xa5f0(%rip), %rdi      # 0xdd66
leaq 0xa4eb(%rip), %rsi      # 0xdc68
leaq 0xa4f5(%rip), %rcx      # 0xdc79
movl $0x5b6, %edx            # imm = 0x5B6
callq 0x10c0
leaq 0xa51a(%rip), %rdi      # 0xdcaf
leaq 0xa4cc(%rip), %rsi      # 0xdc68
leaq 0xa4d6(%rip), %rcx      # 0xdc79
movl $0x5da, %edx            # imm = 0x5DA
callq 0x10c0