[GDIPLUS] Sync with Wine Staging 2.2. CORE-12823

818b141 gdiplus: Add support for more image color formats.
f8f0a35 gdiplus: Implement GdipInitializePalette. (v2)
973bba9 gdiplus: Ignore an externally set DC clipping region.
650b8d0 gdiplus: Ignore an externally set DC origin.
e100661 gdiplus: Add GdipCreateHBITMAPFromBitmap tests when bitmap bits are locked.
b58276a gdiplus: Reimplement GdipCreateHBITMAPFromBitmap so it can work on locked bitmaps.
5673d82 gdiplus: GpBitmap can be only locked once, get rid of numlocks field.
0eaaa15 gdiplus: Make GpBitmap->bitmapbits access thread safe.
4e685eb gdiplus: Added GdipGetCustomLineCapType().
36bb9d9 gdiplus: Fix some spec file entries.
f870708 gdiplus: Make some GdipDraw*Path() functions static.
046fc19 gdiplus: Fix memory leak in format_string_callback error path.
5018594 gdiplus: Create the FontFamily before checking for duplicates.
0d6a4b0 gdiplus: Don't include rotated fonts in the installed font collection.

svn path=/trunk/; revision=74098
This commit is contained in:
Amine Khaldi 2017-03-05 21:15:16 +00:00
parent 814dd8031a
commit 687ee5ded5
8 changed files with 143 additions and 58 deletions

View file

