emfio/inc/mtftools.hxx                                             |    3 
 emfio/qa/cppunit/emf/EmfImportTest.cxx                             |  113 
++++++++++
 emfio/qa/cppunit/emf/data/TestExtTextOutOpaqueAndClipTransform.emf |binary
 emfio/qa/cppunit/wmf/data/TestExtTextOutOpaqueAndClip.wmf          |binary
 emfio/qa/cppunit/wmf/wmfimporttest.cxx                             |   18 +
 emfio/source/reader/emfreader.cxx                                  |   37 ++-
 emfio/source/reader/mtftools.cxx                                   |   35 +--
 emfio/source/reader/wmfreader.cxx                                  |   23 +-
 8 files changed, 190 insertions(+), 39 deletions(-)

New commits:
commit 3a9027609e7ee0c7af457b06426093782ca295a8
Author:     Bartosz Kosiorek <gan...@poczta.onet.pl>
AuthorDate: Mon May 24 20:05:19 2021 +0200
Commit:     Bartosz Kosiorek <gan...@poczta.onet.pl>
CommitDate: Fri May 28 21:47:40 2021 +0200

    tdf#53004 tdf#142495 WMF EMF Fix displaying Text with OPAQUE and CLIPPED
    
    With OPAQUE option enabled, the rectangle need to be drawn,
    before drawing text.
    
    With CLIPPED option enabled, the text needs to be drawn
    only inside rectangle.
    
    In previous implementation, the rectangle read was skipped and
    it was not drawn (for OPAQUE).
    
    For CLIPPED the rectangle was read but Clip was not applied
    to text drawing
    
    This commit fix that issues, and allow to draw rectangle correctly,
    with BGColor (background color), and add support for Text Clipping
    according to [MS-WMF] and [MS-EMF] specification.
    The fix applied to EMR_EXTTEXTOUTW, EMR_EXTTEXTOUTA and EXTTEXTOUT records
    
    Change-Id: I0f6248bb9465e6d5f797cddb53f058afb0815a2d
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/116072
    Tested-by: Jenkins
    Reviewed-by: Bartosz Kosiorek <gan...@poczta.onet.pl>

diff --git a/emfio/inc/mtftools.hxx b/emfio/inc/mtftools.hxx
index 0fb99761d386..cffe5e4fa511 100644
--- a/emfio/inc/mtftools.hxx
+++ b/emfio/inc/mtftools.hxx
@@ -207,11 +207,13 @@ namespace emfio
 #define MAC_CHARSET             77
 #define BALTIC_CHARSET          186
 
+#define ETO_OPAQUE              0x0002
 #define ETO_CLIPPED             0x0004
 /*WINVER >= 0x0400*/
 #define ETO_GLYPH_INDEX         0x0010
 #define ETO_RTLREADING          0x0080
 /*_WIN32_WINNT >= 0x0500*/
+#define ETO_NO_RECT             0x0100
 #define ETO_PDY                 0x2000
 
 #define DEFAULT_PITCH           0x00
