// File: /workspace/github_c_makefile_star2_O1/smilingthax[P]libfontembed/embed_sfnt.c
// Function: emb_otf_ps
int emb_otf_ps(OTF_FILE *otf,unsigned short *encoding,int len,unsigned short *to_unicode,OUTPUT_FN output,void *context) // {{{
{
  const int binary=0; // binary format? // TODO
  if (len>256) {
    fprintf(stderr,"Encoding too big(%d) for Type42\n",len);
    return -1;
  }
  if (len<1) {
    fprintf(stderr,"At least .notdef required in Type42\n");
    return -1;
  }
  if (!encoding) {
    to_unicode=NULL; // does not make sense
  }
  int iA,ret=0;

  DYN_STRING ds;
  if (dyn_init(&ds,1024)==-1) {
    return -1;
  }

  int rlen=0;
  char *head=otf_get_table(otf,OTF_TAG('h','e','a','d'),&rlen);
  if (!head) {
    free(ds.buf);
    return -1;
  }
  dyn_printf(&ds,"%%!PS-TrueTypeFont-%d-%d\n",
                 otf->version,get_ULONG(head+4));
  const int bbxmin=get_SHORT(head+36)*1000/otf->unitsPerEm,
            bbymin=get_SHORT(head+38)*1000/otf->unitsPerEm,
            bbxmax=get_SHORT(head+40)*1000/otf->unitsPerEm,
            bbymax=get_SHORT(head+42)*1000/otf->unitsPerEm;
  free(head);

  char *post=otf_get_table(otf,OTF_TAG('p','o','s','t'),&rlen);
  if ( (!post)&&(rlen!=-1) ) { // other error than "not found"
    free(ds.buf);
    return -1;
  }
  if (post) {
    const unsigned int minMem=get_ULONG(post+16),maxMem=get_ULONG(post+20);
    if (minMem) {
      dyn_printf(&ds,"%%VMusage: %d %d\n",minMem,maxMem);
    }
  }

  // don't forget the coordinate scaling...
  dyn_printf(&ds,"11 dict begin\n"
                 "/FontName /%s def\n"
                 "/FontType 42 def\n"
                 "/FontMatrix [1 0 0 1 0 0] def\n"
                 "/FontBBox [%f %f %f %f] def\n"
                 "/PaintType 0 def\n",
//                 "/XUID [42 16#%X 16#%X 16#%X 16#%X] def\n"  // TODO?!? (md5 of font data)  (16# means base16)
                 emb_otf_get_fontname(otf),
                 bbxmin/1000.0,bbymin/1000.0,bbxmax/1000.0,bbymax/1000.0);
  if (post) {
    dyn_printf(&ds,"/FontInfo 4 dict dup begin\n"
// TODO? [even non-post]: /version|/Notice|/Copyright|/FullName|/FamilyName|/Weight  () readonly def\n   from name table: 5 7 0 4 1 2
// using: otf_get_name(otf,3,1,0x409,?,&len) / otf_get_name(otf,1,0,0,?,&len)   + encoding
                   "  /ItalicAngle %d def\n"
                   "  /isFixedPitch %s def\n"
                   "  /UnderlinePosition %f def\n"
                   "  /UnderlineThickness %f def\n"
                   "end readonly def\n",
                   get_LONG(post+4)>>16,
                   (get_ULONG(post+12)?"true":"false"),
                   (get_SHORT(post+8)-get_SHORT(post+10)/2)/(float)otf->unitsPerEm,
                   get_SHORT(post+10)/(float)otf->unitsPerEm);
  }
  dyn_printf(&ds,"/Encoding 256 array\n"
                 "0 1 255 { 1 index exch /.notdef put } for\n");
  for (iA=0;iA<len;iA++) { // encoding data: 0...255 -> /glyphname
    const int gid=(encoding)?encoding[iA]:otf_from_unicode(otf,iA);
    if (gid!=0) {
      dyn_printf(&ds,"dup %d /%s put\n",
                     iA,get_glyphname(post,to_unicode,iA,gid));
    }
  }
  dyn_printf(&ds,"readonly def\n");

  if (binary) {
    dyn_printf(&ds,"/RD { string currentfile exch readstring pop } executeonly def\n");
  }
  dyn_printf(&ds,"/sfnts[\n");

  if (ds.len<0) {
    free(post);
    free(ds.buf);
    return -1;
  }
  (*output)(ds.buf,ds.len,context);
  ret+=ds.len;
  ds.len=0;

// TODO: only tables as in otf_subset
// TODO:  somehow communicate table boundaries:
  //   otf_action_copy  does exactly one output call (per table)
  //   only otf_action_replace might do two (padding)
  // {{{ copy tables verbatim (does not affect ds .len)
  struct _OTF_WRITE_TABLE *tablesfree=NULL;
#if 0
  struct _OTF_WRITE_TABLE *tables;
  tablesfree=tables=malloc(sizeof(struct _OTF_WRITE_TABLE)*otf->numTables);
  if (!tables) {
    fprintf(stderr,"Bad alloc: %m\n");
    free(post);
    free(ds.buf);
    return -1;
  }
  // just copy everything
  for (iA=0;iA<otf->numTables;iA++) {
    tables[iA].tag=otf->tables[iA].tag;
    tables[iA].action=otf_action_copy;
    tables[iA].copy.otf=otf;
    tables[iA].copy.table_no=iA;
  }
  const int numTables=otf->numTables;
#else
  struct _OTF_WRITE_TABLE tables[]={ // sorted
      {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_copy,.copy={otf,}},
      {OTF_TAG('h','e','a','d'),otf_action_copy,.copy={otf,}},
      {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_copy,.copy={otf,}},
      {OTF_TAG('m','a','x','p'),otf_action_copy,.copy={otf,}},
      {OTF_TAG('n','a','m','e'),otf_action_copy,.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,}};
  const int numTables=otf_intersect_tables(otf,tables);
#endif

  struct OUTFILTER_PS of;
  of.out=output;
  of.ctx=context;
  of.len=0;
  struct _OTF_WRITE_INFO otw={
    .version=otf->version,
    .numTables=numTables,
    .tables=tables,
    .order=otf_tagorder_win_sort(tables,numTables)
  };
  if (binary) {
    iA=otf_write_sfnt(&otw,NULL,outfilter_binary_ps,&of);
  } else {
    iA=otf_write_sfnt(&otw,NULL,outfilter_ascii_ps,&of);
  }
  free(tablesfree);
  if (iA==-1) {
    free(post);
    free(ds.buf);
    return -1;
  }
  ret+=of.len;
  // }}} done copying

  dyn_printf(&ds,"] def\n");

  dyn_printf(&ds,"/CharStrings %d dict dup begin\n"
                 "/.notdef 0 def\n",len);
  for (iA=0;iA<len;iA++) { // charstrings data: /glyphname -> gid
    const int gid=(encoding)?encoding[iA]:otf_from_unicode(otf,iA);
    if (gid) {
      dyn_printf(&ds,"/%s %d def\n",get_glyphname(post,to_unicode,iA,gid),gid);
    }
    // (respecting subsetting...)
  }
  dyn_printf(&ds,"end readonly def\n");
  dyn_printf(&ds,"FontName currentdict end definefont pop\n");
  free(post);

  if (ds.len<0) {
    free(ds.buf);
    return -1;
  }
  (*output)(ds.buf,ds.len,context);
  ret+=ds.len;
  ds.len=0;

  free(ds.buf);
  return ret;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x448, %rsp            # imm = 0x448
movq %rcx, 0x38(%rsp)
movl %edx, %ebp
cmpl $0x101, %edx            # imm = 0x101
jge 0x662a
testl %ebp, %ebp
jle 0x6646
movq %r9, %r13
movq %r8, %r15
movq %rsi, %r12
movq %rdi, %r14
testq %rsi, %rsi
movq 0x38(%rsp), %rax
cmoveq %rsi, %rax
movq %rax, 0x38(%rsp)
leaq 0x10(%rsp), %rdi
movl $0x400, %esi            # imm = 0x400
callq 0x7a74
cmpl $-0x1, %eax
je 0x6611
leaq 0x34(%rsp), %rdx
movl $0x0, (%rdx)
movq %r14, %rdi
movl $0x68656164, %esi       # imm = 0x68656164
callq 0x4249
testq %rax, %rax
je 0x6607
movq %rax, %rbx
movl %ebp, 0x30(%rsp)
movl 0x14(%r14), %edx
movl 0x4(%rax), %ecx
bswapl %ecx
leaq 0x4e8f(%rip), %rsi      # 0xaddf
leaq 0x10(%rsp), %rdi
xorl %eax, %eax
callq 0x7c95
movzbl 0x24(%rbx), %eax
shll $0x8, %eax
movzbl 0x25(%rbx), %ecx
cwtl
orl %ecx, %eax
imull $0x3e8, %eax, %eax      # imm = 0x3E8
movzwl 0x48(%r14), %ecx
cltd
idivl %ecx
movl %eax, 0xc(%rsp)
movzbl 0x26(%rbx), %eax
shll $0x8, %eax
movzbl 0x27(%rbx), %edx
cwtl
orl %edx, %eax
imull $0x3e8, %eax, %eax      # imm = 0x3E8
cltd
idivl %ecx
movl %eax, 0x2c(%rsp)
movzbl 0x28(%rbx), %eax
shll $0x8, %eax
movzbl 0x29(%rbx), %edx
cwtl
orl %edx, %eax
imull $0x3e8, %eax, %eax      # imm = 0x3E8
cltd
idivl %ecx
movl %eax, 0x28(%rsp)
movzbl 0x2a(%rbx), %eax
shll $0x8, %eax
movzbl 0x2b(%rbx), %edx
cwtl
orl %edx, %eax
imull $0x3e8, %eax, %eax      # imm = 0x3E8
cltd
idivl %ecx
movl %eax, %ebp
movq %rbx, %rdi
callq 0x21a0
leaq 0x34(%rsp), %rdx
movq %r14, 0x20(%rsp)
movq %r14, %rdi
movl $0x706f7374, %esi       # imm = 0x706F7374
callq 0x4249
movq %rax, %rbx
testq %rax, %rax
jne 0x5ffd
cmpl $-0x1, 0x34(%rsp)
jne 0x6607
testq %rbx, %rbx
movq %r15, 0x48(%rsp)
movq %r13, 0x40(%rsp)
je 0x6129
movl 0x10(%rbx), %edx
bswapl %edx
testl %edx, %edx
je 0x6031
movl 0x14(%rbx), %ecx
bswapl %ecx
leaq 0x4dd4(%rip), %rsi      # 0xadf9
leaq 0x10(%rsp), %rdi
xorl %eax, %eax
callq 0x7c95
movq 0x20(%rsp), %r15
movq %r15, %rdi
callq 0x54e0
cvtsi2sdl 0xc(%rsp), %xmm0
movsd 0x49d4(%rip), %xmm4     # 0xaa20
cvtsi2sdl 0x2c(%rsp), %xmm1
divsd %xmm4, %xmm0
divsd %xmm4, %xmm1
cvtsi2sdl 0x28(%rsp), %xmm2
divsd %xmm4, %xmm2
cvtsi2sd %ebp, %xmm3
divsd %xmm4, %xmm3
leaq 0x4d98(%rip), %rsi      # 0xae0b
leaq 0x90e6(%rip), %rdx      # 0xf160
leaq 0x10(%rsp), %r14
movq %r14, %rdi
movb $0x4, %al
callq 0x7c95
movzbl 0x4(%rbx), %eax
shll $0x18, %eax
movzbl 0x5(%rbx), %edx
shll $0x10, %edx
orl %eax, %edx
sarl $0x10, %edx
movl 0xc(%rbx), %eax
bswapl %eax
testl %eax, %eax
leaq 0x4e76(%rip), %rax      # 0xaf20
leaq 0x4e6a(%rip), %rcx      # 0xaf1b
cmoveq %rax, %rcx
movzbl 0x8(%rbx), %eax
shll $0x8, %eax
movzbl 0x9(%rbx), %esi
cwtl
orl %esi, %eax
movzbl 0xa(%rbx), %esi
movl %esi, %edi
shll $0x8, %edi
movzbl 0xb(%rbx), %r8d
orl %edi, %r8d
btl $0x7, %esi
movl %r8d, %esi
adcl $0x0, %esi
movswl %si, %esi
sarl %esi
subl %esi, %eax
xorps %xmm0, %xmm0
cvtsi2ss %eax, %xmm0
movzwl 0x48(%r15), %eax
xorps %xmm1, %xmm1
cvtsi2ss %eax, %xmm1
movswl %r8w, %eax
xorps %xmm2, %xmm2
cvtsi2ss %eax, %xmm2
divss %xmm1, %xmm0
cvtss2sd %xmm0, %xmm0
divss %xmm1, %xmm2
xorps %xmm1, %xmm1
cvtss2sd %xmm2, %xmm1
leaq 0x4d6b(%rip), %rsi      # 0xae88
movq %r14, %rdi
movb $0x2, %al
callq 0x7c95
jmp 0x617b
movq 0x20(%rsp), %rdi
callq 0x54e0
cvtsi2sdl 0xc(%rsp), %xmm0
movsd 0x48df(%rip), %xmm4     # 0xaa20
cvtsi2sdl 0x2c(%rsp), %xmm1
divsd %xmm4, %xmm0
divsd %xmm4, %xmm1
cvtsi2sdl 0x28(%rsp), %xmm2
divsd %xmm4, %xmm2
cvtsi2sd %ebp, %xmm3
divsd %xmm4, %xmm3
leaq 0x4ca3(%rip), %rsi      # 0xae0b
leaq 0x8ff1(%rip), %rdx      # 0xf160
leaq 0x10(%rsp), %rdi
movb $0x4, %al
callq 0x7c95
leaq 0x4da4(%rip), %rsi      # 0xaf26
leaq 0x10(%rsp), %r14
movq %r14, %rdi
xorl %eax, %eax
callq 0x7c95
movl 0x30(%rsp), %eax
cmpl $0x2, %eax
movl $0x1, %r15d
cmovgel %eax, %r15d
leaq 0x4dbc(%rip), %rbp      # 0xaf65
xorl %r13d, %r13d
testq %r12, %r12
je 0x61b8
movzwl (%r12,%r13,2), %eax
jmp 0x61c5
movq 0x20(%rsp), %rdi
movl %r13d, %esi
callq 0x4c58
testw %ax, %ax
je 0x61f0
movzwl %ax, %ecx
movq %rbx, %rdi
movq 0x38(%rsp), %rsi
movl %r13d, %edx
callq 0x666d
movq %r14, %rdi
movq %rbp, %rsi
movl %r13d, %edx
movq %rax, %rcx
xorl %eax, %eax
callq 0x7c95
incq %r13
cmpq %r13, %r15
jne 0x61ac
leaq 0x4d0e(%rip), %rsi      # 0xaf0d
xorl %r13d, %r13d
leaq 0x10(%rsp), %r14
movq %r14, %rdi
xorl %eax, %eax
callq 0x7c95
leaq 0x4d5d(%rip), %rsi      # 0xaf75
movq %r14, %rdi
xorl %eax, %eax
callq 0x7c95
movl (%r14), %esi
testl %esi, %esi
js 0x65ff
movq 0x18(%rsp), %rdi
movq 0x40(%rsp), %rdx
callq *0x48(%rsp)
movl 0x10(%rsp), %eax
movl %eax, 0xc(%rsp)
movl %r13d, 0x10(%rsp)
leaq 0x80(%rsp), %rbp
movq $0x636d6170, (%rbp)     # imm = 0x636D6170
leaq 0x2d69(%rip), %rax      # 0x8fc8
movq %rax, 0x8(%rbp)
movq 0x20(%rsp), %r15
movq %r15, 0x10(%rbp)
movl %r13d, 0x18(%rbp)
xorps %xmm0, %xmm0
movaps %xmm0, 0x20(%rbp)
movaps %xmm0, 0x30(%rbp)
movaps %xmm0, 0x40(%rbp)
movq $0x63767420, 0x50(%rbp) # imm = 0x63767420
movq %rax, 0x58(%rbp)
movq %r15, 0x60(%rbp)
movl %r13d, 0x68(%rbp)
movaps %xmm0, 0x70(%rbp)
movaps %xmm0, 0x80(%rbp)
movaps %xmm0, 0x90(%rbp)
movq $0x6670676d, 0xa0(%rbp) # imm = 0x6670676D
movq %rax, 0xa8(%rbp)
movq %r15, 0xb0(%rbp)
movl %r13d, 0xb8(%rbp)
movaps %xmm0, 0xc0(%rbp)
movaps %xmm0, 0xd0(%rbp)
movaps %xmm0, 0xe0(%rbp)
movq $0x676c7966, 0xf0(%rbp) # imm = 0x676C7966
movq %rax, 0xf8(%rbp)
movq %r15, 0x100(%rbp)
movl %r13d, 0x108(%rbp)
movaps %xmm0, 0x110(%rbp)
movaps %xmm0, 0x120(%rbp)
movaps %xmm0, 0x130(%rbp)
movq $0x68656164, 0x140(%rbp) # imm = 0x68656164
movq %rax, 0x148(%rbp)
movq %r15, 0x150(%rbp)
movl %r13d, 0x158(%rbp)
movaps %xmm0, 0x160(%rbp)
movaps %xmm0, 0x170(%rbp)
movaps %xmm0, 0x180(%rbp)
movq $0x68686561, 0x190(%rbp) # imm = 0x68686561
movq %rax, 0x198(%rbp)
movq %r15, 0x1a0(%rbp)
movl %r13d, 0x1a8(%rbp)
movaps %xmm0, 0x1d0(%rbp)
movaps %xmm0, 0x1c0(%rbp)
movaps %xmm0, 0x1b0(%rbp)
movq $0x686d7478, 0x1e0(%rbp) # imm = 0x686D7478
movq %rax, 0x1e8(%rbp)
movq %r15, 0x1f0(%rbp)
movl %r13d, 0x1f8(%rbp)
movaps %xmm0, 0x200(%rbp)
movaps %xmm0, 0x210(%rbp)
movaps %xmm0, 0x220(%rbp)
movq $0x6c6f6361, 0x230(%rbp) # imm = 0x6C6F6361
movq %rax, 0x238(%rbp)
movq %r15, 0x240(%rbp)
movl %r13d, 0x248(%rbp)
movaps %xmm0, 0x250(%rbp)
movaps %xmm0, 0x260(%rbp)
movaps %xmm0, 0x270(%rbp)
movq $0x6d617870, 0x280(%rbp) # imm = 0x6D617870
movq %rax, 0x288(%rbp)
movq %r15, 0x290(%rbp)
movl %r13d, 0x298(%rbp)
movaps %xmm0, 0x2c0(%rbp)
movaps %xmm0, 0x2b0(%rbp)
movaps %xmm0, 0x2a0(%rbp)
movq $0x6e616d65, 0x2d0(%rbp) # imm = 0x6E616D65
movq %rax, 0x2d8(%rbp)
movq %r15, 0x2e0(%rbp)
movl %r13d, 0x2e8(%rbp)
movaps %xmm0, 0x310(%rbp)
movaps %xmm0, 0x300(%rbp)
movaps %xmm0, 0x2f0(%rbp)
movq $0x70726570, 0x320(%rbp) # imm = 0x70726570
movq %rax, 0x328(%rbp)
movq %r15, 0x330(%rbp)
movl %r13d, 0x338(%rbp)
movaps %xmm0, 0x3b0(%rbp)
movaps %xmm0, 0x3a0(%rbp)
movaps %xmm0, 0x390(%rbp)
movaps %xmm0, 0x380(%rbp)
movaps %xmm0, 0x370(%rbp)
movaps %xmm0, 0x360(%rbp)
movaps %xmm0, 0x350(%rbp)
movaps %xmm0, 0x340(%rbp)
movq %r15, %rdi
movq %rbp, %rsi
callq 0x80e2
leaq 0x50(%rsp), %r14
movq 0x48(%rsp), %rcx
movq %rcx, (%r14)
movq 0x40(%rsp), %rcx
movq %rcx, 0x8(%r14)
movl %r13d, 0x10(%r14)
movl 0x14(%r15), %ecx
leaq 0x68(%rsp), %r13
movl %ecx, (%r13)
movw %ax, 0x4(%r13)
movq %rbp, 0x8(%r13)
movq %rbp, %rdi
movl %eax, %esi
callq 0x8e10
movq %rax, 0x10(%r13)
leaq 0x2b7(%rip), %rdx       # 0x67ac
movq %r13, %rdi
xorl %esi, %esi
movq %r14, %rcx
callq 0x914d
cmpl $-0x1, %eax
je 0x664d
movl 0xc(%rsp), %eax
addl 0x60(%rsp), %eax
movl %eax, 0xc(%rsp)
leaq 0x4a60(%rip), %rsi      # 0xaf7e
leaq 0x10(%rsp), %r14
movq %r14, %rdi
xorl %eax, %eax
callq 0x7c95
leaq 0x4a51(%rip), %rsi      # 0xaf85
movq %r14, %rdi
movl 0x30(%rsp), %ebp
movl %ebp, %edx
xorl %eax, %eax
callq 0x7c95
cmpl $0x2, %ebp
movl $0x1, %r15d
cmovgel %ebp, %r15d
leaq 0x4a5c(%rip), %r14      # 0xafb4
xorl %r13d, %r13d
testq %r12, %r12
je 0x6567
movzwl (%r12,%r13,2), %eax
jmp 0x6574
movq 0x20(%rsp), %rdi
movl %r13d, %esi
callq 0x4c58
testw %ax, %ax
je 0x65a2
movzwl %ax, %ebp
movq %rbx, %rdi
movq 0x38(%rsp), %rsi
movl %r13d, %edx
movl %ebp, %ecx
callq 0x666d
leaq 0x10(%rsp), %rdi
movq %r14, %rsi
movq %rax, %rdx
movl %ebp, %ecx
xorl %eax, %eax
callq 0x7c95
incq %r13
cmpq %r13, %r15
jne 0x655b
leaq 0x4958(%rip), %rsi      # 0xaf09
leaq 0x10(%rsp), %r14
movq %r14, %rdi
xorl %eax, %eax
callq 0x7c95
leaq 0x49f9(%rip), %rsi      # 0xafc0
movq %r14, %rdi
xorl %eax, %eax
callq 0x7c95
movq %rbx, %rdi
callq 0x21a0
movl (%r14), %esi
movq 0x8(%r14), %rdi
testl %esi, %esi
js 0x6661
movq 0x40(%rsp), %rdx
callq *0x48(%rsp)
movl 0xc(%rsp), %ebx
addl 0x10(%rsp), %ebx
movl $0x0, 0x10(%rsp)
jmp 0x665a
movq %rbx, %rdi
callq 0x21a0
movq 0x18(%rsp), %rdi
callq 0x21a0
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
movl %ebx, %eax
addq $0x448, %rsp            # imm = 0x448
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x89af(%rip), %rax      # 0xefe0
movq (%rax), %rdi
leaq 0x475e(%rip), %rsi      # 0xad99
movl %ebp, %edx
xorl %eax, %eax
callq 0x21d0
jmp 0x6611
callq 0x2ba9
jmp 0x6611
movq %rbx, %rdi
callq 0x21a0
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
movq 0x18(%rsp), %rdi
jmp 0x6666
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
callq 0x21a0
jmp 0x6616