return Ok;
}
+GpStatus graphics_from_image(GpImage *image, GpGraphics **graphics)
+{
+ GpStatus retval;
+
+ *graphics = GdipAlloc(sizeof(GpGraphics));
+ if(!*graphics) return OutOfMemory;
+
+ if((retval = GdipCreateMatrix(&(*graphics)->worldtrans)) != Ok){
+ GdipFree(*graphics);
+ return retval;
+ }
+
+ if((retval = GdipCreateRegion(&(*graphics)->clip)) != Ok){
+ GdipFree((*graphics)->worldtrans);
+ GdipFree(*graphics);
+ return retval;
+ }
+
+ (*graphics)->hdc = NULL;
+ (*graphics)->hwnd = NULL;
+ (*graphics)->owndc = FALSE;
+ (*graphics)->image = image;
+ (*graphics)->smoothing = SmoothingModeDefault;
+ (*graphics)->compqual = CompositingQualityDefault;
+ (*graphics)->interpolation = InterpolationModeDefault;
+ (*graphics)->pixeloffset = PixelOffsetModeDefault;
+ (*graphics)->compmode = CompositingModeSourceOver;
+ (*graphics)->unit = UnitDisplay;
+ (*graphics)->scale = 1.0;
+ (*graphics)->busy = FALSE;
+ (*graphics)->textcontrast = 4;
+ list_init(&(*graphics)->containers);
+ (*graphics)->contid = 0;
+
+ TRACE("<-- %p\n", *graphics);
+
+ return Ok;
+}
+
GpStatus WINGDIPAPI GdipCreateFromHWND(HWND hwnd, GpGraphics **graphics)
{
GpStatus ret;
PixelFormat format, BYTE* scan0, GpBitmap** bitmap)
{
BITMAPINFO* pbmi;
- HBITMAP hbitmap;
+ HBITMAP hbitmap=NULL;
INT row_size, dib_stride;
HDC hdc;
- BYTE *bits;
+ BYTE *bits=NULL, *own_bits=NULL;
int i;
REAL xres, yres;
GpStatus stat;
if(stride == 0)
stride = dib_stride;
- pbmi = GdipAlloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
- if (!pbmi)
- return OutOfMemory;
+ if (format & PixelFormatGDI)
+ {
+ pbmi = GdipAlloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
+ if (!pbmi)
+ return OutOfMemory;
- pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- pbmi->bmiHeader.biWidth = width;
- pbmi->bmiHeader.biHeight = -height;
- pbmi->bmiHeader.biPlanes = 1;
- /* FIXME: use the rest of the data from format */
- pbmi->bmiHeader.biBitCount = PIXELFORMATBPP(format);
- pbmi->bmiHeader.biCompression = BI_RGB;
- pbmi->bmiHeader.biSizeImage = 0;
- pbmi->bmiHeader.biXPelsPerMeter = 0;
- pbmi->bmiHeader.biYPelsPerMeter = 0;
- pbmi->bmiHeader.biClrUsed = 0;
- pbmi->bmiHeader.biClrImportant = 0;
+ pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ pbmi->bmiHeader.biWidth = width;
+ pbmi->bmiHeader.biHeight = -height;
+ pbmi->bmiHeader.biPlanes = 1;
+ /* FIXME: use the rest of the data from format */
+ pbmi->bmiHeader.biBitCount = PIXELFORMATBPP(format);
+ pbmi->bmiHeader.biCompression = BI_RGB;
+ pbmi->bmiHeader.biSizeImage = 0;
+ pbmi->bmiHeader.biXPelsPerMeter = 0;
+ pbmi->bmiHeader.biYPelsPerMeter = 0;
+ pbmi->bmiHeader.biClrUsed = 0;
+ pbmi->bmiHeader.biClrImportant = 0;
+
+ hdc = CreateCompatibleDC(NULL);
+ if (!hdc) {
+ GdipFree(pbmi);
+ return GenericError;
+ }
- hdc = CreateCompatibleDC(NULL);
- if (!hdc) {
+ hbitmap = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
+
+ DeleteDC(hdc);
GdipFree(pbmi);
- return GenericError;
- }
- hbitmap = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
+ if (!hbitmap) return GenericError;
+ }
+ else
+ {
+ /* Not a GDI format; don't try to make an HBITMAP. */
+ if (scan0)
+ {
+ /* FIXME: We should do this with GDI formats too when scan0 is
+ * provided, but for now we need the HDC for most drawing
+ * operations. */
+ bits = scan0;
+ }
+ else
+ {
+ INT size = abs(stride) * height;
- DeleteDC(hdc);
- GdipFree(pbmi);
+ own_bits = bits = GdipAlloc(size);
+ if (!own_bits) return OutOfMemory;
- if (!hbitmap) return GenericError;
+ if (stride < 0)
+ bits += stride * (1 - height);
+ }
+ }
/* copy bits to the dib if necessary */
/* FIXME: should reference the bits instead of copying them */
- if (scan0)
+ if (scan0 && bits != scan0)
for (i=0; i<height; i++)
memcpy(bits+i*dib_stride, scan0+i*stride, row_size);
if(!*bitmap)
{
DeleteObject(hbitmap);
+ GdipFree(own_bits);
return OutOfMemory;
}
(*bitmap)->hdc = NULL;
(*bitmap)->bits = bits;
(*bitmap)->stride = dib_stride;
+ (*bitmap)->own_bits = own_bits;
if (format == PixelFormat1bppIndexed ||
format == PixelFormat4bppIndexed ||
dst->hdc = src->hdc;
dst->bits = src->bits;
dst->stride = src->stride;
+ dst->own_bits = src->own_bits;
GdipFree(src);
}
if (image->type == ImageTypeBitmap)
{
GdipFree(((GpBitmap*)image)->bitmapbits);
+ GdipFree(((GpBitmap*)image)->own_bits);
DeleteDC(((GpBitmap*)image)->hdc);
DeleteObject(((GpBitmap*)image)->hbitmap);
}
return NotImplemented;
}
- hdc = ((GpBitmap*)image)->hdc;
+ if (((GpBitmap*)image)->hbitmap)
+ {
+ hdc = ((GpBitmap*)image)->hdc;
- if(!hdc){
- hdc = CreateCompatibleDC(0);
- SelectObject(hdc, ((GpBitmap*)image)->hbitmap);
- ((GpBitmap*)image)->hdc = hdc;
- }
+ if(!hdc){
+ hdc = CreateCompatibleDC(0);
+ SelectObject(hdc, ((GpBitmap*)image)->hbitmap);
+ ((GpBitmap*)image)->hdc = hdc;
+ }
- stat = GdipCreateFromHDC(hdc, graphics);
+ stat = GdipCreateFromHDC(hdc, graphics);
- if (stat == Ok)
- (*graphics)->image = image;
+ if (stat == Ok)
+ (*graphics)->image = image;
+ }
+ else
+ stat = graphics_from_image(image, graphics);
return stat;
}
GdipDisposeImage((GpImage*)bitmap);
status = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat48bppRGB, NULL, &bitmap);
- todo_wine expect(Ok, status);
+ expect(Ok, status);
if (status == Ok)
{
status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
}
status = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat64bppARGB, NULL, &bitmap);
- todo_wine expect(Ok, status);
+ expect(Ok, status);
if (status == Ok)
{
status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
}
status = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat64bppPARGB, NULL, &bitmap);
- todo_wine expect(Ok, status);
+ expect(Ok, status);
if (status == Ok)
{
status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);