JDK-8215940 : LinearGradientPaint not extending start color when printing on OSX
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 8u20,9,11,12
  • Priority: P3
  • Status: Open
  • Resolution: Unresolved
  • OS: os_x
  • CPU: x86
  • Submitted: 2018-12-20
  • Updated: 2019-01-02
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbdUnresolved
Description
ADDITIONAL SYSTEM INFORMATION :
The issue is specific to OSX.  I can confirm that in Windows the shape is correctly printed.

A DESCRIPTION OF THE PROBLEM :
From the javadoc on LinearGradientPaint:  in the event that the user does not set the first keyframe value equal to 0 and/or the last keyframe value equal to 1, keyframes will be created at these positions and the first and last colors will be replicated there.  When a nonzero start keyframe is provided and cycle = NO_CYCLE, the start keyframe is rendered correctly on screen but not when printing. 

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Fill a shape with a solid color.  Then set the paint to a LinearGradientPaint with the first keyframe = non zero, and fill again.  The first keyframe is not extended to 0, revealing the solid color underneath, but only when printing.  It is rendered correctly to the screen.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
It is expected that the printed result will look like the screen.
ACTUAL -
The printed result is different that the screen rendering.

---------- BEGIN SOURCE ----------

import java.awt.*;
import java.awt.print.*;
import javax.swing.*;

public class TestGradient {

    public static class TwoRectangles extends JComponent {

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D)g;
        g2d.setColor(Color.RED);
        
        Rectangle r = new Rectangle(0, 75, 500, 150);
        g2d.fill(r);  //paint a red opaque rectangle

        LinearGradientPaint p = new LinearGradientPaint(100, 100, 400, 100, new float[]{0.0f, 1.0f}, new Color[]{Color.GREEN, Color.BLUE}, MultipleGradientPaint.CycleMethod.NO_CYCLE);
        g2d.setPaint(p);
        g2d.fill(r);  //paint a green to blue gradient
    }
}

public static final TwoRectangles rect = new TwoRectangles();

public static void main(String[] args) throws PrinterException {

    JFrame f  = new JFrame("Test Gradient");
    f.setLayout(new BorderLayout());
    f.add(rect);
    f.setSize(600, 300);
    f.setVisible(true);


    PrinterJob printJob = PrinterJob.getPrinterJob();


    Printable prt = new Printable() {

        @Override
        public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException {
            if (pageIndex > 0) 
                return(NO_SUCH_PAGE);

            rect.print(graphics);      
            return PAGE_EXISTS;
        }

    };

    printJob.setPrintable(prt);
    if (printJob.printDialog()) 
          printJob.print();

  } 
 }
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Manually add a keyframe at zero with the color equal to the color of the previous first keyframe.

FREQUENCY : always



Comments
Reported against mac OS X, When a nonzero start keyframe is provided and cycle = NO_CYCLE, the start keyframe is rendered correctly on screen but not when printing. Results (mac): =========== 8u20: Fail 9: Fail 11: Fail 12 ea b 25: Fail The shape is printed correctly in Windows (see attached screenshots for mac and windows as reference). To verify, run the attached test case with respective JDK versions and platform.
02-01-2019

Additional note: ================== The previous description incorrectly referred to the keyframes as being the issue. In fact in the source example the first keyframe is set to zero. The issue is the start position in LinearGradientPaint (100, 100) is not at the edge of the shape and the gradient is not extended to the edge. There is no workaround except to always start the LinearGradientPaint at the edge of a shape (even then that might not be enough if the gradient runs on a diagonal). ==================
28-12-2018