Bug 32349 - Radial shading does not render correctly
Summary: Radial shading does not render correctly
Status: RESOLVED FIXED
Alias: None
Product: poppler
Classification: Unclassified
Component: general (show other bugs)
Version: unspecified
Hardware: Other All
: medium normal
Assignee: poppler-bugs
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-12-13 07:17 UTC by Andrea Canciani
Modified: 2010-12-29 09:50 UTC (History)
1 user (show)

See Also:
i915 platform:
i915 features:


Attachments
PDF file to reproduce the bug (2.56 KB, application/pdf)
2010-12-13 07:17 UTC, Andrea Canciani
Details
should solve this issue (14.75 KB, patch)
2010-12-17 05:08 UTC, Thomas Freitag
Details | Splinter Review
PDF with multiple radial tests (258.48 KB, application/pdf)
2010-12-29 09:50 UTC, Andrea Canciani
Details

Description Andrea Canciani 2010-12-13 07:17:40 UTC
Created attachment 41060 [details]
PDF file to reproduce the bug

poppler git (7313e0a4de6f2146c1dcb3d235f18a3c844d12d5) is unable to correctly render the attached PDF (tested both with splash and cairo backends).

I think that the problem might be in color function sampling.

Similar rendering issues also occur for other shadings in the radial-gradient test from cairo's testsuite when they are using a domain which is different from [0 1].

NB: This is not the same problem as #30887.
Comment 1 Albert Astals Cid 2010-12-13 08:16:50 UTC
Thomas any chance i can convince you to have a look?
Comment 2 Thomas Freitag 2010-12-16 08:18:33 UTC
The problem here is that the shading is deeply non-linear, see comments in Gfx::doRadialShFill:

        // The shading is not necessarily lineal so having two points with the
        // same color does not mean all the areas in between have the same color too
        // Do another bisection to be a bit more sure we are not doing something wrong

But in this case another bisection is definitely not enough. I'm not really sure how many bisections would be enough to speed up rendering but not render wrong, so if we comment the whole block:

/*
      if (isSameGfxColor(colorB, colorA, nComps, radialColorDelta) && ib < radialMaxSplits) {
        // The shading is not necessarily lineal so having two points with the
        // same color does not mean all the areas in between have the same color too
        // Do another bisection to be a bit more sure we are not doing something wrong
        GfxColor colorC;
        int ic = (ia + ib) / 2;
        double sc = sMin + ((double)ic / (double)radialMaxSplits) * (sMax - sMin);
        double tc = t0 + sc * (t1 - t0);
        getShadingColorRadialHelper(t0, t1, tc, shading, &colorC);
		if (isSameGfxColor(colorC, colorA, nComps, radialColorDelta)) {
          break;
		}
      }
*/

the rendering is okay. So there a lot of more circles to be paint, but because radial shading seems to be use not much often, I assume we can live with the lower speed!?
I tested this with the ducks & roses pdf, too, and also there the rendering seems to be a little bit better. What Do You think about it, Albert?
Comment 3 Thomas Freitag 2010-12-17 01:03:49 UTC
Stop any investigation, Albert! I think I found a good compromise between speed and correctness, but I'm still searching for a solution for the wine glass in ducks & roses. I'll come back with a patch asap.
Comment 4 Thomas Freitag 2010-12-17 05:08:09 UTC
Created attachment 41208 [details] [review]
should solve this issue

The patch include 3 differnt kind of changes:
1. The changes in FontInfo.cc and PDFDoc.cc are due to the fact I cannot compile the actual git source code with VS 2008 on Windows anymore. Please have a look at it and be free to commit it or not!
2. The main change in Gfx.cc solves this bug
3. The following change in Gfx.cc
-  if (vaa) {
+  if (vaa && shading->getType() != 3) {
     out->setVectorAntialias(gFalse);
   }
is because of the wine glass in ducks & roses. I'd a deeper look into the source code for radial shading, and I think the way radial shading is implemented needs antialiasing to give better results. I compared the output for the wine glass with and without antialiasing, and in my opinion the output with antialising is much better. But be free to commit this special change or not!
Comment 5 Thomas Freitag 2010-12-19 03:21:25 UTC
I made some regression tests on my PDFs which uses radial shading, and I didn't find any. But I found an additional enhancement:

In line 2928,

if (isSameGfxColor(colorB, colorA, nComps, radialColorDelta) && ib < radialMaxSplits) {

the comparison between ib and radialMaxSplits is no more needed, it just slows down rendering a little bit, so 

if (isSameGfxColor(colorB, colorA, nComps, radialColorDelta)) {

is sufficient now.
Comment 6 Albert Astals Cid 2010-12-20 15:40:09 UTC
I won't be commiting change 3 since it introduces some regressions in the background of http://www.alfa.de/de/admin/content/document/PDF/3907525_13_hi.pdf

Still regtesting the other change but seems cool for the moment.
Comment 7 Thomas Freitag 2010-12-21 01:27:12 UTC
(In reply to comment #6)
> I won't be commiting change 3 since it introduces some regressions in the
> background of
> http://www.alfa.de/de/admin/content/document/PDF/3907525_13_hi.pdf
> 
> Still regtesting the other change but seems cool for the moment.

Oh, I see, what You mean. I haven't encountered that in my own regression test, because I normally use 

#define radialColorDelta (dblToCol(16.0 / 256.0))

instead of 

#define radialColorDelta (dblToCol(1.0 / 256.0))

to make rendering faster. And with this poorer flow the result with antialiasing looks better than without. But You're right, with the better flow the result with antialiasing looks worse.
I already thought about to implement radial shading in SplashOutputDev in drawing Besenham circles instead of using clipping pathes, but this means more effort. So let us see if the patch without antialiasing runs through Your test, and then look if there is time enough left to implement it in my vacation or to put it on my open issues...
Comment 8 Albert Astals Cid 2010-12-23 07:59:27 UTC
Will be in 0.16
Comment 9 Andrea Canciani 2010-12-29 09:50:34 UTC
Created attachment 41506 [details]
PDF with multiple radial tests

poppler 0.16 (or master) handle radial gradients slightly better, but they are still unable to render the attached PDF correctly.

Tested on splash and cairo.


Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.