~matttbe/ubuntu/raring/poppler/lp1072129

« back to all changes in this revision

Viewing changes to splash/Splash.cc

  • Committer: Package Import Robot
  • Author(s): Sebastien Bacher
  • Date: 2011-12-05 17:23:02 UTC
  • mfrom: (1.7.1)
  • Revision ID: package-import@ubuntu.com-20111205172302-tmhrk7s9hikjsa79
Tags: 0.18.2-0ubuntu1
* New upstream version, bugs fixed in the new version (lp: #869850):
  - lines and graphics wrongly rendered (lp: #603929) (lp: #780169)
  - rendering issues on some documents (lp: #784154)
  - some pages are displayed blank (lp: #817626)
* debian/control, debian/rules:
  - updated for the libpoppler and libpoppler-glib soname changes
* drop patches included in the new version
* debian/libpoppler-glib-dev.install:
  - drop deprecated test-poppler-glib
* debian/rules: 
  - drop deprecated qt3 and abiword configure options

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
// All changes made under the Poppler project to this file are licensed
12
12
// under GPL version 2 or later
13
13
//
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>
18
19
//
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
31
32
#include <string.h>
32
33
#include <limits.h>
33
34
#include <assert.h>
 
35
#include <math.h>
34
36
#include "goo/gmem.h"
35
37
#include "goo/GooLikely.h"
36
38
#include "poppler/Error.h"
102
104
 
103
105
  // non-isolated group correction
104
106
  int nonIsolatedGroup;
 
107
 
 
108
  // stroke / fill operation and pattern for calculate overprint
 
109
  GBool stroke;
 
110
  SplashPattern *overprintPattern;
105
111
};
106
112
 
107
113
SplashPipeResultColorCtrl Splash::pipeResultColorNoAlphaBlend[] = {
187
193
inline void Splash::pipeInit(SplashPipe *pipe, int x, int y,
188
194
                             SplashPattern *pattern, SplashColorPtr cSrc,
189
195
                             SplashCoord aInput, GBool usesShape,
190
 
                             GBool nonIsolatedGroup) {
 
196
                             GBool nonIsolatedGroup, SplashPattern *opPattern, GBool strokeA) {
191
197
  pipeSetXY(pipe, x, y);
192
198
  pipe->pattern = NULL;
193
199
 
238
244
  } else {
239
245
    pipe->nonIsolatedGroup = 0;
240
246
  }
 
247
  pipe->stroke = strokeA;
 
248
  pipe->overprintPattern = opPattern;
241
249
}
242
250
 
243
251
inline void Splash::pipeRun(SplashPipe *pipe) {
253
261
  // dynamic pattern
254
262
  if (pipe->pattern) {
255
263
    if (!pipe->pattern->getColor(pipe->x, pipe->y, pipe->cSrcVal)) {
256
 
      switch (bitmap->mode) {
257
 
        case splashModeMono1:
258
 
          if (!(pipe->destColorMask >>= 1)) 
259
 
            ++pipe->destColorPtr;
260
 
        break;
261
 
        case splashModeMono8:
262
 
          ++pipe->destColorPtr;
263
 
        break;
264
 
        case splashModeBGR8:
265
 
        case splashModeRGB8:
266
 
          pipe->destColorPtr += 3;
267
 
        break;
268
 
        case splashModeXBGR8:
269
 
#if SPLASH_CMYK
270
 
        case splashModeCMYK8:
271
 
#endif
272
 
          pipe->destColorPtr += 4;
273
 
        break;
274
 
      }
275
 
      if (pipe->destAlphaPtr) {
276
 
        ++pipe->destAlphaPtr;
277
 
      }
278
 
      ++pipe->x;
279
 
      return;
 
264
                pipeIncX(pipe);
 
265
                return;
280
266
    }
281
267
  }
282
268
 
318
304
      break;
319
305
#if SPLASH_CMYK
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))) {
 
310
        SplashColor cResult;
 
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];
 
320
      } else {
 
321
        *pipe->destColorPtr++ = pipe->cSrc[0];
 
322
        *pipe->destColorPtr++ = pipe->cSrc[1];
 
323
        *pipe->destColorPtr++ = pipe->cSrc[2];
 
324
        *pipe->destColorPtr++ = pipe->cSrc[3];
 
325
      }
325
326
      break;
326
327
#endif
327
328
    }
456
457
        cResult2 = 0;
457
458
        cResult3 = 0;
458
459
      } else {
459
 
        cResult0 = (Guchar)(((alpha2 - aSrc) * cDest[0] +
 
460
        if (pipe->overprintPattern != NULL &&
 
461
           ((pipe->stroke && state->strokeOverprint) ||
 
462
           (!pipe->stroke && state->fillOverprint))) {
 
463
          SplashColor cResult;
 
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];
 
469
        } else {
 
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);
 
478
        }
467
479
      }
