BOOL get_brush_bitmap_info( HBRUSH handle, BITMAPINFO *info, void **bits, UINT *usage ) { BRUSHOBJ *brush; BOOL ret = FALSE; if (!(brush = GDI_GetObjPtr( handle, OBJ_BRUSH ))) return FALSE; if (!brush->info) { BITMAPOBJ *bmp = GDI_GetObjPtr( brush->bitmap, OBJ_BITMAP ); if (bmp) { store_bitmap_bits( brush, bmp ); GDI_ReleaseObj( brush->bitmap ); } } if (brush->info) { memcpy( info, brush->info, get_dib_info_size( brush->info, brush->usage )); if (info->bmiHeader.biBitCount <= 8 && !info->bmiHeader.biClrUsed) fill_default_color_table( info ); *bits = brush->bits.ptr; *usage = brush->usage; ret = TRUE; } GDI_ReleaseObj( handle ); return ret; }
/* * REGION_FrameRgn * Create a region that is a frame around another region. * Expand all rectangles by +/- x and y, then subtract original region. */ BOOL REGION_FrameRgn( HRGN hDest, HRGN hSrc, INT x, INT y ) { BOOL bRet; MWRGNOBJ *srcObj = (MWRGNOBJ*) GDI_GetObjPtr( hSrc, OBJ_REGION ); if (srcObj->rgn->numRects != 0) { MWRGNOBJ* destObj = (MWRGNOBJ*) GDI_GetObjPtr( hDest, OBJ_REGION ); RECT *pRect, *pEndRect; RECT tempRect; EMPTY_REGION( destObj->rgn ); pEndRect = srcObj->rgn->rects + srcObj->rgn->numRects; for(pRect = srcObj->rgn->rects; pRect < pEndRect; pRect++) { tempRect.left = pRect->left - x; tempRect.top = pRect->top - y; tempRect.right = pRect->right + x; tempRect.bottom = pRect->bottom + y; GdUnionRectWithRegion( &tempRect, destObj->rgn ); } GdSubtractRegion( destObj->rgn, destObj->rgn, srcObj->rgn ); bRet = TRUE; } else bRet = FALSE; return bRet; }
/* * Note: The behavior is correct even if src and dest regions are the same. */ INT WINAPI CombineRgn(HRGN hDest, HRGN hSrc1, HRGN hSrc2, INT mode) { MWRGNOBJ *destObj = (MWRGNOBJ *) GDI_GetObjPtr( hDest, OBJ_REGION); INT result = ERRORREGION; /*TRACE(region, " %04x,%04x -> %04x mode=%x\n", hSrc1, hSrc2, hDest,mode);*/ if (destObj) { MWRGNOBJ *src1Obj = (MWRGNOBJ *) GDI_GetObjPtr( hSrc1, OBJ_REGION); if (src1Obj) { /*TRACE(region, "dump:\n"); if(TRACE_ON(region)) REGION_DumpRegion(src1Obj->rgn);*/ if (mode == RGN_COPY) { GdCopyRegion( destObj->rgn, src1Obj->rgn ); result = destObj->rgn->type; } else { MWRGNOBJ *src2Obj = (MWRGNOBJ *) GDI_GetObjPtr( hSrc2, OBJ_REGION); if (src2Obj) { /*TRACE(region, "dump:\n"); if(TRACE_ON(region)) REGION_DumpRegion(src2Obj->rgn);*/ switch (mode) { case RGN_AND: GdIntersectRegion( destObj->rgn, src1Obj->rgn, src2Obj->rgn); break; case RGN_OR: GdUnionRegion( destObj->rgn, src1Obj->rgn, src2Obj->rgn ); break; case RGN_XOR: GdXorRegion( destObj->rgn, src1Obj->rgn, src2Obj->rgn ); break; case RGN_DIFF: GdSubtractRegion( destObj->rgn, src1Obj->rgn, src2Obj->rgn ); break; } result = destObj->rgn->type; } } } /*TRACE(region, "dump:\n"); if(TRACE_ON(region)) REGION_DumpRegion(destObj->rgn);*/ } return result; }
BOOL WINAPI EqualRgn( HRGN hrgn1, HRGN hrgn2 ) { MWRGNOBJ *obj1, *obj2; if ((obj1 = (MWRGNOBJ *) GDI_GetObjPtr( hrgn1, OBJ_REGION ))) if ((obj2 = (MWRGNOBJ *) GDI_GetObjPtr( hrgn2, OBJ_REGION ))) return GdEqualRegion(obj1->rgn, obj2->rgn); return FALSE; }
static BOOL copy_bitmap( BRUSHOBJ *brush, HBITMAP bitmap ) { BITMAPINFO *info; BITMAPOBJ *bmp = GDI_GetObjPtr( bitmap, OBJ_BITMAP ); if (!bmp) return FALSE; if (!bmp->dib) { if ((brush->bitmap = CreateBitmap( bmp->bitmap.bmWidth, bmp->bitmap.bmHeight, bmp->bitmap.bmPlanes, bmp->bitmap.bmBitsPixel, NULL ))) { if (bmp->funcs->pCopyBitmap( bitmap, brush->bitmap )) { BITMAPOBJ *copy = GDI_GetObjPtr( brush->bitmap, OBJ_BITMAP ); copy->funcs = bmp->funcs; GDI_ReleaseObj( copy ); } else { DeleteObject( brush->bitmap ); brush->bitmap = 0; } } GDI_ReleaseObj( bitmap ); return brush->bitmap != 0; } info = HeapAlloc( GetProcessHeap(), 0, get_dib_info_size( (BITMAPINFO *)&bmp->dib->dsBmih, DIB_RGB_COLORS )); if (!info) goto done; info->bmiHeader = bmp->dib->dsBmih; if (info->bmiHeader.biCompression == BI_BITFIELDS) memcpy( &info->bmiHeader + 1, bmp->dib->dsBitfields, sizeof(bmp->dib->dsBitfields) ); else if (info->bmiHeader.biClrUsed) memcpy( &info->bmiHeader + 1, bmp->color_table, info->bmiHeader.biClrUsed * sizeof(RGBQUAD) ); if (!(brush->bits.ptr = HeapAlloc( GetProcessHeap(), 0, info->bmiHeader.biSizeImage ))) { HeapFree( GetProcessHeap(), 0, info ); goto done; } memcpy( brush->bits.ptr, bmp->dib->dsBm.bmBits, info->bmiHeader.biSizeImage ); brush->bits.is_copy = TRUE; brush->bits.free = free_heap_bits; brush->info = info; brush->usage = DIB_RGB_COLORS; done: GDI_ReleaseObj( bitmap ); return brush->info != NULL; }
/*********************************************************************** * BRUSH_SelectObject */ static HGDIOBJ BRUSH_SelectObject( HGDIOBJ handle, HDC hdc ) { BRUSHOBJ *brush; HGDIOBJ ret = 0; DC *dc = get_dc_ptr( hdc ); if (!dc) { SetLastError( ERROR_INVALID_HANDLE ); return 0; } if ((brush = GDI_GetObjPtr( handle, OBJ_BRUSH ))) { PHYSDEV physdev = GET_DC_PHYSDEV( dc, pSelectBrush ); HBITMAP bitmap = brush->bitmap; BITMAPINFO *info; void *bits; UINT usage; if (bitmap && !brush->info) { BITMAPOBJ *bmp = GDI_GetObjPtr( bitmap, OBJ_BITMAP ); /* fetch the bitmap bits if we are selecting into a different type of DC */ if (bmp && bmp->funcs != physdev->funcs) store_bitmap_bits( brush, bmp ); GDI_ReleaseObj( bitmap ); } info = brush->info; bits = brush->bits.ptr; usage = brush->usage; GDI_inc_ref_count( handle ); GDI_ReleaseObj( handle ); if (!physdev->funcs->pSelectBrush( physdev, handle, bitmap, info, bits, usage )) { GDI_dec_ref_count( handle ); } else { ret = dc->hBrush; dc->hBrush = handle; GDI_dec_ref_count( ret ); } } release_dc_ptr( dc ); return ret; }
HRGN WINAPI ExtCreateRegion(const XFORM* lpXform, DWORD dwCount, const RGNDATA* rgndata) { HRGN hrgn = CreateRectRgn(0, 0, 0, 0); MWRGNOBJ *obj = (MWRGNOBJ *) GDI_GetObjPtr( hrgn, OBJ_REGION ); RECT *pCurRect, *pEndRect; /*TRACE(region, " %p %ld %p. Returning %04x\n", lpXform, dwCount, rgndata, hrgn);*/ if(!hrgn) { WARN(region, "Can't create a region!\n"); return 0; } if(lpXform) WARN(region, "Xform not implemented - ignoring\n"); if(rgndata->rdh.iType != RDH_RECTANGLES) { WARN(region, "Type not RDH_RECTANGLES\n"); DeleteObject( hrgn ); return 0; } pEndRect = (RECT *)rgndata->Buffer + rgndata->rdh.nCount; for(pCurRect = (RECT *)rgndata->Buffer; pCurRect < pEndRect; pCurRect++) GdUnionRectWithRegion( pCurRect, obj->rgn ); return hrgn; }
DWORD WINAPI GetRegionData(HRGN hrgn, DWORD count, LPRGNDATA rgndata) { DWORD size; MWRGNOBJ *obj = (MWRGNOBJ *) GDI_GetObjPtr( hrgn, OBJ_REGION ); MWCLIPREGION *rgn; /*TRACE(region," %04x count = %ld, rgndata = %p\n", hrgn, count, rgndata);*/ if(!obj) return 0; rgn = obj->rgn; size = rgn->numRects * sizeof(RECT); if(count < (size + sizeof(RGNDATAHEADER)) || rgndata == NULL) return size + sizeof(RGNDATAHEADER); rgndata->rdh.dwSize = sizeof(RGNDATAHEADER); rgndata->rdh.iType = RDH_RECTANGLES; rgndata->rdh.nCount = rgn->numRects; rgndata->rdh.nRgnSize = size; rgndata->rdh.rcBound.left = rgn->extents.left; rgndata->rdh.rcBound.top = rgn->extents.top; rgndata->rdh.rcBound.right = rgn->extents.right; rgndata->rdh.rcBound.bottom = rgn->extents.bottom; memcpy( rgndata->Buffer, rgn->rects, size ); return 1; }
/*********************************************************************** * EMFDRV_SelectObject */ HGDIOBJ EMFDRV_SelectObject( DC *dc, HGDIOBJ handle ) { GDIOBJHDR * ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE ); HGDIOBJ ret = 0; if (!ptr) return 0; TRACE("hdc=%04x %04x\n", dc->hSelf, handle ); switch(GDIMAGIC(ptr->wMagic)) { case PEN_MAGIC: ret = EMFDRV_PEN_SelectObject( dc, handle ); break; case BRUSH_MAGIC: ret = EMFDRV_BRUSH_SelectObject( dc, handle ); break; case FONT_MAGIC: ret = EMFDRV_FONT_SelectObject( dc, handle ); break; case BITMAP_MAGIC: ret = EMFDRV_BITMAP_SelectObject( dc, handle ); break; } GDI_ReleaseObj( handle ); return ret; }
/*********************************************************************** * GDIRealizePalette (Not a Windows API) */ UINT WINAPI GDIRealizePalette( HDC hdc ) { UINT realized = 0; DC* dc = get_dc_ptr( hdc ); if (!dc) return 0; TRACE("%p...\n", hdc ); if( dc->hPalette == GetStockObject( DEFAULT_PALETTE )) { PHYSDEV physdev = GET_DC_PHYSDEV( dc, pRealizeDefaultPalette ); realized = physdev->funcs->pRealizeDefaultPalette( physdev ); } else if (InterlockedExchangePointer( (void **)&hLastRealizedPalette, dc->hPalette ) != dc->hPalette) { PHYSDEV physdev = GET_DC_PHYSDEV( dc, pRealizePalette ); PALETTEOBJ *palPtr = GDI_GetObjPtr( dc->hPalette, OBJ_PAL ); if (palPtr) { realized = physdev->funcs->pRealizePalette( physdev, dc->hPalette, (dc->hPalette == hPrimaryPalette) ); palPtr->unrealize = physdev->funcs->pUnrealizePalette; GDI_ReleaseObj( dc->hPalette ); } } else TRACE(" skipping (hLastRealizedPalette = %p)\n", hLastRealizedPalette); release_dc_ptr( dc ); TRACE(" realized %i colors.\n", realized ); return realized; }
/*********************************************************************** * GetNearestPaletteIndex [GDI32.@] * * Gets palette index for color. * * NOTES * Should index be initialized to CLR_INVALID instead of 0? * * RETURNS * Success: Index of entry in logical palette * Failure: CLR_INVALID */ UINT WINAPI GetNearestPaletteIndex( HPALETTE hpalette, /* [in] Handle of logical color palette */ COLORREF color) /* [in] Color to be matched */ { PALETTEOBJ* palObj = GDI_GetObjPtr( hpalette, OBJ_PAL ); UINT index = 0; if( palObj ) { int i, diff = 0x7fffffff; int r,g,b; PALETTEENTRY* entry = palObj->entries; for( i = 0; i < palObj->count && diff ; i++, entry++) { r = entry->peRed - GetRValue(color); g = entry->peGreen - GetGValue(color); b = entry->peBlue - GetBValue(color); r = r*r + g*g + b*b; if( r < diff ) { index = i; diff = r; } } GDI_ReleaseObj( hpalette ); } TRACE("(%p,%06x): returning %d\n", hpalette, color, index ); return index; }
/*********************************************************************** * SetPaletteEntries [GDI32.@] * * Sets color values for range in palette. * * RETURNS * Success: Number of entries that were set * Failure: 0 */ UINT WINAPI SetPaletteEntries( HPALETTE hpalette, /* [in] Handle of logical palette */ UINT start, /* [in] Index of first entry to set */ UINT count, /* [in] Number of entries to set */ const PALETTEENTRY *entries) /* [in] Address of array of structures */ { PALETTEOBJ * palPtr; UINT numEntries; TRACE("hpal=%p,start=%i,count=%i\n",hpalette,start,count ); hpalette = get_full_gdi_handle( hpalette ); if (hpalette == GetStockObject(DEFAULT_PALETTE)) return 0; palPtr = GDI_GetObjPtr( hpalette, OBJ_PAL ); if (!palPtr) return 0; numEntries = palPtr->count; if (start >= numEntries) { GDI_ReleaseObj( hpalette ); return 0; } if (start+count > numEntries) count = numEntries - start; memcpy( &palPtr->entries[start], entries, count * sizeof(PALETTEENTRY) ); GDI_ReleaseObj( hpalette ); UnrealizeObject( hpalette ); return count; }
/*********************************************************************** * GetPaletteEntries [GDI32.@] * * Retrieves palette entries. * * RETURNS * Success: Number of entries from logical palette * Failure: 0 */ UINT WINAPI GetPaletteEntries( HPALETTE hpalette, /* [in] Handle of logical palette */ UINT start, /* [in] First entry to receive */ UINT count, /* [in] Number of entries to receive */ LPPALETTEENTRY entries) /* [out] Address of array receiving entries */ { PALETTEOBJ * palPtr; UINT numEntries; TRACE("hpal = %p, count=%i\n", hpalette, count ); palPtr = GDI_GetObjPtr( hpalette, OBJ_PAL ); if (!palPtr) return 0; /* NOTE: not documented but test show this to be the case */ if (count == 0) { count = palPtr->count; } else { numEntries = palPtr->count; if (start+count > numEntries) count = numEntries - start; if (entries) { if (start >= numEntries) count = 0; else memcpy( entries, &palPtr->entries[start], count * sizeof(PALETTEENTRY) ); } } GDI_ReleaseObj( hpalette ); return count; }
/*********************************************************************** * BITMAP_SetOwnerDC * * Set the type of DC that owns the bitmap. This is used when the * bitmap is selected into a device to initialize the bitmap function * table. */ BOOL BITMAP_SetOwnerDC( HBITMAP hbitmap, DC *dc ) { BITMAPOBJ *bitmap; BOOL ret; /* never set the owner of the stock bitmap since it can be selected in multiple DCs */ if (hbitmap == GetStockObject(DEFAULT_BITMAP)) return TRUE; if (!(bitmap = GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ))) return FALSE; ret = TRUE; if (!bitmap->funcs) /* not owned by a DC yet */ { if (dc->funcs->pCreateBitmap) ret = dc->funcs->pCreateBitmap( dc->physDev, hbitmap, bitmap->bitmap.bmBits ); if (ret) bitmap->funcs = dc->funcs; } else if (bitmap->funcs != dc->funcs) { FIXME( "Trying to select bitmap %p in different DC type\n", hbitmap ); ret = FALSE; } GDI_ReleaseObj( hbitmap ); return ret; }
/*********************************************************************** * BITMAP_GetObject */ static INT BITMAP_GetObject( HGDIOBJ handle, INT count, LPVOID buffer ) { INT ret; BITMAPOBJ *bmp = GDI_GetObjPtr( handle, OBJ_BITMAP ); if (!bmp) return 0; if (!buffer) ret = sizeof(BITMAP); else if (count < sizeof(BITMAP)) ret = 0; else if (bmp->dib) { if (count >= sizeof(DIBSECTION)) { DIBSECTION *dib = buffer; *dib = *bmp->dib; dib->dsBmih.biHeight = abs( dib->dsBmih.biHeight ); ret = sizeof(DIBSECTION); } else /* if (count >= sizeof(BITMAP)) */ { DIBSECTION *dib = bmp->dib; memcpy( buffer, &dib->dsBm, sizeof(BITMAP) ); ret = sizeof(BITMAP); } } else { memcpy( buffer, &bmp->bitmap, sizeof(BITMAP) ); ((BITMAP *) buffer)->bmBits = NULL; ret = sizeof(BITMAP); } GDI_ReleaseObj( handle ); return ret; }
/*********************************************************************** * BITMAP_SetOwnerDC * * Set the type of DC that owns the bitmap. This is used when the * bitmap is selected into a device to initialize the bitmap function * table. */ static BOOL BITMAP_SetOwnerDC( HBITMAP hbitmap, PHYSDEV physdev ) { BITMAPOBJ *bitmap; BOOL ret = TRUE; /* never set the owner of the stock bitmap since it can be selected in multiple DCs */ if (hbitmap == GetStockObject(DEFAULT_BITMAP)) return TRUE; if (!(bitmap = GDI_GetObjPtr( hbitmap, OBJ_BITMAP ))) return FALSE; if (!bitmap->dib && bitmap->funcs != physdev->funcs) { /* we can only change from the null driver to some other driver */ if (bitmap->funcs == &null_driver) { if (physdev->funcs->pCreateBitmap) { ret = physdev->funcs->pCreateBitmap( physdev, hbitmap ); if (ret) { bitmap->funcs = physdev->funcs; set_initial_bitmap_bits( hbitmap, bitmap ); } } else bitmap->funcs = &dib_driver; /* use the DIB driver to emulate DDB support */ } else { FIXME( "Trying to select bitmap %p in different DC type\n", hbitmap ); ret = FALSE; } } GDI_ReleaseObj( hbitmap ); return ret; }
/*********************************************************************** * GetObject (GDI.82) */ INT16 WINAPI GetObject16( HANDLE16 handle, INT16 count, LPVOID buffer ) { GDIOBJHDR * ptr; INT16 result = 0; TRACE("%04x %d %p\n", handle, count, buffer ); if (!count) return 0; if (!(ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE ))) return 0; switch(GDIMAGIC(ptr->wMagic)) { case PEN_MAGIC: result = PEN_GetObject16( (PENOBJ *)ptr, count, buffer ); break; case BRUSH_MAGIC: result = BRUSH_GetObject16( (BRUSHOBJ *)ptr, count, buffer ); break; case BITMAP_MAGIC: result = BITMAP_GetObject16( (BITMAPOBJ *)ptr, count, buffer ); break; case FONT_MAGIC: result = FONT_GetObject16( (FONTOBJ *)ptr, count, buffer ); break; case PALETTE_MAGIC: result = PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer ); break; } GDI_ReleaseObj( handle ); return result; }
/*********************************************************************** * UnrealizeObject (GDI32.@) */ BOOL WINAPI UnrealizeObject( HGDIOBJ obj ) { BOOL result = TRUE; /* Check if object is valid */ GDIOBJHDR * header = GDI_GetObjPtr( obj, MAGIC_DONTCARE ); if (!header) return FALSE; TRACE("%04x\n", obj ); /* Unrealize object */ switch(GDIMAGIC(header->wMagic)) { case PALETTE_MAGIC: result = PALETTE_UnrealizeObject( obj, (PALETTEOBJ *)header ); break; case BRUSH_MAGIC: /* Windows resets the brush origin. We don't need to. */ break; } GDI_ReleaseObj( obj ); return result; }
/*********************************************************************** * GetObjectW (GDI32.@) */ INT WINAPI GetObjectW( HANDLE handle, INT count, LPVOID buffer ) { GDIOBJHDR * ptr; INT result = 0; TRACE("%08x %d %p\n", handle, count, buffer ); if (!count) return 0; if (!(ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE ))) return 0; switch(GDIMAGIC(ptr->wMagic)) { case PEN_MAGIC: result = PEN_GetObject( (PENOBJ *)ptr, count, buffer ); break; case BRUSH_MAGIC: result = BRUSH_GetObject( (BRUSHOBJ *)ptr, count, buffer ); break; case BITMAP_MAGIC: result = BITMAP_GetObject( (BITMAPOBJ *)ptr, count, buffer ); break; case FONT_MAGIC: result = FONT_GetObjectW( (FONTOBJ *)ptr, count, buffer ); break; case PALETTE_MAGIC: result = PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer ); break; default: FIXME("Magic %04x not implemented\n", GDIMAGIC(ptr->wMagic) ); break; } GDI_ReleaseObj( handle ); return result; }
INT WINAPI GetRgnBox( HRGN hrgn, LPRECT rect ) { MWRGNOBJ * obj = (MWRGNOBJ *) GDI_GetObjPtr( hrgn, OBJ_REGION ); if (obj) return GdGetRegionBox(obj->rgn, rect); return ERRORREGION; }
/*********************************************************************** * GetBitmapBits [GDI32.@] * * Copies bitmap bits of bitmap to buffer. * * RETURNS * Success: Number of bytes copied * Failure: 0 */ LONG WINAPI GetBitmapBits( HBITMAP hbitmap, /* [in] Handle to bitmap */ LONG count, /* [in] Number of bytes to copy */ LPVOID bits) /* [out] Pointer to buffer to receive bits */ { char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; BITMAPINFO *info = (BITMAPINFO *)buffer; struct gdi_image_bits src_bits; struct bitblt_coords src; int dst_stride, max, ret; BITMAPOBJ *bmp = GDI_GetObjPtr( hbitmap, OBJ_BITMAP ); if (!bmp) return 0; dst_stride = get_bitmap_stride( bmp->dib.dsBm.bmWidth, bmp->dib.dsBm.bmBitsPixel ); ret = max = dst_stride * bmp->dib.dsBm.bmHeight; if (!bits) goto done; if (count > max) count = max; ret = count; src.visrect.left = 0; src.visrect.right = bmp->dib.dsBm.bmWidth; src.visrect.top = 0; src.visrect.bottom = (count + dst_stride - 1) / dst_stride; src.x = src.y = 0; src.width = src.visrect.right - src.visrect.left; src.height = src.visrect.bottom - src.visrect.top; if (!get_image_from_bitmap( bmp, info, &src_bits, &src )) { const char *src_ptr = src_bits.ptr; int src_stride = get_dib_stride( info->bmiHeader.biWidth, info->bmiHeader.biBitCount ); /* GetBitmapBits returns 16-bit aligned data */ if (info->bmiHeader.biHeight > 0) { src_ptr += (info->bmiHeader.biHeight - 1) * src_stride; src_stride = -src_stride; } src_ptr += src.visrect.top * src_stride; if (src_stride == dst_stride) memcpy( bits, src_ptr, count ); else while (count > 0) { memcpy( bits, src_ptr, min( count, dst_stride ) ); src_ptr += src_stride; bits = (char *)bits + dst_stride; count -= dst_stride; } if (src_bits.free) src_bits.free( &src_bits ); } else ret = 0; done: GDI_ReleaseObj( hbitmap ); return ret; }
/*********************************************************************** * BITMAP_SelectObject */ static HGDIOBJ BITMAP_SelectObject( HGDIOBJ handle, HDC hdc ) { HGDIOBJ ret; BITMAPOBJ *bitmap; DC *dc; if (!(dc = get_dc_ptr( hdc ))) return 0; if (GetObjectType( hdc ) != OBJ_MEMDC) { ret = 0; goto done; } ret = dc->hBitmap; if (handle == dc->hBitmap) goto done; /* nothing to do */ if (!(bitmap = GDI_GetObjPtr( handle, BITMAP_MAGIC ))) { ret = 0; goto done; } if (bitmap->header.dwCount && (handle != GetStockObject(DEFAULT_BITMAP))) { WARN( "Bitmap already selected in another DC\n" ); GDI_ReleaseObj( handle ); ret = 0; goto done; } if (!bitmap->funcs && !BITMAP_SetOwnerDC( handle, dc )) { GDI_ReleaseObj( handle ); ret = 0; goto done; } if (dc->funcs->pSelectBitmap && !dc->funcs->pSelectBitmap( dc->physDev, handle )) { GDI_ReleaseObj( handle ); ret = 0; } else { dc->hBitmap = handle; GDI_inc_ref_count( handle ); dc->dirty = 0; SetRectRgn( dc->hVisRgn, 0, 0, bitmap->bitmap.bmWidth, bitmap->bitmap.bmHeight); GDI_ReleaseObj( handle ); DC_InitDC( dc ); GDI_dec_ref_count( ret ); } done: release_dc_ptr( dc ); return ret; }
/****************************************************************************** * GetBitmapDimensionEx [GDI32.@] * * Retrieves dimensions of a bitmap. * * RETURNS * Success: TRUE * Failure: FALSE */ BOOL WINAPI GetBitmapDimensionEx( HBITMAP hbitmap, /* [in] Handle to bitmap */ LPSIZE size) /* [out] Address of struct receiving dimensions */ { BITMAPOBJ * bmp = GDI_GetObjPtr( hbitmap, OBJ_BITMAP ); if (!bmp) return FALSE; *size = bmp->size; GDI_ReleaseObj( hbitmap ); return TRUE; }
BOOL WINAPI PtInRegion( HRGN hrgn, INT x, INT y ) { MWRGNOBJ * obj; obj = (MWRGNOBJ *) GDI_GetObjPtr( hrgn, OBJ_REGION ); if(!obj) return FALSE; return GdPtInRegion(obj->rgn, x, y); }
/* * Returns TRUE if rect is at least partly inside hrgn */ BOOL WINAPI RectInRegion( HRGN hrgn, const RECT *rect ) { MWRGNOBJ * obj; obj = (MWRGNOBJ *) GDI_GetObjPtr( hrgn, OBJ_REGION ); if(!obj) return FALSE; return (GdRectInRegion(obj->rgn, rect) == MWRECT_OUT? FALSE: TRUE); }
/*********************************************************************** * inc_ref_count * * Increment the reference count of a GDI object. */ inline static void inc_ref_count( HGDIOBJ handle ) { GDIOBJHDR *header; if ((header = GDI_GetObjPtr( handle, MAGIC_DONTCARE ))) { header->dwCount++; GDI_ReleaseObj( handle ); } }
/*********************************************************************** * DeleteObject (GDI32.@) */ BOOL WINAPI DeleteObject( HGDIOBJ obj ) { /* Check if object is valid */ GDIOBJHDR * header; if (HIWORD(obj)) return FALSE; if (!(header = GDI_GetObjPtr( obj, MAGIC_DONTCARE ))) return FALSE; if (!(header->wMagic & OBJECT_NOSYSTEM) && (header->wMagic >= FIRST_MAGIC) && (header->wMagic <= LAST_MAGIC)) { TRACE("Preserving system object %04x\n", obj); GDI_ReleaseObj( obj ); return TRUE; } if (header->dwCount) { TRACE("delayed for %04x because object in use, count %ld\n", obj, header->dwCount ); header->dwCount |= 0x80000000; /* mark for delete */ GDI_ReleaseObj( obj ); return TRUE; } TRACE("%04x\n", obj ); /* Delete object */ switch(GDIMAGIC(header->wMagic)) { case PEN_MAGIC: return GDI_FreeObject( obj, header ); case BRUSH_MAGIC: return BRUSH_DeleteObject( obj, (BRUSHOBJ*)header ); case FONT_MAGIC: return FONT_DeleteObject( obj, (FONTOBJ*)header ); case PALETTE_MAGIC: return PALETTE_DeleteObject(obj,(PALETTEOBJ*)header); case BITMAP_MAGIC: return BITMAP_DeleteObject( obj, (BITMAPOBJ*)header); case REGION_MAGIC: return REGION_DeleteObject( obj, (RGNOBJ*)header ); case DC_MAGIC: GDI_ReleaseObj( obj ); return DeleteDC(obj); case 0 : WARN("Already deleted\n"); break; default: WARN("Unknown magic number (%04x)\n",GDIMAGIC(header->wMagic)); } GDI_ReleaseObj( obj ); return FALSE; }
BOOL nulldrv_CopyBitmap( HBITMAP src, HBITMAP dst ) { BOOL ret = TRUE; BITMAPOBJ *src_bmp = GDI_GetObjPtr( src, OBJ_BITMAP ); if (!src_bmp) return FALSE; if (src_bmp->bitmap.bmBits) { BITMAPOBJ *dst_bmp = GDI_GetObjPtr( dst, OBJ_BITMAP ); int stride = get_dib_stride( dst_bmp->bitmap.bmWidth, dst_bmp->bitmap.bmBitsPixel ); dst_bmp->bitmap.bmBits = HeapAlloc( GetProcessHeap(), 0, dst_bmp->bitmap.bmHeight * stride ); if (dst_bmp->bitmap.bmBits) memcpy( dst_bmp->bitmap.bmBits, src_bmp->bitmap.bmBits, dst_bmp->bitmap.bmHeight * stride ); else ret = FALSE; GDI_ReleaseObj( dst ); } GDI_ReleaseObj( src ); return ret; }
/*********************************************************************** * GetObjectType (GDI32.@) */ DWORD WINAPI GetObjectType( HANDLE handle ) { GDIOBJHDR * ptr; INT result = 0; TRACE("%08x\n", handle ); if (!(ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE ))) return 0; switch(GDIMAGIC(ptr->wMagic)) { case PEN_MAGIC: result = OBJ_PEN; break; case BRUSH_MAGIC: result = OBJ_BRUSH; break; case BITMAP_MAGIC: result = OBJ_BITMAP; break; case FONT_MAGIC: result = OBJ_FONT; break; case PALETTE_MAGIC: result = OBJ_PAL; break; case REGION_MAGIC: result = OBJ_REGION; break; case DC_MAGIC: result = OBJ_DC; break; case META_DC_MAGIC: result = OBJ_METADC; break; case METAFILE_MAGIC: result = OBJ_METAFILE; break; case METAFILE_DC_MAGIC: result = OBJ_METADC; break; case ENHMETAFILE_MAGIC: result = OBJ_ENHMETAFILE; break; case ENHMETAFILE_DC_MAGIC: result = OBJ_ENHMETADC; break; default: FIXME("Magic %04x not implemented\n", GDIMAGIC(ptr->wMagic) ); break; } GDI_ReleaseObj( handle ); return result; }
/*********************************************************************** * IsGDIObject (GDI.462) * * returns type of object if valid (W95 system programming secrets p. 264-5) */ BOOL16 WINAPI IsGDIObject16( HGDIOBJ16 handle ) { UINT16 magic = 0; GDIOBJHDR *object = GDI_GetObjPtr( handle, MAGIC_DONTCARE ); if (object) { magic = GDIMAGIC(object->wMagic) - PEN_MAGIC + 1; GDI_ReleaseObj( handle ); } return magic; }