[PATCH 3/3] gdiplus/metafile: Added support for EmfPlusStringFormat object playback

Nikolay Sivov <[email protected]>
Newsgroups gmane.comp.emulators.wine.patches
Message-ID <[email protected]>
Signed-off-by: Nikolay Sivov <[email protected]>
---
 dlls/gdiplus/gdiplus_private.h |  1 +
 dlls/gdiplus/metafile.c        | 84 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 85 insertions(+)

diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h
index 40275a47eb..6b1593b9f3 100644
--- a/dlls/gdiplus/gdiplus_private.h
+++ b/dlls/gdiplus/gdiplus_private.h
@@ -399,6 +399,7 @@ struct emfplus_object {
         GpRegion *region;
         GpImage *image;
         GpFont *font;
+        GpStringFormat *stringformat;
         GpImageAttributes *image_attributes;
         void *object;
     } u;
diff --git a/dlls/gdiplus/metafile.c b/dlls/gdiplus/metafile.c
index 91e18a55c8..5d1c68b9bf 100644
--- a/dlls/gdiplus/metafile.c
+++ b/dlls/gdiplus/metafile.c
@@ -418,6 +418,37 @@ typedef struct EmfPlusFont
     WCHAR FamilyName[1];
 } EmfPlusFont;
 
+typedef struct EmfPlusLanguageIdentifier
+{
+    LANGID langid;
+} EmfPlusLanguageIdentifier;
+
+typedef struct EmfPlusCharacterRange
+{
+    INT First;
+    INT Length;
+} EmfPlusCharacterRange;
+
+typedef struct EmfPlusStringFormat
+{
+    DWORD Version;
+    DWORD StringFormatFlags;
+    EmfPlusLanguageIdentifier Language;
+    DWORD StringAlignment;
+    DWORD LineAlign;
+    DWORD DigitSubstitution;
+    EmfPlusLanguageIdentifier DigitLanguage;
+    float FirstTabOffset;
+    DWORD HotkeyPrefix;
+    float LeadingMargin;
+    float TrailingMargin;
+    float Tracking;
+    DWORD Trimming;
+    INT TabStopCount;
+    INT RangeCount;
+    BYTE StringFormatData[1];
+} EmfPlusStringFormat;
+
 static void metafile_free_object_table_entry(GpMetafile *metafile, BYTE id)
 {
     struct emfplus_object *object = &metafile->objtable[id];
@@ -444,6 +475,9 @@ static void metafile_free_object_table_entry(GpMetafile *metafile, BYTE id)
     case ObjectTypeFont:
         GdipDeleteFont(object->u.font);
         break;
+    case ObjectTypeStringFormat:
+        GdipDeleteStringFormat(object->u.stringformat);
+        break;
     case ObjectTypeImageAttributes:
         GdipDisposeImageAttributes(object->u.image_attributes);
         break;
@@ -2104,6 +2138,56 @@ static GpStatus METAFILE_PlaybackObject(GpMetafile *metafile, UINT flags, UINT d
         GdipDeleteFontFamily(family);
         break;
     }
+    case ObjectTypeStringFormat:
+    {
+        DWORD optional_offset = FIELD_OFFSET(EmfPlusStringFormat, StringFormatData);
+        EmfPlusStringFormat *data = (EmfPlusStringFormat *)record_data;
+        GpStringFormat *format = NULL;
+
+        if (data_size < optional_offset)
+            return InvalidParameter;
+        data_size -= optional_offset;
+
+        if (data_size != (data->TabStopCount * sizeof(float) + data->RangeCount * sizeof(EmfPlusCharacterRange)))
+            return InvalidParameter;
+
+        status = GdipCreateStringFormat(data->StringFormatFlags, data->Language.langid, &format);
+        if (status != Ok)
+            return status;
+
+        status = GdipSetStringFormatAlign(format, data->StringAlignment);
+        if (status == Ok)
+            status = GdipSetStringFormatLineAlign(format, data->LineAlign);
+        if (status == Ok)
+            status = GdipSetStringFormatDigitSubstitution(format, data->DigitLanguage.langid, data->DigitSubstitution);
+        if (status == Ok)
+            status = GdipSetStringFormatHotkeyPrefix(format, data->HotkeyPrefix);
+        if (status == Ok)
+            status = GdipSetStringFormatTrimming(format, data->Trimming);
+        format->leading_margin = data->LeadingMargin;
+        format->trailing_margin = data->TrailingMargin;
+        format->tracking = data->Tracking;
+
+        if (status == Ok && data->TabStopCount > 0)
+        {
+            status = GdipSetStringFormatTabStops(format, data->FirstTabOffset, data->TabStopCount,
+                (float *)data->StringFormatData);
+            optional_offset += data->TabStopCount * sizeof(float);
+        }
+
+        if (status == Ok && data->RangeCount > 0)
+        {
+            status = GdipSetStringFormatMeasurableCharacterRanges(format, data->RangeCount,
+                (CharacterRange *)((BYTE *)data->StringFormatData + optional_offset));
+        }
+
+        if (status == Ok)
+            object = format;
+        else
+            GdipDeleteStringFormat(format);
+
+        break;
+    }
     case ObjectTypeImageAttributes:
     {
         EmfPlusImageAttributes *data = (EmfPlusImageAttributes *)record_data;
-- 
2.14.2
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.