home *** CD-ROM | disk | FTP | other *** search
- //========================================================================
- //
- // GfxState.cc
- //
- // Copyright 1996 Derek B. Noonburg
- //
- //========================================================================
- //
- // Ported to EPOC by Sander van der Wal
- //
- // $Log: GfxState.cpp $
- // Revision 1.4 2000-09-24 21:09:35+02 svdwal
- // Memory leak fixed
- //
- // Revision 1.3 2000-09-21 14:44:54+02 svdwal
- // Some xpdf 0.91 bugfixes added
- //
- // Revision 1.2 2000-09-17 13:38:23+02 svdwal
- // Ported
- //
-
- #ifdef __GNUC__
- #pragma implementation
- #endif
-
- #ifndef __E32DEF_H__
- #include <e32def.h> // remove warning about NULL redefinition
- #endif
-
- #ifndef __E32MATH_H__
- #include <e32math.h>
- #endif
-
- // --o C library
- #include <math.h>
-
- #include "gmem.h"
-
- #include "Error.h"
- #include "Object.h"
- #include "GfxState.h"
-
- #include "Pdf.rsg"
-
- static const TInt KSubpathSizeIncrement = 16;
- static const TInt KPathSizeIncrement = 16;
-
- //------------------------------------------------------------------------
- // GfxColor
- //------------------------------------------------------------------------
- #ifdef FIXCOLOR
- void GfxColor::setGray(int gray) {
- if (gray < 0) {
- gray = 0;
- } else if (gray > 255) {
- gray = 255;
- }
- r = g = b = gray;
- }
-
-
- void GfxColor::setCMYK(int c, int m, int y, int k) {
- if ((r = 255 - (c + k)) < 0) {
- r = 0;
- } else if (r > 255) {
- r = 255;
- }
- if ((g = 255 - (m + k)) < 0) {
- g = 0;
- } else if (g > 255) {
- g = 255;
- }
- if ((b = 255 - (y + k)) < 0) {
- b = 0;
- } else if (b > 255) {
- b = 255;
- }
- }
-
- void GfxColor::setRGB(int r1, int g1, int b1) {
- if ((r = r1) < 0) {
- r = 0;
- } else if (r1 > 255) {
- r = 255;
- }
- if ((g = g1) < 0) {
- g = 0;
- } else if (g1 > 255) {
- g = 255;
- }
- if ((b = b1) < 0) {
- b = 0;
- } else if (b1 > 255) {
- b = 255;
- }
- }
- #else
- void GfxColor::setGray(double gray) {
- if (gray < 0) {
- r = g = b = 0;
- } else if (gray > 1) {
- r = g = b = 1;
- } else {
- r = g = b = gray;
- }
- }
-
- void GfxColor::setCMYK(double c, double m, double y, double k) {
- if ((r = 1 - (c + k)) < 0) {
- r = 0;
- } else if (r > 1) {
- r = 1;
- }
- if ((g = 1 - (m + k)) < 0) {
- g = 0;
- } else if (g > 1) {
- g = 1;
- }
- if ((b = 1 - (y + k)) < 0) {
- b = 0;
- } else if (b > 1) {
- b = 1;
- }
- }
-
- void GfxColor::setRGB(double r1, double g1, double b1) {
- if (r1 < 0) {
- r = 0;
- } else if (r1 > 1) {
- r = 1;
- } else {
- r = r1;
- }
- if (g1 < 0) {
- g = 0;
- } else if (g1 > 1) {
- g = 1;
- } else {
- g = g1;
- }
- if (b1 < 0) {
- b = 0;
- } else if (b1 > 1) {
- b = 1;
- } else {
- b = b1;
- }
- }
- #endif
-
- //------------------------------------------------------------------------
- // GfxColorSpace
- //------------------------------------------------------------------------
-
- void GfxColorSpace::ConstructL(Object *colorSpace) {
- RAutoObject csObj;
- RAutoObject obj, obj2;
- char *s;
- int x;
- int i, j;
-
- ok = gTrue;
- lookup = NULL;
-
- // check for Separation, DeviceN and Pattern colorspaces
- colorSpace->copyL(&csObj);
- sepFunc = NULL;
- if (colorSpace->isArray()) {
- colorSpace->arrayGetL(0, &obj);
- if (obj.isName("Separation") || obj.isName("DeviceN")) {
- csObj.free();
- colorSpace->arrayGetL(2, &csObj);
- sepFunc = new(ELeave) Function();
- sepFunc->ConstructL(colorSpace->arrayGetL(3, &obj2));
- obj2.free();
- if (!sepFunc->isOk()) {
- delete sepFunc;
- sepFunc = NULL;
- }
- }
- else if (obj.isName("Pattern")) {
- csObj.free();
- colorSpace->arrayGetL(1, &csObj);
- }
- obj.free();
- }
-
- // get mode
- indexed = gFalse;
- if (csObj.isName()) {
- setMode(&csObj);
- } else if (csObj.isArray()) {
- csObj.arrayGetL(0, &obj);
- if (obj.isName("Indexed") || obj.isName("I")) {
- indexed = gTrue;
- setMode(csObj.arrayGetL(1, &obj2));
- obj2.free();
- }
- else {
- setMode(&csObj);
- }
- obj.free();
- } else {
- goto err1;
- }
- if (!ok) {
- goto err1;
- }
-
- if (indexed) {
- // get lookup table for indexed colorspace
- csObj.arrayGetL(2, &obj);
- if (!obj.isInt())
- goto err2;
- indexHigh = obj.getInt();
- obj.free();
- lookup = (Guchar (*)[4])User::AllocL((indexHigh + 1) * 4 * sizeof(Guchar));
- csObj.arrayGetL(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() {
- delete sepFunc;
- User::Free(lookup);
- }
-
-
- void GfxColorSpace::ConstructL(GfxColorSpace *colorSpace) {
- int size;
-
- if (colorSpace->sepFunc)
- sepFunc = colorSpace->sepFunc->copyL();
- 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])User::AllocL(size);
- Mem::Copy(lookup, colorSpace->lookup, size);
- } else {
- lookup = NULL;
- }
- ok = gTrue;
- }
-
- GfxColorSpace *GfxColorSpace::copyL()
- {
- GfxColorSpace* self = new(ELeave) GfxColorSpace();
- CleanupStack::PushL(self);
- self->ConstructL(this);
- CleanupStack::Pop(); // self
- return self;
- }
-
- void GfxColorSpace::setMode(Object *colorSpace) {
- RAutoObject 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->arrayGetL(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 if (obj.isName("ICCBased")) {
- obj.free();
- // try the Alternate colorspace. If there's none, use N
- colorSpace->arrayGetL(1, &obj);
- if (obj.isStream()) {
- obj.streamReset();
- RAutoObject obj2;
- obj.streamGetDict()->lookupL("Alternate", &obj2);
- if (obj2.isNone()) {
- obj.streamGetDict()->lookupL("N", &obj2);
- if (obj2.isInt()) {
- switch (numComps = obj2.getInt()) {
- case 1: mode = colorGray; break;
- case 3: mode = colorRGB; break;
- case 4: mode = colorCMYK; break;
- default:
- ok = gFalse;
- }
- }
- else
- ok = gFalse; // N is not optional
- }
- else
- setMode(&obj2);
- }
- else
- ok = gFalse; // must be a stream
- }
- else {
- ok = gFalse;
- }
- obj.free();
- } else {
- ok = gFalse;
- }
- }
-
- #ifdef FIXCOLOR
- void GfxColorSpace::getColor(int x[4], GfxColor *color) {
- int 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[x[0]];
- switch (mode) {
- case colorGray:
- color->setGray(p[0]);
- break;
- case colorCMYK:
- color->setCMYK(p[0], p[1], p[2], p[3]);
- break;
- case colorRGB:
- color->setRGB(p[0], p[1], p[2]);
- break;
- }
- }
- else {
- switch (mode) {
- case colorGray:
- color->setGray(x[0]);
- break;
- case colorCMYK:
- color->setCMYK(x[0], x[1], x[2], x[3]);
- break;
- case colorRGB:
- color->setRGB(x[0], x[1], x[2]);
- break;
- }
- }
- }
- #else
- 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;
- }
- }
- }
- #endif
-
- //------------------------------------------------------------------------
- // Function
- //------------------------------------------------------------------------
-
- void Function::ConstructL(Object *funcObj)
- {
- Stream *str;
- Dict *dict;
- int nSamples, sampleBits;
- double sampleMul;
- RAutoObject obj1, obj2;
- Guint buf, bitMask;
- int bits;
- int s;
- int i;
-
- ok = gFalse;
- samples = NULL;
-
- if (!funcObj->isStream()) {
- error(-1, R_EXPECTED_FUNCTION_DICTIONARY);
- goto err3;
- }
- str = funcObj->getStream();
- dict = str->getDict();
-
- //----- FunctionType
- if (!dict->lookupL("FunctionType", &obj1)->isInt() ||
- obj1.getInt() != 0) {
- error(-1, R_UNKNOWN_FUNCTION_TYPE);
- goto err2;
- }
- obj1.free();
-
- //----- Domain
- if (!dict->lookupL("Domain", &obj1)->isArray()) {
- error(-1, R_FUNCTION_IS_MISSING_DOMAIN);
- goto err2;
- }
- m = obj1.arrayGetLength() / 2;
- if (m > 1) {
- error(-1, R_FUNCTIONS_WITH_MORE_THAN_1_INPUT_ARE_UNSUPPORTED);
- goto err2;
- }
- for (i = 0; i < m; ++i) {
- obj1.arrayGetL(2*i, &obj2);
- if (!obj2.isNum()) {
- error(-1, R_ILLEGAL_VALUE_IN_FUNCTION_DOMAIN_ARRAY);
- goto err1;
- }
- domain[i][0] = obj2.getNum();
- obj2.free();
- obj1.arrayGetL(2*i+1, &obj2);
- if (!obj2.isNum()) {
- error(-1, R_ILLEGAL_VALUE_IN_FUNCTION_DOMAIN_ARRAY);
- goto err1;
- }
- domain[i][1] = obj2.getNum();
- obj2.free();
- }
- obj1.free();
-
- //----- Range
- if (!dict->lookupL("Range", &obj1)->isArray()) {
- error(-1, R_FUNCTION_IS_MISSING_RANGE);
- goto err2;
- }
- n = obj1.arrayGetLength() / 2;
- if (n > 4) {
- error(-1, R_FUNCTIONS_WITH_MORE_THAN_4_OUTPUTS_ARE_UNSUPPORTED);
- goto err2;
- }
- for (i = 0; i < n; ++i) {
- obj1.arrayGetL(2*i, &obj2);
- if (!obj2.isNum()) {
- error(-1, R_ILLEGAL_VALUE_IN_FUNCTION_RANGE_ARRAY);
- goto err1;
- }
- range[i][0] = obj2.getNum();
- obj2.free();
- obj1.arrayGetL(2*i+1, &obj2);
- if (!obj2.isNum()) {
- error(-1, R_ILLEGAL_VALUE_IN_FUNCTION_RANGE_ARRAY);
- goto err1;
- }
- range[i][1] = obj2.getNum();
- obj2.free();
- }
- obj1.free();
-
- //----- Size
- if (!dict->lookupL("Size", &obj1)->isArray() ||
- obj1.arrayGetLength() != m) {
- error(-1, R_FUNCTION_HAS_MISSING_OR_INVALID_SIZE_ARRAY);
- goto err2;
- }
- for (i = 0; i < m; ++i) {
- obj1.arrayGetL(i, &obj2);
- if (!obj2.isInt()) {
- error(-1, R_ILLEGAL_VALUE_IN_FUNCTION_SIZE_ARRAY);
- goto err1;
- }
- sampleSize[i] = obj2.getInt();
- obj2.free();
- }
- obj1.free();
-
- //----- BitsPerSample
- if (!dict->lookupL("BitsPerSample", &obj1)->isInt()) {
- error(-1, R_FUNCTION_HAS_MISSING_OR_INVALID_BITSPERSAMPLE);
- goto err2;
- }
- sampleBits = obj1.getInt();
- sampleMul = 1.0 / (double)((1 << sampleBits) - 1);
- obj1.free();
-
- //----- Encode
- if (dict->lookupL("Encode", &obj1)->isArray() &&
- obj1.arrayGetLength() == 2*m) {
- for (i = 0; i < m; ++i) {
- obj1.arrayGetL(2*i, &obj2);
- if (!obj2.isNum()) {
- error(-1, R_ILLEGAL_VALUE_IN_FUNCTION_ENCODE_ARRAY);
- goto err1;
- }
- encode[i][0] = obj2.getNum();
- obj2.free();
- obj1.arrayGetL(2*i+1, &obj2);
- if (!obj2.isNum()) {
- error(-1, R_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->lookupL("Decode", &obj1)->isArray() &&
- obj1.arrayGetLength() == 2*n) {
- for (i = 0; i < n; ++i) {
- obj1.arrayGetL(2*i, &obj2);
- if (!obj2.isNum()) {
- error(-1, R_ILLEGAL_VALUE_IN_FUNCTION_DECODE_ARRAY);
- goto err1;
- }
- decode[i][0] = obj2.getNum();
- obj2.free();
- obj1.arrayGetL(2*i+1, &obj2);
- if (!obj2.isNum()) {
- error(-1, R_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 *)User::AllocL(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;
- }
-
-
- void Function::ConstructL(Function *func)
- {
- int nSamples, i;
-
- m = func->m;
- n = func->n;
- Mem::Copy(domain, func->domain, sizeof(domain));
- Mem::Copy(range, func->range, sizeof(range));
- Mem::Copy(sampleSize, func->sampleSize, sizeof(sampleSize));
- Mem::Copy(encode, func->encode, sizeof(encode));
- Mem::Copy(decode, func->decode, sizeof(decode));
-
- nSamples = n;
- for (i = 0; i < m; ++i)
- nSamples *= sampleSize[i];
- samples = (double *)User::AllocL(nSamples * sizeof(double));
- Mem::Copy(samples, func->samples, nSamples * sizeof(double));
-
- ok = gTrue;
- }
-
- Function::~Function() {
- User::Free(samples);
- }
-
- Function *Function::copyL()
- {
- Function* self = new(ELeave) Function();
- CleanupStack::PushL(self);
- self->ConstructL(this);
- CleanupStack::Pop(); // self
- return self;
- }
-
-
- #ifdef FIXCOLOR
- void Function::transform(int* in, int* out) {
- int 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];
- }
- }
- #else
- 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];
- }
- }
- #endif
-
- //------------------------------------------------------------------------
- // GfxImageColorMap
- //------------------------------------------------------------------------
- GfxImageColorMap::GfxImageColorMap(GfxColorSpace *aColorSpace): colorSpace(aColorSpace) {}
-
- void GfxImageColorMap::ConstructL(int bits1, Object *decode) {
- GfxColor color;
- #ifdef FIXCOLOR
- int x[4];
- #else
- double x[4];
- #endif
- int maxPixel;
- RAutoObject obj;
- int i, j;
-
- ok = gTrue;
-
- // bits per component and colorspace
- bits = bits1;
- maxPixel = (1 << bits) - 1;
- mode = colorSpace->getMode();
-
- // work around a bug in Distiller (?)
- if (colorSpace->isIndexed() && maxPixel > colorSpace->getIndexHigh()) {
- maxPixel = colorSpace->getIndexHigh();
- }
-
- // get decode map
- if (decode->isNull()) {
- if (colorSpace->isIndexed()) {
- indexed = gTrue;
- numComps = 1;
- #if defined(FIXCOLOR)
- decodeLow[0] = 0;
- decodeRange[0] = maxPixel * 255;
- #else
- decodeLow[0] = 0;
- decodeRange[0] = maxPixel;
- #endif
- } else {
- indexed = gFalse;
- numComps = colorSpace->getNumPixelComps();
- for (i = 0; i < numComps; ++i) {
- #if defined(FIXCOLOR)
- decodeLow[i] = 0;
- decodeRange[i] = 255;
- #else
- decodeLow[i] = 0;
- decodeRange[i] = 1;
- #endif
- }
- }
- }
- else if (decode->isArray()) {
- numComps = decode->arrayGetLength() / 2;
- if (numComps != colorSpace->getNumPixelComps())
- goto err1;
- indexed = colorSpace->isIndexed();
- for (i = 0; i < numComps; ++i) {
- decode->arrayGetL(2*i, &obj);
- if (!obj.isNum())
- goto err2;
- #if defined(FIXCOLOR)
- decodeLow[i] = (int)(obj.getNum() * 255.0);
- #else
- decodeLow[i] = obj.getNum();
- #endif
- obj.free();
- decode->arrayGetL(2*i+1, &obj);
- if (!obj.isNum())
- goto err2;
- #if defined(FIXCOLOR)
- decodeRange[i] = (int)(obj.getNum() * 255.0) - decodeLow[i];
- #else
- decodeRange[i] = obj.getNum() - decodeLow[i];
- #endif
- obj.free();
- }
- } else {
- goto err1;
- }
-
- // construct lookup table
- #ifdef FIXCOLOR
- lookup = (int (*)[4])User::AllocL((maxPixel + 1) * 4 * sizeof(int));
- #else
- lookup = (double (*)[4])User::AllocL((maxPixel + 1) * 4 * sizeof(double));
- #endif
- if (indexed) {
- for (i = 0; i <= maxPixel; ++i) {
- #ifdef FIXCOLOR
- x[0] = i;
- #else
- x[0] = (double)i;
- #endif
- 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;
- User::Free(lookup);
- }
-
- /*
- #if defined(FIXCOLOR)
- void GfxImageColorMap::getColor(Guchar x[4], GfxColor *color) {
- int y[4];
- int i;
-
- if (simpleDecode) {
- for (i = 0; i < decodeComps; ++i) {
- y[i] = (((int)x[i]) * 255) / maxPixel;
- }
- } else if (indexDecode) {
- y[0] = x[0];
- } else {
- for (i = 0; i < decodeComps; ++i) {
- y[i] = (decodeLow[i] + (((int)x[i]) * decodeRange[i]) / maxPixel) / 256;
- // y[i] = decodeLow[i] + (((int)x[i]) * decodeRange[i]) / maxPixel;
- }
- }
- colorSpace->getColor(y, color);
- }
- #else
- */
- void GfxImageColorMap::getColor(Guchar x[4], GfxColor *color) {
- #ifdef FIXCOLOR
- int* p;
- #else
- double *p;
- #endif
-
- 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;
- }
- }
- }
- //#endif
-
- //------------------------------------------------------------------------
- // GfxSubpath and GfxPath
- //------------------------------------------------------------------------
-
- void GfxSubpath::ConstructL(double x1, double y1) {
- size = 16;
- x = (double *)User::AllocL(size * sizeof(double));
- y = (double *)User::AllocL(size * sizeof(double));
- curve = (GBool *)User::AllocL(size * sizeof(GBool));
- n = 1;
- x[0] = x1;
- y[0] = y1;
- curve[0] = gFalse;
- closed = gFalse;
- }
-
- GfxSubpath::~GfxSubpath() {
- User::Free(x);
- User::Free(y);
- User::Free(curve);
- }
-
- // Used for copy().
- void GfxSubpath::ConstructL(GfxSubpath *subpath) {
- size = subpath->size;
- n = subpath->n;
- x = (double *)User::AllocL(size * sizeof(double));
- y = (double *)User::AllocL(size * sizeof(double));
- curve = (GBool *)User::AllocL(size * sizeof(GBool));
- Mem::Copy(x, subpath->x, n * sizeof(double));
- Mem::Copy(y, subpath->y, n * sizeof(double));
- Mem::Copy(curve, subpath->curve, n * sizeof(GBool));
- closed = subpath->closed;
- }
-
- GfxSubpath *GfxSubpath::copyL()
- {
- GfxSubpath* self = new(ELeave) GfxSubpath();
- CleanupStack::PushL(self);
- self->ConstructL(this);
- CleanupStack::Pop(); // self
- return self;
- }
-
- void GfxSubpath::lineTo(double x1, double y1) {
- if (n >= size) {
- size += KSubpathSizeIncrement;
- x = (double *)User::ReAllocL(x, size * sizeof(double));
- y = (double *)User::ReAllocL(y, size * sizeof(double));
- curve = (GBool *)User::ReAllocL(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 += KSubpathSizeIncrement;
- x = (double *)User::ReAllocL(x, size * sizeof(double));
- y = (double *)User::ReAllocL(y, size * sizeof(double));
- curve = (GBool *)User::ReAllocL(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;
- }
-
- void GfxSubpath::close() {
- if (x[n-1] != x[0] || y[n-1] != y[0]) {
- lineTo(x[0], y[0]);
- }
- closed = gTrue;
- }
-
- void GfxPath::ConstructL() {
- justMoved = gFalse;
- size = 16;
- n = 0;
- firstX = firstY = 0;
- subpaths = (GfxSubpath **)User::AllocL(size * sizeof(GfxSubpath *));
- }
-
- GfxPath::~GfxPath() {
- int i;
-
- if (subpaths)
- for (i = 0; i < n; ++i)
- delete subpaths[i];
- User::Free(subpaths);
- }
-
- // Used for copy().
- void GfxPath::ConstructL(GBool justMoved1, double firstX1, double firstY1,
- GfxSubpath **subpaths1, int n1, int size1) {
- int i;
-
- justMoved = justMoved1;
- firstX = firstX1;
- firstY = firstY1;
- size = size1;
- n = 0;
- subpaths = (GfxSubpath **)User::AllocL(size * sizeof(GfxSubpath *));
- // init with no subpaths for cleanup
- n = n1;
- for (i = 0; i < n; ++i)
- subpaths[i] = 0;
- for (i = 0; i < n; ++i)
- subpaths[i] = subpaths1[i]->copyL();
- }
-
- GfxPath *GfxPath::copyL()
- {
- GfxPath* self = new(ELeave) GfxPath();
- CleanupStack::PushL(self);
- self->ConstructL(justMoved, firstX, firstY, subpaths, n, size);
- CleanupStack::Pop(); // self
- return self;
- }
-
- 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 += KPathSizeIncrement;
- subpaths = (GfxSubpath **)
- User::ReAllocL(subpaths, size * sizeof(GfxSubpath *));
- }
- // increment after allocation so subpath can be cleaned up
- subpaths[n] = new(ELeave) GfxSubpath();
- ++n;
- subpaths[n-1]->ConstructL(firstX, firstY);
- 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 += KPathSizeIncrement;
- subpaths = (GfxSubpath **)
- User::ReAllocL(subpaths, size * sizeof(GfxSubpath *));
- }
- // increment after allocation so subpath can be cleaned up
- subpaths[n] = new(ELeave) GfxSubpath();
- ++n;
- subpaths[n-1]->ConstructL(firstX, firstY);
- justMoved = gFalse;
- }
- subpaths[n-1]->curveTo(x1, y1, x2, y2, x3, y3);
- }
-
-
- //------------------------------------------------------------------------
- // GfxState
- //------------------------------------------------------------------------
-
- void GfxState::ConstructL(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(ELeave) GfxColorSpace(colorGray);
- strokeColorSpace = new(ELeave) 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(ELeave) GfxPath();
- path->ConstructL();
- curX = curY = 0;
- lineX = lineY = 0;
-
- saved = NULL;
- }
-
- GfxState::~GfxState() {
- delete fillColorSpace;
- delete strokeColorSpace;
- User::Free(lineDash);
- delete path;
- delete saved;
- }
-
- // Used for copy();
- void GfxState::ConstructL(GfxState *state) {
-
- Mem::Copy(this, state, sizeof(GfxState));
- // clear pointers first, so cleanup won't delete vars twice
- fillColorSpace = 0;
- strokeColorSpace = 0;
- lineDash = 0;
- path = 0;
- saved = NULL;
- if (state->fillColorSpace)
- fillColorSpace = state->fillColorSpace->copyL();
- if (state->strokeColorSpace)
- strokeColorSpace = state->strokeColorSpace->copyL();
- if (lineDashLength > 0) {
- lineDash = (double *)User::AllocL(lineDashLength * sizeof(double));
- Mem::Copy(lineDash, state->lineDash, lineDashLength * sizeof(double));
- }
- path = state->path->copyL();
- }
-
- GfxState *GfxState::copyL()
- {
- GfxState* self = new(ELeave) GfxState();
- CleanupStack::PushL(self);
- self->ConstructL(this);
- CleanupStack::Pop(); // self
- return self;
- }
-
-
- void GfxState::transform(double x1, double y1, double *x2, double *y2)
- {
- *x2 = ctm[0] * x1 + ctm[2] * y1 + ctm[4];
- *y2 = ctm[1] * x1 + ctm[3] * y1 + ctm[5];
- }
-
- void GfxState::transformDelta(double x1, double y1, double *x2, double *y2)
- {
- *x2 = ctm[0] * x1 + ctm[2] * y1;
- *y2 = ctm[1] * x1 + ctm[3] * y1;
- }
-
- void GfxState::textTransform(double x1, double y1, double *x2, double *y2)
- {
- *x2 = textMat[0] * x1 + textMat[2] * y1 + textMat[4];
- *y2 = textMat[1] * x1 + textMat[3] * y1 + textMat[5];
- }
-
- void GfxState::textTransformDelta(double x1, double y1, double *x2, double *y2)
- {
- *x2 = textMat[0] * x1 + textMat[2] * y1;
- *y2 = textMat[1] * x1 + textMat[3] * y1;
- }
-
- // special when y1 == 0
- void GfxState::textTransformDelta(double x1, double *x2, double *y2)
- {
- *x2 = textMat[0] * x1;
- *y2 = textMat[1] * x1;
- }
-
- double GfxState::transformWidth(double w) {
- double x, y;
-
- x = ctm[0] + ctm[2];
- y = ctm[1] + ctm[3];
- double res;
- (void)Math::Sqrt(res, 0.5 * (x * x + y * y));
- return w * res;
- }
-
- 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;
- double res;
- (void)Math::Sqrt(res,x2 * x2 + y2 * y2);
- return res;
- }
-
- 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::setCTM(double a, double b, double c,
- double d, double e, double f) {
- ctm[0] = a;
- ctm[1] = b;
- ctm[2] = c;
- ctm[3] = d;
- ctm[4] = e;
- ctm[5] = f;
- }
-
- 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::setTextMat(double a, double b, double c,
- double d, double e, double f)
- {
- textMat[0] = a; textMat[1] = b; textMat[2] = c;
- textMat[3] = d; textMat[4] = e; textMat[5] = f;
- }
-
- void GfxState::setFillColorSpace(GfxColorSpace *colorSpace) {
- delete fillColorSpace;
- fillColorSpace = colorSpace;
- }
-
- void GfxState::setStrokeColorSpace(GfxColorSpace *colorSpace) {
- delete strokeColorSpace;
- strokeColorSpace = colorSpace;
- }
-
- void GfxState::setLineDash(double *dash, int length, double start) {
- User::Free(lineDash);
- lineDash = dash;
- lineDashLength = length;
- lineDashStart = start;
- }
-
- void GfxState::clearPath() {
- delete path;
- path = 0;
- path = new(ELeave) GfxPath();
- path->ConstructL();
- }
-
- void GfxState::textShift(double tx) {
- double dx, dy;
-
- // faster transform with zero height
- textTransformDelta(tx, 0, &dx, &dy);
- curX += dx;
- curY += dy;
- }
-
- void GfxState::textShift(double tx, double ty) {
- double dx, dy;
-
- textTransformDelta(tx, ty, &dx, &dy);
- curX += dx;
- curY += dy;
- }
-
- GfxState *GfxState::save() {
- GfxState *newState;
-
- newState = copyL();
- newState->saved = this;
- return newState;
- }
-
- GfxState *GfxState::restore() {
- GfxState *oldState;
-
- if (saved) {
- oldState = saved;
- saved = NULL;
- delete this;
- } else {
- oldState = this;
- }
- return oldState;
- }
-