JDK-8372335 : Printing cuts off edges differently when embedding a semi transparent text
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 23,25,26
  • Priority: P3
  • Status: Open
  • Resolution: Unresolved
  • OS: windows_10
  • CPU: x86_64
  • Submitted: 2025-11-19
  • Updated: 2025-11-24
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.
JDK 26
26Unresolved
Related Reports
Causes :  
Description
ADDITIONAL SYSTEM INFORMATION :
The described problem  occurs with 25.0.1 and 23.0.5, but not with 21.0.8 or 17.0.15.

It only occurs when printing on windows on a real printer. Using a PDF printer (without non-printable area) does not lead to the problem, as there is no non-printable area on these printer.

A DESCRIPTION OF THE PROBLEM :
There are obviously 2 print modes in sun.print.RasterPrinterJob.printPage() as sun.awt.windows.WPrinterJob.createPathGraphics() creates no PathGraphics when compositing is used.

This leads to a different printout when printing a semi transparent text somewhere on the page.

In java 17.0.15 I even had the problem, that pdfs were printed with a shift, but I cannot make a short reproducable code to demonstrate it.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Execute the test case code. Use a real printer with non-printable area. Two pages will be printed.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The corner on the printout should be the same. The only exception should be the text.
ACTUAL -
The corners are cut off at the printout with the semi transparent text (although they are not at the printout area)

---------- BEGIN SOURCE ----------
package de.empic.printerproblem;

import java.awt.*;
import java.awt.print.*;

public class PrinterProblemMain {

    static boolean withCompositeGraphics = false;

    public static void main(String[] args) {
        try {
            VirtualPageable virtualPageable = new VirtualPageable();
            PrinterJob job = PrinterJob.getPrinterJob();
            job.setPageable(virtualPageable);
            if (job.printDialog()) {
                job.print();
                withCompositeGraphics = true;
                job.print();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    static class VirtualPageable implements Pageable {
        private final Printable printable = new VirtualPrintable();

        @Override
        public int getNumberOfPages() {
            return 1;
        }

        @Override
        public PageFormat getPageFormat(int pageIndex) throws IndexOutOfBoundsException {
            PageFormat returnValue = new PageFormat();
            returnValue.setOrientation(PageFormat.REVERSE_LANDSCAPE);
            return returnValue;
        }

        @Override
        public Printable getPrintable(int pageIndex) throws IndexOutOfBoundsException {
            return pageIndex == 0 ? printable : null;
        }
    }

    static class VirtualPrintable implements Printable {


        @Override
        public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException {
            // Only a single page should be printed
            if (pageIndex > 0 || graphics == null) {
                return NO_SUCH_PAGE;
            }

            Graphics2D g2 = (Graphics2D) graphics;

            double ix = pageFormat.getImageableX();
            double iy = pageFormat.getImageableY();
            double iw = pageFormat.getImageableWidth();
            double ih = pageFormat.getImageableHeight();
            double offset = 1.0;
            double d = 20.0;

            // Draw circles and numbers 1..4 centered in each circle
            Point[] centersOfCornerCircles = new Point[]{
                    new Point((int) Math.round(ix + offset + d / 2.0), (int) Math.round(iy + offset + d / 2.0)),                                 // top-left
                    new Point((int) Math.round(ix + iw - offset - d / 2.0), (int) Math.round(iy + offset + d / 2.0)),                           // top-right
                    new Point((int) Math.round(ix + offset + d / 2.0), (int) Math.round(iy + ih - offset - d / 2.0)),                           // bottom-left
                    new Point((int) Math.round(ix + iw - offset - d / 2.0), (int) Math.round(iy + ih - offset - d / 2.0))                        // bottom-right
            };
            Font originalFont = g2.getFont();
            Font font = originalFont.deriveFont(12f);
            g2.setFont(font);
            g2.setStroke(new BasicStroke(1.0f));
            g2.setColor(Color.BLACK);

            for (int i = 0; i < centersOfCornerCircles.length; i++) {
                Point c = centersOfCornerCircles[i];
                int x = (int) Math.round(c.x - d / 2.0);
                int y = (int) Math.round(c.y - d / 2.0);

                // Circle
                g2.drawOval(x, y, (int) Math.round(d), (int) Math.round(d));

                // Number centered
                String text = String.valueOf(i + 1);
                FontMetrics fm = g2.getFontMetrics();
                int textWidth = fm.stringWidth(text);
                int textAscent = fm.getAscent();
                int textDescent = fm.getDescent();
                int tx = (int) Math.round(c.x - textWidth / 2.0);
                int ty = (int) Math.round(c.y + (textAscent - textDescent) / 2.0);
                g2.drawString(text, tx, ty);
            }

            // The bug happens, when a composite graphics element is rendered
            if (withCompositeGraphics) {
                Graphics2D gAlpha = (Graphics2D) g2.create();
                try {
                    gAlpha.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
                    gAlpha.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.25f));

                    String centerText = "Composite Graphics";
                    int baseSize = 48;
                    Font centerFont = originalFont.deriveFont(Font.BOLD, baseSize);
                    gAlpha.setFont(centerFont);
                    FontMetrics cfm = gAlpha.getFontMetrics();
                    int textWidth = cfm.stringWidth(centerText);
                    double maxWidth = iw * 0.8;
                    if (textWidth > maxWidth && textWidth > 0) {
                        float scaledSize = (float) (baseSize * (maxWidth / textWidth));
                        scaledSize = Math.max(18f, scaledSize);
                        centerFont = originalFont.deriveFont(Font.BOLD, scaledSize);
                        gAlpha.setFont(centerFont);
                        cfm = gAlpha.getFontMetrics();
                        textWidth = cfm.stringWidth(centerText);
                    }

                    int textAscent = cfm.getAscent();
                    int textDescent = cfm.getDescent();

                    int cx = (int) Math.round(ix + iw / 2.0);
                    int cy = (int) Math.round(iy + ih / 2.0);
                    int tx = (int) Math.round(cx - textWidth / 2.0);
                    int ty = (int) Math.round(cy + (textAscent - textDescent) / 2.0);

                    gAlpha.setColor(Color.BLACK);
                    gAlpha.drawString(centerText, tx, ty);
                } finally {
                    gAlpha.dispose();
                }
            }
            return PAGE_EXISTS;
        }
    }
}

---------- END SOURCE ----------


Comments
Failing from jdk23-b11 due to this fix JDK-8307246 from Author: vtstydev <vtsty.dev@gmail.com>
24-11-2025

Additional Information from Submitter: ======================================== I finally made it to get the bug also to work on java 17 / java 21 (but this bug does not affect java 23 / java 25 ) import java.awt.*; import java.awt.print.*; public class PrinterProblemMain { static boolean withCompositeGraphics = false; public static void main(String[] args) { try { VirtualPageable virtualPageable = new VirtualPageable(); PrinterJob job = PrinterJob.getPrinterJob(); job.setPageable(virtualPageable); if (job.printDialog()) { job.print(); withCompositeGraphics = true; job.print(); } } catch (Exception e) { e.printStackTrace(); } } static class VirtualPageable implements Pageable { private final Printable printable = new VirtualPrintable(); @Override public int getNumberOfPages() { return 1; } @Override public PageFormat getPageFormat(int pageIndex) throws IndexOutOfBoundsException { PageFormat returnValue = new PageFormat(); Paper paper = new Paper(); // A4 paper.setSize(595, 842); paper.setImageableArea(0, 0, 595, 842); returnValue.setPaper(paper); returnValue.setOrientation(PageFormat.REVERSE_LANDSCAPE); return returnValue; } @Override public Printable getPrintable(int pageIndex) throws IndexOutOfBoundsException { return pageIndex == 0 ? printable : null; } } static class VirtualPrintable implements Printable { @Override public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException { // Only a single page should be printed if (pageIndex > 0 || graphics == null) { return NO_SUCH_PAGE; } Graphics2D g2 = (Graphics2D) graphics; double ix = pageFormat.getImageableX(); double iy = pageFormat.getImageableY(); double iw = pageFormat.getImageableWidth(); double ih = pageFormat.getImageableHeight(); double offset = 10.0; double d = 20.0; // Draw circles and numbers 1..4 centered in each circle Point[] centersOfCornerCircles = new Point[]{ new Point((int) Math.round(ix + offset + d / 2.0), (int) Math.round(iy + offset + d / 2.0)), // top-left new Point((int) Math.round(ix + iw - offset - d / 2.0), (int) Math.round(iy + offset + d / 2.0)), // top-right new Point((int) Math.round(ix + offset + d / 2.0), (int) Math.round(iy + ih - offset - d / 2.0)), // bottom-left new Point((int) Math.round(ix + iw - offset - d / 2.0), (int) Math.round(iy + ih - offset - d / 2.0)) // bottom-right }; Font originalFont = g2.getFont(); Font font = originalFont.deriveFont(12f); g2.setFont(font); g2.setStroke(new BasicStroke(1.0f)); g2.setColor(Color.BLACK); for (int i = 0; i < centersOfCornerCircles.length; i++) { Point c = centersOfCornerCircles[i]; int x = (int) Math.round(c.x - d / 2.0); int y = (int) Math.round(c.y - d / 2.0); // Circle g2.drawOval(x, y, (int) Math.round(d), (int) Math.round(d)); // Number centered String text = String.valueOf(i + 1); FontMetrics fm = g2.getFontMetrics(); int textWidth = fm.stringWidth(text); int textAscent = fm.getAscent(); int textDescent = fm.getDescent(); int tx = (int) Math.round(c.x - textWidth / 2.0); int ty = (int) Math.round(c.y + (textAscent - textDescent) / 2.0); g2.drawString(text, tx, ty); } // The bug happens, when a composite graphics element is rendered if (withCompositeGraphics) { Graphics2D gAlpha = (Graphics2D) g2.create(); try { gAlpha.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); gAlpha.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.25f)); String centerText = "Composite Graphics"; int baseSize = 48; Font centerFont = originalFont.deriveFont(Font.BOLD, baseSize); gAlpha.setFont(centerFont); FontMetrics cfm = gAlpha.getFontMetrics(); int textWidth = cfm.stringWidth(centerText); double maxWidth = iw * 0.8; if (textWidth > maxWidth && textWidth > 0) { float scaledSize = (float) (baseSize * (maxWidth / textWidth)); scaledSize = Math.max(18f, scaledSize); centerFont = originalFont.deriveFont(Font.BOLD, scaledSize); gAlpha.setFont(centerFont); cfm = gAlpha.getFontMetrics(); textWidth = cfm.stringWidth(centerText); } int textAscent = cfm.getAscent(); int textDescent = cfm.getDescent(); int cx = (int) Math.round(ix + iw / 2.0); int cy = (int) Math.round(iy + ih / 2.0); int tx = (int) Math.round(cx - textWidth / 2.0); int ty = (int) Math.round(cy + (textAscent - textDescent) / 2.0); gAlpha.setColor(Color.BLACK); gAlpha.drawString(centerText, tx, ty); } finally { gAlpha.dispose(); } } return PAGE_EXISTS; } } }
24-11-2025

Checked with attached testcase in Windows 11, issue is reproducible(attached snapshot of the print) Test Result ========= JDK 26ea24 :Fail JDK 25.0.1:Fail JDK 21.0.9:Pass JDK 17.0.17:Pass JDK 11.0.29:Pass ILW=MMH=P3 =================== Impact: Medium - Regression Likelihood: Medium - Frequently reproducible Workaround: High - No Workaround.
21-11-2025