Пример #1
0
Файл: brush.c Проект: bpon/wine
/* fetch the contents of the brush bitmap and cache them in the brush object */
static BOOL store_bitmap_bits( BRUSHOBJ *brush, BITMAPOBJ *bmp )
{
    const struct gdi_dc_funcs *funcs = get_bitmap_funcs( bmp );
    struct gdi_image_bits bits;
    struct bitblt_coords src;
    BITMAPINFO *info;

    if (!(info = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ))))
        return FALSE;

    src.visrect.left   = src.x = 0;
    src.visrect.top    = src.y = 0;
    src.visrect.right  = src.width = bmp->bitmap.bmWidth;
    src.visrect.bottom = src.height = bmp->bitmap.bmHeight;
    if (funcs->pGetImage( NULL, brush->bitmap, info, &bits, &src ))
    {
        HeapFree( GetProcessHeap(), 0, info );
        return FALSE;
    }

    /* release the unneeded space */
    HeapReAlloc( GetProcessHeap(), HEAP_REALLOC_IN_PLACE_ONLY, info,
                 get_dib_info_size( info, DIB_RGB_COLORS ));
    brush->info  = info;
    brush->bits  = bits;
    brush->usage = DIB_RGB_COLORS;
    return TRUE;
}
Пример #2
0
Файл: brush.c Проект: bpon/wine
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;
}
Пример #3
0
Файл: brush.c Проект: bpon/wine
/***********************************************************************
 *           CreateBrushIndirect    (GDI32.@)
 *
 * Create a logical brush with a given style, color or pattern.
 *
 * PARAMS
 *  brush [I] Pointer to a LOGBRUSH structure describing the desired brush.
 *
 * RETURNS
 *  A handle to the created brush, or a NULL handle if the brush cannot be 
 *  created.
 *
 * NOTES
 * - The brush returned should be freed by the caller using DeleteObject()
 *   when it is no longer required.
 * - Windows 95 and earlier cannot create brushes from bitmaps or DIBs larger
 *   than 8x8 pixels. If a larger bitmap is given, only a portion of the bitmap
 *   is used.
 */
HBRUSH WINAPI CreateBrushIndirect( const LOGBRUSH * brush )
{
    BRUSHOBJ * ptr;
    HBRUSH hbrush;
    HGLOBAL hmem = 0;

    if (!(ptr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ptr) ))) return 0;

    ptr->logbrush = *brush;

    switch (ptr->logbrush.lbStyle)
    {
    case BS_SOLID:
    case BS_HOLLOW:
    case BS_HATCHED:
        break;

    case BS_PATTERN8X8:
        ptr->logbrush.lbStyle = BS_PATTERN;
        /* fall through */
    case BS_PATTERN:
        if (!copy_bitmap( ptr, (HBITMAP)ptr->logbrush.lbHatch )) goto error;
        ptr->logbrush.lbColor = 0;
        break;

    case BS_DIBPATTERN:
        hmem = (HGLOBAL)ptr->logbrush.lbHatch;
        if (!(ptr->logbrush.lbHatch = (ULONG_PTR)GlobalLock( hmem ))) goto error;
        /* fall through */
    case BS_DIBPATTERNPT:
        ptr->usage = ptr->logbrush.lbColor;
        ptr->info = copy_packed_dib( (BITMAPINFO *)ptr->logbrush.lbHatch, ptr->usage );
        if (hmem) GlobalUnlock( hmem );
        if (!ptr->info) goto error;
        ptr->bits.ptr = (char *)ptr->info + get_dib_info_size( ptr->info, ptr->usage );
        ptr->logbrush.lbStyle = BS_DIBPATTERN;
        ptr->logbrush.lbColor = 0;
        break;

    case BS_DIBPATTERN8X8:
    case BS_MONOPATTERN:
    case BS_INDEXED:
    default:
        WARN( "invalid brush style %u\n", ptr->logbrush.lbStyle );
        goto error;
    }

    if ((hbrush = alloc_gdi_handle( &ptr->header, OBJ_BRUSH, &brush_funcs )))
    {
        TRACE("%p\n", hbrush);
        return hbrush;
    }

 error:
    if (ptr->bitmap) DeleteObject( ptr->bitmap );
    HeapFree( GetProcessHeap(), 0, ptr->info );
    HeapFree( GetProcessHeap(), 0, ptr );
    return 0;
}
Пример #4
0
/***********************************************************************
 *              macdrv_surface_get_bitmap_info
 */
