Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
wine
Manage
Activity
Members
Labels
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Package registry
Container Registry
Model registry
Operate
Terraform modules
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Lorenzo Ferrillo
wine
Commits
1372692f
Commit
1372692f
authored
13 years ago
by
Huw Davies
Committed by
Alexandre Julliard
13 years ago
Browse files
Options
Downloads
Patches
Plain Diff
gdi32: Add clipping for horizontal and vertical solid lines.
parent
f33bbbfd
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
dlls/gdi32/dibdrv/objects.c
+68
-25
68 additions, 25 deletions
dlls/gdi32/dibdrv/objects.c
dlls/gdi32/gdi_private.h
+13
-0
13 additions, 0 deletions
dlls/gdi32/gdi_private.h
dlls/gdi32/region.c
+14
-7
14 additions, 7 deletions
dlls/gdi32/region.c
dlls/gdi32/tests/dib.c
+60
-0
60 additions, 0 deletions
dlls/gdi32/tests/dib.c
with
155 additions
and
32 deletions
dlls/gdi32/dibdrv/objects.c
+
68
−
25
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
;
}
/***********************************************************************
...
...
This diff is collapsed.
Click to expand it.
dlls/gdi32/gdi_private.h
+
13
−
0
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
;
...
...
This diff is collapsed.
Click to expand it.
dlls/gdi32/region.c
+
14
−
7
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.@)
*
...
...
This diff is collapsed.
Click to expand it.
dlls/gdi32/tests/dib.c
+
60
−
0
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
);
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment