Module: wine Branch: master Commit: 69b41e7cf3876f00048be036c00050f7bcd21e98 URL: http://source.winehq.org/git/wine.git/?a=commit;h=69b41e7cf3876f00048be036c0...
Author: Nikolay Sivov nsivov@codeweavers.com Date: Fri Apr 28 01:20:31 2017 +0300
gdiplus: Fix generic string formats behavior.
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com Signed-off-by: Vincent Povirk vincent@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/gdiplus/gdiplus.c | 2 ++ dlls/gdiplus/gdiplus_private.h | 5 +++ dlls/gdiplus/graphics.c | 12 +------ dlls/gdiplus/stringformat.c | 69 ++++++++++++++++++++++++++------------- dlls/gdiplus/tests/stringformat.c | 52 +++++++++++++++++++++++++++-- 5 files changed, 104 insertions(+), 36 deletions(-)
diff --git a/dlls/gdiplus/gdiplus.c b/dlls/gdiplus/gdiplus.c index 1281455..d114ff7 100644 --- a/dlls/gdiplus/gdiplus.c +++ b/dlls/gdiplus/gdiplus.c @@ -63,11 +63,13 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved) { case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls( hinst ); + init_generic_string_formats(); break;
case DLL_PROCESS_DETACH: if (reserved) break; free_installed_fonts(); + free_generic_string_formats(); break; } return TRUE; diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h index 9b0151b..443370a 100644 --- a/dlls/gdiplus/gdiplus_private.h +++ b/dlls/gdiplus/gdiplus_private.h @@ -441,6 +441,8 @@ struct GpFont{ Unit unit; };
+extern const struct GpStringFormat default_drawstring_format DECLSPEC_HIDDEN; + struct GpStringFormat{ INT attr; LANGID lang; @@ -458,6 +460,9 @@ struct GpStringFormat{ BOOL generic_typographic; };
+extern void init_generic_string_formats(void) DECLSPEC_HIDDEN; +extern void free_generic_string_formats(void) DECLSPEC_HIDDEN; + struct GpFontCollection{ GpFontFamily **FontFamilies; INT count; diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c index bd37d92..beedb9e 100644 --- a/dlls/gdiplus/graphics.c +++ b/dlls/gdiplus/graphics.c @@ -4909,7 +4909,6 @@ GpStatus gdip_format_string(HDC hdc, INT hotkeyprefix_count=0; INT hotkeyprefix_pos=0, hotkeyprefix_end_pos=0; BOOL seen_prefix = FALSE; - GpStringFormat *dyn_format=NULL;
if(length == -1) length = lstrlenW(string);
@@ -4917,15 +4916,7 @@ GpStatus gdip_format_string(HDC hdc, if(!stringdup) return OutOfMemory;
if (!format) - { - stat = GdipStringFormatGetGenericDefault(&dyn_format); - if (stat != Ok) - { - heap_free(stringdup); - return stat; - } - format = dyn_format; - } + format = &default_drawstring_format;
nwidth = rect->Width; nheight = rect->Height; @@ -5075,7 +5066,6 @@ GpStatus gdip_format_string(HDC hdc,
heap_free(stringdup); heap_free(hotkeyprefix_offsets); - GdipDeleteStringFormat(dyn_format);
return stat; } diff --git a/dlls/gdiplus/stringformat.c b/dlls/gdiplus/stringformat.c index b89458b..660731d 100644 --- a/dlls/gdiplus/stringformat.c +++ b/dlls/gdiplus/stringformat.c @@ -32,6 +32,47 @@
WINE_DEFAULT_DEBUG_CHANNEL(gdiplus);
+const GpStringFormat default_drawstring_format = +{ + 0, + LANG_NEUTRAL, + LANG_NEUTRAL, + StringAlignmentNear, + StringTrimmingCharacter, + HotkeyPrefixNone, + StringAlignmentNear, + StringDigitSubstituteUser, + 0, + 0.0, + NULL, + NULL, + 0, + FALSE +}; + +static GpStringFormat generic_default_format; +static GpStringFormat generic_typographic_format; + +void init_generic_string_formats(void) +{ + memcpy(&generic_default_format, &default_drawstring_format, sizeof(generic_default_format)); + + memcpy(&generic_typographic_format, &default_drawstring_format, sizeof(generic_typographic_format)); + generic_typographic_format.attr = StringFormatFlagsNoFitBlackBox | StringFormatFlagsLineLimit | + StringFormatFlagsNoClip; + generic_typographic_format.trimming = StringTrimmingNone; + generic_typographic_format.generic_typographic = TRUE; +} + +void free_generic_string_formats(void) +{ + heap_free(generic_default_format.character_ranges); + heap_free(generic_default_format.tabs); + + heap_free(generic_typographic_format.character_ranges); + heap_free(generic_typographic_format.tabs); +} + GpStatus WINGDIPAPI GdipCreateStringFormat(INT attr, LANGID lang, GpStringFormat **format) { @@ -66,6 +107,9 @@ GpStatus WINGDIPAPI GdipDeleteStringFormat(GpStringFormat *format) if(!format) return InvalidParameter;
+ if (format == &generic_default_format || format == &generic_typographic_format) + return Ok; + heap_free(format->character_ranges); heap_free(format->tabs); heap_free(format); @@ -75,17 +119,10 @@ GpStatus WINGDIPAPI GdipDeleteStringFormat(GpStringFormat *format)
GpStatus WINGDIPAPI GdipStringFormatGetGenericDefault(GpStringFormat **format) { - GpStatus stat; - if (!format) return InvalidParameter;
- stat = GdipCreateStringFormat(0, LANG_NEUTRAL, format); - if(stat != Ok) - return stat; - - (*format)->align = StringAlignmentNear; - (*format)->vertalign = StringAlignmentNear; + *format = &generic_default_format;
return Ok; } @@ -370,24 +407,10 @@ GpStatus WINGDIPAPI GdipCloneStringFormat(GDIPCONST GpStringFormat *format, GpSt
GpStatus WINGDIPAPI GdipStringFormatGetGenericTypographic(GpStringFormat **format) { - GpStatus stat; - if(!format) return InvalidParameter;
- stat = GdipCreateStringFormat(StringFormatFlagsNoFitBlackBox | - StringFormatFlagsLineLimit | - StringFormatFlagsNoClip, LANG_NEUTRAL, format); - if(stat != Ok) - return stat; - - (*format)->digitlang = LANG_NEUTRAL; - (*format)->digitsub = StringDigitSubstituteUser; - (*format)->trimming = StringTrimmingNone; - (*format)->hkprefix = HotkeyPrefixNone; - (*format)->align = StringAlignmentNear; - (*format)->vertalign = StringAlignmentNear; - (*format)->generic_typographic = TRUE; + *format = &generic_typographic_format;
TRACE("%p => %p\n", format, *format);
diff --git a/dlls/gdiplus/tests/stringformat.c b/dlls/gdiplus/tests/stringformat.c index f7f7a8f..0774e1b 100644 --- a/dlls/gdiplus/tests/stringformat.c +++ b/dlls/gdiplus/tests/stringformat.c @@ -140,7 +140,7 @@ static void test_digitsubstitution(void)
static void test_getgenerictypographic(void) { - GpStringFormat *format; + GpStringFormat *format, *format2; GpStatus stat; INT flags; INT n; @@ -157,6 +157,12 @@ static void test_getgenerictypographic(void) stat = GdipStringFormatGetGenericTypographic(&format); expect(Ok, stat);
+ stat = GdipStringFormatGetGenericTypographic(&format2); + expect(Ok, stat); + ok(format == format2, "expected same format object\n"); + stat = GdipDeleteStringFormat(format2); + expect(Ok, stat); + GdipGetStringFormatFlags(format, &flags); GdipGetStringFormatAlign(format, &align); GdipGetStringFormatLineAlign(format, &line_align); @@ -175,6 +181,24 @@ static void test_getgenerictypographic(void) expect(LANG_NEUTRAL, digitlang); expect(0, tabcount);
+ /* Change format parameters, release, get format object again. */ + stat = GdipSetStringFormatFlags(format, StringFormatFlagsNoWrap); + expect(Ok, stat); + + stat = GdipGetStringFormatFlags(format, &flags); + expect(Ok, stat); + expect(StringFormatFlagsNoWrap, flags); + + stat = GdipDeleteStringFormat(format); + expect(Ok, stat); + + stat = GdipStringFormatGetGenericTypographic(&format); + expect(Ok, stat); + + stat = GdipGetStringFormatFlags(format, &flags); + expect(Ok, stat); + expect(StringFormatFlagsNoWrap, flags); + stat = GdipDeleteStringFormat(format); expect(Ok, stat); } @@ -286,7 +310,7 @@ static void test_tabstops(void)
static void test_getgenericdefault(void) { - GpStringFormat *format; + GpStringFormat *format, *format2; GpStatus stat;
INT flags; @@ -304,6 +328,12 @@ static void test_getgenericdefault(void) stat = GdipStringFormatGetGenericDefault(&format); expect(Ok, stat);
+ stat = GdipStringFormatGetGenericDefault(&format2); + expect(Ok, stat); + ok(format == format2, "expected same format object\n"); + stat = GdipDeleteStringFormat(format2); + expect(Ok, stat); + GdipGetStringFormatFlags(format, &flags); GdipGetStringFormatAlign(format, &align); GdipGetStringFormatLineAlign(format, &line_align); @@ -321,6 +351,24 @@ static void test_getgenericdefault(void) expect(LANG_NEUTRAL, digitlang); expect(0, tabcount);
+ /* Change default format parameters, release, get format object again. */ + stat = GdipSetStringFormatFlags(format, StringFormatFlagsNoWrap); + expect(Ok, stat); + + stat = GdipGetStringFormatFlags(format, &flags); + expect(Ok, stat); + expect(StringFormatFlagsNoWrap, flags); + + stat = GdipDeleteStringFormat(format); + expect(Ok, stat); + + stat = GdipStringFormatGetGenericDefault(&format); + expect(Ok, stat); + + stat = GdipGetStringFormatFlags(format, &flags); + expect(Ok, stat); + expect(StringFormatFlagsNoWrap, flags); + stat = GdipDeleteStringFormat(format); expect(Ok, stat); }