Giter VIP home page Giter VIP logo

Comments (6)

rototor avatar rototor commented on May 24, 2024

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

if( env.isXORMode() ) {
state.ensureExtendedState();
state.pdExtendedGraphicsState.getCOSObject().setItem(COSName.BM, COSName.????);
}

That should be all you need to do. Please provide a test for this too.

from pdfbox-graphics2d.

gredler avatar gredler commented on May 24, 2024

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):

PDF supports some of the xfer modes used in Skia directly. For those, it is simply a matter of setting the blend mode in the graphic state to the appropriate value (Normal/SrcOver, Multiply, Screen, Overlay, Darken, Lighten, !ColorDOdge, ColorBurn, HardLight, SoftLight, Difference, Exclusion). Aside from the standard SrcOver mode, PDF does not directly support the porter-duff xfer modes though. Most of them (Clear, SrcMode, DstMode, DstOver, SrcIn, DstIn, SrcOut, DstOut) can be emulated by various means, mostly by creating form x-objects out of part of the content and drawing it with a another form x-object as a mask. I have not figured out how to emulate the following modes: SrcATop, DstATop, Xor, Plus.

from pdfbox-graphics2d.

rototor avatar rototor commented on May 24, 2024

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.

from pdfbox-graphics2d.

gredler avatar gredler commented on May 24, 2024

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);
    }

blending.pdf

from pdfbox-graphics2d.

rototor avatar rototor commented on May 24, 2024

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?

from pdfbox-graphics2d.

gredler avatar gredler commented on May 24, 2024

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 :-)

from pdfbox-graphics2d.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.