/* * Metafile driver graphics functions * * Copyright 1993, 1994 Alexandre Julliard */ #include #include "gdi.h" #include "dc.h" #include "region.h" #include "xmalloc.h" #include "metafiledrv.h" #include "heap.h" #include "debug.h" DEFAULT_DEBUG_CHANNEL(metafile) /********************************************************************** * MFDRV_MoveToEx */ BOOL MFDRV_MoveToEx(DC *dc,INT x,INT y,LPPOINT pt) { if (!MFDRV_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 */ BOOL MFDRV_LineTo( DC *dc, INT x, INT y ) { return MFDRV_MetaParam2(dc, META_LINETO, x, y); } /*********************************************************************** * MFDRV_Arc */ BOOL MFDRV_Arc( DC *dc, INT left, INT top, INT right, INT bottom, INT xstart, INT ystart, INT xend, INT yend ) { return MFDRV_MetaParam8(dc, META_ARC, left, top, right, bottom, xstart, ystart, xend, yend); } /*********************************************************************** * MFDRV_Pie */ BOOL MFDRV_Pie( DC *dc, INT left, INT top, INT right, INT bottom, INT xstart, INT ystart, INT xend, INT yend ) { return MFDRV_MetaParam8(dc, META_PIE, left, top, right, bottom, xstart, ystart, xend, yend); } /*********************************************************************** * MFDRV_Chord */ BOOL MFDRV_Chord( DC *dc, INT left, INT top, INT right, INT bottom, INT xstart, INT ystart, INT xend, INT yend ) { return MFDRV_MetaParam8(dc, META_CHORD, left, top, right, bottom, xstart, ystart, xend, yend); } /*********************************************************************** * MFDRV_Ellipse */ BOOL MFDRV_Ellipse( DC *dc, INT left, INT top, INT right, INT bottom ) { return MFDRV_MetaParam4(dc, META_ELLIPSE, left, top, right, bottom); } /*********************************************************************** * MFDRV_Rectangle */ BOOL MFDRV_Rectangle(DC *dc, INT left, INT top, INT right, INT bottom) { return MFDRV_MetaParam4(dc, META_RECTANGLE, left, top, right, bottom); } /*********************************************************************** * MFDRV_RoundRect */ BOOL MFDRV_RoundRect( DC *dc, INT left, INT top, INT right, INT bottom, INT ell_width, INT ell_height ) { return MFDRV_MetaParam6(dc, META_ROUNDRECT, left, top, right, bottom, ell_width, ell_height); } /*********************************************************************** * MFDRV_SetPixel */ COLORREF MFDRV_SetPixel( DC *dc, INT x, INT y, COLORREF color ) { return MFDRV_MetaParam4(dc, META_SETPIXEL, x, y,HIWORD(color), LOWORD(color)); } /****************************************************************** * MFDRV_MetaPoly - implements Polygon and Polyline */ static BOOL MFDRV_MetaPoly(DC *dc, short func, LPPOINT16 pt, short count) { BOOL ret; DWORD len; METARECORD *mr; len = sizeof(METARECORD) + (count * 4); if (!(mr = HeapAlloc( SystemHeap, HEAP_ZERO_MEMORY, len ))) return FALSE; mr->rdSize = len / 2; mr->rdFunction = func; *(mr->rdParm) = count; memcpy(mr->rdParm + 1, pt, count * 4); ret = MFDRV_WriteRecord( dc, mr, mr->rdSize * 2); HeapFree( SystemHeap, 0, mr); return ret; } /********************************************************************** * MFDRV_Polyline */ BOOL MFDRV_Polyline( DC *dc, const POINT* pt, INT 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 = MFDRV_MetaPoly(dc, META_POLYLINE, pt16, count); free(pt16); return ret; } /********************************************************************** * MFDRV_Polygon */ BOOL MFDRV_Polygon( DC *dc, const POINT* pt, INT 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 = MFDRV_MetaPoly(dc, META_POLYGON, pt16, count); free(pt16); return ret; } /********************************************************************** * MFDRV_PolyPolygon */ BOOL MFDRV_PolyPolygon( DC *dc, const POINT* pt, const INT* counts, UINT polygons) { int i,j; LPPOINT16 pt16; const POINT* curpt=pt; BOOL ret; for (i=0;i 6 WORDs per rect */ len = sizeof(METARECORD) + 20 + (rgndata->rdh.nCount * 12); if( !(mr = HeapAlloc( SystemHeap, HEAP_ZERO_MEMORY, len )) ) { WARN(metafile, "Can't alloc METARECORD buffer\n"); HeapFree( SystemHeap, 0, rgndata ); return -1; } Param = mr->rdParm + 11; StartBand = NULL; pEndRect = (RECT *)rgndata->Buffer + rgndata->rdh.nCount; for(pCurRect = (RECT *)rgndata->Buffer; pCurRect < pEndRect; pCurRect++) { if( StartBand && pCurRect->top == *(StartBand + 1) ) { *Param++ = pCurRect->left; *Param++ = pCurRect->right; } else { if(StartBand) { *StartBand = Param - StartBand - 3; *Param++ = *StartBand; if(*StartBand > MaxBands) MaxBands = *StartBand; Bands++; } StartBand = Param++; *Param++ = pCurRect->top; *Param++ = pCurRect->bottom; *Param++ = pCurRect->left; *Param++ = pCurRect->right; } } len = Param - (WORD *)mr; mr->rdParm[0] = 0; mr->rdParm[1] = 6; mr->rdParm[2] = 0x1234; mr->rdParm[3] = 0; mr->rdParm[4] = len * 2; mr->rdParm[5] = Bands; mr->rdParm[6] = MaxBands; mr->rdParm[7] = rgndata->rdh.rcBound.left; mr->rdParm[8] = rgndata->rdh.rcBound.top; mr->rdParm[9] = rgndata->rdh.rcBound.right; mr->rdParm[10] = rgndata->rdh.rcBound.bottom; mr->rdFunction = META_CREATEREGION; mr->rdSize = len / 2; ret = MFDRV_WriteRecord( dc, mr, mr->rdSize * 2 ); HeapFree( SystemHeap, 0, mr ); HeapFree( SystemHeap, 0, rgndata ); if(!ret) { WARN(metafile, "MFDRV_WriteRecord failed\n"); return -1; } return MFDRV_AddHandleDC( dc ); } /********************************************************************** * MFDRV_PaintRgn */ BOOL MFDRV_PaintRgn( DC *dc, HRGN hrgn ) { INT16 index; index = MFDRV_CreateRegion( dc, hrgn ); if(index == -1) return FALSE; return MFDRV_MetaParam1( dc, META_PAINTREGION, index ); } /********************************************************************** * MFDRV_InvertRgn */ BOOL MFDRV_InvertRgn( DC *dc, HRGN hrgn ) { INT16 index; index = MFDRV_CreateRegion( dc, hrgn ); if(index == -1) return FALSE; return MFDRV_MetaParam1( dc, META_INVERTREGION, index ); } /********************************************************************** * MFDRV_FillRgn */ BOOL MFDRV_FillRgn( DC *dc, HRGN hrgn, HBRUSH hbrush ) { INT16 iRgn, iBrush; iRgn = MFDRV_CreateRegion( dc, hrgn ); if(iRgn == -1) return FALSE; iBrush = MFDRV_CreateBrushIndirect( dc, hbrush ); if(iBrush == -1) return FALSE; return MFDRV_MetaParam2( dc, META_FILLREGION, iRgn, iBrush ); } /********************************************************************** * MFDRV_FrameRgn */ BOOL MFDRV_FrameRgn( DC *dc, HRGN hrgn, HBRUSH hbrush, INT x, INT y ) { INT16 iRgn, iBrush; iRgn = MFDRV_CreateRegion( dc, hrgn ); if(iRgn == -1) return FALSE; iBrush = MFDRV_CreateBrushIndirect( dc, hbrush ); if(iBrush == -1) return FALSE; return MFDRV_MetaParam4( dc, META_FRAMEREGION, iRgn, iBrush, x, y ); } /********************************************************************** * MFDRV_SetBkColor */ COLORREF MFDRV_SetBkColor( DC *dc, COLORREF color ) { return MFDRV_MetaParam2(dc, META_SETBKCOLOR, HIWORD(color), LOWORD(color)); } /********************************************************************** * MFDRV_SetTextColor */ COLORREF MFDRV_SetTextColor( DC *dc, COLORREF color ) { return MFDRV_MetaParam2(dc, META_SETTEXTCOLOR, HIWORD(color), LOWORD(color)); }