@ -65,6 +65,7 @@ GpStatus WINGDIPAPI GdipCreateCustomLineCap(GpPath* fillPath, GpPath* strokePath
*customCap = heap_alloc_zero(sizeof(GpCustomLineCap)); *customCap = heap_alloc_zero(sizeof(GpCustomLineCap));
if(!*customCap) return OutOfMemory; if(!*customCap) return OutOfMemory;
(*customCap)->type = CustomLineCapTypeDefault;
if(strokePath){ if(strokePath){
(*customCap)->fill = FALSE; (*customCap)->fill = FALSE;
pathdata = &strokePath->pathdata; pathdata = &strokePath->pathdata;
@ -233,6 +234,17 @@ GpStatus WINGDIPAPI GdipGetCustomLineCapBaseCap(GpCustomLineCap *customCap, GpLi
return Ok; return Ok;
} }
GpStatus WINGDIPAPI GdipGetCustomLineCapType(GpCustomLineCap *customCap, CustomLineCapType *type)
{
TRACE("(%p, %p)\n", customCap, type);
if(!customCap || !type)
return InvalidParameter;
*type = customCap->type;
return Ok;
}
GpStatus WINGDIPAPI GdipCreateAdjustableArrowCap(REAL height, REAL width, BOOL fill, GpStatus WINGDIPAPI GdipCreateAdjustableArrowCap(REAL height, REAL width, BOOL fill,
GpAdjustableArrowCap **cap) GpAdjustableArrowCap **cap)
{ {

View file

@ -1584,14 +1584,17 @@ static INT CALLBACK add_font_proc(const LOGFONTW *lfw, const TEXTMETRICW *ntm,
DWORD type, LPARAM lParam) DWORD type, LPARAM lParam)
{ {
GpFontCollection* fonts = (GpFontCollection*)lParam; GpFontCollection* fonts = (GpFontCollection*)lParam;
GpFontFamily* family;
int i; int i;
if (type == RASTER_FONTTYPE) if (type == RASTER_FONTTYPE)
return 1; return 1;
/* skip duplicates */ /* skip rotated fonts */
for (i=0; i<fonts->count; i++) if (lfw->lfFaceName[0] == '@')
if (strcmpiW(lfw->lfFaceName, fonts->FontFamilies[i]->FamilyName) == 0) return 1;
if (fonts->count && strcmpiW(lfw->lfFaceName, fonts->FontFamilies[fonts->count-1]->FamilyName) == 0)
return 1; return 1;
if (fonts->allocated == fonts->count) if (fonts->allocated == fonts->count)
@ -1608,11 +1611,21 @@ static INT CALLBACK add_font_proc(const LOGFONTW *lfw, const TEXTMETRICW *ntm,
fonts->allocated = new_alloc_count; fonts->allocated = new_alloc_count;
} }
if (GdipCreateFontFamilyFromName(lfw->lfFaceName, NULL, &fonts->FontFamilies[fonts->count]) == Ok) if (GdipCreateFontFamilyFromName(lfw->lfFaceName, NULL, &family) != Ok)
fonts->count++;
else
return 0; return 0;
/* skip duplicates */
for (i=0; i<fonts->count; i++)
{
if (strcmpiW(family->FamilyName, fonts->FontFamilies[i]->FamilyName) == 0)
{
GdipDeleteFontFamily(family);
return 1;
}
}
fonts->FontFamilies[fonts->count++] = family;
return 1; return 1;
} }

View file

@ -172,8 +172,8 @@
172 stdcall GdipDrawImagePointsRectI(ptr ptr ptr long long long long long long ptr ptr ptr) 172 stdcall GdipDrawImagePointsRectI(ptr ptr ptr long long long long long long ptr ptr ptr)
173 stdcall GdipDrawImageRect(ptr ptr float float float float) 173 stdcall GdipDrawImageRect(ptr ptr float float float float)
174 stdcall GdipDrawImageRectI(ptr ptr long long long long) 174 stdcall GdipDrawImageRectI(ptr ptr long long long long)
175 stdcall GdipDrawImageRectRect(ptr ptr float float float float float float float float long ptr long ptr) 175 stdcall GdipDrawImageRectRect(ptr ptr float float float float float float float float long ptr ptr ptr)
176 stdcall GdipDrawImageRectRectI(ptr ptr long long long long long long long long long ptr long ptr) 176 stdcall GdipDrawImageRectRectI(ptr ptr long long long long long long long long long ptr ptr ptr)
177 stdcall GdipDrawLine(ptr ptr float float float float) 177 stdcall GdipDrawLine(ptr ptr float float float float)
178 stdcall GdipDrawLineI(ptr ptr long long long long) 178 stdcall GdipDrawLineI(ptr ptr long long long long)
179 stdcall GdipDrawLines(ptr ptr ptr long) 179 stdcall GdipDrawLines(ptr ptr ptr long)
@ -189,7 +189,7 @@
189 stdcall GdipDrawRectanglesI(ptr ptr ptr long) 189 stdcall GdipDrawRectanglesI(ptr ptr ptr long)
190 stdcall GdipDrawString(ptr wstr long ptr ptr ptr ptr) 190 stdcall GdipDrawString(ptr wstr long ptr ptr ptr ptr)
191 stdcall GdipEmfToWmfBits(ptr long ptr long long) 191 stdcall GdipEmfToWmfBits(ptr long ptr long long)
192 stdcall GdipEndContainer(ptr ptr) 192 stdcall GdipEndContainer(ptr long)
193 stdcall GdipEnumerateMetafileDestPoint(ptr ptr ptr ptr ptr ptr) 193 stdcall GdipEnumerateMetafileDestPoint(ptr ptr ptr ptr ptr ptr)
194 stdcall GdipEnumerateMetafileDestPointI(ptr ptr ptr ptr ptr ptr) 194 stdcall GdipEnumerateMetafileDestPointI(ptr ptr ptr ptr ptr ptr)
195 stub GdipEnumerateMetafileDestPoints 195 stub GdipEnumerateMetafileDestPoints
@ -240,7 +240,7 @@
240 stdcall GdipGetCustomLineCapBaseInset(ptr ptr) 240 stdcall GdipGetCustomLineCapBaseInset(ptr ptr)
241 stub GdipGetCustomLineCapStrokeCaps 241 stub GdipGetCustomLineCapStrokeCaps
242 stdcall GdipGetCustomLineCapStrokeJoin(ptr ptr) 242 stdcall GdipGetCustomLineCapStrokeJoin(ptr ptr)
243 stub GdipGetCustomLineCapType 243 stdcall GdipGetCustomLineCapType(ptr ptr)
244 stdcall GdipGetCustomLineCapWidthScale(ptr ptr) 244 stdcall GdipGetCustomLineCapWidthScale(ptr ptr)
245 stdcall GdipGetDC(ptr ptr) 245 stdcall GdipGetDC(ptr ptr)
246 stdcall GdipGetDpiX(ptr ptr) 246 stdcall GdipGetDpiX(ptr ptr)
@ -563,7 +563,7 @@
563 stdcall GdipSetPropertyItem(ptr ptr) 563 stdcall GdipSetPropertyItem(ptr ptr)
564 stdcall GdipSetRenderingOrigin(ptr long long) 564 stdcall GdipSetRenderingOrigin(ptr long long)
565 stdcall GdipSetSmoothingMode(ptr long) 565 stdcall GdipSetSmoothingMode(ptr long)
566 stdcall GdipSetSolidFillColor(ptr ptr) 566 stdcall GdipSetSolidFillColor(ptr long)
567 stdcall GdipSetStringFormatAlign(ptr long) 567 stdcall GdipSetStringFormatAlign(ptr long)
568 stdcall GdipSetStringFormatDigitSubstitution(ptr long long) 568 stdcall GdipSetStringFormatDigitSubstitution(ptr long long)
569 stdcall GdipSetStringFormatFlags(ptr long) 569 stdcall GdipSetStringFormatFlags(ptr long)
@ -604,8 +604,8 @@
604 stdcall GdipWidenPath(ptr ptr ptr float) 604 stdcall GdipWidenPath(ptr ptr ptr float)
605 stdcall GdipWindingModeOutline(ptr ptr float) 605 stdcall GdipWindingModeOutline(ptr ptr float)
606 stdcall GdiplusNotificationHook(ptr) 606 stdcall GdiplusNotificationHook(ptr)
607 stdcall GdiplusNotificationUnhook(ptr) 607 stdcall GdiplusNotificationUnhook(long)
608 stdcall GdiplusShutdown(ptr) GdiplusShutdown_wrapper 608 stdcall GdiplusShutdown(long) GdiplusShutdown_wrapper
609 stdcall GdiplusStartup(ptr ptr ptr) 609 stdcall GdiplusStartup(ptr ptr ptr)
610 stdcall GdipFindFirstImageItem(ptr ptr) 610 stdcall GdipFindFirstImageItem(ptr ptr)
611 stub GdipFindNextImageItem 611 stub GdipFindNextImageItem

View file

@ -335,6 +335,7 @@ struct GpPathIterator{
}; };
struct GpCustomLineCap{ struct GpCustomLineCap{
CustomLineCapType type;
GpPathData pathdata; GpPathData pathdata;
BOOL fill; /* TRUE for fill, FALSE for stroke */ BOOL fill; /* TRUE for fill, FALSE for stroke */
GpLineCap cap; /* as far as I can tell, this value is ignored */ GpLineCap cap; /* as far as I can tell, this value is ignored */
@ -355,6 +356,7 @@ struct GpImage{
UINT frame_count, current_frame; UINT frame_count, current_frame;
ColorPalette *palette; ColorPalette *palette;
REAL xres, yres; REAL xres, yres;
LONG busy;
}; };
struct GpMetafile{ struct GpMetafile{
@ -397,7 +399,6 @@ struct GpBitmap{
INT height; INT height;
PixelFormat format; PixelFormat format;
ImageLockMode lockmode; ImageLockMode lockmode;
INT numlocks;
BYTE *bitmapbits; /* pointer to the buffer we passed in BitmapLockBits */ BYTE *bitmapbits; /* pointer to the buffer we passed in BitmapLockBits */
HBITMAP hbitmap; HBITMAP hbitmap;
HDC hdc; HDC hdc;
@ -522,4 +523,17 @@ GpStatus gdip_format_string(HDC hdc,
void get_log_fontW(const GpFont *, GpGraphics *, LOGFONTW *) DECLSPEC_HIDDEN; void get_log_fontW(const GpFont *, GpGraphics *, LOGFONTW *) DECLSPEC_HIDDEN;
static inline BOOL image_lock(GpImage *image, BOOL *unlock)
{
LONG tid = GetCurrentThreadId(), owner_tid;
owner_tid = InterlockedCompareExchange(&image->busy, tid, 0);
*unlock = !owner_tid;
return !owner_tid || owner_tid==tid;
}
static inline void image_unlock(GpImage *image, BOOL unlock)
{
if (unlock) image->busy = 0;
}
#endif /* __WINE_GP_PRIVATE_H_ */ #endif /* __WINE_GP_PRIVATE_H_ */

View file

@ -493,8 +493,9 @@ static GpStatus alpha_blend_pixels_hrgn(GpGraphics *graphics, INT dst_x, INT dst
save = SaveDC(graphics->hdc); save = SaveDC(graphics->hdc);
if (hrgn) SetViewportOrgEx(graphics->hdc, 0, 0, NULL);
ExtSelectClipRgn(graphics->hdc, hrgn, RGN_AND);
ExtSelectClipRgn(graphics->hdc, hrgn, RGN_COPY);
if (hregion) if (hregion)
ExtSelectClipRgn(graphics->hdc, hregion, RGN_AND); ExtSelectClipRgn(graphics->hdc, hregion, RGN_AND);
@ -3371,7 +3372,7 @@ GpStatus WINGDIPAPI GdipDrawLinesI(GpGraphics *graphics, GpPen *pen, GDIPCONST
return retval; return retval;
} }
GpStatus GDI32_GdipDrawPath(GpGraphics *graphics, GpPen *pen, GpPath *path) static GpStatus GDI32_GdipDrawPath(GpGraphics *graphics, GpPen *pen, GpPath *path)
{ {
INT save_state; INT save_state;
GpStatus retval; GpStatus retval;
@ -3397,7 +3398,7 @@ end:
return retval; return retval;
} }
GpStatus SOFTWARE_GdipDrawThinPath(GpGraphics *graphics, GpPen *pen, GpPath *path) static GpStatus SOFTWARE_GdipDrawThinPath(GpGraphics *graphics, GpPen *pen, GpPath *path)
{ {
GpStatus stat; GpStatus stat;
GpPath* flat_path; GpPath* flat_path;
@ -3695,7 +3696,7 @@ GpStatus SOFTWARE_GdipDrawThinPath(GpGraphics *graphics, GpPen *pen, GpPath *pat
return stat; return stat;
} }
GpStatus SOFTWARE_GdipDrawPath(GpGraphics *graphics, GpPen *pen, GpPath *path) static GpStatus SOFTWARE_GdipDrawPath(GpGraphics *graphics, GpPen *pen, GpPath *path)
{ {
GpStatus stat; GpStatus stat;
GpPath *wide_path; GpPath *wide_path;

View file

@ -867,6 +867,7 @@ static GpStatus format_string_callback(HDC dc,
start = (char *)ph; start = (char *)ph;
if (!ph || !lengthen_path(path, len / sizeof(POINTFX))) if (!ph || !lengthen_path(path, len / sizeof(POINTFX)))
{ {
heap_free(ph);
status = OutOfMemory; status = OutOfMemory;
break; break;
} }

View file

@ -38,13 +38,19 @@ static const struct
{ {
{ &GUID_WICPixelFormatBlackWhite, PixelFormat1bppIndexed, WICBitmapPaletteTypeFixedBW }, { &GUID_WICPixelFormatBlackWhite, PixelFormat1bppIndexed, WICBitmapPaletteTypeFixedBW },
{ &GUID_WICPixelFormat1bppIndexed, PixelFormat1bppIndexed, WICBitmapPaletteTypeFixedBW }, { &GUID_WICPixelFormat1bppIndexed, PixelFormat1bppIndexed, WICBitmapPaletteTypeFixedBW },
{ &GUID_WICPixelFormat4bppIndexed, PixelFormat4bppIndexed, WICBitmapPaletteTypeFixedHalftone8 },
{ &GUID_WICPixelFormat8bppGray, PixelFormat8bppIndexed, WICBitmapPaletteTypeFixedGray256 }, { &GUID_WICPixelFormat8bppGray, PixelFormat8bppIndexed, WICBitmapPaletteTypeFixedGray256 },
{ &GUID_WICPixelFormat32bppGrayFloat, PixelFormat32bppARGB, WICBitmapPaletteTypeFixedGray256 },
{ &GUID_WICPixelFormat8bppIndexed, PixelFormat8bppIndexed, WICBitmapPaletteTypeFixedHalftone256 }, { &GUID_WICPixelFormat8bppIndexed, PixelFormat8bppIndexed, WICBitmapPaletteTypeFixedHalftone256 },
{ &GUID_WICPixelFormat16bppBGR555, PixelFormat16bppRGB555, WICBitmapPaletteTypeFixedHalftone256 }, { &GUID_WICPixelFormat16bppBGR555, PixelFormat16bppRGB555, WICBitmapPaletteTypeFixedHalftone256 },
{ &GUID_WICPixelFormat24bppBGR, PixelFormat24bppRGB, WICBitmapPaletteTypeFixedHalftone256 }, { &GUID_WICPixelFormat24bppBGR, PixelFormat24bppRGB, WICBitmapPaletteTypeFixedHalftone256 },
{ &GUID_WICPixelFormat32bppBGR, PixelFormat32bppRGB, WICBitmapPaletteTypeFixedHalftone256 }, { &GUID_WICPixelFormat32bppBGR, PixelFormat32bppRGB, WICBitmapPaletteTypeFixedHalftone256 },
{ &GUID_WICPixelFormat48bppRGB, PixelFormat48bppRGB, WICBitmapPaletteTypeFixedHalftone256 },
{ &GUID_WICPixelFormat32bppBGRA, PixelFormat32bppARGB, WICBitmapPaletteTypeFixedHalftone256 }, { &GUID_WICPixelFormat32bppBGRA, PixelFormat32bppARGB, WICBitmapPaletteTypeFixedHalftone256 },
{ &GUID_WICPixelFormat32bppPBGRA, PixelFormat32bppPARGB, WICBitmapPaletteTypeFixedHalftone256 }, { &GUID_WICPixelFormat32bppPBGRA, PixelFormat32bppPARGB, WICBitmapPaletteTypeFixedHalftone256 },
{ &GUID_WICPixelFormat32bppCMYK, PixelFormat32bppCMYK, WICBitmapPaletteTypeFixedHalftone256 },
{ &GUID_WICPixelFormat64bppCMYK, PixelFormat48bppRGB, WICBitmapPaletteTypeFixedHalftone256 },
{ &GUID_WICPixelFormat64bppRGBA, PixelFormat48bppRGB, WICBitmapPaletteTypeFixedHalftone256 },
{ NULL } { NULL }
}; };
@ -1010,16 +1016,22 @@ GpStatus WINGDIPAPI GdipBitmapLockBits(GpBitmap* bitmap, GDIPCONST GpRect* rect,
INT bitspp = PIXELFORMATBPP(format); INT bitspp = PIXELFORMATBPP(format);
GpRect act_rect; /* actual rect to be used */ GpRect act_rect; /* actual rect to be used */
GpStatus stat; GpStatus stat;
BOOL unlock;
TRACE("%p %p %d 0x%x %p\n", bitmap, rect, flags, format, lockeddata); TRACE("%p %p %d 0x%x %p\n", bitmap, rect, flags, format, lockeddata);
if(!lockeddata || !bitmap) if(!lockeddata || !bitmap)
return InvalidParameter; return InvalidParameter;
if(!image_lock(&bitmap->image, &unlock))
return ObjectBusy;
if(rect){ if(rect){
if(rect->X < 0 || rect->Y < 0 || (rect->X + rect->Width > bitmap->width) || if(rect->X < 0 || rect->Y < 0 || (rect->X + rect->Width > bitmap->width) ||
(rect->Y + rect->Height > bitmap->height) || !flags) (rect->Y + rect->Height > bitmap->height) || !flags)
{
image_unlock(&bitmap->image, unlock);
return InvalidParameter; return InvalidParameter;
}
act_rect = *rect; act_rect = *rect;
} }
@ -1032,6 +1044,7 @@ GpStatus WINGDIPAPI GdipBitmapLockBits(GpBitmap* bitmap, GDIPCONST GpRect* rect,
if(bitmap->lockmode) if(bitmap->lockmode)
{ {
WARN("bitmap is already locked and cannot be locked again\n"); WARN("bitmap is already locked and cannot be locked again\n");
image_unlock(&bitmap->image, unlock);
return WrongState; return WrongState;
} }
@ -1047,8 +1060,8 @@ GpStatus WINGDIPAPI GdipBitmapLockBits(GpBitmap* bitmap, GDIPCONST GpRect* rect,
bitmap->stride * act_rect.Y; bitmap->stride * act_rect.Y;
bitmap->lockmode = flags | ImageLockModeRead; bitmap->lockmode = flags | ImageLockModeRead;
bitmap->numlocks++;
image_unlock(&bitmap->image, unlock);
return Ok; return Ok;
} }
@ -1059,6 +1072,7 @@ GpStatus WINGDIPAPI GdipBitmapLockBits(GpBitmap* bitmap, GDIPCONST GpRect* rect,
if (stat == NotImplemented) if (stat == NotImplemented)
{ {
FIXME("cannot read bitmap from %x to %x\n", bitmap->format, format); FIXME("cannot read bitmap from %x to %x\n", bitmap->format, format);
image_unlock(&bitmap->image, unlock);
return NotImplemented; return NotImplemented;
} }
} }
@ -1071,6 +1085,7 @@ GpStatus WINGDIPAPI GdipBitmapLockBits(GpBitmap* bitmap, GDIPCONST GpRect* rect,
if (stat == NotImplemented) if (stat == NotImplemented)
{ {
FIXME("cannot write bitmap from %x to %x\n", format, bitmap->format); FIXME("cannot write bitmap from %x to %x\n", format, bitmap->format);
image_unlock(&bitmap->image, unlock);
return NotImplemented; return NotImplemented;
} }
} }
@ -1086,7 +1101,11 @@ GpStatus WINGDIPAPI GdipBitmapLockBits(GpBitmap* bitmap, GDIPCONST GpRect* rect,
bitmap->bitmapbits = heap_alloc_zero(lockeddata->Stride * act_rect.Height); bitmap->bitmapbits = heap_alloc_zero(lockeddata->Stride * act_rect.Height);
if (!bitmap->bitmapbits) return OutOfMemory; if (!bitmap->bitmapbits)
{
image_unlock(&bitmap->image, unlock);
return OutOfMemory;
}
lockeddata->Scan0 = bitmap->bitmapbits; lockeddata->Scan0 = bitmap->bitmapbits;
} }
@ -1111,15 +1130,16 @@ GpStatus WINGDIPAPI GdipBitmapLockBits(GpBitmap* bitmap, GDIPCONST GpRect* rect,
{ {
heap_free(bitmap->bitmapbits); heap_free(bitmap->bitmapbits);
bitmap->bitmapbits = NULL; bitmap->bitmapbits = NULL;
image_unlock(&bitmap->image, unlock);
return stat; return stat;
} }
} }
bitmap->lockmode = flags | ImageLockModeRead; bitmap->lockmode = flags | ImageLockModeRead;
bitmap->numlocks++;
bitmap->lockx = act_rect.X; bitmap->lockx = act_rect.X;
bitmap->locky = act_rect.Y; bitmap->locky = act_rect.Y;
image_unlock(&bitmap->image, unlock);
return Ok; return Ok;
} }
@ -1141,21 +1161,26 @@ GpStatus WINGDIPAPI GdipBitmapUnlockBits(GpBitmap* bitmap,
{ {
GpStatus stat; GpStatus stat;
static BOOL fixme = FALSE; static BOOL fixme = FALSE;
BOOL unlock;
TRACE("(%p,%p)\n", bitmap, lockeddata); TRACE("(%p,%p)\n", bitmap, lockeddata);
if(!bitmap || !lockeddata) if(!bitmap || !lockeddata)
return InvalidParameter; return InvalidParameter;
if(!image_lock(&bitmap->image, &unlock))
return ObjectBusy;
if(!bitmap->lockmode) if(!bitmap->lockmode)
{
image_unlock(&bitmap->image, unlock);
return WrongState; return WrongState;
}
if(!(lockeddata->Reserved & ImageLockModeWrite)){ if(!(lockeddata->Reserved & ImageLockModeWrite)){
if(!(--bitmap->numlocks))
bitmap->lockmode = 0; bitmap->lockmode = 0;
heap_free(bitmap->bitmapbits); heap_free(bitmap->bitmapbits);
bitmap->bitmapbits = NULL; bitmap->bitmapbits = NULL;
image_unlock(&bitmap->image, unlock);
return Ok; return Ok;
} }
@ -1163,7 +1188,7 @@ GpStatus WINGDIPAPI GdipBitmapUnlockBits(GpBitmap* bitmap,
{ {
/* we passed a direct reference; no need to do anything */ /* we passed a direct reference; no need to do anything */
bitmap->lockmode = 0; bitmap->lockmode = 0;
bitmap->numlocks = 0; image_unlock(&bitmap->image, unlock);
return Ok; return Ok;
} }
@ -1187,8 +1212,8 @@ GpStatus WINGDIPAPI GdipBitmapUnlockBits(GpBitmap* bitmap,
heap_free(bitmap->bitmapbits); heap_free(bitmap->bitmapbits);
bitmap->bitmapbits = NULL; bitmap->bitmapbits = NULL;
bitmap->lockmode = 0; bitmap->lockmode = 0;
bitmap->numlocks = 0;
image_unlock(&bitmap->image, unlock);
return stat; return stat;
} }
@ -1441,10 +1466,12 @@ GpStatus WINGDIPAPI GdipCreateHBITMAPFromBitmap(GpBitmap* bitmap,
UINT width, height; UINT width, height;
BITMAPINFOHEADER bih; BITMAPINFOHEADER bih;
LPBYTE bits; LPBYTE bits;
BitmapData lockeddata; BOOL unlock;
TRACE("(%p,%p,%x)\n", bitmap, hbmReturn, background); TRACE("(%p,%p,%x)\n", bitmap, hbmReturn, background);
if (!bitmap || !hbmReturn) return InvalidParameter; if (!bitmap || !hbmReturn) return InvalidParameter;
if (!image_lock(&bitmap->image, &unlock)) return ObjectBusy;
GdipGetImageWidth(&bitmap->image, &width); GdipGetImageWidth(&bitmap->image, &width);
GdipGetImageHeight(&bitmap->image, &height); GdipGetImageHeight(&bitmap->image, &height);
@ -1462,19 +1489,23 @@ GpStatus WINGDIPAPI GdipCreateHBITMAPFromBitmap(GpBitmap* bitmap,
bih.biClrImportant = 0; bih.biClrImportant = 0;
result = CreateDIBSection(0, (BITMAPINFO*)&bih, DIB_RGB_COLORS, (void**)&bits, NULL, 0); result = CreateDIBSection(0, (BITMAPINFO*)&bih, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
if (!result)
if (result)
{ {
lockeddata.Stride = -width * 4; image_unlock(&bitmap->image, unlock);
lockeddata.Scan0 = bits + (width * 4 * (height - 1)); return GenericError;
}
stat = GdipBitmapLockBits(bitmap, NULL, ImageLockModeRead|ImageLockModeUserInputBuf, stat = convert_pixels(width, height, -width*4,
PixelFormat32bppPARGB, &lockeddata); bits + (width * 4 * (height - 1)), PixelFormat32bppPARGB,
bitmap->stride, bitmap->bits, bitmap->format, bitmap->image.palette);
if (stat != Ok)
{
DeleteObject(result);
image_unlock(&bitmap->image, unlock);
return stat;
}
if (stat == Ok) if (background & 0xffffff)
stat = GdipBitmapUnlockBits(bitmap, &lockeddata);
if (stat == Ok && (background & 0xffffff))
{ {
DWORD *ptr; DWORD *ptr;
UINT i; UINT i;
@ -1484,19 +1515,10 @@ GpStatus WINGDIPAPI GdipCreateHBITMAPFromBitmap(GpBitmap* bitmap,
*ptr = blend_argb_no_bkgnd_alpha(*ptr, background); *ptr = blend_argb_no_bkgnd_alpha(*ptr, background);
} }
} }
}
else
stat = GenericError;
if (stat != Ok && result)
{
DeleteObject(result);
result = NULL;
}
*hbmReturn = result; *hbmReturn = result;
image_unlock(&bitmap->image, unlock);
return stat; return Ok;
} }
GpStatus WINGDIPAPI GdipCreateBitmapFromGraphics(INT width, INT height, GpStatus WINGDIPAPI GdipCreateBitmapFromGraphics(INT width, INT height,
@ -3736,6 +3758,7 @@ static GpStatus select_frame_wic(GpImage *image, UINT active_frame)
if(status != Ok) if(status != Ok)
return status; return status;
new_image->busy = image->busy;
memcpy(&new_image->format, &image->format, sizeof(GUID)); memcpy(&new_image->format, &image->format, sizeof(GUID));
free_image_data(image); free_image_data(image);
if (image->type == ImageTypeBitmap) if (image->type == ImageTypeBitmap)
@ -4239,30 +4262,39 @@ GpStatus WINGDIPAPI GdipImageSelectActiveFrame(GpImage *image, GDIPCONST GUID *d
{ {
GpStatus stat; GpStatus stat;
const struct image_codec *codec = NULL; const struct image_codec *codec = NULL;
BOOL unlock;
TRACE("(%p,%s,%u)\n", image, debugstr_guid(dimensionID), frame); TRACE("(%p,%s,%u)\n", image, debugstr_guid(dimensionID), frame);
if (!image || !dimensionID) if (!image || !dimensionID)
return InvalidParameter; return InvalidParameter;
if(!image_lock(image, &unlock))
return ObjectBusy;
if (frame >= image->frame_count) if (frame >= image->frame_count)
{ {
WARN("requested frame %u, but image has only %u\n", frame, image->frame_count); WARN("requested frame %u, but image has only %u\n", frame, image->frame_count);
image_unlock(image, unlock);
return InvalidParameter; return InvalidParameter;
} }
if (image->type != ImageTypeBitmap && image->type != ImageTypeMetafile) if (image->type != ImageTypeBitmap && image->type != ImageTypeMetafile)
{ {
WARN("invalid image type %d\n", image->type); WARN("invalid image type %d\n", image->type);
image_unlock(image, unlock);
return InvalidParameter; return InvalidParameter;
} }
if (image->current_frame == frame) if (image->current_frame == frame)
{
image_unlock(image, unlock);
return Ok; return Ok;
}
if (!image->decoder) if (!image->decoder)
{ {
TRACE("image doesn't have an associated decoder\n"); TRACE("image doesn't have an associated decoder\n");
image_unlock(image, unlock);
return Ok; return Ok;
} }
@ -4271,10 +4303,13 @@ GpStatus WINGDIPAPI GdipImageSelectActiveFrame(GpImage *image, GDIPCONST GUID *d
if (stat != Ok) if (stat != Ok)
{ {
WARN("can't find decoder info\n"); WARN("can't find decoder info\n");
image_unlock(image, unlock);
return stat; return stat;
} }
return codec->select_func(image, frame); stat = codec->select_func(image, frame);
image_unlock(image, unlock);
return stat;
} }
GpStatus WINGDIPAPI GdipLoadImageFromStream(IStream *stream, GpImage **image) GpStatus WINGDIPAPI GdipLoadImageFromStream(IStream *stream, GpImage **image)
@ -5284,11 +5319,14 @@ GpStatus WINGDIPAPI GdipImageRotateFlip(GpImage *image, RotateFlipType type)
UINT x, y, width, height; UINT x, y, width, height;
BitmapData src_lock, dst_lock; BitmapData src_lock, dst_lock;
GpStatus stat; GpStatus stat;
BOOL unlock;
TRACE("(%p, %u)\n", image, type); TRACE("(%p, %u)\n", image, type);
if (!image) if (!image)
return InvalidParameter; return InvalidParameter;
if (!image_lock(image, &unlock))
return ObjectBusy;
rotate_90 = type&1; rotate_90 = type&1;
flip_x = (type&6) == 2 || (type&6) == 4; flip_x = (type&6) == 2 || (type&6) == 4;
@ -5297,6 +5335,7 @@ GpStatus WINGDIPAPI GdipImageRotateFlip(GpImage *image, RotateFlipType type)
if (image->type != ImageTypeBitmap) if (image->type != ImageTypeBitmap)
{ {
FIXME("Not implemented for type %i\n", image->type); FIXME("Not implemented for type %i\n", image->type);
image_unlock(image, unlock);
return NotImplemented; return NotImplemented;
} }
@ -5306,6 +5345,7 @@ GpStatus WINGDIPAPI GdipImageRotateFlip(GpImage *image, RotateFlipType type)
if (bpp < 8) if (bpp < 8)
{ {
FIXME("Not implemented for %i bit images\n", bpp); FIXME("Not implemented for %i bit images\n", bpp);
image_unlock(image, unlock);
return NotImplemented; return NotImplemented;
} }
@ -5325,7 +5365,10 @@ GpStatus WINGDIPAPI GdipImageRotateFlip(GpImage *image, RotateFlipType type)
stat = GdipCreateBitmapFromScan0(width, height, 0, bitmap->format, NULL, &new_bitmap); stat = GdipCreateBitmapFromScan0(width, height, 0, bitmap->format, NULL, &new_bitmap);
if (stat != Ok) if (stat != Ok)
{
image_unlock(image, unlock);
return stat; return stat;
}
stat = GdipBitmapLockBits(bitmap, NULL, ImageLockModeRead, bitmap->format, &src_lock); stat = GdipBitmapLockBits(bitmap, NULL, ImageLockModeRead, bitmap->format, &src_lock);
@ -5385,6 +5428,7 @@ GpStatus WINGDIPAPI GdipImageRotateFlip(GpImage *image, RotateFlipType type)
else else
GdipDisposeImage(&new_bitmap->image); GdipDisposeImage(&new_bitmap->image);
image_unlock(image, unlock);
return stat; return stat;
} }

View file

@ -68,7 +68,7 @@ reactos/dll/win32/dciman32 # Synced to WineStaging-1.9.11
reactos/dll/win32/faultrep # Synced to WineStaging-1.9.11 reactos/dll/win32/faultrep # Synced to WineStaging-1.9.11
reactos/dll/win32/fontsub # Synced to WineStaging-1.9.13 reactos/dll/win32/fontsub # Synced to WineStaging-1.9.13
reactos/dll/win32/fusion # Synced to WineStaging-1.9.23 reactos/dll/win32/fusion # Synced to WineStaging-1.9.23
reactos/dll/win32/gdiplus # Synced to WineStaging-1.9.23 reactos/dll/win32/gdiplus # Synced to WineStaging-2.2
reactos/dll/win32/hhctrl.ocx # Synced to WineStaging-2.2 reactos/dll/win32/hhctrl.ocx # Synced to WineStaging-2.2
reactos/dll/win32/hlink # Synced to WineStaging-2.2 reactos/dll/win32/hlink # Synced to WineStaging-2.2
reactos/dll/win32/hnetcfg # Synced to WineStaging-1.9.16 reactos/dll/win32/hnetcfg # Synced to WineStaging-1.9.16