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

📄 xoutputdev.cc

📁 source code: Covert TXT to PDF
💻 CC
📖 第 1 页 / 共 5 页
字号:
  updateStrokeColor(state);  updateFont(state);}void XOutputDev::updateCTM(GfxState *state, double m11, double m12,			   double m21, double m22, double m31, double m32) {  updateLineAttrs(state, gTrue);}void XOutputDev::updateLineDash(GfxState *state) {  updateLineAttrs(state, gTrue);}void XOutputDev::updateFlatness(GfxState *state) {  flatness = state->getFlatness();}void XOutputDev::updateLineJoin(GfxState *state) {  updateLineAttrs(state, gFalse);}void XOutputDev::updateLineCap(GfxState *state) {  updateLineAttrs(state, gFalse);}// unimplementedvoid XOutputDev::updateMiterLimit(GfxState *state) {}void XOutputDev::updateLineWidth(GfxState *state) {  updateLineAttrs(state, gFalse);}void XOutputDev::updateLineAttrs(GfxState *state, GBool updateDash) {  double width;  int cap, join;  double *dashPattern;  int dashLength;  double dashStart;  char dashList[20];  int i;  width = state->getTransformedLineWidth();  switch (state->getLineCap()) {  case 0: cap = CapButt; break;  case 1: cap = CapRound; break;  case 2: cap = CapProjecting; break;  default:    error(-1, "Bad line cap style (%d)", state->getLineCap());    cap = CapButt;    break;  }  switch (state->getLineJoin()) {  case 0: join = JoinMiter; break;  case 1: join = JoinRound; break;  case 2: join = JoinBevel; break;  default:    error(-1, "Bad line join style (%d)", state->getLineJoin());    join = JoinMiter;    break;  }  state->getLineDash(&dashPattern, &dashLength, &dashStart);#if 1 //~ work around a bug in XFree86 (???)  if (dashLength > 0 && cap == CapProjecting) {    cap = CapButt;  }#endif  XSetLineAttributes(display, strokeGC, xoutRound(width),		     dashLength > 0 ? LineOnOffDash : LineSolid,		     cap, join);  if (updateDash && dashLength > 0) {    if (dashLength > 20)      dashLength = 20;    for (i = 0; i < dashLength; ++i) {      dashList[i] = xoutRound(state->transformWidth(dashPattern[i]));      if (dashList[i] == 0)	dashList[i] = 1;    }    XSetDashes(display, strokeGC, xoutRound(dashStart), dashList, dashLength);  }}void XOutputDev::updateFillColor(GfxState *state) {  GfxRGB rgb;  state->getFillRGB(&rgb);  if (reverseVideo) {    rgb.r = 1 - rgb.r;    rgb.g = 1 - rgb.g;    rgb.b = 1 - rgb.b;  }  XSetForeground(display, fillGC, findColor(&rgb));}void XOutputDev::updateStrokeColor(GfxState *state) {  GfxRGB rgb;  state->getStrokeRGB(&rgb);  if (reverseVideo) {    rgb.r = 1 - rgb.r;    rgb.g = 1 - rgb.g;    rgb.b = 1 - rgb.b;  }  XSetForeground(display, strokeGC, findColor(&rgb));}void XOutputDev::updateFont(GfxState *state) {  double m11, m12, m21, m22;  text->updateFont(state);  if (!(gfxFont = state->getFont())) {    font = NULL;    return;  }  if (gfxFont->getType() == fontType3) {    font = NULL;    return;  }  state->getFontTransMat(&m11, &m12, &m21, &m22);  m11 *= state->getHorizScaling();  m12 *= state->getHorizScaling();  font = fontCache->getFont(xref, gfxFont, m11, m12, m21, m22);  if (font) {    font->updateGC(fillGC);    font->updateGC(strokeGC);  }}void XOutputDev::stroke(GfxState *state) {  XPoint *points;  int *lengths;  int n, size, numPoints, i, j;  // transform points  n = convertPath(state, &points, &size, &numPoints, &lengths, gFalse);  // draw each subpath  j = 0;  for (i = 0; i < n; ++i) {    XDrawLines(display, pixmap, strokeGC, points + j, lengths[i],	       CoordModeOrigin);    j += lengths[i];  }  // free points and lengths arrays  if (points != tmpPoints)    gfree(points);  if (lengths != tmpLengths)    gfree(lengths);}void XOutputDev::fill(GfxState *state) {  doFill(state, WindingRule);}void XOutputDev::eoFill(GfxState *state) {  doFill(state, EvenOddRule);}////  X doesn't color the pixels on the right-most and bottom-most//  borders of a polygon.  This means that one-pixel-thick polygons//  are not colored at all.  I think this is supposed to be a//  feature, but I can't figure out why.  So after it fills a//  polygon, it also draws lines around the border.  This is done//  only for single-component polygons, since it's not very//  compatible with the compound polygon kludge (see convertPath()).//void XOutputDev::doFill(GfxState *state, int rule) {  XPoint *points;  int *lengths;  int n, size, numPoints, i, j;  // set fill rule  XSetFillRule(display, fillGC, rule);  // transform points, build separate polygons  n = convertPath(state, &points, &size, &numPoints, &lengths, gTrue);  // fill them  j = 0;  for (i = 0; i < n; ++i) {    XFillPolygon(display, pixmap, fillGC, points + j, lengths[i],		 Complex, CoordModeOrigin);    if (state->getPath()->getNumSubpaths() == 1) {      XDrawLines(display, pixmap, fillGC, points + j, lengths[i],		 CoordModeOrigin);    }    j += lengths[i] + 1;  }  // free points and lengths arrays  if (points != tmpPoints)    gfree(points);  if (lengths != tmpLengths)    gfree(lengths);}void XOutputDev::clip(GfxState *state) {  doClip(state, WindingRule);}void XOutputDev::eoClip(GfxState *state) {  doClip(state, EvenOddRule);}void XOutputDev::doClip(GfxState *state, int rule) {  Region region, region2;  XPoint *points;  int *lengths;  int n, size, numPoints, i, j;  // transform points, build separate polygons  n = convertPath(state, &points, &size, &numPoints, &lengths, gTrue);  // construct union of subpath regions  // (XPolygonRegion chokes if there aren't at least three points --  // this happens if the PDF file does moveto/closepath/clip, which  // sets an empty clipping region)  if (lengths[0] > 2) {    region = XPolygonRegion(points, lengths[0], rule);  } else {    region = XCreateRegion();  }  j = lengths[0] + 1;  for (i = 1; i < n; ++i) {    if (lengths[i] > 2) {      region2 = XPolygonRegion(points + j, lengths[i], rule);    } else {      region2 = XCreateRegion();    }    XUnionRegion(region2, region, region);    XDestroyRegion(region2);    j += lengths[i] + 1;  }  // intersect region with clipping region  XIntersectRegion(region, clipRegion, clipRegion);  XDestroyRegion(region);  XSetRegion(display, strokeGC, clipRegion);  XSetRegion(display, fillGC, clipRegion);  // free points and lengths arrays  if (points != tmpPoints)    gfree(points);  if (lengths != tmpLengths)    gfree(lengths);}//// Transform points in the path and convert curves to line segments.// Builds a set of subpaths and returns the number of subpaths.// If <fillHack> is set, close any unclosed subpaths and activate a// kludge for polygon fills:  First, it divides up the subpaths into// non-overlapping polygons by simply comparing bounding rectangles.// Then it connects subaths within a single compound polygon to a single// point so that X can fill the polygon (sort of).//int XOutputDev::convertPath(GfxState *state, XPoint **points, int *size,			    int *numPoints, int **lengths, GBool fillHack) {  GfxPath *path;  BoundingRect *rects;  BoundingRect rect;  int n, i, ii, j, k, k0;  // get path and number of subpaths  path = state->getPath();  n = path->getNumSubpaths();  // allocate lengths array  if (n < numTmpSubpaths)    *lengths = tmpLengths;  else    *lengths = (int *)gmalloc(n * sizeof(int));  // allocate bounding rectangles array  if (fillHack) {    if (n < numTmpSubpaths)      rects = tmpRects;    else      rects = (BoundingRect *)gmalloc(n * sizeof(BoundingRect));  } else {    rects = NULL;  }  // do each subpath  *points = tmpPoints;  *size = numTmpPoints;  *numPoints = 0;  for (i = 0; i < n; ++i) {    // transform the points    j = *numPoints;    convertSubpath(state, path->getSubpath(i), points, size, numPoints);    // construct bounding rectangle    if (fillHack) {      rects[i].xMin = rects[i].xMax = (*points)[j].x;      rects[i].yMin = rects[i].yMax = (*points)[j].y;      for (k = j + 1; k < *numPoints; ++k) {	if ((*points)[k].x < rects[i].xMin)	  rects[i].xMin = (*points)[k].x;	else if ((*points)[k].x > rects[i].xMax)	  rects[i].xMax = (*points)[k].x;	if ((*points)[k].y < rects[i].yMin)	  rects[i].yMin = (*points)[k].y;	else if ((*points)[k].y > rects[i].yMax)	  rects[i].yMax = (*points)[k].y;      }    }    // close subpath if necessary    if (fillHack && ((*points)[*numPoints-1].x != (*points)[j].x ||		     (*points)[*numPoints-1].y != (*points)[j].y)) {      addPoint(points, size, numPoints, (*points)[j].x, (*points)[j].y);    }    // length of this subpath    (*lengths)[i] = *numPoints - j;    // leave an extra point for compound fill hack    if (fillHack)      addPoint(points, size, numPoints, 0, 0);  }  // kludge: munge any points that are *way* out of bounds - these can  // crash certain (buggy) X servers  for (i = 0; i < *numPoints; ++i) {    if ((*points)[i].x < -pixmapW) {      (*points)[i].x = -pixmapW;    } else if ((*points)[i].x > 2 * pixmapW) {      (*points)[i].x = 2 * pixmapW;    }    if ((*points)[i].y < -pixmapH) {      (*points)[i].y = -pixmapH;    } else if ((*points)[i].y > 2 * pixmapH) {      (*points)[i].y = 2 * pixmapH;    }  }  // combine compound polygons  if (fillHack) {    i = j = k = 0;    while (i < n) {      // start with subpath i      rect = rects[i];      (*lengths)[j] = (*lengths)[i];      k0 = k;      (*points)[k + (*lengths)[i]] = (*points)[k0];      k += (*lengths)[i] + 1;      ++i;      // combine overlapping polygons      do {	// look for the first subsequent subpath, if any, which overlaps	for (ii = i; ii < n; ++ii) {	  if (rects[ii].xMax > rects[i].xMin &&	      rects[ii].xMin < rects[i].xMax &&	      rects[ii].yMax > rects[i].yMin &&	      rects[ii].yMin < rects[i].yMax) {	    break;	  }	}	// if there is an overlap, combine the polygons	if (ii < n) {	  for (; i <= ii; ++i) {	    if (rects[i].xMin < rect.xMin)	      rect.xMin = rects[j].xMin;	    if (rects[i].xMax > rect.xMax)	      rect.xMax = rects[j].xMax;	    if (rects[i].yMin < rect.yMin)	      rect.yMin = rects[j].yMin;	    if (rects[i].yMax > rect.yMax)	      rect.yMax = rects[j].yMax;	    (*lengths)[j] += (*lengths)[i] + 1;	    (*points)[k + (*lengths)[i]] = (*points)[k0];	    k += (*lengths)[i] + 1;	  }	}      } while (ii < n && i < n);      ++j;    }    // free bounding rectangles    if (rects != tmpRects)      gfree(rects);    n = j;  }  return n;}//// Transform points in a single subpath and convert curves to line// segments.//void XOutputDev::convertSubpath(GfxState *state, GfxSubpath *subpath,				XPoint **points, int *size, int *n) {  double x0, y0, x1, y1, x2, y2, x3, y3;  int m, i;  m = subpath->getNumPoints();  i = 0;  while (i < m) {    if (i >= 1 && subpath->getCurve(i)) {      state->transform(subpath->getX(i-1), subpath->getY(i-1), &x0, &y0);      state->transform(subpath->getX(i), subpath->getY(i), &x1, &y1);      state->transform(subpath->getX(i+1), subpath->getY(i+1), &x2, &y2);      state->transform(subpath->getX(i+2), subpath->getY(i+2), &x3, &y3);      doCurve(points, size, n, x0, y0, x1, y1, x2, y2, x3, y3);      i += 3;    } else {      state->transform(subpath->getX(i), subpath->getY(i), &x1, &y1);      addPoint(points, size, n, xoutRound(x1), xoutRound(y1));      ++i;    }  }}//// Subdivide a Bezier curve.  This uses floating point to avoid// propagating rounding errors.  (The curves look noticeably more// jagged with integer arithmetic.)//void XOutputDev::doCurve(XPoint **points, int *size, int *n,			 double x0, double y0, double x1, double y1,			 double x2, double y2, double x3, double y3) {  double x[(1<<maxCurveSplits)+1][3];  double y[(1<<maxCurveSplits)+1][3];  int next[1<<maxCurveSplits];  int p1, p2, p3;  double xx1, yy1, xx2, yy2;  double dx, dy, mx, my, d1, d2;  double xl0, yl0, xl1, yl1, xl2, yl2;  double xr0, yr0, xr1, yr1, xr2, yr2, xr3, yr3;  double xh, yh;  double flat;  flat = (double)(flatness * flatness);  if (flat < 1)    flat = 1;  // initial segment  p1 = 0;  p2 = 1<<maxCurveSplits;  x[p1][0] = x0;  y[p1][0] = y0;  x[p1][1] = x1;  y[p1][1] = y1;  x[p1][2] = x2;  y[p1][2] = y2;  x[p2][0] = x3;  y[p2][0] = y3;  next[p1] = p2;  while (p1 < (1<<maxCurveSplits)) {    // get next segment    xl0 = x[p1][0];  yl0 = y[p1][0];    xx1 = x[p1][1];  yy1 = y[p1][1];    xx2 = x[p1][2];  yy2 = y[p1][2];    p2 = next[p1];    xr3 = x[p2][0];  yr3 = y[p2][0];    // compute distances from control points to midpoint of the    // straight line (this is a bit of a hack, but it's much faster    // than computing the actual distances to the line)    mx = (xl0 + xr3) * 0.5;    my = (yl0 + yr3) * 0.5;    dx = xx1 - mx;    dy = yy1 - my;    d1 = dx*dx + dy*dy;    dx = xx2 - mx;    dy = yy2 - my;    d2 = dx*dx + dy*dy;    // if curve is flat enough, or no more divisions allowed then    // add the straight line segment    if (p2 - p1 <= 1 || (d1 <= flat && d2 <= flat)) {      addPoint(points, size, n, xoutRound(xr3), xoutRound(yr3));      p1 = p2;    // otherwise, subdivide the curve    } else {      xl1 = (xl0 + xx1) * 0.5;      yl1 = 

⌨️ 快捷键说明

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