Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8041902

When printing, polylines are not rendered as joined

    XMLWordPrintable

Details

    • Bug
    • Resolution: Fixed
    • P3
    • 9
    • 7u21, 8, 9
    • client-libs
    • 2d
    • b24
    • windows_7

    Backports

      Description

        FULL PRODUCT VERSION :
        java version " 1.7.0_21 "
        Java(TM) SE Runtime Environment (build 1.7.0_21-b11)
        Java HotSpot(TM) Client VM (build 23.21-b01, mixed mode)

        ADDITIONAL OS VERSION INFORMATION :
        Microsoft Windows [Version 6.1.7601]

        EXTRA RELEVANT SYSTEM CONFIGURATION :
        Problem can be seen on physical printer (HP Laserjet M4345) as well as 'virtual' printer (Microsoft XPS Document Writer)

        A DESCRIPTION OF THE PROBLEM :
        A polyline is created (multiple points). When this is drawn to the Graphics2D via the graphics.drawPolyline() method while printing, the polyline segments are drawn individually.

        This has the effect of the ends overlapping instead of being drawn using the strokes join definition (miter specifically).

        This is also seen as a difference compared with the on screen rendering; the join definition *is* used then.

        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        Test case included that draws the polyline via the graphics.drawPolyline() as well as the same points via a General Path. Main steps are below:

        // KEY: The Graphics 2D must be for a print
        Graphics2D g2d = (Graphics2D) graphics;
        g2d.setStroke(new BasicStroke(50, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 10.0F, null, 1.0F));

        int[] x2Points = {100, 300, 500};
        int[] y2Points = {300, 700, 300};
        g.drawPolyline(xp, yp, xp.length);


        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        Would expect the graphics.drawPolyline() to draw the correct joins when printing and so look the same as the on screen rendering.
        ACTUAL -
        The polyline joins are not drawn correctly, those on the general path are.

        When drawing to the screen, they both look the same.

        REPRODUCIBILITY :
        This bug can be reproduced always.

        ---------- BEGIN SOURCE ----------
        import java.awt.*;
        import java.awt.geom.*;
        import java.awt.print.*;

        public class PolylinePrinter implements Printable
        {

        public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws
        PrinterException
        {

        if (pageIndex > 0) {
        return NO_SUCH_PAGE;
        }

        Graphics2D g2d = (Graphics2D) graphics;
        g2d.setStroke(new BasicStroke(50, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 10.0F, null, 1.0F));

        int[] x2Points = {100, 300, 500};
        int[] y2Points = {300, 700, 300};
        drawPolylineGOOD(g2d, x2Points, y2Points);
        drawPolylineBAD(g2d, x2Points, y2Points);

        return PAGE_EXISTS;
        }

        private void drawPolylineGOOD(Graphics2D g2d, int[] x2Points, int[] y2Points)
        {
        GeneralPath polyline = new GeneralPath(Path2D.WIND_EVEN_ODD, x2Points.length);

        polyline.moveTo(x2Points[0], y2Points[0]);

        for (int index = 1; index < x2Points.length; index++) {
        polyline.lineTo(x2Points[index], y2Points[index]);
        }
        g2d.draw(polyline);
        }

        private void drawPolylineBAD(Graphics2D g, int[] xp, int[] yp)
        {
        int offset = -200;
        g.translate(0, offset);
        g.drawPolyline(xp, yp, xp.length);
        }

        public PolylinePrinter() throws PrinterException
        {
        PrinterJob job = PrinterJob.getPrinterJob();
        job.setPrintable(this);
        boolean ok = job.printDialog();
        if (ok) {
        job.print();
        }
        }

        public static void main(String[] args) throws PrinterException
        {
        new PolylinePrinter();
        }
        }
        ---------- END SOURCE ----------

        CUSTOMER SUBMITTED WORKAROUND :
        Taking the same points as the polyline, creating a general path and drawing that work as expected.

        instead of:

            g2d.drawPolyline(xp, yp, xp.length)

        ... use:

          GeneralPath gp = new GeneralPath(Path2D.WIND_EVEN_ODD, xp.length);
          gp.moveTo(xp[0], yp[0]);
          for (int index = 1; index < xp.length; index++) {
              gp.lineTo(xp[index], yp[index]);
          }
          g2d.draw(gp);

        Attachments

          Issue Links

            Activity

              People

                prr Philip Race
                webbuggrp Webbug Group
                Votes:
                0 Vote for this issue
                Watchers:
                4 Start watching this issue

                Dates

                  Created:
                  Updated:
                  Resolved: