From f72fd5c03fec8c8d7220c4da964929442962d168 Mon Sep 17 00:00:00 2001 From: kramm Date: Sat, 3 Dec 2005 14:48:56 +0000 Subject: [PATCH] upgraded to xpdf-3.01pl1 --- pdf2swf/xpdf/GfxState.cc | 1485 +++++++++++++++++++++++++++++++++++++----- pdf2swf/xpdf/GlobalParams.cc | 76 +-- pdf2swf/xpdf/GlobalParams.h | 6 +- pdf2swf/xpdf/OutputDev.h | 5 +- pdf2swf/xpdf/Page.cc | 13 - pdf2swf/xpdf/Stream.cc | 2 - pdf2swf/xpdf/config.h | 10 +- pdf2swf/xpdf/gfile.cc | 52 +- pdf2swf/xpdf/gfile.h | 3 - 9 files changed, 1335 insertions(+), 317 deletions(-) diff --git a/pdf2swf/xpdf/GfxState.cc b/pdf2swf/xpdf/GfxState.cc index 33c96cc..051c7b6 100644 --- a/pdf2swf/xpdf/GfxState.cc +++ b/pdf2swf/xpdf/GfxState.cc @@ -14,23 +14,56 @@ #include #include -#include // for memcpy() +#include #include "gmem.h" #include "Error.h" #include "Object.h" #include "Array.h" #include "Page.h" #include "GfxState.h" -#include "cmyk.h" //------------------------------------------------------------------------ +static inline GfxColorComp clip01(GfxColorComp x) { + return (x < 0) ? 0 : (x > gfxColorComp1) ? gfxColorComp1 : x; +} + static inline double clip01(double x) { - return (x < 0) ? 0 : ((x > 1) ? 1 : x); + return (x < 0) ? 0 : (x > 1) ? 1 : x; } //------------------------------------------------------------------------ +static struct { + char *name; + GfxBlendMode mode; +} gfxBlendModeNames[] = { + { "Normal", gfxBlendNormal }, + { "Compatible", gfxBlendNormal }, + { "Multiply", gfxBlendMultiply }, + { "Screen", gfxBlendScreen }, + { "Overlay", gfxBlendOverlay }, + { "Darken", gfxBlendDarken }, + { "Lighten", gfxBlendLighten }, + { "ColorDodge", gfxBlendColorDodge }, + { "ColorBurn", gfxBlendColorBurn }, + { "HardLight", gfxBlendHardLight }, + { "SoftLight", gfxBlendSoftLight }, + { "Difference", gfxBlendDifference }, + { "Exclusion", gfxBlendExclusion }, + { "Hue", gfxBlendHue }, + { "Saturation", gfxBlendSaturation }, + { "Color", gfxBlendColor }, + { "Luminosity", gfxBlendLuminosity } +}; + +#define nGfxBlendModeNames \ + ((int)((sizeof(gfxBlendModeNames) / sizeof(char *)))) + +//------------------------------------------------------------------------ + +// NB: This must match the GfxColorSpaceMode enum defined in +// GfxState.h static char *gfxColorSpaceModeNames[] = { "DeviceGray", "CalGray", @@ -140,7 +173,7 @@ GfxColorSpace *GfxDeviceGrayColorSpace::copy() { return new GfxDeviceGrayColorSpace(); } -void GfxDeviceGrayColorSpace::getGray(GfxColor *color, double *gray) { +void GfxDeviceGrayColorSpace::getGray(GfxColor *color, GfxGray *gray) { *gray = clip01(color->c[0]); } @@ -150,7 +183,7 @@ void GfxDeviceGrayColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { void GfxDeviceGrayColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { cmyk->c = cmyk->m = cmyk->y = 0; - cmyk->k = clip01(1 - color->c[0]); + cmyk->k = clip01(gfxColorComp1 - color->c[0]); } //------------------------------------------------------------------------ @@ -225,7 +258,7 @@ GfxColorSpace *GfxCalGrayColorSpace::parse(Array *arr) { return cs; } -void GfxCalGrayColorSpace::getGray(GfxColor *color, double *gray) { +void GfxCalGrayColorSpace::getGray(GfxColor *color, GfxGray *gray) { *gray = clip01(color->c[0]); } @@ -235,7 +268,7 @@ void GfxCalGrayColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { void GfxCalGrayColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { cmyk->c = cmyk->m = cmyk->y = 0; - cmyk->k = clip01(1 - color->c[0]); + cmyk->k = clip01(gfxColorComp1 - color->c[0]); } //------------------------------------------------------------------------ @@ -252,10 +285,10 @@ GfxColorSpace *GfxDeviceRGBColorSpace::copy() { return new GfxDeviceRGBColorSpace(); } -void GfxDeviceRGBColorSpace::getGray(GfxColor *color, double *gray) { - *gray = clip01(0.299 * color->c[0] + - 0.587 * color->c[1] + - 0.114 * color->c[2]); +void GfxDeviceRGBColorSpace::getGray(GfxColor *color, GfxGray *gray) { + *gray = clip01((GfxColorComp)(0.3 * color->c[0] + + 0.59 * color->c[1] + + 0.11 * color->c[2] + 0.5)); } void GfxDeviceRGBColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { @@ -265,11 +298,11 @@ void GfxDeviceRGBColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { } void GfxDeviceRGBColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { - double c, m, y, k; + GfxColorComp c, m, y, k; - c = clip01(1 - color->c[0]); - m = clip01(1 - color->c[1]); - y = clip01(1 - color->c[2]); + c = clip01(gfxColorComp1 - color->c[0]); + m = clip01(gfxColorComp1 - color->c[1]); + y = clip01(gfxColorComp1 - color->c[2]); k = c; if (m < k) { k = m; @@ -383,10 +416,10 @@ GfxColorSpace *GfxCalRGBColorSpace::parse(Array *arr) { return cs; } -void GfxCalRGBColorSpace::getGray(GfxColor *color, double *gray) { - *gray = clip01(0.299 * color->c[0] + - 0.587 * color->c[1] + - 0.114 * color->c[2]); +void GfxCalRGBColorSpace::getGray(GfxColor *color, GfxGray *gray) { + *gray = clip01((GfxColorComp)(0.299 * color->c[0] + + 0.587 * color->c[1] + + 0.114 * color->c[2] + 0.5)); } void GfxCalRGBColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { @@ -396,11 +429,11 @@ void GfxCalRGBColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { } void GfxCalRGBColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { - double c, m, y, k; + GfxColorComp c, m, y, k; - c = clip01(1 - color->c[0]); - m = clip01(1 - color->c[1]); - y = clip01(1 - color->c[2]); + c = clip01(gfxColorComp1 - color->c[0]); + m = clip01(gfxColorComp1 - color->c[1]); + y = clip01(gfxColorComp1 - color->c[2]); k = c; if (m < k) { k = m; @@ -428,51 +461,73 @@ GfxColorSpace *GfxDeviceCMYKColorSpace::copy() { return new GfxDeviceCMYKColorSpace(); } -void GfxDeviceCMYKColorSpace::getGray(GfxColor *color, double *gray) { - *gray = clip01(1 - color->c[3] - - 0.299 * color->c[0] - - 0.587 * color->c[1] - - 0.114 * color->c[2]); -} - -/*void GfxDeviceCMYKColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { - double c,m,y,k,white; - c = color->c[0]; - m = color->c[1]; - y = color->c[2]; - k = color->c[3]; - white = 1.0 - k; - rgb->r = white - (c*white); - rgb->g = white - (m*white); - rgb->b = white - (y*white); -}*/ -/*void GfxDeviceCMYKColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { - double c, m, y, aw, ac, am, ay, ar, ag, ab; - - c = clip01(color->c[0] + color->c[3]); - m = clip01(color->c[1] + color->c[3]); - y = clip01(color->c[2] + color->c[3]); - aw = (1-c) * (1-m) * (1-y); - ac = c * (1-m) * (1-y); - am = (1-c) * m * (1-y); - ay = (1-c) * (1-m) * y; - ar = (1-c) * m * y; - ag = c * (1-m) * y; - ab = c * m * (1-y); - rgb->r = clip01(aw + 0.9137*am + 0.9961*ay + 0.9882*ar); - rgb->g = clip01(aw + 0.6196*ac + ay + 0.5176*ag); - rgb->b = clip01(aw + 0.7804*ac + 0.5412*am + 0.0667*ar + 0.2118*ag + 0.4863*ab); -}*/ +void GfxDeviceCMYKColorSpace::getGray(GfxColor *color, GfxGray *gray) { + *gray = clip01((GfxColorComp)(gfxColorComp1 - color->c[3] + - 0.3 * color->c[0] + - 0.59 * color->c[1] + - 0.11 * color->c[2] + 0.5)); +} + void GfxDeviceCMYKColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { - unsigned char r,g,b; - float c = color->c[0]; - float m = color->c[1]; - float y = color->c[2]; - float k = color->c[3]; - convert_cmyk2rgb(c,m,y,k, &r,&g,&b); - rgb->r = r/255.0; - rgb->g = g/255.0; - rgb->b = b/255.0; + double c, m, y, k, c1, m1, y1, k1, r, g, b, x; + + c = colToDbl(color->c[0]); + m = colToDbl(color->c[1]); + y = colToDbl(color->c[2]); + k = colToDbl(color->c[3]); + c1 = 1 - c; + m1 = 1 - m; + y1 = 1 - y; + k1 = 1 - k; + // this is a matrix multiplication, unrolled for performance + // C M Y K + x = c1 * m1 * y1 * k1; // 0 0 0 0 + r = g = b = x; + x = c1 * m1 * y1 * k; // 0 0 0 1 + r += 0.1373 * x; + g += 0.1216 * x; + b += 0.1255 * x; + x = c1 * m1 * y * k1; // 0 0 1 0 + r += x; + g += 0.9490 * x; + x = c1 * m1 * y * k; // 0 0 1 1 + r += 0.1098 * x; + g += 0.1020 * x; + x = c1 * m * y1 * k1; // 0 1 0 0 + r += 0.9255 * x; + b += 0.5490 * x; + x = c1 * m * y1 * k; // 0 1 0 1 + r += 0.1412 * x; + x = c1 * m * y * k1; // 0 1 1 0 + r += 0.9294 * x; + g += 0.1098 * x; + b += 0.1412 * x; + x = c1 * m * y * k; // 0 1 1 1 + r += 0.1333 * x; + x = c * m1 * y1 * k1; // 1 0 0 0 + g += 0.6784 * x; + b += 0.9373 * x; + x = c * m1 * y1 * k; // 1 0 0 1 + g += 0.0588 * x; + b += 0.1412 * x; + x = c * m1 * y * k1; // 1 0 1 0 + g += 0.6510 * x; + b += 0.3137 * x; + x = c * m1 * y * k; // 1 0 1 1 + g += 0.0745 * x; + x = c * m * y1 * k1; // 1 1 0 0 + r += 0.1804 * x; + g += 0.1922 * x; + b += 0.5725 * x; + x = c * m * y1 * k; // 1 1 0 1 + b += 0.0078 * x; + x = c * m * y * k1; // 1 1 1 0 + r += 0.2118 * x; + g += 0.2119 * x; + b += 0.2235 * x; + rgb->r = clip01(dblToCol(r)); + rgb->g = clip01(dblToCol(g)); + rgb->b = clip01(dblToCol(b)); } void GfxDeviceCMYKColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { @@ -592,13 +647,13 @@ GfxColorSpace *GfxLabColorSpace::parse(Array *arr) { return cs; } -void GfxLabColorSpace::getGray(GfxColor *color, double *gray) { +void GfxLabColorSpace::getGray(GfxColor *color, GfxGray *gray) { GfxRGB rgb; getRGB(color, &rgb); - *gray = clip01(0.299 * rgb.r + - 0.587 * rgb.g + - 0.114 * rgb.b); + *gray = clip01((GfxColorComp)(0.299 * rgb.r + + 0.587 * rgb.g + + 0.114 * rgb.b + 0.5)); } void GfxLabColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { @@ -607,8 +662,8 @@ void GfxLabColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { double r, g, b; // convert L*a*b* to CIE 1931 XYZ color space - t1 = (color->c[0] + 16) / 116; - t2 = t1 + color->c[1] / 500; + t1 = (colToDbl(color->c[0]) + 16) / 116; + t2 = t1 + colToDbl(color->c[1]) / 500; if (t2 >= (6.0 / 29.0)) { X = t2 * t2 * t2; } else { @@ -621,7 +676,7 @@ void GfxLabColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { Y = (108.0 / 841.0) * (t1 - (4.0 / 29.0)); } Y *= whiteY; - t2 = t1 - color->c[2] / 200; + t2 = t1 - colToDbl(color->c[2]) / 200; if (t2 >= (6.0 / 29.0)) { Z = t2 * t2 * t2; } else { @@ -633,19 +688,19 @@ void GfxLabColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { r = xyzrgb[0][0] * X + xyzrgb[0][1] * Y + xyzrgb[0][2] * Z; g = xyzrgb[1][0] * X + xyzrgb[1][1] * Y + xyzrgb[1][2] * Z; b = xyzrgb[2][0] * X + xyzrgb[2][1] * Y + xyzrgb[2][2] * Z; - rgb->r = pow(clip01(r * kr), 0.5); - rgb->g = pow(clip01(g * kg), 0.5); - rgb->b = pow(clip01(b * kb), 0.5); + rgb->r = dblToCol(pow(clip01(r * kr), 0.5)); + rgb->g = dblToCol(pow(clip01(g * kg), 0.5)); + rgb->b = dblToCol(pow(clip01(b * kb), 0.5)); } void GfxLabColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { GfxRGB rgb; - double c, m, y, k; + GfxColorComp c, m, y, k; getRGB(color, &rgb); - c = clip01(1 - rgb.r); - m = clip01(1 - rgb.g); - y = clip01(1 - rgb.b); + c = clip01(gfxColorComp1 - rgb.r); + m = clip01(gfxColorComp1 - rgb.g); + y = clip01(gfxColorComp1 - rgb.b); k = c; if (m < k) { k = m; @@ -730,6 +785,11 @@ GfxColorSpace *GfxICCBasedColorSpace::parse(Array *arr) { } nCompsA = obj2.getInt(); obj2.free(); + if (nCompsA > gfxColorMaxComps) { + error(-1, "ICCBased color space with too many (%d > %d) components", + nCompsA, gfxColorMaxComps); + nCompsA = gfxColorMaxComps; + } if (dict->lookup("Alternate", &obj2)->isNull() || !(altA = GfxColorSpace::parse(&obj2))) { switch (nCompsA) { @@ -767,7 +827,7 @@ GfxColorSpace *GfxICCBasedColorSpace::parse(Array *arr) { return cs; } -void GfxICCBasedColorSpace::getGray(GfxColor *color, double *gray) { +void GfxICCBasedColorSpace::getGray(GfxColor *color, GfxGray *gray) { alt->getGray(color, gray); } @@ -804,8 +864,8 @@ GfxIndexedColorSpace::GfxIndexedColorSpace(GfxColorSpace *baseA, int indexHighA) { base = baseA; indexHigh = indexHighA; - lookup = (Guchar *)gmalloc((indexHigh + 1) * base->getNComps() * - sizeof(Guchar)); + lookup = (Guchar *)gmallocn((indexHigh + 1) * base->getNComps(), + sizeof(Guchar)); } GfxIndexedColorSpace::~GfxIndexedColorSpace() { @@ -906,14 +966,14 @@ GfxColor *GfxIndexedColorSpace::mapColorToBase(GfxColor *color, n = base->getNComps(); base->getDefaultRanges(low, range, indexHigh); - p = &lookup[(int)(color->c[0] + 0.5) * n]; + p = &lookup[(int)(colToDbl(color->c[0]) + 0.5) * n]; for (i = 0; i < n; ++i) { - baseColor->c[i] = low[i] + (p[i] / 255.0) * range[i]; + baseColor->c[i] = dblToCol(low[i] + (p[i] / 255.0) * range[i]); } return baseColor; } -void GfxIndexedColorSpace::getGray(GfxColor *color, double *gray) { +void GfxIndexedColorSpace::getGray(GfxColor *color, GfxGray *gray) { GfxColor color2; base->getGray(mapColorToBase(color, &color2), gray); @@ -1002,24 +1062,45 @@ GfxColorSpace *GfxSeparationColorSpace::parse(Array *arr) { return NULL; } -void GfxSeparationColorSpace::getGray(GfxColor *color, double *gray) { +void GfxSeparationColorSpace::getGray(GfxColor *color, GfxGray *gray) { + double x; + double c[gfxColorMaxComps]; GfxColor color2; + int i; - func->transform(color->c, color2.c); + x = colToDbl(color->c[0]); + func->transform(&x, c); + for (i = 0; i < alt->getNComps(); ++i) { + color2.c[i] = dblToCol(c[i]); + } alt->getGray(&color2, gray); } void GfxSeparationColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { + double x; + double c[gfxColorMaxComps]; GfxColor color2; + int i; - func->transform(color->c, color2.c); + x = colToDbl(color->c[0]); + func->transform(&x, c); + for (i = 0; i < alt->getNComps(); ++i) { + color2.c[i] = dblToCol(c[i]); + } alt->getRGB(&color2, rgb); } void GfxSeparationColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { + double x; + double c[gfxColorMaxComps]; GfxColor color2; + int i; - func->transform(color->c, color2.c); + x = colToDbl(color->c[0]); + func->transform(&x, c); + for (i = 0; i < alt->getNComps(); ++i) { + color2.c[i] = dblToCol(c[i]); + } alt->getCMYK(&color2, cmyk); } @@ -1076,7 +1157,7 @@ GfxColorSpace *GfxDeviceNColorSpace::parse(Array *arr) { } nCompsA = obj1.arrayGetLength(); if (nCompsA > gfxColorMaxComps) { - error(-1, "DeviceN color space with more than %d > %d components", + error(-1, "DeviceN color space with too many (%d > %d) components", nCompsA, gfxColorMaxComps); nCompsA = gfxColorMaxComps; } @@ -1119,24 +1200,48 @@ GfxColorSpace *GfxDeviceNColorSpace::parse(Array *arr) { return NULL; } -void GfxDeviceNColorSpace::getGray(GfxColor *color, double *gray) { +void GfxDeviceNColorSpace::getGray(GfxColor *color, GfxGray *gray) { + double x[gfxColorMaxComps], c[gfxColorMaxComps]; GfxColor color2; + int i; - func->transform(color->c, color2.c); + for (i = 0; i < nComps; ++i) { + x[i] = colToDbl(color->c[i]); + } + func->transform(x, c); + for (i = 0; i < alt->getNComps(); ++i) { + color2.c[i] = dblToCol(c[i]); + } alt->getGray(&color2, gray); } void GfxDeviceNColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { + double x[gfxColorMaxComps], c[gfxColorMaxComps]; GfxColor color2; + int i; - func->transform(color->c, color2.c); + for (i = 0; i < nComps; ++i) { + x[i] = colToDbl(color->c[i]); + } + func->transform(x, c); + for (i = 0; i < alt->getNComps(); ++i) { + color2.c[i] = dblToCol(c[i]); + } alt->getRGB(&color2, rgb); } void GfxDeviceNColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { + double x[gfxColorMaxComps], c[gfxColorMaxComps]; GfxColor color2; + int i; - func->transform(color->c, color2.c); + for (i = 0; i < nComps; ++i) { + x[i] = colToDbl(color->c[i]); + } + func->transform(x, c); + for (i = 0; i < alt->getNComps(); ++i) { + color2.c[i] = dblToCol(c[i]); + } alt->getCMYK(&color2, cmyk); } @@ -1182,7 +1287,7 @@ GfxColorSpace *GfxPatternColorSpace::parse(Array *arr) { return cs; } -void GfxPatternColorSpace::getGray(GfxColor *color, double *gray) { +void GfxPatternColorSpace::getGray(GfxColor *color, GfxGray *gray) { *gray = 0; } @@ -1467,6 +1572,38 @@ GfxShading *GfxShading::parse(Object *obj) { case 3: shading = GfxRadialShading::parse(dict); break; + case 4: + if (obj->isStream()) { + shading = GfxGouraudTriangleShading::parse(4, dict, obj->getStream()); + } else { + error(-1, "Invalid Type 4 shading object"); + goto err1; + } + break; + case 5: + if (obj->isStream()) { + shading = GfxGouraudTriangleShading::parse(5, dict, obj->getStream()); + } else { + error(-1, "Invalid Type 5 shading object"); + goto err1; + } + break; + case 6: + if (obj->isStream()) { + shading = GfxPatchMeshShading::parse(6, dict, obj->getStream()); + } else { + error(-1, "Invalid Type 6 shading object"); + goto err1; + } + break; + case 7: + if (obj->isStream()) { + shading = GfxPatchMeshShading::parse(7, dict, obj->getStream()); + } else { + error(-1, "Invalid Type 7 shading object"); + goto err1; + } + break; default: error(-1, "Unimplemented shading type %d", typeA); goto err1; @@ -1498,7 +1635,7 @@ GBool GfxShading::init(Dict *dict) { if (obj1.arrayGetLength() == colorSpace->getNComps()) { hasBackground = gTrue; for (i = 0; i < colorSpace->getNComps(); ++i) { - background.c[i] = obj1.arrayGet(i, &obj2)->getNum(); + background.c[i] = dblToCol(obj1.arrayGet(i, &obj2)->getNum()); obj2.free(); } } else { @@ -1666,13 +1803,21 @@ GfxShading *GfxFunctionShading::copy() { } void GfxFunctionShading::getColor(double x, double y, GfxColor *color) { - double in[2]; + double in[2], 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; + } in[0] = x; in[1] = y; for (i = 0; i < nFuncs; ++i) { - funcs[i]->transform(in, &color->c[i]); + funcs[i]->transform(in, &out[i]); + } + for (i = 0; i < gfxColorMaxComps; ++i) { + color->c[i] = dblToCol(out[i]); } } @@ -1820,12 +1965,19 @@ GfxShading *GfxAxialShading::copy() { } void GfxAxialShading::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, &color->c[i]); + funcs[i]->transform(&t, &out[i]); + } + for (i = 0; i < gfxColorMaxComps; ++i) { + color->c[i] = dblToCol(out[i]); } } @@ -1981,16 +2133,964 @@ GfxShading *GfxRadialShading::copy() { } 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, &color->c[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, sizeof(GfxPatch)); + memcpy(patches, shading->patches, nPatches * sizeof(GfxPatch)); + nFuncs = shading->nFuncs; + for (i = 0; i < nFuncs; ++i) { + funcs[i] = shading->funcs[i]->copy(); + } +} + +GfxPatchMeshShading::~GfxPatchMeshShading() { + int i; + + gfree(patches); + for (i = 0; i < nFuncs; ++i) { + delete funcs[i]; + } +} + +GfxPatchMeshShading *GfxPatchMeshShading::parse(int typeA, Dict *dict, + Stream *str) { + GfxPatchMeshShading *shading; + Function *funcsA[gfxColorMaxComps]; + int nFuncsA; + int coordBits, compBits, flagBits; + double xMin, xMax, yMin, yMax; + double cMin[gfxColorMaxComps], cMax[gfxColorMaxComps]; + double xMul, yMul; + double cMul[gfxColorMaxComps]; + GfxPatch *patchesA, *p; + int nComps, nPatchesA, patchesSize, nPts, nColors; + Guint flag; + double x[16], y[16]; + Guint xi, yi; + GfxColorComp c[4][gfxColorMaxComps]; + Guint ci[4]; + GfxShadingBitBuf *bitBuf; + Object obj1, obj2; + int i, j; + + 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(); + if (dict->lookup("BitsPerFlag", &obj1)->isInt()) { + flagBits = obj1.getInt(); + } else { + error(-1, "Missing or invalid BitsPerFlag 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(); + + nPatchesA = 0; + patchesA = NULL; + patchesSize = 0; + bitBuf = new GfxShadingBitBuf(str); + while (1) { + if (!bitBuf->getBits(flagBits, &flag)) { + break; + } + if (typeA == 6) { + switch (flag) { + case 0: nPts = 12; nColors = 4; break; + case 1: + case 2: + case 3: + default: nPts = 8; nColors = 2; break; + } + } else { + switch (flag) { + case 0: nPts = 16; nColors = 4; break; + case 1: + case 2: + case 3: + default: nPts = 12; nColors = 2; break; + } + } + for (i = 0; i < nPts; ++i) { + if (!bitBuf->getBits(coordBits, &xi) || + !bitBuf->getBits(coordBits, &yi)) { + break; + } + x[i] = xMin + xMul * (double)xi; + y[i] = yMin + yMul * (double)yi; + } + if (i < nPts) { + break; + } + for (i = 0; i < nColors; ++i) { + for (j = 0; j < nComps; ++j) { + if (!bitBuf->getBits(compBits, &ci[j])) { + break; + } + c[i][j] = dblToCol(cMin[j] + cMul[j] * (double)ci[j]); + } + if (j < nComps) { + break; + } + } + if (i < nColors) { + break; + } + if (nPatchesA == patchesSize) { + patchesSize = (patchesSize == 0) ? 16 : 2 * patchesSize; + patchesA = (GfxPatch *)greallocn(patchesA, + patchesSize, sizeof(GfxPatch)); + } + p = &patchesA[nPatchesA]; + if (typeA == 6) { + switch (flag) { + case 0: + p->x[0][0] = x[0]; + p->y[0][0] = y[0]; + p->x[0][1] = x[1]; + p->y[0][1] = y[1]; + p->x[0][2] = x[2]; + p->y[0][2] = y[2]; + p->x[0][3] = x[3]; + p->y[0][3] = y[3]; + p->x[1][3] = x[4]; + p->y[1][3] = y[4]; + p->x[2][3] = x[5]; + p->y[2][3] = y[5]; + p->x[3][3] = x[6]; + p->y[3][3] = y[6]; + p->x[3][2] = x[7]; + p->y[3][2] = y[7]; + p->x[3][1] = x[8]; + p->y[3][1] = y[8]; + p->x[3][0] = x[9]; + p->y[3][0] = y[9]; + p->x[2][0] = x[10]; + p->y[2][0] = y[10]; + p->x[1][0] = x[11]; + p->y[1][0] = y[11]; + for (j = 0; j < nComps; ++j) { + p->color[0][0].c[j] = c[0][j]; + p->color[0][1].c[j] = c[1][j]; + p->color[1][1].c[j] = c[2][j]; + p->color[1][0].c[j] = c[3][j]; + } + break; + case 1: + p->x[0][0] = patchesA[nPatchesA-1].x[0][3]; + p->y[0][0] = patchesA[nPatchesA-1].y[0][3]; + p->x[0][1] = patchesA[nPatchesA-1].x[1][3]; + p->y[0][1] = patchesA[nPatchesA-1].y[1][3]; + p->x[0][2] = patchesA[nPatchesA-1].x[2][3]; + p->y[0][2] = patchesA[nPatchesA-1].y[2][3]; + p->x[0][3] = patchesA[nPatchesA-1].x[3][3]; + p->y[0][3] = patchesA[nPatchesA-1].y[3][3]; + p->x[1][3] = x[0]; + p->y[1][3] = y[0]; + p->x[2][3] = x[1]; + p->y[2][3] = y[1]; + p->x[3][3] = x[2]; + p->y[3][3] = y[2]; + p->x[3][2] = x[3]; + p->y[3][2] = y[3]; + p->x[3][1] = x[4]; + p->y[3][1] = y[4]; + p->x[3][0] = x[5]; + p->y[3][0] = y[5]; + p->x[2][0] = x[6]; + p->y[2][0] = y[6]; + p->x[1][0] = x[7]; + p->y[1][0] = y[7]; + for (j = 0; j < nComps; ++j) { + p->color[0][0].c[j] = patchesA[nPatchesA-1].color[0][1].c[j]; + p->color[0][1].c[j] = patchesA[nPatchesA-1].color[1][1].c[j]; + p->color[1][1].c[j] = c[0][j]; + p->color[1][0].c[j] = c[1][j]; + } + break; + case 2: + p->x[0][0] = patchesA[nPatchesA-1].x[3][3]; + p->y[0][0] = patchesA[nPatchesA-1].y[3][3]; + p->x[0][1] = patchesA[nPatchesA-1].x[3][2]; + p->y[0][1] = patchesA[nPatchesA-1].y[3][2]; + p->x[0][2] = patchesA[nPatchesA-1].x[3][1]; + p->y[0][2] = patchesA[nPatchesA-1].y[3][1]; + p->x[0][3] = patchesA[nPatchesA-1].x[3][0]; + p->y[0][3] = patchesA[nPatchesA-1].y[3][0]; + p->x[1][3] = x[0]; + p->y[1][3] = y[0]; + p->x[2][3] = x[1]; + p->y[2][3] = y[1]; + p->x[3][3] = x[2]; + p->y[3][3] = y[2]; + p->x[3][2] = x[3]; + p->y[3][2] = y[3]; + p->x[3][1] = x[4]; + p->y[3][1] = y[4]; + p->x[3][0] = x[5]; + p->y[3][0] = y[5]; + p->x[2][0] = x[6]; + p->y[2][0] = y[6]; + p->x[1][0] = x[7]; + p->y[1][0] = y[7]; + for (j = 0; j < nComps; ++j) { + p->color[0][0].c[j] = patchesA[nPatchesA-1].color[1][1].c[j]; + p->color[0][1].c[j] = patchesA[nPatchesA-1].color[1][0].c[j]; + p->color[1][1].c[j] = c[0][j]; + p->color[1][0].c[j] = c[1][j]; + } + break; + case 3: + p->x[0][0] = patchesA[nPatchesA-1].x[3][0]; + p->y[0][0] = patchesA[nPatchesA-1].y[3][0]; + p->x[0][1] = patchesA[nPatchesA-1].x[2][0]; + p->y[0][1] = patchesA[nPatchesA-1].y[2][0]; + p->x[0][2] = patchesA[nPatchesA-1].x[1][0]; + p->y[0][2] = patchesA[nPatchesA-1].y[1][0]; + p->x[0][3] = patchesA[nPatchesA-1].x[0][0]; + p->y[0][3] = patchesA[nPatchesA-1].y[0][0]; + p->x[1][3] = x[0]; + p->y[1][3] = y[0]; + p->x[2][3] = x[1]; + p->y[2][3] = y[1]; + p->x[3][3] = x[2]; + p->y[3][3] = y[2]; + p->x[3][2] = x[3]; + p->y[3][2] = y[3]; + p->x[3][1] = x[4]; + p->y[3][1] = y[4]; + p->x[3][0] = x[5]; + p->y[3][0] = y[5]; + p->x[2][0] = x[6]; + p->y[2][0] = y[6]; + p->x[1][0] = x[7]; + p->y[1][0] = y[7]; + for (j = 0; j < nComps; ++j) { + p->color[0][1].c[j] = patchesA[nPatchesA-1].color[1][0].c[j]; + p->color[0][1].c[j] = patchesA[nPatchesA-1].color[0][0].c[j]; + p->color[1][1].c[j] = c[0][j]; + p->color[1][0].c[j] = c[1][j]; + } + break; + } + } else { + switch (flag) { + case 0: + p->x[0][0] = x[0]; + p->y[0][0] = y[0]; + p->x[0][1] = x[1]; + p->y[0][1] = y[1]; + p->x[0][2] = x[2]; + p->y[0][2] = y[2]; + p->x[0][3] = x[3]; + p->y[0][3] = y[3]; + p->x[1][3] = x[4]; + p->y[1][3] = y[4]; + p->x[2][3] = x[5]; + p->y[2][3] = y[5]; + p->x[3][3] = x[6]; + p->y[3][3] = y[6]; + p->x[3][2] = x[7]; + p->y[3][2] = y[7]; + p->x[3][1] = x[8]; + p->y[3][1] = y[8]; + p->x[3][0] = x[9]; + p->y[3][0] = y[9]; + p->x[2][0] = x[10]; + p->y[2][0] = y[10]; + p->x[1][0] = x[11]; + p->y[1][0] = y[11]; + p->x[1][1] = x[12]; + p->y[1][1] = y[12]; + p->x[1][2] = x[13]; + p->y[1][2] = y[13]; + p->x[2][2] = x[14]; + p->y[2][2] = y[14]; + p->x[2][1] = x[15]; + p->y[2][1] = y[15]; + for (j = 0; j < nComps; ++j) { + p->color[0][0].c[j] = c[0][j]; + p->color[0][1].c[j] = c[1][j]; + p->color[1][1].c[j] = c[2][j]; + p->color[1][0].c[j] = c[3][j]; + } + break; + case 1: + p->x[0][0] = patchesA[nPatchesA-1].x[0][3]; + p->y[0][0] = patchesA[nPatchesA-1].y[0][3]; + p->x[0][1] = patchesA[nPatchesA-1].x[1][3]; + p->y[0][1] = patchesA[nPatchesA-1].y[1][3]; + p->x[0][2] = patchesA[nPatchesA-1].x[2][3]; + p->y[0][2] = patchesA[nPatchesA-1].y[2][3]; + p->x[0][3] = patchesA[nPatchesA-1].x[3][3]; + p->y[0][3] = patchesA[nPatchesA-1].y[3][3]; + p->x[1][3] = x[0]; + p->y[1][3] = y[0]; + p->x[2][3] = x[1]; + p->y[2][3] = y[1]; + p->x[3][3] = x[2]; + p->y[3][3] = y[2]; + p->x[3][2] = x[3]; + p->y[3][2] = y[3]; + p->x[3][1] = x[4]; + p->y[3][1] = y[4]; + p->x[3][0] = x[5]; + p->y[3][0] = y[5]; + p->x[2][0] = x[6]; + p->y[2][0] = y[6]; + p->x[1][0] = x[7]; + p->y[1][0] = y[7]; + p->x[1][1] = x[8]; + p->y[1][1] = y[8]; + p->x[1][2] = x[9]; + p->y[1][2] = y[9]; + p->x[2][2] = x[10]; + p->y[2][2] = y[10]; + p->x[2][1] = x[11]; + p->y[2][1] = y[11]; + for (j = 0; j < nComps; ++j) { + p->color[0][0].c[j] = patchesA[nPatchesA-1].color[0][1].c[j]; + p->color[0][1].c[j] = patchesA[nPatchesA-1].color[1][1].c[j]; + p->color[1][1].c[j] = c[0][j]; + p->color[1][0].c[j] = c[1][j]; + } + break; + case 2: + p->x[0][0] = patchesA[nPatchesA-1].x[3][3]; + p->y[0][0] = patchesA[nPatchesA-1].y[3][3]; + p->x[0][1] = patchesA[nPatchesA-1].x[3][2]; + p->y[0][1] = patchesA[nPatchesA-1].y[3][2]; + p->x[0][2] = patchesA[nPatchesA-1].x[3][1]; + p->y[0][2] = patchesA[nPatchesA-1].y[3][1]; + p->x[0][3] = patchesA[nPatchesA-1].x[3][0]; + p->y[0][3] = patchesA[nPatchesA-1].y[3][0]; + p->x[1][3] = x[0]; + p->y[1][3] = y[0]; + p->x[2][3] = x[1]; + p->y[2][3] = y[1]; + p->x[3][3] = x[2]; + p->y[3][3] = y[2]; + p->x[3][2] = x[3]; + p->y[3][2] = y[3]; + p->x[3][1] = x[4]; + p->y[3][1] = y[4]; + p->x[3][0] = x[5]; + p->y[3][0] = y[5]; + p->x[2][0] = x[6]; + p->y[2][0] = y[6]; + p->x[1][0] = x[7]; + p->y[1][0] = y[7]; + p->x[1][1] = x[8]; + p->y[1][1] = y[8]; + p->x[1][2] = x[9]; + p->y[1][2] = y[9]; + p->x[2][2] = x[10]; + p->y[2][2] = y[10]; + p->x[2][1] = x[11]; + p->y[2][1] = y[11]; + for (j = 0; j < nComps; ++j) { + p->color[0][0].c[j] = patchesA[nPatchesA-1].color[1][1].c[j]; + p->color[0][1].c[j] = patchesA[nPatchesA-1].color[1][0].c[j]; + p->color[1][1].c[j] = c[0][j]; + p->color[1][0].c[j] = c[1][j]; + } + break; + case 3: + p->x[0][0] = patchesA[nPatchesA-1].x[3][0]; + p->y[0][0] = patchesA[nPatchesA-1].y[3][0]; + p->x[0][1] = patchesA[nPatchesA-1].x[2][0]; + p->y[0][1] = patchesA[nPatchesA-1].y[2][0]; + p->x[0][2] = patchesA[nPatchesA-1].x[1][0]; + p->y[0][2] = patchesA[nPatchesA-1].y[1][0]; + p->x[0][3] = patchesA[nPatchesA-1].x[0][0]; + p->y[0][3] = patchesA[nPatchesA-1].y[0][0]; + p->x[1][3] = x[0]; + p->y[1][3] = y[0]; + p->x[2][3] = x[1]; + p->y[2][3] = y[1]; + p->x[3][3] = x[2]; + p->y[3][3] = y[2]; + p->x[3][2] = x[3]; + p->y[3][2] = y[3]; + p->x[3][1] = x[4]; + p->y[3][1] = y[4]; + p->x[3][0] = x[5]; + p->y[3][0] = y[5]; + p->x[2][0] = x[6]; + p->y[2][0] = y[6]; + p->x[1][0] = x[7]; + p->y[1][0] = y[7]; + p->x[1][1] = x[8]; + p->y[1][1] = y[8]; + p->x[1][2] = x[9]; + p->y[1][2] = y[9]; + p->x[2][2] = x[10]; + p->y[2][2] = y[10]; + p->x[2][1] = x[11]; + p->y[2][1] = y[11]; + for (j = 0; j < nComps; ++j) { + p->color[0][0].c[j] = patchesA[nPatchesA-1].color[1][0].c[j]; + p->color[0][1].c[j] = patchesA[nPatchesA-1].color[0][0].c[j]; + p->color[1][1].c[j] = c[0][j]; + p->color[1][0].c[j] = c[1][j]; + } + break; + } + } + ++nPatchesA; + bitBuf->flushBits(); + } + delete bitBuf; + + if (typeA == 6) { + for (i = 0; i < nPatchesA; ++i) { + p = &patchesA[i]; + p->x[1][1] = (-4 * p->x[0][0] + +6 * (p->x[0][1] + p->x[1][0]) + -2 * (p->x[0][3] + p->x[3][0]) + +3 * (p->x[3][1] + p->x[1][3]) + - p->x[3][3]) / 9; + p->y[1][1] = (-4 * p->y[0][0] + +6 * (p->y[0][1] + p->y[1][0]) + -2 * (p->y[0][3] + p->y[3][0]) + +3 * (p->y[3][1] + p->y[1][3]) + - p->y[3][3]) / 9; + p->x[1][2] = (-4 * p->x[0][3] + +6 * (p->x[0][2] + p->x[1][3]) + -2 * (p->x[0][0] + p->x[3][3]) + +3 * (p->x[3][2] + p->x[1][0]) + - p->x[3][0]) / 9; + p->y[1][2] = (-4 * p->y[0][3] + +6 * (p->y[0][2] + p->y[1][3]) + -2 * (p->y[0][0] + p->y[3][3]) + +3 * (p->y[3][2] + p->y[1][0]) + - p->y[3][0]) / 9; + p->x[2][1] = (-4 * p->x[3][0] + +6 * (p->x[3][1] + p->x[2][0]) + -2 * (p->x[3][3] + p->x[0][0]) + +3 * (p->x[0][1] + p->x[2][3]) + - p->x[0][3]) / 9; + p->y[2][1] = (-4 * p->y[3][0] + +6 * (p->y[3][1] + p->y[2][0]) + -2 * (p->y[3][3] + p->y[0][0]) + +3 * (p->y[0][1] + p->y[2][3]) + - p->y[0][3]) / 9; + p->x[2][2] = (-4 * p->x[3][3] + +6 * (p->x[3][2] + p->x[2][3]) + -2 * (p->x[3][0] + p->x[0][3]) + +3 * (p->x[0][2] + p->x[2][0]) + - p->x[0][0]) / 9; + p->y[2][2] = (-4 * p->y[3][3] + +6 * (p->y[3][2] + p->y[2][3]) + -2 * (p->y[3][0] + p->y[0][3]) + +3 * (p->y[0][2] + p->y[2][0]) + - p->y[0][0]) / 9; + } + } + + shading = new GfxPatchMeshShading(typeA, patchesA, nPatchesA, + funcsA, nFuncsA); + if (!shading->init(dict)) { + delete shading; + return NULL; + } + return shading; + + err2: + obj1.free(); + err1: + return NULL; +} + +GfxShading *GfxPatchMeshShading::copy() { + return new GfxPatchMeshShading(this); +} + +//------------------------------------------------------------------------ // GfxImageColorMap //------------------------------------------------------------------------ @@ -2005,14 +3105,12 @@ GfxImageColorMap::GfxImageColorMap(int bitsA, Object *decode, double x[gfxColorMaxComps]; double y[gfxColorMaxComps]; int i, j, k; - int maxPixelForAlloc; ok = gTrue; // bits per component and color space bits = bitsA; maxPixel = (1 << bits) - 1; - maxPixelForAlloc = (1 << (bits>8?bits:8)); colorSpace = colorSpaceA; // get decode map @@ -2049,6 +3147,9 @@ GfxImageColorMap::GfxImageColorMap(int bitsA, Object *decode, // Optimization: for Indexed and Separation color spaces (which have // only one component), we store color values in the lookup table // rather than component values. + for (k = 0; k < gfxColorMaxComps; ++k) { + lookup[k] = NULL; + } colorSpace2 = NULL; nComps2 = 0; if (colorSpace->getMode() == csIndexed) { @@ -2059,39 +3160,43 @@ GfxImageColorMap::GfxImageColorMap(int bitsA, Object *decode, colorSpace2 = indexedCS->getBase(); indexHigh = indexedCS->getIndexHigh(); nComps2 = colorSpace2->getNComps(); - lookup = (double *)gmalloc((maxPixelForAlloc + 1) * nComps2 * sizeof(double)); lookup2 = indexedCS->getLookup(); colorSpace2->getDefaultRanges(x, y, indexHigh); - for (i = 0; i <= maxPixel; ++i) { - j = (int)(decodeLow[0] + (i * decodeRange[0]) / maxPixel + 0.5); - if (j < 0) { - j = 0; - } else if (j > indexHigh) { - j = indexHigh; - } - for (k = 0; k < nComps2; ++k) { - lookup[i*nComps2 + k] = x[k] + (lookup2[j*nComps2 + k] / 255.0) * y[k]; + for (k = 0; k < nComps2; ++k) { + lookup[k] = (GfxColorComp *)gmallocn(maxPixel + 1, + sizeof(GfxColorComp)); + for (i = 0; i <= maxPixel; ++i) { + j = (int)(decodeLow[0] + (i * decodeRange[0]) / maxPixel + 0.5); + if (j < 0) { + j = 0; + } else if (j > indexHigh) { + j = indexHigh; + } + lookup[k][i] = + dblToCol(x[k] + (lookup2[j*nComps2 + k] / 255.0) * y[k]); } } } else if (colorSpace->getMode() == csSeparation) { sepCS = (GfxSeparationColorSpace *)colorSpace; colorSpace2 = sepCS->getAlt(); nComps2 = colorSpace2->getNComps(); - lookup = (double *)gmalloc((maxPixelForAlloc + 1) * nComps2 * sizeof(double)); sepFunc = sepCS->getFunc(); - for (i = 0; i <= maxPixel; ++i) { - x[0] = decodeLow[0] + (i * decodeRange[0]) / maxPixel; - sepFunc->transform(x, y); - for (k = 0; k < nComps2; ++k) { - lookup[i*nComps2 + k] = y[k]; + for (k = 0; k < nComps2; ++k) { + lookup[k] = (GfxColorComp *)gmallocn(maxPixel + 1, + sizeof(GfxColorComp)); + for (i = 0; i <= maxPixel; ++i) { + x[0] = decodeLow[0] + (i * decodeRange[0]) / maxPixel; + sepFunc->transform(x, y); + lookup[k][i] = dblToCol(y[k]); } } } else { - lookup = (double *)gmalloc((maxPixelForAlloc + 1) * nComps * sizeof(double)); - for (i = 0; i <= maxPixel; ++i) { - for (k = 0; k < nComps; ++k) { - lookup[i*nComps + k] = decodeLow[k] + - (i * decodeRange[k]) / maxPixel; + for (k = 0; k < nComps; ++k) { + lookup[k] = (GfxColorComp *)gmallocn(maxPixel + 1, + sizeof(GfxColorComp)); + for (i = 0; i <= maxPixel; ++i) { + lookup[k][i] = dblToCol(decodeLow[k] + + (i * decodeRange[k]) / maxPixel); } } } @@ -2105,26 +3210,35 @@ GfxImageColorMap::GfxImageColorMap(int bitsA, Object *decode, } GfxImageColorMap::GfxImageColorMap(GfxImageColorMap *colorMap) { - int n, i; + int n, i, k; colorSpace = colorMap->colorSpace->copy(); bits = colorMap->bits; nComps = colorMap->nComps; nComps2 = colorMap->nComps2; colorSpace2 = NULL; - lookup = NULL; + for (k = 0; k < gfxColorMaxComps; ++k) { + lookup[k] = NULL; + } n = 1 << bits; if (colorSpace->getMode() == csIndexed) { colorSpace2 = ((GfxIndexedColorSpace *)colorSpace)->getBase(); - n = n * nComps2 * sizeof(double); + for (k = 0; k < nComps2; ++k) { + lookup[k] = (GfxColorComp *)gmallocn(n, sizeof(GfxColorComp)); + memcpy(lookup[k], colorMap->lookup[k], n * sizeof(GfxColorComp)); + } } else if (colorSpace->getMode() == csSeparation) { colorSpace2 = ((GfxSeparationColorSpace *)colorSpace)->getAlt(); - n = n * nComps2 * sizeof(double); + for (k = 0; k < nComps2; ++k) { + lookup[k] = (GfxColorComp *)gmallocn(n, sizeof(GfxColorComp)); + memcpy(lookup[k], colorMap->lookup[k], n * sizeof(GfxColorComp)); + } } else { - n = n * nComps * sizeof(double); + for (k = 0; k < nComps; ++k) { + lookup[k] = (GfxColorComp *)gmallocn(n, sizeof(GfxColorComp)); + memcpy(lookup[k], colorMap->lookup[k], n * sizeof(GfxColorComp)); + } } - 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]; @@ -2133,24 +3247,26 @@ GfxImageColorMap::GfxImageColorMap(GfxImageColorMap *colorMap) { } GfxImageColorMap::~GfxImageColorMap() { + int i; + delete colorSpace; - gfree(lookup); + for (i = 0; i < gfxColorMaxComps; ++i) { + gfree(lookup[i]); + } } -void GfxImageColorMap::getGray(Guchar *x, double *gray) { +void GfxImageColorMap::getGray(Guchar *x, GfxGray *gray) { GfxColor color; - double *p; int i; if (colorSpace2) { - p = &lookup[x[0] * nComps2]; for (i = 0; i < nComps2; ++i) { - color.c[i] = *p++; + color.c[i] = lookup[i][x[0]]; } colorSpace2->getGray(&color, gray); } else { for (i = 0; i < nComps; ++i) { - color.c[i] = lookup[x[i] * nComps + i]; + color.c[i] = lookup[i][x[i]]; } colorSpace->getGray(&color, gray); } @@ -2158,18 +3274,16 @@ void GfxImageColorMap::getGray(Guchar *x, double *gray) { void GfxImageColorMap::getRGB(Guchar *x, GfxRGB *rgb) { GfxColor color; - double *p; int i; if (colorSpace2) { - p = &lookup[x[0] * nComps2]; for (i = 0; i < nComps2; ++i) { - color.c[i] = *p++; + color.c[i] = lookup[i][x[0]]; } colorSpace2->getRGB(&color, rgb); } else { for (i = 0; i < nComps; ++i) { - color.c[i] = lookup[x[i] * nComps + i]; + color.c[i] = lookup[i][x[i]]; } colorSpace->getRGB(&color, rgb); } @@ -2177,18 +3291,16 @@ void GfxImageColorMap::getRGB(Guchar *x, GfxRGB *rgb) { void GfxImageColorMap::getCMYK(Guchar *x, GfxCMYK *cmyk) { GfxColor color; - double *p; int i; if (colorSpace2) { - p = &lookup[x[0] * nComps2]; for (i = 0; i < nComps2; ++i) { - color.c[i] = *p++; + color.c[i] = lookup[i][x[0]]; } colorSpace2->getCMYK(&color, cmyk); } else { for (i = 0; i < nComps; ++i) { - color.c[i] = lookup[x[i] * nComps + i]; + color.c[i] = lookup[i][x[i]]; } colorSpace->getCMYK(&color, cmyk); } @@ -2199,7 +3311,7 @@ void GfxImageColorMap::getColor(Guchar *x, GfxColor *color) { maxPixel = (1 << bits) - 1; for (i = 0; i < nComps; ++i) { - color->c[i] = decodeLow[i] + (x[i] * decodeRange[i]) / maxPixel; + color->c[i] = dblToCol(decodeLow[i] + (x[i] * decodeRange[i]) / maxPixel); } } @@ -2209,9 +3321,9 @@ void GfxImageColorMap::getColor(Guchar *x, GfxColor *color) { 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)); + x = (double *)gmallocn(size, sizeof(double)); + y = (double *)gmallocn(size, sizeof(double)); + curve = (GBool *)gmallocn(size, sizeof(GBool)); n = 1; x[0] = x1; y[0] = y1; @@ -2229,9 +3341,9 @@ GfxSubpath::~GfxSubpath() { 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)); + x = (double *)gmallocn(size, sizeof(double)); + y = (double *)gmallocn(size, sizeof(double)); + curve = (GBool *)gmallocn(size, sizeof(GBool)); memcpy(x, subpath->x, n * sizeof(double)); memcpy(y, subpath->y, n * sizeof(double)); memcpy(curve, subpath->curve, n * sizeof(GBool)); @@ -2241,9 +3353,9 @@ GfxSubpath::GfxSubpath(GfxSubpath *subpath) { 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 = (double *)greallocn(x, size, sizeof(double)); + y = (double *)greallocn(y, size, sizeof(double)); + curve = (GBool *)greallocn(curve, size, sizeof(GBool)); } x[n] = x1; y[n] = y1; @@ -2255,9 +3367,9 @@ 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 = (double *)greallocn(x, size, sizeof(double)); + y = (double *)greallocn(y, size, sizeof(double)); + curve = (GBool *)greallocn(curve, size, sizeof(GBool)); } x[n] = x1; y[n] = y1; @@ -2291,7 +3403,7 @@ GfxPath::GfxPath() { size = 16; n = 0; firstX = firstY = 0; - subpaths = (GfxSubpath **)gmalloc(size * sizeof(GfxSubpath *)); + subpaths = (GfxSubpath **)gmallocn(size, sizeof(GfxSubpath *)); } GfxPath::~GfxPath() { @@ -2312,7 +3424,7 @@ GfxPath::GfxPath(GBool justMoved1, double firstX1, double firstY1, firstY = firstY1; size = size1; n = n1; - subpaths = (GfxSubpath **)gmalloc(size * sizeof(GfxSubpath *)); + subpaths = (GfxSubpath **)gmallocn(size, sizeof(GfxSubpath *)); for (i = 0; i < n; ++i) subpaths[i] = subpaths1[i]->copy(); } @@ -2328,7 +3440,7 @@ void GfxPath::lineTo(double x, double y) { if (n >= size) { size += 16; subpaths = (GfxSubpath **) - grealloc(subpaths, size * sizeof(GfxSubpath *)); + greallocn(subpaths, size, sizeof(GfxSubpath *)); } subpaths[n] = new GfxSubpath(firstX, firstY); ++n; @@ -2343,7 +3455,7 @@ void GfxPath::curveTo(double x1, double y1, double x2, double y2, if (n >= size) { size += 16; subpaths = (GfxSubpath **) - grealloc(subpaths, size * sizeof(GfxSubpath *)); + greallocn(subpaths, size, sizeof(GfxSubpath *)); } subpaths[n] = new GfxSubpath(firstX, firstY); ++n; @@ -2359,7 +3471,7 @@ void GfxPath::close() { if (n >= size) { size += 16; subpaths = (GfxSubpath **) - grealloc(subpaths, size * sizeof(GfxSubpath *)); + greallocn(subpaths, size, sizeof(GfxSubpath *)); } subpaths[n] = new GfxSubpath(firstX, firstY); ++n; @@ -2374,7 +3486,7 @@ void GfxPath::append(GfxPath *path) { if (n + path->n > size) { size = n + path->n; subpaths = (GfxSubpath **) - grealloc(subpaths, size * sizeof(GfxSubpath *)); + greallocn(subpaths, size, sizeof(GfxSubpath *)); } for (i = 0; i < path->n; ++i) { subpaths[n++] = path->subpaths[i]->copy(); @@ -2395,9 +3507,10 @@ void GfxPath::offset(double dx, double dy) { //------------------------------------------------------------------------ GfxState::GfxState(double hDPI, double vDPI, PDFRectangle *pageBox, - int rotate, GBool upsideDown) { + int rotateA, GBool upsideDown) { double kx, ky; + rotate = rotateA; px1 = pageBox->x1; py1 = pageBox->y1; px2 = pageBox->x2; @@ -2448,8 +3561,11 @@ GfxState::GfxState(double hDPI, double vDPI, PDFRectangle *pageBox, strokeColor.c[0] = 0; fillPattern = NULL; strokePattern = NULL; + blendMode = gfxBlendNormal; fillOpacity = 1; strokeOpacity = 1; + fillOverprint = gFalse; + strokeOverprint = gFalse; lineWidth = 1; lineDash = NULL; @@ -2523,7 +3639,7 @@ GfxState::GfxState(GfxState *state) { strokePattern = state->strokePattern->copy(); } if (lineDashLength > 0) { - lineDash = (double *)gmalloc(lineDashLength * sizeof(double)); + lineDash = (double *)gmallocn(lineDashLength, sizeof(double)); memcpy(lineDash, state->lineDash, lineDashLength * sizeof(double)); } saved = NULL; @@ -2793,3 +3909,38 @@ GfxState *GfxState::restore() { return oldState; } + +GBool GfxState::parseBlendMode(Object *obj, GfxBlendMode *mode) { + Object obj2; + int i, j; + + if (obj->isName()) { + for (i = 0; i < nGfxBlendModeNames; ++i) { + if (!strcmp(obj->getName(), gfxBlendModeNames[i].name)) { + *mode = gfxBlendModeNames[i].mode; + return gTrue; + } + } + return gFalse; + } else if (obj->isArray()) { + for (i = 0; i < obj->arrayGetLength(); ++i) { + obj->arrayGet(i, &obj2); + if (!obj2.isName()) { + obj2.free(); + return gFalse; + } + for (j = 0; j < nGfxBlendModeNames; ++j) { + if (!strcmp(obj2.getName(), gfxBlendModeNames[j].name)) { + obj2.free(); + *mode = gfxBlendModeNames[j].mode; + return gTrue; + } + } + obj2.free(); + } + *mode = gfxBlendNormal; + return gTrue; + } else { + return gFalse; + } +} diff --git a/pdf2swf/xpdf/GlobalParams.cc b/pdf2swf/xpdf/GlobalParams.cc index 882083a..44dae3f 100644 --- a/pdf2swf/xpdf/GlobalParams.cc +++ b/pdf2swf/xpdf/GlobalParams.cc @@ -498,29 +498,6 @@ void GlobalParams::parseFile(GString *fileName, FILE *f) { char buf[512]; FILE *f2; - /* extract path */ - if(fileName) { - char* cfgFileName = fileName->getCString(); - char* pos1 = strrchr(cfgFileName, '/'); - char* pos2 = strrchr(cfgFileName, '\\'); - char* p = pos1>pos2?pos1:pos2; - int pos = p ? p-cfgFileName : -1; - GString*path = new GString(new GString(cfgFileName), 0, (pos < 0 ? strlen(cfgFileName): pos)); - if(pos1>=0) - path->append('/'); - else if(pos2>=0) - path->append('\\'); - else -#ifdef WIN32 - path->append('\\'); -#else - path->append('/'); -#endif - this->path = path; - } else { - this->path = new GString(); - } - line = 1; while (getLine(buf, sizeof(buf) - 1, f)) { @@ -717,32 +694,6 @@ void GlobalParams::parseNameToUnicode(GList *tokens, GString *fileName, fclose(f); } -static GString* qualify_filename(GString*path, GString*filename) -{ - GString*fullpath = 0; - char*prefix = "/usr/local/share/xpdf/"; - - if (filename->getChar(0) != '\\' && filename->getChar(0) != '/') { - /* relative path */ - fullpath = path->copy(); - fullpath->append(filename); - } else if (!strncmp(filename->getCString(), prefix, strlen(prefix))) { - /* xpdf default path */ - char*s = strchr(filename->getCString()+strlen(prefix), '/'); - if(s) { - fullpath = path->copy(); - fullpath->append(s+1); - } else { - fullpath = filename->copy(); - } - } else { - /* absolute path */ - fullpath = filename->copy(); - } - printf("%s -%s-> %s\n", filename->getCString(), path->getCString(), fullpath->getCString()); - return fullpath; -} - void GlobalParams::parseCIDToUnicode(GList *tokens, GString *fileName, int line) { GString *collection, *name, *old; @@ -754,12 +705,10 @@ void GlobalParams::parseCIDToUnicode(GList *tokens, GString *fileName, } collection = (GString *)tokens->get(1); name = (GString *)tokens->get(2); - if ((old = (GString *)cidToUnicodes->remove(collection))) { delete old; } - - cidToUnicodes->add(collection->copy(), qualify_filename(this->path, name)); + cidToUnicodes->add(collection->copy(), name->copy()); } void GlobalParams::parseUnicodeToUnicode(GList *tokens, GString *fileName, @@ -776,8 +725,7 @@ void GlobalParams::parseUnicodeToUnicode(GList *tokens, GString *fileName, if ((old = (GString *)unicodeToUnicodes->remove(font))) { delete old; } - - unicodeToUnicodes->add(font->copy(), qualify_filename(this->path, file)); + unicodeToUnicodes->add(font->copy(), file->copy()); } void GlobalParams::parseUnicodeMap(GList *tokens, GString *fileName, @@ -794,8 +742,7 @@ void GlobalParams::parseUnicodeMap(GList *tokens, GString *fileName, if ((old = (GString *)unicodeMaps->remove(encodingName))) { delete old; } - - unicodeMaps->add(encodingName->copy(), qualify_filename(this->path, name)); + unicodeMaps->add(encodingName->copy(), name->copy()); } void GlobalParams::parseCMapDir(GList *tokens, GString *fileName, int line) { @@ -813,30 +760,23 @@ void GlobalParams::parseCMapDir(GList *tokens, GString *fileName, int line) { list = new GList(); cMapDirs->add(collection->copy(), list); } - - list->append(qualify_filename(this->path, dir)); + list->append(dir->copy()); } void GlobalParams::parseToUnicodeDir(GList *tokens, GString *fileName, int line) { - GString *dir; - if (tokens->getLength() != 2) { error(-1, "Bad 'toUnicodeDir' config file command (%s:%d)", fileName->getCString(), line); return; } - - dir = (GString *)tokens->get(1); - - toUnicodeDirs->append(qualify_filename(this->path, dir)); + toUnicodeDirs->append(((GString *)tokens->get(1))->copy()); } void GlobalParams::parseDisplayFont(GList *tokens, GHash *fontHash, DisplayFontParamKind kind, GString *fileName, int line) { DisplayFontParam *param, *old; - GString *file; if (tokens->getLength() < 2) { goto err1; @@ -848,15 +788,13 @@ void GlobalParams::parseDisplayFont(GList *tokens, GHash *fontHash, if (tokens->getLength() != 3) { goto err2; } - file = (GString *)tokens->get(2); - param->t1.fileName = qualify_filename(this->path, file); + param->t1.fileName = ((GString *)tokens->get(2))->copy(); break; case displayFontTT: if (tokens->getLength() != 3) { goto err2; } - file = (GString *)tokens->get(2); - param->tt.fileName = qualify_filename(this->path, file); + param->tt.fileName = ((GString *)tokens->get(2))->copy(); break; } diff --git a/pdf2swf/xpdf/GlobalParams.h b/pdf2swf/xpdf/GlobalParams.h index e14ad4f..1fdef63 100644 --- a/pdf2swf/xpdf/GlobalParams.h +++ b/pdf2swf/xpdf/GlobalParams.h @@ -212,10 +212,10 @@ public: void addSecurityHandler(XpdfSecurityHandler *handler); XpdfSecurityHandler *getSecurityHandler(char *name); - void parseFile(GString *fileName, FILE *f); private: + void parseFile(GString *fileName, FILE *f); void parseNameToUnicode(GList *tokens, GString *fileName, int line); void parseCIDToUnicode(GList *tokens, GString *fileName, int line); void parseUnicodeToUnicode(GList *tokens, GString *fileName, int line); @@ -246,10 +246,6 @@ private: GBool loadPlugin(char *type, char *name); #endif - //----- config file base path - - GString*path; - //----- static tables NameToCharCode * // mapping from char name to diff --git a/pdf2swf/xpdf/OutputDev.h b/pdf2swf/xpdf/OutputDev.h index 327aa24..fdb0edc 100644 --- a/pdf2swf/xpdf/OutputDev.h +++ b/pdf2swf/xpdf/OutputDev.h @@ -61,9 +61,6 @@ public: // will be reduced to a series of other drawing operations. virtual GBool useShadedFills() { return gFalse; } - // Is this device able to draw gradients? - virtual GBool useGradients() = 0; - // Does this device use beginType3Char/endType3Char? Otherwise, // text in Type 3 fonts will be drawn with drawChar/drawString. virtual GBool interpretType3Chars() = 0; @@ -77,7 +74,7 @@ public: virtual void setDefaultCTM(double *ctm); // Start a page. - virtual void startPage(int pageNum, GfxState *state, double x1,double y1,double x2,double y2) {} + virtual void startPage(int pageNum, GfxState *state) {} // End a page. virtual void endPage() {} diff --git a/pdf2swf/xpdf/Page.cc b/pdf2swf/xpdf/Page.cc index 5c2ae8b..6ef8433 100644 --- a/pdf2swf/xpdf/Page.cc +++ b/pdf2swf/xpdf/Page.cc @@ -66,19 +66,6 @@ PageAttrs::PageAttrs(PageAttrs *attrs, Dict *dict) { cropBox = mediaBox; } - /* if the crop box is larger than the media box, cut it down to - media box size */ - if(haveCropBox && - mediaBox.x1 <= cropBox.x2 && - mediaBox.y1 <= cropBox.y2 && - cropBox.x1 <= mediaBox.x2 && - cropBox.y1 <= mediaBox.y2) { - if(mediaBox.x1 >= cropBox.x1) cropBox.x1 = mediaBox.x1; - if(mediaBox.y1 >= cropBox.y1) cropBox.y1 = mediaBox.y1; - if(mediaBox.x2 <= cropBox.x2) cropBox.x2 = mediaBox.x2; - if(mediaBox.y2 <= cropBox.y2) cropBox.y2 = mediaBox.y2; - } - // other boxes bleedBox = cropBox; readBox(dict, "BleedBox", &bleedBox); diff --git a/pdf2swf/xpdf/Stream.cc b/pdf2swf/xpdf/Stream.cc index 7a663d3..3306279 100644 --- a/pdf2swf/xpdf/Stream.cc +++ b/pdf2swf/xpdf/Stream.cc @@ -17,8 +17,6 @@ #include #ifndef WIN32 #include -#else -extern "C" int unlink(char *filename); #endif #include #include diff --git a/pdf2swf/xpdf/config.h b/pdf2swf/xpdf/config.h index f21e311..4c8f756 100644 --- a/pdf2swf/xpdf/config.h +++ b/pdf2swf/xpdf/config.h @@ -53,18 +53,18 @@ // user config file name, relative to the user's home directory #if defined(VMS) || (defined(WIN32) && !defined(__CYGWIN32__)) -#define xpdfUserConfigFile "pdf2swf.conf" +#define xpdfUserConfigFile "xpdfrc" #else -#define xpdfUserConfigFile ".pdf2swf.conf" +#define xpdfUserConfigFile ".xpdfrc" #endif // system config file name (set via the configure script) -#ifndef WIN32 -#define xpdfSysConfigFile "/etc/pdf2swf.conf" +#ifdef SYSTEM_XPDFRC +#define xpdfSysConfigFile SYSTEM_XPDFRC #else // under Windows, we get the directory with the executable and then // append this file name -#define xpdfSysConfigFile "pdf2swf.conf" +#define xpdfSysConfigFile "xpdfrc" #endif //------------------------------------------------------------------------ diff --git a/pdf2swf/xpdf/gfile.cc b/pdf2swf/xpdf/gfile.cc index 5fa0762..11f5cf6 100644 --- a/pdf2swf/xpdf/gfile.cc +++ b/pdf2swf/xpdf/gfile.cc @@ -437,52 +437,6 @@ time_t getModTime(char *fileName) { #endif } -static char* getTempDir() -{ -#ifdef WIN32 - char*dir = getenv("TMP"); - if(!dir) dir = getenv("TEMP"); - if(!dir) dir = getenv("tmp"); - if(!dir) dir = getenv("temp"); - if(!dir) dir = "C:\\"; -#else - char* dir = "/tmp/"; -#endif - return dir; -} - -char* mktmpname(char*ptr) { - static char tmpbuf[128]; - char*dir = getTempDir(); - int l = strlen(dir); - char*sep = ""; - if(!ptr) - ptr = tmpbuf; - if(l && dir[l-1]!='/' && dir[l-1]!='\\') { -#ifdef WIN32 - sep = "\\"; -#else - sep = "/"; -#endif - } - - // used to be mktemp. This does remove the warnings, but - // It's not exactly an improvement. -#ifdef HAVE_LRAND48 - sprintf(ptr, "%s%s%08x%08x",dir,sep,lrand48(),lrand48()); -#else -# ifdef HAVE_RAND - sprintf(ptr, "%s%s%08x%08x",dir,sep,rand(),rand()); -# else - static int count = 1; - sprintf(ptr, "%s%s%08x%04x%04x",dir,sep,time(0),(unsigned int)tmpbuf^((unsigned int)tmpbuf)>>16,count); - count ++; -# endif -#endif - return ptr; -} - - GBool openTempFile(GString **name, FILE **f, char *mode, char *ext) { #if defined(WIN32) //---------- Win32 ---------- @@ -509,7 +463,7 @@ GBool openTempFile(GString **name, FILE **f, char *mode, char *ext) { // with this file name after the tmpnam call and before the fopen // call. I will happily accept fixes to this function for non-Unix // OSs. - if (!(s = mktmpname(NULL))) { + if (!(s = tmpnam(NULL))) { return gFalse; } *name = new GString(s); @@ -536,7 +490,7 @@ GBool openTempFile(GString **name, FILE **f, char *mode, char *ext) { (*name)->append("/XXXXXX")->append(ext); fd = mkstemps((*name)->getCString(), strlen(ext)); #else - if (!(s = mktmpname(NULL))) { + if (!(s = tmpnam(NULL))) { return gFalse; } *name = new GString(s); @@ -553,7 +507,7 @@ GBool openTempFile(GString **name, FILE **f, char *mode, char *ext) { (*name)->append("/XXXXXX"); fd = mkstemp((*name)->getCString()); #else // HAVE_MKSTEMP - if (!(s = mktmpname(NULL))) { + if (!(s = tmpnam(NULL))) { return gFalse; } *name = new GString(s); diff --git a/pdf2swf/xpdf/gfile.h b/pdf2swf/xpdf/gfile.h index 10a4226..82f1d7a 100644 --- a/pdf2swf/xpdf/gfile.h +++ b/pdf2swf/xpdf/gfile.h @@ -58,9 +58,6 @@ extern GString *getHomeDir(); // Get current directory. extern GString *getCurrentDir(); -/* create a temporary filename */ -char* mktmpname(char*ptr); - // Append a file name to a path string. may be an empty // string, denoting the current directory). Returns . extern GString *appendToPath(GString *path, char *fileName); -- 1.7.10.4