[Libreoffice-commits] core.git: Branch 'libreoffice-7-0' - 2 commits - drawinglayer/source include/drawinglayer

Mike Kaganski (via logerrit) logerrit at kemper.freedesktop.org
Fri May 29 08:31:52 UTC 2020


 drawinglayer/source/primitive2d/glowprimitive2d.cxx        |   16 --
 drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx |   97 +++++++++++++
 drawinglayer/source/processor2d/vclmetafileprocessor2d.hxx |    5 
 drawinglayer/source/processor2d/vclpixelprocessor2d.cxx    |   15 --
 include/drawinglayer/primitive2d/glowprimitive2d.hxx       |    5 
 5 files changed, 109 insertions(+), 29 deletions(-)

New commits:
commit f510bdfa98014ca0ae596dcd0dfd487cfc90f3eb
Author:     Mike Kaganski <mike.kaganski at collabora.com>
AuthorDate: Thu May 28 17:51:15 2020 +0300
Commit:     Mike Kaganski <mike.kaganski at collabora.com>
CommitDate: Fri May 29 10:31:31 2020 +0200

    tdf#101181: use buffer device with alpha in glow effect
    
    Change-Id: Iddc94a5cfdee03befdf245ee086a872f0bfaf7a3
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/95051
    Tested-by: Jenkins
    Tested-by: Mike Kaganski <mike.kaganski at collabora.com>
    Reviewed-by: Mike Kaganski <mike.kaganski at collabora.com>
    (cherry picked from commit c9f4952b98da9adad1b556414c5fcecafedca473)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/95082

diff --git a/drawinglayer/source/primitive2d/glowprimitive2d.cxx b/drawinglayer/source/primitive2d/glowprimitive2d.cxx
index bf49b8e215b5..fb6a599ab4e2 100644
--- a/drawinglayer/source/primitive2d/glowprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/glowprimitive2d.cxx
@@ -60,22 +60,6 @@ GlowPrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation
     return aRetval;
 }
 
-void GlowPrimitive2D::get2DDecomposition(
-    Primitive2DDecompositionVisitor& rVisitor,
-    const geometry::ViewInformation2D& /*rViewInformation*/) const
-{
-    if (getChildren().empty())
-        return;
-
-    // create a modifiedColorPrimitive containing the *black* color and the content. Using black
-    // on white allows creating useful mask in VclPixelProcessor2D::processGlowPrimitive2D.
-    basegfx::BColorModifierSharedPtr aBColorModifier
-        = std::make_shared<basegfx::BColorModifier_replace>(basegfx::BColor());
-
-    const Primitive2DReference xRef(new ModifiedColorPrimitive2D(getChildren(), aBColorModifier));
-    rVisitor.append(xRef);
-}
-
 // provide unique ID
 ImplPrimitive2DIDBlock(GlowPrimitive2D, PRIMITIVE2D_ID_GLOWPRIMITIVE2D)
 
