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
360d4bc5
Commit
360d4bc5
authored
Dec 05, 2011
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
gdi32: Use the DIB engine and PutImage for the null driver triangular gradient implementation.
parent
8e8cdc78
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
131 additions
and
143 deletions
+131
-143
bitblt.c
dlls/gdi32/bitblt.c
+72
-139
bitblt.c
dlls/gdi32/dibdrv/bitblt.c
+57
-3
gdi_private.h
dlls/gdi32/gdi_private.h
+2
-1
No files found.
dlls/gdi32/bitblt.c
View file @
360d4bc5
...
...
@@ -21,7 +21,7 @@
#include "config.h"
#include <stdarg.h>
#include <limits.h>
#include <math.h>
#ifdef HAVE_FLOAT_H
#include <float.h>
...
...
@@ -407,152 +407,85 @@ BOOL nulldrv_GradientFill( PHYSDEV dev, TRIVERTEX *vert_array, ULONG nvert,
struct
bitblt_coords
src
,
dst
;
struct
gdi_image_bits
bits
;
unsigned
int
i
;
POINT
*
pts
;
RECT
clip
;
BOOL
ret
=
TRUE
;
DWORD
err
;
HRGN
rgn
;
switch
(
mode
)
if
(
!
(
pts
=
HeapAlloc
(
GetProcessHeap
(),
0
,
nvert
*
sizeof
(
*
pts
)
)))
return
FALSE
;
for
(
i
=
0
;
i
<
nvert
;
i
++
)
{
case
GRADIENT_FILL_RECT_H
:
case
GRADIENT_FILL_RECT_V
:
pts
[
i
].
x
=
vert_array
[
i
].
x
;
pts
[
i
].
y
=
vert_array
[
i
].
y
;
}
LPtoDP
(
dev
->
hdc
,
pts
,
nvert
);
/* compute bounding rect of all the rectangles/triangles */
dst
.
visrect
.
left
=
dst
.
visrect
.
top
=
INT_MAX
;
dst
.
visrect
.
right
=
dst
.
visrect
.
bottom
=
INT_MIN
;
for
(
i
=
0
;
i
<
ngrad
*
(
mode
==
GRADIENT_FILL_TRIANGLE
?
3
:
2
);
i
++
)
{
const
GRADIENT_RECT
*
rect
=
grad_array
;
TRIVERTEX
v
[
2
];
ULONG
v
=
((
ULONG
*
)
grad_array
)[
i
];
dst
.
visrect
.
left
=
min
(
dst
.
visrect
.
left
,
pts
[
v
].
x
);
dst
.
visrect
.
top
=
min
(
dst
.
visrect
.
top
,
pts
[
v
].
y
);
dst
.
visrect
.
right
=
max
(
dst
.
visrect
.
right
,
pts
[
v
].
x
);
dst
.
visrect
.
bottom
=
max
(
dst
.
visrect
.
bottom
,
pts
[
v
].
y
);
}
for
(
i
=
0
;
i
<
ngrad
;
i
++
,
rect
++
)
{
v
[
0
]
=
vert_array
[
rect
->
UpperLeft
];
v
[
1
]
=
vert_array
[
rect
->
LowerRight
];
dst
.
log_x
=
v
[
0
].
x
;
dst
.
log_y
=
v
[
0
].
y
;
dst
.
log_width
=
v
[
1
].
x
-
v
[
0
].
x
;
dst
.
log_height
=
v
[
1
].
y
-
v
[
0
].
y
;
dst
.
layout
=
dc
->
layout
;
if
(
!
get_vis_rectangles
(
dc
,
&
dst
,
NULL
,
NULL
))
continue
;
if
(
dst
.
width
<
0
)
{
if
(
mode
==
GRADIENT_FILL_RECT_H
)
/* swap the colors */
{
v
[
0
]
=
vert_array
[
rect
->
LowerRight
];
v
[
1
]
=
vert_array
[
rect
->
UpperLeft
];
}
dst
.
x
+=
dst
.
width
+
1
;
dst
.
width
=
-
dst
.
width
;
}
if
(
dst
.
height
<
0
)
{
if
(
mode
==
GRADIENT_FILL_RECT_V
)
/* swap the colors */
{
v
[
0
]
=
vert_array
[
rect
->
LowerRight
];
v
[
1
]
=
vert_array
[
rect
->
UpperLeft
];
}
dst
.
y
+=
dst
.
height
+
1
;
dst
.
height
=
-
dst
.
height
;
}
/* query the bitmap format */
info
->
bmiHeader
.
biSize
=
sizeof
(
info
->
bmiHeader
);
info
->
bmiHeader
.
biPlanes
=
1
;
info
->
bmiHeader
.
biBitCount
=
0
;
info
->
bmiHeader
.
biCompression
=
BI_RGB
;
info
->
bmiHeader
.
biXPelsPerMeter
=
0
;
info
->
bmiHeader
.
biYPelsPerMeter
=
0
;
info
->
bmiHeader
.
biClrUsed
=
0
;
info
->
bmiHeader
.
biClrImportant
=
0
;
info
->
bmiHeader
.
biWidth
=
dst
.
visrect
.
right
-
dst
.
visrect
.
left
;
info
->
bmiHeader
.
biHeight
=
dst
.
visrect
.
bottom
-
dst
.
visrect
.
top
;
info
->
bmiHeader
.
biSizeImage
=
0
;
dev
=
GET_DC_PHYSDEV
(
dc
,
pPutImage
);
err
=
dev
->
funcs
->
pPutImage
(
dev
,
0
,
0
,
info
,
NULL
,
NULL
,
NULL
,
0
);
if
(
!
err
||
err
==
ERROR_BAD_FORMAT
)
{
if
(
!
(
bits
.
ptr
=
HeapAlloc
(
GetProcessHeap
(),
0
,
get_dib_image_size
(
info
))))
return
FALSE
;
bits
.
is_copy
=
TRUE
;
bits
.
free
=
free_heap_bits
;
/* make src relative to the bitmap */
src
=
dst
;
src
.
x
-=
src
.
visrect
.
left
;
src
.
y
-=
src
.
visrect
.
top
;
offset_rect
(
&
src
.
visrect
,
-
src
.
visrect
.
left
,
-
src
.
visrect
.
top
);
v
[
0
].
x
=
src
.
x
;
v
[
0
].
y
=
src
.
y
;
v
[
1
].
x
=
src
.
x
+
src
.
width
;
v
[
1
].
y
=
src
.
y
+
src
.
height
;
err
=
gradient_bitmapinfo
(
info
,
bits
.
ptr
,
v
,
mode
);
if
(
!
err
)
err
=
dev
->
funcs
->
pPutImage
(
dev
,
0
,
0
,
info
,
&
bits
,
&
src
,
&
dst
,
SRCCOPY
);
if
(
bits
.
free
)
bits
.
free
(
&
bits
);
}
if
(
err
)
return
FALSE
;
}
break
;
dst
.
x
=
dst
.
visrect
.
left
;
dst
.
y
=
dst
.
visrect
.
top
;
dst
.
width
=
dst
.
visrect
.
right
-
dst
.
visrect
.
left
;
dst
.
height
=
dst
.
visrect
.
bottom
-
dst
.
visrect
.
top
;
if
(
get_clip_box
(
dc
,
&
clip
))
intersect_rect
(
&
dst
.
visrect
,
&
dst
.
visrect
,
&
clip
);
if
(
is_rect_empty
(
&
dst
.
visrect
))
goto
done
;
/* query the bitmap format */
info
->
bmiHeader
.
biSize
=
sizeof
(
info
->
bmiHeader
);
info
->
bmiHeader
.
biPlanes
=
1
;
info
->
bmiHeader
.
biBitCount
=
0
;
info
->
bmiHeader
.
biCompression
=
BI_RGB
;
info
->
bmiHeader
.
biXPelsPerMeter
=
0
;
info
->
bmiHeader
.
biYPelsPerMeter
=
0
;
info
->
bmiHeader
.
biClrUsed
=
0
;
info
->
bmiHeader
.
biClrImportant
=
0
;
info
->
bmiHeader
.
biWidth
=
dst
.
visrect
.
right
-
dst
.
visrect
.
left
;
info
->
bmiHeader
.
biHeight
=
dst
.
visrect
.
bottom
-
dst
.
visrect
.
top
;
info
->
bmiHeader
.
biSizeImage
=
0
;
dev
=
GET_DC_PHYSDEV
(
dc
,
pPutImage
);
err
=
dev
->
funcs
->
pPutImage
(
dev
,
0
,
0
,
info
,
NULL
,
NULL
,
NULL
,
0
);
if
((
err
&&
err
!=
ERROR_BAD_FORMAT
)
||
!
(
bits
.
ptr
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
get_dib_image_size
(
info
))))
{
ret
=
FALSE
;
goto
done
;
}
case
GRADIENT_FILL_TRIANGLE
:
for
(
i
=
0
;
i
<
ngrad
;
i
++
)
{
GRADIENT_TRIANGLE
*
tri
=
((
GRADIENT_TRIANGLE
*
)
grad_array
)
+
i
;
TRIVERTEX
*
v1
=
vert_array
+
tri
->
Vertex1
;
TRIVERTEX
*
v2
=
vert_array
+
tri
->
Vertex2
;
TRIVERTEX
*
v3
=
vert_array
+
tri
->
Vertex3
;
int
y
,
dy
;
if
(
v1
->
y
>
v2
->
y
)
{
TRIVERTEX
*
t
=
v1
;
v1
=
v2
;
v2
=
t
;
}
if
(
v2
->
y
>
v3
->
y
)
{
TRIVERTEX
*
t
=
v2
;
v2
=
v3
;
v3
=
t
;
if
(
v1
->
y
>
v2
->
y
)
{
t
=
v1
;
v1
=
v2
;
v2
=
t
;
}
}
/* v1->y <= v2->y <= v3->y */
dy
=
v3
->
y
-
v1
->
y
;
for
(
y
=
0
;
y
<
dy
;
y
++
)
{
/* v1->y <= y < v3->y */
TRIVERTEX
*
v
=
y
<
(
v2
->
y
-
v1
->
y
)
?
v1
:
v3
;
/* (v->y <= y < v2->y) || (v2->y <= y < v->y) */
int
dy2
=
v2
->
y
-
v
->
y
;
int
y2
=
y
+
v1
->
y
-
v
->
y
;
int
x1
=
(
v3
->
x
*
y
+
v1
->
x
*
(
dy
-
y
))
/
dy
;
int
x2
=
(
v2
->
x
*
y2
+
v
->
x
*
(
dy2
-
y2
))
/
dy2
;
int
r1
=
(
v3
->
Red
*
y
+
v1
->
Red
*
(
dy
-
y
))
/
dy
;
int
r2
=
(
v2
->
Red
*
y2
+
v
->
Red
*
(
dy2
-
y2
))
/
dy2
;
int
g1
=
(
v3
->
Green
*
y
+
v1
->
Green
*
(
dy
-
y
))
/
dy
;
int
g2
=
(
v2
->
Green
*
y2
+
v
->
Green
*
(
dy2
-
y2
))
/
dy2
;
int
b1
=
(
v3
->
Blue
*
y
+
v1
->
Blue
*
(
dy
-
y
))
/
dy
;
int
b2
=
(
v2
->
Blue
*
y2
+
v
->
Blue
*
(
dy2
-
y2
))
/
dy2
;
int
x
;
if
(
x1
<
x2
)
{
int
dx
=
x2
-
x1
;
for
(
x
=
0
;
x
<
dx
;
x
++
)
SetPixel
(
dev
->
hdc
,
x
+
x1
,
y
+
v1
->
y
,
RGB
(
(
r1
*
(
dx
-
x
)
+
r2
*
x
)
/
dx
>>
8
,
(
g1
*
(
dx
-
x
)
+
g2
*
x
)
/
dx
>>
8
,
(
b1
*
(
dx
-
x
)
+
b2
*
x
)
/
dx
>>
8
));
}
else
{
int
dx
=
x1
-
x2
;
for
(
x
=
0
;
x
<
dx
;
x
++
)
SetPixel
(
dev
->
hdc
,
x
+
x2
,
y
+
v1
->
y
,
RGB
(
(
r2
*
(
dx
-
x
)
+
r1
*
x
)
/
dx
>>
8
,
(
g2
*
(
dx
-
x
)
+
g1
*
x
)
/
dx
>>
8
,
(
b2
*
(
dx
-
x
)
+
b1
*
x
)
/
dx
>>
8
));
}
}
}
break
;
default:
return
FALSE
;
bits
.
is_copy
=
TRUE
;
bits
.
free
=
free_heap_bits
;
/* make src and points relative to the bitmap */
src
=
dst
;
src
.
x
-=
dst
.
visrect
.
left
;
src
.
y
-=
dst
.
visrect
.
top
;
offset_rect
(
&
src
.
visrect
,
-
dst
.
visrect
.
left
,
-
dst
.
visrect
.
top
);
for
(
i
=
0
;
i
<
nvert
;
i
++
)
{
pts
[
i
].
x
-=
dst
.
visrect
.
left
;
pts
[
i
].
y
-=
dst
.
visrect
.
top
;
}
return
TRUE
;
rgn
=
CreateRectRgn
(
0
,
0
,
0
,
0
);
gradient_bitmapinfo
(
info
,
bits
.
ptr
,
vert_array
,
nvert
,
grad_array
,
ngrad
,
mode
,
pts
,
rgn
);
OffsetRgn
(
rgn
,
dst
.
visrect
.
left
,
dst
.
visrect
.
top
);
if
(
dev
->
funcs
->
pPutImage
(
dev
,
0
,
rgn
,
info
,
&
bits
,
&
src
,
&
dst
,
SRCCOPY
))
ret
=
FALSE
;
if
(
bits
.
free
)
bits
.
free
(
&
bits
);
DeleteObject
(
rgn
);
done:
HeapFree
(
GetProcessHeap
(),
0
,
pts
);
return
ret
;
}
/***********************************************************************
...
...
dlls/gdi32/dibdrv/bitblt.c
View file @
360d4bc5
...
...
@@ -1334,13 +1334,67 @@ DWORD blend_bitmapinfo( const BITMAPINFO *src_info, void *src_bits, struct bitbl
return
blend_rect
(
&
dst_dib
,
&
dst
->
visrect
,
&
src_dib
,
&
src
->
visrect
,
NULL
,
blend
);
}
DWORD
gradient_bitmapinfo
(
const
BITMAPINFO
*
info
,
void
*
bits
,
TRIVERTEX
*
v
,
int
mode
)
DWORD
gradient_bitmapinfo
(
const
BITMAPINFO
*
info
,
void
*
bits
,
TRIVERTEX
*
vert_array
,
ULONG
nvert
,
void
*
grad_array
,
ULONG
ngrad
,
ULONG
mode
,
const
POINT
*
dev_pts
,
HRGN
rgn
)
{
dib_info
dib
;
const
GRADIENT_TRIANGLE
*
tri
=
grad_array
;
const
GRADIENT_RECT
*
rect
=
grad_array
;
unsigned
int
i
;
int
y
;
TRIVERTEX
vert
[
3
];
DWORD
ret
=
ERROR_SUCCESS
;
HRGN
tmp_rgn
=
0
;
if
(
!
init_dib_info_from_bitmapinfo
(
&
dib
,
info
,
bits
,
0
))
return
ERROR_BAD_FORMAT
;
if
(
!
gradient_rect
(
&
dib
,
v
,
mode
,
0
))
return
ERROR_INVALID_PARAMETER
;
return
ERROR_SUCCESS
;
switch
(
mode
)
{
case
GRADIENT_FILL_RECT_H
:
for
(
i
=
0
;
i
<
ngrad
;
i
++
,
rect
++
)
{
get_gradient_hrect_vertices
(
rect
,
vert_array
,
dev_pts
,
vert
);
gradient_rect
(
&
dib
,
vert
,
mode
,
0
);
if
(
!
tmp_rgn
)
tmp_rgn
=
CreateRectRgn
(
vert
[
0
].
x
,
vert
[
0
].
y
,
vert
[
1
].
x
,
vert
[
1
].
y
);
else
SetRectRgn
(
tmp_rgn
,
vert
[
0
].
x
,
vert
[
0
].
y
,
vert
[
1
].
x
,
vert
[
1
].
y
);
CombineRgn
(
rgn
,
rgn
,
tmp_rgn
,
RGN_OR
);
}
break
;
case
GRADIENT_FILL_RECT_V
:
for
(
i
=
0
;
i
<
ngrad
;
i
++
,
rect
++
)
{
get_gradient_vrect_vertices
(
rect
,
vert_array
,
dev_pts
,
vert
);
gradient_rect
(
&
dib
,
vert
,
mode
,
0
);
if
(
!
tmp_rgn
)
tmp_rgn
=
CreateRectRgn
(
vert
[
0
].
x
,
vert
[
0
].
y
,
vert
[
1
].
x
,
vert
[
1
].
y
);
else
SetRectRgn
(
tmp_rgn
,
vert
[
0
].
x
,
vert
[
0
].
y
,
vert
[
1
].
x
,
vert
[
1
].
y
);
CombineRgn
(
rgn
,
rgn
,
tmp_rgn
,
RGN_OR
);
}
break
;
case
GRADIENT_FILL_TRIANGLE
:
for
(
i
=
0
;
i
<
ngrad
;
i
++
,
tri
++
)
{
get_gradient_triangle_vertices
(
tri
,
vert_array
,
dev_pts
,
vert
);
if
(
gradient_rect
(
&
dib
,
vert
,
mode
,
0
))
{
if
(
!
tmp_rgn
)
tmp_rgn
=
CreateRectRgn
(
0
,
0
,
0
,
0
);
for
(
y
=
vert
[
0
].
y
;
y
<
vert
[
2
].
y
;
y
++
)
{
int
x1
,
x2
=
edge_coord
(
y
,
vert
[
0
].
x
,
vert
[
0
].
y
,
vert
[
2
].
x
,
vert
[
2
].
y
);
if
(
y
<
vert
[
1
].
y
)
x1
=
edge_coord
(
y
,
vert
[
0
].
x
,
vert
[
0
].
y
,
vert
[
1
].
x
,
vert
[
1
].
y
);
else
x1
=
edge_coord
(
y
,
vert
[
1
].
x
,
vert
[
1
].
y
,
vert
[
2
].
x
,
vert
[
2
].
y
);
SetRectRgn
(
tmp_rgn
,
min
(
x1
,
x2
),
y
,
max
(
x1
,
x2
),
y
+
1
);
CombineRgn
(
rgn
,
rgn
,
tmp_rgn
,
RGN_OR
);
}
}
else
ret
=
ERROR_INVALID_PARAMETER
;
}
break
;
}
DeleteObject
(
tmp_rgn
);
return
ret
;
}
/***********************************************************************
...
...
dlls/gdi32/gdi_private.h
View file @
360d4bc5
...
...
@@ -246,7 +246,8 @@ extern DWORD stretch_bitmapinfo( const BITMAPINFO *src_info, void *src_bits, str
extern
DWORD
blend_bitmapinfo
(
const
BITMAPINFO
*
src_info
,
void
*
src_bits
,
struct
bitblt_coords
*
src
,
const
BITMAPINFO
*
dst_info
,
void
*
dst_bits
,
struct
bitblt_coords
*
dst
,
BLENDFUNCTION
blend
)
DECLSPEC_HIDDEN
;
extern
DWORD
gradient_bitmapinfo
(
const
BITMAPINFO
*
info
,
void
*
bits
,
TRIVERTEX
*
v
,
int
mode
)
DECLSPEC_HIDDEN
;
extern
DWORD
gradient_bitmapinfo
(
const
BITMAPINFO
*
info
,
void
*
bits
,
TRIVERTEX
*
vert_array
,
ULONG
nvert
,
void
*
grad_array
,
ULONG
ngrad
,
ULONG
mode
,
const
POINT
*
dev_pts
,
HRGN
rgn
)
DECLSPEC_HIDDEN
;
extern
BOOL
render_aa_text_bitmapinfo
(
HDC
hdc
,
BITMAPINFO
*
info
,
struct
gdi_image_bits
*
bits
,
struct
bitblt_coords
*
src
,
INT
x
,
INT
y
,
UINT
flags
,
UINT
aa_flags
,
LPCWSTR
str
,
UINT
count
,
const
INT
*
dx
)
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