summaryrefslogtreecommitdiff
path: root/emfio
diff options
context:
space:
mode:
Diffstat (limited to 'emfio')
-rw-r--r--emfio/inc/mtftools.hxx79
-rw-r--r--emfio/qa/cppunit/emf/EmfImportTest.cxx19
-rw-r--r--emfio/qa/cppunit/wmf/data/TestLineTo.wmfbin0 -> 240 bytes
-rw-r--r--emfio/source/reader/emfreader.cxx180
-rw-r--r--emfio/source/reader/wmfreader.cxx65
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
new file mode 100644
index 000000000000..14ba0fc6eb5a
--- /dev/null
+++ b/emfio/qa/cppunit/wmf/data/TestLineTo.wmf
Binary files differ
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;