Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
f28803c0
Commit
f28803c0
authored
Aug 15, 2016
by
Vincent Povirk
Committed by
Alexandre Julliard
Aug 16, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
gdiplus: Add support for containers in metafiles.
Signed-off-by:
Vincent Povirk
<
vincent@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
c90e46b6
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
225 additions
and
0 deletions
+225
-0
gdiplus_private.h
dlls/gdiplus/gdiplus_private.h
+5
-0
graphics.c
dlls/gdiplus/graphics.c
+14
-0
image.c
dlls/gdiplus/image.c
+1
-0
metafile.c
dlls/gdiplus/metafile.c
+205
-0
No files found.
dlls/gdiplus/gdiplus_private.h
View file @
f28803c0
...
...
@@ -96,6 +96,10 @@ extern GpStatus METAFILE_MultiplyWorldTransform(GpMetafile* metafile, GDIPCONST
extern
GpStatus
METAFILE_RotateWorldTransform
(
GpMetafile
*
metafile
,
REAL
angle
,
MatrixOrder
order
)
DECLSPEC_HIDDEN
;
extern
GpStatus
METAFILE_TranslateWorldTransform
(
GpMetafile
*
metafile
,
REAL
dx
,
REAL
dy
,
MatrixOrder
order
)
DECLSPEC_HIDDEN
;
extern
GpStatus
METAFILE_ResetWorldTransform
(
GpMetafile
*
metafile
)
DECLSPEC_HIDDEN
;
extern
GpStatus
METAFILE_BeginContainerNoParams
(
GpMetafile
*
metafile
,
DWORD
StackIndex
)
DECLSPEC_HIDDEN
;
extern
GpStatus
METAFILE_EndContainer
(
GpMetafile
*
metafile
,
DWORD
StackIndex
)
DECLSPEC_HIDDEN
;
extern
GpStatus
METAFILE_SaveGraphics
(
GpMetafile
*
metafile
,
DWORD
StackIndex
)
DECLSPEC_HIDDEN
;
extern
GpStatus
METAFILE_RestoreGraphics
(
GpMetafile
*
metafile
,
DWORD
StackIndex
)
DECLSPEC_HIDDEN
;
extern
GpStatus
METAFILE_GraphicsDeleted
(
GpMetafile
*
metafile
)
DECLSPEC_HIDDEN
;
extern
void
calc_curve_bezier
(
const
GpPointF
*
pts
,
REAL
tension
,
REAL
*
x1
,
...
...
@@ -368,6 +372,7 @@ struct GpMetafile{
GpUnit
page_unit
;
REAL
page_scale
;
GpRegion
*
base_clip
;
/* clip region in device space for all metafile output */
struct
list
containers
;
};
struct
GpBitmap
{
...
...
dlls/gdiplus/graphics.c
View file @
f28803c0
...
...
@@ -5194,6 +5194,13 @@ static GpStatus begin_container(GpGraphics *graphics,
list_add_head
(
&
graphics
->
containers
,
&
container
->
entry
);
*
state
=
graphics
->
contid
=
container
->
contid
;
if
(
graphics
->
image
&&
graphics
->
image
->
type
==
ImageTypeMetafile
)
{
if
(
type
==
BEGIN_CONTAINER
)
METAFILE_BeginContainerNoParams
((
GpMetafile
*
)
graphics
->
image
,
container
->
contid
);
else
METAFILE_SaveGraphics
((
GpMetafile
*
)
graphics
->
image
,
container
->
contid
);
}
return
Ok
;
}
...
...
@@ -5261,6 +5268,13 @@ static GpStatus end_container(GpGraphics *graphics, GraphicsContainerType type,
list_remove
(
&
container
->
entry
);
delete_container
(
container
);
if
(
graphics
->
image
&&
graphics
->
image
->
type
==
ImageTypeMetafile
)
{
if
(
type
==
BEGIN_CONTAINER
)
METAFILE_EndContainer
((
GpMetafile
*
)
graphics
->
image
,
state
);
else
METAFILE_RestoreGraphics
((
GpMetafile
*
)
graphics
->
image
,
state
);
}
return
Ok
;
}
...
...
dlls/gdiplus/image.c
View file @
f28803c0
...
...
@@ -4062,6 +4062,7 @@ static GpStatus decode_image_olepicture_metafile(IStream* stream, GpImage **imag
(
*
image
)
->
frame_count
=
1
;
(
*
image
)
->
current_frame
=
0
;
(
*
image
)
->
palette
=
NULL
;
list_init
(
&
(
*
(
GpMetafile
**
)
image
)
->
containers
);
TRACE
(
"<-- %p
\n
"
,
*
image
);
...
...
dlls/gdiplus/metafile.c
View file @
f28803c0
...
...
@@ -116,6 +116,29 @@ typedef struct EmfPlusTranslateWorldTransform
REAL
dy
;
}
EmfPlusTranslateWorldTransform
;
typedef
struct
EmfPlusContainerRecord
{
EmfPlusRecordHeader
Header
;
DWORD
StackIndex
;
}
EmfPlusContainerRecord
;
enum
container_type
{
BEGIN_CONTAINER
,
SAVE_GRAPHICS
};
typedef
struct
container
{
struct
list
entry
;
DWORD
id
;
enum
container_type
type
;
GraphicsContainer
state
;
GpMatrix
world_transform
;
GpUnit
page_unit
;
REAL
page_scale
;
}
container
;
static
GpStatus
METAFILE_AllocateRecord
(
GpMetafile
*
metafile
,
DWORD
size
,
void
**
result
)
{
DWORD
size_needed
;
...
...
@@ -308,6 +331,7 @@ GpStatus WINGDIPAPI GdipRecordMetafile(HDC hdc, EmfType type, GDIPCONST GpRectF
(
*
metafile
)
->
comment_data_size
=
0
;
(
*
metafile
)
->
comment_data_length
=
0
;
(
*
metafile
)
->
hemf
=
NULL
;
list_init
(
&
(
*
metafile
)
->
containers
);
if
(
!
frameRect
)
{
...
...
@@ -726,6 +750,98 @@ GpStatus METAFILE_ResetWorldTransform(GpMetafile* metafile)
return
Ok
;
}
GpStatus
METAFILE_BeginContainerNoParams
(
GpMetafile
*
metafile
,
DWORD
StackIndex
)
{
if
(
metafile
->
metafile_type
==
MetafileTypeEmfPlusOnly
||
metafile
->
metafile_type
==
MetafileTypeEmfPlusDual
)
{
EmfPlusContainerRecord
*
record
;
GpStatus
stat
;
stat
=
METAFILE_AllocateRecord
(
metafile
,
sizeof
(
EmfPlusContainerRecord
),
(
void
**
)
&
record
);
if
(
stat
!=
Ok
)
return
stat
;
record
->
Header
.
Type
=
EmfPlusRecordTypeBeginContainerNoParams
;
record
->
Header
.
Flags
=
0
;
record
->
StackIndex
=
StackIndex
;
METAFILE_WriteRecords
(
metafile
);
}
return
Ok
;
}
GpStatus
METAFILE_EndContainer
(
GpMetafile
*
metafile
,
DWORD
StackIndex
)
{
if
(
metafile
->
metafile_type
==
MetafileTypeEmfPlusOnly
||
metafile
->
metafile_type
==
MetafileTypeEmfPlusDual
)
{
EmfPlusContainerRecord
*
record
;
GpStatus
stat
;
stat
=
METAFILE_AllocateRecord
(
metafile
,
sizeof
(
EmfPlusContainerRecord
),
(
void
**
)
&
record
);
if
(
stat
!=
Ok
)
return
stat
;
record
->
Header
.
Type
=
EmfPlusRecordTypeEndContainer
;
record
->
Header
.
Flags
=
0
;
record
->
StackIndex
=
StackIndex
;
METAFILE_WriteRecords
(
metafile
);
}
return
Ok
;
}
GpStatus
METAFILE_SaveGraphics
(
GpMetafile
*
metafile
,
DWORD
StackIndex
)
{
if
(
metafile
->
metafile_type
==
MetafileTypeEmfPlusOnly
||
metafile
->
metafile_type
==
MetafileTypeEmfPlusDual
)
{
EmfPlusContainerRecord
*
record
;
GpStatus
stat
;
stat
=
METAFILE_AllocateRecord
(
metafile
,
sizeof
(
EmfPlusContainerRecord
),
(
void
**
)
&
record
);
if
(
stat
!=
Ok
)
return
stat
;
record
->
Header
.
Type
=
EmfPlusRecordTypeSave
;
record
->
Header
.
Flags
=
0
;
record
->
StackIndex
=
StackIndex
;
METAFILE_WriteRecords
(
metafile
);
}
return
Ok
;
}
GpStatus
METAFILE_RestoreGraphics
(
GpMetafile
*
metafile
,
DWORD
StackIndex
)
{
if
(
metafile
->
metafile_type
==
MetafileTypeEmfPlusOnly
||
metafile
->
metafile_type
==
MetafileTypeEmfPlusDual
)
{
EmfPlusContainerRecord
*
record
;
GpStatus
stat
;
stat
=
METAFILE_AllocateRecord
(
metafile
,
sizeof
(
EmfPlusContainerRecord
),
(
void
**
)
&
record
);
if
(
stat
!=
Ok
)
return
stat
;
record
->
Header
.
Type
=
EmfPlusRecordTypeRestore
;
record
->
Header
.
Flags
=
0
;
record
->
StackIndex
=
StackIndex
;
METAFILE_WriteRecords
(
metafile
);
}
return
Ok
;
}
GpStatus
METAFILE_ReleaseDC
(
GpMetafile
*
metafile
,
HDC
hdc
)
{
if
(
hdc
!=
metafile
->
record_dc
)
...
...
@@ -1131,6 +1247,87 @@ GpStatus WINGDIPAPI GdipPlayMetafileRecord(GDIPCONST GpMetafile *metafile,
return
METAFILE_PlaybackUpdateWorldTransform
(
real_metafile
);
}
case
EmfPlusRecordTypeBeginContainerNoParams
:
case
EmfPlusRecordTypeSave
:
{
EmfPlusContainerRecord
*
record
=
(
EmfPlusContainerRecord
*
)
header
;
container
*
cont
;
cont
=
heap_alloc_zero
(
sizeof
(
*
cont
));
if
(
!
cont
)
return
OutOfMemory
;
if
(
recordType
==
EmfPlusRecordTypeBeginContainerNoParams
)
stat
=
GdipBeginContainer2
(
metafile
->
playback_graphics
,
&
cont
->
state
);
else
stat
=
GdipSaveGraphics
(
metafile
->
playback_graphics
,
&
cont
->
state
);
if
(
stat
!=
Ok
)
{
heap_free
(
cont
);
return
stat
;
}
cont
->
id
=
record
->
StackIndex
;
if
(
recordType
==
EmfPlusRecordTypeBeginContainerNoParams
)
cont
->
type
=
BEGIN_CONTAINER
;
else
cont
->
type
=
SAVE_GRAPHICS
;
cont
->
world_transform
=
*
metafile
->
world_transform
;
cont
->
page_unit
=
metafile
->
page_unit
;
cont
->
page_scale
=
metafile
->
page_scale
;
list_add_head
(
&
real_metafile
->
containers
,
&
cont
->
entry
);
break
;
}
case
EmfPlusRecordTypeEndContainer
:
case
EmfPlusRecordTypeRestore
:
{
EmfPlusContainerRecord
*
record
=
(
EmfPlusContainerRecord
*
)
header
;
container
*
cont
;
enum
container_type
type
;
BOOL
found
=
FALSE
;
if
(
recordType
==
EmfPlusRecordTypeEndContainer
)
type
=
BEGIN_CONTAINER
;
else
type
=
SAVE_GRAPHICS
;
LIST_FOR_EACH_ENTRY
(
cont
,
&
real_metafile
->
containers
,
container
,
entry
)
{
if
(
cont
->
id
==
record
->
StackIndex
&&
cont
->
type
==
type
)
{
found
=
TRUE
;
break
;
}
}
if
(
found
)
{
container
*
cont2
;
/* pop any newer items on the stack */
while
((
cont2
=
LIST_ENTRY
(
list_head
(
&
real_metafile
->
containers
),
container
,
entry
))
!=
cont
)
{
list_remove
(
&
cont2
->
entry
);
heap_free
(
cont2
);
}
if
(
type
==
BEGIN_CONTAINER
)
GdipEndContainer
(
real_metafile
->
playback_graphics
,
cont
->
state
);
else
GdipRestoreGraphics
(
real_metafile
->
playback_graphics
,
cont
->
state
);
*
real_metafile
->
world_transform
=
cont
->
world_transform
;
real_metafile
->
page_unit
=
cont
->
page_unit
;
real_metafile
->
page_scale
=
cont
->
page_scale
;
list_remove
(
&
cont
->
entry
);
heap_free
(
cont
);
}
break
;
}
default:
FIXME
(
"Not implemented for record type %x
\n
"
,
recordType
);
return
NotImplemented
;
...
...
@@ -1309,6 +1506,13 @@ GpStatus WINGDIPAPI GdipEnumerateMetafileSrcRectDestPoints(GpGraphics *graphics,
GdipDeleteRegion
(
real_metafile
->
base_clip
);
real_metafile
->
base_clip
=
NULL
;
while
(
list_head
(
&
real_metafile
->
containers
))
{
container
*
cont
=
LIST_ENTRY
(
list_head
(
&
real_metafile
->
containers
),
container
,
entry
);
list_remove
(
&
cont
->
entry
);
heap_free
(
cont
);
}
GdipEndContainer
(
graphics
,
state
);
}
...
...
@@ -1553,6 +1757,7 @@ GpStatus WINGDIPAPI GdipCreateMetafileFromEmf(HENHMETAFILE hemf, BOOL delete,
(
*
metafile
)
->
metafile_type
=
header
.
Type
;
(
*
metafile
)
->
hemf
=
hemf
;
(
*
metafile
)
->
preserve_hemf
=
!
delete
;
list_init
(
&
(
*
metafile
)
->
containers
);
TRACE
(
"<-- %p
\n
"
,
*
metafile
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment