/*
 * 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 "stddebug.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 );
}

