📄 gfx.cc
字号:
for (i = 0; i < gfxColorMaxComps; ++i) { color.c[i] = 0; } state->setStrokeColor(&color); out->updateStrokeColor(state);}void Gfx::opSetFillColor(Object args[], int numArgs) { GfxColor color; int i; state->setFillPattern(NULL); for (i = 0; i < numArgs; ++i) { color.c[i] = dblToCol(args[i].getNum()); } state->setFillColor(&color); out->updateFillColor(state);}void Gfx::opSetStrokeColor(Object args[], int numArgs) { GfxColor color; int i; state->setStrokePattern(NULL); for (i = 0; i < numArgs; ++i) { color.c[i] = dblToCol(args[i].getNum()); } state->setStrokeColor(&color); out->updateStrokeColor(state);}void Gfx::opSetFillColorN(Object args[], int numArgs) { 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] = dblToCol(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] = dblToCol(args[i].getNum()); } } state->setFillColor(&color); out->updateFillColor(state); }}void Gfx::opSetStrokeColorN(Object args[], int numArgs) { 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] = dblToCol(args[i].getNum()); printf("color.c[%d] = %d\n",i,colToByte(color.c[i])); } } state->setStrokeColor(&color); out->updateStrokeColor(state); } if (args[numArgs-1].isName() && (pattern = res->lookupPattern(args[numArgs-1].getName()))) { state->setStrokePattern(pattern); printf("stroke seems to be a pattern\n"); } } else { state->setStrokePattern(NULL); for (i = 0; i < numArgs && i < 4; ++i) { if (args[i].isNum()) { color.c[i] = dblToCol(args[i].getNum()); //printf("color.c[%d] = %d\n",i,colToByte(color.c[i])); } } state->setStrokeColor(&color); out->updateStrokeColor(state); }}//------------------------------------------------------------------------// path segment operators//------------------------------------------------------------------------void Gfx::opMoveTo(Object args[], int numArgs) { state->moveTo(args[0].getNum(), args[1].getNum());}void Gfx::opLineTo(Object args[], int numArgs) { if (!state->isCurPt()) { error(getPos(), "No current point in lineto"); return; } state->lineTo(args[0].getNum(), args[1].getNum());}void Gfx::opCurveTo(Object args[], int numArgs) { 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);}void Gfx::opCurveTo1(Object args[], int numArgs) { 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);}void Gfx::opCurveTo2(Object args[], int numArgs) { 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);}void Gfx::opRectangle(Object args[], int numArgs) { double x, y, w, h; int x1, x2, x3, x4, y1, y2, y3, y4 = 0; x = args[0].getNum(); y = args[1].getNum(); w = args[2].getNum(); h = args[3].getNum(); //cvtUserToDev(x, y,&x1,&y1); //cvtUserToDev(x+w, y+h,&x2,&y2); //cvtUserToDev(x, y,&x3,&y3); //cvtUserToDev(x, y,&x4,&y4); // printf("opRectangle(%f,%f,%f,%f)\n",x,y,x+w,y+h); state->moveTo(x, y); state->lineTo(x + w, y); state->lineTo(x + w, y + h); state->lineTo(x, y + h); state->closePath();}void Gfx::opClosePath(Object args[], int numArgs) { if (!state->isCurPt()) { error(getPos(), "No current point in closepath"); return; } state->closePath();}//------------------------------------------------------------------------// path painting operators//------------------------------------------------------------------------void Gfx::opEndPath(Object args[], int numArgs) { doEndPath();}void Gfx::opStroke(Object args[], int numArgs) { if (!state->isCurPt()) { //error(getPos(), "No path in stroke"); return; } if (state->isPath()) out->stroke(state); doEndPath();}void Gfx::opCloseStroke(Object args[], int numArgs) { if (!state->isCurPt()) { //error(getPos(), "No path in closepath/stroke"); return; } if (state->isPath()) { state->closePath(); out->stroke(state); } doEndPath();}void Gfx::opFill(Object args[], int numArgs) { 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();}void Gfx::opEOFill(Object args[], int numArgs) { 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();}void Gfx::opFillStroke(Object args[], int numArgs) { 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();}void Gfx::opCloseFillStroke(Object args[], int numArgs) { 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();}void Gfx::opEOFillStroke(Object args[], int numArgs) { 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();}void Gfx::opCloseEOFillStroke(Object args[], int numArgs) { 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();}void Gfx::doPatternFill(GBool eoFill) { 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; }}void Gfx::doTilingPatternFill(GfxTilingPattern *tPat, GBool eoFill) { 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 (device 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()); out->updateFillColorSpace(state); state->setStrokeColorSpace(cs->copy()); out->updateStrokeColorSpace(state); state->setStrokeColor(state->getFillColor()); } else { state->setFillColorSpace(new GfxDeviceGrayColorSpace()); out->updateFillColorSpace(state); state->setStrokeColorSpace(new GfxDeviceGrayColorSpace()); out->updateStrokeColorSpace(state); } 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(); // get the clip region, check for empty state->getClipBBox(&cxMin, &cyMin, &cxMax, &cyMax); if (cxMin > cxMax || cyMin > cyMax) { goto err; } // transform clip region bbox to pattern space 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());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -