Question

If i use

PdfContentByte cb = writer.getDirectContent();
cb.setColorFill(new CMYKColor(c, m, y, k));

it's straightforward. However i have some Swing components, that draw self in Graphics2D, it is very convince to use something like that:

PdfContentByte cb = writer.getDirectContent();
Graphics2D g2 cb.createGraphics(w, h);
mySwingComponent.paint(g2);
g2.dispose();

It works fine, but the colors are translated form java's sRGB to CMYK by iText. I want to draw direct with CMYK colors. I am trying to do it so in my Swing component

MySwingComponent extends JComponenet {
    void paint(Graphics2D g2) {
        g.setColor(new com.lowagie.text.pdf.CMYKColor(0, 0, 0, 1));
    }
}

Unfortunately it just does not work. Is there some way exactly to specify which CMYK color will be painted?

P.S. Background of my problem is that if i draw something in garyscale, then in Adobe Illustrator in PDF color is not just (0, 0, 0, 0.4), but like (0.1, 0.15, 0.2, 0.4f).

UPD: I have solution now: Just using g2.setPaint(new CMYKColor(1f, 0.0f, 0.0f, 0.0f)); in your paint(Graphics2D g2) will force iText to produce CMYK Pdf

Was it helpful?

Solution

I had your exact problem. I messed around with the API but finally had to look at the source code. I came up with two solutions.

The first solution is to modify the source code to fit your needs (after all, isn't that the definition of free software?). The source code can be extracted from the itextpdf-5.1.3-sources.jar file (or whatever version of the library you have). The line causing the CMYK/RGB issue is line 1650 of the PdfGraphics2D.java file (com/itextpdf/text/pdf/PdfGraphics2D.java). You should see a line that says:

cb.setColorFill(new BaseColor(color));

If you want a quick and dirty fix, simply change that line to:

cb.setColorFill(new CMYKColor(0f, 0f, 0f, 1f));

This, of course, limits you to one color, but now that you know which line is handling the actual color, you can modify the class and add some functionality/state (if you need it). You'll need to add

import com.itextpdf.text.pdf.CMYKColor;

to the top of the file as well. N.B. Line 1650 handles fills. If you're doing strokes, simply modify the same thing in the else statement (it should be clear when you look at the file).

Compile the source:

javac -cp path/to/itextpdf-5.1.3.jar path/to/PdfGraphics2D.java

Change to the root of the itextpdf-5.1.3-sources folder and update the jar:

jar uf path/to/itextpdf-5.1.3.jar com/itextpdf/text/pdf/PdfGraphics2D.class

And that's it! Your PDF file will now render the color using the CMYK value you specified. This is great for something simple, but if you need more functionality, you will have to modify the PdfGraphics2D class some more. I was personally using this to draw CMYK black fonts using the drawGlyphVector method.

Second solution:

If the first solution doesn't work for you, you can always edit/parse the PostScript directly. In your method that is creating the PDF, add the line Document.compress = false; after you instantiate the PdfWriter. Now you can view the PDF file in a text editor. Search around and you'll find some lines like 0 0 0 1 k or 0 0 1 rg These lines are setting colors (CMYK black and RGB black, respectively). Lowercase letters after the color values (which are floats, it seems) mean fill and uppercase is stroke. So 0 0 0 1 K would be a CMYK black stroke and so forth.

You could read the PDF in line by line and basically do a "search and replace" (in Java, programmatically, of course) for lines ending in "rg". Hope that makes sense. Not terribly fast, since this requires an extra disk read and write...

Hope that helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top