diff options
Diffstat (limited to 'emfio')
-rw-r--r-- | emfio/inc/mtftools.hxx | 79 | ||||
-rw-r--r-- | emfio/qa/cppunit/emf/EmfImportTest.cxx | 19 | ||||
-rw-r--r-- | emfio/qa/cppunit/wmf/data/TestLineTo.wmf | bin | 0 -> 240 bytes | |||
-rw-r--r-- | emfio/source/reader/emfreader.cxx | 180 | ||||
-rw-r--r-- | emfio/source/reader/wmfreader.cxx | 65 |
5 files changed, 110 insertions, 233 deletions
diff --git a/emfio/inc/mtftools.hxx b/emfio/inc/mtftools.hxx index 0290c487c574..997f2287f010 100644 --- a/emfio/inc/mtftools.hxx +++ b/emfio/inc/mtftools.hxx @@ -204,8 +204,6 @@ namespace emfio enum PenStyle : sal_uInt32 { PS_COSMETIC = 0x00000000, - PS_ENDCAP_ROUND = 0x00000000, - PS_JOIN_ROUND = 0x00000000, PS_SOLID = 0x00000000, PS_DASH = 0x00000001, PS_DOT = 0x00000002, @@ -216,12 +214,17 @@ namespace emfio PS_USERSTYLE = 0x00000007, PS_ALTERNATE = 0x00000008, PS_STYLE_MASK = 0x0000000F, + + PS_ENDCAP_ROUND = 0x00000000, PS_ENDCAP_SQUARE = 0x00000100, PS_ENDCAP_FLAT = 0x00000200, PS_ENDCAP_STYLE_MASK = 0x00000F00, + + PS_JOIN_ROUND = 0x00000000, PS_JOIN_BEVEL = 0x00001000, PS_JOIN_MITER = 0x00002000, PS_JOIN_STYLE_MASK = 0x0000F000, + PS_GEOMETRIC = 0x00010000 }; @@ -461,11 +464,75 @@ namespace emfio , bTransparent(bTrans) {} - WinMtfLineStyle(const Color& rColor, const LineInfo& rStyle, bool bTrans) + WinMtfLineStyle(const Color& rColor, const sal_uInt32 nStyle, const sal_Int32 nPenWidth) : aLineColor(rColor) - , aLineInfo(rStyle) - , bTransparent(bTrans) - {} + { + // According to documentation: nStyle = PS_COSMETIC = 0x0 - line with a width of one logical unit and a style that is a solid color + // tdf#140271 Based on observed behaviour the line width is not constant with PS_COSMETIC + + // Width 0 means default width for LineInfo (HairLine) with 1 pixel wide + aLineInfo.SetWidth(nPenWidth); + switch (nStyle & PS_STYLE_MASK) + { + case PS_DASHDOTDOT: + aLineInfo.SetStyle(LineStyle::Dash); + aLineInfo.SetDashCount(1); + aLineInfo.SetDotCount(2); + break; + case PS_DASHDOT: + aLineInfo.SetStyle(LineStyle::Dash); + aLineInfo.SetDashCount(1); + aLineInfo.SetDotCount(1); + break; + case PS_DOT: + aLineInfo.SetStyle(LineStyle::Dash); + aLineInfo.SetDashCount(0); + aLineInfo.SetDotCount(1); + break; + case PS_DASH: + aLineInfo.SetStyle(LineStyle::Dash); + aLineInfo.SetDashCount(1); + aLineInfo.SetDotCount(0); + break; + case PS_NULL: + aLineInfo.SetStyle(LineStyle::NONE); + break; + case PS_INSIDEFRAME: // TODO Implement PS_INSIDEFRAME + case PS_SOLID: + default: + aLineInfo.SetStyle(LineStyle::Solid); + } + if (nPenWidth) + switch (nStyle & PS_ENDCAP_STYLE_MASK) + { + case PS_ENDCAP_ROUND: + aLineInfo.SetLineCap(css::drawing::LineCap_ROUND); + break; + case PS_ENDCAP_SQUARE: + aLineInfo.SetLineCap(css::drawing::LineCap_SQUARE); + break; + case PS_ENDCAP_FLAT: + default: + aLineInfo.SetLineCap(css::drawing::LineCap_BUTT); + } + else + aLineInfo.SetLineCap(css::drawing::LineCap_BUTT); + switch (nStyle & PS_JOIN_STYLE_MASK) + { + case PS_JOIN_ROUND: + aLineInfo.SetLineJoin(basegfx::B2DLineJoin::Round); + break; + case PS_JOIN_BEVEL: + aLineInfo.SetLineJoin(basegfx::B2DLineJoin::Bevel); + break; + // Undocumented but based on experiments with MS Paint and MS Word, + // the default Join Style is PS_JOIN_MITER + case PS_JOIN_MITER: + default: + aLineInfo.SetLineJoin(basegfx::B2DLineJoin::Miter); + } + bTransparent = aLineInfo.GetStyle() == LineStyle::NONE; + } bool operator==(const WinMtfLineStyle& rStyle) const { diff --git a/emfio/qa/cppunit/emf/EmfImportTest.cxx b/emfio/qa/cppunit/emf/EmfImportTest.cxx index e8db00e21fcc..5891799dd607 100644 --- a/emfio/qa/cppunit/emf/EmfImportTest.cxx +++ b/emfio/qa/cppunit/emf/EmfImportTest.cxx @@ -74,6 +74,7 @@ class Test : public test::BootstrapFixture, public XmlTestTools, public unotest: void TestRestoreDCWMF(); void TestRoundrectWMF(); void TestStretchDIBWMF(); + void TestMoveToLineToWMF(); void TestPolylinetoCloseStroke(); void TestPolyLineWidth(); @@ -120,6 +121,7 @@ public: CPPUNIT_TEST(TestRestoreDCWMF); CPPUNIT_TEST(TestRoundrectWMF); CPPUNIT_TEST(TestStretchDIBWMF); + CPPUNIT_TEST(TestMoveToLineToWMF); CPPUNIT_TEST(TestPolylinetoCloseStroke); CPPUNIT_TEST(TestPolyLineWidth); CPPUNIT_TEST(TestRestoreDC); @@ -1206,6 +1208,23 @@ void Test::TestStretchDIBWMF() "720000,721c1c,723838,725555,727171,72728d,55728d,39728d,1d728d,00728d"); } +void Test::TestMoveToLineToWMF() +{ + // tdf#89331 WMF records: MOTETO, LINETO, CREATEPENINDIRECT. + Primitive2DSequence aSequence = parseEmf(u"/emfio/qa/cppunit/wmf/data/TestLineTo.wmf"); + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequence.getLength())); + drawinglayer::Primitive2dXmlDump dumper; + xmlDocUniquePtr pDocument = dumper.dumpAndParse(Primitive2DContainer(aSequence)); + CPPUNIT_ASSERT(pDocument); + + assertXPathContent(pDocument, aXPathPrefix + "polygonstroke/polygon", + "5856,3586 7167,621 8625,3586"); + assertXPath(pDocument, aXPathPrefix + "polygonstroke/line", "color", "#800000"); + assertXPath(pDocument, aXPathPrefix + "polygonstroke/line", "width", "310"); + assertXPath(pDocument, aXPathPrefix + "polygonstroke/line", "linejoin", "Bevel"); + assertXPath(pDocument, aXPathPrefix + "polygonstroke/line", "linecap", "ROUND"); +} + void Test::TestPolyLineWidth() { // EMF import with records: CREATEPEN, ROUNDRECT. diff --git a/emfio/qa/cppunit/wmf/data/TestLineTo.wmf b/emfio/qa/cppunit/wmf/data/TestLineTo.wmf Binary files differnew file mode 100644 index 000000000000..14ba0fc6eb5a --- /dev/null +++ b/emfio/qa/cppunit/wmf/data/TestLineTo.wmf diff --git a/emfio/source/reader/emfreader.cxx b/emfio/source/reader/emfreader.cxx index 54be65c3bcbf..389414c79b9f 100644 --- a/emfio/source/reader/emfreader.cxx +++ b/emfio/source/reader/emfreader.cxx @@ -1144,187 +1144,41 @@ namespace emfio } break; - case EMR_CREATEPEN : + case EMR_CREATEPEN: { - mpInputStream->ReadUInt32( nIndex ); - if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 ) + mpInputStream->ReadUInt32(nIndex); + if ((nIndex & ENHMETA_STOCK_OBJECT) == 0) { - LineInfo aLineInfo; sal_uInt32 nStyle(0); sal_Int32 nPenWidth(0), nIgnored; - - mpInputStream->ReadUInt32( nStyle ).ReadInt32( nPenWidth ).ReadInt32( nIgnored ); - - SAL_INFO("emfio", "\t\tIndex: " << nIndex << " Style: 0x" << std::hex << nStyle << std::dec << " PenWidth: " << nPenWidth); - // According to documentation: nStyle = PS_COSMETIC = 0x0 - line with a width of one logical unit and a style that is a solid color - // tdf#140271 Based on observed behaviour the line width is not constant with PS_COSMETIC - - // Width 0 means default width for LineInfo (HairLine) with 1 pixel wide - aLineInfo.SetWidth( nPenWidth ); - - bool bTransparent = false; - switch( nStyle & PS_STYLE_MASK ) - { - case PS_DASHDOTDOT : - aLineInfo.SetStyle( LineStyle::Dash ); - aLineInfo.SetDashCount( 1 ); - aLineInfo.SetDotCount( 2 ); - break; - case PS_DASHDOT : - aLineInfo.SetStyle( LineStyle::Dash ); - aLineInfo.SetDashCount( 1 ); - aLineInfo.SetDotCount( 1 ); - break; - case PS_DOT : - aLineInfo.SetStyle( LineStyle::Dash ); - aLineInfo.SetDashCount( 0 ); - aLineInfo.SetDotCount( 1 ); - break; - case PS_DASH : - aLineInfo.SetStyle( LineStyle::Dash ); - aLineInfo.SetDashCount( 1 ); - aLineInfo.SetDotCount( 0 ); - break; - case PS_NULL : - bTransparent = true; - aLineInfo.SetStyle( LineStyle::NONE ); - break; - case PS_INSIDEFRAME : - case PS_SOLID : - default : - aLineInfo.SetStyle( LineStyle::Solid ); - } - switch( nStyle & PS_ENDCAP_STYLE_MASK ) - { - case PS_ENDCAP_ROUND : - if ( nPenWidth ) - { - aLineInfo.SetLineCap( css::drawing::LineCap_ROUND ); - break; - } - [[fallthrough]]; - case PS_ENDCAP_SQUARE : - if ( nPenWidth ) - { - aLineInfo.SetLineCap( css::drawing::LineCap_SQUARE ); - break; - } - [[fallthrough]]; - case PS_ENDCAP_FLAT : - default : - aLineInfo.SetLineCap( css::drawing::LineCap_BUTT ); - } - switch( nStyle & PS_JOIN_STYLE_MASK ) - { - case PS_JOIN_ROUND : - aLineInfo.SetLineJoin ( basegfx::B2DLineJoin::Round ); - break; - case PS_JOIN_MITER : - aLineInfo.SetLineJoin ( basegfx::B2DLineJoin::Miter ); - break; - case PS_JOIN_BEVEL : - aLineInfo.SetLineJoin ( basegfx::B2DLineJoin::Bevel ); - break; - default : - aLineInfo.SetLineJoin ( basegfx::B2DLineJoin::NONE ); - } - CreateObjectIndexed(nIndex, std::make_unique<WinMtfLineStyle>( ReadColor(), aLineInfo, bTransparent )); + mpInputStream->ReadUInt32(nStyle).ReadInt32(nPenWidth).ReadInt32(nIgnored); + SAL_INFO("emfio", "\t\tIndex: " << nIndex << " Style: 0x" << std::hex + << nStyle << std::dec + << " PenWidth: " << nPenWidth); + CreateObjectIndexed(nIndex, std::make_unique<WinMtfLineStyle>(ReadColor(), nStyle, nPenWidth)); } } break; - case EMR_EXTCREATEPEN : + case EMR_EXTCREATEPEN: { - mpInputStream->ReadUInt32( nIndex ); - if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 ) + mpInputStream->ReadUInt32(nIndex); + if ((nIndex & ENHMETA_STOCK_OBJECT) == 0) { - sal_uInt32 offBmi, cbBmi, offBits, cbBits, nStyle, nWidth, nBrushStyle, elpNumEntries; - sal_Int32 elpHatch; - mpInputStream->ReadUInt32( offBmi ).ReadUInt32( cbBmi ).ReadUInt32( offBits ).ReadUInt32( cbBits ). ReadUInt32( nStyle ).ReadUInt32( nWidth ).ReadUInt32( nBrushStyle ); + sal_uInt32 offBmi, cbBmi, offBits, cbBits, nStyle, nWidth, nBrushStyle, elpNumEntries; + sal_Int32 elpHatch; + mpInputStream->ReadUInt32(offBmi).ReadUInt32(cbBmi).ReadUInt32(offBits).ReadUInt32(cbBits); + mpInputStream->ReadUInt32(nStyle).ReadUInt32(nWidth).ReadUInt32(nBrushStyle); SAL_INFO("emfio", "\t\tStyle: 0x" << std::hex << nStyle << std::dec); SAL_INFO("emfio", "\t\tWidth: " << nWidth); Color aColorRef = ReadColor(); - mpInputStream->ReadInt32( elpHatch ).ReadUInt32( elpNumEntries ); + mpInputStream->ReadInt32(elpHatch).ReadUInt32(elpNumEntries); if (!mpInputStream->good()) bStatus = false; else - { - LineInfo aLineInfo; - if ( nWidth ) - aLineInfo.SetWidth( nWidth ); - - bool bTransparent = false; - - switch( nStyle & PS_STYLE_MASK ) - { - case PS_DASHDOTDOT : - aLineInfo.SetStyle( LineStyle::Dash ); - aLineInfo.SetDashCount( 1 ); - aLineInfo.SetDotCount( 2 ); - break; - case PS_DASHDOT : - aLineInfo.SetStyle( LineStyle::Dash ); - aLineInfo.SetDashCount( 1 ); - aLineInfo.SetDotCount( 1 ); - break; - case PS_DOT : - aLineInfo.SetStyle( LineStyle::Dash ); - aLineInfo.SetDashCount( 0 ); - aLineInfo.SetDotCount( 1 ); - break; - case PS_DASH : - aLineInfo.SetStyle( LineStyle::Dash ); - aLineInfo.SetDashCount( 1 ); - aLineInfo.SetDotCount( 0 ); - break; - case PS_NULL : - bTransparent = true; - aLineInfo.SetStyle( LineStyle::NONE ); - break; - - case PS_INSIDEFRAME : - case PS_SOLID : - default : - aLineInfo.SetStyle( LineStyle::Solid ); - } - switch( nStyle & PS_ENDCAP_STYLE_MASK ) - { - case PS_ENDCAP_ROUND : - if ( aLineInfo.GetWidth() ) - { - aLineInfo.SetLineCap( css::drawing::LineCap_ROUND ); - break; - } - [[fallthrough]]; - case PS_ENDCAP_SQUARE : - if ( aLineInfo.GetWidth() ) - { - aLineInfo.SetLineCap( css::drawing::LineCap_SQUARE ); - break; - } - [[fallthrough]]; - case PS_ENDCAP_FLAT : - default : - aLineInfo.SetLineCap( css::drawing::LineCap_BUTT ); - } - switch( nStyle & PS_JOIN_STYLE_MASK ) - { - case PS_JOIN_ROUND : - aLineInfo.SetLineJoin ( basegfx::B2DLineJoin::Round ); - break; - case PS_JOIN_MITER : - aLineInfo.SetLineJoin ( basegfx::B2DLineJoin::Miter ); - break; - case PS_JOIN_BEVEL : - aLineInfo.SetLineJoin ( basegfx::B2DLineJoin::Bevel ); - break; - default : - aLineInfo.SetLineJoin ( basegfx::B2DLineJoin::NONE ); - } - CreateObjectIndexed(nIndex, std::make_unique<WinMtfLineStyle>( aColorRef, aLineInfo, bTransparent )); - } + CreateObjectIndexed(nIndex, std::make_unique<WinMtfLineStyle>(aColorRef, nStyle, nWidth)); } } break; diff --git a/emfio/source/reader/wmfreader.cxx b/emfio/source/reader/wmfreader.cxx index 44615556793f..5f6eeed66757 100644 --- a/emfio/source/reader/wmfreader.cxx +++ b/emfio/source/reader/wmfreader.cxx @@ -1025,70 +1025,7 @@ namespace emfio mpInputStream->ReadUInt16(nStyle); mpInputStream->ReadUInt16(nWidth); mpInputStream->ReadUInt16(nHeight); - - if (nWidth > 0) - aLineInfo.SetWidth(nWidth); - - bool bTransparent = false; - - switch( nStyle & 0xFF ) - { - case PS_DASHDOTDOT : - aLineInfo.SetStyle( LineStyle::Dash ); - aLineInfo.SetDashCount( 1 ); - aLineInfo.SetDotCount( 2 ); - break; - case PS_DASHDOT : - aLineInfo.SetStyle( LineStyle::Dash ); - aLineInfo.SetDashCount( 1 ); - aLineInfo.SetDotCount( 1 ); - break; - case PS_DOT : - aLineInfo.SetStyle( LineStyle::Dash ); - aLineInfo.SetDashCount( 0 ); - aLineInfo.SetDotCount( 1 ); - break; - case PS_DASH : - aLineInfo.SetStyle( LineStyle::Dash ); - aLineInfo.SetDashCount( 1 ); - aLineInfo.SetDotCount( 0 ); - break; - case PS_NULL : - bTransparent = true; - aLineInfo.SetStyle( LineStyle::NONE ); - break; - default : - case PS_INSIDEFRAME : - case PS_SOLID : - aLineInfo.SetStyle( LineStyle::Solid ); - } - switch( nStyle & 0xF00 ) - { - case PS_ENDCAP_ROUND : - aLineInfo.SetLineCap( css::drawing::LineCap_ROUND ); - break; - case PS_ENDCAP_SQUARE : - aLineInfo.SetLineCap( css::drawing::LineCap_SQUARE ); - break; - case PS_ENDCAP_FLAT : - default : - aLineInfo.SetLineCap( css::drawing::LineCap_BUTT ); - } - switch( nStyle & 0xF000 ) - { - case PS_JOIN_ROUND : - aLineInfo.SetLineJoin ( basegfx::B2DLineJoin::Round ); - break; - case PS_JOIN_MITER : - aLineInfo.SetLineJoin ( basegfx::B2DLineJoin::Miter ); - break; - case PS_JOIN_BEVEL : - aLineInfo.SetLineJoin ( basegfx::B2DLineJoin::Bevel ); - break; - default : - aLineInfo.SetLineJoin ( basegfx::B2DLineJoin::NONE ); - } - CreateObject(std::make_unique<WinMtfLineStyle>( ReadColor(), aLineInfo, bTransparent )); + CreateObject(std::make_unique<WinMtfLineStyle>(ReadColor(), nStyle, nWidth)); } break; |