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
6714f16c
Commit
6714f16c
authored
Jul 30, 2012
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
gdi32: Clip solid pen regions to the DIB rectangle to avoid overflows.
parent
a9151e5d
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
116 additions
and
74 deletions
+116
-74
dc.c
dlls/gdi32/dibdrv/dc.c
+12
-0
dibdrv.h
dlls/gdi32/dibdrv/dibdrv.h
+1
-0
objects.c
dlls/gdi32/dibdrv/objects.c
+103
-74
No files found.
dlls/gdi32/dibdrv/dc.c
View file @
6714f16c
...
...
@@ -255,6 +255,18 @@ DWORD convert_bitmapinfo( const BITMAPINFO *src_info, void *src_bits, struct bit
return
ERROR_SUCCESS
;
}
int
clip_rect_to_dib
(
const
dib_info
*
dib
,
RECT
*
rc
)
{
RECT
rect
;
rect
.
left
=
max
(
0
,
-
dib
->
rect
.
left
);
rect
.
top
=
max
(
0
,
-
dib
->
rect
.
top
);
rect
.
right
=
min
(
dib
->
rect
.
right
,
dib
->
width
)
-
dib
->
rect
.
left
;
rect
.
bottom
=
min
(
dib
->
rect
.
bottom
,
dib
->
height
)
-
dib
->
rect
.
top
;
if
(
is_rect_empty
(
&
rect
))
return
0
;
return
intersect_rect
(
rc
,
&
rect
,
rc
);
}
int
get_clipped_rects
(
const
dib_info
*
dib
,
const
RECT
*
rc
,
HRGN
clip
,
struct
clipped_rects
*
clip_rects
)
{
const
WINEREGION
*
region
;
...
...
dlls/gdi32/dibdrv/dibdrv.h
View file @
6714f16c
...
...
@@ -244,6 +244,7 @@ extern void copy_dib_color_info(dib_info *dst, const dib_info *src) DECLSPEC_HID
extern
BOOL
convert_dib
(
dib_info
*
dst
,
const
dib_info
*
src
)
DECLSPEC_HIDDEN
;
extern
COLORREF
make_rgb_colorref
(
HDC
hdc
,
dib_info
*
dib
,
COLORREF
color
,
BOOL
*
got_pixel
,
DWORD
*
pixel
)
DECLSPEC_HIDDEN
;
extern
DWORD
get_pixel_color
(
dibdrv_physdev
*
pdev
,
COLORREF
color
,
BOOL
mono_fixup
)
DECLSPEC_HIDDEN
;
extern
int
clip_rect_to_dib
(
const
dib_info
*
dib
,
RECT
*
rc
)
DECLSPEC_HIDDEN
;
extern
int
get_clipped_rects
(
const
dib_info
*
dib
,
const
RECT
*
rc
,
HRGN
clip
,
struct
clipped_rects
*
clip_rects
)
DECLSPEC_HIDDEN
;
extern
void
add_clipped_bounds
(
dibdrv_physdev
*
dev
,
const
RECT
*
rect
,
HRGN
clip
)
DECLSPEC_HIDDEN
;
extern
int
clip_line
(
const
POINT
*
start
,
const
POINT
*
end
,
const
RECT
*
clip
,
...
...
dlls/gdi32/dibdrv/objects.c
View file @
6714f16c
...
...
@@ -654,6 +654,87 @@ static BOOL solid_pen_line(dibdrv_physdev *pdev, POINT *start, POINT *end, DWORD
return
TRUE
;
}
static
void
solid_line_region
(
const
dib_info
*
dib
,
const
POINT
*
start
,
const
struct
line_params
*
params
,
HRGN
region
)
{
int
len
,
err
=
params
->
err_start
;
RECT
rect
;
rect
.
left
=
start
->
x
;
rect
.
top
=
start
->
y
;
rect
.
right
=
start
->
x
+
1
;
rect
.
bottom
=
start
->
y
+
1
;
if
(
params
->
x_major
)
{
if
(
params
->
x_inc
>
0
)
{
for
(
len
=
params
->
length
;
len
;
len
--
,
rect
.
right
++
)
{
if
(
err
+
params
->
bias
>
0
)
{
add_rect_to_region
(
region
,
&
rect
);
rect
.
left
=
rect
.
right
;
rect
.
top
+=
params
->
y_inc
;
rect
.
bottom
+=
params
->
y_inc
;
err
+=
params
->
err_add_1
;
}
else
err
+=
params
->
err_add_2
;
}
}
else
{
for
(
len
=
params
->
length
;
len
;
len
--
,
rect
.
left
--
)
{
if
(
err
+
params
->
bias
>
0
)
{
add_rect_to_region
(
region
,
&
rect
);
rect
.
right
=
rect
.
left
;
rect
.
top
+=
params
->
y_inc
;
rect
.
bottom
+=
params
->
y_inc
;
err
+=
params
->
err_add_1
;
}
else
err
+=
params
->
err_add_2
;
}
}
}
else
{
if
(
params
->
y_inc
>
0
)
{
for
(
len
=
params
->
length
;
len
;
len
--
,
rect
.
bottom
++
)
{
if
(
err
+
params
->
bias
>
0
)
{
add_rect_to_region
(
region
,
&
rect
);
rect
.
top
=
rect
.
bottom
;
rect
.
left
+=
params
->
x_inc
;
rect
.
right
+=
params
->
x_inc
;
err
+=
params
->
err_add_1
;
}
else
err
+=
params
->
err_add_2
;
}
}
else
{
for
(
len
=
params
->
length
;
len
;
len
--
,
rect
.
top
--
)
{
if
(
err
+
params
->
bias
>
0
)
{
add_rect_to_region
(
region
,
&
rect
);
rect
.
bottom
=
rect
.
top
;
rect
.
left
+=
params
->
x_inc
;
rect
.
right
+=
params
->
x_inc
;
err
+=
params
->
err_add_1
;
}
else
err
+=
params
->
err_add_2
;
}
}
}
/* add final rect */
add_rect_to_region
(
region
,
&
rect
);
}
static
BOOL
solid_pen_line_region
(
dibdrv_physdev
*
pdev
,
POINT
*
start
,
POINT
*
end
,
HRGN
region
)
{
RECT
rect
;
...
...
@@ -667,99 +748,47 @@ static BOOL solid_pen_line_region( dibdrv_physdev *pdev, POINT *start, POINT *en
{
rect
.
right
=
end
->
x
;
order_end_points
(
&
rect
.
left
,
&
rect
.
right
);
add_rect_to_region
(
region
,
&
rect
);
if
(
clip_rect_to_dib
(
&
pdev
->
dib
,
&
rect
))
add_rect_to_region
(
region
,
&
rect
);
}
else
if
(
start
->
x
==
end
->
x
)
{
rect
.
bottom
=
end
->
y
;
order_end_points
(
&
rect
.
top
,
&
rect
.
bottom
);
add_rect_to_region
(
region
,
&
rect
);
if
(
clip_rect_to_dib
(
&
pdev
->
dib
,
&
rect
))
add_rect_to_region
(
region
,
&
rect
);
}
else
{
INT
dx
=
end
->
x
-
start
->
x
,
dy
=
end
->
y
-
start
->
y
;
INT
abs_dx
=
abs
(
dx
),
abs_dy
=
abs
(
dy
);
DWORD
octant
=
get_octant_mask
(
dx
,
dy
);
INT
bias
=
get_bias
(
octant
);
bres_params
clip_params
;
struct
line_params
line_params
;
POINT
p1
=
crop_coords
(
*
start
),
p2
=
crop_coords
(
*
end
);
if
(
is_xmajor
(
octant
))
init_bres_params
(
start
,
end
,
&
clip_params
,
&
line_params
,
&
rect
);
if
(
clip_rect_to_dib
(
&
pdev
->
dib
,
&
rect
))
{
int
y_inc
=
is_y_increasing
(
octant
)
?
1
:
-
1
;
int
err_add_1
=
2
*
abs_dy
-
2
*
abs_dx
;
int
err_add_2
=
2
*
abs_dy
;
int
err
=
2
*
abs_dy
-
abs_dx
;
POINT
clipped_start
,
clipped_end
;
if
(
is_x_increasing
(
octant
))
{
for
(
rect
.
right
=
start
->
x
+
1
;
rect
.
right
<=
end
->
x
;
rect
.
right
++
)
{
if
(
err
+
bias
>
0
)
{
add_rect_to_region
(
region
,
&
rect
);
rect
.
left
=
rect
.
right
;
rect
.
top
+=
y_inc
;
rect
.
bottom
+=
y_inc
;
err
+=
err_add_1
;
}
else
err
+=
err_add_2
;
}
}
else
if
(
clip_line
(
&
p1
,
&
p2
,
&
rect
,
&
clip_params
,
&
clipped_start
,
&
clipped_end
))
{
for
(
rect
.
left
=
start
->
x
;
rect
.
left
>
end
->
x
;
rect
.
left
--
)
{
if
(
err
+
bias
>
0
)
{
add_rect_to_region
(
region
,
&
rect
);
rect
.
right
=
rect
.
left
;
rect
.
top
+=
y_inc
;
rect
.
bottom
+=
y_inc
;
err
+=
err_add_1
;
}
else
err
+=
err_add_2
;
}
}
}
else
{
int
x_inc
=
is_x_increasing
(
octant
)
?
1
:
-
1
;
int
err_add_1
=
2
*
abs_dx
-
2
*
abs_dy
;
int
err_add_2
=
2
*
abs_dx
;
int
err
=
2
*
abs_dx
-
abs_dy
;
int
m
=
abs
(
clipped_start
.
x
-
p1
.
x
);
int
n
=
abs
(
clipped_start
.
y
-
p1
.
y
);
if
(
is_y_increasing
(
octant
))
{
for
(
rect
.
bottom
=
start
->
y
+
1
;
rect
.
bottom
<=
end
->
y
;
rect
.
bottom
++
)
if
(
line_params
.
x_major
)
{
if
(
err
+
bias
>
0
)
{
add_rect_to_region
(
region
,
&
rect
);
rect
.
top
=
rect
.
bottom
;
rect
.
left
+=
x_inc
;
rect
.
right
+=
x_inc
;
err
+=
err_add_1
;
}
else
err
+=
err_add_2
;
line_params
.
err_start
=
2
*
clip_params
.
dy
-
clip_params
.
dx
+
m
*
2
*
clip_params
.
dy
-
n
*
2
*
clip_params
.
dx
;
line_params
.
length
=
abs
(
clipped_end
.
x
-
clipped_start
.
x
)
+
1
;
}
}
else
{
for
(
rect
.
top
=
start
->
y
;
rect
.
top
>
end
->
y
;
rect
.
top
--
)
else
{
if
(
err
+
bias
>
0
)
{
add_rect_to_region
(
region
,
&
rect
);
rect
.
bottom
=
rect
.
top
;
rect
.
left
+=
x_inc
;
rect
.
right
+=
x_inc
;
err
+=
err_add_1
;
}
else
err
+=
err_add_2
;
line_params
.
err_start
=
2
*
clip_params
.
dx
-
clip_params
.
dy
+
n
*
2
*
clip_params
.
dx
-
m
*
2
*
clip_params
.
dy
;
line_params
.
length
=
abs
(
clipped_end
.
y
-
clipped_start
.
y
)
+
1
;
}
if
(
clipped_end
.
x
==
p2
.
x
&&
clipped_end
.
y
==
p2
.
y
)
line_params
.
length
--
;
solid_line_region
(
&
pdev
->
dib
,
&
clipped_start
,
&
line_params
,
region
);
}
}
/* add final rect */
add_rect_to_region
(
region
,
&
rect
);
}
return
TRUE
;
}
...
...
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