@@ -642,6 +644,7 @@ namespace emfio
         void                LineTo(const Point& rPoint, bool bRecordPath = 
false);
         void                DrawPixel(const Point& rSource, const Color& 
rColor);
         void                DrawRect(const tools::Rectangle& rRect, bool bEdge 
= true);
+        void                DrawRectWithBGColor(const tools::Rectangle& rRect);
         void                DrawRoundRect(const tools::Rectangle& rRect, const 
Size& rSize);
         void                DrawEllipse(const tools::Rectangle& rRect);
         void                DrawArc(
diff --git a/emfio/qa/cppunit/emf/EmfImportTest.cxx 
b/emfio/qa/cppunit/emf/EmfImportTest.cxx
index 5de9faa36714..1b134551c7ff 100644
--- a/emfio/qa/cppunit/emf/EmfImportTest.cxx
+++ b/emfio/qa/cppunit/emf/EmfImportTest.cxx
@@ -60,6 +60,9 @@ class Test : public test::BootstrapFixture, public 
XmlTestTools, public unotest:
     void TestEllipseXformIntersectClipRect();
     void TestDrawPolyLine16WithClip();
     void TestFillRegion();
+    void TestExtTextOutOpaqueAndClipTransform();
+
+    void TestExtTextOutOpaqueAndClipWMF();
     void TestPaletteWMF();
     void TestRoundrectWMF();
     void TestPolylinetoCloseStroke();
@@ -91,6 +94,8 @@ public:
     CPPUNIT_TEST(TestEllipseXformIntersectClipRect);
     CPPUNIT_TEST(TestDrawPolyLine16WithClip);
     CPPUNIT_TEST(TestFillRegion);
+    CPPUNIT_TEST(TestExtTextOutOpaqueAndClipTransform);
+    CPPUNIT_TEST(TestExtTextOutOpaqueAndClipWMF);
     CPPUNIT_TEST(TestPaletteWMF);
     CPPUNIT_TEST(TestRoundrectWMF);
     CPPUNIT_TEST(TestPolylinetoCloseStroke);
@@ -504,6 +509,114 @@ void Test::TestPolylinetoCloseStroke()
                 "color", "#000000");
 }
 