diff --git a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
index 3c1a1087adcf..d4ee5f39b7a0 100644
--- a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
@@ -983,30 +983,29 @@ void VclPixelProcessor2D::processGlowPrimitive2D(const primitive2d::GlowPrimitiv
     // Consider glow transparency (initial transparency near the object edge)
     const sal_uInt8 nTransparency = rCandidate.getGlowColor().GetTransparency();
 
-    impBufferDevice aBufferDevice(*mpOutputDevice, aRange);
+    impBufferDevice aBufferDevice(*mpOutputDevice, aRange, true);
     if (aBufferDevice.isVisible())
     {
         // remember last OutDev and set to content
         OutputDevice* pLastOutputDevice = mpOutputDevice;
         mpOutputDevice = &aBufferDevice.getContent();
-        // Processing will draw whatever geometry on white background, applying *black*
-        // replacement color. The black color replacement is added in 2d decomposition of
-        // glow primitive.
         mpOutputDevice->Erase();
         process(rCandidate);
         const tools::Rectangle aRect(static_cast<long>(std::floor(aRange.getMinX())),
                                      static_cast<long>(std::floor(aRange.getMinY())),
                                      static_cast<long>(std::ceil(aRange.getMaxX())),
                                      static_cast<long>(std::ceil(aRange.getMaxY())));
-        Bitmap bitmap = mpOutputDevice->GetBitmap(aRect.TopLeft(), aRect.GetSize());
+        BitmapEx bmpEx = mpOutputDevice->GetBitmapEx(aRect.TopLeft(), aRect.GetSize());
 
-        AlphaMask mask = ProcessAndBlurAlphaMask(bitmap, fBlurRadius, fBlurRadius, nTransparency);
+        AlphaMask mask
+            = ProcessAndBlurAlphaMask(bmpEx.GetAlpha(), fBlurRadius, fBlurRadius, nTransparency);
 
         // The end result is the bitmap filled with glow color and blurred 8-bit alpha mask
         const basegfx::BColor aGlowColor(
             maBColorModifierStack.getModifiedColor(rCandidate.getGlowColor().getBColor()));
-        bitmap.Erase(Color(aGlowColor));
-        BitmapEx result(bitmap, mask);
+        Bitmap bmp = bmpEx.GetBitmap();
+        bmp.Erase(Color(aGlowColor));
+        BitmapEx result(bmp, mask);
 
         // back to old OutDev
         mpOutputDevice = pLastOutputDevice;
diff --git a/include/drawinglayer/primitive2d/glowprimitive2d.hxx b/include/drawinglayer/primitive2d/glowprimitive2d.hxx
index 5c3029882de2..62a585276b85 100644
--- a/include/drawinglayer/primitive2d/glowprimitive2d.hxx
+++ b/include/drawinglayer/primitive2d/glowprimitive2d.hxx
@@ -52,11 +52,6 @@ public:
     virtual basegfx::B2DRange
     getB2DRange(const geometry::ViewInformation2D& rViewInformation) const override;
 
-    ///  create decomposition
-    virtual void
-    get2DDecomposition(Primitive2DDecompositionVisitor& rVisitor,
-                       const geometry::ViewInformation2D& rViewInformation) const override;
-
     /// provide unique ID
     virtual sal_uInt32 getPrimitive2DID() const override;
 };
commit c8787b8469053bfa1105697d7852dbdac4a184ba
Author:     Mike Kaganski <mike.kaganski at collabora.com>
AuthorDate: Thu May 14 14:42:24 2020 +0300
Commit:     Mike Kaganski <mike.kaganski at collabora.com>
CommitDate: Fri May 29 10:31:21 2020 +0200

    tdf#49247, tdf#101181: output glow and soft edge effects to metafile
    
    Change-Id: Ie660ae372fc0b5f97f685b6d1e82b9e8a12e7e30
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/94192
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kaganski at collabora.com>
    (cherry picked from commit 9dcbf7b0098e59c22ec17d86c270d610e0416f72)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/95081

diff --git a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
index 231bf8bc9259..297fd725c7b7 100644
--- a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
@@ -38,6 +38,8 @@
 #include <vcl/graph.hxx> // for PDFExtOutDevData Graphic support
 #include <toolkit/helper/formpdfexport.hxx> // for PDFExtOutDevData Graphic support
 #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+#include <drawinglayer/primitive2d/glowprimitive2d.hxx>
+#include <drawinglayer/primitive2d/softedgeprimitive2d.hxx>
 #include <drawinglayer/primitive2d/textprimitive2d.hxx>
 #include <drawinglayer/primitive2d/PolyPolygonHairlinePrimitive2D.hxx>
 #include <drawinglayer/primitive2d/PolyPolygonMarkerPrimitive2D.hxx>
@@ -927,6 +929,12 @@ void VclMetafileProcessor2D::processBasePrimitive2D(const primitive2d::BasePrimi
                 static_cast<const primitive2d::ObjectInfoPrimitive2D&>(rCandidate));
             break;
         }
+        case PRIMITIVE2D_ID_GLOWPRIMITIVE2D:
+        case PRIMITIVE2D_ID_SOFTEDGEPRIMITIVE2D:
+        {
+            processPrimitive2DOnPixelProcessor(rCandidate);
+            break;
+        }
         default:
         {
             // process recursively
@@ -2312,6 +2320,95 @@ void VclMetafileProcessor2D::processStructureTagPrimitive2D(
     }
 }
 
