home *** CD-ROM | disk | FTP | other *** search
- //========================================================================
- //
- // GfxState.cc
- //
- // Copyright 1996 Derek B. Noonburg
- //
- //========================================================================
-
- #ifdef __GNUC__
- #pragma implementation
- #endif
-
- #include <stddef.h>
- #include <math.h>
- #include <string.h> // for memcpy()
- #include "gmem.h"
- #include "Error.h"
- #include "Object.h"
- #include "GfxState.h"
-
- //------------------------------------------------------------------------
- // GfxColor
- //------------------------------------------------------------------------
-
- void GfxColor::setCMYK(double c, double m, double y, double k) {
- if ((r = 1 - (c + k)) < 0)
- r = 0;
- if ((g = 1 - (m + k)) < 0)
- g = 0;
- if ((b = 1 - (y + k)) < 0)
- b = 0;
- }
-
- //------------------------------------------------------------------------
- // GfxColorSpace
- //------------------------------------------------------------------------
-
- GfxColorSpace::GfxColorSpace(Object *colorSpace) {
- Object csObj;
- Object obj, obj2;
- char *s;
- int x;
- int i, j;
-
- ok = gTrue;
- lookup = NULL;
-
- // check for Separation colorspace
- colorSpace->copy(&csObj);
- sepFunc = NULL;
- if (colorSpace->isArray()) {
- colorSpace->arrayGet(0, &obj);
- if (obj.isName("Separation")) {
- csObj.free();
- colorSpace->arrayGet(2, &csObj);
- sepFunc = new Function(colorSpace->arrayGet(3, &obj2));
- obj2.free();
- if (!sepFunc->isOk()) {
- delete sepFunc;
- sepFunc = NULL;
- }
- }
- obj.free();
- }
-
- // get mode
- indexed = gFalse;
- if (csObj.isName()) {
- setMode(&csObj);
- } else if (csObj.isArray()) {
- csObj.arrayGet(0, &obj);
- if (obj.isName("Indexed") || obj.isName("I")) {
- indexed = gTrue;
- setMode(csObj.arrayGet(1, &obj2));
- obj2.free();
- } else {
- setMode(&csObj);
- }
- obj.free();
- } else {
- goto err1;
- }
- if (!ok)
- return;
-
- // get lookup table for indexed colorspace
- if (indexed) {
- csObj.arrayGet(2, &obj);
- if (!obj.isInt())
- goto err2;
- indexHigh = obj.getInt();
- obj.free();
- lookup = (Guchar (*)[4])gmalloc((indexHigh + 1) * 4 * sizeof(Guchar));
- csObj.arrayGet(3, &obj);
- if (obj.isStream()) {
- obj.streamReset();
- for (i = 0; i <= indexHigh; ++i) {
- for (j = 0; j < numComps; ++j) {
- if ((x = obj.streamGetChar()) == EOF)
- goto err2;
- lookup[i][j] = (Guchar)x;
- }
- }
- } else if (obj.isString()) {
- s = obj.getString()->getCString();
- for (i = 0; i <= indexHigh; ++i)
- for (j = 0; j < numComps; ++j)
- lookup[i][j] = (Guchar)*s++;
- } else {
- goto err2;
- }
- obj.free();
- }
-
- csObj.free();
- return;
-
- err2:
- obj.free();
- err1:
- csObj.free();
- ok = gFalse;
- }
-
- GfxColorSpace::GfxColorSpace(GfxColorMode mode1) {
- sepFunc = NULL;
- mode = mode1;
- indexed = gFalse;
- switch (mode) {
- case colorGray: numComps = 1; break;
- case colorCMYK: numComps = 4; break;
- case colorRGB: numComps = 3; break;
- }
- lookup = NULL;
- ok = gTrue;
- }
-
- GfxColorSpace::~GfxColorSpace() {
- if (sepFunc)
- delete sepFunc;
- gfree(lookup);
- }
-
- GfxColorSpace::GfxColorSpace(GfxColorSpace *colorSpace) {
- int size;
-
- if (colorSpace->sepFunc)
- sepFunc = colorSpace->sepFunc->copy();
- else
- sepFunc = NULL;
- mode = colorSpace->mode;
- indexed = colorSpace->indexed;
- numComps = colorSpace->numComps;
- indexHigh = colorSpace->indexHigh;
- if (indexed) {
- size = (indexHigh + 1) * 4 * sizeof(Guchar);
- lookup = (Guchar (*)[4])gmalloc(size);
- memcpy(lookup, colorSpace->lookup, size);
- } else {
- lookup = NULL;
- }
- ok = gTrue;
- }
-
- void GfxColorSpace::setMode(Object *colorSpace) {
- Object obj;
-
- if (colorSpace->isName("DeviceGray") || colorSpace->isName("G")) {
- mode = colorGray;
- numComps = 1;
- } else if (colorSpace->isName("DeviceRGB") || colorSpace->isName("RGB")) {
- mode = colorRGB;
- numComps = 3;
- } else if (colorSpace->isName("DeviceCMYK") || colorSpace->isName("CMYK")) {
- mode = colorCMYK;
- numComps = 4;
- } else if (colorSpace->isArray()) {
- colorSpace->arrayGet(0, &obj);
- if (obj.isName("CalGray")) {
- mode = colorGray;
- numComps = 1;
- } else if (obj.isName("CalRGB")) {
- mode = colorRGB;
- numComps = 3;
- } else if (obj.isName("CalCMYK")) {
- mode = colorCMYK;
- numComps = 4;
- } else {
- ok = gFalse;
- }
- obj.free();
- } else {
- ok = gFalse;
- }
- }
-
- void GfxColorSpace::getColor(double x[4], GfxColor *color) {
- double y[4];
- Guchar *p;
-
- if (sepFunc) {
- sepFunc->transform(x, y);
- } else {
- y[0] = x[0];
- y[1] = x[1];
- y[2] = x[2];
- y[3] = x[3];
- }
- if (indexed) {
- p = lookup[(int)(y[0] + 0.5)];
- switch (mode) {
- case colorGray:
- color->setGray(p[0] / 255.0);
- break;
- case colorCMYK:
- color->setCMYK(p[0] / 255.0, p[1] / 255.0, p[2] / 255.0, p[3] / 255.0);
- break;
- case colorRGB:
- color->setRGB(p[0] / 255.0, p[1] / 255.0, p[2] / 255.0);
- break;
- }
- } else {
- switch (mode) {
- case colorGray:
- color->setGray(y[0]);
- break;
- case colorCMYK:
- color->setCMYK(y[0], y[1], y[2], y[3]);
- break;
- case colorRGB:
- color->setRGB(y[0], y[1], y[2]);
- break;
- }
- }
- }
-
- //------------------------------------------------------------------------
- // Function
- //------------------------------------------------------------------------
-
- Function::Function(Object *funcObj) {
- Stream *str;
- Dict *dict;
- int nSamples, sampleBits;
- double sampleMul;
- Object obj1, obj2;
- Guint buf, bitMask;
- int bits;
- int s;
- int i;
-
- ok = gFalse;
- samples = NULL;
-
- if (!funcObj->isStream()) {
- error(-1, "Expected function dictionary");
- goto err3;
- }
- str = funcObj->getStream();
- dict = str->getDict();
-
- //----- FunctionType
- if (!dict->lookup("FunctionType", &obj1)->isInt() ||
- obj1.getInt() != 0) {
- error(-1, "Unknown function type");
- goto err2;
- }
- obj1.free();
-
- //----- Domain
- if (!dict->lookup("Domain", &obj1)->isArray()) {
- error(-1, "Function is missing domain");
- goto err2;
- }
- m = obj1.arrayGetLength() / 2;
- if (m > 4) {
- error(-1, "Functions with more than 1 input are unsupported");
- goto err2;
- }
- for (i = 0; i < m; ++i) {
- obj1.arrayGet(2*i, &obj2);
- if (!obj2.isNum()) {
- error(-1, "Illegal value in function domain array");
- goto err1;
- }
- domain[i][0] = obj2.getNum();
- obj2.free();
- obj1.arrayGet(2*i+1, &obj2);
- if (!obj2.isNum()) {
- error(-1, "Illegal value in function domain array");
- goto err1;
- }
- domain[i][1] = obj2.getNum();
- obj2.free();
- }
- obj1.free();
-
- //----- Range
- if (!dict->lookup("Range", &obj1)->isArray()) {
- error(-1, "Function is missing range");
- goto err2;
- }
- n = obj1.arrayGetLength() / 2;
- if (n > 4) {
- error(-1, "Functions with more than 4 outputs are unsupported");
- goto err2;
- }
- for (i = 0; i < n; ++i) {
- obj1.arrayGet(2*i, &obj2);
- if (!obj2.isNum()) {
- error(-1, "Illegal value in function range array");
- goto err1;
- }
- range[i][0] = obj2.getNum();
- obj2.free();
- obj1.arrayGet(2*i+1, &obj2);
- if (!obj2.isNum()) {
- error(-1, "Illegal value in function range array");
- goto err1;
- }
- range[i][1] = obj2.getNum();
- obj2.free();
- }
- obj1.free();
-
- //----- Size
- if (!dict->lookup("Size", &obj1)->isArray() ||
- obj1.arrayGetLength() != m) {
- error(-1, "Function has missing or invalid size array");
- goto err2;
- }
- for (i = 0; i < m; ++i) {
- obj1.arrayGet(i, &obj2);
- if (!obj2.isInt()) {
- error(-1, "Illegal value in function size array");
- goto err1;
- }
- sampleSize[i] = obj2.getInt();
- obj2.free();
- }
- obj1.free();
-
- //----- BitsPerSample
- if (!dict->lookup("BitsPerSample", &obj1)->isInt()) {
- error(-1, "Function has missing or invalid BitsPerSample");
- goto err2;
- }
- sampleBits = obj1.getInt();
- sampleMul = 1.0 / (double)((1 << sampleBits) - 1);
- obj1.free();
-
- //----- Encode
- if (dict->lookup("Encode", &obj1)->isArray() &&
- obj1.arrayGetLength() == 2*m) {
- for (i = 0; i < m; ++i) {
- obj1.arrayGet(2*i, &obj2);
- if (!obj2.isNum()) {
- error(-1, "Illegal value in function encode array");
- goto err1;
- }
- encode[i][0] = obj2.getNum();
- obj2.free();
- obj1.arrayGet(2*i+1, &obj2);
- if (!obj2.isNum()) {
- error(-1, "Illegal value in function encode array");
- goto err1;
- }
- encode[i][1] = obj2.getNum();
- obj2.free();
- }
- } else {
- for (i = 0; i < m; ++i) {
- encode[i][0] = 0;
- encode[i][1] = sampleSize[i] - 1;
- }
- }
- obj1.free();
-
- //----- Decode
- if (dict->lookup("Decode", &obj1)->isArray() &&
- obj1.arrayGetLength() == 2*n) {
- for (i = 0; i < n; ++i) {
- obj1.arrayGet(2*i, &obj2);
- if (!obj2.isNum()) {
- error(-1, "Illegal value in function decode array");
- goto err1;
- }
- decode[i][0] = obj2.getNum();
- obj2.free();
- obj1.arrayGet(2*i+1, &obj2);
- if (!obj2.isNum()) {
- error(-1, "Illegal value in function decode array");
- goto err1;
- }
- decode[i][1] = obj2.getNum();
- obj2.free();
- }
- } else {
- for (i = 0; i < n; ++i) {
- decode[i][0] = range[i][0];
- decode[i][1] = range[i][1];
- }
- }
- obj1.free();
-
- //----- samples
- nSamples = n;
- for (i = 0; i < m; ++i)
- nSamples *= sampleSize[i];
- samples = (double *)gmalloc(nSamples * sizeof(double));
- buf = 0;
- bits = 0;
- bitMask = (1 << sampleBits) - 1;
- str->reset();
- for (i = 0; i < nSamples; ++i) {
- if (sampleBits == 8) {
- s = str->getChar();
- } else if (sampleBits == 16) {
- s = str->getChar();
- s = (s << 8) + str->getChar();
- } else if (sampleBits == 32) {
- s = str->getChar();
- s = (s << 8) + str->getChar();
- s = (s << 8) + str->getChar();
- s = (s << 8) + str->getChar();
- } else {
- while (bits < sampleBits) {
- buf = (buf << 8) | (str->getChar() & 0xff);
- bits += 8;
- }
- s = (buf >> (bits - sampleBits)) & bitMask;
- bits -= sampleBits;
- }
- samples[i] = (double)s * sampleMul;
- }
-
- ok = gTrue;
- return;
-
- err1:
- obj2.free();
- err2:
- obj1.free();
- err3:
- return;
- }
-
- Function::Function(Function *func) {
- int nSamples, i;
-
- m = func->m;
- n = func->n;
- memcpy(domain, func->domain, sizeof(domain));
- memcpy(range, func->range, sizeof(range));
- memcpy(sampleSize, func->sampleSize, sizeof(sampleSize));
- memcpy(encode, func->encode, sizeof(encode));
- memcpy(decode, func->decode, sizeof(decode));
-
- nSamples = n;
- for (i = 0; i < m; ++i)
- nSamples *= sampleSize[i];
- samples = (double *)gmalloc(nSamples * sizeof(double));
- memcpy(samples, func->samples, nSamples * sizeof(double));
-
- ok = gTrue;
- }
-
- Function::~Function() {
- if (samples)
- gfree(samples);
- }
-
- void Function::transform(double *in, double *out) {
- double e[4];
- double s;
- double x0, x1;
- int e0, e1;
- double efrac;
- int i;
-
- // map input values into sample array
- for (i = 0; i < m; ++i) {
- e[i] = ((in[i] - domain[i][0]) / (domain[i][1] - domain[i][0])) *
- (encode[i][1] - encode[i][0]) + encode[i][0];
- if (e[i] < 0)
- e[i] = 0;
- else if (e[i] > sampleSize[i] - 1)
- e[i] = sampleSize[i] - 1;
- }
-
- for (i = 0; i < n; ++i) {
-
- // m-linear interpolation
- // (only m=1 is currently supported)
- e0 = (int)floor(e[0]);
- e1 = (int)ceil(e[0]);
- efrac = e[0] - e0;
- x0 = samples[e0 * n + i];
- x1 = samples[e1 * n + i];
- s = (1 - efrac) * x0 + efrac * x1;
-
- // map output values to range
- out[i] = s * (decode[i][1] - decode[i][0]) + decode[i][0];
- if (out[i] < range[i][0])
- out[i] = range[i][0];
- else if (out[i] > range[i][1])
- out[i] = range[i][1];
- }
- }
-
- //------------------------------------------------------------------------
- // GfxImageColorMap
- //------------------------------------------------------------------------
-
- GfxImageColorMap::GfxImageColorMap(int bits1, Object *decode,
- GfxColorSpace *colorSpace1) {
- GfxColor color;
- double x[4];
- int maxPixel;
- Object obj;
- int i, j;
-
- ok = gTrue;
-
- // bits per component and colorspace
- bits = bits1;
- maxPixel = (1 << bits) - 1;
- colorSpace = colorSpace1;
- mode = colorSpace->getMode();
-
- // get decode map
- if (decode->isNull()) {
- if (colorSpace->isIndexed()) {
- indexed = gTrue;
- numComps = 1;
- decodeLow[0] = 0;
- decodeRange[0] = maxPixel;
- } else {
- indexed = gFalse;
- numComps = colorSpace->getNumPixelComps();
- for (i = 0; i < numComps; ++i) {
- decodeLow[i] = 0;
- decodeRange[i] = 1;
- }
- }
- } else if (decode->isArray()) {
- numComps = decode->arrayGetLength() / 2;
- if (numComps != colorSpace->getNumPixelComps())
- goto err1;
- indexed = colorSpace->isIndexed();
- for (i = 0; i < numComps; ++i) {
- decode->arrayGet(2*i, &obj);
- if (!obj.isNum())
- goto err2;
- decodeLow[i] = obj.getNum();
- obj.free();
- decode->arrayGet(2*i+1, &obj);
- if (!obj.isNum())
- goto err2;
- decodeRange[i] = obj.getNum() - decodeLow[i];
- obj.free();
- }
- } else {
- goto err1;
- }
-
- // construct lookup table
- lookup = (double (*)[4])gmalloc((maxPixel + 1) * 4 * sizeof(double));
- if (indexed) {
- for (i = 0; i <= maxPixel; ++i) {
- x[0] = (double)i;
- colorSpace->getColor(x, &color);
- lookup[i][0] = color.getR();
- lookup[i][1] = color.getG();
- lookup[i][2] = color.getB();
- }
- } else {
- for (i = 0; i <= maxPixel; ++i)
- for (j = 0; j < numComps; ++j)
- lookup[i][j] = decodeLow[j] + (i * decodeRange[j]) / maxPixel;
- }
-
- return;
-
- err2:
- obj.free();
- err1:
- ok = gFalse;
- }
-
- GfxImageColorMap::~GfxImageColorMap() {
- delete colorSpace;
- gfree(lookup);
- }
-
- void GfxImageColorMap::getColor(Guchar x[4], GfxColor *color) {
- double *p;
-
- if (indexed) {
- p = lookup[x[0]];
- color->setRGB(p[0], p[1], p[2]);
- } else {
- switch (mode) {
- case colorGray:
- color->setGray(lookup[x[0]][0]);
- break;
- case colorCMYK:
- color->setCMYK(lookup[x[0]][0], lookup[x[1]][1],
- lookup[x[2]][2], lookup[x[3]][3]);
- break;
- case colorRGB:
- color->setRGB(lookup[x[0]][0], lookup[x[1]][1], lookup[x[2]][2]);
- break;
- }
- }
- }
-
- //------------------------------------------------------------------------
- // GfxSubpath and GfxPath
- //------------------------------------------------------------------------
-
- GfxSubpath::GfxSubpath(double x1, double y1) {
- size = 16;
- x = (double *)gmalloc(size * sizeof(double));
- y = (double *)gmalloc(size * sizeof(double));
- curve = (GBool *)gmalloc(size * sizeof(GBool));
- n = 1;
- x[0] = x1;
- y[0] = y1;
- curve[0] = gFalse;
- }
-
- GfxSubpath::~GfxSubpath() {
- gfree(x);
- gfree(y);
- gfree(curve);
- }
-
- // Used for copy().
- GfxSubpath::GfxSubpath(GfxSubpath *subpath) {
- size = subpath->size;
- n = subpath->n;
- x = (double *)gmalloc(size * sizeof(double));
- y = (double *)gmalloc(size * sizeof(double));
- curve = (GBool *)gmalloc(size * sizeof(GBool));
- memcpy(x, subpath->x, n * sizeof(double));
- memcpy(y, subpath->y, n * sizeof(double));
- memcpy(curve, subpath->curve, n * sizeof(GBool));
- }
-
- void GfxSubpath::lineTo(double x1, double y1) {
- if (n >= size) {
- size += 16;
- x = (double *)grealloc(x, size * sizeof(double));
- y = (double *)grealloc(y, size * sizeof(double));
- curve = (GBool *)grealloc(curve, size * sizeof(GBool));
- }
- x[n] = x1;
- y[n] = y1;
- curve[n] = gFalse;
- ++n;
- }
-
- void GfxSubpath::curveTo(double x1, double y1, double x2, double y2,
- double x3, double y3) {
- if (n+3 > size) {
- size += 16;
- x = (double *)grealloc(x, size * sizeof(double));
- y = (double *)grealloc(y, size * sizeof(double));
- curve = (GBool *)grealloc(curve, size * sizeof(GBool));
- }
- x[n] = x1;
- y[n] = y1;
- x[n+1] = x2;
- y[n+1] = y2;
- x[n+2] = x3;
- y[n+2] = y3;
- curve[n] = curve[n+1] = gTrue;
- curve[n+2] = gFalse;
- n += 3;
- }
-
- GfxPath::GfxPath() {
- justMoved = gFalse;
- size = 16;
- n = 0;
- subpaths = (GfxSubpath **)gmalloc(size * sizeof(GfxSubpath *));
- }
-
- GfxPath::~GfxPath() {
- int i;
-
- for (i = 0; i < n; ++i)
- delete subpaths[i];
- gfree(subpaths);
- }
-
- // Used for copy().
- GfxPath::GfxPath(GBool justMoved1, double firstX1, double firstY1,
- GfxSubpath **subpaths1, int n1, int size1) {
- int i;
-
- justMoved = justMoved1;
- firstX = firstX1;
- firstY = firstY1;
- size = size1;
- n = n1;
- subpaths = (GfxSubpath **)gmalloc(size * sizeof(GfxSubpath *));
- for (i = 0; i < n; ++i)
- subpaths[i] = subpaths1[i]->copy();
- }
-
- void GfxPath::moveTo(double x, double y) {
- justMoved = gTrue;
- firstX = x;
- firstY = y;
- }
-
- void GfxPath::lineTo(double x, double y) {
- if (justMoved) {
- if (n >= size) {
- size += 16;
- subpaths = (GfxSubpath **)
- grealloc(subpaths, size * sizeof(GfxSubpath *));
- }
- subpaths[n] = new GfxSubpath(firstX, firstY);
- ++n;
- justMoved = gFalse;
- }
- subpaths[n-1]->lineTo(x, y);
- }
-
- void GfxPath::curveTo(double x1, double y1, double x2, double y2,
- double x3, double y3) {
- if (justMoved) {
- if (n >= size) {
- size += 16;
- subpaths = (GfxSubpath **)
- grealloc(subpaths, size * sizeof(GfxSubpath *));
- }
- subpaths[n] = new GfxSubpath(firstX, firstY);
- ++n;
- justMoved = gFalse;
- }
- subpaths[n-1]->curveTo(x1, y1, x2, y2, x3, y3);
- }
-
-
- //------------------------------------------------------------------------
- // GfxState
- //------------------------------------------------------------------------
-
- GfxState::GfxState(int dpi, double px1a, double py1a, double px2a, double py2a,
- int rotate, GBool upsideDown) {
- double k;
-
- px1 = px1a;
- py1 = py1a;
- px2 = px2a;
- py2 = py2a;
- k = (double)dpi / 72.0;
- if (rotate == 90) {
- ctm[0] = 0;
- ctm[1] = upsideDown ? k : -k;
- ctm[2] = k;
- ctm[3] = 0;
- ctm[4] = -k * py1;
- ctm[5] = k * (upsideDown ? -px1 : px2);
- pageWidth = (int)(k * (py2 - py1));
- pageHeight = (int)(k * (px2 - px1));
- } else if (rotate == 180) {
- ctm[0] = -k;
- ctm[1] = 0;
- ctm[2] = 0;
- ctm[3] = upsideDown ? k : -k;
- ctm[4] = k * px2;
- ctm[5] = k * (upsideDown ? -py1 : py2);
- pageWidth = (int)(k * (px2 - px1));
- pageHeight = (int)(k * (py2 - py1));
- } else if (rotate == 270) {
- ctm[0] = 0;
- ctm[1] = upsideDown ? -k : k;
- ctm[2] = -k;
- ctm[3] = 0;
- ctm[4] = k * py2;
- ctm[5] = k * (upsideDown ? px2 : -px1);
- pageWidth = (int)(k * (py2 - py1));
- pageHeight = (int)(k * (px2 - px1));
- } else {
- ctm[0] = k;
- ctm[1] = 0;
- ctm[2] = 0;
- ctm[3] = upsideDown ? -k : k;
- ctm[4] = -k * px1;
- ctm[5] = k * (upsideDown ? py2 : -py1);
- pageWidth = (int)(k * (px2 - px1));
- pageHeight = (int)(k * (py2 - py1));
- }
-
- fillColorSpace = new GfxColorSpace(colorGray);
- strokeColorSpace = new GfxColorSpace(colorGray);
- fillColor.setGray(0);
- strokeColor.setGray(0);
-
- lineWidth = 1;
- lineDash = NULL;
- lineDashLength = 0;
- lineDashStart = 0;
- flatness = 0;
- lineJoin = 0;
- lineCap = 0;
- miterLimit = 10;
-
- font = NULL;
- fontSize = 0;
- textMat[0] = 1; textMat[1] = 0;
- textMat[2] = 0; textMat[3] = 1;
- textMat[4] = 0; textMat[5] = 0;
- charSpace = 0;
- wordSpace = 0;
- horizScaling = 1;
- leading = 0;
- rise = 0;
- render = 0;
-
- path = new GfxPath();
- curX = curY = 0;
- lineX = lineY = 0;
-
- saved = NULL;
- }
-
- GfxState::~GfxState() {
- if (fillColorSpace)
- delete fillColorSpace;
- if (strokeColorSpace)
- delete strokeColorSpace;
- gfree(lineDash);
- delete path;
- if (saved)
- delete saved;
- }
-
- // Used for copy();
- GfxState::GfxState(GfxState *state) {
- memcpy(this, state, sizeof(GfxState));
- if (fillColorSpace)
- fillColorSpace = state->fillColorSpace->copy();
- if (strokeColorSpace)
- strokeColorSpace = state->strokeColorSpace->copy();
- if (lineDashLength > 0) {
- lineDash = (double *)gmalloc(lineDashLength * sizeof(double));
- memcpy(lineDash, state->lineDash, lineDashLength * sizeof(double));
- }
- path = state->path->copy();
- saved = NULL;
- }
-
- double GfxState::transformWidth(double w) {
- double x, y;
-
- x = ctm[0] + ctm[2];
- y = ctm[1] + ctm[3];
- return w * sqrt(0.5 * (x * x + y * y));
- }
-
- double GfxState::getTransformedFontSize() {
- double x1, y1, x2, y2;
-
- x1 = textMat[2] * fontSize;
- y1 = textMat[3] * fontSize;
- x2 = ctm[0] * x1 + ctm[2] * y1;
- y2 = ctm[1] * x1 + ctm[3] * y1;
- return sqrt(x2 * x2 + y2 * y2);
- }
-
- void GfxState::getFontTransMat(double *m11, double *m12,
- double *m21, double *m22) {
- *m11 = (textMat[0] * ctm[0] + textMat[1] * ctm[2]) * fontSize;
- *m12 = (textMat[0] * ctm[1] + textMat[1] * ctm[3]) * fontSize;
- *m21 = (textMat[2] * ctm[0] + textMat[3] * ctm[2]) * fontSize;
- *m22 = (textMat[2] * ctm[1] + textMat[3] * ctm[3]) * fontSize;
- }
-
- void GfxState::concatCTM(double a, double b, double c,
- double d, double e, double f) {
- double a1 = ctm[0];
- double b1 = ctm[1];
- double c1 = ctm[2];
- double d1 = ctm[3];
-
- ctm[0] = a * a1 + b * c1;
- ctm[1] = a * b1 + b * d1;
- ctm[2] = c * a1 + d * c1;
- ctm[3] = c * b1 + d * d1;
- ctm[4] = e * a1 + f * c1 + ctm[4];
- ctm[5] = e * b1 + f * d1 + ctm[5];
- }
-
- void GfxState::setFillColorSpace(GfxColorSpace *colorSpace) {
- if (fillColorSpace)
- delete fillColorSpace;
- fillColorSpace = colorSpace;
- }
-
- void GfxState::setStrokeColorSpace(GfxColorSpace *colorSpace) {
- if (strokeColorSpace)
- delete strokeColorSpace;
- strokeColorSpace = colorSpace;
- }
-
- void GfxState::setLineDash(double *dash, int length, double start) {
- if (lineDash)
- gfree(lineDash);
- lineDash = dash;
- lineDashLength = length;
- lineDashStart = start;
- }
-
- void GfxState::clearPath() {
- delete path;
- path = new GfxPath();
- }
-
- void GfxState::textShift(double tx) {
- double dx, dy;
-
- textTransformDelta(tx, 0, &dx, &dy);
- curX += dx;
- curY += dy;
- }
-
- GfxState *GfxState::save() {
- GfxState *newState;
-
- newState = copy();
- newState->saved = this;
- return newState;
- }
-
- GfxState *GfxState::restore() {
- GfxState *oldState;
-
- if (saved) {
- oldState = saved;
- saved = NULL;
- delete this;
- } else {
- oldState = this;
- }
- return oldState;
- }
-