From 5b6d43ab50b88d2ab8fd3d7ebf434173c5768065 Mon Sep 17 00:00:00 2001 From: Royce Mitchell III Date: Sun, 17 Aug 2003 17:32:58 +0000 Subject: [PATCH] * fixes a couple (several?) memory leaks * fixes |many| gdi locking bugs ( particularly DC's ) * Polygon and Rectangle now match MS's perfectly. * a lot of functions take PDC or have PDC-equivalents now. * fixed some C89 compatibility issues. ( before you complain, I refuse to upgrade b/c my gcc 2.95 has caught ERRORS that gcc 3 completely ignores, so I refuse to upgrade ) svn path=/trunk/; revision=5619 --- reactos/apps/tests/polytest/polytest.cpp | 155 +++++---- reactos/apps/tests/shaptest/shaptest.c | 118 +++++-- reactos/include/win32k/coord.h | 21 +- reactos/include/win32k/dc.h | 1 + reactos/include/win32k/line.h | 10 +- reactos/lib/user32/controls/button.c | 68 ++-- reactos/lib/user32/windows/window.c | 7 +- reactos/subsys/win32k/eng/bitblt.c | 40 +-- reactos/subsys/win32k/eng/xlate.c | 6 +- reactos/subsys/win32k/include/object.h | 13 +- reactos/subsys/win32k/include/path.h | 44 +-- reactos/subsys/win32k/ntuser/painting.c | 5 +- reactos/subsys/win32k/objects/coord.c | 78 +++-- reactos/subsys/win32k/objects/dc.c | 342 +++++++++---------- reactos/subsys/win32k/objects/fillshap.c | 379 +++++++++++---------- reactos/subsys/win32k/objects/gdiobj.c | 17 +- reactos/subsys/win32k/objects/line.c | 405 ++++++++++++---------- reactos/subsys/win32k/objects/objconv.c | 38 ++- reactos/subsys/win32k/objects/path.c | 407 +++++++++++++---------- reactos/subsys/win32k/objects/polyfill.c | 155 +++++---- 20 files changed, 1340 insertions(+), 969 deletions(-) diff --git a/reactos/apps/tests/polytest/polytest.cpp b/reactos/apps/tests/polytest/polytest.cpp index cebf77b54d1..2f1b9d9c60b 100644 --- a/reactos/apps/tests/polytest/polytest.cpp +++ b/reactos/apps/tests/polytest/polytest.cpp @@ -269,9 +269,9 @@ POLYGONFILL_MakeEdge(POINT From, POINT To) rc->ToY = From.y; rc->YDirection = -1; - // lines that go up get walked backwards, so need to be offset - // by -1 in order to make the walk identically on a pixel-level - rc->Error = -1; + // lines that go up get walked backwards, so need to be offset + // by -1 in order to make the walk identically on a pixel-level + rc->Error = -1; } else { @@ -281,7 +281,7 @@ POLYGONFILL_MakeEdge(POINT From, POINT To) rc->ToY = To.y; rc->YDirection = 1; - rc->Error = 0; + rc->Error = 0; } rc->x = rc->FromX; @@ -301,23 +301,6 @@ POLYGONFILL_MakeEdge(POINT From, POINT To) rc->pNext = 0; - rc->XIntercept[0] = rc->x; - rc->XIntercept[1] = rc->x; - - if ( rc->xmajor && rc->absdy ) - { - int x1 = rc->x; - int steps = (rc->ErrorMax-rc->Error-1) / rc->absdy; - if ( steps ) - { - rc->x += steps * rc->XDirection; - rc->Error += steps * rc->absdy; - ASSERT ( rc->Error < rc->ErrorMax ); - rc->XIntercept[0] = MIN(x1,rc->x); - rc->XIntercept[1] = MAX(x1,rc->x); - } - } - DPRINT("MakeEdge (%i,%i)->(%i,%i) d=(%i,%i) dir=(%i,%i) err=%i max=%i\n", From.x, From.y, To.x, To.y, rc->dx, rc->dy, rc->XDirection, rc->YDirection, rc->Error, rc->ErrorMax ); @@ -457,20 +440,11 @@ POLYGONFILL_UpdateScanline(FILL_EDGE* pEdge, int Scanline) if ( 0 == pEdge->dy ) return; - ASSERT ( pEdge->FromY < Scanline && pEdge->ToY >= Scanline ); + ASSERT ( pEdge->FromY <= Scanline && pEdge->ToY >= Scanline ); if ( pEdge->xmajor ) { int steps; - // we should require exactly 1 step to step onto current scanline... - ASSERT ( (pEdge->ErrorMax-pEdge->Error-1) / pEdge->absdy == 0 ); - pEdge->x += pEdge->XDirection; - pEdge->Error += pEdge->absdy; - ASSERT ( pEdge->Error >= pEdge->ErrorMax ); - - // now step onto current scanline... - pEdge->Error -= pEdge->absdx; - pEdge->y++; ASSERT ( pEdge->y == Scanline ); @@ -491,9 +465,22 @@ POLYGONFILL_UpdateScanline(FILL_EDGE* pEdge, int Scanline) pEdge->XIntercept[0] = pEdge->x; pEdge->XIntercept[1] = pEdge->x; } + + // we should require exactly 1 step to step onto next scanline... + ASSERT ( (pEdge->ErrorMax-pEdge->Error-1) / pEdge->absdy == 0 ); + pEdge->x += pEdge->XDirection; + pEdge->Error += pEdge->absdy; + ASSERT ( pEdge->Error >= pEdge->ErrorMax ); + + // now step onto next scanline... + pEdge->Error -= pEdge->absdx; + pEdge->y++; } else // then this is a y-major line { + pEdge->XIntercept[0] = pEdge->x; + pEdge->XIntercept[1] = pEdge->x; + pEdge->Error += pEdge->absdx; pEdge->y++; @@ -503,9 +490,6 @@ POLYGONFILL_UpdateScanline(FILL_EDGE* pEdge, int Scanline) pEdge->x += pEdge->XDirection; ASSERT ( pEdge->Error < pEdge->ErrorMax ); } - - pEdge->XIntercept[0] = pEdge->x; - pEdge->XIntercept[1] = pEdge->x; } DPRINT("Line (%d, %d) to (%d, %d) intersects scanline %d at (%d,%d)\n", @@ -528,7 +512,7 @@ POLYGONFILL_BuildActiveList ( int Scanline, FILL_EDGE_LIST* list, FILL_EDGE** Ac { FILL_EDGE* pEdge = list->Edges[i]; ASSERT(pEdge); - if ( pEdge->FromY < Scanline && pEdge->ToY >= Scanline ) + if ( pEdge->FromY <= Scanline && pEdge->ToY >= Scanline ) { POLYGONFILL_UpdateScanline ( pEdge, Scanline ); POLYGONFILL_ActiveListInsert ( ActiveHead, pEdge ); @@ -562,8 +546,8 @@ POLYGONFILL_FillScanLineAlternate( while ( NULL != pRight ) { - int x1 = pLeft->XIntercept[1]+1; - int x2 = pRight->XIntercept[0]; + int x1 = pLeft->XIntercept[0]; + int x2 = pRight->XIntercept[1]; if ( x2 > x1 ) { RECTL BoundRect; @@ -600,43 +584,84 @@ POLYGONFILL_FillScanLineWinding( MIX RopMode ) { FILL_EDGE *pLeft, *pRight; - int winding = 0; + int x1, x2, winding = 0; + RECTL BoundRect; if ( !ActiveHead ) return; + BoundRect.top = ScanLine; + BoundRect.bottom = ScanLine + 1; + pLeft = ActiveHead; winding = pLeft->YDirection; pRight = pLeft->pNext; ASSERT(pRight); + // setup first line... + x1 = pLeft->XIntercept[0]; + x2 = pRight->XIntercept[1]; + + pLeft = pRight; + pRight = pLeft->pNext; + winding += pLeft->YDirection; + while ( NULL != pRight ) { - int x1 = pLeft->XIntercept[1]+1; - int x2 = pRight->XIntercept[0]; - if ( winding && x2 > x1 ) + int newx1 = pLeft->XIntercept[0]; + int newx2 = pRight->XIntercept[1]; + if ( winding ) { - RECTL BoundRect; - BoundRect.top = ScanLine; - BoundRect.bottom = ScanLine + 1; - BoundRect.left = x1; - BoundRect.right = x2; + // check and see if this new line touches the previous... + if ( (newx1 >= x1 && newx1 <= x2) + || (newx2 >= x1 && newx2 <= x2) + || (x1 >= newx1 && x1 <= newx2) + || (x2 >= newx2 && x2 <= newx2) + ) + { + // yup, just tack it on to our existing line + x1 = MIN(x1,newx1); + x2 = MAX(x2,newx2); + } + else + { + // nope - render the old line.. + BoundRect.left = x1; + BoundRect.right = x2; - DPRINT("Fill Line (%d, %d) to (%d, %d)\n",x1, ScanLine, x2, ScanLine); - IntEngLineTo( SurfObj, - dc->CombinedClip, - BrushObj, - x1, - ScanLine, - x2, - ScanLine, - &BoundRect, // Bounding rectangle - RopMode); // MIX + DPRINT("Fill Line (%d, %d) to (%d, %d)\n",x1, ScanLine, x2, ScanLine); + IntEngLineTo( SurfObj, + dc->CombinedClip, + BrushObj, + x1, + ScanLine, + x2, + ScanLine, + &BoundRect, // Bounding rectangle + RopMode); // MIX + + x1 = newx1; + x2 = newx2; + } } pLeft = pRight; pRight = pLeft->pNext; winding += pLeft->YDirection; } + // there will always be a line left-over, render it now... + BoundRect.left = x1; + BoundRect.right = x2; + + DPRINT("Fill Line (%d, %d) to (%d, %d)\n",x1, ScanLine, x2, ScanLine); + IntEngLineTo( SurfObj, + dc->CombinedClip, + BrushObj, + x1, + ScanLine, + x2, + ScanLine, + &BoundRect, // Bounding rectangle + RopMode); // MIX } //When the fill mode is ALTERNATE, GDI fills the area between odd-numbered and @@ -689,7 +714,7 @@ FillPolygon( /* For each Scanline from BoundRect.bottom to BoundRect.top, * determine line segments to draw */ - for ( ScanLine = BoundRect.top + 1; ScanLine < BoundRect.bottom; ++ScanLine ) + for ( ScanLine = BoundRect.top; ScanLine < BoundRect.bottom; ++ScanLine ) { POLYGONFILL_BuildActiveList(ScanLine, list, &ActiveHead); //DEBUG_PRINT_ACTIVE_EDGELIST(ActiveHead); @@ -803,6 +828,20 @@ void main() { 0, 0 }, { 12, 4 }, { 4, 8 }, +#elif 1 + { 1, 1 }, + { 3, 1 }, + { 3, 3 }, + { 1, 3 } +#elif 0 + { 0, 0 }, + { 4, 0 }, + { 4, 4 }, + { 8, 4 }, + { 8, 8 }, + { 4, 8 }, + { 4, 4 }, + { 0, 4 }, #else { 4, 16 }, { 12, 4 }, @@ -814,7 +853,7 @@ void main() const int pts_count = sizeof(pts)/sizeof(pts[0]); // use ALTERNATE or WINDING for 3rd param - Polygon ( pts, pts_count, WINDING ); + Polygon ( pts, pts_count, ALTERNATE ); // print out our "screen" for ( int y = 0; y < SCREENY; y++ ) diff --git a/reactos/apps/tests/shaptest/shaptest.c b/reactos/apps/tests/shaptest/shaptest.c index 32e6b4d1a61..4a6b282c453 100644 --- a/reactos/apps/tests/shaptest/shaptest.c +++ b/reactos/apps/tests/shaptest/shaptest.c @@ -10,14 +10,20 @@ #include #include +#include +#ifndef ASSERT +#define ASSERT assert +#endif + +#define nelem(x) (sizeof (x) / sizeof *(x)) HFONT tf; LRESULT WINAPI MainWndProc(HWND, UINT, WPARAM, LPARAM); void PolygonTest ( HDC hdc ) { - HPEN BluePen, OldPen; + HPEN Pen, OldPen; HBRUSH RedBrush, OldBrush; DWORD Mode; POINT PointsAlternate[] = @@ -48,49 +54,99 @@ void PolygonTest ( HDC hdc ) { 7, 7 }, { 3, 7 }, }; + POINT Square1[] = + { + { 1, 15 }, + { 3, 15 }, + { 3, 17 }, + { 1, 17 } + }; + POINT Square2[] = + { + { 5, 15 }, + { 7, 15 }, + { 7, 17 }, + { 5, 17 } + }; + POINT Square3[] = + { + { 1, 23 }, + { 3, 23 }, + { 3, 25 }, + { 1, 25 } + }; + POINT Square4[] = + { + { 5, 23 }, + { 7, 23 }, + { 7, 25 }, + { 5, 25 } + }; + POINT Square5[] = + { + { 1, 31 }, + { 3, 31 }, + { 3, 33 }, + { 1, 33 } + }; + POINT Square6[] = + { + { 5, 31 }, + { 7, 31 }, + { 7, 33 }, + { 5, 33 } + }; //create a pen to draw the shape - BluePen = CreatePen(PS_SOLID, 1, RGB(0, 0, 0xff)); + Pen = CreatePen(PS_SOLID, 1, RGB(0, 0, 0xff)); + ASSERT(Pen); RedBrush = CreateSolidBrush(RGB(0xff, 0, 0)); + ASSERT(RedBrush); - //initialize a set of points for alternate. - /*lpPointsAlternate[0].x = 20; - lpPointsAlternate[0].y = 80; //{20,80}; - lpPointsAlternate[1].x = 60; - lpPointsAlternate[1].y = 20; //{60,20}; - lpPointsAlternate[2].x = 90; - lpPointsAlternate[2].y = 80; //{90,80}; - lpPointsAlternate[3].x = 20; - lpPointsAlternate[3].y = 40; //{20,40}; - lpPointsAlternate[4].x = 100; - lpPointsAlternate[4].y = 40; //{100,40}; - - //initialize a set of points for winding. - lpPointsWinding[0].x = 130; - lpPointsWinding[0].y = 80; //{130,80}; - lpPointsWinding[1].x = 170; - lpPointsWinding[1].y = 20; //{170,20}; - lpPointsWinding[2].x = 200; - lpPointsWinding[2].y = 80; //{200,80}; - lpPointsWinding[3].x = 130; - lpPointsWinding[3].y = 40; //{130,40}; - lpPointsWinding[4].x = 210; - lpPointsWinding[4].y = 40; //{210,40}; -*/ - OldPen = (HPEN)SelectObject(hdc, BluePen); + OldPen = (HPEN)SelectObject(hdc, Pen); OldBrush = (HBRUSH)SelectObject(hdc, RedBrush); Mode = GetPolyFillMode(hdc); SetPolyFillMode(hdc, ALTERNATE); - Polygon(hdc,PointsAlternate,sizeof(PointsAlternate)/sizeof(PointsAlternate[0])); + Polygon(hdc,PointsAlternate,nelem(PointsAlternate)); SetPolyFillMode(hdc, WINDING); - Polygon(hdc,PointsWinding,sizeof(PointsWinding)/sizeof(PointsWinding[0])); + Polygon(hdc,PointsWinding,nelem(PointsWinding)); Rectangle ( hdc, 1, 1, 10, 10 ); - Polygon(hdc,Tri1,sizeof(Tri1)/sizeof(Tri1[0])); - Polygon(hdc,Tri2,sizeof(Tri2)/sizeof(Tri2[0])); + Polygon(hdc,Tri1,nelem(Tri1)); + Polygon(hdc,Tri2,nelem(Tri2)); + + Rectangle ( hdc, 1, 11, 4, 14 ); + Rectangle ( hdc, 5, 11, 8, 14 ); + Rectangle ( hdc, 9, 11, 12, 14 ); + Rectangle ( hdc, 13, 11, 16, 14 ); + Polygon(hdc,Square1,nelem(Square1)); + Polygon(hdc,Square2,nelem(Square2)); + Rectangle ( hdc, 1, 19, 4, 22 ); + Rectangle ( hdc, 5, 19, 8, 22 ); + Rectangle ( hdc, 9, 19, 12, 22 ); + Rectangle ( hdc, 13, 19, 16, 22 ); + Polygon(hdc,Square3,nelem(Square3)); + Polygon(hdc,Square4,nelem(Square4)); + Rectangle ( hdc, 1, 27, 4, 30 ); + Rectangle ( hdc, 5, 27, 8, 30 ); + Rectangle ( hdc, 9, 27, 12, 30 ); + Rectangle ( hdc, 13, 27, 16, 30 ); + + // switch to null pen to make surey they display correctly + DeleteObject ( SelectObject(hdc, OldPen) ); + Pen = CreatePen ( PS_NULL, 0, 0 ); + ASSERT(Pen); + OldPen = (HPEN)SelectObject(hdc, Pen); + + Polygon(hdc,Square5,nelem(Square5)); + Polygon(hdc,Square6,nelem(Square6)); + Rectangle ( hdc, 1, 35, 4, 38 ); + Rectangle ( hdc, 5, 35, 8, 38 ); + Rectangle ( hdc, 9, 35, 12, 38 ); + Rectangle ( hdc, 13, 35, 16, 38 ); //cleanup SetPolyFillMode(hdc, Mode); diff --git a/reactos/include/win32k/coord.h b/reactos/include/win32k/coord.h index 5dfba5d3565..b63fa15b4d7 100644 --- a/reactos/include/win32k/coord.h +++ b/reactos/include/win32k/coord.h @@ -1,6 +1,8 @@ #ifndef __WIN32K_COORD_H #define __WIN32K_COORD_H +#include "dc.h" + BOOL STDCALL W32kCombineTransform ( @@ -15,17 +17,30 @@ W32kDPtoLP ( LPPOINT Points, int Count ); + +int +FASTCALL +IntGetGraphicsMode ( PDC dc ); + int STDCALL -W32kGetGraphicsMode ( - HDC hDC - ); +W32kGetGraphicsMode ( HDC hDC ); + BOOL STDCALL W32kGetWorldTransform ( HDC hDC, LPXFORM Xform ); + +VOID +FASTCALL +CoordLPtoDP ( PDC Dc, LPPOINT Point ); + +VOID +FASTCALL +IntLPtoDP ( PDC dc, LPPOINT Points, INT Count ); + BOOL STDCALL W32kLPtoDP ( diff --git a/reactos/include/win32k/dc.h b/reactos/include/win32k/dc.h index 2a59a136b35..a1b9c92b25d 100644 --- a/reactos/include/win32k/dc.h +++ b/reactos/include/win32k/dc.h @@ -173,6 +173,7 @@ INT STDCALL W32kGetBkMode(HDC hDC); BOOL STDCALL W32kGetBrushOrgEx(HDC hDC, LPPOINT brushOrg); HRGN STDCALL W32kGetClipRgn(HDC hDC); HGDIOBJ STDCALL W32kGetCurrentObject(HDC hDC, UINT ObjectType); +VOID FASTCALL IntGetCurrentPositionEx (PDC dc, LPPOINT currentPosition); BOOL STDCALL W32kGetCurrentPositionEx(HDC hDC, LPPOINT currentPosition); BOOL STDCALL W32kGetDCOrgEx(HDC hDC, LPPOINT Point); HDC STDCALL W32kGetDCState16(HDC hDC); diff --git a/reactos/include/win32k/line.h b/reactos/include/win32k/line.h index 5e893d7d538..64d6c8ef5d6 100644 --- a/reactos/include/win32k/line.h +++ b/reactos/include/win32k/line.h @@ -34,15 +34,19 @@ W32kArcTo(HDC hDC, int XRadial2, int YRadial2); +INT +FASTCALL +IntGetArcDirection ( PDC dc ); + INT STDCALL -W32kGetArcDirection(HDC hDC); +W32kGetArcDirection ( HDC hDC ); BOOL STDCALL W32kLineTo(HDC hDC, - int XEnd, - int YEnd); + int XEnd, + int YEnd ); BOOL STDCALL diff --git a/reactos/lib/user32/controls/button.c b/reactos/lib/user32/controls/button.c index 93012ec7a70..27337eb5a2f 100644 --- a/reactos/lib/user32/controls/button.c +++ b/reactos/lib/user32/controls/button.c @@ -1,4 +1,4 @@ -/* $Id: button.c,v 1.8 2003/08/15 15:55:02 weiden Exp $ +/* $Id: button.c,v 1.9 2003/08/17 17:32:58 royce Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS User32 @@ -133,9 +133,11 @@ inline static void paint_button( HWND hwnd, LONG style, UINT action ) /* retrieve the button text; returned buffer must be freed by caller */ inline static WCHAR *get_button_text( HWND hwnd ) { + INT len; + WCHAR *buffer; DbgPrint("[button] In get_button_text()\n"); - INT len = GetWindowTextLengthW( hwnd ); - WCHAR *buffer = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) ); + len = GetWindowTextLengthW( hwnd ); + buffer = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) ); if (buffer) GetWindowTextW( hwnd, buffer, len + 1 ); DbgPrint("[button] TextLen %d Text = %s\n", len, buffer); return buffer; @@ -147,15 +149,18 @@ inline static WCHAR *get_button_text( HWND hwnd ) static LRESULT WINAPI ButtonWndProc_common(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL unicode ) { - DbgPrint("[button] ButtonWndProc called : msg %d\n", uMsg); - RECT rect; POINT pt; - LONG style = GetWindowLongA( hWnd, GWL_STYLE ); - UINT btn_type = get_button_type( style ); + LONG style; + UINT btn_type; LONG state; HANDLE oldHbitmap; + DbgPrint("[button] ButtonWndProc called : msg %d\n", uMsg); + + style = GetWindowLongA( hWnd, GWL_STYLE ); + btn_type = get_button_type( style ); + pt.x = LOWORD(lParam); pt.y = HIWORD(lParam); @@ -181,8 +186,8 @@ static LRESULT WINAPI ButtonWndProc_common(HWND hWnd, UINT uMsg, if (!hbitmapCheckBoxes) { - DbgPrint("[button] Loading bitmaps\n"); BITMAP bmp; + DbgPrint("[button] Loading bitmaps\n"); hbitmapCheckBoxes = LoadBitmapW(0, MAKEINTRESOURCEW(OBM_CHECKBOXES)); GetObjectW( hbitmapCheckBoxes, sizeof(bmp), &bmp ); checkBoxWidth = bmp.bmWidth / 4; @@ -202,10 +207,12 @@ static LRESULT WINAPI ButtonWndProc_common(HWND hWnd, UINT uMsg, DbgPrint("[button] WM_PAINT\n"); if (btnPaintFunc[btn_type]) { - DbgPrint("[button] About to draw...\n"); PAINTSTRUCT ps; - HDC hdc = wParam ? (HDC)wParam : BeginPaint( hWnd, &ps ); - int nOldMode = SetBkMode( hdc, OPAQUE ); + HDC hdc; + int nOldMode; + DbgPrint("[button] About to draw...\n"); + hdc = wParam ? (HDC)wParam : BeginPaint( hWnd, &ps ); + nOldMode = SetBkMode( hdc, OPAQUE ); (btnPaintFunc[btn_type])( hWnd, hdc, ODA_DRAWENTIRE ); SetBkMode(hdc, nOldMode); /* reset painting mode */ if( !wParam ) EndPaint( hWnd, &ps ); @@ -297,11 +304,12 @@ static LRESULT WINAPI ButtonWndProc_common(HWND hWnd, UINT uMsg, case WM_SETTEXT: { - DbgPrint("[button] WM_SETTEXT"); - /* Clear an old text here as Windows does */ - HDC hdc = GetDC(hWnd); + HDC hdc; HBRUSH hbrush; RECT client, rc; + DbgPrint("[button] WM_SETTEXT"); + /* Clear an old text here as Windows does */ + hdc = GetDC(hWnd); hbrush = (HBRUSH)SendMessageW(GetParent(hWnd), WM_CTLCOLORSTATIC, (WPARAM)hdc, (LPARAM)hWnd); @@ -537,15 +545,17 @@ static UINT BUTTON_BStoDT(DWORD style) */ static UINT BUTTON_CalcLabelRect(HWND hwnd, HDC hdc, RECT *rc) { - DbgPrint("[button] In BUTTON_CalcLabelRect()\n"); - LONG style = GetWindowLongA( hwnd, GWL_STYLE ); + LONG style; WCHAR *text; ICONINFO iconInfo; BITMAP bm; UINT dtStyle = BUTTON_BStoDT(style); RECT r = *rc; INT n; - + + DbgPrint("[button] In BUTTON_CalcLabelRect()\n"); + style = GetWindowLongA( hwnd, GWL_STYLE ); + /* Calculate label rectangle according to label type */ switch (style & (BS_ICON|BS_BITMAP)) { @@ -653,16 +663,20 @@ static BOOL CALLBACK BUTTON_DrawTextCallback(HDC hdc, LPARAM lp, WPARAM wp, int */ static void BUTTON_DrawLabel(HWND hwnd, HDC hdc, UINT dtFlags, RECT *rc) { - DbgPrint("[button] In BUTTON_DrawLabel()\n"); DRAWSTATEPROC lpOutputProc = NULL; LPARAM lp; WPARAM wp = 0; HBRUSH hbr = 0; - UINT flags = IsWindowEnabled(hwnd) ? DSS_NORMAL : DSS_DISABLED; - LONG state = get_button_state( hwnd ); - LONG style = GetWindowLongA( hwnd, GWL_STYLE ); + UINT flags; + LONG state; + LONG style; WCHAR *text = NULL; + DbgPrint("[button] In BUTTON_DrawLabel()\n"); + flags = IsWindowEnabled(hwnd) ? DSS_NORMAL : DSS_DISABLED; + state = get_button_state( hwnd ); + style = GetWindowLongA( hwnd, GWL_STYLE ); + /* FIXME: To draw disabled label in Win31 look-and-feel, we probably * must use DSS_MONO flag and COLOR_GRAYTEXT brush (or maybe DSS_UNION). * I don't have Win31 on hand to verify that, so I leave it as is. @@ -709,7 +723,6 @@ static void BUTTON_DrawLabel(HWND hwnd, HDC hdc, UINT dtFlags, RECT *rc) */ static void PB_Paint( HWND hwnd, HDC hDC, UINT action ) { - DbgPrint("[button] In PB_Paint()\n"); RECT rc, focus_rect, r; UINT dtFlags; HRGN hRgn; @@ -718,11 +731,16 @@ static void PB_Paint( HWND hwnd, HDC hDC, UINT action ) INT oldBkMode; COLORREF oldTxtColor; HFONT hFont; - LONG state = get_button_state( hwnd ); - LONG style = GetWindowLongA( hwnd, GWL_STYLE ); - BOOL pushedState = (state & BUTTON_HIGHLIGHTED); + LONG state; + LONG style; + BOOL pushedState; UINT uState; + DbgPrint("[button] In PB_Paint()\n"); + state = get_button_state( hwnd ); + style = GetWindowLongA( hwnd, GWL_STYLE ); + pushedState = (state & BUTTON_HIGHLIGHTED); + GetClientRect( hwnd, &rc ); /* Send WM_CTLCOLOR to allow changing the font (the colors are fixed) */ diff --git a/reactos/lib/user32/windows/window.c b/reactos/lib/user32/windows/window.c index 4ebadaaad22..0db68891315 100644 --- a/reactos/lib/user32/windows/window.c +++ b/reactos/lib/user32/windows/window.c @@ -1,4 +1,4 @@ -/* $Id: window.c,v 1.59 2003/08/15 02:51:53 silverblade Exp $ +/* $Id: window.c,v 1.60 2003/08/17 17:32:58 royce Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS user32.dll @@ -489,12 +489,13 @@ CreateWindowExA(DWORD dwExStyle, HINSTANCE hInstance, LPVOID lpParam) { - DbgPrint("[window] CreateWindowExA style %d, exstyle %d, parent %d\n", dwStyle, dwExStyle, hWndParent); UNICODE_STRING WindowName; UNICODE_STRING ClassName; HWND Handle; INT sw; - + + DbgPrint("[window] CreateWindowExA style %d, exstyle %d, parent %d\n", dwStyle, dwExStyle, hWndParent); + /* Register built-in controls if not already done */ if (! ControlsInitCalled) { diff --git a/reactos/subsys/win32k/eng/bitblt.c b/reactos/subsys/win32k/eng/bitblt.c index 0329b716671..5668265391c 100644 --- a/reactos/subsys/win32k/eng/bitblt.c +++ b/reactos/subsys/win32k/eng/bitblt.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: bitblt.c,v 1.25 2003/08/04 19:57:05 royce Exp $ +/* $Id: bitblt.c,v 1.26 2003/08/17 17:32:58 royce Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -43,7 +43,7 @@ #include #include -#define NDEBUG +//#define NDEBUG #include typedef BOOLEAN STDCALL (*PBLTRECTFUNC)(PSURFOBJ OutputObj, @@ -84,17 +84,17 @@ BOOL STDCALL EngIntersectRect(PRECTL prcDst, PRECTL prcSrc1, PRECTL prcSrc2) static BOOLEAN STDCALL BltMask(PSURFOBJ Dest, - PSURFGDI DestGDI, - PSURFOBJ Source, - PSURFGDI SourceGDI, - PSURFOBJ Mask, - PXLATEOBJ ColorTranslation, + PSURFGDI DestGDI, + PSURFOBJ Source, + PSURFGDI SourceGDI, + PSURFOBJ Mask, + PXLATEOBJ ColorTranslation, PRECTL DestRect, - PPOINTL SourcePoint, - PPOINTL MaskPoint, - PBRUSHOBJ Brush, + PPOINTL SourcePoint, + PPOINTL MaskPoint, + PBRUSHOBJ Brush, PPOINTL BrushPoint, - ROP4 Rop4) + ROP4 Rop4) { LONG i, j, dx, dy, c8; BYTE *tMask, *lMask; @@ -135,17 +135,17 @@ BltMask(PSURFOBJ Dest, static BOOLEAN STDCALL BltPatCopy(PSURFOBJ Dest, - PSURFGDI DestGDI, - PSURFOBJ Source, - PSURFGDI SourceGDI, - PSURFOBJ Mask, - PXLATEOBJ ColorTranslation, + PSURFGDI DestGDI, + PSURFOBJ Source, + PSURFGDI SourceGDI, + PSURFOBJ Mask, + PXLATEOBJ ColorTranslation, PRECTL DestRect, - PPOINTL SourcePoint, - PPOINTL MaskPoint, - PBRUSHOBJ Brush, + PPOINTL SourcePoint, + PPOINTL MaskPoint, + PBRUSHOBJ Brush, PPOINTL BrushPoint, - ROP4 Rop4) + ROP4 Rop4) { // These functions are assigned if we're working with a DIB // The assigned functions depend on the bitsPerPixel of the DIB diff --git a/reactos/subsys/win32k/eng/xlate.c b/reactos/subsys/win32k/eng/xlate.c index 5833bdcb4ef..72b4a541682 100644 --- a/reactos/subsys/win32k/eng/xlate.c +++ b/reactos/subsys/win32k/eng/xlate.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: xlate.c,v 1.21 2003/08/13 20:24:04 chorns Exp $ +/* $Id: xlate.c,v 1.22 2003/08/17 17:32:58 royce Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -213,8 +213,8 @@ XLATEOBJ * STDCALL IntEngCreateXlate(USHORT DestPalType, USHORT SourcePalType, UINT i; NewXlate = (HPALETTE)CreateGDIHandle(sizeof( XLATEGDI ), sizeof( XLATEOBJ )); - if( !ValidEngHandle( NewXlate ) ) - return NULL; + if ( !ValidEngHandle ( NewXlate ) ) + return NULL; XlateObj = (XLATEOBJ*) AccessUserObject( (ULONG) NewXlate ); XlateGDI = (XLATEGDI*) AccessInternalObject( (ULONG) NewXlate ); diff --git a/reactos/subsys/win32k/include/object.h b/reactos/subsys/win32k/include/object.h index 46177f28ddf..e5d35365b90 100644 --- a/reactos/subsys/win32k/include/object.h +++ b/reactos/subsys/win32k/include/object.h @@ -126,8 +126,17 @@ PPOINT FASTCALL GDI_Bezier (const POINT *Points, INT count, PINT nPtsOut); /* objects/objconv.c */ -PBRUSHOBJ FASTCALL PenToBrushObj (PDC dc, PENOBJ *pen); -HBITMAP FASTCALL BitmapToSurf (PBITMAPOBJ BitmapObj); +BRUSHOBJ* +FASTCALL +PenToBrushObj(BRUSHOBJ *brush, PENOBJ *pen); + +BRUSHOBJ* +FASTCALL +HPenToBrushObj ( BRUSHOBJ *brush, HPEN hpen ); + +HBITMAP +FASTCALL +BitmapToSurf ( PBITMAPOBJ BitmapObj ); #endif /* __WIN32K_OBJECT_H */ diff --git a/reactos/subsys/win32k/include/path.h b/reactos/subsys/win32k/include/path.h index 41f32003f0b..a6e5e554179 100644 --- a/reactos/subsys/win32k/include/path.h +++ b/reactos/subsys/win32k/include/path.h @@ -1,28 +1,28 @@ -BOOL STDCALL PATH_Arc (HDC hdc, INT x1, INT y1, INT x2, INT y2, INT xStart, INT yStart, INT xEnd, INT yEnd); +BOOL FASTCALL PATH_Arc (PDC dc, INT x1, INT y1, INT x2, INT y2, INT xStart, INT yStart, INT xEnd, INT yEnd); BOOL FASTCALL PATH_AssignGdiPath (GdiPath *pPathDest, const GdiPath *pPathSrc); VOID FASTCALL PATH_DestroyGdiPath (GdiPath *pPath); -BOOL STDCALL PATH_Ellipse (HDC hdc, INT x1, INT y1, INT x2, INT y2); -VOID STDCALL PATH_EmptyPath (GdiPath *pPath); +BOOL FASTCALL PATH_Ellipse (PDC dc, INT x1, INT y1, INT x2, INT y2); +VOID FASTCALL PATH_EmptyPath (GdiPath *pPath); VOID FASTCALL PATH_InitGdiPath (GdiPath *pPath); -BOOL STDCALL PATH_LineTo (HDC hdc, INT x, INT y); -BOOL FASTCALL PATH_MoveTo (HDC hdc); -BOOL STDCALL PATH_PolyBezier (HDC hdc, const POINT *pts, DWORD cbPoints); -BOOL STDCALL PATH_PolyBezierTo (HDC hdc, const POINT *pts, DWORD cbPoints); -BOOL STDCALL PATH_Polygon (HDC hdc, const POINT *pts, DWORD cbPoints); -BOOL STDCALL PATH_Polyline (HDC hdc, const POINT *pts, DWORD cbPoints); -BOOL STDCALL PATH_PolylineTo (HDC hdc, const POINT *pts, DWORD cbPoints); -BOOL STDCALL PATH_PolyPolygon ( HDC hdc, const POINT* pts, const INT* counts, UINT polygons); -BOOL STDCALL PATH_PolyPolyline( HDC hdc, const POINT* pts, const DWORD* counts, DWORD polylines); -BOOL STDCALL PATH_Rectangle (HDC hdc, INT x1, INT y1, INT x2, INT y2); -BOOL STDCALL PATH_PathToRegion (const GdiPath *pPath, INT nPolyFillMode, HRGN *pHrgn); +BOOL FASTCALL PATH_LineTo (PDC dc, INT x, INT y); +BOOL FASTCALL PATH_MoveTo (PDC dc); +BOOL FASTCALL PATH_PolyBezier (PDC dc, const POINT *pts, DWORD cbPoints); +BOOL FASTCALL PATH_PolyBezierTo (PDC dc, const POINT *pts, DWORD cbPoints); +BOOL FASTCALL PATH_Polygon (PDC dc, const POINT *pts, DWORD cbPoints); +BOOL FASTCALL PATH_Polyline (PDC dc, const POINT *pts, DWORD cbPoints); +BOOL FASTCALL PATH_PolylineTo (PDC dc, const POINT *pts, DWORD cbPoints); +BOOL FASTCALL PATH_PolyPolygon ( PDC dc, const POINT* pts, const INT* counts, UINT polygons); +BOOL FASTCALL PATH_PolyPolyline( PDC dc, const POINT* pts, const DWORD* counts, DWORD polylines); +BOOL FASTCALL PATH_Rectangle (PDC dc, INT x1, INT y1, INT x2, INT y2); +BOOL FASTCALL PATH_PathToRegion (const GdiPath *pPath, INT nPolyFillMode, HRGN *pHrgn); #ifdef _WIN32K_PATH_INTERNAL -BOOL STDCALL PATH_AddEntry (GdiPath *pPath, const POINT *pPoint, BYTE flags); -BOOL STDCALL PATH_AddFlatBezier (GdiPath *pPath, POINT *pt, BOOL closed); -BOOL STDCALL PATH_DoArcPart (GdiPath *pPath, FLOAT_POINT corners[], double angleStart, double angleEnd, BOOL addMoveTo); +BOOL FASTCALL PATH_AddEntry (GdiPath *pPath, const POINT *pPoint, BYTE flags); +BOOL FASTCALL PATH_AddFlatBezier (GdiPath *pPath, POINT *pt, BOOL closed); +BOOL FASTCALL PATH_DoArcPart (GdiPath *pPath, FLOAT_POINT corners[], double angleStart, double angleEnd, BOOL addMoveTo); BOOL FASTCALL PATH_FlattenPath (GdiPath *pPath); -BOOL FASTCALL PATH_GetPathFromHDC (HDC hdc, GdiPath **ppPath); -VOID STDCALL PATH_NormalizePoint (FLOAT_POINT corners[], const FLOAT_POINT *pPoint, double *pX, double *pY); -BOOL STDCALL PATH_PathToRegion(const GdiPath *pPath, INT nPolyFillMode, HRGN *pHrgn); -BOOL STDCALL PATH_ReserveEntries (GdiPath *pPath, INT numEntries); -VOID STDCALL PATH_ScaleNormalizedPoint (FLOAT_POINT corners[], double x, double y, POINT *pPoint); +VOID FASTCALL PATH_GetPathFromDC (PDC dc, GdiPath **ppPath); +VOID FASTCALL PATH_NormalizePoint (FLOAT_POINT corners[], const FLOAT_POINT *pPoint, double *pX, double *pY); +BOOL FASTCALL PATH_PathToRegion(const GdiPath *pPath, INT nPolyFillMode, HRGN *pHrgn); +BOOL FASTCALL PATH_ReserveEntries (GdiPath *pPath, INT numEntries); +VOID FASTCALL PATH_ScaleNormalizedPoint (FLOAT_POINT corners[], double x, double y, POINT *pPoint); #endif diff --git a/reactos/subsys/win32k/ntuser/painting.c b/reactos/subsys/win32k/ntuser/painting.c index 63a3f251b96..2fddf989941 100644 --- a/reactos/subsys/win32k/ntuser/painting.c +++ b/reactos/subsys/win32k/ntuser/painting.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: painting.c,v 1.27 2003/08/15 02:51:53 silverblade Exp $ +/* $Id: painting.c,v 1.28 2003/08/17 17:32:58 royce Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -458,11 +458,12 @@ PaintRedrawWindow( PWINDOW_OBJECT Window, ULONG Flags, ULONG ExFlags) { - DbgPrint("[win32k.sys:painting] In PaintRedrawWindow()\n"); RECT Rect, Rect2; POINT Pt; HRGN hRgn = NULL; + DbgPrint("[win32k.sys:painting] In PaintRedrawWindow()\n"); + if ((RDW_INVALIDATE | RDW_FRAME) == (Flags & (RDW_INVALIDATE | RDW_FRAME)) || (RDW_VALIDATE | RDW_NOFRAME) == (Flags & (RDW_VALIDATE | RDW_NOFRAME))) { diff --git a/reactos/subsys/win32k/objects/coord.c b/reactos/subsys/win32k/objects/coord.c index 0dec42ae94f..031a0b5e71a 100644 --- a/reactos/subsys/win32k/objects/coord.c +++ b/reactos/subsys/win32k/objects/coord.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: coord.c,v 1.14 2003/08/13 20:24:05 chorns Exp $ +/* $Id: coord.c,v 1.15 2003/08/17 17:32:58 royce Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -118,21 +118,27 @@ W32kDPtoLP(HDC hDC, } int -STDCALL -W32kGetGraphicsMode(HDC hDC) +FASTCALL +IntGetGraphicsMode ( PDC dc ) { - PDC dc; - int GraphicsMode; + ASSERT ( dc ); + return dc->w.GraphicsMode; +} - dc = DC_HandleToPtr (hDC); - if (!dc) +int +STDCALL +W32kGetGraphicsMode ( HDC hDC ) +{ + PDC dc = DC_HandleToPtr ( hDC ); + int GraphicsMode = 0; // default to failure + + if ( dc ) { - return 0; + GraphicsMode = dc->w.GraphicsMode; + DC_ReleasePtr ( hDC ); } - GraphicsMode = dc->w.GraphicsMode; - DC_ReleasePtr( hDC ); - return GraphicsMode; + return GraphicsMode; } BOOL @@ -156,8 +162,9 @@ W32kGetWorldTransform(HDC hDC, return TRUE; } -VOID STATIC -CoordLPtoDP(PDC Dc, LPPOINT Point) +VOID +FASTCALL +CoordLPtoDP ( PDC Dc, LPPOINT Point ) { FLOAT x, y; x = (FLOAT)Point->x; @@ -168,6 +175,16 @@ CoordLPtoDP(PDC Dc, LPPOINT Point) y * Dc->w.xformWorld2Vport.eM22 + Dc->w.xformWorld2Vport.eDy; } +VOID +FASTCALL +IntLPtoDP ( PDC dc, LPPOINT Points, INT Count ) +{ + INT i; + + for ( i = 0; i < Count; i++ ) + CoordLPtoDP ( dc, &Points[i] ); +} + /*! * Converts points from logical coordinates into device coordinates. Conversion depends on the mapping mode, * world transfrom, viewport origin settings for the given device context. @@ -177,28 +194,29 @@ CoordLPtoDP(PDC Dc, LPPOINT Point) * \return TRUE if success. */ BOOL STDCALL -W32kLPtoDP(HDC hDC, LPPOINT UnsafePoints, INT Count) +W32kLPtoDP ( HDC hDC, LPPOINT UnsafePoints, INT Count ) { - PDC Dc; - INT i; - LPPOINT Points = (LPPOINT) ExAllocatePool( PagedPool, Count*sizeof(POINT)); + PDC dc = DC_HandleToPtr ( hDC ); + LPPOINT Points; + + if ( !dc ) + return FALSE; + + Points = (LPPOINT)ExAllocatePool ( PagedPool, Count*sizeof(POINT) ); + + ASSERT ( Points ); - ASSERT(Points); MmCopyFromCaller( Points, UnsafePoints, Count*sizeof(POINT) ); - Dc = DC_HandleToPtr (hDC); - if (Dc == NULL) - { - return(FALSE); - } + IntLPtoDP ( dc, UnsafePoints, Count ); - for (i = 0; i < Count; i++) - { - CoordLPtoDP(Dc, &Points[i]); - } - DC_ReleasePtr( hDC ); - MmCopyToCaller( UnsafePoints, Points, Count*sizeof(POINT) ); - return(TRUE); + MmCopyToCaller ( UnsafePoints, Points, Count*sizeof(POINT) ); + + ExFreePool ( Points ); + + DC_ReleasePtr ( hDC ); + + return TRUE; } BOOL diff --git a/reactos/subsys/win32k/objects/dc.c b/reactos/subsys/win32k/objects/dc.c index 6e5f13c2fa4..6e04aca2d94 100644 --- a/reactos/subsys/win32k/objects/dc.c +++ b/reactos/subsys/win32k/objects/dc.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: dc.c,v 1.69 2003/08/17 03:32:59 royce Exp $ +/* $Id: dc.c,v 1.70 2003/08/17 17:32:58 royce Exp $ * * DC.C - Device context functions * @@ -74,16 +74,22 @@ func_type STDCALL func_name( HDC hdc ) \ * important that the function has the right signature, for the implementation * we can do whatever we want. */ -#define DC_GET_VAL_EX( func_name, ret_x, ret_y, type ) \ -BOOL STDCALL func_name( HDC hdc, LP##type pt ) \ -{ \ - PDC dc = DC_HandleToPtr ( hdc ); \ - if (!dc) \ - return FALSE; \ - ((LPPOINT)pt)->x = dc->ret_x; \ - ((LPPOINT)pt)->y = dc->ret_y; \ - DC_ReleasePtr ( hdc ); \ - return TRUE; \ +#define DC_GET_VAL_EX( W32kFuncName, IntFuncName, ret_x, ret_y, type ) \ +VOID FASTCALL IntFuncName ( PDC dc, LP##type pt ) \ +{ \ + ASSERT ( dc ); \ + ASSERT ( pt ); \ + ((LPPOINT)pt)->x = dc->ret_x; \ + ((LPPOINT)pt)->y = dc->ret_y; \ +} \ +BOOL STDCALL W32kFuncName ( HDC hdc, LP##type pt ) \ +{ \ + PDC dc = DC_HandleToPtr ( hdc ); \ + if ( !dc ) \ + return FALSE; \ + IntFuncName ( dc, pt ); \ + DC_ReleasePtr ( hdc ); \ + return TRUE; \ } #define DC_SET_MODE( func_name, dc_field, min_val, max_val ) \ @@ -601,7 +607,7 @@ W32kEnumObjects(HDC hDC, DC_GET_VAL( COLORREF, W32kGetBkColor, w.backgroundColor ) DC_GET_VAL( INT, W32kGetBkMode, w.backgroundMode ) -DC_GET_VAL_EX( W32kGetBrushOrgEx, w.brushOrgX, w.brushOrgY, POINT ) +DC_GET_VAL_EX( W32kGetBrushOrgEx, IntGetBrushOrgEx, w.brushOrgX, w.brushOrgY, POINT ) DC_GET_VAL( HRGN, W32kGetClipRgn, w.hClipRgn ) HGDIOBJ STDCALL @@ -610,7 +616,7 @@ W32kGetCurrentObject(HDC hDC, UINT ObjectType) UNIMPLEMENTED; } -DC_GET_VAL_EX( W32kGetCurrentPositionEx, w.CursPosX, w.CursPosY, POINT ) +DC_GET_VAL_EX ( W32kGetCurrentPositionEx, IntGetCurrentPositionEx, w.CursPosX, w.CursPosY, POINT ) BOOL STDCALL W32kGetDCOrgEx(HDC hDC, LPPOINT Point) @@ -1111,10 +1117,10 @@ DC_GET_VAL( INT, W32kGetROP2, w.ROPmode ) DC_GET_VAL( INT, W32kGetStretchBltMode, w.stretchBltMode ) DC_GET_VAL( UINT, W32kGetTextAlign, w.textAlign ) DC_GET_VAL( COLORREF, W32kGetTextColor, w.textColor ) -DC_GET_VAL_EX( W32kGetViewportExtEx, vportExtX, vportExtY, SIZE ) -DC_GET_VAL_EX( W32kGetViewportOrgEx, vportOrgX, vportOrgY, POINT ) -DC_GET_VAL_EX( W32kGetWindowExtEx, wndExtX, wndExtY, SIZE ) -DC_GET_VAL_EX( W32kGetWindowOrgEx, wndOrgX, wndOrgY, POINT ) +DC_GET_VAL_EX( W32kGetViewportExtEx, IntGetViewportExtEx, vportExtX, vportExtY, SIZE ) +DC_GET_VAL_EX( W32kGetViewportOrgEx, IntGetViewportOrgEx, vportOrgX, vportOrgY, POINT ) +DC_GET_VAL_EX( W32kGetWindowExtEx, IntGetWindowExtEx, wndExtX, wndExtY, SIZE ) +DC_GET_VAL_EX( W32kGetWindowOrgEx, IntGetWindowOrgEx, wndOrgX, wndOrgY, POINT ) HDC STDCALL W32kResetDC(HDC hDC, CONST DEVMODEW *InitData) @@ -1216,10 +1222,11 @@ W32kSaveDC(HDC hDC) return ret; } -HGDIOBJ STDCALL +HGDIOBJ +STDCALL W32kSelectObject(HDC hDC, HGDIOBJ hGDIObj) { - HGDIOBJ objOrg; + HGDIOBJ objOrg = NULL; // default to failure BITMAPOBJ *pb; PDC dc; PPENOBJ pen; @@ -1234,12 +1241,14 @@ W32kSelectObject(HDC hDC, HGDIOBJ hGDIObj) if(!hDC || !hGDIObj) return NULL; dc = DC_HandleToPtr(hDC); + ASSERT ( dc ); + objectMagic = GDIOBJ_GetHandleMagic (hGDIObj); // GdiObjHdr = hGDIObj; // FIXME: Get object handle from GDIObj and use it instead of GDIObj below? - switch(objectMagic) + switch ( objectMagic ) { case GO_PEN_MAGIC: objOrg = (HGDIOBJ)dc->w.hPen; @@ -1247,15 +1256,16 @@ W32kSelectObject(HDC hDC, HGDIOBJ hGDIObj) // Convert the color of the pen to the format of the DC PalGDI = (PPALGDI)AccessInternalObject((ULONG) dc->w.hPalette); - if( PalGDI ) + if ( PalGDI ) { XlateObj = (PXLATEOBJ)IntEngCreateXlate(PalGDI->Mode, PAL_RGB, dc->w.hPalette, NULL); + ASSERT ( XlateObj ); pen = GDIOBJ_LockObj(dc->w.hPen, GO_PEN_MAGIC); if( pen ) { pen->logpen.lopnColor = XLATEOBJ_iXlate(XlateObj, pen->logpen.lopnColor); + GDIOBJ_UnlockObj( dc->w.hPen, GO_PEN_MAGIC); } - GDIOBJ_UnlockObj( dc->w.hPen, GO_PEN_MAGIC); EngDeleteXlate(XlateObj); } break; @@ -1269,6 +1279,7 @@ W32kSelectObject(HDC hDC, HGDIOBJ hGDIObj) if( PalGDI ) { XlateObj = (PXLATEOBJ)IntEngCreateXlate(PalGDI->Mode, PAL_RGB, dc->w.hPalette, NULL); + ASSERT(XlateObj); brush = GDIOBJ_LockObj(dc->w.hBrush, GO_BRUSH_MAGIC); if( brush ) { @@ -1295,6 +1306,7 @@ W32kSelectObject(HDC hDC, HGDIOBJ hGDIObj) BITMAPOBJ_ReleasePtr(objOrg); dc->w.hBitmap = hGDIObj; pb = BITMAPOBJ_HandleToPtr(hGDIObj); + ASSERT(pb); dc->Surface = BitmapToSurf(pb); // if we're working with a DIB, get the palette [fixme: only create if the selected palette is null] @@ -1309,31 +1321,34 @@ W32kSelectObject(HDC hDC, HGDIOBJ hGDIObj) if(pb->dib->dsBmih.biBitCount == 8) { NumColors = 256; } ColorMap = ExAllocatePool(PagedPool, sizeof(COLORREF) * NumColors); + ASSERT(ColorMap); for (Index = 0; Index < NumColors; Index++) - { + { ColorMap[Index] = RGB(pb->ColorMap[Index].rgbRed, pb->ColorMap[Index].rgbGreen, pb->ColorMap[Index].rgbBlue); } dc->w.hPalette = EngCreatePalette(PAL_INDEXED, NumColors, (ULONG *) ColorMap, 0, 0, 0); ExFreePool(ColorMap); - } else - if(16 == pb->dib->dsBmih.biBitCount) + } + else if ( 16 == pb->dib->dsBmih.biBitCount ) { dc->w.hPalette = EngCreatePalette(PAL_BITFIELDS, pb->dib->dsBmih.biClrUsed, NULL, 0x7c00, 0x03e0, 0x001f); - } else - if(pb->dib->dsBmih.biBitCount >= 24) + } + else if(pb->dib->dsBmih.biBitCount >= 24) { dc->w.hPalette = EngCreatePalette(PAL_RGB, pb->dib->dsBmih.biClrUsed, NULL, 0, 0, 0); } - } else { + } + else + { dc->w.bitsPerPixel = pb->bitmap.bmBitsPixel; } DC_ReleasePtr ( hDC ); - hVisRgn = W32kCreateRectRgn(0, 0, pb->size.cx, pb->size.cy); - W32kSelectVisRgn(hDC, hVisRgn); - W32kDeleteObject(hVisRgn); + hVisRgn = W32kCreateRectRgn ( 0, 0, pb->size.cx, pb->size.cy ); + W32kSelectVisRgn ( hDC, hVisRgn ); + W32kDeleteObject ( hVisRgn ); return objOrg; @@ -1344,8 +1359,7 @@ W32kSelectObject(HDC hDC, HGDIOBJ hGDIObj) return NULL; #endif default: - DC_ReleasePtr ( hDC ); - return NULL; + break; } DC_ReleasePtr( hDC ); return objOrg; @@ -1360,132 +1374,126 @@ DC_SET_MODE( W32kSetStretchBltMode, w.stretchBltMode, BLACKONWHITE, HALFTONE ) COLORREF STDCALL W32kSetBkColor(HDC hDC, COLORREF color) { - COLORREF oldColor; + COLORREF oldColor; PDC dc = DC_HandleToPtr(hDC); - if (!dc) - { + if ( !dc ) return 0x80000000; - } oldColor = dc->w.backgroundColor; dc->w.backgroundColor = color; - DC_ReleasePtr( hDC ); - return oldColor; + DC_ReleasePtr ( hDC ); + return oldColor; } -STATIC VOID FASTCALL -W32kSetDCState16(HDC hDC, HDC hDCSave) +STATIC +VOID +FASTCALL +W32kSetDCState16 ( HDC hDC, HDC hDCSave ) { PDC dc, dcs; - dc = DC_HandleToPtr(hDC); - if (dc == NULL) + dc = DC_HandleToPtr ( hDC ); + if ( dc ) { - return; - } - - dcs = DC_HandleToPtr(hDCSave); - if (dcs == NULL) - { - DC_ReleasePtr( hDC ); - return; - } - if (!dcs->w.flags & DC_SAVED) - { - return; - } - - dc->w.flags = dcs->w.flags & ~DC_SAVED; - - dc->w.hFirstBitmap = dcs->w.hFirstBitmap; - -#if 0 - dc->w.hDevice = dcs->w.hDevice; -#endif - - dc->w.totalExtent = dcs->w.totalExtent; - dc->w.ROPmode = dcs->w.ROPmode; - dc->w.polyFillMode = dcs->w.polyFillMode; - dc->w.stretchBltMode = dcs->w.stretchBltMode; - dc->w.relAbsMode = dcs->w.relAbsMode; - dc->w.backgroundMode = dcs->w.backgroundMode; - dc->w.backgroundColor = dcs->w.backgroundColor; - dc->w.textColor = dcs->w.textColor; - dc->w.brushOrgX = dcs->w.brushOrgX; - dc->w.brushOrgY = dcs->w.brushOrgY; - dc->w.textAlign = dcs->w.textAlign; - dc->w.charExtra = dcs->w.charExtra; - dc->w.breakTotalExtra = dcs->w.breakTotalExtra; - dc->w.breakCount = dcs->w.breakCount; - dc->w.breakExtra = dcs->w.breakExtra; - dc->w.breakRem = dcs->w.breakRem; - dc->w.MapMode = dcs->w.MapMode; - dc->w.GraphicsMode = dcs->w.GraphicsMode; -#if 0 - /* Apparently, the DC origin is not changed by [GS]etDCState */ - dc->w.DCOrgX = dcs->w.DCOrgX; - dc->w.DCOrgY = dcs->w.DCOrgY; -#endif - dc->w.CursPosX = dcs->w.CursPosX; - dc->w.CursPosY = dcs->w.CursPosY; - dc->w.ArcDirection = dcs->w.ArcDirection; - -#if 0 - dc->w.xformWorld2Wnd = dcs->w.xformWorld2Wnd; - dc->w.xformWorld2Vport = dcs->w.xformWorld2Vport; - dc->w.xformVport2World = dcs->w.xformVport2World; - dc->w.vport2WorldValid = dcs->w.vport2WorldValid; -#endif - - dc->wndOrgX = dcs->wndOrgX; - dc->wndOrgY = dcs->wndOrgY; - dc->wndExtX = dcs->wndExtX; - dc->wndExtY = dcs->wndExtY; - dc->vportOrgX = dcs->vportOrgX; - dc->vportOrgY = dcs->vportOrgY; - dc->vportExtX = dcs->vportExtX; - dc->vportExtY = dcs->vportExtY; - - if (!(dc->w.flags & DC_MEMORY)) - { - dc->w.bitsPerPixel = dcs->w.bitsPerPixel; - } - -#if 0 - if (dcs->w.hClipRgn) - { - if (!dc->w.hClipRgn) + dcs = DC_HandleToPtr ( hDCSave ); + if ( dcs ) { - dc->w.hClipRgn = W32kCreateRectRgn( 0, 0, 0, 0 ); - } - W32kCombineRgn( dc->w.hClipRgn, dcs->w.hClipRgn, 0, RGN_COPY ); - } - else - { - if (dc->w.hClipRgn) - { - W32kDeleteObject( dc->w.hClipRgn ); - } + if ( dcs->w.flags & DC_SAVED ) + { + dc->w.flags = dcs->w.flags & ~DC_SAVED; - dc->w.hClipRgn = 0; - } - CLIPPING_UpdateGCRegion( dc ); -#endif - - W32kSelectObject( hDC, dcs->w.hBitmap ); - W32kSelectObject( hDC, dcs->w.hBrush ); - W32kSelectObject( hDC, dcs->w.hFont ); - W32kSelectObject( hDC, dcs->w.hPen ); - W32kSetBkColor( hDC, dcs->w.backgroundColor); - W32kSetTextColor( hDC, dcs->w.textColor); + dc->w.hFirstBitmap = dcs->w.hFirstBitmap; #if 0 - GDISelectPalette16( hDC, dcs->w.hPalette, FALSE ); + dc->w.hDevice = dcs->w.hDevice; #endif - DC_ReleasePtr( hDCSave ); - DC_ReleasePtr( hDC ); + dc->w.totalExtent = dcs->w.totalExtent; + dc->w.ROPmode = dcs->w.ROPmode; + dc->w.polyFillMode = dcs->w.polyFillMode; + dc->w.stretchBltMode = dcs->w.stretchBltMode; + dc->w.relAbsMode = dcs->w.relAbsMode; + dc->w.backgroundMode = dcs->w.backgroundMode; + dc->w.backgroundColor = dcs->w.backgroundColor; + dc->w.textColor = dcs->w.textColor; + dc->w.brushOrgX = dcs->w.brushOrgX; + dc->w.brushOrgY = dcs->w.brushOrgY; + dc->w.textAlign = dcs->w.textAlign; + dc->w.charExtra = dcs->w.charExtra; + dc->w.breakTotalExtra = dcs->w.breakTotalExtra; + dc->w.breakCount = dcs->w.breakCount; + dc->w.breakExtra = dcs->w.breakExtra; + dc->w.breakRem = dcs->w.breakRem; + dc->w.MapMode = dcs->w.MapMode; + dc->w.GraphicsMode = dcs->w.GraphicsMode; +#if 0 + /* Apparently, the DC origin is not changed by [GS]etDCState */ + dc->w.DCOrgX = dcs->w.DCOrgX; + dc->w.DCOrgY = dcs->w.DCOrgY; +#endif + dc->w.CursPosX = dcs->w.CursPosX; + dc->w.CursPosY = dcs->w.CursPosY; + dc->w.ArcDirection = dcs->w.ArcDirection; + +#if 0 + dc->w.xformWorld2Wnd = dcs->w.xformWorld2Wnd; + dc->w.xformWorld2Vport = dcs->w.xformWorld2Vport; + dc->w.xformVport2World = dcs->w.xformVport2World; + dc->w.vport2WorldValid = dcs->w.vport2WorldValid; +#endif + + dc->wndOrgX = dcs->wndOrgX; + dc->wndOrgY = dcs->wndOrgY; + dc->wndExtX = dcs->wndExtX; + dc->wndExtY = dcs->wndExtY; + dc->vportOrgX = dcs->vportOrgX; + dc->vportOrgY = dcs->vportOrgY; + dc->vportExtX = dcs->vportExtX; + dc->vportExtY = dcs->vportExtY; + + if (!(dc->w.flags & DC_MEMORY)) + { + dc->w.bitsPerPixel = dcs->w.bitsPerPixel; + } + +#if 0 + if (dcs->w.hClipRgn) + { + if (!dc->w.hClipRgn) + { + dc->w.hClipRgn = W32kCreateRectRgn( 0, 0, 0, 0 ); + } + W32kCombineRgn( dc->w.hClipRgn, dcs->w.hClipRgn, 0, RGN_COPY ); + } + else + { + if (dc->w.hClipRgn) + { + W32kDeleteObject( dc->w.hClipRgn ); + } + + dc->w.hClipRgn = 0; + } + CLIPPING_UpdateGCRegion( dc ); +#endif + + W32kSelectObject( hDC, dcs->w.hBitmap ); + W32kSelectObject( hDC, dcs->w.hBrush ); + W32kSelectObject( hDC, dcs->w.hFont ); + W32kSelectObject( hDC, dcs->w.hPen ); + W32kSetBkColor( hDC, dcs->w.backgroundColor); + W32kSetTextColor( hDC, dcs->w.textColor); + +#if 0 + GDISelectPalette16( hDC, dcs->w.hPalette, FALSE ); +#endif + } + + DC_ReleasePtr ( hDCSave ); + } + DC_ReleasePtr ( hDC ); + } } // ---------------------------------------------------- Private Interface @@ -1493,38 +1501,38 @@ W32kSetDCState16(HDC hDC, HDC hDCSave) HDC FASTCALL DC_AllocDC(LPCWSTR Driver) { - PDC NewDC; - HDC hDC; + PDC NewDC; + HDC hDC; - hDC = (HDC) GDIOBJ_AllocObj(sizeof(DC), GO_DC_MAGIC); - if (hDC == NULL) - { - return NULL; - } + hDC = (HDC) GDIOBJ_AllocObj(sizeof(DC), GO_DC_MAGIC); + if (hDC == NULL) + { + return NULL; + } - NewDC = (PDC) GDIOBJ_LockObj( hDC, GO_DC_MAGIC ); + NewDC = (PDC) GDIOBJ_LockObj( hDC, GO_DC_MAGIC ); - if (Driver != NULL) - { - NewDC->DriverName = ExAllocatePool(PagedPool, (wcslen(Driver) + 1) * sizeof(WCHAR)); - wcscpy(NewDC->DriverName, Driver); - } + if (Driver != NULL) + { + NewDC->DriverName = ExAllocatePool(PagedPool, (wcslen(Driver) + 1) * sizeof(WCHAR)); + wcscpy(NewDC->DriverName, Driver); + } - NewDC->w.xformWorld2Wnd.eM11 = 1.0f; - NewDC->w.xformWorld2Wnd.eM12 = 0.0f; - NewDC->w.xformWorld2Wnd.eM21 = 0.0f; - NewDC->w.xformWorld2Wnd.eM22 = 1.0f; - NewDC->w.xformWorld2Wnd.eDx = 0.0f; - NewDC->w.xformWorld2Wnd.eDy = 0.0f; - NewDC->w.xformWorld2Vport = NewDC->w.xformWorld2Wnd; - NewDC->w.xformVport2World = NewDC->w.xformWorld2Wnd; - NewDC->w.vport2WorldValid = TRUE; + NewDC->w.xformWorld2Wnd.eM11 = 1.0f; + NewDC->w.xformWorld2Wnd.eM12 = 0.0f; + NewDC->w.xformWorld2Wnd.eM21 = 0.0f; + NewDC->w.xformWorld2Wnd.eM22 = 1.0f; + NewDC->w.xformWorld2Wnd.eDx = 0.0f; + NewDC->w.xformWorld2Wnd.eDy = 0.0f; + NewDC->w.xformWorld2Vport = NewDC->w.xformWorld2Wnd; + NewDC->w.xformVport2World = NewDC->w.xformWorld2Wnd; + NewDC->w.vport2WorldValid = TRUE; - NewDC->w.hFont = W32kGetStockObject(SYSTEM_FONT); - TextIntRealizeFont(NewDC->w.hFont); + NewDC->w.hFont = W32kGetStockObject(SYSTEM_FONT); + TextIntRealizeFont(NewDC->w.hFont); - GDIOBJ_UnlockObj( hDC, GO_DC_MAGIC ); - return hDC; + GDIOBJ_UnlockObj( hDC, GO_DC_MAGIC ); + return hDC; } HDC FASTCALL diff --git a/reactos/subsys/win32k/objects/fillshap.c b/reactos/subsys/win32k/objects/fillshap.c index 4ef22a18fc1..0efd41bf9f7 100644 --- a/reactos/subsys/win32k/objects/fillshap.c +++ b/reactos/subsys/win32k/objects/fillshap.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: fillshap.c,v 1.24 2003/08/16 05:00:14 royce Exp $ */ +/* $Id: fillshap.c,v 1.25 2003/08/17 17:32:58 royce Exp $ */ #undef WIN32_LEAN_AND_MEAN #include @@ -31,7 +31,7 @@ #include #include -#define NDEBUG +//#define NDEBUG #include BOOL @@ -96,128 +96,149 @@ extern BOOL FillPolygon(PDC dc, #endif -//This implementation is blatantly ripped off from W32kRectangle BOOL -STDCALL -W32kPolygon(HDC hDC, - CONST PPOINT UnsafePoints, - int Count) +FASTCALL +IntPolygon(PDC dc, + CONST PPOINT UnsafePoints, + int Count) { - DC *dc = DC_HandleToPtr(hDC); - SURFOBJ *SurfObj = (SURFOBJ*)AccessUserObject((ULONG)dc->Surface); - PBRUSHOBJ OutBrushObj, FillBrushObj; - BOOL ret; + SURFOBJ *SurfObj; + BRUSHOBJ PenBrushObj, *FillBrushObj; + BOOL ret = FALSE; // default to failure PRECTL RectBounds; - PENOBJ *pen; RECTL DestRect; int CurrentPoint; PPOINT Points; NTSTATUS Status; - DPRINT("In W32kPolygon()\n"); - - if (NULL == dc || NULL == UnsafePoints || Count < 2) + ASSERT(dc); // caller's responsibility to pass a valid dc + + if ( NULL == UnsafePoints || Count < 2 ) { SetLastWin32Error(ERROR_INVALID_PARAMETER); return FALSE; } + SurfObj = (SURFOBJ*)AccessUserObject((ULONG)dc->Surface); + ASSERT(SurfObj); + /* Copy points from userspace to kernelspace */ Points = ExAllocatePool(PagedPool, Count * sizeof(POINT)); if (NULL == Points) - { - SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); - return FALSE; - } - Status = MmCopyFromCaller(Points, UnsafePoints, Count * sizeof(POINT)); - if (! NT_SUCCESS(Status)) - { - SetLastNtError(Status); - ExFreePool(Points); - return FALSE; - } - - /* Convert to screen coordinates */ - for (CurrentPoint = 0; CurrentPoint < Count; CurrentPoint++) - { - Points[CurrentPoint].x += dc->w.DCOrgX; - Points[CurrentPoint].y += dc->w.DCOrgY; - } - - RectBounds = GDIOBJ_LockObj(dc->w.hGCClipRgn, GO_REGION_MAGIC); - //ei not yet implemented ASSERT(RectBounds); - - if (PATH_IsPathOpen(dc->w.path)) - { - ret = PATH_Polygon(hDC, Points, Count); - } + SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); else + { + Status = MmCopyFromCaller(Points, UnsafePoints, Count * sizeof(POINT)); + if ( !NT_SUCCESS(Status) ) + SetLastNtError(Status); + else { - /* Get the current pen. */ - pen = (PENOBJ*) GDIOBJ_LockObj(dc->w.hPen, GO_PEN_MAGIC); - ASSERT(pen); - OutBrushObj = (PBRUSHOBJ) PenToBrushObj(dc, pen); - GDIOBJ_UnlockObj(dc->w.hPen, GO_PEN_MAGIC); + /* Convert to screen coordinates */ + for (CurrentPoint = 0; CurrentPoint < Count; CurrentPoint++) + { + Points[CurrentPoint].x += dc->w.DCOrgX; + Points[CurrentPoint].y += dc->w.DCOrgY; + } - DestRect.left = Points[0].x; - DestRect.right = Points[0].x; - DestRect.top = Points[0].y; - DestRect.bottom = Points[0].y; + RectBounds = GDIOBJ_LockObj(dc->w.hGCClipRgn, GO_REGION_MAGIC); + //ei not yet implemented ASSERT(RectBounds); - for (CurrentPoint = 1; CurrentPoint < Count; ++CurrentPoint) + if (PATH_IsPathOpen(dc->w.path)) + ret = PATH_Polygon(dc, Points, Count ); + else + { + DestRect.left = Points[0].x; + DestRect.right = Points[0].x; + DestRect.top = Points[0].y; + DestRect.bottom = Points[0].y; + + for (CurrentPoint = 1; CurrentPoint < Count; ++CurrentPoint) { DestRect.left = MIN(DestRect.left, Points[CurrentPoint].x); DestRect.right = MAX(DestRect.right, Points[CurrentPoint].x); DestRect.top = MIN(DestRect.top, Points[CurrentPoint].y); DestRect.bottom = MAX(DestRect.bottom, Points[CurrentPoint].y); } - - /* Now fill the polygon with the current brush. */ - FillBrushObj = (BRUSHOBJ*) GDIOBJ_LockObj(dc->w.hBrush, GO_BRUSH_MAGIC); #if 1 - ret = FillPolygon ( dc, SurfObj, FillBrushObj, dc->w.ROPmode, Points, Count, DestRect); + /* Now fill the polygon with the current brush. */ + FillBrushObj = (BRUSHOBJ*) GDIOBJ_LockObj(dc->w.hBrush, GO_BRUSH_MAGIC); + ASSERT(FillBrushObj); + if ( FillBrushObj->logbrush.lbStyle != BS_NULL ) + ret = FillPolygon ( dc, SurfObj, FillBrushObj, dc->w.ROPmode, Points, Count, DestRect ); + GDIOBJ_UnlockObj(dc->w.hBrush, GO_BRUSH_MAGIC); #endif - // Draw the Polygon Edges with the current pen - for (CurrentPoint = 0; CurrentPoint < Count; ++CurrentPoint) + + /* make BRUSHOBJ from current pen. */ + HPenToBrushObj ( &PenBrushObj, dc->w.hPen ); + + // Draw the Polygon Edges with the current pen ( if not a NULL pen ) + if ( PenBrushObj.logbrush.lbStyle != BS_NULL ) { - POINT To, From; //, Next; + for ( CurrentPoint = 0; CurrentPoint < Count; ++CurrentPoint ) + { + POINT To, From; //, Next; - /* Let CurrentPoint be i - * if i+1 > Count, Draw a line from Points[i] to Points[0] - * Draw a line from Points[i] to Points[i+1] - */ - From = Points[CurrentPoint]; - if (Count <= CurrentPoint + 1) - { + /* Let CurrentPoint be i + * if i+1 > Count, Draw a line from Points[i] to Points[0] + * Draw a line from Points[i] to Points[i+1] + */ + From = Points[CurrentPoint]; + if (Count <= CurrentPoint + 1) To = Points[0]; - } - else - { + else To = Points[CurrentPoint + 1]; - } - DPRINT("Polygon Making line from (%d,%d) to (%d,%d)\n", From.x, From.y, To.x, To.y ); - ret = IntEngLineTo(SurfObj, - dc->CombinedClip, - OutBrushObj, - From.x, - From.y, - To.x, - To.y, - &DestRect, - dc->w.ROPmode); /* MIX */ - + //DPRINT("Polygon Making line from (%d,%d) to (%d,%d)\n", From.x, From.y, To.x, To.y ); + ret = IntEngLineTo(SurfObj, + dc->CombinedClip, + &PenBrushObj, + From.x, + From.y, + To.x, + To.y, + &DestRect, + dc->w.ROPmode); /* MIX */ + } } #if 0 - ret = FillPolygon ( dc, SurfObj, FillBrushObj, dc->w.ROPmode, Points, Count, DestRect); + /* Now fill the polygon with the current brush. */ + FillBrushObj = (BRUSHOBJ*) GDIOBJ_LockObj(dc->w.hBrush, GO_BRUSH_MAGIC); + ASSERT(FillBrushObj); + if ( FillBrushObj->logbrush.lbStyle != BS_NULL ) + ret = FillPolygon ( dc, SurfObj, FillBrushObj, dc->w.ROPmode, Points, Count, DestRect ); + GDIOBJ_UnlockObj(dc->w.hBrush, GO_BRUSH_MAGIC); #endif - GDIOBJ_UnlockObj(dc->w.hBrush, GO_BRUSH_MAGIC); + } + + GDIOBJ_UnlockObj ( dc->w.hGCClipRgn, GO_REGION_MAGIC ); } - - GDIOBJ_UnlockObj(dc->w.hGCClipRgn, GO_REGION_MAGIC); - DC_ReleasePtr(hDC); - ExFreePool(Points); + ExFreePool ( Points ); + } + return ret; +} + +//This implementation is blatantly ripped off from W32kRectangle +BOOL +STDCALL +W32kPolygon(HDC hDC, + CONST PPOINT UnsafePoints, + int Count) +{ + DC *dc; + BOOL ret = FALSE; // default to failure + + //DPRINT("In W32kPolygon()\n"); + + dc = DC_HandleToPtr ( hDC ); + + if ( !dc ) + SetLastWin32Error(ERROR_INVALID_PARAMETER); + else + { + ret = IntPolygon ( dc, UnsafePoints, Count ); + DC_ReleasePtr ( hDC ); + } return ret; } @@ -225,114 +246,136 @@ W32kPolygon(HDC hDC, BOOL STDCALL -W32kPolyPolygon(HDC hDC, - CONST LPPOINT Points, - CONST LPINT PolyCounts, - int Count) +W32kPolyPolygon(HDC hDC, + CONST LPPOINT Points, + CONST LPINT PolyCounts, + int Count) { UNIMPLEMENTED; } BOOL -STDCALL -W32kRectangle(HDC hDC, - int LeftRect, - int TopRect, - int RightRect, - int BottomRect) +FASTCALL +IntRectangle(PDC dc, + int LeftRect, + int TopRect, + int RightRect, + int BottomRect) { - DC *dc = DC_HandleToPtr(hDC); - SURFOBJ *SurfObj = (SURFOBJ*)AccessUserObject((ULONG)dc->Surface); - PBRUSHOBJ BrushObj; - BOOL ret; - PRECTL RectBounds; - PENOBJ * pen; - RECTL DestRect; + SURFOBJ *SurfObj = (SURFOBJ*)AccessUserObject((ULONG)dc->Surface); + BRUSHOBJ PenBrushObj, *FillBrushObj; + BOOL ret = FALSE; // default to failure + PRECTL RectBounds; + RECTL DestRect; - if(!dc) - return FALSE; + ASSERT ( dc ); // caller's responsibility to set this up - RectBounds = GDIOBJ_LockObj(dc->w.hGCClipRgn, GO_REGION_MAGIC); + RectBounds = GDIOBJ_LockObj ( dc->w.hGCClipRgn, GO_REGION_MAGIC ); //ei not yet implemented ASSERT(RectBounds); - if(PATH_IsPathOpen(dc->w.path)) + if ( PATH_IsPathOpen(dc->w.path) ) { - ret = PATH_Rectangle(hDC, LeftRect, TopRect, RightRect, BottomRect); + ret = PATH_Rectangle ( dc, LeftRect, TopRect, RightRect, BottomRect ); } else { - // Draw the rectangle with the current pen - pen = (PENOBJ*) GDIOBJ_LockObj(dc->w.hPen, GO_PEN_MAGIC); - ASSERT(pen); - BrushObj = (PBRUSHOBJ)PenToBrushObj(dc, pen); - GDIOBJ_UnlockObj( dc->w.hPen, GO_PEN_MAGIC ); - - LeftRect += dc->w.DCOrgX; - RightRect += dc->w.DCOrgX - 1; - TopRect += dc->w.DCOrgY; + LeftRect += dc->w.DCOrgX; + RightRect += dc->w.DCOrgX - 1; + TopRect += dc->w.DCOrgY; BottomRect += dc->w.DCOrgY - 1; - ret = IntEngLineTo(SurfObj, - dc->CombinedClip, - BrushObj, - LeftRect, TopRect, RightRect, TopRect, - RectBounds, // Bounding rectangle - dc->w.ROPmode); // MIX + FillBrushObj = (BRUSHOBJ*) GDIOBJ_LockObj(dc->w.hBrush, GO_BRUSH_MAGIC); - ret = IntEngLineTo(SurfObj, - dc->CombinedClip, - BrushObj, - RightRect, TopRect, RightRect, BottomRect, - RectBounds, // Bounding rectangle - dc->w.ROPmode); // MIX - - ret = IntEngLineTo(SurfObj, - dc->CombinedClip, - BrushObj, - RightRect, BottomRect, LeftRect, BottomRect, - RectBounds, // Bounding rectangle - dc->w.ROPmode); // MIX - - ret = IntEngLineTo(SurfObj, - dc->CombinedClip, - BrushObj, - LeftRect, BottomRect, LeftRect, TopRect, - RectBounds, // Bounding rectangle - dc->w.ROPmode); // MIX */ - - // FIXME: BrushObj is obtained above; decide which one is correct - BrushObj = (BRUSHOBJ*) GDIOBJ_LockObj(dc->w.hBrush, GO_BRUSH_MAGIC); - - if (BrushObj) + ASSERT(FillBrushObj); // FIXME - I *think* this should always happen... + // it would be nice to remove the following if statement if that proves to be true + if ( FillBrushObj ) { - if (BrushObj->logbrush.lbStyle != BS_NULL) - { - DestRect.left = LeftRect + 1; - DestRect.right = RightRect; - DestRect.top = TopRect + 1; - DestRect.bottom = BottomRect; - ret = IntEngBitBlt(SurfObj, - NULL, - NULL, - NULL, - NULL, - &DestRect, - NULL, - NULL, - BrushObj, - NULL, - PATCOPY); - } + if ( FillBrushObj->logbrush.lbStyle != BS_NULL ) + { + DestRect.left = LeftRect; + DestRect.right = RightRect; + DestRect.top = TopRect; + DestRect.bottom = BottomRect; + ret = ret && IntEngBitBlt(SurfObj, + NULL, + NULL, + NULL, + NULL, + &DestRect, + NULL, + NULL, + FillBrushObj, + NULL, + PATCOPY); + } } + GDIOBJ_UnlockObj( dc->w.hBrush, GO_BRUSH_MAGIC ); + + /* make BRUSHOBJ from current pen. */ + HPenToBrushObj ( &PenBrushObj, dc->w.hPen ); + + // Draw the rectangle with the current pen + + ret = TRUE; // change default to success + + if ( PenBrushObj.logbrush.lbStyle != BS_NULL ) + { + ret = ret && IntEngLineTo(SurfObj, + dc->CombinedClip, + &PenBrushObj, + LeftRect, TopRect, RightRect, TopRect, + RectBounds, // Bounding rectangle + dc->w.ROPmode); // MIX + + ret = ret && IntEngLineTo(SurfObj, + dc->CombinedClip, + &PenBrushObj, + RightRect, TopRect, RightRect, BottomRect, + RectBounds, // Bounding rectangle + dc->w.ROPmode); // MIX + + ret = ret && IntEngLineTo(SurfObj, + dc->CombinedClip, + &PenBrushObj, + RightRect, BottomRect, LeftRect, BottomRect, + RectBounds, // Bounding rectangle + dc->w.ROPmode); // MIX + + ret = ret && IntEngLineTo(SurfObj, + dc->CombinedClip, + &PenBrushObj, + LeftRect, BottomRect, LeftRect, TopRect, + RectBounds, // Bounding rectangle + dc->w.ROPmode); // MIX */ + } } -// FIXME: Move current position in DC? + // FIXME: Move current position in DC? GDIOBJ_UnlockObj(dc->w.hGCClipRgn, GO_REGION_MAGIC); - DC_ReleasePtr( hDC ); return TRUE; } +BOOL +STDCALL +W32kRectangle(HDC hDC, + int LeftRect, + int TopRect, + int RightRect, + int BottomRect) +{ + DC *dc = DC_HandleToPtr(hDC); + BOOL ret = FALSE; // default to failure + + if ( dc ) + { + ret = IntRectangle ( dc, LeftRect, TopRect, RightRect, BottomRect ); + DC_ReleasePtr ( hDC ); + } + + return ret; +} + BOOL STDCALL W32kRoundRect(HDC hDC, diff --git a/reactos/subsys/win32k/objects/gdiobj.c b/reactos/subsys/win32k/objects/gdiobj.c index a3d4fd2cc42..2826f3edca4 100644 --- a/reactos/subsys/win32k/objects/gdiobj.c +++ b/reactos/subsys/win32k/objects/gdiobj.c @@ -19,7 +19,7 @@ /* * GDIOBJ.C - GDI object manipulation routines * - * $Id: gdiobj.c,v 1.34 2003/08/11 21:10:49 royce Exp $ + * $Id: gdiobj.c,v 1.35 2003/08/17 17:32:58 royce Exp $ * */ @@ -590,12 +590,21 @@ GDIOBJ_LockObjDbg ( const char* file, int line, HGDIOBJ hObj, WORD Magic ) if ( handleEntry == 0 || (handleEntry->wMagic != Magic && Magic != GO_MAGIC_DONTCARE ) || (handleEntry->hProcessId != (HANDLE)0xFFFFFFFF - && handleEntry->hProcessId != PsGetCurrentProcessId () + && handleEntry->hProcessId != PsGetCurrentProcessId () ) ) { - DPRINT1("GDIBOJ_LockObj failed for %d, magic: %d, reqMagic\n", - (WORD)((size_t)hObj&0xffff), handleEntry->wMagic, Magic); + int reason = 0; + if ( handleEntry == 0 ) + reason = 1; + else if ( handleEntry->wMagic != Magic && Magic != GO_MAGIC_DONTCARE ) + reason = 2; + else if ( handleEntry->hProcessId != (HANDLE)0xFFFFFFFF + && handleEntry->hProcessId != PsGetCurrentProcessId () ) + reason = 3; + + DPRINT1("GDIOBJ_LockObj failed for %d, magic: %d, reqMagic %d reason %d\n", + (WORD)((size_t)hObj&0xffff), handleEntry->wMagic, Magic, reason ); DPRINT1("\tcalled from: %s:%i\n", file, line ); return NULL; } diff --git a/reactos/subsys/win32k/objects/line.c b/reactos/subsys/win32k/objects/line.c index c058f61d883..664b5a2dd90 100644 --- a/reactos/subsys/win32k/objects/line.c +++ b/reactos/subsys/win32k/objects/line.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: line.c,v 1.18 2003/08/11 21:10:49 royce Exp $ */ +/* $Id: line.c,v 1.19 2003/08/17 17:32:58 royce Exp $ */ // Some code from the WINE project source (www.winehq.com) @@ -41,11 +41,11 @@ BOOL STDCALL W32kAngleArc(HDC hDC, - int X, - int Y, - DWORD Radius, - FLOAT StartAngle, - FLOAT SweepAngle) + int X, + int Y, + DWORD Radius, + FLOAT StartAngle, + FLOAT SweepAngle) { UNIMPLEMENTED; } @@ -53,22 +53,26 @@ W32kAngleArc(HDC hDC, BOOL STDCALL W32kArc(HDC hDC, - int LeftRect, - int TopRect, - int RightRect, - int BottomRect, - int XStartArc, - int YStartArc, - int XEndArc, - int YEndArc) + int LeftRect, + int TopRect, + int RightRect, + int BottomRect, + int XStartArc, + int YStartArc, + int XEndArc, + int YEndArc) { DC *dc = DC_HandleToPtr(hDC); if(!dc) return FALSE; if(PATH_IsPathOpen(dc->w.path)) + { + DC_ReleasePtr ( hDC ); return PATH_Arc(hDC, LeftRect, TopRect, RightRect, BottomRect, XStartArc, YStartArc, XEndArc, YEndArc); + } + // FIXME // EngArc(dc, LeftRect, TopRect, RightRect, BottomRect, UNIMPLEMENTED // XStartArc, YStartArc, XEndArc, YEndArc); @@ -79,50 +83,60 @@ W32kArc(HDC hDC, BOOL STDCALL W32kArcTo(HDC hDC, - int LeftRect, - int TopRect, - int RightRect, - int BottomRect, - int XRadial1, - int YRadial1, - int XRadial2, - int YRadial2) + int LeftRect, + int TopRect, + int RightRect, + int BottomRect, + int XRadial1, + int YRadial1, + int XRadial2, + int YRadial2) { BOOL result; - DC *dc = DC_HandleToPtr(hDC); - if(!dc) return FALSE; + //DC *dc; // Line from current position to starting point of arc - W32kLineTo(hDC, XRadial1, YRadial1); + if ( !W32kLineTo(hDC, XRadial1, YRadial1) ) + return FALSE; + + //dc = DC_HandleToPtr(hDC); + + //if(!dc) return FALSE; // Then the arc is drawn. result = W32kArc(hDC, LeftRect, TopRect, RightRect, BottomRect, XRadial1, YRadial1, XRadial2, YRadial2); + //DC_ReleasePtr( hDC ); + // If no error occured, the current position is moved to the ending point of the arc. if(result) - { W32kMoveToEx(hDC, XRadial2, YRadial2, NULL); - } - DC_ReleasePtr( hDC ); + return result; } +INT +FASTCALL +IntGetArcDirection ( PDC dc ) +{ + ASSERT ( dc ); + return dc->w.ArcDirection; +} + INT STDCALL W32kGetArcDirection(HDC hDC) { - PDC dc; - int ret; + PDC dc = DC_HandleToPtr (hDC); + int ret = 0; // default to failure - dc = DC_HandleToPtr (hDC); - if (!dc) + if ( dc ) { - return 0; + ret = IntGetArcDirection ( dc ); + DC_ReleasePtr( hDC ); } - ret = dc->w.ArcDirection; - DC_ReleasePtr( hDC ); return ret; } @@ -132,27 +146,36 @@ W32kLineTo(HDC hDC, int XEnd, int YEnd) { - DC *dc = DC_HandleToPtr(hDC); - SURFOBJ *SurfObj = (SURFOBJ*)AccessUserObject((ULONG)dc->Surface); - BOOL Ret; - PPENOBJ Pen; - RECT Bounds; + DC *dc = DC_HandleToPtr(hDC); + SURFOBJ *SurfObj; + BOOL Ret; + BRUSHOBJ PenBrushObj; + RECT Bounds; - if (NULL == dc) + if ( !dc ) { SetLastWin32Error(ERROR_INVALID_HANDLE); return FALSE; } + SurfObj = (SURFOBJ*)AccessUserObject ( (ULONG)dc->Surface ); + if (PATH_IsPathOpen(dc->w.path)) { + DC_ReleasePtr(hDC); Ret = PATH_LineTo(hDC, XEnd, YEnd); + if (Ret) + { + // FIXME - PATH_LineTo should maybe do this... + dc = DC_HandleToPtr(hDC); + dc->w.CursPosX = XEnd; + dc->w.CursPosY = YEnd; + DC_ReleasePtr(hDC); + } + return Ret; } else { - Pen = (PPENOBJ) GDIOBJ_LockObj(dc->w.hPen, GO_PEN_MAGIC); - ASSERT(NULL != Pen); - if (dc->w.CursPosX <= XEnd) { Bounds.left = dc->w.CursPosX; @@ -174,19 +197,20 @@ W32kLineTo(HDC hDC, { Bounds.top = YEnd; Bounds.bottom = dc->w.CursPosY; - } + } Bounds.top += dc->w.DCOrgY; Bounds.bottom += dc->w.DCOrgY; + /* make BRUSHOBJ from current pen. */ + HPenToBrushObj ( &PenBrushObj, dc->w.hPen ); + Ret = IntEngLineTo(SurfObj, dc->CombinedClip, - PenToBrushObj(dc, Pen), + &PenBrushObj, dc->w.DCOrgX + dc->w.CursPosX, dc->w.DCOrgY + dc->w.CursPosY, dc->w.DCOrgX + XEnd, dc->w.DCOrgY + YEnd, &Bounds, dc->w.ROPmode); - - GDIOBJ_UnlockObj( dc->w.hPen, GO_PEN_MAGIC); } if (Ret) @@ -201,84 +225,96 @@ W32kLineTo(HDC hDC, BOOL STDCALL -W32kMoveToEx(HDC hDC, - int X, - int Y, - LPPOINT Point) +W32kMoveToEx(HDC hDC, + int X, + int Y, + LPPOINT Point) { - DC *dc = DC_HandleToPtr( hDC ); + DC *dc = DC_HandleToPtr( hDC ); + BOOL PathIsOpen; - if(!dc) return FALSE; + if ( !dc ) return FALSE; - if(Point) { + if ( Point ) + { Point->x = dc->w.CursPosX; Point->y = dc->w.CursPosY; } dc->w.CursPosX = X; dc->w.CursPosY = Y; - if(PATH_IsPathOpen(dc->w.path)){ - DC_ReleasePtr( hDC ); - return PATH_MoveTo(hDC); - } - DC_ReleasePtr( hDC ); + PathIsOpen = PATH_IsPathOpen(dc->w.path); + + DC_ReleasePtr ( hDC ); + + if ( PathIsOpen ) + return PATH_MoveTo ( hDC ); + return TRUE; } BOOL STDCALL -W32kPolyBezier(HDC hDC, - CONST LPPOINT pt, - DWORD Count) +W32kPolyBezier(HDC hDC, + CONST LPPOINT pt, + DWORD Count) { DC *dc = DC_HandleToPtr(hDC); - if(!dc) return FALSE; + BOOL ret = FALSE; // default to FAILURE - if(PATH_IsPathOpen(dc->w.path)){ - DC_ReleasePtr( hDC ); - return PATH_PolyBezier(hDC, pt, Count); + if ( !dc ) return FALSE; + + if ( PATH_IsPathOpen(dc->w.path) ) + { + DC_ReleasePtr( hDC ); + return PATH_PolyBezier ( hDC, pt, Count ); } /* We'll convert it into line segments and draw them using Polyline */ { POINT *Pts; INT nOut; - BOOL ret; - Pts = GDI_Bezier(pt, Count, &nOut); - if(!Pts) return FALSE; - DbgPrint("Pts = %p, no = %d\n", Pts, nOut); - ret = W32kPolyline(dc->hSelf, Pts, nOut); - ExFreePool(Pts); - DC_ReleasePtr( hDC ); - return ret; + Pts = GDI_Bezier ( pt, Count, &nOut ); + if ( Pts ) + { + DbgPrint("Pts = %p, no = %d\n", Pts, nOut); + ret = W32kPolyline(dc->hSelf, Pts, nOut); + ExFreePool(Pts); + } } + DC_ReleasePtr( hDC ); + return ret; } BOOL STDCALL W32kPolyBezierTo(HDC hDC, - CONST LPPOINT pt, - DWORD Count) + CONST LPPOINT pt, + DWORD Count) { DC *dc = DC_HandleToPtr(hDC); - BOOL ret; + BOOL ret = FALSE; // default to failure - if(!dc) return FALSE; + if ( !dc ) return ret; - if(PATH_IsPathOpen(dc->w.path)) - ret = PATH_PolyBezierTo(hDC, pt, Count); - else { /* We'll do it using PolyBezier */ + if ( PATH_IsPathOpen(dc->w.path) ) + ret = PATH_PolyBezierTo ( hDC, pt, Count ); + else /* We'll do it using PolyBezier */ + { POINT *npt; npt = ExAllocatePool(NonPagedPool, sizeof(POINT) * (Count + 1)); - if(!npt) return FALSE; - npt[0].x = dc->w.CursPosX; - npt[0].y = dc->w.CursPosY; - memcpy(npt + 1, pt, sizeof(POINT) * Count); - ret = W32kPolyBezier(dc->hSelf, npt, Count+1); - ExFreePool(npt); + if ( npt ) + { + npt[0].x = dc->w.CursPosX; + npt[0].y = dc->w.CursPosY; + memcpy(npt + 1, pt, sizeof(POINT) * Count); + ret = W32kPolyBezier(dc->hSelf, npt, Count+1); + ExFreePool(npt); + } } - if(ret) { + if ( ret ) + { dc->w.CursPosX = pt[Count-1].x; dc->w.CursPosY = pt[Count-1].y; } @@ -288,114 +324,120 @@ W32kPolyBezierTo(HDC hDC, BOOL STDCALL -W32kPolyDraw(HDC hDC, - CONST LPPOINT pt, - CONST LPBYTE Types, - int Count) +W32kPolyDraw(HDC hDC, + CONST LPPOINT pt, + CONST LPBYTE Types, + int Count) { UNIMPLEMENTED; } BOOL -STDCALL -W32kPolyline(HDC hDC, - CONST LPPOINT pt, - int Count) +FASTCALL +IntPolyline(PDC dc, + CONST LPPOINT pt, + int Count) { - DC *dc = DC_HandleToPtr(hDC); - SURFOBJ *SurfObj = (SURFOBJ*)AccessUserObject((ULONG)dc->Surface); - BOOL ret; - LONG i; - PPENOBJ pen; + SURFOBJ *SurfObj = NULL; + BOOL ret = FALSE; // default to failure + LONG i; PROSRGNDATA reg; - POINT *pts; + BRUSHOBJ PenBrushObj; + POINT *pts; - if (!dc) - return(FALSE); + SurfObj = (SURFOBJ*)AccessUserObject((ULONG)dc->Surface); + ASSERT(SurfObj); - if(PATH_IsPathOpen(dc->w.path)) + if ( PATH_IsPathOpen ( dc->w.path ) ) + return PATH_Polyline ( dc, pt, Count ); + + reg = (PROSRGNDATA)GDIOBJ_LockObj(dc->w.hGCClipRgn, GO_REGION_MAGIC); + + //FIXME: Do somthing with reg... + + //Allocate "Count" bytes of memory to hold a safe copy of pt + pts = (POINT*)ExAllocatePool ( NonPagedPool, sizeof(POINT)*Count ); + if ( pts ) { - ret = PATH_Polyline(hDC, pt, Count); - } - else - { - pen = (PPENOBJ) GDIOBJ_LockObj(dc->w.hPen, GO_PEN_MAGIC); - reg = (PROSRGNDATA)GDIOBJ_LockObj(dc->w.hGCClipRgn, GO_REGION_MAGIC); - - ASSERT( pen ); - - //FIXME: Do somthing with reg... - - //Allocate "Count" bytes of memory to hold a safe copy of pt - if (!(pts=ExAllocatePool(NonPagedPool, sizeof(POINT) * Count))) + // safely copy pt to local version + if ( STATUS_SUCCESS == MmCopyFromCaller(pts, pt, sizeof(POINT)*Count) ) { - GDIOBJ_UnlockObj( dc->w.hGCClipRgn, GO_REGION_MAGIC ); - GDIOBJ_UnlockObj( dc->w.hPen, GO_PEN_MAGIC); - DC_ReleasePtr( hDC ); - return(FALSE); - } - - //safly copy pt to local version - if (STATUS_SUCCESS!=MmCopyFromCaller(pts, pt, sizeof(POINT) * Count)) - { - ExFreePool(pts); - GDIOBJ_UnlockObj( dc->w.hGCClipRgn, GO_REGION_MAGIC ); - GDIOBJ_UnlockObj( dc->w.hPen, GO_PEN_MAGIC); - DC_ReleasePtr( hDC ); - return(FALSE); + //offset the array of point by the dc->w.DCOrg + for ( i = 0; i < Count; i++ ) + { + pts[i].x += dc->w.DCOrgX; + pts[i].y += dc->w.DCOrgY; + } + + /* make BRUSHOBJ from current pen. */ + HPenToBrushObj ( &PenBrushObj, dc->w.hPen ); + + //get IntEngPolyline to do the drawing. + ret = IntEngPolyline(SurfObj, + dc->CombinedClip, + &PenBrushObj, + pts, + Count, + dc->w.ROPmode); } - //offset the array of point by the dc->w.DCOrg - for(i=0; iw.DCOrgX; - pts[i].y += dc->w.DCOrgY; - } - - //get IntEngPolyline to do the drawing. - ret = IntEngPolyline(SurfObj, - dc->CombinedClip, - PenToBrushObj(dc, pen), - pts, - Count, - dc->w.ROPmode); - - //Clean up - ExFreePool(pts); - GDIOBJ_UnlockObj( dc->w.hGCClipRgn, GO_REGION_MAGIC ); - GDIOBJ_UnlockObj( dc->w.hPen, GO_PEN_MAGIC); + ExFreePool ( pts ); } - DC_ReleasePtr( hDC ); - return(ret); + //Clean up + GDIOBJ_UnlockObj ( dc->w.hGCClipRgn, GO_REGION_MAGIC ); + + return ret; } BOOL STDCALL -W32kPolylineTo(HDC hDC, - CONST LPPOINT pt, - DWORD Count) +W32kPolyline(HDC hDC, + CONST LPPOINT pt, + int Count) +{ + DC *dc = DC_HandleToPtr(hDC); + BOOL ret = FALSE; // default to failure + + if ( dc ) + { + ret = IntPolyline ( dc, pt, Count ); + + DC_ReleasePtr( hDC ); + } + + return ret; +} + +BOOL +STDCALL +W32kPolylineTo(HDC hDC, + CONST LPPOINT pt, + DWORD Count) { DC *dc = DC_HandleToPtr(hDC); - BOOL ret; + BOOL ret = FALSE; // default to failure - if(!dc) return FALSE; + if ( !dc ) return ret; if(PATH_IsPathOpen(dc->w.path)) { ret = PATH_PolylineTo(hDC, pt, Count); } - else { /* do it using Polyline */ + else /* do it using Polyline */ + { POINT *pts = ExAllocatePool(NonPagedPool, sizeof(POINT) * (Count + 1)); - if(!pts) return FALSE; - - pts[0].x = dc->w.CursPosX; - pts[0].y = dc->w.CursPosY; - memcpy( pts + 1, pt, sizeof(POINT) * Count); - ret = W32kPolyline(hDC, pts, Count + 1); - ExFreePool(pts); + if ( pts ) + { + pts[0].x = dc->w.CursPosX; + pts[0].y = dc->w.CursPosY; + memcpy( pts + 1, pt, sizeof(POINT) * Count); + ret = W32kPolyline(hDC, pts, Count + 1); + ExFreePool(pts); + } } - if(ret) { + if ( ret ) + { dc->w.CursPosX = pt[Count-1].x; dc->w.CursPosY = pt[Count-1].y; } @@ -405,10 +447,10 @@ W32kPolylineTo(HDC hDC, BOOL STDCALL -W32kPolyPolyline(HDC hDC, - CONST LPPOINT pt, - CONST LPDWORD PolyPoints, - DWORD Count) +W32kPolyPolyline(HDC hDC, + CONST LPPOINT pt, + CONST LPDWORD PolyPoints, + DWORD Count) { UNIMPLEMENTED; } @@ -416,25 +458,20 @@ W32kPolyPolyline(HDC hDC, int STDCALL W32kSetArcDirection(HDC hDC, - int ArcDirection) + int ArcDirection) { PDC dc; - INT nOldDirection; + INT nOldDirection = 0; // default to FAILURE dc = DC_HandleToPtr (hDC); - if (!dc) + if ( !dc ) return 0; + + if ( ArcDirection == AD_COUNTERCLOCKWISE || ArcDirection == AD_CLOCKWISE ) { - return 0; - } - if (ArcDirection != AD_COUNTERCLOCKWISE && ArcDirection != AD_CLOCKWISE) - { -// SetLastError(ERROR_INVALID_PARAMETER); - DC_ReleasePtr( hDC ); - return 0; + nOldDirection = dc->w.ArcDirection; + dc->w.ArcDirection = ArcDirection; } - nOldDirection = dc->w.ArcDirection; - dc->w.ArcDirection = ArcDirection; DC_ReleasePtr( hDC ); return nOldDirection; } diff --git a/reactos/subsys/win32k/objects/objconv.c b/reactos/subsys/win32k/objects/objconv.c index 2b82639183f..c08c20a4317 100644 --- a/reactos/subsys/win32k/objects/objconv.c +++ b/reactos/subsys/win32k/objects/objconv.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: objconv.c,v 1.10 2003/08/11 21:10:49 royce Exp $ */ +/* $Id: objconv.c,v 1.11 2003/08/17 17:32:58 royce Exp $ */ #undef WIN32_LEAN_AND_MEAN #include @@ -35,27 +35,43 @@ #include #include -#define NDEBUG +//#define NDEBUG #include -PBRUSHOBJ FASTCALL PenToBrushObj(PDC dc, PENOBJ *pen) +BRUSHOBJ* +FASTCALL +PenToBrushObj ( BRUSHOBJ *brush, PENOBJ *pen ) { - BRUSHOBJ *BrushObj; - //XLATEOBJ *RGBtoVGA16; + ASSERT ( pen ); + ASSERT ( brush ); + memset ( brush, 0, sizeof(BRUSHOBJ) ); + if ( pen->logpen.lopnStyle == PS_NULL ) + brush->logbrush.lbStyle = BS_NULL; + else + brush->iSolidColor = pen->logpen.lopnColor; + return brush; +} - ASSERT( pen ); - - BrushObj = ExAllocatePool(NonPagedPool, sizeof(BRUSHOBJ)); - BrushObj->iSolidColor = pen->logpen.lopnColor; - - return BrushObj; +BRUSHOBJ* +FASTCALL +HPenToBrushObj ( BRUSHOBJ *brush, HPEN hpen ) +{ + PENOBJ *pen; + ASSERT ( hpen ); + ASSERT ( brush ); + pen = (PPENOBJ)GDIOBJ_LockObj ( hpen, GO_PEN_MAGIC ); + ASSERT ( pen ); + PenToBrushObj ( brush, pen ); + GDIOBJ_UnlockObj ( hpen, GO_PEN_MAGIC ); + return brush; } HBITMAP FASTCALL BitmapToSurf(PBITMAPOBJ BitmapObj) { HBITMAP BitmapHandle; + ASSERT ( BitmapObj ); if (NULL != BitmapObj->dib) { BitmapHandle = EngCreateBitmap(BitmapObj->size, BitmapObj->dib->dsBm.bmWidthBytes, diff --git a/reactos/subsys/win32k/objects/path.c b/reactos/subsys/win32k/objects/path.c index 794545e994d..4c0649d8294 100644 --- a/reactos/subsys/win32k/objects/path.c +++ b/reactos/subsys/win32k/objects/path.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: path.c,v 1.12 2003/08/13 20:24:05 chorns Exp $ */ +/* $Id: path.c,v 1.13 2003/08/17 17:32:58 royce Exp $ */ #undef WIN32_LEAN_AND_MEAN #include #include @@ -58,10 +58,27 @@ W32kBeginPath(HDC hDC) } BOOL -STDCALL -W32kCloseFigure(HDC hDC) +FASTCALL +IntCloseFigure ( PDC dc ) { UNIMPLEMENTED; + return FALSE; +} + +BOOL +STDCALL +W32kCloseFigure ( HDC hDC ) +{ + PDC dc = DC_HandleToPtr ( hDC ); + BOOL ret = FALSE; // default to failure + + if ( dc ) + { + ret = IntCloseFigure ( dc ); + DC_ReleasePtr ( hDC ); + } + + return ret; } BOOL @@ -149,7 +166,9 @@ W32kWidenPath(HDC hDC) * * Initializes the GdiPath structure. */ -VOID FASTCALL PATH_InitGdiPath(GdiPath *pPath) +VOID +FASTCALL +PATH_InitGdiPath ( GdiPath *pPath ) { assert(pPath!=NULL); @@ -164,7 +183,9 @@ VOID FASTCALL PATH_InitGdiPath(GdiPath *pPath) * * Destroys a GdiPath structure (frees the memory in the arrays). */ -VOID FASTCALL PATH_DestroyGdiPath(GdiPath *pPath) +VOID +FASTCALL +PATH_DestroyGdiPath ( GdiPath *pPath ) { assert(pPath!=NULL); @@ -182,12 +203,14 @@ VOID FASTCALL PATH_DestroyGdiPath(GdiPath *pPath) * not a copy constructor). * Returns TRUE if successful, else FALSE. */ -BOOL FASTCALL PATH_AssignGdiPath(GdiPath *pPathDest, const GdiPath *pPathSrc) +BOOL +FASTCALL +PATH_AssignGdiPath ( GdiPath *pPathDest, const GdiPath *pPathSrc ) { assert(pPathDest!=NULL && pPathSrc!=NULL); /* Make sure destination arrays are big enough */ - if(!PATH_ReserveEntries(pPathDest, pPathSrc->numEntriesUsed)) + if ( !PATH_ReserveEntries(pPathDest, pPathSrc->numEntriesUsed) ) return FALSE; /* Perform the copy operation */ @@ -209,21 +232,22 @@ BOOL FASTCALL PATH_AssignGdiPath(GdiPath *pPathDest, const GdiPath *pPathSrc) * open path. This starts a new stroke. Returns TRUE if successful, else * FALSE. */ -BOOL FASTCALL PATH_MoveTo(HDC hdc) +BOOL +FASTCALL +PATH_MoveTo ( PDC dc ) { GdiPath *pPath; /* Get pointer to path */ - if(!PATH_GetPathFromHDC(hdc, &pPath)) - return FALSE; + PATH_GetPathFromDC ( dc, &pPath ); /* Check that path is open */ - if(pPath->state!=PATH_Open) + if ( pPath->state != PATH_Open ) /* FIXME: Do we have to call SetLastError? */ return FALSE; /* Start a new stroke */ - pPath->newStroke=TRUE; + pPath->newStroke = TRUE; return TRUE; } @@ -235,33 +259,32 @@ BOOL FASTCALL PATH_MoveTo(HDC hdc) * a PT_MOVETO entry, if this is the first LineTo in a stroke). * Returns TRUE if successful, else FALSE. */ -BOOL STDCALL PATH_LineTo(HDC hdc, INT x, INT y) +BOOL +FASTCALL +PATH_LineTo ( PDC dc, INT x, INT y ) { GdiPath *pPath; POINT point, pointCurPos; /* Get pointer to path */ - if(!PATH_GetPathFromHDC(hdc, &pPath)) - return FALSE; + PATH_GetPathFromDC ( dc, &pPath ); /* Check that path is open */ - if(pPath->state!=PATH_Open) + if ( pPath->state != PATH_Open ) return FALSE; /* Convert point to device coordinates */ point.x=x; point.y=y; - if(!W32kLPtoDP(hdc, &point, 1)) - return FALSE; + CoordLPtoDP ( dc, &point ); /* Add a PT_MOVETO if necessary */ - if(pPath->newStroke) + if ( pPath->newStroke ) { - pPath->newStroke=FALSE; - if(!W32kGetCurrentPositionEx(hdc, &pointCurPos) || - !W32kLPtoDP(hdc, &pointCurPos, 1)) - return FALSE; - if(!PATH_AddEntry(pPath, &pointCurPos, PT_MOVETO)) + pPath->newStroke = FALSE; + IntGetCurrentPositionEx ( dc, &pointCurPos ); + CoordLPtoDP ( dc, &pointCurPos ); + if ( !PATH_AddEntry(pPath, &pointCurPos, PT_MOVETO) ) return FALSE; } @@ -274,18 +297,19 @@ BOOL STDCALL PATH_LineTo(HDC hdc, INT x, INT y) * Should be called when a call to Rectangle is performed on a DC that has * an open path. Returns TRUE if successful, else FALSE. */ -BOOL STDCALL PATH_Rectangle(HDC hdc, INT x1, INT y1, INT x2, INT y2) +BOOL +FASTCALL +PATH_Rectangle ( PDC dc, INT x1, INT y1, INT x2, INT y2 ) { GdiPath *pPath; POINT corners[2], pointTemp; INT temp; /* Get pointer to path */ - if(!PATH_GetPathFromHDC(hdc, &pPath)) - return FALSE; + PATH_GetPathFromDC ( dc, &pPath ); /* Check that path is open */ - if(pPath->state!=PATH_Open) + if ( pPath->state != PATH_Open ) return FALSE; /* Convert points to device coordinates */ @@ -293,17 +317,16 @@ BOOL STDCALL PATH_Rectangle(HDC hdc, INT x1, INT y1, INT x2, INT y2) corners[0].y=y1; corners[1].x=x2; corners[1].y=y2; - if(!W32kLPtoDP(hdc, corners, 2)) - return FALSE; + IntLPtoDP ( dc, corners, 2 ); /* Make sure first corner is top left and second corner is bottom right */ - if(corners[0].x>corners[1].x) + if ( corners[0].x > corners[1].x ) { temp=corners[0].x; corners[0].x=corners[1].x; corners[1].x=temp; } - if(corners[0].y>corners[1].y) + if ( corners[0].y > corners[1].y ) { temp=corners[0].y; corners[0].y=corners[1].y; @@ -311,14 +334,14 @@ BOOL STDCALL PATH_Rectangle(HDC hdc, INT x1, INT y1, INT x2, INT y2) } /* In GM_COMPATIBLE, don't include bottom and right edges */ - if(W32kGetGraphicsMode(hdc)==GM_COMPATIBLE) + if ( IntGetGraphicsMode(dc) == GM_COMPATIBLE ) { corners[1].x--; corners[1].y--; } /* Close any previous figure */ - if(!W32kCloseFigure(hdc)) + if ( !IntCloseFigure ( dc ) ) { /* The W32kCloseFigure call shouldn't have failed */ assert(FALSE); @@ -328,21 +351,21 @@ BOOL STDCALL PATH_Rectangle(HDC hdc, INT x1, INT y1, INT x2, INT y2) /* Add four points to the path */ pointTemp.x=corners[1].x; pointTemp.y=corners[0].y; - if(!PATH_AddEntry(pPath, &pointTemp, PT_MOVETO)) + if ( !PATH_AddEntry(pPath, &pointTemp, PT_MOVETO) ) return FALSE; - if(!PATH_AddEntry(pPath, corners, PT_LINETO)) + if ( !PATH_AddEntry(pPath, corners, PT_LINETO) ) return FALSE; pointTemp.x=corners[0].x; pointTemp.y=corners[1].y; - if(!PATH_AddEntry(pPath, &pointTemp, PT_LINETO)) + if ( !PATH_AddEntry(pPath, &pointTemp, PT_LINETO) ) return FALSE; - if(!PATH_AddEntry(pPath, corners+1, PT_LINETO)) + if ( !PATH_AddEntry(pPath, corners+1, PT_LINETO) ) return FALSE; /* Close the rectangle figure */ - if(!W32kCloseFigure(hdc)) + if ( !IntCloseFigure ( dc ) ) { - /* The W32kCloseFigure call shouldn't have failed */ + /* The IntCloseFigure call shouldn't have failed */ assert(FALSE); return FALSE; } @@ -356,11 +379,13 @@ BOOL STDCALL PATH_Rectangle(HDC hdc, INT x1, INT y1, INT x2, INT y2) * an open path. This adds four Bezier splines representing the ellipse * to the path. Returns TRUE if successful, else FALSE. */ -BOOL STDCALL PATH_Ellipse(HDC hdc, INT x1, INT y1, INT x2, INT y2) +BOOL +FASTCALL +PATH_Ellipse ( PDC dc, INT x1, INT y1, INT x2, INT y2 ) { /* TODO: This should probably be revised to call PATH_AngleArc */ /* (once it exists) */ - return PATH_Arc(hdc, x1, y1, x2, y2, x1, (y1+y2)/2, x1, (y1+y2)/2); + return PATH_Arc ( dc, x1, y1, x2, y2, x1, (y1+y2)/2, x1, (y1+y2)/2 ); } /* PATH_Arc @@ -369,7 +394,9 @@ BOOL STDCALL PATH_Ellipse(HDC hdc, INT x1, INT y1, INT x2, INT y2) * an open path. This adds up to five Bezier splines representing the arc * to the path. Returns TRUE if successful, else FALSE. */ -BOOL STDCALL PATH_Arc(HDC hdc, INT x1, INT y1, INT x2, INT y2, +BOOL +FASTCALL +PATH_Arc ( PDC dc, INT x1, INT y1, INT x2, INT y2, INT xStart, INT yStart, INT xEnd, INT yEnd) { GdiPath *pPath; @@ -380,35 +407,28 @@ BOOL STDCALL PATH_Arc(HDC hdc, INT x1, INT y1, INT x2, INT y2, FLOAT_POINT corners[2], pointStart, pointEnd; BOOL start, end; INT temp; + BOOL clockwise; /* FIXME: This function should check for all possible error returns */ /* FIXME: Do we have to respect newStroke? */ - /* Get pointer to DC */ - pDC=DC_HandleToPtr(hdc); - if(pDC==NULL) - return FALSE; + ASSERT ( dc ); + + clockwise = ( IntGetArcDirection(dc) == AD_CLOCKWISE ); /* Get pointer to path */ - if(!PATH_GetPathFromHDC(hdc, &pPath)){ - DC_ReleasePtr( hdc ); - return FALSE; - } + PATH_GetPathFromDC ( dc, &pPath ); /* Check that path is open */ - if(pPath->state!=PATH_Open){ - DC_ReleasePtr( hdc ); + if ( pPath->state != PATH_Open ) return FALSE; - } /* FIXME: Do we have to close the current figure? */ /* Check for zero height / width */ /* FIXME: Only in GM_COMPATIBLE? */ - if(x1==x2 || y1==y2){ - DC_ReleasePtr( hdc ); + if ( x1==x2 || y1==y2 ) return TRUE; - } /* Convert points to device coordinates */ corners[0].x=(FLOAT)x1; @@ -425,13 +445,13 @@ BOOL STDCALL PATH_Arc(HDC hdc, INT x1, INT y1, INT x2, INT y2, INTERNAL_LPTODP_FLOAT(pDC, &pointEnd); /* Make sure first corner is top left and second corner is bottom right */ - if(corners[0].x>corners[1].x) + if ( corners[0].x > corners[1].x ) { temp=corners[0].x; corners[0].x=corners[1].x; corners[1].x=temp; } - if(corners[0].y>corners[1].y) + if ( corners[0].y > corners[1].y ) { temp=corners[0].y; corners[0].y=corners[1].y; @@ -445,9 +465,9 @@ BOOL STDCALL PATH_Arc(HDC hdc, INT x1, INT y1, INT x2, INT y2, angleEnd=atan2(y, x); /* Make sure the end angle is "on the right side" of the start angle */ - if(W32kGetArcDirection(hdc)==AD_CLOCKWISE) + if ( clockwise ) { - if(angleEnd<=angleStart) + if ( angleEnd <= angleStart ) { angleEnd+=2*M_PI; assert(angleEnd>=angleStart); @@ -463,7 +483,7 @@ BOOL STDCALL PATH_Arc(HDC hdc, INT x1, INT y1, INT x2, INT y2, } /* In GM_COMPATIBLE, don't include bottom and right edges */ - if(W32kGetGraphicsMode(hdc)==GM_COMPATIBLE) + if ( IntGetGraphicsMode(dc) == GM_COMPATIBLE ) { corners[1].x--; corners[1].y--; @@ -479,7 +499,7 @@ BOOL STDCALL PATH_Arc(HDC hdc, INT x1, INT y1, INT x2, INT y2, if(start) { angleStartQuadrant=angleStart; - if(W32kGetArcDirection(hdc)==AD_CLOCKWISE) + if ( clockwise ) angleEndQuadrant=(floor(angleStart/M_PI_2)+1.0)*M_PI_2; else angleEndQuadrant=(ceil(angleStart/M_PI_2)-1.0)*M_PI_2; @@ -487,137 +507,154 @@ BOOL STDCALL PATH_Arc(HDC hdc, INT x1, INT y1, INT x2, INT y2, else { angleStartQuadrant=angleEndQuadrant; - if(W32kGetArcDirection(hdc)==AD_CLOCKWISE) + if ( clockwise ) angleEndQuadrant+=M_PI_2; else angleEndQuadrant-=M_PI_2; } /* Have we reached the last part of the arc? */ - if((W32kGetArcDirection(hdc)==AD_CLOCKWISE && - angleEndangleEndQuadrant)) + if ( (clockwise && angleEndangleEndQuadrant) + ) { /* Adjust the end angle for this quadrant */ - angleEndQuadrant=angleEnd; - end=TRUE; + angleEndQuadrant = angleEnd; + end = TRUE; } /* Add the Bezier spline to the path */ - PATH_DoArcPart(pPath, corners, angleStartQuadrant, angleEndQuadrant, start); - start=FALSE; - } while(!end); + PATH_DoArcPart ( pPath, corners, angleStartQuadrant, angleEndQuadrant, start ); + start = FALSE; + } while(!end); - DC_ReleasePtr( hdc ); return TRUE; } -BOOL STDCALL PATH_PolyBezierTo(HDC hdc, const POINT *pts, DWORD cbPoints) +BOOL +FASTCALL +PATH_PolyBezierTo ( PDC dc, const POINT *pts, DWORD cbPoints ) { GdiPath *pPath; POINT pt; ULONG i; - if(!PATH_GetPathFromHDC(hdc, &pPath)) - return FALSE; + ASSERT ( dc ); + ASSERT ( pts ); + ASSERT ( cbPoints ); + + PATH_GetPathFromDC ( dc, &pPath ); /* Check that path is open */ - if(pPath->state!=PATH_Open) + if ( pPath->state != PATH_Open ) return FALSE; /* Add a PT_MOVETO if necessary */ - if(pPath->newStroke) + if ( pPath->newStroke ) { pPath->newStroke=FALSE; - if(!W32kGetCurrentPositionEx(hdc, &pt) || - !W32kLPtoDP(hdc, &pt, 1)) - return FALSE; - if(!PATH_AddEntry(pPath, &pt, PT_MOVETO)) + IntGetCurrentPositionEx ( dc, &pt ); + CoordLPtoDP ( dc, &pt ); + if ( !PATH_AddEntry(pPath, &pt, PT_MOVETO) ) return FALSE; } - for(i = 0; i < cbPoints; i++) { + for(i = 0; i < cbPoints; i++) + { pt = pts[i]; - if(!W32kLPtoDP(hdc, &pt, 1)) - return FALSE; + CoordLPtoDP ( dc, &pt ); PATH_AddEntry(pPath, &pt, PT_BEZIERTO); } return TRUE; } -BOOL STDCALL PATH_PolyBezier(HDC hdc, const POINT *pts, DWORD cbPoints) +BOOL +FASTCALL +PATH_PolyBezier ( PDC dc, const POINT *pts, DWORD cbPoints ) { GdiPath *pPath; POINT pt; ULONG i; - if(!PATH_GetPathFromHDC(hdc, &pPath)) - return FALSE; + ASSERT ( dc ); + ASSERT ( pts ); + ASSERT ( cbPoints ); + + PATH_GetPathFromDC ( dc, &pPath ); /* Check that path is open */ - if(pPath->state!=PATH_Open) + if ( pPath->state != PATH_Open ) return FALSE; - for(i = 0; i < cbPoints; i++) { + for ( i = 0; i < cbPoints; i++ ) + { pt = pts[i]; - if(!W32kLPtoDP(hdc, &pt, 1)) - return FALSE; - PATH_AddEntry(pPath, &pt, (i == 0) ? PT_MOVETO : PT_BEZIERTO); + CoordLPtoDP ( dc, &pt ); + PATH_AddEntry ( pPath, &pt, (i == 0) ? PT_MOVETO : PT_BEZIERTO ); } + return TRUE; } -BOOL STDCALL PATH_Polyline(HDC hdc, const POINT *pts, DWORD cbPoints) +BOOL +FASTCALL +PATH_Polyline ( PDC dc, const POINT *pts, DWORD cbPoints ) { GdiPath *pPath; POINT pt; ULONG i; - if(!PATH_GetPathFromHDC(hdc, &pPath)) - return FALSE; + ASSERT ( dc ); + ASSERT ( pts ); + ASSERT ( cbPoints ); + + PATH_GetPathFromDC ( dc, &pPath ); /* Check that path is open */ - if(pPath->state!=PATH_Open) + if ( pPath->state != PATH_Open ) return FALSE; - for(i = 0; i < cbPoints; i++) { + for ( i = 0; i < cbPoints; i++ ) + { pt = pts[i]; - if(!W32kLPtoDP(hdc, &pt, 1)) - return FALSE; + CoordLPtoDP ( dc, &pt ); PATH_AddEntry(pPath, &pt, (i == 0) ? PT_MOVETO : PT_LINETO); } return TRUE; } -BOOL STDCALL PATH_PolylineTo(HDC hdc, const POINT *pts, DWORD cbPoints) +BOOL +FASTCALL +PATH_PolylineTo ( PDC dc, const POINT *pts, DWORD cbPoints ) { GdiPath *pPath; POINT pt; ULONG i; - if(!PATH_GetPathFromHDC(hdc, &pPath)) - return FALSE; + ASSERT ( dc ); + ASSERT ( pts ); + ASSERT ( cbPoints ); + + PATH_GetPathFromDC ( dc, &pPath ); /* Check that path is open */ - if(pPath->state!=PATH_Open) + if ( pPath->state != PATH_Open ) return FALSE; /* Add a PT_MOVETO if necessary */ - if(pPath->newStroke) + if ( pPath->newStroke ) { - pPath->newStroke=FALSE; - if(!W32kGetCurrentPositionEx(hdc, &pt) || - !W32kLPtoDP(hdc, &pt, 1)) - return FALSE; - if(!PATH_AddEntry(pPath, &pt, PT_MOVETO)) + pPath->newStroke = FALSE; + IntGetCurrentPositionEx ( dc, &pt ); + CoordLPtoDP ( dc, &pt ); + if ( !PATH_AddEntry(pPath, &pt, PT_MOVETO) ) return FALSE; } - for(i = 0; i < cbPoints; i++) { + for(i = 0; i < cbPoints; i++) + { pt = pts[i]; - if(!W32kLPtoDP(hdc, &pt, 1)) - return FALSE; + CoordLPtoDP ( dc, &pt ); PATH_AddEntry(pPath, &pt, PT_LINETO); } @@ -625,23 +662,27 @@ BOOL STDCALL PATH_PolylineTo(HDC hdc, const POINT *pts, DWORD cbPoints) } -BOOL STDCALL PATH_Polygon(HDC hdc, const POINT *pts, DWORD cbPoints) +BOOL +FASTCALL +PATH_Polygon ( PDC dc, const POINT *pts, DWORD cbPoints ) { GdiPath *pPath; POINT pt; ULONG i; - if(!PATH_GetPathFromHDC(hdc, &pPath)) - return FALSE; + ASSERT ( dc ); + ASSERT ( pts ); + + PATH_GetPathFromDC ( dc, &pPath ); /* Check that path is open */ - if(pPath->state!=PATH_Open) + if ( pPath->state != PATH_Open ) return FALSE; - for(i = 0; i < cbPoints; i++) { + for(i = 0; i < cbPoints; i++) + { pt = pts[i]; - if(!W32kLPtoDP(hdc, &pt, 1)) - return FALSE; + CoordLPtoDP ( dc, &pt ); PATH_AddEntry(pPath, &pt, (i == 0) ? PT_MOVETO : ((i == cbPoints-1) ? PT_LINETO | PT_CLOSEFIGURE : PT_LINETO)); @@ -649,25 +690,31 @@ BOOL STDCALL PATH_Polygon(HDC hdc, const POINT *pts, DWORD cbPoints) return TRUE; } -BOOL STDCALL PATH_PolyPolygon( HDC hdc, const POINT* pts, const INT* counts, - UINT polygons ) +BOOL +FASTCALL +PATH_PolyPolygon ( PDC dc, const POINT* pts, const INT* counts, UINT polygons ) { GdiPath *pPath; POINT pt, startpt; ULONG poly, point, i; - if(!PATH_GetPathFromHDC(hdc, &pPath)) - return FALSE; + ASSERT ( dc ); + ASSERT ( pts ); + ASSERT ( counts ); + ASSERT ( polygons ); + + PATH_GetPathFromDC ( dc, &pPath ); /* Check that path is open */ - if(pPath->state!=PATH_Open) + if ( pPath->state != PATH_Open ); return FALSE; - for(i = 0, poly = 0; poly < polygons; poly++) { - for(point = 0; point < (ULONG) counts[poly]; point++, i++) { + for(i = 0, poly = 0; poly < polygons; poly++) + { + for(point = 0; point < (ULONG) counts[poly]; point++, i++) + { pt = pts[i]; - if(!W32kLPtoDP(hdc, &pt, 1)) - return FALSE; + CoordLPtoDP ( dc, &pt ); if(point == 0) startpt = pt; PATH_AddEntry(pPath, &pt, (point == 0) ? PT_MOVETO : PT_LINETO); } @@ -677,25 +724,31 @@ BOOL STDCALL PATH_PolyPolygon( HDC hdc, const POINT* pts, const INT* counts, return TRUE; } -BOOL STDCALL PATH_PolyPolyline( HDC hdc, const POINT* pts, const DWORD* counts, - DWORD polylines ) +BOOL +FASTCALL +PATH_PolyPolyline ( PDC dc, const POINT* pts, const DWORD* counts, DWORD polylines ) { GdiPath *pPath; POINT pt; ULONG poly, point, i; - if(!PATH_GetPathFromHDC(hdc, &pPath)) - return FALSE; + ASSERT ( dc ); + ASSERT ( pts ); + ASSERT ( counts ); + ASSERT ( polylines ); + + PATH_GetPathFromDC ( dc, &pPath ); /* Check that path is open */ - if(pPath->state!=PATH_Open) + if ( pPath->state != PATH_Open ) return FALSE; - for(i = 0, poly = 0; poly < polylines; poly++) { - for(point = 0; point < counts[poly]; point++, i++) { + for(i = 0, poly = 0; poly < polylines; poly++) + { + for(point = 0; point < counts[poly]; point++, i++) + { pt = pts[i]; - if(!W32kLPtoDP(hdc, &pt, 1)) - return FALSE; + CoordLPtoDP ( dc, &pt ); PATH_AddEntry(pPath, &pt, (point == 0) ? PT_MOVETO : PT_LINETO); } } @@ -710,13 +763,15 @@ BOOL STDCALL PATH_PolyPolyline( HDC hdc, const POINT* pts, const DWORD* counts, /* PATH_AddFlatBezier * */ -BOOL STDCALL PATH_AddFlatBezier(GdiPath *pPath, POINT *pt, BOOL closed) +BOOL +FASTCALL +PATH_AddFlatBezier ( GdiPath *pPath, POINT *pt, BOOL closed ) { POINT *pts; INT no, i; pts = GDI_Bezier( pt, 4, &no ); - if(!pts) return FALSE; + if ( !pts ) return FALSE; for(i = 1; i < no; i++) PATH_AddEntry(pPath, &pts[i], (i == no-1 && closed) ? PT_LINETO | PT_CLOSEFIGURE : PT_LINETO); @@ -730,7 +785,9 @@ BOOL STDCALL PATH_AddFlatBezier(GdiPath *pPath, POINT *pt, BOOL closed) * Replaces Beziers with line segments * */ -BOOL FASTCALL PATH_FlattenPath(GdiPath *pPath) +BOOL +FASTCALL +PATH_FlattenPath(GdiPath *pPath) { GdiPath newPath; INT srcpt; @@ -769,15 +826,16 @@ BOOL FASTCALL PATH_FlattenPath(GdiPath *pPath) // expecting a non-const*. Since this function isn't being called // at the moment, I'm commenting it out until the issue needs to // be addressed. -BOOL STDCALL PATH_PathToRegion(const GdiPath *pPath, INT nPolyFillMode, - HRGN *pHrgn) +BOOL +FASTCALL +PATH_PathToRegion ( const GdiPath *pPath, INT nPolyFillMode, HRGN *pHrgn ) { int numStrokes, iStroke, i; INT *pNumPointsInStroke; HRGN hrgn; - assert(pPath!=NULL); - assert(pHrgn!=NULL); + assert ( pPath!=NULL ); + assert ( pHrgn!=NULL ); PATH_FlattenPath ( pPath ); @@ -834,7 +892,9 @@ BOOL STDCALL PATH_PathToRegion(const GdiPath *pPath, INT nPolyFillMode, * * Removes all entries from the path and sets the path state to PATH_Null. */ -VOID STDCALL PATH_EmptyPath(GdiPath *pPath) +VOID +FASTCALL +PATH_EmptyPath ( GdiPath *pPath ) { assert(pPath!=NULL); @@ -848,7 +908,9 @@ VOID STDCALL PATH_EmptyPath(GdiPath *pPath) * or PT_BEZIERTO, optionally ORed with PT_CLOSEFIGURE. Returns TRUE if * successful, FALSE otherwise (e.g. if not enough memory was available). */ -BOOL STDCALL PATH_AddEntry(GdiPath *pPath, const POINT *pPoint, BYTE flags) +BOOL +FASTCALL +PATH_AddEntry ( GdiPath *pPath, const POINT *pPoint, BYTE flags ) { assert(pPath!=NULL); @@ -857,11 +919,11 @@ BOOL STDCALL PATH_AddEntry(GdiPath *pPath, const POINT *pPoint, BYTE flags) */ /* Check that path is open */ - if(pPath->state!=PATH_Open) + if ( pPath->state != PATH_Open ) return FALSE; /* Reserve enough memory for an extra path entry */ - if(!PATH_ReserveEntries(pPath, pPath->numEntriesUsed+1)) + if ( !PATH_ReserveEntries(pPath, pPath->numEntriesUsed+1) ) return FALSE; /* Store information in path entry */ @@ -884,7 +946,9 @@ BOOL STDCALL PATH_AddEntry(GdiPath *pPath, const POINT *pPoint, BYTE flags) * been allocated; allocates larger arrays and copies the existing entries * to those arrays, if necessary. Returns TRUE if successful, else FALSE. */ -BOOL STDCALL PATH_ReserveEntries(GdiPath *pPath, INT numEntries) +BOOL +FASTCALL +PATH_ReserveEntries ( GdiPath *pPath, INT numEntries ) { INT numEntriesToAllocate; POINT *pPointsNew; @@ -937,23 +1001,18 @@ BOOL STDCALL PATH_ReserveEntries(GdiPath *pPath, INT numEntries) return TRUE; } -/* PATH_GetPathFromHDC +/* PATH_GetPathFromDC * * Retrieves a pointer to the GdiPath structure contained in an HDC and * places it in *ppPath. TRUE is returned if successful, FALSE otherwise. */ -BOOL FASTCALL PATH_GetPathFromHDC(HDC hdc, GdiPath **ppPath) +VOID +FASTCALL +PATH_GetPathFromDC ( PDC dc, GdiPath **ppPath ) { - DC *pDC; - - pDC=DC_HandleToPtr(hdc); - if(pDC) - { - *ppPath=&pDC->w.path; - DC_ReleasePtr( hdc ); - return TRUE; - } - return FALSE; + ASSERT ( dc ); + ASSERT ( ppPath ); + *ppPath = &dc->w.path; } /* PATH_DoArcPart @@ -965,8 +1024,10 @@ BOOL FASTCALL PATH_GetPathFromHDC(HDC hdc, GdiPath **ppPath) * point is added to the path; otherwise, it is assumed that the current * position is equal to the first control point. */ -BOOL STDCALL PATH_DoArcPart(GdiPath *pPath, FLOAT_POINT corners[], - double angleStart, double angleEnd, BOOL addMoveTo) +BOOL +FASTCALL +PATH_DoArcPart ( GdiPath *pPath, FLOAT_POINT corners[], + double angleStart, double angleEnd, BOOL addMoveTo ) { double halfAngle, a; double xNorm[4], yNorm[4]; @@ -1023,9 +1084,13 @@ BOOL STDCALL PATH_DoArcPart(GdiPath *pPath, FLOAT_POINT corners[], * coordinates (-1.0, -1.0) correspond to corners[0], the coordinates * (1.0, 1.0) correspond to corners[1]. */ -VOID STDCALL PATH_ScaleNormalizedPoint(FLOAT_POINT corners[], double x, - double y, POINT *pPoint) +VOID +FASTCALL +PATH_ScaleNormalizedPoint ( FLOAT_POINT corners[], double x, + double y, POINT *pPoint ) { + ASSERT ( corners ); + ASSERT ( pPoint ); pPoint->x=GDI_ROUND( (double)corners[0].x + (double)(corners[1].x-corners[0].x)*0.5*(x+1.0) ); pPoint->y=GDI_ROUND( (double)corners[0].y + (double)(corners[1].y-corners[0].y)*0.5*(y+1.0) ); } @@ -1035,10 +1100,16 @@ VOID STDCALL PATH_ScaleNormalizedPoint(FLOAT_POINT corners[], double x, * Normalizes a point with respect to the box whose corners are passed in * corners. The normalized coordinates are stored in *pX and *pY. */ -VOID STDCALL PATH_NormalizePoint(FLOAT_POINT corners[], +VOID +FASTCALL +PATH_NormalizePoint ( FLOAT_POINT corners[], const FLOAT_POINT *pPoint, double *pX, double *pY) { + ASSERT ( corners ); + ASSERT ( pPoint ); + ASSERT ( pX ); + ASSERT ( pY ); *pX=(double)(pPoint->x-corners[0].x)/(double)(corners[1].x-corners[0].x) * 2.0 - 1.0; *pY=(double)(pPoint->y-corners[0].y)/(double)(corners[1].y-corners[0].y) * 2.0 - 1.0; } diff --git a/reactos/subsys/win32k/objects/polyfill.c b/reactos/subsys/win32k/objects/polyfill.c index 1ac125424c0..51177ff0c61 100644 --- a/reactos/subsys/win32k/objects/polyfill.c +++ b/reactos/subsys/win32k/objects/polyfill.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: polyfill.c,v 1.10 2003/08/16 21:17:20 royce Exp $ +/* $Id: polyfill.c,v 1.11 2003/08/17 17:32:58 royce Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -37,7 +37,7 @@ #include #include -#define NDEBUG +#undef NDEBUG #include INT abs(INT nm); @@ -146,9 +146,9 @@ POLYGONFILL_MakeEdge(POINT From, POINT To) rc->ToY = From.y; rc->YDirection = -1; - // lines that go up get walked backwards, so need to be offset - // by -1 in order to make the walk identically on a pixel-level - rc->Error = -1; + // lines that go up get walked backwards, so need to be offset + // by -1 in order to make the walk identically on a pixel-level + rc->Error = -1; } else { @@ -158,7 +158,7 @@ POLYGONFILL_MakeEdge(POINT From, POINT To) rc->ToY = To.y; rc->YDirection = 1; - rc->Error = 0; + rc->Error = 0; } rc->x = rc->FromX; @@ -178,25 +178,8 @@ POLYGONFILL_MakeEdge(POINT From, POINT To) rc->pNext = 0; - rc->XIntercept[0] = rc->x; - rc->XIntercept[1] = rc->x; - - if ( rc->xmajor && rc->absdy ) - { - int x1 = rc->x; - int steps = (rc->ErrorMax-rc->Error-1) / rc->absdy; - if ( steps ) - { - rc->x += steps * rc->XDirection; - rc->Error += steps * rc->absdy; - ASSERT ( rc->Error < rc->ErrorMax ); - rc->XIntercept[0] = MIN(x1,rc->x); - rc->XIntercept[1] = MAX(x1,rc->x); - } - } - - DPRINT("MakeEdge (%i,%i)->(%i,%i) d=(%i,%i) dir=(%i,%i) err=%i max=%i\n", - From.x, From.y, To.x, To.y, rc->dx, rc->dy, rc->XDirection, rc->YDirection, rc->Error, rc->ErrorMax ); + //DPRINT("MakeEdge (%i,%i)->(%i,%i) d=(%i,%i) dir=(%i,%i) err=%i max=%i\n", + // From.x, From.y, To.x, To.y, rc->dx, rc->dy, rc->XDirection, rc->YDirection, rc->Error, rc->ErrorMax ); return rc; } @@ -334,20 +317,11 @@ POLYGONFILL_UpdateScanline(FILL_EDGE* pEdge, int Scanline) if ( 0 == pEdge->dy ) return; - ASSERT ( pEdge->FromY < Scanline && pEdge->ToY >= Scanline ); + ASSERT ( pEdge->FromY <= Scanline && pEdge->ToY >= Scanline ); if ( pEdge->xmajor ) { int steps; - // we should require exactly 1 step to step onto current scanline... - ASSERT ( (pEdge->ErrorMax-pEdge->Error-1) / pEdge->absdy == 0 ); - pEdge->x += pEdge->XDirection; - pEdge->Error += pEdge->absdy; - ASSERT ( pEdge->Error >= pEdge->ErrorMax ); - - // now step onto current scanline... - pEdge->Error -= pEdge->absdx; - pEdge->y++; ASSERT ( pEdge->y == Scanline ); @@ -368,9 +342,22 @@ POLYGONFILL_UpdateScanline(FILL_EDGE* pEdge, int Scanline) pEdge->XIntercept[0] = pEdge->x; pEdge->XIntercept[1] = pEdge->x; } + + // we should require exactly 1 step to step onto next scanline... + ASSERT ( (pEdge->ErrorMax-pEdge->Error-1) / pEdge->absdy == 0 ); + pEdge->x += pEdge->XDirection; + pEdge->Error += pEdge->absdy; + ASSERT ( pEdge->Error >= pEdge->ErrorMax ); + + // now step onto next scanline... + pEdge->Error -= pEdge->absdx; + pEdge->y++; } else // then this is a y-major line { + pEdge->XIntercept[0] = pEdge->x; + pEdge->XIntercept[1] = pEdge->x; + pEdge->Error += pEdge->absdx; pEdge->y++; @@ -380,13 +367,10 @@ POLYGONFILL_UpdateScanline(FILL_EDGE* pEdge, int Scanline) pEdge->x += pEdge->XDirection; ASSERT ( pEdge->Error < pEdge->ErrorMax ); } - - pEdge->XIntercept[0] = pEdge->x; - pEdge->XIntercept[1] = pEdge->x; } - DPRINT("Line (%d, %d) to (%d, %d) intersects scanline %d at (%d,%d)\n", - pEdge->FromX, pEdge->FromY, pEdge->ToX, pEdge->ToY, Scanline, pEdge->XIntercept[0], pEdge->XIntercept[1] ); + //DPRINT("Line (%d, %d) to (%d, %d) intersects scanline %d at (%d,%d)\n", + // pEdge->FromX, pEdge->FromY, pEdge->ToX, pEdge->ToY, Scanline, pEdge->XIntercept[0], pEdge->XIntercept[1] ); } /* @@ -405,7 +389,7 @@ POLYGONFILL_BuildActiveList ( int Scanline, FILL_EDGE_LIST* list, FILL_EDGE** Ac { FILL_EDGE* pEdge = list->Edges[i]; ASSERT(pEdge); - if ( pEdge->FromY < Scanline && pEdge->ToY >= Scanline ) + if ( pEdge->FromY <= Scanline && pEdge->ToY >= Scanline ) { POLYGONFILL_UpdateScanline ( pEdge, Scanline ); POLYGONFILL_ActiveListInsert ( ActiveHead, pEdge ); @@ -439,8 +423,8 @@ POLYGONFILL_FillScanLineAlternate( while ( NULL != pRight ) { - int x1 = pLeft->XIntercept[1]+1; - int x2 = pRight->XIntercept[0]; + int x1 = pLeft->XIntercept[0]; + int x2 = pRight->XIntercept[1]; if ( x2 > x1 ) { RECTL BoundRect; @@ -449,7 +433,7 @@ POLYGONFILL_FillScanLineAlternate( BoundRect.left = x1; BoundRect.right = x2; - DPRINT("Fill Line (%d, %d) to (%d, %d)\n",x1, ScanLine, x2, ScanLine); + //DPRINT("Fill Line (%d, %d) to (%d, %d)\n",x1, ScanLine, x2, ScanLine); IntEngLineTo( SurfObj, dc->CombinedClip, BrushObj, @@ -477,43 +461,84 @@ POLYGONFILL_FillScanLineWinding( MIX RopMode ) { FILL_EDGE *pLeft, *pRight; - int winding = 0; + int x1, x2, winding = 0; + RECTL BoundRect; if ( !ActiveHead ) return; + BoundRect.top = ScanLine; + BoundRect.bottom = ScanLine + 1; + pLeft = ActiveHead; winding = pLeft->YDirection; pRight = pLeft->pNext; ASSERT(pRight); + // setup first line... + x1 = pLeft->XIntercept[0]; + x2 = pRight->XIntercept[1]; + + pLeft = pRight; + pRight = pLeft->pNext; + winding += pLeft->YDirection; + while ( NULL != pRight ) { - int x1 = pLeft->XIntercept[1]+1; - int x2 = pRight->XIntercept[0]; - if ( winding && x2 > x1 ) + int newx1 = pLeft->XIntercept[0]; + int newx2 = pRight->XIntercept[1]; + if ( winding ) { - RECTL BoundRect; - BoundRect.top = ScanLine; - BoundRect.bottom = ScanLine + 1; - BoundRect.left = x1; - BoundRect.right = x2; + // check and see if this new line touches the previous... + if ( (newx1 >= x1 && newx1 <= x2) + || (newx2 >= x1 && newx2 <= x2) + || (x1 >= newx1 && x1 <= newx2) + || (x2 >= newx2 && x2 <= newx2) + ) + { + // yup, just tack it on to our existing line + x1 = MIN(x1,newx1); + x2 = MAX(x2,newx2); + } + else + { + // nope - render the old line.. + BoundRect.left = x1; + BoundRect.right = x2; - DPRINT("Fill Line (%d, %d) to (%d, %d)\n",x1, ScanLine, x2, ScanLine); - IntEngLineTo( SurfObj, - dc->CombinedClip, - BrushObj, - x1, - ScanLine, - x2, - ScanLine, - &BoundRect, // Bounding rectangle - RopMode); // MIX + //DPRINT("Fill Line (%d, %d) to (%d, %d)\n",x1, ScanLine, x2, ScanLine); + IntEngLineTo( SurfObj, + dc->CombinedClip, + BrushObj, + x1, + ScanLine, + x2, + ScanLine, + &BoundRect, // Bounding rectangle + RopMode); // MIX + + x1 = newx1; + x2 = newx2; + } } pLeft = pRight; pRight = pLeft->pNext; winding += pLeft->YDirection; } + // there will always be a line left-over, render it now... + BoundRect.left = x1; + BoundRect.right = x2; + + //DPRINT("Fill Line (%d, %d) to (%d, %d)\n",x1, ScanLine, x2, ScanLine); + IntEngLineTo( SurfObj, + dc->CombinedClip, + BrushObj, + x1, + ScanLine, + x2, + ScanLine, + &BoundRect, // Bounding rectangle + RopMode); // MIX } //When the fill mode is ALTERNATE, GDI fills the area between odd-numbered and @@ -550,7 +575,7 @@ FillPolygon( PBRUSHOBJ BrushObj, MIX RopMode ); - DPRINT("FillPolygon\n"); + //DPRINT("FillPolygon\n"); /* Create Edge List. */ list = POLYGONFILL_MakeEdgeList(Points, Count); @@ -566,7 +591,7 @@ FillPolygon( /* For each Scanline from BoundRect.bottom to BoundRect.top, * determine line segments to draw */ - for ( ScanLine = BoundRect.top + 1; ScanLine < BoundRect.bottom; ++ScanLine ) + for ( ScanLine = BoundRect.top; ScanLine < BoundRect.bottom; ++ScanLine ) { POLYGONFILL_BuildActiveList(ScanLine, list, &ActiveHead); //DEBUG_PRINT_ACTIVE_EDGELIST(ActiveHead);