Import metafile code from wine. The wine code is unmodified (please keep it that way) and used through a wrapper function dispatcher and some helpers. Fixes 1931 wine tests.

svn path=/trunk/; revision=65893
This commit is contained in:
Timo Kreuzer 2014-12-29 14:25:30 +00:00
parent 2bcae18ec6
commit e6475301eb
35 changed files with 11669 additions and 2378 deletions

View File

@ -1,4 +1,8 @@
add_subdirectory(wine)
add_definitions(-DLANGPACK)
include_directories(
include
${REACTOS_SOURCE_DIR}/win32ss/include)
@ -46,8 +50,19 @@ add_library(gdi32 SHARED
gdi32.rc
${CMAKE_CURRENT_BINARY_DIR}/gdi32.def)
set_module_type(gdi32 win32dll ENTRYPOINT DllMain 12 UNICODE)
target_link_libraries(gdi32 win32ksys dxguid msvcrtex ${PSEH_LIB})
set_module_type(gdi32
win32dll
ENTRYPOINT DllMain 12
UNICODE)
target_link_libraries(gdi32
winegdi
wine
win32ksys
dxguid
msvcrtex
${PSEH_LIB})
add_importlibs(gdi32 user32 advapi32 kernel32 ntdll)
add_pch(gdi32 include/precomp.h SOURCE)
add_cd_file(TARGET gdi32 DESTINATION reactos/system32 FOR all)

View File

@ -444,6 +444,24 @@ _lrintf(float f)
#endif
}
HBRUSH
WINAPI
GdiSelectBrush(
_In_ HDC hdc,
_In_ HBRUSH hbr);
HPEN
WINAPI
GdiSelectPen(
_In_ HDC hdc,
_In_ HPEN hpen);
HFONT
WINAPI
GdiSelectFont(
_In_ HDC hdc,
_In_ HFONT hfont);
HGDIOBJ
WINAPI
GdiCreateClientObj(
@ -473,5 +491,182 @@ GdiRemoveClientObjLink(
extern ULONG gcClientObj;
VOID
WINAPI
METADC_DeleteObject(HGDIOBJ hobj);
BOOL
WINAPI
METADC_DeleteDC(
_In_ HDC hdc);
INT
WINAPI
METADC16_Escape(
_In_ HDC hdc,
_In_ INT nEscape,
_In_ INT cbInput,
_In_ LPCSTR lpvInData,
_Out_ LPVOID lpvOutData);
BOOL
WINAPI
METADC_ExtTextOutW(
HDC hdc,
INT x,
INT y,
UINT fuOptions,
const RECT *lprc,
LPCWSTR lpString,
UINT cchString,
const INT *lpDx);
BOOL
WINAPI
METADC_PatBlt(
_In_ HDC hdc,
_In_ INT xLeft,
_In_ INT yTop,
_In_ INT nWidth,
_In_ INT nHeight,
_In_ DWORD dwRop);
/* The following METADC_* functions follow this pattern: */
#define HANDLE_METADC0P(_RetType, _Func, dwError, hdc, ...) \
if (GDI_HANDLE_GET_TYPE(hdc) != GDILoObjType_LO_DC_TYPE) \
{ \
DWORD_PTR dwResult; \
if (METADC_Dispatch(DCFUNC_##_Func, &dwResult, (DWORD_PTR)dwError, hdc)) \
{ \
return (_RetType)dwResult; \
} \
}
#define HANDLE_METADC(_RetType, _Func, dwError, hdc, ...) \
if (GDI_HANDLE_GET_TYPE(hdc) != GDILoObjType_LO_DC_TYPE) \
{ \
DWORD_PTR dwResult = 1; \
if (METADC_Dispatch(DCFUNC_##_Func, &dwResult, (DWORD_PTR)dwError, hdc, __VA_ARGS__)) \
{ \
return (_RetType)dwResult; \
} \
}
typedef enum _DCFUNC
{
//DCFUNC_AbortDoc,
DCFUNC_AbortPath,
DCFUNC_AlphaBlend, // UNIMPLEMENTED
DCFUNC_AngleArc, // UNIMPLEMENTED
DCFUNC_Arc,
DCFUNC_ArcTo, // UNIMPLEMENTED
DCFUNC_BeginPath,
//DCFUNC_BitBlt,
DCFUNC_Chord,
DCFUNC_CloseFigure,
DCFUNC_Ellipse,
DCFUNC_EndPath,
DCFUNC_ExcludeClipRect,
DCFUNC_ExtEscape,
DCFUNC_ExtFloodFill,
DCFUNC_ExtSelectClipRgn,
DCFUNC_ExtTextOut,
DCFUNC_FillPath,
DCFUNC_FillRgn,
DCFUNC_FlattenPath,
DCFUNC_FrameRgn,
DCFUNC_GetDeviceCaps,
DCFUNC_GdiComment,
DCFUNC_GradientFill, // UNIMPLEMENTED
DCFUNC_IntersectClipRect,
DCFUNC_InvertRgn,
DCFUNC_LineTo,
DCFUNC_MaskBlt, // UNIMPLEMENTED
DCFUNC_ModifyWorldTransform,
DCFUNC_MoveTo,
DCFUNC_OffsetClipRgn,
DCFUNC_OffsetViewportOrgEx,
DCFUNC_OffsetWindowOrgEx,
DCFUNC_PathToRegion, // UNIMPLEMENTED
DCFUNC_PatBlt,
DCFUNC_Pie,
DCFUNC_PlgBlt, // UNIMPLEMENTED
DCFUNC_PolyBezier,
DCFUNC_PolyBezierTo,
DCFUNC_PolyDraw,
DCFUNC_Polygon,
DCFUNC_Polyline,
DCFUNC_PolylineTo,
DCFUNC_PolyPolygon,
DCFUNC_PolyPolyline,
DCFUNC_RealizePalette,
DCFUNC_Rectangle,
DCFUNC_RestoreDC,
DCFUNC_RoundRect,
DCFUNC_SaveDC,
DCFUNC_ScaleViewportExtEx,
DCFUNC_ScaleWindowExtEx,
DCFUNC_SelectBrush,
DCFUNC_SelectClipPath,
DCFUNC_SelectFont,
DCFUNC_SelectPalette,
DCFUNC_SelectPen,
DCFUNC_SetDCBrushColor,
DCFUNC_SetDCPenColor,
DCFUNC_SetDIBitsToDevice,
DCFUNC_SetBkColor,
DCFUNC_SetBkMode,
DCFUNC_SetLayout,
//DCFUNC_SetMapMode,
DCFUNC_SetPixel,
DCFUNC_SetPolyFillMode,
DCFUNC_SetROP2,
DCFUNC_SetStretchBltMode,
DCFUNC_SetTextAlign,
DCFUNC_SetTextCharacterExtra,
DCFUNC_SetTextColor,
DCFUNC_SetTextJustification,
DCFUNC_SetViewportExtEx,
DCFUNC_SetViewportOrgEx,
DCFUNC_SetWindowExtEx,
DCFUNC_SetWindowOrgEx,
DCFUNC_StretchBlt,
DCFUNC_StrokeAndFillPath,
DCFUNC_StrokePath,
DCFUNC_TransparentBlt, // UNIMPLEMENTED
DCFUNC_WidenPath,
} DCFUNC;
BOOL
METADC_Dispatch(
_In_ DCFUNC eFunction,
_Out_ PDWORD_PTR pdwResult,
_In_ DWORD_PTR dwError,
_In_ HDC hdc,
...);
#define HANDLE_METADC2(_RetType, _Func, hdc, ...) \
if (GDI_HANDLE_GET_TYPE(hdc) != GDILoObjType_LO_DC_TYPE) \
{ \
_RetType result; \
if (METADC_##_Func(&result, hdc, __VA_ARGS__)) \
{ \
return result; \
} \
}
BOOL
WINAPI
METADC_GetAndSetDCDWord(
_Out_ PDWORD pdwResult,
_In_ HDC hdc,
_In_ UINT u,
_In_ DWORD dwIn,
_In_ ULONG ulMFId,
_In_ USHORT usMF16Id,
_In_ DWORD dwError);
/* EOF */

View File

@ -0,0 +1,282 @@
/*
* Definitions for Wine GDI drivers
*
* Copyright 2011 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __WINE_WINE_GDI_DRIVER_H
#define __WINE_WINE_GDI_DRIVER_H
//#include "wine/list.h"
struct gdi_dc_funcs;
struct opengl_funcs;
typedef struct gdi_physdev
{
const struct gdi_dc_funcs *funcs;
struct gdi_physdev *next;
HDC hdc;
} *PHYSDEV;
struct bitblt_coords
{
int log_x; /* original position and size, in logical coords */
int log_y;
int log_width;
int log_height;
int x; /* mapped position and size, in device coords */
int y;
int width;
int height;
RECT visrect; /* rectangle clipped to the visible part, in device coords */
DWORD layout; /* DC layout */
};
struct gdi_image_bits
{
void *ptr; /* pointer to the bits */
BOOL is_copy; /* whether this is a copy of the bits that can be modified */
void (*free)(struct gdi_image_bits *); /* callback for freeing the bits */
void *param; /* extra parameter for callback private use */
};
struct brush_pattern
{
BITMAPINFO *info; /* DIB info */
struct gdi_image_bits bits; /* DIB bits */
UINT usage; /* color usage for DIB info */
};
struct gdi_dc_funcs
{
INT (*pAbortDoc)(PHYSDEV);
BOOL (*pAbortPath)(PHYSDEV);
BOOL (*pAlphaBlend)(PHYSDEV,struct bitblt_coords*,PHYSDEV,struct bitblt_coords*,BLENDFUNCTION);
BOOL (*pAngleArc)(PHYSDEV,INT,INT,DWORD,FLOAT,FLOAT);
BOOL (*pArc)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT);
BOOL (*pArcTo)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT);
BOOL (*pBeginPath)(PHYSDEV);
DWORD (*pBlendImage)(PHYSDEV,BITMAPINFO*,const struct gdi_image_bits*,struct bitblt_coords*,struct bitblt_coords*,BLENDFUNCTION);
BOOL (*pChord)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT);
BOOL (*pCloseFigure)(PHYSDEV);
BOOL (*pCreateCompatibleDC)(PHYSDEV,PHYSDEV*);
BOOL (*pCreateDC)(PHYSDEV*,LPCWSTR,LPCWSTR,LPCWSTR,const DEVMODEW*);
BOOL (*pDeleteDC)(PHYSDEV);
BOOL (*pDeleteObject)(PHYSDEV,HGDIOBJ);
DWORD (*pDeviceCapabilities)(LPSTR,LPCSTR,LPCSTR,WORD,LPSTR,LPDEVMODEA);
BOOL (*pEllipse)(PHYSDEV,INT,INT,INT,INT);
INT (*pEndDoc)(PHYSDEV);
INT (*pEndPage)(PHYSDEV);
BOOL (*pEndPath)(PHYSDEV);
BOOL (*pEnumFonts)(PHYSDEV,LPLOGFONTW,FONTENUMPROCW,LPARAM);
INT (*pEnumICMProfiles)(PHYSDEV,ICMENUMPROCW,LPARAM);
INT (*pExcludeClipRect)(PHYSDEV,INT,INT,INT,INT);
INT (*pExtDeviceMode)(LPSTR,HWND,LPDEVMODEA,LPSTR,LPSTR,LPDEVMODEA,LPSTR,DWORD);
INT (*pExtEscape)(PHYSDEV,INT,INT,LPCVOID,INT,LPVOID);
BOOL (*pExtFloodFill)(PHYSDEV,INT,INT,COLORREF,UINT);
INT (*pExtSelectClipRgn)(PHYSDEV,HRGN,INT);
BOOL (*pExtTextOut)(PHYSDEV,INT,INT,UINT,const RECT*,LPCWSTR,UINT,const INT*);
BOOL (*pFillPath)(PHYSDEV);
BOOL (*pFillRgn)(PHYSDEV,HRGN,HBRUSH);
BOOL (*pFlattenPath)(PHYSDEV);
BOOL (*pFontIsLinked)(PHYSDEV);
BOOL (*pFrameRgn)(PHYSDEV,HRGN,HBRUSH,INT,INT);
BOOL (*pGdiComment)(PHYSDEV,UINT,const BYTE*);
BOOL (*pGdiRealizationInfo)(PHYSDEV,void*);
UINT (*pGetBoundsRect)(PHYSDEV,RECT*,UINT);
BOOL (*pGetCharABCWidths)(PHYSDEV,UINT,UINT,LPABC);
BOOL (*pGetCharABCWidthsI)(PHYSDEV,UINT,UINT,WORD*,LPABC);
BOOL (*pGetCharWidth)(PHYSDEV,UINT,UINT,LPINT);
INT (*pGetDeviceCaps)(PHYSDEV,INT);
BOOL (*pGetDeviceGammaRamp)(PHYSDEV,LPVOID);
DWORD (*pGetFontData)(PHYSDEV,DWORD,DWORD,LPVOID,DWORD);
DWORD (*pGetFontUnicodeRanges)(PHYSDEV,LPGLYPHSET);
DWORD (*pGetGlyphIndices)(PHYSDEV,LPCWSTR,INT,LPWORD,DWORD);
DWORD (*pGetGlyphOutline)(PHYSDEV,UINT,UINT,LPGLYPHMETRICS,DWORD,LPVOID,const MAT2*);
BOOL (*pGetICMProfile)(PHYSDEV,LPDWORD,LPWSTR);
DWORD (*pGetImage)(PHYSDEV,BITMAPINFO*,struct gdi_image_bits*,struct bitblt_coords*);
DWORD (*pGetKerningPairs)(PHYSDEV,DWORD,LPKERNINGPAIR);
COLORREF (*pGetNearestColor)(PHYSDEV,COLORREF);
UINT (*pGetOutlineTextMetrics)(PHYSDEV,UINT,LPOUTLINETEXTMETRICW);
COLORREF (*pGetPixel)(PHYSDEV,INT,INT);
UINT (*pGetSystemPaletteEntries)(PHYSDEV,UINT,UINT,LPPALETTEENTRY);
UINT (*pGetTextCharsetInfo)(PHYSDEV,LPFONTSIGNATURE,DWORD);
BOOL (*pGetTextExtentExPoint)(PHYSDEV,LPCWSTR,INT,LPINT);
BOOL (*pGetTextExtentExPointI)(PHYSDEV,const WORD*,INT,LPINT);
INT (*pGetTextFace)(PHYSDEV,INT,LPWSTR);
BOOL (*pGetTextMetrics)(PHYSDEV,TEXTMETRICW*);
BOOL (*pGradientFill)(PHYSDEV,TRIVERTEX*,ULONG,void*,ULONG,ULONG);
INT (*pIntersectClipRect)(PHYSDEV,INT,INT,INT,INT);
BOOL (*pInvertRgn)(PHYSDEV,HRGN);
BOOL (*pLineTo)(PHYSDEV,INT,INT);
BOOL (*pModifyWorldTransform)(PHYSDEV,const XFORM*,DWORD);
BOOL (*pMoveTo)(PHYSDEV,INT,INT);
INT (*pOffsetClipRgn)(PHYSDEV,INT,INT);
BOOL (*pOffsetViewportOrgEx)(PHYSDEV,INT,INT,POINT*);
BOOL (*pOffsetWindowOrgEx)(PHYSDEV,INT,INT,POINT*);
BOOL (*pPaintRgn)(PHYSDEV,HRGN);
BOOL (*pPatBlt)(PHYSDEV,struct bitblt_coords*,DWORD);
BOOL (*pPie)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT);
BOOL (*pPolyBezier)(PHYSDEV,const POINT*,DWORD);
BOOL (*pPolyBezierTo)(PHYSDEV,const POINT*,DWORD);
BOOL (*pPolyDraw)(PHYSDEV,const POINT*,const BYTE *,DWORD);
BOOL (*pPolyPolygon)(PHYSDEV,const POINT*,const INT*,UINT);
BOOL (*pPolyPolyline)(PHYSDEV,const POINT*,const DWORD*,DWORD);
BOOL (*pPolygon)(PHYSDEV,const POINT*,INT);
BOOL (*pPolyline)(PHYSDEV,const POINT*,INT);
BOOL (*pPolylineTo)(PHYSDEV,const POINT*,INT);
DWORD (*pPutImage)(PHYSDEV,HRGN,BITMAPINFO*,const struct gdi_image_bits*,struct bitblt_coords*,struct bitblt_coords*,DWORD);
UINT (*pRealizeDefaultPalette)(PHYSDEV);
UINT (*pRealizePalette)(PHYSDEV,HPALETTE,BOOL);
BOOL (*pRectangle)(PHYSDEV,INT,INT,INT,INT);
HDC (*pResetDC)(PHYSDEV,const DEVMODEW*);
BOOL (*pRestoreDC)(PHYSDEV,INT);
BOOL (*pRoundRect)(PHYSDEV,INT,INT,INT,INT,INT,INT);
INT (*pSaveDC)(PHYSDEV);
BOOL (*pScaleViewportExtEx)(PHYSDEV,INT,INT,INT,INT,SIZE*);
BOOL (*pScaleWindowExtEx)(PHYSDEV,INT,INT,INT,INT,SIZE*);
HBITMAP (*pSelectBitmap)(PHYSDEV,HBITMAP);
HBRUSH (*pSelectBrush)(PHYSDEV,HBRUSH,const struct brush_pattern*);
BOOL (*pSelectClipPath)(PHYSDEV,INT);
HFONT (*pSelectFont)(PHYSDEV,HFONT,UINT*);
HPALETTE (*pSelectPalette)(PHYSDEV,HPALETTE,BOOL);
HPEN (*pSelectPen)(PHYSDEV,HPEN,const struct brush_pattern*);
INT (*pSetArcDirection)(PHYSDEV,INT);
COLORREF (*pSetBkColor)(PHYSDEV,COLORREF);
INT (*pSetBkMode)(PHYSDEV,INT);
UINT (*pSetBoundsRect)(PHYSDEV,RECT*,UINT);
COLORREF (*pSetDCBrushColor)(PHYSDEV, COLORREF);
COLORREF (*pSetDCPenColor)(PHYSDEV, COLORREF);
INT (*pSetDIBitsToDevice)(PHYSDEV,INT,INT,DWORD,DWORD,INT,INT,UINT,UINT,LPCVOID,BITMAPINFO*,UINT);
VOID (*pSetDeviceClipping)(PHYSDEV,HRGN);
BOOL (*pSetDeviceGammaRamp)(PHYSDEV,LPVOID);
DWORD (*pSetLayout)(PHYSDEV,DWORD);
INT (*pSetMapMode)(PHYSDEV,INT);
DWORD (*pSetMapperFlags)(PHYSDEV,DWORD);
COLORREF (*pSetPixel)(PHYSDEV,INT,INT,COLORREF);
INT (*pSetPolyFillMode)(PHYSDEV,INT);
INT (*pSetROP2)(PHYSDEV,INT);
INT (*pSetRelAbs)(PHYSDEV,INT);
INT (*pSetStretchBltMode)(PHYSDEV,INT);
UINT (*pSetTextAlign)(PHYSDEV,UINT);
INT (*pSetTextCharacterExtra)(PHYSDEV,INT);
COLORREF (*pSetTextColor)(PHYSDEV,COLORREF);
BOOL (*pSetTextJustification)(PHYSDEV,INT,INT);
BOOL (*pSetViewportExtEx)(PHYSDEV,INT,INT,SIZE*);
BOOL (*pSetViewportOrgEx)(PHYSDEV,INT,INT,POINT*);
BOOL (*pSetWindowExtEx)(PHYSDEV,INT,INT,SIZE*);
BOOL (*pSetWindowOrgEx)(PHYSDEV,INT,INT,POINT*);
BOOL (*pSetWorldTransform)(PHYSDEV,const XFORM*);
INT (*pStartDoc)(PHYSDEV,const DOCINFOW*);
INT (*pStartPage)(PHYSDEV);
BOOL (*pStretchBlt)(PHYSDEV,struct bitblt_coords*,PHYSDEV,struct bitblt_coords*,DWORD);
INT (*pStretchDIBits)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT,const void*,BITMAPINFO*,UINT,DWORD);
BOOL (*pStrokeAndFillPath)(PHYSDEV);
BOOL (*pStrokePath)(PHYSDEV);
BOOL (*pUnrealizePalette)(HPALETTE);
BOOL (*pWidenPath)(PHYSDEV);
struct opengl_funcs * (*wine_get_wgl_driver)(PHYSDEV,UINT);
/* priority order for the driver on the stack */
UINT priority;
};
/* increment this when you change the DC function table */
#define WINE_GDI_DRIVER_VERSION 46
#define GDI_PRIORITY_NULL_DRV 0 /* null driver */
#define GDI_PRIORITY_FONT_DRV 100 /* any font driver */
#define GDI_PRIORITY_GRAPHICS_DRV 200 /* any graphics driver */
#define GDI_PRIORITY_DIB_DRV 300 /* the DIB driver */
#define GDI_PRIORITY_PATH_DRV 400 /* the path driver */
static inline PHYSDEV get_physdev_entry_point( PHYSDEV dev, size_t offset )
{
while (!((void **)dev->funcs)[offset / sizeof(void *)]) dev = dev->next;
return dev;
}
#define GET_NEXT_PHYSDEV(dev,func) \
get_physdev_entry_point( (dev)->next, FIELD_OFFSET(struct gdi_dc_funcs,func))
static inline void push_dc_driver( PHYSDEV *dev, PHYSDEV physdev, const struct gdi_dc_funcs *funcs )
{
while ((*dev)->funcs->priority > funcs->priority) dev = &(*dev)->next;
physdev->funcs = funcs;
physdev->next = *dev;
physdev->hdc = (*dev)->hdc;
*dev = physdev;
}
/* support for window surfaces */
struct window_surface;
struct window_surface_funcs
{
void (*lock)( struct window_surface *surface );
void (*unlock)( struct window_surface *surface );
void* (*get_info)( struct window_surface *surface, BITMAPINFO *info );
RECT* (*get_bounds)( struct window_surface *surface );
void (*set_region)( struct window_surface *surface, HRGN region );
void (*flush)( struct window_surface *surface );
void (*destroy)( struct window_surface *surface );
};
struct window_surface
{
const struct window_surface_funcs *funcs; /* driver-specific implementations */
// struct list entry; /* entry in global list managed by user32 */
LONG ref; /* reference count */
RECT rect; /* constant, no locking needed */
/* driver-specific fields here */
};
static inline ULONG window_surface_add_ref( struct window_surface *surface )
{
return InterlockedIncrement( &surface->ref );
}
static inline ULONG window_surface_release( struct window_surface *surface )
{
ULONG ret = InterlockedDecrement( &surface->ref );
if (!ret) surface->funcs->destroy( surface );
return ret;
}
/* the DC hook support is only exported on Win16, the 32-bit version is a Wine extension */
#define DCHC_INVALIDVISRGN 0x0001
#define DCHC_DELETEDC 0x0002
#define DCHF_INVALIDATEVISRGN 0x0001
#define DCHF_VALIDATEVISRGN 0x0002
#define DCHF_RESETDC 0x0004 /* Wine extension */
typedef BOOL (CALLBACK *DCHOOKPROC)(HDC,WORD,DWORD_PTR,LPARAM);
WINGDIAPI DWORD_PTR WINAPI GetDCHook(HDC,DCHOOKPROC*);
WINGDIAPI BOOL WINAPI SetDCHook(HDC,DCHOOKPROC,DWORD_PTR);
WINGDIAPI WORD WINAPI SetHookFlags(HDC,WORD);
extern void CDECL __wine_make_gdi_object_system( HGDIOBJ handle, BOOL set );
extern void CDECL __wine_set_visible_region( HDC hdc, HRGN hrgn, const RECT *vis_rect,
const RECT *device_rect, struct window_surface *surface );
extern void CDECL __wine_set_display_driver( HMODULE module );
extern struct opengl_funcs * CDECL __wine_get_wgl_driver( HDC hdc, UINT version );
#endif /* __WINE_WINE_GDI_DRIVER_H */

View File

@ -66,10 +66,7 @@ Escape(
if (ulObjType == GDILoObjType_LO_METADC16_TYPE)
{
/* FIXME we do not support metafile */
UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return SP_ERROR;
return METADC16_Escape(hdc, nEscape, cbInput, lpvInData, lpvOutData);
}
switch (nEscape)

View File

@ -13,31 +13,19 @@ Arc(
_In_ INT xEndArc,
_In_ INT yEndArc)
{
#if 0
// Handle something other than a normal dc object.
if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
// Call Wine (rewrite of) MFDRV_MetaParam8
return MFDRV_MetaParam8( hDC, META_ARC, a1, a2, a3, a4, a5, a6, a7, a8)
else
{
PLDC pLDC = GdiGetLDC(hDC);
if ( !pLDC )
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (pLDC->iType == LDC_EMFLDC)
{
// Call Wine (rewrite of) EMFDRV_ArcChordPie
BOOL Ret = EMFDRV_ArcChordPie( hDC, a1, a2, a3, a4, a5, a6, a7, a8, EMR_ARC);
return Ret;
}
return FALSE;
}
}
#endif
HANDLE_METADC(BOOL,
Arc,
FALSE,
hdc,
xLeft,
yTop,
xRight,
yBottom,
xStartArc,
yStartArc,
xEndArc,
yEndArc);
return NtGdiArcInternal(GdiTypeArc,
hdc,
xLeft,
@ -64,29 +52,16 @@ AngleArc(
_In_ FLOAT eStartAngle,
_In_ FLOAT eSweepAngle)
{
#if 0
// Handle something other than a normal dc object.
if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
return FALSE; //No meta support for AngleArc
else
{
PLDC pLDC = GdiGetLDC(hDC);
if ( !pLDC )
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (pLDC->iType == LDC_EMFLDC)
{
BOOL Ret = EMFDRV_AngleArc( hDC, X, Y, Radius, StartAngle, SweepAngle);
return Ret;
}
return FALSE;
}
}
#endif
HANDLE_METADC(BOOL,
AngleArc,
FALSE,
hdc,
x,
y,
dwRadius,
RCAST(DWORD, eStartAngle),
RCAST(DWORD, eSweepAngle));
return NtGdiAngleArc(hdc,
x,
y,
@ -108,29 +83,19 @@ ArcTo(
_In_ INT xRadial2,
_In_ INT yRadial2)
{
#if 0
// Handle something other than a normal dc object.
if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
return FALSE; //No meta support for ArcTo
else
{
PLDC pLDC = GdiGetLDC(hDC);
if ( !pLDC )
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (pLDC->iType == LDC_EMFLDC)
{
BOOL Ret = EMFDRV_ArcChordPie( hDC, a1, a2, a3, a4, a5, a6, a7, a8, EMR_ARCTO);
return Ret;
}
return FALSE;
}
}
#endif
HANDLE_METADC(BOOL,
ArcTo,
FALSE,
hdc,
xLeft,
yTop,
xRight,
yBottom,
xRadial1,
yRadial1,
xRadial2,
yRadial2);
return NtGdiArcInternal(GdiTypeArcTo,
hdc,
xLeft,
@ -156,29 +121,19 @@ Chord(
_In_ INT xRadial2,
_In_ INT yRadial2)
{
#if 0
// Handle something other than a normal dc object.
if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
return MFDRV_MetaParam8( hDC, META_CHORD, a1, a2, a3, a4, a5, a6, a7, a8)
else
{
PLDC pLDC = GdiGetLDC(hDC);
if ( !pLDC )
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (pLDC->iType == LDC_EMFLDC)
{
BOOL Ret = EMFDRV_ArcChordPie( hDC, a1, a2, a3, a4, a5, a6, a7, a8, EMR_CHORD);
return Ret;
}
return FALSE;
}
}
#endif
HANDLE_METADC(BOOL,
Chord,
FALSE,
hdc,
xLeft,
yTop,
xRight,
yBottom,
xRadial1,
yRadial1,
xRadial2,
yRadial2);
return NtGdiArcInternal(GdiTypeChord,
hdc,
xLeft,
@ -208,29 +163,19 @@ Pie(
_In_ INT xRadial2,
_In_ INT yRadial2)
{
#if 0
// Handle something other than a normal dc object.
if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
return MFDRV_MetaParam8( hDC, META_PIE, a1, a2, a3, a4, a5, a6, a7, a8)
else
{
PLDC pLDC = GdiGetLDC(hDC);
if ( !pLDC )
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (pLDC->iType == LDC_EMFLDC)
{
BOOL Ret = EMFDRV_ArcChordPie( hDC, a1, a2, a3, a4, a5, a6, a7, a8, EMR_PIE);
return Ret;
}
return FALSE;
}
}
#endif
HANDLE_METADC(BOOL,
Pie,
FALSE,
hdc,
xLeft,
yTop,
xRight,
yBottom,
xRadial1,
yRadial1,
xRadial2,
yRadial2);
return NtGdiArcInternal(GdiTypePie,
hdc,
xLeft,

View File

@ -631,50 +631,21 @@ SetDIBitsToDevice(
if (!pConvertedInfo)
return 0;
#if 0
// Handle something other than a normal dc object.
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
return MFDRV_SetDIBitsToDevice( hdc,
XDest,
YDest,
Width,
Height,
XSrc,
YSrc,
StartScan,
ScanLines,
Bits,
lpbmi,
ColorUse);
else
{
PLDC pLDC = GdiGetLDC(hdc);
if ( !pLDC )
{
SetLastError(ERROR_INVALID_HANDLE);
return 0;
}
if (pLDC->iType == LDC_EMFLDC)
{
return EMFDRV_SetDIBitsToDevice(hdc,
XDest,
YDest,
Width,
Height,
XSrc,
YSrc,
StartScan,
ScanLines,
Bits,
lpbmi,
ColorUse);
}
return 0;
}
}
#endif
HANDLE_METADC(INT,
SetDIBitsToDevice,
0,
hdc,
XDest,
YDest,
Width,
Height,
XSrc,
YSrc,
StartScan,
ScanLines,
Bits,
lpbmi,
ColorUse);
if ((pConvertedInfo->bmiHeader.biCompression == BI_RLE8) ||
(pConvertedInfo->bmiHeader.biCompression == BI_RLE4))

View File

@ -139,6 +139,12 @@ SetMapMode(
{
PDC_ATTR pdcattr;
/* Handle METADC16 here, since we don't have a DCATTR. */
if (GDI_HANDLE_GET_TYPE(hdc) == GDILoObjType_LO_METADC16_TYPE) \
{
return GetAndSetDCDWord(hdc, GdiGetSetMapMode, iMode, 0, 0, 0 );
}
/* Get the DC attribute */
pdcattr = GdiGetDcAttr(hdc);
if (pdcattr == NULL)
@ -147,27 +153,13 @@ SetMapMode(
return 0;
}
#if 0
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
return MFDRV_SetMapMode(hdc, iMode);
else
{
SetLastError(ERROR_INVALID_HANDLE);
return 0;
}
}
#endif
/* Force change if Isotropic is set for recompute. */
if ((iMode != pdcattr->iMapMode) || (iMode == MM_ISOTROPIC))
{
pdcattr->ulDirty_ &= ~SLOW_WIDTHS;
return GetAndSetDCDWord(hdc, GdiGetSetMapMode, iMode, 0, 0, 0);
return GetAndSetDCDWord(hdc, GdiGetSetMapMode, iMode, 0, 0, 0 );
}
/* Simply return the old mode, which equals the new mode */
return pdcattr->iMapMode;
}
@ -324,30 +316,10 @@ ModifyWorldTransform(
{
PDC_ATTR pdcattr;
#if 0
// Handle something other than a normal dc object.
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
return FALSE;
else
{
PLDC pLDC = GdiGetLDC(hdc);
if ( !pLDC )
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (pLDC->iType == LDC_EMFLDC)
{
if (dwMode == MWT_MAX+1)
if (!EMFDRV_SetWorldTransform(hdc, pxform) ) return FALSE;
return EMFDRV_ModifyWorldTransform(hdc, pxform, dwMode); // Ported from wine.
}
return FALSE;
}
}
#endif
if (GDI_HANDLE_GET_TYPE(hdc) == GDILoObjType_LO_METADC16_TYPE)
return FALSE;
HANDLE_METADC(BOOL, ModifyWorldTransform, FALSE, hdc, pxform, dwMode);
/* Get the DC attribute */
pdcattr = GdiGetDcAttr(hdc);
@ -488,26 +460,8 @@ SetViewportExtEx(
_Out_opt_ LPSIZE lpSize)
{
PDC_ATTR pdcattr;
#if 0
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
return MFDRV_SetViewportExtEx();
else
{
PLDC pLDC = GdiGetLDC(hdc);
if ( !pLDC )
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (pLDC->iType == LDC_EMFLDC)
{
return EMFDRV_SetViewportExtEx();
}
}
}
#endif
HANDLE_METADC(BOOL, SetViewportExtEx, FALSE, hdc, nXExtent, nYExtent, lpSize);
/* Get the DC attribute */
pdcattr = GdiGetDcAttr(hdc);
@ -569,28 +523,10 @@ SetWindowOrgEx(
_In_ int Y,
_Out_opt_ LPPOINT lpPoint)
{
#if 0
PDC_ATTR pdcattr;
#if 0
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
return MFDRV_SetWindowOrgEx();
else
{
PLDC pLDC = GdiGetLDC(hdc);
if ( !pLDC )
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (pLDC->iType == LDC_EMFLDC)
{
return EMFDRV_SetWindowOrgEx();
}
}
}
#endif
HANDLE_METADC(BOOL, SetWindowOrgEx, FALSE, hdc, X, Y, lpPoint);
/* Get the DC attribute */
pdcattr = GdiGetDcAttr(hdc);
if (pdcattr == NULL)
@ -598,7 +534,7 @@ SetWindowOrgEx(
/* Do not set LastError here! */
return FALSE;
}
#if 0
if (lpPoint)
{
lpPoint->x = pdcattr->ptlWindowOrg.x;
@ -624,7 +560,7 @@ SetWindowOrgEx(
pdcattr->flXform |= (PAGE_XLATE_CHANGED|DEVICE_TO_WORLD_INVALID);
return TRUE;
#endif
return NtGdiSetWindowOrgEx(hdc,X,Y,lpPoint);
return NtGdiSetWindowOrgEx(hdc, X, Y, lpPoint);
}
/*
@ -639,28 +575,8 @@ SetWindowExtEx(
_Out_opt_ LPSIZE lpSize)
{
PDC_ATTR pdcattr;
ULONG ulType;
/* Check what type of DC that is */
ulType = GDI_HANDLE_GET_TYPE(hdc);
switch (ulType)
{
case GDILoObjType_LO_ALTDC_TYPE:
case GDILoObjType_LO_DC_TYPE:
/* Handle this in the path below */
break;
#if 0// FIXME: we don't support this
case GDILoObjType_LO_METADC16_TYPE:
return MFDRV_SetWindowExtEx(hdc, nXExtent, nYExtent, lpSize);
case GDILoObjType_LO_METAFILE_TYPE:
return EMFDRV_SetWindowExtEx(hdc, nXExtent, nYExtent, lpSize);
#endif
default:
/* Other types are not allowed */
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
HANDLE_METADC(BOOL, SetWindowExtEx, FALSE, hdc, nXExtent, nYExtent, lpSize);
/* Get the DC attr */
pdcattr = GdiGetDcAttr(hdc);
@ -729,28 +645,9 @@ SetViewportOrgEx(
_In_ int Y,
_Out_opt_ LPPOINT lpPoint)
{
#if 0
PDC_ATTR pdcattr;
#if 0
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
return MFDRV_SetViewportOrgEx();
else
{
PLDC pLDC = GdiGetLDC(hdc);
if ( !pLDC )
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (pLDC->iType == LDC_EMFLDC)
{
return EMFDRV_SetViewportOrgEx();
}
}
}
#endif
HANDLE_METADC(BOOL, SetViewportOrgEx, FALSE, hdc, X, Y, lpPoint);
/* Get the DC attribute */
pdcattr = GdiGetDcAttr(hdc);
@ -760,6 +657,7 @@ SetViewportOrgEx(
return FALSE;
}
#if 0
if (lpPoint)
{
lpPoint->x = pdcattr->ptlViewportOrg.x;
@ -788,26 +686,8 @@ ScaleViewportExtEx(
_In_ INT yDenom,
_Out_ LPSIZE lpSize)
{
#if 0
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(a0) == GDI_OBJECT_TYPE_METADC)
return MFDRV_;
else
{
PLDC pLDC = GdiGetLDC(hdc);
if ( !pLDC )
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (pLDC->iType == LDC_EMFLDC)
{
return EMFDRV_;
}
}
}
#endif
HANDLE_METADC(BOOL, ScaleViewportExtEx, FALSE, hdc, xNum, xDenom, yNum, yDenom, lpSize);
if (!GdiGetDcAttr(hdc))
{
SetLastError(ERROR_INVALID_PARAMETER);
@ -830,26 +710,7 @@ ScaleWindowExtEx(
_In_ INT yDenom,
_Out_ LPSIZE lpSize)
{
#if 0
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
return MFDRV_;
else
{
PLDC pLDC = GdiGetLDC(hdc);
if ( !pLDC )
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (pLDC->iType == LDC_EMFLDC)
{
return EMFDRV_;
}
}
}
#endif
HANDLE_METADC(BOOL, ScaleWindowExtEx, FALSE, hdc, xNum, xDenom, yNum, yDenom, lpSize);
if (!GdiGetDcAttr(hdc))
{
@ -899,26 +760,8 @@ SetLayout(
_In_ HDC hdc,
_In_ DWORD dwLayout)
{
#if 0
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
return MFDRV_SetLayout( hdc, dwLayout);
else
{
PLDC pLDC = GdiGetLDC(hdc);
if ( !pLDC )
{
SetLastError(ERROR_INVALID_HANDLE);
return 0;
}
if (pLDC->iType == LDC_EMFLDC)
{
return EMFDRV_SetLayout( hdc, dwLayout);
}
}
}
#endif
HANDLE_METADC(DWORD, SetLayout, GDI_ERROR, hdc, dwLayout);
if (!GdiGetDcAttr(hdc))
{
SetLastError(ERROR_INVALID_PARAMETER);
@ -950,7 +793,7 @@ SetLayoutWidth(
return GDI_ERROR;
}
return NtGdiSetLayout( hdc, wox, dwLayout);
return NtGdiSetLayout(hdc, wox, dwLayout);
}
/*
@ -997,28 +840,11 @@ OffsetViewportOrgEx(
_In_ int nYOffset,
_Out_opt_ LPPOINT lpPoint)
{
//PDC_ATTR pdcattr;
HANDLE_METADC(BOOL, OffsetViewportOrgEx, FALSE, hdc, nXOffset, nYOffset, lpPoint);
#if 0
PDC_ATTR pdcattr;
#if 0
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
return MFDRV_OffsetViewportOrgEx(hdc, nXOffset, nYOffset, lpPoint);
else
{
PLDC pLDC = GdiGetLDC(hdc);
if ( !pLDC )
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (pLDC->iType == LDC_EMFLDC)
{
return EMFDRV_OffsetWindowOrgEx(hdc, nXOffset, nYOffset, lpPoint);
}
}
}
#endif
/* Get the DC attribute */
pdcattr = GdiGetDcAttr(hdc);
if (!pdcattr)
@ -1066,28 +892,11 @@ OffsetWindowOrgEx(
_In_ int nYOffset,
_Out_opt_ LPPOINT lpPoint)
{
//PDC_ATTR pdcattr;
HANDLE_METADC(BOOL, OffsetWindowOrgEx, FALSE, hdc, nXOffset, nYOffset, lpPoint);
#if 0
PDC_ATTR pdcattr;
#if 0
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
return MFDRV_OffsetWindowOrgEx(hdc, nXOffset, nYOffset, lpPoint);
else
{
PLDC pLDC = GdiGetLDC(hdc);
if ( !pLDC )
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (pLDC->iType == LDC_EMFLDC)
{
return EMFDRV_OffsetWindowOrgEx(hdc, nXOffset, nYOffset, lpPoint);
}
}
}
#endif
/* Get the DC attribute */
pdcattr = GdiGetDcAttr(hdc);
if (!pdcattr)

View File

@ -289,19 +289,7 @@ DeleteDC(HDC hdc)
if (hType != GDILoObjType_LO_DC_TYPE)
{
if ( !pLDC || hType == GDILoObjType_LO_METADC16_TYPE)
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (pLDC->Flags & LDC_INIT_DOCUMENT) AbortDoc(hdc);
if (pLDC->hPrinter)
{
DocumentEventEx(NULL, pLDC->hPrinter, hdc, DOCUMENTEVENT_DELETEDC, 0, NULL, 0, NULL);
hPrinter = pLDC->hPrinter;
pLDC->hPrinter = NULL;
}
return METADC_DeleteDC(hdc);
}
bResult = NtGdiDeleteObjectApp(hdc);
@ -326,7 +314,7 @@ INT
WINAPI
SaveDC(IN HDC hdc)
{
/* FIXME Sharememory */
HANDLE_METADC0P(INT, SaveDC, 0, hdc);
return NtGdiSaveDC(hdc);
}
@ -339,7 +327,7 @@ WINAPI
RestoreDC(IN HDC hdc,
IN INT iLevel)
{
/* FIXME Sharememory */
HANDLE_METADC(BOOL, RestoreDC, FALSE, hdc, iLevel);
return NtGdiRestoreDC(hdc, iLevel);
}
@ -389,8 +377,8 @@ GetArcDirection(
INT
WINAPI
SetArcDirection(
_In_ HDC hdc,
_In_ INT nDirection)
_In_ HDC hdc,
_In_ INT nDirection)
{
return GetAndSetDCDWord(hdc, GdiGetSetArcDirection, nDirection, 0, 0, 0);
}
@ -576,48 +564,21 @@ GetDeviceCaps(
_In_ int nIndex)
{
PDC_ATTR pdcattr;
PLDC pLDC;
PDEVCAPS pDevCaps = GdiDevCaps; // Primary display device capabilities.
DPRINT("Device CAPS1\n");
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
{
if (nIndex == TECHNOLOGY) return DT_METAFILE;
return 0;
}
else
{
pLDC = GdiGetLDC(hdc);
if ( !pLDC )
{
SetLastError(ERROR_INVALID_HANDLE);
return 0;
}
if (!(pLDC->Flags & LDC_DEVCAPS))
{
if (!NtGdiGetDeviceCapsAll(hdc, &pLDC->DevCaps))
SetLastError(ERROR_INVALID_PARAMETER);
pLDC->Flags |= LDC_DEVCAPS;
}
pDevCaps = &pLDC->DevCaps;
}
}
else
{
/* Get the DC attribute */
pdcattr = GdiGetDcAttr(hdc);
if (pdcattr == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
HANDLE_METADC(INT, GetDeviceCaps, 0, hdc, nIndex);
if (!(pdcattr->ulDirty_ & DC_PRIMARY_DISPLAY) )
return NtGdiGetDeviceCaps(hdc, nIndex);
/* Get the DC attribute */
pdcattr = GdiGetDcAttr(hdc);
if (pdcattr == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
DPRINT("Device CAPS2\n");
if (!(pdcattr->ulDirty_ & DC_PRIMARY_DISPLAY))
return NtGdiGetDeviceCaps(hdc, nIndex);
switch (nIndex)
{
@ -781,35 +742,14 @@ GetAndSetDCDWord(
_In_ DWORD dwError)
{
DWORD dwResult;
BOOL Ret = TRUE;
/* Handle something other than a normal dc object. */
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
return 0; //call MFDRV
else
{
PLDC pLDC = GdiGetLDC(hdc);
if ( !pLDC )
{
SetLastError(ERROR_INVALID_HANDLE);
return 0;
}
if (pLDC->iType == LDC_EMFLDC)
{
Ret = TRUE; //call EMFDRV
if (Ret)
return u;
return 0;
}
}
}
/* This is a special API, handle it appropriately */
HANDLE_METADC2(DWORD, GetAndSetDCDWord, hdc, u, dwIn, ulMFId, usMF16Id, dwError);
/* Call win32k to do the real work */
if (!NtGdiGetAndSetDCDword(hdc, u, dwIn, &dwResult))
{
SetLastError(ERROR_INVALID_HANDLE);
return 0;
return dwError;
}
return dwResult;
@ -888,7 +828,7 @@ WINAPI
GetClipBox(HDC hdc,
LPRECT lprc)
{
return NtGdiGetAppClipBox(hdc, lprc);
return NtGdiGetAppClipBox(hdc, lprc);
}
@ -954,6 +894,9 @@ SetDCBrushColor(
return CLR_INVALID;
}
/* We handle only enhanced meta DCs here */
HANDLE_METADC(COLORREF, SetDCBrushColor, CLR_INVALID, hdc, crColor);
/* Get old color and store the new */
crOldColor = pdcattr->ulBrushClr;
pdcattr->ulBrushClr = crColor;
@ -987,6 +930,9 @@ SetDCPenColor(
return CLR_INVALID;
}
/* We handle only enhanced meta DCs here */
HANDLE_METADC(COLORREF, SetDCPenColor, CLR_INVALID, hdc, crColor);
/* Get old color and store the new */
crOldColor = pdcattr->ulPenClr;
pdcattr->ulPenClr = (ULONG)crColor;
@ -1034,6 +980,8 @@ SetBkColor(
PDC_ATTR pdcattr;
COLORREF crOldColor;
HANDLE_METADC(COLORREF, SetBkColor, CLR_INVALID, hdc, crColor);
/* Get the DC attribute */
pdcattr = GdiGetDcAttr(hdc);
if (pdcattr == NULL)
@ -1042,27 +990,6 @@ SetBkColor(
return CLR_INVALID;
}
#if 0
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
return MFDRV_SetBkColor(hdc, crColor );
else
{
PLDC pLDC = pdcattr->pvLDC;
if ( !pLDC )
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (pLDC->iType == LDC_EMFLDC)
{
return EMFDRV_SetBkColor(hdc, crColor );
}
}
}
#endif
/* Get old color and store the new */
crOldColor = pdcattr->ulBackgroundClr;
pdcattr->ulBackgroundClr = crColor;
@ -1110,6 +1037,8 @@ SetBkMode(
PDC_ATTR pdcattr;
INT iOldMode;
HANDLE_METADC(INT, SetBkMode, 0, hdc, iBkMode);
/* Get the DC attribute */
pdcattr = GdiGetDcAttr(hdc);
if (pdcattr == NULL)
@ -1118,27 +1047,6 @@ SetBkMode(
return 0;
}
#if 0
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
return MFDRV_SetBkMode( hdc, iBkMode )
else
{
PLDC pLDC = pdcattr->pvLDC;
if ( !pLDC )
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (pLDC->iType == LDC_EMFLDC)
{
return EMFDRV_SetBkMode(hdc, iBkMode)
}
}
}
#endif
iOldMode = pdcattr->lBkMode;
pdcattr->jBkMode = iBkMode; // Processed
pdcattr->lBkMode = iBkMode; // Raw
@ -1180,28 +1088,7 @@ SetROP2(
PDC_ATTR pdcattr;
INT rop2Old;
#if 0
// Handle something other than a normal dc object.
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
return MFDRV_SetROP2( hdc, rop2);
else
{
PLDC pLDC = GdiGetLDC(hdc);
if ( !pLDC )
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (pLDC->iType == LDC_EMFLDC)
{
return EMFDRV_SetROP2(( hdc, rop2);
}
return FALSE;
}
}
#endif
HANDLE_METADC(INT, SetROP2, 0, hdc, rop2);
/* Get the DC attribute */
pdcattr = GdiGetDcAttr(hdc);
@ -1261,26 +1148,7 @@ SetPolyFillMode(
INT iOldPolyFillMode;
PDC_ATTR pdcattr;
#if 0
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
return MFDRV_SetPolyFillMode( hdc, iPolyFillMode )
else
{
PLDC pLDC = GdiGetLDC(hdc);
if ( !pLDC )
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (pLDC->iType == LDC_EMFLDC)
{
return EMFDRV_SetPolyFillMode( hdc, iPolyFillMode )
}
}
}
#endif
HANDLE_METADC(INT, SetPolyFillMode, 0, hdc, iPolyFillMode);
/* Get the DC attribute */
pdcattr = GdiGetDcAttr(hdc);
@ -1423,26 +1291,8 @@ SelectPalette(
HPALETTE hpal,
BOOL bForceBackground)
{
#if 0
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
return MFDRV_SelectPalette(hdc, hpal, bForceBackground);
else
{
PLDC pLDC = GdiGetLDC(hdc);
if ( !pLDC )
{
SetLastError(ERROR_INVALID_HANDLE);
return NULL;
}
if (pLDC->iType == LDC_EMFLDC)
{
if return EMFDRV_SelectPalette(hdc, hpal, bForceBackground);
}
}
}
#endif
HANDLE_METADC(HPALETTE, SelectPalette, NULL, hdc, hpal, bForceBackground);
return NtUserSelectPalette(hdc, hpal, bForceBackground);
}
@ -1478,26 +1328,9 @@ SetStretchBltMode(
{
INT iOldMode;
PDC_ATTR pdcattr;
#if 0
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
return MFDRV_SetStretchBltMode( hdc, iStretchMode);
else
{
PLDC pLDC = GdiGetLDC(hdc);
if ( !pLDC )
{
SetLastError(ERROR_INVALID_HANDLE);
return 0;
}
if (pLDC->iType == LDC_EMFLDC)
{
return EMFDRV_SetStretchBltMode( hdc, iStretchMode);
}
}
}
#endif
HANDLE_METADC(INT, SetStretchBltMode, 0, hdc, iStretchMode);
/* Get the DC attribute */
pdcattr = GdiGetDcAttr(hdc);
if (pdcattr == NULL)
@ -1558,6 +1391,8 @@ GdiSelectBrush(
PDC_ATTR pdcattr;
HBRUSH hbrOld;
HANDLE_METADC(HBRUSH, SelectBrush, NULL, hdc, hbr);
/* Get the DC attribute */
pdcattr = GdiGetDcAttr(hdc);
if (pdcattr == NULL)
@ -1586,6 +1421,8 @@ GdiSelectPen(
PDC_ATTR pdcattr;
HPEN hpenOld;
HANDLE_METADC(HPEN, SelectPen, NULL, hdc, hpen);
/* Get the DC attribute */
pdcattr = GdiGetDcAttr(hdc);
if (pdcattr == NULL)
@ -1614,6 +1451,8 @@ GdiSelectFont(
PDC_ATTR pdcattr;
HFONT hfontOld;
HANDLE_METADC(HFONT, SelectFont, NULL, hdc, hfont);
/* Get the DC attribute */
pdcattr = GdiGetDcAttr(hdc);
if (pdcattr == NULL)

View File

@ -3,690 +3,6 @@
#define NDEBUG
#include <debug.h>
/*
* @unimplemented
*/
HENHMETAFILE
WINAPI
CloseEnhMetaFile(
HDC hdc)
{
UNIMPLEMENTED;
return 0;
}
#if 0 // Remove once new EnhMetaFile support is implemented.
HDC
WINAPI
CreateEnhMetaFileW(
HDC hDC, /* [in] optional reference DC */
LPCWSTR filename, /* [in] optional filename for disk metafiles */
const RECT* rect, /* [in] optional bounding rectangle */
LPCWSTR description /* [in] optional description */
)
{
HDC mDC;
PDC_ATTR Dc_Attr;
PLDC pLDC;
HANDLE hFile;
PENHMETAFILE EmfDC;
DWORD size = 0, length = 0;
mDC = NtGdiCreateMetafileDC( hDC ); // Basically changes the handle from 1xxxx to 46xxxx.
// If hDC == NULL, works just like createdc in win32k.
if ( !GdiGetHandleUserData((HGDIOBJ) mDC, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr))
{
SetLastError (ERROR_INVALID_PARAMETER);
return NULL; // need to delete the handle?
}
pLDC = LocalAlloc(LMEM_ZEROINIT, sizeof(LDC));
Dc_Attr->pvLDC = pLDC;
pLDC->hDC = mDC;
pLDC->iType = LDC_EMFDC
if (description)
{
/* App name\0Title\0\0 */
length = lstrlenW(description);
length += lstrlenW(description + length + 1);
length += 3;
length *= 2;
}
size = sizeof(ENHMETAFILE) + (length + 3) / 4 * 4;
//Allocate ENHMETAFILE structure
EmfDC = LocalAlloc(LMEM_ZEROINIT, sizeof(ENHMETAFILE));
pLDC->pvEmfDC = EmfDC;
EmfDC->handles_size = HANDLE_LIST_INC;
EmfDC->cur_handles = 1;
EmfDC->horzres = GetDeviceCaps(mDC, HORZRES);
EmfDC->vertres = GetDeviceCaps(mDC, VERTRES);
EmfDC->logpixelsx = GetDeviceCaps(mDC, LOGPIXELSX);
EmfDC->logpixelsy = GetDeviceCaps(mDC, LOGPIXELSY);
EmfDC->horzsize = GetDeviceCaps(mDC, HORZSIZE);
EmfDC->vertsize = GetDeviceCaps(mDC, VERTSIZE);
EmfDC->bitspixel = GetDeviceCaps(mDC, BITSPIXEL);
EmfDC->textcaps = GetDeviceCaps(mDC, TEXTCAPS);
EmfDC->rastercaps = GetDeviceCaps(mDC, RASTERCAPS);
EmfDC->technology = GetDeviceCaps(mDC, TECHNOLOGY);
EmfDC->planes = GetDeviceCaps(mDC, PLANES);
EmfDC->emf = LocalAlloc(LMEM_ZEROINIT, size);
EmfDC->emf->iType = EMR_HEADER;
EmfDC->emf->nSize = size;
EmfDC->emf->rclBounds.left = EmfDC->emf->rclBounds.top = 0;
EmfDC->emf->rclBounds.right = EmfDC->emf->rclBounds.bottom = -1;
if(rect)
{
EmfDC->emf->rclFrame.left = rect->left;
EmfDC->emf->rclFrame.top = rect->top;
EmfDC->emf->rclFrame.right = rect->right;
EmfDC->emf->rclFrame.bottom = rect->bottom;
}
else
{
/* Set this to {0,0 - -1,-1} and update it at the end */
EmfDC->emf->rclFrame.left = EmfDC->emf->rclFrame.top = 0;
EmfDC->emf->rclFrame.right = EmfDC->emf->rclFrame.bottom = -1;
}
EmfDC->emf->dSignature = ENHMETA_SIGNATURE;
EmfDC->emf->nVersion = 0x10000;
EmfDC->emf->nBytes = pLDC->pvEmfDC->nSize;
EmfDC->emf->nRecords = 1;
EmfDC->emf->nHandles = 1;
EmfDC->emf->sReserved = 0; /* According to docs, this is reserved and must be 0 */
EmfDC->emf->nDescription = length / 2;
EmfDC->emf->offDescription = length ? sizeof(ENHMETAHEADER) : 0;
EmfDC->emf->nPalEntries = 0; /* I guess this should start at 0 */
/* Size in pixels */
EmfDC->emf->szlDevice.cx = EmfDC->horzres;
EmfDC->emf->szlDevice.cy = EmfDC->vertres;
/* Size in millimeters */
EmfDC->emf->szlMillimeters.cx = EmfDC->horzsize;
EmfDC->emf->szlMillimeters.cy = EmfDC->vertsize;
/* Size in micrometers */
EmfDC->emf->szlMicrometers.cx = EmfDC->horzsize * 1000;
EmfDC->emf->szlMicrometers.cy = EmfDC->vertsize * 1000;
RtlCopyMemory((char *)EmfDC->emf + sizeof(ENHMETAHEADER), description, length);
if (filename) /* disk based metafile */
{
if ((hFile = CreateFileW(filename, GENERIC_WRITE | GENERIC_READ, 0,
NULL, CREATE_ALWAYS, 0, 0)) == INVALID_HANDLE_VALUE)
{
EMFDRV_DeleteDC( EmfDC );
return NULL;
}
if (!WriteFile( hFile, (LPSTR)EmfDC->emf, size, NULL, NULL ))
{
EMFDRV_DeleteDC( EmfDC );
return NULL;
}
EmfDC.hFile = hFile;
EmfDC.iType = METAFILE_DISK;
}
else
EmfDC.iType = METAFILE_MEMORY;
return mDC;
}
#endif
/*
* @unimplemented
*/
HENHMETAFILE
WINAPI
CopyEnhMetaFileA(
HENHMETAFILE hemfSrc,
LPCSTR lpszFile)
{
NTSTATUS Status;
LPWSTR lpszFileW;
HENHMETAFILE rc = 0;
Status = HEAP_strdupA2W ( &lpszFileW, lpszFile );
if (!NT_SUCCESS (Status))
SetLastError (RtlNtStatusToDosError(Status));
else
{
rc = NULL;
HEAP_free ( lpszFileW );
}
return rc;
}
/*
* @unimplemented
*/
HDC
WINAPI
CreateEnhMetaFileA(
HDC hdcRef,
LPCSTR lpFileName,
CONST RECT *lpRect,
LPCSTR lpDescription)
{
NTSTATUS Status;
LPWSTR lpFileNameW, lpDescriptionW;
HDC rc = 0;
lpFileNameW = NULL;
if (lpFileName != NULL)
{
Status = HEAP_strdupA2W ( &lpFileNameW, lpFileName );
if (!NT_SUCCESS (Status))
SetLastError (RtlNtStatusToDosError(Status));
return rc;
}
lpDescriptionW = NULL;
if (lpDescription != NULL)
{
Status = HEAP_strdupA2W ( &lpDescriptionW, lpDescription );
if (!NT_SUCCESS (Status))
SetLastError (RtlNtStatusToDosError(Status));
return rc;
}
rc = NULL;
if (lpDescriptionW != NULL)
HEAP_free ( lpDescriptionW );
if (lpFileNameW != NULL)
HEAP_free ( lpFileNameW );
return rc;
}
#if 0
/* Previous implementation in win32k */
HDC
WINAPI
NtGdiCreateEnhMetaFile(HDC hDCRef,
LPCWSTR File,
CONST LPRECT Rect,
LPCWSTR Description)
{
PDC Dc;
HDC ret = NULL;
DWORD length = 0;
HDC tempHDC;
DWORD MemSize;
DWORD dwDesiredAccess;
tempHDC = hDCRef;
if (hDCRef == NULL)
{
/* FIXME ??
* Shall we create hdc NtGdiHdcCompatible hdc ??
*/
UNICODE_STRING DriverName;
RtlInitUnicodeString(&DriverName, L"DISPLAY");
//IntGdiCreateDC(&DriverName, NULL, NULL, NULL, FALSE);
tempHDC = NtGdiOpenDCW( &DriverName,
NULL,
NULL,
0, // DCW 0 and ICW 1.
NULL,
(PVOID) NULL,
(PVOID) NULL );
}
GDIOBJ_SetOwnership(GdiHandleTable, tempHDC, PsGetCurrentProcess());
DC_SetOwnership(tempHDC, PsGetCurrentProcess());
Dc = DC_LockDc(tempHDC);
if (Dc == NULL)
{
if (hDCRef == NULL)
{
NtGdiDeleteObjectApp(tempHDC);
}
SetLastWin32Error(ERROR_INVALID_HANDLE);
return NULL;
}
if(Description)
{
length = wcslen(Description);
length += wcslen(Description + length + 1);
length += 3;
length *= 2;
}
MemSize = sizeof(ENHMETAHEADER) + (length + 3) / 4 * 4;
if (!(Dc->emh = EngAllocMem(FL_ZERO_MEMORY, MemSize, 0)))
{
DC_UnlockDc(Dc);
if (hDCRef == NULL)
{
NtGdiDeleteObjectApp(tempHDC);
}
SetLastWin32Error(ERROR_INVALID_HANDLE);
return NULL;
}
Dc->emh->iType = EMR_HEADER;
Dc->emh->nSize = MemSize;
Dc->emh->rclBounds.left = Dc->emh->rclBounds.top = 0;
Dc->emh->rclBounds.right = Dc->emh->rclBounds.bottom = -1;
if(Rect)
{
Dc->emh->rclFrame.left = Rect->left;
Dc->emh->rclFrame.top = Rect->top;
Dc->emh->rclFrame.right = Rect->right;
Dc->emh->rclFrame.bottom = Rect->bottom;
}
else
{
/* Set this to {0,0 - -1,-1} and update it at the end */
Dc->emh->rclFrame.left = Dc->emh->rclFrame.top = 0;
Dc->emh->rclFrame.right = Dc->emh->rclFrame.bottom = -1;
}
Dc->emh->dSignature = ENHMETA_SIGNATURE;
Dc->emh->nVersion = 0x10000;
Dc->emh->nBytes = Dc->emh->nSize;
Dc->emh->nRecords = 1;
Dc->emh->nHandles = 1;
Dc->emh->sReserved = 0; /* According to docs, this is reserved and must be 0 */
Dc->emh->nDescription = length / 2;
Dc->emh->offDescription = length ? sizeof(ENHMETAHEADER) : 0;
Dc->emh->nPalEntries = 0; /* I guess this should start at 0 */
/* Size in pixels */
Dc->emh->szlDevice.cx = NtGdiGetDeviceCaps(tempHDC, HORZRES);
Dc->emh->szlDevice.cy = NtGdiGetDeviceCaps(tempHDC, VERTRES);
/* Size in millimeters */
Dc->emh->szlMillimeters.cx = NtGdiGetDeviceCaps(tempHDC, HORZSIZE);
Dc->emh->szlMillimeters.cy = NtGdiGetDeviceCaps(tempHDC, VERTSIZE);
/* Size in micrometers */
Dc->emh->szlMicrometers.cx = Dc->emh->szlMillimeters.cx * 1000;
Dc->emh->szlMicrometers.cy = Dc->emh->szlMillimeters.cy * 1000;
if(Description)
{
memcpy((char *)Dc->emh + sizeof(ENHMETAHEADER), Description, length);
}
ret = tempHDC;
if (File)
{
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatusBlock;
IO_STATUS_BLOCK Iosb;
UNICODE_STRING NtPathU;
NTSTATUS Status;
ULONG FileAttributes = (FILE_ATTRIBUTE_VALID_FLAGS & ~FILE_ATTRIBUTE_DIRECTORY);
DPRINT1("Trying Create EnhMetaFile\n");
/* disk based metafile */
dwDesiredAccess = GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE | FILE_READ_ATTRIBUTES;
if (!RtlDosPathNameToNtPathName_U (File, &NtPathU, NULL, NULL))
{
DC_UnlockDc(Dc);
if (hDCRef == NULL)
{
NtGdiDeleteObjectApp(tempHDC);
}
DPRINT1("Can not Create EnhMetaFile\n");
SetLastWin32Error(ERROR_PATH_NOT_FOUND);
return NULL;
}
InitializeObjectAttributes(&ObjectAttributes, &NtPathU, 0, NULL, NULL);
Status = NtCreateFile (&Dc->hFile, dwDesiredAccess, &ObjectAttributes, &IoStatusBlock,
NULL, FileAttributes, 0, FILE_OVERWRITE_IF, FILE_NON_DIRECTORY_FILE,
NULL, 0);
RtlFreeHeap(RtlGetProcessHeap(), 0, NtPathU.Buffer);
if (!NT_SUCCESS(Status))
{
Dc->hFile = NULL;
DC_UnlockDc(Dc);
if (hDCRef == NULL)
{
NtGdiDeleteObjectApp(tempHDC);
}
DPRINT1("Create EnhMetaFile fail\n");
SetLastWin32Error(ERROR_INVALID_HANDLE);
return NULL;
}
SetLastWin32Error(IoStatusBlock.Information == FILE_OVERWRITTEN ? ERROR_ALREADY_EXISTS : 0);
Status = NtWriteFile(Dc->hFile, NULL, NULL, NULL, &Iosb, (PVOID)&Dc->emh, Dc->emh->nSize, NULL, NULL);
if (Status == STATUS_PENDING)
{
Status = NtWaitForSingleObject(Dc->hFile,FALSE,NULL);
if (NT_SUCCESS(Status))
{
Status = Iosb.Status;
}
}
if (NT_SUCCESS(Status))
{
ret = tempHDC;
DC_UnlockDc(Dc);
}
else
{
Dc->hFile = NULL;
DPRINT1("Write to EnhMetaFile fail\n");
SetLastWin32Error(ERROR_CAN_NOT_COMPLETE);
ret = NULL;
DC_UnlockDc(Dc);
if (hDCRef == NULL)
{
NtGdiDeleteObjectApp(tempHDC);
}
}
}
else
{
DC_UnlockDc(Dc);
}
return ret;
}
#endif
/*
* @unimplemented
*/
HENHMETAFILE
WINAPI
GetEnhMetaFileA(
LPCSTR lpszMetaFile)
{
NTSTATUS Status;
LPWSTR lpszMetaFileW;
HENHMETAFILE rc = 0;
Status = HEAP_strdupA2W ( &lpszMetaFileW, lpszMetaFile );
if (!NT_SUCCESS (Status))
SetLastError (RtlNtStatusToDosError(Status));
else
{
rc = NULL;
HEAP_free ( lpszMetaFileW );
}
return rc;
}
/*
* @unimplemented
*/
UINT
WINAPI
GetEnhMetaFileDescriptionA(
HENHMETAFILE hemf,
UINT cchBuffer,
LPSTR lpszDescription)
{
NTSTATUS Status;
LPWSTR lpszDescriptionW;
if ( lpszDescription && cchBuffer )
{
lpszDescriptionW = (LPWSTR)HEAP_alloc ( cchBuffer*sizeof(WCHAR) );
if ( !lpszDescriptionW )
{
SetLastError (RtlNtStatusToDosError(STATUS_NO_MEMORY));
return 0;
}
}
else
lpszDescriptionW = NULL;
if ( lpszDescription && cchBuffer )
{
Status = RtlUnicodeToMultiByteN ( lpszDescription,
cchBuffer,
NULL,
lpszDescriptionW,
cchBuffer );
HEAP_free ( lpszDescriptionW );
if ( !NT_SUCCESS(Status) )
{
SetLastError (RtlNtStatusToDosError(Status));
return 0;
}
}
return 0;
}
/* Unimplemented functions */
HENHMETAFILE
WINAPI
CopyEnhMetaFileW(
HENHMETAFILE hemfSrc,
LPCWSTR lpszFile)
{
UNIMPLEMENTED;
return 0;
}
HENHMETAFILE
WINAPI
GetEnhMetaFileW(
LPCWSTR lpszMetaFile)
{
UNIMPLEMENTED;
return 0;
}
UINT
WINAPI
GetEnhMetaFileDescriptionW(
HENHMETAFILE hemf,
UINT cchBuffer,
LPWSTR lpszDescription)
{
UNIMPLEMENTED;
return 0;
}
HDC
WINAPI
CreateEnhMetaFileW(
HDC hdcRef,
LPCWSTR lpFileName,
LPCRECT lpRect,
LPCWSTR lpDescription)
{
UNIMPLEMENTED;
return 0;
}
/*
* @unimplemented
*/
BOOL
WINAPI
DeleteEnhMetaFile(
HENHMETAFILE a0
)
{
UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/*
* @unimplemented
*/
BOOL
WINAPI
EnumEnhMetaFile(
HDC hdc,
HENHMETAFILE hmf,
ENHMFENUMPROC callback,
LPVOID data,
CONST RECT *lpRect
)
{
if(!lpRect && hdc)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/*
* @unimplemented
*/
UINT
WINAPI
GetEnhMetaFileBits(
HENHMETAFILE a0,
UINT a1,
LPBYTE a2
)
{
UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/*
* @unimplemented
*/
HENHMETAFILE
WINAPI
SetEnhMetaFileBits(
UINT a0,
CONST BYTE *a1
)
{
UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/*
* @unimplemented
*/
UINT
WINAPI
GetEnhMetaFileHeader(
HENHMETAFILE a0,
UINT a1,
LPENHMETAHEADER a2
)
{
UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/*
* @unimplemented
*/
UINT
WINAPI
GetEnhMetaFilePaletteEntries(
HENHMETAFILE a0,
UINT a1,
LPPALETTEENTRY a2
)
{
UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/*
* @unimplemented
*/
BOOL
WINAPI
PlayEnhMetaFile(
HDC a0,
HENHMETAFILE a1,
CONST RECT *a2
)
{
UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/*
* @unimplemented
*/
BOOL
WINAPI
PlayEnhMetaFileRecord(
HDC a0,
LPHANDLETABLE a1,
CONST ENHMETARECORD *a2,
UINT a3
)
{
UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/*
* @unimplemented
*/
@ -746,33 +62,21 @@ GdiCreateLocalEnhMetaFile(HENHMETAFILE hmo)
}
/*
* @unimplemented
* @implemented
*/
BOOL
WINAPI
GdiComment(
HDC hDC,
UINT bytes,
CONST BYTE *buffer
)
_In_ HDC hdc,
_In_ UINT cbSize,
_In_ const BYTE *lpData)
{
#if 0
if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_EMF)
{
PLDC pLDC = GdiGetLDC(hDC);
if ( !pLDC )
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (pLDC->iType == LDC_EMFLDC)
{
// Wine port
return EMFDRV_GdiComment( hDC, bytes, buffer );
}
}
#endif
return FALSE;
if (GDI_HANDLE_GET_TYPE(hdc) != GDILoObjType_LO_ALTDC_TYPE)
return TRUE;
HANDLE_METADC(BOOL, GdiComment, FALSE, hdc, cbSize, lpData);
return TRUE;
}
/*

View File

@ -327,6 +327,12 @@ DeleteObject(HGDIOBJ hObject)
return TRUE;
}
/* If we have any METAFILE objects, we need to check them */
if (gcClientObj > 0)
{
METADC_DeleteObject(hObject);
}
/* Switch by object type */
switch (GDI_HANDLE_GET_TYPE(hObject))
{

View File

@ -1,321 +1,8 @@
#include <precomp.h>
#include <debug.h>
/* DEFINES *******************************************************************/
/* PRIVATE DATA **************************************************************/
PMF_ENTRY hMF_List = NULL;
DWORD hMFCount = 0;
/* INTERNAL FUNCTIONS ********************************************************/
BOOL
MF_CreateMFDC ( HGDIOBJ hMDC,
PMETAFILEDC pmfDC )
{
PMF_ENTRY pMFME;
pMFME = LocalAlloc(LMEM_ZEROINIT, sizeof(MF_ENTRY));
if (!pMFME)
{
return FALSE;
}
if (hMF_List == NULL)
{
hMF_List = pMFME;
InitializeListHead(&hMF_List->List);
}
else
InsertTailList(&hMF_List->List, &pMFME->List);
pMFME->hmDC = hMDC;
pMFME->pmfDC = pmfDC;
hMFCount++;
return TRUE;
}
PMETAFILEDC
MF_GetMFDC ( HGDIOBJ hMDC )
{
PMF_ENTRY pMFME = hMF_List;
do
{
if ( pMFME->hmDC == hMDC ) return pMFME->pmfDC;
pMFME = (PMF_ENTRY) pMFME->List.Flink;
}
while ( pMFME != hMF_List );
return NULL;
}
BOOL
MF_DeleteMFDC ( HGDIOBJ hMDC )
{
PMF_ENTRY pMFME = hMF_List;
do
{
if ( pMFME->hmDC == hMDC)
{
RemoveEntryList(&pMFME->List);
LocalFree ( pMFME );
hMFCount--;
if (!hMFCount) hMF_List = NULL;
return TRUE;
}
pMFME = (PMF_ENTRY) pMFME->List.Flink;
}
while ( pMFME != hMF_List );
return FALSE;
}
/* FUNCTIONS *****************************************************************/
/*
* @unimplemented
*/
HMETAFILE
WINAPI
CloseMetaFile(
HDC a0
)
{
return 0;
}
/*
* @implemented
*/
HMETAFILE
WINAPI
CopyMetaFileW(
HMETAFILE hmfSrc,
LPCWSTR lpszFile
)
{
return NULL;
}
/*
* @implemented
*/
HMETAFILE
WINAPI
CopyMetaFileA(
HMETAFILE hmfSrc,
LPCSTR lpszFile
)
{
NTSTATUS Status;
PWSTR lpszFileW;
HMETAFILE rc = 0;
Status = HEAP_strdupA2W ( &lpszFileW, lpszFile );
if (!NT_SUCCESS (Status))
SetLastError (RtlNtStatusToDosError(Status));
else
{
rc = CopyMetaFileW( hmfSrc, lpszFileW );
HEAP_free ( lpszFileW );
}
return rc;
}
/*
* @implemented
*/
HDC
WINAPI
CreateMetaFileW(
LPCWSTR lpszFile
)
{
HANDLE hFile;
HDC hmDC;
PMETAFILEDC pmfDC = LocalAlloc(LMEM_ZEROINIT, sizeof(METAFILEDC));
if (!pmfDC) return NULL;
pmfDC->mh.mtHeaderSize = sizeof(METAHEADER) / sizeof(WORD);
pmfDC->mh.mtVersion = 0x0300;
pmfDC->mh.mtSize = pmfDC->mh.mtHeaderSize;
pmfDC->hPen = GetStockObject(BLACK_PEN);
pmfDC->hBrush = GetStockObject(WHITE_BRUSH);
pmfDC->hFont = GetStockObject(DEVICE_DEFAULT_FONT);
pmfDC->hBitmap = GetStockObject(DEFAULT_BITMAP);
pmfDC->hPalette = GetStockObject(DEFAULT_PALETTE);
if (lpszFile) /* disk based metafile */
{
pmfDC->mh.mtType = METAFILE_DISK;
if(!GetFullPathName( lpszFile,
MAX_PATH,
(LPTSTR) &pmfDC->Filename,
(LPTSTR*) &lpszFile))
{
LocalFree(pmfDC);
return NULL;
}
if ((hFile = CreateFileW(pmfDC->Filename, GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, 0, 0)) == INVALID_HANDLE_VALUE)
{
LocalFree(pmfDC);
return NULL;
}
if (!WriteFile( hFile, &pmfDC->mh, sizeof(pmfDC->mh), &pmfDC->dwWritten, NULL ))
{
LocalFree(pmfDC);
return NULL;
}
pmfDC->hFile = hFile;
}
else /* memory based metafile */
pmfDC->mh.mtType = METAFILE_MEMORY;
hmDC = NtGdiCreateClientObj ( GDI_OBJECT_TYPE_METADC );
MF_CreateMFDC ( hmDC, pmfDC );
return hmDC;
}
/*
* @implemented
*/
HDC
WINAPI
CreateMetaFileA(
LPCSTR lpszFile
)
{
NTSTATUS Status;
PWSTR lpszFileW;
HDC rc = 0;
Status = HEAP_strdupA2W ( &lpszFileW, lpszFile );
if (!NT_SUCCESS (Status))
SetLastError (RtlNtStatusToDosError(Status));
else
{
rc = CreateMetaFileW( lpszFileW );
HEAP_free ( lpszFileW );
}
return rc;
}
/*
* @unimplemented
*/
BOOL
WINAPI
DeleteMetaFile(
HMETAFILE a0
)
{
return FALSE;
}
/*
* @implemented
*/
HMETAFILE
WINAPI
GetMetaFileW(
LPCWSTR lpszMetaFile
)
{
return NULL;
}
/*
* @implemented
*/
HMETAFILE
WINAPI
GetMetaFileA(
LPCSTR lpszMetaFile
)
{
NTSTATUS Status;
LPWSTR lpszMetaFileW;
HMETAFILE rc = 0;
Status = HEAP_strdupA2W ( &lpszMetaFileW, lpszMetaFile );
if (!NT_SUCCESS (Status))
SetLastError (RtlNtStatusToDosError(Status));
else
{
rc = GetMetaFileW( lpszMetaFileW );
HEAP_free ( lpszMetaFileW );
}
return rc;
}
/*
* @unimplemented
*/
UINT
WINAPI
GetMetaFileBitsEx(
HMETAFILE a0,
UINT a1,
LPVOID a2
)
{
UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/*
* @unimplemented
*/
HMETAFILE
WINAPI
SetMetaFileBitsEx(
UINT size,
CONST BYTE *lpData
)
{
const METAHEADER *mh_in = (const METAHEADER *)lpData;
if (size & 1) return 0;
if (!size || mh_in->mtType != METAFILE_MEMORY || mh_in->mtVersion != 0x300 ||
mh_in->mtHeaderSize != sizeof(METAHEADER) / 2)
{
DPRINT1("SetMetaFileBitsEx failed: %lu,%lu,0x&lx,%lu\n",
size, mh_in->mtType, mh_in->mtVersion, mh_in->mtHeaderSize);
SetLastError(ERROR_INVALID_DATA);
return 0;
}
UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/*
* @implemented
*/
@ -323,95 +10,17 @@ BOOL
WINAPI
GdiIsPlayMetafileDC(HDC hDC)
{
#if 0
PLDC pLDC = GdiGetLDC(hDC);
if ( pLDC )
{
if ( pLDC->Flags & LDC_PLAY_MFDC ) return TRUE;
}
return FALSE;
}
/*
* @unimplemented
*/
BOOL
WINAPI
PlayMetaFile(
HDC a0,
HMETAFILE a1
)
{
#else
UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/*
* @unimplemented
*/
BOOL
WINAPI
PlayMetaFileRecord(
HDC a0,
LPHANDLETABLE a1,
LPMETARECORD a2,
UINT a3
)
{
UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/*
* @unimplemented
*/
BOOL
WINAPI
EnumMetaFile(
HDC a0,
HMETAFILE a1,
MFENUMPROC a2,
LPARAM a3
)
{
UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/*
* @unimplemented
*/
UINT
WINAPI
GetWinMetaFileBits(
HENHMETAFILE a0,
UINT a1,
LPBYTE a2,
INT a3,
HDC a4
)
{
UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/*
* @unimplemented
*/
HENHMETAFILE
WINAPI
SetWinMetaFileBits(
UINT a0,
CONST BYTE *a1,
HDC a2,
CONST METAFILEPICT *a3)
{
UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
#endif
}
/*
@ -419,23 +28,31 @@ SetWinMetaFileBits(
*/
BOOL
WINAPI
GdiIsMetaFileDC(HDC hDC)
GdiIsMetaFileDC(HDC hdc)
{
if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
ULONG ulObjType;
ulObjType = GDI_HANDLE_GET_TYPE(hdc);
if (ulObjType == GDILoObjType_LO_METADC16_TYPE)
{
if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
return TRUE;
else
{
PLDC pLDC = GdiGetLDC(hDC);
if ( !pLDC )
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if ( pLDC->iType == LDC_EMFLDC) return TRUE;
}
return TRUE;
}
if (ulObjType == GDILoObjType_LO_ALTDC_TYPE)
{
#if 0
PLDC pLDC = GdiGetLDC(hdc);
if ( !pLDC )
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if ( pLDC->iType == LDC_EMFLDC) return TRUE;
return FALSE;
#endif
return TRUE;
}
return FALSE;
}
@ -446,7 +63,7 @@ BOOL
WINAPI
GdiIsMetaPrintDC(HDC hDC)
{
#if 0
if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
@ -463,6 +80,10 @@ GdiIsMetaPrintDC(HDC hDC)
}
}
return FALSE;
#else
UNIMPLEMENTED;
return FALSE;
#endif
}
/*

View File

@ -11,28 +11,8 @@ LineTo(
_In_ INT x,
_In_ INT y )
{
#if 0
// Handle something other than a normal dc object.
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
return MFDRV_MetaParam2(hdc, META_LINETO, x, y);
else
{
PLDC pLDC = GdiGetLDC(hdc);
if (!pLDC)
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (pLDC->iType == LDC_EMFLDC)
{
return MFDRV_LineTo(hdc, x, y )
}
return FALSE;
}
}
#endif
HANDLE_METADC(BOOL, LineTo, FALSE, hdc, x, y);
return NtGdiLineTo(hdc, x, y);
}
@ -46,26 +26,9 @@ MoveToEx(
_Out_opt_ LPPOINT ppt)
{
PDC_ATTR pdcattr;
#if 0
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
return MFDRV_MetaParam2(hdc, META_MOVETO, x, y);
else
{
PLDC pLDC = pdcattr->pvLDC;
if ( !pLDC )
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (pLDC->iType == LDC_EMFLDC)
{
if (!EMFDRV_MoveTo(hdc, x, y)) return FALSE;
}
}
}
#endif
HANDLE_METADC(BOOL, MoveTo, FALSE, hdc, x, y, ppt);
/* Get the DC attribute */
pdcattr = GdiGetDcAttr(hdc);
if (pdcattr == NULL)
@ -110,28 +73,8 @@ Ellipse(
_In_ INT right,
_In_ INT bottom)
{
#if 0
// Handle something other than a normal dc object.
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
return MFDRV_MetaParam4(hdc, META_ELLIPSE, left, top, right, bottom );
else
{
PLDC pLDC = GdiGetLDC(hdc);
if ( !pLDC )
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (pLDC->iType == LDC_EMFLDC)
{
return EMFDRV_Ellipse(hdc, left, top, right, bottom );
}
return FALSE;
}
}
#endif
HANDLE_METADC(BOOL, Ellipse, FALSE, hdc, left, top, right, bottom);
return NtGdiEllipse(hdc, left, top, right, bottom);
}
@ -148,28 +91,8 @@ Rectangle(
_In_ INT right,
_In_ INT bottom)
{
#if 0
// Handle something other than a normal dc object.
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
return MFDRV_MetaParam4(hdc, META_RECTANGLE, left, top, right, bottom);
else
{
PLDC pLDC = GdiGetLDC(hdc);
if ( !pLDC )
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (pLDC->iType == LDC_EMFLDC)
{
return EMFDRV_Rectangle(hdc, left, top, right, bottom);
}
return FALSE;
}
}
#endif
HANDLE_METADC(BOOL, Rectangle, FALSE, hdc, left, top, right, bottom);
return NtGdiRectangle(hdc, left, top, right, bottom);
}
@ -188,30 +111,8 @@ RoundRect(
_In_ INT width,
_In_ INT height)
{
#if 0
// Handle something other than a normal dc object.
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
return MFDRV_MetaParam6(hdc, META_ROUNDRECT, left, top, right, bottom,
width, height );
else
{
PLDC pLDC = GdiGetLDC(hdc);
if ( !pLDC )
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (pLDC->iType == LDC_EMFLDC)
{
return EMFDRV_RoundRect(hdc, left, top, right, bottom,
width, height );
}
return FALSE;
}
}
#endif
HANDLE_METADC(BOOL, RoundRect, FALSE, hdc, left, top, right, bottom, width, height);
return NtGdiRoundRect(hdc, left, top, right, bottom, width, height);
}
@ -243,29 +144,8 @@ SetPixel(
_In_ INT y,
_In_ COLORREF crColor)
{
#if 0
// Handle something other than a normal dc object.
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
return MFDRV_MetaParam4(hdc, META_SETPIXEL, x, y, HIWORD(crColor),
LOWORD(crColor));
else
{
PLDC pLDC = GdiGetLDC(hdc);
if ( !pLDC )
{
SetLastError(ERROR_INVALID_HANDLE);
return 0;
}
if (pLDC->iType == LDC_EMFLDC)
{
return EMFDRV_SetPixel(hdc, x, y, crColor);
}
return 0;
}
}
#endif
HANDLE_METADC(COLORREF, SetPixel, CLR_INVALID, hdc, x, y, crColor);
return NtGdiSetPixel(hdc, x, y, crColor);
}
@ -298,28 +178,9 @@ FillRgn(
if ((hrgn == NULL) || (hbr == NULL))
return FALSE;
#if 0
// Handle something other than a normal dc object.
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
return MFDRV_FillRgn(hdc, hrgn, hbr);
else
{
PLDC pLDC = GdiGetLDC(hdc);
if ( !pLDC )
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (pLDC->iType == LDC_EMFLDC)
{
return EMFDRV_FillRgn((hdc, hrgn, hbr);
}
return FALSE;
}
}
#endif
HANDLE_METADC(BOOL, FillRgn, FALSE, hdc, hrgn, hbr);
return NtGdiFillRgn(hdc, hrgn, hbr);
}
@ -339,28 +200,9 @@ FrameRgn(
if ((hrgn == NULL) || (hbr == NULL))
return FALSE;
#if 0
// Handle something other than a normal dc object.
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
return MFDRV_FrameRgn(hdc, hrgn, hbr, nWidth, nHeight );
else
{
PLDC pLDC = GdiGetLDC(hdc);
if ( !pLDC )
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (pLDC->iType == LDC_EMFLDC)
{
return EMFDRV_FrameRgn(hdc, hrgn, hbr, nWidth, nHeight );
}
return FALSE;
}
}
#endif
HANDLE_METADC(BOOL, FrameRgn, FALSE, hdc, hrgn, hbr, nWidth, nHeight);
return NtGdiFrameRgn(hdc, hrgn, hbr, nWidth, nHeight);
}
@ -377,28 +219,9 @@ InvertRgn(
if (hrgn == NULL)
return FALSE;
#if 0
// Handle something other than a normal dc object.
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
return MFDRV_InvertRgn(hdc, HRGN hrgn ); // Use this instead of MFDRV_MetaParam.
else
{
PLDC pLDC = GdiGetLDC(hdc);
if ( !pLDC )
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (pLDC->iType == LDC_EMFLDC)
{
return EMFDRV_PaintInvertRgn(hdc, hrgn, EMR_INVERTRGN );
}
return FALSE;
}
}
#endif
HANDLE_METADC(BOOL, InvertRgn, FALSE, hdc, hrgn);
return NtGdiInvertRgn(hdc, hrgn);
}
@ -412,32 +235,7 @@ PaintRgn(
_In_ HDC hdc,
_In_ HRGN hrgn)
{
#if 0
// Handle something other than a normal dc object.
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
return MFDRV_PaintRgn(hdc, HRGN hrgn ); // Use this instead of MFDRV_MetaParam.
else
{
PLDC pLDC = GdiGetLDC(hdc);
if ( !pLDC )
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (pLDC->iType == LDC_EMFLDC)
{
return EMFDRV_PaintInvertRgn(hdc, hrgn, EMR_PAINTRGN );
}
return FALSE;
}
}
#endif
// Could just use pdcattr->hbrush? No.
HBRUSH hbr = GetCurrentObject(hdc, OBJ_BRUSH);
return NtGdiFillRgn(hdc, hrgn, hbr);
return FillRgn(hdc, hrgn, GetCurrentObject(hdc, OBJ_BRUSH));
}
@ -451,32 +249,8 @@ PolyBezier(
_In_reads_(cpt) const POINT *apt,
_In_ DWORD cpt)
{
#if 0
// Handle something other than a normal dc object.
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
/*
* Since MetaFiles don't record Beziers and they don't even record
* approximations to them using lines.
*/
return FALSE;
else
{
PLDC pLDC = GdiGetLDC(hdc);
if ( !pLDC )
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (pLDC->iType == LDC_EMFLDC)
{
return FALSE; // Not supported yet.
}
return FALSE;
}
}
#endif
HANDLE_METADC(BOOL, PolyBezier, FALSE, hdc, apt, cpt);
return NtGdiPolyPolyDraw(hdc ,(PPOINT)apt, &cpt, 1, GdiPolyBezier);
}
@ -491,28 +265,8 @@ PolyBezierTo(
_In_reads_(cpt) const POINT *apt,
_In_ DWORD cpt)
{
#if 0
// Handle something other than a normal dc object.
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
return FALSE;
else
{
PLDC pLDC = GdiGetLDC(hdc);
if ( !pLDC )
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (pLDC->iType == LDC_EMFLDC)
{
return FALSE; // Not supported yet.
}
return FALSE;
}
}
#endif
HANDLE_METADC(BOOL, PolyBezierTo, FALSE, hdc, apt, cpt);
return NtGdiPolyPolyDraw(hdc , (PPOINT)apt, &cpt, 1, GdiPolyBezierTo);
}
@ -528,28 +282,8 @@ PolyDraw(
_In_reads_(cpt) const BYTE *aj,
_In_ INT cpt)
{
#if 0
// Handle something other than a normal dc object.
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
return FALSE;
else
{
PLDC pLDC = GdiGetLDC(hdc);
if ( !pLDC )
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (pLDC->iType == LDC_EMFLDC)
{
return FALSE; // Not supported yet.
}
return FALSE;
}
}
#endif
HANDLE_METADC(BOOL, PolyDraw, FALSE, hdc, apt, aj, cpt);
return NtGdiPolyDraw(hdc, (PPOINT)apt, (PBYTE)aj, cpt);
}
@ -564,28 +298,8 @@ Polygon(
_In_reads_(cpt) const POINT *apt,
_In_ INT cpt)
{
#if 0
// Handle something other than a normal dc object.
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
return MFDRV_Polygon(hdc, apt, cpt );
else
{
PLDC pLDC = GdiGetLDC(hdc);
if ( !pLDC )
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (pLDC->iType == LDC_EMFLDC)
{
return EMFDRV_Polygon(hdc, apt, cpt );
}
return FALSE;
}
}
#endif
HANDLE_METADC(BOOL, Polygon, FALSE, hdc, apt, cpt);
return NtGdiPolyPolyDraw(hdc , (PPOINT)apt, (PULONG)&cpt, 1, GdiPolyPolygon);
}
@ -600,28 +314,8 @@ Polyline(
_In_reads_(cpt) const POINT *apt,
_In_ INT cpt)
{
#if 0
// Handle something other than a normal dc object.
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
return MFDRV_Polyline(hdc, apt, cpt);
else
{
PLDC pLDC = GdiGetLDC(hdc);
if ( !pLDC )
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (pLDC->iType == LDC_EMFLDC)
{
return EMFDRV_Polyline(hdc, apt, cpt);
}
return FALSE;
}
}
#endif
HANDLE_METADC(BOOL, Polyline, FALSE, hdc, apt, cpt);
return NtGdiPolyPolyDraw(hdc, (PPOINT)apt, (PULONG)&cpt, 1, GdiPolyPolyLine);
}
@ -636,28 +330,8 @@ PolylineTo(
_In_reads_(cpt) const POINT *apt,
_In_ DWORD cpt)
{
#if 0
// Handle something other than a normal dc object.
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
return FALSE;
else
{
PLDC pLDC = GdiGetLDC(hdc);
if ( !pLDC )
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (pLDC->iType == LDC_EMFLDC)
{
return FALSE; // Not supported yet.
}
return FALSE;
}
}
#endif
HANDLE_METADC(BOOL, PolylineTo, FALSE, hdc, apt, cpt);
return NtGdiPolyPolyDraw(hdc , (PPOINT)apt, &cpt, 1, GdiPolyLineTo);
}
@ -673,28 +347,8 @@ PolyPolygon(
_In_reads_(csz) const INT *asz,
_In_ INT csz)
{
#if 0
// Handle something other than a normal dc object.
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
return MFDRV_PolyPolygon(hdc, apt, asz, csz);
else
{
PLDC pLDC = GdiGetLDC(hdc);
if ( !pLDC )
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (pLDC->iType == LDC_EMFLDC)
{
return EMFDRV_PolyPolygon(hdc, apt, asz, csz );
}
return FALSE;
}
}
#endif
HANDLE_METADC(BOOL, PolyPolygon, FALSE, hdc, apt, asz, csz);
return NtGdiPolyPolyDraw(hdc, (PPOINT)apt, (PULONG)asz, csz, GdiPolyPolygon);
}
@ -710,28 +364,11 @@ PolyPolyline(
_In_reads_(csz) CONST DWORD *asz,
_In_ DWORD csz)
{
#if 0
// Handle something other than a normal dc object.
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
return FALSE;
else
{
PLDC pLDC = GdiGetLDC(hdc);
if ( !pLDC )
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (pLDC->iType == LDC_EMFLDC)
{
return EMFDRV_PolyPolyline(hdc, apt, asz, csz);
}
return FALSE;
}
}
#endif
if (GDI_HANDLE_GET_TYPE(hdc) == GDILoObjType_LO_METADC16_TYPE)
return FALSE;
HANDLE_METADC(BOOL, PolyPolyline, FALSE, hdc, apt, asz, csz);
return NtGdiPolyPolyDraw(hdc , (PPOINT)apt, (PULONG)asz, csz, GdiPolyPolyLine);
}
@ -748,28 +385,8 @@ ExtFloodFill(
_In_ COLORREF crFill,
_In_ UINT fuFillType)
{
#if 0
// Handle something other than a normal dc object.
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
return MFDRV_ExtFloodFill(hdc, xStart, yStart, crFill, fuFillType );
else
{
PLDC pLDC = GdiGetLDC(hdc);
if ( !pLDC )
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (pLDC->iType == LDC_EMFLDC)
{
return EMFDRV_ExtFloodFill(hdc, xStart, yStart, crFill, fuFillType );
}
return FALSE;
}
}
#endif
HANDLE_METADC(BOOL, ExtFloodFill, FALSE, hdc, xStart, yStart, crFill, fuFillType);
return NtGdiExtFloodFill(hdc, xStart, yStart, crFill, fuFillType);
}
@ -810,6 +427,22 @@ BitBlt(
return PatBlt(hdcDest, xDest, yDest, cx, cy, dwRop);
}
/* For meta DCs we use StretchBlt */
HANDLE_METADC(BOOL,
StretchBlt,
FALSE,
hdcDest,
xDest,
yDest,
cx,
cx,
hdcSrc,
xSrc,
ySrc,
cx,
cx,
dwRop);
return NtGdiBitBlt(hdcDest, xDest, yDest, cx, cy, hdcSrc, xSrc, ySrc, dwRop, 0, 0);
}
@ -823,6 +456,8 @@ PatBlt(
_In_ INT nHeight,
_In_ DWORD dwRop)
{
HANDLE_METADC(BOOL, PatBlt, FALSE, hdc, nXLeft, nYLeft, nWidth, nHeight, dwRop);
/* FIXME some part need be done in user mode */
return NtGdiPatBlt( hdc, nXLeft, nYLeft, nWidth, nHeight, dwRop);
}
@ -836,6 +471,46 @@ PolyPatBlt(
_In_ DWORD nCount,
_In_ DWORD dwMode)
{
UINT i;
BOOL bResult;
HBRUSH hbrOld;
/* Handle meta DCs */
if ((GDI_HANDLE_GET_TYPE(hdc) == GDILoObjType_LO_METADC16_TYPE) ||
(GDI_HANDLE_GET_TYPE(hdc) == GDILoObjType_LO_ALTDC_TYPE))
{
if (!GdiIsHandleValid(hdc))
{
return FALSE;
}
/* Save the current DC brush */
hbrOld = SelectObject(hdc, GetStockObject(DC_BRUSH));
/* Assume success */
bResult = TRUE;
/* Loop all rect */
for (i = 0; i < nCount; i++)
{
/* Select the brush for this rect */
SelectObject(hdc, pPoly[i].hBrush);
/* Do the PatBlt operation for this rect */
bResult &= PatBlt(hdc,
pPoly[i].nXLeft,
pPoly[i].nYLeft,
pPoly[i].nWidth,
pPoly[i].nHeight,
dwRop);
}
/* Restore the old brush */
SelectObject(hdc, hbrOld);
return bResult;
}
/* FIXME some part need be done in user mode */
return NtGdiPolyPatBlt(hdc, dwRop, pPoly, nCount, dwMode);
}
@ -858,6 +533,21 @@ StretchBlt(
_In_ INT cySrc,
_In_ DWORD dwRop)
{
HANDLE_METADC(BOOL,
StretchBlt,
FALSE,
hdcDest,
xDest,
yDest,
cxDest,
cyDest,
hdcSrc,
xSrc,
ySrc,
cxSrc,
cySrc,
dwRop);
return NtGdiStretchBlt(hdcDest,
xDest,
yDest,
@ -892,6 +582,22 @@ MaskBlt(
_In_ INT yMask,
_In_ DWORD dwRop)
{
HANDLE_METADC(BOOL,
MaskBlt,
FALSE,
hdcDest,
xDest,
yDest,
cx,
cy,
hdcSrc,
xSrc,
ySrc,
hbmMask,
xMask,
yMask,
dwRop);
return NtGdiMaskBlt(hdcDest,
xDest,
yDest,
@ -925,6 +631,20 @@ PlgBlt(
_In_ INT xMask,
_In_ INT yMask)
{
HANDLE_METADC(BOOL,
PlgBlt,
FALSE,
hdcDest,
ppt,
hdcSrc,
xSrc,
ySrc,
cx,
cy,
hbmMask,
xMask,
yMask);
return NtGdiPlgBlt(hdcDest,
(LPPOINT)ppt,
hdcSrc,
@ -957,6 +677,21 @@ GdiAlphaBlend(
if (GDI_HANDLE_GET_TYPE(hdcSrc) == GDI_OBJECT_TYPE_METADC) return FALSE;
HANDLE_METADC(BOOL,
AlphaBlend,
FALSE,
hdcDst,
xDst,
yDst,
cxDst,
cyDst,
hdcSrc,
xSrc,
ySrc,
cxSrc,
cySrc,
blendfn);
return NtGdiAlphaBlend(hdcDst,
xDst,
yDst,
@ -990,6 +725,21 @@ GdiTransparentBlt(
_In_ INT cySrc,
_In_ UINT crTransparent)
{
HANDLE_METADC(BOOL,
TransparentBlt,
FALSE,
hdcDst,
xDst,
yDst,
cxDst,
cyDst,
hdcSrc,
xSrc,
ySrc,
cxSrc,
cySrc,
crTransparent);
/* FIXME some part need be done in user mode */
return NtGdiTransparentBlt(hdcDst, xDst, yDst, cxDst, cyDst, hdcSrc, xSrc, ySrc, cxSrc, cySrc, crTransparent);
}
@ -1007,6 +757,8 @@ GdiGradientFill(
_In_ ULONG nCount,
_In_ ULONG ulMode)
{
HANDLE_METADC(BOOL, GradientFill, FALSE, hdc, pVertex, nVertex, pMesh, nCount, ulMode);
/* FIXME some part need be done in user mode */
return NtGdiGradientFill(hdc, pVertex, nVertex, pMesh, nCount, ulMode);
}

View File

@ -135,25 +135,11 @@ GetDIBColorTable(HDC hDC,
*/
UINT
WINAPI
RealizePalette(HDC hDC) /* [in] Handle of device context */
RealizePalette(
_In_ HDC hdc) /* [in] Handle of device context */
{
#if 0
// Handle something other than a normal dc object.
if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
return MFDRV_(hDC);
else
{
HPALETTE Pal = GetCurrentObject(hDC, OBJ_PAL);
PLDC pLDC = GdiGetLDC((HDC) Pal);
if ( !pLDC ) return FALSE;
if (pLDC->iType == LDC_EMFLDC) return EMFDRV_(Pal);
return FALSE;
}
}
#endif
return UserRealizePalette(hDC);
HANDLE_METADC0P(UINT, RealizePalette, GDI_ERROR, hdc);
return UserRealizePalette(hdc);
}
/*

View File

@ -16,10 +16,10 @@
BOOL
WINAPI
AbortPath(
HDC hdc
)
HDC hdc)
{
return NtGdiAbortPath( hdc );
HANDLE_METADC0P(BOOL, AbortPath, FALSE, hdc);
return NtGdiAbortPath(hdc);
}
@ -29,10 +29,10 @@ AbortPath(
BOOL
WINAPI
BeginPath(
HDC hdc
)
HDC hdc)
{
return NtGdiBeginPath( hdc );
HANDLE_METADC0P(BOOL, BeginPath, FALSE, hdc);
return NtGdiBeginPath(hdc);
}
/*
@ -41,10 +41,10 @@ BeginPath(
BOOL
WINAPI
CloseFigure(
HDC hdc
)
HDC hdc)
{
return NtGdiCloseFigure ( hdc );
HANDLE_METADC0P(BOOL, CloseFigure, FALSE, hdc);
return NtGdiCloseFigure(hdc);
}
@ -54,9 +54,9 @@ CloseFigure(
BOOL
WINAPI
EndPath(
HDC hdc
)
HDC hdc)
{
HANDLE_METADC0P(BOOL, EndPath, FALSE, hdc);
return NtGdiEndPath( hdc );
}
@ -67,9 +67,9 @@ EndPath(
BOOL
WINAPI
FillPath(
HDC hdc
)
HDC hdc)
{
HANDLE_METADC0P(BOOL, FillPath, FALSE, hdc);
return NtGdiFillPath( hdc );
}
@ -80,9 +80,9 @@ FillPath(
BOOL
WINAPI
FlattenPath(
HDC hdc
)
HDC hdc)
{
HANDLE_METADC0P(BOOL, FlattenPath, FALSE, hdc);
return NtGdiFlattenPath ( hdc );
}
@ -118,10 +118,10 @@ GetPath(HDC hdc,
HRGN
WINAPI
PathToRegion(
HDC hdc
)
HDC hdc)
{
return NtGdiPathToRegion ( hdc );
HANDLE_METADC0P(HRGN, PathToRegion, NULL, hdc);
return NtGdiPathToRegion(hdc);
}
/*
@ -151,9 +151,9 @@ SetMiterLimit(
BOOL
WINAPI
StrokeAndFillPath(
HDC hdc
)
HDC hdc)
{
HANDLE_METADC0P(BOOL, StrokeAndFillPath, FALSE, hdc);
return NtGdiStrokeAndFillPath ( hdc );
}
@ -164,9 +164,9 @@ StrokeAndFillPath(
BOOL
WINAPI
StrokePath(
HDC hdc
)
HDC hdc)
{
HANDLE_METADC0P(BOOL, StrokePath, FALSE, hdc);
return NtGdiStrokePath ( hdc );
}
@ -177,9 +177,9 @@ StrokePath(
BOOL
WINAPI
WidenPath(
HDC hdc
)
HDC hdc)
{
HANDLE_METADC0P(BOOL, WidenPath, FALSE, hdc);
return NtGdiWidenPath ( hdc );
}
@ -190,8 +190,8 @@ BOOL
WINAPI
SelectClipPath(
HDC hdc,
int Mode
)
int iMode)
{
return NtGdiSelectClipPath ( hdc, Mode );
HANDLE_METADC(BOOL, SelectClipPath, FALSE, hdc, iMode);
return NtGdiSelectClipPath(hdc, iMode);
}

View File

@ -104,12 +104,13 @@ SortRects(PRECT pRect, INT nCount)
*/
BOOL
FASTCALL
DeleteRegion( HRGN hRgn )
DeleteRegion(
_In_ HRGN hrgn)
{
#if 0
PRGN_ATTR Rgn_Attr;
if ((GdiGetHandleUserData((HGDIOBJ) hRgn, GDI_OBJECT_TYPE_REGION, (PVOID) &Rgn_Attr)) &&
if ((GdiGetHandleUserData(hrgn, GDI_OBJECT_TYPE_REGION, (PVOID) &Rgn_Attr)) &&
( Rgn_Attr != NULL ))
{
PGDIBSOBJECT pgO;
@ -117,29 +118,32 @@ DeleteRegion( HRGN hRgn )
pgO = GdiAllocBatchCommand(NULL, GdiBCDelRgn);
if (pgO)
{
pgO->hgdiobj = (HGDIOBJ)hRgn;
pgO->hgdiobj = hrgn;
return TRUE;
}
}
#endif
return NtGdiDeleteObjectApp((HGDIOBJ) hRgn);
return NtGdiDeleteObjectApp(hrgn);
}
INT
FASTCALL
MirrorRgnByWidth(HRGN hRgn, INT Width, HRGN *phRgn)
MirrorRgnByWidth(
_In_ HRGN hrgn,
_In_ INT Width,
_In_ HRGN *phrgn)
{
INT cRgnDSize, Ret = 0;
PRGNDATA pRgnData;
cRgnDSize = NtGdiGetRegionData(hRgn, 0, NULL);
cRgnDSize = NtGdiGetRegionData(hrgn, 0, NULL);
if (cRgnDSize)
{
pRgnData = LocalAlloc(LMEM_FIXED, cRgnDSize * sizeof(LONG));
if (pRgnData)
{
if ( GetRegionData(hRgn, cRgnDSize, pRgnData) )
if ( GetRegionData(hrgn, cRgnDSize, pRgnData) )
{
HRGN hRgnex;
UINT i;
@ -160,10 +164,10 @@ MirrorRgnByWidth(HRGN hRgn, INT Width, HRGN *phRgn)
hRgnex = ExtCreateRegion(NULL, cRgnDSize , pRgnData);
if (hRgnex)
{
if (phRgn) phRgn = (HRGN *)hRgnex;
if (phrgn) phrgn = (HRGN *)hRgnex;
else
{
CombineRgn(hRgn, hRgnex, 0, RGN_COPY);
CombineRgn(hrgn, hRgnex, 0, RGN_COPY);
DeleteObject(hRgnex);
}
Ret = 1;
@ -177,12 +181,16 @@ MirrorRgnByWidth(HRGN hRgn, INT Width, HRGN *phRgn)
INT
WINAPI
MirrorRgnDC(HDC hdc, HRGN hRgn, HRGN *phRgn)
MirrorRgnDC(
_In_ HDC hdc,
_In_ HRGN hrgn,
_In_ HRGN *phrn)
{
if (!GdiIsHandleValid((HGDIOBJ) hdc) ||
(GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)) return 0;
(GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC))
return 0;
return MirrorRgnByWidth(hRgn, NtGdiGetDeviceWidth(hdc), phRgn);
return MirrorRgnByWidth(hrgn, NtGdiGetDeviceWidth(hdc), phrn);
}
/* FUNCTIONS *****************************************************************/
@ -677,28 +685,15 @@ CreateRectRgnIndirect(
*/
INT
WINAPI
ExcludeClipRect(IN HDC hdc, IN INT xLeft, IN INT yTop, IN INT xRight, IN INT yBottom)
ExcludeClipRect(
_In_ HDC hdc,
_In_ INT xLeft,
_In_ INT yTop,
_In_ INT xRight,
_In_ INT yBottom)
{
#if 0
// Handle something other than a normal dc object.
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
return MFDRV_ExcludeClipRect( hdc, xLeft, yTop, xRight, yBottom);
else
{
PLDC pLDC = GdiGetLDC(hdc);
if ( pLDC )
{
if (pLDC->iType != LDC_EMFLDC || EMFDRV_ExcludeClipRect( hdc, xLeft, yTop, xRight, yBottom))
return NtGdiExcludeClipRect(hdc, xLeft, yTop, xRight, yBottom);
}
else
SetLastError(ERROR_INVALID_HANDLE);
return ERROR;
}
}
#endif
HANDLE_METADC(INT, ExcludeClipRect, ERROR, hdc, xLeft, yTop, xRight, yBottom);
return NtGdiExcludeClipRect(hdc, xLeft, yTop, xRight, yBottom);
}
@ -731,31 +726,16 @@ ExtCreateRegion(
*/
INT
WINAPI
ExtSelectClipRgn( IN HDC hdc, IN HRGN hrgn, IN INT iMode)
ExtSelectClipRgn(
_In_ HDC hdc,
_In_ HRGN hrgn,
_In_ INT iMode)
{
INT Ret;
HRGN NewRgn = NULL;
#if 0
// Handle something other than a normal dc object.
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
return MFDRV_ExtSelectClipRgn( hdc, );
else
{
PLDC pLDC = GdiGetLDC(hdc);
if ( pLDC )
{
if (pLDC->iType != LDC_EMFLDC || EMFDRV_ExtSelectClipRgn( hdc, ))
return NtGdiExtSelectClipRgn(hdc, );
}
else
SetLastError(ERROR_INVALID_HANDLE);
return ERROR;
}
}
#endif
HANDLE_METADC(INT, ExtSelectClipRgn, 0, hdc, hrgn, iMode);
#if 0
if ( hrgn )
{
@ -934,33 +914,15 @@ GetRgnBox(HRGN hrgn,
*/
INT
WINAPI
IntersectClipRect(HDC hdc,
int nLeftRect,
int nTopRect,
int nRightRect,
int nBottomRect)
IntersectClipRect(
_In_ HDC hdc,
_In_ INT nLeft,
_In_ INT nTop,
_In_ INT nRight,
_In_ INT nBottom)
{
#if 0
// Handle something other than a normal dc object.
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
return MFDRV_IntersectClipRect( hdc, nLeftRect, nTopRect, nRightRect, nBottomRect);
else
{
PLDC pLDC = GdiGetLDC(hdc);
if ( pLDC )
{
if (pLDC->iType != LDC_EMFLDC || EMFDRV_IntersectClipRect( hdc, nLeftRect, nTopRect, nRightRect, nBottomRect))
return NtGdiIntersectClipRect(hdc, nLeftRect, nTopRect, nRightRect, nBottomRect);
}
else
SetLastError(ERROR_INVALID_HANDLE);
return ERROR;
}
}
#endif
return NtGdiIntersectClipRect(hdc, nLeftRect, nTopRect, nRightRect, nBottomRect);
HANDLE_METADC(INT, IntersectClipRect, ERROR, hdc, nLeft, nTop, nRight, nBottom);
return NtGdiIntersectClipRect(hdc, nLeft, nTop, nRight, nBottom);
}
/*
@ -980,36 +942,13 @@ MirrorRgn(HWND hwnd, HRGN hrgn)
*/
INT
WINAPI
OffsetClipRgn(HDC hdc,
int nXOffset,
int nYOffset)
OffsetClipRgn(
HDC hdc,
INT nXOffset,
INT nYOffset)
{
if (hdc == NULL)
{
SetLastError(ERROR_INVALID_HANDLE);
return ERROR;
}
#if 0
// Handle something other than a normal dc object.
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
return MFDRV_OffsetClipRgn( hdc, nXOffset, nYOffset );
else
{
PLDC pLDC = GdiGetLDC(hdc);
if ( !pLDC )
{
SetLastError(ERROR_INVALID_HANDLE);
return ERROR;
}
if (pLDC->iType == LDC_EMFLDC && !EMFDRV_OffsetClipRgn( hdc, nXOffset, nYOffset ))
return ERROR;
return NtGdiOffsetClipRgn( hdc, nXOffset, nYOffset);
}
}
#endif
return NtGdiOffsetClipRgn( hdc, nXOffset, nYOffset);
HANDLE_METADC(INT, OffsetClipRgn, ERROR, hdc, nXOffset, nYOffset);
return NtGdiOffsetClipRgn(hdc, nXOffset, nYOffset);
}
/*
@ -1145,11 +1084,11 @@ RectInRegion(HRGN hrgn,
/*
* @implemented
*/
int WINAPI
int
WINAPI
SelectClipRgn(
HDC hdc,
HRGN hrgn
)
_In_ HDC hdc,
_In_ HRGN hrgn)
{
return ExtSelectClipRgn(hdc, hrgn, RGN_COPY);
}
@ -1215,7 +1154,7 @@ SetRectRgn(
*/
int
WINAPI
SetMetaRgn( HDC hDC )
SetMetaRgn(HDC hDC)
{
if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_DC)
return NtGdiSetMetaRgn(hDC);

View File

@ -48,14 +48,7 @@ TextOutW(
_In_reads_(cchString) LPCWSTR lpString,
_In_ INT cchString)
{
return NtGdiExtTextOutW(hdc,
nXStart,
nYStart,
0, NULL,
(LPWSTR)lpString,
cchString,
NULL,
0);
return ExtTextOutW(hdc, nXStart, nYStart, 0, NULL, (LPWSTR)lpString, cchString, NULL);
}
@ -473,6 +466,18 @@ ExtTextOutW(
_In_ UINT cwc,
_In_reads_opt_(cwc) const INT *lpDx)
{
HANDLE_METADC(BOOL,
ExtTextOut,
FALSE,
hdc,
x,
y,
fuOptions,
lprc,
lpString,
cwc,
lpDx);
return NtGdiExtTextOutW(hdc,
x,
y,
@ -633,12 +638,10 @@ SetTextCharacterExtra(
return 0x80000000;
}
#if 0
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
if (GDI_HANDLE_GET_TYPE(hdc) == GDILoObjType_LO_METADC16_TYPE)
{
return MFDRV_SetTextCharacterExtra( hdc, nCharExtra ); // Wine port.
HANDLE_METADC(INT, SetTextCharacterExtra, 0x80000000, hdc, nCharExtra);
}
#endif
/* Get the DC attribute */
pdcattr = GdiGetDcAttr(hdc);
@ -718,7 +721,9 @@ SetTextAlign(
_In_ UINT fMode)
{
PDC_ATTR pdcattr;
INT fOldMode;
UINT fOldMode;
HANDLE_METADC(BOOL, SetTextAlign, GDI_ERROR, hdc, fMode);
/* Get the DC attribute */
pdcattr = GdiGetDcAttr(hdc);
@ -728,26 +733,6 @@ SetTextAlign(
return GDI_ERROR;
}
#if 0
if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
return MFDRV_SetTextAlign( hdc, fMode )
else
{
PLDC pLDC = pdcattr->pvLDC;
if ( !pLDC )
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (pLDC->iType == LDC_EMFLDC)
{
if return EMFDRV_SetTextAlign( hdc, fMode )
}
}
}
#endif
fOldMode = pdcattr->lTextAlign;
pdcattr->lTextAlign = fMode; // Raw
@ -771,37 +756,17 @@ SetTextColor(
_In_ COLORREF crColor)
{
PDC_ATTR pdcattr;
COLORREF crOldColor = CLR_INVALID;
COLORREF crOldColor;
HANDLE_METADC(COLORREF, SetTextColor, CLR_INVALID, hdc, crColor);
/* Get the DC attribute */
pdcattr = GdiGetDcAttr(hdc);
if (pdcattr == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return GDI_ERROR;
return CLR_INVALID;
}
#if 0
if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
return MFDRV_SetTextColor( hDC, crColor );
else
{
PLDC pLDC = pdcattr->pvLDC;
if ( !pLDC )
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (pLDC->iType == LDC_EMFLDC)
{
if return EMFDRV_SetTextColor( hDC, crColor );
}
}
}
#endif
crOldColor = (COLORREF) pdcattr->ulForegroundClr;
pdcattr->ulForegroundClr = (ULONG)crColor;
@ -826,6 +791,11 @@ SetTextJustification(
{
PDC_ATTR pdcattr;
if (GDI_HANDLE_GET_TYPE(hdc) == GDILoObjType_LO_METADC16_TYPE)
{
HANDLE_METADC(BOOL, SetTextJustification, FALSE, hdc, nBreakExtra, nBreakCount);
}
/* Get the DC attribute */
pdcattr = GdiGetDcAttr(hdc);
if (pdcattr == NULL)
@ -834,17 +804,6 @@ SetTextJustification(
return GDI_ERROR;
}
#if 0
if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
{
if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
return MFDRV_SetTextJustification( hdc, nBreakExtra, nBreakCount )
else
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
#endif
if (NtCurrentTeb()->GdiTebBatch.HDC == hdc)
{

View File

@ -0,0 +1,25 @@
include_directories(
${REACTOS_SOURCE_DIR}/include/reactos/wine
${REACTOS_SOURCE_DIR}/win32ss/include
../include
.)
list(APPEND SOURCE
enhmetafile.c
metafile.c
enhmfdrv/bitblt.c
enhmfdrv/dc.c
enhmfdrv/graphics.c
enhmfdrv/init.c
enhmfdrv/objects.c
mfdrv/bitblt.c
mfdrv/dc.c
mfdrv/graphics.c
mfdrv/init.c
mfdrv/objects.c
mfdrv/text.c
rosglue.c
)
add_library(winegdi ${SOURCE})

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,267 @@
/*
* Enhanced MetaFile driver BitBlt functions
*
* Copyright 2002 Huw D M Davies for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#include <string.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "enhmetafiledrv.h"
#include "wine/debug.h"
BOOL EMFDRV_PatBlt( PHYSDEV dev, struct bitblt_coords *dst, DWORD rop )
{
EMRBITBLT emr;
BOOL ret;
emr.emr.iType = EMR_BITBLT;
emr.emr.nSize = sizeof(emr);
emr.rclBounds.left = dst->log_x;
emr.rclBounds.top = dst->log_y;
emr.rclBounds.right = dst->log_x + dst->log_width - 1;
emr.rclBounds.bottom = dst->log_y + dst->log_height - 1;
emr.xDest = dst->log_x;
emr.yDest = dst->log_y;
emr.cxDest = dst->log_width;
emr.cyDest = dst->log_height;
emr.dwRop = rop;
emr.xSrc = 0;
emr.ySrc = 0;
emr.xformSrc.eM11 = 1.0;
emr.xformSrc.eM12 = 0.0;
emr.xformSrc.eM21 = 0.0;
emr.xformSrc.eM22 = 1.0;
emr.xformSrc.eDx = 0.0;
emr.xformSrc.eDy = 0.0;
emr.crBkColorSrc = 0;
emr.iUsageSrc = 0;
emr.offBmiSrc = 0;
emr.cbBmiSrc = 0;
emr.offBitsSrc = 0;
emr.cbBitsSrc = 0;
ret = EMFDRV_WriteRecord( dev, &emr.emr );
if(ret)
EMFDRV_UpdateBBox( dev, &emr.rclBounds );
return ret;
}
BOOL EMFDRV_StretchBlt( PHYSDEV devDst, struct bitblt_coords *dst,
PHYSDEV devSrc, struct bitblt_coords *src, DWORD rop )
{
BOOL ret;
PEMRBITBLT pEMR;
UINT emrSize;
UINT bmiSize;
UINT bitsSize;
UINT size;
BITMAP BM;
WORD nBPP = 0;
LPBITMAPINFOHEADER lpBmiH;
HBITMAP hBitmap = NULL;
DWORD emrType;
if (devSrc->funcs == devDst->funcs) return FALSE; /* can't use a metafile DC as source */
if (src->log_width == dst->log_width && src->log_height == dst->log_height)
{
emrType = EMR_BITBLT;
emrSize = sizeof(EMRBITBLT);
}
else
{
emrType = EMR_STRETCHBLT;
emrSize = sizeof(EMRSTRETCHBLT);
}
hBitmap = GetCurrentObject(devSrc->hdc, OBJ_BITMAP);
if(sizeof(BITMAP) != GetObjectW(hBitmap, sizeof(BITMAP), &BM))
return FALSE;
nBPP = BM.bmPlanes * BM.bmBitsPixel;
if(nBPP > 8) nBPP = 24; /* FIXME Can't get 16bpp to work for some reason */
bitsSize = get_dib_stride( BM.bmWidth, nBPP ) * BM.bmHeight;
bmiSize = sizeof(BITMAPINFOHEADER) +
(nBPP <= 8 ? 1 << nBPP : 0) * sizeof(RGBQUAD);
size = emrSize + bmiSize + bitsSize;
pEMR = HeapAlloc(GetProcessHeap(), 0, size);
if (!pEMR) return FALSE;
/* Initialize EMR */
pEMR->emr.iType = emrType;
pEMR->emr.nSize = size;
pEMR->rclBounds.left = dst->log_x;
pEMR->rclBounds.top = dst->log_y;
pEMR->rclBounds.right = dst->log_x + dst->log_width - 1;
pEMR->rclBounds.bottom = dst->log_y + dst->log_height - 1;
pEMR->xDest = dst->log_x;
pEMR->yDest = dst->log_y;
pEMR->cxDest = dst->log_width;
pEMR->cyDest = dst->log_height;
pEMR->dwRop = rop;
pEMR->xSrc = src->log_x;
pEMR->ySrc = src->log_y;
GetWorldTransform(devSrc->hdc, &pEMR->xformSrc);
pEMR->crBkColorSrc = GetBkColor(devSrc->hdc);
pEMR->iUsageSrc = DIB_RGB_COLORS;
pEMR->offBmiSrc = emrSize;
pEMR->offBitsSrc = emrSize + bmiSize;
pEMR->cbBmiSrc = bmiSize;
pEMR->cbBitsSrc = bitsSize;
if (emrType == EMR_STRETCHBLT)
{
PEMRSTRETCHBLT pEMRStretch = (PEMRSTRETCHBLT)pEMR;
pEMRStretch->cxSrc = src->log_width;
pEMRStretch->cySrc = src->log_height;
}
/* Initialize BITMAPINFO structure */
lpBmiH = (LPBITMAPINFOHEADER)((BYTE*)pEMR + pEMR->offBmiSrc);
lpBmiH->biSize = sizeof(BITMAPINFOHEADER);
lpBmiH->biWidth = BM.bmWidth;
lpBmiH->biHeight = BM.bmHeight;
lpBmiH->biPlanes = BM.bmPlanes;
lpBmiH->biBitCount = nBPP;
/* Assume the bitmap isn't compressed and set the BI_RGB flag. */
lpBmiH->biCompression = BI_RGB;
lpBmiH->biSizeImage = bitsSize;
lpBmiH->biYPelsPerMeter = 0;
lpBmiH->biXPelsPerMeter = 0;
lpBmiH->biClrUsed = nBPP <= 8 ? 1 << nBPP : 0;
/* Set biClrImportant to 0, indicating that all of the
device colors are important. */
lpBmiH->biClrImportant = 0;
/* Initialize bitmap bits */
if (GetDIBits(devSrc->hdc, hBitmap, 0, (UINT)lpBmiH->biHeight,
(BYTE*)pEMR + pEMR->offBitsSrc,
(LPBITMAPINFO)lpBmiH, DIB_RGB_COLORS))
{
ret = EMFDRV_WriteRecord(devDst, (EMR*)pEMR);
if (ret) EMFDRV_UpdateBBox(devDst, &(pEMR->rclBounds));
}
else
ret = FALSE;
HeapFree( GetProcessHeap(), 0, pEMR);
return ret;
}
INT EMFDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst, INT heightDst,
INT xSrc, INT ySrc, INT widthSrc, INT heightSrc, const void *bits,
BITMAPINFO *info, UINT wUsage, DWORD dwRop )
{
EMRSTRETCHDIBITS *emr;
BOOL ret;
UINT bmi_size, emr_size;
/* calculate the size of the colour table */
bmi_size = get_dib_info_size(info, wUsage);
emr_size = sizeof (EMRSTRETCHDIBITS) + bmi_size + info->bmiHeader.biSizeImage;
emr = HeapAlloc(GetProcessHeap(), 0, emr_size );
if (!emr) return 0;
/* write a bitmap info header (with colours) to the record */
memcpy( &emr[1], info, bmi_size);
/* write bitmap bits to the record */
memcpy ( ( (BYTE *) (&emr[1]) ) + bmi_size, bits, info->bmiHeader.biSizeImage);
/* fill in the EMR header at the front of our piece of memory */
emr->emr.iType = EMR_STRETCHDIBITS;
emr->emr.nSize = emr_size;
emr->xDest = xDst;
emr->yDest = yDst;
emr->cxDest = widthDst;
emr->cyDest = heightDst;
emr->dwRop = dwRop;
emr->xSrc = xSrc; /* FIXME: only save the piece of the bitmap needed */
emr->ySrc = ySrc;
emr->iUsageSrc = wUsage;
emr->offBmiSrc = sizeof (EMRSTRETCHDIBITS);
emr->cbBmiSrc = bmi_size;
emr->offBitsSrc = emr->offBmiSrc + bmi_size;
emr->cbBitsSrc = info->bmiHeader.biSizeImage;
emr->cxSrc = widthSrc;
emr->cySrc = heightSrc;
emr->rclBounds.left = xDst;
emr->rclBounds.top = yDst;
emr->rclBounds.right = xDst + widthDst;
emr->rclBounds.bottom = yDst + heightDst;
/* save the record we just created */
ret = EMFDRV_WriteRecord( dev, &emr->emr );
if(ret)
EMFDRV_UpdateBBox( dev, &emr->rclBounds );
HeapFree(GetProcessHeap(), 0, emr);
return ret ? heightSrc : GDI_ERROR;
}
INT EMFDRV_SetDIBitsToDevice( PHYSDEV dev, INT xDst, INT yDst, DWORD width, DWORD height,
INT xSrc, INT ySrc, UINT startscan, UINT lines,
LPCVOID bits, BITMAPINFO *info, UINT wUsage )
{
EMRSETDIBITSTODEVICE* pEMR;
DWORD bmiSize = get_dib_info_size(info, wUsage);
DWORD size = sizeof(EMRSETDIBITSTODEVICE) + bmiSize + info->bmiHeader.biSizeImage;
pEMR = HeapAlloc(GetProcessHeap(), 0, size);
if (!pEMR) return 0;
pEMR->emr.iType = EMR_SETDIBITSTODEVICE;
pEMR->emr.nSize = size;
pEMR->rclBounds.left = xDst;
pEMR->rclBounds.top = yDst;
pEMR->rclBounds.right = xDst + width - 1;
pEMR->rclBounds.bottom = yDst + height - 1;
pEMR->xDest = xDst;
pEMR->yDest = yDst;
pEMR->xSrc = xSrc;
pEMR->ySrc = ySrc;
pEMR->cxSrc = width;
pEMR->cySrc = height;
pEMR->offBmiSrc = sizeof(EMRSETDIBITSTODEVICE);
pEMR->cbBmiSrc = bmiSize;
pEMR->offBitsSrc = sizeof(EMRSETDIBITSTODEVICE) + bmiSize;
pEMR->cbBitsSrc = info->bmiHeader.biSizeImage;
pEMR->iUsageSrc = wUsage;
pEMR->iStartScan = startscan;
pEMR->cScans = lines;
memcpy((BYTE*)pEMR + pEMR->offBmiSrc, info, bmiSize);
memcpy((BYTE*)pEMR + pEMR->offBitsSrc, bits, info->bmiHeader.biSizeImage);
if (EMFDRV_WriteRecord(dev, (EMR*)pEMR))
EMFDRV_UpdateBBox(dev, &(pEMR->rclBounds));
HeapFree( GetProcessHeap(), 0, pEMR);
return lines;
}

View File

@ -0,0 +1,531 @@
/*
* Enhanced MetaFile driver dc value functions
*
* Copyright 1999 Huw D M Davies
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "enhmfdrv/enhmetafiledrv.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(enhmetafile);
INT EMFDRV_SaveDC( PHYSDEV dev )
{
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSaveDC );
INT ret = next->funcs->pSaveDC( next );
if (ret)
{
EMRSAVEDC emr;
emr.emr.iType = EMR_SAVEDC;
emr.emr.nSize = sizeof(emr);
EMFDRV_WriteRecord( dev, &emr.emr );
}
return ret;
}
BOOL EMFDRV_RestoreDC( PHYSDEV dev, INT level )
{
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pRestoreDC );
EMFDRV_PDEVICE* physDev = (EMFDRV_PDEVICE*)dev;
DC *dc = get_dc_ptr( dev->hdc );
EMRRESTOREDC emr;
BOOL ret;
emr.emr.iType = EMR_RESTOREDC;
emr.emr.nSize = sizeof(emr);
if (level < 0)
emr.iRelative = level;
else
emr.iRelative = level - dc->saveLevel - 1;
release_dc_ptr( dc );
physDev->restoring++;
ret = next->funcs->pRestoreDC( next, level );
physDev->restoring--;
if (ret) EMFDRV_WriteRecord( dev, &emr.emr );
return ret;
}
UINT EMFDRV_SetTextAlign( PHYSDEV dev, UINT align )
{
EMRSETTEXTALIGN emr;
emr.emr.iType = EMR_SETTEXTALIGN;
emr.emr.nSize = sizeof(emr);
emr.iMode = align;
return EMFDRV_WriteRecord( dev, &emr.emr ) ? align : GDI_ERROR;
}
BOOL EMFDRV_SetTextJustification(PHYSDEV dev, INT nBreakExtra, INT nBreakCount)
{
EMRSETTEXTJUSTIFICATION emr;
emr.emr.iType = EMR_SETTEXTJUSTIFICATION;
emr.emr.nSize = sizeof(emr);
emr.nBreakExtra = nBreakExtra;
emr.nBreakCount = nBreakCount;
return EMFDRV_WriteRecord(dev, &emr.emr);
}
INT EMFDRV_SetBkMode( PHYSDEV dev, INT mode )
{
EMRSETBKMODE emr;
emr.emr.iType = EMR_SETBKMODE;
emr.emr.nSize = sizeof(emr);
emr.iMode = mode;
return EMFDRV_WriteRecord( dev, &emr.emr ) ? mode : 0;
}
COLORREF EMFDRV_SetBkColor( PHYSDEV dev, COLORREF color )
{
EMRSETBKCOLOR emr;
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE *)dev;
if (physDev->restoring) return color; /* don't output records during RestoreDC */
emr.emr.iType = EMR_SETBKCOLOR;
emr.emr.nSize = sizeof(emr);
emr.crColor = color;
return EMFDRV_WriteRecord( dev, &emr.emr ) ? color : CLR_INVALID;
}
COLORREF EMFDRV_SetTextColor( PHYSDEV dev, COLORREF color )
{
EMRSETTEXTCOLOR emr;
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE *)dev;
if (physDev->restoring) return color; /* don't output records during RestoreDC */
emr.emr.iType = EMR_SETTEXTCOLOR;
emr.emr.nSize = sizeof(emr);
emr.crColor = color;
return EMFDRV_WriteRecord( dev, &emr.emr ) ? color : CLR_INVALID;
}
INT EMFDRV_SetROP2( PHYSDEV dev, INT rop )
{
EMRSETROP2 emr;
emr.emr.iType = EMR_SETROP2;
emr.emr.nSize = sizeof(emr);
emr.iMode = rop;
return EMFDRV_WriteRecord( dev, &emr.emr ) ? rop : 0;
}
INT EMFDRV_SetPolyFillMode( PHYSDEV dev, INT mode )
{
EMRSETPOLYFILLMODE emr;
emr.emr.iType = EMR_SETPOLYFILLMODE;
emr.emr.nSize = sizeof(emr);
emr.iMode = mode;
return EMFDRV_WriteRecord( dev, &emr.emr ) ? mode : 0;
}
INT EMFDRV_SetStretchBltMode( PHYSDEV dev, INT mode )
{
EMRSETSTRETCHBLTMODE emr;
emr.emr.iType = EMR_SETSTRETCHBLTMODE;
emr.emr.nSize = sizeof(emr);
emr.iMode = mode;
return EMFDRV_WriteRecord( dev, &emr.emr ) ? mode : 0;
}
INT EMFDRV_SetArcDirection(PHYSDEV dev, INT arcDirection)
{
EMRSETARCDIRECTION emr;
emr.emr.iType = EMR_SETARCDIRECTION;
emr.emr.nSize = sizeof(emr);
emr.iArcDirection = arcDirection;
return EMFDRV_WriteRecord(dev, &emr.emr) ? arcDirection : 0;
}
INT EMFDRV_ExcludeClipRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom )
{
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pExcludeClipRect );
EMREXCLUDECLIPRECT emr;
emr.emr.iType = EMR_EXCLUDECLIPRECT;
emr.emr.nSize = sizeof(emr);
emr.rclClip.left = left;
emr.rclClip.top = top;
emr.rclClip.right = right;
emr.rclClip.bottom = bottom;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return ERROR;
return next->funcs->pExcludeClipRect( next, left, top, right, bottom );
}
INT EMFDRV_IntersectClipRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom)
{
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pIntersectClipRect );
EMRINTERSECTCLIPRECT emr;
emr.emr.iType = EMR_INTERSECTCLIPRECT;
emr.emr.nSize = sizeof(emr);
emr.rclClip.left = left;
emr.rclClip.top = top;
emr.rclClip.right = right;
emr.rclClip.bottom = bottom;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return ERROR;
return next->funcs->pIntersectClipRect( next, left, top, right, bottom );
}
INT EMFDRV_OffsetClipRgn( PHYSDEV dev, INT x, INT y )
{
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pOffsetClipRgn );
EMROFFSETCLIPRGN emr;
emr.emr.iType = EMR_OFFSETCLIPRGN;
emr.emr.nSize = sizeof(emr);
emr.ptlOffset.x = x;
emr.ptlOffset.y = y;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return ERROR;
return next->funcs->pOffsetClipRgn( next, x, y );
}
INT EMFDRV_ExtSelectClipRgn( PHYSDEV dev, HRGN hrgn, INT mode )
{
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pExtSelectClipRgn );
EMREXTSELECTCLIPRGN *emr;
DWORD size, rgnsize;
BOOL ret;
if (!hrgn)
{
if (mode != RGN_COPY) return ERROR;
rgnsize = 0;
}
else rgnsize = GetRegionData( hrgn, 0, NULL );
size = rgnsize + offsetof(EMREXTSELECTCLIPRGN,RgnData);
emr = HeapAlloc( GetProcessHeap(), 0, size );
if (rgnsize) GetRegionData( hrgn, rgnsize, (RGNDATA *)&emr->RgnData );
emr->emr.iType = EMR_EXTSELECTCLIPRGN;
emr->emr.nSize = size;
emr->cbRgnData = rgnsize;
emr->iMode = mode;
ret = EMFDRV_WriteRecord( dev, &emr->emr );
HeapFree( GetProcessHeap(), 0, emr );
return ret ? next->funcs->pExtSelectClipRgn( next, hrgn, mode ) : ERROR;
}
INT EMFDRV_SetMapMode( PHYSDEV dev, INT mode )
{
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetMapMode );
EMRSETMAPMODE emr;
emr.emr.iType = EMR_SETMAPMODE;
emr.emr.nSize = sizeof(emr);
emr.iMode = mode;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return 0;
return next->funcs->pSetMapMode( next, mode );
}
BOOL EMFDRV_SetViewportExtEx( PHYSDEV dev, INT cx, INT cy, SIZE *size )
{
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetViewportExtEx );
EMRSETVIEWPORTEXTEX emr;
emr.emr.iType = EMR_SETVIEWPORTEXTEX;
emr.emr.nSize = sizeof(emr);
emr.szlExtent.cx = cx;
emr.szlExtent.cy = cy;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
return next->funcs->pSetViewportExtEx( next, cx, cy, size );
}
BOOL EMFDRV_SetWindowExtEx( PHYSDEV dev, INT cx, INT cy, SIZE *size )
{
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetWindowExtEx );
EMRSETWINDOWEXTEX emr;
emr.emr.iType = EMR_SETWINDOWEXTEX;
emr.emr.nSize = sizeof(emr);
emr.szlExtent.cx = cx;
emr.szlExtent.cy = cy;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
return next->funcs->pSetWindowExtEx( next, cx, cy, size );
}
BOOL EMFDRV_SetViewportOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt )
{
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetViewportOrgEx );
EMRSETVIEWPORTORGEX emr;
emr.emr.iType = EMR_SETVIEWPORTORGEX;
emr.emr.nSize = sizeof(emr);
emr.ptlOrigin.x = x;
emr.ptlOrigin.y = y;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
return next->funcs->pSetViewportOrgEx( next, x, y, pt );
}
BOOL EMFDRV_SetWindowOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt )
{
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetWindowOrgEx );
EMRSETWINDOWORGEX emr;
emr.emr.iType = EMR_SETWINDOWORGEX;
emr.emr.nSize = sizeof(emr);
emr.ptlOrigin.x = x;
emr.ptlOrigin.y = y;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
return next->funcs->pSetWindowOrgEx( next, x, y, pt );
}
BOOL EMFDRV_ScaleViewportExtEx( PHYSDEV dev, INT xNum, INT xDenom, INT yNum, INT yDenom, SIZE *size )
{
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pScaleViewportExtEx );
EMRSCALEVIEWPORTEXTEX emr;
emr.emr.iType = EMR_SCALEVIEWPORTEXTEX;
emr.emr.nSize = sizeof(emr);
emr.xNum = xNum;
emr.xDenom = xDenom;
emr.yNum = yNum;
emr.yDenom = yDenom;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
return next->funcs->pScaleViewportExtEx( next, xNum, xDenom, yNum, yDenom, size );
}
BOOL EMFDRV_ScaleWindowExtEx( PHYSDEV dev, INT xNum, INT xDenom, INT yNum, INT yDenom, SIZE *size )
{
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pScaleWindowExtEx );
EMRSCALEWINDOWEXTEX emr;
emr.emr.iType = EMR_SCALEWINDOWEXTEX;
emr.emr.nSize = sizeof(emr);
emr.xNum = xNum;
emr.xDenom = xDenom;
emr.yNum = yNum;
emr.yDenom = yDenom;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
return next->funcs->pScaleWindowExtEx( next, xNum, xDenom, yNum, yDenom, size );
}
DWORD EMFDRV_SetLayout( PHYSDEV dev, DWORD layout )
{
EMRSETLAYOUT emr;
emr.emr.iType = EMR_SETLAYOUT;
emr.emr.nSize = sizeof(emr);
emr.iMode = layout;
return EMFDRV_WriteRecord( dev, &emr.emr ) ? layout : GDI_ERROR;
}
BOOL EMFDRV_SetWorldTransform( PHYSDEV dev, const XFORM *xform)
{
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetWorldTransform );
EMRSETWORLDTRANSFORM emr;
emr.emr.iType = EMR_SETWORLDTRANSFORM;
emr.emr.nSize = sizeof(emr);
emr.xform = *xform;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
return next->funcs->pSetWorldTransform( next, xform );
}
BOOL EMFDRV_ModifyWorldTransform( PHYSDEV dev, const XFORM *xform, DWORD mode)
{
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pModifyWorldTransform );
EMRMODIFYWORLDTRANSFORM emr;
emr.emr.iType = EMR_MODIFYWORLDTRANSFORM;
emr.emr.nSize = sizeof(emr);
emr.xform = *xform;
emr.iMode = mode;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
return next->funcs->pModifyWorldTransform( next, xform, mode );
}
BOOL EMFDRV_OffsetViewportOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt )
{
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pOffsetViewportOrgEx );
EMRSETVIEWPORTORGEX emr;
POINT prev;
GetViewportOrgEx( dev->hdc, &prev );
emr.emr.iType = EMR_SETVIEWPORTORGEX;
emr.emr.nSize = sizeof(emr);
emr.ptlOrigin.x = prev.x + x;
emr.ptlOrigin.y = prev.y + y;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
return next->funcs->pOffsetViewportOrgEx( next, x, y, pt );
}
BOOL EMFDRV_OffsetWindowOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt )
{
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pOffsetWindowOrgEx );
EMRSETWINDOWORGEX emr;
POINT prev;
GetWindowOrgEx( dev->hdc, &prev );
emr.emr.iType = EMR_SETWINDOWORGEX;
emr.emr.nSize = sizeof(emr);
emr.ptlOrigin.x = prev.x + x;
emr.ptlOrigin.y = prev.y + y;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
return next->funcs->pOffsetWindowOrgEx( next, x, y, pt );
}
DWORD EMFDRV_SetMapperFlags( PHYSDEV dev, DWORD flags )
{
EMRSETMAPPERFLAGS emr;
emr.emr.iType = EMR_SETMAPPERFLAGS;
emr.emr.nSize = sizeof(emr);
emr.dwFlags = flags;
return EMFDRV_WriteRecord( dev, &emr.emr ) ? flags : GDI_ERROR;
}
BOOL EMFDRV_AbortPath( PHYSDEV dev )
{
EMRABORTPATH emr;
emr.emr.iType = EMR_ABORTPATH;
emr.emr.nSize = sizeof(emr);
return EMFDRV_WriteRecord( dev, &emr.emr );
}
BOOL EMFDRV_BeginPath( PHYSDEV dev )
{
EMRBEGINPATH emr;
emr.emr.iType = EMR_BEGINPATH;
emr.emr.nSize = sizeof(emr);
return EMFDRV_WriteRecord( dev, &emr.emr );
}
BOOL EMFDRV_CloseFigure( PHYSDEV dev )
{
EMRCLOSEFIGURE emr;
emr.emr.iType = EMR_CLOSEFIGURE;
emr.emr.nSize = sizeof(emr);
return EMFDRV_WriteRecord( dev, &emr.emr );
}
BOOL EMFDRV_EndPath( PHYSDEV dev )
{
EMRENDPATH emr;
emr.emr.iType = EMR_ENDPATH;
emr.emr.nSize = sizeof(emr);
return EMFDRV_WriteRecord( dev, &emr.emr );
}
BOOL EMFDRV_FillPath( PHYSDEV dev )
{
EMRFILLPATH emr;
emr.emr.iType = EMR_FILLPATH;
emr.emr.nSize = sizeof(emr);
FIXME("Bounds\n");
emr.rclBounds.left = 0;
emr.rclBounds.top = 0;
emr.rclBounds.right = 0;
emr.rclBounds.bottom = 0;
return EMFDRV_WriteRecord( dev, &emr.emr );
}
BOOL EMFDRV_FlattenPath( PHYSDEV dev )
{
EMRFLATTENPATH emr;
emr.emr.iType = EMR_FLATTENPATH;
emr.emr.nSize = sizeof(emr);
return EMFDRV_WriteRecord( dev, &emr.emr );
}
BOOL EMFDRV_SelectClipPath( PHYSDEV dev, INT iMode )
{
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSelectClipPath );
EMRSELECTCLIPPATH emr;
emr.emr.iType = EMR_SELECTCLIPPATH;
emr.emr.nSize = sizeof(emr);
emr.iMode = iMode;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
return next->funcs->pSelectClipPath( next, iMode );
}
BOOL EMFDRV_StrokeAndFillPath( PHYSDEV dev )
{
EMRSTROKEANDFILLPATH emr;
emr.emr.iType = EMR_STROKEANDFILLPATH;
emr.emr.nSize = sizeof(emr);
FIXME("Bounds\n");
emr.rclBounds.left = 0;
emr.rclBounds.top = 0;
emr.rclBounds.right = 0;
emr.rclBounds.bottom = 0;
return EMFDRV_WriteRecord( dev, &emr.emr );
}
BOOL EMFDRV_StrokePath( PHYSDEV dev )
{
EMRSTROKEPATH emr;
emr.emr.iType = EMR_STROKEPATH;
emr.emr.nSize = sizeof(emr);
FIXME("Bounds\n");
emr.rclBounds.left = 0;
emr.rclBounds.top = 0;
emr.rclBounds.right = 0;
emr.rclBounds.bottom = 0;
return EMFDRV_WriteRecord( dev, &emr.emr );
}
BOOL EMFDRV_WidenPath( PHYSDEV dev )
{
EMRWIDENPATH emr;
emr.emr.iType = EMR_WIDENPATH;
emr.emr.nSize = sizeof(emr);
return EMFDRV_WriteRecord( dev, &emr.emr );
}
INT EMFDRV_GetDeviceCaps(PHYSDEV dev, INT cap)
{
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE*) dev;
return GetDeviceCaps( physDev->ref_dc, cap );
}

View File

@ -0,0 +1,144 @@
/*
* Enhanced MetaFile driver definitions
*
* Copyright 1999 Huw D M Davies
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __WINE_ENHMETAFILEDRV_H
#define __WINE_ENHMETAFILEDRV_H
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "gdi_private.h"
/* Enhanced Metafile driver physical DC */
typedef struct
{
struct gdi_physdev dev;
ENHMETAHEADER *emh; /* Pointer to enhanced metafile header */
UINT handles_size, cur_handles;
HGDIOBJ *handles;
HANDLE hFile; /* Handle for disk based MetaFile */
HBRUSH dc_brush;
HPEN dc_pen;
HDC ref_dc; /* Reference device */
HDC screen_dc; /* Screen DC if no reference device specified */
INT restoring; /* RestoreDC counter */
} EMFDRV_PDEVICE;
extern BOOL EMFDRV_WriteRecord( PHYSDEV dev, EMR *emr ) DECLSPEC_HIDDEN;
extern void EMFDRV_UpdateBBox( PHYSDEV dev, RECTL *rect ) DECLSPEC_HIDDEN;
extern DWORD EMFDRV_CreateBrushIndirect( PHYSDEV dev, HBRUSH hBrush ) DECLSPEC_HIDDEN;
#define HANDLE_LIST_INC 20
/* Metafile driver functions */
extern BOOL EMFDRV_AbortPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_Arc( PHYSDEV dev, INT left, INT top, INT right,
INT bottom, INT xstart, INT ystart, INT xend, INT yend ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_BeginPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_BitBlt( PHYSDEV devDst, INT xDst, INT yDst, INT width, INT height,
PHYSDEV devSrc, INT xSrc, INT ySrc, DWORD rop ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_Chord( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
INT xstart, INT ystart, INT xend, INT yend ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_CloseFigure( PHYSDEV dev ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_DeleteObject( PHYSDEV dev, HGDIOBJ obj ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_Ellipse( PHYSDEV dev, INT left, INT top, INT right, INT bottom ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_EndPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
extern INT EMFDRV_ExcludeClipRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_ExtFloodFill( PHYSDEV dev, INT x, INT y, COLORREF color, UINT fillType ) DECLSPEC_HIDDEN;
extern INT EMFDRV_ExtSelectClipRgn( PHYSDEV dev, HRGN hrgn, INT mode ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags, const RECT *lprect, LPCWSTR str,
UINT count, const INT *lpDx ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_FillPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_FillRgn( PHYSDEV dev, HRGN hrgn, HBRUSH hbrush ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_FlattenPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_FrameRgn( PHYSDEV dev, HRGN hrgn, HBRUSH hbrush, INT width, INT height ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_GdiComment( PHYSDEV dev, UINT bytes, const BYTE *buffer ) DECLSPEC_HIDDEN;
extern INT EMFDRV_GetDeviceCaps( PHYSDEV dev, INT cap ) DECLSPEC_HIDDEN;
extern INT EMFDRV_IntersectClipRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_InvertRgn( PHYSDEV dev, HRGN hrgn ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_LineTo( PHYSDEV dev, INT x, INT y ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_ModifyWorldTransform( PHYSDEV dev, const XFORM *xform, DWORD mode ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_MoveTo( PHYSDEV dev, INT x, INT y ) DECLSPEC_HIDDEN;
extern INT EMFDRV_OffsetClipRgn( PHYSDEV dev, INT x, INT y ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_OffsetViewportOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_OffsetWindowOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_PaintRgn( PHYSDEV dev, HRGN hrgn ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_PatBlt( PHYSDEV dev, struct bitblt_coords *dst, DWORD rop ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_Pie( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
INT xstart, INT ystart, INT xend, INT yend ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_PolyBezier( PHYSDEV dev, const POINT *pts, DWORD count ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_PolyBezierTo( PHYSDEV dev, const POINT *pts, DWORD count ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_PolyPolygon( PHYSDEV dev, const POINT* pt, const INT* counts, UINT polys) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_PolyPolyline( PHYSDEV dev, const POINT* pt, const DWORD* counts, DWORD polys) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_Polygon( PHYSDEV dev, const POINT* pt, INT count ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_Polyline( PHYSDEV dev, const POINT* pt,INT count) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_Rectangle( PHYSDEV dev, INT left, INT top, INT right, INT bottom) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_RestoreDC( PHYSDEV dev, INT level ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_RoundRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
INT ell_width, INT ell_height ) DECLSPEC_HIDDEN;
extern INT EMFDRV_SaveDC( PHYSDEV dev ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_ScaleViewportExtEx( PHYSDEV dev, INT xNum, INT xDenom,
INT yNum, INT yDenom, SIZE *size ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_ScaleWindowExtEx( PHYSDEV dev, INT xNum, INT xDenom,
INT yNum, INT yDenom, SIZE *size ) DECLSPEC_HIDDEN;
extern HBITMAP EMFDRV_SelectBitmap( PHYSDEV dev, HBITMAP handle ) DECLSPEC_HIDDEN;
extern HBRUSH EMFDRV_SelectBrush( PHYSDEV dev, HBRUSH hbrush, const struct brush_pattern *pattern ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_SelectClipPath( PHYSDEV dev, INT iMode ) DECLSPEC_HIDDEN;
extern HFONT EMFDRV_SelectFont( PHYSDEV dev, HFONT handle, UINT *aa_flags ) DECLSPEC_HIDDEN;
extern HPEN EMFDRV_SelectPen( PHYSDEV dev, HPEN handle, const struct brush_pattern *pattern ) DECLSPEC_HIDDEN;
extern HPALETTE EMFDRV_SelectPalette( PHYSDEV dev, HPALETTE hPal, BOOL force ) DECLSPEC_HIDDEN;
extern INT EMFDRV_SetArcDirection( PHYSDEV dev, INT arcDirection ) DECLSPEC_HIDDEN;
extern COLORREF EMFDRV_SetBkColor( PHYSDEV dev, COLORREF color ) DECLSPEC_HIDDEN;
extern INT EMFDRV_SetBkMode( PHYSDEV dev, INT mode ) DECLSPEC_HIDDEN;
extern COLORREF EMFDRV_SetDCBrushColor( PHYSDEV dev, COLORREF color ) DECLSPEC_HIDDEN;
extern COLORREF EMFDRV_SetDCPenColor( PHYSDEV dev, COLORREF color ) DECLSPEC_HIDDEN;
extern INT EMFDRV_SetDIBitsToDevice( PHYSDEV dev, INT xDest, INT yDest, DWORD cx, DWORD cy, INT xSrc,
INT ySrc, UINT startscan, UINT lines, LPCVOID bits,
BITMAPINFO *info, UINT coloruse ) DECLSPEC_HIDDEN;
extern DWORD EMFDRV_SetLayout( PHYSDEV dev, DWORD layout ) DECLSPEC_HIDDEN;
extern INT EMFDRV_SetMapMode( PHYSDEV dev, INT mode ) DECLSPEC_HIDDEN;
extern DWORD EMFDRV_SetMapperFlags( PHYSDEV dev, DWORD flags ) DECLSPEC_HIDDEN;
extern COLORREF EMFDRV_SetPixel( PHYSDEV dev, INT x, INT y, COLORREF color ) DECLSPEC_HIDDEN;
extern INT EMFDRV_SetPolyFillMode( PHYSDEV dev, INT mode ) DECLSPEC_HIDDEN;
extern INT EMFDRV_SetROP2( PHYSDEV dev, INT rop ) DECLSPEC_HIDDEN;
extern INT EMFDRV_SetStretchBltMode( PHYSDEV dev, INT mode ) DECLSPEC_HIDDEN;
extern UINT EMFDRV_SetTextAlign( PHYSDEV dev, UINT align ) DECLSPEC_HIDDEN;
extern COLORREF EMFDRV_SetTextColor( PHYSDEV dev, COLORREF color ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_SetTextJustification( PHYSDEV dev, INT nBreakExtra, INT nBreakCount ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_SetViewportExtEx( PHYSDEV dev, INT x, INT y, SIZE *size ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_SetViewportOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_SetWindowExtEx( PHYSDEV dev, INT x, INT y, SIZE *size ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_SetWindowOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_SetWorldTransform( PHYSDEV dev, const XFORM *xform ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_StretchBlt( PHYSDEV devDst, struct bitblt_coords *dst,
PHYSDEV devSrc, struct bitblt_coords *src, DWORD rop ) DECLSPEC_HIDDEN;
extern INT EMFDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst, INT heightDst,
INT xSrc, INT ySrc, INT widthSrc, INT heightSrc,
const void *bits, BITMAPINFO *info, UINT wUsage, DWORD dwRop ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_StrokeAndFillPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_StrokePath( PHYSDEV dev ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_WidenPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
#endif /* __WINE_METAFILEDRV_H */

View File

@ -0,0 +1,817 @@
/*
* Enhanced MetaFile driver graphics functions
*
* Copyright 1999 Huw D M Davies
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include "wine/port.h"
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "enhmfdrv/enhmetafiledrv.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(enhmetafile);
/**********************************************************************
* EMFDRV_MoveTo
*/
BOOL EMFDRV_MoveTo(PHYSDEV dev, INT x, INT y)
{
EMRMOVETOEX emr;
emr.emr.iType = EMR_MOVETOEX;
emr.emr.nSize = sizeof(emr);
emr.ptl.x = x;
emr.ptl.y = y;
return EMFDRV_WriteRecord( dev, &emr.emr );
}
/***********************************************************************
* EMFDRV_LineTo
*/
BOOL EMFDRV_LineTo( PHYSDEV dev, INT x, INT y )
{
POINT pt;
EMRLINETO emr;
RECTL bounds;
emr.emr.iType = EMR_LINETO;
emr.emr.nSize = sizeof(emr);
emr.ptl.x = x;
emr.ptl.y = y;
if(!EMFDRV_WriteRecord( dev, &emr.emr ))
return FALSE;
GetCurrentPositionEx( dev->hdc, &pt );
bounds.left = min(x, pt.x);
bounds.top = min(y, pt.y);
bounds.right = max(x, pt.x);
bounds.bottom = max(y, pt.y);
EMFDRV_UpdateBBox( dev, &bounds );
return TRUE;
}
/***********************************************************************
* EMFDRV_ArcChordPie
*/
static BOOL
EMFDRV_ArcChordPie( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
INT xstart, INT ystart, INT xend, INT yend, DWORD iType )
{
INT temp, xCentre, yCentre, i;
double angleStart, angleEnd;
double xinterStart, yinterStart, xinterEnd, yinterEnd;
EMRARC emr;
RECTL bounds;
if(left == right || top == bottom) return FALSE;
if(left > right) {temp = left; left = right; right = temp;}
if(top > bottom) {temp = top; top = bottom; bottom = temp;}
if(GetGraphicsMode(dev->hdc) == GM_COMPATIBLE) {
right--;
bottom--;
}
emr.emr.iType = iType;
emr.emr.nSize = sizeof(emr);
emr.rclBox.left = left;
emr.rclBox.top = top;
emr.rclBox.right = right;
emr.rclBox.bottom = bottom;
emr.ptlStart.x = xstart;
emr.ptlStart.y = ystart;
emr.ptlEnd.x = xend;
emr.ptlEnd.y = yend;
/* Now calculate the BBox */
xCentre = (left + right + 1) / 2;
yCentre = (top + bottom + 1) / 2;
xstart -= xCentre;
ystart -= yCentre;
xend -= xCentre;
yend -= yCentre;
/* invert y co-ords to get angle anti-clockwise from x-axis */
angleStart = atan2( -(double)ystart, (double)xstart);
angleEnd = atan2( -(double)yend, (double)xend);
/* These are the intercepts of the start/end lines with the arc */
xinterStart = (right - left + 1)/2 * cos(angleStart) + xCentre;
yinterStart = -(bottom - top + 1)/2 * sin(angleStart) + yCentre;
xinterEnd = (right - left + 1)/2 * cos(angleEnd) + xCentre;
yinterEnd = -(bottom - top + 1)/2 * sin(angleEnd) + yCentre;
if(angleStart < 0) angleStart += 2 * M_PI;
if(angleEnd < 0) angleEnd += 2 * M_PI;
if(angleEnd < angleStart) angleEnd += 2 * M_PI;
bounds.left = min(xinterStart, xinterEnd);
bounds.top = min(yinterStart, yinterEnd);
bounds.right = max(xinterStart, xinterEnd);
bounds.bottom = max(yinterStart, yinterEnd);
for(i = 0; i <= 8; i++) {
if(i * M_PI / 2 < angleStart) /* loop until we're past start */
continue;
if(i * M_PI / 2 > angleEnd) /* if we're past end we're finished */
break;
/* the arc touches the rectangle at the start of quadrant i, so adjust
BBox to reflect this. */
switch(i % 4) {
case 0:
bounds.right = right;
break;
case 1:
bounds.top = top;
break;
case 2:
bounds.left = left;
break;
case 3:
bounds.bottom = bottom;
break;
}
}
/* If we're drawing a pie then make sure we include the centre */
if(iType == EMR_PIE) {
if(bounds.left > xCentre) bounds.left = xCentre;
else if(bounds.right < xCentre) bounds.right = xCentre;
if(bounds.top > yCentre) bounds.top = yCentre;
else if(bounds.bottom < yCentre) bounds.bottom = yCentre;
}
if(!EMFDRV_WriteRecord( dev, &emr.emr ))
return FALSE;
EMFDRV_UpdateBBox( dev, &bounds );
return TRUE;
}
/***********************************************************************
* EMFDRV_Arc
*/
BOOL EMFDRV_Arc( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
INT xstart, INT ystart, INT xend, INT yend )
{
return EMFDRV_ArcChordPie( dev, left, top, right, bottom, xstart, ystart,
xend, yend, EMR_ARC );
}
/***********************************************************************
* EMFDRV_Pie
*/
BOOL EMFDRV_Pie( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
INT xstart, INT ystart, INT xend, INT yend )
{
return EMFDRV_ArcChordPie( dev, left, top, right, bottom, xstart, ystart,
xend, yend, EMR_PIE );
}
/***********************************************************************
* EMFDRV_Chord
*/
BOOL EMFDRV_Chord( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
INT xstart, INT ystart, INT xend, INT yend )
{
return EMFDRV_ArcChordPie( dev, left, top, right, bottom, xstart, ystart,
xend, yend, EMR_CHORD );
}
/***********************************************************************
* EMFDRV_Ellipse
*/
BOOL EMFDRV_Ellipse( PHYSDEV dev, INT left, INT top, INT right, INT bottom )
{
EMRELLIPSE emr;
INT temp;
TRACE("%d,%d - %d,%d\n", left, top, right, bottom);
if(left == right || top == bottom) return FALSE;
if(left > right) {temp = left; left = right; right = temp;}
if(top > bottom) {temp = top; top = bottom; bottom = temp;}
if(GetGraphicsMode( dev->hdc ) == GM_COMPATIBLE) {
right--;
bottom--;
}
emr.emr.iType = EMR_ELLIPSE;
emr.emr.nSize = sizeof(emr);
emr.rclBox.left = left;
emr.rclBox.top = top;
emr.rclBox.right = right;
emr.rclBox.bottom = bottom;
EMFDRV_UpdateBBox( dev, &emr.rclBox );
return EMFDRV_WriteRecord( dev, &emr.emr );
}
/***********************************************************************
* EMFDRV_Rectangle
*/
BOOL EMFDRV_Rectangle(PHYSDEV dev, INT left, INT top, INT right, INT bottom)
{
EMRRECTANGLE emr;
INT temp;
TRACE("%d,%d - %d,%d\n", left, top, right, bottom);
if(left == right || top == bottom) return FALSE;
if(left > right) {temp = left; left = right; right = temp;}
if(top > bottom) {temp = top; top = bottom; bottom = temp;}
if(GetGraphicsMode( dev->hdc ) == GM_COMPATIBLE) {
right--;
bottom--;
}
emr.emr.iType = EMR_RECTANGLE;
emr.emr.nSize = sizeof(emr);
emr.rclBox.left = left;
emr.rclBox.top = top;
emr.rclBox.right = right;
emr.rclBox.bottom = bottom;
EMFDRV_UpdateBBox( dev, &emr.rclBox );
return EMFDRV_WriteRecord( dev, &emr.emr );
}
/***********************************************************************
* EMFDRV_RoundRect
*/
BOOL EMFDRV_RoundRect( PHYSDEV dev, INT left, INT top, INT right,
INT bottom, INT ell_width, INT ell_height )
{
EMRROUNDRECT emr;
INT temp;
if(left == right || top == bottom) return FALSE;
if(left > right) {temp = left; left = right; right = temp;}
if(top > bottom) {temp = top; top = bottom; bottom = temp;}
if(GetGraphicsMode( dev->hdc ) == GM_COMPATIBLE) {
right--;
bottom--;
}
emr.emr.iType = EMR_ROUNDRECT;
emr.emr.nSize = sizeof(emr);
emr.rclBox.left = left;
emr.rclBox.top = top;
emr.rclBox.right = right;
emr.rclBox.bottom = bottom;
emr.szlCorner.cx = ell_width;
emr.szlCorner.cy = ell_height;
EMFDRV_UpdateBBox( dev, &emr.rclBox );
return EMFDRV_WriteRecord( dev, &emr.emr );
}
/***********************************************************************
* EMFDRV_SetPixel
*/
COLORREF EMFDRV_SetPixel( PHYSDEV dev, INT x, INT y, COLORREF color )
{
EMRSETPIXELV emr;
emr.emr.iType = EMR_SETPIXELV;
emr.emr.nSize = sizeof(emr);
emr.ptlPixel.x = x;
emr.ptlPixel.y = y;
emr.crColor = color;
if (EMFDRV_WriteRecord( dev, &emr.emr )) {
RECTL bounds;
bounds.left = bounds.right = x;
bounds.top = bounds.bottom = y;
EMFDRV_UpdateBBox( dev, &bounds );
return color;
}
return -1;
}
/**********************************************************************
* EMFDRV_Polylinegon
*
* Helper for EMFDRV_Poly{line|gon}
*/
static BOOL
EMFDRV_Polylinegon( PHYSDEV dev, const POINT* pt, INT count, DWORD iType )
{
EMRPOLYLINE *emr;
DWORD size;
INT i;
BOOL ret;
size = sizeof(EMRPOLYLINE) + sizeof(POINTL) * (count - 1);
emr = HeapAlloc( GetProcessHeap(), 0, size );
emr->emr.iType = iType;
emr->emr.nSize = size;
emr->rclBounds.left = emr->rclBounds.right = pt[0].x;
emr->rclBounds.top = emr->rclBounds.bottom = pt[0].y;
for(i = 1; i < count; i++) {
if(pt[i].x < emr->rclBounds.left)
emr->rclBounds.left = pt[i].x;
else if(pt[i].x > emr->rclBounds.right)
emr->rclBounds.right = pt[i].x;
if(pt[i].y < emr->rclBounds.top)
emr->rclBounds.top = pt[i].y;
else if(pt[i].y > emr->rclBounds.bottom)
emr->rclBounds.bottom = pt[i].y;
}
emr->cptl = count;
memcpy(emr->aptl, pt, count * sizeof(POINTL));
ret = EMFDRV_WriteRecord( dev, &emr->emr );
if(ret)
EMFDRV_UpdateBBox( dev, &emr->rclBounds );
HeapFree( GetProcessHeap(), 0, emr );
return ret;
}
/**********************************************************************
* EMFDRV_Polylinegon16
*
* Helper for EMFDRV_Poly{line|gon}
*
* This is not a legacy function!
* We are using SHORT integers to save space.
*/
static BOOL
EMFDRV_Polylinegon16( PHYSDEV dev, const POINT* pt, INT count, DWORD iType )
{
EMRPOLYLINE16 *emr;
DWORD size;
INT i;
BOOL ret;
/* check whether all points fit in the SHORT int POINT structure */
for(i = 0; i < count; i++) {
if( ((pt[i].x+0x8000) & ~0xffff ) ||
((pt[i].y+0x8000) & ~0xffff ) )
return FALSE;
}
size = sizeof(EMRPOLYLINE16) + sizeof(POINTS) * (count - 1);
emr = HeapAlloc( GetProcessHeap(), 0, size );
emr->emr.iType = iType;
emr->emr.nSize = size;
emr->rclBounds.left = emr->rclBounds.right = pt[0].x;
emr->rclBounds.top = emr->rclBounds.bottom = pt[0].y;
for(i = 1; i < count; i++) {
if(pt[i].x < emr->rclBounds.left)
emr->rclBounds.left = pt[i].x;
else if(pt[i].x > emr->rclBounds.right)
emr->rclBounds.right = pt[i].x;
if(pt[i].y < emr->rclBounds.top)
emr->rclBounds.top = pt[i].y;
else if(pt[i].y > emr->rclBounds.bottom)
emr->rclBounds.bottom = pt[i].y;
}
emr->cpts = count;
for(i = 0; i < count; i++ ) {
emr->apts[i].x = pt[i].x;
emr->apts[i].y = pt[i].y;
}
ret = EMFDRV_WriteRecord( dev, &emr->emr );
if(ret)
EMFDRV_UpdateBBox( dev, &emr->rclBounds );
HeapFree( GetProcessHeap(), 0, emr );
return ret;
}
/**********************************************************************
* EMFDRV_Polyline
*/
BOOL EMFDRV_Polyline( PHYSDEV dev, const POINT* pt, INT count )
{
if( EMFDRV_Polylinegon16( dev, pt, count, EMR_POLYLINE16 ) )
return TRUE;
return EMFDRV_Polylinegon( dev, pt, count, EMR_POLYLINE );
}
/**********************************************************************
* EMFDRV_Polygon
*/
BOOL EMFDRV_Polygon( PHYSDEV dev, const POINT* pt, INT count )
{
if(count < 2) return FALSE;
if( EMFDRV_Polylinegon16( dev, pt, count, EMR_POLYGON16 ) )
return TRUE;
return EMFDRV_Polylinegon( dev, pt, count, EMR_POLYGON );
}
/**********************************************************************
* EMFDRV_PolyBezier
*/
BOOL EMFDRV_PolyBezier( PHYSDEV dev, const POINT *pts, DWORD count )
{
if(EMFDRV_Polylinegon16( dev, pts, count, EMR_POLYBEZIER16 ))
return TRUE;
return EMFDRV_Polylinegon( dev, pts, count, EMR_POLYBEZIER );
}
/**********************************************************************
* EMFDRV_PolyBezierTo
*/
BOOL EMFDRV_PolyBezierTo( PHYSDEV dev, const POINT *pts, DWORD count )
{
if(EMFDRV_Polylinegon16( dev, pts, count, EMR_POLYBEZIERTO16 ))
return TRUE;
return EMFDRV_Polylinegon( dev, pts, count, EMR_POLYBEZIERTO );
}
/**********************************************************************
* EMFDRV_PolyPolylinegon
*
* Helper for EMFDRV_PolyPoly{line|gon}
*/
static BOOL
EMFDRV_PolyPolylinegon( PHYSDEV dev, const POINT* pt, const INT* counts, UINT polys,
DWORD iType)
{
EMRPOLYPOLYLINE *emr;
DWORD cptl = 0, poly, size;
INT point;
RECTL bounds;
const POINT *pts;
BOOL ret;
bounds.left = bounds.right = pt[0].x;
bounds.top = bounds.bottom = pt[0].y;
pts = pt;
for(poly = 0; poly < polys; poly++) {
cptl += counts[poly];
for(point = 0; point < counts[poly]; point++) {
if(bounds.left > pts->x) bounds.left = pts->x;
else if(bounds.right < pts->x) bounds.right = pts->x;
if(bounds.top > pts->y) bounds.top = pts->y;
else if(bounds.bottom < pts->y) bounds.bottom = pts->y;
pts++;
}
}
size = sizeof(EMRPOLYPOLYLINE) + (polys - 1) * sizeof(DWORD) +
(cptl - 1) * sizeof(POINTL);
emr = HeapAlloc( GetProcessHeap(), 0, size );
emr->emr.iType = iType;
emr->emr.nSize = size;
emr->rclBounds = bounds;
emr->nPolys = polys;
emr->cptl = cptl;
memcpy(emr->aPolyCounts, counts, polys * sizeof(DWORD));
memcpy(emr->aPolyCounts + polys, pt, cptl * sizeof(POINTL));
ret = EMFDRV_WriteRecord( dev, &emr->emr );
if(ret)
EMFDRV_UpdateBBox( dev, &emr->rclBounds );
HeapFree( GetProcessHeap(), 0, emr );
return ret;
}
/**********************************************************************
* EMFDRV_PolyPolyline
*/
BOOL EMFDRV_PolyPolyline(PHYSDEV dev, const POINT* pt, const DWORD* counts, DWORD polys)
{
return EMFDRV_PolyPolylinegon( dev, pt, (const INT *)counts, polys,
EMR_POLYPOLYLINE );
}
/**********************************************************************
* EMFDRV_PolyPolygon
*/
BOOL EMFDRV_PolyPolygon( PHYSDEV dev, const POINT* pt, const INT* counts, UINT polys )
{
return EMFDRV_PolyPolylinegon( dev, pt, counts, polys, EMR_POLYPOLYGON );
}
/**********************************************************************
* EMFDRV_ExtFloodFill
*/
BOOL EMFDRV_ExtFloodFill( PHYSDEV dev, INT x, INT y, COLORREF color, UINT fillType )
{
EMREXTFLOODFILL emr;
emr.emr.iType = EMR_EXTFLOODFILL;
emr.emr.nSize = sizeof(emr);
emr.ptlStart.x = x;
emr.ptlStart.y = y;
emr.crColor = color;
emr.iMode = fillType;
return EMFDRV_WriteRecord( dev, &emr.emr );
}
/*********************************************************************
* EMFDRV_FillRgn
*/
BOOL EMFDRV_FillRgn( PHYSDEV dev, HRGN hrgn, HBRUSH hbrush )
{
EMRFILLRGN *emr;
DWORD size, rgnsize, index;
BOOL ret;
index = EMFDRV_CreateBrushIndirect( dev, hbrush );
if(!index) return FALSE;
rgnsize = GetRegionData( hrgn, 0, NULL );
size = rgnsize + offsetof(EMRFILLRGN,RgnData);
emr = HeapAlloc( GetProcessHeap(), 0, size );
GetRegionData( hrgn, rgnsize, (RGNDATA *)&emr->RgnData );
emr->emr.iType = EMR_FILLRGN;
emr->emr.nSize = size;
emr->rclBounds.left = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.left;
emr->rclBounds.top = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.top;
emr->rclBounds.right = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.right - 1;
emr->rclBounds.bottom = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.bottom - 1;
emr->cbRgnData = rgnsize;
emr->ihBrush = index;
ret = EMFDRV_WriteRecord( dev, &emr->emr );
if(ret)
EMFDRV_UpdateBBox( dev, &emr->rclBounds );
HeapFree( GetProcessHeap(), 0, emr );
return ret;
}
/*********************************************************************
* EMFDRV_FrameRgn
*/
BOOL EMFDRV_FrameRgn( PHYSDEV dev, HRGN hrgn, HBRUSH hbrush, INT width, INT height )
{
EMRFRAMERGN *emr;
DWORD size, rgnsize, index;
BOOL ret;
index = EMFDRV_CreateBrushIndirect( dev, hbrush );
if(!index) return FALSE;
rgnsize = GetRegionData( hrgn, 0, NULL );
size = rgnsize + offsetof(EMRFRAMERGN,RgnData);
emr = HeapAlloc( GetProcessHeap(), 0, size );
GetRegionData( hrgn, rgnsize, (RGNDATA *)&emr->RgnData );
emr->emr.iType = EMR_FRAMERGN;
emr->emr.nSize = size;
emr->rclBounds.left = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.left;
emr->rclBounds.top = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.top;
emr->rclBounds.right = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.right - 1;
emr->rclBounds.bottom = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.bottom - 1;
emr->cbRgnData = rgnsize;
emr->ihBrush = index;
emr->szlStroke.cx = width;
emr->szlStroke.cy = height;
ret = EMFDRV_WriteRecord( dev, &emr->emr );
if(ret)
EMFDRV_UpdateBBox( dev, &emr->rclBounds );
HeapFree( GetProcessHeap(), 0, emr );
return ret;
}
/*********************************************************************
* EMFDRV_PaintInvertRgn
*
* Helper for EMFDRV_{Paint|Invert}Rgn
*/
static BOOL EMFDRV_PaintInvertRgn( PHYSDEV dev, HRGN hrgn, DWORD iType )
{
EMRINVERTRGN *emr;
DWORD size, rgnsize;
BOOL ret;
rgnsize = GetRegionData( hrgn, 0, NULL );
size = rgnsize + offsetof(EMRINVERTRGN,RgnData);
emr = HeapAlloc( GetProcessHeap(), 0, size );
GetRegionData( hrgn, rgnsize, (RGNDATA *)&emr->RgnData );
emr->emr.iType = iType;
emr->emr.nSize = size;
emr->rclBounds.left = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.left;
emr->rclBounds.top = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.top;
emr->rclBounds.right = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.right - 1;
emr->rclBounds.bottom = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.bottom - 1;
emr->cbRgnData = rgnsize;
ret = EMFDRV_WriteRecord( dev, &emr->emr );
if(ret)
EMFDRV_UpdateBBox( dev, &emr->rclBounds );
HeapFree( GetProcessHeap(), 0, emr );
return ret;
}
/**********************************************************************
* EMFDRV_PaintRgn
*/
BOOL EMFDRV_PaintRgn( PHYSDEV dev, HRGN hrgn )
{
return EMFDRV_PaintInvertRgn( dev, hrgn, EMR_PAINTRGN );
}
/**********************************************************************
* EMFDRV_InvertRgn
*/
BOOL EMFDRV_InvertRgn( PHYSDEV dev, HRGN hrgn )
{
return EMFDRV_PaintInvertRgn( dev, hrgn, EMR_INVERTRGN );
}
/**********************************************************************
* EMFDRV_ExtTextOut
*/
BOOL EMFDRV_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags, const RECT *lprect,
LPCWSTR str, UINT count, const INT *lpDx )
{
EMREXTTEXTOUTW *pemr;
DWORD nSize;
BOOL ret;
int textHeight = 0;
int textWidth = 0;
const UINT textAlign = GetTextAlign( dev->hdc );
const INT graphicsMode = GetGraphicsMode( dev->hdc );
FLOAT exScale, eyScale;
nSize = sizeof(*pemr) + ((count+1) & ~1) * sizeof(WCHAR) + count * sizeof(INT);
TRACE("%s %s count %d nSize = %d\n", debugstr_wn(str, count),
wine_dbgstr_rect(lprect), count, nSize);
pemr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nSize);
if (graphicsMode == GM_COMPATIBLE)
{
const INT horzSize = GetDeviceCaps( dev->hdc, HORZSIZE );
const INT horzRes = GetDeviceCaps( dev->hdc, HORZRES );
const INT vertSize = GetDeviceCaps( dev->hdc, VERTSIZE );
const INT vertRes = GetDeviceCaps( dev->hdc, VERTRES );
SIZE wndext, vportext;
GetViewportExtEx( dev->hdc, &vportext );
GetWindowExtEx( dev->hdc, &wndext );
exScale = 100.0 * ((FLOAT)horzSize / (FLOAT)horzRes) /
((FLOAT)wndext.cx / (FLOAT)vportext.cx);
eyScale = 100.0 * ((FLOAT)vertSize / (FLOAT)vertRes) /
((FLOAT)wndext.cy / (FLOAT)vportext.cy);
}
else
{
exScale = 0.0;
eyScale = 0.0;
}
pemr->emr.iType = EMR_EXTTEXTOUTW;
pemr->emr.nSize = nSize;
pemr->iGraphicsMode = graphicsMode;
pemr->exScale = exScale;
pemr->eyScale = eyScale;
pemr->emrtext.ptlReference.x = x;
pemr->emrtext.ptlReference.y = y;
pemr->emrtext.nChars = count;
pemr->emrtext.offString = sizeof(*pemr);
memcpy((char*)pemr + pemr->emrtext.offString, str, count * sizeof(WCHAR));
pemr->emrtext.fOptions = flags;
if(!lprect) {
pemr->emrtext.rcl.left = pemr->emrtext.rcl.top = 0;
pemr->emrtext.rcl.right = pemr->emrtext.rcl.bottom = -1;
} else {
pemr->emrtext.rcl.left = lprect->left;
pemr->emrtext.rcl.top = lprect->top;
pemr->emrtext.rcl.right = lprect->right;
pemr->emrtext.rcl.bottom = lprect->bottom;
}
pemr->emrtext.offDx = pemr->emrtext.offString + ((count+1) & ~1) * sizeof(WCHAR);
if(lpDx) {
UINT i;
SIZE strSize;
memcpy((char*)pemr + pemr->emrtext.offDx, lpDx, count * sizeof(INT));
for (i = 0; i < count; i++) {
textWidth += lpDx[i];
}
if (GetTextExtentPoint32W( dev->hdc, str, count, &strSize ))
textHeight = strSize.cy;
}
else {
UINT i;
INT *dx = (INT *)((char*)pemr + pemr->emrtext.offDx);
SIZE charSize;
for (i = 0; i < count; i++) {
if (GetTextExtentPoint32W( dev->hdc, str + i, 1, &charSize )) {
dx[i] = charSize.cx;
textWidth += charSize.cx;
textHeight = max(textHeight, charSize.cy);
}
}
}
if (!lprect)
{
pemr->rclBounds.left = pemr->rclBounds.top = 0;
pemr->rclBounds.right = pemr->rclBounds.bottom = -1;
goto no_bounds;
}
switch (textAlign & (TA_LEFT | TA_RIGHT | TA_CENTER)) {
case TA_CENTER: {
pemr->rclBounds.left = x - (textWidth / 2) - 1;
pemr->rclBounds.right = x + (textWidth / 2) + 1;
break;
}
case TA_RIGHT: {
pemr->rclBounds.left = x - textWidth - 1;
pemr->rclBounds.right = x;
break;
}
default: { /* TA_LEFT */
pemr->rclBounds.left = x;
pemr->rclBounds.right = x + textWidth + 1;
}
}
switch (textAlign & (TA_TOP | TA_BOTTOM | TA_BASELINE)) {
case TA_BASELINE: {
TEXTMETRICW tm;
if (!GetTextMetricsW( dev->hdc, &tm ))
tm.tmDescent = 0;
/* Play safe here... it's better to have a bounding box */
/* that is too big than too small. */
pemr->rclBounds.top = y - textHeight - 1;
pemr->rclBounds.bottom = y + tm.tmDescent + 1;
break;
}
case TA_BOTTOM: {
pemr->rclBounds.top = y - textHeight - 1;
pemr->rclBounds.bottom = y;
break;
}
default: { /* TA_TOP */
pemr->rclBounds.top = y;
pemr->rclBounds.bottom = y + textHeight + 1;
}
}
EMFDRV_UpdateBBox( dev, &pemr->rclBounds );
no_bounds:
ret = EMFDRV_WriteRecord( dev, &pemr->emr );
HeapFree( GetProcessHeap(), 0, pemr );
return ret;
}

View File

@ -0,0 +1,510 @@
/*
* Enhanced MetaFile driver initialisation functions
*
* Copyright 1999 Huw D M Davies
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <assert.h>
#include <stdarg.h>
#include <string.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winnls.h"
#include "gdi_private.h"
#include "enhmfdrv/enhmetafiledrv.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(enhmetafile);
static BOOL EMFDRV_DeleteDC( PHYSDEV dev );
static const struct gdi_dc_funcs EMFDRV_Funcs =
{
NULL, /* pAbortDoc */
EMFDRV_AbortPath, /* pAbortPath */
NULL, /* pAlphaBlend */
NULL, /* pAngleArc */
EMFDRV_Arc, /* pArc */
NULL, /* pArcTo */
EMFDRV_BeginPath, /* pBeginPath */
NULL, /* pBlendImage */
EMFDRV_Chord, /* pChord */
EMFDRV_CloseFigure, /* pCloseFigure */
NULL, /* pCreateCompatibleDC */
NULL, /* pCreateDC */
EMFDRV_DeleteDC, /* pDeleteDC */
EMFDRV_DeleteObject, /* pDeleteObject */
NULL, /* pDeviceCapabilities */
EMFDRV_Ellipse, /* pEllipse */
NULL, /* pEndDoc */
NULL, /* pEndPage */
EMFDRV_EndPath, /* pEndPath */
NULL, /* pEnumFonts */
NULL, /* pEnumICMProfiles */
EMFDRV_ExcludeClipRect, /* pExcludeClipRect */
NULL, /* pExtDeviceMode */
NULL, /* pExtEscape */
EMFDRV_ExtFloodFill, /* pExtFloodFill */
EMFDRV_ExtSelectClipRgn, /* pExtSelectClipRgn */
EMFDRV_ExtTextOut, /* pExtTextOut */
EMFDRV_FillPath, /* pFillPath */
EMFDRV_FillRgn, /* pFillRgn */
EMFDRV_FlattenPath, /* pFlattenPath */
NULL, /* pFontIsLinked */
EMFDRV_FrameRgn, /* pFrameRgn */
EMFDRV_GdiComment, /* pGdiComment */
NULL, /* pGdiRealizationInfo */
NULL, /* pGetBoundsRect */
NULL, /* pGetCharABCWidths */
NULL, /* pGetCharABCWidthsI */
NULL, /* pGetCharWidth */
EMFDRV_GetDeviceCaps, /* pGetDeviceCaps */
NULL, /* pGetDeviceGammaRamp */
NULL, /* pGetFontData */
NULL, /* pGetFontUnicodeRanges */
NULL, /* pGetGlyphIndices */
NULL, /* pGetGlyphOutline */
NULL, /* pGetICMProfile */
NULL, /* pGetImage */
NULL, /* pGetKerningPairs */
NULL, /* pGetNearestColor */
NULL, /* pGetOutlineTextMetrics */
NULL, /* pGetPixel */
NULL, /* pGetSystemPaletteEntries */
NULL, /* pGetTextCharsetInfo */
NULL, /* pGetTextExtentExPoint */
NULL, /* pGetTextExtentExPointI */
NULL, /* pGetTextFace */
NULL, /* pGetTextMetrics */
NULL, /* pGradientFill */
EMFDRV_IntersectClipRect, /* pIntersectClipRect */
EMFDRV_InvertRgn, /* pInvertRgn */
EMFDRV_LineTo, /* pLineTo */
EMFDRV_ModifyWorldTransform, /* pModifyWorldTransform */
EMFDRV_MoveTo, /* pMoveTo */
EMFDRV_OffsetClipRgn, /* pOffsetClipRgn */
EMFDRV_OffsetViewportOrgEx, /* pOffsetViewportOrgEx */
EMFDRV_OffsetWindowOrgEx, /* pOffsetWindowOrgEx */
EMFDRV_PaintRgn, /* pPaintRgn */
EMFDRV_PatBlt, /* pPatBlt */
EMFDRV_Pie, /* pPie */
EMFDRV_PolyBezier, /* pPolyBezier */
EMFDRV_PolyBezierTo, /* pPolyBezierTo */
NULL, /* pPolyDraw */
EMFDRV_PolyPolygon, /* pPolyPolygon */
EMFDRV_PolyPolyline, /* pPolyPolyline */
EMFDRV_Polygon, /* pPolygon */
EMFDRV_Polyline, /* pPolyline */
NULL, /* pPolylineTo */
NULL, /* pPutImage */
NULL, /* pRealizeDefaultPalette */
NULL, /* pRealizePalette */
EMFDRV_Rectangle, /* pRectangle */
NULL, /* pResetDC */
EMFDRV_RestoreDC, /* pRestoreDC */
EMFDRV_RoundRect, /* pRoundRect */
EMFDRV_SaveDC, /* pSaveDC */
EMFDRV_ScaleViewportExtEx, /* pScaleViewportExtEx */
EMFDRV_ScaleWindowExtEx, /* pScaleWindowExtEx */
EMFDRV_SelectBitmap, /* pSelectBitmap */
EMFDRV_SelectBrush, /* pSelectBrush */
EMFDRV_SelectClipPath, /* pSelectClipPath */
EMFDRV_SelectFont, /* pSelectFont */
EMFDRV_SelectPalette, /* pSelectPalette */
EMFDRV_SelectPen, /* pSelectPen */
EMFDRV_SetArcDirection, /* pSetArcDirection */
EMFDRV_SetBkColor, /* pSetBkColor */
EMFDRV_SetBkMode, /* pSetBkMode */
NULL, /* pSetBoundsRect */
EMFDRV_SetDCBrushColor, /* pSetDCBrushColor*/
EMFDRV_SetDCPenColor, /* pSetDCPenColor*/
EMFDRV_SetDIBitsToDevice, /* pSetDIBitsToDevice */
NULL, /* pSetDeviceClipping */
NULL, /* pSetDeviceGammaRamp */
EMFDRV_SetLayout, /* pSetLayout */
EMFDRV_SetMapMode, /* pSetMapMode */
EMFDRV_SetMapperFlags, /* pSetMapperFlags */
EMFDRV_SetPixel, /* pSetPixel */
EMFDRV_SetPolyFillMode, /* pSetPolyFillMode */
EMFDRV_SetROP2, /* pSetROP2 */
NULL, /* pSetRelAbs */
EMFDRV_SetStretchBltMode, /* pSetStretchBltMode */
EMFDRV_SetTextAlign, /* pSetTextAlign */
NULL, /* pSetTextCharacterExtra */
EMFDRV_SetTextColor, /* pSetTextColor */
EMFDRV_SetTextJustification, /* pSetTextJustification */
EMFDRV_SetViewportExtEx, /* pSetViewportExtEx */
EMFDRV_SetViewportOrgEx, /* pSetViewportOrgEx */
EMFDRV_SetWindowExtEx, /* pSetWindowExtEx */
EMFDRV_SetWindowOrgEx, /* pSetWindowOrgEx */
EMFDRV_SetWorldTransform, /* pSetWorldTransform */
NULL, /* pStartDoc */
NULL, /* pStartPage */
EMFDRV_StretchBlt, /* pStretchBlt */
EMFDRV_StretchDIBits, /* pStretchDIBits */
EMFDRV_StrokeAndFillPath, /* pStrokeAndFillPath */
EMFDRV_StrokePath, /* pStrokePath */
NULL, /* pUnrealizePalette */
EMFDRV_WidenPath, /* pWidenPath */
NULL, /* wine_get_wgl_driver */
GDI_PRIORITY_GRAPHICS_DRV /* priority */
};
/**********************************************************************
* EMFDRV_DeleteDC
*/
static BOOL EMFDRV_DeleteDC( PHYSDEV dev )
{
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE *)dev;
UINT index;
if (physDev->emh) HeapFree( GetProcessHeap(), 0, physDev->emh );
for(index = 0; index < physDev->handles_size; index++)
if(physDev->handles[index])
GDI_hdc_not_using_object(physDev->handles[index], dev->hdc);
HeapFree( GetProcessHeap(), 0, physDev->handles );
HeapFree( GetProcessHeap(), 0, physDev );
return TRUE;
}
/******************************************************************
* EMFDRV_WriteRecord
*
* Warning: this function can change the pointer to the metafile header.
*/
BOOL EMFDRV_WriteRecord( PHYSDEV dev, EMR *emr )
{
DWORD len;
DWORD bytes_written;
ENHMETAHEADER *emh;
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE *)dev;
TRACE("record %d, size %d %s\n",
emr->iType, emr->nSize, physDev->hFile ? "(to disk)" : "");
assert( !(emr->nSize & 3) );
physDev->emh->nBytes += emr->nSize;
physDev->emh->nRecords++;
if(physDev->hFile) {
if (!WriteFile(physDev->hFile, emr, emr->nSize, &bytes_written, NULL))
return FALSE;
} else {
DWORD nEmfSize = HeapSize(GetProcessHeap(), 0, physDev->emh);
len = physDev->emh->nBytes;
if (len > nEmfSize) {
nEmfSize += (nEmfSize / 2) + emr->nSize;
emh = HeapReAlloc(GetProcessHeap(), 0, physDev->emh, nEmfSize);
if (!emh) return FALSE;
physDev->emh = emh;
}
memcpy((CHAR *)physDev->emh + physDev->emh->nBytes - emr->nSize, emr,
emr->nSize);
}
return TRUE;
}
/******************************************************************
* EMFDRV_UpdateBBox
*/
void EMFDRV_UpdateBBox( PHYSDEV dev, RECTL *rect )
{
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE *)dev;
RECTL *bounds = &physDev->emh->rclBounds;
RECTL vportRect = *rect;
LPtoDP( dev->hdc, (LPPOINT)&vportRect, 2 );
/* The coordinate systems may be mirrored
(LPtoDP handles points, not rectangles) */
if (vportRect.left > vportRect.right)
{
LONG temp = vportRect.right;
vportRect.right = vportRect.left;
vportRect.left = temp;
}
if (vportRect.top > vportRect.bottom)
{
LONG temp = vportRect.bottom;
vportRect.bottom = vportRect.top;
vportRect.top = temp;
}
if (bounds->left > bounds->right)
{
/* first bounding rectangle */
*bounds = vportRect;
}
else
{
bounds->left = min(bounds->left, vportRect.left);
bounds->top = min(bounds->top, vportRect.top);
bounds->right = max(bounds->right, vportRect.right);
bounds->bottom = max(bounds->bottom, vportRect.bottom);
}
}
/**********************************************************************
* CreateEnhMetaFileA (GDI32.@)
*/
HDC WINAPI CreateEnhMetaFileA(
HDC hdc, /* [in] optional reference DC */
LPCSTR filename, /* [in] optional filename for disk metafiles */
const RECT *rect, /* [in] optional bounding rectangle */
LPCSTR description /* [in] optional description */
)
{
LPWSTR filenameW = NULL;
LPWSTR descriptionW = NULL;
HDC hReturnDC;
DWORD len1, len2, total;
if(filename)
{
total = MultiByteToWideChar( CP_ACP, 0, filename, -1, NULL, 0 );
filenameW = HeapAlloc( GetProcessHeap(), 0, total * sizeof(WCHAR) );
MultiByteToWideChar( CP_ACP, 0, filename, -1, filenameW, total );
}
if(description) {
len1 = strlen(description);
len2 = strlen(description + len1 + 1);
total = MultiByteToWideChar( CP_ACP, 0, description, len1 + len2 + 3, NULL, 0 );
descriptionW = HeapAlloc( GetProcessHeap(), 0, total * sizeof(WCHAR) );
MultiByteToWideChar( CP_ACP, 0, description, len1 + len2 + 3, descriptionW, total );
}
hReturnDC = CreateEnhMetaFileW(hdc, filenameW, rect, descriptionW);
HeapFree( GetProcessHeap(), 0, filenameW );
HeapFree( GetProcessHeap(), 0, descriptionW );
return hReturnDC;
}
/**********************************************************************
* CreateEnhMetaFileW (GDI32.@)
*/
HDC WINAPI CreateEnhMetaFileW(
HDC hdc, /* [in] optional reference DC */
LPCWSTR filename, /* [in] optional filename for disk metafiles */
const RECT* rect, /* [in] optional bounding rectangle */
LPCWSTR description /* [in] optional description */
)
{
static const WCHAR displayW[] = {'D','I','S','P','L','A','Y',0};
HDC ret;
DC *dc;
EMFDRV_PDEVICE *physDev;
HANDLE hFile;
DWORD size = 0, length = 0;
DWORD bytes_written;
TRACE("%s\n", debugstr_w(filename) );
if (!(dc = alloc_dc_ptr( OBJ_ENHMETADC ))) return 0;
physDev = HeapAlloc(GetProcessHeap(),0,sizeof(*physDev));
if (!physDev) {
free_dc_ptr( dc );
return 0;
}
if(description) { /* App name\0Title\0\0 */
length = lstrlenW(description);
length += lstrlenW(description + length + 1);
length += 3;
length *= 2;
}
size = sizeof(ENHMETAHEADER) + (length + 3) / 4 * 4;
if (!(physDev->emh = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size))) {
HeapFree( GetProcessHeap(), 0, physDev );
free_dc_ptr( dc );
return 0;
}
push_dc_driver( &dc->physDev, &physDev->dev, &EMFDRV_Funcs );
physDev->handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, HANDLE_LIST_INC * sizeof(physDev->handles[0]));
physDev->handles_size = HANDLE_LIST_INC;
physDev->cur_handles = 1;
physDev->hFile = 0;
physDev->dc_brush = 0;
physDev->dc_pen = 0;
physDev->screen_dc = 0;
physDev->restoring = 0;
if (hdc) /* if no ref, use current display */
physDev->ref_dc = hdc;
else
physDev->ref_dc = physDev->screen_dc = CreateDCW( displayW, NULL, NULL, NULL );
SetVirtualResolution(physDev->dev.hdc, 0, 0, 0, 0);
physDev->emh->iType = EMR_HEADER;
physDev->emh->nSize = size;
physDev->emh->rclBounds.left = physDev->emh->rclBounds.top = 0;
physDev->emh->rclBounds.right = physDev->emh->rclBounds.bottom = -1;
if(rect) {
physDev->emh->rclFrame.left = rect->left;
physDev->emh->rclFrame.top = rect->top;
physDev->emh->rclFrame.right = rect->right;
physDev->emh->rclFrame.bottom = rect->bottom;
} else { /* Set this to {0,0 - -1,-1} and update it at the end */
physDev->emh->rclFrame.left = physDev->emh->rclFrame.top = 0;
physDev->emh->rclFrame.right = physDev->emh->rclFrame.bottom = -1;
}
physDev->emh->dSignature = ENHMETA_SIGNATURE;
physDev->emh->nVersion = 0x10000;
physDev->emh->nBytes = physDev->emh->nSize;
physDev->emh->nRecords = 1;
physDev->emh->nHandles = 1;
physDev->emh->sReserved = 0; /* According to docs, this is reserved and must be 0 */
physDev->emh->nDescription = length / 2;
physDev->emh->offDescription = length ? sizeof(ENHMETAHEADER) : 0;
physDev->emh->nPalEntries = 0; /* I guess this should start at 0 */
/* Size in pixels */
physDev->emh->szlDevice.cx = GetDeviceCaps( physDev->ref_dc, HORZRES );
physDev->emh->szlDevice.cy = GetDeviceCaps( physDev->ref_dc, VERTRES );
/* Size in millimeters */
physDev->emh->szlMillimeters.cx = GetDeviceCaps( physDev->ref_dc, HORZSIZE );
physDev->emh->szlMillimeters.cy = GetDeviceCaps( physDev->ref_dc, VERTSIZE );
/* Size in micrometers */
physDev->emh->szlMicrometers.cx = physDev->emh->szlMillimeters.cx * 1000;
physDev->emh->szlMicrometers.cy = physDev->emh->szlMillimeters.cy * 1000;
memcpy((char *)physDev->emh + sizeof(ENHMETAHEADER), description, length);
if (filename) /* disk based metafile */
{
if ((hFile = CreateFileW(filename, GENERIC_WRITE | GENERIC_READ, 0,
NULL, CREATE_ALWAYS, 0, 0)) == INVALID_HANDLE_VALUE) {
free_dc_ptr( dc );
return 0;
}
if (!WriteFile( hFile, physDev->emh, size, &bytes_written, NULL )) {
free_dc_ptr( dc );
CloseHandle( hFile );
return 0;
}
physDev->hFile = hFile;
}
TRACE("returning %p\n", physDev->dev.hdc);
ret = physDev->dev.hdc;
release_dc_ptr( dc );
return ret;
}
/******************************************************************
* CloseEnhMetaFile (GDI32.@)
*/
HENHMETAFILE WINAPI CloseEnhMetaFile(HDC hdc) /* [in] metafile DC */
{
HENHMETAFILE hmf;
EMFDRV_PDEVICE *physDev;
DC *dc;
EMREOF emr;
HANDLE hMapping = 0;
TRACE("(%p)\n", hdc );
if (!(dc = get_dc_ptr( hdc ))) return NULL;
if (GetObjectType( hdc ) != OBJ_ENHMETADC)
{
release_dc_ptr( dc );
return NULL;
}
if (dc->refcount != 1)
{
FIXME( "not deleting busy DC %p refcount %u\n", hdc, dc->refcount );
release_dc_ptr( dc );
return NULL;
}
physDev = (EMFDRV_PDEVICE *)dc->physDev;
if(dc->saveLevel)
RestoreDC(hdc, 1);
if (physDev->dc_brush) DeleteObject( physDev->dc_brush );
if (physDev->dc_pen) DeleteObject( physDev->dc_pen );
if (physDev->screen_dc) DeleteDC( physDev->screen_dc );
emr.emr.iType = EMR_EOF;
emr.emr.nSize = sizeof(emr);
emr.nPalEntries = 0;
emr.offPalEntries = FIELD_OFFSET(EMREOF, nSizeLast);
emr.nSizeLast = emr.emr.nSize;
EMFDRV_WriteRecord( dc->physDev, &emr.emr );
/* Update rclFrame if not initialized in CreateEnhMetaFile */
if(physDev->emh->rclFrame.left > physDev->emh->rclFrame.right) {
physDev->emh->rclFrame.left = physDev->emh->rclBounds.left *
physDev->emh->szlMillimeters.cx * 100 / physDev->emh->szlDevice.cx;
physDev->emh->rclFrame.top = physDev->emh->rclBounds.top *
physDev->emh->szlMillimeters.cy * 100 / physDev->emh->szlDevice.cy;
physDev->emh->rclFrame.right = physDev->emh->rclBounds.right *
physDev->emh->szlMillimeters.cx * 100 / physDev->emh->szlDevice.cx;
physDev->emh->rclFrame.bottom = physDev->emh->rclBounds.bottom *
physDev->emh->szlMillimeters.cy * 100 / physDev->emh->szlDevice.cy;
}
if (physDev->hFile) /* disk based metafile */
{
if (SetFilePointer(physDev->hFile, 0, NULL, FILE_BEGIN) != 0)
{
CloseHandle( physDev->hFile );
free_dc_ptr( dc );
return 0;
}
if (!WriteFile(physDev->hFile, physDev->emh, sizeof(*physDev->emh),
NULL, NULL))
{
CloseHandle( physDev->hFile );
free_dc_ptr( dc );
return 0;
}
HeapFree( GetProcessHeap(), 0, physDev->emh );
hMapping = CreateFileMappingA(physDev->hFile, NULL, PAGE_READONLY, 0,
0, NULL);
TRACE("hMapping = %p\n", hMapping );
physDev->emh = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
TRACE("view = %p\n", physDev->emh );
CloseHandle( hMapping );
CloseHandle( physDev->hFile );
}
hmf = EMF_Create_HENHMETAFILE( physDev->emh, (physDev->hFile != 0) );
physDev->emh = NULL; /* So it won't be deleted */
free_dc_ptr( dc );
return hmf;
}

View File

@ -0,0 +1,528 @@
/*
* Enhanced MetaFile objects
*
* Copyright 1999 Huw D M Davies
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "enhmfdrv/enhmetafiledrv.h"
#include "gdi_private.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(enhmetafile);
/******************************************************************
* EMFDRV_AddHandle
*/
static UINT EMFDRV_AddHandle( PHYSDEV dev, HGDIOBJ obj )
{
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE *)dev;
UINT index;
for(index = 0; index < physDev->handles_size; index++)
if(physDev->handles[index] == 0) break;
if(index == physDev->handles_size) {
physDev->handles_size += HANDLE_LIST_INC;
physDev->handles = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
physDev->handles,
physDev->handles_size * sizeof(physDev->handles[0]));
}
physDev->handles[index] = get_full_gdi_handle( obj );
physDev->cur_handles++;
if(physDev->cur_handles > physDev->emh->nHandles)
physDev->emh->nHandles++;
return index + 1; /* index 0 is reserved for the hmf, so we increment everything by 1 */
}
/******************************************************************
* EMFDRV_FindObject
*/
static UINT EMFDRV_FindObject( PHYSDEV dev, HGDIOBJ obj )
{
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE*) dev;
UINT index;
for(index = 0; index < physDev->handles_size; index++)
if(physDev->handles[index] == obj) break;
if(index == physDev->handles_size) return 0;
return index + 1;
}
/******************************************************************
* EMFDRV_DeleteObject
*/
BOOL EMFDRV_DeleteObject( PHYSDEV dev, HGDIOBJ obj )
{
EMRDELETEOBJECT emr;
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE*) dev;
UINT index;
BOOL ret = TRUE;
if(!(index = EMFDRV_FindObject(dev, obj))) return FALSE;
emr.emr.iType = EMR_DELETEOBJECT;
emr.emr.nSize = sizeof(emr);
emr.ihObject = index;
if(!EMFDRV_WriteRecord( dev, &emr.emr ))
ret = FALSE;
physDev->handles[index - 1] = 0;
physDev->cur_handles--;
return ret;
}
/***********************************************************************
* EMFDRV_SelectBitmap
*/
HBITMAP EMFDRV_SelectBitmap( PHYSDEV dev, HBITMAP hbitmap )
{
return 0;
}
/***********************************************************************
* EMFDRV_CreateBrushIndirect
*/
DWORD EMFDRV_CreateBrushIndirect( PHYSDEV dev, HBRUSH hBrush )
{
DWORD index = 0;
LOGBRUSH logbrush;
if (!GetObjectA( hBrush, sizeof(logbrush), &logbrush )) return 0;
switch (logbrush.lbStyle) {
case BS_SOLID:
case BS_HATCHED:
case BS_NULL:
{
EMRCREATEBRUSHINDIRECT emr;
emr.emr.iType = EMR_CREATEBRUSHINDIRECT;
emr.emr.nSize = sizeof(emr);
emr.ihBrush = index = EMFDRV_AddHandle( dev, hBrush );
emr.lb.lbStyle = logbrush.lbStyle;
emr.lb.lbColor = logbrush.lbColor;
emr.lb.lbHatch = logbrush.lbHatch;
if(!EMFDRV_WriteRecord( dev, &emr.emr ))
index = 0;
}
break;
case BS_PATTERN:
case BS_DIBPATTERN:
{
EMRCREATEDIBPATTERNBRUSHPT *emr;
char buffer[sizeof(BITMAPINFO) + 255 * sizeof(RGBQUAD)]; // ros!
//char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
BITMAPINFO *info = (BITMAPINFO *)buffer;
DWORD info_size;
void *bits;
UINT usage;
if (!get_brush_bitmap_info( hBrush, info, &bits, &usage )) break;
info_size = get_dib_info_size( info, usage );
emr = HeapAlloc( GetProcessHeap(), 0,
sizeof(EMRCREATEDIBPATTERNBRUSHPT)+info_size+info->bmiHeader.biSizeImage );
if(!emr) break;
if (logbrush.lbStyle == BS_PATTERN && info->bmiHeader.biBitCount == 1)
{
/* Presumably to reduce the size of the written EMF, MS supports an
* undocumented iUsage value of 2, indicating a mono bitmap without the
* 8 byte 2 entry black/white palette. Stupidly, they could have saved
* over 20 bytes more by also ignoring the BITMAPINFO fields that are
* irrelevant/constant for monochrome bitmaps.
* FIXME: It may be that the DIB functions themselves accept this value.
*/
emr->emr.iType = EMR_CREATEMONOBRUSH;
usage = DIB_PAL_MONO;
/* FIXME: There is an extra DWORD written by native before the BMI.
* Not sure what its meant to contain.
*/
emr->offBmi = sizeof( EMRCREATEDIBPATTERNBRUSHPT ) + sizeof(DWORD);
emr->cbBmi = sizeof( BITMAPINFOHEADER );
}
else
{
emr->emr.iType = EMR_CREATEDIBPATTERNBRUSHPT;
emr->offBmi = sizeof( EMRCREATEDIBPATTERNBRUSHPT );
emr->cbBmi = info_size;
}
emr->ihBrush = index = EMFDRV_AddHandle( dev, hBrush );
emr->iUsage = usage;
emr->offBits = emr->offBmi + emr->cbBmi;
emr->cbBits = info->bmiHeader.biSizeImage;
emr->emr.nSize = emr->offBits + emr->cbBits;
memcpy( (BYTE *)emr + emr->offBmi, info, emr->cbBmi );
memcpy( (BYTE *)emr + emr->offBits, bits, emr->cbBits );
if(!EMFDRV_WriteRecord( dev, &emr->emr ))
index = 0;
HeapFree( GetProcessHeap(), 0, emr );
}
break;
default:
FIXME("Unknown style %x\n", logbrush.lbStyle);
break;
}
return index;
}
/***********************************************************************
* EMFDRV_SelectBrush
*/
HBRUSH EMFDRV_SelectBrush( PHYSDEV dev, HBRUSH hBrush, const struct brush_pattern *pattern )
{
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE*)dev;
EMRSELECTOBJECT emr;
DWORD index;
int i;
if (physDev->restoring) return hBrush; /* don't output SelectObject records during RestoreDC */
/* If the object is a stock brush object, do not need to create it.
* See definitions in wingdi.h for range of stock brushes.
* We do however have to handle setting the higher order bit to
* designate that this is a stock object.
*/
for (i = WHITE_BRUSH; i <= DC_BRUSH; i++)
{
if (hBrush == GetStockObject(i))
{
index = i | 0x80000000;
goto found;
}
}
if((index = EMFDRV_FindObject(dev, hBrush)) != 0)
goto found;
if (!(index = EMFDRV_CreateBrushIndirect(dev, hBrush ))) return 0;
GDI_hdc_using_object(hBrush, dev->hdc);
found:
emr.emr.iType = EMR_SELECTOBJECT;
emr.emr.nSize = sizeof(emr);
emr.ihObject = index;
return EMFDRV_WriteRecord( dev, &emr.emr ) ? hBrush : 0;
}
/******************************************************************
* EMFDRV_CreateFontIndirect
*/
static BOOL EMFDRV_CreateFontIndirect(PHYSDEV dev, HFONT hFont )
{
DWORD index = 0;
EMREXTCREATEFONTINDIRECTW emr;
int i;
if (!GetObjectW( hFont, sizeof(emr.elfw.elfLogFont), &emr.elfw.elfLogFont )) return FALSE;
emr.emr.iType = EMR_EXTCREATEFONTINDIRECTW;
emr.emr.nSize = (sizeof(emr) + 3) / 4 * 4;
emr.ihFont = index = EMFDRV_AddHandle( dev, hFont );
emr.elfw.elfFullName[0] = '\0';
emr.elfw.elfStyle[0] = '\0';
emr.elfw.elfVersion = 0;
emr.elfw.elfStyleSize = 0;
emr.elfw.elfMatch = 0;
emr.elfw.elfReserved = 0;
for(i = 0; i < ELF_VENDOR_SIZE; i++)
emr.elfw.elfVendorId[i] = 0;
emr.elfw.elfCulture = PAN_CULTURE_LATIN;
emr.elfw.elfPanose.bFamilyType = PAN_NO_FIT;
emr.elfw.elfPanose.bSerifStyle = PAN_NO_FIT;
emr.elfw.elfPanose.bWeight = PAN_NO_FIT;
emr.elfw.elfPanose.bProportion = PAN_NO_FIT;
emr.elfw.elfPanose.bContrast = PAN_NO_FIT;
emr.elfw.elfPanose.bStrokeVariation = PAN_NO_FIT;
emr.elfw.elfPanose.bArmStyle = PAN_NO_FIT;
emr.elfw.elfPanose.bLetterform = PAN_NO_FIT;
emr.elfw.elfPanose.bMidline = PAN_NO_FIT;
emr.elfw.elfPanose.bXHeight = PAN_NO_FIT;
if(!EMFDRV_WriteRecord( dev, &emr.emr ))
index = 0;
return index;
}
/***********************************************************************
* EMFDRV_SelectFont
*/
HFONT EMFDRV_SelectFont( PHYSDEV dev, HFONT hFont, UINT *aa_flags )
{
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE*)dev;
EMRSELECTOBJECT emr;
DWORD index;
int i;
if (physDev->restoring) goto done; /* don't output SelectObject records during RestoreDC */
/* If the object is a stock font object, do not need to create it.
* See definitions in wingdi.h for range of stock fonts.
* We do however have to handle setting the higher order bit to
* designate that this is a stock object.
*/
for (i = OEM_FIXED_FONT; i <= DEFAULT_GUI_FONT; i++)
{
if (i != DEFAULT_PALETTE && hFont == GetStockObject(i))
{
index = i | 0x80000000;
goto found;
}
}
if((index = EMFDRV_FindObject(dev, hFont)) != 0)
goto found;
if (!(index = EMFDRV_CreateFontIndirect(dev, hFont ))) return 0;
GDI_hdc_using_object(hFont, dev->hdc);
found:
emr.emr.iType = EMR_SELECTOBJECT;
emr.emr.nSize = sizeof(emr);
emr.ihObject = index;
if(!EMFDRV_WriteRecord( dev, &emr.emr ))
return 0;
done:
*aa_flags = GGO_BITMAP; /* no point in anti-aliasing on metafiles */
dev = GET_NEXT_PHYSDEV( dev, pSelectFont );
dev->funcs->pSelectFont( dev, hFont, aa_flags );
return hFont;
}
/******************************************************************
* EMFDRV_CreatePenIndirect
*/
static DWORD EMFDRV_CreatePenIndirect(PHYSDEV dev, HPEN hPen)
{
EMRCREATEPEN emr;
DWORD index = 0;
if (!GetObjectW( hPen, sizeof(emr.lopn), &emr.lopn ))
{
/* must be an extended pen */
EXTLOGPEN *elp;
INT size = GetObjectW( hPen, 0, NULL );
if (!size) return 0;
elp = HeapAlloc( GetProcessHeap(), 0, size );
GetObjectW( hPen, size, elp );
/* FIXME: add support for user style pens */
emr.lopn.lopnStyle = elp->elpPenStyle;
emr.lopn.lopnWidth.x = elp->elpWidth;
emr.lopn.lopnWidth.y = 0;
emr.lopn.lopnColor = elp->elpColor;
HeapFree( GetProcessHeap(), 0, elp );
}
emr.emr.iType = EMR_CREATEPEN;
emr.emr.nSize = sizeof(emr);
emr.ihPen = index = EMFDRV_AddHandle( dev, hPen );
if(!EMFDRV_WriteRecord( dev, &emr.emr ))
index = 0;
return index;
}
/******************************************************************
* EMFDRV_SelectPen
*/
HPEN EMFDRV_SelectPen(PHYSDEV dev, HPEN hPen, const struct brush_pattern *pattern )
{
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE*)dev;
EMRSELECTOBJECT emr;
DWORD index;
int i;
if (physDev->restoring) return hPen; /* don't output SelectObject records during RestoreDC */
/* If the object is a stock pen object, do not need to create it.
* See definitions in wingdi.h for range of stock pens.
* We do however have to handle setting the higher order bit to
* designate that this is a stock object.
*/
for (i = WHITE_PEN; i <= DC_PEN; i++)
{
if (hPen == GetStockObject(i))
{
index = i | 0x80000000;
goto found;
}
}
if((index = EMFDRV_FindObject(dev, hPen)) != 0)
goto found;
if (!(index = EMFDRV_CreatePenIndirect(dev, hPen))) return 0;
GDI_hdc_using_object(hPen, dev->hdc);
found:
emr.emr.iType = EMR_SELECTOBJECT;
emr.emr.nSize = sizeof(emr);
emr.ihObject = index;
return EMFDRV_WriteRecord( dev, &emr.emr ) ? hPen : 0;
}
/******************************************************************
* EMFDRV_CreatePalette
*/
static DWORD EMFDRV_CreatePalette(PHYSDEV dev, HPALETTE hPal)
{
WORD i;
struct {
EMRCREATEPALETTE hdr;
PALETTEENTRY entry[255];
} pal;
memset( &pal, 0, sizeof(pal) );
if (!GetObjectW( hPal, sizeof(pal.hdr.lgpl) + sizeof(pal.entry), &pal.hdr.lgpl ))
return 0;
for (i = 0; i < pal.hdr.lgpl.palNumEntries; i++)
pal.hdr.lgpl.palPalEntry[i].peFlags = 0;
pal.hdr.emr.iType = EMR_CREATEPALETTE;
pal.hdr.emr.nSize = sizeof(pal.hdr) + pal.hdr.lgpl.palNumEntries * sizeof(PALETTEENTRY);
pal.hdr.ihPal = EMFDRV_AddHandle( dev, hPal );
if (!EMFDRV_WriteRecord( dev, &pal.hdr.emr ))
pal.hdr.ihPal = 0;
return pal.hdr.ihPal;
}
/******************************************************************
* EMFDRV_SelectPalette
*/
HPALETTE EMFDRV_SelectPalette( PHYSDEV dev, HPALETTE hPal, BOOL force )
{
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE*)dev;
EMRSELECTPALETTE emr;
DWORD index;
if (physDev->restoring) return hPal; /* don't output SelectObject records during RestoreDC */
if (hPal == GetStockObject( DEFAULT_PALETTE ))
{
index = DEFAULT_PALETTE | 0x80000000;
goto found;
}
if ((index = EMFDRV_FindObject( dev, hPal )) != 0)
goto found;
if (!(index = EMFDRV_CreatePalette( dev, hPal ))) return 0;
GDI_hdc_using_object( hPal, dev->hdc );
found:
emr.emr.iType = EMR_SELECTPALETTE;
emr.emr.nSize = sizeof(emr);
emr.ihPal = index;
return EMFDRV_WriteRecord( dev, &emr.emr ) ? hPal : 0;
}
/******************************************************************
* EMFDRV_SetDCBrushColor
*/
COLORREF EMFDRV_SetDCBrushColor( PHYSDEV dev, COLORREF color )
{
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE*)dev;
EMRSELECTOBJECT emr;
DWORD index;
if (GetCurrentObject( dev->hdc, OBJ_BRUSH ) != GetStockObject( DC_BRUSH )) return color;
if (physDev->dc_brush) DeleteObject( physDev->dc_brush );
if (!(physDev->dc_brush = CreateSolidBrush( color ))) return CLR_INVALID;
if (!(index = EMFDRV_CreateBrushIndirect(dev, physDev->dc_brush ))) return CLR_INVALID;
GDI_hdc_using_object( physDev->dc_brush, dev->hdc );
emr.emr.iType = EMR_SELECTOBJECT;
emr.emr.nSize = sizeof(emr);
emr.ihObject = index;
return EMFDRV_WriteRecord( dev, &emr.emr ) ? color : CLR_INVALID;
}
/******************************************************************
* EMFDRV_SetDCPenColor
*/
COLORREF EMFDRV_SetDCPenColor( PHYSDEV dev, COLORREF color )
{
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE*)dev;
EMRSELECTOBJECT emr;
DWORD index;
LOGPEN logpen = { PS_SOLID, { 0, 0 }, color };
if (GetCurrentObject( dev->hdc, OBJ_PEN ) != GetStockObject( DC_PEN )) return color;
if (physDev->dc_pen) DeleteObject( physDev->dc_pen );
if (!(physDev->dc_pen = CreatePenIndirect( &logpen ))) return CLR_INVALID;
if (!(index = EMFDRV_CreatePenIndirect(dev, physDev->dc_pen))) return CLR_INVALID;
GDI_hdc_using_object( physDev->dc_pen, dev->hdc );
emr.emr.iType = EMR_SELECTOBJECT;
emr.emr.nSize = sizeof(emr);
emr.ihObject = index;
return EMFDRV_WriteRecord( dev, &emr.emr ) ? color : CLR_INVALID;
}
/******************************************************************
* EMFDRV_GdiComment
*/
BOOL EMFDRV_GdiComment(PHYSDEV dev, UINT bytes, const BYTE *buffer)
{
EMRGDICOMMENT *emr;
UINT total, rounded_size;
BOOL ret;
rounded_size = (bytes+3) & ~3;
total = offsetof(EMRGDICOMMENT,Data) + rounded_size;
emr = HeapAlloc(GetProcessHeap(), 0, total);
emr->emr.iType = EMR_GDICOMMENT;
emr->emr.nSize = total;
emr->cbData = bytes;
memset(&emr->Data[bytes], 0, rounded_size - bytes);
memcpy(&emr->Data[0], buffer, bytes);
ret = EMFDRV_WriteRecord( dev, &emr->emr );
HeapFree(GetProcessHeap(), 0, emr);
return ret;
}

View File

@ -0,0 +1,145 @@
/*
* GDI definitions
*
* Copyright 1993 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __WINE_GDI_PRIVATE_H
#define __WINE_GDI_PRIVATE_H
#include <limits.h>
#include <math.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include <wine/gdi_driver.h>
/* Metafile defines */
#define META_EOF 0x0000
/* values of mtType in METAHEADER. Note however that the disk image of a disk
based metafile has mtType == 1 */
#define METAFILE_MEMORY 1
#define METAFILE_DISK 2
#define MFHEADERSIZE (sizeof(METAHEADER))
#define MFVERSION 0x300
typedef struct {
EMR emr;
INT nBreakExtra;
INT nBreakCount;
} EMRSETTEXTJUSTIFICATION, *PEMRSETTEXTJUSTIFICATION;
struct gdi_obj_funcs
{
HGDIOBJ (*pSelectObject)( HGDIOBJ handle, HDC hdc );
INT (*pGetObjectA)( HGDIOBJ handle, INT count, LPVOID buffer );
INT (*pGetObjectW)( HGDIOBJ handle, INT count, LPVOID buffer );
BOOL (*pUnrealizeObject)( HGDIOBJ handle );
BOOL (*pDeleteObject)( HGDIOBJ handle );
};
typedef struct tagWINEDC
{
HDC hdc;
PHYSDEV physDev; /* current top of the physdev stack */
LONG refcount; /* thread refcount */
INT saveLevel;
struct gdi_physdev NullPhysDev;
HFONT hFont;
HBRUSH hBrush;
HPEN hPen;
HPALETTE hPalette;
} WINEDC, DC;
/* brush.c */
extern BOOL get_brush_bitmap_info( HBRUSH handle, BITMAPINFO *info, void **bits, UINT *usage ) DECLSPEC_HIDDEN;
/* dc.c */
extern DC *alloc_dc_ptr( WORD magic ) DECLSPEC_HIDDEN;
extern void free_dc_ptr( DC *dc ) DECLSPEC_HIDDEN;
extern DC *get_dc_ptr( HDC hdc ) DECLSPEC_HIDDEN;
extern void release_dc_ptr( DC *dc ) DECLSPEC_HIDDEN;
/* dib.c */
extern int bitmap_info_size( const BITMAPINFO * info, WORD coloruse ) DECLSPEC_HIDDEN;
/* enhmetafile.c */
extern HENHMETAFILE EMF_Create_HENHMETAFILE(ENHMETAHEADER *emh, BOOL on_disk ) DECLSPEC_HIDDEN;
/* gdiobj.c */
extern HGDIOBJ alloc_gdi_handle( void *obj, WORD type, const struct gdi_obj_funcs *funcs ) DECLSPEC_HIDDEN;
extern void *free_gdi_handle( HGDIOBJ handle ) DECLSPEC_HIDDEN;
extern HGDIOBJ get_full_gdi_handle( HGDIOBJ handle ) DECLSPEC_HIDDEN;
extern void *GDI_GetObjPtr( HGDIOBJ, WORD ) DECLSPEC_HIDDEN;
extern void GDI_ReleaseObj( HGDIOBJ ) DECLSPEC_HIDDEN;
extern void GDI_hdc_using_object(HGDIOBJ obj, HDC hdc) DECLSPEC_HIDDEN;
extern void GDI_hdc_not_using_object(HGDIOBJ obj, HDC hdc) DECLSPEC_HIDDEN;
/* metafile.c */
extern HMETAFILE MF_Create_HMETAFILE(METAHEADER *mh) DECLSPEC_HIDDEN;
extern METAHEADER *MF_CreateMetaHeaderDisk(METAHEADER *mr, LPCVOID filename, BOOL unicode ) DECLSPEC_HIDDEN;
/* palette.c */
extern HPALETTE WINAPI GDISelectPalette( HDC hdc, HPALETTE hpal, WORD wBkg) DECLSPEC_HIDDEN;
extern UINT WINAPI GDIRealizePalette( HDC hdc ) DECLSPEC_HIDDEN;
#define EMR_SETLINKEDUFI 119
/* Undocumented value for DIB's iUsage: Indicates a mono DIB w/o pal entries */
#define DIB_PAL_MONO 2
BOOL WINAPI SetVirtualResolution(HDC hdc, DWORD horz_res, DWORD vert_res, DWORD horz_size, DWORD vert_size);
static inline int get_dib_stride( int width, int bpp )
{
return ((width * bpp + 31) >> 3) & ~3;
}
static inline int get_dib_image_size( const BITMAPINFO *info )
{
return get_dib_stride( info->bmiHeader.biWidth, info->bmiHeader.biBitCount )
* abs( info->bmiHeader.biHeight );
}
/* only for use on sanitized BITMAPINFO structures */
static inline int get_dib_info_size( const BITMAPINFO *info, UINT coloruse )
{
if (info->bmiHeader.biCompression == BI_BITFIELDS)
return sizeof(BITMAPINFOHEADER) + 3 * sizeof(DWORD);
if (coloruse == DIB_PAL_COLORS)
return sizeof(BITMAPINFOHEADER) + info->bmiHeader.biClrUsed * sizeof(WORD);
return FIELD_OFFSET( BITMAPINFO, bmiColors[info->bmiHeader.biClrUsed] );
}
/* Special sauce for reactos */
#define GDIRealizePalette RealizePalette
#define GDISelectPalette SelectPalette
HGDIOBJ WINAPI GdiFixUpHandle(HGDIOBJ hGdiObj);
#define get_full_gdi_handle GdiFixUpHandle
extern void push_dc_driver_ros(PHYSDEV *dev, PHYSDEV physdev, const struct gdi_dc_funcs *funcs);
#define push_dc_driver push_dc_driver_ros
BOOL WINAPI SetWorldTransformForMetafile(HDC hdc, const XFORM *pxform);
#define SetWorldTransform SetWorldTransformForMetafile
#undef ASSERT
#define ASSERT(x) if (!(x)) __int2c()
#endif /* __WINE_GDI_PRIVATE_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,192 @@
/*
* GDI bit-blit operations
*
* Copyright 1993, 1994 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <string.h>
#include "mfdrv/metafiledrv.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(metafile);
/***********************************************************************
* MFDRV_PatBlt
*/
BOOL MFDRV_PatBlt( PHYSDEV dev, struct bitblt_coords *dst, DWORD rop )
{
MFDRV_MetaParam6( dev, META_PATBLT, dst->log_x, dst->log_y, dst->log_width, dst->log_height,
HIWORD(rop), LOWORD(rop) );
return TRUE;
}
/***********************************************************************
* MFDRV_StretchBlt
* this function contains TWO ways for processing StretchBlt in metafiles,
* decide between rdFunction values META_STRETCHBLT or META_DIBSTRETCHBLT
* via #define STRETCH_VIA_DIB
*/
#define STRETCH_VIA_DIB
BOOL MFDRV_StretchBlt( PHYSDEV devDst, struct bitblt_coords *dst,
PHYSDEV devSrc, struct bitblt_coords *src, DWORD rop )
{
BOOL ret;
DWORD len;
METARECORD *mr;
BITMAP BM;
#ifdef STRETCH_VIA_DIB
LPBITMAPINFOHEADER lpBMI;
WORD nBPP;
#endif
HBITMAP hBitmap = GetCurrentObject(devSrc->hdc, OBJ_BITMAP);
if (devSrc->funcs == devDst->funcs) return FALSE; /* can't use a metafile DC as source */
if (GetObjectW(hBitmap, sizeof(BITMAP), &BM) != sizeof(BITMAP))
{
WARN("bad bitmap object %p passed for hdc %p\n", hBitmap, devSrc->hdc);
return FALSE;
}
#ifdef STRETCH_VIA_DIB
nBPP = BM.bmPlanes * BM.bmBitsPixel;
if(nBPP > 8) nBPP = 24; /* FIXME Can't get 16bpp to work for some reason */
len = sizeof(METARECORD) + 10 * sizeof(INT16)
+ sizeof(BITMAPINFOHEADER) + (nBPP <= 8 ? 1 << nBPP: 0) * sizeof(RGBQUAD)
+ get_dib_stride( BM.bmWidth, nBPP ) * BM.bmHeight;
if (!(mr = HeapAlloc( GetProcessHeap(), 0, len)))
return FALSE;
mr->rdFunction = META_DIBSTRETCHBLT;
lpBMI=(LPBITMAPINFOHEADER)(mr->rdParm+10);
lpBMI->biSize = sizeof(BITMAPINFOHEADER);
lpBMI->biWidth = BM.bmWidth;
lpBMI->biHeight = BM.bmHeight;
lpBMI->biPlanes = 1;
lpBMI->biBitCount = nBPP;
lpBMI->biSizeImage = get_dib_image_size( (BITMAPINFO *)lpBMI );
lpBMI->biClrUsed = nBPP <= 8 ? 1 << nBPP : 0;
lpBMI->biCompression = BI_RGB;
lpBMI->biXPelsPerMeter = MulDiv(GetDeviceCaps(devSrc->hdc,LOGPIXELSX),3937,100);
lpBMI->biYPelsPerMeter = MulDiv(GetDeviceCaps(devSrc->hdc,LOGPIXELSY),3937,100);
lpBMI->biClrImportant = 0; /* 1 meter = 39.37 inch */
TRACE("MF_StretchBltViaDIB->len = %d rop=%x PixYPM=%d Caps=%d\n",
len,rop,lpBMI->biYPelsPerMeter,GetDeviceCaps(devSrc->hdc, LOGPIXELSY));
if (GetDIBits(devSrc->hdc, hBitmap, 0, (UINT)lpBMI->biHeight,
(LPSTR)lpBMI + get_dib_info_size( (BITMAPINFO *)lpBMI, DIB_RGB_COLORS ),
(LPBITMAPINFO)lpBMI, DIB_RGB_COLORS))
#else
len = sizeof(METARECORD) + 15 * sizeof(INT16) + BM.bmWidthBytes * BM.bmHeight;
if (!(mr = HeapAlloc( GetProcessHeap(), 0, len )))
return FALSE;
mr->rdFunction = META_STRETCHBLT;
*(mr->rdParm +10) = BM.bmWidth;
*(mr->rdParm +11) = BM.bmHeight;
*(mr->rdParm +12) = BM.bmWidthBytes;
*(mr->rdParm +13) = BM.bmPlanes;
*(mr->rdParm +14) = BM.bmBitsPixel;
TRACE("len = %ld rop=%lx\n", len, rop);
if (GetBitmapBits( hBitmap, BM.bmWidthBytes * BM.bmHeight, mr->rdParm + 15))
#endif
{
mr->rdSize = len / sizeof(INT16);
*(mr->rdParm) = LOWORD(rop);
*(mr->rdParm + 1) = HIWORD(rop);
*(mr->rdParm + 2) = src->log_height;
*(mr->rdParm + 3) = src->log_width;
*(mr->rdParm + 4) = src->log_y;
*(mr->rdParm + 5) = src->log_x;
*(mr->rdParm + 6) = dst->log_height;
*(mr->rdParm + 7) = dst->log_width;
*(mr->rdParm + 8) = dst->log_y;
*(mr->rdParm + 9) = dst->log_x;
ret = MFDRV_WriteRecord( devDst, mr, mr->rdSize * 2);
}
else
ret = FALSE;
HeapFree( GetProcessHeap(), 0, mr);
return ret;
}
/***********************************************************************
* MFDRV_StretchDIBits
*/
INT MFDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst,
INT heightDst, INT xSrc, INT ySrc, INT widthSrc,
INT heightSrc, const void *bits,
BITMAPINFO *info, UINT wUsage, DWORD dwRop )
{
DWORD infosize = get_dib_info_size(info, wUsage);
DWORD len = sizeof(METARECORD) + 10 * sizeof(WORD) + infosize + info->bmiHeader.biSizeImage;
METARECORD *mr = HeapAlloc( GetProcessHeap(), 0, len );
if(!mr) return 0;
mr->rdSize = len / 2;
mr->rdFunction = META_STRETCHDIB;
mr->rdParm[0] = LOWORD(dwRop);
mr->rdParm[1] = HIWORD(dwRop);
mr->rdParm[2] = wUsage;
mr->rdParm[3] = (INT16)heightSrc;
mr->rdParm[4] = (INT16)widthSrc;
mr->rdParm[5] = (INT16)ySrc;
mr->rdParm[6] = (INT16)xSrc;
mr->rdParm[7] = (INT16)heightDst;
mr->rdParm[8] = (INT16)widthDst;
mr->rdParm[9] = (INT16)yDst;
mr->rdParm[10] = (INT16)xDst;
memcpy(mr->rdParm + 11, info, infosize);
memcpy(mr->rdParm + 11 + infosize / 2, bits, info->bmiHeader.biSizeImage);
MFDRV_WriteRecord( dev, mr, mr->rdSize * 2 );
HeapFree( GetProcessHeap(), 0, mr );
return heightSrc;
}
/***********************************************************************
* MFDRV_SetDIBitsToDeivce
*/
INT MFDRV_SetDIBitsToDevice( PHYSDEV dev, INT xDst, INT yDst, DWORD cx,
DWORD cy, INT xSrc, INT ySrc, UINT startscan,
UINT lines, LPCVOID bits, BITMAPINFO *info, UINT coloruse )
{
DWORD infosize = get_dib_info_size(info, coloruse);
DWORD len = sizeof(METARECORD) + 8 * sizeof(WORD) + infosize + info->bmiHeader.biSizeImage;
METARECORD *mr = HeapAlloc( GetProcessHeap(), 0, len );
if(!mr) return 0;
mr->rdSize = len / 2;
mr->rdFunction = META_SETDIBTODEV;
mr->rdParm[0] = coloruse;
mr->rdParm[1] = lines;
mr->rdParm[2] = startscan;
mr->rdParm[3] = (INT16)ySrc;
mr->rdParm[4] = (INT16)xSrc;
mr->rdParm[5] = (INT16)cy;
mr->rdParm[6] = (INT16)cx;
mr->rdParm[7] = (INT16)yDst;
mr->rdParm[8] = (INT16)xDst;
memcpy(mr->rdParm + 9, info, infosize);
memcpy(mr->rdParm + 9 + infosize / 2, bits, info->bmiHeader.biSizeImage);
MFDRV_WriteRecord( dev, mr, mr->rdSize * 2 );
HeapFree( GetProcessHeap(), 0, mr );
return lines;
}

View File

@ -0,0 +1,206 @@
/*
* MetaFile driver DC value functions
*
* Copyright 1999 Huw D M Davies
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "mfdrv/metafiledrv.h"
INT MFDRV_SaveDC( PHYSDEV dev )
{
return MFDRV_MetaParam0( dev, META_SAVEDC );
}
BOOL MFDRV_RestoreDC( PHYSDEV dev, INT level )
{
return MFDRV_MetaParam1( dev, META_RESTOREDC, level );
}
UINT MFDRV_SetTextAlign( PHYSDEV dev, UINT align )
{
return MFDRV_MetaParam2( dev, META_SETTEXTALIGN, HIWORD(align), LOWORD(align)) ? align : GDI_ERROR;
}
INT MFDRV_SetBkMode( PHYSDEV dev, INT mode )
{
return MFDRV_MetaParam1( dev, META_SETBKMODE, (WORD)mode) ? mode : 0;
}
COLORREF MFDRV_SetBkColor( PHYSDEV dev, COLORREF color )
{
return MFDRV_MetaParam2(dev, META_SETBKCOLOR, HIWORD(color), LOWORD(color)) ? color : CLR_INVALID;
}
COLORREF MFDRV_SetTextColor( PHYSDEV dev, COLORREF color )
{
return MFDRV_MetaParam2(dev, META_SETTEXTCOLOR, HIWORD(color), LOWORD(color)) ? color : CLR_INVALID;
}
INT MFDRV_SetROP2( PHYSDEV dev, INT rop )
{
return MFDRV_MetaParam1( dev, META_SETROP2, (WORD)rop) ? rop : 0;
}
INT MFDRV_SetRelAbs( PHYSDEV dev, INT mode )
{
return MFDRV_MetaParam1( dev, META_SETRELABS, (WORD)mode) ? mode : 0;
}
INT MFDRV_SetPolyFillMode( PHYSDEV dev, INT mode )
{
return MFDRV_MetaParam1( dev, META_SETPOLYFILLMODE, (WORD)mode) ? mode : 0;
}
INT MFDRV_SetStretchBltMode( PHYSDEV dev, INT mode )
{
return MFDRV_MetaParam1( dev, META_SETSTRETCHBLTMODE, (WORD)mode) ? mode : 0;
}
INT MFDRV_IntersectClipRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom )
{
return MFDRV_MetaParam4( dev, META_INTERSECTCLIPRECT, left, top, right, bottom );
}
INT MFDRV_ExcludeClipRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom )
{
return MFDRV_MetaParam4( dev, META_EXCLUDECLIPRECT, left, top, right, bottom );
}
INT MFDRV_OffsetClipRgn( PHYSDEV dev, INT x, INT y )
{
return MFDRV_MetaParam2( dev, META_OFFSETCLIPRGN, x, y );
}
INT MFDRV_SetMapMode( PHYSDEV dev, INT mode )
{
return MFDRV_MetaParam1( dev, META_SETMAPMODE, mode );
}
BOOL MFDRV_SetViewportExtEx( PHYSDEV dev, INT x, INT y, SIZE *size )
{
return MFDRV_MetaParam2( dev, META_SETVIEWPORTEXT, x, y );
}
BOOL MFDRV_SetViewportOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt )
{
return MFDRV_MetaParam2( dev, META_SETVIEWPORTORG, x, y );
}
BOOL MFDRV_SetWindowExtEx( PHYSDEV dev, INT x, INT y, SIZE *size )
{
return MFDRV_MetaParam2( dev, META_SETWINDOWEXT, x, y );
}
BOOL MFDRV_SetWindowOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt )
{
return MFDRV_MetaParam2( dev, META_SETWINDOWORG, x, y );
}
BOOL MFDRV_OffsetViewportOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt )
{
return MFDRV_MetaParam2( dev, META_OFFSETVIEWPORTORG, x, y );
}
BOOL MFDRV_OffsetWindowOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt )
{
return MFDRV_MetaParam2( dev, META_OFFSETWINDOWORG, x, y );
}
BOOL MFDRV_ScaleViewportExtEx( PHYSDEV dev, INT xNum, INT xDenom, INT yNum, INT yDenom, SIZE *size )
{
return MFDRV_MetaParam4( dev, META_SCALEVIEWPORTEXT, xNum, xDenom, yNum, yDenom );
}
BOOL MFDRV_ScaleWindowExtEx( PHYSDEV dev, INT xNum, INT xDenom, INT yNum, INT yDenom, SIZE *size )
{
return MFDRV_MetaParam4( dev, META_SCALEWINDOWEXT, xNum, xDenom, yNum, yDenom );
}
BOOL MFDRV_SetTextJustification( PHYSDEV dev, INT extra, INT breaks )
{
return MFDRV_MetaParam2( dev, META_SETTEXTJUSTIFICATION, extra, breaks );
}
INT MFDRV_SetTextCharacterExtra( PHYSDEV dev, INT extra )
{
return MFDRV_MetaParam1( dev, META_SETTEXTCHAREXTRA, extra ) ? extra : 0x80000000;
}
DWORD MFDRV_SetMapperFlags( PHYSDEV dev, DWORD flags )
{
return MFDRV_MetaParam2( dev, META_SETMAPPERFLAGS, HIWORD(flags), LOWORD(flags) ) ? flags : GDI_ERROR;
}
BOOL MFDRV_AbortPath( PHYSDEV dev )
{
return FALSE;
}
BOOL MFDRV_BeginPath( PHYSDEV dev )
{
return FALSE;
}
BOOL MFDRV_CloseFigure( PHYSDEV dev )
{
return FALSE;
}
BOOL MFDRV_EndPath( PHYSDEV dev )
{
return FALSE;
}
BOOL MFDRV_FillPath( PHYSDEV dev )
{
return FALSE;
}
BOOL MFDRV_FlattenPath( PHYSDEV dev )
{
return FALSE;
}
BOOL MFDRV_SelectClipPath( PHYSDEV dev, INT iMode )
{
return FALSE;
}
BOOL MFDRV_StrokeAndFillPath( PHYSDEV dev )
{
return FALSE;
}
BOOL MFDRV_StrokePath( PHYSDEV dev )
{
return FALSE;
}
BOOL MFDRV_WidenPath( PHYSDEV dev )
{
return FALSE;
}
COLORREF MFDRV_SetDCBrushColor( PHYSDEV dev, COLORREF color )
{
return CLR_INVALID;
}
COLORREF MFDRV_SetDCPenColor( PHYSDEV dev, COLORREF color )
{
return CLR_INVALID;
}

View File

@ -0,0 +1,441 @@
/*
* Metafile driver graphics functions
*
* Copyright 1993, 1994 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "mfdrv/metafiledrv.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(metafile);
/**********************************************************************
* MFDRV_MoveTo
*/
BOOL MFDRV_MoveTo(PHYSDEV dev, INT x, INT y)
{
return MFDRV_MetaParam2(dev,META_MOVETO,x,y);
}
/***********************************************************************
* MFDRV_LineTo
*/
BOOL MFDRV_LineTo( PHYSDEV dev, INT x, INT y )
{
return MFDRV_MetaParam2(dev, META_LINETO, x, y);
}
/***********************************************************************
* MFDRV_Arc
*/
BOOL MFDRV_Arc( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
INT xstart, INT ystart, INT xend, INT yend )
{
return MFDRV_MetaParam8(dev, META_ARC, left, top, right, bottom,
xstart, ystart, xend, yend);
}
/***********************************************************************
* MFDRV_Pie
*/
BOOL MFDRV_Pie( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
INT xstart, INT ystart, INT xend, INT yend )
{
return MFDRV_MetaParam8(dev, META_PIE, left, top, right, bottom,
xstart, ystart, xend, yend);
}
/***********************************************************************
* MFDRV_Chord
*/
BOOL MFDRV_Chord( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
INT xstart, INT ystart, INT xend, INT yend )
{
return MFDRV_MetaParam8(dev, META_CHORD, left, top, right, bottom,
xstart, ystart, xend, yend);
}
/***********************************************************************
* MFDRV_Ellipse
*/
BOOL MFDRV_Ellipse( PHYSDEV dev, INT left, INT top, INT right, INT bottom )
{
return MFDRV_MetaParam4(dev, META_ELLIPSE, left, top, right, bottom);
}
/***********************************************************************
* MFDRV_Rectangle
*/
BOOL MFDRV_Rectangle(PHYSDEV dev, INT left, INT top, INT right, INT bottom)
{
return MFDRV_MetaParam4(dev, META_RECTANGLE, left, top, right, bottom);
}
/***********************************************************************
* MFDRV_RoundRect
*/
BOOL MFDRV_RoundRect( PHYSDEV dev, INT left, INT top, INT right,
INT bottom, INT ell_width, INT ell_height )
{
return MFDRV_MetaParam6(dev, META_ROUNDRECT, left, top, right, bottom,
ell_width, ell_height);
}
/***********************************************************************
* MFDRV_SetPixel
*/
COLORREF MFDRV_SetPixel( PHYSDEV dev, INT x, INT y, COLORREF color )
{
return MFDRV_MetaParam4(dev, META_SETPIXEL, x, y,HIWORD(color),
LOWORD(color));
}
/******************************************************************
* MFDRV_MetaPoly - implements Polygon and Polyline
*/
static BOOL MFDRV_MetaPoly(PHYSDEV dev, short func, POINTS *pt, short count)
{
BOOL ret;
DWORD len;
METARECORD *mr;
len = sizeof(METARECORD) + (count * 4);
if (!(mr = HeapAlloc( GetProcessHeap(), 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( dev, mr, mr->rdSize * 2);
HeapFree( GetProcessHeap(), 0, mr);
return ret;
}
/**********************************************************************
* MFDRV_Polyline
*/
BOOL MFDRV_Polyline( PHYSDEV dev, const POINT* pt, INT count )
{
int i;
POINTS *pts;
BOOL ret;
pts = HeapAlloc( GetProcessHeap(), 0, sizeof(POINTS)*count );
if(!pts) return FALSE;
for (i=count;i--;)
{
pts[i].x = pt[i].x;
pts[i].y = pt[i].y;
}
ret = MFDRV_MetaPoly(dev, META_POLYLINE, pts, count);
HeapFree( GetProcessHeap(), 0, pts );
return ret;
}
/**********************************************************************
* MFDRV_Polygon
*/
BOOL MFDRV_Polygon( PHYSDEV dev, const POINT* pt, INT count )
{
int i;
POINTS *pts;
BOOL ret;
pts = HeapAlloc( GetProcessHeap(), 0, sizeof(POINTS)*count );
if(!pts) return FALSE;
for (i=count;i--;)
{
pts[i].x = pt[i].x;
pts[i].y = pt[i].y;
}
ret = MFDRV_MetaPoly(dev, META_POLYGON, pts, count);
HeapFree( GetProcessHeap(), 0, pts );
return ret;
}
/**********************************************************************
* MFDRV_PolyPolygon
*/
BOOL MFDRV_PolyPolygon( PHYSDEV dev, const POINT* pt, const INT* counts, UINT polygons)
{
BOOL ret;
DWORD len;
METARECORD *mr;
unsigned int i,j;
POINTS *pts;
INT16 totalpoint16 = 0;
INT16 * pointcounts;
for (i=0;i<polygons;i++) {
totalpoint16 += counts[i];
}
/* allocate space for all points */
pts=HeapAlloc( GetProcessHeap(), 0, sizeof(POINTS) * totalpoint16 );
pointcounts = HeapAlloc( GetProcessHeap(), 0, sizeof(INT16) * totalpoint16 );
/* copy point counts */
for (i=0;i<polygons;i++) {
pointcounts[i] = counts[i];
}
/* convert all points */
for (j = totalpoint16; j--;){
pts[j].x = pt[j].x;
pts[j].y = pt[j].y;
}
len = sizeof(METARECORD) + sizeof(WORD) + polygons*sizeof(INT16) + totalpoint16*sizeof(*pts);
if (!(mr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len ))) {
HeapFree( GetProcessHeap(), 0, pts );
HeapFree( GetProcessHeap(), 0, pointcounts );
return FALSE;
}
mr->rdSize = len /2;
mr->rdFunction = META_POLYPOLYGON;
*(mr->rdParm) = polygons;
memcpy(mr->rdParm + 1, pointcounts, polygons*sizeof(INT16));
memcpy(mr->rdParm + 1+polygons, pts , totalpoint16*sizeof(*pts));
ret = MFDRV_WriteRecord( dev, mr, mr->rdSize * 2);
HeapFree( GetProcessHeap(), 0, pts );
HeapFree( GetProcessHeap(), 0, pointcounts );
HeapFree( GetProcessHeap(), 0, mr);
return ret;
}
/**********************************************************************
* MFDRV_ExtFloodFill
*/
BOOL MFDRV_ExtFloodFill( PHYSDEV dev, INT x, INT y, COLORREF color, UINT fillType )
{
return MFDRV_MetaParam4(dev,META_FLOODFILL,x,y,HIWORD(color),
LOWORD(color));
}
/******************************************************************
* MFDRV_CreateRegion
*
* For explanation of the format of the record see MF_Play_MetaCreateRegion in
* objects/metafile.c
*/
static INT16 MFDRV_CreateRegion(PHYSDEV dev, HRGN hrgn)
{
DWORD len;
METARECORD *mr;
RGNDATA *rgndata;
RECT *pCurRect, *pEndRect;
WORD Bands = 0, MaxBands = 0;
WORD *Param, *StartBand;
BOOL ret;
if (!(len = GetRegionData( hrgn, 0, NULL ))) return -1;
if( !(rgndata = HeapAlloc( GetProcessHeap(), 0, len )) ) {
WARN("Can't alloc rgndata buffer\n");
return -1;
}
GetRegionData( hrgn, len, rgndata );
/* Overestimate of length:
* Assume every rect is a separate band -> 6 WORDs per rect
*/
len = sizeof(METARECORD) + 20 + (rgndata->rdh.nCount * 12);
if( !(mr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len )) ) {
WARN("Can't alloc METARECORD buffer\n");
HeapFree( GetProcessHeap(), 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;
}
}
if (StartBand)
{
*StartBand = Param - StartBand - 3;
*Param++ = *StartBand;
if(*StartBand > MaxBands)
MaxBands = *StartBand;
Bands++;
}
mr->rdParm[0] = 0;
mr->rdParm[1] = 6;
mr->rdParm[2] = 0x2f6;
mr->rdParm[3] = 0;
mr->rdParm[4] = (Param - &mr->rdFunction) * sizeof(WORD);
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 = Param - (WORD *)mr;
ret = MFDRV_WriteRecord( dev, mr, mr->rdSize * 2 );
HeapFree( GetProcessHeap(), 0, mr );
HeapFree( GetProcessHeap(), 0, rgndata );
if(!ret)
{
WARN("MFDRV_WriteRecord failed\n");
return -1;
}
return MFDRV_AddHandle( dev, hrgn );
}
/**********************************************************************
* MFDRV_PaintRgn
*/
BOOL MFDRV_PaintRgn( PHYSDEV dev, HRGN hrgn )
{
INT16 index;
index = MFDRV_CreateRegion( dev, hrgn );
if(index == -1)
return FALSE;
return MFDRV_MetaParam1( dev, META_PAINTREGION, index );
}
/**********************************************************************
* MFDRV_InvertRgn
*/
BOOL MFDRV_InvertRgn( PHYSDEV dev, HRGN hrgn )
{
INT16 index;
index = MFDRV_CreateRegion( dev, hrgn );
if(index == -1)
return FALSE;
return MFDRV_MetaParam1( dev, META_INVERTREGION, index );
}
/**********************************************************************
* MFDRV_FillRgn
*/
BOOL MFDRV_FillRgn( PHYSDEV dev, HRGN hrgn, HBRUSH hbrush )
{
INT16 iRgn, iBrush;
iRgn = MFDRV_CreateRegion( dev, hrgn );
if(iRgn == -1)
return FALSE;
iBrush = MFDRV_CreateBrushIndirect( dev, hbrush );
if(!iBrush)
return FALSE;
return MFDRV_MetaParam2( dev, META_FILLREGION, iRgn, iBrush );
}
/**********************************************************************
* MFDRV_FrameRgn
*/
BOOL MFDRV_FrameRgn( PHYSDEV dev, HRGN hrgn, HBRUSH hbrush, INT x, INT y )
{
INT16 iRgn, iBrush;
iRgn = MFDRV_CreateRegion( dev, hrgn );
if(iRgn == -1)
return FALSE;
iBrush = MFDRV_CreateBrushIndirect( dev, hbrush );
if(!iBrush)
return FALSE;
return MFDRV_MetaParam4( dev, META_FRAMEREGION, iRgn, iBrush, x, y );
}
/**********************************************************************
* MFDRV_ExtSelectClipRgn
*/
INT MFDRV_ExtSelectClipRgn( PHYSDEV dev, HRGN hrgn, INT mode )
{
INT16 iRgn;
INT ret;
if (mode != RGN_COPY) return ERROR;
if (!hrgn) return NULLREGION;
iRgn = MFDRV_CreateRegion( dev, hrgn );
if(iRgn == -1) return ERROR;
ret = MFDRV_MetaParam1( dev, META_SELECTOBJECT, iRgn ) ? NULLREGION : ERROR;
MFDRV_MetaParam1( dev, META_DELETEOBJECT, iRgn );
MFDRV_RemoveHandle( dev, iRgn );
return ret;
}
/**********************************************************************
* MFDRV_PolyBezier
* Since MetaFiles don't record Beziers and they don't even record
* approximations to them using lines, we need this stub function.
*/
BOOL MFDRV_PolyBezier( PHYSDEV dev, const POINT *pts, DWORD count )
{
return FALSE;
}
/**********************************************************************
* MFDRV_PolyBezierTo
* Since MetaFiles don't record Beziers and they don't even record
* approximations to them using lines, we need this stub function.
*/
BOOL MFDRV_PolyBezierTo( PHYSDEV dev, const POINT *pts, DWORD count )
{
return FALSE;
}

View File

@ -0,0 +1,627 @@
/*
* Metafile driver initialisation functions
*
* Copyright 1996 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#include <string.h>
#include "windef.h"
#include "winbase.h"
#include "winnls.h"
#include "gdi_private.h"
#include "mfdrv/metafiledrv.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(metafile);
static BOOL MFDRV_CreateCompatibleDC( PHYSDEV orig, PHYSDEV *pdev );
static BOOL MFDRV_DeleteDC( PHYSDEV dev );
/**********************************************************************
* MFDRV_ExtEscape
*/
static INT MFDRV_ExtEscape( PHYSDEV dev, INT nEscape, INT cbInput, LPCVOID in_data,
INT cbOutput, LPVOID out_data )
{
METARECORD *mr;
DWORD len;
INT ret;
if (cbOutput) return 0; /* escapes that require output cannot work in metafiles */
len = sizeof(*mr) + sizeof(WORD) + ((cbInput + 1) & ~1);
mr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
mr->rdSize = len / 2;
mr->rdFunction = META_ESCAPE;
mr->rdParm[0] = nEscape;
mr->rdParm[1] = cbInput;
memcpy(&(mr->rdParm[2]), in_data, cbInput);
ret = MFDRV_WriteRecord( dev, mr, len);
HeapFree(GetProcessHeap(), 0, mr);
return ret;
}
/******************************************************************
* MFDRV_GetBoundsRect
*/
static UINT MFDRV_GetBoundsRect( PHYSDEV dev, RECT *rect, UINT flags )
{
return 0;
}
/******************************************************************
* MFDRV_SetBoundsRect
*/
static UINT MFDRV_SetBoundsRect( PHYSDEV dev, RECT *rect, UINT flags )
{
return 0;
}
/******************************************************************
* MFDRV_GetDeviceCaps
*
*A very simple implementation that returns DT_METAFILE
*/
static INT MFDRV_GetDeviceCaps(PHYSDEV dev, INT cap)
{
switch(cap)
{
case TECHNOLOGY:
return DT_METAFILE;
case TEXTCAPS:
return 0;
default:
TRACE(" unsupported capability %d, will return 0\n", cap );
}
return 0;
}
static const struct gdi_dc_funcs MFDRV_Funcs =
{
NULL, /* pAbortDoc */
MFDRV_AbortPath, /* pAbortPath */
NULL, /* pAlphaBlend */
NULL, /* pAngleArc */
MFDRV_Arc, /* pArc */
NULL, /* pArcTo */
MFDRV_BeginPath, /* pBeginPath */
NULL, /* pBlendImage */
MFDRV_Chord, /* pChord */
MFDRV_CloseFigure, /* pCloseFigure */
MFDRV_CreateCompatibleDC, /* pCreateCompatibleDC */
NULL, /* pCreateDC */
MFDRV_DeleteDC, /* pDeleteDC */
MFDRV_DeleteObject, /* pDeleteObject */
NULL, /* pDeviceCapabilities */
MFDRV_Ellipse, /* pEllipse */
NULL, /* pEndDoc */
NULL, /* pEndPage */
MFDRV_EndPath, /* pEndPath */
NULL, /* pEnumFonts */
NULL, /* pEnumICMProfiles */
MFDRV_ExcludeClipRect, /* pExcludeClipRect */
NULL, /* pExtDeviceMode */
MFDRV_ExtEscape, /* pExtEscape */
MFDRV_ExtFloodFill, /* pExtFloodFill */
MFDRV_ExtSelectClipRgn, /* pExtSelectClipRgn */
MFDRV_ExtTextOut, /* pExtTextOut */
MFDRV_FillPath, /* pFillPath */
MFDRV_FillRgn, /* pFillRgn */
MFDRV_FlattenPath, /* pFlattenPath */
NULL, /* pFontIsLinked */
MFDRV_FrameRgn, /* pFrameRgn */
NULL, /* pGdiComment */
NULL, /* pGdiRealizationInfo */
MFDRV_GetBoundsRect, /* pGetBoundsRect */
NULL, /* pGetCharABCWidths */
NULL, /* pGetCharABCWidthsI */
NULL, /* pGetCharWidth */
MFDRV_GetDeviceCaps, /* pGetDeviceCaps */
NULL, /* pGetDeviceGammaRamp */
NULL, /* pGetFontData */
NULL, /* pGetFontUnicodeRanges */
NULL, /* pGetGlyphIndices */
NULL, /* pGetGlyphOutline */
NULL, /* pGetICMProfile */
NULL, /* pGetImage */
NULL, /* pGetKerningPairs */
NULL, /* pGetNearestColor */
NULL, /* pGetOutlineTextMetrics */
NULL, /* pGetPixel */
NULL, /* pGetSystemPaletteEntries */
NULL, /* pGetTextCharsetInfo */
NULL, /* pGetTextExtentExPoint */
NULL, /* pGetTextExtentExPointI */
NULL, /* pGetTextFace */
NULL, /* pGetTextMetrics */
NULL, /* pGradientFill */
MFDRV_IntersectClipRect, /* pIntersectClipRect */
MFDRV_InvertRgn, /* pInvertRgn */
MFDRV_LineTo, /* pLineTo */
NULL, /* pModifyWorldTransform */
MFDRV_MoveTo, /* pMoveTo */
MFDRV_OffsetClipRgn, /* pOffsetClipRgn */
MFDRV_OffsetViewportOrgEx, /* pOffsetViewportOrgEx */
MFDRV_OffsetWindowOrgEx, /* pOffsetWindowOrgEx */
MFDRV_PaintRgn, /* pPaintRgn */
MFDRV_PatBlt, /* pPatBlt */
MFDRV_Pie, /* pPie */
MFDRV_PolyBezier, /* pPolyBezier */
MFDRV_PolyBezierTo, /* pPolyBezierTo */
NULL, /* pPolyDraw */
MFDRV_PolyPolygon, /* pPolyPolygon */
NULL, /* pPolyPolyline */
MFDRV_Polygon, /* pPolygon */
MFDRV_Polyline, /* pPolyline */
NULL, /* pPolylineTo */
NULL, /* pPutImage */
NULL, /* pRealizeDefaultPalette */
MFDRV_RealizePalette, /* pRealizePalette */
MFDRV_Rectangle, /* pRectangle */
NULL, /* pResetDC */
MFDRV_RestoreDC, /* pRestoreDC */
MFDRV_RoundRect, /* pRoundRect */
MFDRV_SaveDC, /* pSaveDC */
MFDRV_ScaleViewportExtEx, /* pScaleViewportExtEx */
MFDRV_ScaleWindowExtEx, /* pScaleWindowExtEx */
MFDRV_SelectBitmap, /* pSelectBitmap */
MFDRV_SelectBrush, /* pSelectBrush */
MFDRV_SelectClipPath, /* pSelectClipPath */
MFDRV_SelectFont, /* pSelectFont */
MFDRV_SelectPalette, /* pSelectPalette */
MFDRV_SelectPen, /* pSelectPen */
NULL, /* pSetArcDirection */
MFDRV_SetBkColor, /* pSetBkColor */
MFDRV_SetBkMode, /* pSetBkMode */
MFDRV_SetBoundsRect, /* pSetBoundsRect */
MFDRV_SetDCBrushColor, /* pSetDCBrushColor*/
MFDRV_SetDCPenColor, /* pSetDCPenColor*/
MFDRV_SetDIBitsToDevice, /* pSetDIBitsToDevice */
NULL, /* pSetDeviceClipping */
NULL, /* pSetDeviceGammaRamp */
NULL, /* pSetLayout */
MFDRV_SetMapMode, /* pSetMapMode */
MFDRV_SetMapperFlags, /* pSetMapperFlags */
MFDRV_SetPixel, /* pSetPixel */
MFDRV_SetPolyFillMode, /* pSetPolyFillMode */
MFDRV_SetROP2, /* pSetROP2 */
MFDRV_SetRelAbs, /* pSetRelAbs */
MFDRV_SetStretchBltMode, /* pSetStretchBltMode */
MFDRV_SetTextAlign, /* pSetTextAlign */
MFDRV_SetTextCharacterExtra, /* pSetTextCharacterExtra */
MFDRV_SetTextColor, /* pSetTextColor */
MFDRV_SetTextJustification, /* pSetTextJustification */
MFDRV_SetViewportExtEx, /* pSetViewportExtEx */
MFDRV_SetViewportOrgEx, /* pSetViewportOrgEx */
MFDRV_SetWindowExtEx, /* pSetWindowExtEx */
MFDRV_SetWindowOrgEx, /* pSetWindowOrgEx */
NULL, /* pSetWorldTransform */
NULL, /* pStartDoc */
NULL, /* pStartPage */
MFDRV_StretchBlt, /* pStretchBlt */
MFDRV_StretchDIBits, /* pStretchDIBits */
MFDRV_StrokeAndFillPath, /* pStrokeAndFillPath */
MFDRV_StrokePath, /* pStrokePath */
NULL, /* pUnrealizePalette */
MFDRV_WidenPath, /* pWidenPath */
NULL, /* wine_get_wgl_driver */
GDI_PRIORITY_GRAPHICS_DRV /* priority */
};
/**********************************************************************
* MFDRV_AllocMetaFile
*/
static DC *MFDRV_AllocMetaFile(void)
{
DC *dc;
METAFILEDRV_PDEVICE *physDev;
if (!(dc = alloc_dc_ptr( OBJ_METADC ))) return NULL;
physDev = HeapAlloc(GetProcessHeap(),0,sizeof(*physDev));
if (!physDev)
{
free_dc_ptr( dc );
return NULL;
}
if (!(physDev->mh = HeapAlloc( GetProcessHeap(), 0, sizeof(*physDev->mh) )))
{
HeapFree( GetProcessHeap(), 0, physDev );
free_dc_ptr( dc );
return NULL;
}
push_dc_driver( &dc->physDev, &physDev->dev, &MFDRV_Funcs );
physDev->handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, HANDLE_LIST_INC * sizeof(physDev->handles[0]));
physDev->handles_size = HANDLE_LIST_INC;
physDev->cur_handles = 0;
physDev->hFile = 0;
physDev->mh->mtHeaderSize = sizeof(METAHEADER) / sizeof(WORD);
physDev->mh->mtVersion = 0x0300;
physDev->mh->mtSize = physDev->mh->mtHeaderSize;
physDev->mh->mtNoObjects = 0;
physDev->mh->mtMaxRecord = 0;
physDev->mh->mtNoParameters = 0;
SetVirtualResolution( physDev->dev.hdc, 0, 0, 0, 0);
return dc;
}
/**********************************************************************
* MFDRV_CreateCompatibleDC
*/
static BOOL MFDRV_CreateCompatibleDC( PHYSDEV orig, PHYSDEV *pdev )
{
/* not supported on metafile DCs */
return FALSE;
}
/**********************************************************************
* MFDRV_DeleteDC
*/
static BOOL MFDRV_DeleteDC( PHYSDEV dev )
{
METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
DWORD index;
HeapFree( GetProcessHeap(), 0, physDev->mh );
for(index = 0; index < physDev->handles_size; index++)
if(physDev->handles[index])
GDI_hdc_not_using_object(physDev->handles[index], dev->hdc);
HeapFree( GetProcessHeap(), 0, physDev->handles );
HeapFree( GetProcessHeap(), 0, physDev );
return TRUE;
}
/**********************************************************************
* CreateMetaFileW (GDI32.@)
*
* Create a new DC and associate it with a metafile. Pass a filename
* to create a disk-based metafile, NULL to create a memory metafile.
*
* PARAMS
* filename [I] Filename of disk metafile
*
* RETURNS
* A handle to the metafile DC if successful, NULL on failure.
*/
HDC WINAPI CreateMetaFileW( LPCWSTR filename )
{
HDC ret;
DC *dc;
METAFILEDRV_PDEVICE *physDev;
HANDLE hFile;
DWORD bytes_written;
TRACE("%s\n", debugstr_w(filename) );
if (!(dc = MFDRV_AllocMetaFile())) return 0;
physDev = (METAFILEDRV_PDEVICE *)dc->physDev;
if (filename) /* disk based metafile */
{
physDev->mh->mtType = METAFILE_DISK;
if ((hFile = CreateFileW(filename, GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, 0, 0)) == INVALID_HANDLE_VALUE) {
free_dc_ptr( dc );
return 0;
}
if (!WriteFile( hFile, physDev->mh, sizeof(*physDev->mh),
&bytes_written, NULL )) {
free_dc_ptr( dc );
CloseHandle (hFile );
return 0;
}
physDev->hFile = hFile;
/* Grow METAHEADER to include filename */
physDev->mh = MF_CreateMetaHeaderDisk(physDev->mh, filename, TRUE);
}
else /* memory based metafile */
physDev->mh->mtType = METAFILE_MEMORY;
TRACE("returning %p\n", physDev->dev.hdc);
ret = physDev->dev.hdc;
release_dc_ptr( dc );
return ret;
}
/**********************************************************************
* CreateMetaFileA (GDI32.@)
*
* See CreateMetaFileW.
*/
HDC WINAPI CreateMetaFileA(LPCSTR filename)
{
LPWSTR filenameW;
DWORD len;
HDC hReturnDC;
if (!filename) return CreateMetaFileW(NULL);
len = MultiByteToWideChar( CP_ACP, 0, filename, -1, NULL, 0 );
filenameW = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
MultiByteToWideChar( CP_ACP, 0, filename, -1, filenameW, len );
hReturnDC = CreateMetaFileW(filenameW);
HeapFree( GetProcessHeap(), 0, filenameW );
return hReturnDC;
}
/**********************************************************************
* MFDRV_CloseMetaFile
*/
static DC *MFDRV_CloseMetaFile( HDC hdc )
{
DC *dc;
METAFILEDRV_PDEVICE *physDev;
DWORD bytes_written;
TRACE("(%p)\n", hdc );
if (!(dc = get_dc_ptr( hdc ))) return NULL;
if (GetObjectType( hdc ) != OBJ_METADC)
{
release_dc_ptr( dc );
return NULL;
}
if (dc->refcount != 1)
{
FIXME( "not deleting busy DC %p refcount %u\n", hdc, dc->refcount );
release_dc_ptr( dc );
return NULL;
}
physDev = (METAFILEDRV_PDEVICE *)dc->physDev;
/* Construct the end of metafile record - this is documented
* in SDK Knowledgebase Q99334.
*/
if (!MFDRV_MetaParam0(dc->physDev, META_EOF))
{
free_dc_ptr( dc );
return 0;
}
if (physDev->mh->mtType == METAFILE_DISK) /* disk based metafile */
{
if (SetFilePointer(physDev->hFile, 0, NULL, FILE_BEGIN) != 0) {
free_dc_ptr( dc );
return 0;
}
physDev->mh->mtType = METAFILE_MEMORY; /* This is what windows does */
if (!WriteFile(physDev->hFile, physDev->mh, sizeof(*physDev->mh),
&bytes_written, NULL)) {
free_dc_ptr( dc );
return 0;
}
CloseHandle(physDev->hFile);
physDev->mh->mtType = METAFILE_DISK;
}
return dc;
}
/******************************************************************
* CloseMetaFile (GDI32.@)
*
* Stop recording graphics operations in metafile associated with
* hdc and retrieve metafile.
*
* PARAMS
* hdc [I] Metafile DC to close
*
* RETURNS
* Handle of newly created metafile on success, NULL on failure.
*/
HMETAFILE WINAPI CloseMetaFile(HDC hdc)
{
HMETAFILE hmf;
METAFILEDRV_PDEVICE *physDev;
DC *dc = MFDRV_CloseMetaFile(hdc);
if (!dc) return 0;
physDev = (METAFILEDRV_PDEVICE *)dc->physDev;
/* Now allocate a global handle for the metafile */
hmf = MF_Create_HMETAFILE( physDev->mh );
physDev->mh = NULL; /* So it won't be deleted */
free_dc_ptr( dc );
return hmf;
}
/******************************************************************
* MFDRV_WriteRecord
*
* Warning: this function can change the pointer to the metafile header.
*/
BOOL MFDRV_WriteRecord( PHYSDEV dev, METARECORD *mr, DWORD rlen)
{
DWORD len, size;
METAHEADER *mh;
METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
switch(physDev->mh->mtType)
{
case METAFILE_MEMORY:
len = physDev->mh->mtSize * 2 + rlen;
/* reallocate memory if needed */
size = HeapSize( GetProcessHeap(), 0, physDev->mh );
if (len > size)
{
/*expand size*/
size += size / 2 + rlen;
mh = HeapReAlloc( GetProcessHeap(), 0, physDev->mh, size);
if (!mh) return FALSE;
physDev->mh = mh;
TRACE("Reallocated metafile: new size is %d\n",size);
}
memcpy((WORD *)physDev->mh + physDev->mh->mtSize, mr, rlen);
break;
case METAFILE_DISK:
TRACE("Writing record to disk\n");
if (!WriteFile(physDev->hFile, mr, rlen, NULL, NULL))
return FALSE;
break;
default:
ERR("Unknown metafile type %d\n", physDev->mh->mtType );
return FALSE;
}
physDev->mh->mtSize += rlen / 2;
physDev->mh->mtMaxRecord = max(physDev->mh->mtMaxRecord, rlen / 2);
return TRUE;
}
/******************************************************************
* MFDRV_MetaParam0
*/
BOOL MFDRV_MetaParam0(PHYSDEV dev, short func)
{
char buffer[8];
METARECORD *mr = (METARECORD *)&buffer;
mr->rdSize = 3;
mr->rdFunction = func;
return MFDRV_WriteRecord( dev, mr, mr->rdSize * 2);
}
/******************************************************************
* MFDRV_MetaParam1
*/
BOOL MFDRV_MetaParam1(PHYSDEV dev, short func, short param1)
{
char buffer[8];
METARECORD *mr = (METARECORD *)&buffer;
WORD *params = mr->rdParm;
mr->rdSize = 4;
mr->rdFunction = func;
params[0] = param1;
return MFDRV_WriteRecord( dev, mr, mr->rdSize * 2);
}
/******************************************************************
* MFDRV_MetaParam2
*/
BOOL MFDRV_MetaParam2(PHYSDEV dev, short func, short param1, short param2)
{
char buffer[10];
METARECORD *mr = (METARECORD *)&buffer;
WORD *params = mr->rdParm;
mr->rdSize = 5;
mr->rdFunction = func;
params[0] = param2;
params[1] = param1;
return MFDRV_WriteRecord( dev, mr, mr->rdSize * 2);
}
/******************************************************************
* MFDRV_MetaParam4
*/
BOOL MFDRV_MetaParam4(PHYSDEV dev, short func, short param1, short param2,
short param3, short param4)
{
char buffer[14];
METARECORD *mr = (METARECORD *)&buffer;
WORD *params = mr->rdParm;
mr->rdSize = 7;
mr->rdFunction = func;
params[0] = param4;
params[1] = param3;
params[2] = param2;
params[3] = param1;
return MFDRV_WriteRecord( dev, mr, mr->rdSize * 2);
}
/******************************************************************
* MFDRV_MetaParam6
*/
BOOL MFDRV_MetaParam6(PHYSDEV dev, short func, short param1, short param2,
short param3, short param4, short param5, short param6)
{
char buffer[18];
METARECORD *mr = (METARECORD *)&buffer;
WORD *params = mr->rdParm;
mr->rdSize = 9;
mr->rdFunction = func;
params[0] = param6;
params[1] = param5;
params[2] = param4;
params[3] = param3;
params[4] = param2;
params[5] = param1;
return MFDRV_WriteRecord( dev, mr, mr->rdSize * 2);
}
/******************************************************************
* MFDRV_MetaParam8
*/
BOOL MFDRV_MetaParam8(PHYSDEV dev, short func, short param1, short param2,
short param3, short param4, short param5,
short param6, short param7, short param8)
{
char buffer[22];
METARECORD *mr = (METARECORD *)&buffer;
WORD *params = mr->rdParm;
mr->rdSize = 11;
mr->rdFunction = func;
params[0] = param8;
params[1] = param7;
params[2] = param6;
params[3] = param5;
params[4] = param4;
params[5] = param3;
params[6] = param2;
params[7] = param1;
return MFDRV_WriteRecord( dev, mr, mr->rdSize * 2);
}

View File

@ -0,0 +1,145 @@
/*
* Metafile driver definitions
*
* Copyright 1996 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __WINE_METAFILEDRV_H
#define __WINE_METAFILEDRV_H
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "gdi_private.h"
/* Metafile driver physical DC */
typedef struct
{
struct gdi_physdev dev;
METAHEADER *mh; /* Pointer to metafile header */
UINT handles_size, cur_handles;
HGDIOBJ *handles;
HANDLE hFile; /* Handle for disk based MetaFile */
} METAFILEDRV_PDEVICE;
#define HANDLE_LIST_INC 20
extern BOOL MFDRV_MetaParam0(PHYSDEV dev, short func) DECLSPEC_HIDDEN;
extern BOOL MFDRV_MetaParam1(PHYSDEV dev, short func, short param1) DECLSPEC_HIDDEN;
extern BOOL MFDRV_MetaParam2(PHYSDEV dev, short func, short param1, short param2) DECLSPEC_HIDDEN;
extern BOOL MFDRV_MetaParam4(PHYSDEV dev, short func, short param1, short param2,
short param3, short param4) DECLSPEC_HIDDEN;
extern BOOL MFDRV_MetaParam6(PHYSDEV dev, short func, short param1, short param2,
short param3, short param4, short param5,
short param6) DECLSPEC_HIDDEN;
extern BOOL MFDRV_MetaParam8(PHYSDEV dev, short func, short param1, short param2,
short param3, short param4, short param5,
short param6, short param7, short param8) DECLSPEC_HIDDEN;
extern BOOL MFDRV_WriteRecord(PHYSDEV dev, METARECORD *mr, DWORD rlen) DECLSPEC_HIDDEN;
extern UINT MFDRV_AddHandle( PHYSDEV dev, HGDIOBJ obj ) DECLSPEC_HIDDEN;
extern BOOL MFDRV_RemoveHandle( PHYSDEV dev, UINT index ) DECLSPEC_HIDDEN;
extern INT16 MFDRV_CreateBrushIndirect( PHYSDEV dev, HBRUSH hBrush ) DECLSPEC_HIDDEN;
/* Metafile driver functions */
extern BOOL MFDRV_AbortPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
extern BOOL MFDRV_Arc( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
INT xstart, INT ystart, INT xend, INT yend ) DECLSPEC_HIDDEN;
extern BOOL MFDRV_BeginPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
extern BOOL MFDRV_Chord( PHYSDEV dev, INT left, INT top, INT right,
INT bottom, INT xstart, INT ystart, INT xend, INT yend ) DECLSPEC_HIDDEN;
extern BOOL MFDRV_CloseFigure( PHYSDEV dev ) DECLSPEC_HIDDEN;
extern BOOL MFDRV_DeleteObject( PHYSDEV dev, HGDIOBJ obj ) DECLSPEC_HIDDEN;
extern BOOL MFDRV_Ellipse( PHYSDEV dev, INT left, INT top, INT right, INT bottom ) DECLSPEC_HIDDEN;
extern BOOL MFDRV_EndPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
extern INT MFDRV_ExcludeClipRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom ) DECLSPEC_HIDDEN;
extern BOOL MFDRV_ExtFloodFill( PHYSDEV dev, INT x, INT y, COLORREF color, UINT fillType ) DECLSPEC_HIDDEN;
extern INT MFDRV_ExtSelectClipRgn( PHYSDEV dev, HRGN hrgn, INT mode ) DECLSPEC_HIDDEN;
extern BOOL MFDRV_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags, const RECT *lprect, LPCWSTR str,
UINT count, const INT *lpDx ) DECLSPEC_HIDDEN;
extern BOOL MFDRV_FillPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
extern BOOL MFDRV_FillRgn( PHYSDEV dev, HRGN hrgn, HBRUSH hbrush ) DECLSPEC_HIDDEN;
extern BOOL MFDRV_FlattenPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
extern BOOL MFDRV_FrameRgn( PHYSDEV dev, HRGN hrgn, HBRUSH hbrush, INT x, INT y ) DECLSPEC_HIDDEN;
extern INT MFDRV_IntersectClipRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom ) DECLSPEC_HIDDEN;
extern BOOL MFDRV_InvertRgn( PHYSDEV dev, HRGN hrgn ) DECLSPEC_HIDDEN;
extern BOOL MFDRV_LineTo( PHYSDEV dev, INT x, INT y ) DECLSPEC_HIDDEN;
extern BOOL MFDRV_MoveTo( PHYSDEV dev, INT x, INT y ) DECLSPEC_HIDDEN;
extern INT MFDRV_OffsetClipRgn( PHYSDEV dev, INT x, INT y ) DECLSPEC_HIDDEN;
extern BOOL MFDRV_OffsetViewportOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt ) DECLSPEC_HIDDEN;
extern BOOL MFDRV_OffsetWindowOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt ) DECLSPEC_HIDDEN;
extern BOOL MFDRV_PaintRgn( PHYSDEV dev, HRGN hrgn ) DECLSPEC_HIDDEN;
extern BOOL MFDRV_PatBlt( PHYSDEV dev, struct bitblt_coords *dst, DWORD rop ) DECLSPEC_HIDDEN;
extern BOOL MFDRV_Pie( PHYSDEV dev, INT left, INT top, INT right,
INT bottom, INT xstart, INT ystart, INT xend, INT yend ) DECLSPEC_HIDDEN;
extern BOOL MFDRV_PolyBezier( PHYSDEV dev, const POINT* pt, DWORD count ) DECLSPEC_HIDDEN;
extern BOOL MFDRV_PolyBezierTo( PHYSDEV dev, const POINT* pt, DWORD count ) DECLSPEC_HIDDEN;
extern BOOL MFDRV_PolyPolygon( PHYSDEV dev, const POINT* pt, const INT* counts, UINT polygons) DECLSPEC_HIDDEN;
extern BOOL MFDRV_Polygon( PHYSDEV dev, const POINT* pt, INT count ) DECLSPEC_HIDDEN;
extern BOOL MFDRV_Polyline( PHYSDEV dev, const POINT* pt,INT count) DECLSPEC_HIDDEN;
extern BOOL MFDRV_Rectangle( PHYSDEV dev, INT left, INT top, INT right, INT bottom) DECLSPEC_HIDDEN;
extern BOOL MFDRV_RestoreDC( PHYSDEV dev, INT level ) DECLSPEC_HIDDEN;
extern BOOL MFDRV_RoundRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
INT ell_width, INT ell_height ) DECLSPEC_HIDDEN;
extern INT MFDRV_SaveDC( PHYSDEV dev ) DECLSPEC_HIDDEN;
extern BOOL MFDRV_ScaleViewportExtEx( PHYSDEV dev, INT xNum, INT xDenom, INT yNum, INT yDenom, SIZE *size ) DECLSPEC_HIDDEN;
extern BOOL MFDRV_ScaleWindowExtEx( PHYSDEV dev, INT xNum, INT xDenom, INT yNum, INT yDenom, SIZE *size ) DECLSPEC_HIDDEN;
extern HBITMAP MFDRV_SelectBitmap( PHYSDEV dev, HBITMAP handle ) DECLSPEC_HIDDEN;
extern HBRUSH MFDRV_SelectBrush( PHYSDEV dev, HBRUSH hbrush, const struct brush_pattern *pattern ) DECLSPEC_HIDDEN;
extern BOOL MFDRV_SelectClipPath( PHYSDEV dev, INT iMode ) DECLSPEC_HIDDEN;
extern HFONT MFDRV_SelectFont( PHYSDEV dev, HFONT handle, UINT *aa_flags ) DECLSPEC_HIDDEN;
extern HPEN MFDRV_SelectPen( PHYSDEV dev, HPEN handle, const struct brush_pattern *pattern ) DECLSPEC_HIDDEN;
extern HPALETTE MFDRV_SelectPalette( PHYSDEV dev, HPALETTE hPalette, BOOL bForceBackground) DECLSPEC_HIDDEN;
extern UINT MFDRV_RealizePalette(PHYSDEV dev, HPALETTE hPalette, BOOL primary) DECLSPEC_HIDDEN;
extern COLORREF MFDRV_SetBkColor( PHYSDEV dev, COLORREF color ) DECLSPEC_HIDDEN;
extern INT MFDRV_SetBkMode( PHYSDEV dev, INT mode ) DECLSPEC_HIDDEN;
extern COLORREF MFDRV_SetDCBrushColor( PHYSDEV dev, COLORREF color ) DECLSPEC_HIDDEN;
extern COLORREF MFDRV_SetDCPenColor( PHYSDEV dev, COLORREF color ) DECLSPEC_HIDDEN;
extern INT MFDRV_SetMapMode( PHYSDEV dev, INT mode ) DECLSPEC_HIDDEN;
extern DWORD MFDRV_SetMapperFlags( PHYSDEV dev, DWORD flags ) DECLSPEC_HIDDEN;
extern COLORREF MFDRV_SetPixel( PHYSDEV dev, INT x, INT y, COLORREF color ) DECLSPEC_HIDDEN;
extern INT MFDRV_SetPolyFillMode( PHYSDEV dev, INT mode ) DECLSPEC_HIDDEN;
extern INT MFDRV_SetROP2( PHYSDEV dev, INT rop ) DECLSPEC_HIDDEN;
extern INT MFDRV_SetRelAbs( PHYSDEV dev, INT mode ) DECLSPEC_HIDDEN;
extern INT MFDRV_SetStretchBltMode( PHYSDEV dev, INT mode ) DECLSPEC_HIDDEN;
extern UINT MFDRV_SetTextAlign( PHYSDEV dev, UINT align ) DECLSPEC_HIDDEN;
extern INT MFDRV_SetTextCharacterExtra( PHYSDEV dev, INT extra ) DECLSPEC_HIDDEN;
extern COLORREF MFDRV_SetTextColor( PHYSDEV dev, COLORREF color ) DECLSPEC_HIDDEN;
extern BOOL MFDRV_SetTextJustification( PHYSDEV dev, INT extra, INT breaks ) DECLSPEC_HIDDEN;
extern BOOL MFDRV_SetViewportExtEx( PHYSDEV dev, INT x, INT y, SIZE *size ) DECLSPEC_HIDDEN;
extern BOOL MFDRV_SetViewportOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt ) DECLSPEC_HIDDEN;
extern BOOL MFDRV_SetWindowExtEx( PHYSDEV dev, INT x, INT y, SIZE *size ) DECLSPEC_HIDDEN;
extern BOOL MFDRV_SetWindowOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt ) DECLSPEC_HIDDEN;
extern BOOL MFDRV_StretchBlt( PHYSDEV devDst, struct bitblt_coords *dst,
PHYSDEV devSrc, struct bitblt_coords *src, DWORD rop ) DECLSPEC_HIDDEN;
extern BOOL MFDRV_PaintRgn( PHYSDEV dev, HRGN hrgn ) DECLSPEC_HIDDEN;
extern INT MFDRV_SetDIBitsToDevice( PHYSDEV dev, INT xDest, INT yDest, DWORD cx,
DWORD cy, INT xSrc, INT ySrc,
UINT startscan, UINT lines, LPCVOID bits,
BITMAPINFO *info, UINT coloruse ) DECLSPEC_HIDDEN;
extern INT MFDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst,
INT heightDst, INT xSrc, INT ySrc, INT widthSrc, INT heightSrc,
const void *bits, BITMAPINFO *info, UINT wUsage, DWORD dwRop ) DECLSPEC_HIDDEN;
extern BOOL MFDRV_StrokeAndFillPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
extern BOOL MFDRV_StrokePath( PHYSDEV dev ) DECLSPEC_HIDDEN;
extern BOOL MFDRV_WidenPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
#endif /* __WINE_METAFILEDRV_H */

View File

@ -0,0 +1,462 @@
/*
* GDI objects
*
* Copyright 1993 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "wine/wingdi16.h"
#include "mfdrv/metafiledrv.h"
#include "gdi_private.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(metafile);
/******************************************************************
* MFDRV_AddHandle
*/
UINT MFDRV_AddHandle( PHYSDEV dev, HGDIOBJ obj )
{
METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
UINT16 index;
for(index = 0; index < physDev->handles_size; index++)
if(physDev->handles[index] == 0) break;
if(index == physDev->handles_size) {
physDev->handles_size += HANDLE_LIST_INC;
physDev->handles = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
physDev->handles,
physDev->handles_size * sizeof(physDev->handles[0]));
}
physDev->handles[index] = get_full_gdi_handle( obj );
physDev->cur_handles++;
if(physDev->cur_handles > physDev->mh->mtNoObjects)
physDev->mh->mtNoObjects++;
return index ; /* index 0 is not reserved for metafiles */
}
/******************************************************************
* MFDRV_RemoveHandle
*/
BOOL MFDRV_RemoveHandle( PHYSDEV dev, UINT index )
{
METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
BOOL ret = FALSE;
if (index < physDev->handles_size && physDev->handles[index])
{
physDev->handles[index] = 0;
physDev->cur_handles--;
ret = TRUE;
}
return ret;
}
/******************************************************************
* MFDRV_FindObject
*/
static INT16 MFDRV_FindObject( PHYSDEV dev, HGDIOBJ obj )
{
METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
INT16 index;
for(index = 0; index < physDev->handles_size; index++)
if(physDev->handles[index] == obj) break;
if(index == physDev->handles_size) return -1;
return index ;
}
/******************************************************************
* MFDRV_DeleteObject
*/
BOOL MFDRV_DeleteObject( PHYSDEV dev, HGDIOBJ obj )
{
METARECORD mr;
METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
INT16 index;
BOOL ret = TRUE;
index = MFDRV_FindObject(dev, obj);
if( index < 0 )
return FALSE;
mr.rdSize = sizeof mr / 2;
mr.rdFunction = META_DELETEOBJECT;
mr.rdParm[0] = index;
if(!MFDRV_WriteRecord( dev, &mr, mr.rdSize*2 ))
ret = FALSE;
physDev->handles[index] = 0;
physDev->cur_handles--;
return ret;
}
/***********************************************************************
* MFDRV_SelectObject
*/
static BOOL MFDRV_SelectObject( PHYSDEV dev, INT16 index)
{
METARECORD mr;
mr.rdSize = sizeof mr / 2;
mr.rdFunction = META_SELECTOBJECT;
mr.rdParm[0] = index;
return MFDRV_WriteRecord( dev, &mr, mr.rdSize*2 );
}
/***********************************************************************
* MFDRV_SelectBitmap
*/
HBITMAP MFDRV_SelectBitmap( PHYSDEV dev, HBITMAP hbitmap )
{
return 0;
}
/******************************************************************
* MFDRV_CreateBrushIndirect
*/
INT16 MFDRV_CreateBrushIndirect(PHYSDEV dev, HBRUSH hBrush )
{
DWORD size;
METARECORD *mr;
LOGBRUSH logbrush;
BOOL r;
if (!GetObjectA( hBrush, sizeof(logbrush), &logbrush )) return -1;
switch(logbrush.lbStyle)
{
case BS_SOLID:
case BS_NULL:
case BS_HATCHED:
{
LOGBRUSH16 lb16;
lb16.lbStyle = logbrush.lbStyle;
lb16.lbColor = logbrush.lbColor;
lb16.lbHatch = logbrush.lbHatch;
size = sizeof(METARECORD) + sizeof(LOGBRUSH16) - 2;
mr = HeapAlloc( GetProcessHeap(), 0, size );
mr->rdSize = size / 2;
mr->rdFunction = META_CREATEBRUSHINDIRECT;
memcpy( mr->rdParm, &lb16, sizeof(LOGBRUSH16));
break;
}
case BS_PATTERN:
case BS_DIBPATTERN:
{
char buffer[sizeof(BITMAPINFO) + 255 * sizeof(RGBQUAD)]; // ros
//char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
BITMAPINFO *dst_info, *src_info = (BITMAPINFO *)buffer;
DWORD info_size;
char *dst_ptr;
void *bits;
UINT usage;
if (!get_brush_bitmap_info( hBrush, src_info, &bits, &usage )) goto done;
info_size = get_dib_info_size( src_info, usage );
size = FIELD_OFFSET( METARECORD, rdParm[2] ) + info_size + src_info->bmiHeader.biSizeImage;
if (!(mr = HeapAlloc( GetProcessHeap(), 0, size ))) goto done;
mr->rdFunction = META_DIBCREATEPATTERNBRUSH;
mr->rdSize = size / 2;
mr->rdParm[0] = logbrush.lbStyle;
mr->rdParm[1] = usage;
dst_info = (BITMAPINFO *)(mr->rdParm + 2);
memcpy( dst_info, src_info, info_size );
if (dst_info->bmiHeader.biClrUsed == 1 << dst_info->bmiHeader.biBitCount)
dst_info->bmiHeader.biClrUsed = 0;
dst_ptr = (char *)dst_info + info_size;
/* always return a bottom-up DIB */
if (dst_info->bmiHeader.biHeight < 0)
{
int i, width_bytes = get_dib_stride( dst_info->bmiHeader.biWidth,
dst_info->bmiHeader.biBitCount );
dst_info->bmiHeader.biHeight = -dst_info->bmiHeader.biHeight;
dst_ptr += (dst_info->bmiHeader.biHeight - 1) * width_bytes;
for (i = 0; i < dst_info->bmiHeader.biHeight; i++, dst_ptr -= width_bytes)
memcpy( dst_ptr, (char *)bits + i * width_bytes, width_bytes );
}
else memcpy( dst_ptr, bits, src_info->bmiHeader.biSizeImage );
break;
}
default:
FIXME("Unknown brush style %x\n", logbrush.lbStyle);
return 0;
}
r = MFDRV_WriteRecord( dev, mr, mr->rdSize * 2);
HeapFree(GetProcessHeap(), 0, mr);
if( !r )
return -1;
done:
return MFDRV_AddHandle( dev, hBrush );
}
/***********************************************************************
* MFDRV_SelectBrush
*/
HBRUSH MFDRV_SelectBrush( PHYSDEV dev, HBRUSH hbrush, const struct brush_pattern *pattern )
{
INT16 index;
index = MFDRV_FindObject(dev, hbrush);
if( index < 0 )
{
index = MFDRV_CreateBrushIndirect( dev, hbrush );
if( index < 0 )
return 0;
GDI_hdc_using_object(hbrush, dev->hdc);
}
return MFDRV_SelectObject( dev, index ) ? hbrush : 0;
}
/******************************************************************
* MFDRV_CreateFontIndirect
*/
static UINT16 MFDRV_CreateFontIndirect(PHYSDEV dev, HFONT hFont, LOGFONTW *logfont)
{
char buffer[sizeof(METARECORD) - 2 + sizeof(LOGFONT16)];
METARECORD *mr = (METARECORD *)&buffer;
LOGFONT16 *font16;
INT written;
mr->rdSize = (sizeof(METARECORD) + sizeof(LOGFONT16) - 2) / 2;
mr->rdFunction = META_CREATEFONTINDIRECT;
font16 = (LOGFONT16 *)&mr->rdParm;
font16->lfHeight = logfont->lfHeight;
font16->lfWidth = logfont->lfWidth;
font16->lfEscapement = logfont->lfEscapement;
font16->lfOrientation = logfont->lfOrientation;
font16->lfWeight = logfont->lfWeight;
font16->lfItalic = logfont->lfItalic;
font16->lfUnderline = logfont->lfUnderline;
font16->lfStrikeOut = logfont->lfStrikeOut;
font16->lfCharSet = logfont->lfCharSet;
font16->lfOutPrecision = logfont->lfOutPrecision;
font16->lfClipPrecision = logfont->lfClipPrecision;
font16->lfQuality = logfont->lfQuality;
font16->lfPitchAndFamily = logfont->lfPitchAndFamily;
written = WideCharToMultiByte( CP_ACP, 0, logfont->lfFaceName, -1, font16->lfFaceName, LF_FACESIZE - 1, NULL, NULL );
/* Zero pad the facename buffer, so that we don't write uninitialized data to disk */
memset(font16->lfFaceName + written, 0, LF_FACESIZE - written);
if (!(MFDRV_WriteRecord( dev, mr, mr->rdSize * 2)))
return 0;
return MFDRV_AddHandle( dev, hFont );
}
/***********************************************************************
* MFDRV_SelectFont
*/
HFONT MFDRV_SelectFont( PHYSDEV dev, HFONT hfont, UINT *aa_flags )
{
LOGFONTW font;
INT16 index;
*aa_flags = GGO_BITMAP; /* no point in anti-aliasing on metafiles */
index = MFDRV_FindObject(dev, hfont);
if( index < 0 )
{
if (!GetObjectW( hfont, sizeof(font), &font ))
return 0;
index = MFDRV_CreateFontIndirect(dev, hfont, &font);
if( index < 0 )
return 0;
GDI_hdc_using_object(hfont, dev->hdc);
}
return MFDRV_SelectObject( dev, index ) ? hfont : 0;
}
/******************************************************************
* MFDRV_CreatePenIndirect
*/
static UINT16 MFDRV_CreatePenIndirect(PHYSDEV dev, HPEN hPen, LOGPEN16 *logpen)
{
char buffer[sizeof(METARECORD) - 2 + sizeof(*logpen)];
METARECORD *mr = (METARECORD *)&buffer;
mr->rdSize = (sizeof(METARECORD) + sizeof(*logpen) - 2) / 2;
mr->rdFunction = META_CREATEPENINDIRECT;
memcpy(&(mr->rdParm), logpen, sizeof(*logpen));
if (!(MFDRV_WriteRecord( dev, mr, mr->rdSize * 2)))
return 0;
return MFDRV_AddHandle( dev, hPen );
}
/***********************************************************************
* MFDRV_SelectPen
*/
HPEN MFDRV_SelectPen( PHYSDEV dev, HPEN hpen, const struct brush_pattern *pattern )
{
LOGPEN16 logpen;
INT16 index;
index = MFDRV_FindObject(dev, hpen);
if( index < 0 )
{
/* must be an extended pen */
INT size = GetObjectW( hpen, 0, NULL );
if (!size) return 0;
if (size == sizeof(LOGPEN))
{
LOGPEN pen;
GetObjectW( hpen, sizeof(pen), &pen );
logpen.lopnStyle = pen.lopnStyle;
logpen.lopnWidth.x = pen.lopnWidth.x;
logpen.lopnWidth.y = pen.lopnWidth.y;
logpen.lopnColor = pen.lopnColor;
}
else /* must be an extended pen */
{
EXTLOGPEN *elp = HeapAlloc( GetProcessHeap(), 0, size );
GetObjectW( hpen, size, elp );
/* FIXME: add support for user style pens */
logpen.lopnStyle = elp->elpPenStyle;
logpen.lopnWidth.x = elp->elpWidth;
logpen.lopnWidth.y = 0;
logpen.lopnColor = elp->elpColor;
HeapFree( GetProcessHeap(), 0, elp );
}
index = MFDRV_CreatePenIndirect( dev, hpen, &logpen );
if( index < 0 )
return 0;
GDI_hdc_using_object(hpen, dev->hdc);
}
return MFDRV_SelectObject( dev, index ) ? hpen : 0;
}
/******************************************************************
* MFDRV_CreatePalette
*/
static BOOL MFDRV_CreatePalette(PHYSDEV dev, HPALETTE hPalette, LOGPALETTE* logPalette, int sizeofPalette)
{
int index;
BOOL ret;
METARECORD *mr;
mr = HeapAlloc( GetProcessHeap(), 0, sizeof(METARECORD) + sizeofPalette - sizeof(WORD) );
mr->rdSize = (sizeof(METARECORD) + sizeofPalette - sizeof(WORD)) / sizeof(WORD);
mr->rdFunction = META_CREATEPALETTE;
memcpy(&(mr->rdParm), logPalette, sizeofPalette);
if (!(MFDRV_WriteRecord( dev, mr, mr->rdSize * sizeof(WORD))))
{
HeapFree(GetProcessHeap(), 0, mr);
return FALSE;
}
mr->rdSize = sizeof(METARECORD) / sizeof(WORD);
mr->rdFunction = META_SELECTPALETTE;
if ((index = MFDRV_AddHandle( dev, hPalette )) == -1) ret = FALSE;
else
{
*(mr->rdParm) = index;
ret = MFDRV_WriteRecord( dev, mr, mr->rdSize * sizeof(WORD));
}
HeapFree(GetProcessHeap(), 0, mr);
return ret;
}
/***********************************************************************
* MFDRV_SelectPalette
*/
HPALETTE MFDRV_SelectPalette( PHYSDEV dev, HPALETTE hPalette, BOOL bForceBackground )
{
#define PALVERSION 0x0300
PLOGPALETTE logPalette;
WORD wNumEntries = 0;
BOOL creationSucceed;
int sizeofPalette;
GetObjectA(hPalette, sizeof(WORD), &wNumEntries);
if (wNumEntries == 0) return 0;
sizeofPalette = sizeof(LOGPALETTE) + ((wNumEntries-1) * sizeof(PALETTEENTRY));
logPalette = HeapAlloc( GetProcessHeap(), 0, sizeofPalette );
if (logPalette == NULL) return 0;
logPalette->palVersion = PALVERSION;
logPalette->palNumEntries = wNumEntries;
GetPaletteEntries(hPalette, 0, wNumEntries, logPalette->palPalEntry);
creationSucceed = MFDRV_CreatePalette( dev, hPalette, logPalette, sizeofPalette );
HeapFree( GetProcessHeap(), 0, logPalette );
if (creationSucceed)
return hPalette;
return 0;
}
/***********************************************************************
* MFDRV_RealizePalette
*/
UINT MFDRV_RealizePalette(PHYSDEV dev, HPALETTE hPalette, BOOL dummy)
{
char buffer[sizeof(METARECORD) - sizeof(WORD)];
METARECORD *mr = (METARECORD *)&buffer;
mr->rdSize = (sizeof(METARECORD) - sizeof(WORD)) / sizeof(WORD);
mr->rdFunction = META_REALIZEPALETTE;
if (!(MFDRV_WriteRecord( dev, mr, mr->rdSize * sizeof(WORD)))) return 0;
/* The return value is suppose to be the number of entries
in the logical palette mapped to the system palette or 0
if the function failed. Since it's not trivial here to
get that kind of information and since it's of little
use in the case of metafiles, we'll always return 1. */
return 1;
}

View File

@ -0,0 +1,153 @@
/*
* metafile driver text functions
*
* Copyright 1993, 1994 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#include <string.h>
#include "windef.h"
#include "winbase.h"
#include "wine/wingdi16.h"
#include "mfdrv/metafiledrv.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(metafile);
/******************************************************************
* MFDRV_MetaExtTextOut
*/
static BOOL MFDRV_MetaExtTextOut( PHYSDEV dev, short x, short y, UINT16 flags,
const RECT16 *rect, LPCSTR str, short count,
const INT16 *lpDx)
{
BOOL ret;
DWORD len;
METARECORD *mr;
BOOL isrect = flags & (ETO_CLIPPED | ETO_OPAQUE);
len = sizeof(METARECORD) + (((count + 1) >> 1) * 2) + 2 * sizeof(short)
+ sizeof(UINT16);
if (isrect)
len += sizeof(RECT16);
if (lpDx)
len+=count*sizeof(INT16);
if (!(mr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len)))
return FALSE;
mr->rdSize = len / 2;
mr->rdFunction = META_EXTTEXTOUT;
*(mr->rdParm) = y;
*(mr->rdParm + 1) = x;
*(mr->rdParm + 2) = count;
*(mr->rdParm + 3) = flags;
if (isrect) memcpy(mr->rdParm + 4, rect, sizeof(RECT16));
memcpy(mr->rdParm + (isrect ? 8 : 4), str, count);
if (lpDx)
memcpy(mr->rdParm + (isrect ? 8 : 4) + ((count + 1) >> 1),lpDx,
count*sizeof(INT16));
ret = MFDRV_WriteRecord( dev, mr, mr->rdSize * 2);
HeapFree( GetProcessHeap(), 0, mr);
return ret;
}
/***********************************************************************
* MFDRV_ExtTextOut
*/
BOOL MFDRV_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags,
const RECT *lprect, LPCWSTR str, UINT count, const INT *lpDx )
{
RECT16 rect16;
LPINT16 lpdx16 = NULL;
BOOL ret;
unsigned int i, j;
LPSTR ascii;
DWORD len;
CHARSETINFO csi;
int charset = GetTextCharset( dev->hdc );
UINT cp = CP_ACP;
if(TranslateCharsetInfo(ULongToPtr(charset), &csi, TCI_SRCCHARSET))
cp = csi.ciACP;
else {
switch(charset) {
case OEM_CHARSET:
cp = GetOEMCP();
break;
case DEFAULT_CHARSET:
cp = GetACP();
break;
case VISCII_CHARSET:
case TCVN_CHARSET:
case KOI8_CHARSET:
case ISO3_CHARSET:
case ISO4_CHARSET:
case ISO10_CHARSET:
case CELTIC_CHARSET:
/* FIXME: These have no place here, but because x11drv
enumerates fonts with these (made up) charsets some apps
might use them and then the FIXME below would become
annoying. Now we could pick the intended codepage for
each of these, but since it's broken anyway we'll just
use CP_ACP and hope it'll go away...
*/
cp = CP_ACP;
break;
default:
FIXME("Can't find codepage for charset %d\n", charset);
break;
}
}
TRACE("cp == %d\n", cp);
len = WideCharToMultiByte(cp, 0, str, count, NULL, 0, NULL, NULL);
ascii = HeapAlloc(GetProcessHeap(), 0, len);
WideCharToMultiByte(cp, 0, str, count, ascii, len, NULL, NULL);
TRACE("mapped %s -> %s\n", debugstr_wn(str, count), debugstr_an(ascii, len));
if (lprect)
{
rect16.left = lprect->left;
rect16.top = lprect->top;
rect16.right = lprect->right;
rect16.bottom = lprect->bottom;
}
if(lpDx) {
lpdx16 = HeapAlloc( GetProcessHeap(), 0, sizeof(INT16)*len );
for(i = j = 0; i < len; )
if(IsDBCSLeadByteEx(cp, ascii[i])) {
lpdx16[i++] = lpDx[j++];
lpdx16[i++] = 0;
} else
lpdx16[i++] = lpDx[j++];
}
ret = MFDRV_MetaExtTextOut(dev,x,y,flags,lprect?&rect16:NULL,ascii,len,lpdx16);
HeapFree( GetProcessHeap(), 0, ascii );
HeapFree( GetProcessHeap(), 0, lpdx16 );
return ret;
}

File diff suppressed because it is too large Load Diff

View File

@ -15,18 +15,15 @@
/* DEFINES *******************************************************************/
/* Base address where the handle table is mapped to */
#define GDI_HANDLE_TABLE_BASE_ADDRESS (0x400000)
/* GDI handle table can hold 0x10000 handles */
#define GDI_HANDLE_COUNT 0x10000
#define GDI_GLOBAL_PROCESS (0x0)
#define GDI_CFONT_MAX 16
/* Handle Masks and shifts */
#define GDI_HANDLE_INDEX_MASK (GDI_HANDLE_COUNT - 1)
#define GDI_HANDLE_TYPE_MASK 0x007f0000
#define GDI_HANDLE_BASETYPE_MASK 0x001f0000
#define GDI_HANDLE_EXTYPE_MASK 0x00600000
#define GDI_HANDLE_STOCK_MASK 0x00800000
#define GDI_HANDLE_REUSE_MASK 0xff000000
#define GDI_HANDLE_UPPER_MASK (GDI_HANDLE_TYPE_MASK|GDI_HANDLE_STOCK_MASK|GDI_HANDLE_REUSE_MASK)
@ -34,11 +31,7 @@
#define GDI_HANDLE_BASETYPE_SHIFT 16
#define GDI_ENTRY_STOCK_MASK 0x00000080
#define GDI_ENTRY_REUSE_MASK 0x0000ff00
#define GDI_ENTRY_REUSE_INC 0x00000100
#define GDI_ENTRY_BASETYPE_MASK 0x001f0000
#define GDI_ENTRY_FLAGS_MASK 0xff000000
#define GDI_ENTRY_REUSECNT_SHIFT 8
#define GDI_ENTRY_UPPER_SHIFT 16
/* GDI Entry Flags */
@ -115,9 +108,6 @@
#define GDI_HANDLE_GET_REUSECNT(h) \
(((ULONG_PTR)(h)) >> GDI_HANDLE_REUSECNT_SHIFT)
#define GDI_ENTRY_GET_REUSECNT(e) \
((((ULONG_PTR)(e)) & GDI_ENTRY_REUSE_MASK) >> GDI_ENTRY_REUSECNT_SHIFT)
#define GDI_OBJECT_GET_TYPE_INDEX(t) \
((t & GDI_HANDLE_BASETYPE_MASK) >> GDI_HANDLE_BASETYPE_SHIFT)