Uploaded image for project: 'PDFBox'
  1. PDFBox
  2. PDFBOX-615

shfill operator needs implementation

    Details

      Description

      I have a PDF file (for which I do not yet have release permission) that uses the "sh" operator, equivalent to PostScript's shfill (per PDF spec 1.7 page 987).

      Adobe provides implementation guidance in a 78-page document at http://www.adobe.com/devnet/postscript/pdfs/TN5600.SmoothShading.pdf#17

      I will be trying to add this functionality this week, but if anyone has hints, suggestions, etc. they are most certainly welcome!

      1. Vertex.java
        1 kB
        Tilman Hausherr
      2. Type5ShadingPaint.java
        2 kB
        Tilman Hausherr
      3. Type5ShadingContext.java
        7 kB
        Tilman Hausherr
      4. Type4ShadingPaint.java
        2 kB
        Tilman Hausherr
      5. Type4ShadingContext.java
        10 kB
        Tilman Hausherr
      6. trityp4.pdf-1.png
        277 kB
        Tilman Hausherr
      7. shading_pattern.pdf-2.png
        125 kB
        Tilman Hausherr
      8. shading_pattern.pdf
        2 kB
        Tilman Hausherr
      9. radial-input-before.png
        4 kB
        Luis Bernardo
      10. radial-input-after.png
        12 kB
        Luis Bernardo
      11. radial-input.pdf
        6 kB
        Luis Bernardo
      12. pslib-shading.pdf
        15 kB
        Tilman Hausherr
      13. PDShadingPatternResources.patch
        3 kB
        Tilman Hausherr
      14. pdfbox-615-radial-input.pdf-1.png
        81 kB
        Tilman Hausherr
      15. pdfbox-1.8.patch
        4 kB
        Luis Bernardo
      16. pdfbox.patch
        4 kB
        Luis Bernardo
      17. lattice2.pdf-1.png
        4.70 MB
        Tilman Hausherr
      18. LATTICE2.pdf
        3 kB
        Tilman Hausherr
      19. lattice1.pdf-1.png
        1.28 MB
        Tilman Hausherr
      20. LATTICE1.pdf
        3 kB
        Tilman Hausherr
      21. input1.png
        5 kB
        Luis Bernardo
      22. input.pdf
        6 kB
        Luis Bernardo
      23. GouraudTriangle.java
        3 kB
        Tilman Hausherr
      24. GouraudShadingContext.patch
        1 kB
        Tilman Hausherr
      25. GouraudShadingContext.java
        11 kB
        Tilman Hausherr
      26. decahed.pdf-1.png
        1.98 MB
        Tilman Hausherr
      27. DECAHED.pdf
        3 kB
        Tilman Hausherr
      28. color_gradient.pdf-1.png
        265 kB
        Tilman Hausherr
      29. color_gradient.pdf
        2 kB
        Tilman Hausherr
      30. ch14.pdf-13.png
        556 kB
        Tilman Hausherr
      31. ch14.pdf
        774 kB
        Tilman Hausherr
      32. Centerplan.pdf
        541 kB
        Andreas Lehmkühler
      33. bugzilla843488.pdf-1.png
        87 kB
        Tilman Hausherr
      34. bugzilla843488.pdf
        1.27 MB
        Tilman Hausherr
      35. axial-input-before.png
        6 kB
        Luis Bernardo
      36. axial-input-after.png
        4 kB
        Luis Bernardo
      37. axial-input.pdf
        6 kB
        Luis Bernardo

        Issue Links

          Activity

          Hide
          lehmi Andreas Lehmkühler added a comment -

          Closed after releasing PDFBox 1.8.5

          Show
          lehmi Andreas Lehmkühler added a comment - Closed after releasing PDFBox 1.8.5
          Hide
          lehmi Andreas Lehmkühler added a comment -

          I've merged all changes into the 1.8 branch in revision 1563639.

          Thanks to all for their contribution/help/input!

          Show
          lehmi Andreas Lehmkühler added a comment - I've merged all changes into the 1.8 branch in revision 1563639. Thanks to all for their contribution/help/input!
          Hide
          tilman Tilman Hausherr added a comment -

          It wasn't an optimization, it was a bugfix

          Close it if you want... I hope that the Apache Foundation doesn't have to pay for each ticket

          Show
          tilman Tilman Hausherr added a comment - It wasn't an optimization, it was a bugfix Close it if you want... I hope that the Apache Foundation doesn't have to pay for each ticket
          Hide
          lehmi Andreas Lehmkühler added a comment -

          I've added the optimization in revision 1563430 as proposed.

          I'm going to backport all changes (incl. PDFBOX-1870 and PDFBOX-1869) to the 1.8 branch. After that I'd like to close all three of the issues and suggest to open new ones for any additions/fixes/optimizations. I'm working on PDFBOX-1094 to add some tiling pattern support. It already works by I've to update my sources first.

          Show
          lehmi Andreas Lehmkühler added a comment - I've added the optimization in revision 1563430 as proposed. I'm going to backport all changes (incl. PDFBOX-1870 and PDFBOX-1869 ) to the 1.8 branch. After that I'd like to close all three of the issues and suggest to open new ones for any additions/fixes/optimizations. I'm working on PDFBOX-1094 to add some tiling pattern support. It already works by I've to update my sources first.
          Hide
          tilman Tilman Hausherr added a comment - - edited

          Bugfix patch for GouraudShadingContext - don't "new" the values array only once, because in certain cases it has a larger size after getting tint-transformed, which then results in an index bounds overflow the next time that shadingTinttransform.eval() is called.

          The good news is that for the first time, I was able to render page 13 of ch14.pdf (newly generated with gs, not the file from the website).

          Show
          tilman Tilman Hausherr added a comment - - edited Bugfix patch for GouraudShadingContext - don't "new" the values array only once, because in certain cases it has a larger size after getting tint-transformed, which then results in an index bounds overflow the next time that shadingTinttransform.eval() is called. The good news is that for the first time, I was able to render page 13 of ch14.pdf (newly generated with gs, not the file from the website).
          Hide
          lehmi Andreas Lehmkühler added a comment -

          I've added the type4 and type sading support in revision 1563199 as proposed with some sminor changes (reformatted, replaced some headers)

          Tilman Hausherr Thanks a lot for the contribution!

          Show
          lehmi Andreas Lehmkühler added a comment - I've added the type4 and type sading support in revision 1563199 as proposed with some sminor changes (reformatted, replaced some headers) Tilman Hausherr Thanks a lot for the contribution!
          Hide
          tilman Tilman Hausherr added a comment -

          The new rendering of the radial shading (pdfbox-615-radial-input.pdf-1.png) has a red edge on the left that wasn't there before.

          Show
          tilman Tilman Hausherr added a comment - The new rendering of the radial shading (pdfbox-615-radial-input.pdf-1.png) has a red edge on the left that wasn't there before.
          Hide
          tilman Tilman Hausherr added a comment -

          I added your transparency changes to type 1, 4 and 5, the background problems are gone. Will upload changed versions later.

          Show
          tilman Tilman Hausherr added a comment - I added your transparency changes to type 1, 4 and 5, the background problems are gone. Will upload changed versions later.
          Hide
          lehmi Andreas Lehmkühler added a comment -

          I've started with Luis patch and added some of my own code to support a possible background of a shading. I've added bot changes in revision 1562921.

          Luis Bernardo Thanks for the contribution!

          I'm going to follow up with the other stuff soon.

          Show
          lehmi Andreas Lehmkühler added a comment - I've started with Luis patch and added some of my own code to support a possible background of a shading. I've added bot changes in revision 1562921. Luis Bernardo Thanks for the contribution! I'm going to follow up with the other stuff soon.
          Hide
          tilman Tilman Hausherr added a comment -

          Yes... one might delete it and replace the code with the java bit stream solution. (I always prefer using java functions instead of reinventing something). On the other hand, I remember that somebody somewhere said that there may be problems with functions that open files.

          Show
          tilman Tilman Hausherr added a comment - Yes... one might delete it and replace the code with the java bit stream solution. (I always prefer using java functions instead of reinventing something). On the other hand, I remember that somebody somewhere said that there may be problems with functions that open files.
          Hide
          jahewson John Hewson added a comment - - edited

          So there is, well spotted! Looks like NBitInputStream is only used by LZWFilter.

          Show
          jahewson John Hewson added a comment - - edited So there is, well spotted! Looks like NBitInputStream is only used by LZWFilter .
          Hide
          tilman Tilman Hausherr added a comment -

          Great idea! The readBits() function did all I need. Funny thing: while cleaning up, I found there's already a bit reading class in the code - NBitInputStream.

          Show
          tilman Tilman Hausherr added a comment - Great idea! The readBits() function did all I need. Funny thing: while cleaning up, I found there's already a bit reading class in the code - NBitInputStream.
          Hide
          jahewson John Hewson added a comment -

          I've recently discovered ImageInputStream in the package javax.imageio.stream. Even though it's part of ImageIO it's actually a general-purpose bit stream. You can probably replace your bit-io dependency with it if you want?

          Show
          jahewson John Hewson added a comment - I've recently discovered ImageInputStream in the package javax.imageio.stream . Even though it's part of ImageIO it's actually a general-purpose bit stream. You can probably replace your bit-io dependency with it if you want?
          Hide
          tilman Tilman Hausherr added a comment - - edited

          My comment of 17/Jan/14 08:11 as two patches. All the rest are new files.

          Show
          tilman Tilman Hausherr added a comment - - edited My comment of 17/Jan/14 08:11 as two patches. All the rest are new files.
          Hide
          lmpmbernardo Luis Bernardo added a comment -

          can this new code be provided as a patch?... it would be easier for others to try it.

          Show
          lmpmbernardo Luis Bernardo added a comment - can this new code be provided as a patch?... it would be easier for others to try it.
          Hide
          tilman Tilman Hausherr added a comment -

          Refactored the vertex reading

          Show
          tilman Tilman Hausherr added a comment - Refactored the vertex reading
          Hide
          jahewson John Hewson added a comment -

          Let's get this in trunk, JIRA makes a very poor replacement for subversion.

          Show
          jahewson John Hewson added a comment - Let's get this in trunk, JIRA makes a very poor replacement for subversion.
          Hide
          tilman Tilman Hausherr added a comment -

          See my comment from 17/Jan/14 08:11 for how to get the bit-io. That comment also mentions some other changes in other files that are needed. I'd advise against putting this in the trunk. (There are changes in radial and axial shadings that have also not been committed, likely because there is more work to do on them)

          Show
          tilman Tilman Hausherr added a comment - See my comment from 17/Jan/14 08:11 for how to get the bit-io. That comment also mentions some other changes in other files that are needed. I'd advise against putting this in the trunk. (There are changes in radial and axial shadings that have also not been committed, likely because there is more work to do on them)
          Hide
          jahewson John Hewson added a comment -

          Looking good, leaving the debugging comments and logging seems reasonable for now because there is still work to do done once this is in trunk. A few leftovers:

          • JavaDoc tag needs competing in Type4ShadingContext#createTriangleList
          • patch needs to include "bit-io" in pom.xml, currently the code does not compile. The comments against import statements can then be removed.
          • The static LOG field should be declared before the member fields in Type5ShadingContext, Type4ShadingContext, and GouraudShadingContext.
          Show
          jahewson John Hewson added a comment - Looking good, leaving the debugging comments and logging seems reasonable for now because there is still work to do done once this is in trunk. A few leftovers: JavaDoc tag needs competing in Type4ShadingContext#createTriangleList patch needs to include "bit-io" in pom.xml, currently the code does not compile. The comments against import statements can then be removed. The static LOG field should be declared before the member fields in Type5ShadingContext, Type4ShadingContext, and GouraudShadingContext.
          Hide
          tilman Tilman Hausherr added a comment -

          Cleaned up files. I didn't split the more in the constructors because I don't feel its ready for it. I couldn't put some of the stuff in the helper class because it would require changes in the PDShadingType4 and PDShadingType5 classes (which do have common methods).

          Show
          tilman Tilman Hausherr added a comment - Cleaned up files. I didn't split the more in the constructors because I don't feel its ready for it. I couldn't put some of the stuff in the helper class because it would require changes in the PDShadingType4 and PDShadingType5 classes (which do have common methods).
          Hide
          tilman Tilman Hausherr added a comment - - edited

          Code for type 4 and (new) 5 shading, refactored. The two changes in other classes described previously must be done analog for type 5. The background problem is not just "not knowing what to paint there" because this time (see lattice1.pdf) there is text around the pattern which is missing in the rendered image. Any help is appreciated.

          (See also the wrong background of the rendering of page 2 in shading_pattern.pdf)

          Show
          tilman Tilman Hausherr added a comment - - edited Code for type 4 and (new) 5 shading, refactored. The two changes in other classes described previously must be done analog for type 5. The background problem is not just "not knowing what to paint there" because this time (see lattice1.pdf) there is text around the pattern which is missing in the rendered image. Any help is appreciated. (See also the wrong background of the rendering of page 2 in shading_pattern.pdf)
          Hide
          tilman Tilman Hausherr added a comment -

          Code for type 4 shading patterns (not shfill, because I don't have a test file) attached, which works for the two adobe tests. I haven't solved the background problem, I don't find anything in the specification how this should be done. It supports only DeviceRGB and not functions. If you want to use the code, first do this:

          In PDShadingType4.java correct getFunction:

              public PDFunction getFunction() throws IOException
              {
                  if (function == null)
                  {
                      COSBase dictionaryFunctionObject = getCOSDictionary().getDictionaryObject(COSName.FUNCTION);
                      if (dictionaryFunctionObject != null) //TH
                          function = PDFunction.create(dictionaryFunctionObject);
                  }
                  return function;
              }
          

          In PDShadingPatternResources.java, insert at case PDShadingResources.SHADING_TYPE4:

                      case PDShadingResources.SHADING_TYPE4:
                          if (!(getShading().getColorSpace() instanceof PDDeviceRGB))
                          {
                              LOG.error("can't handle Colorspace " + shading.getColorSpace());
                              return null;
                          }
                          paint = new Type4ShadingPaint((PDShadingType4) getShading(), ctm, pageHeight);
                          break;
          

          Get the Bitinput lib by adding this to the pdfbox pom.xml:

                  <dependency>
                      <groupId>com.github.jinahya</groupId>
                      <artifactId>bit-io</artifactId>
                      <version>1.0.3</version>
                  </dependency>
          

          That lib has an apache 2.0 license

          The code works for the two Adobe demo files DECAHED.pdf and TRITYP4.pdf. It does not work for ch14.pdf because 0) that pdf uses shfill 1) the vertex streams in that file don't comply with the pdf spec (however creating a new pdf from the ps file from the homepage http://www.math.ubc.ca/~cass/graphics/manual/index.html creates a better file), 2) that pdf file has different color spaces than DeviceRGB and I need to learn about these or get help with that segment of the code.

          I think that the implementation for type4 shfill would be to use the gouraud triangle mesh as a shape and pass this shape to graphics.fill() in PageDrawer.java, and then again use the existing code. Currently, PageDrawer passes the full page to graphics.fill() which is why the pages 1,13,15 and 20 are black.

          I also had a look at type 5 shading spec. The only difference is that the triangles are defined differently (lattice), but the rest is the same, so I will handle this too when I have the time.

          Show
          tilman Tilman Hausherr added a comment - Code for type 4 shading patterns (not shfill, because I don't have a test file) attached, which works for the two adobe tests. I haven't solved the background problem, I don't find anything in the specification how this should be done. It supports only DeviceRGB and not functions. If you want to use the code, first do this: In PDShadingType4.java correct getFunction: public PDFunction getFunction() throws IOException { if (function == null ) { COSBase dictionaryFunctionObject = getCOSDictionary().getDictionaryObject(COSName.FUNCTION); if (dictionaryFunctionObject != null ) //TH function = PDFunction.create(dictionaryFunctionObject); } return function; } In PDShadingPatternResources.java, insert at case PDShadingResources.SHADING_TYPE4: case PDShadingResources.SHADING_TYPE4: if (!(getShading().getColorSpace() instanceof PDDeviceRGB)) { LOG.error( "can't handle Colorspace " + shading.getColorSpace()); return null ; } paint = new Type4ShadingPaint((PDShadingType4) getShading(), ctm, pageHeight); break ; Get the Bitinput lib by adding this to the pdfbox pom.xml: <dependency> <groupId>com.github.jinahya</groupId> <artifactId>bit-io</artifactId> <version>1.0.3</version> </dependency> That lib has an apache 2.0 license The code works for the two Adobe demo files DECAHED.pdf and TRITYP4.pdf. It does not work for ch14.pdf because 0) that pdf uses shfill 1) the vertex streams in that file don't comply with the pdf spec (however creating a new pdf from the ps file from the homepage http://www.math.ubc.ca/~cass/graphics/manual/index.html creates a better file), 2) that pdf file has different color spaces than DeviceRGB and I need to learn about these or get help with that segment of the code. I think that the implementation for type4 shfill would be to use the gouraud triangle mesh as a shape and pass this shape to graphics.fill() in PageDrawer.java, and then again use the existing code. Currently, PageDrawer passes the full page to graphics.fill() which is why the pages 1,13,15 and 20 are black. I also had a look at type 5 shading spec. The only difference is that the triangles are defined differently (lattice), but the rest is the same, so I will handle this too when I have the time.
          Hide
          tilman Tilman Hausherr added a comment - - edited

          The first page of the file shading_pattern.pdf ( mentioned here: http://itextpdf.com/examples/iia.php?id=180 ) is fine, but the second has a problem with the top figure and with the background.

          Show
          tilman Tilman Hausherr added a comment - - edited The first page of the file shading_pattern.pdf ( mentioned here: http://itextpdf.com/examples/iia.php?id=180 ) is fine, but the second has a problem with the top figure and with the background.
          Hide
          tilman Tilman Hausherr added a comment -

          The mentioned pdflib example ( http://www.pdflib.com/pdflib-cookbook/color/color-gradient/ ) has a very minor problem: the "hello world" glyphs are not shaded.

          Show
          tilman Tilman Hausherr added a comment - The mentioned pdflib example ( http://www.pdflib.com/pdflib-cookbook/color/color-gradient/ ) has a very minor problem: the "hello world" glyphs are not shaded.
          Hide
          tilman Tilman Hausherr added a comment -

          Here's a sample pdf for shading type 4:
          http://book.huihoo.com/pdf/mathematical-illustrations/pdf/ch14.pdf
          On pages 1, 13, 15 and 20.

          Show
          tilman Tilman Hausherr added a comment - Here's a sample pdf for shading type 4: http://book.huihoo.com/pdf/mathematical-illustrations/pdf/ch14.pdf On pages 1, 13, 15 and 20.
          Hide
          tilman Tilman Hausherr added a comment -

          Example taken from https://bugzilla.mozilla.org/show_bug.cgi?id=843488
          Like there, a & d are wrong, the other ones are good (I used Luis' code). And reference image b is wrong too.

          Show
          tilman Tilman Hausherr added a comment - Example taken from https://bugzilla.mozilla.org/show_bug.cgi?id=843488 Like there, a & d are wrong, the other ones are good (I used Luis' code). And reference image b is wrong too.
          Hide
          lmpmbernardo Luis Bernardo added a comment -

          attached are two patches, for trunk and 1.8 branch, that fix the issues with the examples provided.

          Note: the getX() methods in the patches are not needed for the examples to work, but I need them in FOP so I would appreciate if they could remain part of the patch.

          Show
          lmpmbernardo Luis Bernardo added a comment - attached are two patches, for trunk and 1.8 branch, that fix the issues with the examples provided. Note: the getX() methods in the patches are not needed for the examples to work, but I need them in FOP so I would appreciate if they could remain part of the patch.
          Hide
          lmpmbernardo Luis Bernardo added a comment -

          Attached a PDF input and the current PNG output. The current radial shading implementation does not work with this example.

          Show
          lmpmbernardo Luis Bernardo added a comment - Attached a PDF input and the current PNG output. The current radial shading implementation does not work with this example.
          Hide
          lehmi Andreas Lehmkühler added a comment -

          I added an implementation of a radial shading in revision 1239309

          Show
          lehmi Andreas Lehmkühler added a comment - I added an implementation of a radial shading in revision 1239309
          Hide
          lehmi Andreas Lehmkühler added a comment -

          I fixed the transformation issue in revision 1236359, so that the current status is 4 out of 4

          Any additional tests and samples are welcome.

          @Maruan
          Thanks for the pointer. The sample I found at pdflib.com helped me finding the solution as it is way much simplier than the other samples I have.

          Show
          lehmi Andreas Lehmkühler added a comment - I fixed the transformation issue in revision 1236359, so that the current status is 4 out of 4 Any additional tests and samples are welcome. @Maruan Thanks for the pointer. The sample I found at pdflib.com helped me finding the solution as it is way much simplier than the other samples I have.
          Hide
          lehmi Andreas Lehmkühler added a comment -

          @Daniel
          Thanks for the encouragement

          I guess the remaining issue has something to do with the transformation from the shading/user space to the device space. I'm on it.

          Show
          lehmi Andreas Lehmkühler added a comment - @Daniel Thanks for the encouragement I guess the remaining issue has something to do with the transformation from the shading/user space to the device space. I'm on it.
          Hide
          danielwilson Daniel Wilson added a comment -

          If your implementation works with 3 of 4 examples, it's a step forward!

          Show
          danielwilson Daniel Wilson added a comment - If your implementation works with 3 of 4 examples, it's a step forward!
          Hide
          lehmi Andreas Lehmkühler added a comment -

          My solution works fine with the attached Centerplan.pdf, the pdf attached to PDFBOX-1058 (page 7) and a pdf which I can't publish. But I doesn't work with a sample from pdflib.com. So, I guess I have to rework my implementation.

          Show
          lehmi Andreas Lehmkühler added a comment - My solution works fine with the attached Centerplan.pdf, the pdf attached to PDFBOX-1058 (page 7) and a pdf which I can't publish. But I doesn't work with a sample from pdflib.com. So, I guess I have to rework my implementation.
          Hide
          msahyoun Maruan Sahyoun added a comment -

          There are public samples on pdflib.com or iText website

          Show
          msahyoun Maruan Sahyoun added a comment - There are public samples on pdflib.com or iText website
          Hide
          lehmi Andreas Lehmkühler added a comment -

          I added an implementation for an axial shading to be used in combination with the sh operator in revision 1235384. At least the shading of the attached pdf looks good to me. Probably I'll be able to implement the radial shading as well, as long as I'll find a sample pdf using it.

          Show
          lehmi Andreas Lehmkühler added a comment - I added an implementation for an axial shading to be used in combination with the sh operator in revision 1235384. At least the shading of the attached pdf looks good to me. Probably I'll be able to implement the radial shading as well, as long as I'll find a sample pdf using it.
          Hide
          lehmi Andreas Lehmkühler added a comment -

          I added some classes to manage the different shading resources in revision 1161633 as I'll need it for the implementation of patterns (see PDFBOX-1094)

          Show
          lehmi Andreas Lehmkühler added a comment - I added some classes to manage the different shading resources in revision 1161633 as I'll need it for the implementation of patterns (see PDFBOX-1094 )
          Hide
          danielwilson Daniel Wilson added a comment -

          Thanks, Andreas, for both the pointers and the example.

          That example looks much more approachable than the one from my customer! I'll see if I can make some headway on it this week.

          Show
          danielwilson Daniel Wilson added a comment - Thanks, Andreas, for both the pointers and the example. That example looks much more approachable than the one from my customer! I'll see if I can make some headway on it this week.
          Hide
          lehmi Andreas Lehmkühler added a comment -

          An other pdf example using a shading dictionary

          Show
          lehmi Andreas Lehmkühler added a comment - An other pdf example using a shading dictionary
          Hide
          lehmi Andreas Lehmkühler added a comment -

          I'm not an expert, but AFAIU the shfill operator, you are not that far away from the solution. The shfill operator can be used similar to the fill operator under the following terms:

          • use Graphics2D.setPaint instead of Graphics2D.setColor, all needed information should be in the shading dictionary
          • take the current clipping area into amount
          • don't use the current path
          • use the path information from the shading dictionary (AFAIU that depends on the used function??)
          • if there aren't any path information in the dictionary, just use the clipping path
          • the current color in the grpahics state isn't used and must not be altered

          HTH

          Show
          lehmi Andreas Lehmkühler added a comment - I'm not an expert, but AFAIU the shfill operator, you are not that far away from the solution. The shfill operator can be used similar to the fill operator under the following terms: use Graphics2D.setPaint instead of Graphics2D.setColor, all needed information should be in the shading dictionary take the current clipping area into amount don't use the current path use the path information from the shading dictionary (AFAIU that depends on the used function??) if there aren't any path information in the dictionary, just use the clipping path the current color in the grpahics state isn't used and must not be altered HTH
          Hide
          danielwilson Daniel Wilson added a comment -

          Revision 926744 takes a big step closer.

          Currently I have only 1 example PDF that uses this operator ... and it is a very complex example.

          Show
          danielwilson Daniel Wilson added a comment - Revision 926744 takes a big step closer. Currently I have only 1 example PDF that uses this operator ... and it is a very complex example.
          Hide
          danielwilson Daniel Wilson added a comment -

          Initial code in revision 916345.
          Still needs several function bodies written.

          Show
          danielwilson Daniel Wilson added a comment - Initial code in revision 916345. Still needs several function bodies written.
          Hide
          danielwilson Daniel Wilson added a comment -

          Thank you, Igor. That's getting me closer ...

          Show
          danielwilson Daniel Wilson added a comment - Thank you, Igor. That's getting me closer ...
          Hide
          podolsir Igor Podolskiy added a comment -

          > I must say I'm a little confused regarding how to take that name and get the Shading Dictionary.

          Well, the specification of the sh operator says ([PDF32000:2008], p. 182, Table 77, second paragraph) says:

          "[...] [Operand] <name> is the name of a shading dictionary resource in the Shadingsubdictionary of the current resource dictionary [...]"

          As far as I understand, you are supposed to do the following if you encounter an sh operator:

          1. Get its operand (Sh0 in your example)
          2. Look for a Shading entry in the Resources dictionary of the current page. This entry is a dictionary itself.
          3. Use your sh operand value (Sh0) as the key for that dictionary. The corresponding value is the shading descriptor dictionary you use for the painting.

          (Derefencing the indirect references may be needed in between, of course.)

          I think the confusion arises from the fact that the spec uses the term "shading dictionary" for two different things: firstly, the entry in the page's Resources dictionary with the key /Shading, and secondly, for the thing I called "shading descriptor" here, i.e. the one with the /ShadingType etc. entries which is described in section 8.7.4.3 of the spec.

          [PDF32000:2008] http://www.adobe.com/devnet/acrobat/pdfs/PDF32000_2008.pdf

          Show
          podolsir Igor Podolskiy added a comment - > I must say I'm a little confused regarding how to take that name and get the Shading Dictionary. Well, the specification of the sh operator says ( [PDF32000:2008] , p. 182, Table 77, second paragraph) says: " [...] [Operand] <name> is the name of a shading dictionary resource in the Shadingsubdictionary of the current resource dictionary [...] " As far as I understand, you are supposed to do the following if you encounter an sh operator: 1. Get its operand (Sh0 in your example) 2. Look for a Shading entry in the Resources dictionary of the current page. This entry is a dictionary itself. 3. Use your sh operand value (Sh0) as the key for that dictionary. The corresponding value is the shading descriptor dictionary you use for the painting. (Derefencing the indirect references may be needed in between, of course.) I think the confusion arises from the fact that the spec uses the term "shading dictionary" for two different things: firstly, the entry in the page's Resources dictionary with the key /Shading, and secondly, for the thing I called "shading descriptor" here, i.e. the one with the /ShadingType etc. entries which is described in section 8.7.4.3 of the spec. [PDF32000:2008] http://www.adobe.com/devnet/acrobat/pdfs/PDF32000_2008.pdf
          Hide
          danielwilson Daniel Wilson added a comment -

          I'll note my "progress" here in hopes that if I'm way off base in the concept, one of you can throw a flag.

          It does seem that there should be a class to represent a Shading Dictionary. Conceptually it is parallel to PDPattern, so I now have a PDShading class. I haven't committed this code as it's really not doing anything yet ... but it looks like part of the solution.

          The piece I completely overlooked in last night's comment was the sh operator. I'm implementing it as o.a.p.util.operator.pagedrawer.SHFill.

          At this point its process method is simply logging the argument list.

          This operator is getting a single name argument – just like the spec says it should. In my case it's:
          [COSName

          {Sh0}

          ]

          I must say I'm a little confused regarding how to take that name and get the Shading Dictionary.

          The relevant section of the PDF file looks like this:
          <</Parent 2 0 R
          /Contents 178 0 R
          /BleedBox[0.0 0.0 1152.0 1656.0]
          /PieceInfo
          <</Illustrator 142 0 R>>
          /ArtBox[39.6431 171.689 963.828 1655.02]
          /MediaBox[0.0 0.0 1152.0 1656.0]
          /Thumb 183 0 R
          /TrimBox[0.0 0.0 1152.0 1656.0]
          /Resources
          <</Shading
          <</Sh0 170 0 R>>
          /ColorSpace
          <</CS0 174 0 R/CS1 162 0 R/CS2 175 0 R/CS3 168 0 R/CS4 163 0 R/CS5 169 0 R>>
          /Font
          <</T1_0 176 0 R>>
          /ProcSet[/PDF/Text]
          /Properties
          <</MC0 158 0 R>>
          /ExtGState
          <</GS0 161 0 R>>
          >>
          /Type
          /Page
          /LastModified(D:20090602144525-05'00')
          >>

          The Sh0 name is clearly there ... and it refers to object 170 if I'm reading it right. Object 170 appears to be:
          170 0 obj
          <</ColorSpace 162 0 R/AntiAlias false/Coords[0.0 0.0 1.0 0.0]/Function 171 0 R/Extend[true true]/Domain[0.0 1.0]/ShadingType 2>>
          endobj

          This contains the required entries for a shading dictionary of ShadingType 2 (Axial) as well as a couple of the optional ones.

          Which all brings me back to trying to get the Shading Dictionary from the name Sh0.

          Again, pointers are MUCH appreciated.

          Show
          danielwilson Daniel Wilson added a comment - I'll note my "progress" here in hopes that if I'm way off base in the concept, one of you can throw a flag. It does seem that there should be a class to represent a Shading Dictionary. Conceptually it is parallel to PDPattern, so I now have a PDShading class. I haven't committed this code as it's really not doing anything yet ... but it looks like part of the solution. The piece I completely overlooked in last night's comment was the sh operator. I'm implementing it as o.a.p.util.operator.pagedrawer.SHFill. At this point its process method is simply logging the argument list. This operator is getting a single name argument – just like the spec says it should. In my case it's: [COSName {Sh0} ] I must say I'm a little confused regarding how to take that name and get the Shading Dictionary. The relevant section of the PDF file looks like this: <</Parent 2 0 R /Contents 178 0 R /BleedBox [0.0 0.0 1152.0 1656.0] /PieceInfo <</Illustrator 142 0 R>> /ArtBox [39.6431 171.689 963.828 1655.02] /MediaBox [0.0 0.0 1152.0 1656.0] /Thumb 183 0 R /TrimBox [0.0 0.0 1152.0 1656.0] /Resources <</Shading <</Sh0 170 0 R>> /ColorSpace <</CS0 174 0 R/CS1 162 0 R/CS2 175 0 R/CS3 168 0 R/CS4 163 0 R/CS5 169 0 R>> /Font <</T1_0 176 0 R>> /ProcSet [/PDF/Text] /Properties <</MC0 158 0 R>> /ExtGState <</GS0 161 0 R>> >> /Type /Page /LastModified(D:20090602144525-05'00') >> The Sh0 name is clearly there ... and it refers to object 170 if I'm reading it right. Object 170 appears to be: 170 0 obj <</ColorSpace 162 0 R/AntiAlias false/Coords [0.0 0.0 1.0 0.0] /Function 171 0 R/Extend [true true] /Domain [0.0 1.0] /ShadingType 2>> endobj This contains the required entries for a shading dictionary of ShadingType 2 (Axial) as well as a couple of the optional ones. Which all brings me back to trying to get the Shading Dictionary from the name Sh0. Again, pointers are MUCH appreciated.
          Hide
          danielwilson Daniel Wilson added a comment -

          Pages 302 - 331 of the PDF spec 1.7 describe the shading operation.

          Shading is one set of the Pattern operations ... the other set being Tiling Patterns. Those don't concern me at the moment, and we have some support for them in the org.apache.pdfbox.pdmodel.graphics.color.PDPattern class.

          The set of Shading operations does gradient fills – and there are 7 different types of these gradient fill shadings.

          Now, I could use some implementation thoughts as I bring the concept back to our object model.

          Since the shading operation is used for stroking & filling operations, is deriving it from PDColorSpace as was done with PDPattern the right answer?

          Since there are 7 different types of shading operations, do we need 7 different classes?

          Or should the method that does the fill/stroke check the class's type and do the operation? And ... which method is that? PDPattern has next to no methods. And neither do the PDColorSpace derivatives that we use frequently like PDDeviceRGB. The only thing that really appears to matter there is createColorModel. In the case of a shading / gradient fill, is createColorModel possibly enough? It hardly seems it ...

          Any thoughts along this line are MUCH appreciated.

          Show
          danielwilson Daniel Wilson added a comment - Pages 302 - 331 of the PDF spec 1.7 describe the shading operation. Shading is one set of the Pattern operations ... the other set being Tiling Patterns. Those don't concern me at the moment, and we have some support for them in the org.apache.pdfbox.pdmodel.graphics.color.PDPattern class. The set of Shading operations does gradient fills – and there are 7 different types of these gradient fill shadings. Now, I could use some implementation thoughts as I bring the concept back to our object model. Since the shading operation is used for stroking & filling operations, is deriving it from PDColorSpace as was done with PDPattern the right answer? Since there are 7 different types of shading operations, do we need 7 different classes? Or should the method that does the fill/stroke check the class's type and do the operation? And ... which method is that? PDPattern has next to no methods. And neither do the PDColorSpace derivatives that we use frequently like PDDeviceRGB. The only thing that really appears to matter there is createColorModel. In the case of a shading / gradient fill, is createColorModel possibly enough? It hardly seems it ... Any thoughts along this line are MUCH appreciated.

            People

            • Assignee:
              lehmi Andreas Lehmkühler
              Reporter:
              danielwilson Daniel Wilson
            • Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development