[Libreoffice-commits] core.git: drawinglayer/source

Caolán McNamara caolanm at redhat.com
Thu Jul 4 07:26:32 PDT 2013


 drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx |   20 ++
 drawinglayer/source/processor2d/vclpixelprocessor2d.cxx    |   18 ++
 drawinglayer/source/processor2d/vclprocessor2d.cxx         |   91 +++++++++++++
 drawinglayer/source/processor2d/vclprocessor2d.hxx         |    1 
 4 files changed, 127 insertions(+), 3 deletions(-)

New commits:
commit 71a049c97049a38f37bf9417d752ca2d8d161a81
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Thu Jul 4 15:21:34 2013 +0100

    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

diff --git a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
index 83238c0..c9f4af1 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 a486dd8..1376a03 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 d1b85ff..1ec9f50 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 f1fccb3..c97222f 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


More information about the Libreoffice-commits mailing list