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
139aeba3
Commit
139aeba3
authored
May 23, 2012
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
gdi32: Implement dithering of solid brushes when drawing to DDBs.
parent
6afed7a5
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
249 additions
and
10 deletions
+249
-10
dibdrv.h
dlls/gdi32/dibdrv/dibdrv.h
+1
-0
objects.c
dlls/gdi32/dibdrv/objects.c
+59
-10
primitives.c
dlls/gdi32/dibdrv/primitives.c
+189
-0
No files found.
dlls/gdi32/dibdrv/dibdrv.h
View file @
139aeba3
...
...
@@ -188,6 +188,7 @@ typedef struct primitive_funcs
void
(
*
convert_to
)(
dib_info
*
dst
,
const
dib_info
*
src
,
const
RECT
*
src_rect
,
BOOL
dither
);
void
(
*
create_rop_masks
)(
const
dib_info
*
dib
,
const
BYTE
*
hatch_ptr
,
const
rop_mask
*
fg
,
const
rop_mask
*
bg
,
rop_mask_bits
*
bits
);
void
(
*
create_dither_masks
)(
const
dib_info
*
dib
,
int
rop2
,
COLORREF
color
,
rop_mask_bits
*
bits
);
void
(
*
stretch_row
)(
const
dib_info
*
dst_dib
,
const
POINT
*
dst_start
,
const
dib_info
*
src_dib
,
const
POINT
*
src_start
,
const
struct
stretch_params
*
params
,
int
mode
,
BOOL
keep_dst
);
...
...
dlls/gdi32/dibdrv/objects.c
View file @
139aeba3
...
...
@@ -1788,10 +1788,8 @@ static const BYTE hatches[6][8] =
{
0x81
,
0x42
,
0x24
,
0x18
,
0x18
,
0x24
,
0x42
,
0x81
}
/* HS_DIAGCROSS */
};
static
BOOL
create_hatch_brush_bits
(
dibdrv_physdev
*
pdev
,
dib_brush
*
brush
,
BOOL
*
needs_reselect
)
static
BOOL
init_hatch_brush
(
dibdrv_physdev
*
pdev
,
dib_brush
*
brush
)
{
rop_mask
fg_mask
,
bg_mask
;
/* Just initialise brush dib with the color / sizing info. We don't
need the bits as we'll calculate the rop masks straight from
the hatch patterns. */
...
...
@@ -1804,8 +1802,14 @@ static BOOL create_hatch_brush_bits(dibdrv_physdev *pdev, dib_brush *brush, BOOL
brush
->
dib
.
rect
.
top
=
0
;
brush
->
dib
.
rect
.
right
=
8
;
brush
->
dib
.
rect
.
bottom
=
8
;
return
alloc_brush_mask_bits
(
brush
);
}
if
(
!
alloc_brush_mask_bits
(
brush
))
return
FALSE
;
static
BOOL
create_hatch_brush_bits
(
dibdrv_physdev
*
pdev
,
dib_brush
*
brush
,
BOOL
*
needs_reselect
)
{
rop_mask
fg_mask
,
bg_mask
;
if
(
!
init_hatch_brush
(
pdev
,
brush
))
return
FALSE
;
get_color_masks
(
pdev
,
brush
->
rop
,
brush
->
colorref
,
GetBkMode
(
pdev
->
dev
.
hdc
),
&
fg_mask
,
&
bg_mask
);
...
...
@@ -1820,6 +1824,23 @@ static BOOL create_hatch_brush_bits(dibdrv_physdev *pdev, dib_brush *brush, BOOL
return
TRUE
;
}
static
BOOL
create_dither_brush_bits
(
dibdrv_physdev
*
pdev
,
dib_brush
*
brush
,
BOOL
*
needs_reselect
)
{
COLORREF
rgb
;
DWORD
pixel
;
BOOL
got_pixel
;
if
(
!
init_hatch_brush
(
pdev
,
brush
))
return
FALSE
;
if
(
brush
->
colorref
&
(
1
<<
24
))
/* PALETTEINDEX */
*
needs_reselect
=
TRUE
;
rgb
=
make_rgb_colorref
(
pdev
->
dev
.
hdc
,
&
pdev
->
dib
,
brush
->
colorref
,
&
got_pixel
,
&
pixel
);
brush
->
dib
.
funcs
->
create_dither_masks
(
&
brush
->
dib
,
brush
->
rop
,
rgb
,
&
brush
->
masks
);
return
TRUE
;
}
static
BOOL
matching_pattern_format
(
dib_info
*
dib
,
dib_info
*
pattern
)
{
if
(
dib
->
bit_count
!=
pattern
->
bit_count
)
return
FALSE
;
...
...
@@ -1950,6 +1971,11 @@ static BOOL pattern_brush(dibdrv_physdev *pdev, dib_brush *brush, dib_info *dib,
return
FALSE
;
break
;
case
BS_SOLID
:
if
(
!
create_dither_brush_bits
(
pdev
,
brush
,
&
needs_reselect
))
return
FALSE
;
break
;
case
BS_HATCHED
:
if
(
!
create_hatch_brush_bits
(
pdev
,
brush
,
&
needs_reselect
))
return
FALSE
;
...
...
@@ -1975,7 +2001,26 @@ static BOOL null_brush(dibdrv_physdev *pdev, dib_brush *brush, dib_info *dib,
return
TRUE
;
}
static
void
select_brush
(
dib_brush
*
brush
,
const
LOGBRUSH
*
logbrush
,
const
struct
brush_pattern
*
pattern
)
static
BOOL
brush_needs_dithering
(
dibdrv_physdev
*
pdev
,
COLORREF
color
)
{
int
i
;
RGBQUAD
rgb
;
const
RGBQUAD
*
color_table
=
get_default_color_table
(
pdev
->
dib
.
bit_count
);
if
(
!
color_table
)
return
FALSE
;
if
(
pdev
->
dib
.
color_table
)
return
FALSE
;
if
(
color
&
(
1
<<
24
))
return
TRUE
;
/* PALETTEINDEX */
if
(
color
>>
16
==
0x10ff
)
return
FALSE
;
/* DIBINDEX */
rgb
=
rgbquad_from_colorref
(
color
);
for
(
i
=
0
;
i
<
(
1
<<
pdev
->
dib
.
bit_count
);
i
++
)
if
(
rgbquad_equal
(
&
color_table
[
i
],
&
rgb
))
return
FALSE
;
return
TRUE
;
}
static
void
select_brush
(
dibdrv_physdev
*
pdev
,
dib_brush
*
brush
,
const
LOGBRUSH
*
logbrush
,
const
struct
brush_pattern
*
pattern
)
{
free_pattern_brush
(
brush
);
...
...
@@ -1993,9 +2038,11 @@ static void select_brush( dib_brush *brush, const LOGBRUSH *logbrush, const stru
switch
(
logbrush
->
lbStyle
)
{
case
BS_SOLID
:
brush
->
rects
=
solid_brush
;
break
;
case
BS_NULL
:
brush
->
rects
=
null_brush
;
break
;
case
BS_HATCHED
:
brush
->
rects
=
pattern_brush
;
break
;
case
BS_SOLID
:
brush
->
rects
=
brush_needs_dithering
(
pdev
,
brush
->
colorref
)
?
pattern_brush
:
solid_brush
;
break
;
}
}
}
...
...
@@ -2015,7 +2062,7 @@ HBRUSH dibdrv_SelectBrush( PHYSDEV dev, HBRUSH hbrush, const struct brush_patter
if
(
hbrush
==
GetStockObject
(
DC_BRUSH
))
logbrush
.
lbColor
=
GetDCBrushColor
(
dev
->
hdc
);
select_brush
(
&
pdev
->
brush
,
&
logbrush
,
pattern
);
select_brush
(
pdev
,
&
pdev
->
brush
,
&
logbrush
,
pattern
);
return
hbrush
;
}
...
...
@@ -2065,7 +2112,7 @@ HPEN dibdrv_SelectPen( PHYSDEV dev, HPEN hpen, const struct brush_pattern *patte
logbrush
.
lbColor
=
GetDCPenColor
(
dev
->
hdc
);
set_dash_pattern
(
&
pdev
->
pen_pattern
,
0
,
NULL
);
select_brush
(
&
pdev
->
pen_brush
,
&
logbrush
,
pattern
);
select_brush
(
pdev
,
&
pdev
->
pen_brush
,
&
logbrush
,
pattern
);
pdev
->
pen_style
=
logpen
.
lopnStyle
&
PS_STYLE_MASK
;
...
...
@@ -2129,8 +2176,10 @@ COLORREF dibdrv_SetDCBrushColor( PHYSDEV dev, COLORREF color )
dibdrv_physdev
*
pdev
=
get_dibdrv_pdev
(
dev
);
if
(
GetCurrentObject
(
dev
->
hdc
,
OBJ_BRUSH
)
==
GetStockObject
(
DC_BRUSH
))
pdev
->
brush
.
colorref
=
color
;
{
LOGBRUSH
logbrush
=
{
BS_SOLID
,
color
,
0
};
select_brush
(
pdev
,
&
pdev
->
brush
,
&
logbrush
,
NULL
);
}
return
color
;
}
...
...
dlls/gdi32/dibdrv/primitives.c
View file @
139aeba3
...
...
@@ -37,6 +37,18 @@ static const BYTE bayer_4x4[4][4] =
{
15
,
7
,
13
,
5
}
};
static
const
BYTE
bayer_8x8
[
8
][
8
]
=
{
{
0
,
32
,
8
,
40
,
2
,
34
,
10
,
42
},
{
48
,
16
,
56
,
24
,
50
,
18
,
58
,
26
},
{
12
,
44
,
4
,
36
,
14
,
46
,
6
,
38
},
{
60
,
28
,
52
,
20
,
62
,
30
,
54
,
22
},
{
3
,
35
,
11
,
43
,
1
,
33
,
9
,
41
},
{
51
,
19
,
59
,
27
,
49
,
17
,
57
,
25
},
{
15
,
47
,
7
,
39
,
13
,
45
,
5
,
37
},
{
63
,
31
,
55
,
23
,
61
,
29
,
53
,
21
}
};
static
const
BYTE
bayer_16x16
[
16
][
16
]
=
{
{
0
,
128
,
32
,
160
,
8
,
136
,
40
,
168
,
2
,
130
,
34
,
162
,
10
,
138
,
42
,
170
},
...
...
@@ -5041,6 +5053,174 @@ static void create_rop_masks_null(const dib_info *dib, const BYTE *hatch_ptr,
{
}
static
void
create_dither_masks_8
(
const
dib_info
*
dib
,
int
rop2
,
COLORREF
color
,
rop_mask_bits
*
bits
)
{
/* mapping between RGB triples and the default color table */
static
const
BYTE
mapping
[
27
]
=
{
0
,
/* 000000 -> 000000 */
4
,
/* 00007f -> 000080 */
252
,
/* 0000ff -> 0000ff */
2
,
/* 007f00 -> 008000 */
6
,
/* 007f7f -> 008080 */
224
,
/* 007fff -> 0080c0 */
250
,
/* 00ff00 -> 00ff00 */
184
,
/* 00ff7f -> 00e080 */
254
,
/* 00ffff -> 00ffff */
1
,
/* 7f0000 -> 800000 */
5
,
/* 7f007f -> 800080 */
196
,
/* 7f00ff -> 8000c0 */
3
,
/* 7f7f00 -> 808000 */
248
,
/* 7f7f7f -> 808080 */
228
,
/* 7f7fff -> 8080c0 */
60
,
/* 7fff00 -> 80e000 */
188
,
/* 7fff7f -> 80e080 */
244
,
/* 7fffff -> 80c0c0 */
249
,
/* ff0000 -> ff0000 */
135
,
/* ff007f -> e00080 */
253
,
/* ff00ff -> ff00ff */
39
,
/* ff7f00 -> e08000 */
167
,
/* ff7f7f -> e08080 */
231
,
/* ff7fff -> e080c0 */
251
,
/* ffff00 -> ffff00 */
191
,
/* ffff7f -> e0e080 */
255
/* ffffff -> ffffff */
};
BYTE
*
and_bits
=
bits
->
and
,
*
xor_bits
=
bits
->
xor
;
struct
rop_codes
codes
;
int
x
,
y
;
/* masks are always 8x8 */
assert
(
dib
->
width
==
8
);
assert
(
dib
->
height
==
8
);
get_rop_codes
(
rop2
,
&
codes
);
for
(
y
=
0
;
y
<
8
;
y
++
)
{
for
(
x
=
0
;
x
<
8
;
x
++
)
{
DWORD
r
=
((
GetRValue
(
color
)
+
1
)
/
2
+
bayer_8x8
[
y
][
x
])
/
64
;
DWORD
g
=
((
GetGValue
(
color
)
+
1
)
/
2
+
bayer_8x8
[
y
][
x
])
/
64
;
DWORD
b
=
((
GetBValue
(
color
)
+
1
)
/
2
+
bayer_8x8
[
y
][
x
])
/
64
;
DWORD
pixel
=
mapping
[
r
*
9
+
g
*
3
+
b
];
and_bits
[
x
]
=
(
pixel
&
codes
.
a1
)
^
codes
.
a2
;
xor_bits
[
x
]
=
(
pixel
&
codes
.
x1
)
^
codes
.
x2
;
}
and_bits
+=
dib
->
stride
;
xor_bits
+=
dib
->
stride
;
}
}
static
void
create_dither_masks_4
(
const
dib_info
*
dib
,
int
rop2
,
COLORREF
color
,
rop_mask_bits
*
bits
)
{
/* mapping between RGB triples and the default color table */
static
const
BYTE
mapping
[
27
]
=
{
0
,
/* 000000 -> 000000 */
4
,
/* 00007f -> 000080 */
12
,
/* 0000ff -> 0000ff */
2
,
/* 007f00 -> 008000 */
6
,
/* 007f7f -> 008080 */
6
,
/* 007fff -> 008080 */
10
,
/* 00ff00 -> 00ff00 */
6
,
/* 00ff7f -> 008080 */
14
,
/* 00ffff -> 00ffff */
1
,
/* 7f0000 -> 800000 */
5
,
/* 7f007f -> 800080 */
5
,
/* 7f00ff -> 800080 */
3
,
/* 7f7f00 -> 808000 */
7
,
/* 7f7f7f -> 808080 */
8
,
/* 7f7fff -> c0c0c0 */
3
,
/* 7fff00 -> 808000 */
8
,
/* 7fff7f -> c0c0c0 */
8
,
/* 7fffff -> c0c0c0 */
9
,
/* ff0000 -> ff0000 */
5
,
/* ff007f -> 800080 */
13
,
/* ff00ff -> ff00ff */
3
,
/* ff7f00 -> 808000 */
8
,
/* ff7f7f -> c0c0c0 */
8
,
/* ff7fff -> c0c0c0 */
11
,
/* ffff00 -> ffff00 */
8
,
/* ffff7f -> c0c0c0 */
15
/* ffffff -> ffffff */
};
BYTE
*
and_bits
=
bits
->
and
,
*
xor_bits
=
bits
->
xor
;
struct
rop_codes
codes
;
int
x
,
y
;
/* masks are always 8x8 */
assert
(
dib
->
width
==
8
);
assert
(
dib
->
height
==
8
);
get_rop_codes
(
rop2
,
&
codes
);
for
(
y
=
0
;
y
<
8
;
y
++
)
{
for
(
x
=
0
;
x
<
8
;
x
++
)
{
DWORD
r
=
((
GetRValue
(
color
)
+
1
)
/
2
+
bayer_8x8
[
y
][
x
])
/
64
;
DWORD
g
=
((
GetGValue
(
color
)
+
1
)
/
2
+
bayer_8x8
[
y
][
x
])
/
64
;
DWORD
b
=
((
GetBValue
(
color
)
+
1
)
/
2
+
bayer_8x8
[
y
][
x
])
/
64
;
DWORD
pixel
=
mapping
[
r
*
9
+
g
*
3
+
b
];
if
(
x
&
1
)
{
and_bits
[
x
/
2
]
|=
(
pixel
&
codes
.
a1
)
^
codes
.
a2
;
xor_bits
[
x
/
2
]
|=
(
pixel
&
codes
.
x1
)
^
codes
.
x2
;
}
else
{
and_bits
[
x
/
2
]
=
((
pixel
&
codes
.
a1
)
^
codes
.
a2
)
<<
4
;
xor_bits
[
x
/
2
]
=
((
pixel
&
codes
.
x1
)
^
codes
.
x2
)
<<
4
;
}
}
and_bits
+=
dib
->
stride
;
xor_bits
+=
dib
->
stride
;
}
}
static
void
create_dither_masks_1
(
const
dib_info
*
dib
,
int
rop2
,
COLORREF
color
,
rop_mask_bits
*
bits
)
{
BYTE
*
and_bits
=
bits
->
and
,
*
xor_bits
=
bits
->
xor
;
struct
rop_codes
codes
;
rop_mask
rop_mask
;
int
x
,
y
,
grey
=
(
30
*
GetRValue
(
color
)
+
59
*
GetGValue
(
color
)
+
11
*
GetBValue
(
color
)
+
200
)
/
400
;
/* masks are always 8x8 */
assert
(
dib
->
width
==
8
);
assert
(
dib
->
height
==
8
);
get_rop_codes
(
rop2
,
&
codes
);
for
(
y
=
0
;
y
<
8
;
y
++
)
{
*
and_bits
=
*
xor_bits
=
0
;
for
(
x
=
0
;
x
<
8
;
x
++
)
{
if
(
grey
+
bayer_8x8
[
y
][
x
]
>
63
)
{
rop_mask
.
and
=
(
0xff
&
codes
.
a1
)
^
codes
.
a2
;
rop_mask
.
xor
=
(
0xff
&
codes
.
x1
)
^
codes
.
x2
;
}
else
{
rop_mask
.
and
=
(
0x00
&
codes
.
a1
)
^
codes
.
a2
;
rop_mask
.
xor
=
(
0x00
&
codes
.
x1
)
^
codes
.
x2
;
}
*
and_bits
|=
(
rop_mask
.
and
&
pixel_masks_1
[
x
]);
*
xor_bits
|=
(
rop_mask
.
xor
&
pixel_masks_1
[
x
]);
}
and_bits
+=
dib
->
stride
;
xor_bits
+=
dib
->
stride
;
}
}
static
void
create_dither_masks_null
(
const
dib_info
*
dib
,
int
rop2
,
COLORREF
color
,
rop_mask_bits
*
bits
)
{
}
static
inline
void
rop_codes_from_stretch_mode
(
int
mode
,
struct
rop_codes
*
codes
)
{
switch
(
mode
)
...
...
@@ -5460,6 +5640,7 @@ const primitive_funcs funcs_8888 =
pixel_to_colorref_888
,
convert_to_8888
,
create_rop_masks_32
,
create_dither_masks_null
,
stretch_row_32
,
shrink_row_32
};
...
...
@@ -5478,6 +5659,7 @@ const primitive_funcs funcs_32 =
pixel_to_colorref_masks
,
convert_to_32
,
create_rop_masks_32
,
create_dither_masks_null
,
stretch_row_32
,
shrink_row_32
};
...
...
@@ -5496,6 +5678,7 @@ const primitive_funcs funcs_24 =
pixel_to_colorref_888
,
convert_to_24
,
create_rop_masks_24
,
create_dither_masks_null
,
stretch_row_24
,
shrink_row_24
};
...
...
@@ -5514,6 +5697,7 @@ const primitive_funcs funcs_555 =
pixel_to_colorref_555
,
convert_to_555
,
create_rop_masks_16
,
create_dither_masks_null
,
stretch_row_16
,
shrink_row_16
};
...
...
@@ -5532,6 +5716,7 @@ const primitive_funcs funcs_16 =
pixel_to_colorref_masks
,
convert_to_16
,
create_rop_masks_16
,
create_dither_masks_null
,
stretch_row_16
,
shrink_row_16
};
...
...
@@ -5550,6 +5735,7 @@ const primitive_funcs funcs_8 =
pixel_to_colorref_colortable
,
convert_to_8
,
create_rop_masks_8
,
create_dither_masks_8
,
stretch_row_8
,
shrink_row_8
};
...
...
@@ -5568,6 +5754,7 @@ const primitive_funcs funcs_4 =
pixel_to_colorref_colortable
,
convert_to_4
,
create_rop_masks_4
,
create_dither_masks_4
,
stretch_row_4
,
shrink_row_4
};
...
...
@@ -5586,6 +5773,7 @@ const primitive_funcs funcs_1 =
pixel_to_colorref_colortable
,
convert_to_1
,
create_rop_masks_1
,
create_dither_masks_1
,
stretch_row_1
,
shrink_row_1
};
...
...
@@ -5604,6 +5792,7 @@ const primitive_funcs funcs_null =
pixel_to_colorref_null
,
convert_to_null
,
create_rop_masks_null
,
create_dither_masks_null
,
stretch_row_null
,
shrink_row_null
};
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