Esempio n. 1
0
void emb_otf_get_pdf_fontdescr(OTF_FILE *otf,EMB_PDF_FONTDESCR *ret) // {{{
{
  int len;

//  TODO
//  ... fill in struct
  char *head=otf_get_table(otf,OTF_TAG('h','e','a','d'),&len);
  assert(head); // version is 1.0 from otf_load
  ret->bbxmin=get_SHORT(head+36)*1000/otf->unitsPerEm;
  ret->bbymin=get_SHORT(head+38)*1000/otf->unitsPerEm;
  ret->bbxmax=get_SHORT(head+40)*1000/otf->unitsPerEm;
  ret->bbymax=get_SHORT(head+42)*1000/otf->unitsPerEm;
  const int macStyle=get_USHORT(head+44);
  free(head);

  char *post=otf_get_table(otf,OTF_TAG('p','o','s','t'),&len);
  assert(post);
  const unsigned int post_version=get_ULONG(post);
  // check length
  assert( (post_version!=0x00010000)||(len==32) );
  assert( (post_version!=0x00020000)||(len>=34+2*otf->numGlyphs) );
  assert( (post_version!=0x00025000)||(len==35+otf->numGlyphs) );
  assert( (post_version!=0x00030000)||(len==32) );
  assert( (post_version!=0x00020000)||(get_USHORT(post+32)==otf->numGlyphs) );
//  assert( (post_version==0x00030000)==(!!(otf->flags&OTF_F_FMT_CFF)) ); // ghostscript embedding does this..
  // TODO: v4 (apple) :  uint16 reencoding[numGlyphs]
  if ( (post_version==0x00010000)||
       (post_version==0x00020000)||
       (post_version==0x00025000)||
       (post_version==0x00030000) ) {
    ret->italicAngle=get_LONG(post+4)>>16;
    if (get_ULONG(post+12)>0) { // monospaced
      ret->flags|=1;
    }
  } else {
Esempio n. 2
0
// TODO no subsetting actually done (for now)
int otf_subset_cff(OTF_FILE *otf,BITSET glyphs,OUTPUT_FN output,void *context) // {{{ - returns number of bytes written
{
  assert(otf);
  assert(output);

// TODO char *new_cff=cff_subset(...);

  // determine new tables.
  struct _OTF_WRITE otw[]={
      {OTF_TAG('C','F','F',' '),otf_action_copy,otf,},
//      {OTF_TAG('C','F','F',' '),otf_action_replace,new_glyf,glyfSize},
      {OTF_TAG('c','m','a','p'),otf_action_copy,otf,},
#if 0 // not actually needed!
      {OTF_TAG('c','v','t',' '),otf_action_copy,otf,},
      {OTF_TAG('f','p','g','m'),otf_action_copy,otf,},
      {OTF_TAG('h','e','a','d'),otf_action_copy,otf,}, // _copy_head
      {OTF_TAG('h','h','e','a'),otf_action_copy,otf,},
      {OTF_TAG('h','m','t','x'),otf_action_copy,otf,},
      {OTF_TAG('m','a','x','p'),otf_action_copy,otf,},
      {OTF_TAG('n','a','m','e'),otf_action_copy,otf,},
      {OTF_TAG('p','r','e','p'),otf_action_copy,otf,},
#endif
      {0,0,0,0}};

  // and write them
  int numTables=otf_intersect_tables(otf,otw);
  int ret=otf_write_sfnt(otw,otf->version,numTables,output,context);

//  free(new_cff);
  return ret;
}
Esempio n. 3
0
EMB_RIGHT_TYPE emb_otf_get_rights(OTF_FILE *otf) // {{{
{
  EMB_RIGHT_TYPE ret=EMB_RIGHT_FULL;

  int len;
  char *os2=otf_get_table(otf,OTF_TAG('O','S','/','2'),&len);
  if (os2) {
    const unsigned short os2_version=get_USHORT(os2);
    // check len
    assert( (os2_version!=0x0000)||(len==78) );
    assert( (os2_version!=0x0001)||(len==86) );
    assert( (os2_version<0x0002)||(os2_version>0x0004)||(len==96) );
    if (os2_version<=0x0004) {
      // get rights
      unsigned short fsType=get_USHORT(os2+8);
      ret=fsType&0x0200;
      if ((fsType&0x0f)==0x0002) {
        ret|=EMB_RIGHT_NONE;
      } else if ((fsType&0x0f)==0x0004) {
        ret|=EMB_RIGHT_READONLY;
      } 
    }
    free(os2);
  }
  return ret;
}
Esempio n. 4
0
EMB_RIGHT_TYPE emb_otf_get_rights(OTF_FILE *otf) // {{{
{
  EMB_RIGHT_TYPE ret=EMB_RIGHT_FULL;

  int len;
  char *os2=otf_get_table(otf,OTF_TAG('O','S','/','2'),&len);
  if (os2) {
    const unsigned short os2_version=get_USHORT(os2);
    // check len
    assert( (os2_version!=0x0000)||(len==78) );
    assert( (os2_version!=0x0001)||(len==86) );
    assert( (os2_version<0x0002)||(os2_version>0x0004)||(len==96) );
    if (os2_version<=0x0004) {
      // get rights
      unsigned short fsType=get_USHORT(os2+8);
      // from Adobe's Fontpolicies_v9.pdf, pg 13:
      if (fsType==0x0002) {
        ret=EMB_RIGHT_NONE;
      } else {
        ret=fsType&0x0300; // EMB_RIGHT_BITMAPONLY, EMB_RIGHT_NO_SUBSET
        if ((fsType&0x000c)==0x0004) {
          ret|=EMB_RIGHT_READONLY;
        }
      }
    }
    free(os2);
  }
  return ret;
}
Esempio n. 5
0
int otf_cff_extract(OTF_FILE *otf,OUTPUT_FN output,void *context) // {{{ - returns number of bytes written
{
  assert(otf);
  assert(output);

  int idx=otf_find_table(otf,OTF_TAG('C','F','F',' '));
  if (idx==-1) {
    return -1;
  }
  const OTF_DIRENT *table=otf->tables+idx;

  return copy_block(otf->f,table->offset,table->length,output,context);
}
Esempio n. 6
0
// TODO: cmap only required in non-CID context
int otf_subset(OTF_FILE *otf,BITSET glyphs,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(locaSize);
  char *new_glyf=malloc(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 otw[]={ // sorted
    // TODO: cmap only required in non-CID context   or always in CFF
      {OTF_TAG('c','m','a','p'),otf_action_copy,otf,},
      {OTF_TAG('c','v','t',' '),otf_action_copy,otf,},
      {OTF_TAG('f','p','g','m'),otf_action_copy,otf,},
      {OTF_TAG('g','l','y','f'),otf_action_replace,new_glyf,glyfSize},
      {OTF_TAG('h','e','a','d'),otf_action_copy,otf,}, // _copy_head
      {OTF_TAG('h','h','e','a'),otf_action_copy,otf,},
      {OTF_TAG('h','m','t','x'),otf_action_copy,otf,},
      {OTF_TAG('l','o','c','a'),otf_action_replace,new_loca,locaSize},
      {OTF_TAG('m','a','x','p'),otf_action_copy,otf,},
      {OTF_TAG('n','a','m','e'),otf_action_copy,otf,},
      {OTF_TAG('p','r','e','p'),otf_action_copy,otf,},
      // vhea vmtx (never used in PDF, but possible in PS>=3011)
      {0,0,0,0}};

  // and write them
  int numTables=otf_intersect_tables(otf,otw);
  int ret=otf_write_sfnt(otw,otf->version,numTables,output,context);

  free(new_loca);
  free(new_glyf);
  return ret;

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