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
3ace5011
Commit
3ace5011
authored
Sep 22, 2011
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
gdi32: Copy DIB rectangles in the correct order when source and destination overlap.
parent
6176fa46
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
96 additions
and
1 deletion
+96
-1
bitblt.c
dlls/gdi32/dibdrv/bitblt.c
+91
-1
dibdrv.h
dlls/gdi32/dibdrv/dibdrv.h
+5
-0
No files found.
dlls/gdi32/dibdrv/bitblt.c
View file @
3ace5011
...
...
@@ -431,21 +431,110 @@ static const unsigned char BITBLT_Opcodes[256][MAX_OP_LEN] =
{
OP
(
PAT
,
DST
,
R2_WHITE
)
}
/* 0xff 1 */
};
static
int
get_overlap
(
const
dib_info
*
dst
,
const
RECT
*
dst_rect
,
const
dib_info
*
src
,
const
RECT
*
src_rect
)
{
const
char
*
src_top
,
*
dst_top
;
int
height
,
ret
=
0
;
if
(
dst
->
stride
!=
src
->
stride
)
return
0
;
/* can't be the same dib */
if
(
dst_rect
->
right
<=
src_rect
->
left
)
return
0
;
if
(
dst_rect
->
left
>=
src_rect
->
right
)
return
0
;
src_top
=
(
const
char
*
)
src
->
bits
.
ptr
+
src_rect
->
top
*
src
->
stride
;
dst_top
=
(
const
char
*
)
dst
->
bits
.
ptr
+
dst_rect
->
top
*
dst
->
stride
;
height
=
(
dst_rect
->
bottom
-
dst_rect
->
top
)
*
dst
->
stride
;
if
(
dst
->
stride
>
0
)
{
if
(
src_top
>=
dst_top
+
height
)
return
0
;
if
(
src_top
+
height
<=
dst_top
)
return
0
;
if
(
dst_top
<
src_top
)
ret
|=
OVERLAP_ABOVE
;
else
if
(
dst_top
>
src_top
)
ret
|=
OVERLAP_BELOW
;
}
else
{
if
(
src_top
<=
dst_top
+
height
)
return
0
;
if
(
src_top
+
height
>=
dst_top
)
return
0
;
if
(
dst_top
>
src_top
)
ret
|=
OVERLAP_ABOVE
;
else
if
(
dst_top
<
src_top
)
ret
|=
OVERLAP_BELOW
;
}
if
(
dst_rect
->
left
<
src_rect
->
left
)
ret
|=
OVERLAP_LEFT
;
else
if
(
dst_rect
->
left
>
src_rect
->
left
)
ret
|=
OVERLAP_RIGHT
;
return
ret
;
}
static
DWORD
copy_rect
(
dib_info
*
dst
,
const
RECT
*
dst_rect
,
const
dib_info
*
src
,
const
RECT
*
src_rect
,
HRGN
clip
,
INT
rop2
)
{
POINT
origin
;
RECT
clipped_rect
;
const
WINEREGION
*
clip_data
;
int
i
;
int
i
,
start
,
end
,
overlap
;
origin
.
x
=
src_rect
->
left
;
origin
.
y
=
src_rect
->
top
;
overlap
=
get_overlap
(
dst
,
dst_rect
,
src
,
src_rect
);
if
(
clip
==
NULL
)
dst
->
funcs
->
copy_rect
(
dst
,
dst_rect
,
src
,
&
origin
,
rop2
);
else
{
clip_data
=
get_wine_region
(
clip
);
if
(
overlap
&
OVERLAP_BELOW
)
{
if
(
overlap
&
OVERLAP_RIGHT
)
/* right to left, bottom to top */
{
for
(
i
=
clip_data
->
numRects
-
1
;
i
>=
0
;
i
--
)
{
if
(
intersect_rect
(
&
clipped_rect
,
dst_rect
,
clip_data
->
rects
+
i
))
{
origin
.
x
=
src_rect
->
left
+
clipped_rect
.
left
-
dst_rect
->
left
;
origin
.
y
=
src_rect
->
top
+
clipped_rect
.
top
-
dst_rect
->
top
;
dst
->
funcs
->
copy_rect
(
dst
,
&
clipped_rect
,
src
,
&
origin
,
rop2
);
}
}
}
else
/* left to right, bottom to top */
{
for
(
start
=
clip_data
->
numRects
-
1
;
start
>=
0
;
start
=
end
)
{
for
(
end
=
start
-
1
;
end
>=
0
;
end
--
)
if
(
clip_data
->
rects
[
start
].
top
!=
clip_data
->
rects
[
end
].
top
)
break
;
for
(
i
=
end
+
1
;
i
<=
start
;
i
++
)
{
if
(
intersect_rect
(
&
clipped_rect
,
dst_rect
,
clip_data
->
rects
+
i
))
{
origin
.
x
=
src_rect
->
left
+
clipped_rect
.
left
-
dst_rect
->
left
;
origin
.
y
=
src_rect
->
top
+
clipped_rect
.
top
-
dst_rect
->
top
;
dst
->
funcs
->
copy_rect
(
dst
,
&
clipped_rect
,
src
,
&
origin
,
rop2
);
}
}
}
}
}
else
if
(
overlap
&
OVERLAP_RIGHT
)
/* right to left, top to bottom */
{
for
(
start
=
0
;
start
<
clip_data
->
numRects
;
start
=
end
)
{
for
(
end
=
start
+
1
;
end
<
clip_data
->
numRects
;
end
++
)
if
(
clip_data
->
rects
[
start
].
top
!=
clip_data
->
rects
[
end
].
top
)
break
;
for
(
i
=
end
-
1
;
i
>=
start
;
i
--
)
{
if
(
intersect_rect
(
&
clipped_rect
,
dst_rect
,
clip_data
->
rects
+
i
))
{
origin
.
x
=
src_rect
->
left
+
clipped_rect
.
left
-
dst_rect
->
left
;
origin
.
y
=
src_rect
->
top
+
clipped_rect
.
top
-
dst_rect
->
top
;
dst
->
funcs
->
copy_rect
(
dst
,
&
clipped_rect
,
src
,
&
origin
,
rop2
);
}
}
}
}
else
/* left to right, top to bottom */
{
for
(
i
=
0
;
i
<
clip_data
->
numRects
;
i
++
)
{
if
(
intersect_rect
(
&
clipped_rect
,
dst_rect
,
clip_data
->
rects
+
i
))
...
...
@@ -455,6 +544,7 @@ static DWORD copy_rect( dib_info *dst, const RECT *dst_rect, const dib_info *src
dst
->
funcs
->
copy_rect
(
dst
,
&
clipped_rect
,
src
,
&
origin
,
rop2
);
}
}
}
release_wine_region
(
clip
);
}
return
ERROR_SUCCESS
;
...
...
dlls/gdi32/dibdrv/dibdrv.h
View file @
3ace5011
...
...
@@ -147,6 +147,11 @@ struct rop_codes
DWORD
a1
,
a2
,
x1
,
x2
;
};
#define OVERLAP_LEFT 0x01
/* dest starts left of source */
#define OVERLAP_RIGHT 0x02
/* dest starts right of source */
#define OVERLAP_ABOVE 0x04
/* dest starts above source */
#define OVERLAP_BELOW 0x08
/* dest starts below source */
extern
void
get_rop_codes
(
INT
rop
,
struct
rop_codes
*
codes
);
extern
void
calc_and_xor_masks
(
INT
rop
,
DWORD
color
,
DWORD
*
and
,
DWORD
*
xor
)
DECLSPEC_HIDDEN
;
extern
void
update_brush_rop
(
dibdrv_physdev
*
pdev
,
INT
rop
)
DECLSPEC_HIDDEN
;
...
...
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