// File: /workspace/github_c_makefile_star2_O3/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 0x8792
testq %rsi, %rsi
je 0x87b1
testq %r8, %r8
je 0x87d0
movq %r9, %r13
movq %rdi, %r12
movl %edx, 0x24(%rsp)
movq %rcx, 0x40(%rsp)
movq %r8, 0x48(%rsp)
orb $0x1, (%rsi)
cmpw $0x0, 0x4c(%rdi)
movq %rsi, 0x18(%rsp)
movq %r9, 0x28(%rsp)
je 0x81fe
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, (%rsi,%r15,4)
je 0x81d9
movzwl %bx, %esi
movq %r12, %rdi
callq 0x4ad0
testl %eax, %eax
js 0x8754
je 0x81d4
movl %eax, %ebp
movq %r12, %rdi
movl %ebx, %esi
movl %ebx, %edx
movq %r13, %rcx
callq 0x8813
movq %r13, %rsi
addl 0x10(%rsp), %ebp
addl %eax, %ebp
movl %ebp, %eax
movq %rax, 0x10(%rsp)
jmp 0x81d9
movq 0x18(%rsp), %rsi
incl %ebx
addl %r14d, %r14d
movzwl 0x4c(%r12), %ebp
movzwl %bp, %eax
cmpl %eax, %ebx
jb 0x8184
leal 0x2(,%rax,2), %eax
movq 0x10(%rsp), %r15
movq 0x28(%rsp), %r13
jmp 0x8208
movl $0x2, %eax
xorl %ebp, %ebp
xorl %r15d, %r15d
movzwl 0x4a(%r12), %r14d
leal 0x1(%r14), %ecx
imull %eax, %ecx
movq %rcx, 0x38(%rsp)
leal 0x3(%rcx), %edi
andl $0x7ffffffc, %edi       # imm = 0x7FFFFFFC
callq 0x21c0
movq %rax, %rbx
leal 0x3(%r15), %edi
andl $-0x4, %edi
callq 0x21c0
movq %rbx, 0x8(%rsp)
testq %rbx, %rbx
je 0x87ef
testq %rax, %rax
je 0x87ef
testw %bp, %bp
je 0x832a
movq %r15, 0x10(%rsp)
movq %rax, 0x30(%rsp)
movl $0x1, %ecx
xorl %r14d, %r14d
xorl %r13d, %r13d
xorl %ebx, %ebx
movl %ecx, %r15d
movq 0x18(%rsp), %rsi
cmpl $0x1, %ecx
adcl $0x0, %r15d
cmpl $0x1, %ecx
adcl $0x0, %r13d
testb $0x1, %bl
jne 0x8735
cmpw $0x0, 0x4a(%r12)
je 0x82a5
movl %ebx, %eax
bswapl %eax
movq 0x8(%rsp), %rcx
movl %eax, (%rcx,%r14,4)
jmp 0x82bc
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 0x82fe
movzwl %r14w, %esi
movq %r12, %rdi
callq 0x4ad0
testl %eax, %eax
js 0x8773
movl %eax, %ebp
movl %ebx, %edi
addq 0x30(%rsp), %rdi
movq 0x80(%r12), %rsi
movl %eax, %edx
callq 0x2100
addl %ebp, %ebx
movzwl 0x4c(%r12), %ebp
movq 0x18(%rsp), %rsi
incq %r14
addl %r15d, %r15d
movzwl %bp, %edx
movl %r15d, %ecx
cmpq %rdx, %r14
jb 0x8276
movzwl 0x4a(%r12), %r14d
movq 0x28(%rsp), %r13
movq 0x30(%rsp), %rax
movq 0x10(%rsp), %r15
jmp 0x832e
xorl %ebx, %ebx
xorl %edx, %edx
testw %r14w, %r14w
je 0x8344
movl %edx, %esi
movl %ebx, %ecx
bswapl %ecx
movq 0x8(%rsp), %rdx
movl %ecx, (%rdx,%rsi,4)
jmp 0x835b
movl %edx, %edi
movl %ebx, %ecx
shrl %ecx
movl %ebx, %edx
shrl $0x9, %edx
movq 0x8(%rsp), %rsi
movb %dl, (%rsi,%rdi,2)
movb %cl, 0x1(%rsi,%rdi,2)
cmpl %r15d, %ebx
jne 0x87f4
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 0xb72(%rip), %rsi       # 0x8f19
movq %rsi, 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 %rsi, 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 %rsi, 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 0xb98(%rip), %rdx       # 0x8ff9
movq %rdx, 0x198(%rsp)
movq %rax, %rbx
movq %rax, 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 %rsi, 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 %rsi, 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 %rsi, 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), %rax
movl %eax, 0x2e8(%rsp)
movaps %xmm0, 0x310(%rsp)
movaps %xmm0, 0x300(%rsp)
movaps %xmm0, 0x2f0(%rsp)
movq $0x6d617870, 0x320(%rsp) # imm = 0x6D617870
movq %rsi, 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 %rsi, 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 %rsi, 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)
jne 0x86b3
movq %rsi, 0x58(%rsp)
movq %rsi, 0x3c8(%rsp)
leaq 0x50(%rsp), %r15
movq %r12, %rdi
movq %r15, %rsi
callq 0x802c
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 0x8d68
movq %rax, 0x10(%r12)
movq %r12, %rdi
movq 0x40(%rsp), %rsi
movq 0x48(%rsp), %rdx
movq %r13, %rcx
callq 0x909a
movl %eax, %ebp
movq 0x10(%r12), %rdi
callq 0x21a0
movq 0x8(%rsp), %rdi
callq 0x21a0
movq %rbx, %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 0x327d(%rip), %rdi      # 0xb9b9
leaq 0x3172(%rip), %rsi      # 0xb8b5
leaq 0x3203(%rip), %rcx      # 0xb94d
movl $0xbb, %edx
callq 0x20e0
leaq 0x2565(%rip), %rdi      # 0xacc0
leaq 0x3153(%rip), %rsi      # 0xb8b5
leaq 0x31e4(%rip), %rcx      # 0xb94d
movl $0x99, %edx
callq 0x20e0
leaq 0x324b(%rip), %rdi      # 0xb9c5
leaq 0x3134(%rip), %rsi      # 0xb8b5
leaq 0x31c5(%rip), %rcx      # 0xb94d
movl $0xc5, %edx
callq 0x20e0
leaq 0x189f(%rip), %rdi      # 0xa038
leaq 0x3115(%rip), %rsi      # 0xb8b5
leaq 0x31a6(%rip), %rcx      # 0xb94d
movl $0x88, %edx
callq 0x20e0
leaq 0x31fa(%rip), %rdi      # 0xb9b2
leaq 0x30f6(%rip), %rsi      # 0xb8b5
leaq 0x3187(%rip), %rcx      # 0xb94d
movl $0x89, %edx
callq 0x20e0
leaq 0x2242(%rip), %rdi      # 0xaa19
leaq 0x30d7(%rip), %rsi      # 0xb8b5
leaq 0x3168(%rip), %rcx      # 0xb94d
movl $0x8a, %edx
callq 0x20e0
callq 0x2e1a
leaq 0x31d1(%rip), %rdi      # 0xb9cc
leaq 0x30b3(%rip), %rsi      # 0xb8b5
leaq 0x3144(%rip), %rcx      # 0xb94d
movl $0xd0, %edx
callq 0x20e0