static void *macdrv_surface_get_bitmap_info(struct window_surface *window_surface,
                                            BITMAPINFO *info)
{
    struct macdrv_window_surface *surface = get_mac_surface(window_surface);

    memcpy(info, &surface->info, get_dib_info_size(&surface->info, DIB_RGB_COLORS));
    return surface->bits;
}
Пример #5
0
INT EMFDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst, INT heightDst,
                          INT xSrc, INT ySrc, INT widthSrc, INT heightSrc, const void *bits,
                          BITMAPINFO *info, UINT wUsage, DWORD dwRop )
{
    EMRSTRETCHDIBITS *emr;
    BOOL ret;
    UINT bmi_size, emr_size;

    /* calculate the size of the colour table */
    bmi_size = get_dib_info_size(info, wUsage);

    emr_size = sizeof (EMRSTRETCHDIBITS) + bmi_size + info->bmiHeader.biSizeImage;
    emr = HeapAlloc(GetProcessHeap(), 0, emr_size );
    if (!emr) return 0;

    /* write a bitmap info header (with colours) to the record */
    memcpy( &emr[1], info, bmi_size);

    /* write bitmap bits to the record */
    memcpy ( ( (BYTE *) (&emr[1]) ) + bmi_size, bits, info->bmiHeader.biSizeImage);

    /* fill in the EMR header at the front of our piece of memory */
    emr->emr.iType = EMR_STRETCHDIBITS;
    emr->emr.nSize = emr_size;

    emr->xDest     = xDst;
    emr->yDest     = yDst;
    emr->cxDest    = widthDst;
    emr->cyDest    = heightDst;
    emr->dwRop     = dwRop;
    emr->xSrc      = xSrc; /* FIXME: only save the piece of the bitmap needed */
    emr->ySrc      = ySrc;

    emr->iUsageSrc    = wUsage;
    emr->offBmiSrc    = sizeof (EMRSTRETCHDIBITS);
    emr->cbBmiSrc     = bmi_size;
    emr->offBitsSrc   = emr->offBmiSrc + bmi_size; 
    emr->cbBitsSrc    = info->bmiHeader.biSizeImage;

    emr->cxSrc = widthSrc;
    emr->cySrc = heightSrc;

    emr->rclBounds.left   = xDst;
    emr->rclBounds.top    = yDst;
    emr->rclBounds.right  = xDst + widthDst;
    emr->rclBounds.bottom = yDst + heightDst;

    /* save the record we just created */
    ret = EMFDRV_WriteRecord( dev, &emr->emr );
    if(ret)
        EMFDRV_UpdateBBox( dev, &emr->rclBounds );

    HeapFree(GetProcessHeap(), 0, emr);

    return ret ? heightSrc : GDI_ERROR;
}
Пример #6
0
Файл: brush.c Проект: bpon/wine
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;
}
Пример #7
0
BOOL store_brush_pattern( LOGBRUSH *brush, struct brush_pattern *pattern )
{
    HGLOBAL hmem = 0;

    pattern->info = NULL;
    pattern->bits.free = NULL;

    switch (brush->lbStyle)
    {
    case BS_SOLID:
    case BS_HOLLOW:
        return TRUE;

    case BS_HATCHED:
        if (brush->lbHatch > HS_DIAGCROSS)
        {
            if (brush->lbHatch >= HS_API_MAX) return FALSE;
            brush->lbStyle = BS_SOLID;
            brush->lbHatch = 0;
        }
        return TRUE;

    case BS_PATTERN8X8:
        brush->lbStyle = BS_PATTERN;
        /* fall through */
    case BS_PATTERN:
        brush->lbColor = 0;
        return copy_bitmap( pattern, (HBITMAP)brush->lbHatch );

    case BS_DIBPATTERN:
        hmem = (HGLOBAL)brush->lbHatch;
        if (!(brush->lbHatch = (ULONG_PTR)GlobalLock( hmem ))) return FALSE;
        /* fall through */
    case BS_DIBPATTERNPT:
        pattern->usage = brush->lbColor;
        pattern->info = copy_packed_dib( (BITMAPINFO *)brush->lbHatch, pattern->usage );
        if (hmem) GlobalUnlock( hmem );
        if (!pattern->info) return FALSE;
        pattern->bits.ptr = (char *)pattern->info + get_dib_info_size( pattern->info, pattern->usage );
        brush->lbStyle = BS_DIBPATTERN;
        brush->lbColor = 0;
        return TRUE;

    case BS_DIBPATTERN8X8:
    case BS_MONOPATTERN:
    case BS_INDEXED:
    default:
        WARN( "invalid brush style %u\n", brush->lbStyle );
        return FALSE;
    }
}
Пример #8
0
static BOOL copy_bitmap( struct brush_pattern *brush, HBITMAP bitmap )
{
    char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256])];
    BITMAPINFO *info = (BITMAPINFO *)buffer;
    struct gdi_image_bits bits;
    struct bitblt_coords src;
    BITMAPOBJ *bmp = GDI_GetObjPtr( bitmap, OBJ_BITMAP );

    if (!bmp) return FALSE;

    src.visrect.left   = src.x = 0;
    src.visrect.top    = src.y = 0;
    src.visrect.right  = src.width = bmp->dib.dsBm.bmWidth;
    src.visrect.bottom = src.height = bmp->dib.dsBm.bmHeight;
    if (get_image_from_bitmap( bmp, info, &bits, &src )) goto done;

    brush->bits = bits;
    if (!bits.free)
    {
        if (!(brush->bits.ptr = HeapAlloc( GetProcessHeap(), 0, info->bmiHeader.biSizeImage ))) goto done;
        memcpy( brush->bits.ptr, bits.ptr, info->bmiHeader.biSizeImage );
        brush->bits.free = free_heap_bits;
    }

    if (!(brush->info = HeapAlloc( GetProcessHeap(), 0, get_dib_info_size( info, DIB_RGB_COLORS ))))
    {
        if (brush->bits.free) brush->bits.free( &brush->bits );
        goto done;
    }
    memcpy( brush->info, info, get_dib_info_size( info, DIB_RGB_COLORS ));
    brush->bits.is_copy = FALSE;  /* the bits can't be modified */
    brush->usage = DIB_RGB_COLORS;

