1 /* 2 * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 #include "common.h" 27 28 #include "Pixels.h" 29 30 #include "com_sun_glass_ui_Pixels_Format.h" 31 #include "com_sun_glass_ui_win_WinPixels.h" 32 33 Bitmap::Bitmap(int width, int height) 34 { 35 BYTE *mpixels = new BYTE[width * height]; 36 memset(mpixels, 0, width * height); 37 Attach(::CreateBitmap(width, height, 1, 1, mpixels)); 38 delete[] mpixels; 39 ASSERT((HBITMAP)*this); 40 } 41 42 Bitmap::Bitmap(int width, int height, void **data, HDC hdc) 43 { 44 ASSERT(width && height && data); 45 46 BITMAPV5HEADER bmi = {0}; 47 bmi.bV5Width = width; 48 bmi.bV5Height = -height; 49 bmi.bV5Planes = 1; 50 bmi.bV5BitCount = 32; 51 52 bmi.bV5Size = sizeof(BITMAPV5HEADER); 53 bmi.bV5Compression = BI_BITFIELDS; 54 bmi.bV5XPelsPerMeter = 72; 55 bmi.bV5YPelsPerMeter = 72; 56 bmi.bV5RedMask = 0x00FF0000; 57 bmi.bV5GreenMask = 0x0000FF00; 58 bmi.bV5BlueMask = 0x000000FF; 59 bmi.bV5AlphaMask = 0xFF000000; 60 61 Attach(::CreateDIBSection( 62 hdc, 63 (BITMAPINFO*)&bmi, 64 DIB_RGB_COLORS, 65 data, 66 NULL, 67 0)); 68 69 ASSERT((HBITMAP)*this); 70 } 71 72 Bitmap::Bitmap(Pixels & pixels) 73 { 74 Attach(::CreateBitmap(pixels.GetWidth(), pixels.GetHeight(), 1, 32, pixels.GetBits())); 75 ASSERT((HBITMAP)*this); 76 } 77 78 DIBitmap::DIBitmap(Pixels & pixels) 79 { 80 int const width = pixels.GetWidth(); 81 int const height = pixels.GetHeight(); 82 void * const bits = pixels.GetBits(); 83 84 void *bitmapBits = NULL; 85 jsize imageSize = width * height * 4; 86 87 BITMAPINFOHEADER bmi = {0}; 88 bmi.biSize = sizeof(bmi); 89 bmi.biWidth = width; 90 bmi.biHeight = -height; 91 bmi.biPlanes = 1; 92 bmi.biBitCount = 32; 93 bmi.biCompression = BI_RGB; 94 bmi.biSizeImage = imageSize; 95 96 HBITMAP hBitmap = ::CreateDIBSection(NULL, (BITMAPINFO *)&bmi, DIB_RGB_COLORS, &bitmapBits, NULL, 0); 97 98 if (bitmapBits) { 99 memcpy(bitmapBits, bits, imageSize); 100 Attach(hBitmap); 101 } 102 ASSERT((HBITMAP)*this); 103 } 104 105 HICON Pixels::CreateIcon(JNIEnv *env, jobject jPixels, BOOL fIcon, jint x, jint y) 106 { 107 Pixels pixels(env, jPixels); 108 109 Bitmap mask(pixels.GetWidth(), pixels.GetHeight()); 110 Bitmap bitmap(pixels); 111 112 ICONINFO iconInfo; 113 memset(&iconInfo, 0, sizeof(ICONINFO)); 114 iconInfo.hbmMask = mask; 115 iconInfo.hbmColor = bitmap; 116 iconInfo.fIcon = fIcon; 117 iconInfo.xHotspot = x; 118 iconInfo.yHotspot = y; 119 HICON hIcon = ::CreateIconIndirect(&iconInfo); 120 ASSERT(hIcon); 121 122 ::GdiFlush(); 123 124 return hIcon; 125 } 126 127 Pixels::Pixels(JNIEnv *env, jobject jPixels) 128 { 129 env->CallVoidMethod(jPixels, javaIDs.Pixels.attachData, ptr_to_jlong(this)); 130 CheckAndClearException(env); 131 } 132 133 void Pixels::AttachInt(JNIEnv *env, jint w, jint h, jobject buf, jintArray array, jint offset) 134 { 135 width = w; 136 height = h; 137 ints.Attach(env, buf, array, offset); 138 } 139 140 void Pixels::AttachByte(JNIEnv *env, jint w, jint h, jobject buf, jbyteArray array, jint offset) 141 { 142 width = w; 143 height = h; 144 bytes.Attach(env, buf, array, offset); 145 } 146 147 void * Pixels::GetBits() 148 { 149 if (ints) { 150 return ints.GetPtr(); 151 } 152 if (bytes) { 153 return bytes.GetPtr(); 154 } 155 return NULL; 156 } 157 158 HANDLE BaseBitmap::GetGlobalDIB() 159 { 160 HBITMAP hBitmap = (HBITMAP)*this; 161 BITMAP bm; 162 ::GetObject(hBitmap, sizeof(bm), &bm); 163 164 jsize imageSize = bm.bmWidth*bm.bmHeight*4; 165 166 //BITMAPV5HEADER converts to ordinal BITMAPINFOHEADER 167 //as in/out parameter of GetDIBits call. 168 //Negative height is not supported by MS Wordpad. Sorry. 169 BITMAPINFOHEADER bmi = {0}; 170 bmi.biSize = sizeof(bmi); 171 bmi.biWidth = bm.bmWidth; 172 bmi.biHeight = bm.bmHeight; 173 bmi.biPlanes = 1; 174 bmi.biBitCount = 32; 175 bmi.biCompression = BI_RGB; 176 bmi.biSizeImage = imageSize; 177 178 HANDLE hDIB = ::GlobalAlloc(GHND, bmi.biSize + imageSize); 179 if (hDIB) { 180 bool success = false; 181 HDC hDC = ::GetDC(NULL); 182 if (hDC) { 183 BITMAPINFOHEADER *pbi = (BITMAPINFOHEADER *)::GlobalLock(hDIB); 184 if (pbi) { 185 *pbi = bmi; 186 success = ::GetDIBits(hDC, hBitmap, 187 0, bm.bmHeight, 188 (LPSTR)pbi + bmi.biSize, 189 (LPBITMAPINFO)pbi, 190 DIB_RGB_COLORS) != 0; 191 ::GlobalUnlock(hDIB); 192 } 193 ::ReleaseDC(NULL, hDC); 194 } 195 if (!success) { 196 ::GlobalFree(hDIB); 197 hDIB = NULL; 198 } 199 } 200 return hDIB; 201 } 202 203 extern "C" { 204 205 /* 206 * Class: com_sun_glass_ui_win_WinPixels 207 * Method: _initIDs 208 * Signature: ()I 209 */ 210 JNIEXPORT jint JNICALL Java_com_sun_glass_ui_win_WinPixels__1initIDs 211 (JNIEnv *env, jclass cls) 212 { 213 javaIDs.Pixels.attachData = env->GetMethodID(cls, "attachData", "(J)V"); 214 ASSERT(javaIDs.Pixels.attachData); 215 216 return com_sun_glass_ui_Pixels_Format_BYTE_BGRA_PRE; 217 } 218 219 /* 220 * Class: com_sun_glass_ui_win_WinPixels 221 * Method: _attachInt 222 * Signature: (JIILjava/nio/IntBuffer;[II)V 223 */ 224 JNIEXPORT void JNICALL Java_com_sun_glass_ui_win_WinPixels__1attachInt 225 (JNIEnv *env, jobject pixels, jlong ptr, jint w, jint h, jobject buf, jintArray array, jint offset) 226 { 227 ((Pixels*)jlong_to_ptr(ptr))->AttachInt(env, w, h, buf, array, offset); 228 } 229 230 /* 231 * Class: com_sun_glass_ui_win_WinPixels 232 * Method: _attachByte 233 * Signature: (JIILjava/nio/ByteBuffer;[BI)V 234 */ 235 JNIEXPORT void JNICALL Java_com_sun_glass_ui_win_WinPixels__1attachByte 236 (JNIEnv *env, jobject pixels, jlong ptr, jint w, jint h, jobject buf, jbyteArray array, jint offset) 237 { 238 ((Pixels*)jlong_to_ptr(ptr))->AttachByte(env, w, h, buf, array, offset); 239 } 240 241 /* 242 * Class: com_sun_glass_ui_win_WinPixels 243 * Method: _fillDirectByteBuffer 244 * Signature: (Ljava/nio/ByteBuffer;)V 245 */ 246 JNIEXPORT void JNICALL Java_com_sun_glass_ui_win_WinPixels__1fillDirectByteBuffer 247 (JNIEnv *env, jobject jPixels, jobject bb) 248 { 249 Pixels pixels(env, jPixels); 250 251 memcpy(env->GetDirectBufferAddress(bb), pixels.GetBits(), 252 pixels.GetWidth() * pixels.GetHeight() * 4); 253 } 254 255 } // extern "C" 256