468
480
      break;
469
481
#endif
1011
1023
  state->fillAlpha = alpha;
1012
1024
}
1013
1025
 
 
1026
void Splash::setFillOverprint(GBool fop) {
 
1027
  state->fillOverprint = fop;
 
1028
}
 
1029
 
 
1030
void Splash::setStrokeOverprint(GBool gop) {
 
1031
  state->strokeOverprint = gop;
 
1032
}
 
1033
 
 
1034
void Splash::setOverprintMode(int opm) {
 
1035
  state->overprintMode = opm;
 
1036
}
 
1037
 
1014
1038
void Splash::setLineWidth(SplashCoord lineWidth) {
1015
1039
  state->lineWidth = lineWidth;
1016
1040
}
1263
1287
  xPath = new SplashXPath(path, state->matrix, state->flatness, gFalse);
1264
1288
 
1265
1289
  pipeInit(&pipe, 0, 0, state->strokePattern, NULL, state->strokeAlpha,
1266
 
           gFalse, gFalse);
 
1290
           gFalse, gFalse, state->strokePattern, gTrue);
1267
1291
 
1268
1292
  for (i = 0, seg = xPath->segs; i < xPath->length; ++i, ++seg) {
1269
1293
 
1573
1597
    }
1574
1598
    i = j + 1;
1575
1599
  }
 
1600
  
 
1601
  if (dPath->length == 0) {
 
1602
    GBool allSame = gTrue;
 
1603
    for (int i = 0; allSame && i < path->length - 1; ++i) {
 
1604
      allSame = path->pts[i].x == path->pts[i + 1].x && path->pts[i].y == path->pts[i + 1].y;
 
1605
    }
 
1606
    if (allSame) {
 
1607
      x0 = path->pts[0].x;
 
1608
      y0 = path->pts[0].y;
 
1609
      dPath->moveTo(x0, y0);
 
1610
      dPath->lineTo(x0, y0);
 
1611
    }
 
1612
  }
1576
1613
 
1577
1614
  return dPath;
1578
1615
}
1623
1660
      yMaxI = state->clip->getYMaxI();
1624
1661
    }
1625
1662
 
1626
 
    pipeInit(&pipe, 0, yMinI, pattern, NULL, alpha, vectorAntialias, gFalse);
 
1663
    pipeInit(&pipe, 0, yMinI, pattern, NULL, alpha, vectorAntialias, gFalse, pattern);
1627
1664
 
1628
1665
    // draw the spans
1629
1666
    if (vectorAntialias) {
1693
1730
 
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);
1697
1734
 
1698
1735
    // draw the spans
1699
1736
    for (y = yMinI; y <= yMaxI; ++y) {
1780
1817
  int yStart = y0 - glyph->y;
1781
1818
  int xxLimit = glyph->w;
1782
1819
  int yyLimit = glyph->h;
 
1820
  int xShift = 0;
1783
1821
 
1784
1822
  if (yStart < 0)
1785
1823
  {
1786
 
    p += glyph->w * -yStart; // move p to the beginning of the first painted row
 
1824
    p += (glyph->aa ? glyph->w : splashCeil(glyph->w / 8.0)) * -yStart; // move p to the beginning of the first painted row
1787
1825
    yyLimit += yStart;
1788
1826
    yStart = 0;
1789
1827
  }
1790
1828
 
1791
1829
  if (xStart < 0)
1792
1830
  {
1793
 
    p += -xStart; // move p to the first painted pixel
 
1831
    if (glyph->aa) {
 
1832
      p += -xStart;
 
1833
    } else {
 
1834
      p += (-xStart) / 8;
 
1835
      xShift = (-xStart) % 8;
 
1836
    }
1794
1837
    xxLimit += xStart;
1795
1838
    xStart = 0;
1796
1839
  }
1801
1844
  if (noClip) {
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);
1822
1865
 
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) {
1828
 
          alpha0 = p[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);
1843
1886
  } else {
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);
1868
1911
 
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) {
1874
 
          alpha0 = p[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) {
2045
2088
 
2046
2089
  // initialize the pixel pipe
2047
2090
  pipeInit(&pipe, 0, 0, state->fillPattern, NULL, state->fillAlpha,
2048
 
           gTrue, gFalse);
 
2091
           gTrue, gFalse, state->fillPattern);
2049
2092
  if (vectorAntialias) {
2050
2093
    drawAAPixelInit();
2051
2094
  }
2180
2223
 
2181
2224
SplashError Splash::drawImage(SplashImageSource src, void *srcData,
2182
2225
                              SplashColorMode srcMode, GBool srcAlpha,
2183
 
                              int w, int h, SplashCoord *mat) {
 
2226
                              int w, int h, SplashCoord *mat, SplashPattern *opImagePattern) {
2184
2227
  SplashPipe pipe;
2185
2228
  GBool ok, rot;
2186
2229
  SplashCoord xScale, yScale, xShear, yShear, yShear1;
2359
2402
  // initialize the pixel pipe
2360
2403
  pipeInit(&pipe, 0, 0, NULL, pix, state->fillAlpha,
2361
2404
           srcAlpha || (vectorAntialias && clipRes != splashClipAllInside),
2362
 
           gFalse);
 
2405
           gFalse, opImagePattern);
2363
2406
  if (vectorAntialias) {
2364
2407
    drawAAPixelInit();
2365
2408
  }
2395
2438
 
2396
2439
      // loop-invariant constants
2397
2440
      k1 = splashRound(xShear * ySign * y);
2398
 
  
 
2441
 
2399
2442
      // clipping test
2400
2443
      if (clipRes != splashClipAllInside &&
2401
2444
          !rot &&
3097
3140
  Guchar color3;
3098
3141
#endif
3099
3142
  int x, y, mask;
3100
 
  
 
3143
 
3101
3144
  if (unlikely(bitmap->alpha == NULL)) {
3102
3145
    error(-1, "bitmap->alpha is NULL in Splash::compositeBackground");
3103
3146
    return;
3241
3284
 
3242
3285
  int scanLineOff = 0;
3243
3286
  int bitmapOff = 0;
3244
 
  int scanLimitR = 0, scanLimitL = 0, Yt = 0;
 
3287
  int scanLimitR = 0, scanLimitL = 0;
3245
3288
 
3246
3289
  int bitmapWidth = bitmap->getWidth();
3247
3290
  SplashClip* clip = getClip();
3279
3322
  SplashPipe pipe;
3280
3323
  SplashColor cSrcVal;
3281
3324
 
3282
 
  pipeInit(&pipe, 0, 0, NULL, cSrcVal, state->strokeAlpha, gFalse, gFalse);
 
3325
  pipeInit(&pipe, 0, 0, NULL, cSrcVal, state->strokeAlpha, gFalse, gFalse, NULL, gTrue);
3283
3326
 
3284
3327
  if (vectorAntialias) {
3285
 
    if (aaBuf == NULL) 
 
3328
    if (aaBuf == NULL)
3286
3329
      return gFalse; // fall back to old behaviour
3287
3330
    drawAAPixelInit();
3288
3331
  }
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];
3333
3376
        xdbl[m] = xt;
3334
3377
        ydbl[m] = yt;
3335
3378
        // we operate on scanlines which are integer offsets into the
3421
3464
      scanColorMapR[0] = (color[scanEdgeR[1]] - color[scanEdgeR[0]]) / (y[scanEdgeR[1]] - y[scanEdgeR[0]]);
3422
3465
      scanColorMapR[1] = color[scanEdgeR[0]] - y[scanEdgeR[0]] * scanColorMapR[0];
3423
3466
 
3424
 
      Yt = y[2];
3425
3467
      hasFurtherSegment = (y[1] < y[2]);
3426
3468
      scanLineOff = y[0] * rowSize;
3427
3469
 
3533
3575
 
3534
3576
SplashError Splash::blitTransparent(SplashBitmap *src, int xSrc, int ySrc,
3535
3577
                                    int xDest, int yDest, int w, int h) {
3536
 
  SplashColor pixel;
3537
3578
  SplashColorPtr p, sp;
3538
3579
  Guchar *q;
3539
3580
  int x, y, mask;
3546
3587
  case splashModeMono1:
3547
3588
    for (y = 0; y < h; ++y) {
3548
3589
      p = &bitmap->data[(yDest + y) * bitmap->rowSize + (xDest >> 3)];
 
3590
      sp = &src->data[(ySrc + y) * bitmap->rowSize + (xSrc >> 3)];
3549
3591
      mask = 0x80 >> (xDest & 7);
3550
3592
      for (x = 0; x < w; ++x) {
3551
 
        src->getPixel(xSrc + x, ySrc + y, pixel);
3552
 
        if (pixel[0]) {
 
3593
        if (sp[0] & (0x80 >> (x & 7))) {
3553
3594
          *p |= mask;
3554
3595
        } else {
3555
3596
          *p &= ~mask;
3557
3598
        if (!(mask >>= 1)) {
3558
3599
          mask = 0x80;
3559
3600
          ++p;
 
3601
          ++sp;
3560
3602
        }
3561
3603
      }
3562
3604
    }
3564
3606
  case splashModeMono8:
3565
3607
    for (y = 0; y < h; ++y) {
3566
3608
      p = &bitmap->data[(yDest + y) * bitmap->rowSize + xDest];
 
3609
      sp = &src->data[(ySrc + y) * bitmap->rowSize + xSrc];
3567
3610
      for (x = 0; x < w; ++x) {
3568
 
        src->getPixel(xSrc + x, ySrc + y, pixel);
3569
 
        *p++ = pixel[0];
 
3611
        *p++ = *sp++;
3570
3612
      }
3571
3613
    }
3572
3614
    break;
3599
3641
  case splashModeCMYK8:
3600
3642
    for (y = 0; y < h; ++y) {
3601
3643
      p = &bitmap->data[(yDest + y) * bitmap->rowSize + 4 * xDest];
 
3644
      sp = &src->data[(ySrc + y) * bitmap->rowSize + 4 * xSrc];
3602
3645
      for (x = 0; x < w; ++x) {
3603
 
        src->getPixel(xSrc + x, ySrc + y, pixel);
3604
 
        *p++ = pixel[0];
3605
 
        *p++ = pixel[1];
3606
 
        *p++ = pixel[2];
3607
 
        *p++ = pixel[3];
 
3646
        *p++ = *sp++;
 
3647
        *p++ = *sp++;
 
3648
        *p++ = *sp++;
 
3649
        *p++ = *sp++;
3608
3650
      }
3609
3651
    }
3610
3652
    break;
3950
3992
  int xMinI, yMinI, xMaxI, yMaxI, x0, x1, y;
3951
3993
  SplashClipResult clipRes;
3952
3994
 
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;
3955
3997
  }
3956
3998
  if (path->length == 0) {
3957
3999
    return splashErrEmptyPath;
3958
4000
  }
3959
4001
  xPath = new SplashXPath(path, state->matrix, state->flatness, gTrue);
3960
 
  xPath->aaScale();
 
4002
  if (vectorAntialias) {
 
4003
    xPath->aaScale();
 
4004
  }
3961
4005
  xPath->sort();
3962
4006
  scanner = new SplashXPathScanner(xPath, gFalse);
3963
4007
 
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);
 
4011
  } else {
 
4012
    scanner->getBBox(&xMinI, &yMinI, &xMaxI, &yMaxI);
 
4013
  }
3966
4014
 
3967
4015
  // check clipping
3968
4016
  if ((clipRes = state->clip->testRect(xMinI, yMinI, xMaxI, yMaxI)) != splashClipAllOutside) {
3974
4022
      yMaxI = state->clip->getYMaxI();
3975
4023
    }
3976
4024
 
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);
3978
4026
 
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);
3984
 
      }
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);
 
4033
        }
 
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();
 
4044
          if (x0 & 1) {
 
4045
           c1 = (*p0 & 0x0f); c2 =(*p1 & 0x0f); c3 = (*p2 & 0x0f) ; c4 = (*p3 & 0x0f);
 
4046
          } else {
 
4047
            c1 = (*p0 >> 4); c2 = (*p1 >> 4); c3 = (*p2 >> 4); c4 = (*p3 >> 4);
 
4048
          }
 
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) )
 
4052
          {
 
4053
            Guchar shapeCorrection = (x0 & 1) ? 0x0f : 0xf0;
 
4054
            *p0 |= shapeCorrection;
 
4055
            *p1 |= shapeCorrection;
 
4056
            *p2 |= shapeCorrection;
 
4057
            *p3 |= shapeCorrection;
 
4058
          }
 
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();
 
4065
          if (x1 & 1) {
 
4066
            c1 = (*p0 & 0x0f); c2 =(*p1 & 0x0f); c3 = (*p2 & 0x0f) ; c4 = (*p3 & 0x0f);
 
4067
          } else {
 
4068
            c1 = (*p0 >> 4); c2 = (*p1 >> 4); c3 = (*p2 >> 4); c4 = (*p3 >> 4);
 
4069
          }
 
4070
 
 
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) )
 
4074
          {
 
4075
            Guchar shapeCorrection = (x1 & 1) ? 0x0f : 0xf0;
 
4076
            *p0 |= shapeCorrection;
 
4077
            *p1 |= shapeCorrection;
 
4078
            *p2 |= shapeCorrection;
 
4079
            *p3 |= shapeCorrection;
 
4080
          }
 
4081
        }
 
4082
#endif
 
4083
        drawAALine(&pipe, x0, x1, y);
 
4084
      }
 
4085
    } else {
 
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);
 
4091
          } else {
 
4092
            // limit the x range
 
4093
            if (x0 < state->clip->getXMinI()) {
 
4094
              x0 = state->clip->getXMinI();
 
4095
            }
 
4096
            if (x1 > state->clip->getXMaxI()) {
 
4097
              x1 = state->clip->getXMaxI();
 
4098
            }
 
4099
            clipRes2 = state->clip->testSpan(x0, x1, y);
 
4100
            drawSpan(&pipe, x0, x1, y, clipRes2 == splashClipAllInside);
 
4101
          }
 
4102
        }
 
4103
      }
3986
4104
    }
3987
4105
  }
3988
4106
  opClipRes = clipRes;