PixelFormat format, BYTE* scan0, GpBitmap** bitmap)
{
BITMAPINFO* pbmi;
- HBITMAP hbitmap;
+ HBITMAP hbitmap=NULL;
INT row_size, dib_stride;
HDC hdc;
- BYTE *bits;
- int i;
+ BYTE *bits=NULL, *own_bits=NULL;
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 && !(format & (PixelFormatAlpha|PixelFormatIndexed)) && !scan0)
+ {
+ 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;
- DeleteDC(hdc);
- GdipFree(pbmi);
+ stride = dib_stride;
+ }
+ else
+ {
+ /* Not a GDI format; don't try to make an HBITMAP. */
+ if (scan0)
+ bits = scan0;
+ else
+ {
+ INT size = abs(stride) * height;
- if (!hbitmap) return GenericError;
+ own_bits = bits = GdipAlloc(size);
+ if (!own_bits) return OutOfMemory;
- /* copy bits to the dib if necessary */
- /* FIXME: should reference the bits instead of copying them */
- if (scan0)
- for (i=0; i<height; i++)
- memcpy(bits+i*dib_stride, scan0+i*stride, row_size);
+ if (stride < 0)
+ bits += stride * (1 - height);
+ }
+ }
*bitmap = GdipAlloc(sizeof(GpBitmap));
if(!*bitmap)
{
DeleteObject(hbitmap);
+ GdipFree(own_bits);
return OutOfMemory;
}
(*bitmap)->hbitmap = hbitmap;
(*bitmap)->hdc = NULL;
(*bitmap)->bits = bits;
- (*bitmap)->stride = dib_stride;
+ (*bitmap)->stride = stride;
+ (*bitmap)->own_bits = own_bits;
+
+ /* set format-related flags */
+ if (format & (PixelFormatAlpha|PixelFormatPAlpha|PixelFormatIndexed))
+ (*bitmap)->image.flags |= ImageFlagsHasAlpha;
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)
return InvalidParameter;
- if (image->picture)
- IPicture_Release(image->picture);
if (image->type == ImageTypeBitmap)
{
GdipFree(((GpBitmap*)image)->bitmapbits);
+ GdipFree(((GpBitmap*)image)->own_bits);
DeleteDC(((GpBitmap*)image)->hdc);
DeleteObject(((GpBitmap*)image)->hbitmap);
}
+ else if (image->type != ImageTypeMetafile)
+ {
+ WARN("invalid image: %p\n", image);
+ return ObjectBusy;
+ }
+ if (image->picture)
+ IPicture_Release(image->picture);
GdipFree(image->palette_entries);
+ image->type = ~0;
GdipFree(image);
return Ok;
if(image->type == ImageTypeMetafile){
HDC hdc = GetDC(0);
+ REAL res = (REAL)GetDeviceCaps(hdc, LOGPIXELSX);
- *height = convert_unit(hdc, ((GpMetafile*)image)->unit) *
+ ReleaseDC(0, hdc);
+
+ *height = convert_unit(res, ((GpMetafile*)image)->unit) *
((GpMetafile*)image)->bounds.Height;
- *width = convert_unit(hdc, ((GpMetafile*)image)->unit) *
+ *width = convert_unit(res, ((GpMetafile*)image)->unit) *
((GpMetafile*)image)->bounds.Width;
-
- ReleaseDC(0, hdc);
}
else if(image->type == ImageTypeBitmap){
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;
}
if(image->type == ImageTypeMetafile){
HDC hdc = GetDC(0);
-
- *height = roundr(convert_unit(hdc, ((GpMetafile*)image)->unit) *
- ((GpMetafile*)image)->bounds.Height);
+ REAL res = (REAL)GetDeviceCaps(hdc, LOGPIXELSX);
ReleaseDC(0, hdc);
+
+ *height = roundr(convert_unit(res, ((GpMetafile*)image)->unit) *
+ ((GpMetafile*)image)->bounds.Height);
}
else if(image->type == ImageTypeBitmap)
*height = ((GpBitmap*)image)->height;
if(image->type == ImageTypeMetafile){
HDC hdc = GetDC(0);
-
- *width = roundr(convert_unit(hdc, ((GpMetafile*)image)->unit) *
- ((GpMetafile*)image)->bounds.Width);
+ REAL res = (REAL)GetDeviceCaps(hdc, LOGPIXELSX);
ReleaseDC(0, hdc);
+
+ *width = roundr(convert_unit(res, ((GpMetafile*)image)->unit) *
+ ((GpMetafile*)image)->bounds.Width);
}
else if(image->type == ImageTypeBitmap)
*width = ((GpBitmap*)image)->width;
*image = NULL;
GdipDisposeImage((GpImage*)bitmap);
}
+
+ if (SUCCEEDED(hr) && status == Ok)
+ {
+ double dpix, dpiy;
+ hr = IWICBitmapSource_GetResolution(source, &dpix, &dpiy);
+ if (SUCCEEDED(hr))
+ {
+ bitmap->image.xres = dpix;
+ bitmap->image.yres = dpiy;
+ }
+ hr = S_OK;
+ }
}
IWICBitmapSource_Release(source);
if (FAILED(hr) && status == Ok) status = hresult_to_status(hr);
+ if (status == Ok)
+ {
+ /* Native GDI+ used to be smarter, but since Win7 it just sets these flags. */
+ bitmap->image.flags |= ImageFlagsReadOnly|ImageFlagsHasRealPixelSize|ImageFlagsHasRealDPI|ImageFlagsColorSpaceRGB;
+ }
+
return status;
}
return stat;
}
+
+/*****************************************************************************
+ * GdipConvertToEmfPlusToFile [GDIPLUS.@]
+ */
+
+GpStatus WINGDIPAPI GdipConvertToEmfPlusToFile(const GpGraphics* refGraphics,
+ GpMetafile* metafile, BOOL* conversionSuccess,
+ const WCHAR* filename, EmfType emfType,
+ const WCHAR* description, GpMetafile** out_metafile)
+{
+ FIXME("stub: %p, %p, %p, %p, %u, %p, %p\n", refGraphics, metafile, conversionSuccess, filename, emfType, description, out_metafile);
+ return NotImplemented;
+}