summaryrefslogtreecommitdiff
path: root/emfio
diff options
context:
space:
mode:
authorBartosz Kosiorek <gang65@poczta.onet.pl>2022-03-21 20:20:02 +0100
committerBartosz Kosiorek <gang65@poczta.onet.pl>2023-05-10 16:45:47 +0200
commitba0bf0ab2c24d309e8a938cec26daa41eba9c8cf (patch)
treedb9de0c5255bff176d251f5b121fc4bb1db7dc90 /emfio
parent88bd66d258de5fee3d35aba80c61fec49eb2a969 (diff)
tdf#142249 EMF Implement EMR_POLYDRAW record
The EMR_POLYDRAW record specifies a set of line segments and Bezier curves. Change-Id: I93d846d2fbb7a60b0565668a17ee092da30ef21c Reviewed-on: https://gerrit.libreoffice.org/c/core/+/151424 Tested-by: Jenkins Reviewed-by: Bartosz Kosiorek <gang65@poczta.onet.pl>
Diffstat (limited to 'emfio')
-rw-r--r--emfio/qa/cppunit/emf/EmfImportTest.cxx24
-rw-r--r--emfio/qa/cppunit/emf/data/TestEmfPolydraw.emfbin0 -> 368 bytes
-rw-r--r--emfio/source/reader/emfreader.cxx88
-rw-r--r--emfio/source/reader/mtftools.cxx6
4 files changed, 115 insertions, 3 deletions
diff --git a/emfio/qa/cppunit/emf/EmfImportTest.cxx b/emfio/qa/cppunit/emf/EmfImportTest.cxx
index 5f8ad7e18044..ba0a8050f24e 100644
--- a/emfio/qa/cppunit/emf/EmfImportTest.cxx
+++ b/emfio/qa/cppunit/emf/EmfImportTest.cxx
@@ -891,6 +891,30 @@ CPPUNIT_TEST_FIXTURE(Test, testPolylinetoCloseStroke)
assertXPath(pDocument, aXPathPrefix + "polygonhairline[2]", "color", "#000000");
}
+CPPUNIT_TEST_FIXTURE(Test, testEmfPolydraw)
+{
+ // tdf#142249 EMF import with records: POLYDRAW, CREATEPEN.
+ Primitive2DSequence aSequence = parseEmf(u"/emfio/qa/cppunit/emf/data/TestEmfPolydraw.emf");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequence.getLength()));
+ drawinglayer::Primitive2dXmlDump dumper;
+ xmlDocUniquePtr pDocument = dumper.dumpAndParse(Primitive2DContainer(aSequence));
+ CPPUNIT_ASSERT(pDocument);
+
+ assertXPath(pDocument, aXPathPrefix + "polygonhairline", 2);
+ assertXPath(pDocument, aXPathPrefix + "polygonhairline[1]", "color", "#000000");
+ assertXPathContent(pDocument, aXPathPrefix + "polygonhairline[1]/polygon",
+ "2000,200 3000,200 3000,1000");
+ assertXPath(pDocument, aXPathPrefix + "polygonhairline[2]", "color", "#000000");
+ assertXPathContent(pDocument, aXPathPrefix + "polygonhairline[2]/polygon",
+ "3000,2000 3000,2000 4000,2000 3000,3000");
+
+ assertXPath(pDocument, aXPathPrefix + "polygonstroke", 1);
+ assertXPathContent(pDocument, aXPathPrefix + "polygonstroke[1]/polygon",
+ "50,50 50,50 1000,1000 1000,1000 2000,2500 2000,1000");
+ assertXPath(pDocument, aXPathPrefix + "polygonstroke[1]/line", "color", "#ff0000");
+ assertXPath(pDocument, aXPathPrefix + "polygonstroke[1]/stroke", "dotDashArray", "30 10 ");
+}
+
CPPUNIT_TEST_FIXTURE(Test, testEmfPlusBrushPathGradientWithBlendColors)
{
// tdf#131506 EMF+ records: FillRects, Brush with PathGradient and BlendColor, FillRects
diff --git a/emfio/qa/cppunit/emf/data/TestEmfPolydraw.emf b/emfio/qa/cppunit/emf/data/TestEmfPolydraw.emf
new file mode 100644
index 000000000000..962b163bf363
--- /dev/null
+++ b/emfio/qa/cppunit/emf/data/TestEmfPolydraw.emf
Binary files differ
diff --git a/emfio/source/reader/emfreader.cxx b/emfio/source/reader/emfreader.cxx
index af676e7de669..ee848097b84f 100644
--- a/emfio/source/reader/emfreader.cxx
+++ b/emfio/source/reader/emfreader.cxx
@@ -175,6 +175,16 @@ constexpr sal_Int32 ARCDIRECTION_CLOCKWISE = 0x00000002;
namespace
{
+/* [MS-EMF] - v20210625 - page 41 */
+/* 2.1.26 Point Enumeration */
+enum EMFPointTypes
+{
+ PT_CLOSEFIGURE = 0x01,
+ PT_LINETO = 0x02,
+ PT_BEZIERTO = 0x04,
+ PT_MOVETO = 0x06
+};
+
const char *
record_type_name(sal_uInt32 nRecType)
{
@@ -932,6 +942,83 @@ namespace emfio
DrawPolyLine(ReadPolygonWithSkip<sal_Int32>(true, nNextPos), true, mbRecordPath);
break;
+ case EMR_POLYDRAW:
+ {
+ sal_uInt32 nPointsCount, nBezierCount = 0;
+ std::vector<Point> aPoints;
+ sal_Int32 nX, nY;
+ bool wrongFile = false;
+ unsigned char nPointType;
+ std::vector<unsigned char> aPointTypes;
+ mpInputStream->ReadInt32(nX32)
+ .ReadInt32(nY32)
+ .ReadInt32(nx32)
+ .ReadInt32(ny32)
+ .ReadUInt32(nPointsCount);
+
+ aPoints.reserve(nPointsCount);
+ for (sal_uInt32 i = 0; i < nPointsCount && mpInputStream->good(); i++)
+ {
+ *mpInputStream >> nX >> nY;
+ aPoints.push_back(Point(nX, nY));
+ }
+ aPointTypes.reserve(nPointsCount);
+ for (sal_uInt32 i = 0; i < nPointsCount && mpInputStream->good(); i++)
+ {
+ mpInputStream->ReadUChar(nPointType);
+ aPointTypes.push_back(nPointType);
+ SAL_INFO_IF(aPointTypes[i] == PT_MOVETO, "emfio",
+ "\t\t" << i << "/" << nPointsCount - 1 << " PT_MOVETO, "
+ << aPoints[i].getX() << ", " << aPoints[i].getY());
+ SAL_INFO_IF((aPointTypes[i] != PT_MOVETO) && (aPointTypes[i] & PT_LINETO), "emfio",
+ "\t\t" << i << "/" << nPointsCount - 1 << " PT_LINETO, "
+ << aPoints[i].getX() << ", " << aPoints[i].getY());
+ SAL_INFO_IF((aPointTypes[i] != PT_MOVETO) && (aPointTypes[i] & PT_CLOSEFIGURE), "emfio",
+ "\t\t" << i << "/" << nPointsCount - 1 << " PT_CLOSEFIGURE, "
+ << aPoints[i].getX() << ", " << aPoints[i].getY());
+ SAL_INFO_IF((aPointTypes[i] != PT_MOVETO) && (aPointTypes[i] & PT_BEZIERTO), "emfio",
+ "\t\t" << i << "/" << nPointsCount - 1 << " PT_BEZIERTO, "
+ << aPoints[i].getX() << ", " << aPoints[i].getY());
+
+ if ((aPointTypes[i] != PT_MOVETO) && (nPointType & PT_BEZIERTO))
+ nBezierCount++;
+ else if (nBezierCount % 3 == 0)
+ nBezierCount = 0;
+ else
+ {
+ SAL_WARN(
+ "emfio",
+ "EMF file error: Number of Bezier points is not set of three.");
+ wrongFile = true;
+ }
+ }
+ if (wrongFile) break;
+ for (sal_uInt32 i = 0; i < nPointsCount; i++)
+ {
+ if (aPointTypes[i] == PT_MOVETO)
+ MoveTo(aPoints[i], true);
+ else if (aPointTypes[i] & PT_LINETO)
+ {
+ LineTo(aPoints[i], true);
+ if (aPointTypes[i] & PT_CLOSEFIGURE)
+ ClosePath();
+ }
+ else if (aPointTypes[i] & PT_BEZIERTO)
+ {
+ tools::Polygon aPolygon(4);
+ aPolygon[0] = maActPos;
+ aPolygon[1] = aPoints[i++];
+ aPolygon[2] = aPoints[i++];
+ aPolygon[3] = aPoints[i];
+ DrawPolyBezier(std::move(aPolygon), true, true);
+ if (aPointTypes[i] & PT_CLOSEFIGURE)
+ ClosePath();
+ }
+ }
+ StrokeAndFillPath(true, false);
+ }
+ break;
+
case EMR_POLYLINE :
DrawPolyLine(ReadPolygonWithSkip<sal_Int32>(false, nNextPos), false, mbRecordPath);
break;
@@ -2047,7 +2134,6 @@ namespace emfio
case EMR_INVERTRGN :
case EMR_FLATTENPATH :
case EMR_WIDENPATH :
- case EMR_POLYDRAW :
case EMR_SETPALETTEENTRIES :
case EMR_RESIZEPALETTE :
case EMR_EXTFLOODFILL :
diff --git a/emfio/source/reader/mtftools.cxx b/emfio/source/reader/mtftools.cxx
index 5b82c54daa21..8c85d0e126a3 100644
--- a/emfio/source/reader/mtftools.cxx
+++ b/emfio/source/reader/mtftools.cxx
@@ -1618,10 +1618,12 @@ namespace emfio
{
sal_uInt16 nPoints = rPolygon.GetSize();
if ( ( nPoints < 4 ) || ( ( ( nPoints - 4 ) % 3 ) != 0 ) )
+ {
+ SAL_WARN("emfio",
+ "EMF file error: Number of Bezier points is not set of three");
return;
-
+ }
UpdateClipRegion();
-
ImplMap( rPolygon );
if ( bTo )
{