WINE_DEFAULT_DEBUG_CHANNEL(gdi);
+/***********************************************************************
+ * null driver fallback implementations
+ */
+
+BOOL CDECL nulldrv_AngleArc( PHYSDEV dev, INT x, INT y, DWORD radius, FLOAT start, FLOAT sweep )
+{
+ INT x1 = GDI_ROUND( x + cos( start * M_PI / 180 ) * radius );
+ INT y1 = GDI_ROUND( y - sin( start * M_PI / 180 ) * radius );
+ INT x2 = GDI_ROUND( x + cos( (start + sweep) * M_PI / 180) * radius );
+ INT y2 = GDI_ROUND( y - sin( (start + sweep) * M_PI / 180) * radius );
+ INT arcdir = SetArcDirection( dev->hdc, sweep >= 0 ? AD_COUNTERCLOCKWISE : AD_CLOCKWISE );
+ BOOL ret = ArcTo( dev->hdc, x - radius, y - radius, x + radius, y + radius, x1, y1, x2, y2 );
+ SetArcDirection( dev->hdc, arcdir );
+ return ret;
+}
+
+BOOL CDECL nulldrv_ArcTo( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
+ INT xstart, INT ystart, INT xend, INT yend )
+{
+ INT width = abs( right - left );
+ INT height = abs( bottom - top );
+ double xradius = width / 2.0;
+ double yradius = height / 2.0;
+ double xcenter = right > left ? left + xradius : right + xradius;
+ double ycenter = bottom > top ? top + yradius : bottom + yradius;
+ double angle;
+
+ if (!height || !width) return FALSE;
+ /* draw a line from the current position to the starting point of the arc, then draw the arc */
+ angle = atan2( (ystart - ycenter) / height, (xstart - xcenter) / width );
+ LineTo( dev->hdc, GDI_ROUND( xcenter + cos(angle) * xradius ),
+ GDI_ROUND( ycenter + sin(angle) * yradius ));
+ return Arc( dev->hdc, left, top, right, bottom, xstart, ystart, xend, yend );
+}
+
+BOOL CDECL nulldrv_FillRgn( PHYSDEV dev, HRGN rgn, HBRUSH brush )
+{
+ BOOL ret = FALSE;
+ HBRUSH prev;
+
+ if ((prev = SelectObject( dev->hdc, brush )))
+ {
+ ret = PaintRgn( dev->hdc, rgn );
+ SelectObject( dev->hdc, prev );
+ }
+ return ret;
+}
+
+BOOL CDECL nulldrv_FrameRgn( PHYSDEV dev, HRGN rgn, HBRUSH brush, INT width, INT height )
+{
+ BOOL ret = FALSE;
+ HRGN tmp = CreateRectRgn( 0, 0, 0, 0 );
+
+ if (tmp)
+ {
+ if (REGION_FrameRgn( tmp, rgn, width, height )) ret = FillRgn( dev->hdc, tmp, brush );
+ DeleteObject( tmp );
+ }
+ return ret;
+}
+
+BOOL CDECL nulldrv_InvertRgn( PHYSDEV dev, HRGN rgn )
+{
+ HBRUSH prev_brush = SelectObject( dev->hdc, GetStockObject(BLACK_BRUSH) );
+ INT prev_rop = SetROP2( dev->hdc, R2_NOT );
+ BOOL ret = PaintRgn( dev->hdc, rgn );
+ SelectObject( dev->hdc, prev_brush );
+ SetROP2( dev->hdc, prev_rop );
+ return ret;
+}
+
+BOOL CDECL nulldrv_PolyBezier( PHYSDEV dev, const POINT *points, DWORD count )
+{
+ BOOL ret = FALSE;
+ POINT *pts;
+ INT n;
+
+ if ((pts = GDI_Bezier( points, count, &n )))
+ {
+ ret = Polyline( dev->hdc, pts, n );
+ HeapFree( GetProcessHeap(), 0, pts );
+ }
+ return ret;
+}
+
+BOOL CDECL nulldrv_PolyBezierTo( PHYSDEV dev, const POINT *points, DWORD count )
+{
+ BOOL ret = FALSE;
+ POINT *pts = HeapAlloc( GetProcessHeap(), 0, sizeof(POINT) * (count + 1) );
+
+ if (pts)
+ {
+ GetCurrentPositionEx( dev->hdc, &pts[0] );
+ memcpy( pts + 1, points, sizeof(POINT) * count );
+ ret = PolyBezier( dev->hdc, pts, count + 1 );
+ HeapFree( GetProcessHeap(), 0, pts );
+ }
+ return ret;
+}
+
+BOOL CDECL nulldrv_PolyDraw( PHYSDEV dev, const POINT *points, const BYTE *types, DWORD count )
+{
+ POINT *line_pts = NULL, *bzr_pts = NULL, bzr[4];
+ INT i, num_pts, num_bzr_pts, space, size;
+
+ /* check for valid point types */
+ for (i = 0; i < count; i++)
+ {
+ switch (types[i])
+ {
+ case PT_MOVETO:
+ case PT_LINETO | PT_CLOSEFIGURE:
+ case PT_LINETO:
+ break;
+ case PT_BEZIERTO:
+ if((i + 2 < count) && (types[i + 1] == PT_BEZIERTO) &&
+ ((types[i + 2] & ~PT_CLOSEFIGURE) == PT_BEZIERTO))
+ {
+ i += 2;
+ break;
+ }
+ default:
+ return FALSE;
+ }
+ }
+
+ space = count + 300;
+ line_pts = HeapAlloc( GetProcessHeap(), 0, space * sizeof(POINT) );
+ num_pts = 1;
+
+ GetCurrentPositionEx( dev->hdc, &line_pts[0] );
+ for (i = 0; i < count; i++)
+ {
+ switch (types[i])
+ {
+ case PT_MOVETO:
+ if (num_pts >= 2) Polyline( dev->hdc, line_pts, num_pts );
+ num_pts = 0;
+ line_pts[num_pts++] = points[i];
+ break;
+ case PT_LINETO:
+ case (PT_LINETO | PT_CLOSEFIGURE):
+ line_pts[num_pts++] = points[i];
+ break;
+ case PT_BEZIERTO:
+ bzr[0].x = line_pts[num_pts - 1].x;
+ bzr[0].y = line_pts[num_pts - 1].y;
+ memcpy( &bzr[1], &points[i], 3 * sizeof(POINT) );
+
+ if ((bzr_pts = GDI_Bezier( bzr, 4, &num_bzr_pts )))
+ {
+ size = num_pts + (count - i) + num_bzr_pts;
+ if (space < size)
+ {
+ space = size * 2;
+ line_pts = HeapReAlloc( GetProcessHeap(), 0, line_pts, space * sizeof(POINT) );
+ }
+ memcpy( &line_pts[num_pts], &bzr_pts[1], (num_bzr_pts - 1) * sizeof(POINT) );
+ num_pts += num_bzr_pts - 1;
+ HeapFree( GetProcessHeap(), 0, bzr_pts );
+ }
+ i += 2;
+ break;
+ }
+ if (types[i] & PT_CLOSEFIGURE) line_pts[num_pts++] = line_pts[0];
+ }
+
+ if (num_pts >= 2) Polyline( dev->hdc, line_pts, num_pts );
+ MoveToEx( dev->hdc, line_pts[num_pts - 1].x, line_pts[num_pts - 1].y, NULL );
+ HeapFree( GetProcessHeap(), 0, line_pts );
+ return TRUE;
+}
+
+BOOL CDECL nulldrv_PolylineTo( PHYSDEV dev, const POINT *points, INT count )
+{
+ BOOL ret = FALSE;
+ POINT *pts;
+
+ if (!count) return FALSE;
+ if ((pts = HeapAlloc( GetProcessHeap(), 0, sizeof(POINT) * (count + 1) )))
+ {
+ GetCurrentPositionEx( dev->hdc, &pts[0] );
+ memcpy( pts + 1, points, sizeof(POINT) * count );
+ ret = Polyline( dev->hdc, pts, count + 1 );
+ HeapFree( GetProcessHeap(), 0, pts );
+ }
+ return ret;
+}
+
/***********************************************************************
* LineTo (GDI32.@)
*/
BOOL WINAPI LineTo( HDC hdc, INT x, INT y )
{
- DC * dc = DC_GetDCUpdate( hdc );
+ DC * dc = get_dc_ptr( hdc );
BOOL ret;
if(!dc) return FALSE;
+ update_dc( dc );
if(PATH_IsPathOpen(dc->path))
ret = PATH_LineTo(dc, x, y);
else
- ret = dc->funcs->pLineTo && dc->funcs->pLineTo(dc->physDev,x,y);
+ {
+ PHYSDEV physdev = GET_DC_PHYSDEV( dc, pLineTo );
+ ret = physdev->funcs->pLineTo( physdev, x, y );
+ }
if(ret) {
dc->CursPosX = x;
dc->CursPosY = y;
}
- GDI_ReleaseObj( hdc );
+ release_dc_ptr( dc );
return ret;
}
BOOL WINAPI MoveToEx( HDC hdc, INT x, INT y, LPPOINT pt )
{
BOOL ret = TRUE;
- DC * dc = DC_GetDCPtr( hdc );
+ DC * dc = get_dc_ptr( hdc );
if(!dc) return FALSE;
dc->CursPosY = y;
if(PATH_IsPathOpen(dc->path)) ret = PATH_MoveTo(dc);
- else if (dc->funcs->pMoveTo) ret = dc->funcs->pMoveTo(dc->physDev,x,y);
- GDI_ReleaseObj( hdc );
+ else
+ {
+ PHYSDEV physdev = GET_DC_PHYSDEV( dc, pMoveTo );
+ ret = physdev->funcs->pMoveTo( physdev, x, y );
+ }
+ release_dc_ptr( dc );
return ret;
}
INT xend, INT yend )
{
BOOL ret = FALSE;
- DC * dc = DC_GetDCUpdate( hdc );
+ DC * dc = get_dc_ptr( hdc );
+
if (dc)
{
- if(PATH_IsPathOpen(dc->path))
+ update_dc( dc );
+ if(PATH_IsPathOpen(dc->path))
ret = PATH_Arc(dc, left, top, right, bottom, xstart, ystart, xend, yend,0);
- else if (dc->funcs->pArc)
- ret = dc->funcs->pArc(dc->physDev,left,top,right,bottom,xstart,ystart,xend,yend);
- GDI_ReleaseObj( hdc );
+ else
+ {
+ PHYSDEV physdev = GET_DC_PHYSDEV( dc, pArc );
+ ret = physdev->funcs->pArc( physdev, left, top, right, bottom, xstart, ystart, xend, yend );
+ }
+ release_dc_ptr( dc );
}
return ret;
}
ycenter = bottom > top ? top+yradius : bottom+yradius,
angle;
BOOL result;
- DC * dc = DC_GetDCUpdate( hdc );
+ DC * dc = get_dc_ptr( hdc );
if(!dc) return FALSE;
+ update_dc( dc );
if(PATH_IsPathOpen(dc->path))
result = PATH_Arc(dc,left,top,right,bottom,xstart,ystart,xend,yend,-1);
- else if(dc->funcs->pArcTo)
- result = dc->funcs->pArcTo( dc->physDev, left, top, right, bottom,
- xstart, ystart, xend, yend );
- else /* We'll draw a line from the current position to the starting point of the arc, then draw the arc */
+ else
{
- angle = atan2(((ystart-ycenter)/height),
- ((xstart-xcenter)/width));
- LineTo(hdc, GDI_ROUND(xcenter+(cos(angle)*xradius)),
- GDI_ROUND(ycenter+(sin(angle)*yradius)));
- result = Arc(hdc, left, top, right, bottom, xstart, ystart, xend, yend);
+ PHYSDEV physdev = GET_DC_PHYSDEV( dc, pArcTo );
+ result = physdev->funcs->pArcTo( physdev, left, top, right, bottom, xstart, ystart, xend, yend );
}
if (result) {
angle = atan2(((yend-ycenter)/height),
dc->CursPosX = GDI_ROUND(xcenter+(cos(angle)*xradius));
dc->CursPosY = GDI_ROUND(ycenter+(sin(angle)*yradius));
}
- GDI_ReleaseObj( hdc );
+ release_dc_ptr( dc );
return result;
}
INT xend, INT yend )
{
BOOL ret = FALSE;
- DC * dc = DC_GetDCUpdate( hdc );
+ DC * dc = get_dc_ptr( hdc );
if (!dc) return FALSE;
+ update_dc( dc );
if(PATH_IsPathOpen(dc->path))
ret = PATH_Arc(dc,left,top,right,bottom,xstart,ystart,xend,yend,2);
- else if(dc->funcs->pPie)
- ret = dc->funcs->pPie(dc->physDev,left,top,right,bottom,xstart,ystart,xend,yend);
-
- GDI_ReleaseObj( hdc );
+ else
+ {
+ PHYSDEV physdev = GET_DC_PHYSDEV( dc, pPie );
+ ret = physdev->funcs->pPie( physdev, left, top, right, bottom, xstart, ystart, xend, yend );
+ }
+ release_dc_ptr( dc );
return ret;
}
INT xend, INT yend )
{
BOOL ret = FALSE;
- DC * dc = DC_GetDCUpdate( hdc );
+ DC * dc = get_dc_ptr( hdc );
if (!dc) return FALSE;
+ update_dc( dc );
if(PATH_IsPathOpen(dc->path))
ret = PATH_Arc(dc,left,top,right,bottom,xstart,ystart,xend,yend,1);
- else if(dc->funcs->pChord)
- ret = dc->funcs->pChord(dc->physDev,left,top,right,bottom,xstart,ystart,xend,yend);
-
- GDI_ReleaseObj( hdc );
+ else
+ {
+ PHYSDEV physdev = GET_DC_PHYSDEV( dc, pChord );
+ ret = physdev->funcs->pChord( physdev, left, top, right, bottom, xstart, ystart, xend, yend );
+ }
+ release_dc_ptr( dc );
return ret;
}
INT right, INT bottom )
{
BOOL ret = FALSE;
- DC * dc = DC_GetDCUpdate( hdc );
+ DC * dc = get_dc_ptr( hdc );
if (!dc) return FALSE;
+ update_dc( dc );
if(PATH_IsPathOpen(dc->path))
ret = PATH_Ellipse(dc,left,top,right,bottom);
- else if (dc->funcs->pEllipse)
- ret = dc->funcs->pEllipse(dc->physDev,left,top,right,bottom);
+ else
+ {
+ PHYSDEV physdev = GET_DC_PHYSDEV( dc, pEllipse );
+ ret = physdev->funcs->pEllipse( physdev, left, top, right, bottom );
+ }
- GDI_ReleaseObj( hdc );
+ release_dc_ptr( dc );
return ret;
}
INT right, INT bottom )
{
BOOL ret = FALSE;
- DC * dc = DC_GetDCUpdate( hdc );
+ DC * dc = get_dc_ptr( hdc );
+
if (dc)
{
- if(PATH_IsPathOpen(dc->path))
+ update_dc( dc );
+ if(PATH_IsPathOpen(dc->path))
ret = PATH_Rectangle(dc, left, top, right, bottom);
- else if (dc->funcs->pRectangle)
- ret = dc->funcs->pRectangle(dc->physDev,left,top,right,bottom);
- GDI_ReleaseObj( hdc );
+ else
+ {
+ PHYSDEV physdev = GET_DC_PHYSDEV( dc, pRectangle );
+ ret = physdev->funcs->pRectangle( physdev, left, top, right, bottom );
+ }
+ release_dc_ptr( dc );
}
return ret;
}
INT bottom, INT ell_width, INT ell_height )
{
BOOL ret = FALSE;
- DC *dc = DC_GetDCUpdate( hdc );
+ DC *dc = get_dc_ptr( hdc );
if (dc)
{
+ update_dc( dc );
if(PATH_IsPathOpen(dc->path))
ret = PATH_RoundRect(dc,left,top,right,bottom,ell_width,ell_height);
- else if (dc->funcs->pRoundRect)
- ret = dc->funcs->pRoundRect(dc->physDev,left,top,right,bottom,ell_width,ell_height);
- GDI_ReleaseObj( hdc );
+ else
+ {
+ PHYSDEV physdev = GET_DC_PHYSDEV( dc, pRoundRect );
+ ret = physdev->funcs->pRoundRect( physdev, left, top, right, bottom, ell_width, ell_height );
+ }
+ release_dc_ptr( dc );
}
return ret;
}
COLORREF WINAPI SetPixel( HDC hdc, INT x, INT y, COLORREF color )
{
COLORREF ret = 0;
- DC * dc = DC_GetDCUpdate( hdc );
+ DC * dc = get_dc_ptr( hdc );
+
if (dc)
{
- if (dc->funcs->pSetPixel) ret = dc->funcs->pSetPixel(dc->physDev,x,y,color);
- GDI_ReleaseObj( hdc );
+ PHYSDEV physdev = GET_DC_PHYSDEV( dc, pSetPixel );
+ update_dc( dc );
+ ret = physdev->funcs->pSetPixel( physdev, x, y, color );
+ release_dc_ptr( dc );
}
return ret;
}
BOOL WINAPI SetPixelV( HDC hdc, INT x, INT y, COLORREF color )
{
BOOL ret = FALSE;
- DC * dc = DC_GetDCUpdate( hdc );
+ DC * dc = get_dc_ptr( hdc );
+
if (dc)
{
- if (dc->funcs->pSetPixel)
- {
- dc->funcs->pSetPixel(dc->physDev,x,y,color);
- ret = TRUE;
- }
- GDI_ReleaseObj( hdc );
+ PHYSDEV physdev = GET_DC_PHYSDEV( dc, pSetPixel );
+ update_dc( dc );
+ physdev->funcs->pSetPixel( physdev, x, y, color );
+ ret = TRUE;
+ release_dc_ptr( dc );
}
return ret;
}
COLORREF WINAPI GetPixel( HDC hdc, INT x, INT y )
{
COLORREF ret = CLR_INVALID;
- DC * dc = DC_GetDCUpdate( hdc );
+ DC * dc = get_dc_ptr( hdc );
if (dc)
{
- /* FIXME: should this be in the graphics driver? */
+ update_dc( dc );
+ /* FIXME: should this be in the graphics driver? */
if (PtVisible( hdc, x, y ))
{
- if (dc->funcs->pGetPixel) ret = dc->funcs->pGetPixel(dc->physDev,x,y);
+ PHYSDEV physdev = GET_DC_PHYSDEV( dc, pGetPixel );
+ ret = physdev->funcs->pGetPixel( physdev, x, y );
}
- GDI_ReleaseObj( hdc );
+ release_dc_ptr( dc );
}
return ret;
}
INT WINAPI ChoosePixelFormat( HDC hdc, const PIXELFORMATDESCRIPTOR* ppfd )
{
INT ret = 0;
- DC * dc = DC_GetDCPtr( hdc );
+ DC * dc = get_dc_ptr( hdc );
TRACE("(%p,%p)\n",hdc,ppfd);
- if (!dc) return 0;
-
- if (!dc->funcs->pChoosePixelFormat) FIXME(" :stub\n");
- else ret = dc->funcs->pChoosePixelFormat(dc->physDev,ppfd);
-
- GDI_ReleaseObj( hdc );
+ if (dc)
+ {
+ PHYSDEV physdev = GET_DC_PHYSDEV( dc, pChoosePixelFormat );
+ ret = physdev->funcs->pChoosePixelFormat( physdev, ppfd );
+ release_dc_ptr( dc );
+ }
return ret;
}
const PIXELFORMATDESCRIPTOR *ppfd)
{
INT bRet = FALSE;
- DC * dc = DC_GetDCPtr( hdc );
+ DC * dc = get_dc_ptr( hdc );
TRACE("(%p,%d,%p)\n",hdc,iPixelFormat,ppfd);
- if (!dc) return 0;
-
- if (!dc->funcs->pSetPixelFormat) FIXME(" :stub\n");
- else bRet = dc->funcs->pSetPixelFormat(dc->physDev,iPixelFormat,ppfd);
-
- GDI_ReleaseObj( hdc );
+ if (dc)
+ {
+ PHYSDEV physdev = GET_DC_PHYSDEV( dc, pSetPixelFormat );
+ update_dc( dc );
+ bRet = physdev->funcs->pSetPixelFormat( physdev, iPixelFormat, ppfd );
+ release_dc_ptr( dc );
+ }
return bRet;
}
INT WINAPI GetPixelFormat( HDC hdc )
{
INT ret = 0;
- DC * dc = DC_GetDCPtr( hdc );
+ DC * dc = get_dc_ptr( hdc );
TRACE("(%p)\n",hdc);
- if (!dc) return 0;
-
- if (!dc->funcs->pGetPixelFormat) FIXME(" :stub\n");
- else ret = dc->funcs->pGetPixelFormat(dc->physDev);
-
- GDI_ReleaseObj( hdc );
+ if (dc)
+ {
+ PHYSDEV physdev = GET_DC_PHYSDEV( dc, pGetPixelFormat );
+ update_dc( dc );
+ ret = physdev->funcs->pGetPixelFormat( physdev );
+ release_dc_ptr( dc );
+ }
return ret;
}
LPPIXELFORMATDESCRIPTOR ppfd )
{
INT ret = 0;
- DC * dc = DC_GetDCPtr( hdc );
+ DC * dc = get_dc_ptr( hdc );
TRACE("(%p,%d,%d,%p): stub\n",hdc,iPixelFormat,nBytes,ppfd);
- if (!dc) return 0;
-
- if (!dc->funcs->pDescribePixelFormat)
+ if (dc)
{
- FIXME(" :stub\n");
- ppfd->nSize = nBytes;
- ppfd->nVersion = 1;
- ret = 3;
+ PHYSDEV physdev = GET_DC_PHYSDEV( dc, pDescribePixelFormat );
+ update_dc( dc );
+ ret = physdev->funcs->pDescribePixelFormat( physdev, iPixelFormat, nBytes, ppfd );
+ release_dc_ptr( dc );
}
- else ret = dc->funcs->pDescribePixelFormat(dc->physDev,iPixelFormat,nBytes,ppfd);
-
- GDI_ReleaseObj( hdc );
return ret;
}
BOOL WINAPI SwapBuffers( HDC hdc )
{
INT bRet = FALSE;
- DC * dc = DC_GetDCPtr( hdc );
+ DC * dc = get_dc_ptr( hdc );
TRACE("(%p)\n",hdc);
- if (!dc) return TRUE;
-
- if (!dc->funcs->pSwapBuffers)
+ if (dc)
{
- FIXME(" :stub\n");
- bRet = TRUE;
+ PHYSDEV physdev = GET_DC_PHYSDEV( dc, pSwapBuffers );
+ update_dc( dc );
+ bRet = physdev->funcs->pSwapBuffers( physdev );
+ release_dc_ptr( dc );
}
- else bRet = dc->funcs->pSwapBuffers(dc->physDev);
-
- GDI_ReleaseObj( hdc );
return bRet;
}
BOOL WINAPI PaintRgn( HDC hdc, HRGN hrgn )
{
BOOL ret = FALSE;
- DC * dc = DC_GetDCUpdate( hdc );
+ DC * dc = get_dc_ptr( hdc );
+
if (dc)
{
- if (dc->funcs->pPaintRgn) ret = dc->funcs->pPaintRgn(dc->physDev,hrgn);
- GDI_ReleaseObj( hdc );
+ PHYSDEV physdev = GET_DC_PHYSDEV( dc, pPaintRgn );
+ update_dc( dc );
+ ret = physdev->funcs->pPaintRgn( physdev, hrgn );
+ release_dc_ptr( dc );
}
return ret;
}
BOOL WINAPI FillRgn( HDC hdc, HRGN hrgn, HBRUSH hbrush )
{
BOOL retval = FALSE;
- HBRUSH prevBrush;
- DC * dc = DC_GetDCUpdate( hdc );
+ DC * dc = get_dc_ptr( hdc );
- if (!dc) return FALSE;
- if(dc->funcs->pFillRgn)
- retval = dc->funcs->pFillRgn(dc->physDev, hrgn, hbrush);
- else if ((prevBrush = SelectObject( hdc, hbrush )))
+ if (dc)
{
- retval = PaintRgn( hdc, hrgn );
- SelectObject( hdc, prevBrush );
+ PHYSDEV physdev = GET_DC_PHYSDEV( dc, pFillRgn );
+ update_dc( dc );
+ retval = physdev->funcs->pFillRgn( physdev, hrgn, hbrush );
+ release_dc_ptr( dc );
}
- GDI_ReleaseObj( hdc );
return retval;
}
INT nWidth, INT nHeight )
{
BOOL ret = FALSE;
- DC *dc = DC_GetDCUpdate( hdc );
+ DC *dc = get_dc_ptr( hdc );
- if (!dc) return FALSE;
- if(dc->funcs->pFrameRgn)
- ret = dc->funcs->pFrameRgn( dc->physDev, hrgn, hbrush, nWidth, nHeight );
- else
+ if (dc)
{
- HRGN tmp = CreateRectRgn( 0, 0, 0, 0 );
- if (tmp)
- {
- if (REGION_FrameRgn( tmp, hrgn, nWidth, nHeight ))
- {
- FillRgn( hdc, tmp, hbrush );
- ret = TRUE;
- }
- DeleteObject( tmp );
- }
+ PHYSDEV physdev = GET_DC_PHYSDEV( dc, pFrameRgn );
+ update_dc( dc );
+ ret = physdev->funcs->pFrameRgn( physdev, hrgn, hbrush, nWidth, nHeight );
+ release_dc_ptr( dc );
}
- GDI_ReleaseObj( hdc );
return ret;
}
*/
BOOL WINAPI InvertRgn( HDC hdc, HRGN hrgn )
{
- HBRUSH prevBrush;
- INT prevROP;
- BOOL retval;
- DC *dc = DC_GetDCUpdate( hdc );
- if (!dc) return FALSE;
+ BOOL ret = FALSE;
+ DC *dc = get_dc_ptr( hdc );
- if(dc->funcs->pInvertRgn)
- retval = dc->funcs->pInvertRgn( dc->physDev, hrgn );
- else
+ if (dc)
{
- prevBrush = SelectObject( hdc, GetStockObject(BLACK_BRUSH) );
- prevROP = SetROP2( hdc, R2_NOT );
- retval = PaintRgn( hdc, hrgn );
- SelectObject( hdc, prevBrush );
- SetROP2( hdc, prevROP );
+ PHYSDEV physdev = GET_DC_PHYSDEV( dc, pInvertRgn );
+ update_dc( dc );
+ ret = physdev->funcs->pInvertRgn( physdev, hrgn );
+ release_dc_ptr( dc );
}
- GDI_ReleaseObj( hdc );
- return retval;
+ return ret;
}
BOOL WINAPI Polyline( HDC hdc, const POINT* pt, INT count )
{
BOOL ret = FALSE;
- DC * dc = DC_GetDCUpdate( hdc );
+ DC * dc = get_dc_ptr( hdc );
+
if (dc)
{
+ update_dc( dc );
if (PATH_IsPathOpen(dc->path)) ret = PATH_Polyline(dc, pt, count);
- else if (dc->funcs->pPolyline) ret = dc->funcs->pPolyline(dc->physDev,pt,count);
- GDI_ReleaseObj( hdc );
+ else
+ {
+ PHYSDEV physdev = GET_DC_PHYSDEV( dc, pPolyline );
+ ret = physdev->funcs->pPolyline( physdev, pt, count );
+ }
+ release_dc_ptr( dc );
}
return ret;
}
*/
BOOL WINAPI PolylineTo( HDC hdc, const POINT* pt, DWORD cCount )
{
- DC * dc = DC_GetDCUpdate( hdc );
+ DC * dc = get_dc_ptr( hdc );
BOOL ret = FALSE;
if(!dc) return FALSE;
- if(PATH_IsPathOpen(dc->path))
- ret = PATH_PolylineTo(dc, pt, cCount);
-
- else if(dc->funcs->pPolylineTo)
- ret = dc->funcs->pPolylineTo(dc->physDev, pt, cCount);
-
- else { /* do it using Polyline */
- POINT *pts = HeapAlloc( GetProcessHeap(), 0,
- sizeof(POINT) * (cCount + 1) );
- if (pts)
- {
- pts[0].x = dc->CursPosX;
- pts[0].y = dc->CursPosY;
- memcpy( pts + 1, pt, sizeof(POINT) * cCount );
- ret = Polyline( hdc, pts, cCount + 1 );
- HeapFree( GetProcessHeap(), 0, pts );
- }
+ update_dc( dc );
+ if(PATH_IsPathOpen(dc->path)) ret = PATH_PolylineTo(dc, pt, cCount);
+ else
+ {
+ PHYSDEV physdev = GET_DC_PHYSDEV( dc, pPolylineTo );
+ ret = physdev->funcs->pPolylineTo( physdev, pt, cCount );
}
- if(ret) {
+ if (ret && cCount)
+ {
dc->CursPosX = pt[cCount-1].x;
dc->CursPosY = pt[cCount-1].y;
}
- GDI_ReleaseObj( hdc );
+ release_dc_ptr( dc );
return ret;
}
BOOL WINAPI Polygon( HDC hdc, const POINT* pt, INT count )
{
BOOL ret = FALSE;
- DC * dc = DC_GetDCUpdate( hdc );
+ DC * dc = get_dc_ptr( hdc );
+
if (dc)
{
+ update_dc( dc );
if (PATH_IsPathOpen(dc->path)) ret = PATH_Polygon(dc, pt, count);
- else if (dc->funcs->pPolygon) ret = dc->funcs->pPolygon(dc->physDev,pt,count);
- GDI_ReleaseObj( hdc );
+ else
+ {
+ PHYSDEV physdev = GET_DC_PHYSDEV( dc, pPolygon );
+ ret = physdev->funcs->pPolygon( physdev, pt, count );
+ }
+ release_dc_ptr( dc );
}
return ret;
}
UINT polygons )
{
BOOL ret = FALSE;
- DC * dc = DC_GetDCUpdate( hdc );
+ DC * dc = get_dc_ptr( hdc );
+
if (dc)
{
+ update_dc( dc );
if (PATH_IsPathOpen(dc->path)) ret = PATH_PolyPolygon(dc, pt, counts, polygons);
- else if (dc->funcs->pPolyPolygon) ret = dc->funcs->pPolyPolygon(dc->physDev,pt,counts,polygons);
- GDI_ReleaseObj( hdc );
+ else
+ {
+ PHYSDEV physdev = GET_DC_PHYSDEV( dc, pPolyPolygon );
+ ret = physdev->funcs->pPolyPolygon( physdev, pt, counts, polygons );
+ }
+ release_dc_ptr( dc );
}
return ret;
}
DWORD polylines )
{
BOOL ret = FALSE;
- DC * dc = DC_GetDCUpdate( hdc );
+ DC * dc = get_dc_ptr( hdc );
+
if (dc)
{
+ update_dc( dc );
if (PATH_IsPathOpen(dc->path)) ret = PATH_PolyPolyline(dc, pt, counts, polylines);
- else if (dc->funcs->pPolyPolyline) ret = dc->funcs->pPolyPolyline(dc->physDev,pt,counts,polylines);
- GDI_ReleaseObj( hdc );
+ else
+ {
+ PHYSDEV physdev = GET_DC_PHYSDEV( dc, pPolyPolyline );
+ ret = physdev->funcs->pPolyPolyline( physdev, pt, counts, polylines );
+ }
+ release_dc_ptr( dc );
}
return ret;
}
UINT fillType )
{
BOOL ret = FALSE;
- DC * dc = DC_GetDCUpdate( hdc );
+ DC * dc = get_dc_ptr( hdc );
+
if (dc)
{
- if (dc->funcs->pExtFloodFill) ret = dc->funcs->pExtFloodFill(dc->physDev,x,y,color,fillType);
- GDI_ReleaseObj( hdc );
+ PHYSDEV physdev = GET_DC_PHYSDEV( dc, pExtFloodFill );
+
+ update_dc( dc );
+ ret = physdev->funcs->pExtFloodFill( physdev, x, y, color, fillType );
+ release_dc_ptr( dc );
}
return ret;
}
/* cPoints must be 3 * n + 1 (where n>=1) */
if (cPoints == 1 || (cPoints % 3) != 1) return FALSE;
- dc = DC_GetDCUpdate( hdc );
+ dc = get_dc_ptr( hdc );
if(!dc) return FALSE;
- if(PATH_IsPathOpen(dc->path))
- ret = PATH_PolyBezier(dc, lppt, cPoints);
- else if (dc->funcs->pPolyBezier)
- ret = dc->funcs->pPolyBezier(dc->physDev, lppt, cPoints);
- else /* We'll convert it into line segments and draw them using Polyline */
+ update_dc( dc );
+ if(PATH_IsPathOpen(dc->path)) ret = PATH_PolyBezier(dc, lppt, cPoints);
+ else
{
- POINT *Pts;
- INT nOut;
-
- if ((Pts = GDI_Bezier( lppt, cPoints, &nOut )))
- {
- TRACE("Pts = %p, no = %d\n", Pts, nOut);
- ret = Polyline( dc->hSelf, Pts, nOut );
- HeapFree( GetProcessHeap(), 0, Pts );
- }
+ PHYSDEV physdev = GET_DC_PHYSDEV( dc, pPolyBezier );
+ ret = physdev->funcs->pPolyBezier( physdev, lppt, cPoints );
}
-
- GDI_ReleaseObj( hdc );
+ release_dc_ptr( dc );
return ret;
}
BOOL WINAPI PolyBezierTo( HDC hdc, const POINT* lppt, DWORD cPoints )
{
DC * dc;
- BOOL ret;
+ BOOL ret = FALSE;
/* cbPoints must be 3 * n (where n>=1) */
if (!cPoints || (cPoints % 3) != 0) return FALSE;
- dc = DC_GetDCUpdate( hdc );
+ dc = get_dc_ptr( hdc );
if(!dc) return FALSE;
- if(PATH_IsPathOpen(dc->path))
- ret = PATH_PolyBezierTo(dc, lppt, cPoints);
- else if(dc->funcs->pPolyBezierTo)
- ret = dc->funcs->pPolyBezierTo(dc->physDev, lppt, cPoints);
- else { /* We'll do it using PolyBezier */
- POINT *pt;
- pt = HeapAlloc( GetProcessHeap(), 0, sizeof(POINT) * (cPoints + 1) );
- if(!pt) return FALSE;
- pt[0].x = dc->CursPosX;
- pt[0].y = dc->CursPosY;
- memcpy(pt + 1, lppt, sizeof(POINT) * cPoints);
- ret = PolyBezier(dc->hSelf, pt, cPoints+1);
- HeapFree( GetProcessHeap(), 0, pt );
+ update_dc( dc );
+ if(PATH_IsPathOpen(dc->path)) ret = PATH_PolyBezierTo(dc, lppt, cPoints);
+ else
+ {
+ PHYSDEV physdev = GET_DC_PHYSDEV( dc, pPolyBezierTo );
+ ret = physdev->funcs->pPolyBezierTo( physdev, lppt, cPoints );
}
if(ret) {
dc->CursPosX = lppt[cPoints-1].x;
dc->CursPosY = lppt[cPoints-1].y;
}
- GDI_ReleaseObj( hdc );
+ release_dc_ptr( dc );
return ret;
}
if( (signed int)dwRadius < 0 )
return FALSE;
- dc = DC_GetDCUpdate( hdc );
+ dc = get_dc_ptr( hdc );
if(!dc) return FALSE;
/* Calculate the end point */
- x2 = x + cos((eStartAngle+eSweepAngle)*M_PI/180) * dwRadius;
- y2 = y - sin((eStartAngle+eSweepAngle)*M_PI/180) * dwRadius;
+ x2 = GDI_ROUND( x + cos((eStartAngle+eSweepAngle)*M_PI/180) * dwRadius );
+ y2 = GDI_ROUND( y - sin((eStartAngle+eSweepAngle)*M_PI/180) * dwRadius );
- if(!PATH_IsPathOpen(dc->path) && dc->funcs->pAngleArc)
- result = dc->funcs->pAngleArc( dc->physDev, x, y, dwRadius, eStartAngle, eSweepAngle );
+ update_dc( dc );
+ if(!PATH_IsPathOpen(dc->path))
+ {
+ PHYSDEV physdev = GET_DC_PHYSDEV( dc, pAngleArc );
+ result = physdev->funcs->pAngleArc( physdev, x, y, dwRadius, eStartAngle, eSweepAngle );
+ }
else { /* do it using ArcTo */
- x1 = x + cos(eStartAngle*M_PI/180) * dwRadius;
- y1 = y - sin(eStartAngle*M_PI/180) * dwRadius;
+ x1 = GDI_ROUND( x + cos(eStartAngle*M_PI/180) * dwRadius );
+ y1 = GDI_ROUND( y - sin(eStartAngle*M_PI/180) * dwRadius );
arcdir = SetArcDirection( hdc, eSweepAngle >= 0 ? AD_COUNTERCLOCKWISE : AD_CLOCKWISE);
result = ArcTo( hdc, x-dwRadius, y-dwRadius, x+dwRadius, y+dwRadius,
dc->CursPosX = x2;
dc->CursPosY = y2;
}
- GDI_ReleaseObj( hdc );
+ release_dc_ptr( dc );
return result;
}
BOOL WINAPI PolyDraw(HDC hdc, const POINT *lppt, const BYTE *lpbTypes,
DWORD cCount)
{
- DC *dc;
- BOOL result;
- POINT lastmove;
- unsigned int i;
+ DC *dc = get_dc_ptr( hdc );
+ BOOL result = FALSE;
- dc = DC_GetDCUpdate( hdc );
if(!dc) return FALSE;
- if(dc->funcs->pPolyDraw)
- {
- result = dc->funcs->pPolyDraw( dc->physDev, lppt, lpbTypes, cCount );
- goto end;
- }
-
- /* check for each bezierto if there are two more points */
- for( i = 0; i < cCount; i++ )
- if( lpbTypes[i] != PT_MOVETO &&
- lpbTypes[i] & PT_BEZIERTO )
- {
- if( cCount < i+3 ){
- result = FALSE;
- goto end;
- }
- else
- i += 2;
- }
-
- /* if no moveto occurs, we will close the figure here */
- lastmove.x = dc->CursPosX;
- lastmove.y = dc->CursPosY;
-
- /* now let's draw */
- for( i = 0; i < cCount; i++ )
+ update_dc( dc );
+ if( PATH_IsPathOpen( dc->path ) ) result = PATH_PolyDraw(dc, lppt, lpbTypes, cCount);
+ else
{
- if( lpbTypes[i] == PT_MOVETO )
- {
- MoveToEx( hdc, lppt[i].x, lppt[i].y, NULL );
- lastmove.x = dc->CursPosX;
- lastmove.y = dc->CursPosY;
- }
- else if( lpbTypes[i] & PT_LINETO )
- LineTo( hdc, lppt[i].x, lppt[i].y );
- else if( lpbTypes[i] & PT_BEZIERTO )
- {
- PolyBezierTo( hdc, &lppt[i], 3 );
- i += 2;
- }
- else{
- result = FALSE;
- goto end;
- }
-
- if( lpbTypes[i] & PT_CLOSEFIGURE )
- {
- if( PATH_IsPathOpen( dc->path ) )
- CloseFigure( hdc );
- else
- LineTo( hdc, lastmove.x, lastmove.y );
- }
+ PHYSDEV physdev = GET_DC_PHYSDEV( dc, pPolyDraw );
+ result = physdev->funcs->pPolyDraw( physdev, lppt, lpbTypes, cCount );
}
-
- result = TRUE;
-end:
- GDI_ReleaseObj( hdc );
+ release_dc_ptr( dc );
return result;
}
if (dx > dy) /* line is "more horizontal" */
{
err = 2*dy - dx; erradd = 2*dy - 2*dx;
- for(cnt = 0;cnt <= dx; cnt++)
+ for(cnt = 0;cnt < dx; cnt++)
{
callback(nXStart,nYStart,lParam);
if (err > 0)
else /* line is "more vertical" */
{
err = 2*dx - dy; erradd = 2*dx - 2*dy;
- for(cnt = 0;cnt <= dy; cnt++)
+ for(cnt = 0;cnt < dy; cnt++)
{
callback(nXStart,nYStart,lParam);
if (err > 0)
* *Very* simple bezier drawing code,
*
* 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
* algorithm.
*
* Points[0] and Points[3] are begin and endpoint
* Points[1] and Points[2] are control points
* level is the recursion depth
-* returns true if the recusion can be terminated
+* returns true if the recursion can be terminated
*/
static BOOL BezierCheck( int level, POINT *Points)
{
*
* 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
* 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
* and a second time to do the work - I decided this was too much of a pain].
*/
{
unsigned int i;
- TRACE("vert_array:0x%08lx nvert:%d grad_array:0x%08lx ngrad:%d\n",
- (long)vert_array, nvert, (long)grad_array, ngrad);
+ TRACE("vert_array:%p nvert:%d grad_array:%p ngrad:%d\n",
+ vert_array, nvert, grad_array, ngrad);
switch(mode)
{
return TRUE;
}
+
+/******************************************************************************
+ * GdiDrawStream (GDI32.@)
+ *
+ */
+BOOL WINAPI GdiDrawStream( HDC hdc, ULONG in, void * pvin )
+{
+ FIXME("stub: %p, %d, %p\n", hdc, in, pvin);
+ return FALSE;
+}