gfxfont.cc

来自「source code: Covert TXT to PDF」· CC 代码 · 共 1,305 行 · 第 1/3 页

CC
1,305
字号
    fontBBox[0] = 0.001 * builtinFont->bbox[0];    fontBBox[1] = 0.001 * builtinFont->bbox[1];    fontBBox[2] = 0.001 * builtinFont->bbox[2];    fontBBox[3] = 0.001 * builtinFont->bbox[3];  } else {    ascent = 0.95;    descent = -0.35;    fontBBox[0] = fontBBox[1] = fontBBox[2] = fontBBox[3] = 0;  }  // get info from font descriptor  readFontDescriptor(xref, fontDict);  // look for an external font file  findExtFontFile();  // get font matrix  fontMat[0] = fontMat[3] = 1;  fontMat[1] = fontMat[2] = fontMat[4] = fontMat[5] = 0;  if (fontDict->lookup("FontMatrix", &obj1)->isArray()) {    for (i = 0; i < 6 && i < obj1.arrayGetLength(); ++i) {      if (obj1.arrayGet(i, &obj2)->isNum()) {	fontMat[i] = obj2.getNum();      }      obj2.free();    }  }  obj1.free();  // get Type 3 bounding box, font definition, and resources  if (type == fontType3) {    if (fontDict->lookup("FontBBox", &obj1)->isArray()) {      for (i = 0; i < 4 && i < obj1.arrayGetLength(); ++i) {	if (obj1.arrayGet(i, &obj2)->isNum()) {	  fontBBox[i] = obj2.getNum();	}	obj2.free();      }    }    obj1.free();    if (!fontDict->lookup("CharProcs", &charProcs)->isDict()) {      error(-1, "Missing or invalid CharProcs dictionary in Type 3 font");      charProcs.free();    }    if (!fontDict->lookup("Resources", &resources)->isDict()) {      resources.free();    }  }  //----- build the font encoding -----  // Encodings start with a base encoding, which can come from  // (in order of priority):  //   1. FontDict.Encoding or FontDict.Encoding.BaseEncoding  //        - MacRoman / MacExpert / WinAnsi / Standard  //   2. embedded or external font file  //   3. default:  //        - builtin --> builtin encoding  //        - TrueType --> MacRomanEncoding  //        - others --> StandardEncoding  // and then add a list of differences (if any) from  // FontDict.Encoding.Differences.  // check FontDict for base encoding  hasEncoding = gFalse;  baseEnc = NULL;  baseEncFromFontFile = gFalse;  fontDict->lookup("Encoding", &obj1);  if (obj1.isDict()) {    obj1.dictLookup("BaseEncoding", &obj2);    if (obj2.isName("MacRomanEncoding")) {      hasEncoding = gTrue;      baseEnc = macRomanEncoding;    } else if (obj2.isName("MacExpertEncoding")) {      hasEncoding = gTrue;      baseEnc = macExpertEncoding;    } else if (obj2.isName("WinAnsiEncoding")) {      hasEncoding = gTrue;      baseEnc = winAnsiEncoding;    } else if (obj2.isName("StandardEncoding")) {      hasEncoding = gTrue;      baseEnc = standardEncoding;    }    obj2.free();  } else if (obj1.isName("MacRomanEncoding")) {    hasEncoding = gTrue;    baseEnc = macRomanEncoding;  } else if (obj1.isName("MacExpertEncoding")) {    hasEncoding = gTrue;    baseEnc = macExpertEncoding;  } else if (obj1.isName("WinAnsiEncoding")) {    hasEncoding = gTrue;    baseEnc = winAnsiEncoding;  } else if (obj1.isName("StandardEncoding")) {    hasEncoding = gTrue;    baseEnc = standardEncoding;  }  // check embedded or external font file for base encoding  // (only for Type 1 fonts - trying to get an encoding out of a  // TrueType font is a losing proposition)  fontFile = NULL;  buf = NULL;  if ((type == fontType1 || type == fontType1C) &&      (extFontFile || embFontID.num >= 0)) {    if (extFontFile) {      buf = readExtFontFile(&len);    } else {      buf = readEmbFontFile(xref, &len);    }    if (buf) {      if (type == fontType1C && !strncmp(buf, "%!", 2)) {	// various tools (including Adobe's) occasionally embed Type 1	// fonts but label them Type 1C	type = fontType1;      }      if (type == fontType1) {	fontFile = new Type1FontFile(buf, len);      } else {	fontFile = new Type1CFontFile(buf, len);      }      if (fontFile->getName()) {	if (embFontName) {	  delete embFontName;	}	embFontName = new GString(fontFile->getName());      }      if (!baseEnc) {	baseEnc = fontFile->getEncoding();	baseEncFromFontFile = gTrue;      }      gfree(buf);    }  }  // get default base encoding  if (!baseEnc) {    if (builtinFont) {      baseEnc = builtinFont->defaultBaseEnc;      hasEncoding = gTrue;    } else if (type == fontTrueType) {      baseEnc = winAnsiEncoding;    } else {      baseEnc = standardEncoding;    }  }  // copy the base encoding  for (i = 0; i < 256; ++i) {    enc[i] = baseEnc[i];    if ((encFree[i] = baseEncFromFontFile) && enc[i]) {      enc[i] = copyString(baseEnc[i]);    }  }  // merge differences into encoding  if (obj1.isDict()) {    obj1.dictLookup("Differences", &obj2);    if (obj2.isArray()) {      hasEncoding = gTrue;      code = 0;      for (i = 0; i < obj2.arrayGetLength(); ++i) {	obj2.arrayGet(i, &obj3);	if (obj3.isInt()) {	  code = obj3.getInt();	} else if (obj3.isName()) {	  if (code < 256) {	    if (encFree[code]) {	      gfree(enc[code]);	    }	    enc[code] = copyString(obj3.getName());	    encFree[code] = gTrue;	  }	  ++code;	} else {	  error(-1, "Wrong type in font encoding resource differences (%s)",		obj3.getTypeName());	}	obj3.free();      }    }    obj2.free();  }  obj1.free();  if (fontFile) {    delete fontFile;  }  //----- build the mapping to Unicode -----  // look for a ToUnicode CMap  if (!(ctu = readToUnicodeCMap(fontDict, 8))) {    // no ToUnicode CMap, so use the char names    // pass 1: use the name-to-Unicode mapping table    missing = hex = gFalse;    for (code = 0; code < 256; ++code) {      if ((charName = enc[code])) {	if (!(toUnicode[code] = globalParams->mapNameToUnicode(charName)) &&	    strcmp(charName, ".notdef")) {	  // if it wasn't in the name-to-Unicode table, check for a	  // name that looks like 'Axx' or 'xx', where 'A' is any letter	  // and 'xx' is two hex digits	  if ((strlen(charName) == 3 &&	       isalpha(charName[0]) &&	       isxdigit(charName[1]) && isxdigit(charName[2]) &&	       ((charName[1] >= 'a' && charName[1] <= 'f') ||		(charName[1] >= 'A' && charName[1] <= 'F') ||		(charName[2] >= 'a' && charName[2] <= 'f') ||		(charName[2] >= 'A' && charName[2] <= 'F'))) ||	      (strlen(charName) == 2 &&	       isxdigit(charName[0]) && isxdigit(charName[1]) &&	       ((charName[0] >= 'a' && charName[0] <= 'f') ||		(charName[0] >= 'A' && charName[0] <= 'F') ||		(charName[1] >= 'a' && charName[1] <= 'f') ||		(charName[1] >= 'A' && charName[1] <= 'F')))) {	    hex = gTrue;	  }	  missing = gTrue;	}      } else {	toUnicode[code] = 0;      }    }    // pass 2: try to fill in the missing chars, looking for names of    // the form 'Axx', 'xx', 'Ann', 'ABnn', or 'nn', where 'A' and 'B'    // are any letters, 'xx' is two hex digits, and 'nn' is 2-4    // decimal digits    if (missing && globalParams->getMapNumericCharNames()) {      for (code = 0; code < 256; ++code) {	if ((charName = enc[code]) && !toUnicode[code] &&	    strcmp(charName, ".notdef")) {	  n = strlen(charName);	  code2 = -1;	  if (hex && n == 3 && isalpha(charName[0]) &&	      isxdigit(charName[1]) && isxdigit(charName[2])) {	    sscanf(charName+1, "%x", &code2);	  } else if (hex && n == 2 &&		     isxdigit(charName[0]) && isxdigit(charName[1])) {	    sscanf(charName, "%x", &code2);	  } else if (!hex && n >= 2 && n <= 4 &&		     isdigit(charName[0]) && isdigit(charName[1])) {	    code2 = atoi(charName);	  } else if (n >= 3 && n <= 5 &&		     isdigit(charName[1]) && isdigit(charName[2])) {	    code2 = atoi(charName+1);	  } else if (n >= 4 && n <= 6 &&		     isdigit(charName[2]) && isdigit(charName[3])) {	    code2 = atoi(charName+2);	  }	  if (code2 >= 0 && code2 <= 0xff) {	    toUnicode[code] = (Unicode)code2;	  }	}      }    }    ctu = CharCodeToUnicode::make8BitToUnicode(toUnicode);  }  //----- get the character widths -----  // initialize all widths  for (code = 0; code < 256; ++code) {    widths[code] = missingWidth * 0.001;  }  // use widths from font dict, if present  fontDict->lookup("FirstChar", &obj1);  firstChar = obj1.isInt() ? obj1.getInt() : 0;  obj1.free();  fontDict->lookup("LastChar", &obj1);  lastChar = obj1.isInt() ? obj1.getInt() : 255;  obj1.free();  mul = (type == fontType3) ? fontMat[0] : 0.001;  fontDict->lookup("Widths", &obj1);  if (obj1.isArray()) {    flags |= fontFixedWidth;    for (code = firstChar; code <= lastChar; ++code) {      obj1.arrayGet(code - firstChar, &obj2);      if (obj2.isNum()) {	widths[code] = obj2.getNum() * mul;	if (widths[code] != widths[firstChar]) {	  flags &= ~fontFixedWidth;	}      }      obj2.free();    }  // use widths from built-in font  } else if (builtinFont) {    // this is a kludge for broken PDF files that encode char 32    // as .notdef    if (builtinFont->widths->getWidth("space", &w)) {      widths[32] = 0.001 * w;    }    for (code = 0; code < 256; ++code) {      if (enc[code] && builtinFont->widths->getWidth(enc[code], &w)) {	widths[code] = 0.001 * w;      }    }  // couldn't find widths -- use defaults   } else {    // this is technically an error -- the Widths entry is required    // for all but the Base-14 fonts -- but certain PDF generators    // apparently don't include widths for Arial and TimesNewRoman    if (isFixedWidth()) {      i = 0;    } else if (isSerif()) {      i = 8;    } else {      i = 4;    }    if (isBold()) {      i += 2;    }    if (isItalic()) {      i += 1;    }    builtinFont = builtinFontSubst[i];    // this is a kludge for broken PDF files that encode char 32    // as .notdef    if (builtinFont->widths->getWidth("space", &w)) {      widths[32] = 0.001 * w;    }    for (code = 0; code < 256; ++code) {      if (enc[code] && builtinFont->widths->getWidth(enc[code], &w)) {	widths[code] = 0.001 * w;      }    }  }  obj1.free();  ok = gTrue;}Gfx8BitFont::~Gfx8BitFont() {  int i;  for (i = 0; i < 256; ++i) {    if (encFree[i] && enc[i]) {      gfree(enc[i]);    }  }  ctu->decRefCnt();  if (charProcs.isDict()) {    charProcs.free();  }  if (resources.isDict()) {    resources.free();  }}int Gfx8BitFont::getNextChar(char *s, int len, CharCode *code,			     Unicode *u, int uSize, int *uLen,			     double *dx, double *dy, double *ox, double *oy) {  CharCode c;  *code = c = (CharCode)(*s & 0xff);  *uLen = ctu->mapToUnicode(c, u, uSize);  *dx = widths[c];  *dy = *ox = *oy = 0;  return 1;}CharCodeToUnicode *Gfx8BitFont::getToUnicode() {  ctu->incRefCnt();  return ctu;}Dict *Gfx8BitFont::getCharProcs() {  return charProcs.isDict() ? charProcs.getDict() : (Dict *)NULL;}Object *Gfx8BitFont::getCharProc(int code, Object *proc) {  if (charProcs.isDict()) {    charProcs.dictLookup(enc[code], proc);  } else {    proc->initNull();  }  return proc;}Dict *Gfx8BitFont::getResources() {  return resources.isDict() ? resources.getDict() : (Dict *)NULL;}//------------------------------------------------------------------------// GfxCIDFont//------------------------------------------------------------------------static int cmpWidthExcep(const void *w1, const void *w2) {  return ((GfxFontCIDWidthExcep *)w1)->first -         ((GfxFontCIDWidthExcep *)w2)->first;}static int cmpWidthExcepV(const void *w1, const void *w2) {  return ((GfxFontCIDWidthExcepV *)w1)->first -         ((GfxFontCIDWidthExcepV *)w2)->first;}GfxCIDFont::GfxCIDFont(XRef *xref, char *tagA, Ref idA, GString *nameA,		       Dict *fontDict):  GfxFont(tagA, idA, nameA){  Dict *desFontDict;  GString *collection, *cMapName;  Object desFontDictObj;  Object obj1, obj2, obj3, obj4, obj5, obj6;  int c1, c2;  int excepsSize, i, j, k;  ascent = 0.95;  descent = -0.35;  fontBBox[0] = fontBBox[1] = fontBBox[2] = fontBBox[3] = 0;  cMap = NULL;  ctu = NULL;  widths.defWidth = 1.0;  widths.defHeight = -1.0;  widths.defVY = 0.880;  widths.exceps = NULL;  widths.nExceps = 0;  widths.excepsV = NULL;  widths.nExcepsV = 0;  cidToGID = NULL;  cidToGIDLen = 0;  // get the descendant font  if (!fontDict->lookup("DescendantFonts", &obj1)->isArray()) {    error(-1, "Missing DescendantFonts entry in Type 0 font");    obj1.free();    goto err1;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?