Wine-bug: https://bugs.winehq.org/show_bug.cgi?id=52196
-- v5: gdiplus: add GdipGetPenCompoundArray 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 | 20 ++++++++++++++++---- dlls/gdiplus/tests/pen.c | 12 +++++++++++- 4 files changed, 32 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..c5aa9e43f07 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,24 @@ 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 = *compoundarray; + 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;
- return NotImplemented; + for(size_t i = 1; i<count; i++) + { + if ((compoundarray[i] < previousValue) || (compoundarray[i] > 1.0)) + return InvalidParameter; + previousValue = compoundarray[i]; + } + 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 c5aa9e43f07..99eefdced6d 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 99eefdced6d..1d05c4b0da0 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..ca977e7e9dc 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, "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.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=125422
Your paranoid android.
=== debian11 (32 bit report) ===
gdiplus: Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x64a952d5).
=== debian11 (32 bit ar:MA report) ===
gdiplus: Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x64a952d5).
=== debian11 (32 bit de report) ===
gdiplus: Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x64a952d5).
=== debian11 (32 bit fr report) ===
gdiplus: Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x64a952d5).
=== debian11 (32 bit he:IL report) ===
gdiplus: Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x64a952d5).
=== debian11 (32 bit hi:IN report) ===
gdiplus: Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x64a952d5).
=== debian11 (32 bit ja:JP report) ===
gdiplus: Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x64a952d5).
=== debian11 (32 bit zh:CN report) ===
gdiplus: Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x64a952d5).
=== debian11 (32 bit WoW report) ===
gdiplus: Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x64a952d5).
=== debian11 (64 bit WoW report) ===
gdiplus: Unhandled exception: page fault on read access to 0x0000000000000000 in 64-bit code (0x000000648968dd).