コード例 #1
0
ファイル: ligkern.c プロジェクト: bngabonziza/miktex
static void
rmkern(char *s1, char *s2,
       ttfinfo *ti,
       Font *fnt)
{
  if (ti == NULL)
  {
    if (strcmp(s1, "*") == 0)
    {
      for (ti = fnt->charlist; ti; ti = ti->next)
        rmkern(s1, s2, ti, fnt);
      return;
    }
    else
    {
      ti = findadobe(s1, fnt->charlist);
      if (ti == NULL)
        return;
    }
  }

  if (strcmp(s2, "*") == 0)
    ti->kerns = NULL; /* drop them on the floor */
  else
    ti->kerns = rmkernmatch(ti->kerns, s2);
}
コード例 #2
0
ファイル: ligkern.c プロジェクト: bngabonziza/miktex
static void
addkern(char *s1, char *s2,
        Font *fnt)
{
  ttfinfo *ti1 = findadobe(s1, fnt->charlist);
  ttfinfo *ti2 = findadobe(s2, fnt->charlist);


  if (ti1 && ti2 && !ti1->kerns)
  {
    /* Put the new one at the head of the list, since order is immaterial. */
    ttfptr *ap = (ttfptr *)mymalloc(sizeof (ttfptr));


    ap->next = ti2->kern_equivs;
    ap->ch = ti1;
    ti2->kern_equivs = ap;
  }
}
コード例 #3
0
ファイル: ttfenc.c プロジェクト: BackupTheBerlios/texlive
void
replace_glyphs(Font *fnt)
{
  stringlist *sl, *sl_old;
  ttfinfo *ti;


  for (sl = fnt->replacements, sl_old = NULL; sl; sl_old = sl, sl = sl->next)
  {
    if ((ti = findadobe(sl->old_name, fnt->charlist)))
      ti->adobename = sl->new_name;
    else
    {
      warning("Glyph name `%s' not found.", sl->old_name);
      warning("Replacement glyph name `%s' thus ignored.", sl->new_name);
      if (sl_old == NULL)
        fnt->replacements = sl->next;
      else
        sl_old->next = sl->next;
    }
  }
}
コード例 #4
0
ファイル: ligkern.c プロジェクト: bngabonziza/miktex
void
checkligkern(char *s, Font *fnt)
{
  char *mlist[5];
  char *os;
  char *orig_s, *pos;
  size_t offset[5];
  int n;


  os = newstring(s);
  orig_s = s;

  s++;
  while (isspace(*s))
    s++;
  if (strncmp(s, "LIGKERN", 7) == 0)
  {
    fnt->sawligkern = True;
    s += 7;
    while (isspace(*s))
      s++;
    pos = s;
    while (*pos)
    {
      for (n = 0; n < 5;)
      {
        if (*pos == '\0')
          break;
        offset[n] = pos - orig_s;
        mlist[n] = paramstring(&pos);
        if (strcmp(mlist[n], ";") == 0)
          break;
        n++;
      }

      if (n > 4)
        boops(os, pos - orig_s, "Too many parameters in lig kern data.");
      if (n < 3)
        boops(os, pos - orig_s, "Too few parameters in lig kern data.");

      if (n == 3 && strcmp(mlist[1], "{}") == 0)        /* rmkern command */
        rmkern(mlist[0], mlist[2], (ttfinfo *)0, fnt);
      else if (n == 3 && strcmp(mlist[1], "<>") == 0)   /* addkern */
        addkern(mlist[0], mlist[2], fnt);
      else if (n == 3 && strcmp(mlist[0], "||") == 0 &&
               strcmp(mlist[1], "=") == 0)              /* bc command */
      {
        ttfinfo *ti = findadobe("||", fnt->charlist);


        if (fnt->boundarychar != -1)
          boops(os, offset[0], "Multiple boundary character commands?");
        if (sscanf(mlist[2], "%d", &n) != 1)
          boops(os, offset[2],
                "Expected number assignment for boundary char.");
        if (n < 0 || n > 0xFF)
          boops(os, offset[2], "Boundary character number must be 0..0xFF.");

        fnt->boundarychar = n;
        if (ti == NULL)
          oops("Internal error: boundary char.");
        ti->outcode = n; /* prime the pump, so to speak, for lig/kerns */
      }
      else if (n == 4)
      {
        int op = -1;
        ttfinfo *ti;


        for (n = 0; encligops[n]; n++)
          if (strcmp(mlist[2], encligops[n]) == 0)
          {
            op = n;
            break;
          }
        if (op < 0)
          boops(os, offset[2], "Bad ligature op specified.");

        if (NULL != (ti = findadobe(mlist[0], fnt->charlist)))
        {
          lig *lig;


          if (findadobe(mlist[1], fnt->charlist))
                                                /* remove coincident kerns */
            rmkern(mlist[0], mlist[1], ti, fnt);

          if (strcmp(mlist[3], "||") == 0)
            boops(os, offset[3], "You can't lig to the boundary character!");

          if (!fnt->fixedpitch)         /* fixed pitch fonts get *0* ligs */
          {
            for (lig = ti->ligs; lig; lig = lig->next)
              if (strcmp(lig->succ, mlist[1]) == 0)
                break;                  /* we'll re-use this structure */

            if (lig == NULL)
            {
              lig = newlig();
              lig->succ = newstring(mlist[1]);
              lig->next = ti->ligs;
              ti->ligs = lig;
            }
            lig->sub = newstring(mlist[3]);
            lig->op = op;
 
            if (strcmp(mlist[1], "||") == 0)
            {
              lig->boundleft = 1;
              if (strcmp(mlist[0], "||") == 0)
                boops(os, offset[0],
                      "You can't lig boundarychar boundarychar!");
            }
            else
              lig->boundleft = 0;
          }
        }
      }
      else
        boops(os, offset[0], "Bad form in LIGKERN command.");
    }
  }

  free(os);
}
コード例 #5
0
ファイル: ttf2tfm.c プロジェクト: clerkma/texlive-mobile
int
main(int argc, char *argv[])
{
  Font font;
  ttfinfo *ti;


#ifdef MIKTEX
  miktex_initialize();
#endif

  init_font_structure(&font);

  TeX_search_init(argv[0], "ttf2tfm", "TTF2TFM");

  if (argc == 1)
  {
    fputs("ttf2tfm: Need at least one file argument.\n", stderr);
    fputs("Try `ttf2tfm --help' for more information.\n", stderr);
    exit(1);
  }
  if (argc == 2)
  {
    if (strcmp(argv[1], "--help") == 0)
      usage();
    else if (strcmp(argv[1], "--version") == 0)
      version();
  }

  handle_options(argc, argv, &font);

  if (font.sfdname)
  {
    while (get_sfd(&font, True))
    {
      char *temp, *ttemp;
      int i, start, end, len;


      get_tfm_fullname(&font);

      /*
       *   Extract base name of sfd file.
       */

      temp = newstring(font.sfdname);
      len = strlen(temp);

      start = 0;
      for (i = len - 1; i >= 0; i--)
        if (temp[i] == '/' || temp[i] == ':' || temp[i] == '\\')
        {
          start = i + 1;
          break;
        }

      end = len;
      for (i = len - 1; i >= 0; i--)
        if (temp[i] == '.')
        {
          end = i;
          break;
        }
      temp[end] = '\0';

      ttemp = (char *)mymalloc(strlen(temp + start) + 4 + 1);
      sprintf(ttemp, "CJK-%s", temp + start);
      font.codingscheme = ttemp;
      free(temp);

      readttf(&font, quiet, True);
      if (font.replacements)
        warning("Replacement glyphs will be ignored.");

      /* second try to get an xheight value */
      if (font.xheight == 0)
      {
        if (NULL != (ti = findadobe("x", font.charlist)))
          font.xheight = ti->ury;
        else if (font.pid == 3 && font.eid == 1 &&
                 NULL != (ti = findadobe(".c0x78", font.charlist)))
          font.xheight = ti->ury;
        else
          font.xheight = 400;
      }

      if (NULL != (ti = findadobe("space", font.charlist)))
        font.fontspace = ti->width;
      else if (NULL != (ti = findadobe(".c0x20", font.charlist)))
        font.fontspace = ti->width;
      else
        font.fontspace = transform(500, 0, font.efactor, font.slant);

      if (font.ligname)
        get_sfd(&font, False); /* read sfd files for ligatures */

      if (buildtfm(&font))
      {
        writetfm(&font);
        if (font.write_enc)
          writeenc(&font);
        if (font.vplout)
          add_subfont_list(&font);
      }
    }

    close_sfd();

    if (font.vplout)
    {
      writeovp(&font);
      fclose(font.vplout);
      release_subfont_list(&font);
    }
  }
  else
  {
    get_tfm_fullname(&font);

    readttf(&font, quiet, False);
    replace_glyphs(&font);

    /* second try to get an xheight value */
    if (font.xheight == 0)
    {
      if (NULL != (ti = findadobe("x", font.charlist)))
        font.xheight = ti->ury;
      else if (font.pid == 3 && font.eid == 1 &&
               NULL != (ti = findadobe(".c0x78", font.charlist)))
        font.xheight = ti->ury;
      else
        font.xheight = 400;
    }

    if (NULL != (ti = findadobe("space", font.charlist)))
      font.fontspace = ti->width;
    else if (NULL != (ti = findadobe(".c0x20", font.charlist)))
      font.fontspace = ti->width;
    else
      font.fontspace = transform(500, 0, font.efactor, font.slant);

    handlereencoding(&font);

    buildtfm(&font);
    writetfm(&font);
  }

  if (makevpl)
  {
    assignchars(&font);
    if (makevpl > 1)
      upmap(&font);
    writevpl(&font, makevpl, forceoctal);
    fclose(font.vplout);
  }

  consttfonts(&font);

  exit(0);      /* for safety reasons */
  return 0;     /* never reached */
}
コード例 #6
0
ファイル: ttf2tfm.c プロジェクト: clerkma/texlive-mobile
static void
handlereencoding(Font *fnt)
{
  int i;
  ttfinfo *ti;
  const char *p;


  if (fnt->inencname)
  {
    fnt->inencoding = readencoding(&(fnt->inencname), fnt, True);

    /* reset all pointers in the mapping table */
    for (i = 0; i <= 0xFF; i++)
      if (NULL != (ti = fnt->inencptrs[i]))
      {
        ti->incode = -1;
        fnt->inencptrs[i] = NULL;
      }

    /*
     *   Reencode TTF <--> raw TeX.  Only these code points will be used
     *   for the output encoding.
     */

    for (i = 0; i <= 0xFF; i++)
    {
      p = fnt->inencoding->vec[i];
      if (p && *p)
      {
        if ((ti = findadobe(p, fnt->charlist)))
        {
          if (ti->incode >= 0)
          {
            warning("Character `%s' encoded twice in input encoding\n"
                    "         (positions %x and %x; the latter is ignored).",
                    p, ti->incode, i);
            fnt->inencoding->vec[i] = ".notdef";
            continue;
          }
          if (ti->charcode >= 0)
          {
            ti->incode = i;
            fnt->inencptrs[i] = ti;
          }
        }
        else
        {
          warning("Cannot find character `%s'\n"
                  "         specified in input encoding.", p);
        }
      }
    }
    fnt->codingscheme = fnt->inencoding->name;
  }

  if (!quiet)
  {
    if (fnt->inencname)
      printf("\nUsing %s as input encoding.\n", fnt->inencname);
    else
    {
      printf(
        "\nUsing the first 256 glyphs in the following input encoding:\n\n");
      for (i = 0; i <= 0xFF; i++)
      {
        if ((ti = fnt->inencptrs[i]))
          printf("  0x%02x    %s\n", i, ti->adobename);
      }
      printf("\n");
    }
  }

  if (fnt->outencname)
    fnt->outencoding = readencoding(&(fnt->outencname), fnt, False);
  else
    fnt->outencoding = readencoding(NULL, fnt, False);
}
コード例 #7
0
ファイル: ttfaux.c プロジェクト: BackupTheBerlios/texlive
void
readttf(Font *fnt, Boolean quiet, Boolean only_range)
{
  TT_Error error;
  ttfinfo *ti, *Ti;
  long Num, index;
  unsigned int i, j;
  long k, max_k;
  unsigned short num_cmap;
  unsigned short cmap_plat, cmap_enc;
  int index_array[257];

  static Boolean initialized = False;

  TT_UShort in_string[2];
  TTO_GSUB_String in, out;

  TT_UShort script_index, language_index, feature_index;
  TT_UShort req_feature_index = 0xFFFF;


  /*
   *   We allocate a placeholder boundary and the `.notdef' character.
   */

  if (!only_range)
  {
    ti = newchar(fnt);
    ti->charcode = -1;
    ti->adobename = ".notdef";

    ti = newchar(fnt);
    ti->charcode = -1;
    ti->adobename = "||"; /* boundary character name */
  }

  /*
   *   Initialize FreeType engine.
   */

  if (!initialized)
  {
    if ((error = TT_Init_FreeType(&engine)))
      oops("Cannot initialize engine (error code = 0x%x).", error);

    if ((error = TT_Init_Kerning_Extension(engine)))
      oops("Cannot initialize kerning (error code = 0x%x).", error);

    if (fnt->PSnames)
      if ((error = TT_Init_Post_Extension(engine)))
        oops("Cannot initialize PS name support (error code = 0x%x).", error);

    if (fnt->rotate)
      if ((error = TT_Init_GSUB_Extension(engine)))
        oops("Cannot initialize GSUB support (error code = 0x%x).", error);

    /*
     *   Load face.
     */

    real_ttfname = TeX_search_ttf_file(&(fnt->ttfname));
    if (!real_ttfname)
      oops("Cannot find `%s'.", fnt->ttfname);

    if ((error = TT_Open_Face(engine, real_ttfname, &face)))
      oops("Cannot open `%s'.", real_ttfname);

    /*
     *   Get face properties and allocate preload arrays.
     */

    TT_Get_Face_Properties(face, &properties);

    /*
     *   Now we try to open the proper font in a collection.
     */

    if (fnt->fontindex != 0)
    {
      if (properties.num_Faces == 1)
      {
        warning("This isn't a TrueType collection.\n"
                "Parameter `-f' is ignored.");
        fnt->fontindex = 0;
        fnt->fontindexparam = NULL;
      }
      else
      {
        TT_Close_Face(face);
        if ((error = TT_Open_Collection(engine, real_ttfname,
                                        fnt->fontindex, &face)))
          oops("Cannot open font %lu in TrueType Collection `%s'.",
               fnt->fontindex, real_ttfname);
      }
    }

    /*
     *   Create instance.
     */

    if ((error = TT_New_Instance(face, &instance)))
      oops("Cannot create instance for `%s' (error code = 0x%x).",
           real_ttfname, error);

    /*
     *   We use a dummy glyph size of 10pt.
     */

    if ((error = TT_Set_Instance_CharSize(instance, 10 * 64)))
      oops("Cannot set character size (error code = 0x%x).", error);

    matrix1.xx = (TT_Fixed)(floor(fnt->efactor * 1024) * (1L<<16)/1024);
    matrix1.xy = (TT_Fixed)(floor(fnt->slant * 1024) * (1L<<16)/1024);
    matrix1.yx = (TT_Fixed)0;
    matrix1.yy = (TT_Fixed)(1L<<16);

    if (fnt->rotate)
    {
      matrix2.xx = 0;
      matrix2.yx = 1L << 16;
      matrix2.xy = -matrix2.yx;
      matrix2.yy = matrix2.xx;
    }

    if ((error = TT_Set_Instance_Transform_Flags(
                   instance,
                   fnt->rotate ? 1 : 0,
                   fnt->efactor != 1.0 ? 1 : 0)))
      oops("Cannot set transform flags (error code = 0x%x).", error);

    /*
     *   Create glyph container.
     */

    if ((error = TT_New_Glyph(face, &glyph)))
      oops("Cannot create glyph container (error code = 0x%x).", error);

    fnt->units_per_em = properties.header->Units_Per_EM;
    fnt->fixedpitch = properties.postscript->isFixedPitch;
    fnt->italicangle = properties.postscript->italicAngle / 65536.0;

    if (fnt->PSnames != Only)
    {
      num_cmap = properties.num_CharMaps;
      for (i = 0; i < num_cmap; i++)
      {
        if ((error = TT_Get_CharMap_ID(face, i, &cmap_plat, &cmap_enc)))
          oops("Cannot query cmap (error code = 0x%x).", error);
        if (cmap_plat == fnt->pid && cmap_enc == fnt->eid)
          break;
      }
      if (i == num_cmap)
      {
        fprintf(stderr, "%s: ERROR: Invalid platform and/or encoding ID.\n",
                progname);
        if (num_cmap == 1)
          fprintf(stderr, "  The only valid PID/EID pair is");
        else
          fprintf(stderr, "  Valid PID/EID pairs are:\n");
        for (i = 0; i < num_cmap; i++)
        {
          TT_Get_CharMap_ID(face, i, &cmap_plat, &cmap_enc);
          fprintf(stderr, "    (%i,%i)\n", cmap_plat, cmap_enc);
        }
        fprintf(stderr, "\n");
        exit(1);
      }

      if ((error = TT_Get_CharMap(face, i, &char_map)))
        oops("Cannot load cmap (error code = 0x%x).", error);
    }

    if (fnt->PSnames)
    {
      if ((error = TT_Load_PS_Names(face, &post)))
        oops("Cannot load TrueType PS names (error code = 0x%x).", error);
    }
    else if (cmap_plat == Microsoft_platform &&
             cmap_enc == Microsoft_Unicode_encoding)
      set_encoding_scheme(encUnicode, fnt);
    else if (cmap_plat == Macintosh_platform &&
             cmap_enc == Macintosh_encoding)
      set_encoding_scheme(encMac, fnt);
    else
      set_encoding_scheme(encFontSpecific, fnt);

    if (fnt->rotate)
    {
      gsub = &gsub_;

      error = TT_Load_GSUB_Table(face, gsub, NULL);
      if (!error)
        has_gsub = True;
      else if (error != TT_Err_Table_Missing)
        warning("Cannot load GSUB table (error code = 0x%x).", error);
      else
        warning("No GSUB data available "
                "for vertical glyph presentation forms.");

      /* we check for the `vert' feature in Chinese, Japanese, and Korean */

      error = TT_GSUB_Select_Script(gsub,
                                    SCRIPT_kana,
                                    &script_index);
      if (error)
        goto check_hani;
      error = TT_GSUB_Select_Feature(gsub,
                                     FEATURE_vert,
                                     script_index,
                                     0xFFFF,
                                     &feature_index);
      if (error)
      {
        error = TT_GSUB_Select_Language(gsub,
                                        LANGUAGE_JAN,
                                        script_index,
                                        &language_index,
                                        &req_feature_index);
        if (error)
          goto check_hani;
        error = TT_GSUB_Select_Feature(gsub,
                                       FEATURE_vert,
                                       script_index,
                                       language_index,
                                       &feature_index);
        if (error)
          goto check_hani;
        else
          goto Done;
      }
      else
        goto Done;

    check_hani:
      error = TT_GSUB_Select_Script(gsub,
                                    SCRIPT_hani,
                                    &script_index);
      if (error)
        goto check_hang;
      error = TT_GSUB_Select_Feature(gsub,
                                     FEATURE_vert,
                                     script_index,
                                     0xFFFF,
                                     &feature_index);
      if (error)
      {
        error = TT_GSUB_Select_Language(gsub,
                                        LANGUAGE_CHN,
                                        script_index,
                                        &language_index,
                                        &req_feature_index);
        if (error)
          goto check_hang;
        error = TT_GSUB_Select_Feature(gsub,
                                       FEATURE_vert,
                                       script_index,
                                       language_index,
                                       &feature_index);
        if (error)
          goto check_hang;
        else
          goto Done;
      }
      else
        goto Done;

    check_hang:
      error = TT_GSUB_Select_Script(gsub,
                                    SCRIPT_hang,
                                    &script_index);
      if (error)
        goto Done;
      error = TT_GSUB_Select_Feature(gsub,
                                     FEATURE_vert,
                                     script_index,
                                     0xFFFF,
                                     &feature_index);
      if (error)
      {
        error = TT_GSUB_Select_Language(gsub,
                                        LANGUAGE_KOR,
                                        script_index,
                                        &language_index,
                                        &req_feature_index);
        if (error)
          goto Done;
        error = TT_GSUB_Select_Feature(gsub,
                                       FEATURE_vert,
                                       script_index,
                                       language_index,
                                       &feature_index);
      }

    Done:
      if (error)
      {
        warning("There is no data for vertical typesetting in GSUB table.");
        has_gsub = False;
      }

      if (req_feature_index != 0xFFFF)
        TT_GSUB_Add_Feature(gsub, req_feature_index, ALL_GLYPHS);
      TT_GSUB_Add_Feature(gsub, feature_index, ALL_GLYPHS);

      in.length = 1;
      in.pos = 0;
      in.string = in_string;
      in.properties = NULL;

      out.pos = 0;
      out.allocated = 0;
      out.string = NULL;
      out.properties = NULL;
    }

    initialized = True;
  }

  if (!quiet)
  {
    if (only_range)
      printf("\n\n%s:\n", fnt->fullname);
    printf("\n");
    printf("Glyph  Code   Glyph Name                ");
    printf("Width  llx    lly      urx    ury\n");
    printf("---------------------------------------");
    printf("---------------------------------\n");
  }

  /*
   *   We load only glyphs with a valid cmap entry.  Nevertheless, for
   *   the default mapping, we use the first 256 glyphs addressed by
   *   ascending code points, followed by glyphs not in the cmap.
   *
   *   If we compute a range, we take the character codes given in
   *   the fnt->sf_code array.
   *
   *   If the -N flag is set, no cmap is used at all.  Instead, the
   *   first 256 glyphs (with a valid PS name) are used for the default
   *   mapping.
   */

  if (!only_range)
    for (i = 0; i < 257; i++)
      index_array[i] = 0;
  else
    for (i = 0; i < 256; i++)
      fnt->inencptrs[i] = 0;

  j = 0;
  if (fnt->PSnames == Only)
    max_k = properties.num_Glyphs - 1;
  else
    max_k = only_range ? 0xFF : 0x16FFFF;

  for (k = 0; k <= max_k; k++)
  {
    char *an;


    if (fnt->PSnames != Only)
    {
      if (only_range)
      {
        index = fnt->sf_code[k];
        if (index < 0)
          continue;
        j = k;
      }
      else
        index = k;

      Num = TT_Char_Index(char_map, index);

      /* now we try to get a vertical glyph form */

      if (has_gsub)
      {
        in_string[0] = Num;
        error = TT_GSUB_Apply_String(gsub, &in, &out);
        if (error && error != TTO_Err_Not_Covered)
          warning("Cannot get the vertical glyph form for glyph index %d.",
                  Num);
        else
          Num = out.string[0];
      }

      if (Num < 0)
        oops("Failure on cmap mapping from %s.", fnt->ttfname);
      if (Num == 0)
        continue;
      if (!only_range)
        if (Num <= 256)
          index_array[Num] = 1;
    }
    else
    {
      Num = k;
      index = 0;
    }

    error = TT_Load_Glyph(instance, glyph, Num, 0);
    if (!error)
      error = TT_Get_Glyph_Big_Metrics(glyph, &metrics);
    if (!error)
      error = TT_Get_Glyph_Outline(glyph, &outline);
    if (!error)
    {
      if (fnt->efactor != 1.0 || fnt->slant != 0.0 )
        TT_Transform_Outline(&outline, &matrix1);
      if (fnt->rotate)
        TT_Transform_Outline(&outline, &matrix2);
    }
    if (!error)
      error = TT_Get_Outline_BBox(&outline, &bbox); /* we need the non-
                                                       grid-fitted bbox */
    if (!error)
    {
      if (fnt->PSnames)
        (void)TT_Get_PS_Name(face, Num, &an);
      else
        an = code_to_adobename(index);

      /* ignore characters not usable for typesetting with TeX */

      if (strcmp(an, ".notdef") == 0)
        continue;
      if (strcmp(an, ".null") == 0)
        continue;
      if (strcmp(an, "nonmarkingreturn") == 0)
        continue;

      ti = newchar(fnt);
      ti->charcode = index;
      ti->glyphindex = Num;
      ti->adobename = an;
      ti->llx = bbox.xMin * 1000 / fnt->units_per_em;
      ti->lly = bbox.yMin * 1000 / fnt->units_per_em;
      ti->urx = bbox.xMax * 1000 / fnt->units_per_em;
      ti->ury = bbox.yMax * 1000 / fnt->units_per_em;

      /*
       *   We must now shift the rotated character both horizontally
       *   and vertically.  The vertical amount is 25% by default.
       */

      if (fnt->rotate)
      {
        ti->llx += (metrics.vertBearingY - bbox.xMin) *
                     1000 / fnt->units_per_em;
        ti->lly -= 1000 * fnt->y_offset;
        ti->urx += (metrics.vertBearingY - bbox.xMin) *
                     1000 / fnt->units_per_em;
        ti->ury -= 1000 * fnt->y_offset;
      }

      /*
       *   We need to avoid negative heights or depths.  They break accents
       *   in math mode, among other things.
       */

      if (ti->lly > 0)
        ti->lly = 0;
      if (ti->ury < 0)
        ti->ury = 0;
      if (fnt->rotate)
        ti->width = metrics.vertAdvance * 1000 / fnt->units_per_em;
      else
        ti->width = transform(metrics.horiAdvance * 1000 / fnt->units_per_em,
                              0, fnt->efactor, fnt->slant);

      if (!quiet)
        printf("%5ld  %05lx  %-25s %5d  % 5d,% 5d -- % 5d,% 5d\n",
               Num, index, ti->adobename,
               ti->width,
               ti->llx, ti->lly, ti->urx, ti->ury);

      if (j < 256)
      {
        fnt->inencptrs[j] = ti;
        ti->incode = j;
      }
      j++;
    }
  }

  /*
   *   Now we load glyphs without a cmap entry, provided some slots are
   *   still free -- we skip this if we have to compute a range or use
   *   PS names.
   */

  if (!only_range && !fnt->PSnames)
  {
    for (i = 1; i <= properties.num_Glyphs; i++)
    {
      char *an;


      if (index_array[i] == 0)
      {
        error = TT_Load_Glyph(instance, glyph, i, 0);
        if (!error)
          error = TT_Get_Glyph_Big_Metrics(glyph, &metrics);
        if (!error)
          error = TT_Get_Glyph_Outline(glyph, &outline);
        if (!error)
          error = TT_Get_Outline_BBox(&outline, &bbox);
        if (!error)
        {
          an = code_to_adobename(i | 0x1000000);

          ti = newchar(fnt);
          ti->charcode = i | 0x1000000;
          ti->glyphindex = i;
          ti->adobename = an;
          ti->llx = bbox.xMin * 1000 / fnt->units_per_em;
          ti->lly = bbox.yMin * 1000 / fnt->units_per_em;
          ti->urx = bbox.xMax * 1000 / fnt->units_per_em;
          ti->ury = bbox.yMax * 1000 / fnt->units_per_em;

          if (ti->lly > 0)
            ti->lly = 0;
          if (ti->ury < 0)
            ti->ury = 0;
          ti->width = transform(metrics.horiAdvance*1000 / fnt->units_per_em,
                                0, fnt->efactor, fnt->slant);

          if (!quiet)
            printf("%5d         %-25s %5d  % 5d,% 5d -- % 5d,% 5d\n",
                   i, ti->adobename,
                   ti->width,
                   ti->llx, ti->lly, ti->urx, ti->ury);

          if (j < 256)
          {
            fnt->inencptrs[j] = ti;
            ti->incode = j;
          }
          else
            break;
          j++;
        }
      }
    }
  }

  /* Finally, we construct a `Germandbls' glyph if necessary */

  if (!only_range)
  {
    if (NULL == findadobe("Germandbls", fnt->charlist) &&
        NULL != (Ti = findadobe("S", fnt->charlist)))
    {
      pcc *np, *nq;


      ti = newchar(fnt);
      ti->charcode = properties.num_Glyphs | 0x1000000;
      ti->glyphindex = properties.num_Glyphs;
      ti->adobename = "Germandbls";
      ti->width = Ti->width << 1;
      ti->llx = Ti->llx;
      ti->lly = Ti->lly;
      ti->urx = Ti->width + Ti->urx;
      ti->ury = Ti->ury;
      ti->kerns = Ti->kerns;

      np = newpcc();
      np->partname = "S";
      nq = newpcc();
      nq->partname = "S";
      nq->xoffset = Ti->width;
      np->next = nq;
      ti->pccs = np;
      ti->constructed = True;

      if (!quiet)
        printf("*            %-25s %5d  % 5d,% 5d -- % 5d,% 5d\n",
               ti->adobename,
               ti->width,
               ti->llx, ti->lly, ti->urx, ti->ury);
    }
  }

  /* kerning between subfonts isn't available */
  if (!only_range)
    readttf_kern(fnt);
}
コード例 #8
0
ファイル: ttfaux.c プロジェクト: MiKTeX/miktex
void
readttf(Font *fnt, Boolean quiet, Boolean only_range)
{
  FT_Error error;
  ttfinfo *ti, *Ti;
  long Num, index;
  unsigned int i, j;
  long k, max_k;
  int index_array[257];

  static Boolean initialized = False;


  /*
   *   We allocate a placeholder boundary and the `.notdef' character.
   */

  if (!only_range)
  {
    ti = newchar(fnt);
    ti->charcode = -1;
    ti->adobename = ".notdef";

    ti = newchar(fnt);
    ti->charcode = -1;
    ti->adobename = "||"; /* boundary character name */
  }

  /*
   *   Initialize FreeType engine.
   */

  if (!initialized)
  {
    /*
     *   We use a dummy glyph size of 10pt.
     */
    dpi = 92;
    ptsize = 10 * 64;

    real_ttfname = TeX_search_ttf_file(&(fnt->ttfname));
    if (!real_ttfname)
      oops("Cannot find `%s'.", fnt->ttfname);

    FTopen(real_ttfname, fnt, True, True);

    initialized = True;
  }

  if (!quiet)
  {
    if (only_range)
      printf("\n\n%s:\n", fnt->fullname);
    printf("\n");
    printf("Glyph  Code   Glyph Name                ");
    printf("Width    llx   lly      urx   ury\n");
    printf("----------------------------------------");
    printf("---------------------------------\n");
  }

  /*
   *   We load only glyphs with a valid cmap entry.  Nevertheless, for
   *   the default mapping, we use the first 256 glyphs addressed by
   *   ascending code points, followed by glyphs not in the cmap.
   *
   *   If we compute a range, we take the character codes given in
   *   the fnt->sf_code array.
   *
   *   If the -N flag is set, no cmap is used at all.  Instead, the
   *   first 256 glyphs (with a valid PS name) are used for the default
   *   mapping.
   */

  if (!only_range)
    for (i = 0; i < 257; i++)
      index_array[i] = 0;
  else
    for (i = 0; i < 256; i++)
      fnt->inencptrs[i] = 0;

  j = 0;
  if (fnt->PSnames == Only)
    max_k = face->num_glyphs - 1;
  else
    max_k = only_range ? 0xFF : 0x16FFFF;

  for (k = 0; k <= max_k; k++)
  {
    char buff[128];
    const char *an;


    if (fnt->PSnames != Only)
    {
      if (only_range)
      {
        index = fnt->sf_code[k];
        if (index < 0)
          continue;
        j = k;
      }
      else
        index = k;

      Num = FT_Get_Char_Index(face, index);

      /* now we try to get a vertical glyph form */
      if (has_gsub)
        Num = Get_Vert(Num);

      if (Num < 0)
        oops("Failure on cmap mapping from %s.", fnt->ttfname);
      if (Num == 0)
        continue;
      if (!only_range)
        if (Num <= 256)
          index_array[Num] = 1;
    }
    else
    {
      Num = k;
      index = 0;
    }

    error = FT_Load_Glyph(face, Num, flags);
    if (!error)
    {
      if (fnt->efactor != 1.0 || fnt->slant != 0.0 )
        FT_Outline_Transform(&face->glyph->outline, &matrix1);
      if (fnt->rotate)
        FT_Outline_Transform(&face->glyph->outline, &matrix2);
      error = FT_Outline_Get_BBox(&face->glyph->outline, &bbox); /* we need the non-
                                                                    grid-fitted bbox */
    }
    if (!error)
    {
      if (fnt->PSnames)
      {
        (void)FT_Get_Glyph_Name(face, Num, buff, 128);
        an = newstring(buff);
      }
      else
        an = code_to_adobename(index);

      /* ignore characters not usable for typesetting with TeX */

      if (strcmp(an, ".notdef") == 0)
        continue;
      if (strcmp(an, ".null") == 0)
        continue;
      if (strcmp(an, "nonmarkingreturn") == 0)
        continue;

      ti = newchar(fnt);
      ti->charcode = index;
      ti->glyphindex = Num;
      ti->adobename = an;
      ti->llx = bbox.xMin * 1000 / fnt->units_per_em;
      ti->lly = bbox.yMin * 1000 / fnt->units_per_em;
      ti->urx = bbox.xMax * 1000 / fnt->units_per_em;
      ti->ury = bbox.yMax * 1000 / fnt->units_per_em;

      ti->fntnum = fnt->subfont_num;

      /*
       *   We must now shift the rotated character both horizontally
       *   and vertically.  The vertical amount is 25% by default.
       */

      if (fnt->rotate)
      {
        ti->llx += (face->glyph->metrics.vertBearingY - bbox.xMin) *
                     1000 / fnt->units_per_em;
        ti->lly -= 1000 * fnt->y_offset;
        ti->urx += (face->glyph->metrics.vertBearingY - bbox.xMin) *
                     1000 / fnt->units_per_em;
        ti->ury -= 1000 * fnt->y_offset;
      }

      /*
       *   We need to avoid negative heights or depths.  They break accents
       *   in math mode, among other things.
       */

      if (ti->lly > 0)
        ti->lly = 0;
      if (ti->ury < 0)
        ti->ury = 0;
      if (fnt->rotate)
        ti->width = face->glyph->metrics.vertAdvance * 1000 / fnt->units_per_em;
      else
        ti->width = transform(face->glyph->metrics.horiAdvance * 1000 / fnt->units_per_em,
                              0, fnt->efactor, fnt->slant);

      if (!quiet)
        printf("%5ld  %05lx  %-25s %5d  % 5d,% 5d -- % 5d,% 5d\n",
               Num, index, ti->adobename,
               ti->width,
               ti->llx, ti->lly, ti->urx, ti->ury);

      if (j < 256)
      {
        fnt->inencptrs[j] = ti;
        ti->incode = j;
      }
      j++;
    }
  }

  /*
   *   Now we load glyphs without a cmap entry, provided some slots are
   *   still free -- we skip this if we have to compute a range or use
   *   PS names.
   */

  if (!only_range && !fnt->PSnames)
  {
    for (i = 1; i <= face->num_glyphs; i++)
    {
      const char *an;


      if (index_array[i] == 0)
      {
        error = FT_Load_Glyph(face, i, flags);
        if (!error)
          error = FT_Outline_Get_BBox(&face->glyph->outline, &bbox);
        if (!error)
        {
          an = code_to_adobename(i | 0x1000000);

          ti = newchar(fnt);
          ti->charcode = i | 0x1000000;
          ti->glyphindex = i;
          ti->adobename = an;
          ti->llx = bbox.xMin * 1000 / fnt->units_per_em;
          ti->lly = bbox.yMin * 1000 / fnt->units_per_em;
          ti->urx = bbox.xMax * 1000 / fnt->units_per_em;
          ti->ury = bbox.yMax * 1000 / fnt->units_per_em;

          if (ti->lly > 0)
            ti->lly = 0;
          if (ti->ury < 0)
            ti->ury = 0;
          ti->width = transform(face->glyph->metrics.horiAdvance*1000 / fnt->units_per_em,
                                0, fnt->efactor, fnt->slant);

          if (!quiet)
            printf("%5d         %-25s %5d  % 5d,% 5d -- % 5d,% 5d\n",
                   i, ti->adobename,
                   ti->width,
                   ti->llx, ti->lly, ti->urx, ti->ury);

          if (j < 256)
          {
            fnt->inencptrs[j] = ti;
            ti->incode = j;
          }
          else
            break;
          j++;
        }
      }
    }
  }

  /* Finally, we construct a `Germandbls' glyph if necessary */

  if (!only_range)
  {
    if (NULL == findadobe("Germandbls", fnt->charlist) &&
        NULL != (Ti = findadobe("S", fnt->charlist)))
    {
      pcc *np, *nq;


      ti = newchar(fnt);
      ti->charcode = face->num_glyphs | 0x1000000;
      ti->glyphindex = face->num_glyphs;
      ti->adobename = "Germandbls";
      ti->width = Ti->width << 1;
      ti->llx = Ti->llx;
      ti->lly = Ti->lly;
      ti->urx = Ti->width + Ti->urx;
      ti->ury = Ti->ury;
      ti->kerns = Ti->kerns;

      np = newpcc();
      np->partname = "S";
      nq = newpcc();
      nq->partname = "S";
      nq->xoffset = Ti->width;
      np->next = nq;
      ti->pccs = np;
      ti->constructed = True;

      if (!quiet)
        printf("*            %-25s %5d  % 5d,% 5d -- % 5d,% 5d\n",
               ti->adobename,
               ti->width,
               ti->llx, ti->lly, ti->urx, ti->ury);
    }
  }

  /* kerning between subfonts isn't available */
  if (!only_range)
    readttf_kern(fnt);
}