-
Notifications
You must be signed in to change notification settings - Fork 22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
setXORMode / setPaintMode not implemented #14
Comments
Yes, it's not used at the moment. I just completely forgot about it ... Responsible for setting the paint stuff is the PdfBoxGraphics2DPaintApplier, to get the info about the XOR Mode into it you can just extend the IPaintEnv with a "boolean isXORMode()" method. Within the PdfBoxGraphics2DPaintApplier#applyMethod() you would do a
That should be all you need to do. Please provide a test for this too. |
Do you know what the blend mode would be, though? My local tests haven't been very productive, and I'm a little worried after running across this paragraph on the Skia website (PDF Theory of Operation):
|
Hmm, I would try Exclusive and ColorDodge - if those do not create an similar effect like XOR then we are out of luck... I can document the fact that XOR mode is not working due to technical PDF limits. |
I've tried to test the absolute simplest scenario (monochrome black and white) and Difference seems like it should work like XOR mode in this simple scenario. However, while painting white over white results in black as expected, painting white over black does not result in white, but rather some brownish color. This doesn't make sense to me based on the my understanding of the color space (RGB) and the Difference blend mode function ( B(cb, cs) = | cb - cs| ). Any idea why it wouldn't work even in this simplest of test cases? Vanilla PDFBox test code which generates the attached test PDF file: @Test
public void testAllBlendingModes() throws Exception {
List< COSName > blendModeNames = Arrays.asList(COSName.NORMAL, COSName.MULTIPLY, COSName.SCREEN, COSName.OVERLAY,
COSName.DARKEN, COSName.LIGHTEN, COSName.COLOR_DODGE, COSName.COLOR_BURN, COSName.HARD_LIGHT,
COSName.SOFT_LIGHT, COSName.DIFFERENCE, COSName.EXCLUSION, COSName.HUE, COSName.SATURATION,
COSName.COLOR, COSName.LUMINOSITY);
PDDocument document = new PDDocument();
PDPage page = new PDPage(new PDRectangle(400, 800));
document.addPage(page);
try (PDPageContentStream contentStream = new PDPageContentStream(document, page, AppendMode.APPEND, false)) {
contentStream.setNonStrokingColor(Color.WHITE);
contentStream.addRect(0, 0, 400, 800);
contentStream.fill();
contentStream.setNonStrokingColor(Color.BLACK);
contentStream.addRect(0, 0, 200, 800);
contentStream.fill();
int y = 10;
for (int i = 0; i < blendModeNames.size(); i++) {
COSName blendModeName = blendModeNames.get(i);
drawRow(contentStream, Color.BLACK, blendModeName, y);
y += 20;
}
for (int i = 0; i < blendModeNames.size(); i++) {
COSName blendModeName = blendModeNames.get(i);
drawRow(contentStream, Color.WHITE, blendModeName, y);
y += 20;
}
}
document.save(new File("blending.pdf"));
}
private static void drawRow(PDPageContentStream contentStream, Color color, COSName blendModeName, int y) throws IOException {
contentStream.setNonStrokingColor(color);
contentStream.setGraphicsStateParameters(blendingMode(blendModeName));
contentStream.addRect(100, y, 300, 10);
contentStream.fill();
contentStream.beginText();
contentStream.setNonStrokingColor(Color.WHITE);
contentStream.setGraphicsStateParameters(blendingMode(COSName.NORMAL));
contentStream.newLineAtOffset(0, y);
contentStream.setFont(PDType1Font.HELVETICA, 9);
contentStream.showText(blendModeName.getName() + " (" + (Color.WHITE.equals(color) ? "white" : "black") + ")");
contentStream.endText();
}
private static PDExtendedGraphicsState blendingMode(COSName blendModeName) throws IOException {
COSDictionary dict = new COSDictionary();
dict.setItem(COSName.TYPE, COSName.EXT_G_STATE);
if (blendModeName != null) {
dict.setItem(COSName.BM, blendModeName);
}
return new PDExtendedGraphicsState(dict);
} |
I had a look into the PDF spec, and I also don't think that there is a way to correctly implement the XOR mode. I've now documented this in the README. Thanks for pointing this out. Beside this I see the XOR mode as something very useful for interactive UI stuff (e.g. drag boxes, ...) but nothing I would normally want in a PDF. What kind of stuff do you want to draw into the PDF which needs the XOR mode? |
Yep, it's looking that way to me, as well. I was thinking it would at least be possible for monochrome and grayscale color spaces (with difference blending mode), but it's looking less and less likely... the worst part is not understanding why, though :-) |
The setXORMode method sets an instance variable, but it never appears to be used. I'd submit a pull request, but I'm not sure how to implement this (aside from a rough idea that the exclusion and difference blend modes might be useful).
The text was updated successfully, but these errors were encountered: