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

📄 splash.cc

📁 这是一个做pdf阅读器的源代码文件,是大家学习阅读器资料的很好参考
💻 CC
📖 第 1 页 / 共 5 页
字号:
  }  oldState = state;  state = state->next;  delete oldState;  return splashOk;}//------------------------------------------------------------------------// drawing operations//------------------------------------------------------------------------void Splash::clear(SplashColorPtr color, Guchar alpha) {  SplashColorPtr row, p;  Guchar mono;  int x, y;  switch (bitmap->mode) {  case splashModeMono1:    mono = (color[0] & 0x80) ? 0xff : 0x00;    if (bitmap->rowSize < 0) {      memset(bitmap->data + bitmap->rowSize * (bitmap->height - 1),	     mono, -bitmap->rowSize * bitmap->height);    } else {      memset(bitmap->data, mono, bitmap->rowSize * bitmap->height);    }    break;  case splashModeMono8:    if (bitmap->rowSize < 0) {      memset(bitmap->data + bitmap->rowSize * (bitmap->height - 1),	     color[0], -bitmap->rowSize * bitmap->height);    } else {      memset(bitmap->data, color[0], bitmap->rowSize * bitmap->height);    }    break;  case splashModeRGB8:    if (color[0] == color[1] && color[1] == color[2]) {      if (bitmap->rowSize < 0) {	memset(bitmap->data + bitmap->rowSize * (bitmap->height - 1),	       color[0], -bitmap->rowSize * bitmap->height);      } else {	memset(bitmap->data, color[0], bitmap->rowSize * bitmap->height);      }    } else {      row = bitmap->data;      for (y = 0; y < bitmap->height; ++y) {	p = row;	for (x = 0; x < bitmap->width; ++x) {	  *p++ = color[2];	  *p++ = color[1];	  *p++ = color[0];	}	row += bitmap->rowSize;      }    }    break;  case splashModeBGR8:    if (color[0] == color[1] && color[1] == color[2]) {      if (bitmap->rowSize < 0) {	memset(bitmap->data + bitmap->rowSize * (bitmap->height - 1),	       color[0], -bitmap->rowSize * bitmap->height);      } else {	memset(bitmap->data, color[0], bitmap->rowSize * bitmap->height);      }    } else {      row = bitmap->data;      for (y = 0; y < bitmap->height; ++y) {	p = row;	for (x = 0; x < bitmap->width; ++x) {	  *p++ = color[0];	  *p++ = color[1];	  *p++ = color[2];	}	row += bitmap->rowSize;      }    }    break;#if SPLASH_CMYK  case splashModeCMYK8:    if (color[0] == color[1] && color[1] == color[2] && color[2] == color[3]) {      if (bitmap->rowSize < 0) {	memset(bitmap->data + bitmap->rowSize * (bitmap->height - 1),	       color[0], -bitmap->rowSize * bitmap->height);      } else {	memset(bitmap->data, color[0], bitmap->rowSize * bitmap->height);      }    } else {      row = bitmap->data;      for (y = 0; y < bitmap->height; ++y) {	p = row;	for (x = 0; x < bitmap->width; ++x) {	  *p++ = color[0];	  *p++ = color[1];	  *p++ = color[2];	  *p++ = color[3];	}	row += bitmap->rowSize;      }    }    break;#endif  }  if (bitmap->alpha) {    memset(bitmap->alpha, alpha, bitmap->width * bitmap->height);  }  updateModX(0);  updateModY(0);  updateModX(bitmap->width - 1);  updateModY(bitmap->height - 1);}SplashError Splash::stroke(SplashPath *path) {  SplashPath *path2, *dPath;  if (debugMode) {    printf("stroke [dash:%d] [width:%.2f]:\n",	   state->lineDashLength, (double)state->lineWidth);    dumpPath(path);  }  opClipRes = splashClipAllOutside;  if (path->length == 0) {    return splashErrEmptyPath;  }  path2 = flattenPath(path, state->matrix, state->flatness);  if (state->lineDashLength > 0) {    dPath = makeDashedPath(path2);    delete path2;    path2 = dPath;  }  if (state->lineWidth == 0) {    strokeNarrow(path2);  } else {    strokeWide(path2);  }  delete path2;  return splashOk;}void Splash::strokeNarrow(SplashPath *path) {  SplashPipe pipe;  SplashXPath *xPath;  SplashXPathSeg *seg;  int x0, x1, x2, x3, y0, y1, x, y, t;  SplashCoord dx, dy, dxdy;  SplashClipResult clipRes;  int nClipRes[3];  int i;  nClipRes[0] = nClipRes[1] = nClipRes[2] = 0;  xPath = new SplashXPath(path, state->matrix, state->flatness, gFalse);  pipeInit(&pipe, 0, 0, state->strokePattern, NULL, state->strokeAlpha,	   gFalse, gFalse);  for (i = 0, seg = xPath->segs; i < xPath->length; ++i, ++seg) {    x0 = splashFloor(seg->x0);    x1 = splashFloor(seg->x1);    y0 = splashFloor(seg->y0);    y1 = splashFloor(seg->y1);    // horizontal segment    if (y0 == y1) {      if (x0 > x1) {	t = x0; x0 = x1; x1 = t;      }      if ((clipRes = state->clip->testSpan(x0, x1, y0))	  != splashClipAllOutside) {	drawSpan(&pipe, x0, x1, y0, clipRes == splashClipAllInside);      }    // segment with |dx| > |dy|    } else if (splashAbs(seg->dxdy) > 1) {      dx = seg->x1 - seg->x0;      dy = seg->y1 - seg->y0;      dxdy = seg->dxdy;      if (y0 > y1) {	t = y0; y0 = y1; y1 = t;	t = x0; x0 = x1; x1 = t;	dx = -dx;	dy = -dy;      }      if ((clipRes = state->clip->testRect(x0 <= x1 ? x0 : x1, y0,					   x0 <= x1 ? x1 : x0, y1))	  != splashClipAllOutside) {	if (dx > 0) {	  x2 = x0;	  x3 = splashFloor(seg->x0 + ((SplashCoord)y0 + 1 - seg->y0) * dxdy);	  drawSpan(&pipe, x2, (x2 <= x3 - 1) ? x3 - 1 : x2, y0,		   clipRes == splashClipAllInside);	  x2 = x3;	  for (y = y0 + 1; y <= y1 - 1; ++y) {	    x3 = splashFloor(seg->x0 + ((SplashCoord)y + 1 - seg->y0) * dxdy);	    drawSpan(&pipe, x2, x3 - 1, y, clipRes == splashClipAllInside);	    x2 = x3;	  }	  drawSpan(&pipe, x2, x2 <= x1 ? x1 : x2, y1,		   clipRes == splashClipAllInside);	} else {	  x2 = x0;	  x3 = splashFloor(seg->x0 + ((SplashCoord)y0 + 1 - seg->y0) * dxdy);	  drawSpan(&pipe, (x3 + 1 <= x2) ? x3 + 1 : x2, x2, y0,		   clipRes == splashClipAllInside);	  x2 = x3;	  for (y = y0 + 1; y <= y1 - 1; ++y) {	    x3 = splashFloor(seg->x0 + ((SplashCoord)y + 1 - seg->y0) * dxdy);	    drawSpan(&pipe, x3 + 1, x2, y, clipRes == splashClipAllInside);	    x2 = x3;	  }	  drawSpan(&pipe, x1, (x1 <= x2) ? x2 : x1, y1,		   clipRes == splashClipAllInside);	}      }    // segment with |dy| > |dx|    } else {      dxdy = seg->dxdy;      if (y0 > y1) {	t = x0; x0 = x1; x1 = t;	t = y0; y0 = y1; y1 = t;      }      if ((clipRes = state->clip->testRect(x0 <= x1 ? x0 : x1, y0,					   x0 <= x1 ? x1 : x0, y1))	  != splashClipAllOutside) {	drawPixel(&pipe, x0, y0, clipRes == splashClipAllInside);	for (y = y0 + 1; y <= y1 - 1; ++y) {	  x = splashFloor(seg->x0 + ((SplashCoord)y - seg->y0) * dxdy);	  drawPixel(&pipe, x, y, clipRes == splashClipAllInside);	}	drawPixel(&pipe, x1, y1, clipRes == splashClipAllInside);      }    }    ++nClipRes[clipRes];  }  if (nClipRes[splashClipPartial] ||      (nClipRes[splashClipAllInside] && nClipRes[splashClipAllOutside])) {    opClipRes = splashClipPartial;  } else if (nClipRes[splashClipAllInside]) {    opClipRes = splashClipAllInside;  } else {    opClipRes = splashClipAllOutside;  }  delete xPath;}void Splash::strokeWide(SplashPath *path) {  SplashPath *path2;  path2 = makeStrokePath(path, gFalse);  fillWithPattern(path2, gFalse, state->strokePattern, state->strokeAlpha);  delete path2;}SplashPath *Splash::flattenPath(SplashPath *path, SplashCoord *matrix,				SplashCoord flatness) {  SplashPath *fPath;  SplashCoord flatness2;  Guchar flag;  int i;  fPath = new SplashPath();  flatness2 = flatness * flatness;  i = 0;  while (i < path->length) {    flag = path->flags[i];    if (flag & splashPathFirst) {      fPath->moveTo(path->pts[i].x, path->pts[i].y);      ++i;    } else {      if (flag & splashPathCurve) {	flattenCurve(path->pts[i-1].x, path->pts[i-1].y,		     path->pts[i  ].x, path->pts[i  ].y,		     path->pts[i+1].x, path->pts[i+1].y,		     path->pts[i+2].x, path->pts[i+2].y,		     matrix, flatness2, fPath);	i += 3;      } else {	fPath->lineTo(path->pts[i].x, path->pts[i].y);	++i;      }      if (path->flags[i-1] & splashPathClosed) {	fPath->close();      }    }  }  return fPath;}void Splash::flattenCurve(SplashCoord x0, SplashCoord y0,			  SplashCoord x1, SplashCoord y1,			  SplashCoord x2, SplashCoord y2,			  SplashCoord x3, SplashCoord y3,			  SplashCoord *matrix, SplashCoord flatness2,			  SplashPath *fPath) {  SplashCoord cx[splashMaxCurveSplits + 1][3];  SplashCoord cy[splashMaxCurveSplits + 1][3];  int cNext[splashMaxCurveSplits + 1];  SplashCoord xl0, xl1, xl2, xr0, xr1, xr2, xr3, xx1, xx2, xh;  SplashCoord yl0, yl1, yl2, yr0, yr1, yr2, yr3, yy1, yy2, yh;  SplashCoord dx, dy, mx, my, tx, ty, d1, d2;  int p1, p2, p3;  // initial segment  p1 = 0;  p2 = splashMaxCurveSplits;  cx[p1][0] = x0;  cy[p1][0] = y0;  cx[p1][1] = x1;  cy[p1][1] = y1;  cx[p1][2] = x2;  cy[p1][2] = y2;  cx[p2][0] = x3;  cy[p2][0] = y3;  cNext[p1] = p2;  while (p1 < splashMaxCurveSplits) {    // get the next segment    xl0 = cx[p1][0];  yl0 = cy[p1][0];    xx1 = cx[p1][1];  yy1 = cy[p1][1];    xx2 = cx[p1][2];  yy2 = cy[p1][2];    p2 = cNext[p1];    xr3 = cx[p2][0];  yr3 = cy[p2][0];    // compute the distances (in device space) from the control points    // to the 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)    transform(matrix, (xl0 + xr3) * 0.5, (yl0 + yr3) * 0.5, &mx, &my);    transform(matrix, xx1, yy1, &tx, &ty);    dx = tx - mx;    dy = ty - my;    d1 = dx*dx + dy*dy;    transform(matrix, xx2, yy2, &tx, &ty);    dx = tx - mx;    dy = ty - my;    d2 = dx*dx + dy*dy;    // if the curve is flat enough, or no more subdivisions are    // allowed, add the straight line segment    if (p2 - p1 == 1 || (d1 <= flatness2 && d2 <= flatness2)) {      fPath->lineTo(xr3, yr3);      p1 = p2;    // otherwise, subdivide the curve    } else {      xl1 = (xl0 + xx1) * 0.5;      yl1 = (yl0 + yy1) * 0.5;      xh = (xx1 + xx2) * 0.5;      yh = (yy1 + yy2) * 0.5;      xl2 = (xl1 + xh) * 0.5;      yl2 = (yl1 + yh) * 0.5;      xr2 = (xx2 + xr3) * 0.5;      yr2 = (yy2 + yr3) * 0.5;      xr1 = (xh + xr2) * 0.5;      yr1 = (yh + yr2) * 0.5;      xr0 = (xl2 + xr1) * 0.5;      yr0 = (yl2 + yr1) * 0.5;      // add the new subdivision points      p3 = (p1 + p2) / 2;      cx[p1][1] = xl1;  cy[p1][1] = yl1;      cx[p1][2] = xl2;  cy[p1][2] = yl2;      cNext[p1] = p3;      cx[p3][0] = xr0;  cy[p3][0] = yr0;      cx[p3][1] = xr1;  cy[p3][1] = yr1;      cx[p3][2] = xr2;  cy[p3][2] = yr2;      cNext[p3] = p2;    }  }}SplashPath *Splash::makeDashedPath(SplashPath *path) {  SplashPath *dPath;  SplashCoord lineDashTotal;  SplashCoord lineDashStartPhase, lineDashDist, segLen;  SplashCoord x0, y0, x1, y1, xa, ya;  GBool lineDashStartOn, lineDashOn, newPath;  int lineDashStartIdx, lineDashIdx;  int i, j, k;  lineDashTotal = 0;  for (i = 0; i < state->lineDashLength; ++i) {    lineDashTotal += state->lineDash[i];  }  lineDashStartPhase = state->lineDashPhase;  i = splashFloor(lineDashStartPhase / lineDashTotal);  lineDashStartPhase -= (SplashCoord)i * lineDashTotal;  lineDashStartOn = gTrue;  lineDashStartIdx = 0;  while (lineDashStartPhase >= state->lineDash[lineDashStartIdx]) {    lineDashStartOn = !lineDashStartOn;    lineDashStartPhase -= state->lineDash[lineDashStartIdx];    ++lineDashStartIdx;  }  dPath = new SplashPath();  // process each subpath  i = 0;  while (i < path->length) {    // find the end of the subpath    for (j = i;	 j < path->length - 1 && !(path->flags[j] & splashPathLast);	 ++j) ;    // initialize the dash parameters    lineDashOn = lineDashStartOn;    lineDashIdx = lineDashStartIdx;    lineDashDist = state->lineDash[lineDashIdx] - lineDashStartPhase;    // process each segment of the subpath    newPath = gTrue;    for (k = i; k < j; ++k) {      // grab the segment      x0 = path->pts[k].x;      y0 = path->pts[k].y;      x1 = path->pts[k+1].x;      y1 = path->pts[k+1].y;      segLen = splashDist(x0, y0, x1, y1);      // process the segment      while (segLen > 0) {	if (lineDashDist >= segLen) {	  if (lineDashOn) {	    if (newPath) {	      dPath->moveTo(x0, y0);	      newPath = gFalse;	    }	    dPath->lineTo(x1, y1);	  }	  lineDashDist -= segLen;	  segLen = 0;	} else {	  xa = x0 + (lineDashDist / segLen) * (x1 - x0);	  ya = y0 + (lineDashDist / segLen) * (y1 - y0);	  if (lineDashOn) {	    if (newPath) {	      dPath->moveTo(x0, y0);	      newPath = gFalse;	    }	    dPath->lineTo(xa, ya);	  }	  x0 = xa;	  y0 = ya;	  segLen -= lineDashDist;	  lineDashDist = 0;	}	// get the next entry in the dash array	if (lineDashDist <= 0) {	  lineDashOn = !lineDashOn;	  if (++lineDashIdx == state->lineDashLength) {	    lineDashIdx = 0;	  }	  lineDashDist = state->lineDash[lineDashIdx];	  newPath = gTrue;	}      }    }    i = j + 1;  }  return dPath;}SplashError Splash::fill(SplashPath *path, GBool eo) {  if (debugMode) {    printf("fill [eo:%d]:\n", eo);    dumpPath(path);  }  return fillWithPattern(path, eo, state->fillPattern, state->fillAlpha);}SplashError Splash::fillWithPattern(SplashPath *path, GBool eo,				    SplashPattern *pattern,				    SplashCoord alpha) {  SplashPipe pipe;  SplashXPath *xPath;  SplashXPathScanner *scanner;  int xMinI, yMinI, xMaxI, yMaxI, x0, x1, y;  SplashClipResult clipRes, clipRes2;  if (path->length == 0) {    return splashErrEmptyPath;  }  xPath = new SplashXPath(path, state->matrix, state->flatness, gTrue);  if (vectorAntialias) {    xPath->aaScale();  }  xPath->sort();  scanner = new SplashXPathScanner(xPath, eo);  // get the min and max x and y values  if (vectorAntialias) {    scanner->getBBoxAA(&xMinI, &yMinI, &xMaxI, &yMaxI);  } else {    scanner->getBBox(&xMinI, &yMinI, &xMaxI, &yMaxI);  }  // check clipping  if ((clipRes = state->clip->testRect(xMinI, yMinI, xMaxI, yMaxI))      != splashClipAllOutside) {

⌨️ 快捷键说明

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