/*********************************************************************** * BRUSH_DitherColor */ static Pixmap BRUSH_DitherColor( COLORREF color, int depth) { /* X image for building dithered pixmap */ static XImage *ditherImage = NULL; static COLORREF prevColor = 0xffffffff; unsigned int x, y; Pixmap pixmap; GC gc = get_bitmap_gc(depth); wine_tsx11_lock(); if (!ditherImage) { ditherImage = XCreateImage( gdi_display, visual, depth, ZPixmap, 0, NULL, MATRIX_SIZE, MATRIX_SIZE, 32, 0 ); if (!ditherImage) { wine_tsx11_unlock(); ERR("Could not create dither image\n"); return 0; } ditherImage->data = HeapAlloc( GetProcessHeap(), 0, ditherImage->height * ditherImage->bytes_per_line ); } if (color != prevColor) { int r = GetRValue( color ) * DITHER_LEVELS; int g = GetGValue( color ) * DITHER_LEVELS; int b = GetBValue( color ) * DITHER_LEVELS; const int *pmatrix = dither_matrix; for (y = 0; y < MATRIX_SIZE; y++) { for (x = 0; x < MATRIX_SIZE; x++) { int d = *pmatrix++ * 256; int dr = ((r + d) / MATRIX_SIZE_2) / 256; int dg = ((g + d) / MATRIX_SIZE_2) / 256; int db = ((b + d) / MATRIX_SIZE_2) / 256; XPutPixel( ditherImage, x, y, PIXEL_VALUE(dr,dg,db) ); } } prevColor = color; } pixmap = XCreatePixmap( gdi_display, root_window, MATRIX_SIZE, MATRIX_SIZE, depth ); XPutImage( gdi_display, pixmap, gc, ditherImage, 0, 0, 0, 0, MATRIX_SIZE, MATRIX_SIZE ); wine_tsx11_unlock(); return pixmap; }
/*********************************************************************** * BRUSH_SelectPatternBrush */ static void BRUSH_SelectPatternBrush( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, X_PHYSBITMAP *physBitmap ) { BITMAP bitmap; GetObjectW( hbitmap, sizeof(bitmap), &bitmap ); wine_tsx11_lock(); if (physDev->brush.pixmap) XFreePixmap( gdi_display, physDev->brush.pixmap ); if ((physDev->depth == 1) && (physBitmap->depth != 1)) { /* Special case: a color pattern on a monochrome DC */ physDev->brush.pixmap = XCreatePixmap( gdi_display, root_window, bitmap.bmWidth, bitmap.bmHeight, 1); /* FIXME: should probably convert to monochrome instead */ XCopyPlane( gdi_display, physBitmap->pixmap, physDev->brush.pixmap, get_bitmap_gc(1), 0, 0, bitmap.bmWidth, bitmap.bmHeight, 0, 0, 1 ); } else { physDev->brush.pixmap = XCreatePixmap( gdi_display, root_window, bitmap.bmWidth, bitmap.bmHeight, physBitmap->depth ); XCopyArea( gdi_display, physBitmap->pixmap, physDev->brush.pixmap, get_bitmap_gc(physBitmap->depth), 0, 0, bitmap.bmWidth, bitmap.bmHeight, 0, 0 ); } wine_tsx11_unlock(); if (physBitmap->depth > 1) { physDev->brush.fillStyle = FillTiled; physDev->brush.pixel = 0; /* Ignored */ } else { physDev->brush.fillStyle = FillOpaqueStippled; physDev->brush.pixel = -1; /* Special case (see DC_SetupGCForBrush) */ } }
/*********************************************************************** * BRUSH_SelectPatternBrush */ static BOOL BRUSH_SelectPatternBrush( X11DRV_PDEVICE *physDev, HBITMAP hbitmap ) { BITMAP bitmap; X_PHYSBITMAP *physBitmap = X11DRV_get_phys_bitmap( hbitmap ); if (!physBitmap || !GetObjectW( hbitmap, sizeof(bitmap), &bitmap )) return FALSE; X11DRV_DIB_Lock( physBitmap, DIB_Status_GdiMod ); if ((physDev->depth == 1) && (physBitmap->pixmap_depth != 1)) { wine_tsx11_lock(); /* Special case: a color pattern on a monochrome DC */ physDev->brush.pixmap = XCreatePixmap( gdi_display, root_window, bitmap.bmWidth, bitmap.bmHeight, 1); /* FIXME: should probably convert to monochrome instead */ XCopyPlane( gdi_display, physBitmap->pixmap, physDev->brush.pixmap, get_bitmap_gc(1), 0, 0, bitmap.bmWidth, bitmap.bmHeight, 0, 0, 1 ); wine_tsx11_unlock(); } else { /* XRender is needed because of possible depth conversion */ X11DRV_XRender_CopyBrush(physDev, physBitmap, bitmap.bmWidth, bitmap.bmHeight); } X11DRV_DIB_Unlock( physBitmap, TRUE ); if (physBitmap->pixmap_depth > 1) { physDev->brush.fillStyle = FillTiled; physDev->brush.pixel = 0; /* Ignored */ } else { physDev->brush.fillStyle = FillOpaqueStippled; physDev->brush.pixel = -1; /* Special case (see DC_SetupGCForBrush) */ } return TRUE; }