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

📄 gfx.cc

📁 将pdf文档转换为高质量的html文档
💻 CC
📖 第 1 页 / 共 5 页
字号:
	for (k = 0; k < nComps; ++k) {	  if (abs(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] = (color0.c[k] + color1.c[k]) / 2;      }      // 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 (dxZero && dyZero) {	sMin = sMax = 0;      } if (dxZero) {	sMin = (xMin - tx) / -dy;	sMax = (xMax - tx) / -dy;	if (sMin > sMax) { tmp = sMin; sMin = sMax; sMax = tmp; }      } else if (dyZero) {	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];    }  }}void Gfx::doRadialShFill(GfxRadialShading *shading) {  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, d0, d1;  if (out->useShadedFills()) {    out->radialShadedFill(state, shading);  } else {    // 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	state->getUserClipBBox(&xMin, &yMin, &xMax, &yMax);	d0 = (x0 - xMin) * (x0 - xMin);	d1 = (x0 - xMax) * (x0 - xMax);	sMin = d0 > d1 ? d0 : d1;	d0 = (y0 - yMin) * (y0 - yMin);	d1 = (y0 - yMax) * (y0 - yMax);	sMin += d0 > d1 ? d0 : d1;	sMin = (sqrt(sMin) - 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);	d0 = (x1 - xMin) * (x1 - xMin);	d1 = (x1 - xMax) * (x1 - xMax);	sMax = d0 > d1 ? d0 : d1;	d0 = (y1 - yMin) * (y1 - yMin);	d1 = (y1 - yMax) * (y1 - yMax);	sMax += d0 > d1 ? d0 : d1;	sMax = (sqrt(sMax) - r0) / (r1 - r0);	if (sMax < 1) {	  sMax = 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 (abs(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] = (colorA.c[k] + colorB.c[k]) / 2;      }      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;    }  }}void Gfx::doGouraudTriangleShFill(GfxGouraudTriangleShading *shading) {  double x0, y0, x1, y1, x2, y2;  GfxColor color0, color1, color2;  int i;  for (i = 0; i < shading->getNTriangles(); ++i) {    shading->getTriangle(i, &x0, &y0, &color0,			 &x1, &y1, &color1,			 &x2, &y2, &color2);    gouraudFillTriangle(x0, y0, &color0, x1, y1, &color1, x2, y2, &color2,			shading->getColorSpace()->getNComps(), 0);  }}void Gfx::gouraudFillTriangle(double x0, double y0, GfxColor *color0,			      double x1, double y1, GfxColor *color1,			      double x2, double y2, GfxColor *color2,			      int nComps, int depth) {  double x01, y01, x12, y12, x20, y20;  GfxColor color01, color12, color20;  int i;  for (i = 0; i < nComps; ++i) {    if (abs(color0->c[i] - color1->c[i]) > gouraudColorDelta ||	abs(color1->c[i] - color2->c[i]) > gouraudColorDelta) {      break;    }  }  if (i == nComps || depth == gouraudMaxDepth) {    state->setFillColor(color0);    out->updateFillColor(state);    state->moveTo(x0, y0);    state->lineTo(x1, y1);    state->lineTo(x2, y2);    state->closePath();    out->fill(state);    state->clearPath();  } else {    x01 = 0.5 * (x0 + x1);    y01 = 0.5 * (y0 + y1);    x12 = 0.5 * (x1 + x2);    y12 = 0.5 * (y1 + y2);    x20 = 0.5 * (x2 + x0);    y20 = 0.5 * (y2 + y0);    //~ if the shading has a Function, this should interpolate on the    //~ function parameter, not on the color components    for (i = 0; i < nComps; ++i) {      color01.c[i] = (color0->c[i] + color1->c[i]) / 2;      color12.c[i] = (color1->c[i] + color2->c[i]) / 2;      color20.c[i] = (color2->c[i] + color0->c[i]) / 2;    }    gouraudFillTriangle(x0, y0, color0, x01, y01, &color01,			x20, y20, &color20, nComps, depth + 1);    gouraudFillTriangle(x01, y01, &color01, x1, y1, color1,			x12, y12, &color12, nComps, depth + 1);    gouraudFillTriangle(x01, y01, &color01, x12, y12, &color12,			x20, y20, &color20, nComps, depth + 1);    gouraudFillTriangle(x20, y20, &color20, x12, y12, &color12,			x2, y2, color2, nComps, depth + 1);  }}void Gfx::doPatchMeshShFill(GfxPatchMeshShading *shading) {  int start, i;  if (shading->getNPatches() > 128) {    start = 3;  } else if (shading->getNPatches() > 64) {    start = 2;  } else if (shading->getNPatches() > 16) {    start = 1;  } else {    start = 0;  }  for (i = 0; i < shading->getNPatches(); ++i) {    fillPatch(shading->getPatch(i), shading->getColorSpace()->getNComps(),	      start);  }}void Gfx::fillPatch(GfxPatch *patch, int nComps, int depth) {  GfxPatch patch00, patch01, patch10, patch11;  double xx[4][8], yy[4][8];  double xxm, yym;  int i;  for (i = 0; i < nComps; ++i) {    if (abs(patch->color[0][0].c[i] - patch->color[0][1].c[i])	  > patchColorDelta ||	abs(patch->color[0][1].c[i] - patch->color[1][1].c[i])	  > patchColorDelta ||	abs(patch->color[1][1].c[i] - patch->color[1][0].c[i])	  > patchColorDelta ||	abs(patch->color[1][0].c[i] - patch->color[0][0].c[i])	  > patchColorDelta) {      break;    }  }  if (i == nComps || depth == patchMaxDepth) {    state->setFillColor(&patch->color[0][0]);    out->updateFillColor(state);    state->moveTo(patch->x[0][0], patch->y[0][0]);    state->curveTo(patch->x[0][1], patch->y[0][1],		   patch->x[0][2], patch->y[0][2],		   patch->x[0][3], patch->y[0][3]);    state->curveTo(patch->x[1][3], patch->y[1][3],		   patch->x[2][3], patch->y[2][3],		   patch->x[3][3], patch->y[3][3]);    state->curveTo(patch->x[3][2], patch->y[3][2],		   patch->x[3][1], patch->y[3][1],		   patch->x[3][0], patch->y[3][0]);    state->curveTo(patch->x[2][0], patch->y[2][0],		   patch->x[1][0], patch->y[1][0],		   patch->x[0][0], patch->y[0][0]);    state->closePath();    out->fill(state);    state->clearPath();  } else {    for (i = 0; i < 4; ++i) {      xx[i][0] = patch->x[i][0];      yy[i][0] = patch->y[i][0];      xx[i][1] = 0.5 * (patch->x[i][0] + patch->x[i][1]);      yy[i][1] = 0.5 * (patch->y[i][0] + patch->y[i][1]);      xxm = 0.5 * (patch->x[i][1] + patch->x[i][2]);      yym = 0.5 * (patch->y[i][1] + patch->y[i][2]);      xx[i][6] = 0.5 * (patch->x[i][2] + patch->x[i][3]);      yy[i][6] = 0.5 * (patch->y[i][2] + patch->y[i][3]);      xx[i][2] = 0.5 * (xx[i][1] + xxm);      yy[i][2] = 0.5 * (yy[i][1] + yym);      xx[i][5] = 0.5 * (xxm + xx[i][6]);      yy[i][5] = 0.5 * (yym + yy[i][6]);      xx[i][3] = xx[i][4] = 0.5 * (xx[i][2] + xx[i][5]);      yy[i][3] = yy[i][4] = 0.5 * (yy[i][2] + yy[i][5]);      xx[i][7] = patch->x[i][3];      yy[i][7] = patch->y[i][3];    }    for (i = 0; i < 4; ++i) {      patch00.x[0][i] = xx[0][i];      patch00.y[0][i] = yy[0][i];      patch00.x[1][i] = 0.5 * (xx[0][i] + xx[1][i]);      patch00.y[1][i] = 0.5 * (yy[0][i] + yy[1][i]);      xxm = 0.5 * (xx[1][i] + xx[2][i]);      yym = 0.5 * (yy[1][i] + yy[2][i]);      patch10.x[2][i] = 0.5 * (xx[2][i] + xx[3][i]);      patch10.y[2][i] = 0.5 * (yy[2][i] + yy[3][i]);      patch00.x[2][i] = 0.5 * (patch00.x[1][i] + xxm);      patch00.y[2][i] = 0.5 * (patch00.y[1][i] + yym);      patch10.x[1][i] = 0.5 * (xxm + patch10.x[2][i]);      patch10.y[1][i] = 0.5 * (yym + patch10.y[2][i]);      patch00.x[3][i] = 0.5 * (patch00.x[2][i] + patch10.x[1][i]);      patch00.y[3][i] = 0.5 * (patch00.y[2][i] + patch10.y[1][i]);      patch10.x[0][i] = patch00.x[3][i];      patch10.y[0][i] = patch00.y[3][i];      patch10.x[3][i] = xx[3][i];      patch10.y[3][i] = yy[3][i];    }    for (i = 4; i < 8; ++i) {      patch01.x[0][i-4] = xx[0][i];      patch01.y[0][i-4] = yy[0][i];      patch01.x[1][i-4] = 0.5 * (xx[0][i] + xx[1][i]);      patch01.y[1][i-4] = 0.5 * (yy[0][i] + yy[1][i]);      xxm = 0.5 * (xx[1][i] + xx[2][i]);      yym = 0.5 * (yy[1][i] + yy[2][i]);      patch11.x[2][i-4] = 0.5 * (xx[2][i] + xx[3][i]);      patch11.y[2][i-4] = 0.5 * (yy[2][i] + yy[3][i]);      patch01.x[2][i-4] = 0.5 * (patch01.x[1][i-4] + xxm);      patch01.y[2][i-4] = 0.5 * (patch01.y[1][i-4] + yym);      patch11.x[1][i-4] = 0.5 * (xxm + patch11.x[2][i-4]);      patch11.y[1][i-4] = 0.5 * (yym + patch11.y[2][i-4]);      patch01.x[3][i-4] = 0.5 * (patch01.x[2][i-4] + patch11.x[1][i-4]);      patch01.y[3][i-4] = 0.5 * (patch01.y[2][i-4] + patch11.y[1][i-4]);      patch11.x[0][i-4] = patch01.x[3][i-4];      patch11.y[0][i-4] = patch01.y[3][i-4];      patch11.x[3][i-4] = xx[3][i];      patch11.y[3][i-4] = yy[3][i];    }    //~ if the shading has a Function, this should interpolate on the    //~ function parameter, not on the color components    for (i = 0; i < nComps; ++i) {      patch00.color[0][0].c[i] = patch->color[0][0].c[i];      patch00.color[0][1].c[i] = (patch->color[0][0].c[i] +				  patch->color[0][1].c[i]) / 2;      patch01.color[0][0].c[i] = patch00.color[0][1].c[i];      patch01.color[0][1].c[i] = patch->color[0][1].c[i];      patch01.color[1][1].c[i] = (patch->color[0][1].c[i] +				  patch->color[1][1].c[i]) / 2;      patch11.color[0][1].c[i] = patch01.color[1][1].c[i];      patch11.color[1][1].c[i] = patch->color[1][1].c[i];      patch11.color[1][0].c[i] = (patch->color[1][1].c[i] +				  patch->color[1][0].c[i]) / 2;      patch10.color[1][1].

⌨️ 快捷键说明

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