// File: /workspace/github_c_makefile_star2_O2/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
testq %rdi, %rdi
je 0x7fc3
movq %rsi, %r13
testq %rsi, %rsi
je 0x7fe2
testq %r8, %r8
je 0x8001
movq %rdi, %r12
movq %r9, 0x38(%rsp)
movl %edx, 0x14(%rsp)
movq %rcx, 0x48(%rsp)
movq %r8, 0x30(%rsp)
orb $0x1, (%r13)
pushq $0x1
popq %rax
movq $0x0, 0x18(%rsp)
xorl %r14d, %r14d
xorl %ebx, %ebx
movq %r13, 0x20(%rsp)
movzwl 0x4c(%r12), %ebp
movzwl %bp, %ecx
cmpl %ecx, %ebx
jae 0x7a3f
cmpl $0x1, %eax
movl %eax, %r15d
adcl $0x0, %r15d
cmpl $0x1, %eax
adcl $0x0, %r14d
testl %r15d, (%r13,%r14,4)
je 0x7a35
movzwl %bx, %esi
movq %r12, %rdi
callq 0x4137
testl %eax, %eax
js 0x7f85
je 0x7a30
movl %eax, %ebp
movq %r12, %rdi
movl %ebx, %esi
movl %ebx, %edx
movq 0x20(%rsp), %r13
movq %r13, %rcx
callq 0x8088
addl 0x18(%rsp), %ebp
addl %eax, %ebp
movl %ebp, %eax
movq %rax, 0x18(%rsp)
jmp 0x7a35
movq 0x20(%rsp), %r13
incl %ebx
addl %r15d, %r15d
movl %r15d, %eax
jmp 0x79d1
movzwl 0x4a(%r12), %eax
incl %eax
leal 0x2(,%rcx,2), %ecx
imull %eax, %ecx
movq %rcx, 0x40(%rsp)
leal 0x3(%rcx), %edi
andl $0x7ffffffc, %edi       # imm = 0x7FFFFFFC
callq 0x21d0
movq %rax, %rbx
movq 0x18(%rsp), %rax
leal 0x3(%rax), %edi
andl $-0x4, %edi
callq 0x21d0
movq %rbx, 0x8(%rsp)
testq %rbx, %rbx
je 0x8020
testq %rax, %rax
je 0x8020
movq %rax, 0x28(%rsp)
pushq $0x1
popq %rax
xorl %r14d, %r14d
xorl %ebx, %ebx
xorl %r13d, %r13d
movq 0x20(%rsp), %rsi
movzwl %bp, %edx
movl %ebx, %ecx
bswapl %ecx
cmpq %rdx, %r14
jae 0x7b48
cmpl $0x1, %eax
movl %eax, %r15d
adcl $0x0, %r15d
cmpl $0x1, %eax
adcl $0x0, %r13d
testb $0x1, %bl
jne 0x7f66
cmpw $0x0, 0x4a(%r12)
je 0x7ae1
movq 0x8(%rsp), %rax
movl %ecx, (%rax,%r14,4)
jmp 0x7af8
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, (%rsi,%rax,4)
je 0x7b3a
movzwl %r14w, %esi
movq %r12, %rdi
callq 0x4137
testl %eax, %eax
js 0x7fa4
movl %eax, %ebp
movl %ebx, %edi
addq 0x28(%rsp), %rdi
movq 0x80(%r12), %rsi
movl %eax, %edx
callq 0x2110
addl %ebp, %ebx
movzwl 0x4c(%r12), %ebp
movq 0x20(%rsp), %rsi
incq %r14
addl %r15d, %r15d
movl %r15d, %eax
jmp 0x7aa3
cmpw $0x0, 0x4a(%r12)
je 0x7b5d
movl %edx, %eax
movq 0x8(%rsp), %rdx
movl %ecx, (%rdx,%rax,4)
jmp 0x7b74
movl %edx, %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)
movq 0x38(%rsp), %r14
movq 0x30(%rsp), %r13
movl 0x14(%rsp), %edx
movq 0x18(%rsp), %rdi
cmpl %edi, %ebx
jne 0x8069
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 0xbfb(%rip), %rax       # 0x87cd
movq %rax, 0xa8(%rsp)
movq %r12, 0xb0(%rsp)
andl $0x0, 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)
andl $0x0, 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)
andl $0x0, 0x158(%rsp)
movaps %xmm0, 0x160(%rsp)
movaps %xmm0, 0x170(%rsp)
movaps %xmm0, 0x180(%rsp)
movq $0x676c7966, 0x190(%rsp) # imm = 0x676C7966
leaq 0xc11(%rip), %rcx       # 0x889e
movq %rcx, 0x198(%rsp)
movq 0x28(%rsp), %rsi
movq %rsi, 0x1a0(%rsp)
movl %edi, 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)
andl $0x0, 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)
andl $0x0, 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)
andl $0x0, 0x298(%rsp)
movaps %xmm0, 0x2c0(%rsp)
movaps %xmm0, 0x2b0(%rsp)
movaps %xmm0, 0x2a0(%rsp)
movq $0x6c6f6361, 0x2d0(%rsp) # imm = 0x6C6F6361
movq %rcx, 0x2d8(%rsp)
movq 0x8(%rsp), %rcx
movq %rcx, 0x2e0(%rsp)
movq 0x40(%rsp), %rcx
movl %ecx, 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)
andl $0x0, 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)
andl $0x0, 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)
andl $0x0, 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, %edx
jne 0x7ee4
movq %rax, 0x58(%rsp)
movq %rax, 0x3c8(%rsp)
leaq 0x50(%rsp), %r15
movq %r12, %rdi
movq %r15, %rsi
callq 0x7860
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 0x85e8
movq %rax, 0x10(%r12)
movq %r12, %rdi
movq 0x48(%rsp), %rsi
movq %r13, %rdx
movq %r14, %rcx
callq 0x894c
movl %eax, %ebp
movq 0x10(%r12), %rdi
callq 0x21b0
movq 0x8(%rsp), %rdi
callq 0x21b0
movq 0x28(%rsp), %rdi
callq 0x21b0
movl %ebp, %eax
addq $0x4c8, %rsp            # imm = 0x4C8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x3a4c(%rip), %rdi      # 0xb9b9
leaq 0x3941(%rip), %rsi      # 0xb8b5
leaq 0x39d2(%rip), %rcx      # 0xb94d
movl $0xbb, %edx
callq 0x20f0
leaq 0x2d34(%rip), %rdi      # 0xacc0
leaq 0x3922(%rip), %rsi      # 0xb8b5
leaq 0x39b3(%rip), %rcx      # 0xb94d
movl $0x99, %edx
callq 0x20f0
leaq 0x3a1a(%rip), %rdi      # 0xb9c5
leaq 0x3903(%rip), %rsi      # 0xb8b5
leaq 0x3994(%rip), %rcx      # 0xb94d
movl $0xc5, %edx
callq 0x20f0
leaq 0x206e(%rip), %rdi      # 0xa038
leaq 0x38e4(%rip), %rsi      # 0xb8b5
leaq 0x3975(%rip), %rcx      # 0xb94d
movl $0x88, %edx
callq 0x20f0
leaq 0x39c9(%rip), %rdi      # 0xb9b2
leaq 0x38c5(%rip), %rsi      # 0xb8b5
leaq 0x3956(%rip), %rcx      # 0xb94d
movl $0x89, %edx
callq 0x20f0
leaq 0x2a11(%rip), %rdi      # 0xaa19
leaq 0x38a6(%rip), %rsi      # 0xb8b5
leaq 0x3937(%rip), %rcx      # 0xb94d
movl $0x8a, %edx
callq 0x20f0
movq 0x6fb9(%rip), %rax      # 0xefe0
movq (%rax), %rbx
callq 0x2040
movl (%rax), %edi
callq 0x2070
leaq 0x231c(%rip), %rsi      # 0xa359
movq %rbx, %rdi
movq %rax, %rdx
xorl %eax, %eax
callq 0x21e0
leaq 0x2c6f(%rip), %rdi      # 0xacc0
leaq 0x385d(%rip), %rsi      # 0xb8b5
leaq 0x38ee(%rip), %rcx      # 0xb94d
movl $0xae, %edx
callq 0x20f0
leaq 0x395c(%rip), %rdi      # 0xb9cc
leaq 0x383e(%rip), %rsi      # 0xb8b5
leaq 0x38cf(%rip), %rcx      # 0xb94d
movl $0xd0, %edx
callq 0x20f0