gdi32: Avoid computing grayscale glyph intensities when not needed.

This commit is contained in:
Alexandre Julliard 2012-11-30 17:24:05 +01:00
parent abdce5c2c8
commit 2d3385eec9
3 changed files with 40 additions and 57 deletions

View File

@ -245,8 +245,8 @@ extern void free_dib_info(dib_info *dib) DECLSPEC_HIDDEN;
extern void free_pattern_brush(dib_brush *brush) 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 COLORREF make_rgb_colorref( HDC hdc, const dib_info *dib, COLORREF color, BOOL *got_pixel, DWORD *pixel ) DECLSPEC_HIDDEN;
extern DWORD get_pixel_color( HDC hdc, const dib_info *dib, COLORREF color, BOOL mono_fixup ) DECLSPEC_HIDDEN;
extern int clip_rect_to_dib( const dib_info *dib, RECT *rc ) DECLSPEC_HIDDEN;
extern int get_clipped_rects( const dib_info *dib, const RECT *rc, HRGN clip, struct clipped_rects *clip_rects ) DECLSPEC_HIDDEN;
extern void add_clipped_bounds( dibdrv_physdev *dev, const RECT *rect, HRGN clip ) DECLSPEC_HIDDEN;

View File

@ -574,18 +574,18 @@ static struct cached_glyph *get_cached_glyph( struct cached_font *font, UINT ind
*
* See the comment above get_pen_bkgnd_masks
*/
static inline void get_text_bkgnd_masks( dibdrv_physdev *pdev, rop_mask *mask )
static inline void get_text_bkgnd_masks( HDC hdc, const dib_info *dib, rop_mask *mask )
{
COLORREF bg = GetBkColor( pdev->dev.hdc );
COLORREF bg = GetBkColor( hdc );
mask->and = 0;
if (pdev->dib.bit_count != 1)
mask->xor = get_pixel_color( pdev, bg, FALSE );
if (dib->bit_count != 1)
mask->xor = get_pixel_color( hdc, dib, bg, FALSE );
else
{
COLORREF fg = GetTextColor( pdev->dev.hdc );
mask->xor = get_pixel_color( pdev, fg, TRUE );
COLORREF fg = GetTextColor( hdc );
mask->xor = get_pixel_color( hdc, dib, fg, TRUE );
if (fg != bg) mask->xor = ~mask->xor;
}
}
@ -717,13 +717,14 @@ done:
}
static void render_string( HDC hdc, dib_info *dib, struct cached_font *font, INT x, INT y,
UINT flags, const WCHAR *str, UINT count, const INT *dx, DWORD text_color,
const struct intensity_range *ranges, const struct clipped_rects *clipped_rects,
RECT *bounds )
UINT flags, const WCHAR *str, UINT count, const INT *dx,
const struct clipped_rects *clipped_rects, RECT *bounds )
{
UINT i;
struct cached_glyph *glyph;
dib_info glyph_dib;
DWORD text_color;
struct intensity_range ranges[17];
glyph_dib.bit_count = get_glyph_depth( font->aa_flags );
glyph_dib.rect.left = 0;
@ -731,6 +732,11 @@ static void render_string( HDC hdc, dib_info *dib, struct cached_font *font, INT
glyph_dib.bits.is_copy = FALSE;
glyph_dib.bits.free = NULL;
text_color = get_pixel_color( hdc, dib, GetTextColor( hdc ), TRUE );
if (glyph_dib.bit_count == 8)
get_aa_ranges( dib->funcs->pixel_to_colorref( dib, text_color ), ranges );
EnterCriticalSection( &font_cache_cs );
for (i = 0; i < count; i++)
{
@ -770,10 +776,6 @@ BOOL render_aa_text_bitmapinfo( HDC hdc, BITMAPINFO *info, struct gdi_image_bits
UINT aa_flags, LPCWSTR str, UINT count, const INT *dx )
{
dib_info dib;
BOOL got_pixel;
COLORREF fg, bg;
DWORD fg_pixel, bg_pixel;
struct intensity_range glyph_intensities[17];
struct clipped_rects visrect;
struct cached_font *font;
@ -784,27 +786,16 @@ BOOL render_aa_text_bitmapinfo( HDC hdc, BITMAPINFO *info, struct gdi_image_bits
visrect.count = 1;
visrect.rects = &src->visrect;
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;
get_text_bkgnd_masks( hdc, &dib, &bkgnd_color );
dib.funcs->solid_rects( &dib, 1, &src->visrect, bkgnd_color.and, bkgnd_color.xor );
}
if (!(font = add_cached_font( hdc, GetCurrentObject( hdc, OBJ_FONT ), aa_flags ))) return FALSE;
render_string( hdc, &dib, font, x, y, flags, str, count, dx,
fg_pixel, glyph_intensities, &visrect, NULL );
render_string( hdc, &dib, font, x, y, flags, str, count, dx, &visrect, NULL );
release_cached_font( font );
return TRUE;
}
@ -817,10 +808,7 @@ BOOL dibdrv_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags,
{
dibdrv_physdev *pdev = get_dibdrv_pdev(dev);
struct clipped_rects clipped_rects;
DC *dc;
RECT bounds;
DWORD text_color;
struct intensity_range ranges[17];
if (!pdev->font) return FALSE;
@ -830,7 +818,7 @@ BOOL dibdrv_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags,
if (flags & ETO_OPAQUE)
{
rop_mask bkgnd_color;
get_text_bkgnd_masks( pdev, &bkgnd_color );
get_text_bkgnd_masks( dev->hdc, &pdev->dib, &bkgnd_color );
add_bounds_rect( &bounds, rect );
get_clipped_rects( &pdev->dib, rect, pdev->clip, &clipped_rects );
pdev->dib.funcs->solid_rects( &pdev->dib, clipped_rects.count, clipped_rects.rects,
@ -851,13 +839,8 @@ BOOL dibdrv_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags,
}
if (!clipped_rects.count) goto done;
text_color = get_pixel_color( pdev, GetTextColor( pdev->dev.hdc ), TRUE );
get_aa_ranges( pdev->dib.funcs->pixel_to_colorref( &pdev->dib, text_color ), ranges );
dc = get_dc_ptr( dev->hdc );
render_string( dev->hdc, &pdev->dib, pdev->font, x, y, flags, str, count, dx,
text_color, ranges, &clipped_rects, &bounds );
release_dc_ptr( dc );
&clipped_rects, &bounds );
done:
add_clipped_bounds( pdev, &bounds, pdev->clip );
@ -975,7 +958,7 @@ static void fill_row( dib_info *dib, HRGN clip, RECT *row, DWORD pixel, UINT typ
BOOL dibdrv_ExtFloodFill( PHYSDEV dev, INT x, INT y, COLORREF color, UINT type )
{
dibdrv_physdev *pdev = get_dibdrv_pdev( dev );
DWORD pixel = get_pixel_color( pdev, color, FALSE );
DWORD pixel = get_pixel_color( dev->hdc, &pdev->dib, color, FALSE );
RECT row;
HRGN rgn;
@ -1008,7 +991,7 @@ COLORREF dibdrv_GetNearestColor( PHYSDEV dev, COLORREF color )
TRACE( "(%p, %08x)\n", dev, color );
pixel = get_pixel_color( pdev, color, FALSE );
pixel = get_pixel_color( dev->hdc, &pdev->dib, color, FALSE );
return pdev->dib.funcs->pixel_to_colorref( &pdev->dib, pixel );
}
@ -1481,7 +1464,7 @@ COLORREF dibdrv_SetPixel( PHYSDEV dev, INT x, INT y, COLORREF color )
add_clipped_bounds( pdev, &rect, pdev->clip );
/* SetPixel doesn't do the 1bpp massaging like other fg colors */
pixel = get_pixel_color( pdev, color, FALSE );
pixel = get_pixel_color( dev->hdc, &pdev->dib, color, FALSE );
color = pdev->dib.funcs->pixel_to_colorref( &pdev->dib, pixel );
if (!get_clipped_rects( &pdev->dib, &rect, pdev->clip, &clipped_rects )) return color;

View File

@ -135,7 +135,7 @@ static inline BOOL rgbquad_equal(const RGBQUAD *a, const RGBQUAD *b)
return FALSE;
}
COLORREF make_rgb_colorref( HDC hdc, dib_info *dib, COLORREF color, BOOL *got_pixel, DWORD *pixel )
COLORREF make_rgb_colorref( HDC hdc, const dib_info *dib, COLORREF color, BOOL *got_pixel, DWORD *pixel )
{
*pixel = 0;
*got_pixel = FALSE;
@ -172,7 +172,7 @@ COLORREF make_rgb_colorref( HDC hdc, dib_info *dib, COLORREF color, BOOL *got_pi
* Otherwise the bg color is mapped to the closest entry in the table and
* the fg takes the other one.
*/
DWORD get_pixel_color( dibdrv_physdev *pdev, COLORREF color, BOOL mono_fixup )
DWORD get_pixel_color( HDC hdc, const dib_info *dib, COLORREF color, BOOL mono_fixup )
{
RGBQUAD fg_quad;
BOOL got_pixel;
@ -180,21 +180,21 @@ DWORD get_pixel_color( dibdrv_physdev *pdev, COLORREF color, BOOL mono_fixup )
COLORREF rgb_ref;
const RGBQUAD *color_table;
rgb_ref = make_rgb_colorref( pdev->dev.hdc, &pdev->dib, color, &got_pixel, &pixel );
rgb_ref = make_rgb_colorref( hdc, dib, color, &got_pixel, &pixel );
if (got_pixel) return pixel;
if (pdev->dib.bit_count != 1 || !mono_fixup)
return pdev->dib.funcs->colorref_to_pixel( &pdev->dib, rgb_ref );
if (dib->bit_count != 1 || !mono_fixup)
return dib->funcs->colorref_to_pixel( dib, rgb_ref );
color_table = get_dib_color_table( &pdev->dib );
color_table = get_dib_color_table( dib );
fg_quad = rgbquad_from_colorref( rgb_ref );
if(rgbquad_equal(&fg_quad, color_table))
return 0;
if(rgbquad_equal(&fg_quad, color_table + 1))
return 1;
pixel = get_pixel_color( pdev, GetBkColor(pdev->dev.hdc), FALSE );
if (color == GetBkColor(pdev->dev.hdc)) return pixel;
pixel = get_pixel_color( hdc, dib, GetBkColor(hdc), FALSE );
if (color == GetBkColor(hdc)) return pixel;
else return !pixel;
}
@ -205,10 +205,10 @@ DWORD get_pixel_color( dibdrv_physdev *pdev, COLORREF color, BOOL mono_fixup )
* there are several fg sources (pen, brush, text) we take as bg the inverse
* of the relevant fg color (which is always set up correctly).
*/
static inline void get_color_masks( dibdrv_physdev *pdev, UINT rop, COLORREF colorref,
static inline void get_color_masks( HDC hdc, const dib_info *dib, UINT rop, COLORREF colorref,
INT bkgnd_mode, rop_mask *fg_mask, rop_mask *bg_mask )
{
DWORD color = get_pixel_color( pdev, colorref, TRUE );
DWORD color = get_pixel_color( hdc, dib, colorref, TRUE );
calc_rop_masks( rop, color, fg_mask );
@ -219,8 +219,8 @@ static inline void get_color_masks( dibdrv_physdev *pdev, UINT rop, COLORREF col
return;
}
if (pdev->dib.bit_count != 1) color = get_pixel_color( pdev, GetBkColor(pdev->dev.hdc), FALSE );
else if (colorref != GetBkColor(pdev->dev.hdc)) color = !color;
if (dib->bit_count != 1) color = get_pixel_color( hdc, dib, GetBkColor(hdc), FALSE );
else if (colorref != GetBkColor(hdc)) color = !color;
calc_rop_masks( rop, color, bg_mask );
}
@ -817,7 +817,7 @@ static BOOL solid_pen_lines(dibdrv_physdev *pdev, int num, POINT *pts, BOOL clos
{
DWORD color, and, xor;
color = get_pixel_color( pdev, pdev->pen_brush.colorref, TRUE );
color = get_pixel_color( pdev->dev.hdc, &pdev->dib, pdev->pen_brush.colorref, TRUE );
calc_and_xor_masks( GetROP2(pdev->dev.hdc), color, &and, &xor );
for (i = 0; i < num - 1; i++)
@ -1227,7 +1227,7 @@ static BOOL dashed_pen_lines(dibdrv_physdev *pdev, int num, POINT *pts, BOOL clo
}
else
{
get_color_masks( pdev, GetROP2(pdev->dev.hdc), pdev->pen_brush.colorref,
get_color_masks( pdev->dev.hdc, &pdev->dib, GetROP2(pdev->dev.hdc), pdev->pen_brush.colorref,
pdev->pen_is_ext ? TRANSPARENT : GetBkMode(pdev->dev.hdc),
&pdev->dash_masks[1], &pdev->dash_masks[0] );
@ -1760,7 +1760,7 @@ static BOOL solid_brush(dibdrv_physdev *pdev, dib_brush *brush, dib_info *dib,
int num, const RECT *rects, INT rop)
{
rop_mask brush_color;
DWORD color = get_pixel_color( pdev, brush->colorref, TRUE );
DWORD color = get_pixel_color( pdev->dev.hdc, &pdev->dib, brush->colorref, TRUE );
calc_rop_masks( rop, color, &brush_color );
dib->funcs->solid_rects( dib, num, rects, brush_color.and, brush_color.xor );
@ -1851,7 +1851,7 @@ static BOOL create_hatch_brush_bits(dibdrv_physdev *pdev, dib_brush *brush, BOOL
if (!init_hatch_brush( pdev, brush )) return FALSE;
get_color_masks( pdev, brush->rop, brush->colorref, GetBkMode(pdev->dev.hdc),
get_color_masks( pdev->dev.hdc, &pdev->dib, brush->rop, brush->colorref, GetBkMode(pdev->dev.hdc),
&fg_mask, &bg_mask );
if (brush->colorref & (1 << 24)) /* PALETTEINDEX */