X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Fxwt%2Fplat%2FWin32.cc;h=95fe5f7deb78fed6ee44f9ea788ea8df5c15e34a;hb=86730c1d88ded8f44d0c5d2e2c7268185aea73ec;hp=bd277210fe53594d068adb2971d0bc12a5fdb659;hpb=798082a9cf2856f50f91483da37b5d9661355f00;p=org.ibex.core.git diff --git a/src/org/xwt/plat/Win32.cc b/src/org/xwt/plat/Win32.cc index bd27721..95fe5f7 100644 --- a/src/org/xwt/plat/Win32.cc +++ b/src/org/xwt/plat/Win32.cc @@ -5,7 +5,7 @@ #define INT32 WIN32_INT32 // this has to precede the others so we don't get collisions on min/max -#include +#include #include #include @@ -25,15 +25,12 @@ #include #include #include -#include +#include #include -#include #include -#include #include -#include #include -#include +#include #include #include #include @@ -65,25 +62,6 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { } } -// 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 //////////////////////////////////////////////////////////////////// @@ -187,13 +165,6 @@ void org::xwt::plat::Win32::natInit() { 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(); @@ -354,50 +325,6 @@ jint org::xwt::plat::Win32::_getScreenHeight() { 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)); @@ -417,7 +344,7 @@ jboolean org::xwt::plat::Win32::_newBrowserWindow_(jstring url) { } -// Win32DoubleBuffer ///////////////////////////////////////////////////////////////////////// +// Win32PixelBuffer ///////////////////////////////////////////////////////////////////////// // This is a scratch area; when blitting a translucent image, we copy the underlying data here first. // Since all drawing operations are single-threaded, it's safe to use a global here. @@ -427,24 +354,19 @@ static jint* scratch_bits = NULL; 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); - -void org::xwt::plat::Win32$Win32DoubleBuffer::drawPicture(org::xwt::Picture* source0, - jint dx1, jint dy1, jint dx2, jint dy2, - jint sx1, jint sy1, jint sx2, jint sy2) { +void org::xwt::plat::Win32$Win32PixelBuffer::drawPicture(org::xwt::Picture* source0, + 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; 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)); @@ -462,57 +384,42 @@ void org::xwt::plat::Win32$Win32DoubleBuffer::drawPicture(org::xwt::Picture* sou } // 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, cy2, (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, cy2, (HDC)source->maskdc, cx1 - dx, cy1 - dy, SRCAND); + BitBlt((HDC)hdc, cx1, cy1, cx2, cy2, (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, cy2, (HDC)source->hdc, cx1 - dx, cy1 - dy, SRCCOPY); } } } -void org::xwt::plat::Win32$Win32DoubleBuffer::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$Win32DoubleBuffer::fillRect(jint x, jint y, jint x2, jint y2, jint color) { +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; @@ -524,27 +431,20 @@ void org::xwt::plat::Win32$Win32DoubleBuffer::fillRect(jint x, jint y, jint x2, DeleteObject(brush); } -void org::xwt::plat::Win32$Win32Surface::blit(org::xwt::DoubleBuffer* s, jint sx, jint sy, jint dx, jint dy, jint dx2, jint dy2) { +void org::xwt::plat::Win32$Win32Surface::blit(org::xwt::PixelBuffer* s, jint sx, jint sy, jint dx, jint dy, jint dx2, jint dy2) { // we create the DC lazily to get around some strange race condition in WinXP if (hdc == 0) hdc = (jint)GetDC((HWND)hwnd); - BitBlt((HDC)hdc, dx, dy, dx2 - dx, dy2 - dy, (HDC)(((org::xwt::plat::Win32$Win32DoubleBuffer*)s)->hdc), sx, sy, SRCCOPY); + BitBlt((HDC)hdc, dx, dy, dx2 - dx, dy2 - dy, (HDC)(((org::xwt::plat::Win32$Win32PixelBuffer*)s)->hdc), sx, sy, SRCCOPY); } -void org::xwt::plat::Win32$Win32DoubleBuffer::natInit() { +void org::xwt::plat::Win32$Win32PixelBuffer::natInit() { hbitmap = (jint)CreateCompatibleBitmap((HDC)org::xwt::plat::Win32::desktop_dc, w, h); hdc = (jint)CreateCompatibleDC((HDC)org::xwt::plat::Win32::desktop_dc); SetBkMode((HDC)hdc, TRANSPARENT); SelectObject((HDC)hdc, (HBITMAP)hbitmap); } -void org::xwt::plat::Win32$Win32DoubleBuffer::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$Win32DoubleBuffer::finalize() { +void org::xwt::plat::Win32$Win32PixelBuffer::finalize() { DeleteObject((void*)hdc); DeleteObject((void*)hbitmap); } @@ -627,17 +527,17 @@ void org::xwt::plat::Win32$Win32Surface::_setMinimized(jboolean m) { ShowWindow( 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); @@ -667,7 +567,7 @@ void org::xwt::plat::Win32$Win32Surface::setIcon(org::xwt::Picture* p0) { 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); @@ -712,7 +612,6 @@ jint org::xwt::plat::Win32$Win32Surface::WndProc(jint _hwnd, jint _iMsg, jint _w 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; @@ -819,10 +718,10 @@ jint org::xwt::plat::Win32$Win32Surface::WndProc(jint _hwnd, jint _iMsg, jint _w addwidth = (window_rect.right - window_rect.left) - (client_rect.right - client_rect.left); addheight = (window_rect.bottom - window_rect.top) - (client_rect.bottom - client_rect.top); mmi = (MINMAXINFO*)lParam; - mmi->ptMinTrackSize.x = ((uint32_t)root->dmin(0)) + addwidth; - mmi->ptMinTrackSize.y = ((uint32_t)root->dmin(1)) + addheight; - mmi->ptMaxTrackSize.x = min(org::xwt::plat::Win32::getScreenWidth(), ((uint32_t)root->dmax(0)) + addwidth); - mmi->ptMaxTrackSize.y = min(org::xwt::plat::Win32::getScreenHeight(), ((uint32_t)root->dmax(1)) + addheight); + 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); return 0; case WM_PAINT: