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
0188dc7d
Commit
0188dc7d
authored
Apr 04, 2018
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
gdi32: Clip the computed region to the DIB rectangle in PolyPolygon().
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
737a113c
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
82 additions
and
61 deletions
+82
-61
graphics.c
dlls/gdi32/dibdrv/graphics.c
+8
-4
gdi_private.h
dlls/gdi32/gdi_private.h
+2
-0
region.c
dlls/gdi32/region.c
+72
-57
No files found.
dlls/gdi32/dibdrv/graphics.c
View file @
0188dc7d
...
...
@@ -319,7 +319,7 @@ static BOOL draw_arc( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
{
dibdrv_physdev
*
pdev
=
get_dibdrv_pdev
(
dev
);
DC
*
dc
=
get_physdev_dc
(
dev
);
RECT
rect
;
RECT
rect
,
rc
;
POINT
pt
[
2
],
*
points
;
int
width
,
height
,
count
;
BOOL
ret
=
TRUE
;
...
...
@@ -370,8 +370,10 @@ static BOOL draw_arc( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
return
FALSE
;
}
if
(
pdev
->
brush
.
style
!=
BS_NULL
&&
extra_lines
>
0
&&
!
(
interior
=
CreatePolygonRgn
(
points
,
count
,
WINDING
)))
if
(
pdev
->
brush
.
style
!=
BS_NULL
&&
extra_lines
>
0
&&
get_dib_rect
(
&
pdev
->
dib
,
&
rc
)
&&
!
(
interior
=
create_polypolygon_region
(
points
,
&
count
,
1
,
WINDING
,
&
rc
)))
{
HeapFree
(
GetProcessHeap
(),
0
,
points
);
if
(
outline
)
DeleteObject
(
outline
);
...
...
@@ -1246,6 +1248,7 @@ BOOL dibdrv_PolyPolygon( PHYSDEV dev, const POINT *pt, const INT *counts, DWORD
dibdrv_physdev
*
pdev
=
get_dibdrv_pdev
(
dev
);
DC
*
dc
=
get_physdev_dc
(
dev
);
DWORD
total
,
i
,
pos
;
RECT
rc
;
BOOL
ret
=
TRUE
;
POINT
pt_buf
[
32
];
POINT
*
points
=
pt_buf
;
...
...
@@ -1266,7 +1269,8 @@ BOOL dibdrv_PolyPolygon( PHYSDEV dev, const POINT *pt, const INT *counts, DWORD
lp_to_dp
(
dc
,
points
,
total
);
if
(
pdev
->
brush
.
style
!=
BS_NULL
&&
!
(
interior
=
CreatePolyPolygonRgn
(
points
,
counts
,
polygons
,
dc
->
polyFillMode
)))
get_dib_rect
(
&
pdev
->
dib
,
&
rc
)
&&
!
(
interior
=
create_polypolygon_region
(
points
,
counts
,
polygons
,
dc
->
polyFillMode
,
&
rc
)))
{
ret
=
FALSE
;
goto
done
;
...
...
dlls/gdi32/gdi_private.h
View file @
0188dc7d
...
...
@@ -354,6 +354,8 @@ extern HPALETTE PALETTE_Init(void) DECLSPEC_HIDDEN;
extern
BOOL
add_rect_to_region
(
HRGN
rgn
,
const
RECT
*
rect
)
DECLSPEC_HIDDEN
;
extern
INT
mirror_region
(
HRGN
dst
,
HRGN
src
,
INT
width
)
DECLSPEC_HIDDEN
;
extern
BOOL
REGION_FrameRgn
(
HRGN
dest
,
HRGN
src
,
INT
x
,
INT
y
)
DECLSPEC_HIDDEN
;
extern
HRGN
create_polypolygon_region
(
const
POINT
*
pts
,
const
INT
*
count
,
INT
nbpolygons
,
INT
mode
,
const
RECT
*
clip_rect
)
DECLSPEC_HIDDEN
;
#define RGN_DEFAULT_RECTS 4
typedef
struct
...
...
dlls/gdi32/region.c
View file @
0188dc7d
...
...
@@ -2388,7 +2388,8 @@ static void REGION_InsertEdgeInET(EdgeTable *ET, EdgeTableEntry *ETE,
*/
static
unsigned
int
REGION_CreateEdgeTable
(
const
INT
*
Count
,
INT
nbpolygons
,
const
POINT
*
pts
,
EdgeTable
*
ET
,
EdgeTableEntry
*
pETEs
,
ScanLineListBlock
*
pSLLBlock
)
EdgeTableEntry
*
pETEs
,
ScanLineListBlock
*
pSLLBlock
,
const
RECT
*
clip_rect
)
{
const
POINT
*
top
,
*
bottom
;
const
POINT
*
PrevPt
,
*
CurrPt
,
*
EndPt
;
...
...
@@ -2419,7 +2420,7 @@ static unsigned int REGION_CreateEdgeTable(const INT *Count, INT nbpolygons,
* In this loop we are dealing with two vertices at
* a time -- these make up one edge of the polygon.
*/
while
(
count
--
)
for
(
;
count
;
PrevPt
=
CurrPt
,
count
--
)
{
CurrPt
=
pts
++
;
...
...
@@ -2440,30 +2441,25 @@ static unsigned int REGION_CreateEdgeTable(const INT *Count, INT nbpolygons,
/*
* don't add horizontal edges to the Edge table.
*/
if
(
bottom
->
y
!=
top
->
y
)
{
pETEs
->
ymax
=
bottom
->
y
-
1
;
/* -1 so we don't get last scanline */
if
(
bottom
->
y
==
top
->
y
)
continue
;
if
(
clip_rect
&&
(
top
->
y
>=
clip_rect
->
bottom
||
bottom
->
y
<=
clip_rect
->
top
))
continue
;
pETEs
->
ymax
=
bottom
->
y
-
1
;
/* -1 so we don't get last scanline */
/*
* initialize integer edge algorithm
*/
dy
=
bottom
->
y
-
top
->
y
;
bres_init_polygon
(
dy
,
top
->
x
,
bottom
->
x
,
&
pETEs
->
bres
);
if
(
total
+
dy
<
total
)
return
0
;
/* overflow */
total
+=
dy
;
REGION_InsertEdgeInET
(
ET
,
pETEs
,
top
->
y
,
&
pSLLBlock
,
&
iSLLBlock
);
if
(
PrevPt
->
y
>
ET
->
ymax
)
ET
->
ymax
=
PrevPt
->
y
;
if
(
PrevPt
->
y
<
ET
->
ymin
)
ET
->
ymin
=
PrevPt
->
y
;
pETEs
++
;
}
dy
=
bottom
->
y
-
top
->
y
;
bres_init_polygon
(
dy
,
top
->
x
,
bottom
->
x
,
&
pETEs
->
bres
);
if
(
clip_rect
)
dy
=
min
(
bottom
->
y
,
clip_rect
->
bottom
)
-
max
(
top
->
y
,
clip_rect
->
top
);
if
(
total
+
dy
<
total
)
return
0
;
/* overflow */
total
+=
dy
;
PrevPt
=
CurrPt
;
REGION_InsertEdgeInET
(
ET
,
pETEs
,
top
->
y
,
&
pSLLBlock
,
&
iSLLBlock
);
if
(
PrevPt
->
y
>
ET
->
ymax
)
ET
->
ymax
=
PrevPt
->
y
;
if
(
PrevPt
->
y
<
ET
->
ymin
)
ET
->
ymin
=
PrevPt
->
y
;
pETEs
++
;
}
}
return
total
;
...
...
@@ -2587,12 +2583,13 @@ static void REGION_FreeStorage(ScanLineListBlock *pSLLBlock)
}
}
/***********************************************************************
* CreatePolyPolygonRgn (GDI32.@)
* create_polypolygon_region
*
* Helper for CreatePolyPolygonRgn.
*/
HRGN
WINAPI
CreatePolyPolygonRgn
(
const
POINT
*
Pts
,
const
INT
*
Count
,
INT
nbpolygons
,
INT
mode
)
HRGN
create_polypolygon_region
(
const
POINT
*
Pts
,
const
INT
*
Count
,
INT
nbpolygons
,
INT
mode
,
const
RECT
*
clip_rect
)
{
HRGN
hrgn
=
0
;
WINEREGION
*
obj
=
NULL
;
...
...
@@ -2630,10 +2627,12 @@ HRGN WINAPI CreatePolyPolygonRgn(const POINT *Pts, const INT *Count,
if
(
!
(
pETEs
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
EdgeTableEntry
)
*
total
)))
return
0
;
if
(
!
(
nb_points
=
REGION_CreateEdgeTable
(
Count
,
nbpolygons
,
Pts
,
&
ET
,
pETEs
,
&
SLLBlock
)))
goto
done
;
if
(
!
(
nb_points
=
REGION_CreateEdgeTable
(
Count
,
nbpolygons
,
Pts
,
&
ET
,
pETEs
,
&
SLLBlock
,
clip_rect
)))
goto
done
;
if
(
!
(
obj
=
alloc_region
(
nb_points
/
2
)))
goto
done
;
if
(
clip_rect
)
ET
.
ymax
=
min
(
ET
.
ymax
,
clip_rect
->
bottom
);
list_init
(
&
AET
);
pSLL
=
ET
.
scanlines
.
next
;
if
(
mode
!=
WINDING
)
{
...
...
@@ -2650,21 +2649,25 @@ HRGN WINAPI CreatePolyPolygonRgn(const POINT *Pts, const INT *Count,
pSLL
=
pSLL
->
next
;
}
LIST_FOR_EACH_ENTRY
(
active
,
&
AET
,
struct
edge_table_entry
,
entry
)
if
(
!
clip_rect
||
y
>=
clip_rect
->
top
)
{
if
(
first
)
LIST_FOR_EACH_ENTRY
(
active
,
&
AET
,
struct
edge_table_entry
,
entry
)
{
obj
->
rects
[
obj
->
numRects
].
left
=
active
->
bres
.
minor_axis
;
obj
->
rects
[
obj
->
numRects
].
top
=
y
;
}
else
if
(
obj
->
rects
[
obj
->
numRects
].
left
!=
active
->
bres
.
minor_axis
)
{
obj
->
rects
[
obj
->
numRects
].
right
=
active
->
bres
.
minor_axis
;
obj
->
rects
[
obj
->
numRects
].
bottom
=
y
+
1
;
obj
->
numRects
++
;
if
(
first
)
{
obj
->
rects
[
obj
->
numRects
].
left
=
active
->
bres
.
minor_axis
;
obj
->
rects
[
obj
->
numRects
].
top
=
y
;
}
else
if
(
obj
->
rects
[
obj
->
numRects
].
left
!=
active
->
bres
.
minor_axis
)
{
obj
->
rects
[
obj
->
numRects
].
right
=
active
->
bres
.
minor_axis
;
obj
->
rects
[
obj
->
numRects
].
bottom
=
y
+
1
;
obj
->
numRects
++
;
}
first
=
!
first
;
}
first
=
!
first
;
}
next_scanline
(
&
AET
,
y
);
if
(
obj
->
numRects
)
...
...
@@ -2693,26 +2696,30 @@ HRGN WINAPI CreatePolyPolygonRgn(const POINT *Pts, const INT *Count,
/*
* for each active edge
*/
LIST_FOR_EACH_ENTRY
(
active
,
&
AET
,
struct
edge_table_entry
,
entry
)
if
(
!
clip_rect
||
y
>=
clip_rect
->
top
)
{
/*
* add to the buffer only those edges that
* are in the Winding active edge table.
*/
if
(
pWETE
==
&
active
->
winding_entry
)
{
if
(
first
)
{
obj
->
rects
[
obj
->
numRects
].
left
=
active
->
bres
.
minor_axis
;
obj
->
rects
[
obj
->
numRects
].
top
=
y
;
}
else
if
(
obj
->
rects
[
obj
->
numRects
].
left
!=
active
->
bres
.
minor_axis
)
LIST_FOR_EACH_ENTRY
(
active
,
&
AET
,
struct
edge_table_entry
,
entry
)
{
/*
* add to the buffer only those edges that
* are in the Winding active edge table.
*/
if
(
pWETE
==
&
active
->
winding_entry
)
{
obj
->
rects
[
obj
->
numRects
].
right
=
active
->
bres
.
minor_axis
;
obj
->
rects
[
obj
->
numRects
].
bottom
=
y
+
1
;
obj
->
numRects
++
;
if
(
first
)
{
obj
->
rects
[
obj
->
numRects
].
left
=
active
->
bres
.
minor_axis
;
obj
->
rects
[
obj
->
numRects
].
top
=
y
;
}
else
if
(
obj
->
rects
[
obj
->
numRects
].
left
!=
active
->
bres
.
minor_axis
)
{
obj
->
rects
[
obj
->
numRects
].
right
=
active
->
bres
.
minor_axis
;
obj
->
rects
[
obj
->
numRects
].
bottom
=
y
+
1
;
obj
->
numRects
++
;
}
first
=
!
first
;
pWETE
=
list_next
(
&
WETE
,
pWETE
);
}
first
=
!
first
;
pWETE
=
list_next
(
&
WETE
,
pWETE
);
}
}
...
...
@@ -2757,10 +2764,18 @@ done:
/***********************************************************************
* CreatePolyPolygonRgn (GDI32.@)
*/
HRGN
WINAPI
CreatePolyPolygonRgn
(
const
POINT
*
pts
,
const
INT
*
count
,
INT
nbpolygons
,
INT
mode
)
{
return
create_polypolygon_region
(
pts
,
count
,
nbpolygons
,
mode
,
NULL
);
}
/***********************************************************************
* CreatePolygonRgn (GDI32.@)
*/
HRGN
WINAPI
CreatePolygonRgn
(
const
POINT
*
points
,
INT
count
,
INT
mode
)
HRGN
WINAPI
CreatePolygonRgn
(
const
POINT
*
points
,
INT
count
,
INT
mode
)
{
return
CreatePolyPolygonRgn
(
points
,
&
count
,
1
,
mode
);
return
create_polypolygon_region
(
points
,
&
count
,
1
,
mode
,
NULL
);
}
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