ReactOS.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008
December
November
October
September
August
July
June
May
April
March
February
January
2007
December
November
October
September
August
July
June
May
April
March
February
January
2006
December
November
October
September
August
July
June
May
April
March
February
January
2005
December
November
October
September
August
July
June
May
April
March
February
January
2004
December
November
October
September
August
July
June
May
April
March
February
List overview
Download
Ros-diffs
January 2018
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
April 2006
March 2006
February 2006
January 2006
----- 2005 -----
December 2005
November 2005
October 2005
September 2005
August 2005
July 2005
June 2005
May 2005
April 2005
March 2005
February 2005
January 2005
----- 2004 -----
December 2004
November 2004
October 2004
September 2004
August 2004
July 2004
June 2004
May 2004
April 2004
March 2004
February 2004
ros-diffs@reactos.org
37 participants
372 discussions
Start a n
N
ew thread
01/01: [HLINK] Sync with Wine 3.0. CORE-14225
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=73921e94128290a08598e…
commit 73921e94128290a08598ef479ce5cd7d997e2b34 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Fri Jan 19 00:23:23 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Fri Jan 19 00:23:23 2018 +0100 [HLINK] Sync with Wine 3.0. CORE-14225 --- dll/win32/hlink/browse_ctx.c | 27 +++++++++++++++++++++++---- dll/win32/hlink/link.c | 43 ++++++++++++++++++++++++------------------- media/doc/README.WINE | 2 +- 3 files changed, 48 insertions(+), 24 deletions(-) diff --git a/dll/win32/hlink/browse_ctx.c b/dll/win32/hlink/browse_ctx.c index 0e76284544..00007f6b52 100644 --- a/dll/win32/hlink/browse_ctx.c +++ b/dll/win32/hlink/browse_ctx.c @@ -95,10 +95,11 @@ static ULONG WINAPI IHlinkBC_fnRelease (IHlinkBrowseContext* iface) return ref; } +static const WCHAR szIdent[] = {'W','I','N','E','H','L','I','N','K',0}; + static HRESULT WINAPI IHlinkBC_Register(IHlinkBrowseContext* iface, DWORD dwReserved, IUnknown *piunk, IMoniker *pimk, DWORD *pdwRegister) { - static const WCHAR szIdent[] = {'W','I','N','E','H','L','I','N','K',0}; HlinkBCImpl *This = impl_from_IHlinkBrowseContext(iface); IMoniker *mon; IMoniker *composite; @@ -122,11 +123,29 @@ static HRESULT WINAPI IHlinkBC_Register(IHlinkBrowseContext* iface, return S_OK; } -static HRESULT WINAPI IHlinkBC_GetObject(IHlinkBrowseContext* face, +static HRESULT WINAPI IHlinkBC_GetObject(IHlinkBrowseContext* iface, IMoniker *pimk, BOOL fBindifRootRegistered, IUnknown **ppiunk) { - FIXME("\n"); - return E_NOTIMPL; + HlinkBCImpl *This = impl_from_IHlinkBrowseContext(iface); + IMoniker *mon; + IMoniker *composite; + IRunningObjectTable *ROT; + HRESULT hr; + + TRACE("(%p)->(%p, %d, %p)\n", This, pimk, fBindifRootRegistered, ppiunk); + + hr = CreateItemMoniker(NULL, szIdent, &mon); + if (FAILED(hr)) return hr; + CreateGenericComposite(mon, pimk, &composite); + + GetRunningObjectTable(0, &ROT); + hr = IRunningObjectTable_GetObject(ROT, composite, ppiunk); + + IRunningObjectTable_Release(ROT); + IMoniker_Release(composite); + IMoniker_Release(mon); + + return hr; } static HRESULT WINAPI IHlinkBC_Revoke(IHlinkBrowseContext* iface, diff --git a/dll/win32/hlink/link.c b/dll/win32/hlink/link.c index c240fccd36..88b7093c32 100644 --- a/dll/win32/hlink/link.c +++ b/dll/win32/hlink/link.c @@ -481,25 +481,33 @@ static HRESULT WINAPI IHlink_fnNavigate(IHlink* iface, DWORD grfHLNF, LPBC pbc, if (SUCCEEDED(r)) { - IBindCtx *bcxt; + IBindCtx *bcxt = NULL; IUnknown *unk = NULL; IHlinkTarget *target; - CreateBindCtx(0, &bcxt); - - RegisterBindStatusCallback(bcxt, pbsc, NULL, 0); - - r = IMoniker_BindToObject(mon, bcxt, NULL, &IID_IUnknown, (void**)&unk); - if (r == S_OK) - { - r = IUnknown_QueryInterface(unk, &IID_IHlinkTarget, (void**)&target); - IUnknown_Release(unk); - } - if (r == S_OK) + if (phbc) { - IHlinkTarget_SetBrowseContext(target, phbc); - r = IHlinkTarget_Navigate(target, grfHLNF, This->Location); - IHlinkTarget_Release(target); + r = IHlinkBrowseContext_GetObject(phbc, mon, TRUE, &unk); + if (r == S_FALSE) + { + CreateBindCtx(0, &bcxt); + RegisterBindStatusCallback(bcxt, pbsc, NULL, 0); + r = IMoniker_BindToObject(mon, bcxt, NULL, &IID_IUnknown, (void**)&unk); + } + if (r == S_OK) + { + r = IUnknown_QueryInterface(unk, &IID_IHlinkTarget, (void **)&target); + IUnknown_Release(unk); + } + if (r == S_OK) + { + if (bcxt) IHlinkTarget_SetBrowseContext(target, phbc); + r = IHlinkTarget_Navigate(target, grfHLNF, This->Location); + IHlinkTarget_Release(target); + } + + RevokeBindStatusCallback(bcxt, pbsc); + if (bcxt) IBindCtx_Release(bcxt); } else { @@ -511,12 +519,9 @@ static HRESULT WINAPI IHlink_fnNavigate(IHlink* iface, DWORD grfHLNF, LPBC pbc, { ShellExecuteW(NULL, szOpen, target, NULL, NULL, SW_SHOW); CoTaskMemFree(target); + r = DRAGDROP_S_DROP; } } - - RevokeBindStatusCallback(bcxt, pbsc); - - IBindCtx_Release(bcxt); IMoniker_Release(mon); } diff --git a/media/doc/README.WINE b/media/doc/README.WINE index d6031a54b7..e67bc01b74 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -70,7 +70,7 @@ reactos/dll/win32/fontsub # Synced to WineStaging-2.9 reactos/dll/win32/fusion # Synced to Wine-3.0 reactos/dll/win32/gdiplus # Synced to Wine-3.0 reactos/dll/win32/hhctrl.ocx # Synced to Wine-3.0 -reactos/dll/win32/hlink # Synced to WineStaging-2.9 +reactos/dll/win32/hlink # Synced to Wine-3.0 reactos/dll/win32/hnetcfg # Synced to WineStaging-2.9 reactos/dll/win32/httpapi # Synced to WineStaging-2.9 reactos/dll/win32/iccvid # Synced to WineStaging-2.9
6 years, 11 months
1
0
0
0
01/01: [HHCTRL.OCX] Sync with Wine 3.0. CORE-14225
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=8d2d12d7eeac24300add5…
commit 8d2d12d7eeac24300add5e41bec67fefa3783696 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Fri Jan 19 00:21:29 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Fri Jan 19 00:21:29 2018 +0100 [HHCTRL.OCX] Sync with Wine 3.0. CORE-14225 --- dll/win32/hhctrl.ocx/help.c | 9 +++------ media/doc/README.WINE | 2 +- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/dll/win32/hhctrl.ocx/help.c b/dll/win32/hhctrl.ocx/help.c index 3f3d2ffe51..add3b74dac 100644 --- a/dll/win32/hhctrl.ocx/help.c +++ b/dll/win32/hhctrl.ocx/help.c @@ -1596,7 +1596,7 @@ static LRESULT CALLBACK Help_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPA static BOOL HH_CreateHelpWindow(HHInfo *info) { - HWND hWnd, parent = 0; + HWND hWnd; RECT winPos = info->WinType.rcWindowPos; WNDCLASSEXW wcex; DWORD dwStyles, dwExStyles; @@ -1670,11 +1670,8 @@ static BOOL HH_CreateHelpWindow(HHInfo *info) caption = info->WinType.pszCaption; if (!*caption) caption = info->pCHMInfo->defTitle; - if (info->WinType.dwStyles & WS_CHILD) - parent = info->WinType.hwndCaller; - - hWnd = CreateWindowExW(dwExStyles, windowClassW, caption, - dwStyles, x, y, width, height, parent, NULL, hhctrl_hinstance, NULL); + hWnd = CreateWindowExW(dwExStyles, windowClassW, caption, dwStyles, x, y, width, height, + info->WinType.hwndCaller, NULL, hhctrl_hinstance, NULL); if (!hWnd) return FALSE; diff --git a/media/doc/README.WINE b/media/doc/README.WINE index 4cc97bd42a..d6031a54b7 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -69,7 +69,7 @@ reactos/dll/win32/faultrep # Synced to WineStaging-2.9 reactos/dll/win32/fontsub # Synced to WineStaging-2.9 reactos/dll/win32/fusion # Synced to Wine-3.0 reactos/dll/win32/gdiplus # Synced to Wine-3.0 -reactos/dll/win32/hhctrl.ocx # Synced to WineStaging-2.9 +reactos/dll/win32/hhctrl.ocx # Synced to Wine-3.0 reactos/dll/win32/hlink # Synced to WineStaging-2.9 reactos/dll/win32/hnetcfg # Synced to WineStaging-2.9 reactos/dll/win32/httpapi # Synced to WineStaging-2.9
6 years, 11 months
1
0
0
0
01/01: [GDIPLUS_WINETEST] Sync with Wine 3.0. CORE-14225
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=70c9f307473b3993b6f18…
commit 70c9f307473b3993b6f18fd7acd5ab92f9e94d63 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Fri Jan 19 00:20:03 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Fri Jan 19 00:20:03 2018 +0100 [GDIPLUS_WINETEST] Sync with Wine 3.0. CORE-14225 --- modules/rostests/winetests/gdiplus/CMakeLists.txt | 3 +- modules/rostests/winetests/gdiplus/brush.c | 113 +++++ modules/rostests/winetests/gdiplus/font.c | 134 +++++- modules/rostests/winetests/gdiplus/graphics.c | 139 +++++- modules/rostests/winetests/gdiplus/image.c | 502 +++++++-------------- modules/rostests/winetests/gdiplus/matrix.c | 1 + modules/rostests/winetests/gdiplus/metafile.c | 422 ++++++++--------- modules/rostests/winetests/gdiplus/pathiterator.c | 15 +- modules/rostests/winetests/gdiplus/resource.rc | 22 + .../rostests/winetests/gdiplus/wine_longname.sfd | 66 +++ .../rostests/winetests/gdiplus/wine_longname.ttf | Bin 0 -> 2216 bytes 11 files changed, 847 insertions(+), 570 deletions(-) diff --git a/modules/rostests/winetests/gdiplus/CMakeLists.txt b/modules/rostests/winetests/gdiplus/CMakeLists.txt index 6bac596c78..d73d3137cc 100644 --- a/modules/rostests/winetests/gdiplus/CMakeLists.txt +++ b/modules/rostests/winetests/gdiplus/CMakeLists.txt @@ -19,7 +19,8 @@ list(APPEND SOURCE add_executable(gdiplus_winetest ${SOURCE} guid.c - testlist.c) + testlist.c + resource.rc) set_module_type(gdiplus_winetest win32cui) add_importlibs(gdiplus_winetest gdiplus user32 gdi32 ole32 msvcrt kernel32) diff --git a/modules/rostests/winetests/gdiplus/brush.c b/modules/rostests/winetests/gdiplus/brush.c index ec9a74ba15..c012b97933 100644 --- a/modules/rostests/winetests/gdiplus/brush.c +++ b/modules/rostests/winetests/gdiplus/brush.c @@ -41,6 +41,95 @@ static void test_constructor_destructor(void) expect(Ok, status); } +static void test_createHatchBrush(void) +{ + GpStatus status; + GpHatch *brush; + + status = GdipCreateHatchBrush(HatchStyleMin, 1, 2, &brush); + expect(Ok, status); + ok(brush != NULL, "Expected the brush to be initialized.\n"); + + GdipDeleteBrush((GpBrush *)brush); + + status = GdipCreateHatchBrush(HatchStyleMax, 1, 2, &brush); + expect(Ok, status); + ok(brush != NULL, "Expected the brush to be initialized.\n"); + + GdipDeleteBrush((GpBrush *)brush); + + status = GdipCreateHatchBrush(HatchStyle05Percent, 1, 2, NULL); + expect(InvalidParameter, status); + + status = GdipCreateHatchBrush((HatchStyle)(HatchStyleMin - 1), 1, 2, &brush); + expect(InvalidParameter, status); + + status = GdipCreateHatchBrush((HatchStyle)(HatchStyleMax + 1), 1, 2, &brush); + expect(InvalidParameter, status); +} + +static void test_createLineBrushFromRectWithAngle(void) +{ + GpStatus status; + GpLineGradient *brush; + GpRectF rect1 = { 1, 3, 1, 2 }; + GpRectF rect2 = { 1, 3, -1, -2 }; + GpRectF rect3 = { 1, 3, 0, 1 }; + GpRectF rect4 = { 1, 3, 1, 0 }; + + status = GdipCreateLineBrushFromRectWithAngle(&rect1, 10, 11, 0, TRUE, WrapModeTile, &brush); + expect(Ok, status); + GdipDeleteBrush((GpBrush *) brush); + + status = GdipCreateLineBrushFromRectWithAngle(&rect2, 10, 11, 135, TRUE, (WrapMode)(WrapModeTile - 1), &brush); + expect(Ok, status); + GdipDeleteBrush((GpBrush *) brush); + + status = GdipCreateLineBrushFromRectWithAngle(&rect2, 10, 11, -225, FALSE, (WrapMode)(WrapModeTile - 1), &brush); + expect(Ok, status); + GdipDeleteBrush((GpBrush *) brush); + + status = GdipCreateLineBrushFromRectWithAngle(&rect1, 10, 11, 405, TRUE, (WrapMode)(WrapModeClamp + 1), &brush); + expect(Ok, status); + GdipDeleteBrush((GpBrush *) brush); + + status = GdipCreateLineBrushFromRectWithAngle(&rect1, 10, 11, 45, FALSE, (WrapMode)(WrapModeClamp + 1), &brush); + expect(Ok, status); + GdipDeleteBrush((GpBrush *) brush); + + status = GdipCreateLineBrushFromRectWithAngle(&rect1, 10, 11, 90, TRUE, WrapModeTileFlipX, &brush); + expect(Ok, status); + + status = GdipCreateLineBrushFromRectWithAngle(NULL, 10, 11, 90, TRUE, WrapModeTile, &brush); + expect(InvalidParameter, status); + + status = GdipCreateLineBrushFromRectWithAngle(&rect3, 10, 11, 90, TRUE, WrapModeTileFlipXY, &brush); + expect(OutOfMemory, status); + + status = GdipCreateLineBrushFromRectWithAngle(&rect4, 10, 11, 90, TRUE, WrapModeTileFlipXY, &brush); + expect(OutOfMemory, status); + + status = GdipCreateLineBrushFromRectWithAngle(&rect3, 10, 11, 90, TRUE, WrapModeTileFlipXY, NULL); + expect(InvalidParameter, status); + + status = GdipCreateLineBrushFromRectWithAngle(&rect4, 10, 11, 90, TRUE, WrapModeTileFlipXY, NULL); + expect(InvalidParameter, status); + + status = GdipCreateLineBrushFromRectWithAngle(&rect3, 10, 11, 90, TRUE, WrapModeClamp, &brush); + expect(InvalidParameter, status); + + status = GdipCreateLineBrushFromRectWithAngle(&rect4, 10, 11, 90, TRUE, WrapModeClamp, &brush); + expect(InvalidParameter, status); + + status = GdipCreateLineBrushFromRectWithAngle(&rect1, 10, 11, 90, TRUE, WrapModeClamp, &brush); + expect(InvalidParameter, status); + + status = GdipCreateLineBrushFromRectWithAngle(&rect1, 10, 11, 90, TRUE, WrapModeTile, NULL); + expect(InvalidParameter, status); + + GdipDeleteBrush((GpBrush *) brush); +} + static void test_type(void) { GpStatus status; @@ -1525,6 +1614,27 @@ static void test_pathgradientblend(void) expect(Ok, status); } +static void test_getHatchStyle(void) +{ + GpStatus status; + GpHatch *brush; + GpHatchStyle hatchStyle; + + GdipCreateHatchBrush(HatchStyleHorizontal, 11, 12, &brush); + + status = GdipGetHatchStyle(NULL, &hatchStyle); + expect(InvalidParameter, status); + + status = GdipGetHatchStyle(brush, NULL); + expect(InvalidParameter, status); + + status = GdipGetHatchStyle(brush, &hatchStyle); + expect(Ok, status); + expect(HatchStyleHorizontal, hatchStyle); + + GdipDeleteBrush((GpBrush *)brush); +} + START_TEST(brush) { struct GdiplusStartupInput gdiplusStartupInput; @@ -1559,6 +1669,8 @@ START_TEST(brush) GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); test_constructor_destructor(); + test_createHatchBrush(); + test_createLineBrushFromRectWithAngle(); test_type(); test_gradientblendcount(); test_getblend(); @@ -1574,6 +1686,7 @@ START_TEST(brush) test_pathgradientcenterpoint(); test_pathgradientpresetblend(); test_pathgradientblend(); + test_getHatchStyle(); GdiplusShutdown(gdiplusToken); DestroyWindow(hwnd); diff --git a/modules/rostests/winetests/gdiplus/font.c b/modules/rostests/winetests/gdiplus/font.c index b68c2ba539..de8e64dc59 100644 --- a/modules/rostests/winetests/gdiplus/font.c +++ b/modules/rostests/winetests/gdiplus/font.c @@ -39,6 +39,78 @@ static void set_rect_empty(RectF *rc) rc->Height = 0.0; } +static void create_testfontfile(const WCHAR *filename, int resource, WCHAR pathW[MAX_PATH]) +{ + DWORD written; + HANDLE file; + HRSRC res; + void *ptr; + + GetTempPathW(MAX_PATH, pathW); + lstrcatW(pathW, filename); + + file = CreateFileW(pathW, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0); + ok(file != INVALID_HANDLE_VALUE, "file creation failed, at %s, error %d\n", wine_dbgstr_w(pathW), GetLastError()); + + res = FindResourceA(GetModuleHandleA(NULL), MAKEINTRESOURCEA(resource), (LPCSTR)RT_RCDATA); + ok(res != 0, "couldn't find resource\n"); + ptr = LockResource(LoadResource(GetModuleHandleA(NULL), res)); + WriteFile(file, ptr, SizeofResource(GetModuleHandleA(NULL), res), &written, NULL); + ok(written == SizeofResource(GetModuleHandleA(NULL), res), "couldn't write resource\n"); + CloseHandle(file); +} + +#define DELETE_FONTFILE(filename) _delete_testfontfile(filename, __LINE__) +static void _delete_testfontfile(const WCHAR *filename, int line) +{ + BOOL ret = DeleteFileW(filename); + ok_(__FILE__,line)(ret, "failed to delete file %s, error %d\n", wine_dbgstr_w(filename), GetLastError()); +} + +static void test_long_name(void) +{ + WCHAR path[MAX_PATH]; + static const WCHAR path_longname[] = {'w','i','n','e','_','l','o','n','g','n','a','m','e','.','t','t','f',0}; + GpStatus stat; + GpFontCollection *fonts; + INT num_families; + GpFontFamily *family; + WCHAR family_name[LF_FACESIZE]; + GpFont *font; + + stat = GdipNewPrivateFontCollection(&fonts); + ok(stat == Ok, "GdipNewPrivateFontCollection failed: %d\n", stat); + + create_testfontfile(path_longname, 1, path); + + stat = GdipPrivateAddFontFile(fonts, path); + ok(stat == Ok, "GdipPrivateAddFontFile failed: %d\n", stat); + + stat = GdipGetFontCollectionFamilyCount(fonts, &num_families); + ok(stat == Ok, "GdipGetFontCollectionFamilyCount failed: %d\n", stat); + + ok(num_families == 1, "expected num_families to be 1, got %d\n", num_families); + + stat = GdipGetFontCollectionFamilyList(fonts, num_families, &family, &num_families); + ok(stat == Ok, "GdipGetFontCollectionFamilyList failed: %d\n", stat); + + stat = GdipGetFamilyName(family, family_name, LANG_NEUTRAL); + ok(stat == Ok, "GdipGetFamilyName failed: %d\n", stat); + + stat = GdipCreateFont(family, 256.0, FontStyleRegular, UnitPixel, &font); + ok(stat == Ok, "GdipCreateFont failed: %d\n", stat); + + /* Cleanup */ + + stat = GdipDeleteFont(font); + ok(stat == Ok, "GdipDeleteFont failed: %d\n", stat); + + stat = GdipDeletePrivateFontCollection(&fonts); + ok(stat == Ok, "GdipDeletePrivateFontCollection failed: %d\n", stat); + + DELETE_FONTFILE(path); +} + static void test_createfont(void) { GpFontFamily* fontfamily = NULL, *fontfamily2; @@ -79,7 +151,8 @@ static void test_createfont(void) for (i = UnitWorld; i <=UnitMillimeter; i++) { if (i == UnitDisplay) continue; /* Crashes WindowsXP, wtf? */ - GdipCreateFont(fontfamily, 24, FontStyleRegular, i, &font); + stat = GdipCreateFont(fontfamily, 24, FontStyleRegular, i, &font); + expect(Ok, stat); GdipGetFontSize (font, &size); ok (size == 24, "Expected 24, got %f (with unit: %d)\n", size, i); GdipGetFontUnit (font, &unit); @@ -103,7 +176,8 @@ static void test_logfont(void) UINT16 em_height, line_spacing; Unit unit; - GdipCreateFromHDC(hdc, &graphics); + stat = GdipCreateFromHDC(hdc, &graphics); + expect(Ok, stat); memset(&lfa, 0, sizeof(LOGFONTA)); memset(&lfa2, 0xff, sizeof(LOGFONTA)); @@ -1106,6 +1180,60 @@ todo_wine DeleteDC(hdc); } +static void test_GdipGetFontCollectionFamilyList(void) +{ + GpFontFamily *family, *family2; + GpFontCollection *collection; + INT found, count; + GpStatus status; + + status = GdipNewInstalledFontCollection(&collection); + ok(status == Ok, "Failed to get system collection, status %d.\n", status); + + count = 0; + status = GdipGetFontCollectionFamilyCount(collection, &count); + ok(status == Ok, "Failed to get family count, status %d.\n", status); + ok(count > 0, "Unexpected empty collection.\n"); + + status = GdipGetFontCollectionFamilyList(NULL, 0, NULL, NULL); + ok(status == InvalidParameter, "Unexpected status %d.\n", status); + + found = 123; + status = GdipGetFontCollectionFamilyList(NULL, 0, NULL, &found); + ok(status == InvalidParameter, "Unexpected status %d.\n", status); + ok(found == 123, "Unexpected list count %d.\n", found); + + status = GdipGetFontCollectionFamilyList(collection, 0, NULL, NULL); + ok(status == InvalidParameter, "Unexpected status %d.\n", status); + + found = 123; + status = GdipGetFontCollectionFamilyList(collection, 0, NULL, &found); + ok(status == InvalidParameter, "Unexpected status %d.\n", status); + ok(found == 123, "Unexpected list count %d.\n", found); + + found = 123; + status = GdipGetFontCollectionFamilyList(collection, 1, NULL, &found); + ok(status == InvalidParameter, "Unexpected status %d.\n", status); + ok(found == 123, "Unexpected list count %d.\n", found); + + family = NULL; + found = 0; + status = GdipGetFontCollectionFamilyList(collection, 1, &family, &found); + ok(status == Ok, "Failed to get family list, status %d.\n", status); + ok(found == 1, "Unexpected list count %d.\n", found); + ok(family != NULL, "Expected family instance.\n"); + + family = NULL; + found = 0; + status = GdipGetFontCollectionFamilyList(collection, 1, &family2, &found); + ok(status == Ok, "Failed to get family list, status %d.\n", status); + ok(found == 1, "Unexpected list count %d.\n", found); + ok(family2 != family, "Unexpected family instance.\n"); + + GdipDeleteFontFamily(family); + GdipDeleteFontFamily(family2); +} + START_TEST(font) { struct GdiplusStartupInput gdiplusStartupInput; @@ -1125,6 +1253,7 @@ START_TEST(font) GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); + test_long_name(); test_font_transform(); if (!winetest_interactive) skip("ROSTESTS-154: Skipping test_font_substitution because of improper error handling\n"); @@ -1138,6 +1267,7 @@ START_TEST(font) test_getgenerics(); test_installedfonts(); test_heightgivendpi(); + test_GdipGetFontCollectionFamilyList(); GdiplusShutdown(gdiplusToken); } diff --git a/modules/rostests/winetests/gdiplus/graphics.c b/modules/rostests/winetests/gdiplus/graphics.c index 2ea529b496..2c0221c10c 100644 --- a/modules/rostests/winetests/gdiplus/graphics.c +++ b/modules/rostests/winetests/gdiplus/graphics.c @@ -361,7 +361,8 @@ static void test_save_restore(void) log_state(state_a, &state_log); /* BeginContainer and SaveGraphics use the same stack. */ - GdipCreateFromHDC(hdc, &graphics1); + stat = GdipCreateFromHDC(hdc, &graphics1); + expect(Ok, stat); GdipSetInterpolationMode(graphics1, InterpolationModeBilinear); stat = GdipBeginContainer2(graphics1, &state_a); expect(Ok, stat); @@ -727,7 +728,8 @@ static void test_BeginContainer2(void) status = GdipCreateMatrix(&transform); expect(Ok, status); GdipGetWorldTransform(graphics, transform); - GdipGetMatrixElements(transform, elems); + status = GdipGetMatrixElements(transform, elems); + expect(Ok, status); ok(fabs(defTrans[0] - elems[0]) < 0.0001 && fabs(defTrans[1] - elems[1]) < 0.0001 && fabs(defTrans[2] - elems[2]) < 0.0001 && @@ -1596,10 +1598,12 @@ static void test_Get_Release_DC(void) status = GdipCreateMatrix(&m); expect(Ok, status); - GdipCreateRegion(®ion); + status = GdipCreateRegion(®ion); + expect(Ok, status); GdipCreateSolidFill((ARGB)0xdeadbeef, &brush); GdipCreatePath(FillModeAlternate, &path); - GdipCreateRegion(&clip); + status = GdipCreateRegion(&clip); + expect(Ok, status); status = GdipCreateFromHDC(hdc, &graphics); expect(Ok, status); @@ -6221,11 +6225,6 @@ static DWORD* GetBitmapPixelBuffer(HDC hdc, HBITMAP hbmp, int width, int height) return buffer; } -static void ReleaseBitmapPixelBuffer(DWORD* buffer) -{ - if (buffer) GdipFree(buffer); -} - static void test_GdipFillRectanglesOnMemoryDCSolidBrush(void) { ARGB color[6] = {0,0,0,0,0,0}; @@ -6275,7 +6274,7 @@ static void test_GdipFillRectanglesOnMemoryDCSolidBrush(void) ok(is_blue_color(color[0]) && is_blue_color(color[1]) && is_blue_color(color[2]) && color[3] == 0 && color[4] == 0 && color[5] == 0, "Expected GdipFillRectangleI take effect!\n" ); - ReleaseBitmapPixelBuffer(pixel); + GdipFree(pixel); SelectObject(hdc, old); DeleteObject(bmp); @@ -6360,7 +6359,7 @@ static void test_GdipFillRectanglesOnMemoryDCTextureBrush(void) ok(is_blue_color(color[0]) && is_blue_color(color[1]) && is_blue_color(color[2]) && color[3] == 0 && color[4] == 0 && color[5] == 0, "Expected GdipFillRectangleI take effect!\n" ); - ReleaseBitmapPixelBuffer(pixel); + GdipFree(pixel); SelectObject(hdc, old); DeleteObject(bmp); @@ -6517,7 +6516,7 @@ static void test_GdipDrawImagePointsRectOnMemoryDC(void) ok(is_blue_color(color[0]) && is_blue_color(color[1]) && is_blue_color(color[2]) && color[3] == 0 && color[4] == 0 && color[5] == 0, "Expected GdipDrawImageRectRectI take effect!\n" ); - ReleaseBitmapPixelBuffer(pixel); + GdipFree(pixel); SelectObject(hdc, old); DeleteObject(bmp); @@ -6525,6 +6524,120 @@ static void test_GdipDrawImagePointsRectOnMemoryDC(void) ReleaseDC(hwnd, dc); } +static void test_cliphrgn_transform(void) +{ + HDC hdc; + GpStatus status; + GpGraphics *graphics; + HRGN rgn; + RectF rectf; + BOOL res; + + hdc = GetDC(hwnd); + + SetViewportOrgEx(hdc, 10, 10, NULL); + + status = GdipCreateFromHDC(hdc, &graphics); + expect(Ok, status); + + rgn = CreateRectRgn(0, 0, 100, 100); + + status = GdipSetClipHrgn(graphics, rgn, CombineModeReplace); + expect(Ok, status); + + status = GdipGetVisibleClipBounds(graphics, &rectf); + expect(Ok, status); + expectf(-10.0, rectf.X); + expectf(-10.0, rectf.Y); + expectf(100.0, rectf.Width); + expectf(100.0, rectf.Height); + + status = GdipIsVisiblePoint(graphics, 95, 95, &res); + expect(Ok, status); + expect(FALSE, res); + + status = GdipIsVisiblePoint(graphics, -5, -5, &res); + expect(Ok, status); + expect(TRUE, res); + + DeleteObject(rgn); + + GdipDeleteGraphics(graphics); + + SetViewportOrgEx(hdc, 0, 0, NULL); + + ReleaseDC(hwnd, hdc); +} + +static void test_hdc_caching(void) +{ + GpStatus status; + HDC hdc; + HBITMAP hbm; + GpGraphics *graphics; + ULONG *bits; + BITMAPINFO bmi; + HRGN hrgn; + GpBrush *brush; + + hdc = CreateCompatibleDC(0); + ok(hdc != NULL, "CreateCompatibleDC failed\n"); + bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader); + bmi.bmiHeader.biHeight = -5; + bmi.bmiHeader.biWidth = 5; + bmi.bmiHeader.biBitCount = 32; + bmi.bmiHeader.biPlanes = 1; + bmi.bmiHeader.biCompression = BI_RGB; + bmi.bmiHeader.biClrUsed = 0; + + hbm = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0); + ok(hbm != NULL, "CreateDIBSection failed\n"); + + SelectObject(hdc, hbm); + + SetViewportOrgEx(hdc, 1, 1, NULL); + + hrgn = CreateRectRgn(0, 0, 3, 3); + SelectClipRgn(hdc, hrgn); + DeleteObject(hrgn); + + status = GdipCreateSolidFill((ARGB)0xffaaaaaa, (GpSolidFill**)&brush); + expect(Ok, status); + + status = GdipCreateFromHDC(hdc, &graphics); + expect(Ok, status); + + memset(bits, 0, sizeof(*bits) * 25); + status = GdipFillRectangleI(graphics, brush, 0, 0, 4, 4); + expect(Ok, status); + + expect(0, bits[0]); + expect(0xffaaaaaa, bits[6]); + expect(0xffaaaaaa, bits[12]); + expect(0, bits[18]); + expect(0, bits[24]); + + SetViewportOrgEx(hdc, 0, 0, NULL); + OffsetClipRgn(hdc, 2, 2); + + memset(bits, 0, sizeof(*bits) * 25); + status = GdipFillRectangleI(graphics, brush, 0, 0, 4, 4); + expect(Ok, status); + + expect(0, bits[0]); + expect(0xffaaaaaa, bits[6]); + expect(0xffaaaaaa, bits[12]); + expect(0, bits[18]); + expect(0, bits[24]); + + GdipDeleteGraphics(graphics); + + GdipDeleteBrush(brush); + + DeleteDC(hdc); + DeleteObject(hbm); +} + START_TEST(graphics) { struct GdiplusStartupInput gdiplusStartupInput; @@ -6614,6 +6727,8 @@ START_TEST(graphics) test_GdipDrawImagePointsRectOnMemoryDC(); test_container_rects(); test_GdipGraphicsSetAbort(); + test_cliphrgn_transform(); + test_hdc_caching(); GdiplusShutdown(gdiplusToken); DestroyWindow( hwnd ); diff --git a/modules/rostests/winetests/gdiplus/image.c b/modules/rostests/winetests/gdiplus/image.c index d87df83127..96e988ccba 100644 --- a/modules/rostests/winetests/gdiplus/image.c +++ b/modules/rostests/winetests/gdiplus/image.c @@ -2,7 +2,7 @@ * Unit test suite for images * * Copyright (C) 2007 Google (Evan Stade) - * Copyright (C) 2012,2016 Dmitry Timoshkov + * Copyright (C) 2012, 2016 Dmitry Timoshkov * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -41,8 +41,6 @@ static GpStatus (WINAPI *pGdipBitmapGetHistogramSize)(HistogramFormat,UINT*); static GpStatus (WINAPI *pGdipBitmapGetHistogram)(GpBitmap*,HistogramFormat,UINT,UINT*,UINT*,UINT*,UINT*); static GpStatus (WINAPI *pGdipImageSetAbort)(GpImage*,GdiplusAbort*); -static GpStatus (WINGDIPAPI *pGdipInitializePalette)(ColorPalette*,PaletteType,INT,BOOL,GpBitmap*); - #define expect(expected, got) ok((got) == (expected), "Expected %d, got %d\n", (UINT)(expected), (UINT)(got)) #define expectf(expected, got) ok(fabs((expected) - (got)) < 0.0001, "Expected %f, got %f\n", (expected), (got)) @@ -376,7 +374,8 @@ static void test_GdipImageGetFrameDimensionsCount(void) /* SelectActiveFrame has no effect on image data of memory bitmaps */ color = 0xdeadbeef; - GdipBitmapGetPixel(bm, 0, 0, &color); + stat = GdipBitmapGetPixel(bm, 0, 0, &color); + expect(Ok, stat); expect(0xffffffff, color); GdipDisposeImage((GpImage*)bm); @@ -1779,6 +1778,7 @@ static void test_createhbitmap(void) } /* create HBITMAP with bkgnd colour */ + /* gdiplus.dll 5.1 is broken and only applies the blue value */ stat = GdipCreateHBITMAPFromBitmap(bitmap, &hbitmap, 0xff00ff); expect(Ok, stat); @@ -1798,20 +1798,20 @@ static void test_createhbitmap(void) if (bm.bmBits) { DWORD val = *(DWORD*)bm.bmBits; - ok(val == 0x68c12ac1, "got %x, expected 0x682a2a2a\n", val); + ok(val == 0x68c12ac1 || broken(val == 0x682a2ac1), "got %x, expected 0x68c12ac1\n", val); val = *((DWORD*)bm.bmBits + (bm.bmHeight-1) * bm.bmWidthBytes/4 + 1); - ok(val == 0xff00ff, "got %x, expected 0x682a2a2a\n", val); + ok(val == 0xff00ff || broken(val == 0xff), "got %x, expected 0xff00ff\n", val); } hdc = CreateCompatibleDC(NULL); oldhbitmap = SelectObject(hdc, hbitmap); pixel = GetPixel(hdc, 5, 5); - expect(0xc12ac1, pixel); + ok(pixel == 0xc12ac1 || broken(pixel == 0xc12a2a), "got %x, expected 0xc12ac1\n", pixel); pixel = GetPixel(hdc, 1, 0); - expect(0xff00ff, pixel); + ok(pixel == 0xff00ff || broken(pixel == 0xff0000), "got %x, expected 0xff00ff\n", pixel); pixel = GetPixel(hdc, 2, 0); - expect(0xb12ac1, pixel); + ok(pixel == 0xb12ac1 || broken(pixel == 0xb12a2a), "got %x, expected 0xb12ac1\n", pixel); SelectObject(hdc, oldhbitmap); DeleteDC(hdc); @@ -1838,20 +1838,20 @@ static void test_createhbitmap(void) if (bm.bmBits) { DWORD val = *(DWORD*)bm.bmBits; - ok(val == 0x68c12ac1, "got %x, expected 0x682a2a2a\n", val); + ok(val == 0x68c12ac1 || broken(val == 0x682a2ac1), "got %x, expected 0x68c12ac1\n", val); val = *((DWORD*)bm.bmBits + (bm.bmHeight-1) * bm.bmWidthBytes/4 + 1); - ok(val == 0xff00ff, "got %x, expected 0x682a2a2a\n", val); + ok(val == 0xff00ff || broken(val == 0xff), "got %x, expected 0xff00ff\n", val); } hdc = CreateCompatibleDC(NULL); oldhbitmap = SelectObject(hdc, hbitmap); pixel = GetPixel(hdc, 5, 5); - expect(0xc12ac1, pixel); + ok(pixel == 0xc12ac1 || broken(pixel == 0xc12a2a), "got %x, expected 0xc12ac1\n", pixel); pixel = GetPixel(hdc, 1, 0); - expect(0xff00ff, pixel); + ok(pixel == 0xff00ff || broken(pixel == 0xff0000), "got %x, expected 0xff00ff\n", pixel); pixel = GetPixel(hdc, 2, 0); - expect(0xb12ac1, pixel); + ok(pixel == 0xb12ac1 || broken(pixel == 0xb12a2a), "got %x, expected 0xb12ac1\n", pixel); SelectObject(hdc, oldhbitmap); DeleteDC(hdc); @@ -2382,10 +2382,44 @@ static void test_colormatrix(void) expect(Ok, stat); ok(color_match(0xeeff40cc, color, 3), "expected 0xeeff40cc, got 0x%08x\n", color); + /* Toggle NoOp */ + stat = GdipSetImageAttributesNoOp(imageattr, ColorAdjustTypeDefault, FALSE); + expect(Ok, stat); + + stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1, + UnitPixel, imageattr, NULL, NULL); + expect(Ok, stat); + + stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color); + expect(Ok, stat); + ok(color_match(0xfefe40cc, color, 3), "expected 0xfefe40cc, got 0x%08x\n", color); + + stat = GdipSetImageAttributesNoOp(imageattr, ColorAdjustTypeDefault, TRUE); + expect(Ok, stat); + + stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1, + UnitPixel, imageattr, NULL, NULL); + expect(Ok, stat); + + stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color); + expect(Ok, stat); + ok(color_match(0xff40ccee, color, 3), "expected 0xff40ccee, got 0x%08x\n", color); + stat = GdipResetImageAttributes(imageattr, ColorAdjustTypeDefault); expect(Ok, stat); - stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1, + stat = GdipSetImageAttributesNoOp(imageattr, ColorAdjustTypeDefault, FALSE); + expect(Ok, stat); + + stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1, + UnitPixel, imageattr, NULL, NULL); + expect(Ok, stat); + + stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color); + expect(Ok, stat); + ok(color_match(0xff40ccee, color, 3), "expected 0xff40ccee, got 0x%08x\n", color); + + stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1, UnitPixel, imageattr, NULL, NULL); expect(Ok, stat); @@ -2393,6 +2427,101 @@ static void test_colormatrix(void) expect(Ok, stat); ok(color_match(0xff40ccee, color, 1), "Expected ff40ccee, got %.8x\n", color); + /* Disable adjustment, toggle NoOp */ + stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault, + FALSE, &colormatrix, NULL, ColorMatrixFlagsDefault); + expect(Ok, stat); + + stat = GdipSetImageAttributesNoOp(imageattr, ColorAdjustTypeDefault, FALSE); + expect(Ok, stat); + + stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1, + UnitPixel, imageattr, NULL, NULL); + expect(Ok, stat); + + stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color); + expect(Ok, stat); + ok(color_match(0xff40ccee, color, 3), "expected 0xff40ccee, got 0x%08x\n", color); + + stat = GdipSetImageAttributesNoOp(imageattr, ColorAdjustTypeDefault, TRUE); + expect(Ok, stat); + + stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1, + UnitPixel, imageattr, NULL, NULL); + expect(Ok, stat); + + stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color); + expect(Ok, stat); + ok(color_match(0xff40ccee, color, 3), "expected 0xff40ccee, got 0x%08x\n", color); + + /* Reset with NoOp on, enable adjustment. */ + stat = GdipResetImageAttributes(imageattr, ColorAdjustTypeDefault); + expect(Ok, stat); + + stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault, + TRUE, &colormatrix, NULL, ColorMatrixFlagsDefault); + expect(Ok, stat); + + stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1, + UnitPixel, imageattr, NULL, NULL); + expect(Ok, stat); + + stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color); + expect(Ok, stat); + ok(color_match(0xfff24ace, color, 3), "expected 0xfff24ace, got 0x%08x\n", color); + + /* Now inhibit specific category. */ + stat = GdipResetImageAttributes(imageattr, ColorAdjustTypeDefault); + expect(Ok, stat); + + stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeBitmap, + TRUE, &colormatrix, NULL, ColorMatrixFlagsDefault); + expect(Ok, stat); + + stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1, + UnitPixel, imageattr, NULL, NULL); + expect(Ok, stat); + + stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color); + expect(Ok, stat); + ok(color_match(0xfffe41cc, color, 3), "expected 0xfffe41cc, got 0x%08x\n", color); + + stat = GdipSetImageAttributesNoOp(imageattr, ColorAdjustTypeBitmap, TRUE); + expect(Ok, stat); + + stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1, + UnitPixel, imageattr, NULL, NULL); + expect(Ok, stat); + + stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color); + expect(Ok, stat); + ok(color_match(0xff40ccee, color, 3), "expected 0xff40ccee, got 0x%08x\n", color); + + stat = GdipSetImageAttributesNoOp(imageattr, ColorAdjustTypeBitmap, FALSE); + expect(Ok, stat); + + stat = GdipSetImageAttributesNoOp(imageattr, ColorAdjustTypeDefault, TRUE); + expect(Ok, stat); + + stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1, + UnitPixel, imageattr, NULL, NULL); + expect(Ok, stat); + + stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color); + expect(Ok, stat); + ok(color_match(0xfff24ace, color, 3), "expected 0xfff24ace, got 0x%08x\n", color); + + stat = GdipResetImageAttributes(imageattr, ColorAdjustTypeBitmap); + expect(Ok, stat); + + stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1, + UnitPixel, imageattr, NULL, NULL); + expect(Ok, stat); + + stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color); + expect(Ok, stat); + ok(color_match(0xff40ccee, color, 3), "expected 0xff40ccee, got 0x%08x\n", color); + GdipDeleteGraphics(graphics); GdipDisposeImage((GpImage*)bitmap1); GdipDisposeImage((GpImage*)bitmap2); @@ -2603,7 +2732,7 @@ static void test_multiframegif(void) expect(Ok, stat); color = 0xdeadbeef; - GdipBitmapGetPixel(bmp, 0, 0, &color); + stat = GdipBitmapGetPixel(bmp, 0, 0, &color); expect(Ok, stat); expect(0xffffffff, color); @@ -3119,6 +3248,8 @@ static GpImage *load_image(const BYTE *image_data, UINT image_size) ok(refcount == 1, "expected stream refcount 1, got %d\n", refcount); status = GdipLoadImageFromStream(stream, &image); + ok(status == Ok || broken(status == InvalidParameter), /* XP */ + "GdipLoadImageFromStream error %d\n", status); if (status != Ok) { IStream_Release(stream); @@ -4673,13 +4804,14 @@ static void test_supported_encoders(void) { LPCWSTR mime; const GUID *format; + BOOL todo; } td[] = { - { bmp_mimetype, &ImageFormatBMP }, - { jpeg_mimetype, &ImageFormatJPEG }, - { gif_mimetype, &ImageFormatGIF }, - { tiff_mimetype, &ImageFormatTIFF }, - { png_mimetype, &ImageFormatPNG } + { bmp_mimetype, &ImageFormatBMP, FALSE }, + { jpeg_mimetype, &ImageFormatJPEG, FALSE }, + { gif_mimetype, &ImageFormatGIF, TRUE }, + { tiff_mimetype, &ImageFormatTIFF, FALSE }, + { png_mimetype, &ImageFormatPNG, FALSE } }; GUID format, clsid; BOOL ret; @@ -4705,7 +4837,8 @@ static void test_supported_encoders(void) ok(hr == S_OK, "CreateStreamOnHGlobal error %#x\n", hr); status = GdipSaveImageToStream((GpImage *)bm, stream, &clsid, NULL); - ok(status == Ok, "GdipSaveImageToStream error %d\n", status); + todo_wine_if (td[i].todo) + ok(status == Ok, "GdipSaveImageToStream error %d\n", status); IStream_Release(stream); } @@ -5035,329 +5168,6 @@ static void test_png_color_formats(void) } } -static BYTE *init_bitmap(UINT *width, UINT *height, UINT *stride) -{ - BYTE *src; - UINT i, j, scale; - - *width = 256; - *height = 256; - *stride = (*width * 3 + 3) & ~3; - trace("width %d, height %d, stride %d\n", *width, *height, *stride); - - src = HeapAlloc(GetProcessHeap(), 0, *stride * *height); - - scale = 256 / *width; - if (!scale) scale = 1; - - for (i = 0; i < *height; i++) - { - for (j = 0; j < *width; j++) - { - src[i * *stride + j*3 + 0] = scale * i; - src[i * *stride + j*3 + 1] = scale * (255 - (i+j)/2); - src[i * *stride + j*3 + 2] = scale * j; - } - } - - return src; -} - -static void test_GdipInitializePalette(void) -{ - GpStatus status; - BYTE *data; - GpBitmap *bitmap; - ColorPalette *palette; - UINT width, height, stride; - - pGdipInitializePalette = (void *)GetProcAddress(GetModuleHandleA("gdiplus.dll"), "GdipInitializePalette"); - if (!pGdipInitializePalette) - { - win_skip("GdipInitializePalette is not supported on this platform\n"); - return; - } - - data = init_bitmap(&width, &height, &stride); - - status = GdipCreateBitmapFromScan0(width, height, stride, PixelFormat24bppRGB, data, &bitmap); - expect(Ok, status); - - palette = GdipAlloc(sizeof(*palette) + sizeof(ARGB) * 255); - - palette->Flags = 0; - palette->Count = 15; - status = pGdipInitializePalette(palette, PaletteTypeOptimal, 16, FALSE, bitmap); - expect(GenericError, status); - - palette->Flags = 0; - palette->Count = 256; - status = pGdipInitializePalette(palette, PaletteTypeOptimal, 16, FALSE, NULL); - expect(InvalidParameter, status); - - memset(palette->Entries, 0x11, sizeof(ARGB) * 256); - palette->Flags = 0; - palette->Count = 256; - status = pGdipInitializePalette(palette, PaletteTypeCustom, 16, FALSE, NULL); - expect(Ok, status); - expect(0, palette->Flags); - expect(256, palette->Count); - expect(0x11111111, palette->Entries[0]); - expect(0x11111111, palette->Entries[128]); - expect(0x11111111, palette->Entries[255]); - - memset(palette->Entries, 0x11, sizeof(ARGB) * 256); - palette->Flags = 0; - palette->Count = 256; - status = pGdipInitializePalette(palette, PaletteTypeFixedBW, 0, FALSE, bitmap); - expect(Ok, status); -todo_wine - expect(0x200, palette->Flags); - expect(2, palette->Count); - expect(0xff000000, palette->Entries[0]); - expect(0xffffffff, palette->Entries[1]); - - memset(palette->Entries, 0x11, sizeof(ARGB) * 256); - palette->Flags = 0; - palette->Count = 256; - status = pGdipInitializePalette(palette, PaletteTypeFixedHalftone8, 1, FALSE, NULL); - expect(Ok, status); -todo_wine - expect(0x300, palette->Flags); - expect(16, palette->Count); - expect(0xff000000, palette->Entries[0]); - expect(0xffc0c0c0, palette->Entries[8]); - expect(0xff008080, palette->Entries[15]); - - memset(palette->Entries, 0x11, sizeof(ARGB) * 256); - palette->Flags = 0; - palette->Count = 256; - status = pGdipInitializePalette(palette, PaletteTypeFixedHalftone8, 1, FALSE, bitmap); - expect(Ok, status); -todo_wine - expect(0x300, palette->Flags); - expect(16, palette->Count); - expect(0xff000000, palette->Entries[0]); - expect(0xffc0c0c0, palette->Entries[8]); - expect(0xff008080, palette->Entries[15]); - - memset(palette->Entries, 0x11, sizeof(ARGB) * 256); - palette->Flags = 0; - palette->Count = 256; - status = pGdipInitializePalette(palette, PaletteTypeFixedHalftone252, 1, FALSE, bitmap); - expect(Ok, status); -todo_wine - expect(0x800, palette->Flags); - expect(252, palette->Count); - expect(0xff000000, palette->Entries[0]); - expect(0xff990066, palette->Entries[128]); - expect(0xffffffff, palette->Entries[251]); - - palette->Flags = 0; - palette->Count = 256; - status = pGdipInitializePalette(palette, PaletteTypeOptimal, 1, FALSE, bitmap); - expect(InvalidParameter, status); - - palette->Flags = 0; - palette->Count = 256; - status = pGdipInitializePalette(palette, PaletteTypeOptimal, 2, FALSE, bitmap); - expect(Ok, status); - expect(0, palette->Flags); - expect(2, palette->Count); - - palette->Flags = 0; - palette->Count = 256; - status = pGdipInitializePalette(palette, PaletteTypeOptimal, 16, FALSE, bitmap); - expect(Ok, status); - expect(0, palette->Flags); - expect(16, palette->Count); - - /* passing invalid enumeration palette type crashes under most Windows versions */ - - GdipFree(palette); - GdipDisposeImage((GpImage *)bitmap); -} - -#include "pshpack2.h" -static const struct tiff_1x1_data -{ - USHORT byte_order; - USHORT version; - ULONG dir_offset; - USHORT number_of_entries; - struct IFD_entry entry[12]; - ULONG next_IFD; - struct IFD_rational res; - short palette_data[3][256]; - short bps_data[4]; - BYTE pixel_data[32]; -} tiff_1x1_data = -{ -#ifdef WORDS_BIGENDIAN - 'M' | 'M' << 8, -#else - 'I' | 'I' << 8, -#endif - 42, - FIELD_OFFSET(struct tiff_1x1_data, number_of_entries), - 12, - { - { 0xff, IFD_SHORT, 1, 0 }, /* SUBFILETYPE */ - { 0x100, IFD_LONG, 1, 1 }, /* IMAGEWIDTH */ - { 0x101, IFD_LONG, 1, 1 }, /* IMAGELENGTH */ - { 0x102, IFD_SHORT, 3, FIELD_OFFSET(struct tiff_1x1_data, bps_data) }, /* BITSPERSAMPLE */ - { 0x103, IFD_SHORT, 1, 1 }, /* COMPRESSION: XP doesn't accept IFD_LONG here */ - { 0x106, IFD_SHORT, 1, 2 }, /* PHOTOMETRIC */ - { 0x111, IFD_LONG, 1, FIELD_OFFSET(struct tiff_1x1_data, pixel_data) }, /* STRIPOFFSETS */ - { 0x115, IFD_SHORT, 1, 3 }, /* SAMPLESPERPIXEL */ - { 0x11a, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_1x1_data, res) }, - { 0x11b, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_1x1_data, res) }, - { 0x128, IFD_SHORT, 1, 2 }, /* RESOLUTIONUNIT */ - { 0x140, IFD_SHORT, 256*3, FIELD_OFFSET(struct tiff_1x1_data, palette_data) } /* COLORMAP */ - }, - 0, - { 96, 1 }, - { { 0 } }, - { 8,8,8,0 }, - { 1,0,2,3,4,5,6,7,8,9,0,1,2,3,4,5 } -}; -#include "poppack.h" - -static void test_tiff_color_formats(void) -{ - static const struct - { - int photometric; /* PhotometricInterpretation */ - int samples; /* SamplesPerPixel */ - int bps; /* BitsPerSample */ - PixelFormat format; - } td[] = - { - /* 2 - RGB */ - { 2, 3, 1, PixelFormat24bppRGB }, - { 2, 3, 4, PixelFormat24bppRGB }, - { 2, 3, 8, PixelFormat24bppRGB }, - { 2, 3, 16, PixelFormat48bppRGB }, - { 2, 3, 24, 0 }, -#if 0 /* FIXME */ - { 2, 3, 32, 0 }, -#endif - { 2, 4, 1, PixelFormat32bppARGB }, - { 2, 4, 4, PixelFormat32bppARGB }, - { 2, 4, 8, PixelFormat32bppARGB }, - { 2, 4, 16, PixelFormat48bppRGB }, - { 2, 4, 24, 0 }, - { 2, 4, 32, 0 }, - /* 1 - BlackIsZero (Bilevel) */ - { 1, 1, 1, PixelFormat1bppIndexed }, -#if 0 /* FIXME: PNG vs TIFF mismatch */ - { 1, 1, 4, PixelFormat8bppIndexed }, -#endif - { 1, 1, 8, PixelFormat8bppIndexed }, - { 1, 1, 16, PixelFormat32bppARGB }, - { 1, 1, 24, 0 }, - { 1, 1, 32, PixelFormat32bppARGB }, - /* 3 - Palette Color */ - { 3, 1, 1, PixelFormat1bppIndexed }, - { 3, 1, 4, PixelFormat4bppIndexed }, - { 3, 1, 8, PixelFormat8bppIndexed }, -#if 0 /* FIXME: for some reason libtiff replaces photometric 3 by 1 for bps > 8 */ - { 3, 1, 16, 0 }, - { 3, 1, 24, 0 }, - { 3, 1, 32, 0 }, -#endif - /* 5 - Separated */ - { 5, 4, 1, 0 }, - { 5, 4, 4, 0 }, - { 5, 4, 8, PixelFormat32bppCMYK }, - { 5, 4, 16, PixelFormat48bppRGB }, - { 5, 4, 24, 0 }, - { 5, 4, 32, 0 }, - }; - BYTE buf[sizeof(tiff_1x1_data)]; - GpStatus status; - GpImage *image; - UINT count, i; - struct IFD_entry *tag, *tag_photo = NULL, *tag_bps = NULL, *tag_samples = NULL, *tag_colormap = NULL; - short *bps; - ImageType type; - PixelFormat format; - - memcpy(buf, &tiff_1x1_data, sizeof(tiff_1x1_data)); - - count = *(short *)(buf + tiff_1x1_data.dir_offset); - tag = (struct IFD_entry *)(buf + tiff_1x1_data.dir_offset + sizeof(short)); - - /* verify the TIFF structure */ - for (i = 0; i < count; i++) - { - if (tag[i].id == 0x102) /* BitsPerSample */ - tag_bps = &tag[i]; - else if (tag[i].id == 0x106) /* PhotometricInterpretation */ - tag_photo = &tag[i]; - else if (tag[i].id == 0x115) /* SamplesPerPixel */ - tag_samples = &tag[i]; - else if (tag[i].id == 0x140) /* ColorMap */ - tag_colormap = &tag[i]; - } - - ok(tag_bps && tag_photo && tag_samples && tag_colormap, "tag 0x102,0x106,0x115 or 0x140 is missing\n"); - if (!tag_bps || !tag_photo || !tag_samples || !tag_colormap) return; - - ok(tag_bps->type == IFD_SHORT, "tag 0x102 should have type IFD_SHORT\n"); - bps = (short *)(buf + tag_bps->value); - ok(bps[0] == 8 && bps[1] == 8 && bps[2] == 8 && bps[3] == 0, - "expected bps 8,8,8,0 got %d,%d,%d,%d\n", bps[0], bps[1], bps[2], bps[3]); - - for (i = 0; i < sizeof(td)/sizeof(td[0]); i++) - { - tag_colormap->count = (1 << td[i].bps) * 3; - tag_photo->value = td[i].photometric; - tag_bps->count = td[i].samples; - tag_samples->value = td[i].samples; - - if (td[i].samples == 1) - tag_bps->value = td[i].bps; - else if (td[i].samples == 2) - tag_bps->value = MAKELONG(td[i].bps, td[i].bps); - else if (td[i].samples == 3) - { - tag_bps->value = (BYTE *)bps - buf; - bps[0] = bps[1] = bps[2] = td[i].bps; - } - else if (td[i].samples == 4) - { - tag_bps->value = (BYTE *)bps - buf; - bps[0] = bps[1] = bps[2] = bps[3] = td[i].bps; - } - else - { - ok(0, "%u: unsupported samples count %d\n", i, td[i].samples); - continue; - } - - image = load_image(buf, sizeof(buf)); - if (!td[i].format) - ok(!image, - "%u: (%d,%d,%d) TIFF image loading should have failed\n", i, td[i].photometric, td[i].samples, td[i].bps); - else - ok(image != NULL || broken(!image) /* XP */, "%u: failed to load TIFF image data (%d,%d,%d)\n", - i, td[i].photometric, td[i].samples, td[i].bps); - if (!image) continue; - - status = GdipGetImageType(image, &type); - ok(status == Ok, "%u: GdipGetImageType error %d\n", i, status); - ok(type == ImageTypeBitmap, "%u: wrong image type %d\n", i, type); - - status = GdipGetImagePixelFormat(image, &format); - expect(Ok, status); - ok(format == td[i].format, - "%u: expected %#x, got %#x\n", i, td[i].format, format); - - GdipDisposeImage(image); - } -} - START_TEST(image) { HMODULE mod = GetModuleHandleA("gdiplus.dll"); @@ -5382,8 +5192,6 @@ START_TEST(image) pGdipBitmapGetHistogram = (void*)GetProcAddress(mod, "GdipBitmapGetHistogram"); pGdipImageSetAbort = (void*)GetProcAddress(mod, "GdipImageSetAbort"); - test_tiff_color_formats(); - test_GdipInitializePalette(); test_png_color_formats(); test_supported_encoders(); test_CloneBitmapArea(); diff --git a/modules/rostests/winetests/gdiplus/matrix.c b/modules/rostests/winetests/gdiplus/matrix.c index b6c04f62ea..719b6a0251 100644 --- a/modules/rostests/winetests/gdiplus/matrix.c +++ b/modules/rostests/winetests/gdiplus/matrix.c @@ -159,6 +159,7 @@ static void test_invert(void) GdipCreateMatrix2(2.0/16.0, 2.0/16.0, -5.0/16.0, 3.0/16.0, 3.0/16.0, -21.0/16.0, &inverted); GdipIsMatrixEqual(matrix, inverted, &equal); expect(TRUE, equal); + GdipDeleteMatrix(matrix); GdipCreateMatrix2(0.0006, 0, 0, 0.0006, 400, 400, &matrix); status = GdipInvertMatrix(matrix); diff --git a/modules/rostests/winetests/gdiplus/metafile.c b/modules/rostests/winetests/gdiplus/metafile.c index b4bf38a6fd..49f06ca5aa 100644 --- a/modules/rostests/winetests/gdiplus/metafile.c +++ b/modules/rostests/winetests/gdiplus/metafile.c @@ -29,11 +29,13 @@ static BOOL load_metafiles; typedef struct emfplus_record { + DWORD record_type; + DWORD flags; /* Used for EMF+ records only. */ BOOL todo; - ULONG record_type; BOOL playback_todo; void (*playback_fn)(GpMetafile* metafile, EmfPlusRecordType record_type, unsigned int flags, unsigned int dataSize, const unsigned char *pStr); + DWORD broken_flags; } emfplus_record; typedef struct emfplus_check_state @@ -46,10 +48,21 @@ typedef struct emfplus_check_state static void check_record(int count, const char *desc, const struct emfplus_record *expected, const struct emfplus_record *actual) { + if (actual->record_type > GDIP_EMFPLUS_RECORD_BASE) + { + todo_wine_if (expected->todo) + ok(expected->record_type == actual->record_type && (expected->flags == actual->flags || + broken(expected->broken_flags == actual->flags)), + "%s.%i: Expected record type 0x%x, got 0x%x. Expected flags %#x, got %#x.\n", desc, count, + expected->record_type, actual->record_type, expected->flags, actual->flags); + } + else + { todo_wine_if (expected->todo) ok(expected->record_type == actual->record_type, - "%s.%i: Expected record type 0x%x, got 0x%x\n", desc, count, + "%s.%i: Expected record type 0x%x, got 0x%x.\n", desc, count, expected->record_type, actual->record_type); + } } typedef struct EmfPlusRecordHeader @@ -124,6 +137,7 @@ static int CALLBACK enum_emf_proc(HDC hDC, HANDLETABLE *lpHTable, const ENHMETAR { actual.todo = FALSE; actual.record_type = record->Type; + actual.flags = record->Flags; check_record(state->count, state->desc, &state->expected[state->count], &actual); state->count++; @@ -163,6 +177,7 @@ static int CALLBACK enum_emf_proc(HDC hDC, HANDLETABLE *lpHTable, const ENHMETAR { actual.todo = FALSE; actual.record_type = lpEMFR->iType; + actual.flags = 0; check_record(state->count, state->desc, &state->expected[state->count], &actual); @@ -198,6 +213,7 @@ static BOOL CALLBACK enum_metafile_proc(EmfPlusRecordType record_type, unsigned actual.todo = FALSE; actual.record_type = record_type; + actual.flags = flags; if (dataSize == 0) ok(pStr == NULL, "non-NULL pStr\n"); @@ -338,11 +354,11 @@ static void sync_metafile(GpMetafile **metafile, const char *filename) } static const emfplus_record empty_records[] = { - {0, EMR_HEADER}, - {0, EmfPlusRecordTypeHeader}, - {0, EmfPlusRecordTypeEndOfFile}, - {0, EMR_EOF}, - {0} + { EMR_HEADER }, + { EmfPlusRecordTypeHeader }, + { EmfPlusRecordTypeEndOfFile }, + { EMR_EOF }, + { 0 } }; static void test_empty(void) @@ -537,17 +553,17 @@ static void test_empty(void) } static const emfplus_record getdc_records[] = { - {0, EMR_HEADER}, - {0, EmfPlusRecordTypeHeader}, - {0, EmfPlusRecordTypeGetDC}, - {0, EMR_CREATEBRUSHINDIRECT}, - {0, EMR_SELECTOBJECT}, - {0, EMR_RECTANGLE}, - {0, EMR_SELECTOBJECT}, - {0, EMR_DELETEOBJECT}, - {0, EmfPlusRecordTypeEndOfFile}, - {0, EMR_EOF}, - {0} + { EMR_HEADER }, + { EmfPlusRecordTypeHeader }, + { EmfPlusRecordTypeGetDC }, + { EMR_CREATEBRUSHINDIRECT }, + { EMR_SELECTOBJECT }, + { EMR_RECTANGLE }, + { EMR_SELECTOBJECT }, + { EMR_DELETEOBJECT }, + { EmfPlusRecordTypeEndOfFile }, + { EMR_EOF }, + { 0 } }; static void test_getdc(void) @@ -675,34 +691,34 @@ static void test_getdc(void) } static const emfplus_record emfonly_records[] = { - {0, EMR_HEADER}, - {0, EMR_CREATEBRUSHINDIRECT}, - {0, EMR_SELECTOBJECT}, - {0, EMR_RECTANGLE}, - {0, EMR_SELECTOBJECT}, - {0, EMR_DELETEOBJECT}, - {0, EMR_EOF}, - {0} + { EMR_HEADER }, + { EMR_CREATEBRUSHINDIRECT }, + { EMR_SELECTOBJECT }, + { EMR_RECTANGLE }, + { EMR_SELECTOBJECT }, + { EMR_DELETEOBJECT }, + { EMR_EOF }, + { 0 } }; static const emfplus_record emfonly_draw_records[] = { - {0, EMR_HEADER}, - {1, EMR_SAVEDC}, - {1, EMR_SETICMMODE}, - {1, EMR_SETMITERLIMIT}, - {1, EMR_MODIFYWORLDTRANSFORM}, - {1, EMR_EXTCREATEPEN}, - {1, EMR_SELECTOBJECT}, - {1, EMR_SELECTOBJECT}, - {1, EMR_POLYLINE16}, - {1, EMR_SELECTOBJECT}, - {1, EMR_SELECTOBJECT}, - {1, EMR_MODIFYWORLDTRANSFORM}, - {1, EMR_DELETEOBJECT}, - {1, EMR_SETMITERLIMIT}, - {1, EMR_RESTOREDC}, - {0, EMR_EOF}, - {1} + { EMR_HEADER }, + { EMR_SAVEDC, 0, 1 }, + { EMR_SETICMMODE, 0, 1 }, + { EMR_SETMITERLIMIT, 0, 1 }, + { EMR_MODIFYWORLDTRANSFORM, 0, 1 }, + { EMR_EXTCREATEPEN, 0, 1 }, + { EMR_SELECTOBJECT, 0, 1 }, + { EMR_SELECTOBJECT, 0, 1 }, + { EMR_POLYLINE16, 0, 1 }, + { EMR_SELECTOBJECT, 0, 1 }, + { EMR_SELECTOBJECT, 0, 1 }, + { EMR_MODIFYWORLDTRANSFORM, 0, 1 }, + { EMR_DELETEOBJECT, 0, 1 }, + { EMR_SETMITERLIMIT, 0, 1 }, + { EMR_RESTOREDC, 0, 1 }, + { EMR_EOF }, + { 0, 0, 1 } }; static void test_emfonly(void) @@ -998,12 +1014,12 @@ static void test_emfonly(void) } static const emfplus_record fillrect_records[] = { - {0, EMR_HEADER}, - {0, EmfPlusRecordTypeHeader}, - {0, EmfPlusRecordTypeFillRects}, - {0, EmfPlusRecordTypeEndOfFile}, - {0, EMR_EOF}, - {0} + { EMR_HEADER }, + { EmfPlusRecordTypeHeader }, + { EmfPlusRecordTypeFillRects, 0xc000 }, + { EmfPlusRecordTypeEndOfFile }, + { EMR_EOF }, + { 0 } }; static void test_fillrect(void) @@ -1108,16 +1124,16 @@ static void test_fillrect(void) } static const emfplus_record clear_emf_records[] = { - {0, EMR_HEADER}, - {0, EmfPlusRecordTypeHeader}, - {0, EmfPlusRecordTypeClear}, - {1, EMR_SAVEDC}, - {1, EMR_SETICMMODE}, - {1, EMR_BITBLT}, - {1, EMR_RESTOREDC}, - {0, EmfPlusRecordTypeEndOfFile}, - {0, EMR_EOF}, - {0} + { EMR_HEADER }, + { EmfPlusRecordTypeHeader }, + { EmfPlusRecordTypeClear }, + { EMR_SAVEDC, 0, 1 }, + { EMR_SETICMMODE, 0, 1 }, + { EMR_BITBLT, 0, 1 }, + { EMR_RESTOREDC, 0, 1 }, + { EmfPlusRecordTypeEndOfFile }, + { EMR_EOF }, + { 0 } }; static void test_clear(void) @@ -1312,20 +1328,20 @@ static void test_nullframerect(void) { } static const emfplus_record pagetransform_records[] = { - {0, EMR_HEADER}, - {0, EmfPlusRecordTypeHeader}, - {0, EmfPlusRecordTypeFillRects}, - {0, EmfPlusRecordTypeSetPageTransform}, - {0, EmfPlusRecordTypeFillRects}, - {0, EmfPlusRecordTypeSetPageTransform}, - {0, EmfPlusRecordTypeFillRects}, - {0, EmfPlusRecordTypeSetPageTransform}, - {0, EmfPlusRecordTypeFillRects}, - {0, EmfPlusRecordTypeSetPageTransform}, - {0, EmfPlusRecordTypeFillRects}, - {0, EmfPlusRecordTypeEndOfFile}, - {0, EMR_EOF}, - {0} + { EMR_HEADER }, + { EmfPlusRecordTypeHeader }, + { EmfPlusRecordTypeFillRects, 0xc000 }, + { EmfPlusRecordTypeSetPageTransform, UnitPixel }, + { EmfPlusRecordTypeFillRects, 0xc000 }, + { EmfPlusRecordTypeSetPageTransform, UnitPixel }, + { EmfPlusRecordTypeFillRects, 0xc000 }, + { EmfPlusRecordTypeSetPageTransform, UnitInch }, + { EmfPlusRecordTypeFillRects, 0x8000 }, + { EmfPlusRecordTypeSetPageTransform, UnitDisplay }, + { EmfPlusRecordTypeFillRects, 0xc000 }, + { EmfPlusRecordTypeEndOfFile }, + { EMR_EOF }, + { 0 } }; static void test_pagetransform(void) @@ -1513,24 +1529,24 @@ static void test_pagetransform(void) } static const emfplus_record worldtransform_records[] = { - {0, EMR_HEADER}, - {0, EmfPlusRecordTypeHeader}, - {0, EmfPlusRecordTypeFillRects}, - {0, EmfPlusRecordTypeScaleWorldTransform}, - {0, EmfPlusRecordTypeFillRects}, - {0, EmfPlusRecordTypeResetWorldTransform}, - {0, EmfPlusRecordTypeFillRects}, - {0, EmfPlusRecordTypeMultiplyWorldTransform}, - {0, EmfPlusRecordTypeFillRects}, - {0, EmfPlusRecordTypeRotateWorldTransform}, - {0, EmfPlusRecordTypeFillRects}, - {0, EmfPlusRecordTypeSetWorldTransform}, - {0, EmfPlusRecordTypeFillRects}, - {0, EmfPlusRecordTypeTranslateWorldTransform}, - {0, EmfPlusRecordTypeFillRects}, - {0, EmfPlusRecordTypeEndOfFile}, - {0, EMR_EOF}, - {0} + { EMR_HEADER }, + { EmfPlusRecordTypeHeader }, + { EmfPlusRecordTypeFillRects, 0xc000 }, + { EmfPlusRecordTypeScaleWorldTransform }, + { EmfPlusRecordTypeFillRects, 0x8000 }, + { EmfPlusRecordTypeResetWorldTransform }, + { EmfPlusRecordTypeFillRects, 0xc000 }, + { EmfPlusRecordTypeMultiplyWorldTransform }, + { EmfPlusRecordTypeFillRects, 0x8000 }, + { EmfPlusRecordTypeRotateWorldTransform, 0x2000 }, + { EmfPlusRecordTypeFillRects, 0x8000 }, + { EmfPlusRecordTypeSetWorldTransform }, + { EmfPlusRecordTypeFillRects, 0xc000 }, + { EmfPlusRecordTypeTranslateWorldTransform, 0x2000 }, + { EmfPlusRecordTypeFillRects, 0xc000 }, + { EmfPlusRecordTypeEndOfFile }, + { EMR_EOF }, + { 0 } }; static void test_worldtransform(void) @@ -1938,29 +1954,29 @@ static void test_frameunit(void) } static const emfplus_record container_records[] = { - {0, EMR_HEADER}, - {0, EmfPlusRecordTypeHeader}, - {0, EmfPlusRecordTypeBeginContainerNoParams}, - {0, EmfPlusRecordTypeScaleWorldTransform}, - {0, EmfPlusRecordTypeFillRects}, - {0, EmfPlusRecordTypeEndContainer}, - {0, EmfPlusRecordTypeScaleWorldTransform}, - {0, EmfPlusRecordTypeFillRects}, - {0, EmfPlusRecordTypeSave}, - {0, EmfPlusRecordTypeRestore}, - {0, EmfPlusRecordTypeScaleWorldTransform}, - {0, EmfPlusRecordTypeBeginContainerNoParams}, - {0, EmfPlusRecordTypeScaleWorldTransform}, - {0, EmfPlusRecordTypeBeginContainerNoParams}, - {0, EmfPlusRecordTypeEndContainer}, - {0, EmfPlusRecordTypeFillRects}, - {0, EmfPlusRecordTypeBeginContainer}, - {0, EmfPlusRecordTypeFillRects}, - {0, EmfPlusRecordTypeEndContainer}, - {0, EmfPlusRecordTypeBeginContainerNoParams}, - {0, EmfPlusRecordTypeEndOfFile}, - {0, EMR_EOF}, - {0} + { EMR_HEADER }, + { EmfPlusRecordTypeHeader }, + { EmfPlusRecordTypeBeginContainerNoParams }, + { EmfPlusRecordTypeScaleWorldTransform }, + { EmfPlusRecordTypeFillRects, 0xc000 }, + { EmfPlusRecordTypeEndContainer }, + { EmfPlusRecordTypeScaleWorldTransform }, + { EmfPlusRecordTypeFillRects, 0xc000 }, + { EmfPlusRecordTypeSave }, + { EmfPlusRecordTypeRestore }, + { EmfPlusRecordTypeScaleWorldTransform }, + { EmfPlusRecordTypeBeginContainerNoParams }, + { EmfPlusRecordTypeScaleWorldTransform }, + { EmfPlusRecordTypeBeginContainerNoParams }, + { EmfPlusRecordTypeEndContainer }, + { EmfPlusRecordTypeFillRects, 0xc000 }, + { EmfPlusRecordTypeBeginContainer, UnitInch }, + { EmfPlusRecordTypeFillRects, 0xc000 }, + { EmfPlusRecordTypeEndContainer }, + { EmfPlusRecordTypeBeginContainerNoParams }, + { EmfPlusRecordTypeEndOfFile }, + { EMR_EOF }, + { 0 } }; static void test_containers(void) @@ -2142,19 +2158,19 @@ static void test_containers(void) } static const emfplus_record clipping_records[] = { - {0, EMR_HEADER}, - {0, EmfPlusRecordTypeHeader}, - {0, EmfPlusRecordTypeSave}, - {0, EmfPlusRecordTypeSetClipRect}, - {0, EmfPlusRecordTypeFillRects}, - {0, EmfPlusRecordTypeRestore}, - {0, EmfPlusRecordTypeSetClipRect}, - {0, EmfPlusRecordTypeFillRects}, - {0, EmfPlusRecordTypeObject, 1}, - {0, EmfPlusRecordTypeSetClipRegion, 1}, - {0, EmfPlusRecordTypeEndOfFile}, - {0, EMR_EOF}, - {0} + { EMR_HEADER }, + { EmfPlusRecordTypeHeader }, + { EmfPlusRecordTypeSave }, + { EmfPlusRecordTypeSetClipRect }, + { EmfPlusRecordTypeFillRects, 0xc000 }, + { EmfPlusRecordTypeRestore }, + { EmfPlusRecordTypeSetClipRect, 0x300 }, + { EmfPlusRecordTypeFillRects, 0xc000 }, + { EmfPlusRecordTypeObject, ObjectTypeRegion << 8 }, + { EmfPlusRecordTypeSetClipRegion, 0x100 }, + { EmfPlusRecordTypeEndOfFile }, + { EMR_EOF }, + { 0 } }; static void test_clipping(void) @@ -2291,14 +2307,14 @@ static void test_gditransform_cb(GpMetafile* metafile, EmfPlusRecordType record_ } static const emfplus_record gditransform_records[] = { - {0, EMR_HEADER}, - {0, EMR_CREATEBRUSHINDIRECT}, - {0, EMR_SELECTOBJECT}, - {0, EMR_GDICOMMENT, 0, test_gditransform_cb}, - {0, EMR_SELECTOBJECT}, - {0, EMR_DELETEOBJECT}, - {0, EMR_EOF}, - {0} + { EMR_HEADER }, + { EMR_CREATEBRUSHINDIRECT }, + { EMR_SELECTOBJECT }, + { EMR_GDICOMMENT, 0, 0, 0, test_gditransform_cb }, + { EMR_SELECTOBJECT }, + { EMR_DELETEOBJECT }, + { EMR_EOF }, + { 0 } }; static void test_gditransform(void) @@ -2395,45 +2411,45 @@ static void test_gditransform(void) } static const emfplus_record draw_image_bitmap_records[] = { - {0, EMR_HEADER}, - {0, EmfPlusRecordTypeHeader}, - {0, EmfPlusRecordTypeObject}, - {0, EmfPlusRecordTypeObject}, - {0, EmfPlusRecordTypeDrawImagePoints}, - {1, EMR_SAVEDC}, - {1, EMR_SETICMMODE}, - {1, EMR_BITBLT}, - {1, EMR_RESTOREDC}, - {0, EmfPlusRecordTypeEndOfFile}, - {0, EMR_EOF}, - {0} + { EMR_HEADER }, + { EmfPlusRecordTypeHeader }, + { EmfPlusRecordTypeObject, ObjectTypeImage << 8 }, + { EmfPlusRecordTypeObject, (ObjectTypeImageAttributes << 8) | 1 }, + { EmfPlusRecordTypeDrawImagePoints, 0, 0, 0, NULL, 0x4000 }, + { EMR_SAVEDC, 0, 1 }, + { EMR_SETICMMODE, 0, 1 }, + { EMR_BITBLT, 0, 1 }, + { EMR_RESTOREDC, 0, 1 }, + { EmfPlusRecordTypeEndOfFile }, + { EMR_EOF }, + { 0 } }; static const emfplus_record draw_image_metafile_records[] = { - {0, EMR_HEADER}, - {0, EmfPlusRecordTypeHeader}, - {0, EmfPlusRecordTypeObject}, + { EMR_HEADER }, + { EmfPlusRecordTypeHeader }, + { EmfPlusRecordTypeObject, ObjectTypeImage << 8 }, /* metafile object */ - {0, EMR_HEADER}, - {0, EmfPlusRecordTypeHeader}, - {0, EmfPlusRecordTypeObject}, - {0, EmfPlusRecordTypeObject}, - {0, EmfPlusRecordTypeDrawImagePoints}, - {1, EMR_SAVEDC}, - {1, EMR_SETICMMODE}, - {1, EMR_BITBLT}, - {1, EMR_RESTOREDC}, - {0, EmfPlusRecordTypeEndOfFile}, - {0, EMR_EOF}, + { EMR_HEADER }, + { EmfPlusRecordTypeHeader }, + { EmfPlusRecordTypeObject, ObjectTypeImage << 8 }, + { EmfPlusRecordTypeObject, (ObjectTypeImageAttributes << 8) | 1 }, + { EmfPlusRecordTypeDrawImagePoints }, + { EMR_SAVEDC, 0, 1 }, + { EMR_SETICMMODE, 0, 1 }, + { EMR_BITBLT, 0, 1 }, + { EMR_RESTOREDC, 0, 1 }, + { EmfPlusRecordTypeEndOfFile }, + { EMR_EOF }, /* end of metafile object */ - {0, EmfPlusRecordTypeDrawImagePoints}, - {1, EMR_SAVEDC}, - {1, EMR_SETICMMODE}, - {1, EMR_BITBLT}, - {1, EMR_RESTOREDC}, - {0, EmfPlusRecordTypeEndOfFile}, - {0, EMR_EOF}, - {0} + { EmfPlusRecordTypeDrawImagePoints }, + { EMR_SAVEDC, 0, 1 }, + { EMR_SETICMMODE, 0, 1 }, + { EMR_BITBLT, 0, 1 }, + { EMR_RESTOREDC, 0, 1 }, + { EmfPlusRecordTypeEndOfFile }, + { EMR_EOF }, + { 0 } }; static void test_drawimage(void) @@ -2538,17 +2554,17 @@ static void test_drawimage(void) } static const emfplus_record properties_records[] = { - {0, EMR_HEADER}, - {0, EmfPlusRecordTypeHeader}, - {0, EmfPlusRecordTypeSetTextRenderingHint}, - {0, EmfPlusRecordTypeSetPixelOffsetMode}, - {0, EmfPlusRecordTypeSetAntiAliasMode}, - {0, EmfPlusRecordTypeSetCompositingMode}, - {0, EmfPlusRecordTypeSetCompositingQuality}, - {0, EmfPlusRecordTypeSetInterpolationMode}, - {0, EmfPlusRecordTypeEndOfFile}, - {0, EMR_EOF}, - {0} + { EMR_HEADER }, + { EmfPlusRecordTypeHeader }, + { EmfPlusRecordTypeSetTextRenderingHint, TextRenderingHintAntiAlias }, + { EmfPlusRecordTypeSetPixelOffsetMode, PixelOffsetModeHighQuality }, + { EmfPlusRecordTypeSetAntiAliasMode, (SmoothingModeAntiAlias << 1) | 1, 0, 0, NULL, 0x1 }, + { EmfPlusRecordTypeSetCompositingMode, CompositingModeSourceCopy }, + { EmfPlusRecordTypeSetCompositingQuality, CompositingQualityHighQuality }, + { EmfPlusRecordTypeSetInterpolationMode, InterpolationModeHighQualityBicubic }, + { EmfPlusRecordTypeEndOfFile }, + { EMR_EOF }, + { 0 } }; static void test_properties(void) @@ -2615,18 +2631,18 @@ static void test_properties(void) } static const emfplus_record draw_path_records[] = { - {0, EMR_HEADER}, - {0, EmfPlusRecordTypeHeader}, - {0, EmfPlusRecordTypeObject}, - {0, EmfPlusRecordTypeObject}, - {0, EmfPlusRecordTypeDrawPath}, - {1, EMR_SAVEDC}, - {1, EMR_SETICMMODE}, - {1, EMR_BITBLT}, - {1, EMR_RESTOREDC}, - {0, EmfPlusRecordTypeEndOfFile}, - {0, EMR_EOF}, - {0} + { EMR_HEADER }, + { EmfPlusRecordTypeHeader }, + { EmfPlusRecordTypeObject, ObjectTypePen << 8 }, + { EmfPlusRecordTypeObject, (ObjectTypePath << 8) | 1 }, + { EmfPlusRecordTypeDrawPath, 1 }, + { EMR_SAVEDC, 0, 1 }, + { EMR_SETICMMODE, 0, 1 }, + { EMR_BITBLT, 0, 1 }, + { EMR_RESTOREDC, 0, 1 }, + { EmfPlusRecordTypeEndOfFile }, + { EMR_EOF }, + { 0 } }; static void test_drawpath(void) @@ -2681,17 +2697,17 @@ static void test_drawpath(void) } static const emfplus_record fill_path_records[] = { - {0, EMR_HEADER}, - {0, EmfPlusRecordTypeHeader}, - {0, EmfPlusRecordTypeObject}, - {0, EmfPlusRecordTypeFillPath}, - {1, EMR_SAVEDC}, - {1, EMR_SETICMMODE}, - {1, EMR_BITBLT}, - {1, EMR_RESTOREDC}, - {0, EmfPlusRecordTypeEndOfFile}, - {0, EMR_EOF}, - {0} + { EMR_HEADER }, + { EmfPlusRecordTypeHeader }, + { EmfPlusRecordTypeObject, ObjectTypePath << 8 }, + { EmfPlusRecordTypeFillPath, 0x8000 }, + { EMR_SAVEDC, 0, 1 }, + { EMR_SETICMMODE, 0, 1 }, + { EMR_BITBLT, 0, 1 }, + { EMR_RESTOREDC, 0, 1 }, + { EmfPlusRecordTypeEndOfFile }, + { EMR_EOF }, + { 0 } }; static void test_fillpath(void) diff --git a/modules/rostests/winetests/gdiplus/pathiterator.c b/modules/rostests/winetests/gdiplus/pathiterator.c index 753ea64cba..bb8a1e7ed0 100644 --- a/modules/rostests/winetests/gdiplus/pathiterator.c +++ b/modules/rostests/winetests/gdiplus/pathiterator.c @@ -78,7 +78,8 @@ static void test_hascurve(void) GdipDeletePathIter(iter); - GdipAddPathEllipse(path, 0.0, 0.0, 35.0, 70.0); + stat = GdipAddPathEllipse(path, 0.0, 0.0, 35.0, 70.0); + expect(Ok, stat); stat = GdipCreatePathIter(&iter, path); expect(Ok, stat); @@ -328,9 +329,12 @@ static void test_isvalid(void) GdipDeletePathIter(iter); /* no markers */ - GdipAddPathLine(path, 50.0, 50.0, 110.0, 40.0); - GdipCreatePathIter(&iter, path); - GdipPathIterNextMarker(iter, &result, &start, &end); + stat = GdipAddPathLine(path, 50.0, 50.0, 110.0, 40.0); + expect(Ok, stat); + stat = GdipCreatePathIter(&iter, path); + expect(Ok, stat); + stat = GdipPathIterNextMarker(iter, &result, &start, &end); + expect(Ok, stat); isvalid = FALSE; stat = GdipPathIterIsValid(iter, &isvalid); expect(Ok, stat); @@ -525,7 +529,8 @@ static void test_nextpathtype(void) todo_wine expect(0, result); GdipDeletePathIter(iter); - GdipAddPathEllipse(path, 0.0, 0.0, 35.0, 70.0); + stat = GdipAddPathEllipse(path, 0.0, 0.0, 35.0, 70.0); + expect(Ok, stat); GdipCreatePathIter(&iter, path); start = end = result = (INT)0xdeadbeef; type = 255; /* out of range */ diff --git a/modules/rostests/winetests/gdiplus/resource.rc b/modules/rostests/winetests/gdiplus/resource.rc new file mode 100644 index 0000000000..d7d915ce00 --- /dev/null +++ b/modules/rostests/winetests/gdiplus/resource.rc @@ -0,0 +1,22 @@ +/* + * Resources for gdiplus test suite. + * + * Copyright 2017 Fabian Maurer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* @makedep: wine_longname.ttf */ +1 RCDATA wine_longname.ttf diff --git a/modules/rostests/winetests/gdiplus/wine_longname.sfd b/modules/rostests/winetests/gdiplus/wine_longname.sfd new file mode 100644 index 0000000000..998d7cc01f --- /dev/null +++ b/modules/rostests/winetests/gdiplus/wine_longname.sfd @@ -0,0 +1,66 @@ +SplineFontDB: 3.0 +FontName: wine_1_this_is_a_very_long_name_that_might_be_too_long_for_gdi32 +FullName: wine_2_this_is_a_very_long_name_that_might_be_too_long_for_gdi32 +FamilyName: wine_3_this_is_a_very_long_name_that_might_be_too_long_for_gdi32 +Weight: Regular +Copyright: Copyright (c) 2017, Fabian Maurer +UComments: "2017-11-17: Created with FontForge (
http://fontforge.org
)" +Version: 001.000 +ItalicAngle: 0 +UnderlinePosition: -102.4 +UnderlineWidth: 51.2 +Ascent: 819 +Descent: 205 +InvalidEm: 0 +LayerCount: 2 +Layer: 0 0 "Back" 1 +Layer: 1 0 "Fore" 0 +XUID: [1021 48 28337276 3092883] +OS2Version: 0 +OS2_WeightWidthSlopeOnly: 0 +OS2_UseTypoMetrics: 1 +CreationTime: 1510948643 +ModificationTime: 1510949092 +OS2TypoAscent: 0 +OS2TypoAOffset: 1 +OS2TypoDescent: 0 +OS2TypoDOffset: 1 +OS2TypoLinegap: 0 +OS2WinAscent: 0 +OS2WinAOffset: 1 +OS2WinDescent: 0 +OS2WinDOffset: 1 +HheadAscent: 0 +HheadAOffset: 1 +HheadDescent: 0 +HheadDOffset: 1 +OS2Vendor: 'PfEd' +MarkAttachClasses: 1 +DEI: 91125 +Encoding: ISO8859-1 +UnicodeInterp: none +NameList: AGL For New Fonts +DisplaySize: -48 +AntiAlias: 1 +FitToEm: 0 +WinInfo: 64 16 4 +BeginPrivate: 0 +EndPrivate +BeginChars: 256 1 + +StartChar: at +Encoding: 64 64 0 +Width: 1024 +VWidth: 0 +Flags: HW +LayerCount: 2 +Fore +SplineSet +259 332 m 29 + 468 664 l 29 + 514 332 l 29 + 259 332 l 29 +EndSplineSet +EndChar +EndChars +EndSplineFont diff --git a/modules/rostests/winetests/gdiplus/wine_longname.ttf b/modules/rostests/winetests/gdiplus/wine_longname.ttf new file mode 100644 index 0000000000..1a519c64ad Binary files /dev/null and b/modules/rostests/winetests/gdiplus/wine_longname.ttf differ
6 years, 11 months
1
0
0
0
01/01: [GDIPLUS] Sync with Wine 3.0. CORE-14225
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=007122e7743763b2534f8…
commit 007122e7743763b2534f8b2d1525e473e653d57c Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Fri Jan 19 00:17:41 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Fri Jan 19 00:17:41 2018 +0100 [GDIPLUS] Sync with Wine 3.0. CORE-14225 --- dll/win32/gdiplus/brush.c | 14 +- dll/win32/gdiplus/font.c | 38 +- dll/win32/gdiplus/gdiplus.spec | 2 +- dll/win32/gdiplus/gdiplus_private.h | 70 +- dll/win32/gdiplus/graphics.c | 323 +++--- dll/win32/gdiplus/image.c | 137 +-- dll/win32/gdiplus/imageattributes.c | 11 +- dll/win32/gdiplus/metafile.c | 1856 +++++++++++++++++++++++++++++++---- dll/win32/gdiplus/region.c | 24 - media/doc/README.WINE | 2 +- 10 files changed, 1905 insertions(+), 572 deletions(-) diff --git a/dll/win32/gdiplus/brush.c b/dll/win32/gdiplus/brush.c index 7e6d7efbad..dfacfbcb03 100644 --- a/dll/win32/gdiplus/brush.c +++ b/dll/win32/gdiplus/brush.c @@ -243,7 +243,7 @@ static const char HatchBrushes[][8] = { { 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff }, /* HatchStyleDarkHorizontal */ }; -GpStatus get_hatch_data(HatchStyle hatchstyle, const char **result) +GpStatus get_hatch_data(GpHatchStyle hatchstyle, const char **result) { if (hatchstyle < sizeof(HatchBrushes) / sizeof(HatchBrushes[0])) { @@ -257,12 +257,15 @@ GpStatus get_hatch_data(HatchStyle hatchstyle, const char **result) /****************************************************************************** * GdipCreateHatchBrush [GDIPLUS.@] */ -GpStatus WINGDIPAPI GdipCreateHatchBrush(HatchStyle hatchstyle, ARGB forecol, ARGB backcol, GpHatch **brush) +GpStatus WINGDIPAPI GdipCreateHatchBrush(GpHatchStyle hatchstyle, ARGB forecol, ARGB backcol, GpHatch **brush) { TRACE("(%d, %d, %d, %p)\n", hatchstyle, forecol, backcol, brush); if(!brush) return InvalidParameter; + if(hatchstyle < HatchStyleMin || hatchstyle > HatchStyleMax) + return InvalidParameter; + *brush = heap_alloc_zero(sizeof(GpHatch)); if (!*brush) return OutOfMemory; @@ -491,9 +494,12 @@ GpStatus WINGDIPAPI GdipCreateLineBrushFromRectWithAngle(GDIPCONST GpRectF* rect TRACE("(%p, %x, %x, %.2f, %d, %d, %p)\n", rect, startcolor, endcolor, angle, isAngleScalable, wrap, line); - if (!rect || !rect->Width || !rect->Height) + if (!rect || !line || wrap == WrapModeClamp) return InvalidParameter; + if (!rect->Width || !rect->Height) + return OutOfMemory; + angle = fmodf(angle, 360); if (angle < 0) angle += 360; @@ -951,7 +957,7 @@ GpStatus WINGDIPAPI GdipGetHatchForegroundColor(GpHatch *brush, ARGB *forecol) return Ok; } -GpStatus WINGDIPAPI GdipGetHatchStyle(GpHatch *brush, HatchStyle *hatchstyle) +GpStatus WINGDIPAPI GdipGetHatchStyle(GpHatch *brush, GpHatchStyle *hatchstyle) { TRACE("(%p, %p)\n", brush, hatchstyle); diff --git a/dll/win32/gdiplus/font.c b/dll/win32/gdiplus/font.c index 57f90e7caa..c0fb51c076 100644 --- a/dll/win32/gdiplus/font.c +++ b/dll/win32/gdiplus/font.c @@ -1378,33 +1378,36 @@ static int match_name_table_language( const tt_name_record *name, LANGID lang ) return 0; } -static WCHAR *copy_name_table_string( const tt_name_record *name, const BYTE *data, WCHAR *ret, DWORD len ) +static WCHAR *copy_name_table_string( const tt_name_record *name, const BYTE *data ) { WORD name_len = GET_BE_WORD(name->length); WORD codepage; + WCHAR *ret; + int len; switch (GET_BE_WORD(name->platform_id)) { case TT_PLATFORM_APPLE_UNICODE: case TT_PLATFORM_MICROSOFT: - if (name_len >= len*sizeof(WCHAR)) - return NULL; + ret = heap_alloc((name_len / 2 + 1) * sizeof(WCHAR)); for (len = 0; len < name_len / 2; len++) ret[len] = (data[len * 2] << 8) | data[len * 2 + 1]; ret[len] = 0; return ret; case TT_PLATFORM_MACINTOSH: codepage = get_mac_code_page( name ); - len = MultiByteToWideChar( codepage, 0, (char *)data, name_len, ret, len-1 ); + len = MultiByteToWideChar( codepage, 0, (char *)data, name_len, NULL, 0 ) + 1; if (!len) return NULL; + ret = heap_alloc(len * sizeof(WCHAR)); + len = MultiByteToWideChar( codepage, 0, (char *)data, name_len, ret, len - 1 ); ret[len] = 0; return ret; } return NULL; } -static WCHAR *load_ttf_name_id( const BYTE *mem, DWORD_PTR size, DWORD id, WCHAR *ret, DWORD len ) +static WCHAR *load_ttf_name_id( const BYTE *mem, DWORD_PTR size, DWORD id ) { LANGID lang = GetSystemDefaultLangID(); const tt_header *header; @@ -1465,8 +1468,9 @@ static WCHAR *load_ttf_name_id( const BYTE *mem, DWORD_PTR size, DWORD id, WCHAR if (best_lang) { + WCHAR *ret; name_record = (const tt_name_record*)(name_table + 1) + best_index; - ret = copy_name_table_string( name_record, mem+ofs+GET_BE_WORD(name_record->offset), ret, len ); + ret = copy_name_table_string( name_record, mem+ofs+GET_BE_WORD(name_record->offset) ); TRACE( "name %u found platform %u lang %04x %s\n", GET_BE_WORD(name_record->name_id), GET_BE_WORD(name_record->platform_id), GET_BE_WORD(name_record->language_id), debugstr_w( ret )); return ret; @@ -1482,43 +1486,45 @@ static INT CALLBACK add_font_proc(const LOGFONTW *lfw, const TEXTMETRICW *ntm, D GpStatus WINGDIPAPI GdipPrivateAddMemoryFont(GpFontCollection* fontCollection, GDIPCONST void* memory, INT length) { - WCHAR buf[32], *name; + WCHAR *name; DWORD count = 0; HANDLE font; + GpStatus ret = Ok; TRACE("%p, %p, %d\n", fontCollection, memory, length); if (!fontCollection || !memory || !length) return InvalidParameter; - name = load_ttf_name_id(memory, length, NAME_ID_FULL_FONT_NAME, buf, sizeof(buf)/sizeof(*buf)); + name = load_ttf_name_id(memory, length, NAME_ID_FULL_FONT_NAME); if (!name) return OutOfMemory; font = AddFontMemResourceEx((void*)memory, length, NULL, &count); TRACE("%s: %p/%u\n", debugstr_w(name), font, count); if (!font || !count) - return InvalidParameter; - - if (count) + ret = InvalidParameter; + else { HDC hdc; LOGFONTW lfw; hdc = CreateCompatibleDC(0); + /* Truncate name if necessary, GDI32 can't deal with long names */ + if(lstrlenW(name) > LF_FACESIZE - 1) + name[LF_FACESIZE - 1] = 0; + lfw.lfCharSet = DEFAULT_CHARSET; lstrcpyW(lfw.lfFaceName, name); lfw.lfPitchAndFamily = 0; if (!EnumFontFamiliesExW(hdc, &lfw, add_font_proc, (LPARAM)fontCollection, 0)) - { - DeleteDC(hdc); - return OutOfMemory; - } + ret = OutOfMemory; DeleteDC(hdc); } - return Ok; + heap_free(name); + return ret; } /***************************************************************************** diff --git a/dll/win32/gdiplus/gdiplus.spec b/dll/win32/gdiplus/gdiplus.spec index b29e41ebfa..0e7a78f30c 100644 --- a/dll/win32/gdiplus/gdiplus.spec +++ b/dll/win32/gdiplus/gdiplus.spec @@ -615,7 +615,7 @@ 615 stub GdipGetEffectParameterSize 616 stub GdipGetEffectParameters 617 stdcall GdipSetEffectParameters(ptr ptr long) -618 stdcall GdipInitializePalette(ptr long long long ptr) +618 stdcall -stub GdipInitializePalette(ptr long long long ptr) 619 stdcall GdipBitmapCreateApplyEffect(ptr long ptr ptr ptr ptr long ptr ptr) 620 stdcall GdipBitmapApplyEffect(ptr ptr ptr long ptr ptr) 621 stdcall GdipBitmapGetHistogram(ptr long long ptr ptr ptr ptr) diff --git a/dll/win32/gdiplus/gdiplus_private.h b/dll/win32/gdiplus/gdiplus_private.h index 633ef14b41..192e36756a 100644 --- a/dll/win32/gdiplus/gdiplus_private.h +++ b/dll/win32/gdiplus/gdiplus_private.h @@ -129,6 +129,7 @@ extern GpStatus METAFILE_DrawImagePointsRect(GpMetafile* metafile, GpImage *imag extern GpStatus METAFILE_AddSimpleProperty(GpMetafile *metafile, SHORT prop, SHORT val) DECLSPEC_HIDDEN; extern GpStatus METAFILE_DrawPath(GpMetafile *metafile, GpPen *pen, GpPath *path) DECLSPEC_HIDDEN; extern GpStatus METAFILE_FillPath(GpMetafile *metafile, GpBrush *brush, GpPath *path) DECLSPEC_HIDDEN; +extern void METAFILE_Free(GpMetafile *metafile) DECLSPEC_HIDDEN; extern void calc_curve_bezier(const GpPointF *pts, REAL tension, REAL *x1, REAL *y1, REAL *x2, REAL *y2) DECLSPEC_HIDDEN; @@ -147,7 +148,7 @@ extern GpStatus trace_path(GpGraphics *graphics, GpPath *path) DECLSPEC_HIDDEN; typedef struct region_element region_element; extern void delete_element(region_element *element) DECLSPEC_HIDDEN; -extern GpStatus get_hatch_data(HatchStyle hatchstyle, const char **result) DECLSPEC_HIDDEN; +extern GpStatus get_hatch_data(GpHatchStyle hatchstyle, const char **result) DECLSPEC_HIDDEN; static inline INT gdip_round(REAL x) { @@ -270,6 +271,7 @@ struct GpGraphics{ INT origin_x, origin_y; INT gdi_transform_acquire_count, gdi_transform_save; GpMatrix gdi_transform; + HRGN gdi_clip; /* For giving the caller an HDC when we technically can't: */ HBITMAP temp_hbitmap; int temp_hbitmap_width; @@ -284,7 +286,7 @@ struct GpBrush{ struct GpHatch{ GpBrush brush; - HatchStyle hatchstyle; + GpHatchStyle hatchstyle; ARGB forecol; ARGB backcol; }; @@ -378,6 +380,38 @@ struct GpImage{ LONG busy; }; +#define EmfPlusObjectTableSize 64 + +typedef enum EmfPlusObjectType +{ + ObjectTypeInvalid, + ObjectTypeBrush, + ObjectTypePen, + ObjectTypePath, + ObjectTypeRegion, + ObjectTypeImage, + ObjectTypeFont, + ObjectTypeStringFormat, + ObjectTypeImageAttributes, + ObjectTypeCustomLineCap, + ObjectTypeMax = ObjectTypeCustomLineCap, +} EmfPlusObjectType; + +/* Deserialized EmfPlusObject record. */ +struct emfplus_object { + EmfPlusObjectType type; + union { + GpBrush *brush; + GpPen *pen; + GpPath *path; + GpRegion *region; + GpImage *image; + GpFont *font; + GpImageAttributes *image_attributes; + void *object; + } u; +}; + struct GpMetafile{ GpImage image; GpRectF bounds; @@ -411,6 +445,7 @@ struct GpMetafile{ GpRegion *base_clip; /* clip region in device space for all metafile output */ GpRegion *clip; /* clip region within the metafile */ struct list containers; + struct emfplus_object objtable[EmfPlusObjectTableSize]; }; struct GpBitmap{ @@ -454,6 +489,12 @@ struct color_remap_table{ ColorMap *colormap; }; +enum imageattr_noop{ + IMAGEATTR_NOOP_UNDEFINED, + IMAGEATTR_NOOP_SET, + IMAGEATTR_NOOP_CLEAR, +}; + struct GpImageAttributes{ WrapMode wrap; ARGB outside_color; @@ -463,6 +504,7 @@ struct GpImageAttributes{ struct color_remap_table colorremaptables[ColorAdjustTypeCount]; BOOL gamma_enabled[ColorAdjustTypeCount]; REAL gamma[ColorAdjustTypeCount]; + enum imageattr_noop noop[ColorAdjustTypeCount]; }; struct GpFont{ @@ -535,6 +577,30 @@ struct GpRegion{ region_element node; }; +struct memory_buffer +{ + const BYTE *buffer; + INT size, pos; +}; + +static inline void init_memory_buffer(struct memory_buffer *mbuf, const BYTE *buffer, INT size) +{ + mbuf->buffer = buffer; + mbuf->size = size; + mbuf->pos = 0; +} + +static inline const void *buffer_read(struct memory_buffer *mbuf, INT size) +{ + if (mbuf->size - mbuf->pos >= size) + { + const void *data = mbuf->buffer + mbuf->pos; + mbuf->pos += size; + return data; + } + return NULL; +} + typedef GpStatus (*gdip_format_string_callback)(HDC hdc, GDIPCONST WCHAR *string, INT index, INT length, GDIPCONST GpFont *font, GDIPCONST RectF *rect, GDIPCONST GpStringFormat *format, diff --git a/dll/win32/gdiplus/graphics.c b/dll/win32/gdiplus/graphics.c index 79f9b11248..71ea19cbb5 100644 --- a/dll/win32/gdiplus/graphics.c +++ b/dll/win32/gdiplus/graphics.c @@ -302,13 +302,6 @@ static void round_points(POINT *pti, GpPointF *ptf, INT count) } } -static void transform_and_round_points(GpGraphics *graphics, POINT *pti, - GpPointF *ptf, INT count) -{ - gdip_transform_points(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, ptf, count); - round_points(pti, ptf, count); -} - static void gdi_alpha_blend(GpGraphics *graphics, INT dst_x, INT dst_y, INT dst_width, INT dst_height, HDC hdc, INT src_x, INT src_y, INT src_width, INT src_height) { @@ -355,6 +348,17 @@ static GpStatus get_clip_hrgn(GpGraphics *graphics, HRGN *hrgn) GdipDeleteRegion(rgn); } + if (stat == Ok && graphics->gdi_clip) + { + if (*hrgn) + CombineRgn(*hrgn, *hrgn, graphics->gdi_clip, RGN_AND); + else + { + *hrgn = CreateRectRgn(0,0,0,0); + CombineRgn(*hrgn, graphics->gdi_clip, graphics->gdi_clip, RGN_COPY); + } + } + return stat; } @@ -505,8 +509,6 @@ static GpStatus alpha_blend_pixels_hrgn(GpGraphics *graphics, INT dst_x, INT dst save = SaveDC(graphics->hdc); - SetViewportOrgEx(graphics->hdc, 0, 0, NULL); - ExtSelectClipRgn(graphics->hdc, hrgn, RGN_COPY); if (hregion) @@ -529,23 +531,12 @@ static GpStatus alpha_blend_pixels(GpGraphics *graphics, INT dst_x, INT dst_y, return alpha_blend_pixels_hrgn(graphics, dst_x, dst_y, src, src_width, src_height, src_stride, NULL, fmt); } -/* NOTE: start and end pixels must be in pre-multiplied ARGB format */ -static inline ARGB blend_colors_premult(ARGB start, ARGB end, REAL position) -{ - UINT pos = position * 255.0f + 0.5f; - return - (((((start >> 24) ) << 8) + (((end >> 24) ) - ((start >> 24) )) * pos) >> 8) << 24 | - (((((start >> 16) & 0xff) << 8) + (((end >> 16) & 0xff) - ((start >> 16) & 0xff)) * pos) >> 8) << 16 | - (((((start >> 8) & 0xff) << 8) + (((end >> 8) & 0xff) - ((start >> 8) & 0xff)) * pos) >> 8) << 8 | - (((((start ) & 0xff) << 8) + (((end ) & 0xff) - ((start ) & 0xff)) * pos) >> 8); -} - static ARGB blend_colors(ARGB start, ARGB end, REAL position) { INT start_a, end_a, final_a; INT pos; - pos = (INT)(position * 255.0f + 0.5f); + pos = gdip_round(position * 0xff); start_a = ((start >> 24) & 0xff) * (pos ^ 0xff); end_a = ((end >> 24) & 0xff) * pos; @@ -685,6 +676,11 @@ PixelFormat apply_image_attributes(const GpImageAttributes *attributes, LPBYTE d UINT x, y; INT i; + if ((attributes->noop[type] == IMAGEATTR_NOOP_UNDEFINED && + attributes->noop[ColorAdjustTypeDefault] == IMAGEATTR_NOOP_SET) || + (attributes->noop[type] == IMAGEATTR_NOOP_SET)) + return fmt; + if (attributes->colorkeys[type].enabled || attributes->colorkeys[ColorAdjustTypeDefault].enabled) { @@ -946,11 +942,6 @@ static ARGB sample_bitmap_pixel(GDIPCONST GpRect *src_rect, LPBYTE bits, UINT wi return ((DWORD*)(bits))[(x - src_rect->X) + (y - src_rect->Y) * src_rect->Width]; } -static inline int positive_ceilf(float f) -{ - return f - (int)f > 0.0f ? f + 1.0f : f; -} - static ARGB resample_bitmap_pixel(GDIPCONST GpRect *src_rect, LPBYTE bits, UINT width, UINT height, GpPointF *point, GDIPCONST GpImageAttributes *attributes, InterpolationMode interpolation, PixelOffsetMode offset_mode) @@ -971,12 +962,12 @@ static ARGB resample_bitmap_pixel(GDIPCONST GpRect *src_rect, LPBYTE bits, UINT ARGB top, bottom; float x_offset; - leftx = (INT)point->X; - leftxf = (REAL)leftx; - rightx = positive_ceilf(point->X); - topy = (INT)point->Y; - topyf = (REAL)topy; - bottomy = positive_ceilf(point->Y); + leftxf = floorf(point->X); + leftx = (INT)leftxf; + rightx = (INT)ceilf(point->X); + topyf = floorf(point->Y); + topy = (INT)topyf; + bottomy = (INT)ceilf(point->Y); if (leftx == rightx && topy == bottomy) return sample_bitmap_pixel(src_rect, bits, width, height, @@ -1020,75 +1011,6 @@ static ARGB resample_bitmap_pixel(GDIPCONST GpRect *src_rect, LPBYTE bits, UINT } } -static ARGB resample_bitmap_pixel_premult(GDIPCONST GpRect *src_rect, LPBYTE bits, UINT width, - UINT height, GpPointF *point, GDIPCONST GpImageAttributes *attributes, - InterpolationMode interpolation, PixelOffsetMode offset_mode) -{ - static int fixme; - - switch (interpolation) - { - default: - if (!fixme++) - FIXME("Unimplemented interpolation %i\n", interpolation); - /* fall-through */ - case InterpolationModeBilinear: - { - REAL leftxf, topyf; - INT leftx, rightx, topy, bottomy; - ARGB topleft, topright, bottomleft, bottomright; - ARGB top, bottom; - float x_offset; - - leftx = (INT)point->X; - leftxf = (REAL)leftx; - rightx = positive_ceilf(point->X); - topy = (INT)point->Y; - topyf = (REAL)topy; - bottomy = positive_ceilf(point->Y); - - if (leftx == rightx && topy == bottomy) - return sample_bitmap_pixel(src_rect, bits, width, height, - leftx, topy, attributes); - - topleft = sample_bitmap_pixel(src_rect, bits, width, height, - leftx, topy, attributes); - topright = sample_bitmap_pixel(src_rect, bits, width, height, - rightx, topy, attributes); - bottomleft = sample_bitmap_pixel(src_rect, bits, width, height, - leftx, bottomy, attributes); - bottomright = sample_bitmap_pixel(src_rect, bits, width, height, - rightx, bottomy, attributes); - - x_offset = point->X - leftxf; - top = blend_colors_premult(topleft, topright, x_offset); - bottom = blend_colors_premult(bottomleft, bottomright, x_offset); - - return blend_colors_premult(top, bottom, point->Y - topyf); - } - case InterpolationModeNearestNeighbor: - { - FLOAT pixel_offset; - switch (offset_mode) - { - default: - case PixelOffsetModeNone: - case PixelOffsetModeHighSpeed: - pixel_offset = 0.5; - break; - - case PixelOffsetModeHalf: - case PixelOffsetModeHighQuality: - pixel_offset = 0.0; - break; - } - return sample_bitmap_pixel(src_rect, bits, width, height, - floorf(point->X + pixel_offset), point->Y + pixel_offset, attributes); - } - - } -} - static REAL intersect_line_scanline(const GpPointF *p1, const GpPointF *p2, REAL y) { return (p1->X - p2->X) * (p2->Y - y) / (p2->Y - p1->Y) + p2->X; @@ -2312,7 +2234,7 @@ static void get_font_hfont(GpGraphics *graphics, GDIPCONST GpFont *font, GdipTransformMatrixPoints(&xform, pt, 3); } - GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, pt, 3); + gdip_transform_points(graphics, WineCoordinateSpaceGdiDevice, CoordinateSpaceWorld, pt, 3); angle = -gdiplus_atan2((pt[1].Y - pt[0].Y), (pt[1].X - pt[0].X)); rel_width = sqrt((pt[1].Y-pt[0].Y)*(pt[1].Y-pt[0].Y)+ (pt[1].X-pt[0].X)*(pt[1].X-pt[0].X)); @@ -2342,6 +2264,20 @@ GpStatus WINGDIPAPI GdipCreateFromHDC(HDC hdc, GpGraphics **graphics) return GdipCreateFromHDC2(hdc, NULL, graphics); } +static void get_gdi_transform(GpGraphics *graphics, GpMatrix *matrix) +{ + XFORM xform; + + if (graphics->hdc == NULL) + { + GdipSetMatrixElements(matrix, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0); + return; + } + + GetTransform(graphics->hdc, 0x204, &xform); + GdipSetMatrixElements(matrix, xform.eM11, xform.eM12, xform.eM21, xform.eM22, xform.eDx, xform.eDy); +} + GpStatus WINGDIPAPI GdipCreateFromHDC2(HDC hdc, HANDLE hDevice, GpGraphics **graphics) { GpStatus retval; @@ -2391,7 +2327,19 @@ GpStatus WINGDIPAPI GdipCreateFromHDC2(HDC hdc, HANDLE hDevice, GpGraphics **gra (*graphics)->busy = FALSE; (*graphics)->textcontrast = 4; list_init(&(*graphics)->containers); +#ifdef __REACTOS__ (*graphics)->contid = GDIP_GET_NEW_CONTID_FOR(*graphics); +#else + (*graphics)->contid = 0; +#endif + get_gdi_transform(*graphics, &(*graphics)->gdi_transform); + + (*graphics)->gdi_clip = CreateRectRgn(0,0,0,0); + if (!GetClipRgn(hdc, (*graphics)->gdi_clip)) + { + DeleteObject((*graphics)->gdi_clip); + (*graphics)->gdi_clip = NULL; + } TRACE("<-- %p\n", *graphics); @@ -2406,6 +2354,7 @@ GpStatus graphics_from_image(GpImage *image, GpGraphics **graphics) if(!*graphics) return OutOfMemory; GdipSetMatrixElements(&(*graphics)->worldtrans, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0); + GdipSetMatrixElements(&(*graphics)->gdi_transform, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0); if((retval = GdipCreateRegion(&(*graphics)->clip)) != Ok){ heap_free(*graphics); @@ -2431,7 +2380,11 @@ GpStatus graphics_from_image(GpImage *image, GpGraphics **graphics) (*graphics)->busy = FALSE; (*graphics)->textcontrast = 4; list_init(&(*graphics)->containers); +#ifdef __REACTOS__ (*graphics)->contid = GDIP_GET_NEW_CONTID_FOR(*graphics); +#else + (*graphics)->contid = 0; +#endif TRACE("<-- %p\n", *graphics); @@ -2516,6 +2469,8 @@ GpStatus WINGDIPAPI GdipDeleteGraphics(GpGraphics *graphics) GdipDeleteRegion(graphics->clip); + DeleteObject(graphics->gdi_clip); + /* Native returns ObjectBusy on the second free, instead of crashing as we'd * do otherwise, but we can't have that in the test suite because it means * accessing freed memory. */ @@ -3151,10 +3106,8 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image lockeddata.Scan0 = src_data; if (!do_resampling && bitmap->format == PixelFormat32bppPARGB) lockeddata.PixelFormat = apply_image_attributes(imageAttributes, NULL, 0, 0, 0, ColorAdjustTypeBitmap, bitmap->format); - else if (imageAttributes != &defaultImageAttributes) - lockeddata.PixelFormat = PixelFormat32bppARGB; else - lockeddata.PixelFormat = PixelFormat32bppPARGB; + lockeddata.PixelFormat = PixelFormat32bppARGB; stat = GdipBitmapLockBits(bitmap, &src_area, ImageLockModeRead|ImageLockModeUserInputBuf, lockeddata.PixelFormat, &lockeddata); @@ -3174,8 +3127,6 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image if (do_resampling) { - REAL delta_xx, delta_xy, delta_yx, delta_yy; - /* Transform the bits as needed to the destination. */ dst_data = dst_dyn_data = heap_alloc_zero(sizeof(ARGB) * (dst_area.right - dst_area.left) * (dst_area.bottom - dst_area.top)); if (!dst_data) @@ -3193,42 +3144,24 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image y_dx = dst_to_src_points[2].X - dst_to_src_points[0].X; y_dy = dst_to_src_points[2].Y - dst_to_src_points[0].Y; - delta_yy = dst_area.top * y_dy; - delta_yx = dst_area.top * y_dx; - - for (y=dst_area.top; y<dst_area.bottom; y++) + for (x=dst_area.left; x<dst_area.right; x++) { - delta_xx = dst_area.left * x_dx; - delta_xy = dst_area.left * x_dy; - - for (x=dst_area.left; x<dst_area.right; x++) + for (y=dst_area.top; y<dst_area.bottom; y++) { GpPointF src_pointf; ARGB *dst_color; - src_pointf.X = dst_to_src_points[0].X + delta_xx + delta_yx; - src_pointf.Y = dst_to_src_points[0].Y + delta_xy + delta_yy; + src_pointf.X = dst_to_src_points[0].X + x * x_dx + y * y_dx; + src_pointf.Y = dst_to_src_points[0].Y + x * x_dy + y * y_dy; dst_color = (ARGB*)(dst_data + dst_stride * (y - dst_area.top) + sizeof(ARGB) * (x - dst_area.left)); if (src_pointf.X >= srcx && src_pointf.X < srcx + srcwidth && src_pointf.Y >= srcy && src_pointf.Y < srcy+srcheight) - { - if (lockeddata.PixelFormat != PixelFormat32bppPARGB) - *dst_color = resample_bitmap_pixel(&src_area, src_data, bitmap->width, bitmap->height, &src_pointf, - imageAttributes, interpolation, offset_mode); - else - *dst_color = resample_bitmap_pixel_premult(&src_area, src_data, bitmap->width, bitmap->height, &src_pointf, - imageAttributes, interpolation, offset_mode); - } + *dst_color = resample_bitmap_pixel(&src_area, src_data, bitmap->width, bitmap->height, &src_pointf, + imageAttributes, interpolation, offset_mode); else *dst_color = 0; - - delta_xx += x_dx; - delta_yx += y_dx; } - - delta_xy += x_dy; - delta_yy += y_dy; } } else @@ -3322,9 +3255,9 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image stat = get_clip_hrgn(graphics, &hrgn); - if (stat == Ok && hrgn) + if (stat == Ok) { - ExtSelectClipRgn(graphics->hdc, hrgn, RGN_AND); + ExtSelectClipRgn(graphics->hdc, hrgn, RGN_COPY); DeleteObject(hrgn); } @@ -3565,8 +3498,7 @@ static GpStatus GDI32_GdipDrawPath(GpGraphics *graphics, GpPen *pen, GpPath *pat if (retval != Ok) goto end; - if (hrgn) - ExtSelectClipRgn(graphics->hdc, hrgn, RGN_AND); + ExtSelectClipRgn(graphics->hdc, hrgn, RGN_COPY); gdi_transform_acquire(graphics); @@ -3907,7 +3839,7 @@ static GpStatus SOFTWARE_GdipDrawPath(GpGraphics *graphics, GpPen *pen, GpPath * points[1].X = pen->width; points[2].Y = pen->width; - stat = GdipTransformPoints(graphics, CoordinateSpaceDevice, + stat = gdip_transform_points(graphics, WineCoordinateSpaceGdiDevice, CoordinateSpaceWorld, points, 3); if (stat != Ok) @@ -3931,7 +3863,7 @@ static GpStatus SOFTWARE_GdipDrawPath(GpGraphics *graphics, GpPen *pen, GpPath * stat = GdipCreateMatrix(&transform); if (stat == Ok) - stat = get_graphics_transform(graphics, CoordinateSpaceDevice, + stat = get_graphics_transform(graphics, WineCoordinateSpaceGdiDevice, CoordinateSpaceWorld, transform); } else @@ -3939,7 +3871,7 @@ static GpStatus SOFTWARE_GdipDrawPath(GpGraphics *graphics, GpPen *pen, GpPath * /* Set flatness based on the final coordinate space */ GpMatrix t; - stat = get_graphics_transform(graphics, CoordinateSpaceDevice, + stat = get_graphics_transform(graphics, WineCoordinateSpaceGdiDevice, CoordinateSpaceWorld, &t); if (stat != Ok) @@ -4254,8 +4186,7 @@ static GpStatus GDI32_GdipFillPath(GpGraphics *graphics, GpBrush *brush, GpPath if (retval != Ok) goto end; - if (hrgn) - ExtSelectClipRgn(graphics->hdc, hrgn, RGN_AND); + ExtSelectClipRgn(graphics->hdc, hrgn, RGN_COPY); gdi_transform_acquire(graphics); @@ -4542,32 +4473,30 @@ static GpStatus GDI32_GdipFillRegion(GpGraphics* graphics, GpBrush* brush, if(!graphics->hdc || !brush_can_fill_path(brush, TRUE)) return NotImplemented; - status = GdipGetRegionHRgn(region, graphics, &hrgn); - if(status != Ok) - return status; - save_state = SaveDC(graphics->hdc); EndPath(graphics->hdc); - ExtSelectClipRgn(graphics->hdc, hrgn, RGN_AND); - - DeleteObject(hrgn); - hrgn = NULL; status = get_clip_hrgn(graphics, &hrgn); - if (status != Ok) { RestoreDC(graphics->hdc, save_state); return status; } - if (hrgn) + ExtSelectClipRgn(graphics->hdc, hrgn, RGN_COPY); + DeleteObject(hrgn); + + status = GdipGetRegionHRgn(region, graphics, &hrgn); + if (status != Ok) { - ExtSelectClipRgn(graphics->hdc, hrgn, RGN_AND); - DeleteObject(hrgn); + RestoreDC(graphics->hdc, save_state); + return status; } + ExtSelectClipRgn(graphics->hdc, hrgn, RGN_AND); + DeleteObject(hrgn); + if (GetClipBox(graphics->hdc, &rc) != NULLREGION) { BeginPath(graphics->hdc); @@ -5371,7 +5300,7 @@ GpStatus WINGDIPAPI GdipMeasureCharacterRanges(GpGraphics* graphics, pt[1].Y = 0.0; pt[2].X = 0.0; pt[2].Y = 1.0; - GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, pt, 3); + gdip_transform_points(graphics, WineCoordinateSpaceGdiDevice, CoordinateSpaceWorld, pt, 3); args.rel_width = sqrt((pt[1].Y-pt[0].Y)*(pt[1].Y-pt[0].Y)+ (pt[1].X-pt[0].X)*(pt[1].X-pt[0].X)); args.rel_height = sqrt((pt[2].Y-pt[0].Y)*(pt[2].Y-pt[0].Y)+ @@ -5400,9 +5329,13 @@ GpStatus WINGDIPAPI GdipMeasureCharacterRanges(GpGraphics* graphics, args.regions = regions; + gdi_transform_acquire(graphics); + stat = gdip_format_string(hdc, string, length, font, &scaled_rect, stringFormat, (stringFormat->attr & StringFormatFlagsNoClip) != 0, measure_ranges_callback, &args); + gdi_transform_release(graphics); + SelectObject(hdc, oldfont); DeleteObject(gdifont); @@ -5490,7 +5423,7 @@ GpStatus WINGDIPAPI GdipMeasureString(GpGraphics *graphics, pt[1].Y = 0.0; pt[2].X = 0.0; pt[2].Y = 1.0; - GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, pt, 3); + gdip_transform_points(graphics, WineCoordinateSpaceGdiDevice, CoordinateSpaceWorld, pt, 3); args.rel_width = sqrt((pt[1].Y-pt[0].Y)*(pt[1].Y-pt[0].Y)+ (pt[1].X-pt[0].X)*(pt[1].X-pt[0].X)); args.rel_height = sqrt((pt[2].Y-pt[0].Y)*(pt[2].Y-pt[0].Y)+ @@ -5525,9 +5458,13 @@ GpStatus WINGDIPAPI GdipMeasureString(GpGraphics *graphics, args.linesfilled = &lines; lines = glyphs = 0; + gdi_transform_acquire(graphics); + gdip_format_string(hdc, string, length, font, &scaled_rect, format, TRUE, measure_string_callback, &args); + gdi_transform_release(graphics); + if (linesfilled) *linesfilled = lines; if (codepointsfitted) *codepointsfitted = glyphs; @@ -5657,7 +5594,7 @@ GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string pt[1].Y = 0.0; pt[2].X = 0.0; pt[2].Y = 1.0; - GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, pt, 3); + gdip_transform_points(graphics, WineCoordinateSpaceGdiDevice, CoordinateSpaceWorld, pt, 3); rel_width = sqrt((pt[1].Y-pt[0].Y)*(pt[1].Y-pt[0].Y)+ (pt[1].X-pt[0].X)*(pt[1].X-pt[0].X)); rel_height = sqrt((pt[2].Y-pt[0].Y)*(pt[2].Y-pt[0].Y)+ @@ -5667,7 +5604,8 @@ GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string rectcpy[1].Y = rectcpy[0].Y = rect->Y; rectcpy[2].X = rectcpy[1].X = rect->X + rect->Width; rectcpy[3].Y = rectcpy[2].Y = rect->Y + rect->Height; - transform_and_round_points(graphics, corners, rectcpy, 4); + gdip_transform_points(graphics, WineCoordinateSpaceGdiDevice, CoordinateSpaceWorld, rectcpy, 4); + round_points(corners, rectcpy, 4); margin_x = (format && format->generic_typographic) ? 0.0 : font->emSize / 6.0; margin_x *= units_scale(font->unit, graphics->unit, graphics->xres); @@ -5706,12 +5644,16 @@ GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string args.rel_width = rel_width; args.rel_height = rel_height; + gdi_transform_acquire(graphics); + GetTextMetricsW(hdc, &textmetric); args.ascent = textmetric.tmAscent / rel_height; gdip_format_string(hdc, string, length, font, &scaled_rect, format, TRUE, draw_string_callback, &args); + gdi_transform_release(graphics); + DeleteObject(rgn); DeleteObject(gdifont); @@ -6311,6 +6253,7 @@ GpStatus WINGDIPAPI GdipSetClipHrgn(GpGraphics *graphics, HRGN hrgn, CombineMode { GpRegion *region; GpStatus status; + GpMatrix transform; TRACE("(%p, %p, %d)\n", graphics, hrgn, mode); @@ -6320,14 +6263,21 @@ GpStatus WINGDIPAPI GdipSetClipHrgn(GpGraphics *graphics, HRGN hrgn, CombineMode if(graphics->busy) return ObjectBusy; - /* hrgn is already in device units */ + /* hrgn is in gdi32 device units */ status = GdipCreateRegionHrgn(hrgn, ®ion); - if(status != Ok) - return status; - status = GdipCombineRegionRegion(graphics->clip, region, mode); + if (status == Ok) + { + status = get_graphics_transform(graphics, CoordinateSpaceDevice, WineCoordinateSpaceGdiDevice, &transform); + + if (status == Ok) + status = GdipTransformRegion(region, &transform); + + if (status == Ok) + status = GdipCombineRegionRegion(graphics->clip, region, mode); - GdipDeleteRegion(region); + GdipDeleteRegion(region); + } return status; } @@ -6723,31 +6673,10 @@ GpStatus WINGDIPAPI GdipGetClip(GpGraphics *graphics, GpRegion *region) return Ok; } -static void get_gdi_transform(GpGraphics *graphics, GpMatrix *matrix) -{ - XFORM xform; - - if (graphics->hdc == NULL) - { - GdipSetMatrixElements(matrix, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0); - return; - } - - if (graphics->gdi_transform_acquire_count) - { - *matrix = graphics->gdi_transform; - return; - } - - GetTransform(graphics->hdc, 0x204, &xform); - GdipSetMatrixElements(matrix, xform.eM11, xform.eM12, xform.eM21, xform.eM22, xform.eDx, xform.eDy); -} - GpStatus gdi_transform_acquire(GpGraphics *graphics) { if (graphics->gdi_transform_acquire_count == 0 && graphics->hdc) { - get_gdi_transform(graphics, &graphics->gdi_transform); graphics->gdi_transform_save = SaveDC(graphics->hdc); SetGraphicsMode(graphics->hdc, GM_COMPATIBLE); SetMapMode(graphics->hdc, MM_TEXT); @@ -6762,7 +6691,7 @@ GpStatus gdi_transform_release(GpGraphics *graphics) { if (graphics->gdi_transform_acquire_count <= 0) { - ERR("called without matching gdi_transform_acquire"); + ERR("called without matching gdi_transform_acquire\n"); return GenericError; } if (graphics->gdi_transform_acquire_count == 1 && graphics->hdc) @@ -6800,7 +6729,7 @@ GpStatus get_graphics_transform(GpGraphics *graphics, GpCoordinateSpace dst_spac case WineCoordinateSpaceGdiDevice: { GpMatrix gdixform; - get_gdi_transform(graphics, &gdixform); + gdixform = graphics->gdi_transform; stat = GdipInvertMatrix(&gdixform); if (stat != Ok) break; @@ -6841,9 +6770,7 @@ GpStatus get_graphics_transform(GpGraphics *graphics, GpCoordinateSpace dst_spac /* else fall-through */ case CoordinateSpaceDevice: { - GpMatrix gdixform; - get_gdi_transform(graphics, &gdixform); - GdipMultiplyMatrix(matrix, &gdixform, MatrixOrderAppend); + GdipMultiplyMatrix(matrix, &graphics->gdi_transform, MatrixOrderAppend); break; } } @@ -7015,7 +6942,7 @@ GpStatus WINGDIPAPI GdipMeasureDriverString(GpGraphics *graphics, GDIPCONST UINT GpMatrix xform = *matrix; GdipTransformMatrixPoints(&xform, pt, 3); } - GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, pt, 3); + gdip_transform_points(graphics, WineCoordinateSpaceGdiDevice, CoordinateSpaceWorld, pt, 3); rel_width = sqrt((pt[1].Y-pt[0].Y)*(pt[1].Y-pt[0].Y)+ (pt[1].X-pt[0].X)*(pt[1].X-pt[0].X)); rel_height = sqrt((pt[2].Y-pt[0].Y)*(pt[2].Y-pt[0].Y)+ @@ -7102,22 +7029,26 @@ static GpStatus GDI32_GdipDrawDriverString(GpGraphics *graphics, GDIPCONST UINT1 status = get_clip_hrgn(graphics, &hrgn); - if (status == Ok && hrgn) + if (status == Ok) { - ExtSelectClipRgn(graphics->hdc, hrgn, RGN_AND); + ExtSelectClipRgn(graphics->hdc, hrgn, RGN_COPY); DeleteObject(hrgn); } pt = positions[0]; - GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, &pt, 1); + gdip_transform_points(graphics, WineCoordinateSpaceGdiDevice, CoordinateSpaceWorld, &pt, 1); get_font_hfont(graphics, font, format, &hfont, matrix); SelectObject(graphics->hdc, hfont); SetTextAlign(graphics->hdc, TA_BASELINE|TA_LEFT); + gdi_transform_acquire(graphics); + ExtTextOutW(graphics->hdc, gdip_round(pt.X), gdip_round(pt.Y), eto_flags, NULL, text, length, NULL); + gdi_transform_release(graphics); + RestoreDC(graphics->hdc, save_state); DeleteObject(hfont); @@ -7165,7 +7096,8 @@ static GpStatus SOFTWARE_GdipDrawDriverString(GpGraphics *graphics, GDIPCONST UI { real_position = positions[0]; - transform_and_round_points(graphics, pti, &real_position, 1); + gdip_transform_points(graphics, WineCoordinateSpaceGdiDevice, CoordinateSpaceWorld, &real_position, 1); + round_points(pti, &real_position, 1); } else { @@ -7178,7 +7110,8 @@ static GpStatus SOFTWARE_GdipDrawDriverString(GpGraphics *graphics, GDIPCONST UI memcpy(real_positions, positions, sizeof(PointF) * length); - transform_and_round_points(graphics, pti, real_positions, length); + gdip_transform_points(graphics, WineCoordinateSpaceGdiDevice, CoordinateSpaceWorld, real_positions, length); + round_points(pti, real_positions, length); heap_free(real_positions); } @@ -7318,10 +7251,14 @@ static GpStatus SOFTWARE_GdipDrawDriverString(GpGraphics *graphics, GDIPCONST UI heap_free(text_mask); + gdi_transform_acquire(graphics); + /* draw the result */ stat = alpha_blend_pixels(graphics, min_x, min_y, pixel_data, pixel_area.Width, pixel_area.Height, pixel_data_stride, PixelFormat32bppARGB); + gdi_transform_release(graphics); + heap_free(pixel_data); return stat; diff --git a/dll/win32/gdiplus/image.c b/dll/win32/gdiplus/image.c index 214b95f40e..6390bff288 100644 --- a/dll/win32/gdiplus/image.c +++ b/dll/win32/gdiplus/image.c @@ -38,19 +38,13 @@ static const struct { { &GUID_WICPixelFormatBlackWhite, PixelFormat1bppIndexed, WICBitmapPaletteTypeFixedBW }, { &GUID_WICPixelFormat1bppIndexed, PixelFormat1bppIndexed, WICBitmapPaletteTypeFixedBW }, - { &GUID_WICPixelFormat4bppIndexed, PixelFormat4bppIndexed, WICBitmapPaletteTypeFixedHalftone8 }, { &GUID_WICPixelFormat8bppGray, PixelFormat8bppIndexed, WICBitmapPaletteTypeFixedGray256 }, { &GUID_WICPixelFormat8bppIndexed, PixelFormat8bppIndexed, WICBitmapPaletteTypeFixedHalftone256 }, { &GUID_WICPixelFormat16bppBGR555, PixelFormat16bppRGB555, WICBitmapPaletteTypeFixedHalftone256 }, { &GUID_WICPixelFormat24bppBGR, PixelFormat24bppRGB, WICBitmapPaletteTypeFixedHalftone256 }, { &GUID_WICPixelFormat32bppBGR, PixelFormat32bppRGB, WICBitmapPaletteTypeFixedHalftone256 }, - { &GUID_WICPixelFormat48bppRGB, PixelFormat48bppRGB, WICBitmapPaletteTypeFixedHalftone256 }, { &GUID_WICPixelFormat32bppBGRA, PixelFormat32bppARGB, WICBitmapPaletteTypeFixedHalftone256 }, { &GUID_WICPixelFormat32bppPBGRA, PixelFormat32bppPARGB, WICBitmapPaletteTypeFixedHalftone256 }, - { &GUID_WICPixelFormat32bppCMYK, PixelFormat32bppCMYK, WICBitmapPaletteTypeFixedHalftone256 }, - { &GUID_WICPixelFormat32bppGrayFloat, PixelFormat32bppARGB, WICBitmapPaletteTypeFixedGray256 }, - { &GUID_WICPixelFormat64bppCMYK, PixelFormat48bppRGB, WICBitmapPaletteTypeFixedHalftone256 }, - { &GUID_WICPixelFormat64bppRGBA, PixelFormat48bppRGB, WICBitmapPaletteTypeFixedHalftone256 }, { NULL } }; @@ -2074,24 +2068,7 @@ static GpStatus free_image_data(GpImage *image) heap_free(((GpBitmap*)image)->prop_item); } else if (image->type == ImageTypeMetafile) - { - GpMetafile *metafile = (GpMetafile*)image; - heap_free(metafile->comment_data); - DeleteEnhMetaFile(CloseEnhMetaFile(metafile->record_dc)); - if (!metafile->preserve_hemf) - DeleteEnhMetaFile(metafile->hemf); - if (metafile->record_graphics) - { - WARN("metafile closed while recording\n"); - /* not sure what to do here; for now just prevent the graphics from functioning or using this object */ - metafile->record_graphics->image = NULL; - metafile->record_graphics->busy = TRUE; - } - if (metafile->record_stream) - { - IStream_Release(metafile->record_stream); - } - } + METAFILE_Free((GpMetafile *)image); else { WARN("invalid image: %p\n", image); @@ -4568,7 +4545,7 @@ static GpStatus encode_image_jpeg(GpImage *image, IStream* stream, static GpStatus encode_image_gif(GpImage *image, IStream* stream, GDIPCONST EncoderParameters* params) { - return encode_image_wic(image, stream, &GUID_ContainerFormatGif, params); + return encode_image_wic(image, stream, &CLSID_WICGifEncoder, params); } /***************************************************************************** @@ -4581,7 +4558,7 @@ GpStatus WINGDIPAPI GdipSaveImageToStream(GpImage *image, IStream* stream, encode_image_func encode_image; int i; - TRACE("%p %p %s %p\n", image, stream, wine_dbgstr_guid(clsid), params); + TRACE("%p %p %p %p\n", image, stream, clsid, params); if(!image || !stream) return InvalidParameter; @@ -5595,111 +5572,3 @@ GpStatus WINGDIPAPI GdipBitmapGetHistogramSize(HistogramFormat format, UINT *num *num_of_entries = 256; return Ok; } - -static GpStatus create_optimal_palette(ColorPalette *palette, INT desired, - BOOL transparent, GpBitmap *bitmap) -{ - GpStatus status; - BitmapData data; - HRESULT hr; - IWICImagingFactory *factory; - IWICPalette *wic_palette; - - if (!bitmap) return InvalidParameter; - if (palette->Count < desired) return GenericError; - - status = GdipBitmapLockBits(bitmap, NULL, ImageLockModeRead, PixelFormat24bppRGB, &data); - if (status != Ok) return status; - - hr = WICCreateImagingFactory_Proxy(WINCODEC_SDK_VERSION, &factory); - if (hr != S_OK) - { - GdipBitmapUnlockBits(bitmap, &data); - return hresult_to_status(hr); - } - - hr = IWICImagingFactory_CreatePalette(factory, &wic_palette); - if (hr == S_OK) - { - IWICBitmap *bitmap; - - /* PixelFormat24bppRGB actually stores the bitmap bits as BGR. */ - hr = IWICImagingFactory_CreateBitmapFromMemory(factory, data.Width, data.Height, - &GUID_WICPixelFormat24bppBGR, data.Stride, data.Stride * data.Width, data.Scan0, &bitmap); - if (hr == S_OK) - { - hr = IWICPalette_InitializeFromBitmap(wic_palette, (IWICBitmapSource *)bitmap, desired, transparent); - if (hr == S_OK) - { - palette->Flags = 0; - IWICPalette_GetColorCount(wic_palette, &palette->Count); - IWICPalette_GetColors(wic_palette, palette->Count, palette->Entries, &palette->Count); - } - - IWICBitmap_Release(bitmap); - } - - IWICPalette_Release(wic_palette); - } - - IWICImagingFactory_Release(factory); - GdipBitmapUnlockBits(bitmap, &data); - - return hresult_to_status(hr); -} - -/***************************************************************************** - * GdipInitializePalette [GDIPLUS.@] - */ -GpStatus WINGDIPAPI GdipInitializePalette(ColorPalette *palette, - PaletteType type, INT desired, BOOL transparent, GpBitmap *bitmap) -{ - TRACE("(%p,%d,%d,%d,%p)\n", palette, type, desired, transparent, bitmap); - - if (!palette) return InvalidParameter; - - switch (type) - { - case PaletteTypeCustom: - return Ok; - - case PaletteTypeOptimal: - return create_optimal_palette(palette, desired, transparent, bitmap); - - /* WIC palette type enumeration matches these gdiplus enums */ - case PaletteTypeFixedBW: - case PaletteTypeFixedHalftone8: - case PaletteTypeFixedHalftone27: - case PaletteTypeFixedHalftone64: - case PaletteTypeFixedHalftone125: - case PaletteTypeFixedHalftone216: - case PaletteTypeFixedHalftone252: - case PaletteTypeFixedHalftone256: - { - ColorPalette *wic_palette; - GpStatus status = Ok; - - wic_palette = get_palette(NULL, type); - if (!wic_palette) return OutOfMemory; - - if (palette->Count >= wic_palette->Count) - { - palette->Flags = wic_palette->Flags; - palette->Count = wic_palette->Count; - memcpy(palette->Entries, wic_palette->Entries, wic_palette->Count * sizeof(wic_palette->Entries[0])); - } - else - status = GenericError; - - heap_free(wic_palette); - - return status; - } - - default: - FIXME("unknown palette type %d\n", type); - break; - } - - return InvalidParameter; -} diff --git a/dll/win32/gdiplus/imageattributes.c b/dll/win32/gdiplus/imageattributes.c index 12941f7b9a..b30eba9444 100644 --- a/dll/win32/gdiplus/imageattributes.c +++ b/dll/win32/gdiplus/imageattributes.c @@ -209,14 +209,14 @@ GpStatus WINGDIPAPI GdipSetImageAttributesGamma(GpImageAttributes *imageAttr, GpStatus WINGDIPAPI GdipSetImageAttributesNoOp(GpImageAttributes *imageAttr, ColorAdjustType type, BOOL enableFlag) { - static int calls; - TRACE("(%p,%u,%i)\n", imageAttr, type, enableFlag); - if(!(calls++)) - FIXME("not implemented\n"); + if (type >= ColorAdjustTypeCount) + return InvalidParameter; - return NotImplemented; + imageAttr->noop[type] = enableFlag ? IMAGEATTR_NOOP_SET : IMAGEATTR_NOOP_CLEAR; + + return Ok; } GpStatus WINGDIPAPI GdipSetImageAttributesOutputChannel(GpImageAttributes *imageAttr, @@ -323,6 +323,7 @@ GpStatus WINGDIPAPI GdipResetImageAttributes(GpImageAttributes *imageAttr, GdipSetImageAttributesColorKeys(imageAttr, type, FALSE, 0, 0); GdipSetImageAttributesRemapTable(imageAttr, type, FALSE, 0, NULL); GdipSetImageAttributesGamma(imageAttr, type, FALSE, 0.0); + imageAttr->noop[type] = IMAGEATTR_NOOP_UNDEFINED; return Ok; } diff --git a/dll/win32/gdiplus/metafile.c b/dll/win32/gdiplus/metafile.c index 6171352d97..165a55dc8c 100644 --- a/dll/win32/gdiplus/metafile.c +++ b/dll/win32/gdiplus/metafile.c @@ -21,13 +21,9 @@ #include <assert.h> #include <ole2.h> -typedef struct EmfPlusARGB -{ - BYTE Blue; - BYTE Green; - BYTE Red; - BYTE Alpha; -} EmfPlusARGB; +HRESULT WINAPI WICCreateImagingFactory_Proxy(UINT, IWICImagingFactory**); + +typedef ARGB EmfPlusARGB; typedef struct EmfPlusRecordHeader { @@ -175,6 +171,30 @@ enum LineStyle LineStyleCustom }; +typedef struct EmfPlusDashedLineData +{ + DWORD DashedLineDataSize; + BYTE data[1]; +} EmfPlusDashedLineData; + +typedef struct EmfPlusCompoundLineData +{ + DWORD CompoundLineDataSize; + BYTE data[1]; +} EmfPlusCompoundLineData; + +typedef struct EmfPlusCustomStartCapData +{ + DWORD CustomStartCapSize; + BYTE data[1]; +} EmfPlusCustomStartCapData; + +typedef struct EmfPlusCustomEndCapData +{ + DWORD CustomEndCapSize; + BYTE data[1]; +} EmfPlusCustomEndCapData; + typedef struct EmfPlusPenData { DWORD PenDataFlags; @@ -183,17 +203,66 @@ typedef struct EmfPlusPenData BYTE OptionalData[1]; } EmfPlusPenData; +enum BrushDataFlags +{ + BrushDataPath = 1 << 0, + BrushDataTransform = 1 << 1, + BrushDataPresetColors = 1 << 2, + BrushDataBlendFactorsH = 1 << 3, + BrushDataBlendFactorsV = 1 << 4, + BrushDataFocusScales = 1 << 6, + BrushDataIsGammaCorrected = 1 << 7, + BrushDataDoNotTransform = 1 << 8, +}; + typedef struct EmfPlusSolidBrushData { EmfPlusARGB SolidColor; } EmfPlusSolidBrushData; +typedef struct EmfPlusHatchBrushData +{ + DWORD HatchStyle; + EmfPlusARGB ForeColor; + EmfPlusARGB BackColor; +} EmfPlusHatchBrushData; + +typedef struct EmfPlusTextureBrushData +{ + DWORD BrushDataFlags; + INT WrapMode; + BYTE OptionalData[1]; +} EmfPlusTextureBrushData; + +typedef struct EmfPlusRectF +{ + float X; + float Y; + float Width; + float Height; +} EmfPlusRectF; + +typedef struct EmfPlusLinearGradientBrushData +{ + DWORD BrushDataFlags; + INT WrapMode; + EmfPlusRectF RectF; + EmfPlusARGB StartColor; + EmfPlusARGB EndColor; + DWORD Reserved1; + DWORD Reserved2; + BYTE OptionalData[1]; +} EmfPlusLinearGradientBrushData; + typedef struct EmfPlusBrush { DWORD Version; DWORD Type; union { EmfPlusSolidBrushData solid; + EmfPlusHatchBrushData hatch; + EmfPlusTextureBrushData texture; + EmfPlusLinearGradientBrushData lineargradient; } BrushData; } EmfPlusBrush; @@ -217,6 +286,12 @@ typedef struct EmfPlusPath BYTE data[1]; } EmfPlusPath; +typedef struct EmfPlusRegionNodePath +{ + DWORD RegionNodePathLength; + EmfPlusPath RegionNodePath; +} EmfPlusRegionNodePath; + typedef struct EmfPlusRegion { DWORD Version; @@ -224,6 +299,13 @@ typedef struct EmfPlusRegion BYTE RegionNode[1]; } EmfPlusRegion; +typedef struct EmfPlusPalette +{ + DWORD PaletteStyleFlags; + DWORD PaletteCount; + BYTE PaletteEntries[1]; +} EmfPlusPalette; + typedef enum { BitmapDataTypePixel, @@ -275,20 +357,6 @@ typedef struct EmfPlusImageAttributes DWORD Reserved2; } EmfPlusImageAttributes; -typedef enum ObjectType -{ - ObjectTypeInvalid, - ObjectTypeBrush, - ObjectTypePen, - ObjectTypePath, - ObjectTypeRegion, - ObjectTypeImage, - ObjectTypeFont, - ObjectTypeStringFormat, - ObjectTypeImageAttributes, - ObjectTypeCustomLineCap, -} ObjectType; - typedef struct EmfPlusObject { EmfPlusRecordHeader Header; @@ -303,13 +371,17 @@ typedef struct EmfPlusObject } ObjectData; } EmfPlusObject; -typedef struct EmfPlusRectF +typedef struct EmfPlusPointR7 { - float X; - float Y; - float Width; - float Height; -} EmfPlusRectF; + BYTE X; + BYTE Y; +} EmfPlusPointR7; + +typedef struct EmfPlusPoint +{ + short X; + short Y; +} EmfPlusPoint; typedef struct EmfPlusPointF { @@ -317,6 +389,19 @@ typedef struct EmfPlusPointF float Y; } EmfPlusPointF; +typedef struct EmfPlusDrawImage +{ + EmfPlusRecordHeader Header; + DWORD ImageAttributesID; + DWORD SrcUnit; + EmfPlusRectF SrcRect; + union + { + EmfPlusRect rect; + EmfPlusRectF rectF; + } RectData; +} EmfPlusDrawImage; + typedef struct EmfPlusDrawImagePoints { EmfPlusRecordHeader Header; @@ -326,10 +411,10 @@ typedef struct EmfPlusDrawImagePoints DWORD count; union { - /*EmfPlusPointR pointR; - EmfPlusPoint point;*/ - EmfPlusPointF pointF; - } PointData[3]; + EmfPlusPointR7 pointsR[3]; + EmfPlusPoint points[3]; + EmfPlusPointF pointsF[3]; + } PointData; } EmfPlusDrawImagePoints; typedef struct EmfPlusDrawPath @@ -338,6 +423,51 @@ typedef struct EmfPlusDrawPath DWORD PenId; } EmfPlusDrawPath; +typedef struct EmfPlusDrawArc +{ + EmfPlusRecordHeader Header; + float StartAngle; + float SweepAngle; + union + { + EmfPlusRect rect; + EmfPlusRectF rectF; + } RectData; +} EmfPlusDrawArc; + +typedef struct EmfPlusDrawEllipse +{ + EmfPlusRecordHeader Header; + union + { + EmfPlusRect rect; + EmfPlusRectF rectF; + } RectData; +} EmfPlusDrawEllipse; + +typedef struct EmfPlusDrawPie +{ + EmfPlusRecordHeader Header; + float StartAngle; + float SweepAngle; + union + { + EmfPlusRect rect; + EmfPlusRectF rectF; + } RectData; +} EmfPlusDrawPie; + +typedef struct EmfPlusDrawRects +{ + EmfPlusRecordHeader Header; + DWORD Count; + union + { + EmfPlusRect rect[1]; + EmfPlusRectF rectF[1]; + } RectData; +} EmfPlusDrawRects; + typedef struct EmfPlusFillPath { EmfPlusRecordHeader Header; @@ -348,9 +478,119 @@ typedef struct EmfPlusFillPath } data; } EmfPlusFillPath; +typedef struct EmfPlusFillClosedCurve +{ + EmfPlusRecordHeader Header; + DWORD BrushId; + float Tension; + DWORD Count; + union + { + EmfPlusPointR7 pointsR[1]; + EmfPlusPoint points[1]; + EmfPlusPointF pointsF[1]; + } PointData; +} EmfPlusFillClosedCurve; + +typedef struct EmfPlusFillEllipse +{ + EmfPlusRecordHeader Header; + DWORD BrushId; + union + { + EmfPlusRect rect; + EmfPlusRectF rectF; + } RectData; +} EmfPlusFillEllipse; + +typedef struct EmfPlusFillPie +{ + EmfPlusRecordHeader Header; + DWORD BrushId; + float StartAngle; + float SweepAngle; + union + { + EmfPlusRect rect; + EmfPlusRectF rectF; + } RectData; +} EmfPlusFillPie; + +typedef struct EmfPlusFont +{ + DWORD Version; + float EmSize; + DWORD SizeUnit; + DWORD FontStyleFlags; + DWORD Reserved; + DWORD Length; + WCHAR FamilyName[1]; +} EmfPlusFont; + +static void metafile_free_object_table_entry(GpMetafile *metafile, BYTE id) +{ + struct emfplus_object *object = &metafile->objtable[id]; + + switch (object->type) + { + case ObjectTypeInvalid: + break; + case ObjectTypeBrush: + GdipDeleteBrush(object->u.brush); + break; + case ObjectTypePen: + GdipDeletePen(object->u.pen); + break; + case ObjectTypePath: + GdipDeletePath(object->u.path); + break; + case ObjectTypeRegion: + GdipDeleteRegion(object->u.region); + break; + case ObjectTypeImage: + GdipDisposeImage(object->u.image); + break; + case ObjectTypeFont: + GdipDeleteFont(object->u.font); + break; + case ObjectTypeImageAttributes: + GdipDisposeImageAttributes(object->u.image_attributes); + break; + default: + FIXME("not implemented for object type %u.\n", object->type); + return; + } + + object->type = ObjectTypeInvalid; + object->u.object = NULL; +} + +void METAFILE_Free(GpMetafile *metafile) +{ + unsigned int i; + + heap_free(metafile->comment_data); + DeleteEnhMetaFile(CloseEnhMetaFile(metafile->record_dc)); + if (!metafile->preserve_hemf) + DeleteEnhMetaFile(metafile->hemf); + if (metafile->record_graphics) + { + WARN("metafile closed while recording\n"); + /* not sure what to do here; for now just prevent the graphics from functioning or using this object */ + metafile->record_graphics->image = NULL; + metafile->record_graphics->busy = TRUE; + } + + if (metafile->record_stream) + IStream_Release(metafile->record_stream); + + for (i = 0; i < sizeof(metafile->objtable)/sizeof(metafile->objtable[0]); i++) + metafile_free_object_table_entry(metafile, i); +} + static DWORD METAFILE_AddObjectId(GpMetafile *metafile) { - return (metafile->next_object_id++) % 64; + return (metafile->next_object_id++) % EmfPlusObjectTableSize; } static GpStatus METAFILE_AllocateRecord(GpMetafile *metafile, DWORD size, void **result) @@ -718,6 +958,74 @@ static BOOL is_integer_rect(const GpRectF *rect) return TRUE; } +static GpStatus METAFILE_PrepareBrushData(GpBrush *brush, DWORD *size) +{ + switch (brush->bt) + { + case BrushTypeSolidColor: + *size = FIELD_OFFSET(EmfPlusBrush, BrushData) + sizeof(EmfPlusSolidBrushData); + break; + case BrushTypeHatchFill: + *size = FIELD_OFFSET(EmfPlusBrush, BrushData) + sizeof(EmfPlusHatchBrushData); + break; + default: + FIXME("unsupported brush type: %d\n", brush->bt); + return NotImplemented; + } + + return Ok; +} + +static void METAFILE_FillBrushData(GpBrush *brush, EmfPlusBrush *data) +{ + data->Version = VERSION_MAGIC2; + data->Type = brush->bt; + + switch (brush->bt) + { + case BrushTypeSolidColor: + { + GpSolidFill *solid = (GpSolidFill *)brush; + data->BrushData.solid.SolidColor = solid->color; + break; + } + case BrushTypeHatchFill: + { + GpHatch *hatch = (GpHatch *)brush; + data->BrushData.hatch.HatchStyle = hatch->hatchstyle; + data->BrushData.hatch.ForeColor = hatch->forecol; + data->BrushData.hatch.BackColor = hatch->backcol; + break; + } + default: + FIXME("unsupported brush type: %d\n", brush->bt); + } +} + +static GpStatus METAFILE_AddBrushObject(GpMetafile *metafile, GpBrush *brush, DWORD *id) +{ + EmfPlusObject *object_record; + GpStatus stat; + DWORD size; + + *id = -1; + if (metafile->metafile_type != MetafileTypeEmfPlusOnly && metafile->metafile_type != MetafileTypeEmfPlusDual) + return Ok; + + stat = METAFILE_PrepareBrushData(brush, &size); + if (stat != Ok) return stat; + + stat = METAFILE_AllocateRecord(metafile, + FIELD_OFFSET(EmfPlusObject, ObjectData) + size, (void**)&object_record); + if (stat != Ok) return stat; + + *id = METAFILE_AddObjectId(metafile); + object_record->Header.Type = EmfPlusRecordTypeObject; + object_record->Header.Flags = *id | ObjectTypeBrush << 8; + METAFILE_FillBrushData(brush, &object_record->ObjectData.brush); + return Ok; +} + GpStatus METAFILE_FillRectangles(GpMetafile* metafile, GpBrush* brush, GDIPCONST GpRectF* rects, INT count) { @@ -737,8 +1045,9 @@ GpStatus METAFILE_FillRectangles(GpMetafile* metafile, GpBrush* brush, } else { - FIXME("brush serialization not implemented\n"); - return NotImplemented; + stat = METAFILE_AddBrushObject(metafile, brush, &brushid); + if (stat != Ok) + return stat; } for (i=0; i<count; i++) @@ -1385,99 +1694,841 @@ static GpStatus METAFILE_PlaybackUpdateWorldTransform(GpMetafile *metafile) return stat; } -GpStatus WINGDIPAPI GdipPlayMetafileRecord(GDIPCONST GpMetafile *metafile, - EmfPlusRecordType recordType, UINT flags, UINT dataSize, GDIPCONST BYTE *data) +static void metafile_set_object_table_entry(GpMetafile *metafile, BYTE id, BYTE type, void *object) { - GpStatus stat; - GpMetafile *real_metafile = (GpMetafile*)metafile; + metafile_free_object_table_entry(metafile, id); + metafile->objtable[id].type = type; + metafile->objtable[id].u.object = object; +} - TRACE("(%p,%x,%x,%d,%p)\n", metafile, recordType, flags, dataSize, data); +static GpStatus metafile_deserialize_image(const BYTE *record_data, UINT data_size, GpImage **image) +{ + EmfPlusImage *data = (EmfPlusImage *)record_data; + GpStatus status; - if (!metafile || (dataSize && !data) || !metafile->playback_graphics) + *image = NULL; + + if (data_size < FIELD_OFFSET(EmfPlusImage, ImageData)) return InvalidParameter; + data_size -= FIELD_OFFSET(EmfPlusImage, ImageData); - if (recordType >= 1 && recordType <= 0x7a) + switch (data->Type) { - /* regular EMF record */ - if (metafile->playback_dc) - { - switch (recordType) - { - case EMR_SETMAPMODE: - case EMR_SAVEDC: - case EMR_RESTOREDC: - case EMR_SETWINDOWORGEX: - case EMR_SETWINDOWEXTEX: - case EMR_SETVIEWPORTORGEX: - case EMR_SETVIEWPORTEXTEX: - case EMR_SCALEVIEWPORTEXTEX: - case EMR_SCALEWINDOWEXTEX: - case EMR_MODIFYWORLDTRANSFORM: - FIXME("not implemented for record type %x\n", recordType); - break; - case EMR_SETWORLDTRANSFORM: - { - const XFORM* xform = (void*)data; - real_metafile->gdiworldtransform = *xform; - METAFILE_PlaybackUpdateGdiTransform(real_metafile); - break; - } - case EMR_EXTSELECTCLIPRGN: - { - DWORD rgndatasize = *(DWORD*)data; - DWORD mode = *(DWORD*)(data + 4); - const RGNDATA *rgndata = (const RGNDATA*)(data + 8); - HRGN hrgn = NULL; + case ImageDataTypeBitmap: + { + EmfPlusBitmap *bitmapdata = &data->ImageData.bitmap; - if (dataSize > 8) - { - XFORM final; + if (data_size <= FIELD_OFFSET(EmfPlusBitmap, BitmapData)) + return InvalidParameter; + data_size -= FIELD_OFFSET(EmfPlusBitmap, BitmapData); - METAFILE_GetFinalGdiTransform(metafile, &final); + switch (bitmapdata->Type) + { + case BitmapDataTypePixel: + { + ColorPalette *palette; + BYTE *scan0; - hrgn = ExtCreateRegion(&final, rgndatasize, rgndata); - } + if (bitmapdata->PixelFormat & PixelFormatIndexed) + { + EmfPlusPalette *palette_obj = (EmfPlusPalette *)bitmapdata->BitmapData; + UINT palette_size = FIELD_OFFSET(EmfPlusPalette, PaletteEntries); - ExtSelectClipRgn(metafile->playback_dc, hrgn, mode); + if (data_size <= palette_size) + return InvalidParameter; + palette_size += palette_obj->PaletteCount * sizeof(EmfPlusARGB); - DeleteObject(hrgn); + if (data_size < palette_size) + return InvalidParameter; + data_size -= palette_size; - return Ok; + palette = (ColorPalette *)bitmapdata->BitmapData; + scan0 = (BYTE *)bitmapdata->BitmapData + palette_size; } - default: + else { - ENHMETARECORD *record = heap_alloc_zero(dataSize + 8); - - if (record) - { - record->iType = recordType; - record->nSize = dataSize + 8; - memcpy(record->dParm, data, dataSize); + palette = NULL; + scan0 = bitmapdata->BitmapData; + } - if(PlayEnhMetaFileRecord(metafile->playback_dc, metafile->handle_table, - record, metafile->handle_count) == 0) - ERR("PlayEnhMetaFileRecord failed\n"); + if (data_size < bitmapdata->Height * bitmapdata->Stride) + return InvalidParameter; - heap_free(record); + status = GdipCreateBitmapFromScan0(bitmapdata->Width, bitmapdata->Height, bitmapdata->Stride, + bitmapdata->PixelFormat, scan0, (GpBitmap **)image); + if (status == Ok && palette) + { + status = GdipSetImagePalette(*image, palette); + if (status != Ok) + { + GdipDisposeImage(*image); + *image = NULL; } - else - return OutOfMemory; - - break; - } } + break; } - } - else - { - EmfPlusRecordHeader *header = (EmfPlusRecordHeader*)(data)-1; + case BitmapDataTypeCompressed: + { + IWICImagingFactory *factory; + IWICStream *stream; + HRESULT hr; - METAFILE_PlaybackReleaseDC((GpMetafile*)metafile); + if (WICCreateImagingFactory_Proxy(WINCODEC_SDK_VERSION, &factory) != S_OK) + return GenericError; - switch(recordType) - { - case EmfPlusRecordTypeHeader: - case EmfPlusRecordTypeEndOfFile: + hr = IWICImagingFactory_CreateStream(factory, &stream); + IWICImagingFactory_Release(factory); + if (hr != S_OK) + return GenericError; + + if (IWICStream_InitializeFromMemory(stream, bitmapdata->BitmapData, data_size) == S_OK) + status = GdipCreateBitmapFromStream((IStream *)stream, (GpBitmap **)image); + else + status = GenericError; + + IWICStream_Release(stream); + break; + } + default: + WARN("Invalid bitmap type %d.\n", bitmapdata->Type); + return InvalidParameter; + } + break; + } + default: + FIXME("image type %d not supported.\n", data->Type); + return NotImplemented; + } + + return status; +} + +static GpStatus metafile_deserialize_path(const BYTE *record_data, UINT data_size, GpPath **path) +{ + EmfPlusPath *data = (EmfPlusPath *)record_data; + GpStatus status; + BYTE *types; + UINT size; + DWORD i; + + *path = NULL; + + if (data_size <= FIELD_OFFSET(EmfPlusPath, data)) + return InvalidParameter; + data_size -= FIELD_OFFSET(EmfPlusPath, data); + + if (data->PathPointFlags & 0x800) /* R */ + { + FIXME("RLE encoded path data is not supported.\n"); + return NotImplemented; + } + else + { + if (data->PathPointFlags & 0x4000) /* C */ + size = sizeof(EmfPlusPoint); + else + size = sizeof(EmfPlusPointF); + size += sizeof(BYTE); /* EmfPlusPathPointType */ + size *= data->PathPointCount; + } + + if (data_size < size) + return InvalidParameter; + + status = GdipCreatePath(FillModeAlternate, path); + if (status != Ok) + return status; + + (*path)->pathdata.Count = data->PathPointCount; + (*path)->pathdata.Points = GdipAlloc(data->PathPointCount * sizeof(*(*path)->pathdata.Points)); + (*path)->pathdata.Types = GdipAlloc(data->PathPointCount * sizeof(*(*path)->pathdata.Types)); + (*path)->datalen = (*path)->pathdata.Count; + + if (!(*path)->pathdata.Points || !(*path)->pathdata.Types) + { + GdipDeletePath(*path); + return OutOfMemory; + } + + if (data->PathPointFlags & 0x4000) /* C */ + { + EmfPlusPoint *points = (EmfPlusPoint *)data->data; + for (i = 0; i < data->PathPointCount; i++) + { + (*path)->pathdata.Points[i].X = points[i].X; + (*path)->pathdata.Points[i].Y = points[i].Y; + } + types = (BYTE *)(points + i); + } + else + { + EmfPlusPointF *points = (EmfPlusPointF *)data->data; + memcpy((*path)->pathdata.Points, points, sizeof(*points) * data->PathPointCount); + types = (BYTE *)(points + data->PathPointCount); + } + + memcpy((*path)->pathdata.Types, types, sizeof(*types) * data->PathPointCount); + + return Ok; +} + +static GpStatus metafile_read_region_node(struct memory_buffer *mbuf, GpRegion *region, region_element *node, UINT *count) +{ + const DWORD *type; + GpStatus status; + + type = buffer_read(mbuf, sizeof(*type)); + if (!type) return Ok; + + node->type = *type; + + switch (node->type) + { + case CombineModeReplace: + case CombineModeIntersect: + case CombineModeUnion: + case CombineModeXor: + case CombineModeExclude: + case CombineModeComplement: + { + region_element *left, *right; + + left = heap_alloc_zero(sizeof(*left)); + if (!left) + return OutOfMemory; + + right = heap_alloc_zero(sizeof(*right)); + if (!right) + { + heap_free(left); + return OutOfMemory; + } + + status = metafile_read_region_node(mbuf, region, left, count); + if (status == Ok) + { + status = metafile_read_region_node(mbuf, region, right, count); + if (status == Ok) + { + node->elementdata.combine.left = left; + node->elementdata.combine.right = right; + region->num_children += 2; + return Ok; + } + } + + heap_free(left); + heap_free(right); + return status; + } + case RegionDataRect: + { + const EmfPlusRectF *rect; + + rect = buffer_read(mbuf, sizeof(*rect)); + if (!rect) + return InvalidParameter; + + memcpy(&node->elementdata.rect, rect, sizeof(*rect)); + *count += 1; + return Ok; + } + case RegionDataPath: + { + const BYTE *path_data; + const UINT *data_size; + GpPath *path; + + data_size = buffer_read(mbuf, FIELD_OFFSET(EmfPlusRegionNodePath, RegionNodePath)); + if (!data_size) + return InvalidParameter; + + path_data = buffer_read(mbuf, *data_size); + if (!path_data) + return InvalidParameter; + + status = metafile_deserialize_path(path_data, *data_size, &path); + if (status == Ok) + { + node->elementdata.path = path; + *count += 1; + } + return Ok; + } + case RegionDataEmptyRect: + case RegionDataInfiniteRect: + *count += 1; + return Ok; + default: + FIXME("element type %#x is not supported\n", *type); + break; + } + + return InvalidParameter; +} + +static GpStatus metafile_deserialize_region(const BYTE *record_data, UINT data_size, GpRegion **region) +{ + struct memory_buffer mbuf; + GpStatus status; + UINT count; + + *region = NULL; + + init_memory_buffer(&mbuf, record_data, data_size); + + if (!buffer_read(&mbuf, FIELD_OFFSET(EmfPlusRegion, RegionNode))) + return InvalidParameter; + + status = GdipCreateRegion(region); + if (status != Ok) + return status; + + count = 0; + status = metafile_read_region_node(&mbuf, *region, &(*region)->node, &count); + if (status == Ok && !count) + status = InvalidParameter; + + if (status != Ok) + { + GdipDeleteRegion(*region); + *region = NULL; + } + + return status; +} + +static GpStatus metafile_deserialize_brush(const BYTE *record_data, UINT data_size, GpBrush **brush) +{ + static const UINT header_size = FIELD_OFFSET(EmfPlusBrush, BrushData); + EmfPlusBrush *data = (EmfPlusBrush *)record_data; + EmfPlusTransformMatrix *transform = NULL; + DWORD brushflags; + GpStatus status; + UINT offset; + + *brush = NULL; + + if (data_size < header_size) + return InvalidParameter; + + switch (data->Type) + { + case BrushTypeSolidColor: + if (data_size != header_size + sizeof(EmfPlusSolidBrushData)) + return InvalidParameter; + + status = GdipCreateSolidFill(data->BrushData.solid.SolidColor, (GpSolidFill **)brush); + break; + case BrushTypeHatchFill: + if (data_size != header_size + sizeof(EmfPlusHatchBrushData)) + return InvalidParameter; + + status = GdipCreateHatchBrush(data->BrushData.hatch.HatchStyle, data->BrushData.hatch.ForeColor, + data->BrushData.hatch.BackColor, (GpHatch **)brush); + break; + case BrushTypeTextureFill: + { + GpImage *image; + + offset = header_size + FIELD_OFFSET(EmfPlusTextureBrushData, OptionalData); + if (data_size <= offset) + return InvalidParameter; + + brushflags = data->BrushData.texture.BrushDataFlags; + if (brushflags & BrushDataTransform) + { + if (data_size <= offset + sizeof(EmfPlusTransformMatrix)) + return InvalidParameter; + transform = (EmfPlusTransformMatrix *)(record_data + offset); + offset += sizeof(EmfPlusTransformMatrix); + } + + status = metafile_deserialize_image(record_data + offset, data_size - offset, &image); + if (status != Ok) + return status; + + status = GdipCreateTexture(image, data->BrushData.texture.WrapMode, (GpTexture **)brush); + if (status == Ok && transform && !(brushflags & BrushDataDoNotTransform)) + GdipSetTextureTransform((GpTexture *)*brush, (const GpMatrix *)transform); + + GdipDisposeImage(image); + break; + } + case BrushTypeLinearGradient: + { + GpLineGradient *gradient = NULL; + GpPointF startpoint, endpoint; + UINT position_count = 0; + + offset = header_size + FIELD_OFFSET(EmfPlusLinearGradientBrushData, OptionalData); + if (data_size <= offset) + return InvalidParameter; + + brushflags = data->BrushData.lineargradient.BrushDataFlags; + if ((brushflags & BrushDataPresetColors) && (brushflags & (BrushDataBlendFactorsH | BrushDataBlendFactorsV))) + return InvalidParameter; + + if (brushflags & BrushDataTransform) + { + if (data_size <= offset + sizeof(EmfPlusTransformMatrix)) + return InvalidParameter; + transform = (EmfPlusTransformMatrix *)(record_data + offset); + offset += sizeof(EmfPlusTransformMatrix); + } + + if (brushflags & (BrushDataPresetColors | BrushDataBlendFactorsH | BrushDataBlendFactorsV)) + { + if (data_size <= offset + sizeof(DWORD)) /* Number of factors/preset colors. */ + return InvalidParameter; + position_count = *(DWORD *)(record_data + offset); + offset += sizeof(DWORD); + } + + if (brushflags & BrushDataPresetColors) + { + if (data_size != offset + position_count * (sizeof(float) + sizeof(EmfPlusARGB))) + return InvalidParameter; + } + else if (brushflags & BrushDataBlendFactorsH) + { + if (data_size != offset + position_count * 2 * sizeof(float)) + return InvalidParameter; + } + + startpoint.X = data->BrushData.lineargradient.RectF.X; + startpoint.Y = data->BrushData.lineargradient.RectF.Y; + endpoint.X = startpoint.X + data->BrushData.lineargradient.RectF.Width; + endpoint.Y = startpoint.Y + data->BrushData.lineargradient.RectF.Height; + + status = GdipCreateLineBrush(&startpoint, &endpoint, data->BrushData.lineargradient.StartColor, + data->BrushData.lineargradient.EndColor, data->BrushData.lineargradient.WrapMode, &gradient); + if (status == Ok) + { + if (transform) + status = GdipSetLineTransform(gradient, (const GpMatrix *)transform); + + if (status == Ok) + { + if (brushflags & BrushDataPresetColors) + status = GdipSetLinePresetBlend(gradient, (ARGB *)(record_data + offset + + position_count * sizeof(REAL)), (REAL *)(record_data + offset), position_count); + else if (brushflags & BrushDataBlendFactorsH) + status = GdipSetLineBlend(gradient, (REAL *)(record_data + offset + position_count * sizeof(REAL)), + (REAL *)(record_data + offset), position_count); + + if (brushflags & BrushDataIsGammaCorrected) + FIXME("BrushDataIsGammaCorrected is not handled.\n"); + } + } + + if (status == Ok) + *brush = (GpBrush *)gradient; + else + GdipDeleteBrush((GpBrush *)gradient); + + break; + } + default: + FIXME("brush type %u is not supported.\n", data->Type); + return NotImplemented; + } + + return status; +} + +static GpStatus metafile_get_pen_brush_data_offset(EmfPlusPen *data, UINT data_size, DWORD *ret) +{ + EmfPlusPenData *pendata = (EmfPlusPenData *)data->data; + DWORD offset = FIELD_OFFSET(EmfPlusPen, data); + + if (data_size <= offset) + return InvalidParameter; + + offset += FIELD_OFFSET(EmfPlusPenData, OptionalData); + if (data_size <= offset) + return InvalidParameter; + + if (pendata->PenDataFlags & PenDataTransform) + offset += sizeof(EmfPlusTransformMatrix); + + if (pendata->PenDataFlags & PenDataStartCap) + offset += sizeof(DWORD); + + if (pendata->PenDataFlags & PenDataEndCap) + offset += sizeof(DWORD); + + if (pendata->PenDataFlags & PenDataJoin) + offset += sizeof(DWORD); + + if (pendata->PenDataFlags & PenDataMiterLimit) + offset += sizeof(REAL); + + if (pendata->PenDataFlags & PenDataLineStyle) + offset += sizeof(DWORD); + + if (pendata->PenDataFlags & PenDataDashedLineCap) + offset += sizeof(DWORD); + + if (pendata->PenDataFlags & PenDataDashedLineOffset) + offset += sizeof(REAL); + + if (pendata->PenDataFlags & PenDataDashedLine) + { + EmfPlusDashedLineData *dashedline = (EmfPlusDashedLineData *)((BYTE *)data + offset); + + offset += FIELD_OFFSET(EmfPlusDashedLineData, data); + if (data_size <= offset) + return InvalidParameter; + + offset += dashedline->DashedLineDataSize * sizeof(float); + } + + if (pendata->PenDataFlags & PenDataNonCenter) + offset += sizeof(DWORD); + + if (pendata->PenDataFlags & PenDataCompoundLine) + { + EmfPlusCompoundLineData *compoundline = (EmfPlusCompoundLineData *)((BYTE *)data + offset); + + offset += FIELD_OFFSET(EmfPlusCompoundLineData, data); + if (data_size <= offset) + return InvalidParameter; + + offset += compoundline->CompoundLineDataSize * sizeof(float); + } + + if (pendata->PenDataFlags & PenDataCustomStartCap) + { + EmfPlusCustomStartCapData *startcap = (EmfPlusCustomStartCapData *)((BYTE *)data + offset); + + offset += FIELD_OFFSET(EmfPlusCustomStartCapData, data); + if (data_size <= offset) + return InvalidParameter; + + offset += startcap->CustomStartCapSize; + } + + if (pendata->PenDataFlags & PenDataCustomEndCap) + { + EmfPlusCustomEndCapData *endcap = (EmfPlusCustomEndCapData *)((BYTE *)data + offset); + + offset += FIELD_OFFSET(EmfPlusCustomEndCapData, data); + if (data_size <= offset) + return InvalidParameter; + + offset += endcap->CustomEndCapSize; + } + + *ret = offset; + return Ok; +} + +static GpStatus METAFILE_PlaybackObject(GpMetafile *metafile, UINT flags, UINT data_size, const BYTE *record_data) +{ + BYTE type = (flags >> 8) & 0xff; + BYTE id = flags & 0xff; + void *object = NULL; + GpStatus status; + + if (type > ObjectTypeMax || id >= EmfPlusObjectTableSize) + return InvalidParameter; + + switch (type) + { + case ObjectTypeBrush: + status = metafile_deserialize_brush(record_data, data_size, (GpBrush **)&object); + break; + case ObjectTypePen: + { + EmfPlusPen *data = (EmfPlusPen *)record_data; + EmfPlusPenData *pendata = (EmfPlusPenData *)data->data; + GpBrush *brush; + DWORD offset; + GpPen *pen; + + status = metafile_get_pen_brush_data_offset(data, data_size, &offset); + if (status != Ok) + return status; + + status = metafile_deserialize_brush(record_data + offset, data_size - offset, &brush); + if (status != Ok) + return status; + + status = GdipCreatePen2(brush, pendata->PenWidth, pendata->PenUnit, &pen); + GdipDeleteBrush(brush); + if (status != Ok) + return status; + + offset = FIELD_OFFSET(EmfPlusPenData, OptionalData); + + if (pendata->PenDataFlags & PenDataTransform) + { + FIXME("PenDataTransform is not supported.\n"); + offset += sizeof(EmfPlusTransformMatrix); + } + + if (pendata->PenDataFlags & PenDataStartCap) + { + if ((status = GdipSetPenStartCap(pen, *(DWORD *)((BYTE *)pendata + offset))) != Ok) + goto penfailed; + offset += sizeof(DWORD); + } + + if (pendata->PenDataFlags & PenDataEndCap) + { + if ((status = GdipSetPenEndCap(pen, *(DWORD *)((BYTE *)pendata + offset))) != Ok) + goto penfailed; + offset += sizeof(DWORD); + } + + if (pendata->PenDataFlags & PenDataJoin) + { + if ((status = GdipSetPenLineJoin(pen, *(DWORD *)((BYTE *)pendata + offset))) != Ok) + goto penfailed; + offset += sizeof(DWORD); + } + + if (pendata->PenDataFlags & PenDataMiterLimit) + { + if ((status = GdipSetPenMiterLimit(pen, *(REAL *)((BYTE *)pendata + offset))) != Ok) + goto penfailed; + offset += sizeof(REAL); + } + + if (pendata->PenDataFlags & PenDataLineStyle) + { + if ((status = GdipSetPenDashStyle(pen, *(DWORD *)((BYTE *)pendata + offset))) != Ok) + goto penfailed; + offset += sizeof(DWORD); + } + + if (pendata->PenDataFlags & PenDataDashedLineCap) + { + FIXME("PenDataDashedLineCap is not supported.\n"); + offset += sizeof(DWORD); + } + + if (pendata->PenDataFlags & PenDataDashedLineOffset) + { + if ((status = GdipSetPenDashOffset(pen, *(REAL *)((BYTE *)pendata + offset))) != Ok) + goto penfailed; + offset += sizeof(REAL); + } + + if (pendata->PenDataFlags & PenDataDashedLine) + { + EmfPlusDashedLineData *dashedline = (EmfPlusDashedLineData *)((BYTE *)pendata + offset); + FIXME("PenDataDashedLine is not supported.\n"); + offset += FIELD_OFFSET(EmfPlusDashedLineData, data) + dashedline->DashedLineDataSize * sizeof(float); + } + + if (pendata->PenDataFlags & PenDataNonCenter) + { + FIXME("PenDataNonCenter is not supported.\n"); + offset += sizeof(DWORD); + } + + if (pendata->PenDataFlags & PenDataCompoundLine) + { + EmfPlusCompoundLineData *compoundline = (EmfPlusCompoundLineData *)((BYTE *)pendata + offset); + FIXME("PenDataCompundLine is not supported.\n"); + offset += FIELD_OFFSET(EmfPlusCompoundLineData, data) + compoundline->CompoundLineDataSize * sizeof(float); + } + + if (pendata->PenDataFlags & PenDataCustomStartCap) + { + EmfPlusCustomStartCapData *startcap = (EmfPlusCustomStartCapData *)((BYTE *)pendata + offset); + FIXME("PenDataCustomStartCap is not supported.\n"); + offset += FIELD_OFFSET(EmfPlusCustomStartCapData, data) + startcap->CustomStartCapSize; + } + + if (pendata->PenDataFlags & PenDataCustomEndCap) + { + EmfPlusCustomEndCapData *endcap = (EmfPlusCustomEndCapData *)((BYTE *)pendata + offset); + FIXME("PenDataCustomEndCap is not supported.\n"); + offset += FIELD_OFFSET(EmfPlusCustomEndCapData, data) + endcap->CustomEndCapSize; + } + + object = pen; + break; + + penfailed: + GdipDeletePen(pen); + return status; + } + case ObjectTypePath: + status = metafile_deserialize_path(record_data, data_size, (GpPath **)&object); + break; + case ObjectTypeRegion: + status = metafile_deserialize_region(record_data, data_size, (GpRegion **)&object); + break; + case ObjectTypeImage: + status = metafile_deserialize_image(record_data, data_size, (GpImage **)&object); + break; + case ObjectTypeFont: + { + EmfPlusFont *data = (EmfPlusFont *)record_data; + GpFontFamily *family; + WCHAR *familyname; + + if (data_size <= FIELD_OFFSET(EmfPlusFont, FamilyName)) + return InvalidParameter; + data_size -= FIELD_OFFSET(EmfPlusFont, FamilyName); + + if (data_size < data->Length * sizeof(WCHAR)) + return InvalidParameter; + + if (!(familyname = GdipAlloc((data->Length + 1) * sizeof(*familyname)))) + return OutOfMemory; + + memcpy(familyname, data->FamilyName, data->Length * sizeof(*familyname)); + familyname[data->Length] = 0; + + status = GdipCreateFontFamilyFromName(familyname, NULL, &family); + GdipFree(familyname); + if (status != Ok) + return InvalidParameter; + + status = GdipCreateFont(family, data->EmSize, data->FontStyleFlags, data->SizeUnit, (GpFont **)&object); + GdipDeleteFontFamily(family); + break; + } + case ObjectTypeImageAttributes: + { + EmfPlusImageAttributes *data = (EmfPlusImageAttributes *)record_data; + GpImageAttributes *attributes = NULL; + + if (data_size != sizeof(*data)) + return InvalidParameter; + + if ((status = GdipCreateImageAttributes(&attributes)) != Ok) + return status; + + status = GdipSetImageAttributesWrapMode(attributes, data->WrapMode, *(DWORD *)&data->ClampColor, + !!data->ObjectClamp); + if (status == Ok) + object = attributes; + else + GdipDisposeImageAttributes(attributes); + break; + } + default: + FIXME("not implemented for object type %d.\n", type); + return NotImplemented; + } + + if (status == Ok) + metafile_set_object_table_entry(metafile, id, type, object); + + return status; +} + +static GpStatus metafile_set_clip_region(GpMetafile *metafile, GpRegion *region, CombineMode mode) +{ + GpMatrix world_to_device; + + get_graphics_transform(metafile->playback_graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, &world_to_device); + + GdipTransformRegion(region, &world_to_device); + GdipCombineRegionRegion(metafile->clip, region, mode); + + return METAFILE_PlaybackUpdateClip(metafile); +} + +GpStatus WINGDIPAPI GdipPlayMetafileRecord(GDIPCONST GpMetafile *metafile, + EmfPlusRecordType recordType, UINT flags, UINT dataSize, GDIPCONST BYTE *data) +{ + GpStatus stat; + GpMetafile *real_metafile = (GpMetafile*)metafile; + + TRACE("(%p,%x,%x,%d,%p)\n", metafile, recordType, flags, dataSize, data); + + if (!metafile || (dataSize && !data) || !metafile->playback_graphics) + return InvalidParameter; + + if (recordType >= 1 && recordType <= 0x7a) + { + /* regular EMF record */ + if (metafile->playback_dc) + { + switch (recordType) + { + case EMR_SETMAPMODE: + case EMR_SAVEDC: + case EMR_RESTOREDC: + case EMR_SETWINDOWORGEX: + case EMR_SETWINDOWEXTEX: + case EMR_SETVIEWPORTORGEX: + case EMR_SETVIEWPORTEXTEX: + case EMR_SCALEVIEWPORTEXTEX: + case EMR_SCALEWINDOWEXTEX: + case EMR_MODIFYWORLDTRANSFORM: + FIXME("not implemented for record type %x\n", recordType); + break; + case EMR_SETWORLDTRANSFORM: + { + const XFORM* xform = (void*)data; + real_metafile->gdiworldtransform = *xform; + METAFILE_PlaybackUpdateGdiTransform(real_metafile); + break; + } + case EMR_EXTSELECTCLIPRGN: + { + DWORD rgndatasize = *(DWORD*)data; + DWORD mode = *(DWORD*)(data + 4); + const RGNDATA *rgndata = (const RGNDATA*)(data + 8); + HRGN hrgn = NULL; + + if (dataSize > 8) + { + XFORM final; + + METAFILE_GetFinalGdiTransform(metafile, &final); + + hrgn = ExtCreateRegion(&final, rgndatasize, rgndata); + } + + ExtSelectClipRgn(metafile->playback_dc, hrgn, mode); + + DeleteObject(hrgn); + + return Ok; + } + default: + { + ENHMETARECORD *record = heap_alloc_zero(dataSize + 8); + + if (record) + { + record->iType = recordType; + record->nSize = dataSize + 8; + memcpy(record->dParm, data, dataSize); + + if(PlayEnhMetaFileRecord(metafile->playback_dc, metafile->handle_table, + record, metafile->handle_count) == 0) + ERR("PlayEnhMetaFileRecord failed\n"); + + heap_free(record); + } + else + return OutOfMemory; + + break; + } + } + } + } + else + { + EmfPlusRecordHeader *header = (EmfPlusRecordHeader*)(data)-1; + + METAFILE_PlaybackReleaseDC((GpMetafile*)metafile); + + switch(recordType) + { + case EmfPlusRecordTypeHeader: + case EmfPlusRecordTypeEndOfFile: break; case EmfPlusRecordTypeGetDC: METAFILE_PlaybackGetDC((GpMetafile*)metafile); @@ -1486,6 +2537,9 @@ GpStatus WINGDIPAPI GdipPlayMetafileRecord(GDIPCONST GpMetafile *metafile, { EmfPlusClear *record = (EmfPlusClear*)header; + if (dataSize != sizeof(record->Color)) + return InvalidParameter; + return GdipGraphicsClear(metafile->playback_graphics, record->Color); } case EmfPlusRecordTypeFillRects: @@ -1510,13 +2564,17 @@ GpStatus WINGDIPAPI GdipPlayMetafileRecord(GDIPCONST GpMetafile *metafile, if (flags & 0x8000) { - stat = GdipCreateSolidFill((ARGB)record->BrushID, (GpSolidFill**)&temp_brush); + stat = GdipCreateSolidFill(record->BrushID, (GpSolidFill **)&temp_brush); brush = temp_brush; } else { - FIXME("brush deserialization not implemented\n"); - return NotImplemented; + if (record->BrushID >= EmfPlusObjectTableSize || + real_metafile->objtable[record->BrushID].type != ObjectTypeBrush) + return InvalidParameter; + + brush = real_metafile->objtable[record->BrushID].u.brush; + stat = Ok; } if (stat == Ok) @@ -1546,39 +2604,74 @@ GpStatus WINGDIPAPI GdipPlayMetafileRecord(GDIPCONST GpMetafile *metafile, if (stat == Ok) { - stat = GdipFillRectangles(metafile->playback_graphics, brush, rects, record->Count); + stat = GdipFillRectangles(metafile->playback_graphics, brush, rects, record->Count); + } + + GdipDeleteBrush(temp_brush); + heap_free(temp_rects); + + return stat; + } + case EmfPlusRecordTypeSetClipRect: + { + EmfPlusSetClipRect *record = (EmfPlusSetClipRect*)header; + CombineMode mode = (CombineMode)((flags >> 8) & 0xf); + GpRegion *region; + + if (dataSize + sizeof(EmfPlusRecordHeader) < sizeof(*record)) + return InvalidParameter; + + stat = GdipCreateRegionRect(&record->ClipRect, ®ion); + + if (stat == Ok) + { + stat = metafile_set_clip_region(real_metafile, region, mode); + GdipDeleteRegion(region); + } + + return stat; + } + case EmfPlusRecordTypeSetClipRegion: + { + CombineMode mode = (flags >> 8) & 0xf; + BYTE regionid = flags & 0xff; + GpRegion *region; + + if (dataSize != 0) + return InvalidParameter; + + if (regionid >= EmfPlusObjectTableSize || real_metafile->objtable[regionid].type != ObjectTypeRegion) + return InvalidParameter; + + stat = GdipCloneRegion(real_metafile->objtable[regionid].u.region, ®ion); + if (stat == Ok) + { + stat = metafile_set_clip_region(real_metafile, region, mode); + GdipDeleteRegion(region); } - GdipDeleteBrush(temp_brush); - heap_free(temp_rects); - return stat; } - case EmfPlusRecordTypeSetClipRect: + case EmfPlusRecordTypeSetClipPath: { - EmfPlusSetClipRect *record = (EmfPlusSetClipRect*)header; - CombineMode mode = (CombineMode)((flags >> 8) & 0xf); + CombineMode mode = (flags >> 8) & 0xf; + BYTE pathid = flags & 0xff; GpRegion *region; - GpMatrix world_to_device; - if (dataSize + sizeof(EmfPlusRecordHeader) < sizeof(*record)) + if (dataSize != 0) return InvalidParameter; - stat = GdipCreateRegionRect(&record->ClipRect, ®ion); + if (pathid >= EmfPlusObjectTableSize || real_metafile->objtable[pathid].type != ObjectTypePath) + return InvalidParameter; + stat = GdipCreateRegionPath(real_metafile->objtable[pathid].u.path, ®ion); if (stat == Ok) { - get_graphics_transform(real_metafile->playback_graphics, - CoordinateSpaceDevice, CoordinateSpaceWorld, &world_to_device); - - GdipTransformRegion(region, &world_to_device); - - GdipCombineRegionRegion(real_metafile->clip, region, mode); - + stat = metafile_set_clip_region(real_metafile, region, mode); GdipDeleteRegion(region); } - return METAFILE_PlaybackUpdateClip(real_metafile); + return stat; } case EmfPlusRecordTypeSetPageTransform: { @@ -1810,6 +2903,447 @@ GpStatus WINGDIPAPI GdipPlayMetafileRecord(GDIPCONST GpMetafile *metafile, break; } + case EmfPlusRecordTypeSetPixelOffsetMode: + { + return GdipSetPixelOffsetMode(real_metafile->playback_graphics, flags & 0xff); + } + case EmfPlusRecordTypeSetCompositingQuality: + { + return GdipSetCompositingQuality(real_metafile->playback_graphics, flags & 0xff); + } + case EmfPlusRecordTypeSetInterpolationMode: + { + return GdipSetInterpolationMode(real_metafile->playback_graphics, flags & 0xff); + } + case EmfPlusRecordTypeSetTextRenderingHint: + { + return GdipSetTextRenderingHint(real_metafile->playback_graphics, flags & 0xff); + } + case EmfPlusRecordTypeSetAntiAliasMode: + { + return GdipSetSmoothingMode(real_metafile->playback_graphics, (flags >> 1) & 0xff); + } + case EmfPlusRecordTypeSetCompositingMode: + { + return GdipSetCompositingMode(real_metafile->playback_graphics, flags & 0xff); + } + case EmfPlusRecordTypeObject: + { + return METAFILE_PlaybackObject(real_metafile, flags, dataSize, data); + } + case EmfPlusRecordTypeDrawImage: + { + EmfPlusDrawImage *draw = (EmfPlusDrawImage *)header; + BYTE image = flags & 0xff; + GpPointF points[3]; + + if (image >= EmfPlusObjectTableSize || real_metafile->objtable[image].type != ObjectTypeImage) + return InvalidParameter; + + if (dataSize != FIELD_OFFSET(EmfPlusDrawImage, RectData) - sizeof(EmfPlusRecordHeader) + + (flags & 0x4000 ? sizeof(EmfPlusRect) : sizeof(EmfPlusRectF))) + return InvalidParameter; + + if (draw->ImageAttributesID >= EmfPlusObjectTableSize || + real_metafile->objtable[draw->ImageAttributesID].type != ObjectTypeImageAttributes) + return InvalidParameter; + + if (flags & 0x4000) /* C */ + { + points[0].X = draw->RectData.rect.X; + points[0].Y = draw->RectData.rect.Y; + points[1].X = points[0].X + draw->RectData.rect.Width; + points[1].Y = points[0].Y; + points[2].X = points[1].X; + points[2].Y = points[1].Y + draw->RectData.rect.Height; + } + else + { + points[0].X = draw->RectData.rectF.X; + points[0].Y = draw->RectData.rectF.Y; + points[1].X = points[0].X + draw->RectData.rectF.Width; + points[1].Y = points[0].Y; + points[2].X = points[1].X; + points[2].Y = points[1].Y + draw->RectData.rectF.Height; + } + + return GdipDrawImagePointsRect(real_metafile->playback_graphics, real_metafile->objtable[image].u.image, + points, 3, draw->SrcRect.X, draw->SrcRect.Y, draw->SrcRect.Width, draw->SrcRect.Height, draw->SrcUnit, + real_metafile->objtable[draw->ImageAttributesID].u.image_attributes, NULL, NULL); + } + case EmfPlusRecordTypeDrawImagePoints: + { + EmfPlusDrawImagePoints *draw = (EmfPlusDrawImagePoints *)header; + static const UINT fixed_part_size = FIELD_OFFSET(EmfPlusDrawImagePoints, PointData) - + FIELD_OFFSET(EmfPlusDrawImagePoints, ImageAttributesID); + BYTE image = flags & 0xff; + GpPointF points[3]; + unsigned int i; + UINT size; + + if (image >= EmfPlusObjectTableSize || real_metafile->objtable[image].type != ObjectTypeImage) + return InvalidParameter; + + if (dataSize <= fixed_part_size) + return InvalidParameter; + dataSize -= fixed_part_size; + + if (draw->ImageAttributesID >= EmfPlusObjectTableSize || + real_metafile->objtable[draw->ImageAttributesID].type != ObjectTypeImageAttributes) + return InvalidParameter; + + if (draw->count != 3) + return InvalidParameter; + + if ((flags >> 13) & 1) /* E */ + FIXME("image effects are not supported.\n"); + + if ((flags >> 11) & 1) /* P */ + size = sizeof(EmfPlusPointR7) * draw->count; + else if ((flags >> 14) & 1) /* C */ + size = sizeof(EmfPlusPoint) * draw->count; + else + size = sizeof(EmfPlusPointF) * draw->count; + + if (dataSize != size) + return InvalidParameter; + + if ((flags >> 11) & 1) /* P */ + { + points[0].X = draw->PointData.pointsR[0].X; + points[0].Y = draw->PointData.pointsR[0].Y; + for (i = 1; i < 3; i++) + { + points[i].X = points[i-1].X + draw->PointData.pointsR[i].X; + points[i].Y = points[i-1].Y + draw->PointData.pointsR[i].Y; + } + } + else if ((flags >> 14) & 1) /* C */ + { + for (i = 0; i < 3; i++) + { + points[i].X = draw->PointData.points[i].X; + points[i].Y = draw->PointData.points[i].Y; + } + } + else + memcpy(points, draw->PointData.pointsF, sizeof(points)); + + return GdipDrawImagePointsRect(real_metafile->playback_graphics, real_metafile->objtable[image].u.image, + points, 3, draw->SrcRect.X, draw->SrcRect.Y, draw->SrcRect.Width, draw->SrcRect.Height, draw->SrcUnit, + real_metafile->objtable[draw->ImageAttributesID].u.image_attributes, NULL, NULL); + } + case EmfPlusRecordTypeFillPath: + { + EmfPlusFillPath *fill = (EmfPlusFillPath *)header; + GpSolidFill *solidfill = NULL; + BYTE path = flags & 0xff; + GpBrush *brush; + + if (path >= EmfPlusObjectTableSize || real_metafile->objtable[path].type != ObjectTypePath) + return InvalidParameter; + + if (dataSize != sizeof(fill->data.BrushId)) + return InvalidParameter; + + if (flags & 0x8000) + { + stat = GdipCreateSolidFill(fill->data.Color, (GpSolidFill **)&solidfill); + if (stat != Ok) + return stat; + brush = (GpBrush *)solidfill; + } + else + { + if (fill->data.BrushId >= EmfPlusObjectTableSize || + real_metafile->objtable[fill->data.BrushId].type != ObjectTypeBrush) + return InvalidParameter; + + brush = real_metafile->objtable[fill->data.BrushId].u.brush; + } + + stat = GdipFillPath(real_metafile->playback_graphics, brush, real_metafile->objtable[path].u.path); + GdipDeleteBrush((GpBrush *)solidfill); + return stat; + } + case EmfPlusRecordTypeFillClosedCurve: + { + static const UINT fixed_part_size = FIELD_OFFSET(EmfPlusFillClosedCurve, PointData) - + sizeof(EmfPlusRecordHeader); + EmfPlusFillClosedCurve *fill = (EmfPlusFillClosedCurve *)header; + GpSolidFill *solidfill = NULL; + GpFillMode mode; + GpBrush *brush; + UINT size, i; + + if (dataSize <= fixed_part_size) + return InvalidParameter; + + if (fill->Count == 0) + return InvalidParameter; + + if (flags & 0x800) /* P */ + size = (fixed_part_size + sizeof(EmfPlusPointR7) * fill->Count + 3) & ~3; + else if (flags & 0x4000) /* C */ + size = fixed_part_size + sizeof(EmfPlusPoint) * fill->Count; + else + size = fixed_part_size + sizeof(EmfPlusPointF) * fill->Count; + + if (dataSize != size) + return InvalidParameter; + + mode = flags & 0x200 ? FillModeWinding : FillModeAlternate; /* W */ + + if (flags & 0x8000) /* S */ + { + stat = GdipCreateSolidFill(fill->BrushId, (GpSolidFill **)&solidfill); + if (stat != Ok) + return stat; + brush = (GpBrush *)solidfill; + } + else + { + if (fill->BrushId >= EmfPlusObjectTableSize || + real_metafile->objtable[fill->BrushId].type != ObjectTypeBrush) + return InvalidParameter; + + brush = real_metafile->objtable[fill->BrushId].u.brush; + } + + if (flags & (0x800 | 0x4000)) + { + GpPointF *points = GdipAlloc(fill->Count * sizeof(*points)); + if (points) + { + if (flags & 0x800) /* P */ + { + for (i = 1; i < fill->Count; i++) + { + points[i].X = points[i - 1].X + fill->PointData.pointsR[i].X; + points[i].Y = points[i - 1].Y + fill->PointData.pointsR[i].Y; + } + } + else + { + for (i = 0; i < fill->Count; i++) + { + points[i].X = fill->PointData.points[i].X; + points[i].Y = fill->PointData.points[i].Y; + } + } + + stat = GdipFillClosedCurve2(real_metafile->playback_graphics, brush, + points, fill->Count, fill->Tension, mode); + GdipFree(points); + } + else + stat = OutOfMemory; + } + else + stat = GdipFillClosedCurve2(real_metafile->playback_graphics, brush, + (const GpPointF *)fill->PointData.pointsF, fill->Count, fill->Tension, mode); + + GdipDeleteBrush((GpBrush *)solidfill); + return stat; + } + case EmfPlusRecordTypeFillEllipse: + { + EmfPlusFillEllipse *fill = (EmfPlusFillEllipse *)header; + GpSolidFill *solidfill = NULL; + GpBrush *brush; + + if (dataSize <= FIELD_OFFSET(EmfPlusFillEllipse, RectData) - sizeof(EmfPlusRecordHeader)) + return InvalidParameter; + dataSize -= FIELD_OFFSET(EmfPlusFillEllipse, RectData) - sizeof(EmfPlusRecordHeader); + + if (dataSize != (flags & 0x4000 ? sizeof(EmfPlusRect) : sizeof(EmfPlusRectF))) + return InvalidParameter; + + if (flags & 0x8000) + { + stat = GdipCreateSolidFill(fill->BrushId, (GpSolidFill **)&solidfill); + if (stat != Ok) + return stat; + brush = (GpBrush *)solidfill; + } + else + { + if (fill->BrushId >= EmfPlusObjectTableSize || + real_metafile->objtable[fill->BrushId].type != ObjectTypeBrush) + return InvalidParameter; + + brush = real_metafile->objtable[fill->BrushId].u.brush; + } + + if (flags & 0x4000) + stat = GdipFillEllipseI(real_metafile->playback_graphics, brush, fill->RectData.rect.X, + fill->RectData.rect.Y, fill->RectData.rect.Width, fill->RectData.rect.Height); + else + stat = GdipFillEllipse(real_metafile->playback_graphics, brush, fill->RectData.rectF.X, + fill->RectData.rectF.Y, fill->RectData.rectF.Width, fill->RectData.rectF.Height); + + GdipDeleteBrush((GpBrush *)solidfill); + return stat; + } + case EmfPlusRecordTypeFillPie: + { + EmfPlusFillPie *fill = (EmfPlusFillPie *)header; + GpSolidFill *solidfill = NULL; + GpBrush *brush; + + if (dataSize <= FIELD_OFFSET(EmfPlusFillPie, RectData) - sizeof(EmfPlusRecordHeader)) + return InvalidParameter; + dataSize -= FIELD_OFFSET(EmfPlusFillPie, RectData) - sizeof(EmfPlusRecordHeader); + + if (dataSize != (flags & 0x4000 ? sizeof(EmfPlusRect) : sizeof(EmfPlusRectF))) + return InvalidParameter; + + if (flags & 0x8000) /* S */ + { + stat = GdipCreateSolidFill(fill->BrushId, (GpSolidFill **)&solidfill); + if (stat != Ok) + return stat; + brush = (GpBrush *)solidfill; + } + else + { + if (fill->BrushId >= EmfPlusObjectTableSize || + real_metafile->objtable[fill->BrushId].type != ObjectTypeBrush) + return InvalidParameter; + + brush = real_metafile->objtable[fill->BrushId].u.brush; + } + + if (flags & 0x4000) /* C */ + stat = GdipFillPieI(real_metafile->playback_graphics, brush, fill->RectData.rect.X, + fill->RectData.rect.Y, fill->RectData.rect.Width, fill->RectData.rect.Height, + fill->StartAngle, fill->SweepAngle); + else + stat = GdipFillPie(real_metafile->playback_graphics, brush, fill->RectData.rectF.X, + fill->RectData.rectF.Y, fill->RectData.rectF.Width, fill->RectData.rectF.Height, + fill->StartAngle, fill->SweepAngle); + + GdipDeleteBrush((GpBrush *)solidfill); + return stat; + } + case EmfPlusRecordTypeDrawPath: + { + EmfPlusDrawPath *draw = (EmfPlusDrawPath *)header; + BYTE path = flags & 0xff; + + if (dataSize != sizeof(draw->PenId)) + return InvalidParameter; + + if (path >= EmfPlusObjectTableSize || draw->PenId >= EmfPlusObjectTableSize) + return InvalidParameter; + + if (real_metafile->objtable[path].type != ObjectTypePath || + real_metafile->objtable[draw->PenId].type != ObjectTypePen) + return InvalidParameter; + + return GdipDrawPath(real_metafile->playback_graphics, real_metafile->objtable[draw->PenId].u.pen, + real_metafile->objtable[path].u.path); + } + case EmfPlusRecordTypeDrawArc: + { + EmfPlusDrawArc *draw = (EmfPlusDrawArc *)header; + BYTE pen = flags & 0xff; + + if (pen >= EmfPlusObjectTableSize || real_metafile->objtable[pen].type != ObjectTypePen) + return InvalidParameter; + + if (dataSize != FIELD_OFFSET(EmfPlusDrawArc, RectData) - sizeof(EmfPlusRecordHeader) + + (flags & 0x4000 ? sizeof(EmfPlusRect) : sizeof(EmfPlusRectF))) + return InvalidParameter; + + if (flags & 0x4000) /* C */ + return GdipDrawArcI(real_metafile->playback_graphics, real_metafile->objtable[pen].u.pen, + draw->RectData.rect.X, draw->RectData.rect.Y, draw->RectData.rect.Width, + draw->RectData.rect.Height, draw->StartAngle, draw->SweepAngle); + else + return GdipDrawArc(real_metafile->playback_graphics, real_metafile->objtable[pen].u.pen, + draw->RectData.rectF.X, draw->RectData.rectF.Y, draw->RectData.rectF.Width, + draw->RectData.rectF.Height, draw->StartAngle, draw->SweepAngle); + } + case EmfPlusRecordTypeDrawEllipse: + { + EmfPlusDrawEllipse *draw = (EmfPlusDrawEllipse *)header; + BYTE pen = flags & 0xff; + + if (pen >= EmfPlusObjectTableSize || real_metafile->objtable[pen].type != ObjectTypePen) + return InvalidParameter; + + if (dataSize != (flags & 0x4000 ? sizeof(EmfPlusRect) : sizeof(EmfPlusRectF))) + return InvalidParameter; + + if (flags & 0x4000) /* C */ + return GdipDrawEllipseI(real_metafile->playback_graphics, real_metafile->objtable[pen].u.pen, + draw->RectData.rect.X, draw->RectData.rect.Y, draw->RectData.rect.Width, + draw->RectData.rect.Height); + else + return GdipDrawEllipse(real_metafile->playback_graphics, real_metafile->objtable[pen].u.pen, + draw->RectData.rectF.X, draw->RectData.rectF.Y, draw->RectData.rectF.Width, + draw->RectData.rectF.Height); + } + case EmfPlusRecordTypeDrawPie: + { + EmfPlusDrawPie *draw = (EmfPlusDrawPie *)header; + BYTE pen = flags & 0xff; + + if (pen >= EmfPlusObjectTableSize || real_metafile->objtable[pen].type != ObjectTypePen) + return InvalidParameter; + + if (dataSize != FIELD_OFFSET(EmfPlusDrawPie, RectData) - sizeof(EmfPlusRecordHeader) + + (flags & 0x4000 ? sizeof(EmfPlusRect) : sizeof(EmfPlusRectF))) + return InvalidParameter; + + if (flags & 0x4000) /* C */ + return GdipDrawPieI(real_metafile->playback_graphics, real_metafile->objtable[pen].u.pen, + draw->RectData.rect.X, draw->RectData.rect.Y, draw->RectData.rect.Width, + draw->RectData.rect.Height, draw->StartAngle, draw->SweepAngle); + else + return GdipDrawPie(real_metafile->playback_graphics, real_metafile->objtable[pen].u.pen, + draw->RectData.rectF.X, draw->RectData.rectF.Y, draw->RectData.rectF.Width, + draw->RectData.rectF.Height, draw->StartAngle, draw->SweepAngle); + } + case EmfPlusRecordTypeDrawRects: + { + EmfPlusDrawRects *draw = (EmfPlusDrawRects *)header; + BYTE pen = flags & 0xff; + GpRectF *rects = NULL; + + if (pen >= EmfPlusObjectTableSize || real_metafile->objtable[pen].type != ObjectTypePen) + return InvalidParameter; + + if (dataSize <= FIELD_OFFSET(EmfPlusDrawRects, RectData) - sizeof(EmfPlusRecordHeader)) + return InvalidParameter; + dataSize -= FIELD_OFFSET(EmfPlusDrawRects, RectData) - sizeof(EmfPlusRecordHeader); + + if (dataSize != draw->Count * (flags & 0x4000 ? sizeof(EmfPlusRect) : sizeof(EmfPlusRectF))) + return InvalidParameter; + + if (flags & 0x4000) + { + DWORD i; + + rects = GdipAlloc(draw->Count * sizeof(*rects)); + if (!rects) + return OutOfMemory; + + for (i = 0; i < draw->Count; i++) + { + rects[i].X = draw->RectData.rect[i].X; + rects[i].Y = draw->RectData.rect[i].Y; + rects[i].Width = draw->RectData.rect[i].Width; + rects[i].Height = draw->RectData.rect[i].Height; + } + } + + stat = GdipDrawRectangles(real_metafile->playback_graphics, real_metafile->objtable[pen].u.pen, + rects ? rects : (GpRectF *)draw->RectData.rectF, draw->Count); + GdipFree(rects); + return stat; + } default: FIXME("Not implemented for record type %x\n", recordType); return NotImplemented; @@ -2625,10 +4159,7 @@ static GpStatus METAFILE_AddImageAttributesObject(GpMetafile *metafile, const Gp attrs_record->Version = VERSION_MAGIC2; attrs_record->Reserved1 = 0; attrs_record->WrapMode = attrs->wrap; - attrs_record->ClampColor.Blue = attrs->outside_color & 0xff; - attrs_record->ClampColor.Green = (attrs->outside_color >> 8) & 0xff; - attrs_record->ClampColor.Red = (attrs->outside_color >> 16) & 0xff; - attrs_record->ClampColor.Alpha = attrs->outside_color >> 24; + attrs_record->ClampColor = attrs->outside_color; attrs_record->ObjectClamp = attrs->clamp; attrs_record->Reserved2 = 0; return Ok; @@ -2708,12 +4239,7 @@ GpStatus METAFILE_DrawImagePointsRect(GpMetafile *metafile, GpImage *image, draw_image_record->SrcRect.Width = units_to_pixels(srcwidth, srcUnit, metafile->image.xres); draw_image_record->SrcRect.Height = units_to_pixels(srcheight, srcUnit, metafile->image.yres); draw_image_record->count = 3; - draw_image_record->PointData[0].pointF.X = points[0].X; - draw_image_record->PointData[0].pointF.Y = points[0].Y; - draw_image_record->PointData[1].pointF.X = points[1].X; - draw_image_record->PointData[1].pointF.Y = points[1].Y; - draw_image_record->PointData[2].pointF.X = points[2].X; - draw_image_record->PointData[2].pointF.Y = points[2].Y; + memcpy(draw_image_record->PointData.pointsF, points, 3 * sizeof(*points)); METAFILE_WriteRecords(metafile); return Ok; } @@ -2759,33 +4285,6 @@ static GpStatus METAFILE_AddPathObject(GpMetafile *metafile, GpPath *path, DWORD return Ok; } -static GpStatus METAFILE_PrepareBrushData(GpBrush *brush, DWORD *size) -{ - if (brush->bt == BrushTypeSolidColor) - { - *size = FIELD_OFFSET(EmfPlusBrush, BrushData.solid) + sizeof(EmfPlusSolidBrushData); - return Ok; - } - - FIXME("unsupported brush type: %d\n", brush->bt); - return NotImplemented; -} - -static void METAFILE_FillBrushData(GpBrush *brush, EmfPlusBrush *data) -{ - if (brush->bt == BrushTypeSolidColor) - { - GpSolidFill *solid = (GpSolidFill*)brush; - - data->Version = VERSION_MAGIC2; - data->Type = solid->brush.bt; - data->BrushData.solid.SolidColor.Blue = solid->color & 0xff; - data->BrushData.solid.SolidColor.Green = (solid->color >> 8) & 0xff; - data->BrushData.solid.SolidColor.Red = (solid->color >> 16) & 0xff; - data->BrushData.solid.SolidColor.Alpha = solid->color >> 24; - } -} - static GpStatus METAFILE_AddPenObject(GpMetafile *metafile, GpPen *pen, DWORD *id) { DWORD i, data_flags, pen_data_size, brush_size; @@ -2981,30 +4480,6 @@ GpStatus METAFILE_DrawPath(GpMetafile *metafile, GpPen *pen, GpPath *path) return Ok; } -static GpStatus METAFILE_AddBrushObject(GpMetafile *metafile, GpBrush *brush, DWORD *id) -{ - EmfPlusObject *object_record; - GpStatus stat; - DWORD size; - - *id = -1; - if (metafile->metafile_type != MetafileTypeEmfPlusOnly && metafile->metafile_type != MetafileTypeEmfPlusDual) - return Ok; - - stat = METAFILE_PrepareBrushData(brush, &size); - if (stat != Ok) return stat; - - stat = METAFILE_AllocateRecord(metafile, - FIELD_OFFSET(EmfPlusObject, ObjectData) + size, (void**)&object_record); - if (stat != Ok) return stat; - - *id = METAFILE_AddObjectId(metafile); - object_record->Header.Type = EmfPlusRecordTypeObject; - object_record->Header.Flags = *id | ObjectTypeBrush << 8; - METAFILE_FillBrushData(brush, &object_record->ObjectData.brush); - return Ok; -} - GpStatus METAFILE_FillPath(GpMetafile *metafile, GpBrush *brush, GpPath *path) { EmfPlusFillPath *fill_path_record; @@ -3035,10 +4510,7 @@ GpStatus METAFILE_FillPath(GpMetafile *metafile, GpBrush *brush, GpPath *path) if (inline_color) { fill_path_record->Header.Flags = 0x8000 | path_id; - fill_path_record->data.Color.Blue = ((GpSolidFill*)brush)->color & 0xff; - fill_path_record->data.Color.Green = (((GpSolidFill*)brush)->color >> 8) & 0xff; - fill_path_record->data.Color.Red = (((GpSolidFill*)brush)->color >> 16) & 0xff; - fill_path_record->data.Color.Alpha = ((GpSolidFill*)brush)->color >> 24; + fill_path_record->data.Color = ((GpSolidFill *)brush)->color; } else { diff --git a/dll/win32/gdiplus/region.c b/dll/win32/gdiplus/region.c index b5fa5bcd92..c40882c7ad 100644 --- a/dll/win32/gdiplus/region.c +++ b/dll/win32/gdiplus/region.c @@ -64,12 +64,6 @@ #define FLAGS_INTPATH 0x4000 -struct memory_buffer -{ - const BYTE *buffer; - INT size, pos; -}; - struct region_header { DWORD magic; @@ -766,24 +760,6 @@ GpStatus WINGDIPAPI GdipGetRegionData(GpRegion *region, BYTE *buffer, UINT size, return Ok; } -static inline void init_memory_buffer(struct memory_buffer *mbuf, const BYTE *buffer, INT size) -{ - mbuf->buffer = buffer; - mbuf->size = size; - mbuf->pos = 0; -} - -static inline const void *buffer_read(struct memory_buffer *mbuf, INT size) -{ - if (mbuf->size - mbuf->pos >= size) - { - const void *data = mbuf->buffer + mbuf->pos; - mbuf->pos += size; - return data; - } - return NULL; -} - static GpStatus read_element(struct memory_buffer *mbuf, GpRegion *region, region_element *node, INT *count) { GpStatus status; diff --git a/media/doc/README.WINE b/media/doc/README.WINE index 8b15f8045b..4cc97bd42a 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -68,7 +68,7 @@ reactos/dll/win32/dciman32 # Synced to WineStaging-2.9 reactos/dll/win32/faultrep # Synced to WineStaging-2.9 reactos/dll/win32/fontsub # Synced to WineStaging-2.9 reactos/dll/win32/fusion # Synced to Wine-3.0 -reactos/dll/win32/gdiplus # Synced to WineStaging-2.16 +reactos/dll/win32/gdiplus # Synced to Wine-3.0 reactos/dll/win32/hhctrl.ocx # Synced to WineStaging-2.9 reactos/dll/win32/hlink # Synced to WineStaging-2.9 reactos/dll/win32/hnetcfg # Synced to WineStaging-2.9
6 years, 11 months
1
0
0
0
01/01: [PSDK] Update gdiplusflat.h and gdiplusgpstubs.h. CORE-14225
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=7a00f240c6cfe6d4dc53f…
commit 7a00f240c6cfe6d4dc53f04fa1345bbb76364e51 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Fri Jan 19 00:15:20 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Fri Jan 19 00:15:20 2018 +0100 [PSDK] Update gdiplusflat.h and gdiplusgpstubs.h. CORE-14225 --- sdk/include/psdk/gdiplusflat.h | 4 ++-- sdk/include/psdk/gdiplusgpstubs.h | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/sdk/include/psdk/gdiplusflat.h b/sdk/include/psdk/gdiplusflat.h index 64a3a62e32..54d3ea94b5 100644 --- a/sdk/include/psdk/gdiplusflat.h +++ b/sdk/include/psdk/gdiplusflat.h @@ -388,10 +388,10 @@ GpStatus WINGDIPAPI GdipWarpPath(GpPath*,GpMatrix*,GDIPCONST GpPointF*,INT,REAL, GpStatus WINGDIPAPI GdipWidenPath(GpPath*,GpPen*,GpMatrix*,REAL); /* HatchBrush */ -GpStatus WINGDIPAPI GdipCreateHatchBrush(HatchStyle,ARGB,ARGB,GpHatch**); +GpStatus WINGDIPAPI GdipCreateHatchBrush(GpHatchStyle,ARGB,ARGB,GpHatch**); GpStatus WINGDIPAPI GdipGetHatchBackgroundColor(GpHatch*,ARGB*); GpStatus WINGDIPAPI GdipGetHatchForegroundColor(GpHatch*,ARGB*); -GpStatus WINGDIPAPI GdipGetHatchStyle(GpHatch*,HatchStyle*); +GpStatus WINGDIPAPI GdipGetHatchStyle(GpHatch*,GpHatchStyle*); /* Image */ GpStatus WINGDIPAPI GdipCloneImage(GpImage*, GpImage**); diff --git a/sdk/include/psdk/gdiplusgpstubs.h b/sdk/include/psdk/gdiplusgpstubs.h index 5a65cd83e9..67b6ac1e34 100644 --- a/sdk/include/psdk/gdiplusgpstubs.h +++ b/sdk/include/psdk/gdiplusgpstubs.h @@ -95,5 +95,6 @@ typedef FlushIntention GpFlushIntention; typedef CoordinateSpace GpCoordinateSpace; typedef PenAlignment GpPenAlignment; typedef PenType GpPenType; +typedef HatchStyle GpHatchStyle; #endif
6 years, 11 months
1
0
0
0
01/01: [FUSION_WINETEST] Sync with Wine 3.0. CORE-14225
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9e28af37922d8c02098cc…
commit 9e28af37922d8c02098cc5dc20c132bb7721da92 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Fri Jan 19 00:11:52 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Fri Jan 19 00:11:52 2018 +0100 [FUSION_WINETEST] Sync with Wine 3.0. CORE-14225 --- modules/rostests/winetests/fusion/asmname.c | 61 ++++++++++++++++++++++++----- 1 file changed, 51 insertions(+), 10 deletions(-) diff --git a/modules/rostests/winetests/fusion/asmname.c b/modules/rostests/winetests/fusion/asmname.c index ee4fbc4901..1558f500de 100644 --- a/modules/rostests/winetests/fusion/asmname.c +++ b/modules/rostests/winetests/fusion/asmname.c @@ -33,6 +33,7 @@ //#include <mscoree.h> #include <fusion.h> #include <corerror.h> +#include <strsafe.h> #include <wine/test.h> @@ -314,7 +315,7 @@ static const ASMPROP_RES enname[ASM_NAME_MAX_PARAMS] = static const ASMPROP_RES pubkeyname[ASM_NAME_MAX_PARAMS] = { {S_OK, "", 0}, - {S_OK, "\x12\x34\x56\x78\x90\xab\xcd\xef", 8}, + {S_OK, "\x01\x23\x45\x67\x89\x0a\xbc\xde", 8}, {S_OK, "", 0}, {S_OK, "wine", 10}, {S_OK, "", 0}, @@ -348,11 +349,6 @@ static inline void to_widechar(LPWSTR dest, LPCSTR src) MultiByteToWideChar(CP_ACP, 0, src, -1, dest, MAX_PATH); } -static inline void to_multibyte(LPSTR dest, LPWSTR src) -{ - WideCharToMultiByte(CP_ACP, 0, src, -1, dest, MAX_PATH, NULL, NULL); -} - static void test_assembly_name_props_line(IAssemblyName *name, const ASMPROP_RES *vals, int line) { @@ -376,7 +372,11 @@ static void test_assembly_name_props_line(IAssemblyName *name, if (hr != E_INVALIDARG) { ok(size == vals[i].size, "%d: prop %d: Expected %d, got %d\n", line, i, vals[i].size, size); - if (size && size != MAX_PATH) + if (!size) + { + ok(str[0] == 0xcccc, "%d: prop %d: str[0] = %x\n", line, i, str[0]); + } + else if (size != MAX_PATH) { if (i != ASM_NAME_NAME && i != ASM_NAME_CULTURE) ok( !memcmp( vals[i].val, str, size ), "%d: prop %d: wrong value\n", line, i ); @@ -384,6 +384,15 @@ static void test_assembly_name_props_line(IAssemblyName *name, ok( !lstrcmpW( expect, str ), "%d: prop %d: Expected %s, got %s\n", line, i, wine_dbgstr_w(expect), wine_dbgstr_w(str) ); } + + if (size != 0 && size != MAX_PATH) + { + size--; + hr = IAssemblyName_GetProperty(name, i, str, &size); + ok(hr == STRSAFE_E_INSUFFICIENT_BUFFER, + "%d: prop %d: Expected STRSAFE_E_INSUFFICIENT_BUFFER, got %08x\n", line, i, hr); + ok(size == vals[i].size, "%d: prop %d: Expected %d, got %d\n", line, i, vals[i].size, size); + } } } } @@ -397,6 +406,7 @@ static void test_CreateAssemblyNameObject(void) WCHAR str[MAX_PATH]; WCHAR namestr[MAX_PATH]; DWORD size, hi, lo; + PEKIND arch; HRESULT hr; static const WCHAR empty[] = {0}; @@ -536,6 +546,13 @@ static void test_CreateAssemblyNameObject(void) ok(str[0] == 'a', "got %c\n", str[0]); ok(size == 5, "got %u\n", size); + size = 0; + str[0] = 'a'; + hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_FULL); + ok(hr == E_NOT_SUFFICIENT_BUFFER, "got %08x\n", hr); + ok(str[0] == 'a', "got %c\n", str[0]); + ok(size == 5, "Wrong size %u\n", size); + size = MAX_PATH; hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_FULL); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); @@ -740,8 +757,8 @@ static void test_CreateAssemblyNameObject(void) IAssemblyName_Release(name); - /* 'wine, PublicKeyToken=1234567890abcdef' */ - to_widechar(namestr, "wine, PublicKeyToken=1234567890abcdef"); + /* 'wine, PublicKeyToken=01234567890abcde' */ + to_widechar(namestr, "wine, PublicKeyToken=01234567890abcde"); name = NULL; hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); @@ -750,7 +767,7 @@ static void test_CreateAssemblyNameObject(void) size = MAX_PATH; hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_FULL); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); - ok_aw("wine, PublicKeyToken=1234567890abcdef", str); + ok_aw("wine, PublicKeyToken=01234567890abcde", str); ok(size == 38, "Expected 38, got %d\n", size); size = MAX_PATH; @@ -794,6 +811,12 @@ static void test_CreateAssemblyNameObject(void) ok_aw("wine, processorArchitecture=x86", str); ok(size == 32, "Expected 32, got %d\n", size); + size = sizeof(arch); + hr = IAssemblyName_GetProperty(name, ASM_NAME_ARCHITECTURE, &arch, &size); + ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); + ok(arch == peI386, "Expected peI386, got %d\n", arch); + ok(size == sizeof(arch), "Wrong size %d\n", size); + IAssemblyName_Release(name); /* amd64 */ @@ -808,6 +831,12 @@ static void test_CreateAssemblyNameObject(void) ok_aw("wine, processorArchitecture=AMD64", str); ok(size == 34, "Expected 34, got %d\n", size); + size = sizeof(arch); + hr = IAssemblyName_GetProperty(name, ASM_NAME_ARCHITECTURE, &arch, &size); + ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); + ok(arch == peAMD64, "Expected peAMD64, got %d\n", arch); + ok(size == sizeof(arch), "Wrong size %d\n", size); + IAssemblyName_Release(name); /* ia64 */ @@ -822,6 +851,12 @@ static void test_CreateAssemblyNameObject(void) ok_aw("wine, processorArchitecture=IA64", str); ok(size == 33, "Expected 33, got %d\n", size); + size = sizeof(arch); + hr = IAssemblyName_GetProperty(name, ASM_NAME_ARCHITECTURE, &arch, &size); + ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); + ok(arch == peIA64, "Expected peIA64, got %d\n", arch); + ok(size == sizeof(arch), "Wrong size %d\n", size); + IAssemblyName_Release(name); /* msil */ @@ -836,6 +871,12 @@ static void test_CreateAssemblyNameObject(void) ok_aw("wine, processorArchitecture=MSIL", str); ok(size == 33, "Expected 33, got %d\n", size); + size = sizeof(arch); + hr = IAssemblyName_GetProperty(name, ASM_NAME_ARCHITECTURE, &arch, &size); + ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); + ok(arch == peMSIL, "Expected peMSIL, got %d\n", arch); + ok(size == sizeof(arch), "Wrong size %d\n", size); + IAssemblyName_Release(name); }
6 years, 11 months
1
0
0
0
01/01: [FUSION] Sync with Wine 3.0. CORE-14225
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=975d9d4d4c5644dd66f6d…
commit 975d9d4d4c5644dd66f6df337049607494f38a2f Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Fri Jan 19 00:10:53 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Fri Jan 19 00:10:53 2018 +0100 [FUSION] Sync with Wine 3.0. CORE-14225 --- dll/win32/fusion/asmname.c | 89 +++++++++++++++++++++++++++++++++++++++------- dll/win32/fusion/fusion.c | 2 +- media/doc/README.WINE | 2 +- 3 files changed, 79 insertions(+), 14 deletions(-) diff --git a/dll/win32/fusion/asmname.c b/dll/win32/fusion/asmname.c index 3fc54d28b1..79a99f5bc0 100644 --- a/dll/win32/fusion/asmname.c +++ b/dll/win32/fusion/asmname.c @@ -22,6 +22,7 @@ #include <assert.h> #include <winuser.h> +#include <strsafe.h> typedef struct { IAssemblyName IAssemblyName_iface; @@ -39,6 +40,8 @@ typedef struct { BYTE pubkey[8]; BOOL haspubkey; + PEKIND pekind; + LONG ref; } IAssemblyNameImpl; @@ -123,11 +126,11 @@ static HRESULT WINAPI IAssemblyNameImpl_GetProperty(IAssemblyName *iface, LPDWORD pcbProperty) { IAssemblyNameImpl *name = impl_from_IAssemblyName(iface); + DWORD size; TRACE("(%p, %d, %p, %p)\n", iface, PropertyId, pvProperty, pcbProperty); - *((LPWSTR)pvProperty) = '\0'; - + size = *pcbProperty; switch (PropertyId) { case ASM_NAME_NULL_PUBLIC_KEY: @@ -143,45 +146,65 @@ static HRESULT WINAPI IAssemblyNameImpl_GetProperty(IAssemblyName *iface, *pcbProperty = 0; if (name->name) { - lstrcpyW(pvProperty, name->name); *pcbProperty = (lstrlenW(name->name) + 1) * 2; + if (size < *pcbProperty) + return STRSAFE_E_INSUFFICIENT_BUFFER; + lstrcpyW(pvProperty, name->name); } break; case ASM_NAME_MAJOR_VERSION: *pcbProperty = 0; - *((WORD *)pvProperty) = name->version[0]; if (name->versize >= 1) + { *pcbProperty = sizeof(WORD); + if (size < *pcbProperty) + return STRSAFE_E_INSUFFICIENT_BUFFER; + *((WORD *)pvProperty) = name->version[0]; + } break; case ASM_NAME_MINOR_VERSION: *pcbProperty = 0; - *((WORD *)pvProperty) = name->version[1]; if (name->versize >= 2) + { *pcbProperty = sizeof(WORD); + if (size < *pcbProperty) + return STRSAFE_E_INSUFFICIENT_BUFFER; + *((WORD *)pvProperty) = name->version[1]; + } break; case ASM_NAME_BUILD_NUMBER: *pcbProperty = 0; - *((WORD *)pvProperty) = name->version[2]; if (name->versize >= 3) + { *pcbProperty = sizeof(WORD); + if (size < *pcbProperty) + return STRSAFE_E_INSUFFICIENT_BUFFER; + *((WORD *)pvProperty) = name->version[2]; + } break; case ASM_NAME_REVISION_NUMBER: *pcbProperty = 0; - *((WORD *)pvProperty) = name->version[3]; if (name->versize >= 4) + { *pcbProperty = sizeof(WORD); + if (size < *pcbProperty) + return STRSAFE_E_INSUFFICIENT_BUFFER; + *((WORD *)pvProperty) = name->version[3]; + } break; case ASM_NAME_CULTURE: *pcbProperty = 0; if (name->culture) { - lstrcpyW(pvProperty, name->culture); *pcbProperty = (lstrlenW(name->culture) + 1) * 2; + if (size < *pcbProperty) + return STRSAFE_E_INSUFFICIENT_BUFFER; + lstrcpyW(pvProperty, name->culture); } break; @@ -189,8 +212,21 @@ static HRESULT WINAPI IAssemblyNameImpl_GetProperty(IAssemblyName *iface, *pcbProperty = 0; if (name->haspubkey) { - memcpy(pvProperty, name->pubkey, sizeof(DWORD) * 2); *pcbProperty = sizeof(DWORD) * 2; + if (size < *pcbProperty) + return STRSAFE_E_INSUFFICIENT_BUFFER; + memcpy(pvProperty, name->pubkey, sizeof(DWORD) * 2); + } + break; + + case ASM_NAME_ARCHITECTURE: + *pcbProperty = 0; + if (name->pekind != peNone) + { + *pcbProperty = sizeof(PEKIND); + if (size < *pcbProperty) + return STRSAFE_E_INSUFFICIENT_BUFFER; + *((PEKIND *)pvProperty) = name->pekind; } break; @@ -281,7 +317,10 @@ static HRESULT WINAPI IAssemblyNameImpl_GetDisplayName(IAssemblyName *iface, size += lstrlenW(separator) + lstrlenW(procarch) + lstrlenW(equals) + lstrlenW(name->procarch); if (size > *pccDisplayName) - return S_FALSE; + { + *pccDisplayName = size; + return E_NOT_SUFFICIENT_BUFFER; + } /* Construct the string */ lstrcpyW(szDisplayName, name->name); @@ -307,8 +346,8 @@ static HRESULT WINAPI IAssemblyNameImpl_GetDisplayName(IAssemblyName *iface, if ((dwDisplayFlags & ASM_DISPLAYF_PUBLIC_KEY_TOKEN) && (name->haspubkey)) { WCHAR pkt[CHARS_PER_PUBKEY + 1]; - static const WCHAR spec[] = {'%','0','x','%','0','x','%','0','x', - '%','0','x','%','0','x','%','0','x','%','0','x','%','0','x',0}; + static const WCHAR spec[] = {'%','0','2','x','%','0','2','x','%','0','2','x', + '%','0','2','x','%','0','2','x','%','0','2','x','%','0','2','x','%','0','2','x',0}; lstrcatW(szDisplayName, separator); @@ -578,6 +617,30 @@ static HRESULT parse_pubkey(IAssemblyNameImpl *name, LPCWSTR pubkey) return S_OK; } +static HRESULT parse_procarch(IAssemblyNameImpl *name, LPCWSTR procarch) +{ + static const WCHAR msilW[] = {'m','s','i','l',0}; + static const WCHAR x86W[] = {'x','8','6',0}; + static const WCHAR ia64W[] = {'i','a','6','4',0}; + static const WCHAR amd64W[] = {'a','m','d','6','4',0}; + + if (!lstrcmpiW(procarch, msilW)) + name->pekind = peMSIL; + else if (!lstrcmpiW(procarch, x86W)) + name->pekind = peI386; + else if (!lstrcmpiW(procarch, ia64W)) + name->pekind = peIA64; + else if (!lstrcmpiW(procarch, amd64W)) + name->pekind = peAMD64; + else + { + ERR("unrecognized architecture: %s\n", wine_dbgstr_w(procarch)); + return FUSION_E_INVALID_NAME; + } + + return S_OK; +} + static WCHAR *parse_value( const WCHAR *str, unsigned int len ) { WCHAR *ret; @@ -688,6 +751,8 @@ static HRESULT parse_display_name(IAssemblyNameImpl *name, LPCWSTR szAssemblyNam { name->procarch = value; value = NULL; + + hr = parse_procarch( name, name->procarch ); } HeapFree( GetProcessHeap(), 0, value ); diff --git a/dll/win32/fusion/fusion.c b/dll/win32/fusion/fusion.c index 729356208e..a51f40660d 100644 --- a/dll/win32/fusion/fusion.c +++ b/dll/win32/fusion/fusion.c @@ -26,7 +26,7 @@ HRESULT WINAPI InitializeFusion(void) { FIXME("\n"); - return E_NOTIMPL; + return S_OK; } /****************************************************************** diff --git a/media/doc/README.WINE b/media/doc/README.WINE index 5e4932e3ad..8b15f8045b 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -67,7 +67,7 @@ reactos/dll/win32/dbghelp # Synced to Wine-3.0 reactos/dll/win32/dciman32 # Synced to WineStaging-2.9 reactos/dll/win32/faultrep # Synced to WineStaging-2.9 reactos/dll/win32/fontsub # Synced to WineStaging-2.9 -reactos/dll/win32/fusion # Synced to WineStaging-2.16 +reactos/dll/win32/fusion # Synced to Wine-3.0 reactos/dll/win32/gdiplus # Synced to WineStaging-2.16 reactos/dll/win32/hhctrl.ocx # Synced to WineStaging-2.9 reactos/dll/win32/hlink # Synced to WineStaging-2.9
6 years, 11 months
1
0
0
0
01/01: [DBGHELP] Sync with Wine 3.0. CORE-14225
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=f9c57f84898ada4d39184…
commit f9c57f84898ada4d391849497754101fc55b2a75 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Fri Jan 19 00:09:29 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Fri Jan 19 00:09:29 2018 +0100 [DBGHELP] Sync with Wine 3.0. CORE-14225 --- dll/win32/dbghelp/cpu_arm64.c | 69 +++++++++++++++++++++--------------------- dll/win32/dbghelp/cpu_i386.c | 6 ++-- dll/win32/dbghelp/elf_module.c | 8 ++--- media/doc/README.WINE | 2 +- 4 files changed, 41 insertions(+), 44 deletions(-) diff --git a/dll/win32/dbghelp/cpu_arm64.c b/dll/win32/dbghelp/cpu_arm64.c index 68cff95eaa..a2a0bb4df9 100644 --- a/dll/win32/dbghelp/cpu_arm64.c +++ b/dll/win32/dbghelp/cpu_arm64.c @@ -160,41 +160,40 @@ static void* arm64_fetch_context_reg(CONTEXT* ctx, unsigned regno, unsigned* siz #ifdef __aarch64__ switch (regno) { - case CV_ARM64_PSTATE: *size = sizeof(ctx->Cpsr); return &ctx->Cpsr; - case CV_ARM64_X0 + 0: *size = sizeof(ctx->X0); return &ctx->X0; - case CV_ARM64_X0 + 1: *size = sizeof(ctx->X1); return &ctx->X1; - case CV_ARM64_X0 + 2: *size = sizeof(ctx->X2); return &ctx->X2; - case CV_ARM64_X0 + 3: *size = sizeof(ctx->X3); return &ctx->X3; - case CV_ARM64_X0 + 4: *size = sizeof(ctx->X4); return &ctx->X4; - case CV_ARM64_X0 + 5: *size = sizeof(ctx->X5); return &ctx->X5; - case CV_ARM64_X0 + 6: *size = sizeof(ctx->X6); return &ctx->X6; - case CV_ARM64_X0 + 7: *size = sizeof(ctx->X7); return &ctx->X7; - case CV_ARM64_X0 + 8: *size = sizeof(ctx->X8); return &ctx->X8; - case CV_ARM64_X0 + 9: *size = sizeof(ctx->X9); return &ctx->X9; - case CV_ARM64_X0 + 10: *size = sizeof(ctx->X10); return &ctx->X10; - case CV_ARM64_X0 + 11: *size = sizeof(ctx->X11); return &ctx->X11; - case CV_ARM64_X0 + 12: *size = sizeof(ctx->X12); return &ctx->X12; - case CV_ARM64_X0 + 13: *size = sizeof(ctx->X13); return &ctx->X13; - case CV_ARM64_X0 + 14: *size = sizeof(ctx->X14); return &ctx->X14; - case CV_ARM64_X0 + 15: *size = sizeof(ctx->X15); return &ctx->X15; - case CV_ARM64_X0 + 16: *size = sizeof(ctx->X16); return &ctx->X16; - case CV_ARM64_X0 + 17: *size = sizeof(ctx->X17); return &ctx->X17; - case CV_ARM64_X0 + 18: *size = sizeof(ctx->X18); return &ctx->X18; - case CV_ARM64_X0 + 19: *size = sizeof(ctx->X19); return &ctx->X19; - case CV_ARM64_X0 + 20: *size = sizeof(ctx->X20); return &ctx->X20; - case CV_ARM64_X0 + 21: *size = sizeof(ctx->X21); return &ctx->X21; - case CV_ARM64_X0 + 22: *size = sizeof(ctx->X22); return &ctx->X22; - case CV_ARM64_X0 + 23: *size = sizeof(ctx->X23); return &ctx->X23; - case CV_ARM64_X0 + 24: *size = sizeof(ctx->X24); return &ctx->X24; - case CV_ARM64_X0 + 25: *size = sizeof(ctx->X25); return &ctx->X25; - case CV_ARM64_X0 + 26: *size = sizeof(ctx->X26); return &ctx->X26; - case CV_ARM64_X0 + 27: *size = sizeof(ctx->X27); return &ctx->X27; - case CV_ARM64_X0 + 28: *size = sizeof(ctx->X28); return &ctx->X28; - - case CV_ARM64_FP: *size = sizeof(ctx->Fp); return &ctx->Fp; - case CV_ARM64_LR: *size = sizeof(ctx->Lr); return &ctx->Lr; - case CV_ARM64_SP: *size = sizeof(ctx->Sp); return &ctx->Sp; - case CV_ARM64_PC: *size = sizeof(ctx->Pc); return &ctx->Pc; + case CV_ARM64_X0 + 0: + case CV_ARM64_X0 + 1: + case CV_ARM64_X0 + 2: + case CV_ARM64_X0 + 3: + case CV_ARM64_X0 + 4: + case CV_ARM64_X0 + 5: + case CV_ARM64_X0 + 6: + case CV_ARM64_X0 + 7: + case CV_ARM64_X0 + 8: + case CV_ARM64_X0 + 9: + case CV_ARM64_X0 + 10: + case CV_ARM64_X0 + 11: + case CV_ARM64_X0 + 12: + case CV_ARM64_X0 + 13: + case CV_ARM64_X0 + 14: + case CV_ARM64_X0 + 15: + case CV_ARM64_X0 + 16: + case CV_ARM64_X0 + 17: + case CV_ARM64_X0 + 18: + case CV_ARM64_X0 + 19: + case CV_ARM64_X0 + 20: + case CV_ARM64_X0 + 21: + case CV_ARM64_X0 + 22: + case CV_ARM64_X0 + 23: + case CV_ARM64_X0 + 24: + case CV_ARM64_X0 + 25: + case CV_ARM64_X0 + 26: + case CV_ARM64_X0 + 27: + case CV_ARM64_X0 + 28: *size = sizeof(ctx->u.X[0]); return &ctx->u.X[regno - CV_ARM64_X0]; + case CV_ARM64_PSTATE: *size = sizeof(ctx->Cpsr); return &ctx->Cpsr; + case CV_ARM64_FP: *size = sizeof(ctx->Fp); return &ctx->Fp; + case CV_ARM64_LR: *size = sizeof(ctx->Lr); return &ctx->Lr; + case CV_ARM64_SP: *size = sizeof(ctx->Sp); return &ctx->Sp; + case CV_ARM64_PC: *size = sizeof(ctx->Pc); return &ctx->Pc; } #endif FIXME("Unknown register %x\n", regno); diff --git a/dll/win32/dbghelp/cpu_i386.c b/dll/win32/dbghelp/cpu_i386.c index f0cf33aaf8..c713049cf2 100644 --- a/dll/win32/dbghelp/cpu_i386.c +++ b/dll/win32/dbghelp/cpu_i386.c @@ -215,16 +215,16 @@ static BOOL i386_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CO /* Init done */ set_curr_mode((frame->AddrPC.Mode == AddrModeFlat) ? stm_32bit : stm_16bit); - /* cur_switch holds address of SystemReserved1[0] field in TEB in debuggee + /* cur_switch holds address of WOW32Reserved field in TEB in debuggee * address space */ if (NtQueryInformationThread(csw->hThread, ThreadBasicInformation, &info, sizeof(info), NULL) == STATUS_SUCCESS) { - curr_switch = (DWORD_PTR)info.TebBaseAddress + FIELD_OFFSET(TEB, SystemReserved1[0]); + curr_switch = (DWORD_PTR)info.TebBaseAddress + FIELD_OFFSET(TEB, WOW32Reserved); if (!sw_read_mem(csw, curr_switch, &p, sizeof(p))) { - WARN("Can't read TEB:SystemReserved1[0]\n"); + WARN("Can't read TEB:WOW32Reserved\n"); goto done_err; } next_switch = p; diff --git a/dll/win32/dbghelp/elf_module.c b/dll/win32/dbghelp/elf_module.c index b44d988d02..2edab86b70 100644 --- a/dll/win32/dbghelp/elf_module.c +++ b/dll/win32/dbghelp/elf_module.c @@ -1471,11 +1471,9 @@ static BOOL elf_search_and_load_file(struct process* pcs, const WCHAR* filename, if (!ret && !strchrW(filename, '/')) { ret = elf_load_file_from_path(pcs, filename, load_offset, dyn_addr, - getenv("PATH"), elf_info); - if (!ret) ret = elf_load_file_from_path(pcs, filename, load_offset, dyn_addr, - getenv("LD_LIBRARY_PATH"), elf_info); - if (!ret) ret = elf_load_file_from_path(pcs, filename, load_offset, dyn_addr, - BINDIR, elf_info); + getenv("PATH"), elf_info) || + elf_load_file_from_path(pcs, filename, load_offset, dyn_addr, + getenv("LD_LIBRARY_PATH"), elf_info); if (!ret) ret = elf_load_file_from_dll_path(pcs, filename, load_offset, dyn_addr, elf_info); } diff --git a/media/doc/README.WINE b/media/doc/README.WINE index 1d25ea7149..5e4932e3ad 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -63,7 +63,7 @@ reactos/dll/win32/cryptdlg # Synced to WineStaging-2.9 reactos/dll/win32/cryptdll # Synced to WineStaging-2.9 reactos/dll/win32/cryptnet # Synced to WineStaging-2.9 reactos/dll/win32/cryptui # Synced to WineStaging-2.16 -reactos/dll/win32/dbghelp # Synced to WineStaging-2.16 +reactos/dll/win32/dbghelp # Synced to Wine-3.0 reactos/dll/win32/dciman32 # Synced to WineStaging-2.9 reactos/dll/win32/faultrep # Synced to WineStaging-2.9 reactos/dll/win32/fontsub # Synced to WineStaging-2.9
6 years, 11 months
1
0
0
0
01/01: [CABINET_WINETEST] Sync with Wine 3.0. CORE-14225
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=2afa4566bae6fe137668a…
commit 2afa4566bae6fe137668a44fd536ab6c3fd898c3 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Fri Jan 19 00:07:18 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Fri Jan 19 00:07:18 2018 +0100 [CABINET_WINETEST] Sync with Wine 3.0. CORE-14225 --- modules/rostests/winetests/cabinet/fdi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/rostests/winetests/cabinet/fdi.c b/modules/rostests/winetests/cabinet/fdi.c index 1393e9a469..741283afe6 100644 --- a/modules/rostests/winetests/cabinet/fdi.c +++ b/modules/rostests/winetests/cabinet/fdi.c @@ -744,7 +744,7 @@ static void test_FDIIsCabinet(void) static INT_PTR __cdecl CopyProgress(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin) { - return 0; + return 37; /* doc says 0, but anything != -1 apparently means success as well */ } static INT_PTR CDECL fdi_mem_open(char *name, int oflag, int pmode)
6 years, 11 months
1
0
0
0
01/01: [CABINET] Sync with Wine 3.0. CORE-14225
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=736e16553a1453cacc2f3…
commit 736e16553a1453cacc2f3a87d7516658d336e74c Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Fri Jan 19 00:06:11 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Fri Jan 19 00:06:11 2018 +0100 [CABINET] Sync with Wine 3.0. CORE-14225 --- dll/win32/cabinet/fdi.c | 18 +++++++++--------- media/doc/README.WINE | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/dll/win32/cabinet/fdi.c b/dll/win32/cabinet/fdi.c index 250ff1b2e3..a864bd7fdb 100644 --- a/dll/win32/cabinet/fdi.c +++ b/dll/win32/cabinet/fdi.c @@ -2039,19 +2039,19 @@ static int fdi_decomp(const struct fdi_file *fi, int savemode, fdi_decomp_state fullpath[0] = '\0'; if (pathlen) { strcpy(fullpath, userpath); -#ifndef __REACTOS__ - if (fullpath[pathlen - 1] != '\\') - strcat(fullpath, "\\"); -#else +#ifdef __REACTOS__ if (fullpath[pathlen - 1] == '\\') fullpath[pathlen - 1] = '\0'; +#else + if (fullpath[pathlen - 1] != '\\') + strcat(fullpath, "\\"); #endif } -#ifndef __REACTOS__ - if (filenamelen) -#else +#ifdef __REACTOS__ if (filenamelen) { strcat(fullpath, "\\"); +#else + if (filenamelen) #endif strcat(fullpath, cab->mii.nextname); #ifdef __REACTOS__ @@ -2498,7 +2498,7 @@ BOOL __cdecl FDICopy( fdin.psz2 = (CAB(mii).nextinfo) ? CAB(mii).nextinfo : &emptystring; fdin.psz3 = pszCabPath; - if (((*pfnfdin)(fdintCABINET_INFO, &fdin))) { + if (pfnfdin(fdintCABINET_INFO, &fdin) == -1) { set_error( fdi, FDIERROR_USER_ABORT, 0 ); goto bail_and_fail; } @@ -2625,7 +2625,7 @@ BOOL __cdecl FDICopy( fdin.psz2 = (CAB(mii).prevname) ? CAB(mii).prevname : &emptystring; fdin.psz3 = (CAB(mii).previnfo) ? CAB(mii).previnfo : &emptystring; - if (((*pfnfdin)(fdintPARTIAL_FILE, &fdin))) { + if (pfnfdin(fdintPARTIAL_FILE, &fdin) == -1) { set_error( fdi, FDIERROR_USER_ABORT, 0 ); goto bail_and_fail; } diff --git a/media/doc/README.WINE b/media/doc/README.WINE index 239c5fd0d8..1d25ea7149 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -51,7 +51,7 @@ reactos/dll/win32/atl100 # Synced to Wine-3.0 reactos/dll/win32/avifil32 # Synced to Wine-3.0 reactos/dll/win32/bcrypt # Synced to WineStaging-1.9.23 reactos/dll/win32/browseui # Out of sync -reactos/dll/win32/cabinet # Synced to WineStaging-2.9 +reactos/dll/win32/cabinet # Synced to Wine-3.0 reactos/dll/win32/clusapi # Synced to WineStaging-2.9 reactos/dll/win32/comcat # Synced to WineStaging-2.9 reactos/dll/win32/comctl32 # Synced to Wine-3.0
6 years, 11 months
1
0
0
0
← Newer
1
...
23
24
25
26
27
28
29
...
38
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
Results per page:
10
25
50
100
200