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
670f25cc
Commit
670f25cc
authored
Nov 17, 2011
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
gdi32: Add support for anti-aliasing in the null driver text output fallback.
parent
1b63d5a6
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
236 additions
and
19 deletions
+236
-19
dibdrv.h
dlls/gdi32/dibdrv/dibdrv.h
+1
-0
graphics.c
dlls/gdi32/dibdrv/graphics.c
+104
-9
objects.c
dlls/gdi32/dibdrv/objects.c
+8
-9
font.c
dlls/gdi32/font.c
+120
-1
gdi_private.h
dlls/gdi32/gdi_private.h
+3
-0
No files found.
dlls/gdi32/dibdrv/dibdrv.h
View file @
670f25cc
...
...
@@ -231,6 +231,7 @@ extern void free_dib_info(dib_info *dib) DECLSPEC_HIDDEN;
extern
void
free_pattern_brush
(
dibdrv_physdev
*
pdev
)
DECLSPEC_HIDDEN
;
extern
void
copy_dib_color_info
(
dib_info
*
dst
,
const
dib_info
*
src
)
DECLSPEC_HIDDEN
;
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
BOOL
brush_rects
(
dibdrv_physdev
*
pdev
,
int
num
,
const
RECT
*
rects
)
DECLSPEC_HIDDEN
;
extern
void
solid_rects
(
dib_info
*
dib
,
int
num
,
const
RECT
*
rects
,
const
rop_mask
*
color
,
HRGN
region
)
DECLSPEC_HIDDEN
;
...
...
dlls/gdi32/dibdrv/graphics.c
View file @
670f25cc
...
...
@@ -18,6 +18,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <assert.h>
#include "gdi_private.h"
#include "dibdrv.h"
...
...
@@ -90,19 +91,24 @@ static inline void get_range( BYTE aa, DWORD text_comp, BYTE *min_comp, BYTE *ma
*
max_comp
=
ramp
[
16
-
aa
]
+
((
0xff
-
ramp
[
16
-
aa
])
*
text_comp
)
/
0xff
;
}
void
update_aa_ranges
(
dibdrv_physdev
*
pdev
)
static
inline
void
get_aa_ranges
(
COLORREF
col
,
struct
intensity_range
intensities
[
17
]
)
{
int
i
;
COLORREF
text
=
pdev
->
dib
.
funcs
->
pixel_to_colorref
(
&
pdev
->
dib
,
pdev
->
text_color
);
for
(
i
=
0
;
i
<
17
;
i
++
)
{
get_range
(
i
,
GetRValue
(
text
),
&
pdev
->
glyph_intensities
[
i
].
r_min
,
&
pdev
->
glyph_
intensities
[
i
].
r_max
);
get_range
(
i
,
GetGValue
(
text
),
&
pdev
->
glyph_intensities
[
i
].
g_min
,
&
pdev
->
glyph_
intensities
[
i
].
g_max
);
get_range
(
i
,
GetBValue
(
text
),
&
pdev
->
glyph_intensities
[
i
].
b_min
,
&
pdev
->
glyph_
intensities
[
i
].
b_max
);
get_range
(
i
,
GetRValue
(
col
),
&
intensities
[
i
].
r_min
,
&
intensities
[
i
].
r_max
);
get_range
(
i
,
GetGValue
(
col
),
&
intensities
[
i
].
g_min
,
&
intensities
[
i
].
g_max
);
get_range
(
i
,
GetBValue
(
col
),
&
intensities
[
i
].
b_min
,
&
intensities
[
i
].
b_max
);
}
}
void
update_aa_ranges
(
dibdrv_physdev
*
pdev
)
{
COLORREF
text
=
pdev
->
dib
.
funcs
->
pixel_to_colorref
(
&
pdev
->
dib
,
pdev
->
text_color
);
get_aa_ranges
(
text
,
pdev
->
glyph_intensities
);
}
/**********************************************************************
* get_text_bkgnd_masks
*
...
...
@@ -168,7 +174,7 @@ static const int padding[4] = {0, 3, 2, 1};
* For non-antialiased bitmaps convert them to the 17-level format
* using only values 0 or 16.
*/
static
DWORD
get_glyph_bitmap
(
dibdrv_physdev
*
pdev
,
UINT
index
,
UINT
aa_flags
,
GLYPHMETRICS
*
metrics
,
static
DWORD
get_glyph_bitmap
(
HDC
hdc
,
UINT
index
,
UINT
aa_flags
,
GLYPHMETRICS
*
metrics
,
struct
gdi_image_bits
*
image
)
{
UINT
ggo_flags
=
aa_flags
|
GGO_GLYPH_INDEX
;
...
...
@@ -188,7 +194,7 @@ static DWORD get_glyph_bitmap( dibdrv_physdev *pdev, UINT index, UINT aa_flags,
for
(
i
=
0
;
i
<
sizeof
(
indices
)
/
sizeof
(
indices
[
0
]);
index
=
indices
[
++
i
])
{
ret
=
GetGlyphOutlineW
(
pdev
->
dev
.
hdc
,
index
,
ggo_flags
,
metrics
,
0
,
NULL
,
&
identity
);
ret
=
GetGlyphOutlineW
(
hdc
,
index
,
ggo_flags
,
metrics
,
0
,
NULL
,
&
identity
);
if
(
ret
!=
GDI_ERROR
)
break
;
}
...
...
@@ -203,7 +209,7 @@ static DWORD get_glyph_bitmap( dibdrv_physdev *pdev, UINT index, UINT aa_flags,
buf
=
HeapAlloc
(
GetProcessHeap
(),
0
,
size
);
if
(
!
buf
)
return
ERROR_OUTOFMEMORY
;
ret
=
GetGlyphOutlineW
(
pdev
->
dev
.
hdc
,
index
,
ggo_flags
,
metrics
,
size
,
buf
,
&
identity
);
ret
=
GetGlyphOutlineW
(
hdc
,
index
,
ggo_flags
,
metrics
,
size
,
buf
,
&
identity
);
if
(
ret
==
GDI_ERROR
)
{
HeapFree
(
GetProcessHeap
(),
0
,
buf
);
...
...
@@ -233,6 +239,95 @@ static DWORD get_glyph_bitmap( dibdrv_physdev *pdev, UINT index, UINT aa_flags,
return
ERROR_SUCCESS
;
}
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
)
{
dib_info
dib
;
UINT
i
;
DWORD
err
;
BOOL
got_pixel
;
COLORREF
fg
,
bg
;
DWORD
fg_pixel
,
bg_pixel
;
struct
intensity_range
glyph_intensities
[
17
];
assert
(
info
->
bmiHeader
.
biBitCount
>
8
);
/* mono and indexed formats don't support anti-aliasing */
if
(
!
init_dib_info_from_bitmapinfo
(
&
dib
,
info
,
bits
->
ptr
,
0
))
return
FALSE
;
fg
=
make_rgb_colorref
(
hdc
,
&
dib
,
GetTextColor
(
hdc
),
&
got_pixel
,
&
fg_pixel
);
if
(
!
got_pixel
)
fg_pixel
=
dib
.
funcs
->
colorref_to_pixel
(
&
dib
,
fg
);
get_aa_ranges
(
fg
,
glyph_intensities
);
if
(
flags
&
ETO_OPAQUE
)
{
rop_mask
bkgnd_color
;
bg
=
make_rgb_colorref
(
hdc
,
&
dib
,
GetBkColor
(
hdc
),
&
got_pixel
,
&
bg_pixel
);
if
(
!
got_pixel
)
bg_pixel
=
dib
.
funcs
->
colorref_to_pixel
(
&
dib
,
bg
);
bkgnd_color
.
and
=
0
;
bkgnd_color
.
xor
=
bg_pixel
;
solid_rects
(
&
dib
,
1
,
&
src
->
visrect
,
&
bkgnd_color
,
0
);
}
for
(
i
=
0
;
i
<
count
;
i
++
)
{
GLYPHMETRICS
metrics
;
struct
gdi_image_bits
image
;
err
=
get_glyph_bitmap
(
hdc
,
(
UINT
)
str
[
i
],
aa_flags
,
&
metrics
,
&
image
);
if
(
err
)
continue
;
if
(
image
.
ptr
)
{
RECT
rect
,
clipped_rect
;
POINT
src_origin
;
dib_info
glyph_dib
;
glyph_dib
.
bit_count
=
8
;
glyph_dib
.
width
=
metrics
.
gmBlackBoxX
;
glyph_dib
.
height
=
metrics
.
gmBlackBoxY
;
glyph_dib
.
stride
=
get_dib_stride
(
metrics
.
gmBlackBoxX
,
8
);
glyph_dib
.
bits
=
image
;
rect
.
left
=
x
+
metrics
.
gmptGlyphOrigin
.
x
;
rect
.
top
=
y
-
metrics
.
gmptGlyphOrigin
.
y
;
rect
.
right
=
rect
.
left
+
metrics
.
gmBlackBoxX
;
rect
.
bottom
=
rect
.
top
+
metrics
.
gmBlackBoxY
;
if
(
intersect_rect
(
&
clipped_rect
,
&
rect
,
&
src
->
visrect
))
{
src_origin
.
x
=
clipped_rect
.
left
-
rect
.
left
;
src_origin
.
y
=
clipped_rect
.
top
-
rect
.
top
;
dib
.
funcs
->
draw_glyph
(
&
dib
,
&
clipped_rect
,
&
glyph_dib
,
&
src_origin
,
fg_pixel
,
glyph_intensities
);
}
}
if
(
image
.
free
)
image
.
free
(
&
image
);
if
(
dx
)
{
if
(
flags
&
ETO_PDY
)
{
x
+=
dx
[
i
*
2
];
y
+=
dx
[
i
*
2
+
1
];
}
else
x
+=
dx
[
i
];
}
else
{
x
+=
metrics
.
gmCellIncX
;
y
+=
metrics
.
gmCellIncY
;
}
}
free_dib_info
(
&
dib
);
return
TRUE
;
}
/***********************************************************************
* dibdrv_ExtTextOut
*/
...
...
@@ -269,7 +364,7 @@ BOOL dibdrv_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags,
GLYPHMETRICS
metrics
;
struct
gdi_image_bits
image
;
err
=
get_glyph_bitmap
(
pdev
,
(
UINT
)
str
[
i
],
aa_flags
,
&
metrics
,
&
image
);
err
=
get_glyph_bitmap
(
dev
->
hdc
,
(
UINT
)
str
[
i
],
aa_flags
,
&
metrics
,
&
image
);
if
(
err
)
continue
;
if
(
image
.
ptr
)
draw_glyph
(
pdev
,
&
origin
,
&
metrics
,
&
image
);
...
...
dlls/gdi32/dibdrv/objects.c
View file @
670f25cc
...
...
@@ -123,12 +123,11 @@ static inline BOOL rgbquad_equal(const RGBQUAD *a, const RGBQUAD *b)
return
FALSE
;
}
static
COLORREF
make_rgb_colorref
(
dibdrv_physdev
*
pdev
,
COLORREF
color
,
BOOL
*
got_pixel
,
DWORD
*
pixel
)
COLORREF
make_rgb_colorref
(
HDC
hdc
,
dib_info
*
dib
,
COLORREF
color
,
BOOL
*
got_pixel
,
DWORD
*
pixel
)
{
BYTE
type
=
color
>>
24
;
WORD
index
=
LOWORD
(
color
);
HPALETTE
pal
=
GetCurrentObject
(
pdev
->
dev
.
hdc
,
OBJ_PAL
);
HPALETTE
pal
=
GetCurrentObject
(
hdc
,
OBJ_PAL
);
PALETTEENTRY
pal_ent
;
*
pixel
=
0
;
...
...
@@ -143,13 +142,13 @@ static COLORREF make_rgb_colorref( dibdrv_physdev *pdev, COLORREF color,
*
pixel
=
0
;
color
=
RGB
(
0
,
0
,
0
);
if
(
pdev
->
dib
.
bit_count
<=
8
&&
index
<
(
1
<<
pdev
->
dib
.
bit_count
))
if
(
dib
->
bit_count
<=
8
&&
index
<
(
1
<<
dib
->
bit_count
))
{
*
pixel
=
index
;
if
(
index
<
pdev
->
dib
.
color_table_size
)
color
=
RGB
(
pdev
->
dib
.
color_table
[
index
].
rgbRed
,
pdev
->
dib
.
color_table
[
index
].
rgbGreen
,
pdev
->
dib
.
color_table
[
index
].
rgbBlue
);
if
(
index
<
dib
->
color_table_size
)
color
=
RGB
(
dib
->
color_table
[
index
].
rgbRed
,
dib
->
color_table
[
index
].
rgbGreen
,
dib
->
color_table
[
index
].
rgbBlue
);
}
break
;
...
...
@@ -187,7 +186,7 @@ DWORD get_pixel_color( dibdrv_physdev *pdev, COLORREF color, BOOL mono_fixup )
DWORD
pixel
;
COLORREF
rgb_ref
;
rgb_ref
=
make_rgb_colorref
(
pdev
,
color
,
&
got_pixel
,
&
pixel
);
rgb_ref
=
make_rgb_colorref
(
pdev
->
dev
.
hdc
,
&
pdev
->
dib
,
color
,
&
got_pixel
,
&
pixel
);
if
(
got_pixel
)
return
pixel
;
if
(
pdev
->
dib
.
bit_count
!=
1
||
!
mono_fixup
)
...
...
dlls/gdi32/font.c
View file @
670f25cc
...
...
@@ -23,6 +23,7 @@
#include "config.h"
#include "wine/port.h"
#include <limits.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
...
...
@@ -1669,6 +1670,44 @@ static DWORD get_glyph_bitmap( HDC hdc, UINT index, UINT aa_flags,
}
/* helper for nulldrv_ExtTextOut */
static
RECT
get_total_extents
(
HDC
hdc
,
INT
x
,
INT
y
,
UINT
flags
,
UINT
aa_flags
,
LPCWSTR
str
,
UINT
count
,
const
INT
*
dx
)
{
int
i
;
RECT
rect
;
rect
.
left
=
rect
.
top
=
INT_MAX
;
rect
.
right
=
rect
.
bottom
=
INT_MIN
;
for
(
i
=
0
;
i
<
count
;
i
++
)
{
GLYPHMETRICS
metrics
;
if
(
get_glyph_bitmap
(
hdc
,
(
UINT
)
str
[
i
],
aa_flags
,
&
metrics
,
NULL
))
continue
;
rect
.
left
=
min
(
rect
.
left
,
x
+
metrics
.
gmptGlyphOrigin
.
x
);
rect
.
top
=
min
(
rect
.
top
,
y
-
metrics
.
gmptGlyphOrigin
.
y
);
rect
.
right
=
max
(
rect
.
right
,
x
+
metrics
.
gmptGlyphOrigin
.
x
+
(
int
)
metrics
.
gmBlackBoxX
);
rect
.
bottom
=
max
(
rect
.
bottom
,
y
-
metrics
.
gmptGlyphOrigin
.
y
+
(
int
)
metrics
.
gmBlackBoxY
);
if
(
dx
)
{
if
(
flags
&
ETO_PDY
)
{
x
+=
dx
[
i
*
2
];
y
+=
dx
[
i
*
2
+
1
];
}
else
x
+=
dx
[
i
];
}
else
{
x
+=
metrics
.
gmCellIncX
;
y
+=
metrics
.
gmCellIncY
;
}
}
return
rect
;
}
/* helper for nulldrv_ExtTextOut */
static
void
draw_glyph
(
HDC
hdc
,
INT
origin_x
,
INT
origin_y
,
const
GLYPHMETRICS
*
metrics
,
const
struct
gdi_image_bits
*
image
,
const
RECT
*
clip
)
{
...
...
@@ -1718,7 +1757,8 @@ static void draw_glyph( HDC hdc, INT origin_x, INT origin_y, const GLYPHMETRICS
BOOL
nulldrv_ExtTextOut
(
PHYSDEV
dev
,
INT
x
,
INT
y
,
UINT
flags
,
const
RECT
*
rect
,
LPCWSTR
str
,
UINT
count
,
const
INT
*
dx
)
{
UINT
i
;
DC
*
dc
=
get_nulldrv_dc
(
dev
);
UINT
aa_flags
,
i
;
DWORD
err
;
HGDIOBJ
orig
;
HPEN
pen
;
...
...
@@ -1740,6 +1780,85 @@ BOOL nulldrv_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags, const RECT *rect
if
(
!
count
)
return
TRUE
;
aa_flags
=
get_font_aa_flags
(
dev
->
hdc
);
if
(
aa_flags
!=
GGO_BITMAP
)
{
char
buffer
[
FIELD_OFFSET
(
BITMAPINFO
,
bmiColors
[
256
]
)];
BITMAPINFO
*
info
=
(
BITMAPINFO
*
)
buffer
;
struct
gdi_image_bits
bits
;
struct
bitblt_coords
src
,
dst
;
PHYSDEV
dst_dev
;
RECT
clip
;
dst_dev
=
GET_DC_PHYSDEV
(
dc
,
pPutImage
);
src
.
visrect
=
get_total_extents
(
dev
->
hdc
,
x
,
y
,
flags
,
aa_flags
,
str
,
count
,
dx
);
if
(
flags
&
ETO_CLIPPED
)
intersect_rect
(
&
src
.
visrect
,
&
src
.
visrect
,
rect
);
if
(
get_clip_box
(
dc
,
&
clip
))
intersect_rect
(
&
src
.
visrect
,
&
src
.
visrect
,
&
clip
);
if
(
is_rect_empty
(
&
src
.
visrect
))
return
TRUE
;
/* FIXME: check for ETO_OPAQUE and avoid GetImage */
src
.
x
=
src
.
visrect
.
left
;
src
.
y
=
src
.
visrect
.
top
;
src
.
width
=
src
.
visrect
.
right
-
src
.
visrect
.
left
;
src
.
height
=
src
.
visrect
.
bottom
-
src
.
visrect
.
top
;
dst
=
src
;
if
((
flags
&
ETO_OPAQUE
)
&&
(
src
.
visrect
.
left
>=
rect
->
left
)
&&
(
src
.
visrect
.
top
>=
rect
->
top
)
&&
(
src
.
visrect
.
right
<=
rect
->
right
)
&&
(
src
.
visrect
.
bottom
<=
rect
->
bottom
))
{
/* we can avoid the GetImage, just query the needed format */
memset
(
&
info
->
bmiHeader
,
0
,
sizeof
(
info
->
bmiHeader
)
);
info
->
bmiHeader
.
biSize
=
sizeof
(
info
->
bmiHeader
);
info
->
bmiHeader
.
biWidth
=
src
.
width
;
info
->
bmiHeader
.
biHeight
=
-
src
.
height
;
err
=
dst_dev
->
funcs
->
pPutImage
(
dst_dev
,
0
,
0
,
info
,
NULL
,
NULL
,
NULL
,
0
);
if
(
!
err
||
err
==
ERROR_BAD_FORMAT
)
{
/* make the source rectangle relative to the source bits */
src
.
x
=
src
.
y
=
0
;
src
.
visrect
.
left
=
src
.
visrect
.
top
=
0
;
src
.
visrect
.
right
=
src
.
width
;
src
.
visrect
.
bottom
=
src
.
height
;
bits
.
ptr
=
HeapAlloc
(
GetProcessHeap
(),
0
,
get_dib_image_size
(
info
));
if
(
!
bits
.
ptr
)
return
ERROR_OUTOFMEMORY
;
bits
.
is_copy
=
TRUE
;
bits
.
free
=
free_heap_bits
;
err
=
ERROR_SUCCESS
;
}
}
else
{
PHYSDEV
src_dev
=
GET_DC_PHYSDEV
(
dc
,
pGetImage
);
err
=
src_dev
->
funcs
->
pGetImage
(
src_dev
,
0
,
info
,
&
bits
,
&
src
);
if
(
!
err
&&
!
bits
.
is_copy
)
{
void
*
ptr
=
HeapAlloc
(
GetProcessHeap
(),
0
,
get_dib_image_size
(
info
));
if
(
!
ptr
)
{
if
(
bits
.
free
)
bits
.
free
(
&
bits
);
return
ERROR_OUTOFMEMORY
;
}
memcpy
(
ptr
,
bits
.
ptr
,
get_dib_image_size
(
info
));
if
(
bits
.
free
)
bits
.
free
(
&
bits
);
bits
.
ptr
=
ptr
;
bits
.
is_copy
=
TRUE
;
bits
.
free
=
free_heap_bits
;
}
}
if
(
!
err
)
{
/* make x,y relative to the image bits */
x
+=
src
.
visrect
.
left
-
dst
.
visrect
.
left
;
y
+=
src
.
visrect
.
top
-
dst
.
visrect
.
top
;
render_aa_text_bitmapinfo
(
dev
->
hdc
,
info
,
&
bits
,
&
src
,
x
,
y
,
flags
,
aa_flags
,
str
,
count
,
dx
);
err
=
dst_dev
->
funcs
->
pPutImage
(
dst_dev
,
0
,
0
,
info
,
&
bits
,
&
src
,
&
dst
,
SRCCOPY
);
if
(
bits
.
free
)
bits
.
free
(
&
bits
);
return
!
err
;
}
}
pen
=
CreatePen
(
PS_SOLID
,
1
,
GetTextColor
(
dev
->
hdc
)
);
orig
=
SelectObject
(
dev
->
hdc
,
pen
);
...
...
dlls/gdi32/gdi_private.h
View file @
670f25cc
...
...
@@ -266,6 +266,9 @@ 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
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
;
/* driver.c */
extern
const
struct
gdi_dc_funcs
null_driver
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