mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 04:53:00 +00:00
[WIN32K] Sync bezier.c with Wine Staging 1.7.37. CORE-9246
svn path=/trunk/; revision=67957
This commit is contained in:
parent
604dacb5af
commit
af907575d7
3 changed files with 129 additions and 139 deletions
|
@ -331,5 +331,8 @@ secur32 -
|
||||||
reactos/dll/win32/secur32/thunks.c # Synced to WineStaging-1.7.37
|
reactos/dll/win32/secur32/thunks.c # Synced to WineStaging-1.7.37
|
||||||
reactos/dll/win32/secur32/wrapper.c # Synced to WineStaging-1.7.37
|
reactos/dll/win32/secur32/wrapper.c # Synced to WineStaging-1.7.37
|
||||||
|
|
||||||
|
win32k -
|
||||||
|
win32ss/gdi/ntgdi/bezier.c # Synced to WineStaging-1.7.37
|
||||||
|
|
||||||
ws2_32 -
|
ws2_32 -
|
||||||
reactos/dll/win32/ws2_32/misc/async.c # Synced to Wine-1.5.4
|
reactos/dll/win32/ws2_32/misc/async.c # Synced to Wine-1.5.4
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* COPYRIGHT: GNU GPL, See COPYING in the top level directory
|
* COPYRIGHT: GNU LGPL
|
||||||
* PROJECT: ReactOS kernel
|
* PURPOSE: Bezier functions
|
||||||
* PURPOSE: Bezier functions
|
|
||||||
* FILE: subsys/win32k/objects/bezier.c
|
|
||||||
* PROGRAMER: Unknown
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <win32k.h>
|
#include <win32k.h>
|
||||||
|
@ -11,12 +8,14 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
/* Based on Wine Staging 1.7.37 - dlls/gdi32/painting.c */
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
*
|
*
|
||||||
* *Very* simple bezier drawing code,
|
* *Very* simple bezier drawing code,
|
||||||
*
|
*
|
||||||
* It uses a recursive algorithm to divide the curve in a series
|
* It uses a recursive algorithm to divide the curve in a series
|
||||||
* of straight line segements. Not ideal but for me sufficient.
|
* of straight line segments. Not ideal but sufficient for me.
|
||||||
* If you are in need for something better look for some incremental
|
* If you are in need for something better look for some incremental
|
||||||
* algorithm.
|
* algorithm.
|
||||||
*
|
*
|
||||||
|
@ -24,14 +23,14 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Some macro definitions for bezier drawing.
|
* some macro definitions for bezier drawing
|
||||||
*
|
*
|
||||||
* To avoid trucation errors the coordinates are
|
* to avoid truncation errors the coordinates are
|
||||||
* shifted upwards. When used in drawing they are
|
* shifted upwards. When used in drawing they are
|
||||||
* shifted down again, including correct rounding
|
* shifted down again, including correct rounding
|
||||||
* and avoiding floating point arithmatic
|
* and avoiding floating point arithmetic
|
||||||
* 4 bits should allow 27 bits coordinates which I saw
|
* 4 bits should allow 27 bits coordinates which I saw
|
||||||
* somewere in the win32 doc's
|
* somewhere in the win32 doc's
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -39,20 +38,20 @@
|
||||||
#define BEZIERSHIFTUP(x) ((x)<<BEZIERSHIFTBITS)
|
#define BEZIERSHIFTUP(x) ((x)<<BEZIERSHIFTBITS)
|
||||||
#define BEZIERPIXEL BEZIERSHIFTUP(1)
|
#define BEZIERPIXEL BEZIERSHIFTUP(1)
|
||||||
#define BEZIERSHIFTDOWN(x) (((x)+(1<<(BEZIERSHIFTBITS-1)))>>BEZIERSHIFTBITS)
|
#define BEZIERSHIFTDOWN(x) (((x)+(1<<(BEZIERSHIFTBITS-1)))>>BEZIERSHIFTBITS)
|
||||||
/* Maximum depth of recursion */
|
/* maximum depth of recursion */
|
||||||
#define BEZIERMAXDEPTH 8
|
#define BEZIERMAXDEPTH 8
|
||||||
|
|
||||||
/* Size of array to store points on */
|
/* size of array to store points on */
|
||||||
/* enough for one curve */
|
/* enough for one curve */
|
||||||
#define BEZIER_INITBUFSIZE (150)
|
#define BEZIER_INITBUFSIZE (150)
|
||||||
|
|
||||||
/* Calculate Bezier average, in this case the middle
|
/* calculate Bezier average, in this case the middle
|
||||||
* correctly rounded...
|
* correctly rounded...
|
||||||
* */
|
* */
|
||||||
|
|
||||||
#define BEZIERMIDDLE(Mid, P1, P2) \
|
#define BEZIERMIDDLE(Mid, P1, P2) \
|
||||||
(Mid).x=((P1).x+(P2).x + 1) >> 1;\
|
(Mid).x=((P1).x+(P2).x + 1)/2;\
|
||||||
(Mid).y=((P1).y+(P2).y + 1) >> 1;
|
(Mid).y=((P1).y+(P2).y + 1)/2;
|
||||||
|
|
||||||
/**********************************************************
|
/**********************************************************
|
||||||
* BezierCheck helper function to check
|
* BezierCheck helper function to check
|
||||||
|
@ -60,120 +59,109 @@
|
||||||
* Points[0] and Points[3] are begin and endpoint
|
* Points[0] and Points[3] are begin and endpoint
|
||||||
* Points[1] and Points[2] are control points
|
* Points[1] and Points[2] are control points
|
||||||
* level is the recursion depth
|
* level is the recursion depth
|
||||||
* returns true if the recusion can be terminated
|
* returns true if the recursion can be terminated
|
||||||
*/
|
*/
|
||||||
static BOOL FASTCALL BezierCheck( int level, POINT *Points)
|
static BOOL BezierCheck( int level, POINT *Points)
|
||||||
{
|
{
|
||||||
INT dx, dy;
|
INT dx, dy;
|
||||||
|
dx=Points[3].x-Points[0].x;
|
||||||
dx=Points[3].x-Points[0].x;
|
dy=Points[3].y-Points[0].y;
|
||||||
dy=Points[3].y-Points[0].y;
|
if(abs(dy)<=abs(dx)){/* shallow line */
|
||||||
if ( abs(dy) <= abs(dx) ) /* Shallow line */
|
/* check that control points are between begin and end */
|
||||||
{
|
if(Points[1].x < Points[0].x){
|
||||||
/* Check that control points are between begin and end */
|
if(Points[1].x < Points[3].x)
|
||||||
if ( Points[1].x < Points[0].x )
|
return FALSE;
|
||||||
{
|
}else
|
||||||
if ( Points[1].x < Points[3].x )
|
if(Points[1].x > Points[3].x)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
if(Points[2].x < Points[0].x){
|
||||||
else if ( Points[1].x > Points[3].x )
|
if(Points[2].x < Points[3].x)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if ( Points[2].x < Points[0].x)
|
}else
|
||||||
{
|
if(Points[2].x > Points[3].x)
|
||||||
if ( Points[2].x < Points[3].x )
|
return FALSE;
|
||||||
return FALSE;
|
dx=BEZIERSHIFTDOWN(dx);
|
||||||
}
|
if(!dx) return TRUE;
|
||||||
else if ( Points[2].x > Points[3].x )
|
if(abs(Points[1].y-Points[0].y-(dy/dx)*
|
||||||
return FALSE;
|
BEZIERSHIFTDOWN(Points[1].x-Points[0].x)) > BEZIERPIXEL ||
|
||||||
dx = BEZIERSHIFTDOWN(dx);
|
abs(Points[2].y-Points[0].y-(dy/dx)*
|
||||||
if ( !dx )
|
BEZIERSHIFTDOWN(Points[2].x-Points[0].x)) > BEZIERPIXEL )
|
||||||
return TRUE;
|
return FALSE;
|
||||||
if ( abs(Points[1].y-Points[0].y-(dy/dx)*
|
else
|
||||||
BEZIERSHIFTDOWN(Points[1].x-Points[0].x)) > BEZIERPIXEL ||
|
return TRUE;
|
||||||
abs(Points[2].y-Points[0].y-(dy/dx)*
|
}else{ /* steep line */
|
||||||
BEZIERSHIFTDOWN(Points[2].x-Points[0].x)) > BEZIERPIXEL
|
/* check that control points are between begin and end */
|
||||||
)
|
if(Points[1].y < Points[0].y){
|
||||||
return FALSE;
|
if(Points[1].y < Points[3].y)
|
||||||
else
|
return FALSE;
|
||||||
return TRUE;
|
}else
|
||||||
}
|
if(Points[1].y > Points[3].y)
|
||||||
else
|
return FALSE;
|
||||||
{
|
if(Points[2].y < Points[0].y){
|
||||||
/* Steep line */
|
if(Points[2].y < Points[3].y)
|
||||||
/* Check that control points are between begin and end */
|
return FALSE;
|
||||||
if(Points[1].y < Points[0].y)
|
}else
|
||||||
{
|
if(Points[2].y > Points[3].y)
|
||||||
if(Points[1].y < Points[3].y)
|
return FALSE;
|
||||||
return FALSE;
|
dy=BEZIERSHIFTDOWN(dy);
|
||||||
}
|
if(!dy) return TRUE;
|
||||||
else if(Points[1].y > Points[3].y)
|
if(abs(Points[1].x-Points[0].x-(dx/dy)*
|
||||||
return FALSE;
|
BEZIERSHIFTDOWN(Points[1].y-Points[0].y)) > BEZIERPIXEL ||
|
||||||
if ( Points[2].y < Points[0].y )
|
abs(Points[2].x-Points[0].x-(dx/dy)*
|
||||||
{
|
BEZIERSHIFTDOWN(Points[2].y-Points[0].y)) > BEZIERPIXEL )
|
||||||
if ( Points[2].y < Points[3].y )
|
return FALSE;
|
||||||
return FALSE;
|
else
|
||||||
}
|
return TRUE;
|
||||||
else if ( Points[2].y > Points[3].y )
|
|
||||||
return FALSE;
|
|
||||||
dy = BEZIERSHIFTDOWN(dy);
|
|
||||||
if ( !dy )
|
|
||||||
return TRUE;
|
|
||||||
if ( abs(Points[1].x-Points[0].x-(dx/dy)*
|
|
||||||
BEZIERSHIFTDOWN(Points[1].y-Points[0].y)) > BEZIERPIXEL ||
|
|
||||||
abs(Points[2].x-Points[0].x-(dx/dy)*
|
|
||||||
BEZIERSHIFTDOWN(Points[2].y-Points[0].y)) > BEZIERPIXEL
|
|
||||||
)
|
|
||||||
return FALSE;
|
|
||||||
else
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Helper for GDI_Bezier.
|
/* Helper for GDI_Bezier.
|
||||||
* Just handles one Bezier, so Points should point to four POINTs
|
* Just handles one Bezier, so Points should point to four POINTs
|
||||||
*/
|
*/
|
||||||
static void APIENTRY GDI_InternalBezier( POINT *Points, POINT **PtsOut, INT *dwOut,
|
static void GDI_InternalBezier( POINT *Points, POINT **PtsOut, INT *dwOut,
|
||||||
INT *nPtsOut, INT level )
|
INT *nPtsOut, INT level )
|
||||||
{
|
{
|
||||||
if(*nPtsOut == *dwOut) {
|
if(*nPtsOut == *dwOut) {
|
||||||
*dwOut *= 2;
|
*dwOut *= 2;
|
||||||
*PtsOut = ExAllocatePoolWithTag(PagedPool, *dwOut * sizeof(POINT), TAG_BEZIER);
|
*PtsOut = ExAllocatePoolWithTag(PagedPool, *dwOut * sizeof(POINT), TAG_BEZIER);
|
||||||
if (*PtsOut == NULL)
|
if (*PtsOut == NULL)
|
||||||
{
|
{
|
||||||
/// \todo FIXME!
|
/// \todo FIXME!
|
||||||
NT_ASSERT(FALSE);
|
NT_ASSERT(FALSE);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if(!level || BezierCheck(level, Points)) {
|
if(!level || BezierCheck(level, Points)) {
|
||||||
if(*nPtsOut == 0) {
|
if(*nPtsOut == 0) {
|
||||||
(*PtsOut)[0].x = BEZIERSHIFTDOWN(Points[0].x);
|
(*PtsOut)[0].x = BEZIERSHIFTDOWN(Points[0].x);
|
||||||
(*PtsOut)[0].y = BEZIERSHIFTDOWN(Points[0].y);
|
(*PtsOut)[0].y = BEZIERSHIFTDOWN(Points[0].y);
|
||||||
*nPtsOut = 1;
|
*nPtsOut = 1;
|
||||||
|
}
|
||||||
|
(*PtsOut)[*nPtsOut].x = BEZIERSHIFTDOWN(Points[3].x);
|
||||||
|
(*PtsOut)[*nPtsOut].y = BEZIERSHIFTDOWN(Points[3].y);
|
||||||
|
(*nPtsOut) ++;
|
||||||
|
} else {
|
||||||
|
POINT Points2[4]; /* for the second recursive call */
|
||||||
|
Points2[3]=Points[3];
|
||||||
|
BEZIERMIDDLE(Points2[2], Points[2], Points[3]);
|
||||||
|
BEZIERMIDDLE(Points2[0], Points[1], Points[2]);
|
||||||
|
BEZIERMIDDLE(Points2[1],Points2[0],Points2[2]);
|
||||||
|
|
||||||
|
BEZIERMIDDLE(Points[1], Points[0], Points[1]);
|
||||||
|
BEZIERMIDDLE(Points[2], Points[1], Points2[0]);
|
||||||
|
BEZIERMIDDLE(Points[3], Points[2], Points2[1]);
|
||||||
|
|
||||||
|
Points2[0]=Points[3];
|
||||||
|
|
||||||
|
/* do the two halves */
|
||||||
|
GDI_InternalBezier(Points, PtsOut, dwOut, nPtsOut, level-1);
|
||||||
|
GDI_InternalBezier(Points2, PtsOut, dwOut, nPtsOut, level-1);
|
||||||
}
|
}
|
||||||
(*PtsOut)[*nPtsOut].x = BEZIERSHIFTDOWN(Points[3].x);
|
|
||||||
(*PtsOut)[*nPtsOut].y = BEZIERSHIFTDOWN(Points[3].y);
|
|
||||||
(*nPtsOut) ++;
|
|
||||||
} else {
|
|
||||||
POINT Points2[4]; /* For the second recursive call */
|
|
||||||
Points2[3]=Points[3];
|
|
||||||
BEZIERMIDDLE(Points2[2], Points[2], Points[3]);
|
|
||||||
BEZIERMIDDLE(Points2[0], Points[1], Points[2]);
|
|
||||||
BEZIERMIDDLE(Points2[1],Points2[0],Points2[2]);
|
|
||||||
|
|
||||||
BEZIERMIDDLE(Points[1], Points[0], Points[1]);
|
|
||||||
BEZIERMIDDLE(Points[2], Points[1], Points2[0]);
|
|
||||||
BEZIERMIDDLE(Points[3], Points[2], Points2[1]);
|
|
||||||
|
|
||||||
Points2[0]=Points[3];
|
|
||||||
|
|
||||||
/* Do the two halves */
|
|
||||||
GDI_InternalBezier(Points, PtsOut, dwOut, nPtsOut, level-1);
|
|
||||||
GDI_InternalBezier(Points2, PtsOut, dwOut, nPtsOut, level-1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* GDI_Bezier [INTERNAL]
|
* GDI_Bezier [INTERNAL]
|
||||||
* Calculate line segments that approximate -what microsoft calls- a bezier
|
* Calculate line segments that approximate -what microsoft calls- a bezier
|
||||||
|
@ -191,38 +179,37 @@ static void APIENTRY GDI_InternalBezier( POINT *Points, POINT **PtsOut, INT *dwO
|
||||||
*
|
*
|
||||||
* RETURNS
|
* RETURNS
|
||||||
*
|
*
|
||||||
* Ptr to an array of POINTs that contain the lines that approximinate the
|
* Ptr to an array of POINTs that contain the lines that approximate the
|
||||||
* Beziers. The array is allocated on the process heap and it is the caller's
|
* Beziers. The array is allocated on the process heap and it is the caller's
|
||||||
* responsibility to HeapFree it. [this is not a particularly nice interface
|
* responsibility to HeapFree it. [this is not a particularly nice interface
|
||||||
* but since we can't know in advance how many points will generate, the
|
* but since we can't know in advance how many points we will generate, the
|
||||||
* alternative would be to call the function twice, once to determine the size
|
* alternative would be to call the function twice, once to determine the size
|
||||||
* and a second time to do the work - I decided this was too much of a pain].
|
* and a second time to do the work - I decided this was too much of a pain].
|
||||||
*/
|
*/
|
||||||
POINT * FASTCALL GDI_Bezier( const POINT *Points, INT count, INT *nPtsOut )
|
POINT *GDI_Bezier( const POINT *Points, INT count, INT *nPtsOut )
|
||||||
{
|
{
|
||||||
POINT *out;
|
POINT *out;
|
||||||
INT Bezier, dwOut = BEZIER_INITBUFSIZE, i;
|
INT Bezier, dwOut = BEZIER_INITBUFSIZE, i;
|
||||||
|
|
||||||
if((count - 1) % 3 != 0) {
|
if (count == 1 || (count - 1) % 3 != 0) {
|
||||||
return NULL;
|
DPRINT1("Invalid no. of points %d\n", count);
|
||||||
}
|
return NULL;
|
||||||
*nPtsOut = 0;
|
|
||||||
|
|
||||||
out = ExAllocatePoolWithTag(PagedPool, dwOut * sizeof(POINT), TAG_BEZIER);
|
|
||||||
if(!out) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(Bezier = 0; Bezier < (count-1)/3; Bezier++) {
|
|
||||||
POINT ptBuf[4];
|
|
||||||
memcpy(ptBuf, Points + Bezier * 3, sizeof(POINT) * 4);
|
|
||||||
for(i = 0; i < 4; i++) {
|
|
||||||
ptBuf[i].x = BEZIERSHIFTUP(ptBuf[i].x);
|
|
||||||
ptBuf[i].y = BEZIERSHIFTUP(ptBuf[i].y);
|
|
||||||
}
|
}
|
||||||
GDI_InternalBezier( ptBuf, &out, &dwOut, nPtsOut, BEZIERMAXDEPTH );
|
*nPtsOut = 0;
|
||||||
}
|
|
||||||
|
|
||||||
return out;
|
out = ExAllocatePoolWithTag(PagedPool, dwOut * sizeof(POINT), TAG_BEZIER);
|
||||||
|
if (!out) return NULL;
|
||||||
|
|
||||||
|
for(Bezier = 0; Bezier < (count-1)/3; Bezier++) {
|
||||||
|
POINT ptBuf[4];
|
||||||
|
memcpy(ptBuf, Points + Bezier * 3, sizeof(POINT) * 4);
|
||||||
|
for(i = 0; i < 4; i++) {
|
||||||
|
ptBuf[i].x = BEZIERSHIFTUP(ptBuf[i].x);
|
||||||
|
ptBuf[i].y = BEZIERSHIFTUP(ptBuf[i].y);
|
||||||
|
}
|
||||||
|
GDI_InternalBezier( ptBuf, &out, &dwOut, nPtsOut, BEZIERMAXDEPTH );
|
||||||
|
}
|
||||||
|
DPRINT("Produced %d points\n", *nPtsOut);
|
||||||
|
return out;
|
||||||
}
|
}
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -124,7 +124,7 @@ IntGetSystemPaletteEntries(HDC hDC,
|
||||||
VOID FASTCALL CreateStockObjects (VOID);
|
VOID FASTCALL CreateStockObjects (VOID);
|
||||||
VOID FASTCALL CreateSysColorObjects (VOID);
|
VOID FASTCALL CreateSysColorObjects (VOID);
|
||||||
|
|
||||||
PPOINT FASTCALL GDI_Bezier (const POINT *Points, INT count, PINT nPtsOut);
|
PPOINT GDI_Bezier (const POINT *Points, INT count, PINT nPtsOut);
|
||||||
|
|
||||||
BOOL FASTCALL IntFillArc( PDC dc, INT XLeft, INT YLeft, INT Width, INT Height, double StartArc, double EndArc, ARCTYPE arctype);
|
BOOL FASTCALL IntFillArc( PDC dc, INT XLeft, INT YLeft, INT Width, INT Height, double StartArc, double EndArc, ARCTYPE arctype);
|
||||||
BOOL FASTCALL IntDrawArc( PDC dc, INT XLeft, INT YLeft, INT Width, INT Height, double StartArc, double EndArc, ARCTYPE arctype, PBRUSH pbrush);
|
BOOL FASTCALL IntDrawArc( PDC dc, INT XLeft, INT YLeft, INT Width, INT Height, double StartArc, double EndArc, ARCTYPE arctype, PBRUSH pbrush);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue