From: Piotr Caban piotr@codeweavers.com
--- dlls/gdi32/emfdc.c | 114 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 94 insertions(+), 20 deletions(-)
diff --git a/dlls/gdi32/emfdc.c b/dlls/gdi32/emfdc.c index 9690bee2a17..990ee6e8109 100644 --- a/dlls/gdi32/emfdc.c +++ b/dlls/gdi32/emfdc.c @@ -892,13 +892,16 @@ BOOL EMFDC_MoveTo( DC_ATTR *dc_attr, INT x, INT y )
BOOL EMFDC_LineTo( DC_ATTR *dc_attr, INT x, INT y ) { + struct emf *emf = get_dc_emf( dc_attr ); EMRLINETO emr;
+ if (emf->document_state == NEEDS_START_PAGE) StartPage( dc_attr_handle(dc_attr) ); + emr.emr.iType = EMR_LINETO; emr.emr.nSize = sizeof(emr); emr.ptl.x = x; emr.ptl.y = y; - return emfdc_record( get_dc_emf( dc_attr ), &emr.emr ); + return emfdc_record( emf, &emr.emr ); }
BOOL EMFDC_ArcChordPie( DC_ATTR *dc_attr, INT left, INT top, INT right, INT bottom, @@ -909,6 +912,7 @@ BOOL EMFDC_ArcChordPie( DC_ATTR *dc_attr, INT left, INT top, INT right, INT bott INT temp;
if (left == right || top == bottom) return FALSE; + if (emf->document_state == NEEDS_START_PAGE) StartPage( dc_attr_handle(dc_attr) );
if (left > right) { temp = left; left = right; right = temp; } if (top > bottom) { temp = top; top = bottom; bottom = temp; } @@ -934,8 +938,11 @@ BOOL EMFDC_ArcChordPie( DC_ATTR *dc_attr, INT left, INT top, INT right, INT bott
BOOL EMFDC_AngleArc( DC_ATTR *dc_attr, INT x, INT y, DWORD radius, FLOAT start, FLOAT sweep ) { + struct emf *emf = get_dc_emf( dc_attr ); EMRANGLEARC emr;
+ if (emf->document_state == NEEDS_START_PAGE) StartPage( dc_attr_handle(dc_attr) ); + emr.emr.iType = EMR_ANGLEARC; emr.emr.nSize = sizeof( emr ); emr.ptlCenter.x = x; @@ -943,7 +950,7 @@ BOOL EMFDC_AngleArc( DC_ATTR *dc_attr, INT x, INT y, DWORD radius, FLOAT start, emr.nRadius = radius; emr.eStartAngle = start; emr.eSweepAngle = sweep; - return emfdc_record( get_dc_emf( dc_attr ), &emr.emr ); + return emfdc_record( emf, &emr.emr ); }
BOOL EMFDC_Ellipse( DC_ATTR *dc_attr, INT left, INT top, INT right, INT bottom ) @@ -952,6 +959,7 @@ BOOL EMFDC_Ellipse( DC_ATTR *dc_attr, INT left, INT top, INT right, INT bottom ) EMRELLIPSE emr;
if (left == right || top == bottom) return FALSE; + if (emf->document_state == NEEDS_START_PAGE) StartPage( dc_attr_handle(dc_attr) );
emr.emr.iType = EMR_ELLIPSE; emr.emr.nSize = sizeof(emr); @@ -972,7 +980,8 @@ BOOL EMFDC_Rectangle( DC_ATTR *dc_attr, INT left, INT top, INT right, INT bottom struct emf *emf = get_dc_emf( dc_attr ); EMRRECTANGLE emr;
- if(left == right || top == bottom) return FALSE; + if (left == right || top == bottom) return FALSE; + if (emf->document_state == NEEDS_START_PAGE) StartPage( dc_attr_handle(dc_attr) );
emr.emr.iType = EMR_RECTANGLE; emr.emr.nSize = sizeof(emr); @@ -995,6 +1004,7 @@ BOOL EMFDC_RoundRect( DC_ATTR *dc_attr, INT left, INT top, INT right, EMRROUNDRECT emr;
if (left == right || top == bottom) return FALSE; + if (emf->document_state == NEEDS_START_PAGE) StartPage( dc_attr_handle(dc_attr) );
emr.emr.iType = EMR_ROUNDRECT; emr.emr.nSize = sizeof(emr); @@ -1014,14 +1024,17 @@ BOOL EMFDC_RoundRect( DC_ATTR *dc_attr, INT left, INT top, INT right,
BOOL EMFDC_SetPixel( DC_ATTR *dc_attr, INT x, INT y, COLORREF color ) { + struct emf *emf = get_dc_emf( dc_attr ); EMRSETPIXELV emr;
+ if (emf->document_state == NEEDS_START_PAGE) StartPage( dc_attr_handle(dc_attr) ); + emr.emr.iType = EMR_SETPIXELV; emr.emr.nSize = sizeof(emr); emr.ptlPixel.x = x; emr.ptlPixel.y = y; emr.crColor = color; - return emfdc_record( get_dc_emf( dc_attr ), &emr.emr ); + return emfdc_record( emf, &emr.emr ); }
static BOOL emfdc_polylinegon( DC_ATTR *dc_attr, const POINT *points, INT count, DWORD type ) @@ -1031,6 +1044,8 @@ static BOOL emfdc_polylinegon( DC_ATTR *dc_attr, const POINT *points, INT count, DWORD size; BOOL ret, use_small_emr = can_use_short_points( points, count );
+ if (emf->document_state == NEEDS_START_PAGE) StartPage( dc_attr_handle(dc_attr) ); + size = use_small_emr ? offsetof( EMRPOLYLINE16, apts[count] ) : offsetof( EMRPOLYLINE, aptl[count] );
emr = HeapAlloc( GetProcessHeap(), 0, size ); @@ -1131,11 +1146,17 @@ static BOOL emfdc_poly_polylinegon( struct emf *emf, const POINT *pt, const INT
BOOL EMFDC_PolyPolyline( DC_ATTR *dc_attr, const POINT *pt, const DWORD *counts, DWORD polys) { + struct emf *emf = get_dc_emf( dc_attr ); + + if (emf->document_state == NEEDS_START_PAGE) StartPage( dc_attr_handle(dc_attr) ); return emfdc_poly_polylinegon( get_dc_emf( dc_attr ), pt, (const INT *)counts, polys, EMR_POLYPOLYLINE ); }
BOOL EMFDC_PolyPolygon( DC_ATTR *dc_attr, const POINT *pt, const INT *counts, UINT polys ) { + struct emf *emf = get_dc_emf( dc_attr ); + + if (emf->document_state == NEEDS_START_PAGE) StartPage( dc_attr_handle(dc_attr) ); return emfdc_poly_polylinegon( get_dc_emf( dc_attr ), pt, counts, polys, EMR_POLYPOLYGON ); }
@@ -1148,6 +1169,8 @@ BOOL EMFDC_PolyDraw( DC_ATTR *dc_attr, const POINT *pts, const BYTE *types, DWOR BOOL use_small_emr = can_use_short_points( pts, count ); DWORD size;
+ if (emf->document_state == NEEDS_START_PAGE) StartPage( dc_attr_handle(dc_attr) ); + size = use_small_emr ? offsetof( EMRPOLYDRAW16, apts[count] ) : offsetof( EMRPOLYDRAW, aptl[count] ); size += (count + 3) & ~3; @@ -1175,15 +1198,18 @@ BOOL EMFDC_PolyDraw( DC_ATTR *dc_attr, const POINT *pts, const BYTE *types, DWOR
BOOL EMFDC_ExtFloodFill( DC_ATTR *dc_attr, INT x, INT y, COLORREF color, UINT fill_type ) { + struct emf *emf = get_dc_emf( dc_attr ); EMREXTFLOODFILL emr;
+ if (emf->document_state == NEEDS_START_PAGE) StartPage( dc_attr_handle(dc_attr) ); + emr.emr.iType = EMR_EXTFLOODFILL; emr.emr.nSize = sizeof(emr); emr.ptlStart.x = x; emr.ptlStart.y = y; emr.crColor = color; emr.iMode = fill_type; - return emfdc_record( get_dc_emf( dc_attr ), &emr.emr ); + return emfdc_record( emf, &emr.emr ); }
BOOL EMFDC_FillRgn( DC_ATTR *dc_attr, HRGN hrgn, HBRUSH hbrush ) @@ -1193,6 +1219,8 @@ BOOL EMFDC_FillRgn( DC_ATTR *dc_attr, HRGN hrgn, HBRUSH hbrush ) DWORD size, rgnsize, index; BOOL ret;
+ if (emf->document_state == NEEDS_START_PAGE) StartPage( dc_attr_handle(dc_attr) ); + if (!(index = emfdc_create_brush( emf, hbrush ))) return FALSE;
rgnsize = NtGdiGetRegionData( hrgn, 0, NULL ); @@ -1223,6 +1251,8 @@ BOOL EMFDC_FrameRgn( DC_ATTR *dc_attr, HRGN hrgn, HBRUSH hbrush, INT width, INT DWORD size, rgnsize, index; BOOL ret;
+ if (emf->document_state == NEEDS_START_PAGE) StartPage( dc_attr_handle(dc_attr) ); + index = emfdc_create_brush( emf, hbrush ); if(!index) return FALSE;
@@ -1277,12 +1307,18 @@ static BOOL emfdc_paint_invert_region( struct emf *emf, HRGN hrgn, DWORD iType )
BOOL EMFDC_PaintRgn( DC_ATTR *dc_attr, HRGN hrgn ) { - return emfdc_paint_invert_region( get_dc_emf( dc_attr ), hrgn, EMR_PAINTRGN ); + struct emf *emf = get_dc_emf( dc_attr ); + + if (emf->document_state == NEEDS_START_PAGE) StartPage( dc_attr_handle(dc_attr) ); + return emfdc_paint_invert_region( emf, hrgn, EMR_PAINTRGN ); }
BOOL EMFDC_InvertRgn( DC_ATTR *dc_attr, HRGN hrgn ) { - return emfdc_paint_invert_region( get_dc_emf( dc_attr ), hrgn, EMR_INVERTRGN ); + struct emf *emf = get_dc_emf( dc_attr ); + + if (emf->document_state == NEEDS_START_PAGE) StartPage( dc_attr_handle(dc_attr) ); + return emfdc_paint_invert_region( emf, hrgn, EMR_INVERTRGN ); }
BOOL EMFDC_ExtTextOut( DC_ATTR *dc_attr, INT x, INT y, UINT flags, const RECT *rect, @@ -1298,6 +1334,8 @@ BOOL EMFDC_ExtTextOut( DC_ATTR *dc_attr, INT x, INT y, UINT flags, const RECT *r DWORD size; BOOL ret;
+ if (emf->document_state == NEEDS_START_PAGE) StartPage( dc_attr_handle(dc_attr) ); + size = sizeof(*emr) + ((count+1) & ~1) * sizeof(WCHAR) + count * sizeof(INT);
TRACE( "%s %s count %d size = %ld\n", debugstr_wn(str, count), @@ -1431,11 +1469,14 @@ no_bounds: BOOL EMFDC_GradientFill( DC_ATTR *dc_attr, TRIVERTEX *vert_array, ULONG nvert, void *grad_array, ULONG ngrad, ULONG mode ) { + struct emf *emf = get_dc_emf( dc_attr ); EMRGRADIENTFILL *emr; ULONG i, pt, size, num_pts = ngrad * (mode == GRADIENT_FILL_TRIANGLE ? 3 : 2); const ULONG *pts = (const ULONG *)grad_array; BOOL ret;
+ if (emf->document_state == NEEDS_START_PAGE) StartPage( dc_attr_handle(dc_attr) ); + size = FIELD_OFFSET(EMRGRADIENTFILL, Ver[nvert]) + num_pts * sizeof(pts[0]);
emr = HeapAlloc( GetProcessHeap(), 0, size ); @@ -1473,25 +1514,34 @@ BOOL EMFDC_GradientFill( DC_ATTR *dc_attr, TRIVERTEX *vert_array, ULONG nvert, memcpy( emr->Ver, vert_array, nvert * sizeof(vert_array[0]) ); memcpy( emr->Ver + nvert, pts, num_pts * sizeof(pts[0]) );
- emfdc_update_bounds( get_dc_emf( dc_attr ), &emr->rclBounds ); - ret = emfdc_record( get_dc_emf( dc_attr ), &emr->emr ); + emfdc_update_bounds( emf, &emr->rclBounds ); + ret = emfdc_record( emf, &emr->emr ); HeapFree( GetProcessHeap(), 0, emr ); return ret; }
BOOL EMFDC_FillPath( DC_ATTR *dc_attr ) { - return emfdrv_stroke_and_fill_path( get_dc_emf( dc_attr ), EMR_FILLPATH ); + struct emf *emf = get_dc_emf( dc_attr ); + + if (emf->document_state == NEEDS_START_PAGE) StartPage( dc_attr_handle(dc_attr) ); + return emfdrv_stroke_and_fill_path( emf, EMR_FILLPATH ); }
BOOL EMFDC_StrokeAndFillPath( DC_ATTR *dc_attr ) { - return emfdrv_stroke_and_fill_path( get_dc_emf( dc_attr ), EMR_STROKEANDFILLPATH ); + struct emf *emf = get_dc_emf( dc_attr ); + + if (emf->document_state == NEEDS_START_PAGE) StartPage( dc_attr_handle(dc_attr) ); + return emfdrv_stroke_and_fill_path( emf, EMR_STROKEANDFILLPATH ); }
BOOL EMFDC_StrokePath( DC_ATTR *dc_attr ) { - return emfdrv_stroke_and_fill_path( get_dc_emf( dc_attr ), EMR_STROKEPATH ); + struct emf *emf = get_dc_emf( dc_attr ); + + if (emf->document_state == NEEDS_START_PAGE) StartPage( dc_attr_handle(dc_attr) ); + return emfdrv_stroke_and_fill_path( emf, EMR_STROKEPATH ); }
/* Generate an EMRBITBLT, EMRSTRETCHBLT or EMRALPHABLEND record depending on the type parameter */ @@ -1567,7 +1617,10 @@ BOOL EMFDC_AlphaBlend( DC_ATTR *dc_attr, INT x_dst, INT y_dst, INT width_dst, IN HDC hdc_src, INT x_src, INT y_src, INT width_src, INT height_src, BLENDFUNCTION blend_function ) { - return emfdrv_stretchblt( get_dc_emf( dc_attr ), x_dst, y_dst, width_dst, height_dst, hdc_src, + struct emf *emf = get_dc_emf( dc_attr ); + + if (emf->document_state == NEEDS_START_PAGE) StartPage( dc_attr_handle(dc_attr) ); + return emfdrv_stretchblt( emf, x_dst, y_dst, width_dst, height_dst, hdc_src, x_src, y_src, width_src, height_src, *(DWORD *)&blend_function, EMR_ALPHABLEND ); } @@ -1578,6 +1631,8 @@ BOOL EMFDC_PatBlt( DC_ATTR *dc_attr, INT left, INT top, INT width, INT height, D EMRBITBLT emr; BOOL ret;
+ if (emf->document_state == NEEDS_START_PAGE) StartPage( dc_attr_handle(dc_attr) ); + emr.emr.iType = EMR_BITBLT; emr.emr.nSize = sizeof(emr); emr.rclBounds.left = left; @@ -1617,8 +1672,11 @@ static inline BOOL rop_uses_src( DWORD rop ) BOOL EMFDC_BitBlt( DC_ATTR *dc_attr, INT x_dst, INT y_dst, INT width, INT height, HDC hdc_src, INT x_src, INT y_src, DWORD rop ) { + struct emf *emf = get_dc_emf( dc_attr ); + if (!rop_uses_src( rop )) return EMFDC_PatBlt( dc_attr, x_dst, y_dst, width, height, rop ); - return emfdrv_stretchblt( get_dc_emf( dc_attr ), x_dst, y_dst, width, height, + if (emf->document_state == NEEDS_START_PAGE) StartPage( dc_attr_handle(dc_attr) ); + return emfdrv_stretchblt( emf, x_dst, y_dst, width, height, hdc_src, x_src, y_src, width, height, rop, EMR_BITBLT ); }
@@ -1626,8 +1684,11 @@ BOOL EMFDC_StretchBlt( DC_ATTR *dc_attr, INT x_dst, INT y_dst, INT width_dst, IN HDC hdc_src, INT x_src, INT y_src, INT width_src, INT height_src, DWORD rop ) { + struct emf *emf = get_dc_emf( dc_attr ); + if (!rop_uses_src( rop )) return EMFDC_PatBlt( dc_attr, x_dst, y_dst, width_dst, height_dst, rop ); - return emfdrv_stretchblt( get_dc_emf( dc_attr ), x_dst, y_dst, width_dst, height_dst, + if (emf->document_state == NEEDS_START_PAGE) StartPage( dc_attr_handle(dc_attr) ); + return emfdrv_stretchblt( emf, x_dst, y_dst, width_dst, height_dst, hdc_src, x_src, y_src, width_src, height_src, rop, EMR_STRETCHBLT ); } @@ -1636,7 +1697,10 @@ BOOL EMFDC_TransparentBlt( DC_ATTR *dc_attr, int x_dst, int y_dst, int width_dst HDC hdc_src, int x_src, int y_src, int width_src, int height_src, UINT color ) { - return emfdrv_stretchblt( get_dc_emf( dc_attr ), x_dst, y_dst, width_dst, height_dst, + struct emf *emf = get_dc_emf( dc_attr ); + + if (emf->document_state == NEEDS_START_PAGE) StartPage( dc_attr_handle(dc_attr) ); + return emfdrv_stretchblt( emf, x_dst, y_dst, width_dst, height_dst, hdc_src, x_src, y_src, width_src, height_src, color, EMR_TRANSPARENTBLT ); } @@ -1657,6 +1721,8 @@ BOOL EMFDC_MaskBlt( DC_ATTR *dc_attr, INT x_dst, INT y_dst, INT width_dst, INT h HDC blit_dc, mask_dc = NULL; BOOL ret = FALSE;
+ if (emf->document_state == NEEDS_START_PAGE) StartPage( dc_attr_handle(dc_attr) ); + if (!rop_uses_src( rop )) return EMFDC_PatBlt( dc_attr, x_dst, y_dst, width_dst, height_dst, rop );
@@ -1753,6 +1819,8 @@ BOOL EMFDC_PlgBlt( DC_ATTR *dc_attr, const POINT *points, HDC hdc_src, INT x_src int x_min, y_min, x_max, y_max, i; BOOL ret = FALSE;
+ if (emf->document_state == NEEDS_START_PAGE) StartPage( dc_attr_handle(dc_attr) ); + if (!(bitmap = GetCurrentObject( hdc_src, OBJ_BITMAP ))) return FALSE;
blit_dc = hdc_src; @@ -1844,12 +1912,15 @@ BOOL EMFDC_StretchDIBits( DC_ATTR *dc_attr, INT x_dst, INT y_dst, INT width_dst, INT x_src, INT y_src, INT width_src, INT height_src, const void *bits, const BITMAPINFO *info, UINT usage, DWORD rop ) { + struct emf *emf = get_dc_emf( dc_attr ); EMRSTRETCHDIBITS *emr; BOOL ret; UINT bmi_size, img_size, payload_size, emr_size; BITMAPINFOHEADER bih; BITMAPINFO *bi;
+ if (emf->document_state == NEEDS_START_PAGE) StartPage( dc_attr_handle(dc_attr) ); + /* calculate the size of the colour table and the image */ if (!emf_parse_user_bitmapinfo( &bih, &info->bmiHeader, usage, TRUE, &bmi_size, &img_size )) return 0; @@ -1899,8 +1970,8 @@ BOOL EMFDC_StretchDIBits( DC_ATTR *dc_attr, INT x_dst, INT y_dst, INT width_dst, emr->rclBounds.bottom = y_dst + height_dst - 1;
/* save the record we just created */ - ret = emfdc_record( get_dc_emf( dc_attr ), &emr->emr ); - if (ret) emfdc_update_bounds( get_dc_emf( dc_attr ), &emr->rclBounds ); + ret = emfdc_record( emf, &emr->emr ); + if (ret) emfdc_update_bounds( emf, &emr->rclBounds ); HeapFree( GetProcessHeap(), 0, emr ); return ret; } @@ -1909,6 +1980,7 @@ BOOL EMFDC_SetDIBitsToDevice( DC_ATTR *dc_attr, INT x_dst, INT y_dst, DWORD widt INT x_src, INT y_src, UINT startscan, UINT lines, const void *bits, const BITMAPINFO *info, UINT usage ) { + struct emf *emf = get_dc_emf( dc_attr ); EMRSETDIBITSTODEVICE *emr; BOOL ret; UINT bmi_size, img_size, payload_size, emr_size; @@ -1916,6 +1988,8 @@ BOOL EMFDC_SetDIBitsToDevice( DC_ATTR *dc_attr, INT x_dst, INT y_dst, DWORD widt BITMAPINFOHEADER bih; BITMAPINFO *bi;
+ if (emf->document_state == NEEDS_START_PAGE) StartPage( dc_attr_handle(dc_attr) ); + /* calculate the size of the colour table and the image */ if (!emf_parse_user_bitmapinfo( &bih, &info->bmiHeader, usage, TRUE, &bmi_size, &img_size )) return 0; @@ -1977,8 +2051,8 @@ BOOL EMFDC_SetDIBitsToDevice( DC_ATTR *dc_attr, INT x_dst, INT y_dst, DWORD widt emr->iStartScan = startscan; emr->cScans = lines;
- if ((ret = emfdc_record( get_dc_emf( dc_attr ), (EMR*)emr ))) - emfdc_update_bounds( get_dc_emf( dc_attr ), &emr->rclBounds ); + if ((ret = emfdc_record( emf, (EMR*)emr ))) + emfdc_update_bounds( emf, &emr->rclBounds );
HeapFree( GetProcessHeap(), 0, emr ); return ret;