static GF_Err gdip_surface_clear(GF_SURFACE _this, GF_IRect *rc, u32 color) { GpPath *path; GPGRAPH(); GdipCreatePath(FillModeAlternate, &path); if (rc) { /*luckily enough this maps well for both flipped and unflipped coords*/ GdipAddPathRectangleI(path, rc->x, rc->y - rc->height, rc->width, rc->height); } else { /* if (_graph->center_coords) { GdipAddPathRectangleI(path, -1 * (s32)_graph->w / 2, -1 * (s32)_graph->h / 2, _graph->w, _graph->h); } else { */ GdipAddPathRectangleI(path, 0, 0, _graph->w, _graph->h); // } } /*we MUST use clear otherwise ARGB surfaces are not cleared correctly*/ GdipSetClipPath(_graph->graph, path, CombineModeReplace); GdipGraphicsClear(_graph->graph, color); GdipDeletePath(path); return GF_OK; }
GpStatus WINGDIPAPI GdipPlayMetafileRecord(GDIPCONST GpMetafile *metafile, EmfPlusRecordType recordType, UINT flags, UINT dataSize, GDIPCONST BYTE *data) { GpStatus stat; GpMetafile *real_metafile = (GpMetafile*)metafile; TRACE("(%p,%x,%x,%d,%p)\n", metafile, recordType, flags, dataSize, data); if (!metafile || (dataSize && !data) || !metafile->playback_graphics) return InvalidParameter; if (recordType >= 1 && recordType <= 0x7a) { /* regular EMF record */ if (metafile->playback_dc) { ENHMETARECORD *record; record = heap_alloc_zero(dataSize + 8); if (record) { record->iType = recordType; record->nSize = dataSize + 8; memcpy(record->dParm, data, dataSize); PlayEnhMetaFileRecord(metafile->playback_dc, metafile->handle_table, record, metafile->handle_count); heap_free(record); } else return OutOfMemory; } } else { EmfPlusRecordHeader *header = (EmfPlusRecordHeader*)(data)-1; METAFILE_PlaybackReleaseDC((GpMetafile*)metafile); switch(recordType) { case EmfPlusRecordTypeHeader: case EmfPlusRecordTypeEndOfFile: break; case EmfPlusRecordTypeGetDC: METAFILE_PlaybackGetDC((GpMetafile*)metafile); break; case EmfPlusRecordTypeClear: { EmfPlusClear *record = (EmfPlusClear*)header; return GdipGraphicsClear(metafile->playback_graphics, record->Color); } case EmfPlusRecordTypeFillRects: { EmfPlusFillRects *record = (EmfPlusFillRects*)header; GpBrush *brush, *temp_brush=NULL; GpRectF *rects, *temp_rects=NULL; if (dataSize + sizeof(EmfPlusRecordHeader) < sizeof(EmfPlusFillRects)) return InvalidParameter; if (flags & 0x4000) { if (dataSize + sizeof(EmfPlusRecordHeader) < sizeof(EmfPlusFillRects) + sizeof(EmfPlusRect) * record->Count) return InvalidParameter; } else { if (dataSize + sizeof(EmfPlusRecordHeader) < sizeof(EmfPlusFillRects) + sizeof(GpRectF) * record->Count) return InvalidParameter; } if (flags & 0x8000) { stat = GdipCreateSolidFill((ARGB)record->BrushID, (GpSolidFill**)&temp_brush); brush = temp_brush; } else { FIXME("brush deserialization not implemented\n"); return NotImplemented; } if (stat == Ok) { if (flags & 0x4000) { EmfPlusRect *int_rects = (EmfPlusRect*)(record+1); int i; rects = temp_rects = heap_alloc_zero(sizeof(GpRectF) * record->Count); if (rects) { for (i=0; i<record->Count; i++) { rects[i].X = int_rects[i].X; rects[i].Y = int_rects[i].Y; rects[i].Width = int_rects[i].Width; rects[i].Height = int_rects[i].Height; } } else stat = OutOfMemory; } else rects = (GpRectF*)(record+1); } if (stat == Ok) { stat = GdipFillRectangles(metafile->playback_graphics, brush, rects, record->Count); } GdipDeleteBrush(temp_brush); heap_free(temp_rects); return stat; } case EmfPlusRecordTypeSetPageTransform: { EmfPlusSetPageTransform *record = (EmfPlusSetPageTransform*)header; GpUnit unit = (GpUnit)flags; if (dataSize + sizeof(EmfPlusRecordHeader) < sizeof(EmfPlusSetPageTransform)) return InvalidParameter; real_metafile->page_unit = unit; real_metafile->page_scale = record->PageScale; return METAFILE_PlaybackUpdateWorldTransform(real_metafile); } default: FIXME("Not implemented for record type %x\n", recordType); return NotImplemented; } } return Ok; }