done:
    GDI_ReleaseObj( bitmap );
    return brush->info != NULL;
}
Пример #9
0
INT EMFDRV_SetDIBitsToDevice( PHYSDEV dev, INT xDst, INT yDst, DWORD width, DWORD height,
                              INT xSrc, INT ySrc, UINT startscan, UINT lines,
                              LPCVOID bits, BITMAPINFO *info, UINT wUsage )
{
    EMRSETDIBITSTODEVICE* pEMR;
    DWORD bmiSize = get_dib_info_size(info, wUsage);
    DWORD size = sizeof(EMRSETDIBITSTODEVICE) + bmiSize + info->bmiHeader.biSizeImage;

    pEMR = HeapAlloc(GetProcessHeap(), 0, size);
    if (!pEMR) return 0;

    pEMR->emr.iType = EMR_SETDIBITSTODEVICE;
    pEMR->emr.nSize = size;
    pEMR->rclBounds.left = xDst;
    pEMR->rclBounds.top = yDst;
    pEMR->rclBounds.right = xDst + width - 1;
    pEMR->rclBounds.bottom = yDst + height - 1;
    pEMR->xDest = xDst;
    pEMR->yDest = yDst;
    pEMR->xSrc = xSrc;
    pEMR->ySrc = ySrc;
    pEMR->cxSrc = width;
    pEMR->cySrc = height;
    pEMR->offBmiSrc = sizeof(EMRSETDIBITSTODEVICE);
    pEMR->cbBmiSrc = bmiSize;
    pEMR->offBitsSrc = sizeof(EMRSETDIBITSTODEVICE) + bmiSize;
    pEMR->cbBitsSrc = info->bmiHeader.biSizeImage;
    pEMR->iUsageSrc = wUsage;
    pEMR->iStartScan = startscan;
    pEMR->cScans = lines;
    memcpy((BYTE*)pEMR + pEMR->offBmiSrc, info, bmiSize);
    memcpy((BYTE*)pEMR + pEMR->offBitsSrc, bits, info->bmiHeader.biSizeImage);

    if (EMFDRV_WriteRecord(dev, (EMR*)pEMR))
        EMFDRV_UpdateBBox(dev, &(pEMR->rclBounds));

    HeapFree( GetProcessHeap(), 0, pEMR);
    return lines;
}
Пример #10
0
/***********************************************************************
 *           EMFDRV_CreateBrushIndirect
 */
