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
b51d9e2c
Commit
b51d9e2c
authored
Apr 13, 2023
by
Piotr Caban
Committed by
Alexandre Julliard
Apr 13, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
wineps: Handle EMR_GRADIENTFILL record in spool files.
parent
d0e48343
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
133 additions
and
0 deletions
+133
-0
printproc.c
dlls/wineps.drv/printproc.c
+133
-0
No files found.
dlls/wineps.drv/printproc.c
View file @
b51d9e2c
...
...
@@ -800,6 +800,132 @@ static int poly_draw(PHYSDEV dev, const POINT *points, const BYTE *types, DWORD
return
TRUE
;
}
static
inline
void
reset_bounds
(
RECT
*
bounds
)
{
bounds
->
left
=
bounds
->
top
=
INT_MAX
;
bounds
->
right
=
bounds
->
bottom
=
INT_MIN
;
}
static
BOOL
gradient_fill
(
PHYSDEV
dev
,
const
TRIVERTEX
*
vert_array
,
DWORD
nvert
,
const
void
*
grad_array
,
DWORD
ngrad
,
ULONG
mode
)
{
char
buffer
[
FIELD_OFFSET
(
BITMAPINFO
,
bmiColors
[
256
])];
BITMAPINFO
*
info
=
(
BITMAPINFO
*
)
buffer
;
struct
bitblt_coords
src
,
dst
;
struct
gdi_image_bits
bits
;
HBITMAP
bmp
,
old_bmp
;
BOOL
ret
=
FALSE
;
TRIVERTEX
*
pts
;
unsigned
int
i
;
HDC
hdc_src
;
HRGN
rgn
;
if
(
!
(
pts
=
malloc
(
nvert
*
sizeof
(
*
pts
))))
return
FALSE
;
memcpy
(
pts
,
vert_array
,
sizeof
(
*
pts
)
*
nvert
);
for
(
i
=
0
;
i
<
nvert
;
i
++
)
LPtoDP
(
dev
->
hdc
,
(
POINT
*
)
&
pts
[
i
],
1
);
/* compute bounding rect of all the rectangles/triangles */
reset_bounds
(
&
dst
.
visrect
);
for
(
i
=
0
;
i
<
ngrad
*
(
mode
==
GRADIENT_FILL_TRIANGLE
?
3
:
2
);
i
++
)
{
ULONG
v
=
((
ULONG
*
)
grad_array
)[
i
];
dst
.
visrect
.
left
=
min
(
dst
.
visrect
.
left
,
pts
[
v
].
x
);
dst
.
visrect
.
top
=
min
(
dst
.
visrect
.
top
,
pts
[
v
].
y
);
dst
.
visrect
.
right
=
max
(
dst
.
visrect
.
right
,
pts
[
v
].
x
);
dst
.
visrect
.
bottom
=
max
(
dst
.
visrect
.
bottom
,
pts
[
v
].
y
);
}
dst
.
x
=
dst
.
visrect
.
left
;
dst
.
y
=
dst
.
visrect
.
top
;
dst
.
width
=
dst
.
visrect
.
right
-
dst
.
visrect
.
left
;
dst
.
height
=
dst
.
visrect
.
bottom
-
dst
.
visrect
.
top
;
clip_visrect
(
dev
->
hdc
,
&
dst
.
visrect
,
&
dst
.
visrect
);
info
->
bmiHeader
.
biSize
=
sizeof
(
info
->
bmiHeader
);
info
->
bmiHeader
.
biPlanes
=
1
;
info
->
bmiHeader
.
biBitCount
=
24
;
info
->
bmiHeader
.
biCompression
=
BI_RGB
;
info
->
bmiHeader
.
biXPelsPerMeter
=
0
;
info
->
bmiHeader
.
biYPelsPerMeter
=
0
;
info
->
bmiHeader
.
biClrUsed
=
0
;
info
->
bmiHeader
.
biClrImportant
=
0
;
info
->
bmiHeader
.
biWidth
=
dst
.
visrect
.
right
-
dst
.
visrect
.
left
;
info
->
bmiHeader
.
biHeight
=
dst
.
visrect
.
bottom
-
dst
.
visrect
.
top
;
info
->
bmiHeader
.
biSizeImage
=
0
;
memset
(
&
bits
,
0
,
sizeof
(
bits
));
hdc_src
=
CreateCompatibleDC
(
NULL
);
if
(
!
hdc_src
)
{
free
(
pts
);
return
FALSE
;
}
bmp
=
CreateDIBSection
(
hdc_src
,
info
,
DIB_RGB_COLORS
,
&
bits
.
ptr
,
NULL
,
0
);
if
(
!
bmp
)
{
DeleteObject
(
hdc_src
);
free
(
pts
);
return
FALSE
;
}
old_bmp
=
SelectObject
(
hdc_src
,
bmp
);
/* make src and points relative to the bitmap */
src
=
dst
;
src
.
x
-=
dst
.
visrect
.
left
;
src
.
y
-=
dst
.
visrect
.
top
;
OffsetRect
(
&
src
.
visrect
,
-
dst
.
visrect
.
left
,
-
dst
.
visrect
.
top
);
for
(
i
=
0
;
i
<
nvert
;
i
++
)
{
pts
[
i
].
x
-=
dst
.
visrect
.
left
;
pts
[
i
].
y
-=
dst
.
visrect
.
top
;
}
ret
=
GdiGradientFill
(
hdc_src
,
pts
,
nvert
,
(
void
*
)
grad_array
,
ngrad
,
mode
);
SelectObject
(
hdc_src
,
old_bmp
);
DeleteObject
(
hdc_src
);
rgn
=
CreateRectRgn
(
0
,
0
,
0
,
0
);
if
(
mode
==
GRADIENT_FILL_TRIANGLE
)
{
const
GRADIENT_TRIANGLE
*
gt
=
grad_array
;
POINT
triangle
[
3
];
HRGN
tmp
;
for
(
i
=
0
;
i
<
ngrad
;
i
++
)
{
triangle
[
0
].
x
=
pts
[
gt
[
i
].
Vertex1
].
x
;
triangle
[
0
].
y
=
pts
[
gt
[
i
].
Vertex1
].
y
;
triangle
[
1
].
x
=
pts
[
gt
[
i
].
Vertex2
].
x
;
triangle
[
1
].
y
=
pts
[
gt
[
i
].
Vertex2
].
y
;
triangle
[
2
].
x
=
pts
[
gt
[
i
].
Vertex3
].
x
;
triangle
[
2
].
y
=
pts
[
gt
[
i
].
Vertex3
].
y
;
tmp
=
CreatePolygonRgn
(
triangle
,
3
,
ALTERNATE
);
CombineRgn
(
rgn
,
rgn
,
tmp
,
RGN_OR
);
DeleteObject
(
tmp
);
}
}
else
{
const
GRADIENT_RECT
*
gr
=
grad_array
;
HRGN
tmp
=
CreateRectRgn
(
0
,
0
,
0
,
0
);
for
(
i
=
0
;
i
<
ngrad
;
i
++
)
{
SetRectRgn
(
tmp
,
pts
[
gr
[
i
].
UpperLeft
].
x
,
pts
[
gr
[
i
].
UpperLeft
].
y
,
pts
[
gr
[
i
].
LowerRight
].
x
,
pts
[
gr
[
i
].
LowerRight
].
y
);
CombineRgn
(
rgn
,
rgn
,
tmp
,
RGN_OR
);
}
DeleteObject
(
tmp
);
}
free
(
pts
);
OffsetRgn
(
rgn
,
dst
.
visrect
.
left
,
dst
.
visrect
.
top
);
if
(
ret
)
ret
=
(
PSDRV_PutImage
(
dev
,
rgn
,
info
,
&
bits
,
&
src
,
&
dst
,
SRCCOPY
)
==
ERROR_SUCCESS
);
DeleteObject
(
rgn
);
DeleteObject
(
bmp
);
return
ret
;
}
static
HGDIOBJ
get_object_handle
(
struct
pp_data
*
data
,
HANDLETABLE
*
handletable
,
DWORD
i
,
struct
brush_pattern
**
pattern
)
{
...
...
@@ -1332,6 +1458,13 @@ static int WINAPI hmf_proc(HDC hdc, HANDLETABLE *htable,
data
->
patterns
[
p
->
ihBrush
].
bits
.
ptr
=
(
BYTE
*
)
p
+
p
->
offBits
;
return
1
;
}
case
EMR_GRADIENTFILL
:
{
const
EMRGRADIENTFILL
*
p
=
(
const
EMRGRADIENTFILL
*
)
rec
;
return
gradient_fill
(
&
data
->
pdev
->
dev
,
p
->
Ver
,
p
->
nVer
,
p
->
Ver
+
p
->
nVer
,
p
->
nTri
,
p
->
ulMode
);
}
case
EMR_SETWINDOWEXTEX
:
case
EMR_SETWINDOWORGEX
:
...
...
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