From 37aa7d81aacaae12dfe0fd2ade2779235bbf72f1 Mon Sep 17 00:00:00 2001 From: Armin Le Grand Date: Tue, 16 Oct 2012 08:44:02 +0000 Subject: Resolves: #i121194# Better support for graphic fill styles... which are not bitmaps (svg, metafiles, ..) (cherry picked from commit 7a652a2b2ab5e0d37e32185c8c5fac3af482bb76) Conflicts: drawinglayer/Library_drawinglayer.mk drawinglayer/Package_inc.mk drawinglayer/inc/drawinglayer/attribute/fillgraphicattribute.hxx drawinglayer/inc/drawinglayer/attribute/sdrfillattribute.hxx drawinglayer/inc/drawinglayer/attribute/sdrfillgraphicattribute.hxx drawinglayer/inc/drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx drawinglayer/inc/drawinglayer/primitive2d/fillgraphicprimitive2d.hxx drawinglayer/inc/drawinglayer/primitive2d/polypolygonprimitive2d.hxx drawinglayer/inc/drawinglayer/primitive3d/textureprimitive3d.hxx drawinglayer/inc/drawinglayer/processor2d/vclprocessor2d.hxx drawinglayer/inc/drawinglayer/texture/texture.hxx drawinglayer/inc/drawinglayer/texture/texture3d.hxx drawinglayer/source/attribute/fillbitmapattribute.cxx drawinglayer/source/attribute/sdrfillattribute.cxx drawinglayer/source/attribute/sdrfillgraphicattribute.cxx drawinglayer/source/primitive2d/fillbitmapprimitive2d.cxx drawinglayer/source/primitive2d/graphicprimitive2d.cxx drawinglayer/source/primitive2d/polypolygonprimitive2d.cxx drawinglayer/source/processor2d/canvasprocessor.cxx svx/inc/svx/sdr/primitive2d/sdrattributecreator.hxx svx/source/sdr/contact/objectcontacttools.cxx vcl/inc/vcl/graph.hxx unused file _vclmetafileprocessor2d.cxx deleted, was added by error (cherry picked from commit ed0d53f8283cd3ce579a90b599118884d0db6119) Conflicts: drawinglayer/source/processor2d/_vclmetafileprocessor2d.cxx Corrected canvasProcessor usage (cherry picked from commit 7903c33f31c457eb6ff506958c4233f2a5d39bcf) Conflicts: svx/source/sdr/contact/objectcontacttools.cxx Change-Id: I80008050b98dafc92fde043524843c13a75fe22c d2fa667d7c127b4d735334e56093d1d4553b0a5b e20c60c7d6472da1295a162d9a629be998861f62 --- drawinglayer/Library_drawinglayer.mk | 8 +- .../source/attribute/fillbitmapattribute.cxx | 139 --- .../source/attribute/fillgraphicattribute.cxx | 156 ++++ drawinglayer/source/attribute/sdrfillattribute.cxx | 22 +- .../source/attribute/sdrfillbitmapattribute.cxx | 353 -------- .../source/attribute/sdrfillgraphicattribute.cxx | 305 +++++++ .../source/primitive2d/fillbitmapprimitive2d.cxx | 130 --- .../source/primitive2d/fillgraphicprimitive2d.cxx | 139 +++ .../source/primitive2d/graphicprimitive2d.cxx | 301 +------ .../primitive2d/graphicprimitivehelper2d.cxx | 322 +++++++ .../source/primitive2d/metafileprimitive2d.cxx | 2 +- .../source/primitive2d/patternfillprimitive2d.cxx | 3 +- .../source/primitive2d/polypolygonprimitive2d.cxx | 73 +- .../source/primitive2d/wallpaperprimitive2d.cxx | 27 +- .../source/primitive3d/sdrdecompositiontools3d.cxx | 14 +- .../source/primitive3d/textureprimitive3d.cxx | 6 +- .../source/processor2d/canvasprocessor.cxx | 993 --------------------- .../processor2d/processorfromoutputdevice.cxx | 35 +- .../source/processor2d/vclmetafileprocessor2d.cxx | 73 +- .../source/processor2d/vclpixelprocessor2d.cxx | 10 +- drawinglayer/source/processor2d/vclprocessor2d.cxx | 390 ++++---- .../source/processor3d/defaultprocessor3d.cxx | 34 +- drawinglayer/source/texture/texture.cxx | 129 ++- drawinglayer/source/texture/texture3d.cxx | 217 ++++- .../attribute/fillgraphicattribute.hxx | 85 ++ .../drawinglayer/attribute/sdrfillattribute.hxx | 6 +- .../attribute/sdrfillbitmapattribute.hxx | 96 -- .../attribute/sdrfillgraphicattribute.hxx | 96 ++ .../primitive2d/drawinglayer_primitivetypes2d.hxx | 4 +- .../primitive2d/fillgraphicprimitive2d.hxx | 87 ++ .../primitive2d/graphicprimitivehelper2d.hxx | 54 ++ .../primitive2d/polypolygonprimitive2d.hxx | 18 +- .../primitive3d/textureprimitive3d.hxx | 8 +- .../drawinglayer/processor2d/vclprocessor2d.hxx | 8 +- include/drawinglayer/texture/texture.hxx | 19 +- include/drawinglayer/texture/texture3d.hxx | 58 +- .../svx/sdr/primitive2d/sdrattributecreator.hxx | 4 +- include/vcl/graph.hxx | 8 +- svx/source/sdr/contact/viewobjectcontact.cxx | 6 + svx/source/sdr/primitive2d/sdrattributecreator.cxx | 69 +- .../sdr/primitive2d/sdrdecompositiontools.cxx | 6 +- svx/source/xoutdev/xattrbmp.cxx | 6 + vcl/source/gdi/impgraph.cxx | 6 +- 43 files changed, 2058 insertions(+), 2467 deletions(-) delete mode 100644 drawinglayer/source/attribute/fillbitmapattribute.cxx create mode 100644 drawinglayer/source/attribute/fillgraphicattribute.cxx delete mode 100644 drawinglayer/source/attribute/sdrfillbitmapattribute.cxx create mode 100755 drawinglayer/source/attribute/sdrfillgraphicattribute.cxx delete mode 100644 drawinglayer/source/primitive2d/fillbitmapprimitive2d.cxx create mode 100644 drawinglayer/source/primitive2d/fillgraphicprimitive2d.cxx create mode 100644 drawinglayer/source/primitive2d/graphicprimitivehelper2d.cxx delete mode 100644 drawinglayer/source/processor2d/canvasprocessor.cxx create mode 100644 include/drawinglayer/attribute/fillgraphicattribute.hxx delete mode 100644 include/drawinglayer/attribute/sdrfillbitmapattribute.hxx create mode 100644 include/drawinglayer/attribute/sdrfillgraphicattribute.hxx create mode 100644 include/drawinglayer/primitive2d/fillgraphicprimitive2d.hxx create mode 100644 include/drawinglayer/primitive2d/graphicprimitivehelper2d.hxx diff --git a/drawinglayer/Library_drawinglayer.mk b/drawinglayer/Library_drawinglayer.mk index 96e61de06896..93014a888e8a 100644 --- a/drawinglayer/Library_drawinglayer.mk +++ b/drawinglayer/Library_drawinglayer.mk @@ -41,7 +41,7 @@ $(eval $(call gb_Library_use_libraries,drawinglayer,\ $(eval $(call gb_Library_add_exception_objects,drawinglayer,\ drawinglayer/source/animation/animationtiming \ - drawinglayer/source/attribute/fillbitmapattribute \ + drawinglayer/source/attribute/fillgraphicattribute \ drawinglayer/source/attribute/fillgradientattribute \ drawinglayer/source/attribute/fillhatchattribute \ drawinglayer/source/attribute/fontattribute \ @@ -50,7 +50,7 @@ $(eval $(call gb_Library_add_exception_objects,drawinglayer,\ drawinglayer/source/attribute/materialattribute3d \ drawinglayer/source/attribute/sdrallattribute3d \ drawinglayer/source/attribute/sdrfillattribute \ - drawinglayer/source/attribute/sdrfillbitmapattribute \ + drawinglayer/source/attribute/sdrfillgraphicattribute \ drawinglayer/source/attribute/sdrlightattribute3d \ drawinglayer/source/attribute/sdrlightingattribute3d \ drawinglayer/source/attribute/sdrlineattribute \ @@ -73,9 +73,10 @@ $(eval $(call gb_Library_add_exception_objects,drawinglayer,\ drawinglayer/source/primitive2d/discreteshadowprimitive2d \ drawinglayer/source/primitive2d/embedded3dprimitive2d \ drawinglayer/source/primitive2d/epsprimitive2d \ - drawinglayer/source/primitive2d/fillbitmapprimitive2d \ + drawinglayer/source/primitive2d/fillgraphicprimitive2d \ drawinglayer/source/primitive2d/fillgradientprimitive2d \ drawinglayer/source/primitive2d/fillhatchprimitive2d \ + drawinglayer/source/primitive2d/graphicprimitivehelper2d \ drawinglayer/source/primitive2d/graphicprimitive2d \ drawinglayer/source/primitive2d/gridprimitive2d \ drawinglayer/source/primitive2d/groupprimitive2d \ @@ -133,7 +134,6 @@ $(eval $(call gb_Library_add_exception_objects,drawinglayer,\ drawinglayer/source/primitive3d/textureprimitive3d \ drawinglayer/source/primitive3d/transformprimitive3d \ drawinglayer/source/processor2d/baseprocessor2d \ - drawinglayer/source/processor2d/canvasprocessor \ drawinglayer/source/processor2d/contourextractor2d \ drawinglayer/source/processor2d/getdigitlanguage \ drawinglayer/source/processor2d/helperwrongspellrenderer \ diff --git a/drawinglayer/source/attribute/fillbitmapattribute.cxx b/drawinglayer/source/attribute/fillbitmapattribute.cxx deleted file mode 100644 index e2bedb47d7e3..000000000000 --- a/drawinglayer/source/attribute/fillbitmapattribute.cxx +++ /dev/null @@ -1,139 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include -#include - -////////////////////////////////////////////////////////////////////////////// - -namespace drawinglayer -{ - namespace attribute - { - class ImpFillBitmapAttribute - { - public: - // data definitions - BitmapEx maBitmapEx; - basegfx::B2DPoint maTopLeft; - basegfx::B2DVector maSize; - - // bitfield - unsigned mbTiling : 1; - - ImpFillBitmapAttribute( - const BitmapEx& rBitmapEx, - const basegfx::B2DPoint& rTopLeft, - const basegfx::B2DVector& rSize, - bool bTiling) - : maBitmapEx(rBitmapEx), - maTopLeft(rTopLeft), - maSize(rSize), - mbTiling(bTiling) - { - } - - ImpFillBitmapAttribute() - : maBitmapEx(BitmapEx()), - maTopLeft(basegfx::B2DPoint()), - maSize(basegfx::B2DVector()), - mbTiling(false) - { - } - - bool operator==(const ImpFillBitmapAttribute& rCandidate) const - { - return (maBitmapEx == rCandidate.maBitmapEx - && maTopLeft == rCandidate.maTopLeft - && maSize == rCandidate.maSize - && mbTiling == rCandidate.mbTiling); - } - - // data read access - const BitmapEx& getBitmapEx() const { return maBitmapEx; } - const basegfx::B2DPoint& getTopLeft() const { return maTopLeft; } - const basegfx::B2DVector& getSize() const { return maSize; } - bool getTiling() const { return mbTiling; } - }; - - namespace - { - struct theGlobalDefault : - public rtl::Static< FillBitmapAttribute::ImplType, theGlobalDefault > {}; - } - - FillBitmapAttribute::FillBitmapAttribute( - const BitmapEx& rBitmapEx, - const basegfx::B2DPoint& rTopLeft, - const basegfx::B2DVector& rSize, - bool bTiling) - : mpFillBitmapAttribute(ImpFillBitmapAttribute( - rBitmapEx, rTopLeft, rSize, bTiling)) - { - } - - FillBitmapAttribute::FillBitmapAttribute(const FillBitmapAttribute& rCandidate) - : mpFillBitmapAttribute(rCandidate.mpFillBitmapAttribute) - { - } - - FillBitmapAttribute::~FillBitmapAttribute() - { - } - - bool FillBitmapAttribute::isDefault() const - { - return mpFillBitmapAttribute.same_object(theGlobalDefault::get()); - } - - FillBitmapAttribute& FillBitmapAttribute::operator=(const FillBitmapAttribute& rCandidate) - { - mpFillBitmapAttribute = rCandidate.mpFillBitmapAttribute; - return *this; - } - - bool FillBitmapAttribute::operator==(const FillBitmapAttribute& rCandidate) const - { - return rCandidate.mpFillBitmapAttribute == mpFillBitmapAttribute; - } - - const BitmapEx& FillBitmapAttribute::getBitmapEx() const - { - return mpFillBitmapAttribute->getBitmapEx(); - } - - const basegfx::B2DPoint& FillBitmapAttribute::getTopLeft() const - { - return mpFillBitmapAttribute->getTopLeft(); - } - - const basegfx::B2DVector& FillBitmapAttribute::getSize() const - { - return mpFillBitmapAttribute->getSize(); - } - - bool FillBitmapAttribute::getTiling() const - { - return mpFillBitmapAttribute->getTiling(); - } - - } // end of namespace attribute -} // end of namespace drawinglayer - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/drawinglayer/source/attribute/fillgraphicattribute.cxx b/drawinglayer/source/attribute/fillgraphicattribute.cxx new file mode 100644 index 000000000000..f92b06d5b080 --- /dev/null +++ b/drawinglayer/source/attribute/fillgraphicattribute.cxx @@ -0,0 +1,156 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include +#include + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace attribute + { + class ImpFillGraphicAttribute + { + public: + // data definitions + Graphic maGraphic; + basegfx::B2DRange maGraphicRange; + + // bitfield + unsigned mbTiling : 1; + + // tiling definitions, offsets in X/Y in percent for each 2nd row. + // If both are set, Y is ignored (X has precedence) + double mfOffsetX; + double mfOffsetY; + + ImpFillGraphicAttribute( + const Graphic& rGraphic, + const basegfx::B2DRange& rGraphicRange, + bool bTiling, + double fOffsetX, + double fOffsetY) + : maGraphic(rGraphic), + maGraphicRange(rGraphicRange), + mbTiling(bTiling), + mfOffsetX(fOffsetX), + mfOffsetY(fOffsetY) + { + } + + ImpFillGraphicAttribute() + : maGraphic(Graphic()), + maGraphicRange(basegfx::B2DRange()), + mbTiling(false), + mfOffsetX(0.0), + mfOffsetY(0.0) + { + } + + // data read access + const Graphic& getGraphic() const { return maGraphic; } + const basegfx::B2DRange& getGraphicRange() const { return maGraphicRange; } + bool getTiling() const { return mbTiling; } + double getOffsetX() const { return mfOffsetX; } + double getOffsetY() const { return mfOffsetY; } + + bool operator==(const ImpFillGraphicAttribute& rCandidate) const + { + return (getGraphic() == rCandidate.getGraphic() + && getGraphicRange() == rCandidate.getGraphicRange() + && getTiling() == rCandidate.getTiling() + && getOffsetX() == rCandidate.getOffsetX() + && getOffsetY() == rCandidate.getOffsetY()); + } + }; + + namespace + { + struct theGlobalDefault : + public rtl::Static< FillGraphicAttribute::ImplType, theGlobalDefault > {}; + } + + FillGraphicAttribute::FillGraphicAttribute( + const Graphic& rGraphic, + const basegfx::B2DRange& rGraphicRange, + bool bTiling, + double fOffsetX, + double fOffsetY) + : mpFillGraphicAttribute(ImpFillGraphicAttribute( + rGraphic, rGraphicRange, bTiling, + basegfx::clamp(fOffsetX, 0.0, 1.0), + basegfx::clamp(fOffsetY, 0.0, 1.0))) + { + } + + FillGraphicAttribute::FillGraphicAttribute(const FillGraphicAttribute& rCandidate) + : mpFillGraphicAttribute(rCandidate.mpFillGraphicAttribute) + { + } + + FillGraphicAttribute::~FillGraphicAttribute() + { + } + + bool FillGraphicAttribute::isDefault() const + { + return mpFillGraphicAttribute.same_object(theGlobalDefault::get()); + } + + FillGraphicAttribute& FillGraphicAttribute::operator=(const FillGraphicAttribute& rCandidate) + { + mpFillGraphicAttribute = rCandidate.mpFillGraphicAttribute; + return *this; + } + + bool FillGraphicAttribute::operator==(const FillGraphicAttribute& rCandidate) const + { + return rCandidate.mpFillGraphicAttribute == mpFillGraphicAttribute; + } + + const Graphic& FillGraphicAttribute::getGraphic() const + { + return mpFillGraphicAttribute->getGraphic(); + } + + const basegfx::B2DRange& FillGraphicAttribute::getGraphicRange() const + { + return mpFillGraphicAttribute->getGraphicRange(); + } + + bool FillGraphicAttribute::getTiling() const + { + return mpFillGraphicAttribute->getTiling(); + } + + double FillGraphicAttribute::getOffsetX() const + { + return mpFillGraphicAttribute->getOffsetX(); + } + + double FillGraphicAttribute::getOffsetY() const + { + return mpFillGraphicAttribute->getOffsetY(); + } + + } // end of namespace attribute +} // end of namespace drawinglayer + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/drawinglayer/source/attribute/sdrfillattribute.cxx b/drawinglayer/source/attribute/sdrfillattribute.cxx index 98c6450a7088..f6e07fb898fc 100644 --- a/drawinglayer/source/attribute/sdrfillattribute.cxx +++ b/drawinglayer/source/attribute/sdrfillattribute.cxx @@ -19,7 +19,7 @@ #include #include -#include +#include #include #include #include @@ -38,7 +38,7 @@ namespace drawinglayer basegfx::BColor maColor; // fill color FillGradientAttribute maGradient; // fill gradient (if used) FillHatchAttribute maHatch; // fill hatch (if used) - SdrFillBitmapAttribute maBitmap; // fill bitmap (if used) + SdrFillGraphicAttribute maFillGraphic; // fill graphic (if used) public: ImpSdrFillAttribute( @@ -46,12 +46,12 @@ namespace drawinglayer const basegfx::BColor& rColor, const FillGradientAttribute& rGradient, const FillHatchAttribute& rHatch, - const SdrFillBitmapAttribute& rBitmap) + const SdrFillGraphicAttribute& rFillGraphic) : mfTransparence(fTransparence), maColor(rColor), maGradient(rGradient), maHatch(rHatch), - maBitmap(rBitmap) + maFillGraphic(rFillGraphic) { } @@ -60,7 +60,7 @@ namespace drawinglayer maColor(basegfx::BColor()), maGradient(FillGradientAttribute()), maHatch(FillHatchAttribute()), - maBitmap(SdrFillBitmapAttribute()) + maFillGraphic(SdrFillGraphicAttribute()) { } @@ -69,7 +69,7 @@ namespace drawinglayer const basegfx::BColor& getColor() const { return maColor; } const FillGradientAttribute& getGradient() const { return maGradient; } const FillHatchAttribute& getHatch() const { return maHatch; } - const SdrFillBitmapAttribute& getBitmap() const { return maBitmap; } + const SdrFillGraphicAttribute& getFillGraphic() const { return maFillGraphic; } // compare operator bool operator==(const ImpSdrFillAttribute& rCandidate) const @@ -78,7 +78,7 @@ namespace drawinglayer && getColor() == rCandidate.getColor() && getGradient() == rCandidate.getGradient() && getHatch() == rCandidate.getHatch() - && getBitmap() == rCandidate.getBitmap()); + && getFillGraphic() == rCandidate.getFillGraphic()); } }; @@ -93,9 +93,9 @@ namespace drawinglayer const basegfx::BColor& rColor, const FillGradientAttribute& rGradient, const FillHatchAttribute& rHatch, - const SdrFillBitmapAttribute& rBitmap) + const SdrFillGraphicAttribute& rFillGraphic) : mpSdrFillAttribute(ImpSdrFillAttribute( - fTransparence, rColor, rGradient, rHatch, rBitmap)) + fTransparence, rColor, rGradient, rHatch, rFillGraphic)) { } @@ -149,9 +149,9 @@ namespace drawinglayer return mpSdrFillAttribute->getHatch(); } - const SdrFillBitmapAttribute& SdrFillAttribute::getBitmap() const + const SdrFillGraphicAttribute& SdrFillAttribute::getFillGraphic() const { - return mpSdrFillAttribute->getBitmap(); + return mpSdrFillAttribute->getFillGraphic(); } } // end of namespace attribute } // end of namespace drawinglayer diff --git a/drawinglayer/source/attribute/sdrfillbitmapattribute.cxx b/drawinglayer/source/attribute/sdrfillbitmapattribute.cxx deleted file mode 100644 index b21566f06d81..000000000000 --- a/drawinglayer/source/attribute/sdrfillbitmapattribute.cxx +++ /dev/null @@ -1,353 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include -#include -#include -#include - -////////////////////////////////////////////////////////////////////////////// - -namespace drawinglayer -{ - namespace attribute - { - class ImpSdrFillBitmapAttribute - { - public: - // data definitions - BitmapEx maBitmapEx; - basegfx::B2DVector maSize; - basegfx::B2DVector maOffset; - basegfx::B2DVector maOffsetPosition; - basegfx::B2DVector maRectPoint; - - // bitfield - unsigned mbTiling : 1; - unsigned mbStretch : 1; - unsigned mbLogSize : 1; - - ImpSdrFillBitmapAttribute( - const BitmapEx& rBitmapEx, - const basegfx::B2DVector& rSize, - const basegfx::B2DVector& rOffset, - const basegfx::B2DVector& rOffsetPosition, - const basegfx::B2DVector& rRectPoint, - bool bTiling, - bool bStretch, - bool bLogSize) - : maBitmapEx(rBitmapEx), - maSize(rSize), - maOffset(rOffset), - maOffsetPosition(rOffsetPosition), - maRectPoint(rRectPoint), - mbTiling(bTiling), - mbStretch(bStretch), - mbLogSize(bLogSize) - { - } - - ImpSdrFillBitmapAttribute() - : maBitmapEx(BitmapEx()), - maSize(basegfx::B2DVector()), - maOffset(basegfx::B2DVector()), - maOffsetPosition(basegfx::B2DVector()), - maRectPoint(basegfx::B2DVector()), - mbTiling(false), - mbStretch(false), - mbLogSize(false) - { - } - - // data read access - const BitmapEx& getBitmapEx() const { return maBitmapEx; } - const basegfx::B2DVector& getSize() const { return maSize; } - const basegfx::B2DVector& getOffset() const { return maOffset; } - const basegfx::B2DVector& getOffsetPosition() const { return maOffsetPosition; } - const basegfx::B2DVector& getRectPoint() const { return maRectPoint; } - bool getTiling() const { return mbTiling; } - bool getStretch() const { return mbStretch; } - bool getLogSize() const { return mbLogSize; } - - bool operator==(const ImpSdrFillBitmapAttribute& rCandidate) const - { - return (getBitmapEx() == rCandidate.getBitmapEx() - && getSize() == rCandidate.getSize() - && getOffset() == rCandidate.getOffset() - && getOffsetPosition() == rCandidate.getOffsetPosition() - && getRectPoint() == rCandidate.getRectPoint() - && getTiling() == rCandidate.getTiling() - && getStretch() == rCandidate.getStretch() - && getLogSize() == rCandidate.getLogSize()); - } - }; - - namespace - { - struct theGlobalDefault : - public rtl::Static< SdrFillBitmapAttribute::ImplType, theGlobalDefault > {}; - } - - SdrFillBitmapAttribute::SdrFillBitmapAttribute( - const BitmapEx& rBitmapEx, - const basegfx::B2DVector& rSize, - const basegfx::B2DVector& rOffset, - const basegfx::B2DVector& rOffsetPosition, - const basegfx::B2DVector& rRectPoint, - bool bTiling, - bool bStretch, - bool bLogSize) - : mpSdrFillBitmapAttribute( - ImpSdrFillBitmapAttribute( - rBitmapEx, - rSize, - rOffset, - rOffsetPosition, - rRectPoint, - bTiling, - bStretch, - bLogSize)) - { - } - - SdrFillBitmapAttribute::SdrFillBitmapAttribute() - : mpSdrFillBitmapAttribute(theGlobalDefault::get()) - { - } - - SdrFillBitmapAttribute::SdrFillBitmapAttribute(const SdrFillBitmapAttribute& rCandidate) - : mpSdrFillBitmapAttribute(rCandidate.mpSdrFillBitmapAttribute) - { - } - - SdrFillBitmapAttribute::~SdrFillBitmapAttribute() - { - } - - bool SdrFillBitmapAttribute::isDefault() const - { - return mpSdrFillBitmapAttribute.same_object(theGlobalDefault::get()); - } - - SdrFillBitmapAttribute& SdrFillBitmapAttribute::operator=(const SdrFillBitmapAttribute& rCandidate) - { - mpSdrFillBitmapAttribute = rCandidate.mpSdrFillBitmapAttribute; - return *this; - } - - bool SdrFillBitmapAttribute::operator==(const SdrFillBitmapAttribute& rCandidate) const - { - return rCandidate.mpSdrFillBitmapAttribute == mpSdrFillBitmapAttribute; - } - - const BitmapEx& SdrFillBitmapAttribute::getBitmapEx() const - { - return mpSdrFillBitmapAttribute->getBitmapEx(); - } - - const basegfx::B2DVector& SdrFillBitmapAttribute::getSize() const - { - return mpSdrFillBitmapAttribute->getSize(); - } - - const basegfx::B2DVector& SdrFillBitmapAttribute::getOffset() const - { - return mpSdrFillBitmapAttribute->getOffset(); - } - - const basegfx::B2DVector& SdrFillBitmapAttribute::getOffsetPosition() const - { - return mpSdrFillBitmapAttribute->getOffsetPosition(); - } - - const basegfx::B2DVector& SdrFillBitmapAttribute::getRectPoint() const - { - return mpSdrFillBitmapAttribute->getRectPoint(); - } - - bool SdrFillBitmapAttribute::getTiling() const - { - return mpSdrFillBitmapAttribute->getTiling(); - } - - bool SdrFillBitmapAttribute::getStretch() const - { - return mpSdrFillBitmapAttribute->getStretch(); - } - - FillBitmapAttribute SdrFillBitmapAttribute::getFillBitmapAttribute(const basegfx::B2DRange& rRange) const - { - // get logical size of bitmap (before expanding eventually) - BitmapEx aBitmapEx(getBitmapEx()); - const basegfx::B2DVector aLogicalSize(aBitmapEx.GetPrefSize().getWidth(), aBitmapEx.GetPrefSize().getHeight()); - - // get hor/ver shiftings and apply them eventually to the bitmap, but only - // when tiling is on - bool bExpandWidth(false); - bool bExpandHeight(false); - - if(getTiling()) - { - if(0.0 != getOffset().getX() || 0.0 != getOffset().getY()) - { - const sal_uInt32 nWidth(aBitmapEx.GetSizePixel().getWidth()); - const sal_uInt32 nHeight(aBitmapEx.GetSizePixel().getHeight()); - - if(0.0 != getOffset().getX()) - { - bExpandHeight = true; - const sal_uInt32 nOffset(basegfx::fround(((double)nWidth * getOffset().getX()) / 100.0)); - aBitmapEx.Expand(0L, nHeight); - - const Size aSizeA(nOffset, nHeight); - const Rectangle aDstA(Point(0L, nHeight), aSizeA); - const Rectangle aSrcA(Point(nWidth - nOffset, 0L), aSizeA); - aBitmapEx.CopyPixel(aDstA, aSrcA); - - const Size aSizeB(nWidth - nOffset, nHeight); - const Rectangle aDstB(Point(nOffset, nHeight), aSizeB); - const Rectangle aSrcB(Point(0L, 0L), aSizeB); - aBitmapEx.CopyPixel(aDstB, aSrcB); - } - else - { - bExpandWidth = true; - const sal_uInt32 nOffset(basegfx::fround(((double)nHeight * getOffset().getY()) / 100.0)); - aBitmapEx.Expand(nWidth, 0L); - - const Size aSize(nWidth, nHeight); - const Rectangle aDst(Point(nWidth, 0L), aSize); - const Rectangle aSrc(Point(0L, 0L), aSize); - aBitmapEx.CopyPixel(aDst, aSrc); - - const Size aSizeA(nWidth, nOffset); - const Rectangle aDstA(Point(0L, 0L), aSizeA); - const Rectangle aSrcA(Point(nWidth, nHeight - nOffset), aSizeA); - aBitmapEx.CopyPixel(aDstA, aSrcA); - - const Size aSizeB(nWidth, nHeight - nOffset); - const Rectangle aDstB(Point(0L, nOffset), aSizeB); - const Rectangle aSrcB(Point(nWidth, 0L), aSizeB); - aBitmapEx.CopyPixel(aDstB, aSrcB); - } - } - } - - // init values with defaults - basegfx::B2DPoint aBitmapSize(1.0, 1.0); - basegfx::B2DVector aBitmapTopLeft(0.0, 0.0); - - // are canges needed? - if(getTiling() || !getStretch()) - { - // init values with range sizes - const double fRangeWidth(0.0 != rRange.getWidth() ? rRange.getWidth() : 1.0); - const double fRangeHeight(0.0 != rRange.getHeight() ? rRange.getHeight() : 1.0); - aBitmapSize = basegfx::B2DPoint(fRangeWidth, fRangeHeight); - - // size changes - if(0.0 != getSize().getX()) - { - if(getSize().getX() < 0.0) - { - aBitmapSize.setX(aBitmapSize.getX() * (getSize().getX() * -0.01)); - } - else - { - aBitmapSize.setX(getSize().getX()); - } - } - else - { - aBitmapSize.setX(aLogicalSize.getX()); - } - - if(0.0 != getSize().getY()) - { - if(getSize().getY() < 0.0) - { - aBitmapSize.setY(aBitmapSize.getY() * (getSize().getY() * -0.01)); - } - else - { - aBitmapSize.setY(getSize().getY()); - } - } - else - { - aBitmapSize.setY(aLogicalSize.getY()); - } - - // get values, force to centered if necessary - const basegfx::B2DVector aRectPoint(getTiling() ? getRectPoint() : basegfx::B2DVector(0.0, 0.0)); - - // position changes X - if(0.0 == aRectPoint.getX()) - { - aBitmapTopLeft.setX((fRangeWidth - aBitmapSize.getX()) * 0.5); - } - else if(1.0 == aRectPoint.getX()) - { - aBitmapTopLeft.setX(fRangeWidth - aBitmapSize.getX()); - } - - if(getTiling() && 0.0 != getOffsetPosition().getX()) - { - aBitmapTopLeft.setX(aBitmapTopLeft.getX() + (aBitmapSize.getX() * (getOffsetPosition().getX() * 0.01))); - } - - // position changes Y - if(0.0 == aRectPoint.getY()) - { - aBitmapTopLeft.setY((fRangeHeight - aBitmapSize.getY()) * 0.5); - } - else if(1.0 == aRectPoint.getY()) - { - aBitmapTopLeft.setY(fRangeHeight - aBitmapSize.getY()); - } - - if(getTiling() && 0.0 != getOffsetPosition().getY()) - { - aBitmapTopLeft.setY(aBitmapTopLeft.getY() + (aBitmapSize.getY() * (getOffsetPosition().getY() * 0.01))); - } - - // apply expand - if(bExpandWidth) - { - aBitmapSize.setX(aBitmapSize.getX() * 2.0); - } - - if(bExpandHeight) - { - aBitmapSize.setY(aBitmapSize.getY() * 2.0); - } - - // apply bitmap size scaling to unit rectangle - aBitmapTopLeft.setX(aBitmapTopLeft.getX() / fRangeWidth); - aBitmapTopLeft.setY(aBitmapTopLeft.getY() / fRangeHeight); - aBitmapSize.setX(aBitmapSize.getX() / fRangeWidth); - aBitmapSize.setY(aBitmapSize.getY() / fRangeHeight); - } - - return FillBitmapAttribute(aBitmapEx, aBitmapTopLeft, aBitmapSize, getTiling()); - } - } // end of namespace attribute -} // end of namespace drawinglayer - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/drawinglayer/source/attribute/sdrfillgraphicattribute.cxx b/drawinglayer/source/attribute/sdrfillgraphicattribute.cxx new file mode 100755 index 000000000000..0b1af9cb07d6 --- /dev/null +++ b/drawinglayer/source/attribute/sdrfillgraphicattribute.cxx @@ -0,0 +1,305 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include +#include +#include +#include + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace attribute + { + class ImpSdrFillGraphicAttribute + { + public: + // data definitions + Graphic maFillGraphic; + basegfx::B2DVector maSize; + basegfx::B2DVector maOffset; + basegfx::B2DVector maOffsetPosition; + basegfx::B2DVector maRectPoint; + + // bitfield + unsigned mbTiling : 1; + unsigned mbStretch : 1; + unsigned mbLogSize : 1; + + ImpSdrFillGraphicAttribute( + const Graphic& rFillGraphic, + const basegfx::B2DVector& rSize, + const basegfx::B2DVector& rOffset, + const basegfx::B2DVector& rOffsetPosition, + const basegfx::B2DVector& rRectPoint, + bool bTiling, + bool bStretch, + bool bLogSize) + : maFillGraphic(rFillGraphic), + maSize(rSize), + maOffset(rOffset), + maOffsetPosition(rOffsetPosition), + maRectPoint(rRectPoint), + mbTiling(bTiling), + mbStretch(bStretch), + mbLogSize(bLogSize) + { + } + + ImpSdrFillGraphicAttribute() + : maFillGraphic(Graphic()), + maSize(basegfx::B2DVector()), + maOffset(basegfx::B2DVector()), + maOffsetPosition(basegfx::B2DVector()), + maRectPoint(basegfx::B2DVector()), + mbTiling(false), + mbStretch(false), + mbLogSize(false) + { + } + + // data read access + const Graphic& getFillGraphic() const { return maFillGraphic; } + const basegfx::B2DVector& getSize() const { return maSize; } + const basegfx::B2DVector& getOffset() const { return maOffset; } + const basegfx::B2DVector& getOffsetPosition() const { return maOffsetPosition; } + const basegfx::B2DVector& getRectPoint() const { return maRectPoint; } + bool getTiling() const { return mbTiling; } + bool getStretch() const { return mbStretch; } + bool getLogSize() const { return mbLogSize; } + + bool operator==(const ImpSdrFillGraphicAttribute& rCandidate) const + { + return (getFillGraphic() == rCandidate.getFillGraphic() + && getSize() == rCandidate.getSize() + && getOffset() == rCandidate.getOffset() + && getOffsetPosition() == rCandidate.getOffsetPosition() + && getRectPoint() == rCandidate.getRectPoint() + && getTiling() == rCandidate.getTiling() + && getStretch() == rCandidate.getStretch() + && getLogSize() == rCandidate.getLogSize()); + } + }; + + namespace + { + struct theGlobalDefault : + public rtl::Static< SdrFillGraphicAttribute::ImplType, theGlobalDefault > {}; + } + + SdrFillGraphicAttribute::SdrFillGraphicAttribute( + const Graphic& rFillGraphic, + const basegfx::B2DVector& rSize, + const basegfx::B2DVector& rOffset, + const basegfx::B2DVector& rOffsetPosition, + const basegfx::B2DVector& rRectPoint, + bool bTiling, + bool bStretch, + bool bLogSize) + : mpSdrFillGraphicAttribute( + ImpSdrFillGraphicAttribute( + rFillGraphic, + rSize, + rOffset, + rOffsetPosition, + rRectPoint, + bTiling, + bStretch, + bLogSize)) + { + } + + SdrFillGraphicAttribute::SdrFillGraphicAttribute() + : mpSdrFillGraphicAttribute(theGlobalDefault::get()) + { + } + + SdrFillGraphicAttribute::SdrFillGraphicAttribute(const SdrFillGraphicAttribute& rCandidate) + : mpSdrFillGraphicAttribute(rCandidate.mpSdrFillGraphicAttribute) + { + } + + SdrFillGraphicAttribute::~SdrFillGraphicAttribute() + { + } + + bool SdrFillGraphicAttribute::isDefault() const + { + return mpSdrFillGraphicAttribute.same_object(theGlobalDefault::get()); + } + + SdrFillGraphicAttribute& SdrFillGraphicAttribute::operator=(const SdrFillGraphicAttribute& rCandidate) + { + mpSdrFillGraphicAttribute = rCandidate.mpSdrFillGraphicAttribute; + return *this; + } + + bool SdrFillGraphicAttribute::operator==(const SdrFillGraphicAttribute& rCandidate) const + { + return rCandidate.mpSdrFillGraphicAttribute == mpSdrFillGraphicAttribute; + } + + const Graphic& SdrFillGraphicAttribute::getFillGraphic() const + { + return mpSdrFillGraphicAttribute->getFillGraphic(); + } + + const basegfx::B2DVector& SdrFillGraphicAttribute::getSize() const + { + return mpSdrFillGraphicAttribute->getSize(); + } + + const basegfx::B2DVector& SdrFillGraphicAttribute::getOffset() const + { + return mpSdrFillGraphicAttribute->getOffset(); + } + + const basegfx::B2DVector& SdrFillGraphicAttribute::getOffsetPosition() const + { + return mpSdrFillGraphicAttribute->getOffsetPosition(); + } + + const basegfx::B2DVector& SdrFillGraphicAttribute::getRectPoint() const + { + return mpSdrFillGraphicAttribute->getRectPoint(); + } + + bool SdrFillGraphicAttribute::getTiling() const + { + return mpSdrFillGraphicAttribute->getTiling(); + } + + bool SdrFillGraphicAttribute::getStretch() const + { + return mpSdrFillGraphicAttribute->getStretch(); + } + + bool SdrFillGraphicAttribute::getLogSize() const + { + return mpSdrFillGraphicAttribute->getLogSize(); + } + + FillGraphicAttribute SdrFillGraphicAttribute::createFillGraphicAttribute(const basegfx::B2DRange& rRange) const + { + // get logical size of bitmap (before expanding eventually) + Graphic aGraphic(getFillGraphic()); + const basegfx::B2DVector aLogicalSize(aGraphic.GetPrefSize().getWidth(), aGraphic.GetPrefSize().getHeight()); + + // init values with defaults + basegfx::B2DPoint aBitmapSize(1.0, 1.0); + basegfx::B2DVector aBitmapTopLeft(0.0, 0.0); + + // are changes needed? + if(getTiling() || !getStretch()) + { + // init values with range sizes + const double fRangeWidth(0.0 != rRange.getWidth() ? rRange.getWidth() : 1.0); + const double fRangeHeight(0.0 != rRange.getHeight() ? rRange.getHeight() : 1.0); + aBitmapSize = basegfx::B2DPoint(fRangeWidth, fRangeHeight); + + // size changes + if(0.0 != getSize().getX()) + { + if(getSize().getX() < 0.0) + { + aBitmapSize.setX(aBitmapSize.getX() * (getSize().getX() * -0.01)); + } + else + { + aBitmapSize.setX(getSize().getX()); + } + } + else + { + aBitmapSize.setX(aLogicalSize.getX()); + } + + if(0.0 != getSize().getY()) + { + if(getSize().getY() < 0.0) + { + aBitmapSize.setY(aBitmapSize.getY() * (getSize().getY() * -0.01)); + } + else + { + aBitmapSize.setY(getSize().getY()); + } + } + else + { + aBitmapSize.setY(aLogicalSize.getY()); + } + + // get values, force to centered if necessary + const basegfx::B2DVector aRectPoint(getTiling() ? getRectPoint() : basegfx::B2DVector(0.0, 0.0)); + + // position changes X + if(0.0 == aRectPoint.getX()) + { + aBitmapTopLeft.setX((fRangeWidth - aBitmapSize.getX()) * 0.5); + } + else if(1.0 == aRectPoint.getX()) + { + aBitmapTopLeft.setX(fRangeWidth - aBitmapSize.getX()); + } + + if(getTiling() && 0.0 != getOffsetPosition().getX()) + { + aBitmapTopLeft.setX(aBitmapTopLeft.getX() + (aBitmapSize.getX() * (getOffsetPosition().getX() * 0.01))); + } + + // position changes Y + if(0.0 == aRectPoint.getY()) + { + aBitmapTopLeft.setY((fRangeHeight - aBitmapSize.getY()) * 0.5); + } + else if(1.0 == aRectPoint.getY()) + { + aBitmapTopLeft.setY(fRangeHeight - aBitmapSize.getY()); + } + + if(getTiling() && 0.0 != getOffsetPosition().getY()) + { + aBitmapTopLeft.setY(aBitmapTopLeft.getY() + (aBitmapSize.getY() * (getOffsetPosition().getY() * 0.01))); + } + + // apply bitmap size scaling to unit rectangle + aBitmapTopLeft.setX(aBitmapTopLeft.getX() / fRangeWidth); + aBitmapTopLeft.setY(aBitmapTopLeft.getY() / fRangeHeight); + aBitmapSize.setX(aBitmapSize.getX() / fRangeWidth); + aBitmapSize.setY(aBitmapSize.getY() / fRangeHeight); + } + + // get offset in percent + const double fOffsetX(basegfx::clamp(getOffset().getX() * 0.01, 0.0, 1.0)); + const double fOffsetY(basegfx::clamp(getOffset().getY() * 0.01, 0.0, 1.0)); + + // create FillGraphicAttribute + return FillGraphicAttribute( + aGraphic, + basegfx::B2DRange(aBitmapTopLeft, aBitmapTopLeft + aBitmapSize), + getTiling(), + fOffsetX, + fOffsetY); + } + } // end of namespace attribute +} // end of namespace drawinglayer + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/drawinglayer/source/primitive2d/fillbitmapprimitive2d.cxx b/drawinglayer/source/primitive2d/fillbitmapprimitive2d.cxx deleted file mode 100644 index 1c997aec97b0..000000000000 --- a/drawinglayer/source/primitive2d/fillbitmapprimitive2d.cxx +++ /dev/null @@ -1,130 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include -#include -#include -#include -#include -#include -#include - -////////////////////////////////////////////////////////////////////////////// - -using namespace com::sun::star; - -////////////////////////////////////////////////////////////////////////////// - -namespace drawinglayer -{ - namespace primitive2d - { - Primitive2DSequence FillBitmapPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const - { - Primitive2DSequence aRetval; - - if(!getFillBitmap().isDefault()) - { - const Size aTileSizePixel(getFillBitmap().getBitmapEx().GetSizePixel()); - - // is there a tile with some size at all? - if(aTileSizePixel.getWidth() && aTileSizePixel.getHeight()) - { - if(getFillBitmap().getTiling()) - { - // get object range and create tiling matrices - ::std::vector< basegfx::B2DHomMatrix > aMatrices; - texture::GeoTexSvxTiled aTiling(getFillBitmap().getTopLeft(), getFillBitmap().getSize()); - aTiling.appendTransformations(aMatrices); - - // resize result - aRetval.realloc(aMatrices.size()); - - // create one primitive for each matrix - for(sal_uInt32 a(0L); a < aMatrices.size(); a++) - { - basegfx::B2DHomMatrix aNewMatrix = aMatrices[a]; - aNewMatrix *= getTransformation(); - - // create bitmap primitive and add to result - const Primitive2DReference xRef( - new BitmapPrimitive2D(getFillBitmap().getBitmapEx(), aNewMatrix)); - - aRetval[a] = xRef; - } - } - else - { - // create new object transform - basegfx::B2DHomMatrix aObjectTransform; - aObjectTransform.set(0L, 0L, getFillBitmap().getSize().getX()); - aObjectTransform.set(1L, 1L, getFillBitmap().getSize().getY()); - aObjectTransform.set(0L, 2L, getFillBitmap().getTopLeft().getX()); - aObjectTransform.set(1L, 2L, getFillBitmap().getTopLeft().getY()); - aObjectTransform *= getTransformation(); - - // create bitmap primitive and add exclusive to decomposition (hand over ownership) - const Primitive2DReference xRef( - new BitmapPrimitive2D(getFillBitmap().getBitmapEx(), aObjectTransform)); - - aRetval = Primitive2DSequence(&xRef, 1L); - } - } - } - - return aRetval; - } - - FillBitmapPrimitive2D::FillBitmapPrimitive2D( - const basegfx::B2DHomMatrix& rTransformation, - const attribute::FillBitmapAttribute& rFillBitmap) - : BufferedDecompositionPrimitive2D(), - maTransformation(rTransformation), - maFillBitmap(rFillBitmap) - { - } - - bool FillBitmapPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const - { - if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) - { - const FillBitmapPrimitive2D& rCompare = static_cast< const FillBitmapPrimitive2D& >(rPrimitive); - - return (getTransformation() == rCompare.getTransformation() - && getFillBitmap() == rCompare.getFillBitmap()); - } - - return false; - } - - basegfx::B2DRange FillBitmapPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const - { - // return range of it - basegfx::B2DPolygon aPolygon(basegfx::tools::createUnitPolygon()); - aPolygon.transform(getTransformation()); - return basegfx::tools::getRange(aPolygon); - } - - // provide unique ID - ImplPrimitive2DIDBlock(FillBitmapPrimitive2D, PRIMITIVE2D_ID_FILLBITMAPPRIMITIVE2D) - - } // end of namespace primitive2d -} // end of namespace drawinglayer - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/drawinglayer/source/primitive2d/fillgraphicprimitive2d.cxx b/drawinglayer/source/primitive2d/fillgraphicprimitive2d.cxx new file mode 100644 index 000000000000..9eff7b9afabe --- /dev/null +++ b/drawinglayer/source/primitive2d/fillgraphicprimitive2d.cxx @@ -0,0 +1,139 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +////////////////////////////////////////////////////////////////////////////// + +using namespace com::sun::star; + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + Primitive2DSequence FillGraphicPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const + { + Primitive2DSequence aRetval; + const attribute::FillGraphicAttribute& rAttribute = getFillGraphic(); + + if(!rAttribute.isDefault()) + { + const Graphic& rGraphic = rAttribute.getGraphic(); + + if(GRAPHIC_BITMAP == rGraphic.GetType() || GRAPHIC_GDIMETAFILE == rGraphic.GetType()) + { + const Size aSize(rGraphic.GetPrefSize()); + + if(aSize.Width() && aSize.Height()) + { + // we have a graphic (bitmap or metafile) with some size + if(rAttribute.getTiling()) + { + // get object range and create tiling matrices + ::std::vector< basegfx::B2DHomMatrix > aMatrices; + texture::GeoTexSvxTiled aTiling( + rAttribute.getGraphicRange(), + rAttribute.getOffsetX(), + rAttribute.getOffsetY()); + + // get matrices and realloc retval + aTiling.appendTransformations(aMatrices); + aRetval.realloc(aMatrices.size()); + + // prepare content primitive + const Primitive2DSequence xSeq = create2DDecompositionOfGraphic( + rGraphic, + basegfx::B2DHomMatrix()); + + for(sal_uInt32 a(0); a < aMatrices.size(); a++) + { + aRetval[a] = new TransformPrimitive2D( + getTransformation() * aMatrices[a], + xSeq); + } + } + else + { + // add graphic without tiling + const basegfx::B2DHomMatrix aObjectTransform( + getTransformation() * basegfx::tools::createScaleTranslateB2DHomMatrix( + rAttribute.getGraphicRange().getRange(), + rAttribute.getGraphicRange().getMinimum())); + + aRetval = create2DDecompositionOfGraphic( + rGraphic, + aObjectTransform); + } + } + } + } + + return aRetval; + } + + FillGraphicPrimitive2D::FillGraphicPrimitive2D( + const basegfx::B2DHomMatrix& rTransformation, + const attribute::FillGraphicAttribute& rFillGraphic) + : BufferedDecompositionPrimitive2D(), + maTransformation(rTransformation), + maFillGraphic(rFillGraphic) + { + } + + bool FillGraphicPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const + { + if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) + { + const FillGraphicPrimitive2D& rCompare = static_cast< const FillGraphicPrimitive2D& >(rPrimitive); + + return (getTransformation() == rCompare.getTransformation() + && getFillGraphic() == rCompare.getFillGraphic()); + } + + return false; + } + + basegfx::B2DRange FillGraphicPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const + { + // return range of it + basegfx::B2DPolygon aPolygon(basegfx::tools::createUnitPolygon()); + aPolygon.transform(getTransformation()); + + return basegfx::tools::getRange(aPolygon); + } + + // provide unique ID + ImplPrimitive2DIDBlock(FillGraphicPrimitive2D, PRIMITIVE2D_ID_FILLGRAPHICPRIMITIVE2D) + + } // end of namespace primitive2d +} // end of namespace drawinglayer + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/drawinglayer/source/primitive2d/graphicprimitive2d.cxx b/drawinglayer/source/primitive2d/graphicprimitive2d.cxx index 00a248525b6c..865d52f0cd86 100644 --- a/drawinglayer/source/primitive2d/graphicprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/graphicprimitive2d.cxx @@ -18,178 +18,13 @@ */ #include -#include -#include -#include -#include -#include -#include -#include #include #include #include - -////////////////////////////////////////////////////////////////////////////// -// helper class for animated graphics - -#include -#include -#include +#include +#include #include -#include - -////////////////////////////////////////////////////////////////////////////// -// includes for testing MetafilePrimitive2D::create2DDecomposition - -////////////////////////////////////////////////////////////////////////////// - -namespace -{ - struct animationStep - { - BitmapEx maBitmapEx; - sal_uInt32 mnTime; - }; - - class animatedBitmapExPreparator - { - ::Animation maAnimation; - ::std::vector< animationStep > maSteps; - - sal_uInt32 generateStepTime(sal_uInt32 nIndex) const; - - public: - explicit animatedBitmapExPreparator(const Graphic& rGraphic); - - sal_uInt32 count() const { return maSteps.size(); } - sal_uInt32 loopCount() const { return (sal_uInt32)maAnimation.GetLoopCount(); } - sal_uInt32 stepTime(sal_uInt32 a) const { return maSteps[a].mnTime; } - const BitmapEx& stepBitmapEx(sal_uInt32 a) const { return maSteps[a].maBitmapEx; } - }; - - sal_uInt32 animatedBitmapExPreparator::generateStepTime(sal_uInt32 nIndex) const - { - const AnimationBitmap& rAnimBitmap = maAnimation.Get(sal_uInt16(nIndex)); - sal_uInt32 nWaitTime(rAnimBitmap.nWait * 10); - - // #115934# - // Take care of special value for MultiPage TIFFs. ATM these shall just - // show their first page. Later we will offer some switching when object - // is selected. - if(ANIMATION_TIMEOUT_ON_CLICK == rAnimBitmap.nWait) - { - // ATM the huge value would block the timer, so - // use a long time to show first page (whole day) - nWaitTime = 100 * 60 * 60 * 24; - } - - // Bad trap: There are animated gifs with no set WaitTime (!). - // In that case use a default value. - if(0L == nWaitTime) - { - nWaitTime = 100L; - } - - return nWaitTime; - } - - animatedBitmapExPreparator::animatedBitmapExPreparator(const Graphic& rGraphic) - : maAnimation(rGraphic.GetAnimation()) - { - OSL_ENSURE(GRAPHIC_BITMAP == rGraphic.GetType() && rGraphic.IsAnimated(), "animatedBitmapExPreparator: graphic is not animated (!)"); - - // #128539# secure access to Animation, looks like there exist animated GIFs out there - // with a step count of zero - if(maAnimation.Count()) - { - VirtualDevice aVirtualDevice(*Application::GetDefaultDevice()); - VirtualDevice aVirtualDeviceMask(*Application::GetDefaultDevice(), 1L); - - // Prepare VirtualDevices and their states - aVirtualDevice.EnableMapMode(sal_False); - aVirtualDeviceMask.EnableMapMode(sal_False); - aVirtualDevice.SetOutputSizePixel(maAnimation.GetDisplaySizePixel()); - aVirtualDeviceMask.SetOutputSizePixel(maAnimation.GetDisplaySizePixel()); - aVirtualDevice.Erase(); - aVirtualDeviceMask.Erase(); - - for(sal_uInt16 a(0L); a < maAnimation.Count(); a++) - { - animationStep aNextStep; - aNextStep.mnTime = generateStepTime(a); - - // prepare step - const AnimationBitmap& rAnimBitmap = maAnimation.Get(sal_uInt16(a)); - - switch(rAnimBitmap.eDisposal) - { - case DISPOSE_NOT: - { - aVirtualDevice.DrawBitmapEx(rAnimBitmap.aPosPix, rAnimBitmap.aBmpEx); - Bitmap aMask = rAnimBitmap.aBmpEx.GetMask(); - - if(aMask.IsEmpty()) - { - const Point aEmpty; - const Rectangle aRect(aEmpty, aVirtualDeviceMask.GetOutputSizePixel()); - const Wallpaper aWallpaper(COL_BLACK); - aVirtualDeviceMask.DrawWallpaper(aRect, aWallpaper); - } - else - { - BitmapEx aExpandVisibilityMask = BitmapEx(aMask, aMask); - aVirtualDeviceMask.DrawBitmapEx(rAnimBitmap.aPosPix, aExpandVisibilityMask); - } - - break; - } - case DISPOSE_BACK: - { - // #i70772# react on no mask, for primitives, too. - const Bitmap aMask(rAnimBitmap.aBmpEx.GetMask()); - const Bitmap aContent(rAnimBitmap.aBmpEx.GetBitmap()); - - aVirtualDeviceMask.Erase(); - aVirtualDevice.DrawBitmap(rAnimBitmap.aPosPix, aContent); - - if(aMask.IsEmpty()) - { - const Rectangle aRect(rAnimBitmap.aPosPix, aContent.GetSizePixel()); - aVirtualDeviceMask.SetFillColor(COL_BLACK); - aVirtualDeviceMask.SetLineColor(); - aVirtualDeviceMask.DrawRect(aRect); - } - else - { - aVirtualDeviceMask.DrawBitmap(rAnimBitmap.aPosPix, aMask); - } - - break; - } - case DISPOSE_FULL: - { - aVirtualDevice.DrawBitmapEx(rAnimBitmap.aPosPix, rAnimBitmap.aBmpEx); - break; - } - case DISPOSE_PREVIOUS : - { - aVirtualDevice.DrawBitmapEx(rAnimBitmap.aPosPix, rAnimBitmap.aBmpEx); - aVirtualDeviceMask.DrawBitmap(rAnimBitmap.aPosPix, rAnimBitmap.aBmpEx.GetMask()); - break; - } - } - - // create BitmapEx - Bitmap aMainBitmap = aVirtualDevice.GetBitmap(Point(), aVirtualDevice.GetOutputSizePixel()); - Bitmap aMaskBitmap = aVirtualDeviceMask.GetBitmap(Point(), aVirtualDeviceMask.GetOutputSizePixel()); - aNextStep.maBitmapEx = BitmapEx(aMainBitmap, aMaskBitmap); - - // add to vector - maSteps.push_back(aNextStep); - } - } - } -} // end of anonymous namespace +#include ////////////////////////////////////////////////////////////////////////////// @@ -204,8 +39,6 @@ namespace drawinglayer if(255L != getGraphicAttr().GetTransparency()) { - Primitive2DReference xPrimitive; - // do not apply mirroring from GraphicAttr to the Metafile by calling // GetTransformedGraphic, this will try to mirror the Metafile using Scale() // at the Metafile. This again calls Scale at the single MetaFile actions, @@ -241,111 +74,11 @@ namespace drawinglayer const GraphicObject& rGraphicObject = getGraphicObject(); const Graphic aTransformedGraphic(rGraphicObject.GetTransformedGraphic(&aSuppressGraphicAttr)); - switch(aTransformedGraphic.GetType()) - { - case GRAPHIC_BITMAP : - { - if(aTransformedGraphic.IsAnimated()) - { - // prepare animation data - animatedBitmapExPreparator aData(aTransformedGraphic); - - if(aData.count()) - { - // create sub-primitives for animated bitmap and the needed animation loop - animation::AnimationEntryLoop aAnimationLoop(aData.loopCount() ? aData.loopCount() : 0xffff); - Primitive2DSequence aBitmapPrimitives(aData.count()); - - for(sal_uInt32 a(0L); a < aData.count(); a++) - { - animation::AnimationEntryFixed aTime((double)aData.stepTime(a), (double)a / (double)aData.count()); - aAnimationLoop.append(aTime); - const Primitive2DReference xRef(new BitmapPrimitive2D(aData.stepBitmapEx(a), aTransform)); - aBitmapPrimitives[a] = xRef; - } - - // prepare animation list - animation::AnimationEntryList aAnimationList; - aAnimationList.append(aAnimationLoop); - - // create and add animated switch primitive - xPrimitive = Primitive2DReference(new AnimatedSwitchPrimitive2D(aAnimationList, aBitmapPrimitives, false)); - } - } - else if(aTransformedGraphic.getSvgData().get()) - { - // embedded Svg fill, create embed transform - const basegfx::B2DRange& rSvgRange(aTransformedGraphic.getSvgData()->getRange()); - - if(basegfx::fTools::more(rSvgRange.getWidth(), 0.0) && basegfx::fTools::more(rSvgRange.getHeight(), 0.0)) - { - // translate back to origin, scale to unit coordinates - basegfx::B2DHomMatrix aEmbedSvg( - basegfx::tools::createTranslateB2DHomMatrix( - -rSvgRange.getMinX(), - -rSvgRange.getMinY())); - - aEmbedSvg.scale( - 1.0 / rSvgRange.getWidth(), - 1.0 / rSvgRange.getHeight()); - - // apply created object transformation - aEmbedSvg = aTransform * aEmbedSvg; - - // add Svg primitives embedded - xPrimitive = new TransformPrimitive2D( - aEmbedSvg, - aTransformedGraphic.getSvgData()->getPrimitive2DSequence()); - } - } - else - { - xPrimitive = Primitive2DReference(new BitmapPrimitive2D(aTransformedGraphic.GetBitmapEx(), aTransform)); - } - - break; - } - - case GRAPHIC_GDIMETAFILE : - { - // create MetafilePrimitive2D - const GDIMetaFile& rMetafile = aTransformedGraphic.GetGDIMetaFile(); + aRetval = create2DDecompositionOfGraphic( + aTransformedGraphic, + aTransform); - xPrimitive = Primitive2DReference( - new MetafilePrimitive2D( aTransform, rMetafile ) ); - - // #i100357# find out if clipping is needed for this primitive. Unfortunately, - // there exist Metafiles who's content is bigger than the proposed PrefSize set - // at them. This is an error, but we need to work around this - const Size aMetaFilePrefSize(rMetafile.GetPrefSize()); - const Size aMetaFileRealSize( - const_cast< GDIMetaFile& >(rMetafile).GetBoundRect( - *Application::GetDefaultDevice()).GetSize()); - - if(aMetaFileRealSize.getWidth() > aMetaFilePrefSize.getWidth() - || aMetaFileRealSize.getHeight() > aMetaFilePrefSize.getHeight()) - { - // clipping needed. Embed to MaskPrimitive2D. Create childs and mask polygon - const primitive2d::Primitive2DSequence aChildContent(&xPrimitive, 1); - basegfx::B2DPolygon aMaskPolygon(basegfx::tools::createUnitPolygon()); - aMaskPolygon.transform(aTransform); - - xPrimitive = Primitive2DReference( - new MaskPrimitive2D( - basegfx::B2DPolyPolygon(aMaskPolygon), - aChildContent)); - } - break; - } - - default: - { - // nothing to create - break; - } - } - - if(xPrimitive.is()) + if(aRetval.getLength()) { // check for cropping if(getGraphicAttr().IsCropped()) @@ -385,17 +118,17 @@ namespace drawinglayer } // embed content in cropPrimitive - xPrimitive = new CropPrimitive2D( - Primitive2DSequence(&xPrimitive, 1), - aTransform, - getGraphicAttr().GetLeftCrop() * fFactorX, - getGraphicAttr().GetTopCrop() * fFactorY, - getGraphicAttr().GetRightCrop() * fFactorX, - getGraphicAttr().GetBottomCrop() * fFactorY); + Primitive2DReference xPrimitive( + new CropPrimitive2D( + aRetval, + aTransform, + getGraphicAttr().GetLeftCrop() * fFactorX, + getGraphicAttr().GetTopCrop() * fFactorY, + getGraphicAttr().GetRightCrop() * fFactorX, + getGraphicAttr().GetBottomCrop() * fFactorY)); + + aRetval = Primitive2DSequence(&xPrimitive, 1); } - - // add to decomposition - appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, xPrimitive); } } diff --git a/drawinglayer/source/primitive2d/graphicprimitivehelper2d.cxx b/drawinglayer/source/primitive2d/graphicprimitivehelper2d.cxx new file mode 100644 index 000000000000..ee51ea0f1309 --- /dev/null +++ b/drawinglayer/source/primitive2d/graphicprimitivehelper2d.cxx @@ -0,0 +1,322 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +////////////////////////////////////////////////////////////////////////////// +// helper class for animated graphics + +#include +#include +#include +#include +#include + +////////////////////////////////////////////////////////////////////////////// +// includes for testing MetafilePrimitive2D::create2DDecomposition + +////////////////////////////////////////////////////////////////////////////// + +namespace +{ + struct animationStep + { + BitmapEx maBitmapEx; + sal_uInt32 mnTime; + }; + + class animatedBitmapExPreparator + { + ::Animation maAnimation; + ::std::vector< animationStep > maSteps; + + sal_uInt32 generateStepTime(sal_uInt32 nIndex) const; + + public: + animatedBitmapExPreparator(const Graphic& rGraphic); + + sal_uInt32 count() const { return maSteps.size(); } + sal_uInt32 loopCount() const { return (sal_uInt32)maAnimation.GetLoopCount(); } + sal_uInt32 stepTime(sal_uInt32 a) const { return maSteps[a].mnTime; } + const BitmapEx& stepBitmapEx(sal_uInt32 a) const { return maSteps[a].maBitmapEx; } + }; + + sal_uInt32 animatedBitmapExPreparator::generateStepTime(sal_uInt32 nIndex) const + { + const AnimationBitmap& rAnimBitmap = maAnimation.Get(sal_uInt16(nIndex)); + sal_uInt32 nWaitTime(rAnimBitmap.nWait * 10); + + // #115934# + // Take care of special value for MultiPage TIFFs. ATM these shall just + // show their first page. Later we will offer some switching when object + // is selected. + if(ANIMATION_TIMEOUT_ON_CLICK == rAnimBitmap.nWait) + { + // ATM the huge value would block the timer, so + // use a long time to show first page (whole day) + nWaitTime = 100 * 60 * 60 * 24; + } + + // Bad trap: There are animated gifs with no set WaitTime (!). + // In that case use a default value. + if(0L == nWaitTime) + { + nWaitTime = 100L; + } + + return nWaitTime; + } + + animatedBitmapExPreparator::animatedBitmapExPreparator(const Graphic& rGraphic) + : maAnimation(rGraphic.GetAnimation()) + { + OSL_ENSURE(GRAPHIC_BITMAP == rGraphic.GetType() && rGraphic.IsAnimated(), "animatedBitmapExPreparator: graphic is not animated (!)"); + + // #128539# secure access to Animation, looks like there exist animated GIFs out there + // with a step count of zero + if(maAnimation.Count()) + { + VirtualDevice aVirtualDevice(*Application::GetDefaultDevice()); + VirtualDevice aVirtualDeviceMask(*Application::GetDefaultDevice(), 1L); + + // Prepare VirtualDevices and their states + aVirtualDevice.EnableMapMode(sal_False); + aVirtualDeviceMask.EnableMapMode(sal_False); + aVirtualDevice.SetOutputSizePixel(maAnimation.GetDisplaySizePixel()); + aVirtualDeviceMask.SetOutputSizePixel(maAnimation.GetDisplaySizePixel()); + aVirtualDevice.Erase(); + aVirtualDeviceMask.Erase(); + + for(sal_uInt16 a(0L); a < maAnimation.Count(); a++) + { + animationStep aNextStep; + aNextStep.mnTime = generateStepTime(a); + + // prepare step + const AnimationBitmap& rAnimBitmap = maAnimation.Get(sal_uInt16(a)); + + switch(rAnimBitmap.eDisposal) + { + case DISPOSE_NOT: + { + aVirtualDevice.DrawBitmapEx(rAnimBitmap.aPosPix, rAnimBitmap.aBmpEx); + Bitmap aMask = rAnimBitmap.aBmpEx.GetMask(); + + if(aMask.IsEmpty()) + { + const Point aEmpty; + const Rectangle aRect(aEmpty, aVirtualDeviceMask.GetOutputSizePixel()); + const Wallpaper aWallpaper(COL_BLACK); + aVirtualDeviceMask.DrawWallpaper(aRect, aWallpaper); + } + else + { + BitmapEx aExpandVisibilityMask = BitmapEx(aMask, aMask); + aVirtualDeviceMask.DrawBitmapEx(rAnimBitmap.aPosPix, aExpandVisibilityMask); + } + + break; + } + case DISPOSE_BACK: + { + // #i70772# react on no mask, for primitives, too. + const Bitmap aMask(rAnimBitmap.aBmpEx.GetMask()); + const Bitmap aContent(rAnimBitmap.aBmpEx.GetBitmap()); + + aVirtualDeviceMask.Erase(); + aVirtualDevice.DrawBitmap(rAnimBitmap.aPosPix, aContent); + + if(aMask.IsEmpty()) + { + const Rectangle aRect(rAnimBitmap.aPosPix, aContent.GetSizePixel()); + aVirtualDeviceMask.SetFillColor(COL_BLACK); + aVirtualDeviceMask.SetLineColor(); + aVirtualDeviceMask.DrawRect(aRect); + } + else + { + aVirtualDeviceMask.DrawBitmap(rAnimBitmap.aPosPix, aMask); + } + + break; + } + case DISPOSE_FULL: + { + aVirtualDevice.DrawBitmapEx(rAnimBitmap.aPosPix, rAnimBitmap.aBmpEx); + break; + } + case DISPOSE_PREVIOUS : + { + aVirtualDevice.DrawBitmapEx(rAnimBitmap.aPosPix, rAnimBitmap.aBmpEx); + aVirtualDeviceMask.DrawBitmap(rAnimBitmap.aPosPix, rAnimBitmap.aBmpEx.GetMask()); + break; + } + } + + // create BitmapEx + Bitmap aMainBitmap = aVirtualDevice.GetBitmap(Point(), aVirtualDevice.GetOutputSizePixel()); + Bitmap aMaskBitmap = aVirtualDeviceMask.GetBitmap(Point(), aVirtualDeviceMask.GetOutputSizePixel()); + aNextStep.maBitmapEx = BitmapEx(aMainBitmap, aMaskBitmap); + + // add to vector + maSteps.push_back(aNextStep); + } + } + } +} // end of anonymous namespace + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + Primitive2DSequence create2DDecompositionOfGraphic( + const Graphic& rGraphic, + const basegfx::B2DHomMatrix& rTransform) + { + Primitive2DSequence aRetval; + + switch(rGraphic.GetType()) + { + case GRAPHIC_BITMAP : + { + if(rGraphic.IsAnimated()) + { + // prepare animation data + animatedBitmapExPreparator aData(rGraphic); + + if(aData.count()) + { + // create sub-primitives for animated bitmap and the needed animation loop + animation::AnimationEntryLoop aAnimationLoop(aData.loopCount() ? aData.loopCount() : 0xffff); + Primitive2DSequence aBitmapPrimitives(aData.count()); + + for(sal_uInt32 a(0); a < aData.count(); a++) + { + animation::AnimationEntryFixed aTime((double)aData.stepTime(a), (double)a / (double)aData.count()); + aAnimationLoop.append(aTime); + aBitmapPrimitives[a] = new BitmapPrimitive2D( + aData.stepBitmapEx(a), + rTransform); + } + + // prepare animation list + animation::AnimationEntryList aAnimationList; + aAnimationList.append(aAnimationLoop); + + // create and add animated switch primitive + aRetval.realloc(1); + aRetval[0] = new AnimatedSwitchPrimitive2D( + aAnimationList, + aBitmapPrimitives, + false); + } + } + else if(rGraphic.getSvgData().get()) + { + // embedded Svg fill, create embed transform + const basegfx::B2DRange& rSvgRange(rGraphic.getSvgData()->getRange()); + + if(basegfx::fTools::more(rSvgRange.getWidth(), 0.0) && basegfx::fTools::more(rSvgRange.getHeight(), 0.0)) + { + // translate back to origin, scale to unit coordinates + basegfx::B2DHomMatrix aEmbedSvg( + basegfx::tools::createTranslateB2DHomMatrix( + -rSvgRange.getMinX(), + -rSvgRange.getMinY())); + + aEmbedSvg.scale( + 1.0 / rSvgRange.getWidth(), + 1.0 / rSvgRange.getHeight()); + + // apply created object transformation + aEmbedSvg = rTransform * aEmbedSvg; + + // add Svg primitives embedded + aRetval.realloc(1); + aRetval[0] = new TransformPrimitive2D( + aEmbedSvg, + rGraphic.getSvgData()->getPrimitive2DSequence()); + } + } + else + { + aRetval.realloc(1); + aRetval[0] = new BitmapPrimitive2D( + rGraphic.GetBitmapEx(), + rTransform); + } + + break; + } + + case GRAPHIC_GDIMETAFILE : + { + // create MetafilePrimitive2D + const GDIMetaFile& rMetafile = rGraphic.GetGDIMetaFile(); + + aRetval.realloc(1); + aRetval[0] = new MetafilePrimitive2D( + rTransform, + rMetafile); + + // #i100357# find out if clipping is needed for this primitive. Unfortunately, + // there exist Metafiles who's content is bigger than the proposed PrefSize set + // at them. This is an error, but we need to work around this + const Size aMetaFilePrefSize(rMetafile.GetPrefSize()); + const Size aMetaFileRealSize( + const_cast< GDIMetaFile& >(rMetafile).GetBoundRect( + *Application::GetDefaultDevice()).GetSize()); + + if(aMetaFileRealSize.getWidth() > aMetaFilePrefSize.getWidth() + || aMetaFileRealSize.getHeight() > aMetaFilePrefSize.getHeight()) + { + // clipping needed. Embed to MaskPrimitive2D. Create childs and mask polygon + basegfx::B2DPolygon aMaskPolygon(basegfx::tools::createUnitPolygon()); + aMaskPolygon.transform(rTransform); + + aRetval[0] = new MaskPrimitive2D( + basegfx::B2DPolyPolygon(aMaskPolygon), + aRetval); + } + break; + } + + default: + { + // nothing to create + break; + } + } + + return aRetval; + } + } // end of namespace primitive2d +} // end of namespace drawinglayer + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/drawinglayer/source/primitive2d/metafileprimitive2d.cxx b/drawinglayer/source/primitive2d/metafileprimitive2d.cxx index 3df6c70025ec..4a0719ea0ffb 100644 --- a/drawinglayer/source/primitive2d/metafileprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/metafileprimitive2d.cxx @@ -43,7 +43,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drawinglayer/source/primitive2d/patternfillprimitive2d.cxx b/drawinglayer/source/primitive2d/patternfillprimitive2d.cxx index 79b67050a23f..0518f0e45ff5 100644 --- a/drawinglayer/source/primitive2d/patternfillprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/patternfillprimitive2d.cxx @@ -50,7 +50,8 @@ namespace drawinglayer { // create tiling matrices ::std::vector< basegfx::B2DHomMatrix > aMatrices; - texture::GeoTexSvxTiled aTiling(getReferenceRange().getMinimum(), getReferenceRange().getRange()); + texture::GeoTexSvxTiled aTiling(getReferenceRange()); + aTiling.appendTransformations(aMatrices); // check if content needs to be clipped diff --git a/drawinglayer/source/primitive2d/polypolygonprimitive2d.cxx b/drawinglayer/source/primitive2d/polypolygonprimitive2d.cxx index 95b5aac96977..7cd2a1a1b50c 100644 --- a/drawinglayer/source/primitive2d/polypolygonprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/polypolygonprimitive2d.cxx @@ -24,9 +24,11 @@ #include #include #include -#include +#include #include #include +#include +#include ////////////////////////////////////////////////////////////////////////////// @@ -404,56 +406,69 @@ namespace drawinglayer { namespace primitive2d { - Primitive2DSequence PolyPolygonBitmapPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const + Primitive2DSequence PolyPolygonGraphicPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const { - if(!getFillBitmap().isDefault()) + if(!getFillGraphic().isDefault()) { - // create SubSequence with FillBitmapPrimitive2D - const basegfx::B2DRange aPolyPolygonRange(getB2DPolyPolygon().getB2DRange()); - basegfx::B2DHomMatrix aNewObjectTransform; - aNewObjectTransform.set(0, 0, aPolyPolygonRange.getWidth()); - aNewObjectTransform.set(1, 1, aPolyPolygonRange.getHeight()); - aNewObjectTransform.set(0, 2, aPolyPolygonRange.getMinX()); - aNewObjectTransform.set(1, 2, aPolyPolygonRange.getMinY()); - FillBitmapPrimitive2D* pNewBitmap = new FillBitmapPrimitive2D(aNewObjectTransform, getFillBitmap()); - const Primitive2DReference xSubRef(pNewBitmap); - const Primitive2DSequence aSubSequence(&xSubRef, 1L); + const Graphic& rGraphic = getFillGraphic().getGraphic(); + const GraphicType aType(rGraphic.GetType()); - // create mask primitive - MaskPrimitive2D* pNewMask = new MaskPrimitive2D(getB2DPolyPolygon(), aSubSequence); - const Primitive2DReference xRef(pNewMask); - - return Primitive2DSequence(&xRef, 1); - } - else - { - return Primitive2DSequence(); + // is there a bitmap or a metafile (do we have content)? + if(GRAPHIC_BITMAP == aType || GRAPHIC_GDIMETAFILE == aType) + { + const Size aPrefSize(rGraphic.GetPrefSize()); + + // does content have a size? + if(aPrefSize.Width() && aPrefSize.Height()) + { + // create SubSequence with FillGraphicPrimitive2D based on polygon range + const basegfx::B2DRange aPolyPolygonRange(getB2DPolyPolygon().getB2DRange()); + const basegfx::B2DHomMatrix aNewObjectTransform( + basegfx::tools::createScaleTranslateB2DHomMatrix( + aPolyPolygonRange.getRange(), + aPolyPolygonRange.getMinimum())); + const Primitive2DReference xSubRef( + new FillGraphicPrimitive2D( + aNewObjectTransform, + getFillGraphic())); + + // embed to mask primitive + const Primitive2DReference xRef( + new MaskPrimitive2D( + getB2DPolyPolygon(), + Primitive2DSequence(&xSubRef, 1))); + + return Primitive2DSequence(&xRef, 1); + } + } } + + return Primitive2DSequence(); } - PolyPolygonBitmapPrimitive2D::PolyPolygonBitmapPrimitive2D( + PolyPolygonGraphicPrimitive2D::PolyPolygonGraphicPrimitive2D( const basegfx::B2DPolyPolygon& rPolyPolygon, - const attribute::FillBitmapAttribute& rFillBitmap) + const attribute::FillGraphicAttribute& rFillGraphic) : BufferedDecompositionPrimitive2D(), maPolyPolygon(rPolyPolygon), - maFillBitmap(rFillBitmap) + maFillGraphic(rFillGraphic) { } - bool PolyPolygonBitmapPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const + bool PolyPolygonGraphicPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const { if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) { - const PolyPolygonBitmapPrimitive2D& rCompare = (PolyPolygonBitmapPrimitive2D&)rPrimitive; + const PolyPolygonGraphicPrimitive2D& rCompare = (PolyPolygonGraphicPrimitive2D&)rPrimitive; - return (getFillBitmap() == rCompare.getFillBitmap()); + return (getFillGraphic() == rCompare.getFillGraphic()); } return false; } // provide unique ID - ImplPrimitive2DIDBlock(PolyPolygonBitmapPrimitive2D, PRIMITIVE2D_ID_POLYPOLYGONBITMAPPRIMITIVE2D) + ImplPrimitive2DIDBlock(PolyPolygonGraphicPrimitive2D, PRIMITIVE2D_ID_POLYPOLYGONGRAPHICPRIMITIVE2D) } // end of namespace primitive2d } // end of namespace drawinglayer diff --git a/drawinglayer/source/primitive2d/wallpaperprimitive2d.cxx b/drawinglayer/source/primitive2d/wallpaperprimitive2d.cxx index bf3c5f81bde1..61bafc650ca2 100644 --- a/drawinglayer/source/primitive2d/wallpaperprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/wallpaperprimitive2d.cxx @@ -20,10 +20,12 @@ #include #include #include -#include +#include #include #include #include +#include +#include ////////////////////////////////////////////////////////////////////////////// @@ -175,26 +177,23 @@ namespace drawinglayer aRelativeTopLeft.setY(0.5 - aRelativeSize.getY()); } - // prepare FillBitmapAttribute - const attribute::FillBitmapAttribute aFillBitmapAttribute( - getBitmapEx(), - aRelativeTopLeft, - aRelativeSize, + // prepare FillGraphicAttribute + const attribute::FillGraphicAttribute aFillGraphicAttribute( + Graphic(getBitmapEx()), + basegfx::B2DRange(aRelativeTopLeft, aRelativeTopLeft+ aRelativeSize), true); // create ObjectTransform - basegfx::B2DHomMatrix aObjectTransform; - - aObjectTransform.set(0, 0, getLocalObjectRange().getWidth()); - aObjectTransform.set(1, 1, getLocalObjectRange().getHeight()); - aObjectTransform.set(0, 2, getLocalObjectRange().getMinX()); - aObjectTransform.set(1, 2, getLocalObjectRange().getMinY()); + const basegfx::B2DHomMatrix aObjectTransform( + basegfx::tools::createScaleTranslateB2DHomMatrix( + getLocalObjectRange().getRange(), + getLocalObjectRange().getMinimum())); // create FillBitmapPrimitive const drawinglayer::primitive2d::Primitive2DReference xFillBitmap( - new drawinglayer::primitive2d::FillBitmapPrimitive2D( + new drawinglayer::primitive2d::FillGraphicPrimitive2D( aObjectTransform, - aFillBitmapAttribute)); + aFillGraphicAttribute)); aRetval = Primitive2DSequence(&xFillBitmap, 1); // always embed tiled fill to clipping diff --git a/drawinglayer/source/primitive3d/sdrdecompositiontools3d.cxx b/drawinglayer/source/primitive3d/sdrdecompositiontools3d.cxx index 108445052843..667fae1f576e 100644 --- a/drawinglayer/source/primitive3d/sdrdecompositiontools3d.cxx +++ b/drawinglayer/source/primitive3d/sdrdecompositiontools3d.cxx @@ -25,8 +25,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include @@ -201,7 +201,7 @@ namespace drawinglayer // look for and evtl. build texture sub-group primitive if(!rFill.getGradient().isDefault() || !rFill.getHatch().isDefault() - || !rFill.getBitmap().isDefault()) + || !rFill.getFillGraphic().isDefault()) { bool bModulate(::com::sun::star::drawing::TextureMode_MODULATE == aSdr3DObjectAttribute.getTextureMode()); bool bFilter(aSdr3DObjectAttribute.getTextureFilter()); @@ -227,13 +227,13 @@ namespace drawinglayer bModulate, bFilter); } - else // if(!rFill.getBitmap().isDefault()) + else // if(!rFill.getFillGraphic().isDefault()) { // create bitmapTexture3D with sublist, add to local aRetval - basegfx::B2DRange aTexRange(0.0, 0.0, rTextureSize.getX(), rTextureSize.getY()); + const basegfx::B2DRange aTexRange(0.0, 0.0, rTextureSize.getX(), rTextureSize.getY()); pNewTexturePrimitive3D = new BitmapTexturePrimitive3D( - rFill.getBitmap().getFillBitmapAttribute(aTexRange), + rFill.getFillGraphic().createFillGraphicAttribute(aTexRange), aRetval, rTextureSize, bModulate, @@ -306,7 +306,7 @@ namespace drawinglayer basegfx::BColor(), attribute::FillGradientAttribute(), attribute::FillHatchAttribute(), - attribute::SdrFillBitmapAttribute()); + attribute::SdrFillGraphicAttribute()); const Primitive3DReference aHidden( new HiddenGeometryPrimitive3D( diff --git a/drawinglayer/source/primitive3d/textureprimitive3d.cxx b/drawinglayer/source/primitive3d/textureprimitive3d.cxx index edd220ca7386..4f4569edd730 100644 --- a/drawinglayer/source/primitive3d/textureprimitive3d.cxx +++ b/drawinglayer/source/primitive3d/textureprimitive3d.cxx @@ -160,12 +160,12 @@ namespace drawinglayer namespace primitive3d { BitmapTexturePrimitive3D::BitmapTexturePrimitive3D( - const attribute::FillBitmapAttribute& rFillBitmapAttribute, + const attribute::FillGraphicAttribute& rFillGraphicAttribute, const Primitive3DSequence& rChildren, const basegfx::B2DVector& rTextureSize, bool bModulate, bool bFilter) : TexturePrimitive3D(rChildren, rTextureSize, bModulate, bFilter), - maFillBitmapAttribute(rFillBitmapAttribute) + maFillGraphicAttribute(rFillGraphicAttribute) { } @@ -175,7 +175,7 @@ namespace drawinglayer { const BitmapTexturePrimitive3D& rCompare = (BitmapTexturePrimitive3D&)rPrimitive; - return (getFillBitmapAttribute() == rCompare.getFillBitmapAttribute()); + return (getFillGraphicAttribute() == rCompare.getFillGraphicAttribute()); } return false; diff --git a/drawinglayer/source/processor2d/canvasprocessor.cxx b/drawinglayer/source/processor2d/canvasprocessor.cxx deleted file mode 100644 index b8d260aa941e..000000000000 --- a/drawinglayer/source/processor2d/canvasprocessor.cxx +++ /dev/null @@ -1,993 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "getdigitlanguage.hxx" - -////////////////////////////////////////////////////////////////////////////// - -using namespace com::sun::star; - -////////////////////////////////////////////////////////////////////////////// - -namespace drawinglayer -{ - namespace processor2d - { - ////////////////////////////////////////////////////////////////////////////// - // single primitive renderers - - void canvasProcessor2D::impRenderMaskPrimitive2D(const primitive2d::MaskPrimitive2D& rMaskCandidate) - { - const primitive2d::Primitive2DSequence& rChildren = rMaskCandidate.getChildren(); - static bool bUseMaskBitmapMethod(true); - - if(rChildren.hasElements()) - { - basegfx::B2DPolyPolygon aMask(rMaskCandidate.getMask()); - - if(!aMask.count()) - { - // no mask, no clipping. recursively paint content - process(rChildren); - } - else - { - // there are principally two methods for implementing the mask primitive. One - // is to set a clip polygon at the canvas, the other is to create and use a - // transparence-using XBitmap for content and draw the mask as transparence. Both have their - // advantages and disadvantages, so here are both with a bool allowing simple - // change - if(bUseMaskBitmapMethod) - { - // get logic range of transparent part, clip with ViewRange - basegfx::B2DRange aLogicRange(aMask.getB2DRange()); - - if(!getViewInformation2D().getViewport().isEmpty()) - { - aLogicRange.intersect(getViewInformation2D().getViewport()); - } - - if(!aLogicRange.isEmpty()) - { - // get discrete range of transparent part - basegfx::B2DRange aDiscreteRange(aLogicRange); - aDiscreteRange.transform(getViewInformation2D().getObjectToViewTransformation()); - - // expand to next covering discrete values (pixel bounds) - aDiscreteRange.expand(basegfx::B2DTuple(floor(aDiscreteRange.getMinX()), floor(aDiscreteRange.getMinY()))); - aDiscreteRange.expand(basegfx::B2DTuple(ceil(aDiscreteRange.getMaxX()), ceil(aDiscreteRange.getMaxY()))); - - // use VCL-based buffer device - impBufferDevice aBufferDevice(*mpOutputDevice, aDiscreteRange, false); - - if(aBufferDevice.isVisible()) - { - // remember current OutDev, Canvas and ViewInformation - OutputDevice* pLastOutputDevice = mpOutputDevice; - uno::Reference< rendering::XCanvas > xLastCanvas(mxCanvas); - const geometry::ViewInformation2D aLastViewInformation2D(getViewInformation2D()); - - // prepare discrete offset for XBitmap, do not forget that the buffer bitmap - // may be truncated to discrete visible pixels - const basegfx::B2DHomMatrix aDiscreteOffset(basegfx::tools::createTranslateB2DHomMatrix( - aDiscreteRange.getMinX() > 0.0 ? -aDiscreteRange.getMinX() : 0.0, - aDiscreteRange.getMinY() > 0.0 ? -aDiscreteRange.getMinY() : 0.0)); - - // create new local ViewInformation2D with new transformation - const geometry::ViewInformation2D aViewInformation2D( - getViewInformation2D().getObjectTransformation(), - aDiscreteOffset * getViewInformation2D().getViewTransformation(), - getViewInformation2D().getViewport(), - getViewInformation2D().getVisualizedPage(), - getViewInformation2D().getViewTime(), - getViewInformation2D().getExtendedInformationSequence()); - updateViewInformation(aViewInformation2D); - - // set OutDev and Canvas to content target - mpOutputDevice = &aBufferDevice.getContent(); - mxCanvas = mpOutputDevice->GetCanvas(); - canvas::tools::setViewStateTransform(maViewState, getViewInformation2D().getViewTransformation()); - - // if ViewState transform is changed, the clipping polygon needs to be adapted, too - const basegfx::B2DPolyPolygon aOldClipPolyPolygon(maClipPolyPolygon); - - if(maClipPolyPolygon.count()) - { - maClipPolyPolygon.transform(aDiscreteOffset); - maViewState.Clip = basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(mxCanvas->getDevice(), maClipPolyPolygon); - } - - // paint content - process(rChildren); - - // draw mask - const basegfx::BColor aBlack(0.0, 0.0, 0.0); - maRenderState.DeviceColor = aBlack.colorToDoubleSequence(mxCanvas->getDevice()); - - if(getOptionsDrawinglayer().IsAntiAliasing()) - { - // with AA, use 8bit AlphaMask to get nice borders - VirtualDevice& rTransparence = aBufferDevice.getTransparence(); - rTransparence.GetCanvas()->fillPolyPolygon( - basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(mxCanvas->getDevice(), aMask), - maViewState, maRenderState); - } - else - { - // No AA, use 1bit mask - VirtualDevice& rMask = aBufferDevice.getMask(); - rMask.GetCanvas()->fillPolyPolygon( - basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(mxCanvas->getDevice(), aMask), - maViewState, maRenderState); - } - - // back to old color stack, OutDev, Canvas and ViewTransform - mpOutputDevice = pLastOutputDevice; - mxCanvas = xLastCanvas; - updateViewInformation(aLastViewInformation2D); - canvas::tools::setViewStateTransform(maViewState, getViewInformation2D().getViewTransformation()); - - // restore clipping polygon - maClipPolyPolygon = aOldClipPolyPolygon; - - if(maClipPolyPolygon.count()) - { - maViewState.Clip = basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(mxCanvas->getDevice(), maClipPolyPolygon); - } - - // dump buffer to outdev - aBufferDevice.paint(); - } - } - } - else - { - // transform new mask polygon to view coordinates for processing. All masks - // are processed in view coordinates and clipped against each other evtl. to - // create multi-clips - aMask.transform(getViewInformation2D().getObjectTransformation()); - - // remember last current clip polygon - const basegfx::B2DPolyPolygon aLastClipPolyPolygon(maClipPolyPolygon); - - if(maClipPolyPolygon.count()) - { - // there is already a clip polygon set; build clipped union of - // current mask polygon and new one - maClipPolyPolygon = basegfx::tools::clipPolyPolygonOnPolyPolygon(aMask, maClipPolyPolygon, false, false); - } - else - { - // use mask directly - maClipPolyPolygon = aMask; - } - - // set at ViewState - if(maClipPolyPolygon.count()) - { - // set new as clip polygon - maViewState.Clip = basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(mxCanvas->getDevice(), maClipPolyPolygon); - } - else - { - // empty, reset - maViewState.Clip.clear(); - } - - // paint content - process(rChildren); - - // restore local current to rescued clip polygon - maClipPolyPolygon = aLastClipPolyPolygon; - - // set at ViewState - if(maClipPolyPolygon.count()) - { - // set new as clip polygon - maViewState.Clip = basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(mxCanvas->getDevice(), maClipPolyPolygon); - } - else - { - // empty, reset - maViewState.Clip.clear(); - } - } - } - } - } - - void canvasProcessor2D::impRenderMetafilePrimitive2D(const primitive2d::MetafilePrimitive2D& rMetaCandidate) - { - 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(); - } - - cppcanvas::BitmapCanvasSharedPtr pCanvas(cppcanvas::VCLFactory::getInstance().createCanvas( - uno::Reference(mxCanvas, uno::UNO_QUERY_THROW))); - cppcanvas::RendererSharedPtr pMtfRenderer(cppcanvas::VCLFactory::getInstance().createRenderer( - pCanvas, aMetaFile, cppcanvas::Renderer::Parameters())); - - if(pMtfRenderer) - { - pCanvas->setTransformation(getViewInformation2D().getObjectToViewTransformation()); - pMtfRenderer->setTransformation(rMetaCandidate.getTransform()); - pMtfRenderer->draw(); - } - } - - void canvasProcessor2D::impRenderTextSimplePortionPrimitive2D(const primitive2d::TextSimplePortionPrimitive2D& rTextCandidate) - { - if(rTextCandidate.getTextLength()) - { - double fShearX(0.0); - { - const basegfx::B2DHomMatrix aLocalTransform(getViewInformation2D().getObjectToViewTransformation() * rTextCandidate.getTextTransform()); - basegfx::B2DVector aScale, aTranslate; - double fRotate; - aLocalTransform.decompose(aScale, aTranslate, fRotate, fShearX); - } - - if(!basegfx::fTools::equalZero(fShearX)) - { - // text is sheared. As long as the canvas renderers do not support this, - // use the decomposed primitive - process(rTextCandidate.get2DDecomposition(getViewInformation2D())); - } - else - { - const attribute::FontAttribute& rFontAttr(rTextCandidate.getFontAttribute()); - rendering::FontRequest aFontRequest; - - aFontRequest.FontDescription.FamilyName = rFontAttr.getFamilyName(); - aFontRequest.FontDescription.StyleName = rFontAttr.getStyleName(); - aFontRequest.FontDescription.IsSymbolFont = rFontAttr.getSymbol() ? util::TriState_YES : util::TriState_NO; - aFontRequest.FontDescription.IsVertical = rFontAttr.getVertical() ? util::TriState_YES : util::TriState_NO; - // TODO(F2): improve vclenum->panose conversion - aFontRequest.FontDescription.FontDescription.Weight = static_cast< sal_uInt8 >(rFontAttr.getWeight()); - aFontRequest.FontDescription.FontDescription.Proportion = - rFontAttr.getMonospaced() - ? rendering::PanoseProportion::MONO_SPACED - : rendering::PanoseProportion::ANYTHING; - aFontRequest.FontDescription.FontDescription.Letterform = rFontAttr.getItalic() ? 9 : 0; - - // init CellSize to 1.0, else a default font height will be used - aFontRequest.CellSize = 1.0; - aFontRequest.Locale = rTextCandidate.getLocale(); - - // font matrix should only be used for glyph rotations etc. - com::sun::star::geometry::Matrix2D aFontMatrix; - canvas::tools::setIdentityMatrix2D(aFontMatrix); - - uno::Reference xFont(mxCanvas->createFont( - aFontRequest, uno::Sequence< beans::PropertyValue >(), aFontMatrix)); - - if(xFont.is()) - { - // got a font, now try to get a TextLayout - const rendering::StringContext aStringContext( - rTextCandidate.getText(), rTextCandidate.getTextPosition(), rTextCandidate.getTextLength()); - uno::Reference xLayout(xFont->createTextLayout( - aStringContext, com::sun::star::rendering::TextDirection::WEAK_LEFT_TO_RIGHT, 0)); - - if(xLayout.is()) - { - // got a text layout, apply DXArray if given - const ::std::vector< double >& rDXArray = rTextCandidate.getDXArray(); - const sal_uInt32 nDXCount(rDXArray.size()); - - if(nDXCount) - { - // DXArray does not need to be adapted to getTextPosition/getTextLength, - // it is already provided correctly - const uno::Sequence< double > aDXSequence(&rDXArray[0], nDXCount); - xLayout->applyLogicalAdvancements(aDXSequence); - } - - // set text color - const basegfx::BColor aRGBColor(maBColorModifierStack.getModifiedColor(rTextCandidate.getFontColor())); - maRenderState.DeviceColor = aRGBColor.colorToDoubleSequence(mxCanvas->getDevice()); - - // set text transformation - canvas::tools::setRenderStateTransform(maRenderState, - getViewInformation2D().getObjectTransformation() * rTextCandidate.getTextTransform()); - - // paint - mxCanvas->drawTextLayout(xLayout, maViewState, maRenderState); - } - } - } - } - } - - void canvasProcessor2D::impRenderBitmapPrimitive2D(const primitive2d::BitmapPrimitive2D& rBitmapCandidate) - { - // apply possible color modification to BitmapEx - BitmapEx aModifiedBitmapEx(impModifyBitmapEx(maBColorModifierStack, rBitmapCandidate.getBitmapEx())); - - if(aModifiedBitmapEx.IsEmpty()) - { - // replace with color filled polygon - const basegfx::BColor aModifiedColor(maBColorModifierStack.getModifiedColor(basegfx::BColor())); - const basegfx::B2DPolygon aPolygon(basegfx::tools::createUnitPolygon()); - - maRenderState.DeviceColor = aModifiedColor.colorToDoubleSequence(mxCanvas->getDevice()); - canvas::tools::setRenderStateTransform(maRenderState, - getViewInformation2D().getObjectTransformation() * rBitmapCandidate.getTransform()); - - mxCanvas->fillPolyPolygon(basegfx::unotools::xPolyPolygonFromB2DPolyPolygon( - mxCanvas->getDevice(), basegfx::B2DPolyPolygon(aPolygon)), maViewState, maRenderState); - } - else - { - // adapt object's transformation to the correct scale - basegfx::B2DVector aScale, aTranslate; - const Size aSizePixel(aModifiedBitmapEx.GetSizePixel()); - - if(0 != aSizePixel.Width() && 0 != aSizePixel.Height()) - { - double fRotate, fShearX; - rBitmapCandidate.getTransform().decompose(aScale, aTranslate, fRotate, fShearX); - const basegfx::B2DHomMatrix aNewMatrix(basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix( - aScale.getX() / aSizePixel.Width(), aScale.getY() / aSizePixel.Height(), - fShearX, fRotate, aTranslate.getX(), aTranslate.getY())); - - canvas::tools::setRenderStateTransform(maRenderState, - getViewInformation2D().getObjectTransformation() * aNewMatrix); - - mxCanvas->drawBitmap( - vcl::unotools::xBitmapFromBitmapEx(mxCanvas->getDevice(), aModifiedBitmapEx), - maViewState, maRenderState); - } - } - } - - void canvasProcessor2D::impRenderTransparencePrimitive2D(const primitive2d::TransparencePrimitive2D& rTransparenceCandidate) - { - const primitive2d::Primitive2DSequence& rChildren = rTransparenceCandidate.getChildren(); - const primitive2d::Primitive2DSequence& rTransparence = rTransparenceCandidate.getTransparence(); - - if(rChildren.hasElements() && rTransparence.hasElements()) - { - // get logic range of transparent part and clip with ViewRange - basegfx::B2DRange aLogicRange(primitive2d::getB2DRangeFromPrimitive2DSequence(rChildren, getViewInformation2D())); - - if(!getViewInformation2D().getViewport().isEmpty()) - { - aLogicRange.intersect(getViewInformation2D().getViewport()); - } - - if(!aLogicRange.isEmpty()) - { - // get discrete range of transparent part - basegfx::B2DRange aDiscreteRange(aLogicRange); - aDiscreteRange.transform(getViewInformation2D().getObjectToViewTransformation()); - - // expand to next covering discrete values (pixel bounds) - aDiscreteRange.expand(basegfx::B2DTuple(floor(aDiscreteRange.getMinX()), floor(aDiscreteRange.getMinY()))); - aDiscreteRange.expand(basegfx::B2DTuple(ceil(aDiscreteRange.getMaxX()), ceil(aDiscreteRange.getMaxY()))); - - // use VCL-based buffer device - impBufferDevice aBufferDevice(*mpOutputDevice, aDiscreteRange, false); - - if(aBufferDevice.isVisible()) - { - // remember current OutDev, Canvas and ViewInformation - OutputDevice* pLastOutputDevice = mpOutputDevice; - uno::Reference< rendering::XCanvas > xLastCanvas(mxCanvas); - const geometry::ViewInformation2D aLastViewInformation2D(getViewInformation2D()); - - // prepare discrete offset for XBitmap, do not forget that the buffer bitmap - // may be truncated to discrete visible pixels - const basegfx::B2DHomMatrix aDiscreteOffset(basegfx::tools::createTranslateB2DHomMatrix( - aDiscreteRange.getMinX() > 0.0 ? -aDiscreteRange.getMinX() : 0.0, - aDiscreteRange.getMinY() > 0.0 ? -aDiscreteRange.getMinY() : 0.0)); - - // create new local ViewInformation2D with new transformation - const geometry::ViewInformation2D aViewInformation2D( - getViewInformation2D().getObjectTransformation(), - aDiscreteOffset * getViewInformation2D().getViewTransformation(), - getViewInformation2D().getViewport(), - getViewInformation2D().getVisualizedPage(), - getViewInformation2D().getViewTime(), - getViewInformation2D().getExtendedInformationSequence()); - updateViewInformation(aViewInformation2D); - - // set OutDev and Canvas to content target - mpOutputDevice = &aBufferDevice.getContent(); - mxCanvas = mpOutputDevice->GetCanvas(); - canvas::tools::setViewStateTransform(maViewState, getViewInformation2D().getViewTransformation()); - - // if ViewState transform is changed, the clipping polygon needs to be adapted, too - const basegfx::B2DPolyPolygon aOldClipPolyPolygon(maClipPolyPolygon); - - if(maClipPolyPolygon.count()) - { - maClipPolyPolygon.transform(aDiscreteOffset); - maViewState.Clip = basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(mxCanvas->getDevice(), maClipPolyPolygon); - } - - // paint content - process(rChildren); - - // set to mask - mpOutputDevice = &aBufferDevice.getTransparence(); - mxCanvas = mpOutputDevice->GetCanvas(); - canvas::tools::setViewStateTransform(maViewState, getViewInformation2D().getViewTransformation()); - - // when painting transparence masks, reset the color stack - basegfx::BColorModifierStack aLastBColorModifierStack(maBColorModifierStack); - maBColorModifierStack = basegfx::BColorModifierStack(); - - // paint mask to it (always with transparence intensities, evtl. with AA) - process(rTransparence); - - // back to old color stack, OutDev, Canvas and ViewTransform - maBColorModifierStack = aLastBColorModifierStack; - mpOutputDevice = pLastOutputDevice; - mxCanvas = xLastCanvas; - updateViewInformation(aLastViewInformation2D); - canvas::tools::setViewStateTransform(maViewState, getViewInformation2D().getViewTransformation()); - - // restore clipping polygon - maClipPolyPolygon = aOldClipPolyPolygon; - - if(maClipPolyPolygon.count()) - { - maViewState.Clip = basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(mxCanvas->getDevice(), maClipPolyPolygon); - } - - // dump buffer to outdev - aBufferDevice.paint(); - } - } - } - } - - void canvasProcessor2D::impRenderPolygonStrokePrimitive2D(const primitive2d::PolygonStrokePrimitive2D& rPolygonStrokePrimitive) - { - // support direct fat line geometry. This moves the decomposition to the canvas. - // As long as our canvases are used (which also use basegfx tooling) this makes - // no difference, but potentially canvases may better support this - static bool bSupportFatLineDirectly(true); - bool bOutputDone(false); - - if(bSupportFatLineDirectly) - { - const attribute::LineAttribute& rLineAttribute = rPolygonStrokePrimitive.getLineAttribute(); - const attribute::StrokeAttribute& rStrokeAttribute = rPolygonStrokePrimitive.getStrokeAttribute(); - - if(0.0 < rLineAttribute.getWidth() || 0 != rStrokeAttribute.getDotDashArray().size()) - { - rendering::StrokeAttributes aStrokeAttribute; - - aStrokeAttribute.StrokeWidth = rLineAttribute.getWidth(); - aStrokeAttribute.MiterLimit = 15.0; // degrees; maybe here (15.0 * F_PI180) is needed, not clear in the documentation - const ::std::vector< double >& rDotDashArray = rStrokeAttribute.getDotDashArray(); - - if(!rDotDashArray.empty()) - { - aStrokeAttribute.DashArray = uno::Sequence< double >(&rDotDashArray[0], rDotDashArray.size()); - } - - switch(rLineAttribute.getLineJoin()) - { - default: // B2DLINEJOIN_NONE, B2DLINEJOIN_MIDDLE - aStrokeAttribute.JoinType = rendering::PathJoinType::NONE; - break; - case basegfx::B2DLINEJOIN_BEVEL: - aStrokeAttribute.JoinType = rendering::PathJoinType::BEVEL; - break; - case basegfx::B2DLINEJOIN_MITER: - aStrokeAttribute.JoinType = rendering::PathJoinType::MITER; - break; - case basegfx::B2DLINEJOIN_ROUND: - aStrokeAttribute.JoinType = rendering::PathJoinType::ROUND; - break; - } - - switch(rLineAttribute.getLineCap()) - { - case com::sun::star::drawing::LineCap_ROUND: - aStrokeAttribute.StartCapType = rendering::PathCapType::ROUND; - aStrokeAttribute.EndCapType = rendering::PathCapType::ROUND; - break; - case com::sun::star::drawing::LineCap_SQUARE: - aStrokeAttribute.StartCapType = rendering::PathCapType::SQUARE; - aStrokeAttribute.EndCapType = rendering::PathCapType::SQUARE; - break; - default: // com::sun::star::drawing::LineCap_BUTT - aStrokeAttribute.StartCapType = rendering::PathCapType::BUTT; - aStrokeAttribute.EndCapType = rendering::PathCapType::BUTT; - break; - } - - const basegfx::BColor aHairlineColor(maBColorModifierStack.getModifiedColor(rLineAttribute.getColor())); - maRenderState.DeviceColor = aHairlineColor.colorToDoubleSequence(mxCanvas->getDevice()); - canvas::tools::setRenderStateTransform(maRenderState, getViewInformation2D().getObjectTransformation()); - - mxCanvas->strokePolyPolygon( - basegfx::unotools::xPolyPolygonFromB2DPolygon(mxCanvas->getDevice(), rPolygonStrokePrimitive.getB2DPolygon()), - maViewState, maRenderState, aStrokeAttribute); - - bOutputDone = true; - } - } - - if(!bOutputDone) - { - // process decomposition - process(rPolygonStrokePrimitive.get2DDecomposition(getViewInformation2D())); - } - } - - void canvasProcessor2D::impRenderFillBitmapPrimitive2D(const primitive2d::FillBitmapPrimitive2D& rFillBitmapPrimitive2D) - { - // support tiled fills directly when tiling is on - static bool bSupportFillBitmapDirectly(true); - bool bOutputDone(false); - - if(bSupportFillBitmapDirectly) - { - const attribute::FillBitmapAttribute& rFillBitmapAttribute = rFillBitmapPrimitive2D.getFillBitmap(); - - if(rFillBitmapAttribute.getTiling()) - { - // apply possible color modification to Bitmap - const BitmapEx aChangedBitmapEx(impModifyBitmapEx(maBColorModifierStack, rFillBitmapAttribute.getBitmapEx())); - - if(aChangedBitmapEx.IsEmpty()) - { - // replace with color filled polygon - const basegfx::BColor aModifiedColor(maBColorModifierStack.getModifiedColor(basegfx::BColor())); - const basegfx::B2DPolygon aPolygon(basegfx::tools::createUnitPolygon()); - - maRenderState.DeviceColor = aModifiedColor.colorToDoubleSequence(mxCanvas->getDevice()); - canvas::tools::setRenderStateTransform(maRenderState, - getViewInformation2D().getObjectTransformation() * rFillBitmapPrimitive2D.getTransformation()); - - mxCanvas->fillPolyPolygon(basegfx::unotools::xPolyPolygonFromB2DPolyPolygon( - mxCanvas->getDevice(), basegfx::B2DPolyPolygon(aPolygon)), maViewState, maRenderState); - } - else - { - const Size aSizePixel(aChangedBitmapEx.GetSizePixel()); - - if(0 != aSizePixel.Width() && 0 != aSizePixel.Height()) - { - // create texture matrix from texture to object (where object is unit square here), - // so use values directly - const basegfx::B2DHomMatrix aTextureMatrix(basegfx::tools::createScaleTranslateB2DHomMatrix( - rFillBitmapAttribute.getSize().getX(), rFillBitmapAttribute.getSize().getY(), - rFillBitmapAttribute.getTopLeft().getX(), rFillBitmapAttribute.getTopLeft().getY())); - - // create and fill texture - rendering::Texture aTexture; - - basegfx::unotools::affineMatrixFromHomMatrix(aTexture.AffineTransform, aTextureMatrix); - aTexture.Alpha = 1.0; - aTexture.Bitmap = vcl::unotools::xBitmapFromBitmapEx(mxCanvas->getDevice(), aChangedBitmapEx); - aTexture.RepeatModeX = rendering::TexturingMode::REPEAT; - aTexture.RepeatModeY = rendering::TexturingMode::REPEAT; - - // canvas needs a polygon to fill, create unit rectangle polygon - const basegfx::B2DPolygon aOutlineRectangle(basegfx::tools::createUnitPolygon()); - - // set primitive's transformation as render state transform - canvas::tools::setRenderStateTransform(maRenderState, - getViewInformation2D().getObjectTransformation() * rFillBitmapPrimitive2D.getTransformation()); - - // put texture into a uno sequence for handover - uno::Sequence< rendering::Texture > aSeq(1); - aSeq[0] = aTexture; - - // draw textured rectangle - mxCanvas->fillTexturedPolyPolygon( - basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(mxCanvas->getDevice(), basegfx::B2DPolyPolygon(aOutlineRectangle)), - maViewState, maRenderState, aSeq); - } - } - - bOutputDone = true; - } - } - - if(!bOutputDone) - { - // process decomposition - process(rFillBitmapPrimitive2D.get2DDecomposition(getViewInformation2D())); - } - } - - void canvasProcessor2D::impRenderUnifiedTransparencePrimitive2D(const primitive2d::UnifiedTransparencePrimitive2D& rUniTransparenceCandidate) - { - if(0.0 == rUniTransparenceCandidate.getTransparence()) - { - // not transparent at all, directly use content - process(rUniTransparenceCandidate.getChildren()); - } - else if(rUniTransparenceCandidate.getTransparence() > 0.0 && rUniTransparenceCandidate.getTransparence() < 1.0) - { - const primitive2d::Primitive2DSequence rChildren = rUniTransparenceCandidate.getChildren(); - - if(rChildren.hasElements()) - { - bool bOutputDone(false); - - // Detect if a single PolyPolygonColorPrimitive2D is contained; in that case, - // use the fillPolyPolygon method with correctly set transparence. This is a often used - // case, so detectiong it is valuable - if(1 == rChildren.getLength()) - { - const primitive2d::Primitive2DReference xReference(rChildren[0]); - const primitive2d::PolyPolygonColorPrimitive2D* pPoPoColor = dynamic_cast< const primitive2d::PolyPolygonColorPrimitive2D* >(xReference.get()); - - if(pPoPoColor && PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D == pPoPoColor->getPrimitive2DID()) - { - // direct draw of PolyPolygon with color and transparence - const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(pPoPoColor->getBColor())); - - // add transparence modulation value to DeviceColor - uno::Sequence< double > aColor(4); - - aColor[0] = aPolygonColor.getRed(); - aColor[1] = aPolygonColor.getGreen(); - aColor[2] = aPolygonColor.getBlue(); - aColor[3] = 1.0 - rUniTransparenceCandidate.getTransparence(); - maRenderState.DeviceColor = aColor; - - canvas::tools::setRenderStateTransform(maRenderState, getViewInformation2D().getObjectTransformation()); - mxCanvas->fillPolyPolygon( - basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(mxCanvas->getDevice(), pPoPoColor->getB2DPolyPolygon()), - maViewState, maRenderState); - bOutputDone = true; - } - } - - if(!bOutputDone) - { - // process decomposition. This will be decomposed to an TransparencePrimitive2D - // with the same child context and a single polygon for transparent context. This could be - // directly handled here with known VCL-buffer technology, but would only - // make a small difference compared to directly rendering the TransparencePrimitive2D - // using impRenderTransparencePrimitive2D above. - process(rUniTransparenceCandidate.get2DDecomposition(getViewInformation2D())); - } - } - } - } - - ////////////////////////////////////////////////////////////////////////////// - // internal processing support - - void canvasProcessor2D::processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate) - { - switch(rCandidate.getPrimitive2DID()) - { - case PRIMITIVE2D_ID_POLYGONHAIRLINEPRIMITIVE2D : - { - // direct draw of hairline - const primitive2d::PolygonHairlinePrimitive2D& rPolygonCandidate = static_cast< const primitive2d::PolygonHairlinePrimitive2D& >(rCandidate); - const basegfx::BColor aHairlineColor(maBColorModifierStack.getModifiedColor(rPolygonCandidate.getBColor())); - - maRenderState.DeviceColor = aHairlineColor.colorToDoubleSequence(mxCanvas->getDevice()); - canvas::tools::setRenderStateTransform(maRenderState, getViewInformation2D().getObjectTransformation()); - mxCanvas->drawPolyPolygon( - basegfx::unotools::xPolyPolygonFromB2DPolygon(mxCanvas->getDevice(), rPolygonCandidate.getB2DPolygon()), - maViewState, maRenderState); - - break; - } - case PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D : - { - // direct draw of PolyPolygon with color - const primitive2d::PolyPolygonColorPrimitive2D& rPolygonCandidate = static_cast< const primitive2d::PolyPolygonColorPrimitive2D& >(rCandidate); - const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(rPolygonCandidate.getBColor())); - - maRenderState.DeviceColor = aPolygonColor.colorToDoubleSequence(mxCanvas->getDevice()); - canvas::tools::setRenderStateTransform(maRenderState, getViewInformation2D().getObjectTransformation()); - mxCanvas->fillPolyPolygon( - basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(mxCanvas->getDevice(), rPolygonCandidate.getB2DPolyPolygon()), - maViewState, maRenderState); - - break; - } - case PRIMITIVE2D_ID_MODIFIEDCOLORPRIMITIVE2D : - { - // modified color group. Force output to unified color. - const primitive2d::ModifiedColorPrimitive2D& rModifiedCandidate = static_cast< const primitive2d::ModifiedColorPrimitive2D& >(rCandidate); - - if(rModifiedCandidate.getChildren().hasElements()) - { - maBColorModifierStack.push(rModifiedCandidate.getColorModifier()); - process(rModifiedCandidate.getChildren()); - maBColorModifierStack.pop(); - } - - break; - } - case PRIMITIVE2D_ID_MASKPRIMITIVE2D : - { - // mask group - impRenderMaskPrimitive2D(static_cast< const primitive2d::MaskPrimitive2D& >(rCandidate)); - - break; - } - case PRIMITIVE2D_ID_TRANSFORMPRIMITIVE2D : - { - // transform group. Remember current ViewInformation2D - const primitive2d::TransformPrimitive2D& rTransformCandidate = static_cast< const primitive2d::TransformPrimitive2D& >(rCandidate); - const geometry::ViewInformation2D aLastViewInformation2D(getViewInformation2D()); - - // create new local ViewInformation2D with new transformation - const geometry::ViewInformation2D aViewInformation2D( - getViewInformation2D().getObjectTransformation() * rTransformCandidate.getTransformation(), - getViewInformation2D().getViewTransformation(), - getViewInformation2D().getViewport(), - getViewInformation2D().getVisualizedPage(), - getViewInformation2D().getViewTime(), - getViewInformation2D().getExtendedInformationSequence()); - updateViewInformation(aViewInformation2D); - - // set at canvas - canvas::tools::setRenderStateTransform(maRenderState, getViewInformation2D().getObjectTransformation()); - - // proccess content - process(rTransformCandidate.getChildren()); - - // restore transformations - updateViewInformation(aLastViewInformation2D); - - // restore at canvas - canvas::tools::setRenderStateTransform(maRenderState, getViewInformation2D().getObjectTransformation()); - - break; - } - case PRIMITIVE2D_ID_PAGEPREVIEWPRIMITIVE2D : - { - // new XDrawPage for ViewInformation2D - const primitive2d::PagePreviewPrimitive2D& rPagePreviewCandidate = static_cast< const primitive2d::PagePreviewPrimitive2D& >(rCandidate); - - // remember current transformation and ViewInformation - const geometry::ViewInformation2D aLastViewInformation2D(getViewInformation2D()); - - // create new local ViewInformation2D - const geometry::ViewInformation2D aViewInformation2D( - getViewInformation2D().getObjectTransformation(), - getViewInformation2D().getViewTransformation(), - getViewInformation2D().getViewport(), - rPagePreviewCandidate.getXDrawPage(), - getViewInformation2D().getViewTime(), - getViewInformation2D().getExtendedInformationSequence()); - updateViewInformation(aViewInformation2D); - - // proccess decomposed content - process(rPagePreviewCandidate.get2DDecomposition(getViewInformation2D())); - - // restore transformations - updateViewInformation(aLastViewInformation2D); - break; - } - case PRIMITIVE2D_ID_METAFILEPRIMITIVE2D : - { - // MetaFile primitive - impRenderMetafilePrimitive2D(static_cast< const primitive2d::MetafilePrimitive2D& >(rCandidate)); - - break; - } - case PRIMITIVE2D_ID_POINTARRAYPRIMITIVE2D : - { - // PointArray primitive - const primitive2d::PointArrayPrimitive2D& rPointArrayCandidate = static_cast< const primitive2d::PointArrayPrimitive2D& >(rCandidate); - - // set point color - const basegfx::BColor aRGBColor(maBColorModifierStack.getModifiedColor(rPointArrayCandidate.getRGBColor())); - maRenderState.DeviceColor = aRGBColor.colorToDoubleSequence(mxCanvas->getDevice()); - canvas::tools::setRenderStateTransform(maRenderState, getViewInformation2D().getObjectTransformation()); - - const std::vector< basegfx::B2DPoint >& rPointVector = rPointArrayCandidate.getPositions(); - const sal_uInt32 nPointCount(rPointVector.size()); - - for(sal_uInt32 a(0); a < nPointCount; a++) - { - const basegfx::B2DPoint& rPoint = rPointVector[a]; - mxCanvas->drawPoint(basegfx::unotools::point2DFromB2DPoint(rPoint), maViewState, maRenderState); - } - - break; - } - case PRIMITIVE2D_ID_TEXTSIMPLEPORTIONPRIMITIVE2D : - { - // TextSimplePortion primitive - impRenderTextSimplePortionPrimitive2D(static_cast< const primitive2d::TextSimplePortionPrimitive2D& >(rCandidate)); - - break; - } - case PRIMITIVE2D_ID_BITMAPPRIMITIVE2D : - { - // Bitmap primitive - impRenderBitmapPrimitive2D(static_cast< const primitive2d::BitmapPrimitive2D& >(rCandidate)); - - break; - } - case PRIMITIVE2D_ID_TRANSPARENCEPRIMITIVE2D : - { - // Transparence primitive - impRenderTransparencePrimitive2D(static_cast< const primitive2d::TransparencePrimitive2D& >(rCandidate)); - - break; - } - case PRIMITIVE2D_ID_POLYGONSTROKEPRIMITIVE2D: - { - // PolygonStrokePrimitive - impRenderPolygonStrokePrimitive2D(static_cast< const primitive2d::PolygonStrokePrimitive2D& >(rCandidate)); - - break; - } - case PRIMITIVE2D_ID_FILLBITMAPPRIMITIVE2D : - { - // FillBitmapPrimitive2D - impRenderFillBitmapPrimitive2D(static_cast< const primitive2d::FillBitmapPrimitive2D& >(rCandidate)); - - break; - } - case PRIMITIVE2D_ID_UNIFIEDTRANSPARENCEPRIMITIVE2D : - { - // UnifiedTransparencePrimitive2D - impRenderUnifiedTransparencePrimitive2D(static_cast< const primitive2d::UnifiedTransparencePrimitive2D& >(rCandidate)); - - break; - } - case PRIMITIVE2D_ID_WRONGSPELLPRIMITIVE2D : - { - // wrong spell primitive. Handled directly here using VCL since VCL has a nice and - // very direct waveline painting which is needed for this. If VCL is to be avoided, - // this can be removed anytime and the decomposition may be used - const primitive2d::WrongSpellPrimitive2D& rWrongSpellPrimitive = static_cast< const primitive2d::WrongSpellPrimitive2D& >(rCandidate); - - if(!renderWrongSpellPrimitive2D( - rWrongSpellPrimitive, - *mpOutputDevice, - getViewInformation2D().getObjectToViewTransformation(), - maBColorModifierStack)) - { - // fallback to decomposition (MetaFile) - process(rWrongSpellPrimitive.get2DDecomposition(getViewInformation2D())); - } - - break; - } - - // nice to have: - // - // case PRIMITIVE2D_ID_CONTROLPRIMITIVE2D : - // - support FormControls more direct eventually, not sure if this is needed - // with the canvas renderer. The decomposition provides a bitmap representation - // of the control which will work - // - - default : - { - // process recursively - process(rCandidate.get2DDecomposition(getViewInformation2D())); - - break; - } - } - } - - ////////////////////////////////////////////////////////////////////////////// - // process support - - canvasProcessor2D::canvasProcessor2D( - const geometry::ViewInformation2D& rViewInformation, - OutputDevice& rOutDev) - : BaseProcessor2D(rViewInformation), - mpOutputDevice(&rOutDev), - mxCanvas(rOutDev.GetCanvas()), - maViewState(), - maRenderState(), - maBColorModifierStack(), - maDrawinglayerOpt(), - maClipPolyPolygon(), - meLang(drawinglayer::detail::getDigitLanguage()) - { - canvas::tools::initViewState(maViewState); - canvas::tools::initRenderState(maRenderState); - canvas::tools::setViewStateTransform(maViewState, getViewInformation2D().getViewTransformation()); - - // set digit language, derived from SvtCTLOptions to have the correct - // number display for arabic/hindi numerals - rOutDev.SetDigitLanguage(meLang); - - // prepare output directly to pixels - mpOutputDevice->Push(PUSH_MAPMODE); - mpOutputDevice->SetMapMode(); - - // react on AntiAliasing settings - if(getOptionsDrawinglayer().IsAntiAliasing()) - { - mpOutputDevice->SetAntialiasing(mpOutputDevice->GetAntialiasing() | ANTIALIASING_ENABLE_B2DDRAW); - } - else - { - mpOutputDevice->SetAntialiasing(mpOutputDevice->GetAntialiasing() & ~ANTIALIASING_ENABLE_B2DDRAW); - } - } - - canvasProcessor2D::~canvasProcessor2D() - { - // restore MapMode - mpOutputDevice->Pop(); - - // restore AntiAliasing - mpOutputDevice->SetAntialiasing(mpOutputDevice->GetAntialiasing() & ~ANTIALIASING_ENABLE_B2DDRAW); - } - } // end of namespace processor2d -} // end of namespace drawinglayer - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/drawinglayer/source/processor2d/processorfromoutputdevice.cxx b/drawinglayer/source/processor2d/processorfromoutputdevice.cxx index 9875e79a7aae..ac7848829ec0 100644 --- a/drawinglayer/source/processor2d/processorfromoutputdevice.cxx +++ b/drawinglayer/source/processor2d/processorfromoutputdevice.cxx @@ -26,7 +26,6 @@ #include #include #include -#include #include ////////////////////////////////////////////////////////////////////////////// @@ -53,38 +52,8 @@ namespace drawinglayer } else { -#ifdef WIN32 - // for a first AA incarnation VCL-PixelRenderer will be okay since - // simple (and fast) GDIPlus support over VCL will be used. - // Leaving the code below as a hint for what to do when we will - // use canvas renderers in the future - - //static SvtOptionsDrawinglayer aSvtOptionsDrawinglayer; - - //if(false && aSvtOptionsDrawinglayer.IsAntiAliasing()) - //{ - // // for WIN32 AA, create cairo canvas processor - // return new drawinglayer::processor2d::canvasProcessor2D(rViewInformation2D, rTargetOutDev); - //} - //else - //{ - // create Pixel Vcl-Processor - return new drawinglayer::processor2d::VclPixelProcessor2D(rViewInformation2D, rTargetOutDev); - //} -#else - static bool bTryTestCanvas(false); - - if(bTryTestCanvas) - { - // create test-cancas-Processor - return new drawinglayer::processor2d::canvasProcessor2D(rViewInformation2D, rTargetOutDev); - } - else - { - // create Pixel Vcl-Processor - return new drawinglayer::processor2d::VclPixelProcessor2D(rViewInformation2D, rTargetOutDev); - } -#endif + // create Pixel Vcl-Processor + return new drawinglayer::processor2d::VclPixelProcessor2D(rViewInformation2D, rTargetOutDev); } } } // end of namespace processor2d diff --git a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx index ec5ad2d48d71..cf3c79b92638 100644 --- a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx +++ b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx @@ -615,7 +615,7 @@ namespace drawinglayer Even for XFillTransparenceItem it is used, thus it may need to be supported in UnifiedTransparencePrimitive2D, too, when interpreted as normally filled PolyPolygon. Implemented for: - PRIMITIVE2D_ID_POLYPOLYGONBITMAPPRIMITIVE2D, + PRIMITIVE2D_ID_POLYPOLYGONGRAPHICPRIMITIVE2D, PRIMITIVE2D_ID_POLYPOLYGONHATCHPRIMITIVE2D, PRIMITIVE2D_ID_POLYPOLYGONGRADIENTPRIMITIVE2D, PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D, @@ -1345,19 +1345,19 @@ namespace drawinglayer RenderBitmapPrimitive2D(static_cast< const primitive2d::BitmapPrimitive2D& >(rCandidate)); break; } - case PRIMITIVE2D_ID_POLYPOLYGONBITMAPPRIMITIVE2D : + case PRIMITIVE2D_ID_POLYPOLYGONGRAPHICPRIMITIVE2D : { - // need to handle PolyPolygonBitmapPrimitive2D here to support XPATHFILL_SEQ_BEGIN/XPATHFILL_SEQ_END - const primitive2d::PolyPolygonBitmapPrimitive2D& rBitmapCandidate = static_cast< const primitive2d::PolyPolygonBitmapPrimitive2D& >(rCandidate); + // need to handle PolyPolygonGraphicPrimitive2D here to support XPATHFILL_SEQ_BEGIN/XPATHFILL_SEQ_END + const primitive2d::PolyPolygonGraphicPrimitive2D& rBitmapCandidate = static_cast< const primitive2d::PolyPolygonGraphicPrimitive2D& >(rCandidate); basegfx::B2DPolyPolygon aLocalPolyPolygon(rBitmapCandidate.getB2DPolyPolygon()); if(fillPolyPolygonNeededToBeSplit(aLocalPolyPolygon)) { // #i112245# Metafiles use tools Polygon and are not able to have more than 65535 points // per polygon. If there are more use the splitted polygon and call recursively - const primitive2d::PolyPolygonBitmapPrimitive2D aSplitted( + const primitive2d::PolyPolygonGraphicPrimitive2D aSplitted( aLocalPolyPolygon, - rBitmapCandidate.getFillBitmap()); + rBitmapCandidate.getFillGraphic()); processBasePrimitive2D(aSplitted); } @@ -1367,46 +1367,41 @@ namespace drawinglayer if(!mnSvtGraphicFillCount && aLocalPolyPolygon.count()) { - aLocalPolyPolygon.transform(maCurrentTransformation); - // calculate transformation. Get real object size, all values in FillBitmapAttribute - // are relative to the unified object - const attribute::FillBitmapAttribute& rFillBitmapAttribute = rBitmapCandidate .getFillBitmap(); - const basegfx::B2DRange aOutlineRange(basegfx::tools::getRange(aLocalPolyPolygon)); - const basegfx::B2DVector aOutlineSize(aOutlineRange.getRange()); + // #121194# Changed implementation and checked usages fo convert to metafile, + // presentation start (uses SvtGraphicFill) and printing. - // get absolute values - const basegfx::B2DVector aFillBitmapSize(rFillBitmapAttribute.getSize() * aOutlineSize); - const basegfx::B2DPoint aFillBitmapTopLeft(rFillBitmapAttribute.getTopLeft() * aOutlineSize); + // calculate transformation. Get real object size, all values in FillGraphicAttribute + // are relative to the unified object + aLocalPolyPolygon.transform(maCurrentTransformation); + const basegfx::B2DVector aOutlineSize(aLocalPolyPolygon.getB2DRange().getRange()); // the scaling needs scale from pixel to logic coordinate system - const BitmapEx& rBitmapEx = rFillBitmapAttribute.getBitmapEx(); - Size aBmpSizePixel(rBitmapEx.GetSizePixel()); - - if(!aBmpSizePixel.Width()) - { - aBmpSizePixel.Width() = 1; - } - - if(!aBmpSizePixel.Height()) - { - aBmpSizePixel.Height() = 1; - } + const attribute::FillGraphicAttribute& rFillGraphicAttribute = rBitmapCandidate.getFillGraphic(); + const Size aBmpSizePixel(rFillGraphicAttribute.getGraphic().GetSizePixel()); + + // setup transformation like in impgrfll. Multiply with aOutlineSize + // to get from unit coordinates in rFillGraphicAttribute.getGraphicRange() + // to object coordinates with object's top left being at (0,0). Divide + // by pixel size so that scale from pixel to logic will work in SvtGraphicFill. + const basegfx::B2DVector aTransformScale( + rFillGraphicAttribute.getGraphicRange().getRange() / + basegfx::B2DVector( + std::max(1.0, double(aBmpSizePixel.Width())), + std::max(1.0, double(aBmpSizePixel.Height()))) * + aOutlineSize); + const basegfx::B2DPoint aTransformPosition( + rFillGraphicAttribute.getGraphicRange().getMinimum() * aOutlineSize); // setup transformation like in impgrfll SvtGraphicFill::Transform aTransform; // scale values are divided by bitmap pixel sizes - aTransform.matrix[0] = aFillBitmapSize.getX() / aBmpSizePixel.Width(); - aTransform.matrix[4] = aFillBitmapSize.getY() / aBmpSizePixel.Height(); + aTransform.matrix[0] = aTransformScale.getX(); + aTransform.matrix[4] = aTransformScale.getY(); // translates are absolute - aTransform.matrix[2] = aFillBitmapTopLeft.getX(); - aTransform.matrix[5] = aFillBitmapTopLeft.getY(); - - // setup fill graphic like in impgrfll - Graphic aFillGraphic = Graphic(rBitmapEx); - aFillGraphic.SetPrefMapMode(MapMode(MAP_PIXEL)); - aFillGraphic.SetPrefSize(aBmpSizePixel); + aTransform.matrix[2] = aTransformPosition.getX(); + aTransform.matrix[5] = aTransformPosition.getY(); pSvtGraphicFill = new SvtGraphicFill( getFillPolyPolygon(aLocalPolyPolygon), @@ -1415,14 +1410,14 @@ namespace drawinglayer SvtGraphicFill::fillEvenOdd, SvtGraphicFill::fillTexture, aTransform, - rFillBitmapAttribute.getTiling(), + rFillGraphicAttribute.getTiling(), SvtGraphicFill::hatchSingle, Color(), SvtGraphicFill::gradientLinear, Color(), Color(), 0, - aFillGraphic); + rFillGraphicAttribute.getGraphic()); } // Do use decomposition; encapsulate with SvtGraphicFill @@ -1806,7 +1801,7 @@ namespace drawinglayer } // PolyPolygonGradientPrimitive2D, PolyPolygonHatchPrimitive2D and - // PolyPolygonBitmapPrimitive2D are derived from PolyPolygonColorPrimitive2D. + // PolyPolygonGraphicPrimitive2D are derived from PolyPolygonColorPrimitive2D. // Check also for correct ID to exclude derived implementations if(pPoPoColor && PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D == pPoPoColor->getPrimitive2DID()) { diff --git a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx index dde9bb5724dc..1f2d518e3c9d 100644 --- a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx +++ b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include #include @@ -179,10 +179,10 @@ namespace drawinglayer RenderBitmapPrimitive2D(static_cast< const primitive2d::BitmapPrimitive2D& >(rCandidate)); break; } - case PRIMITIVE2D_ID_FILLBITMAPPRIMITIVE2D : + case PRIMITIVE2D_ID_FILLGRAPHICPRIMITIVE2D : { // direct draw of fillBitmapPrimitive - RenderFillBitmapPrimitive2D(static_cast< const primitive2d::FillBitmapPrimitive2D& >(rCandidate)); + RenderFillGraphicPrimitive2D(static_cast< const primitive2d::FillGraphicPrimitive2D& >(rCandidate)); break; } case PRIMITIVE2D_ID_POLYPOLYGONGRADIENTPRIMITIVE2D : @@ -191,10 +191,10 @@ namespace drawinglayer RenderPolyPolygonGradientPrimitive2D(static_cast< const primitive2d::PolyPolygonGradientPrimitive2D& >(rCandidate)); break; } - case PRIMITIVE2D_ID_POLYPOLYGONBITMAPPRIMITIVE2D : + case PRIMITIVE2D_ID_POLYPOLYGONGRAPHICPRIMITIVE2D : { // direct draw of bitmap - RenderPolyPolygonBitmapPrimitive2D(static_cast< const primitive2d::PolyPolygonBitmapPrimitive2D& >(rCandidate)); + RenderPolyPolygonGraphicPrimitive2D(static_cast< const primitive2d::PolyPolygonGraphicPrimitive2D& >(rCandidate)); break; } case PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D : diff --git a/drawinglayer/source/processor2d/vclprocessor2d.cxx b/drawinglayer/source/processor2d/vclprocessor2d.cxx index cced61242c17..d129251dbfc1 100644 --- a/drawinglayer/source/processor2d/vclprocessor2d.cxx +++ b/drawinglayer/source/processor2d/vclprocessor2d.cxx @@ -28,8 +28,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include @@ -52,6 +52,7 @@ #include #include #include +#include #include "getdigitlanguage.hxx" @@ -474,122 +475,192 @@ namespace drawinglayer } } - void VclProcessor2D::RenderFillBitmapPrimitive2D(const primitive2d::FillBitmapPrimitive2D& rFillBitmapCandidate) + void VclProcessor2D::RenderFillGraphicPrimitive2D(const primitive2d::FillGraphicPrimitive2D& rFillBitmapCandidate) { - const attribute::FillBitmapAttribute& rFillBitmapAttribute(rFillBitmapCandidate.getFillBitmap()); + const attribute::FillGraphicAttribute& rFillGraphicAttribute(rFillBitmapCandidate.getFillGraphic()); bool bPrimitiveAccepted(false); + static bool bTryTilingDirect = true; - if(rFillBitmapAttribute.getTiling()) - { - // decompose matrix to check for shear, rotate and mirroring - basegfx::B2DHomMatrix aLocalTransform(maCurrentTransformation * rFillBitmapCandidate.getTransformation()); - basegfx::B2DVector aScale, aTranslate; - double fRotate, fShearX; - aLocalTransform.decompose(aScale, aTranslate, fRotate, fShearX); + // #121194# when tiling is used and content is bitmap-based, do direct tiling in the + // renderer on pixel base to ensure tight fitting. Do not do this when + // the fill is rotated or sheared. - if(basegfx::fTools::equalZero(fRotate) && basegfx::fTools::equalZero(fShearX)) + // ovveride static bool (for debug) and tiling is active + if(bTryTilingDirect && rFillGraphicAttribute.getTiling()) + { + // content is bitmap(ex) + // + // for SVG support, force decomposition when SVG is present. This will lead to use + // the primitive representation of the svg directly. + // + // when graphic is animated, force decomposition to use the correct graphic, else + // fill style will not be animated + if(GRAPHIC_BITMAP == rFillGraphicAttribute.getGraphic().GetType() + && !rFillGraphicAttribute.getGraphic().getSvgData().get() + && !rFillGraphicAttribute.getGraphic().IsAnimated()) { - // no shear or rotate, draw direct in pixel coordinates - bPrimitiveAccepted = true; - BitmapEx aBitmapEx(rFillBitmapAttribute.getBitmapEx()); - bool bPainted(false); - - if(maBColorModifierStack.count()) + // decompose matrix to check for shear, rotate and mirroring + basegfx::B2DHomMatrix aLocalTransform(maCurrentTransformation * rFillBitmapCandidate.getTransformation()); + basegfx::B2DVector aScale, aTranslate; + double fRotate, fShearX; + aLocalTransform.decompose(aScale, aTranslate, fRotate, fShearX); + + // when nopt rotated/sheared + if(basegfx::fTools::equalZero(fRotate) && basegfx::fTools::equalZero(fShearX)) { - aBitmapEx = impModifyBitmapEx(maBColorModifierStack, aBitmapEx); - - if(aBitmapEx.IsEmpty()) - { - // color gets completely replaced, get it - const basegfx::BColor aModifiedColor(maBColorModifierStack.getModifiedColor(basegfx::BColor())); - basegfx::B2DPolygon aPolygon(basegfx::tools::createUnitPolygon()); - aPolygon.transform(aLocalTransform); + // no shear or rotate, draw direct in pixel coordinates + bPrimitiveAccepted = true; - mpOutputDevice->SetFillColor(Color(aModifiedColor)); - mpOutputDevice->SetLineColor(); - mpOutputDevice->DrawPolygon(aPolygon); + // transform object range to device coordinates (pixels). Use + // the device transformation for better accuracy + basegfx::B2DRange aObjectRange(aTranslate, aTranslate + aScale); + aObjectRange.transform(mpOutputDevice->GetViewTransformation()); - bPainted = true; - } - } - - if(!bPainted) - { - const basegfx::B2DPoint aObjTopLeft(aTranslate.getX(), aTranslate.getY()); - const basegfx::B2DPoint aObjBottomRight(aTranslate.getX() + aScale.getX(), aTranslate.getY() + aScale.getY()); - const Point aObjTL(mpOutputDevice->LogicToPixel(Point((sal_Int32)aObjTopLeft.getX(), (sal_Int32)aObjTopLeft.getY()))); - const Point aObjBR(mpOutputDevice->LogicToPixel(Point((sal_Int32)aObjBottomRight.getX(), (sal_Int32)aObjBottomRight.getY()))); - - const basegfx::B2DPoint aBmpTopLeft(aLocalTransform * rFillBitmapAttribute.getTopLeft()); - const basegfx::B2DPoint aBmpBottomRight(aLocalTransform * basegfx::B2DPoint(rFillBitmapAttribute.getTopLeft() + rFillBitmapAttribute.getSize())); - const Point aBmpTL(mpOutputDevice->LogicToPixel(Point((sal_Int32)aBmpTopLeft.getX(), (sal_Int32)aBmpTopLeft.getY()))); - const Point aBmpBR(mpOutputDevice->LogicToPixel(Point((sal_Int32)aBmpBottomRight.getX(), (sal_Int32)aBmpBottomRight.getY()))); - - sal_Int32 nOWidth(aObjBR.X() - aObjTL.X()); - sal_Int32 nOHeight(aObjBR.Y() - aObjTL.Y()); + // extract discrete size of object + const sal_Int32 nOWidth(basegfx::fround(aObjectRange.getWidth())); + const sal_Int32 nOHeight(basegfx::fround(aObjectRange.getHeight())); // only do something when object has a size in discrete units if(nOWidth > 0 && nOHeight > 0) { - sal_Int32 nBWidth(aBmpBR.X() - aBmpTL.X()); - sal_Int32 nBHeight(aBmpBR.Y() - aBmpTL.Y()); + // transform graphic range to device coordinates (pixels). Use + // the device transformation for better accuracy + basegfx::B2DRange aGraphicRange(rFillGraphicAttribute.getGraphicRange()); + aGraphicRange.transform(mpOutputDevice->GetViewTransformation() * aLocalTransform); + + // extract discrete size of graphic + const sal_Int32 nBWidth(basegfx::fround(aGraphicRange.getWidth())); + const sal_Int32 nBHeight(basegfx::fround(aGraphicRange.getHeight())); // only do something when bitmap fill has a size in discrete units if(nBWidth > 0 && nBHeight > 0) { - sal_Int32 nBLeft(aBmpTL.X()); - sal_Int32 nBTop(aBmpTL.Y()); - - if(nBLeft > aObjTL.X()) + // nBWidth, nBHeight is the pixel size of the neede bitmap. To not need to scale it + // in vcl many times, create a size-optimized version + const Size aNeededBitmapSizePixel(nBWidth, nBHeight); + BitmapEx aBitmapEx(rFillGraphicAttribute.getGraphic().GetBitmapEx( + GraphicConversionParameters( + aNeededBitmapSizePixel, // get the correct size immediately + false, // no unlimited size + false, // Use AntiAliasing + false, //SnapHorVerLines + true // ScaleHighQuality + ))); + bool bPainted(false); + + if(maBColorModifierStack.count()) { - nBLeft -= ((nBLeft / nBWidth) + 1L) * nBWidth; - } + // when color modifier, apply to bitmap + aBitmapEx = impModifyBitmapEx(maBColorModifierStack, aBitmapEx); - if(nBLeft + nBWidth <= aObjTL.X()) - { - nBLeft -= (nBLeft / nBWidth) * nBWidth; - } + // impModifyBitmapEx uses empty bitmap as sign to return that + // the content will be completely replaced to mono color, use shortcut + if(aBitmapEx.IsEmpty()) + { + // color gets completely replaced, get it + const basegfx::BColor aModifiedColor(maBColorModifierStack.getModifiedColor(basegfx::BColor())); + basegfx::B2DPolygon aPolygon(basegfx::tools::createUnitPolygon()); + aPolygon.transform(aLocalTransform); - if(nBTop > aObjTL.Y()) - { - nBTop -= ((nBTop / nBHeight) + 1L) * nBHeight; + mpOutputDevice->SetFillColor(Color(aModifiedColor)); + mpOutputDevice->SetLineColor(); + mpOutputDevice->DrawPolygon(aPolygon); + + bPainted = true; + } } - if(nBTop + nBHeight <= aObjTL.Y()) + if(!bPainted) { - nBTop -= (nBTop / nBHeight) * nBHeight; - } + sal_Int32 nBLeft(basegfx::fround(aGraphicRange.getMinX())); + sal_Int32 nBTop(basegfx::fround(aGraphicRange.getMinY())); + const sal_Int32 nOLeft(basegfx::fround(aObjectRange.getMinX())); + const sal_Int32 nOTop(basegfx::fround(aObjectRange.getMinY())); + sal_Int32 nPosX(0); + sal_Int32 nPosY(0); + + if(nBLeft > nOLeft) + { + const sal_Int32 nDiff((nBLeft / nBWidth) + 1); - // nBWidth, nBHeight is the pixel size of the neede bitmap. To not need to scale it - // in vcl many times, create a size-optimized version - const Size aNeededBitmapSizePixel(nBWidth, nBHeight); + nPosX -= nDiff; + nBLeft -= nDiff * nBWidth; + } - if(aNeededBitmapSizePixel != aBitmapEx.GetSizePixel()) - { - aBitmapEx.Scale(aNeededBitmapSizePixel); - } + if(nBLeft + nBWidth <= nOLeft) + { + const sal_Int32 nDiff(-nBLeft / nBWidth); - // prepare OutDev - const Point aEmptyPoint(0, 0); - const Rectangle aVisiblePixel(aEmptyPoint, mpOutputDevice->GetOutputSizePixel()); - const bool bWasEnabled(mpOutputDevice->IsMapModeEnabled()); - mpOutputDevice->EnableMapMode(false); + nPosX += nDiff; + nBLeft += nDiff * nBWidth; + } - for(sal_Int32 nXPos(nBLeft); nXPos < aObjTL.X() + nOWidth; nXPos += nBWidth) - { - for(sal_Int32 nYPos(nBTop); nYPos < aObjTL.Y() + nOHeight; nYPos += nBHeight) + if(nBTop > nOTop) + { + const sal_Int32 nDiff((nBTop / nBHeight) + 1); + + nPosY -= nDiff; + nBTop -= nDiff * nBHeight; + } + + if(nBTop + nBHeight <= nOTop) + { + const sal_Int32 nDiff(-nBTop / nBHeight); + + nPosY += nDiff; + nBTop += nDiff * nBHeight; + } + + // prepare OutDev + const Point aEmptyPoint(0, 0); + const Rectangle aVisiblePixel(aEmptyPoint, mpOutputDevice->GetOutputSizePixel()); + const bool bWasEnabled(mpOutputDevice->IsMapModeEnabled()); + mpOutputDevice->EnableMapMode(false); + + // check if offset is used + const sal_Int32 nOffsetX(basegfx::fround(rFillGraphicAttribute.getOffsetX() * nBWidth)); + + if(nOffsetX) + { + // offset in X, so iterate over Y first and draw lines + for(sal_Int32 nYPos(nBTop); nYPos < nOTop + nOHeight; nYPos += nBHeight, nPosY++) + { + for(sal_Int32 nXPos(nPosY % 2 ? nBLeft - nBWidth + nOffsetX : nBLeft); + nXPos < nOLeft + nOWidth; nXPos += nBWidth) + { + const Rectangle aOutRectPixel(Point(nXPos, nYPos), aNeededBitmapSizePixel); + + if(aOutRectPixel.IsOver(aVisiblePixel)) + { + mpOutputDevice->DrawBitmapEx(aOutRectPixel.TopLeft(), aBitmapEx); + } + } + } + } + else { - const Rectangle aOutRectPixel(Point(nXPos, nYPos), aNeededBitmapSizePixel); + // check if offset is used + const sal_Int32 nOffsetY(basegfx::fround(rFillGraphicAttribute.getOffsetY() * nBHeight)); - if(aOutRectPixel.IsOver(aVisiblePixel)) + // possible offset in Y, so iterate over X first and draw columns + for(sal_Int32 nXPos(nBLeft); nXPos < nOLeft + nOWidth; nXPos += nBWidth, nPosX++) { - mpOutputDevice->DrawBitmapEx(aOutRectPixel.TopLeft(), aBitmapEx); + for(sal_Int32 nYPos(nPosX % 2 ? nBTop - nBHeight + nOffsetY : nBTop); + nYPos < nOTop + nOHeight; nYPos += nBHeight) + { + const Rectangle aOutRectPixel(Point(nXPos, nYPos), aNeededBitmapSizePixel); + + if(aOutRectPixel.IsOver(aVisiblePixel)) + { + mpOutputDevice->DrawBitmapEx(aOutRectPixel.TopLeft(), aBitmapEx); + } + } } } - } - // restore OutDev - mpOutputDevice->EnableMapMode(bWasEnabled); + // restore OutDev + mpOutputDevice->EnableMapMode(bWasEnabled); + } } } } @@ -641,90 +712,105 @@ namespace drawinglayer } } - // direct draw of bitmap - void VclProcessor2D::RenderPolyPolygonBitmapPrimitive2D(const primitive2d::PolyPolygonBitmapPrimitive2D& rPolygonCandidate) + // direct draw of Graphic + void VclProcessor2D::RenderPolyPolygonGraphicPrimitive2D(const primitive2d::PolyPolygonGraphicPrimitive2D& rPolygonCandidate) { bool bDone(false); const basegfx::B2DPolyPolygon& rPolyPolygon = rPolygonCandidate.getB2DPolyPolygon(); - if(rPolyPolygon.count()) + // #121194# Todo: check if this works + if(!rPolyPolygon.count()) { - const attribute::FillBitmapAttribute& rFillBitmapAttribute = rPolygonCandidate.getFillBitmap(); - const BitmapEx& rBitmapEx = rFillBitmapAttribute.getBitmapEx(); + // empty polyPolygon, done + bDone = true; + } + else + { + const attribute::FillGraphicAttribute& rFillGraphicAttribute = rPolygonCandidate.getFillGraphic(); - if(rBitmapEx.IsEmpty()) - { - // empty bitmap, done - bDone = true; - } - else + // try to catch cases where the graphic will be color-modified to a single + // color (e.g. shadow) + switch(rFillGraphicAttribute.getGraphic().GetType()) { - // try to catch cases where the bitmap will be color-modified to a single - // color (e.g. shadow). This would NOT be optimizable with an transparence channel - // at the Bitmap which we do not have here. When this should change, this - // optimization has to be reworked accordingly. - const sal_uInt32 nBColorModifierStackCount(maBColorModifierStack.count()); - - if(nBColorModifierStackCount) + case GRAPHIC_GDIMETAFILE: { - const basegfx::BColorModifier& rTopmostModifier = maBColorModifierStack.getBColorModifier(nBColorModifierStackCount - 1); - - if(basegfx::BCOLORMODIFYMODE_REPLACE == rTopmostModifier.getMode()) + // metafiles are potentially transparent, cannot optimize´, not done + break; + } + case GRAPHIC_BITMAP: + { + if(!rFillGraphicAttribute.getGraphic().IsTransparent() && !rFillGraphicAttribute.getGraphic().IsAlpha()) { - // the bitmap fill is in unified color, so we can replace it with - // a single polygon fill. The form of the fill depends on tiling - if(rFillBitmapAttribute.getTiling()) - { - // with tiling, fill the whole PolyPolygon with the modifier color - basegfx::B2DPolyPolygon aLocalPolyPolygon(rPolyPolygon); + // bitmap is not transparent and has no alpha + const sal_uInt32 nBColorModifierStackCount(maBColorModifierStack.count()); - aLocalPolyPolygon.transform(maCurrentTransformation); - mpOutputDevice->SetLineColor(); - mpOutputDevice->SetFillColor(Color(rTopmostModifier.getBColor())); - mpOutputDevice->DrawPolyPolygon(aLocalPolyPolygon); - } - else + if(nBColorModifierStackCount) { - // without tiling, only the area common to the bitmap tile and the - // PolyPolygon is filled. Create the bitmap tile area in object - // coordinates. For this, the object transformation needs to be created - // from the already scaled PolyPolygon. The tile area in object - // coordinates wil always be non-rotated, so it's not necessary to - // work with a polygon here - basegfx::B2DRange aTileRange(rFillBitmapAttribute.getTopLeft(), - rFillBitmapAttribute.getTopLeft() + rFillBitmapAttribute.getSize()); - const basegfx::B2DRange aPolyPolygonRange(rPolyPolygon.getB2DRange()); - basegfx::B2DHomMatrix aNewObjectTransform; - - aNewObjectTransform.set(0, 0, aPolyPolygonRange.getWidth()); - aNewObjectTransform.set(1, 1, aPolyPolygonRange.getHeight()); - aNewObjectTransform.set(0, 2, aPolyPolygonRange.getMinX()); - aNewObjectTransform.set(1, 2, aPolyPolygonRange.getMinY()); - aTileRange.transform(aNewObjectTransform); - - // now clip the object polyPolygon against the tile range - // to get the common area (OR) - basegfx::B2DPolyPolygon aTarget = basegfx::tools::clipPolyPolygonOnRange(rPolyPolygon, aTileRange, true, false); - - if(aTarget.count()) + const basegfx::BColorModifier& rTopmostModifier = maBColorModifierStack.getBColorModifier(nBColorModifierStackCount - 1); + + if(basegfx::BCOLORMODIFYMODE_REPLACE == rTopmostModifier.getMode()) { - aTarget.transform(maCurrentTransformation); - mpOutputDevice->SetLineColor(); - mpOutputDevice->SetFillColor(Color(rTopmostModifier.getBColor())); - mpOutputDevice->DrawPolyPolygon(aTarget); + // the bitmap fill is in unified color, so we can replace it with + // a single polygon fill. The form of the fill depends on tiling + if(rFillGraphicAttribute.getTiling()) + { + // with tiling, fill the whole PolyPolygon with the modifier color + basegfx::B2DPolyPolygon aLocalPolyPolygon(rPolyPolygon); + + aLocalPolyPolygon.transform(maCurrentTransformation); + mpOutputDevice->SetLineColor(); + mpOutputDevice->SetFillColor(Color(rTopmostModifier.getBColor())); + mpOutputDevice->DrawPolyPolygon(aLocalPolyPolygon); + } + else + { + // without tiling, only the area common to the bitmap tile and the + // PolyPolygon is filled. Create the bitmap tile area in object + // coordinates. For this, the object transformation needs to be created + // from the already scaled PolyPolygon. The tile area in object + // coordinates wil always be non-rotated, so it's not necessary to + // work with a polygon here + basegfx::B2DRange aTileRange(rFillGraphicAttribute.getGraphicRange()); + const basegfx::B2DRange aPolyPolygonRange(rPolyPolygon.getB2DRange()); + const basegfx::B2DHomMatrix aNewObjectTransform( + basegfx::tools::createScaleTranslateB2DHomMatrix( + aPolyPolygonRange.getRange(), + aPolyPolygonRange.getMinimum())); + + aTileRange.transform(aNewObjectTransform); + + // now clip the object polyPolygon against the tile range + // to get the common area + basegfx::B2DPolyPolygon aTarget = basegfx::tools::clipPolyPolygonOnRange( + rPolyPolygon, + aTileRange, + true, + false); + + if(aTarget.count()) + { + aTarget.transform(maCurrentTransformation); + mpOutputDevice->SetLineColor(); + mpOutputDevice->SetFillColor(Color(rTopmostModifier.getBColor())); + mpOutputDevice->DrawPolyPolygon(aTarget); + } + } + + // simplified output executed, we are done + bDone = true; } } - - bDone = true; } + break; + } + default: //GRAPHIC_NONE, GRAPHIC_DEFAULT + { + // empty graphic, we are done + bDone = true; + break; } } } - else - { - // empty polyPolygon, done - bDone = true; - } if(!bDone) { diff --git a/drawinglayer/source/processor3d/defaultprocessor3d.cxx b/drawinglayer/source/processor3d/defaultprocessor3d.cxx index 1781efbbe282..6c575095f43b 100644 --- a/drawinglayer/source/processor3d/defaultprocessor3d.cxx +++ b/drawinglayer/source/processor3d/defaultprocessor3d.cxx @@ -34,6 +34,8 @@ #include #include #include +#include +#include ////////////////////////////////////////////////////////////////////////////// @@ -210,21 +212,33 @@ namespace drawinglayer boost::shared_ptr< texture::GeoTexSvx > pOldTex = mpGeoTexSvx; // create texture - const attribute::FillBitmapAttribute& rFillBitmapAttribute = rPrimitive.getFillBitmapAttribute(); + const attribute::FillGraphicAttribute& rFillGraphicAttribute = rPrimitive.getFillGraphicAttribute(); - if(rFillBitmapAttribute.getTiling()) + // #121194# For 3D texture we will use the BitmapRex representation + const BitmapEx aBitmapEx(rFillGraphicAttribute.getGraphic().GetBitmapEx()); + + // create range scaled by texture size + basegfx::B2DRange aGraphicRange(rFillGraphicAttribute.getGraphicRange()); + + aGraphicRange.transform( + basegfx::tools::createScaleB2DHomMatrix( + rPrimitive.getTextureSize())); + + if(rFillGraphicAttribute.getTiling()) { - mpGeoTexSvx.reset(new texture::GeoTexSvxBitmapTiled( - rFillBitmapAttribute.getBitmapEx().GetBitmap(), - rFillBitmapAttribute.getTopLeft() * rPrimitive.getTextureSize(), - rFillBitmapAttribute.getSize() * rPrimitive.getTextureSize())); + mpGeoTexSvx.reset( + new texture::GeoTexSvxBitmapExTiled( + aBitmapEx, + aGraphicRange, + rFillGraphicAttribute.getOffsetX(), + rFillGraphicAttribute.getOffsetY())); } else { - mpGeoTexSvx.reset(new texture::GeoTexSvxBitmap( - rFillBitmapAttribute.getBitmapEx().GetBitmap(), - rFillBitmapAttribute.getTopLeft() * rPrimitive.getTextureSize(), - rFillBitmapAttribute.getSize() * rPrimitive.getTextureSize())); + mpGeoTexSvx.reset( + new texture::GeoTexSvxBitmapEx( + aBitmapEx, + aGraphicRange)); } // process sub-list diff --git a/drawinglayer/source/texture/texture.cxx b/drawinglayer/source/texture/texture.cxx index f69c9736ac40..d11026143c5f 100644 --- a/drawinglayer/source/texture/texture.cxx +++ b/drawinglayer/source/texture/texture.cxx @@ -603,19 +603,16 @@ namespace drawinglayer namespace texture { GeoTexSvxTiled::GeoTexSvxTiled( - const basegfx::B2DPoint& rTopLeft, - const basegfx::B2DVector& rSize) - : maTopLeft(rTopLeft), - maSize(rSize) + const basegfx::B2DRange& rRange, + double fOffsetX, + double fOffsetY) + : maRange(rRange), + mfOffsetX(basegfx::clamp(fOffsetX, 0.0, 1.0)), + mfOffsetY(basegfx::clamp(fOffsetY, 0.0, 1.0)) { - if(basegfx::fTools::lessOrEqual(maSize.getX(), 0.0)) - { - maSize.setX(1.0); - } - - if(basegfx::fTools::lessOrEqual(maSize.getY(), 0.0)) + if(!basegfx::fTools::equalZero(mfOffsetX)) { - maSize.setY(1.0); + mfOffsetY = 0.0; } } @@ -626,48 +623,92 @@ namespace drawinglayer bool GeoTexSvxTiled::operator==(const GeoTexSvx& rGeoTexSvx) const { const GeoTexSvxTiled* pCompare = dynamic_cast< const GeoTexSvxTiled* >(&rGeoTexSvx); + return (pCompare - && maTopLeft == pCompare->maTopLeft - && maSize == pCompare->maSize); + && maRange == pCompare->maRange + && mfOffsetX == pCompare->mfOffsetX + && mfOffsetY == pCompare->mfOffsetY); } void GeoTexSvxTiled::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices) { - double fStartX(maTopLeft.getX()); - double fStartY(maTopLeft.getY()); + const double fWidth(maRange.getWidth()); - if(basegfx::fTools::more(fStartX, 0.0)) + if(!basegfx::fTools::equalZero(fWidth)) { - fStartX -= (floor(fStartX / maSize.getX()) + 1.0) * maSize.getX(); - } - - if(basegfx::fTools::less(fStartX + maSize.getX(), 0.0)) - { - fStartX += floor(-fStartX / maSize.getX()) * maSize.getX(); - } + const double fHeight(maRange.getHeight()); - if(basegfx::fTools::more(fStartY, 0.0)) - { - fStartY -= (floor(fStartY / maSize.getY()) + 1.0) * maSize.getY(); - } - - if(basegfx::fTools::less(fStartY + maSize.getY(), 0.0)) - { - fStartY += floor(-fStartY / maSize.getY()) * maSize.getY(); - } - - for(double fPosY(fStartY); basegfx::fTools::less(fPosY, 1.0); fPosY += maSize.getY()) - { - for(double fPosX(fStartX); basegfx::fTools::less(fPosX, 1.0); fPosX += maSize.getX()) + if(!basegfx::fTools::equalZero(fHeight)) { - basegfx::B2DHomMatrix aNew; - - aNew.set(0, 0, maSize.getX()); - aNew.set(1, 1, maSize.getY()); - aNew.set(0, 2, fPosX); - aNew.set(1, 2, fPosY); - - rMatrices.push_back(aNew); + double fStartX(maRange.getMinX()); + double fStartY(maRange.getMinY()); + sal_Int32 nPosX(0); + sal_Int32 nPosY(0); + + if(basegfx::fTools::more(fStartX, 0.0)) + { + const sal_Int32 nDiff(static_cast(floor(fStartX / fWidth)) + 1); + + nPosX -= nDiff; + fStartX -= nDiff * fWidth; + } + + if(basegfx::fTools::less(fStartX + fWidth, 0.0)) + { + const sal_Int32 nDiff(static_cast(floor(-fStartX / fWidth))); + + nPosX += nDiff; + fStartX += nDiff * fWidth; + } + + if(basegfx::fTools::more(fStartY, 0.0)) + { + const sal_Int32 nDiff(static_cast(floor(fStartY / fHeight)) + 1); + + nPosY -= nDiff; + fStartY -= nDiff * fHeight; + } + + if(basegfx::fTools::less(fStartY + fHeight, 0.0)) + { + const sal_Int32 nDiff(static_cast(floor(-fStartY / fHeight))); + + nPosY += nDiff; + fStartY += nDiff * fHeight; + } + + if(!basegfx::fTools::equalZero(mfOffsetY)) + { + for(double fPosX(fStartX); basegfx::fTools::less(fPosX, 1.0); fPosX += fWidth, nPosX++) + { + for(double fPosY(nPosX % 2 ? fStartY - fHeight + (mfOffsetY * fHeight) : fStartY); + basegfx::fTools::less(fPosY, 1.0); fPosY += fHeight) + { + rMatrices.push_back( + basegfx::tools::createScaleTranslateB2DHomMatrix( + fWidth, + fHeight, + fPosX, + fPosY)); + } + } + } + else + { + for(double fPosY(fStartY); basegfx::fTools::less(fPosY, 1.0); fPosY += fHeight, nPosY++) + { + for(double fPosX(nPosY % 2 ? fStartX - fWidth + (mfOffsetX * fWidth) : fStartX); + basegfx::fTools::less(fPosX, 1.0); fPosX += fWidth) + { + rMatrices.push_back( + basegfx::tools::createScaleTranslateB2DHomMatrix( + fWidth, + fHeight, + fPosX, + fPosY)); + } + } + } } } } diff --git a/drawinglayer/source/texture/texture3d.cxx b/drawinglayer/source/texture/texture3d.cxx index 88fa8bb6a6be..2e46508dbd71 100644 --- a/drawinglayer/source/texture/texture3d.cxx +++ b/drawinglayer/source/texture/texture3d.cxx @@ -27,7 +27,9 @@ namespace drawinglayer { namespace texture { - GeoTexSvxMono::GeoTexSvxMono(const basegfx::BColor& rSingleColor, double fOpacity) + GeoTexSvxMono::GeoTexSvxMono( + const basegfx::BColor& rSingleColor, + double fOpacity) : maSingleColor(rSingleColor), mfOpacity(fOpacity) { @@ -36,6 +38,7 @@ namespace drawinglayer bool GeoTexSvxMono::operator==(const GeoTexSvx& rGeoTexSvx) const { const GeoTexSvxMono* pCompare = dynamic_cast< const GeoTexSvxMono* >(&rGeoTexSvx); + return (pCompare && maSingleColor == pCompare->maSingleColor && mfOpacity == pCompare->mfOpacity); @@ -59,56 +62,144 @@ namespace drawinglayer { namespace texture { - GeoTexSvxBitmap::GeoTexSvxBitmap(const Bitmap& rBitmap, const basegfx::B2DPoint& rTopLeft, const basegfx::B2DVector& rSize) - : maBitmap(rBitmap), - mpRead(0L), - maTopLeft(rTopLeft), - maSize(rSize), + GeoTexSvxBitmapEx::GeoTexSvxBitmapEx( + const BitmapEx& rBitmapEx, + const basegfx::B2DRange& rRange) + : maBitmapEx(rBitmapEx), + mpReadBitmap(0), + maTransparence(), + mpReadTransparence(0), + maTopLeft(rRange.getMinimum()), + maSize(rRange.getRange()), mfMulX(0.0), - mfMulY(0.0) + mfMulY(0.0), + mbIsAlpha(false), + mbIsTransparent(maBitmapEx.IsTransparent()) + { + // #121194# Todo: use alpha channel, too (for 3d) + mpReadBitmap = maBitmapEx.GetBitmap().AcquireReadAccess(); + OSL_ENSURE(mpReadBitmap, "GeoTexSvxBitmapEx: Got no read access to Bitmap (!)"); + + if(mbIsTransparent) + { + if(maBitmapEx.IsAlpha()) + { + mbIsAlpha = true; + maTransparence = rBitmapEx.GetAlpha().GetBitmap(); + } + else + { + maTransparence = rBitmapEx.GetMask(); + } + + mpReadTransparence = maTransparence.AcquireReadAccess(); + } + + mfMulX = (double)mpReadBitmap->Width() / maSize.getX(); + mfMulY = (double)mpReadBitmap->Height() / maSize.getY(); + + if(maSize.getX() <= 1.0) + { + maSize.setX(1.0); + } + + if(maSize.getY() <= 1.0) + { + maSize.setY(1.0); + } + } + + GeoTexSvxBitmapEx::~GeoTexSvxBitmapEx() { - mpRead = maBitmap.AcquireReadAccess(); - OSL_ENSURE(mpRead, "GeoTexSvxBitmap: Got no read access to Bitmap (!)"); - mfMulX = (double)mpRead->Width() / maSize.getX(); - mfMulY = (double)mpRead->Height() / maSize.getY(); + delete mpReadTransparence; + delete mpReadBitmap; } - GeoTexSvxBitmap::~GeoTexSvxBitmap() + sal_uInt8 GeoTexSvxBitmapEx::impGetTransparence(sal_Int32& rX, sal_Int32& rY) const { - delete mpRead; + switch(maBitmapEx.GetTransparentType()) + { + case TRANSPARENT_NONE: + { + break; + } + case TRANSPARENT_COLOR: + { + const Color aColor(mpReadBitmap->GetColor(rY, rX)); + + if(maBitmapEx.GetTransparentColor() == aColor) + { + return 255; + } + + break; + } + case TRANSPARENT_BITMAP: + { + OSL_ENSURE(mpReadTransparence, "OOps, transparence type Bitmap, but no read access created in the constructor (?)"); + const BitmapColor aBitmapColor(mpReadTransparence->GetPixel(rY, rX)); + + if(mbIsAlpha) + { + return aBitmapColor.GetIndex(); + } + else + { + if(0x00 != aBitmapColor.GetIndex()) + { + return 255; + } + } + break; + } + } + + return 0; } - bool GeoTexSvxBitmap::impIsValid(const basegfx::B2DPoint& rUV, sal_Int32& rX, sal_Int32& rY) const + bool GeoTexSvxBitmapEx::impIsValid(const basegfx::B2DPoint& rUV, sal_Int32& rX, sal_Int32& rY) const { - if(mpRead) + if(mpReadBitmap) { rX = (sal_Int32)((rUV.getX() - maTopLeft.getX()) * mfMulX); - if(rX >= 0L && rX < mpRead->Width()) + if(rX >= 0L && rX < mpReadBitmap->Width()) { rY = (sal_Int32)((rUV.getY() - maTopLeft.getY()) * mfMulY); - return (rY >= 0L && rY < mpRead->Height()); + return (rY >= 0L && rY < mpReadBitmap->Height()); } } return false; } - void GeoTexSvxBitmap::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& rfOpacity) const + void GeoTexSvxBitmapEx::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& rfOpacity) const { sal_Int32 nX, nY; if(impIsValid(rUV, nX, nY)) { const double fConvertColor(1.0 / 255.0); - const BitmapColor aBMCol(mpRead->GetColor(nY, nX)); + const BitmapColor aBMCol(mpReadBitmap->GetColor(nY, nX)); const basegfx::BColor aBSource( (double)aBMCol.GetRed() * fConvertColor, (double)aBMCol.GetGreen() * fConvertColor, (double)aBMCol.GetBlue() * fConvertColor); rBColor = aBSource; + + if(mbIsTransparent) + { + // when we have a transparence, make use of it + const sal_uInt8 aLuminance(impGetTransparence(nX, nY)); + + rfOpacity = ((double)(0xff - aLuminance) * (1.0 / 255.0)); + } + else + { + rfOpacity = 1.0; + } } else { @@ -116,16 +207,28 @@ namespace drawinglayer } } - void GeoTexSvxBitmap::modifyOpacity(const basegfx::B2DPoint& rUV, double& rfOpacity) const + void GeoTexSvxBitmapEx::modifyOpacity(const basegfx::B2DPoint& rUV, double& rfOpacity) const { sal_Int32 nX, nY; if(impIsValid(rUV, nX, nY)) { - const BitmapColor aBMCol(mpRead->GetColor(nY, nX)); - const Color aColor(aBMCol.GetRed(), aBMCol.GetGreen(), aBMCol.GetBlue()); + if(mbIsTransparent) + { + // this texture has an alpha part, use it + const sal_uInt8 aLuminance(impGetTransparence(nX, nY)); + const double fNewOpacity((double)(0xff - aLuminance) * (1.0 / 255.0)); + + rfOpacity = 1.0 - ((1.0 - fNewOpacity) * (1.0 - rfOpacity)); + } + else + { + // this texture is a color bitmap used as transparence map + const BitmapColor aBMCol(mpReadBitmap->GetColor(nY, nX)); + const Color aColor(aBMCol.GetRed(), aBMCol.GetGreen(), aBMCol.GetBlue()); - rfOpacity = ((double)(0xff - aColor.GetLuminance()) * (1.0 / 255.0)); + rfOpacity = ((double)(0xff - aColor.GetLuminance()) * (1.0 / 255.0)); + } } else { @@ -141,24 +244,72 @@ namespace drawinglayer { namespace texture { - GeoTexSvxBitmapTiled::GeoTexSvxBitmapTiled(const Bitmap& rBitmap, const basegfx::B2DPoint& rTopLeft, const basegfx::B2DVector& rSize) - : GeoTexSvxBitmap(rBitmap, rTopLeft, rSize) + basegfx::B2DPoint GeoTexSvxBitmapExTiled::impGetCorrected(const basegfx::B2DPoint& rUV) const + { + double fX(rUV.getX() - maTopLeft.getX()); + double fY(rUV.getY() - maTopLeft.getY()); + + if(mbUseOffsetX) + { + const sal_Int32 nCol(static_cast< sal_Int32 >((fY < 0.0 ? maSize.getY() -fY : fY) / maSize.getY())); + + if(nCol % 2) + { + fX += mfOffsetX * maSize.getX(); + } + } + else if(mbUseOffsetY) + { + const sal_Int32 nRow(static_cast< sal_Int32 >((fX < 0.0 ? maSize.getX() -fX : fX) / maSize.getX())); + + if(nRow % 2) + { + fY += mfOffsetY * maSize.getY(); + } + } + + fX = fmod(fX, maSize.getX()); + fY = fmod(fY, maSize.getY()); + + if(fX < 0.0) + { + fX += maSize.getX(); + } + + if(fY < 0.0) + { + fY += maSize.getY(); + } + + return basegfx::B2DPoint(fX + maTopLeft.getX(), fY + maTopLeft.getY()); + } + + GeoTexSvxBitmapExTiled::GeoTexSvxBitmapExTiled( + const BitmapEx& rBitmapEx, + const basegfx::B2DRange& rRange, + double fOffsetX, + double fOffsetY) + : GeoTexSvxBitmapEx(rBitmapEx, rRange), + mfOffsetX(basegfx::clamp(fOffsetX, 0.0, 1.0)), + mfOffsetY(basegfx::clamp(fOffsetY, 0.0, 1.0)), + mbUseOffsetX(!basegfx::fTools::equalZero(mfOffsetX)), + mbUseOffsetY(!mbUseOffsetX && !basegfx::fTools::equalZero(mfOffsetY)) { } - void GeoTexSvxBitmapTiled::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& rfOpacity) const + void GeoTexSvxBitmapExTiled::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& rfOpacity) const { - if(mpRead) + if(mpReadBitmap) { - GeoTexSvxBitmap::modifyBColor(impGetCorrected(rUV), rBColor, rfOpacity); + GeoTexSvxBitmapEx::modifyBColor(impGetCorrected(rUV), rBColor, rfOpacity); } } - void GeoTexSvxBitmapTiled::modifyOpacity(const basegfx::B2DPoint& rUV, double& rfOpacity) const + void GeoTexSvxBitmapExTiled::modifyOpacity(const basegfx::B2DPoint& rUV, double& rfOpacity) const { - if(mpRead) + if(mpReadBitmap) { - GeoTexSvxBitmap::modifyOpacity(impGetCorrected(rUV), rfOpacity); + GeoTexSvxBitmapEx::modifyOpacity(impGetCorrected(rUV), rfOpacity); } } } // end of namespace texture @@ -170,7 +321,9 @@ namespace drawinglayer { namespace texture { - GeoTexSvxMultiHatch::GeoTexSvxMultiHatch(const primitive3d::HatchTexturePrimitive3D& rPrimitive, double fLogicPixelSize) + GeoTexSvxMultiHatch::GeoTexSvxMultiHatch( + const primitive3d::HatchTexturePrimitive3D& rPrimitive, + double fLogicPixelSize) : mfLogicPixelSize(fLogicPixelSize), mp0(0L), mp1(0L), diff --git a/include/drawinglayer/attribute/fillgraphicattribute.hxx b/include/drawinglayer/attribute/fillgraphicattribute.hxx new file mode 100644 index 000000000000..55a8d8933f7d --- /dev/null +++ b/include/drawinglayer/attribute/fillgraphicattribute.hxx @@ -0,0 +1,85 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_DRAWINGLAYER_ATTRIBUTE_FILLGRAPHICATTRIBUTE_HXX +#define INCLUDED_DRAWINGLAYER_ATTRIBUTE_FILLGRAPHICATTRIBUTE_HXX + +#include +#include + +////////////////////////////////////////////////////////////////////////////// +// predefines + +class Graphic; + +namespace basegfx { + class B2DRange; +} + +namespace drawinglayer { namespace attribute { + class ImpFillGraphicAttribute; +}} + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace attribute + { + class DRAWINGLAYER_DLLPUBLIC FillGraphicAttribute + { + public: + typedef o3tl::cow_wrapper< ImpFillGraphicAttribute > ImplType; + + private: + ImplType mpFillGraphicAttribute; + + public: + /// constructors/assignmentoperator/destructor + FillGraphicAttribute( + const Graphic& rGraphic, + const basegfx::B2DRange& rGraphicRange, + bool bTiling = false, + double fOffsetX = 0.0, + double fOffsetY = 0.0); + FillGraphicAttribute(); + FillGraphicAttribute(const FillGraphicAttribute& rCandidate); + FillGraphicAttribute& operator=(const FillGraphicAttribute& rCandidate); + ~FillGraphicAttribute(); + + // checks if the incarnation is default constructed + bool isDefault() const; + + // compare operator + bool operator==(const FillGraphicAttribute& rCandidate) const; + + // data read access + const Graphic& getGraphic() const; + const basegfx::B2DRange& getGraphicRange() const; + bool getTiling() const; + double getOffsetX() const; + double getOffsetY() const; + }; + } // end of namespace attribute +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// + +#endif //INCLUDED_DRAWINGLAYER_ATTRIBUTE_FILLGRAPHICATTRIBUTE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/drawinglayer/attribute/sdrfillattribute.hxx b/include/drawinglayer/attribute/sdrfillattribute.hxx index 7fd3d38c224e..a0dee88030bc 100644 --- a/include/drawinglayer/attribute/sdrfillattribute.hxx +++ b/include/drawinglayer/attribute/sdrfillattribute.hxx @@ -34,7 +34,7 @@ namespace drawinglayer { namespace attribute { class ImpSdrFillAttribute; class FillGradientAttribute; class FillHatchAttribute; - class SdrFillBitmapAttribute; + class SdrFillGraphicAttribute; }} ////////////////////////////////////////////////////////////////////////////// @@ -58,7 +58,7 @@ namespace drawinglayer const basegfx::BColor& rColor, const FillGradientAttribute& rGradient, const FillHatchAttribute& rHatch, - const SdrFillBitmapAttribute& rBitmap); + const SdrFillGraphicAttribute& rFillGraphic); SdrFillAttribute(); SdrFillAttribute(const SdrFillAttribute& rCandidate); SdrFillAttribute& operator=(const SdrFillAttribute& rCandidate); @@ -75,7 +75,7 @@ namespace drawinglayer const basegfx::BColor& getColor() const; const FillGradientAttribute& getGradient() const; const FillHatchAttribute& getHatch() const; - const SdrFillBitmapAttribute& getBitmap() const; + const SdrFillGraphicAttribute& getFillGraphic() const; }; } // end of namespace attribute } // end of namespace drawinglayer diff --git a/include/drawinglayer/attribute/sdrfillbitmapattribute.hxx b/include/drawinglayer/attribute/sdrfillbitmapattribute.hxx deleted file mode 100644 index 78417f3577c9..000000000000 --- a/include/drawinglayer/attribute/sdrfillbitmapattribute.hxx +++ /dev/null @@ -1,96 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_DRAWINGLAYER_ATTRIBUTE_SDRFILLBITMAPATTRIBUTE_HXX -#define INCLUDED_DRAWINGLAYER_ATTRIBUTE_SDRFILLBITMAPATTRIBUTE_HXX - -#include -#include - -////////////////////////////////////////////////////////////////////////////// -// predefines - -class BitmapEx; - -namespace basegfx { - class B2DRange; - class B2DVector; -} - -namespace drawinglayer { namespace attribute { - class FillBitmapAttribute; - class ImpSdrFillBitmapAttribute; -}} - -////////////////////////////////////////////////////////////////////////////// - -namespace drawinglayer -{ - namespace attribute - { - class DRAWINGLAYER_DLLPUBLIC SdrFillBitmapAttribute - { - public: - typedef o3tl::cow_wrapper< ImpSdrFillBitmapAttribute > ImplType; - - private: - ImplType mpSdrFillBitmapAttribute; - - public: - /// constructors/assignmentoperator/destructor - SdrFillBitmapAttribute( - const BitmapEx& rBitmapEx, - const basegfx::B2DVector& rSize, - const basegfx::B2DVector& rOffset, - const basegfx::B2DVector& rOffsetPosition, - const basegfx::B2DVector& rRectPoint, - bool bTiling, - bool bStretch, - bool bLogSize); - SdrFillBitmapAttribute(); - SdrFillBitmapAttribute(const SdrFillBitmapAttribute& rCandidate); - SdrFillBitmapAttribute& operator=(const SdrFillBitmapAttribute& rCandidate); - ~SdrFillBitmapAttribute(); - - // checks if the incarnation is default constructed - bool isDefault() const; - - // compare operator - bool operator==(const SdrFillBitmapAttribute& rCandidate) const; - - // data read access - const BitmapEx& getBitmapEx() const; - const basegfx::B2DVector& getSize() const; - const basegfx::B2DVector& getOffset() const; - const basegfx::B2DVector& getOffsetPosition() const; - const basegfx::B2DVector& getRectPoint() const; - bool getTiling() const; - bool getStretch() const; - - // FillBitmapAttribute generator - FillBitmapAttribute getFillBitmapAttribute(const basegfx::B2DRange& rRange) const; - }; - } // end of namespace attribute -} // end of namespace drawinglayer - -////////////////////////////////////////////////////////////////////////////// - -#endif //INCLUDED_DRAWINGLAYER_ATTRIBUTE_SDRFILLBITMAPATTRIBUTE_HXX - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/drawinglayer/attribute/sdrfillgraphicattribute.hxx b/include/drawinglayer/attribute/sdrfillgraphicattribute.hxx new file mode 100644 index 000000000000..600db24f7cea --- /dev/null +++ b/include/drawinglayer/attribute/sdrfillgraphicattribute.hxx @@ -0,0 +1,96 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_DRAWINGLAYER_ATTRIBUTE_SDRFILLGRAPHICATTRIBUTE_HXX +#define INCLUDED_DRAWINGLAYER_ATTRIBUTE_SDRFILLGRAPHICATTRIBUTE_HXX + +#include +#include + +////////////////////////////////////////////////////////////////////////////// +// predefines + +class Graphic; + +namespace basegfx { + class B2DRange; + class B2DVector; +} + +namespace drawinglayer { namespace attribute { + class FillGraphicAttribute; + class ImpSdrFillGraphicAttribute; +}} + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace attribute + { + class DRAWINGLAYER_DLLPUBLIC SdrFillGraphicAttribute + { + public: + typedef o3tl::cow_wrapper< ImpSdrFillGraphicAttribute > ImplType; + + private: + ImplType mpSdrFillGraphicAttribute; + + public: + /// constructors/assignmentoperator/destructor + SdrFillGraphicAttribute( + const Graphic& rFillGraphic, + const basegfx::B2DVector& rSize, + const basegfx::B2DVector& rOffset, + const basegfx::B2DVector& rOffsetPosition, + const basegfx::B2DVector& rRectPoint, + bool bTiling, + bool bStretch, + bool bLogSize); + SdrFillGraphicAttribute(); + SdrFillGraphicAttribute(const SdrFillGraphicAttribute& rCandidate); + SdrFillGraphicAttribute& operator=(const SdrFillGraphicAttribute& rCandidate); + ~SdrFillGraphicAttribute(); + + // checks if the incarnation is default constructed + bool isDefault() const; + + // compare operator + bool operator==(const SdrFillGraphicAttribute& rCandidate) const; + + // data read access + const Graphic& getFillGraphic() const; + const basegfx::B2DVector& getSize() const; + const basegfx::B2DVector& getOffset() const; + const basegfx::B2DVector& getOffsetPosition() const; + const basegfx::B2DVector& getRectPoint() const; + bool getTiling() const; + bool getStretch() const; + bool getLogSize() const; + + // FillGraphicAttribute generator + FillGraphicAttribute createFillGraphicAttribute(const basegfx::B2DRange& rRange) const; + }; + } // end of namespace attribute +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// + +#endif //INCLUDED_DRAWINGLAYER_ATTRIBUTE_SDRFILLGRAPHICATTRIBUTE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx b/include/drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx index a3af5cbb04e1..c6467f482c70 100644 --- a/include/drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx +++ b/include/drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx @@ -40,7 +40,7 @@ #define PRIMITIVE2D_ID_BITMAPPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 5) #define PRIMITIVE2D_ID_CONTROLPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 6) #define PRIMITIVE2D_ID_EMBEDDED3DPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 7) -#define PRIMITIVE2D_ID_FILLBITMAPPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 8) +#define PRIMITIVE2D_ID_FILLGRAPHICPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 8) #define PRIMITIVE2D_ID_FILLGRADIENTPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 9) #define PRIMITIVE2D_ID_FILLHATCHPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 10) #define PRIMITIVE2D_ID_GRAPHICPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 11) @@ -61,7 +61,7 @@ #define PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 26) #define PRIMITIVE2D_ID_POLYPOLYGONGRADIENTPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 27) #define PRIMITIVE2D_ID_POLYPOLYGONHATCHPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 28) -#define PRIMITIVE2D_ID_POLYPOLYGONBITMAPPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 29) +#define PRIMITIVE2D_ID_POLYPOLYGONGRAPHICPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 29) #define PRIMITIVE2D_ID_SCENEPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 30) #define PRIMITIVE2D_ID_SHADOWPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 31) #define PRIMITIVE2D_ID_TEXTSIMPLEPORTIONPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 32) diff --git a/include/drawinglayer/primitive2d/fillgraphicprimitive2d.hxx b/include/drawinglayer/primitive2d/fillgraphicprimitive2d.hxx new file mode 100644 index 000000000000..17b8c5c6cac3 --- /dev/null +++ b/include/drawinglayer/primitive2d/fillgraphicprimitive2d.hxx @@ -0,0 +1,87 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_DRAWINGLAYER_PRIMITIVE2D_FILLGRAPHICPRIMITIVE2D_HXX +#define INCLUDED_DRAWINGLAYER_PRIMITIVE2D_FILLGRAPHICPRIMITIVE2D_HXX + +#include + +#include +#include +#include + +////////////////////////////////////////////////////////////////////////////// +// FillbitmapPrimitive2D class + +namespace drawinglayer +{ + namespace primitive2d + { + /** FillGraphicPrimitive2D class + + This class defines a bitmap filling for a rectangular area. The + Range is defined by the Transformation, the fill by the FillGraphicAttribute. + There, the fill consists of a Bitmap (not transparent) defining the fill data + and a Point/Vector pair defining the relative position/size [0.0 .. 1.0] + inside the area where the bitmap is positioned. A flag defines then if this + is tiled or not. + + Renderers should handle this primitive; it has a geometrically correct + decomposition, but on pixel oututs the areas where the tiled pieces are + aligned tend to show up (one overlapping or empty pixel) + */ + class DRAWINGLAYER_DLLPUBLIC FillGraphicPrimitive2D : public BufferedDecompositionPrimitive2D + { + private: + /// the geometric definition + basegfx::B2DHomMatrix maTransformation; + + /// the fill attributes + attribute::FillGraphicAttribute maFillGraphic; + + protected: + /// local decomposition. + virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + + public: + /// constructor + FillGraphicPrimitive2D( + const basegfx::B2DHomMatrix& rTransformation, + const attribute::FillGraphicAttribute& rFillGraphic); + + /// data read access + const basegfx::B2DHomMatrix& getTransformation() const { return maTransformation; } + const attribute::FillGraphicAttribute& getFillGraphic() const { return maFillGraphic; } + + /// compare operator + virtual bool operator==( const BasePrimitive2D& rPrimitive ) const; + + /// get range + virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const; + + /// provide unique ID + DeclPrimitive2DIDBlock() + }; + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// + +#endif //INCLUDED_DRAWINGLAYER_PRIMITIVE2D_FILLGRAPHICPRIMITIVE2D_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/drawinglayer/primitive2d/graphicprimitivehelper2d.hxx b/include/drawinglayer/primitive2d/graphicprimitivehelper2d.hxx new file mode 100644 index 000000000000..9755a2dd21de --- /dev/null +++ b/include/drawinglayer/primitive2d/graphicprimitivehelper2d.hxx @@ -0,0 +1,54 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_DRAWINGLAYER_PRIMITIVE2D_GRAPHICPRIMITIVEHELPER2D_HXX +#define INCLUDED_DRAWINGLAYER_PRIMITIVE2D_GRAPHICPRIMITIVEHELPER2D_HXX + +#include +#include + +////////////////////////////////////////////////////////////////////////////// +// predefines + +class Graphic; + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + /** Helper method with supports decomposing a Graphic with all + possible contents to lower level primitives. + + #i121194# Unified to use this helper for FillGraphicPrimitive2D + and GraphicPrimitive2D at the same time. It is able to handle + Bitmaps (with the sub-categories animated bitmap, and SVG), + and Metafiles. + */ + Primitive2DSequence create2DDecompositionOfGraphic( + const Graphic& rGraphic, + const basegfx::B2DHomMatrix& rTransform); + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// + +#endif // INCLUDED_DRAWINGLAYER_PRIMITIVE2D_GRAPHICPRIMITIVEHELPER2D_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/drawinglayer/primitive2d/polypolygonprimitive2d.hxx b/include/drawinglayer/primitive2d/polypolygonprimitive2d.hxx index 6284b8867eff..0679ce4deb8c 100644 --- a/include/drawinglayer/primitive2d/polypolygonprimitive2d.hxx +++ b/include/drawinglayer/primitive2d/polypolygonprimitive2d.hxx @@ -23,7 +23,7 @@ #include #include -#include +#include #include #include #include @@ -331,26 +331,26 @@ namespace drawinglayer } // end of namespace drawinglayer ////////////////////////////////////////////////////////////////////////////// -// PolyPolygonBitmapPrimitive2D class +// PolyPolygonGraphicPrimitive2D class namespace drawinglayer { namespace primitive2d { - /** PolyPolygonBitmapPrimitive2D class + /** PolyPolygonGraphicPrimitive2D class This primitive defines a PolyPolygon filled with bitmap data (including transparence). The decomosition will create a MaskPrimitive2D - containing a FillBitmapPrimitive2D. + containing a FillGraphicPrimitive2D. */ - class DRAWINGLAYER_DLLPUBLIC PolyPolygonBitmapPrimitive2D : public BufferedDecompositionPrimitive2D + class DRAWINGLAYER_DLLPUBLIC PolyPolygonGraphicPrimitive2D : public BufferedDecompositionPrimitive2D { private: /// the PolyPolygon geometry basegfx::B2DPolyPolygon maPolyPolygon; /// the bitmap fill definition (may include tiling) - attribute::FillBitmapAttribute maFillBitmap; + attribute::FillGraphicAttribute maFillGraphic; protected: /// local decomposition. @@ -358,13 +358,13 @@ namespace drawinglayer public: /// constructor - PolyPolygonBitmapPrimitive2D( + PolyPolygonGraphicPrimitive2D( const basegfx::B2DPolyPolygon& rPolyPolygon, - const attribute::FillBitmapAttribute& rFillBitmap); + const attribute::FillGraphicAttribute& rFillGraphic); /// data read access const basegfx::B2DPolyPolygon& getB2DPolyPolygon() const { return maPolyPolygon; } - const attribute::FillBitmapAttribute& getFillBitmap() const { return maFillBitmap; } + const attribute::FillGraphicAttribute& getFillGraphic() const { return maFillGraphic; } /// compare operator virtual bool operator==(const BasePrimitive2D& rPrimitive) const; diff --git a/include/drawinglayer/primitive3d/textureprimitive3d.hxx b/include/drawinglayer/primitive3d/textureprimitive3d.hxx index 4296f0fe5bbb..ab0798b0965b 100644 --- a/include/drawinglayer/primitive3d/textureprimitive3d.hxx +++ b/include/drawinglayer/primitive3d/textureprimitive3d.hxx @@ -23,7 +23,7 @@ #include #include -#include +#include #include #include #include @@ -169,19 +169,19 @@ namespace drawinglayer { private: /// bitmap fill attribute - attribute::FillBitmapAttribute maFillBitmapAttribute; + attribute::FillGraphicAttribute maFillGraphicAttribute; public: /// constructor BitmapTexturePrimitive3D( - const attribute::FillBitmapAttribute& rFillBitmapAttribute, + const attribute::FillGraphicAttribute& rFillGraphicAttribute, const Primitive3DSequence& rChildren, const basegfx::B2DVector& rTextureSize, bool bModulate, bool bFilter); /// data read access - const attribute::FillBitmapAttribute& getFillBitmapAttribute() const { return maFillBitmapAttribute; } + const attribute::FillGraphicAttribute& getFillGraphicAttribute() const { return maFillGraphicAttribute; } /// compare operator virtual bool operator==(const BasePrimitive3D& rPrimitive) const; diff --git a/include/drawinglayer/processor2d/vclprocessor2d.hxx b/include/drawinglayer/processor2d/vclprocessor2d.hxx index 32dafbc42b0a..aa0d8782fa3c 100644 --- a/include/drawinglayer/processor2d/vclprocessor2d.hxx +++ b/include/drawinglayer/processor2d/vclprocessor2d.hxx @@ -35,9 +35,9 @@ namespace drawinglayer { namespace primitive2d { class TextSimplePortionPrimitive2D; class PolygonHairlinePrimitive2D; class BitmapPrimitive2D; - class FillBitmapPrimitive2D; + class FillGraphicPrimitive2D; class PolyPolygonGradientPrimitive2D; - class PolyPolygonBitmapPrimitive2D; + class PolyPolygonGraphicPrimitive2D; class PolyPolygonColorPrimitive2D; class MetafilePrimitive2D; class MaskPrimitive2D; @@ -93,9 +93,9 @@ namespace drawinglayer void RenderTextSimpleOrDecoratedPortionPrimitive2D(const primitive2d::TextSimplePortionPrimitive2D& rTextCandidate); void RenderPolygonHairlinePrimitive2D(const primitive2d::PolygonHairlinePrimitive2D& rPolygonCandidate, bool bPixelBased); void RenderBitmapPrimitive2D(const primitive2d::BitmapPrimitive2D& rBitmapCandidate); - void RenderFillBitmapPrimitive2D(const primitive2d::FillBitmapPrimitive2D& rFillBitmapCandidate); + void RenderFillGraphicPrimitive2D(const primitive2d::FillGraphicPrimitive2D& rFillBitmapCandidate); void RenderPolyPolygonGradientPrimitive2D(const primitive2d::PolyPolygonGradientPrimitive2D& rPolygonCandidate); - void RenderPolyPolygonBitmapPrimitive2D(const primitive2d::PolyPolygonBitmapPrimitive2D& rPolygonCandidate); + void RenderPolyPolygonGraphicPrimitive2D(const primitive2d::PolyPolygonGraphicPrimitive2D& rPolygonCandidate); void RenderPolyPolygonColorPrimitive2D(const primitive2d::PolyPolygonColorPrimitive2D& rPolygonCandidate); void RenderMetafilePrimitive2D(const primitive2d::MetafilePrimitive2D& rPolygonCandidate); void RenderMaskPrimitive2DPixel(const primitive2d::MaskPrimitive2D& rMaskCandidate); diff --git a/include/drawinglayer/texture/texture.hxx b/include/drawinglayer/texture/texture.hxx index b22e61d12be8..994a04f89e57 100644 --- a/include/drawinglayer/texture/texture.hxx +++ b/include/drawinglayer/texture/texture.hxx @@ -306,16 +306,27 @@ namespace drawinglayer { namespace texture { + // This class applies a tiling to the unit range. The given range + // will be repeated inside the unit range in X and Y and for each + // tile a matrix will be created (by appendTransformations) that + // represents the needed transformation to map a filling in unit + // coordinates to that tile. + // When offsetX is given, every 2nd line will be ofsetted by the + // given percentage value (offsetX has to be 0.0 <= offsetX <= 1.0). + // Accordingly to offsetY. If both are given, offsetX is preferred + // and offsetY is ignored. class DRAWINGLAYER_DLLPUBLIC GeoTexSvxTiled : public GeoTexSvx { protected: - basegfx::B2DPoint maTopLeft; - basegfx::B2DVector maSize; + basegfx::B2DRange maRange; + double mfOffsetX; + double mfOffsetY; public: GeoTexSvxTiled( - const basegfx::B2DPoint& rTopLeft, - const basegfx::B2DVector& rSize); + const basegfx::B2DRange& rRange, + double fOffsetX = 0.0, + double fOffsetY = 0.0); virtual ~GeoTexSvxTiled(); // compare operator diff --git a/include/drawinglayer/texture/texture3d.hxx b/include/drawinglayer/texture/texture3d.hxx index 713cea76c928..c51845c52220 100644 --- a/include/drawinglayer/texture/texture3d.hxx +++ b/include/drawinglayer/texture/texture3d.hxx @@ -23,7 +23,7 @@ #include #include -#include +#include ////////////////////////////////////////////////////////////////////////////// // predeclarations @@ -45,7 +45,9 @@ namespace drawinglayer double mfOpacity; public: - GeoTexSvxMono(const basegfx::BColor& rSingleColor, double fOpacity); + GeoTexSvxMono( + const basegfx::BColor& rSingleColor, + double fOpacity); // compare operator virtual bool operator==(const GeoTexSvx& rGeoTexSvx) const; @@ -61,22 +63,32 @@ namespace drawinglayer { namespace texture { - class DRAWINGLAYER_DLLPUBLIC GeoTexSvxBitmap : public GeoTexSvx + class DRAWINGLAYER_DLLPUBLIC GeoTexSvxBitmapEx : public GeoTexSvx { protected: - Bitmap maBitmap; - BitmapReadAccess* mpRead; + BitmapEx maBitmapEx; + BitmapReadAccess* mpReadBitmap; + Bitmap maTransparence; + BitmapReadAccess* mpReadTransparence; basegfx::B2DPoint maTopLeft; basegfx::B2DVector maSize; double mfMulX; double mfMulY; + /// bitfield + bool mbIsAlpha : 1; + bool mbIsTransparent : 1; + // helpers bool impIsValid(const basegfx::B2DPoint& rUV, sal_Int32& rX, sal_Int32& rY) const; + sal_uInt8 impGetTransparence(sal_Int32& rX, sal_Int32& rY) const; public: - GeoTexSvxBitmap(const Bitmap& rBitmap, const basegfx::B2DPoint& rTopLeft, const basegfx::B2DVector& rSize); - virtual ~GeoTexSvxBitmap(); + GeoTexSvxBitmapEx( + const BitmapEx& rBitmapEx, + const basegfx::B2DRange& rRange); + virtual ~GeoTexSvxBitmapEx(); + virtual void modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& rfOpacity) const; virtual void modifyOpacity(const basegfx::B2DPoint& rUV, double& rfOpacity) const; }; @@ -89,30 +101,26 @@ namespace drawinglayer { namespace texture { - class DRAWINGLAYER_DLLPUBLIC GeoTexSvxBitmapTiled : public GeoTexSvxBitmap + class DRAWINGLAYER_DLLPUBLIC GeoTexSvxBitmapExTiled : public GeoTexSvxBitmapEx { protected: - // helpers - basegfx::B2DPoint impGetCorrected(const basegfx::B2DPoint& rUV) const - { - double fX(fmod(rUV.getX() - maTopLeft.getX(), maSize.getX())); - double fY(fmod(rUV.getY() - maTopLeft.getY(), maSize.getY())); + double mfOffsetX; + double mfOffsetY; - if(fX < 0.0) - { - fX += maSize.getX(); - } + /// bitfield + bool mbUseOffsetX : 1; + bool mbUseOffsetY : 1; - if(fY < 0.0) - { - fY += maSize.getY(); - } - - return basegfx::B2DPoint(fX + maTopLeft.getX(), fY + maTopLeft.getY()); - } + // helpers + basegfx::B2DPoint impGetCorrected(const basegfx::B2DPoint& rUV) const; public: - GeoTexSvxBitmapTiled(const Bitmap& rBitmap, const basegfx::B2DPoint& rTopLeft, const basegfx::B2DVector& rSize); + GeoTexSvxBitmapExTiled( + const BitmapEx& rBitmapEx, + const basegfx::B2DRange& rRange, + double fOffsetX = 0.0, + double fOffsetY = 0.0); + virtual void modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& rfOpacity) const; virtual void modifyOpacity(const basegfx::B2DPoint& rUV, double& rfOpacity) const; }; diff --git a/include/svx/sdr/primitive2d/sdrattributecreator.hxx b/include/svx/sdr/primitive2d/sdrattributecreator.hxx index 1b3ade76f926..ae80a3aca8cb 100644 --- a/include/svx/sdr/primitive2d/sdrattributecreator.hxx +++ b/include/svx/sdr/primitive2d/sdrattributecreator.hxx @@ -35,7 +35,7 @@ namespace drawinglayer { namespace attribute { class SdrFillAttribute; class SdrTextAttribute; class FillGradientAttribute; - class SdrFillBitmapAttribute; + class SdrFillGraphicAttribute; class SdrShadowTextAttribute; class SdrLineShadowTextAttribute; class SdrLineFillShadowTextAttribute; @@ -81,7 +81,7 @@ namespace drawinglayer attribute::FillGradientAttribute createNewTransparenceGradientAttribute( const SfxItemSet& rSet); - attribute::SdrFillBitmapAttribute createNewSdrFillBitmapAttribute( + attribute::SdrFillGraphicAttribute createNewSdrFillGraphicAttribute( const SfxItemSet& rSet); attribute::SdrShadowTextAttribute createNewSdrShadowTextAttribute( diff --git a/include/vcl/graph.hxx b/include/vcl/graph.hxx index 4f1facae5395..ce48262f6e9b 100644 --- a/include/vcl/graph.hxx +++ b/include/vcl/graph.hxx @@ -52,17 +52,20 @@ private: unsigned mbUnlimitedSize : 1; // default is false unsigned mbAntiAliase : 1; // default is false unsigned mbSnapHorVerLines : 1; // default is false + unsigned mbScaleHighQuality : 1; // default is false public: GraphicConversionParameters( const Size& rSizePixel = Size(), bool bUnlimitedSize = false, bool bAntiAliase = false, - bool bSnapHorVerLines = false) + bool bSnapHorVerLines = false, + bool bScaleHighQuality = false) : maSizePixel(rSizePixel), mbUnlimitedSize(bUnlimitedSize), mbAntiAliase(bAntiAliase), - mbSnapHorVerLines(bSnapHorVerLines) + mbSnapHorVerLines(bSnapHorVerLines), + mbScaleHighQuality(bScaleHighQuality) { } @@ -71,6 +74,7 @@ public: bool getUnlimitedSize() const { return mbUnlimitedSize; } bool getAntiAliase() const { return mbAntiAliase; } bool getSnapHorVerLines() const { return mbSnapHorVerLines; } + bool getScaleHighQuality() const { return mbScaleHighQuality; } }; class VCL_DLLPUBLIC Graphic : public SvDataCopyStream diff --git a/svx/source/sdr/contact/viewobjectcontact.cxx b/svx/source/sdr/contact/viewobjectcontact.cxx index 479d09d50f63..b2443d6a381e 100644 --- a/svx/source/sdr/contact/viewobjectcontact.cxx +++ b/svx/source/sdr/contact/viewobjectcontact.cxx @@ -131,6 +131,12 @@ namespace case PRIMITIVE2D_ID_SDRPATHPRIMITIVE2D : case PRIMITIVE2D_ID_SDRRECTANGLEPRIMITIVE2D : + // #121194# With Graphic as Bitmap FillStyle, also check + // for primitives filled with animated graphics + case PRIMITIVE2D_ID_POLYPOLYGONGRAPHICPRIMITIVE2D: + case PRIMITIVE2D_ID_FILLGRAPHICPRIMITIVE2D: + case PRIMITIVE2D_ID_TRANSFORMPRIMITIVE2D: + // decompose evtl. animated text contained in MaskPrimitive2D // or group rimitives case PRIMITIVE2D_ID_MASKPRIMITIVE2D : diff --git a/svx/source/sdr/primitive2d/sdrattributecreator.cxx b/svx/source/sdr/primitive2d/sdrattributecreator.cxx index a6fd57358534..fcfba853bdf4 100644 --- a/svx/source/sdr/primitive2d/sdrattributecreator.cxx +++ b/svx/source/sdr/primitive2d/sdrattributecreator.cxx @@ -46,10 +46,10 @@ #include #include #include -#include +#include #include #include -#include +#include #include #include #include @@ -417,7 +417,7 @@ namespace drawinglayer const Color aColor(((const XFillColorItem&)(rSet.Get(XATTR_FILLCOLOR))).GetColorValue()); attribute::FillGradientAttribute aGradient; attribute::FillHatchAttribute aHatch; - attribute::SdrFillBitmapAttribute aBitmap; + attribute::SdrFillGraphicAttribute aFillGraphic; switch(eStyle) { @@ -480,7 +480,7 @@ namespace drawinglayer } case XFILL_BITMAP : { - aBitmap = createNewSdrFillBitmapAttribute(rSet); + aFillGraphic = createNewSdrFillGraphicAttribute(rSet); break; } } @@ -490,7 +490,7 @@ namespace drawinglayer aColor.getBColor(), aGradient, aHatch, - aBitmap); + aFillGraphic); } } @@ -610,44 +610,57 @@ namespace drawinglayer return attribute::FillGradientAttribute(); } - attribute::SdrFillBitmapAttribute createNewSdrFillBitmapAttribute(const SfxItemSet& rSet) + attribute::SdrFillGraphicAttribute createNewSdrFillGraphicAttribute(const SfxItemSet& rSet) { - BitmapEx aBitmapEx(((const XFillBitmapItem&)(rSet.Get(XATTR_FILLBITMAP))).GetGraphicObject().GetGraphic().GetBitmapEx()); + Graphic aGraphic(((const XFillBitmapItem&)(rSet.Get(XATTR_FILLBITMAP))).GetGraphicObject().GetGraphic()); - // make sure it's not empty, use default instead - if(aBitmapEx.IsEmpty()) + if(!(GRAPHIC_BITMAP == aGraphic.GetType() || GRAPHIC_GDIMETAFILE == aGraphic.GetType())) { - // #i118485# Add PrefMapMode and PrefSize to avoid mini-tiling and - // expensive primitive processing in this case. Use 10x10 cm - aBitmapEx = Bitmap(Size(4,4), 8); - aBitmapEx.SetPrefMapMode(MapMode(MAP_100TH_MM)); - aBitmapEx.SetPrefSize(Size(10000.0, 10000.0)); + // no content if not bitmap or metafile + OSL_ENSURE(false, "No fill graphic in SfxItemSet (!)"); + return attribute::SdrFillGraphicAttribute(); } - // if there is no logical size, create a size from pixel size and set MapMode accordingly - if(0L == aBitmapEx.GetPrefSize().Width() || 0L == aBitmapEx.GetPrefSize().Height()) + Size aPrefSize(aGraphic.GetPrefSize()); + + if(!aPrefSize.Width() || !aPrefSize.Height()) + { + // if there is no logical size, create a size from pixel size and set MapMode accordingly + if(GRAPHIC_BITMAP == aGraphic.GetType()) + { + aGraphic.SetPrefSize(aGraphic.GetBitmapEx().GetSizePixel()); + aGraphic.SetPrefMapMode(MAP_PIXEL); + } + } + + if(!aPrefSize.Width() || !aPrefSize.Height()) { - aBitmapEx.SetPrefSize(aBitmapEx.GetSizePixel()); - aBitmapEx.SetPrefMapMode(MAP_PIXEL); + // no content if no size + OSL_ENSURE(false, "Graphic has no size in SfxItemSet (!)"); + return attribute::SdrFillGraphicAttribute(); } - // convert size and MapMode to destination logical size and MapMode. The created - // bitmap must have a valid logical size (PrefSize) + // convert size and MapMode to destination logical size and MapMode const MapUnit aDestinationMapUnit((MapUnit)rSet.GetPool()->GetMetric(0)); - if(aBitmapEx.GetPrefMapMode() != aDestinationMapUnit) + if(aGraphic.GetPrefMapMode() != aDestinationMapUnit) { // #i100360# for MAP_PIXEL, LogicToLogic will not work properly, // so fallback to Application::GetDefaultDevice() - if(MAP_PIXEL == aBitmapEx.GetPrefMapMode().GetMapUnit()) + if(MAP_PIXEL == aGraphic.GetPrefMapMode().GetMapUnit()) { - aBitmapEx.SetPrefSize(Application::GetDefaultDevice()->PixelToLogic( - aBitmapEx.GetPrefSize(), aDestinationMapUnit)); + aGraphic.SetPrefSize( + Application::GetDefaultDevice()->PixelToLogic( + aGraphic.GetPrefSize(), + aDestinationMapUnit)); } else { - aBitmapEx.SetPrefSize(OutputDevice::LogicToLogic( - aBitmapEx.GetPrefSize(), aBitmapEx.GetPrefMapMode(), aDestinationMapUnit)); + aGraphic.SetPrefSize( + OutputDevice::LogicToLogic( + aGraphic.GetPrefSize(), + aGraphic.GetPrefMapMode(), + aDestinationMapUnit)); } } @@ -662,8 +675,8 @@ namespace drawinglayer (double)((const SfxUInt16Item&) (rSet.Get(XATTR_FILLBMP_POSOFFSETX))).GetValue(), (double)((const SfxUInt16Item&) (rSet.Get(XATTR_FILLBMP_POSOFFSETY))).GetValue()); - return attribute::SdrFillBitmapAttribute( - aBitmapEx, + return attribute::SdrFillGraphicAttribute( + aGraphic, aSize, aOffset, aOffsetPosition, diff --git a/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx b/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx index fe8320163241..047f5a77d452 100644 --- a/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx +++ b/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include #include @@ -74,10 +74,10 @@ namespace drawinglayer { pNewFillPrimitive = new PolyPolygonHatchPrimitive2D(aScaledPolyPolygon, rFill.getColor(), rFill.getHatch()); } - else if(!rFill.getBitmap().isDefault()) + else if(!rFill.getFillGraphic().isDefault()) { const basegfx::B2DRange aRange(basegfx::tools::getRange(aScaledPolyPolygon)); - pNewFillPrimitive = new PolyPolygonBitmapPrimitive2D(aScaledPolyPolygon, rFill.getBitmap().getFillBitmapAttribute(aRange)); + pNewFillPrimitive = new PolyPolygonGraphicPrimitive2D(aScaledPolyPolygon, rFill.getFillGraphic().createFillGraphicAttribute(aRange)); } else { diff --git a/svx/source/xoutdev/xattrbmp.cxx b/svx/source/xoutdev/xattrbmp.cxx index d2a556676611..85255918e682 100644 --- a/svx/source/xoutdev/xattrbmp.cxx +++ b/svx/source/xoutdev/xattrbmp.cxx @@ -606,6 +606,12 @@ bool XFillBitmapItem::PutValue( const ::com::sun::star::uno::Any& rVal, sal_uInt if( bSetURL ) { maGraphicObject = GraphicObject::CreateGraphicObjectFromURL(aURL); + + // #121194# Prefer GraphicObject over bitmap object if both are provided + if(bSetBitmap && GRAPHIC_NONE != maGraphicObject.GetType()) + { + bSetBitmap = false; + } } if( bSetBitmap ) { diff --git a/vcl/source/gdi/impgraph.cxx b/vcl/source/gdi/impgraph.cxx index 01d0341bfa49..2786b6deaa8f 100644 --- a/vcl/source/gdi/impgraph.cxx +++ b/vcl/source/gdi/impgraph.cxx @@ -579,7 +579,11 @@ BitmapEx ImpGraphic::ImplGetBitmapEx(const GraphicConversionParameters& rParamet aRetBmpEx = ( mpAnimation ? mpAnimation->GetBitmapEx() : maEx ); if(rParameters.getSizePixel().Width() || rParameters.getSizePixel().Height()) - aRetBmpEx.Scale(rParameters.getSizePixel()); + { + aRetBmpEx.Scale( + rParameters.getSizePixel(), + rParameters.getScaleHighQuality() ? BMP_SCALE_INTERPOLATE : BMP_SCALE_FAST); + } } else if( ( meType != GRAPHIC_DEFAULT ) && ImplIsSupportedGraphic() ) { -- cgit