+VclPtr<VirtualDevice> VclMetafileProcessor2D::CreateBufferDevice(
+    const basegfx::B2DRange& rCandidateRange, const double fMaxQuadratPixels,
+    geometry::ViewInformation2D& rViewInfo, tools::Rectangle& rRectLogic, Size& rSizePixel)
+{
+    basegfx::B2DRange aViewRange(rCandidateRange);
+    aViewRange.transform(maCurrentTransformation);
+    rRectLogic = tools::Rectangle(static_cast<long>(std::floor(aViewRange.getMinX())),
+                                  static_cast<long>(std::floor(aViewRange.getMinY())),
+                                  static_cast<long>(std::ceil(aViewRange.getMaxX())),
+                                  static_cast<long>(std::ceil(aViewRange.getMaxY())));
+    const tools::Rectangle aRectPixel(mpOutputDevice->LogicToPixel(rRectLogic));
+    rSizePixel = aRectPixel.GetSize();
+    const double fViewVisibleArea(rSizePixel.getWidth() * rSizePixel.getHeight());
+    double fReduceFactor(1.0);
+
+    if (fViewVisibleArea > fMaxQuadratPixels)
+    {
+        // reduce render size
+        fReduceFactor = sqrt(fMaxQuadratPixels / fViewVisibleArea);
+        rSizePixel = Size(basegfx::fround(rSizePixel.getWidth() * fReduceFactor),
+                          basegfx::fround(rSizePixel.getHeight() * fReduceFactor));
+    }
+
+    VclPtrInstance<VirtualDevice> pBufferDevice(DeviceFormat::DEFAULT, DeviceFormat::DEFAULT);
+    if (pBufferDevice->SetOutputSizePixel(rSizePixel))
+    {
+        // create and set MapModes for target devices
+        MapMode aNewMapMode(mpOutputDevice->GetMapMode());
+        aNewMapMode.SetOrigin(Point(-rRectLogic.Left(), -rRectLogic.Top()));
+        pBufferDevice->SetMapMode(aNewMapMode);
+
+        // prepare view transformation for target renderers
+        // ATTENTION! Need to apply another scaling because of the potential DPI differences
+        // between Printer and VDev (mpOutputDevice and pBufferDevice here).
+        // To get the DPI, LogicToPixel from (1,1) from MapUnit::MapInch needs to be used.
+        basegfx::B2DHomMatrix aViewTransform(pBufferDevice->GetViewTransformation());
+        const Size aDPIOld(mpOutputDevice->LogicToPixel(Size(1, 1), MapMode(MapUnit::MapInch)));
+        const Size aDPINew(pBufferDevice->LogicToPixel(Size(1, 1), MapMode(MapUnit::MapInch)));
+        const double fDPIXChange(static_cast<double>(aDPIOld.getWidth())
+                                 / static_cast<double>(aDPINew.getWidth()));
+        const double fDPIYChange(static_cast<double>(aDPIOld.getHeight())
+                                 / static_cast<double>(aDPINew.getHeight()));
+
+        if (!basegfx::fTools::equal(fDPIXChange, 1.0) || !basegfx::fTools::equal(fDPIYChange, 1.0))
+        {
+            aViewTransform.scale(fDPIXChange, fDPIYChange);
+        }
+
+        // also take scaling from Size reduction into account
+        if (!basegfx::fTools::equal(fReduceFactor, 1.0))
+        {
+            aViewTransform.scale(fReduceFactor, fReduceFactor);
+        }
+
+        // create view information and pixel renderer. Reuse known ViewInformation
+        // except new transformation and range
+        rViewInfo = geometry::ViewInformation2D(
+            getViewInformation2D().getObjectTransformation(), aViewTransform, aViewRange,
+            getViewInformation2D().getVisualizedPage(), getViewInformation2D().getViewTime(),
+            getViewInformation2D().getExtendedInformationSequence());
+    }
+    else
+        pBufferDevice.disposeAndClear();
+
+    return std::move(pBufferDevice);
+}
+
+void VclMetafileProcessor2D::processPrimitive2DOnPixelProcessor(
+    const primitive2d::BasePrimitive2D& rCandidate)
+{
+    basegfx::B2DRange aViewRange(rCandidate.getB2DRange(getViewInformation2D()));
+    geometry::ViewInformation2D aViewInfo;
+    tools::Rectangle aRectLogic;
+    Size aSizePixel;
+    auto pBufferDevice(CreateBufferDevice(aViewRange, 500000, aViewInfo, aRectLogic, aSizePixel));
+    if (pBufferDevice)
+    {
+        VclPixelProcessor2D aBufferProcessor(aViewInfo, *pBufferDevice);
+
+        // draw content using pixel renderer
+        primitive2d::Primitive2DReference aRef(
+            &const_cast<primitive2d::BasePrimitive2D&>(rCandidate));
+        aBufferProcessor.process({ aRef });
+        const BitmapEx aBmContent(pBufferDevice->GetBitmapEx(Point(), aSizePixel));
+        mpOutputDevice->DrawBitmapEx(aRectLogic.TopLeft(), aRectLogic.GetSize(), aBmContent);
+        pBufferDevice.disposeAndClear();
+    }
+}
+
 } // end of namespace
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/drawinglayer/source/processor2d/vclmetafileprocessor2d.hxx b/drawinglayer/source/processor2d/vclmetafileprocessor2d.hxx
index 0393039f4455..5febad18c3d7 100644
--- a/drawinglayer/source/processor2d/vclmetafileprocessor2d.hxx
+++ b/drawinglayer/source/processor2d/vclmetafileprocessor2d.hxx
@@ -144,6 +144,11 @@ private:
         const primitive2d::TransparencePrimitive2D& rTransparenceCandidate);
     void processStructureTagPrimitive2D(
         const primitive2d::StructureTagPrimitive2D& rStructureTagCandidate);
+    void processPrimitive2DOnPixelProcessor(const primitive2d::BasePrimitive2D& rCandidate);
+    VclPtr<VirtualDevice> CreateBufferDevice(const basegfx::B2DRange& rCandidateRange,
+                                             const double fMaxQuadratPixels,
+                                             geometry::ViewInformation2D& rViewInfo,
+                                             tools::Rectangle& rRectLogic, Size& rSizePixel);
 
     /// Convert the fWidth to the same space as its coordinates.
     double getTransformedLineWidth(double fWidth) const;


More information about the Libreoffice-commits mailing list