[PATCH 2/3] gdiplus: Fix generic string formats behavior
Nikolay Sivov
nsivov at codeweavers.com
Thu Apr 27 17:20:31 CDT 2017
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
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 128145581d..d114ff797e 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 9b0151b36c..443370a787 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 bd37d925d3..beedb9ea4a 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 b89458bdeb..660731d7ce 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 f7f7a8f498..0774e1b79d 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);
}
--
2.11.0
More information about the wine-patches
mailing list