Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
e155a805
Commit
e155a805
authored
Dec 09, 2011
by
Huw Davies
Committed by
Alexandre Julliard
Dec 09, 2011
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
gdi32: Add support for wide cosmetic pens.
parent
c368e551
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
185 additions
and
3 deletions
+185
-3
dibdrv.h
dlls/gdi32/dibdrv/dibdrv.h
+2
-1
objects.c
dlls/gdi32/dibdrv/objects.c
+183
-2
No files found.
dlls/gdi32/dibdrv/dibdrv.h
View file @
e155a805
...
...
@@ -85,7 +85,8 @@ typedef struct dibdrv_physdev
/* pen */
COLORREF
pen_colorref
;
DWORD
pen_color
,
pen_and
,
pen_xor
;
DWORD
pen_color
,
pen_and
,
pen_xor
,
pen_endcap
,
pen_join
;
int
pen_width
;
dash_pattern
pen_pattern
;
dash_pos
dash_pos
;
BOOL
(
*
pen_lines
)(
struct
dibdrv_physdev
*
pdev
,
int
num
,
POINT
*
pts
,
BOOL
close
);
...
...
dlls/gdi32/dibdrv/objects.c
View file @
e155a805
...
...
@@ -1017,6 +1017,166 @@ static BOOL null_pen_lines(dibdrv_physdev *pdev, int num, POINT *pts, BOOL close
return
TRUE
;
}
static
void
add_cap
(
dibdrv_physdev
*
pdev
,
HRGN
region
,
const
POINT
*
pt
)
{
HRGN
cap
;
switch
(
pdev
->
pen_endcap
)
{
case
PS_ENDCAP_ROUND
:
cap
=
CreateEllipticRgn
(
pt
->
x
-
pdev
->
pen_width
/
2
,
pt
->
y
-
pdev
->
pen_width
/
2
,
pt
->
x
+
(
pdev
->
pen_width
+
1
)
/
2
,
pt
->
y
+
(
pdev
->
pen_width
+
1
)
/
2
);
break
;
default:
/* only supporting cosmetic pens so far, so always PS_ENDCAP_ROUND */
return
;
}
CombineRgn
(
region
,
region
,
cap
,
RGN_OR
);
DeleteObject
(
cap
);
return
;
}
static
void
add_join
(
dibdrv_physdev
*
pdev
,
HRGN
region
,
const
POINT
*
pt
)
{
HRGN
join
;
switch
(
pdev
->
pen_join
)
{
case
PS_JOIN_ROUND
:
join
=
CreateEllipticRgn
(
pt
->
x
-
pdev
->
pen_width
/
2
,
pt
->
y
-
pdev
->
pen_width
/
2
,
pt
->
x
+
(
pdev
->
pen_width
+
1
)
/
2
,
pt
->
y
+
(
pdev
->
pen_width
+
1
)
/
2
);
break
;
default:
/* only supporting cosmetic pens so far, so always PS_JOIN_ROUND */
return
;
}
CombineRgn
(
region
,
region
,
join
,
RGN_OR
);
DeleteObject
(
join
);
return
;
}
#define round( f ) (((f) > 0) ? (f) + 0.5 : (f) - 0.5)
static
HRGN
get_wide_lines_region
(
dibdrv_physdev
*
pdev
,
int
num
,
POINT
*
pts
,
BOOL
close
)
{
int
i
;
HRGN
total
,
segment
;
assert
(
num
>=
2
);
total
=
CreateRectRgn
(
0
,
0
,
0
,
0
);
if
(
!
close
)
num
--
;
for
(
i
=
0
;
i
<
num
;
i
++
)
{
const
POINT
*
pt_1
=
pts
+
i
;
const
POINT
*
pt_2
=
pts
+
((
close
&&
i
==
num
-
1
)
?
0
:
i
+
1
);
int
dx
=
pt_2
->
x
-
pt_1
->
x
;
int
dy
=
pt_2
->
y
-
pt_1
->
y
;
RECT
rect
;
if
(
dx
==
0
&&
dy
==
0
)
continue
;
if
(
dy
==
0
)
{
rect
.
left
=
min
(
pt_1
->
x
,
pt_2
->
x
);
rect
.
right
=
rect
.
left
+
abs
(
dx
);
rect
.
top
=
pt_1
->
y
-
pdev
->
pen_width
/
2
;
rect
.
bottom
=
rect
.
top
+
pdev
->
pen_width
;
segment
=
CreateRectRgnIndirect
(
&
rect
);
}
else
if
(
dx
==
0
)
{
rect
.
top
=
min
(
pt_1
->
y
,
pt_2
->
y
);
rect
.
bottom
=
rect
.
top
+
abs
(
dy
);
rect
.
left
=
pt_1
->
x
-
pdev
->
pen_width
/
2
;
rect
.
right
=
rect
.
left
+
pdev
->
pen_width
;
segment
=
CreateRectRgnIndirect
(
&
rect
);
}
else
{
double
len
=
hypot
(
dx
,
dy
);
double
width_x
,
width_y
;
POINT
seg_pts
[
4
];
POINT
wide_half
,
narrow_half
;
width_x
=
pdev
->
pen_width
*
abs
(
dy
)
/
len
;
width_y
=
pdev
->
pen_width
*
abs
(
dx
)
/
len
;
narrow_half
.
x
=
round
(
width_x
/
2
);
narrow_half
.
y
=
round
(
width_y
/
2
);
wide_half
.
x
=
round
(
(
width_x
+
1
)
/
2
);
wide_half
.
y
=
round
(
(
width_y
+
1
)
/
2
);
if
(
dx
<
0
)
{
wide_half
.
y
=
-
wide_half
.
y
;
narrow_half
.
y
=
-
narrow_half
.
y
;
}
if
(
dy
<
0
)
{
POINT
tmp
=
narrow_half
;
narrow_half
=
wide_half
;
wide_half
=
tmp
;
wide_half
.
x
=
-
wide_half
.
x
;
narrow_half
.
x
=
-
narrow_half
.
x
;
}
seg_pts
[
0
].
x
=
pt_1
->
x
-
narrow_half
.
x
;
seg_pts
[
0
].
y
=
pt_1
->
y
+
narrow_half
.
y
;
seg_pts
[
1
].
x
=
pt_1
->
x
+
wide_half
.
x
;
seg_pts
[
1
].
y
=
pt_1
->
y
-
wide_half
.
y
;
seg_pts
[
2
].
x
=
pt_2
->
x
+
wide_half
.
x
;
seg_pts
[
2
].
y
=
pt_2
->
y
-
wide_half
.
y
;
seg_pts
[
3
].
x
=
pt_2
->
x
-
narrow_half
.
x
;
seg_pts
[
3
].
y
=
pt_2
->
y
+
narrow_half
.
y
;
segment
=
CreatePolygonRgn
(
seg_pts
,
4
,
ALTERNATE
);
}
CombineRgn
(
total
,
total
,
segment
,
RGN_OR
);
DeleteObject
(
segment
);
if
(
i
==
0
)
{
if
(
!
close
)
add_cap
(
pdev
,
total
,
pt_1
);
}
else
add_join
(
pdev
,
total
,
pt_1
);
if
(
i
==
num
-
1
)
{
if
(
close
)
add_join
(
pdev
,
total
,
pt_2
);
else
add_cap
(
pdev
,
total
,
pt_2
);
}
}
return
total
;
}
static
BOOL
wide_pen_lines
(
dibdrv_physdev
*
pdev
,
int
num
,
POINT
*
pts
,
BOOL
close
)
{
const
WINEREGION
*
data
;
rop_mask
color
;
HRGN
region
;
color
.
and
=
pdev
->
pen_and
;
color
.
xor
=
pdev
->
pen_xor
;
region
=
get_wide_lines_region
(
pdev
,
num
,
pts
,
close
);
if
(
CombineRgn
(
region
,
region
,
pdev
->
clip
,
RGN_AND
)
!=
ERROR
)
{
data
=
get_wine_region
(
region
);
solid_rects
(
&
pdev
->
dib
,
data
->
numRects
,
data
->
rects
,
&
color
,
NULL
);
release_wine_region
(
region
);
}
DeleteObject
(
region
);
return
TRUE
;
}
static
const
dash_pattern
dash_patterns
[
5
]
=
{
{
0
,
{
0
},
0
},
/* PS_SOLID - a pseudo-pattern used to initialise unpatterned pens. */
...
...
@@ -1026,6 +1186,21 @@ static const dash_pattern dash_patterns[5] =
{
6
,
{
9
,
3
,
3
,
3
,
3
,
3
},
24
}
/* PS_DASHDOTDOT */
};
static
inline
int
get_pen_device_width
(
dibdrv_physdev
*
pdev
,
LOGPEN
*
pen
)
{
int
width
=
pen
->
lopnWidth
.
x
;
if
(
pen
->
lopnStyle
&
PS_GEOMETRIC
&&
width
>
1
)
{
POINT
pts
[
2
];
pts
[
0
].
x
=
pts
[
0
].
y
=
pts
[
1
].
y
=
0
;
pts
[
1
].
x
=
width
;
LPtoDP
(
pdev
->
dev
.
hdc
,
pts
,
2
);
width
=
max
(
abs
(
pts
[
1
].
x
-
pts
[
0
].
x
),
1
);
}
return
width
;
}
/***********************************************************************
* dibdrv_SelectPen
*/
...
...
@@ -1058,6 +1233,10 @@ HPEN dibdrv_SelectPen( PHYSDEV dev, HPEN hpen )
HeapFree
(
GetProcessHeap
(),
0
,
elp
);
}
pdev
->
pen_join
=
logpen
.
lopnStyle
&
PS_JOIN_MASK
;
pdev
->
pen_endcap
=
logpen
.
lopnStyle
&
PS_ENDCAP_MASK
;
pdev
->
pen_width
=
get_pen_device_width
(
pdev
,
&
logpen
);
if
(
hpen
==
GetStockObject
(
DC_PEN
))
logpen
.
lopnColor
=
GetDCPenColor
(
dev
->
hdc
);
...
...
@@ -1075,8 +1254,10 @@ HPEN dibdrv_SelectPen( PHYSDEV dev, HPEN hpen )
{
case
PS_SOLID
:
if
(
logpen
.
lopnStyle
&
PS_GEOMETRIC
)
break
;
if
(
logpen
.
lopnWidth
.
x
>
1
)
break
;
pdev
->
pen_lines
=
solid_pen_lines
;
if
(
pdev
->
pen_width
<=
1
)
pdev
->
pen_lines
=
solid_pen_lines
;
else
pdev
->
pen_lines
=
wide_pen_lines
;
pdev
->
defer
&=
~
DEFER_PEN
;
break
;
...
...
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