⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gfxfont.cc

📁 这是一个做pdf阅读器的源代码文件,是大家学习阅读器资料的很好参考
💻 CC
📖 第 1 页 / 共 3 页
字号:
	}	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 --> WinAnsiEncoding  //        - others --> StandardEncoding  // and then add a list of differences (if any) from  // FontDict.Encoding.Differences.  // check FontDict for base encoding  hasEncoding = gFalse;  usesMacRomanEnc = gFalse;  baseEnc = NULL;  baseEncFromFontFile = gFalse;  fontDict->lookup("Encoding", &obj1);  if (obj1.isDict()) {    obj1.dictLookup("BaseEncoding", &obj2);    if (obj2.isName("MacRomanEncoding")) {      hasEncoding = gTrue;      usesMacRomanEnc = gTrue;      baseEnc = macRomanEncoding;    } else if (obj2.isName("MacExpertEncoding")) {      hasEncoding = gTrue;      baseEnc = macExpertEncoding;    } else if (obj2.isName("WinAnsiEncoding")) {      hasEncoding = gTrue;      baseEnc = winAnsiEncoding;    }    obj2.free();  } else if (obj1.isName("MacRomanEncoding")) {    hasEncoding = gTrue;    usesMacRomanEnc = gTrue;    baseEnc = macRomanEncoding;  } else if (obj1.isName("MacExpertEncoding")) {    hasEncoding = gTrue;    baseEnc = macExpertEncoding;  } else if (obj1.isName("WinAnsiEncoding")) {    hasEncoding = gTrue;    baseEnc = winAnsiEncoding;  }  // 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)  ffT1 = NULL;  ffT1C = NULL;  buf = NULL;  if (type == fontType1 && (extFontFile || embFontID.num >= 0)) {    if (extFontFile) {      ffT1 = FoFiType1::load(extFontFile->getCString());    } else {      buf = readEmbFontFile(xref, &len);      ffT1 = FoFiType1::make(buf, len);    }    if (ffT1) {      if (ffT1->getName()) {	if (embFontName) {	  delete embFontName;	}	embFontName = new GString(ffT1->getName());      }      if (!baseEnc) {	baseEnc = ffT1->getEncoding();	baseEncFromFontFile = gTrue;      }    }  } else if (type == fontType1C && (extFontFile || embFontID.num >= 0)) {    if (extFontFile) {      ffT1C = FoFiType1C::load(extFontFile->getCString());    } else {      buf = readEmbFontFile(xref, &len);      ffT1C = FoFiType1C::make(buf, len);    }    if (ffT1C) {      if (ffT1C->getName()) {	if (embFontName) {	  delete embFontName;	}	embFontName = new GString(ffT1C->getName());      }      if (!baseEnc) {	baseEnc = ffT1C->getEncoding();	baseEncFromFontFile = gTrue;      }    }  }  if (buf) {    gfree(buf);  }  // get default base encoding  if (!baseEnc) {    if (builtinFont && embFontID.num < 0) {      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]);    }  }  // some Type 1C font files have empty encodings, which can break the  // T1C->T1 conversion (since the 'seac' operator depends on having  // the accents in the encoding), so we fill in any gaps from  // StandardEncoding  if (type == fontType1C && (extFontFile || embFontID.num >= 0) &&      baseEncFromFontFile) {    for (i = 0; i < 256; ++i) {      if (!enc[i] && standardEncoding[i]) {	enc[i] = standardEncoding[i];	encFree[i] = gFalse;      }    }  }  // 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 >= 0 && 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 (ffT1) {    delete ffT1;  }  if (ffT1C) {    delete ffT1C;  }  //----- build the mapping to Unicode -----  // 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;	}      }    }  // if the 'mapUnknownCharNames' flag is set, do a simple pass-through  // mapping for unknown character names  } else if (missing && globalParams->getMapUnknownCharNames()) {    for (code = 0; code < 256; ++code) {      if (!toUnicode[code]) {	toUnicode[code] = code;      }    }  }  // construct the char code -> Unicode mapping object  ctu = CharCodeToUnicode::make8BitToUnicode(toUnicode);  // merge in a ToUnicode CMap, if there is one -- this overwrites  // existing entries in ctu, i.e., the ToUnicode CMap takes  // precedence, but the other encoding info is allowed to fill in any  // holes  readToUnicodeCMap(fontDict, 8, ctu);  // look for a Unicode-to-Unicode mapping  if (name && (utu = globalParams->getUnicodeToUnicode(name))) {    for (i = 0; i < 256; ++i) {      toUnicode[i] = 0;    }    ctu2 = CharCodeToUnicode::make8BitToUnicode(toUnicode);    for (i = 0; i < 256; ++i) {      n = ctu->mapToUnicode((CharCode)i, uBuf, 8);      if (n >= 1) {	n = utu->mapToUnicode((CharCode)uBuf[0], uBuf, 8);	if (n >= 1) {	  ctu2->setMapping((CharCode)i, uBuf, n);	}      }    }    utu->decRefCnt();    delete ctu;    ctu = ctu2;  }  //----- 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();  if (firstChar < 0 || firstChar > 255) {    firstChar = 0;  }  fontDict->lookup("LastChar", &obj1);  lastChar = obj1.isInt() ? obj1.getInt() : 255;  obj1.free();  if (lastChar < 0 || lastChar > 255) {    lastChar = 255;  }  mul = (type == fontType3) ? fontMat[0] : 0.001;  fontDict->lookup("Widths", &obj1);  if (obj1.isArray()) {    flags |= fontFixedWidth;    if (obj1.arrayGetLength() < lastChar - firstChar + 1) {      lastChar = firstChar + obj1.arrayGetLength() - 1;    }    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;}Gushort *Gfx8BitFont::getCodeToGIDMap(FoFiTrueType *ff) {  Gushort *map;  int cmapPlatform, cmapEncoding;  int unicodeCmap, macRomanCmap, msSymbolCmap, cmap;  GBool useMacRoman, useUnicode;  char *charName;  Unicode u;  int code, i, n;  map = (Gushort *)gmallocn(256, sizeof(Gushort));  for (i = 0; i < 256; ++i) {    map[i] = 0;  }  // To match up with the Adobe-defined behaviour, we choose a cmap  // like this:  // 1. If the PDF font has an encoding:  //    1a. If the PDF font specified MacRomanEncoding and the  //        TrueType font has a Macintosh Roman cmap, use it, and  //        reverse map the char names through MacRomanEncoding to  //        get char codes.  //    1b. If the TrueType font has a Microsoft Unicode cmap or a  //        non-Microsoft Unicode cmap, use it, and use the Unicode  //        indexes, not the char codes.  //    1c. If the PDF font is symbolic and the TrueType font has a  //        Microsoft Symbol cmap, use it, and use char codes  //        directly (possibly with an offset of 0xf000).  //    1d. If the TrueType font has a Macintosh Roman cmap, use it,  //        as in case 1a.  // 2. If the PDF font does not have an encoding or the PDF font is  //    symbolic:  //    2a. If the TrueType font has a Macintosh Roman cmap, use it,  //        and use char codes directly (possibly with an offset of  //        0xf000).  //    2b. If the TrueType font has a Microsoft Symbol cmap, use it,  //        and use char codes directly (possible with an offset of  //        0xf000).  // 3. If none of these rules apply, use the first cmap and hope for  //    the best (this shouldn't happen).  unicodeCmap = macRomanCmap = msSymbolCmap = -1;  for (i = 0; i < ff->getNumCmaps(); ++i) {    cmapPlatform = ff->getCmapPlatform(i);    cmapEncoding = ff->getCmapEncoding(i);    if ((cmapPlatform == 3 && cmapEncoding == 1) ||	cmapPlatform == 0) {      unicodeCmap = i;    } else if (cmapPlatform == 1 && cmapEncoding == 0) {      macRomanCmap = i;    } else if (cmapPlatform == 3 && cmapEncoding == 0) {      msSymbolCmap = i;    }  }  cmap = 0;  useMacRoman = gFalse;  useUnicode = gFalse;  if (hasEncoding) {    if (usesMacRomanEnc && macRomanCmap >= 0) {      cmap = macRomanCmap;      useMacRoman = gTrue;    } else if (unicodeCmap >= 0) {      cmap = unicodeCmap;      useUnicode = gTrue;    } else if ((flags & fontSymbolic) && msSymbolCmap >= 0) {      cmap = msSymbolCmap;    } else if ((flags & fontSymbolic) && macRomanCmap >= 0) {      cmap = macRomanCmap;    } else if (macRomanCmap >= 0) {      cmap = macRomanCmap;      useMacRoman = gTrue;    }  } else {    if (msSymbolCmap >= 0) {      cmap = msSymbolCmap;    } else if (macRomanCmap >= 0) {      cmap = macRomanCmap;    }  }  // reverse map the char names through MacRomanEncoding, then map the  // char codes through the cmap  if (useMacRoman) {    for (i = 0; i < 256; ++i) {      if ((charName = enc[i])) {	if ((code = globalParams->getMacRomanCharCode(charName))) {	  map[i] = ff->mapCodeToGID(cmap, code);	}      }    }  // map Unicode through the cmap  } else if (useUnicode) {    for (i = 0; i < 256; ++i) {      if (((charName = enc[i]) &&	   (u = globalParams->mapNameToUnicode(charName))) ||	  (n = ctu->mapToUnicode((CharCode)i, &u, 1))) {	map[i] = ff->mapCodeToGID(cmap, u);      }    }  // map the char codes through the cmap, possibly with an offset of  // 0xf000  } else {    for (i = 0; i < 256; ++i) {      if (!(map[i] = ff->mapCodeToGID(cmap, i))) {	map[i] = ff->mapCodeToGID(cmap, 0xf000 + i);      }    }  }  // try the TrueType 'post' table to handle any unmapped characters  for (i = 0; i < 256; ++i) {    if (!map[i] && (charName = enc[i])) {      map[i] = (Gushort)(int)ff->mapNameToGID(charName);    }  }  return map;}Dict *Gfx8BitFont::getCharProcs() {

⌨️ 快捷键说明

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