+
+void Test::TestExtTextOutOpaqueAndClipTransform()
+{
+    // tdf#142495 EMF records: SETBKCOLOR, SELECTOBJECT, EXTTEXTOUTW, 
MODIFYWORLDTRANSFORM, CREATEFONTINDIRECT.
+    Primitive2DSequence aSequence = 
parseEmf(u"/emfio/qa/cppunit/emf/data/TestExtTextOutOpaqueAndClipTransform.emf");
+    CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequence.getLength()));
+    drawinglayer::Primitive2dXmlDump dumper;
+    xmlDocUniquePtr pDocument = 
dumper.dumpAndParse(comphelper::sequenceToContainer<Primitive2DContainer>(aSequence));
+    CPPUNIT_ASSERT (pDocument);
+
+    assertXPath(pDocument, "/primitive2D/metafile/transform/textsimpleportion",
+                "text", "No_rect- DLP-");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/textsimpleportion",
+                "fontcolor", "#000000");
+
+    assertXPath(pDocument, "/primitive2D/metafile/transform/polypolygoncolor", 
2);
+    assertXPath(pDocument, 
"/primitive2D/metafile/transform/polypolygoncolor[1]/polypolygon",
+                "path", "m966 490-477-275-84 147 476 275z");
+    assertXPath(pDocument, 
"/primitive2D/metafile/transform/polypolygoncolor[1]",
+                "color", "#ff0000");
+
+    assertXPath(pDocument, 
"/primitive2D/metafile/transform/polypolygoncolor[2]/polypolygon",
+                "path", "m251 713 623 361-148 257-623-361z");
+    assertXPath(pDocument, 
"/primitive2D/metafile/transform/polypolygoncolor[2]",
+                "color", "#0080ff");
+
+    assertXPath(pDocument, "/primitive2D/metafile/transform/group", 3);
+    assertXPath(pDocument, 
"/primitive2D/metafile/transform/group[1]/polypolygoncolor",
+                "color", "#ff0000");
+    assertXPath(pDocument, 
"/primitive2D/metafile/transform/group[1]/textsimpleportion",
+                "text", "Opaque - DLP-");
+    assertXPath(pDocument, 
"/primitive2D/metafile/transform/group[1]/textsimpleportion",
+                "fontcolor", "#000000");
+
+    assertXPath(pDocument, 
"/primitive2D/metafile/transform/group[2]/mask/group/polypolygoncolor",
+                "color", "#00ff00");
+    assertXPath(pDocument, 
"/primitive2D/metafile/transform/group[2]/mask/polypolygon",
+                "path", "m320 508 586 340-169 293-586-339z");
+    assertXPath(pDocument, 
"/primitive2D/metafile/transform/group[2]/mask/group/textsimpleportion",
+                "text", "Clip  -  DLP-");
+    assertXPath(pDocument, 
"/primitive2D/metafile/transform/group[2]/mask/group/textsimpleportion",
+                "fontcolor", "#000000");
+
+    assertXPath(pDocument, 
"/primitive2D/metafile/transform/group[3]/mask/group/polypolygoncolor",
+                "color", "#0080ff");
+    assertXPath(pDocument, 
"/primitive2D/metafile/transform/group[3]/mask/polypolygon",
+                "path", "m251 713 623 361-148 257-623-361z");
+    assertXPath(pDocument, 
"/primitive2D/metafile/transform/group[3]/mask/group/textsimpleportion",
+                "text", "Opaque ClipP-");
+    assertXPath(pDocument, 
"/primitive2D/metafile/transform/group[3]/mask/group/textsimpleportion",
+                "fontcolor", "#000000");
+}
+
+void Test::TestExtTextOutOpaqueAndClipWMF()
+{
+    // tdf#53004 WMF records: SETBKCOLOR, SELECTOBJECT, EXTTEXTOUT, 
CREATEBRUSHINDIRECT.
+    Primitive2DSequence aSequence = 
parseEmf(u"/emfio/qa/cppunit/wmf/data/TestExtTextOutOpaqueAndClip.wmf");
+    CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequence.getLength()));
+    drawinglayer::Primitive2dXmlDump dumper;
+    xmlDocUniquePtr pDocument = 
dumper.dumpAndParse(comphelper::sequenceToContainer<Primitive2DContainer>(aSequence));
+    CPPUNIT_ASSERT (pDocument);
+
+#ifdef MACOSX
+    // On some operating systems (Linux on LO Jenkins CI), the `/mask/` string 
is not added to XPath
+    // As a result tests are failing. On my Ubuntu 20.04 the `/mask/` string 
was added
+    // I would leave this test case for macOS to make sure there is no 
regression at least on one platform.
+    assertXPath(pDocument, 
"/primitive2D/metafile/transform/mask/polypolygoncolor", 5);
+    assertXPath(pDocument, 
"/primitive2D/metafile/transform/mask/polypolygoncolor[1]/polypolygon",
+                "path", "m7219 1825h319v3608h-319z");
+    assertXPath(pDocument, 
"/primitive2D/metafile/transform/mask/polypolygoncolor[1]",
+                "color", "#ff0000");
+
+    assertXPath(pDocument, 
"/primitive2D/metafile/transform/mask/polypolygoncolor[2]/polypolygon",
+                "path", "m7219 5942h319v318h-319z");
+    assertXPath(pDocument, 
"/primitive2D/metafile/transform/mask/polypolygoncolor[2]",
+                "color", "#00ff00");
+
+    assertXPath(pDocument, 
"/primitive2D/metafile/transform/mask/polypolygoncolor[3]/polypolygon",
+                "path", "m10149 5942h319v318h-319z");
+    assertXPath(pDocument, 
"/primitive2D/metafile/transform/mask/polypolygoncolor[3]",
+                "color", "#8080ff");
+
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/group", 5);
+    assertXPath(pDocument, 
"/primitive2D/metafile/transform/mask/group[1]/polypolygoncolor",
+                "color", "#00ff00");
+    assertXPath(pDocument, 
"/primitive2D/metafile/transform/mask/group[1]/textsimpleportion",
+                "text", "ABCD");
+    assertXPath(pDocument, 
"/primitive2D/metafile/transform/mask/group[1]/textsimpleportion",
+                "fontcolor", "#000000");
+
+    assertXPath(pDocument, 
"/primitive2D/metafile/transform/mask/group[2]/polypolygoncolor",
+                "color", "#8080ff");
+    assertXPath(pDocument, 
"/primitive2D/metafile/transform/mask/group[2]/textsimpleportion",
+                "text", "MMMM");
+    assertXPath(pDocument, 
"/primitive2D/metafile/transform/mask/group[2]/textsimpleportion",
+                "fontcolor", "#000000");
+
+    assertXPath(pDocument, 
"/primitive2D/metafile/transform/mask/group[3]/mask/group/polypolygoncolor",
+                "color", "#ff8000");
+    assertXPath(pDocument, 
"/primitive2D/metafile/transform/mask/group[3]/mask/group/polypolygoncolor/polypolygon",
+                "path", "m1062 1061h1270v473h-1270z");
+    assertXPath(pDocument, 
"/primitive2D/metafile/transform/mask/group[3]/mask/group/textsimpleportion",
+                "text", "OOOO");
+    assertXPath(pDocument, 
"/primitive2D/metafile/transform/mask/group[3]/mask/group/textsimpleportion",
+                "fontcolor", "#000000");
+#endif
+}
+
 void Test::TestPaletteWMF()
 {
     // WMF import with records: CREATEPALETTE, SELECTOBJECT, 
CREATEPENINDIRECT, CREATEBRUSHINDIRECT, ELLIPSE.
diff --git a/emfio/qa/cppunit/emf/data/TestExtTextOutOpaqueAndClipTransform.emf 
b/emfio/qa/cppunit/emf/data/TestExtTextOutOpaqueAndClipTransform.emf
new file mode 100644
index 000000000000..7d59ac3e5bd2
Binary files /dev/null and 
b/emfio/qa/cppunit/emf/data/TestExtTextOutOpaqueAndClipTransform.emf differ
diff --git a/emfio/qa/cppunit/wmf/data/TestExtTextOutOpaqueAndClip.wmf 
b/emfio/qa/cppunit/wmf/data/TestExtTextOutOpaqueAndClip.wmf
new file mode 100644
index 000000000000..fb6fd20f0cb4
Binary files /dev/null and 
b/emfio/qa/cppunit/wmf/data/TestExtTextOutOpaqueAndClip.wmf differ
diff --git a/emfio/qa/cppunit/wmf/wmfimporttest.cxx 
b/emfio/qa/cppunit/wmf/wmfimporttest.cxx
index 41c15e3989f8..62a669fe3676 100644
--- a/emfio/qa/cppunit/wmf/wmfimporttest.cxx
+++ b/emfio/qa/cppunit/wmf/wmfimporttest.cxx
@@ -206,7 +206,7 @@ void WmfTest::testWorldTransformFontSize()
 
     CPPUNIT_ASSERT(pDoc);
 
-    assertXPath(pDoc, "/metafile/font", 8);
+    assertXPath(pDoc, "/metafile/font", 9);
 
     assertXPath(pDoc, "/metafile/font[1]", "color", "#595959");
     assertXPath(pDoc, "/metafile/font[1]", "width", "0");
@@ -214,13 +214,19 @@ void WmfTest::testWorldTransformFontSize()
     assertXPath(pDoc, "/metafile/font[1]", "orientation", "0");
     assertXPath(pDoc, "/metafile/font[1]", "weight", "bold");
 
-    // World transform should not affect font size. Rotating text for 90 
degrees
-    // should not exchange font width and height.
     assertXPath(pDoc, "/metafile/font[3]", "color", "#000000");
     assertXPath(pDoc, "/metafile/font[3]", "width", "0");
-    assertXPath(pDoc, "/metafile/font[3]", "height", "530");
-    assertXPath(pDoc, "/metafile/font[3]", "orientation", "900");
-    assertXPath(pDoc, "/metafile/font[3]", "weight", "normal");
+    assertXPath(pDoc, "/metafile/font[3]", "height", "389");
+    assertXPath(pDoc, "/metafile/font[3]", "orientation", "0");
+    assertXPath(pDoc, "/metafile/font[3]", "weight", "bold");
+
+    // World transform should not affect font size. Rotating text for 90 
degrees
+    // should not exchange font width and height.
+    assertXPath(pDoc, "/metafile/font[4]", "color", "#000000");
+    assertXPath(pDoc, "/metafile/font[4]", "width", "0");
+    assertXPath(pDoc, "/metafile/font[4]", "height", "530");
+    assertXPath(pDoc, "/metafile/font[4]", "orientation", "900");
+    assertXPath(pDoc, "/metafile/font[4]", "weight", "normal");
 }
 
 void WmfTest::testTdf93750()
