Module: wine
Branch: master
Commit: 69b41e7cf3876f00048be036c00050f7bcd21e98
URL:
http://source.winehq.org/git/wine.git/?a=commit;h=69b41e7cf3876f00048be036c…
Author: Nikolay Sivov <nsivov(a)codeweavers.com>
Date: Fri Apr 28 01:20:31 2017 +0300
gdiplus: Fix generic string formats behavior.
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
Signed-off-by: Vincent Povirk <vincent(a)codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard(a)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);
}