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

📄 annot.cc

📁 这是一个做pdf阅读器的源代码文件,是大家学习阅读器资料的很好参考
💻 CC
📖 第 1 页 / 共 3 页
字号:
	quadding = fieldQuadLeft;      }      obj2.free();      comb = 0;      if (ff & fieldFlagComb) {	if (fieldLookup(field, "MaxLen", &obj2)->isInt()) {	  comb = obj2.getInt();	}	obj2.free();      }      drawText(obj1.getString(), da, fontDict,	       ff & fieldFlagMultiline, comb, quadding, gTrue, gFalse);    }    obj1.free();  } else if (ftObj.isName("Ch")) {    //~ value/option strings can be Unicode    if (fieldLookup(field, "Q", &obj1)->isInt()) {      quadding = obj1.getInt();    } else {      quadding = fieldQuadLeft;    }    obj1.free();    // combo box    if (ff & fieldFlagCombo) {      if (fieldLookup(field, "V", &obj1)->isString()) {	drawText(obj1.getString(), da, fontDict,		 gFalse, 0, quadding, gTrue, gFalse);	//~ Acrobat draws a popup icon on the right side      }      obj1.free();    // list box    } else {      if (field->lookup("Opt", &obj1)->isArray()) {	nOptions = obj1.arrayGetLength();	// get the option text	text = (GString **)gmallocn(nOptions, sizeof(GString *));	for (i = 0; i < nOptions; ++i) {	  text[i] = NULL;	  obj1.arrayGet(i, &obj2);	  if (obj2.isString()) {	    text[i] = obj2.getString()->copy();	  } else if (obj2.isArray() && obj2.arrayGetLength() == 2) {	    if (obj2.arrayGet(1, &obj3)->isString()) {	      text[i] = obj3.getString()->copy();	    }	    obj3.free();	  }	  obj2.free();	  if (!text[i]) {	    text[i] = new GString();	  }	}	// get the selected option(s)	selection = (GBool *)gmallocn(nOptions, sizeof(GBool));	//~ need to use the I field in addition to the V field	fieldLookup(field, "V", &obj2);	for (i = 0; i < nOptions; ++i) {	  selection[i] = gFalse;	  if (obj2.isString()) {	    if (!obj2.getString()->cmp(text[i])) {	      selection[i] = gTrue;	    }	  } else if (obj2.isArray()) {	    for (j = 0; j < obj2.arrayGetLength(); ++j) {	      if (obj2.arrayGet(j, &obj3)->isString() &&		  !obj3.getString()->cmp(text[i])) {		selection[i] = gTrue;	      }	      obj3.free();	    }	  }	}	obj2.free();	// get the top index	if (field->lookup("TI", &obj2)->isInt()) {	  topIdx = obj2.getInt();	} else {	  topIdx = 0;	}	obj2.free();	// draw the text	drawListBox(text, selection, nOptions, topIdx, da, fontDict, quadding);	for (i = 0; i < nOptions; ++i) {	  delete text[i];	}	gfree(text);	gfree(selection);      }      obj1.free();    }  } else if (ftObj.isName("Sig")) {    //~unimp  } else {    error(-1, "Unknown field type");  }  if (da) {    delete da;  }  // build the appearance stream dictionary  appearDict.initDict(xref);  appearDict.dictAdd(copyString("Length"),		     obj1.initInt(appearBuf->getLength()));  appearDict.dictAdd(copyString("Subtype"), obj1.initName("Form"));  obj1.initArray(xref);  obj1.arrayAdd(obj2.initReal(0));  obj1.arrayAdd(obj2.initReal(0));  obj1.arrayAdd(obj2.initReal(xMax - xMin));  obj1.arrayAdd(obj2.initReal(yMax - yMin));  appearDict.dictAdd(copyString("BBox"), &obj1);  // set the resource dictionary  if (drObj.isDict()) {    appearDict.dictAdd(copyString("Resources"), drObj.copy(&obj1));  }  drObj.free();  // build the appearance stream  appearStream = new MemStream(appearBuf->getCString(), 0,			       appearBuf->getLength(), &appearDict);  appearance.free();  appearance.initStream(appearStream);  if (fontDict) {    delete fontDict;  }  ftObj.free();  mkObj.free();}// Set the current fill or stroke color, based on <a> (which should// have 1, 3, or 4 elements).  If <adjust> is +1, color is brightened;// if <adjust> is -1, color is darkened; otherwise color is not// modified.void Annot::setColor(Array *a, GBool fill, int adjust) {  Object obj1;  double color[4];  int nComps, i;  nComps = a->getLength();  if (nComps > 4) {    nComps = 4;  }  for (i = 0; i < nComps && i < 4; ++i) {    if (a->get(i, &obj1)->isNum()) {      color[i] = obj1.getNum();    } else {      color[i] = 0;    }    obj1.free();  }  if (nComps == 4) {    adjust = -adjust;  }  if (adjust > 0) {    for (i = 0; i < nComps; ++i) {      color[i] = 0.5 * color[i] + 0.5;    }  } else if (adjust < 0) {    for (i = 0; i < nComps; ++i) {      color[i] = 0.5 * color[i];    }  }  if (nComps == 4) {    appearBuf->appendf("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:c}\n",		       color[0], color[1], color[2], color[3],		       fill ? 'k' : 'K');  } else if (nComps == 3) {    appearBuf->appendf("{0:.2f} {1:.2f} {2:.2f} {3:s}\n",		       color[0], color[1], color[2],		       fill ? "rg" : "RG");  } else {    appearBuf->appendf("{0:.2f} {1:c}\n",		       color[0],		       fill ? 'g' : 'G');  }}// Draw the variable text or caption for a field.void Annot::drawText(GString *text, GString *da, GfxFontDict *fontDict,		     GBool multiline, int comb, int quadding,		     GBool txField, GBool forceZapfDingbats) {  GList *daToks;  GString *tok;  GfxFont *font;  double fontSize, fontSize2, border, x, xPrev, y, w, w2, wMax;  int tfPos, tmPos, i, j, k, c;  //~ if there is no MK entry, this should use the existing content stream,  //~ and only replace the marked content portion of it  //~ (this is only relevant for Tx fields)  // parse the default appearance string  tfPos = tmPos = -1;  if (da) {    daToks = new GList();    i = 0;    while (i < da->getLength()) {      while (i < da->getLength() && Lexer::isSpace(da->getChar(i))) {	++i;      }      if (i < da->getLength()) {	for (j = i + 1;	     j < da->getLength() && !Lexer::isSpace(da->getChar(j));	     ++j) ;	daToks->append(new GString(da, i, j - i));	i = j;      }    }    for (i = 2; i < daToks->getLength(); ++i) {      if (i >= 2 && !((GString *)daToks->get(i))->cmp("Tf")) {	tfPos = i - 2;      } else if (i >= 6 && !((GString *)daToks->get(i))->cmp("Tm")) {	tmPos = i - 6;      }    }  } else {    daToks = NULL;  }  // force ZapfDingbats  //~ this should create the font if needed (?)  if (forceZapfDingbats) {    if (tfPos >= 0) {      tok = (GString *)daToks->get(tfPos);      if (tok->cmp("/ZaDb")) {	tok->clear();	tok->append("/ZaDb");      }    }  }  // get the font and font size  font = NULL;  fontSize = 0;  if (tfPos >= 0) {    tok = (GString *)daToks->get(tfPos);    if (tok->getLength() >= 1 && tok->getChar(0) == '/') {      if (!fontDict || !(font = fontDict->lookup(tok->getCString() + 1))) {	error(-1, "Unknown font in field's DA string");      }    } else {      error(-1, "Invalid font name in 'Tf' operator in field's DA string");    }    tok = (GString *)daToks->get(tfPos + 1);    fontSize = atof(tok->getCString());  } else {    error(-1, "Missing 'Tf' operator in field's DA string");  }  // get the border width  border = borderStyle->getWidth();  // setup  if (txField) {    appearBuf->append("/Tx BMC\n");  }  appearBuf->append("q\n");  appearBuf->append("BT\n");  // multi-line text  if (multiline) {    // note: the comb flag is ignored in multiline mode    wMax = xMax - xMin - 2 * border - 4;    // compute font autosize    if (fontSize == 0) {      for (fontSize = 20; fontSize > 1; --fontSize) {	y = yMax - yMin;	w2 = 0;	i = 0;	while (i < text->getLength()) {	  getNextLine(text, i, font, fontSize, wMax, &j, &w, &k);	  if (w > w2) {	    w2 = w;	  }	  i = k;	  y -= fontSize;	}	// approximate the descender for the last line	if (y >= 0.33 * fontSize) {	  break;	}      }      if (tfPos >= 0) {	tok = (GString *)daToks->get(tfPos + 1);	tok->clear();	tok->appendf("{0:.2f}", fontSize);      }    }    // starting y coordinate    // (note: each line of text starts with a Td operator that moves    // down a line)    y = yMax - yMin;    // set the font matrix    if (tmPos >= 0) {      tok = (GString *)daToks->get(tmPos + 4);      tok->clear();      tok->append('0');      tok = (GString *)daToks->get(tmPos + 5);      tok->clear();      tok->appendf("{0:.2f}", y);    }    // write the DA string    if (daToks) {      for (i = 0; i < daToks->getLength(); ++i) {	appearBuf->append((GString *)daToks->get(i))->append(' ');      }    }    // write the font matrix (if not part of the DA string)    if (tmPos < 0) {      appearBuf->appendf("1 0 0 1 0 {0:.2f} Tm\n", y);    }    // write a series of lines of text    i = 0;    xPrev = 0;    while (i < text->getLength()) {      getNextLine(text, i, font, fontSize, wMax, &j, &w, &k);      // compute text start position      switch (quadding) {      case fieldQuadLeft:      default:	x = border + 2;	break;      case fieldQuadCenter:	x = (xMax - xMin - w) / 2;	break;      case fieldQuadRight:	x = xMax - xMin - border - 2 - w;	break;      }      // draw the line      appearBuf->appendf("{0:.2f} {1:.2f} Td\n", x - xPrev, -fontSize);      appearBuf->append('(');      for (; i < j; ++i) {	c = text->getChar(i) & 0xff;	if (c == '(' || c == ')' || c == '\\') {	  appearBuf->append('\\');	  appearBuf->append(c);	} else if (c < 0x20 || c >= 0x80) {	  appearBuf->appendf("\\{0:03o}", c);	} else {	  appearBuf->append(c);	}      }      appearBuf->append(") Tj\n");      // next line      i = k;      xPrev = x;    }  // single-line text  } else {    //~ replace newlines with spaces? - what does Acrobat do?    // comb formatting    if (comb > 0) {      // compute comb spacing      w = (xMax - xMin - 2 * border) / comb;      // compute font autosize      if (fontSize == 0) {	fontSize = yMax - yMin - 2 * border;	if (w < fontSize) {	  fontSize = w;	}	fontSize = floor(fontSize);	if (tfPos >= 0) {	  tok = (GString *)daToks->get(tfPos + 1);	  tok->clear();	  tok->appendf("{0:.2f}", fontSize);	}      }      // compute text start position      switch (quadding) {      case fieldQuadLeft:      default:	x = border + 2;	break;      case fieldQuadCenter:	x = border + 2 + 0.5 * (comb - text->getLength()) * w;	break;      case fieldQuadRight:	x = border + 2 + (comb - text->getLength()) * w;	break;      }      y = 0.5 * (yMax - yMin) - 0.4 * fontSize;      // set the font matrix      if (tmPos >= 0) {	tok = (GString *)daToks->get(tmPos + 4);	tok->clear();	tok->appendf("{0:.2f}", x);	tok = (GString *)daToks->get(tmPos + 5);	tok->clear();	tok->appendf("{0:.2f}", y);      }      // write the DA string      if (daToks) {	for (i = 0; i < daToks->getLength(); ++i) {	  appearBuf->append((GString *)daToks->get(i))->append(' ');	}      }      // write the font matrix (if not part of the DA string)      if (tmPos < 0) {	appearBuf->appendf("1 0 0 1 {0:.2f} {1:.2f} Tm\n", x, y);      }      // write the text string      //~ this should center (instead of left-justify) each character within      //~     its comb cell      for (i = 0; i < text->getLength(); ++i) {	if (i > 0) {	  appearBuf->appendf("{0:.2f} 0 Td\n", w);	}	appearBuf->append('(');	c = text->getChar(i) & 0xff;	if (c == '(' || c == ')' || c == '\\') {	  appearBuf->append('\\');	  appearBuf->append(c);	} else if (c < 0x20 || c >= 0x80) {	  appearBuf->appendf("{0:.2f} 0 Td\n", w);	} else {	  appearBuf->append(c);	}	appearBuf->append(") Tj\n");      }    // regular (non-comb) formatting    } else {      // compute string width      if (font && !font->isCIDFont()) {	w = 0;	for (i = 0; i < text->getLength(); ++i) {	  w += ((Gfx8BitFont *)font)->getWidth(text->getChar(i));	}      } else {	// otherwise, make a crude estimate	w = text->getLength() * 0.5;      }      // compute font autosize      if (fontSize == 0) {	fontSize = yMax - yMin - 2 * border;	fontSize2 = (xMax - xMin - 4 - 2 * border) / w;	if (fontSize2 < fontSize) {	  fontSize = fontSize2;	}	fontSize = floor(fontSize);	if (tfPos >= 0) {	  tok = (GString *)daToks->get(tfPos + 1);	  tok->clear();	  tok->appendf("{0:.2f}", fontSize);	}      }      // compute text start position      w *= fontSize;      switch (quadding) {      case fieldQuadLeft:      default:	x = border + 2;	break;      case fieldQuadCenter:	x = (xMax - xMin - w) / 2;	break;      case fieldQuadRight:	x = xMax - xMin - border - 2 - w;	break;      }      y = 0.5 * (yMax - yMin) - 0.4 * fontSize;      // set the font matrix      if (tmPos >= 0) {	tok = (GString *)daToks->get(tmPos + 4);	tok->clear();	tok->appendf("{0:.2f}", x);	tok = (GString *)daToks->get(tmPos + 5);	tok->clear();	tok->appendf("{0:.2f}", y);      }      // write the DA string      if (daToks) {	for (i = 0; i < daToks->getLength(); ++i) {	  appearBuf->append((GString *)daToks->get(i))->append(' ');	}      }      // write the font matrix (if not part of the DA string)      if (tmPos < 0) {	appearBuf->appendf("1 0 0 1 {0:.2f} {1:.2f} Tm\n", x, y);      }      // write the text string      appearBuf->append('(');      for (i = 0; i < text->getLength(); ++i) {	c = text->getChar(i) & 0xff;	if (c == '(' || c == ')' || c == '\\') {	  appearBuf->append('\\');	  appearBuf->append(c);	} else if (c < 0x20 || c >= 0x80) {	  appearBuf->appendf("\\{0:03o}", c);

⌨️ 快捷键说明

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