winehq.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
2025
February
January
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
January
2003
December
November
October
September
August
July
June
May
April
March
February
January
2002
December
November
October
September
August
July
June
May
April
March
February
January
2001
December
November
October
September
August
July
June
May
April
March
February
List overview
wine-commits
November 2022
----- 2025 -----
February 2025
January 2025
----- 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
January 2004
----- 2003 -----
December 2003
November 2003
October 2003
September 2003
August 2003
July 2003
June 2003
May 2003
April 2003
March 2003
February 2003
January 2003
----- 2002 -----
December 2002
November 2002
October 2002
September 2002
August 2002
July 2002
June 2002
May 2002
April 2002
March 2002
February 2002
January 2002
----- 2001 -----
December 2001
November 2001
October 2001
September 2001
August 2001
July 2001
June 2001
May 2001
April 2001
March 2001
February 2001
wine-commits@winehq.org
1 participants
1171 discussions
Start a n
N
ew thread
Alexandre Julliard : winecrt0: Add a helper function and macro to simplify Unix library usage.
by Alexandre Julliard
24 Nov '22
24 Nov '22
Module: wine Branch: master Commit: 1d036c04930e449cfc374e52e9663ab8ecad0465 URL:
https://gitlab.winehq.org/wine/wine/-/commit/1d036c04930e449cfc374e52e9663a…
Author: Alexandre Julliard <julliard(a)winehq.org> Date: Thu Nov 24 10:25:52 2022 +0100 winecrt0: Add a helper function and macro to simplify Unix library usage. --- dlls/winecrt0/unix_lib.c | 23 +++++++++++++++++++++-- include/wine/unixlib.h | 10 +++++++++- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/dlls/winecrt0/unix_lib.c b/dlls/winecrt0/unix_lib.c index c86897b9905..10be32899ba 100644 --- a/dlls/winecrt0/unix_lib.c +++ b/dlls/winecrt0/unix_lib.c @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#ifdef __WINE_PE_BUILD - #include <stdarg.h> #include "ntstatus.h" @@ -29,6 +27,8 @@ #include "winternl.h" #include "wine/unixlib.h" +#ifdef __WINE_PE_BUILD + static NTSTATUS (WINAPI *p__wine_unix_call)( unixlib_handle_t, unsigned int, void * ); static void load_func( void **func, const char *name, void *def ) @@ -54,3 +54,22 @@ NTSTATUS WINAPI __wine_unix_call( unixlib_handle_t handle, unsigned int code, vo } #endif /* __WINE_PE_BUILD */ + +static inline void *image_base(void) +{ +#ifdef __WINE_PE_BUILD + extern IMAGE_DOS_HEADER __ImageBase; + return (void *)&__ImageBase; +#else + extern IMAGE_NT_HEADERS __wine_spec_nt_header; + return (void *)((__wine_spec_nt_header.OptionalHeader.ImageBase + 0xffff) & ~0xffff); +#endif +} + +unixlib_handle_t __wine_unixlib_handle = 0; + +NTSTATUS WINAPI __wine_init_unix_call(void) +{ + return NtQueryVirtualMemory( GetCurrentProcess(), image_base(), MemoryWineUnixFuncs, + &__wine_unixlib_handle, sizeof(__wine_unixlib_handle), NULL ); +} diff --git a/include/wine/unixlib.h b/include/wine/unixlib.h index ef60b32184c..fcb25422524 100644 --- a/include/wine/unixlib.h +++ b/include/wine/unixlib.h @@ -21,13 +21,14 @@ #ifndef __WINE_WINE_UNIXLIB_H #define __WINE_WINE_UNIXLIB_H -typedef NTSTATUS (*unixlib_entry_t)( void *args ); typedef UINT64 unixlib_handle_t; extern NTSTATUS WINAPI __wine_unix_call( unixlib_handle_t handle, unsigned int code, void *args ); #ifdef WINE_UNIX_LIB +typedef NTSTATUS (*unixlib_entry_t)( void *args ); + /* some useful helpers from ntdll */ extern const char *ntdll_get_build_dir(void); extern const char *ntdll_get_data_dir(void); @@ -264,6 +265,13 @@ static inline ULONG ntdll_wcstoul( const WCHAR *s, WCHAR **end, int base ) #define wcstol(str,e,b) ntdll_wcstol(str,e,b) #define wcstoul(str,e,b) ntdll_wcstoul(str,e,b) +#else /* WINE_UNIX_LIB */ + +extern unixlib_handle_t __wine_unixlib_handle DECLSPEC_HIDDEN; +extern NTSTATUS WINAPI __wine_init_unix_call(void) DECLSPEC_HIDDEN; + +#define WINE_UNIX_CALL(code,args) __wine_unix_call( __wine_unixlib_handle, (code), (args) ) + #endif /* WINE_UNIX_LIB */ #endif /* __WINE_WINE_UNIXLIB_H */
1
0
0
0
Alex Henrie : pdh: Use standard C functions for memory allocation.
by Alexandre Julliard
24 Nov '22
24 Nov '22
Module: wine Branch: master Commit: ed510dd900a6feb57f280b0d10ee2a61b7873fe8 URL:
https://gitlab.winehq.org/wine/wine/-/commit/ed510dd900a6feb57f280b0d10ee2a…
Author: Alex Henrie <alexhenrie24(a)gmail.com> Date: Wed Nov 23 21:43:11 2022 -0700 pdh: Use standard C functions for memory allocation. --- dlls/pdh/pdh_main.c | 51 +++++++++++++++++++++------------------------------ 1 file changed, 21 insertions(+), 30 deletions(-) diff --git a/dlls/pdh/pdh_main.c b/dlls/pdh/pdh_main.c index 3fc3f7bc6b8..7eae7872b48 100644 --- a/dlls/pdh/pdh_main.c +++ b/dlls/pdh/pdh_main.c @@ -20,6 +20,7 @@ */ #include <stdarg.h> +#include <stdlib.h> #include <math.h> #define NONAMELESSUNION @@ -32,7 +33,6 @@ #include "winperf.h" #include "wine/debug.h" -#include "wine/heap.h" #include "wine/list.h" WINE_DEFAULT_DEBUG_CHANNEL(pdh); @@ -47,15 +47,6 @@ static CRITICAL_SECTION_DEBUG pdh_handle_cs_debug = }; static CRITICAL_SECTION pdh_handle_cs = { &pdh_handle_cs_debug, -1, 0, 0, 0, 0 }; -static inline WCHAR *pdh_strdup( const WCHAR *src ) -{ - WCHAR *dst; - - if (!src) return NULL; - if ((dst = heap_alloc( (lstrlenW( src ) + 1) * sizeof(WCHAR) ))) lstrcpyW( dst, src ); - return dst; -} - static inline WCHAR *pdh_strdup_aw( const char *src ) { int len; @@ -63,7 +54,7 @@ static inline WCHAR *pdh_strdup_aw( const char *src ) if (!src) return NULL; len = MultiByteToWideChar( CP_ACP, 0, src, -1, NULL, 0 ); - if ((dst = heap_alloc( len * sizeof(WCHAR) ))) MultiByteToWideChar( CP_ACP, 0, src, -1, dst, len ); + if ((dst = malloc( len * sizeof(WCHAR) ))) MultiByteToWideChar( CP_ACP, 0, src, -1, dst, len ); return dst; } @@ -98,7 +89,7 @@ static struct counter *create_counter( void ) { struct counter *counter; - if ((counter = heap_alloc_zero( sizeof(struct counter) ))) + if ((counter = calloc( 1, sizeof(struct counter) ))) { counter->magic = PDH_MAGIC_COUNTER; return counter; @@ -109,8 +100,8 @@ static struct counter *create_counter( void ) static void destroy_counter( struct counter *counter ) { counter->magic = 0; - heap_free( counter->path ); - heap_free( counter ); + free( counter->path ); + free( counter ); } #define PDH_MAGIC_QUERY 0x50444830 /* 'PDH0' */ @@ -130,7 +121,7 @@ static struct query *create_query( void ) { struct query *query; - if ((query = heap_alloc_zero( sizeof(struct query) ))) + if ((query = calloc( 1, sizeof(struct query) ))) { query->magic = PDH_MAGIC_QUERY; list_init( &query->counters ); @@ -142,7 +133,7 @@ static struct query *create_query( void ) static void destroy_query( struct query *query ) { query->magic = 0; - heap_free( query ); + free( query ); } struct source @@ -222,7 +213,7 @@ PDH_STATUS WINAPI PdhAddCounterA( PDH_HQUERY query, LPCSTR path, ret = PdhAddCounterW( query, pathW, userdata, counter ); - heap_free( pathW ); + free( pathW ); return ret; } @@ -254,7 +245,7 @@ PDH_STATUS WINAPI PdhAddCounterW( PDH_HQUERY hquery, LPCWSTR path, { if ((counter = create_counter())) { - counter->path = pdh_strdup( counter_sources[i].path ); + counter->path = wcsdup( counter_sources[i].path ); counter->collect = counter_sources[i].collect; counter->type = counter_sources[i].type; counter->defaultscale = counter_sources[i].scale; @@ -822,8 +813,8 @@ PDH_STATUS WINAPI PdhLookupPerfIndexByNameA( LPCSTR machine, LPCSTR name, LPDWOR ret = PdhLookupPerfIndexByNameW( machineW, nameW, index ); - heap_free( nameW ); - heap_free( machineW ); + free( nameW ); + free( machineW ); return ret; } @@ -878,7 +869,7 @@ PDH_STATUS WINAPI PdhLookupPerfNameByIndexA( LPCSTR machine, DWORD index, LPSTR else WideCharToMultiByte( CP_ACP, 0, bufferW, -1, buffer, required, NULL, NULL ); *size = required; } - heap_free( machineW ); + free( machineW ); return ret; } @@ -934,7 +925,7 @@ PDH_STATUS WINAPI PdhOpenQueryA( LPCSTR source, DWORD_PTR userdata, PDH_HQUERY * if (source && !(sourceW = pdh_strdup_aw( source ))) return PDH_MEMORY_ALLOCATION_FAILURE; ret = PdhOpenQueryW( sourceW, userdata, query ); - heap_free( sourceW ); + free( sourceW ); return ret; } @@ -1030,7 +1021,7 @@ PDH_STATUS WINAPI PdhValidatePathA( LPCSTR path ) ret = PdhValidatePathW( pathW ); - heap_free( pathW ); + free( pathW ); return ret; } @@ -1128,7 +1119,7 @@ PDH_STATUS WINAPI PdhMakeCounterPathA( PDH_COUNTER_PATH_ELEMENTS_A *e, LPSTR buf ret = PdhMakeCounterPathW( &eW, NULL, &buflenW, flags ); if (ret == PDH_MORE_DATA) { - if ((bufferW = heap_alloc( buflenW * sizeof(WCHAR) ))) + if ((bufferW = malloc( buflenW * sizeof(WCHAR) ))) { if (!(ret = PdhMakeCounterPathW( &eW, bufferW, &buflenW, flags ))) { @@ -1137,18 +1128,18 @@ PDH_STATUS WINAPI PdhMakeCounterPathA( PDH_COUNTER_PATH_ELEMENTS_A *e, LPSTR buf else ret = PDH_MORE_DATA; *buflen = len; } - heap_free( bufferW ); + free( bufferW ); } else ret = PDH_MEMORY_ALLOCATION_FAILURE; } done: - heap_free( eW.szMachineName ); - heap_free( eW.szObjectName ); - heap_free( eW.szInstanceName ); - heap_free( eW.szParentInstance ); - heap_free( eW.szCounterName ); + free( eW.szMachineName ); + free( eW.szObjectName ); + free( eW.szInstanceName ); + free( eW.szParentInstance ); + free( eW.szCounterName ); return ret; }
1
0
0
0
Nikolay Sivov : kernel32/profile: Trim spaces from section names on load.
by Alexandre Julliard
24 Nov '22
24 Nov '22
Module: wine Branch: master Commit: 8d9eb707c61455583a42891d6841ba9feeaf78d3 URL:
https://gitlab.winehq.org/wine/wine/-/commit/8d9eb707c61455583a42891d6841ba…
Author: Nikolay Sivov <nsivov(a)codeweavers.com> Date: Sun Nov 20 17:56:06 2022 +0300 kernel32/profile: Trim spaces from section names on load. Wine-Bug:
https://bugs.winehq.org/show_bug.cgi?id=53814
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com> --- dlls/kernel32/profile.c | 22 ++++++++++++++++++---- dlls/kernel32/tests/profile.c | 10 +++++++++- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/dlls/kernel32/profile.c b/dlls/kernel32/profile.c index bf1a9170896..f65790ecc92 100644 --- a/dlls/kernel32/profile.c +++ b/dlls/kernel32/profile.c @@ -292,6 +292,16 @@ static inline ENCODING PROFILE_DetectTextEncoding(const void * buffer, int * len return ENCODING_ANSI; } +static void profile_trim_spaces(WCHAR **start, WCHAR **end) +{ + WCHAR *s = *start, *e = *end; + + while (s < e && PROFILE_isspaceW(*s)) s++; + while ((e > s) && PROFILE_isspaceW(e[-1])) e--; + + *start = s; + *end = e; +} /*********************************************************************** * PROFILE_Load @@ -302,8 +312,8 @@ static PROFILESECTION *PROFILE_Load(HANDLE hFile, ENCODING * pEncoding) { void *buffer_base, *pBuffer; WCHAR * szFile; - const WCHAR *szLineStart, *szLineEnd; - const WCHAR *szValueStart, *szEnd, *next_line; + WCHAR *szLineStart, *szLineEnd, *next_line; + const WCHAR *szValueStart, *szEnd; int len; PROFILESECTION *section, *first_section; PROFILESECTION **next_section; @@ -400,8 +410,7 @@ static PROFILESECTION *PROFILE_Load(HANDLE hFile, ENCODING * pEncoding) szLineEnd = next_line; /* get rid of white space */ - while (szLineStart < szLineEnd && PROFILE_isspaceW(*szLineStart)) szLineStart++; - while ((szLineEnd > szLineStart) && PROFILE_isspaceW(szLineEnd[-1])) szLineEnd--; + profile_trim_spaces(&szLineStart, &szLineEnd); if (szLineStart >= szLineEnd) continue; @@ -415,8 +424,13 @@ static PROFILESECTION *PROFILE_Load(HANDLE hFile, ENCODING * pEncoding) } else { + /* Skip brackets */ szLineStart++; len -= 2; + szLineEnd = szLineStart + len; + profile_trim_spaces(&szLineStart, &szLineEnd); + len = szLineEnd - szLineStart; + /* no need to allocate +1 for NULL terminating character as * already included in structure */ if (!(section = HeapAlloc( GetProcessHeap(), 0, sizeof(*section) + len * sizeof(WCHAR) ))) diff --git a/dlls/kernel32/tests/profile.c b/dlls/kernel32/tests/profile.c index 18e12690f18..59842627b4f 100644 --- a/dlls/kernel32/tests/profile.c +++ b/dlls/kernel32/tests/profile.c @@ -80,6 +80,7 @@ static void test_profile_int(void) { SECTION, KEY, "B4294967297", TESTFILE, 1, 0}, }; int i, num_test = ARRAY_SIZE(profileInt); + char section[64]; UINT res; DeleteFileA( TESTFILE); @@ -93,6 +94,12 @@ static void test_profile_int(void) profileInt[i].defaultVal, profileInt[i].iniFile); ok((res == profileInt[i].result), "test<%02d>: ret<%010u> exp<%010u>\n", i, res, profileInt[i].result); + + sprintf(section, " %s ", profileInt[i].section); + res = GetPrivateProfileIntA(profileInt[i].section, profileInt[i].key, + profileInt[i].defaultVal, profileInt[i].iniFile); + ok((res == profileInt[i].result), "test<%02d>: ret<%010u> exp<%010u>\n", + i, res, profileInt[i].result); } DeleteFileA( TESTFILE); @@ -270,7 +277,7 @@ static void test_profile_sections_names(void) DWORD count; char buf[100]; WCHAR bufW[100]; - static const char content[]="[section1]\r\n[section2]\r\n[section3]\r\n"; + static const char content[]="[ section1 ]\r\n[section2]\r\n[section3]\r\n"; static const char testfile3[]=".\\testwine3.ini"; static const WCHAR testfile3W[]={ '.','\\','t','e','s','t','w','i','n','e','3','.','i','n','i',0 }; static const WCHAR not_here[] = {'.','\\','n','o','t','_','h','e','r','e','.','i','n','i',0}; @@ -288,6 +295,7 @@ static void test_profile_sections_names(void) ok( ret == 27, "expected return size 27, got %d\n", ret ); ok( (buf[ret-1] == 0 && buf[ret] == 0), "returned buffer not terminated with double-null\n" ); + ok( !strcmp(buf, "section1"), "Unexpected content %s.\n", debugstr_a(buf)); /* Test with exactly fitting buffer */ memset(buf, 0xc, sizeof(buf));
1
0
0
0
Anton Baskanov : wined3d: Add a lower size bound for the streaming buffer allocation.
by Alexandre Julliard
24 Nov '22
24 Nov '22
Module: wine Branch: master Commit: 1c84acd0573176b0f3b4b33ecd58d8aec428270a URL:
https://gitlab.winehq.org/wine/wine/-/commit/1c84acd0573176b0f3b4b33ecd58d8…
Author: Anton Baskanov <baskanov(a)gmail.com> Date: Thu Nov 17 15:01:05 2022 +0700 wined3d: Add a lower size bound for the streaming buffer allocation. Apps that issues many small draw calls (e.g. Earth 2150) may cause frequent DISCARD maps, which are significantly slower than NOOVERWRITE ones. --- dlls/wined3d/buffer.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c index fca7f2916b7..74c2a1b8b2b 100644 --- a/dlls/wined3d/buffer.c +++ b/dlls/wined3d/buffer.c @@ -34,6 +34,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); #define VB_MAXFULLCONVERSIONS 5 /* Number of full conversions before we stop converting */ #define VB_RESETFULLCONVS 20 /* Reset full conversion counts after that number of draws */ +#define SB_MIN_SIZE (512 * 1024) /* Minimum size of an allocated streaming buffer. */ + struct wined3d_buffer_ops { BOOL (*buffer_prepare_location)(struct wined3d_buffer *buffer, @@ -1665,7 +1667,7 @@ static HRESULT wined3d_streaming_buffer_prepare(struct wined3d_device *device, return S_OK; } - size = max(old_size * 2, min_size); + size = max(SB_MIN_SIZE, max(old_size * 2, min_size)); TRACE("Growing buffer to %u bytes.\n", size); desc.byte_width = size;
1
0
0
0
Anton Baskanov : ddraw: Use the wined3d_streaming_buffer helpers to manage the streaming index buffer.
by Alexandre Julliard
24 Nov '22
24 Nov '22
Module: wine Branch: master Commit: 42503f4ea352315b409d76b43f70e10dc7937965 URL:
https://gitlab.winehq.org/wine/wine/-/commit/42503f4ea352315b409d76b43f70e1…
Author: Anton Baskanov <baskanov(a)gmail.com> Date: Fri Oct 21 15:21:16 2022 +0700 ddraw: Use the wined3d_streaming_buffer helpers to manage the streaming index buffer. --- dlls/ddraw/ddraw_private.h | 6 +-- dlls/ddraw/device.c | 110 +++++---------------------------------------- 2 files changed, 12 insertions(+), 104 deletions(-) diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h index d2b1fc495fc..6693a650394 100644 --- a/dlls/ddraw/ddraw_private.h +++ b/dlls/ddraw/ddraw_private.h @@ -335,11 +335,7 @@ struct d3d_device struct ddraw *ddraw; IUnknown *rt_iface; - struct wined3d_buffer *index_buffer; - UINT index_buffer_size; - UINT index_buffer_pos; - - struct wined3d_streaming_buffer vertex_buffer; + struct wined3d_streaming_buffer vertex_buffer, index_buffer; /* Viewport management */ struct list viewport_list; diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c index 19ae3b6cf33..ac6647b8dad 100644 --- a/dlls/ddraw/device.c +++ b/dlls/ddraw/device.c @@ -279,8 +279,7 @@ static ULONG WINAPI d3d_device_inner_Release(IUnknown *iface) /* There is no need to unset any resources here, wined3d will take * care of that on uninit_3d(). */ - if (This->index_buffer) - wined3d_buffer_decref(This->index_buffer); + wined3d_streaming_buffer_cleanup(&This->index_buffer); wined3d_streaming_buffer_cleanup(&This->vertex_buffer); wined3d_device_context_set_rendertarget_views(This->immediate_context, 0, 1, &null_rtv, FALSE); @@ -3569,42 +3568,6 @@ static HRESULT WINAPI d3d_device2_DrawPrimitive(IDirect3DDevice2 *iface, * DDERR_INVALIDPARAMS if Vertices or Indices is NULL * *****************************************************************************/ -/* The caller is responsible for wined3d locking */ -static HRESULT d3d_device_prepare_index_buffer(struct d3d_device *device, UINT min_size) -{ - HRESULT hr; - - if (device->index_buffer_size < min_size || !device->index_buffer) - { - UINT size = max(device->index_buffer_size * 2, min_size); - struct wined3d_buffer_desc desc; - struct wined3d_buffer *buffer; - - TRACE("Growing index buffer to %u bytes\n", size); - - desc.byte_width = size; - desc.usage = WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_STATICDECL; - desc.bind_flags = WINED3D_BIND_INDEX_BUFFER; - desc.access = WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_MAP_W; - desc.misc_flags = 0; - desc.structure_byte_stride = 0; - - if (FAILED(hr = wined3d_buffer_create(device->wined3d_device, &desc, - NULL, NULL, &ddraw_null_wined3d_parent_ops, &buffer))) - { - ERR("Failed to create index buffer, hr %#lx.\n", hr); - return hr; - } - - if (device->index_buffer) - wined3d_buffer_decref(device->index_buffer); - device->index_buffer = buffer; - device->index_buffer_size = size; - device->index_buffer_pos = 0; - } - return D3D_OK; -} - static HRESULT d3d_device7_DrawIndexedPrimitive(IDirect3DDevice7 *iface, D3DPRIMITIVETYPE primitive_type, DWORD fvf, void *vertices, DWORD vertex_count, WORD *indices, DWORD index_count, DWORD flags) @@ -3613,9 +3576,6 @@ static HRESULT d3d_device7_DrawIndexedPrimitive(IDirect3DDevice7 *iface, HRESULT hr; UINT stride = get_flexible_vertex_size(fvf); UINT vtx_size = stride * vertex_count, idx_size = index_count * sizeof(*indices); - struct wined3d_map_desc wined3d_map_desc; - struct wined3d_box wined3d_box = {0}; - struct wined3d_resource *ib; UINT vb_pos, ib_pos; TRACE("iface %p, primitive_type %#x, fvf %#lx, vertices %p, vertex_count %lu, " @@ -3635,27 +3595,14 @@ static HRESULT d3d_device7_DrawIndexedPrimitive(IDirect3DDevice7 *iface, &device->vertex_buffer, vertices, vtx_size, stride, &vb_pos))) goto done; - hr = d3d_device_prepare_index_buffer(device, idx_size); - if (FAILED(hr)) - goto done; - ib_pos = device->index_buffer_pos; - if (device->index_buffer_size - idx_size < ib_pos) - ib_pos = 0; - - wined3d_box.left = ib_pos; - wined3d_box.right = ib_pos + idx_size; - ib = wined3d_buffer_get_resource(device->index_buffer); - if (FAILED(hr = wined3d_resource_map(ib, 0, &wined3d_map_desc, &wined3d_box, - WINED3D_MAP_WRITE | (ib_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD)))) + if (FAILED(hr = wined3d_streaming_buffer_upload(device->wined3d_device, + &device->index_buffer, indices, idx_size, sizeof(*indices), &ib_pos))) goto done; - memcpy(wined3d_map_desc.data, indices, idx_size); - wined3d_resource_unmap(ib, 0); - device->index_buffer_pos = ib_pos + idx_size; hr = wined3d_stateblock_set_stream_source(device->state, 0, device->vertex_buffer.buffer, 0, stride); if (FAILED(hr)) goto done; - wined3d_stateblock_set_index_buffer(device->state, device->index_buffer, WINED3DFMT_R16_UINT); + wined3d_stateblock_set_index_buffer(device->state, device->index_buffer.buffer, WINED3DFMT_R16_UINT); wined3d_stateblock_set_vertex_declaration(device->state, ddraw_find_decl(device->ddraw, fvf)); wined3d_device_context_set_primitive_type(device->immediate_context, @@ -4043,9 +3990,6 @@ static HRESULT d3d_device7_DrawIndexedPrimitiveStrided(IDirect3DDevice7 *iface, UINT vtx_dst_stride = get_flexible_vertex_size(fvf); UINT vtx_dst_size = vertex_count * vtx_dst_stride; UINT idx_size = index_count * sizeof(WORD); - struct wined3d_map_desc wined3d_map_desc; - struct wined3d_box wined3d_box = {0}; - struct wined3d_resource *ib; void *dst_data; UINT vb_pos; UINT ib_pos; @@ -4069,27 +4013,14 @@ static HRESULT d3d_device7_DrawIndexedPrimitiveStrided(IDirect3DDevice7 *iface, pack_strided_data(dst_data, vertex_count, strided_data, fvf); wined3d_streaming_buffer_unmap(&device->vertex_buffer); - hr = d3d_device_prepare_index_buffer(device, idx_size); - if (FAILED(hr)) - goto done; - ib_pos = device->index_buffer_pos; - if (device->index_buffer_size - idx_size < ib_pos) - ib_pos = 0; - - wined3d_box.left = ib_pos; - wined3d_box.right = ib_pos + idx_size; - ib = wined3d_buffer_get_resource(device->index_buffer); - if (FAILED(hr = wined3d_resource_map(ib, 0, &wined3d_map_desc, &wined3d_box, - WINED3D_MAP_WRITE | (ib_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD)))) + if (FAILED(hr = wined3d_streaming_buffer_upload(device->wined3d_device, + &device->index_buffer, indices, idx_size, sizeof(WORD), &ib_pos))) goto done; - memcpy(wined3d_map_desc.data, indices, idx_size); - wined3d_resource_unmap(ib, 0); - device->index_buffer_pos = ib_pos + idx_size; hr = wined3d_stateblock_set_stream_source(device->state, 0, device->vertex_buffer.buffer, 0, vtx_dst_stride); if (FAILED(hr)) goto done; - wined3d_stateblock_set_index_buffer(device->state, device->index_buffer, WINED3DFMT_R16_UINT); + wined3d_stateblock_set_index_buffer(device->state, device->index_buffer.buffer, WINED3DFMT_R16_UINT); wined3d_stateblock_set_vertex_declaration(device->state, ddraw_find_decl(device->ddraw, fvf)); wined3d_device_context_set_primitive_type(device->immediate_context, @@ -4291,7 +4222,6 @@ static HRESULT d3d_device7_DrawIndexedPrimitiveVB(IDirect3DDevice7 *iface, struct wined3d_resource *wined3d_resource; struct wined3d_map_desc wined3d_map_desc; struct wined3d_box wined3d_box = {0}; - struct wined3d_resource *ib; HRESULT hr; UINT ib_pos; @@ -4338,34 +4268,15 @@ static HRESULT d3d_device7_DrawIndexedPrimitiveVB(IDirect3DDevice7 *iface, wined3d_stateblock_set_vertex_declaration(device->state, vb_impl->wined3d_declaration); - hr = d3d_device_prepare_index_buffer(device, index_count * sizeof(WORD)); - if (FAILED(hr)) - { - wined3d_mutex_unlock(); - return hr; - } - ib_pos = device->index_buffer_pos; - - if (device->index_buffer_size - index_count * sizeof(WORD) < ib_pos) - ib_pos = 0; - - /* Copy the index stream into the index buffer. */ - wined3d_box.left = ib_pos; - wined3d_box.right = ib_pos + index_count * sizeof(WORD); - ib = wined3d_buffer_get_resource(device->index_buffer); - if (FAILED(hr = wined3d_resource_map(ib, 0, &wined3d_map_desc, &wined3d_box, - WINED3D_MAP_WRITE | (ib_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD)))) + if (FAILED(hr = wined3d_streaming_buffer_upload(device->wined3d_device, + &device->index_buffer, indices, index_count * sizeof(WORD), sizeof(WORD), &ib_pos))) { - ERR("Failed to map buffer, hr %#lx.\n", hr); wined3d_mutex_unlock(); return hr; } - memcpy(wined3d_map_desc.data, indices, index_count * sizeof(WORD)); - wined3d_resource_unmap(ib, 0); - device->index_buffer_pos = ib_pos + index_count * sizeof(WORD); /* Set the index stream */ - wined3d_stateblock_set_index_buffer(device->state, device->index_buffer, WINED3DFMT_R16_UINT); + wined3d_stateblock_set_index_buffer(device->state, device->index_buffer.buffer, WINED3DFMT_R16_UINT); /* Set the vertex stream source */ if (FAILED(hr = wined3d_stateblock_set_stream_source(device->state, @@ -6944,6 +6855,7 @@ static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw, c wined3d_stateblock_incref(ddraw->state); wined3d_streaming_buffer_init(&device->vertex_buffer, WINED3D_BIND_VERTEX_BUFFER); + wined3d_streaming_buffer_init(&device->index_buffer, WINED3D_BIND_INDEX_BUFFER); /* Render to the back buffer */ rtv = ddraw_surface_get_rendertarget_view(target);
1
0
0
0
Anton Baskanov : ddraw: Use the wined3d_streaming_buffer helpers to manage the streaming vertex buffer.
by Alexandre Julliard
24 Nov '22
24 Nov '22
Module: wine Branch: master Commit: e359c1466a964e9511d25e9010a4b70a65c2dbd1 URL:
https://gitlab.winehq.org/wine/wine/-/commit/e359c1466a964e9511d25e9010a4b7…
Author: Anton Baskanov <baskanov(a)gmail.com> Date: Fri Oct 21 15:12:24 2022 +0700 ddraw: Use the wined3d_streaming_buffer helpers to manage the streaming vertex buffer. --- dlls/ddraw/ddraw_private.h | 4 +- dlls/ddraw/device.c | 161 ++++++++------------------------------------- 2 files changed, 28 insertions(+), 137 deletions(-)
1
0
0
0
Anton Baskanov : wined3d: Factor out and expose functions to map/unmap wined3d_streaming_buffer.
by Alexandre Julliard
24 Nov '22
24 Nov '22
Module: wine Branch: master Commit: ef127f12435a43f0f82d8256f93b5823aeee3957 URL:
https://gitlab.winehq.org/wine/wine/-/commit/ef127f12435a43f0f82d8256f93b58…
Author: Anton Baskanov <baskanov(a)gmail.com> Date: Fri Oct 21 14:22:03 2022 +0700 wined3d: Factor out and expose functions to map/unmap wined3d_streaming_buffer. --- dlls/wined3d/buffer.c | 31 +++++++++++++++++++++++++------ dlls/wined3d/wined3d.spec | 2 ++ include/wine/wined3d.h | 4 ++++ 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c index 1a953f8e218..fca7f2916b7 100644 --- a/dlls/wined3d/buffer.c +++ b/dlls/wined3d/buffer.c @@ -1685,8 +1685,9 @@ static HRESULT wined3d_streaming_buffer_prepare(struct wined3d_device *device, return hr; } -HRESULT CDECL wined3d_streaming_buffer_upload(struct wined3d_device *device, struct wined3d_streaming_buffer *buffer, - const void *data, unsigned int size, unsigned int stride, unsigned int *ret_pos) +HRESULT CDECL wined3d_streaming_buffer_map(struct wined3d_device *device, + struct wined3d_streaming_buffer *buffer, unsigned int size, unsigned int stride, + unsigned int *ret_pos, void **ret_data) { unsigned int map_flags = WINED3D_MAP_WRITE; struct wined3d_resource *resource; @@ -1695,8 +1696,8 @@ HRESULT CDECL wined3d_streaming_buffer_upload(struct wined3d_device *device, str struct wined3d_box box; HRESULT hr; - TRACE("device %p, buffer %p, data %p, size %u, stride %u, ret_pos %p.\n", - device, buffer, data, size, stride, ret_pos); + TRACE("device %p, buffer %p, size %u, stride %u, ret_pos %p, ret_data %p.\n", + device, buffer, size, stride, ret_pos, ret_data); if (FAILED(hr = wined3d_streaming_buffer_prepare(device, buffer, size))) return hr; @@ -1719,10 +1720,28 @@ HRESULT CDECL wined3d_streaming_buffer_upload(struct wined3d_device *device, str wined3d_box_set(&box, pos, 0, pos + size, 1, 0, 1); if (SUCCEEDED(hr = wined3d_resource_map(resource, 0, &map_desc, &box, map_flags))) { - memcpy(map_desc.data, data, size); - wined3d_resource_unmap(resource, 0); *ret_pos = pos; + *ret_data = map_desc.data; buffer->pos = pos + size; } return hr; } + +void CDECL wined3d_streaming_buffer_unmap(struct wined3d_streaming_buffer *buffer) +{ + wined3d_resource_unmap(&buffer->buffer->resource, 0); +} + +HRESULT CDECL wined3d_streaming_buffer_upload(struct wined3d_device *device, struct wined3d_streaming_buffer *buffer, + const void *data, unsigned int size, unsigned int stride, unsigned int *ret_pos) +{ + void *dst_data; + HRESULT hr; + + if (SUCCEEDED(hr = wined3d_streaming_buffer_map(device, buffer, size, stride, ret_pos, &dst_data))) + { + memcpy(dst_data, data, size); + wined3d_streaming_buffer_unmap(buffer); + } + return hr; +} diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index e6126faf838..827ac295ddc 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -260,6 +260,8 @@ @ cdecl wined3d_stateblock_set_vs_consts_f(ptr long long ptr) @ cdecl wined3d_stateblock_set_vs_consts_i(ptr long long ptr) +@ cdecl wined3d_streaming_buffer_map(ptr ptr long long ptr ptr) +@ cdecl wined3d_streaming_buffer_unmap(ptr) @ cdecl wined3d_streaming_buffer_upload(ptr ptr ptr long long ptr) @ cdecl wined3d_swapchain_create(ptr ptr ptr ptr ptr ptr) diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index a18dcda45be..8ec397b73a5 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2788,6 +2788,10 @@ HRESULT __cdecl wined3d_stateblock_set_vs_consts_f(struct wined3d_stateblock *st HRESULT __cdecl wined3d_stateblock_set_vs_consts_i(struct wined3d_stateblock *stateblock, unsigned int start_idx, unsigned int count, const struct wined3d_ivec4 *constants); +HRESULT __cdecl wined3d_streaming_buffer_map(struct wined3d_device *device, + struct wined3d_streaming_buffer *buffer, unsigned int size, unsigned int stride, + unsigned int *ret_pos, void **ret_data); +void __cdecl wined3d_streaming_buffer_unmap(struct wined3d_streaming_buffer *buffer); HRESULT __cdecl wined3d_streaming_buffer_upload(struct wined3d_device *device, struct wined3d_streaming_buffer *buffer, const void *data, unsigned int size, unsigned int stride, unsigned int *pos);
1
0
0
0
Bartosz Kosiorek : gdiplus: Add GdipSetCustomLineCapStrokeCaps implementation and usage.
by Alexandre Julliard
23 Nov '22
23 Nov '22
Module: wine Branch: master Commit: e0f32f53d575cdffd0f35d39d97a941281e3e23d URL:
https://gitlab.winehq.org/wine/wine/-/commit/e0f32f53d575cdffd0f35d39d97a94…
Author: Bartosz Kosiorek <gang65(a)poczta.onet.pl> Date: Fri Nov 18 16:50:04 2022 +0100 gdiplus: Add GdipSetCustomLineCapStrokeCaps implementation and usage. --- dlls/gdiplus/customlinecap.c | 16 ++++++++-------- dlls/gdiplus/gdiplus_private.h | 2 ++ dlls/gdiplus/graphicspath.c | 2 +- dlls/gdiplus/tests/customlinecap.c | 28 ++++++++++++++++++++++++++++ 4 files changed, 39 insertions(+), 9 deletions(-) diff --git a/dlls/gdiplus/customlinecap.c b/dlls/gdiplus/customlinecap.c index 306c4db242b..f35fea90eba 100644 --- a/dlls/gdiplus/customlinecap.c +++ b/dlls/gdiplus/customlinecap.c @@ -97,6 +97,8 @@ static GpStatus init_custom_linecap(GpCustomLineCap *cap, GpPathData *pathdata, cap->inset = base_inset; cap->basecap = basecap; + cap->strokeStartCap = LineCapFlat; + cap->strokeEndCap = LineCapFlat; cap->join = LineJoinMiter; cap->scale = 1.0; @@ -177,19 +179,17 @@ GpStatus WINGDIPAPI GdipGetCustomLineCapWidthScale(GpCustomLineCap* custom, } GpStatus WINGDIPAPI GdipSetCustomLineCapStrokeCaps(GpCustomLineCap* custom, - GpLineCap start, GpLineCap end) + GpLineCap startcap, GpLineCap endcap) { - static int calls; + TRACE("(%p,%u,%u)\n", custom, startcap, endcap); - TRACE("(%p,%u,%u)\n", custom, start, end); - - if(!custom) + if(!custom || startcap > LineCapTriangle || endcap > LineCapTriangle) return InvalidParameter; - if(!(calls++)) - FIXME("not implemented\n"); + custom->strokeStartCap = startcap; + custom->strokeEndCap = endcap; - return NotImplemented; + return Ok; } GpStatus WINGDIPAPI GdipSetCustomLineCapBaseCap(GpCustomLineCap* custom, diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h index baae159d7f9..c68fdedb0b8 100644 --- a/dlls/gdiplus/gdiplus_private.h +++ b/dlls/gdiplus/gdiplus_private.h @@ -353,6 +353,8 @@ struct GpCustomLineCap{ BOOL fill; /* TRUE for fill, FALSE for stroke */ GpLineCap basecap; /* cap used together with customLineCap */ REAL inset; /* distance between line end and cap beginning */ + GpLineCap strokeStartCap; + GpLineCap strokeEndCap; GpLineJoin join; /* joins used for drawing custom cap*/ REAL scale; }; diff --git a/dlls/gdiplus/graphicspath.c b/dlls/gdiplus/graphicspath.c index 8bb835c1ca1..fdb7dd24906 100644 --- a/dlls/gdiplus/graphicspath.c +++ b/dlls/gdiplus/graphicspath.c @@ -2145,7 +2145,7 @@ static void add_anchor(const GpPointF *endpoint, const GpPointF *nextpoint, if ((custom->pathdata.Types[custom->pathdata.Count - 1] & PathPointTypeCloseSubpath) == PathPointTypeCloseSubpath) widen_closed_figure(tmp_points, 0, custom->pathdata.Count - 1, pen, pen_width, last_point); else - widen_open_figure(tmp_points, 0, custom->pathdata.Count - 1, pen, pen_width, LineCapFlat, LineCapFlat, last_point); + widen_open_figure(tmp_points, 0, custom->pathdata.Count - 1, pen, pen_width, custom->strokeEndCap, custom->strokeStartCap, last_point); } else { diff --git a/dlls/gdiplus/tests/customlinecap.c b/dlls/gdiplus/tests/customlinecap.c index 89323040ad1..4ff090ddce0 100644 --- a/dlls/gdiplus/tests/customlinecap.c +++ b/dlls/gdiplus/tests/customlinecap.c @@ -380,6 +380,33 @@ static void test_captype(void) GdipDeleteCustomLineCap((GpCustomLineCap*)arrowcap); } +static void test_strokecap(void) +{ + GpCustomLineCap *cap; + GpStatus stat; + GpPath *path; + + /* default cap */ + stat = GdipCreatePath(FillModeAlternate, &path); + ok(stat == Ok, "Failed to create path, %d\n", stat); + stat = GdipAddPathRectangle(path, 5.0, 5.0, 10.0, 10.0); + ok(stat == Ok, "AddPathRectangle failed, %d\n", stat); + + stat = GdipCreateCustomLineCap(NULL, path, LineCapFlat, 0.0, &cap); + ok(stat == Ok, "Failed to create cap, %d\n", stat); + + stat = GdipSetCustomLineCapStrokeCaps((GpCustomLineCap*)cap, LineCapSquare, LineCapFlat); + ok(stat == Ok, "Unexpected return code, %d\n", stat); + + stat = GdipSetCustomLineCapStrokeCaps((GpCustomLineCap*)cap, LineCapSquareAnchor, LineCapFlat); + ok(stat == InvalidParameter, "Unexpected return code, %d\n", stat); + + stat = GdipSetCustomLineCapStrokeCaps((GpCustomLineCap*)cap, LineCapFlat, LineCapSquareAnchor); + ok(stat == InvalidParameter, "Unexpected return code, %d\n", stat); + GdipDeleteCustomLineCap(cap); + GdipDeletePath(path); +} + START_TEST(customlinecap) { struct GdiplusStartupInput gdiplusStartupInput; @@ -405,6 +432,7 @@ START_TEST(customlinecap) test_scale(); test_create_adjustable_cap(); test_captype(); + test_strokecap(); GdiplusShutdown(gdiplusToken); }
1
0
0
0
Bartosz Kosiorek : gdiplus: Fix shape of CustomLineCap created by GdipCreateAdjustableArrowCap.
by Alexandre Julliard
23 Nov '22
23 Nov '22
Module: wine Branch: master Commit: cd17de88279e23ccd0b20c7d50b1b35dd8297e39 URL:
https://gitlab.winehq.org/wine/wine/-/commit/cd17de88279e23ccd0b20c7d50b1b3…
Author: Bartosz Kosiorek <gang65(a)poczta.onet.pl> Date: Wed Nov 16 23:19:46 2022 +0100 gdiplus: Fix shape of CustomLineCap created by GdipCreateAdjustableArrowCap. --- dlls/gdiplus/customlinecap.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dlls/gdiplus/customlinecap.c b/dlls/gdiplus/customlinecap.c index c05aecae29a..306c4db242b 100644 --- a/dlls/gdiplus/customlinecap.c +++ b/dlls/gdiplus/customlinecap.c @@ -305,18 +305,18 @@ static void arrowcap_update_path(GpAdjustableArrowCap *cap) points[2].X = cap->width / 2.0; points[2].Y = -cap->height; points[3].X = 0.0; - points[3].Y = -cap->height - cap->middle_inset; + points[3].Y = -cap->height + cap->middle_inset; } else { memcpy(cap->cap.pathdata.Types, types_unfilled, sizeof(types_unfilled)); cap->cap.pathdata.Count = 3; - points[0].X = -cap->width / 4.0; - points[0].Y = -cap->height / 2.0; + points[0].X = -cap->width / 2.0; + points[0].Y = -cap->height; points[1].X = 0.0; points[1].Y = 0.0; - points[2].X = cap->width / 4.0; - points[2].Y = -cap->height / 2.0; + points[2].X = cap->width / 2.0; + points[2].Y = -cap->height; } if (cap->width == 0.0)
1
0
0
0
Bartosz Kosiorek : gdiplus: Add support for widen path with GpCustomLineCap.
by Alexandre Julliard
23 Nov '22
23 Nov '22
Module: wine Branch: master Commit: 1271ae3ebdf9b5b6e39c5688b64c8a3f0a98b8d4 URL:
https://gitlab.winehq.org/wine/wine/-/commit/1271ae3ebdf9b5b6e39c5688b64c8a…
Author: Bartosz Kosiorek <gang65(a)poczta.onet.pl> Date: Mon Nov 7 17:36:05 2022 +0100 gdiplus: Add support for widen path with GpCustomLineCap. Wine-Bug:
https://bugs.winehq.org/show_bug.cgi?id=45273
--- dlls/gdiplus/gdiplus_private.h | 4 +- dlls/gdiplus/graphicspath.c | 81 ++++++++++++++++++++++++++++++++++++--- dlls/gdiplus/tests/graphicspath.c | 13 +++++++ 3 files changed, 90 insertions(+), 8 deletions(-) diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h index 77b35659946..baae159d7f9 100644 --- a/dlls/gdiplus/gdiplus_private.h +++ b/dlls/gdiplus/gdiplus_private.h @@ -352,8 +352,8 @@ struct GpCustomLineCap{ GpPathData pathdata; BOOL fill; /* TRUE for fill, FALSE for stroke */ GpLineCap basecap; /* cap used together with customLineCap */ - REAL inset; /* how much to adjust the end of the line */ - GpLineJoin join; + REAL inset; /* distance between line end and cap beginning */ + GpLineJoin join; /* joins used for drawing custom cap*/ REAL scale; }; diff --git a/dlls/gdiplus/graphicspath.c b/dlls/gdiplus/graphicspath.c index e24053004e0..8bb835c1ca1 100644 --- a/dlls/gdiplus/graphicspath.c +++ b/dlls/gdiplus/graphicspath.c @@ -1982,9 +1982,17 @@ static void widen_cap(const GpPointF *endpoint, const GpPointF *nextpoint, } } +static void widen_open_figure(const GpPointF *points, int start, int end, + GpPen *pen, REAL pen_width, GpLineCap start_cap, + GpLineCap end_cap, path_list_node_t **last_point); + +static void widen_closed_figure(const GpPointF *points, int start, int end, + GpPen *pen, REAL pen_width, path_list_node_t **last_point); + static void add_anchor(const GpPointF *endpoint, const GpPointF *nextpoint, - REAL pen_width, GpLineCap cap, GpCustomLineCap *custom, path_list_node_t **last_point) + GpPen *pen, GpLineCap cap, GpCustomLineCap *custom, path_list_node_t **last_point) { + REAL pen_width = max(pen->width, 2.0); switch (cap) { default: @@ -2091,6 +2099,68 @@ static void add_anchor(const GpPointF *endpoint, const GpPointF *nextpoint, endpoint->Y + perp_dy, PathPointTypeLine); break; } + case LineCapCustom: + { + REAL segment_dy = nextpoint->Y - endpoint->Y; + REAL segment_dx = nextpoint->X - endpoint->X; + REAL segment_length = sqrtf(segment_dy * segment_dy + segment_dx * segment_dx); + REAL posx, posy; + REAL perp_dx, perp_dy; + REAL sina, cosa; + GpPointF *tmp_points; + + if(!custom) + break; + + if (custom->type == CustomLineCapTypeAdjustableArrow) + { + GpAdjustableArrowCap *arrow = (GpAdjustableArrowCap *)custom; + TRACE("GpAdjustableArrowCap middle_inset: %f height: %f width: %f\n", + arrow->middle_inset, arrow->height, arrow->width); + } + else + TRACE("GpCustomLineCap fill: %d basecap: %d inset: %f join: %d scale: %f pen_width:%f\n", + custom->fill, custom->basecap, custom->inset, custom->join, custom->scale, pen_width); + + /* Coordination where cap needs to be drawn */ + posx = endpoint->X - pen_width * segment_dx / segment_length; + posy = endpoint->Y - pen_width * segment_dy / segment_length; + + sina = -pen_width * custom->scale * segment_dx / segment_length; + cosa = pen_width * custom->scale * segment_dy / segment_length; + + if (!custom->fill) + { + tmp_points = heap_alloc_zero(custom->pathdata.Count * sizeof(GpPoint)); + if (!tmp_points) { + ERR("Out of memory\n"); + return; + } + + for (INT i = 0; i < custom->pathdata.Count; i++) + { + tmp_points[i].X = posx + custom->pathdata.Points[i].X * cosa + (custom->pathdata.Points[i].Y - 1.0) * sina; + tmp_points[i].Y = posy + custom->pathdata.Points[i].X * sina - (custom->pathdata.Points[i].Y - 1.0) * cosa; + } + if ((custom->pathdata.Types[custom->pathdata.Count - 1] & PathPointTypeCloseSubpath) == PathPointTypeCloseSubpath) + widen_closed_figure(tmp_points, 0, custom->pathdata.Count - 1, pen, pen_width, last_point); + else + widen_open_figure(tmp_points, 0, custom->pathdata.Count - 1, pen, pen_width, LineCapFlat, LineCapFlat, last_point); + } + else + { + for (INT i = 0; i < custom->pathdata.Count; i++) + { + /* rotation of CustomCap according to line */ + perp_dx = custom->pathdata.Points[i].X * cosa + (custom->pathdata.Points[i].Y - 1.0) * sina; + perp_dy = custom->pathdata.Points[i].X * sina - (custom->pathdata.Points[i].Y - 1.0) * cosa; + *last_point = add_path_list_node(*last_point, posx + perp_dx, + posy + perp_dy, custom->pathdata.Types[i]); + } + } + /* FIXME: The line should be adjusted by the inset value of the custom cap. */ + break; + } } (*last_point)->type |= PathPointTypeCloseSubpath; @@ -2335,16 +2405,15 @@ GpStatus WINGDIPAPI GdipWidenPath(GpPath *path, GpPen *pen, GpMatrix *matrix, if (status == Ok) { - REAL anchor_pen_width = max(pen->width, 2.0); REAL pen_width = (pen->unit == UnitWorld) ? max(pen->width, 1.0) : pen->width; BYTE *types = flat_path->pathdata.Types; last_point = points; - if (pen->endcap > LineCapDiamondAnchor) + if (pen->endcap > LineCapDiamondAnchor && pen->endcap != LineCapCustom) FIXME("unimplemented end cap %x\n", pen->endcap); - if (pen->startcap > LineCapDiamondAnchor) + if (pen->startcap > LineCapDiamondAnchor && pen->startcap != LineCapCustom) FIXME("unimplemented start cap %x\n", pen->startcap); if (pen->dashcap != DashCapFlat) @@ -2395,12 +2464,12 @@ GpStatus WINGDIPAPI GdipWidenPath(GpPath *path, GpPen *pen, GpMatrix *matrix, if (pen->startcap & LineCapAnchorMask) add_anchor(&flat_path->pathdata.Points[subpath_start], &flat_path->pathdata.Points[subpath_start+1], - anchor_pen_width, pen->startcap, pen->customstart, &last_point); + pen, pen->startcap, pen->customstart, &last_point); if (pen->endcap & LineCapAnchorMask) add_anchor(&flat_path->pathdata.Points[i], &flat_path->pathdata.Points[i-1], - anchor_pen_width, pen->endcap, pen->customend, &last_point); + pen, pen->endcap, pen->customend, &last_point); } } diff --git a/dlls/gdiplus/tests/graphicspath.c b/dlls/gdiplus/tests/graphicspath.c index 07e6dd166ad..ab1e7cb2fda 100644 --- a/dlls/gdiplus/tests/graphicspath.c +++ b/dlls/gdiplus/tests/graphicspath.c @@ -1682,9 +1682,12 @@ static void test_widen_cap(void) { LineCapSquareAnchor, 10.0, widenline_capsquareanchor_dashed_path, ARRAY_SIZE(widenline_capsquareanchor_dashed_path), TRUE }, }; + + GpAdjustableArrowCap *arrowcap; GpStatus status; GpPath *path; GpPen *pen; + int i; status = GdipCreatePath(FillModeAlternate, &path); @@ -1749,6 +1752,16 @@ static void test_widen_cap(void) expect(Ok, status); ok_path_fudge(path, widenline_capsquareanchor_multifigure_path, ARRAY_SIZE(widenline_capsquareanchor_multifigure_path), FALSE, 0.000005); + + status = GdipCreateAdjustableArrowCap(4.0, 4.0, TRUE, &arrowcap); + ok(status == Ok, "Failed to create adjustable cap, %d\n", status); + status = GdipSetAdjustableArrowCapMiddleInset(arrowcap, 1.0); + ok(status == Ok, "Failed to set middle inset inadjustable cap, %d\n", status); + status = GdipSetPenCustomEndCap(pen, (GpCustomLineCap*)arrowcap); + ok(status == Ok, "Failed to create custom end cap, %d\n", status); + status = GdipWidenPath(path, pen, NULL, FlatnessDefault); + expect(Ok, status); + GdipDeletePen(pen); GdipDeletePath(path);
1
0
0
0
← Newer
1
...
24
25
26
27
28
29
30
...
118
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
Results per page:
10
25
50
100
200