static void update_masks( dibdrv_physdev *pdev, INT rop ) { calc_and_xor_masks( rop, pdev->pen_color, &pdev->pen_and, &pdev->pen_xor ); update_brush_rop( pdev, rop ); if( GetBkMode( pdev->dev.hdc ) == OPAQUE ) calc_and_xor_masks( rop, pdev->bkgnd_color, &pdev->bkgnd_and, &pdev->bkgnd_xor ); }
void update_brush_rop( dibdrv_physdev *pdev, INT rop ) { pdev->brush_rop = rop; if(pdev->brush_style == BS_SOLID || pdev->brush_style == BS_HATCHED) calc_and_xor_masks(rop, pdev->brush_color, &pdev->brush_and, &pdev->brush_xor); free_pattern_brush_bits( pdev ); }
static BOOL create_pattern_brush_bits(dibdrv_physdev *pdev) { DWORD size = pdev->brush_dib.height * abs(pdev->brush_dib.stride); DWORD *brush_bits = pdev->brush_dib.bits; DWORD *and_bits, *xor_bits; assert(pdev->brush_and_bits == NULL); assert(pdev->brush_xor_bits == NULL); assert(pdev->brush_dib.stride > 0); and_bits = pdev->brush_and_bits = HeapAlloc(GetProcessHeap(), 0, size); xor_bits = pdev->brush_xor_bits = HeapAlloc(GetProcessHeap(), 0, size); if(!and_bits || !xor_bits) { ERR("Failed to create pattern brush bits\n"); free_pattern_brush_bits( pdev ); return FALSE; } while(size) { calc_and_xor_masks(pdev->brush_rop, *brush_bits++, and_bits++, xor_bits++); size -= 4; } return TRUE; }
/*********************************************************************** * dibdrv_SelectBrush */ HBRUSH CDECL dibdrv_SelectBrush( PHYSDEV dev, HBRUSH hbrush ) { PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSelectBrush ); dibdrv_physdev *pdev = get_dibdrv_pdev(dev); LOGBRUSH logbrush; TRACE("(%p, %p)\n", dev, hbrush); if (!GetObjectW( hbrush, sizeof(logbrush), &logbrush )) return 0; if (hbrush == GetStockObject( DC_BRUSH )) logbrush.lbColor = GetDCBrushColor( dev->hdc ); pdev->brush_style = logbrush.lbStyle; pdev->defer |= DEFER_BRUSH; free_pattern_brush( pdev ); switch(logbrush.lbStyle) { case BS_SOLID: pdev->brush_color = pdev->dib.funcs->colorref_to_pixel(&pdev->dib, logbrush.lbColor); calc_and_xor_masks(GetROP2(dev->hdc), pdev->brush_color, &pdev->brush_and, &pdev->brush_xor); pdev->brush_rects = solid_brush; pdev->defer &= ~DEFER_BRUSH; break; case BS_NULL: pdev->brush_rects = null_brush; pdev->defer &= ~DEFER_BRUSH; break; case BS_DIBPATTERN: { BITMAPINFOHEADER *bi = GlobalLock((HGLOBAL)logbrush.lbHatch); dib_info orig_dib; if(!bi) return NULL; if(init_dib_info_from_packed(&orig_dib, bi, LOWORD(logbrush.lbColor))) { copy_dib_color_info(&pdev->brush_dib, &pdev->dib); if(convert_dib(&pdev->brush_dib, &orig_dib)) { pdev->brush_rects = pattern_brush; pdev->defer &= ~DEFER_BRUSH; } free_dib_info(&orig_dib, FALSE); } GlobalUnlock((HGLOBAL)logbrush.lbHatch); break; } default: break; } return next->funcs->pSelectBrush( next, hbrush ); }
/*********************************************************************** * dibdrv_SetDCPenColor */ COLORREF CDECL dibdrv_SetDCPenColor( PHYSDEV dev, COLORREF color ) { PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetDCPenColor ); dibdrv_physdev *pdev = get_dibdrv_pdev(dev); if (GetCurrentObject(dev->hdc, OBJ_PEN) == GetStockObject( DC_PEN )) { pdev->pen_color = pdev->dib.funcs->colorref_to_pixel(&pdev->dib, color); calc_and_xor_masks(GetROP2(dev->hdc), pdev->pen_color, &pdev->pen_and, &pdev->pen_xor); } return next->funcs->pSetDCPenColor( next, color ); }
/*************************************************************************** * get_pen_bkgnd_masks * * Returns the pre-calculated bkgnd color masks unless the dib is 1 bpp. * In this case since there are several fg sources (pen, brush, text) * this makes pdev->bkgnd_color unusable. So here we take the inverse * of the relevant fg color (which is always set up correctly). */ static inline void get_pen_bkgnd_masks(const dibdrv_physdev *pdev, DWORD *and, DWORD *xor) { if(pdev->dib.bit_count != 1 || GetBkMode(pdev->dev.hdc) == TRANSPARENT) { *and = pdev->bkgnd_and; *xor = pdev->bkgnd_xor; } else { DWORD color = ~pdev->pen_color; if(pdev->pen_colorref == GetBkColor(pdev->dev.hdc)) color = pdev->pen_color; calc_and_xor_masks( GetROP2(pdev->dev.hdc), color, and, xor ); } }
/*********************************************************************** * dibdrv_SetDCBrushColor */ COLORREF CDECL dibdrv_SetDCBrushColor( PHYSDEV dev, COLORREF color ) { PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetDCBrushColor ); dibdrv_physdev *pdev = get_dibdrv_pdev(dev); if (GetCurrentObject(dev->hdc, OBJ_BRUSH) == GetStockObject( DC_BRUSH )) { pdev->brush_colorref = color; pdev->brush_color = get_fg_color( pdev, pdev->brush_colorref ); calc_and_xor_masks(GetROP2(dev->hdc), pdev->brush_color, &pdev->brush_and, &pdev->brush_xor); } return next->funcs->pSetDCBrushColor( next, color ); }
/*********************************************************************** * dibdrv_SetBkMode */ static INT dibdrv_SetBkMode( PHYSDEV dev, INT mode ) { PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetBkMode ); dibdrv_physdev *pdev = get_dibdrv_pdev(dev); if( mode == OPAQUE ) calc_and_xor_masks( GetROP2(dev->hdc), pdev->bkgnd_color, &pdev->bkgnd_and, &pdev->bkgnd_xor ); else { pdev->bkgnd_and = ~0u; pdev->bkgnd_xor = 0; } return next->funcs->pSetBkMode( next, mode ); }
/*********************************************************************** * dibdrv_SetBkColor */ static COLORREF dibdrv_SetBkColor( PHYSDEV dev, COLORREF color ) { PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetBkColor ); dibdrv_physdev *pdev = get_dibdrv_pdev(dev); pdev->bkgnd_color = get_pixel_color( pdev, color, FALSE ); if( GetBkMode(dev->hdc) == OPAQUE ) calc_and_xor_masks( GetROP2(dev->hdc), pdev->bkgnd_color, &pdev->bkgnd_and, &pdev->bkgnd_xor ); else { pdev->bkgnd_and = ~0u; pdev->bkgnd_xor = 0; } update_fg_colors( pdev ); /* Only needed in the 1 bpp case */ return next->funcs->pSetBkColor( next, color ); }
static inline void get_brush_bkgnd_masks(const dibdrv_physdev *pdev, DWORD *and, DWORD *xor) { if(GetBkMode(pdev->dev.hdc) == TRANSPARENT) { *and = pdev->bkgnd_and; *xor = pdev->bkgnd_xor; } else { DWORD color = pdev->bkgnd_color; if(pdev->dib.bit_count == 1) { if(pdev->brush_colorref == GetBkColor(pdev->dev.hdc)) color = pdev->brush_color; else color = ~pdev->brush_color; } calc_and_xor_masks( pdev->brush_rop, color, and, xor ); } }
static BOOL create_pattern_brush_bits(dibdrv_physdev *pdev) { DWORD size = pdev->brush_dib.height * abs(pdev->brush_dib.stride); DWORD *brush_bits = pdev->brush_dib.bits; DWORD *and_bits, *xor_bits; assert(pdev->brush_and_bits == NULL); assert(pdev->brush_xor_bits == NULL); and_bits = pdev->brush_and_bits = HeapAlloc(GetProcessHeap(), 0, size); xor_bits = pdev->brush_xor_bits = HeapAlloc(GetProcessHeap(), 0, size); if(!and_bits || !xor_bits) { ERR("Failed to create pattern brush bits\n"); free_pattern_brush_bits( pdev ); return FALSE; } if(pdev->brush_dib.stride < 0) brush_bits = (DWORD*)((BYTE*)brush_bits + (pdev->brush_dib.height - 1) * pdev->brush_dib.stride); while(size) { calc_and_xor_masks(pdev->brush_rop, *brush_bits++, and_bits++, xor_bits++); size -= 4; } if(pdev->brush_dib.stride < 0) { /* Update the bits ptrs if the dib is bottom up. The subtraction is because stride is -ve */ pdev->brush_and_bits = (BYTE*)pdev->brush_and_bits - (pdev->brush_dib.height - 1) * pdev->brush_dib.stride; pdev->brush_xor_bits = (BYTE*)pdev->brush_xor_bits - (pdev->brush_dib.height - 1) * pdev->brush_dib.stride; } return TRUE; }
/*********************************************************************** * dibdrv_SelectPen */ HPEN CDECL dibdrv_SelectPen( PHYSDEV dev, HPEN hpen ) { PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSelectPen ); dibdrv_physdev *pdev = get_dibdrv_pdev(dev); LOGPEN logpen; DWORD style; TRACE("(%p, %p)\n", dev, hpen); if (!GetObjectW( hpen, sizeof(logpen), &logpen )) { /* must be an extended pen */ EXTLOGPEN *elp; INT size = GetObjectW( hpen, 0, NULL ); if (!size) return 0; elp = HeapAlloc( GetProcessHeap(), 0, size ); GetObjectW( hpen, size, elp ); /* FIXME: add support for user style pens */ logpen.lopnStyle = elp->elpPenStyle; logpen.lopnWidth.x = elp->elpWidth; logpen.lopnWidth.y = 0; logpen.lopnColor = elp->elpColor; HeapFree( GetProcessHeap(), 0, elp ); } if (hpen == GetStockObject( DC_PEN )) logpen.lopnColor = GetDCPenColor( dev->hdc ); pdev->pen_colorref = logpen.lopnColor; pdev->pen_color = get_fg_color( pdev, pdev->pen_colorref ); calc_and_xor_masks(GetROP2(dev->hdc), pdev->pen_color, &pdev->pen_and, &pdev->pen_xor); pdev->pen_pattern = dash_patterns[PS_SOLID]; pdev->defer |= DEFER_PEN; style = logpen.lopnStyle & PS_STYLE_MASK; switch(style) { case PS_SOLID: if(logpen.lopnStyle & PS_GEOMETRIC) break; if(logpen.lopnWidth.x > 1) break; pdev->pen_line = solid_pen_line; pdev->defer &= ~DEFER_PEN; break; case PS_DASH: case PS_DOT: case PS_DASHDOT: case PS_DASHDOTDOT: if(logpen.lopnStyle & PS_GEOMETRIC) break; if(logpen.lopnWidth.x > 1) break; pdev->pen_line = dashed_pen_line; pdev->pen_pattern = dash_patterns[style]; pdev->defer &= ~DEFER_PEN; break; case PS_NULL: pdev->pen_line = null_pen_line; pdev->defer &= ~DEFER_PEN; break; default: break; } return next->funcs->pSelectPen( next, hpen ); }
/*********************************************************************** * dibdrv_SelectBrush */ HBRUSH dibdrv_SelectBrush( PHYSDEV dev, HBRUSH hbrush ) { PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSelectBrush ); dibdrv_physdev *pdev = get_dibdrv_pdev(dev); LOGBRUSH logbrush; TRACE("(%p, %p)\n", dev, hbrush); if (!GetObjectW( hbrush, sizeof(logbrush), &logbrush )) return 0; if (hbrush == GetStockObject( DC_BRUSH )) logbrush.lbColor = GetDCBrushColor( dev->hdc ); pdev->brush_style = logbrush.lbStyle; pdev->defer |= DEFER_BRUSH; free_pattern_brush( pdev ); switch(logbrush.lbStyle) { case BS_SOLID: pdev->brush_colorref = logbrush.lbColor; pdev->brush_color = get_fg_color( pdev, pdev->brush_colorref ); calc_and_xor_masks(GetROP2(dev->hdc), pdev->brush_color, &pdev->brush_and, &pdev->brush_xor); pdev->brush_rects = solid_brush; pdev->defer &= ~DEFER_BRUSH; break; case BS_NULL: pdev->brush_rects = null_brush; pdev->defer &= ~DEFER_BRUSH; break; case BS_DIBPATTERN: { BITMAPINFOHEADER *bi = GlobalLock((HGLOBAL)logbrush.lbHatch); dib_info orig_dib; WORD usage = LOWORD(logbrush.lbColor); HPALETTE pal = (usage == DIB_PAL_COLORS) ? GetCurrentObject(dev->hdc, OBJ_PAL) : NULL; if(!bi) return NULL; if(init_dib_info_from_packed(&orig_dib, bi, usage, pal)) { copy_dib_color_info(&pdev->brush_dib, &pdev->dib); if(convert_dib(&pdev->brush_dib, &orig_dib)) { pdev->brush_rects = pattern_brush; pdev->defer &= ~DEFER_BRUSH; } free_dib_info(&orig_dib); } GlobalUnlock((HGLOBAL)logbrush.lbHatch); break; } case BS_HATCHED: { if(logbrush.lbHatch > HS_DIAGCROSS) return 0; pdev->brush_hatch = logbrush.lbHatch; pdev->brush_colorref = logbrush.lbColor; pdev->brush_color = get_fg_color( pdev, pdev->brush_colorref ); calc_and_xor_masks(GetROP2(dev->hdc), pdev->brush_color, &pdev->brush_and, &pdev->brush_xor); pdev->brush_rects = pattern_brush; pdev->defer &= ~DEFER_BRUSH; break; } default: break; } return next->funcs->pSelectBrush( next, hbrush ); }