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
1372692f
Commit
1372692f
authored
Apr 15, 2011
by
Huw Davies
Committed by
Alexandre Julliard
Apr 15, 2011
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
gdi32: Add clipping for horizontal and vertical solid lines.
parent
f33bbbfd
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
155 additions
and
32 deletions
+155
-32
objects.c
dlls/gdi32/dibdrv/objects.c
+68
-25
gdi_private.h
dlls/gdi32/gdi_private.h
+13
-0
region.c
dlls/gdi32/region.c
+14
-7
dib.c
dlls/gdi32/tests/dib.c
+60
-0
No files found.
dlls/gdi32/dibdrv/objects.c
View file @
1372692f
...
...
@@ -100,10 +100,10 @@ static inline void order_end_points(int *s, int *e)
}
}
static
inline
BOOL
pt_in_rect
(
const
RECT
*
rect
,
POINT
pt
)
static
inline
BOOL
pt_in_rect
(
const
RECT
*
rect
,
const
POINT
*
pt
)
{
return
((
pt
.
x
>=
rect
->
left
)
&&
(
pt
.
x
<
rect
->
right
)
&&
(
pt
.
y
>=
rect
->
top
)
&&
(
pt
.
y
<
rect
->
bottom
));
return
((
pt
->
x
>=
rect
->
left
)
&&
(
pt
->
x
<
rect
->
right
)
&&
(
pt
->
y
>=
rect
->
top
)
&&
(
pt
->
y
<
rect
->
bottom
));
}
static
void
WINAPI
solid_pen_line_callback
(
INT
x
,
INT
y
,
LPARAM
lparam
)
...
...
@@ -121,36 +121,79 @@ static void WINAPI solid_pen_line_callback(INT x, INT y, LPARAM lparam)
static
BOOL
solid_pen_line
(
dibdrv_physdev
*
pdev
,
POINT
*
start
,
POINT
*
end
)
{
RECT
rc
;
DC
*
dc
=
get_dibdrv_dc
(
&
pdev
->
dev
);
if
(
get_clip_region
(
dc
)
||
!
pt_in_rect
(
&
dc
->
vis_rect
,
*
start
)
||
!
pt_in_rect
(
&
dc
->
vis_rect
,
*
end
))
return
FALSE
;
const
WINEREGION
*
clip
=
get_wine_region
(
pdev
->
clip
);
BOOL
ret
=
TRUE
;
rc
.
left
=
start
->
x
;
rc
.
top
=
start
->
y
;
rc
.
right
=
end
->
x
;
rc
.
bottom
=
end
->
y
;
if
(
rc
.
top
==
rc
.
bottom
)
if
(
start
->
y
==
end
->
y
)
{
order_end_points
(
&
rc
.
left
,
&
rc
.
right
);
rc
.
bottom
++
;
pdev
->
dib
.
funcs
->
solid_rects
(
&
pdev
->
dib
,
1
,
&
rc
,
pdev
->
pen_and
,
pdev
->
pen_xor
);
RECT
rect
;
int
i
;
rect
.
left
=
start
->
x
;
rect
.
top
=
start
->
y
;
rect
.
right
=
end
->
x
;
rect
.
bottom
=
end
->
y
+
1
;
order_end_points
(
&
rect
.
left
,
&
rect
.
right
);
for
(
i
=
0
;
i
<
clip
->
numRects
;
i
++
)
{
if
(
clip
->
rects
[
i
].
top
>=
rect
.
bottom
)
break
;
if
(
clip
->
rects
[
i
].
bottom
<=
rect
.
top
)
continue
;
/* Optimize the unclipped case */
if
(
clip
->
rects
[
i
].
left
<=
rect
.
left
&&
clip
->
rects
[
i
].
right
>=
rect
.
right
)
{
pdev
->
dib
.
funcs
->
solid_rects
(
&
pdev
->
dib
,
1
,
&
rect
,
pdev
->
pen_and
,
pdev
->
pen_xor
);
break
;
}
if
(
clip
->
rects
[
i
].
right
>
rect
.
left
&&
clip
->
rects
[
i
].
left
<
rect
.
right
)
{
RECT
tmp
=
rect
;
tmp
.
left
=
max
(
rect
.
left
,
clip
->
rects
[
i
].
left
);
tmp
.
right
=
min
(
rect
.
right
,
clip
->
rects
[
i
].
right
);
pdev
->
dib
.
funcs
->
solid_rects
(
&
pdev
->
dib
,
1
,
&
tmp
,
pdev
->
pen_and
,
pdev
->
pen_xor
);
}
}
}
else
if
(
rc
.
left
==
rc
.
right
)
else
if
(
start
->
x
==
end
->
x
)
{
order_end_points
(
&
rc
.
top
,
&
rc
.
bottom
);
rc
.
right
++
;
pdev
->
dib
.
funcs
->
solid_rects
(
&
pdev
->
dib
,
1
,
&
rc
,
pdev
->
pen_and
,
pdev
->
pen_xor
);
RECT
rect
;
int
i
;
rect
.
left
=
start
->
x
;
rect
.
top
=
start
->
y
;
rect
.
right
=
end
->
x
+
1
;
rect
.
bottom
=
end
->
y
;
order_end_points
(
&
rect
.
top
,
&
rect
.
bottom
);
for
(
i
=
0
;
i
<
clip
->
numRects
;
i
++
)
{
/* Optimize unclipped case */
if
(
clip
->
rects
[
i
].
top
<=
rect
.
top
&&
clip
->
rects
[
i
].
bottom
>=
rect
.
bottom
&&
clip
->
rects
[
i
].
left
<=
rect
.
left
&&
clip
->
rects
[
i
].
right
>=
rect
.
right
)
{
pdev
->
dib
.
funcs
->
solid_rects
(
&
pdev
->
dib
,
1
,
&
rect
,
pdev
->
pen_and
,
pdev
->
pen_xor
);
break
;
}
if
(
clip
->
rects
[
i
].
top
>=
rect
.
bottom
)
break
;
if
(
clip
->
rects
[
i
].
bottom
<=
rect
.
top
)
continue
;
if
(
clip
->
rects
[
i
].
right
>
rect
.
left
&&
clip
->
rects
[
i
].
left
<
rect
.
right
)
{
RECT
tmp
=
rect
;
tmp
.
top
=
max
(
rect
.
top
,
clip
->
rects
[
i
].
top
);
tmp
.
bottom
=
min
(
rect
.
bottom
,
clip
->
rects
[
i
].
bottom
);
pdev
->
dib
.
funcs
->
solid_rects
(
&
pdev
->
dib
,
1
,
&
tmp
,
pdev
->
pen_and
,
pdev
->
pen_xor
);
}
}
}
else
{
/* FIXME: Optimize by moving Bresenham algorithm to the primitive functions,
or at least cache adjacent points in the callback */
LineDDA
(
start
->
x
,
start
->
y
,
end
->
x
,
end
->
y
,
solid_pen_line_callback
,
(
LPARAM
)
pdev
);
if
(
clip
->
numRects
==
1
&&
pt_in_rect
(
&
clip
->
extents
,
start
)
&&
pt_in_rect
(
&
clip
->
extents
,
end
))
/* FIXME: Optimize by moving Bresenham algorithm to the primitive functions,
or at least cache adjacent points in the callback */
LineDDA
(
start
->
x
,
start
->
y
,
end
->
x
,
end
->
y
,
solid_pen_line_callback
,
(
LPARAM
)
pdev
);
else
if
(
clip
->
numRects
>=
1
)
ret
=
FALSE
;
}
return
TRUE
;
release_wine_region
(
pdev
->
clip
);
return
ret
;
}
/***********************************************************************
...
...
dlls/gdi32/gdi_private.h
View file @
1372692f
...
...
@@ -553,6 +553,19 @@ extern HPALETTE PALETTE_Init(void) 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
;
typedef
struct
{
INT
size
;
INT
numRects
;
RECT
*
rects
;
RECT
extents
;
}
WINEREGION
;
extern
const
WINEREGION
*
get_wine_region
(
HRGN
rgn
)
DECLSPEC_HIDDEN
;
static
inline
void
release_wine_region
(
HRGN
rgn
)
{
GDI_ReleaseObj
(
rgn
);
}
/* null driver entry points */
extern
BOOL
CDECL
nulldrv_AbortPath
(
PHYSDEV
dev
)
DECLSPEC_HIDDEN
;
extern
BOOL
CDECL
nulldrv_AngleArc
(
PHYSDEV
dev
,
INT
x
,
INT
y
,
DWORD
radius
,
FLOAT
start
,
FLOAT
sweep
)
DECLSPEC_HIDDEN
;
...
...
dlls/gdi32/region.c
View file @
1372692f
...
...
@@ -105,13 +105,6 @@ SOFTWARE.
WINE_DEFAULT_DEBUG_CHANNEL
(
region
);
typedef
struct
{
INT
size
;
INT
numRects
;
RECT
*
rects
;
RECT
extents
;
}
WINEREGION
;
/* GDI logical region object */
typedef
struct
{
...
...
@@ -924,6 +917,20 @@ HRGN WINAPI CreateEllipticRgnIndirect( const RECT *rect )
rect
->
bottom
-
rect
->
top
);
}
/*********************************************************************
* get_wine_region
*
* Return the region data without making a copy. The caller
* must not alter anything and must call GDI_ReleaseObj() when
* they have finished with the data.
*/
const
WINEREGION
*
get_wine_region
(
HRGN
rgn
)
{
RGNOBJ
*
obj
=
GDI_GetObjPtr
(
rgn
,
OBJ_REGION
);
if
(
!
obj
)
return
NULL
;
return
&
obj
->
rgn
;
}
/***********************************************************************
* GetRegionData (GDI32.@)
*
...
...
dlls/gdi32/tests/dib.c
View file @
1372692f
...
...
@@ -78,6 +78,8 @@ static const char *sha1_graphics_a8r8g8b8[] =
"a3cadd34d95d3d5cc23344f69aab1c2e55935fcf"
,
"2426172d9e8fec27d9228088f382ef3c93717da9"
,
"9e8f27ca952cdba01dbf25d07c34e86a7820c012"
,
"76343ceb04e6295e0560019249d3c0318a23c8a6"
,
"6ecee6ba1c06dcb6b70ff42a8ea2df7803847860"
,
"17b2c177bdce5e94433574a928bda5c94a8cdfa5"
,
NULL
};
...
...
@@ -147,12 +149,43 @@ static void compare_hash(BITMAPINFO *bmi, BYTE *bits, const char ***sha1, const
HeapFree
(
GetProcessHeap
(),
0
,
hash
);
}
static
const
RECT
hline_clips
[]
=
{
{
120
,
120
,
140
,
120
},
/* unclipped */
{
100
,
122
,
140
,
122
},
/* l edgecase */
{
99
,
124
,
140
,
124
},
/* l edgecase clipped */
{
120
,
126
,
200
,
126
},
/* r edgecase */
{
120
,
128
,
201
,
128
},
/* r edgecase clipped */
{
99
,
130
,
201
,
130
},
/* l and r clipped */
{
120
,
100
,
140
,
100
},
/* t edgecase */
{
120
,
99
,
140
,
99
},
/* t edgecase clipped */
{
120
,
199
,
140
,
199
},
/* b edgecase */
{
120
,
200
,
140
,
200
},
/* b edgecase clipped */
{
120
,
132
,
310
,
132
}
/* inside two clip rects */
};
static
const
RECT
vline_clips
[]
=
{
{
120
,
120
,
120
,
140
},
/* unclipped */
{
100
,
120
,
100
,
140
},
/* l edgecase */
{
99
,
120
,
99
,
140
},
/* l edgecase clipped */
{
199
,
120
,
199
,
140
},
/* r edgecase */
{
200
,
120
,
200
,
140
},
/* r edgecase clipped */
{
122
,
99
,
122
,
201
},
/* t and b clipped */
{
124
,
100
,
124
,
140
},
/* t edgecase */
{
126
,
99
,
126
,
140
},
/* t edgecase clipped */
{
128
,
120
,
128
,
200
},
/* b edgecase */
{
130
,
120
,
130
,
201
},
/* b edgecase clipped */
{
132
,
12
,
132
,
140
}
/* inside two clip rects */
};
static
void
draw_graphics
(
HDC
hdc
,
BITMAPINFO
*
bmi
,
BYTE
*
bits
,
const
char
***
sha1
)
{
DWORD
dib_size
=
get_dib_size
(
bmi
);
HPEN
solid_pen
,
orig_pen
;
HBRUSH
solid_brush
,
orig_brush
;
INT
i
,
y
;
HRGN
hrgn
,
hrgn2
;
memset
(
bits
,
0xcc
,
dib_size
);
compare_hash
(
bmi
,
bits
,
sha1
,
"empty"
);
...
...
@@ -188,6 +221,33 @@ static void draw_graphics(HDC hdc, BITMAPINFO *bmi, BYTE *bits, const char ***sh
compare_hash
(
bmi
,
bits
,
sha1
,
"diagonal solid lines"
);
memset
(
bits
,
0xcc
,
dib_size
);
hrgn
=
CreateRectRgn
(
10
,
10
,
200
,
20
);
hrgn2
=
CreateRectRgn
(
100
,
100
,
200
,
200
);
CombineRgn
(
hrgn
,
hrgn
,
hrgn2
,
RGN_OR
);
SetRectRgn
(
hrgn2
,
290
,
100
,
300
,
200
);
CombineRgn
(
hrgn
,
hrgn
,
hrgn2
,
RGN_OR
);
ExtSelectClipRgn
(
hdc
,
hrgn
,
RGN_COPY
);
DeleteObject
(
hrgn2
);
DeleteObject
(
hrgn
);
for
(
i
=
0
;
i
<
sizeof
(
hline_clips
)
/
sizeof
(
hline_clips
[
0
]);
i
++
)
{
MoveToEx
(
hdc
,
hline_clips
[
i
].
left
,
hline_clips
[
i
].
top
,
NULL
);
LineTo
(
hdc
,
hline_clips
[
i
].
right
,
hline_clips
[
i
].
bottom
);
}
compare_hash
(
bmi
,
bits
,
sha1
,
"clipped solid hlines"
);
memset
(
bits
,
0xcc
,
dib_size
);
for
(
i
=
0
;
i
<
sizeof
(
vline_clips
)
/
sizeof
(
vline_clips
[
0
]);
i
++
)
{
MoveToEx
(
hdc
,
vline_clips
[
i
].
left
,
vline_clips
[
i
].
top
,
NULL
);
LineTo
(
hdc
,
vline_clips
[
i
].
right
,
vline_clips
[
i
].
bottom
);
}
compare_hash
(
bmi
,
bits
,
sha1
,
"clipped solid vlines"
);
memset
(
bits
,
0xcc
,
dib_size
);
ExtSelectClipRgn
(
hdc
,
NULL
,
RGN_COPY
);
solid_brush
=
CreateSolidBrush
(
RGB
(
0x33
,
0xaa
,
0xff
));
orig_brush
=
SelectObject
(
hdc
,
solid_brush
);
...
...
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