Back to index

tetex-bin  3.0
Public Member Functions | Private Member Functions | Private Attributes | Static Private Attributes
Gfx Class Reference

#include <Gfx.h>

Collaboration diagram for Gfx:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 Gfx (XRef *xrefA, OutputDev *outA, int pageNum, Dict *resDict, double hDPI, double vDPI, PDFRectangle *box, GBool crop, PDFRectangle *cropBox, int rotate, GBool(*abortCheckCbkA)(void *data)=NULL, void *abortCheckCbkDataA=NULL)
 Gfx (XRef *xrefA, OutputDev *outA, Dict *resDict, PDFRectangle *box, GBool crop, PDFRectangle *cropBox, GBool(*abortCheckCbkA)(void *data)=NULL, void *abortCheckCbkDataA=NULL)
 ~Gfx ()
void display (Object *obj, GBool topLevel=gTrue)
void doAnnot (Object *str, double xMin, double yMin, double xMax, double yMax)
void saveState ()
void restoreState ()

Private Member Functions

void go (GBool topLevel)
void execOp (Object *cmd, Object args[], int numArgs)
OperatorfindOp (char *name)
GBool checkArg (Object *arg, TchkType type)
int getPos ()
void opSave (Object args[], int numArgs)
void opRestore (Object args[], int numArgs)
void opConcat (Object args[], int numArgs)
void opSetDash (Object args[], int numArgs)
void opSetFlat (Object args[], int numArgs)
void opSetLineJoin (Object args[], int numArgs)
void opSetLineCap (Object args[], int numArgs)
void opSetMiterLimit (Object args[], int numArgs)
void opSetLineWidth (Object args[], int numArgs)
void opSetExtGState (Object args[], int numArgs)
void opSetRenderingIntent (Object args[], int numArgs)
void opSetFillGray (Object args[], int numArgs)
void opSetStrokeGray (Object args[], int numArgs)
void opSetFillCMYKColor (Object args[], int numArgs)
void opSetStrokeCMYKColor (Object args[], int numArgs)
void opSetFillRGBColor (Object args[], int numArgs)
void opSetStrokeRGBColor (Object args[], int numArgs)
void opSetFillColorSpace (Object args[], int numArgs)
void opSetStrokeColorSpace (Object args[], int numArgs)
void opSetFillColor (Object args[], int numArgs)
void opSetStrokeColor (Object args[], int numArgs)
void opSetFillColorN (Object args[], int numArgs)
void opSetStrokeColorN (Object args[], int numArgs)
void opMoveTo (Object args[], int numArgs)
void opLineTo (Object args[], int numArgs)
void opCurveTo (Object args[], int numArgs)
void opCurveTo1 (Object args[], int numArgs)
void opCurveTo2 (Object args[], int numArgs)
void opRectangle (Object args[], int numArgs)
void opClosePath (Object args[], int numArgs)
void opEndPath (Object args[], int numArgs)
void opStroke (Object args[], int numArgs)
void opCloseStroke (Object args[], int numArgs)
void opFill (Object args[], int numArgs)
void opEOFill (Object args[], int numArgs)
void opFillStroke (Object args[], int numArgs)
void opCloseFillStroke (Object args[], int numArgs)
void opEOFillStroke (Object args[], int numArgs)
void opCloseEOFillStroke (Object args[], int numArgs)
void doPatternFill (GBool eoFill)
void doTilingPatternFill (GfxTilingPattern *tPat, GBool eoFill)
void doShadingPatternFill (GfxShadingPattern *sPat, GBool eoFill)
void opShFill (Object args[], int numArgs)
void doFunctionShFill (GfxFunctionShading *shading)
void doFunctionShFill1 (GfxFunctionShading *shading, double x0, double y0, double x1, double y1, GfxColor *colors, int depth)
void doAxialShFill (GfxAxialShading *shading)
void doRadialShFill (GfxRadialShading *shading)
void doEndPath ()
void opClip (Object args[], int numArgs)
void opEOClip (Object args[], int numArgs)
void opBeginText (Object args[], int numArgs)
void opEndText (Object args[], int numArgs)
void opSetCharSpacing (Object args[], int numArgs)
void opSetFont (Object args[], int numArgs)
void opSetTextLeading (Object args[], int numArgs)
void opSetTextRender (Object args[], int numArgs)
void opSetTextRise (Object args[], int numArgs)
void opSetWordSpacing (Object args[], int numArgs)
void opSetHorizScaling (Object args[], int numArgs)
void opTextMove (Object args[], int numArgs)
void opTextMoveSet (Object args[], int numArgs)
void opSetTextMatrix (Object args[], int numArgs)
void opTextNextLine (Object args[], int numArgs)
void opShowText (Object args[], int numArgs)
void opMoveShowText (Object args[], int numArgs)
void opMoveSetShowText (Object args[], int numArgs)
void opShowSpaceText (Object args[], int numArgs)
void doShowText (GString *s)
void opXObject (Object args[], int numArgs)
void doImage (Object *ref, Stream *str, GBool inlineImg)
void doForm (Object *str)
void doForm1 (Object *str, Dict *resDict, double *matrix, double *bbox)
void opBeginImage (Object args[], int numArgs)
StreambuildImageStream ()
void opImageData (Object args[], int numArgs)
void opEndImage (Object args[], int numArgs)
void opSetCharWidth (Object args[], int numArgs)
void opSetCacheDevice (Object args[], int numArgs)
void opBeginIgnoreUndef (Object args[], int numArgs)
void opEndIgnoreUndef (Object args[], int numArgs)
void opBeginMarkedContent (Object args[], int numArgs)
void opEndMarkedContent (Object args[], int numArgs)
void opMarkPoint (Object args[], int numArgs)
void pushResources (Dict *resDict)
void popResources ()

Private Attributes

XRefxref
OutputDevout
GBool subPage
GBool printCommands
GfxResourcesres
int updateLevel
GfxStatestate
GBool fontChanged
GfxClipType clip
int ignoreUndef
double baseMatrix [6]
int formDepth
Parserparser
GBool(* abortCheckCbk )(void *data)
voidabortCheckCbkData

Static Private Attributes

static Operator opTab []

Detailed Description

Definition at line 99 of file Gfx.h.


Constructor & Destructor Documentation

