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

Nikolay Sivov nsivov at codeweavers.com
Tue Oct 24 05:56:40 CDT 2017


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 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




More information about the wine-patches mailing list