Wine-bug: https://bugs.winehq.org/show_bug.cgi?id=52196
-- v8: gdiplus: add GdipGetPenCompoundArray implementation gdiplus: add GdipGetPenCompoundCount implementation gdiplus: add GdipSetPenCompoundArray implementation
From: Bartosz Kosiorek gang65@poczta.onet.pl
Wine-bug: https://bugs.winehq.org/show_bug.cgi?id=52196 --- dlls/gdiplus/gdiplus_private.h | 2 ++ dlls/gdiplus/graphicspath.c | 3 +++ dlls/gdiplus/pen.c | 22 ++++++++++++++++++---- dlls/gdiplus/tests/pen.c | 12 +++++++++++- 4 files changed, 34 insertions(+), 5 deletions(-)
diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h index 03bfa5513cb..559944a770c 100644 --- a/dlls/gdiplus/gdiplus_private.h +++ b/dlls/gdiplus/gdiplus_private.h @@ -235,6 +235,8 @@ struct GpPen{ GpBrush *brush; GpPenAlignment align; GpMatrix transform; + REAL *compound_array; + UINT compound_array_size; };
struct GpGraphics{ diff --git a/dlls/gdiplus/graphicspath.c b/dlls/gdiplus/graphicspath.c index ce2666eedab..d98a5ae4bf6 100644 --- a/dlls/gdiplus/graphicspath.c +++ b/dlls/gdiplus/graphicspath.c @@ -2356,6 +2356,9 @@ GpStatus WINGDIPAPI GdipWidenPath(GpPath *path, GpPen *pen, GpMatrix *matrix, if (pen->align != PenAlignmentCenter) FIXME("unimplemented pen alignment %d\n", pen->align);
+ if (pen->compound_array_size != 0) + FIXME("unimplemented pen compoundline. Solid line will be drawn instead: %d\n", pen->compound_array_size); + for (i=0; i < flat_path->pathdata.Count; i++) { if ((types[i]&PathPointTypePathTypeMask) == PathPointTypeStart) diff --git a/dlls/gdiplus/pen.c b/dlls/gdiplus/pen.c index 32579adc484..1b23de5fe0f 100644 --- a/dlls/gdiplus/pen.c +++ b/dlls/gdiplus/pen.c @@ -171,6 +171,8 @@ GpStatus WINGDIPAPI GdipCreatePen2(GpBrush *brush, REAL width, GpUnit unit, gp_pen->offset = 0.0; gp_pen->customstart = NULL; gp_pen->customend = NULL; + gp_pen->compound_array = NULL; + gp_pen->compound_array_size = 0; GdipSetMatrixElements(&gp_pen->transform, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
if(!((gp_pen->unit == UnitWorld) || (gp_pen->unit == UnitPixel))) { @@ -198,6 +200,7 @@ GpStatus WINGDIPAPI GdipDeletePen(GpPen *pen) GdipDeleteBrush(pen->brush); GdipDeleteCustomLineCap(pen->customstart); GdipDeleteCustomLineCap(pen->customend); + heap_free(pen->compound_array); heap_free(pen->dashes); heap_free(pen);
@@ -533,15 +536,26 @@ GpStatus WINGDIPAPI GdipGetPenCompoundCount(GpPen *pen, INT *count) return NotImplemented; }
-GpStatus WINGDIPAPI GdipSetPenCompoundArray(GpPen *pen, GDIPCONST REAL *dash, +GpStatus WINGDIPAPI GdipSetPenCompoundArray(GpPen *pen, GDIPCONST REAL *compoundarray, INT count) { - FIXME("(%p, %p, %i): stub\n", pen, dash, count); + REAL previousValue; + TRACE("(%p, %p, %i)\n", pen, compoundarray, count);
- if (!pen || !dash || count < 2 || count%2 == 1) + if (!pen || !compoundarray || count < 2 || count%2 == 1 || *compoundarray < 0.0 || *compoundarray > 1.0) return InvalidParameter; + previousValue = *compoundarray;
- return NotImplemented; + for(size_t i = 1; i<count; i++) + { + if ((compoundarray[i] < previousValue) || (compoundarray[i] > 1.0)) + return InvalidParameter; + previousValue = compoundarray[i]; + } + pen->compound_array = realloc(pen->compound_array, count * sizeof(REAL)); + memcpy(pen->compound_array, compoundarray, count * sizeof(REAL)); + pen->compound_array_size = count; + return Ok; }
GpStatus WINGDIPAPI GdipSetPenCustomEndCap(GpPen *pen, GpCustomLineCap* customCap) diff --git a/dlls/gdiplus/tests/pen.c b/dlls/gdiplus/tests/pen.c index cd3e45f9b41..d7dca6656f5 100644 --- a/dlls/gdiplus/tests/pen.c +++ b/dlls/gdiplus/tests/pen.c @@ -351,6 +351,9 @@ static void test_compoundarray(void) GpStatus status; GpPen *pen; static const REAL testvalues[] = {0.2, 0.4, 0.6, 0.8}; + static const REAL notSortedValues[] = {0.2, 0.6, 0.4, 0.8}; + static const REAL negativeValues[] = {-1.2, 0.4, 0.6, 2.8}; + static const REAL tooLargeValues[] = {0.2, 0.4, 0.6, 2.8}; INT count;
status = GdipSetPenCompoundArray(NULL, testvalues, 4); @@ -382,8 +385,15 @@ todo_wine { status = GdipSetPenCompoundArray(pen, testvalues, -2); expect(InvalidParameter, status);
+ status = GdipSetPenCompoundArray(pen, notSortedValues, 4); + expect(InvalidParameter, status); + status = GdipSetPenCompoundArray(pen, negativeValues, 4); + expect(InvalidParameter, status); + status = GdipSetPenCompoundArray(pen, tooLargeValues, 4); + expect(InvalidParameter, status); + status = GdipSetPenCompoundArray(pen, testvalues, 4); - todo_wine expect(Ok, status); + expect(Ok, status); status = GdipSetPenCompoundArray(pen, NULL, 0); expect(InvalidParameter, status);
From: Bartosz Kosiorek gang65@poczta.onet.pl
Wine-bug: https://bugs.winehq.org/show_bug.cgi?id=52196 --- dlls/gdiplus/pen.c | 6 +++--- dlls/gdiplus/tests/pen.c | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/dlls/gdiplus/pen.c b/dlls/gdiplus/pen.c index 1b23de5fe0f..688cb13a23c 100644 --- a/dlls/gdiplus/pen.c +++ b/dlls/gdiplus/pen.c @@ -528,12 +528,12 @@ GpStatus WINGDIPAPI GdipSetPenColor(GpPen *pen, ARGB argb)
GpStatus WINGDIPAPI GdipGetPenCompoundCount(GpPen *pen, INT *count) { - FIXME("(%p, %p): stub\n", pen, count); + TRACE("(%p, %p)\n", pen, count);
if (!pen || !count) return InvalidParameter; - - return NotImplemented; + *count = pen->compound_array_size; + return Ok; }
GpStatus WINGDIPAPI GdipSetPenCompoundArray(GpPen *pen, GDIPCONST REAL *compoundarray, diff --git a/dlls/gdiplus/tests/pen.c b/dlls/gdiplus/tests/pen.c index d7dca6656f5..545e27aa9b2 100644 --- a/dlls/gdiplus/tests/pen.c +++ b/dlls/gdiplus/tests/pen.c @@ -370,10 +370,9 @@ static void test_compoundarray(void)
count = 10; status = GdipGetPenCompoundCount(pen, &count); -todo_wine { expect(Ok, status); ok(count == 0, "Unexpected compound count %d\n", count); -} + status = GdipSetPenCompoundArray(pen, NULL, 0); expect(InvalidParameter, status); status = GdipSetPenCompoundArray(pen, NULL, 4);
From: Bartosz Kosiorek gang65@poczta.onet.pl
Wine-bug: https://bugs.winehq.org/show_bug.cgi?id=52196 --- dlls/gdiplus/gdiplus.spec | 2 +- dlls/gdiplus/pen.c | 14 +++++++++++++- dlls/gdiplus/tests/pen.c | 22 +++++++++++++++++++--- include/gdiplusflat.h | 1 + 4 files changed, 34 insertions(+), 5 deletions(-)
diff --git a/dlls/gdiplus/gdiplus.spec b/dlls/gdiplus/gdiplus.spec index 15d9b5d81e8..d4545abf319 100644 --- a/dlls/gdiplus/gdiplus.spec +++ b/dlls/gdiplus/gdiplus.spec @@ -334,7 +334,7 @@ 334 stdcall GdipGetPathWorldBoundsI(ptr ptr ptr ptr) 335 stdcall GdipGetPenBrushFill(ptr ptr) 336 stdcall GdipGetPenColor(ptr ptr) -337 stub GdipGetPenCompoundArray +337 stdcall GdipGetPenCompoundArray(ptr ptr long) 338 stdcall GdipGetPenCompoundCount(ptr ptr) 339 stdcall GdipGetPenCustomEndCap(ptr ptr) 340 stdcall GdipGetPenCustomStartCap(ptr ptr) diff --git a/dlls/gdiplus/pen.c b/dlls/gdiplus/pen.c index 688cb13a23c..c789a43cfe9 100644 --- a/dlls/gdiplus/pen.c +++ b/dlls/gdiplus/pen.c @@ -195,7 +195,8 @@ GpStatus WINGDIPAPI GdipDeletePen(GpPen *pen) { TRACE("(%p)\n", pen);
- if(!pen) return InvalidParameter; + if(!pen) + return InvalidParameter;
GdipDeleteBrush(pen->brush); GdipDeleteCustomLineCap(pen->customstart); @@ -526,6 +527,17 @@ GpStatus WINGDIPAPI GdipSetPenColor(GpPen *pen, ARGB argb) return GdipSetSolidFillColor(((GpSolidFill*)pen->brush), argb); }
+GpStatus WINGDIPAPI GdipGetPenCompoundArray(GpPen *pen, REAL *compoundarray, INT count) +{ + TRACE("(%p, %p, %i)\n", pen, compoundarray, count); + + if (!pen || !compoundarray || count > pen->compound_array_size) + return InvalidParameter; + if (pen->compound_array && count) + memcpy(compoundarray, pen->compound_array, count * sizeof(REAL)); + return Ok; +} + GpStatus WINGDIPAPI GdipGetPenCompoundCount(GpPen *pen, INT *count) { TRACE("(%p, %p)\n", pen, count); diff --git a/dlls/gdiplus/tests/pen.c b/dlls/gdiplus/tests/pen.c index 545e27aa9b2..2e0da329604 100644 --- a/dlls/gdiplus/tests/pen.c +++ b/dlls/gdiplus/tests/pen.c @@ -350,9 +350,10 @@ static void test_compoundarray(void) { GpStatus status; GpPen *pen; + REAL *returnvalues; static const REAL testvalues[] = {0.2, 0.4, 0.6, 0.8}; static const REAL notSortedValues[] = {0.2, 0.6, 0.4, 0.8}; - static const REAL negativeValues[] = {-1.2, 0.4, 0.6, 2.8}; + static const REAL negativeValues[] = {-1.2, 0.4, 0.6, 0.8}; static const REAL tooLargeValues[] = {0.2, 0.4, 0.6, 2.8}; INT count;
@@ -398,10 +399,25 @@ static void test_compoundarray(void)
count = 0; status = GdipGetPenCompoundCount(pen, &count); -todo_wine { expect(Ok, status); ok(count == 4, "Unexpected compound count %d\n", count); -} + + returnvalues = calloc(5, sizeof(REAL)); + // When count larger than stored array return error + status = GdipGetPenCompoundArray(pen, returnvalues, 40); + expect(InvalidParameter, status); + status = GdipGetPenCompoundArray(NULL, returnvalues, 4); + expect(InvalidParameter, status); + // When count is zero, it should do nothing + status = GdipGetPenCompoundArray(pen, returnvalues, 0); + expect(Ok, status); + ok(returnvalues[0] == 0.0, "Unexpected compound array %f\n", returnvalues[0]); + + status = GdipGetPenCompoundArray(pen, returnvalues, 4); + expect(Ok, status); + ok(memcmp(returnvalues, testvalues, 4 * sizeof(REAL)) == 0, "Unexpected compound array\n"); + + free(returnvalues); GdipDeletePen(pen); }
diff --git a/include/gdiplusflat.h b/include/gdiplusflat.h index 5c9600ed30b..10f4d435a85 100644 --- a/include/gdiplusflat.h +++ b/include/gdiplusflat.h @@ -629,6 +629,7 @@ GpStatus WINGDIPAPI GdipCreatePen2(GpBrush*,REAL,GpUnit,GpPen**); GpStatus WINGDIPAPI GdipDeletePen(GpPen*); GpStatus WINGDIPAPI GdipGetPenBrushFill(GpPen*,GpBrush**); GpStatus WINGDIPAPI GdipGetPenColor(GpPen*,ARGB*); +GpStatus WINGDIPAPI GdipGetPenCompoundArray(GpPen*,REAL*,INT); GpStatus WINGDIPAPI GdipGetPenCompoundCount(GpPen*,INT*); GpStatus WINGDIPAPI GdipGetPenCustomStartCap(GpPen*,GpCustomLineCap**); GpStatus WINGDIPAPI GdipGetPenCustomEndCap(GpPen*,GpCustomLineCap**);
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
23 TestBot errors prevented a full analysis of your patch. If the test caused the operating system (e.g. Windows) to crash or reboot you will probably have to modify it to avoid that. Other issues should be reported to the TestBot administrators.
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=125477
Your paranoid android.
=== w7u_2qxl (testbot log) ===
WineRunTask.pl:error: Could not copy the test executable to the VM: Unable to open '/home/testbot/var/jobs/125477/gdiplus_test.exe' for reading: No such file or directory WineRunTask.pl:error: BotError: The test VM has crashed, rebooted or lost connectivity (or the TestAgent server died) WineRunTask.pl:error: Giving up after 3 run(s)
=== w7u_adm (testbot log) ===
WineRunTask.pl:error: Could not copy the test executable to the VM: Unable to open '/home/testbot/var/jobs/125477/gdiplus_test.exe' for reading: No such file or directory WineRunTask.pl:error: BotError: The test VM has crashed, rebooted or lost connectivity (or the TestAgent server died) WineRunTask.pl:error: Giving up after 3 run(s)
=== w7u_el (testbot log) ===
WineRunTask.pl:error: Could not copy the test executable to the VM: Unable to open '/home/testbot/var/jobs/125477/gdiplus_test.exe' for reading: No such file or directory WineRunTask.pl:error: BotError: The test VM has crashed, rebooted or lost connectivity (or the TestAgent server died) WineRunTask.pl:error: Giving up after 3 run(s)
=== w8 (testbot log) ===
WineRunTask.pl:error: Could not copy the test executable to the VM: Unable to open '/home/testbot/var/jobs/125477/gdiplus_test.exe' for reading: No such file or directory WineRunTask.pl:error: BotError: The test VM has crashed, rebooted or lost connectivity (or the TestAgent server died) WineRunTask.pl:error: Giving up after 3 run(s)
=== w8adm (testbot log) ===
WineRunTask.pl:error: Could not copy the test executable to the VM: Unable to open '/home/testbot/var/jobs/125477/gdiplus_test.exe' for reading: No such file or directory WineRunTask.pl:error: BotError: The test VM has crashed, rebooted or lost connectivity (or the TestAgent server died) WineRunTask.pl:error: Giving up after 3 run(s)
=== w864 (testbot log) ===
WineRunTask.pl:error: Could not copy the test executable to the VM: Unable to open '/home/testbot/var/jobs/125477/gdiplus_test.exe' for reading: No such file or directory WineRunTask.pl:error: BotError: The test VM has crashed, rebooted or lost connectivity (or the TestAgent server died) WineRunTask.pl:error: Giving up after 3 run(s)
=== w1064v1507 (testbot log) ===
WineRunTask.pl:error: Could not copy the test executable to the VM: Unable to open '/home/testbot/var/jobs/125477/gdiplus_test.exe' for reading: No such file or directory WineRunTask.pl:error: BotError: The test VM has crashed, rebooted or lost connectivity (or the TestAgent server died) WineRunTask.pl:error: Giving up after 3 run(s)
=== w1064v1809 (testbot log) ===
WineRunTask.pl:error: Could not copy the test executable to the VM: Unable to open '/home/testbot/var/jobs/125477/gdiplus_test.exe' for reading: No such file or directory WineRunTask.pl:error: BotError: The test VM has crashed, rebooted or lost connectivity (or the TestAgent server died) WineRunTask.pl:error: Giving up after 3 run(s)
=== w1064 (testbot log) ===
WineRunTask.pl:error: Could not copy the test executable to the VM: Unable to open '/home/testbot/var/jobs/125477/gdiplus_test.exe' for reading: No such file or directory WineRunTask.pl:error: BotError: The test VM has crashed, rebooted or lost connectivity (or the TestAgent server died) WineRunTask.pl:error: Giving up after 3 run(s)
=== w1064_tsign (testbot log) ===
WineRunTask.pl:error: Could not copy the test executable to the VM: Unable to open '/home/testbot/var/jobs/125477/gdiplus_test.exe' for reading: No such file or directory WineRunTask.pl:error: BotError: The test VM has crashed, rebooted or lost connectivity (or the TestAgent server died) WineRunTask.pl:error: Giving up after 3 run(s)
=== w10pro64 (testbot log) ===
WineRunTask.pl:error: Could not copy the test executable to the VM: Unable to open '/home/testbot/var/jobs/125477/gdiplus_test.exe' for reading: No such file or directory WineRunTask.pl:error: BotError: The test VM has crashed, rebooted or lost connectivity (or the TestAgent server died) WineRunTask.pl:error: Giving up after 3 run(s)
=== w864 (testbot log) ===
WineRunTask.pl:error: Could not copy the test executable to the VM: Unable to open '/home/testbot/var/jobs/125477/gdiplus_test64.exe' for reading: No such file or directory WineRunTask.pl:error: BotError: The test VM has crashed, rebooted or lost connectivity (or the TestAgent server died) WineRunTask.pl:error: Giving up after 3 run(s)
=== w1064v1507 (testbot log) ===
WineRunTask.pl:error: Could not copy the test executable to the VM: Unable to open '/home/testbot/var/jobs/125477/gdiplus_test64.exe' for reading: No such file or directory WineRunTask.pl:error: BotError: The test VM has crashed, rebooted or lost connectivity (or the TestAgent server died) WineRunTask.pl:error: Giving up after 3 run(s)
=== w1064v1809 (testbot log) ===
WineRunTask.pl:error: Could not copy the test executable to the VM: Unable to open '/home/testbot/var/jobs/125477/gdiplus_test64.exe' for reading: No such file or directory WineRunTask.pl:error: BotError: The test VM has crashed, rebooted or lost connectivity (or the TestAgent server died) WineRunTask.pl:error: Giving up after 3 run(s)
=== w1064 (testbot log) ===
WineRunTask.pl:error: Could not copy the test executable to the VM: Unable to open '/home/testbot/var/jobs/125477/gdiplus_test64.exe' for reading: No such file or directory WineRunTask.pl:error: BotError: The test VM has crashed, rebooted or lost connectivity (or the TestAgent server died) WineRunTask.pl:error: Giving up after 3 run(s)
=== w1064_2qxl (testbot log) ===
WineRunTask.pl:error: Could not copy the test executable to the VM: Unable to open '/home/testbot/var/jobs/125477/gdiplus_test64.exe' for reading: No such file or directory WineRunTask.pl:error: BotError: The test VM has crashed, rebooted or lost connectivity (or the TestAgent server died) WineRunTask.pl:error: Giving up after 3 run(s)
=== w1064_adm (testbot log) ===
WineRunTask.pl:error: Could not copy the test executable to the VM: Unable to open '/home/testbot/var/jobs/125477/gdiplus_test64.exe' for reading: No such file or directory WineRunTask.pl:error: BotError: The test VM has crashed, rebooted or lost connectivity (or the TestAgent server died) WineRunTask.pl:error: Giving up after 3 run(s)
=== w1064_tsign (testbot log) ===
WineRunTask.pl:error: Could not copy the test executable to the VM: Unable to open '/home/testbot/var/jobs/125477/gdiplus_test64.exe' for reading: No such file or directory WineRunTask.pl:error: BotError: The test VM has crashed, rebooted or lost connectivity (or the TestAgent server died) WineRunTask.pl:error: Giving up after 3 run(s)
=== w10pro64 (testbot log) ===
WineRunTask.pl:error: Could not copy the test executable to the VM: Unable to open '/home/testbot/var/jobs/125477/gdiplus_test64.exe' for reading: No such file or directory WineRunTask.pl:error: BotError: The test VM has crashed, rebooted or lost connectivity (or the TestAgent server died) WineRunTask.pl:error: Giving up after 3 run(s)
=== w10pro64_en_AE_u8 (testbot log) ===
WineRunTask.pl:error: Could not copy the test executable to the VM: Unable to open '/home/testbot/var/jobs/125477/gdiplus_test64.exe' for reading: No such file or directory WineRunTask.pl:error: BotError: The test VM has crashed, rebooted or lost connectivity (or the TestAgent server died) WineRunTask.pl:error: Giving up after 3 run(s)
=== w10pro64_ar (testbot log) ===
WineRunTask.pl:error: Could not copy the test executable to the VM: Unable to open '/home/testbot/var/jobs/125477/gdiplus_test64.exe' for reading: No such file or directory WineRunTask.pl:error: BotError: The test VM has crashed, rebooted or lost connectivity (or the TestAgent server died) WineRunTask.pl:error: Giving up after 3 run(s)
=== w10pro64_ja (testbot log) ===
WineRunTask.pl:error: Could not copy the test executable to the VM: Unable to open '/home/testbot/var/jobs/125477/gdiplus_test64.exe' for reading: No such file or directory WineRunTask.pl:error: BotError: The test VM has crashed, rebooted or lost connectivity (or the TestAgent server died) WineRunTask.pl:error: Giving up after 3 run(s)
=== w10pro64_zh_CN (testbot log) ===
WineRunTask.pl:error: Could not copy the test executable to the VM: Unable to open '/home/testbot/var/jobs/125477/gdiplus_test64.exe' for reading: No such file or directory WineRunTask.pl:error: BotError: The test VM has crashed, rebooted or lost connectivity (or the TestAgent server died) WineRunTask.pl:error: Giving up after 3 run(s)
=== debian11 (build log) ===
Task: WineTest did not produce the win32 report
=== debian11 (build log) ===
Task: WineTest did not produce the wow32 report
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
1 TestBot errors prevented a full analysis of your patch. If the test caused the operating system (e.g. Windows) to crash or reboot you will probably have to modify it to avoid that. Other issues should be reported to the TestBot administrators.
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=125477
Your paranoid android.
=== w864 (testbot log) ===
WineRunTask.pl:error: Could not copy the test executable to the VM: Unable to open '/home/testbot/var/jobs/125477/gdiplus_test.exe' for reading: No such file or directory WineRunTask.pl:error: BotError: The test VM has crashed, rebooted or lost connectivity (or the TestAgent server died) WineRunTask.pl:error: Giving up after 3 run(s)