From ad63666daeeda50acc7630132d61fe044634fddd Mon Sep 17 00:00:00 2001 From: Martin Kretzschmar Date: Sun, 16 May 2004 22:45:42 +0000 Subject: Imported Xpdf 2.03 and fixed build. * ANNOUNCE: * CHANGES: * README: * aconf2.h: * configure.in: * dj_make.bat: * doc/pdffonts.1: * doc/pdffonts.cat: * doc/pdffonts.hlp: * doc/pdfimages.1: * doc/pdfimages.cat: * doc/pdfimages.hlp: * doc/pdfinfo.1: * doc/pdfinfo.cat: * doc/pdfinfo.hlp: * doc/pdftopbm.1: * doc/pdftopbm.cat: * doc/pdftopbm.hlp: * doc/pdftops.1: * doc/pdftops.cat: * doc/pdftops.hlp: * doc/pdftotext.1: * doc/pdftotext.cat: * doc/pdftotext.hlp: * doc/xpdf.1: * doc/xpdf.cat: * doc/xpdf.hlp: * doc/xpdfrc.5: * doc/xpdfrc.cat: * doc/xpdfrc.hlp: * goo/gfile.cc: * ms_make.bat: * vms_make.com: * xpdf/Annot.cc: * xpdf/Array.cc: * xpdf/BuiltinFontTables.cc: * xpdf/CMap.cc: * xpdf/CMap.h: * xpdf/Catalog.cc: * xpdf/CharCodeToUnicode.cc: * xpdf/CharCodeToUnicode.h: * xpdf/Decrypt.cc: * xpdf/Dict.cc: * xpdf/ErrorCodes.h: * xpdf/FTFont.cc: * xpdf/FTFont.h: * xpdf/FontFile.cc: * xpdf/FontFile.h: * xpdf/Function.cc: * xpdf/Gfx.cc: * xpdf/Gfx.h: * xpdf/GfxFont.cc: * xpdf/GfxFont.h: * xpdf/GfxState.cc: * xpdf/GfxState.h: * xpdf/GlobalParams.cc: * xpdf/GlobalParams.h: * xpdf/JBIG2Stream.cc: * xpdf/Link.cc: * xpdf/Link.h: * xpdf/Makefile.am: * xpdf/OutputDev.h: * xpdf/PDFDoc.cc: * xpdf/PDFDoc.h: * xpdf/PSOutputDev.cc: * xpdf/PSOutputDev.h: * xpdf/Page.cc: * xpdf/Page.h: * xpdf/Parser.cc: * xpdf/Stream.cc: * xpdf/Stream.h: * xpdf/TTFont.cc: * xpdf/TTFont.h: * xpdf/TextOutputDev.cc: * xpdf/TextOutputDev.h: * xpdf/UnicodeMap.cc: * xpdf/UnicodeMap.h: * xpdf/UnicodeTypeTable.cc: * xpdf/UnicodeTypeTable.h: * xpdf/XOutputDev.cc: * xpdf/XOutputDev.h: * xpdf/XPDFApp.cc: * xpdf/XPDFCore.cc: * xpdf/XPDFCore.h: * xpdf/XPDFViewer.cc: * xpdf/XPDFViewer.h: * xpdf/XRef.cc: * xpdf/about-text.h: * xpdf/config.h: * xpdf/gpdf-control.cc: * xpdf/gpdf-link-canvas-item.cc: * xpdf/gpdf-links-canvas-layer.cc: * xpdf/pdffonts.cc: * xpdf/pdfimages.cc: * xpdf/pdfinfo.cc: * xpdf/pdftopbm.cc: * xpdf/pdftops.cc: * xpdf/pdftotext.cc: * xpdf/tests/test-links.cc: * xpdf/vms_make.com: * xpdf/xpdf.cc: Imported Xpdf 2.03 and fixed build. --- (limited to 'pdf/xpdf/GfxState.cc') diff --git a/pdf/xpdf/GfxState.cc b/pdf/xpdf/GfxState.cc index 7efd0b9..d202939 100644 --- a/pdf/xpdf/GfxState.cc +++ b/pdf/xpdf/GfxState.cc @@ -98,7 +98,7 @@ GfxColorSpace *GfxColorSpace::parse(Object *csObj) { } else if (obj1.isName("Pattern")) { cs = GfxPatternColorSpace::parse(csObj->getArray()); } else { - error(-1, "Bad color space '%s'", csObj->getName()); + error(-1, "Bad color space"); } obj1.free(); } else { @@ -1181,18 +1181,22 @@ GfxPattern::~GfxPattern() { GfxPattern *GfxPattern::parse(Object *obj) { GfxPattern *pattern; - Dict *dict; Object obj1; + if (obj->isDict()) { + obj->dictLookup("PatternType", &obj1); + } else if (obj->isStream()) { + obj->streamGetDict()->lookup("PatternType", &obj1); + } else { + return NULL; + } pattern = NULL; - if (obj->isStream()) { - dict = obj->streamGetDict(); - dict->lookup("PatternType", &obj1); - if (obj1.isInt() && obj1.getInt() == 1) { - pattern = new GfxTilingPattern(dict, obj); - } - obj1.free(); + if (obj1.isInt() && obj1.getInt() == 1) { + pattern = GfxTilingPattern::parse(obj); + } else if (obj1.isInt() && obj1.getInt() == 2) { + pattern = GfxShadingPattern::parse(obj); } + obj1.free(); return pattern; } @@ -1200,33 +1204,42 @@ GfxPattern *GfxPattern::parse(Object *obj) { // GfxTilingPattern //------------------------------------------------------------------------ -GfxTilingPattern::GfxTilingPattern(Dict *streamDict, Object *stream): - GfxPattern(1) -{ +GfxTilingPattern *GfxTilingPattern::parse(Object *patObj) { + GfxTilingPattern *pat; + Dict *dict; + int paintTypeA, tilingTypeA; + double bboxA[4], matrixA[6]; + double xStepA, yStepA; + Object resDictA; Object obj1, obj2; int i; - if (streamDict->lookup("PaintType", &obj1)->isInt()) { - paintType = obj1.getInt(); + if (!patObj->isStream()) { + return NULL; + } + dict = patObj->streamGetDict(); + + if (dict->lookup("PaintType", &obj1)->isInt()) { + paintTypeA = obj1.getInt(); } else { - paintType = 1; + paintTypeA = 1; error(-1, "Invalid or missing PaintType in pattern"); } obj1.free(); - if (streamDict->lookup("TilingType", &obj1)->isInt()) { - tilingType = obj1.getInt(); + if (dict->lookup("TilingType", &obj1)->isInt()) { + tilingTypeA = obj1.getInt(); } else { - tilingType = 1; + tilingTypeA = 1; error(-1, "Invalid or missing TilingType in pattern"); } obj1.free(); - bbox[0] = bbox[1] = 0; - bbox[2] = bbox[3] = 1; - if (streamDict->lookup("BBox", &obj1)->isArray() && + bboxA[0] = bboxA[1] = 0; + bboxA[2] = bboxA[3] = 1; + if (dict->lookup("BBox", &obj1)->isArray() && obj1.arrayGetLength() == 4) { for (i = 0; i < 4; ++i) { if (obj1.arrayGet(i, &obj2)->isNum()) { - bbox[i] = obj2.getNum(); + bboxA[i] = obj2.getNum(); } obj2.free(); } @@ -1234,39 +1247,65 @@ GfxTilingPattern::GfxTilingPattern(Dict *streamDict, Object *stream): error(-1, "Invalid or missing BBox in pattern"); } obj1.free(); - if (streamDict->lookup("XStep", &obj1)->isNum()) { - xStep = obj1.getNum(); + if (dict->lookup("XStep", &obj1)->isNum()) { + xStepA = obj1.getNum(); } else { - xStep = 1; + xStepA = 1; error(-1, "Invalid or missing XStep in pattern"); } obj1.free(); - if (streamDict->lookup("YStep", &obj1)->isNum()) { - yStep = obj1.getNum(); + if (dict->lookup("YStep", &obj1)->isNum()) { + yStepA = obj1.getNum(); } else { - yStep = 1; + yStepA = 1; error(-1, "Invalid or missing YStep in pattern"); } obj1.free(); - if (!streamDict->lookup("Resources", &resDict)->isDict()) { - resDict.free(); - resDict.initNull(); + if (!dict->lookup("Resources", &resDictA)->isDict()) { + resDictA.free(); + resDictA.initNull(); error(-1, "Invalid or missing Resources in pattern"); } - matrix[0] = 1; matrix[1] = 0; - matrix[2] = 0; matrix[3] = 1; - matrix[4] = 0; matrix[5] = 0; - if (streamDict->lookup("Matrix", &obj1)->isArray() && + matrixA[0] = 1; matrixA[1] = 0; + matrixA[2] = 0; matrixA[3] = 1; + matrixA[4] = 0; matrixA[5] = 0; + if (dict->lookup("Matrix", &obj1)->isArray() && obj1.arrayGetLength() == 6) { for (i = 0; i < 6; ++i) { if (obj1.arrayGet(i, &obj2)->isNum()) { - matrix[i] = obj2.getNum(); + matrixA[i] = obj2.getNum(); } obj2.free(); } } obj1.free(); - stream->copy(&contentStream); + + pat = new GfxTilingPattern(paintTypeA, tilingTypeA, bboxA, xStepA, yStepA, + &resDictA, matrixA, patObj); + resDictA.free(); + return pat; +} + +GfxTilingPattern::GfxTilingPattern(int paintTypeA, int tilingTypeA, + double *bboxA, double xStepA, double yStepA, + Object *resDictA, double *matrixA, + Object *contentStreamA): + GfxPattern(1) +{ + int i; + + paintType = paintTypeA; + tilingType = tilingTypeA; + for (i = 0; i < 4; ++i) { + bbox[i] = bboxA[i]; + } + xStep = xStepA; + yStep = yStepA; + resDictA->copy(&resDict); + for (i = 0; i < 6; ++i) { + matrix[i] = matrixA[i]; + } + contentStreamA->copy(&contentStream); } GfxTilingPattern::~GfxTilingPattern() { @@ -1275,127 +1314,341 @@ GfxTilingPattern::~GfxTilingPattern() { } GfxPattern *GfxTilingPattern::copy() { - return new GfxTilingPattern(this); + return new GfxTilingPattern(paintType, tilingType, bbox, xStep, yStep, + &resDict, matrix, &contentStream); } -GfxTilingPattern::GfxTilingPattern(GfxTilingPattern *pat): - GfxPattern(1) +//------------------------------------------------------------------------ +// GfxShadingPattern +//------------------------------------------------------------------------ + +GfxShadingPattern *GfxShadingPattern::parse(Object *patObj) { + Dict *dict; + GfxShading *shadingA; + double matrixA[6]; + Object obj1, obj2; + int i; + + if (!patObj->isDict()) { + return NULL; + } + dict = patObj->getDict(); + + dict->lookup("Shading", &obj1); + shadingA = GfxShading::parse(&obj1); + obj1.free(); + if (!shadingA) { + return NULL; + } + + matrixA[0] = 1; matrixA[1] = 0; + matrixA[2] = 0; matrixA[3] = 1; + matrixA[4] = 0; matrixA[5] = 0; + if (dict->lookup("Matrix", &obj1)->isArray() && + obj1.arrayGetLength() == 6) { + for (i = 0; i < 6; ++i) { + if (obj1.arrayGet(i, &obj2)->isNum()) { + matrixA[i] = obj2.getNum(); + } + obj2.free(); + } + } + obj1.free(); + + return new GfxShadingPattern(shadingA, matrixA); +} + +GfxShadingPattern::GfxShadingPattern(GfxShading *shadingA, double *matrixA): + GfxPattern(2) { - memcpy(this, pat, sizeof(GfxTilingPattern)); - pat->resDict.copy(&resDict); - pat->contentStream.copy(&contentStream); + int i; + + shading = shadingA; + for (i = 0; i < 6; ++i) { + matrix[i] = matrixA[i]; + } +} + +GfxShadingPattern::~GfxShadingPattern() { + delete shading; +} + +GfxPattern *GfxShadingPattern::copy() { + return new GfxShadingPattern(shading->copy(), matrix); } //------------------------------------------------------------------------ // GfxShading //------------------------------------------------------------------------ -GfxShading::GfxShading() { +GfxShading::GfxShading(int typeA) { + type = typeA; + colorSpace = NULL; +} + +GfxShading::GfxShading(GfxShading *shading) { + int i; + + type = shading->type; + colorSpace = shading->colorSpace->copy(); + for (i = 0; i < gfxColorMaxComps; ++i) { + background.c[i] = shading->background.c[i]; + } + hasBackground = shading->hasBackground; + xMin = shading->xMin; + yMin = shading->yMin; + xMax = shading->xMax; + yMax = shading->yMax; + hasBBox = shading->hasBBox; } GfxShading::~GfxShading() { - delete colorSpace; + if (colorSpace) { + delete colorSpace; + } } GfxShading *GfxShading::parse(Object *obj) { GfxShading *shading; + Dict *dict; int typeA; - GfxColorSpace *colorSpaceA; - GfxColor backgroundA; - GBool hasBackgroundA; - double xMinA, yMinA, xMaxA, yMaxA; - GBool hasBBoxA; - Object obj1, obj2; - int i; + Object obj1; - shading = NULL; if (obj->isDict()) { + dict = obj->getDict(); + } else if (obj->isStream()) { + dict = obj->streamGetDict(); + } else { + return NULL; + } - if (!obj->dictLookup("ShadingType", &obj1)->isInt()) { - error(-1, "Invalid ShadingType in shading dictionary"); - obj1.free(); - goto err1; - } - typeA = obj1.getInt(); + if (!dict->lookup("ShadingType", &obj1)->isInt()) { + error(-1, "Invalid ShadingType in shading dictionary"); obj1.free(); + return NULL; + } + typeA = obj1.getInt(); + obj1.free(); - obj->dictLookup("ColorSpace", &obj1); - if (!(colorSpaceA = GfxColorSpace::parse(&obj1))) { - error(-1, "Bad color space in shading dictionary"); - obj1.free(); - goto err1; - } - obj1.free(); + switch (typeA) { + case 1: + shading = GfxFunctionShading::parse(dict); + break; + case 2: + shading = GfxAxialShading::parse(dict); + break; + case 3: + shading = GfxRadialShading::parse(dict); + break; + default: + error(-1, "Unimplemented shading type %d", typeA); + goto err1; + } - for (i = 0; i < gfxColorMaxComps; ++i) { - backgroundA.c[i] = 0; - } - hasBackgroundA = gFalse; - if (obj->dictLookup("Background", &obj1)->isArray()) { - if (obj1.arrayGetLength() == colorSpaceA->getNComps()) { - hasBackgroundA = gTrue; - for (i = 0; i < colorSpaceA->getNComps(); ++i) { - backgroundA.c[i] = obj1.arrayGet(i, &obj2)->getNum(); - obj2.free(); - } - } else { - error(-1, "Bad Background in shading dictionary"); - } - } + return shading; + + err1: + return NULL; +} + +GBool GfxShading::init(Dict *dict) { + Object obj1, obj2; + int i; + + dict->lookup("ColorSpace", &obj1); + if (!(colorSpace = GfxColorSpace::parse(&obj1))) { + error(-1, "Bad color space in shading dictionary"); obj1.free(); + return gFalse; + } + obj1.free(); - xMinA = yMinA = xMaxA = yMaxA = 0; - hasBBoxA = gFalse; - if (obj->dictLookup("BBox", &obj1)->isArray()) { - if (obj1.arrayGetLength() == 4) { - hasBBoxA = gTrue; - xMinA = obj1.arrayGet(0, &obj2)->getNum(); - obj2.free(); - yMinA = obj1.arrayGet(1, &obj2)->getNum(); - obj2.free(); - xMaxA = obj1.arrayGet(2, &obj2)->getNum(); - obj2.free(); - yMaxA = obj1.arrayGet(3, &obj2)->getNum(); + for (i = 0; i < gfxColorMaxComps; ++i) { + background.c[i] = 0; + } + hasBackground = gFalse; + if (dict->lookup("Background", &obj1)->isArray()) { + if (obj1.arrayGetLength() == colorSpace->getNComps()) { + hasBackground = gTrue; + for (i = 0; i < colorSpace->getNComps(); ++i) { + background.c[i] = obj1.arrayGet(i, &obj2)->getNum(); obj2.free(); - } else { - error(-1, "Bad BBox in shading dictionary"); } + } else { + error(-1, "Bad Background in shading dictionary"); } - obj1.free(); + } + obj1.free(); - switch (typeA) { - case 2: - shading = GfxAxialShading::parse(obj->getDict()); - break; - case 3: - shading = GfxRadialShading::parse(obj->getDict()); - break; - default: - error(-1, "Unimplemented shading type %d", typeA); - goto err1; + xMin = yMin = xMax = yMax = 0; + hasBBox = gFalse; + if (dict->lookup("BBox", &obj1)->isArray()) { + if (obj1.arrayGetLength() == 4) { + hasBBox = gTrue; + xMin = obj1.arrayGet(0, &obj2)->getNum(); + obj2.free(); + yMin = obj1.arrayGet(1, &obj2)->getNum(); + obj2.free(); + xMax = obj1.arrayGet(2, &obj2)->getNum(); + obj2.free(); + yMax = obj1.arrayGet(3, &obj2)->getNum(); + obj2.free(); + } else { + error(-1, "Bad BBox in shading dictionary"); } + } + obj1.free(); - if (shading) { - shading->type = typeA; - shading->colorSpace = colorSpaceA; - shading->background = backgroundA; - shading->hasBackground = hasBackgroundA; - shading->xMin = xMinA; - shading->yMin = yMinA; - shading->xMax = xMaxA; - shading->yMax = yMaxA; - shading->hasBBox = hasBBoxA; - } else { - delete colorSpaceA; + return gTrue; +} + +//------------------------------------------------------------------------ +// GfxFunctionShading +//------------------------------------------------------------------------ + +GfxFunctionShading::GfxFunctionShading(double x0A, double y0A, + double x1A, double y1A, + double *matrixA, + Function **funcsA, int nFuncsA): + GfxShading(1) +{ + int i; + + x0 = x0A; + y0 = y0A; + x1 = x1A; + y1 = y1A; + for (i = 0; i < 6; ++i) { + matrix[i] = matrixA[i]; + } + nFuncs = nFuncsA; + for (i = 0; i < nFuncs; ++i) { + funcs[i] = funcsA[i]; + } +} + +GfxFunctionShading::GfxFunctionShading(GfxFunctionShading *shading): + GfxShading(shading) +{ + int i; + + x0 = shading->x0; + y0 = shading->y0; + x1 = shading->x1; + y1 = shading->y1; + for (i = 0; i < 6; ++i) { + matrix[i] = shading->matrix[i]; + } + nFuncs = shading->nFuncs; + for (i = 0; i < nFuncs; ++i) { + funcs[i] = shading->funcs[i]->copy(); + } +} + +GfxFunctionShading::~GfxFunctionShading() { + int i; + + for (i = 0; i < nFuncs; ++i) { + delete funcs[i]; + } +} + +GfxFunctionShading *GfxFunctionShading::parse(Dict *dict) { + GfxFunctionShading *shading; + double x0A, y0A, x1A, y1A; + double matrixA[6]; + Function *funcsA[gfxColorMaxComps]; + int nFuncsA; + Object obj1, obj2; + int i; + + x0A = y0A = 0; + x1A = y1A = 1; + if (dict->lookup("Domain", &obj1)->isArray() && + obj1.arrayGetLength() == 4) { + x0A = obj1.arrayGet(0, &obj2)->getNum(); + obj2.free(); + y0A = obj1.arrayGet(1, &obj2)->getNum(); + obj2.free(); + x1A = obj1.arrayGet(2, &obj2)->getNum(); + obj2.free(); + y1A = obj1.arrayGet(3, &obj2)->getNum(); + obj2.free(); + } + obj1.free(); + + matrixA[0] = 1; matrixA[1] = 0; + matrixA[2] = 0; matrixA[3] = 1; + matrixA[4] = 0; matrixA[5] = 0; + if (dict->lookup("Matrix", &obj1)->isArray() && + obj1.arrayGetLength() == 6) { + matrixA[0] = obj1.arrayGet(0, &obj2)->getNum(); + obj2.free(); + matrixA[1] = obj1.arrayGet(1, &obj2)->getNum(); + obj2.free(); + matrixA[2] = obj1.arrayGet(2, &obj2)->getNum(); + obj2.free(); + matrixA[3] = obj1.arrayGet(3, &obj2)->getNum(); + obj2.free(); + matrixA[4] = obj1.arrayGet(4, &obj2)->getNum(); + obj2.free(); + matrixA[5] = obj1.arrayGet(5, &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))) { + goto err2; + } + obj2.free(); + } + } else { + nFuncsA = 1; + if (!(funcsA[0] = Function::parse(&obj1))) { + goto err1; } } + obj1.free(); + shading = new GfxFunctionShading(x0A, y0A, x1A, y1A, matrixA, + funcsA, nFuncsA); + if (!shading->init(dict)) { + delete shading; + return NULL; + } return shading; + err2: + obj2.free(); err1: + obj1.free(); return NULL; } +GfxShading *GfxFunctionShading::copy() { + return new GfxFunctionShading(this); +} + +void GfxFunctionShading::getColor(double x, double y, GfxColor *color) { + double in[2]; + int i; + + in[0] = x; + in[1] = y; + for (i = 0; i < nFuncs; ++i) { + funcs[i]->transform(in, &color->c[i]); + } +} + //------------------------------------------------------------------------ // GfxAxialShading //------------------------------------------------------------------------ @@ -1404,7 +1657,9 @@ GfxAxialShading::GfxAxialShading(double x0A, double y0A, double x1A, double y1A, double t0A, double t1A, Function **funcsA, int nFuncsA, - GBool extend0A, GBool extend1A) { + GBool extend0A, GBool extend1A): + GfxShading(2) +{ int i; x0 = x0A; @@ -1421,6 +1676,25 @@ GfxAxialShading::GfxAxialShading(double x0A, double y0A, extend1 = extend1A; } +GfxAxialShading::GfxAxialShading(GfxAxialShading *shading): + GfxShading(shading) +{ + int i; + + x0 = shading->x0; + y0 = shading->y0; + x1 = shading->x1; + y1 = shading->y1; + t0 = shading->t0; + y1 = shading->t1; + nFuncs = shading->nFuncs; + for (i = 0; i < nFuncs; ++i) { + funcs[i] = shading->funcs[i]->copy(); + } + extend0 = shading->extend0; + extend1 = shading->extend1; +} + GfxAxialShading::~GfxAxialShading() { int i; @@ -1430,6 +1704,7 @@ GfxAxialShading::~GfxAxialShading() { } GfxAxialShading *GfxAxialShading::parse(Dict *dict) { + GfxAxialShading *shading; double x0A, y0A, x1A, y1A; double t0A, t1A; Function *funcsA[gfxColorMaxComps]; @@ -1469,6 +1744,10 @@ GfxAxialShading *GfxAxialShading::parse(Dict *dict) { 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))) { @@ -1497,16 +1776,27 @@ GfxAxialShading *GfxAxialShading::parse(Dict *dict) { } obj1.free(); - return new GfxAxialShading(x0A, y0A, x1A, y1A, t0A, t1A, - funcsA, nFuncsA, extend0A, extend1A); + shading = new GfxAxialShading(x0A, y0A, x1A, y1A, t0A, t1A, + funcsA, nFuncsA, extend0A, extend1A); + if (!shading->init(dict)) { + delete shading; + return NULL; + } + return shading; err1: return NULL; } +GfxShading *GfxAxialShading::copy() { + return new GfxAxialShading(this); +} + void GfxAxialShading::getColor(double t, GfxColor *color) { 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 < nFuncs; ++i) { funcs[i]->transform(&t, &color->c[i]); } @@ -1520,7 +1810,9 @@ GfxRadialShading::GfxRadialShading(double x0A, double y0A, double r0A, double x1A, double y1A, double r1A, double t0A, double t1A, Function **funcsA, int nFuncsA, - GBool extend0A, GBool extend1A) { + GBool extend0A, GBool extend1A): + GfxShading(3) +{ int i; x0 = x0A; @@ -1539,6 +1831,27 @@ GfxRadialShading::GfxRadialShading(double x0A, double y0A, double r0A, extend1 = extend1A; } +GfxRadialShading::GfxRadialShading(GfxRadialShading *shading): + GfxShading(shading) +{ + int i; + + x0 = shading->x0; + y0 = shading->y0; + r0 = shading->r0; + x1 = shading->x1; + y1 = shading->y1; + r1 = shading->r1; + t0 = shading->t0; + y1 = shading->t1; + nFuncs = shading->nFuncs; + for (i = 0; i < nFuncs; ++i) { + funcs[i] = shading->funcs[i]->copy(); + } + extend0 = shading->extend0; + extend1 = shading->extend1; +} + GfxRadialShading::~GfxRadialShading() { int i; @@ -1548,6 +1861,7 @@ GfxRadialShading::~GfxRadialShading() { } GfxRadialShading *GfxRadialShading::parse(Dict *dict) { + GfxRadialShading *shading; double x0A, y0A, r0A, x1A, y1A, r1A; double t0A, t1A; Function *funcsA[gfxColorMaxComps]; @@ -1591,6 +1905,10 @@ GfxRadialShading *GfxRadialShading::parse(Dict *dict) { 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))) { @@ -1619,16 +1937,27 @@ GfxRadialShading *GfxRadialShading::parse(Dict *dict) { } obj1.free(); - return new GfxRadialShading(x0A, y0A, r0A, x1A, y1A, r1A, t0A, t1A, - funcsA, nFuncsA, extend0A, extend1A); + 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) { 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 < nFuncs; ++i) { funcs[i]->transform(&t, &color->c[i]); } @@ -1741,6 +2070,36 @@ GfxImageColorMap::GfxImageColorMap(int bitsA, Object *decode, ok = gFalse; } +GfxImageColorMap::GfxImageColorMap(GfxImageColorMap *colorMap) { + int n, i; + + colorSpace = colorMap->colorSpace->copy(); + bits = colorMap->bits; + nComps = colorMap->nComps; + nComps2 = colorMap->nComps2; + colorSpace2 = NULL; + lookup = NULL; + if (colorSpace->getMode() == csIndexed) { + colorSpace2 = ((GfxIndexedColorSpace *)colorSpace)->getBase(); + n = ((GfxIndexedColorSpace *)colorSpace)->getIndexHigh(); + n = (n + 1) * nComps2 * sizeof(double); + } else if (colorSpace->getMode() == csSeparation) { + colorSpace2 = ((GfxSeparationColorSpace *)colorSpace)->getAlt(); + n = (1 << bits) - 1; + n = (n + 1) * nComps2 * sizeof(double); + } else { + n = (1 << bits) - 1; + n = (n + 1) * nComps * sizeof(double); + } + lookup = (double *)gmalloc(n); + memcpy(lookup, colorMap->lookup, n); + for (i = 0; i < nComps; ++i) { + decodeLow[i] = colorMap->decodeLow[i]; + decodeRange[i] = colorMap->decodeRange[i]; + } + ok = gTrue; +} + GfxImageColorMap::~GfxImageColorMap() { delete colorSpace; gfree(lookup); @@ -1886,6 +2245,15 @@ void GfxSubpath::close() { closed = gTrue; } +void GfxSubpath::offset(double dx, double dy) { + int i; + + for (i = 0; i < n; ++i) { + x[i] += dx; + y[i] += dy; + } +} + GfxPath::GfxPath() { justMoved = gFalse; size = 16; @@ -1968,55 +2336,78 @@ void GfxPath::close() { subpaths[n-1]->close(); } +void GfxPath::append(GfxPath *path) { + int i; + + if (n + path->n > size) { + size = n + path->n; + subpaths = (GfxSubpath **) + grealloc(subpaths, size * sizeof(GfxSubpath *)); + } + for (i = 0; i < path->n; ++i) { + subpaths[n++] = path->subpaths[i]->copy(); + } + justMoved = gFalse; +} + +void GfxPath::offset(double dx, double dy) { + int i; + + for (i = 0; i < n; ++i) { + subpaths[i]->offset(dx, dy); + } +} + //------------------------------------------------------------------------ // GfxState //------------------------------------------------------------------------ -GfxState::GfxState(double dpi, PDFRectangle *pageBox, int rotate, - GBool upsideDown) { - double k; +GfxState::GfxState(double hDPI, double vDPI, PDFRectangle *pageBox, + int rotate, GBool upsideDown) { + double kx, ky; px1 = pageBox->x1; py1 = pageBox->y1; px2 = pageBox->x2; py2 = pageBox->y2; - k = dpi / 72.0; + kx = hDPI / 72.0; + ky = vDPI / 72.0; if (rotate == 90) { ctm[0] = 0; - ctm[1] = upsideDown ? k : -k; - ctm[2] = k; + ctm[1] = upsideDown ? ky : -ky; + ctm[2] = kx; ctm[3] = 0; - ctm[4] = -k * py1; - ctm[5] = k * (upsideDown ? -px1 : px2); - pageWidth = k * (py2 - py1); - pageHeight = k * (px2 - px1); + ctm[4] = -kx * py1; + ctm[5] = ky * (upsideDown ? -px1 : px2); + pageWidth = kx * (py2 - py1); + pageHeight = ky * (px2 - px1); } else if (rotate == 180) { - ctm[0] = -k; + ctm[0] = -kx; ctm[1] = 0; ctm[2] = 0; - ctm[3] = upsideDown ? k : -k; - ctm[4] = k * px2; - ctm[5] = k * (upsideDown ? -py1 : py2); - pageWidth = k * (px2 - px1); - pageHeight = k * (py2 - py1); + ctm[3] = upsideDown ? ky : -ky; + ctm[4] = kx * px2; + ctm[5] = ky * (upsideDown ? -py1 : py2); + pageWidth = kx * (px2 - px1); + pageHeight = ky * (py2 - py1); } else if (rotate == 270) { ctm[0] = 0; - ctm[1] = upsideDown ? -k : k; - ctm[2] = -k; + ctm[1] = upsideDown ? -ky : ky; + ctm[2] = -kx; ctm[3] = 0; - ctm[4] = k * py2; - ctm[5] = k * (upsideDown ? px2 : -px1); - pageWidth = k * (py2 - py1); - pageHeight = k * (px2 - px1); + ctm[4] = kx * py2; + ctm[5] = ky * (upsideDown ? px2 : -px1); + pageWidth = kx * (py2 - py1); + pageHeight = ky * (px2 - px1); } else { - ctm[0] = k; + ctm[0] = kx; ctm[1] = 0; ctm[2] = 0; - ctm[3] = upsideDown ? -k : k; - ctm[4] = -k * px1; - ctm[5] = k * (upsideDown ? py2 : -py1); - pageWidth = k * (px2 - px1); - pageHeight = k * (py2 - py1); + ctm[3] = upsideDown ? -ky : ky; + ctm[4] = -kx * px1; + ctm[5] = ky * (upsideDown ? py2 : -py1); + pageWidth = kx * (px2 - px1); + pageHeight = ky * (py2 - py1); } fillColorSpace = new GfxDeviceGrayColorSpace(); @@ -2032,7 +2423,7 @@ GfxState::GfxState(double dpi, PDFRectangle *pageBox, int rotate, lineDash = NULL; lineDashLength = 0; lineDashStart = 0; - flatness = 0; + flatness = 1; lineJoin = 0; lineCap = 0; miterLimit = 10; -- cgit v0.9.1