DWORD EMFDRV_CreateBrushIndirect( PHYSDEV dev, HBRUSH hBrush )
{
    DWORD index = 0;
    LOGBRUSH logbrush;

    if (!GetObjectA( hBrush, sizeof(logbrush), &logbrush )) return 0;

    switch (logbrush.lbStyle) {
    case BS_SOLID:
    case BS_HATCHED:
    case BS_NULL:
      {
	EMRCREATEBRUSHINDIRECT emr;
	emr.emr.iType = EMR_CREATEBRUSHINDIRECT;
	emr.emr.nSize = sizeof(emr);
	emr.ihBrush = index = EMFDRV_AddHandle( dev, hBrush );
	emr.lb.lbStyle = logbrush.lbStyle;
	emr.lb.lbColor = logbrush.lbColor;
	emr.lb.lbHatch = logbrush.lbHatch;

	if(!EMFDRV_WriteRecord( dev, &emr.emr ))
	    index = 0;
      }
      break;
    case BS_PATTERN:
    case BS_DIBPATTERN:
      {
        EMRCREATEDIBPATTERNBRUSHPT *emr;
        char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
        BITMAPINFO *info = (BITMAPINFO *)buffer;
        DWORD info_size;
        void *bits;
        UINT usage;

        if (!get_brush_bitmap_info( hBrush, info, &bits, &usage )) break;
        info_size = get_dib_info_size( info, usage );

        emr = HeapAlloc( GetProcessHeap(), 0,
                         sizeof(EMRCREATEDIBPATTERNBRUSHPT)+info_size+info->bmiHeader.biSizeImage );
        if(!emr) break;

        if (logbrush.lbStyle == BS_PATTERN && info->bmiHeader.biBitCount == 1)
        {
            /* Presumably to reduce the size of the written EMF, MS supports an
             * undocumented iUsage value of 2, indicating a mono bitmap without the
             * 8 byte 2 entry black/white palette. Stupidly, they could have saved
             * over 20 bytes more by also ignoring the BITMAPINFO fields that are
             * irrelevant/constant for monochrome bitmaps.
             * FIXME: It may be that the DIB functions themselves accept this value.
             */
            emr->emr.iType = EMR_CREATEMONOBRUSH;
            usage = DIB_PAL_MONO;
            /* FIXME: There is an extra DWORD written by native before the BMI.
             *        Not sure what its meant to contain.
             */
            emr->offBmi = sizeof( EMRCREATEDIBPATTERNBRUSHPT ) + sizeof(DWORD);
            emr->cbBmi = sizeof( BITMAPINFOHEADER );
        }
        else
        {
            emr->emr.iType = EMR_CREATEDIBPATTERNBRUSHPT;
            emr->offBmi = sizeof( EMRCREATEDIBPATTERNBRUSHPT );
            emr->cbBmi = info_size;
        }
        emr->ihBrush = index = EMFDRV_AddHandle( dev, hBrush );
        emr->iUsage = usage;
        emr->offBits = emr->offBmi + emr->cbBmi;
        emr->cbBits = info->bmiHeader.biSizeImage;
        emr->emr.nSize = emr->offBits + emr->cbBits;

        memcpy( (BYTE *)emr + emr->offBmi, info, emr->cbBmi );
        memcpy( (BYTE *)emr + emr->offBits, bits, emr->cbBits );

        if(!EMFDRV_WriteRecord( dev, &emr->emr ))
            index = 0;
        HeapFree( GetProcessHeap(), 0, emr );
      }
      break;

    default:
        FIXME("Unknown style %x\n", logbrush.lbStyle);
	break;
    }
    return index;
}
Пример #11
0
INT16 MFDRV_CreateBrushIndirect(PHYSDEV dev, HBRUSH hBrush )
{
    DWORD size;
    METARECORD *mr;
    LOGBRUSH logbrush;
    BOOL r;

    if (!GetObjectA( hBrush, sizeof(logbrush), &logbrush )) return -1;

    switch(logbrush.lbStyle)
    {
    case BS_SOLID:
    case BS_NULL:
    case BS_HATCHED:
        {
	    LOGBRUSH16 lb16;

	    lb16.lbStyle = logbrush.lbStyle;
	    lb16.lbColor = logbrush.lbColor;
	    lb16.lbHatch = logbrush.lbHatch;
	    size = sizeof(METARECORD) + sizeof(LOGBRUSH16) - 2;
	    mr = HeapAlloc( GetProcessHeap(), 0, size );
	    mr->rdSize = size / 2;
	    mr->rdFunction = META_CREATEBRUSHINDIRECT;
	    memcpy( mr->rdParm, &lb16, sizeof(LOGBRUSH16));
	    break;
	}
    case BS_PATTERN:
    case BS_DIBPATTERN:
        {
            char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
            BITMAPINFO *dst_info, *src_info = (BITMAPINFO *)buffer;
            DWORD info_size;
            char *dst_ptr;
            void *bits;
            UINT usage;

            if (!get_brush_bitmap_info( hBrush, src_info, &bits, &usage )) goto done;

            info_size = get_dib_info_size( src_info, usage );
	    size = FIELD_OFFSET( METARECORD, rdParm[2] ) + info_size + src_info->bmiHeader.biSizeImage;

            if (!(mr = HeapAlloc( GetProcessHeap(), 0, size ))) goto done;
	    mr->rdFunction = META_DIBCREATEPATTERNBRUSH;
	    mr->rdSize = size / 2;
	    mr->rdParm[0] = logbrush.lbStyle;
	    mr->rdParm[1] = usage;
            dst_info = (BITMAPINFO *)(mr->rdParm + 2);
            memcpy( dst_info, src_info, info_size );
            if (dst_info->bmiHeader.biClrUsed == 1 << dst_info->bmiHeader.biBitCount)
                dst_info->bmiHeader.biClrUsed = 0;
            dst_ptr = (char *)dst_info + info_size;

            /* always return a bottom-up DIB */
            if (dst_info->bmiHeader.biHeight < 0)
            {
                int i, width_bytes = get_dib_stride( dst_info->bmiHeader.biWidth,
                                                     dst_info->bmiHeader.biBitCount );
                dst_info->bmiHeader.biHeight = -dst_info->bmiHeader.biHeight;
                dst_ptr += (dst_info->bmiHeader.biHeight - 1) * width_bytes;
                for (i = 0; i < dst_info->bmiHeader.biHeight; i++, dst_ptr -= width_bytes)
                    memcpy( dst_ptr, (char *)bits + i * width_bytes, width_bytes );
            }
            else memcpy( dst_ptr, bits, src_info->bmiHeader.biSizeImage );
	    break;
	}

	default:
	    FIXME("Unkonwn brush style %x\n", logbrush.lbStyle);
	    return 0;
    }
    r = MFDRV_WriteRecord( dev, mr, mr->rdSize * 2);
    HeapFree(GetProcessHeap(), 0, mr);
    if( !r )
        return -1;
done:
    return MFDRV_AddHandle( dev, hBrush );
}