diff --git a/emfio/source/reader/emfreader.cxx 
b/emfio/source/reader/emfreader.cxx
index 9a8784c7e631..e6a758175fb5 100644
--- a/emfio/source/reader/emfreader.cxx
+++ b/emfio/source/reader/emfreader.cxx
@@ -1795,14 +1795,18 @@ namespace emfio
                         [[fallthrough]];
                     case EMR_EXTTEXTOUTW :
                     {
-                        sal_Int32   nLeft, nTop, nRight, nBottom, 
ptlReferenceX, ptlReferenceY, nGfxMode, nXScale, nYScale;
-                        sal_uInt32  nOffString, nOptions, offDx;
-                        sal_Int32   nLen;
+                        sal_Int32   nLeft, nTop, nRight, nBottom;
+                        sal_uInt32  nGfxMode;
+                        float       nXScale, nYScale;
+                        sal_Int32   ptlReferenceX, ptlReferenceY;
+                        sal_uInt32  nLen, nOffString, nOptions, offDx;
+                        sal_Int32   nLeftRect, nTopRect, nRightRect, 
nBottomRect;
 
                         nCurPos = mpInputStream->Tell() - 8;
 
-                        mpInputStream->ReadInt32( nLeft ).ReadInt32( nTop 
).ReadInt32( nRight ).ReadInt32( nBottom ).ReadInt32( nGfxMode ).ReadInt32( 
nXScale ).ReadInt32( nYScale )
-                           .ReadInt32( ptlReferenceX ).ReadInt32( 
ptlReferenceY ).ReadInt32( nLen ).ReadUInt32( nOffString ).ReadUInt32( nOptions 
);
+                        mpInputStream->ReadInt32( nLeft ).ReadInt32( nTop 
).ReadInt32( nRight ).ReadInt32( nBottom )
+                           .ReadUInt32( nGfxMode ).ReadFloat( nXScale 
).ReadFloat( nYScale )
+                           .ReadInt32( ptlReferenceX ).ReadInt32( 
ptlReferenceY ).ReadUInt32( nLen ).ReadUInt32( nOffString ).ReadUInt32( 
nOptions );
 
                         SAL_INFO("emfio", "\t\tBounds: " << nLeft << ", " << 
nTop << ", " << nRight << ", " << nBottom);
                         SAL_INFO("emfio", "\t\tiGraphicsMode: 0x" << std::hex 
<< nGfxMode << std::dec);
@@ -1810,7 +1814,13 @@ namespace emfio
                         SAL_INFO("emfio", "\t\teyScale: " << nYScale);
                         SAL_INFO("emfio", "\t\tReference: (" << ptlReferenceX 
<< ", " << ptlReferenceY << ")");
 
-                        mpInputStream->SeekRel( 0x10 );
+                        mpInputStream->ReadInt32( nLeftRect ).ReadInt32( 
nTopRect ).ReadInt32( nRightRect ).ReadInt32( nBottomRect );
+                        const tools::Rectangle aRect( nLeftRect, nTopRect, 
nRightRect, nBottomRect );
+                        BkMode mnBkModeBackup = mnBkMode;
+                        if ( nOptions & ETO_NO_RECT ) // Don't draw the 
background rectangle
+                            mnBkMode = BkMode::Transparent;
+                        if ( nOptions & ETO_OPAQUE )
+                            DrawRectWithBGColor( aRect );
                         mpInputStream->ReadUInt32( offDx );
 
                         ComplexTextLayoutFlags nTextLayoutMode = 
ComplexTextLayoutFlags::Default;
@@ -1820,15 +1830,14 @@ namespace emfio
                         SAL_WARN_IF( ( nOptions & ( ETO_PDY | ETO_GLYPH_INDEX 
) ) != 0, "emfio", "SJ: ETO_PDY || ETO_GLYPH_INDEX in EMF" );
 
                         Point aPos( ptlReferenceX, ptlReferenceY );
-                        bool bLenSane = nLen > 0 && nLen < 
static_cast<sal_Int32>( SAL_MAX_UINT32 / sizeof(sal_Int32) );
                         bool bOffStringSane = nOffString <= mnEndPos - nCurPos;
-                        if (bLenSane && bOffStringSane)
+                        if ( bOffStringSane )
                         {
                             mpInputStream->Seek( nCurPos + nOffString );
                             OUString aText;
                             if ( bFlag )
                             {
-                                if ( nLen <= static_cast<sal_Int32>( mnEndPos 
- mpInputStream->Tell() ) )
+                                if ( nLen <= ( mnEndPos - 
mpInputStream->Tell() ) )
                                 {
                                     std::unique_ptr<char[]> pBuf(new char[ 
nLen ]);
                                     mpInputStream->ReadBytes(pBuf.get(), nLen);
@@ -1862,7 +1871,7 @@ namespace emfio
                                 for (sal_Int32 i = 0; i < aText.getLength(); 
++i)
                                 {
                                     sal_Int32 nDxCount = 1;
-                                    if (aText.getLength() != nLen)
+                                    if (aText.getLength() != 
static_cast<sal_Int32>( nLen ) )
                                     {
                                         sal_Unicode cUniChar = aText[i];
                                         OString aTmp(&cUniChar, 1, 
GetCharSet());
@@ -1894,7 +1903,15 @@ namespace emfio
                                     }
                                 }
                             }
+                            if ( nOptions & ETO_CLIPPED )
+                            {
+                                Push(); // Save the current clip. It will be 
restored after text drawing
+                                IntersectClipRect( aRect );
+                            }
                             DrawText(aPos, aText, pDXAry.get(), pDYAry.get(), 
mbRecordPath, nGfxMode);
+                            if ( nOptions & ETO_CLIPPED )
+                                Pop();
+                            mnBkMode = mnBkModeBackup;
                         }
                     }
                     break;
diff --git a/emfio/source/reader/mtftools.cxx b/emfio/source/reader/mtftools.cxx
index d68e36e361ef..6bf0d98a3e76 100644
--- a/emfio/source/reader/mtftools.cxx
+++ b/emfio/source/reader/mtftools.cxx
@@ -1051,14 +1051,8 @@ namespace emfio
         {
             return; // empty rectangles cause trouble
         }
-        Point aPoints[] { Point(rRect.Left(), rRect.Top()),
-                          Point(rRect.Right(), rRect.Top()),
-                          Point(rRect.Right(), rRect.Bottom()),
-                          Point(rRect.Left(), rRect.Bottom()) };
-        tools::Polygon aPoly(4, aPoints);
-        aPoly = ImplMap( aPoly );
-        aPoly.Optimize( PolyOptimizeFlags::CLOSE );
-        tools::PolyPolygon aPolyPolyRect( aPoly );
+        tools::Polygon aPoly( rRect );
+        const tools::PolyPolygon aPolyPolyRect( ImplMap( aPoly ) );
         maClipPath.intersectClip( aPolyPolyRect.getB2DPolyPolygon() );
     }
 
