gfx.cc

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

CC
2,586 行
字号
    mat = font->getFontMatrix();    newCTM[0] = mat[0] * newCTM[0] + mat[1] * newCTM[2];    newCTM[1] = mat[0] * newCTM[1] + mat[1] * newCTM[3];    newCTM[2] = mat[2] * newCTM[0] + mat[3] * newCTM[2];    newCTM[3] = mat[2] * newCTM[1] + mat[3] * newCTM[3];    newCTM[0] *= state->getFontSize();    newCTM[3] *= state->getFontSize();    newCTM[0] *= state->getHorizScaling();    newCTM[2] *= state->getHorizScaling();    state->textTransformDelta(0, state->getRise(), &riseX, &riseY);    curX = state->getCurX();    curY = state->getCurY();    lineX = state->getLineX();    lineY = state->getLineY();    oldParser = parser;    p = s->getCString();    len = s->getLength();    while (len > 0) {      n = font->getNextChar(p, len, &code,			    u, (int)(sizeof(u) / sizeof(Unicode)), &uLen,			    &dx, &dy, &originX, &originY);      dx = dx * state->getFontSize() + state->getCharSpace();      if (n == 1 && *p == ' ') {	dx += state->getWordSpace();      }      dx *= state->getHorizScaling();      dy *= state->getFontSize();      state->textTransformDelta(dx, dy, &tdx, &tdy);      state->transform(curX + riseX, curY + riseY, &x, &y);      out->saveState(state);      state = state->save();      state->setCTM(newCTM[0], newCTM[1], newCTM[2], newCTM[3], x, y);      //~ out->updateCTM(???)      if (!out->beginType3Char(state, code, u, uLen)) {	((Gfx8BitFont *)font)->getCharProc(code, &charProc);	if ((resDict = ((Gfx8BitFont *)font)->getResources())) {	  pushResources(resDict);	}	if (charProc.isStream()) {	  display(&charProc, gFalse);	} else {	  error(getPos(), "Missing or bad Type3 CharProc entry");	}	out->endType3Char(state);	if (resDict) {	  popResources();	}	charProc.free();      }      state = state->restore();      out->restoreState(state);      // GfxState::restore() does *not* restore the current position,      // so we deal with it here using (curX, curY) and (lineX, lineY)      curX += tdx;      curY += tdy;      state->moveTo(curX, curY);      state->textSetPos(lineX, lineY);      p += n;      len -= n;    }    parser = oldParser;  } else if (out->useDrawChar()) {    state->textTransformDelta(0, state->getRise(), &riseX, &riseY);    p = s->getCString();    len = s->getLength();    while (len > 0) {      n = font->getNextChar(p, len, &code,			    u, (int)(sizeof(u) / sizeof(Unicode)), &uLen,			    &dx, &dy, &originX, &originY);      if (wMode) {	dx *= state->getFontSize();	dy = dy * state->getFontSize() + state->getCharSpace();	if (n == 1 && *p == ' ') {	  dy += state->getWordSpace();	}      } else {	dx = dx * state->getFontSize() + state->getCharSpace();	if (n == 1 && *p == ' ') {	  dx += state->getWordSpace();	}	dx *= state->getHorizScaling();	dy *= state->getFontSize();      }      state->textTransformDelta(dx, dy, &tdx, &tdy);      originX *= state->getFontSize();      originY *= state->getFontSize();      state->textTransformDelta(originX, originY, &tOriginX, &tOriginY);      out->drawChar(state, state->getCurX() + riseX, state->getCurY() + riseY,		    tdx, tdy, tOriginX, tOriginY, code, u, uLen);      state->shift(tdx, tdy);      p += n;      len -= n;    }  } else {    dx = dy = 0;    p = s->getCString();    len = s->getLength();    nChars = nSpaces = 0;    while (len > 0) {      n = font->getNextChar(p, len, &code,			    u, (int)(sizeof(u) / sizeof(Unicode)), &uLen,			    &dx2, &dy2, &originX, &originY);      dx += dx2;      dy += dy2;      if (n == 1 && *p == ' ') {	++nSpaces;      }      ++nChars;      p += n;      len -= n;    }    if (wMode) {      dx *= state->getFontSize();      dy = dy * state->getFontSize()	   + nChars * state->getCharSpace()	   + nSpaces * state->getWordSpace();    } else {      dx = dx * state->getFontSize()	   + nChars * state->getCharSpace()	   + nSpaces * state->getWordSpace();      dx *= state->getHorizScaling();      dy *= state->getFontSize();    }    state->textTransformDelta(dx, dy, &tdx, &tdy);    out->drawString(state, s);    state->shift(tdx, tdy);  }  if (out->useDrawChar()) {    out->endString(state);  }  updateLevel += 10 * s->getLength();}//------------------------------------------------------------------------// XObject operators//------------------------------------------------------------------------void Gfx::opXObject(Object args[], int numArgs) {  Object obj1, obj2, obj3, refObj;#if OPI_SUPPORT  Object opiDict;#endif  if (!res->lookupXObject(args[0].getName(), &obj1)) {    return;  }  if (!obj1.isStream()) {    error(getPos(), "XObject '%s' is wrong type", args[0].getName());    obj1.free();    return;  }#if OPI_SUPPORT  obj1.streamGetDict()->lookup("OPI", &opiDict);  if (opiDict.isDict()) {    out->opiBegin(state, opiDict.getDict());  }#endif  obj1.streamGetDict()->lookup("Subtype", &obj2);  if (obj2.isName("Image")) {    res->lookupXObjectNF(args[0].getName(), &refObj);    doImage(&refObj, obj1.getStream(), gFalse);    refObj.free();  } else if (obj2.isName("Form")) {    doForm(&obj1);  } else if (obj2.isName("PS")) {    obj1.streamGetDict()->lookup("Level1", &obj3);    out->psXObject(obj1.getStream(),		   obj3.isStream() ? obj3.getStream() : (Stream *)NULL);  } else if (obj2.isName()) {    error(getPos(), "Unknown XObject subtype '%s'", obj2.getName());  } else {    error(getPos(), "XObject subtype is missing or wrong type");  }  obj2.free();#if OPI_SUPPORT  if (opiDict.isDict()) {    out->opiEnd(state, opiDict.getDict());  }  opiDict.free();#endif  obj1.free();}void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {  Dict *dict;  int width, height;  int bits;  GBool mask;  GBool invert;  GfxColorSpace *colorSpace;  GfxImageColorMap *colorMap;  Object maskObj;  GBool haveMask;  int maskColors[2*gfxColorMaxComps];  Object obj1, obj2;  int i;  // get stream dict  dict = str->getDict();  // get size  dict->lookup("Width", &obj1);  if (obj1.isNull()) {    obj1.free();    dict->lookup("W", &obj1);  }  if (!obj1.isInt())    goto err2;  width = obj1.getInt();  obj1.free();  dict->lookup("Height", &obj1);  if (obj1.isNull()) {    obj1.free();    dict->lookup("H", &obj1);  }  if (!obj1.isInt())    goto err2;  height = obj1.getInt();  obj1.free();  // image or mask?  dict->lookup("ImageMask", &obj1);  if (obj1.isNull()) {    obj1.free();    dict->lookup("IM", &obj1);  }  mask = gFalse;  if (obj1.isBool())    mask = obj1.getBool();  else if (!obj1.isNull())    goto err2;  obj1.free();  // bit depth  dict->lookup("BitsPerComponent", &obj1);  if (obj1.isNull()) {    obj1.free();    dict->lookup("BPC", &obj1);  }  if (!obj1.isInt())    goto err2;  bits = obj1.getInt();  obj1.free();  // display a mask  if (mask) {    // check for inverted mask    if (bits != 1)      goto err1;    invert = gFalse;    dict->lookup("Decode", &obj1);    if (obj1.isNull()) {      obj1.free();      dict->lookup("D", &obj1);    }    if (obj1.isArray()) {      obj1.arrayGet(0, &obj2);      if (obj2.isInt() && obj2.getInt() == 1)	invert = gTrue;      obj2.free();    } else if (!obj1.isNull()) {      goto err2;    }    obj1.free();    // draw it    out->drawImageMask(state, ref, str, width, height, invert, inlineImg);  } else {    // get color space and color map    dict->lookup("ColorSpace", &obj1);    if (obj1.isNull()) {      obj1.free();      dict->lookup("CS", &obj1);    }    if (obj1.isName()) {      res->lookupColorSpace(obj1.getName(), &obj2);      if (!obj2.isNull()) {	obj1.free();	obj1 = obj2;      } else {	obj2.free();      }    }    colorSpace = GfxColorSpace::parse(&obj1);    obj1.free();    if (!colorSpace) {      goto err1;    }    dict->lookup("Decode", &obj1);    if (obj1.isNull()) {      obj1.free();      dict->lookup("D", &obj1);    }    colorMap = new GfxImageColorMap(bits, &obj1, colorSpace);    obj1.free();    if (!colorMap->isOk()) {      delete colorMap;      goto err1;    }    // get the mask    haveMask = gFalse;    dict->lookup("Mask", &maskObj);    if (maskObj.isArray()) {      for (i = 0; i < maskObj.arrayGetLength(); ++i) {	maskObj.arrayGet(i, &obj1);	maskColors[i] = obj1.getInt();	obj1.free();      }      haveMask = gTrue;    }    // draw it    out->drawImage(state, ref, str, width, height, colorMap,		   haveMask ? maskColors : (int *)NULL,  inlineImg);    delete colorMap;    maskObj.free();  }  if ((i = width * height) > 1000) {    i = 1000;  }  updateLevel += i;  return; err2:  obj1.free(); err1:  error(getPos(), "Bad image parameters");}void Gfx::doForm(Object *str) {  Dict *dict;  Object matrixObj, bboxObj;  double m[6], bbox[6];  Object resObj;  Dict *resDict;  Object obj1;  int i;  // get stream dict  dict = str->streamGetDict();  // check form type  dict->lookup("FormType", &obj1);  if (!(obj1.isInt() && obj1.getInt() == 1)) {    error(getPos(), "Unknown form type");  }  obj1.free();  // get bounding box  dict->lookup("BBox", &bboxObj);  if (!bboxObj.isArray()) {    matrixObj.free();    bboxObj.free();    error(getPos(), "Bad form bounding box");    return;  }  for (i = 0; i < 4; ++i) {    bboxObj.arrayGet(i, &obj1);    bbox[i] = obj1.getNum();    obj1.free();  }  bboxObj.free();  // get matrix  dict->lookup("Matrix", &matrixObj);  if (matrixObj.isArray()) {    for (i = 0; i < 6; ++i) {      matrixObj.arrayGet(i, &obj1);      m[i] = obj1.getNum();      obj1.free();    }  } else {    m[0] = 1; m[1] = 0;    m[2] = 0; m[3] = 1;    m[4] = 0; m[5] = 0;  }  matrixObj.free();  // get resources  dict->lookup("Resources", &resObj);  resDict = resObj.isDict() ? resObj.getDict() : (Dict *)NULL;  // draw it  doForm1(str, resDict, m, bbox);  resObj.free();}void Gfx::doAnnot(Object *str, double xMin, double yMin,		  double xMax, double yMax) {  Dict *dict, *resDict;  Object matrixObj, bboxObj, resObj;  Object obj1;  double m[6], bbox[6], ictm[6];  double *ctm;  double formX0, formY0, formX1, formY1;  double annotX0, annotY0, annotX1, annotY1;  double det, x, y, sx, sy;  int i;  // get stream dict  dict = str->streamGetDict();  // get the form bounding box  dict->lookup("BBox", &bboxObj);  if (!bboxObj.isArray()) {    bboxObj.free();    error(getPos(), "Bad form bounding box");    return;  }  for (i = 0; i < 4; ++i) {    bboxObj.arrayGet(i, &obj1);    bbox[i] = obj1.getNum();    obj1.free();  }  bboxObj.free();  // get the form matrix  dict->lookup("Matrix", &matrixObj);  if (matrixObj.isArray()) {    for (i = 0; i < 6; ++i) {      matrixObj.arrayGet(i, &obj1);      m[i] = obj1.getNum();      obj1.free();    }  } else {    m[0] = 1; m[1] = 0;    m[2] = 0; m[3] = 1;    m[4] = 0; m[5] = 0;  }  matrixObj.free();  // transform the form bbox from form space to user space  formX0 = bbox[0] * m[0] + bbox[1] * m[2] + m[4];  formY0 = bbox[0] * m[1] + bbox[1] * m[3] + m[5];  formX1 = bbox[2] * m[0] + bbox[3] * m[2] + m[4];  formY1 = bbox[2] * m[1] + bbox[3] * m[3] + m[5];  // transform the annotation bbox from default user space to user  // space: (bbox * baseMatrix) * iCTM  ctm = state->getCTM();  det = 1 / (ctm[0] * ctm[3] - ctm[1] * ctm[2]);  ictm[0] = ctm[3] * det;  ictm[1] = -ctm[1] * det;  ictm[2] = -ctm[2] * det;  ictm[3] = ctm[0] * det;  ictm[4] = (ctm[2] * ctm[5] - ctm[3] * ctm[4]) * det;  ictm[5] = (ctm[1] * ctm[4] - ctm[0] * ctm[5]) * det;  x = baseMatrix[0] * xMin + baseMatrix[2] * yMin + baseMatrix[4];  y = baseMatrix[1] * xMin + baseMatrix[3] * yMin + baseMatrix[5];  annotX0 = ictm[0] * x + ictm[2] * y + ictm[4];  annotY0 = ictm[1] * x + ictm[3] * y + ictm[5];  x = baseMatrix[0] * xMax + baseMatrix[2] * yMax + baseMatrix[4];  y = baseMatrix[1] * xMax + baseMatrix[3] * yMax + baseMatrix[5];  annotX1 = ictm[0] * x + ictm[2] * y + ictm[4];  annotY1 = ictm[1] * x + ictm[3] * y + ictm[5];  // swap min/max coords  if (formX0 > formX1) {    x = formX0; formX0 = formX1; formX1 = x;  }  if (formY0 > formY1) {    y = formY0; formY0 = formY1; formY1 = y;  }  if (annotX0 > annotX1) {    x = annotX0; annotX0 = annotX1; annotX1 = x;  }  if (annotY0 > annotY1) {    y = annotY0; annotY0 = annotY1; annotY1 = y;  }  // scale the form to fit the annotation bbox  if (formX1 == formX0) {    // this shouldn't happen    sx = 1;  } else {    sx = (annotX1 - annotX0) / (formX1 - formX0);  }  if (formY1 == formY0) {    // this shouldn't happen    sy = 1;  } else {    sy = (annotY1 - annotY0) / (formY1 - formY0);  }  m[0] *= sx;  m[2] *= sx;  m[4] = (m[4] - formX0) * sx + annotX0;  m[1] *= sy;  m[3] *= sy;  m[5] = (m[5] - formY0) * sy + annotY0;  // get resources  dict->lookup("Resources", &resObj);  resDict = resObj.isDict() ? resObj.getDict() : (Dict *)NULL;  // draw it  doForm1(str, resDict, m, bbox);  resObj.free();  bboxObj.free();}void Gfx::doForm1(Object

⌨️ 快捷键说明

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