summaryrefslogtreecommitdiff
path: root/noncore/unsupported/qpdf/xpdf/GfxState.cc
Unidiff
Diffstat (limited to 'noncore/unsupported/qpdf/xpdf/GfxState.cc') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/unsupported/qpdf/xpdf/GfxState.cc246
1 files changed, 235 insertions, 11 deletions
diff --git a/noncore/unsupported/qpdf/xpdf/GfxState.cc b/noncore/unsupported/qpdf/xpdf/GfxState.cc
index af4e0d4..befd45a 100644
--- a/noncore/unsupported/qpdf/xpdf/GfxState.cc
+++ b/noncore/unsupported/qpdf/xpdf/GfxState.cc
@@ -2,7 +2,7 @@
2// 2//
3// GfxState.cc 3// GfxState.cc
4// 4//
5// Copyright 1996 Derek B. Noonburg 5// Copyright 1996-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
@@ -408,9 +408,22 @@ void GfxDeviceCMYKColorSpace::getGray(GfxColor *color, fouble *gray) {
408} 408}
409 409
410void GfxDeviceCMYKColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { 410void GfxDeviceCMYKColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
411 rgb->r = clip01(1 - (color->c[0] + color->c[3])); 411 fouble c, m, y, aw, ac, am, ay, ar, ag, ab;
412 rgb->g = clip01(1 - (color->c[1] + color->c[3])); 412
413 rgb->b = clip01(1 - (color->c[2] + color->c[3])); 413 c = clip01(color->c[0] + color->c[3]);
414 m = clip01(color->c[1] + color->c[3]);
415 y = clip01(color->c[2] + color->c[3]);
416 aw = (1-c) * (1-m) * (1-y);
417 ac = c * (1-m) * (1-y);
418 am = (1-c) * m * (1-y);
419 ay = (1-c) * (1-m) * y;
420 ar = (1-c) * m * y;
421 ag = c * (1-m) * y;
422 ab = c * m * (1-y);
423 rgb->r = clip01(aw + 0.9137*am + 0.9961*ay + 0.9882*ar);
424 rgb->g = clip01(aw + 0.6196*ac + ay + 0.5176*ag);
425 rgb->b = clip01(aw + 0.7804*ac + 0.5412*am + 0.0667*ar + 0.2118*ag +
426 0.4863*ab);
414} 427}
415 428
416void GfxDeviceCMYKColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { 429void GfxDeviceCMYKColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
@@ -1268,10 +1281,6 @@ GfxShading *GfxShading::parse(Object *obj) {
1268 } 1281 }
1269 typeA = obj1.getInt(); 1282 typeA = obj1.getInt();
1270 obj1.free(); 1283 obj1.free();
1271 if (typeA != 2) {
1272 error(-1, "Unimplemented shading type %d", typeA);
1273 goto err1;
1274 }
1275 1284
1276 obj->dictLookup("ColorSpace", &obj1); 1285 obj->dictLookup("ColorSpace", &obj1);
1277 if (!(colorSpaceA = GfxColorSpace::parse(&obj1))) { 1286 if (!(colorSpaceA = GfxColorSpace::parse(&obj1))) {
@@ -1317,7 +1326,17 @@ GfxShading *GfxShading::parse(Object *obj) {
1317 } 1326 }
1318 obj1.free(); 1327 obj1.free();
1319 1328
1320 shading = GfxAxialShading::parse(obj->getDict()); 1329 switch (typeA) {
1330 case 2:
1331 shading = GfxAxialShading::parse(obj->getDict());
1332 break;
1333 case 3:
1334 shading = GfxRadialShading::parse(obj->getDict());
1335 break;
1336 default:
1337 error(-1, "Unimplemented shading type %d", typeA);
1338 goto err1;
1339 }
1321 1340
1322 if (shading) { 1341 if (shading) {
1323 shading->type = typeA; 1342 shading->type = typeA;
@@ -1457,6 +1476,128 @@ void GfxAxialShading::getColor(fouble t, GfxColor *color) {
1457} 1476}
1458 1477
1459//------------------------------------------------------------------------ 1478//------------------------------------------------------------------------
1479// GfxRadialShading
1480//------------------------------------------------------------------------
1481
1482GfxRadialShading::GfxRadialShading(fouble x0A, fouble y0A, fouble r0A,
1483 fouble x1A, fouble y1A, fouble r1A,
1484 fouble t0A, fouble t1A,
1485 Function **funcsA, int nFuncsA,
1486 GBool extend0A, GBool extend1A) {
1487 int i;
1488
1489 x0 = x0A;
1490 y0 = y0A;
1491 r0 = r0A;
1492 x1 = x1A;
1493 y1 = y1A;
1494 r1 = r1A;
1495 t0 = t0A;
1496 t1 = t1A;
1497 nFuncs = nFuncsA;
1498 for (i = 0; i < nFuncs; ++i) {
1499 funcs[i] = funcsA[i];
1500 }
1501 extend0 = extend0A;
1502 extend1 = extend1A;
1503}
1504
1505GfxRadialShading::~GfxRadialShading() {
1506 int i;
1507
1508 for (i = 0; i < nFuncs; ++i) {
1509 delete funcs[i];
1510 }
1511}
1512
1513GfxRadialShading *GfxRadialShading::parse(Dict *dict) {
1514 fouble x0A, y0A, r0A, x1A, y1A, r1A;
1515 fouble t0A, t1A;
1516 Function *funcsA[gfxColorMaxComps];
1517 int nFuncsA;
1518 GBool extend0A, extend1A;
1519 Object obj1, obj2;
1520 int i;
1521
1522 x0A = y0A = r0A = x1A = y1A = r1A = 0;
1523 if (dict->lookup("Coords", &obj1)->isArray() &&
1524 obj1.arrayGetLength() == 6) {
1525 x0A = obj1.arrayGet(0, &obj2)->getNum();
1526 obj2.free();
1527 y0A = obj1.arrayGet(1, &obj2)->getNum();
1528 obj2.free();
1529 r0A = obj1.arrayGet(2, &obj2)->getNum();
1530 obj2.free();
1531 x1A = obj1.arrayGet(3, &obj2)->getNum();
1532 obj2.free();
1533 y1A = obj1.arrayGet(4, &obj2)->getNum();
1534 obj2.free();
1535 r1A = obj1.arrayGet(5, &obj2)->getNum();
1536 obj2.free();
1537 } else {
1538 error(-1, "Missing or invalid Coords in shading dictionary");
1539 goto err1;
1540 }
1541 obj1.free();
1542
1543 t0A = 0;
1544 t1A = 1;
1545 if (dict->lookup("Domain", &obj1)->isArray() &&
1546 obj1.arrayGetLength() == 2) {
1547 t0A = obj1.arrayGet(0, &obj2)->getNum();
1548 obj2.free();
1549 t1A = obj1.arrayGet(1, &obj2)->getNum();
1550 obj2.free();
1551 }
1552 obj1.free();
1553
1554 dict->lookup("Function", &obj1);
1555 if (obj1.isArray()) {
1556 nFuncsA = obj1.arrayGetLength();
1557 for (i = 0; i < nFuncsA; ++i) {
1558 obj1.arrayGet(i, &obj2);
1559 if (!(funcsA[i] = Function::parse(&obj2))) {
1560 obj1.free();
1561 obj2.free();
1562 goto err1;
1563 }
1564 obj2.free();
1565 }
1566 } else {
1567 nFuncsA = 1;
1568 if (!(funcsA[0] = Function::parse(&obj1))) {
1569 obj1.free();
1570 goto err1;
1571 }
1572 }
1573 obj1.free();
1574
1575 extend0A = extend1A = gFalse;
1576 if (dict->lookup("Extend", &obj1)->isArray() &&
1577 obj1.arrayGetLength() == 2) {
1578 extend0A = obj1.arrayGet(0, &obj2)->getBool();
1579 obj2.free();
1580 extend1A = obj1.arrayGet(1, &obj2)->getBool();
1581 obj2.free();
1582 }
1583 obj1.free();
1584
1585 return new GfxRadialShading(x0A, y0A, r0A, x1A, y1A, r1A, t0A, t1A,
1586 funcsA, nFuncsA, extend0A, extend1A);
1587
1588 err1:
1589 return NULL;
1590}
1591
1592void GfxRadialShading::getColor(fouble t, GfxColor *color) {
1593 int i;
1594
1595 for (i = 0; i < nFuncs; ++i) {
1596 funcs[i]->transform(&t, &color->c[i]);
1597 }
1598}
1599
1600//------------------------------------------------------------------------
1460// GfxImageColorMap 1601// GfxImageColorMap
1461//------------------------------------------------------------------------ 1602//------------------------------------------------------------------------
1462 1603
@@ -1918,6 +2059,67 @@ GfxState::GfxState(GfxState *state) {
1918 saved = NULL; 2059 saved = NULL;
1919} 2060}
1920 2061
2062void GfxState::getUserClipBBox(fouble *xMin, fouble *yMin,
2063 fouble *xMax, fouble *yMax) {
2064 fouble ictm[6];
2065 fouble xMin1, yMin1, xMax1, yMax1, det, tx, ty;
2066
2067 // invert the CTM
2068 det = 1 / (ctm[0] * ctm[3] - ctm[1] * ctm[2]);
2069 ictm[0] = ctm[3] * det;
2070 ictm[1] = -ctm[1] * det;
2071 ictm[2] = -ctm[2] * det;
2072 ictm[3] = ctm[0] * det;
2073 ictm[4] = (ctm[2] * ctm[5] - ctm[3] * ctm[4]) * det;
2074 ictm[5] = (ctm[1] * ctm[4] - ctm[0] * ctm[5]) * det;
2075
2076 // transform all four corners of the clip bbox; find the min and max
2077 // x and y values
2078 xMin1 = xMax1 = clipXMin * ictm[0] + clipYMin * ictm[2] + ictm[4];
2079 yMin1 = yMax1 = clipXMin * ictm[1] + clipYMin * ictm[3] + ictm[5];
2080 tx = clipXMin * ictm[0] + clipYMax * ictm[2] + ictm[4];
2081 ty = clipXMin * ictm[1] + clipYMax * ictm[3] + ictm[5];
2082 if (tx < xMin1) {
2083 xMin1 = tx;
2084 } else if (tx > xMax1) {
2085 xMax1 = tx;
2086 }
2087 if (ty < yMin1) {
2088 yMin1 = ty;
2089 } else if (ty > yMax1) {
2090 yMax1 = ty;
2091 }
2092 tx = clipXMax * ictm[0] + clipYMin * ictm[2] + ictm[4];
2093 ty = clipXMax * ictm[1] + clipYMin * ictm[3] + ictm[5];
2094 if (tx < xMin1) {
2095 xMin1 = tx;
2096 } else if (tx > xMax1) {
2097 xMax1 = tx;
2098 }
2099 if (ty < yMin1) {
2100 yMin1 = ty;
2101 } else if (ty > yMax1) {
2102 yMax1 = ty;
2103 }
2104 tx = clipXMax * ictm[0] + clipYMax * ictm[2] + ictm[4];
2105 ty = clipXMax * ictm[1] + clipYMax * ictm[3] + ictm[5];
2106 if (tx < xMin1) {
2107 xMin1 = tx;
2108 } else if (tx > xMax1) {
2109 xMax1 = tx;
2110 }
2111 if (ty < yMin1) {
2112 yMin1 = ty;
2113 } else if (ty > yMax1) {
2114 yMax1 = ty;
2115 }
2116
2117 *xMin = xMin1;
2118 *yMin = yMin1;
2119 *xMax = xMax1;
2120 *yMax = yMax1;
2121}
2122
1921fouble GfxState::transformWidth(fouble w) { 2123fouble GfxState::transformWidth(fouble w) {
1922 fouble x, y; 2124 fouble x, y;
1923 2125
@@ -1946,12 +2148,23 @@ void GfxState::getFontTransMat(fouble *m11, fouble *m12,
1946 2148
1947void GfxState::setCTM(fouble a, fouble b, fouble c, 2149void GfxState::setCTM(fouble a, fouble b, fouble c,
1948 fouble d, fouble e, fouble f) { 2150 fouble d, fouble e, fouble f) {
2151 int i;
2152
1949 ctm[0] = a; 2153 ctm[0] = a;
1950 ctm[1] = b; 2154 ctm[1] = b;
1951 ctm[2] = c; 2155 ctm[2] = c;
1952 ctm[3] = d; 2156 ctm[3] = d;
1953 ctm[4] = e; 2157 ctm[4] = e;
1954 ctm[5] = f; 2158 ctm[5] = f;
2159
2160 // avoid FP exceptions on badly messed up PDF files
2161 for (i = 0; i < 6; ++i) {
2162 if (ctm[i] > fouble(1e3)) {
2163 ctm[i] = fouble(1e3);
2164 } else if (ctm[i] < -fouble(1e3)) {
2165 ctm[i] = -fouble(1e3);
2166 }
2167 }
1955} 2168}
1956 2169
1957void GfxState::concatCTM(fouble a, fouble b, fouble c, 2170void GfxState::concatCTM(fouble a, fouble b, fouble c,
@@ -1960,6 +2173,7 @@ void GfxState::concatCTM(fouble a, fouble b, fouble c,
1960 fouble b1 = ctm[1]; 2173 fouble b1 = ctm[1];
1961 fouble c1 = ctm[2]; 2174 fouble c1 = ctm[2];
1962 fouble d1 = ctm[3]; 2175 fouble d1 = ctm[3];
2176 int i;
1963 2177
1964 ctm[0] = a * a1 + b * c1; 2178 ctm[0] = a * a1 + b * c1;
1965 ctm[1] = a * b1 + b * d1; 2179 ctm[1] = a * b1 + b * d1;
@@ -1967,6 +2181,15 @@ void GfxState::concatCTM(fouble a, fouble b, fouble c,
1967 ctm[3] = c * b1 + d * d1; 2181 ctm[3] = c * b1 + d * d1;
1968 ctm[4] = e * a1 + f * c1 + ctm[4]; 2182 ctm[4] = e * a1 + f * c1 + ctm[4];
1969 ctm[5] = e * b1 + f * d1 + ctm[5]; 2183 ctm[5] = e * b1 + f * d1 + ctm[5];
2184
2185 // avoid FP exceptions on badly messed up PDF files
2186 for (i = 0; i < 6; ++i) {
2187 if (ctm[i] > fouble(1e3)) {
2188 ctm[i] = fouble(1e3);
2189 } else if (ctm[i] < -fouble(1e3)) {
2190 ctm[i] = -fouble(1e3);
2191 }
2192 }
1970} 2193}
1971 2194
1972void GfxState::setFillColorSpace(GfxColorSpace *colorSpace) { 2195void GfxState::setFillColorSpace(GfxColorSpace *colorSpace) {
@@ -2051,10 +2274,10 @@ void GfxState::clip() {
2051 } 2274 }
2052} 2275}
2053 2276
2054void GfxState::textShift(fouble tx) { 2277void GfxState::textShift(fouble tx, fouble ty) {
2055 fouble dx, dy; 2278 fouble dx, dy;
2056 2279
2057 textTransformDelta(tx, 0, &dx, &dy); 2280 textTransformDelta(tx, ty, &dx, &dy);
2058 curX += dx; 2281 curX += dx;
2059 curY += dy; 2282 curY += dy;
2060} 2283}
@@ -2095,3 +2318,4 @@ GfxState *GfxState::restore() {
2095 2318
2096 return oldState; 2319 return oldState;
2097} 2320}
2321