@@ -1067,15 +1061,8 @@ namespace emfio
         if (utl::ConfigManager::IsFuzzing())
             return;
         mbClipNeedsUpdate=true;
-
-        Point aPoints[] { Point(rRect.Left(), rRect.Top()),
-                          Point(rRect.Right(), rRect.Top()),
-                          Point(rRect.Right(), rRect.Bottom()),
-                          Point(rRect.Left(), rRect.Bottom()) };
-        tools::Polygon aPoly(4, aPoints);
-        aPoly = ImplMap( aPoly );
-        aPoly.Optimize( PolyOptimizeFlags::CLOSE );
-        tools::PolyPolygon aPolyPolyRect( aPoly );
+        tools::Polygon aPoly( rRect );
+        const tools::PolyPolygon aPolyPolyRect( ImplMap( aPoly ) );
         maClipPath.excludeClip( aPolyPolyRect.getB2DPolyPolygon() );
     }
 
@@ -1390,6 +1377,20 @@ namespace emfio
         maActPos = aDest;
     }
 
+    void MtfTools::DrawRectWithBGColor(const tools::Rectangle& rRect)
+    {
+        WinMtfFillStyle aFillStyleBackup = maFillStyle;
+        bool            aTransparentBackup = maLineStyle.bTransparent;
+
+        const tools::Polygon aPoly( rRect );
+        maLineStyle.bTransparent = true;
+        maFillStyle = maBkColor;
+        ImplSetNonPersistentLineColorTransparenz();
+        DrawPolygon(aPoly, false);
+        maFillStyle = aFillStyleBackup;
+        maLineStyle.bTransparent = aTransparentBackup;
+    }
+
     void MtfTools::DrawRect( const tools::Rectangle& rRect, bool bEdge )
     {
         UpdateClipRegion();
diff --git a/emfio/source/reader/wmfreader.cxx 
b/emfio/source/reader/wmfreader.cxx
index 2f0aafabfaa9..f14949135ad4 100644
--- a/emfio/source/reader/wmfreader.cxx
+++ b/emfio/source/reader/wmfreader.cxx
@@ -666,8 +666,9 @@ namespace emfio
                 Point aPosition = ReadYX();
                 sal_uInt16 nLen = 0, nOptions = 0;
                 mpInputStream->ReadUInt16( nLen ).ReadUInt16( nOptions );
-
-                if (nOptions & ETO_CLIPPED)
+                SAL_INFO( "emfio", "\t\t\t Pos: " << aPosition.getX() << ":" 
<< aPosition.getY() << " String Length: " << nLen << " Options: " << nOptions );
+                tools::Rectangle aRect;
+                if ( ( nOptions & ETO_CLIPPED ) || ( nOptions & ETO_OPAQUE ) )
                 {
                     nNonStringLen += 2 * sizeof(sal_uInt16);
 
@@ -676,10 +677,12 @@ namespace emfio
                         SAL_WARN("emfio", "W_META_TEXTOUT too short");
                         break;
                     }
-
-                    ReadPoint();
-                    ReadPoint();
-                    SAL_WARN("emfio", "clipping unsupported");
+                    const Point aTopLeft = ReadPoint();
+                    const Point aBottomRight = ReadPoint();
+                    aRect = tools::Rectangle( aTopLeft, aBottomRight );
+                    if ( nOptions & ETO_OPAQUE )
+                        DrawRectWithBGColor( aRect );
+                    SAL_INFO( "emfio", "\t\t\t Rectangle : " << 
aTopLeft.getX() << ":" << aTopLeft.getY() << ", " << aBottomRight.getX() << ":" 
<< aBottomRight.getY() );
                 }
 
                 ComplexTextLayoutFlags nTextLayoutMode = 
ComplexTextLayoutFlags::Default;
@@ -709,6 +712,12 @@ namespace emfio
                                                                                
        // dxAry will not fit
                     if ( nNewTextLen )
                     {
+                        if ( nOptions & ETO_CLIPPED )
+                        {
+                            Push(); // Save the current clip. It will be 
restored after text drawing
+                            IntersectClipRect( aRect );
+                        }
+                        SAL_INFO( "emfio", "\t\t\t Text : " << aText );
                         std::unique_ptr<tools::Long[]> pDXAry, pDYAry;
                         auto nDxArySize =  nMaxStreamPos - 
mpInputStream->Tell();
                         auto nDxAryEntries = nDxArySize >> 1;
@@ -768,6 +777,8 @@ namespace emfio
                             DrawText( aPosition, aText, pDXAry.get(), 
pDYAry.get() );
                         else
                             DrawText( aPosition, aText );
+                        if ( nOptions & ETO_CLIPPED )
+                            Pop();
                     }
                 }
             }
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to