* 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
This commit is contained in:
Royce Mitchell III 2003-08-17 17:32:58 +00:00
parent 8b7c8b8dff
commit 5b6d43ab50
20 changed files with 1340 additions and 969 deletions

View file

@ -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++ )

View file

@ -10,14 +10,20 @@
#include <windows.h>
#include <stdio.h>
#include <assert.h>
#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);

View file

@ -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 (

View file

@ -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);

View file

@ -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

View file

@ -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) */

View file

@ -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)
{

View file

@ -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/copybits.h>
#include <include/inteng.h>
#define NDEBUG
//#define NDEBUG
#include <win32k/debug1.h>
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

View file

@ -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 );

View file

@ -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 */

View file

@ -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

View file

@ -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)))
{

View file

@ -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

View file

@ -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

View file

@ -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 <windows.h>
@ -31,7 +31,7 @@
#include <include/paint.h>
#include <internal/safe.h>
#define NDEBUG
//#define NDEBUG
#include <win32k/debug1.h>
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,

View file

@ -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;
}

View file

@ -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; i<Count; i++)
{
pts[i].x += dc->w.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;
}

View file

@ -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 <windows.h>
@ -35,27 +35,43 @@
#include <include/object.h>
#include <include/surface.h>
#define NDEBUG
//#define NDEBUG
#include <win32k/debug1.h>
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,

View file

@ -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 <windows.h>
#include <ddk/ntddk.h>
@ -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 &&
angleEnd<angleEndQuadrant) ||
(W32kGetArcDirection(hdc)==AD_COUNTERCLOCKWISE &&
angleEnd>angleEndQuadrant))
if ( (clockwise && angleEnd<angleEndQuadrant)
|| (!clockwise && angleEnd>angleEndQuadrant)
)
{
/* 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;
}

View file

@ -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/object.h>
#include <include/paint.h>
#define NDEBUG
#undef NDEBUG
#include <win32k/debug1.h>
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);