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

Printing of AWT components on windows is not working

    Details

    • Subcomponent:
    • Introduced In Build:
      b12
    • Introduced In Version:
    • Resolved In Build:
      b27
    • CPU:
      generic, x86
    • OS:
      windows

      Backports

        Description

        Printing of AWT componenst is not working both with old and new Plug-in on IE6/IE7, FF2/FF3 and mozilla browsers. This regression got introduced in 6u10-b12. Everything worked fine till 6u10-b11. With the current build printing is working fine if applet contains Swing component or painting is done directly on Applet panel.

        Steps to reproduce:
        -----------
        1) Install latest 6u10
        2) Try to load any of the following applets
        http://java.sun.com/products/plugin/1.5.0/demos/applets/ArcTest/example1.html
        (this applet contains AWT Text fields and Buttons)
        or
        http://sqeweb.sfbay.sun.com/deployment2/jitu/plug-bug/ALC/PrintThreadNew.html

        3) Try to print applets using Browser File > Print menu option

        If AWT components fails to print then bug is reproduced

        Repeat all the above steps with old Plug-in

        Non-AWT applets(Printing should work fine applets listed below)
        http://java.sun.com/products/plugin/1.5.0/demos/jfc/SwingSet2/SwingSet2.html
        http://java.sun.com/products/plugin/1.5.0/demos/applets/Clock/example1.html
        http://java.sun.com/products/plugin/1.5.0/demos/applets/SpreadSheet/example1.html
        http://java.sun.com/products/plugin/1.5.0/demos/applets/BarChart/example1.html

          Issue Links

            Activity

            Hide
            prr Philip Race added a comment -
            BT2:EVALUATION

            Its not just applets. I'm seeing lots of problems in a standalone app using
            test/java/awt/PrintJob/PrintComponentTest/PrintComponentTest.java

            I suspect a z-ordering issue as WComponentPeer.createPrintedPixels() is
            apparently returning some data.
            Show
            prr Philip Race added a comment - BT2:EVALUATION Its not just applets. I'm seeing lots of problems in a standalone app using test/java/awt/PrintJob/PrintComponentTest/PrintComponentTest.java I suspect a z-ordering issue as WComponentPeer.createPrintedPixels() is apparently returning some data.
            Hide
            anthony Anthony Petrov (Inactive) added a comment -
            BT2:EVALUATION

            This is a regression of the fix for 6648996 (Frame.printAll() invoked on a non-opaque window prints black background).

            The problem is the type of the BufferedImage created in the WComponentPeer.print() method. It used to be BufferedImage.TYPE_INT_RGB, but with the fix for 6648996 it changed to BufferedImage.TYPE_INT_ARGB. W/o that change the non-opaque windows got printed with a black background instead of transparent background.

            It seems that the problem is the createPrintedPixels() method which draws heavyweight components with alpha value of zero. That's why they probably do not get printed.
            Show
            anthony Anthony Petrov (Inactive) added a comment - BT2:EVALUATION This is a regression of the fix for 6648996 (Frame.printAll() invoked on a non-opaque window prints black background). The problem is the type of the BufferedImage created in the WComponentPeer.print() method. It used to be BufferedImage.TYPE_INT_RGB, but with the fix for 6648996 it changed to BufferedImage.TYPE_INT_ARGB. W/o that change the non-opaque windows got printed with a black background instead of transparent background. It seems that the problem is the createPrintedPixels() method which draws heavyweight components with alpha value of zero. That's why they probably do not get printed.
            Hide
            anthony Anthony Petrov (Inactive) added a comment -
            BT2:EVALUATION

            The AwtComponent::CreatePrintedPixels() function did not ever write the alpha component of the printed pixels. Hence, the alpha in the pixels array was always zero. It didn't cause problems before the fix for 6648996 because TYPE_INT_RGB kind of BufferedImage was used which obviously ignored the alpha color component (when using its setRGB() method). However, when using the TYPE_INT_ARGB type, the BufferedImage started to respect the alpha component. As all alpha components were zeros, no heavyweight content was printed.

            The suggested fix resolves this issue manually filling the alpha color component when handling the WM_PRINT message for heavyweight components.
            Show
            anthony Anthony Petrov (Inactive) added a comment - BT2:EVALUATION The AwtComponent::CreatePrintedPixels() function did not ever write the alpha component of the printed pixels. Hence, the alpha in the pixels array was always zero. It didn't cause problems before the fix for 6648996 because TYPE_INT_RGB kind of BufferedImage was used which obviously ignored the alpha color component (when using its setRGB() method). However, when using the TYPE_INT_ARGB type, the BufferedImage started to respect the alpha component. As all alpha components were zeros, no heavyweight content was printed. The suggested fix resolves this issue manually filling the alpha color component when handling the WM_PRINT message for heavyweight components.
            Hide
            anthony Anthony Petrov (Inactive) added a comment -
            BT2:SUGGESTED FIX

            --- old/src/windows/native/sun/windows/awt_BitmapUtil.cpp 2008-07-01 16:53:17.000000000 +0400
            +++ new/src/windows/native/sun/windows/awt_BitmapUtil.cpp 2008-07-01 16:53:17.000000000 +0400
            @@ -396,3 +396,23 @@
                 return hDstBitmap;
             }
             
            +/**
            + * Creates a 32 bit ARGB bitmap. Returns the bitmap handle. The *bitmapBits
            + * receives a pointer to the location of the DIB bit values.
            + */
            +HBITMAP BitmapUtil::CreateARGBBitmap(int width, int height, void ** bitmapBits)
            +{
            + BITMAPINFOHEADER bmi;
            +
            + ::ZeroMemory(&bmi, sizeof(bmi));
            + bmi.biSize = sizeof(bmi);
            + bmi.biWidth = width;
            + bmi.biHeight = -height;
            + bmi.biPlanes = 1;
            + bmi.biBitCount = 32;
            + bmi.biCompression = BI_RGB;
            +
            + return ::CreateDIBSection(NULL, (BITMAPINFO *) & bmi, DIB_RGB_COLORS,
            + bitmapBits, NULL, 0);
            +}
            +
            --- old/src/windows/native/sun/windows/awt_BitmapUtil.h 2008-07-01 16:53:17.000000000 +0400
            +++ new/src/windows/native/sun/windows/awt_BitmapUtil.h 2008-07-01 16:53:17.000000000 +0400
            @@ -47,6 +47,12 @@
                  * simply makes a plain copy of the source without any blending.
                  */
                 static HBITMAP BlendCopy(HBITMAP hSrcBitmap, COLORREF blendColor, BYTE alpha);
            +
            + /**
            + * Creates a 32 bit ARGB bitmap. Returns the bitmap handle. The *bitmapBits
            + * receives a pointer to the location of the DIB bit values.
            + */
            + static HBITMAP CreateARGBBitmap(int width, int height, void ** bitmapBits);
             };
             
             #endif
            --- old/src/windows/native/sun/windows/awt_Component.cpp 2008-07-01 16:53:17.000000000 +0400
            +++ new/src/windows/native/sun/windows/awt_Component.cpp 2008-07-01 16:53:17.000000000 +0400
            @@ -11,6 +11,7 @@
             
             #include "jlong.h"
             #include "awt_AWTEvent.h"
            +#include "awt_BitmapUtil.h"
             #include "awt_Component.h"
             #include "awt_Cursor.h"
             #include "awt_Dimension.h"
            @@ -4825,6 +4826,27 @@
                 return hdc;
             }
             
            +void AwtComponent::FillBackground(HDC hDC, SIZE &size)
            +{
            + RECT eraseR = { 0, 0, size.cx, size.cy };
            + VERIFY(::FillRect(hDC, &eraseR, GetBackgroundBrush()));
            +}
            +
            +void AwtComponent::FillAlpha(void *bitmapBits, SIZE &size, BYTE alpha)
            +{
            + if (!bitmapBits) {
            + return;
            + }
            +
            + DWORD* dest = (DWORD*)bitmapBits;
            + //XXX: might be optimized to use one loop (int i = cy*cx; i > 0; i++).
            + for (int i = 0; i < size.cy; i++ ) {
            + for (int j = 0; j < size.cx; j++ ) {
            + ((BYTE*)(dest++))[3] = alpha;
            + }
            + }
            +}
            +
             jintArray AwtComponent::CreatePrintedPixels(SIZE &loc, SIZE &size) {
                 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
             
            @@ -4837,12 +4859,13 @@
                     return NULL;
                 }
                 HDC hMemoryDC = ::CreateCompatibleDC(hdc);
            - HBITMAP hBitmap = ::CreateCompatibleBitmap(hdc, size.cx, size.cy);
            + void *bitmapBits = NULL;
            + HBITMAP hBitmap = BitmapUtil::CreateARGBBitmap(size.cx, size.cy,
            + &bitmapBits);
                 HBITMAP hOldBitmap = (HBITMAP)::SelectObject(hMemoryDC, hBitmap);
                 SendMessage(WM_AWT_RELEASEDC, (WPARAM)hdc);
             
            - RECT eraseR = { 0, 0, size.cx, size.cy };
            - VERIFY(::FillRect(hMemoryDC, &eraseR, GetBackgroundBrush()));
            + FillBackground(hMemoryDC, size);
             
                 VERIFY(::SetWindowOrgEx(hMemoryDC, loc.cx, loc.cy, NULL));
             
            @@ -4850,6 +4873,14 @@
                 // above.
                 SendMessage(WM_PRINT, (WPARAM)hMemoryDC, PRF_CLIENT | PRF_NONCLIENT);
             
            + // First make sure the system completed any drawing to the bitmap.
            + ::GdiFlush();
            +
            + // WM_PRINT does not fill the alpha-channel of the ARGB bitmap
            + // leaving it equal to zero. Hence we need to fill it manually. Otherwise
            + // the pixels will be considered transparent when interpreting the data.
            + FillAlpha(bitmapBits, size, 0xFF);
            +
                 ::SelectObject(hMemoryDC, hOldBitmap);
             
                 BITMAPINFO bmi;
            --- old/src/windows/native/sun/windows/awt_Component.h 2008-07-01 16:53:18.000000000 +0400
            +++ new/src/windows/native/sun/windows/awt_Component.h 2008-07-01 16:53:18.000000000 +0400
            @@ -576,6 +576,11 @@
             
                 void UpdateColorModel();
             
            +protected:
            + //These functions are overridden in AwtWindow to handle non-opaque windows.
            + virtual void FillBackground(HDC hDC, SIZE &size);
            + virtual void FillAlpha(void *bitmapBits, SIZE &size, BYTE alpha);
            +public:
                 jintArray CreatePrintedPixels(SIZE &loc, SIZE &size);
             
                 static void * GetNativeFocusOwner();
            --- old/src/windows/native/sun/windows/awt_Window.cpp 2008-07-01 16:53:18.000000000 +0400
            +++ new/src/windows/native/sun/windows/awt_Window.cpp 2008-07-01 16:53:18.000000000 +0400
            @@ -2772,6 +2772,20 @@
                 ::LeaveCriticalSection(&contentBitmapCS);
             }
             
            +void AwtWindow::FillBackground(HDC hDC, SIZE &size)
            +{
            + if (isOpaque()) {
            + AwtCanvas::FillBackground(hDC, size);
            + }
            +}
            +
            +void AwtWindow::FillAlpha(void *bitmapBits, SIZE &size, BYTE alpha)
            +{
            + if (isOpaque()) {
            + AwtCanvas::FillAlpha(bitmapBits, size, alpha);
            + }
            +}
            +
             extern "C" {
             
             /*
            --- old/src/windows/native/sun/windows/awt_Window.h 2008-07-01 16:53:19.000000000 +0400
            +++ new/src/windows/native/sun/windows/awt_Window.h 2008-07-01 16:53:19.000000000 +0400
            @@ -291,6 +291,11 @@
                     return warningString != NULL;
                 }
             
            + //These are used in AwtComponent::CreatePrintedPixels. They are overridden
            + //here to handle non-opaque windows.
            + virtual void FillBackground(HDC hDC, SIZE &size);
            + virtual void FillAlpha(void *bitmapBits, SIZE &size, BYTE alpha);
            +
             private:
                 int m_screenNum;
            Show
            anthony Anthony Petrov (Inactive) added a comment - BT2:SUGGESTED FIX --- old/src/windows/native/sun/windows/awt_BitmapUtil.cpp 2008-07-01 16:53:17.000000000 +0400 +++ new/src/windows/native/sun/windows/awt_BitmapUtil.cpp 2008-07-01 16:53:17.000000000 +0400 @@ -396,3 +396,23 @@      return hDstBitmap;  }   +/** + * Creates a 32 bit ARGB bitmap. Returns the bitmap handle. The *bitmapBits + * receives a pointer to the location of the DIB bit values. + */ +HBITMAP BitmapUtil::CreateARGBBitmap(int width, int height, void ** bitmapBits) +{ + BITMAPINFOHEADER bmi; + + ::ZeroMemory(&bmi, sizeof(bmi)); + bmi.biSize = sizeof(bmi); + bmi.biWidth = width; + bmi.biHeight = -height; + bmi.biPlanes = 1; + bmi.biBitCount = 32; + bmi.biCompression = BI_RGB; + + return ::CreateDIBSection(NULL, (BITMAPINFO *) & bmi, DIB_RGB_COLORS, + bitmapBits, NULL, 0); +} + --- old/src/windows/native/sun/windows/awt_BitmapUtil.h 2008-07-01 16:53:17.000000000 +0400 +++ new/src/windows/native/sun/windows/awt_BitmapUtil.h 2008-07-01 16:53:17.000000000 +0400 @@ -47,6 +47,12 @@       * simply makes a plain copy of the source without any blending.       */      static HBITMAP BlendCopy(HBITMAP hSrcBitmap, COLORREF blendColor, BYTE alpha); + + /** + * Creates a 32 bit ARGB bitmap. Returns the bitmap handle. The *bitmapBits + * receives a pointer to the location of the DIB bit values. + */ + static HBITMAP CreateARGBBitmap(int width, int height, void ** bitmapBits);  };    #endif --- old/src/windows/native/sun/windows/awt_Component.cpp 2008-07-01 16:53:17.000000000 +0400 +++ new/src/windows/native/sun/windows/awt_Component.cpp 2008-07-01 16:53:17.000000000 +0400 @@ -11,6 +11,7 @@    #include "jlong.h"  #include "awt_AWTEvent.h" +#include "awt_BitmapUtil.h"  #include "awt_Component.h"  #include "awt_Cursor.h"  #include "awt_Dimension.h" @@ -4825,6 +4826,27 @@      return hdc;  }   +void AwtComponent::FillBackground(HDC hDC, SIZE &size) +{ + RECT eraseR = { 0, 0, size.cx, size.cy }; + VERIFY(::FillRect(hDC, &eraseR, GetBackgroundBrush())); +} + +void AwtComponent::FillAlpha(void *bitmapBits, SIZE &size, BYTE alpha) +{ + if (!bitmapBits) { + return; + } + + DWORD* dest = (DWORD*)bitmapBits; + //XXX: might be optimized to use one loop (int i = cy*cx; i > 0; i++). + for (int i = 0; i < size.cy; i++ ) { + for (int j = 0; j < size.cx; j++ ) { + ((BYTE*)(dest++))[3] = alpha; + } + } +} +  jintArray AwtComponent::CreatePrintedPixels(SIZE &loc, SIZE &size) {      JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);   @@ -4837,12 +4859,13 @@          return NULL;      }      HDC hMemoryDC = ::CreateCompatibleDC(hdc); - HBITMAP hBitmap = ::CreateCompatibleBitmap(hdc, size.cx, size.cy); + void *bitmapBits = NULL; + HBITMAP hBitmap = BitmapUtil::CreateARGBBitmap(size.cx, size.cy, + &bitmapBits);      HBITMAP hOldBitmap = (HBITMAP)::SelectObject(hMemoryDC, hBitmap);      SendMessage(WM_AWT_RELEASEDC, (WPARAM)hdc);   - RECT eraseR = { 0, 0, size.cx, size.cy }; - VERIFY(::FillRect(hMemoryDC, &eraseR, GetBackgroundBrush())); + FillBackground(hMemoryDC, size);        VERIFY(::SetWindowOrgEx(hMemoryDC, loc.cx, loc.cy, NULL));   @@ -4850,6 +4873,14 @@      // above.      SendMessage(WM_PRINT, (WPARAM)hMemoryDC, PRF_CLIENT | PRF_NONCLIENT);   + // First make sure the system completed any drawing to the bitmap. + ::GdiFlush(); + + // WM_PRINT does not fill the alpha-channel of the ARGB bitmap + // leaving it equal to zero. Hence we need to fill it manually. Otherwise + // the pixels will be considered transparent when interpreting the data. + FillAlpha(bitmapBits, size, 0xFF); +      ::SelectObject(hMemoryDC, hOldBitmap);        BITMAPINFO bmi; --- old/src/windows/native/sun/windows/awt_Component.h 2008-07-01 16:53:18.000000000 +0400 +++ new/src/windows/native/sun/windows/awt_Component.h 2008-07-01 16:53:18.000000000 +0400 @@ -576,6 +576,11 @@        void UpdateColorModel();   +protected: + //These functions are overridden in AwtWindow to handle non-opaque windows. + virtual void FillBackground(HDC hDC, SIZE &size); + virtual void FillAlpha(void *bitmapBits, SIZE &size, BYTE alpha); +public:      jintArray CreatePrintedPixels(SIZE &loc, SIZE &size);        static void * GetNativeFocusOwner(); --- old/src/windows/native/sun/windows/awt_Window.cpp 2008-07-01 16:53:18.000000000 +0400 +++ new/src/windows/native/sun/windows/awt_Window.cpp 2008-07-01 16:53:18.000000000 +0400 @@ -2772,6 +2772,20 @@      ::LeaveCriticalSection(&contentBitmapCS);  }   +void AwtWindow::FillBackground(HDC hDC, SIZE &size) +{ + if (isOpaque()) { + AwtCanvas::FillBackground(hDC, size); + } +} + +void AwtWindow::FillAlpha(void *bitmapBits, SIZE &size, BYTE alpha) +{ + if (isOpaque()) { + AwtCanvas::FillAlpha(bitmapBits, size, alpha); + } +} +  extern "C" {    /* --- old/src/windows/native/sun/windows/awt_Window.h 2008-07-01 16:53:19.000000000 +0400 +++ new/src/windows/native/sun/windows/awt_Window.h 2008-07-01 16:53:19.000000000 +0400 @@ -291,6 +291,11 @@          return warningString != NULL;      }   + //These are used in AwtComponent::CreatePrintedPixels. They are overridden + //here to handle non-opaque windows. + virtual void FillBackground(HDC hDC, SIZE &size); + virtual void FillAlpha(void *bitmapBits, SIZE &size, BYTE alpha); +  private:      int m_screenNum;

              People

              • Assignee:
                anthony Anthony Petrov (Inactive)
                Reporter:
                jijising Jitender Singh
              • Votes:
                0 Vote for this issue
                Watchers:
                1 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:
                  Imported:
                  Indexed: