/********************************************************************** * EMFDRV_PolyDraw */ BOOL EMFDRV_PolyDraw( PHYSDEV dev, const POINT *pts, const BYTE *types, DWORD count ) { EMFDRV_PDEVICE *physDev = get_emf_physdev( dev ); EMRPOLYDRAW *emr; BOOL ret; BYTE *types_dest; BOOL use_small_emr = can_use_short_points( pts, count ); DWORD size; size = use_small_emr ? offsetof( EMRPOLYDRAW16, apts[count] ) : offsetof( EMRPOLYDRAW, aptl[count] ); size += (count + 3) & ~3; if (!(emr = HeapAlloc( GetProcessHeap(), 0, size ))) return FALSE; emr->emr.iType = use_small_emr ? EMR_POLYDRAW16 : EMR_POLYDRAW; emr->emr.nSize = size; emr->cptl = count; types_dest = store_points( emr->aptl, pts, count, use_small_emr ); memcpy( types_dest, types, count ); if (count & 3) memset( types_dest + count, 0, 4 - (count & 3) ); if (!physDev->path) get_points_bounds( &emr->rclBounds, pts, count, 0 ); else emr->rclBounds = empty_bounds; ret = EMFDRV_WriteRecord( dev, &emr->emr ); if (ret && !physDev->path) EMFDRV_UpdateBBox( dev, &emr->rclBounds ); HeapFree( GetProcessHeap(), 0, emr ); return ret; }
/********************************************************************** * EMFDRV_Polylinegon * * Helper for EMFDRV_Poly{line|gon} */ static BOOL EMFDRV_Polylinegon( PHYSDEV dev, const POINT* pt, INT count, DWORD iType ) { EMFDRV_PDEVICE *physDev = get_emf_physdev( dev ); DC *dc = get_physdev_dc( dev ); EMRPOLYLINE *emr; DWORD size; BOOL ret, use_small_emr = can_use_short_points( pt, count ); size = use_small_emr ? offsetof( EMRPOLYLINE16, apts[count] ) : offsetof( EMRPOLYLINE, aptl[count] ); emr = HeapAlloc( GetProcessHeap(), 0, size ); emr->emr.iType = use_small_emr ? iType + EMR_POLYLINE16 - EMR_POLYLINE : iType; emr->emr.nSize = size; emr->cptl = count; store_points( emr->aptl, pt, count, use_small_emr ); if (!physDev->path) get_points_bounds( &emr->rclBounds, pt, count, (iType == EMR_POLYBEZIERTO || iType == EMR_POLYLINETO) ? dc : 0 ); else emr->rclBounds = empty_bounds; ret = EMFDRV_WriteRecord( dev, &emr->emr ); if (ret && !physDev->path) EMFDRV_UpdateBBox( dev, &emr->rclBounds ); HeapFree( GetProcessHeap(), 0, emr ); return ret; }
/********************************************************************** * EMFDRV_PolyPolylinegon * * Helper for EMFDRV_PolyPoly{line|gon} */ static BOOL EMFDRV_PolyPolylinegon( PHYSDEV dev, const POINT* pt, const INT* counts, UINT polys, DWORD iType) { EMFDRV_PDEVICE *physDev = get_emf_physdev( dev ); EMRPOLYPOLYLINE *emr; DWORD cptl = 0, poly, size; BOOL ret, use_small_emr, bounds_valid = TRUE; for(poly = 0; poly < polys; poly++) { cptl += counts[poly]; if(counts[poly] < 2) bounds_valid = FALSE; } if(!cptl) bounds_valid = FALSE; use_small_emr = can_use_short_points( pt, cptl ); size = FIELD_OFFSET(EMRPOLYPOLYLINE, aPolyCounts[polys]); if(use_small_emr) size += cptl * sizeof(POINTS); else size += cptl * sizeof(POINTL); emr = HeapAlloc( GetProcessHeap(), 0, size ); emr->emr.iType = iType; if(use_small_emr) emr->emr.iType += EMR_POLYPOLYLINE16 - EMR_POLYPOLYLINE; emr->emr.nSize = size; if(bounds_valid && !physDev->path) get_points_bounds( &emr->rclBounds, pt, cptl, 0 ); else emr->rclBounds = empty_bounds; emr->nPolys = polys; emr->cptl = cptl; if(polys) { memcpy( emr->aPolyCounts, counts, polys * sizeof(DWORD) ); store_points( (POINTL *)(emr->aPolyCounts + polys), pt, cptl, use_small_emr ); } ret = EMFDRV_WriteRecord( dev, &emr->emr ); if(ret && !bounds_valid) { ret = FALSE; SetLastError( ERROR_INVALID_PARAMETER ); } if(ret && !physDev->path) EMFDRV_UpdateBBox( dev, &emr->rclBounds ); HeapFree( GetProcessHeap(), 0, emr ); return ret; }
/* helper for path stroke and fill functions */ static BOOL emfdrv_stroke_and_fill_path( PHYSDEV dev, INT type ) { EMRSTROKEANDFILLPATH emr; struct gdi_path *path; POINT *points; BYTE *flags; emr.emr.iType = type; emr.emr.nSize = sizeof(emr); if ((path = get_gdi_flat_path( dev->hdc, NULL ))) { int count = get_gdi_path_data( path, &points, &flags ); get_points_bounds( &emr.rclBounds, points, count, 0 ); free_gdi_path( path ); } else emr.rclBounds = empty_bounds; if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE; if (!path) return FALSE; EMFDRV_UpdateBBox( dev, &emr.rclBounds ); return TRUE; }