summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArmin Le Grand <Armin.Le.Grand@cib.de>2017-06-21 19:31:32 +0200
committerThorsten Behrens <Thorsten.Behrens@CIB.de>2017-07-15 11:01:30 +0200
commit41f5459e5d4cbf5024995bce7d967104c7943830 (patch)
treed85eca88a6ac13b4a6eeaf9893a69979947328e4
parent63bc9be68e6d7a0e681516b5a04953388644101a (diff)
emfplus: more corrections and rough geometry
Corrected/streamlined more, added 1st rough geometry creation to have a proof of concept. Checked the helper classes based on EMFPObject and their derivates. First versions of EMFPPlusDrawPolygon and EMFPPlusFillPolygon, but the complex info in the data objects needs more complex primitive creation. Not sure if primitive creators like createHairlineAndFillPrimitive will be usable, these are based on PropertyHolder info. Also added usage of HandleNewClipRegion, that should be usable Change-Id: I96119be290140bee252ee21a3e1187fad60e9c7d
-rw-r--r--drawinglayer/inc/wmfemfhelper.hxx5
-rw-r--r--drawinglayer/source/tools/emfpbrush.cxx450
-rw-r--r--drawinglayer/source/tools/emfpcustomlinecap.cxx7
-rw-r--r--drawinglayer/source/tools/emfpfont.cxx5
-rw-r--r--drawinglayer/source/tools/emfphelperdata.cxx1649
-rw-r--r--drawinglayer/source/tools/emfphelperdata.hxx4
-rw-r--r--drawinglayer/source/tools/emfpimage.cxx21
-rw-r--r--drawinglayer/source/tools/emfppath.cxx79
-rw-r--r--drawinglayer/source/tools/emfppen.cxx77
-rw-r--r--drawinglayer/source/tools/emfpregion.cxx13
-rw-r--r--drawinglayer/source/tools/emfpstringformat.cxx2
11 files changed, 1251 insertions, 1061 deletions
diff --git a/drawinglayer/inc/wmfemfhelper.hxx b/drawinglayer/inc/wmfemfhelper.hxx
index 699b065795df..a11b6578e572 100644
--- a/drawinglayer/inc/wmfemfhelper.hxx
+++ b/drawinglayer/inc/wmfemfhelper.hxx
@@ -208,6 +208,11 @@ namespace wmfemfhelper
drawinglayer::primitive2d::Primitive2DContainer interpretMetafile(
const GDIMetaFile& rMetaFile,
const drawinglayer::geometry::ViewInformation2D& rViewInformation);
+
+ void HandleNewClipRegion(
+ const basegfx::B2DPolyPolygon& rClipPolyPolygon,
+ TargetHolders& rTargetHolders,
+ PropertyHolders& rPropertyHolders);
}
#endif
diff --git a/drawinglayer/source/tools/emfpbrush.cxx b/drawinglayer/source/tools/emfpbrush.cxx
index c093a5682572..d55a16ad30d7 100644
--- a/drawinglayer/source/tools/emfpbrush.cxx
+++ b/drawinglayer/source/tools/emfpbrush.cxx
@@ -64,23 +64,32 @@ namespace emfplushelper
EMFPBrush::~EMFPBrush()
{
- if (blendPositions != nullptr) {
+ if (blendPositions != nullptr)
+ {
delete[] blendPositions;
blendPositions = nullptr;
}
- if (colorblendPositions != nullptr) {
+
+ if (colorblendPositions != nullptr)
+ {
delete[] colorblendPositions;
colorblendPositions = nullptr;
}
- if (colorblendColors != nullptr) {
+
+ if (colorblendColors != nullptr)
+ {
delete[] colorblendColors;
colorblendColors = nullptr;
}
- if (surroundColors != nullptr) {
+
+ if (surroundColors != nullptr)
+ {
delete[] surroundColors;
surroundColors = nullptr;
}
- if (path) {
+
+ if (path)
+ {
delete path;
path = nullptr;
}
@@ -95,232 +104,267 @@ namespace emfplushelper
SAL_INFO("cppcanvas.emf", "EMF+\tbrush");
SAL_INFO("cppcanvas.emf", "EMF+\theader: 0x" << std::hex << header << " type: " << type << std::dec);
- switch (type) {
- case BrushTypeSolidColor:
+ switch (type)
{
- sal_uInt32 color;
+ case BrushTypeSolidColor:
+ {
+ sal_uInt32 color;
+ s.ReadUInt32(color);
- s.ReadUInt32(color);
- solidColor = ::Color(0xff - (color >> 24), (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff);
- SAL_INFO("cppcanvas.emf", "EMF+\tsolid color: 0x" << std::hex << color << std::dec);
- break;
- }
- case BrushTypeHatchFill:
- {
- sal_uInt32 style;
- sal_uInt32 foregroundColor;
- sal_uInt32 backgroundColor;
- s.ReadUInt32(style);
- s.ReadUInt32(foregroundColor);
- s.ReadUInt32(backgroundColor);
-
- hatchStyle = static_cast<EmfPlusHatchStyle>(style);
- solidColor = ::Color(0xff - (foregroundColor >> 24), (foregroundColor >> 16) & 0xff, (foregroundColor >> 8) & 0xff, foregroundColor & 0xff);
- secondColor = ::Color(0xff - (backgroundColor >> 24), (backgroundColor >> 16) & 0xff, (backgroundColor >> 8) & 0xff, backgroundColor & 0xff);
- SAL_INFO("cppcanvas.emf", "EMF+\thatch style " << style << " foregroundcolor: 0x" << solidColor.AsRGBHexString() << " background 0x" << secondColor.AsRGBHexString());
- break;
- }
- case BrushTypeTextureFill:
- {
- SAL_WARN("cppcanvas.emf", "EMF+\tTODO: implement BrushTypeTextureFill brush");
- break;
- }
- case BrushTypePathGradient:
- {
- s.ReadUInt32(additionalFlags).ReadInt32(wrapMode);
+ solidColor = ::Color(0xff - (color >> 24), (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff);
+ SAL_INFO("cppcanvas.emf", "EMF+\tsolid color: 0x" << std::hex << color << std::dec);
+ break;
+ }
+ case BrushTypeHatchFill:
+ {
+ sal_uInt32 style;
+ sal_uInt32 foregroundColor;
+ sal_uInt32 backgroundColor;
+ s.ReadUInt32(style);
+ s.ReadUInt32(foregroundColor);
+ s.ReadUInt32(backgroundColor);
+
+ hatchStyle = static_cast<EmfPlusHatchStyle>(style);
+ solidColor = ::Color(0xff - (foregroundColor >> 24), (foregroundColor >> 16) & 0xff, (foregroundColor >> 8) & 0xff, foregroundColor & 0xff);
+ secondColor = ::Color(0xff - (backgroundColor >> 24), (backgroundColor >> 16) & 0xff, (backgroundColor >> 8) & 0xff, backgroundColor & 0xff);
+ SAL_INFO("cppcanvas.emf", "EMF+\thatch style " << style << " foregroundcolor: 0x" << solidColor.AsRGBHexString() << " background 0x" << secondColor.AsRGBHexString());
+ break;
+ }
+ case BrushTypeTextureFill:
+ {
+ SAL_WARN("cppcanvas.emf", "EMF+\tTODO: implement BrushTypeTextureFill brush");
+ break;
+ }
+ case BrushTypePathGradient:
+ {
+ s.ReadUInt32(additionalFlags).ReadInt32(wrapMode);
+ SAL_INFO("cppcanvas.emf", "EMF+\tpath gradient, additional flags: 0x" << std::hex << additionalFlags << std::dec);
+ sal_uInt32 color;
+ s.ReadUInt32(color);
+ solidColor = ::Color(0xff - (color >> 24), (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff);
+ SAL_INFO("cppcanvas.emf", "EMF+\tcenter color: 0x" << std::hex << color << std::dec);
+ s.ReadFloat(areaX).ReadFloat(areaY);
+ SAL_INFO("cppcanvas.emf", "EMF+\tcenter point: " << areaX << "," << areaY);
+ s.ReadInt32(surroundColorsNumber);
+ SAL_INFO("cppcanvas.emf", "EMF+\t number of surround colors: " << surroundColorsNumber);
+
+ if (surroundColorsNumber<0 || sal_uInt32(surroundColorsNumber)>SAL_MAX_INT32 / sizeof(::Color))
+ {
+ surroundColorsNumber = SAL_MAX_INT32 / sizeof(::Color);
+ }
- SAL_INFO("cppcanvas.emf", "EMF+\tpath gradient, additional flags: 0x" << std::hex << additionalFlags << std::dec);
+ surroundColors = new ::Color[surroundColorsNumber];
- sal_uInt32 color;
+ for (int i = 0; i < surroundColorsNumber; i++)
+ {
+ s.ReadUInt32(color);
+ surroundColors[i] = ::Color(0xff - (color >> 24), (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff);
+ if (i == 0)
+ secondColor = surroundColors[0];
+ SAL_INFO("cppcanvas.emf", "EMF+\tsurround color[" << i << "]: 0x" << std::hex << color << std::dec);
+ }
- s.ReadUInt32(color);
- solidColor = ::Color(0xff - (color >> 24), (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff);
- SAL_INFO("cppcanvas.emf", "EMF+\tcenter color: 0x" << std::hex << color << std::dec);
+ if (additionalFlags & 0x01)
+ {
+ sal_Int32 pathLength;
- s.ReadFloat(areaX).ReadFloat(areaY);
- SAL_INFO("cppcanvas.emf", "EMF+\tcenter point: " << areaX << "," << areaY);
+ s.ReadInt32(pathLength);
+ SAL_INFO("cppcanvas.emf", "EMF+\tpath length: " << pathLength);
- s.ReadInt32(surroundColorsNumber);
- SAL_INFO("cppcanvas.emf", "EMF+\t number of surround colors: " << surroundColorsNumber);
+ sal_uInt64 const pos = s.Tell();
- if (surroundColorsNumber<0 || sal_uInt32(surroundColorsNumber)>SAL_MAX_INT32 / sizeof(::Color))
- surroundColorsNumber = SAL_MAX_INT32 / sizeof(::Color);
+ sal_uInt32 pathHeader;
+ sal_Int32 pathPoints, pathFlags;
+ s.ReadUInt32(pathHeader).ReadInt32(pathPoints).ReadInt32(pathFlags);
- surroundColors = new ::Color[surroundColorsNumber];
- for (int i = 0; i < surroundColorsNumber; i++) {
- s.ReadUInt32(color);
- surroundColors[i] = ::Color(0xff - (color >> 24), (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff);
- if (i == 0)
- secondColor = surroundColors[0];
- SAL_INFO("cppcanvas.emf", "EMF+\tsurround color[" << i << "]: 0x" << std::hex << color << std::dec);
- }
+ SAL_INFO("cppcanvas.emf", "EMF+\tpath (brush path gradient)");
+ SAL_INFO("cppcanvas.emf", "EMF+\theader: 0x" << std::hex << pathHeader << " points: " << std::dec << pathPoints << " additional flags: 0x" << std::hex << pathFlags << std::dec);
- if (additionalFlags & 0x01) {
- sal_Int32 pathLength;
+ path = new EMFPPath(pathPoints);
+ path->Read(s, pathFlags, rR);
- s.ReadInt32(pathLength);
- SAL_INFO("cppcanvas.emf", "EMF+\tpath length: " << pathLength);
+ s.Seek(pos + pathLength);
- sal_uInt64 const pos = s.Tell();
+ const ::basegfx::B2DRectangle aBounds(::basegfx::tools::getRange(path->GetPolygon(rR, false)));
+ areaWidth = aBounds.getWidth();
+ areaHeight = aBounds.getHeight();
+ SAL_INFO("cppcanvas.emf", "EMF+\t polygon bounding box: " << aBounds.getMinX() << "," << aBounds.getMinY() << " " << aBounds.getWidth() << "x" << aBounds.getHeight());
+ }
+ else
+ {
+ sal_Int32 boundaryPointCount;
+ s.ReadInt32(boundaryPointCount);
+
+ sal_uInt64 const pos = s.Tell();
+ SAL_INFO("cppcanvas.emf", "EMF+\t use boundary, points: " << boundaryPointCount);
+ path = new EMFPPath(boundaryPointCount);
+ path->Read(s, 0x0, rR);
+
+ s.Seek(pos + 8 * boundaryPointCount);
+
+ const ::basegfx::B2DRectangle aBounds(::basegfx::tools::getRange(path->GetPolygon(rR, false)));
+ areaWidth = aBounds.getWidth();
+ areaHeight = aBounds.getHeight();
+ SAL_INFO("cppcanvas.emf", "EMF+\t polygon bounding box: " << aBounds.getMinX() << "," << aBounds.getMinY() << " " << aBounds.getWidth() << "x" << aBounds.getHeight());
+ }
- sal_uInt32 pathHeader;
- sal_Int32 pathPoints, pathFlags;
- s.ReadUInt32(pathHeader).ReadInt32(pathPoints).ReadInt32(pathFlags);
+ if (additionalFlags & 0x02)
+ {
+ SAL_INFO("cppcanvas.emf", "EMF+\tuse transformation");
+ rR.readXForm(s, brush_transformation);
+ hasTransformation = true;
+ SAL_INFO("cppcanvas.emf",
+ "EMF+\tm11: " << brush_transformation.get(0,0) << " m12: " << brush_transformation.get(1,0) <<
+ "\nEMF+\tm21: " << brush_transformation.get(0,1) << " m22: " << brush_transformation.get(1,1) <<
+ "\nEMF+\tdx: " << brush_transformation.get(0,2) << " dy: " << brush_transformation.get(1,2));
- SAL_INFO("cppcanvas.emf", "EMF+\tpath (brush path gradient)");
- SAL_INFO("cppcanvas.emf", "EMF+\theader: 0x" << std::hex << pathHeader << " points: " << std::dec << pathPoints << " additional flags: 0x" << std::hex << pathFlags << std::dec);
+ }
- path = new EMFPPath(pathPoints);
- path->Read(s, pathFlags, rR);
+ if (additionalFlags & 0x08)
+ {
+ s.ReadInt32(blendPoints);
+ SAL_INFO("cppcanvas.emf", "EMF+\tuse blend, points: " << blendPoints);
+ if (blendPoints<0 || sal_uInt32(blendPoints)>SAL_MAX_INT32 / (2 * sizeof(float)))
+ blendPoints = SAL_MAX_INT32 / (2 * sizeof(float));
+ blendPositions = new float[2 * blendPoints];
+ blendFactors = blendPositions + blendPoints;
+
+ for (int i = 0; i < blendPoints; i++)
+ {
+ s.ReadFloat(blendPositions[i]);
+ SAL_INFO("cppcanvas.emf", "EMF+\tposition[" << i << "]: " << blendPositions[i]);
+ }
+
+ for (int i = 0; i < blendPoints; i++)
+ {
+ s.ReadFloat(blendFactors[i]);
+ SAL_INFO("cppcanvas.emf", "EMF+\tfactor[" << i << "]: " << blendFactors[i]);
+ }
+ }
- s.Seek(pos + pathLength);
+ if (additionalFlags & 0x04)
+ {
+ s.ReadInt32(colorblendPoints);
+ SAL_INFO("cppcanvas.emf", "EMF+\tuse color blend, points: " << colorblendPoints);
+
+ if (colorblendPoints<0 || sal_uInt32(colorblendPoints)>SAL_MAX_INT32 / sizeof(float))
+ {
+ colorblendPoints = SAL_MAX_INT32 / sizeof(float);
+ }
+
+ if (sal_uInt32(colorblendPoints) > SAL_MAX_INT32 / sizeof(::Color))
+ {
+ colorblendPoints = SAL_MAX_INT32 / sizeof(::Color);
+ }
+
+ colorblendPositions = new float[colorblendPoints];
+ colorblendColors = new ::Color[colorblendPoints];
+
+ for (int i = 0; i < colorblendPoints; i++)
+ {
+ s.ReadFloat(colorblendPositions[i]);
+ SAL_INFO("cppcanvas.emf", "EMF+\tposition[" << i << "]: " << colorblendPositions[i]);
+ }
+
+ for (int i = 0; i < colorblendPoints; i++)
+ {
+ s.ReadUInt32(color);
+ colorblendColors[i] = ::Color(0xff - (color >> 24), (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff);
+ SAL_INFO("cppcanvas.emf", "EMF+\tcolor[" << i << "]: 0x" << std::hex << color << std::dec);
+ }
+ }
- const ::basegfx::B2DRectangle aBounds(::basegfx::tools::getRange(path->GetPolygon(rR, false)));
- areaWidth = aBounds.getWidth();
- areaHeight = aBounds.getHeight();
- SAL_INFO("cppcanvas.emf", "EMF+\t polygon bounding box: " << aBounds.getMinX() << "," << aBounds.getMinY() << " " << aBounds.getWidth() << "x" << aBounds.getHeight());
+ break;
}
- else
+ case BrushTypeLinearGradient:
{
- sal_Int32 boundaryPointCount;
- s.ReadInt32(boundaryPointCount);
-
- sal_uInt64 const pos = s.Tell();
- SAL_INFO("cppcanvas.emf", "EMF+\t use boundary, points: " << boundaryPointCount);
- path = new EMFPPath(boundaryPointCount);
- path->Read(s, 0x0, rR);
-
- s.Seek(pos + 8 * boundaryPointCount);
-
- const ::basegfx::B2DRectangle aBounds(::basegfx::tools::getRange(path->GetPolygon(rR, false)));
- areaWidth = aBounds.getWidth();
- areaHeight = aBounds.getHeight();
- SAL_INFO("cppcanvas.emf", "EMF+\t polygon bounding box: " << aBounds.getMinX() << "," << aBounds.getMinY() << " " << aBounds.getWidth() << "x" << aBounds.getHeight());
- }
+ s.ReadUInt32(additionalFlags).ReadInt32(wrapMode);
+ SAL_INFO("cppcanvas.emf", "EMF+\tlinear gradient, additional flags: 0x" << std::hex << additionalFlags << std::dec);
+ s.ReadFloat(areaX).ReadFloat(areaY).ReadFloat(areaWidth).ReadFloat(areaHeight);
+ SAL_INFO("cppcanvas.emf", "EMF+\tarea: " << areaX << "," << areaY << " - " << areaWidth << "x" << areaHeight);
+ sal_uInt32 color;
+ s.ReadUInt32(color);
+ solidColor = ::Color(0xff - (color >> 24), (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff);
+ SAL_INFO("cppcanvas.emf", "EMF+\tfirst color: 0x" << std::hex << color << std::dec);
+ s.ReadUInt32(color);
+ secondColor = ::Color(0xff - (color >> 24), (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff);
+ SAL_INFO("cppcanvas.emf", "EMF+\tsecond color: 0x" << std::hex << color << std::dec);
- if (additionalFlags & 0x02) {
- SAL_INFO("cppcanvas.emf", "EMF+\tuse transformation");
- rR.readXForm(s, brush_transformation);
- hasTransformation = true;
- SAL_INFO("cppcanvas.emf",
- "EMF+\tm11: " << brush_transformation.get(0,0) << " m12: " << brush_transformation.get(1,0) <<
- "\nEMF+\tm21: " << brush_transformation.get(0,1) << " m22: " << brush_transformation.get(1,1) <<
- "\nEMF+\tdx: " << brush_transformation.get(0,2) << " dy: " << brush_transformation.get(1,2));
+ // repeated colors, unknown meaning, see http://www.aces.uiuc.edu/~jhtodd/Metafile/MetafileRecords/ObjectBrush.html
+ s.ReadUInt32(color);
+ s.ReadUInt32(color);
- }
- if (additionalFlags & 0x08) {
- s.ReadInt32(blendPoints);
- SAL_INFO("cppcanvas.emf", "EMF+\tuse blend, points: " << blendPoints);
- if (blendPoints<0 || sal_uInt32(blendPoints)>SAL_MAX_INT32 / (2 * sizeof(float)))
- blendPoints = SAL_MAX_INT32 / (2 * sizeof(float));
- blendPositions = new float[2 * blendPoints];
- blendFactors = blendPositions + blendPoints;
- for (int i = 0; i < blendPoints; i++) {
- s.ReadFloat(blendPositions[i]);
- SAL_INFO("cppcanvas.emf", "EMF+\tposition[" << i << "]: " << blendPositions[i]);
+ if (additionalFlags & 0x02)
+ {
+ SAL_INFO("cppcanvas.emf", "EMF+\tuse transformation");
+ rR.readXForm(s, brush_transformation);
+ hasTransformation = true;
+ SAL_INFO("cppcanvas.emf",
+ "EMF+\tm11: " << brush_transformation.get(0,0) << " m12: " << brush_transformation.get(1,0) <<
+ "\nEMF+\tm21: " << brush_transformation.get(0,1) << " m22: " << brush_transformation.get(1,1) <<
+ "\nEMF+\tdx: " << brush_transformation.get(0,2) << " dy: " << brush_transformation.get(1,2));
}
- for (int i = 0; i < blendPoints; i++) {
- s.ReadFloat(blendFactors[i]);
- SAL_INFO("cppcanvas.emf", "EMF+\tfactor[" << i << "]: " << blendFactors[i]);
- }
- }
- if (additionalFlags & 0x04) {
- s.ReadInt32(colorblendPoints);
- SAL_INFO("cppcanvas.emf", "EMF+\tuse color blend, points: " << colorblendPoints);
- if (colorblendPoints<0 || sal_uInt32(colorblendPoints)>SAL_MAX_INT32 / sizeof(float))
- colorblendPoints = SAL_MAX_INT32 / sizeof(float);
- if (sal_uInt32(colorblendPoints)>SAL_MAX_INT32 / sizeof(::Color))
- colorblendPoints = SAL_MAX_INT32 / sizeof(::Color);
- colorblendPositions = new float[colorblendPoints];
- colorblendColors = new ::Color[colorblendPoints];
- for (int i = 0; i < colorblendPoints; i++) {
- s.ReadFloat(colorblendPositions[i]);
- SAL_INFO("cppcanvas.emf", "EMF+\tposition[" << i << "]: " << colorblendPositions[i]);
- }
- for (int i = 0; i < colorblendPoints; i++) {
- s.ReadUInt32(color);
- colorblendColors[i] = ::Color(0xff - (color >> 24), (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff);
- SAL_INFO("cppcanvas.emf", "EMF+\tcolor[" << i << "]: 0x" << std::hex << color << std::dec);
+ if (additionalFlags & 0x08)
+ {
+ s.ReadInt32(blendPoints);
+ SAL_INFO("cppcanvas.emf", "EMF+\tuse blend, points: " << blendPoints);
+ if (blendPoints<0 || sal_uInt32(blendPoints)>SAL_MAX_INT32 / (2 * sizeof(float)))
+ blendPoints = SAL_MAX_INT32 / (2 * sizeof(float));
+ blendPositions = new float[2 * blendPoints];
+ blendFactors = blendPositions + blendPoints;
+
+ for (int i = 0; i < blendPoints; i++)
+ {
+ s.ReadFloat(blendPositions[i]);
+ SAL_INFO("cppcanvas.emf", "EMF+\tposition[" << i << "]: " << blendPositions[i]);
+ }
+
+ for (int i = 0; i < blendPoints; i++)
+ {
+ s.ReadFloat(blendFactors[i]);
+ SAL_INFO("cppcanvas.emf", "EMF+\tfactor[" << i << "]: " << blendFactors[i]);
+ }
}
- }
-
- break;
- }
- case BrushTypeLinearGradient:
- {
- s.ReadUInt32(additionalFlags).ReadInt32(wrapMode);
- SAL_INFO("cppcanvas.emf", "EMF+\tlinear gradient, additional flags: 0x" << std::hex << additionalFlags << std::dec);
-
- s.ReadFloat(areaX).ReadFloat(areaY).ReadFloat(areaWidth).ReadFloat(areaHeight);
-
- SAL_INFO("cppcanvas.emf", "EMF+\tarea: " << areaX << "," << areaY << " - " << areaWidth << "x" << areaHeight);
-
- sal_uInt32 color;
-
- s.ReadUInt32(color);
- solidColor = ::Color(0xff - (color >> 24), (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff);
- SAL_INFO("cppcanvas.emf", "EMF+\tfirst color: 0x" << std::hex << color << std::dec);
-
- s.ReadUInt32(color);
- secondColor = ::Color(0xff - (color >> 24), (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff);
- SAL_INFO("cppcanvas.emf", "EMF+\tsecond color: 0x" << std::hex << color << std::dec);
-
- // repeated colors, unknown meaning, see http://www.aces.uiuc.edu/~jhtodd/Metafile/MetafileRecords/ObjectBrush.html
- s.ReadUInt32(color);
- s.ReadUInt32(color);
-
- if (additionalFlags & 0x02) {
- SAL_INFO("cppcanvas.emf", "EMF+\tuse transformation");
- rR.readXForm(s, brush_transformation);
- hasTransformation = true;
- SAL_INFO("cppcanvas.emf",
- "EMF+\tm11: " << brush_transformation.get(0,0) << " m12: " << brush_transformation.get(1,0) <<
- "\nEMF+\tm21: " << brush_transformation.get(0,1) << " m22: " << brush_transformation.get(1,1) <<
- "\nEMF+\tdx: " << brush_transformation.get(0,2) << " dy: " << brush_transformation.get(1,2));
- }
- if (additionalFlags & 0x08) {
- s.ReadInt32(blendPoints);
- SAL_INFO("cppcanvas.emf", "EMF+\tuse blend, points: " << blendPoints);
- if (blendPoints<0 || sal_uInt32(blendPoints)>SAL_MAX_INT32 / (2 * sizeof(float)))
- blendPoints = SAL_MAX_INT32 / (2 * sizeof(float));
- blendPositions = new float[2 * blendPoints];
- blendFactors = blendPositions + blendPoints;
- for (int i = 0; i < blendPoints; i++) {
- s.ReadFloat(blendPositions[i]);
- SAL_INFO("cppcanvas.emf", "EMF+\tposition[" << i << "]: " << blendPositions[i]);
- }
- for (int i = 0; i < blendPoints; i++) {
- s.ReadFloat(blendFactors[i]);
- SAL_INFO("cppcanvas.emf", "EMF+\tfactor[" << i << "]: " << blendFactors[i]);
+ if (additionalFlags & 0x04)
+ {
+ s.ReadInt32(colorblendPoints);
+ SAL_INFO("cppcanvas.emf", "EMF+\tuse color blend, points: " << colorblendPoints);
+
+ if (colorblendPoints<0 || sal_uInt32(colorblendPoints)>SAL_MAX_INT32 / sizeof(float))
+ {
+ colorblendPoints = SAL_MAX_INT32 / sizeof(float);
+ }
+
+ if (sal_uInt32(colorblendPoints) > SAL_MAX_INT32 / sizeof(::Color))
+ {
+ colorblendPoints = sal_uInt32(SAL_MAX_INT32) / sizeof(::Color);
+ }
+
+ colorblendPositions = new float[colorblendPoints];
+ colorblendColors = new ::Color[colorblendPoints];
+
+ for (int i = 0; i < colorblendPoints; i++)
+ {
+ s.ReadFloat(colorblendPositions[i]);
+ SAL_INFO("cppcanvas.emf", "EMF+\tposition[" << i << "]: " << colorblendPositions[i]);
+ }
+
+ for (int i = 0; i < colorblendPoints; i++)
+ {
+ s.ReadUInt32(color);
+ colorblendColors[i] = ::Color(0xff - (color >> 24), (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff);
+ SAL_INFO("cppcanvas.emf", "EMF+\tcolor[" << i << "]: 0x" << std::hex << color << std::dec);
+ }
}
- }
- if (additionalFlags & 0x04) {
- s.ReadInt32(colorblendPoints);
- SAL_INFO("cppcanvas.emf", "EMF+\tuse color blend, points: " << colorblendPoints);
- if (colorblendPoints<0 || sal_uInt32(colorblendPoints)>SAL_MAX_INT32 / sizeof(float))
- colorblendPoints = SAL_MAX_INT32 / sizeof(float);
- if (sal_uInt32(colorblendPoints)>SAL_MAX_INT32 / sizeof(::Color))
- colorblendPoints = sal_uInt32(SAL_MAX_INT32) / sizeof(::Color);
- colorblendPositions = new float[colorblendPoints];
- colorblendColors = new ::Color[colorblendPoints];
- for (int i = 0; i < colorblendPoints; i++) {
- s.ReadFloat(colorblendPositions[i]);
- SAL_INFO("cppcanvas.emf", "EMF+\tposition[" << i << "]: " << colorblendPositions[i]);
- }
- for (int i = 0; i < colorblendPoints; i++) {
- s.ReadUInt32(color);
- colorblendColors[i] = ::Color(0xff - (color >> 24), (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff);
- SAL_INFO("cppcanvas.emf", "EMF+\tcolor[" << i << "]: 0x" << std::hex << color << std::dec);
- }
+ break;
+ }
+ default:
+ {
+ SAL_INFO("cppcanvas.emf", "EMF+\tunhandled brush type: " << std::hex << type << std::dec);
}
-
- break;
- }
- default:
- SAL_INFO("cppcanvas.emf", "EMF+\tunhandled brush type: " << std::hex << type << std::dec);
}
}
}
diff --git a/drawinglayer/source/tools/emfpcustomlinecap.cxx b/drawinglayer/source/tools/emfpcustomlinecap.cxx
index 9024a11a564e..d2d211d62d3e 100644
--- a/drawinglayer/source/tools/emfpcustomlinecap.cxx
+++ b/drawinglayer/source/tools/emfpcustomlinecap.cxx
@@ -46,7 +46,6 @@ namespace emfplushelper
{
const sal_uInt32 EmfPlusCustomLineCapDataTypeDefault = 0x00000000;
const sal_uInt32 EmfPlusCustomLineCapDataTypeAdjustableArrow = 0x00000001;
-
const sal_uInt32 EmfPlusCustomLineCapDataFillPath = 0x00000001;
const sal_uInt32 EmfPlusCustomLineCapDataLinePath = 0x00000002;
@@ -75,17 +74,14 @@ namespace emfplushelper
sal_Int32 pathLength;
s.ReadInt32(pathLength);
SAL_INFO("cppcanvas.emf", "EMF+\t\tpath length: " << pathLength);
-
sal_uInt32 pathHeader;
sal_Int32 pathPoints, pathFlags;
s.ReadUInt32(pathHeader).ReadInt32(pathPoints).ReadInt32(pathFlags);
-
SAL_INFO("cppcanvas.emf", "EMF+\t\tpath (custom cap line path)");
SAL_INFO("cppcanvas.emf", "EMF+\t\theader: 0x" << std::hex << pathHeader << " points: " << std::dec << pathPoints << " additional flags: 0x" << std::hex << pathFlags << std::dec);
EMFPPath path(pathPoints);
path.Read(s, pathFlags, rR);
-
polygon = path.GetPolygon(rR, false);
mbIsFilled = bFill;
@@ -93,16 +89,13 @@ namespace emfplushelper
// expects
B2DHomMatrix aMatrix;
aMatrix.scale(1.0, -1.0);
-
polygon.transform(aMatrix);
};
void EMFPCustomLineCap::Read(SvStream& s, EmfPlusHelperData& rR)
{
sal_uInt32 header;
-
s.ReadUInt32(header).ReadUInt32(type);
-
SAL_INFO("cppcanvas.emf", "EMF+\t\tcustom cap");
SAL_INFO("cppcanvas.emf", "EMF+\t\theader: 0x" << std::hex << header << " type: " << type << std::dec);
diff --git a/drawinglayer/source/tools/emfpfont.cxx b/drawinglayer/source/tools/emfpfont.cxx
index b191a8f4c7e5..754e59e94319 100644
--- a/drawinglayer/source/tools/emfpfont.cxx
+++ b/drawinglayer/source/tools/emfpfont.cxx
@@ -44,11 +44,8 @@ namespace emfplushelper
sal_uInt32 header;
sal_uInt32 reserved;
sal_uInt32 length;
-
s.ReadUInt32(header).ReadFloat(emSize).ReadUInt32(sizeUnit).ReadInt32(fontFlags).ReadUInt32(reserved).ReadUInt32(length);
-
SAL_WARN_IF((header >> 12) != 0xdbc01, "cppcanvas.emf", "Invalid header - not 0xdbc01");
-
SAL_INFO("cppcanvas.emf", "EMF+\tfont\nEMF+\theader: 0x" << std::hex << (header >> 12) << " version: 0x" << (header & 0x1fff) << " size: " << std::dec << emSize << " unit: 0x" << std::hex << sizeUnit << std::dec);
SAL_INFO("cppcanvas.emf", "EMF+\tflags: 0x" << std::hex << fontFlags << " reserved: 0x" << reserved << " length: 0x" << std::hex << length << std::dec);
@@ -58,7 +55,9 @@ namespace emfplushelper
sal_Unicode *chars = pStr->buffer;
for (sal_uInt32 i = 0; i < length; ++i)
+ {
s.ReadUtf16(chars[i]);
+ }
family = OUString(pStr, SAL_NO_ACQUIRE);
SAL_INFO("cppcanvas.emf", "EMF+\tfamily: " << family);
diff --git a/drawinglayer/source/tools/emfphelperdata.cxx b/drawinglayer/source/tools/emfphelperdata.cxx
index fcab2bbd7a44..80d9a7f3fafa 100644
--- a/drawinglayer/source/tools/emfphelperdata.cxx
+++ b/drawinglayer/source/tools/emfphelperdata.cxx
@@ -26,6 +26,8 @@
#include <emfpfont.hxx>
#include <emfpstringformat.hxx>
#include <basegfx/curve/b2dcubicbezier.hxx>
+#include <wmfemfhelper.hxx>
+#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
namespace emfplushelper
{
@@ -33,45 +35,45 @@ namespace emfplushelper
{
switch (type)
{
- case EmfPlusRecordTypeHeader: return "EmfPlusRecordTypeHeader";
- case EmfPlusRecordTypeEndOfFile: return "EmfPlusRecordTypeEndOfFile";
- case EmfPlusRecordTypeGetDC: return "EmfPlusRecordTypeGetDC";
- case EmfPlusRecordTypeObject: return "EmfPlusRecordTypeObject";
- case EmfPlusRecordTypeFillRects: return "EmfPlusRecordTypeFillRects";
- case EmfPlusRecordTypeDrawRects: return "EmfPlusRecordTypeDrawRects";
- case EmfPlusRecordTypeFillPolygon: return "EmfPlusRecordTypeFillPolygon";
- case EmfPlusRecordTypeDrawLines: return "EmfPlusRecordTypeDrawLines";
- case EmfPlusRecordTypeFillEllipse: return "EmfPlusRecordTypeFillEllipse";
- case EmfPlusRecordTypeDrawEllipse: return "EmfPlusRecordTypeDrawEllipse";
- case EmfPlusRecordTypeFillPie: return "EmfPlusRecordTypeFillPie";
- case EmfPlusRecordTypeDrawPie: return "EmfPlusRecordTypeDrawPie";
- case EmfPlusRecordTypeDrawArc: return "EmfPlusRecordTypeDrawArc";
- case EmfPlusRecordTypeFillPath: return "EmfPlusRecordTypeFillPath";
- case EmfPlusRecordTypeDrawPath: return "EmfPlusRecordTypeDrawPath";
- case EmfPlusRecordTypeDrawBeziers: return "EmfPlusRecordTypeDrawBeziers";
- case EmfPlusRecordTypeDrawImage: return "EmfPlusRecordTypeDrawImage";
- case EmfPlusRecordTypeDrawImagePoints: return "EmfPlusRecordTypeDrawImagePoints";
- case EmfPlusRecordTypeDrawString: return "EmfPlusRecordTypeDrawString";
- case EmfPlusRecordTypeSetRenderingOrigin: return "EmfPlusRecordTypeSetRenderingOrigin";
- case EmfPlusRecordTypeSetAntiAliasMode: return "EmfPlusRecordTypeSetAntiAliasMode";
- case EmfPlusRecordTypeSetTextRenderingHint: return "EmfPlusRecordTypeSetTextRenderingHint";
- case EmfPlusRecordTypeSetInterpolationMode: return "EmfPlusRecordTypeSetInterpolationMode";
- case EmfPlusRecordTypeSetPixelOffsetMode: return "EmfPlusRecordTypeSetPixelOffsetMode";
- case EmfPlusRecordTypeSetCompositingQuality: return "EmfPlusRecordTypeSetCompositingQuality";
- case EmfPlusRecordTypeSave: return "EmfPlusRecordTypeSave";
- case EmfPlusRecordTypeRestore: return "EmfPlusRecordTypeRestore";
- case EmfPlusRecordTypeBeginContainerNoParams: return "EmfPlusRecordTypeBeginContainerNoParams";
- case EmfPlusRecordTypeEndContainer: return "EmfPlusRecordTypeEndContainer";
- case EmfPlusRecordTypeSetWorldTransform: return "EmfPlusRecordTypeSetWorldTransform";
- case EmfPlusRecordTypeResetWorldTransform: return "EmfPlusRecordTypeResetWorldTransform";
- case EmfPlusRecordTypeMultiplyWorldTransform: return "EmfPlusRecordTypeMultiplyWorldTransform";
- case EmfPlusRecordTypeTranslateWorldTransform: return "EmfPlusRecordTypeTranslateWorldTransform";
- case EmfPlusRecordTypeScaleWorldTransform: return "EmfPlusRecordTypeScaleWorldTransform";
- case EmfPlusRecordTypeSetPageTransform: return "EmfPlusRecordTypeSetPageTransform";
- case EmfPlusRecordTypeSetClipRect: return "EmfPlusRecordTypeSetClipRect";
- case EmfPlusRecordTypeSetClipPath: return "EmfPlusRecordTypeSetClipPath";
- case EmfPlusRecordTypeSetClipRegion: return "EmfPlusRecordTypeSetClipRegion";
- case EmfPlusRecordTypeDrawDriverString: return "EmfPlusRecordTypeDrawDriverString";
+ case EmfPlusRecordTypeHeader: return "EmfPlusRecordTypeHeader";
+ case EmfPlusRecordTypeEndOfFile: return "EmfPlusRecordTypeEndOfFile";
+ case EmfPlusRecordTypeGetDC: return "EmfPlusRecordTypeGetDC";
+ case EmfPlusRecordTypeObject: return "EmfPlusRecordTypeObject";
+ case EmfPlusRecordTypeFillRects: return "EmfPlusRecordTypeFillRects";
+ case EmfPlusRecordTypeDrawRects: return "EmfPlusRecordTypeDrawRects";
+ case EmfPlusRecordTypeFillPolygon: return "EmfPlusRecordTypeFillPolygon";
+ case EmfPlusRecordTypeDrawLines: return "EmfPlusRecordTypeDrawLines";
+ case EmfPlusRecordTypeFillEllipse: return "EmfPlusRecordTypeFillEllipse";
+ case EmfPlusRecordTypeDrawEllipse: return "EmfPlusRecordTypeDrawEllipse";
+ case EmfPlusRecordTypeFillPie: return "EmfPlusRecordTypeFillPie";
+ case EmfPlusRecordTypeDrawPie: return "EmfPlusRecordTypeDrawPie";
+ case EmfPlusRecordTypeDrawArc: return "EmfPlusRecordTypeDrawArc";
+ case EmfPlusRecordTypeFillPath: return "EmfPlusRecordTypeFillPath";
+ case EmfPlusRecordTypeDrawPath: return "EmfPlusRecordTypeDrawPath";
+ case EmfPlusRecordTypeDrawBeziers: return "EmfPlusRecordTypeDrawBeziers";
+ case EmfPlusRecordTypeDrawImage: return "EmfPlusRecordTypeDrawImage";
+ case EmfPlusRecordTypeDrawImagePoints: return "EmfPlusRecordTypeDrawImagePoints";
+ case EmfPlusRecordTypeDrawString: return "EmfPlusRecordTypeDrawString";
+ case EmfPlusRecordTypeSetRenderingOrigin: return "EmfPlusRecordTypeSetRenderingOrigin";
+ case EmfPlusRecordTypeSetAntiAliasMode: return "EmfPlusRecordTypeSetAntiAliasMode";
+ case EmfPlusRecordTypeSetTextRenderingHint: return "EmfPlusRecordTypeSetTextRenderingHint";
+ case EmfPlusRecordTypeSetInterpolationMode: return "EmfPlusRecordTypeSetInterpolationMode";
+ case EmfPlusRecordTypeSetPixelOffsetMode: return "EmfPlusRecordTypeSetPixelOffsetMode";
+ case EmfPlusRecordTypeSetCompositingQuality: return "EmfPlusRecordTypeSetCompositingQuality";
+ case EmfPlusRecordTypeSave: return "EmfPlusRecordTypeSave";
+ case EmfPlusRecordTypeRestore: return "EmfPlusRecordTypeRestore";
+ case EmfPlusRecordTypeBeginContainerNoParams: return "EmfPlusRecordTypeBeginContainerNoParams";
+ case EmfPlusRecordTypeEndContainer: return "EmfPlusRecordTypeEndContainer";
+ case EmfPlusRecordTypeSetWorldTransform: return "EmfPlusRecordTypeSetWorldTransform";
+ case EmfPlusRecordTypeResetWorldTransform: return "EmfPlusRecordTypeResetWorldTransform";
+ case EmfPlusRecordTypeMultiplyWorldTransform: return "EmfPlusRecordTypeMultiplyWorldTransform";
+ case EmfPlusRecordTypeTranslateWorldTransform: return "EmfPlusRecordTypeTranslateWorldTransform";
+ case EmfPlusRecordTypeScaleWorldTransform: return "EmfPlusRecordTypeScaleWorldTransform";
+ case EmfPlusRecordTypeSetPageTransform: return "EmfPlusRecordTypeSetPageTransform";
+ case EmfPlusRecordTypeSetClipRect: return "EmfPlusRecordTypeSetClipRect";
+ case EmfPlusRecordTypeSetClipPath: return "EmfPlusRecordTypeSetClipPath";
+ case EmfPlusRecordTypeSetClipRegion: return "EmfPlusRecordTypeSetClipRegion";
+ case EmfPlusRecordTypeDrawDriverString: return "EmfPlusRecordTypeDrawDriverString";
}
return "";
}
@@ -126,82 +128,83 @@ namespace emfplushelper
switch (flags & 0x7f00)
{
- case EmfPlusObjectTypeBrush:
- {
- EMFPBrush *brush;
- aObjects[index].reset(brush = new EMFPBrush());
- brush->Read(rObjectStream, *this);
- break;
- }
- case EmfPlusObjectTypePen:
- {
- EMFPPen *pen;
- aObjects[index].reset(pen = new EMFPPen());
- pen->Read(rObjectStream, *this);
- break;
- }
- case EmfPlusObjectTypePath:
- {
- sal_uInt32 header, pathFlags;
- sal_Int32 points;
-
- rObjectStream.ReadUInt32(header).ReadInt32(points).ReadUInt32(pathFlags);
- SAL_INFO("cppcanvas.emf", "EMF+\tpath");
- SAL_INFO("cppcanvas.emf", "EMF+\theader: 0x" << std::hex << header << " points: " << std::dec << points << " additional flags: 0x" << std::hex << pathFlags << std::dec);
- EMFPPath *path;
- aObjects[index].reset(path = new EMFPPath(points));
- path->Read(rObjectStream, pathFlags, *this);
- break;
- }
- case EmfPlusObjectTypeRegion:
- {
- EMFPRegion *region;
- aObjects[index].reset(region = new EMFPRegion());
- region->Read(rObjectStream);
- break;
- }
- case EmfPlusObjectTypeImage:
- {
- EMFPImage *image;
- aObjects[index].reset(image = new EMFPImage);
- image->type = 0;
- image->width = 0;
- image->height = 0;
- image->stride = 0;
- image->pixelFormat = 0;
- image->Read(rObjectStream, dataSize, bUseWholeStream);
- break;
- }
- case EmfPlusObjectTypeFont:
- {
- EMFPFont *font;
- aObjects[index].reset(font = new EMFPFont);
- font->emSize = 0;
- font->sizeUnit = 0;
- font->fontFlags = 0;
- font->Read(rObjectStream);
- break;
- }
- case EmfPlusObjectTypeStringFormat:
- {
- EMFPStringFormat *stringFormat;
- aObjects[index].reset(stringFormat = new EMFPStringFormat());
- stringFormat->Read(rObjectStream);
- break;
- }
- case EmfPlusObjectTypeImageAttributes:
- {
- SAL_INFO("cppcanvas.emf", "EMF+\t Object type 'image attributes' not yet implemented");
- break;
- }
- case EmfPlusObjectTypeCustomLineCap:
- {
- SAL_INFO("cppcanvas.emf", "EMF+\t Object type 'custom line cap' not yet implemented");
- break;
- }
- default:
- SAL_INFO("cppcanvas.emf", "EMF+\tObject unhandled flags: 0x" << std::hex << (flags & 0xff00) << std::dec);
- break;
+ case EmfPlusObjectTypeBrush:
+ {
+ EMFPBrush *brush;
+ aObjects[index].reset(brush = new EMFPBrush());
+ brush->Read(rObjectStream, *this);
+ break;
+ }
+ case EmfPlusObjectTypePen:
+ {
+ EMFPPen *pen;
+ aObjects[index].reset(pen = new EMFPPen());
+ pen->Read(rObjectStream, *this);
+ break;
+ }
+ case EmfPlusObjectTypePath:
+ {
+ sal_uInt32 header, pathFlags;
+ sal_Int32 points;
+
+ rObjectStream.ReadUInt32(header).ReadInt32(points).ReadUInt32(pathFlags);
+ SAL_INFO("cppcanvas.emf", "EMF+\tpath");
+ SAL_INFO("cppcanvas.emf", "EMF+\theader: 0x" << std::hex << header << " points: " << std::dec << points << " additional flags: 0x" << std::hex << pathFlags << std::dec);
+ EMFPPath *path;
+ aObjects[index].reset(path = new EMFPPath(points));
+ path->Read(rObjectStream, pathFlags, *this);
+ break;
+ }
+ case EmfPlusObjectTypeRegion:
+ {
+ EMFPRegion *region;
+ aObjects[index].reset(region = new EMFPRegion());
+ region->Read(rObjectStream);
+ break;
+ }
+ case EmfPlusObjectTypeImage:
+ {
+ EMFPImage *image;
+ aObjects[index].reset(image = new EMFPImage);
+ image->type = 0;
+ image->width = 0;
+ image->height = 0;
+ image->stride = 0;
+ image->pixelFormat = 0;
+ image->Read(rObjectStream, dataSize, bUseWholeStream);
+ break;
+ }
+ case EmfPlusObjectTypeFont:
+ {
+ EMFPFont *font;
+ aObjects[index].reset(font = new EMFPFont);
+ font->emSize = 0;
+ font->sizeUnit = 0;
+ font->fontFlags = 0;
+ font->Read(rObjectStream);
+ break;
+ }
+ case EmfPlusObjectTypeStringFormat:
+ {
+ EMFPStringFormat *stringFormat;
+ aObjects[index].reset(stringFormat = new EMFPStringFormat());
+ stringFormat->Read(rObjectStream);
+ break;
+ }
+ case EmfPlusObjectTypeImageAttributes:
+ {
+ SAL_INFO("cppcanvas.emf", "EMF+\t Object type 'image attributes' not yet implemented");
+ break;
+ }
+ case EmfPlusObjectTypeCustomLineCap:
+ {
+ SAL_INFO("cppcanvas.emf", "EMF+\t Object type 'custom line cap' not yet implemented");
+ break;
+ }
+ default:
+ {
+ SAL_INFO("cppcanvas.emf", "EMF+\tObject unhandled flags: 0x" << std::hex << (flags & 0xff00) << std::dec);
+ }
}
}
@@ -324,6 +327,34 @@ namespace emfplushelper
return ::basegfx::B2DSize(w, h);
}
+ void EmfPlusHelperData::EMFPPlusDrawPolygon(const ::basegfx::B2DPolyPolygon& polygon, sal_uInt32 penIndex)
+ {
+ const EMFPPen* pen = static_cast<EMFPPen*>(aObjects[penIndex & 0xff].get());
+ SAL_WARN_IF(!pen, "cppcanvas.emf", "emf+ missing pen");
+
+ if (pen && polygon.count())
+ {
+ mrTargetHolders.Current().append(
+ new drawinglayer::primitive2d::PolyPolygonHairlinePrimitive2D(
+ polygon,
+ pen->GetColor().getBColor()));
+ }
+ }
+
+ void EmfPlusHelperData::EMFPPlusFillPolygon(const ::basegfx::B2DPolyPolygon& polygon, bool isColor, sal_uInt32 brushIndexOrColor)
+ {
+ if (polygon.count())
+ {
+ if (isColor)
+ {
+ mrTargetHolders.Current().append(
+ new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(
+ polygon,
+ ::Color(0xff - (brushIndexOrColor >> 24), (brushIndexOrColor >> 16) & 0xff, (brushIndexOrColor >> 8) & 0xff, brushIndexOrColor & 0xff).getBColor()));
+ }
+ }
+ }
+
EmfPlusHelperData::EmfPlusHelperData(
SvMemoryStream& rMS,
wmfemfhelper::TargetHolders& rTargetHolders,
@@ -431,804 +462,834 @@ namespace emfplushelper
{
switch (type)
{
- case EmfPlusRecordTypeHeader:
- {
- sal_uInt32 header, version;
-
- rMS.ReadUInt32(header).ReadUInt32(version).ReadInt32(nHDPI).ReadInt32(nVDPI);
- SAL_INFO("cppcanvas.emf", "EMF+ Header");
- SAL_INFO("cppcanvas.emf", "EMF+\theader: 0x" << std::hex << header << " version: " << std::dec << version << " horizontal DPI: " << nHDPI << " vertical DPI: " << nVDPI << " dual: " << (flags & 1));
- break;
- }
- case EmfPlusRecordTypeEndOfFile:
- {
- SAL_INFO("cppcanvas.emf", "EMF+ EndOfFile");
- break;
- }
- case EmfPlusRecordTypeGetDC:
- {
- SAL_INFO("cppcanvas.emf", "EMF+ GetDC");
- SAL_INFO("cppcanvas.emf", "EMF+\talready used in svtools wmf/emf filter parser");
- break;
- }
- case EmfPlusRecordTypeObject:
- {
- processObjectRecord(rMS, flags, dataSize);
- break;
- }
- case EmfPlusRecordTypeFillPie:
- case EmfPlusRecordTypeDrawPie:
- case EmfPlusRecordTypeDrawArc:
- {
- float startAngle, sweepAngle;
-
- // Silent MSVC warning C4701: potentially uninitialized local variable 'brushIndexOrColor' used
- sal_uInt32 brushIndexOrColor = 999;
-
- if (type == EmfPlusRecordTypeFillPie)
+ case EmfPlusRecordTypeHeader:
{
- rMS.ReadUInt32(brushIndexOrColor);
- SAL_INFO("cppcanvas.emf", "EMF+ FillPie colorOrIndex: " << brushIndexOrColor);
+ sal_uInt32 header, version;
+
+ rMS.ReadUInt32(header).ReadUInt32(version).ReadInt32(nHDPI).ReadInt32(nVDPI);
+ SAL_INFO("cppcanvas.emf", "EMF+ Header");
+ SAL_INFO("cppcanvas.emf", "EMF+\theader: 0x" << std::hex << header << " version: " << std::dec << version << " horizontal DPI: " << nHDPI << " vertical DPI: " << nVDPI << " dual: " << (flags & 1));
+ break;
}
- else if (type == EmfPlusRecordTypeDrawPie)
+ case EmfPlusRecordTypeEndOfFile:
{
- SAL_INFO("cppcanvas.emf", "EMF+ DrawPie");
+ SAL_INFO("cppcanvas.emf", "EMF+ EndOfFile");
+ break;
}
- else
+ case EmfPlusRecordTypeGetDC:
{
- SAL_INFO("cppcanvas.emf", "EMF+ DrawArc");
+ SAL_INFO("cppcanvas.emf", "EMF+ GetDC");
+ SAL_INFO("cppcanvas.emf", "EMF+\talready used in svtools wmf/emf filter parser");
+ break;
}
-
- rMS.ReadFloat(startAngle).ReadFloat(sweepAngle);
- float dx, dy, dw, dh;
- ReadRectangle(rMS, dx, dy, dw, dh, bool(flags & 0x4000));
- SAL_INFO("cppcanvas.emf", "EMF+\t RectData: " << dx << "," << dy << " " << dw << "x" << dh);
- startAngle = 2 * M_PI*startAngle / 360;
- sweepAngle = 2 * M_PI*sweepAngle / 360;
- ::basegfx::B2DPoint mappedCenter(Map(dx + dw / 2, dy + dh / 2));
- ::basegfx::B2DSize mappedSize(MapSize(dw / 2, dh / 2));
- float endAngle = startAngle + sweepAngle;
- startAngle = fmodf(startAngle, static_cast<float>(M_PI * 2));
-
- if (startAngle < 0.0)
+ case EmfPlusRecordTypeObject:
{
- startAngle += static_cast<float>(M_PI * 2.0);
+ processObjectRecord(rMS, flags, dataSize);
+ break;
}
-
- endAngle = fmodf(endAngle, static_cast<float>(M_PI * 2.0));
-
- if (endAngle < 0.0)
+ case EmfPlusRecordTypeFillPie:
+ case EmfPlusRecordTypeDrawPie:
+ case EmfPlusRecordTypeDrawArc:
{
- endAngle += static_cast<float>(M_PI * 2.0);
- }
+ float startAngle, sweepAngle;
- if (sweepAngle < 0)
- {
- std::swap(endAngle, startAngle);
- }
+ // Silent MSVC warning C4701: potentially uninitialized local variable 'brushIndexOrColor' used
+ sal_uInt32 brushIndexOrColor = 999;
- SAL_INFO("cppcanvas.emf", "EMF+\t adjusted angles: start " <<
- (360.0*startAngle / M_PI) << ", end: " << (360.0*endAngle / M_PI) <<
- " startAngle: " << startAngle << " sweepAngle: " << sweepAngle);
+ if (type == EmfPlusRecordTypeFillPie)
+ {
+ rMS.ReadUInt32(brushIndexOrColor);
+ SAL_INFO("cppcanvas.emf", "EMF+ FillPie colorOrIndex: " << brushIndexOrColor);
+ }
+ else if (type == EmfPlusRecordTypeDrawPie)
+ {
+ SAL_INFO("cppcanvas.emf", "EMF+ DrawPie");
+ }
+ else
+ {
+ SAL_INFO("cppcanvas.emf", "EMF+ DrawArc");
+ }
- ::basegfx::B2DPolygon polygon = basegfx::tools::createPolygonFromEllipseSegment(
- mappedCenter, mappedSize.getX(), mappedSize.getY(), startAngle, endAngle);
+ rMS.ReadFloat(startAngle).ReadFloat(sweepAngle);
+ float dx, dy, dw, dh;
+ ReadRectangle(rMS, dx, dy, dw, dh, bool(flags & 0x4000));
+ SAL_INFO("cppcanvas.emf", "EMF+\t RectData: " << dx << "," << dy << " " << dw << "x" << dh);
+ startAngle = 2 * M_PI*startAngle / 360;
+ sweepAngle = 2 * M_PI*sweepAngle / 360;
+ ::basegfx::B2DPoint mappedCenter(Map(dx + dw / 2, dy + dh / 2));
+ ::basegfx::B2DSize mappedSize(MapSize(dw / 2, dh / 2));
+ float endAngle = startAngle + sweepAngle;
+ startAngle = fmodf(startAngle, static_cast<float>(M_PI * 2));
+
+ if (startAngle < 0.0)
+ {
+ startAngle += static_cast<float>(M_PI * 2.0);
+ }
- if (type != EmfPlusRecordTypeDrawArc)
- {
- polygon.append(mappedCenter);
- polygon.setClosed(true);
- }
+ endAngle = fmodf(endAngle, static_cast<float>(M_PI * 2.0));
- ::basegfx::B2DPolyPolygon polyPolygon(polygon);
-// if (type == EmfPlusRecordTypeFillPie)
-// EMFPPlusFillPolygon(polyPolygon,
-// rFactoryParms, rState, rCanvas, flags & 0x8000, brushIndexOrColor);
-// else
-// EMFPPlusDrawPolygon(polyPolygon,
-// rFactoryParms, rState, rCanvas, flags & 0xff);
- }
- break;
- case EmfPlusRecordTypeFillPath:
- {
- sal_uInt32 index = flags & 0xff;
- sal_uInt32 brushIndexOrColor;
- rMS.ReadUInt32(brushIndexOrColor);
- SAL_INFO("cppcanvas.emf", "EMF+ FillPath slot: " << index);
+ if (endAngle < 0.0)
+ {
+ endAngle += static_cast<float>(M_PI * 2.0);
+ }
-// EMFPPlusFillPolygon(static_cast<EMFPPath*>(aObjects[index])->GetPolygon(*this), rFactoryParms, rState, rCanvas, flags & 0x8000, brushIndexOrColor);
- }
- break;
- case EmfPlusRecordTypeDrawEllipse:
- case EmfPlusRecordTypeFillEllipse:
- {
- // Intentionally very bogus initial value to avoid MSVC complaining about potentially uninitialized local
- // variable. As long as the code stays as intended, this variable will be assigned a (real) value in the case
- // when it is later used.
- sal_uInt32 brushIndexOrColor = 1234567;
+ if (sweepAngle < 0)
+ {
+ std::swap(endAngle, startAngle);
+ }
- if (type == EmfPlusRecordTypeFillEllipse)
- {
- rMS.ReadUInt32(brushIndexOrColor);
- }
+ SAL_INFO("cppcanvas.emf", "EMF+\t adjusted angles: start " <<
+ (360.0*startAngle / M_PI) << ", end: " << (360.0*endAngle / M_PI) <<
+ " startAngle: " << startAngle << " sweepAngle: " << sweepAngle);
- SAL_INFO("cppcanvas.emf", "EMF+ " << (type == EmfPlusRecordTypeFillEllipse ? "Fill" : "Draw") << "Ellipse slot: " << (flags & 0xff));
- float dx, dy, dw, dh;
- ReadRectangle(rMS, dx, dy, dw, dh, bool(flags & 0x4000));
- SAL_INFO("cppcanvas.emf", "EMF+ RectData: " << dx << "," << dy << " " << dw << "x" << dh);
- ::basegfx::B2DPoint mappedCenter(Map(dx + dw / 2, dy + dh / 2));
- ::basegfx::B2DSize mappedSize(MapSize(dw / 2, dh / 2));
- ::basegfx::B2DPolyPolygon polyPolygon(
- ::basegfx::B2DPolygon(
- ::basegfx::tools::createPolygonFromEllipse(mappedCenter, mappedSize.getX(), mappedSize.getY())));
-
-// if (type == EmfPlusRecordTypeFillEllipse)
-// EMFPPlusFillPolygon(polyPolygon,
-// rFactoryParms, rState, rCanvas, flags & 0x8000, brushIndexOrColor);
-// else
-// EMFPPlusDrawPolygon(polyPolygon,
-// rFactoryParms, rState, rCanvas, flags & 0xff);
- }
- break;
- case EmfPlusRecordTypeFillRects:
- case EmfPlusRecordTypeDrawRects:
- {
- // Silent MSVC warning C4701: potentially uninitialized local variable 'brushIndexOrColor' used
- sal_uInt32 brushIndexOrColor = 999;
- sal_Int32 rectangles;
- bool isColor = (flags & 0x8000);
- ::basegfx::B2DPolygon polygon;
+ ::basegfx::B2DPolygon polygon = basegfx::tools::createPolygonFromEllipseSegment(
+ mappedCenter, mappedSize.getX(), mappedSize.getY(), startAngle, endAngle);
+
+ if (type != EmfPlusRecordTypeDrawArc)
+ {
+ polygon.append(mappedCenter);
+ polygon.setClosed(true);
+ }
- if (EmfPlusRecordTypeFillRects == type)
+ ::basegfx::B2DPolyPolygon polyPolygon(polygon);
+ if (type == EmfPlusRecordTypeFillPie)
+ {
+ EMFPPlusFillPolygon(polyPolygon, flags & 0x8000, brushIndexOrColor);
+ // EMFPPlusFillPolygon(polyPolygon,
+ // rFactoryParms, rState, rCanvas, flags & 0x8000, brushIndexOrColor);
+ }
+ else
+ {
+ EMFPPlusDrawPolygon(polyPolygon, flags & 0xff);
+ // EMFPPlusDrawPolygon(polyPolygon,
+ // rFactoryParms, rState, rCanvas, flags & 0xff);
+ }
+ }
+ break;
+ case EmfPlusRecordTypeFillPath:
{
- SAL_INFO("cppcanvas.emf", "EMF+ FillRects");
+ sal_uInt32 index = flags & 0xff;
+ sal_uInt32 brushIndexOrColor;
rMS.ReadUInt32(brushIndexOrColor);
- SAL_INFO("cppcanvas.emf", "EMF+\t" << (isColor ? "color" : "brush index") << ": 0x" << std::hex << brushIndexOrColor << std::dec);
+ SAL_INFO("cppcanvas.emf", "EMF+ FillPath slot: " << index);
+
+ EMFPPlusFillPolygon(static_cast<EMFPPath*>(aObjects[index].get())->GetPolygon(*this), flags & 0x8000, brushIndexOrColor);
+ // EMFPPlusFillPolygon(static_cast<EMFPPath*>(aObjects[index])->GetPolygon(*this), rFactoryParms, rState, rCanvas, flags & 0x8000, brushIndexOrColor);
}
- else
+ break;
+ case EmfPlusRecordTypeDrawEllipse:
+ case EmfPlusRecordTypeFillEllipse:
{
- SAL_INFO("cppcanvas.emf", "EMF+ DrawRects");
- }
+ // Intentionally very bogus initial value to avoid MSVC complaining about potentially uninitialized local
+ // variable. As long as the code stays as intended, this variable will be assigned a (real) value in the case
+ // when it is later used.
+ sal_uInt32 brushIndexOrColor = 1234567;
- rMS.ReadInt32(rectangles);
+ if (type == EmfPlusRecordTypeFillEllipse)
+ {
+ rMS.ReadUInt32(brushIndexOrColor);
+ }
- for (int i = 0; i < rectangles; i++)
+ SAL_INFO("cppcanvas.emf", "EMF+ " << (type == EmfPlusRecordTypeFillEllipse ? "Fill" : "Draw") << "Ellipse slot: " << (flags & 0xff));
+ float dx, dy, dw, dh;
+ ReadRectangle(rMS, dx, dy, dw, dh, bool(flags & 0x4000));
+ SAL_INFO("cppcanvas.emf", "EMF+ RectData: " << dx << "," << dy << " " << dw << "x" << dh);
+ ::basegfx::B2DPoint mappedCenter(Map(dx + dw / 2, dy + dh / 2));
+ ::basegfx::B2DSize mappedSize(MapSize(dw / 2, dh / 2));
+ ::basegfx::B2DPolyPolygon polyPolygon(
+ ::basegfx::B2DPolygon(
+ ::basegfx::tools::createPolygonFromEllipse(mappedCenter, mappedSize.getX(), mappedSize.getY())));
+
+ if (type == EmfPlusRecordTypeFillEllipse)
+ {
+ EMFPPlusFillPolygon(polyPolygon, flags & 0x8000, brushIndexOrColor);
+ // EMFPPlusFillPolygon(polyPolygon,
+ // rFactoryParms, rState, rCanvas, flags & 0x8000, brushIndexOrColor);
+ }
+ else
+ {
+ EMFPPlusDrawPolygon(polyPolygon, flags & 0xff);
+ // EMFPPlusDrawPolygon(polyPolygon,
+ // rFactoryParms, rState, rCanvas, flags & 0xff);
+ }
+ }
+ break;
+ case EmfPlusRecordTypeFillRects:
+ case EmfPlusRecordTypeDrawRects:
{
- float x, y, width, height;
- ReadRectangle(rMS, x, y, width, height, bool(flags & 0x4000));
+ // Silent MSVC warning C4701: potentially uninitialized local variable 'brushIndexOrColor' used
+ sal_uInt32 brushIndexOrColor = 999;
+ sal_Int32 rectangles;
+ bool isColor = (flags & 0x8000);
+ ::basegfx::B2DPolygon polygon;
- polygon.append(Map(x, y));
- polygon.append(Map(x + width, y));
- polygon.append(Map(x + width, y + height));
- polygon.append(Map(x, y + height));
- polygon.append(Map(x, y));
-
- SAL_INFO("cppcanvas.emf", "EMF+\trectangle: " << x << ", " << width << "x" << height);
+ if (EmfPlusRecordTypeFillRects == type)
+ {
+ SAL_INFO("cppcanvas.emf", "EMF+ FillRects");
+ rMS.ReadUInt32(brushIndexOrColor);
+ SAL_INFO("cppcanvas.emf", "EMF+\t" << (isColor ? "color" : "brush index") << ": 0x" << std::hex << brushIndexOrColor << std::dec);
+ }
+ else
+ {
+ SAL_INFO("cppcanvas.emf", "EMF+ DrawRects");
+ }
- ::basegfx::B2DPolyPolygon polyPolygon(polygon);
-// if (type == EmfPlusRecordTypeFillRects)
-// EMFPPlusFillPolygon(polyPolygon,
-// rFactoryParms, rState, rCanvas, isColor, brushIndexOrColor);
-// else
-// EMFPPlusDrawPolygon(polyPolygon,
-// rFactoryParms, rState, rCanvas, flags & 0xff);
- }
- break;
- }
- case EmfPlusRecordTypeFillPolygon:
- {
- sal_uInt8 index = flags & 0xff;
- sal_uInt32 brushIndexOrColor;
- sal_Int32 points;
+ rMS.ReadInt32(rectangles);
- rMS.ReadUInt32(brushIndexOrColor);
- rMS.ReadInt32(points);
- SAL_INFO("cppcanvas.emf", "EMF+ FillPolygon in slot: " << +index << " points: " << points);
- SAL_INFO("cppcanvas.emf", "EMF+\t: " << ((flags & 0x8000) ? "color" : "brush index") << " 0x" << std::hex << brushIndexOrColor << std::dec);
+ for (int i = 0; i < rectangles; i++)
+ {
+ float x, y, width, height;
+ ReadRectangle(rMS, x, y, width, height, bool(flags & 0x4000));
- EMFPPath path(points, true);
- path.Read(rMS, flags, *this);
+ polygon.append(Map(x, y));
+ polygon.append(Map(x + width, y));
+ polygon.append(Map(x + width, y + height));
+ polygon.append(Map(x, y + height));
+ polygon.append(Map(x, y));
-// EMFPPlusFillPolygon(path.GetPolygon(*this), rFactoryParms, rState, rCanvas, flags & 0x8000, brushIndexOrColor);
+ SAL_INFO("cppcanvas.emf", "EMF+\trectangle: " << x << ", " << width << "x" << height);
- break;
- }
- case EmfPlusRecordTypeDrawLines:
- {
- sal_uInt32 points;
- rMS.ReadUInt32(points);
- SAL_INFO("cppcanvas.emf", "EMF+ DrawLines in slot: " << (flags & 0xff) << " points: " << points);
- EMFPPath path(points, true);
- path.Read(rMS, flags, *this);
+ ::basegfx::B2DPolyPolygon polyPolygon(polygon);
+ if (type == EmfPlusRecordTypeFillRects)
+ {
+ EMFPPlusFillPolygon(polyPolygon, isColor, brushIndexOrColor);
+ // EMFPPlusFillPolygon(polyPolygon,
+ // rFactoryParms, rState, rCanvas, isColor, brushIndexOrColor);
+ }
+ else
+ {
+ EMFPPlusDrawPolygon(polyPolygon, flags & 0xff);
+ // EMFPPlusDrawPolygon(polyPolygon,
+ // rFactoryParms, rState, rCanvas, flags & 0xff);
+ }
+ }
+ break;
+ }
+ case EmfPlusRecordTypeFillPolygon:
+ {
+ sal_uInt8 index = flags & 0xff;
+ sal_uInt32 brushIndexOrColor;
+ sal_Int32 points;
- // 0x2000 bit indicates whether to draw an extra line between the last point
- // and the first point, to close the shape.
-// EMFPPlusDrawPolygon(path.GetPolygon(*this, true, (flags & 0x2000)), rFactoryParms, rState, rCanvas, flags);
+ rMS.ReadUInt32(brushIndexOrColor);
+ rMS.ReadInt32(points);
+ SAL_INFO("cppcanvas.emf", "EMF+ FillPolygon in slot: " << +index << " points: " << points);
+ SAL_INFO("cppcanvas.emf", "EMF+\t: " << ((flags & 0x8000) ? "color" : "brush index") << " 0x" << std::hex << brushIndexOrColor << std::dec);
- break;
- }
- case EmfPlusRecordTypeDrawPath:
- {
- sal_uInt32 penIndex;
- rMS.ReadUInt32(penIndex);
- SAL_INFO("cppcanvas.emf", "EMF+ DrawPath");
- SAL_INFO("cppcanvas.emf", "EMF+\tpen: " << penIndex);
- EMFPPath* path = static_cast<EMFPPath*>(aObjects[flags & 0xff].get());
- SAL_WARN_IF(!path, "cppcanvas.emf", "EmfPlusRecordTypeDrawPath missing path");
+ EMFPPath path(points, true);
+ path.Read(rMS, flags, *this);
-// EMFPPlusDrawPolygon(path->GetPolygon(*this), rFactoryParms, rState, rCanvas, penIndex);
+ EMFPPlusFillPolygon(path.GetPolygon(*this), flags & 0x8000, brushIndexOrColor);
+ // EMFPPlusFillPolygon(path.GetPolygon(*this), rFactoryParms, rState, rCanvas, flags & 0x8000, brushIndexOrColor);
- break;
- }
- case EmfPlusRecordTypeDrawBeziers:
- {
- sal_uInt32 aCount;
- float x1, y1, x2, y2, x3, y3, x4, y4;
- ::basegfx::B2DPoint aStartPoint, aControlPointA, aControlPointB, aEndPoint;
- ::basegfx::B2DPolygon aPolygon;
- rMS.ReadUInt32(aCount);
- SAL_INFO("cppcanvas.emf", "EMF+ DrawBeziers slot: " << (flags & 0xff) << "Number of points: " << aCount);
- SAL_WARN_IF((aCount - 1) % 3 != 0, "cppcanvas.emf", "EMF+\t Bezier Draw not support number of points other than 4, 7, 10, 13, 16...");
-
- if (aCount < 4)
- {
- SAL_WARN("cppcanvas.emf", "EMF+\t Bezier Draw does not support less than 4 points. Number of points: " << aCount);
break;
}
+ case EmfPlusRecordTypeDrawLines:
+ {
+ sal_uInt32 points;
+ rMS.ReadUInt32(points);
+ SAL_INFO("cppcanvas.emf", "EMF+ DrawLines in slot: " << (flags & 0xff) << " points: " << points);
+ EMFPPath path(points, true);
+ path.Read(rMS, flags, *this);
- ReadPoint(rMS, x1, y1, flags);
- // We need to add first starting point
- aStartPoint = Map(x1, y1);
- aPolygon.append(aStartPoint);
+ // 0x2000 bit indicates whether to draw an extra line between the last point
+ // and the first point, to close the shape.
+ EMFPPlusDrawPolygon(path.GetPolygon(*this, true, (flags & 0x2000)), flags);
+ // EMFPPlusDrawPolygon(path.GetPolygon(*this, true, (flags & 0x2000)), rFactoryParms, rState, rCanvas, flags);
- for (sal_uInt32 i = 4; i <= aCount; i += 3)
+ break;
+ }
+ case EmfPlusRecordTypeDrawPath:
{
- ReadPoint(rMS, x2, y2, flags);
- ReadPoint(rMS, x3, y3, flags);
- ReadPoint(rMS, x4, y4, flags);
+ sal_uInt32 penIndex;
+ rMS.ReadUInt32(penIndex);
+ SAL_INFO("cppcanvas.emf", "EMF+ DrawPath");
+ SAL_INFO("cppcanvas.emf", "EMF+\tpen: " << penIndex);
+ EMFPPath* path = static_cast<EMFPPath*>(aObjects[flags & 0xff].get());
+ SAL_WARN_IF(!path, "cppcanvas.emf", "EmfPlusRecordTypeDrawPath missing path");
- SAL_INFO("cppcanvas.emf", "EMF+\t Bezier points: " << x1 << "," << y1 << " " << x2 << "," << y2 << " " << x3 << "," << y3 << " " << x4 << "," << y4);
+ EMFPPlusDrawPolygon(path->GetPolygon(*this), penIndex);
+ // EMFPPlusDrawPolygon(path->GetPolygon(*this), rFactoryParms, rState, rCanvas, penIndex);
- aStartPoint = Map(x1, y1);
- aControlPointA = Map(x2, y2);
- aControlPointB = Map(x3, y3);
- aEndPoint = Map(x4, y4);
-
- ::basegfx::B2DCubicBezier cubicBezier(aStartPoint, aControlPointA, aControlPointB, aEndPoint);
- cubicBezier.adaptiveSubdivideByDistance(aPolygon, 10.0);
-// EMFPPlusDrawPolygon(::basegfx::B2DPolyPolygon(aPolygon), rFactoryParms,
-// rState, rCanvas, flags & 0xff);
- // The ending coordinate of one Bezier curve is the starting coordinate of the next.
- x1 = x4;
- y1 = y4;
+ break;
}
- break;
- }
- case EmfPlusRecordTypeDrawImage:
- case EmfPlusRecordTypeDrawImagePoints:
- {
- sal_uInt32 attrIndex;
- sal_Int32 sourceUnit;
- rMS.ReadUInt32(attrIndex).ReadInt32(sourceUnit);
- SAL_INFO("cppcanvas.emf", "EMF+ " << (type == EmfPlusRecordTypeDrawImagePoints ? "DrawImagePoints" : "DrawImage") << "attributes index: " << attrIndex << "source unit: " << sourceUnit);
- SAL_INFO("cppcanvas.emf", "EMF+\tTODO: use image attributes");
-
- if (sourceUnit == 2 && aObjects[flags & 0xff].get())
+ case EmfPlusRecordTypeDrawBeziers:
{
- // we handle only GraphicsUnit.Pixel now
- EMFPImage& image = *static_cast<EMFPImage *>(aObjects[flags & 0xff].get());
- float sx, sy, sw, sh;
- sal_Int32 aCount;
- ReadRectangle(rMS, sx, sy, sw, sh);
- ::tools::Rectangle aSource(Point(sx, sy), Size(sw, sh));
- SAL_INFO("cppcanvas.emf", "EMF+ " << (type == EmfPlusRecordTypeDrawImagePoints ? "DrawImagePoints" : "DrawImage") << " source rectangle: " << sx << "," << sy << " " << sw << "x" << sh);
- ::basegfx::B2DPoint aDstPoint;
- ::basegfx::B2DSize aDstSize;
- bool bValid = false;
-
- if (type == EmfPlusRecordTypeDrawImagePoints)
+ sal_uInt32 aCount;
+ float x1, y1, x2, y2, x3, y3, x4, y4;
+ ::basegfx::B2DPoint aStartPoint, aControlPointA, aControlPointB, aEndPoint;
+ ::basegfx::B2DPolygon aPolygon;
+ rMS.ReadUInt32(aCount);
+ SAL_INFO("cppcanvas.emf", "EMF+ DrawBeziers slot: " << (flags & 0xff) << "Number of points: " << aCount);
+ SAL_WARN_IF((aCount - 1) % 3 != 0, "cppcanvas.emf", "EMF+\t Bezier Draw not support number of points other than 4, 7, 10, 13, 16...");
+
+ if (aCount < 4)
+ {
+ SAL_WARN("cppcanvas.emf", "EMF+\t Bezier Draw does not support less than 4 points. Number of points: " << aCount);
+ break;
+ }
+
+ ReadPoint(rMS, x1, y1, flags);
+ // We need to add first starting point
+ aStartPoint = Map(x1, y1);
+ aPolygon.append(aStartPoint);
+
+ for (sal_uInt32 i = 4; i <= aCount; i += 3)
{
- rMS.ReadInt32(aCount);
+ ReadPoint(rMS, x2, y2, flags);
+ ReadPoint(rMS, x3, y3, flags);
+ ReadPoint(rMS, x4, y4, flags);
+
+ SAL_INFO("cppcanvas.emf", "EMF+\t Bezier points: " << x1 << "," << y1 << " " << x2 << "," << y2 << " " << x3 << "," << y3 << " " << x4 << "," << y4);
+
+ aStartPoint = Map(x1, y1);
+ aControlPointA = Map(x2, y2);
+ aControlPointB = Map(x3, y3);
+ aEndPoint = Map(x4, y4);
+
+ ::basegfx::B2DCubicBezier cubicBezier(aStartPoint, aControlPointA, aControlPointB, aEndPoint);
+ cubicBezier.adaptiveSubdivideByDistance(aPolygon, 10.0);
+
+ EMFPPlusDrawPolygon(::basegfx::B2DPolyPolygon(aPolygon), flags & 0xff);
+ // EMFPPlusDrawPolygon(::basegfx::B2DPolyPolygon(aPolygon), rFactoryParms,
+ // rState, rCanvas, flags & 0xff);
+ // The ending coordinate of one Bezier curve is the starting coordinate of the next.
+ x1 = x4;
+ y1 = y4;
+ }
+ break;
+ }
+ case EmfPlusRecordTypeDrawImage:
+ case EmfPlusRecordTypeDrawImagePoints:
+ {
+ sal_uInt32 attrIndex;
+ sal_Int32 sourceUnit;
+ rMS.ReadUInt32(attrIndex).ReadInt32(sourceUnit);
+ SAL_INFO("cppcanvas.emf", "EMF+ " << (type == EmfPlusRecordTypeDrawImagePoints ? "DrawImagePoints" : "DrawImage") << "attributes index: " << attrIndex << "source unit: " << sourceUnit);
+ SAL_INFO("cppcanvas.emf", "EMF+\tTODO: use image attributes");
- if (aCount == 3)
+ if (sourceUnit == 2 && aObjects[flags & 0xff].get())
+ {
+ // we handle only GraphicsUnit.Pixel now
+ EMFPImage& image = *static_cast<EMFPImage *>(aObjects[flags & 0xff].get());
+ float sx, sy, sw, sh;
+ sal_Int32 aCount;
+ ReadRectangle(rMS, sx, sy, sw, sh);
+ ::tools::Rectangle aSource(Point(sx, sy), Size(sw, sh));
+ SAL_INFO("cppcanvas.emf", "EMF+ " << (type == EmfPlusRecordTypeDrawImagePoints ? "DrawImagePoints" : "DrawImage") << " source rectangle: " << sx << "," << sy << " " << sw << "x" << sh);
+ ::basegfx::B2DPoint aDstPoint;
+ ::basegfx::B2DSize aDstSize;
+ bool bValid = false;
+
+ if (type == EmfPlusRecordTypeDrawImagePoints)
{
- // TODO: now that we now that this value is count we should support it better
- float x1, y1, x2, y2, x3, y3;
+ rMS.ReadInt32(aCount);
- ReadPoint(rMS, x1, y1, flags);
- ReadPoint(rMS, x2, y2, flags);
- ReadPoint(rMS, x3, y3, flags);
+ if (aCount == 3)
+ {
+ // TODO: now that we now that this value is count we should support it better
+ float x1, y1, x2, y2, x3, y3;
- SAL_INFO("cppcanvas.emf", "EMF+ destination points: " << x1 << "," << y1 << " " << x2 << "," << y2 << " " << x3 << "," << y3);
- SAL_INFO("cppcanvas.emf", "EMF+ destination rectangle: " << x1 << "," << y1 << " " << x2 - x1 << "x" << y3 - y1);
+ ReadPoint(rMS, x1, y1, flags);
+ ReadPoint(rMS, x2, y2, flags);
+ ReadPoint(rMS, x3, y3, flags);
- aDstPoint = Map(x1, y1);
- aDstSize = MapSize(x2 - x1, y3 - y1);
+ SAL_INFO("cppcanvas.emf", "EMF+ destination points: " << x1 << "," << y1 << " " << x2 << "," << y2 << " " << x3 << "," << y3);
+ SAL_INFO("cppcanvas.emf", "EMF+ destination rectangle: " << x1 << "," << y1 << " " << x2 - x1 << "x" << y3 - y1);
+ aDstPoint = Map(x1, y1);
+ aDstSize = MapSize(x2 - x1, y3 - y1);
+
+ bValid = true;
+ }
+ }
+ else if (type == EmfPlusRecordTypeDrawImage)
+ {
+ float dx, dy, dw, dh;
+ ReadRectangle(rMS, dx, dy, dw, dh, bool(flags & 0x4000));
+ SAL_INFO("cppcanvas.emf", "EMF+ destination rectangle: " << dx << "," << dy << " " << dw << "x" << dh);
+ aDstPoint = Map(dx, dy);
+ aDstSize = MapSize(dw, dh);
bValid = true;
}
- }
- else if (type == EmfPlusRecordTypeDrawImage)
- {
- float dx, dy, dw, dh;
- ReadRectangle(rMS, dx, dy, dw, dh, bool(flags & 0x4000));
- SAL_INFO("cppcanvas.emf", "EMF+ destination rectangle: " << dx << "," << dy << " " << dw << "x" << dh);
- aDstPoint = Map(dx, dy);
- aDstSize = MapSize(dw, dh);
- bValid = true;
- }
- if (bValid)
- {
- BitmapEx aBmp(image.graphic.GetBitmapEx());
- aBmp.Crop(aSource);
- Size aSize(aBmp.GetSizePixel());
- SAL_INFO("cppcanvas.emf", "EMF+ bitmap size: " << aSize.Width() << "x" << aSize.Height());
- if (aSize.Width() > 0 && aSize.Height() > 0)
+ if (bValid)
{
-// ActionSharedPtr pBmpAction(
-// internal::BitmapActionFactory::createBitmapAction(
-// aBmp,
-// rState.mapModeTransform * aDstPoint,
-// rState.mapModeTransform * aDstSize,
-// rCanvas,
-// rState));
-//
-// if (pBmpAction) {
-// maActions.push_back(MtfAction(pBmpAction,
-// rFactoryParms.mrCurrActionIndex));
-//
-// rFactoryParms.mrCurrActionIndex += pBmpAction->getActionCount() - 1;
-// }
+ BitmapEx aBmp(image.graphic.GetBitmapEx());
+ aBmp.Crop(aSource);
+ Size aSize(aBmp.GetSizePixel());
+ SAL_INFO("cppcanvas.emf", "EMF+ bitmap size: " << aSize.Width() << "x" << aSize.Height());
+ if (aSize.Width() > 0 && aSize.Height() > 0)
+ {
+ // ActionSharedPtr pBmpAction(
+ // internal::BitmapActionFactory::createBitmapAction(
+ // aBmp,
+ // rState.mapModeTransform * aDstPoint,
+ // rState.mapModeTransform * aDstSize,
+ // rCanvas,
+ // rState));
+ //
+ // if (pBmpAction) {
+ // maActions.push_back(MtfAction(pBmpAction,
+ // rFactoryParms.mrCurrActionIndex));
+ //
+ // rFactoryParms.mrCurrActionIndex += pBmpAction->getActionCount() - 1;
+ // }
+ }
+ else
+ {
+ SAL_INFO("cppcanvas.emf", "EMF+ warning: empty bitmap");
+ }
}
else
{
- SAL_INFO("cppcanvas.emf", "EMF+ warning: empty bitmap");
+ SAL_WARN("cppcanvas.emf", "EMF+ DrawImage(Points) TODO (fixme)");
}
}
else
{
- SAL_WARN("cppcanvas.emf", "EMF+ DrawImage(Points) TODO (fixme)");
+ SAL_WARN("cppcanvas.emf", "EMF+ DrawImage(Points) TODO (fixme) - possibly unsupported source units for crop rectangle");
}
+ break;
}
- else
+ case EmfPlusRecordTypeDrawString:
{
- SAL_WARN("cppcanvas.emf", "EMF+ DrawImage(Points) TODO (fixme) - possibly unsupported source units for crop rectangle");
+ SAL_INFO("cppcanvas.emf", "EMF+ DrawString");
+ sal_uInt32 brushId;
+ sal_uInt32 formatId;
+ sal_uInt32 stringLength;
+ rMS.ReadUInt32(brushId).ReadUInt32(formatId).ReadUInt32(stringLength);
+ SAL_INFO("cppcanvas.emf", "EMF+ DrawString brushId: " << brushId << " formatId: " << formatId << " length: " << stringLength);
+
+ if (flags & 0x8000)
+ {
+ float lx, ly, lw, lh;
+ rMS.ReadFloat(lx).ReadFloat(ly).ReadFloat(lw).ReadFloat(lh);
+ SAL_INFO("cppcanvas.emf", "EMF+ DrawString layoutRect: " << lx << "," << ly << " - " << lw << "x" << lh);
+ OUString text = read_uInt16s_ToOUString(rMS, stringLength);
+ EMFPStringFormat *stringFormat = static_cast< EMFPStringFormat* >(aObjects[formatId & 0xff].get());
+ // css::rendering::FontRequest aFontRequest;
+ //
+ // if (stringFormat)
+ // {
+ // LanguageTag aLanguageTag(static_cast< LanguageType >(stringFormat->language));
+ // aFontRequest.Locale = aLanguageTag.getLocale(false);
+ // SAL_INFO("cppcanvas.emf", "EMF+\t\t Font locale, Country:" << aLanguageTag.getCountry() << " Language:" << aLanguageTag.getLanguage());
+ // }
+ //
+ // SAL_INFO("cppcanvas.emf", "EMF+\t\t TODO Use all string formatting attributes during drawing");
+ //
+ // double cellSize = setFont(aFontRequest, flags & 0xff, rFactoryParms, rState);
+ // rState.textColor = COLOR(brushId);
+ //
+ // ::basegfx::B2DPoint point(Map(lx + 0.15*cellSize, ly + cellSize));
+ //
+ // ActionSharedPtr pTextAction(
+ // TextActionFactory::createTextAction(
+ // // position is just rough guess for now
+ // // we should calculate it exactly from layoutRect or font
+ // vcl::unotools::pointFromB2DPoint(point),
+ // ::Size(),
+ // ::Color(),
+ // ::Size(),
+ // ::Color(),
+ // text,
+ // 0,
+ // stringLength,
+ // nullptr,
+ // rFactoryParms.mrVDev,
+ // rFactoryParms.mrCanvas,
+ // rState,
+ // rFactoryParms.mrParms,
+ // false));
+ // if (pTextAction)
+ // {
+ // SAL_INFO("cppcanvas.emf", "EMF+\t\tadd text action");
+ //
+ // maActions.push_back(
+ // MtfAction(
+ // pTextAction,
+ // rFactoryParms.mrCurrActionIndex));
+ //
+ // rFactoryParms.mrCurrActionIndex += pTextAction->getActionCount() - 1;
+ // }
+ }
+ else
+ {
+ SAL_WARN("cppcanvas.emf", "EMF+ DrawString TODO - drawing with brush not yet supported");
+ }
+ break;
}
- break;
- }
- case EmfPlusRecordTypeDrawString:
- {
- SAL_INFO("cppcanvas.emf", "EMF+ DrawString");
- sal_uInt32 brushId;
- sal_uInt32 formatId;
- sal_uInt32 stringLength;
- rMS.ReadUInt32(brushId).ReadUInt32(formatId).ReadUInt32(stringLength);
- SAL_INFO("cppcanvas.emf", "EMF+ DrawString brushId: " << brushId << " formatId: " << formatId << " length: " << stringLength);
-
- if (flags & 0x8000)
+ case EmfPlusRecordTypeSetPageTransform:
{
- float lx, ly, lw, lh;
- rMS.ReadFloat(lx).ReadFloat(ly).ReadFloat(lw).ReadFloat(lh);
- SAL_INFO("cppcanvas.emf", "EMF+ DrawString layoutRect: " << lx << "," << ly << " - " << lw << "x" << lh);
- OUString text = read_uInt16s_ToOUString(rMS, stringLength);
- EMFPStringFormat *stringFormat = static_cast< EMFPStringFormat* >(aObjects[formatId & 0xff].get());
- css::rendering::FontRequest aFontRequest;
-
- if (stringFormat)
+ rMS.ReadFloat(fPageScale);
+ SAL_INFO("cppcanvas.emf", "EMF+ SetPageTransform");
+ SAL_INFO("cppcanvas.emf", "EMF+\tscale: " << fPageScale << " unit: " << flags);
+
+ if (flags != UnitTypePixel)
{
- LanguageTag aLanguageTag(static_cast< LanguageType >(stringFormat->language));
- aFontRequest.Locale = aLanguageTag.getLocale(false);
- SAL_INFO("cppcanvas.emf", "EMF+\t\t Font locale, Country:" << aLanguageTag.getCountry() << " Language:" << aLanguageTag.getLanguage());
+ SAL_WARN("cppcanvas.emf", "EMF+\t TODO Only UnitTypePixel is supported. ");
}
-
- SAL_INFO("cppcanvas.emf", "EMF+\t\t TODO Use all string formatting attributes during drawing");
-
-// double cellSize = setFont(aFontRequest, flags & 0xff, rFactoryParms, rState);
-// rState.textColor = COLOR(brushId);
-//
-// ::basegfx::B2DPoint point(Map(lx + 0.15*cellSize, ly + cellSize));
-//
-// ActionSharedPtr pTextAction(
-// TextActionFactory::createTextAction(
-// // position is just rough guess for now
-// // we should calculate it exactly from layoutRect or font
-// vcl::unotools::pointFromB2DPoint(point),
-// ::Size(),
-// ::Color(),
-// ::Size(),
-// ::Color(),
-// text,
-// 0,
-// stringLength,
-// nullptr,
-// rFactoryParms.mrVDev,
-// rFactoryParms.mrCanvas,
-// rState,
-// rFactoryParms.mrParms,
-// false));
-// if (pTextAction)
-// {
-// SAL_INFO("cppcanvas.emf", "EMF+\t\tadd text action");
-//
-// maActions.push_back(
-// MtfAction(
-// pTextAction,
-// rFactoryParms.mrCurrActionIndex));
-//
-// rFactoryParms.mrCurrActionIndex += pTextAction->getActionCount() - 1;
-// }
+ else
+ {
+ mnMmX *= fPageScale;
+ mnMmY *= fPageScale;
+ }
+ break;
}
- else
+ case EmfPlusRecordTypeSetRenderingOrigin:
{
- SAL_WARN("cppcanvas.emf", "EMF+ DrawString TODO - drawing with brush not yet supported");
+ rMS.ReadInt32(nOriginX).ReadInt32(nOriginY);
+ SAL_INFO("cppcanvas.emf", "EMF+ SetRenderingOrigin");
+ SAL_INFO("cppcanvas.emf", "EMF+\torigin [x,y]: " << nOriginX << "," << nOriginY);
+ break;
}
- break;
- }
- case EmfPlusRecordTypeSetPageTransform:
- {
- rMS.ReadFloat(fPageScale);
- SAL_INFO("cppcanvas.emf", "EMF+ SetPageTransform");
- SAL_INFO("cppcanvas.emf", "EMF+\tscale: " << fPageScale << " unit: " << flags);
-
- if (flags != UnitTypePixel)
+ case EmfPlusRecordTypeSetTextRenderingHint:
{
- SAL_WARN("cppcanvas.emf", "EMF+\t TODO Only UnitTypePixel is supported. ");
+ SAL_INFO("cppcanvas.emf", "EMF+ SetTextRenderingHint");
+ SAL_INFO("cppcanvas.emf", "EMF+\tTODO");
+ break;
}
- else
+ case EmfPlusRecordTypeSetAntiAliasMode:
{
- mnMmX *= fPageScale;
- mnMmY *= fPageScale;
+ SAL_INFO("cppcanvas.emf", "EMF+ SetAntiAliasMode");
+ SAL_INFO("cppcanvas.emf", "EMF+\tTODO");
+ break;
}
- break;
- }
- case EmfPlusRecordTypeSetRenderingOrigin:
- {
- rMS.ReadInt32(nOriginX).ReadInt32(nOriginY);
- SAL_INFO("cppcanvas.emf", "EMF+ SetRenderingOrigin");
- SAL_INFO("cppcanvas.emf", "EMF+\torigin [x,y]: " << nOriginX << "," << nOriginY);
- break;
- }
- case EmfPlusRecordTypeSetTextRenderingHint:
- {
- SAL_INFO("cppcanvas.emf", "EMF+ SetTextRenderingHint");
- SAL_INFO("cppcanvas.emf", "EMF+\tTODO");
- break;
- }
- case EmfPlusRecordTypeSetAntiAliasMode:
- {
- SAL_INFO("cppcanvas.emf", "EMF+ SetAntiAliasMode");
- SAL_INFO("cppcanvas.emf", "EMF+\tTODO");
- break;
- }
- case EmfPlusRecordTypeSetInterpolationMode:
- {
- SAL_INFO("cppcanvas.emf", "EMF+ InterpolationMode");
- SAL_INFO("cppcanvas.emf", "EMF+\tTODO");
- break;
- }
- case EmfPlusRecordTypeSetPixelOffsetMode:
- {
- SAL_INFO("cppcanvas.emf", "EMF+ SetPixelOffsetMode");
- SAL_INFO("cppcanvas.emf", "EMF+\tTODO");
- break;
- }
- case EmfPlusRecordTypeSetCompositingQuality:
- {
- SAL_INFO("cppcanvas.emf", "EMF+ SetCompositingQuality");
- SAL_INFO("cppcanvas.emf", "EMF+\tTODO");
- break;
- }
- case EmfPlusRecordTypeSave:
- {
- sal_uInt32 stackIndex;
- rMS.ReadUInt32(stackIndex);
- SAL_INFO("cppcanvas.emf", "EMF+ Save stack index: " << stackIndex);
-
-// GraphicStatePush(mGSStack, stackIndex, rState);
-
- break;
- }
- case EmfPlusRecordTypeRestore:
- {
- sal_uInt32 stackIndex;
- rMS.ReadUInt32(stackIndex);
- SAL_INFO("cppcanvas.emf", "EMF+ Restore stack index: " << stackIndex);
-
-// GraphicStatePop(mGSStack, stackIndex, rState);
-
- break;
- }
- case EmfPlusRecordTypeBeginContainerNoParams:
- {
- sal_uInt32 stackIndex;
- rMS.ReadUInt32(stackIndex);
- SAL_INFO("cppcanvas.emf", "EMF+ Begin Container No Params stack index: " << stackIndex);
-
-// GraphicStatePush(mGSContainerStack, stackIndex, rState);
- break;
- }
- case EmfPlusRecordTypeEndContainer:
- {
- sal_uInt32 stackIndex;
- rMS.ReadUInt32(stackIndex);
- SAL_INFO("cppcanvas.emf", "EMF+ End Container stack index: " << stackIndex);
-
-// GraphicStatePop(mGSContainerStack, stackIndex, rState);
- break;
- }
- case EmfPlusRecordTypeSetWorldTransform:
- {
- SAL_INFO("cppcanvas.emf", "EMF+ SetWorldTransform");
- basegfx::B2DHomMatrix transform;
- readXForm(rMS, transform);
- aWorldTransform = transform;
- SAL_INFO("cppcanvas.emf",
- "EMF+\tm11: " << aWorldTransform.get(0,0) << "\tm12: " << aWorldTransform.get(1,0) <<
- "\tm21: " << aWorldTransform.get(0,1) << "\tm22: " << aWorldTransform.get(1,1) <<
- "\tdx: " << aWorldTransform.get(0,2) << "\tdy: " << aWorldTransform.get(1,2));
- break;
- }
- case EmfPlusRecordTypeResetWorldTransform:
- {
- SAL_INFO("cppcanvas.emf", "EMF+ ResetWorldTransform");
- aWorldTransform.identity();
- break;
- }
- case EmfPlusRecordTypeMultiplyWorldTransform:
- {
- SAL_INFO("cppcanvas.emf", "EMF+ MultiplyWorldTransform");
- basegfx::B2DHomMatrix transform;
- readXForm(rMS, transform);
-
- SAL_INFO("cppcanvas.emf",
- "EMF+\tmatrix m11: " << transform.get(0,0) << "m12: " << transform.get(0,1) <<
- "EMF+\tm21: " << transform.get(1,0) << "m22: " << transform.get(1,1) <<
- "EMF+\tdx: " << transform.get(2,0) << "dy: " << transform.get(2,1));
-
- if (flags & 0x2000)
+ case EmfPlusRecordTypeSetInterpolationMode:
{
- // post multiply
- aWorldTransform *= transform;
+ SAL_INFO("cppcanvas.emf", "EMF+ InterpolationMode");
+ SAL_INFO("cppcanvas.emf", "EMF+\tTODO");
+ break;
}
- else
+ case EmfPlusRecordTypeSetPixelOffsetMode:
{
- // pre multiply
- transform *= aWorldTransform;
- aWorldTransform = transform;
+ SAL_INFO("cppcanvas.emf", "EMF+ SetPixelOffsetMode");
+ SAL_INFO("cppcanvas.emf", "EMF+\tTODO");
+ break;
+ }
+ case EmfPlusRecordTypeSetCompositingQuality:
+ {
+ SAL_INFO("cppcanvas.emf", "EMF+ SetCompositingQuality");
+ SAL_INFO("cppcanvas.emf", "EMF+\tTODO");
+ break;
}
+ case EmfPlusRecordTypeSave:
+ {
+ sal_uInt32 stackIndex;
+ rMS.ReadUInt32(stackIndex);
+ SAL_INFO("cppcanvas.emf", "EMF+ Save stack index: " << stackIndex);
- SAL_INFO("cppcanvas.emf",
- "EMF+\tmatrix m11: " << aWorldTransform.get(0, 0) << "m12: " << aWorldTransform.get(0, 1) <<
- "EMF+\tm21: " << aWorldTransform.get(1, 0) << "m22: " << aWorldTransform.get(1, 1) <<
- "EMF+\tdx: " << aWorldTransform.get(2, 0) << "dy: " << aWorldTransform.get(2, 1));
- break;
- }
- case EmfPlusRecordTypeTranslateWorldTransform:
- {
- SAL_INFO("cppcanvas.emf", "EMF+ TranslateWorldTransform");
+ // GraphicStatePush(mGSStack, stackIndex, rState);
- basegfx::B2DHomMatrix transform;
- float eDx, eDy;
- rMS.ReadFloat(eDx).ReadFloat(eDy);
- transform.set(0, 2, eDx);
- transform.set(1, 2, eDy);
+ break;
+ }
+ case EmfPlusRecordTypeRestore:
+ {
+ sal_uInt32 stackIndex;
+ rMS.ReadUInt32(stackIndex);
+ SAL_INFO("cppcanvas.emf", "EMF+ Restore stack index: " << stackIndex);
- SAL_INFO("cppcanvas.emf",
- "EMF+\tmatrix m11: " << transform.get(0, 0) << "m12: " << transform.get(0, 1) <<
- "EMF+\tm21: " << transform.get(1, 0) << "m22: " << transform.get(1, 1) <<
- "EMF+\tdx: " << transform.get(2, 0) << "dy: " << transform.get(2, 1));
+ // GraphicStatePop(mGSStack, stackIndex, rState);
- if (flags & 0x2000)
- {
- // post multiply
- aWorldTransform *= transform;
+ break;
}
- else
+ case EmfPlusRecordTypeBeginContainerNoParams:
{
- // pre multiply
- transform *= aWorldTransform;
- aWorldTransform = transform;
- }
+ sal_uInt32 stackIndex;
+ rMS.ReadUInt32(stackIndex);
+ SAL_INFO("cppcanvas.emf", "EMF+ Begin Container No Params stack index: " << stackIndex);
- SAL_INFO("cppcanvas.emf",
- "EMF+\tmatrix m11: " << aWorldTransform.get(0, 0) << "m12: " << aWorldTransform.get(0, 1) <<
- "EMF+\tm21: " << aWorldTransform.get(1, 0) << "m22: " << aWorldTransform.get(1, 1) <<
- "EMF+\tdx: " << aWorldTransform.get(2, 0) << "dy: " << aWorldTransform.get(2, 1));
- break;
- }
- case EmfPlusRecordTypeScaleWorldTransform:
- {
- basegfx::B2DHomMatrix transform;
- float eM11, eM22;
- rMS.ReadFloat(eM11).ReadFloat(eM22);
- transform.set(0, 0, eM11);
- transform.set(1, 1, eM22);
-
- SAL_INFO("cppcanvas.emf", "EMF+ ScaleWorldTransform Sx: " << transform.get(0,0) << " Sy: " << transform.get(1,1));
- SAL_INFO("cppcanvas.emf",
- "EMF+\t m11: " << aWorldTransform.get(0,0) << ", m12: " << aWorldTransform.get(0,1) <<
- "EMF+\t m21: " << aWorldTransform.get(1,0) << ", m22: " << aWorldTransform.get(1,1) <<
- "EMF+\t dx: " << aWorldTransform.get(2,0) << ", dy: " << aWorldTransform.get(2,1));
-
- if (flags & 0x2000)
+ // GraphicStatePush(mGSContainerStack, stackIndex, rState);
+ break;
+ }
+ case EmfPlusRecordTypeEndContainer:
{
- // post multiply
- aWorldTransform *= transform;
+ sal_uInt32 stackIndex;
+ rMS.ReadUInt32(stackIndex);
+ SAL_INFO("cppcanvas.emf", "EMF+ End Container stack index: " << stackIndex);
+
+ // GraphicStatePop(mGSContainerStack, stackIndex, rState);
+ break;
}
- else
+ case EmfPlusRecordTypeSetWorldTransform:
{
- // pre multiply
- transform *= aWorldTransform;
+ SAL_INFO("cppcanvas.emf", "EMF+ SetWorldTransform");
+ basegfx::B2DHomMatrix transform;
+ readXForm(rMS, transform);
aWorldTransform = transform;
+ SAL_INFO("cppcanvas.emf",
+ "EMF+\tm11: " << aWorldTransform.get(0,0) << "\tm12: " << aWorldTransform.get(1,0) <<
+ "\tm21: " << aWorldTransform.get(0,1) << "\tm22: " << aWorldTransform.get(1,1) <<
+ "\tdx: " << aWorldTransform.get(0,2) << "\tdy: " << aWorldTransform.get(1,2));
+ break;
}
+ case EmfPlusRecordTypeResetWorldTransform:
+ {
+ SAL_INFO("cppcanvas.emf", "EMF+ ResetWorldTransform");
+ aWorldTransform.identity();
+ break;
+ }
+ case EmfPlusRecordTypeMultiplyWorldTransform:
+ {
+ SAL_INFO("cppcanvas.emf", "EMF+ MultiplyWorldTransform");
+ basegfx::B2DHomMatrix transform;
+ readXForm(rMS, transform);
- SAL_INFO("cppcanvas.emf",
- "EMF+\t m11: " << aWorldTransform.get(0, 0) << ", m12: " << aWorldTransform.get(0, 1) <<
- "EMF+\t m21: " << aWorldTransform.get(1, 0) << ", m22: " << aWorldTransform.get(1, 1) <<
- "EMF+\t dx: " << aWorldTransform.get(2, 0) << ", dy: " << aWorldTransform.get(2, 1));
- break;
- }
- case EmfPlusRecordTypeSetClipRect:
- {
- int combineMode = (flags >> 8) & 0xf;
+ SAL_INFO("cppcanvas.emf",
+ "EMF+\tmatrix m11: " << transform.get(0,0) << "m12: " << transform.get(0,1) <<
+ "EMF+\tm21: " << transform.get(1,0) << "m22: " << transform.get(1,1) <<
+ "EMF+\tdx: " << transform.get(2,0) << "dy: " << transform.get(2,1));
+
+ if (flags & 0x2000)
+ {
+ // post multiply
+ aWorldTransform *= transform;
+ }
+ else
+ {
+ // pre multiply
+ transform *= aWorldTransform;
+ aWorldTransform = transform;
+ }
- SAL_INFO("cppcanvas.emf", "EMF+ SetClipRect combine mode: " << combineMode);
-#if OSL_DEBUG_LEVEL > 1
- if (combineMode > 1) {
- SAL_INFO("cppcanvas.emf", "EMF+ TODO combine mode > 1");
+ SAL_INFO("cppcanvas.emf",
+ "EMF+\tmatrix m11: " << aWorldTransform.get(0, 0) << "m12: " << aWorldTransform.get(0, 1) <<
+ "EMF+\tm21: " << aWorldTransform.get(1, 0) << "m22: " << aWorldTransform.get(1, 1) <<
+ "EMF+\tdx: " << aWorldTransform.get(2, 0) << "dy: " << aWorldTransform.get(2, 1));
+ break;
}
-#endif
+ case EmfPlusRecordTypeTranslateWorldTransform:
+ {
+ SAL_INFO("cppcanvas.emf", "EMF+ TranslateWorldTransform");
- float dx, dy, dw, dh;
- ReadRectangle(rMS, dx, dy, dw, dh);
- SAL_INFO("cppcanvas.emf", "EMF+ RectData: " << dx << "," << dy << " " << dw << "x" << dh);
- ::basegfx::B2DPoint mappedPoint(Map(dx, dy));
- ::basegfx::B2DSize mappedSize(MapSize(dw, dh));
-
- ::basegfx::B2DPolyPolygon polyPolygon(
- ::basegfx::B2DPolygon(
- ::basegfx::tools::createPolygonFromRect(::basegfx::B2DRectangle(
- mappedPoint.getX(),
- mappedPoint.getY(),
- mappedPoint.getX() + mappedSize.getX(),
- mappedPoint.getY() + mappedSize.getY()))));
-// polyPolygon.transform(rState.mapModeTransform);
-//
-// updateClipping(polyPolygon, rFactoryParms, combineMode == 1);
- break;
- }
- case EmfPlusRecordTypeSetClipPath:
- {
- int combineMode = (flags >> 8) & 0xf;
- SAL_INFO("cppcanvas.emf", "EMF+ SetClipPath combine mode: " << combineMode);
- SAL_INFO("cppcanvas.emf", "EMF+\tpath in slot: " << (flags & 0xff));
+ basegfx::B2DHomMatrix transform;
+ float eDx, eDy;
+ rMS.ReadFloat(eDx).ReadFloat(eDy);
+ transform.set(0, 2, eDx);
+ transform.set(1, 2, eDy);
- EMFPPath& path = *static_cast<EMFPPath*>(aObjects[flags & 0xff].get());
- ::basegfx::B2DPolyPolygon& clipPoly(path.GetPolygon(*this));
-// clipPoly.transform(rState.mapModeTransform);
+ SAL_INFO("cppcanvas.emf",
+ "EMF+\tmatrix m11: " << transform.get(0, 0) << "m12: " << transform.get(0, 1) <<
+ "EMF+\tm21: " << transform.get(1, 0) << "m22: " << transform.get(1, 1) <<
+ "EMF+\tdx: " << transform.get(2, 0) << "dy: " << transform.get(2, 1));
- switch (combineMode)
- {
- case EmfPlusCombineModeReplace:
- case EmfPlusCombineModeIntersect:
- case EmfPlusCombineModeUnion: // Is this, EmfPlusCombineModeXOR and EmfPlusCombineModeComplement correct?
- case EmfPlusCombineModeXOR:
- case EmfPlusCombineModeComplement:
+ if (flags & 0x2000)
{
- // updateClipping(clipPoly, rFactoryParms, combineMode == 1);
- break;
+ // post multiply
+ aWorldTransform *= transform;
}
- case EmfPlusCombineModeExclude:
+ else
{
- // Not doing anything is better then including exactly what we wanted to exclude.
- break;
+ // pre multiply
+ transform *= aWorldTransform;
+ aWorldTransform = transform;
}
- }
-
- break;
- }
- case EmfPlusRecordTypeSetClipRegion:
- {
- int combineMode = (flags >> 8) & 0xf;
- SAL_INFO("cppcanvas.emf", "EMF+ SetClipRegion");
- SAL_INFO("cppcanvas.emf", "EMF+\tregion in slot: " << (flags & 0xff) << " combine mode: " << combineMode);
- EMFPRegion *region = static_cast<EMFPRegion*>(aObjects[flags & 0xff].get());
- // reset clip
- if (region && region->parts == 0 && region->initialState == EmfPlusRegionInitialStateInfinite)
+ SAL_INFO("cppcanvas.emf",
+ "EMF+\tmatrix m11: " << aWorldTransform.get(0, 0) << "m12: " << aWorldTransform.get(0, 1) <<
+ "EMF+\tm21: " << aWorldTransform.get(1, 0) << "m22: " << aWorldTransform.get(1, 1) <<
+ "EMF+\tdx: " << aWorldTransform.get(2, 0) << "dy: " << aWorldTransform.get(2, 1));
+ break;
+ }
+ case EmfPlusRecordTypeScaleWorldTransform:
{
-// updateClipping(::basegfx::B2DPolyPolygon(), rFactoryParms, combineMode == 1);
+ basegfx::B2DHomMatrix transform;
+ float eM11, eM22;
+ rMS.ReadFloat(eM11).ReadFloat(eM22);
+ transform.set(0, 0, eM11);
+ transform.set(1, 1, eM22);
+
+ SAL_INFO("cppcanvas.emf", "EMF+ ScaleWorldTransform Sx: " << transform.get(0,0) << " Sy: " << transform.get(1,1));
+ SAL_INFO("cppcanvas.emf",
+ "EMF+\t m11: " << aWorldTransform.get(0,0) << ", m12: " << aWorldTransform.get(0,1) <<
+ "EMF+\t m21: " << aWorldTransform.get(1,0) << ", m22: " << aWorldTransform.get(1,1) <<
+ "EMF+\t dx: " << aWorldTransform.get(2,0) << ", dy: " << aWorldTransform.get(2,1));
+
+ if (flags & 0x2000)
+ {
+ // post multiply
+ aWorldTransform *= transform;
+ }
+ else
+ {
+ // pre multiply
+ transform *= aWorldTransform;
+ aWorldTransform = transform;
+ }
+
+ SAL_INFO("cppcanvas.emf",
+ "EMF+\t m11: " << aWorldTransform.get(0, 0) << ", m12: " << aWorldTransform.get(0, 1) <<
+ "EMF+\t m21: " << aWorldTransform.get(1, 0) << ", m22: " << aWorldTransform.get(1, 1) <<
+ "EMF+\t dx: " << aWorldTransform.get(2, 0) << ", dy: " << aWorldTransform.get(2, 1));
+ break;
}
- else
+ case EmfPlusRecordTypeSetClipRect:
{
- SAL_INFO("cppcanvas.emf", "EMF+\tTODO");
+ int combineMode = (flags >> 8) & 0xf;
+
+ SAL_INFO("cppcanvas.emf", "EMF+ SetClipRect combine mode: " << combineMode);
+ #if OSL_DEBUG_LEVEL > 1
+ if (combineMode > 1) {
+ SAL_INFO("cppcanvas.emf", "EMF+ TODO combine mode > 1");
+ }
+ #endif
+
+ float dx, dy, dw, dh;
+ ReadRectangle(rMS, dx, dy, dw, dh);
+ SAL_INFO("cppcanvas.emf", "EMF+ RectData: " << dx << "," << dy << " " << dw << "x" << dh);
+ ::basegfx::B2DPoint mappedPoint(Map(dx, dy));
+ ::basegfx::B2DSize mappedSize(MapSize(dw, dh));
+
+ ::basegfx::B2DPolyPolygon polyPolygon(
+ ::basegfx::B2DPolygon(
+ ::basegfx::tools::createPolygonFromRect(::basegfx::B2DRectangle(
+ mappedPoint.getX(),
+ mappedPoint.getY(),
+ mappedPoint.getX() + mappedSize.getX(),
+ mappedPoint.getY() + mappedSize.getY()))));
+
+ // use existing tooling from wmfemfhelper
+ HandleNewClipRegion(polyPolygon, mrTargetHolders, mrPropertyHolders);
+ // polyPolygon.transform(rState.mapModeTransform);
+ // updateClipping(polyPolygon, rFactoryParms, combineMode == 1);
+ break;
}
- break;
- }
- case EmfPlusRecordTypeDrawDriverString:
- {
- SAL_INFO("cppcanvas.emf", "EMF+ DrawDriverString, flags: 0x" << std::hex << flags << std::dec);
- sal_uInt32 brushIndexOrColor;
- sal_uInt32 optionFlags;
- sal_uInt32 hasMatrix;
- sal_uInt32 glyphsCount;
- rMS.ReadUInt32(brushIndexOrColor).ReadUInt32(optionFlags).ReadUInt32(hasMatrix).ReadUInt32(glyphsCount);
- SAL_INFO("cppcanvas.emf", "EMF+\t: " << ((flags & 0x8000) ? "color" : "brush index") << " 0x" << std::hex << brushIndexOrColor << std::dec);
- SAL_INFO("cppcanvas.emf", "EMF+\toption flags: 0x" << std::hex << optionFlags << std::dec);
- SAL_INFO("cppcanvas.emf", "EMF+\thas matrix: " << hasMatrix);
- SAL_INFO("cppcanvas.emf", "EMF+\tglyphs: " << glyphsCount);
-
- if ((optionFlags & 1) && glyphsCount > 0)
+ case EmfPlusRecordTypeSetClipPath:
{
- std::unique_ptr<float[]> charsPosX(new float[glyphsCount]);
- std::unique_ptr<float[]> charsPosY(new float[glyphsCount]);
- OUString text = read_uInt16s_ToOUString(rMS, glyphsCount);
+ int combineMode = (flags >> 8) & 0xf;
+ SAL_INFO("cppcanvas.emf", "EMF+ SetClipPath combine mode: " << combineMode);
+ SAL_INFO("cppcanvas.emf", "EMF+\tpath in slot: " << (flags & 0xff));
+
+ EMFPPath& path = *static_cast<EMFPPath*>(aObjects[flags & 0xff].get());
+ ::basegfx::B2DPolyPolygon& clipPoly(path.GetPolygon(*this));
+ // clipPoly.transform(rState.mapModeTransform);
- for (sal_uInt32 i = 0; i<glyphsCount; i++)
+ switch (combineMode)
{
- rMS.ReadFloat(charsPosX[i]).ReadFloat(charsPosY[i]);
- SAL_INFO("cppcanvas.emf", "EMF+\tglyphPosition[" << i << "]: " << charsPosX[i] << "," << charsPosY[i]);
+ case EmfPlusCombineModeReplace:
+ case EmfPlusCombineModeIntersect:
+ case EmfPlusCombineModeUnion: // Is this, EmfPlusCombineModeXOR and EmfPlusCombineModeComplement correct?
+ case EmfPlusCombineModeXOR:
+ case EmfPlusCombineModeComplement:
+ {
+ // use existing tooling from wmfemfhelper
+ HandleNewClipRegion(clipPoly, mrTargetHolders, mrPropertyHolders);
+ // updateClipping(clipPoly, rFactoryParms, combineMode == 1);
+ break;
+ }
+ case EmfPlusCombineModeExclude:
+ {
+ // Not doing anything is better then including exactly what we wanted to exclude.
+ break;
+ }
}
- basegfx::B2DHomMatrix transform;
+ break;
+ }
+ case EmfPlusRecordTypeSetClipRegion:
+ {
+ int combineMode = (flags >> 8) & 0xf;
+ SAL_INFO("cppcanvas.emf", "EMF+ SetClipRegion");
+ SAL_INFO("cppcanvas.emf", "EMF+\tregion in slot: " << (flags & 0xff) << " combine mode: " << combineMode);
+ EMFPRegion *region = static_cast<EMFPRegion*>(aObjects[flags & 0xff].get());
- if (hasMatrix)
+ // reset clip
+ if (region && region->parts == 0 && region->initialState == EmfPlusRegionInitialStateInfinite)
+ {
+ // use existing tooling from wmfemfhelper
+ HandleNewClipRegion(::basegfx::B2DPolyPolygon(), mrTargetHolders, mrPropertyHolders);
+ // updateClipping(::basegfx::B2DPolyPolygon(), rFactoryParms, combineMode == 1);
+ }
+ else
{
- readXForm(rMS, transform);
- SAL_INFO("cppcanvas.emf", "EMF+\tmatrix: " << transform.get(0,0) << ", " << transform.get(1,0) <<
- ", " << transform.get(0,1) << ", " << transform.get(1,1) <<
- ", " << transform.get(0,2) << ", " << transform.get(1,2));
+ SAL_INFO("cppcanvas.emf", "EMF+\tTODO");
}
+ break;
+ }
+ case EmfPlusRecordTypeDrawDriverString:
+ {
+ SAL_INFO("cppcanvas.emf", "EMF+ DrawDriverString, flags: 0x" << std::hex << flags << std::dec);
+ sal_uInt32 brushIndexOrColor;
+ sal_uInt32 optionFlags;
+ sal_uInt32 hasMatrix;
+ sal_uInt32 glyphsCount;
+ rMS.ReadUInt32(brushIndexOrColor).ReadUInt32(optionFlags).ReadUInt32(hasMatrix).ReadUInt32(glyphsCount);
+ SAL_INFO("cppcanvas.emf", "EMF+\t: " << ((flags & 0x8000) ? "color" : "brush index") << " 0x" << std::hex << brushIndexOrColor << std::dec);
+ SAL_INFO("cppcanvas.emf", "EMF+\toption flags: 0x" << std::hex << optionFlags << std::dec);
+ SAL_INFO("cppcanvas.emf", "EMF+\thas matrix: " << hasMatrix);
+ SAL_INFO("cppcanvas.emf", "EMF+\tglyphs: " << glyphsCount);
+
+ if ((optionFlags & 1) && glyphsCount > 0)
+ {
+ std::unique_ptr<float[]> charsPosX(new float[glyphsCount]);
+ std::unique_ptr<float[]> charsPosY(new float[glyphsCount]);
+ OUString text = read_uInt16s_ToOUString(rMS, glyphsCount);
-// rendering::FontRequest aFontRequest;
-// // add the text action
-// setFont(aFontRequest, flags & 0xff, rFactoryParms, rState);
-//
-// if (flags & 0x8000)
-// rState.textColor = COLOR(brushIndexOrColor);
-//
-// ::basegfx::B2DPoint point(Map(charsPosX[0], charsPosY[0]));
-//
-// ActionSharedPtr pTextAction(
-// TextActionFactory::createTextAction(
-// vcl::unotools::pointFromB2DPoint(point),
-// ::Size(),
-// ::Color(),
-// ::Size(),
-// ::Color(),
-// text,
-// 0,
-// glyphsCount,
-// nullptr,
-// rFactoryParms.mrVDev,
-// rFactoryParms.mrCanvas,
-// rState,
-// rFactoryParms.mrParms,
-// false));
-//
-// if (pTextAction)
-// {
-// SAL_INFO("cppcanvas.emf", "EMF+\t\tadd text action");
-//
-// maActions.push_back(
-// MtfAction(
-// pTextAction,
-// rFactoryParms.mrCurrActionIndex));
-//
-// rFactoryParms.mrCurrActionIndex += pTextAction->getActionCount() - 1;
-// }
+ for (sal_uInt32 i = 0; i<glyphsCount; i++)
+ {
+ rMS.ReadFloat(charsPosX[i]).ReadFloat(charsPosY[i]);
+ SAL_INFO("cppcanvas.emf", "EMF+\tglyphPosition[" << i << "]: " << charsPosX[i] << "," << charsPosY[i]);
+ }
+
+ basegfx::B2DHomMatrix transform;
+
+ if (hasMatrix)
+ {
+ readXForm(rMS, transform);
+ SAL_INFO("cppcanvas.emf", "EMF+\tmatrix: " << transform.get(0,0) << ", " << transform.get(1,0) <<
+ ", " << transform.get(0,1) << ", " << transform.get(1,1) <<
+ ", " << transform.get(0,2) << ", " << transform.get(1,2));
+ }
+
+ // rendering::FontRequest aFontRequest;
+ // // add the text action
+ // setFont(aFontRequest, flags & 0xff, rFactoryParms, rState);
+ //
+ // if (flags & 0x8000)
+ // rState.textColor = COLOR(brushIndexOrColor);
+ //
+ // ::basegfx::B2DPoint point(Map(charsPosX[0], charsPosY[0]));
+ //
+ // ActionSharedPtr pTextAction(
+ // TextActionFactory::createTextAction(
+ // vcl::unotools::pointFromB2DPoint(point),
+ // ::Size(),
+ // ::Color(),
+ // ::Size(),
+ // ::Color(),
+ // text,
+ // 0,
+ // glyphsCount,
+ // nullptr,
+ // rFactoryParms.mrVDev,
+ // rFactoryParms.mrCanvas,
+ // rState,
+ // rFactoryParms.mrParms,
+ // false));
+ //
+ // if (pTextAction)
+ // {
+ // SAL_INFO("cppcanvas.emf", "EMF+\t\tadd text action");
+ //
+ // maActions.push_back(
+ // MtfAction(
+ // pTextAction,
+ // rFactoryParms.mrCurrActionIndex));
+ //
+ // rFactoryParms.mrCurrActionIndex += pTextAction->getActionCount() - 1;
+ // }
+ }
+ else
+ {
+ SAL_WARN("cppcanvas.emf", "EMF+\tTODO: fonts (non-unicode glyphs chars)");
+ }
+ break;
}
- else
+ default:
{
- SAL_WARN("cppcanvas.emf", "EMF+\tTODO: fonts (non-unicode glyphs chars)");
+ SAL_WARN("cppcanvas.emf", "EMF+ TODO unhandled record type: 0x" << std::hex << type << std::dec);
}
- break;
- }
- default:
- {
- SAL_WARN("cppcanvas.emf", "EMF+ TODO unhandled record type: 0x" << std::hex << type << std::dec);
- }
}
}
diff --git a/drawinglayer/source/tools/emfphelperdata.hxx b/drawinglayer/source/tools/emfphelperdata.hxx
index f4920fb9d3e5..c2d799cfd5f5 100644
--- a/drawinglayer/source/tools/emfphelperdata.hxx
+++ b/drawinglayer/source/tools/emfphelperdata.hxx
@@ -220,6 +220,10 @@ namespace emfplushelper
// internal mapper
void MapToDevice(double& x, double& y);
+ // primitive creators
+ void EMFPPlusDrawPolygon(const ::basegfx::B2DPolyPolygon& polygon, sal_uInt32 penIndex);
+ void EMFPPlusFillPolygon(const ::basegfx::B2DPolyPolygon& polygon, bool isColor, sal_uInt32 brushIndexOrColor);
+
public:
EmfPlusHelperData(
SvMemoryStream& rMS,
diff --git a/drawinglayer/source/tools/emfpimage.cxx b/drawinglayer/source/tools/emfpimage.cxx
index 5b388c0da660..9e1cc8ac3551 100644
--- a/drawinglayer/source/tools/emfpimage.cxx
+++ b/drawinglayer/source/tools/emfpimage.cxx
@@ -43,36 +43,39 @@ namespace emfplushelper
void EMFPImage::Read(SvMemoryStream &s, sal_uInt32 dataSize, bool bUseWholeStream)
{
sal_uInt32 header, bitmapType;
-
s.ReadUInt32(header).ReadUInt32(type);
-
SAL_INFO("cppcanvas.emf", "EMF+\timage\nEMF+\theader: 0x" << std::hex << header << " type: " << type << std::dec);
- if (type == 1) { // bitmap
+ if (1 == type)
+ {
+ // bitmap
s.ReadInt32(width).ReadInt32(height).ReadInt32(stride).ReadInt32(pixelFormat).ReadUInt32(bitmapType);
SAL_INFO("cppcanvas.emf", "EMF+\tbitmap width: " << width << " height: " << height << " stride: " << stride << " pixelFormat: 0x" << std::hex << pixelFormat << std::dec);
- if ((bitmapType != 0) || (width == 0)) { // non native formats
- GraphicFilter filter;
+ if ((bitmapType != 0) || (width == 0))
+ {
+ // non native formats
+ GraphicFilter filter;
filter.ImportGraphic(graphic, OUString(), s);
SAL_INFO("cppcanvas.emf", "EMF+\tbitmap width: " << graphic.GetBitmap().GetSizePixel().Width() << " height: " << graphic.GetBitmap().GetSizePixel().Height());
}
-
}
- else if (type == 2) { // metafile
+ else if (2 == type)
+ {
+ // metafile
sal_Int32 mfType, mfSize;
-
s.ReadInt32(mfType).ReadInt32(mfSize);
+
if (bUseWholeStream)
dataSize = s.remainingSize();
else
dataSize -= 16;
+
SAL_INFO("cppcanvas.emf", "EMF+\tmetafile type: " << mfType << " dataSize: " << mfSize << " real size calculated from record dataSize: " << dataSize);
GraphicFilter filter;
// workaround buggy metafiles, which have wrong mfSize set (n#705956 for example)
SvMemoryStream mfStream(const_cast<char *>(static_cast<char const *>(s.GetData()) + s.Tell()), dataSize, StreamMode::READ);
-
filter.ImportGraphic(graphic, OUString(), mfStream);
// debug code - write the stream to debug file /tmp/emf-stream.emf
diff --git a/drawinglayer/source/tools/emfppath.cxx b/drawinglayer/source/tools/emfppath.cxx
index ae4cfa60149a..64b3411e4b49 100644
--- a/drawinglayer/source/tools/emfppath.cxx
+++ b/drawinglayer/source/tools/emfppath.cxx
@@ -44,10 +44,14 @@ namespace emfplushelper
{
EMFPPath::EMFPPath (sal_Int32 _nPoints, bool bLines)
{
- if( _nPoints<0 || sal_uInt32(_nPoints)>SAL_MAX_INT32/(2*sizeof(float)) )
- _nPoints = SAL_MAX_INT32/(2*sizeof(float));
+ if (_nPoints<0 || sal_uInt32(_nPoints)>SAL_MAX_INT32 / (2 * sizeof(float)))
+ {
+ _nPoints = SAL_MAX_INT32 / (2 * sizeof(float));
+ }
+
nPoints = _nPoints;
pPoints = new float [nPoints*2];
+
if (!bLines)
pPointTypes = new sal_uInt8 [_nPoints];
else
@@ -63,13 +67,17 @@ namespace emfplushelper
// TODO: remove rR argument when debug code is no longer needed
void EMFPPath::Read (SvStream& s, sal_uInt32 pathFlags, EmfPlusHelperData& rR)
{
- for (int i = 0; i < nPoints; i ++) {
- if (pathFlags & 0x800) {
+ for (int i = 0; i < nPoints; i ++)
+ {
+ if (pathFlags & 0x800)
+ {
// EMFPlusPointR: points are stored in EMFPlusInteger7 or
// EMFPlusInteger15 objects, see section 2.2.2.21/22
// If 0x800 bit is set, the 0x4000 bit is undefined and must be ignored
SAL_WARN("cppcanvas.emf", "EMF+\t\t TODO - parse EMFPlusPointR object (section 2.2.1.6)");
- } else if (pathFlags & 0x4000) {
+ }
+ else if (pathFlags & 0x4000)
+ {
// EMFPlusPoint: stored in signed short 16bit integer format
sal_Int16 x, y;
@@ -77,19 +85,23 @@ namespace emfplushelper
SAL_INFO ("cppcanvas.emf", "EMF+\t EMFPlusPoint [x,y]: " << x << "," << y);
pPoints [i*2] = x;
pPoints [i*2 + 1] = y;
- } else {
+ }
+ else
+ {
// EMFPlusPointF: stored in Single (float) format
s.ReadFloat( pPoints [i*2] ).ReadFloat( pPoints [i*2 + 1] );
SAL_INFO ("cppcanvas.emf", "EMF+\t EMFPlusPointF [x,y]: " << pPoints [i*2] << "," << pPoints [i*2 + 1]);
}
-
}
if (pPointTypes)
- for (int i = 0; i < nPoints; i ++) {
- s.ReadUChar( pPointTypes [i] );
- SAL_INFO ("cppcanvas.emf", "EMF+\tpoint type: " << (int)pPointTypes [i]);
+ {
+ for (int i = 0; i < nPoints; i++)
+ {
+ s.ReadUChar(pPointTypes[i]);
+ SAL_INFO("cppcanvas.emf", "EMF+\tpoint type: " << (int)pPointTypes[i]);
}
+ }
aPolygon.clear ();
@@ -106,14 +118,15 @@ namespace emfplushelper
::basegfx::B2DPolyPolygon& EMFPPath::GetPolygon (EmfPlusHelperData& rR, bool bMapIt, bool bAddLineToCloseShape)
{
::basegfx::B2DPolygon polygon;
-
aPolygon.clear ();
-
int last_normal = 0, p = 0;
::basegfx::B2DPoint prev, mapped;
bool hasPrev = false;
- for (int i = 0; i < nPoints; i ++) {
- if (p && pPointTypes && (pPointTypes [i] == 0)) {
+
+ for (int i = 0; i < nPoints; i ++)
+ {
+ if (p && pPointTypes && (pPointTypes [i] == 0))
+ {
aPolygon.append (polygon);
last_normal = i;
p = 0;
@@ -124,29 +137,45 @@ namespace emfplushelper
mapped = rR.Map (pPoints [i*2], pPoints [i*2 + 1]);
else
mapped = ::basegfx::B2DPoint (pPoints [i*2], pPoints [i*2 + 1]);
- if (pPointTypes) {
- if ((pPointTypes [i] & 0x07) == 3) {
- if (((i - last_normal )% 3) == 1) {
+
+ if (pPointTypes)
+ {
+ if ((pPointTypes [i] & 0x07) == 3)
+ {
+ if (((i - last_normal )% 3) == 1)
+ {
polygon.setNextControlPoint (p - 1, mapped);
SAL_INFO ("cppcanvas.emf", "polygon append next: " << p - 1 << " mapped: " << mapped.getX () << "," << mapped.getY ());
continue;
- } else if (((i - last_normal) % 3) == 2) {
+ }
+ else if (((i - last_normal) % 3) == 2)
+ {
prev = mapped;
hasPrev = true;
continue;
}
- } else
+ }
+ else
+ {
last_normal = i;
+ }
}
+
polygon.append (mapped);
SAL_INFO ("cppcanvas.emf", "polygon append point: " << pPoints [i*2] << "," << pPoints [i*2 + 1] << " mapped: " << mapped.getX () << ":" << mapped.getY ());
- if (hasPrev) {
+
+ if (hasPrev)
+ {
polygon.setPrevControlPoint (p, prev);
SAL_INFO ("cppcanvas.emf", "polygon append prev: " << p << " mapped: " << prev.getX () << "," << prev.getY ());
hasPrev = false;
}
+
p ++;
- if (pPointTypes && (pPointTypes [i] & 0x80)) { // closed polygon
+
+ if (pPointTypes && (pPointTypes [i] & 0x80))
+ {
+ // closed polygon
polygon.setClosed (true);
aPolygon.append (polygon);
SAL_INFO ("cppcanvas.emf", "close polygon");
@@ -155,14 +184,18 @@ namespace emfplushelper
polygon.clear ();
}
}
+
// Draw an extra line between the last point and the first point, to close the shape.
- if (bAddLineToCloseShape) {
+ if (bAddLineToCloseShape)
+ {
if (bMapIt)
polygon.append (rR.Map (pPoints [0], pPoints [1]) );
else
polygon.append (::basegfx::B2DPoint (pPoints [0], pPoints [1]) );
}
- if (polygon.count ()) {
+
+ if (polygon.count ())
+ {
aPolygon.append (polygon);
#if OSL_DEBUG_LEVEL > 1
diff --git a/drawinglayer/source/tools/emfppen.cxx b/drawinglayer/source/tools/emfppen.cxx
index d60f10e360f4..851518b486f5 100644
--- a/drawinglayer/source/tools/emfppen.cxx
+++ b/drawinglayer/source/tools/emfppen.cxx
@@ -116,8 +116,8 @@ namespace emfplushelper
{
switch (nEmfStroke)
{
- case EmfPlusLineCapTypeSquare: return rendering::PathCapType::SQUARE;
- case EmfPlusLineCapTypeRound: return rendering::PathCapType::ROUND;
+ case EmfPlusLineCapTypeSquare: return rendering::PathCapType::SQUARE;
+ case EmfPlusLineCapTypeRound: return rendering::PathCapType::ROUND;
}
// we have no mapping for EmfPlusLineCapTypeTriangle = 0x00000003,
@@ -129,11 +129,12 @@ namespace emfplushelper
{
switch (nEmfLineJoin)
{
- case EmfPlusLineJoinTypeMiter: // fall-through
- case EmfPlusLineJoinTypeMiterClipped: return rendering::PathJoinType::MITER;
- case EmfPlusLineJoinTypeBevel: return rendering::PathJoinType::BEVEL;
- case EmfPlusLineJoinTypeRound: return rendering::PathJoinType::ROUND;
+ case EmfPlusLineJoinTypeMiter: // fall-through
+ case EmfPlusLineJoinTypeMiterClipped: return rendering::PathJoinType::MITER;
+ case EmfPlusLineJoinTypeBevel: return rendering::PathJoinType::BEVEL;
+ case EmfPlusLineJoinTypeRound: return rendering::PathJoinType::ROUND;
}
+
assert(false); // Line Join type isn't in specification.
return 0;
}
@@ -154,12 +155,13 @@ namespace emfplushelper
const float *pPattern = nullptr;
switch (dashStyle)
{
- case EmfPlusLineStyleDash: nLen = SAL_N_ELEMENTS(dash); pPattern = dash; break;
- case EmfPlusLineStyleDot: nLen = SAL_N_ELEMENTS(dot); pPattern = dot; break;
- case EmfPlusLineStyleDashDot: nLen = SAL_N_ELEMENTS(dashdot); pPattern = dashdot; break;
- case EmfPlusLineStyleDashDotDot: nLen = SAL_N_ELEMENTS(dashdotdot); pPattern = dashdotdot; break;
- case EmfPlusLineStyleCustom: nLen = dashPatternLen; pPattern = dashPattern; break;
+ case EmfPlusLineStyleDash: nLen = SAL_N_ELEMENTS(dash); pPattern = dash; break;
+ case EmfPlusLineStyleDot: nLen = SAL_N_ELEMENTS(dot); pPattern = dot; break;
+ case EmfPlusLineStyleDashDot: nLen = SAL_N_ELEMENTS(dashdot); pPattern = dashdot; break;
+ case EmfPlusLineStyleDashDotDot: nLen = SAL_N_ELEMENTS(dashdotdot); pPattern = dashdotdot; break;
+ case EmfPlusLineStyleCustom: nLen = dashPatternLen; pPattern = dashPattern; break;
}
+
if (nLen > 0)
{
uno::Sequence<double> aDashArray(nLen);
@@ -175,15 +177,15 @@ namespace emfplushelper
{
sal_uInt32 graphicsVersion, penType, penDataFlags, penUnit;
int i;
-
s.ReadUInt32(graphicsVersion).ReadUInt32(penType).ReadUInt32(penDataFlags).ReadUInt32(penUnit).ReadFloat(penWidth);
-
SAL_INFO("cppcanvas.emf", "EMF+\tpen");
SAL_INFO("cppcanvas.emf", "EMF+\t graphics version: 0x" << std::hex << graphicsVersion << " type (must be set to zero): " << penType <<
" pen data flags: 0x" << penDataFlags << " unit: " << penUnit << " width: " << std::dec << penWidth);
if (penDataFlags & PenDataTransform)
+ {
rR.readXForm(s, pen_transformation);
+ }
if (penDataFlags & PenDataStartCap)
{
@@ -191,7 +193,9 @@ namespace emfplushelper
SAL_INFO("cppcanvas.emf", "EMF+\t\tstartCap: 0x" << std::hex << startCap);
}
else
+ {
startCap = 0;
+ }
if (penDataFlags & PenDataEndCap)
{
@@ -199,17 +203,27 @@ namespace emfplushelper
SAL_INFO("cppcanvas.emf", "EMF+\t\tendCap: 0x" << std::hex << endCap);
}
else
+ {
endCap = 0;
+ }
if (penDataFlags & PenDataJoin)
+ {
s.ReadInt32(lineJoin);
+ }
else
+ {
lineJoin = 0;
+ }
if (penDataFlags & PenDataMiterLimit)
+ {
s.ReadFloat(mitterLimit);
+ }
else
+ {
mitterLimit = 0;
+ }
if (penDataFlags & PenDataLineStyle)
{
@@ -217,28 +231,41 @@ namespace emfplushelper
SAL_INFO("cppcanvas.emf", "EMF+\t\tdashStyle: 0x" << std::hex << dashStyle);
}
else
+ {
dashStyle = 0;
+ }
if (penDataFlags & PenDataDashedLineCap)
+ {
s.ReadInt32(dashCap);
+ }
else
+ {
dashCap = 0;
+ }
if (penDataFlags & PenDataDashedLineOffset)
+ {
s.ReadFloat(dashOffset);
+ }
else
+ {
dashOffset = 0;
+ }
if (penDataFlags & PenDataDashedLine)
{
dashStyle = EmfPlusLineStyleCustom;
-
s.ReadInt32(dashPatternLen);
SAL_INFO("cppcanvas.emf", "EMF+\t\tdashPatternLen: " << dashPatternLen);
if (dashPatternLen<0 || sal_uInt32(dashPatternLen)>SAL_MAX_INT32 / sizeof(float))
+ {
dashPatternLen = SAL_MAX_INT32 / sizeof(float);
+ }
+
dashPattern = new float[dashPatternLen];
+
for (i = 0; i < dashPatternLen; i++)
{
s.ReadFloat(dashPattern[i]);
@@ -246,23 +273,39 @@ namespace emfplushelper
}
}
else
+ {
dashPatternLen = 0;
+ }
if (penDataFlags & PenDataNonCenter)
+ {
s.ReadInt32(alignment);
+ }
else
+ {
alignment = 0;
+ }
- if (penDataFlags & PenDataCompoundLine) {
+ if (penDataFlags & PenDataCompoundLine)
+ {
s.ReadInt32(compoundArrayLen);
+
if (compoundArrayLen<0 || sal_uInt32(compoundArrayLen)>SAL_MAX_INT32 / sizeof(float))
+ {
compoundArrayLen = SAL_MAX_INT32 / sizeof(float);
+ }
+
compoundArray = new float[compoundArrayLen];
+
for (i = 0; i < compoundArrayLen; i++)
+ {
s.ReadFloat(compoundArray[i]);
+ }
}
else
+ {
compoundArrayLen = 0;
+ }
if (penDataFlags & PenDataCustomStartCap)
{
@@ -277,7 +320,9 @@ namespace emfplushelper
s.Seek(pos + customStartCapLen);
}
else
+ {
customStartCapLen = 0;
+ }
if (penDataFlags & PenDataCustomEndCap)
{
@@ -292,7 +337,9 @@ namespace emfplushelper
s.Seek(pos + customEndCapLen);
}
else
+ {
customEndCapLen = 0;
+ }
EMFPBrush::Read(s, rR);
}
diff --git a/drawinglayer/source/tools/emfpregion.cxx b/drawinglayer/source/tools/emfpregion.cxx
index e4e58e70c683..65fc1e88b1c8 100644
--- a/drawinglayer/source/tools/emfpregion.cxx
+++ b/drawinglayer/source/tools/emfpregion.cxx
@@ -55,7 +55,8 @@ namespace emfplushelper
EMFPRegion::~EMFPRegion()
{
- if (combineMode) {
+ if (combineMode)
+ {
delete[] combineMode;
combineMode = nullptr;
}
@@ -64,19 +65,21 @@ namespace emfplushelper
void EMFPRegion::Read(SvStream& s)
{
sal_uInt32 header;
-
s.ReadUInt32(header).ReadInt32(parts);
-
SAL_INFO("cppcanvas.emf", "EMF+\tregion");
SAL_INFO("cppcanvas.emf", "EMF+\theader: 0x" << std::hex << header << " parts: " << parts << std::dec);
- if (parts) {
+ if (parts)
+ {
if (parts<0 || sal_uInt32(parts)>SAL_MAX_INT32 / sizeof(sal_Int32))
+ {
parts = SAL_MAX_INT32 / sizeof(sal_Int32);
+ }
combineMode = new sal_Int32[parts];
- for (int i = 0; i < parts; i++) {
+ for (int i = 0; i < parts; i++)
+ {
s.ReadInt32(combineMode[i]);
SAL_INFO("cppcanvas.emf", "EMF+\tcombine mode [" << i << "]: 0x" << std::hex << combineMode[i] << std::dec);
}
diff --git a/drawinglayer/source/tools/emfpstringformat.cxx b/drawinglayer/source/tools/emfpstringformat.cxx
index 0af2409fa17f..2256e8035726 100644
--- a/drawinglayer/source/tools/emfpstringformat.cxx
+++ b/drawinglayer/source/tools/emfpstringformat.cxx
@@ -48,9 +48,7 @@ namespace emfplushelper
s.ReadUInt32(stringAlignment).ReadUInt32(lineAlign).ReadUInt32(digitSubstitution).ReadUInt32(digitLanguage);
s.ReadFloat(firstTabOffset).ReadInt32(hotkeyPrefix).ReadFloat(leadingMargin).ReadFloat(trailingMargin).ReadFloat(tracking);
s.ReadInt32(trimming).ReadInt32(tabStopCount).ReadInt32(rangeCount);
-
SAL_WARN_IF((header >> 12) != 0xdbc01, "cppcanvas.emf", "Invalid header - not 0xdbc01");
-
SAL_INFO("cppcanvas.emf", "EMF+\t string format\nEMF+\theader: 0x" << std::hex << (header >> 12) << " version: 0x" << (header & 0x1fff) << " StringFormatFlags: " << std::dec << stringFormatFlags << " Language: " << language);
SAL_INFO("cppcanvas.emf", "EMF+\t StringAlignment: " << stringAlignment << " LineAlign: " << lineAlign << " DigitSubstitution: " << digitSubstitution << " DigitLanguage: " << digitLanguage);
SAL_INFO("cppcanvas.emf", "EMF+\t FirstTabOffset: " << firstTabOffset << " HotkeyPrefix: " << hotkeyPrefix << " LeadingMargin: " << leadingMargin << " TrailingMargin: " << trailingMargin << " Tracking: " << tracking);