ReactOS 0.4.17-dev-218-g5635d24
metafile.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2011 Vincent Povirk for CodeWeavers
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
19#include <stdarg.h>
20#include <math.h>
21#include <assert.h>
22
23#include "windef.h"
24#include "winbase.h"
25#include "wingdi.h"
26
27#define COBJMACROS
28#include "objbase.h"
29#include "ocidl.h"
30#include "olectl.h"
31#include "ole2.h"
32
33#include "winreg.h"
34#include "shlwapi.h"
35
36#include "gdiplus.h"
37#include "gdiplus_private.h"
38#include "wine/debug.h"
39#include "wine/list.h"
40
42
44
46
47typedef struct EmfPlusPointF
48{
49 float X;
50 float Y;
52
53typedef struct EmfPlusRecordHeader
54{
60
61typedef struct EmfPlusHeader
62{
69
70typedef struct EmfPlusClear
71{
75
76typedef struct EmfPlusFillRects
77{
82
83typedef struct EmfPlusSetClipRect
84{
88
90{
94
95typedef struct EmfPlusRect
96{
102
104{
108
110{
115
117{
121
123{
127
129{
134
136{
142
144{
148
150{
154
155typedef struct container
156{
157 struct list entry;
166
168{
172 PenDataJoin = 0x0008,
181 PenDataCustomEndCap = 0x1000
183
185{
188};
189
191{
194
196{
204
206{
210
212{
216
218{
222
224{
228
229typedef struct EmfPlusPenData
230{
236
238{
247};
248
250{
253
255{
260
262{
267
268typedef struct EmfPlusRectF
269{
270 float X;
271 float Y;
272 float Width;
273 float Height;
275
277{
287
288typedef struct EmfPlusBrush
289{
292 union {
299
301{
314
315typedef struct EmfPlusPath
316{
320 /* PathPoints[] */
321 /* PathPointTypes[] */
322 /* AlignmentPadding */
325
327{
329 /* EmfPlusPath */
332
334{
336 /* EmfPlusPath */
339
341{
352 /* EmfPlusCustomLineCapDataFillPath */
353 /* EmfPlusCustomLineCapDataLinePath */
356
358{
361 /* EmfPlusCustomLineCapArrowData */
362 /* EmfPlusCustomLineCapData */
365
366typedef struct EmfPlusPen
367{
370 /* EmfPlusPenData */
371 /* EmfPlusBrush */
374
376{
380
381typedef struct EmfPlusRegion
382{
387
388typedef struct EmfPlusPalette
389{
394
395typedef enum
396{
400
401typedef struct EmfPlusBitmap
402{
410
411typedef struct EmfPlusMetafile
412{
417
418typedef enum ImageDataType
419{
424
425typedef struct EmfPlusImage
426{
429 union
430 {
435
437{
445
446typedef struct EmfPlusFont
447{
449 float EmSize;
456
457typedef struct EmfPlusObject
458{
460 union
461 {
471
472typedef struct EmfPlusPointR7
473{
477
478typedef struct EmfPlusPoint
479{
480 short X;
481 short Y;
483
484typedef struct EmfPlusDrawImage
485{
490 union
491 {
496
498{
504 union
505 {
511
512typedef struct EmfPlusDrawPath
513{
517
518typedef struct EmfPlusDrawArc
519{
523 union
524 {
529
530typedef struct EmfPlusDrawEllipse
531{
533 union
534 {
539
540typedef struct EmfPlusDrawPie
541{
545 union
546 {
551
552typedef struct EmfPlusDrawRects
553{
556 union
557 {
562
563typedef struct EmfPlusFillPath
564{
566 union
567 {
572
574{
577 float Tension;
579 union
580 {
586
587typedef struct EmfPlusFillEllipse
588{
591 union
592 {
597
598typedef struct EmfPlusFillPie
599{
604 union
605 {
610
612{
614 union
615 {
624
625typedef struct EmfPlusFillRegion
626{
628 union
629 {
634
635typedef struct EmfPlusOffsetClip
636{
638 float dx;
639 float dy;
641
643{
648
650{
651 struct emfplus_object *object = &metafile->objtable[id];
652
653 switch (object->type)
654 {
656 break;
657 case ObjectTypeBrush:
658 GdipDeleteBrush(object->u.brush);
659 break;
660 case ObjectTypePen:
661 GdipDeletePen(object->u.pen);
662 break;
663 case ObjectTypePath:
664 GdipDeletePath(object->u.path);
665 break;
666 case ObjectTypeRegion:
667 GdipDeleteRegion(object->u.region);
668 break;
669 case ObjectTypeImage:
670 GdipDisposeImage(object->u.image);
671 break;
672 case ObjectTypeFont:
673 GdipDeleteFont(object->u.font);
674 break;
676 GdipDisposeImageAttributes(object->u.image_attributes);
677 break;
678 default:
679 FIXME("not implemented for object type %u.\n", object->type);
680 return;
681 }
682
683 object->type = ObjectTypeInvalid;
684 object->u.object = NULL;
685}
686
688{
689 unsigned int i;
690
691 free(metafile->comment_data);
693 if (!metafile->preserve_hemf)
695 if (metafile->record_graphics)
696 {
697 WARN("metafile closed while recording\n");
698 /* not sure what to do here; for now just prevent the graphics from functioning or using this object */
699 metafile->record_graphics->image = NULL;
700 metafile->record_graphics->busy = TRUE;
701 }
702
703 if (metafile->record_stream)
704 IStream_Release(metafile->record_stream);
705
706 for (i = 0; i < ARRAY_SIZE(metafile->objtable); i++)
708}
709
711{
712 return (metafile->next_object_id++) % EmfPlusObjectTableSize;
713}
714
716 DWORD size, void **result)
717{
718 DWORD size_needed;
720
721 if (!metafile->comment_data_size)
722 {
723 DWORD data_size = max(256, size * 2 + 4);
724 metafile->comment_data = calloc(1, data_size);
725
726 if (!metafile->comment_data)
727 return OutOfMemory;
728
729 memcpy(metafile->comment_data, "EMF+", 4);
730
731 metafile->comment_data_size = data_size;
732 metafile->comment_data_length = 4;
733 }
734
735 size_needed = size + metafile->comment_data_length;
736
737 if (size_needed > metafile->comment_data_size)
738 {
739 DWORD data_size = size_needed * 2;
740 BYTE *new_data = calloc(1, data_size);
741
742 if (!new_data)
743 return OutOfMemory;
744
745 memcpy(new_data, metafile->comment_data, metafile->comment_data_length);
746
747 metafile->comment_data_size = data_size;
748 free(metafile->comment_data);
749 metafile->comment_data = new_data;
750 }
751
752 *result = metafile->comment_data + metafile->comment_data_length;
753 metafile->comment_data_length += size;
754
756 record->Type = record_type;
757 record->Flags = 0;
758 record->Size = size;
759 record->DataSize = size - sizeof(EmfPlusRecordHeader);
760
761 return Ok;
762}
763
765{
766 assert(metafile->comment_data + metafile->comment_data_length == (BYTE*)record + record->Size);
767 metafile->comment_data_length -= record->Size;
768}
769
771{
772 if (metafile->comment_data_length > 4)
773 {
774 GdiComment(metafile->record_dc, metafile->comment_data_length, metafile->comment_data);
775 metafile->comment_data_length = 4;
776 }
777}
778
780{
782
783 if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
784 {
786
788 if (stat != Ok)
789 return stat;
790
791 if (metafile->metafile_type == MetafileTypeEmfPlusDual)
792 header->Header.Flags = 1;
793
794 header->Version = VERSION_MAGIC2;
795
797 header->EmfPlusFlags = 1;
798 else
799 header->EmfPlusFlags = 0;
800
801 header->LogicalDpiX = GetDeviceCaps(hdc, LOGPIXELSX);
802 header->LogicalDpiY = GetDeviceCaps(hdc, LOGPIXELSY);
803
805 }
806
807 return Ok;
808}
809
811{
813
814 if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
815 {
817
819 if (stat != Ok)
820 return stat;
821
823 }
824
825 return Ok;
826}
827
830{
831
832 TRACE("(%p %d %s %d %p %p)\n", hdc, type, debugstr_rectf(frameRect), frameUnit, desc, metafile);
833
834 return GdipRecordMetafileFileName(NULL, hdc, type, frameRect, frameUnit, desc, metafile);
835}
836
837/*****************************************************************************
838 * GdipRecordMetafileI [GDIPLUS.@]
839 */
842{
843 GpRectF frameRectF, *pFrameRectF;
844
845 TRACE("(%p %d %p %d %p %p)\n", hdc, type, frameRect, frameUnit, desc, metafile);
846
847 if (frameRect)
848 {
849 set_rect(&frameRectF, frameRect->X, frameRect->Y, frameRect->Width, frameRect->Height);
850 pFrameRectF = &frameRectF;
851 }
852 else
853 pFrameRectF = NULL;
854
855 return GdipRecordMetafile(hdc, type, pFrameRectF, frameUnit, desc, metafile);
856}
857
860{
861 GpRectF frameRectF, *pFrameRectF;
862
863 TRACE("(%p %p %d %p %d %p %p)\n", stream, hdc, type, frameRect, frameUnit, desc, metafile);
864
865 if (frameRect)
866 {
867 set_rect(&frameRectF, frameRect->X, frameRect->Y, frameRect->Width, frameRect->Height);
868 pFrameRectF = &frameRectF;
869 }
870 else
871 pFrameRectF = NULL;
872
873 return GdipRecordMetafileStream(stream, hdc, type, pFrameRectF, frameUnit, desc, metafile);
874}
875
878{
880
881 TRACE("(%p %p %d %s %d %p %p)\n", stream, hdc, type, debugstr_rectf(frameRect), frameUnit, desc, metafile);
882
883 if (!stream)
884 return InvalidParameter;
885
886 stat = GdipRecordMetafile(hdc, type, frameRect, frameUnit, desc, metafile);
887
888 if (stat == Ok)
889 {
890 (*metafile)->record_stream = stream;
891 IStream_AddRef(stream);
892 }
893
894 return stat;
895}
896
898 UINT num_points)
899{
900 int i;
901
902 if (!metafile->auto_frame || !num_points)
903 return;
904
905 if (metafile->auto_frame_max.X < metafile->auto_frame_min.X)
906 metafile->auto_frame_max = metafile->auto_frame_min = points[0];
907
908 for (i=0; i<num_points; i++)
909 {
910 if (points[i].X < metafile->auto_frame_min.X)
911 metafile->auto_frame_min.X = points[i].X;
912 if (points[i].X > metafile->auto_frame_max.X)
913 metafile->auto_frame_max.X = points[i].X;
914 if (points[i].Y < metafile->auto_frame_min.Y)
915 metafile->auto_frame_min.Y = points[i].Y;
916 if (points[i].Y > metafile->auto_frame_max.Y)
917 metafile->auto_frame_max.Y = points[i].Y;
918 }
919}
920
922{
924
925 if (!metafile->record_dc || metafile->record_graphics)
926 return InvalidParameter;
927
928 stat = graphics_from_image((GpImage*)metafile, &metafile->record_graphics);
929
930 if (stat == Ok)
931 {
932 *result = metafile->record_graphics;
933 metafile->record_graphics->xres = metafile->logical_dpix;
934 metafile->record_graphics->yres = metafile->logical_dpiy;
935 metafile->record_graphics->printer_display = metafile->printer_display;
936 }
937
938 return stat;
939}
940
942{
943 if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
944 {
947
949 if (stat != Ok)
950 return stat;
951
953 }
954
955 *hdc = metafile->record_dc;
956
957 return Ok;
958}
959
961{
962 if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
963 {
966
968 if (stat != Ok)
969 return stat;
970
971 record->Color = color;
972
974 }
975
976 return Ok;
977}
978
980{
981 SHORT x, y, width, height;
982 x = rect->X;
983 y = rect->Y;
984 width = rect->Width;
985 height = rect->Height;
986 if (rect->X != (REAL)x || rect->Y != (REAL)y ||
987 rect->Width != (REAL)width || rect->Height != (REAL)height)
988 return FALSE;
989 return TRUE;
990}
991
993{
994 switch (brush->bt)
995 {
997 *size = FIELD_OFFSET(EmfPlusBrush, BrushData) + sizeof(EmfPlusSolidBrushData);
998 break;
1000 *size = FIELD_OFFSET(EmfPlusBrush, BrushData) + sizeof(EmfPlusHatchBrushData);
1001 break;
1003 {
1004 BOOL ignore_xform;
1005 GpLineGradient *gradient = (GpLineGradient*)brush;
1006
1008
1009 GdipIsMatrixIdentity(&gradient->transform, &ignore_xform);
1010 if (!ignore_xform)
1011 *size += sizeof(gradient->transform);
1012
1013 if (gradient->pblendcount > 1 && gradient->pblendcolor && gradient->pblendpos)
1014 *size += sizeof(DWORD) + gradient->pblendcount *
1015 (sizeof(*gradient->pblendcolor) + sizeof(*gradient->pblendpos));
1016 else if (gradient->blendcount > 1 && gradient->blendfac && gradient->blendpos)
1017 *size += sizeof(DWORD) + gradient->blendcount *
1018 (sizeof(*gradient->blendfac) + sizeof(*gradient->blendpos));
1019
1020 break;
1021 }
1022 default:
1023 FIXME("unsupported brush type: %d\n", brush->bt);
1024 return NotImplemented;
1025 }
1026
1027 return Ok;
1028}
1029
1031{
1032 data->Version = VERSION_MAGIC2;
1033 data->Type = brush->bt;
1034
1035 switch (brush->bt)
1036 {
1038 {
1039 GpSolidFill *solid = (GpSolidFill *)brush;
1040 data->BrushData.solid.SolidColor = solid->color;
1041 break;
1042 }
1043 case BrushTypeHatchFill:
1044 {
1045 GpHatch *hatch = (GpHatch *)brush;
1046 data->BrushData.hatch.HatchStyle = hatch->hatchstyle;
1047 data->BrushData.hatch.ForeColor = hatch->forecol;
1048 data->BrushData.hatch.BackColor = hatch->backcol;
1049 break;
1050 }
1052 {
1053 BYTE *cursor;
1054 BOOL ignore_xform;
1055 GpLineGradient *gradient = (GpLineGradient*)brush;
1056
1057 data->BrushData.lineargradient.BrushDataFlags = 0;
1058 data->BrushData.lineargradient.WrapMode = gradient->wrap;
1059 data->BrushData.lineargradient.RectF.X = gradient->rect.X;
1060 data->BrushData.lineargradient.RectF.Y = gradient->rect.Y;
1061 data->BrushData.lineargradient.RectF.Width = gradient->rect.Width;
1062 data->BrushData.lineargradient.RectF.Height = gradient->rect.Height;
1063 data->BrushData.lineargradient.StartColor = gradient->startcolor;
1064 data->BrushData.lineargradient.EndColor = gradient->endcolor;
1065 data->BrushData.lineargradient.Reserved1 = gradient->startcolor;
1066 data->BrushData.lineargradient.Reserved2 = gradient->endcolor;
1067
1068 if (gradient->gamma)
1069 data->BrushData.lineargradient.BrushDataFlags |= BrushDataIsGammaCorrected;
1070
1071 cursor = &data->BrushData.lineargradient.OptionalData[0];
1072
1073 GdipIsMatrixIdentity(&gradient->transform, &ignore_xform);
1074 if (!ignore_xform)
1075 {
1076 data->BrushData.lineargradient.BrushDataFlags |= BrushDataTransform;
1077 memcpy(cursor, &gradient->transform, sizeof(gradient->transform));
1078 cursor += sizeof(gradient->transform);
1079 }
1080
1081 if (gradient->pblendcount > 1 && gradient->pblendcolor && gradient->pblendpos)
1082 {
1083 const DWORD count = gradient->pblendcount;
1084
1085 data->BrushData.lineargradient.BrushDataFlags |= BrushDataPresetColors;
1086
1087 memcpy(cursor, &count, sizeof(count));
1088 cursor += sizeof(count);
1089
1090 memcpy(cursor, gradient->pblendpos, count * sizeof(*gradient->pblendpos));
1091 cursor += count * sizeof(*gradient->pblendpos);
1092
1093 memcpy(cursor, gradient->pblendcolor, count * sizeof(*gradient->pblendcolor));
1094 }
1095 else if (gradient->blendcount > 1 && gradient->blendfac && gradient->blendpos)
1096 {
1097 const DWORD count = gradient->blendcount;
1098
1099 data->BrushData.lineargradient.BrushDataFlags |= BrushDataBlendFactorsH;
1100
1101 memcpy(cursor, &count, sizeof(count));
1102 cursor += sizeof(count);
1103
1104 memcpy(cursor, gradient->blendpos, count * sizeof(*gradient->blendpos));
1105 cursor += count * sizeof(*gradient->blendpos);
1106
1107 memcpy(cursor, gradient->blendfac, count * sizeof(*gradient->blendfac));
1108 }
1109
1110 break;
1111 }
1112 default:
1113 FIXME("unsupported brush type: %d\n", brush->bt);
1114 }
1115}
1116
1118 DWORD *ret_cap_data_size, DWORD *ret_path_size)
1119{
1120 DWORD cap_size, path_size = 0;
1121
1122 /* EmfPlusCustomStartCapData */
1124 /* -> EmfPlusCustomLineCap */
1126 /* -> EmfPlusCustomLineCapArrowData */
1128 cap_size += sizeof(EmfPlusCustomLineCapArrowData);
1129 /* -> EmfPlusCustomLineCapData */
1130 else
1131 {
1132 /* -> EmfPlusCustomLineCapOptionalData */
1133 cap_size += FIELD_OFFSET(EmfPlusCustomLineCapData, OptionalData);
1134 if (cap->fill)
1135 /* -> EmfPlusCustomLineCapDataFillPath */
1137 else
1138 /* -> EmfPlusCustomLineCapDataLinePath */
1139 cap_size += FIELD_OFFSET(EmfPlusCustomLineCapDataLinePath, LinePath);
1140
1141 /* -> EmfPlusPath in EmfPlusCustomLineCapDataFillPath and EmfPlusCustomLineCapDataLinePath */
1142 path_size = FIELD_OFFSET(EmfPlusPath, data);
1143 path_size += sizeof(PointF) * cap->pathdata.Count;
1144 path_size += sizeof(BYTE) * cap->pathdata.Count;
1145 path_size = (path_size + 3) & ~3;
1146
1147 cap_size += path_size;
1148 }
1149
1150 *ret_cap_size = cap_size;
1151 *ret_cap_data_size = cap_size - FIELD_OFFSET(EmfPlusCustomStartCapData, data);
1152 *ret_path_size = path_size;
1153}
1154
1156 REAL line_miter_limit, DWORD data_size, DWORD path_size)
1157{
1158 EmfPlusCustomStartCapData *cap_data;
1159 EmfPlusCustomLineCap *line_cap;
1160 DWORD i;
1161
1162 cap_data = (EmfPlusCustomStartCapData *)ptr;
1163 cap_data->CustomStartCapSize = data_size;
1165
1166 line_cap = (EmfPlusCustomLineCap *)(ptr + i);
1167 line_cap->Version = VERSION_MAGIC2;
1168 line_cap->Type = cap->type;
1170
1172 {
1174 GpAdjustableArrowCap *arrow_cap;
1175
1176 arrow_data = (EmfPlusCustomLineCapArrowData *)(ptr + i);
1177 arrow_cap = (GpAdjustableArrowCap *)cap;
1178 arrow_data->Width = arrow_cap->width;
1179 arrow_data->Height = arrow_cap->height;
1180 arrow_data->MiddleInset = arrow_cap->middle_inset;
1181 arrow_data->FillState = arrow_cap->cap.fill;
1182 arrow_data->LineStartCap = arrow_cap->cap.strokeStartCap;
1183 arrow_data->LineEndCap = arrow_cap->cap.strokeEndCap;
1184 arrow_data->LineJoin = arrow_cap->cap.join;
1185 arrow_data->LineMiterLimit = line_miter_limit;
1186 arrow_data->WidthScale = arrow_cap->cap.scale;
1187 arrow_data->FillHotSpot.X = 0;
1188 arrow_data->FillHotSpot.Y = 0;
1189 arrow_data->LineHotSpot.X = 0;
1190 arrow_data->LineHotSpot.Y = 0;
1191 }
1192 else
1193 {
1196
1197 if (cap->fill)
1199 else
1201 line_cap_data->BaseCap = cap->basecap;
1202 line_cap_data->BaseInset = cap->inset;
1203 line_cap_data->StrokeStartCap = cap->strokeStartCap;
1204 line_cap_data->StrokeEndCap = cap->strokeEndCap;
1205 line_cap_data->StrokeJoin = cap->join;
1206 line_cap_data->StrokeMiterLimit = line_miter_limit;
1207 line_cap_data->WidthScale = cap->scale;
1208 line_cap_data->FillHotSpot.X = 0;
1209 line_cap_data->FillHotSpot.Y = 0;
1210 line_cap_data->LineHotSpot.X = 0;
1211 line_cap_data->LineHotSpot.Y = 0;
1212 i += FIELD_OFFSET(EmfPlusCustomLineCapData, OptionalData);
1213
1214 if (cap->fill)
1215 {
1217 fill_path->FillPathLength = path_size;
1219 }
1220 else
1221 {
1223 line_path->LinePathLength = path_size;
1225 }
1226
1227 path = (EmfPlusPath *)(ptr + i);
1228 path->Version = VERSION_MAGIC2;
1229 path->PathPointCount = cap->pathdata.Count;
1230 path->PathPointFlags = 0;
1232 memcpy(ptr + i, cap->pathdata.Points, cap->pathdata.Count * sizeof(PointF));
1233 i += cap->pathdata.Count * sizeof(PointF);
1234 memcpy(ptr + i, cap->pathdata.Types, cap->pathdata.Count * sizeof(BYTE));
1235 }
1236}
1237
1239{
1240 EmfPlusObject *object_record;
1241 GpStatus stat;
1242 DWORD size;
1243
1244 *id = -1;
1245 if (metafile->metafile_type != MetafileTypeEmfPlusOnly && metafile->metafile_type != MetafileTypeEmfPlusDual)
1246 return Ok;
1247
1249 if (stat != Ok) return stat;
1250
1252 FIELD_OFFSET(EmfPlusObject, ObjectData) + size, (void**)&object_record);
1253 if (stat != Ok) return stat;
1254
1256 object_record->Header.Flags = *id | ObjectTypeBrush << 8;
1257 METAFILE_FillBrushData(brush, &object_record->ObjectData.brush);
1258 return Ok;
1259}
1260
1262 GDIPCONST GpRectF* rects, INT count)
1263{
1264 if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
1265 {
1267 GpStatus stat;
1268 BOOL integer_rects = TRUE;
1269 int i;
1270 DWORD brushid;
1271 int flags = 0;
1272
1274 {
1275 flags |= 0x8000;
1276 brushid = ((GpSolidFill*)brush)->color;
1277 }
1278 else
1279 {
1281 if (stat != Ok)
1282 return stat;
1283 }
1284
1285 for (i=0; i<count; i++)
1286 {
1287 if (!is_integer_rect(&rects[i]))
1288 {
1289 integer_rects = FALSE;
1290 break;
1291 }
1292 }
1293
1294 if (integer_rects)
1295 flags |= 0x4000;
1296
1298 sizeof(EmfPlusFillRects) + count * (integer_rects ? sizeof(EmfPlusRect) : sizeof(GpRectF)),
1299 (void**)&record);
1300 if (stat != Ok)
1301 return stat;
1302
1303 record->Header.Flags = flags;
1304 record->BrushID = brushid;
1305 record->Count = count;
1306
1307 if (integer_rects)
1308 {
1309 EmfPlusRect *record_rects = (EmfPlusRect*)(record+1);
1310 for (i=0; i<count; i++)
1311 {
1312 record_rects[i].X = (SHORT)rects[i].X;
1313 record_rects[i].Y = (SHORT)rects[i].Y;
1314 record_rects[i].Width = (SHORT)rects[i].Width;
1315 record_rects[i].Height = (SHORT)rects[i].Height;
1316 }
1317 }
1318 else
1319 memcpy(record+1, rects, sizeof(GpRectF) * count);
1320
1322 }
1323
1324 if (metafile->auto_frame)
1325 {
1326 GpPointF corners[4];
1327 int i;
1328
1329 for (i=0; i<count; i++)
1330 {
1331 corners[0].X = rects[i].X;
1332 corners[0].Y = rects[i].Y;
1333 corners[1].X = rects[i].X + rects[i].Width;
1334 corners[1].Y = rects[i].Y;
1335 corners[2].X = rects[i].X;
1336 corners[2].Y = rects[i].Y + rects[i].Height;
1337 corners[3].X = rects[i].X + rects[i].Width;
1338 corners[3].Y = rects[i].Y + rects[i].Height;
1339
1341 CoordinateSpaceWorld, corners, 4);
1342
1343 METAFILE_AdjustFrame(metafile, corners, 4);
1344 }
1345 }
1346
1347 return Ok;
1348}
1349
1351{
1352 if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
1353 {
1355 GpStatus stat;
1356
1358 sizeof(EmfPlusSetClipRect), (void **)&record);
1359 if (stat != Ok)
1360 return stat;
1361
1362 record->Header.Flags = (mode & 0xf) << 8;
1363 record->ClipRect.X = x;
1364 record->ClipRect.Y = y;
1365 record->ClipRect.Width = width;
1366 record->ClipRect.Height = height;
1367
1369 }
1370
1371 return Ok;
1372}
1373
1375{
1376 EmfPlusObject *object_record;
1377 DWORD size;
1378 GpStatus stat;
1379
1380 *id = -1;
1381 if (metafile->metafile_type != MetafileTypeEmfPlusOnly && metafile->metafile_type != MetafileTypeEmfPlusDual)
1382 return Ok;
1383
1386 FIELD_OFFSET(EmfPlusObject, ObjectData.region) + size, (void**)&object_record);
1387 if (stat != Ok) return stat;
1388
1390 object_record->Header.Flags = *id | ObjectTypeRegion << 8;
1391 write_region_data(region, &object_record->ObjectData.region);
1392 return Ok;
1393}
1394
1396{
1398 DWORD region_id;
1399 GpStatus stat;
1400
1401 if (metafile->metafile_type == MetafileTypeEmf)
1402 {
1403 FIXME("stub!\n");
1404 return NotImplemented;
1405 }
1406
1408 if (stat != Ok) return stat;
1409
1411 if (stat != Ok) return stat;
1412
1413 record->Flags = region_id | mode << 8;
1414
1416 return Ok;
1417}
1418
1420{
1421 if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
1422 {
1424 GpStatus stat;
1425
1427 sizeof(EmfPlusSetPageTransform), (void **)&record);
1428 if (stat != Ok)
1429 return stat;
1430
1431 record->Header.Flags = unit;
1432 record->PageScale = scale;
1433
1435 }
1436
1437 return Ok;
1438}
1439
1441{
1442 if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
1443 {
1445 GpStatus stat;
1446
1448 sizeof(EmfPlusSetWorldTransform), (void **)&record);
1449 if (stat != Ok)
1450 return stat;
1451
1452 memcpy(record->MatrixData, transform->matrix, sizeof(record->MatrixData));
1453
1455 }
1456
1457 return Ok;
1458}
1459
1461{
1462 if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
1463 {
1465 GpStatus stat;
1466
1468 sizeof(EmfPlusScaleWorldTransform), (void **)&record);
1469 if (stat != Ok)
1470 return stat;
1471
1472 record->Header.Flags = (order == MatrixOrderAppend ? 0x2000 : 0);
1473 record->Sx = sx;
1474 record->Sy = sy;
1475
1477 }
1478
1479 return Ok;
1480}
1481
1483{
1484 if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
1485 {
1487 GpStatus stat;
1488
1490 sizeof(EmfPlusMultiplyWorldTransform), (void **)&record);
1491 if (stat != Ok)
1492 return stat;
1493
1494 record->Header.Flags = (order == MatrixOrderAppend ? 0x2000 : 0);
1495 memcpy(record->MatrixData, matrix->matrix, sizeof(record->MatrixData));
1496
1498 }
1499
1500 return Ok;
1501}
1502
1504{
1505 if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
1506 {
1508 GpStatus stat;
1509
1511 sizeof(EmfPlusRotateWorldTransform), (void **)&record);
1512 if (stat != Ok)
1513 return stat;
1514
1515 record->Header.Flags = (order == MatrixOrderAppend ? 0x2000 : 0);
1516 record->Angle = angle;
1517
1519 }
1520
1521 return Ok;
1522}
1523
1525{
1526 if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
1527 {
1529 GpStatus stat;
1530
1532 sizeof(EmfPlusTranslateWorldTransform), (void **)&record);
1533 if (stat != Ok)
1534 return stat;
1535
1536 record->Header.Flags = (order == MatrixOrderAppend ? 0x2000 : 0);
1537 record->dx = dx;
1538 record->dy = dy;
1539
1541 }
1542
1543 return Ok;
1544}
1545
1547{
1548 if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
1549 {
1551 GpStatus stat;
1552
1554 sizeof(EmfPlusRecordHeader), (void **)&record);
1555 if (stat != Ok)
1556 return stat;
1557
1559 }
1560
1561 return Ok;
1562}
1563
1565 GDIPCONST GpRectF *srcrect, GpUnit unit, DWORD StackIndex)
1566{
1567 if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
1568 {
1570 GpStatus stat;
1571
1573 if (stat != Ok)
1574 return stat;
1575
1576 record->Header.Flags = unit & 0xff;
1577 record->DestRect = *dstrect;
1578 record->SrcRect = *srcrect;
1579 record->StackIndex = StackIndex;
1580
1582 }
1583
1584 return Ok;
1585}
1586
1588{
1589 if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
1590 {
1592 GpStatus stat;
1593
1595 sizeof(EmfPlusContainerRecord), (void **)&record);
1596 if (stat != Ok)
1597 return stat;
1598
1599 record->StackIndex = StackIndex;
1600
1602 }
1603
1604 return Ok;
1605}
1606
1608{
1609 if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
1610 {
1612 GpStatus stat;
1613
1615 sizeof(EmfPlusContainerRecord), (void **)&record);
1616 if (stat != Ok)
1617 return stat;
1618
1619 record->StackIndex = StackIndex;
1620
1622 }
1623
1624 return Ok;
1625}
1626
1628{
1629 if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
1630 {
1632 GpStatus stat;
1633
1635 sizeof(EmfPlusContainerRecord), (void **)&record);
1636 if (stat != Ok)
1637 return stat;
1638
1639 record->StackIndex = StackIndex;
1640
1642 }
1643
1644 return Ok;
1645}
1646
1648{
1649 if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
1650 {
1652 GpStatus stat;
1653
1655 sizeof(EmfPlusContainerRecord), (void **)&record);
1656 if (stat != Ok)
1657 return stat;
1658
1659 record->StackIndex = StackIndex;
1660
1662 }
1663
1664 return Ok;
1665}
1666
1668{
1669 if (hdc != metafile->record_dc)
1670 return InvalidParameter;
1671
1672 return Ok;
1673}
1674
1676{
1677 GpStatus stat;
1678
1680 metafile->record_graphics = NULL;
1681
1682 metafile->hemf = CloseEnhMetaFile(metafile->record_dc);
1683 metafile->record_dc = NULL;
1684
1685 free(metafile->comment_data);
1686 metafile->comment_data = NULL;
1687 metafile->comment_data_size = 0;
1688
1689 if (stat == Ok)
1690 {
1692
1694 if (stat == Ok && metafile->auto_frame &&
1695 metafile->auto_frame_max.X >= metafile->auto_frame_min.X)
1696 {
1697 RECTL bounds_rc, gdi_bounds_rc;
1698 REAL x_scale = 2540.0 / header.DpiX;
1699 REAL y_scale = 2540.0 / header.DpiY;
1700 BYTE* buffer;
1702
1703 gdi_bounds_rc = header.EmfHeader.rclBounds;
1704 if (gdi_bounds_rc.right > gdi_bounds_rc.left &&
1705 gdi_bounds_rc.bottom > gdi_bounds_rc.top)
1706 {
1707 GpPointF *af_min = &metafile->auto_frame_min;
1708 GpPointF *af_max = &metafile->auto_frame_max;
1709
1710 af_min->X = fmin(af_min->X, gdi_bounds_rc.left);
1711 af_min->Y = fmin(af_min->Y, gdi_bounds_rc.top);
1712 af_max->X = fmax(af_max->X, gdi_bounds_rc.right);
1713 af_max->Y = fmax(af_max->Y, gdi_bounds_rc.bottom);
1714 }
1715
1716 bounds_rc.left = floorf(metafile->auto_frame_min.X * x_scale);
1717 bounds_rc.top = floorf(metafile->auto_frame_min.Y * y_scale);
1718 bounds_rc.right = ceilf(metafile->auto_frame_max.X * x_scale);
1719 bounds_rc.bottom = ceilf(metafile->auto_frame_max.Y * y_scale);
1720
1723 if (buffer)
1724 {
1725 HENHMETAFILE new_hemf;
1726
1728
1729 ((ENHMETAHEADER*)buffer)->rclFrame = bounds_rc;
1730
1732
1733 if (new_hemf)
1734 {
1736 metafile->hemf = new_hemf;
1737 }
1738 else
1739 stat = OutOfMemory;
1740
1741 free(buffer);
1742 }
1743 else
1744 stat = OutOfMemory;
1745
1746 if (stat == Ok)
1748 }
1749 if (stat == Ok)
1750 {
1751 metafile->bounds.X = header.X;
1752 metafile->bounds.Y = header.Y;
1753 metafile->bounds.Width = header.Width;
1754 metafile->bounds.Height = header.Height;
1755 }
1756 }
1757
1758 if (stat == Ok && metafile->record_stream)
1759 {
1760 BYTE *buffer;
1762
1764
1766 if (buffer)
1767 {
1768 HRESULT hr;
1769
1771
1772 hr = IStream_Write(metafile->record_stream, buffer, buffer_size, NULL);
1773
1774 if (FAILED(hr))
1776
1777 free(buffer);
1778 }
1779 else
1780 stat = OutOfMemory;
1781 }
1782
1783 if (metafile->record_stream)
1784 {
1785 IStream_Release(metafile->record_stream);
1786 metafile->record_stream = NULL;
1787 }
1788
1789 return stat;
1790}
1791
1793{
1794 TRACE("(%p,%p)\n", metafile, hEmf);
1795
1796 if (!metafile || !hEmf || !metafile->hemf)
1797 return InvalidParameter;
1798
1799 *hEmf = metafile->hemf;
1800 metafile->hemf = NULL;
1801
1802 return Ok;
1803}
1804
1806{
1807 GpStatus stat = Ok;
1808
1809 stat = GdipGetDC(metafile->playback_graphics, &metafile->playback_dc);
1810
1811 return stat;
1812}
1813
1815{
1816 if (metafile->playback_dc)
1817 {
1818 GdipReleaseDC(metafile->playback_graphics, metafile->playback_dc);
1819 metafile->playback_dc = NULL;
1820 }
1821}
1822
1824{
1825 GpStatus stat;
1826 stat = GdipCombineRegionRegion(metafile->playback_graphics->clip, metafile->base_clip, CombineModeReplace);
1827 if (stat == Ok)
1828 stat = GdipCombineRegionRegion(metafile->playback_graphics->clip, metafile->clip, CombineModeIntersect);
1829 return stat;
1830}
1831
1833{
1834 GpMatrix *real_transform;
1835 GpStatus stat;
1836
1837 stat = GdipCreateMatrix3(&metafile->src_rect, metafile->playback_points, &real_transform);
1838
1839 if (stat == Ok)
1840 {
1841 REAL scale_x = units_to_pixels(1.0, metafile->page_unit, metafile->logical_dpix, metafile->printer_display);
1842 REAL scale_y = units_to_pixels(1.0, metafile->page_unit, metafile->logical_dpiy, metafile->printer_display);
1843
1844 if (metafile->page_unit != UnitDisplay)
1845 {
1846 scale_x *= metafile->page_scale;
1847 scale_y *= metafile->page_scale;
1848 }
1849
1850 stat = GdipScaleMatrix(real_transform, scale_x, scale_y, MatrixOrderPrepend);
1851
1852 if (stat == Ok)
1853 stat = GdipMultiplyMatrix(real_transform, metafile->world_transform, MatrixOrderPrepend);
1854
1855 if (stat == Ok)
1856 stat = GdipSetWorldTransform(metafile->playback_graphics, real_transform);
1857
1858 GdipDeleteMatrix(real_transform);
1859 }
1860
1861 return stat;
1862}
1863
1865{
1867 metafile->objtable[id].type = type;
1868 metafile->objtable[id].u.object = object;
1869}
1870
1871static GpStatus metafile_deserialize_image(const BYTE *record_data, UINT data_size, GpImage **image)
1872{
1873 EmfPlusImage *data = (EmfPlusImage *)record_data;
1875
1876 *image = NULL;
1877
1878 if (data_size < FIELD_OFFSET(EmfPlusImage, ImageData))
1879 return InvalidParameter;
1880 data_size -= FIELD_OFFSET(EmfPlusImage, ImageData);
1881
1882 switch (data->Type)
1883 {
1885 {
1886 EmfPlusBitmap *bitmapdata = &data->ImageData.bitmap;
1887
1888 if (data_size <= FIELD_OFFSET(EmfPlusBitmap, BitmapData))
1889 return InvalidParameter;
1890 data_size -= FIELD_OFFSET(EmfPlusBitmap, BitmapData);
1891
1892 switch (bitmapdata->Type)
1893 {
1895 {
1897 BYTE *scan0;
1898
1899 if (bitmapdata->PixelFormat & PixelFormatIndexed)
1900 {
1901 EmfPlusPalette *palette_obj = (EmfPlusPalette *)bitmapdata->BitmapData;
1902 UINT palette_size = FIELD_OFFSET(EmfPlusPalette, PaletteEntries);
1903
1904 if (data_size <= palette_size)
1905 return InvalidParameter;
1906 palette_size += palette_obj->PaletteCount * sizeof(EmfPlusARGB);
1907
1908 if (data_size < palette_size)
1909 return InvalidParameter;
1910 data_size -= palette_size;
1911
1912 palette = (ColorPalette *)bitmapdata->BitmapData;
1913 scan0 = (BYTE *)bitmapdata->BitmapData + palette_size;
1914 }
1915 else
1916 {
1917 palette = NULL;
1918 scan0 = bitmapdata->BitmapData;
1919 }
1920
1921 if (data_size < bitmapdata->Height * bitmapdata->Stride)
1922 return InvalidParameter;
1923
1924 status = GdipCreateBitmapFromScan0(bitmapdata->Width, bitmapdata->Height, bitmapdata->Stride,
1925 bitmapdata->PixelFormat, scan0, (GpBitmap **)image);
1926 if (status == Ok && palette)
1927 {
1929 if (status != Ok)
1930 {
1932 *image = NULL;
1933 }
1934 }
1935 break;
1936 }
1938 {
1941 HRESULT hr;
1942
1943 if (WICCreateImagingFactory_Proxy(WINCODEC_SDK_VERSION, &factory) != S_OK)
1944 return GenericError;
1945
1946 hr = IWICImagingFactory_CreateStream(factory, &stream);
1947 IWICImagingFactory_Release(factory);
1948 if (hr != S_OK)
1949 return GenericError;
1950
1951 if (IWICStream_InitializeFromMemory(stream, bitmapdata->BitmapData, data_size) == S_OK)
1953 else
1955
1956 IWICStream_Release(stream);
1957 break;
1958 }
1959 default:
1960 WARN("Invalid bitmap type %ld.\n", bitmapdata->Type);
1961 return InvalidParameter;
1962 }
1963 break;
1964 }
1966 {
1967 EmfPlusMetafile *metafiledata = &data->ImageData.metafile;
1968
1969 if (data_size <= FIELD_OFFSET(EmfPlusMetafile, MetafileData))
1970 return InvalidParameter;
1971 data_size -= FIELD_OFFSET(EmfPlusMetafile, MetafileData);
1972
1973 switch (metafiledata->Type) {
1974 case MetafileTypeEmf:
1977 {
1978 HENHMETAFILE hemf;
1979
1980 hemf = SetEnhMetaFileBits(data_size, metafiledata->MetafileData);
1981
1982 if (!hemf)
1983 return GenericError;
1984
1986
1987 if (status != Ok)
1988 DeleteEnhMetaFile(hemf);
1989
1990 break;
1991 }
1992 default:
1993 FIXME("metafile type %ld not supported.\n", metafiledata->Type);
1994 return NotImplemented;
1995 }
1996 break;
1997 }
1998 default:
1999 FIXME("image type %d not supported.\n", data->Type);
2000 return NotImplemented;
2001 }
2002
2003 return status;
2004}
2005
2006static GpStatus metafile_deserialize_path(const BYTE *record_data, UINT data_size, GpPath **path)
2007{
2008 EmfPlusPath *data = (EmfPlusPath *)record_data;
2009 BYTE *types;
2010 UINT size;
2011 DWORD i;
2012
2013 *path = NULL;
2014
2015 if (data_size <= FIELD_OFFSET(EmfPlusPath, data))
2016 return InvalidParameter;
2017 data_size -= FIELD_OFFSET(EmfPlusPath, data);
2018
2019 if (data->PathPointFlags & 0x800) /* R */
2020 {
2021 FIXME("RLE encoded path data is not supported.\n");
2022 return NotImplemented;
2023 }
2024 else
2025 {
2026 if (data->PathPointFlags & 0x4000) /* C */
2027 size = sizeof(EmfPlusPoint);
2028 else
2029 size = sizeof(EmfPlusPointF);
2030 size += sizeof(BYTE); /* EmfPlusPathPointType */
2031 size *= data->PathPointCount;
2032 }
2033
2034 if (data_size < size)
2035 return InvalidParameter;
2036
2037 if (data->PathPointCount)
2038 {
2039 if (data->PathPointFlags & 0x4000) /* C */
2040 {
2042 GpPointF *temp = malloc(sizeof(GpPointF) * data->PathPointCount);
2043
2044 for (i = 0; i < data->PathPointCount; i++)
2045 {
2046 temp[i].X = points[i].X;
2047 temp[i].Y = points[i].Y;
2048 }
2049
2050 types = (BYTE *)(points + i);
2051 GdipCreatePath2(temp, types, data->PathPointCount, FillModeAlternate, path);
2052 free(temp);
2053 }
2054 else
2055 {
2057 types = (BYTE *)(points + data->PathPointCount);
2058 return GdipCreatePath2((GpPointF*)points, types, data->PathPointCount, FillModeAlternate, path);
2059 }
2060 }
2061 else
2062 {
2064 }
2065
2066 return Ok;
2067}
2068
2070{
2071 const DWORD *type;
2073
2074 type = buffer_read(mbuf, sizeof(*type));
2075 if (!type) return Ok;
2076
2077 node->type = *type;
2078
2079 switch (node->type)
2080 {
2081 case CombineModeReplace:
2083 case CombineModeUnion:
2084 case CombineModeXor:
2085 case CombineModeExclude:
2087 {
2089
2090 left = calloc(1, sizeof(*left));
2091 if (!left)
2092 return OutOfMemory;
2093
2094 right = calloc(1, sizeof(*right));
2095 if (!right)
2096 {
2097 free(left);
2098 return OutOfMemory;
2099 }
2100
2102 if (status == Ok)
2103 {
2105 if (status == Ok)
2106 {
2107 node->elementdata.combine.left = left;
2108 node->elementdata.combine.right = right;
2109 region->num_children += 2;
2110 return Ok;
2111 }
2112 }
2113
2114 free(left);
2115 free(right);
2116 return status;
2117 }
2118 case RegionDataRect:
2119 {
2120 const EmfPlusRectF *rect;
2121
2122 rect = buffer_read(mbuf, sizeof(*rect));
2123 if (!rect)
2124 return InvalidParameter;
2125
2126 memcpy(&node->elementdata.rect, rect, sizeof(*rect));
2127 *count += 1;
2128 return Ok;
2129 }
2130 case RegionDataPath:
2131 {
2132 const BYTE *path_data;
2133 const UINT *data_size;
2134 GpPath *path;
2135
2136 data_size = buffer_read(mbuf, FIELD_OFFSET(EmfPlusRegionNodePath, RegionNodePath));
2137 if (!data_size)
2138 return InvalidParameter;
2139
2140 path_data = buffer_read(mbuf, *data_size);
2141 if (!path_data)
2142 return InvalidParameter;
2143
2144 status = metafile_deserialize_path(path_data, *data_size, &path);
2145 if (status == Ok)
2146 {
2147 node->elementdata.path = path;
2148 *count += 1;
2149 }
2150 return Ok;
2151 }
2154 *count += 1;
2155 return Ok;
2156 default:
2157 FIXME("element type %#lx is not supported\n", *type);
2158 break;
2159 }
2160
2161 return InvalidParameter;
2162}
2163
2164static GpStatus metafile_deserialize_region(const BYTE *record_data, UINT data_size, GpRegion **region)
2165{
2166 struct memory_buffer mbuf;
2168 UINT count;
2169
2170 *region = NULL;
2171
2172 init_memory_buffer(&mbuf, record_data, data_size);
2173
2174 if (!buffer_read(&mbuf, FIELD_OFFSET(EmfPlusRegion, RegionNode)))
2175 return InvalidParameter;
2176
2177 status = GdipCreateRegion(region);
2178 if (status != Ok)
2179 return status;
2180
2181 count = 0;
2182 status = metafile_read_region_node(&mbuf, *region, &(*region)->node, &count);
2183 if (status == Ok && !count)
2185
2186 if (status != Ok)
2187 {
2188 GdipDeleteRegion(*region);
2189 *region = NULL;
2190 }
2191
2192 return status;
2193}
2194
2195static GpStatus metafile_deserialize_brush(const BYTE *record_data, UINT data_size, GpBrush **brush)
2196{
2197 static const UINT header_size = FIELD_OFFSET(EmfPlusBrush, BrushData);
2198 EmfPlusBrush *data = (EmfPlusBrush *)record_data;
2200 DWORD brushflags;
2202 UINT offset;
2203
2204 *brush = NULL;
2205
2206 if (data_size < header_size)
2207 return InvalidParameter;
2208
2209 switch (data->Type)
2210 {
2212 if (data_size != header_size + sizeof(EmfPlusSolidBrushData))
2213 return InvalidParameter;
2214
2215 status = GdipCreateSolidFill(data->BrushData.solid.SolidColor, (GpSolidFill **)brush);
2216 break;
2217 case BrushTypeHatchFill:
2218 if (data_size != header_size + sizeof(EmfPlusHatchBrushData))
2219 return InvalidParameter;
2220
2221 status = GdipCreateHatchBrush(data->BrushData.hatch.HatchStyle, data->BrushData.hatch.ForeColor,
2222 data->BrushData.hatch.BackColor, (GpHatch **)brush);
2223 break;
2225 {
2226 GpImage *image;
2227
2228 offset = header_size + FIELD_OFFSET(EmfPlusTextureBrushData, OptionalData);
2229 if (data_size <= offset)
2230 return InvalidParameter;
2231
2232 brushflags = data->BrushData.texture.BrushDataFlags;
2233 if (brushflags & BrushDataTransform)
2234 {
2235 if (data_size <= offset + sizeof(EmfPlusTransformMatrix))
2236 return InvalidParameter;
2237 transform = (EmfPlusTransformMatrix *)(record_data + offset);
2238 offset += sizeof(EmfPlusTransformMatrix);
2239 }
2240
2241 status = metafile_deserialize_image(record_data + offset, data_size - offset, &image);
2242 if (status != Ok)
2243 return status;
2244
2245 status = GdipCreateTexture(image, data->BrushData.texture.WrapMode, (GpTexture **)brush);
2246 if (status == Ok && transform && !(brushflags & BrushDataDoNotTransform))
2248
2250 break;
2251 }
2253 {
2254 GpLineGradient *gradient = NULL;
2255 GpRectF rect;
2256 UINT position_count = 0;
2257
2258 offset = header_size + FIELD_OFFSET(EmfPlusLinearGradientBrushData, OptionalData);
2259 if (data_size < offset)
2260 return InvalidParameter;
2261
2262 brushflags = data->BrushData.lineargradient.BrushDataFlags;
2263 if ((brushflags & BrushDataPresetColors) && (brushflags & (BrushDataBlendFactorsH | BrushDataBlendFactorsV)))
2264 return InvalidParameter;
2265
2266 if (brushflags & BrushDataTransform)
2267 {
2268 if (data_size < offset + sizeof(EmfPlusTransformMatrix))
2269 return InvalidParameter;
2270 transform = (EmfPlusTransformMatrix *)(record_data + offset);
2271 offset += sizeof(EmfPlusTransformMatrix);
2272 }
2273
2275 {
2276 if (data_size <= offset + sizeof(DWORD)) /* Number of factors/preset colors. */
2277 return InvalidParameter;
2278 position_count = *(DWORD *)(record_data + offset);
2279 offset += sizeof(DWORD);
2280 }
2281
2282 if (brushflags & BrushDataPresetColors)
2283 {
2284 if (data_size != offset + position_count * (sizeof(float) + sizeof(EmfPlusARGB)))
2285 return InvalidParameter;
2286 }
2287 else if (brushflags & BrushDataBlendFactorsH)
2288 {
2289 if (data_size != offset + position_count * 2 * sizeof(float))
2290 return InvalidParameter;
2291 }
2292
2293 rect.X = data->BrushData.lineargradient.RectF.X;
2294 rect.Y = data->BrushData.lineargradient.RectF.Y;
2295 rect.Width = data->BrushData.lineargradient.RectF.Width;
2296 rect.Height = data->BrushData.lineargradient.RectF.Height;
2297
2298 status = GdipCreateLineBrushFromRect(&rect, data->BrushData.lineargradient.StartColor,
2299 data->BrushData.lineargradient.EndColor, LinearGradientModeHorizontal,
2300 data->BrushData.lineargradient.WrapMode, &gradient);
2301 if (status == Ok)
2302 {
2303 if (transform)
2304 status = GdipSetLineTransform(gradient, (const GpMatrix *)transform);
2305
2306 if (status == Ok)
2307 {
2308 if (brushflags & BrushDataPresetColors)
2309 status = GdipSetLinePresetBlend(gradient, (ARGB *)(record_data + offset +
2310 position_count * sizeof(REAL)), (REAL *)(record_data + offset), position_count);
2311 else if (brushflags & BrushDataBlendFactorsH)
2312 status = GdipSetLineBlend(gradient, (REAL *)(record_data + offset + position_count * sizeof(REAL)),
2313 (REAL *)(record_data + offset), position_count);
2314
2315 if (brushflags & BrushDataIsGammaCorrected)
2316 FIXME("BrushDataIsGammaCorrected is not handled.\n");
2317 }
2318 }
2319
2320 if (status == Ok)
2321 *brush = (GpBrush *)gradient;
2322 else
2323 GdipDeleteBrush((GpBrush *)gradient);
2324
2325 break;
2326 }
2327 default:
2328 FIXME("brush type %lu is not supported.\n", data->Type);
2329 return NotImplemented;
2330 }
2331
2332 return status;
2333}
2334
2336{
2337 EmfPlusCustomStartCapData *custom_cap_data = (EmfPlusCustomStartCapData *)record_data;
2338 EmfPlusCustomLineCap *line_cap;
2340 UINT offset;
2341
2342 *cap = NULL;
2343
2345 return InvalidParameter;
2346 if (data_size < FIELD_OFFSET(EmfPlusCustomStartCapData, data) + custom_cap_data->CustomStartCapSize)
2347 return InvalidParameter;
2349 line_cap = (EmfPlusCustomLineCap *)(record_data + offset);
2350
2352 return InvalidParameter;
2354
2355 if (line_cap->Type == CustomLineCapTypeAdjustableArrow)
2356 {
2358 GpAdjustableArrowCap *arrow_cap;
2359
2360 arrow_data = (EmfPlusCustomLineCapArrowData *)(record_data + offset);
2361
2362 if (data_size < offset + sizeof(EmfPlusCustomLineCapArrowData))
2363 return InvalidParameter;
2364
2365 if ((status = GdipCreateAdjustableArrowCap(arrow_data->Height, arrow_data->Width,
2366 arrow_data->FillState, &arrow_cap)))
2367 return status;
2368
2369 if ((status = GdipSetAdjustableArrowCapMiddleInset(arrow_cap, arrow_data->MiddleInset)))
2370 goto arrow_cap_failed;
2371 if ((status = GdipSetCustomLineCapStrokeCaps((GpCustomLineCap *)arrow_cap, arrow_data->LineStartCap, arrow_data->LineEndCap)))
2372 goto arrow_cap_failed;
2373 if ((status = GdipSetCustomLineCapStrokeJoin((GpCustomLineCap *)arrow_cap, arrow_data->LineJoin)))
2374 goto arrow_cap_failed;
2375 if ((status = GdipSetCustomLineCapWidthScale((GpCustomLineCap *)arrow_cap, arrow_data->WidthScale)))
2376 goto arrow_cap_failed;
2377
2378 *cap = (GpCustomLineCap *)arrow_cap;
2379 return Ok;
2380
2381 arrow_cap_failed:
2383 return status;
2384 }
2385 else
2386 {
2387 GpPath *path, *fill_path = NULL, *stroke_path = NULL;
2388 EmfPlusCustomLineCapData *line_cap_data;
2389 GpCustomLineCap *line_cap = NULL;
2391
2392 line_cap_data = (EmfPlusCustomLineCapData *)(record_data + offset);
2393
2394 if (data_size < offset + FIELD_OFFSET(EmfPlusCustomLineCapData, OptionalData))
2395 return InvalidParameter;
2397
2399 {
2401
2403 return InvalidParameter;
2404 if (data_size < offset + fill_path->FillPathLength)
2405 return InvalidParameter;
2406
2408 }
2409 else
2410 {
2412
2413 if (data_size < offset + FIELD_OFFSET(EmfPlusCustomLineCapDataLinePath, LinePath))
2414 return InvalidParameter;
2415 if (data_size < offset + line_path->LinePathLength)
2416 return InvalidParameter;
2417
2419 }
2420
2421 if ((status = metafile_deserialize_path(record_data + offset, data_size - offset, &path)))
2422 return status;
2423
2425 fill_path = path;
2426 else
2427 stroke_path = path;
2428
2429 if ((status = GdipCreateCustomLineCap(fill_path, stroke_path, line_cap_data->BaseCap,
2430 line_cap_data->BaseInset, &line_cap)))
2431 goto default_cap_failed;
2432 if ((status = GdipSetCustomLineCapStrokeCaps(line_cap, line_cap_data->StrokeStartCap, line_cap_data->StrokeEndCap)))
2433 goto default_cap_failed;
2434 if ((status = GdipSetCustomLineCapStrokeJoin(line_cap, line_cap_data->StrokeJoin)))
2435 goto default_cap_failed;
2436 if ((status = GdipSetCustomLineCapWidthScale(line_cap, line_cap_data->WidthScale)))
2437 goto default_cap_failed;
2438
2440 *cap = line_cap;
2441 return Ok;
2442
2443 default_cap_failed:
2444 if (line_cap)
2445 GdipDeleteCustomLineCap(line_cap);
2447 return status;
2448 }
2449}
2450
2452{
2453 EmfPlusPenData *pendata = (EmfPlusPenData *)data->data;
2455
2456 if (data_size <= offset)
2457 return InvalidParameter;
2458
2459 offset += FIELD_OFFSET(EmfPlusPenData, OptionalData);
2460 if (data_size <= offset)
2461 return InvalidParameter;
2462
2463 if (pendata->PenDataFlags & PenDataTransform)
2464 offset += sizeof(EmfPlusTransformMatrix);
2465
2466 if (pendata->PenDataFlags & PenDataStartCap)
2467 offset += sizeof(DWORD);
2468
2469 if (pendata->PenDataFlags & PenDataEndCap)
2470 offset += sizeof(DWORD);
2471
2472 if (pendata->PenDataFlags & PenDataJoin)
2473 offset += sizeof(DWORD);
2474
2475 if (pendata->PenDataFlags & PenDataMiterLimit)
2476 offset += sizeof(REAL);
2477
2478 if (pendata->PenDataFlags & PenDataLineStyle)
2479 offset += sizeof(DWORD);
2480
2481 if (pendata->PenDataFlags & PenDataDashedLineCap)
2482 offset += sizeof(DWORD);
2483
2485 offset += sizeof(REAL);
2486
2487 if (pendata->PenDataFlags & PenDataDashedLine)
2488 {
2490
2492 if (data_size <= offset)
2493 return InvalidParameter;
2494
2495 offset += dashedline->DashedLineDataSize * sizeof(float);
2496 }
2497
2498 if (pendata->PenDataFlags & PenDataNonCenter)
2499 offset += sizeof(DWORD);
2500
2501 if (pendata->PenDataFlags & PenDataCompoundLine)
2502 {
2504
2506 if (data_size <= offset)
2507 return InvalidParameter;
2508
2509 offset += compoundline->CompoundLineDataSize * sizeof(float);
2510 }
2511
2512 if (pendata->PenDataFlags & PenDataCustomStartCap)
2513 {
2515
2517 if (data_size <= offset)
2518 return InvalidParameter;
2519
2520 offset += startcap->CustomStartCapSize;
2521 }
2522
2523 if (pendata->PenDataFlags & PenDataCustomEndCap)
2524 {
2526
2528 if (data_size <= offset)
2529 return InvalidParameter;
2530
2531 offset += endcap->CustomEndCapSize;
2532 }
2533
2534 *ret = offset;
2535 return Ok;
2536}
2537
2538static GpStatus METAFILE_PlaybackObject(GpMetafile *metafile, UINT flags, UINT data_size, const BYTE *record_data)
2539{
2540 BYTE type = (flags >> 8) & 0xff;
2541 BYTE id = flags & 0xff;
2542 void *object = NULL;
2544
2546 return InvalidParameter;
2547
2548 switch (type)
2549 {
2550 case ObjectTypeBrush:
2551 status = metafile_deserialize_brush(record_data, data_size, (GpBrush **)&object);
2552 break;
2553 case ObjectTypePen:
2554 {
2555 EmfPlusPen *data = (EmfPlusPen *)record_data;
2556 EmfPlusPenData *pendata = (EmfPlusPenData *)data->data;
2557 GpCustomLineCap *custom_line_cap;
2558 GpBrush *brush;
2559 DWORD offset;
2560 GpPen *pen;
2561
2563 if (status != Ok)
2564 return status;
2565
2566 status = metafile_deserialize_brush(record_data + offset, data_size - offset, &brush);
2567 if (status != Ok)
2568 return status;
2569
2570 status = GdipCreatePen2(brush, pendata->PenWidth, pendata->PenUnit, &pen);
2571 GdipDeleteBrush(brush);
2572 if (status != Ok)
2573 return status;
2574
2575 offset = FIELD_OFFSET(EmfPlusPenData, OptionalData);
2576
2577 if (pendata->PenDataFlags & PenDataTransform)
2578 {
2579 FIXME("PenDataTransform is not supported.\n");
2580 offset += sizeof(EmfPlusTransformMatrix);
2581 }
2582
2583 if (pendata->PenDataFlags & PenDataStartCap)
2584 {
2585 if ((status = GdipSetPenStartCap(pen, *(DWORD *)((BYTE *)pendata + offset))) != Ok)
2586 goto penfailed;
2587 offset += sizeof(DWORD);
2588 }
2589
2590 if (pendata->PenDataFlags & PenDataEndCap)
2591 {
2592 if ((status = GdipSetPenEndCap(pen, *(DWORD *)((BYTE *)pendata + offset))) != Ok)
2593 goto penfailed;
2594 offset += sizeof(DWORD);
2595 }
2596
2597 if (pendata->PenDataFlags & PenDataJoin)
2598 {
2599 if ((status = GdipSetPenLineJoin(pen, *(DWORD *)((BYTE *)pendata + offset))) != Ok)
2600 goto penfailed;
2601 offset += sizeof(DWORD);
2602 }
2603
2604 if (pendata->PenDataFlags & PenDataMiterLimit)
2605 {
2606 if ((status = GdipSetPenMiterLimit(pen, *(REAL *)((BYTE *)pendata + offset))) != Ok)
2607 goto penfailed;
2608 offset += sizeof(REAL);
2609 }
2610
2611 if (pendata->PenDataFlags & PenDataLineStyle)
2612 {
2613 if ((status = GdipSetPenDashStyle(pen, *(DWORD *)((BYTE *)pendata + offset))) != Ok)
2614 goto penfailed;
2615 offset += sizeof(DWORD);
2616 }
2617
2618 if (pendata->PenDataFlags & PenDataDashedLineCap)
2619 {
2620 FIXME("PenDataDashedLineCap is not supported.\n");
2621 offset += sizeof(DWORD);
2622 }
2623
2625 {
2626 if ((status = GdipSetPenDashOffset(pen, *(REAL *)((BYTE *)pendata + offset))) != Ok)
2627 goto penfailed;
2628 offset += sizeof(REAL);
2629 }
2630
2631 if (pendata->PenDataFlags & PenDataDashedLine)
2632 {
2633 EmfPlusDashedLineData *dashedline = (EmfPlusDashedLineData *)((BYTE *)pendata + offset);
2634 FIXME("PenDataDashedLine is not supported.\n");
2636 }
2637
2638 if (pendata->PenDataFlags & PenDataNonCenter)
2639 {
2640 FIXME("PenDataNonCenter is not supported.\n");
2641 offset += sizeof(DWORD);
2642 }
2643
2644 if (pendata->PenDataFlags & PenDataCompoundLine)
2645 {
2646 EmfPlusCompoundLineData *compoundline = (EmfPlusCompoundLineData *)((BYTE *)pendata + offset);
2647 FIXME("PenDataCompoundLine is not supported.\n");
2649 }
2650
2651 if (pendata->PenDataFlags & PenDataCustomStartCap)
2652 {
2653 EmfPlusCustomStartCapData *startcap = (EmfPlusCustomStartCapData *)((BYTE *)pendata + offset);
2654 if ((status = metafile_deserialize_custom_line_cap((BYTE *)startcap, data_size, &custom_line_cap)) != Ok)
2655 goto penfailed;
2656 status = GdipSetPenCustomStartCap(pen, custom_line_cap);
2657 GdipDeleteCustomLineCap(custom_line_cap);
2658 if (status != Ok)
2659 goto penfailed;
2661 }
2662
2663 if (pendata->PenDataFlags & PenDataCustomEndCap)
2664 {
2665 EmfPlusCustomEndCapData *endcap = (EmfPlusCustomEndCapData *)((BYTE *)pendata + offset);
2666 if ((status = metafile_deserialize_custom_line_cap((BYTE *)endcap, data_size, &custom_line_cap)) != Ok)
2667 goto penfailed;
2668 status = GdipSetPenCustomEndCap(pen, custom_line_cap);
2669 GdipDeleteCustomLineCap(custom_line_cap);
2670 if (status != Ok)
2671 goto penfailed;
2673 }
2674
2675 object = pen;
2676 break;
2677
2678 penfailed:
2679 GdipDeletePen(pen);
2680 return status;
2681 }
2682 case ObjectTypePath:
2683 status = metafile_deserialize_path(record_data, data_size, (GpPath **)&object);
2684 break;
2685 case ObjectTypeRegion:
2686 status = metafile_deserialize_region(record_data, data_size, (GpRegion **)&object);
2687 break;
2688 case ObjectTypeImage:
2689 status = metafile_deserialize_image(record_data, data_size, (GpImage **)&object);
2690 break;
2691 case ObjectTypeFont:
2692 {
2693 EmfPlusFont *data = (EmfPlusFont *)record_data;
2694 GpFontFamily *family;
2695 WCHAR *familyname;
2696
2697 if (data_size <= FIELD_OFFSET(EmfPlusFont, FamilyName))
2698 return InvalidParameter;
2699 data_size -= FIELD_OFFSET(EmfPlusFont, FamilyName);
2700
2701 if (data_size < data->Length * sizeof(WCHAR))
2702 return InvalidParameter;
2703
2704 if (!(familyname = malloc((data->Length + 1) * sizeof(*familyname))))
2705 return OutOfMemory;
2706
2707 memcpy(familyname, data->FamilyName, data->Length * sizeof(*familyname));
2708 familyname[data->Length] = 0;
2709
2710 status = GdipCreateFontFamilyFromName(familyname, NULL, &family);
2711 free(familyname);
2712
2713 /* If a font family cannot be created from family name, native
2714 falls back to a sans serif font. */
2715 if (status != Ok)
2717 if (status != Ok)
2718 return status;
2719
2720 status = GdipCreateFont(family, data->EmSize, data->FontStyleFlags, data->SizeUnit, (GpFont **)&object);
2721 GdipDeleteFontFamily(family);
2722 break;
2723 }
2725 {
2728
2729 if (data_size != sizeof(*data))
2730 return InvalidParameter;
2731
2733 return status;
2734
2735 status = GdipSetImageAttributesWrapMode(attributes, data->WrapMode, *(DWORD *)&data->ClampColor,
2736 !!data->ObjectClamp);
2737 if (status == Ok)
2738 object = attributes;
2739 else
2741 break;
2742 }
2743 default:
2744 FIXME("not implemented for object type %d.\n", type);
2745 return NotImplemented;
2746 }
2747
2748 if (status == Ok)
2750
2751 return status;
2752}
2753
2755{
2756 GpMatrix world_to_device;
2757
2758 get_graphics_transform(metafile->playback_graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, &world_to_device);
2759
2760 GdipTransformRegion(region, &world_to_device);
2761 GdipCombineRegionRegion(metafile->clip, region, mode);
2762
2764}
2765
2768{
2769 GpStatus stat;
2770 GpMetafile *real_metafile = (GpMetafile*)metafile;
2771
2772 TRACE("(%p,%x,%x,%d,%p)\n", metafile, recordType, flags, dataSize, data);
2773
2774 if (!metafile || (dataSize && !data) || !metafile->playback_graphics)
2775 return InvalidParameter;
2776
2777 if (recordType >= 1 && recordType <= 0x7a)
2778 {
2779 /* regular EMF record */
2780 if (metafile->playback_dc)
2781 {
2783
2784 if (record)
2785 {
2786 record->iType = recordType;
2787 record->nSize = dataSize + 8;
2788 memcpy(record->dParm, data, dataSize);
2789
2790 if (record->iType == EMR_BITBLT || record->iType == EMR_STRETCHBLT)
2792
2793 if(PlayEnhMetaFileRecord(metafile->playback_dc, metafile->handle_table,
2794 record, metafile->handle_count) == 0)
2795 ERR("PlayEnhMetaFileRecord failed\n");
2796
2797 free(record);
2798 }
2799 else
2800 return OutOfMemory;
2801 }
2802 }
2803 else
2804 {
2806
2808
2809 switch(recordType)
2810 {
2813 break;
2816 break;
2818 {
2820
2821 if (dataSize != sizeof(record->Color))
2822 return InvalidParameter;
2823
2824 return GdipGraphicsClear(metafile->playback_graphics, record->Color);
2825 }
2827 {
2829 GpBrush *brush, *temp_brush=NULL;
2830 GpRectF *rects, *temp_rects=NULL;
2831
2832 if (dataSize + sizeof(EmfPlusRecordHeader) < sizeof(EmfPlusFillRects))
2833 return InvalidParameter;
2834
2835 if (flags & 0x4000)
2836 {
2837 if (dataSize + sizeof(EmfPlusRecordHeader) < sizeof(EmfPlusFillRects) + sizeof(EmfPlusRect) * record->Count)
2838 return InvalidParameter;
2839 }
2840 else
2841 {
2842 if (dataSize + sizeof(EmfPlusRecordHeader) < sizeof(EmfPlusFillRects) + sizeof(GpRectF) * record->Count)
2843 return InvalidParameter;
2844 }
2845
2846 if (flags & 0x8000)
2847 {
2848 stat = GdipCreateSolidFill(record->BrushID, (GpSolidFill **)&temp_brush);
2849 brush = temp_brush;
2850 }
2851 else
2852 {
2853 if (record->BrushID >= EmfPlusObjectTableSize ||
2854 real_metafile->objtable[record->BrushID].type != ObjectTypeBrush)
2855 return InvalidParameter;
2856
2857 brush = real_metafile->objtable[record->BrushID].u.brush;
2858 stat = Ok;
2859 }
2860
2861 if (stat == Ok)
2862 {
2863 if (flags & 0x4000)
2864 {
2865 EmfPlusRect *int_rects = (EmfPlusRect*)(record+1);
2866 int i;
2867
2868 rects = temp_rects = calloc(record->Count, sizeof(GpRectF));
2869 if (rects)
2870 {
2871 for (i=0; i<record->Count; i++)
2872 {
2873 rects[i].X = int_rects[i].X;
2874 rects[i].Y = int_rects[i].Y;
2875 rects[i].Width = int_rects[i].Width;
2876 rects[i].Height = int_rects[i].Height;
2877 }
2878 }
2879 else
2880 stat = OutOfMemory;
2881 }
2882 else
2883 rects = (GpRectF*)(record+1);
2884 }
2885
2886 if (stat == Ok)
2887 {
2888 stat = GdipFillRectangles(metafile->playback_graphics, brush, rects, record->Count);
2889 }
2890
2891 GdipDeleteBrush(temp_brush);
2892 free(temp_rects);
2893
2894 return stat;
2895 }
2897 {
2899 CombineMode mode = (CombineMode)((flags >> 8) & 0xf);
2900 GpRegion *region;
2901
2902 if (dataSize + sizeof(EmfPlusRecordHeader) < sizeof(*record))
2903 return InvalidParameter;
2904
2905 stat = GdipCreateRegionRect(&record->ClipRect, &region);
2906
2907 if (stat == Ok)
2908 {
2909 stat = metafile_set_clip_region(real_metafile, region, mode);
2910 GdipDeleteRegion(region);
2911 }
2912
2913 return stat;
2914 }
2916 {
2917 CombineMode mode = (flags >> 8) & 0xf;
2918 BYTE regionid = flags & 0xff;
2919 GpRegion *region;
2920
2921 if (dataSize != 0)
2922 return InvalidParameter;
2923
2924 if (regionid >= EmfPlusObjectTableSize || real_metafile->objtable[regionid].type != ObjectTypeRegion)
2925 return InvalidParameter;
2926
2927 stat = GdipCloneRegion(real_metafile->objtable[regionid].u.region, &region);
2928 if (stat == Ok)
2929 {
2930 stat = metafile_set_clip_region(real_metafile, region, mode);
2931 GdipDeleteRegion(region);
2932 }
2933
2934 return stat;
2935 }
2937 {
2938 CombineMode mode = (flags >> 8) & 0xf;
2939 BYTE pathid = flags & 0xff;
2940 GpRegion *region;
2941
2942 if (dataSize != 0)
2943 return InvalidParameter;
2944
2945 if (pathid >= EmfPlusObjectTableSize || real_metafile->objtable[pathid].type != ObjectTypePath)
2946 return InvalidParameter;
2947
2948 stat = GdipCreateRegionPath(real_metafile->objtable[pathid].u.path, &region);
2949 if (stat == Ok)
2950 {
2951 stat = metafile_set_clip_region(real_metafile, region, mode);
2952 GdipDeleteRegion(region);
2953 }
2954
2955 return stat;
2956 }
2958 {
2961
2963 return InvalidParameter;
2964
2965 real_metafile->page_unit = unit;
2966 real_metafile->page_scale = record->PageScale;
2967
2968 return METAFILE_PlaybackUpdateWorldTransform(real_metafile);
2969 }
2971 {
2973
2975 return InvalidParameter;
2976
2977 memcpy(real_metafile->world_transform->matrix, record->MatrixData, sizeof(record->MatrixData));
2978
2979 return METAFILE_PlaybackUpdateWorldTransform(real_metafile);
2980 }
2982 {
2985
2987 return InvalidParameter;
2988
2989 GdipScaleMatrix(real_metafile->world_transform, record->Sx, record->Sy, order);
2990
2991 return METAFILE_PlaybackUpdateWorldTransform(real_metafile);
2992 }
2994 {
2998
3000 return InvalidParameter;
3001
3002 memcpy(matrix.matrix, record->MatrixData, sizeof(matrix.matrix));
3003
3005
3006 return METAFILE_PlaybackUpdateWorldTransform(real_metafile);
3007 }
3009 {
3012
3014 return InvalidParameter;
3015
3016 GdipRotateMatrix(real_metafile->world_transform, record->Angle, order);
3017
3018 return METAFILE_PlaybackUpdateWorldTransform(real_metafile);
3019 }
3021 {
3024
3026 return InvalidParameter;
3027
3028 GdipTranslateMatrix(real_metafile->world_transform, record->dx, record->dy, order);
3029
3030 return METAFILE_PlaybackUpdateWorldTransform(real_metafile);
3031 }
3033 {
3034 GdipSetMatrixElements(real_metafile->world_transform, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
3035
3036 return METAFILE_PlaybackUpdateWorldTransform(real_metafile);
3037 }
3039 {
3041 container* cont;
3042 GpUnit unit;
3043 REAL scale_x, scale_y;
3044 GpRectF scaled_srcrect;
3046
3047 cont = calloc(1, sizeof(*cont));
3048 if (!cont)
3049 return OutOfMemory;
3050
3051 stat = GdipCloneRegion(metafile->clip, &cont->clip);
3052 if (stat != Ok)
3053 {
3054 free(cont);
3055 return stat;
3056 }
3057
3058 stat = GdipBeginContainer2(metafile->playback_graphics, &cont->state);
3059
3060 if (stat != Ok)
3061 {
3062 GdipDeleteRegion(cont->clip);
3063 free(cont);
3064 return stat;
3065 }
3066
3067 cont->id = record->StackIndex;
3068 cont->type = BEGIN_CONTAINER;
3069 cont->world_transform = *metafile->world_transform;
3070 cont->page_unit = metafile->page_unit;
3071 cont->page_scale = metafile->page_scale;
3072 list_add_head(&real_metafile->containers, &cont->entry);
3073
3074 unit = record->Header.Flags & 0xff;
3075
3076 scale_x = units_to_pixels(1.0, unit, metafile->image.xres, metafile->printer_display);
3077 scale_y = units_to_pixels(1.0, unit, metafile->image.yres, metafile->printer_display);
3078
3079 scaled_srcrect.X = scale_x * record->SrcRect.X;
3080 scaled_srcrect.Y = scale_y * record->SrcRect.Y;
3081 scaled_srcrect.Width = scale_x * record->SrcRect.Width;
3082 scaled_srcrect.Height = scale_y * record->SrcRect.Height;
3083
3084 transform.matrix[0] = record->DestRect.Width / scaled_srcrect.Width;
3085 transform.matrix[1] = 0.0;
3086 transform.matrix[2] = 0.0;
3087 transform.matrix[3] = record->DestRect.Height / scaled_srcrect.Height;
3088 transform.matrix[4] = record->DestRect.X - scaled_srcrect.X;
3089 transform.matrix[5] = record->DestRect.Y - scaled_srcrect.Y;
3090
3092
3093 return METAFILE_PlaybackUpdateWorldTransform(real_metafile);
3094 }
3097 {
3099 container* cont;
3100
3101 cont = calloc(1, sizeof(*cont));
3102 if (!cont)
3103 return OutOfMemory;
3104
3105 stat = GdipCloneRegion(metafile->clip, &cont->clip);
3106 if (stat != Ok)
3107 {
3108 free(cont);
3109 return stat;
3110 }
3111
3113 stat = GdipBeginContainer2(metafile->playback_graphics, &cont->state);
3114 else
3115 stat = GdipSaveGraphics(metafile->playback_graphics, &cont->state);
3116
3117 if (stat != Ok)
3118 {
3119 GdipDeleteRegion(cont->clip);
3120 free(cont);
3121 return stat;
3122 }
3123
3124 cont->id = record->StackIndex;
3126 cont->type = BEGIN_CONTAINER;
3127 else
3128 cont->type = SAVE_GRAPHICS;
3129 cont->world_transform = *metafile->world_transform;
3130 cont->page_unit = metafile->page_unit;
3131 cont->page_scale = metafile->page_scale;
3132 list_add_head(&real_metafile->containers, &cont->entry);
3133
3134 break;
3135 }
3138 {
3140 container* cont;
3141 enum container_type type;
3142 BOOL found=FALSE;
3143
3144 if (recordType == EmfPlusRecordTypeEndContainer)
3146 else
3148
3149 LIST_FOR_EACH_ENTRY(cont, &real_metafile->containers, container, entry)
3150 {
3151 if (cont->id == record->StackIndex && cont->type == type)
3152 {
3153 found = TRUE;
3154 break;
3155 }
3156 }
3157
3158 if (found)
3159 {
3160 container* cont2;
3161
3162 /* pop any newer items on the stack */
3163 while ((cont2 = LIST_ENTRY(list_head(&real_metafile->containers), container, entry)) != cont)
3164 {
3165 list_remove(&cont2->entry);
3166 GdipDeleteRegion(cont2->clip);
3167 free(cont2);
3168 }
3169
3170 if (type == BEGIN_CONTAINER)
3171 GdipEndContainer(real_metafile->playback_graphics, cont->state);
3172 else
3173 GdipRestoreGraphics(real_metafile->playback_graphics, cont->state);
3174
3175 *real_metafile->world_transform = cont->world_transform;
3176 real_metafile->page_unit = cont->page_unit;
3177 real_metafile->page_scale = cont->page_scale;
3178 GdipCombineRegionRegion(real_metafile->clip, cont->clip, CombineModeReplace);
3179
3180 list_remove(&cont->entry);
3181 GdipDeleteRegion(cont->clip);
3182 free(cont);
3183 }
3184
3185 break;
3186 }
3188 {
3189 return GdipSetPixelOffsetMode(real_metafile->playback_graphics, flags & 0xff);
3190 }
3192 {
3193 return GdipSetCompositingQuality(real_metafile->playback_graphics, flags & 0xff);
3194 }
3196 {
3197 return GdipSetInterpolationMode(real_metafile->playback_graphics, flags & 0xff);
3198 }
3200 {
3201 return GdipSetTextRenderingHint(real_metafile->playback_graphics, flags & 0xff);
3202 }
3204 {
3205 return GdipSetSmoothingMode(real_metafile->playback_graphics, (flags >> 1) & 0xff);
3206 }
3208 {
3209 return GdipSetCompositingMode(real_metafile->playback_graphics, flags & 0xff);
3210 }
3212 {
3213 return METAFILE_PlaybackObject(real_metafile, flags, dataSize, data);
3214 }
3216 {
3218 BYTE image = flags & 0xff;
3219 GpPointF points[3];
3220
3221 if (image >= EmfPlusObjectTableSize || real_metafile->objtable[image].type != ObjectTypeImage)
3222 return InvalidParameter;
3223
3224 if (dataSize != FIELD_OFFSET(EmfPlusDrawImage, RectData) - sizeof(EmfPlusRecordHeader) +
3225 (flags & 0x4000 ? sizeof(EmfPlusRect) : sizeof(EmfPlusRectF)))
3226 return InvalidParameter;
3227
3229 real_metafile->objtable[draw->ImageAttributesID].type != ObjectTypeImageAttributes)
3230 return InvalidParameter;
3231
3232 if (flags & 0x4000) /* C */
3233 {
3234 points[0].X = draw->RectData.rect.X;
3235 points[0].Y = draw->RectData.rect.Y;
3236 points[1].X = points[0].X + draw->RectData.rect.Width;
3237 points[1].Y = points[0].Y;
3238 points[2].X = points[1].X;
3239 points[2].Y = points[1].Y + draw->RectData.rect.Height;
3240 }
3241 else
3242 {
3243 points[0].X = draw->RectData.rectF.X;
3244 points[0].Y = draw->RectData.rectF.Y;
3245 points[1].X = points[0].X + draw->RectData.rectF.Width;
3246 points[1].Y = points[0].Y;
3247 points[2].X = points[1].X;
3248 points[2].Y = points[1].Y + draw->RectData.rectF.Height;
3249 }
3250
3251 return GdipDrawImagePointsRect(real_metafile->playback_graphics, real_metafile->objtable[image].u.image,
3252 points, 3, draw->SrcRect.X, draw->SrcRect.Y, draw->SrcRect.Width, draw->SrcRect.Height, draw->SrcUnit,
3253 real_metafile->objtable[draw->ImageAttributesID].u.image_attributes, NULL, NULL);
3254 }
3256 {
3258 static const UINT fixed_part_size = FIELD_OFFSET(EmfPlusDrawImagePoints, PointData) -
3259 FIELD_OFFSET(EmfPlusDrawImagePoints, ImageAttributesID);
3260 BYTE image = flags & 0xff;
3261 GpPointF points[3];
3262 unsigned int i;
3263 UINT size;
3264
3265 if (image >= EmfPlusObjectTableSize || real_metafile->objtable[image].type != ObjectTypeImage)
3266 return InvalidParameter;
3267
3268 if (dataSize <= fixed_part_size)
3269 return InvalidParameter;
3270 dataSize -= fixed_part_size;
3271
3273 real_metafile->objtable[draw->ImageAttributesID].type != ObjectTypeImageAttributes)
3274 return InvalidParameter;
3275
3276 if (draw->count != 3)
3277 return InvalidParameter;
3278
3279 if ((flags >> 13) & 1) /* E */
3280 FIXME("image effects are not supported.\n");
3281
3282 if ((flags >> 11) & 1) /* P */
3283 size = sizeof(EmfPlusPointR7) * draw->count;
3284 else if ((flags >> 14) & 1) /* C */
3285 size = sizeof(EmfPlusPoint) * draw->count;
3286 else
3287 size = sizeof(EmfPlusPointF) * draw->count;
3288
3289 if (dataSize != size)
3290 return InvalidParameter;
3291
3292 if ((flags >> 11) & 1) /* P */
3293 {
3294 points[0].X = draw->PointData.pointsR[0].X;
3295 points[0].Y = draw->PointData.pointsR[0].Y;
3296 for (i = 1; i < 3; i++)
3297 {
3298 points[i].X = points[i-1].X + draw->PointData.pointsR[i].X;
3299 points[i].Y = points[i-1].Y + draw->PointData.pointsR[i].Y;
3300 }
3301 }
3302 else if ((flags >> 14) & 1) /* C */
3303 {
3304 for (i = 0; i < 3; i++)
3305 {
3306 points[i].X = draw->PointData.points[i].X;
3307 points[i].Y = draw->PointData.points[i].Y;
3308 }
3309 }
3310 else
3311 memcpy(points, draw->PointData.pointsF, sizeof(points));
3312
3313 return GdipDrawImagePointsRect(real_metafile->playback_graphics, real_metafile->objtable[image].u.image,
3314 points, 3, draw->SrcRect.X, draw->SrcRect.Y, draw->SrcRect.Width, draw->SrcRect.Height, draw->SrcUnit,
3315 real_metafile->objtable[draw->ImageAttributesID].u.image_attributes, NULL, NULL);
3316 }
3318 {
3320 GpSolidFill *solidfill = NULL;
3321 BYTE path = flags & 0xff;
3322 GpBrush *brush;
3323
3324 if (path >= EmfPlusObjectTableSize || real_metafile->objtable[path].type != ObjectTypePath)
3325 return InvalidParameter;
3326
3327 if (dataSize != sizeof(fill->data.BrushId))
3328 return InvalidParameter;
3329
3330 if (flags & 0x8000)
3331 {
3332 stat = GdipCreateSolidFill(fill->data.Color, &solidfill);
3333 if (stat != Ok)
3334 return stat;
3335 brush = (GpBrush *)solidfill;
3336 }
3337 else
3338 {
3339 if (fill->data.BrushId >= EmfPlusObjectTableSize ||
3340 real_metafile->objtable[fill->data.BrushId].type != ObjectTypeBrush)
3341 return InvalidParameter;
3342
3343 brush = real_metafile->objtable[fill->data.BrushId].u.brush;
3344 }
3345
3346 stat = GdipFillPath(real_metafile->playback_graphics, brush, real_metafile->objtable[path].u.path);
3347 GdipDeleteBrush((GpBrush *)solidfill);
3348 return stat;
3349 }
3351 {
3352 static const UINT fixed_part_size = FIELD_OFFSET(EmfPlusFillClosedCurve, PointData) -
3353 sizeof(EmfPlusRecordHeader);
3355 GpSolidFill *solidfill = NULL;
3357 GpBrush *brush;
3358 UINT size, i;
3359
3360 if (dataSize <= fixed_part_size)
3361 return InvalidParameter;
3362
3363 if (fill->Count == 0)
3364 return InvalidParameter;
3365
3366 if (flags & 0x800) /* P */
3367 size = (fixed_part_size + sizeof(EmfPlusPointR7) * fill->Count + 3) & ~3;
3368 else if (flags & 0x4000) /* C */
3369 size = fixed_part_size + sizeof(EmfPlusPoint) * fill->Count;
3370 else
3371 size = fixed_part_size + sizeof(EmfPlusPointF) * fill->Count;
3372
3373 if (dataSize != size)
3374 return InvalidParameter;
3375
3376 mode = flags & 0x200 ? FillModeWinding : FillModeAlternate; /* W */
3377
3378 if (flags & 0x8000) /* S */
3379 {
3380 stat = GdipCreateSolidFill(fill->BrushId, &solidfill);
3381 if (stat != Ok)
3382 return stat;
3383 brush = (GpBrush *)solidfill;
3384 }
3385 else
3386 {
3387 if (fill->BrushId >= EmfPlusObjectTableSize ||
3388 real_metafile->objtable[fill->BrushId].type != ObjectTypeBrush)
3389 return InvalidParameter;
3390
3391 brush = real_metafile->objtable[fill->BrushId].u.brush;
3392 }
3393
3394 if (flags & (0x800 | 0x4000))
3395 {
3396 GpPointF *points = malloc(fill->Count * sizeof(*points));
3397 if (points)
3398 {
3399 if (flags & 0x800) /* P */
3400 {
3401 points[0].X = 0;
3402 points[0].Y = 0;
3403 for (i = 1; i < fill->Count; i++)
3404 {
3405 points[i].X = points[i - 1].X + fill->PointData.pointsR[i].X;
3406 points[i].Y = points[i - 1].Y + fill->PointData.pointsR[i].Y;
3407 }
3408 }
3409 else
3410 {
3411 for (i = 0; i < fill->Count; i++)
3412 {
3413 points[i].X = fill->PointData.points[i].X;
3414 points[i].Y = fill->PointData.points[i].Y;
3415 }
3416 }
3417
3418 stat = GdipFillClosedCurve2(real_metafile->playback_graphics, brush,
3419 points, fill->Count, fill->Tension, mode);
3420 free(points);
3421 }
3422 else
3423 stat = OutOfMemory;
3424 }
3425 else
3426 stat = GdipFillClosedCurve2(real_metafile->playback_graphics, brush,
3427 (const GpPointF *)fill->PointData.pointsF, fill->Count, fill->Tension, mode);
3428
3429 GdipDeleteBrush((GpBrush *)solidfill);
3430 return stat;
3431 }
3433 {
3435 GpSolidFill *solidfill = NULL;
3436 GpBrush *brush;
3437
3438 if (dataSize <= FIELD_OFFSET(EmfPlusFillEllipse, RectData) - sizeof(EmfPlusRecordHeader))
3439 return InvalidParameter;
3441
3442 if (dataSize != (flags & 0x4000 ? sizeof(EmfPlusRect) : sizeof(EmfPlusRectF)))
3443 return InvalidParameter;
3444
3445 if (flags & 0x8000)
3446 {
3447 stat = GdipCreateSolidFill(fill->BrushId, &solidfill);
3448 if (stat != Ok)
3449 return stat;
3450 brush = (GpBrush *)solidfill;
3451 }
3452 else
3453 {
3454 if (fill->BrushId >= EmfPlusObjectTableSize ||
3455 real_metafile->objtable[fill->BrushId].type != ObjectTypeBrush)
3456 return InvalidParameter;
3457
3458 brush = real_metafile->objtable[fill->BrushId].u.brush;
3459 }
3460
3461 if (flags & 0x4000)
3462 stat = GdipFillEllipseI(real_metafile->playback_graphics, brush, fill->RectData.rect.X,
3463 fill->RectData.rect.Y, fill->RectData.rect.Width, fill->RectData.rect.Height);
3464 else
3465 stat = GdipFillEllipse(real_metafile->playback_graphics, brush, fill->RectData.rectF.X,
3466 fill->RectData.rectF.Y, fill->RectData.rectF.Width, fill->RectData.rectF.Height);
3467
3468 GdipDeleteBrush((GpBrush *)solidfill);
3469 return stat;
3470 }
3472 {
3474 GpSolidFill *solidfill = NULL;
3475 GpBrush *brush;
3476
3477 if (dataSize <= FIELD_OFFSET(EmfPlusFillPie, RectData) - sizeof(EmfPlusRecordHeader))
3478 return InvalidParameter;
3480
3481 if (dataSize != (flags & 0x4000 ? sizeof(EmfPlusRect) : sizeof(EmfPlusRectF)))
3482 return InvalidParameter;
3483
3484 if (flags & 0x8000) /* S */
3485 {
3486 stat = GdipCreateSolidFill(fill->BrushId, &solidfill);
3487 if (stat != Ok)
3488 return stat;
3489 brush = (GpBrush *)solidfill;
3490 }
3491 else
3492 {
3493 if (fill->BrushId >= EmfPlusObjectTableSize ||
3494 real_metafile->objtable[fill->BrushId].type != ObjectTypeBrush)
3495 return InvalidParameter;
3496
3497 brush = real_metafile->objtable[fill->BrushId].u.brush;
3498 }
3499
3500 if (flags & 0x4000) /* C */
3501 stat = GdipFillPieI(real_metafile->playback_graphics, brush, fill->RectData.rect.X,
3502 fill->RectData.rect.Y, fill->RectData.rect.Width, fill->RectData.rect.Height,
3503 fill->StartAngle, fill->SweepAngle);
3504 else
3505 stat = GdipFillPie(real_metafile->playback_graphics, brush, fill->RectData.rectF.X,
3506 fill->RectData.rectF.Y, fill->RectData.rectF.Width, fill->RectData.rectF.Height,
3507 fill->StartAngle, fill->SweepAngle);
3508
3509 GdipDeleteBrush((GpBrush *)solidfill);
3510 return stat;
3511 }
3513 {
3515 BYTE path = flags & 0xff;
3516
3517 if (dataSize != sizeof(draw->PenId))
3518 return InvalidParameter;
3519
3521 return InvalidParameter;
3522
3523 if (real_metafile->objtable[path].type != ObjectTypePath ||
3524 real_metafile->objtable[draw->PenId].type != ObjectTypePen)
3525 return InvalidParameter;
3526
3527 return GdipDrawPath(real_metafile->playback_graphics, real_metafile->objtable[draw->PenId].u.pen,
3528 real_metafile->objtable[path].u.path);
3529 }
3531 {
3533 BYTE pen = flags & 0xff;
3534
3535 if (pen >= EmfPlusObjectTableSize || real_metafile->objtable[pen].type != ObjectTypePen)
3536 return InvalidParameter;
3537
3538 if (dataSize != FIELD_OFFSET(EmfPlusDrawArc, RectData) - sizeof(EmfPlusRecordHeader) +
3539 (flags & 0x4000 ? sizeof(EmfPlusRect) : sizeof(EmfPlusRectF)))
3540 return InvalidParameter;
3541
3542 if (flags & 0x4000) /* C */
3543 return GdipDrawArcI(real_metafile->playback_graphics, real_metafile->objtable[pen].u.pen,
3544 draw->RectData.rect.X, draw->RectData.rect.Y, draw->RectData.rect.Width,
3545 draw->RectData.rect.Height, draw->StartAngle, draw->SweepAngle);
3546 else
3547 return GdipDrawArc(real_metafile->playback_graphics, real_metafile->objtable[pen].u.pen,
3548 draw->RectData.rectF.X, draw->RectData.rectF.Y, draw->RectData.rectF.Width,
3549 draw->RectData.rectF.Height, draw->StartAngle, draw->SweepAngle);
3550 }
3552 {
3554 BYTE pen = flags & 0xff;
3555
3556 if (pen >= EmfPlusObjectTableSize || real_metafile->objtable[pen].type != ObjectTypePen)
3557 return InvalidParameter;
3558
3559 if (dataSize != (flags & 0x4000 ? sizeof(EmfPlusRect) : sizeof(EmfPlusRectF)))
3560 return InvalidParameter;
3561
3562 if (flags & 0x4000) /* C */
3563 return GdipDrawEllipseI(real_metafile->playback_graphics, real_metafile->objtable[pen].u.pen,
3564 draw->RectData.rect.X, draw->RectData.rect.Y, draw->RectData.rect.Width,
3565 draw->RectData.rect.Height);
3566 else
3567 return GdipDrawEllipse(real_metafile->playback_graphics, real_metafile->objtable[pen].u.pen,
3568 draw->RectData.rectF.X, draw->RectData.rectF.Y, draw->RectData.rectF.Width,
3569 draw->RectData.rectF.Height);
3570 }
3572 {
3574 BYTE pen = flags & 0xff;
3575
3576 if (pen >= EmfPlusObjectTableSize || real_metafile->objtable[pen].type != ObjectTypePen)
3577 return InvalidParameter;
3578
3579 if (dataSize != FIELD_OFFSET(EmfPlusDrawPie, RectData) - sizeof(EmfPlusRecordHeader) +
3580 (flags & 0x4000 ? sizeof(EmfPlusRect) : sizeof(EmfPlusRectF)))
3581 return InvalidParameter;
3582
3583 if (flags & 0x4000) /* C */
3584 return GdipDrawPieI(real_metafile->playback_graphics, real_metafile->objtable[pen].u.pen,
3585 draw->RectData.rect.X, draw->RectData.rect.Y, draw->RectData.rect.Width,
3586 draw->RectData.rect.Height, draw->StartAngle, draw->SweepAngle);
3587 else
3588 return GdipDrawPie(real_metafile->playback_graphics, real_metafile->objtable[pen].u.pen,
3589 draw->RectData.rectF.X, draw->RectData.rectF.Y, draw->RectData.rectF.Width,
3590 draw->RectData.rectF.Height, draw->StartAngle, draw->SweepAngle);
3591 }
3593 {
3595 BYTE pen = flags & 0xff;
3596 GpRectF *rects = NULL;
3597
3598 if (pen >= EmfPlusObjectTableSize || real_metafile->objtable[pen].type != ObjectTypePen)
3599 return InvalidParameter;
3600
3601 if (dataSize <= FIELD_OFFSET(EmfPlusDrawRects, RectData) - sizeof(EmfPlusRecordHeader))
3602 return InvalidParameter;
3604
3605 if (dataSize != draw->Count * (flags & 0x4000 ? sizeof(EmfPlusRect) : sizeof(EmfPlusRectF)))
3606 return InvalidParameter;
3607
3608 if (flags & 0x4000)
3609 {
3610 DWORD i;
3611
3612 rects = malloc(draw->Count * sizeof(*rects));
3613 if (!rects)
3614 return OutOfMemory;
3615
3616 for (i = 0; i < draw->Count; i++)
3617 {
3618 rects[i].X = draw->RectData.rect[i].X;
3619 rects[i].Y = draw->RectData.rect[i].Y;
3620 rects[i].Width = draw->RectData.rect[i].Width;
3621 rects[i].Height = draw->RectData.rect[i].Height;
3622 }
3623 }
3624
3625 stat = GdipDrawRectangles(real_metafile->playback_graphics, real_metafile->objtable[pen].u.pen,
3626 rects ? rects : (GpRectF *)draw->RectData.rectF, draw->Count);
3627 free(rects);
3628 return stat;
3629 }
3631 {
3632 GpBrush *brush;
3633 DWORD expected_size;
3634 UINT16 *text;
3635 PointF *positions;
3636 GpSolidFill *solidfill = NULL;
3637 void* alignedmem = NULL;
3638 GpMatrix *matrix = NULL;
3639 BYTE font = flags & 0xff;
3641
3643 real_metafile->objtable[font].type != ObjectTypeFont)
3644 return InvalidParameter;
3645
3646 expected_size = FIELD_OFFSET(EmfPlusDrawDriverString, VariableData) -
3647 sizeof(EmfPlusRecordHeader);
3648 if (dataSize < expected_size || draw->GlyphCount <= 0)
3649 return InvalidParameter;
3650
3651 expected_size += draw->GlyphCount * (sizeof(*text) + sizeof(*positions));
3652 if (draw->MatrixPresent)
3653 expected_size += sizeof(*matrix);
3654
3655 /* Pad expected size to DWORD alignment. */
3656 expected_size = (expected_size + 3) & ~3;
3657
3658 if (dataSize != expected_size)
3659 return InvalidParameter;
3660
3661 if (flags & 0x8000)
3662 {
3663 stat = GdipCreateSolidFill(draw->brush.Color, &solidfill);
3664
3665 if (stat != Ok)
3666 return InvalidParameter;
3667
3668 brush = (GpBrush*)solidfill;
3669 }
3670 else
3671 {
3672 if (draw->brush.BrushId >= EmfPlusObjectTableSize ||
3673 real_metafile->objtable[draw->brush.BrushId].type != ObjectTypeBrush)
3674 return InvalidParameter;
3675
3676 brush = real_metafile->objtable[draw->brush.BrushId].u.brush;
3677 }
3678
3679 text = (UINT16*)&draw->VariableData[0];
3680
3681 /* If GlyphCount is odd, all subsequent fields will be 2-byte
3682 aligned rather than 4-byte aligned, which may lead to access
3683 issues. Handle this case by making our own copy of positions. */
3684 if (draw->GlyphCount % 2)
3685 {
3686 SIZE_T alloc_size = draw->GlyphCount * sizeof(*positions);
3687
3688 if (draw->MatrixPresent)
3689 alloc_size += sizeof(*matrix);
3690
3691 positions = alignedmem = malloc(alloc_size);
3692 if (!positions)
3693 {
3694 GdipDeleteBrush((GpBrush*)solidfill);
3695 return OutOfMemory;
3696 }
3697
3698 memcpy(positions, &text[draw->GlyphCount], alloc_size);
3699 }
3700 else
3701 positions = (PointF*)&text[draw->GlyphCount];
3702
3703 if (draw->MatrixPresent)
3704 matrix = (GpMatrix*)&positions[draw->GlyphCount];
3705
3707 real_metafile->objtable[font].u.font, brush, positions,
3709
3710 GdipDeleteBrush((GpBrush*)solidfill);
3711 free(alignedmem);
3712
3713 return stat;
3714 }
3716 {
3718 GpSolidFill *solidfill = NULL;
3719 GpBrush *brush;
3720 BYTE region = flags & 0xff;
3721
3722 if (dataSize != sizeof(EmfPlusFillRegion) - sizeof(EmfPlusRecordHeader))
3723 return InvalidParameter;
3724
3725 if (region >= EmfPlusObjectTableSize ||
3726 real_metafile->objtable[region].type != ObjectTypeRegion)
3727 return InvalidParameter;
3728
3729 if (flags & 0x8000)
3730 {
3731 stat = GdipCreateSolidFill(fill->data.Color, &solidfill);
3732 if (stat != Ok)
3733 return stat;
3734 brush = (GpBrush*)solidfill;
3735 }
3736 else
3737 {
3738 if (fill->data.BrushId >= EmfPlusObjectTableSize ||
3739 real_metafile->objtable[fill->data.BrushId].type != ObjectTypeBrush)
3740 return InvalidParameter;
3741
3742 brush = real_metafile->objtable[fill->data.BrushId].u.brush;
3743 }
3744
3745 stat = GdipFillRegion(real_metafile->playback_graphics, brush,
3746 real_metafile->objtable[region].u.region);
3747 GdipDeleteBrush((GpBrush*)solidfill);
3748
3749 return stat;
3750 }
3752 {
3754
3756 return InvalidParameter;
3757
3758 return GdipSetRenderingOrigin(real_metafile->playback_graphics, origin->x, origin->y);
3759 }
3760 default:
3761 if (recordType >= GDIP_EMFPLUS_RECORD_BASE)
3762 FIXME("Not implemented for EMF+ record type %u\n", recordType - GDIP_EMFPLUS_RECORD_BASE);
3763 else
3764 FIXME("Not implemented for record type %x\n", recordType);
3765 return NotImplemented;
3766 }
3767 }
3768
3769 return Ok;
3770}
3771
3773{
3777};
3778
3779static int CALLBACK enum_metafile_proc(HDC hDC, HANDLETABLE *lpHTable, const ENHMETARECORD *lpEMFR,
3780 int nObj, LPARAM lpData)
3781{
3782 BOOL ret;
3783 struct enum_metafile_data *data = (struct enum_metafile_data*)lpData;
3784 const BYTE* pStr;
3785
3786 data->metafile->handle_table = lpHTable;
3787 data->metafile->handle_count = nObj;
3788
3789 /* First check for an EMF+ record. */
3790 if (lpEMFR->iType == EMR_GDICOMMENT)
3791 {
3792 const EMRGDICOMMENT *comment = (const EMRGDICOMMENT*)lpEMFR;
3793
3794 if (comment->cbData >= 4 && memcmp(comment->Data, "EMF+", 4) == 0)
3795 {
3796 int offset = 4;
3797
3798 while (offset + sizeof(EmfPlusRecordHeader) <= comment->cbData)
3799 {
3801
3802 if (record->DataSize)
3803 pStr = (const BYTE*)(record+1);
3804 else
3805 pStr = NULL;
3806
3807 ret = data->callback(record->Type, record->Flags, record->DataSize,
3808 pStr, data->callback_data);
3809
3810 if (!ret)
3811 return 0;
3812
3813 offset += record->Size;
3814 }
3815
3816 return 1;
3817 }
3818 }
3819
3820 if (lpEMFR->nSize != 8)
3821 pStr = (const BYTE*)lpEMFR->dParm;
3822 else
3823 pStr = NULL;
3824
3825 return data->callback(lpEMFR->iType, 0, lpEMFR->nSize-8,
3826 pStr, data->callback_data);
3827}
3828
3832 VOID *callbackData, GDIPCONST GpImageAttributes *imageAttributes)
3833{
3834 struct enum_metafile_data data;
3835 GpStatus stat;
3836 GpMetafile *real_metafile = (GpMetafile*)metafile; /* whoever made this const was joking */
3838 GpPath *dst_path;
3839 RECT dst_bounds;
3840
3841 TRACE("(%p,%p,%p,%i,%p,%i,%p,%p,%p)\n", graphics, metafile,
3842 destPoints, count, srcRect, srcUnit, callback, callbackData,
3843 imageAttributes);
3844
3845 if (!graphics || !metafile || !destPoints || count != 3 || !srcRect)
3846 return InvalidParameter;
3847
3848 if (!metafile->hemf)
3849 return InvalidParameter;
3850
3851 if (metafile->playback_graphics)
3852 return ObjectBusy;
3853
3854 TRACE("%s %i -> %s %s %s\n", debugstr_rectf(srcRect), srcUnit,
3855 debugstr_pointf(&destPoints[0]), debugstr_pointf(&destPoints[1]),
3856 debugstr_pointf(&destPoints[2]));
3857
3858 data.callback = callback;
3859 data.callback_data = callbackData;
3860 data.metafile = real_metafile;
3861
3862 real_metafile->playback_graphics = graphics;
3863 real_metafile->playback_dc = NULL;
3864 real_metafile->src_rect = *srcRect;
3865
3866 memcpy(real_metafile->playback_points, destPoints, sizeof(PointF) * 3);
3868
3869 if (stat == Ok)
3870 stat = GdipBeginContainer2(graphics, &state);
3871
3872 if (stat == Ok)
3873 {
3874 stat = GdipSetPageScale(graphics, 1.0);
3875
3876 if (stat == Ok)
3877 stat = GdipSetPageUnit(graphics, UnitPixel);
3878
3879 if (stat == Ok)
3880 stat = GdipResetWorldTransform(graphics);
3881
3882 if (stat == Ok)
3883 stat = GdipCreateRegion(&real_metafile->base_clip);
3884
3885 if (stat == Ok)
3886 stat = GdipGetClip(graphics, real_metafile->base_clip);
3887
3888 if (stat == Ok)
3889 stat = GdipCreateRegion(&real_metafile->clip);
3890
3891 if (stat == Ok)
3893
3894 if (stat == Ok)
3895 {
3896 GpPointF clip_points[4];
3897
3898 clip_points[0] = real_metafile->playback_points[0];
3899 clip_points[1] = real_metafile->playback_points[1];
3900 clip_points[2].X = real_metafile->playback_points[1].X + real_metafile->playback_points[2].X
3901 - real_metafile->playback_points[0].X;
3902 clip_points[2].Y = real_metafile->playback_points[1].Y + real_metafile->playback_points[2].Y
3903 - real_metafile->playback_points[0].Y;
3904 clip_points[3] = real_metafile->playback_points[2];
3905
3906 stat = GdipAddPathPolygon(dst_path, clip_points, 4);
3907
3908 if (stat == Ok)
3909 stat = GdipCombineRegionPath(real_metafile->base_clip, dst_path, CombineModeIntersect);
3910
3911 GdipDeletePath(dst_path);
3912 }
3913
3914 if (stat == Ok)
3915 stat = GdipCreateMatrix(&real_metafile->world_transform);
3916
3917 if (stat == Ok)
3918 {
3919 real_metafile->page_unit = UnitDisplay;
3920 real_metafile->page_scale = 1.0;
3922 }
3923
3924 if (stat == Ok)
3925 {
3926 stat = METAFILE_PlaybackUpdateClip(real_metafile);
3927 }
3928
3929 if (stat == Ok)
3930 {
3931 stat = METAFILE_PlaybackGetDC(real_metafile);
3932
3933 dst_bounds.left = real_metafile->playback_points[0].X;
3934 dst_bounds.right = real_metafile->playback_points[1].X;
3935 dst_bounds.top = real_metafile->playback_points[0].Y;
3936 dst_bounds.bottom = real_metafile->playback_points[2].Y;
3937 }
3938
3939 if (stat == Ok)
3941 &data, &dst_bounds);
3942
3943 METAFILE_PlaybackReleaseDC(real_metafile);
3944
3945 GdipDeleteMatrix(real_metafile->world_transform);
3946 real_metafile->world_transform = NULL;
3947
3948 GdipDeleteRegion(real_metafile->base_clip);
3949 real_metafile->base_clip = NULL;
3950
3951 GdipDeleteRegion(real_metafile->clip);
3952 real_metafile->clip = NULL;
3953
3954 while (list_head(&real_metafile->containers))
3955 {
3956 container* cont = LIST_ENTRY(list_head(&real_metafile->containers), container, entry);
3957 list_remove(&cont->entry);
3958 GdipDeleteRegion(cont->clip);
3959 free(cont);
3960 }
3961
3962 GdipEndContainer(graphics, state);
3963 }
3964
3965 real_metafile->playback_graphics = NULL;
3966
3967 return stat;
3968}
3969
3973 VOID *cb_data, GDIPCONST GpImageAttributes *attrs)
3974{
3975 GpPointF points[3];
3976
3977 if (!graphics || !metafile || !dest) return InvalidParameter;
3978
3979 points[0].X = points[2].X = dest->X;
3980 points[0].Y = points[1].Y = dest->Y;
3981 points[1].X = dest->X + dest->Width;
3982 points[2].Y = dest->Y + dest->Height;
3983
3985 src, srcUnit, callback, cb_data, attrs);
3986}
3990 VOID *cb_data, GDIPCONST GpImageAttributes *attrs )
3991{
3992 GpRectF destRectF, srcRectF;
3993
3994 destRectF.X = destRect->X;
3995 destRectF.Y = destRect->Y;
3996 destRectF.Width = destRect->Width;
3997 destRectF.Height = destRect->Height;
3998
3999 srcRectF.X = srcRect->X;
4000 srcRectF.Y = srcRect->Y;
4001 srcRectF.Width = srcRect->Width;
4002 srcRectF.Height = srcRect->Height;
4003
4004 return GdipEnumerateMetafileSrcRectDestRect( graphics, metafile, &destRectF, &srcRectF, srcUnit, callback, cb_data, attrs);
4005}
4006
4010{
4011 GpPointF points[3];
4012
4013 if (!graphics || !metafile || !dest) return InvalidParameter;
4014
4015 points[0].X = points[2].X = dest->X;
4016 points[0].Y = points[1].Y = dest->Y;
4017 points[1].X = dest->X + dest->Width;
4018 points[2].Y = dest->Y + dest->Height;
4019
4021 &metafile->bounds, metafile->unit, callback, cb_data, attrs);
4022}
4023
4027{
4028 GpRectF destf;
4029
4030 if (!graphics || !metafile || !dest) return InvalidParameter;
4031
4032 destf.X = dest->X;
4033 destf.Y = dest->Y;
4034 destf.Width = dest->Width;
4035 destf.Height = dest->Height;
4036
4037 return GdipEnumerateMetafileDestRect(graphics, metafile, &destf, callback, cb_data, attrs);
4038}
4039
4043{
4044 GpRectF destf;
4045
4046 if (!graphics || !metafile || !dest) return InvalidParameter;
4047
4048 destf.X = dest->X;
4049 destf.Y = dest->Y;
4050 destf.Width = units_to_pixels(metafile->bounds.Width, metafile->unit,
4051 metafile->image.xres, metafile->printer_display);
4052 destf.Height = units_to_pixels(metafile->bounds.Height, metafile->unit,
4053 metafile->image.yres, metafile->printer_display);
4054
4055 return GdipEnumerateMetafileDestRect(graphics, metafile, &destf, callback, cb_data, attrs);
4056}
4057
4061{
4062 GpPointF ptf;
4063
4064 if (!graphics || !metafile || !dest) return InvalidParameter;
4065
4066 ptf.X = dest->X;
4067 ptf.Y = dest->Y;
4068
4069 return GdipEnumerateMetafileDestPoint(graphics, metafile, &ptf, callback, cb_data, attrs);
4070}
4071
4074{
4076
4077 TRACE("(%p, %p)\n", metafile, header);
4078
4079 if(!metafile || !header)
4080 return InvalidParameter;
4081
4082 if (metafile->hemf)
4083 {
4085 if (status != Ok) return status;
4086 }
4087 else
4088 {
4089 memset(header, 0, sizeof(*header));
4090 header->Version = VERSION_MAGIC2;
4091 }
4092
4093 header->Type = metafile->metafile_type;
4094 header->DpiX = metafile->image.xres;
4095 header->DpiY = metafile->image.yres;
4096 header->Width = gdip_round(metafile->bounds.Width);
4097 header->Height = gdip_round(metafile->bounds.Height);
4098
4099 return Ok;
4100}
4101
4103 int nObj, LPARAM lpData)
4104{
4105 EmfPlusHeader *dst_header = (EmfPlusHeader*)lpData;
4106
4107 if (lpEMFR->iType == EMR_GDICOMMENT)
4108 {
4109 const EMRGDICOMMENT *comment = (const EMRGDICOMMENT*)lpEMFR;
4110
4111 if (comment->cbData >= 4 && memcmp(comment->Data, "EMF+", 4) == 0)
4112 {
4113 const EmfPlusRecordHeader *header = (const EmfPlusRecordHeader*)&comment->Data[4];
4114
4115 if (4 + sizeof(EmfPlusHeader) <= comment->cbData &&
4117 {
4118 memcpy(dst_header, header, sizeof(*dst_header));
4119 }
4120 }
4121 }
4122 else if (lpEMFR->iType == EMR_HEADER)
4123 return TRUE;
4124
4125 return FALSE;
4126}
4127
4130{
4131 ENHMETAHEADER3 emfheader;
4132 EmfPlusHeader emfplusheader;
4133 MetafileType metafile_type;
4134
4135 TRACE("(%p,%p)\n", hemf, header);
4136
4137 if(!hemf || !header)
4138 return InvalidParameter;
4139
4140 if (GetEnhMetaFileHeader(hemf, sizeof(emfheader), (ENHMETAHEADER*)&emfheader) == 0)
4141 return GenericError;
4142
4143 emfplusheader.Header.Type = 0;
4144
4145 EnumEnhMetaFile(NULL, hemf, get_emfplus_header_proc, &emfplusheader, NULL);
4146
4147 if (emfplusheader.Header.Type == EmfPlusRecordTypeHeader)
4148 {
4149 if ((emfplusheader.Header.Flags & 1) == 1)
4150 metafile_type = MetafileTypeEmfPlusDual;
4151 else
4152 metafile_type = MetafileTypeEmfPlusOnly;
4153 }
4154 else
4155 metafile_type = MetafileTypeEmf;
4156
4157 header->Type = metafile_type;
4158 header->Size = emfheader.nBytes;
4159 header->DpiX = (REAL)emfheader.szlDevice.cx * 25.4 / emfheader.szlMillimeters.cx;
4160 header->DpiY = (REAL)emfheader.szlDevice.cy * 25.4 / emfheader.szlMillimeters.cy;
4161 header->X = gdip_round((REAL)emfheader.rclFrame.left / 2540.0 * header->DpiX);
4162 header->Y = gdip_round((REAL)emfheader.rclFrame.top / 2540.0 * header->DpiY);
4163 header->Width = gdip_round((REAL)(emfheader.rclFrame.right - emfheader.rclFrame.left) / 2540.0 * header->DpiX);
4164 header->Height = gdip_round((REAL)(emfheader.rclFrame.bottom - emfheader.rclFrame.top) / 2540.0 * header->DpiY);
4165 header->EmfHeader = emfheader;
4166
4167 if (metafile_type == MetafileTypeEmfPlusDual || metafile_type == MetafileTypeEmfPlusOnly)
4168 {
4169 header->Version = emfplusheader.Version;
4170 header->EmfPlusFlags = emfplusheader.EmfPlusFlags;
4171 header->EmfPlusHeaderSize = emfplusheader.Header.Size;
4172 header->LogicalDpiX = emfplusheader.LogicalDpiX;
4173 header->LogicalDpiY = emfplusheader.LogicalDpiY;
4174 }
4175 else
4176 {
4177 header->Version = emfheader.nVersion;
4178 header->EmfPlusFlags = 0;
4179 header->EmfPlusHeaderSize = 0;
4180 header->LogicalDpiX = 0;
4181 header->LogicalDpiY = 0;
4182 }
4183
4184 return Ok;
4185}
4186
4189{
4192
4193 TRACE("(%p,%p,%p)\n", hwmf, placeable, header);
4194
4195 status = GdipCreateMetafileFromWmf(hwmf, FALSE, placeable, &metafile);
4196 if (status == Ok)
4197 {
4199 GdipDisposeImage(&metafile->image);
4200 }
4201 return status;
4202}
4203
4206{
4209
4210 TRACE("(%s,%p)\n", debugstr_w(filename), header);
4211
4212 if (!filename || !header)
4213 return InvalidParameter;
4214
4216 if (status == Ok)
4217 {
4219 GdipDisposeImage(&metafile->image);
4220 }
4221 return status;
4222}
4223
4226{
4229
4230 TRACE("(%p,%p)\n", stream, header);
4231
4232 if (!stream || !header)
4233 return InvalidParameter;
4234
4236 if (status == Ok)
4237 {
4239 GdipDisposeImage(&metafile->image);
4240 }
4241 return status;
4242}
4243
4246{
4247 GpStatus stat;
4249
4250 TRACE("(%p,%i,%p)\n", hemf, delete, metafile);
4251
4252 if(!hemf || !metafile)
4253 return InvalidParameter;
4254
4256 if (stat != Ok)
4257 return stat;
4258
4259 *metafile = calloc(1, sizeof(GpMetafile));
4260 if (!*metafile)
4261 return OutOfMemory;
4262
4263 (*metafile)->image.type = ImageTypeMetafile;
4264 (*metafile)->image.format = ImageFormatEMF;
4265 (*metafile)->image.frame_count = 1;
4266 (*metafile)->image.xres = header.DpiX;
4267 (*metafile)->image.yres = header.DpiY;
4268 (*metafile)->bounds.X = (REAL)header.EmfHeader.rclFrame.left / 2540.0 * header.DpiX;
4269 (*metafile)->bounds.Y = (REAL)header.EmfHeader.rclFrame.top / 2540.0 * header.DpiY;
4270 (*metafile)->bounds.Width = (REAL)(header.EmfHeader.rclFrame.right - header.EmfHeader.rclFrame.left)
4271 / 2540.0 * header.DpiX;
4272 (*metafile)->bounds.Height = (REAL)(header.EmfHeader.rclFrame.bottom - header.EmfHeader.rclFrame.top)
4273 / 2540.0 * header.DpiY;
4274 (*metafile)->unit = UnitPixel;
4275 (*metafile)->metafile_type = header.Type;
4276 (*metafile)->hemf = hemf;
4277 (*metafile)->preserve_hemf = !delete;
4278 /* If the 31th bit of EmfPlusFlags was set, metafile was recorded with a DC for a video display.
4279 * If clear, metafile was recorded with a DC for a printer */
4280 (*metafile)->printer_display = !(header.EmfPlusFlags & (1u << 31));
4281 (*metafile)->logical_dpix = header.LogicalDpiX;
4282 (*metafile)->logical_dpiy = header.LogicalDpiY;
4283 list_init(&(*metafile)->containers);
4284
4285 TRACE("<-- %p\n", *metafile);
4286
4287 return Ok;
4288}
4289
4292{
4293 UINT read;
4294 BYTE *copy;
4295 HENHMETAFILE hemf;
4296 GpStatus retval = Ok;
4297
4298 TRACE("(%p, %d, %p, %p)\n", hwmf, delete, placeable, metafile);
4299
4300 if(!hwmf || !metafile)
4301 return InvalidParameter;
4302
4303 *metafile = NULL;
4304 read = GetMetaFileBitsEx(hwmf, 0, NULL);
4305 if(!read)
4306 return GenericError;
4307 copy = malloc(read);
4308 GetMetaFileBitsEx(hwmf, read, copy);
4309
4311 free(copy);
4312
4313 /* FIXME: We should store and use hwmf instead of converting to hemf */
4315
4316 if (retval == Ok)
4317 {
4318 if (placeable)
4319 {
4320 (*metafile)->image.xres = (REAL)placeable->Inch;
4321 (*metafile)->image.yres = (REAL)placeable->Inch;
4322 (*metafile)->bounds.X = ((REAL)placeable->BoundingBox.Left) / ((REAL)placeable->Inch);
4323 (*metafile)->bounds.Y = ((REAL)placeable->BoundingBox.Top) / ((REAL)placeable->Inch);
4324 (*metafile)->bounds.Width = (REAL)(placeable->BoundingBox.Right -
4325 placeable->BoundingBox.Left);
4326 (*metafile)->bounds.Height = (REAL)(placeable->BoundingBox.Bottom -
4327 placeable->BoundingBox.Top);
4328 (*metafile)->metafile_type = MetafileTypeWmfPlaceable;
4329 }
4330 else
4331 (*metafile)->metafile_type = MetafileTypeWmf;
4332 (*metafile)->image.format = ImageFormatWMF;
4333
4334 if (delete) DeleteMetaFile(hwmf);
4335 }
4336 else
4337 DeleteEnhMetaFile(hemf);
4338 return retval;
4339}
4340
4343{
4344 HMETAFILE hmf;
4345 HENHMETAFILE emf;
4346
4347 TRACE("(%s, %p, %p)\n", debugstr_w(file), placeable, metafile);
4348
4349 hmf = GetMetaFileW(file);
4350 if(hmf)
4351 return GdipCreateMetafileFromWmf(hmf, TRUE, placeable, metafile);
4352
4354 if(emf)
4356
4357 return GenericError;
4358}
4359
4362{
4364 IStream *stream;
4365
4366 TRACE("(%p, %p)\n", file, metafile);
4367
4368 if (!file || !metafile) return InvalidParameter;
4369
4370 *metafile = NULL;
4371
4373 if (status == Ok)
4374 {
4376 IStream_Release(stream);
4377 }
4378 return status;
4379}
4380
4383{
4384 GpStatus stat;
4385
4386 TRACE("%p %p\n", stream, metafile);
4387
4389 if (stat != Ok) return stat;
4390
4391 if ((*metafile)->image.type != ImageTypeMetafile)
4392 {
4393 GdipDisposeImage(&(*metafile)->image);
4394 *metafile = NULL;
4395 return GenericError;
4396 }
4397
4398 return Ok;
4399}
4400
4402 UINT *limitDpi)
4403{
4404 TRACE("(%p,%p)\n", metafile, limitDpi);
4405
4406 if (!metafile || !limitDpi)
4407 return InvalidParameter;
4408
4409 if (!metafile->record_dc)
4410 return WrongState;
4411
4412 *limitDpi = metafile->limit_dpi;
4413
4414 return Ok;
4415}
4416
4418 UINT limitDpi)
4419{
4420 TRACE("(%p,%u)\n", metafile, limitDpi);
4421
4422 if (limitDpi == 0)
4423 limitDpi = 96;
4424
4425 if (!metafile || limitDpi < 10)
4426 return InvalidParameter;
4427
4428 if (!metafile->record_dc)
4429 return WrongState;
4430
4431 metafile->limit_dpi = limitDpi;
4432
4433 return Ok;
4434}
4435
4437 GpMetafile* metafile, BOOL* succ, EmfType emfType,
4438 const WCHAR* description, GpMetafile** out_metafile)
4439{
4440 static int calls;
4441
4442 TRACE("(%p,%p,%p,%u,%s,%p)\n", ref, metafile, succ, emfType,
4443 debugstr_w(description), out_metafile);
4444
4445 if(!ref || !metafile || !out_metafile || emfType < EmfTypeEmfOnly || emfType > EmfTypeEmfPlusDual)
4446 return InvalidParameter;
4447
4448 if(succ)
4449 *succ = FALSE;
4450 *out_metafile = NULL;
4451
4452 if(!(calls++))
4453 FIXME("not implemented\n");
4454
4455 return NotImplemented;
4456}
4457
4458GpStatus WINGDIPAPI GdipEmfToWmfBits(HENHMETAFILE hemf, UINT cbData16,
4459 LPBYTE pData16, INT iMapMode, INT eFlags)
4460{
4461 FIXME("(%p, %d, %p, %d, %d): stub\n", hemf, cbData16, pData16, iMapMode, eFlags);
4462 return NotImplemented;
4463}
4464
4466 HDC hdc, EmfType type, GDIPCONST GpRectF *pFrameRect,
4469{
4470 HDC record_dc;
4471 REAL dpix, dpiy;
4472 REAL framerect_factor_x, framerect_factor_y;
4473 RECT rc, *lprc;
4474 GpStatus stat;
4475
4476 TRACE("%s %p %d %s %d %s %p\n", debugstr_w(fileName), hdc, type, debugstr_rectf(pFrameRect),
4477 frameUnit, debugstr_w(desc), metafile);
4478
4479 if (!hdc || type < EmfTypeEmfOnly || type > EmfTypeEmfPlusDual || !metafile)
4480 return InvalidParameter;
4481
4482 dpix = (REAL)GetDeviceCaps(hdc, HORZRES) / GetDeviceCaps(hdc, HORZSIZE) * 25.4;
4483 dpiy = (REAL)GetDeviceCaps(hdc, VERTRES) / GetDeviceCaps(hdc, VERTSIZE) * 25.4;
4484
4485 if (pFrameRect)
4486 {
4487 switch (frameUnit)
4488 {
4490 framerect_factor_x = 2540.0 / dpix;
4491 framerect_factor_y = 2540.0 / dpiy;
4492 break;
4494 framerect_factor_x = framerect_factor_y = 2540.0 / 72.0;
4495 break;
4497 framerect_factor_x = framerect_factor_y = 2540.0;
4498 break;
4500 framerect_factor_x = framerect_factor_y = 2540.0 / 300.0;
4501 break;
4503 framerect_factor_x = framerect_factor_y = 100.0;
4504 break;
4506 framerect_factor_x = framerect_factor_y = 1.0;
4507 break;
4508 default:
4509 return InvalidParameter;
4510 }
4511
4512 rc.left = framerect_factor_x * pFrameRect->X;
4513 rc.top = framerect_factor_y * pFrameRect->Y;
4514 rc.right = rc.left + framerect_factor_x * pFrameRect->Width;
4515 rc.bottom = rc.top + framerect_factor_y * pFrameRect->Height;
4516
4517 lprc = &rc;
4518 }
4519 else
4520 lprc = NULL;
4521
4522 record_dc = CreateEnhMetaFileW(hdc, fileName, lprc, desc);
4523
4524 if (!record_dc)
4525 return GenericError;
4526
4527 *metafile = calloc(1, sizeof(GpMetafile));
4528 if(!*metafile)
4529 {
4531 return OutOfMemory;
4532 }
4533
4534 (*metafile)->image.type = ImageTypeMetafile;
4535 (*metafile)->image.flags = ImageFlagsNone;
4536 (*metafile)->image.palette = NULL;
4537 (*metafile)->image.xres = dpix;
4538 (*metafile)->image.yres = dpiy;
4539 (*metafile)->bounds.X = (*metafile)->bounds.Y = 0.0;
4540 (*metafile)->bounds.Width = (*metafile)->bounds.Height = 1.0;
4541 (*metafile)->unit = UnitPixel;
4542 (*metafile)->metafile_type = (MetafileType)type;
4543 (*metafile)->record_dc = record_dc;
4544 (*metafile)->comment_data = NULL;
4545 (*metafile)->comment_data_size = 0;
4546 (*metafile)->comment_data_length = 0;
4547 (*metafile)->limit_dpi = 96;
4548 (*metafile)->hemf = NULL;
4549 (*metafile)->printer_display = (GetDeviceCaps(record_dc, TECHNOLOGY) == DT_RASPRINTER);
4550 (*metafile)->logical_dpix = (REAL)GetDeviceCaps(record_dc, LOGPIXELSX);
4551 (*metafile)->logical_dpiy = (REAL)GetDeviceCaps(record_dc, LOGPIXELSY);
4552 list_init(&(*metafile)->containers);
4553
4554 if (!pFrameRect)
4555 {
4556 (*metafile)->auto_frame = TRUE;
4557 (*metafile)->auto_frame_min.X = 0;
4558 (*metafile)->auto_frame_min.Y = 0;
4559 (*metafile)->auto_frame_max.X = -1;
4560 (*metafile)->auto_frame_max.Y = -1;
4561 }
4562
4564
4565 if (stat != Ok)
4566 {
4568 free(*metafile);
4569 *metafile = NULL;
4570 return OutOfMemory;
4571 }
4572
4573 return stat;
4574}
4575
4577 GDIPCONST GpRect *pFrameRect, MetafileFrameUnit frameUnit,
4579{
4580 FIXME("%s %p %d %p %d %s %p stub!\n", debugstr_w(fileName), hdc, type, pFrameRect,
4581 frameUnit, debugstr_w(desc), metafile);
4582
4583 return NotImplemented;
4584}
4585
4586/*****************************************************************************
4587 * GdipConvertToEmfPlusToFile [GDIPLUS.@]
4588 */
4589
4591 GpMetafile* metafile, BOOL* conversionSuccess,
4592 const WCHAR* filename, EmfType emfType,
4593 const WCHAR* description, GpMetafile** out_metafile)
4594{
4595 FIXME("stub: %p, %p, %p, %p, %u, %p, %p\n", refGraphics, metafile, conversionSuccess, filename, emfType, description, out_metafile);
4596 return NotImplemented;
4597}
4598
4600{
4602 STATSTG statstg;
4603 GpStatus stat;
4604 HRESULT hr;
4605
4606 *size = 0;
4607
4609 if (FAILED(hr)) return hresult_to_status(hr);
4610
4612 if (stat != Ok)
4613 {
4614 IStream_Release(*stream);
4615 return stat;
4616 }
4617
4618 hr = IStream_Stat(*stream, &statstg, 1);
4619 if (FAILED(hr))
4620 {
4621 IStream_Release(*stream);
4622 return hresult_to_status(hr);
4623 }
4624 *size = statstg.cbSize.u.LowPart;
4625
4626 zero.QuadPart = 0;
4627 hr = IStream_Seek(*stream, zero, STREAM_SEEK_SET, NULL);
4628 if (FAILED(hr))
4629 {
4630 IStream_Release(*stream);
4631 return hresult_to_status(hr);
4632 }
4633
4634 return Ok;
4635}
4636
4638{
4639 HRESULT hr;
4640
4641 record->Width = 0;
4642 record->Height = 0;
4643 record->Stride = 0;
4644 record->PixelFormat = 0;
4646
4647 hr = IStream_Read(stream, record->BitmapData, size, NULL);
4648 if (FAILED(hr)) return hresult_to_status(hr);
4649 return Ok;
4650}
4651
4653{
4654 EmfPlusObject *object_record;
4655 GpStatus stat;
4656 DWORD size;
4657
4658 *id = -1;
4659
4660 if (metafile->metafile_type != MetafileTypeEmfPlusOnly && metafile->metafile_type != MetafileTypeEmfPlusDual)
4661 return Ok;
4662
4663 if (image->type == ImageTypeBitmap)
4664 {
4665 IStream *stream;
4666 DWORD aligned_size;
4667
4669 if (stat != Ok) return stat;
4670 aligned_size = (size + 3) & ~3;
4671
4673 FIELD_OFFSET(EmfPlusObject, ObjectData.image.ImageData.bitmap.BitmapData[aligned_size]),
4674 (void**)&object_record);
4675 if (stat != Ok)
4676 {
4677 IStream_Release(stream);
4678 return stat;
4679 }
4680 memset(object_record->ObjectData.image.ImageData.bitmap.BitmapData + size, 0, aligned_size - size);
4681
4683 object_record->Header.Flags = *id | ObjectTypeImage << 8;
4684 object_record->ObjectData.image.Version = VERSION_MAGIC2;
4685 object_record->ObjectData.image.Type = ImageDataTypeBitmap;
4686
4687 stat = METAFILE_FillEmfPlusBitmap(&object_record->ObjectData.image.ImageData.bitmap, stream, size);
4688 IStream_Release(stream);
4689 if (stat != Ok) METAFILE_RemoveLastRecord(metafile, &object_record->Header);
4690 return stat;
4691 }
4692 else if (image->type == ImageTypeMetafile)
4693 {
4694 HENHMETAFILE hemf = ((GpMetafile*)image)->hemf;
4695 EmfPlusMetafile *metafile_record;
4696
4697 if (!hemf) return InvalidParameter;
4698
4699 size = GetEnhMetaFileBits(hemf, 0, NULL);
4700 if (!size) return GenericError;
4701
4704 (void**)&object_record);
4705 if (stat != Ok) return stat;
4706
4708 object_record->Header.Flags = *id | ObjectTypeImage << 8;
4709 object_record->ObjectData.image.Version = VERSION_MAGIC2;
4710 object_record->ObjectData.image.Type = ImageDataTypeMetafile;
4711 metafile_record = &object_record->ObjectData.image.ImageData.metafile;
4712 metafile_record->Type = ((GpMetafile*)image)->metafile_type;
4713 metafile_record->MetafileDataSize = size;
4714 if (GetEnhMetaFileBits(hemf, size, metafile_record->MetafileData) != size)
4715 {
4716 METAFILE_RemoveLastRecord(metafile, &object_record->Header);
4717 return GenericError;
4718 }
4719 return Ok;
4720 }
4721 else
4722 {
4723 FIXME("not supported image type (%d)\n", image->type);
4724 return NotImplemented;
4725 }
4726}
4727
4729{
4730 EmfPlusObject *object_record;
4731 EmfPlusImageAttributes *attrs_record;
4732 GpStatus stat;
4733
4734 *id = -1;
4735
4736 if (metafile->metafile_type != MetafileTypeEmfPlusOnly && metafile->metafile_type != MetafileTypeEmfPlusDual)
4737 return Ok;
4738
4739 if (!attrs)
4740 return Ok;
4741
4744 (void**)&object_record);
4745 if (stat != Ok) return stat;
4746
4748 object_record->Header.Flags = *id | (ObjectTypeImageAttributes << 8);
4749 attrs_record = &object_record->ObjectData.image_attributes;
4750 attrs_record->Version = VERSION_MAGIC2;
4751 attrs_record->Reserved1 = 0;
4752 attrs_record->WrapMode = attrs->wrap;
4753 attrs_record->ClampColor = attrs->outside_color;
4754 attrs_record->ObjectClamp = attrs->clamp;
4755 attrs_record->Reserved2 = 0;
4756 return Ok;
4757}
4758
4760 GDIPCONST GpPointF *points, INT count, REAL srcx, REAL srcy, REAL srcwidth,
4761 REAL srcheight, GpUnit srcUnit, GDIPCONST GpImageAttributes* imageAttributes,
4762 DrawImageAbort callback, VOID *callbackData)
4763{
4764 EmfPlusDrawImagePoints *draw_image_record;
4765 DWORD image_id, attributes_id;
4766 GpStatus stat;
4767
4768 if (count != 3) return InvalidParameter;
4769
4770 if (metafile->metafile_type == MetafileTypeEmf)
4771 {
4772 FIXME("MetafileTypeEmf metafiles not supported\n");
4773 return NotImplemented;
4774 }
4775 else
4776 FIXME("semi-stub\n");
4777
4778 if (!imageAttributes)
4779 {
4781 }
4782 else if (image->type == ImageTypeBitmap)
4783 {
4784 INT width = ((GpBitmap*)image)->width;
4785 INT height = ((GpBitmap*)image)->height;
4786 GpGraphics *graphics;
4788
4791 if (stat != Ok) return stat;
4792
4794 if (stat != Ok)
4795 {
4797 return stat;
4798 }
4799
4800 stat = GdipDrawImageRectRectI(graphics, image, 0, 0, width, height,
4801 0, 0, width, height, UnitPixel, imageAttributes, NULL, NULL);
4802 GdipDeleteGraphics(graphics);
4803 if (stat != Ok)
4804 {
4806 return stat;
4807 }
4808
4811 }
4812 else
4813 {
4814 FIXME("imageAttributes not supported (image type %d)\n", image->type);
4815 return NotImplemented;
4816 }
4817 if (stat != Ok) return stat;
4818
4819 stat = METAFILE_AddImageAttributesObject(metafile, imageAttributes, &attributes_id);
4820 if (stat != Ok) return stat;
4821
4823 sizeof(EmfPlusDrawImagePoints), (void **)&draw_image_record);
4824 if (stat != Ok) return stat;
4825
4826 draw_image_record->Header.Flags = image_id;
4827 draw_image_record->ImageAttributesID = attributes_id;
4828 draw_image_record->SrcUnit = UnitPixel;
4829 draw_image_record->SrcRect.X = units_to_pixels(srcx, srcUnit, metafile->image.xres, metafile->printer_display);
4830 draw_image_record->SrcRect.Y = units_to_pixels(srcy, srcUnit, metafile->image.yres, metafile->printer_display);
4831 draw_image_record->SrcRect.Width = units_to_pixels(srcwidth, srcUnit, metafile->image.xres, metafile->printer_display);
4832 draw_image_record->SrcRect.Height = units_to_pixels(srcheight, srcUnit, metafile->image.yres, metafile->printer_display);
4833 draw_image_record->count = 3;
4834 memcpy(draw_image_record->PointData.pointsF, points, 3 * sizeof(*points));
4836 return Ok;
4837}
4838
4840{
4842 GpStatus stat;
4843
4844 if (metafile->metafile_type != MetafileTypeEmfPlusOnly && metafile->metafile_type != MetafileTypeEmfPlusDual)
4845 return Ok;
4846
4847 stat = METAFILE_AllocateRecord(metafile, prop, sizeof(*record), (void**)&record);
4848 if (stat != Ok) return stat;
4849
4850 record->Flags = val;
4851
4853 return Ok;
4854}
4855
4857{
4858 EmfPlusObject *object_record;
4859 GpStatus stat;
4860 DWORD size;
4861
4862 *id = -1;
4863 if (metafile->metafile_type != MetafileTypeEmfPlusOnly && metafile->metafile_type != MetafileTypeEmfPlusDual)
4864 return Ok;
4865
4868 FIELD_OFFSET(EmfPlusObject, ObjectData.path) + size,
4869 (void**)&object_record);
4870 if (stat != Ok) return stat;
4871
4873 object_record->Header.Flags = *id | ObjectTypePath << 8;
4874 write_path_data(path, &object_record->ObjectData.path);
4875 return Ok;
4876}
4877
4879{
4880 DWORD custom_start_cap_size = 0, custom_start_cap_data_size = 0, custom_start_cap_path_size = 0;
4881 DWORD custom_end_cap_size = 0, custom_end_cap_data_size = 0, custom_end_cap_path_size = 0;
4882 DWORD i, data_flags, pen_data_size, brush_size;
4883 EmfPlusObject *object_record;
4884 EmfPlusPenData *pen_data;
4885 GpStatus stat;
4886 BOOL result;
4887
4888 *id = -1;
4889 if (metafile->metafile_type != MetafileTypeEmfPlusOnly && metafile->metafile_type != MetafileTypeEmfPlusDual)
4890 return Ok;
4891
4892 data_flags = 0;
4893 pen_data_size = FIELD_OFFSET(EmfPlusPenData, OptionalData);
4894
4896 if (!result)
4897 {
4898 data_flags |= PenDataTransform;
4899 pen_data_size += sizeof(EmfPlusTransformMatrix);
4900 }
4901 if (pen->startcap != LineCapFlat)
4902 {
4903 data_flags |= PenDataStartCap;
4904 pen_data_size += sizeof(DWORD);
4905 }
4906 if (pen->endcap != LineCapFlat)
4907 {
4908 data_flags |= PenDataEndCap;
4909 pen_data_size += sizeof(DWORD);
4910 }
4911 if (pen->join != LineJoinMiter)
4912 {
4913 data_flags |= PenDataJoin;
4914 pen_data_size += sizeof(DWORD);
4915 }
4916 if (pen->miterlimit != 10.0)
4917 {
4918 data_flags |= PenDataMiterLimit;
4919 pen_data_size += sizeof(REAL);
4920 }
4921 if (pen->style != GP_DEFAULT_PENSTYLE)
4922 {
4923 data_flags |= PenDataLineStyle;
4924 pen_data_size += sizeof(DWORD);
4925 }
4926 if (pen->dashcap != DashCapFlat)
4927 {
4928 data_flags |= PenDataDashedLineCap;
4929 pen_data_size += sizeof(DWORD);
4930 }
4931 data_flags |= PenDataDashedLineOffset;
4932 pen_data_size += sizeof(REAL);
4933 if (pen->numdashes)
4934 {
4935 data_flags |= PenDataDashedLine;
4936 pen_data_size += sizeof(DWORD) + pen->numdashes*sizeof(REAL);
4937 }
4938 if (pen->align != PenAlignmentCenter)
4939 {
4940 data_flags |= PenDataNonCenter;
4941 pen_data_size += sizeof(DWORD);
4942 }
4943 /* TODO: Add support for PenDataCompoundLine */
4944 if (pen->customstart)
4945 {
4946 data_flags |= PenDataCustomStartCap;
4947 METAFILE_PrepareCustomLineCapData(pen->customstart, &custom_start_cap_size,
4948 &custom_start_cap_data_size, &custom_start_cap_path_size);
4949 pen_data_size += custom_start_cap_size;
4950 }
4951 if (pen->customend)
4952 {
4953 data_flags |= PenDataCustomEndCap;
4954 METAFILE_PrepareCustomLineCapData(pen->customend, &custom_end_cap_size,
4955 &custom_end_cap_data_size, &custom_end_cap_path_size);
4956 pen_data_size += custom_end_cap_size;
4957 }
4958
4959 stat = METAFILE_PrepareBrushData(pen->brush, &brush_size);
4960 if (stat != Ok) return stat;
4961
4963 FIELD_OFFSET(EmfPlusObject, ObjectData.pen.data) + pen_data_size + brush_size,
4964 (void**)&object_record);
4965 if (stat != Ok) return stat;
4966
4968 object_record->Header.Flags = *id | ObjectTypePen << 8;
4969 object_record->ObjectData.pen.Version = VERSION_MAGIC2;
4970 object_record->ObjectData.pen.Type = 0;
4971
4972 pen_data = (EmfPlusPenData*)object_record->ObjectData.pen.data;
4973 pen_data->PenDataFlags = data_flags;
4974 pen_data->PenUnit = pen->unit;
4975 pen_data->PenWidth = pen->width;
4976
4977 i = 0;
4978 if (data_flags & PenDataTransform)
4979 {
4981 memcpy(m, &pen->transform, sizeof(*m));
4982 i += sizeof(EmfPlusTransformMatrix);
4983 }
4984 if (data_flags & PenDataStartCap)
4985 {
4986 *(DWORD*)(pen_data->OptionalData + i) = pen->startcap;
4987 i += sizeof(DWORD);
4988 }
4989 if (data_flags & PenDataEndCap)
4990 {
4991 *(DWORD*)(pen_data->OptionalData + i) = pen->endcap;
4992 i += sizeof(DWORD);
4993 }
4994 if (data_flags & PenDataJoin)
4995 {
4996 *(DWORD*)(pen_data->OptionalData + i) = pen->join;
4997 i += sizeof(DWORD);
4998 }
4999 if (data_flags & PenDataMiterLimit)
5000 {
5001 *(REAL*)(pen_data->OptionalData + i) = pen->miterlimit;
5002 i += sizeof(REAL);
5003 }
5004 if (data_flags & PenDataLineStyle)
5005 {
5006 switch (pen->style & PS_STYLE_MASK)
5007 {
5008 case PS_SOLID: *(DWORD*)(pen_data->OptionalData + i) = LineStyleSolid; break;
5009 case PS_DASH: *(DWORD*)(pen_data->OptionalData + i) = LineStyleDash; break;
5010 case PS_DOT: *(DWORD*)(pen_data->OptionalData + i) = LineStyleDot; break;
5011 case PS_DASHDOT: *(DWORD*)(pen_data->OptionalData + i) = LineStyleDashDot; break;
5012 case PS_DASHDOTDOT: *(DWORD*)(pen_data->OptionalData + i) = LineStyleDashDotDot; break;
5013 default: *(DWORD*)(pen_data->OptionalData + i) = LineStyleCustom; break;
5014 }
5015 i += sizeof(DWORD);
5016 }
5017 if (data_flags & PenDataDashedLineCap)
5018 {
5019 *(DWORD*)(pen_data->OptionalData + i) = pen->dashcap;
5020 i += sizeof(DWORD);
5021 }
5022 if (data_flags & PenDataDashedLineOffset)
5023 {
5024 *(REAL*)(pen_data->OptionalData + i) = pen->offset;
5025 i += sizeof(REAL);
5026 }
5027 if (data_flags & PenDataDashedLine)
5028 {
5029 int j;
5030
5031 *(DWORD*)(pen_data->OptionalData + i) = pen->numdashes;
5032 i += sizeof(DWORD);
5033
5034 for (j=0; j<pen->numdashes; j++)
5035 {
5036 *(REAL*)(pen_data->OptionalData + i) = pen->dashes[j];
5037 i += sizeof(REAL);
5038 }
5039 }
5040 if (data_flags & PenDataNonCenter)
5041 {
5042 *(REAL*)(pen_data->OptionalData + i) = pen->align;
5043 i += sizeof(DWORD);
5044 }
5045 if (data_flags & PenDataCustomStartCap)
5046 {
5048 pen->miterlimit, custom_start_cap_data_size,
5049 custom_start_cap_path_size);
5050 i += custom_start_cap_size;
5051 }
5052 if (data_flags & PenDataCustomEndCap)
5053 {
5055 pen->miterlimit, custom_end_cap_data_size,
5056 custom_end_cap_path_size);
5057 i += custom_end_cap_size;
5058 }
5059
5061 (EmfPlusBrush*)(object_record->ObjectData.pen.data + pen_data_size));
5062 return Ok;
5063}
5064
5066{
5067 EmfPlusDrawPath *draw_path_record;
5068 DWORD path_id;
5069 DWORD pen_id;
5070 GpStatus stat;
5071
5072 if (metafile->metafile_type == MetafileTypeEmf)
5073 {
5074 FIXME("stub!\n");
5075 return NotImplemented;
5076 }
5077
5078 stat = METAFILE_AddPenObject(metafile, pen, &pen_id);
5079 if (stat != Ok) return stat;
5080
5082 if (stat != Ok) return stat;
5083
5085 sizeof(EmfPlusDrawPath), (void **)&draw_path_record);
5086 if (stat != Ok) return stat;
5087 draw_path_record->Header.Type = EmfPlusRecordTypeDrawPath;
5088 draw_path_record->Header.Flags = path_id;
5089 draw_path_record->PenId = pen_id;
5090
5092 return Ok;
5093}
5094
5096{
5098 BOOL is_int_rect;
5099 GpStatus stat;
5100 DWORD pen_id;
5101
5102 if (metafile->metafile_type == MetafileTypeEmf)
5103 {
5104 FIXME("stub!\n");
5105 return NotImplemented;
5106 }
5107
5108 stat = METAFILE_AddPenObject(metafile, pen, &pen_id);
5109 if (stat != Ok) return stat;
5110
5111 is_int_rect = is_integer_rect(rect);
5112
5114 FIELD_OFFSET(EmfPlusDrawEllipse, RectData) + (is_int_rect ? sizeof(EmfPlusRect) : sizeof(EmfPlusRectF)),
5115 (void **)&record);
5116 if (stat != Ok) return stat;
5117 record->Header.Type = EmfPlusRecordTypeDrawEllipse;
5118 record->Header.Flags = pen_id;
5119 if (is_int_rect)
5120 {
5121 record->Header.Flags |= 0x4000;
5122 record->RectData.rect.X = (SHORT)rect->X;
5123 record->RectData.rect.Y = (SHORT)rect->Y;
5124 record->RectData.rect.Width = (SHORT)rect->Width;
5125 record->RectData.rect.Height = (SHORT)rect->Height;
5126 }
5127 else
5128 memcpy(&record->RectData.rectF, rect, sizeof(*rect));
5129
5131 return Ok;
5132}
5133
5135{
5136 EmfPlusFillPath *fill_path_record;
5137 DWORD brush_id = -1, path_id;
5138 BOOL inline_color;
5139 GpStatus stat;
5140
5141 if (metafile->metafile_type == MetafileTypeEmf)
5142 {
5143 FIXME("stub!\n");
5144 return NotImplemented;
5145 }
5146
5147 inline_color = brush->bt == BrushTypeSolidColor;
5148 if (!inline_color)
5149 {
5150 stat = METAFILE_AddBrushObject(metafile, brush, &brush_id);
5151 if (stat != Ok) return stat;
5152 }
5153
5155 if (stat != Ok) return stat;
5156
5158 sizeof(EmfPlusFillPath), (void**)&fill_path_record);
5159 if (stat != Ok) return stat;
5160 if (inline_color)
5161 {
5162 fill_path_record->Header.Flags = 0x8000 | path_id;
5163 fill_path_record->data.Color = ((GpSolidFill *)brush)->color;
5164 }
5165 else
5166 {
5167 fill_path_record->Header.Flags = path_id;
5168 fill_path_record->data.BrushId = brush_id;
5169 }
5170
5172 return Ok;
5173}
5174
5176{
5177 BOOL is_int_rect, inline_color;
5179 DWORD brush_id = -1;
5180 GpStatus stat;
5181
5182 if (metafile->metafile_type == MetafileTypeEmf)
5183 {
5184 FIXME("stub!\n");
5185 return NotImplemented;
5186 }
5187
5188 inline_color = brush->bt == BrushTypeSolidColor;
5189 if (!inline_color)
5190 {
5191 stat = METAFILE_AddBrushObject(metafile, brush, &brush_id);
5192 if (stat != Ok) return stat;
5193 }
5194
5195 is_int_rect = is_integer_rect(rect);
5196
5198 FIELD_OFFSET(EmfPlusFillEllipse, RectData) + (is_int_rect ? sizeof(EmfPlusRect) : sizeof(EmfPlusRectF)),
5199 (void **)&record);
5200 if (stat != Ok) return stat;
5201 if (inline_color)
5202 {
5203 record->Header.Flags = 0x8000;
5204 record->BrushId = ((GpSolidFill *)brush)->color;
5205 }
5206 else
5207 record->BrushId = brush_id;
5208
5209 if (is_int_rect)
5210 {
5211 record->Header.Flags |= 0x4000;
5212 record->RectData.rect.X = (SHORT)rect->X;
5213 record->RectData.rect.Y = (SHORT)rect->Y;
5214 record->RectData.rect.Width = (SHORT)rect->Width;
5215 record->RectData.rect.Height = (SHORT)rect->Height;
5216 }
5217 else
5218 memcpy(&record->RectData.rectF, rect, sizeof(*rect));
5219
5221 return Ok;
5222}
5223
5225 REAL startAngle, REAL sweepAngle)
5226{
5227 BOOL is_int_rect, inline_color;
5229 DWORD brush_id = -1;
5230 GpStatus stat;
5231
5232 if (metafile->metafile_type == MetafileTypeEmf)
5233 {
5234 FIXME("stub!\n");
5235 return NotImplemented;
5236 }
5237
5238 inline_color = brush->bt == BrushTypeSolidColor;
5239 if (!inline_color)
5240 {
5241 stat = METAFILE_AddBrushObject(metafile, brush, &brush_id);
5242 if (stat != Ok) return stat;
5243 }
5244
5245 is_int_rect = is_integer_rect(rect);
5246
5248 FIELD_OFFSET(EmfPlusFillPie, RectData) + (is_int_rect ? sizeof(EmfPlusRect) : sizeof(EmfPlusRectF)),
5249 (void **)&record);
5250 if (stat != Ok) return stat;
5251 if (inline_color)
5252 {
5253 record->Header.Flags = 0x8000;
5254 record->BrushId = ((GpSolidFill *)brush)->color;
5255 }
5256 else
5257 record->BrushId = brush_id;
5258
5259 record->StartAngle = startAngle;
5260 record->SweepAngle = sweepAngle;
5261
5262 if (is_int_rect)
5263 {
5264 record->Header.Flags |= 0x4000;
5265 record->RectData.rect.X = (SHORT)rect->X;
5266 record->RectData.rect.Y = (SHORT)rect->Y;
5267 record->RectData.rect.Width = (SHORT)rect->Width;
5268 record->RectData.rect.Height = (SHORT)rect->Height;
5269 }
5270 else
5271 memcpy(&record->RectData.rectF, rect, sizeof(*rect));
5272
5274 return Ok;
5275}
5276
5278{
5279 EmfPlusObject *object_record;
5280 EmfPlusFont *font_record;
5281 GpStatus stat;
5282 INT fn_len;
5283 INT style;
5284
5285 *id = -1;
5286
5287 if (metafile->metafile_type != MetafileTypeEmfPlusOnly &&
5288 metafile->metafile_type != MetafileTypeEmfPlusDual)
5289 return Ok;
5290
5291 /* The following cast is ugly, but GdipGetFontStyle does treat
5292 its first parameter as const. */
5294 if (stat != Ok)
5295 return stat;
5296
5297 fn_len = lstrlenW(font->family->FamilyName);
5299 FIELD_OFFSET(EmfPlusObject, ObjectData.font.FamilyName[(fn_len + 1) & ~1]),
5300 (void**)&object_record);
5301 if (stat != Ok)
5302 return stat;
5303
5305
5306 object_record->Header.Flags = *id | ObjectTypeFont << 8;
5307
5308 font_record = &object_record->ObjectData.font;
5309 font_record->Version = VERSION_MAGIC2;
5310 font_record->EmSize = font->emSize;
5311 font_record->SizeUnit = font->unit;
5312 font_record->FontStyleFlags = style;
5313 font_record->Reserved = 0;
5314 font_record->Length = fn_len;
5315
5316 memcpy(font_record->FamilyName, font->family->FamilyName,
5317 fn_len * sizeof(*font->family->FamilyName));
5318
5319 return Ok;
5320}
5321
5325{
5326 DWORD brush_id;
5327 DWORD font_id;
5328 DWORD alloc_size;
5329 GpStatus stat;
5330 EmfPlusDrawDriverString *draw_string_record;
5331 BYTE *cursor;
5332 BOOL inline_color;
5333 BOOL include_matrix = FALSE;
5334
5335 if (length <= 0)
5336 return InvalidParameter;
5337
5338 if (metafile->metafile_type != MetafileTypeEmfPlusOnly &&
5339 metafile->metafile_type != MetafileTypeEmfPlusDual)
5340 {
5341 FIXME("metafile type not supported: %i\n", metafile->metafile_type);
5342 return NotImplemented;
5343 }
5344
5346 if (stat != Ok)
5347 return stat;
5348
5349 inline_color = (brush->bt == BrushTypeSolidColor);
5350 if (!inline_color)
5351 {
5352 stat = METAFILE_AddBrushObject(metafile, brush, &brush_id);
5353 if (stat != Ok)
5354 return stat;
5355 }
5356
5357 if (matrix)
5358 {
5359 BOOL identity;
5360
5362 if (stat != Ok)
5363 return stat;
5364
5365 include_matrix = !identity;
5366 }
5367
5368 alloc_size = FIELD_OFFSET(EmfPlusDrawDriverString, VariableData) +
5369 length * (sizeof(*text) + sizeof(*positions));
5370
5371 if (include_matrix)
5372 alloc_size += sizeof(*matrix);
5373
5374 /* Pad record to DWORD alignment. */
5375 alloc_size = (alloc_size + 3) & ~3;
5376
5377 stat = METAFILE_AllocateRecord(metafile, EmfPlusRecordTypeDrawDriverString, alloc_size, (void**)&draw_string_record);
5378 if (stat != Ok)
5379 return stat;
5380
5381 draw_string_record->Header.Flags = font_id;
5382 draw_string_record->DriverStringOptionsFlags = flags;
5383 draw_string_record->MatrixPresent = include_matrix;
5384 draw_string_record->GlyphCount = length;
5385
5386 if (inline_color)
5387 {
5388 draw_string_record->Header.Flags |= 0x8000;
5389 draw_string_record->brush.Color = ((GpSolidFill*)brush)->color;
5390 }
5391 else
5392 draw_string_record->brush.BrushId = brush_id;
5393
5394 cursor = &draw_string_record->VariableData[0];
5395
5396 memcpy(cursor, text, length * sizeof(*text));
5397 cursor += length * sizeof(*text);
5398
5400 {
5401 static BOOL fixme_written = FALSE;
5402
5403 /* Native never writes DriverStringOptionsRealizedAdvance. Instead,
5404 in the case of RealizedAdvance, each glyph position is computed
5405 and serialized.
5406
5407 While native GDI+ is capable of playing back metafiles with this
5408 flag set, it is possible that some application might rely on
5409 metafiles produced from GDI+ not setting this flag. Ideally we
5410 would also compute the position of each glyph here, serialize those
5411 values, and not set DriverStringOptionsRealizedAdvance. */
5412 if (!fixme_written)
5413 {
5414 fixme_written = TRUE;
5415 FIXME("serializing RealizedAdvance flag and single GlyphPos with padding\n");
5416 }
5417
5418 *((PointF*)cursor) = *positions;
5419 }
5420 else
5421 memcpy(cursor, positions, length * sizeof(*positions));
5422
5423 if (include_matrix)
5424 {
5425 cursor += length * sizeof(*positions);
5426 memcpy(cursor, matrix, sizeof(*matrix));
5427 }
5428
5430
5431 return Ok;
5432}
5433
5435{
5436 GpStatus stat;
5437 DWORD brush_id;
5438 DWORD region_id;
5439 EmfPlusFillRegion *fill_region_record;
5440 BOOL inline_color;
5441
5442 if (metafile->metafile_type != MetafileTypeEmfPlusOnly &&
5443 metafile->metafile_type != MetafileTypeEmfPlusDual)
5444 {
5445 FIXME("metafile type not supported: %i\n", metafile->metafile_type);
5446 return NotImplemented;
5447 }
5448
5449 inline_color = (brush->bt == BrushTypeSolidColor);
5450 if (!inline_color)
5451 {
5452 stat = METAFILE_AddBrushObject(metafile, brush, &brush_id);
5453 if (stat != Ok)
5454 return stat;
5455 }
5456
5457 stat = METAFILE_AddRegionObject(metafile, region, &region_id);
5458 if (stat != Ok)
5459 return stat;
5460
5462 (void**)&fill_region_record);
5463 if (stat != Ok)
5464 return stat;
5465
5466 fill_region_record->Header.Flags = region_id;
5467
5468 if (inline_color)
5469 {
5470 fill_region_record->Header.Flags |= 0x8000;
5471 fill_region_record->data.Color = ((GpSolidFill*)brush)->color;
5472 }
5473 else
5474 fill_region_record->data.BrushId = brush_id;
5475
5477
5478 return Ok;
5479}
5480
5482{
5484 GpStatus stat;
5485 BOOL integer_rects = TRUE;
5486 DWORD pen_id;
5487 int i;
5488
5489 if (metafile->metafile_type == MetafileTypeEmf)
5490 {
5491 FIXME("stub!\n");
5492 return NotImplemented;
5493 }
5494
5495 stat = METAFILE_AddPenObject(metafile, pen, &pen_id);
5496 if (stat != Ok) return stat;
5497
5498 for (i = 0; i < count; i++)
5499 {
5500 if (!is_integer_rect(&rects[i]))
5501 {
5502 integer_rects = FALSE;
5503 break;
5504 }
5505 }
5506
5508 count * (integer_rects ? sizeof(record->RectData.rect) : sizeof(record->RectData.rectF)),
5509 (void **)&record);
5510 if (stat != Ok)
5511 return stat;
5512
5513 record->Header.Flags = pen_id;
5514 if (integer_rects)
5515 record->Header.Flags |= 0x4000;
5516 record->Count = count;
5517
5518 if (integer_rects)
5519 {
5520 for (i = 0; i < count; i++)
5521 {
5522 record->RectData.rect[i].X = (SHORT)rects[i].X;
5523 record->RectData.rect[i].Y = (SHORT)rects[i].Y;
5524 record->RectData.rect[i].Width = (SHORT)rects[i].Width;
5525 record->RectData.rect[i].Height = (SHORT)rects[i].Height;
5526 }
5527 }
5528 else
5529 memcpy(record->RectData.rectF, rects, sizeof(*rects) * count);
5530
5532
5533 return Ok;
5534}
5535
5536GpStatus METAFILE_DrawArc(GpMetafile *metafile, GpPen *pen, const GpRectF *rect, REAL startAngle, REAL sweepAngle)
5537{
5539 GpStatus stat;
5540 BOOL integer_rect;
5541 DWORD pen_id;
5542
5543 if (metafile->metafile_type == MetafileTypeEmf)
5544 {
5545 FIXME("stub!\n");
5546 return NotImplemented;
5547 }
5548
5549 stat = METAFILE_AddPenObject(metafile, pen, &pen_id);
5550 if (stat != Ok) return stat;
5551
5552 integer_rect = is_integer_rect(rect);
5553
5555 (integer_rect ? sizeof(record->RectData.rect) : sizeof(record->RectData.rectF)),
5556 (void **)&record);
5557 if (stat != Ok)
5558 return stat;
5559
5560 record->Header.Flags = pen_id;
5561 if (integer_rect)
5562 record->Header.Flags |= 0x4000;
5563 record->StartAngle = startAngle;
5564 record->SweepAngle = sweepAngle;
5565
5566 if (integer_rect)
5567 {
5568 record->RectData.rect.X = (SHORT)rect->X;
5569 record->RectData.rect.Y = (SHORT)rect->Y;
5570 record->RectData.rect.Width = (SHORT)rect->Width;
5571 record->RectData.rect.Height = (SHORT)rect->Height;
5572 }
5573 else
5574 memcpy(&record->RectData.rectF, rect, sizeof(*rect));
5575
5577
5578 return Ok;
5579}
5580
5582{
5584 GpStatus stat;
5585
5586 if (metafile->metafile_type == MetafileTypeEmf)
5587 {
5588 FIXME("stub!\n");
5589 return NotImplemented;
5590 }
5591
5593 sizeof(*record), (void **)&record);
5594 if (stat != Ok)
5595 return stat;
5596
5597 record->dx = dx;
5598 record->dy = dy;
5599
5601
5602 return Ok;
5603}
5604
5606{
5608 GpStatus stat;
5609
5610 if (metafile->metafile_type == MetafileTypeEmf)
5611 {
5612 FIXME("stub!\n");
5613 return NotImplemented;
5614 }
5615
5617 sizeof(*record), (void **)&record);
5618 if (stat != Ok)
5619 return stat;
5620
5622
5623 return Ok;
5624}
5625
5627{
5629 DWORD path_id;
5630 GpStatus stat;
5631
5632 if (metafile->metafile_type == MetafileTypeEmf)
5633 {
5634 FIXME("stub!\n");
5635 return NotImplemented;
5636 }
5637
5639 if (stat != Ok) return stat;
5640
5642 sizeof(*record), (void **)&record);
5643 if (stat != Ok)
5644 return stat;
5645
5646 record->Flags = ((mode & 0xf) << 8) | path_id;
5647
5649
5650 return Ok;
5651}
5652
5654{
5656 GpStatus stat;
5657
5658 if (metafile->metafile_type == MetafileTypeEmf)
5659 {
5660 FIXME("stub!\n");
5661 return NotImplemented;
5662 }
5663
5665 sizeof(*record), (void **)&record);
5666 if (stat != Ok)
5667 return stat;
5668
5669 record->x = x;
5670 record->y = y;
5671
5673
5674 return Ok;
5675}
static HDC hDC
Definition: 3dtext.c:33
_STLP_MOVE_TO_STD_NAMESPACE void fill(_ForwardIter __first, _ForwardIter __last, const _Tp &__val)
Definition: _algobase.h:449
unsigned short UINT16
Definition: actypes.h:129
#define stat
Definition: acwin.h:100
#define read
Definition: acwin.h:97
Arabic default style
Definition: afstyles.h:94
static int state
Definition: maze.c:121
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define ARRAY_SIZE(A)
Definition: main.h:20
static void list_remove(struct list_entry *entry)
Definition: list.h:90
static void list_add_head(struct list_entry *head, struct list_entry *entry)
Definition: list.h:76
static void list_init(struct list_entry *head)
Definition: list.h:51
INT copy(TCHAR source[MAX_PATH], TCHAR dest[MAX_PATH], INT append, DWORD lpdwFlags, BOOL bTouch)
Definition: copy.c:51
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
Definition: list.h:37
RECT rect
Definition: combotst.c:67
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
HRESULT hr
Definition: delayimp.cpp:582
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static unsigned int palette_size(DWORD flags)
Definition: palette.c:241
float REAL
Definition: types.h:41
#define Y(I)
HRESULT WINAPI CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL delete_on_release, IStream **stream)
#define GENERIC_READ
Definition: compat.h:135
#define CALLBACK
Definition: compat.h:35
#define lstrlenW
Definition: compat.h:750
GpStatus WINGDIPAPI GdipCreateLineBrushFromRect(GDIPCONST GpRectF *rect, ARGB startcolor, ARGB endcolor, LinearGradientMode mode, GpWrapMode wrap, GpLineGradient **line)
Definition: brush.c:462
GpStatus WINGDIPAPI GdipDeleteBrush(GpBrush *brush)
Definition: brush.c:1020
GpStatus WINGDIPAPI GdipCreateHatchBrush(GpHatchStyle hatchstyle, ARGB forecol, ARGB backcol, GpHatch **brush)
Definition: brush.c:302
GpStatus WINGDIPAPI GdipSetTextureTransform(GpTexture *texture, GDIPCONST GpMatrix *matrix)
Definition: brush.c:1965
GpStatus WINGDIPAPI GdipSetLinePresetBlend(GpLineGradient *brush, GDIPCONST ARGB *blend, GDIPCONST REAL *positions, INT count)
Definition: brush.c:2068
GpStatus WINGDIPAPI GdipSetLineTransform(GpLineGradient *brush, GDIPCONST GpMatrix *matrix)
Definition: brush.c:2142
GpStatus WINGDIPAPI GdipSetLineBlend(GpLineGradient *brush, GDIPCONST REAL *factors, GDIPCONST REAL *positions, INT count)
Definition: brush.c:1395
GpStatus WINGDIPAPI GdipCreateSolidFill(ARGB color, GpSolidFill **sf)
Definition: brush.c:783
GpStatus WINGDIPAPI GdipCreateTexture(GpImage *image, GpWrapMode wrapmode, GpTexture **texture)
Definition: brush.c:812
GpStatus WINGDIPAPI GdipSetCustomLineCapStrokeCaps(GpCustomLineCap *custom, GpLineCap startcap, GpLineCap endcap)
GpStatus WINGDIPAPI GdipSetCustomLineCapWidthScale(GpCustomLineCap *custom, REAL width)
GpStatus WINGDIPAPI GdipCreateCustomLineCap(GpPath *fillPath, GpPath *strokePath, GpLineCap baseCap, REAL baseInset, GpCustomLineCap **customCap)
GpStatus WINGDIPAPI GdipDeleteCustomLineCap(GpCustomLineCap *customCap)
GpStatus WINGDIPAPI GdipCreateAdjustableArrowCap(REAL height, REAL width, BOOL fill, GpAdjustableArrowCap **cap)
GpStatus WINGDIPAPI GdipSetCustomLineCapStrokeJoin(GpCustomLineCap *custom, GpLineJoin join)
GpStatus WINGDIPAPI GdipSetAdjustableArrowCapMiddleInset(GpAdjustableArrowCap *cap, REAL middle)
GpStatus WINGDIPAPI GdipDeleteFontFamily(GpFontFamily *FontFamily)
Definition: font.c:821
GpStatus WINGDIPAPI GdipDeleteFont(GpFont *font)
Definition: font.c:272
GpStatus WINGDIPAPI GdipGetFontStyle(GpFont *font, INT *style)
Definition: font.c:395
GpStatus WINGDIPAPI GdipGetGenericFontFamilySansSerif(GpFontFamily **nativeFamily)
Definition: font.c:1029
GpStatus WINGDIPAPI GdipCreateFont(GDIPCONST GpFontFamily *fontFamily, REAL emSize, INT style, Unit unit, GpFont **font)
Definition: font.c:150
GpStatus WINGDIPAPI GdipCreateFontFamilyFromName(GDIPCONST WCHAR *name, GpFontCollection *collection, GpFontFamily **family)
Definition: font.c:701
GpStatus WINGDIPAPI GdipFillRectangles(GpGraphics *graphics, GpBrush *brush, GDIPCONST GpRectF *rects, INT count)
Definition: graphics.c:4704
GpStatus WINGDIPAPI GdipCreateStreamOnFile(GDIPCONST WCHAR *filename, UINT access, IStream **stream)
Definition: graphics.c:2593
GpStatus WINGDIPAPI GdipDrawEllipseI(GpGraphics *graphics, GpPen *pen, INT x, INT y, INT width, INT height)
Definition: graphics.c:3017
GpStatus WINGDIPAPI GdipFillRegion(GpGraphics *graphics, GpBrush *brush, GpRegion *region)
Definition: graphics.c:4891
GpStatus WINGDIPAPI GdipDeleteGraphics(GpGraphics *graphics)
Definition: graphics.c:2616
GpStatus WINGDIPAPI GdipFillEllipse(GpGraphics *graphics, GpBrush *brush, REAL x, REAL y, REAL width, REAL height)
Definition: graphics.c:4416
GpStatus WINGDIPAPI GdipGetClip(GpGraphics *graphics, GpRegion *region)
Definition: graphics.c:7195
GpStatus WINGDIPAPI GdipSetCompositingMode(GpGraphics *graphics, CompositingMode mode)
Definition: graphics.c:6440
GpStatus WINGDIPAPI GdipFillClosedCurve2(GpGraphics *graphics, GpBrush *brush, GDIPCONST GpPointF *points, INT count, REAL tension, GpFillMode fill)
Definition: graphics.c:4339
GpStatus WINGDIPAPI GdipDrawPie(GpGraphics *graphics, GpPen *pen, REAL x, REAL y, REAL width, REAL height, REAL startAngle, REAL sweepAngle)
Definition: graphics.c:4232
GpStatus WINGDIPAPI GdipGetDC(GpGraphics *graphics, HDC *hdc)
Definition: graphics.c:7050
GpStatus WINGDIPAPI GdipGraphicsClear(GpGraphics *graphics, ARGB color)
Definition: graphics.c:5229
GpStatus WINGDIPAPI GdipDrawRectangles(GpGraphics *graphics, GpPen *pen, GDIPCONST GpRectF *rects, INT count)
Definition: graphics.c:4286
GpStatus WINGDIPAPI GdipFillPie(GpGraphics *graphics, GpBrush *brush, REAL x, REAL y, REAL width, REAL height, REAL startAngle, REAL sweepAngle)
Definition: graphics.c:4562
GpStatus WINGDIPAPI GdipSetTextRenderingHint(GpGraphics *graphics, TextRenderingHint hint)
Definition: graphics.c:6696
GpStatus WINGDIPAPI GdipDrawDriverString(GpGraphics *graphics, GDIPCONST UINT16 *text, INT length, GDIPCONST GpFont *font, GDIPCONST GpBrush *brush, GDIPCONST PointF *positions, INT flags, GDIPCONST GpMatrix *matrix)
Definition: graphics.c:7903
GpStatus WINGDIPAPI GdipSetWorldTransform(GpGraphics *graphics, GpMatrix *matrix)
Definition: graphics.c:6724
GpStatus WINGDIPAPI GdipDrawImageRectRectI(GpGraphics *graphics, GpImage *image, INT dstx, INT dsty, INT dstwidth, INT dstheight, INT srcx, INT srcy, INT srcwidth, INT srcheight, GpUnit srcUnit, GDIPCONST GpImageAttributes *imageAttributes, DrawImageAbort callback, VOID *callbackData)
Definition: graphics.c:3574
GpStatus WINGDIPAPI GdipSaveGraphics(GpGraphics *graphics, GraphicsState *state)
Definition: graphics.c:6267
GpStatus WINGDIPAPI GdipDrawPath(GpGraphics *graphics, GpPen *pen, GpPath *path)
Definition: graphics.c:4207
GpStatus WINGDIPAPI GdipEndContainer(GpGraphics *graphics, GraphicsContainer state)
Definition: graphics.c:6394
GpStatus WINGDIPAPI GdipSetCompositingQuality(GpGraphics *graphics, CompositingQuality quality)
Definition: graphics.c:6469
GpStatus WINGDIPAPI GdipSetInterpolationMode(GpGraphics *graphics, InterpolationMode mode)
Definition: graphics.c:6498
GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image, GDIPCONST GpPointF *points, INT count, REAL srcx, REAL srcy, REAL srcwidth, REAL srcheight, GpUnit srcUnit, GDIPCONST GpImageAttributes *imageAttributes, DrawImageAbort callback, VOID *callbackData)
Definition: graphics.c:3173
GpStatus WINGDIPAPI GdipDrawEllipse(GpGraphics *graphics, GpPen *pen, REAL x, REAL y, REAL width, REAL height)
Definition: graphics.c:2985
GpStatus WINGDIPAPI GdipFillPath(GpGraphics *graphics, GpBrush *brush, GpPath *path)
Definition: graphics.c:4529
GpStatus WINGDIPAPI GdipDrawPieI(GpGraphics *graphics, GpPen *pen, INT x, INT y, INT width, INT height, REAL startAngle, REAL sweepAngle)
Definition: graphics.c:4258
GpStatus WINGDIPAPI GdipReleaseDC(GpGraphics *graphics, HDC hdc)
Definition: graphics.c:7141
GpStatus WINGDIPAPI GdipSetRenderingOrigin(GpGraphics *graphics, INT x, INT y)
Definition: graphics.c:6616
GpStatus WINGDIPAPI GdipDrawArc(GpGraphics *graphics, GpPen *pen, REAL x, REAL y, REAL width, REAL height, REAL startAngle, REAL sweepAngle)
Definition: graphics.c:2662
GpStatus WINGDIPAPI GdipDrawArcI(GpGraphics *graphics, GpPen *pen, INT x, INT y, INT width, INT height, REAL startAngle, REAL sweepAngle)
Definition: graphics.c:2695
GpStatus WINGDIPAPI GdipTransformPoints(GpGraphics *graphics, GpCoordinateSpace dst_space, GpCoordinateSpace src_space, GpPointF *points, INT count)
Definition: graphics.c:7356
GpStatus WINGDIPAPI GdipFillPieI(GpGraphics *graphics, GpBrush *brush, INT x, INT y, INT width, INT height, REAL startAngle, REAL sweepAngle)
Definition: graphics.c:4599
GpStatus WINGDIPAPI GdipRestoreGraphics(GpGraphics *graphics, GraphicsState state)
Definition: graphics.c:6400
GpStatus WINGDIPAPI GdipSetPageUnit(GpGraphics *graphics, GpUnit unit)
Definition: graphics.c:6560
GpStatus WINGDIPAPI GdipSetSmoothingMode(GpGraphics *graphics, SmoothingMode mode)
Definition: graphics.c:6654
GpStatus WINGDIPAPI GdipFillEllipseI(GpGraphics *graphics, GpBrush *brush, INT x, INT y, INT width, INT height)
Definition: graphics.c:4452
GpStatus WINGDIPAPI GdipSetPixelOffsetMode(GpGraphics *graphics, PixelOffsetMode mode)
Definition: graphics.c:6587
GpStatus WINGDIPAPI GdipResetWorldTransform(GpGraphics *graphics)
Definition: graphics.c:6194
GpStatus WINGDIPAPI GdipSetPageScale(GpGraphics *graphics, REAL scale)
Definition: graphics.c:6533
GpStatus WINGDIPAPI GdipBeginContainer2(GpGraphics *graphics, GraphicsContainer *state)
Definition: graphics.c:6273
GpStatus WINGDIPAPI GdipCreatePath(GpFillMode fill, GpPath **path)
GpStatus WINGDIPAPI GdipDeletePath(GpPath *path)
GpStatus WINGDIPAPI GdipCreatePath2(GDIPCONST GpPointF *points, GDIPCONST BYTE *types, INT count, GpFillMode fill, GpPath **path)
GpStatus WINGDIPAPI GdipAddPathPolygon(GpPath *path, GDIPCONST GpPointF *points, INT count)
Definition: graphicspath.c:932
GpStatus WINGDIPAPI GdipCreateBitmapFromScan0(INT width, INT height, INT stride, PixelFormat format, BYTE *scan0, GpBitmap **bitmap)
Definition: image.c:1793
GpStatus WINGDIPAPI GdipSetImagePalette(GpImage *image, GDIPCONST ColorPalette *palette)
Definition: image.c:4984
GpStatus WINGDIPAPI GdipGetImageGraphicsContext(GpImage *image, GpGraphics **graphics)
Definition: image.c:2195
GpStatus WINGDIPAPI GdipDisposeImage(GpImage *image)
Definition: image.c:2099
GpStatus WINGDIPAPI GdipLoadImageFromStream(IStream *stream, GpImage **image)
Definition: image.c:4525
GpStatus WINGDIPAPI GdipCreateBitmapFromStream(IStream *stream, GpBitmap **bitmap)
Definition: image.c:1895
GpStatus WINGDIPAPI GdipScaleMatrix(GpMatrix *matrix, REAL scaleX, REAL scaleY, GpMatrixOrder order)
Definition: matrix.c:288
GpStatus WINGDIPAPI GdipMultiplyMatrix(GpMatrix *matrix, GDIPCONST GpMatrix *matrix2, GpMatrixOrder order)
Definition: matrix.c:239
GpStatus WINGDIPAPI GdipTranslateMatrix(GpMatrix *matrix, REAL offsetX, REAL offsetY, GpMatrixOrder order)
Definition: matrix.c:420
GpStatus WINGDIPAPI GdipCreateMatrix3(GDIPCONST GpRectF *rect, GDIPCONST GpPointF *pt, GpMatrix **matrix)
Definition: matrix.c:83
GpStatus WINGDIPAPI GdipSetMatrixElements(GpMatrix *matrix, REAL m11, REAL m12, REAL m21, REAL m22, REAL dx, REAL dy)
Definition: matrix.c:318
GpStatus WINGDIPAPI GdipRotateMatrix(GpMatrix *matrix, REAL angle, GpMatrixOrder order)
Definition: matrix.c:257
GpStatus WINGDIPAPI GdipIsMatrixIdentity(GDIPCONST GpMatrix *matrix, BOOL *result)
Definition: matrix.c:513
GpStatus WINGDIPAPI GdipDeleteMatrix(GpMatrix *matrix)
Definition: matrix.c:156
GpStatus WINGDIPAPI GdipCreateMatrix(GpMatrix **matrix)
Definition: matrix.c:136
GpStatus METAFILE_RotateWorldTransform(GpMetafile *metafile, REAL angle, MatrixOrder order)
Definition: metafile.c:1503
GpStatus WINGDIPAPI GdipCreateMetafileFromWmf(HMETAFILE hwmf, BOOL delete, GDIPCONST WmfPlaceableFileHeader *placeable, GpMetafile **metafile)
Definition: metafile.c:4290
ImageDataType
Definition: metafile.c:419
@ ImageDataTypeBitmap
Definition: metafile.c:421
@ ImageDataTypeUnknown
Definition: metafile.c:420
@ ImageDataTypeMetafile
Definition: metafile.c:422
GpStatus WINGDIPAPI GdipGetMetafileHeaderFromStream(IStream *stream, MetafileHeader *header)
Definition: metafile.c:4224
static GpStatus METAFILE_AddBrushObject(GpMetafile *metafile, GDIPCONST GpBrush *brush, DWORD *id)
Definition: metafile.c:1238
static GpStatus metafile_deserialize_brush(const BYTE *record_data, UINT data_size, GpBrush **brush)
Definition: metafile.c:2195
GpStatus METAFILE_GraphicsClear(GpMetafile *metafile, ARGB color)
Definition: metafile.c:960
GpStatus METAFILE_TranslateWorldTransform(GpMetafile *metafile, REAL dx, REAL dy, MatrixOrder order)
Definition: metafile.c:1524
GpStatus METAFILE_OffsetClip(GpMetafile *metafile, REAL dx, REAL dy)
Definition: metafile.c:5581
GpStatus METAFILE_GetGraphicsContext(GpMetafile *metafile, GpGraphics **result)
Definition: metafile.c:921
static GpStatus METAFILE_WriteEndOfFile(GpMetafile *metafile)
Definition: metafile.c:810
GpStatus WINGDIPAPI GdipCreateMetafileFromFile(GDIPCONST WCHAR *file, GpMetafile **metafile)
Definition: metafile.c:4360
GpStatus WINGDIPAPI GdipRecordMetafileStreamI(IStream *stream, HDC hdc, EmfType type, GDIPCONST GpRect *frameRect, MetafileFrameUnit frameUnit, GDIPCONST WCHAR *desc, GpMetafile **metafile)
Definition: metafile.c:858
GpStatus METAFILE_ScaleWorldTransform(GpMetafile *metafile, REAL sx, REAL sy, MatrixOrder order)
Definition: metafile.c:1460
static GpStatus METAFILE_PlaybackUpdateWorldTransform(GpMetafile *metafile)
Definition: metafile.c:1832
GpStatus WINGDIPAPI GdipGetMetafileDownLevelRasterizationLimit(GDIPCONST GpMetafile *metafile, UINT *limitDpi)
Definition: metafile.c:4401
static void metafile_free_object_table_entry(GpMetafile *metafile, BYTE id)
Definition: metafile.c:649
GpStatus METAFILE_FillEllipse(GpMetafile *metafile, GpBrush *brush, GpRectF *rect)
Definition: metafile.c:5175
GpStatus METAFILE_AddSimpleProperty(GpMetafile *metafile, SHORT prop, SHORT val)
Definition: metafile.c:4839
static GpStatus METAFILE_FillEmfPlusBitmap(EmfPlusBitmap *record, IStream *stream, DWORD size)
Definition: metafile.c:4637
GpStatus METAFILE_SetPageTransform(GpMetafile *metafile, GpUnit unit, REAL scale)
Definition: metafile.c:1419
PenDataFlags
Definition: metafile.c:168
@ PenDataNonCenter
Definition: metafile.c:178
@ PenDataDashedLineCap
Definition: metafile.c:175
@ PenDataJoin
Definition: metafile.c:172
@ PenDataCustomEndCap
Definition: metafile.c:181
@ PenDataMiterLimit
Definition: metafile.c:173
@ PenDataStartCap
Definition: metafile.c:170
@ PenDataLineStyle
Definition: metafile.c:174
@ PenDataDashedLineOffset
Definition: metafile.c:176
@ PenDataCustomStartCap
Definition: metafile.c:180
@ PenDataTransform
Definition: metafile.c:169
@ PenDataCompoundLine
Definition: metafile.c:179
@ PenDataDashedLine
Definition: metafile.c:177
@ PenDataEndCap
Definition: metafile.c:171
GpStatus METAFILE_ReleaseDC(GpMetafile *metafile, HDC hdc)
Definition: metafile.c:1667
GpStatus WINGDIPAPI GdipRecordMetafileFileName(GDIPCONST WCHAR *fileName, HDC hdc, EmfType type, GDIPCONST GpRectF *pFrameRect, MetafileFrameUnit frameUnit, GDIPCONST WCHAR *desc, GpMetafile **metafile)
Definition: metafile.c:4465
GpStatus METAFILE_SetClipRegion(GpMetafile *metafile, GpRegion *region, CombineMode mode)
Definition: metafile.c:1395
static GpStatus METAFILE_AddPenObject(GpMetafile *metafile, GpPen *pen, DWORD *id)
Definition: metafile.c:4878
GpStatus WINGDIPAPI GdipEnumerateMetafileDestPoint(GpGraphics *graphics, GDIPCONST GpMetafile *metafile, GDIPCONST GpPointF *dest, EnumerateMetafileProc callback, VOID *cb_data, GDIPCONST GpImageAttributes *attrs)
Definition: metafile.c:4040
GpStatus METAFILE_SetClipRect(GpMetafile *metafile, REAL x, REAL y, REAL width, REAL height, CombineMode mode)
Definition: metafile.c:1350
GpStatus WINGDIPAPI GdipGetMetafileHeaderFromFile(GDIPCONST WCHAR *filename, MetafileHeader *header)
Definition: metafile.c:4204
static void METAFILE_RemoveLastRecord(GpMetafile *metafile, EmfPlusRecordHeader *record)
Definition: metafile.c:764
static DWORD METAFILE_AddObjectId(GpMetafile *metafile)
Definition: metafile.c:710
static GpStatus METAFILE_AddImageObject(GpMetafile *metafile, GpImage *image, DWORD *id)
Definition: metafile.c:4652
GpStatus WINGDIPAPI GdipConvertToEmfPlusToFile(const GpGraphics *refGraphics, GpMetafile *metafile, BOOL *conversionSuccess, const WCHAR *filename, EmfType emfType, const WCHAR *description, GpMetafile **out_metafile)
Definition: metafile.c:4590
static GpStatus metafile_deserialize_custom_line_cap(const BYTE *record_data, UINT data_size, GpCustomLineCap **cap)
Definition: metafile.c:2335
GpStatus METAFILE_GraphicsDeleted(GpMetafile *metafile)
Definition: metafile.c:1675
static int CALLBACK enum_metafile_proc(HDC hDC, HANDLETABLE *lpHTable, const ENHMETARECORD *lpEMFR, int nObj, LPARAM lpData)
Definition: metafile.c:3779
GpStatus WINGDIPAPI GdipCreateMetafileFromWmfFile(GDIPCONST WCHAR *file, GDIPCONST WmfPlaceableFileHeader *placeable, GpMetafile **metafile)
Definition: metafile.c:4341
BitmapDataType
Definition: metafile.c:396
@ BitmapDataTypePixel
Definition: metafile.c:397
@ BitmapDataTypeCompressed
Definition: metafile.c:398
static GpStatus METAFILE_AddRegionObject(GpMetafile *metafile, GpRegion *region, DWORD *id)
Definition: metafile.c:1374
static GpStatus METAFILE_PrepareBrushData(GDIPCONST GpBrush *brush, DWORD *size)
Definition: metafile.c:992
CustomLineCapData
Definition: metafile.c:185
@ CustomLineCapDataFillPath
Definition: metafile.c:186
@ CustomLineCapDataLinePath
Definition: metafile.c:187
GpStatus METAFILE_BeginContainerNoParams(GpMetafile *metafile, DWORD StackIndex)
Definition: metafile.c:1587
static GpStatus METAFILE_WriteHeader(GpMetafile *metafile, HDC hdc)
Definition: metafile.c:779
GpStatus WINGDIPAPI GdipCreateMetafileFromStream(IStream *stream, GpMetafile **metafile)
Definition: metafile.c:4381
GpStatus WINGDIPAPI GdipRecordMetafileFileNameI(GDIPCONST WCHAR *fileName, HDC hdc, EmfType type, GDIPCONST GpRect *pFrameRect, MetafileFrameUnit frameUnit, GDIPCONST WCHAR *desc, GpMetafile **metafile)
Definition: metafile.c:4576
GpStatus WINGDIPAPI GdipRecordMetafileStream(IStream *stream, HDC hdc, EmfType type, GDIPCONST GpRectF *frameRect, MetafileFrameUnit frameUnit, GDIPCONST WCHAR *desc, GpMetafile **metafile)
Definition: metafile.c:876
static GpStatus METAFILE_AddImageAttributesObject(GpMetafile *metafile, const GpImageAttributes *attrs, DWORD *id)
Definition: metafile.c:4728
GpStatus METAFILE_GetDC(GpMetafile *metafile, HDC *hdc)
Definition: metafile.c:941
LineStyle
Definition: metafile.c:196
@ LineStyleDot
Definition: metafile.c:199
@ LineStyleDashDotDot
Definition: metafile.c:201
@ LineStyleDashDot
Definition: metafile.c:200
@ LineStyleSolid
Definition: metafile.c:197
@ LineStyleDash
Definition: metafile.c:198
@ LineStyleCustom
Definition: metafile.c:202
static void METAFILE_FillCustomLineCapData(GDIPCONST GpCustomLineCap *cap, BYTE *ptr, REAL line_miter_limit, DWORD data_size, DWORD path_size)
Definition: metafile.c:1155
GpStatus METAFILE_FillPath(GpMetafile *metafile, GpBrush *brush, GpPath *path)
Definition: metafile.c:5134
GpStatus METAFILE_DrawArc(GpMetafile *metafile, GpPen *pen, const GpRectF *rect, REAL startAngle, REAL sweepAngle)
Definition: metafile.c:5536
GpStatus METAFILE_SetClipPath(GpMetafile *metafile, GpPath *path, CombineMode mode)
Definition: metafile.c:5626
struct EmfPlusRecordHeader EmfPlusRecordHeader
GpStatus WINGDIPAPI GdipPlayMetafileRecord(GDIPCONST GpMetafile *metafile, EmfPlusRecordType recordType, UINT flags, UINT dataSize, GDIPCONST BYTE *data)
Definition: metafile.c:2766
GpStatus WINGDIPAPI GdipEnumerateMetafileSrcRectDestRectI(GpGraphics *graphics, GDIPCONST GpMetafile *metafile, GDIPCONST Rect *destRect, GDIPCONST Rect *srcRect, Unit srcUnit, EnumerateMetafileProc callback, VOID *cb_data, GDIPCONST GpImageAttributes *attrs)
Definition: metafile.c:3987
GpStatus WINGDIPAPI GdipRecordMetafileI(HDC hdc, EmfType type, GDIPCONST GpRect *frameRect, MetafileFrameUnit frameUnit, GDIPCONST WCHAR *desc, GpMetafile **metafile)
Definition: metafile.c:840
static BOOL is_integer_rect(const GpRectF *rect)
Definition: metafile.c:979
static GpStatus metafile_deserialize_image(const BYTE *record_data, UINT data_size, GpImage **image)
Definition: metafile.c:1871
static void METAFILE_WriteRecords(GpMetafile *metafile)
Definition: metafile.c:770
GpStatus METAFILE_DrawRectangles(GpMetafile *metafile, GpPen *pen, const GpRectF *rects, INT count)
Definition: metafile.c:5481
static GpStatus METAFILE_AddFontObject(GpMetafile *metafile, GDIPCONST GpFont *font, DWORD *id)
Definition: metafile.c:5277
static void METAFILE_AdjustFrame(GpMetafile *metafile, const GpPointF *points, UINT num_points)
Definition: metafile.c:897
GpStatus METAFILE_SetRenderingOrigin(GpMetafile *metafile, INT x, INT y)
Definition: metafile.c:5653
GpStatus METAFILE_RestoreGraphics(GpMetafile *metafile, DWORD StackIndex)
Definition: metafile.c:1647
static GpStatus metafile_set_clip_region(GpMetafile *metafile, GpRegion *region, CombineMode mode)
Definition: metafile.c:2754
static void METAFILE_PlaybackReleaseDC(GpMetafile *metafile)
Definition: metafile.c:1814
GpStatus WINGDIPAPI GdipCreateMetafileFromEmf(HENHMETAFILE hemf, BOOL delete, GpMetafile **metafile)
Definition: metafile.c:4244
GpStatus WINGDIPAPI GdipEnumerateMetafileDestPointI(GpGraphics *graphics, GDIPCONST GpMetafile *metafile, GDIPCONST GpPoint *dest, EnumerateMetafileProc callback, VOID *cb_data, GDIPCONST GpImageAttributes *attrs)
Definition: metafile.c:4058
static int CALLBACK get_emfplus_header_proc(HDC hDC, HANDLETABLE *lpHTable, const ENHMETARECORD *lpEMFR, int nObj, LPARAM lpData)
Definition: metafile.c:4102
void METAFILE_Free(GpMetafile *metafile)
Definition: metafile.c:687
BrushDataFlags
Definition: metafile.c:238
@ BrushDataBlendFactorsH
Definition: metafile.c:242
@ BrushDataTransform
Definition: metafile.c:240
@ BrushDataBlendFactorsV
Definition: metafile.c:243
@ BrushDataPresetColors
Definition: metafile.c:241
@ BrushDataDoNotTransform
Definition: metafile.c:246
@ BrushDataFocusScales
Definition: metafile.c:244
@ BrushDataPath
Definition: metafile.c:239
@ BrushDataIsGammaCorrected
Definition: metafile.c:245
GpStatus METAFILE_MultiplyWorldTransform(GpMetafile *metafile, GDIPCONST GpMatrix *matrix, MatrixOrder order)
Definition: metafile.c:1482
GpStatus METAFILE_SetWorldTransform(GpMetafile *metafile, GDIPCONST GpMatrix *transform)
Definition: metafile.c:1440
GpStatus METAFILE_ResetWorldTransform(GpMetafile *metafile)
Definition: metafile.c:1546
GpStatus METAFILE_DrawImagePointsRect(GpMetafile *metafile, GpImage *image, GDIPCONST GpPointF *points, INT count, REAL srcx, REAL srcy, REAL srcwidth, REAL srcheight, GpUnit srcUnit, GDIPCONST GpImageAttributes *imageAttributes, DrawImageAbort callback, VOID *callbackData)
Definition: metafile.c:4759
GpStatus METAFILE_DrawEllipse(GpMetafile *metafile, GpPen *pen, GpRectF *rect)
Definition: metafile.c:5095
static void metafile_set_object_table_entry(GpMetafile *metafile, BYTE id, BYTE type, void *object)
Definition: metafile.c:1864
static GpStatus metafile_read_region_node(struct memory_buffer *mbuf, GpRegion *region, region_element *node, UINT *count)
Definition: metafile.c:2069
GpStatus METAFILE_BeginContainer(GpMetafile *metafile, GDIPCONST GpRectF *dstrect, GDIPCONST GpRectF *srcrect, GpUnit unit, DWORD StackIndex)
Definition: metafile.c:1564
static void METAFILE_PrepareCustomLineCapData(GDIPCONST GpCustomLineCap *cap, DWORD *ret_cap_size, DWORD *ret_cap_data_size, DWORD *ret_path_size)
Definition: metafile.c:1117
GpStatus WINGDIPAPI GdipGetHemfFromMetafile(GpMetafile *metafile, HENHMETAFILE *hEmf)
Definition: metafile.c:1792
GpStatus METAFILE_FillPie(GpMetafile *metafile, GpBrush *brush, const GpRectF *rect, REAL startAngle, REAL sweepAngle)
Definition: metafile.c:5224
GpStatus METAFILE_DrawDriverString(GpMetafile *metafile, GDIPCONST UINT16 *text, INT length, GDIPCONST GpFont *font, GDIPCONST GpStringFormat *format, GDIPCONST GpBrush *brush, GDIPCONST PointF *positions, INT flags, GDIPCONST GpMatrix *matrix)
Definition: metafile.c:5322
GpStatus METAFILE_EndContainer(GpMetafile *metafile, DWORD StackIndex)
Definition: metafile.c:1607
static GpStatus METAFILE_PlaybackUpdateClip(GpMetafile *metafile)
Definition: metafile.c:1823
HRESULT WINAPI WICCreateImagingFactory_Proxy(UINT, IWICImagingFactory **)
Definition: proxy.c:649
static GpStatus METAFILE_AllocateRecord(GpMetafile *metafile, EmfPlusRecordType record_type, DWORD size, void **result)
Definition: metafile.c:715
static GpStatus METAFILE_PlaybackObject(GpMetafile *metafile, UINT flags, UINT data_size, const BYTE *record_data)
Definition: metafile.c:2538
container_type
Definition: metafile.c:150
@ SAVE_GRAPHICS
Definition: metafile.c:152
@ BEGIN_CONTAINER
Definition: metafile.c:151
static GpStatus metafile_deserialize_path(const BYTE *record_data, UINT data_size, GpPath **path)
Definition: metafile.c:2006
GpStatus WINGDIPAPI GdipGetMetafileHeaderFromWmf(HMETAFILE hwmf, GDIPCONST WmfPlaceableFileHeader *placeable, MetafileHeader *header)
Definition: metafile.c:4187
static GpStatus metafile_get_pen_brush_data_offset(EmfPlusPen *data, UINT data_size, DWORD *ret)
Definition: metafile.c:2451
GpStatus WINGDIPAPI GdipEmfToWmfBits(HENHMETAFILE hemf, UINT cbData16, LPBYTE pData16, INT iMapMode, INT eFlags)
Definition: metafile.c:4458
GpStatus WINGDIPAPI GdipGetMetafileHeaderFromEmf(HENHMETAFILE hemf, MetafileHeader *header)
Definition: metafile.c:4128
GpStatus WINGDIPAPI GdipSetMetafileDownLevelRasterizationLimit(GpMetafile *metafile, UINT limitDpi)
Definition: metafile.c:4417
GpStatus WINGDIPAPI GdipEnumerateMetafileDestRect(GpGraphics *graphics, GDIPCONST GpMetafile *metafile, GDIPCONST GpRectF *dest, EnumerateMetafileProc callback, VOID *cb_data, GDIPCONST GpImageAttributes *attrs)
Definition: metafile.c:4007
GpStatus METAFILE_DrawPath(GpMetafile *metafile, GpPen *pen, GpPath *path)
Definition: metafile.c:5065
GpStatus WINGDIPAPI GdipConvertToEmfPlus(const GpGraphics *ref, GpMetafile *metafile, BOOL *succ, EmfType emfType, const WCHAR *description, GpMetafile **out_metafile)
Definition: metafile.c:4436
GpStatus WINGDIPAPI GdipEnumerateMetafileDestRectI(GpGraphics *graphics, GDIPCONST GpMetafile *metafile, GDIPCONST GpRect *dest, EnumerateMetafileProc callback, VOID *cb_data, GDIPCONST GpImageAttributes *attrs)
Definition: metafile.c:4024
GpStatus WINGDIPAPI GdipGetMetafileHeaderFromMetafile(GpMetafile *metafile, MetafileHeader *header)
Definition: metafile.c:4072
GpStatus METAFILE_SaveGraphics(GpMetafile *metafile, DWORD StackIndex)
Definition: metafile.c:1627
static GpStatus METAFILE_AddPathObject(GpMetafile *metafile, GpPath *path, DWORD *id)
Definition: metafile.c:4856
static GpStatus METAFILE_PlaybackGetDC(GpMetafile *metafile)
Definition: metafile.c:1805
GpStatus WINGDIPAPI GdipEnumerateMetafileSrcRectDestPoints(GpGraphics *graphics, GDIPCONST GpMetafile *metafile, GDIPCONST GpPointF *destPoints, INT count, GDIPCONST GpRectF *srcRect, Unit srcUnit, EnumerateMetafileProc callback, VOID *callbackData, GDIPCONST GpImageAttributes *imageAttributes)
Definition: metafile.c:3829
GpStatus METAFILE_ResetClip(GpMetafile *metafile)
Definition: metafile.c:5605
GpStatus WINGDIPAPI GdipRecordMetafile(HDC hdc, EmfType type, GDIPCONST GpRectF *frameRect, MetafileFrameUnit frameUnit, GDIPCONST WCHAR *desc, GpMetafile **metafile)
Definition: metafile.c:828
static GpStatus metafile_deserialize_region(const BYTE *record_data, UINT data_size, GpRegion **region)
Definition: metafile.c:2164
ARGB EmfPlusARGB
Definition: metafile.c:45
static void METAFILE_FillBrushData(GDIPCONST GpBrush *brush, EmfPlusBrush *data)
Definition: metafile.c:1030
GpStatus METAFILE_FillRegion(GpMetafile *metafile, GpBrush *brush, GpRegion *region)
Definition: metafile.c:5434
GpStatus WINGDIPAPI GdipEnumerateMetafileSrcRectDestRect(GpGraphics *graphics, GDIPCONST GpMetafile *metafile, GDIPCONST GpRectF *dest, GDIPCONST GpRectF *src, Unit srcUnit, EnumerateMetafileProc callback, VOID *cb_data, GDIPCONST GpImageAttributes *attrs)
Definition: metafile.c:3970
static GpStatus METAFILE_CreateCompressedImageStream(GpImage *image, IStream **stream, DWORD *size)
Definition: metafile.c:4599
GpStatus METAFILE_FillRectangles(GpMetafile *metafile, GpBrush *brush, GDIPCONST GpRectF *rects, INT count)
Definition: metafile.c:1261
GpStatus WINGDIPAPI GdipSetPenLineJoin(GpPen *pen, GpLineJoin join)
Definition: pen.c:746
GpStatus WINGDIPAPI GdipDeletePen(GpPen *pen)
Definition: pen.c:204
GpStatus WINGDIPAPI GdipCreatePen2(GpBrush *brush, REAL width, GpUnit unit, GpPen **pen)
Definition: pen.c:160
GpStatus WINGDIPAPI GdipSetPenMiterLimit(GpPen *pen, REAL limit)
Definition: pen.c:759
GpStatus WINGDIPAPI GdipSetPenDashStyle(GpPen *pen, GpDashStyle dash)
Definition: pen.c:688
GpStatus WINGDIPAPI GdipSetPenCustomEndCap(GpPen *pen, GpCustomLineCap *customCap)
Definition: pen.c:590
GpStatus WINGDIPAPI GdipSetPenEndCap(GpPen *pen, GpLineCap cap)
Definition: pen.c:709
GpStatus WINGDIPAPI GdipSetPenStartCap(GpPen *pen, GpLineCap cap)
Definition: pen.c:771
GpStatus WINGDIPAPI GdipSetPenCustomStartCap(GpPen *pen, GpCustomLineCap *customCap)
Definition: pen.c:609
GpStatus WINGDIPAPI GdipSetPenDashOffset(GpPen *pen, REAL offset)
Definition: pen.c:676
GpStatus WINGDIPAPI GdipCombineRegionPath(GpRegion *region, GpPath *path, CombineMode mode)
Definition: region.c:236
GpStatus WINGDIPAPI GdipTransformRegion(GpRegion *region, GpMatrix *matrix)
Definition: region.c:1702
GpStatus WINGDIPAPI GdipCreateRegionRect(GDIPCONST GpRectF *rect, GpRegion **region)
Definition: region.c:459
GpStatus WINGDIPAPI GdipCreateRegion(GpRegion **region)
Definition: region.c:390
GpStatus WINGDIPAPI GdipCombineRegionRegion(GpRegion *region1, GpRegion *region2, CombineMode mode)
Definition: region.c:346
GpStatus WINGDIPAPI GdipCreateRegionPath(GpPath *path, GpRegion **region)
Definition: region.c:425
GpStatus WINGDIPAPI GdipDeleteRegion(GpRegion *region)
Definition: region.c:567
GpStatus WINGDIPAPI GdipCloneRegion(GpRegion *region, GpRegion **clone)
Definition: region.c:215
const WCHAR * text
Definition: package.c:1794
#define assert(_expr)
Definition: assert.h:32
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2802
_ACRTIMP double __cdecl fmin(double, double)
_ACRTIMP double __cdecl fmax(double, double)
return ret
Definition: mutex.c:146
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GpStatus hresult_to_status(HRESULT res)
Definition: gdiplus.c:314
const char * debugstr_rectf(const RectF *rc)
Definition: gdiplus.c:486
REAL units_to_pixels(REAL units, GpUnit unit, REAL dpi, BOOL printer_display)
Definition: gdiplus.c:329
const char * debugstr_pointf(const PointF *pt)
Definition: gdiplus.c:492
DWORD write_region_data(const GpRegion *region, void *data)
Definition: region.c:689
GpStatus encode_image_png(GpImage *image, IStream *stream, GDIPCONST EncoderParameters *params)
Definition: image.c:4859
GpStatus get_graphics_transform(GpGraphics *graphics, GpCoordinateSpace dst_space, GpCoordinateSpace src_space, GpMatrix *matrix)
Definition: graphics.c:7266
static INT gdip_round(REAL x)
#define EmfPlusObjectTableSize
static void init_memory_buffer(struct memory_buffer *mbuf, const BYTE *buffer, INT size)
DWORD write_path_data(GpPath *path, void *data)
static void set_rect(GpRectF *rect, REAL x, REAL y, REAL width, REAL height)
#define VERSION_MAGIC2
@ ObjectTypeImage
@ ObjectTypeInvalid
@ ObjectTypeImageAttributes
@ ObjectTypePen
@ ObjectTypeFont
@ ObjectTypeRegion
@ ObjectTypeMax
@ ObjectTypeBrush
@ ObjectTypePath
static const void * buffer_read(struct memory_buffer *mbuf, INT size)
GpStatus graphics_from_image(GpImage *image, GpGraphics **graphics)
Definition: graphics.c:2520
@ RegionDataEmptyRect
@ RegionDataRect
@ RegionDataInfiniteRect
@ RegionDataPath
#define GP_DEFAULT_PENSTYLE
@ DashCapFlat
Definition: gdiplusenums.h:170
@ LineJoinMiter
Definition: gdiplusenums.h:105
#define GDIP_EMFPLUS_RECORD_BASE
Definition: gdiplusenums.h:487
@ ImageTypeBitmap
Definition: gdiplusenums.h:194
@ ImageTypeMetafile
Definition: gdiplusenums.h:195
CombineMode
Definition: gdiplusenums.h:387
@ CombineModeUnion
Definition: gdiplusenums.h:390
@ CombineModeReplace
Definition: gdiplusenums.h:388
@ CombineModeComplement
Definition: gdiplusenums.h:393
@ CombineModeIntersect
Definition: gdiplusenums.h:389
@ CombineModeExclude
Definition: gdiplusenums.h:392
@ CombineModeXor
Definition: gdiplusenums.h:391
@ ImageFlagsNone
Definition: gdiplusenums.h:331
EmfPlusRecordType
Definition: gdiplusenums.h:491
@ EmfPlusRecordTypeGetDC
Definition: gdiplusenums.h:699
@ EmfPlusRecordTypeDrawPie
Definition: gdiplusenums.h:712
@ EmfPlusRecordTypeSetCompositingQuality
Definition: gdiplusenums.h:731
@ EmfPlusRecordTypeSetClipRect
Definition: gdiplusenums.h:745
@ EmfPlusRecordTypeSetClipPath
Definition: gdiplusenums.h:746
@ EmfPlusRecordTypeResetWorldTransform
Definition: gdiplusenums.h:738
@ EmfPlusRecordTypeResetClip
Definition: gdiplusenums.h:744
@ EmfPlusRecordTypeEndContainer
Definition: gdiplusenums.h:736
@ EmfPlusRecordTypeSave
Definition: gdiplusenums.h:732
@ EmfPlusRecordTypeRotateWorldTransform
Definition: gdiplusenums.h:742
@ EmfPlusRecordTypeTranslateWorldTransform
Definition: gdiplusenums.h:740
@ EmfPlusRecordTypeDrawImagePoints
Definition: gdiplusenums.h:722
@ EmfPlusRecordTypeRestore
Definition: gdiplusenums.h:733
@ EmfPlusRecordTypeClear
Definition: gdiplusenums.h:704
@ EmfPlusRecordTypeFillPath
Definition: gdiplusenums.h:715
@ EmfPlusRecordTypeSetPixelOffsetMode
Definition: gdiplusenums.h:729
@ EmfPlusRecordTypeDrawArc
Definition: gdiplusenums.h:713
@ EmfPlusRecordTypeSetCompositingMode
Definition: gdiplusenums.h:730
@ EmfPlusRecordTypeBeginContainer
Definition: gdiplusenums.h:734
@ EmfPlusRecordTypeDrawDriverString
Definition: gdiplusenums.h:749
@ EmfPlusRecordTypeDrawPath
Definition: gdiplusenums.h:716
@ EmfPlusRecordTypeOffsetClip
Definition: gdiplusenums.h:748
@ EmfPlusRecordTypeObject
Definition: gdiplusenums.h:703
@ EmfPlusRecordTypeFillClosedCurve
Definition: gdiplusenums.h:717
@ EmfPlusRecordTypeFillPie
Definition: gdiplusenums.h:711
@ EmfPlusRecordTypeSetWorldTransform
Definition: gdiplusenums.h:737
@ EmfPlusRecordTypeFillRects
Definition: gdiplusenums.h:705
@ EmfPlusRecordTypeHeader
Definition: gdiplusenums.h:696
@ EmfPlusRecordTypeDrawEllipse
Definition: gdiplusenums.h:710
@ EmfPlusRecordTypeFillEllipse
Definition: gdiplusenums.h:709
@ EmfPlusRecordTypeSetInterpolationMode
Definition: gdiplusenums.h:728
@ EmfPlusRecordTypeEndOfFile
Definition: gdiplusenums.h:697
@ EmfPlusRecordTypeDrawRects
Definition: gdiplusenums.h:706
@ EmfPlusRecordTypeSetPageTransform
Definition: gdiplusenums.h:743
@ EmfPlusRecordTypeSetRenderingOrigin
Definition: gdiplusenums.h:724
@ EmfPlusRecordTypeSetAntiAliasMode
Definition: gdiplusenums.h:725
@ EmfPlusRecordTypeBeginContainerNoParams
Definition: gdiplusenums.h:735
@ EmfPlusRecordTypeFillRegion
Definition: gdiplusenums.h:714
@ EmfPlusRecordTypeDrawImage
Definition: gdiplusenums.h:721
@ EmfPlusRecordTypeScaleWorldTransform
Definition: gdiplusenums.h:741
@ EmfPlusRecordTypeMultiplyWorldTransform
Definition: gdiplusenums.h:739
@ EmfPlusRecordTypeSetClipRegion
Definition: gdiplusenums.h:747
@ EmfPlusRecordTypeSetTextRenderingHint
Definition: gdiplusenums.h:726
EmfType
Definition: gdiplusenums.h:231
@ EmfTypeEmfPlusDual
Definition: gdiplusenums.h:234
@ CustomLineCapTypeAdjustableArrow
Definition: gdiplusenums.h:79
@ LineCapFlat
Definition: gdiplusenums.h:61
UINT GraphicsContainer
Definition: gdiplusenums.h:23
FillMode
Definition: gdiplusenums.h:54
@ FillModeAlternate
Definition: gdiplusenums.h:55
@ FillModeWinding
Definition: gdiplusenums.h:56
MatrixOrder
Definition: gdiplusenums.h:186
@ MatrixOrderAppend
Definition: gdiplusenums.h:188
@ MatrixOrderPrepend
Definition: gdiplusenums.h:187
@ PenAlignmentCenter
Definition: gdiplusenums.h:154
Unit
Definition: gdiplusenums.h:26
@ UnitDisplay
Definition: gdiplusenums.h:28
@ UnitPixel
Definition: gdiplusenums.h:29
@ DriverStringOptionsRealizedAdvance
Definition: gdiplusenums.h:49
MetafileType
Definition: gdiplusenums.h:213
@ MetafileTypeEmfPlusOnly
Definition: gdiplusenums.h:218
@ MetafileTypeWmf
Definition: gdiplusenums.h:215
@ MetafileTypeWmfPlaceable
Definition: gdiplusenums.h:216
@ MetafileTypeEmf
Definition: gdiplusenums.h:217
@ MetafileTypeEmfPlusDual
Definition: gdiplusenums.h:219
@ CoordinateSpaceDevice
Definition: gdiplusenums.h:406
@ CoordinateSpaceWorld
Definition: gdiplusenums.h:404
@ BrushTypeHatchFill
Definition: gdiplusenums.h:39
@ BrushTypeLinearGradient
Definition: gdiplusenums.h:42
@ BrushTypeTextureFill
Definition: gdiplusenums.h:40
@ BrushTypeSolidColor
Definition: gdiplusenums.h:38
@ LinearGradientModeHorizontal
Definition: gdiplusenums.h:224
MetafileFrameUnit
Definition: gdiplusenums.h:417
@ MetafileFrameUnitMillimeter
Definition: gdiplusenums.h:422
@ MetafileFrameUnitInch
Definition: gdiplusenums.h:420
@ MetafileFrameUnitPixel
Definition: gdiplusenums.h:418
@ MetafileFrameUnitPoint
Definition: gdiplusenums.h:419
@ MetafileFrameUnitGdi
Definition: gdiplusenums.h:423
@ MetafileFrameUnitDocument
Definition: gdiplusenums.h:421
#define GDIPCONST
Definition: gdiplusflat.h:24
#define WINGDIPAPI
Definition: gdiplusflat.h:22
Unit GpUnit
DWORD ARGB
#define PixelFormatIndexed
#define PixelFormat32bppARGB
ImageAbort DrawImageAbort
Definition: gdiplustypes.h:55
Status
Definition: gdiplustypes.h:24
@ Ok
Definition: gdiplustypes.h:25
@ WrongState
Definition: gdiplustypes.h:33
@ ObjectBusy
Definition: gdiplustypes.h:29
@ InvalidParameter
Definition: gdiplustypes.h:27
@ OutOfMemory
Definition: gdiplustypes.h:28
@ NotImplemented
Definition: gdiplustypes.h:31
@ GenericError
Definition: gdiplustypes.h:26
BOOL(CALLBACK * EnumerateMetafileProc)(EmfPlusRecordType, UINT, UINT, const BYTE *, VOID *)
Definition: gdiplustypes.h:59
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLeglImageOES image
Definition: gl.h:2204
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
GLint GLint GLsizei width
Definition: gl.h:1546
GLuint GLenum GLenum transform
Definition: glext.h:9407
GLenum GLenum GLenum GLenum GLenum scale
Definition: glext.h:9032
GLenum src
Definition: glext.h:6340
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
GLintptr offset
Definition: glext.h:5920
GLuint color
Definition: glext.h:6243
GLdouble GLdouble right
Definition: glext.h:10859
GLuint GLenum matrix
Definition: glext.h:9407
GLenum mode
Definition: glext.h:6217
GLint left
Definition: glext.h:7726
GLbitfield flags
Definition: glext.h:7161
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLfloat angle
Definition: glext.h:10853
GLenum GLsizei dataSize
Definition: glext.h:11123
GLuint GLfloat * val
Definition: glext.h:7180
GLuint64EXT * result
Definition: glext.h:11304
GLuint GLdouble GLdouble GLint GLint order
Definition: glext.h:11194
GLenum cap
Definition: glext.h:9639
GLuint id
Definition: glext.h:5910
GLsizei const GLfloat * points
Definition: glext.h:8112
const GLfloat * m
Definition: glext.h:10848
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
const char cursor[]
Definition: icontest.c:13
GpStatus WINGDIPAPI GdipCreateImageAttributes(GpImageAttributes **imageattr)
GpStatus WINGDIPAPI GdipDisposeImageAttributes(GpImageAttributes *imageattr)
GpStatus WINGDIPAPI GdipSetImageAttributesWrapMode(GpImageAttributes *imageAttr, WrapMode wrap, ARGB argb, BOOL clamp)
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
const char * filename
Definition: ioapi.h:137
voidpf uLong int origin
Definition: ioapi.h:144
uint32_t entry
Definition: isohybrid.c:63
#define debugstr_w
Definition: kernel32.h:32
GLint dy
Definition: linetemp.h:97
if(dx< 0)
Definition: linetemp.h:194
GLint dx
Definition: linetemp.h:97
LONG_PTR LPARAM
Definition: minwindef.h:175
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static PVOID ptr
Definition: dispmode.c:27
HDC hdc
Definition: main.c:9
static HDC
Definition: imagelist.c:88
#define comment(fmt, arg1)
Definition: rebar.c:847
static IPrintDialogCallback callback
Definition: printdlg.c:326
D3D11_SHADER_VARIABLE_DESC desc
Definition: reflection.c:1204
static char * dest
Definition: rtl.c:149
static const unsigned char metafile[]
Definition: olepicture.c:138
static float(__cdecl *square_half_float)(float x
static HPALETTE palette
Definition: clipboard.c:1457
#define ceilf(x)
Definition: mymath.h:62
#define floorf(x)
Definition: mymath.h:65
Definition: mk_font.cpp:20
unsigned int UINT
Definition: ndis.h:50
#define DWORD
Definition: nt_native.h:44
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
static HANDLE ACCESS_MASK ULONG attributes
Definition: om.c:94
short WCHAR
Definition: pedump.c:58
short SHORT
Definition: pedump.c:59
png_const_structrp png_const_inforp int * unit
Definition: png.h:2392
#define calloc
Definition: rosglue.h:14
static calc_node_t temp
Definition: rpn_ieee.c:38
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
#define memset(x, y, z)
Definition: compat.h:39
int zero
Definition: sehframes.cpp:29
#define TRACE(s)
Definition: solgame.cpp:4
wchar_t const *const size_t const buffer_size
Definition: stat.cpp:95
EmfPlusRecordHeader Header
Definition: metafile.c:137
DWORD Height
Definition: metafile.c:404
BYTE BitmapData[1]
Definition: metafile.c:408
DWORD Type
Definition: metafile.c:407
DWORD Stride
Definition: metafile.c:405
DWORD PixelFormat
Definition: metafile.c:406
DWORD Width
Definition: metafile.c:403
EmfPlusLinearGradientBrushData lineargradient
Definition: metafile.c:296
DWORD Type
Definition: metafile.c:291
EmfPlusTextureBrushData texture
Definition: metafile.c:295
EmfPlusSolidBrushData solid
Definition: metafile.c:293
EmfPlusHatchBrushData hatch
Definition: metafile.c:294
DWORD Version
Definition: metafile.c:290
union EmfPlusBrush::@408 BrushData
DWORD Color
Definition: metafile.c:73
EmfPlusRecordHeader Header
Definition: metafile.c:72
EmfPlusRecordHeader Header
Definition: metafile.c:145
EmfPlusPointF FillHotSpot
Definition: metafile.c:350
EmfPlusPointF LineHotSpot
Definition: metafile.c:351
EmfPlusRectF rectF
Definition: metafile.c:526
float SweepAngle
Definition: metafile.c:522
union EmfPlusDrawArc::@413 RectData
EmfPlusRecordHeader Header
Definition: metafile.c:520
EmfPlusRect rect
Definition: metafile.c:525
float StartAngle
Definition: metafile.c:521
EmfPlusRecordHeader Header
Definition: metafile.c:613
union EmfPlusDrawDriverString::@421 brush
DWORD DriverStringOptionsFlags
Definition: metafile.c:619
EmfPlusRecordHeader Header
Definition: metafile.c:532
EmfPlusRect rect
Definition: metafile.c:535
EmfPlusRectF rectF
Definition: metafile.c:536
union EmfPlusDrawEllipse::@414 RectData
EmfPlusRectF SrcRect
Definition: metafile.c:502
EmfPlusPointR7 pointsR[3]
Definition: metafile.c:506
union EmfPlusDrawImagePoints::@412 PointData
EmfPlusPointF pointsF[3]
Definition: metafile.c:508
EmfPlusRecordHeader Header
Definition: metafile.c:499
EmfPlusPoint points[3]
Definition: metafile.c:507
DWORD ImageAttributesID
Definition: metafile.c:487
union EmfPlusDrawImage::@411 RectData
EmfPlusRect rect
Definition: metafile.c:492
EmfPlusRectF rectF
Definition: metafile.c:493
EmfPlusRecordHeader Header
Definition: metafile.c:486
EmfPlusRectF SrcRect
Definition: metafile.c:489
EmfPlusRecordHeader Header
Definition: metafile.c:514
float SweepAngle
Definition: metafile.c:544
EmfPlusRecordHeader Header
Definition: metafile.c:542
float StartAngle
Definition: metafile.c:543
union EmfPlusDrawPie::@415 RectData
EmfPlusRect rect
Definition: metafile.c:547
EmfPlusRectF rectF
Definition: metafile.c:548
EmfPlusRectF rectF[1]
Definition: metafile.c:559
EmfPlusRecordHeader Header
Definition: metafile.c:554
EmfPlusRect rect[1]
Definition: metafile.c:558
union EmfPlusDrawRects::@416 RectData
EmfPlusPointF pointsF[1]
Definition: metafile.c:583
EmfPlusPointR7 pointsR[1]
Definition: metafile.c:581
union EmfPlusFillClosedCurve::@418 PointData
EmfPlusRecordHeader Header
Definition: metafile.c:575
EmfPlusRecordHeader Header
Definition: metafile.c:589
EmfPlusRect rect
Definition: metafile.c:593
EmfPlusRectF rectF
Definition: metafile.c:594
union EmfPlusFillEllipse::@419 RectData
EmfPlusRecordHeader Header
Definition: metafile.c:565
EmfPlusARGB Color
Definition: metafile.c:569
union EmfPlusFillPath::@417 data
float SweepAngle
Definition: metafile.c:603
EmfPlusRecordHeader Header
Definition: metafile.c:600
float StartAngle
Definition: metafile.c:602
EmfPlusRectF rectF
Definition: metafile.c:607
DWORD BrushId
Definition: metafile.c:601
union EmfPlusFillPie::@420 RectData
EmfPlusRect rect
Definition: metafile.c:606
EmfPlusRecordHeader Header
Definition: metafile.c:78
EmfPlusRecordHeader Header
Definition: metafile.c:627
union EmfPlusFillRegion::@422 data
EmfPlusARGB Color
Definition: metafile.c:631
DWORD Length
Definition: metafile.c:453
DWORD Version
Definition: metafile.c:448
DWORD Reserved
Definition: metafile.c:452
WCHAR FamilyName[1]
Definition: metafile.c:454
float EmSize
Definition: metafile.c:449
DWORD SizeUnit
Definition: metafile.c:450
DWORD FontStyleFlags
Definition: metafile.c:451
EmfPlusARGB ForeColor
Definition: metafile.c:257
EmfPlusARGB BackColor
Definition: metafile.c:258
DWORD Version
Definition: metafile.c:64
EmfPlusRecordHeader Header
Definition: metafile.c:63
DWORD LogicalDpiY
Definition: metafile.c:67
DWORD LogicalDpiX
Definition: metafile.c:66
DWORD EmfPlusFlags
Definition: metafile.c:65
EmfPlusARGB ClampColor
Definition: metafile.c:441
ImageDataType Type
Definition: metafile.c:428
EmfPlusMetafile metafile
Definition: metafile.c:432
DWORD Version
Definition: metafile.c:427
EmfPlusBitmap bitmap
Definition: metafile.c:431
union EmfPlusImage::@409 ImageData
DWORD MetafileDataSize
Definition: metafile.c:414
BYTE MetafileData[1]
Definition: metafile.c:415
EmfPlusRecordHeader Header
Definition: metafile.c:118
EmfPlusImage image
Definition: metafile.c:466
EmfPlusRecordHeader Header
Definition: metafile.c:459
EmfPlusImageAttributes image_attributes
Definition: metafile.c:467
union EmfPlusObject::@410 ObjectData
EmfPlusPen pen
Definition: metafile.c:463
EmfPlusFont font
Definition: metafile.c:468
EmfPlusBrush brush
Definition: metafile.c:462
EmfPlusPath path
Definition: metafile.c:464
EmfPlusRegion region
Definition: metafile.c:465
EmfPlusRecordHeader Header
Definition: metafile.c:637
DWORD PaletteStyleFlags
Definition: metafile.c:390
DWORD PaletteCount
Definition: metafile.c:391
BYTE PaletteEntries[1]
Definition: metafile.c:392
DWORD PathPointCount
Definition: metafile.c:318
DWORD Version
Definition: metafile.c:317
DWORD PathPointFlags
Definition: metafile.c:319
DWORD PenDataFlags
Definition: metafile.c:231
DWORD PenUnit
Definition: metafile.c:232
BYTE OptionalData[1]
Definition: metafile.c:234
DWORD Type
Definition: metafile.c:369
DWORD Version
Definition: metafile.c:368
BYTE data[1]
Definition: metafile.c:372
float Width
Definition: metafile.c:272
float Height
Definition: metafile.c:273
SHORT Y
Definition: metafile.c:98
SHORT X
Definition: metafile.c:97
SHORT Height
Definition: metafile.c:100
SHORT Width
Definition: metafile.c:99
DWORD RegionNodePathLength
Definition: metafile.c:377
EmfPlusPath RegionNodePath
Definition: metafile.c:378
BYTE RegionNode[1]
Definition: metafile.c:385
DWORD Version
Definition: metafile.c:383
DWORD RegionNodeCount
Definition: metafile.c:384
EmfPlusRecordHeader Header
Definition: metafile.c:124
EmfPlusRecordHeader Header
Definition: metafile.c:111
EmfPlusRecordHeader Header
Definition: metafile.c:85
GpRectF ClipRect
Definition: metafile.c:86
EmfPlusRecordHeader Header
Definition: metafile.c:91
EmfPlusRecordHeader Header
Definition: metafile.c:644
EmfPlusRecordHeader Header
Definition: metafile.c:105
EmfPlusARGB SolidColor
Definition: metafile.c:251
EmfPlusRecordHeader Header
Definition: metafile.c:130
GpCustomLineCap cap
GpBrushType bt
GpLineCap strokeEndCap
GpLineCap strokeStartCap
GpHatchStyle hatchstyle
REAL matrix[6]
GpRegion * base_clip
struct list containers
GpMatrix * world_transform
struct emfplus_object objtable[EmfPlusObjectTableSize]
GpGraphics * playback_graphics
GpUnit page_unit
GpRectF src_rect
HANDLETABLE * handle_table
GpRegion * clip
GpPointF playback_points[3]
GpLineCap startcap
INT numdashes
REAL * dashes
GpCustomLineCap * customend
GpMatrix transform
REAL offset
REAL miterlimit
GpLineCap endcap
UINT style
GpLineJoin join
GpDashCap dashcap
GpBrush * brush
GpPenAlignment align
GpUnit unit
REAL width
GpCustomLineCap * customstart
region_element node
DWORD num_children
REAL Y
Definition: gdiplustypes.h:644
REAL X
Definition: gdiplustypes.h:643
long bottom
Definition: polytest.cpp:53
long right
Definition: polytest.cpp:53
long top
Definition: polytest.cpp:53
long left
Definition: polytest.cpp:53
REAL Height
Definition: gdiplustypes.h:659
REAL X
Definition: gdiplustypes.h:656
REAL Width
Definition: gdiplustypes.h:658
REAL Y
Definition: gdiplustypes.h:657
LONG cx
Definition: kdterminal.h:27
LONG cy
Definition: kdterminal.h:28
Definition: uimain.c:89
DWORD id
Definition: metafile.c:158
REAL page_scale
Definition: metafile.c:163
struct list entry
Definition: metafile.c:157
GpRegion * clip
Definition: metafile.c:164
GpUnit page_unit
Definition: metafile.c:162
enum container_type type
Definition: metafile.c:159
GpMatrix world_transform
Definition: metafile.c:161
GraphicsContainer state
Definition: metafile.c:160
Definition: emfdc.c:45
GpRegion * region
EnumerateMetafileProc callback
Definition: metafile.c:3774
void * callback_data
Definition: metafile.c:3775
GpMetafile * metafile
Definition: metafile.c:3776
Definition: main.c:439
Definition: fci.c:127
Definition: format.c:58
Definition: list.h:15
Definition: send.c:48
Definition: stat.h:66
Definition: ps.c:97
Definition: parse.h:23
DWORD dParm[1]
Definition: wingdi.h:2798
LONG right
Definition: windef.h:108
LONG bottom
Definition: windef.h:109
LONG top
Definition: windef.h:107
LONG left
Definition: windef.h:106
Definition: cmds.c:130
#define max(a, b)
Definition: svc.c:63
#define LIST_ENTRY(type)
Definition: queue.h:175
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
unsigned char * LPBYTE
Definition: typedefs.h:53
ULONG_PTR SIZE_T
Definition: typedefs.h:80
int32_t INT
Definition: typedefs.h:58
Definition: dlist.c:348
_In_ HFONT _Out_ PUINT _Out_ PUINT Width
Definition: font.h:89
_In_ HFONT _Out_ PUINT Height
Definition: font.h:88
int retval
Definition: wcstombs.cpp:91
#define WINAPI
Definition: msvc.h:6
const char * description
Definition: directx.c:2497
BOOL WINAPI DeleteMetaFile(_In_ HMETAFILE)
#define EMR_STRETCHBLT
Definition: wingdi.h:150
#define STRETCH_HALFTONE
Definition: wingdi.h:959
UINT WINAPI GetEnhMetaFileBits(_In_ HENHMETAFILE hEMF, _In_ UINT nSize, _Out_writes_bytes_opt_(nSize) LPBYTE lpData)
#define PS_DASH
Definition: wingdi.h:587
#define HORZRES
Definition: wingdi.h:716
#define EMR_BITBLT
Definition: wingdi.h:149
BOOL WINAPI DeleteEnhMetaFile(_In_opt_ HENHMETAFILE)
#define DT_RASDISPLAY
Definition: wingdi.h:708
int WINAPI GetDeviceCaps(_In_opt_ HDC, _In_ int)
#define DT_RASPRINTER
Definition: wingdi.h:709
HMETAFILE WINAPI GetMetaFileW(_In_ LPCWSTR)
BOOL WINAPI PlayEnhMetaFileRecord(_In_ HDC hdc, _In_reads_(cht) LPHANDLETABLE pht, _In_ CONST ENHMETARECORD *pmr, _In_ UINT cht)
#define PS_DOT
Definition: wingdi.h:588
#define VERTSIZE
Definition: wingdi.h:715
#define LOGPIXELSY
Definition: wingdi.h:719
#define PS_STYLE_MASK
Definition: wingdi.h:601
HDC WINAPI CreateEnhMetaFileW(_In_opt_ HDC, _In_opt_ LPCWSTR, _In_opt_ LPCRECT, _In_opt_ LPCWSTR)
BOOL WINAPI FillPath(_In_ HDC)
#define HORZSIZE
Definition: wingdi.h:714
UINT WINAPI GetMetaFileBitsEx(_In_ HMETAFILE hMF, _In_ UINT cbBuffer, _Out_writes_bytes_opt_(cbBuffer) LPVOID lpData)
#define VERTRES
Definition: wingdi.h:717
BOOL WINAPI GdiComment(_In_ HDC hdc, _In_ UINT nSize, _In_reads_bytes_(nSize) const BYTE *lpData)
BOOL WINAPI EnumEnhMetaFile(_In_opt_ HDC, _In_ HENHMETAFILE, _In_ ENHMFENUMPROC, _In_opt_ PVOID, _In_opt_ LPCRECT)
HENHMETAFILE WINAPI CloseEnhMetaFile(_In_ HDC hdc)
#define LOGPIXELSX
Definition: wingdi.h:718
HENHMETAFILE WINAPI SetEnhMetaFileBits(_In_ UINT nSize, _In_reads_bytes_(nSize) const BYTE *pb)
UINT WINAPI GetEnhMetaFileHeader(_In_ HENHMETAFILE hemf, _In_ UINT nSize, _Out_writes_bytes_opt_(nSize) LPENHMETAHEADER lpEnhMetaHeader)
#define EMR_HEADER
Definition: wingdi.h:75
int WINAPI SetStretchBltMode(_In_ HDC, _In_ int)
Definition: dc.c:1373
#define PS_SOLID
Definition: wingdi.h:586
#define EMR_GDICOMMENT
Definition: wingdi.h:143
#define TECHNOLOGY
Definition: wingdi.h:706
#define PS_DASHDOT
Definition: wingdi.h:589
#define PS_DASHDOTDOT
Definition: wingdi.h:590
HENHMETAFILE WINAPI GetEnhMetaFileW(_In_ LPCWSTR)
HENHMETAFILE WINAPI SetWinMetaFileBits(_In_ UINT nSize, _In_reads_bytes_(nSize) const BYTE *lpMeta16Data, _In_opt_ HDC hdcRef, _In_opt_ const METAFILEPICT *lpMFP)
_In_ int _Inout_ LPRECT lprc
Definition: winuser.h:4620
unsigned char BYTE
Definition: xxhash.c:193