diff options
-rw-r--r-- | drawinglayer/source/processor2d/vclpixelprocessor2d.cxx | 72 | ||||
-rw-r--r-- | drawinglayer/source/processor2d/vclpixelprocessor2d.hxx | 2 | ||||
-rw-r--r-- | vcl/headless/svpgdi.cxx | 49 | ||||
-rw-r--r-- | vcl/inc/headless/svpgdi.hxx | 3 |
4 files changed, 125 insertions, 1 deletions
diff --git a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx index 0cc87e6eaa20..10d8e69e51fa 100644 --- a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx +++ b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx @@ -36,6 +36,7 @@ #include <drawinglayer/primitive2d/controlprimitive2d.hxx> #include <drawinglayer/primitive2d/borderlineprimitive2d.hxx> #include <com/sun/star/awt/XWindow2.hpp> +#include <drawinglayer/primitive2d/fillgradientprimitive2d.hxx> #include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx> #include <drawinglayer/primitive2d/pagepreviewprimitive2d.hxx> #include "helperwrongspellrenderer.hxx" @@ -58,6 +59,13 @@ #include <com/sun/star/table/BorderLineStyle.hpp> +#include <vcl/window.hxx> +#include <vcl/gradient.hxx> +#include <svtools/borderhelper.hxx> +#include <editeng/borderline.hxx> + +#include <com/sun/star/table/BorderLineStyle.hpp> + using namespace com::sun::star; namespace drawinglayer @@ -213,6 +221,30 @@ namespace drawinglayer /* false bBypassAACheck, default*/); } +namespace +{ +GradientStyle convertGradientStyle(drawinglayer::attribute::GradientStyle eGradientStyle) +{ + switch (eGradientStyle) + { + case drawinglayer::attribute::GradientStyle::Axial: + return GradientStyle::Axial; + case drawinglayer::attribute::GradientStyle::Radial: + return GradientStyle::Radial; + case drawinglayer::attribute::GradientStyle::Elliptical: + return GradientStyle::Elliptical; + case drawinglayer::attribute::GradientStyle::Square: + return GradientStyle::Square; + case drawinglayer::attribute::GradientStyle::Rect: + return GradientStyle::Rect; + case drawinglayer::attribute::GradientStyle::Linear: + default: + return GradientStyle::Linear; + } +} + +} // end anonymous namespace + void VclPixelProcessor2D::processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate) { switch(rCandidate.getPrimitive2DID()) @@ -373,6 +405,12 @@ namespace drawinglayer processBorderLinePrimitive2D(static_cast<const drawinglayer::primitive2d::BorderLinePrimitive2D&>(rCandidate)); break; } + case PRIMITIVE2D_ID_FILLGRADIENTPRIMITIVE2D: + { + processFillGradientPrimitive2D( + static_cast<const drawinglayer::primitive2d::FillGradientPrimitive2D&>(rCandidate)); + break; + } default : { SAL_INFO("drawinglayer", "default case for " << drawinglayer::primitive2d::idToString(rCandidate.getPrimitive2DID())); @@ -857,6 +895,40 @@ namespace drawinglayer mpOutputDevice->SetAntialiasing(nOldAntiAliase); } } + + void VclPixelProcessor2D::processFillGradientPrimitive2D( + const primitive2d::FillGradientPrimitive2D& rPrimitive) + { + const attribute::FillGradientAttribute& rFillGradient = rPrimitive.getFillGradient(); + + if (rFillGradient.getSteps() > 0 + || rFillGradient.getStyle() != drawinglayer::attribute::GradientStyle::Linear) + { + process(rPrimitive); + return; + } + + GradientStyle eGradientStyle = convertGradientStyle(rFillGradient.getStyle()); + + basegfx::B2DRange aRange(rPrimitive.getOutputRange()); + aRange.transform(maCurrentTransformation); + + const tools::Rectangle aRectangle( + sal_Int32(std::floor(aRange.getMinX())), sal_Int32(std::floor(aRange.getMinY())), + sal_Int32(std::ceil(aRange.getMaxX())), sal_Int32(std::ceil(aRange.getMaxY()))); + + Gradient aGradient(eGradientStyle, Color(rFillGradient.getStartColor()), + Color(rFillGradient.getEndColor())); + + aGradient.SetAngle(rFillGradient.getAngle() / F_PI1800); + aGradient.SetBorder(rFillGradient.getBorder() * 100); + aGradient.SetOfsX(rFillGradient.getOffsetX() * 100.0); + aGradient.SetOfsY(rFillGradient.getOffsetY() * 100.0); + aGradient.SetSteps(rFillGradient.getSteps()); + + mpOutputDevice->DrawGradient(aRectangle, aGradient); + } + } // end of namespace processor2d } // end of namespace drawinglayer diff --git a/drawinglayer/source/processor2d/vclpixelprocessor2d.hxx b/drawinglayer/source/processor2d/vclpixelprocessor2d.hxx index 1111943a62c8..7fbcd7954dca 100644 --- a/drawinglayer/source/processor2d/vclpixelprocessor2d.hxx +++ b/drawinglayer/source/processor2d/vclpixelprocessor2d.hxx @@ -44,6 +44,7 @@ namespace drawinglayer { namespace primitive2d { class FillHatchPrimitive2D; class BackgroundColorPrimitive2D; class BorderLinePrimitive2D; + class FillGradientPrimitive2D; }} namespace drawinglayer @@ -86,6 +87,7 @@ namespace drawinglayer void processBorderLinePrimitive2D(const drawinglayer::primitive2d::BorderLinePrimitive2D& rBorder); void processInvertPrimitive2D(const primitive2d::BasePrimitive2D& rCandidate); void processMetaFilePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate); + void processFillGradientPrimitive2D(const primitive2d::FillGradientPrimitive2D& rPrimitive); public: /// constructor/destructor diff --git a/vcl/headless/svpgdi.cxx b/vcl/headless/svpgdi.cxx index feaaa671e67e..e196c3b8b2cc 100644 --- a/vcl/headless/svpgdi.cxx +++ b/vcl/headless/svpgdi.cxx @@ -1600,6 +1600,55 @@ bool SvpSalGraphics::drawPolyPolygon( return true; } +bool SvpSalGraphics::drawGradient(const tools::PolyPolygon& rPolyPolygon, const Gradient& rGradient) +{ + cairo_t* cr = getCairoContext(true); + clipRegion(cr); + + basegfx::B2DPolyPolygon aB2DPolyPolygon(rPolyPolygon.getB2DPolyPolygon()); + + for (auto const & rPolygon : aB2DPolyPolygon) + { + basegfx::B2DHomMatrix rObjectToDevice; + AddPolygonToPath(cr, rPolygon, rObjectToDevice, !getAntiAliasB2DDraw(), false); + } + + Gradient aGradient(rGradient); + + tools::Rectangle aInputRect(rPolyPolygon.GetBoundRect()); + tools::Rectangle aBoundRect; + Point aCenter; + + aGradient.SetAngle(aGradient.GetAngle() + 2700); + aGradient.GetBoundRect(aInputRect, aBoundRect, aCenter); + + tools::Polygon aPoly(aBoundRect); + aPoly.Rotate(aCenter, aGradient.GetAngle() % 3600); + + cairo_pattern_t* pattern; + pattern = cairo_pattern_create_linear(aPoly[0].X(), aPoly[0].Y(), aPoly[1].X(), aPoly[1].Y()); + + cairo_pattern_add_color_stop_rgba(pattern, aGradient.GetBorder() / 100.0, + aGradient.GetStartColor().GetRed() / 255.0, + aGradient.GetStartColor().GetGreen() / 255.0, + aGradient.GetStartColor().GetBlue() / 255.0, + 1.0); + + cairo_pattern_add_color_stop_rgba(pattern, 1.0, + aGradient.GetEndColor().GetRed() / 255.0, + aGradient.GetEndColor().GetGreen() / 255.0, + aGradient.GetEndColor().GetBlue() / 255.0, + 1.0); + cairo_set_source(cr, pattern); + + basegfx::B2DRange extents = getClippedFillDamage(cr); + cairo_fill_preserve(cr); + + releaseCairoContext(cr, true, extents); + + return true; +} + bool SvpSalGraphics::implDrawGradient(basegfx::B2DPolyPolygon const & rPolyPolygon, SalGradient const & rGradient) { cairo_t* cr = getCairoContext(true); diff --git a/vcl/inc/headless/svpgdi.hxx b/vcl/inc/headless/svpgdi.hxx index ef64d5b241c9..21c1ebe64a54 100644 --- a/vcl/inc/headless/svpgdi.hxx +++ b/vcl/inc/headless/svpgdi.hxx @@ -234,7 +234,8 @@ public: const sal_uInt32* pPoints, const SalPoint* const* pPtAry, const PolyFlags* const* pFlgAry ) override; - virtual bool drawGradient( const tools::PolyPolygon&, const Gradient& ) override { return false; }; + + virtual bool drawGradient(tools::PolyPolygon const & rPolyPolygon, Gradient const & rGradient) override; virtual bool implDrawGradient(basegfx::B2DPolyPolygon const & rPolyPolygon, SalGradient const & rGradient) override; |