Signed-off-by: Shawn M. Chapla schapla@codeweavers.com --- dlls/gdiplus/tests/metafile.c | 141 ++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+)
diff --git a/dlls/gdiplus/tests/metafile.c b/dlls/gdiplus/tests/metafile.c index f3b817b3de..9e25da7561 100644 --- a/dlls/gdiplus/tests/metafile.c +++ b/dlls/gdiplus/tests/metafile.c @@ -2953,6 +2953,146 @@ static void test_restoredc(void) expect(Ok, stat); }
+static const emfplus_record drawdriverstring_records[] = { + { EMR_HEADER }, + { EmfPlusRecordTypeHeader }, + { EmfPlusRecordTypeObject, ObjectTypeFont << 8, 1, 0 }, + { EmfPlusRecordTypeDrawDriverString, 0x8000, 1, 0 }, + { EmfPlusRecordTypeObject, (ObjectTypeFont << 8) | 1, 1 }, + { EmfPlusRecordTypeObject, (ObjectTypeBrush << 8) | 2, 1, 1 }, + { EmfPlusRecordTypeDrawDriverString, 0x1, 1, 1 }, + { EmfPlusRecordTypeEndOfFile }, + { EMR_EOF }, + { 0 } +}; + +static void test_drawdriverstring(void) +{ + static const GpPointF dst_points[3] = {{0.0,0.0},{100.0,0.0},{0.0,100.0}}; + static const GpRectF frame = {0.0, 0.0, 100.0, 100.0}; + static const PointF solidpos[4] = {{10.0,10.0}, {20.0,10.0}, {30.0,10.0}, {40.0,10.0}}; + static const PointF hatchpos = {10.0,30.0}; + + GpBitmap *bitmap; + GpStatus stat; + GpGraphics *graphics; + GpFont *solidfont, *hatchfont; + GpBrush *solidbrush, *hatchbrush; + HDC hdc; + GpMatrix *matrix; + GpMetafile *metafile; + ARGB color; + LOGFONTA logfont = { 0 }; + + hdc = CreateCompatibleDC(0); + + strcpy(logfont.lfFaceName, "Times New Roman"); + logfont.lfHeight = 12; + logfont.lfCharSet = DEFAULT_CHARSET; + + stat = GdipCreateFontFromLogfontA(hdc, &logfont, &solidfont); + if (stat == NotTrueTypeFont || stat == FileNotFound) + { + DeleteDC(hdc); + skip("Times New Roman not installed.\n"); + return; + } + + stat = GdipCloneFont(solidfont, &hatchfont); + expect(Ok, stat); + + stat = GdipRecordMetafile(hdc, EmfTypeEmfPlusOnly, &frame, MetafileFrameUnitPixel, + L"winetest", &metafile); + expect(Ok, stat); + + DeleteDC(hdc); + hdc = NULL; + + stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics); + expect(Ok, stat); + + stat = GdipCreateSolidFill((ARGB)0xff0000ff, (GpSolidFill**)&solidbrush); + expect(Ok, stat); + + stat = GdipCreateHatchBrush(HatchStyleHorizontal, (ARGB)0xff00ff00, (ARGB)0xffff0000, + (GpHatch**)&hatchbrush); + expect(Ok, stat); + + stat = GdipCreateMatrix(&matrix); + expect(Ok, stat); + + stat = GdipDrawDriverString(graphics, L"Test", 4, solidfont, solidbrush, solidpos, + DriverStringOptionsCmapLookup, matrix); + todo_wine expect(Ok, stat); + + stat = GdipSetMatrixElements(matrix, 1.5, 0.0, 0.0, 1.5, 0.0, 0.0); + expect(Ok, stat); + + stat = GdipDrawDriverString(graphics, L"Test ", 5, hatchfont, hatchbrush, &hatchpos, + DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance, matrix); + todo_wine expect(Ok, stat); + + stat = GdipDeleteGraphics(graphics); + graphics = NULL; + + check_metafile(metafile, drawdriverstring_records, "drawdriverstring metafile", dst_points, + &frame, UnitPixel); + sync_metafile(&metafile, "drawdriverstring.emf"); + + stat = GdipCreateBitmapFromScan0(100, 100, 0, PixelFormat32bppARGB, NULL, &bitmap); + expect(Ok, stat); + + stat = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics); + expect(Ok, stat); + + play_metafile(metafile, graphics, drawdriverstring_records, "drawdriverstring playback", + dst_points, &frame, UnitPixel); + +/* The way we render glyphs differs slightly from native wrt. alpha + channel values around edges. Since verifying that glyphs are + rendered in a way that is pixel identical to native isn't really + the point of this test, simply perform a cursory check that + alpha channel values are non-zero. */ +#define fuzzy_expect(expected, got) \ + ok((got & ~0xff000000) == expected && (got & 0xff000000), \ + "Expected RGB 0x%.8x with any non-zero alpha value, got 0x%.8x\n", expected, got) + + GdipBitmapGetPixel(bitmap, 12, 9, &color); + todo_wine fuzzy_expect(0xff, color); + + GdipBitmapGetPixel(bitmap, 21, 9, &color); + todo_wine fuzzy_expect(0xff, color); + + GdipBitmapGetPixel(bitmap, 31, 9, &color); + todo_wine fuzzy_expect(0xff, color); + + GdipBitmapGetPixel(bitmap, 41, 9, &color); + todo_wine fuzzy_expect(0xff, color); + + GdipBitmapGetPixel(bitmap, 14, 23, &color); + todo_wine fuzzy_expect(0xff0000, color); + + GdipBitmapGetPixel(bitmap, 23, 23, &color); + todo_wine fuzzy_expect(0xff0000, color); + + GdipBitmapGetPixel(bitmap, 28, 23, &color); + todo_wine fuzzy_expect(0xff0000, color); + + GdipBitmapGetPixel(bitmap, 32, 23, &color); + todo_wine fuzzy_expect(0xff0000, color); + +#undef fuzzy_expect + + GdipDeleteMatrix(matrix); + GdipDeleteGraphics(graphics); + GdipDeleteBrush(solidbrush); + GdipDeleteBrush(hatchbrush); + GdipDeleteFont(solidfont); + GdipDeleteFont(hatchfont); + GdipDisposeImage((GpImage*)bitmap); + GdipDisposeImage((GpImage*)metafile); +} + START_TEST(metafile) { struct GdiplusStartupInput gdiplusStartupInput; @@ -3002,6 +3142,7 @@ START_TEST(metafile) test_drawpath(); test_fillpath(); test_restoredc(); + test_drawdriverstring();
GdiplusShutdown(gdiplusToken); }
Signed-off-by: Shawn M. Chapla schapla@codeweavers.com --- dlls/gdiplus/metafile.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/dlls/gdiplus/metafile.c b/dlls/gdiplus/metafile.c index 9ab8b1325f..b50a106e98 100644 --- a/dlls/gdiplus/metafile.c +++ b/dlls/gdiplus/metafile.c @@ -1001,7 +1001,7 @@ static BOOL is_integer_rect(const GpRectF *rect) return TRUE; }
-static GpStatus METAFILE_PrepareBrushData(GpBrush *brush, DWORD *size) +static GpStatus METAFILE_PrepareBrushData(GDIPCONST GpBrush *brush, DWORD *size) { switch (brush->bt) { @@ -1019,7 +1019,7 @@ static GpStatus METAFILE_PrepareBrushData(GpBrush *brush, DWORD *size) return Ok; }
-static void METAFILE_FillBrushData(GpBrush *brush, EmfPlusBrush *data) +static void METAFILE_FillBrushData(GDIPCONST GpBrush *brush, EmfPlusBrush *data) { data->Version = VERSION_MAGIC2; data->Type = brush->bt; @@ -1045,7 +1045,7 @@ static void METAFILE_FillBrushData(GpBrush *brush, EmfPlusBrush *data) } }
-static GpStatus METAFILE_AddBrushObject(GpMetafile *metafile, GpBrush *brush, DWORD *id) +static GpStatus METAFILE_AddBrushObject(GpMetafile *metafile, GDIPCONST GpBrush *brush, DWORD *id) { EmfPlusObject *object_record; GpStatus stat;
Signed-off-by: Shawn M. Chapla schapla@codeweavers.com --- dlls/gdiplus/metafile.c | 99 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+)
diff --git a/dlls/gdiplus/metafile.c b/dlls/gdiplus/metafile.c index b50a106e98..d25278d115 100644 --- a/dlls/gdiplus/metafile.c +++ b/dlls/gdiplus/metafile.c @@ -548,6 +548,20 @@ typedef struct EmfPlusFont WCHAR FamilyName[1]; } EmfPlusFont;
+typedef struct EmfPlusDrawDriverString +{ + EmfPlusRecordHeader Header; + union + { + DWORD BrushId; + ARGB Color; + } brush; + DWORD DriverStringOptionsFlags; + DWORD MatrixPresent; + DWORD GlyphCount; + BYTE VariableData[1]; +} EmfPlusDrawDriverString; + static void metafile_free_object_table_entry(GpMetafile *metafile, BYTE id) { struct emfplus_object *object = &metafile->objtable[id]; @@ -3333,6 +3347,91 @@ GpStatus WINGDIPAPI GdipPlayMetafileRecord(GDIPCONST GpMetafile *metafile, GdipFree(rects); return stat; } + case EmfPlusRecordTypeDrawDriverString: + { + GpBrush *brush; + DWORD expected_size; + UINT16 *text; + PointF *positions; + GpSolidFill *solidfill = NULL; + void* alignedmem = NULL; + GpMatrix *matrix = NULL; + BYTE font = flags & 0xff; + EmfPlusDrawDriverString *draw = (EmfPlusDrawDriverString*)header; + + if (font >= EmfPlusObjectTableSize || + real_metafile->objtable[font].type != ObjectTypeFont) + return InvalidParameter; + + expected_size = FIELD_OFFSET(EmfPlusDrawDriverString, VariableData) - + sizeof(EmfPlusRecordHeader); + if (dataSize < expected_size || draw->GlyphCount <= 0) + return InvalidParameter; + + expected_size += draw->GlyphCount * (sizeof(*text) + sizeof(*positions)); + if (draw->MatrixPresent) + expected_size += sizeof(*matrix); + + /* Pad expected size to DWORD alignment. */ + expected_size = (expected_size + 3) & ~3; + + if (dataSize != expected_size) + return InvalidParameter; + + if (flags & 0x8000) + { + stat = GdipCreateSolidFill(draw->brush.Color, (GpSolidFill**)&solidfill); + + if (stat != Ok) + return InvalidParameter; + + brush = (GpBrush*)solidfill; + } + else + { + if (draw->brush.BrushId >= EmfPlusObjectTableSize || + real_metafile->objtable[draw->brush.BrushId].type != ObjectTypeBrush) + return InvalidParameter; + + brush = real_metafile->objtable[draw->brush.BrushId].u.brush; + } + + text = (UINT16*)&draw->VariableData[0]; + + /* If GlyphCount is odd, all subsequent fields will be 2-byte + aligned rather than 4-byte aligned, which may lead to access + issues. Handle this case by making our own copy of positions. */ + if (draw->GlyphCount % 2) + { + SIZE_T alloc_size = draw->GlyphCount * sizeof(*positions); + + if (draw->MatrixPresent) + alloc_size += sizeof(*matrix); + + positions = alignedmem = heap_alloc(alloc_size); + if (!positions) + { + GdipDeleteBrush((GpBrush*)solidfill); + return OutOfMemory; + } + + memcpy(positions, &text[draw->GlyphCount], alloc_size); + } + else + positions = (PointF*)&text[draw->GlyphCount]; + + if (draw->MatrixPresent) + matrix = (GpMatrix*)&positions[draw->GlyphCount]; + + stat = GdipDrawDriverString(real_metafile->playback_graphics, text, draw->GlyphCount, + real_metafile->objtable[font].u.font, brush, positions, + draw->DriverStringOptionsFlags, matrix); + + GdipDeleteBrush((GpBrush*)solidfill); + heap_free(alignedmem); + + return stat; + } default: FIXME("Not implemented for record type %x\n", recordType); return NotImplemented;
Signed-off-by: Shawn M. Chapla schapla@codeweavers.com --- dlls/gdiplus/gdiplus_private.h | 3 + dlls/gdiplus/graphics.c | 5 +- dlls/gdiplus/metafile.c | 182 +++++++++++++++++++++++++++++++-- dlls/gdiplus/tests/metafile.c | 30 +++--- 4 files changed, 193 insertions(+), 27 deletions(-)
diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h index 2ceaeade01..1b2de4e8f4 100644 --- a/dlls/gdiplus/gdiplus_private.h +++ b/dlls/gdiplus/gdiplus_private.h @@ -104,6 +104,9 @@ 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 GpStatus METAFILE_DrawDriverString(GpMetafile *metafile, GDIPCONST UINT16 *text, INT length, + GDIPCONST GpFont *font, GDIPCONST GpStringFormat *format, GDIPCONST GpBrush *brush, + GDIPCONST PointF *positions, INT flags, GDIPCONST GpMatrix *matrix) DECLSPEC_HIDDEN; extern void METAFILE_Free(GpMetafile *metafile) DECLSPEC_HIDDEN;
extern void calc_curve_bezier(const GpPointF *pts, REAL tension, REAL *x1, diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c index 6c50d2d56c..383a6286ac 100644 --- a/dlls/gdiplus/graphics.c +++ b/dlls/gdiplus/graphics.c @@ -7427,7 +7427,10 @@ static GpStatus draw_driver_string(GpGraphics *graphics, GDIPCONST UINT16 *text, if (length == -1) length = lstrlenW(text);
- if (graphics->hdc && !graphics->alpha_hdc && + if (graphics->image && graphics->image->type == ImageTypeMetafile) + return METAFILE_DrawDriverString((GpMetafile*)graphics->image, text, length, font, + format, brush, positions, flags, matrix); + else if (graphics->hdc && !graphics->alpha_hdc && brush->bt == BrushTypeSolidColor && (((GpSolidFill*)brush)->color & 0xff000000) == 0xff000000) stat = GDI32_GdipDrawDriverString(graphics, text, length, font, format, diff --git a/dlls/gdiplus/metafile.c b/dlls/gdiplus/metafile.c index d25278d115..cedffb23ca 100644 --- a/dlls/gdiplus/metafile.c +++ b/dlls/gdiplus/metafile.c @@ -378,6 +378,17 @@ typedef struct EmfPlusImageAttributes DWORD Reserved2; } EmfPlusImageAttributes;
+typedef struct EmfPlusFont +{ + DWORD Version; + float EmSize; + DWORD SizeUnit; + DWORD FontStyleFlags; + DWORD Reserved; + DWORD Length; + WCHAR FamilyName[1]; +} EmfPlusFont; + typedef struct EmfPlusObject { EmfPlusRecordHeader Header; @@ -389,6 +400,7 @@ typedef struct EmfPlusObject EmfPlusRegion region; EmfPlusImage image; EmfPlusImageAttributes image_attributes; + EmfPlusFont font; } ObjectData; } EmfPlusObject;
@@ -537,17 +549,6 @@ typedef struct EmfPlusFillPie } RectData; } EmfPlusFillPie;
-typedef struct EmfPlusFont -{ - DWORD Version; - float EmSize; - DWORD SizeUnit; - DWORD FontStyleFlags; - DWORD Reserved; - DWORD Length; - WCHAR FamilyName[1]; -} EmfPlusFont; - typedef struct EmfPlusDrawDriverString { EmfPlusRecordHeader Header; @@ -4643,3 +4644,162 @@ GpStatus METAFILE_FillPath(GpMetafile *metafile, GpBrush *brush, GpPath *path) METAFILE_WriteRecords(metafile); return Ok; } + +static GpStatus METAFILE_AddFontObject(GpMetafile *metafile, GDIPCONST GpFont *font, DWORD *id) +{ + EmfPlusObject *object_record; + EmfPlusFont *font_record; + GpStatus stat; + INT fn_len; + INT style; + + *id = -1; + + if (metafile->metafile_type != MetafileTypeEmfPlusOnly && + metafile->metafile_type != MetafileTypeEmfPlusDual) + return Ok; + + /* The following cast is ugly, but GdipGetFontStyle does treat + its first parameter as const. */ + stat = GdipGetFontStyle((GpFont*)font, &style); + if (stat != Ok) + return stat; + + fn_len = lstrlenW(font->family->FamilyName); + stat = METAFILE_AllocateRecord(metafile, + FIELD_OFFSET(EmfPlusObject, ObjectData.font.FamilyName[(fn_len + 1) & ~1]), + (void**)&object_record); + if (stat != Ok) + return stat; + + *id = METAFILE_AddObjectId(metafile); + + object_record->Header.Type = EmfPlusRecordTypeObject; + object_record->Header.Flags = *id | ObjectTypeFont << 8; + + font_record = &object_record->ObjectData.font; + font_record->Version = VERSION_MAGIC2; + font_record->EmSize = font->emSize; + font_record->SizeUnit = font->unit; + font_record->FontStyleFlags = style; + font_record->Reserved = 0; + font_record->Length = fn_len; + + memcpy(font_record->FamilyName, font->family->FamilyName, + fn_len * sizeof(*font->family->FamilyName)); + + return Ok; +} + +GpStatus METAFILE_DrawDriverString(GpMetafile *metafile, GDIPCONST UINT16 *text, INT length, + GDIPCONST GpFont *font, GDIPCONST GpStringFormat *format, GDIPCONST GpBrush *brush, + GDIPCONST PointF *positions, INT flags, GDIPCONST GpMatrix *matrix) +{ + DWORD brush_id; + DWORD font_id; + DWORD alloc_size; + GpStatus stat; + EmfPlusDrawDriverString *draw_string_record; + BYTE *cursor; + BOOL inline_color; + BOOL include_matrix = FALSE; + + if (length <= 0) + return InvalidParameter; + + if (metafile->metafile_type != MetafileTypeEmfPlusOnly && + metafile->metafile_type != MetafileTypeEmfPlusDual) + { + FIXME("metafile type not supported: %i\n", metafile->metafile_type); + return NotImplemented; + } + + stat = METAFILE_AddFontObject(metafile, font, &font_id); + if (stat != Ok) + return stat; + + inline_color = (brush->bt == BrushTypeSolidColor); + if (!inline_color) + { + stat = METAFILE_AddBrushObject(metafile, brush, &brush_id); + if (stat != Ok) + return stat; + } + + if (matrix) + { + BOOL identity; + + stat = GdipIsMatrixIdentity(matrix, &identity); + if (stat != Ok) + return stat; + + include_matrix = !identity; + } + + alloc_size = FIELD_OFFSET(EmfPlusDrawDriverString, VariableData) + + length * (sizeof(*text) + sizeof(*positions)); + + if (include_matrix) + alloc_size += sizeof(*matrix); + + /* Pad record to DWORD alignment. */ + alloc_size = (alloc_size + 3) & ~3; + + stat = METAFILE_AllocateRecord(metafile, alloc_size, (void**)&draw_string_record); + if (stat != Ok) + return stat; + + draw_string_record->Header.Type = EmfPlusRecordTypeDrawDriverString; + draw_string_record->Header.Flags = font_id; + draw_string_record->DriverStringOptionsFlags = flags; + draw_string_record->MatrixPresent = include_matrix; + draw_string_record->GlyphCount = length; + + if (inline_color) + { + draw_string_record->Header.Flags |= 0x8000; + draw_string_record->brush.Color = ((GpSolidFill*)brush)->color; + } + else + draw_string_record->brush.BrushId = brush_id; + + cursor = &draw_string_record->VariableData[0]; + + memcpy(cursor, text, length * sizeof(*text)); + cursor += length * sizeof(*text); + + if (flags & DriverStringOptionsRealizedAdvance) + { + static BOOL fixme_written = FALSE; + + /* Native never writes DriverStringOptionsRealizedAdvance. Instead, + in the case of RealizedAdvance, each glyph position is computed + and serialized. + + While native GDI+ is capable of playing back metafiles with this + flag set, it is possible that some application might rely on + metafiles produced from GDI+ not setting this flag. Ideally we + would also compute the position of each glyph here, serialize those + values, and not set DriverStringOptionsRealizedAdvance. */ + if (!fixme_written) + { + fixme_written = TRUE; + FIXME("serializing RealizedAdvance flag and single GlyphPos with padding\n"); + } + + *((PointF*)cursor) = *positions; + } + else + memcpy(cursor, positions, length * sizeof(*positions)); + + if (include_matrix) + { + cursor += length * sizeof(*positions); + memcpy(cursor, matrix, sizeof(*matrix)); + } + + METAFILE_WriteRecords(metafile); + + return Ok; +} diff --git a/dlls/gdiplus/tests/metafile.c b/dlls/gdiplus/tests/metafile.c index 9e25da7561..cebbec1db7 100644 --- a/dlls/gdiplus/tests/metafile.c +++ b/dlls/gdiplus/tests/metafile.c @@ -2956,11 +2956,11 @@ static void test_restoredc(void) static const emfplus_record drawdriverstring_records[] = { { EMR_HEADER }, { EmfPlusRecordTypeHeader }, - { EmfPlusRecordTypeObject, ObjectTypeFont << 8, 1, 0 }, - { EmfPlusRecordTypeDrawDriverString, 0x8000, 1, 0 }, - { EmfPlusRecordTypeObject, (ObjectTypeFont << 8) | 1, 1 }, - { EmfPlusRecordTypeObject, (ObjectTypeBrush << 8) | 2, 1, 1 }, - { EmfPlusRecordTypeDrawDriverString, 0x1, 1, 1 }, + { EmfPlusRecordTypeObject, ObjectTypeFont << 8 }, + { EmfPlusRecordTypeDrawDriverString, 0x8000 }, + { EmfPlusRecordTypeObject, (ObjectTypeFont << 8) | 1 }, + { EmfPlusRecordTypeObject, (ObjectTypeBrush << 8) | 2 }, + { EmfPlusRecordTypeDrawDriverString, 0x1 }, { EmfPlusRecordTypeEndOfFile }, { EMR_EOF }, { 0 } @@ -3023,14 +3023,14 @@ static void test_drawdriverstring(void)
stat = GdipDrawDriverString(graphics, L"Test", 4, solidfont, solidbrush, solidpos, DriverStringOptionsCmapLookup, matrix); - todo_wine expect(Ok, stat); + expect(Ok, stat);
stat = GdipSetMatrixElements(matrix, 1.5, 0.0, 0.0, 1.5, 0.0, 0.0); expect(Ok, stat);
stat = GdipDrawDriverString(graphics, L"Test ", 5, hatchfont, hatchbrush, &hatchpos, DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance, matrix); - todo_wine expect(Ok, stat); + expect(Ok, stat);
stat = GdipDeleteGraphics(graphics); graphics = NULL; @@ -3058,28 +3058,28 @@ static void test_drawdriverstring(void) "Expected RGB 0x%.8x with any non-zero alpha value, got 0x%.8x\n", expected, got)
GdipBitmapGetPixel(bitmap, 12, 9, &color); - todo_wine fuzzy_expect(0xff, color); + fuzzy_expect(0xff, color);
GdipBitmapGetPixel(bitmap, 21, 9, &color); - todo_wine fuzzy_expect(0xff, color); + fuzzy_expect(0xff, color);
GdipBitmapGetPixel(bitmap, 31, 9, &color); - todo_wine fuzzy_expect(0xff, color); + fuzzy_expect(0xff, color);
GdipBitmapGetPixel(bitmap, 41, 9, &color); - todo_wine fuzzy_expect(0xff, color); + fuzzy_expect(0xff, color);
GdipBitmapGetPixel(bitmap, 14, 23, &color); - todo_wine fuzzy_expect(0xff0000, color); + fuzzy_expect(0xff0000, color);
GdipBitmapGetPixel(bitmap, 23, 23, &color); - todo_wine fuzzy_expect(0xff0000, color); + fuzzy_expect(0xff0000, color);
GdipBitmapGetPixel(bitmap, 28, 23, &color); - todo_wine fuzzy_expect(0xff0000, color); + fuzzy_expect(0xff0000, color);
GdipBitmapGetPixel(bitmap, 32, 23, &color); - todo_wine fuzzy_expect(0xff0000, color); + fuzzy_expect(0xff0000, color);
#undef fuzzy_expect
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=75206
Your paranoid android.
=== w2008s64 (32 bit report) ===
gdiplus: metafile.c:3073: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0xffe00000
=== w8 (32 bit report) ===
gdiplus: metafile.c:3073: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0xffe00000 metafile.c:3076: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0x00000000 metafile.c:3079: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0x00000000
=== w8adm (32 bit report) ===
gdiplus: metafile.c:3073: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0xffe00000 metafile.c:3076: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0x00000000 metafile.c:3079: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0x00000000
=== w1064v1507 (32 bit report) ===
gdiplus: metafile.c:3073: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0xffe00000 metafile.c:3076: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0x00000000 metafile.c:3079: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0x00000000
=== w1064v1809 (32 bit report) ===
gdiplus: metafile.c:3073: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0xffe00000 metafile.c:3076: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0x00000000 metafile.c:3079: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0x00000000
=== w1064v1809_2scr (32 bit report) ===
gdiplus: metafile.c:3073: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0xffe00000 metafile.c:3076: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0x00000000 metafile.c:3079: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0x00000000
=== w1064v1809_ar (32 bit report) ===
gdiplus: metafile.c:3073: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0xffe00000 metafile.c:3076: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0x00000000 metafile.c:3079: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0x00000000
=== w1064v1809_he (32 bit report) ===
gdiplus: metafile.c:3073: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0xffe00000 metafile.c:3076: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0x00000000 metafile.c:3079: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0x00000000
=== w1064v1809_ja (32 bit report) ===
gdiplus: metafile.c:3073: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0xffe00000 metafile.c:3076: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0x00000000 metafile.c:3079: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0x00000000
=== w1064v1809_zh_CN (32 bit report) ===
gdiplus: metafile.c:3073: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0xffe00000 metafile.c:3076: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0x00000000 metafile.c:3079: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0x00000000
=== w2008s64 (64 bit report) ===
gdiplus: metafile.c:3073: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0xffe00000
=== w864 (64 bit report) ===
gdiplus: metafile.c:3073: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0xffe00000 metafile.c:3076: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0x00000000 metafile.c:3079: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0x00000000
=== w1064v1507 (64 bit report) ===
gdiplus: metafile.c:3073: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0xffe00000 metafile.c:3076: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0x00000000 metafile.c:3079: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0x00000000
=== w1064v1809 (64 bit report) ===
gdiplus: metafile.c:3073: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0xffe00000 metafile.c:3076: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0x00000000 metafile.c:3079: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0x00000000
I think it would be better not to test the drawing. I don't know how to do it reliably.
On Mon, Jul 13, 2020 at 10:06:24AM -0500, Esme Povirk (they/them) wrote:
I think it would be better not to test the drawing. I don't know how to do it reliably.
That's a bit unfortunate, but it does make things easier. The only thing I could really think of was counting the non-zero pixels in some area (regardless of their exact position) and checking that the count is greater than some threshold, which is pretty obtuse and probably worse than nothing.
I'll send another patchset with the fragile parts of the test removed shortly.
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=75203
Your paranoid android.
=== w2008s64 (32 bit report) ===
gdiplus: metafile.c:3073: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0xffe00000
=== w8 (32 bit report) ===
gdiplus: metafile.c:3073: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0xffe00000 metafile.c:3076: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0x00000000 metafile.c:3079: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0x00000000
=== w8adm (32 bit report) ===
gdiplus: metafile.c:3073: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0xffe00000 metafile.c:3076: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0x00000000 metafile.c:3079: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0x00000000
=== w1064v1507 (32 bit report) ===
gdiplus: metafile.c:3073: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0xffe00000 metafile.c:3076: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0x00000000 metafile.c:3079: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0x00000000
=== w1064v1809 (32 bit report) ===
gdiplus: metafile.c:3073: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0xffe00000 metafile.c:3076: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0x00000000 metafile.c:3079: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0x00000000
=== w1064v1809_2scr (32 bit report) ===
gdiplus: metafile.c:3073: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0xffe00000 metafile.c:3076: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0x00000000 metafile.c:3079: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0x00000000
=== w1064v1809_ar (32 bit report) ===
gdiplus: metafile.c:3073: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0xffe00000 metafile.c:3076: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0x00000000 metafile.c:3079: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0x00000000
=== w1064v1809_he (32 bit report) ===
gdiplus: metafile.c:3073: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0xffe00000 metafile.c:3076: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0x00000000 metafile.c:3079: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0x00000000
=== w1064v1809_ja (32 bit report) ===
gdiplus: metafile.c:3073: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0xffe00000 metafile.c:3076: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0x00000000 metafile.c:3079: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0x00000000
=== w1064v1809_zh_CN (32 bit report) ===
gdiplus: metafile.c:3073: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0xffe00000 metafile.c:3076: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0x00000000 metafile.c:3079: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0x00000000
=== w2008s64 (64 bit report) ===
gdiplus: metafile.c:3073: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0xffe00000
=== w864 (64 bit report) ===
gdiplus: metafile.c:3073: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0xffe00000 metafile.c:3076: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0x00000000 metafile.c:3079: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0x00000000
=== w1064v1507 (64 bit report) ===
gdiplus: metafile.c:3073: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0xffe00000 metafile.c:3076: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0x00000000 metafile.c:3079: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0x00000000
=== w1064v1809 (64 bit report) ===
gdiplus: metafile.c:3073: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0xffe00000 metafile.c:3076: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0x00000000 metafile.c:3079: Test failed: Expected RGB 0x00ff0000 with any non-zero alpha value, got 0x00000000
It looks like this test is just too sensitive to minor font rendering differences to be useful in its current state. I'll have to figure something else out.
Sorry for the spam. Please disregard this patchset for now.