Commit 51670972 authored by Albert Astals Cid's avatar Albert Astals Cid
Browse files

Last xpdf 3.01 merge (at least from my side)

It's very big, but noone has opposed in the 2 weeks time i gave on the ml so either poppler is dead or people agree with the patch
parent 10dfa225
2005-10-30 Albert Astals Cid <aacid@kde.org>
* glib/poppler-page.cc
* poppler/ArthurOutputDev.cc
* poppler/ArthurOutputDev.h
* poppler/CairoOutputDev.cc
* poppler/CairoOutputDev.h
* poppler/Gfx.cc
* poppler/Gfx.h
* poppler/GfxState.cc
* poppler/GfxState.h
* poppler/OutputDev.cc
* poppler/OutputDev.h
* poppler/PDFDoc.cc
* poppler/PDFDoc.h
* poppler/PSOutputDev.cc
* poppler/PSOutputDev.h
* poppler/Page.cc
* poppler/Page.h
* poppler/SplashOutputDev.cc
* poppler/SplashOutputDev.h
* poppler/TextOutputDev.cc
* poppler/TextOutputDev.h
* qt/poppler-page.cc
* qt4/src/poppler-page.cc
* splash/Splash.cc
* splash/Splash.h
* splash/SplashBitmap.cc
* splash/SplashBitmap.h
* splash/SplashPattern.cc
* splash/SplashPattern.h
* splash/SplashState.cc
* splash/SplashState.h
* splash/SplashTypes.h
* test/gtk-cairo-test.cc
* test/gtk-splash-test.cc
* test/pdf-inspector.cc: Last xpdf 3.01 merges
2005-10-16 Kristian Høgsberg <krh@redhat.com>
* poppler/poppler-config.h.in (GCC_PRINTF_FORMAT): Remove evil
......
......@@ -85,11 +85,11 @@ poppler_page_get_size (PopplerPage *page,
rotate = page->page->getRotate ();
if (rotate == 90 || rotate == 270) {
page_height = page->page->getWidth ();
page_width = page->page->getHeight ();
page_height = page->page->getCropWidth ();
page_width = page->page->getCropHeight ();
} else {
page_width = page->page->getWidth ();
page_height = page->page->getHeight ();
page_width = page->page->getCropWidth ();
page_height = page->page->getCropHeight ();
}
if (width != NULL)
......@@ -129,11 +129,11 @@ poppler_page_prepare_output_dev (PopplerPage *page,
rotate = (rotation + page->page->getRotate()) % 360;
if (rotate == 90 || rotate == 270) {
cairo_width = MAX ((int)(page->page->getHeight() * scale + 0.5), 1);
cairo_height = MAX ((int)(page->page->getWidth() * scale + 0.5), 1);
cairo_width = MAX ((int)(page->page->getCropHeight() * scale + 0.5), 1);
cairo_height = MAX ((int)(page->page->getCropWidth() * scale + 0.5), 1);
} else {
cairo_width = MAX ((int)(page->page->getWidth() * scale + 0.5), 1);
cairo_height = MAX ((int)(page->page->getHeight() * scale + 0.5), 1);
cairo_width = MAX ((int)(page->page->getCropWidth() * scale + 0.5), 1);
cairo_height = MAX ((int)(page->page->getCropHeight() * scale + 0.5), 1);
}
output_dev = page->document->output_dev;
......@@ -301,6 +301,7 @@ poppler_page_render_to_pixbuf (PopplerPage *page,
page->page->displaySlice(page->document->output_dev,
72.0 * scale, 72.0 * scale,
rotation,
gFalse, /* useMediaBox */
gTrue, /* Crop */
src_x, src_y,
src_width, src_height,
......@@ -318,6 +319,7 @@ poppler_page_get_text_output_dev (PopplerPage *page)
page->gfx = page->page->createGfx(page->text_dev,
72.0, 72.0, 0,
gFalse, /* useMediaBox */
gTrue, /* Crop */
-1, -1, -1, -1,
NULL, /* links */
......@@ -642,15 +644,17 @@ poppler_page_find_text (PopplerPage *page,
doc = page->document->doc;
poppler_page_get_size (page, NULL, &height);
page->page->display (output_dev, 72, 72, 0,
page->page->display (output_dev, 72, 72, 0, gFalse,
gTrue, NULL, doc->getCatalog());
matches = NULL;
xMin = 0;
yMin = 0;
#warning you probably want to add caseSensitive and backwards as parameters
while (output_dev->findText (ucs4, ucs4_len,
gFalse, gTrue, // startAtTop, stopAtBottom
gTrue, gFalse, // startAtLast, stopAtLast
gFalse, gFalse, // caseSensitive, backwards
&xMin, &yMin, &xMax, &yMax))
{
match = g_new (PopplerRectangle, 1);
......@@ -693,7 +697,7 @@ poppler_page_render_to_ps (PopplerPage *page,
ps_file->document->doc->displayPage (ps_file->out, page->index + 1, 72.0, 72.0,
0, gTrue, gFalse);
0, gFalse, gTrue, gFalse);
}
static void
......@@ -780,10 +784,10 @@ poppler_page_get_link_mapping (PopplerPage *page)
link->getRect (&(mapping->area.x1), &(mapping->area.y1),
&(mapping->area.x2), &(mapping->area.y2));
mapping->area.x1 -= page->page->getBox()->x1;
mapping->area.x2 -= page->page->getBox()->x1;
mapping->area.y1 -= page->page->getBox()->y1;
mapping->area.y2 -= page->page->getBox()->y1;
mapping->area.x1 -= page->page->getCropBox()->x1;
mapping->area.x2 -= page->page->getCropBox()->x1;
mapping->area.y1 -= page->page->getCropBox()->y1;
mapping->area.y2 -= page->page->getCropBox()->y1;
map_list = g_list_prepend (map_list, mapping);
}
......
......@@ -485,7 +485,7 @@ void ArthurOutputDev::eoClip(GfxState *state)
void ArthurOutputDev::drawChar(GfxState *state, double x, double y,
double dx, double dy,
double originX, double originY,
CharCode code, Unicode *u, int uLen) {
CharCode code, int nBytes, Unicode *u, int uLen) {
double x1, y1;
// SplashPath *path;
int render;
......
......@@ -102,7 +102,7 @@ public:
virtual void drawChar(GfxState *state, double x, double y,
double dx, double dy,
double originX, double originY,
CharCode code, Unicode *u, int uLen);
CharCode code, int nBytes, Unicode *u, int uLen);
virtual GBool beginType3Char(GfxState *state, double x, double y,
double dx, double dy,
CharCode code, Unicode *u, int uLen);
......
......@@ -348,7 +348,7 @@ void CairoOutputDev::beginString(GfxState *state, GooString *s)
void CairoOutputDev::drawChar(GfxState *state, double x, double y,
double dx, double dy,
double originX, double originY,
CharCode code, Unicode *u, int uLen)
CharCode code, int nBytes, Unicode *u, int uLen)
{
double tx, ty;
......
......@@ -102,7 +102,7 @@ public:
void drawChar(GfxState *state, double x, double y,
double dx, double dy,
double originX, double originY,
CharCode code, Unicode *u, int uLen);
CharCode code, int nBytes, Unicode *u, int uLen);
virtual GBool beginType3Char(GfxState *state, double x, double y,
double dx, double dy,
......
......@@ -12,6 +12,7 @@
#pragma implementation
#endif
#include <stdlib.h>
#include <stdio.h>
#include <stddef.h>
#include <string.h>
......@@ -48,19 +49,33 @@
#define functionMaxDepth 6
// Max delta allowed in any color component for a function shading fill.
#define functionColorDelta (1 / 256.0)
#define functionColorDelta (dblToCol(1 / 256.0))
// Max number of splits along the t axis for an axial shading fill.
#define axialMaxSplits 256
// Max delta allowed in any color component for an axial shading fill.
#define axialColorDelta (1 / 256.0)
#define axialColorDelta (dblToCol(1 / 256.0))
// Max number of splits along the t axis for a radial shading fill.
#define radialMaxSplits 256
// Max delta allowed in any color component for a radial shading fill.
#define radialColorDelta (1 / 256.0)
#define radialColorDelta (dblToCol(1 / 256.0))
// Max recursive depth for a Gouraud triangle shading fill.
#define gouraudMaxDepth 4
// Max delta allowed in any color component for a Gouraud triangle
// shading fill.
#define gouraudColorDelta (dblToCol(1 / 256.0))
// Max recursive depth for a patch mesh shading fill.
#define patchMaxDepth 6
// Max delta allowed in any color component for a patch mesh shading
// fill.
#define patchColorDelta (dblToCol(1 / 256.0))
//------------------------------------------------------------------------
// Operator table
......@@ -408,7 +423,7 @@ GBool GfxResources::lookupGState(char *name, Object *obj) {
//------------------------------------------------------------------------
Gfx::Gfx(XRef *xrefA, OutputDev *outA, int pageNum, Dict *resDict,
double hDPI, double vDPI, PDFRectangle *box, GBool crop,
double hDPI, double vDPI, PDFRectangle *box,
PDFRectangle *cropBox, int rotate,
GBool (*abortCheckCbkA)(void *data),
void *abortCheckCbkDataA) {
......@@ -439,7 +454,7 @@ Gfx::Gfx(XRef *xrefA, OutputDev *outA, int pageNum, Dict *resDict,
abortCheckCbkData = abortCheckCbkDataA;
// set crop box
if (crop) {
if (cropBox) {
state->moveTo(cropBox->x1, cropBox->y1);
state->lineTo(cropBox->x2, cropBox->y1);
state->lineTo(cropBox->x2, cropBox->y2);
......@@ -452,7 +467,7 @@ Gfx::Gfx(XRef *xrefA, OutputDev *outA, int pageNum, Dict *resDict,
}
Gfx::Gfx(XRef *xrefA, OutputDev *outA, Dict *resDict,
PDFRectangle *box, GBool crop, PDFRectangle *cropBox,
PDFRectangle *box, PDFRectangle *cropBox,
GBool (*abortCheckCbkA)(void *data),
void *abortCheckCbkDataA) {
int i;
......@@ -478,7 +493,7 @@ Gfx::Gfx(XRef *xrefA, OutputDev *outA, Dict *resDict,
abortCheckCbkData = abortCheckCbkDataA;
// set crop box
if (crop) {
if (cropBox) {
state->moveTo(cropBox->x1, cropBox->y1);
state->lineTo(cropBox->x2, cropBox->y1);
state->lineTo(cropBox->x2, cropBox->y2);
......@@ -801,6 +816,8 @@ void Gfx::opSetLineWidth(Object args[], int numArgs) {
void Gfx::opSetExtGState(Object args[], int numArgs) {
Object obj1, obj2;
GfxBlendMode mode;
GBool haveFillOP;
if (!res->lookupGState(args[0].getName(), &obj1)) {
return;
......@@ -810,6 +827,17 @@ void Gfx::opSetExtGState(Object args[], int numArgs) {
obj1.free();
return;
}
// transparency support: blend mode, fill/stroke opacity
if (!obj1.dictLookup("BM", &obj2)->isNull()) {
if (state->parseBlendMode(&obj2, &mode)) {
state->setBlendMode(mode);
out->updateBlendMode(state);
} else {
error(getPos(), "Invalid blend mode in ExtGState");
}
}
obj2.free();
if (obj1.dictLookup("ca", &obj2)->isNum()) {
state->setFillOpacity(obj2.getNum());
out->updateFillOpacity(state);
......@@ -820,6 +848,23 @@ void Gfx::opSetExtGState(Object args[], int numArgs) {
out->updateStrokeOpacity(state);
}
obj2.free();
// fill/stroke overprint
if ((haveFillOP = (obj1.dictLookup("op", &obj2)->isBool()))) {
state->setFillOverprint(obj2.getBool());
out->updateFillOverprint(state);
}
obj2.free();
if (obj1.dictLookup("OP", &obj2)->isBool()) {
state->setStrokeOverprint(obj2.getBool());
out->updateStrokeOverprint(state);
if (!haveFillOP) {
state->setFillOverprint(obj2.getBool());
out->updateFillOverprint(state);
}
}
obj2.free();
obj1.free();
}
......@@ -835,7 +880,8 @@ void Gfx::opSetFillGray(Object args[], int numArgs) {
state->setFillPattern(NULL);
state->setFillColorSpace(new GfxDeviceGrayColorSpace());
color.c[0] = args[0].getNum();
out->updateFillColorSpace(state);
color.c[0] = dblToCol(args[0].getNum());
state->setFillColor(&color);
out->updateFillColor(state);
}
......@@ -845,7 +891,8 @@ void Gfx::opSetStrokeGray(Object args[], int numArgs) {
state->setStrokePattern(NULL);
state->setStrokeColorSpace(new GfxDeviceGrayColorSpace());
color.c[0] = args[0].getNum();
out->updateStrokeColorSpace(state);
color.c[0] = dblToCol(args[0].getNum());
state->setStrokeColor(&color);
out->updateStrokeColor(state);
}
......@@ -856,8 +903,9 @@ void Gfx::opSetFillCMYKColor(Object args[], int numArgs) {
state->setFillPattern(NULL);
state->setFillColorSpace(new GfxDeviceCMYKColorSpace());
out->updateFillColorSpace(state);
for (i = 0; i < 4; ++i) {
color.c[i] = args[i].getNum();
color.c[i] = dblToCol(args[i].getNum());
}
state->setFillColor(&color);
out->updateFillColor(state);
......@@ -869,8 +917,9 @@ void Gfx::opSetStrokeCMYKColor(Object args[], int numArgs) {
state->setStrokePattern(NULL);
state->setStrokeColorSpace(new GfxDeviceCMYKColorSpace());
out->updateStrokeColorSpace(state);
for (i = 0; i < 4; ++i) {
color.c[i] = args[i].getNum();
color.c[i] = dblToCol(args[i].getNum());
}
state->setStrokeColor(&color);
out->updateStrokeColor(state);
......@@ -882,8 +931,9 @@ void Gfx::opSetFillRGBColor(Object args[], int numArgs) {
state->setFillPattern(NULL);
state->setFillColorSpace(new GfxDeviceRGBColorSpace());
out->updateFillColorSpace(state);
for (i = 0; i < 3; ++i) {
color.c[i] = args[i].getNum();
color.c[i] = dblToCol(args[i].getNum());
}
state->setFillColor(&color);
out->updateFillColor(state);
......@@ -895,8 +945,9 @@ void Gfx::opSetStrokeRGBColor(Object args[], int numArgs) {
state->setStrokePattern(NULL);
state->setStrokeColorSpace(new GfxDeviceRGBColorSpace());
out->updateStrokeColorSpace(state);
for (i = 0; i < 3; ++i) {
color.c[i] = args[i].getNum();
color.c[i] = dblToCol(args[i].getNum());
}
state->setStrokeColor(&color);
out->updateStrokeColor(state);
......@@ -918,6 +969,7 @@ void Gfx::opSetFillColorSpace(Object args[], int numArgs) {
obj.free();
if (colorSpace) {
state->setFillColorSpace(colorSpace);
out->updateFillColorSpace(state);
} else {
error(getPos(), "Bad color space (fill)");
}
......@@ -944,6 +996,7 @@ void Gfx::opSetStrokeColorSpace(Object args[], int numArgs) {
obj.free();
if (colorSpace) {
state->setStrokeColorSpace(colorSpace);
out->updateStrokeColorSpace(state);
} else {
error(getPos(), "Bad color space (stroke)");
}
......@@ -960,7 +1013,7 @@ void Gfx::opSetFillColor(Object args[], int numArgs) {
state->setFillPattern(NULL);
for (i = 0; i < numArgs; ++i) {
color.c[i] = args[i].getNum();
color.c[i] = dblToCol(args[i].getNum());
}
state->setFillColor(&color);
out->updateFillColor(state);
......@@ -972,7 +1025,7 @@ void Gfx::opSetStrokeColor(Object args[], int numArgs) {
state->setStrokePattern(NULL);
for (i = 0; i < numArgs; ++i) {
color.c[i] = args[i].getNum();
color.c[i] = dblToCol(args[i].getNum());
}
state->setStrokeColor(&color);
out->updateStrokeColor(state);
......@@ -987,7 +1040,7 @@ void Gfx::opSetFillColorN(Object args[], int numArgs) {
if (numArgs > 1) {
for (i = 0; i < numArgs && i < 4; ++i) {
if (args[i].isNum()) {
color.c[i] = args[i].getNum();
color.c[i] = dblToCol(args[i].getNum());
}
}
state->setFillColor(&color);
......@@ -1002,7 +1055,7 @@ void Gfx::opSetFillColorN(Object args[], int numArgs) {
state->setFillPattern(NULL);
for (i = 0; i < numArgs && i < 4; ++i) {
if (args[i].isNum()) {
color.c[i] = args[i].getNum();
color.c[i] = dblToCol(args[i].getNum());
}
}
state->setFillColor(&color);
......@@ -1019,7 +1072,7 @@ void Gfx::opSetStrokeColorN(Object args[], int numArgs) {
if (numArgs > 1) {
for (i = 0; i < numArgs && i < 4; ++i) {
if (args[i].isNum()) {
color.c[i] = args[i].getNum();
color.c[i] = dblToCol(args[i].getNum());
}
}
state->setStrokeColor(&color);
......@@ -1034,7 +1087,7 @@ void Gfx::opSetStrokeColorN(Object args[], int numArgs) {
state->setStrokePattern(NULL);
for (i = 0; i < numArgs && i < 4; ++i) {
if (args[i].isNum()) {
color.c[i] = args[i].getNum();
color.c[i] = dblToCol(args[i].getNum());
}
}
state->setStrokeColor(&color);
......@@ -1324,7 +1377,7 @@ void Gfx::doTilingPatternFill(GfxTilingPattern *tPat, GBool eoFill) {
m[4] = m1[4] * ictm[0] + m1[5] * ictm[2] + ictm[4];
m[5] = m1[4] * ictm[1] + m1[5] * ictm[3] + ictm[5];
// construct a (base space) -> (pattern space) transform matrix
// construct a (device space) -> (pattern space) transform matrix
det = 1 / (m1[0] * m1[3] - m1[1] * m1[2]);
imb[0] = m1[3] * det;
imb[1] = -m1[1] * det;
......@@ -1342,11 +1395,15 @@ void Gfx::doTilingPatternFill(GfxTilingPattern *tPat, GBool eoFill) {
// Adobe's behavior
if (tPat->getPaintType() == 2 && (cs = patCS->getUnder())) {
state->setFillColorSpace(cs->copy());
out->updateFillColorSpace(state);
state->setStrokeColorSpace(cs->copy());
out->updateStrokeColorSpace(state);
state->setStrokeColor(state->getFillColor());
} else {
state->setFillColorSpace(new GfxDeviceGrayColorSpace());
out->updateFillColorSpace(state);
state->setStrokeColorSpace(new GfxDeviceGrayColorSpace());
out->updateStrokeColorSpace(state);
}
state->setFillPattern(NULL);
out->updateFillColor(state);
......@@ -1364,8 +1421,13 @@ void Gfx::doTilingPatternFill(GfxTilingPattern *tPat, GBool eoFill) {
}
state->clearPath();
// transform clip region bbox to pattern space
// get the clip region, check for empty
state->getClipBBox(&cxMin, &cyMin, &cxMax, &cyMax);
if (cxMin > cxMax || cyMin > cyMax) {
goto err;
}
// transform clip region bbox to pattern space
xMin = xMax = cxMin * imb[0] + cyMin * imb[2] + imb[4];
yMin = yMax = cxMin * imb[1] + cyMin * imb[3] + imb[5];
x1 = cxMin * imb[0] + cyMax * imb[2] + imb[4];
......@@ -1417,6 +1479,14 @@ void Gfx::doTilingPatternFill(GfxTilingPattern *tPat, GBool eoFill) {
for (i = 0; i < 4; ++i) {
m1[i] = m[i];
}
if (out->useTilingPatternFill()) {
m1[4] = m[4];
m1[5] = m[5];
out->tilingPatternFill(state, tPat->getContentStream(),
tPat->getPaintType(), tPat->getResDict(),
m1, tPat->getBBox(),
xi0, yi0, xi1, yi1, xstep, ystep);
} else {
for (yi = yi0; yi < yi1; ++yi) {
for (xi = xi0; xi < xi1; ++xi) {
x = xi * xstep;
......@@ -1427,8 +1497,10 @@ void Gfx::doTilingPatternFill(GfxTilingPattern *tPat, GBool eoFill) {
m1, tPat->getBBox());
}
}
}
// restore graphics state
err:
restoreState();
state->setPath(savedPath);
}
......@@ -1457,7 +1529,7 @@ void Gfx::doShadingPatternFill(GfxShadingPattern *sPat, GBool eoFill) {
state->closePath();
state->clip();
out->clip(state);
state->clearPath();
state->setPath(savedPath->copy());
}
// clip to current path
......@@ -1467,6 +1539,17 @@ void Gfx::doShadingPatternFill(GfxShadingPattern *sPat, GBool eoFill) {
} else {
out->clip(state);
}
// set the color space
state->setFillColorSpace(shading->getColorSpace()->copy());
out->updateFillColorSpace(state);
// background color fill
if (shading->getHasBackground()) {
state->setFillColor(shading->getBackground());
out->updateFillColor(state);
out->fill(state);
}
state->clearPath();
// construct a (pattern space) -> (current space) transform matrix
......@@ -1500,9 +1583,6 @@ void Gfx::doShadingPatternFill(GfxShadingPattern *sPat, GBool eoFill) {
state->concatCTM(m[0], m[1], m[2], m[3], m[4], m[5]);
out->updateCTM(state, m[0], m[1], m[2], m[3], m[4], m[5]);
// set the color space
state->setFillColorSpace(shading->getColorSpace()->copy());
// do shading type-specific operations
switch (shading->getType()) {
case 1:
......@@ -1514,6 +1594,14 @@ void Gfx::doShadingPatternFill(GfxShadingPattern *sPat, GBool eoFill) {
case 3:
doRadialShFill((GfxRadialShading *)shading);
break;
case 4:
case 5:
doGouraudTriangleShFill((GfxGouraudTriangleShading *)shading);
break;
case 6:
case 7:
doPatchMeshShFill((GfxPatchMeshShading *)shading);
break;
}
// restore graphics state
......@@ -1549,6 +1637,7 @@ void Gfx::opShFill(Object args[], int numArgs) {
// set the color space
state->setFillColorSpace(shading->getColorSpace()->copy());
out->updateFillColorSpace(state);
// do shading type-specific operations
switch (shading->getType()) {
......@@ -1561,6 +1650,14 @@ void Gfx::opShFill(Object args[], int numArgs) {
case 3:
doRadialShFill((GfxRadialShading *)shading);
break;
case 4:
case 5:
doGouraudTriangleShFill((GfxGouraudTriangleShading *)shading);
break;
case 6:
case 7:
doPatchMeshShFill((GfxPatchMeshShading *)shading);
break;
}
// restore graphics state
......@@ -1574,12 +1671,16 @@ void Gfx::doFunctionShFill(GfxFunctionShading *shading) {
double x0, y0, x1, y1;
GfxColor colors[4];
if (out->useShadedFills()) {
out->functionShadedFill(state, shading);
} else {
shading->getDomain(&x0, &y0, &x1, &y1);
shading->getColor(x0, y0, &colors[0]);
shading->getColor(x0, y1, &colors[1]);
shading->getColor(x1, y0, &colors[2]);
shading->getColor(x1, y1, &colors[3]);
doFunctionShFill1(shading, x0, y0, x1, y1, colors, 0);
}
}
void Gfx::doFunctionShFill1(GfxFunctionShading *shading,
......@@ -1599,7 +1700,7 @@ void Gfx::doFunctionShFill1(GfxFunctionShading *shading,
// compare the four corner colors
for (i = 0; i < 4; ++i) {
for (j = 0; j < nComps; ++j) {
if (fabs(colors[i].c[j] - colors[(i+1)&3].c[j]) > functionColorDelta) {
if (abs(colors[i].c[j] - colors[(i+1)&3].c[j]) > functionColorDelta) {
break;
}
}
......@@ -1694,6 +1795,7 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
double xMin, yMin, xMax, yMax;
double x0, y0, x1, y1;
double dx, dy, mul;
GBool dxZero, dyZero;
double tMin, tMax, t, tx, ty;
double s[4], sMin, sMax, tmp;
double ux0, uy0, ux1, uy1, vx0, vy0, vx1, vy1;
......@@ -1704,6 +1806,12 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
int nComps;
int i, j, k, kk;
if (out->useShadedFills()) {
out->axialShadedFill(state, shading);
} else {
// get the clip region bbox
state->getUserClipBBox(&xMin, &yMin, &xMax, &yMax);
......@@ -1712,6 +1820,8 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
shading->getCoords(&x0, &y0, &x1, &y1);
dx = x1 - x0;
dy = y1 - y0;
dxZero = fabs(dx) < 0.001;
dyZero = fabs(dy) < 0.001;
mul = 1 / (dx * dx + dy * dy);
tMin = tMax = ((xMin - x0