diff options
Diffstat (limited to 'drawinglayer/source/tools')
-rw-r--r-- | drawinglayer/source/tools/emfpbrush.cxx | 450 | ||||
-rw-r--r-- | drawinglayer/source/tools/emfpcustomlinecap.cxx | 7 | ||||
-rw-r--r-- | drawinglayer/source/tools/emfpfont.cxx | 5 | ||||
-rw-r--r-- | drawinglayer/source/tools/emfphelperdata.cxx | 1649 | ||||
-rw-r--r-- | drawinglayer/source/tools/emfphelperdata.hxx | 4 | ||||
-rw-r--r-- | drawinglayer/source/tools/emfpimage.cxx | 21 | ||||
-rw-r--r-- | drawinglayer/source/tools/emfppath.cxx | 79 | ||||
-rw-r--r-- | drawinglayer/source/tools/emfppen.cxx | 77 | ||||
-rw-r--r-- | drawinglayer/source/tools/emfpregion.cxx | 13 | ||||
-rw-r--r-- | drawinglayer/source/tools/emfpstringformat.cxx | 2 |
10 files changed, 1246 insertions, 1061 deletions
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); |