[ Index ]

PHP Cross Reference of vtigercrm-6.1.0

title

Body

[close]

/libraries/tcpdf/fonts/ttf2ufm/ttf2ufm-src/ -> ttf.c (source)

   1  /*
   2   * True Type Font to Adobe Type 1 font converter 
   3   * By Mark Heath <[email protected]> 
   4   * Based on ttf2pfa by Andrew Weeks <[email protected]> 
   5   * With help from Frank M. Siegert <[email protected]> 
   6   *
   7   * see COPYRIGHT
   8   *
   9   */
  10  #include <stdio.h>
  11  #include <stdlib.h>
  12  #include <string.h>
  13  #include <sys/types.h>
  14  #include <sys/stat.h>
  15  #include <fcntl.h>
  16  #include <time.h>
  17  #include <ctype.h>
  18  #include <math.h>
  19  
  20  #ifndef WINDOWS
  21  #    include <unistd.h>
  22  #    include <netinet/in.h>
  23  #else
  24  #    include "windows.h"
  25  #endif
  26  
  27  #include "ttf.h"
  28  #include "pt1.h"
  29  #include "global.h"
  30  
  31  /* prototypes of call entries */
  32  static void openfont(char *fname, char *arg);
  33  static void closefont( void);
  34  static int getnglyphs ( void);
  35  static int glnames( GLYPH *glyph_list);
  36  static void glmetrics( GLYPH *glyph_list);
  37  static int glenc( GLYPH *glyph_list, int *encoding, int *unimap);
  38  static void fnmetrics( struct font_metrics *fm);
  39  static void glpath( int glyphno, GLYPH *glyph_list);
  40  static void kerning( GLYPH *glyph_list);
  41  
  42  /* globals */
  43  
  44  /* front-end descriptor */
  45  struct frontsw ttf_sw = {
  46      /*name*/       "ttf",
  47      /*descr*/      "built-in TTF support",
  48      /*suffix*/     { "ttf" },
  49      /*open*/       openfont,
  50      /*close*/      closefont,
  51      /*nglyphs*/    getnglyphs,
  52      /*glnames*/    glnames,
  53      /*glmetrics*/  glmetrics,
  54      /*glenc*/      glenc,
  55      /*fnmetrics*/  fnmetrics,
  56      /*glpath*/     glpath,
  57      /*kerning*/    kerning,
  58  };
  59  
  60  /* statics */
  61  
  62  static FILE    *ttf_file;
  63  static int      ttf_nglyphs, long_offsets;
  64  
  65  static TTF_DIRECTORY *directory;
  66  static TTF_DIR_ENTRY *dir_entry;
  67  static char    *filebuffer;
  68  static char    *filebuffer_end;
  69  static TTF_NAME *name_table = NULL;
  70  static TTF_NAME_REC *name_record;
  71  static TTF_HEAD *head_table = NULL;
  72  static TTF_HHEA *hhea_table = NULL;
  73  static TTF_KERN *kern_table = NULL;
  74  static TTF_CMAP *cmap_table = NULL;
  75  static LONGHORMETRIC *hmtx_table = NULL;
  76  static TTF_GLYF *glyf_table;
  77  static BYTE    *glyf_start = NULL;
  78  static TTF_MAXP *maxp_table = NULL;
  79  static TTF_POST_HEAD *post_table = NULL;
  80  static union {
  81      USHORT *sp;
  82      ULONG  *lp;
  83  } loca_table;
  84  #define short_loca_table    loca_table.sp
  85  #define long_loca_table        loca_table.lp
  86  
  87  static short    cmap_n_segs;
  88  static USHORT  *cmap_seg_start, *cmap_seg_end;
  89  static short   *cmap_idDelta, *cmap_idRangeOffset;
  90  static TTF_CMAP_FMT0  *encoding0;
  91  static int             enc_type;
  92  
  93  static char    *name_fields[8];
  94  
  95  static int enc_found_ms, enc_found_mac;
  96  
  97  static char    *mac_glyph_names[258] = {
  98      ".notdef", ".null", "CR",
  99      "space", "exclam", "quotedbl", "numbersign",
 100      "dollar", "percent", "ampersand", "quotesingle",
 101      "parenleft", "parenright", "asterisk", "plus",
 102      "comma", "hyphen", "period", "slash",
 103      "zero", "one", "two", "three",
 104      "four", "five", "six", "seven",
 105      "eight", "nine", "colon", "semicolon",
 106      "less", "equal", "greater", "question",
 107      "at", "A", "B", "C",
 108      "D", "E", "F", "G",
 109      "H", "I", "J", "K",
 110      "L", "M", "N", "O",
 111      "P", "Q", "R", "S",
 112      "T", "U", "V", "W",
 113      "X", "Y", "Z", "bracketleft",
 114      "backslash", "bracketright", "asciicircum", "underscore",
 115      "grave", "a", "b", "c",
 116      "d", "e", "f", "g",
 117      "h", "i", "j", "k",
 118      "l", "m", "n", "o",
 119      "p", "q", "r", "s",
 120      "t", "u", "v", "w",
 121      "x", "y", "z", "braceleft",
 122      "bar", "braceright", "asciitilde", "Adieresis",
 123      "Aring", "Ccedilla", "Eacute", "Ntilde",
 124      "Odieresis", "Udieresis", "aacute", "agrave",
 125      "acircumflex", "adieresis", "atilde", "aring",
 126      "ccedilla", "eacute", "egrave", "ecircumflex",
 127      "edieresis", "iacute", "igrave", "icircumflex",
 128      "idieresis", "ntilde", "oacute", "ograve",
 129      "ocircumflex", "odieresis", "otilde", "uacute",
 130      "ugrave", "ucircumflex", "udieresis", "dagger",
 131      "degree", "cent", "sterling", "section",
 132      "bullet", "paragraph", "germandbls", "registered",
 133      "copyright", "trademark", "acute", "dieresis",
 134      "notequal", "AE", "Oslash", "infinity",
 135      "plusminus", "lessequal", "greaterequal", "yen",
 136      "mu", "partialdiff", "summation", "product",
 137      "pi", "integral", "ordfeminine", "ordmasculine",
 138      "Omega", "ae", "oslash", "questiondown",
 139      "exclamdown", "logicalnot", "radical", "florin",
 140      "approxequal", "increment", "guillemotleft", "guillemotright",
 141      "ellipsis", "nbspace", "Agrave", "Atilde",
 142      "Otilde", "OE", "oe", "endash",
 143      "emdash", "quotedblleft", "quotedblright", "quoteleft",
 144      "quoteright", "divide", "lozenge", "ydieresis",
 145      "Ydieresis", "fraction", "currency", "guilsinglleft",
 146      "guilsinglright", "fi", "fl", "daggerdbl",
 147      "periodcentered", "quotesinglbase", "quotedblbase", "perthousand",
 148      "Acircumflex", "Ecircumflex", "Aacute", "Edieresis",
 149      "Egrave", "Iacute", "Icircumflex", "Idieresis",
 150      "Igrave", "Oacute", "Ocircumflex", "applelogo",
 151      "Ograve", "Uacute", "Ucircumflex", "Ugrave",
 152      "dotlessi", "circumflex", "tilde", "macron",
 153      "breve", "dotaccent", "ring", "cedilla",
 154      "hungarumlaut", "ogonek", "caron", "Lslash",
 155      "lslash", "Scaron", "scaron", "Zcaron",
 156      "zcaron", "brokenbar", "Eth", "eth",
 157      "Yacute", "yacute", "Thorn", "thorn",
 158      "minus", "multiply", "onesuperior", "twosuperior",
 159      "threesuperior", "onehalf", "onequarter", "threequarters",
 160      "franc", "Gbreve", "gbreve", "Idot",
 161      "Scedilla", "scedilla", "Cacute", "cacute",
 162      "Ccaron", "ccaron", "dmacron"
 163  };
 164  
 165  /* other prototypes */
 166  static void draw_composite_glyf( GLYPH *g, GLYPH *glyph_list, int glyphno, 
 167      double *matrix, int level);
 168  static void draw_simple_glyf( GLYPH *g, GLYPH *glyph_list, int glyphno, 
 169      double *matrix);
 170  static double f2dot14( short x);
 171  
 172  /* get the TTF description table address and length for this index */
 173  
 174  static void
 175  get_glyf_table(
 176      int glyphno,
 177      TTF_GLYF **tab,
 178      int *len
 179  )
 180  {
 181      if(tab!=NULL) {
 182          if (long_offsets) {
 183              *tab = (TTF_GLYF *) (glyf_start + ntohl(long_loca_table[glyphno]));
 184          } else {
 185              *tab = (TTF_GLYF *) (glyf_start + (ntohs(short_loca_table[glyphno]) << 1));
 186          }
 187      }
 188      if(len!=NULL) {
 189          if (long_offsets) {
 190              *len = ntohl(long_loca_table[glyphno + 1]) - ntohl(long_loca_table[glyphno]);
 191          } else {
 192              *len = (ntohs(short_loca_table[glyphno + 1]) - ntohs(short_loca_table[glyphno])) << 1;
 193          }
 194      }
 195  }
 196  
 197  static void
 198  handle_name(void)
 199  {
 200      int             j, k, lang, len, platform;
 201      char           *p, *string_area;
 202      int             found3 = 0;
 203  
 204      string_area = (char *) name_table + ntohs(name_table->offset);
 205      name_record = &(name_table->nameRecords);
 206  
 207      for (j = 0; j < 8; j++) {
 208          name_fields[j] = ""; 
 209      }
 210  
 211      for (j = 0; j < ntohs(name_table->numberOfNameRecords); j++) {
 212  
 213          platform = ntohs(name_record->platformID);
 214  
 215          if (platform == 3) {
 216  
 217              found3 = 1;
 218              lang = ntohs(name_record->languageID) & 0xff;
 219              len = ntohs(name_record->stringLength);
 220              if (lang == 0 || lang == 9) {
 221                  k = ntohs(name_record->nameID);
 222                  if (k < 8) {
 223                      p = string_area + ntohs(name_record->stringOffset);
 224                      name_fields[k] = dupcnstring(p, len);
 225                  }
 226              }
 227          }
 228          name_record++;
 229      }
 230  
 231      string_area = (char *) name_table + ntohs(name_table->offset);
 232      name_record = &(name_table->nameRecords);
 233  
 234      if (!found3) {
 235          for (j = 0; j < ntohs(name_table->numberOfNameRecords); j++) {
 236  
 237              platform = ntohs(name_record->platformID);
 238  
 239              if (platform == 1) {
 240  
 241                  found3 = 1;
 242                  lang = ntohs(name_record->languageID) & 0xff;
 243                  len = ntohs(name_record->stringLength);
 244                  if (lang == 0 || lang == 9) {
 245                      k = ntohs(name_record->nameID);
 246                      if (k < 8) {
 247                          p = string_area + ntohs(name_record->stringOffset);
 248                          name_fields[k] = dupcnstring(p, len);
 249                      }
 250                  }
 251              }
 252              name_record++;
 253          }
 254      }
 255      if (!found3) {
 256          fprintf(stderr, "**** Cannot decode font name fields ****\n");
 257          exit(1);
 258      }
 259      if (name_fields[4][0] == 0) { /* Full Name empty, use Family Name */
 260          name_fields[4] = name_fields[1];
 261      }
 262      if (name_fields[6][0] == 0) { /* Font Name empty, use Full Name */
 263          name_fields[6] = name_fields[4];
 264          if (name_fields[6][0] == 0) { /* oops, empty again */
 265              WARNING_1 fprintf(stderr, "Font name is unknown, setting to \"Unknown\"\n");
 266              name_fields[6] = "Unknown";
 267          }
 268      }
 269      p = name_fields[6];
 270      /* must not start with a digit */
 271      if(isdigit(*p))
 272          *p+= 'A'-'0'; /* change to a letter */
 273      while (*p != '\0') {
 274          if (!isalnum(*p) || *p=='_') {
 275              *p = '-';
 276          }
 277          p++;
 278      }
 279  }
 280  
 281  static void
 282  handle_head(void)
 283  {
 284      long_offsets = ntohs(head_table->indexToLocFormat);
 285      if (long_offsets != 0 && long_offsets != 1) {
 286          fprintf(stderr, "**** indexToLocFormat wrong ****\n");
 287          exit(1);
 288      }
 289  }
 290  
 291  /* limit the recursion level to avoid cycles */
 292  #define MAX_COMPOSITE_LEVEL 20
 293  
 294  static void
 295  draw_composite_glyf(
 296      GLYPH *g,
 297      GLYPH *glyph_list,
 298      int glyphno,
 299      double *orgmatrix,
 300      int level
 301  )
 302  {
 303      int len;
 304      short           ncontours;
 305      USHORT          flagbyte, glyphindex;
 306      double          arg1, arg2;
 307      BYTE           *ptr;
 308      char           *bptr;
 309      SHORT          *sptr;
 310      double          matrix[6], newmatrix[6];
 311  
 312      get_glyf_table(glyphno, &glyf_table, &len);
 313  
 314      if(len<=0) /* nothing to do */
 315          return;
 316  
 317      ncontours = ntohs(glyf_table->numberOfContours);
 318      if (ncontours >= 0) { /* simple case */
 319          draw_simple_glyf(g, glyph_list, glyphno, orgmatrix);
 320          return;
 321      }
 322  
 323      if(ISDBG(COMPOSITE) && level ==0)
 324          fprintf(stderr, "* %s [ %.2f %.2f %.2f %.2f %.2f %.2f ]\n", g->name,
 325              orgmatrix[0], orgmatrix[1], orgmatrix[2], orgmatrix[3],
 326              orgmatrix[4], orgmatrix[5]);
 327  
 328      /* complex case */
 329      if(level >= MAX_COMPOSITE_LEVEL) {
 330          WARNING_1 fprintf(stderr, 
 331              "*** Glyph %s: stopped (possibly infinite) recursion at depth %d\n",
 332              g->name, level);
 333          return;
 334      }
 335  
 336      ptr = ((BYTE *) glyf_table + sizeof(TTF_GLYF));
 337      sptr = (SHORT *) ptr;
 338      do {
 339          flagbyte = ntohs(*sptr);
 340          sptr++;
 341          glyphindex = ntohs(*sptr);
 342          sptr++;
 343  
 344          if (flagbyte & ARG_1_AND_2_ARE_WORDS) {
 345              arg1 = (short)ntohs(*sptr);
 346              sptr++;
 347              arg2 = (short)ntohs(*sptr);
 348              sptr++;
 349          } else {
 350              bptr = (char *) sptr;
 351              arg1 = (signed char) bptr[0];
 352              arg2 = (signed char) bptr[1];
 353              sptr++;
 354          }
 355          matrix[1] = matrix[2] = 0.0;
 356  
 357          if (flagbyte & WE_HAVE_A_SCALE) {
 358              matrix[0] = matrix[3] = f2dot14(*sptr);
 359              sptr++;
 360          } else if (flagbyte & WE_HAVE_AN_X_AND_Y_SCALE) {
 361              matrix[0] = f2dot14(*sptr);
 362              sptr++;
 363              matrix[3] = f2dot14(*sptr);
 364              sptr++;
 365          } else if (flagbyte & WE_HAVE_A_TWO_BY_TWO) {
 366              matrix[0] = f2dot14(*sptr);
 367              sptr++;
 368              matrix[2] = f2dot14(*sptr);
 369              sptr++;
 370              matrix[1] = f2dot14(*sptr);
 371              sptr++;
 372              matrix[3] = f2dot14(*sptr);
 373              sptr++;
 374          } else {
 375              matrix[0] = matrix[3] = 1.0;
 376          }
 377  
 378          /*
 379           * See *
 380           * http://fonts.apple.com/TTRefMan/RM06/Chap6g
 381           * lyf.html * matrix[0,1,2,3,4,5]=a,b,c,d,m,n
 382           */
 383  
 384          if (fabs(matrix[0]) > fabs(matrix[1]))
 385              matrix[4] = fabs(matrix[0]);
 386          else
 387              matrix[4] = fabs(matrix[1]);
 388          if (fabs(fabs(matrix[0]) - fabs(matrix[2])) <= 33. / 65536.)
 389              matrix[4] *= 2.0;
 390  
 391          if (fabs(matrix[2]) > fabs(matrix[3]))
 392              matrix[5] = fabs(matrix[2]);
 393          else
 394              matrix[5] = fabs(matrix[3]);
 395          if (fabs(fabs(matrix[2]) - fabs(matrix[3])) <= 33. / 65536.)
 396              matrix[5] *= 2.0;
 397  
 398          /*
 399           * fprintf (stderr,"Matrix Opp %hd
 400           * %hd\n",arg1,arg2);
 401           */
 402  #if 0
 403          fprintf(stderr, "Matrix: %f %f %f %f %f %f\n",
 404           matrix[0], matrix[1], matrix[2], matrix[3],
 405              matrix[4], matrix[5]);
 406          fprintf(stderr, "Offset: %f %f (%s)\n",
 407              arg1, arg2,
 408              ((flagbyte & ARGS_ARE_XY_VALUES) ? "XY" : "index"));
 409  #endif
 410  
 411          if (flagbyte & ARGS_ARE_XY_VALUES) {
 412              matrix[4] *= arg1;
 413              matrix[5] *= arg2;
 414          } else {
 415              WARNING_1 fprintf(stderr, 
 416                  "*** Glyph %s: reusing scale from another glyph is unsupported\n",
 417                  g->name);
 418              /*
 419               * must extract values from a glyph
 420               * but it seems to be too much pain
 421               * and it's not clear now that it
 422               * would be really used in any
 423               * interesting font
 424               */
 425          }
 426  
 427          /* at this point arg1,arg2 contain what logically should be matrix[4,5] */
 428  
 429          /* combine matrices */
 430  
 431          newmatrix[0] = orgmatrix[0]*matrix[0] + orgmatrix[2]*matrix[1];
 432          newmatrix[1] = orgmatrix[0]*matrix[2] + orgmatrix[2]*matrix[3];
 433  
 434          newmatrix[2] = orgmatrix[1]*matrix[0] + orgmatrix[3]*matrix[1];
 435          newmatrix[3] = orgmatrix[1]*matrix[2] + orgmatrix[3]*matrix[3];
 436  
 437          newmatrix[4] = orgmatrix[0]*matrix[4] + orgmatrix[2]*matrix[5] + orgmatrix[4];
 438          newmatrix[5] = orgmatrix[1]*matrix[4] + orgmatrix[3]*matrix[5] + orgmatrix[5];
 439  
 440          if(ISDBG(COMPOSITE)) {
 441              fprintf(stderr, "%*c+-> %2d %s [ %.2f %.2f %.2f %.2f %.2f %.2f ]\n",
 442                  level+1, ' ', level, glyph_list[glyphindex].name,
 443                  matrix[0], matrix[1], matrix[2], matrix[3],
 444                  matrix[4], matrix[5]);
 445              fprintf(stderr, "%*c        = [ %.2f %.2f %.2f %.2f %.2f %.2f ]\n",
 446                  level+1, ' ',
 447                  newmatrix[0], newmatrix[1], newmatrix[2], newmatrix[3],
 448                  newmatrix[4], newmatrix[5]);
 449          }
 450          draw_composite_glyf(g, glyph_list, glyphindex, newmatrix, level+1);
 451  
 452      } while (flagbyte & MORE_COMPONENTS);
 453  }
 454  
 455  static void
 456  draw_simple_glyf(
 457      GLYPH *g,
 458      GLYPH *glyph_list,
 459      int glyphno,
 460      double *matrix
 461  )
 462  {
 463      int             i, j, k, k1, len, first, cs, ce;
 464      /* We assume that hsbw always sets to(0, 0) */
 465      double          xlast = 0, ylast = 0;
 466      int             finished, nguide, contour_start, contour_end;
 467      short           ncontours, n_inst, last_point;
 468      USHORT         *contour_end_pt;
 469      BYTE           *ptr;
 470  #define GLYFSZ    2000
 471      short           xabs[GLYFSZ], yabs[GLYFSZ], xrel[GLYFSZ], yrel[GLYFSZ];
 472      double          xcoord[GLYFSZ], ycoord[GLYFSZ];
 473      BYTE            flags[GLYFSZ];
 474      double          tx, ty;
 475      int             needreverse = 0;    /* transformation may require
 476                           * that */
 477      GENTRY         *lge;
 478  
 479      lge = g->lastentry;
 480  
 481      get_glyf_table(glyphno, &glyf_table, &len);
 482  
 483      if (len <= 0) {
 484          WARNING_1 fprintf(stderr,
 485              "**** Composite glyph %s refers to non-existent glyph %s, ignored\n",
 486              g->name,
 487              glyph_list[glyphno].name);
 488          return;
 489      }
 490      ncontours = ntohs(glyf_table->numberOfContours);
 491      if (ncontours < 0) {
 492          WARNING_1 fprintf(stderr,
 493              "**** Composite glyph %s refers to composite glyph %s, ignored\n",
 494              g->name,
 495              glyph_list[glyphno].name);
 496          return;
 497      }
 498      contour_end_pt = (USHORT *) ((char *) glyf_table + sizeof(TTF_GLYF));
 499  
 500      last_point = ntohs(contour_end_pt[ncontours - 1]);
 501      n_inst = ntohs(contour_end_pt[ncontours]);
 502  
 503      ptr = ((BYTE *) contour_end_pt) + (ncontours << 1) + n_inst + 2;
 504      j = k = 0;
 505      while (k <= last_point) {
 506          flags[k] = ptr[j];
 507  
 508          if (ptr[j] & REPEAT) {
 509              for (k1 = 0; k1 < ptr[j + 1]; k1++) {
 510                  k++;
 511                  flags[k] = ptr[j];
 512              }
 513              j++;
 514          }
 515          j++;
 516          k++;
 517      }
 518  
 519      for (k = 0; k <= last_point; k++) {
 520          if (flags[k] & XSHORT) {
 521              if (flags[k] & XSAME) {
 522                  xrel[k] = ptr[j];
 523              } else {
 524                  xrel[k] = -ptr[j];
 525              }
 526              j++;
 527          } else if (flags[k] & XSAME) {
 528              xrel[k] = 0.0;
 529          } else {
 530              xrel[k] = (short)( ptr[j] * 256 + ptr[j + 1] );
 531              j += 2;
 532          }
 533          if (k == 0) {
 534              xabs[k] = xrel[k];
 535          } else {
 536              xabs[k] = xrel[k] + xabs[k - 1];
 537          }
 538  
 539      }
 540  
 541      for (k = 0; k <= last_point; k++) {
 542          if (flags[k] & YSHORT) {
 543              if (flags[k] & YSAME) {
 544                  yrel[k] = ptr[j];
 545              } else {
 546                  yrel[k] = -ptr[j];
 547              }
 548              j++;
 549          } else if (flags[k] & YSAME) {
 550              yrel[k] = 0;
 551          } else {
 552              yrel[k] = ptr[j] * 256 + ptr[j + 1];
 553              j += 2;
 554          }
 555          if (k == 0) {
 556              yabs[k] = yrel[k];
 557          } else {
 558              yabs[k] = yrel[k] + yabs[k - 1];
 559          }
 560      }
 561  
 562      if (matrix) {
 563          for (i = 0; i <= last_point; i++) {
 564              tx = xabs[i];
 565              ty = yabs[i];
 566              xcoord[i] = fscale(matrix[0] * tx + matrix[2] * ty + matrix[4]);
 567              ycoord[i] = fscale(matrix[1] * tx + matrix[3] * ty + matrix[5]);
 568          }
 569      } else {
 570          for (i = 0; i <= last_point; i++) {
 571              xcoord[i] = fscale(xabs[i]);
 572              ycoord[i] = fscale(yabs[i]);
 573          }
 574      }
 575  
 576      i = j = 0;
 577      first = 1;
 578  
 579      while (i <= ntohs(contour_end_pt[ncontours - 1])) {
 580          contour_end = ntohs(contour_end_pt[j]);
 581  
 582          if (first) {
 583              fg_rmoveto(g, xcoord[i], ycoord[i]);
 584              xlast = xcoord[i];
 585              ylast = ycoord[i];
 586              contour_start = i;
 587              first = 0;
 588          } else if (flags[i] & ONOROFF) {
 589              fg_rlineto(g, xcoord[i], ycoord[i]);
 590              xlast = xcoord[i];
 591              ylast = ycoord[i];
 592          } else {
 593              cs = i - 1;
 594              finished = nguide = 0;
 595              while (!finished) {
 596                  if (i == contour_end + 1) {
 597                      ce = contour_start;
 598                      finished = 1;
 599                  } else if (flags[i] & ONOROFF) {
 600                      ce = i;
 601                      finished = 1;
 602                  } else {
 603                      i++;
 604                      nguide++;
 605                  }
 606              }
 607  
 608              switch (nguide) {
 609              case 0:
 610                  fg_rlineto(g, xcoord[ce], ycoord[ce]);
 611                  xlast = xcoord[ce];
 612                  ylast = ycoord[ce];
 613                  break;
 614  
 615              case 1:
 616                  fg_rrcurveto(g,
 617                        (xcoord[cs] + 2.0 * xcoord[cs + 1]) / 3.0,
 618                        (ycoord[cs] + 2.0 * ycoord[cs + 1]) / 3.0,
 619                        (2.0 * xcoord[cs + 1] + xcoord[ce]) / 3.0,
 620                        (2.0 * ycoord[cs + 1] + ycoord[ce]) / 3.0,
 621                          xcoord[ce],
 622                          ycoord[ce]
 623                      );
 624                  xlast = xcoord[ce];
 625                  ylast = ycoord[ce];
 626  
 627                  break;
 628  
 629              case 2:
 630                  fg_rrcurveto(g,
 631                       (-xcoord[cs] + 4.0 * xcoord[cs + 1]) / 3.0,
 632                       (-ycoord[cs] + 4.0 * ycoord[cs + 1]) / 3.0,
 633                        (4.0 * xcoord[cs + 2] - xcoord[ce]) / 3.0,
 634                        (4.0 * ycoord[cs + 2] - ycoord[ce]) / 3.0,
 635                          xcoord[ce],
 636                          ycoord[ce]
 637                      );
 638                  xlast = xcoord[ce];
 639                  ylast = ycoord[ce];
 640                  break;
 641  
 642              case 3:
 643                  fg_rrcurveto(g,
 644                        (xcoord[cs] + 2.0 * xcoord[cs + 1]) / 3.0,
 645                        (ycoord[cs] + 2.0 * ycoord[cs + 1]) / 3.0,
 646                    (5.0 * xcoord[cs + 1] + xcoord[cs + 2]) / 6.0,
 647                    (5.0 * ycoord[cs + 1] + ycoord[cs + 2]) / 6.0,
 648                        (xcoord[cs + 1] + xcoord[cs + 2]) / 2.0,
 649                        (ycoord[cs + 1] + ycoord[cs + 2]) / 2.0
 650                      );
 651  
 652                  fg_rrcurveto(g,
 653                    (xcoord[cs + 1] + 5.0 * xcoord[cs + 2]) / 6.0,
 654                    (ycoord[cs + 1] + 5.0 * ycoord[cs + 2]) / 6.0,
 655                    (5.0 * xcoord[cs + 2] + xcoord[cs + 3]) / 6.0,
 656                    (5.0 * ycoord[cs + 2] + ycoord[cs + 3]) / 6.0,
 657                        (xcoord[cs + 3] + xcoord[cs + 2]) / 2.0,
 658                        (ycoord[cs + 3] + ycoord[cs + 2]) / 2.0
 659                      );
 660  
 661                  fg_rrcurveto(g,
 662                    (xcoord[cs + 2] + 5.0 * xcoord[cs + 3]) / 6.0,
 663                    (ycoord[cs + 2] + 5.0 * ycoord[cs + 3]) / 6.0,
 664                        (2.0 * xcoord[cs + 3] + xcoord[ce]) / 3.0,
 665                        (2.0 * ycoord[cs + 3] + ycoord[ce]) / 3.0,
 666                          xcoord[ce],
 667                          ycoord[ce]
 668                      );
 669                  ylast = ycoord[ce];
 670                  xlast = xcoord[ce];
 671  
 672                  break;
 673  
 674              default:
 675                  k1 = cs + nguide;
 676                  fg_rrcurveto(g,
 677                        (xcoord[cs] + 2.0 * xcoord[cs + 1]) / 3.0,
 678                        (ycoord[cs] + 2.0 * ycoord[cs + 1]) / 3.0,
 679                    (5.0 * xcoord[cs + 1] + xcoord[cs + 2]) / 6.0,
 680                    (5.0 * ycoord[cs + 1] + ycoord[cs + 2]) / 6.0,
 681                        (xcoord[cs + 1] + xcoord[cs + 2]) / 2.0,
 682                        (ycoord[cs + 1] + ycoord[cs + 2]) / 2.0
 683                      );
 684  
 685                  for (k = cs + 2; k <= k1 - 1; k++) {
 686                      fg_rrcurveto(g,
 687                      (xcoord[k - 1] + 5.0 * xcoord[k]) / 6.0,
 688                      (ycoord[k - 1] + 5.0 * ycoord[k]) / 6.0,
 689                      (5.0 * xcoord[k] + xcoord[k + 1]) / 6.0,
 690                      (5.0 * ycoord[k] + ycoord[k + 1]) / 6.0,
 691                          (xcoord[k] + xcoord[k + 1]) / 2.0,
 692                           (ycoord[k] + ycoord[k + 1]) / 2.0
 693                          );
 694  
 695                  }
 696  
 697                  fg_rrcurveto(g,
 698                        (xcoord[k1 - 1] + 5.0 * xcoord[k1]) / 6.0,
 699                        (ycoord[k1 - 1] + 5.0 * ycoord[k1]) / 6.0,
 700                        (2.0 * xcoord[k1] + xcoord[ce]) / 3.0,
 701                        (2.0 * ycoord[k1] + ycoord[ce]) / 3.0,
 702                          xcoord[ce],
 703                          ycoord[ce]
 704                      );
 705                  xlast = xcoord[ce];
 706                  ylast = ycoord[ce];
 707  
 708                  break;
 709              }
 710          }
 711          if (i >= contour_end) {
 712              g_closepath(g);
 713              first = 1;
 714              i = contour_end + 1;
 715              j++;
 716          } else {
 717              i++;
 718          }
 719      }
 720  
 721      if (matrix) {
 722          /* guess whether do we need to reverse the results */
 723  
 724          double             x[3], y[3];
 725          int                max = 0, from, to;
 726  
 727          /* transform a triangle going in proper direction */
 728          /*
 729           * the origin of triangle is in (0,0) so we know it in
 730           * advance
 731           */
 732  
 733          x[0] = y[0] = 0;
 734          x[1] = matrix[0] * 0 + matrix[2] * 300;
 735          y[1] = matrix[1] * 0 + matrix[3] * 300;
 736          x[2] = matrix[0] * 300 + matrix[2] * 0;
 737          y[2] = matrix[1] * 300 + matrix[3] * 0;
 738  
 739          /* then find the topmost point */
 740          for (i = 0; i < 3; i++)
 741              if (y[i] > y[max])
 742                  max = i;
 743          from = (max + 3 - 1) % 3;
 744          to = (max + 1) % 3;
 745  
 746          needreverse = 0;
 747  
 748          /* special cases for horizontal lines */
 749          if (y[max] == y[from]) {
 750              if (x[max] < y[from])
 751                  needreverse = 1;
 752          } else if (y[to] == y[from]) {
 753              if (x[to] < x[max])
 754                  needreverse = 1;
 755          } else {    /* generic case */
 756              if ((x[to] - x[max]) * (y[max] - y[from])
 757                  > (x[max] - x[from]) * (y[to] - y[max]))
 758                  needreverse = 1;
 759          }
 760  
 761          if (needreverse) {
 762              if (lge) {
 763                  assertpath(lge->next, __FILE__, __LINE__, g->name);
 764                  reversepathsfromto(lge->next, NULL);
 765              } else {
 766                  assertpath(g->entries, __FILE__, __LINE__, g->name);
 767                  reversepaths(g);
 768              }
 769          }
 770      }
 771  }
 772  
 773  static double
 774  f2dot14(
 775      short x
 776  )
 777  {
 778      short           y = ntohs(x);
 779      return (y >> 14) + ((y & 0x3fff) / 16384.0);
 780  }
 781  
 782  
 783  /* check that the pointer points within the file */
 784  /* returns 0 if pointer is good, 1 if bad */
 785  static int
 786  badpointer(
 787      void *ptr
 788  )
 789  {
 790      return (ptr < (void *)filebuffer || ptr >= (void *)filebuffer_end);
 791  }
 792  
 793  /*
 794   * Externally accessible methods
 795   */
 796  
 797  /*
 798   * Open font and prepare to return information to the main driver.
 799   * May print error and warning messages.
 800   * Exit on error.
 801   */
 802  
 803  static void
 804  openfont(
 805      char *fname,
 806      char *arg /* unused now */
 807  )
 808  {
 809      int             i, j;
 810      struct stat     statbuf;
 811      static struct {
 812          void **tbpp; /* pointer to pointer to the table */
 813          char name[5]; /* table name */
 814          char optional; /* flag: table may be missing */
 815      } tables[] = {
 816          { (void **)&name_table, "name", 0 },
 817          { (void **)&head_table, "head", 0 },
 818          { (void **)&hhea_table, "hhea", 0 },
 819          { (void **)&post_table, "post", 0 },
 820          { (void **)&glyf_start, "glyf", 0 },
 821          { (void **)&cmap_table, "cmap", 0 },
 822          { (void **)&kern_table, "kern", 1 },
 823          { (void **)&maxp_table, "maxp", 0 },
 824          { (void **)&hmtx_table, "hmtx", 0 },
 825          { (void **)&long_loca_table, "loca", 0 },
 826          { NULL, "", 0 } /* end of table */
 827      };
 828  
 829      if (stat(fname, &statbuf) == -1) {
 830          fprintf(stderr, "**** Cannot access %s ****\n", fname);
 831          exit(1);
 832      }
 833      if ((filebuffer = malloc(statbuf.st_size)) == NULL) {
 834          fprintf(stderr, "**** Cannot malloc space for file ****\n");
 835          exit(1);
 836      }
 837  
 838      filebuffer_end = filebuffer + statbuf.st_size;
 839  
 840      if ((ttf_file = fopen(fname, "rb")) == NULL) {
 841          fprintf(stderr, "**** Cannot open file '%s'\n", fname);
 842          exit(1);
 843      } else {
 844          WARNING_2 fprintf(stderr, "Processing file %s\n", fname);
 845      }
 846  
 847      if (fread(filebuffer, 1, statbuf.st_size, ttf_file) != statbuf.st_size) {
 848          fprintf(stderr, "**** Could not read whole file \n");
 849          exit(1);
 850      }
 851      fclose(ttf_file);
 852  
 853      directory = (TTF_DIRECTORY *) filebuffer;
 854  
 855      if (ntohl(directory->sfntVersion) != 0x00010000) {
 856          fprintf(stderr,
 857              "**** Unknown File Version number [%x], or not a TrueType file\n",
 858              directory->sfntVersion);
 859          exit(1);
 860      }
 861  
 862      /* clear the tables */
 863      for(j=0; tables[j].tbpp != NULL; j++)
 864          *(tables[j].tbpp) = NULL;
 865  
 866      dir_entry = &(directory->list);
 867  
 868      for (i = 0; i < ntohs(directory->numTables); i++) {
 869  
 870          for(j=0; tables[j].tbpp != NULL; j++)
 871              if (memcmp(dir_entry->tag, tables[j].name, 4) == 0) {
 872                  *(tables[j].tbpp) = (void *) (filebuffer + ntohl(dir_entry->offset));
 873                  break;
 874              }
 875  
 876          if (memcmp(dir_entry->tag, "EBDT", 4) == 0 ||
 877                 memcmp(dir_entry->tag, "EBLC", 4) == 0 ||
 878                 memcmp(dir_entry->tag, "EBSC", 4) == 0) {
 879              WARNING_1 fprintf(stderr, "Font contains bitmaps\n");
 880          }
 881          dir_entry++;
 882      }
 883  
 884      for(j=0; tables[j].tbpp != NULL; j++)
 885          if(!tables[j].optional && badpointer( *(tables[j].tbpp) )) {
 886              fprintf(stderr, "**** File contains no required table '%s'\n", tables[j].name);
 887              exit(1);
 888          }
 889  
 890      handle_name();
 891  
 892      handle_head();
 893  
 894      ttf_nglyphs = ntohs(maxp_table->numGlyphs);
 895  
 896      enc_found_ms = enc_found_mac = 0;
 897  }
 898  
 899  /*
 900   * Close font.
 901   * Exit on error.
 902   */
 903  
 904  static void
 905  closefont(
 906      void
 907  )
 908  {
 909      return; /* empty operation */
 910  }
 911  
 912  /*
 913   * Get the number of glyphs in font.
 914   */
 915  
 916  static int
 917  getnglyphs (
 918      void
 919  )
 920  {
 921      return ttf_nglyphs;
 922  }
 923  
 924  /*
 925   * Get the names of the glyphs.
 926   * Returns 0 if the names were assigned, non-zero if the font
 927   * provides no glyph names.
 928   */
 929  
 930  static int
 931  glnames(
 932      GLYPH *glyph_list
 933  )
 934  {
 935      int             i, len, n, npost;
 936      unsigned int    format;
 937      USHORT         *name_index;
 938      char           *ptr, *p;
 939      char          **ps_name_ptr = (char **) malloc(ttf_nglyphs * sizeof(char *));
 940      int             n_ps_names;
 941      int             ps_fmt_3 = 0;
 942  
 943      format = ntohl(post_table->formatType);
 944  
 945      if (format == 0x00010000) {
 946          for (i = 0; i < 258 && i < ttf_nglyphs; i++) {
 947              glyph_list[i].name = mac_glyph_names[i];
 948          }
 949      } else if (format == 0x00020000) {
 950                  npost = ntohs(post_table->numGlyphs);
 951                  if (ttf_nglyphs != npost) {
 952                          /* This is an error in the font, but we can now cope */
 953                          WARNING_1 fprintf(stderr, "**** Postscript table size mismatch %d/%d ****\n",
 954                                  npost, ttf_nglyphs);
 955                  }
 956                  n_ps_names = 0;
 957                  name_index = &(post_table->glyphNameIndex);
 958  
 959                  /* This checks the integrity of the post table */       
 960                  for (i=0; i<npost; i++) {
 961                      n = ntohs(name_index[i]);
 962                      if (n > n_ps_names + 257) {
 963                          n_ps_names = n - 257;
 964                      }
 965                  }
 966  
 967                  ptr = (char *) post_table + 34 + (ttf_nglyphs << 1);
 968                  i = 0;
 969                  while (*ptr > 0 && i < n_ps_names) {
 970                          len = *ptr;
 971                          /* previously the program wrote nulls into the table. If the table
 972                             was corrupt, this could put zeroes anywhere, leading to obscure bugs,
 973                             so now I malloc space for the names. Yes it is much less efficient */
 974                             
 975                          if ((p = malloc(len+1)) == NULL) {
 976                              fprintf (stderr, "****malloc failed %s line %d\n", __FILE__, __LINE__);
 977                              exit(255);
 978                          }
 979                          
 980                          ps_name_ptr[i] = p;
 981                          strncpy(p, ptr+1, len);
 982                          p[len] = '\0';
 983                          i ++;
 984                          ptr += len + 1;
 985                  }
 986          
 987                  if (i != n_ps_names)
 988                  {
 989                      WARNING_2 fprintf (stderr, "** Postscript Name mismatch %d != %d **\n",
 990                               i, n_ps_names);
 991                      n_ps_names = i;
 992                  }
 993  
 994                  /*
 995                   * for (i=0; i<n_ps_names; i++) { fprintf(stderr, "i=%d,
 996                   * len=%d, name=%s\n", i, ps_name_len[i], ps_name_ptr[i]); }
 997                   */
 998  
 999                  for (i = 0; i < npost; i++) {
1000                          n = ntohs(name_index[i]);
1001                          if (n < 258) {
1002                                  glyph_list[i].name = mac_glyph_names[n];
1003                          } else if (n < 258 + n_ps_names) {
1004                                  glyph_list[i].name = ps_name_ptr[n - 258];
1005                          } else {
1006                                  glyph_list[i].name = malloc(16);
1007                                  sprintf(glyph_list[i].name, "_g_%d", i);
1008                                  WARNING_2 fprintf(stderr,
1009                                          "Glyph No. %d has no postscript name, becomes %s\n",
1010                                          i, glyph_list[i].name);
1011                          }
1012                  }
1013                  /* Now fake postscript names for all those beyond the end of the table */
1014                  if (npost < ttf_nglyphs) {
1015                      for (i=npost; i<ttf_nglyphs; i++) {
1016                          if ((glyph_list[i].name = malloc(16)) == NULL)
1017                          {
1018                              fprintf (stderr, "****malloc failed %s line %d\n", __FILE__, __LINE__);
1019                              exit(255);
1020                          }
1021                          sprintf(glyph_list[i].name, "_g_%d", i);
1022                          WARNING_2 fprintf(stderr,
1023                                  "Glyph No. %d has no postscript name, becomes %s\n",
1024                                  i, glyph_list[i].name);
1025                      }
1026                  }
1027      } else if (format == 0x00030000) {
1028          WARNING_3 fputs("No postscript table, using default\n", stderr);
1029          ps_fmt_3 = 1;
1030      } else if (format == 0x00028000) {
1031          ptr = (char *) &(post_table->numGlyphs);
1032          for (i = 0; i < ttf_nglyphs; i++) {
1033              glyph_list[i].name = mac_glyph_names[i + ptr[i]];
1034          }
1035      } else {
1036          fprintf(stderr,
1037              "**** Postscript table in wrong format %x ****\n",
1038              format);
1039          exit(1);
1040      }
1041  
1042      return ps_fmt_3;
1043  }
1044  
1045  /*
1046   * Get the metrics of the glyphs.
1047   */
1048  
1049  static void
1050  glmetrics(
1051      GLYPH *glyph_list
1052  )
1053  {
1054      int             i;
1055      int             n_hmetrics = ntohs(hhea_table->numberOfHMetrics);
1056      GLYPH          *g;
1057      LONGHORMETRIC  *hmtx_entry = hmtx_table;
1058      FWORD          *lsblist;
1059  
1060      for (i = 0; i < n_hmetrics; i++) {
1061          g = &(glyph_list[i]);
1062          g->width = ntohs(hmtx_entry->advanceWidth);
1063          g->lsb = ntohs(hmtx_entry->lsb);
1064          hmtx_entry++;
1065      }
1066  
1067      lsblist = (FWORD *) hmtx_entry;
1068      hmtx_entry--;
1069  
1070      for (i = n_hmetrics; i < ttf_nglyphs; i++) {
1071          g = &(glyph_list[i]);
1072          g->width = ntohs(hmtx_entry->advanceWidth);
1073          g->lsb = ntohs(lsblist[i - n_hmetrics]);
1074      }
1075  
1076      for (i = 0; i < ttf_nglyphs; i++) {
1077          g = &(glyph_list[i]);
1078          get_glyf_table(i, &glyf_table, &g->ttf_pathlen);
1079  
1080          g->xMin = (short)ntohs(glyf_table->xMin);
1081          g->xMax = (short)ntohs(glyf_table->xMax);
1082          g->yMin = (short)ntohs(glyf_table->yMin);
1083          g->yMax = (short)ntohs(glyf_table->yMax);
1084      }
1085  
1086  }
1087  
1088  
1089  static void
1090  handle_ms_encoding(
1091      GLYPH *glyph_list,
1092      int *encoding,
1093      int *unimap
1094  )
1095  {
1096      int             j, k, kk, set_ok;
1097      USHORT          start, end, ro;
1098      short           delta, n;
1099  
1100      for (j = 0; j < cmap_n_segs - 1; j++) {
1101          start = ntohs(cmap_seg_start[j]);
1102          end = ntohs(cmap_seg_end[j]);
1103          delta = ntohs(cmap_idDelta[j]);
1104          ro = ntohs(cmap_idRangeOffset[j]);
1105  
1106          for (k = start; k <= end; k++) {
1107              if (ro == 0) {
1108                  n = k + delta;
1109              } else {
1110                  n = ntohs(*((ro >> 1) + (k - start) +
1111                   &(cmap_idRangeOffset[j])));
1112                  if (delta != 0)
1113                  {
1114                      /*  Not exactly sure how to deal with this circumstance,
1115                          I suspect it never occurs */
1116                      n += delta;
1117                      fprintf (stderr,
1118                           "rangeoffset and delta both non-zero - %d/%d",
1119                           ro, delta);
1120                  }
1121              }
1122              if(n<0 || n>=ttf_nglyphs) {
1123                  WARNING_1 fprintf(stderr, "Font contains a broken glyph code mapping, ignored\n");
1124                  continue;
1125              }
1126              if (glyph_list[n].orig_code != -1) {
1127  #if 0
1128                  if (strcmp(glyph_list[n].name, ".notdef") != 0) {
1129                      WARNING_2 fprintf(stderr,
1130                          "Glyph %s has >= two encodings (A), %4.4x & %4.4x\n",
1131                       glyph_list[n].name,
1132                          glyph_list[n].orig_code,
1133                          k);
1134                  }
1135  #endif
1136                  set_ok = 0;
1137              } else {
1138                  set_ok = 1;
1139              }
1140              if (enc_type==1 || forcemap) {
1141                  kk = unicode_rev_lookup(k);
1142                  if(ISDBG(UNICODE))
1143                      fprintf(stderr, "Unicode %s - 0x%04x\n",glyph_list[n].name,k);
1144                  if (set_ok) {
1145                      glyph_list[n].orig_code = k;
1146                      /* glyph_list[n].char_no = kk; */
1147                  }
1148                  if (kk >= 0 && kk < ENCTABSZ && encoding[kk] == -1)
1149                      encoding[kk] = n;
1150              } else {
1151                  if ((k & 0xff00) == 0xf000) {
1152                      if( encoding[k & 0x00ff] == -1 ) {
1153                          encoding[k & 0x00ff] = n;
1154                          if (set_ok) {
1155                              /* glyph_list[n].char_no = k & 0x00ff; */
1156                              glyph_list[n].orig_code = k;
1157                          }
1158                      }
1159                  } else {
1160                      if (set_ok) {
1161                          /* glyph_list[n].char_no = k; */
1162                          glyph_list[n].orig_code = k;
1163                      }
1164                      WARNING_2 fprintf(stderr,
1165                          "Glyph %s has non-symbol encoding %4.4x\n",
1166                       glyph_list[n].name,
1167                          k & 0xffff);
1168                      /*
1169                       * just use the code
1170                       * as it is
1171                       */
1172                      if ((k & ~0xff) == 0 && encoding[k] == -1 )
1173                          encoding[k] = n;
1174                  }
1175              }
1176          }
1177      }
1178  }
1179  
1180  static void
1181  handle_mac_encoding(
1182      GLYPH *glyph_list,
1183      int *encoding,
1184      int *unimap
1185  )
1186  {
1187      short           n;
1188      int             j, size;
1189  
1190      size = ntohs(encoding0->length) - 6;
1191      for (j = 0; j < size; j++) {
1192          n = encoding0->glyphIdArray[j];
1193          if (glyph_list[n].char_no != -1) {
1194              WARNING_2 fprintf(stderr,
1195                  "Glyph %s has >= two encodings (B), %4.4x & %4.4x\n",
1196                  glyph_list[n].name,
1197                    glyph_list[n].char_no,
1198                  j);
1199          } else {
1200              if (j < ENCTABSZ) {
1201                  if(encoding[j] == -1) {
1202                      glyph_list[n].char_no = j;
1203                      encoding[j] = n;
1204                  }
1205              }
1206          }
1207      }
1208  }
1209  
1210  /*
1211   * Get the original encoding of the font. 
1212   * Returns 1 for if the original encoding is Unicode, 2 if the
1213   * original encoding is other 16-bit, 0 if 8-bit.
1214   */
1215  
1216  static int
1217  glenc(
1218      GLYPH *glyph_list,
1219      int *encoding,
1220      int *unimap
1221  )
1222  {
1223      int             num_tables = ntohs(cmap_table->numberOfEncodingTables);
1224      BYTE           *ptr;
1225      int             i, format, offset, seg_c2, found;
1226      int             platform, encoding_id;
1227      TTF_CMAP_ENTRY *table_entry;
1228      TTF_CMAP_FMT4  *encoding4;
1229  
1230      if(enc_found_ms) {
1231          handle_ms_encoding(glyph_list, encoding, unimap);
1232          return enc_type;
1233      } else if(enc_found_mac) {
1234          handle_mac_encoding(glyph_list, encoding, unimap);
1235          return 0;
1236      }
1237  
1238      enc_type = 0;
1239      found = 0;
1240  
1241      for (i = 0; i < num_tables && !found; i++) {
1242          table_entry = &(cmap_table->encodingTable[i]);
1243          offset = ntohl(table_entry->offset);
1244          encoding4 = (TTF_CMAP_FMT4 *) ((BYTE *) cmap_table + offset);
1245          format = ntohs(encoding4->format);
1246          platform = ntohs(table_entry->platformID);
1247          encoding_id = ntohs(table_entry->encodingID);
1248  
1249          if (format != 4)
1250              continue;
1251  
1252          if(force_pid != -1) {
1253              if(force_pid != platform || encoding_id != force_eid)
1254                  continue;
1255              WARNING_1 fprintf(stderr, "Found Encoding PID=%d/EID=%d\n", 
1256                  force_pid, force_eid);
1257              enc_type = 1;
1258          } else {
1259              if (platform == 3 ) {
1260                  switch (encoding_id) {
1261                  case 0:
1262                      WARNING_1 fputs("Found Symbol Encoding\n", stderr);
1263                      break;
1264                  case 1:
1265                      WARNING_1 fputs("Found Unicode Encoding\n", stderr);
1266                      enc_type = 1;
1267                      break;
1268                  default:
1269                      WARNING_1 {
1270                          fprintf(stderr,
1271                          "****MS Encoding ID %d not supported****\n",
1272                              encoding_id);
1273                          fputs("Treating it like Symbol encoding\n", stderr);
1274                      }
1275                      break;
1276                  }
1277              } else
1278                  continue;
1279          }
1280  
1281          found = 1;
1282          seg_c2 = ntohs(encoding4->segCountX2);
1283          cmap_n_segs = seg_c2 >> 1;
1284          ptr = (BYTE *) encoding4 + 14;
1285          cmap_seg_end = (USHORT *) ptr;
1286          cmap_seg_start = (USHORT *) (ptr + seg_c2 + 2);
1287          cmap_idDelta = (short *) (ptr + (seg_c2 * 2) + 2);
1288          cmap_idRangeOffset = (short *) (ptr + (seg_c2 * 3) + 2);
1289          enc_found_ms = 1;
1290  
1291          handle_ms_encoding(glyph_list, encoding, unimap);
1292      }
1293  
1294      if (!found && force_pid == -1) {
1295          WARNING_1 fputs("No Microsoft encoding, looking for MAC encoding\n", stderr);
1296          for (i = 0; i < num_tables && !found; i++) {
1297              table_entry = &(cmap_table->encodingTable[i]);
1298              offset = ntohl(table_entry->offset);
1299              encoding0 = (TTF_CMAP_FMT0 *) ((BYTE *) cmap_table + offset);
1300              format = ntohs(encoding0->format);
1301              platform = ntohs(table_entry->platformID);
1302              encoding_id = ntohs(table_entry->encodingID);
1303  
1304              if (format == 0) {
1305                  found = 1;
1306                  enc_found_mac = 1;
1307  
1308                  handle_mac_encoding(glyph_list, encoding, unimap);
1309              }
1310          }
1311      }
1312  
1313      if (!found && force_pid == -1) {
1314          WARNING_1 fputs("No MAC encoding either, looking for any format 4 encoding\n", stderr);
1315          for (i = 0; i < num_tables && !found; i++) {
1316              table_entry = &(cmap_table->encodingTable[i]);
1317              offset = ntohl(table_entry->offset);
1318              encoding4 = (TTF_CMAP_FMT4 *) ((BYTE *) cmap_table + offset);
1319              format = ntohs(encoding4->format);
1320              platform = ntohs(table_entry->platformID);
1321              encoding_id = ntohs(table_entry->encodingID);
1322  
1323              if (format != 4)
1324                  continue;
1325  
1326              WARNING_1 fprintf(stderr, "Found a last ditch encoding PID=%d/EID=%d, treating it as Unicode.\n", 
1327                  platform, encoding_id);
1328              found = 1;
1329              enc_type = 1;
1330              seg_c2 = ntohs(encoding4->segCountX2);
1331              cmap_n_segs = seg_c2 >> 1;
1332              ptr = (BYTE *) encoding4 + 14;
1333              cmap_seg_end = (USHORT *) ptr;
1334              cmap_seg_start = (USHORT *) (ptr + seg_c2 + 2);
1335              cmap_idDelta = (short *) (ptr + (seg_c2 * 2) + 2);
1336              cmap_idRangeOffset = (short *) (ptr + (seg_c2 * 3) + 2);
1337              enc_found_ms = 1;
1338  
1339              handle_ms_encoding(glyph_list, encoding, unimap);
1340          
1341          }
1342      }
1343  
1344      if (!found) {
1345          if(force_pid != -1) {
1346              fprintf(stderr, "*** TTF encoding table PID=%d/EID=%d not found\n", 
1347                  force_pid, force_eid);
1348          }
1349          fprintf(stderr, "**** No Recognised Encoding Table ****\n");
1350          if(warnlevel >= 2) {
1351              fprintf(stderr, "Font contains the following unsupported encoding tables:\n");
1352              for (i = 0; i < num_tables && !found; i++) {
1353                  table_entry = &(cmap_table->encodingTable[i]);
1354                  offset = ntohl(table_entry->offset);
1355                  encoding0 = (TTF_CMAP_FMT0 *) ((BYTE *) cmap_table + offset);
1356                  format = ntohs(encoding0->format);
1357                  platform = ntohs(table_entry->platformID);
1358                  encoding_id = ntohs(table_entry->encodingID);
1359  
1360                  fprintf(stderr, "  format=%d platform=%d encoding_id=%d\n",
1361                      format, platform, encoding_id);
1362              }
1363          }
1364          exit(1);
1365      }
1366  
1367      return enc_type;
1368  }
1369  
1370  /*
1371   * Get the font metrics
1372   */
1373  static void 
1374  fnmetrics(
1375      struct font_metrics *fm
1376  )
1377  {
1378      char *str;
1379      static int fieldstocheck[]= {2,4,6};
1380      int i, j, len;
1381  
1382      fm->italic_angle = (short) (ntohs(post_table->italicAngle.upper)) +
1383          ((short) ntohs(post_table->italicAngle.lower) / 65536.0);
1384      fm->underline_position = (short) ntohs(post_table->underlinePosition);
1385      fm->underline_thickness = (short) ntohs(post_table->underlineThickness);
1386      fm->is_fixed_pitch = ntohl(post_table->isFixedPitch);
1387  
1388      fm->ascender = (short)ntohs(hhea_table->ascender);
1389      fm->descender = (short)ntohs(hhea_table->descender);
1390  
1391      fm->units_per_em =  ntohs(head_table->unitsPerEm);
1392  
1393      fm->bbox[0] = (short) ntohs(head_table->xMin);
1394      fm->bbox[1] = (short) ntohs(head_table->yMin);
1395      fm->bbox[2] = (short) ntohs(head_table->xMax);
1396      fm->bbox[3] = (short) ntohs(head_table->yMax);
1397  
1398      fm->name_copyright = name_fields[0];
1399      fm->name_family = name_fields[1];
1400      fm->name_style = name_fields[2];
1401      fm->name_full = name_fields[4];
1402      fm->name_version = name_fields[5];
1403      fm->name_ps = name_fields[6];
1404  
1405      /* guess the boldness from the font names */
1406      fm->force_bold=0;
1407  
1408      for(i=0; !fm->force_bold && i<sizeof fieldstocheck /sizeof(int); i++) {
1409          str = name_fields[fieldstocheck[i]];
1410          len = strlen(str);
1411          for(j=0; j<len; j++) {
1412              if( (str[j]=='B'
1413                  || str[j]=='b' 
1414                      && ( j==0 || !isalpha(str[j-1]) )
1415                  )
1416              && !strncmp("old",&str[j+1],3)
1417              && (j+4 >= len || !islower(str[j+4]))
1418              ) {
1419                  fm->force_bold=1;
1420                  break;
1421              }
1422          }
1423      }
1424  }
1425  
1426  /*
1427   * Get the path of contrours for a glyph.
1428   */
1429  
1430  static void
1431  glpath(
1432      int glyphno,
1433      GLYPH *glyf_list
1434  )
1435  {
1436      double          matrix[6];
1437      GLYPH          *g;
1438  
1439      g = &glyph_list[glyphno];
1440  
1441      matrix[0] = matrix[3] = 1.0;
1442      matrix[1] = matrix[2] = matrix[4] = matrix[5] = 0.0;
1443      draw_composite_glyf(g, glyf_list, glyphno, matrix, 0 /*level*/);
1444  }
1445  
1446  /*
1447   * Get the kerning data.
1448   */
1449  
1450  static void
1451  kerning(
1452      GLYPH *glyph_list
1453  )
1454  {
1455      TTF_KERN_SUB   *subtable;
1456      TTF_KERN_ENTRY *kern_entry;
1457      int             i, j;
1458      int             ntables;
1459      int             npairs;
1460      char           *ptr;
1461  
1462      if(kern_table == NULL) {
1463          WARNING_1 fputs("No Kerning data\n", stderr);
1464          return;
1465      }
1466      if(badpointer(kern_table)) {
1467          fputs("**** Defective Kerning table, ignored\n", stderr);
1468          return;
1469      }
1470  
1471      ntables = ntohs(kern_table->nTables);
1472      ptr = (char *) kern_table + 4;
1473  
1474      for (i = 0; i < ntables; i++) {
1475          subtable = (TTF_KERN_SUB *) ptr;
1476          if ((ntohs(subtable->coverage) & 0xff00) == 0) {
1477              npairs = (short) ntohs(subtable->nPairs);
1478              kern_entry = (TTF_KERN_ENTRY *) (ptr + sizeof(TTF_KERN_SUB));
1479  
1480              kern_entry = (TTF_KERN_ENTRY *) (ptr + sizeof(TTF_KERN_SUB));
1481              for (j = 0; j < npairs; j++) {
1482                  if( kern_entry->value != 0)
1483                      addkernpair(ntohs(kern_entry->left), 
1484                          ntohs(kern_entry->right), (short)ntohs(kern_entry->value));
1485                  kern_entry++;
1486              }
1487          }
1488          ptr += subtable->length;
1489      }
1490  }
1491  


Generated: Fri Nov 28 20:08:37 2014 Cross-referenced by PHPXref 0.7.1