Printing cuts off edges differently when embedding a semi transparent text

XMLWordPrintable

    • x86_64
    • windows_10

      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 ----------

        1. PrinterProblemMain.java
          6 kB
          Praveen Narayanaswamy
        2. IMG_3629.jpg
          889 kB
          Praveen Narayanaswamy
        3. IMG_3631.jpg
          907 kB
          Praveen Narayanaswamy
        4. IMG_3628.jpg
          784 kB
          Praveen Narayanaswamy
        5. IMG_3630.jpg
          912 kB
          Praveen Narayanaswamy
        6. 11.0.29.pdf
          308 kB
          Praveen Narayanaswamy
        7. 21.0.9.pdf
          302 kB
          Praveen Narayanaswamy
        8. 17.0.17.pdf
          299 kB
          Praveen Narayanaswamy

            Assignee:
            Prasanta Sadhukhan
            Reporter:
            Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated: