/*
 * Metafile driver graphics functions
 *
 * Copyright 1993, 1994 Alexandre Julliard
 */

#include <stdlib.h>
#include "graphics.h"
#include "gdi.h"
#include "dc.h"
#include "metafile.h"
#include "region.h"
#include "xmalloc.h"
#include "metafiledrv.h"
#include "debug.h"

/**********************************************************************
 *	     MFDRV_MoveToEx
 */
BOOL32
MFDRV_MoveToEx(DC *dc,INT32 x,INT32 y,LPPOINT32 pt)
{
    if (!MF_MetaParam2(dc,META_MOVETO,x,y))
    	return FALSE;

    if (pt)
    {
	pt->x = dc->w.CursPosX;
	pt->y = dc->w.CursPosY;
    }
    dc->w.CursPosX = x;
    dc->w.CursPosY = y;
    return TRUE;
}

/***********************************************************************
 *           MFDRV_LineTo
 */
BOOL32
MFDRV_LineTo( DC *dc, INT32 x, INT32 y )
{
     return MF_MetaParam2(dc, META_LINETO, x, y);
}


/***********************************************************************
 *           MFDRV_Arc
 */
BOOL32 
MFDRV_Arc( DC *dc, INT32 left, INT32 top, INT32 right, INT32 bottom,
           INT32 xstart, INT32 ystart, INT32 xend, INT32 yend )
{
     return MF_MetaParam8(dc, META_ARC, left, top, right, bottom,
			  xstart, ystart, xend, yend);
}


/***********************************************************************
 *           MFDRV_Pie
 */
BOOL32
MFDRV_Pie( DC *dc, INT32 left, INT32 top, INT32 right, INT32 bottom,
           INT32 xstart, INT32 ystart, INT32 xend, INT32 yend )
{
    return MF_MetaParam8(dc, META_PIE, left, top, right, bottom,
			 xstart, ystart, xend, yend);
}


/***********************************************************************
 *           MFDRV_Chord
 */
BOOL32
MFDRV_Chord( DC *dc, INT32 left, INT32 top, INT32 right, INT32 bottom,
             INT32 xstart, INT32 ystart, INT32 xend, INT32 yend )
{
    return MF_MetaParam8(dc, META_CHORD, left, top, right, bottom,
			 xstart, ystart, xend, yend);
}

/***********************************************************************
 *           MFDRV_Ellipse
 */
BOOL32
MFDRV_Ellipse( DC *dc, INT32 left, INT32 top, INT32 right, INT32 bottom )
{
    return MF_MetaParam4(dc, META_ELLIPSE, left, top, right, bottom);
}

/***********************************************************************
 *           MFDRV_Rectangle
 */
BOOL32
MFDRV_Rectangle(DC *dc, INT32 left, INT32 top, INT32 right, INT32 bottom)
{
    return MF_MetaParam4(dc, META_RECTANGLE, left, top, right, bottom);
}

/***********************************************************************
 *           MFDRV_RoundRect
 */
BOOL32 
MFDRV_RoundRect( DC *dc, INT32 left, INT32 top, INT32 right,
                 INT32 bottom, INT32 ell_width, INT32 ell_height )
{
    return MF_MetaParam6(dc, META_ROUNDRECT, left, top, right, bottom,
			 ell_width, ell_height);
}

/***********************************************************************
 *           MFDRV_SetPixel
 */
COLORREF
MFDRV_SetPixel( DC *dc, INT32 x, INT32 y, COLORREF color )
{
    return MF_MetaParam4(dc, META_SETPIXEL, x, y,HIWORD(color),LOWORD(color)); 
}


/**********************************************************************
 *          MFDRV_Polyline
 */
BOOL32
MFDRV_Polyline( DC *dc, const LPPOINT32 pt, INT32 count )
{
    register int i;
    LPPOINT16	pt16;
    BOOL16	ret;

    pt16 = (LPPOINT16)xmalloc(sizeof(POINT16)*count);
    for (i=count;i--;) CONV_POINT32TO16(&(pt[i]),&(pt16[i]));
    ret = MF_MetaPoly(dc, META_POLYLINE, pt16, count); 

    free(pt16);
    return ret;
}


/**********************************************************************
 *          MFDRV_Polygon
 */
BOOL32
MFDRV_Polygon( DC *dc, LPPOINT32 pt, INT32 count )
{
    register int i;
    LPPOINT16	pt16;
    BOOL16	ret;

    pt16 = (LPPOINT16)xmalloc(sizeof(POINT16)*count);
    for (i=count;i--;) CONV_POINT32TO16(&(pt[i]),&(pt16[i]));
    ret = MF_MetaPoly(dc, META_POLYGON, pt16, count); 

    free(pt16);
    return ret;
}


/**********************************************************************
 *          PolyPolygon
 */
BOOL32 
MFDRV_PolyPolygon( DC *dc, LPPOINT32 pt, LPINT32 counts, UINT32 polygons)
{
    int		i,j;
    LPPOINT16	pt16;
    LPPOINT32	curpt=pt;
    BOOL32	ret;

    for (i=0;i<polygons;i++) {
    	pt16=(LPPOINT16)xmalloc(sizeof(POINT16)*counts[i]);
	for (j=counts[i];j--;) CONV_POINT32TO16(&(curpt[j]),&(pt16[j]));
	ret = MF_MetaPoly(dc, META_POLYGON, pt16, counts[i]);
	free(pt16);
	if (!ret)
	    return FALSE;
	curpt+=counts[i];
    }
    return TRUE;
}


/**********************************************************************
 *          MFDRV_ExtFloodFill
 */
BOOL32 
MFDRV_ExtFloodFill( DC *dc, INT32 x, INT32 y, COLORREF color, UINT32 fillType )
{
    return MF_MetaParam4(dc,META_FLOODFILL,x,y,HIWORD(color),LOWORD(color)); 
}


/**********************************************************************
 *          MFDRV_PaintRgn
 */
BOOL32
MFDRV_PaintRgn( DC *dc, HRGN32 hrgn )
{
    INT16 index;
    index = MF_CreateRegion( dc, hrgn );
    if(index == -1)
        return FALSE;
    return MF_MetaParam1( dc, META_PAINTREGION, index );
}

