summaryrefslogtreecommitdiff
path: root/drawinglayer
diff options
context:
space:
mode:
authorMike Kaganski <mike.kaganski@collabora.com>2020-05-14 14:42:24 +0300
committerMike Kaganski <mike.kaganski@collabora.com>2020-05-29 10:31:21 +0200
commitc8787b8469053bfa1105697d7852dbdac4a184ba (patch)
tree641c6c46ba276bb4998f01f00a2f9f6e58060aa7 /drawinglayer
parent82acd02f1395ea1a1b1e43c6b4beeec93ebf9428 (diff)
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@collabora.com> (cherry picked from commit 9dcbf7b0098e59c22ec17d86c270d610e0416f72) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/95081
Diffstat (limited to 'drawinglayer')
-rw-r--r--drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx97
-rw-r--r--drawinglayer/source/processor2d/vclmetafileprocessor2d.hxx5
2 files changed, 102 insertions, 0 deletions
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;