Issue
I'm facing the issue that I'm trying to draw a rectangle with Spot Colors (PDSeparation) one for stroke and one for NonStroke (fill).
First color values: spotColorName = stroke color 6, R = 255, G = 153, B = 51
Second color values: spotColorName = fill color 6, R = 0, G = 0, B = 255
This is a screenshot of the PDF output
here is the code that creating the separation and color
private PDColor createSpotColorFromRGB(String spotColorName, int r,
int g, int b) throws IOException {
PDSeparation seperation = new PDSeparation();
COSDictionary dictionary = new COSDictionary();
COSArray C0 = new COSArray();
COSArray C1 = new COSArray();
COSArray range = new COSArray();
COSArray domain = new COSArray();
float[] components = null;
seperation.setColorantName(spotColorName);
components = new float[] { r / 255f, g / 255f, b / 255f };
seperation.setAlternateColorSpace(PDDeviceRGB.INSTANCE);
C0.add(COSInteger.ZERO);
C0.add(COSInteger.ZERO);
C0.add(COSInteger.ZERO);
range.add(COSInteger.ZERO);
range.add(COSInteger.ONE);
range.add(COSInteger.ZERO);
range.add(COSInteger.ONE);
range.add(COSInteger.ZERO);
range.add(COSInteger.ONE);
C1.add(COSInteger.ONE);
C1.add(COSInteger.ONE);
C1.add(COSInteger.ONE);
domain.add(COSInteger.ZERO);
domain.add(COSInteger.ONE);
dictionary.setItem(COSName.C0, C0);
dictionary.setItem(COSName.C1, C1);
dictionary.setItem(COSName.DOMAIN, domain);
dictionary.setItem(COSName.FUNCTION_TYPE, COSInteger.TWO);
dictionary.setItem(COSName.N, COSInteger.ONE);
dictionary.setItem(COSName.RANGE, range);
PDFunction functionTyp2 = new PDFunctionType2(dictionary);
seperation.setTintTransform(functionTyp2);
return new PDColor(components, seperation);
}
then I set the generated colors to the page content stream by
outputPageContentStream.setNonStrokingColor(fillColor);
outputPageContentStream.setStrokingColor(strokeColor);
Only one color of the 2 colors is shown, the color with 1 scn/SCN is shown.
Attached the output PDF file:https://docdro.id/0sVSuWE
The code for drawing is:
outputPageContentStream.saveGraphicsState();
outputPageContentStream.setNonStrokingColor(fillingColorForDrawingPDColor);
outputPageContentStream.setStrokingColor(strokingColorForDrawingPDColor);
outputPageContentStream.moveTo(a, b);
outputPageContentStream.lineTo(a + c, b);
outputPageContentStream.lineTo(a + c, b - d);
outputPageContentStream.lineTo(a, b - d);
outputPageContentStream.closePath();
outputPageContentStream.fillAndStroke();
outputPageContentStream.restoreGraphicsState();
Can anyone help with this?
Solution
I looked at the file with PDFBox PDFDebugger, and cs1 being 0 ("0 scn" in the screenshot) means it will appear as white. (You should look at the creation of "fillingColorForDrawingPDColor").
That's because C0 (the lower bound, value 0) is (1, 1, 1) which is white. C1 (the upper bound, value 1) is (0, 0, 1) which is blue. The colors between are calculated by the tint transform function.
Update:
This code
components = new float[] { r / 255f, g / 255f, b / 255f };
...
return new PDColor(components, seperation);
shows a misunderstanding. A separation color needs only one color, which is between 0 and 1. That the final color is "colorful" is because of the values in C0 (minimum) and C1 (maximum) and the function to create the colors between.
The RGB is the "destination" colorspace for the alternative colorspace. Separation colors are for "special" colors, e.g. gold, glitter, metallic, fluorescent, etc. The alternative colorspace simulates this for cases where the actual color isn't available (e.g. display).
In the example for PDSeparation in the source code (or here) there is this
PDColor color = new PDColor(new float[]{0.5f}, spotColorSpace);
Answered By - Tilman Hausherr
Answer Checked By - Marilyn (JavaFixing Volunteer)