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
d436e518
Commit
d436e518
authored
Apr 01, 2011
by
Vincent Povirk
Committed by
Alexandre Julliard
May 23, 2011
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
gdiplus: Add basic metafile recording support.
parent
4e26336e
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
370 additions
and
36 deletions
+370
-36
Makefile.in
dlls/gdiplus/Makefile.in
+1
-0
gdiplus_private.h
dlls/gdiplus/gdiplus_private.h
+10
-0
graphics.c
dlls/gdiplus/graphics.c
+13
-29
image.c
dlls/gdiplus/image.c
+3
-6
metafile.c
dlls/gdiplus/metafile.c
+324
-0
metafile.c
dlls/gdiplus/tests/metafile.c
+19
-1
No files found.
dlls/gdiplus/Makefile.in
View file @
d436e518
...
...
@@ -13,6 +13,7 @@ C_SRCS = \
image.c
\
imageattributes.c
\
matrix.c
\
metafile.c
\
pathiterator.c
\
pen.c
\
region.c
\
...
...
dlls/gdiplus/gdiplus_private.h
View file @
d436e518
...
...
@@ -51,6 +51,9 @@ extern REAL convert_unit(REAL logpixels, GpUnit unit) DECLSPEC_HIDDEN;
extern
GpStatus
graphics_from_image
(
GpImage
*
image
,
GpGraphics
**
graphics
)
DECLSPEC_HIDDEN
;
extern
GpStatus
METAFILE_GetGraphicsContext
(
GpMetafile
*
metafile
,
GpGraphics
**
result
)
DECLSPEC_HIDDEN
;
extern
GpStatus
METAFILE_GraphicsDeleted
(
GpMetafile
*
metafile
)
DECLSPEC_HIDDEN
;
extern
void
calc_curve_bezier
(
CONST
GpPointF
*
pts
,
REAL
tension
,
REAL
*
x1
,
REAL
*
y1
,
REAL
*
x2
,
REAL
*
y2
)
DECLSPEC_HIDDEN
;
extern
void
calc_curve_bezier_endp
(
REAL
xend
,
REAL
yend
,
REAL
xadj
,
REAL
yadj
,
...
...
@@ -268,6 +271,13 @@ struct GpMetafile{
GpImage
image
;
GpRectF
bounds
;
GpUnit
unit
;
MetafileType
metafile_type
;
HDC
record_dc
;
GpGraphics
*
record_graphics
;
BYTE
*
comment_data
;
DWORD
comment_data_size
;
DWORD
comment_data_length
;
HENHMETAFILE
hemf
;
};
struct
GpBitmap
{
...
...
dlls/gdiplus/graphics.c
View file @
d436e518
...
...
@@ -206,6 +206,11 @@ static GpStatus alpha_blend_pixels(GpGraphics *graphics, INT dst_x, INT dst_y,
return
Ok
;
}
else
if
(
graphics
->
image
&&
graphics
->
image
->
type
==
ImageTypeMetafile
)
{
ERR
(
"This should not be used for metafiles; fix caller
\n
"
);
return
NotImplemented
;
}
else
{
HDC
hdc
;
...
...
@@ -1967,11 +1972,19 @@ GpStatus WINGDIPAPI GdipCreateStreamOnFile(GDIPCONST WCHAR * filename,
GpStatus
WINGDIPAPI
GdipDeleteGraphics
(
GpGraphics
*
graphics
)
{
GraphicsContainerItem
*
cont
,
*
next
;
GpStatus
stat
;
TRACE
(
"(%p)
\n
"
,
graphics
);
if
(
!
graphics
)
return
InvalidParameter
;
if
(
graphics
->
busy
)
return
ObjectBusy
;
if
(
graphics
->
image
&&
graphics
->
image
->
type
==
ImageTypeMetafile
)
{
stat
=
METAFILE_GraphicsDeleted
((
GpMetafile
*
)
graphics
->
image
);
if
(
stat
!=
Ok
)
return
stat
;
}
if
(
graphics
->
owndc
)
ReleaseDC
(
graphics
->
hwnd
,
graphics
->
hdc
);
...
...
@@ -5873,23 +5886,6 @@ GpStatus WINGDIPAPI GdipDrawDriverString(GpGraphics *graphics, GDIPCONST UINT16
return
stat
;
}
GpStatus
WINGDIPAPI
GdipRecordMetafile
(
HDC
hdc
,
EmfType
type
,
GDIPCONST
GpRectF
*
frameRect
,
MetafileFrameUnit
frameUnit
,
GDIPCONST
WCHAR
*
desc
,
GpMetafile
**
metafile
)
{
FIXME
(
"(%p %d %p %d %p %p): stub
\n
"
,
hdc
,
type
,
frameRect
,
frameUnit
,
desc
,
metafile
);
return
NotImplemented
;
}
/*****************************************************************************
* GdipRecordMetafileI [GDIPLUS.@]
*/
GpStatus
WINGDIPAPI
GdipRecordMetafileI
(
HDC
hdc
,
EmfType
type
,
GDIPCONST
GpRect
*
frameRect
,
MetafileFrameUnit
frameUnit
,
GDIPCONST
WCHAR
*
desc
,
GpMetafile
**
metafile
)
{
FIXME
(
"(%p %d %p %d %p %p): stub
\n
"
,
hdc
,
type
,
frameRect
,
frameUnit
,
desc
,
metafile
);
return
NotImplemented
;
}
GpStatus
WINGDIPAPI
GdipRecordMetafileStream
(
IStream
*
stream
,
HDC
hdc
,
EmfType
type
,
GDIPCONST
GpRect
*
frameRect
,
MetafileFrameUnit
frameUnit
,
GDIPCONST
WCHAR
*
desc
,
GpMetafile
**
metafile
)
{
...
...
@@ -5919,15 +5915,3 @@ cleanup:
GdipDeleteRegion
(
rgn
);
return
stat
;
}
GpStatus
WINGDIPAPI
GdipGetHemfFromMetafile
(
GpMetafile
*
metafile
,
HENHMETAFILE
*
hEmf
)
{
FIXME
(
"(%p,%p): stub
\n
"
,
metafile
,
hEmf
);
if
(
!
metafile
||
!
hEmf
)
return
InvalidParameter
;
*
hEmf
=
NULL
;
return
NotImplemented
;
}
dlls/gdiplus/image.c
View file @
d436e518
...
...
@@ -2143,12 +2143,7 @@ GpStatus WINGDIPAPI GdipGetImageGraphicsContext(GpImage *image,
if
(
!
image
||
!
graphics
)
return
InvalidParameter
;
if
(
image
->
type
!=
ImageTypeBitmap
){
FIXME
(
"not implemented for image type %d
\n
"
,
image
->
type
);
return
NotImplemented
;
}
if
(((
GpBitmap
*
)
image
)
->
hbitmap
)
if
(
image
->
type
==
ImageTypeBitmap
&&
((
GpBitmap
*
)
image
)
->
hbitmap
)
{
hdc
=
((
GpBitmap
*
)
image
)
->
hdc
;
...
...
@@ -2163,6 +2158,8 @@ GpStatus WINGDIPAPI GdipGetImageGraphicsContext(GpImage *image,
if
(
stat
==
Ok
)
(
*
graphics
)
->
image
=
image
;
}
else
if
(
image
->
type
==
ImageTypeMetafile
)
stat
=
METAFILE_GetGraphicsContext
((
GpMetafile
*
)
image
,
graphics
);
else
stat
=
graphics_from_image
(
image
,
graphics
);
...
...
dlls/gdiplus/metafile.c
0 → 100644
View file @
d436e518
/*
* Copyright (C) 2011 Vincent Povirk for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#include <math.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "wine/unicode.h"
#define COBJMACROS
#include "objbase.h"
#include "ocidl.h"
#include "olectl.h"
#include "ole2.h"
#include "winreg.h"
#include "shlwapi.h"
#include "gdiplus.h"
#include "gdiplus_private.h"
#include "wine/debug.h"
#include "wine/list.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
gdiplus
);
typedef
struct
EmfPlusRecordHeader
{
WORD
Type
;
WORD
Flags
;
DWORD
Size
;
DWORD
DataSize
;
}
EmfPlusRecordHeader
;
typedef
struct
EmfPlusHeader
{
EmfPlusRecordHeader
Header
;
DWORD
Version
;
DWORD
EmfPlusFlags
;
DWORD
LogicalDpiX
;
DWORD
LogicalDpiY
;
}
EmfPlusHeader
;
static
GpStatus
METAFILE_AllocateRecord
(
GpMetafile
*
metafile
,
DWORD
size
,
void
**
result
)
{
DWORD
size_needed
;
EmfPlusRecordHeader
*
record
;
if
(
!
metafile
->
comment_data_size
)
{
DWORD
data_size
=
max
(
256
,
size
*
2
+
4
);
metafile
->
comment_data
=
GdipAlloc
(
data_size
);
if
(
!
metafile
->
comment_data
)
return
OutOfMemory
;
memcpy
(
metafile
->
comment_data
,
"EMF+"
,
4
);
metafile
->
comment_data_size
=
data_size
;
metafile
->
comment_data_length
=
4
;
}
size_needed
=
size
+
metafile
->
comment_data_length
;
if
(
size_needed
>
metafile
->
comment_data_size
)
{
DWORD
data_size
=
size_needed
*
2
;
BYTE
*
new_data
=
GdipAlloc
(
data_size
);
if
(
!
new_data
)
return
OutOfMemory
;
memcpy
(
new_data
,
metafile
->
comment_data
,
metafile
->
comment_data_length
);
metafile
->
comment_data_size
=
data_size
;
GdipFree
(
metafile
->
comment_data
);
metafile
->
comment_data
=
new_data
;
}
*
result
=
metafile
->
comment_data
+
metafile
->
comment_data_length
;
metafile
->
comment_data_length
+=
size
;
record
=
(
EmfPlusRecordHeader
*
)
*
result
;
record
->
Size
=
size
;
record
->
DataSize
=
size
-
sizeof
(
EmfPlusRecordHeader
);
return
Ok
;
}
static
void
METAFILE_WriteRecords
(
GpMetafile
*
metafile
)
{
if
(
metafile
->
comment_data_length
>
4
)
{
GdiComment
(
metafile
->
record_dc
,
metafile
->
comment_data_length
,
metafile
->
comment_data
);
metafile
->
comment_data_length
=
4
;
}
}
static
GpStatus
METAFILE_WriteHeader
(
GpMetafile
*
metafile
,
HDC
hdc
)
{
GpStatus
stat
;
if
(
metafile
->
metafile_type
==
MetafileTypeEmfPlusOnly
||
metafile
->
metafile_type
==
MetafileTypeEmfPlusDual
)
{
EmfPlusHeader
*
header
;
stat
=
METAFILE_AllocateRecord
(
metafile
,
sizeof
(
EmfPlusHeader
),
(
void
**
)
&
header
);
if
(
stat
!=
Ok
)
return
stat
;
header
->
Header
.
Type
=
EmfPlusRecordTypeHeader
;
if
(
metafile
->
metafile_type
==
MetafileTypeEmfPlusDual
)
header
->
Header
.
Flags
=
1
;
else
header
->
Header
.
Flags
=
0
;
header
->
Version
=
0xDBC01002
;
if
(
GetDeviceCaps
(
hdc
,
TECHNOLOGY
)
==
DT_RASDISPLAY
)
header
->
EmfPlusFlags
=
1
;
else
header
->
EmfPlusFlags
=
0
;
header
->
LogicalDpiX
=
GetDeviceCaps
(
hdc
,
LOGPIXELSX
);
header
->
LogicalDpiY
=
GetDeviceCaps
(
hdc
,
LOGPIXELSY
);
METAFILE_WriteRecords
(
metafile
);
}
return
Ok
;
}
static
GpStatus
METAFILE_WriteEndOfFile
(
GpMetafile
*
metafile
)
{
GpStatus
stat
;
if
(
metafile
->
metafile_type
==
MetafileTypeEmfPlusOnly
||
metafile
->
metafile_type
==
MetafileTypeEmfPlusDual
)
{
EmfPlusRecordHeader
*
record
;
stat
=
METAFILE_AllocateRecord
(
metafile
,
sizeof
(
EmfPlusRecordHeader
),
(
void
**
)
&
record
);
if
(
stat
!=
Ok
)
return
stat
;
record
->
Type
=
EmfPlusRecordTypeEndOfFile
;
record
->
Flags
=
0
;
METAFILE_WriteRecords
(
metafile
);
}
return
Ok
;
}
GpStatus
WINGDIPAPI
GdipRecordMetafile
(
HDC
hdc
,
EmfType
type
,
GDIPCONST
GpRectF
*
frameRect
,
MetafileFrameUnit
frameUnit
,
GDIPCONST
WCHAR
*
desc
,
GpMetafile
**
metafile
)
{
HDC
record_dc
;
REAL
framerect_factor_x
,
framerect_factor_y
;
RECT
rc
;
GpStatus
stat
;
TRACE
(
"(%p %d %p %d %p %p)
\n
"
,
hdc
,
type
,
frameRect
,
frameUnit
,
desc
,
metafile
);
if
(
!
hdc
||
type
<
EmfTypeEmfOnly
||
type
>
EmfTypeEmfPlusDual
||
!
metafile
)
return
InvalidParameter
;
if
(
!
frameRect
)
{
FIXME
(
"not implemented for NULL rect
\n
"
);
return
NotImplemented
;
}
switch
(
frameUnit
)
{
case
MetafileFrameUnitPixel
:
framerect_factor_x
=
2540
.
0
/
GetDeviceCaps
(
hdc
,
LOGPIXELSX
);
framerect_factor_y
=
2540
.
0
/
GetDeviceCaps
(
hdc
,
LOGPIXELSY
);
break
;
case
MetafileFrameUnitPoint
:
framerect_factor_x
=
framerect_factor_y
=
2540
.
0
/
72
.
0
;
break
;
case
MetafileFrameUnitInch
:
framerect_factor_x
=
framerect_factor_y
=
2540
.
0
;
break
;
case
MetafileFrameUnitDocument
:
framerect_factor_x
=
framerect_factor_y
=
2540
.
0
/
300
.
0
;
break
;
case
MetafileFrameUnitMillimeter
:
framerect_factor_x
=
framerect_factor_y
=
100
.
0
;
break
;
case
MetafileFrameUnitGdi
:
framerect_factor_x
=
framerect_factor_y
=
1
.
0
;
break
;
default:
return
InvalidParameter
;
}
rc
.
left
=
framerect_factor_x
*
frameRect
->
X
;
rc
.
top
=
framerect_factor_y
*
frameRect
->
Y
;
rc
.
right
=
rc
.
left
+
framerect_factor_x
*
frameRect
->
Width
;
rc
.
bottom
=
rc
.
top
+
framerect_factor_y
*
frameRect
->
Height
;
record_dc
=
CreateEnhMetaFileW
(
hdc
,
NULL
,
&
rc
,
desc
);
if
(
!
record_dc
)
return
GenericError
;
*
metafile
=
GdipAlloc
(
sizeof
(
GpMetafile
));
if
(
!*
metafile
)
{
DeleteEnhMetaFile
(
CloseEnhMetaFile
(
record_dc
));
return
OutOfMemory
;
}
(
*
metafile
)
->
image
.
type
=
ImageTypeMetafile
;
(
*
metafile
)
->
image
.
picture
=
NULL
;
(
*
metafile
)
->
image
.
flags
=
ImageFlagsNone
;
(
*
metafile
)
->
image
.
palette_flags
=
0
;
(
*
metafile
)
->
image
.
palette_count
=
0
;
(
*
metafile
)
->
image
.
palette_size
=
0
;
(
*
metafile
)
->
image
.
palette_entries
=
NULL
;
(
*
metafile
)
->
bounds
=
*
frameRect
;
(
*
metafile
)
->
unit
=
frameUnit
;
(
*
metafile
)
->
metafile_type
=
type
;
(
*
metafile
)
->
record_dc
=
record_dc
;
(
*
metafile
)
->
comment_data
=
NULL
;
(
*
metafile
)
->
comment_data_size
=
0
;
(
*
metafile
)
->
comment_data_length
=
0
;
(
*
metafile
)
->
hemf
=
NULL
;
stat
=
METAFILE_WriteHeader
(
*
metafile
,
hdc
);
if
(
stat
!=
Ok
)
{
DeleteEnhMetaFile
(
CloseEnhMetaFile
(
record_dc
));
GdipFree
(
*
metafile
);
*
metafile
=
NULL
;
return
OutOfMemory
;
}
return
stat
;
}
/*****************************************************************************
* GdipRecordMetafileI [GDIPLUS.@]
*/
GpStatus
WINGDIPAPI
GdipRecordMetafileI
(
HDC
hdc
,
EmfType
type
,
GDIPCONST
GpRect
*
frameRect
,
MetafileFrameUnit
frameUnit
,
GDIPCONST
WCHAR
*
desc
,
GpMetafile
**
metafile
)
{
GpRectF
frameRectF
,
*
pFrameRectF
;
TRACE
(
"(%p %d %p %d %p %p)
\n
"
,
hdc
,
type
,
frameRect
,
frameUnit
,
desc
,
metafile
);
if
(
frameRect
)
{
frameRectF
.
X
=
frameRect
->
X
;
frameRectF
.
Y
=
frameRect
->
Y
;
frameRectF
.
Width
=
frameRect
->
Width
;
frameRectF
.
Height
=
frameRect
->
Height
;
pFrameRectF
=
&
frameRectF
;
}
else
pFrameRectF
=
NULL
;
return
GdipRecordMetafile
(
hdc
,
type
,
pFrameRectF
,
frameUnit
,
desc
,
metafile
);
}
GpStatus
METAFILE_GetGraphicsContext
(
GpMetafile
*
metafile
,
GpGraphics
**
result
)
{
GpStatus
stat
;
if
(
!
metafile
->
record_dc
||
metafile
->
record_graphics
)
return
InvalidParameter
;
stat
=
graphics_from_image
((
GpImage
*
)
metafile
,
&
metafile
->
record_graphics
);
if
(
stat
==
Ok
)
*
result
=
metafile
->
record_graphics
;
return
stat
;
}
GpStatus
METAFILE_GraphicsDeleted
(
GpMetafile
*
metafile
)
{
GpStatus
stat
;
stat
=
METAFILE_WriteEndOfFile
(
metafile
);
metafile
->
record_graphics
=
NULL
;
metafile
->
hemf
=
CloseEnhMetaFile
(
metafile
->
record_dc
);
metafile
->
record_dc
=
NULL
;
return
stat
;
}
GpStatus
WINGDIPAPI
GdipGetHemfFromMetafile
(
GpMetafile
*
metafile
,
HENHMETAFILE
*
hEmf
)
{
TRACE
(
"(%p,%p)
\n
"
,
metafile
,
hEmf
);
if
(
!
metafile
||
!
hEmf
||
!
metafile
->
hemf
)
return
InvalidParameter
;
*
hEmf
=
metafile
->
hemf
;
metafile
->
hemf
=
NULL
;
return
Ok
;
}
dlls/gdiplus/tests/metafile.c
View file @
d436e518
...
...
@@ -161,8 +161,26 @@ static void test_empty(void)
hdc
=
CreateCompatibleDC
(
0
);
stat
=
GdipRecordMetafile
(
NULL
,
EmfTypeEmfPlusOnly
,
&
frame
,
MetafileFrameUnitPixel
,
description
,
&
metafile
);
expect
(
InvalidParameter
,
stat
);
stat
=
GdipRecordMetafile
(
hdc
,
MetafileTypeInvalid
,
&
frame
,
MetafileFrameUnitPixel
,
description
,
&
metafile
);
expect
(
InvalidParameter
,
stat
);
stat
=
GdipRecordMetafile
(
hdc
,
MetafileTypeWmf
,
&
frame
,
MetafileFrameUnitPixel
,
description
,
&
metafile
);
expect
(
InvalidParameter
,
stat
);
stat
=
GdipRecordMetafile
(
hdc
,
MetafileTypeWmfPlaceable
,
&
frame
,
MetafileFrameUnitPixel
,
description
,
&
metafile
);
expect
(
InvalidParameter
,
stat
);
stat
=
GdipRecordMetafile
(
hdc
,
MetafileTypeEmfPlusDual
+
1
,
&
frame
,
MetafileFrameUnitPixel
,
description
,
&
metafile
);
expect
(
InvalidParameter
,
stat
);
stat
=
GdipRecordMetafile
(
hdc
,
EmfTypeEmfPlusOnly
,
&
frame
,
MetafileFrameUnitPixel
,
description
,
NULL
);
expect
(
InvalidParameter
,
stat
);
stat
=
GdipRecordMetafile
(
hdc
,
EmfTypeEmfPlusOnly
,
&
frame
,
MetafileFrameUnitPixel
,
description
,
&
metafile
);
todo_wine
expect
(
Ok
,
stat
);
expect
(
Ok
,
stat
);
DeleteDC
(
hdc
);
...
...
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