ReactOS 0.4.15-dev-7788-g1ad9096
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#define NONAMELESSUNION
24
25#include "windef.h"
26#include "winbase.h"
27#include "wingdi.h"
28#include "wine/unicode.h"
29
30#define COBJMACROS
31#include "objbase.h"
32#include "ocidl.h"
33#include "olectl.h"
34#include "ole2.h"
35
36#include "winreg.h"
37#include "shlwapi.h"
38
39#include "gdiplus.h"
40#include "gdiplus_private.h"
41#include "wine/debug.h"
42#include "wine/list.h"
43
45
47
49
50typedef struct EmfPlusRecordHeader
51{
57
58typedef struct EmfPlusHeader
59{
66
67typedef struct EmfPlusClear
68{
72
73typedef struct EmfPlusFillRects
74{
79
80typedef struct EmfPlusSetClipRect
81{
85
87{
91
92typedef struct EmfPlusRect
93{
99
101{
105
107{
112
114{
118
120{
124
126{
131
133{
139
141{
145
147{
151
152typedef struct container
153{
154 struct list entry;
163
165{
169 PenDataJoin = 0x0008,
178 PenDataCustomEndCap = 0x1000
180
182{
185
187{
195
197{
201
203{
207
209{
213
215{
219
220typedef struct EmfPlusPenData
221{
227
229{
238};
239
241{
244
246{
251
253{
258
259typedef struct EmfPlusRectF
260{
261 float X;
262 float Y;
263 float Width;
264 float Height;
266
268{
278
279typedef struct EmfPlusBrush
280{
283 union {
290
291typedef struct EmfPlusPen
292{
295 /* EmfPlusPenData */
296 /* EmfPlusBrush */
299
300typedef struct EmfPlusPath
301{
305 /* PathPoints[] */
306 /* PathPointTypes[] */
307 /* AlignmentPadding */
310
312{
316
317typedef struct EmfPlusRegion
318{
323
324typedef struct EmfPlusPalette
325{
330
331typedef enum
332{
336
337typedef struct EmfPlusBitmap
338{
346
347typedef struct EmfPlusMetafile
348{
353
354typedef enum ImageDataType
355{
360
361typedef struct EmfPlusImage
362{
365 union
366 {
371
373{
381
382typedef struct EmfPlusObject
383{
385 union
386 {
395
396typedef struct EmfPlusPointR7
397{
401
402typedef struct EmfPlusPoint
403{
404 short X;
405 short Y;
407
408typedef struct EmfPlusPointF
409{
410 float X;
411 float Y;
413
414typedef struct EmfPlusDrawImage
415{
420 union
421 {
426
428{
434 union
435 {
441
442typedef struct EmfPlusDrawPath
443{
447
448typedef struct EmfPlusDrawArc
449{
453 union
454 {
459
460typedef struct EmfPlusDrawEllipse
461{
463 union
464 {
469
470typedef struct EmfPlusDrawPie
471{
475 union
476 {
481
482typedef struct EmfPlusDrawRects
483{
486 union
487 {
492
493typedef struct EmfPlusFillPath
494{
496 union
497 {
502
504{
507 float Tension;
509 union
510 {
516
517typedef struct EmfPlusFillEllipse
518{
521 union
522 {
527
528typedef struct EmfPlusFillPie
529{
534 union
535 {
540
541typedef struct EmfPlusFont
542{
544 float EmSize;
551
553{
554 struct emfplus_object *object = &metafile->objtable[id];
555
556 switch (object->type)
557 {
559 break;
560 case ObjectTypeBrush:
561 GdipDeleteBrush(object->u.brush);
562 break;
563 case ObjectTypePen:
564 GdipDeletePen(object->u.pen);
565 break;
566 case ObjectTypePath:
567 GdipDeletePath(object->u.path);
568 break;
569 case ObjectTypeRegion:
570 GdipDeleteRegion(object->u.region);
571 break;
572 case ObjectTypeImage:
573 GdipDisposeImage(object->u.image);
574 break;
575 case ObjectTypeFont:
576 GdipDeleteFont(object->u.font);
577 break;
579 GdipDisposeImageAttributes(object->u.image_attributes);
580 break;
581 default:
582 FIXME("not implemented for object type %u.\n", object->type);
583 return;
584 }
585
586 object->type = ObjectTypeInvalid;
587 object->u.object = NULL;
588}
589
591{
592 unsigned int i;
593
594 heap_free(metafile->comment_data);
596 if (!metafile->preserve_hemf)
598 if (metafile->record_graphics)
599 {
600 WARN("metafile closed while recording\n");
601 /* not sure what to do here; for now just prevent the graphics from functioning or using this object */
602 metafile->record_graphics->image = NULL;
603 metafile->record_graphics->busy = TRUE;
604 }
605
606 if (metafile->record_stream)
607 IStream_Release(metafile->record_stream);
608
609 for (i = 0; i < ARRAY_SIZE(metafile->objtable); i++)
611}
612
614{
615 return (metafile->next_object_id++) % EmfPlusObjectTableSize;
616}
617
619{
620 DWORD size_needed;
622
623 if (!metafile->comment_data_size)
624 {
625 DWORD data_size = max(256, size * 2 + 4);
626 metafile->comment_data = heap_alloc_zero(data_size);
627
628 if (!metafile->comment_data)
629 return OutOfMemory;
630
631 memcpy(metafile->comment_data, "EMF+", 4);
632
633 metafile->comment_data_size = data_size;
634 metafile->comment_data_length = 4;
635 }
636
637 size_needed = size + metafile->comment_data_length;
638
639 if (size_needed > metafile->comment_data_size)
640 {
641 DWORD data_size = size_needed * 2;
642 BYTE *new_data = heap_alloc_zero(data_size);
643
644 if (!new_data)
645 return OutOfMemory;
646
647 memcpy(new_data, metafile->comment_data, metafile->comment_data_length);
648
649 metafile->comment_data_size = data_size;
650 heap_free(metafile->comment_data);
651 metafile->comment_data = new_data;
652 }
653
654 *result = metafile->comment_data + metafile->comment_data_length;
655 metafile->comment_data_length += size;
656
658 record->Size = size;
659 record->DataSize = size - sizeof(EmfPlusRecordHeader);
660
661 return Ok;
662}
663
665{
666 assert(metafile->comment_data + metafile->comment_data_length == (BYTE*)record + record->Size);
667 metafile->comment_data_length -= record->Size;
668}
669
671{
672 if (metafile->comment_data_length > 4)
673 {
674 GdiComment(metafile->record_dc, metafile->comment_data_length, metafile->comment_data);
675 metafile->comment_data_length = 4;
676 }
677}
678
680{
682
683 if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
684 {
686
688 if (stat != Ok)
689 return stat;
690
691 header->Header.Type = EmfPlusRecordTypeHeader;
692
693 if (metafile->metafile_type == MetafileTypeEmfPlusDual)
694 header->Header.Flags = 1;
695 else
696 header->Header.Flags = 0;
697
698 header->Version = VERSION_MAGIC2;
699
701 header->EmfPlusFlags = 1;
702 else
703 header->EmfPlusFlags = 0;
704
705 header->LogicalDpiX = GetDeviceCaps(hdc, LOGPIXELSX);
706 header->LogicalDpiY = GetDeviceCaps(hdc, LOGPIXELSY);
707
709 }
710
711 return Ok;
712}
713
715{
717
718 if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
719 {
721
723 if (stat != Ok)
724 return stat;
725
727 record->Flags = 0;
728
730 }
731
732 return Ok;
733}
734
737{
738 HDC record_dc;
739 REAL dpix, dpiy;
740 REAL framerect_factor_x, framerect_factor_y;
741 RECT rc, *lprc;
743
744 TRACE("(%p %d %p %d %p %p)\n", hdc, type, frameRect, frameUnit, desc, metafile);
745
746 if (!hdc || type < EmfTypeEmfOnly || type > EmfTypeEmfPlusDual || !metafile)
747 return InvalidParameter;
748
751
752 if (frameRect)
753 {
754 switch (frameUnit)
755 {
757 framerect_factor_x = 2540.0 / dpix;
758 framerect_factor_y = 2540.0 / dpiy;
759 break;
761 framerect_factor_x = framerect_factor_y = 2540.0 / 72.0;
762 break;
764 framerect_factor_x = framerect_factor_y = 2540.0;
765 break;
767 framerect_factor_x = framerect_factor_y = 2540.0 / 300.0;
768 break;
770 framerect_factor_x = framerect_factor_y = 100.0;
771 break;
773 framerect_factor_x = framerect_factor_y = 1.0;
774 break;
775 default:
776 return InvalidParameter;
777 }
778
779 rc.left = framerect_factor_x * frameRect->X;
780 rc.top = framerect_factor_y * frameRect->Y;
781 rc.right = rc.left + framerect_factor_x * frameRect->Width;
782 rc.bottom = rc.top + framerect_factor_y * frameRect->Height;
783
784 lprc = &rc;
785 }
786 else
787 lprc = NULL;
788
789 record_dc = CreateEnhMetaFileW(hdc, NULL, lprc, desc);
790
791 if (!record_dc)
792 return GenericError;
793
794 *metafile = heap_alloc_zero(sizeof(GpMetafile));
795 if(!*metafile)
796 {
798 return OutOfMemory;
799 }
800
801 (*metafile)->image.type = ImageTypeMetafile;
802 (*metafile)->image.flags = ImageFlagsNone;
803 (*metafile)->image.palette = NULL;
804 (*metafile)->image.xres = dpix;
805 (*metafile)->image.yres = dpiy;
806 (*metafile)->bounds.X = (*metafile)->bounds.Y = 0.0;
807 (*metafile)->bounds.Width = (*metafile)->bounds.Height = 1.0;
808 (*metafile)->unit = UnitPixel;
809 (*metafile)->metafile_type = type;
810 (*metafile)->record_dc = record_dc;
811 (*metafile)->comment_data = NULL;
812 (*metafile)->comment_data_size = 0;
813 (*metafile)->comment_data_length = 0;
814 (*metafile)->hemf = NULL;
815 list_init(&(*metafile)->containers);
816
817 if (!frameRect)
818 {
819 (*metafile)->auto_frame = TRUE;
820 (*metafile)->auto_frame_min.X = 0;
821 (*metafile)->auto_frame_min.Y = 0;
822 (*metafile)->auto_frame_max.X = -1;
823 (*metafile)->auto_frame_max.Y = -1;
824 }
825
827
828 if (stat != Ok)
829 {
832 *metafile = NULL;
833 return OutOfMemory;
834 }
835
836 return stat;
837}
838
839/*****************************************************************************
840 * GdipRecordMetafileI [GDIPLUS.@]
841 */
844{
845 GpRectF frameRectF, *pFrameRectF;
846
847 TRACE("(%p %d %p %d %p %p)\n", hdc, type, frameRect, frameUnit, desc, metafile);
848
849 if (frameRect)
850 {
851 frameRectF.X = frameRect->X;
852 frameRectF.Y = frameRect->Y;
853 frameRectF.Width = frameRect->Width;
854 frameRectF.Height = frameRect->Height;
855 pFrameRectF = &frameRectF;
856 }
857 else
858 pFrameRectF = NULL;
859
860 return GdipRecordMetafile(hdc, type, pFrameRectF, frameUnit, desc, metafile);
861}
862
865{
867
868 TRACE("(%p %p %d %p %d %p %p)\n", stream, hdc, type, frameRect, frameUnit, desc, metafile);
869
870 if (!stream)
871 return InvalidParameter;
872
873 stat = GdipRecordMetafile(hdc, type, frameRect, frameUnit, desc, metafile);
874
875 if (stat == Ok)
876 {
877 (*metafile)->record_stream = stream;
878 IStream_AddRef(stream);
879 }
880
881 return stat;
882}
883
885 UINT num_points)
886{
887 int i;
888
889 if (!metafile->auto_frame || !num_points)
890 return;
891
892 if (metafile->auto_frame_max.X < metafile->auto_frame_min.X)
893 metafile->auto_frame_max = metafile->auto_frame_min = points[0];
894
895 for (i=0; i<num_points; i++)
896 {
897 if (points[i].X < metafile->auto_frame_min.X)
898 metafile->auto_frame_min.X = points[i].X;
899 if (points[i].X > metafile->auto_frame_max.X)
900 metafile->auto_frame_max.X = points[i].X;
901 if (points[i].Y < metafile->auto_frame_min.Y)
902 metafile->auto_frame_min.Y = points[i].Y;
903 if (points[i].Y > metafile->auto_frame_max.Y)
904 metafile->auto_frame_max.Y = points[i].Y;
905 }
906}
907
909{
911
912 if (!metafile->record_dc || metafile->record_graphics)
913 return InvalidParameter;
914
915 stat = graphics_from_image((GpImage*)metafile, &metafile->record_graphics);
916
917 if (stat == Ok)
918 {
919 *result = metafile->record_graphics;
920 metafile->record_graphics->xres = 96.0;
921 metafile->record_graphics->yres = 96.0;
922 }
923
924 return stat;
925}
926
928{
929 if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
930 {
933
935 if (stat != Ok)
936 return stat;
937
939 record->Flags = 0;
940
942 }
943
944 *hdc = metafile->record_dc;
945
946 return Ok;
947}
948
950{
951 if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
952 {
955
957 if (stat != Ok)
958 return stat;
959
960 record->Header.Type = EmfPlusRecordTypeClear;
961 record->Header.Flags = 0;
962 record->Color = color;
963
965 }
966
967 return Ok;
968}
969
971{
972 SHORT x, y, width, height;
973 x = rect->X;
974 y = rect->Y;
975 width = rect->Width;
976 height = rect->Height;
977 if (rect->X != (REAL)x || rect->Y != (REAL)y ||
978 rect->Width != (REAL)width || rect->Height != (REAL)height)
979 return FALSE;
980 return TRUE;
981}
982
984{
985 switch (brush->bt)
986 {
988 *size = FIELD_OFFSET(EmfPlusBrush, BrushData) + sizeof(EmfPlusSolidBrushData);
989 break;
991 *size = FIELD_OFFSET(EmfPlusBrush, BrushData) + sizeof(EmfPlusHatchBrushData);
992 break;
993 default:
994 FIXME("unsupported brush type: %d\n", brush->bt);
995 return NotImplemented;
996 }
997
998 return Ok;
999}
1000
1002{
1003 data->Version = VERSION_MAGIC2;
1004 data->Type = brush->bt;
1005
1006 switch (brush->bt)
1007 {
1009 {
1010 GpSolidFill *solid = (GpSolidFill *)brush;
1011 data->BrushData.solid.SolidColor = solid->color;
1012 break;
1013 }
1014 case BrushTypeHatchFill:
1015 {
1016 GpHatch *hatch = (GpHatch *)brush;
1017 data->BrushData.hatch.HatchStyle = hatch->hatchstyle;
1018 data->BrushData.hatch.ForeColor = hatch->forecol;
1019 data->BrushData.hatch.BackColor = hatch->backcol;
1020 break;
1021 }
1022 default:
1023 FIXME("unsupported brush type: %d\n", brush->bt);
1024 }
1025}
1026
1028{
1029 EmfPlusObject *object_record;
1030 GpStatus stat;
1031 DWORD size;
1032
1033 *id = -1;
1034 if (metafile->metafile_type != MetafileTypeEmfPlusOnly && metafile->metafile_type != MetafileTypeEmfPlusDual)
1035 return Ok;
1036
1038 if (stat != Ok) return stat;
1039
1041 FIELD_OFFSET(EmfPlusObject, ObjectData) + size, (void**)&object_record);
1042 if (stat != Ok) return stat;
1043
1045 object_record->Header.Type = EmfPlusRecordTypeObject;
1046 object_record->Header.Flags = *id | ObjectTypeBrush << 8;
1047 METAFILE_FillBrushData(brush, &object_record->ObjectData.brush);
1048 return Ok;
1049}
1050
1052 GDIPCONST GpRectF* rects, INT count)
1053{
1054 if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
1055 {
1057 GpStatus stat;
1058 BOOL integer_rects = TRUE;
1059 int i;
1060 DWORD brushid;
1061 int flags = 0;
1062
1064 {
1065 flags |= 0x8000;
1066 brushid = ((GpSolidFill*)brush)->color;
1067 }
1068 else
1069 {
1071 if (stat != Ok)
1072 return stat;
1073 }
1074
1075 for (i=0; i<count; i++)
1076 {
1077 if (!is_integer_rect(&rects[i]))
1078 {
1079 integer_rects = FALSE;
1080 break;
1081 }
1082 }
1083
1084 if (integer_rects)
1085 flags |= 0x4000;
1086
1088 sizeof(EmfPlusFillRects) + count * (integer_rects ? sizeof(EmfPlusRect) : sizeof(GpRectF)),
1089 (void**)&record);
1090 if (stat != Ok)
1091 return stat;
1092
1093 record->Header.Type = EmfPlusRecordTypeFillRects;
1094 record->Header.Flags = flags;
1095 record->BrushID = brushid;
1096 record->Count = count;
1097
1098 if (integer_rects)
1099 {
1100 EmfPlusRect *record_rects = (EmfPlusRect*)(record+1);
1101 for (i=0; i<count; i++)
1102 {
1103 record_rects[i].X = (SHORT)rects[i].X;
1104 record_rects[i].Y = (SHORT)rects[i].Y;
1105 record_rects[i].Width = (SHORT)rects[i].Width;
1106 record_rects[i].Height = (SHORT)rects[i].Height;
1107 }
1108 }
1109 else
1110 memcpy(record+1, rects, sizeof(GpRectF) * count);
1111
1113 }
1114
1115 if (metafile->auto_frame)
1116 {
1117 GpPointF corners[4];
1118 int i;
1119
1120 for (i=0; i<count; i++)
1121 {
1122 corners[0].X = rects[i].X;
1123 corners[0].Y = rects[i].Y;
1124 corners[1].X = rects[i].X + rects[i].Width;
1125 corners[1].Y = rects[i].Y;
1126 corners[2].X = rects[i].X;
1127 corners[2].Y = rects[i].Y + rects[i].Height;
1128 corners[3].X = rects[i].X + rects[i].Width;
1129 corners[3].Y = rects[i].Y + rects[i].Height;
1130
1132 CoordinateSpaceWorld, corners, 4);
1133
1134 METAFILE_AdjustFrame(metafile, corners, 4);
1135 }
1136 }
1137
1138 return Ok;
1139}
1140
1142{
1143 if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
1144 {
1146 GpStatus stat;
1147
1149 sizeof(EmfPlusSetClipRect),
1150 (void**)&record);
1151 if (stat != Ok)
1152 return stat;
1153
1154 record->Header.Type = EmfPlusRecordTypeSetClipRect;
1155 record->Header.Flags = (mode & 0xf) << 8;
1156 record->ClipRect.X = x;
1157 record->ClipRect.Y = y;
1158 record->ClipRect.Width = width;
1159 record->ClipRect.Height = height;
1160
1162 }
1163
1164 return Ok;
1165}
1166
1168{
1169 EmfPlusObject *object_record;
1170 DWORD size;
1171 GpStatus stat;
1172
1173 *id = -1;
1174 if (metafile->metafile_type != MetafileTypeEmfPlusOnly && metafile->metafile_type != MetafileTypeEmfPlusDual)
1175 return Ok;
1176
1179 FIELD_OFFSET(EmfPlusObject, ObjectData.region) + size, (void**)&object_record);
1180 if (stat != Ok) return stat;
1181
1183 object_record->Header.Type = EmfPlusRecordTypeObject;
1184 object_record->Header.Flags = *id | ObjectTypeRegion << 8;
1185 write_region_data(region, &object_record->ObjectData.region);
1186 return Ok;
1187}
1188
1190{
1192 DWORD region_id;
1193 GpStatus stat;
1194
1195 if (metafile->metafile_type == MetafileTypeEmf)
1196 {
1197 FIXME("stub!\n");
1198 return NotImplemented;
1199 }
1200
1202 if (stat != Ok) return stat;
1203
1204 stat = METAFILE_AllocateRecord(metafile, sizeof(*record), (void**)&record);
1205 if (stat != Ok) return stat;
1206
1208 record->Flags = region_id | mode << 8;
1209
1211 return Ok;
1212}
1213
1215{
1216 if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
1217 {
1219 GpStatus stat;
1220
1223 (void**)&record);
1224 if (stat != Ok)
1225 return stat;
1226
1228 record->Header.Flags = unit;
1229 record->PageScale = scale;
1230
1232 }
1233
1234 return Ok;
1235}
1236
1238{
1239 if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
1240 {
1242 GpStatus stat;
1243
1246 (void**)&record);
1247 if (stat != Ok)
1248 return stat;
1249
1251 record->Header.Flags = 0;
1252 memcpy(record->MatrixData, transform->matrix, sizeof(record->MatrixData));
1253
1255 }
1256
1257 return Ok;
1258}
1259
1261{
1262 if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
1263 {
1265 GpStatus stat;
1266
1269 (void**)&record);
1270 if (stat != Ok)
1271 return stat;
1272
1274 record->Header.Flags = (order == MatrixOrderAppend ? 0x2000 : 0);
1275 record->Sx = sx;
1276 record->Sy = sy;
1277
1279 }
1280
1281 return Ok;
1282}
1283
1285{
1286 if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
1287 {
1289 GpStatus stat;
1290
1293 (void**)&record);
1294 if (stat != Ok)
1295 return stat;
1296
1298 record->Header.Flags = (order == MatrixOrderAppend ? 0x2000 : 0);
1299 memcpy(record->MatrixData, matrix->matrix, sizeof(record->MatrixData));
1300
1302 }
1303
1304 return Ok;
1305}
1306
1308{
1309 if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
1310 {
1312 GpStatus stat;
1313
1316 (void**)&record);
1317 if (stat != Ok)
1318 return stat;
1319
1321 record->Header.Flags = (order == MatrixOrderAppend ? 0x2000 : 0);
1322 record->Angle = angle;
1323
1325 }
1326
1327 return Ok;
1328}
1329
1331{
1332 if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
1333 {
1335 GpStatus stat;
1336
1339 (void**)&record);
1340 if (stat != Ok)
1341 return stat;
1342
1344 record->Header.Flags = (order == MatrixOrderAppend ? 0x2000 : 0);
1345 record->dx = dx;
1346 record->dy = dy;
1347
1349 }
1350
1351 return Ok;
1352}
1353
1355{
1356 if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
1357 {
1359 GpStatus stat;
1360
1362 sizeof(EmfPlusRecordHeader),
1363 (void**)&record);
1364 if (stat != Ok)
1365 return stat;
1366
1368 record->Flags = 0;
1369
1371 }
1372
1373 return Ok;
1374}
1375
1377 GDIPCONST GpRectF *srcrect, GpUnit unit, DWORD StackIndex)
1378{
1379 if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
1380 {
1382 GpStatus stat;
1383
1384 stat = METAFILE_AllocateRecord(metafile, sizeof(*record), (void**)&record);
1385 if (stat != Ok)
1386 return stat;
1387
1389 record->Header.Flags = unit & 0xff;
1390 record->DestRect = *dstrect;
1391 record->SrcRect = *srcrect;
1392 record->StackIndex = StackIndex;
1393
1395 }
1396
1397 return Ok;
1398}
1399
1401{
1402 if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
1403 {
1405 GpStatus stat;
1406
1408 sizeof(EmfPlusContainerRecord),
1409 (void**)&record);
1410 if (stat != Ok)
1411 return stat;
1412
1414 record->Header.Flags = 0;
1415 record->StackIndex = StackIndex;
1416
1418 }
1419
1420 return Ok;
1421}
1422
1424{
1425 if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
1426 {
1428 GpStatus stat;
1429
1431 sizeof(EmfPlusContainerRecord),
1432 (void**)&record);
1433 if (stat != Ok)
1434 return stat;
1435
1437 record->Header.Flags = 0;
1438 record->StackIndex = StackIndex;
1439
1441 }
1442
1443 return Ok;
1444}
1445
1447{
1448 if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
1449 {
1451 GpStatus stat;
1452
1454 sizeof(EmfPlusContainerRecord),
1455 (void**)&record);
1456 if (stat != Ok)
1457 return stat;
1458
1459 record->Header.Type = EmfPlusRecordTypeSave;
1460 record->Header.Flags = 0;
1461 record->StackIndex = StackIndex;
1462
1464 }
1465
1466 return Ok;
1467}
1468
1470{
1471 if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
1472 {
1474 GpStatus stat;
1475
1477 sizeof(EmfPlusContainerRecord),
1478 (void**)&record);
1479 if (stat != Ok)
1480 return stat;
1481
1482 record->Header.Type = EmfPlusRecordTypeRestore;
1483 record->Header.Flags = 0;
1484 record->StackIndex = StackIndex;
1485
1487 }
1488
1489 return Ok;
1490}
1491
1493{
1494 if (hdc != metafile->record_dc)
1495 return InvalidParameter;
1496
1497 return Ok;
1498}
1499
1501{
1502 GpStatus stat;
1503
1505 metafile->record_graphics = NULL;
1506
1507 metafile->hemf = CloseEnhMetaFile(metafile->record_dc);
1508 metafile->record_dc = NULL;
1509
1510 heap_free(metafile->comment_data);
1511 metafile->comment_data = NULL;
1512 metafile->comment_data_size = 0;
1513
1514 if (stat == Ok)
1515 {
1517
1519 if (stat == Ok && metafile->auto_frame &&
1520 metafile->auto_frame_max.X >= metafile->auto_frame_min.X)
1521 {
1522 RECTL bounds_rc, gdi_bounds_rc;
1523 REAL x_scale = 2540.0 / header.DpiX;
1524 REAL y_scale = 2540.0 / header.DpiY;
1525 BYTE* buffer;
1527
1528 bounds_rc.left = floorf(metafile->auto_frame_min.X * x_scale);
1529 bounds_rc.top = floorf(metafile->auto_frame_min.Y * y_scale);
1530 bounds_rc.right = ceilf(metafile->auto_frame_max.X * x_scale);
1531 bounds_rc.bottom = ceilf(metafile->auto_frame_max.Y * y_scale);
1532
1533 gdi_bounds_rc = header.u.EmfHeader.rclBounds;
1534 if (gdi_bounds_rc.right > gdi_bounds_rc.left && gdi_bounds_rc.bottom > gdi_bounds_rc.top)
1535 {
1536 bounds_rc.left = min(bounds_rc.left, gdi_bounds_rc.left);
1537 bounds_rc.top = min(bounds_rc.top, gdi_bounds_rc.top);
1538 bounds_rc.right = max(bounds_rc.right, gdi_bounds_rc.right);
1539 bounds_rc.bottom = max(bounds_rc.bottom, gdi_bounds_rc.bottom);
1540 }
1541
1544 if (buffer)
1545 {
1546 HENHMETAFILE new_hemf;
1547
1549
1550 ((ENHMETAHEADER*)buffer)->rclFrame = bounds_rc;
1551
1553
1554 if (new_hemf)
1555 {
1557 metafile->hemf = new_hemf;
1558 }
1559 else
1560 stat = OutOfMemory;
1561
1563 }
1564 else
1565 stat = OutOfMemory;
1566
1567 if (stat == Ok)
1569 }
1570 if (stat == Ok)
1571 {
1572 metafile->bounds.X = header.X;
1573 metafile->bounds.Y = header.Y;
1574 metafile->bounds.Width = header.Width;
1575 metafile->bounds.Height = header.Height;
1576 }
1577 }
1578
1579 if (stat == Ok && metafile->record_stream)
1580 {
1581 BYTE *buffer;
1583
1585
1587 if (buffer)
1588 {
1589 HRESULT hr;
1590
1592
1593 hr = IStream_Write(metafile->record_stream, buffer, buffer_size, NULL);
1594
1595 if (FAILED(hr))
1597
1599 }
1600 else
1601 stat = OutOfMemory;
1602 }
1603
1604 if (metafile->record_stream)
1605 {
1606 IStream_Release(metafile->record_stream);
1607 metafile->record_stream = NULL;
1608 }
1609
1610 return stat;
1611}
1612
1614{
1615 TRACE("(%p,%p)\n", metafile, hEmf);
1616
1617 if (!metafile || !hEmf || !metafile->hemf)
1618 return InvalidParameter;
1619
1620 *hEmf = metafile->hemf;
1621 metafile->hemf = NULL;
1622
1623 return Ok;
1624}
1625
1627{
1628 const GpRectF *rect;
1629 const GpPointF *pt;
1630
1631 /* This transforms metafile device space to output points. */
1632 rect = &metafile->src_rect;
1633 pt = metafile->playback_points;
1634 result->eM11 = (pt[1].X - pt[0].X) / rect->Width;
1635 result->eM21 = (pt[2].X - pt[0].X) / rect->Height;
1636 result->eDx = pt[0].X - result->eM11 * rect->X - result->eM21 * rect->Y;
1637 result->eM12 = (pt[1].Y - pt[0].Y) / rect->Width;
1638 result->eM22 = (pt[2].Y - pt[0].Y) / rect->Height;
1639 result->eDy = pt[0].Y - result->eM12 * rect->X - result->eM22 * rect->Y;
1640}
1641
1643{
1644 XFORM combined, final;
1645
1647
1648 CombineTransform(&combined, &metafile->gdiworldtransform, &final);
1649
1650 SetGraphicsMode(metafile->playback_dc, GM_ADVANCED);
1651 SetWorldTransform(metafile->playback_dc, &combined);
1652
1653 return Ok;
1654}
1655
1657{
1658 GpStatus stat = Ok;
1659
1660 stat = GdipGetDC(metafile->playback_graphics, &metafile->playback_dc);
1661
1662 if (stat == Ok)
1663 {
1664 static const XFORM identity = {1, 0, 0, 1, 0, 0};
1665
1666 metafile->gdiworldtransform = identity;
1668 }
1669
1670 return stat;
1671}
1672
1674{
1675 if (metafile->playback_dc)
1676 {
1677 GdipReleaseDC(metafile->playback_graphics, metafile->playback_dc);
1678 metafile->playback_dc = NULL;
1679 }
1680}
1681
1683{
1684 GpStatus stat;
1685 stat = GdipCombineRegionRegion(metafile->playback_graphics->clip, metafile->base_clip, CombineModeReplace);
1686 if (stat == Ok)
1687 stat = GdipCombineRegionRegion(metafile->playback_graphics->clip, metafile->clip, CombineModeIntersect);
1688 return stat;
1689}
1690
1692{
1693 GpMatrix *real_transform;
1694 GpStatus stat;
1695
1696 stat = GdipCreateMatrix3(&metafile->src_rect, metafile->playback_points, &real_transform);
1697
1698 if (stat == Ok)
1699 {
1700 REAL scale = units_to_pixels(1.0, metafile->page_unit, 96.0);
1701
1702 if (metafile->page_unit != UnitDisplay)
1703 scale *= metafile->page_scale;
1704
1705 stat = GdipScaleMatrix(real_transform, scale, scale, MatrixOrderPrepend);
1706
1707 if (stat == Ok)
1708 stat = GdipMultiplyMatrix(real_transform, metafile->world_transform, MatrixOrderPrepend);
1709
1710 if (stat == Ok)
1711 stat = GdipSetWorldTransform(metafile->playback_graphics, real_transform);
1712
1713 GdipDeleteMatrix(real_transform);
1714 }
1715
1716 return stat;
1717}
1718
1720{
1722 metafile->objtable[id].type = type;
1723 metafile->objtable[id].u.object = object;
1724}
1725
1726static GpStatus metafile_deserialize_image(const BYTE *record_data, UINT data_size, GpImage **image)
1727{
1728 EmfPlusImage *data = (EmfPlusImage *)record_data;
1730
1731 *image = NULL;
1732
1733 if (data_size < FIELD_OFFSET(EmfPlusImage, ImageData))
1734 return InvalidParameter;
1735 data_size -= FIELD_OFFSET(EmfPlusImage, ImageData);
1736
1737 switch (data->Type)
1738 {
1740 {
1741 EmfPlusBitmap *bitmapdata = &data->ImageData.bitmap;
1742
1743 if (data_size <= FIELD_OFFSET(EmfPlusBitmap, BitmapData))
1744 return InvalidParameter;
1745 data_size -= FIELD_OFFSET(EmfPlusBitmap, BitmapData);
1746
1747 switch (bitmapdata->Type)
1748 {
1750 {
1752 BYTE *scan0;
1753
1754 if (bitmapdata->PixelFormat & PixelFormatIndexed)
1755 {
1756 EmfPlusPalette *palette_obj = (EmfPlusPalette *)bitmapdata->BitmapData;
1757 UINT palette_size = FIELD_OFFSET(EmfPlusPalette, PaletteEntries);
1758
1759 if (data_size <= palette_size)
1760 return InvalidParameter;
1761 palette_size += palette_obj->PaletteCount * sizeof(EmfPlusARGB);
1762
1763 if (data_size < palette_size)
1764 return InvalidParameter;
1765 data_size -= palette_size;
1766
1767 palette = (ColorPalette *)bitmapdata->BitmapData;
1768 scan0 = (BYTE *)bitmapdata->BitmapData + palette_size;
1769 }
1770 else
1771 {
1772 palette = NULL;
1773 scan0 = bitmapdata->BitmapData;
1774 }
1775
1776 if (data_size < bitmapdata->Height * bitmapdata->Stride)
1777 return InvalidParameter;
1778
1779 status = GdipCreateBitmapFromScan0(bitmapdata->Width, bitmapdata->Height, bitmapdata->Stride,
1780 bitmapdata->PixelFormat, scan0, (GpBitmap **)image);
1781 if (status == Ok && palette)
1782 {
1784 if (status != Ok)
1785 {
1787 *image = NULL;
1788 }
1789 }
1790 break;
1791 }
1793 {
1796 HRESULT hr;
1797
1798 if (WICCreateImagingFactory_Proxy(WINCODEC_SDK_VERSION, &factory) != S_OK)
1799 return GenericError;
1800
1801 hr = IWICImagingFactory_CreateStream(factory, &stream);
1802 IWICImagingFactory_Release(factory);
1803 if (hr != S_OK)
1804 return GenericError;
1805
1806 if (IWICStream_InitializeFromMemory(stream, bitmapdata->BitmapData, data_size) == S_OK)
1808 else
1810
1811 IWICStream_Release(stream);
1812 break;
1813 }
1814 default:
1815 WARN("Invalid bitmap type %d.\n", bitmapdata->Type);
1816 return InvalidParameter;
1817 }
1818 break;
1819 }
1820 default:
1821 FIXME("image type %d not supported.\n", data->Type);
1822 return NotImplemented;
1823 }
1824
1825 return status;
1826}
1827
1828static GpStatus metafile_deserialize_path(const BYTE *record_data, UINT data_size, GpPath **path)
1829{
1830 EmfPlusPath *data = (EmfPlusPath *)record_data;
1832 BYTE *types;
1833 UINT size;
1834 DWORD i;
1835
1836 *path = NULL;
1837
1838 if (data_size <= FIELD_OFFSET(EmfPlusPath, data))
1839 return InvalidParameter;
1840 data_size -= FIELD_OFFSET(EmfPlusPath, data);
1841
1842 if (data->PathPointFlags & 0x800) /* R */
1843 {
1844 FIXME("RLE encoded path data is not supported.\n");
1845 return NotImplemented;
1846 }
1847 else
1848 {
1849 if (data->PathPointFlags & 0x4000) /* C */
1850 size = sizeof(EmfPlusPoint);
1851 else
1852 size = sizeof(EmfPlusPointF);
1853 size += sizeof(BYTE); /* EmfPlusPathPointType */
1854 size *= data->PathPointCount;
1855 }
1856
1857 if (data_size < size)
1858 return InvalidParameter;
1859
1861 if (status != Ok)
1862 return status;
1863
1864 (*path)->pathdata.Count = data->PathPointCount;
1865 (*path)->pathdata.Points = GdipAlloc(data->PathPointCount * sizeof(*(*path)->pathdata.Points));
1866 (*path)->pathdata.Types = GdipAlloc(data->PathPointCount * sizeof(*(*path)->pathdata.Types));
1867 (*path)->datalen = (*path)->pathdata.Count;
1868
1869 if (!(*path)->pathdata.Points || !(*path)->pathdata.Types)
1870 {
1872 return OutOfMemory;
1873 }
1874
1875 if (data->PathPointFlags & 0x4000) /* C */
1876 {
1878 for (i = 0; i < data->PathPointCount; i++)
1879 {
1880 (*path)->pathdata.Points[i].X = points[i].X;
1881 (*path)->pathdata.Points[i].Y = points[i].Y;
1882 }
1883 types = (BYTE *)(points + i);
1884 }
1885 else
1886 {
1888 memcpy((*path)->pathdata.Points, points, sizeof(*points) * data->PathPointCount);
1889 types = (BYTE *)(points + data->PathPointCount);
1890 }
1891
1892 memcpy((*path)->pathdata.Types, types, sizeof(*types) * data->PathPointCount);
1893
1894 return Ok;
1895}
1896
1898{
1899 const DWORD *type;
1901
1902 type = buffer_read(mbuf, sizeof(*type));
1903 if (!type) return Ok;
1904
1905 node->type = *type;
1906
1907 switch (node->type)
1908 {
1909 case CombineModeReplace:
1911 case CombineModeUnion:
1912 case CombineModeXor:
1913 case CombineModeExclude:
1915 {
1917
1918 left = heap_alloc_zero(sizeof(*left));
1919 if (!left)
1920 return OutOfMemory;
1921
1922 right = heap_alloc_zero(sizeof(*right));
1923 if (!right)
1924 {
1925 heap_free(left);
1926 return OutOfMemory;
1927 }
1928
1930 if (status == Ok)
1931 {
1933 if (status == Ok)
1934 {
1935 node->elementdata.combine.left = left;
1936 node->elementdata.combine.right = right;
1937 region->num_children += 2;
1938 return Ok;
1939 }
1940 }
1941
1942 heap_free(left);
1944 return status;
1945 }
1946 case RegionDataRect:
1947 {
1948 const EmfPlusRectF *rect;
1949
1950 rect = buffer_read(mbuf, sizeof(*rect));
1951 if (!rect)
1952 return InvalidParameter;
1953
1954 memcpy(&node->elementdata.rect, rect, sizeof(*rect));
1955 *count += 1;
1956 return Ok;
1957 }
1958 case RegionDataPath:
1959 {
1960 const BYTE *path_data;
1961 const UINT *data_size;
1962 GpPath *path;
1963
1964 data_size = buffer_read(mbuf, FIELD_OFFSET(EmfPlusRegionNodePath, RegionNodePath));
1965 if (!data_size)
1966 return InvalidParameter;
1967
1968 path_data = buffer_read(mbuf, *data_size);
1969 if (!path_data)
1970 return InvalidParameter;
1971
1972 status = metafile_deserialize_path(path_data, *data_size, &path);
1973 if (status == Ok)
1974 {
1975 node->elementdata.path = path;
1976 *count += 1;
1977 }
1978 return Ok;
1979 }
1982 *count += 1;
1983 return Ok;
1984 default:
1985 FIXME("element type %#x is not supported\n", *type);
1986 break;
1987 }
1988
1989 return InvalidParameter;
1990}
1991
1992static GpStatus metafile_deserialize_region(const BYTE *record_data, UINT data_size, GpRegion **region)
1993{
1994 struct memory_buffer mbuf;
1996 UINT count;
1997
1998 *region = NULL;
1999
2000 init_memory_buffer(&mbuf, record_data, data_size);
2001
2002 if (!buffer_read(&mbuf, FIELD_OFFSET(EmfPlusRegion, RegionNode)))
2003 return InvalidParameter;
2004
2005 status = GdipCreateRegion(region);
2006 if (status != Ok)
2007 return status;
2008
2009 count = 0;
2010 status = metafile_read_region_node(&mbuf, *region, &(*region)->node, &count);
2011 if (status == Ok && !count)
2013
2014 if (status != Ok)
2015 {
2016 GdipDeleteRegion(*region);
2017 *region = NULL;
2018 }
2019
2020 return status;
2021}
2022
2023static GpStatus metafile_deserialize_brush(const BYTE *record_data, UINT data_size, GpBrush **brush)
2024{
2025 static const UINT header_size = FIELD_OFFSET(EmfPlusBrush, BrushData);
2026 EmfPlusBrush *data = (EmfPlusBrush *)record_data;
2028 DWORD brushflags;
2030 UINT offset;
2031
2032 *brush = NULL;
2033
2034 if (data_size < header_size)
2035 return InvalidParameter;
2036
2037 switch (data->Type)
2038 {
2040 if (data_size != header_size + sizeof(EmfPlusSolidBrushData))
2041 return InvalidParameter;
2042
2043 status = GdipCreateSolidFill(data->BrushData.solid.SolidColor, (GpSolidFill **)brush);
2044 break;
2045 case BrushTypeHatchFill:
2046 if (data_size != header_size + sizeof(EmfPlusHatchBrushData))
2047 return InvalidParameter;
2048
2049 status = GdipCreateHatchBrush(data->BrushData.hatch.HatchStyle, data->BrushData.hatch.ForeColor,
2050 data->BrushData.hatch.BackColor, (GpHatch **)brush);
2051 break;
2053 {
2054 GpImage *image;
2055
2056 offset = header_size + FIELD_OFFSET(EmfPlusTextureBrushData, OptionalData);
2057 if (data_size <= offset)
2058 return InvalidParameter;
2059
2060 brushflags = data->BrushData.texture.BrushDataFlags;
2061 if (brushflags & BrushDataTransform)
2062 {
2063 if (data_size <= offset + sizeof(EmfPlusTransformMatrix))
2064 return InvalidParameter;
2065 transform = (EmfPlusTransformMatrix *)(record_data + offset);
2066 offset += sizeof(EmfPlusTransformMatrix);
2067 }
2068
2069 status = metafile_deserialize_image(record_data + offset, data_size - offset, &image);
2070 if (status != Ok)
2071 return status;
2072
2073 status = GdipCreateTexture(image, data->BrushData.texture.WrapMode, (GpTexture **)brush);
2074 if (status == Ok && transform && !(brushflags & BrushDataDoNotTransform))
2076
2078 break;
2079 }
2081 {
2082 GpLineGradient *gradient = NULL;
2083 GpPointF startpoint, endpoint;
2084 UINT position_count = 0;
2085
2086 offset = header_size + FIELD_OFFSET(EmfPlusLinearGradientBrushData, OptionalData);
2087 if (data_size <= offset)
2088 return InvalidParameter;
2089
2090 brushflags = data->BrushData.lineargradient.BrushDataFlags;
2091 if ((brushflags & BrushDataPresetColors) && (brushflags & (BrushDataBlendFactorsH | BrushDataBlendFactorsV)))
2092 return InvalidParameter;
2093
2094 if (brushflags & BrushDataTransform)
2095 {
2096 if (data_size <= offset + sizeof(EmfPlusTransformMatrix))
2097 return InvalidParameter;
2098 transform = (EmfPlusTransformMatrix *)(record_data + offset);
2099 offset += sizeof(EmfPlusTransformMatrix);
2100 }
2101
2103 {
2104 if (data_size <= offset + sizeof(DWORD)) /* Number of factors/preset colors. */
2105 return InvalidParameter;
2106 position_count = *(DWORD *)(record_data + offset);
2107 offset += sizeof(DWORD);
2108 }
2109
2110 if (brushflags & BrushDataPresetColors)
2111 {
2112 if (data_size != offset + position_count * (sizeof(float) + sizeof(EmfPlusARGB)))
2113 return InvalidParameter;
2114 }
2115 else if (brushflags & BrushDataBlendFactorsH)
2116 {
2117 if (data_size != offset + position_count * 2 * sizeof(float))
2118 return InvalidParameter;
2119 }
2120
2121 startpoint.X = data->BrushData.lineargradient.RectF.X;
2122 startpoint.Y = data->BrushData.lineargradient.RectF.Y;
2123 endpoint.X = startpoint.X + data->BrushData.lineargradient.RectF.Width;
2124 endpoint.Y = startpoint.Y + data->BrushData.lineargradient.RectF.Height;
2125
2126 status = GdipCreateLineBrush(&startpoint, &endpoint, data->BrushData.lineargradient.StartColor,
2127 data->BrushData.lineargradient.EndColor, data->BrushData.lineargradient.WrapMode, &gradient);
2128 if (status == Ok)
2129 {
2130 if (transform)
2131 status = GdipSetLineTransform(gradient, (const GpMatrix *)transform);
2132
2133 if (status == Ok)
2134 {
2135 if (brushflags & BrushDataPresetColors)
2136 status = GdipSetLinePresetBlend(gradient, (ARGB *)(record_data + offset +
2137 position_count * sizeof(REAL)), (REAL *)(record_data + offset), position_count);
2138 else if (brushflags & BrushDataBlendFactorsH)
2139 status = GdipSetLineBlend(gradient, (REAL *)(record_data + offset + position_count * sizeof(REAL)),
2140 (REAL *)(record_data + offset), position_count);
2141
2142 if (brushflags & BrushDataIsGammaCorrected)
2143 FIXME("BrushDataIsGammaCorrected is not handled.\n");
2144 }
2145 }
2146
2147 if (status == Ok)
2148 *brush = (GpBrush *)gradient;
2149 else
2150 GdipDeleteBrush((GpBrush *)gradient);
2151
2152 break;
2153 }
2154 default:
2155 FIXME("brush type %u is not supported.\n", data->Type);
2156 return NotImplemented;
2157 }
2158
2159 return status;
2160}
2161
2163{
2164 EmfPlusPenData *pendata = (EmfPlusPenData *)data->data;
2166
2167 if (data_size <= offset)
2168 return InvalidParameter;
2169
2170 offset += FIELD_OFFSET(EmfPlusPenData, OptionalData);
2171 if (data_size <= offset)
2172 return InvalidParameter;
2173
2174 if (pendata->PenDataFlags & PenDataTransform)
2175 offset += sizeof(EmfPlusTransformMatrix);
2176
2177 if (pendata->PenDataFlags & PenDataStartCap)
2178 offset += sizeof(DWORD);
2179
2180 if (pendata->PenDataFlags & PenDataEndCap)
2181 offset += sizeof(DWORD);
2182
2183 if (pendata->PenDataFlags & PenDataJoin)
2184 offset += sizeof(DWORD);
2185
2186 if (pendata->PenDataFlags & PenDataMiterLimit)
2187 offset += sizeof(REAL);
2188
2189 if (pendata->PenDataFlags & PenDataLineStyle)
2190 offset += sizeof(DWORD);
2191
2192 if (pendata->PenDataFlags & PenDataDashedLineCap)
2193 offset += sizeof(DWORD);
2194
2196 offset += sizeof(REAL);
2197
2198 if (pendata->PenDataFlags & PenDataDashedLine)
2199 {
2201
2203 if (data_size <= offset)
2204 return InvalidParameter;
2205
2206 offset += dashedline->DashedLineDataSize * sizeof(float);
2207 }
2208
2209 if (pendata->PenDataFlags & PenDataNonCenter)
2210 offset += sizeof(DWORD);
2211
2212 if (pendata->PenDataFlags & PenDataCompoundLine)
2213 {
2215
2217 if (data_size <= offset)
2218 return InvalidParameter;
2219
2220 offset += compoundline->CompoundLineDataSize * sizeof(float);
2221 }
2222
2223 if (pendata->PenDataFlags & PenDataCustomStartCap)
2224 {
2226
2228 if (data_size <= offset)
2229 return InvalidParameter;
2230
2231 offset += startcap->CustomStartCapSize;
2232 }
2233
2234 if (pendata->PenDataFlags & PenDataCustomEndCap)
2235 {
2237
2239 if (data_size <= offset)
2240 return InvalidParameter;
2241
2242 offset += endcap->CustomEndCapSize;
2243 }
2244
2245 *ret = offset;
2246 return Ok;
2247}
2248
2249static GpStatus METAFILE_PlaybackObject(GpMetafile *metafile, UINT flags, UINT data_size, const BYTE *record_data)
2250{
2251 BYTE type = (flags >> 8) & 0xff;
2252 BYTE id = flags & 0xff;
2253 void *object = NULL;
2255
2257 return InvalidParameter;
2258
2259 switch (type)
2260 {
2261 case ObjectTypeBrush:
2262 status = metafile_deserialize_brush(record_data, data_size, (GpBrush **)&object);
2263 break;
2264 case ObjectTypePen:
2265 {
2266 EmfPlusPen *data = (EmfPlusPen *)record_data;
2267 EmfPlusPenData *pendata = (EmfPlusPenData *)data->data;
2268 GpBrush *brush;
2269 DWORD offset;
2270 GpPen *pen;
2271
2273 if (status != Ok)
2274 return status;
2275
2276 status = metafile_deserialize_brush(record_data + offset, data_size - offset, &brush);
2277 if (status != Ok)
2278 return status;
2279
2280 status = GdipCreatePen2(brush, pendata->PenWidth, pendata->PenUnit, &pen);
2281 GdipDeleteBrush(brush);
2282 if (status != Ok)
2283 return status;
2284
2285 offset = FIELD_OFFSET(EmfPlusPenData, OptionalData);
2286
2287 if (pendata->PenDataFlags & PenDataTransform)
2288 {
2289 FIXME("PenDataTransform is not supported.\n");
2290 offset += sizeof(EmfPlusTransformMatrix);
2291 }
2292
2293 if (pendata->PenDataFlags & PenDataStartCap)
2294 {
2295 if ((status = GdipSetPenStartCap(pen, *(DWORD *)((BYTE *)pendata + offset))) != Ok)
2296 goto penfailed;
2297 offset += sizeof(DWORD);
2298 }
2299
2300 if (pendata->PenDataFlags & PenDataEndCap)
2301 {
2302 if ((status = GdipSetPenEndCap(pen, *(DWORD *)((BYTE *)pendata + offset))) != Ok)
2303 goto penfailed;
2304 offset += sizeof(DWORD);
2305 }
2306
2307 if (pendata->PenDataFlags & PenDataJoin)
2308 {
2309 if ((status = GdipSetPenLineJoin(pen, *(DWORD *)((BYTE *)pendata + offset))) != Ok)
2310 goto penfailed;
2311 offset += sizeof(DWORD);
2312 }
2313
2314 if (pendata->PenDataFlags & PenDataMiterLimit)
2315 {
2316 if ((status = GdipSetPenMiterLimit(pen, *(REAL *)((BYTE *)pendata + offset))) != Ok)
2317 goto penfailed;
2318 offset += sizeof(REAL);
2319 }
2320
2321 if (pendata->PenDataFlags & PenDataLineStyle)
2322 {
2323 if ((status = GdipSetPenDashStyle(pen, *(DWORD *)((BYTE *)pendata + offset))) != Ok)
2324 goto penfailed;
2325 offset += sizeof(DWORD);
2326 }
2327
2328 if (pendata->PenDataFlags & PenDataDashedLineCap)
2329 {
2330 FIXME("PenDataDashedLineCap is not supported.\n");
2331 offset += sizeof(DWORD);
2332 }
2333
2335 {
2336 if ((status = GdipSetPenDashOffset(pen, *(REAL *)((BYTE *)pendata + offset))) != Ok)
2337 goto penfailed;
2338 offset += sizeof(REAL);
2339 }
2340
2341 if (pendata->PenDataFlags & PenDataDashedLine)
2342 {
2343 EmfPlusDashedLineData *dashedline = (EmfPlusDashedLineData *)((BYTE *)pendata + offset);
2344 FIXME("PenDataDashedLine is not supported.\n");
2346 }
2347
2348 if (pendata->PenDataFlags & PenDataNonCenter)
2349 {
2350 FIXME("PenDataNonCenter is not supported.\n");
2351 offset += sizeof(DWORD);
2352 }
2353
2354 if (pendata->PenDataFlags & PenDataCompoundLine)
2355 {
2356 EmfPlusCompoundLineData *compoundline = (EmfPlusCompoundLineData *)((BYTE *)pendata + offset);
2357 FIXME("PenDataCompundLine is not supported.\n");
2359 }
2360
2361 if (pendata->PenDataFlags & PenDataCustomStartCap)
2362 {
2363 EmfPlusCustomStartCapData *startcap = (EmfPlusCustomStartCapData *)((BYTE *)pendata + offset);
2364 FIXME("PenDataCustomStartCap is not supported.\n");
2366 }
2367
2368 if (pendata->PenDataFlags & PenDataCustomEndCap)
2369 {
2370 EmfPlusCustomEndCapData *endcap = (EmfPlusCustomEndCapData *)((BYTE *)pendata + offset);
2371 FIXME("PenDataCustomEndCap is not supported.\n");
2373 }
2374
2375 object = pen;
2376 break;
2377
2378 penfailed:
2379 GdipDeletePen(pen);
2380 return status;
2381 }
2382 case ObjectTypePath:
2383 status = metafile_deserialize_path(record_data, data_size, (GpPath **)&object);
2384 break;
2385 case ObjectTypeRegion:
2386 status = metafile_deserialize_region(record_data, data_size, (GpRegion **)&object);
2387 break;
2388 case ObjectTypeImage:
2389 status = metafile_deserialize_image(record_data, data_size, (GpImage **)&object);
2390 break;
2391 case ObjectTypeFont:
2392 {
2393 EmfPlusFont *data = (EmfPlusFont *)record_data;
2394 GpFontFamily *family;
2395 WCHAR *familyname;
2396
2397 if (data_size <= FIELD_OFFSET(EmfPlusFont, FamilyName))
2398 return InvalidParameter;
2399 data_size -= FIELD_OFFSET(EmfPlusFont, FamilyName);
2400
2401 if (data_size < data->Length * sizeof(WCHAR))
2402 return InvalidParameter;
2403
2404 if (!(familyname = GdipAlloc((data->Length + 1) * sizeof(*familyname))))
2405 return OutOfMemory;
2406
2407 memcpy(familyname, data->FamilyName, data->Length * sizeof(*familyname));
2408 familyname[data->Length] = 0;
2409
2410 status = GdipCreateFontFamilyFromName(familyname, NULL, &family);
2411 GdipFree(familyname);
2412 if (status != Ok)
2413 return InvalidParameter;
2414
2415 status = GdipCreateFont(family, data->EmSize, data->FontStyleFlags, data->SizeUnit, (GpFont **)&object);
2416 GdipDeleteFontFamily(family);
2417 break;
2418 }
2420 {
2422 GpImageAttributes *attributes = NULL;
2423
2424 if (data_size != sizeof(*data))
2425 return InvalidParameter;
2426
2427 if ((status = GdipCreateImageAttributes(&attributes)) != Ok)
2428 return status;
2429
2430 status = GdipSetImageAttributesWrapMode(attributes, data->WrapMode, *(DWORD *)&data->ClampColor,
2431 !!data->ObjectClamp);
2432 if (status == Ok)
2433 object = attributes;
2434 else
2435 GdipDisposeImageAttributes(attributes);
2436 break;
2437 }
2438 default:
2439 FIXME("not implemented for object type %d.\n", type);
2440 return NotImplemented;
2441 }
2442
2443 if (status == Ok)
2445
2446 return status;
2447}
2448
2450{
2451 GpMatrix world_to_device;
2452
2453 get_graphics_transform(metafile->playback_graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, &world_to_device);
2454
2455 GdipTransformRegion(region, &world_to_device);
2456 GdipCombineRegionRegion(metafile->clip, region, mode);
2457
2459}
2460
2463{
2464 GpStatus stat;
2465 GpMetafile *real_metafile = (GpMetafile*)metafile;
2466
2467 TRACE("(%p,%x,%x,%d,%p)\n", metafile, recordType, flags, dataSize, data);
2468
2469 if (!metafile || (dataSize && !data) || !metafile->playback_graphics)
2470 return InvalidParameter;
2471
2472 if (recordType >= 1 && recordType <= 0x7a)
2473 {
2474 /* regular EMF record */
2475 if (metafile->playback_dc)
2476 {
2477 switch (recordType)
2478 {
2479 case EMR_SETMAPMODE:
2480 case EMR_SAVEDC:
2481 case EMR_RESTOREDC:
2482 case EMR_SETWINDOWORGEX:
2483 case EMR_SETWINDOWEXTEX:
2489 FIXME("not implemented for record type %x\n", recordType);
2490 break;
2492 {
2493 const XFORM* xform = (void*)data;
2494 real_metafile->gdiworldtransform = *xform;
2496 break;
2497 }
2499 {
2500 DWORD rgndatasize = *(DWORD*)data;
2501 DWORD mode = *(DWORD*)(data + 4);
2502 const RGNDATA *rgndata = (const RGNDATA*)(data + 8);
2503 HRGN hrgn = NULL;
2504
2505 if (dataSize > 8)
2506 {
2507 XFORM final;
2508
2510
2511 hrgn = ExtCreateRegion(&final, rgndatasize, rgndata);
2512 }
2513
2514 ExtSelectClipRgn(metafile->playback_dc, hrgn, mode);
2515
2517
2518 return Ok;
2519 }
2520 default:
2521 {
2522 ENHMETARECORD *record = heap_alloc_zero(dataSize + 8);
2523
2524 if (record)
2525 {
2526 record->iType = recordType;
2527 record->nSize = dataSize + 8;
2528 memcpy(record->dParm, data, dataSize);
2529
2530 if(PlayEnhMetaFileRecord(metafile->playback_dc, metafile->handle_table,
2531 record, metafile->handle_count) == 0)
2532 ERR("PlayEnhMetaFileRecord failed\n");
2533
2535 }
2536 else
2537 return OutOfMemory;
2538
2539 break;
2540 }
2541 }
2542 }
2543 }
2544 else
2545 {
2547
2549
2550 switch(recordType)
2551 {
2554 break;
2557 break;
2559 {
2561
2562 if (dataSize != sizeof(record->Color))
2563 return InvalidParameter;
2564
2565 return GdipGraphicsClear(metafile->playback_graphics, record->Color);
2566 }
2568 {
2570 GpBrush *brush, *temp_brush=NULL;
2571 GpRectF *rects, *temp_rects=NULL;
2572
2573 if (dataSize + sizeof(EmfPlusRecordHeader) < sizeof(EmfPlusFillRects))
2574 return InvalidParameter;
2575
2576 if (flags & 0x4000)
2577 {
2578 if (dataSize + sizeof(EmfPlusRecordHeader) < sizeof(EmfPlusFillRects) + sizeof(EmfPlusRect) * record->Count)
2579 return InvalidParameter;
2580 }
2581 else
2582 {
2583 if (dataSize + sizeof(EmfPlusRecordHeader) < sizeof(EmfPlusFillRects) + sizeof(GpRectF) * record->Count)
2584 return InvalidParameter;
2585 }
2586
2587 if (flags & 0x8000)
2588 {
2589 stat = GdipCreateSolidFill(record->BrushID, (GpSolidFill **)&temp_brush);
2590 brush = temp_brush;
2591 }
2592 else
2593 {
2594 if (record->BrushID >= EmfPlusObjectTableSize ||
2595 real_metafile->objtable[record->BrushID].type != ObjectTypeBrush)
2596 return InvalidParameter;
2597
2598 brush = real_metafile->objtable[record->BrushID].u.brush;
2599 stat = Ok;
2600 }
2601
2602 if (stat == Ok)
2603 {
2604 if (flags & 0x4000)
2605 {
2606 EmfPlusRect *int_rects = (EmfPlusRect*)(record+1);
2607 int i;
2608
2609 rects = temp_rects = heap_alloc_zero(sizeof(GpRectF) * record->Count);
2610 if (rects)
2611 {
2612 for (i=0; i<record->Count; i++)
2613 {
2614 rects[i].X = int_rects[i].X;
2615 rects[i].Y = int_rects[i].Y;
2616 rects[i].Width = int_rects[i].Width;
2617 rects[i].Height = int_rects[i].Height;
2618 }
2619 }
2620 else
2621 stat = OutOfMemory;
2622 }
2623 else
2624 rects = (GpRectF*)(record+1);
2625 }
2626
2627 if (stat == Ok)
2628 {
2629 stat = GdipFillRectangles(metafile->playback_graphics, brush, rects, record->Count);
2630 }
2631
2632 GdipDeleteBrush(temp_brush);
2633 heap_free(temp_rects);
2634
2635 return stat;
2636 }
2638 {
2640 CombineMode mode = (CombineMode)((flags >> 8) & 0xf);
2641 GpRegion *region;
2642
2643 if (dataSize + sizeof(EmfPlusRecordHeader) < sizeof(*record))
2644 return InvalidParameter;
2645
2646 stat = GdipCreateRegionRect(&record->ClipRect, &region);
2647
2648 if (stat == Ok)
2649 {
2650 stat = metafile_set_clip_region(real_metafile, region, mode);
2651 GdipDeleteRegion(region);
2652 }
2653
2654 return stat;
2655 }
2657 {
2658 CombineMode mode = (flags >> 8) & 0xf;
2659 BYTE regionid = flags & 0xff;
2660 GpRegion *region;
2661
2662 if (dataSize != 0)
2663 return InvalidParameter;
2664
2665 if (regionid >= EmfPlusObjectTableSize || real_metafile->objtable[regionid].type != ObjectTypeRegion)
2666 return InvalidParameter;
2667
2668 stat = GdipCloneRegion(real_metafile->objtable[regionid].u.region, &region);
2669 if (stat == Ok)
2670 {
2671 stat = metafile_set_clip_region(real_metafile, region, mode);
2672 GdipDeleteRegion(region);
2673 }
2674
2675 return stat;
2676 }
2678 {
2679 CombineMode mode = (flags >> 8) & 0xf;
2680 BYTE pathid = flags & 0xff;
2681 GpRegion *region;
2682
2683 if (dataSize != 0)
2684 return InvalidParameter;
2685
2686 if (pathid >= EmfPlusObjectTableSize || real_metafile->objtable[pathid].type != ObjectTypePath)
2687 return InvalidParameter;
2688
2689 stat = GdipCreateRegionPath(real_metafile->objtable[pathid].u.path, &region);
2690 if (stat == Ok)
2691 {
2692 stat = metafile_set_clip_region(real_metafile, region, mode);
2693 GdipDeleteRegion(region);
2694 }
2695
2696 return stat;
2697 }
2699 {
2702
2704 return InvalidParameter;
2705
2706 real_metafile->page_unit = unit;
2707 real_metafile->page_scale = record->PageScale;
2708
2709 return METAFILE_PlaybackUpdateWorldTransform(real_metafile);
2710 }
2712 {
2714
2716 return InvalidParameter;
2717
2718 memcpy(real_metafile->world_transform->matrix, record->MatrixData, sizeof(record->MatrixData));
2719
2720 return METAFILE_PlaybackUpdateWorldTransform(real_metafile);
2721 }
2723 {
2726
2728 return InvalidParameter;
2729
2730 GdipScaleMatrix(real_metafile->world_transform, record->Sx, record->Sy, order);
2731
2732 return METAFILE_PlaybackUpdateWorldTransform(real_metafile);
2733 }
2735 {
2739
2741 return InvalidParameter;
2742
2743 memcpy(matrix.matrix, record->MatrixData, sizeof(matrix.matrix));
2744
2746
2747 return METAFILE_PlaybackUpdateWorldTransform(real_metafile);
2748 }
2750 {
2753
2755 return InvalidParameter;
2756
2757 GdipRotateMatrix(real_metafile->world_transform, record->Angle, order);
2758
2759 return METAFILE_PlaybackUpdateWorldTransform(real_metafile);
2760 }
2762 {
2765
2767 return InvalidParameter;
2768
2769 GdipTranslateMatrix(real_metafile->world_transform, record->dx, record->dy, order);
2770
2771 return METAFILE_PlaybackUpdateWorldTransform(real_metafile);
2772 }
2774 {
2775 GdipSetMatrixElements(real_metafile->world_transform, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
2776
2777 return METAFILE_PlaybackUpdateWorldTransform(real_metafile);
2778 }
2780 {
2782 container* cont;
2783 GpUnit unit;
2784 REAL scale_x, scale_y;
2785 GpRectF scaled_srcrect;
2787
2788 cont = heap_alloc_zero(sizeof(*cont));
2789 if (!cont)
2790 return OutOfMemory;
2791
2792 stat = GdipCloneRegion(metafile->clip, &cont->clip);
2793 if (stat != Ok)
2794 {
2795 heap_free(cont);
2796 return stat;
2797 }
2798
2799 stat = GdipBeginContainer2(metafile->playback_graphics, &cont->state);
2800
2801 if (stat != Ok)
2802 {
2803 GdipDeleteRegion(cont->clip);
2804 heap_free(cont);
2805 return stat;
2806 }
2807
2808 cont->id = record->StackIndex;
2809 cont->type = BEGIN_CONTAINER;
2810 cont->world_transform = *metafile->world_transform;
2811 cont->page_unit = metafile->page_unit;
2812 cont->page_scale = metafile->page_scale;
2813 list_add_head(&real_metafile->containers, &cont->entry);
2814
2815 unit = record->Header.Flags & 0xff;
2816
2817 scale_x = units_to_pixels(1.0, unit, metafile->image.xres);
2818 scale_y = units_to_pixels(1.0, unit, metafile->image.yres);
2819
2820 scaled_srcrect.X = scale_x * record->SrcRect.X;
2821 scaled_srcrect.Y = scale_y * record->SrcRect.Y;
2822 scaled_srcrect.Width = scale_x * record->SrcRect.Width;
2823 scaled_srcrect.Height = scale_y * record->SrcRect.Height;
2824
2825 transform.matrix[0] = record->DestRect.Width / scaled_srcrect.Width;
2826 transform.matrix[1] = 0.0;
2827 transform.matrix[2] = 0.0;
2828 transform.matrix[3] = record->DestRect.Height / scaled_srcrect.Height;
2829 transform.matrix[4] = record->DestRect.X - scaled_srcrect.X;
2830 transform.matrix[5] = record->DestRect.Y - scaled_srcrect.Y;
2831
2833
2834 return METAFILE_PlaybackUpdateWorldTransform(real_metafile);
2835 }
2838 {
2840 container* cont;
2841
2842 cont = heap_alloc_zero(sizeof(*cont));
2843 if (!cont)
2844 return OutOfMemory;
2845
2846 stat = GdipCloneRegion(metafile->clip, &cont->clip);
2847 if (stat != Ok)
2848 {
2849 heap_free(cont);
2850 return stat;
2851 }
2852
2854 stat = GdipBeginContainer2(metafile->playback_graphics, &cont->state);
2855 else
2856 stat = GdipSaveGraphics(metafile->playback_graphics, &cont->state);
2857
2858 if (stat != Ok)
2859 {
2860 GdipDeleteRegion(cont->clip);
2861 heap_free(cont);
2862 return stat;
2863 }
2864
2865 cont->id = record->StackIndex;
2867 cont->type = BEGIN_CONTAINER;
2868 else
2869 cont->type = SAVE_GRAPHICS;
2870 cont->world_transform = *metafile->world_transform;
2871 cont->page_unit = metafile->page_unit;
2872 cont->page_scale = metafile->page_scale;
2873 list_add_head(&real_metafile->containers, &cont->entry);
2874
2875 break;
2876 }
2879 {
2881 container* cont;
2882 enum container_type type;
2883 BOOL found=FALSE;
2884
2885 if (recordType == EmfPlusRecordTypeEndContainer)
2887 else
2889
2890 LIST_FOR_EACH_ENTRY(cont, &real_metafile->containers, container, entry)
2891 {
2892 if (cont->id == record->StackIndex && cont->type == type)
2893 {
2894 found = TRUE;
2895 break;
2896 }
2897 }
2898
2899 if (found)
2900 {
2901 container* cont2;
2902
2903 /* pop any newer items on the stack */
2904 while ((cont2 = LIST_ENTRY(list_head(&real_metafile->containers), container, entry)) != cont)
2905 {
2906 list_remove(&cont2->entry);
2907 GdipDeleteRegion(cont2->clip);
2908 heap_free(cont2);
2909 }
2910
2911 if (type == BEGIN_CONTAINER)
2912 GdipEndContainer(real_metafile->playback_graphics, cont->state);
2913 else
2914 GdipRestoreGraphics(real_metafile->playback_graphics, cont->state);
2915
2916 *real_metafile->world_transform = cont->world_transform;
2917 real_metafile->page_unit = cont->page_unit;
2918 real_metafile->page_scale = cont->page_scale;
2919 GdipCombineRegionRegion(real_metafile->clip, cont->clip, CombineModeReplace);
2920
2921 list_remove(&cont->entry);
2922 GdipDeleteRegion(cont->clip);
2923 heap_free(cont);
2924 }
2925
2926 break;
2927 }
2929 {
2930 return GdipSetPixelOffsetMode(real_metafile->playback_graphics, flags & 0xff);
2931 }
2933 {
2934 return GdipSetCompositingQuality(real_metafile->playback_graphics, flags & 0xff);
2935 }
2937 {
2938 return GdipSetInterpolationMode(real_metafile->playback_graphics, flags & 0xff);
2939 }
2941 {
2942 return GdipSetTextRenderingHint(real_metafile->playback_graphics, flags & 0xff);
2943 }
2945 {
2946 return GdipSetSmoothingMode(real_metafile->playback_graphics, (flags >> 1) & 0xff);
2947 }
2949 {
2950 return GdipSetCompositingMode(real_metafile->playback_graphics, flags & 0xff);
2951 }
2953 {
2954 return METAFILE_PlaybackObject(real_metafile, flags, dataSize, data);
2955 }
2957 {
2959 BYTE image = flags & 0xff;
2960 GpPointF points[3];
2961
2962 if (image >= EmfPlusObjectTableSize || real_metafile->objtable[image].type != ObjectTypeImage)
2963 return InvalidParameter;
2964
2965 if (dataSize != FIELD_OFFSET(EmfPlusDrawImage, RectData) - sizeof(EmfPlusRecordHeader) +
2966 (flags & 0x4000 ? sizeof(EmfPlusRect) : sizeof(EmfPlusRectF)))
2967 return InvalidParameter;
2968
2970 real_metafile->objtable[draw->ImageAttributesID].type != ObjectTypeImageAttributes)
2971 return InvalidParameter;
2972
2973 if (flags & 0x4000) /* C */
2974 {
2975 points[0].X = draw->RectData.rect.X;
2976 points[0].Y = draw->RectData.rect.Y;
2977 points[1].X = points[0].X + draw->RectData.rect.Width;
2978 points[1].Y = points[0].Y;
2979 points[2].X = points[1].X;
2980 points[2].Y = points[1].Y + draw->RectData.rect.Height;
2981 }
2982 else
2983 {
2984 points[0].X = draw->RectData.rectF.X;
2985 points[0].Y = draw->RectData.rectF.Y;
2986 points[1].X = points[0].X + draw->RectData.rectF.Width;
2987 points[1].Y = points[0].Y;
2988 points[2].X = points[1].X;
2989 points[2].Y = points[1].Y + draw->RectData.rectF.Height;
2990 }
2991
2992 return GdipDrawImagePointsRect(real_metafile->playback_graphics, real_metafile->objtable[image].u.image,
2993 points, 3, draw->SrcRect.X, draw->SrcRect.Y, draw->SrcRect.Width, draw->SrcRect.Height, draw->SrcUnit,
2994 real_metafile->objtable[draw->ImageAttributesID].u.image_attributes, NULL, NULL);
2995 }
2997 {
2999 static const UINT fixed_part_size = FIELD_OFFSET(EmfPlusDrawImagePoints, PointData) -
3000 FIELD_OFFSET(EmfPlusDrawImagePoints, ImageAttributesID);
3001 BYTE image = flags & 0xff;
3002 GpPointF points[3];
3003 unsigned int i;
3004 UINT size;
3005
3006 if (image >= EmfPlusObjectTableSize || real_metafile->objtable[image].type != ObjectTypeImage)
3007 return InvalidParameter;
3008
3009 if (dataSize <= fixed_part_size)
3010 return InvalidParameter;
3011 dataSize -= fixed_part_size;
3012
3014 real_metafile->objtable[draw->ImageAttributesID].type != ObjectTypeImageAttributes)
3015 return InvalidParameter;
3016
3017 if (draw->count != 3)
3018 return InvalidParameter;
3019
3020 if ((flags >> 13) & 1) /* E */
3021 FIXME("image effects are not supported.\n");
3022
3023 if ((flags >> 11) & 1) /* P */
3024 size = sizeof(EmfPlusPointR7) * draw->count;
3025 else if ((flags >> 14) & 1) /* C */
3026 size = sizeof(EmfPlusPoint) * draw->count;
3027 else
3028 size = sizeof(EmfPlusPointF) * draw->count;
3029
3030 if (dataSize != size)
3031 return InvalidParameter;
3032
3033 if ((flags >> 11) & 1) /* P */
3034 {
3035 points[0].X = draw->PointData.pointsR[0].X;
3036 points[0].Y = draw->PointData.pointsR[0].Y;
3037 for (i = 1; i < 3; i++)
3038 {
3039 points[i].X = points[i-1].X + draw->PointData.pointsR[i].X;
3040 points[i].Y = points[i-1].Y + draw->PointData.pointsR[i].Y;
3041 }
3042 }
3043 else if ((flags >> 14) & 1) /* C */
3044 {
3045 for (i = 0; i < 3; i++)
3046 {
3047 points[i].X = draw->PointData.points[i].X;
3048 points[i].Y = draw->PointData.points[i].Y;
3049 }
3050 }
3051 else
3052 memcpy(points, draw->PointData.pointsF, sizeof(points));
3053
3054 return GdipDrawImagePointsRect(real_metafile->playback_graphics, real_metafile->objtable[image].u.image,
3055 points, 3, draw->SrcRect.X, draw->SrcRect.Y, draw->SrcRect.Width, draw->SrcRect.Height, draw->SrcUnit,
3056 real_metafile->objtable[draw->ImageAttributesID].u.image_attributes, NULL, NULL);
3057 }
3059 {
3061 GpSolidFill *solidfill = NULL;
3062 BYTE path = flags & 0xff;
3063 GpBrush *brush;
3064
3065 if (path >= EmfPlusObjectTableSize || real_metafile->objtable[path].type != ObjectTypePath)
3066 return InvalidParameter;
3067
3068 if (dataSize != sizeof(fill->data.BrushId))
3069 return InvalidParameter;
3070
3071 if (flags & 0x8000)
3072 {
3073 stat = GdipCreateSolidFill(fill->data.Color, (GpSolidFill **)&solidfill);
3074 if (stat != Ok)
3075 return stat;
3076 brush = (GpBrush *)solidfill;
3077 }
3078 else
3079 {
3080 if (fill->data.BrushId >= EmfPlusObjectTableSize ||
3081 real_metafile->objtable[fill->data.BrushId].type != ObjectTypeBrush)
3082 return InvalidParameter;
3083
3084 brush = real_metafile->objtable[fill->data.BrushId].u.brush;
3085 }
3086
3087 stat = GdipFillPath(real_metafile->playback_graphics, brush, real_metafile->objtable[path].u.path);
3088 GdipDeleteBrush((GpBrush *)solidfill);
3089 return stat;
3090 }
3092 {
3093 static const UINT fixed_part_size = FIELD_OFFSET(EmfPlusFillClosedCurve, PointData) -
3094 sizeof(EmfPlusRecordHeader);
3096 GpSolidFill *solidfill = NULL;
3098 GpBrush *brush;
3099 UINT size, i;
3100
3101 if (dataSize <= fixed_part_size)
3102 return InvalidParameter;
3103
3104 if (fill->Count == 0)
3105 return InvalidParameter;
3106
3107 if (flags & 0x800) /* P */
3108 size = (fixed_part_size + sizeof(EmfPlusPointR7) * fill->Count + 3) & ~3;
3109 else if (flags & 0x4000) /* C */
3110 size = fixed_part_size + sizeof(EmfPlusPoint) * fill->Count;
3111 else
3112 size = fixed_part_size + sizeof(EmfPlusPointF) * fill->Count;
3113
3114 if (dataSize != size)
3115 return InvalidParameter;
3116
3117 mode = flags & 0x200 ? FillModeWinding : FillModeAlternate; /* W */
3118
3119 if (flags & 0x8000) /* S */
3120 {
3121 stat = GdipCreateSolidFill(fill->BrushId, (GpSolidFill **)&solidfill);
3122 if (stat != Ok)
3123 return stat;
3124 brush = (GpBrush *)solidfill;
3125 }
3126 else
3127 {
3128 if (fill->BrushId >= EmfPlusObjectTableSize ||
3129 real_metafile->objtable[fill->BrushId].type != ObjectTypeBrush)
3130 return InvalidParameter;
3131
3132 brush = real_metafile->objtable[fill->BrushId].u.brush;
3133 }
3134
3135 if (flags & (0x800 | 0x4000))
3136 {
3137 GpPointF *points = GdipAlloc(fill->Count * sizeof(*points));
3138 if (points)
3139 {
3140 if (flags & 0x800) /* P */
3141 {
3142 for (i = 1; i < fill->Count; i++)
3143 {
3144 points[i].X = points[i - 1].X + fill->PointData.pointsR[i].X;
3145 points[i].Y = points[i - 1].Y + fill->PointData.pointsR[i].Y;
3146 }
3147 }
3148 else
3149 {
3150 for (i = 0; i < fill->Count; i++)
3151 {
3152 points[i].X = fill->PointData.points[i].X;
3153 points[i].Y = fill->PointData.points[i].Y;
3154 }
3155 }
3156
3157 stat = GdipFillClosedCurve2(real_metafile->playback_graphics, brush,
3158 points, fill->Count, fill->Tension, mode);
3160 }
3161 else
3162 stat = OutOfMemory;
3163 }
3164 else
3165 stat = GdipFillClosedCurve2(real_metafile->playback_graphics, brush,
3166 (const GpPointF *)fill->PointData.pointsF, fill->Count, fill->Tension, mode);
3167
3168 GdipDeleteBrush((GpBrush *)solidfill);
3169 return stat;
3170 }
3172 {
3174 GpSolidFill *solidfill = NULL;
3175 GpBrush *brush;
3176
3177 if (dataSize <= FIELD_OFFSET(EmfPlusFillEllipse, RectData) - sizeof(EmfPlusRecordHeader))
3178 return InvalidParameter;
3180
3181 if (dataSize != (flags & 0x4000 ? sizeof(EmfPlusRect) : sizeof(EmfPlusRectF)))
3182 return InvalidParameter;
3183
3184 if (flags & 0x8000)
3185 {
3186 stat = GdipCreateSolidFill(fill->BrushId, (GpSolidFill **)&solidfill);
3187 if (stat != Ok)
3188 return stat;
3189 brush = (GpBrush *)solidfill;
3190 }
3191 else
3192 {
3193 if (fill->BrushId >= EmfPlusObjectTableSize ||
3194 real_metafile->objtable[fill->BrushId].type != ObjectTypeBrush)
3195 return InvalidParameter;
3196
3197 brush = real_metafile->objtable[fill->BrushId].u.brush;
3198 }
3199
3200 if (flags & 0x4000)
3201 stat = GdipFillEllipseI(real_metafile->playback_graphics, brush, fill->RectData.rect.X,
3202 fill->RectData.rect.Y, fill->RectData.rect.Width, fill->RectData.rect.Height);
3203 else
3204 stat = GdipFillEllipse(real_metafile->playback_graphics, brush, fill->RectData.rectF.X,
3205 fill->RectData.rectF.Y, fill->RectData.rectF.Width, fill->RectData.rectF.Height);
3206
3207 GdipDeleteBrush((GpBrush *)solidfill);
3208 return stat;
3209 }
3211 {
3213 GpSolidFill *solidfill = NULL;
3214 GpBrush *brush;
3215
3216 if (dataSize <= FIELD_OFFSET(EmfPlusFillPie, RectData) - sizeof(EmfPlusRecordHeader))
3217 return InvalidParameter;
3219
3220 if (dataSize != (flags & 0x4000 ? sizeof(EmfPlusRect) : sizeof(EmfPlusRectF)))
3221 return InvalidParameter;
3222
3223 if (flags & 0x8000) /* S */
3224 {
3225 stat = GdipCreateSolidFill(fill->BrushId, (GpSolidFill **)&solidfill);
3226 if (stat != Ok)
3227 return stat;
3228 brush = (GpBrush *)solidfill;
3229 }
3230 else
3231 {
3232 if (fill->BrushId >= EmfPlusObjectTableSize ||
3233 real_metafile->objtable[fill->BrushId].type != ObjectTypeBrush)
3234 return InvalidParameter;
3235
3236 brush = real_metafile->objtable[fill->BrushId].u.brush;
3237 }
3238
3239 if (flags & 0x4000) /* C */
3240 stat = GdipFillPieI(real_metafile->playback_graphics, brush, fill->RectData.rect.X,
3241 fill->RectData.rect.Y, fill->RectData.rect.Width, fill->RectData.rect.Height,
3242 fill->StartAngle, fill->SweepAngle);
3243 else
3244 stat = GdipFillPie(real_metafile->playback_graphics, brush, fill->RectData.rectF.X,
3245 fill->RectData.rectF.Y, fill->RectData.rectF.Width, fill->RectData.rectF.Height,
3246 fill->StartAngle, fill->SweepAngle);
3247
3248 GdipDeleteBrush((GpBrush *)solidfill);
3249 return stat;
3250 }
3252 {
3254 BYTE path = flags & 0xff;
3255
3256 if (dataSize != sizeof(draw->PenId))
3257 return InvalidParameter;
3258
3260 return InvalidParameter;
3261
3262 if (real_metafile->objtable[path].type != ObjectTypePath ||
3263 real_metafile->objtable[draw->PenId].type != ObjectTypePen)
3264 return InvalidParameter;
3265
3266 return GdipDrawPath(real_metafile->playback_graphics, real_metafile->objtable[draw->PenId].u.pen,
3267 real_metafile->objtable[path].u.path);
3268 }
3270 {
3272 BYTE pen = flags & 0xff;
3273
3274 if (pen >= EmfPlusObjectTableSize || real_metafile->objtable[pen].type != ObjectTypePen)
3275 return InvalidParameter;
3276
3277 if (dataSize != FIELD_OFFSET(EmfPlusDrawArc, RectData) - sizeof(EmfPlusRecordHeader) +
3278 (flags & 0x4000 ? sizeof(EmfPlusRect) : sizeof(EmfPlusRectF)))
3279 return InvalidParameter;
3280
3281 if (flags & 0x4000) /* C */
3282 return GdipDrawArcI(real_metafile->playback_graphics, real_metafile->objtable[pen].u.pen,
3283 draw->RectData.rect.X, draw->RectData.rect.Y, draw->RectData.rect.Width,
3284 draw->RectData.rect.Height, draw->StartAngle, draw->SweepAngle);
3285 else
3286 return GdipDrawArc(real_metafile->playback_graphics, real_metafile->objtable[pen].u.pen,
3287 draw->RectData.rectF.X, draw->RectData.rectF.Y, draw->RectData.rectF.Width,
3288 draw->RectData.rectF.Height, draw->StartAngle, draw->SweepAngle);
3289 }
3291 {
3293 BYTE pen = flags & 0xff;
3294
3295 if (pen >= EmfPlusObjectTableSize || real_metafile->objtable[pen].type != ObjectTypePen)
3296 return InvalidParameter;
3297
3298 if (dataSize != (flags & 0x4000 ? sizeof(EmfPlusRect) : sizeof(EmfPlusRectF)))
3299 return InvalidParameter;
3300
3301 if (flags & 0x4000) /* C */
3302 return GdipDrawEllipseI(real_metafile->playback_graphics, real_metafile->objtable[pen].u.pen,
3303 draw->RectData.rect.X, draw->RectData.rect.Y, draw->RectData.rect.Width,
3304 draw->RectData.rect.Height);
3305 else
3306 return GdipDrawEllipse(real_metafile->playback_graphics, real_metafile->objtable[pen].u.pen,
3307 draw->RectData.rectF.X, draw->RectData.rectF.Y, draw->RectData.rectF.Width,
3308 draw->RectData.rectF.Height);
3309 }
3311 {
3313 BYTE pen = flags & 0xff;
3314
3315 if (pen >= EmfPlusObjectTableSize || real_metafile->objtable[pen].type != ObjectTypePen)
3316 return InvalidParameter;
3317
3318 if (dataSize != FIELD_OFFSET(EmfPlusDrawPie, RectData) - sizeof(EmfPlusRecordHeader) +
3319 (flags & 0x4000 ? sizeof(EmfPlusRect) : sizeof(EmfPlusRectF)))
3320 return InvalidParameter;
3321
3322 if (flags & 0x4000) /* C */
3323 return GdipDrawPieI(real_metafile->playback_graphics, real_metafile->objtable[pen].u.pen,
3324 draw->RectData.rect.X, draw->RectData.rect.Y, draw->RectData.rect.Width,
3325 draw->RectData.rect.Height, draw->StartAngle, draw->SweepAngle);
3326 else
3327 return GdipDrawPie(real_metafile->playback_graphics, real_metafile->objtable[pen].u.pen,
3328 draw->RectData.rectF.X, draw->RectData.rectF.Y, draw->RectData.rectF.Width,
3329 draw->RectData.rectF.Height, draw->StartAngle, draw->SweepAngle);
3330 }
3332 {
3334 BYTE pen = flags & 0xff;
3335 GpRectF *rects = NULL;
3336
3337 if (pen >= EmfPlusObjectTableSize || real_metafile->objtable[pen].type != ObjectTypePen)
3338 return InvalidParameter;
3339
3340 if (dataSize <= FIELD_OFFSET(EmfPlusDrawRects, RectData) - sizeof(EmfPlusRecordHeader))
3341 return InvalidParameter;
3343
3344 if (dataSize != draw->Count * (flags & 0x4000 ? sizeof(EmfPlusRect) : sizeof(EmfPlusRectF)))
3345 return InvalidParameter;
3346
3347 if (flags & 0x4000)
3348 {
3349 DWORD i;
3350
3351 rects = GdipAlloc(draw->Count * sizeof(*rects));
3352 if (!rects)
3353 return OutOfMemory;
3354
3355 for (i = 0; i < draw->Count; i++)
3356 {
3357 rects[i].X = draw->RectData.rect[i].X;
3358 rects[i].Y = draw->RectData.rect[i].Y;
3359 rects[i].Width = draw->RectData.rect[i].Width;
3360 rects[i].Height = draw->RectData.rect[i].Height;
3361 }
3362 }
3363
3364 stat = GdipDrawRectangles(real_metafile->playback_graphics, real_metafile->objtable[pen].u.pen,
3365 rects ? rects : (GpRectF *)draw->RectData.rectF, draw->Count);
3366 GdipFree(rects);
3367 return stat;
3368 }
3369 default:
3370 FIXME("Not implemented for record type %x\n", recordType);
3371 return NotImplemented;
3372 }
3373 }
3374
3375 return Ok;
3376}
3377
3379{
3383};
3384
3385static int CALLBACK enum_metafile_proc(HDC hDC, HANDLETABLE *lpHTable, const ENHMETARECORD *lpEMFR,
3386 int nObj, LPARAM lpData)
3387{
3388 BOOL ret;
3389 struct enum_metafile_data *data = (struct enum_metafile_data*)lpData;
3390 const BYTE* pStr;
3391
3392 data->metafile->handle_table = lpHTable;
3393 data->metafile->handle_count = nObj;
3394
3395 /* First check for an EMF+ record. */
3396 if (lpEMFR->iType == EMR_GDICOMMENT)
3397 {
3398 const EMRGDICOMMENT *comment = (const EMRGDICOMMENT*)lpEMFR;
3399
3400 if (comment->cbData >= 4 && memcmp(comment->Data, "EMF+", 4) == 0)
3401 {
3402 int offset = 4;
3403
3404 while (offset + sizeof(EmfPlusRecordHeader) <= comment->cbData)
3405 {
3407
3408 if (record->DataSize)
3409 pStr = (const BYTE*)(record+1);
3410 else
3411 pStr = NULL;
3412
3413 ret = data->callback(record->Type, record->Flags, record->DataSize,
3414 pStr, data->callback_data);
3415
3416 if (!ret)
3417 return 0;
3418
3419 offset += record->Size;
3420 }
3421
3422 return 1;
3423 }
3424 }
3425
3426 if (lpEMFR->nSize != 8)
3427 pStr = (const BYTE*)lpEMFR->dParm;
3428 else
3429 pStr = NULL;
3430
3431 return data->callback(lpEMFR->iType, 0, lpEMFR->nSize-8,
3432 pStr, data->callback_data);
3433}
3434
3438 VOID *callbackData, GDIPCONST GpImageAttributes *imageAttributes)
3439{
3440 struct enum_metafile_data data;
3441 GpStatus stat;
3442 GpMetafile *real_metafile = (GpMetafile*)metafile; /* whoever made this const was joking */
3444 GpPath *dst_path;
3445
3446 TRACE("(%p,%p,%p,%i,%p,%i,%p,%p,%p)\n", graphics, metafile,
3447 destPoints, count, srcRect, srcUnit, callback, callbackData,
3448 imageAttributes);
3449
3450 if (!graphics || !metafile || !destPoints || count != 3 || !srcRect)
3451 return InvalidParameter;
3452
3453 if (!metafile->hemf)
3454 return InvalidParameter;
3455
3456 if (metafile->playback_graphics)
3457 return ObjectBusy;
3458
3459 TRACE("%s %i -> %s %s %s\n", debugstr_rectf(srcRect), srcUnit,
3460 debugstr_pointf(&destPoints[0]), debugstr_pointf(&destPoints[1]),
3461 debugstr_pointf(&destPoints[2]));
3462
3463 data.callback = callback;
3464 data.callback_data = callbackData;
3465 data.metafile = real_metafile;
3466
3467 real_metafile->playback_graphics = graphics;
3468 real_metafile->playback_dc = NULL;
3469 real_metafile->src_rect = *srcRect;
3470
3471 memcpy(real_metafile->playback_points, destPoints, sizeof(PointF) * 3);
3473
3474 if (stat == Ok)
3475 stat = GdipBeginContainer2(graphics, &state);
3476
3477 if (stat == Ok)
3478 {
3479 stat = GdipSetPageScale(graphics, 1.0);
3480
3481 if (stat == Ok)
3482 stat = GdipSetPageUnit(graphics, UnitPixel);
3483
3484 if (stat == Ok)
3485 stat = GdipResetWorldTransform(graphics);
3486
3487 if (stat == Ok)
3488 stat = GdipCreateRegion(&real_metafile->base_clip);
3489
3490 if (stat == Ok)
3491 stat = GdipGetClip(graphics, real_metafile->base_clip);
3492
3493 if (stat == Ok)
3494 stat = GdipCreateRegion(&real_metafile->clip);
3495
3496 if (stat == Ok)
3498
3499 if (stat == Ok)
3500 {
3501 GpPointF clip_points[4];
3502
3503 clip_points[0] = real_metafile->playback_points[0];
3504 clip_points[1] = real_metafile->playback_points[1];
3505 clip_points[2].X = real_metafile->playback_points[1].X + real_metafile->playback_points[2].X
3506 - real_metafile->playback_points[0].X;
3507 clip_points[2].Y = real_metafile->playback_points[1].Y + real_metafile->playback_points[2].Y
3508 - real_metafile->playback_points[0].Y;
3509 clip_points[3] = real_metafile->playback_points[2];
3510
3511 stat = GdipAddPathPolygon(dst_path, clip_points, 4);
3512
3513 if (stat == Ok)
3514 stat = GdipCombineRegionPath(real_metafile->base_clip, dst_path, CombineModeIntersect);
3515
3516 GdipDeletePath(dst_path);
3517 }
3518
3519 if (stat == Ok)
3520 stat = GdipCreateMatrix(&real_metafile->world_transform);
3521
3522 if (stat == Ok)
3523 {
3524 real_metafile->page_unit = UnitDisplay;
3525 real_metafile->page_scale = 1.0;
3527 }
3528
3529 if (stat == Ok)
3530 {
3531 stat = METAFILE_PlaybackUpdateClip(real_metafile);
3532 }
3533
3534 if (stat == Ok && (metafile->metafile_type == MetafileTypeEmf ||
3535 metafile->metafile_type == MetafileTypeWmfPlaceable ||
3536 metafile->metafile_type == MetafileTypeWmf))
3537 stat = METAFILE_PlaybackGetDC(real_metafile);
3538
3539 if (stat == Ok)
3541
3542 METAFILE_PlaybackReleaseDC(real_metafile);
3543
3544 GdipDeleteMatrix(real_metafile->world_transform);
3545 real_metafile->world_transform = NULL;
3546
3547 GdipDeleteRegion(real_metafile->base_clip);
3548 real_metafile->base_clip = NULL;
3549
3550 GdipDeleteRegion(real_metafile->clip);
3551 real_metafile->clip = NULL;
3552
3553 while (list_head(&real_metafile->containers))
3554 {
3555 container* cont = LIST_ENTRY(list_head(&real_metafile->containers), container, entry);
3556 list_remove(&cont->entry);
3557 GdipDeleteRegion(cont->clip);
3558 heap_free(cont);
3559 }
3560
3561 GdipEndContainer(graphics, state);
3562 }
3563
3564 real_metafile->playback_graphics = NULL;
3565
3566 return stat;
3567}
3568
3572{
3573 GpPointF points[3];
3574
3575 if (!graphics || !metafile || !dest) return InvalidParameter;
3576
3577 points[0].X = points[2].X = dest->X;
3578 points[0].Y = points[1].Y = dest->Y;
3579 points[1].X = dest->X + dest->Width;
3580 points[2].Y = dest->Y + dest->Height;
3581
3583 &metafile->bounds, metafile->unit, callback, cb_data, attrs);
3584}
3585
3589{
3590 GpRectF destf;
3591
3592 if (!graphics || !metafile || !dest) return InvalidParameter;
3593
3594 destf.X = dest->X;
3595 destf.Y = dest->Y;
3596 destf.Width = dest->Width;
3597 destf.Height = dest->Height;
3598
3599 return GdipEnumerateMetafileDestRect(graphics, metafile, &destf, callback, cb_data, attrs);
3600}
3601
3605{
3606 GpRectF destf;
3607
3608 if (!graphics || !metafile || !dest) return InvalidParameter;
3609
3610 destf.X = dest->X;
3611 destf.Y = dest->Y;
3612 destf.Width = units_to_pixels(metafile->bounds.Width, metafile->unit, metafile->image.xres);
3613 destf.Height = units_to_pixels(metafile->bounds.Height, metafile->unit, metafile->image.yres);
3614
3615 return GdipEnumerateMetafileDestRect(graphics, metafile, &destf, callback, cb_data, attrs);
3616}
3617
3621{
3622 GpPointF ptf;
3623
3624 if (!graphics || !metafile || !dest) return InvalidParameter;
3625
3626 ptf.X = dest->X;
3627 ptf.Y = dest->Y;
3628
3629 return GdipEnumerateMetafileDestPoint(graphics, metafile, &ptf, callback, cb_data, attrs);
3630}
3631
3634{
3636
3637 TRACE("(%p, %p)\n", metafile, header);
3638
3639 if(!metafile || !header)
3640 return InvalidParameter;
3641
3642 if (metafile->hemf)
3643 {
3645 if (status != Ok) return status;
3646 }
3647 else
3648 {
3649 memset(header, 0, sizeof(*header));
3650 header->Version = VERSION_MAGIC2;
3651 }
3652
3653 header->Type = metafile->metafile_type;
3654 header->DpiX = metafile->image.xres;
3655 header->DpiY = metafile->image.yres;
3656 header->Width = gdip_round(metafile->bounds.Width);
3657 header->Height = gdip_round(metafile->bounds.Height);
3658
3659 return Ok;
3660}
3661
3663 int nObj, LPARAM lpData)
3664{
3665 EmfPlusHeader *dst_header = (EmfPlusHeader*)lpData;
3666
3667 if (lpEMFR->iType == EMR_GDICOMMENT)
3668 {
3669 const EMRGDICOMMENT *comment = (const EMRGDICOMMENT*)lpEMFR;
3670
3671 if (comment->cbData >= 4 && memcmp(comment->Data, "EMF+", 4) == 0)
3672 {
3673 const EmfPlusRecordHeader *header = (const EmfPlusRecordHeader*)&comment->Data[4];
3674
3675 if (4 + sizeof(EmfPlusHeader) <= comment->cbData &&
3677 {
3678 memcpy(dst_header, header, sizeof(*dst_header));
3679 }
3680 }
3681 }
3682 else if (lpEMFR->iType == EMR_HEADER)
3683 return TRUE;
3684
3685 return FALSE;
3686}
3687
3690{
3691 ENHMETAHEADER3 emfheader;
3692 EmfPlusHeader emfplusheader;
3693 MetafileType metafile_type;
3694
3695 TRACE("(%p,%p)\n", hemf, header);
3696
3697 if(!hemf || !header)
3698 return InvalidParameter;
3699
3700 if (GetEnhMetaFileHeader(hemf, sizeof(emfheader), (ENHMETAHEADER*)&emfheader) == 0)
3701 return GenericError;
3702
3703 emfplusheader.Header.Type = 0;
3704
3705 EnumEnhMetaFile(NULL, hemf, get_emfplus_header_proc, &emfplusheader, NULL);
3706
3707 if (emfplusheader.Header.Type == EmfPlusRecordTypeHeader)
3708 {
3709 if ((emfplusheader.Header.Flags & 1) == 1)
3710 metafile_type = MetafileTypeEmfPlusDual;
3711 else
3712 metafile_type = MetafileTypeEmfPlusOnly;
3713 }
3714 else
3715 metafile_type = MetafileTypeEmf;
3716
3717 header->Type = metafile_type;
3718 header->Size = emfheader.nBytes;
3719 header->DpiX = (REAL)emfheader.szlDevice.cx * 25.4 / emfheader.szlMillimeters.cx;
3720 header->DpiY = (REAL)emfheader.szlDevice.cy * 25.4 / emfheader.szlMillimeters.cy;
3721 header->X = gdip_round((REAL)emfheader.rclFrame.left / 2540.0 * header->DpiX);
3722 header->Y = gdip_round((REAL)emfheader.rclFrame.top / 2540.0 * header->DpiY);
3723 header->Width = gdip_round((REAL)(emfheader.rclFrame.right - emfheader.rclFrame.left) / 2540.0 * header->DpiX);
3724 header->Height = gdip_round((REAL)(emfheader.rclFrame.bottom - emfheader.rclFrame.top) / 2540.0 * header->DpiY);
3725 header->u.EmfHeader = emfheader;
3726
3727 if (metafile_type == MetafileTypeEmfPlusDual || metafile_type == MetafileTypeEmfPlusOnly)
3728 {
3729 header->Version = emfplusheader.Version;
3730 header->EmfPlusFlags = emfplusheader.EmfPlusFlags;
3731 header->EmfPlusHeaderSize = emfplusheader.Header.Size;
3732 header->LogicalDpiX = emfplusheader.LogicalDpiX;
3733 header->LogicalDpiY = emfplusheader.LogicalDpiY;
3734 }
3735 else
3736 {
3737 header->Version = emfheader.nVersion;
3738 header->EmfPlusFlags = 0;
3739 header->EmfPlusHeaderSize = 0;
3740 header->LogicalDpiX = 0;
3741 header->LogicalDpiY = 0;
3742 }
3743
3744 return Ok;
3745}
3746
3749{
3752
3753 TRACE("(%p,%p,%p)\n", hwmf, placeable, header);
3754
3755 status = GdipCreateMetafileFromWmf(hwmf, FALSE, placeable, &metafile);
3756 if (status == Ok)
3757 {
3759 GdipDisposeImage(&metafile->image);
3760 }
3761 return status;
3762}
3763
3766{
3769
3770 TRACE("(%s,%p)\n", debugstr_w(filename), header);
3771
3772 if (!filename || !header)
3773 return InvalidParameter;
3774
3776 if (status == Ok)
3777 {
3779 GdipDisposeImage(&metafile->image);
3780 }
3781 return status;
3782}
3783
3786{
3789
3790 TRACE("(%p,%p)\n", stream, header);
3791
3792 if (!stream || !header)
3793 return InvalidParameter;
3794
3796 if (status == Ok)
3797 {
3799 GdipDisposeImage(&metafile->image);
3800 }
3801 return status;
3802}
3803
3806{
3807 GpStatus stat;
3809
3810 TRACE("(%p,%i,%p)\n", hemf, delete, metafile);
3811
3812 if(!hemf || !metafile)
3813 return InvalidParameter;
3814
3816 if (stat != Ok)
3817 return stat;
3818
3819 *metafile = heap_alloc_zero(sizeof(GpMetafile));
3820 if (!*metafile)
3821 return OutOfMemory;
3822
3823 (*metafile)->image.type = ImageTypeMetafile;
3824 (*metafile)->image.format = ImageFormatEMF;
3825 (*metafile)->image.frame_count = 1;
3826 (*metafile)->image.xres = header.DpiX;
3827 (*metafile)->image.yres = header.DpiY;
3828 (*metafile)->bounds.X = (REAL)header.u.EmfHeader.rclFrame.left / 2540.0 * header.DpiX;
3829 (*metafile)->bounds.Y = (REAL)header.u.EmfHeader.rclFrame.top / 2540.0 * header.DpiY;
3830 (*metafile)->bounds.Width = (REAL)(header.u.EmfHeader.rclFrame.right - header.u.EmfHeader.rclFrame.left)
3831 / 2540.0 * header.DpiX;
3832 (*metafile)->bounds.Height = (REAL)(header.u.EmfHeader.rclFrame.bottom - header.u.EmfHeader.rclFrame.top)
3833 / 2540.0 * header.DpiY;
3834 (*metafile)->unit = UnitPixel;
3835 (*metafile)->metafile_type = header.Type;
3836 (*metafile)->hemf = hemf;
3837 (*metafile)->preserve_hemf = !delete;
3838 list_init(&(*metafile)->containers);
3839
3840 TRACE("<-- %p\n", *metafile);
3841
3842 return Ok;
3843}
3844
3847{
3848 UINT read;
3849 BYTE *copy;
3850 HENHMETAFILE hemf;
3851 GpStatus retval = Ok;
3852
3853 TRACE("(%p, %d, %p, %p)\n", hwmf, delete, placeable, metafile);
3854
3855 if(!hwmf || !metafile)
3856 return InvalidParameter;
3857
3858 *metafile = NULL;
3859 read = GetMetaFileBitsEx(hwmf, 0, NULL);
3860 if(!read)
3861 return GenericError;
3862 copy = heap_alloc_zero(read);
3863 GetMetaFileBitsEx(hwmf, read, copy);
3864
3866 heap_free(copy);
3867
3868 /* FIXME: We should store and use hwmf instead of converting to hemf */
3869 retval = GdipCreateMetafileFromEmf(hemf, TRUE, metafile);
3870
3871 if (retval == Ok)
3872 {
3873 if (placeable)
3874 {
3875 (*metafile)->image.xres = (REAL)placeable->Inch;
3876 (*metafile)->image.yres = (REAL)placeable->Inch;
3877 (*metafile)->bounds.X = ((REAL)placeable->BoundingBox.Left) / ((REAL)placeable->Inch);
3878 (*metafile)->bounds.Y = ((REAL)placeable->BoundingBox.Top) / ((REAL)placeable->Inch);
3879 (*metafile)->bounds.Width = (REAL)(placeable->BoundingBox.Right -
3880 placeable->BoundingBox.Left);
3881 (*metafile)->bounds.Height = (REAL)(placeable->BoundingBox.Bottom -
3882 placeable->BoundingBox.Top);
3883 (*metafile)->metafile_type = MetafileTypeWmfPlaceable;
3884 }
3885 else
3886 (*metafile)->metafile_type = MetafileTypeWmf;
3887 (*metafile)->image.format = ImageFormatWMF;
3888
3889 if (delete) DeleteMetaFile(hwmf);
3890 }
3891 else
3892 DeleteEnhMetaFile(hemf);
3893 return retval;
3894}
3895
3898{
3899 HMETAFILE hmf;
3900 HENHMETAFILE emf;
3901
3902 TRACE("(%s, %p, %p)\n", debugstr_w(file), placeable, metafile);
3903
3904 hmf = GetMetaFileW(file);
3905 if(hmf)
3906 return GdipCreateMetafileFromWmf(hmf, TRUE, placeable, metafile);
3907
3909 if(emf)
3911
3912 return GenericError;
3913}
3914
3917{
3919 IStream *stream;
3920
3921 TRACE("(%p, %p)\n", file, metafile);
3922
3923 if (!file || !metafile) return InvalidParameter;
3924
3925 *metafile = NULL;
3926
3928 if (status == Ok)
3929 {
3931 IStream_Release(stream);
3932 }
3933 return status;
3934}
3935
3938{
3939 GpStatus stat;
3940
3941 TRACE("%p %p\n", stream, metafile);
3942
3944 if (stat != Ok) return stat;
3945
3946 if ((*metafile)->image.type != ImageTypeMetafile)
3947 {
3948 GdipDisposeImage(&(*metafile)->image);
3949 *metafile = NULL;
3950 return GenericError;
3951 }
3952
3953 return Ok;
3954}
3955
3957 UINT limitDpi)
3958{
3959 TRACE("(%p,%u)\n", metafile, limitDpi);
3960
3961 return Ok;
3962}
3963
3965 GpMetafile* metafile, BOOL* succ, EmfType emfType,
3966 const WCHAR* description, GpMetafile** out_metafile)
3967{
3968 static int calls;
3969
3970 TRACE("(%p,%p,%p,%u,%s,%p)\n", ref, metafile, succ, emfType,
3971 debugstr_w(description), out_metafile);
3972
3973 if(!ref || !metafile || !out_metafile || emfType < EmfTypeEmfOnly || emfType > EmfTypeEmfPlusDual)
3974 return InvalidParameter;
3975
3976 if(succ)
3977 *succ = FALSE;
3978 *out_metafile = NULL;
3979
3980 if(!(calls++))
3981 FIXME("not implemented\n");
3982
3983 return NotImplemented;
3984}
3985
3986GpStatus WINGDIPAPI GdipEmfToWmfBits(HENHMETAFILE hemf, UINT cbData16,
3987 LPBYTE pData16, INT iMapMode, INT eFlags)
3988{
3989 FIXME("(%p, %d, %p, %d, %d): stub\n", hemf, cbData16, pData16, iMapMode, eFlags);
3990 return NotImplemented;
3991}
3992
3994 HDC hdc, EmfType type, GDIPCONST GpRectF *pFrameRect,
3997{
3998 FIXME("%s %p %d %p %d %s %p stub!\n", debugstr_w(fileName), hdc, type, pFrameRect,
3999 frameUnit, debugstr_w(desc), metafile);
4000
4001 return NotImplemented;
4002}
4003
4005 GDIPCONST GpRect *pFrameRect, MetafileFrameUnit frameUnit,
4007{
4008 FIXME("%s %p %d %p %d %s %p stub!\n", debugstr_w(fileName), hdc, type, pFrameRect,
4009 frameUnit, debugstr_w(desc), metafile);
4010
4011 return NotImplemented;
4012}
4013
4014/*****************************************************************************
4015 * GdipConvertToEmfPlusToFile [GDIPLUS.@]
4016 */
4017
4019 GpMetafile* metafile, BOOL* conversionSuccess,
4020 const WCHAR* filename, EmfType emfType,
4021 const WCHAR* description, GpMetafile** out_metafile)
4022{
4023 FIXME("stub: %p, %p, %p, %p, %u, %p, %p\n", refGraphics, metafile, conversionSuccess, filename, emfType, description, out_metafile);
4024 return NotImplemented;
4025}
4026
4028{
4030 STATSTG statstg;
4031 GpStatus stat;
4032 HRESULT hr;
4033
4034 *size = 0;
4035
4037 if (FAILED(hr)) return hresult_to_status(hr);
4038
4040 if (stat != Ok)
4041 {
4042 IStream_Release(*stream);
4043 return stat;
4044 }
4045
4046 hr = IStream_Stat(*stream, &statstg, 1);
4047 if (FAILED(hr))
4048 {
4049 IStream_Release(*stream);
4050 return hresult_to_status(hr);
4051 }
4052 *size = statstg.cbSize.u.LowPart;
4053
4054 zero.QuadPart = 0;
4055 hr = IStream_Seek(*stream, zero, STREAM_SEEK_SET, NULL);
4056 if (FAILED(hr))
4057 {
4058 IStream_Release(*stream);
4059 return hresult_to_status(hr);
4060 }
4061
4062 return Ok;
4063}
4064
4066{
4067 HRESULT hr;
4068
4069 record->Width = 0;
4070 record->Height = 0;
4071 record->Stride = 0;
4072 record->PixelFormat = 0;
4074
4075 hr = IStream_Read(stream, record->BitmapData, size, NULL);
4076 if (FAILED(hr)) return hresult_to_status(hr);
4077 return Ok;
4078}
4079
4081{
4082 EmfPlusObject *object_record;
4083 GpStatus stat;
4084 DWORD size;
4085
4086 *id = -1;
4087
4088 if (metafile->metafile_type != MetafileTypeEmfPlusOnly && metafile->metafile_type != MetafileTypeEmfPlusDual)
4089 return Ok;
4090
4091 if (image->type == ImageTypeBitmap)
4092 {
4093 IStream *stream;
4094 DWORD aligned_size;
4095
4097 if (stat != Ok) return stat;
4098 aligned_size = (size + 3) & ~3;
4099
4101 FIELD_OFFSET(EmfPlusObject, ObjectData.image.ImageData.bitmap.BitmapData[aligned_size]),
4102 (void**)&object_record);
4103 if (stat != Ok)
4104 {
4105 IStream_Release(stream);
4106 return stat;
4107 }
4108 memset(object_record->ObjectData.image.ImageData.bitmap.BitmapData + size, 0, aligned_size - size);
4109
4111 object_record->Header.Type = EmfPlusRecordTypeObject;
4112 object_record->Header.Flags = *id | ObjectTypeImage << 8;
4113 object_record->ObjectData.image.Version = VERSION_MAGIC2;
4114 object_record->ObjectData.image.Type = ImageDataTypeBitmap;
4115
4116 stat = METAFILE_FillEmfPlusBitmap(&object_record->ObjectData.image.ImageData.bitmap, stream, size);
4117 IStream_Release(stream);
4118 if (stat != Ok) METAFILE_RemoveLastRecord(metafile, &object_record->Header);
4119 return stat;
4120 }
4121 else if (image->type == ImageTypeMetafile)
4122 {
4123 HENHMETAFILE hemf = ((GpMetafile*)image)->hemf;
4124 EmfPlusMetafile *metafile_record;
4125
4126 if (!hemf) return InvalidParameter;
4127
4128 size = GetEnhMetaFileBits(hemf, 0, NULL);
4129 if (!size) return GenericError;
4130
4133 (void**)&object_record);
4134 if (stat != Ok) return stat;
4135
4137 object_record->Header.Type = EmfPlusRecordTypeObject;
4138 object_record->Header.Flags = *id | ObjectTypeImage << 8;
4139 object_record->ObjectData.image.Version = VERSION_MAGIC2;
4140 object_record->ObjectData.image.Type = ImageDataTypeMetafile;
4141 metafile_record = &object_record->ObjectData.image.ImageData.metafile;
4142 metafile_record->Type = ((GpMetafile*)image)->metafile_type;
4143 metafile_record->MetafileDataSize = size;
4144 if (GetEnhMetaFileBits(hemf, size, metafile_record->MetafileData) != size)
4145 {
4146 METAFILE_RemoveLastRecord(metafile, &object_record->Header);
4147 return GenericError;
4148 }
4149 return Ok;
4150 }
4151 else
4152 {
4153 FIXME("not supported image type (%d)\n", image->type);
4154 return NotImplemented;
4155 }
4156}
4157
4159{
4160 EmfPlusObject *object_record;
4161 EmfPlusImageAttributes *attrs_record;
4162 GpStatus stat;
4163
4164 *id = -1;
4165
4166 if (metafile->metafile_type != MetafileTypeEmfPlusOnly && metafile->metafile_type != MetafileTypeEmfPlusDual)
4167 return Ok;
4168
4169 if (!attrs)
4170 return Ok;
4171
4174 (void**)&object_record);
4175 if (stat != Ok) return stat;
4176
4178 object_record->Header.Type = EmfPlusRecordTypeObject;
4179 object_record->Header.Flags = *id | (ObjectTypeImageAttributes << 8);
4180 attrs_record = &object_record->ObjectData.image_attributes;
4181 attrs_record->Version = VERSION_MAGIC2;
4182 attrs_record->Reserved1 = 0;
4183 attrs_record->WrapMode = attrs->wrap;
4184 attrs_record->ClampColor = attrs->outside_color;
4185 attrs_record->ObjectClamp = attrs->clamp;
4186 attrs_record->Reserved2 = 0;
4187 return Ok;
4188}
4189
4191 GDIPCONST GpPointF *points, INT count, REAL srcx, REAL srcy, REAL srcwidth,
4192 REAL srcheight, GpUnit srcUnit, GDIPCONST GpImageAttributes* imageAttributes,
4193 DrawImageAbort callback, VOID *callbackData)
4194{
4195 EmfPlusDrawImagePoints *draw_image_record;
4196 DWORD image_id, attributes_id;
4197 GpStatus stat;
4198
4199 if (count != 3) return InvalidParameter;
4200
4201 if (metafile->metafile_type == MetafileTypeEmf)
4202 {
4203 FIXME("MetafileTypeEmf metafiles not supported\n");
4204 return NotImplemented;
4205 }
4206 else
4207 FIXME("semi-stub\n");
4208
4209 if (!imageAttributes)
4210 {
4212 }
4213 else if (image->type == ImageTypeBitmap)
4214 {
4215 INT width = ((GpBitmap*)image)->width;
4216 INT height = ((GpBitmap*)image)->height;
4217 GpGraphics *graphics;
4219
4222 if (stat != Ok) return stat;
4223
4225 if (stat != Ok)
4226 {
4228 return stat;
4229 }
4230
4231 stat = GdipDrawImageRectRectI(graphics, image, 0, 0, width, height,
4232 0, 0, width, height, UnitPixel, imageAttributes, NULL, NULL);
4233 GdipDeleteGraphics(graphics);
4234 if (stat != Ok)
4235 {
4237 return stat;
4238 }
4239
4242 }
4243 else
4244 {
4245 FIXME("imageAttributes not supported (image type %d)\n", image->type);
4246 return NotImplemented;
4247 }
4248 if (stat != Ok) return stat;
4249
4250 stat = METAFILE_AddImageAttributesObject(metafile, imageAttributes, &attributes_id);
4251 if (stat != Ok) return stat;
4252
4253 stat = METAFILE_AllocateRecord(metafile, sizeof(EmfPlusDrawImagePoints), (void**)&draw_image_record);
4254 if (stat != Ok) return stat;
4255 draw_image_record->Header.Type = EmfPlusRecordTypeDrawImagePoints;
4256 draw_image_record->Header.Flags = image_id;
4257 draw_image_record->ImageAttributesID = attributes_id;
4258 draw_image_record->SrcUnit = UnitPixel;
4259 draw_image_record->SrcRect.X = units_to_pixels(srcx, srcUnit, metafile->image.xres);
4260 draw_image_record->SrcRect.Y = units_to_pixels(srcy, srcUnit, metafile->image.yres);
4261 draw_image_record->SrcRect.Width = units_to_pixels(srcwidth, srcUnit, metafile->image.xres);
4262 draw_image_record->SrcRect.Height = units_to_pixels(srcheight, srcUnit, metafile->image.yres);
4263 draw_image_record->count = 3;
4264 memcpy(draw_image_record->PointData.pointsF, points, 3 * sizeof(*points));
4266 return Ok;
4267}
4268
4270{
4272 GpStatus stat;
4273
4274 if (metafile->metafile_type != MetafileTypeEmfPlusOnly && metafile->metafile_type != MetafileTypeEmfPlusDual)
4275 return Ok;
4276
4277 stat = METAFILE_AllocateRecord(metafile, sizeof(*record), (void**)&record);
4278 if (stat != Ok) return stat;
4279
4280 record->Type = prop;
4281 record->Flags = val;
4282
4284 return Ok;
4285}
4286
4288{
4289 EmfPlusObject *object_record;
4290 GpStatus stat;
4291 DWORD size;
4292
4293 *id = -1;
4294 if (metafile->metafile_type != MetafileTypeEmfPlusOnly && metafile->metafile_type != MetafileTypeEmfPlusDual)
4295 return Ok;
4296
4299 FIELD_OFFSET(EmfPlusObject, ObjectData.path) + size,
4300 (void**)&object_record);
4301 if (stat != Ok) return stat;
4302
4304 object_record->Header.Type = EmfPlusRecordTypeObject;
4305 object_record->Header.Flags = *id | ObjectTypePath << 8;
4306 write_path_data(path, &object_record->ObjectData.path);
4307 return Ok;
4308}
4309
4311{
4312 DWORD i, data_flags, pen_data_size, brush_size;
4313 EmfPlusObject *object_record;
4314 EmfPlusPenData *pen_data;
4315 GpStatus stat;
4316 BOOL result;
4317
4318 *id = -1;
4319 if (metafile->metafile_type != MetafileTypeEmfPlusOnly && metafile->metafile_type != MetafileTypeEmfPlusDual)
4320 return Ok;
4321
4322 data_flags = 0;
4323 pen_data_size = FIELD_OFFSET(EmfPlusPenData, OptionalData);
4324
4326 if (!result)
4327 {
4328 data_flags |= PenDataTransform;
4329 pen_data_size += sizeof(EmfPlusTransformMatrix);
4330 }
4331 if (pen->startcap != LineCapFlat)
4332 {
4333 data_flags |= PenDataStartCap;
4334 pen_data_size += sizeof(DWORD);
4335 }
4336 if (pen->endcap != LineCapFlat)
4337 {
4338 data_flags |= PenDataEndCap;
4339 pen_data_size += sizeof(DWORD);
4340 }
4341 if (pen->join != LineJoinMiter)
4342 {
4343 data_flags |= PenDataJoin;
4344 pen_data_size += sizeof(DWORD);
4345 }
4346 if (pen->miterlimit != 10.0)
4347 {
4348 data_flags |= PenDataMiterLimit;
4349 pen_data_size += sizeof(REAL);
4350 }
4351 if (pen->style != GP_DEFAULT_PENSTYLE)
4352 {
4353 data_flags |= PenDataLineStyle;
4354 pen_data_size += sizeof(DWORD);
4355 }
4356 if (pen->dashcap != DashCapFlat)
4357 {
4358 data_flags |= PenDataDashedLineCap;
4359 pen_data_size += sizeof(DWORD);
4360 }
4361 data_flags |= PenDataDashedLineOffset;
4362 pen_data_size += sizeof(REAL);
4363 if (pen->numdashes)
4364 {
4365 data_flags |= PenDataDashedLine;
4366 pen_data_size += sizeof(DWORD) + pen->numdashes*sizeof(REAL);
4367 }
4368 if (pen->align != PenAlignmentCenter)
4369 {
4370 data_flags |= PenDataNonCenter;
4371 pen_data_size += sizeof(DWORD);
4372 }
4373 /* TODO: Add support for PenDataCompoundLine */
4374 if (pen->customstart)
4375 {
4376 FIXME("ignoring custom start cup\n");
4377 }
4378 if (pen->customend)
4379 {
4380 FIXME("ignoring custom end cup\n");
4381 }
4382
4383 stat = METAFILE_PrepareBrushData(pen->brush, &brush_size);
4384 if (stat != Ok) return stat;
4385
4387 FIELD_OFFSET(EmfPlusObject, ObjectData.pen.data) + pen_data_size + brush_size,
4388 (void**)&object_record);
4389 if (stat != Ok) return stat;
4390
4392 object_record->Header.Type = EmfPlusRecordTypeObject;
4393 object_record->Header.Flags = *id | ObjectTypePen << 8;
4394 object_record->ObjectData.pen.Version = VERSION_MAGIC2;
4395 object_record->ObjectData.pen.Type = 0;
4396
4397 pen_data = (EmfPlusPenData*)object_record->ObjectData.pen.data;
4398 pen_data->PenDataFlags = data_flags;
4399 pen_data->PenUnit = pen->unit;
4400 pen_data->PenWidth = pen->width;
4401
4402 i = 0;
4403 if (data_flags & PenDataTransform)
4404 {
4406 memcpy(m, &pen->transform, sizeof(*m));
4407 i += sizeof(EmfPlusTransformMatrix);
4408 }
4409 if (data_flags & PenDataStartCap)
4410 {
4411 *(DWORD*)(pen_data->OptionalData + i) = pen->startcap;
4412 i += sizeof(DWORD);
4413 }
4414 if (data_flags & PenDataEndCap)
4415 {
4416 *(DWORD*)(pen_data->OptionalData + i) = pen->endcap;
4417 i += sizeof(DWORD);
4418 }
4419 if (data_flags & PenDataJoin)
4420 {
4421 *(DWORD*)(pen_data->OptionalData + i) = pen->join;
4422 i += sizeof(DWORD);
4423 }
4424 if (data_flags & PenDataMiterLimit)
4425 {
4426 *(REAL*)(pen_data->OptionalData + i) = pen->miterlimit;
4427 i += sizeof(REAL);
4428 }
4429 if (data_flags & PenDataLineStyle)
4430 {
4431 switch (pen->style & PS_STYLE_MASK)
4432 {
4433 case PS_SOLID: *(DWORD*)(pen_data->OptionalData + i) = LineStyleSolid; break;
4434 case PS_DASH: *(DWORD*)(pen_data->OptionalData + i) = LineStyleDash; break;
4435 case PS_DOT: *(DWORD*)(pen_data->OptionalData + i) = LineStyleDot; break;
4436 case PS_DASHDOT: *(DWORD*)(pen_data->OptionalData + i) = LineStyleDashDot; break;
4437 case PS_DASHDOTDOT: *(DWORD*)(pen_data->OptionalData + i) = LineStyleDashDotDot; break;
4438 default: *(DWORD*)(pen_data->OptionalData + i) = LineStyleCustom; break;
4439 }
4440 i += sizeof(DWORD);
4441 }
4442 if (data_flags & PenDataDashedLineCap)
4443 {
4444 *(DWORD*)(pen_data->OptionalData + i) = pen->dashcap;
4445 i += sizeof(DWORD);
4446 }
4447 if (data_flags & PenDataDashedLineOffset)
4448 {
4449 *(REAL*)(pen_data->OptionalData + i) = pen->offset;
4450 i += sizeof(REAL);
4451 }
4452 if (data_flags & PenDataDashedLine)
4453 {
4454 int j;
4455
4456 *(DWORD*)(pen_data->OptionalData + i) = pen->numdashes;
4457 i += sizeof(DWORD);
4458
4459 for (j=0; j<pen->numdashes; j++)
4460 {
4461 *(REAL*)(pen_data->OptionalData + i) = pen->dashes[j];
4462 i += sizeof(REAL);
4463 }
4464 }
4465 if (data_flags & PenDataNonCenter)
4466 {
4467 *(REAL*)(pen_data->OptionalData + i) = pen->align;
4468 i += sizeof(DWORD);
4469 }
4470
4472 (EmfPlusBrush*)(object_record->ObjectData.pen.data + pen_data_size));
4473 return Ok;
4474}
4475
4477{
4478 EmfPlusDrawPath *draw_path_record;
4479 DWORD path_id;
4480 DWORD pen_id;
4481 GpStatus stat;
4482
4483 if (metafile->metafile_type == MetafileTypeEmf)
4484 {
4485 FIXME("stub!\n");
4486 return NotImplemented;
4487 }
4488
4489 stat = METAFILE_AddPenObject(metafile, pen, &pen_id);
4490 if (stat != Ok) return stat;
4491
4493 if (stat != Ok) return stat;
4494
4495 stat = METAFILE_AllocateRecord(metafile, sizeof(EmfPlusDrawPath), (void**)&draw_path_record);
4496 if (stat != Ok) return stat;
4497 draw_path_record->Header.Type = EmfPlusRecordTypeDrawPath;
4498 draw_path_record->Header.Flags = path_id;
4499 draw_path_record->PenId = pen_id;
4500
4502 return Ok;
4503}
4504
4506{
4507 EmfPlusFillPath *fill_path_record;
4508 DWORD brush_id = -1, path_id;
4509 BOOL inline_color;
4510 GpStatus stat;
4511
4512 if (metafile->metafile_type == MetafileTypeEmf)
4513 {
4514 FIXME("stub!\n");
4515 return NotImplemented;
4516 }
4517
4518 inline_color = brush->bt == BrushTypeSolidColor;
4519 if (!inline_color)
4520 {
4521 stat = METAFILE_AddBrushObject(metafile, brush, &brush_id);
4522 if (stat != Ok) return stat;
4523 }
4524
4526 if (stat != Ok) return stat;
4527
4529 sizeof(EmfPlusFillPath), (void**)&fill_path_record);
4530 if (stat != Ok) return stat;
4531 fill_path_record->Header.Type = EmfPlusRecordTypeFillPath;
4532 if (inline_color)
4533 {
4534 fill_path_record->Header.Flags = 0x8000 | path_id;
4535 fill_path_record->data.Color = ((GpSolidFill *)brush)->color;
4536 }
4537 else
4538 {
4539 fill_path_record->Header.Flags = path_id;
4540 fill_path_record->data.BrushId = brush_id;
4541 }
4542
4544 return Ok;
4545}
static HDC hDC
Definition: 3dtext.c:33
static HRGN hrgn
_STLP_MOVE_TO_STD_NAMESPACE void fill(_ForwardIter __first, _ForwardIter __last, const _Tp &__val)
Definition: _algobase.h:449
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define stat
Definition: acwin.h:99
#define read
Definition: acwin.h:96
static int state
Definition: maze.c:121
static void * heap_alloc(size_t len)
Definition: appwiz.h:66
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define ARRAY_SIZE(A)
Definition: main.h:33
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: debug.h:111
#define WARN(fmt,...)
Definition: debug.h:112
#define ERR(fmt,...)
Definition: debug.h:110
Definition: list.h:37
#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)
#define GENERIC_READ
Definition: compat.h:135
#define CALLBACK
Definition: compat.h:35
GpStatus WINGDIPAPI GdipDeleteBrush(GpBrush *brush)
Definition: brush.c:994
GpStatus WINGDIPAPI GdipCreateHatchBrush(GpHatchStyle hatchstyle, ARGB forecol, ARGB backcol, GpHatch **brush)
Definition: brush.c:276
GpStatus WINGDIPAPI GdipSetTextureTransform(GpTexture *texture, GDIPCONST GpMatrix *matrix)
Definition: brush.c:1939
GpStatus WINGDIPAPI GdipCreateLineBrush(GDIPCONST GpPointF *startpoint, GDIPCONST GpPointF *endpoint, ARGB startcolor, ARGB endcolor, GpWrapMode wrap, GpLineGradient **line)
Definition: brush.c:372
GpStatus WINGDIPAPI GdipSetLinePresetBlend(GpLineGradient *brush, GDIPCONST ARGB *blend, GDIPCONST REAL *positions, INT count)
Definition: brush.c:2042
GpStatus WINGDIPAPI GdipSetLineTransform(GpLineGradient *brush, GDIPCONST GpMatrix *matrix)
Definition: brush.c:2116
GpStatus WINGDIPAPI GdipSetLineBlend(GpLineGradient *brush, GDIPCONST REAL *factors, GDIPCONST REAL *positions, INT count)
Definition: brush.c:1369
GpStatus WINGDIPAPI GdipCreateSolidFill(ARGB color, GpSolidFill **sf)
Definition: brush.c:757
GpStatus WINGDIPAPI GdipCreateTexture(GpImage *image, GpWrapMode wrapmode, GpTexture **texture)
Definition: brush.c:786
GpStatus WINGDIPAPI GdipDeleteFontFamily(GpFontFamily *FontFamily)
Definition: font.c:869
GpStatus WINGDIPAPI GdipDeleteFont(GpFont *font)
Definition: font.c:270
GpStatus WINGDIPAPI GdipCreateFontFamilyFromName(GDIPCONST WCHAR *name, GpFontCollection *fontCollection, GpFontFamily **FontFamily)
Definition: font.c:746
GpStatus WINGDIPAPI GdipCreateFont(GDIPCONST GpFontFamily *fontFamily, REAL emSize, INT style, Unit unit, GpFont **font)
Definition: font.c:144
GpStatus WINGDIPAPI GdipFillRectangles(GpGraphics *graphics, GpBrush *brush, GDIPCONST GpRectF *rects, INT count)
Definition: graphics.c:4567
GpStatus WINGDIPAPI GdipCreateStreamOnFile(GDIPCONST WCHAR *filename, UINT access, IStream **stream)
Definition: graphics.c:2558
GpStatus WINGDIPAPI GdipDrawEllipseI(GpGraphics *graphics, GpPen *pen, INT x, INT y, INT width, INT height)
Definition: graphics.c:2960
GpStatus WINGDIPAPI GdipDeleteGraphics(GpGraphics *graphics)
Definition: graphics.c:2581
GpStatus WINGDIPAPI GdipFillEllipse(GpGraphics *graphics, GpBrush *brush, REAL x, REAL y, REAL width, REAL height)
Definition: graphics.c:4290
GpStatus WINGDIPAPI GdipGetClip(GpGraphics *graphics, GpRegion *region)
Definition: graphics.c:6809
GpStatus WINGDIPAPI GdipSetCompositingMode(GpGraphics *graphics, CompositingMode mode)
Definition: graphics.c:6085
GpStatus WINGDIPAPI GdipFillClosedCurve2(GpGraphics *graphics, GpBrush *brush, GDIPCONST GpPointF *points, INT count, REAL tension, GpFillMode fill)
Definition: graphics.c:4213
GpStatus WINGDIPAPI GdipDrawPie(GpGraphics *graphics, GpPen *pen, REAL x, REAL y, REAL width, REAL height, REAL startAngle, REAL sweepAngle)
Definition: graphics.c:4091
GpStatus WINGDIPAPI GdipGetDC(GpGraphics *graphics, HDC *hdc)
Definition: graphics.c:6682
GpStatus WINGDIPAPI GdipGraphicsClear(GpGraphics *graphics, ARGB color)
Definition: graphics.c:5076
GpStatus WINGDIPAPI GdipDrawRectangles(GpGraphics *graphics, GpPen *pen, GDIPCONST GpRectF *rects, INT count)
Definition: graphics.c:4159
GpStatus WINGDIPAPI GdipFillPie(GpGraphics *graphics, GpBrush *brush, REAL x, REAL y, REAL width, REAL height, REAL startAngle, REAL sweepAngle)
Definition: graphics.c:4424
GpStatus WINGDIPAPI GdipSetTextRenderingHint(GpGraphics *graphics, TextRenderingHint hint)
Definition: graphics.c:6330
GpStatus WINGDIPAPI GdipSetWorldTransform(GpGraphics *graphics, GpMatrix *matrix)
Definition: graphics.c:6358
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:3517
GpStatus WINGDIPAPI GdipSaveGraphics(GpGraphics *graphics, GraphicsState *state)
Definition: graphics.c:5911
GpStatus WINGDIPAPI GdipDrawPath(GpGraphics *graphics, GpPen *pen, GpPath *path)
Definition: graphics.c:4066
GpStatus WINGDIPAPI GdipEndContainer(GpGraphics *graphics, GraphicsContainer state)
Definition: graphics.c:6039
GpStatus WINGDIPAPI GdipSetCompositingQuality(GpGraphics *graphics, CompositingQuality quality)
Definition: graphics.c:6114
GpStatus WINGDIPAPI GdipSetInterpolationMode(GpGraphics *graphics, InterpolationMode mode)
Definition: graphics.c:6143
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:3071
GpStatus WINGDIPAPI GdipDrawEllipse(GpGraphics *graphics, GpPen *pen, REAL x, REAL y, REAL width, REAL height)
Definition: graphics.c:2935
GpStatus WINGDIPAPI GdipFillPath(GpGraphics *graphics, GpBrush *brush, GpPath *path)
Definition: graphics.c:4391
GpStatus WINGDIPAPI GdipDrawPieI(GpGraphics *graphics, GpPen *pen, INT x, INT y, INT width, INT height, REAL startAngle, REAL sweepAngle)
Definition: graphics.c:4117
GpStatus WINGDIPAPI GdipReleaseDC(GpGraphics *graphics, HDC hdc)
Definition: graphics.c:6758
GpStatus WINGDIPAPI GdipDrawArc(GpGraphics *graphics, GpPen *pen, REAL x, REAL y, REAL width, REAL height, REAL startAngle, REAL sweepAngle)
Definition: graphics.c:2619
GpStatus WINGDIPAPI GdipDrawArcI(GpGraphics *graphics, GpPen *pen, INT x, INT y, INT width, INT height, REAL startAngle, REAL sweepAngle)
Definition: graphics.c:2645
GpStatus WINGDIPAPI GdipTransformPoints(GpGraphics *graphics, GpCoordinateSpace dst_space, GpCoordinateSpace src_space, GpPointF *points, INT count)
Definition: graphics.c:6960
GpStatus WINGDIPAPI GdipFillPieI(GpGraphics *graphics, GpBrush *brush, INT x, INT y, INT width, INT height, REAL startAngle, REAL sweepAngle)
Definition: graphics.c:4454
GpStatus WINGDIPAPI GdipRestoreGraphics(GpGraphics *graphics, GraphicsState state)
Definition: graphics.c:6045
GpStatus WINGDIPAPI GdipSetPageUnit(GpGraphics *graphics, GpUnit unit)
Definition: graphics.c:6202
GpStatus WINGDIPAPI GdipSetSmoothingMode(GpGraphics *graphics, SmoothingMode mode)
Definition: graphics.c:6289
GpStatus WINGDIPAPI GdipFillEllipseI(GpGraphics *graphics, GpBrush *brush, INT x, INT y, INT width, INT height)
Definition: graphics.c:4319
GpStatus WINGDIPAPI GdipSetPixelOffsetMode(GpGraphics *graphics, PixelOffsetMode mode)
Definition: graphics.c:6229
GpStatus WINGDIPAPI GdipResetWorldTransform(GpGraphics *graphics)
Definition: graphics.c:5840
GpStatus WINGDIPAPI GdipSetPageScale(GpGraphics *graphics, REAL scale)
Definition: graphics.c:6178
GpStatus WINGDIPAPI GdipBeginContainer2(GpGraphics *graphics, GraphicsContainer *state)
Definition: graphics.c:5917
GpStatus WINGDIPAPI GdipCreatePath(GpFillMode fill, GpPath **path)
GpStatus WINGDIPAPI GdipDeletePath(GpPath *path)
GpStatus WINGDIPAPI GdipAddPathPolygon(GpPath *path, GDIPCONST GpPointF *points, INT count)
Definition: graphicspath.c:844
GpStatus WINGDIPAPI GdipCreateBitmapFromScan0(INT width, INT height, INT stride, PixelFormat format, BYTE *scan0, GpBitmap **bitmap)
Definition: image.c:1760
GpStatus WINGDIPAPI GdipSetImagePalette(GpImage *image, GDIPCONST ColorPalette *palette)
Definition: image.c:4744
GpStatus WINGDIPAPI GdipGetImageGraphicsContext(GpImage *image, GpGraphics **graphics)
Definition: image.c:2249
GpStatus WINGDIPAPI GdipDisposeImage(GpImage *image)
Definition: image.c:2155
GpStatus WINGDIPAPI GdipLoadImageFromStream(IStream *stream, GpImage **image)
Definition: image.c:4405
GpStatus WINGDIPAPI GdipCreateBitmapFromStream(IStream *stream, GpBitmap **bitmap)
Definition: image.c:1935
GpStatus WINGDIPAPI GdipScaleMatrix(GpMatrix *matrix, REAL scaleX, REAL scaleY, GpMatrixOrder order)
Definition: matrix.c:289
GpStatus WINGDIPAPI GdipMultiplyMatrix(GpMatrix *matrix, GDIPCONST GpMatrix *matrix2, GpMatrixOrder order)
Definition: matrix.c:240
GpStatus WINGDIPAPI GdipTranslateMatrix(GpMatrix *matrix, REAL offsetX, REAL offsetY, GpMatrixOrder order)
Definition: matrix.c:418
GpStatus WINGDIPAPI GdipCreateMatrix3(GDIPCONST GpRectF *rect, GDIPCONST GpPointF *pt, GpMatrix **matrix)
Definition: matrix.c:85
GpStatus WINGDIPAPI GdipSetMatrixElements(GpMatrix *matrix, REAL m11, REAL m12, REAL m21, REAL m22, REAL dx, REAL dy)
Definition: matrix.c:316
GpStatus WINGDIPAPI GdipRotateMatrix(GpMatrix *matrix, REAL angle, GpMatrixOrder order)
Definition: matrix.c:258
GpStatus WINGDIPAPI GdipIsMatrixIdentity(GDIPCONST GpMatrix *matrix, BOOL *result)
Definition: matrix.c:512
GpStatus WINGDIPAPI GdipDeleteMatrix(GpMatrix *matrix)
Definition: matrix.c:160
GpStatus WINGDIPAPI GdipCreateMatrix(GpMatrix **matrix)
Definition: matrix.c:140
GpStatus METAFILE_RotateWorldTransform(GpMetafile *metafile, REAL angle, MatrixOrder order)
Definition: metafile.c:1307
GpStatus WINGDIPAPI GdipCreateMetafileFromWmf(HMETAFILE hwmf, BOOL delete, GDIPCONST WmfPlaceableFileHeader *placeable, GpMetafile **metafile)
Definition: metafile.c:3845
ImageDataType
Definition: metafile.c:355
@ ImageDataTypeBitmap
Definition: metafile.c:357
@ ImageDataTypeUnknown
Definition: metafile.c:356
@ ImageDataTypeMetafile
Definition: metafile.c:358
GpStatus WINGDIPAPI GdipGetMetafileHeaderFromStream(IStream *stream, MetafileHeader *header)
Definition: metafile.c:3784
static GpStatus metafile_deserialize_brush(const BYTE *record_data, UINT data_size, GpBrush **brush)
Definition: metafile.c:2023
GpStatus METAFILE_GraphicsClear(GpMetafile *metafile, ARGB color)
Definition: metafile.c:949
GpStatus METAFILE_TranslateWorldTransform(GpMetafile *metafile, REAL dx, REAL dy, MatrixOrder order)
Definition: metafile.c:1330
GpStatus METAFILE_GetGraphicsContext(GpMetafile *metafile, GpGraphics **result)
Definition: metafile.c:908
static GpStatus METAFILE_WriteEndOfFile(GpMetafile *metafile)
Definition: metafile.c:714
GpStatus WINGDIPAPI GdipCreateMetafileFromFile(GDIPCONST WCHAR *file, GpMetafile **metafile)
Definition: metafile.c:3915
GpStatus METAFILE_ScaleWorldTransform(GpMetafile *metafile, REAL sx, REAL sy, MatrixOrder order)
Definition: metafile.c:1260
static GpStatus METAFILE_PlaybackUpdateWorldTransform(GpMetafile *metafile)
Definition: metafile.c:1691
static void metafile_free_object_table_entry(GpMetafile *metafile, BYTE id)
Definition: metafile.c:552
GpStatus METAFILE_AddSimpleProperty(GpMetafile *metafile, SHORT prop, SHORT val)
Definition: metafile.c:4269
static GpStatus METAFILE_FillEmfPlusBitmap(EmfPlusBitmap *record, IStream *stream, DWORD size)
Definition: metafile.c:4065
GpStatus METAFILE_SetPageTransform(GpMetafile *metafile, GpUnit unit, REAL scale)
Definition: metafile.c:1214
static GpStatus METAFILE_PlaybackUpdateGdiTransform(GpMetafile *metafile)
Definition: metafile.c:1642
PenDataFlags
Definition: metafile.c:165
@ PenDataNonCenter
Definition: metafile.c:175
@ PenDataDashedLineCap
Definition: metafile.c:172
@ PenDataJoin
Definition: metafile.c:169
@ PenDataCustomEndCap
Definition: metafile.c:178
@ PenDataMiterLimit
Definition: metafile.c:170
@ PenDataStartCap
Definition: metafile.c:167
@ PenDataLineStyle
Definition: metafile.c:171
@ PenDataDashedLineOffset
Definition: metafile.c:173
@ PenDataCustomStartCap
Definition: metafile.c:177
@ PenDataTransform
Definition: metafile.c:166
@ PenDataCompoundLine
Definition: metafile.c:176
@ PenDataDashedLine
Definition: metafile.c:174
@ PenDataEndCap
Definition: metafile.c:168
static GpStatus METAFILE_AllocateRecord(GpMetafile *metafile, DWORD size, void **result)
Definition: metafile.c:618
GpStatus METAFILE_ReleaseDC(GpMetafile *metafile, HDC hdc)
Definition: metafile.c:1492
GpStatus WINGDIPAPI GdipRecordMetafileFileName(GDIPCONST WCHAR *fileName, HDC hdc, EmfType type, GDIPCONST GpRectF *pFrameRect, MetafileFrameUnit frameUnit, GDIPCONST WCHAR *desc, GpMetafile **metafile)
Definition: metafile.c:3993
GpStatus METAFILE_SetClipRegion(GpMetafile *metafile, GpRegion *region, CombineMode mode)
Definition: metafile.c:1189
static GpStatus METAFILE_AddPenObject(GpMetafile *metafile, GpPen *pen, DWORD *id)
Definition: metafile.c:4310
GpStatus WINGDIPAPI GdipEnumerateMetafileDestPoint(GpGraphics *graphics, GDIPCONST GpMetafile *metafile, GDIPCONST GpPointF *dest, EnumerateMetafileProc callback, VOID *cb_data, GDIPCONST GpImageAttributes *attrs)
Definition: metafile.c:3602
GpStatus METAFILE_SetClipRect(GpMetafile *metafile, REAL x, REAL y, REAL width, REAL height, CombineMode mode)
Definition: metafile.c:1141
GpStatus WINGDIPAPI GdipGetMetafileHeaderFromFile(GDIPCONST WCHAR *filename, MetafileHeader *header)
Definition: metafile.c:3764
static void METAFILE_RemoveLastRecord(GpMetafile *metafile, EmfPlusRecordHeader *record)
Definition: metafile.c:664
static DWORD METAFILE_AddObjectId(GpMetafile *metafile)
Definition: metafile.c:613
static GpStatus METAFILE_AddImageObject(GpMetafile *metafile, GpImage *image, DWORD *id)
Definition: metafile.c:4080
GpStatus WINGDIPAPI GdipConvertToEmfPlusToFile(const GpGraphics *refGraphics, GpMetafile *metafile, BOOL *conversionSuccess, const WCHAR *filename, EmfType emfType, const WCHAR *description, GpMetafile **out_metafile)
Definition: metafile.c:4018
GpStatus METAFILE_GraphicsDeleted(GpMetafile *metafile)
Definition: metafile.c:1500
static int CALLBACK enum_metafile_proc(HDC hDC, HANDLETABLE *lpHTable, const ENHMETARECORD *lpEMFR, int nObj, LPARAM lpData)
Definition: metafile.c:3385
GpStatus WINGDIPAPI GdipCreateMetafileFromWmfFile(GDIPCONST WCHAR *file, GDIPCONST WmfPlaceableFileHeader *placeable, GpMetafile **metafile)
Definition: metafile.c:3896
BitmapDataType
Definition: metafile.c:332
@ BitmapDataTypePixel
Definition: metafile.c:333
@ BitmapDataTypeCompressed
Definition: metafile.c:334
static GpStatus METAFILE_AddRegionObject(GpMetafile *metafile, GpRegion *region, DWORD *id)
Definition: metafile.c:1167
GpStatus METAFILE_BeginContainerNoParams(GpMetafile *metafile, DWORD StackIndex)
Definition: metafile.c:1400
static GpStatus METAFILE_WriteHeader(GpMetafile *metafile, HDC hdc)
Definition: metafile.c:679
GpStatus WINGDIPAPI GdipCreateMetafileFromStream(IStream *stream, GpMetafile **metafile)
Definition: metafile.c:3936
GpStatus WINGDIPAPI GdipRecordMetafileFileNameI(GDIPCONST WCHAR *fileName, HDC hdc, EmfType type, GDIPCONST GpRect *pFrameRect, MetafileFrameUnit frameUnit, GDIPCONST WCHAR *desc, GpMetafile **metafile)
Definition: metafile.c:4004
GpStatus WINGDIPAPI GdipRecordMetafileStream(IStream *stream, HDC hdc, EmfType type, GDIPCONST GpRectF *frameRect, MetafileFrameUnit frameUnit, GDIPCONST WCHAR *desc, GpMetafile **metafile)
Definition: metafile.c:863
static GpStatus METAFILE_AddImageAttributesObject(GpMetafile *metafile, const GpImageAttributes *attrs, DWORD *id)
Definition: metafile.c:4158
static void METAFILE_FillBrushData(GpBrush *brush, EmfPlusBrush *data)
Definition: metafile.c:1001
GpStatus METAFILE_GetDC(GpMetafile *metafile, HDC *hdc)
Definition: metafile.c:927
LineStyle
Definition: metafile.c:187
@ LineStyleDot
Definition: metafile.c:190
@ LineStyleDashDotDot
Definition: metafile.c:192
@ LineStyleDashDot
Definition: metafile.c:191
@ LineStyleSolid
Definition: metafile.c:188
@ LineStyleDash
Definition: metafile.c:189
@ LineStyleCustom
Definition: metafile.c:193
GpStatus METAFILE_FillPath(GpMetafile *metafile, GpBrush *brush, GpPath *path)
Definition: metafile.c:4505
struct EmfPlusRecordHeader EmfPlusRecordHeader
GpStatus WINGDIPAPI GdipPlayMetafileRecord(GDIPCONST GpMetafile *metafile, EmfPlusRecordType recordType, UINT flags, UINT dataSize, GDIPCONST BYTE *data)
Definition: metafile.c:2461
GpStatus WINGDIPAPI GdipRecordMetafileI(HDC hdc, EmfType type, GDIPCONST GpRect *frameRect, MetafileFrameUnit frameUnit, GDIPCONST WCHAR *desc, GpMetafile **metafile)
Definition: metafile.c:842
static BOOL is_integer_rect(const GpRectF *rect)
Definition: metafile.c:970
static GpStatus metafile_deserialize_image(const BYTE *record_data, UINT data_size, GpImage **image)
Definition: metafile.c:1726
static void METAFILE_WriteRecords(GpMetafile *metafile)
Definition: metafile.c:670
static void METAFILE_AdjustFrame(GpMetafile *metafile, const GpPointF *points, UINT num_points)
Definition: metafile.c:884
static GpStatus METAFILE_AddBrushObject(GpMetafile *metafile, GpBrush *brush, DWORD *id)
Definition: metafile.c:1027
GpStatus METAFILE_RestoreGraphics(GpMetafile *metafile, DWORD StackIndex)
Definition: metafile.c:1469
static GpStatus metafile_set_clip_region(GpMetafile *metafile, GpRegion *region, CombineMode mode)
Definition: metafile.c:2449
static void METAFILE_PlaybackReleaseDC(GpMetafile *metafile)
Definition: metafile.c:1673
GpStatus WINGDIPAPI GdipCreateMetafileFromEmf(HENHMETAFILE hemf, BOOL delete, GpMetafile **metafile)
Definition: metafile.c:3804
GpStatus WINGDIPAPI GdipEnumerateMetafileDestPointI(GpGraphics *graphics, GDIPCONST GpMetafile *metafile, GDIPCONST GpPoint *dest, EnumerateMetafileProc callback, VOID *cb_data, GDIPCONST GpImageAttributes *attrs)
Definition: metafile.c:3618
static int CALLBACK get_emfplus_header_proc(HDC hDC, HANDLETABLE *lpHTable, const ENHMETARECORD *lpEMFR, int nObj, LPARAM lpData)
Definition: metafile.c:3662
void METAFILE_Free(GpMetafile *metafile)
Definition: metafile.c:590
BrushDataFlags
Definition: metafile.c:229
@ BrushDataBlendFactorsH
Definition: metafile.c:233
@ BrushDataTransform
Definition: metafile.c:231
@ BrushDataBlendFactorsV
Definition: metafile.c:234
@ BrushDataPresetColors
Definition: metafile.c:232
@ BrushDataDoNotTransform
Definition: metafile.c:237
@ BrushDataFocusScales
Definition: metafile.c:235
@ BrushDataPath
Definition: metafile.c:230
@ BrushDataIsGammaCorrected
Definition: metafile.c:236
GpStatus METAFILE_MultiplyWorldTransform(GpMetafile *metafile, GDIPCONST GpMatrix *matrix, MatrixOrder order)
Definition: metafile.c:1284
GpStatus METAFILE_SetWorldTransform(GpMetafile *metafile, GDIPCONST GpMatrix *transform)
Definition: metafile.c:1237
static void METAFILE_GetFinalGdiTransform(const GpMetafile *metafile, XFORM *result)
Definition: metafile.c:1626
static GpStatus METAFILE_PrepareBrushData(GpBrush *brush, DWORD *size)
Definition: metafile.c:983
GpStatus METAFILE_ResetWorldTransform(GpMetafile *metafile)
Definition: metafile.c:1354
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:4190
static void metafile_set_object_table_entry(GpMetafile *metafile, BYTE id, BYTE type, void *object)
Definition: metafile.c:1719
static GpStatus metafile_read_region_node(struct memory_buffer *mbuf, GpRegion *region, region_element *node, UINT *count)
Definition: metafile.c:1897
GpStatus METAFILE_BeginContainer(GpMetafile *metafile, GDIPCONST GpRectF *dstrect, GDIPCONST GpRectF *srcrect, GpUnit unit, DWORD StackIndex)
Definition: metafile.c:1376
GpStatus WINGDIPAPI GdipGetHemfFromMetafile(GpMetafile *metafile, HENHMETAFILE *hEmf)
Definition: metafile.c:1613
GpStatus METAFILE_EndContainer(GpMetafile *metafile, DWORD StackIndex)
Definition: metafile.c:1423
static GpStatus METAFILE_PlaybackUpdateClip(GpMetafile *metafile)
Definition: metafile.c:1682
HRESULT WINAPI WICCreateImagingFactory_Proxy(UINT, IWICImagingFactory **)
Definition: proxy.c:651
static GpStatus METAFILE_PlaybackObject(GpMetafile *metafile, UINT flags, UINT data_size, const BYTE *record_data)
Definition: metafile.c:2249
container_type
Definition: metafile.c:147
@ SAVE_GRAPHICS
Definition: metafile.c:149
@ BEGIN_CONTAINER
Definition: metafile.c:148
static GpStatus metafile_deserialize_path(const BYTE *record_data, UINT data_size, GpPath **path)
Definition: metafile.c:1828
GpStatus WINGDIPAPI GdipGetMetafileHeaderFromWmf(HMETAFILE hwmf, GDIPCONST WmfPlaceableFileHeader *placeable, MetafileHeader *header)
Definition: metafile.c:3747
static GpStatus metafile_get_pen_brush_data_offset(EmfPlusPen *data, UINT data_size, DWORD *ret)
Definition: metafile.c:2162
GpStatus WINGDIPAPI GdipEmfToWmfBits(HENHMETAFILE hemf, UINT cbData16, LPBYTE pData16, INT iMapMode, INT eFlags)
Definition: metafile.c:3986
GpStatus WINGDIPAPI GdipGetMetafileHeaderFromEmf(HENHMETAFILE hemf, MetafileHeader *header)
Definition: metafile.c:3688
GpStatus WINGDIPAPI GdipSetMetafileDownLevelRasterizationLimit(GpMetafile *metafile, UINT limitDpi)
Definition: metafile.c:3956
GpStatus WINGDIPAPI GdipEnumerateMetafileDestRect(GpGraphics *graphics, GDIPCONST GpMetafile *metafile, GDIPCONST GpRectF *dest, EnumerateMetafileProc callback, VOID *cb_data, GDIPCONST GpImageAttributes *attrs)
Definition: metafile.c:3569
GpStatus METAFILE_DrawPath(GpMetafile *metafile, GpPen *pen, GpPath *path)
Definition: metafile.c:4476
GpStatus WINGDIPAPI GdipConvertToEmfPlus(const GpGraphics *ref, GpMetafile *metafile, BOOL *succ, EmfType emfType, const WCHAR *description, GpMetafile **out_metafile)
Definition: metafile.c:3964
GpStatus WINGDIPAPI GdipEnumerateMetafileDestRectI(GpGraphics *graphics, GDIPCONST GpMetafile *metafile, GDIPCONST GpRect *dest, EnumerateMetafileProc callback, VOID *cb_data, GDIPCONST GpImageAttributes *attrs)
Definition: metafile.c:3586
GpStatus WINGDIPAPI GdipGetMetafileHeaderFromMetafile(GpMetafile *metafile, MetafileHeader *header)
Definition: metafile.c:3632
GpStatus METAFILE_SaveGraphics(GpMetafile *metafile, DWORD StackIndex)
Definition: metafile.c:1446
static GpStatus METAFILE_AddPathObject(GpMetafile *metafile, GpPath *path, DWORD *id)
Definition: metafile.c:4287
static GpStatus METAFILE_PlaybackGetDC(GpMetafile *metafile)
Definition: metafile.c:1656
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:3435
GpStatus WINGDIPAPI GdipRecordMetafile(HDC hdc, EmfType type, GDIPCONST GpRectF *frameRect, MetafileFrameUnit frameUnit, GDIPCONST WCHAR *desc, GpMetafile **metafile)
Definition: metafile.c:735
static GpStatus metafile_deserialize_region(const BYTE *record_data, UINT data_size, GpRegion **region)
Definition: metafile.c:1992
ARGB EmfPlusARGB
Definition: metafile.c:48
static GpStatus METAFILE_CreateCompressedImageStream(GpImage *image, IStream **stream, DWORD *size)
Definition: metafile.c:4027
GpStatus METAFILE_FillRectangles(GpMetafile *metafile, GpBrush *brush, GDIPCONST GpRectF *rects, INT count)
Definition: metafile.c:1051
GpStatus WINGDIPAPI GdipSetPenLineJoin(GpPen *pen, GpLineJoin join)
Definition: pen.c:708
GpStatus WINGDIPAPI GdipDeletePen(GpPen *pen)
Definition: pen.c:192
GpStatus WINGDIPAPI GdipCreatePen2(GpBrush *brush, REAL width, GpUnit unit, GpPen **pen)
Definition: pen.c:150
GpStatus WINGDIPAPI GdipSetPenMiterLimit(GpPen *pen, REAL limit)
Definition: pen.c:721
GpStatus WINGDIPAPI GdipSetPenDashStyle(GpPen *pen, GpDashStyle dash)
Definition: pen.c:650
GpStatus WINGDIPAPI GdipSetPenEndCap(GpPen *pen, GpLineCap cap)
Definition: pen.c:671
GpStatus WINGDIPAPI GdipSetPenStartCap(GpPen *pen, GpLineCap cap)
Definition: pen.c:733
GpStatus WINGDIPAPI GdipSetPenDashOffset(GpPen *pen, REAL offset)
Definition: pen.c:638
GpStatus WINGDIPAPI GdipCombineRegionPath(GpRegion *region, GpPath *path, CombineMode mode)
Definition: region.c:232
GpStatus WINGDIPAPI GdipTransformRegion(GpRegion *region, GpMatrix *matrix)
Definition: region.c:1480
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:571
GpStatus WINGDIPAPI GdipCloneRegion(GpRegion *region, GpRegion **clone)
Definition: region.c:211
HRESULT WINAPI CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL fDeleteOnRelease, LPSTREAM *ppstm)
#define assert(x)
Definition: debug.h:53
#define pt(x, y)
Definition: drawing.c:79
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
pKey DeleteObject()
void WINGDIPAPI GdipFree(void *ptr)
Definition: gdiplus.c:150
GpStatus hresult_to_status(HRESULT res)
Definition: gdiplus.c:312
const char * debugstr_rectf(const RectF *rc)
Definition: gdiplus.c:476
const char * debugstr_pointf(const PointF *pt)
Definition: gdiplus.c:482
void *WINGDIPAPI GdipAlloc(SIZE_T size)
Definition: gdiplus.c:142
REAL units_to_pixels(REAL units, GpUnit unit, REAL dpi)
Definition: gdiplus.c:327
DWORD write_path_data(GpPath *path, void *data) DECLSPEC_HIDDEN
static INT gdip_round(REAL x)
#define EmfPlusObjectTableSize
static void init_memory_buffer(struct memory_buffer *mbuf, const BYTE *buffer, INT size)
#define VERSION_MAGIC2
GpStatus graphics_from_image(GpImage *image, GpGraphics **graphics) DECLSPEC_HIDDEN
Definition: graphics.c:2484
@ ObjectTypeImage
@ ObjectTypeInvalid
@ ObjectTypeImageAttributes
@ ObjectTypePen
@ ObjectTypeFont
@ ObjectTypeRegion
@ ObjectTypeMax
@ ObjectTypeBrush
@ ObjectTypePath
GpStatus get_graphics_transform(GpGraphics *graphics, GpCoordinateSpace dst_space, GpCoordinateSpace src_space, GpMatrix *matrix) DECLSPEC_HIDDEN
Definition: graphics.c:6871
static const void * buffer_read(struct memory_buffer *mbuf, INT size)
GpStatus encode_image_png(GpImage *image, IStream *stream, GDIPCONST EncoderParameters *params) DECLSPEC_HIDDEN
Definition: image.c:4650
@ RegionDataEmptyRect
@ RegionDataRect
@ RegionDataInfiniteRect
@ RegionDataPath
#define GP_DEFAULT_PENSTYLE
DWORD write_region_data(const GpRegion *region, void *data) DECLSPEC_HIDDEN
Definition: region.c:696
@ DashCapFlat
Definition: gdiplusenums.h:171
@ LineJoinMiter
Definition: gdiplusenums.h:106
@ ImageTypeBitmap
Definition: gdiplusenums.h:195
@ ImageTypeMetafile
Definition: gdiplusenums.h:196
CombineMode
Definition: gdiplusenums.h:350
@ CombineModeUnion
Definition: gdiplusenums.h:353
@ CombineModeReplace
Definition: gdiplusenums.h:351
@ CombineModeComplement
Definition: gdiplusenums.h:356
@ CombineModeIntersect
Definition: gdiplusenums.h:352
@ CombineModeExclude
Definition: gdiplusenums.h:355
@ CombineModeXor
Definition: gdiplusenums.h:354
@ ImageFlagsNone
Definition: gdiplusenums.h:333
EmfPlusRecordType
Definition: gdiplusenums.h:455
@ EmfPlusRecordTypeGetDC
Definition: gdiplusenums.h:663
@ EmfPlusRecordTypeDrawPie
Definition: gdiplusenums.h:676
@ EmfPlusRecordTypeSetCompositingQuality
Definition: gdiplusenums.h:695
@ EmfPlusRecordTypeSetClipRect
Definition: gdiplusenums.h:709
@ EmfPlusRecordTypeSetClipPath
Definition: gdiplusenums.h:710
@ EmfPlusRecordTypeResetWorldTransform
Definition: gdiplusenums.h:702
@ EmfPlusRecordTypeEndContainer
Definition: gdiplusenums.h:700
@ EmfPlusRecordTypeSave
Definition: gdiplusenums.h:696
@ EmfPlusRecordTypeRotateWorldTransform
Definition: gdiplusenums.h:706
@ EmfPlusRecordTypeTranslateWorldTransform
Definition: gdiplusenums.h:704
@ EmfPlusRecordTypeDrawImagePoints
Definition: gdiplusenums.h:686
@ EmfPlusRecordTypeRestore
Definition: gdiplusenums.h:697
@ EmfPlusRecordTypeClear
Definition: gdiplusenums.h:668
@ EmfPlusRecordTypeFillPath
Definition: gdiplusenums.h:679
@ EmfPlusRecordTypeSetPixelOffsetMode
Definition: gdiplusenums.h:693
@ EmfPlusRecordTypeDrawArc
Definition: gdiplusenums.h:677
@ EmfPlusRecordTypeSetCompositingMode
Definition: gdiplusenums.h:694
@ EmfPlusRecordTypeBeginContainer
Definition: gdiplusenums.h:698
@ EmfPlusRecordTypeDrawPath
Definition: gdiplusenums.h:680
@ EmfPlusRecordTypeObject
Definition: gdiplusenums.h:667
@ EmfPlusRecordTypeFillClosedCurve
Definition: gdiplusenums.h:681
@ EmfPlusRecordTypeFillPie
Definition: gdiplusenums.h:675
@ EmfPlusRecordTypeSetWorldTransform
Definition: gdiplusenums.h:701
@ EmfPlusRecordTypeFillRects
Definition: gdiplusenums.h:669
@ EmfPlusRecordTypeHeader
Definition: gdiplusenums.h:660
@ EmfPlusRecordTypeDrawEllipse
Definition: gdiplusenums.h:674
@ EmfPlusRecordTypeFillEllipse
Definition: gdiplusenums.h:673
@ EmfPlusRecordTypeSetInterpolationMode
Definition: gdiplusenums.h:692
@ EmfPlusRecordTypeEndOfFile
Definition: gdiplusenums.h:661
@ EmfPlusRecordTypeDrawRects
Definition: gdiplusenums.h:670
@ EmfPlusRecordTypeSetPageTransform
Definition: gdiplusenums.h:707
@ EmfPlusRecordTypeSetAntiAliasMode
Definition: gdiplusenums.h:689
@ EmfPlusRecordTypeBeginContainerNoParams
Definition: gdiplusenums.h:699
@ EmfPlusRecordTypeDrawImage
Definition: gdiplusenums.h:685
@ EmfPlusRecordTypeScaleWorldTransform
Definition: gdiplusenums.h:705
@ EmfPlusRecordTypeMultiplyWorldTransform
Definition: gdiplusenums.h:703
@ EmfPlusRecordTypeSetClipRegion
Definition: gdiplusenums.h:711
@ EmfPlusRecordTypeSetTextRenderingHint
Definition: gdiplusenums.h:690
EmfType
Definition: gdiplusenums.h:233
@ EmfTypeEmfPlusDual
Definition: gdiplusenums.h:236
@ 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:187
@ MatrixOrderAppend
Definition: gdiplusenums.h:189
@ MatrixOrderPrepend
Definition: gdiplusenums.h:188
@ PenAlignmentCenter
Definition: gdiplusenums.h:155
Unit
Definition: gdiplusenums.h:26
@ UnitDisplay
Definition: gdiplusenums.h:28
@ UnitPixel
Definition: gdiplusenums.h:29
MetafileType
Definition: gdiplusenums.h:215
@ MetafileTypeEmfPlusOnly
Definition: gdiplusenums.h:220
@ MetafileTypeWmf
Definition: gdiplusenums.h:217
@ MetafileTypeWmfPlaceable
Definition: gdiplusenums.h:218
@ MetafileTypeEmf
Definition: gdiplusenums.h:219
@ MetafileTypeEmfPlusDual
Definition: gdiplusenums.h:221
@ CoordinateSpaceDevice
Definition: gdiplusenums.h:369
@ CoordinateSpaceWorld
Definition: gdiplusenums.h:367
@ BrushTypeHatchFill
Definition: gdiplusenums.h:39
@ BrushTypeLinearGradient
Definition: gdiplusenums.h:42
@ BrushTypeTextureFill
Definition: gdiplusenums.h:40
@ BrushTypeSolidColor
Definition: gdiplusenums.h:38
MetafileFrameUnit
Definition: gdiplusenums.h:380
@ MetafileFrameUnitMillimeter
Definition: gdiplusenums.h:385
@ MetafileFrameUnitInch
Definition: gdiplusenums.h:383
@ MetafileFrameUnitPixel
Definition: gdiplusenums.h:381
@ MetafileFrameUnitPoint
Definition: gdiplusenums.h:382
@ MetafileFrameUnitGdi
Definition: gdiplusenums.h:386
@ MetafileFrameUnitDocument
Definition: gdiplusenums.h:384
#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:56
Status
Definition: gdiplustypes.h:25
@ Ok
Definition: gdiplustypes.h:26
@ ObjectBusy
Definition: gdiplustypes.h:30
@ InvalidParameter
Definition: gdiplustypes.h:28
@ OutOfMemory
Definition: gdiplustypes.h:29
@ NotImplemented
Definition: gdiplustypes.h:32
@ GenericError
Definition: gdiplustypes.h:27
BOOL(CALLBACK * EnumerateMetafileProc)(EmfPlusRecordType, UINT, UINT, const BYTE *, VOID *)
Definition: gdiplustypes.h:60
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
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
GLuint GLuint GLsizei count
Definition: gl.h:1545
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
GLsizeiptr size
Definition: glext.h:5919
GLuint GLenum GLenum transform
Definition: glext.h:9407
GLenum GLenum GLenum GLenum GLenum scale
Definition: glext.h:9032
GLuint buffer
Definition: glext.h:5915
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
GLfloat angle
Definition: glext.h:10853
GLenum GLsizei dataSize
Definition: glext.h:11123
GLuint GLfloat * val
Definition: glext.h:7180
GLuint GLdouble GLdouble GLint GLint order
Definition: glext.h:11194
GLuint64EXT * result
Definition: glext.h:11304
GLuint id
Definition: glext.h:5910
GLsizei const GLfloat * points
Definition: glext.h:8112
GLintptr offset
Definition: glext.h:5920
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
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
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
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define for
Definition: utility.h:88
HDC hdc
Definition: main.c:9
static HDC
Definition: imagelist.c:92
#define comment(fmt, arg1)
Definition: rebar.c:820
static IPrintDialogCallback callback
Definition: printdlg.c:326
static const WCHAR desc[]
Definition: protectdata.c:36
static char * dest
Definition: rtl.c:135
static const unsigned char metafile[]
Definition: olepicture.c:138
static float(__cdecl *square_half_float)(float x
static HPALETTE palette
Definition: clipboard.c:1345
#define min(a, b)
Definition: monoChain.cc:55
#define ceilf(x)
Definition: mymath.h:62
#define floorf(x)
Definition: mymath.h:65
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
short SHORT
Definition: pedump.c:59
png_const_structrp png_const_inforp int * unit
Definition: png.h:2159
#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
HRESULT hr
Definition: shlfolder.c:183
#define TRACE(s)
Definition: solgame.cpp:4
& rect
Definition: startmenu.cpp:1413
EmfPlusRecordHeader Header
Definition: metafile.c:134
DWORD Height
Definition: metafile.c:340
BYTE BitmapData[1]
Definition: metafile.c:344
DWORD Type
Definition: metafile.c:343
DWORD Stride
Definition: metafile.c:341
DWORD PixelFormat
Definition: metafile.c:342
DWORD Width
Definition: metafile.c:339
EmfPlusLinearGradientBrushData lineargradient
Definition: metafile.c:287
DWORD Type
Definition: metafile.c:282
EmfPlusTextureBrushData texture
Definition: metafile.c:286
EmfPlusSolidBrushData solid
Definition: metafile.c:284
union EmfPlusBrush::@417 BrushData
EmfPlusHatchBrushData hatch
Definition: metafile.c:285
DWORD Version
Definition: metafile.c:281
DWORD Color
Definition: metafile.c:70
EmfPlusRecordHeader Header
Definition: metafile.c:69
EmfPlusRecordHeader Header
Definition: metafile.c:142
EmfPlusRectF rectF
Definition: metafile.c:456
float SweepAngle
Definition: metafile.c:452
union EmfPlusDrawArc::@422 RectData
EmfPlusRecordHeader Header
Definition: metafile.c:450
EmfPlusRect rect
Definition: metafile.c:455
float StartAngle
Definition: metafile.c:451
EmfPlusRecordHeader Header
Definition: metafile.c:462
EmfPlusRect rect
Definition: metafile.c:465
EmfPlusRectF rectF
Definition: metafile.c:466
union EmfPlusDrawEllipse::@423 RectData
EmfPlusRectF SrcRect
Definition: metafile.c:432
union EmfPlusDrawImagePoints::@421 PointData
EmfPlusPointR7 pointsR[3]
Definition: metafile.c:436
EmfPlusPointF pointsF[3]
Definition: metafile.c:438
EmfPlusRecordHeader Header
Definition: metafile.c:429
EmfPlusPoint points[3]
Definition: metafile.c:437
DWORD ImageAttributesID
Definition: metafile.c:417
EmfPlusRect rect
Definition: metafile.c:422
union EmfPlusDrawImage::@420 RectData
EmfPlusRectF rectF
Definition: metafile.c:423
EmfPlusRecordHeader Header
Definition: metafile.c:416
EmfPlusRectF SrcRect
Definition: metafile.c:419
EmfPlusRecordHeader Header
Definition: metafile.c:444
float SweepAngle
Definition: metafile.c:474
EmfPlusRecordHeader Header
Definition: metafile.c:472
float StartAngle
Definition: metafile.c:473
EmfPlusRect rect
Definition: metafile.c:477
EmfPlusRectF rectF
Definition: metafile.c:478
union EmfPlusDrawPie::@424 RectData
union EmfPlusDrawRects::@425 RectData
EmfPlusRectF rectF[1]
Definition: metafile.c:489
EmfPlusRecordHeader Header
Definition: metafile.c:484
EmfPlusRect rect[1]
Definition: metafile.c:488
union EmfPlusFillClosedCurve::@427 PointData
EmfPlusPointF pointsF[1]
Definition: metafile.c:513
EmfPlusPointR7 pointsR[1]
Definition: metafile.c:511
EmfPlusRecordHeader Header
Definition: metafile.c:505
EmfPlusRecordHeader Header
Definition: metafile.c:519
EmfPlusRect rect
Definition: metafile.c:523
EmfPlusRectF rectF
Definition: metafile.c:524
union EmfPlusFillEllipse::@428 RectData
EmfPlusRecordHeader Header
Definition: metafile.c:495
EmfPlusARGB Color
Definition: metafile.c:499
union EmfPlusFillPath::@426 data
union EmfPlusFillPie::@429 RectData
float SweepAngle
Definition: metafile.c:533
EmfPlusRecordHeader Header
Definition: metafile.c:530
float StartAngle
Definition: metafile.c:532
EmfPlusRectF rectF
Definition: metafile.c:537
DWORD BrushId
Definition: metafile.c:531
EmfPlusRect rect
Definition: metafile.c:536
EmfPlusRecordHeader Header
Definition: metafile.c:75
DWORD Length
Definition: metafile.c:548
DWORD Version
Definition: metafile.c:543
DWORD Reserved
Definition: metafile.c:547
WCHAR FamilyName[1]
Definition: metafile.c:549
float EmSize
Definition: metafile.c:544
DWORD SizeUnit
Definition: metafile.c:545
DWORD FontStyleFlags
Definition: metafile.c:546
EmfPlusARGB ForeColor
Definition: metafile.c:248
EmfPlusARGB BackColor
Definition: metafile.c:249
DWORD Version
Definition: metafile.c:61
EmfPlusRecordHeader Header
Definition: metafile.c:60
DWORD LogicalDpiY
Definition: metafile.c:64
DWORD LogicalDpiX
Definition: metafile.c:63
DWORD EmfPlusFlags
Definition: metafile.c:62
EmfPlusARGB ClampColor
Definition: metafile.c:377
union EmfPlusImage::@418 ImageData
ImageDataType Type
Definition: metafile.c:364
EmfPlusMetafile metafile
Definition: metafile.c:368
DWORD Version
Definition: metafile.c:363
EmfPlusBitmap bitmap
Definition: metafile.c:367
DWORD MetafileDataSize
Definition: metafile.c:350
BYTE MetafileData[1]
Definition: metafile.c:351
EmfPlusRecordHeader Header
Definition: metafile.c:115
EmfPlusImage image
Definition: metafile.c:391
union EmfPlusObject::@419 ObjectData
EmfPlusRecordHeader Header
Definition: metafile.c:384
EmfPlusImageAttributes image_attributes
Definition: metafile.c:392
EmfPlusPen pen
Definition: metafile.c:388
EmfPlusBrush brush
Definition: metafile.c:387
EmfPlusPath path
Definition: metafile.c:389
EmfPlusRegion region
Definition: metafile.c:390
DWORD PaletteStyleFlags
Definition: metafile.c:326
DWORD PaletteCount
Definition: metafile.c:327
BYTE PaletteEntries[1]
Definition: metafile.c:328
DWORD PathPointCount
Definition: metafile.c:303
DWORD Version
Definition: metafile.c:302
DWORD PathPointFlags
Definition: metafile.c:304
DWORD PenDataFlags
Definition: metafile.c:222
DWORD PenUnit
Definition: metafile.c:223
BYTE OptionalData[1]
Definition: metafile.c:225
DWORD Type
Definition: metafile.c:294
DWORD Version
Definition: metafile.c:293
BYTE data[1]
Definition: metafile.c:297
float Width
Definition: metafile.c:263
float Height
Definition: metafile.c:264
SHORT Y
Definition: metafile.c:95
SHORT X
Definition: metafile.c:94
SHORT Height
Definition: metafile.c:97
SHORT Width
Definition: metafile.c:96
DWORD RegionNodePathLength
Definition: metafile.c:313
EmfPlusPath RegionNodePath
Definition: metafile.c:314
BYTE RegionNode[1]
Definition: metafile.c:321
DWORD Version
Definition: metafile.c:319
DWORD RegionNodeCount
Definition: metafile.c:320
EmfPlusRecordHeader Header
Definition: metafile.c:121
EmfPlusRecordHeader Header
Definition: metafile.c:108
EmfPlusRecordHeader Header
Definition: metafile.c:82
GpRectF ClipRect
Definition: metafile.c:83
EmfPlusRecordHeader Header
Definition: metafile.c:88
EmfPlusRecordHeader Header
Definition: metafile.c:102
EmfPlusARGB SolidColor
Definition: metafile.c:242
EmfPlusRecordHeader Header
Definition: metafile.c:127
GpBrushType bt
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]
XFORM gdiworldtransform
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:649
REAL X
Definition: gdiplustypes.h:648
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:664
REAL X
Definition: gdiplustypes.h:661
REAL Width
Definition: gdiplustypes.h:663
REAL Y
Definition: gdiplustypes.h:662
LONG cx
Definition: kdterminal.h:27
LONG cy
Definition: kdterminal.h:28
Definition: uimain.c:89
DWORD id
Definition: metafile.c:155
REAL page_scale
Definition: metafile.c:160
struct list entry
Definition: metafile.c:154
GpRegion * clip
Definition: metafile.c:161
GpUnit page_unit
Definition: metafile.c:159
enum container_type type
Definition: metafile.c:156
GpMatrix world_transform
Definition: metafile.c:158
GraphicsContainer state
Definition: metafile.c:157
Definition: emfdc.c:45
GpRegion * region
Definition: nis.h:10
EnumerateMetafileProc callback
Definition: metafile.c:3380
void * callback_data
Definition: metafile.c:3381
GpMetafile * metafile
Definition: metafile.c:3382
Definition: main.c:439
Definition: fci.c:127
Definition: list.h:15
Definition: send.c:48
Definition: stat.h:55
Definition: ps.c:97
Definition: parse.h:23
DWORD dParm[1]
Definition: wingdi.h:2352
LONG right
Definition: windef.h:308
LONG bottom
Definition: windef.h:309
LONG top
Definition: windef.h:307
LONG left
Definition: windef.h:306
Definition: cmds.c:130
#define max(a, b)
Definition: svc.c:63
static void buffer_size(GLcontext *ctx, GLuint *width, GLuint *height)
Definition: swimpl.c:888
#define LIST_ENTRY(type)
Definition: queue.h:175
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
unsigned char * LPBYTE
Definition: typedefs.h:53
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 ret
LONG_PTR LPARAM
Definition: windef.h:208
#define WINAPI
Definition: msvc.h:6
const char * description
Definition: directx.c:2497
BOOL WINAPI DeleteMetaFile(_In_ HMETAFILE)
#define EMR_SAVEDC
Definition: wingdi.h:107
#define EMR_SETWINDOWEXTEX
Definition: wingdi.h:83
UINT WINAPI GetEnhMetaFileBits(_In_ HENHMETAFILE hEMF, _In_ UINT nSize, _Out_writes_bytes_opt_(nSize) LPBYTE lpData)
#define EMR_SETVIEWPORTEXTEX
Definition: wingdi.h:85
#define PS_DASH
Definition: wingdi.h:587
#define HORZRES
Definition: wingdi.h:716
BOOL WINAPI DeleteEnhMetaFile(_In_opt_ HENHMETAFILE)
#define EMR_EXTSELECTCLIPRGN
Definition: wingdi.h:148
#define DT_RASDISPLAY
Definition: wingdi.h:708
int WINAPI GetDeviceCaps(_In_opt_ HDC, _In_ int)
int WINAPI SetGraphicsMode(_In_ HDC, _In_ int)
Definition: dc.c:1226
#define GM_ADVANCED
Definition: wingdi.h:865
HMETAFILE WINAPI GetMetaFileW(_In_ LPCWSTR)
#define EMR_RESTOREDC
Definition: wingdi.h:108
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)
HRGN WINAPI ExtCreateRegion(_In_opt_ const XFORM *lpx, _In_ DWORD nCount, _In_reads_bytes_(nCount) const RGNDATA *lpData)
#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)
#define EMR_SETWINDOWORGEX
Definition: wingdi.h:84
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)
#define EMR_SETVIEWPORTORGEX
Definition: wingdi.h:86
BOOL WINAPI SetWorldTransform(_In_ HDC, _In_ const XFORM *)
UINT WINAPI GetEnhMetaFileHeader(_In_ HENHMETAFILE hemf, _In_ UINT nSize, _Out_writes_bytes_opt_(nSize) LPENHMETAHEADER lpEnhMetaHeader)
BOOL WINAPI CombineTransform(_Out_ LPXFORM pxformResult, _In_ const XFORM *pxform1, _In_ const XFORM *pxform2)
Definition: coord.c:64
#define EMR_SETMAPMODE
Definition: wingdi.h:91
#define EMR_HEADER
Definition: wingdi.h:75
#define EMR_MODIFYWORLDTRANSFORM
Definition: wingdi.h:110
#define EMR_SCALEWINDOWEXTEX
Definition: wingdi.h:106
#define PS_SOLID
Definition: wingdi.h:586
#define EMR_SETWORLDTRANSFORM
Definition: wingdi.h:109
#define EMR_GDICOMMENT
Definition: wingdi.h:143
int WINAPI ExtSelectClipRgn(_In_ HDC, _In_opt_ HRGN, _In_ int)
#define TECHNOLOGY
Definition: wingdi.h:706
#define PS_DASHDOT
Definition: wingdi.h:589
#define EMR_SCALEVIEWPORTEXTEX
Definition: wingdi.h:105
#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:4466
__wchar_t WCHAR
Definition: xmlstorage.h:180
unsigned char BYTE
Definition: xxhash.c:193