// File: /workspace/github_c_makefile_star2_O1/smilingthax[P]libfontembed/sfnt_subset.c
// Function: otf_subset2
int otf_subset2(OTF_FILE *otf,BITSET glyphs,SUBSET_DESTINATION dest,struct _OTF_WRITE_WOFF *woff,OUTPUT_FN output,void *context) // {{{ - returns number of bytes written
{
  assert(otf);
  assert(glyphs);
  assert(output);

  int iA,b,c;

  // first pass: include all required glyphs
  bit_set(glyphs,0); // .notdef always required
  int glyfSize=0;
  for (iA=0,b=0,c=1;iA<otf->numGlyphs;iA++,c<<=1) {
    if (!c) {
      b++;
      c=1;
    }
    if (glyphs[b]&c) {
      int len=otf_get_glyph(otf,iA);
      if (len<0) {
        assert(0);
        return -1;
      } else if (len>0) {
        glyfSize+=len;
        len=otf_subset_glyf(otf,iA,iA,glyphs);
        if (len<0) {
          assert(0);
          return -1;
        }
        glyfSize+=len;
      }
    }
  }

  // second pass: calculate new glyf and loca
  int locaSize=(otf->numGlyphs+1)*(otf->indexToLocFormat+1)*2;

  char *new_loca=malloc(otf_padded(locaSize));
  char *new_glyf=malloc(otf_padded(glyfSize));
  if ( (!new_loca)||(!new_glyf) ) {
    fprintf(stderr,"Bad alloc: %s\n", strerror(errno));
    assert(0);
    free(new_loca);
    free(new_glyf);
    return -1;
  }

  int offset=0;
  for (iA=0,b=0,c=1;iA<otf->numGlyphs;iA++,c<<=1) {
    if (!c) {
      b++;
      c=1;
    }

    assert(offset%2==0);
    // TODO? change format? if glyfSize<0x20000
    if (otf->indexToLocFormat==0) {
      set_USHORT(new_loca+iA*2,offset/2);
    } else { // ==1
      set_ULONG(new_loca+iA*4,offset);
    }

    if (glyphs[b]&c) {
      const int len=otf_get_glyph(otf,iA);
      assert(len>=0);
      memcpy(new_glyf+offset,otf->gly,len);
      offset+=len;
    }
  }
  // last entry
  if (otf->indexToLocFormat==0) {
    set_USHORT(new_loca+otf->numGlyphs*2,offset/2);
  } else { // ==1
    set_ULONG(new_loca+otf->numGlyphs*4,offset);
  }
  assert(offset==glyfSize);

  // determine new tables.
  struct _OTF_WRITE_TABLE tables[]={ // sorted
    // TODO: cmap only required in non-CID context   or always in CFF
      {OTF_TAG('O','S','/','2'),NULL,.copy={otf,}}, // 0
      {OTF_TAG('c','m','a','p'),otf_action_copy,.copy={otf,}},
      {OTF_TAG('c','v','t',' '),otf_action_copy,.copy={otf,}},
      {OTF_TAG('f','p','g','m'),otf_action_copy,.copy={otf,}},
      {OTF_TAG('g','l','y','f'),otf_action_replace,.replace={new_glyf,glyfSize}},
      {OTF_TAG('h','e','a','d'),otf_action_copy,.copy={otf,}}, // 5 // _copy_head
      {OTF_TAG('h','h','e','a'),otf_action_copy,.copy={otf,}},
      {OTF_TAG('h','m','t','x'),otf_action_copy,.copy={otf,}},
      {OTF_TAG('l','o','c','a'),otf_action_replace,.replace={new_loca,locaSize}},
      {OTF_TAG('m','a','x','p'),otf_action_copy,.copy={otf,}},
      {OTF_TAG('n','a','m','e'),otf_action_copy,.copy={otf,}}, // 10
      {OTF_TAG('p','o','s','t'),NULL,.copy={otf,}},
      {OTF_TAG('p','r','e','p'),otf_action_copy,.copy={otf,}},
      // vhea vmtx (never used in PDF, but possible in PS>=3011)
      {0,0,}};
  if (dest==SUBSET_DST_BROWSER) {
    // esp. chrome:
    tables[0].action=otf_action_copy; // OS/2
    tables[11].action=otf_action_copy; // post
  }

  // and write them
  int numTables=otf_intersect_tables(otf,tables);
  struct _OTF_WRITE_INFO otw={
    .version=otf->version,
    .numTables=numTables,
    .tables=tables,
    .order=otf_tagorder_win_sort(tables,numTables)
  };
  const int ret=otf_write_sfnt(&otw,woff,output,context);

  free(otw.order);
  free(new_loca);
  free(new_glyf);
  return ret;

  //TODO ? reduce cmap [to (1,0) ;-)]
  //TODO (cmap for non-cid)
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x4c8, %rsp            # imm = 0x4C8
movq %r9, 0x28(%rsp)
testq %rdi, %rdi
je 0x8840
movq %rsi, %rbp
testq %rsi, %rsi
je 0x885f
testq %r8, %r8
je 0x887e
movq %rdi, %r12
movl %edx, 0x24(%rsp)
movq %rcx, 0x40(%rsp)
movq %r8, 0x48(%rsp)
orb $0x1, (%rbp)
movzwl 0x4c(%rdi), %eax
testl %eax, %eax
movq %rbp, 0x18(%rsp)
je 0x82a3
movl $0x1, %r14d
xorl %ebx, %ebx
xorl %r15d, %r15d
movq $0x0, 0x10(%rsp)
movq 0x18(%rsp), %r13
movl %r14d, %eax
cmpl $0x1, %r14d
adcl $0x0, %r14d
cmpl $0x1, %eax
adcl $0x0, %r15d
testl %r14d, (%rbp,%r15,4)
je 0x8292
movzwl %bx, %esi
movq %r12, %rdi
callq 0x4b02
testl %eax, %eax
js 0x8802
je 0x828d
movl %eax, %ebp
movq %r12, %rdi
movl %ebx, %esi
movl %ebx, %edx
movq %r13, %rcx
callq 0x88c1
addl 0x10(%rsp), %ebp
addl %eax, %ebp
movl %ebp, %eax
movq %r13, %rbp
movq %rax, 0x10(%rsp)
jmp 0x8292
movq 0x18(%rsp), %rbp
incl %ebx
addl %r14d, %r14d
movzwl 0x4c(%r12), %eax
cmpl %eax, %ebx
jb 0x823c
jmp 0x82ac
movq $0x0, 0x10(%rsp)
movzwl 0x4a(%r12), %ecx
incl %ecx
leal 0x2(,%rax,2), %eax
imull %ecx, %eax
movq %rax, 0x38(%rsp)
leal 0x3(%rax), %edi
andl $0x7ffffffc, %edi       # imm = 0x7FFFFFFC
callq 0x21c0
movq %rax, %rbx
movq 0x10(%rsp), %r15
leal 0x3(%r15), %edi
andl $-0x4, %edi
callq 0x21c0
movq %rbx, 0x8(%rsp)
testq %rbx, %rbx
je 0x889d
movq %rax, %r14
testq %rax, %rax
je 0x889d
movzwl 0x4c(%r12), %eax
testw %ax, %ax
je 0x83cf
movq %r14, 0x30(%rsp)
movl $0x1, %ecx
xorl %r14d, %r14d
xorl %r13d, %r13d
xorl %ebx, %ebx
movl %ecx, %r15d
cmpl $0x1, %ecx
adcl $0x0, %r15d
cmpl $0x1, %ecx
adcl $0x0, %r13d
testb $0x1, %bl
jne 0x87e3
cmpw $0x0, 0x4a(%r12)
je 0x8352
movl %ebx, %eax
bswapl %eax
movq 0x8(%rsp), %rcx
movl %eax, (%rcx,%r14,4)
jmp 0x8369
movl %ebx, %eax
shrl %eax
movl %ebx, %ecx
shrl $0x9, %ecx
movq 0x8(%rsp), %rdx
movb %cl, (%rdx,%r14,2)
movb %al, 0x1(%rdx,%r14,2)
movl %r13d, %eax
testl %r15d, (%rbp,%rax,4)
je 0x83a6
movzwl %r14w, %esi
movq %r12, %rdi
callq 0x4b02
testl %eax, %eax
js 0x8821
movl %eax, %ebp
movl %ebx, %edi
addq 0x30(%rsp), %rdi
movq 0x80(%r12), %rsi
movl %eax, %edx
callq 0x2100
addl %ebp, %ebx
movq 0x18(%rsp), %rbp
incq %r14
addl %r15d, %r15d
movzwl 0x4c(%r12), %eax
movl %r15d, %ecx
cmpq %rax, %r14
jb 0x8323
movq 0x28(%rsp), %r13
movq 0x30(%rsp), %r14
movq 0x10(%rsp), %r15
jmp 0x83d6
xorl %ebx, %ebx
movq 0x28(%rsp), %r13
movzwl %ax, %eax
cmpw $0x0, 0x4a(%r12)
je 0x83f2
movl %eax, %eax
movl %ebx, %ecx
bswapl %ecx
movq 0x8(%rsp), %rdx
movl %ecx, (%rdx,%rax,4)
jmp 0x8409
movl %eax, %eax
movl %ebx, %ecx
shrl %ecx
movl %ebx, %edx
shrl $0x9, %edx
movq 0x8(%rsp), %rsi
movb %dl, (%rsi,%rax,2)
movb %cl, 0x1(%rsi,%rax,2)
cmpl %r15d, %ebx
jne 0x88a2
xorps %xmm0, %xmm0
movaps %xmm0, 0x50(%rsp)
movaps %xmm0, 0x60(%rsp)
movaps %xmm0, 0x90(%rsp)
movaps %xmm0, 0x80(%rsp)
movaps %xmm0, 0x70(%rsp)
movq $0x4f532f32, 0x50(%rsp) # imm = 0x4F532F32
movq %r12, 0x60(%rsp)
movq $0x636d6170, 0xa0(%rsp) # imm = 0x636D6170
leaq 0xb73(%rip), %rax       # 0x8fc8
movq %rax, 0xa8(%rsp)
movq %r12, 0xb0(%rsp)
xorl %ecx, %ecx
movl %ecx, 0xb8(%rsp)
movaps %xmm0, 0xc0(%rsp)
movaps %xmm0, 0xd0(%rsp)
movaps %xmm0, 0xe0(%rsp)
movq $0x63767420, 0xf0(%rsp) # imm = 0x63767420
movq %rax, 0xf8(%rsp)
movq %r12, 0x100(%rsp)
movl %ecx, 0x108(%rsp)
movaps %xmm0, 0x110(%rsp)
movaps %xmm0, 0x120(%rsp)
movaps %xmm0, 0x130(%rsp)
movq $0x6670676d, 0x140(%rsp) # imm = 0x6670676D
movq %rax, 0x148(%rsp)
movq %r12, 0x150(%rsp)
movl %ecx, 0x158(%rsp)
movaps %xmm0, 0x160(%rsp)
movaps %xmm0, 0x170(%rsp)
movaps %xmm0, 0x180(%rsp)
movq $0x676c7966, 0x190(%rsp) # imm = 0x676C7966
leaq 0xb9d(%rip), %rdx       # 0x90ac
movq %rdx, 0x198(%rsp)
movq %r14, 0x1a0(%rsp)
movl %r15d, 0x1a8(%rsp)
movaps %xmm0, 0x1b0(%rsp)
movaps %xmm0, 0x1c0(%rsp)
movaps %xmm0, 0x1d0(%rsp)
movq $0x68656164, 0x1e0(%rsp) # imm = 0x68656164
movq %rax, 0x1e8(%rsp)
movq %r12, 0x1f0(%rsp)
movl %ecx, 0x1f8(%rsp)
movaps %xmm0, 0x220(%rsp)
movaps %xmm0, 0x210(%rsp)
movaps %xmm0, 0x200(%rsp)
movq $0x68686561, 0x230(%rsp) # imm = 0x68686561
movq %rax, 0x238(%rsp)
movq %r12, 0x240(%rsp)
movl %ecx, 0x248(%rsp)
movaps %xmm0, 0x270(%rsp)
movaps %xmm0, 0x260(%rsp)
movaps %xmm0, 0x250(%rsp)
movq $0x686d7478, 0x280(%rsp) # imm = 0x686D7478
movq %rax, 0x288(%rsp)
movq %r12, 0x290(%rsp)
movl %ecx, 0x298(%rsp)
movaps %xmm0, 0x2c0(%rsp)
movaps %xmm0, 0x2b0(%rsp)
movaps %xmm0, 0x2a0(%rsp)
movq $0x6c6f6361, 0x2d0(%rsp) # imm = 0x6C6F6361
movq %rdx, 0x2d8(%rsp)
movq 0x8(%rsp), %rdx
movq %rdx, 0x2e0(%rsp)
movq 0x38(%rsp), %rdx
movl %edx, 0x2e8(%rsp)
movaps %xmm0, 0x310(%rsp)
movaps %xmm0, 0x300(%rsp)
movaps %xmm0, 0x2f0(%rsp)
movq $0x6d617870, 0x320(%rsp) # imm = 0x6D617870
movq %rax, 0x328(%rsp)
movq %r12, 0x330(%rsp)
movl %ecx, 0x338(%rsp)
movaps %xmm0, 0x360(%rsp)
movaps %xmm0, 0x350(%rsp)
movaps %xmm0, 0x340(%rsp)
movq $0x6e616d65, 0x370(%rsp) # imm = 0x6E616D65
movq %rax, 0x378(%rsp)
movq %r12, 0x380(%rsp)
movl %ecx, 0x388(%rsp)
movaps %xmm0, 0x400(%rsp)
movaps %xmm0, 0x3f0(%rsp)
movaps %xmm0, 0x3e0(%rsp)
movaps %xmm0, 0x3d0(%rsp)
movaps %xmm0, 0x3c0(%rsp)
movaps %xmm0, 0x3b0(%rsp)
movaps %xmm0, 0x3a0(%rsp)
movaps %xmm0, 0x390(%rsp)
movq $0x706f7374, 0x3c0(%rsp) # imm = 0x706F7374
movq %r12, 0x3d0(%rsp)
movq $0x70726570, 0x410(%rsp) # imm = 0x70726570
movq %rax, 0x418(%rsp)
movq %r12, 0x420(%rsp)
movl %ecx, 0x428(%rsp)
movaps %xmm0, 0x4a0(%rsp)
movaps %xmm0, 0x490(%rsp)
movaps %xmm0, 0x480(%rsp)
movaps %xmm0, 0x470(%rsp)
movaps %xmm0, 0x460(%rsp)
movaps %xmm0, 0x450(%rsp)
movaps %xmm0, 0x440(%rsp)
movaps %xmm0, 0x430(%rsp)
cmpl $0x1, 0x24(%rsp)
movq 0x48(%rsp), %rbx
jne 0x8763
movq %rax, 0x58(%rsp)
movq %rax, 0x3c8(%rsp)
leaq 0x50(%rsp), %r15
movq %r12, %rdi
movq %r15, %rsi
callq 0x80e2
movl 0x14(%r12), %ecx
leaq 0x4b0(%rsp), %r12
movl %ecx, (%r12)
movw %ax, 0x4(%r12)
movq %r15, 0x8(%r12)
movq %r15, %rdi
movl %eax, %esi
callq 0x8e10
movq %rax, 0x10(%r12)
movq %r12, %rdi
movq 0x40(%rsp), %rsi
movq %rbx, %rdx
movq %r13, %rcx
callq 0x914d
movl %eax, %ebp
movq 0x10(%r12), %rdi
callq 0x21a0
movq 0x8(%rsp), %rdi
callq 0x21a0
movq %r14, %rdi
callq 0x21a0
movl %ebp, %eax
addq $0x4c8, %rsp            # imm = 0x4C8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x31cf(%rip), %rdi      # 0xb9b9
leaq 0x30c4(%rip), %rsi      # 0xb8b5
leaq 0x3155(%rip), %rcx      # 0xb94d
movl $0xbb, %edx
callq 0x20e0
leaq 0x24b7(%rip), %rdi      # 0xacc0
leaq 0x30a5(%rip), %rsi      # 0xb8b5
leaq 0x3136(%rip), %rcx      # 0xb94d
movl $0x99, %edx
callq 0x20e0
leaq 0x319d(%rip), %rdi      # 0xb9c5
leaq 0x3086(%rip), %rsi      # 0xb8b5
leaq 0x3117(%rip), %rcx      # 0xb94d
movl $0xc5, %edx
callq 0x20e0
leaq 0x17f1(%rip), %rdi      # 0xa038
leaq 0x3067(%rip), %rsi      # 0xb8b5
leaq 0x30f8(%rip), %rcx      # 0xb94d
movl $0x88, %edx
callq 0x20e0
leaq 0x314c(%rip), %rdi      # 0xb9b2
leaq 0x3048(%rip), %rsi      # 0xb8b5
leaq 0x30d9(%rip), %rcx      # 0xb94d
movl $0x89, %edx
callq 0x20e0
leaq 0x2194(%rip), %rdi      # 0xaa19
leaq 0x3029(%rip), %rsi      # 0xb8b5
leaq 0x30ba(%rip), %rcx      # 0xb94d
movl $0x8a, %edx
callq 0x20e0
callq 0x2e12
leaq 0x3123(%rip), %rdi      # 0xb9cc
leaq 0x3005(%rip), %rsi      # 0xb8b5
leaq 0x3096(%rip), %rcx      # 0xb94d
movl $0xd0, %edx
callq 0x20e0