Windows2003-3790/windows/advcore/gdiplus/engine/gpmf3216/beziers.c
2020-09-30 16:53:55 +02:00

323 lines
9.9 KiB
C

/*****************************************************************************
*
* beziers - Entry points for Win32 to Win 16 converter
*
* Date: 7/1/91
* Author: Jeffrey Newman (c-jeffn)
*
* Copyright 1991 Microsoft Corp
*****************************************************************************/
#include "precomp.h"
#pragma hdrstop
BOOL PolyBezierCommon(PLOCALDC pLocalDC, LPPOINT pptl, PBYTE pb, DWORD cptl, DWORD mrType) ;
/***************************************************************************
* PolyDraw - Win32 to Win16 Metafile Converter Entry Point
**************************************************************************/
BOOL WINAPI DoPolyDraw
(
PLOCALDC pLocalDC,
LPPOINT pptl,
PBYTE pb,
DWORD cptl
)
{
return(PolyBezierCommon(pLocalDC, pptl, pb, cptl, EMR_POLYDRAW));
}
/***************************************************************************
* PolyBezier - Win32 to Win16 Metafile Converter Entry Point
**************************************************************************/
BOOL WINAPI DoPolyBezier
(
PLOCALDC pLocalDC,
LPPOINT pptl,
DWORD cptl
)
{
return(PolyBezierCommon(pLocalDC, pptl, (PBYTE) NULL, cptl, EMR_POLYBEZIER));
}
/***************************************************************************
* PolyBezierTo - Win32 to Win16 Metafile Converter Entry Point
**************************************************************************/
BOOL WINAPI DoPolyBezierTo
(
PLOCALDC pLocalDC,
LPPOINT pptl,
DWORD cptl
)
{
return(PolyBezierCommon(pLocalDC, pptl, (PBYTE) NULL, cptl, EMR_POLYBEZIERTO));
}
/***************************************************************************
* PolyBezierCommon - Common code for PolyDraw, PolyBezier and PolyBezierTo
**************************************************************************/
BOOL PolyBezierCommon(PLOCALDC pLocalDC, LPPOINT pptl, PBYTE pb, DWORD cptl, DWORD mrType)
{
BOOL b ;
// If we're recording the drawing order for a path
// then just pass the drawing order to the helper DC.
// Do not emit any Win16 drawing orders.
if (pLocalDC->flags & RECORDING_PATH)
{
// On Win9x transform the points with the WorldToPage transform
// before calling the HelperDC functions
if (pfnSetVirtualResolution == NULL)
{
if (!bXformWorkhorse((PPOINTL) pptl, cptl, &pLocalDC->xformRWorldToRDev))
return FALSE;
}
switch (mrType)
{
case EMR_POLYBEZIER:
b = PolyBezier(pLocalDC->hdcHelper, pptl, cptl) ;
break ;
case EMR_POLYBEZIERTO:
b = PolyBezierTo(pLocalDC->hdcHelper, pptl, cptl) ;
break ;
case EMR_POLYDRAW:
b = PolyDraw(pLocalDC->hdcHelper, pptl, pb, cptl) ;
break ;
default:
b = FALSE;
RIPS(("MF3216: PolyBezierCommon, bad mrType\n")) ;
break ;
}
ASSERTGDI(b, "MF3216: PolyBezierCommon, in path render failed\n") ;
return (b) ;
}
// Call the common curve renderer.
return
(
bRenderCurveWithPath(pLocalDC, pptl, pb, cptl,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0f, 0.0f, mrType)
);
}
/***************************************************************************
* bRenderCurveWithPath - Renders a curve or area using the path api.
* The supported curves and areas are PolyDraw, PolyBezier, PolyBezierTo,
* AngleArc, Arc, Chord, Pie, Ellipse, Rectangle, and RoundRect.
**************************************************************************/
BOOL bRenderCurveWithPath
(
PLOCALDC pLocalDC,
LPPOINT pptl,
PBYTE pb,
DWORD cptl,
INT x1,
INT y1,
INT x2,
INT y2,
INT x3,
INT y3,
INT x4,
INT y4,
DWORD nRadius,
FLOAT eStartAngle,
FLOAT eSweepAngle,
DWORD mrType
)
{
BOOL b = FALSE;
INT iPathType;
POINTL ppts[4] = {x1, y1, x2, y2, x3, y3, x4, y4};
if (pfnSetVirtualResolution == NULL)
{
// On Win9x tranform the points before passing them to the DC
if (!bXformWorkhorse((PPOINTL) pptl, cptl, &pLocalDC->xformRWorldToRDev))
{
RIPS("GPMF3216: bRenderCurveWithPath, BeginPath failed\n");
goto exit_bRenderCurveWithPath;
}
if (!bXformWorkhorse(ppts, 4, &pLocalDC->xformRWorldToRDev))
{
RIPS("GPMF3216: bRenderCurveWithPath, BeginPath failed\n");
goto exit_bRenderCurveWithPath;
}
}
// We don't do curves in a path bracket here. They should be
// taken care of by the caller.
ASSERTGDI(!(pLocalDC->flags & RECORDING_PATH),
"MF3216: bRenderCurveWithPath, cannot be in a path bracket\n");
// Save the helper DC first.
// This is to prevent us from accidentally deleteing the current path
// in the helper DC when we create another path to render the curve.
// E.g. BeginPath, Polyline, EndPath, PolyBezier, StrokePath.
if (!SaveDC(pLocalDC->hdcHelper))
{
RIPS("MF3216: bRenderCurveWithPath, SaveDC failed\n");
return(FALSE);
}
// Create the path for the curve and stroke it.
// Be careful not to modify the states of the LocalDC especially in
// DoRenderPath below.
// Note that BeginPath uses the previous current position. So this
// code will work correctly in the case of PolyBezierTo, PolyDraw
// and AngleArc.
// Begin the path.
b = BeginPath(pLocalDC->hdcHelper);
if (!b)
{
RIPS("MF3216: bRenderCurveWithPath, BeginPath failed\n");
goto exit_bRenderCurveWithPath;
}
// Do the curve.
switch (mrType)
{
case EMR_POLYBEZIER:
iPathType = EMR_STROKEPATH;
b = PolyBezier(pLocalDC->hdcHelper, pptl, cptl);
break;
case EMR_POLYBEZIERTO:
iPathType = EMR_STROKEPATH;
b = PolyBezierTo(pLocalDC->hdcHelper, pptl, cptl);
break;
case EMR_POLYDRAW:
iPathType = EMR_STROKEPATH;
b = PolyDraw(pLocalDC->hdcHelper, pptl, pb, cptl);
break;
case EMR_ANGLEARC:
iPathType = EMR_STROKEPATH;
b = AngleArc(pLocalDC->hdcHelper, ppts[0].x, ppts[0].y, nRadius, eStartAngle, eSweepAngle);
break;
case EMR_ARC:
iPathType = EMR_STROKEPATH;
b = Arc(pLocalDC->hdcHelper, ppts[0].x, ppts[0].y, ppts[1].x, ppts[1].y,
ppts[2].x, ppts[2].y, ppts[3].x, ppts[3].y);
break;
case EMR_CHORD:
iPathType = EMR_STROKEANDFILLPATH;
b = Chord(pLocalDC->hdcHelper, ppts[0].x, ppts[0].y, ppts[1].x, ppts[1].y,
ppts[2].x, ppts[2].y, ppts[3].x, ppts[3].y);
break;
case EMR_PIE:
iPathType = EMR_STROKEANDFILLPATH;
b = Pie(pLocalDC->hdcHelper, ppts[0].x, ppts[0].y, ppts[1].x, ppts[1].y,
ppts[2].x, ppts[2].y, ppts[3].x, ppts[3].y);
break;
case EMR_ELLIPSE:
iPathType = EMR_STROKEANDFILLPATH;
b = Ellipse(pLocalDC->hdcHelper, ppts[0].x, ppts[0].y, ppts[1].x, ppts[1].y);
break;
case EMR_RECTANGLE:
iPathType = EMR_STROKEANDFILLPATH;
b = Rectangle(pLocalDC->hdcHelper, ppts[0].x, ppts[0].y, ppts[1].x, ppts[1].y) ;
break;
case EMR_ROUNDRECT:
iPathType = EMR_STROKEANDFILLPATH;
b = RoundRect(pLocalDC->hdcHelper, ppts[0].x, ppts[0].y, ppts[1].x, ppts[1].y,
ppts[2].x, ppts[2].y) ;
break;
default:
b = FALSE;
RIPS("MF3216: bRenderCurveWithPath, bad mrType");
break;
}
if (!b)
{
RIPS("MF3216: bRenderCurveWithPath, render failed\n");
goto exit_bRenderCurveWithPath;
}
// End the path
b = EndPath(pLocalDC->hdcHelper);
if (!b)
{
RIPS("MF3216: bRenderCurveWithPath, EndPath failed\n");
goto exit_bRenderCurveWithPath;
}
// Stroke or fill the path.
b = DoRenderPath(pLocalDC, iPathType, FALSE);
if (!b)
{
RIPS("MF3216: bRenderCurveWithPath, DoRenderPath failed\n");
goto exit_bRenderCurveWithPath;
}
exit_bRenderCurveWithPath:
// Restore the helper DC.
if (!RestoreDC(pLocalDC->hdcHelper, -1))
ASSERTGDI(FALSE, "MF3216: bRenderCurveWithPath, RestoreDC failed\n") ;
// If this is a PolyBezeirTo, PolyDraw or AngleArc, make the call to the
// helper DC to update its current position.
if (b)
{
switch (mrType)
{
case EMR_POLYBEZIER:
case EMR_ARC:
case EMR_CHORD:
case EMR_PIE:
case EMR_ELLIPSE:
case EMR_RECTANGLE:
case EMR_ROUNDRECT: // no need to update the helper DC
break ;
case EMR_POLYBEZIERTO:
(void) PolyBezierTo(pLocalDC->hdcHelper, pptl, cptl) ;
break ;
case EMR_POLYDRAW:
(void) PolyDraw(pLocalDC->hdcHelper, pptl, pb, cptl) ;
break ;
case EMR_ANGLEARC:
(void) AngleArc(pLocalDC->hdcHelper, ppts[0].x, ppts[0].y, nRadius, eStartAngle, eSweepAngle);
break ;
default:
RIPS("MF3216: bRenderCurveWithPath, bad mrType");
break;
}
}
// Return the result.
return(b);
}