
import javax.swing.*;
import java.awt.*;
import com.lowagie.text.*;
import com.lowagie.text.pdf.*;
import java.awt.geom.GeneralPath;
import java.io.FileOutputStream;

public class TransparentGradient2 extends JComponent {

    boolean once = true;
    final int width = 400;
    final int height = 300;
    GeneralPath rectPath, triPath;
    final Color transparentColour = new Color(1F, 1F, 1F, 0F);

    public static void main(String[] args) {
        new TransparentGradient2();
    }

    public TransparentGradient2() {
        makePaths();
        JFrame frame = new JFrame("TransparentGradient2");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(this);
        frame.setSize(width, height);
        frame.setVisible(true);
    }

    /** Construct two GeneralPath's */
    public void makePaths() {
        rectPath = new GeneralPath();
        rectPath.moveTo(50, 0);
        rectPath.lineTo(100, 0);
        rectPath.lineTo(100, 300);
        rectPath.lineTo(50, 300);
        rectPath.closePath();

        triPath = new GeneralPath();
        triPath.moveTo(0, 50);
        triPath.lineTo(50, 150);
        triPath.lineTo(100, 50);
        triPath.closePath();
    }

    @Override
    public void paint(Graphics g) {
        // Draw the content
        draw((Graphics2D) g);

        //Make the PDF only once
        if (once) {
            makePDF();
            once = false;
        }
    }

    public void draw(Graphics2D g2) {
        // Draw the white background
        g2.setColor(Color.WHITE);
        g2.fillRect(0, 0, width, height);

        // If this is the PDF renderer then get the PdfContentByte
        PdfContentByte cb = null;
        if (g2 instanceof PdfGraphics2D) {
            PdfGraphics2D g2pdf = (PdfGraphics2D) g2;
            cb = g2pdf.getContent();
        }

        // Red Rectangle
        GradientPaint redGradient = new GradientPaint(50, 0, Color.RED, 100, 0, transparentColour);
        // If making a pdf then do some custom gradient action
        if (cb != null) {
            drawTransparentGradient(cb, g2, redGradient, rectPath);
        } else {
            g2.setPaint(redGradient);
            g2.fill(rectPath);
        }

        // Blue Triangle
        GradientPaint blueGradient = new GradientPaint(0, 50, Color.BLUE, 0, 150, transparentColour);
        // If making a pdf then do some custom gradient action
        if (cb != null) {
            drawTransparentGradient(cb, g2, blueGradient, triPath);
        } else {
            g2.setPaint(blueGradient);
            g2.fill(triPath);
        }
    }

    public void drawTransparentGradient(PdfContentByte cb, Graphics2D g2, GradientPaint gp, GeneralPath path) {
        // Clipping area
        g2.fill(path);
        cb.clip();
        cb.newPath();
        
        //Create template
        PdfTemplate template = cb.createTemplate(width, height);

        //Prepare transparent group
        PdfTransparencyGroup transGroup = new PdfTransparencyGroup();
        transGroup.put(PdfName.CS, PdfName.DEVICERGB);
        transGroup.setIsolated(true);
        transGroup.setKnockout(false);
        template.setGroup(transGroup);

        //Prepare graphic state
        PdfGState gState = new PdfGState();
        PdfDictionary maskDict = new PdfDictionary();
        maskDict.put(PdfName.TYPE, PdfName.MASK);
        maskDict.put(PdfName.S, new PdfName("Luminosity"));
        maskDict.put(new PdfName("G"), template.getIndirectReference());
        gState.put(PdfName.SMASK, maskDict);
        cb.setGState(gState);

        // Create a gradient to use as the mask
        // Also flip the Y location
        PdfShading shading = PdfShading.simpleAxial(
                cb.getPdfWriter(),
                (float) gp.getPoint1().getX(),
                (float) (height - gp.getPoint1().getY()),
                (float) gp.getPoint2().getX(),
                (float) (height - gp.getPoint2().getY()),
                Color.BLACK,
                Color.WHITE);
        template.paintShading(shading);
        
        // Draw the actual colour under the mask
        g2.setColor(gp.getColor1());
        g2.fill(path);
    }

    public void makePDF() {
        // step 1: creation of a document-object
        Document document = new Document(new com.lowagie.text.Rectangle(width, height), 0, 0, 0, 0);
        try {
            // step 2: creation of the writer
            PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("TransparentGradient2.pdf"));
            // step 3: we open the document
            document.open();
            // step 4: we grab the ContentByte and do some stuff with it
            PdfContentByte cb = writer.getDirectContent();
            Graphics2D g2pdf = cb.createGraphics(width, height);
            draw(g2pdf);
            g2pdf.dispose();
        } catch (Exception ex) {
        }
        // step 5: we close the document
        document.close();
    }
}
