* 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->ToY = From.y;
rc->YDirection = -1; rc->YDirection = -1;
// lines that go up get walked backwards, so need to be offset // 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 // by -1 in order to make the walk identically on a pixel-level
rc->Error = -1; rc->Error = -1;
} }
else else
{ {
@ -281,7 +281,7 @@ POLYGONFILL_MakeEdge(POINT From, POINT To)
rc->ToY = To.y; rc->ToY = To.y;
rc->YDirection = 1; rc->YDirection = 1;
rc->Error = 0; rc->Error = 0;
} }
rc->x = rc->FromX; rc->x = rc->FromX;
@ -301,23 +301,6 @@ POLYGONFILL_MakeEdge(POINT From, POINT To)
rc->pNext = 0; 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", 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 ); 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 ) if ( 0 == pEdge->dy )
return; return;
ASSERT ( pEdge->FromY < Scanline && pEdge->ToY >= Scanline ); ASSERT ( pEdge->FromY <= Scanline && pEdge->ToY >= Scanline );
if ( pEdge->xmajor ) if ( pEdge->xmajor )
{ {
int steps; 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 ); ASSERT ( pEdge->y == Scanline );
@ -491,9 +465,22 @@ POLYGONFILL_UpdateScanline(FILL_EDGE* pEdge, int Scanline)
pEdge->XIntercept[0] = pEdge->x; pEdge->XIntercept[0] = pEdge->x;
pEdge->XIntercept[1] = 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 else // then this is a y-major line
{ {
pEdge->XIntercept[0] = pEdge->x;
pEdge->XIntercept[1] = pEdge->x;
pEdge->Error += pEdge->absdx; pEdge->Error += pEdge->absdx;
pEdge->y++; pEdge->y++;
@ -503,9 +490,6 @@ POLYGONFILL_UpdateScanline(FILL_EDGE* pEdge, int Scanline)
pEdge->x += pEdge->XDirection; pEdge->x += pEdge->XDirection;
ASSERT ( pEdge->Error < pEdge->ErrorMax ); 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", 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]; FILL_EDGE* pEdge = list->Edges[i];
ASSERT(pEdge); ASSERT(pEdge);
if ( pEdge->FromY < Scanline && pEdge->ToY >= Scanline ) if ( pEdge->FromY <= Scanline && pEdge->ToY >= Scanline )
{ {
POLYGONFILL_UpdateScanline ( pEdge, Scanline ); POLYGONFILL_UpdateScanline ( pEdge, Scanline );
POLYGONFILL_ActiveListInsert ( ActiveHead, pEdge ); POLYGONFILL_ActiveListInsert ( ActiveHead, pEdge );
@ -562,8 +546,8 @@ POLYGONFILL_FillScanLineAlternate(
while ( NULL != pRight ) while ( NULL != pRight )
{ {
int x1 = pLeft->XIntercept[1]+1; int x1 = pLeft->XIntercept[0];
int x2 = pRight->XIntercept[0]; int x2 = pRight->XIntercept[1];
if ( x2 > x1 ) if ( x2 > x1 )
{ {
RECTL BoundRect; RECTL BoundRect;
@ -600,43 +584,84 @@ POLYGONFILL_FillScanLineWinding(
MIX RopMode ) MIX RopMode )
{ {
FILL_EDGE *pLeft, *pRight; FILL_EDGE *pLeft, *pRight;
int winding = 0; int x1, x2, winding = 0;
RECTL BoundRect;
if ( !ActiveHead ) if ( !ActiveHead )
return; return;
BoundRect.top = ScanLine;
BoundRect.bottom = ScanLine + 1;
pLeft = ActiveHead; pLeft = ActiveHead;
winding = pLeft->YDirection; winding = pLeft->YDirection;
pRight = pLeft->pNext; pRight = pLeft->pNext;
ASSERT(pRight); ASSERT(pRight);
// setup first line...
x1 = pLeft->XIntercept[0];
x2 = pRight->XIntercept[1];
pLeft = pRight;
pRight = pLeft->pNext;
winding += pLeft->YDirection;
while ( NULL != pRight ) while ( NULL != pRight )
{ {
int x1 = pLeft->XIntercept[1]+1; int newx1 = pLeft->XIntercept[0];
int x2 = pRight->XIntercept[0]; int newx2 = pRight->XIntercept[1];
if ( winding && x2 > x1 ) if ( winding )
{ {
RECTL BoundRect; // check and see if this new line touches the previous...
BoundRect.top = ScanLine; if ( (newx1 >= x1 && newx1 <= x2)
BoundRect.bottom = ScanLine + 1; || (newx2 >= x1 && newx2 <= x2)
BoundRect.left = x1; || (x1 >= newx1 && x1 <= newx2)
BoundRect.right = x2; || (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); DPRINT("Fill Line (%d, %d) to (%d, %d)\n",x1, ScanLine, x2, ScanLine);
IntEngLineTo( SurfObj, IntEngLineTo( SurfObj,
dc->CombinedClip, dc->CombinedClip,
BrushObj, BrushObj,
x1, x1,
ScanLine, ScanLine,
x2, x2,
ScanLine, ScanLine,
&BoundRect, // Bounding rectangle &BoundRect, // Bounding rectangle
RopMode); // MIX RopMode); // MIX
x1 = newx1;
x2 = newx2;
}
} }
pLeft = pRight; pLeft = pRight;
pRight = pLeft->pNext; pRight = pLeft->pNext;
winding += pLeft->YDirection; 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 //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, /* For each Scanline from BoundRect.bottom to BoundRect.top,
* determine line segments to draw * 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); POLYGONFILL_BuildActiveList(ScanLine, list, &ActiveHead);
//DEBUG_PRINT_ACTIVE_EDGELIST(ActiveHead); //DEBUG_PRINT_ACTIVE_EDGELIST(ActiveHead);
@ -803,6 +828,20 @@ void main()
{ 0, 0 }, { 0, 0 },
{ 12, 4 }, { 12, 4 },
{ 4, 8 }, { 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 #else
{ 4, 16 }, { 4, 16 },
{ 12, 4 }, { 12, 4 },
@ -814,7 +853,7 @@ void main()
const int pts_count = sizeof(pts)/sizeof(pts[0]); const int pts_count = sizeof(pts)/sizeof(pts[0]);
// use ALTERNATE or WINDING for 3rd param // use ALTERNATE or WINDING for 3rd param
Polygon ( pts, pts_count, WINDING ); Polygon ( pts, pts_count, ALTERNATE );
// print out our "screen" // print out our "screen"
for ( int y = 0; y < SCREENY; y++ ) for ( int y = 0; y < SCREENY; y++ )

View file

@ -10,14 +10,20 @@
#include <windows.h> #include <windows.h>
#include <stdio.h> #include <stdio.h>
#include <assert.h>
#ifndef ASSERT
#define ASSERT assert
#endif
#define nelem(x) (sizeof (x) / sizeof *(x))
HFONT tf; HFONT tf;
LRESULT WINAPI MainWndProc(HWND, UINT, WPARAM, LPARAM); LRESULT WINAPI MainWndProc(HWND, UINT, WPARAM, LPARAM);
void PolygonTest ( HDC hdc ) void PolygonTest ( HDC hdc )
{ {
HPEN BluePen, OldPen; HPEN Pen, OldPen;
HBRUSH RedBrush, OldBrush; HBRUSH RedBrush, OldBrush;
DWORD Mode; DWORD Mode;
POINT PointsAlternate[] = POINT PointsAlternate[] =
@ -48,49 +54,99 @@ void PolygonTest ( HDC hdc )
{ 7, 7 }, { 7, 7 },
{ 3, 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 //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)); RedBrush = CreateSolidBrush(RGB(0xff, 0, 0));
ASSERT(RedBrush);
//initialize a set of points for alternate. OldPen = (HPEN)SelectObject(hdc, Pen);
/*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);
OldBrush = (HBRUSH)SelectObject(hdc, RedBrush); OldBrush = (HBRUSH)SelectObject(hdc, RedBrush);
Mode = GetPolyFillMode(hdc); Mode = GetPolyFillMode(hdc);
SetPolyFillMode(hdc, ALTERNATE); SetPolyFillMode(hdc, ALTERNATE);
Polygon(hdc,PointsAlternate,sizeof(PointsAlternate)/sizeof(PointsAlternate[0])); Polygon(hdc,PointsAlternate,nelem(PointsAlternate));
SetPolyFillMode(hdc, WINDING); SetPolyFillMode(hdc, WINDING);
Polygon(hdc,PointsWinding,sizeof(PointsWinding)/sizeof(PointsWinding[0])); Polygon(hdc,PointsWinding,nelem(PointsWinding));
Rectangle ( hdc, 1, 1, 10, 10 ); Rectangle ( hdc, 1, 1, 10, 10 );
Polygon(hdc,Tri1,sizeof(Tri1)/sizeof(Tri1[0])); Polygon(hdc,Tri1,nelem(Tri1));
Polygon(hdc,Tri2,sizeof(Tri2)/sizeof(Tri2[0])); 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 //cleanup
SetPolyFillMode(hdc, Mode); SetPolyFillMode(hdc, Mode);

View file

@ -1,6 +1,8 @@
#ifndef __WIN32K_COORD_H #ifndef __WIN32K_COORD_H
#define __WIN32K_COORD_H #define __WIN32K_COORD_H
#include "dc.h"
BOOL BOOL
STDCALL STDCALL
W32kCombineTransform ( W32kCombineTransform (
@ -15,17 +17,30 @@ W32kDPtoLP (
LPPOINT Points, LPPOINT Points,
int Count int Count
); );
int
FASTCALL
IntGetGraphicsMode ( PDC dc );
int int
STDCALL STDCALL
W32kGetGraphicsMode ( W32kGetGraphicsMode ( HDC hDC );
HDC hDC
);
BOOL BOOL
STDCALL STDCALL
W32kGetWorldTransform ( W32kGetWorldTransform (
HDC hDC, HDC hDC,
LPXFORM Xform LPXFORM Xform
); );
VOID
FASTCALL
CoordLPtoDP ( PDC Dc, LPPOINT Point );
VOID
FASTCALL
IntLPtoDP ( PDC dc, LPPOINT Points, INT Count );
BOOL BOOL
STDCALL STDCALL
W32kLPtoDP ( W32kLPtoDP (

View file

@ -173,6 +173,7 @@ INT STDCALL W32kGetBkMode(HDC hDC);
BOOL STDCALL W32kGetBrushOrgEx(HDC hDC, LPPOINT brushOrg); BOOL STDCALL W32kGetBrushOrgEx(HDC hDC, LPPOINT brushOrg);
HRGN STDCALL W32kGetClipRgn(HDC hDC); HRGN STDCALL W32kGetClipRgn(HDC hDC);
HGDIOBJ STDCALL W32kGetCurrentObject(HDC hDC, UINT ObjectType); HGDIOBJ STDCALL W32kGetCurrentObject(HDC hDC, UINT ObjectType);
VOID FASTCALL IntGetCurrentPositionEx (PDC dc, LPPOINT currentPosition);
BOOL STDCALL W32kGetCurrentPositionEx(HDC hDC, LPPOINT currentPosition); BOOL STDCALL W32kGetCurrentPositionEx(HDC hDC, LPPOINT currentPosition);
BOOL STDCALL W32kGetDCOrgEx(HDC hDC, LPPOINT Point); BOOL STDCALL W32kGetDCOrgEx(HDC hDC, LPPOINT Point);
HDC STDCALL W32kGetDCState16(HDC hDC); HDC STDCALL W32kGetDCState16(HDC hDC);

View file

@ -34,15 +34,19 @@ W32kArcTo(HDC hDC,
int XRadial2, int XRadial2,
int YRadial2); int YRadial2);
INT
FASTCALL
IntGetArcDirection ( PDC dc );
INT INT
STDCALL STDCALL
W32kGetArcDirection(HDC hDC); W32kGetArcDirection ( HDC hDC );
BOOL BOOL
STDCALL STDCALL
W32kLineTo(HDC hDC, W32kLineTo(HDC hDC,
int XEnd, int XEnd,
int YEnd); int YEnd );
BOOL BOOL
STDCALL 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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS User32 * 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 */ /* retrieve the button text; returned buffer must be freed by caller */
inline static WCHAR *get_button_text( HWND hwnd ) inline static WCHAR *get_button_text( HWND hwnd )
{ {
INT len;
WCHAR *buffer;
DbgPrint("[button] In get_button_text()\n"); DbgPrint("[button] In get_button_text()\n");
INT len = GetWindowTextLengthW( hwnd ); len = GetWindowTextLengthW( hwnd );
WCHAR *buffer = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) ); buffer = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) );
if (buffer) GetWindowTextW( hwnd, buffer, len + 1 ); if (buffer) GetWindowTextW( hwnd, buffer, len + 1 );
DbgPrint("[button] TextLen %d Text = %s\n", len, buffer); DbgPrint("[button] TextLen %d Text = %s\n", len, buffer);
return buffer; return buffer;
@ -147,15 +149,18 @@ inline static WCHAR *get_button_text( HWND hwnd )
static LRESULT WINAPI ButtonWndProc_common(HWND hWnd, UINT uMsg, static LRESULT WINAPI ButtonWndProc_common(HWND hWnd, UINT uMsg,
WPARAM wParam, LPARAM lParam, BOOL unicode ) WPARAM wParam, LPARAM lParam, BOOL unicode )
{ {
DbgPrint("[button] ButtonWndProc called : msg %d\n", uMsg);
RECT rect; RECT rect;
POINT pt; POINT pt;
LONG style = GetWindowLongA( hWnd, GWL_STYLE ); LONG style;
UINT btn_type = get_button_type( style ); UINT btn_type;
LONG state; LONG state;
HANDLE oldHbitmap; 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.x = LOWORD(lParam);
pt.y = HIWORD(lParam); pt.y = HIWORD(lParam);
@ -181,8 +186,8 @@ static LRESULT WINAPI ButtonWndProc_common(HWND hWnd, UINT uMsg,
if (!hbitmapCheckBoxes) if (!hbitmapCheckBoxes)
{ {
DbgPrint("[button] Loading bitmaps\n");
BITMAP bmp; BITMAP bmp;
DbgPrint("[button] Loading bitmaps\n");
hbitmapCheckBoxes = LoadBitmapW(0, MAKEINTRESOURCEW(OBM_CHECKBOXES)); hbitmapCheckBoxes = LoadBitmapW(0, MAKEINTRESOURCEW(OBM_CHECKBOXES));
GetObjectW( hbitmapCheckBoxes, sizeof(bmp), &bmp ); GetObjectW( hbitmapCheckBoxes, sizeof(bmp), &bmp );
checkBoxWidth = bmp.bmWidth / 4; checkBoxWidth = bmp.bmWidth / 4;
@ -202,10 +207,12 @@ static LRESULT WINAPI ButtonWndProc_common(HWND hWnd, UINT uMsg,
DbgPrint("[button] WM_PAINT\n"); DbgPrint("[button] WM_PAINT\n");
if (btnPaintFunc[btn_type]) if (btnPaintFunc[btn_type])
{ {
DbgPrint("[button] About to draw...\n");
PAINTSTRUCT ps; PAINTSTRUCT ps;
HDC hdc = wParam ? (HDC)wParam : BeginPaint( hWnd, &ps ); HDC hdc;
int nOldMode = SetBkMode( hdc, OPAQUE ); 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 ); (btnPaintFunc[btn_type])( hWnd, hdc, ODA_DRAWENTIRE );
SetBkMode(hdc, nOldMode); /* reset painting mode */ SetBkMode(hdc, nOldMode); /* reset painting mode */
if( !wParam ) EndPaint( hWnd, &ps ); if( !wParam ) EndPaint( hWnd, &ps );
@ -297,11 +304,12 @@ static LRESULT WINAPI ButtonWndProc_common(HWND hWnd, UINT uMsg,
case WM_SETTEXT: case WM_SETTEXT:
{ {
DbgPrint("[button] WM_SETTEXT"); HDC hdc;
/* Clear an old text here as Windows does */
HDC hdc = GetDC(hWnd);
HBRUSH hbrush; HBRUSH hbrush;
RECT client, rc; 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, hbrush = (HBRUSH)SendMessageW(GetParent(hWnd), WM_CTLCOLORSTATIC,
(WPARAM)hdc, (LPARAM)hWnd); (WPARAM)hdc, (LPARAM)hWnd);
@ -537,15 +545,17 @@ static UINT BUTTON_BStoDT(DWORD style)
*/ */
static UINT BUTTON_CalcLabelRect(HWND hwnd, HDC hdc, RECT *rc) static UINT BUTTON_CalcLabelRect(HWND hwnd, HDC hdc, RECT *rc)
{ {
DbgPrint("[button] In BUTTON_CalcLabelRect()\n"); LONG style;
LONG style = GetWindowLongA( hwnd, GWL_STYLE );
WCHAR *text; WCHAR *text;
ICONINFO iconInfo; ICONINFO iconInfo;
BITMAP bm; BITMAP bm;
UINT dtStyle = BUTTON_BStoDT(style); UINT dtStyle = BUTTON_BStoDT(style);
RECT r = *rc; RECT r = *rc;
INT n; INT n;
DbgPrint("[button] In BUTTON_CalcLabelRect()\n");
style = GetWindowLongA( hwnd, GWL_STYLE );
/* Calculate label rectangle according to label type */ /* Calculate label rectangle according to label type */
switch (style & (BS_ICON|BS_BITMAP)) 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) static void BUTTON_DrawLabel(HWND hwnd, HDC hdc, UINT dtFlags, RECT *rc)
{ {
DbgPrint("[button] In BUTTON_DrawLabel()\n");
DRAWSTATEPROC lpOutputProc = NULL; DRAWSTATEPROC lpOutputProc = NULL;
LPARAM lp; LPARAM lp;
WPARAM wp = 0; WPARAM wp = 0;
HBRUSH hbr = 0; HBRUSH hbr = 0;
UINT flags = IsWindowEnabled(hwnd) ? DSS_NORMAL : DSS_DISABLED; UINT flags;
LONG state = get_button_state( hwnd ); LONG state;
LONG style = GetWindowLongA( hwnd, GWL_STYLE ); LONG style;
WCHAR *text = NULL; 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 /* 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). * 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. * 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 ) static void PB_Paint( HWND hwnd, HDC hDC, UINT action )
{ {
DbgPrint("[button] In PB_Paint()\n");
RECT rc, focus_rect, r; RECT rc, focus_rect, r;
UINT dtFlags; UINT dtFlags;
HRGN hRgn; HRGN hRgn;
@ -718,11 +731,16 @@ static void PB_Paint( HWND hwnd, HDC hDC, UINT action )
INT oldBkMode; INT oldBkMode;
COLORREF oldTxtColor; COLORREF oldTxtColor;
HFONT hFont; HFONT hFont;
LONG state = get_button_state( hwnd ); LONG state;
LONG style = GetWindowLongA( hwnd, GWL_STYLE ); LONG style;
BOOL pushedState = (state & BUTTON_HIGHLIGHTED); BOOL pushedState;
UINT uState; 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 ); GetClientRect( hwnd, &rc );
/* Send WM_CTLCOLOR to allow changing the font (the colors are fixed) */ /* 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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS user32.dll * PROJECT: ReactOS user32.dll
@ -489,12 +489,13 @@ CreateWindowExA(DWORD dwExStyle,
HINSTANCE hInstance, HINSTANCE hInstance,
LPVOID lpParam) LPVOID lpParam)
{ {
DbgPrint("[window] CreateWindowExA style %d, exstyle %d, parent %d\n", dwStyle, dwExStyle, hWndParent);
UNICODE_STRING WindowName; UNICODE_STRING WindowName;
UNICODE_STRING ClassName; UNICODE_STRING ClassName;
HWND Handle; HWND Handle;
INT sw; INT sw;
DbgPrint("[window] CreateWindowExA style %d, exstyle %d, parent %d\n", dwStyle, dwExStyle, hWndParent);
/* Register built-in controls if not already done */ /* Register built-in controls if not already done */
if (! ControlsInitCalled) if (! ControlsInitCalled)
{ {

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -43,7 +43,7 @@
#include <include/copybits.h> #include <include/copybits.h>
#include <include/inteng.h> #include <include/inteng.h>
#define NDEBUG //#define NDEBUG
#include <win32k/debug1.h> #include <win32k/debug1.h>
typedef BOOLEAN STDCALL (*PBLTRECTFUNC)(PSURFOBJ OutputObj, typedef BOOLEAN STDCALL (*PBLTRECTFUNC)(PSURFOBJ OutputObj,
@ -84,17 +84,17 @@ BOOL STDCALL EngIntersectRect(PRECTL prcDst, PRECTL prcSrc1, PRECTL prcSrc2)
static BOOLEAN STDCALL static BOOLEAN STDCALL
BltMask(PSURFOBJ Dest, BltMask(PSURFOBJ Dest,
PSURFGDI DestGDI, PSURFGDI DestGDI,
PSURFOBJ Source, PSURFOBJ Source,
PSURFGDI SourceGDI, PSURFGDI SourceGDI,
PSURFOBJ Mask, PSURFOBJ Mask,
PXLATEOBJ ColorTranslation, PXLATEOBJ ColorTranslation,
PRECTL DestRect, PRECTL DestRect,
PPOINTL SourcePoint, PPOINTL SourcePoint,
PPOINTL MaskPoint, PPOINTL MaskPoint,
PBRUSHOBJ Brush, PBRUSHOBJ Brush,
PPOINTL BrushPoint, PPOINTL BrushPoint,
ROP4 Rop4) ROP4 Rop4)
{ {
LONG i, j, dx, dy, c8; LONG i, j, dx, dy, c8;
BYTE *tMask, *lMask; BYTE *tMask, *lMask;
@ -135,17 +135,17 @@ BltMask(PSURFOBJ Dest,
static BOOLEAN STDCALL static BOOLEAN STDCALL
BltPatCopy(PSURFOBJ Dest, BltPatCopy(PSURFOBJ Dest,
PSURFGDI DestGDI, PSURFGDI DestGDI,
PSURFOBJ Source, PSURFOBJ Source,
PSURFGDI SourceGDI, PSURFGDI SourceGDI,
PSURFOBJ Mask, PSURFOBJ Mask,
PXLATEOBJ ColorTranslation, PXLATEOBJ ColorTranslation,
PRECTL DestRect, PRECTL DestRect,
PPOINTL SourcePoint, PPOINTL SourcePoint,
PPOINTL MaskPoint, PPOINTL MaskPoint,
PBRUSHOBJ Brush, PBRUSHOBJ Brush,
PPOINTL BrushPoint, PPOINTL BrushPoint,
ROP4 Rop4) ROP4 Rop4)
{ {
// These functions are assigned if we're working with a DIB // These functions are assigned if we're working with a DIB
// The assigned functions depend on the bitsPerPixel of the 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 * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -213,8 +213,8 @@ XLATEOBJ * STDCALL IntEngCreateXlate(USHORT DestPalType, USHORT SourcePalType,
UINT i; UINT i;
NewXlate = (HPALETTE)CreateGDIHandle(sizeof( XLATEGDI ), sizeof( XLATEOBJ )); NewXlate = (HPALETTE)CreateGDIHandle(sizeof( XLATEGDI ), sizeof( XLATEOBJ ));
if( !ValidEngHandle( NewXlate ) ) if ( !ValidEngHandle ( NewXlate ) )
return NULL; return NULL;
XlateObj = (XLATEOBJ*) AccessUserObject( (ULONG) NewXlate ); XlateObj = (XLATEOBJ*) AccessUserObject( (ULONG) NewXlate );
XlateGDI = (XLATEGDI*) AccessInternalObject( (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 */ /* objects/objconv.c */
PBRUSHOBJ FASTCALL PenToBrushObj (PDC dc, PENOBJ *pen); BRUSHOBJ*
HBITMAP FASTCALL BitmapToSurf (PBITMAPOBJ BitmapObj); FASTCALL
PenToBrushObj(BRUSHOBJ *brush, PENOBJ *pen);
BRUSHOBJ*
FASTCALL
HPenToBrushObj ( BRUSHOBJ *brush, HPEN hpen );
HBITMAP
FASTCALL
BitmapToSurf ( PBITMAPOBJ BitmapObj );
#endif /* __WIN32K_OBJECT_H */ #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); BOOL FASTCALL PATH_AssignGdiPath (GdiPath *pPathDest, const GdiPath *pPathSrc);
VOID FASTCALL PATH_DestroyGdiPath (GdiPath *pPath); VOID FASTCALL PATH_DestroyGdiPath (GdiPath *pPath);
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);
VOID STDCALL PATH_EmptyPath (GdiPath *pPath); VOID FASTCALL PATH_EmptyPath (GdiPath *pPath);
VOID FASTCALL PATH_InitGdiPath (GdiPath *pPath); VOID FASTCALL PATH_InitGdiPath (GdiPath *pPath);
BOOL STDCALL PATH_LineTo (HDC hdc, INT x, INT y); BOOL FASTCALL PATH_LineTo (PDC dc, INT x, INT y);
BOOL FASTCALL PATH_MoveTo (HDC hdc); BOOL FASTCALL PATH_MoveTo (PDC dc);
BOOL STDCALL PATH_PolyBezier (HDC hdc, const POINT *pts, DWORD cbPoints); BOOL FASTCALL PATH_PolyBezier (PDC dc, const POINT *pts, DWORD cbPoints);
BOOL STDCALL PATH_PolyBezierTo (HDC hdc, const POINT *pts, DWORD cbPoints); BOOL FASTCALL PATH_PolyBezierTo (PDC dc, 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);
BOOL STDCALL PATH_Polyline (HDC hdc, const POINT *pts, DWORD cbPoints); BOOL FASTCALL PATH_Polyline (PDC dc, const POINT *pts, DWORD cbPoints);
BOOL STDCALL PATH_PolylineTo (HDC hdc, const POINT *pts, DWORD cbPoints); BOOL FASTCALL PATH_PolylineTo (PDC dc, const POINT *pts, DWORD cbPoints);
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);
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);
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);
BOOL STDCALL PATH_PathToRegion (const GdiPath *pPath, INT nPolyFillMode, HRGN *pHrgn); BOOL FASTCALL PATH_PathToRegion (const GdiPath *pPath, INT nPolyFillMode, HRGN *pHrgn);
#ifdef _WIN32K_PATH_INTERNAL #ifdef _WIN32K_PATH_INTERNAL
BOOL STDCALL PATH_AddEntry (GdiPath *pPath, const POINT *pPoint, BYTE flags); BOOL FASTCALL PATH_AddEntry (GdiPath *pPath, const POINT *pPoint, BYTE flags);
BOOL STDCALL PATH_AddFlatBezier (GdiPath *pPath, POINT *pt, BOOL closed); BOOL FASTCALL 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_DoArcPart (GdiPath *pPath, FLOAT_POINT corners[], double angleStart, double angleEnd, BOOL addMoveTo);
BOOL FASTCALL PATH_FlattenPath (GdiPath *pPath); BOOL FASTCALL PATH_FlattenPath (GdiPath *pPath);
BOOL FASTCALL PATH_GetPathFromHDC (HDC hdc, GdiPath **ppPath); VOID FASTCALL PATH_GetPathFromDC (PDC dc, GdiPath **ppPath);
VOID STDCALL PATH_NormalizePoint (FLOAT_POINT corners[], const FLOAT_POINT *pPoint, double *pX, double *pY); VOID FASTCALL 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 FASTCALL PATH_PathToRegion(const GdiPath *pPath, INT nPolyFillMode, HRGN *pHrgn);
BOOL STDCALL PATH_ReserveEntries (GdiPath *pPath, INT numEntries); BOOL FASTCALL PATH_ReserveEntries (GdiPath *pPath, INT numEntries);
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);
#endif #endif

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -458,11 +458,12 @@ PaintRedrawWindow( PWINDOW_OBJECT Window,
ULONG Flags, ULONG Flags,
ULONG ExFlags) ULONG ExFlags)
{ {
DbgPrint("[win32k.sys:painting] In PaintRedrawWindow()\n");
RECT Rect, Rect2; RECT Rect, Rect2;
POINT Pt; POINT Pt;
HRGN hRgn = NULL; HRGN hRgn = NULL;
DbgPrint("[win32k.sys:painting] In PaintRedrawWindow()\n");
if ((RDW_INVALIDATE | RDW_FRAME) == (Flags & (RDW_INVALIDATE | RDW_FRAME)) || if ((RDW_INVALIDATE | RDW_FRAME) == (Flags & (RDW_INVALIDATE | RDW_FRAME)) ||
(RDW_VALIDATE | RDW_NOFRAME) == (Flags & (RDW_VALIDATE | RDW_NOFRAME))) (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 * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -118,21 +118,27 @@ W32kDPtoLP(HDC hDC,
} }
int int
STDCALL FASTCALL
W32kGetGraphicsMode(HDC hDC) IntGetGraphicsMode ( PDC dc )
{ {
PDC dc; ASSERT ( dc );
int GraphicsMode; return dc->w.GraphicsMode;
}
dc = DC_HandleToPtr (hDC); int
if (!dc) 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; return GraphicsMode;
DC_ReleasePtr( hDC );
return GraphicsMode;
} }
BOOL BOOL
@ -156,8 +162,9 @@ W32kGetWorldTransform(HDC hDC,
return TRUE; return TRUE;
} }
VOID STATIC VOID
CoordLPtoDP(PDC Dc, LPPOINT Point) FASTCALL
CoordLPtoDP ( PDC Dc, LPPOINT Point )
{ {
FLOAT x, y; FLOAT x, y;
x = (FLOAT)Point->x; x = (FLOAT)Point->x;
@ -168,6 +175,16 @@ CoordLPtoDP(PDC Dc, LPPOINT Point)
y * Dc->w.xformWorld2Vport.eM22 + Dc->w.xformWorld2Vport.eDy; 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, * Converts points from logical coordinates into device coordinates. Conversion depends on the mapping mode,
* world transfrom, viewport origin settings for the given device context. * world transfrom, viewport origin settings for the given device context.
@ -177,28 +194,29 @@ CoordLPtoDP(PDC Dc, LPPOINT Point)
* \return TRUE if success. * \return TRUE if success.
*/ */
BOOL STDCALL BOOL STDCALL
W32kLPtoDP(HDC hDC, LPPOINT UnsafePoints, INT Count) W32kLPtoDP ( HDC hDC, LPPOINT UnsafePoints, INT Count )
{ {
PDC Dc; PDC dc = DC_HandleToPtr ( hDC );
INT i; LPPOINT Points;
LPPOINT Points = (LPPOINT) ExAllocatePool( PagedPool, Count*sizeof(POINT));
if ( !dc )
return FALSE;
Points = (LPPOINT)ExAllocatePool ( PagedPool, Count*sizeof(POINT) );
ASSERT ( Points );
ASSERT(Points);
MmCopyFromCaller( Points, UnsafePoints, Count*sizeof(POINT) ); MmCopyFromCaller( Points, UnsafePoints, Count*sizeof(POINT) );
Dc = DC_HandleToPtr (hDC); IntLPtoDP ( dc, UnsafePoints, Count );
if (Dc == NULL)
{
return(FALSE);
}
for (i = 0; i < Count; i++) MmCopyToCaller ( UnsafePoints, Points, Count*sizeof(POINT) );
{
CoordLPtoDP(Dc, &Points[i]); ExFreePool ( Points );
}
DC_ReleasePtr( hDC ); DC_ReleasePtr ( hDC );
MmCopyToCaller( UnsafePoints, Points, Count*sizeof(POINT) );
return(TRUE); return TRUE;
} }
BOOL BOOL

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 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 * 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 * important that the function has the right signature, for the implementation
* we can do whatever we want. * we can do whatever we want.
*/ */
#define DC_GET_VAL_EX( func_name, ret_x, ret_y, type ) \ #define DC_GET_VAL_EX( W32kFuncName, IntFuncName, ret_x, ret_y, type ) \
BOOL STDCALL func_name( HDC hdc, LP##type pt ) \ VOID FASTCALL IntFuncName ( PDC dc, LP##type pt ) \
{ \ { \
PDC dc = DC_HandleToPtr ( hdc ); \ ASSERT ( dc ); \
if (!dc) \ ASSERT ( pt ); \
return FALSE; \ ((LPPOINT)pt)->x = dc->ret_x; \
((LPPOINT)pt)->x = dc->ret_x; \ ((LPPOINT)pt)->y = dc->ret_y; \
((LPPOINT)pt)->y = dc->ret_y; \ } \
DC_ReleasePtr ( hdc ); \ BOOL STDCALL W32kFuncName ( HDC hdc, LP##type pt ) \
return TRUE; \ { \
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 ) \ #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( COLORREF, W32kGetBkColor, w.backgroundColor )
DC_GET_VAL( INT, W32kGetBkMode, w.backgroundMode ) 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 ) DC_GET_VAL( HRGN, W32kGetClipRgn, w.hClipRgn )
HGDIOBJ STDCALL HGDIOBJ STDCALL
@ -610,7 +616,7 @@ W32kGetCurrentObject(HDC hDC, UINT ObjectType)
UNIMPLEMENTED; UNIMPLEMENTED;
} }
DC_GET_VAL_EX( W32kGetCurrentPositionEx, w.CursPosX, w.CursPosY, POINT ) DC_GET_VAL_EX ( W32kGetCurrentPositionEx, IntGetCurrentPositionEx, w.CursPosX, w.CursPosY, POINT )
BOOL STDCALL BOOL STDCALL
W32kGetDCOrgEx(HDC hDC, LPPOINT Point) 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( INT, W32kGetStretchBltMode, w.stretchBltMode )
DC_GET_VAL( UINT, W32kGetTextAlign, w.textAlign ) DC_GET_VAL( UINT, W32kGetTextAlign, w.textAlign )
DC_GET_VAL( COLORREF, W32kGetTextColor, w.textColor ) DC_GET_VAL( COLORREF, W32kGetTextColor, w.textColor )
DC_GET_VAL_EX( W32kGetViewportExtEx, vportExtX, vportExtY, SIZE ) DC_GET_VAL_EX( W32kGetViewportExtEx, IntGetViewportExtEx, vportExtX, vportExtY, SIZE )
DC_GET_VAL_EX( W32kGetViewportOrgEx, vportOrgX, vportOrgY, POINT ) DC_GET_VAL_EX( W32kGetViewportOrgEx, IntGetViewportOrgEx, vportOrgX, vportOrgY, POINT )
DC_GET_VAL_EX( W32kGetWindowExtEx, wndExtX, wndExtY, SIZE ) DC_GET_VAL_EX( W32kGetWindowExtEx, IntGetWindowExtEx, wndExtX, wndExtY, SIZE )
DC_GET_VAL_EX( W32kGetWindowOrgEx, wndOrgX, wndOrgY, POINT ) DC_GET_VAL_EX( W32kGetWindowOrgEx, IntGetWindowOrgEx, wndOrgX, wndOrgY, POINT )
HDC STDCALL HDC STDCALL
W32kResetDC(HDC hDC, CONST DEVMODEW *InitData) W32kResetDC(HDC hDC, CONST DEVMODEW *InitData)
@ -1216,10 +1222,11 @@ W32kSaveDC(HDC hDC)
return ret; return ret;
} }
HGDIOBJ STDCALL HGDIOBJ
STDCALL
W32kSelectObject(HDC hDC, HGDIOBJ hGDIObj) W32kSelectObject(HDC hDC, HGDIOBJ hGDIObj)
{ {
HGDIOBJ objOrg; HGDIOBJ objOrg = NULL; // default to failure
BITMAPOBJ *pb; BITMAPOBJ *pb;
PDC dc; PDC dc;
PPENOBJ pen; PPENOBJ pen;
@ -1234,12 +1241,14 @@ W32kSelectObject(HDC hDC, HGDIOBJ hGDIObj)
if(!hDC || !hGDIObj) return NULL; if(!hDC || !hGDIObj) return NULL;
dc = DC_HandleToPtr(hDC); dc = DC_HandleToPtr(hDC);
ASSERT ( dc );
objectMagic = GDIOBJ_GetHandleMagic (hGDIObj); objectMagic = GDIOBJ_GetHandleMagic (hGDIObj);
// GdiObjHdr = hGDIObj; // GdiObjHdr = hGDIObj;
// FIXME: Get object handle from GDIObj and use it instead of GDIObj below? // FIXME: Get object handle from GDIObj and use it instead of GDIObj below?
switch(objectMagic) switch ( objectMagic )
{ {
case GO_PEN_MAGIC: case GO_PEN_MAGIC:
objOrg = (HGDIOBJ)dc->w.hPen; 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 // Convert the color of the pen to the format of the DC
PalGDI = (PPALGDI)AccessInternalObject((ULONG) dc->w.hPalette); PalGDI = (PPALGDI)AccessInternalObject((ULONG) dc->w.hPalette);
if( PalGDI ) if ( PalGDI )
{ {
XlateObj = (PXLATEOBJ)IntEngCreateXlate(PalGDI->Mode, PAL_RGB, dc->w.hPalette, NULL); XlateObj = (PXLATEOBJ)IntEngCreateXlate(PalGDI->Mode, PAL_RGB, dc->w.hPalette, NULL);
ASSERT ( XlateObj );
pen = GDIOBJ_LockObj(dc->w.hPen, GO_PEN_MAGIC); pen = GDIOBJ_LockObj(dc->w.hPen, GO_PEN_MAGIC);
if( pen ) if( pen )
{ {
pen->logpen.lopnColor = XLATEOBJ_iXlate(XlateObj, pen->logpen.lopnColor); 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); EngDeleteXlate(XlateObj);
} }
break; break;
@ -1269,6 +1279,7 @@ W32kSelectObject(HDC hDC, HGDIOBJ hGDIObj)
if( PalGDI ) if( PalGDI )
{ {
XlateObj = (PXLATEOBJ)IntEngCreateXlate(PalGDI->Mode, PAL_RGB, dc->w.hPalette, NULL); XlateObj = (PXLATEOBJ)IntEngCreateXlate(PalGDI->Mode, PAL_RGB, dc->w.hPalette, NULL);
ASSERT(XlateObj);
brush = GDIOBJ_LockObj(dc->w.hBrush, GO_BRUSH_MAGIC); brush = GDIOBJ_LockObj(dc->w.hBrush, GO_BRUSH_MAGIC);
if( brush ) if( brush )
{ {
@ -1295,6 +1306,7 @@ W32kSelectObject(HDC hDC, HGDIOBJ hGDIObj)
BITMAPOBJ_ReleasePtr(objOrg); BITMAPOBJ_ReleasePtr(objOrg);
dc->w.hBitmap = hGDIObj; dc->w.hBitmap = hGDIObj;
pb = BITMAPOBJ_HandleToPtr(hGDIObj); pb = BITMAPOBJ_HandleToPtr(hGDIObj);
ASSERT(pb);
dc->Surface = BitmapToSurf(pb); dc->Surface = BitmapToSurf(pb);
// if we're working with a DIB, get the palette [fixme: only create if the selected palette is null] // 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; } if(pb->dib->dsBmih.biBitCount == 8) { NumColors = 256; }
ColorMap = ExAllocatePool(PagedPool, sizeof(COLORREF) * NumColors); ColorMap = ExAllocatePool(PagedPool, sizeof(COLORREF) * NumColors);
ASSERT(ColorMap);
for (Index = 0; Index < NumColors; Index++) for (Index = 0; Index < NumColors; Index++)
{ {
ColorMap[Index] = RGB(pb->ColorMap[Index].rgbRed, ColorMap[Index] = RGB(pb->ColorMap[Index].rgbRed,
pb->ColorMap[Index].rgbGreen, pb->ColorMap[Index].rgbGreen,
pb->ColorMap[Index].rgbBlue); pb->ColorMap[Index].rgbBlue);
} }
dc->w.hPalette = EngCreatePalette(PAL_INDEXED, NumColors, (ULONG *) ColorMap, 0, 0, 0); dc->w.hPalette = EngCreatePalette(PAL_INDEXED, NumColors, (ULONG *) ColorMap, 0, 0, 0);
ExFreePool(ColorMap); 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); 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); dc->w.hPalette = EngCreatePalette(PAL_RGB, pb->dib->dsBmih.biClrUsed, NULL, 0, 0, 0);
} }
} else { }
else
{
dc->w.bitsPerPixel = pb->bitmap.bmBitsPixel; dc->w.bitsPerPixel = pb->bitmap.bmBitsPixel;
} }
DC_ReleasePtr ( hDC ); DC_ReleasePtr ( hDC );
hVisRgn = W32kCreateRectRgn(0, 0, pb->size.cx, pb->size.cy); hVisRgn = W32kCreateRectRgn ( 0, 0, pb->size.cx, pb->size.cy );
W32kSelectVisRgn(hDC, hVisRgn); W32kSelectVisRgn ( hDC, hVisRgn );
W32kDeleteObject(hVisRgn); W32kDeleteObject ( hVisRgn );
return objOrg; return objOrg;
@ -1344,8 +1359,7 @@ W32kSelectObject(HDC hDC, HGDIOBJ hGDIObj)
return NULL; return NULL;
#endif #endif
default: default:
DC_ReleasePtr ( hDC ); break;
return NULL;
} }
DC_ReleasePtr( hDC ); DC_ReleasePtr( hDC );
return objOrg; return objOrg;
@ -1360,132 +1374,126 @@ DC_SET_MODE( W32kSetStretchBltMode, w.stretchBltMode, BLACKONWHITE, HALFTONE )
COLORREF STDCALL COLORREF STDCALL
W32kSetBkColor(HDC hDC, COLORREF color) W32kSetBkColor(HDC hDC, COLORREF color)
{ {
COLORREF oldColor; COLORREF oldColor;
PDC dc = DC_HandleToPtr(hDC); PDC dc = DC_HandleToPtr(hDC);
if (!dc) if ( !dc )
{
return 0x80000000; return 0x80000000;
}
oldColor = dc->w.backgroundColor; oldColor = dc->w.backgroundColor;
dc->w.backgroundColor = color; dc->w.backgroundColor = color;
DC_ReleasePtr( hDC ); DC_ReleasePtr ( hDC );
return oldColor; return oldColor;
} }
STATIC VOID FASTCALL STATIC
W32kSetDCState16(HDC hDC, HDC hDCSave) VOID
FASTCALL
W32kSetDCState16 ( HDC hDC, HDC hDCSave )
{ {
PDC dc, dcs; PDC dc, dcs;
dc = DC_HandleToPtr(hDC); dc = DC_HandleToPtr ( hDC );
if (dc == NULL) if ( dc )
{ {
return; dcs = DC_HandleToPtr ( hDCSave );
} if ( dcs )
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)
{ {
dc->w.hClipRgn = W32kCreateRectRgn( 0, 0, 0, 0 ); if ( dcs->w.flags & DC_SAVED )
} {
W32kCombineRgn( dc->w.hClipRgn, dcs->w.hClipRgn, 0, RGN_COPY ); dc->w.flags = dcs->w.flags & ~DC_SAVED;
}
else
{
if (dc->w.hClipRgn)
{
W32kDeleteObject( dc->w.hClipRgn );
}
dc->w.hClipRgn = 0; dc->w.hFirstBitmap = dcs->w.hFirstBitmap;
}
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 #if 0
GDISelectPalette16( hDC, dcs->w.hPalette, FALSE ); dc->w.hDevice = dcs->w.hDevice;
#endif #endif
DC_ReleasePtr( hDCSave ); dc->w.totalExtent = dcs->w.totalExtent;
DC_ReleasePtr( hDC ); 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 // ---------------------------------------------------- Private Interface
@ -1493,38 +1501,38 @@ W32kSetDCState16(HDC hDC, HDC hDCSave)
HDC FASTCALL HDC FASTCALL
DC_AllocDC(LPCWSTR Driver) DC_AllocDC(LPCWSTR Driver)
{ {
PDC NewDC; PDC NewDC;
HDC hDC; HDC hDC;
hDC = (HDC) GDIOBJ_AllocObj(sizeof(DC), GO_DC_MAGIC); hDC = (HDC) GDIOBJ_AllocObj(sizeof(DC), GO_DC_MAGIC);
if (hDC == NULL) if (hDC == NULL)
{ {
return NULL; return NULL;
} }
NewDC = (PDC) GDIOBJ_LockObj( hDC, GO_DC_MAGIC ); NewDC = (PDC) GDIOBJ_LockObj( hDC, GO_DC_MAGIC );
if (Driver != NULL) if (Driver != NULL)
{ {
NewDC->DriverName = ExAllocatePool(PagedPool, (wcslen(Driver) + 1) * sizeof(WCHAR)); NewDC->DriverName = ExAllocatePool(PagedPool, (wcslen(Driver) + 1) * sizeof(WCHAR));
wcscpy(NewDC->DriverName, Driver); wcscpy(NewDC->DriverName, Driver);
} }
NewDC->w.xformWorld2Wnd.eM11 = 1.0f; NewDC->w.xformWorld2Wnd.eM11 = 1.0f;
NewDC->w.xformWorld2Wnd.eM12 = 0.0f; NewDC->w.xformWorld2Wnd.eM12 = 0.0f;
NewDC->w.xformWorld2Wnd.eM21 = 0.0f; NewDC->w.xformWorld2Wnd.eM21 = 0.0f;
NewDC->w.xformWorld2Wnd.eM22 = 1.0f; NewDC->w.xformWorld2Wnd.eM22 = 1.0f;
NewDC->w.xformWorld2Wnd.eDx = 0.0f; NewDC->w.xformWorld2Wnd.eDx = 0.0f;
NewDC->w.xformWorld2Wnd.eDy = 0.0f; NewDC->w.xformWorld2Wnd.eDy = 0.0f;
NewDC->w.xformWorld2Vport = NewDC->w.xformWorld2Wnd; NewDC->w.xformWorld2Vport = NewDC->w.xformWorld2Wnd;
NewDC->w.xformVport2World = NewDC->w.xformWorld2Wnd; NewDC->w.xformVport2World = NewDC->w.xformWorld2Wnd;
NewDC->w.vport2WorldValid = TRUE; NewDC->w.vport2WorldValid = TRUE;
NewDC->w.hFont = W32kGetStockObject(SYSTEM_FONT); NewDC->w.hFont = W32kGetStockObject(SYSTEM_FONT);
TextIntRealizeFont(NewDC->w.hFont); TextIntRealizeFont(NewDC->w.hFont);
GDIOBJ_UnlockObj( hDC, GO_DC_MAGIC ); GDIOBJ_UnlockObj( hDC, GO_DC_MAGIC );
return hDC; return hDC;
} }
HDC FASTCALL HDC FASTCALL

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 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 #undef WIN32_LEAN_AND_MEAN
#include <windows.h> #include <windows.h>
@ -31,7 +31,7 @@
#include <include/paint.h> #include <include/paint.h>
#include <internal/safe.h> #include <internal/safe.h>
#define NDEBUG //#define NDEBUG
#include <win32k/debug1.h> #include <win32k/debug1.h>
BOOL BOOL
@ -96,128 +96,149 @@ extern BOOL FillPolygon(PDC dc,
#endif #endif
//This implementation is blatantly ripped off from W32kRectangle
BOOL BOOL
STDCALL FASTCALL
W32kPolygon(HDC hDC, IntPolygon(PDC dc,
CONST PPOINT UnsafePoints, CONST PPOINT UnsafePoints,
int Count) int Count)
{ {
DC *dc = DC_HandleToPtr(hDC); SURFOBJ *SurfObj;
SURFOBJ *SurfObj = (SURFOBJ*)AccessUserObject((ULONG)dc->Surface); BRUSHOBJ PenBrushObj, *FillBrushObj;
PBRUSHOBJ OutBrushObj, FillBrushObj; BOOL ret = FALSE; // default to failure
BOOL ret;
PRECTL RectBounds; PRECTL RectBounds;
PENOBJ *pen;
RECTL DestRect; RECTL DestRect;
int CurrentPoint; int CurrentPoint;
PPOINT Points; PPOINT Points;
NTSTATUS Status; NTSTATUS Status;
DPRINT("In W32kPolygon()\n"); ASSERT(dc); // caller's responsibility to pass a valid dc
if (NULL == dc || NULL == UnsafePoints || Count < 2) if ( NULL == UnsafePoints || Count < 2 )
{ {
SetLastWin32Error(ERROR_INVALID_PARAMETER); SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
SurfObj = (SURFOBJ*)AccessUserObject((ULONG)dc->Surface);
ASSERT(SurfObj);
/* Copy points from userspace to kernelspace */ /* Copy points from userspace to kernelspace */
Points = ExAllocatePool(PagedPool, Count * sizeof(POINT)); Points = ExAllocatePool(PagedPool, Count * sizeof(POINT));
if (NULL == Points) if (NULL == Points)
{ SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
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);
}
else else
{
Status = MmCopyFromCaller(Points, UnsafePoints, Count * sizeof(POINT));
if ( !NT_SUCCESS(Status) )
SetLastNtError(Status);
else
{ {
/* Get the current pen. */ /* Convert to screen coordinates */
pen = (PENOBJ*) GDIOBJ_LockObj(dc->w.hPen, GO_PEN_MAGIC); for (CurrentPoint = 0; CurrentPoint < Count; CurrentPoint++)
ASSERT(pen); {
OutBrushObj = (PBRUSHOBJ) PenToBrushObj(dc, pen); Points[CurrentPoint].x += dc->w.DCOrgX;
GDIOBJ_UnlockObj(dc->w.hPen, GO_PEN_MAGIC); Points[CurrentPoint].y += dc->w.DCOrgY;
}
DestRect.left = Points[0].x; RectBounds = GDIOBJ_LockObj(dc->w.hGCClipRgn, GO_REGION_MAGIC);
DestRect.right = Points[0].x; //ei not yet implemented ASSERT(RectBounds);
DestRect.top = Points[0].y;
DestRect.bottom = Points[0].y;
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.left = MIN(DestRect.left, Points[CurrentPoint].x);
DestRect.right = MAX(DestRect.right, Points[CurrentPoint].x); DestRect.right = MAX(DestRect.right, Points[CurrentPoint].x);
DestRect.top = MIN(DestRect.top, Points[CurrentPoint].y); DestRect.top = MIN(DestRect.top, Points[CurrentPoint].y);
DestRect.bottom = MAX(DestRect.bottom, 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 #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 #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 /* Let CurrentPoint be i
* if i+1 > Count, Draw a line from Points[i] to Points[0] * if i+1 > Count, Draw a line from Points[i] to Points[0]
* Draw a line from Points[i] to Points[i+1] * Draw a line from Points[i] to Points[i+1]
*/ */
From = Points[CurrentPoint]; From = Points[CurrentPoint];
if (Count <= CurrentPoint + 1) if (Count <= CurrentPoint + 1)
{
To = Points[0]; To = Points[0];
} else
else
{
To = Points[CurrentPoint + 1]; To = Points[CurrentPoint + 1];
}
DPRINT("Polygon Making line from (%d,%d) to (%d,%d)\n", From.x, From.y, To.x, To.y ); //DPRINT("Polygon Making line from (%d,%d) to (%d,%d)\n", From.x, From.y, To.x, To.y );
ret = IntEngLineTo(SurfObj, ret = IntEngLineTo(SurfObj,
dc->CombinedClip, dc->CombinedClip,
OutBrushObj, &PenBrushObj,
From.x, From.x,
From.y, From.y,
To.x, To.x,
To.y, To.y,
&DestRect, &DestRect,
dc->w.ROPmode); /* MIX */ dc->w.ROPmode); /* MIX */
}
} }
#if 0 #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 #endif
GDIOBJ_UnlockObj(dc->w.hBrush, GO_BRUSH_MAGIC); }
GDIOBJ_UnlockObj ( dc->w.hGCClipRgn, GO_REGION_MAGIC );
} }
ExFreePool ( Points );
GDIOBJ_UnlockObj(dc->w.hGCClipRgn, GO_REGION_MAGIC); }
DC_ReleasePtr(hDC); return ret;
ExFreePool(Points); }
//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; return ret;
} }
@ -225,114 +246,136 @@ W32kPolygon(HDC hDC,
BOOL BOOL
STDCALL STDCALL
W32kPolyPolygon(HDC hDC, W32kPolyPolygon(HDC hDC,
CONST LPPOINT Points, CONST LPPOINT Points,
CONST LPINT PolyCounts, CONST LPINT PolyCounts,
int Count) int Count)
{ {
UNIMPLEMENTED; UNIMPLEMENTED;
} }
BOOL BOOL
STDCALL FASTCALL
W32kRectangle(HDC hDC, IntRectangle(PDC dc,
int LeftRect, int LeftRect,
int TopRect, int TopRect,
int RightRect, int RightRect,
int BottomRect) int BottomRect)
{ {
DC *dc = DC_HandleToPtr(hDC); SURFOBJ *SurfObj = (SURFOBJ*)AccessUserObject((ULONG)dc->Surface);
SURFOBJ *SurfObj = (SURFOBJ*)AccessUserObject((ULONG)dc->Surface); BRUSHOBJ PenBrushObj, *FillBrushObj;
PBRUSHOBJ BrushObj; BOOL ret = FALSE; // default to failure
BOOL ret; PRECTL RectBounds;
PRECTL RectBounds; RECTL DestRect;
PENOBJ * pen;
RECTL DestRect;
if(!dc) ASSERT ( dc ); // caller's responsibility to set this up
return FALSE;
RectBounds = GDIOBJ_LockObj(dc->w.hGCClipRgn, GO_REGION_MAGIC); RectBounds = GDIOBJ_LockObj ( dc->w.hGCClipRgn, GO_REGION_MAGIC );
//ei not yet implemented ASSERT(RectBounds); //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 else
{ {
// Draw the rectangle with the current pen LeftRect += dc->w.DCOrgX;
pen = (PENOBJ*) GDIOBJ_LockObj(dc->w.hPen, GO_PEN_MAGIC); RightRect += dc->w.DCOrgX - 1;
ASSERT(pen); TopRect += dc->w.DCOrgY;
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;
BottomRect += dc->w.DCOrgY - 1; BottomRect += dc->w.DCOrgY - 1;
ret = IntEngLineTo(SurfObj, FillBrushObj = (BRUSHOBJ*) GDIOBJ_LockObj(dc->w.hBrush, GO_BRUSH_MAGIC);
dc->CombinedClip,
BrushObj,
LeftRect, TopRect, RightRect, TopRect,
RectBounds, // Bounding rectangle
dc->w.ROPmode); // MIX
ret = IntEngLineTo(SurfObj, ASSERT(FillBrushObj); // FIXME - I *think* this should always happen...
dc->CombinedClip, // it would be nice to remove the following if statement if that proves to be true
BrushObj, if ( FillBrushObj )
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)
{ {
if (BrushObj->logbrush.lbStyle != BS_NULL) if ( FillBrushObj->logbrush.lbStyle != BS_NULL )
{ {
DestRect.left = LeftRect + 1; DestRect.left = LeftRect;
DestRect.right = RightRect; DestRect.right = RightRect;
DestRect.top = TopRect + 1; DestRect.top = TopRect;
DestRect.bottom = BottomRect; DestRect.bottom = BottomRect;
ret = IntEngBitBlt(SurfObj, ret = ret && IntEngBitBlt(SurfObj,
NULL, NULL,
NULL, NULL,
NULL, NULL,
NULL, NULL,
&DestRect, &DestRect,
NULL, NULL,
NULL, NULL,
BrushObj, FillBrushObj,
NULL, NULL,
PATCOPY); PATCOPY);
} }
} }
GDIOBJ_UnlockObj( dc->w.hBrush, GO_BRUSH_MAGIC ); 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); GDIOBJ_UnlockObj(dc->w.hGCClipRgn, GO_REGION_MAGIC);
DC_ReleasePtr( hDC );
return TRUE; 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 BOOL
STDCALL STDCALL
W32kRoundRect(HDC hDC, W32kRoundRect(HDC hDC,

View file

@ -19,7 +19,7 @@
/* /*
* GDIOBJ.C - GDI object manipulation routines * 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 if ( handleEntry == 0
|| (handleEntry->wMagic != Magic && Magic != GO_MAGIC_DONTCARE ) || (handleEntry->wMagic != Magic && Magic != GO_MAGIC_DONTCARE )
|| (handleEntry->hProcessId != (HANDLE)0xFFFFFFFF || (handleEntry->hProcessId != (HANDLE)0xFFFFFFFF
&& handleEntry->hProcessId != PsGetCurrentProcessId () && handleEntry->hProcessId != PsGetCurrentProcessId ()
) )
) )
{ {
DPRINT1("GDIBOJ_LockObj failed for %d, magic: %d, reqMagic\n", int reason = 0;
(WORD)((size_t)hObj&0xffff), handleEntry->wMagic, Magic); 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 ); DPRINT1("\tcalled from: %s:%i\n", file, line );
return NULL; return NULL;
} }

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 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) // Some code from the WINE project source (www.winehq.com)
@ -41,11 +41,11 @@
BOOL BOOL
STDCALL STDCALL
W32kAngleArc(HDC hDC, W32kAngleArc(HDC hDC,
int X, int X,
int Y, int Y,
DWORD Radius, DWORD Radius,
FLOAT StartAngle, FLOAT StartAngle,
FLOAT SweepAngle) FLOAT SweepAngle)
{ {
UNIMPLEMENTED; UNIMPLEMENTED;
} }
@ -53,22 +53,26 @@ W32kAngleArc(HDC hDC,
BOOL BOOL
STDCALL STDCALL
W32kArc(HDC hDC, W32kArc(HDC hDC,
int LeftRect, int LeftRect,
int TopRect, int TopRect,
int RightRect, int RightRect,
int BottomRect, int BottomRect,
int XStartArc, int XStartArc,
int YStartArc, int YStartArc,
int XEndArc, int XEndArc,
int YEndArc) int YEndArc)
{ {
DC *dc = DC_HandleToPtr(hDC); DC *dc = DC_HandleToPtr(hDC);
if(!dc) return FALSE; if(!dc) return FALSE;
if(PATH_IsPathOpen(dc->w.path)) if(PATH_IsPathOpen(dc->w.path))
{
DC_ReleasePtr ( hDC );
return PATH_Arc(hDC, LeftRect, TopRect, RightRect, BottomRect, return PATH_Arc(hDC, LeftRect, TopRect, RightRect, BottomRect,
XStartArc, YStartArc, XEndArc, YEndArc); XStartArc, YStartArc, XEndArc, YEndArc);
}
// FIXME
// EngArc(dc, LeftRect, TopRect, RightRect, BottomRect, UNIMPLEMENTED // EngArc(dc, LeftRect, TopRect, RightRect, BottomRect, UNIMPLEMENTED
// XStartArc, YStartArc, XEndArc, YEndArc); // XStartArc, YStartArc, XEndArc, YEndArc);
@ -79,50 +83,60 @@ W32kArc(HDC hDC,
BOOL BOOL
STDCALL STDCALL
W32kArcTo(HDC hDC, W32kArcTo(HDC hDC,
int LeftRect, int LeftRect,
int TopRect, int TopRect,
int RightRect, int RightRect,
int BottomRect, int BottomRect,
int XRadial1, int XRadial1,
int YRadial1, int YRadial1,
int XRadial2, int XRadial2,
int YRadial2) int YRadial2)
{ {
BOOL result; BOOL result;
DC *dc = DC_HandleToPtr(hDC); //DC *dc;
if(!dc) return FALSE;
// Line from current position to starting point of arc // 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. // Then the arc is drawn.
result = W32kArc(hDC, LeftRect, TopRect, RightRect, BottomRect, result = W32kArc(hDC, LeftRect, TopRect, RightRect, BottomRect,
XRadial1, YRadial1, XRadial2, YRadial2); XRadial1, YRadial1, XRadial2, YRadial2);
//DC_ReleasePtr( hDC );
// If no error occured, the current position is moved to the ending point of the arc. // If no error occured, the current position is moved to the ending point of the arc.
if(result) if(result)
{
W32kMoveToEx(hDC, XRadial2, YRadial2, NULL); W32kMoveToEx(hDC, XRadial2, YRadial2, NULL);
}
DC_ReleasePtr( hDC );
return result; return result;
} }
INT
FASTCALL
IntGetArcDirection ( PDC dc )
{
ASSERT ( dc );
return dc->w.ArcDirection;
}
INT INT
STDCALL STDCALL
W32kGetArcDirection(HDC hDC) W32kGetArcDirection(HDC hDC)
{ {
PDC dc; PDC dc = DC_HandleToPtr (hDC);
int ret; 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; return ret;
} }
@ -132,27 +146,36 @@ W32kLineTo(HDC hDC,
int XEnd, int XEnd,
int YEnd) int YEnd)
{ {
DC *dc = DC_HandleToPtr(hDC); DC *dc = DC_HandleToPtr(hDC);
SURFOBJ *SurfObj = (SURFOBJ*)AccessUserObject((ULONG)dc->Surface); SURFOBJ *SurfObj;
BOOL Ret; BOOL Ret;
PPENOBJ Pen; BRUSHOBJ PenBrushObj;
RECT Bounds; RECT Bounds;
if (NULL == dc) if ( !dc )
{ {
SetLastWin32Error(ERROR_INVALID_HANDLE); SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
SurfObj = (SURFOBJ*)AccessUserObject ( (ULONG)dc->Surface );
if (PATH_IsPathOpen(dc->w.path)) if (PATH_IsPathOpen(dc->w.path))
{ {
DC_ReleasePtr(hDC);
Ret = PATH_LineTo(hDC, XEnd, YEnd); 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 else
{ {
Pen = (PPENOBJ) GDIOBJ_LockObj(dc->w.hPen, GO_PEN_MAGIC);
ASSERT(NULL != Pen);
if (dc->w.CursPosX <= XEnd) if (dc->w.CursPosX <= XEnd)
{ {
Bounds.left = dc->w.CursPosX; Bounds.left = dc->w.CursPosX;
@ -174,19 +197,20 @@ W32kLineTo(HDC hDC,
{ {
Bounds.top = YEnd; Bounds.top = YEnd;
Bounds.bottom = dc->w.CursPosY; Bounds.bottom = dc->w.CursPosY;
} }
Bounds.top += dc->w.DCOrgY; Bounds.top += dc->w.DCOrgY;
Bounds.bottom += dc->w.DCOrgY; Bounds.bottom += dc->w.DCOrgY;
/* make BRUSHOBJ from current pen. */
HPenToBrushObj ( &PenBrushObj, dc->w.hPen );
Ret = IntEngLineTo(SurfObj, Ret = IntEngLineTo(SurfObj,
dc->CombinedClip, dc->CombinedClip,
PenToBrushObj(dc, Pen), &PenBrushObj,
dc->w.DCOrgX + dc->w.CursPosX, dc->w.DCOrgY + dc->w.CursPosY, dc->w.DCOrgX + dc->w.CursPosX, dc->w.DCOrgY + dc->w.CursPosY,
dc->w.DCOrgX + XEnd, dc->w.DCOrgY + YEnd, dc->w.DCOrgX + XEnd, dc->w.DCOrgY + YEnd,
&Bounds, &Bounds,
dc->w.ROPmode); dc->w.ROPmode);
GDIOBJ_UnlockObj( dc->w.hPen, GO_PEN_MAGIC);
} }
if (Ret) if (Ret)
@ -201,84 +225,96 @@ W32kLineTo(HDC hDC,
BOOL BOOL
STDCALL STDCALL
W32kMoveToEx(HDC hDC, W32kMoveToEx(HDC hDC,
int X, int X,
int Y, int Y,
LPPOINT Point) 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->x = dc->w.CursPosX;
Point->y = dc->w.CursPosY; Point->y = dc->w.CursPosY;
} }
dc->w.CursPosX = X; dc->w.CursPosX = X;
dc->w.CursPosY = Y; dc->w.CursPosY = Y;
if(PATH_IsPathOpen(dc->w.path)){ PathIsOpen = PATH_IsPathOpen(dc->w.path);
DC_ReleasePtr( hDC );
return PATH_MoveTo(hDC); DC_ReleasePtr ( hDC );
}
DC_ReleasePtr( hDC ); if ( PathIsOpen )
return PATH_MoveTo ( hDC );
return TRUE; return TRUE;
} }
BOOL BOOL
STDCALL STDCALL
W32kPolyBezier(HDC hDC, W32kPolyBezier(HDC hDC,
CONST LPPOINT pt, CONST LPPOINT pt,
DWORD Count) DWORD Count)
{ {
DC *dc = DC_HandleToPtr(hDC); DC *dc = DC_HandleToPtr(hDC);
if(!dc) return FALSE; BOOL ret = FALSE; // default to FAILURE
if(PATH_IsPathOpen(dc->w.path)){ if ( !dc ) return FALSE;
DC_ReleasePtr( hDC );
return PATH_PolyBezier(hDC, pt, Count); 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 */ /* We'll convert it into line segments and draw them using Polyline */
{ {
POINT *Pts; POINT *Pts;
INT nOut; INT nOut;
BOOL ret;
Pts = GDI_Bezier(pt, Count, &nOut); Pts = GDI_Bezier ( pt, Count, &nOut );
if(!Pts) return FALSE; if ( Pts )
DbgPrint("Pts = %p, no = %d\n", Pts, nOut); {
ret = W32kPolyline(dc->hSelf, Pts, nOut); DbgPrint("Pts = %p, no = %d\n", Pts, nOut);
ExFreePool(Pts); ret = W32kPolyline(dc->hSelf, Pts, nOut);
DC_ReleasePtr( hDC ); ExFreePool(Pts);
return ret; }
} }
DC_ReleasePtr( hDC );
return ret;
} }
BOOL BOOL
STDCALL STDCALL
W32kPolyBezierTo(HDC hDC, W32kPolyBezierTo(HDC hDC,
CONST LPPOINT pt, CONST LPPOINT pt,
DWORD Count) DWORD Count)
{ {
DC *dc = DC_HandleToPtr(hDC); 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)) if ( PATH_IsPathOpen(dc->w.path) )
ret = PATH_PolyBezierTo(hDC, pt, Count); ret = PATH_PolyBezierTo ( hDC, pt, Count );
else { /* We'll do it using PolyBezier */ else /* We'll do it using PolyBezier */
{
POINT *npt; POINT *npt;
npt = ExAllocatePool(NonPagedPool, sizeof(POINT) * (Count + 1)); npt = ExAllocatePool(NonPagedPool, sizeof(POINT) * (Count + 1));
if(!npt) return FALSE; if ( npt )
npt[0].x = dc->w.CursPosX; {
npt[0].y = dc->w.CursPosY; npt[0].x = dc->w.CursPosX;
memcpy(npt + 1, pt, sizeof(POINT) * Count); npt[0].y = dc->w.CursPosY;
ret = W32kPolyBezier(dc->hSelf, npt, Count+1); memcpy(npt + 1, pt, sizeof(POINT) * Count);
ExFreePool(npt); ret = W32kPolyBezier(dc->hSelf, npt, Count+1);
ExFreePool(npt);
}
} }
if(ret) { if ( ret )
{
dc->w.CursPosX = pt[Count-1].x; dc->w.CursPosX = pt[Count-1].x;
dc->w.CursPosY = pt[Count-1].y; dc->w.CursPosY = pt[Count-1].y;
} }
@ -288,114 +324,120 @@ W32kPolyBezierTo(HDC hDC,
BOOL BOOL
STDCALL STDCALL
W32kPolyDraw(HDC hDC, W32kPolyDraw(HDC hDC,
CONST LPPOINT pt, CONST LPPOINT pt,
CONST LPBYTE Types, CONST LPBYTE Types,
int Count) int Count)
{ {
UNIMPLEMENTED; UNIMPLEMENTED;
} }
BOOL BOOL
STDCALL FASTCALL
W32kPolyline(HDC hDC, IntPolyline(PDC dc,
CONST LPPOINT pt, CONST LPPOINT pt,
int Count) int Count)
{ {
DC *dc = DC_HandleToPtr(hDC); SURFOBJ *SurfObj = NULL;
SURFOBJ *SurfObj = (SURFOBJ*)AccessUserObject((ULONG)dc->Surface); BOOL ret = FALSE; // default to failure
BOOL ret; LONG i;
LONG i;
PPENOBJ pen;
PROSRGNDATA reg; PROSRGNDATA reg;
POINT *pts; BRUSHOBJ PenBrushObj;
POINT *pts;
if (!dc) SurfObj = (SURFOBJ*)AccessUserObject((ULONG)dc->Surface);
return(FALSE); 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); // safely copy pt to local version
} if ( STATUS_SUCCESS == MmCopyFromCaller(pts, pt, sizeof(POINT)*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)))
{ {
GDIOBJ_UnlockObj( dc->w.hGCClipRgn, GO_REGION_MAGIC ); //offset the array of point by the dc->w.DCOrg
GDIOBJ_UnlockObj( dc->w.hPen, GO_PEN_MAGIC); for ( i = 0; i < Count; i++ )
DC_ReleasePtr( hDC ); {
return(FALSE); pts[i].x += dc->w.DCOrgX;
} pts[i].y += dc->w.DCOrgY;
}
//safly copy pt to local version
if (STATUS_SUCCESS!=MmCopyFromCaller(pts, pt, sizeof(POINT) * Count)) /* make BRUSHOBJ from current pen. */
{ HPenToBrushObj ( &PenBrushObj, dc->w.hPen );
ExFreePool(pts);
GDIOBJ_UnlockObj( dc->w.hGCClipRgn, GO_REGION_MAGIC ); //get IntEngPolyline to do the drawing.
GDIOBJ_UnlockObj( dc->w.hPen, GO_PEN_MAGIC); ret = IntEngPolyline(SurfObj,
DC_ReleasePtr( hDC ); dc->CombinedClip,
return(FALSE); &PenBrushObj,
pts,
Count,
dc->w.ROPmode);
} }
//offset the array of point by the dc->w.DCOrg ExFreePool ( pts );
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);
} }
DC_ReleasePtr( hDC ); //Clean up
return(ret); GDIOBJ_UnlockObj ( dc->w.hGCClipRgn, GO_REGION_MAGIC );
return ret;
} }
BOOL BOOL
STDCALL STDCALL
W32kPolylineTo(HDC hDC, W32kPolyline(HDC hDC,
CONST LPPOINT pt, CONST LPPOINT pt,
DWORD Count) 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); 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)) if(PATH_IsPathOpen(dc->w.path))
{ {
ret = PATH_PolylineTo(hDC, pt, Count); ret = PATH_PolylineTo(hDC, pt, Count);
} }
else { /* do it using Polyline */ else /* do it using Polyline */
{
POINT *pts = ExAllocatePool(NonPagedPool, sizeof(POINT) * (Count + 1)); POINT *pts = ExAllocatePool(NonPagedPool, sizeof(POINT) * (Count + 1));
if(!pts) return FALSE; if ( pts )
{
pts[0].x = dc->w.CursPosX; pts[0].x = dc->w.CursPosX;
pts[0].y = dc->w.CursPosY; pts[0].y = dc->w.CursPosY;
memcpy( pts + 1, pt, sizeof(POINT) * Count); memcpy( pts + 1, pt, sizeof(POINT) * Count);
ret = W32kPolyline(hDC, pts, Count + 1); ret = W32kPolyline(hDC, pts, Count + 1);
ExFreePool(pts); ExFreePool(pts);
}
} }
if(ret) { if ( ret )
{
dc->w.CursPosX = pt[Count-1].x; dc->w.CursPosX = pt[Count-1].x;
dc->w.CursPosY = pt[Count-1].y; dc->w.CursPosY = pt[Count-1].y;
} }
@ -405,10 +447,10 @@ W32kPolylineTo(HDC hDC,
BOOL BOOL
STDCALL STDCALL
W32kPolyPolyline(HDC hDC, W32kPolyPolyline(HDC hDC,
CONST LPPOINT pt, CONST LPPOINT pt,
CONST LPDWORD PolyPoints, CONST LPDWORD PolyPoints,
DWORD Count) DWORD Count)
{ {
UNIMPLEMENTED; UNIMPLEMENTED;
} }
@ -416,25 +458,20 @@ W32kPolyPolyline(HDC hDC,
int int
STDCALL STDCALL
W32kSetArcDirection(HDC hDC, W32kSetArcDirection(HDC hDC,
int ArcDirection) int ArcDirection)
{ {
PDC dc; PDC dc;
INT nOldDirection; INT nOldDirection = 0; // default to FAILURE
dc = DC_HandleToPtr (hDC); dc = DC_HandleToPtr (hDC);
if (!dc) if ( !dc ) return 0;
if ( ArcDirection == AD_COUNTERCLOCKWISE || ArcDirection == AD_CLOCKWISE )
{ {
return 0; nOldDirection = dc->w.ArcDirection;
} dc->w.ArcDirection = ArcDirection;
if (ArcDirection != AD_COUNTERCLOCKWISE && ArcDirection != AD_CLOCKWISE)
{
// SetLastError(ERROR_INVALID_PARAMETER);
DC_ReleasePtr( hDC );
return 0;
} }
nOldDirection = dc->w.ArcDirection;
dc->w.ArcDirection = ArcDirection;
DC_ReleasePtr( hDC ); DC_ReleasePtr( hDC );
return nOldDirection; return nOldDirection;
} }

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 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 #undef WIN32_LEAN_AND_MEAN
#include <windows.h> #include <windows.h>
@ -35,27 +35,43 @@
#include <include/object.h> #include <include/object.h>
#include <include/surface.h> #include <include/surface.h>
#define NDEBUG //#define NDEBUG
#include <win32k/debug1.h> #include <win32k/debug1.h>
PBRUSHOBJ FASTCALL PenToBrushObj(PDC dc, PENOBJ *pen) BRUSHOBJ*
FASTCALL
PenToBrushObj ( BRUSHOBJ *brush, PENOBJ *pen )
{ {
BRUSHOBJ *BrushObj; ASSERT ( pen );
//XLATEOBJ *RGBtoVGA16; 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*
FASTCALL
BrushObj = ExAllocatePool(NonPagedPool, sizeof(BRUSHOBJ)); HPenToBrushObj ( BRUSHOBJ *brush, HPEN hpen )
BrushObj->iSolidColor = pen->logpen.lopnColor; {
PENOBJ *pen;
return BrushObj; 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 FASTCALL BitmapToSurf(PBITMAPOBJ BitmapObj)
{ {
HBITMAP BitmapHandle; HBITMAP BitmapHandle;
ASSERT ( BitmapObj );
if (NULL != BitmapObj->dib) if (NULL != BitmapObj->dib)
{ {
BitmapHandle = EngCreateBitmap(BitmapObj->size, BitmapObj->dib->dsBm.bmWidthBytes, 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 * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 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 #undef WIN32_LEAN_AND_MEAN
#include <windows.h> #include <windows.h>
#include <ddk/ntddk.h> #include <ddk/ntddk.h>
@ -58,10 +58,27 @@ W32kBeginPath(HDC hDC)
} }
BOOL BOOL
STDCALL FASTCALL
W32kCloseFigure(HDC hDC) IntCloseFigure ( PDC dc )
{ {
UNIMPLEMENTED; 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 BOOL
@ -149,7 +166,9 @@ W32kWidenPath(HDC hDC)
* *
* Initializes the GdiPath structure. * Initializes the GdiPath structure.
*/ */
VOID FASTCALL PATH_InitGdiPath(GdiPath *pPath) VOID
FASTCALL
PATH_InitGdiPath ( GdiPath *pPath )
{ {
assert(pPath!=NULL); assert(pPath!=NULL);
@ -164,7 +183,9 @@ VOID FASTCALL PATH_InitGdiPath(GdiPath *pPath)
* *
* Destroys a GdiPath structure (frees the memory in the arrays). * 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); assert(pPath!=NULL);
@ -182,12 +203,14 @@ VOID FASTCALL PATH_DestroyGdiPath(GdiPath *pPath)
* not a copy constructor). * not a copy constructor).
* Returns TRUE if successful, else FALSE. * 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); assert(pPathDest!=NULL && pPathSrc!=NULL);
/* Make sure destination arrays are big enough */ /* Make sure destination arrays are big enough */
if(!PATH_ReserveEntries(pPathDest, pPathSrc->numEntriesUsed)) if ( !PATH_ReserveEntries(pPathDest, pPathSrc->numEntriesUsed) )
return FALSE; return FALSE;
/* Perform the copy operation */ /* 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 * open path. This starts a new stroke. Returns TRUE if successful, else
* FALSE. * FALSE.
*/ */
BOOL FASTCALL PATH_MoveTo(HDC hdc) BOOL
FASTCALL
PATH_MoveTo ( PDC dc )
{ {
GdiPath *pPath; GdiPath *pPath;
/* Get pointer to path */ /* Get pointer to path */
if(!PATH_GetPathFromHDC(hdc, &pPath)) PATH_GetPathFromDC ( dc, &pPath );
return FALSE;
/* Check that path is open */ /* Check that path is open */
if(pPath->state!=PATH_Open) if ( pPath->state != PATH_Open )
/* FIXME: Do we have to call SetLastError? */ /* FIXME: Do we have to call SetLastError? */
return FALSE; return FALSE;
/* Start a new stroke */ /* Start a new stroke */
pPath->newStroke=TRUE; pPath->newStroke = TRUE;
return 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). * a PT_MOVETO entry, if this is the first LineTo in a stroke).
* Returns TRUE if successful, else FALSE. * 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; GdiPath *pPath;
POINT point, pointCurPos; POINT point, pointCurPos;
/* Get pointer to path */ /* Get pointer to path */
if(!PATH_GetPathFromHDC(hdc, &pPath)) PATH_GetPathFromDC ( dc, &pPath );
return FALSE;
/* Check that path is open */ /* Check that path is open */
if(pPath->state!=PATH_Open) if ( pPath->state != PATH_Open )
return FALSE; return FALSE;
/* Convert point to device coordinates */ /* Convert point to device coordinates */
point.x=x; point.x=x;
point.y=y; point.y=y;
if(!W32kLPtoDP(hdc, &point, 1)) CoordLPtoDP ( dc, &point );
return FALSE;
/* Add a PT_MOVETO if necessary */ /* Add a PT_MOVETO if necessary */
if(pPath->newStroke) if ( pPath->newStroke )
{ {
pPath->newStroke=FALSE; pPath->newStroke = FALSE;
if(!W32kGetCurrentPositionEx(hdc, &pointCurPos) || IntGetCurrentPositionEx ( dc, &pointCurPos );
!W32kLPtoDP(hdc, &pointCurPos, 1)) CoordLPtoDP ( dc, &pointCurPos );
return FALSE; if ( !PATH_AddEntry(pPath, &pointCurPos, PT_MOVETO) )
if(!PATH_AddEntry(pPath, &pointCurPos, PT_MOVETO))
return FALSE; 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 * Should be called when a call to Rectangle is performed on a DC that has
* an open path. Returns TRUE if successful, else FALSE. * 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; GdiPath *pPath;
POINT corners[2], pointTemp; POINT corners[2], pointTemp;
INT temp; INT temp;
/* Get pointer to path */ /* Get pointer to path */
if(!PATH_GetPathFromHDC(hdc, &pPath)) PATH_GetPathFromDC ( dc, &pPath );
return FALSE;
/* Check that path is open */ /* Check that path is open */
if(pPath->state!=PATH_Open) if ( pPath->state != PATH_Open )
return FALSE; return FALSE;
/* Convert points to device coordinates */ /* 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[0].y=y1;
corners[1].x=x2; corners[1].x=x2;
corners[1].y=y2; corners[1].y=y2;
if(!W32kLPtoDP(hdc, corners, 2)) IntLPtoDP ( dc, corners, 2 );
return FALSE;
/* Make sure first corner is top left and second corner is bottom right */ /* 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; temp=corners[0].x;
corners[0].x=corners[1].x; corners[0].x=corners[1].x;
corners[1].x=temp; corners[1].x=temp;
} }
if(corners[0].y>corners[1].y) if ( corners[0].y > corners[1].y )
{ {
temp=corners[0].y; temp=corners[0].y;
corners[0].y=corners[1].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 */ /* 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].x--;
corners[1].y--; corners[1].y--;
} }
/* Close any previous figure */ /* Close any previous figure */
if(!W32kCloseFigure(hdc)) if ( !IntCloseFigure ( dc ) )
{ {
/* The W32kCloseFigure call shouldn't have failed */ /* The W32kCloseFigure call shouldn't have failed */
assert(FALSE); 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 */ /* Add four points to the path */
pointTemp.x=corners[1].x; pointTemp.x=corners[1].x;
pointTemp.y=corners[0].y; pointTemp.y=corners[0].y;
if(!PATH_AddEntry(pPath, &pointTemp, PT_MOVETO)) if ( !PATH_AddEntry(pPath, &pointTemp, PT_MOVETO) )
return FALSE; return FALSE;
if(!PATH_AddEntry(pPath, corners, PT_LINETO)) if ( !PATH_AddEntry(pPath, corners, PT_LINETO) )
return FALSE; return FALSE;
pointTemp.x=corners[0].x; pointTemp.x=corners[0].x;
pointTemp.y=corners[1].y; pointTemp.y=corners[1].y;
if(!PATH_AddEntry(pPath, &pointTemp, PT_LINETO)) if ( !PATH_AddEntry(pPath, &pointTemp, PT_LINETO) )
return FALSE; return FALSE;
if(!PATH_AddEntry(pPath, corners+1, PT_LINETO)) if ( !PATH_AddEntry(pPath, corners+1, PT_LINETO) )
return FALSE; return FALSE;
/* Close the rectangle figure */ /* 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); assert(FALSE);
return 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 * an open path. This adds four Bezier splines representing the ellipse
* to the path. Returns TRUE if successful, else FALSE. * 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 */ /* TODO: This should probably be revised to call PATH_AngleArc */
/* (once it exists) */ /* (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 /* 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 * an open path. This adds up to five Bezier splines representing the arc
* to the path. Returns TRUE if successful, else FALSE. * 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) INT xStart, INT yStart, INT xEnd, INT yEnd)
{ {
GdiPath *pPath; 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; FLOAT_POINT corners[2], pointStart, pointEnd;
BOOL start, end; BOOL start, end;
INT temp; INT temp;
BOOL clockwise;
/* FIXME: This function should check for all possible error returns */ /* FIXME: This function should check for all possible error returns */
/* FIXME: Do we have to respect newStroke? */ /* FIXME: Do we have to respect newStroke? */
/* Get pointer to DC */ ASSERT ( dc );
pDC=DC_HandleToPtr(hdc);
if(pDC==NULL) clockwise = ( IntGetArcDirection(dc) == AD_CLOCKWISE );
return FALSE;
/* Get pointer to path */ /* Get pointer to path */
if(!PATH_GetPathFromHDC(hdc, &pPath)){ PATH_GetPathFromDC ( dc, &pPath );
DC_ReleasePtr( hdc );
return FALSE;
}
/* Check that path is open */ /* Check that path is open */
if(pPath->state!=PATH_Open){ if ( pPath->state != PATH_Open )
DC_ReleasePtr( hdc );
return FALSE; return FALSE;
}
/* FIXME: Do we have to close the current figure? */ /* FIXME: Do we have to close the current figure? */
/* Check for zero height / width */ /* Check for zero height / width */
/* FIXME: Only in GM_COMPATIBLE? */ /* FIXME: Only in GM_COMPATIBLE? */
if(x1==x2 || y1==y2){ if ( x1==x2 || y1==y2 )
DC_ReleasePtr( hdc );
return TRUE; return TRUE;
}
/* Convert points to device coordinates */ /* Convert points to device coordinates */
corners[0].x=(FLOAT)x1; 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); INTERNAL_LPTODP_FLOAT(pDC, &pointEnd);
/* Make sure first corner is top left and second corner is bottom right */ /* 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; temp=corners[0].x;
corners[0].x=corners[1].x; corners[0].x=corners[1].x;
corners[1].x=temp; corners[1].x=temp;
} }
if(corners[0].y>corners[1].y) if ( corners[0].y > corners[1].y )
{ {
temp=corners[0].y; temp=corners[0].y;
corners[0].y=corners[1].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); angleEnd=atan2(y, x);
/* Make sure the end angle is "on the right side" of the start angle */ /* 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; angleEnd+=2*M_PI;
assert(angleEnd>=angleStart); 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 */ /* 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].x--;
corners[1].y--; corners[1].y--;
@ -479,7 +499,7 @@ BOOL STDCALL PATH_Arc(HDC hdc, INT x1, INT y1, INT x2, INT y2,
if(start) if(start)
{ {
angleStartQuadrant=angleStart; angleStartQuadrant=angleStart;
if(W32kGetArcDirection(hdc)==AD_CLOCKWISE) if ( clockwise )
angleEndQuadrant=(floor(angleStart/M_PI_2)+1.0)*M_PI_2; angleEndQuadrant=(floor(angleStart/M_PI_2)+1.0)*M_PI_2;
else else
angleEndQuadrant=(ceil(angleStart/M_PI_2)-1.0)*M_PI_2; 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 else
{ {
angleStartQuadrant=angleEndQuadrant; angleStartQuadrant=angleEndQuadrant;
if(W32kGetArcDirection(hdc)==AD_CLOCKWISE) if ( clockwise )
angleEndQuadrant+=M_PI_2; angleEndQuadrant+=M_PI_2;
else else
angleEndQuadrant-=M_PI_2; angleEndQuadrant-=M_PI_2;
} }
/* Have we reached the last part of the arc? */ /* Have we reached the last part of the arc? */
if((W32kGetArcDirection(hdc)==AD_CLOCKWISE && if ( (clockwise && angleEnd<angleEndQuadrant)
angleEnd<angleEndQuadrant) || || (!clockwise && angleEnd>angleEndQuadrant)
(W32kGetArcDirection(hdc)==AD_COUNTERCLOCKWISE && )
angleEnd>angleEndQuadrant))
{ {
/* Adjust the end angle for this quadrant */ /* Adjust the end angle for this quadrant */
angleEndQuadrant=angleEnd; angleEndQuadrant = angleEnd;
end=TRUE; end = TRUE;
} }
/* Add the Bezier spline to the path */ /* Add the Bezier spline to the path */
PATH_DoArcPart(pPath, corners, angleStartQuadrant, angleEndQuadrant, start); PATH_DoArcPart ( pPath, corners, angleStartQuadrant, angleEndQuadrant, start );
start=FALSE; start = FALSE;
} while(!end); } while(!end);
DC_ReleasePtr( hdc );
return TRUE; 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; GdiPath *pPath;
POINT pt; POINT pt;
ULONG i; ULONG i;
if(!PATH_GetPathFromHDC(hdc, &pPath)) ASSERT ( dc );
return FALSE; ASSERT ( pts );
ASSERT ( cbPoints );
PATH_GetPathFromDC ( dc, &pPath );
/* Check that path is open */ /* Check that path is open */
if(pPath->state!=PATH_Open) if ( pPath->state != PATH_Open )
return FALSE; return FALSE;
/* Add a PT_MOVETO if necessary */ /* Add a PT_MOVETO if necessary */
if(pPath->newStroke) if ( pPath->newStroke )
{ {
pPath->newStroke=FALSE; pPath->newStroke=FALSE;
if(!W32kGetCurrentPositionEx(hdc, &pt) || IntGetCurrentPositionEx ( dc, &pt );
!W32kLPtoDP(hdc, &pt, 1)) CoordLPtoDP ( dc, &pt );
return FALSE; if ( !PATH_AddEntry(pPath, &pt, PT_MOVETO) )
if(!PATH_AddEntry(pPath, &pt, PT_MOVETO))
return FALSE; return FALSE;
} }
for(i = 0; i < cbPoints; i++) { for(i = 0; i < cbPoints; i++)
{
pt = pts[i]; pt = pts[i];
if(!W32kLPtoDP(hdc, &pt, 1)) CoordLPtoDP ( dc, &pt );
return FALSE;
PATH_AddEntry(pPath, &pt, PT_BEZIERTO); PATH_AddEntry(pPath, &pt, PT_BEZIERTO);
} }
return TRUE; 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; GdiPath *pPath;
POINT pt; POINT pt;
ULONG i; ULONG i;
if(!PATH_GetPathFromHDC(hdc, &pPath)) ASSERT ( dc );
return FALSE; ASSERT ( pts );
ASSERT ( cbPoints );
PATH_GetPathFromDC ( dc, &pPath );
/* Check that path is open */ /* Check that path is open */
if(pPath->state!=PATH_Open) if ( pPath->state != PATH_Open )
return FALSE; return FALSE;
for(i = 0; i < cbPoints; i++) { for ( i = 0; i < cbPoints; i++ )
{
pt = pts[i]; pt = pts[i];
if(!W32kLPtoDP(hdc, &pt, 1)) CoordLPtoDP ( dc, &pt );
return FALSE; PATH_AddEntry ( pPath, &pt, (i == 0) ? PT_MOVETO : PT_BEZIERTO );
PATH_AddEntry(pPath, &pt, (i == 0) ? PT_MOVETO : PT_BEZIERTO);
} }
return TRUE; 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; GdiPath *pPath;
POINT pt; POINT pt;
ULONG i; ULONG i;
if(!PATH_GetPathFromHDC(hdc, &pPath)) ASSERT ( dc );
return FALSE; ASSERT ( pts );
ASSERT ( cbPoints );
PATH_GetPathFromDC ( dc, &pPath );
/* Check that path is open */ /* Check that path is open */
if(pPath->state!=PATH_Open) if ( pPath->state != PATH_Open )
return FALSE; return FALSE;
for(i = 0; i < cbPoints; i++) { for ( i = 0; i < cbPoints; i++ )
{
pt = pts[i]; pt = pts[i];
if(!W32kLPtoDP(hdc, &pt, 1)) CoordLPtoDP ( dc, &pt );
return FALSE;
PATH_AddEntry(pPath, &pt, (i == 0) ? PT_MOVETO : PT_LINETO); PATH_AddEntry(pPath, &pt, (i == 0) ? PT_MOVETO : PT_LINETO);
} }
return TRUE; 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; GdiPath *pPath;
POINT pt; POINT pt;
ULONG i; ULONG i;
if(!PATH_GetPathFromHDC(hdc, &pPath)) ASSERT ( dc );
return FALSE; ASSERT ( pts );
ASSERT ( cbPoints );
PATH_GetPathFromDC ( dc, &pPath );
/* Check that path is open */ /* Check that path is open */
if(pPath->state!=PATH_Open) if ( pPath->state != PATH_Open )
return FALSE; return FALSE;
/* Add a PT_MOVETO if necessary */ /* Add a PT_MOVETO if necessary */
if(pPath->newStroke) if ( pPath->newStroke )
{ {
pPath->newStroke=FALSE; pPath->newStroke = FALSE;
if(!W32kGetCurrentPositionEx(hdc, &pt) || IntGetCurrentPositionEx ( dc, &pt );
!W32kLPtoDP(hdc, &pt, 1)) CoordLPtoDP ( dc, &pt );
return FALSE; if ( !PATH_AddEntry(pPath, &pt, PT_MOVETO) )
if(!PATH_AddEntry(pPath, &pt, PT_MOVETO))
return FALSE; return FALSE;
} }
for(i = 0; i < cbPoints; i++) { for(i = 0; i < cbPoints; i++)
{
pt = pts[i]; pt = pts[i];
if(!W32kLPtoDP(hdc, &pt, 1)) CoordLPtoDP ( dc, &pt );
return FALSE;
PATH_AddEntry(pPath, &pt, PT_LINETO); 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; GdiPath *pPath;
POINT pt; POINT pt;
ULONG i; ULONG i;
if(!PATH_GetPathFromHDC(hdc, &pPath)) ASSERT ( dc );
return FALSE; ASSERT ( pts );
PATH_GetPathFromDC ( dc, &pPath );
/* Check that path is open */ /* Check that path is open */
if(pPath->state!=PATH_Open) if ( pPath->state != PATH_Open )
return FALSE; return FALSE;
for(i = 0; i < cbPoints; i++) { for(i = 0; i < cbPoints; i++)
{
pt = pts[i]; pt = pts[i];
if(!W32kLPtoDP(hdc, &pt, 1)) CoordLPtoDP ( dc, &pt );
return FALSE;
PATH_AddEntry(pPath, &pt, (i == 0) ? PT_MOVETO : PATH_AddEntry(pPath, &pt, (i == 0) ? PT_MOVETO :
((i == cbPoints-1) ? PT_LINETO | PT_CLOSEFIGURE : ((i == cbPoints-1) ? PT_LINETO | PT_CLOSEFIGURE :
PT_LINETO)); PT_LINETO));
@ -649,25 +690,31 @@ BOOL STDCALL PATH_Polygon(HDC hdc, const POINT *pts, DWORD cbPoints)
return TRUE; return TRUE;
} }
BOOL STDCALL PATH_PolyPolygon( HDC hdc, const POINT* pts, const INT* counts, BOOL
UINT polygons ) FASTCALL
PATH_PolyPolygon ( PDC dc, const POINT* pts, const INT* counts, UINT polygons )
{ {
GdiPath *pPath; GdiPath *pPath;
POINT pt, startpt; POINT pt, startpt;
ULONG poly, point, i; ULONG poly, point, i;
if(!PATH_GetPathFromHDC(hdc, &pPath)) ASSERT ( dc );
return FALSE; ASSERT ( pts );
ASSERT ( counts );
ASSERT ( polygons );
PATH_GetPathFromDC ( dc, &pPath );
/* Check that path is open */ /* Check that path is open */
if(pPath->state!=PATH_Open) if ( pPath->state != PATH_Open );
return FALSE; return FALSE;
for(i = 0, poly = 0; poly < polygons; poly++) { for(i = 0, poly = 0; poly < polygons; poly++)
for(point = 0; point < (ULONG) counts[poly]; point++, i++) { {
for(point = 0; point < (ULONG) counts[poly]; point++, i++)
{
pt = pts[i]; pt = pts[i];
if(!W32kLPtoDP(hdc, &pt, 1)) CoordLPtoDP ( dc, &pt );
return FALSE;
if(point == 0) startpt = pt; if(point == 0) startpt = pt;
PATH_AddEntry(pPath, &pt, (point == 0) ? PT_MOVETO : PT_LINETO); 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; return TRUE;
} }
BOOL STDCALL PATH_PolyPolyline( HDC hdc, const POINT* pts, const DWORD* counts, BOOL
DWORD polylines ) FASTCALL
PATH_PolyPolyline ( PDC dc, const POINT* pts, const DWORD* counts, DWORD polylines )
{ {
GdiPath *pPath; GdiPath *pPath;
POINT pt; POINT pt;
ULONG poly, point, i; ULONG poly, point, i;
if(!PATH_GetPathFromHDC(hdc, &pPath)) ASSERT ( dc );
return FALSE; ASSERT ( pts );
ASSERT ( counts );
ASSERT ( polylines );
PATH_GetPathFromDC ( dc, &pPath );
/* Check that path is open */ /* Check that path is open */
if(pPath->state!=PATH_Open) if ( pPath->state != PATH_Open )
return FALSE; return FALSE;
for(i = 0, poly = 0; poly < polylines; poly++) { for(i = 0, poly = 0; poly < polylines; poly++)
for(point = 0; point < counts[poly]; point++, i++) { {
for(point = 0; point < counts[poly]; point++, i++)
{
pt = pts[i]; pt = pts[i];
if(!W32kLPtoDP(hdc, &pt, 1)) CoordLPtoDP ( dc, &pt );
return FALSE;
PATH_AddEntry(pPath, &pt, (point == 0) ? PT_MOVETO : PT_LINETO); 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 /* PATH_AddFlatBezier
* *
*/ */
BOOL STDCALL PATH_AddFlatBezier(GdiPath *pPath, POINT *pt, BOOL closed) BOOL
FASTCALL
PATH_AddFlatBezier ( GdiPath *pPath, POINT *pt, BOOL closed )
{ {
POINT *pts; POINT *pts;
INT no, i; INT no, i;
pts = GDI_Bezier( pt, 4, &no ); pts = GDI_Bezier( pt, 4, &no );
if(!pts) return FALSE; if ( !pts ) return FALSE;
for(i = 1; i < no; i++) for(i = 1; i < no; i++)
PATH_AddEntry(pPath, &pts[i], (i == no-1 && closed) ? PT_LINETO | PT_CLOSEFIGURE : PT_LINETO); 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 * Replaces Beziers with line segments
* *
*/ */
BOOL FASTCALL PATH_FlattenPath(GdiPath *pPath) BOOL
FASTCALL
PATH_FlattenPath(GdiPath *pPath)
{ {
GdiPath newPath; GdiPath newPath;
INT srcpt; INT srcpt;
@ -769,15 +826,16 @@ BOOL FASTCALL PATH_FlattenPath(GdiPath *pPath)
// expecting a non-const*. Since this function isn't being called // expecting a non-const*. Since this function isn't being called
// at the moment, I'm commenting it out until the issue needs to // at the moment, I'm commenting it out until the issue needs to
// be addressed. // be addressed.
BOOL STDCALL PATH_PathToRegion(const GdiPath *pPath, INT nPolyFillMode, BOOL
HRGN *pHrgn) FASTCALL
PATH_PathToRegion ( const GdiPath *pPath, INT nPolyFillMode, HRGN *pHrgn )
{ {
int numStrokes, iStroke, i; int numStrokes, iStroke, i;
INT *pNumPointsInStroke; INT *pNumPointsInStroke;
HRGN hrgn; HRGN hrgn;
assert(pPath!=NULL); assert ( pPath!=NULL );
assert(pHrgn!=NULL); assert ( pHrgn!=NULL );
PATH_FlattenPath ( pPath ); 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. * 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); assert(pPath!=NULL);
@ -848,7 +908,9 @@ VOID STDCALL PATH_EmptyPath(GdiPath *pPath)
* or PT_BEZIERTO, optionally ORed with PT_CLOSEFIGURE. Returns TRUE if * or PT_BEZIERTO, optionally ORed with PT_CLOSEFIGURE. Returns TRUE if
* successful, FALSE otherwise (e.g. if not enough memory was available). * 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); assert(pPath!=NULL);
@ -857,11 +919,11 @@ BOOL STDCALL PATH_AddEntry(GdiPath *pPath, const POINT *pPoint, BYTE flags)
*/ */
/* Check that path is open */ /* Check that path is open */
if(pPath->state!=PATH_Open) if ( pPath->state != PATH_Open )
return FALSE; return FALSE;
/* Reserve enough memory for an extra path entry */ /* Reserve enough memory for an extra path entry */
if(!PATH_ReserveEntries(pPath, pPath->numEntriesUsed+1)) if ( !PATH_ReserveEntries(pPath, pPath->numEntriesUsed+1) )
return FALSE; return FALSE;
/* Store information in path entry */ /* 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 * been allocated; allocates larger arrays and copies the existing entries
* to those arrays, if necessary. Returns TRUE if successful, else FALSE. * 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; INT numEntriesToAllocate;
POINT *pPointsNew; POINT *pPointsNew;
@ -937,23 +1001,18 @@ BOOL STDCALL PATH_ReserveEntries(GdiPath *pPath, INT numEntries)
return TRUE; return TRUE;
} }
/* PATH_GetPathFromHDC /* PATH_GetPathFromDC
* *
* Retrieves a pointer to the GdiPath structure contained in an HDC and * Retrieves a pointer to the GdiPath structure contained in an HDC and
* places it in *ppPath. TRUE is returned if successful, FALSE otherwise. * 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; ASSERT ( dc );
ASSERT ( ppPath );
pDC=DC_HandleToPtr(hdc); *ppPath = &dc->w.path;
if(pDC)
{
*ppPath=&pDC->w.path;
DC_ReleasePtr( hdc );
return TRUE;
}
return FALSE;
} }
/* PATH_DoArcPart /* 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 * point is added to the path; otherwise, it is assumed that the current
* position is equal to the first control point. * position is equal to the first control point.
*/ */
BOOL STDCALL PATH_DoArcPart(GdiPath *pPath, FLOAT_POINT corners[], BOOL
double angleStart, double angleEnd, BOOL addMoveTo) FASTCALL
PATH_DoArcPart ( GdiPath *pPath, FLOAT_POINT corners[],
double angleStart, double angleEnd, BOOL addMoveTo )
{ {
double halfAngle, a; double halfAngle, a;
double xNorm[4], yNorm[4]; 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 * coordinates (-1.0, -1.0) correspond to corners[0], the coordinates
* (1.0, 1.0) correspond to corners[1]. * (1.0, 1.0) correspond to corners[1].
*/ */
VOID STDCALL PATH_ScaleNormalizedPoint(FLOAT_POINT corners[], double x, VOID
double y, POINT *pPoint) 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->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) ); 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 * Normalizes a point with respect to the box whose corners are passed in
* corners. The normalized coordinates are stored in *pX and *pY. * 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, const FLOAT_POINT *pPoint,
double *pX, double *pY) 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; *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; *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 * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -37,7 +37,7 @@
#include <include/object.h> #include <include/object.h>
#include <include/paint.h> #include <include/paint.h>
#define NDEBUG #undef NDEBUG
#include <win32k/debug1.h> #include <win32k/debug1.h>
INT abs(INT nm); INT abs(INT nm);
@ -146,9 +146,9 @@ POLYGONFILL_MakeEdge(POINT From, POINT To)
rc->ToY = From.y; rc->ToY = From.y;
rc->YDirection = -1; rc->YDirection = -1;
// lines that go up get walked backwards, so need to be offset // 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 // by -1 in order to make the walk identically on a pixel-level
rc->Error = -1; rc->Error = -1;
} }
else else
{ {
@ -158,7 +158,7 @@ POLYGONFILL_MakeEdge(POINT From, POINT To)
rc->ToY = To.y; rc->ToY = To.y;
rc->YDirection = 1; rc->YDirection = 1;
rc->Error = 0; rc->Error = 0;
} }
rc->x = rc->FromX; rc->x = rc->FromX;
@ -178,25 +178,8 @@ POLYGONFILL_MakeEdge(POINT From, POINT To)
rc->pNext = 0; rc->pNext = 0;
rc->XIntercept[0] = rc->x; //DPRINT("MakeEdge (%i,%i)->(%i,%i) d=(%i,%i) dir=(%i,%i) err=%i max=%i\n",
rc->XIntercept[1] = rc->x; // From.x, From.y, To.x, To.y, rc->dx, rc->dy, rc->XDirection, rc->YDirection, rc->Error, rc->ErrorMax );
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 );
return rc; return rc;
} }
@ -334,20 +317,11 @@ POLYGONFILL_UpdateScanline(FILL_EDGE* pEdge, int Scanline)
if ( 0 == pEdge->dy ) if ( 0 == pEdge->dy )
return; return;
ASSERT ( pEdge->FromY < Scanline && pEdge->ToY >= Scanline ); ASSERT ( pEdge->FromY <= Scanline && pEdge->ToY >= Scanline );
if ( pEdge->xmajor ) if ( pEdge->xmajor )
{ {
int steps; 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 ); ASSERT ( pEdge->y == Scanline );
@ -368,9 +342,22 @@ POLYGONFILL_UpdateScanline(FILL_EDGE* pEdge, int Scanline)
pEdge->XIntercept[0] = pEdge->x; pEdge->XIntercept[0] = pEdge->x;
pEdge->XIntercept[1] = 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 else // then this is a y-major line
{ {
pEdge->XIntercept[0] = pEdge->x;
pEdge->XIntercept[1] = pEdge->x;
pEdge->Error += pEdge->absdx; pEdge->Error += pEdge->absdx;
pEdge->y++; pEdge->y++;
@ -380,13 +367,10 @@ POLYGONFILL_UpdateScanline(FILL_EDGE* pEdge, int Scanline)
pEdge->x += pEdge->XDirection; pEdge->x += pEdge->XDirection;
ASSERT ( pEdge->Error < pEdge->ErrorMax ); 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", //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] ); // 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]; FILL_EDGE* pEdge = list->Edges[i];
ASSERT(pEdge); ASSERT(pEdge);
if ( pEdge->FromY < Scanline && pEdge->ToY >= Scanline ) if ( pEdge->FromY <= Scanline && pEdge->ToY >= Scanline )
{ {
POLYGONFILL_UpdateScanline ( pEdge, Scanline ); POLYGONFILL_UpdateScanline ( pEdge, Scanline );
POLYGONFILL_ActiveListInsert ( ActiveHead, pEdge ); POLYGONFILL_ActiveListInsert ( ActiveHead, pEdge );
@ -439,8 +423,8 @@ POLYGONFILL_FillScanLineAlternate(
while ( NULL != pRight ) while ( NULL != pRight )
{ {
int x1 = pLeft->XIntercept[1]+1; int x1 = pLeft->XIntercept[0];
int x2 = pRight->XIntercept[0]; int x2 = pRight->XIntercept[1];
if ( x2 > x1 ) if ( x2 > x1 )
{ {
RECTL BoundRect; RECTL BoundRect;
@ -449,7 +433,7 @@ POLYGONFILL_FillScanLineAlternate(
BoundRect.left = x1; BoundRect.left = x1;
BoundRect.right = x2; 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, IntEngLineTo( SurfObj,
dc->CombinedClip, dc->CombinedClip,
BrushObj, BrushObj,
@ -477,43 +461,84 @@ POLYGONFILL_FillScanLineWinding(
MIX RopMode ) MIX RopMode )
{ {
FILL_EDGE *pLeft, *pRight; FILL_EDGE *pLeft, *pRight;
int winding = 0; int x1, x2, winding = 0;
RECTL BoundRect;
if ( !ActiveHead ) if ( !ActiveHead )
return; return;
BoundRect.top = ScanLine;
BoundRect.bottom = ScanLine + 1;
pLeft = ActiveHead; pLeft = ActiveHead;
winding = pLeft->YDirection; winding = pLeft->YDirection;
pRight = pLeft->pNext; pRight = pLeft->pNext;
ASSERT(pRight); ASSERT(pRight);
// setup first line...
x1 = pLeft->XIntercept[0];
x2 = pRight->XIntercept[1];
pLeft = pRight;
pRight = pLeft->pNext;
winding += pLeft->YDirection;
while ( NULL != pRight ) while ( NULL != pRight )
{ {
int x1 = pLeft->XIntercept[1]+1; int newx1 = pLeft->XIntercept[0];
int x2 = pRight->XIntercept[0]; int newx2 = pRight->XIntercept[1];
if ( winding && x2 > x1 ) if ( winding )
{ {
RECTL BoundRect; // check and see if this new line touches the previous...
BoundRect.top = ScanLine; if ( (newx1 >= x1 && newx1 <= x2)
BoundRect.bottom = ScanLine + 1; || (newx2 >= x1 && newx2 <= x2)
BoundRect.left = x1; || (x1 >= newx1 && x1 <= newx2)
BoundRect.right = x2; || (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); //DPRINT("Fill Line (%d, %d) to (%d, %d)\n",x1, ScanLine, x2, ScanLine);
IntEngLineTo( SurfObj, IntEngLineTo( SurfObj,
dc->CombinedClip, dc->CombinedClip,
BrushObj, BrushObj,
x1, x1,
ScanLine, ScanLine,
x2, x2,
ScanLine, ScanLine,
&BoundRect, // Bounding rectangle &BoundRect, // Bounding rectangle
RopMode); // MIX RopMode); // MIX
x1 = newx1;
x2 = newx2;
}
} }
pLeft = pRight; pLeft = pRight;
pRight = pLeft->pNext; pRight = pLeft->pNext;
winding += pLeft->YDirection; 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 //When the fill mode is ALTERNATE, GDI fills the area between odd-numbered and
@ -550,7 +575,7 @@ FillPolygon(
PBRUSHOBJ BrushObj, PBRUSHOBJ BrushObj,
MIX RopMode ); MIX RopMode );
DPRINT("FillPolygon\n"); //DPRINT("FillPolygon\n");
/* Create Edge List. */ /* Create Edge List. */
list = POLYGONFILL_MakeEdgeList(Points, Count); list = POLYGONFILL_MakeEdgeList(Points, Count);
@ -566,7 +591,7 @@ FillPolygon(
/* For each Scanline from BoundRect.bottom to BoundRect.top, /* For each Scanline from BoundRect.bottom to BoundRect.top,
* determine line segments to draw * 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); POLYGONFILL_BuildActiveList(ScanLine, list, &ActiveHead);
//DEBUG_PRINT_ACTIVE_EDGELIST(ActiveHead); //DEBUG_PRINT_ACTIVE_EDGELIST(ActiveHead);