📄 gfxstate.cc
字号:
}GfxRadialShading::~GfxRadialShading() { int i; for (i = 0; i < nFuncs; ++i) { delete funcs[i]; }}GfxRadialShading *GfxRadialShading::parse(Dict *dict) { GfxRadialShading *shading; double x0A, y0A, r0A, x1A, y1A, r1A; double t0A, t1A; Function *funcsA[gfxColorMaxComps]; int nFuncsA; GBool extend0A, extend1A; Object obj1, obj2; int i; x0A = y0A = r0A = x1A = y1A = r1A = 0; if (dict->lookup("Coords", &obj1)->isArray() && obj1.arrayGetLength() == 6) { x0A = obj1.arrayGet(0, &obj2)->getNum(); obj2.free(); y0A = obj1.arrayGet(1, &obj2)->getNum(); obj2.free(); r0A = obj1.arrayGet(2, &obj2)->getNum(); obj2.free(); x1A = obj1.arrayGet(3, &obj2)->getNum(); obj2.free(); y1A = obj1.arrayGet(4, &obj2)->getNum(); obj2.free(); r1A = obj1.arrayGet(5, &obj2)->getNum(); obj2.free(); } else { error(-1, "Missing or invalid Coords in shading dictionary"); goto err1; } obj1.free(); t0A = 0; t1A = 1; if (dict->lookup("Domain", &obj1)->isArray() && obj1.arrayGetLength() == 2) { t0A = obj1.arrayGet(0, &obj2)->getNum(); obj2.free(); t1A = obj1.arrayGet(1, &obj2)->getNum(); obj2.free(); } obj1.free(); dict->lookup("Function", &obj1); if (obj1.isArray()) { nFuncsA = obj1.arrayGetLength(); if (nFuncsA > gfxColorMaxComps) { error(-1, "Invalid Function array in shading dictionary"); goto err1; } for (i = 0; i < nFuncsA; ++i) { obj1.arrayGet(i, &obj2); if (!(funcsA[i] = Function::parse(&obj2))) { obj1.free(); obj2.free(); goto err1; } obj2.free(); } } else { nFuncsA = 1; if (!(funcsA[0] = Function::parse(&obj1))) { obj1.free(); goto err1; } } obj1.free(); extend0A = extend1A = gFalse; if (dict->lookup("Extend", &obj1)->isArray() && obj1.arrayGetLength() == 2) { extend0A = obj1.arrayGet(0, &obj2)->getBool(); obj2.free(); extend1A = obj1.arrayGet(1, &obj2)->getBool(); obj2.free(); } obj1.free(); shading = new GfxRadialShading(x0A, y0A, r0A, x1A, y1A, r1A, t0A, t1A, funcsA, nFuncsA, extend0A, extend1A); if (!shading->init(dict)) { delete shading; return NULL; } return shading; err1: return NULL;}GfxShading *GfxRadialShading::copy() { return new GfxRadialShading(this);}void GfxRadialShading::getColor(double t, GfxColor *color) { double out[gfxColorMaxComps]; int i; // NB: there can be one function with n outputs or n functions with // one output each (where n = number of color components) for (i = 0; i < gfxColorMaxComps; ++i) { out[i] = 0; } for (i = 0; i < nFuncs; ++i) { funcs[i]->transform(&t, &out[i]); } for (i = 0; i < gfxColorMaxComps; ++i) { color->c[i] = dblToCol(out[i]); }}//------------------------------------------------------------------------// GfxShadingBitBuf//------------------------------------------------------------------------class GfxShadingBitBuf {public: GfxShadingBitBuf(Stream *strA); ~GfxShadingBitBuf(); GBool getBits(int n, Guint *val); void flushBits();private: Stream *str; int bitBuf; int nBits;};GfxShadingBitBuf::GfxShadingBitBuf(Stream *strA) { str = strA; str->reset(); bitBuf = 0; nBits = 0;}GfxShadingBitBuf::~GfxShadingBitBuf() { str->close();}GBool GfxShadingBitBuf::getBits(int n, Guint *val) { int x; if (nBits >= n) { x = (bitBuf >> (nBits - n)) & ((1 << n) - 1); nBits -= n; } else { x = 0; if (nBits > 0) { x = bitBuf & ((1 << nBits) - 1); n -= nBits; nBits = 0; } while (n > 0) { if ((bitBuf = str->getChar()) == EOF) { nBits = 0; return gFalse; } if (n >= 8) { x = (x << 8) | bitBuf; n -= 8; } else { x = (x << n) | (bitBuf >> (8 - n)); nBits = 8 - n; n = 0; } } } *val = x; return gTrue;}void GfxShadingBitBuf::flushBits() { bitBuf = 0; nBits = 0;}//------------------------------------------------------------------------// GfxGouraudTriangleShading//------------------------------------------------------------------------GfxGouraudTriangleShading::GfxGouraudTriangleShading( int typeA, GfxGouraudVertex *verticesA, int nVerticesA, int (*trianglesA)[3], int nTrianglesA, Function **funcsA, int nFuncsA): GfxShading(typeA){ int i; vertices = verticesA; nVertices = nVerticesA; triangles = trianglesA; nTriangles = nTrianglesA; nFuncs = nFuncsA; for (i = 0; i < nFuncs; ++i) { funcs[i] = funcsA[i]; }}GfxGouraudTriangleShading::GfxGouraudTriangleShading( GfxGouraudTriangleShading *shading): GfxShading(shading){ int i; nVertices = shading->nVertices; vertices = (GfxGouraudVertex *)gmallocn(nVertices, sizeof(GfxGouraudVertex)); memcpy(vertices, shading->vertices, nVertices * sizeof(GfxGouraudVertex)); nTriangles = shading->nTriangles; triangles = (int (*)[3])gmallocn(nTriangles * 3, sizeof(int)); memcpy(triangles, shading->triangles, nTriangles * 3 * sizeof(int)); nFuncs = shading->nFuncs; for (i = 0; i < nFuncs; ++i) { funcs[i] = shading->funcs[i]->copy(); }}GfxGouraudTriangleShading::~GfxGouraudTriangleShading() { int i; gfree(vertices); gfree(triangles); for (i = 0; i < nFuncs; ++i) { delete funcs[i]; }}GfxGouraudTriangleShading *GfxGouraudTriangleShading::parse(int typeA, Dict *dict, Stream *str) { GfxGouraudTriangleShading *shading; Function *funcsA[gfxColorMaxComps]; int nFuncsA; int coordBits, compBits, flagBits, vertsPerRow, nRows; double xMin, xMax, yMin, yMax; double cMin[gfxColorMaxComps], cMax[gfxColorMaxComps]; double xMul, yMul; double cMul[gfxColorMaxComps]; GfxGouraudVertex *verticesA; int (*trianglesA)[3]; int nComps, nVerticesA, nTrianglesA, vertSize, triSize; Guint x, y, flag; Guint c[gfxColorMaxComps]; GfxShadingBitBuf *bitBuf; Object obj1, obj2; int i, j, k, state; if (dict->lookup("BitsPerCoordinate", &obj1)->isInt()) { coordBits = obj1.getInt(); } else { error(-1, "Missing or invalid BitsPerCoordinate in shading dictionary"); goto err2; } obj1.free(); if (dict->lookup("BitsPerComponent", &obj1)->isInt()) { compBits = obj1.getInt(); } else { error(-1, "Missing or invalid BitsPerComponent in shading dictionary"); goto err2; } obj1.free(); flagBits = vertsPerRow = 0; // make gcc happy if (typeA == 4) { if (dict->lookup("BitsPerFlag", &obj1)->isInt()) { flagBits = obj1.getInt(); } else { error(-1, "Missing or invalid BitsPerFlag in shading dictionary"); goto err2; } obj1.free(); } else { if (dict->lookup("VerticesPerRow", &obj1)->isInt()) { vertsPerRow = obj1.getInt(); } else { error(-1, "Missing or invalid VerticesPerRow in shading dictionary"); goto err2; } obj1.free(); } if (dict->lookup("Decode", &obj1)->isArray() && obj1.arrayGetLength() >= 6) { xMin = obj1.arrayGet(0, &obj2)->getNum(); obj2.free(); xMax = obj1.arrayGet(1, &obj2)->getNum(); obj2.free(); xMul = (xMax - xMin) / (pow(2.0, coordBits) - 1); yMin = obj1.arrayGet(2, &obj2)->getNum(); obj2.free(); yMax = obj1.arrayGet(3, &obj2)->getNum(); obj2.free(); yMul = (yMax - yMin) / (pow(2.0, coordBits) - 1); for (i = 0; 5 + 2*i < obj1.arrayGetLength() && i < gfxColorMaxComps; ++i) { cMin[i] = obj1.arrayGet(4 + 2*i, &obj2)->getNum(); obj2.free(); cMax[i] = obj1.arrayGet(5 + 2*i, &obj2)->getNum(); obj2.free(); cMul[i] = (cMax[i] - cMin[i]) / (double)((1 << compBits) - 1); } nComps = i; } else { error(-1, "Missing or invalid Decode array in shading dictionary"); goto err2; } obj1.free(); if (!dict->lookup("Function", &obj1)->isNull()) { if (obj1.isArray()) { nFuncsA = obj1.arrayGetLength(); if (nFuncsA > gfxColorMaxComps) { error(-1, "Invalid Function array in shading dictionary"); goto err1; } for (i = 0; i < nFuncsA; ++i) { obj1.arrayGet(i, &obj2); if (!(funcsA[i] = Function::parse(&obj2))) { obj1.free(); obj2.free(); goto err1; } obj2.free(); } } else { nFuncsA = 1; if (!(funcsA[0] = Function::parse(&obj1))) { obj1.free(); goto err1; } } } else { nFuncsA = 0; } obj1.free(); nVerticesA = nTrianglesA = 0; verticesA = NULL; trianglesA = NULL; vertSize = triSize = 0; state = 0; flag = 0; // make gcc happy bitBuf = new GfxShadingBitBuf(str); while (1) { if (typeA == 4) { if (!bitBuf->getBits(flagBits, &flag)) { break; } } if (!bitBuf->getBits(coordBits, &x) || !bitBuf->getBits(coordBits, &y)) { break; } for (i = 0; i < nComps; ++i) { if (!bitBuf->getBits(compBits, &c[i])) { break; } } if (i < nComps) { break; } if (nVerticesA == vertSize) { vertSize = (vertSize == 0) ? 16 : 2 * vertSize; verticesA = (GfxGouraudVertex *) greallocn(verticesA, vertSize, sizeof(GfxGouraudVertex)); } verticesA[nVerticesA].x = xMin + xMul * (double)x; verticesA[nVerticesA].y = yMin + yMul * (double)y; for (i = 0; i < nComps; ++i) { verticesA[nVerticesA].color.c[i] = dblToCol(cMin[i] + cMul[i] * (double)c[i]); } ++nVerticesA; bitBuf->flushBits(); if (typeA == 4) { if (state == 0 || state == 1) { ++state; } else if (state == 2 || flag > 0) { if (nTrianglesA == triSize) { triSize = (triSize == 0) ? 16 : 2 * triSize; trianglesA = (int (*)[3]) greallocn(trianglesA, triSize * 3, sizeof(int)); } if (state == 2) { trianglesA[nTrianglesA][0] = nVerticesA - 3; trianglesA[nTrianglesA][1] = nVerticesA - 2; trianglesA[nTrianglesA][2] = nVerticesA - 1; ++state; } else if (flag == 1) { trianglesA[nTrianglesA][0] = trianglesA[nTrianglesA - 1][1]; trianglesA[nTrianglesA][1] = trianglesA[nTrianglesA - 1][2]; trianglesA[nTrianglesA][2] = nVerticesA - 1; } else { // flag == 2 trianglesA[nTrianglesA][0] = trianglesA[nTrianglesA - 1][0]; trianglesA[nTrianglesA][1] = trianglesA[nTrianglesA - 1][2]; trianglesA[nTrianglesA][2] = nVerticesA - 1; } ++nTrianglesA; } else { // state == 3 && flag == 0 state = 1; } } } delete bitBuf; if (typeA == 5) { nRows = nVerticesA / vertsPerRow; nTrianglesA = (nRows - 1) * 2 * (vertsPerRow - 1); trianglesA = (int (*)[3])gmallocn(nTrianglesA * 3, sizeof(int)); k = 0; for (i = 0; i < nRows - 1; ++i) { for (j = 0; j < vertsPerRow - 1; ++j) { trianglesA[k][0] = i * vertsPerRow + j; trianglesA[k][1] = i * vertsPerRow + j+1; trianglesA[k][2] = (i+1) * vertsPerRow + j; ++k; trianglesA[k][0] = i * vertsPerRow + j+1; trianglesA[k][1] = (i+1) * vertsPerRow + j; trianglesA[k][2] = (i+1) * vertsPerRow + j+1; ++k; } } } shading = new GfxGouraudTriangleShading(typeA, verticesA, nVerticesA, trianglesA, nTrianglesA, funcsA, nFuncsA); if (!shading->init(dict)) { delete shading; return NULL; } return shading; err2: obj1.free(); err1: return NULL;}GfxShading *GfxGouraudTriangleShading::copy() { return new GfxGouraudTriangleShading(this);}void GfxGouraudTriangleShading::getTriangle( int i, double *x0, double *y0, GfxColor *color0, double *x1, double *y1, GfxColor *color1, double *x2, double *y2, GfxColor *color2) { double in; double out[gfxColorMaxComps]; int v, j; v = triangles[i][0]; *x0 = vertices[v].x; *y0 = vertices[v].y; if (nFuncs > 0) { in = colToDbl(vertices[v].color.c[0]); for (j = 0; j < nFuncs; ++j) { funcs[j]->transform(&in, &out[j]); } for (j = 0; j < gfxColorMaxComps; ++j) { color0->c[j] = dblToCol(out[j]); } } else { *color0 = vertices[v].color; } v = triangles[i][1]; *x1 = vertices[v].x; *y1 = vertices[v].y; if (nFuncs > 0) { in = colToDbl(vertices[v].color.c[0]); for (j = 0; j < nFuncs; ++j) { funcs[j]->transform(&in, &out[j]); } for (j = 0; j < gfxColorMaxComps; ++j) { color1->c[j] = dblToCol(out[j]); } } else { *color1 = vertices[v].color; } v = triangles[i][2]; *x2 = vertices[v].x; *y2 = vertices[v].y; if (nFuncs > 0) { in = colToDbl(vertices[v].color.c[0]); for (j = 0; j < nFuncs; ++j) { funcs[j]->transform(&in, &out[j]); } for (j = 0; j < gfxColorMaxComps; ++j) { color2->c[j] = dblToCol(out[j]); } } else { *color2 = vertices[v].color; }}//------------------------------------------------------------------------// GfxPatchMeshShading//------------------------------------------------------------------------GfxPatchMeshShading::GfxPatchMeshShading(int typeA, GfxPatch *patchesA, int nPatchesA, Function **funcsA, int nFuncsA): GfxShading(typeA){ int i; patches = patchesA; nPatches = nPatchesA; nFuncs = nFuncsA; for (i = 0; i < nFuncs; ++i) { funcs[i] = funcsA[i]; }}GfxPatchMeshShading::GfxPatchMeshShading(GfxPatchMeshShading *shading): GfxShading(shading){ int i; nPatches = shading->nPatches; patches = (GfxPatch *)gmallocn(nPatches, size
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -