diff options
author | Bartosz Kosiorek <gang65@poczta.onet.pl> | 2017-05-11 22:58:06 +0200 |
---|---|---|
committer | Bartosz Kosiorek <gang65@poczta.onet.pl> | 2017-05-12 14:38:35 +0200 |
commit | 43f5268c6fa394b0d219f8653ef827bdd531b4e4 (patch) | |
tree | 6a25a0fe8a95c7487d4f859ff18ed9b80fdf0430 | |
parent | 016e4d0e2650b2fb350068d86e8d392a7ef5acb1 (diff) |
EMF+ tdf#31814 Add support of reading EmfPlusBoundaryPointData
The EmfPlusBoundaryPointData object specifies a closed cardinal spline boundary for a gradient brush.
This data is starting point for displaying correctly gradients.
Change-Id: I91b01417c6dc00a04dabfc5a035afe9085999240
Reviewed-on: https://gerrit.libreoffice.org/37519
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Bartosz Kosiorek <gang65@poczta.onet.pl>
-rwxr-xr-x | cppcanvas/source/mtfrenderer/emfpbrush.cxx | 112 | ||||
-rwxr-xr-x | cppcanvas/source/mtfrenderer/emfpbrush.hxx | 9 | ||||
-rw-r--r-- | cppcanvas/source/mtfrenderer/emfplus.cxx | 34 |
3 files changed, 87 insertions, 68 deletions
diff --git a/cppcanvas/source/mtfrenderer/emfpbrush.cxx b/cppcanvas/source/mtfrenderer/emfpbrush.cxx index 72bbc7131d56..051859d33549 100755 --- a/cppcanvas/source/mtfrenderer/emfpbrush.cxx +++ b/cppcanvas/source/mtfrenderer/emfpbrush.cxx @@ -43,16 +43,6 @@ namespace cppcanvas { namespace internal { - - enum EmfPlusBrushType - { - BrushTypeSolidColor = 0x00000000, - BrushTypeHatchFill = 0x00000001, - BrushTypeTextureFill = 0x00000002, - BrushTypePathGradient = 0x00000003, - BrushTypeLinearGradient = 0x00000004 - }; - EMFPBrush::EMFPBrush() : type(0) , additionalFlags(0) @@ -154,7 +144,7 @@ namespace cppcanvas SAL_INFO("cppcanvas.emf", "EMF+\tcenter point: " << areaX << "," << areaY); s.ReadInt32(surroundColorsNumber); - SAL_INFO("cppcanvas.emf", "EMF+\tsurround colors: " << 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); @@ -191,57 +181,73 @@ namespace cppcanvas 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); - SAL_INFO("cppcanvas.emf", "EMF+\tpolygon bounding box: " << aBounds.getMinX() << "," << aBounds.getMinY() << " " << aBounds.getWidth() << "x" << aBounds.getHeight()); + 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()); + } - if (additionalFlags & 0x02) { - SAL_INFO("cppcanvas.emf", "EMF+\tuse transformation"); - ReadXForm(s, brush_transformation); - hasTransformation = true; - SAL_INFO("cppcanvas.emf", - "EMF+\tm11: " << brush_transformation.eM11 << " m12: " << brush_transformation.eM12 << - "\nEMF+\tm21: " << brush_transformation.eM21 << " m22: " << brush_transformation.eM22 << - "\nEMF+\tdx: " << brush_transformation.eDx << " dy: " << brush_transformation.eDy); + if (additionalFlags & 0x02) { + SAL_INFO("cppcanvas.emf", "EMF+\tuse transformation"); + ReadXForm(s, brush_transformation); + hasTransformation = true; + SAL_INFO("cppcanvas.emf", + "EMF+\tm11: " << brush_transformation.eM11 << " m12: " << brush_transformation.eM12 << + "\nEMF+\tm21: " << brush_transformation.eM21 << " m22: " << brush_transformation.eM22 << + "\nEMF+\tdx: " << brush_transformation.eDx << " dy: " << brush_transformation.eDy); + } + 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 & 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]); - } + 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 & 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); } } + break; } case BrushTypeLinearGradient: diff --git a/cppcanvas/source/mtfrenderer/emfpbrush.hxx b/cppcanvas/source/mtfrenderer/emfpbrush.hxx index 88fe7b840961..3d5561b55846 100755 --- a/cppcanvas/source/mtfrenderer/emfpbrush.hxx +++ b/cppcanvas/source/mtfrenderer/emfpbrush.hxx @@ -81,6 +81,15 @@ namespace cppcanvas HatchStyleSolidDiamond = 0x00000034 }; + enum EmfPlusBrushType + { + BrushTypeSolidColor = 0x00000000, + BrushTypeHatchFill = 0x00000001, + BrushTypeTextureFill = 0x00000002, + BrushTypePathGradient = 0x00000003, + BrushTypeLinearGradient = 0x00000004 + }; + struct EMFPPath; struct EMFPBrush : public EMFPObject diff --git a/cppcanvas/source/mtfrenderer/emfplus.cxx b/cppcanvas/source/mtfrenderer/emfplus.cxx index 6b4cf6eb4240..aea0aef58a95 100644 --- a/cppcanvas/source/mtfrenderer/emfplus.cxx +++ b/cppcanvas/source/mtfrenderer/emfplus.cxx @@ -330,7 +330,7 @@ namespace cppcanvas rState.isFillColorSet = false; rState.isLineColorSet = false; - if (brush->type == 1) + if (brush->type == BrushTypeHatchFill) { // EMF+ like hatching is currently not supported. These are just color blends which serve as an approximation for some of them // for the others the hatch "background" color (secondColor in brush) is used. @@ -371,11 +371,16 @@ namespace cppcanvas rState.fillColor = vcl::unotools::colorToDoubleSequence(fillColor, rCanvas->getUNOCanvas()->getDevice()->getDeviceColorSpace()); pPolyAction = ActionSharedPtr ( internal::PolyPolyActionFactory::createPolyPolyAction( localPolygon, rParms.mrCanvas, rState ) ); } - else if (brush->type == 3 || brush->type == 4) + else if (brush->type == BrushTypeTextureFill) { - if (brush->type == 3 && !(brush->additionalFlags & 0x1)) - return; // we are unable to parse these brushes yet - + SAL_WARN("cppcanvas.emf", "EMF+\tTODO: implement BrushTypeTextureFill brush"); + } + else if (brush->type == BrushTypePathGradient || brush->type == BrushTypeLinearGradient) + { + if (brush->type == BrushTypePathGradient && !(brush->additionalFlags & 0x1)) + { + SAL_WARN("cppcanvas.emf", "EMF+\t TODO Verify proper displaying of BrushTypePathGradient with flags: " << std::hex << brush->additionalFlags << std::dec); + } ::basegfx::B2DHomMatrix aTextureTransformation; ::basegfx::B2DHomMatrix aWorldTransformation; ::basegfx::B2DHomMatrix aBaseTransformation; @@ -395,14 +400,13 @@ namespace cppcanvas aBaseTransformation.set (1, 1, aBaseTransform.eM22); aBaseTransformation.set (1, 2, aBaseTransform.eDy); - if (brush->type == 4) { - aTextureTransformation.scale (brush->areaWidth, brush->areaHeight); - aTextureTransformation.translate (brush->areaX, brush->areaY); - } else { + // TODO Verify on example image, why there is shift (-0.5, -0.5) + if (brush->type == BrushTypePathGradient && (brush->additionalFlags & 0x1)) + { aTextureTransformation.translate (-0.5, -0.5); - aTextureTransformation.scale (brush->areaWidth, brush->areaHeight); - aTextureTransformation.translate (brush->areaX,brush->areaY); } + aTextureTransformation.scale (brush->areaWidth, brush->areaHeight); + aTextureTransformation.translate (brush->areaX, brush->areaY); if (brush->hasTransformation) { ::basegfx::B2DHomMatrix aTransformation; @@ -452,7 +456,7 @@ namespace cppcanvas aStops[i] = brush->blendPositions [i]; for (int j = 0; j < length; j++) { - if (brush->type == 4) { + if (brush->type == BrushTypeLinearGradient) { aColor [j] = aStartColor [j]*(1 - brush->blendFactors[i]) + aEndColor [j]*brush->blendFactors[i]; } else aColor [j] = aStartColor [j]*brush->blendFactors[i] + aEndColor [j]*(1 - brush->blendFactors[i]); @@ -467,14 +471,14 @@ namespace cppcanvas for (int i = 0; i < brush->colorblendPoints; i++) { aStops[i] = brush->colorblendPositions [i]; - aColors[(brush->type == 4) ? i : brush->colorblendPoints - 1 - i] = vcl::unotools::colorToDoubleSequence( brush->colorblendColors [i], + aColors[(brush->type == BrushTypeLinearGradient) ? i : brush->colorblendPoints - 1 - i] = vcl::unotools::colorToDoubleSequence( brush->colorblendColors [i], rParms.mrCanvas->getUNOCanvas()->getDevice()->getDeviceColorSpace() ); } } else { aStops[0] = 0.0; aStops[1] = 1.0; - if (brush->type == 4) { + if (brush->type == BrushTypeLinearGradient) { aColors[0] = aStartColor; aColors[1] = aEndColor; } else { @@ -485,7 +489,7 @@ namespace cppcanvas SAL_INFO("cppcanvas.emf", "EMF+\t\tset gradient"); basegfx::B2DRange aBoundsRectangle (0, 0, 1, 1); - if (brush->type == 4) { + if (brush->type == BrushTypeLinearGradient) { aGradientService = "LinearGradient"; aGradInfo = basegfx::tools::createLinearODFGradientInfo( aBoundsRectangle, |