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

📄 splash.cc

📁 这是一个做pdf阅读器的源代码文件,是大家学习阅读器资料的很好参考
💻 CC
📖 第 1 页 / 共 5 页
字号:
    // limit the y range    if (yMinI < state->clip->getYMinI()) {      yMinI = state->clip->getYMinI();    }    if (yMaxI > state->clip->getYMaxI()) {      yMaxI = state->clip->getYMaxI();    }    pipeInit(&pipe, 0, yMinI, pattern, NULL, alpha, vectorAntialias, gFalse);    // draw the spans    if (vectorAntialias) {      for (y = yMinI; y <= yMaxI; ++y) {	scanner->renderAALine(aaBuf, &x0, &x1, y);	if (clipRes != splashClipAllInside) {	  state->clip->clipAALine(aaBuf, &x0, &x1, y);	}	drawAALine(&pipe, x0, x1, y);      }    } else {      for (y = yMinI; y <= yMaxI; ++y) {	while (scanner->getNextSpan(y, &x0, &x1)) {	  if (clipRes == splashClipAllInside) {	    drawSpan(&pipe, x0, x1, y, gTrue);	  } else {	    // limit the x range	    if (x0 < state->clip->getXMinI()) {	      x0 = state->clip->getXMinI();	    }	    if (x1 > state->clip->getXMaxI()) {	      x1 = state->clip->getXMaxI();	    }	    clipRes2 = state->clip->testSpan(x0, x1, y);	    drawSpan(&pipe, x0, x1, y, clipRes2 == splashClipAllInside);	  }	}      }    }  }  opClipRes = clipRes;  delete scanner;  delete xPath;  return splashOk;}SplashError Splash::xorFill(SplashPath *path, GBool eo) {  SplashPipe pipe;  SplashXPath *xPath;  SplashXPathScanner *scanner;  int xMinI, yMinI, xMaxI, yMaxI, x0, x1, y;  SplashClipResult clipRes, clipRes2;  SplashBlendFunc origBlendFunc;  if (path->length == 0) {    return splashErrEmptyPath;  }  xPath = new SplashXPath(path, state->matrix, state->flatness, gTrue);  xPath->sort();  scanner = new SplashXPathScanner(xPath, eo);  // get the min and max x and y values  scanner->getBBox(&xMinI, &yMinI, &xMaxI, &yMaxI);  // check clipping  if ((clipRes = state->clip->testRect(xMinI, yMinI, xMaxI, yMaxI))      != splashClipAllOutside) {    // limit the y range    if (yMinI < state->clip->getYMinI()) {      yMinI = state->clip->getYMinI();    }    if (yMaxI > state->clip->getYMaxI()) {      yMaxI = state->clip->getYMaxI();    }    origBlendFunc = state->blendFunc;    state->blendFunc = &blendXor;    pipeInit(&pipe, 0, yMinI, state->fillPattern, NULL, 1, gFalse, gFalse);    // draw the spans    for (y = yMinI; y <= yMaxI; ++y) {      while (scanner->getNextSpan(y, &x0, &x1)) {	if (clipRes == splashClipAllInside) {	  drawSpan(&pipe, x0, x1, y, gTrue);	} else {	  // limit the x range	  if (x0 < state->clip->getXMinI()) {	    x0 = state->clip->getXMinI();	  }	  if (x1 > state->clip->getXMaxI()) {	    x1 = state->clip->getXMaxI();	  }	  clipRes2 = state->clip->testSpan(x0, x1, y);	  drawSpan(&pipe, x0, x1, y, clipRes2 == splashClipAllInside);	}      }    }    state->blendFunc = origBlendFunc;  }  opClipRes = clipRes;  delete scanner;  delete xPath;  return splashOk;}SplashError Splash::fillChar(SplashCoord x, SplashCoord y,			     int c, SplashFont *font) {  SplashGlyphBitmap glyph;  SplashCoord xt, yt;  int x0, y0, xFrac, yFrac;  SplashError err;  if (debugMode) {    printf("fillChar: x=%.2f y=%.2f c=%3d=0x%02x='%c'\n",	   (double)x, (double)y, c, c, c);  }  transform(state->matrix, x, y, &xt, &yt);  x0 = splashFloor(xt);  xFrac = splashFloor((xt - x0) * splashFontFraction);  y0 = splashFloor(yt);  yFrac = splashFloor((yt - y0) * splashFontFraction);  if (!font->getGlyph(c, xFrac, yFrac, &glyph)) {    return splashErrNoGlyph;  }  err = fillGlyph2(x0, y0, &glyph);  if (glyph.freeData) {    gfree(glyph.data);  }  return err;}SplashError Splash::fillGlyph(SplashCoord x, SplashCoord y,			      SplashGlyphBitmap *glyph) {  SplashCoord xt, yt;  int x0, y0;  transform(state->matrix, x, y, &xt, &yt);  x0 = splashFloor(xt);  y0 = splashFloor(yt);  return fillGlyph2(x0, y0, glyph);}SplashError Splash::fillGlyph2(int x0, int y0, SplashGlyphBitmap *glyph) {  SplashPipe pipe;  SplashClipResult clipRes;  GBool noClip;  int alpha0, alpha;  Guchar *p;  int x1, y1, xx, xx1, yy;  if ((clipRes = state->clip->testRect(x0 - glyph->x,				       y0 - glyph->y,				       x0 - glyph->x + glyph->w - 1,				       y0 - glyph->y + glyph->h - 1))      != splashClipAllOutside) {    noClip = clipRes == splashClipAllInside;    if (noClip) {      if (glyph->aa) {	pipeInit(&pipe, x0 - glyph->x, y0 - glyph->y,		 state->fillPattern, NULL, state->fillAlpha, gTrue, gFalse);	p = glyph->data;	for (yy = 0, y1 = y0 - glyph->y; yy < glyph->h; ++yy, ++y1) {	  pipeSetXY(&pipe, x0 - glyph->x, y1);	  for (xx = 0, x1 = x0 - glyph->x; xx < glyph->w; ++xx, ++x1) {	    alpha = *p++;	    if (alpha != 0) {	      pipe.shape = (SplashCoord)(alpha / 255.0);	      pipeRun(&pipe);	      updateModX(x1);	      updateModY(y1);	    } else {	      pipeIncX(&pipe);	    }	  }	}      } else {	pipeInit(&pipe, x0 - glyph->x, y0 - glyph->y,		 state->fillPattern, NULL, state->fillAlpha, gFalse, gFalse);	p = glyph->data;	for (yy = 0, y1 = y0 - glyph->y; yy < glyph->h; ++yy, ++y1) {	  pipeSetXY(&pipe, x0 - glyph->x, y1);	  for (xx = 0, x1 = x0 - glyph->x; xx < glyph->w; xx += 8) {	    alpha0 = *p++;	    for (xx1 = 0; xx1 < 8 && xx + xx1 < glyph->w; ++xx1, ++x1) {	      if (alpha0 & 0x80) {		pipeRun(&pipe);		updateModX(x1);		updateModY(y1);	      } else {		pipeIncX(&pipe);	      }	      alpha0 <<= 1;	    }	  }	}      }    } else {      if (glyph->aa) {	pipeInit(&pipe, x0 - glyph->x, y0 - glyph->y,		 state->fillPattern, NULL, state->fillAlpha, gTrue, gFalse);	p = glyph->data;	for (yy = 0, y1 = y0 - glyph->y; yy < glyph->h; ++yy, ++y1) {	  pipeSetXY(&pipe, x0 - glyph->x, y1);	  for (xx = 0, x1 = x0 - glyph->x; xx < glyph->w; ++xx, ++x1) {	    if (state->clip->test(x1, y1)) {	      alpha = *p++;	      if (alpha != 0) {		pipe.shape = (SplashCoord)(alpha / 255.0);		pipeRun(&pipe);		updateModX(x1);		updateModY(y1);	      } else {		pipeIncX(&pipe);	      }	    } else {	      pipeIncX(&pipe);	      ++p;	    }	  }	}      } else {	pipeInit(&pipe, x0 - glyph->x, y0 - glyph->y,		 state->fillPattern, NULL, state->fillAlpha, gFalse, gFalse);	p = glyph->data;	for (yy = 0, y1 = y0 - glyph->y; yy < glyph->h; ++yy, ++y1) {	  pipeSetXY(&pipe, x0 - glyph->x, y1);	  for (xx = 0, x1 = x0 - glyph->x; xx < glyph->w; xx += 8) {	    alpha0 = *p++;	    for (xx1 = 0; xx1 < 8 && xx + xx1 < glyph->w; ++xx1, ++x1) {	      if (state->clip->test(x1, y1)) {		if (alpha0 & 0x80) {		  pipeRun(&pipe);		  updateModX(x1);		  updateModY(y1);		} else {		  pipeIncX(&pipe);		}	      } else {		pipeIncX(&pipe);	      }	      alpha0 <<= 1;	    }	  }	}      }    }  }  opClipRes = clipRes;  return splashOk;}SplashError Splash::fillImageMask(SplashImageMaskSource src, void *srcData,				  int w, int h, SplashCoord *mat,				  GBool glyphMode) {  SplashPipe pipe;  GBool rot;  SplashCoord xScale, yScale, xShear, yShear, yShear1;  int tx, tx2, ty, ty2, scaledWidth, scaledHeight, xSign, ySign;  int ulx, uly, llx, lly, urx, ury, lrx, lry;  int ulx1, uly1, llx1, lly1, urx1, ury1, lrx1, lry1;  int xMin, xMax, yMin, yMax;  SplashClipResult clipRes, clipRes2;  int yp, yq, yt, yStep, lastYStep;  int xp, xq, xt, xStep, xSrc;  int k1, spanXMin, spanXMax, spanY;  SplashColorPtr pixBuf, p;  int pixAcc;  int x, y, x1, x2, y2;  SplashCoord y1;  int n, m, i, j;  if (debugMode) {    printf("fillImageMask: w=%d h=%d mat=[%.2f %.2f %.2f %.2f %.2f %.2f]\n",	   w, h, (double)mat[0], (double)mat[1], (double)mat[2],	   (double)mat[3], (double)mat[4], (double)mat[5]);  }  // check for singular matrix  if (splashAbs(mat[0] * mat[3] - mat[1] * mat[2]) < 0.000001) {    return splashErrSingularMatrix;  }  // compute scale, shear, rotation, translation parameters  rot = splashAbs(mat[1]) > splashAbs(mat[0]);  if (rot) {    xScale = -mat[1];    yScale = mat[2] - (mat[0] * mat[3]) / mat[1];    xShear = -mat[3] / yScale;    yShear = -mat[0] / mat[1];  } else {    xScale = mat[0];    yScale = mat[3] - (mat[1] * mat[2]) / mat[0];    xShear = mat[2] / yScale;    yShear = mat[1] / mat[0];  }  // Note 1: The PDF spec says that all pixels whose *centers* lie  // within the region get painted -- but that doesn't seem to match  // up with what Acrobat actually does: it ends up leaving gaps  // between image stripes.  So we use the same rule here as for  // fills: any pixel that overlaps the region gets painted.  // Note 2: The "glyphMode" flag is a kludge: it switches back to  // "correct" behavior (matching the spec), for use in rendering Type  // 3 fonts.  // Note 3: The +/-0.01 in these computations is to avoid floating  // point precision problems which can lead to gaps between image  // stripes (it can cause image stripes to overlap, but that's a much  // less visible problem).  if (glyphMode) {    if (xScale >= 0) {      tx = splashRound(mat[4]);      tx2 = splashRound(mat[4] + xScale) - 1;    } else {      tx = splashRound(mat[4]) - 1;      tx2 = splashRound(mat[4] + xScale);    }  } else {    if (xScale >= 0) {      tx = splashFloor(mat[4] - 0.01);      tx2 = splashFloor(mat[4] + xScale + 0.01);    } else {      tx = splashFloor(mat[4] + 0.01);      tx2 = splashFloor(mat[4] + xScale - 0.01);    }  }  scaledWidth = abs(tx2 - tx) + 1;  if (glyphMode) {    if (yScale >= 0) {      ty = splashRound(mat[5]);      ty2 = splashRound(mat[5] + yScale) - 1;    } else {      ty = splashRound(mat[5]) - 1;      ty2 = splashRound(mat[5] + yScale);    }  } else {    if (yScale >= 0) {      ty = splashFloor(mat[5] - 0.01);      ty2 = splashFloor(mat[5] + yScale + 0.01);    } else {      ty = splashFloor(mat[5] + 0.01);      ty2 = splashFloor(mat[5] + yScale - 0.01);    }  }  scaledHeight = abs(ty2 - ty) + 1;  xSign = (xScale < 0) ? -1 : 1;  ySign = (yScale < 0) ? -1 : 1;  yShear1 = (SplashCoord)xSign * yShear;  // clipping  ulx1 = 0;  uly1 = 0;  urx1 = xSign * (scaledWidth - 1);  ury1 = (int)(yShear * urx1);  llx1 = splashRound(xShear * ySign * (scaledHeight - 1));  lly1 = ySign * (scaledHeight - 1) + (int)(yShear * llx1);  lrx1 = xSign * (scaledWidth - 1) +           splashRound(xShear * ySign * (scaledHeight - 1));  lry1 = ySign * (scaledHeight - 1) + (int)(yShear * lrx1);  if (rot) {    ulx = tx + uly1;    uly = ty - ulx1;    urx = tx + ury1;    ury = ty - urx1;    llx = tx + lly1;    lly = ty - llx1;    lrx = tx + lry1;    lry = ty - lrx1;  } else {    ulx = tx + ulx1;    uly = ty + uly1;    urx = tx + urx1;    ury = ty + ury1;    llx = tx + llx1;    lly = ty + lly1;    lrx = tx + lrx1;    lry = ty + lry1;  }  xMin = (ulx < urx) ? (ulx < llx) ? (ulx < lrx) ? ulx : lrx                                   : (llx < lrx) ? llx : lrx		     : (urx < llx) ? (urx < lrx) ? urx : lrx                                   : (llx < lrx) ? llx : lrx;  xMax = (ulx > urx) ? (ulx > llx) ? (ulx > lrx) ? ulx : lrx                                   : (llx > lrx) ? llx : lrx		     : (urx > llx) ? (urx > lrx) ? urx : lrx                                   : (llx > lrx) ? llx : lrx;  yMin = (uly < ury) ? (uly < lly) ? (uly < lry) ? uly : lry                                   : (lly < lry) ? lly : lry		     : (ury < lly) ? (ury < lry) ? ury : lry                                   : (lly < lry) ? lly : lry;  yMax = (uly > ury) ? (uly > lly) ? (uly > lry) ? uly : lry                                   : (lly > lry) ? lly : lry		     : (ury > lly) ? (ury > lry) ? ury : lry                                   : (lly > lry) ? lly : lry;  clipRes = state->clip->testRect(xMin, yMin, xMax, yMax);  opClipRes = clipRes;  // compute Bresenham parameters for x and y scaling  yp = h / scaledHeight;  yq = h % scaledHeight;  xp = w / scaledWidth;  xq = w % scaledWidth;  // allocate pixel buffer  pixBuf = (SplashColorPtr)gmalloc((yp + 1) * w);  // initialize the pixel pipe  pipeInit(&pipe, 0, 0, state->fillPattern, NULL, state->fillAlpha,	   gTrue, gFalse);  if (vectorAntialias) {    drawAAPixelInit();  }  // init y scale Bresenham  yt = 0;  lastYStep = 1;  for (y = 0; y < scaledHeight; ++y) {    // y scale Bresenham    yStep = yp;    yt += yq;    if (yt >= scaledHeight) {      yt -= scaledHeight;      ++yStep;    }    // read row(s) from image    n = (yp > 0) ? yStep : lastYStep;    if (n > 0) {      p = pixBuf;      for (i = 0; i < n; ++i) {	(*src)(srcData, p);	p += w;      }    }    lastYStep = yStep;    // loop-invariant constants    k1 = splashRound(xShear * ySign * y);    // clipping test    if (clipRes != splashClipAllInside &&	!rot &&	(int)(yShear * k1) ==	  (int)(yShear * (xSign * (scaledWidth - 1) + k1))) {      if (xSign > 0) {	spanXMin = tx + k1;	spanXMax = spanXMin + (scaledWidth - 1);      } else {	spanXMax = tx + k1;	spanXMin = spanXMax - (scaledWidth - 1);      }      spanY = ty + ySign * y + (int)(yShear * k1);      clipRes2 = state->clip->testSpan(spanXMin, spanXMax, spanY);      if (clipRes2 == splashClipAllOutside) {	continue;      }    } else {      clipRes2 = clipRes;    }    // init x scale Bresenham    xt = 0;    xSrc = 0;    // x shear    x1 = k1;    // y shear    y1 = (SplashCoord)ySign * y + yShear * x1;    // this is a kludge: if yShear1 is negative, then (int)y1 would    // change immediately after the first pixel, which is not what we    // want    if (yShear1 < 0) {      y1 += 0.999;    }    // loop-invariant constants    n = yStep > 0 ? yStep : 1;    for (x = 0; x < scaledWidth; ++x) {      // x scale Bresenham      xStep = xp;      xt += xq;      if (xt >= scaledWidth) {	xt -= scaledWidth;	++xStep;      }      // rotation      if (rot) {	x2 = (int)y1;	y2 = -x1;      } else {	x2 = x1;	y2 = (int)y1;      }      // compute the alpha value for (x,y) after the x and y scaling      // operations      m = xStep > 0 ? xStep : 1;      p = pixBuf + xSrc;      pixAcc = 0;      for (i = 0; i < n; ++i) {	for (j = 0; j < m; ++j) {	  pixAcc += *p++;	}	p += w - m;

⌨️ 快捷键说明

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