11
11
// All changes made under the Poppler project to this file are licensed
12
12
// under GPL version 2 or later
14
// Copyright (C) 2005-2010 Albert Astals Cid <aacid@kde.org>
14
// Copyright (C) 2005-2011 Albert Astals Cid <aacid@kde.org>
15
15
// Copyright (C) 2005 Marco Pesenti Gritti <mpg@redhat.com>
16
// Copyright (C) 2010 Thomas Freitag <Thomas.Freitag@alfa.de>
16
// Copyright (C) 2010, 2011 Thomas Freitag <Thomas.Freitag@alfa.de>
17
17
// Copyright (C) 2010 Christian Feuers�nger <cfeuersaenger@googlemail.com>
18
// Copyright (C) 2011 William Bader <williambader@hotmail.com>
19
20
// To see a description of the changes please see the Changelog file that
20
21
// came with your tarball or type make ChangeLog if you are building from git
320
306
case splashModeCMYK8:
321
*pipe->destColorPtr++ = pipe->cSrc[0];
322
*pipe->destColorPtr++ = pipe->cSrc[1];
323
*pipe->destColorPtr++ = pipe->cSrc[2];
324
*pipe->destColorPtr++ = pipe->cSrc[3];
307
if (pipe->overprintPattern != NULL &&
308
((pipe->stroke && state->strokeOverprint) ||
309
(!pipe->stroke && state->fillOverprint))) {
311
cDest[0] = pipe->destColorPtr[0];
312
cDest[1] = pipe->destColorPtr[1];
313
cDest[2] = pipe->destColorPtr[2];
314
cDest[3] = pipe->destColorPtr[3];
315
pipe->overprintPattern->overprint(state->overprintMode == 1, pipe->aSrc, pipe->cSrc, 255, cDest, cResult);
316
*pipe->destColorPtr++ = cResult[0];
317
*pipe->destColorPtr++ = cResult[1];
318
*pipe->destColorPtr++ = cResult[2];
319
*pipe->destColorPtr++ = cResult[3];
321
*pipe->destColorPtr++ = pipe->cSrc[0];
322
*pipe->destColorPtr++ = pipe->cSrc[1];
323
*pipe->destColorPtr++ = pipe->cSrc[2];
324
*pipe->destColorPtr++ = pipe->cSrc[3];
459
cResult0 = (Guchar)(((alpha2 - aSrc) * cDest[0] +
460
if (pipe->overprintPattern != NULL &&
461
((pipe->stroke && state->strokeOverprint) ||
462
(!pipe->stroke && state->fillOverprint))) {
464
pipe->overprintPattern->overprint(state->overprintMode == 1, aSrc, pipe->cSrc, alpha2, cDest, cResult);
465
cResult0 = cResult[0];
466
cResult1 = cResult[1];
467
cResult2 = cResult[2];
468
cResult3 = cResult[3];
470
cResult0 = (Guchar)(((alpha2 - aSrc) * cDest[0] +
460
471
aSrc * pipe->cSrc[0]) / alpha2);
461
cResult1 = (Guchar)(((alpha2 - aSrc) * cDest[1] +
472
cResult1 = (Guchar)(((alpha2 - aSrc) * cDest[1] +
462
473
aSrc * pipe->cSrc[1]) / alpha2);
463
cResult2 = (Guchar)(((alpha2 - aSrc) * cDest[2] +
474
cResult2 = (Guchar)(((alpha2 - aSrc) * cDest[2] +
464
475
aSrc * pipe->cSrc[2]) / alpha2);
465
cResult3 = (Guchar)(((alpha2 - aSrc) * cDest[3] +
476
cResult3 = (Guchar)(((alpha2 - aSrc) * cDest[3] +
466
477
aSrc * pipe->cSrc[3]) / alpha2);
1694
1731
origBlendFunc = state->blendFunc;
1695
1732
state->blendFunc = &blendXor;
1696
pipeInit(&pipe, 0, yMinI, state->fillPattern, NULL, 1, gFalse, gFalse);
1733
pipeInit(&pipe, 0, yMinI, state->fillPattern, NULL, 1, gFalse, gFalse, state->fillPattern);
1698
1735
// draw the spans
1699
1736
for (y = yMinI; y <= yMaxI; ++y) {
1802
1845
if (glyph->aa) {
1803
1846
pipeInit(&pipe, xStart, yStart,
1804
state->fillPattern, NULL, state->fillAlpha, gTrue, gFalse);
1847
state->fillPattern, NULL, state->fillAlpha, gTrue, gFalse, state->fillPattern);
1805
1848
for (yy = 0, y1 = yStart; yy < yyLimit; ++yy, ++y1) {
1806
1849
pipeSetXY(&pipe, xStart, y1);
1807
1850
for (xx = 0, x1 = xStart; xx < xxLimit; ++xx, ++x1) {
1821
1864
const int widthEight = splashCeil(glyph->w / 8.0);
1823
1866
pipeInit(&pipe, xStart, yStart,
1824
state->fillPattern, NULL, state->fillAlpha, gFalse, gFalse);
1867
state->fillPattern, NULL, state->fillAlpha, gFalse, gFalse, state->fillPattern);
1825
1868
for (yy = 0, y1 = yStart; yy < yyLimit; ++yy, ++y1) {
1826
1869
pipeSetXY(&pipe, xStart, y1);
1827
1870
for (xx = 0, x1 = xStart; xx < xxLimit; xx += 8) {
1871
alpha0 = (xShift > 0 ? (p[xx / 8] << xShift) | (p[xx / 8 + 1] >> (8 - xShift)) : p[xx / 8]);
1829
1872
for (xx1 = 0; xx1 < 8 && xx + xx1 < xxLimit; ++xx1, ++x1) {
1830
1873
if (alpha0 & 0x80) {
1831
1874
pipeRun(&pipe);
1844
1887
if (glyph->aa) {
1845
1888
pipeInit(&pipe, xStart, yStart,
1846
state->fillPattern, NULL, state->fillAlpha, gTrue, gFalse);
1889
state->fillPattern, NULL, state->fillAlpha, gTrue, gFalse, state->fillPattern);
1847
1890
for (yy = 0, y1 = yStart; yy < yyLimit; ++yy, ++y1) {
1848
1891
pipeSetXY(&pipe, xStart, y1);
1849
1892
for (xx = 0, x1 = xStart; xx < xxLimit; ++xx, ++x1) {
1867
1910
const int widthEight = splashCeil(glyph->w / 8.0);
1869
1912
pipeInit(&pipe, xStart, yStart,
1870
state->fillPattern, NULL, state->fillAlpha, gFalse, gFalse);
1913
state->fillPattern, NULL, state->fillAlpha, gFalse, gFalse, state->fillPattern);
1871
1914
for (yy = 0, y1 = yStart; yy < yyLimit; ++yy, ++y1) {
1872
1915
pipeSetXY(&pipe, xStart, y1);
1873
1916
for (xx = 0, x1 = xStart; xx < xxLimit; xx += 8) {
1917
alpha0 = (xShift > 0 ? (p[xx / 8] << xShift) | (p[xx / 8 + 1] >> (8 - xShift)) : p[xx / 8]);
1875
1918
for (xx1 = 0; xx1 < 8 && xx + xx1 < xxLimit; ++xx1, ++x1) {
1876
1919
if (state->clip->test(x1, y1)) {
1877
1920
if (alpha0 & 0x80) {
3328
3371
xdbl + 1, ydbl + 1, color + 1,
3329
3372
xdbl + 2, ydbl + 2, color + 2);
3330
3373
for (int m = 0; m < 3; ++m) {
3331
xt = xdbl[m] * userToCanvasMatrix[0] + ydbl[m] * userToCanvasMatrix[2] + userToCanvasMatrix[4];
3332
yt = xdbl[m] * userToCanvasMatrix[1] + ydbl[m] * userToCanvasMatrix[3] + userToCanvasMatrix[5];
3374
xt = xdbl[m] * (double)userToCanvasMatrix[0] + ydbl[m] * (double)userToCanvasMatrix[2] + (double)userToCanvasMatrix[4];
3375
yt = xdbl[m] * (double)userToCanvasMatrix[1] + ydbl[m] * (double)userToCanvasMatrix[3] + (double)userToCanvasMatrix[5];
3335
3378
// we operate on scanlines which are integer offsets into the
3950
3992
int xMinI, yMinI, xMaxI, yMaxI, x0, x1, y;
3951
3993
SplashClipResult clipRes;
3953
if (aaBuf == NULL) { // should not happen, but to be secure
3995
if (vectorAntialias && aaBuf == NULL) { // should not happen, but to be secure
3954
3996
return splashErrGeneric;
3956
3998
if (path->length == 0) {
3957
3999
return splashErrEmptyPath;
3959
4001
xPath = new SplashXPath(path, state->matrix, state->flatness, gTrue);
4002
if (vectorAntialias) {
3962
4006
scanner = new SplashXPathScanner(xPath, gFalse);
3964
4008
// get the min and max x and y values
3965
scanner->getBBoxAA(&xMinI, &yMinI, &xMaxI, &yMaxI);
4009
if (vectorAntialias) {
4010
scanner->getBBoxAA(&xMinI, &yMinI, &xMaxI, &yMaxI);
4012
scanner->getBBox(&xMinI, &yMinI, &xMaxI, &yMaxI);
3967
4015
// check clipping
3968
4016
if ((clipRes = state->clip->testRect(xMinI, yMinI, xMaxI, yMaxI)) != splashClipAllOutside) {
3974
4022
yMaxI = state->clip->getYMaxI();
3977
pipeInit(&pipe, 0, yMinI, pattern, NULL, state->fillAlpha, vectorAntialias && !hasBBox, gFalse);
4025
pipeInit(&pipe, 0, yMinI, pattern, NULL, state->fillAlpha, vectorAntialias && !hasBBox, gFalse, pattern);
3979
4027
// draw the spans
3980
for (y = yMinI; y <= yMaxI; ++y) {
3981
scanner->renderAALine(aaBuf, &x0, &x1, y);
3982
if (clipRes != splashClipAllInside) {
3983
state->clip->clipAALine(aaBuf, &x0, &x1, y);
3985
drawAALine(&pipe, x0, x1, y);
4028
if (vectorAntialias) {
4029
for (y = yMinI; y <= yMaxI; ++y) {
4030
scanner->renderAALine(aaBuf, &x0, &x1, y);
4031
if (clipRes != splashClipAllInside) {
4032
state->clip->clipAALine(aaBuf, &x0, &x1, y);
4034
#if splashAASize == 4
4035
if (!hasBBox && y > yMinI && y < yMaxI) {
4036
// correct shape on left side if clip is
4037
// vertical through the middle of shading:
4038
Guchar *p0, *p1, *p2, *p3;
4039
Guchar c1, c2, c3, c4;
4040
p0 = aaBuf->getDataPtr() + (x0 >> 1);
4041
p1 = p0 + aaBuf->getRowSize();
4042
p2 = p1 + aaBuf->getRowSize();
4043
p3 = p2 + aaBuf->getRowSize();
4045
c1 = (*p0 & 0x0f); c2 =(*p1 & 0x0f); c3 = (*p2 & 0x0f) ; c4 = (*p3 & 0x0f);
4047
c1 = (*p0 >> 4); c2 = (*p1 >> 4); c3 = (*p2 >> 4); c4 = (*p3 >> 4);
4049
if ( (c1 & 0x03) == 0x03 && (c2 & 0x03) == 0x03 && (c3 & 0x03) == 0x03 && (c4 & 0x03) == 0x03
4050
&& c1 == c2 && c2 == c3 && c3 == c4 &&
4051
pattern->testPosition(x0 - 1, y) )
4053
Guchar shapeCorrection = (x0 & 1) ? 0x0f : 0xf0;
4054
*p0 |= shapeCorrection;
4055
*p1 |= shapeCorrection;
4056
*p2 |= shapeCorrection;
4057
*p3 |= shapeCorrection;
4059
// correct shape on right side if clip is
4060
// through the middle of shading:
4061
p0 = aaBuf->getDataPtr() + (x1 >> 1);
4062
p1 = p0 + aaBuf->getRowSize();
4063
p2 = p1 + aaBuf->getRowSize();
4064
p3 = p2 + aaBuf->getRowSize();
4066
c1 = (*p0 & 0x0f); c2 =(*p1 & 0x0f); c3 = (*p2 & 0x0f) ; c4 = (*p3 & 0x0f);
4068
c1 = (*p0 >> 4); c2 = (*p1 >> 4); c3 = (*p2 >> 4); c4 = (*p3 >> 4);
4071
if ( (c1 & 0xc) == 0x0c && (c2 & 0x0c) == 0x0c && (c3 & 0x0c) == 0x0c && (c4 & 0x0c) == 0x0c
4072
&& c1 == c2 && c2 == c3 && c3 == c4 &&
4073
pattern->testPosition(x1 + 1, y) )
4075
Guchar shapeCorrection = (x1 & 1) ? 0x0f : 0xf0;
4076
*p0 |= shapeCorrection;
4077
*p1 |= shapeCorrection;
4078
*p2 |= shapeCorrection;
4079
*p3 |= shapeCorrection;
4083
drawAALine(&pipe, x0, x1, y);
4086
SplashClipResult clipRes2;
4087
for (y = yMinI; y <= yMaxI; ++y) {
4088
while (scanner->getNextSpan(y, &x0, &x1)) {
4089
if (clipRes == splashClipAllInside) {
4090
drawSpan(&pipe, x0, x1, y, gTrue);
4092
// limit the x range
4093
if (x0 < state->clip->getXMinI()) {
4094
x0 = state->clip->getXMinI();
4096
if (x1 > state->clip->getXMaxI()) {
4097
x1 = state->clip->getXMaxI();
4099
clipRes2 = state->clip->testSpan(x0, x1, y);
4100
drawSpan(&pipe, x0, x1, y, clipRes2 == splashClipAllInside);
3988
4106
opClipRes = clipRes;