Gfx::Gfx ( XRef xrefA,
OutputDev outA,
int  pageNum,
Dict resDict,
double  hDPI,
double  vDPI,
PDFRectangle box,
GBool  crop,
PDFRectangle cropBox,
int  rotate,
GBool(*)(void *data abortCheckCbkA = NULL,
void abortCheckCbkDataA = NULL 
)

Definition at line 407 of file Gfx.cc.

                                  {
  int i;

  xref = xrefA;
  subPage = gFalse;
  printCommands = globalParams->getPrintCommands();

  // start the resource stack
  res = new GfxResources(xref, resDict, NULL);

  // initialize
  out = outA;
  state = new GfxState(hDPI, vDPI, box, rotate, out->upsideDown());
  fontChanged = gFalse;
  clip = clipNone;
  ignoreUndef = 0;
  out->startPage(pageNum, state);
  out->setDefaultCTM(state->getCTM());
  out->updateAll(state);
  for (i = 0; i < 6; ++i) {
    baseMatrix[i] = state->getCTM()[i];
  }
  formDepth = 0;
  abortCheckCbk = abortCheckCbkA;
  abortCheckCbkData = abortCheckCbkDataA;

  // set crop box
  if (crop) {
    state->moveTo(cropBox->x1, cropBox->y1);
    state->lineTo(cropBox->x2, cropBox->y1);
    state->lineTo(cropBox->x2, cropBox->y2);
    state->lineTo(cropBox->x1, cropBox->y2);
    state->closePath();
    state->clip();
    out->clip(state);
    state->clearPath();
  }
}

Here is the call graph for this function:

Gfx::Gfx ( XRef xrefA,
OutputDev outA,
Dict resDict,
PDFRectangle box,
GBool  crop,
PDFRectangle cropBox,
GBool(*)(void *data abortCheckCbkA = NULL,
void abortCheckCbkDataA = NULL 
)

Definition at line 450 of file Gfx.cc.

                                  {
  int i;

  xref = xrefA;
  subPage = gTrue;
  printCommands = globalParams->getPrintCommands();

  // start the resource stack
  res = new GfxResources(xref, resDict, NULL);

  // initialize
  out = outA;
  state = new GfxState(72, 72, box, 0, gFalse);
  fontChanged = gFalse;
  clip = clipNone;
  ignoreUndef = 0;
  for (i = 0; i < 6; ++i) {
    baseMatrix[i] = state->getCTM()[i];
  }
  formDepth = 0;
  abortCheckCbk = abortCheckCbkA;
  abortCheckCbkData = abortCheckCbkDataA;

  // set crop box
  if (crop) {
    state->moveTo(cropBox->x1, cropBox->y1);
    state->lineTo(cropBox->x2, cropBox->y1);
    state->lineTo(cropBox->x2, cropBox->y2);
    state->lineTo(cropBox->x1, cropBox->y2);
    state->closePath();
    state->clip();
    out->clip(state);
    state->clearPath();
  }
}

Here is the call graph for this function:

Gfx::~Gfx ( )

Definition at line 489 of file Gfx.cc.

          {
  while (state->hasSaves()) {
    restoreState();
  }
  if (!subPage) {
    out->endPage();
  }
  while (res) {
    popResources();
  }
  if (state) {
    delete state;
  }
}

Here is the call graph for this function:


Member Function Documentation

Stream * Gfx::buildImageStream ( ) [private]

Definition at line 2953 of file Gfx.cc.

                              {
  Object dict;
  Object obj;
  char *key;
  Stream *str;

  // build dictionary
  dict.initDict(xref);
  parser->getObj(&obj);
  while (!obj.isCmd("ID") && !obj.isEOF()) {
    if (!obj.isName()) {
      error(getPos(), "Inline image dictionary key must be a name object");
      obj.free();
    } else {
      key = copyString(obj.getName());
      obj.free();
      parser->getObj(&obj);
      if (obj.isEOF() || obj.isError()) {
       gfree(key);
       break;
      }
      dict.dictAdd(key, &obj);
    }
    parser->getObj(&obj);
  }
  if (obj.isEOF()) {
    error(getPos(), "End of file in inline image");
    obj.free();
    dict.free();
    return NULL;
  }
  obj.free();

  // make stream
  str = new EmbedStream(parser->getStream(), &dict, gFalse, 0);
  str = str->addFilters(&dict);

  return str;
}

Here is the call graph for this function:

Here is the caller graph for this function:

GBool Gfx::checkArg ( Object arg,
TchkType  type 
) [private]

Definition at line 684 of file Gfx.cc.

                                              {
  switch (type) {
  case tchkBool:   return arg->isBool();
  case tchkInt:    return arg->isInt();
  case tchkNum:    return arg->isNum();
  case tchkString: return arg->isString();
  case tchkName:   return arg->isName();
  case tchkArray:  return arg->isArray();
  case tchkProps:  return arg->isDict() || arg->isName();
  case tchkSCN:    return arg->isNum() || arg->isName();
  case tchkNone:   return gFalse;
  }
  return gFalse;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void Gfx::display ( Object obj,
GBool  topLevel = gTrue 
)

Definition at line 504 of file Gfx.cc.

                                             {
  Object obj2;
  int i;

  if (obj->isArray()) {
    for (i = 0; i < obj->arrayGetLength(); ++i) {
      obj->arrayGet(i, &obj2);
      if (!obj2.isStream()) {
       error(-1, "Weird page contents");
       obj2.free();
       return;
      }
      obj2.free();
    }
  } else if (!obj->isStream()) {
    error(-1, "Weird page contents");
    return;
  }
  parser = new Parser(xref, new Lexer(xref, obj));
  go(topLevel);
  delete parser;
  parser = NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void Gfx::doAnnot ( Object str,
double  xMin,
double  yMin,
double  xMax,
double  yMax 
)

Definition at line 2754 of file Gfx.cc.

                                          {
  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();
}

Here is the call graph for this function:

void Gfx::doAxialShFill ( GfxAxialShading shading) [private]

Definition at line 1663 of file Gfx.cc.

                                                {
  double xMin, yMin, xMax, yMax;
  double x0, y0, x1, y1;
  double dx, dy, mul;
  double tMin, tMax, t, tx, ty;
  double s[4], sMin, sMax, tmp;
  double ux0, uy0, ux1, uy1, vx0, vy0, vx1, vy1;
  double t0, t1, tt;
  double ta[axialMaxSplits + 1];
  int next[axialMaxSplits + 1];
  GfxColor color0, color1;
  int nComps;
  int i, j, k, kk;

  // get the clip region bbox
  state->getUserClipBBox(&xMin, &yMin, &xMax, &yMax);

  // compute min and max t values, based on the four corners of the
  // clip region bbox
  shading->getCoords(&x0, &y0, &x1, &y1);
  dx = x1 - x0;
  dy = y1 - y0;
  mul = 1 / (dx * dx + dy * dy);
  tMin = tMax = ((xMin - x0) * dx + (yMin - y0) * dy) * mul;
  t = ((xMin - x0) * dx + (yMax - y0) * dy) * mul;
  if (t < tMin) {
    tMin = t;
  } else if (t > tMax) {
    tMax = t;
  }
  t = ((xMax - x0) * dx + (yMin - y0) * dy) * mul;
  if (t < tMin) {
    tMin = t;
  } else if (t > tMax) {
    tMax = t;
  }
  t = ((xMax - x0) * dx + (yMax - y0) * dy) * mul;
  if (t < tMin) {
    tMin = t;
  } else if (t > tMax) {
    tMax = t;
  }
  if (tMin < 0 && !shading->getExtend0()) {
    tMin = 0;
  }
  if (tMax > 1 && !shading->getExtend1()) {
    tMax = 1;
  }

  // get the function domain
  t0 = shading->getDomain0();
  t1 = shading->getDomain1();

  // Traverse the t axis and do the shading.
  //
  // For each point (tx, ty) on the t axis, consider a line through
  // that point perpendicular to the t axis:
  //
  //     x(s) = tx + s * -dy   -->   s = (x - tx) / -dy
  //     y(s) = ty + s * dx    -->   s = (y - ty) / dx
  //
  // Then look at the intersection of this line with the bounding box
  // (xMin, yMin, xMax, yMax).  In the general case, there are four
  // intersection points:
  //
  //     s0 = (xMin - tx) / -dy
  //     s1 = (xMax - tx) / -dy
  //     s2 = (yMin - ty) / dx
  //     s3 = (yMax - ty) / dx
  //
  // and we want the middle two s values.
  //
  // In the case where dx = 0, take s0 and s1; in the case where dy =
  // 0, take s2 and s3.
  //
  // Each filled polygon is bounded by two of these line segments
  // perpdendicular to the t axis.
  //
  // The t axis is bisected into smaller regions until the color
  // difference across a region is small enough, and then the region
  // is painted with a single color.

  // set up: require at least one split to avoid problems when the two
  // ends of the t axis have the same color
  nComps = shading->getColorSpace()->getNComps();
  ta[0] = tMin;
  next[0] = axialMaxSplits / 2;
  ta[axialMaxSplits / 2] = 0.5 * (tMin + tMax);
  next[axialMaxSplits / 2] = axialMaxSplits;
  ta[axialMaxSplits] = tMax;

  // compute the color at t = tMin
  if (tMin < 0) {
    tt = t0;
  } else if (tMin > 1) {
    tt = t1;
  } else {
    tt = t0 + (t1 - t0) * tMin;
  }
  shading->getColor(tt, &color0);

  // compute the coordinates of the point on the t axis at t = tMin;
  // then compute the intersection of the perpendicular line with the
  // bounding box
  tx = x0 + tMin * dx;
  ty = y0 + tMin * dy;
  if (dx == 0 && dy == 0) {
    sMin = sMax = 0;
  } if (dx == 0) {
    sMin = (xMin - tx) / -dy;
    sMax = (xMax - tx) / -dy;
    if (sMin > sMax) { tmp = sMin; sMin = sMax; sMax = tmp; }
  } else if (dy == 0) {
    sMin = (yMin - ty) / dx;
    sMax = (yMax - ty) / dx;
    if (sMin > sMax) { tmp = sMin; sMin = sMax; sMax = tmp; }
  } else {
    s[0] = (yMin - ty) / dx;
    s[1] = (yMax - ty) / dx;
    s[2] = (xMin - tx) / -dy;
    s[3] = (xMax - tx) / -dy;
    for (j = 0; j < 3; ++j) {
      kk = j;
      for (k = j + 1; k < 4; ++k) {
       if (s[k] < s[kk]) {
         kk = k;
       }
      }
      tmp = s[j]; s[j] = s[kk]; s[kk] = tmp;
    }
    sMin = s[1];
    sMax = s[2];
  }
  ux0 = tx - sMin * dy;
  uy0 = ty + sMin * dx;
  vx0 = tx - sMax * dy;
  vy0 = ty + sMax * dx;

  i = 0;
  while (i < axialMaxSplits) {

    // bisect until color difference is small enough or we hit the
    // bisection limit
    j = next[i];
    while (j > i + 1) {
      if (ta[j] < 0) {
       tt = t0;
      } else if (ta[j] > 1) {
       tt = t1;
      } else {
       tt = t0 + (t1 - t0) * ta[j];
      }
      shading->getColor(tt, &color1);
      for (k = 0; k < nComps; ++k) {
       if (fabs(color1.c[k] - color0.c[k]) > axialColorDelta) {
         break;
       }
      }
      if (k == nComps) {
       break;
      }
      k = (i + j) / 2;
      ta[k] = 0.5 * (ta[i] + ta[j]);
      next[i] = k;
      next[k] = j;
      j = k;
    }

    // use the average of the colors of the two sides of the region
    for (k = 0; k < nComps; ++k) {
      color0.c[k] = 0.5 * (color0.c[k] + color1.c[k]);
    }

    // compute the coordinates of the point on the t axis; then
    // compute the intersection of the perpendicular line with the
    // bounding box
    tx = x0 + ta[j] * dx;
    ty = y0 + ta[j] * dy;
    if (dx == 0 && dy == 0) {
      sMin = sMax = 0;
    } if (dx == 0) {
      sMin = (xMin - tx) / -dy;
      sMax = (xMax - tx) / -dy;
      if (sMin > sMax) { tmp = sMin; sMin = sMax; sMax = tmp; }
    } else if (dy == 0) {
      sMin = (yMin - ty) / dx;
      sMax = (yMax - ty) / dx;
      if (sMin > sMax) { tmp = sMin; sMin = sMax; sMax = tmp; }
    } else {
      s[0] = (yMin - ty) / dx;
      s[1] = (yMax - ty) / dx;
      s[2] = (xMin - tx) / -dy;
      s[3] = (xMax - tx) / -dy;
      for (j = 0; j < 3; ++j) {
       kk = j;
       for (k = j + 1; k < 4; ++k) {
         if (s[k] < s[kk]) {
           kk = k;
         }
       }
       tmp = s[j]; s[j] = s[kk]; s[kk] = tmp;
      }
      sMin = s[1];
      sMax = s[2];
    }
    ux1 = tx - sMin * dy;
    uy1 = ty + sMin * dx;
    vx1 = tx - sMax * dy;
    vy1 = ty + sMax * dx;

    // set the color
    state->setFillColor(&color0);
    out->updateFillColor(state);

    // fill the region
    state->moveTo(ux0, uy0);
    state->lineTo(vx0, vy0);
    state->lineTo(vx1, vy1);
    state->lineTo(ux1, uy1);
    state->closePath();
    out->fill(state);
    state->clearPath();

    // set up for next region
    ux0 = ux1;
    uy0 = uy1;
    vx0 = vx1;
    vy0 = vy1;
    color0 = color1;
    i = next[i];
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void Gfx::doEndPath ( ) [private]

Definition at line 2094 of file Gfx.cc.

                    {
  if (state->isCurPt() && clip != clipNone) {
    state->clip();
    if (clip == clipNormal) {
      out->clip(state);
    } else {
      out->eoClip(state);
    }
  }
  clip = clipNone;
  state->clearPath();
}

Here is the call graph for this function:

Here is the caller graph for this function:

void Gfx::doForm ( Object str) [private]

Definition at line 2688 of file Gfx.cc.

                            {
  Dict *dict;
  Object matrixObj, bboxObj;
  double m[6], bbox[6];
  Object resObj;
  Dict *resDict;
  Object obj1;
  int i;

  // check for excessive recursion
  if (formDepth > 20) {
    return;
  }

  // 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
  ++formDepth;
  doForm1(str, resDict, m, bbox);
  --formDepth;

  resObj.free();
}

Here is the call graph for this function:

Here is the caller graph for this function:

void Gfx::doForm1 ( Object str,
Dict resDict,
double *  matrix,
double *  bbox 
) [private]

Definition at line 2868 of file Gfx.cc.

                                                                          {
  Parser *oldParser;
  double oldBaseMatrix[6];
  int i;

  // push new resources on stack
  pushResources(resDict);

  // save current graphics state
  saveState();

  // kill any pre-existing path
  state->clearPath();

  // save current parser
  oldParser = parser;

  // set form transformation matrix
  state->concatCTM(matrix[0], matrix[1], matrix[2],
                 matrix[3], matrix[4], matrix[5]);
  out->updateCTM(state, matrix[0], matrix[1], matrix[2],
               matrix[3], matrix[4], matrix[5]);

  // set new base matrix
  for (i = 0; i < 6; ++i) {
    oldBaseMatrix[i] = baseMatrix[i];
    baseMatrix[i] = state->getCTM()[i];
  }

  // set form bounding box
  state->moveTo(bbox[0], bbox[1]);
  state->lineTo(bbox[2], bbox[1]);
  state->lineTo(bbox[2], bbox[3]);
  state->lineTo(bbox[0], bbox[3]);
  state->closePath();
  state->clip();
  out->clip(state);
  state->clearPath();

  // draw the form
  display(str, gFalse);

  // restore base matrix
  for (i = 0; i < 6; ++i) {
    baseMatrix[i] = oldBaseMatrix[i];
  }

  // restore parser
  parser = oldParser;

  // restore graphics state
  restoreState();

  // pop resource stack
  popResources();

  return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void Gfx::doFunctionShFill ( GfxFunctionShading shading) [private]

Definition at line 1543 of file Gfx.cc.

                                                      {
  double x0, y0, x1, y1;
  GfxColor colors[4];

  shading->getDomain(&x0, &y0, &x1, &y1);
  shading->getColor(x0, y0, &colors[0]);
  shading->getColor(x0, y1, &colors[1]);
  shading->getColor(x1, y0, &colors[2]);
  shading->getColor(x1, y1, &colors[3]);
  doFunctionShFill1(shading, x0, y0, x1, y1, colors, 0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void Gfx::doFunctionShFill1 ( GfxFunctionShading shading,
double  x0,
double  y0,
double  x1,
double  y1,
GfxColor colors,
int  depth 
) [private]

Definition at line 1555 of file Gfx.cc.

                                                      {
  GfxColor fillColor;
  GfxColor color0M, color1M, colorM0, colorM1, colorMM;
  GfxColor colors2[4];
  double *matrix;
  double xM, yM;
  int nComps, i, j;

  nComps = shading->getColorSpace()->getNComps();
  matrix = shading->getMatrix();

  // compare the four corner colors
  for (i = 0; i < 4; ++i) {
    for (j = 0; j < nComps; ++j) {
      if (fabs(colors[i].c[j] - colors[(i+1)&3].c[j]) > functionColorDelta) {
       break;
      }
    }
    if (j < nComps) {
      break;
    }
  }

  // center of the rectangle
  xM = 0.5 * (x0 + x1);
  yM = 0.5 * (y0 + y1);

  // the four corner colors are close (or we hit the recursive limit)
  // -- fill the rectangle; but require at least one subdivision
  // (depth==0) to avoid problems when the four outer corners of the
  // shaded region are the same color
  if ((i == 4 && depth > 0) || depth == functionMaxDepth) {

    // use the center color
    shading->getColor(xM, yM, &fillColor);
    state->setFillColor(&fillColor);
    out->updateFillColor(state);

    // fill the rectangle
    state->moveTo(x0 * matrix[0] + y0 * matrix[2] + matrix[4],
                x0 * matrix[1] + y0 * matrix[3] + matrix[5]);
    state->lineTo(x1 * matrix[0] + y0 * matrix[2] + matrix[4],
                x1 * matrix[1] + y0 * matrix[3] + matrix[5]);
    state->lineTo(x1 * matrix[0] + y1 * matrix[2] + matrix[4],
                x1 * matrix[1] + y1 * matrix[3] + matrix[5]);
    state->lineTo(x0 * matrix[0] + y1 * matrix[2] + matrix[4],
                x0 * matrix[1] + y1 * matrix[3] + matrix[5]);
    state->closePath();
    out->fill(state);
    state->clearPath();

  // the four corner colors are not close enough -- subdivide the
  // rectangle
  } else {

    // colors[0]       colorM0       colors[2]
    //   (x0,y0)       (xM,y0)       (x1,y0)
    //         +----------+----------+
    //         |          |          |
    //         |    UL    |    UR    |
    // color0M |       colorMM       | color1M
    // (x0,yM) +----------+----------+ (x1,yM)
    //         |       (xM,yM)       |
    //         |    LL    |    LR    |
    //         |          |          |
    //         +----------+----------+
    // colors[1]       colorM1       colors[3]
    //   (x0,y1)       (xM,y1)       (x1,y1)

    shading->getColor(x0, yM, &color0M);
    shading->getColor(x1, yM, &color1M);
    shading->getColor(xM, y0, &colorM0);
    shading->getColor(xM, y1, &colorM1);
    shading->getColor(xM, yM, &colorMM);

    // upper-left sub-rectangle
    colors2[0] = colors[0];
    colors2[1] = color0M;
    colors2[2] = colorM0;
    colors2[3] = colorMM;
    doFunctionShFill1(shading, x0, y0, xM, yM, colors2, depth + 1);
    
    // lower-left sub-rectangle
    colors2[0] = color0M;
    colors2[1] = colors[1];
    colors2[2] = colorMM;
    colors2[3] = colorM1;
    doFunctionShFill1(shading, x0, yM, xM, y1, colors2, depth + 1);
    
    // upper-right sub-rectangle
    colors2[0] = colorM0;
    colors2[1] = colorMM;
    colors2[2] = colors[2];
    colors2[3] = color1M;
    doFunctionShFill1(shading, xM, y0, x1, yM, colors2, depth + 1);

    // lower-right sub-rectangle
    colors2[0] = colorMM;
    colors2[1] = colorM1;
    colors2[2] = color1M;
    colors2[3] = colors[3];
    doFunctionShFill1(shading, xM, yM, x1, y1, colors2, depth + 1);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void Gfx::doImage ( Object ref,
Stream str,
GBool  inlineImg 
) [private]

Definition at line 2529 of file Gfx.cc.

                                                           {
  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()) {
    bits = obj1.getInt();
  } else if (mask) {
    bits = 1;
  } else {
    goto err2;
  }
  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 < 2*gfxColorMaxComps;
          ++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");
}

Here is the call graph for this function:

Here is the caller graph for this function:

void Gfx::doPatternFill ( GBool  eoFill) [private]

Definition at line 1227 of file Gfx.cc.

                                    {
  GfxPattern *pattern;

  // this is a bit of a kludge -- patterns can be really slow, so we
  // skip them if we're only doing text extraction, since they almost
  // certainly don't contain any text
  if (!out->needNonText()) {
    return;
  }

  if (!(pattern = state->getFillPattern())) {
    return;
  }
  switch (pattern->getType()) {
  case 1:
    doTilingPatternFill((GfxTilingPattern *)pattern, eoFill);
    break;
  case 2:
    doShadingPatternFill((GfxShadingPattern *)pattern, eoFill);
    break;
  default:
    error(getPos(), "Unimplemented pattern type (%d) in fill",
         pattern->getType());
    break;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void Gfx::doRadialShFill ( GfxRadialShading shading) [private]

Definition at line 1896 of file Gfx.cc.

                                                  {
  double sMin, sMax, xMin, yMin, xMax, yMax;
  double x0, y0, r0, x1, y1, r1, t0, t1;
  int nComps;
  GfxColor colorA, colorB;
  double xa, ya, xb, yb, ra, rb;
  double ta, tb, sa, sb;
  int ia, ib, k, n;
  double *ctm;
  double angle, t;

  // get the shading info
  shading->getCoords(&x0, &y0, &r0, &x1, &y1, &r1);
  t0 = shading->getDomain0();
  t1 = shading->getDomain1();
  nComps = shading->getColorSpace()->getNComps();

  // compute the (possibly extended) s range
  sMin = 0;
  sMax = 1;
  if (shading->getExtend0()) {
    if (r0 < r1) {
      // extend the smaller end
      sMin = -r0 / (r1 - r0);
    } else {
      // extend the larger end
      //~ this computes the diagonal of the bounding box -- we should
      //~ really compute the intersection of the moving/expanding
      //~ circles with each of the four corners and look for the max
      //~ radius
      state->getUserClipBBox(&xMin, &yMin, &xMax, &yMax);
      sMin = (sqrt((xMax - xMin) * (xMax - xMin) +
                 (yMax - yMin) * (yMax - yMin)) - r0) / (r1 - r0);
      if (sMin > 0) {
       sMin = 0;
      } else if (sMin < -20) {
       // sanity check
       sMin = -20;
      }
    }
  }
  if (shading->getExtend1()) {
    if (r1 < r0) {
      // extend the smaller end
      sMax = -r0 / (r1 - r0);
    } else if (r1 > r0) {
      // extend the larger end
      state->getUserClipBBox(&xMin, &yMin, &xMax, &yMax);
      sMax = (sqrt((xMax - xMin) * (xMax - xMin) +
                 (yMax - yMin) * (yMax - yMin)) - r0) / (r1 - r0);
      if (sMax < 1) {
       sMin = 1;
      } else if (sMax > 20) {
       // sanity check
       sMax = 20;
      }
    }
  }

  // compute the number of steps into which circles must be divided to
  // achieve a curve flatness of 0.1 pixel in device space for the
  // largest circle (note that "device space" is 72 dpi when generating
  // PostScript, hence the relatively small 0.1 pixel accuracy)
  ctm = state->getCTM();
  t = fabs(ctm[0]);
  if (fabs(ctm[1]) > t) {
    t = fabs(ctm[1]);
  }
  if (fabs(ctm[2]) > t) {
    t = fabs(ctm[2]);
  }
  if (fabs(ctm[3]) > t) {
    t = fabs(ctm[3]);
  }
  if (r0 > r1) {
    t *= r0;
  } else {
    t *= r1;
  }
  if (t < 1) {
    n = 3;
  } else {
    n = (int)(M_PI / acos(1 - 0.1 / t));
    if (n < 3) {
      n = 3;
    } else if (n > 200) {
      n = 200;
    }
  }

  // Traverse the t axis and do the shading.
  //
  // This generates and fills a series of rings.  Each ring is defined
  // by two circles:
  //   sa, ta, xa, ya, ra, colorA
  //   sb, tb, xb, yb, rb, colorB
  //
  // The s/t axis is divided into radialMaxSplits parts; these parts
  // are combined as much as possible while respecting the
  // radialColorDelta parameter.

  // setup for the start circle
  ia = 0;
  sa = sMin;
  ta = t0 + sa * (t1 - t0);
  xa = x0 + sa * (x1 - x0);
  ya = y0 + sa * (y1 - y0);
  ra = r0 + sa * (r1 - r0);
  if (ta < t0) {
    shading->getColor(t0, &colorA);
  } else if (ta > t1) {
    shading->getColor(t1, &colorA);
  } else {
    shading->getColor(ta, &colorA);
  }

  while (ia < radialMaxSplits) {

    // go as far along the t axis (toward t1) as we can, such that the
    // color difference is within the tolerance (radialColorDelta) --
    // this uses bisection (between the current value, t, and t1),
    // limited to radialMaxSplits points along the t axis; require at
    // least one split to avoid problems when the innermost and
    // outermost colors are the same
    ib = radialMaxSplits;
    sb = sMin + ((double)ib / (double)radialMaxSplits) * (sMax - sMin);
    tb = t0 + sb * (t1 - t0);
    if (tb < t0) {
      shading->getColor(t0, &colorB);
    } else if (tb > t1) {
      shading->getColor(t1, &colorB);
    } else {
      shading->getColor(tb, &colorB);
    }
    while (ib - ia > 1) {
      for (k = 0; k < nComps; ++k) {
       if (fabs(colorB.c[k] - colorA.c[k]) > radialColorDelta) {
         break;
       }
      }
      if (k == nComps && ib < radialMaxSplits) {
       break;
      }
      ib = (ia + ib) / 2;
      sb = sMin + ((double)ib / (double)radialMaxSplits) * (sMax - sMin);
      tb = t0 + sb * (t1 - t0);
      if (tb < t0) {
       shading->getColor(t0, &colorB);
      } else if (tb > t1) {
       shading->getColor(t1, &colorB);
      } else {
       shading->getColor(tb, &colorB);
      }
    }

    // compute center and radius of the circle
    xb = x0 + sb * (x1 - x0);
    yb = y0 + sb * (y1 - y0);
    rb = r0 + sb * (r1 - r0);

    // use the average of the colors at the two circles
    for (k = 0; k < nComps; ++k) {
      colorA.c[k] = 0.5 * (colorA.c[k] + colorB.c[k]);
    }
    state->setFillColor(&colorA);
    out->updateFillColor(state);

    // construct path for first circle
    state->moveTo(xa + ra, ya);
    for (k = 1; k < n; ++k) {
      angle = ((double)k / (double)n) * 2 * M_PI;
      state->lineTo(xa + ra * cos(angle), ya + ra * sin(angle));
    }
    state->closePath();

    // construct and append path for second circle
    state->moveTo(xb + rb, yb);
    for (k = 1; k < n; ++k) {
      angle = ((double)k / (double)n) * 2 * M_PI;
      state->lineTo(xb + rb * cos(angle), yb + rb * sin(angle));
    }
    state->closePath();

    // fill the ring
    out->eoFill(state);
    state->clearPath();

    // step to the next value of t
    ia = ib;
    sa = sb;
    ta = tb;
    xa = xb;
    ya = yb;
    ra = rb;
    colorA = colorB;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void Gfx::doShadingPatternFill ( GfxShadingPattern sPat,
GBool  eoFill 
) [private]

Definition at line 1406 of file Gfx.cc.

                                                                    {
  GfxShading *shading;
  GfxPath *savedPath;
  double *ctm, *btm, *ptm;
  double m[6], ictm[6], m1[6];
  double xMin, yMin, xMax, yMax;
  double det;

  shading = sPat->getShading();

  // save current graphics state
  savedPath = state->getPath()->copy();
  saveState();

  // clip to bbox
  if (shading->getHasBBox()) {
    shading->getBBox(&xMin, &yMin, &xMax, &yMax);
    state->moveTo(xMin, yMin);
    state->lineTo(xMax, yMin);
    state->lineTo(xMax, yMax);
    state->lineTo(xMin, yMax);
    state->closePath();
    state->clip();
    out->clip(state);
    state->clearPath();
  }

  // clip to current path
  state->clip();
  if (eoFill) {
    out->eoClip(state);
  } else {
    out->clip(state);
  }
  state->clearPath();

  // construct a (pattern space) -> (current space) transform matrix
  ctm = state->getCTM();
  btm = baseMatrix;
  ptm = sPat->getMatrix();
  // iCTM = invert CTM
  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;
  // m1 = PTM * BTM = PTM * base transform matrix
  m1[0] = ptm[0] * btm[0] + ptm[1] * btm[2];
  m1[1] = ptm[0] * btm[1] + ptm[1] * btm[3];
  m1[2] = ptm[2] * btm[0] + ptm[3] * btm[2];
  m1[3] = ptm[2] * btm[1] + ptm[3] * btm[3];
  m1[4] = ptm[4] * btm[0] + ptm[5] * btm[2] + btm[4];
  m1[5] = ptm[4] * btm[1] + ptm[5] * btm[3] + btm[5];
  // m = m1 * iCTM = (PTM * BTM) * (iCTM)
  m[0] = m1[0] * ictm[0] + m1[1] * ictm[2];
  m[1] = m1[0] * ictm[1] + m1[1] * ictm[3];
  m[2] = m1[2] * ictm[0] + m1[3] * ictm[2];
  m[3] = m1[2] * ictm[1] + m1[3] * ictm[3];
  m[4] = m1[4] * ictm[0] + m1[5] * ictm[2] + ictm[4];
  m[5] = m1[4] * ictm[1] + m1[5] * ictm[3] + ictm[5];

  // set the new matrix
  state->concatCTM(m[0], m[1], m[2], m[3], m[4], m[5]);
  out->updateCTM(state, m[0], m[1], m[2], m[3], m[4], m[5]);

  // set the color space
  state->setFillColorSpace(shading->getColorSpace()->copy());

  // do shading type-specific operations
  switch (shading->getType()) {
  case 1:
    doFunctionShFill((GfxFunctionShading *)shading);
    break;
  case 2:
    doAxialShFill((GfxAxialShading *)shading);
    break;
  case 3:
    doRadialShFill((GfxRadialShading *)shading);
    break;
  }

  // restore graphics state
  restoreState();
  state->setPath(savedPath);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void Gfx::doShowText ( GString s) [private]

Definition at line 2303 of file Gfx.cc.

                               {
  GfxFont *font;
  int wMode;
  double riseX, riseY;
  CharCode code;
  Unicode u[8];
  double x, y, dx, dy, dx2, dy2, curX, curY, tdx, tdy, lineX, lineY;
  double originX, originY, tOriginX, tOriginY;
  double oldCTM[6], newCTM[6];
  double *mat;
  Object charProc;
  Dict *resDict;
  Parser *oldParser;
  char *p;
  int len, n, uLen, nChars, nSpaces, i;

  if (fontChanged) {
    out->updateFont(state);
    fontChanged = gFalse;
  }
  font = state->getFont();
  wMode = font->getWMode();

  if (out->useDrawChar()) {
    out->beginString(state, s);
  }

  // handle a Type 3 char
  if (font->getType() == fontType3 && out->interpretType3Chars()) {
    mat = state->getCTM();
    for (i = 0; i < 6; ++i) {
      oldCTM[i] = mat[i];
    }
    mat = state->getTextMat();
    newCTM[0] = mat[0] * oldCTM[0] + mat[1] * oldCTM[2];
    newCTM[1] = mat[0] * oldCTM[1] + mat[1] * oldCTM[3];
    newCTM[2] = mat[2] * oldCTM[0] + mat[3] * oldCTM[2];
    newCTM[3] = mat[2] * oldCTM[1] + mat[3] * oldCTM[3];
    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[1] *= state->getFontSize();
    newCTM[2] *= 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);
      saveState();
      state->setCTM(newCTM[0], newCTM[1], newCTM[2], newCTM[3], x, y);
      //~ out->updateCTM(???)
      if (!out->beginType3Char(state, curX + riseX, curY + riseY, tdx, tdy,
                            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();
      }
      restoreState();
      // 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();
}

Here is the caller graph for this function:

void Gfx::doTilingPatternFill ( GfxTilingPattern tPat,
GBool  eoFill 
) [private]

Definition at line 1254 of file Gfx.cc.

                                                                  {
  GfxPatternColorSpace *patCS;
  GfxColorSpace *cs;
  GfxPath *savedPath;
  double xMin, yMin, xMax, yMax, x, y, x1, y1;
  double cxMin, cyMin, cxMax, cyMax;
  int xi0, yi0, xi1, yi1, xi, yi;
  double *ctm, *btm, *ptm;
  double m[6], ictm[6], m1[6], imb[6];
  double det;
  double xstep, ystep;
  int i;

  // get color space
  patCS = (GfxPatternColorSpace *)state->getFillColorSpace();

  // construct a (pattern space) -> (current space) transform matrix
  ctm = state->getCTM();
  btm = baseMatrix;
  ptm = tPat->getMatrix();
  // iCTM = invert CTM
  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;
  // m1 = PTM * BTM = PTM * base transform matrix
  m1[0] = ptm[0] * btm[0] + ptm[1] * btm[2];
  m1[1] = ptm[0] * btm[1] + ptm[1] * btm[3];
  m1[2] = ptm[2] * btm[0] + ptm[3] * btm[2];
  m1[3] = ptm[2] * btm[1] + ptm[3] * btm[3];
  m1[4] = ptm[4] * btm[0] + ptm[5] * btm[2] + btm[4];
  m1[5] = ptm[4] * btm[1] + ptm[5] * btm[3] + btm[5];
  // m = m1 * iCTM = (PTM * BTM) * (iCTM)
  m[0] = m1[0] * ictm[0] + m1[1] * ictm[2];
  m[1] = m1[0] * ictm[1] + m1[1] * ictm[3];
  m[2] = m1[2] * ictm[0] + m1[3] * ictm[2];
  m[3] = m1[2] * ictm[1] + m1[3] * ictm[3];
  m[4] = m1[4] * ictm[0] + m1[5] * ictm[2] + ictm[4];
  m[5] = m1[4] * ictm[1] + m1[5] * ictm[3] + ictm[5];

  // construct a (base space) -> (pattern space) transform matrix
  det = 1 / (m1[0] * m1[3] - m1[1] * m1[2]);
  imb[0] = m1[3] * det;
  imb[1] = -m1[1] * det;
  imb[2] = -m1[2] * det;
  imb[3] = m1[0] * det;
  imb[4] = (m1[2] * m1[5] - m1[3] * m1[4]) * det;
  imb[5] = (m1[1] * m1[4] - m1[0] * m1[5]) * det;

  // save current graphics state
  savedPath = state->getPath()->copy();
  saveState();

  // set underlying color space (for uncolored tiling patterns); set
  // various other parameters (stroke color, line width) to match
  // Adobe's behavior
  if (tPat->getPaintType() == 2 && (cs = patCS->getUnder())) {
    state->setFillColorSpace(cs->copy());
    state->setStrokeColorSpace(cs->copy());
    state->setStrokeColor(state->getFillColor());
  } else {
    state->setFillColorSpace(new GfxDeviceGrayColorSpace());
    state->setStrokeColorSpace(new GfxDeviceGrayColorSpace());
  }
  state->setFillPattern(NULL);
  out->updateFillColor(state);
  state->setStrokePattern(NULL);
  out->updateStrokeColor(state);
  state->setLineWidth(0);
  out->updateLineWidth(state);

  // clip to current path
  state->clip();
  if (eoFill) {
    out->eoClip(state);
  } else {
    out->clip(state);
  }
  state->clearPath();

  // transform clip region bbox to pattern space
  state->getClipBBox(&cxMin, &cyMin, &cxMax, &cyMax);
  xMin = xMax = cxMin * imb[0] + cyMin * imb[2] + imb[4];
  yMin = yMax = cxMin * imb[1] + cyMin * imb[3] + imb[5];
  x1 = cxMin * imb[0] + cyMax * imb[2] + imb[4];
  y1 = cxMin * imb[1] + cyMax * imb[3] + imb[5];
  if (x1 < xMin) {
    xMin = x1;
  } else if (x1 > xMax) {
    xMax = x1;
  }
  if (y1 < yMin) {
    yMin = y1;
  } else if (y1 > yMax) {
    yMax = y1;
  }
  x1 = cxMax * imb[0] + cyMin * imb[2] + imb[4];
  y1 = cxMax * imb[1] + cyMin * imb[3] + imb[5];
  if (x1 < xMin) {
    xMin = x1;
  } else if (x1 > xMax) {
    xMax = x1;
  }
  if (y1 < yMin) {
    yMin = y1;
  } else if (y1 > yMax) {
    yMax = y1;
  }
  x1 = cxMax * imb[0] + cyMax * imb[2] + imb[4];
  y1 = cxMax * imb[1] + cyMax * imb[3] + imb[5];
  if (x1 < xMin) {
    xMin = x1;
  } else if (x1 > xMax) {
    xMax = x1;
  }
  if (y1 < yMin) {
    yMin = y1;
  } else if (y1 > yMax) {
    yMax = y1;
  }

  // draw the pattern
  //~ this should treat negative steps differently -- start at right/top
  //~ edge instead of left/bottom (?)
  xstep = fabs(tPat->getXStep());
  ystep = fabs(tPat->getYStep());
  xi0 = (int)floor((xMin - tPat->getBBox()[0]) / xstep);
  xi1 = (int)ceil((xMax - tPat->getBBox()[0]) / xstep);
  yi0 = (int)floor((yMin - tPat->getBBox()[1]) / ystep);
  yi1 = (int)ceil((yMax - tPat->getBBox()[1]) / ystep);
  for (i = 0; i < 4; ++i) {
    m1[i] = m[i];
  }
  for (yi = yi0; yi < yi1; ++yi) {
    for (xi = xi0; xi < xi1; ++xi) {
      x = xi * xstep;
      y = yi * ystep;
      m1[4] = x * m[0] + y * m[2] + m[4];
      m1[5] = x * m[1] + y * m[3] + m[5];
      doForm1(tPat->getContentStream(), tPat->getResDict(),
             m1, tPat->getBBox());
    }
  }

  // restore graphics state
  restoreState();
  state->setPath(savedPath);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void Gfx::execOp ( Object cmd,
Object  args[],
int  numArgs 
) [private]

Definition at line 616 of file Gfx.cc.

                                                        {
  Operator *op;
  char *name;
  Object *argPtr;
  int i;

  // find operator
  name = cmd->getCmd();
  if (!(op = findOp(name))) {
    if (ignoreUndef == 0)
      error(getPos(), "Unknown operator '%s'", name);
    return;
  }

  // type check args
  argPtr = args;
  if (op->numArgs >= 0) {
    if (numArgs < op->numArgs) {
      error(getPos(), "Too few (%d) args to '%s' operator", numArgs, name);
      return;
    }
    if (numArgs > op->numArgs) {
#if 0
      error(getPos(), "Too many (%d) args to '%s' operator", numArgs, name);
#endif
      argPtr += numArgs - op->numArgs;
      numArgs = op->numArgs;
    }
  } else {
    if (numArgs > -op->numArgs) {
      error(getPos(), "Too many (%d) args to '%s' operator",
           numArgs, name);
      return;
    }
  }
  for (i = 0; i < numArgs; ++i) {
    if (!checkArg(&argPtr[i], op->tchk[i])) {
      error(getPos(), "Arg #%d to '%s' operator is wrong type (%s)",
           i, name, argPtr[i].getTypeName());
      return;
    }
  }

  // do it
  (this->*op->func)(argPtr, numArgs);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Operator * Gfx::findOp ( char *  name) [private]

Definition at line 663 of file Gfx.cc.

                                {
  int a, b, m, cmp;

  a = -1;
  b = numOps;
  // invariant: opTab[a] < name < opTab[b]
  while (b - a > 1) {
    m = (a + b) / 2;
    cmp = strcmp(opTab[m].name, name);
    if (cmp < 0)
      a = m;
    else if (cmp > 0)
      b = m;
    else
      a = b = m;
  }
  if (cmp != 0)
    return NULL;
  return &opTab[a];
}

Here is the call graph for this function:

Here is the caller graph for this function:

int Gfx::getPos ( ) [private]

Definition at line 699 of file Gfx.cc.

                {
  return parser ? parser->getPos() : -1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void Gfx::go ( GBool  topLevel) [private]

Definition at line 528 of file Gfx.cc.

                           {
  Object obj;
  Object args[maxArgs];
  int numArgs, i;
  int lastAbortCheck;

  // scan a sequence of objects
  updateLevel = lastAbortCheck = 0;
  numArgs = 0;
  parser->getObj(&obj);
  while (!obj.isEOF()) {

    // got a command - execute it
    if (obj.isCmd()) {
      if (printCommands) {
       obj.print(stdout);
       for (i = 0; i < numArgs; ++i) {
         printf(" ");
         args[i].print(stdout);
       }
       printf("\n");
       fflush(stdout);
      }
      execOp(&obj, args, numArgs);
      obj.free();
      for (i = 0; i < numArgs; ++i)
       args[i].free();
      numArgs = 0;

      // periodically update display
      if (++updateLevel >= 20000) {
       out->dump();
       updateLevel = 0;
      }

      // check for an abort
      if (abortCheckCbk) {
       if (updateLevel - lastAbortCheck > 10) {
         if ((*abortCheckCbk)(abortCheckCbkData)) {
           break;
         }
         lastAbortCheck = updateLevel;
       }
      }

    // got an argument - save it
    } else if (numArgs < maxArgs) {
      args[numArgs++] = obj;

    // too many arguments - something is wrong
    } else {
      error(getPos(), "Too many args in content stream");
      if (printCommands) {
       printf("throwing away arg: ");
       obj.print(stdout);
       printf("\n");
       fflush(stdout);
      }
      obj.free();
    }

    // grab the next object
    parser->getObj(&obj);
  }
  obj.free();

  // args at end with no command
  if (numArgs > 0) {
    error(getPos(), "Leftover args in content stream");
    if (printCommands) {
      printf("%d leftovers:", numArgs);
      for (i = 0; i < numArgs; ++i) {
       printf(" ");
       args[i].print(stdout);
      }
      printf("\n");
      fflush(stdout);
    }
    for (i = 0; i < numArgs; ++i)
      args[i].free();
  }

  // update display
  if (topLevel && updateLevel > 0) {
    out->dump();
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void Gfx::opBeginIgnoreUndef ( Object  args[],
int  numArgs 
) [private]

Definition at line 3019 of file Gfx.cc.

                                                       {
  ++ignoreUndef;
}
void Gfx::opBeginImage ( Object  args[],
int  numArgs 
) [private]

Definition at line 2931 of file Gfx.cc.

                                                 {
  Stream *str;
  int c1, c2;

  // build dict/stream
  str = buildImageStream();

  // display the image
  if (str) {
    doImage(NULL, str, gTrue);
  
    // skip 'EI' tag
    c1 = str->getBaseStream()->getChar();
    c2 = str->getBaseStream()->getChar();
    while (!(c1 == 'E' && c2 == 'I') && c2 != EOF) {
      c1 = c2;
      c2 = str->getBaseStream()->getChar();
    }
    delete str;
  }
}

Here is the call graph for this function:

void Gfx::opBeginMarkedContent ( Object  args[],
int  numArgs 
) [private]

Definition at line 3032 of file Gfx.cc.

                                                         {
  if (printCommands) {
    printf("  marked content: %s ", args[0].getName());
    if (numArgs == 2)
      args[2].print(stdout);
    printf("\n");
    fflush(stdout);
  }
}

Here is the call graph for this function:

void Gfx::opBeginText ( Object  args[],
int  numArgs 
) [private]

Definition at line 2123 of file Gfx.cc.

Here is the call graph for this function:

void Gfx::opClip ( Object  args[],
int  numArgs 
) [private]

Definition at line 2111 of file Gfx.cc.

                                           {
  clip = clipNormal;
}
void Gfx::opCloseEOFillStroke ( Object  args[],
int  numArgs 
) [private]

Definition at line 1210 of file Gfx.cc.

                                                        {
  if (!state->isCurPt()) {
    //error(getPos(), "No path in closepath/eofill/stroke");
    return;
  }
  if (state->isPath()) {
    state->closePath();
    if (state->getFillColorSpace()->getMode() == csPattern) {
      doPatternFill(gTrue);
    } else {
      out->eoFill(state);
    }
    out->stroke(state);
  }
  doEndPath();
}

Here is the call graph for this function:

void Gfx::opCloseFillStroke ( Object  args[],
int  numArgs 
) [private]

Definition at line 1177 of file Gfx.cc.

                                                      {
  if (!state->isCurPt()) {
    //error(getPos(), "No path in closepath/fill/stroke");
    return;
  }
  if (state->isPath()) {
    state->closePath();
    if (state->getFillColorSpace()->getMode() == csPattern) {
      doPatternFill(gFalse);
    } else {
      out->fill(state);
    }
    out->stroke(state);
  }
  doEndPath();
}

Here is the call graph for this function:

void Gfx::opClosePath ( Object  args[],
int  numArgs 
) [private]

Definition at line 1093 of file Gfx.cc.

                                                {
  if (!state->isCurPt()) {
    error(getPos(), "No current point in closepath");
    return;
  }
  state->closePath();
}

Here is the call graph for this function:

void Gfx::opCloseStroke ( Object  args[],
int  numArgs 
) [private]

Definition at line 1119 of file Gfx.cc.

                                                  {
  if (!state->isCurPt()) {
    //error(getPos(), "No path in closepath/stroke");
    return;
  }
  if (state->isPath()) {
    state->closePath();
    out->stroke(state);
  }
  doEndPath();
}

Here is the call graph for this function:

void Gfx::opConcat ( Object  args[],
int  numArgs 
) [private]

Definition at line 715 of file Gfx.cc.

                                             {
  state->concatCTM(args[0].getNum(), args[1].getNum(),
                 args[2].getNum(), args[3].getNum(),
                 args[4].getNum(), args[5].getNum());
  out->updateCTM(state, args[0].getNum(), args[1].getNum(),
               args[2].getNum(), args[3].getNum(),
               args[4].getNum(), args[5].getNum());
  fontChanged = gTrue;
}

Here is the call graph for this function:

void Gfx::opCurveTo ( Object  args[],
int  numArgs 
) [private]

Definition at line 1031 of file Gfx.cc.

                                              {
  double x1, y1, x2, y2, x3, y3;

  if (!state->isCurPt()) {
    error(getPos(), "No current point in curveto");
    return;
  }
  x1 = args[0].getNum();
  y1 = args[1].getNum();
  x2 = args[2].getNum();
  y2 = args[3].getNum();
  x3 = args[4].getNum();
  y3 = args[5].getNum();
  state->curveTo(x1, y1, x2, y2, x3, y3);
}

Here is the call graph for this function:

void Gfx::opCurveTo1 ( Object  args[],
int  numArgs 
) [private]

Definition at line 1047 of file Gfx.cc.

                                               {
  double x1, y1, x2, y2, x3, y3;

  if (!state->isCurPt()) {
    error(getPos(), "No current point in curveto1");
    return;
  }
  x1 = state->getCurX();
  y1 = state->getCurY();
  x2 = args[0].getNum();
  y2 = args[1].getNum();
  x3 = args[2].getNum();
  y3 = args[3].getNum();
  state->curveTo(x1, y1, x2, y2, x3, y3);
}

Here is the call graph for this function:

void Gfx::opCurveTo2 ( Object  args[],
int  numArgs 
) [private]

Definition at line 1063 of file Gfx.cc.

                                               {
  double x1, y1, x2, y2, x3, y3;

  if (!state->isCurPt()) {
    error(getPos(), "No current point in curveto2");
    return;
  }
  x1 = args[0].getNum();
  y1 = args[1].getNum();
  x2 = args[2].getNum();
  y2 = args[3].getNum();
  x3 = x2;
  y3 = y2;
  state->curveTo(x1, y1, x2, y2, x3, y3);
}

Here is the call graph for this function:

void Gfx::opEndIgnoreUndef ( Object  args[],
int  numArgs 
) [private]

Definition at line 3023 of file Gfx.cc.

                                                     {
  if (ignoreUndef > 0)
    --ignoreUndef;
}
void Gfx::opEndImage ( Object  args[],
int  numArgs 
) [private]

Definition at line 2997 of file Gfx.cc.

                                               {
  error(getPos(), "Internal: got 'EI' operator");
}

Here is the call graph for this function:

void Gfx::opEndMarkedContent ( Object  args[],
int  numArgs 
) [private]

Definition at line 3042 of file Gfx.cc.

                                                       {
}
void Gfx::opEndPath ( Object  args[],
int  numArgs 
) [private]

Definition at line 1105 of file Gfx.cc.

                                              {
  doEndPath();
}

Here is the call graph for this function:

void Gfx::opEndText ( Object  args[],
int  numArgs 
) [private]

Definition at line 2131 of file Gfx.cc.

Here is the call graph for this function:

void Gfx::opEOClip ( Object  args[],
int  numArgs 
) [private]

Definition at line 2115 of file Gfx.cc.

                                             {
  clip = clipEO;
}
void Gfx::opEOFill ( Object  args[],
int  numArgs 
) [private]

Definition at line 1146 of file Gfx.cc.

                                             {
  if (!state->isCurPt()) {
    //error(getPos(), "No path in eofill");
    return;
  }
  if (state->isPath()) {
    if (state->getFillColorSpace()->getMode() == csPattern) {
      doPatternFill(gTrue);
    } else {
      out->eoFill(state);
    }
  }
  doEndPath();
}

Here is the call graph for this function:

void Gfx::opEOFillStroke ( Object  args[],
int  numArgs 
) [private]

Definition at line 1194 of file Gfx.cc.

                                                   {
  if (!state->isCurPt()) {
    //error(getPos(), "No path in eofill/stroke");
    return;
  }
  if (state->isPath()) {
    if (state->getFillColorSpace()->getMode() == csPattern) {
      doPatternFill(gTrue);
    } else {
      out->eoFill(state);
    }
    out->stroke(state);
  }
  doEndPath();
}

Here is the call graph for this function:

void Gfx::opFill ( Object  args[],
int  numArgs 
) [private]

Definition at line 1131 of file Gfx.cc.

                                           {
  if (!state->isCurPt()) {
    //error(getPos(), "No path in fill");
    return;
  }
  if (state->isPath()) {
    if (state->getFillColorSpace()->getMode() == csPattern) {
      doPatternFill(gFalse);
    } else {
      out->fill(state);
    }
  }
  doEndPath();
}

Here is the call graph for this function:

void Gfx::opFillStroke ( Object  args[],
int  numArgs 
) [private]

Definition at line 1161 of file Gfx.cc.

                                                 {
  if (!state->isCurPt()) {
    //error(getPos(), "No path in fill/stroke");
    return;
  }
  if (state->isPath()) {
    if (state->getFillColorSpace()->getMode() == csPattern) {
      doPatternFill(gFalse);
    } else {
      out->fill(state);
    }
    out->stroke(state);
  }
  doEndPath();
}

Here is the call graph for this function:

void Gfx::opImageData ( Object  args[],
int  numArgs 
) [private]

Definition at line 2993 of file Gfx.cc.

                                                {
  error(getPos(), "Internal: got 'ID' operator");
}

Here is the call graph for this function:

void Gfx::opLineTo ( Object  args[],
int  numArgs 
) [private]

Definition at line 1023 of file Gfx.cc.

                                             {
  if (!state->isCurPt()) {
    error(getPos(), "No current point in lineto");
    return;
  }
  state->lineTo(args[0].getNum(), args[1].getNum());
}

Here is the call graph for this function:

void Gfx::opMarkPoint ( Object  args[],
int  numArgs 
) [private]

Definition at line 3045 of file Gfx.cc.

                                                {
  if (printCommands) {
    printf("  mark point: %s ", args[0].getName());
    if (numArgs == 2)
      args[2].print(stdout);
    printf("\n");
    fflush(stdout);
  }
}

Here is the call graph for this function:

void Gfx::opMoveSetShowText ( Object  args[],
int  numArgs 
) [private]

Definition at line 2255 of file Gfx.cc.

                                                      {
  double tx, ty;

  if (!state->getFont()) {
    error(getPos(), "No font in move/set/show");
    return;
  }
  state->setWordSpace(args[0].getNum());
  state->setCharSpace(args[1].getNum());
  tx = state->getLineX();
  ty = state->getLineY() - state->getLeading();
  state->textMoveTo(tx, ty);
  out->updateWordSpace(state);
  out->updateCharSpace(state);
  out->updateTextPos(state);
  doShowText(args[2].getString());
}

Here is the call graph for this function:

void Gfx::opMoveShowText ( Object  args[],
int  numArgs 
) [private]

Definition at line 2241 of file Gfx.cc.

                                                   {
  double tx, ty;

  if (!state->getFont()) {
    error(getPos(), "No font in move/show");
    return;
  }
  tx = state->getLineX();
  ty = state->getLineY() - state->getLeading();
  state->textMoveTo(tx, ty);
  out->updateTextPos(state);
  doShowText(args[0].getString());
}

Here is the call graph for this function:

void Gfx::opMoveTo ( Object  args[],
int  numArgs 
) [private]

Definition at line 1019 of file Gfx.cc.

                                             {
  state->moveTo(args[0].getNum(), args[1].getNum());
}

Here is the call graph for this function:

void Gfx::opRectangle ( Object  args[],
int  numArgs 
) [private]

Definition at line 1079 of file Gfx.cc.

                                                {
  double x, y, w, h;

  x = args[0].getNum();
  y = args[1].getNum();
  w = args[2].getNum();
  h = args[3].getNum();
  state->moveTo(x, y);
  state->lineTo(x + w, y);
  state->lineTo(x + w, y + h);
  state->lineTo(x, y + h);
  state->closePath();
}

Here is the call graph for this function:

void Gfx::opRestore ( Object  args[],
int  numArgs 
) [private]

Definition at line 711 of file Gfx.cc.

                                              {
  restoreState();
}

Here is the call graph for this function:

void Gfx::opSave ( Object  args[],
int  numArgs 
) [private]

Definition at line 707 of file Gfx.cc.

                                           {
  saveState();
}

Here is the call graph for this function:

void Gfx::opSetCacheDevice ( Object  args[],
int  numArgs 
) [private]

Definition at line 3009 of file Gfx.cc.

                                                     {
  out->type3D1(state, args[0].getNum(), args[1].getNum(),
              args[2].getNum(), args[3].getNum(),
              args[4].getNum(), args[5].getNum());
}

Here is the call graph for this function:

void Gfx::opSetCharSpacing ( Object  args[],
int  numArgs 
) [private]

Definition at line 2139 of file Gfx.cc.

                                                     {
  state->setCharSpace(args[0].getNum());
  out->updateCharSpace(state);
}

Here is the call graph for this function:

void Gfx::opSetCharWidth ( Object  args[],
int  numArgs 
) [private]

Definition at line 3005 of file Gfx.cc.

                                                   {
  out->type3D0(state, args[0].getNum(), args[1].getNum());
}

Here is the call graph for this function:

void Gfx::opSetDash ( Object  args[],
int  numArgs 
) [private]

Definition at line 725 of file Gfx.cc.

                                              {
  Array *a;
  int length;
  Object obj;
  double *dash;
  int i;

  a = args[0].getArray();
  length = a->getLength();
  if (length == 0) {
    dash = NULL;
  } else {
    dash = (double *)gmalloc(length * sizeof(double));
    for (i = 0; i < length; ++i) {
      dash[i] = a->get(i, &obj)->getNum();
      obj.free();
    }
  }
  state->setLineDash(dash, length, args[1].getNum());
  out->updateLineDash(state);
}

Here is the call graph for this function:

void Gfx::opSetExtGState ( Object  args[],
int  numArgs 
) [private]

Definition at line 772 of file Gfx.cc.

                                                   {
  Object obj1, obj2;

  if (!res->lookupGState(args[0].getName(), &obj1)) {
    return;
  }
  if (!obj1.isDict()) {
    error(getPos(), "ExtGState '%s' is wrong type", args[0].getName());
    obj1.free();
    return;
  }
  if (obj1.dictLookup("ca", &obj2)->isNum()) {
    state->setFillOpacity(obj2.getNum());
    out->updateFillOpacity(state);
  }
  obj2.free();
  if (obj1.dictLookup("CA", &obj2)->isNum()) {
    state->setStrokeOpacity(obj2.getNum());
    out->updateStrokeOpacity(state);
  }
  obj2.free();
  obj1.free();
}

Here is the call graph for this function:

void Gfx::opSetFillCMYKColor ( Object  args[],
int  numArgs 
) [private]

Definition at line 823 of file Gfx.cc.

                                                       {
  GfxColor color;
  int i;

  state->setFillPattern(NULL);
  state->setFillColorSpace(new GfxDeviceCMYKColorSpace());
  for (i = 0; i < 4; ++i) {
    color.c[i] = args[i].getNum();
  }
  state->setFillColor(&color);
  out->updateFillColor(state);
}

Here is the call graph for this function:

void Gfx::opSetFillColor ( Object  args[],
int  numArgs 
) [private]

Definition at line 927 of file Gfx.cc.

                                                   {
  GfxColor color;
  int i;

  state->setFillPattern(NULL);
  for (i = 0; i < numArgs; ++i) {
    color.c[i] = args[i].getNum();
  }
  state->setFillColor(&color);
  out->updateFillColor(state);
}

Here is the call graph for this function:

void Gfx::opSetFillColorN ( Object  args[],
int  numArgs 
) [private]

Definition at line 951 of file Gfx.cc.

                                                    {
  GfxColor color;
  GfxPattern *pattern;
  int i;

  if (state->getFillColorSpace()->getMode() == csPattern) {
    if (numArgs > 1) {
      for (i = 0; i < numArgs && i < 4; ++i) {
       if (args[i].isNum()) {
         color.c[i] = args[i].getNum();
       }
      }
      state->setFillColor(&color);
      out->updateFillColor(state);
    }
    if (args[numArgs-1].isName() &&
       (pattern = res->lookupPattern(args[numArgs-1].getName()))) {
      state->setFillPattern(pattern);
    }

  } else {
    state->setFillPattern(NULL);
    for (i = 0; i < numArgs && i < 4; ++i) {
      if (args[i].isNum()) {
       color.c[i] = args[i].getNum();
      }
    }
    state->setFillColor(&color);
    out->updateFillColor(state);
  }
}

Here is the call graph for this function:

void Gfx::opSetFillColorSpace ( Object  args[],
int  numArgs 
) [private]

Definition at line 875 of file Gfx.cc.

                                                        {
  Object obj;
  GfxColorSpace *colorSpace;
  GfxColor color;
  int i;

  state->setFillPattern(NULL);
  res->lookupColorSpace(args[0].getName(), &obj);
  if (obj.isNull()) {
    colorSpace = GfxColorSpace::parse(&args[0]);
  } else {
    colorSpace = GfxColorSpace::parse(&obj);
  }
  obj.free();
  if (colorSpace) {
    state->setFillColorSpace(colorSpace);
  } else {
    error(getPos(), "Bad color space (fill)");
  }
  for (i = 0; i < gfxColorMaxComps; ++i) {
    color.c[i] = 0;
  }
  state->setFillColor(&color);
  out->updateFillColor(state);
}

Here is the call graph for this function:

void Gfx::opSetFillGray ( Object  args[],
int  numArgs 
) [private]

Definition at line 803 of file Gfx.cc.

Here is the call graph for this function:

void Gfx::opSetFillRGBColor ( Object  args[],
int  numArgs 
) [private]

Definition at line 849 of file Gfx.cc.

                                                      {
  GfxColor color;
  int i;

  state->setFillPattern(NULL);
  state->setFillColorSpace(new GfxDeviceRGBColorSpace());
  for (i = 0; i < 3; ++i) {
    color.c[i] = args[i].getNum();
  }
  state->setFillColor(&color);
  out->updateFillColor(state);
}

Here is the call graph for this function:

void Gfx::opSetFlat ( Object  args[],
int  numArgs 
) [private]

Definition at line 747 of file Gfx.cc.

                                              {
  state->setFlatness((int)args[0].getNum());
  out->updateFlatness(state);
}

Here is the call graph for this function:

void Gfx::opSetFont ( Object  args[],
int  numArgs 
) [private]

Definition at line 2144 of file Gfx.cc.

                                              {
  GfxFont *font;

  if (!(font = res->lookupFont(args[0].getName()))) {
    return;
  }
  if (printCommands) {
    printf("  font: tag=%s name='%s' %g\n",
          font->getTag()->getCString(),
          font->getName() ? font->getName()->getCString() : "???",
          args[1].getNum());
    fflush(stdout);
  }
  state->setFont(font, args[1].getNum());
  fontChanged = gTrue;
}

Here is the call graph for this function:

void Gfx::opSetHorizScaling ( Object  args[],
int  numArgs 
) [private]

Definition at line 2180 of file Gfx.cc.

Here is the call graph for this function:

void Gfx::opSetLineCap ( Object  args[],
int  numArgs 
) [private]

Definition at line 757 of file Gfx.cc.

Here is the call graph for this function:

void Gfx::opSetLineJoin ( Object  args[],
int  numArgs 
) [private]

Definition at line 752 of file Gfx.cc.

Here is the call graph for this function:

void Gfx::opSetLineWidth ( Object  args[],
int  numArgs 
) [private]

Definition at line 767 of file Gfx.cc.

                                                   {
  state->setLineWidth(args[0].getNum());
  out->updateLineWidth(state);
}

Here is the call graph for this function:

void Gfx::opSetMiterLimit ( Object  args[],
int  numArgs 
) [private]

Definition at line 762 of file Gfx.cc.

                                                    {
  state->setMiterLimit(args[0].getNum());
  out->updateMiterLimit(state);
}

Here is the call graph for this function:

void Gfx::opSetRenderingIntent ( Object  args[],
int  numArgs 
) [private]

Definition at line 796 of file Gfx.cc.

                                                         {
}
void Gfx::opSetStrokeCMYKColor ( Object  args[],
int  numArgs 
) [private]

Definition at line 836 of file Gfx.cc.

                                                         {
  GfxColor color;
  int i;

  state->setStrokePattern(NULL);
  state->setStrokeColorSpace(new GfxDeviceCMYKColorSpace());
  for (i = 0; i < 4; ++i) {
    color.c[i] = args[i].getNum();
  }
  state->setStrokeColor(&color);
  out->updateStrokeColor(state);
}

Here is the call graph for this function:

void Gfx::opSetStrokeColor ( Object  args[],
int  numArgs 
) [private]

Definition at line 939 of file Gfx.cc.

                                                     {
  GfxColor color;
  int i;

  state->setStrokePattern(NULL);
  for (i = 0; i < numArgs; ++i) {
    color.c[i] = args[i].getNum();
  }
  state->setStrokeColor(&color);
  out->updateStrokeColor(state);
}

Here is the call graph for this function:

void Gfx::opSetStrokeColorN ( Object  args[],
int  numArgs 
) [private]

Definition at line 983 of file Gfx.cc.

                                                      {
  GfxColor color;
  GfxPattern *pattern;
  int i;

  if (state->getStrokeColorSpace()->getMode() == csPattern) {
    if (numArgs > 1) {
      for (i = 0; i < numArgs && i < 4; ++i) {
       if (args[i].isNum()) {
         color.c[i] = args[i].getNum();
       }
      }
      state->setStrokeColor(&color);
      out->updateStrokeColor(state);
    }
    if (args[numArgs-1].isName() &&
       (pattern = res->lookupPattern(args[numArgs-1].getName()))) {
      state->setStrokePattern(pattern);
    }

  } else {
    state->setStrokePattern(NULL);
    for (i = 0; i < numArgs && i < 4; ++i) {
      if (args[i].isNum()) {
       color.c[i] = args[i].getNum();
      }
    }
    state->setStrokeColor(&color);
    out->updateStrokeColor(state);
  }
}

Here is the call graph for this function:

void Gfx::opSetStrokeColorSpace ( Object  args[],
int  numArgs 
) [private]

Definition at line 901 of file Gfx.cc.

                                                          {
  Object obj;
  GfxColorSpace *colorSpace;
  GfxColor color;
  int i;

  state->setStrokePattern(NULL);
  res->lookupColorSpace(args[0].getName(), &obj);
  if (obj.isNull()) {
    colorSpace = GfxColorSpace::parse(&args[0]);
  } else {
    colorSpace = GfxColorSpace::parse(&obj);
  }
  obj.free();
  if (colorSpace) {
    state->setStrokeColorSpace(colorSpace);
  } else {
    error(getPos(), "Bad color space (stroke)");
  }
  for (i = 0; i < gfxColorMaxComps; ++i) {
    color.c[i] = 0;
  }
  state->setStrokeColor(&color);
  out->updateStrokeColor(state);
}

Here is the call graph for this function:

void Gfx::opSetStrokeGray ( Object  args[],
int  numArgs 
) [private]

Definition at line 813 of file Gfx.cc.

Here is the call graph for this function:

void Gfx::opSetStrokeRGBColor ( Object  args[],
int  numArgs 
) [private]

Definition at line 862 of file Gfx.cc.

                                                        {
  GfxColor color;
  int i;

  state->setStrokePattern(NULL);
  state->setStrokeColorSpace(new GfxDeviceRGBColorSpace());
  for (i = 0; i < 3; ++i) {
    color.c[i] = args[i].getNum();
  }
  state->setStrokeColor(&color);
  out->updateStrokeColor(state);
}

Here is the call graph for this function:

void Gfx::opSetTextLeading ( Object  args[],
int  numArgs 
) [private]

Definition at line 2161 of file Gfx.cc.

                                                     {
  state->setLeading(args[0].getNum());
}

Here is the call graph for this function:

void Gfx::opSetTextMatrix ( Object  args[],
int  numArgs 
) [private]

Definition at line 2210 of file Gfx.cc.

                                                    {
  state->setTextMat(args[0].getNum(), args[1].getNum(),
                  args[2].getNum(), args[3].getNum(),
                  args[4].getNum(), args[5].getNum());
  state->textMoveTo(0, 0);
  out->updateTextMat(state);
  out->updateTextPos(state);
  fontChanged = gTrue;
}

Here is the call graph for this function:

void Gfx::opSetTextRender ( Object  args[],
int  numArgs 
) [private]

Definition at line 2165 of file Gfx.cc.

                                                    {
  state->setRender(args[0].getInt());
  out->updateRender(state);
}

Here is the call graph for this function:

void Gfx::opSetTextRise ( Object  args[],
int  numArgs 
) [private]

Definition at line 2170 of file Gfx.cc.

                                                  {
  state->setRise(args[0].getNum());
  out->updateRise(state);
}

Here is the call graph for this function:

void Gfx::opSetWordSpacing ( Object  args[],
int  numArgs 
) [private]

Definition at line 2175 of file Gfx.cc.

                                                     {
  state->setWordSpace(args[0].getNum());
  out->updateWordSpace(state);
}

Here is the call graph for this function:

void Gfx::opShFill ( Object  args[],
int  numArgs 
) [private]

Definition at line 1494 of file Gfx.cc.

                                             {
  GfxShading *shading;
  GfxPath *savedPath;
  double xMin, yMin, xMax, yMax;

  if (!(shading = res->lookupShading(args[0].getName()))) {
    return;
  }

  // save current graphics state
  savedPath = state->getPath()->copy();
  saveState();

  // clip to bbox
  if (shading->getHasBBox()) {
    shading->getBBox(&xMin, &yMin, &xMax, &yMax);
    state->moveTo(xMin, yMin);
    state->lineTo(xMax, yMin);
    state->lineTo(xMax, yMax);
    state->lineTo(xMin, yMax);
    state->closePath();
    state->clip();
    out->clip(state);
    state->clearPath();
  }

  // set the color space
  state->setFillColorSpace(shading->getColorSpace()->copy());

  // do shading type-specific operations
  switch (shading->getType()) {
  case 1:
    doFunctionShFill((GfxFunctionShading *)shading);
    break;
  case 2:
    doAxialShFill((GfxAxialShading *)shading);
    break;
  case 3:
    doRadialShFill((GfxRadialShading *)shading);
    break;
  }

  // restore graphics state
  restoreState();
  state->setPath(savedPath);

  delete shading;
}

Here is the call graph for this function:

void Gfx::opShowSpaceText ( Object  args[],
int  numArgs 
) [private]

Definition at line 2273 of file Gfx.cc.

                                                    {
  Array *a;
  Object obj;
  int wMode;
  int i;

  if (!state->getFont()) {
    error(getPos(), "No font in show/space");
    return;
  }
  wMode = state->getFont()->getWMode();
  a = args[0].getArray();
  for (i = 0; i < a->getLength(); ++i) {
    a->get(i, &obj);
    if (obj.isNum()) {
      if (wMode) {
       state->textShift(0, -obj.getNum() * 0.001 * state->getFontSize());
      } else {
       state->textShift(-obj.getNum() * 0.001 * state->getFontSize(), 0);
      }
      out->updateTextShift(state, obj.getNum());
    } else if (obj.isString()) {
      doShowText(obj.getString());
    } else {
      error(getPos(), "Element of show/space array must be number or string");
    }
    obj.free();
  }
}

Here is the call graph for this function:

void Gfx::opShowText ( Object  args[],
int  numArgs 
) [private]

Definition at line 2233 of file Gfx.cc.

                                               {
  if (!state->getFont()) {
    error(getPos(), "No font in show");
    return;
  }
  doShowText(args[0].getString());
}

Here is the call graph for this function:

void Gfx::opStroke ( Object  args[],
int  numArgs 
) [private]

Definition at line 1109 of file Gfx.cc.

                                             {
  if (!state->isCurPt()) {
    //error(getPos(), "No path in stroke");
    return;
  }
  if (state->isPath())
    out->stroke(state);
  doEndPath();
}

Here is the call graph for this function:

void Gfx::opTextMove ( Object  args[],
int  numArgs 
) [private]

Definition at line 2190 of file Gfx.cc.

                                               {
  double tx, ty;

  tx = state->getLineX() + args[0].getNum();
  ty = state->getLineY() + args[1].getNum();
  state->textMoveTo(tx, ty);
  out->updateTextPos(state);
}

Here is the call graph for this function:

void Gfx::opTextMoveSet ( Object  args[],
int  numArgs 
) [private]

Definition at line 2199 of file Gfx.cc.

                                                  {
  double tx, ty;

  tx = state->getLineX() + args[0].getNum();
  ty = args[1].getNum();
  state->setLeading(-ty);
  ty += state->getLineY();
  state->textMoveTo(tx, ty);
  out->updateTextPos(state);
}

Here is the call graph for this function:

void Gfx::opTextNextLine ( Object  args[],
int  numArgs 
) [private]

Definition at line 2220 of file Gfx.cc.

                                                   {
  double tx, ty;

  tx = state->getLineX();
  ty = state->getLineY() - state->getLeading();
  state->textMoveTo(tx, ty);
  out->updateTextPos(state);
}

Here is the call graph for this function:

void Gfx::opXObject ( Object  args[],
int  numArgs 
) [private]

Definition at line 2483 of file Gfx.cc.

                                              {
  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();
}

Here is the call graph for this function:

void Gfx::popResources ( ) [private]

Definition at line 3073 of file Gfx.cc.

                       {
  GfxResources *resPtr;

  resPtr = res->getNext();
  delete res;
  res = resPtr;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void Gfx::pushResources ( Dict resDict) [private]

Definition at line 3069 of file Gfx.cc.

                                     {
  res = new GfxResources(xref, resDict, res);
}

Here is the caller graph for this function:

Definition at line 3064 of file Gfx.cc.

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 3059 of file Gfx.cc.

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

Definition at line 151 of file Gfx.h.

Definition at line 152 of file Gfx.h.

double Gfx::baseMatrix[6] [private]

Definition at line 144 of file Gfx.h.

Definition at line 142 of file Gfx.h.

Definition at line 141 of file Gfx.h.

int Gfx::formDepth [private]

Definition at line 146 of file Gfx.h.

int Gfx::ignoreUndef [private]

Definition at line 143 of file Gfx.h.

Operator Gfx::opTab [static, private]

Definition at line 154 of file Gfx.h.

OutputDev* Gfx::out [private]

Definition at line 134 of file Gfx.h.

Parser* Gfx::parser [private]

Definition at line 148 of file Gfx.h.

Definition at line 136 of file Gfx.h.

GfxResources* Gfx::res [private]

Definition at line 137 of file Gfx.h.

GfxState* Gfx::state [private]

Definition at line 140 of file Gfx.h.

GBool Gfx::subPage [private]

Definition at line 135 of file Gfx.h.

int Gfx::updateLevel [private]

Definition at line 138 of file Gfx.h.

XRef* Gfx::xref [private]

Definition at line 133 of file Gfx.h.


The documentation for this class was generated from the following files: