- Implement PATHOBJ_Xxx service routines, see CORE-13536.

svn path=/trunk/; revision=75332
This commit is contained in:
James Tabor 2017-07-13 19:34:49 +00:00
parent e61d96aa6a
commit 899d12e786
3 changed files with 458 additions and 120 deletions

View file

@ -76,6 +76,7 @@ list(APPEND SOURCE
gdi/eng/engmisc.c
gdi/eng/mouse.c
gdi/eng/paint.c
gdi/eng/pathobj.c
gdi/eng/pdevobj.c
gdi/eng/perfcnt.c
gdi/eng/rlecomp.c

View file

@ -0,0 +1,457 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS win32 subsystem
* PURPOSE: PATHOBJ service routines
* FILE: win32ss/gdi/eng/pathobj.c
* PROGRAMERS: Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
*/
/* INCLUDES *****************************************************************/
#include <win32k.h>
#undef XFORMOBJ
#define NDEBUG
#include <debug.h>
/* TYPES *********************************************************************/
/* extended PATHDATA */
typedef struct _EXTPATHDATA
{
PATHDATA pd;
struct _EXTPATHDATA *ppdNext;
} EXTPATHDATA, *PEXTPATHDATA;
/* extended PATHOBJ */
typedef struct _EXTPATHOBJ
{
PATHOBJ po;
PEXTPATHDATA ppdFirst;
PEXTPATHDATA ppdLast;
PEXTPATHDATA ppdCurrent;
} EXTPATHOBJ, *PEXTPATHOBJ;
/* FUNCTIONS *****************************************************************/
/* FIXME: set last error */
/* FIXME: PATHOBJ_vEnumStartClipLines and PATHOBJ_bEnumClipLines */
/*
* @implemented
*/
PATHOBJ*
APIENTRY
EngCreatePath(VOID)
{
PEXTPATHOBJ pPathObj;
const ULONG size = sizeof(EXTPATHOBJ);
pPathObj = ExAllocatePoolWithTag(PagedPool, size, GDITAG_PATHOBJ);
if (pPathObj == NULL)
{
return NULL;
}
RtlZeroMemory(pPathObj, size);
return &pPathObj->po;
}
/*
* @implemented
*/
VOID
APIENTRY
EngDeletePath(IN PATHOBJ *ppo)
{
PEXTPATHOBJ pPathObj;
PEXTPATHDATA ppd, ppdNext;
pPathObj = (PEXTPATHOBJ)ppo;
if (pPathObj == NULL)
return;
for (ppd = pPathObj->ppdFirst; ppd; ppd = ppdNext)
{
ppdNext = ppd->ppdNext;
ExFreePoolWithTag(ppd, GDITAG_PATHOBJ);
}
ExFreePoolWithTag(pPathObj, GDITAG_PATHOBJ);
}
/*
* @implemented
*/
BOOL
APIENTRY
PATHOBJ_bCloseFigure(IN PATHOBJ *ppo)
{
PEXTPATHDATA ppd;
PEXTPATHOBJ pPathObj = (PEXTPATHOBJ)ppo;
if (pPathObj == NULL)
return FALSE;
ppd = pPathObj->ppdLast;
if (ppd == NULL)
return FALSE;
ppd->pd.flags |= PD_CLOSEFIGURE | PD_ENDSUBPATH;
return TRUE;
}
/*
* @implemented
*/
VOID
APIENTRY
PATHOBJ_vEnumStart(IN PATHOBJ *ppo)
{
PEXTPATHOBJ pPathObj = (PEXTPATHOBJ)ppo;
if (pPathObj == NULL)
return;
pPathObj->ppdCurrent = pPathObj->ppdFirst;
}
/*
* @implemented
*/
BOOL
APIENTRY
PATHOBJ_bEnum(
IN PATHOBJ *ppo,
OUT PATHDATA *ppd)
{
PEXTPATHOBJ pPathObj = (PEXTPATHOBJ)ppo;
if (pPathObj == NULL || pPathObj->ppdCurrent == NULL)
return FALSE;
*ppd = pPathObj->ppdCurrent->pd;
pPathObj->ppdCurrent = pPathObj->ppdCurrent->ppdNext;
return (pPathObj->ppdCurrent != NULL);
}
/*
* @implemented
*/
BOOL
APIENTRY
PATHOBJ_bMoveTo(
IN PATHOBJ *ppo,
IN POINTFIX ptfx)
{
PEXTPATHOBJ pPathObj;
PEXTPATHDATA ppd, ppdLast;
pPathObj = (PEXTPATHOBJ)ppo;
if (pPathObj == NULL)
return FALSE;
/* allocate a subpath data */
ppd = ExAllocatePoolWithTag(PagedPool, sizeof(EXTPATHDATA), GDITAG_PATHOBJ);
if (ppd == NULL)
return FALSE;
RtlZeroMemory(ppd, sizeof(EXTPATHDATA));
/* add the first point to the subpath */
ppd->pd.flags = PD_BEGINSUBPATH;
ppd->pd.count = 1;
ppd->pd.pptfx = ExAllocatePoolWithTag(PagedPool, sizeof(POINTFIX), GDITAG_PATHOBJ);
if (ppd->pd.pptfx == NULL)
{
ExFreePoolWithTag(ppd, GDITAG_PATHOBJ);
return FALSE;
}
ppd->pd.pptfx[0] = ptfx;
ppdLast = pPathObj->ppdLast;
if (ppdLast)
{
/* end the last subpath */
ppdLast->pd.flags |= PD_ENDSUBPATH;
/* add the subpath to the last */
ppdLast->ppdNext = ppd;
pPathObj->ppdLast = ppd;
}
else
{
/* add the subpath */
pPathObj->ppdLast = pPathObj->ppdFirst = ppd;
}
pPathObj->po.cCurves++;
return TRUE;
}
/*
* @implemented
*/
BOOL
APIENTRY
PATHOBJ_bPolyLineTo(
IN PATHOBJ *ppo,
IN POINTFIX *pptfx,
IN ULONG cptfx)
{
PEXTPATHOBJ pPathObj;
PEXTPATHDATA ppd, ppdLast;
PPOINTFIX pptfxNew, pptfxOld;
ULONG size;
pPathObj = (PEXTPATHOBJ)ppo;
if (pPathObj == NULL || pptfx == NULL || cptfx == 0)
return FALSE;
ppdLast = pPathObj->ppdLast;
if (ppdLast == NULL)
{
/* allocate a subpath data */
ppd = ExAllocatePoolWithTag(PagedPool, sizeof(EXTPATHDATA), GDITAG_PATHOBJ);
if (ppd == NULL)
return FALSE;
/* store data */
RtlZeroMemory(ppd, sizeof(EXTPATHDATA));
ppd->pd.flags = PD_BEGINSUBPATH;
ppd->pd.count = cptfx;
size = cptfx * sizeof(POINTFIX);
pptfxNew = ExAllocatePoolWithTag(PagedPool, size, GDITAG_PATHOBJ);
if (pptfxNew == NULL)
{
ExFreePoolWithTag(ppd, GDITAG_PATHOBJ);
return FALSE;
}
RtlCopyMemory(pptfxNew, pptfx, size);
ppd->pd.pptfx = pptfxNew;
/* set the subpath */
pPathObj->ppdLast = pPathObj->ppdFirst = ppd;
pPathObj->po.cCurves++;
}
else if (ppdLast->pd.flags & (PD_BEZIERS | PD_ENDSUBPATH))
{
/* allocate a subpath data */
ppd = ExAllocatePoolWithTag(PagedPool, sizeof(EXTPATHDATA), GDITAG_PATHOBJ);
if (ppd == NULL)
return FALSE;
/* store data */
RtlZeroMemory(ppd, sizeof(EXTPATHDATA));
ppd->pd.flags = 0;
ppd->pd.count = cptfx;
size = cptfx * sizeof(POINTFIX);
pptfxNew = ExAllocatePoolWithTag(PagedPool, size, GDITAG_PATHOBJ);
if (pptfxNew == NULL)
{
ExFreePoolWithTag(ppd, GDITAG_PATHOBJ);
return FALSE;
}
RtlCopyMemory(pptfxNew, pptfx, size);
ppd->pd.pptfx = pptfxNew;
/* add to last */
ppdLast->ppdNext = ppd;
pPathObj->ppdLast = ppd;
pPathObj->po.cCurves++;
}
else
{
/* concatnate ppdLast->pd.pptfx and pptfx */
size = (ppdLast->pd.count + cptfx) * sizeof(POINTFIX);
pptfxNew = ExAllocatePoolWithTag(PagedPool, size, GDITAG_PATHOBJ);
if (pptfxNew == NULL)
return FALSE;
size = ppdLast->pd.count * sizeof(POINTFIX);
RtlCopyMemory(&pptfxNew[0], ppdLast->pd.pptfx, size);
size = cptfx * sizeof(POINTFIX);
RtlCopyMemory(&pptfxNew[ppdLast->pd.count], pptfx, size);
pptfxOld = ppdLast->pd.pptfx;
ppd->pd.pptfx = pptfxNew;
ExFreePoolWithTag(pptfxOld, GDITAG_PATHOBJ);
}
return TRUE;
}
/*
* @implemented
*/
BOOL
APIENTRY
PATHOBJ_bPolyBezierTo(
IN PATHOBJ *ppo,
IN POINTFIX *pptfx,
IN ULONG cptfx)
{
PEXTPATHDATA ppd, ppdLast;
PEXTPATHOBJ pPathObj;
PPOINTFIX pptfxNew, pptfxOld;
ULONG size;
pPathObj = (PEXTPATHOBJ)ppo;
if (pPathObj == NULL || pptfx == NULL || cptfx == 0)
return FALSE;
ppdLast = pPathObj->ppdLast;
if (ppdLast == NULL)
{
/* allocate a subpath data */
ppd = ExAllocatePoolWithTag(PagedPool, sizeof(EXTPATHDATA), GDITAG_PATHOBJ);
if (ppd == NULL)
return FALSE;
/* store data */
RtlZeroMemory(ppd, sizeof(EXTPATHDATA));
ppd->pd.flags = PD_BEGINSUBPATH | PD_BEZIERS;
ppd->pd.count = cptfx;
size = cptfx * sizeof(POINTFIX);
pptfxNew = ExAllocatePoolWithTag(PagedPool, size, GDITAG_PATHOBJ);
if (pptfxNew == NULL)
{
ExFreePoolWithTag(ppd, GDITAG_PATHOBJ);
return FALSE;
}
RtlCopyMemory(pptfxNew, pptfx, size);
ppd->pd.pptfx = pptfxNew;
/* set the subpath */
pPathObj->ppdLast = pPathObj->ppdFirst = ppd;
pPathObj->po.cCurves++;
}
else if (!(ppdLast->pd.flags & PD_BEZIERS) || (ppdLast->pd.flags & PD_ENDSUBPATH))
{
/* allocate a subpath data */
ppd = ExAllocatePoolWithTag(PagedPool, sizeof(EXTPATHDATA), GDITAG_PATHOBJ);
if (ppd == NULL)
return FALSE;
/* store data */
RtlZeroMemory(ppd, sizeof(EXTPATHDATA));
ppd->pd.flags = PD_BEZIERS;
ppd->pd.count = cptfx;
size = cptfx * sizeof(POINTFIX);
pptfxNew = ExAllocatePoolWithTag(PagedPool, size, GDITAG_PATHOBJ);
if (pptfxNew == NULL)
{
ExFreePoolWithTag(ppd, GDITAG_PATHOBJ);
return FALSE;
}
RtlCopyMemory(pptfxNew, pptfx, size);
ppd->pd.pptfx = pptfxNew;
/* add to last */
ppdLast->ppdNext = ppd;
pPathObj->ppdLast = ppd;
pPathObj->po.cCurves++;
}
else
{
/* concatnate ppdLast->pd.pptfx and pptfx */
size = (ppdLast->pd.count + cptfx) * sizeof(POINTFIX);
pptfxNew = ExAllocatePoolWithTag(PagedPool, size, GDITAG_PATHOBJ);
if (pptfxNew == NULL)
return FALSE;
size = ppdLast->pd.count * sizeof(POINTFIX);
RtlCopyMemory(&pptfxNew[0], ppdLast->pd.pptfx, size);
size = cptfx * sizeof(POINTFIX);
RtlCopyMemory(&pptfxNew[ppdLast->pd.count], pptfx, size);
pptfxOld = ppdLast->pd.pptfx;
ppd->pd.pptfx = pptfxNew;
ExFreePoolWithTag(pptfxOld, GDITAG_PATHOBJ);
}
pPathObj->po.fl |= PO_BEZIERS;
return TRUE;
}
VOID
APIENTRY
PATHOBJ_vEnumStartClipLines(
IN PATHOBJ *ppo,
IN CLIPOBJ *pco,
IN SURFOBJ *pso,
IN LINEATTRS *pla)
{
UNIMPLEMENTED;
}
BOOL
APIENTRY
PATHOBJ_bEnumClipLines(
IN PATHOBJ *ppo,
IN ULONG cb,
OUT CLIPLINE *pcl)
{
UNIMPLEMENTED;
return FALSE;
}
/*
* @implemented
*/
VOID
APIENTRY
PATHOBJ_vGetBounds(
IN PATHOBJ *ppo,
OUT PRECTFX prectfx)
{
FIX xLeft, yTop, xRight, yBottom;
PEXTPATHOBJ pPathObj;
PEXTPATHDATA ppd, ppdNext;
ULONG i;
pPathObj = (PEXTPATHOBJ)ppo;
if (pPathObj == NULL || prectfx == NULL)
return;
yTop = xLeft = MAXLONG;
yBottom = xRight = MINLONG;
for (ppd = pPathObj->ppdFirst; ppd; ppd = ppdNext)
{
ppdNext = ppd->ppdNext;
for (i = 0; i < ppd->pd.count; ++i)
{
PPOINTFIX pptfx = &ppd->pd.pptfx[i];
if (pptfx->x < xLeft)
xLeft = pptfx->x;
if (pptfx->x > xRight)
xRight = pptfx->x;
if (pptfx->y < yTop)
yTop = pptfx->y;
if (pptfx->y > yBottom)
yBottom = pptfx->y;
}
}
if (xLeft <= xRight && yTop <= yBottom)
{
prectfx->xLeft = xLeft;
prectfx->yTop = yTop;
prectfx->xRight = xRight + 1;
prectfx->yBottom = yBottom + 1;
}
else
{
RtlZeroMemory(prectfx, sizeof(*prectfx));
}
}
/* EOF */

View file

@ -69,29 +69,6 @@ EngComputeGlyphSet(
return NULL;
}
/*
* @unimplemented
*/
PATHOBJ*
APIENTRY
EngCreatePath(VOID)
{
// www.osr.com/ddk/graphics/gdifncs_4aav.htm
UNIMPLEMENTED;
return NULL;
}
/*
* @unimplemented
*/
VOID
APIENTRY
EngDeletePath(IN PATHOBJ *ppo)
{
// www.osr.com/ddk/graphics/gdifncs_3fl3.htm
UNIMPLEMENTED;
}
/*
* @unimplemented
*/
@ -498,103 +475,6 @@ HT_Get8BPPFormatPalette(
return 0;
}
BOOL
APIENTRY
PATHOBJ_bCloseFigure(IN PATHOBJ *ppo)
{
// www.osr.com/ddk/graphics/gdifncs_5mhz.htm
UNIMPLEMENTED;
return FALSE;
}
BOOL
APIENTRY
PATHOBJ_bEnum(
IN PATHOBJ *ppo,
OUT PATHDATA *ppd)
{
// www.osr.com/ddk/graphics/gdifncs_98o7.htm
UNIMPLEMENTED;
return FALSE;
}
BOOL
APIENTRY
PATHOBJ_bEnumClipLines(
IN PATHOBJ *ppo,
IN ULONG cb,
OUT CLIPLINE *pcl)
{
// www.osr.com/ddk/graphics/gdifncs_4147.htm
UNIMPLEMENTED;
return FALSE;
}
BOOL
APIENTRY
PATHOBJ_bMoveTo(
IN PATHOBJ *ppo,
IN POINTFIX ptfx)
{
// www.osr.com/ddk/graphics/gdifncs_70vb.htm
UNIMPLEMENTED;
return FALSE;
}
BOOL
APIENTRY
PATHOBJ_bPolyBezierTo(
IN PATHOBJ *ppo,
IN POINTFIX *pptfx,
IN ULONG cptfx)
{
// www.osr.com/ddk/graphics/gdifncs_2c9z.htm
UNIMPLEMENTED;
return FALSE;
}
BOOL
APIENTRY
PATHOBJ_bPolyLineTo(
IN PATHOBJ *ppo,
IN POINTFIX *pptfx,
IN ULONG cptfx)
{
// www.osr.com/ddk/graphics/gdifncs_0x47.htm
UNIMPLEMENTED;
return FALSE;
}
VOID
APIENTRY
PATHOBJ_vEnumStart(IN PATHOBJ *ppo)
{
// www.osr.com/ddk/graphics/gdifncs_74br.htm
UNIMPLEMENTED;
}
VOID
APIENTRY
PATHOBJ_vEnumStartClipLines(
IN PATHOBJ *ppo,
IN CLIPOBJ *pco,
IN SURFOBJ *pso,
IN LINEATTRS *pla)
{
// www.osr.com/ddk/graphics/gdifncs_5grr.htm
UNIMPLEMENTED;
}
VOID
APIENTRY
PATHOBJ_vGetBounds(
IN PATHOBJ *ppo,
OUT PRECTFX prectfx)
{
// www.osr.com/ddk/graphics/gdifncs_8qp3.htm
UNIMPLEMENTED;
}
/*
* @unimplemented
*/