diff options
author | Caolán McNamara <caolanm@redhat.com> | 2013-07-04 15:21:34 +0100 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2013-07-04 15:26:11 +0100 |
commit | 71a049c97049a38f37bf9417d752ca2d8d161a81 (patch) | |
tree | f0ba7e45fef1cc96616df80144db56f209287462 /drawinglayer | |
parent | 743b111cf62ef42ead3d8dd6a4aefbb884ce8ee4 (diff) |
emf+ is not decomposed into primitives, so restore wind and play
regression from f69df53b316b53931e10d35402a70f533399398c
we presumably should process comments and go through their
emfplus contents too, or something of that nature
Change-Id: Ifa8c3f058f0a320057d02b53f5717eaa42e63282
Diffstat (limited to 'drawinglayer')
4 files changed, 127 insertions, 3 deletions
diff --git a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx index 83238c0bce97..c9f4af1c3784 100644 --- a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx +++ b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx @@ -28,6 +28,7 @@ #include <drawinglayer/primitive2d/polygonprimitive2d.hxx> #include <drawinglayer/primitive2d/bitmapprimitive2d.hxx> #include <drawinglayer/primitive2d/maskprimitive2d.hxx> +#include <drawinglayer/primitive2d/metafileprimitive2d.hxx> #include <basegfx/polygon/b2dpolygonclipper.hxx> #include <basegfx/polygon/b2dpolypolygontools.hxx> #include <drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx> @@ -1719,6 +1720,25 @@ namespace drawinglayer break; } + case PRIMITIVE2D_ID_METAFILEPRIMITIVE2D : + { + static bool bUseMetaFilePrimitiveDecomposition(true); + const primitive2d::MetafilePrimitive2D& aMetafile = static_cast< const primitive2d::MetafilePrimitive2D& >(rCandidate); + + if(bUseMetaFilePrimitiveDecomposition && !aMetafile.getMetaFile().GetUseCanvas()) + { + // Use new Metafile decomposition. + // TODO EMF+ stuffed into METACOMMENT support required + process(rCandidate.get2DDecomposition(getViewInformation2D())); + } + else + { + // direct draw of MetaFile, use default processing + RenderMetafilePrimitive2D(aMetafile); + } + + break; + } case PRIMITIVE2D_ID_MASKPRIMITIVE2D : { // mask group. Special handling for MetaFiles. diff --git a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx index a486dd84b578..1376a03ba29f 100644 --- a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx +++ b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx @@ -435,7 +435,7 @@ namespace drawinglayer } case PRIMITIVE2D_ID_METAFILEPRIMITIVE2D : { - // #i98289# + // #i98289# const bool bForceLineSnap(getOptionsDrawinglayer().IsAntiAliasing() && getOptionsDrawinglayer().IsSnapHorVerLinesToDiscrete()); const sal_uInt16 nOldAntiAliase(mpOutputDevice->GetAntialiasing()); @@ -444,8 +444,20 @@ namespace drawinglayer mpOutputDevice->SetAntialiasing(nOldAntiAliase | ANTIALIASING_PIXELSNAPHAIRLINE); } - // use new Metafile decomposition - process(rCandidate.get2DDecomposition(getViewInformation2D())); + const primitive2d::MetafilePrimitive2D& rMetafilePrimitive( static_cast< const primitive2d::MetafilePrimitive2D& >(rCandidate) ); + + static bool bTestMetaFilePrimitiveDecomposition( true ); + if( bTestMetaFilePrimitiveDecomposition && !rMetafilePrimitive.getMetaFile().GetUseCanvas() ) + { + // use new Metafile decomposition + // TODO EMF+ stuffed into METACOMMENT support required + process(rCandidate.get2DDecomposition(getViewInformation2D())); + } + else + { + // direct draw of MetaFile + RenderMetafilePrimitive2D( rMetafilePrimitive ); + } if(bForceLineSnap) { diff --git a/drawinglayer/source/processor2d/vclprocessor2d.cxx b/drawinglayer/source/processor2d/vclprocessor2d.cxx index d1b85ff9618f..1ec9f50dc53e 100644 --- a/drawinglayer/source/processor2d/vclprocessor2d.cxx +++ b/drawinglayer/source/processor2d/vclprocessor2d.cxx @@ -782,6 +782,97 @@ namespace drawinglayer } } + // direct draw of MetaFile + void VclProcessor2D::RenderMetafilePrimitive2D(const primitive2d::MetafilePrimitive2D& rMetaCandidate) + { + // decompose matrix to check for shear, rotate and mirroring + basegfx::B2DHomMatrix aLocalTransform(maCurrentTransformation * rMetaCandidate.getTransform()); + basegfx::B2DVector aScale, aTranslate; + double fRotate, fShearX; + aLocalTransform.decompose(aScale, aTranslate, fRotate, fShearX); + + if(basegfx::fTools::less(aScale.getX(), 0.0) && basegfx::fTools::less(aScale.getY(), 0.0)) + { + // #i102175# handle special case: If scale is negative in (x,y) (3rd quadrant), it can + // be expressed as rotation by PI. This needs to be done for Metafiles since + // these can be rotated, but not really mirrored + aScale = basegfx::absolute(aScale); + fRotate += F_PI; + } + + // get BoundRect + basegfx::B2DRange aOutlineRange(rMetaCandidate.getB2DRange(getViewInformation2D())); + aOutlineRange.transform(maCurrentTransformation); + + // Due to the integer MapModes used from VCL aind inside MetaFiles errors of up to three + // pixels in size may happen. As long as there is no better way (e.g. convert the MetaFile + // to primitives) it is necessary to reduce maximum pixel size by 1 in X and Y and to use + // the inner pixel bounds accordingly (ceil resp. floor). This will also be done for logic + // units e.g. when creating a new MetaFile, but since much huger value ranges are used + // there typically will be okay for this compromize. + Rectangle aDestRectView( + // !!CAUTION!! Here, ceil and floor are exchanged BY PURPOSE, do NOT copy when + // looking for a standard conversion to rectangle (!) + (sal_Int32)ceil(aOutlineRange.getMinX()), (sal_Int32)ceil(aOutlineRange.getMinY()), + (sal_Int32)floor(aOutlineRange.getMaxX()), (sal_Int32)floor(aOutlineRange.getMaxY())); + + // get metafile (copy it) + GDIMetaFile aMetaFile; + + if(maBColorModifierStack.count()) + { + const basegfx::BColor aRGBBaseColor(0, 0, 0); + const basegfx::BColor aRGBColor(maBColorModifierStack.getModifiedColor(aRGBBaseColor)); + aMetaFile = rMetaCandidate.getMetaFile().GetMonochromeMtf(Color(aRGBColor)); + } + else + { + aMetaFile = rMetaCandidate.getMetaFile(); + } + + // rotation + if(!basegfx::fTools::equalZero(fRotate)) + { + // #i103530# + // MetaFile::Rotate has no input parameter check, so the parameter needs to be + // well-aligned to the old range [0..3600] 10th degrees with inverse orientation + sal_Int16 nRotation((sal_Int16)((fRotate / F_PI180) * -10.0)); + + while(nRotation < 0) + nRotation += 3600; + + while(nRotation >= 3600) + nRotation -= 3600; + + aMetaFile.Rotate(nRotation); + } + + // Prepare target output size + Size aDestSize(aDestRectView.GetSize()); + + if(aDestSize.getWidth() && aDestSize.getHeight()) + { + // Get preferred Metafile output size. When it's very equal to the output size, it's probably + // a rounding error somewhere, so correct it to get a 1:1 output without single pixel scalings + // of the Metafile (esp. for contaned Bitmaps, e.g 3D charts) + const Size aPrefSize(mpOutputDevice->LogicToPixel(aMetaFile.GetPrefSize(), aMetaFile.GetPrefMapMode())); + + if(aPrefSize.getWidth() && (aPrefSize.getWidth() - 1 == aDestSize.getWidth() || aPrefSize.getWidth() + 1 == aDestSize.getWidth())) + { + aDestSize.setWidth(aPrefSize.getWidth()); + } + + if(aPrefSize.getHeight() && (aPrefSize.getHeight() - 1 == aDestSize.getHeight() || aPrefSize.getHeight() + 1 == aDestSize.getHeight())) + { + aDestSize.setHeight(aPrefSize.getHeight()); + } + + // paint it + aMetaFile.WindStart(); + aMetaFile.Play(mpOutputDevice, aDestRectView.TopLeft(), aDestSize); + } + } + // mask group. Force output to VDev and create mask from given mask void VclProcessor2D::RenderMaskPrimitive2DPixel(const primitive2d::MaskPrimitive2D& rMaskCandidate) { diff --git a/drawinglayer/source/processor2d/vclprocessor2d.hxx b/drawinglayer/source/processor2d/vclprocessor2d.hxx index f1fccb368abd..c97222f16773 100644 --- a/drawinglayer/source/processor2d/vclprocessor2d.hxx +++ b/drawinglayer/source/processor2d/vclprocessor2d.hxx @@ -106,6 +106,7 @@ namespace drawinglayer void RenderEpsPrimitive2D(const primitive2d::EpsPrimitive2D& rEpsPrimitive2D); void RenderSvgLinearAtomPrimitive2D(const primitive2d::SvgLinearAtomPrimitive2D& rCandidate); void RenderSvgRadialAtomPrimitive2D(const primitive2d::SvgRadialAtomPrimitive2D& rCandidate); + void RenderMetafilePrimitive2D(const primitive2d::MetafilePrimitive2D& rPolygonCandidate); ///////////////////////////////////////////////////////////////////////////// // DrawMode adaption support |