#define INT32 WIN32_INT32
// this has to precede the others so we don't get collisions on min/max
+#include <org/xwt/js/JS.h>
#include <org/xwt/Box.h>
#include <stdint.h>
#include <org/xwt/Surface.h>
#include <org/xwt/PixelBuffer.h>
#include <org/xwt/Picture.h>
-#include <org/xwt/ByteStream.h>
#include <org/xwt/Platform.h>
-#include <org/xwt/Platform$ParsedFont.h>
#include <org/xwt/plat/Win32.h>
-#include <org/xwt/plat/Win32$Win32Font.h>
#include <org/xwt/plat/Win32$Win32Surface.h>
#include <org/xwt/plat/Win32$Win32PixelBuffer.h>
#include <org/xwt/plat/Win32$Win32Picture.h>
}
}
-// This function iterates over each family (lparam == 0), and then over each size (lparam == 1)
-int CALLBACK fontproc(const LOGFONTA* enumlogfont, const TEXTMETRICA* tm, long unsigned int type, LPARAM lparam) {
-
- if (lparam == 0) {
- LOGFONT lf;
- lf.lfCharSet = ANSI_CHARSET;
- strncpy(lf.lfFaceName, enumlogfont->lfFaceName, 32);
- lf.lfPitchAndFamily = 0;
- EnumFontFamiliesEx((HDC)org::xwt::plat::Win32::desktop_dc, &lf, fontproc, 1, 0);
-
- } else {
- org::xwt::plat::Win32::addFont(JvNewStringLatin1(enumlogfont->lfFaceName),
- ((type & RASTER_FONTTYPE) == 0) ? 0 : tm->tmHeight,
- tm->tmItalic == 0 ? 0 : 1,
- tm->tmWeight <= 400 ? 0 : 1);
- }
- return 1;
-}
-
// Initialization ////////////////////////////////////////////////////////////////////
org::xwt::plat::Win32::sizewe_cursor = (jint)LoadCursor(NULL, IDC_SIZEWE);
org::xwt::plat::Win32::hand_cursor = (jint)CreateCursor(GetModuleHandle(NULL), 14, 1, 32, 32, hand_cursor_and, hand_cursor_xor);
- // enumerate fonts
- LOGFONT lf;
- lf.lfCharSet = ANSI_CHARSET;
- lf.lfFaceName[0] = 0;
- lf.lfPitchAndFamily = 0;
- EnumFontFamiliesEx((HDC)desktop_dc, &lf, fontproc, 0, 0);
-
messagePumpThread = (jint)GetCurrentThreadId();
messagePumpStarted->release();
sprintf(buf, "XWT_WINDOW_CLASS_%i", window_class_counter++);
WNDCLASSEX wc;
- wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
+ wc.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbSize = sizeof(WNDCLASSEX);
wc.cbWndExtra = 0;
wc.hInstance = GetModuleHandle(NULL);
- wc.hIcon = NULL;
- wc.hIconSm = NULL;
- wc.hCursor = NULL;
- wc.hbrBackground = (HBRUSH)(COLOR_SCROLLBAR + 1);
- wc.lpszMenuName = NULL;
+ wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
+ wc.hIconSm = (HICON)LoadImage(GetModuleHandle(NULL),
+ MAKEINTRESOURCE(5),
+ IMAGE_ICON,
+ GetSystemMetrics(SM_CXSMICON),
+ GetSystemMetrics(SM_CYSMICON),
+ LR_DEFAULTCOLOR);
+ wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
+ wc.lpszMenuName = "menu";
wc.lpszClassName = buf;
RegisterClassEx(&wc);
+
+ surface->hwnd = (jint)CreateWindow(wc.lpszClassName, TEXT(""),
+ msg.wParam ? WS_NORMAL : WS_POPUP,
+ 200, 200, 100, 100,
+ (HWND__*)NULL, (HMENU__*)NULL,
+ GetModuleHandle(NULL), (LPVOID)NULL);
- surface->hwnd = (jint)CreateWindow(wc.lpszClassName, TEXT(""), msg.wParam ? WS_NORMAL : WS_POPUP, 200, 200, 100, 100,
- (HWND__*)NULL, (HMENU__*)NULL, GetModuleHandle(NULL), (LPVOID)NULL);
SetFocus((HWND)surface->hwnd);
surface->hwndCreated->release();
return rect.bottom - rect.top;
}
-org::xwt::plat::Win32$Win32Font* org::xwt::plat::Win32::mapFont(org::xwt::Platform$ParsedFont* pf) {
- org::xwt::plat::Win32$Win32Font* ret = new org::xwt::plat::Win32$Win32Font();
- LOGFONT logfont;
- memset(&logfont, 0, sizeof(LOGFONT));
- logfont.lfHeight = -MulDiv(pf->size, GetDeviceCaps((HDC)org::xwt::plat::Win32::desktop_dc, LOGPIXELSY), 72);
- if (pf->italic) logfont.lfItalic = 1;
- if (pf->bold) logfont.lfWeight = FW_BOLD;
- logfont.lfCharSet = ANSI_CHARSET;
-
- JvGetStringUTFRegion(pf->name, 0, min(31, JvGetStringUTFLength(pf->name)), logfont.lfFaceName);
- logfont.lfFaceName[min(31, JvGetStringUTFLength(pf->name))] = 0;
-
- ret->hfont = (jint)CreateFontIndirect(&logfont);
- SelectObject((HDC)desktop_dc, (HFONT)(ret->hfont));
-
- TEXTMETRIC tm;
- GetTextMetrics((HDC)desktop_dc, &tm);
- POINT p;
- p.x = 0; p.y = tm.tmAscent;
- LPtoDP((HDC)desktop_dc, &p, 1);
- ret->maxAscent = p.y;
-
- p.x = 0; p.y = tm.tmDescent;
- LPtoDP((HDC)desktop_dc, &p, 1);
- ret->maxDescent = p.y;
-
- return ret;
-}
-
-jint org::xwt::plat::Win32::_stringWidth(jstring font, jstring text) {
-
- HFONT hfont = (HFONT)(getFont(font)->hfont);
- SelectObject((HDC)org::xwt::plat::Win32::desktop_dc, hfont);
-
- int len = min(1024, JvGetStringUTFLength(text));
- char buf[len + 1];
- buf[len] = '\0';
- JvGetStringUTFRegion(text, 0, len, buf);
-
- SIZE size;
- GetTextExtentPoint32((HDC)org::xwt::plat::Win32::desktop_dc, buf, len, &size);
- return size.cx;
-}
-
jboolean org::xwt::plat::Win32::_newBrowserWindow_(jstring url) {
int len = min(2048, JvGetStringUTFLength(url));
static jint scratch_w = 0;
static jint scratch_h = 0;
-#define BLT(dest, dx1, dy1, dx2, dy2, src, sx1, sy1, sx2, sy2, op) \
- if ((dx2 - dx1 == sx2 - sx1) && (dy2 - dy1 == sy2 - sy1)) \
- BitBlt(dest, dx1, dy1, dx2 - dx1, dy2 - dy1, src, sx1, sy1, op); \
- else \
- StretchBlt(dest, dx1, dy1, dx2 - dx1, dy2 - dy1, src, sx1, sy1, sx2 - sx1, sy2 - sy1, op);
-
+#define max(a,b) ((a)>(b)?(a):(b))
+#define min(a,b) ((a)<(b)?(a):(b))
+
void org::xwt::plat::Win32$Win32PixelBuffer::drawPicture(org::xwt::Picture* source0,
- jint dx1, jint dy1, jint dx2, jint dy2,
- jint sx1, jint sy1, jint sx2, jint sy2) {
+ jint dx, jint dy,
+ jint cx1, jint cy1, jint cx2, jint cy2,
+ jint rgb, jboolean alphaOnly) {
org::xwt::plat::Win32$Win32Picture* source = (org::xwt::plat::Win32$Win32Picture*)source0;
+ cx1 = max(dx, cx1);
+ cy1 = max(dy, cy1);
+ cx2 = min(dx + source->getWidth(), cx2);
+ cy2 = min(dy + source->getHeight(), cy2);
+ if (cx1 >= cx2 || cy1 >= cy2) return;
+
if (source->hasalpha) {
- if (scratch == NULL || scratch_w < dx2 - dx1 || scratch_h < dy2 - dy1) {
+ if (scratch == NULL || scratch_w < cx2 - cx1 || scratch_h < cy2 - cy1) {
if (scratch_dc != NULL) DeleteDC(scratch_dc);
if (scratch != NULL) DeleteObject(scratch);
- scratch_w = max(dx2 - dx1, scratch_w);
- scratch_h = max(dy2 - dy1, scratch_h);
+ scratch_w = max(cx2 - cx1, scratch_w);
+ scratch_h = max(cy2 - cy1, scratch_h);
BITMAPINFO bitmapinfo;
memset(&bitmapinfo, 0, sizeof(BITMAPINFO));
}
// copy from screen to scratch
- BitBlt((HDC)scratch_dc, 0, 0, dx2 - dx1, dy2 - dy1, (HDC)hdc, dx1, dy1, SRCCOPY);
+ BitBlt((HDC)scratch_dc, 0, 0, cx2 - cx1, cy2 - cy1, (HDC)hdc, cx1, cy1, SRCCOPY);
// apply alpha-blending to scratch
jint* dat = elements(source->data);
- for(int x = max(clipx1, dx1) - dx1; x < min(clipx2, dx2) - dx1; x++)
- for(int y = max(clipy1, dy1) - dy1; y < min(clipy2, dy2) - dy1; y++) {
- int sx = (x * (sx2 - sx1)) / (dx2 - dx1) + sx1;
- int sy = (y * (sy2 - sy1)) / (dy2 - dy1) + sy1;
- jint dst = scratch_bits[y * scratch_w + x];
- jint src = dat[sy * source->getWidth() + sx];
- jint alpha = (src & 0xFF000000) >> 24;
+ for(int x = cx1; x < cx2; x++)
+ for(int y = cy1; y < cy2; y++) {
+ jint dst = scratch_bits[(y - dy) * scratch_w + (x - dx)];
+
+ // FEATURE: see if we can leverage GDI to do something more clever here with alphaOnly
+ jint src = alphaOnly ? rgb : dat[(y - dy) * source->getWidth() + x - dx];
+ jint alpha = (dat[(y - dy) * source->getWidth() + x - dx] & 0xFF000000) >> 24;
jint r = (((src & 0x00FF0000) >> 16) * alpha + ((dst & 0x00FF0000) >> 16) * (0xFF - alpha)) / 0xFF;
jint g = (((src & 0x0000FF00) >> 8) * alpha + ((dst & 0x0000FF00) >> 8) * (0xFF - alpha)) / 0xFF;
jint b = (((src & 0x000000FF)) * alpha + ((dst & 0x000000FF)) * (0xFF - alpha)) / 0xFF;
- scratch_bits[y * scratch_w + x] = (r << 16) | (g << 8) | b;
+ scratch_bits[(y - dy) * scratch_w + (x - dx)] = (r << 16) | (g << 8) | b;
}
// copy back from scratch to screen
- BitBlt((HDC)hdc, dx1, dy1, dx2 - dx1, dy2 - dy1, (HDC)scratch_dc, 0, 0, SRCCOPY);
+ BitBlt((HDC)hdc, cx1, cy1, cx2 - cx1, cy2 - cy1, (HDC)scratch_dc, 0, 0, SRCCOPY);
} else {
+
+ // FIXME: support alphaOnly case here
if (source->hasmask) {
- BLT((HDC)hdc, dx1, dy1, dx2, dy2, (HDC)source->maskdc, sx1, sy1, sx2, sy2, SRCAND);
- BLT((HDC)hdc, dx1, dy1, dx2, dy2, (HDC)source->hdc, sx1, sy1, sx2, sy2, SRCPAINT);
+ BitBlt((HDC)hdc, cx1, cy1, cx2 - cx1, cy2 - cy1, (HDC)source->maskdc, cx1 - dx, cy1 - dy, SRCAND);
+ BitBlt((HDC)hdc, cx1, cy1, cx2 - cx1, cy2 - cy1, (HDC)source->hdc, cx1 - dx, cy1 - dy, SRCPAINT);
} else {
- BLT((HDC)hdc, dx1, dy1, dx2, dy2, (HDC)source->hdc, sx1, sy1, sx2, sy2, SRCCOPY);
+ BitBlt((HDC)hdc, cx1, cy1, cx2 - cx1, cy2 - cy1, (HDC)source->hdc, cx1 - dx, cy1 - dy, SRCCOPY);
}
}
}
-void org::xwt::plat::Win32$Win32PixelBuffer::drawString(jstring font, jstring text, jint x, jint y, jint color) {
-
- org::xwt::plat::Win32$Win32Font* wf = org::xwt::plat::Win32::getFont(font);
- SelectObject((HDC)hdc, (HFONT)(wf->hfont));
-
- // Platform API passes us the y-pos of the bottom of the text; we need the top
- y -= wf->maxAscent;
-
- int len = min(1024, JvGetStringUTFLength(text));
- char buf[len + 1];
- buf[len] = '\0';
- JvGetStringUTFRegion(text, 0, len, buf);
-
- SetTextColor((HDC)hdc, PALETTERGB((color & 0xFF0000) >> 16, (color & 0xFF00) >> 8, color & 0xFF));
- TextOut((HDC)hdc, x, y, buf, len);
-}
-
void org::xwt::plat::Win32$Win32PixelBuffer::fillRect(jint x, jint y, jint x2, jint y2, jint color) {
jint w = x2 - x;
jint h = y2 - y;
SelectObject((HDC)hdc, (HBITMAP)hbitmap);
}
-void org::xwt::plat::Win32$Win32PixelBuffer::setClip(jint x, jint y, jint x2, jint y2) {
- clipx1 = x; clipx2 = x2; clipy1 = y; clipy2 = y2;
- HRGN hrgn = CreateRectRgn(x, y, x2, y2);
- SelectClipRgn((HDC)hdc, hrgn);
- DeleteObject(hrgn);
-}
-
void org::xwt::plat::Win32$Win32PixelBuffer::finalize() {
DeleteObject((void*)hdc);
DeleteObject((void*)hbitmap);
BITMAPINFO bitmapinfo;
memset(&bitmapinfo, 0, sizeof(BITMAPINFO));
bitmapinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bitmapinfo.bmiHeader.biWidth = w;
- bitmapinfo.bmiHeader.biHeight = -1 * h;
+ bitmapinfo.bmiHeader.biWidth = width;
+ bitmapinfo.bmiHeader.biHeight = -1 * height;
bitmapinfo.bmiHeader.biPlanes = 1;
bitmapinfo.bmiHeader.biBitCount = 32;
bitmapinfo.bmiHeader.biCompression = BI_RGB;
- hbitmap = (jint)CreateCompatibleBitmap((HDC)org::xwt::plat::Win32::desktop_dc, w, h);
+ hbitmap = (jint)CreateCompatibleBitmap((HDC)org::xwt::plat::Win32::desktop_dc, width, height);
hdc = (jint)CreateCompatibleDC((HDC)org::xwt::plat::Win32::desktop_dc);
SelectObject((HDC)hdc, (HBITMAP)hbitmap);
uint32_t* dat = (uint32_t*)elements(data);
for(int i=0; i<data->length; i++) if ((dat[i] & 0xFF000000) == 0x00000000) dat[i] = 0x00000000;
- StretchDIBits((HDC)hdc, 0, 0, w, h, 0, 0, w, h, elements(data), &bitmapinfo, DIB_RGB_COLORS, SRCCOPY);
+ StretchDIBits((HDC)hdc, 0, 0, width, height, 0, 0, width, height, elements(data), &bitmapinfo, DIB_RGB_COLORS, SRCCOPY);
jint _copy[min(1024, data->length)];
jint* copy = data->length > 1024 ? (jint*)malloc(data->length * 4) : _copy;
}
// hmask = (jint)CreateBitmap(w, h, 1, 1, NULL);
- hmask = (jint)CreateCompatibleBitmap((HDC)org::xwt::plat::Win32::desktop_dc, w, h);
+ hmask = (jint)CreateCompatibleBitmap((HDC)org::xwt::plat::Win32::desktop_dc, width, height);
maskdc = (jint)CreateCompatibleDC(NULL);
SelectObject((HDC)maskdc, (HBITMAP)hmask);
- StretchDIBits((HDC)maskdc, 0, 0, w, h, 0, 0, w, h, copy, &bitmapinfo, DIB_RGB_COLORS, SRCCOPY);
+ StretchDIBits((HDC)maskdc, 0, 0, width, height, 0, 0, width, height, copy, &bitmapinfo, DIB_RGB_COLORS, SRCCOPY);
if (data->length > 1024) free(copy);
}
void org::xwt::plat::Win32$Win32Surface::_setMaximized(jboolean m) { ShowWindow((HWND)hwnd, m ? SW_SHOWMAXIMIZED : SW_SHOWNORMAL); }
void org::xwt::plat::Win32$Win32Surface::postCursorChange() { PostMessage((HWND)hwnd, WM_USER_SETCURSOR, 0, 0); }
-void org::xwt::plat::Win32$Win32Surface::setLocation(jint x, jint y) {
+void org::xwt::plat::Win32$Win32Surface::setLocation() {
POINT point;
RECT rect;
point.x = 0;
point.y = 0;
ClientToScreen((HWND)hwnd, &point);
GetWindowRect((HWND)hwnd, &rect);
- SetWindowPos((HWND)hwnd, NULL, x - (point.x - rect.left), y - (point.y - rect.top), 0, 0, SWP_NOZORDER | SWP_NOSIZE);
+ SetWindowPos((HWND)hwnd, NULL, root->x - (point.x - rect.left), root->y - (point.y - rect.top), 0, 0, SWP_NOZORDER | SWP_NOSIZE);
}
-void org::xwt::plat::Win32$Win32Surface::setSize(jint w, jint h) {
+void org::xwt::plat::Win32$Win32Surface::_setSize(jint w, jint h) {
RECT client_rect, window_rect;
GetClientRect((HWND)hwnd, &client_rect);
GetWindowRect((HWND)hwnd, &window_rect);
HBITMAP bit = CreateCompatibleBitmap((HDC)hdc, icon_width, icon_height);
HDC memdc = CreateCompatibleDC((HDC)hdc);
SelectObject(memdc, bit);
- BLT((HDC)memdc, 0, 0, icon_width, icon_height, (HDC)(p->hdc), 0, 0, p->getWidth(), p->getHeight(), SRCCOPY);
+ BitBlt((HDC)memdc, 0, 0, icon_width, icon_height, (HDC)(p->hdc), 0, 0, SRCCOPY);
// create the mask
jint* dat = elements(p->data);
int oldmousex, oldmousey;
MINMAXINFO* mmi;
+ int resizable;
POINT point;
HWND hwnd2;
RECT rect, rect2;
switch(iMsg) {
case WM_DEVMODECHANGE: break; // FEATURE: color depth changed
case WM_DISPLAYCHANGE: break; // FEATURE: screen size changed
- case WM_FONTCHANGE: break; // FEATURE: set of fonts changed
case WM_MOUSEWHEEL: break; // FEATURE: Mouse Wheel
case WM_SYSKEYDOWN: if (GetKeyState(VK_MENU) >> (sizeof(SHORT) * 8 - 1) == 0) return 0;
mmi = (MINMAXINFO*)lParam;
mmi->ptMinTrackSize.x = ((uint32_t)root->minwidth) + addwidth;
mmi->ptMinTrackSize.y = ((uint32_t)root->minheight) + addheight;
- mmi->ptMaxTrackSize.x = min(org::xwt::plat::Win32::getScreenWidth(), ((uint32_t)root->maxwidth) + addwidth);
- mmi->ptMaxTrackSize.y = min(org::xwt::plat::Win32::getScreenHeight(), ((uint32_t)root->maxheight) + addheight);
+ resizable = !((root->minwidth == root->maxwidth) && (root->minheight == root->maxheight));
+ mmi->ptMaxTrackSize.x = resizable ? org::xwt::plat::Win32::getScreenWidth() : mmi->ptMinTrackSize.x;
+ mmi->ptMaxTrackSize.y = resizable ? org::xwt::plat::Win32::getScreenHeight() : mmi->ptMinTrackSize.y;
return 0;
case WM_PAINT: