diff --git a/reactos/dll/win32/gdi32/objects/painting.c b/reactos/dll/win32/gdi32/objects/painting.c index e0c949f7772..c0918eca75d 100644 --- a/reactos/dll/win32/gdi32/objects/painting.c +++ b/reactos/dll/win32/gdi32/objects/painting.c @@ -1,6 +1,185 @@ #include "precomp.h" +typedef union +{ + FLOAT f; + ULONG l; +} gxf_long; + +#define XFPMANT(fp) ((fp.l) & 0x7fffff) +#define XFPEXP(fp) ((fp.l) >> 23) & 0xff) +#define XFPBUILD(e, m) (((e << 23) & 0x7f800000) | (m & 0x7fffff)) + + +VOID FASTCALL +CoordCnvP(MATRIX_S * mx, LPPOINT Point) +{ + FLOAT x, y; + gxf_long a, b; + + x = (FLOAT)Point->x; + y = (FLOAT)Point->y; + + a.l = XFPBUILD( mx->efM11.lExp, mx->efM11.lMant); + b.l = XFPBUILD( mx->efM21.lExp, mx->efM21.lMant); + + Point->x = x * a.f + y * b.f + mx->fxDx; + + a.l = XFPBUILD( mx->efM12.lExp, mx->efM12.lMant); + b.l = XFPBUILD( mx->efM22.lExp, mx->efM22.lMant); + + Point->y = x * a.f + y * b.f + mx->fxDy; +} + + +BOOL +STDCALL +DPtoLP ( HDC hDC, LPPOINT Points, INT Count ) +{ + INT i; + PDC_ATTR Dc_Attr; + + if (!GdiGetHandleUserData((HGDIOBJ) hDC, (PVOID) &Dc_Attr)) return FALSE; + + for ( i = 0; i < Count; i++ ) + CoordCnvP ( &Dc_Attr->mxDevicetoWorld, &Points[i] ); + return TRUE; +} + + +BOOL +STDCALL +LPtoDP ( HDC hDC, LPPOINT Points, INT Count ) +{ + INT i; + PDC_ATTR Dc_Attr; + + if (!GdiGetHandleUserData((HGDIOBJ) hDC, (PVOID) &Dc_Attr)) return FALSE; + + for ( i = 0; i < Count; i++ ) + CoordCnvP ( &Dc_Attr->mxWorldToDevice, &Points[i] ); + return TRUE; +} + + +// Will move to dc.c +HGDIOBJ +STDCALL +GetDCObject( HDC hDC, INT iType) +{ + + if((iType == GDI_OBJECT_TYPE_BRUSH) || + (iType == GDI_OBJECT_TYPE_EXTPEN)|| + (iType == GDI_OBJECT_TYPE_PEN) || + (iType == GDI_OBJECT_TYPE_COLORSPACE)) + { + HGDIOBJ hGO; + PDC_ATTR Dc_Attr; + + if (!GdiGetHandleUserData((HGDIOBJ) hDC, (PVOID) &Dc_Attr)) return NULL; + + switch (iType) + { + case GDI_OBJECT_TYPE_BRUSH: + hGO = Dc_Attr->hbrush; + break; + + case GDI_OBJECT_TYPE_EXTPEN: + case GDI_OBJECT_TYPE_PEN: + hGO = Dc_Attr->hpen; + break; + + case GDI_OBJECT_TYPE_COLORSPACE: + hGO = Dc_Attr->hColorSpace; + break; + } + return hGO; + } + return NtGdiGetDCObject( hDC, iType ); +} + + +BOOL +STDCALL +LineTo( HDC hDC, INT x, INT y ) +{ +// Handle something other than a normal dc object. + if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC) + { + if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC) + return MFDRV_MetaParam2( hDC, META_LINETO, x, y); + else + { + PLDC pLDC = GdiGetLDC(hDC); + if ( !pLDC ) + { + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + if (pLDC->iType == LDC_EMFLDC) + { + return MFDRV_LineTo( hDC, x, y ) + } + return FALSE; + } + } + return NtGdiLineTo( hDC, x, y); +} + + +BOOL +STDCALL +MoveToEx( HDC hDC, INT x, INT y, LPPOINT Point ) +{ + PDC_ATTR Dc_Attr; + + if (!GdiGetHandleUserData((HGDIOBJ) hDC, (PVOID) &Dc_Attr)) return FALSE; + + if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC) + { + if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC) +// return MFDRV_MetaParam2( hDC, META_MOVETO, x, y); + return FALSE; + else + { + PLDC pLDC = Dc_Attr->pvLDC; + if ( !pLDC ) + { + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + if (pLDC->iType == LDC_EMFLDC) + { + //if (!EMFDRV_MoveTo( hDC, x, y)) + return FALSE; + } + } + } + + if ( Point ) + { + if ( Dc_Attr->ulDirty_ & DIRTY_PTLCURRENT ) // Double hit! + { + Point->x = Dc_Attr->ptfxCurrent.x; // ret prev before change. + Point->y = Dc_Attr->ptfxCurrent.y; + DPtoLP ( hDC, Point, 1); // reconvert back. + } + else + { + Point->x = Dc_Attr->ptlCurrent.x; + Point->y = Dc_Attr->ptlCurrent.y; + } + } + + Dc_Attr->ptlCurrent.x = x; + Dc_Attr->ptlCurrent.y = y; + + Dc_Attr->ulDirty_ |= ( DIRTY_PTLCURRENT|DIRTY_STYLESTATE); // Set dirty + return TRUE; +} + + /* * @unimplemented */ @@ -25,8 +204,8 @@ NewArc( // Call Wine (rewrite of) MFDRV_MetaParam8 return MFDRV_MetaParam8( hDC, META_ARC, a1, a2, a3, a4, a5, a6, a7, a8) else - { - PLDC pLDC = GdiGetLDC(HDC hDC); + { + PLDC pLDC = GdiGetLDC(hDC); if ( !pLDC ) { SetLastError(ERROR_INVALID_HANDLE); @@ -68,8 +247,8 @@ NewArcTo( if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC) return FALSE; //No meta support for ArcTo else - { - PLDC pLDC = GdiGetLDC(HDC hDC); + { + PLDC pLDC = GdiGetLDC(hDC); if ( !pLDC ) { SetLastError(ERROR_INVALID_HANDLE); @@ -110,8 +289,8 @@ Chord( if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC) return MFDRV_MetaParam8( hDC, META_CHORD, a1, a2, a3, a4, a5, a6, a7, a8) else - { - PLDC pLDC = GdiGetLDC(HDC hDC); + { + PLDC pLDC = GdiGetLDC(hDC); if ( !pLDC ) { SetLastError(ERROR_INVALID_HANDLE); @@ -152,8 +331,8 @@ NewPie( if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC) return MFDRV_MetaParam8( hDC, META_PIE, a1, a2, a3, a4, a5, a6, a7, a8) else - { - PLDC pLDC = GdiGetLDC(HDC hDC); + { + PLDC pLDC = GdiGetLDC(hDC); if ( !pLDC ) { SetLastError(ERROR_INVALID_HANDLE); @@ -171,3 +350,495 @@ NewPie( } +BOOL +STDCALL +Ellipse(HDC hDC, INT Left, INT Top, INT Right, INT Bottom) +{ +// Handle something other than a normal dc object. + if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC) + { + if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC) + return MFDRV_MetaParam4(hDC, META_ELLIPSE, Left, Top, Right, Bottom ); + else + { + PLDC pLDC = GdiGetLDC(hDC); + if ( !pLDC ) + { + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + if (pLDC->iType == LDC_EMFLDC) + { + return EMFDRV_Ellipse( hDC, Left, Top, Right, Bottom ); + } + return FALSE; + } + } + return NtGdiEllipse( hDC, Left, Top, Right, Bottom); +} + + +BOOL +STDCALL +Rectangle(HDC, INT Left, INT Top, INT Right, INT Bottom) +{ +// Handle something other than a normal dc object. + if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC) + { + if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC) + return MFDRV_MetaParam4(hDC, META_RECTANGLE, Left, Top, Right, Bottom ); + else + { + PLDC pLDC = GdiGetLDC(hDC); + if ( !pLDC ) + { + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + if (pLDC->iType == LDC_EMFLDC) + { + return EMFDRV_Rectangle( hDC, Left, Top, Right, Bottom ); + } + return FALSE; + } + } + return NtGdiRectangle( hDC, Left, Top, Right, Bottom); +} + + +BOOL +STDCALL +RoundRect(HDC, INT Left, INT Top, INT Right, INT Bottom, + INT ell_Width, INT ell_Height) +{ +// Handle something other than a normal dc object. + if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC) + { + if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC) + return MFDRV_MetaParam6( hDC, META_ROUNDRECT, Left, Top, Right, Bottom, + ell_Width, ell_Height ); + else + { + PLDC pLDC = GdiGetLDC(hDC); + if ( !pLDC ) + { + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + if (pLDC->iType == LDC_EMFLDC) + { + return EMFDRV_RoundRect( hDC, Left, Top, Right, Bottom, + ell_Width, ell_Height ); + } + return FALSE; + } + } + return NtGdiRoundRect( hDc, Left, Top, Right, Bottom, ell_Width, ell_Height); +} + + +COLORREF +STDCALL +GetPixel( HDC hDC, INT x, INT y ) +{ + PDC_ATTR Dc_Attr; + + if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC) return CLR_INVALID; + + if (!GdiGetHandleUserData((HGDIOBJ) hDC, (PVOID) &Dc_Attr)) return CLR_INVALID; + + return NtGdiGetPixel( hDC, x, y); +} + + +COLORREF +STDCALL +SetPixel( HDC hDC, INT x, INT y, COLORREF Color ) +{ +// Handle something other than a normal dc object. + if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC) + { + if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC) + return MFDRV_MetaParam4(hDC, META_SETPIXEL, x, y, HIWORD(Color), + LOWORD(Color)); + else + { + PLDC pLDC = GdiGetLDC(hDC); + if ( !pLDC ) + { + SetLastError(ERROR_INVALID_HANDLE); + return 0; + } + if (pLDC->iType == LDC_EMFLDC) + { + return EMFDRV_SetPixel( hDC, x, y, Color ); + } + return 0; + } + } + return NtGdiSetPixel( hDC, x, y, Color); +} + + +BOOL +STDCALL +SetPixelV( HDC hDC, INT x, INT y, COLORREF Color ) +{ + COLORREF Cr = SetPixel( hDC, x, y, Color ); + if (Cr) return TRUE; + return FALSE; +} + + +BOOL +STDCALL +FillRgn( HDC hDC, HRGN hRgn, HBRUSH hBrush ) +{ + + if ( (!hRgn) || (!hBrush) ) return FALSE; + +// Handle something other than a normal dc object. + if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC) + { + if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC) + return MFDRV_FillRgn( hDC, hRgn, hBrush); + else + { + PLDC pLDC = GdiGetLDC(hDC); + if ( !pLDC ) + { + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + if (pLDC->iType == LDC_EMFLDC) + { + return EMFDRV_FillRgn(( hDC, hRgn, hBrush); + } + return FALSE; + } + } + return NtGdiFillRgn( hDC, hRgn, hBrush); +} + + +BOOL +STDCALL +FrameRgn( HDC hDC, HRGN hRgn, HBRUSH hBrush, INT nWidth, INT nHeight ) +{ + + if ( (!hRgn) || (!hBrush) ) return FALSE; + +// Handle something other than a normal dc object. + if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC) + { + if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC) + return MFDRV_FrameRgn( hDC, hRgn, hBrush, nWidth, nHeight ); + else + { + PLDC pLDC = GdiGetLDC(hDC); + if ( !pLDC ) + { + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + if (pLDC->iType == LDC_EMFLDC) + { + return EMFDRV_FrameRgn( hDC, hRgn, hBrush, nWidth, nHeight ); + } + return FALSE; + } + } + return NtGdiFrameRgn( hDC, hRgn, hBrush, nWidth, nHeight); +} + + +BOOL +STDCALL +InvertRgn( HDC hDC, HRGN hRgn ) +{ + + if ( !hRgn ) return FALSE; + +// Handle something other than a normal dc object. + if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC) + { + if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC) + return MFDRV_InvertRgn( hDC, HRGN hRgn ); // Use this instead of MFDRV_MetaParam. + else + { + PLDC pLDC = GdiGetLDC(hDC); + if ( !pLDC ) + { + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + if (pLDC->iType == LDC_EMFLDC) + { + return EMFDRV_PaintInvertRgn( hDC, hRgn, EMR_INVERTRGN ); + } + return FALSE; + } + } + return NtGdiInvertRgn( hDC, hRgn); +} + +BOOL +STDCALL +PaintRgn( HDC hDC, HRGN hRgn ) +{ +// Handle something other than a normal dc object. + if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC) + { + if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC) + return MFDRV_PaintRgn( hDC, HRGN hRgn ); // Use this instead of MFDRV_MetaParam. + else + { + PLDC pLDC = GdiGetLDC(hDC); + if ( !pLDC ) + { + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + if (pLDC->iType == LDC_EMFLDC) + { + return EMFDRV_PaintInvertRgn( hDC, hRgn, EMR_PAINTRGN ); + } + return FALSE; + } + } + // Could just use Dc_Attr->hbrush + HBRUSH hbrush = (HBRUSH) GetDCObject( hDC, GDI_OBJECT_TYPE_BRUSH); + + return NtGdiFillRgn( hDC, hRgn, hBrush); +} + + +BOOL +STDCALL +PolyBezier(HDC hDC ,const POINT* Point, DWORD cPoints) +{ +// Handle something other than a normal dc object. + if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC) + { + if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC) + /* + * Since MetaFiles don't record Beziers and they don't even record + * approximations to them using lines. + */ + return FALSE; + else + { + PLDC pLDC = GdiGetLDC(hDC); + if ( !pLDC ) + { + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + if (pLDC->iType == LDC_EMFLDC) + { + return FALSE; // Not supported yet. + } + return FALSE; + } + } + return NtGdiPolyPolyDraw( hDC , Point, &cPoints, 1, GdiPolyBezier ); +} + + +BOOL +STDCALL +PolyBezierTo(HDC hDC, const POINT* Point ,DWORD cPoints) +{ +// Handle something other than a normal dc object. + if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC) + { + if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC) + return FALSE; + else + { + PLDC pLDC = GdiGetLDC(hDC); + if ( !pLDC ) + { + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + if (pLDC->iType == LDC_EMFLDC) + { + return FALSE; // Not supported yet. + } + return FALSE; + } + } + return NtGdiPolyPolyDraw( hDC , Point, &cPoints, 1, GdiPolyBezierTo ); +} + + +BOOL +STDCALL +PolyDraw(HDC hDC, const POINT* Point, const BYTE *lpbTypes, int cCount ) +{ +// Handle something other than a normal dc object. + if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC) + { + if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC) + return FALSE; + else + { + PLDC pLDC = GdiGetLDC(hDC); + if ( !pLDC ) + { + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + if (pLDC->iType == LDC_EMFLDC) + { + return FALSE; // Not supported yet. + } + return FALSE; + } + } + return NtGdiPolyDraw( hDC , Point, lpbTypes, cCount ); +} + + +BOOL +STDCALL +Polygon(HDC hDC, const POINT *Point, int Count) +{ +// Handle something other than a normal dc object. + if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC) + { + if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC) + return MFDRV_Polygon( hDC, Point, Count ); + else + { + PLDC pLDC = GdiGetLDC(hDC); + if ( !pLDC ) + { + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + if (pLDC->iType == LDC_EMFLDC) + { + return EMFDRV_Polygon( hDC, Point, Count ); + } + return FALSE; + } + } + return NtGdiPolyPolyDraw( hDC , Point, &Count, 1, GdiPolygon ); +} + + +BOOL +STDCALL +Polyline(HDC hDC, const POINT *Point, int Count) +{ +// Handle something other than a normal dc object. + if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC) + { + if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC) + return MFDRV_Polyline( hDC, Point, Count ); + else + { + PLDC pLDC = GdiGetLDC(hDC); + if ( !pLDC ) + { + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + if (pLDC->iType == LDC_EMFLDC) + { + return EMFDRV_Polyline( hDC, Point, Count ); + } + return FALSE; + } + } + return NtGdiPolyPolyDraw( hDC , Point, &Count, 1, GdiPolyPolyLine ); +} + + +BOOL +STDCALL +PolylineTo(HDC hDC, const POINT* Point, DWORD Count) +{ +// Handle something other than a normal dc object. + if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC) + { + if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC) + return FALSE; + else + { + PLDC pLDC = GdiGetLDC(hDC); + if ( !pLDC ) + { + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + if (pLDC->iType == LDC_EMFLDC) + { + return FALSE; // Not supported yet. + } + return FALSE; + } + } + return NtGdiPolyPolyDraw( hDC , Point, &Count, 1, GdiPolyLineTo ); + +} + + +BOOL +STDCALL +PolyPolygon(HDC hDC, const POINT* Point, const INT* Count, int Polys) +{ +// Handle something other than a normal dc object. + if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC) + { + if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC) + return MFDRV_PolyPolygon( hDC, Point, Count, Polys); + else + { + PLDC pLDC = GdiGetLDC(hDC); + if ( !pLDC ) + { + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + if (pLDC->iType == LDC_EMFLDC) + { + return EMFDRV_PolyPolygon( hDC, Point, Count, Polys ); + } + return FALSE; + } + } + return NtGdiPolyPolyDraw( hDC , Point, Count, Polys, GdiPolygon ); + +} + + +BOOL +STDCALL +PolyPolyline(HDC hDC, const POINT* Point, const DWORD* Counts, DWORD Polys) +{ +// Handle something other than a normal dc object. + if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC) + { + if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC) + return FALSE; + else + { + PLDC pLDC = GdiGetLDC(hDC); + if ( !pLDC ) + { + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + if (pLDC->iType == LDC_EMFLDC) + { + return EMFDRV_PolyPolyline(hDC, Point, Counts, Polys); + } + return FALSE; + } + } + return NtGdiPolyPolyDraw( hDC , Point, Count, Polys, GdiPolyPolyLine ); +} +