diff options
author | Mathias Bauer <mba@openoffice.org> | 2010-01-21 13:49:22 +0100 |
---|---|---|
committer | Mathias Bauer <mba@openoffice.org> | 2010-01-21 13:49:22 +0100 |
commit | d5d854cc42815ff0bbe0347be4e28c8896048b8d (patch) | |
tree | 29000ef0d8c19f47b31d81dbca2fa3205e0ad3c7 /drawinglayer | |
parent | d668e9b58922429c5e16abc698520efdc32c7af8 (diff) | |
parent | 3b3e144c13a85b21b32904f245f44256c63e10e5 (diff) |
resync to DEV300_m70
Diffstat (limited to 'drawinglayer')
140 files changed, 8814 insertions, 2083 deletions
diff --git a/drawinglayer/inc/drawinglayer/attribute/fillbitmapattribute.hxx b/drawinglayer/inc/drawinglayer/attribute/fillbitmapattribute.hxx index 4e316232bd81..376e1d626927 100644 --- a/drawinglayer/inc/drawinglayer/attribute/fillbitmapattribute.hxx +++ b/drawinglayer/inc/drawinglayer/attribute/fillbitmapattribute.hxx @@ -36,7 +36,7 @@ #ifndef INCLUDED_DRAWINGLAYER_ATTRIBUTE_FILLBITMAPATTRIBUTE_HXX #define INCLUDED_DRAWINGLAYER_ATTRIBUTE_FILLBITMAPATTRIBUTE_HXX -#include <vcl/bitmap.hxx> +#include <vcl/bitmapex.hxx> #include <basegfx/point/b2dpoint.hxx> #include <basegfx/vector/b2dvector.hxx> @@ -56,7 +56,7 @@ namespace drawinglayer { class FillBitmapAttribute { - Bitmap maBitmap; + BitmapEx maBitmapEx; basegfx::B2DPoint maTopLeft; basegfx::B2DVector maSize; @@ -64,11 +64,15 @@ namespace drawinglayer unsigned mbTiling : 1; public: - FillBitmapAttribute(const Bitmap& rBitmap, const basegfx::B2DPoint& rTopLeft, const basegfx::B2DVector& rSize, bool bTiling); + FillBitmapAttribute( + const BitmapEx& rBitmapEx, + const basegfx::B2DPoint& rTopLeft, + const basegfx::B2DVector& rSize, + bool bTiling); bool operator==(const FillBitmapAttribute& rCandidate) const; // data access - const Bitmap& getBitmap() const { return maBitmap; } + 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; } diff --git a/drawinglayer/inc/drawinglayer/attribute/fontattribute.hxx b/drawinglayer/inc/drawinglayer/attribute/fontattribute.hxx new file mode 100644 index 000000000000..d8eed659f5e7 --- /dev/null +++ b/drawinglayer/inc/drawinglayer/attribute/fontattribute.hxx @@ -0,0 +1,129 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: strokeattribute.hxx,v $ + * + * $Revision: 1.5 $ + * + * last change: $Author: aw $ $Date: 2008-05-27 14:11:16 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef INCLUDED_DRAWINGLAYER_ATTRIBUTE_FONTATTRIBUTE_HXX +#define INCLUDED_DRAWINGLAYER_ATTRIBUTE_FONTATTRIBUTE_HXX + +#include <sal/config.h> +#include <sal/types.h> +#include <tools/string.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace attribute + { + /** FontAttribute class + + This attribute class is able to hold all parameters needed/used + to completely define the parametrisation of a text portion. + */ + class FontAttribute + { + private: + /// core data + String maFamilyName; // Font Family Name + String maStyleName; // Font Style Name + sal_uInt16 mnWeight; // Font weight + + /// bitfield + unsigned mbSymbol : 1; // Symbol Font Flag + unsigned mbVertical : 1; // Vertical Text Flag + unsigned mbItalic : 1; // Italic Flag + unsigned mbOutline : 1; // Outline Flag + unsigned mbRTL : 1; // RTL Flag + unsigned mbBiDiStrong : 1; // BiDi Flag + // TODO: pair kerning and CJK kerning + + public: + /// constructor + FontAttribute( + const String& rFamilyName, + const String& rStyleName, + sal_uInt16 nWeight, + bool bSymbol = false, + bool bVertical = false, + bool bItalic = false, + bool bOutline = false, + bool bRTL = false, + bool bBiDiStrong = false) + : maFamilyName(rFamilyName), + maStyleName(rStyleName), + mnWeight(nWeight), + mbSymbol(bSymbol), + mbVertical(bVertical), + mbItalic(bItalic), + mbOutline(bOutline), + mbRTL(bRTL), + mbBiDiStrong(bBiDiStrong) + { + } + + FontAttribute() + : maFamilyName(), + maStyleName(), + mnWeight(0), + mbSymbol(false), + mbVertical(false), + mbItalic(false), + mbOutline(false), + mbRTL(false), + mbBiDiStrong(false) + { + } + + /// compare operator + bool operator==(const FontAttribute& rCompare) const; + + /// data read access + const String& getFamilyName() const { return maFamilyName; } + const String& getStyleName() const { return maStyleName; } + sal_uInt16 getWeight() const { return mnWeight; } + bool getSymbol() const { return mbSymbol; } + bool getVertical() const { return mbVertical; } + bool getItalic() const { return mbItalic; } + bool getOutline() const { return mbOutline; } + bool getRTL() const { return mbRTL; } + bool getBiDiStrong() const { return mbBiDiStrong; } + }; + } // end of namespace attribute +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// + +#endif //INCLUDED_DRAWINGLAYER_ATTRIBUTE_FONTATTRIBUTE_HXX + +// eof diff --git a/drawinglayer/inc/drawinglayer/primitive2d/alphaprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/alphaprimitive2d.hxx index 6fdf3200543c..10288b70bd1b 100644 --- a/drawinglayer/inc/drawinglayer/primitive2d/alphaprimitive2d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive2d/alphaprimitive2d.hxx @@ -44,23 +44,52 @@ namespace drawinglayer { namespace primitive2d { + /** AlphaPrimitive2D class + + This is the basic primitive for applying freely defined transparence + to freely defined content. The basic idea is to associate a content + which is defined as a sequence of primitives and hold as child content + in the GroupPrimitive2D with an alpha channel also defined as a sequence + of primitives and hold in the Alpha member. + + The basic definition is to use the Alpha content as Alpha-Mask by + interpreting the Alpha-content not as RGB, but as Luminance alpha mask + using the common RGB_to_luminance definition as e.g. used by VCL. + + The defining geometry is the Range of the child primitive sequence, + this means the renderers will/shall use this geometric information for + rendering, not the alpha one. The alpha one should/will be clipped + accordingly. + */ class AlphaPrimitive2D : public GroupPrimitive2D { private: - Primitive2DSequence maAlpha; // transparence sequence + /// The Alpha-Mask who's RGB-Values are interpreted as Luminance + Primitive2DSequence maAlpha; public: + /** constructor + + @param rChildren + The content which is defined to have a transparency. The + range of this primitive is defined by this content + + @param rAlpha + The definition of the Alpha-channel for this primitive. It + will be interpreted as mask by interpreting as gray values + using the common RGB_to_luminance definitions + */ AlphaPrimitive2D( const Primitive2DSequence& rChildren, const Primitive2DSequence& rAlpha); - // get data + /// data read access const Primitive2DSequence& getAlpha() const { return maAlpha; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive2D& rPrimitive) const; - // provide unique ID + /// provide unique ID DeclPrimitrive2DIDBlock() }; } // end of namespace primitive2d diff --git a/drawinglayer/inc/drawinglayer/primitive2d/animatedprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/animatedprimitive2d.hxx index 41ae18b30fc9..cd6133dc54d8 100644 --- a/drawinglayer/inc/drawinglayer/primitive2d/animatedprimitive2d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive2d/animatedprimitive2d.hxx @@ -38,6 +38,7 @@ #include <drawinglayer/primitive2d/groupprimitive2d.hxx> #include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> ////////////////////////////////////////////////////////////////////////////// // predefines @@ -51,50 +52,59 @@ namespace drawinglayer { namespace primitive2d { + /** AnimatedSwitchPrimitive2D class + + This is the basic class for simple, animated primitives. The basic idea + is to have an animation definition (AnimationEntry) who's basic + functionality is to return a state value for any given animation time in + the range of [0.0 .. 1.0]. Depending on the state, the decomposition + calculates an index, which of the members of the child vector is to + be visualized. + + An example: For blinking, the Child vector should exist of two entries; + for values of [0.0 .. 0.5] the first, else the last entry will be used. + This mechanism is not limited to two entries, though. + */ class AnimatedSwitchPrimitive2D : public GroupPrimitive2D { private: - // the animation definition which allows translation of a point in time - // to an animation state [0.0 .. 1.0]. This member contains a cloned - // definition and is owned by this implementation + /** + The animation definition which allows translation of a point in time + to an animation state [0.0 .. 1.0]. This member contains a cloned + definition and is owned by this implementation. + */ animation::AnimationEntry* mpAnimationEntry; - // the last remembered decompose time, created and used by getDecomposition() for - // buffering purposes - double mfDecomposeViewTime; - - // bitfield - // flag if this is a text or graphic animation. Necessary since SdrViews need to differentiate - // between both types if they are on/off + /// bitfield + /** flag if this is a text or graphic animation. Necessary since SdrViews need to differentiate + between both types if they are on/off + */ unsigned mbIsTextAnimation : 1; - protected: - // create local decomposition - virtual Primitive2DSequence createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const; - public: + /// constructor AnimatedSwitchPrimitive2D( const animation::AnimationEntry& rAnimationEntry, const Primitive2DSequence& rChildren, bool bIsTextAnimation); + + /// destructor - needed due to mpAnimationEntry virtual ~AnimatedSwitchPrimitive2D(); - // get data + /// data read access const animation::AnimationEntry& getAnimationEntry() const { return *mpAnimationEntry; } bool isTextAnimation() const { return mbIsTextAnimation; } bool isGraphicAnimation() const { return !isTextAnimation(); } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive2D& rPrimitive) const; - // get range - virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const; - - // provide unique ID + /// provide unique ID DeclPrimitrive2DIDBlock() - // The getDecomposition is overloaded here since the decompose is dependent of the point in time, - // so the default implementation is nut useful here, it needs to be handled locally + /** The getDecomposition is overloaded here since the decompose is dependent of the point in time, + so the default implementation is nut useful here, it needs to be handled locally + */ virtual Primitive2DSequence get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; }; } // end of namespace primitive2d @@ -106,84 +116,63 @@ namespace drawinglayer { namespace primitive2d { + /** AnimatedBlinkPrimitive2D class + + Basically the same mechanism as in AnimatedSwitchPrimitive2D, but the + decomposition is specialized in delivering the children in the + range [0.0.. 0.5] and an empty sequence else + */ class AnimatedBlinkPrimitive2D : public AnimatedSwitchPrimitive2D { protected: - // create local decomposition - virtual Primitive2DSequence createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const; - public: + /// constructor AnimatedBlinkPrimitive2D( const animation::AnimationEntry& rAnimationEntry, const Primitive2DSequence& rChildren, bool bIsTextAnimation); - // provide unique ID + /// create local decomposition + virtual Primitive2DSequence get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + + /// provide unique ID DeclPrimitrive2DIDBlock() }; } // end of namespace primitive2d } // end of namespace drawinglayer ////////////////////////////////////////////////////////////////////////////// -// helper class for AnimatedInterpolatePrimitive2D namespace drawinglayer { namespace primitive2d { - class BufferedMatrixDecompose - { - private: - // the matrix itself - basegfx::B2DHomMatrix maB2DHomMatrix; - - // the decomposition - basegfx::B2DVector maScale; - basegfx::B2DVector maTranslate; - double mfRotate; - double mfShearX; - - // flag if already decomposed, used by ensureDecompose() - bool mbDecomposed; + /** AnimatedInterpolatePrimitive2D class - public: - BufferedMatrixDecompose(const basegfx::B2DHomMatrix& rMatrix); - void ensureDecompose() const; - - // data access - const basegfx::B2DHomMatrix& getB2DHomMatrix() const { return maB2DHomMatrix; } - const basegfx::B2DVector& getScale() const { return maScale; } - const basegfx::B2DVector& getTranslate() const { return maTranslate; } - double getRotate() const { return mfRotate; } - double getShearX() const { return mfShearX; } - }; - } // end of anonymous namespace -} // end of namespace drawinglayer - -////////////////////////////////////////////////////////////////////////////// - -namespace drawinglayer -{ - namespace primitive2d - { + Specialized on multi-step animations based on matrix transformations. The + Child sequelce will be embedded in a matrix transformation. That transformation + will be linearly combined from the decomposed values and the animation value + to allow a smooth animation. + */ class AnimatedInterpolatePrimitive2D : public AnimatedSwitchPrimitive2D { private: - // the transformations - std::vector< BufferedMatrixDecompose > maMatrixStack; + /// the transformations + std::vector< basegfx::tools::B2DHomMatrixBufferedDecompose > maMatrixStack; protected: - // create local decomposition - virtual Primitive2DSequence createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const; - public: + /// constructor AnimatedInterpolatePrimitive2D( const std::vector< basegfx::B2DHomMatrix >& rmMatrixStack, const animation::AnimationEntry& rAnimationEntry, const Primitive2DSequence& rChildren, bool bIsTextAnimation); - // provide unique ID + /// create local decomposition + virtual Primitive2DSequence get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + + /// provide unique ID DeclPrimitrive2DIDBlock() }; } // end of namespace primitive2d diff --git a/drawinglayer/inc/drawinglayer/primitive2d/backgroundcolorprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/backgroundcolorprimitive2d.hxx index 65977cfd4241..85cf5e236d4f 100644 --- a/drawinglayer/inc/drawinglayer/primitive2d/backgroundcolorprimitive2d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive2d/backgroundcolorprimitive2d.hxx @@ -46,35 +46,48 @@ namespace drawinglayer { namespace primitive2d { - class BackgroundColorPrimitive2D : public BasePrimitive2D + /** BackgroundColorPrimitive2D class + + This primitive is defined to fill the whole visible Viewport with + the given color (and thus decomposes to a filled polygon). This + makes it a view-depnendent primitive by definition. It only has + a valid decomposition if a valid Viewport is given in the + ViewInformation2D at decomposition time. + + It will try to buffer it's last decomposition using maLastViewport + to detect changes in the get2DDecomposition call. + */ + class BackgroundColorPrimitive2D : public BufferedDecompositionPrimitive2D { private: + /// the fill color to use basegfx::BColor maBColor; - // the last used viewInformation, used from getDecomposition for buffering + /// the last used viewInformation, used from getDecomposition for buffering basegfx::B2DRange maLastViewport; protected: - // create local decomposition - virtual Primitive2DSequence createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + /// create local decomposition + virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; public: + /// constructor BackgroundColorPrimitive2D( const basegfx::BColor& rBColor); - // get data + /// data read access const basegfx::BColor& getBColor() const { return maBColor; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive2D& rPrimitive) const; - // get 2d range + /// get B2Drange virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const; - // provide unique ID + /// provide unique ID DeclPrimitrive2DIDBlock() - // Overload standard getDecomposition call to be view-dependent here + /// Overload standard getDecomposition call to be view-dependent here virtual Primitive2DSequence get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; }; } // end of namespace primitive2d diff --git a/drawinglayer/inc/drawinglayer/primitive2d/baseprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/baseprimitive2d.hxx index b05c60394ecd..6cf45ffefe54 100644 --- a/drawinglayer/inc/drawinglayer/primitive2d/baseprimitive2d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive2d/baseprimitive2d.hxx @@ -43,16 +43,17 @@ #include <basegfx/range/b2drange.hxx> ////////////////////////////////////////////////////////////////////////////// -// defines for DeclPrimitrive2DIDBlock and ImplPrimitrive2DIDBlock -// Added to be able to simply change identification stuff later, e.g. add -// a identification string and/or ID to the interface and to the implementation -// ATM used to delclare implement getPrimitiveID() +/** defines for DeclPrimitrive2DIDBlock and ImplPrimitrive2DIDBlock + Added to be able to simply change identification stuff later, e.g. add + a identification string and/or ID to the interface and to the implementation + ATM used to delclare implement getPrimitive2DID() +*/ #define DeclPrimitrive2DIDBlock() \ - virtual sal_uInt32 getPrimitiveID() const; + virtual sal_uInt32 getPrimitive2DID() const; #define ImplPrimitrive2DIDBlock(TheClass, TheID) \ - sal_uInt32 TheClass::getPrimitiveID() const { return TheID; } + sal_uInt32 TheClass::getPrimitive2DID() const { return TheID; } ////////////////////////////////////////////////////////////////////////////// // predefines @@ -61,6 +62,13 @@ namespace drawinglayer { namespace geometry { class ViewInformation2D; }} +namespace drawinglayer { namespace primitive2d { + /// typedefs for basePrimitive2DImplBase, Primitive2DSequence and Primitive2DReference + typedef cppu::WeakComponentImplHelper1< ::com::sun::star::graphic::XPrimitive2D > BasePrimitive2DImplBase; + typedef ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XPrimitive2D > Primitive2DReference; + typedef ::com::sun::star::uno::Sequence< Primitive2DReference > Primitive2DSequence; +}} + ////////////////////////////////////////////////////////////////////////////// // basePrimitive2D class @@ -68,101 +76,222 @@ namespace drawinglayer { namespace primitive2d { - // typedefs for basePrimitive2DImplBase, Primitive2DSequence and Primitive2DReference - typedef cppu::WeakComponentImplHelper1< ::com::sun::star::graphic::XPrimitive2D > BasePrimitive2DImplBase; - typedef ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XPrimitive2D > Primitive2DReference; - typedef ::com::sun::star::uno::Sequence< Primitive2DReference > Primitive2DSequence; - - // base class for all C++ implementations of com::sun::star::graphic::XPrimitive2D. This class - // is strongly virtual due to the lack of getPrimitiveID() implementation. This is by purpose, this - // base class shall not be incarnated and be used directly as a XPrimitive2D. + /** BasePrimitive2D class + + Baseclass for all C++ implementations of com::sun::star::graphic::XPrimitive2D + + This class is strongly virtual due to the lack of getPrimitiveID() implementation. + This is by purpose, this base class shall not be incarnated and be used directly as + a XPrimitive2D. + + Is is derived from boost::noncopyable to make clear that a primitive is a read-only + instance and copying or changing values is not intended. The idea is to hold all data + needed for visualisation of this primitive in unchangeable form. + + It is derived from comphelper::OBaseMutex to have a Mutex at hand; in a base + implementation this may not be needed, but e.g. when buffering at last decomposition + in a local member, multiple threads may try to decompose at the same time, so locking + is needed to avoid race conditions seen from the UNO object implementation. + + A method to get a simplified representation is provided by get2DDecomposition. The + default implementation returns an empty sequence. The idea is that processors + using this primitive and do not know it, may get the decomposition and process + these instead. An example is e.g. a fat line, who's decomposition may contain + the geometric representation of that line using filled polygon prmimitives. When + the renderer knows how to handle fat lines, he may proccess this primitive directly; + if not he can use the decomposition. With this functionality, renderers may operate by + knowing only a small set of primitives. + + When a primitive does not implement get2DDecomposition, it is called a 'Basic Primitive' and + belongs to the set of primitives which a processor should be able to handle. Practice + will define this minimal sets of primitives. When defined and the concept is prooved, + unique UNO APIs may be defined/implemented for these set to allow more intense work + with primitives using UNO. + + Current Basic 2D Primitives are: + + - BitmapPrimitive2D (bitmap data, evtl. with alpha) + - MetafilePrimitive2D (VCL Metafile, currently no decomposition, but planned, so may vanish) + - PointArrayPrimitive2D (single points) + - PolygonHairlinePrimitive2D (hairline curves/polygons) + - PolyPolygonColorPrimitive2D (colored polygons) + + All other implemented primitives have a defined decomposition and can thus be + decomposed downt to this small set. + + A renderer implementing support for this minimal set of primitives can completely + render primitive-based visualisations. Of course, he also has to take states into account + which are representated by GroupPrimitive2D derivations, see groupprimitive2d.hxx + + To support getting the geometric BoundRect, getB2DRange is used. The default + implementation will use the get2DDecomposition result and merge a range from the + entries. Thus, an implementation is only necessary for the Basic Primitives, but + of course speedups are possible (and are used) by implementing the method at higher-level + primitives. + + For primitive identification, getPrimitiveID is used currently in this implementations + to allow a fast switch/case processing. This needs a unique identifier mechanism which + currently uses defines (see drawinglayer_primitivetypes2d.hxx). For UNO prmitive API + it will be needed to add a unique descriptor (Name?) later to the API. + + This base implementation provides mappings from the methods from XPrimitive2D + (getDecomposition/getRange) to the appropriate methods in the C++ implementations + (get2DDecomposition/getB2DRange). The PropertyValue ViewParameters is converted to + the appropriate C++ implementation class ViewInformation2D. + + This base class does not implement any buffering; e.g. buffering the decompositon + and/or the range. These may be buffered anytime since the definition is that the primitive + is read-only and thus unchangeable. This implies that the decomposition and/or getting + the range will lead to the same result as last time, under the precondition that + the parameter ViewInformation2D is the same as the last one. This is usually the case + for view-independent primitives which are defined by not using ViewInformation2D + in their get2DDecomposition/getB2DRange implementations. + */ class BasePrimitive2D : private boost::noncopyable, protected comphelper::OBaseMutex, public BasePrimitive2DImplBase { private: - // a sequence used for buffering the last createLocalDecomposition() result. Use - // the protected access methods to change. Only implementations of getDecomposition() - // should make use. - Primitive2DSequence maLocalDecomposition; - protected: - // access methods to maLocalDecomposition. The usage of this methods may allow - // later thread-safe stuff to be added if needed. Only to be used by getDecomposition() - // implementations for buffering the last decomposition. - const Primitive2DSequence& getLocalDecomposition() const { return maLocalDecomposition; } - void setLocalDecomposition(const Primitive2DSequence& rNew) { maLocalDecomposition = rNew; } - - // method which is to be used to implement the local decomposition of a 2D primitive. The default - // implementation will just return an empty decomposition - virtual Primitive2DSequence createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const; - public: - // constructor + // constructor/destructor BasePrimitive2D(); + virtual ~BasePrimitive2D(); - // the ==operator is mainly needed to allow testing newly-created primitives against their last - // incarnation which buffers/holds the made decompositions. The default implementation - // uses getPrimitiveID()-calls to test if it's the same ID at last. Overloaded implementation are then - // based on this implementation + /** the ==operator is mainly needed to allow testing newly-created primitives against their last + incarnation which buffers/holds the made decompositions. The default implementation + uses getPrimitive2DID()-calls to test if it's the same ID at last. Overloaded implementation are then + based on this implementation + */ virtual bool operator==( const BasePrimitive2D& rPrimitive ) const; bool operator!=( const BasePrimitive2D& rPrimitive ) const { return !operator==(rPrimitive); } - // The default implementation will use getDecomposition results to create the range + /// The default implementation will use getDecomposition results to create the range virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const; - // provide unique ID for fast identifying of known primitive implementations in renderers. These use - // the the defines from primitivetypes2d.hxx to define unique IDs. - // This method is normally defined using DeclPrimitrive2DIDBlock() - virtual sal_uInt32 getPrimitiveID() const = 0; + /** provide unique ID for fast identifying of known primitive implementations in renderers. These use + the the defines from primitivetypes2d.hxx to define unique IDs. + This method is normally defined using DeclPrimitrive2DIDBlock() + */ + virtual sal_uInt32 getPrimitive2DID() const = 0; - // The getDecomposition default implementation will on demand use createLocalDecomposition() if maLocalDecomposition is empty. - // It will set maLocalDecomposition to this obtained decomposition to buffer it. - // If the decomposition is also ViewInformation2D-dependent, this method needs to be overloaded and the - // ViewInformation2D for the last decomposition need to be remembered, too, and be used in the next call to decide if - // the buffered decomposition may be reused or not. + /// The default implementation will return an empty sequence virtual Primitive2DSequence get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; // // Methods from XPrimitive2D // - // The getDecomposition implementation for UNO API will use getDecomposition from this implementation. It - // will construct a ViewInformation2D from the ViewParameters for that purpose + /** The getDecomposition implementation for UNO API will use getDecomposition from this implementation. It + will construct a ViewInformation2D from the ViewParameters for that purpose + */ virtual Primitive2DSequence SAL_CALL getDecomposition( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rViewParameters ) throw ( ::com::sun::star::uno::RuntimeException ); - // The getRange implementation for UNO API will use getRange from this implementation. It - // will construct a ViewInformation2D from the ViewParameters for that purpose + /** The getRange implementation for UNO API will use getRange from this implementation. It + will construct a ViewInformation2D from the ViewParameters for that purpose + */ virtual ::com::sun::star::geometry::RealRectangle2D SAL_CALL getRange( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rViewParameters ) throw ( ::com::sun::star::uno::RuntimeException ); }; } // end of namespace primitive2d } // end of namespace drawinglayer ////////////////////////////////////////////////////////////////////////////// +// BufferedDecompositionPrimitive2D class + +namespace drawinglayer +{ + namespace primitive2d + { + /** BufferedDecompositionPrimitive2D class + + Baseclass for all C++ implementations of com::sun::star::graphic::XPrimitive2D + which want to buffer the decomoposition result + + Buffering the decomposition is the most-used buffering and is thus used my most + primitive implementations which support a decomposition as base class. + + The buffering is done by holding the last decomposition in the local parameter + maBuffered2DDecomposition. The default implementation of get2DDecomposition checks + if maBuffered2DDecomposition is empty. If yes, it uses create2DDecomposition + to create the content. In all cases, maBuffered2DDecomposition is returned. + + For view-dependent primitives derived from Primitive2DBufferDecomposition more needs + to be done when the decomposition depends on parts of the parameter ViewInformation2D. + This defines a standard method for processing these: + + Implement a view-dependent get2DDecomposition doing te following steps: + (a) Locally extract needed parameters from ViewInformation2D to new, local parameters + (this may be a complete local copy of ViewInformation2D) + (b) If a buffered decomposition exists, ckeck if one of the new local parameters + differs from the corresponding locally remembered (as member) ones. If yes, + clear maBuffered2DDecomposition + (d) call baseclass::get2DDecomposition which will use create2DDecomposition + to fill maBuffered2DDecomposition if it's empty + (e) copy the new local parameters to the corresponding locally remembered ones + to identify if a new decomposition is needed at the next call + (f) return maBuffered2DDecomposition + */ + class BufferedDecompositionPrimitive2D + : public BasePrimitive2D + { + private: + /// a sequence used for buffering the last create2DDecomposition() result + Primitive2DSequence maBuffered2DDecomposition; + + protected: + /** access methods to maBuffered2DDecomposition. The usage of this methods may allow + later thread-safe stuff to be added if needed. Only to be used by getDecomposition() + implementations for buffering the last decomposition. + */ + const Primitive2DSequence& getBuffered2DDecomposition() const { return maBuffered2DDecomposition; } + void setBuffered2DDecomposition(const Primitive2DSequence& rNew) { maBuffered2DDecomposition = rNew; } + + /** method which is to be used to implement the local decomposition of a 2D primitive. The default + implementation will just return an empty decomposition + */ + virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + + public: + // constructor/destructor + BufferedDecompositionPrimitive2D(); + + /** The getDecomposition default implementation will on demand use create2DDecomposition() if + maBuffered2DDecomposition is empty. It will set maBuffered2DDecomposition to this obtained decomposition + to buffer it. If the decomposition is also ViewInformation2D-dependent, this method needs to be + overloaded and the ViewInformation2D for the last decomposition need to be remembered, too, and + be used in the next call to decide if the buffered decomposition may be reused or not. + */ + virtual Primitive2DSequence get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + }; + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// // tooling namespace drawinglayer { namespace primitive2d { - // get B2DRange from a given Primitive2DReference + /// get B2DRange from a given Primitive2DReference basegfx::B2DRange getB2DRangeFromPrimitive2DReference(const Primitive2DReference& rCandidate, const geometry::ViewInformation2D& aViewInformation); - // get B2DRange from a given Primitive2DSequence + /// get B2DRange from a given Primitive2DSequence basegfx::B2DRange getB2DRangeFromPrimitive2DSequence(const Primitive2DSequence& rCandidate, const geometry::ViewInformation2D& aViewInformation); - // compare two Primitive2DReferences for equality, including trying to get implementations (BasePrimitive2D) - // and using compare operator + /** compare two Primitive2DReferences for equality, including trying to get implementations (BasePrimitive2D) + and using compare operator + */ bool arePrimitive2DReferencesEqual(const Primitive2DReference& rA, const Primitive2DReference& rB); - // compare two Primitive2DReferences for equality, uses arePrimitive2DReferencesEqual internally + /// compare two Primitive2DReferences for equality, uses arePrimitive2DReferencesEqual internally bool arePrimitive2DSequencesEqual(const Primitive2DSequence& rA, const Primitive2DSequence& rB); - // concatenate sequence + /// concatenate sequence void appendPrimitive2DSequenceToPrimitive2DSequence(Primitive2DSequence& rDest, const Primitive2DSequence& rSource); - // concatenate single Primitive2D + /// concatenate single Primitive2D void appendPrimitive2DReferenceToPrimitive2DSequence(Primitive2DSequence& rDest, const Primitive2DReference& rSource); } // end of namespace primitive2d diff --git a/drawinglayer/inc/drawinglayer/primitive2d/bitmapprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/bitmapprimitive2d.hxx index d295c6ab4b89..f5de130febf9 100644 --- a/drawinglayer/inc/drawinglayer/primitive2d/bitmapprimitive2d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive2d/bitmapprimitive2d.hxx @@ -47,28 +47,41 @@ namespace drawinglayer { namespace primitive2d { + /** BitmapPrimitive2D class + + This class is the central primitive for Bitmap-based primitives. + It provides RGBA-based bitmaps, currently using a BitmapEx from VCL. + This may change in the future to any other, maybe more general base + class providing 24bit RGBA. + */ class BitmapPrimitive2D : public BasePrimitive2D { private: + /// the RGBA Bitmap-data BitmapEx maBitmapEx; + + /** the object transformation from unit coordinates, defining + size, shear, rotate and position + */ basegfx::B2DHomMatrix maTransform; public: + /// constructor BitmapPrimitive2D( const BitmapEx& rBitmapEx, const basegfx::B2DHomMatrix& rTransform); - // get data + /// data read access const BitmapEx& getBitmapEx() const { return maBitmapEx; } const basegfx::B2DHomMatrix& getTransform() const { return maTransform; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive2D& rPrimitive) const; - // get range + /// get range virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const; - // provide unique ID + /// provide unique ID DeclPrimitrive2DIDBlock() }; } // end of namespace primitive2d diff --git a/drawinglayer/inc/drawinglayer/primitive2d/borderlineprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/borderlineprimitive2d.hxx index 504ada20f8ac..b13528184f3b 100644 --- a/drawinglayer/inc/drawinglayer/primitive2d/borderlineprimitive2d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive2d/borderlineprimitive2d.hxx @@ -46,25 +46,41 @@ namespace drawinglayer { namespace primitive2d { - class BorderLinePrimitive2D : public BasePrimitive2D + /** BorderLinePrimitive2D class + + This is the basic primitive to build frames around objects, e.g. tables. + It defines a single or double line from Start to nd using the LeftWidth, + Distance and RightWidth definitions. + The LineStart/End overlap is defined by the Extend(Inner|Outer)(Start|End) + definitions. + */ + class BorderLinePrimitive2D : public BufferedDecompositionPrimitive2D { private: + /// the line definition basegfx::B2DPoint maStart; basegfx::B2DPoint maEnd; + + /// the widths of single/double line double mfLeftWidth; double mfDistance; double mfRightWidth; + + /// edge overlap sizes double mfExtendInnerStart; double mfExtendInnerEnd; double mfExtendOuterStart; double mfExtendOuterEnd; + + /// the line color basegfx::BColor maRGBColor; - // bitfield + /// bitfield + /// flags to influence inside/outside creation unsigned mbCreateInside : 1; unsigned mbCreateOutside : 1; - // helpers + /// local helpers double getCorrectedLeftWidth() const { return basegfx::fTools::equal(1.0, mfLeftWidth) ? 0.0 : mfLeftWidth; @@ -106,10 +122,11 @@ namespace drawinglayer } protected: - // create local decomposition - virtual Primitive2DSequence createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + /// create local decomposition + virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; public: + /// constructor BorderLinePrimitive2D( const basegfx::B2DPoint& rStart, const basegfx::B2DPoint& rEnd, @@ -124,7 +141,7 @@ namespace drawinglayer bool bCreateOutside, const basegfx::BColor& rRGBColor); - // get data + /// data read access const basegfx::B2DPoint& getStart() const { return maStart; } const basegfx::B2DPoint& getEnd() const { return maEnd; } double getLeftWidth() const { return mfLeftWidth; } @@ -138,10 +155,10 @@ namespace drawinglayer bool getCreateOutside() const { return mbCreateOutside; } const basegfx::BColor& getRGBColor() const { return maRGBColor; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive2D& rPrimitive) const; - // provide unique ID + /// provide unique ID DeclPrimitrive2DIDBlock() }; } // end of namespace primitive2d diff --git a/drawinglayer/inc/drawinglayer/primitive2d/chartprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/chartprimitive2d.hxx index 95c53347debb..b153e04ee1cb 100644 --- a/drawinglayer/inc/drawinglayer/primitive2d/chartprimitive2d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive2d/chartprimitive2d.hxx @@ -46,6 +46,12 @@ namespace drawinglayer { namespace primitive2d { + /** ChartPrimitive2D class + + This is a helper primitive which decomposes to the ChartMetaFile + visualisation. It is used to allow specific renderers to do something + direct for visualising the chart. + */ class ChartPrimitive2D : public GroupPrimitive2D { private: diff --git a/drawinglayer/inc/drawinglayer/primitive2d/controlprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/controlprimitive2d.hxx index 0e69cb7bdfc0..5dd55405adf7 100644 --- a/drawinglayer/inc/drawinglayer/primitive2d/controlprimitive2d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive2d/controlprimitive2d.hxx @@ -47,63 +47,74 @@ namespace drawinglayer { namespace primitive2d { - class ControlPrimitive2D : public BasePrimitive2D + /** ControlPrimitive2D class + + Base class for ControlPrimitive handling. It decoposes to a + graphical representation (Bitmap data) of the control. This + representation is limited to a quadratic pixel maximum defined + in the applicatin settings. + */ + class ControlPrimitive2D : public BufferedDecompositionPrimitive2D { private: - // object's base data + /// object's base data basegfx::B2DHomMatrix maTransform; com::sun::star::uno::Reference< com::sun::star::awt::XControlModel > mxControlModel; - // the created an cached awt::XControl + /// the created an cached awt::XControl com::sun::star::uno::Reference< com::sun::star::awt::XControl > mxXControl; - // the last used scaling, used from getDecomposition for buffering + /// the last used scaling, used from getDecomposition for buffering basegfx::B2DVector maLastViewScaling; - // used from getXControl() to create a local awt::XControl which is remembered in mxXControl - // and from thereon always used and returned by getXControl() + /** used from getXControl() to create a local awt::XControl which is remembered in mxXControl + and from thereon always used and returned by getXControl() + */ void createXControl(); - // single local decompositions, used from createLocalDecomposition() + /// single local decompositions, used from create2DDecomposition() Primitive2DReference createBitmapDecomposition(const geometry::ViewInformation2D& rViewInformation) const; Primitive2DReference createPlaceholderDecomposition(const geometry::ViewInformation2D& rViewInformation) const; protected: - // local decomposition - virtual Primitive2DSequence createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + /// local decomposition + virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; public: + /// constructor ControlPrimitive2D( const basegfx::B2DHomMatrix& rTransform, const com::sun::star::uno::Reference< com::sun::star::awt::XControlModel >& rxControlModel); - // constructor with an additional XControl as parameter to allow to hand it over at incarnation time - // if it exists. This will avoid to create a 2nd one on demand in createXControl() - // and thus double the XControls. + /** constructor with an additional XControl as parameter to allow to hand it over at incarnation time + if it exists. This will avoid to create a 2nd one on demand in createXControl() + and thus double the XControls. + */ ControlPrimitive2D( const basegfx::B2DHomMatrix& rTransform, const com::sun::star::uno::Reference< com::sun::star::awt::XControlModel >& rxControlModel, const com::sun::star::uno::Reference< com::sun::star::awt::XControl >& rxXControl); - // get data + /// data read access const basegfx::B2DHomMatrix& getTransform() const { return maTransform; } const com::sun::star::uno::Reference< com::sun::star::awt::XControlModel >& getControlModel() const { return mxControlModel; } - // mxControl access. This will on demand create the awt::XControl using createXControl() - // if it does not exist. It may already have been created or even handed over at - // incarnation + /** mxControl access. This will on demand create the awt::XControl using createXControl() + if it does not exist. It may already have been created or even handed over at + incarnation + */ const com::sun::star::uno::Reference< com::sun::star::awt::XControl >& getXControl() const; - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive2D& rPrimitive) const; - // get range + /// get range virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const; - // provide unique ID + /// provide unique ID DeclPrimitrive2DIDBlock() - // Overload standard getDecomposition call to be view-dependent here + /// Overload standard getDecomposition call to be view-dependent here virtual Primitive2DSequence get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; }; } // end of namespace primitive2d diff --git a/drawinglayer/inc/drawinglayer/primitive2d/discretebitmapprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/discretebitmapprimitive2d.hxx new file mode 100644 index 000000000000..04ddb73460fa --- /dev/null +++ b/drawinglayer/inc/drawinglayer/primitive2d/discretebitmapprimitive2d.hxx @@ -0,0 +1,93 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: bitmapprimitive2d.hxx,v $ + * + * $Revision: 1.4 $ + * + * last change: $Author: aw $ $Date: 2008-05-27 14:11:16 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef INCLUDED_DRAWINGLAYER_PRIMITIVE2D_DISCRETEBITMAPPRIMITIVE2D_HXX +#define INCLUDED_DRAWINGLAYER_PRIMITIVE2D_DISCRETEBITMAPPRIMITIVE2D_HXX + +#include <drawinglayer/primitive2d/primitivetools2d.hxx> +#include <vcl/bitmapex.hxx> + +////////////////////////////////////////////////////////////////////////////// +// DiscreteBitmapPrimitive2D class + +namespace drawinglayer +{ + namespace primitive2d + { + /** DiscreteBitmapPrimitive2D class + + This class defines a view-dependent BitmapPrimitive which has a + logic position for the top-left position and is always to be + painted in 1:1 pixel resolution. It will never be sheared, rotated + or scaled with the view. + */ + class DiscreteBitmapPrimitive2D : public ObjectAndViewTransformationDependentPrimitive2D + { + private: + /// the RGBA Bitmap-data + BitmapEx maBitmapEx; + + /** the top-left object position */ + basegfx::B2DPoint maTopLeft; + + protected: + /// local decomposition. + virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + + public: + /// constructor + DiscreteBitmapPrimitive2D( + const BitmapEx& rBitmapEx, + const basegfx::B2DPoint& rTopLeft); + + /// data read access + const BitmapEx& getBitmapEx() const { return maBitmapEx; } + const basegfx::B2DPoint& getTopLeft() const { return maTopLeft; } + + /// compare operator + virtual bool operator==(const BasePrimitive2D& rPrimitive) const; + + /// provide unique ID + DeclPrimitrive2DIDBlock() + }; + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// + +#endif // INCLUDED_DRAWINGLAYER_PRIMITIVE2D_DISCRETEBITMAPPRIMITIVE2D_HXX + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/drawinglayer/inc/drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx index 8d5d089f5800..d287482389b5 100644 --- a/drawinglayer/inc/drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx @@ -103,6 +103,12 @@ #define PRIMITIVE2D_ID_POLYPOLYGONMARKERPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 52) #define PRIMITIVE2D_ID_HITTESTPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 53) #define PRIMITIVE2D_ID_INVERTPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 54) +#define PRIMITIVE2D_ID_DISCRETEBITMAPPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 55) +#define PRIMITIVE2D_ID_WALLPAPERBITMAPPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 56) +#define PRIMITIVE2D_ID_TEXTLINEPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 57) +#define PRIMITIVE2D_ID_TEXTCHARACTERSTRIKEOUTPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 58) +#define PRIMITIVE2D_ID_TEXTGEOMETRYSTRIKEOUTPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 59) +#define PRIMITIVE2D_ID_EPSPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 60) ////////////////////////////////////////////////////////////////////////////// diff --git a/drawinglayer/inc/drawinglayer/primitive2d/embedded3dprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/embedded3dprimitive2d.hxx index e0da8a36c3f5..c27b6874891f 100644 --- a/drawinglayer/inc/drawinglayer/primitive2d/embedded3dprimitive2d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive2d/embedded3dprimitive2d.hxx @@ -42,52 +42,65 @@ #include <basegfx/matrix/b2dhommatrix.hxx> ////////////////////////////////////////////////////////////////////////////// -// BackgroundColorPrimitive2D class +// Embedded3DPrimitive2D class namespace drawinglayer { namespace primitive2d { - class Embedded3DPrimitive2D : public BasePrimitive2D + /** Embedded3DPrimitive2D class + + This is a helper primitive which allows embedding of single 3D + primitives to the 2D primitive logic. It will get the scene it's + involved and thus the 3D transformation. With this information it + is able to provide 2D range data for a 3D primitive. + + This primitive will not be visualized and decomposes to a yellow + 2D rectangle to visualize that this should never be visualized + */ + class Embedded3DPrimitive2D : public BufferedDecompositionPrimitive2D { private: - // the sequence of 3d primitives + /// the sequence of 3d primitives primitive3d::Primitive3DSequence mxChildren3D; - // the 2D scene object transformation + /// the 2D scene object transformation basegfx::B2DHomMatrix maObjectTransformation; - // the 3D transformations + /// the 3D transformations geometry::ViewInformation3D maViewInformation3D; - // if the embedded 3D primitives contain shadow, these parameters are needed - // to extract the shadow wich is a sequence od 2D primitives and may expand - // the 2D range. Since every single 3D object in a scene may individually - // have shadow or not, these values need to be provided and prepared. The shadow - // distance itself (a 2D transformation) is part of the 3D shadow definition + /** if the embedded 3D primitives contain shadow, these parameters are needed + to extract the shadow wich is a sequence od 2D primitives and may expand + the 2D range. Since every single 3D object in a scene may individually + have shadow or not, these values need to be provided and prepared. The shadow + distance itself (a 2D transformation) is part of the 3D shadow definition + */ basegfx::B3DVector maLightNormal; double mfShadowSlant; basegfx::B3DRange maScene3DRange; - // the primitiveSequence for on-demand created shadow primitives (see mbShadow3DChecked) + /// the primitiveSequence for on-demand created shadow primitives (see mbShadow3DChecked) Primitive2DSequence maShadowPrimitives; - // #i96669# add simple range buffering for this primitive + /// #i96669# add simple range buffering for this primitive basegfx::B2DRange maB2DRange; - // bitfield - // flag if given 3D geometry is already cheched for shadow definitions and 2d shadows - // are created in maShadowPrimitives + /// bitfield + /** flag if given 3D geometry is already cheched for shadow definitions and 2d shadows + are created in maShadowPrimitives + */ unsigned mbShadow3DChecked : 1; - // private helpers + /// private helpers bool impGetShadow3D(const geometry::ViewInformation2D& rViewInformation) const; protected: - // local decomposition. - virtual Primitive2DSequence createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + /// local decomposition. + virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; public: + /// constructor Embedded3DPrimitive2D( const primitive3d::Primitive3DSequence& rxChildren3D, const basegfx::B2DHomMatrix& rObjectTransformation, @@ -96,7 +109,7 @@ namespace drawinglayer double fShadowSlant, const basegfx::B3DRange& rScene3DRange); - // get data + /// get data const primitive3d::Primitive3DSequence& getChildren3D() const { return mxChildren3D; } const basegfx::B2DHomMatrix& getObjectTransformation() const { return maObjectTransformation; } const geometry::ViewInformation3D& getViewInformation3D() const { return maViewInformation3D; } @@ -104,13 +117,13 @@ namespace drawinglayer double getShadowSlant() const { return mfShadowSlant; } const basegfx::B3DRange& getScene3DRange() const { return maScene3DRange; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive2D& rPrimitive) const; - // get range + /// get range virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const; - // provide unique ID + /// provide unique ID DeclPrimitrive2DIDBlock() }; } // end of namespace primitive2d diff --git a/drawinglayer/inc/drawinglayer/primitive2d/epsprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/epsprimitive2d.hxx new file mode 100644 index 000000000000..0ebb29e153ec --- /dev/null +++ b/drawinglayer/inc/drawinglayer/primitive2d/epsprimitive2d.hxx @@ -0,0 +1,96 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: backgroundcolorprimitive2d.hxx,v $ + * + * $Revision: 1.3 $ + * + * last change: $Author: aw $ $Date: 2008-05-27 14:11:16 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef INCLUDED_DRAWINGLAYER_PRIMITIVE2D_EPSPRIMITIVE2D_HXX +#define INCLUDED_DRAWINGLAYER_PRIMITIVE2D_EPSPRIMITIVE2D_HXX + +#include <drawinglayer/primitive2d/baseprimitive2d.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <vcl/gfxlink.hxx> +#include <vcl/gdimtf.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + /** EpsPrimitive2D class */ + class EpsPrimitive2D : public BufferedDecompositionPrimitive2D + { + private: + /// the geometry definition + basegfx::B2DHomMatrix maEpsTransform; + + /// the Eps content definition + GfxLink maGfxLink; + + /// the replacement content definition + GDIMetaFile maMetaFile; + + protected: + /// create local decomposition + virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + + public: + /// constructor + EpsPrimitive2D( + const basegfx::B2DHomMatrix& rEpsTransform, + const GfxLink& rGfxLink, + const GDIMetaFile& rMetaFile); + + /// data read access + const basegfx::B2DHomMatrix& getEpsTransform() const { return maEpsTransform; } + const GfxLink& getGfxLink() const { return maGfxLink; } + const GDIMetaFile& getMetaFile() const { return maMetaFile; } + + /// compare operator + virtual bool operator==(const BasePrimitive2D& rPrimitive) const; + + /// get B2Drange + virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const; + + /// provide unique ID + DeclPrimitrive2DIDBlock() + }; + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// + +#endif //INCLUDED_DRAWINGLAYER_PRIMITIVE2D_EPSPRIMITIVE2D_HXX + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/drawinglayer/inc/drawinglayer/primitive2d/fillbitmapprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/fillbitmapprimitive2d.hxx index 1811b9bfaad9..7d2b084a9356 100644 --- a/drawinglayer/inc/drawinglayer/primitive2d/fillbitmapprimitive2d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive2d/fillbitmapprimitive2d.hxx @@ -47,32 +47,49 @@ namespace drawinglayer { namespace primitive2d { - class FillBitmapPrimitive2D : public BasePrimitive2D + /** FillBitmapPrimitive2D class + + This class defines a bitmap filling for a rectangular area. The + Range is defined by the Transformation, the fill by the FillBitmapAttribute. + 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 FillBitmapPrimitive2D : public BufferedDecompositionPrimitive2D { private: + /// the geometric definition basegfx::B2DHomMatrix maTransformation; + + /// the fill attributes attribute::FillBitmapAttribute maFillBitmap; protected: - // local decomposition. - virtual Primitive2DSequence createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + /// local decomposition. + virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; public: + /// constructor FillBitmapPrimitive2D( const basegfx::B2DHomMatrix& rTransformation, const attribute::FillBitmapAttribute& rFillBitmap); - // get data + /// data read access const basegfx::B2DHomMatrix& getTransformation() const { return maTransformation; } const attribute::FillBitmapAttribute& getFillBitmap() const { return maFillBitmap; } - // compare operator + /// compare operator virtual bool operator==( const BasePrimitive2D& rPrimitive ) const; - // get range + /// get range virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const; - // provide unique ID + /// provide unique ID DeclPrimitrive2DIDBlock() }; } // end of namespace primitive2d diff --git a/drawinglayer/inc/drawinglayer/primitive2d/fillgradientprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/fillgradientprimitive2d.hxx index ef5a52c6ddcf..0fd084c6fad0 100644 --- a/drawinglayer/inc/drawinglayer/primitive2d/fillgradientprimitive2d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive2d/fillgradientprimitive2d.hxx @@ -40,38 +40,77 @@ #include <drawinglayer/attribute/fillattribute.hxx> ////////////////////////////////////////////////////////////////////////////// -// FillbitmapPrimitive2D class +// predefines + +namespace basegfx { class B2DPolygon; } + +////////////////////////////////////////////////////////////////////////////// +// FillGradientPrimitive2D class namespace drawinglayer { namespace primitive2d { - class FillGradientPrimitive2D : public BasePrimitive2D + /** FillGradientPrimitive2D class + + This class defines a gradient filling for a rectangular area. The + Range is defined by the Transformation, the gradient by the FillGradientAttribute. + + The decomposition will deliver the decomposed gradient, e.g. for an ellipse + gradient the various ellipses in various color steps will be created. + + I have added functionality to create both versions of filled decompositions: + Those who overlap and non-overlapping ones. The overlapping version is the + default one since it works with and without AntiAliasing. The non-overlapping + version is used in the MetafilePrimitive2D decomposition when the old XOR + paint was recorded. + */ + class FillGradientPrimitive2D : public BufferedDecompositionPrimitive2D { private: + /// the geometric definition basegfx::B2DRange maObjectRange; + + /// the gradient definition attribute::FillGradientAttribute maFillGradient; + /// local helpers + void generateMatricesAndColors( + std::vector< basegfx::B2DHomMatrix >& rMatrices, + std::vector< basegfx::BColor >& rColors) const; + Primitive2DSequence createOverlappingFill( + const std::vector< basegfx::B2DHomMatrix >& rMatrices, + const std::vector< basegfx::BColor >& rColors, + const basegfx::B2DPolygon& rUnitPolygon) const; + Primitive2DSequence createNonOverlappingFill( + const std::vector< basegfx::B2DHomMatrix >& rMatrices, + const std::vector< basegfx::BColor >& rColors, + const basegfx::B2DPolygon& rUnitPolygon) const; + protected: - // local decomposition. - virtual Primitive2DSequence createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + /// local helper + Primitive2DSequence createFill(bool bOverlapping) const; + + /// local decomposition. + virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; public: + /// constructor FillGradientPrimitive2D( const basegfx::B2DRange& rObjectRange, const attribute::FillGradientAttribute& rFillGradient); - // get data + /// data read access const basegfx::B2DRange& getObjectRange() const { return maObjectRange; } const attribute::FillGradientAttribute& getFillGradient() const { return maFillGradient; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive2D& rPrimitive) const; - // get range + /// get range virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const; - // provide unique ID + /// provide unique ID DeclPrimitrive2DIDBlock() }; } // end of namespace primitive2d diff --git a/drawinglayer/inc/drawinglayer/primitive2d/fillhatchprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/fillhatchprimitive2d.hxx index 04410429d4a3..1df3bb103eb0 100644 --- a/drawinglayer/inc/drawinglayer/primitive2d/fillhatchprimitive2d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive2d/fillhatchprimitive2d.hxx @@ -40,41 +40,56 @@ #include <drawinglayer/attribute/fillattribute.hxx> ////////////////////////////////////////////////////////////////////////////// -// FillbitmapPrimitive2D class +// FillHatchPrimitive2D class namespace drawinglayer { namespace primitive2d { - class FillHatchPrimitive2D : public BasePrimitive2D + /** FillHatchPrimitive2D class + + This class defines a hatch filling for a rectangular area. The + Range is defined by the Transformation, the hatch by the FillHatchAttribute. + If the background is to be filled, a flag in FillHatchAttribute is set and + the BColor defines the background color. + + The decomposition will deliver the hatch lines. + */ + class FillHatchPrimitive2D : public BufferedDecompositionPrimitive2D { private: + /// the geometric definition basegfx::B2DRange maObjectRange; + + /// the hatch definition attribute::FillHatchAttribute maFillHatch; + + /// hatch background color (if used) basegfx::BColor maBColor; protected: - // local decomposition. - virtual Primitive2DSequence createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + /// local decomposition. + virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; public: + /// constructor FillHatchPrimitive2D( const basegfx::B2DRange& rObjectRange, const basegfx::BColor& rBColor, const attribute::FillHatchAttribute& rFillHatch); - // get data + /// data read access const basegfx::B2DRange& getObjectRange() const { return maObjectRange; } const attribute::FillHatchAttribute& getFillHatch() const { return maFillHatch; } const basegfx::BColor& getBColor() const { return maBColor; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive2D& rPrimitive) const; - // get range + /// get range virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const; - // provide unique ID + /// provide unique ID DeclPrimitrive2DIDBlock() }; } // end of namespace primitive2d diff --git a/drawinglayer/inc/drawinglayer/primitive2d/graphicprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/graphicprimitive2d.hxx index 4d020a3ab1c5..6d3c0ebf702a 100644 --- a/drawinglayer/inc/drawinglayer/primitive2d/graphicprimitive2d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive2d/graphicprimitive2d.hxx @@ -46,18 +46,39 @@ namespace drawinglayer { namespace primitive2d { - class GraphicPrimitive2D : public BasePrimitive2D + /** GraphicPrimitive2D class + + Primitive to hold graphics defined by GraphicObject and GraphicAttr + combination. This includes MetaFiles and diverse pixel-oriented graphic + formats. It even includes animated GIFs, Croppings and other changes + defined in GraphicAttr. + + This makes the decomposition contain a wide variety of possibilites, + too. From a simple BitmapPrimitive over AnimatedSwitchPrimitive2D, + MetafilePrimitive2D (with and without embedding in a masking when e.g. + the Metafile is bigger than the geometry) and embeddings in + TransformPrimitive2D and MaskPrimitive2D for croppings. + + The primitive geometry area is defined by Transform. + */ + class GraphicPrimitive2D : public BufferedDecompositionPrimitive2D { private: + /// the geometric definition basegfx::B2DHomMatrix maTransform; + + /// the GraphicObject with all it's content possibilities GraphicObject maGraphicObject; + + /// The GraphicAttr with all it's modification possibilities GraphicAttr maGraphicAttr; protected: - // local decomposition - virtual Primitive2DSequence createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + /// local decomposition + virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; public: + /// constructor(s) GraphicPrimitive2D( const basegfx::B2DHomMatrix& rTransform, const GraphicObject& rGraphicObject, @@ -66,19 +87,19 @@ namespace drawinglayer const basegfx::B2DHomMatrix& rTransform, const GraphicObject& rGraphicObject); - // get data + /// data read access const basegfx::B2DHomMatrix& getTransform() const { return maTransform; } const GraphicObject& getGraphicObject() const { return maGraphicObject; } const GraphicAttr& getGraphicAttr() const { return maGraphicAttr; } bool isTransparent() const; - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive2D& rPrimitive) const; - // get range + /// get range virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const; - // provide unique ID + /// provide unique ID DeclPrimitrive2DIDBlock() }; } // end of namespace primitive2d diff --git a/drawinglayer/inc/drawinglayer/primitive2d/gridprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/gridprimitive2d.hxx index f0aad415bfce..4ba83fc75c88 100644 --- a/drawinglayer/inc/drawinglayer/primitive2d/gridprimitive2d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive2d/gridprimitive2d.hxx @@ -48,29 +48,47 @@ namespace drawinglayer { namespace primitive2d { - class GridPrimitive2D : public BasePrimitive2D + /** GridPrimitive2D class + + This primitive is specialized to Grid visualisation. The graphic definition + (Transform) contains the whole grid area, but will of course be combined + with the visible area (Viewport) when decomposed. Also a reolution-dependent + point reduction is used to not create too much grid visualisation data. This + makes this primitive highly view-dependent and it dynamically buffers + the last decomposition dependent from the Viewport used. + */ + class GridPrimitive2D : public BufferedDecompositionPrimitive2D { private: + /// The geometry definition for the grid area basegfx::B2DHomMatrix maTransform; + + /// grid layout definitions double mfWidth; double mfHeight; double mfSmallestViewDistance; double mfSmallestSubdivisionViewDistance; sal_uInt32 mnSubdivisionsX; sal_uInt32 mnSubdivisionsY; + + /// Grid color for single-pixel grid points basegfx::BColor maBColor; + + /// The Bitmap (with alpha) for grid cross points BitmapEx maCrossMarker; - // the last used object to view transformtion and the last Viewport, - // used from getDecomposition for decide buffering + /** the last used object to view transformtion and the last Viewport, + used from getDecomposition for decide buffering + */ basegfx::B2DHomMatrix maLastObjectToViewTransformation; basegfx::B2DRange maLastViewport; protected: - // create local decomposition - virtual Primitive2DSequence createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + /// create local decomposition + virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; public: + /// constructor GridPrimitive2D( const basegfx::B2DHomMatrix& rTransform, double fWidth, @@ -82,7 +100,7 @@ namespace drawinglayer const basegfx::BColor& rBColor, const BitmapEx& rCrossMarker); - // get data + /// data read access const basegfx::B2DHomMatrix& getTransform() const { return maTransform; } double getWidth() const { return mfWidth; } double getHeight() const { return mfHeight; } @@ -93,16 +111,16 @@ namespace drawinglayer const basegfx::BColor& getBColor() const { return maBColor; } const BitmapEx& getCrossMarker() const { return maCrossMarker; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive2D& rPrimitive) const; - // get 2d range + /// get 2d range virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const; - // provide unique ID + /// provide unique ID DeclPrimitrive2DIDBlock() - // Overload standard getDecomposition call to be view-dependent here + /// Overload standard getDecomposition call to be view-dependent here virtual Primitive2DSequence get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; }; } // end of namespace primitive2d diff --git a/drawinglayer/inc/drawinglayer/primitive2d/groupprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/groupprimitive2d.hxx index 855e65ba98f8..89b49420a3e7 100644 --- a/drawinglayer/inc/drawinglayer/primitive2d/groupprimitive2d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive2d/groupprimitive2d.hxx @@ -45,27 +45,58 @@ namespace drawinglayer { namespace primitive2d { + /** GroupPrimitive2D class + + Baseclass for all grouping 2D primitives + + The grouping primitive in it's basic form is capable of holding + a child primitive content and returns it on decomposition on default. + It is used for two main purposes, but more may apply: + + - to transport extended information, e.g. for text classification, + see e.g. TextHierarchy*Primitive2D implementations. Since they + decompose to their child content, renderers not aware/interested + in that extra information will just ignore these primitives + + - to encapsulate common geometry, e.g. the ShadowPrimitive2D implements + applying a generic shadow to a child sequence by adding the needed + offset and color stuff in the decomposition + + In most cases the decomposition is straightforward, so by default + this primitive will not buffer the result and is not derived from + BufferedDecompositionPrimitive2D, but from BasePrimitive2D. + + A renderer has to take GroupPrimitive2D derivations into account which + are used to hold a state. + + Current Basic 2D StatePrimitives are: + + - AlphaPrimitive2D (objects with freely defined transparence) + - InvertPrimitive2D (for XOR) + - MaskPrimitive2D (for masking) + - ModifiedColorPrimitive2D (for a stack of color modifications) + - TransformPrimitive2D (for a transformation stack) + */ class GroupPrimitive2D : public BasePrimitive2D { private: - // the children. Declared private since this shall never be changed at all after construction + /// the children. Declared private since this shall never be changed at all after construction Primitive2DSequence maChildren; - protected: - // local decomposition. Implementation will just return children - virtual Primitive2DSequence createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const; - public: - // constructor + /// constructor GroupPrimitive2D(const Primitive2DSequence& rChildren); - // data access + /// data read access const Primitive2DSequence& getChildren() const { return maChildren; } - // compare operator + /// compare operator virtual bool operator==( const BasePrimitive2D& rPrimitive ) const; - // provide unique ID + /// local decomposition. Implementation will just return children + virtual Primitive2DSequence get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + + /// provide unique ID DeclPrimitrive2DIDBlock() }; } // end of namespace primitive2d diff --git a/drawinglayer/inc/drawinglayer/primitive2d/helplineprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/helplineprimitive2d.hxx index 4e8357a3eac1..a1171cb846e0 100644 --- a/drawinglayer/inc/drawinglayer/primitive2d/helplineprimitive2d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive2d/helplineprimitive2d.hxx @@ -47,32 +47,52 @@ namespace drawinglayer { namespace primitive2d { + /** HelplineStyle2D definition + + The available styles of Helplines + */ enum HelplineStyle2D { HELPLINESTYLE2D_POINT, HELPLINESTYLE2D_LINE }; - class HelplinePrimitive2D : public BasePrimitive2D + /** HelplinePrimitive2D class + + This primitive provides a view-dependent helpline definition. The Helpline + is defined by a line equation (Point and vector) and a style. When the style + is a line, dependent from Viewport the visible part of that Helpline is + constructed. For Point, a cross is constructed. This primitive is highly + view-dependent. + + The visualisation uses the two given colors to create a dashed line with + the given dash length. + */ + class HelplinePrimitive2D : public BufferedDecompositionPrimitive2D { private: + /// Helpline geometry definition basegfx::B2DPoint maPosition; basegfx::B2DVector maDirection; HelplineStyle2D meStyle; + + /// Helpline style definition basegfx::BColor maRGBColA; basegfx::BColor maRGBColB; double mfDiscreteDashLength; - // the last used object to view transformtion and the last Viewport, - // used from getDecomposition for decide buffering + /** the last used object to view transformtion and the last Viewport, + used from getDecomposition for decide buffering + */ basegfx::B2DHomMatrix maLastObjectToViewTransformation; basegfx::B2DRange maLastViewport; protected: - // create local decomposition - virtual Primitive2DSequence createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + /// create local decomposition + virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; public: + /// constructor HelplinePrimitive2D( const basegfx::B2DPoint& rPosition, const basegfx::B2DVector& rDirection, @@ -81,7 +101,7 @@ namespace drawinglayer const basegfx::BColor& aRGBColB, double fDiscreteDashLength); - // get data + /// data read access const basegfx::B2DPoint getPosition() const { return maPosition; } const basegfx::B2DVector getDirection() const { return maDirection; } HelplineStyle2D getStyle() const { return meStyle; } @@ -89,13 +109,13 @@ namespace drawinglayer const basegfx::BColor& getRGBColB() const { return maRGBColB; } double getDiscreteDashLength() const { return mfDiscreteDashLength; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive2D& rPrimitive) const; - // provide unique ID + /// provide unique ID DeclPrimitrive2DIDBlock() - // Overload standard getDecomposition call to be view-dependent here + /// Overload standard getDecomposition call to be view-dependent here virtual Primitive2DSequence get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; }; } // end of namespace primitive2d diff --git a/drawinglayer/inc/drawinglayer/primitive2d/hittestprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/hittestprimitive2d.hxx index 2bbcad315eb3..3b69c685c985 100644 --- a/drawinglayer/inc/drawinglayer/primitive2d/hittestprimitive2d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive2d/hittestprimitive2d.hxx @@ -44,30 +44,35 @@ namespace drawinglayer { namespace primitive2d { - // This primitive is used to represent geometry for non-visible objects, - // e.g. a PresObj's outline. To still be able to use primitives for HitTest - // functionality, the 2d decompositions will produce an as much as possible - // simplified line geometry encapsulated in this primtive when there is no - // line geometry. In a further enchanced version this may change to 'if neither - // filled nor lines' creation criteria. The whole primitive decomposes to nothing, - // so no one not knowing it will be influenced. Only helper processors for hit test - // (and maybe BoundRect extractors) will use it and it's children subcontent. + /** HitTestPrimitive2D class + + This primitive is used to represent geometry for non-visible objects, + e.g. a PresObj's outline. To still be able to use primitives for HitTest + functionality, the 2d decompositions will produce an as much as possible + simplified line geometry encapsulated in this primtive when there is no + line geometry. In a further enchanced version this may change to 'if neither + filled nor lines' creation criteria. The whole primitive decomposes to nothing, + so no one not knowing it will be influenced. Only helper processors for hit test + (and maybe BoundRect extractors) will use it and it's children subcontent. + */ class HitTestPrimitive2D : public GroupPrimitive2D { - protected: - // local decomposition. Implementation will return empty Primitive2DSequence - // since this is no visualisation data - virtual Primitive2DSequence createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const; - public: + /// constructor HitTestPrimitive2D(const Primitive2DSequence& rChildren); - // despite returning an empty decomposition since it's no visualisation data, - // range calculation is intended to use invisible replacement geometry, so - // the local implementation will return the children's range + /** despite returning an empty decomposition since it's no visualisation data, + range calculation is intended to use invisible replacement geometry, so + the local implementation will return the children's range + */ virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const; - // provide unique ID + /** local decomposition. Implementation will return empty Primitive2DSequence + since this is no visualisation data + */ + virtual Primitive2DSequence get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + + /// provide unique ID DeclPrimitrive2DIDBlock() }; } // end of namespace primitive2d diff --git a/drawinglayer/inc/drawinglayer/primitive2d/invertprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/invertprimitive2d.hxx index ae7a316e03da..85f1c6510c5a 100644 --- a/drawinglayer/inc/drawinglayer/primitive2d/invertprimitive2d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive2d/invertprimitive2d.hxx @@ -44,12 +44,23 @@ namespace drawinglayer { namespace primitive2d { + /** InvertPrimitive2D class + + This is a helper class which encapsulates geometry that should be + painted XOR, e.g. old cursor visualisations. It decomposes to + it's content, so when not supporting it, the contained geometry + will be visualized normally. + Unfortunately this is still needed, but hard to support on various + systems. XOR painting needs read access to the target, so modern + graphic systems tend to not support it anymore. + */ class InvertPrimitive2D : public GroupPrimitive2D { public: + /// constructor InvertPrimitive2D(const Primitive2DSequence& rChildren); - // provide unique ID + /// provide unique ID DeclPrimitrive2DIDBlock() }; } // end of namespace primitive2d diff --git a/drawinglayer/inc/drawinglayer/primitive2d/markerarrayprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/markerarrayprimitive2d.hxx index 350471f4aff3..cc4c054f8bb3 100644 --- a/drawinglayer/inc/drawinglayer/primitive2d/markerarrayprimitive2d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive2d/markerarrayprimitive2d.hxx @@ -41,38 +41,55 @@ #include <vcl/bitmapex.hxx> ////////////////////////////////////////////////////////////////////////////// -// MarkerPrimitive2D class +// MarkerArrayPrimitive2D class namespace drawinglayer { namespace primitive2d { - class MarkerArrayPrimitive2D : public BasePrimitive2D + /** MarkerArrayPrimitive2D class + + This primtive defines an array of markers. Their size is defined + in pixels and independent from the view transformation which makes + this primitive highly view-dependent. It is also transformation + invariant, so that the bitmap is always visualized unscaled and + unrotated. + It is used e.g. for grid position visualisation. The given Bitmap + (with alpha) is defined to be visible centered at each of the given + positions. + It decomposes to the needed number of BitmapPrimitive2D's, so it would + be efficient to handle it directly in a renderer. + */ + class MarkerArrayPrimitive2D : public BufferedDecompositionPrimitive2D { private: + /// the positions for the marker std::vector< basegfx::B2DPoint > maPositions; + + /// the marker definintion to visualize BitmapEx maMarker; protected: - // create local decomposition - virtual Primitive2DSequence createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + /// create local decomposition + virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; public: + /// constructor MarkerArrayPrimitive2D( const std::vector< basegfx::B2DPoint >& rPositions, const BitmapEx& rMarker); - // get data + /// data read access const std::vector< basegfx::B2DPoint >& getPositions() const { return maPositions; } const BitmapEx& getMarker() const { return maMarker; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive2D& rPrimitive) const; - // get range + /// get range virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const; - // provide unique ID + /// provide unique ID DeclPrimitrive2DIDBlock() }; } // end of namespace primitive2d diff --git a/drawinglayer/inc/drawinglayer/primitive2d/maskprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/maskprimitive2d.hxx index 9be17376941e..e5cb12e6e87c 100644 --- a/drawinglayer/inc/drawinglayer/primitive2d/maskprimitive2d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive2d/maskprimitive2d.hxx @@ -45,23 +45,42 @@ namespace drawinglayer { namespace primitive2d { + /** MaskPrimitive2D class + + This is the central masking primitive. It's a grouping + primitive and contains a PolyPolygon which defines the visible + area. Only visualisation parts of the Child primitive sequence + inside of the mask PolyPolygon is defined to be visible. + + This primitive should be handled by a renderer. If it is not handled, + it decomposes to it's Child content, and thus the visualisation would + contaiun no clips. + + The geometrc range of this primitive is completely defined by the Mask + PolyPolygon since by definition nothing outside of the mask is visible. + */ class MaskPrimitive2D : public GroupPrimitive2D { private: + /// the mask PolyPolygon basegfx::B2DPolyPolygon maMask; public: + /// constructor MaskPrimitive2D( const basegfx::B2DPolyPolygon& rMask, const Primitive2DSequence& rChildren); - // get data + /// data read access const basegfx::B2DPolyPolygon& getMask() const { return maMask; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive2D& rPrimitive) const; - // provide unique ID + /// get range + virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const; + + /// provide unique ID DeclPrimitrive2DIDBlock() }; } // end of namespace primitive2d diff --git a/drawinglayer/inc/drawinglayer/primitive2d/mediaprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/mediaprimitive2d.hxx index 019fdc69bd3f..e5f884f09294 100644 --- a/drawinglayer/inc/drawinglayer/primitive2d/mediaprimitive2d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive2d/mediaprimitive2d.hxx @@ -46,38 +46,55 @@ namespace drawinglayer { namespace primitive2d { - class MediaPrimitive2D : public BasePrimitive2D + /** MediaPrimitive2D class + + This is a unified primitive for Media visualisation, e.g. animations + or sounds. It's geometry is defined by Transform. For conveinience, + it also contains a discrete border size (aka Pixels) which will be added + if used. This makes it a view-dependent primitive. It also gets a filled + background and the decomposition will try to create a graphic representation + if te content (defined by the URL), e.g. a still frome for animated stuff. + */ + class MediaPrimitive2D : public BufferedDecompositionPrimitive2D { private: + /// the geometry definition basegfx::B2DHomMatrix maTransform; + + /// the content definition rtl::OUString maURL; + + /// style: background color basegfx::BColor maBackgroundColor; + + /// discrete border (in 'pixels') sal_uInt32 mnDiscreteBorder; protected: - // local decomposition - virtual Primitive2DSequence createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + /// local decomposition + virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; public: + /// constructor MediaPrimitive2D( const basegfx::B2DHomMatrix& rTransform, const rtl::OUString& rURL, const basegfx::BColor& rBackgroundColor, sal_uInt32 nDiscreteBorder); - // get data + /// data read access const basegfx::B2DHomMatrix& getTransform() const { return maTransform; } const rtl::OUString& getURL() const { return maURL; } const basegfx::BColor& getBackgroundColor() const { return maBackgroundColor; } sal_uInt32 getDiscreteBorder() const { return mnDiscreteBorder; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive2D& rPrimitive) const; - // get range + /// get range virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const; - // provide unique ID + /// provide unique ID DeclPrimitrive2DIDBlock() }; } // end of namespace primitive2d diff --git a/drawinglayer/inc/drawinglayer/primitive2d/metafileprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/metafileprimitive2d.hxx index 23eb5dd1b36e..0cbd7e4628cb 100644 --- a/drawinglayer/inc/drawinglayer/primitive2d/metafileprimitive2d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive2d/metafileprimitive2d.hxx @@ -47,28 +47,55 @@ namespace drawinglayer { namespace primitive2d { - class MetafilePrimitive2D : public BasePrimitive2D + /** MediaPrimitive2D class + + This is the MetaFile representing primitive. It's geometry is defined + by MetaFileTransform. The content (defined by MetaFile) will be scaled + to the geometric definiton by using PrefMapMode and PrefSize of the + Metafile. + + It has shown that this not always guarantees that all Metafile content + is inside the geometric definition, but this primitive defines that this + is the case to allow a getB2DRange implementation. If it cannot be + guaranteed that the Metafile is inside the geometric definition, it should + be embedded to a MaskPrimitive2D. + + This primitive has no decomposition yet, so when not supported by a renderer, + it will not be visualized. + + In the future, a decomposition implementation would be appreciated and would + have many advantages; Metafile would no longer have to be rendered by + sub-systems and a standard way for converting Metafiles would exist. + */ + class MetafilePrimitive2D : public BufferedDecompositionPrimitive2D { private: + /// the geometry definition basegfx::B2DHomMatrix maMetaFileTransform; + + /// the content definition GDIMetaFile maMetaFile; + protected: + /// local decomposition. + virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; public: + /// constructor MetafilePrimitive2D( const basegfx::B2DHomMatrix& rMetaFileTransform, const GDIMetaFile& rMetaFile); - // get data + /// data read access const basegfx::B2DHomMatrix& getTransform() const { return maMetaFileTransform; } const GDIMetaFile& getMetaFile() const { return maMetaFile; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive2D& rPrimitive) const; - // get range + /// get range virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const; - // provide unique ID + /// provide unique ID DeclPrimitrive2DIDBlock() }; } // end of namespace primitive2d diff --git a/drawinglayer/inc/drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx index 903ba89c9a5b..e93dd523e0b7 100644 --- a/drawinglayer/inc/drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx @@ -45,23 +45,42 @@ namespace drawinglayer { namespace primitive2d { + /** ModifiedColorPrimitive2D class + + This primitive is a grouping primitive and allows to define + how the colors of it's child content shall be modified for + visualisation. This can be (and is) used e.g. for generic shadow + visualisation by forcing all color usages of the contained + sub-content to the shadow color. + + For the possibilities of color modifications, please refer + to the basegfx::BColorModifier definitions in basegfx. For + processing there is tooling in basegfx to build a stack of + BColorModifiers to always be able to proccess the correct + colors. + + If a renderer does not handle this primitive, the content will + be visualized unchanged. + */ class ModifiedColorPrimitive2D : public GroupPrimitive2D { private: + /// The ColorModifier to use basegfx::BColorModifier maColorModifier; public: + /// constructor ModifiedColorPrimitive2D( const Primitive2DSequence& rChildren, const basegfx::BColorModifier& rColorModifier); - // get data + /// data read access const basegfx::BColorModifier& getColorModifier() const { return maColorModifier; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive2D& rPrimitive) const; - // provide unique ID + /// provide unique ID DeclPrimitrive2DIDBlock() }; } // end of namespace primitive2d diff --git a/drawinglayer/inc/drawinglayer/primitive2d/pagepreviewprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/pagepreviewprimitive2d.hxx index edba5455ff0a..5eca0ac2ab13 100644 --- a/drawinglayer/inc/drawinglayer/primitive2d/pagepreviewprimitive2d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive2d/pagepreviewprimitive2d.hxx @@ -36,7 +36,7 @@ #ifndef INCLUDED_DRAWINGLAYER_PRIMITIVE2D_PAGEPREVIEWPRIMITIVE2D_HXX #define INCLUDED_DRAWINGLAYER_PRIMITIVE2D_PAGEPREVIEWPRIMITIVE2D_HXX -#include <drawinglayer/primitive2d/groupprimitive2d.hxx> +#include <drawinglayer/primitive2d/baseprimitive2d.hxx> #include <com/sun/star/drawing/XDrawPage.hpp> #include <basegfx/matrix/b2dhommatrix.hxx> @@ -46,57 +46,66 @@ namespace drawinglayer { namespace primitive2d { - // This primitive is needed to have the correct XDrawPage as ViewInformation for decomposing - // the page contents (given as childs of the GroupPrimitive2D here) if these contain e.g. - // view-dependent (in this case XDrawPage-dependent) text fields like PageNumber. If You want - // those primitives to be visualized correctly, Your renderer needs to locally correct it's - // ViewInformation2D to reference the new XDrawPage. - class PagePreviewPrimitive2D : public GroupPrimitive2D + /** PagePreviewPrimitive2D class + + This primitive is needed to have the correct XDrawPage as ViewInformation for decomposing + the page contents (given as PageContent here) if these contain e.g. + view-dependent (in this case XDrawPage-dependent) text fields like PageNumber. If You want + those primitives to be visualized correctly, Your renderer needs to locally correct it's + ViewInformation2D to reference the new XDrawPage. + */ + class PagePreviewPrimitive2D : public BufferedDecompositionPrimitive2D { private: - // the XDrawPage visualized by this primitive. When we go forward with primitives - // this will not only be used by the renderers to provide the correct decompose - // graphic attribute context, but also to completely create the page's sub-content. + /** the XDrawPage visualized by this primitive. When we go forward with primitives + this will not only be used by the renderers to provide the correct decompose + graphic attribute context, but also to completely create the page's sub-content. + */ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage > mxDrawPage; - // the own geometry + /// the PageContent + Primitive2DSequence maPageContent; + + /// the own geometry basegfx::B2DHomMatrix maTransform; - // content width and height + /// content width and height double mfContentWidth; double mfContentHeight; - // bitfield - // flag to allow keeping the aspect ratio + /// bitfield + /// flag to allow keeping the aspect ratio unsigned mbKeepAspectRatio : 1; protected: - // local decomposition. Implementation will just return children - virtual Primitive2DSequence createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + /// local decomposition. Implementation will just return children + virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; public: + /// constructor PagePreviewPrimitive2D( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage >& rxDrawPage, const basegfx::B2DHomMatrix& rTransform, double fContentWidth, double fContentHeight, - const Primitive2DSequence& rChildren, + const Primitive2DSequence& rPageContent, bool bKeepAspectRatio); - // get data + /// data read access const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage >& getXDrawPage() const { return mxDrawPage; } + const Primitive2DSequence& getPageContent() const { return maPageContent; } const basegfx::B2DHomMatrix& getTransform() const { return maTransform; } double getContentWidth() const { return mfContentWidth; } double getContentHeight() const { return mfContentHeight; } bool getKeepAspectRatio() const { return mbKeepAspectRatio; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive2D& rPrimitive) const; - // own getB2DRange + /// own getB2DRange virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const; - // provide unique ID + /// provide unique ID DeclPrimitrive2DIDBlock() }; } // end of namespace primitive2d diff --git a/drawinglayer/inc/drawinglayer/primitive2d/pointarrayprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/pointarrayprimitive2d.hxx index bdd4142b0584..793c96444bac 100644 --- a/drawinglayer/inc/drawinglayer/primitive2d/pointarrayprimitive2d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive2d/pointarrayprimitive2d.hxx @@ -40,37 +40,51 @@ #include <basegfx/color/bcolor.hxx> ////////////////////////////////////////////////////////////////////////////// -// MarkerPrimitive2D class +// PointArrayPrimitive2D class namespace drawinglayer { namespace primitive2d { + /** PointArrayPrimitive2D class + + This primitive defines single,discrete 'pixels' for the given + positions in the given color. This makes it view-dependent since + the logic size of a 'pixel' depends on the view transformation. + + This is one of the non-decomposable primitives, so a renderer + should proccess it (Currently it is only used for grid visualisation, + but this may change). + */ class PointArrayPrimitive2D : public BasePrimitive2D { private: + /// the array of positions std::vector< basegfx::B2DPoint > maPositions; + + /// the color to use basegfx::BColor maRGBColor; - // #i96669# add simple range buffering for this primitive - basegfx::B2DRange maB2DRange; + /// #i96669# add simple range buffering for this primitive + basegfx::B2DRange maB2DRange; public: + /// constructor PointArrayPrimitive2D( const std::vector< basegfx::B2DPoint >& rPositions, const basegfx::BColor& rRGBColor); - // get data + /// data read access const std::vector< basegfx::B2DPoint >& getPositions() const { return maPositions; } const basegfx::BColor& getRGBColor() const { return maRGBColor; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive2D& rPrimitive) const; - // get range + /// get range virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const; - // provide unique ID + /// provide unique ID DeclPrimitrive2DIDBlock() }; } // end of namespace primitive2d diff --git a/drawinglayer/inc/drawinglayer/primitive2d/polygonprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/polygonprimitive2d.hxx index 48ec5e80aa09..4c6f5b49bf01 100644 --- a/drawinglayer/inc/drawinglayer/primitive2d/polygonprimitive2d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive2d/polygonprimitive2d.hxx @@ -49,26 +49,40 @@ namespace drawinglayer { namespace primitive2d { + /** PolygonHairlinePrimitive2D class + + This primitive defines a Hairline. Since hairlines are view-dependent, + this primitive is view-dependent, too. + + This is one of the non-decomposable primitives, so a renderer + should proccess it. + */ class PolygonHairlinePrimitive2D : public BasePrimitive2D { private: + /// the hairline geometry basegfx::B2DPolygon maPolygon; + + /// the hairline color basegfx::BColor maBColor; public: - PolygonHairlinePrimitive2D(const basegfx::B2DPolygon& rPolygon, const basegfx::BColor& rBColor); + /// constructor + PolygonHairlinePrimitive2D( + const basegfx::B2DPolygon& rPolygon, + const basegfx::BColor& rBColor); - // get data + /// data read access const basegfx::B2DPolygon& getB2DPolygon() const { return maPolygon; } const basegfx::BColor& getBColor() const { return maBColor; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive2D& rPrimitive) const; - // get range + /// get range virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const; - // provide unique ID + /// provide unique ID DeclPrimitrive2DIDBlock() }; } // end of namespace primitive2d @@ -81,44 +95,59 @@ namespace drawinglayer { namespace primitive2d { - class PolygonMarkerPrimitive2D : public BasePrimitive2D + /** PolygonMarkerPrimitive2D class + + This primitive defines a two-colored marker hairline which is + dashed with the given dash length. Since hairlines are view-dependent, + this primitive is view-dependent, too. + + It will be decomposed to the needed PolygonHairlinePrimitive2D if + not handled directly by a renderer. + */ + class PolygonMarkerPrimitive2D : public BufferedDecompositionPrimitive2D { private: + /// the marker hairline geometry basegfx::B2DPolygon maPolygon; + + /// the two colors basegfx::BColor maRGBColorA; basegfx::BColor maRGBColorB; + + /// the dash distance in 'pixels' double mfDiscreteDashLength; - // decomposition is view-dependent, remember last InverseObjectToViewTransformation + /// decomposition is view-dependent, remember last InverseObjectToViewTransformation basegfx::B2DHomMatrix maLastInverseObjectToViewTransformation; protected: - // local decomposition. - virtual Primitive2DSequence createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + /// local decomposition. + virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; public: + /// constructor PolygonMarkerPrimitive2D( const basegfx::B2DPolygon& rPolygon, const basegfx::BColor& rRGBColorA, const basegfx::BColor& rRGBColorB, double fDiscreteDashLength); - // get data + /// data read access const basegfx::B2DPolygon& getB2DPolygon() const { return maPolygon; } const basegfx::BColor& getRGBColorA() const { return maRGBColorA; } const basegfx::BColor& getRGBColorB() const { return maRGBColorB; } double getDiscreteDashLength() const { return mfDiscreteDashLength; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive2D& rPrimitive) const; - // get range + /// get range virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const; - // get local decomposition. Overloaded since this decomposition is view-dependent + /// get local decomposition. Overloaded since this decomposition is view-dependent virtual Primitive2DSequence get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; - // provide unique ID + /// provide unique ID DeclPrimitrive2DIDBlock() }; } // end of namespace primitive2d @@ -131,39 +160,52 @@ namespace drawinglayer { namespace primitive2d { - class PolygonStrokePrimitive2D : public BasePrimitive2D + /** PolygonStrokePrimitive2D class + + This primitive defines a line with line width, line join, line color + and stroke attributes. It will be decomposed dependent on the definition + to the needed primitives, e.g. filled PolyPolygons for fat lines. + */ + class PolygonStrokePrimitive2D : public BufferedDecompositionPrimitive2D { private: + /// the line geometry basegfx::B2DPolygon maPolygon; + + /// the line attributes like width, join and color attribute::LineAttribute maLineAttribute; + + /// the line stroking (if used) attribute::StrokeAttribute maStrokeAttribute; protected: - // local decomposition. - virtual Primitive2DSequence createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + /// local decomposition. + virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; public: + /// constructor PolygonStrokePrimitive2D( const basegfx::B2DPolygon& rPolygon, const attribute::LineAttribute& rLineAttribute, const attribute::StrokeAttribute& rStrokeAttribute); + /// constructor without stroking PolygonStrokePrimitive2D( const basegfx::B2DPolygon& rPolygon, const attribute::LineAttribute& rLineAttribute); - // get data + /// data read access basegfx::B2DPolygon getB2DPolygon() const { return maPolygon; } const attribute::LineAttribute& getLineAttribute() const { return maLineAttribute; } const attribute::StrokeAttribute& getStrokeAttribute() const { return maStrokeAttribute; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive2D& rPrimitive) const; - // get range + /// get range virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const; - // provide unique ID + /// provide unique ID DeclPrimitrive2DIDBlock() }; } // end of namespace primitive2d @@ -176,17 +218,24 @@ namespace drawinglayer { namespace primitive2d { + /** PolygonWavePrimitive2D class + + This primitive defines a waveline based on a PolygonStrokePrimitive2D + where the wave is defined by wave width and wave length. + */ class PolygonWavePrimitive2D : public PolygonStrokePrimitive2D { private: + /// wave definition double mfWaveWidth; double mfWaveHeight; protected: - // local decomposition. - virtual Primitive2DSequence createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + /// local decomposition. + virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; public: + /// constructor PolygonWavePrimitive2D( const basegfx::B2DPolygon& rPolygon, const attribute::LineAttribute& rLineAttribute, @@ -194,23 +243,24 @@ namespace drawinglayer double fWaveWidth, double fWaveHeight); + /// constructor without stroking PolygonWavePrimitive2D( const basegfx::B2DPolygon& rPolygon, const attribute::LineAttribute& rLineAttribute, double fWaveWidth, double fWaveHeight); - // get data + /// data read access double getWaveWidth() const { return mfWaveWidth; } double getWaveHeight() const { return mfWaveHeight; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive2D& rPrimitive) const; - // get range + /// get range virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const; - // provide unique ID + /// provide unique ID DeclPrimitrive2DIDBlock() }; } // end of namespace primitive2d @@ -223,17 +273,25 @@ namespace drawinglayer { namespace primitive2d { + /** PolygonStrokeArrowPrimitive2D class + + This primitive defines a PolygonStrokePrimitive2D which is extended + eventually by start and end definitions which are normally used for + arrows. + */ class PolygonStrokeArrowPrimitive2D : public PolygonStrokePrimitive2D { private: + /// geometric definitions for line start and end attribute::LineStartEndAttribute maStart; attribute::LineStartEndAttribute maEnd; protected: - // local decomposition. - virtual Primitive2DSequence createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + /// local decomposition. + virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; public: + /// constructor PolygonStrokeArrowPrimitive2D( const basegfx::B2DPolygon& rPolygon, const attribute::LineAttribute& rLineAttribute, @@ -241,23 +299,24 @@ namespace drawinglayer const attribute::LineStartEndAttribute& rStart, const attribute::LineStartEndAttribute& rEnd); + /// constructor without stroking PolygonStrokeArrowPrimitive2D( const basegfx::B2DPolygon& rPolygon, const attribute::LineAttribute& rLineAttribute, const attribute::LineStartEndAttribute& rStart, const attribute::LineStartEndAttribute& rEnd); - // get data + /// data read access const attribute::LineStartEndAttribute& getStart() const { return maStart; } const attribute::LineStartEndAttribute& getEnd() const { return maEnd; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive2D& rPrimitive) const; - // get range + /// get range virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const; - // provide unique ID + /// provide unique ID DeclPrimitrive2DIDBlock() }; } // end of namespace primitive2d diff --git a/drawinglayer/inc/drawinglayer/primitive2d/polypolygonprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/polypolygonprimitive2d.hxx index 9991a3109e10..187e89f42e97 100644 --- a/drawinglayer/inc/drawinglayer/primitive2d/polypolygonprimitive2d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive2d/polypolygonprimitive2d.hxx @@ -51,30 +51,40 @@ namespace drawinglayer { namespace primitive2d { - class PolyPolygonHairlinePrimitive2D : public BasePrimitive2D + /** PolyPolygonHairlinePrimitive2D class + + This primitive defines a multi-PolygonHairlinePrimitive2D and is + just for convenience. The definition is not different from the single + defined PolygonHairlinePrimitive2Ds. + */ + class PolyPolygonHairlinePrimitive2D : public BufferedDecompositionPrimitive2D { private: + /// the hairline geometry basegfx::B2DPolyPolygon maPolyPolygon; + + /// the hairline color basegfx::BColor maBColor; protected: - // local decomposition. - virtual Primitive2DSequence createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + /// local decomposition. + virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; public: + /// constructor PolyPolygonHairlinePrimitive2D(const basegfx::B2DPolyPolygon& rPolyPolygon, const basegfx::BColor& rBColor); - // get data + /// data read access basegfx::B2DPolyPolygon getB2DPolyPolygon() const { return maPolyPolygon; } const basegfx::BColor& getBColor() const { return maBColor; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive2D& rPrimitive) const; - // get range + /// get range virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const; - // provide unique ID + /// provide unique ID DeclPrimitrive2DIDBlock() }; } // end of namespace primitive2d @@ -87,38 +97,50 @@ namespace drawinglayer { namespace primitive2d { - class PolyPolygonMarkerPrimitive2D : public BasePrimitive2D + /** PolyPolygonMarkerPrimitive2D class + + This primitive defines a multi-PolygonMarkerPrimitive2D and is + just for convenience. The definition is not different from the single + defined PolygonMarkerPrimitive2Ds. + */ + class PolyPolygonMarkerPrimitive2D : public BufferedDecompositionPrimitive2D { private: + /// the marker hairline geometry basegfx::B2DPolyPolygon maPolyPolygon; + + /// the two colors basegfx::BColor maRGBColorA; basegfx::BColor maRGBColorB; + + /// the dash distance in 'pixels' double mfDiscreteDashLength; protected: - // local decomposition. - virtual Primitive2DSequence createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + /// local decomposition. + virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; public: + /// constructor PolyPolygonMarkerPrimitive2D( const basegfx::B2DPolyPolygon& rPolyPolygon, const basegfx::BColor& rRGBColorA, const basegfx::BColor& rRGBColorB, double fDiscreteDashLength); - // get data + // data read access basegfx::B2DPolyPolygon getB2DPolyPolygon() const { return maPolyPolygon; } const basegfx::BColor& getRGBColorA() const { return maRGBColorA; } const basegfx::BColor& getRGBColorB() const { return maRGBColorB; } double getDiscreteDashLength() const { return mfDiscreteDashLength; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive2D& rPrimitive) const; - // get range + /// get range virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const; - // provide unique ID + /// provide unique ID DeclPrimitrive2DIDBlock() }; } // end of namespace primitive2d @@ -131,39 +153,52 @@ namespace drawinglayer { namespace primitive2d { - class PolyPolygonStrokePrimitive2D : public BasePrimitive2D + /** PolyPolygonStrokePrimitive2D class + + This primitive defines a multi-PolygonStrokePrimitive2D and is + just for convenience. The definition is not different from the single + defined PolygonStrokePrimitive2Ds. + */ + class PolyPolygonStrokePrimitive2D : public BufferedDecompositionPrimitive2D { private: + /// the line geometry basegfx::B2DPolyPolygon maPolyPolygon; + + /// the line attributes like width, join and color attribute::LineAttribute maLineAttribute; + + /// the line stroking (if used) attribute::StrokeAttribute maStrokeAttribute; protected: - // local decomposition. - virtual Primitive2DSequence createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + /// local decomposition. + virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; public: + /// constructor PolyPolygonStrokePrimitive2D( const basegfx::B2DPolyPolygon& rPolyPolygon, const attribute::LineAttribute& rLineAttribute, const attribute::StrokeAttribute& rStrokeAttribute); + /// constructor without stroking PolyPolygonStrokePrimitive2D( const basegfx::B2DPolyPolygon& rPolyPolygon, const attribute::LineAttribute& rLineAttribute); - // get data + /// data read access basegfx::B2DPolyPolygon getB2DPolyPolygon() const { return maPolyPolygon; } const attribute::LineAttribute& getLineAttribute() const { return maLineAttribute; } const attribute::StrokeAttribute& getStrokeAttribute() const { return maStrokeAttribute; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive2D& rPrimitive) const; - // get range + /// get range virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const; - // provide unique ID + /// provide unique ID DeclPrimitrive2DIDBlock() }; } // end of namespace primitive2d @@ -176,17 +211,25 @@ namespace drawinglayer { namespace primitive2d { + /** PolyPolygonStrokePrimitive2D class + + This primitive defines a multi-PolygonStrokeArrowPrimitive2D and is + just for convenience. The definition is not different from the single + defined PolygonStrokeArrowPrimitive2Ds. + */ class PolyPolygonStrokeArrowPrimitive2D : public PolyPolygonStrokePrimitive2D { private: + /// geometric definitions for line start and end attribute::LineStartEndAttribute maStart; attribute::LineStartEndAttribute maEnd; protected: - // local decomposition. - virtual Primitive2DSequence createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + /// local decomposition. + virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; public: + /// constructor PolyPolygonStrokeArrowPrimitive2D( const basegfx::B2DPolyPolygon& rPolyPolygon, const attribute::LineAttribute& rLineAttribute, @@ -194,23 +237,24 @@ namespace drawinglayer const attribute::LineStartEndAttribute& rStart, const attribute::LineStartEndAttribute& rEnd); + /// constructor without stroking PolyPolygonStrokeArrowPrimitive2D( const basegfx::B2DPolyPolygon& rPolyPolygon, const attribute::LineAttribute& rLineAttribute, const attribute::LineStartEndAttribute& rStart, const attribute::LineStartEndAttribute& rEnd); - // get data + /// data read access const attribute::LineStartEndAttribute& getStart() const { return maStart; } const attribute::LineStartEndAttribute& getEnd() const { return maEnd; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive2D& rPrimitive) const; - // get range + /// get range virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const; - // provide unique ID + /// provide unique ID DeclPrimitrive2DIDBlock() }; } // end of namespace primitive2d @@ -223,28 +267,38 @@ namespace drawinglayer { namespace primitive2d { + /** PolyPolygonColorPrimitive2D class + + This primitive defines a PolyPolygon filled with a single color. + This is one of the non-decomposable primitives, so a renderer + should proccess it. + */ class PolyPolygonColorPrimitive2D : public BasePrimitive2D { private: + /// the PolyPolygon geometry basegfx::B2DPolyPolygon maPolyPolygon; + + /// the polygon fill color basegfx::BColor maBColor; public: + /// constructor PolyPolygonColorPrimitive2D( const basegfx::B2DPolyPolygon& rPolyPolygon, const basegfx::BColor& rBColor); - // get data + /// data read access const basegfx::B2DPolyPolygon& getB2DPolyPolygon() const { return maPolyPolygon; } const basegfx::BColor& getBColor() const { return maBColor; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive2D& rPrimitive) const; - // get range + /// get range virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const; - // provide unique ID + /// provide unique ID DeclPrimitrive2DIDBlock() }; } // end of namespace primitive2d @@ -257,28 +311,39 @@ namespace drawinglayer { namespace primitive2d { - class PolyPolygonGradientPrimitive2D : public PolyPolygonColorPrimitive2D + /** PolyPolygonColorPrimitive2D class + + This primitive defines a PolyPolygon filled with a gradient. The + decomosition will create a MaskPrimitive2D containing a + FillGradientPrimitive2D. + */ + class PolyPolygonGradientPrimitive2D : public BufferedDecompositionPrimitive2D { private: + /// the PolyPolygon geometry + basegfx::B2DPolyPolygon maPolyPolygon; + + /// the gradient definition attribute::FillGradientAttribute maFillGradient; protected: - // local decomposition. - virtual Primitive2DSequence createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + /// local decomposition. + virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; public: + /// constructor PolyPolygonGradientPrimitive2D( const basegfx::B2DPolyPolygon& rPolyPolygon, - const basegfx::BColor& rBColor, const attribute::FillGradientAttribute& rFillGradient); - // get data + /// data read access + const basegfx::B2DPolyPolygon& getB2DPolyPolygon() const { return maPolyPolygon; } const attribute::FillGradientAttribute& getFillGradient() const { return maFillGradient; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive2D& rPrimitive) const; - // provide unique ID + /// provide unique ID DeclPrimitrive2DIDBlock() }; } // end of namespace primitive2d @@ -291,28 +356,44 @@ namespace drawinglayer { namespace primitive2d { - class PolyPolygonHatchPrimitive2D : public PolyPolygonColorPrimitive2D + /** PolyPolygonHatchPrimitive2D class + + This primitive defines a PolyPolygon filled with a hatch. The + decomosition will create a MaskPrimitive2D containing a + FillHatchPrimitive2D. + */ + class PolyPolygonHatchPrimitive2D : public BufferedDecompositionPrimitive2D { private: + /// the PolyPolygon geometry + basegfx::B2DPolyPolygon maPolyPolygon; + + /// the hatch background color (if used) + basegfx::BColor maBackgroundColor; + + /// the hatch definition attribute::FillHatchAttribute maFillHatch; protected: - // local decomposition. - virtual Primitive2DSequence createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + /// local decomposition. + virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; public: + /// constructor PolyPolygonHatchPrimitive2D( const basegfx::B2DPolyPolygon& rPolyPolygon, - const basegfx::BColor& rBColor, + const basegfx::BColor& rBackgroundColor, const attribute::FillHatchAttribute& rFillHatch); - // get data + /// data read access + const basegfx::B2DPolyPolygon& getB2DPolyPolygon() const { return maPolyPolygon; } + const basegfx::BColor& getBackgroundColor() const { return maBackgroundColor; } const attribute::FillHatchAttribute& getFillHatch() const { return maFillHatch; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive2D& rPrimitive) const; - // provide unique ID + /// provide unique ID DeclPrimitrive2DIDBlock() }; } // end of namespace primitive2d @@ -325,28 +406,39 @@ namespace drawinglayer { namespace primitive2d { - class PolyPolygonBitmapPrimitive2D : public PolyPolygonColorPrimitive2D + /** PolyPolygonBitmapPrimitive2D class + + This primitive defines a PolyPolygon filled with bitmap data + (including alpha). The decomosition will create a MaskPrimitive2D + containing a FillBitmapPrimitive2D. + */ + class PolyPolygonBitmapPrimitive2D : public BufferedDecompositionPrimitive2D { private: + /// the PolyPolygon geometry + basegfx::B2DPolyPolygon maPolyPolygon; + + /// the bitmap fill definition (may include tiling) attribute::FillBitmapAttribute maFillBitmap; protected: - // local decomposition. - virtual Primitive2DSequence createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + /// local decomposition. + virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; public: + /// constructor PolyPolygonBitmapPrimitive2D( const basegfx::B2DPolyPolygon& rPolyPolygon, - const basegfx::BColor& rBColor, const attribute::FillBitmapAttribute& rFillBitmap); - // get data + /// data read access + const basegfx::B2DPolyPolygon& getB2DPolyPolygon() const { return maPolyPolygon; } const attribute::FillBitmapAttribute& getFillBitmap() const { return maFillBitmap; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive2D& rPrimitive) const; - // provide unique ID + /// provide unique ID DeclPrimitrive2DIDBlock() }; } // end of namespace primitive2d diff --git a/drawinglayer/inc/drawinglayer/primitive2d/primitivetools2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/primitivetools2d.hxx index bd561cbab21a..a095c558ba12 100644 --- a/drawinglayer/inc/drawinglayer/primitive2d/primitivetools2d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive2d/primitivetools2d.hxx @@ -37,70 +37,163 @@ #define INCLUDED_DRAWINGLAYER_PRIMITIVE2D_PRIMITIVE2DTOOLS_HXX #include <drawinglayer/primitive2d/baseprimitive2d.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> ////////////////////////////////////////////////////////////////////////////// -// tooling class for BasePrimitive2D baseed classes which are view-dependent -// regarding the size of a discrete unit. The implementation of get2DDecomposition -// guards the buffered local decomposition and ensures that a createLocalDecomposition -// implementation may use an up-to-date DiscreteUnit accessible using getDiscreteUnit() namespace drawinglayer { namespace primitive2d { - class DiscreteMetricDependentPrimitive2D : public BasePrimitive2D + /** DiscreteMetricDependentPrimitive2D class + + tooling class for BufferedDecompositionPrimitive2D baseed classes which are view-dependent + regarding the size of a discrete unit. The implementation of get2DDecomposition + guards the buffered local decomposition and ensures that a create2DDecomposition + implementation may use an up-to-date DiscreteUnit accessible using getDiscreteUnit() + */ + class DiscreteMetricDependentPrimitive2D : public BufferedDecompositionPrimitive2D { private: - // the last used fDiscreteUnit definitions for decomposition. Since this - // is checked and updated from get2DDecomposition() it will be current and - // usable in createLocalDecomposition() + /** the last used fDiscreteUnit definitions for decomposition. Since this + is checked and updated from get2DDecomposition() it will be current and + usable in create2DDecomposition() + */ double mfDiscreteUnit; public: + /// constructor DiscreteMetricDependentPrimitive2D() - : BasePrimitive2D(), + : BufferedDecompositionPrimitive2D(), mfDiscreteUnit(0.0) { } - // data access + /// data read access double getDiscreteUnit() const { return mfDiscreteUnit; } - // get local decomposition. Overloaded since this decomposition is view-dependent + /// get local decomposition. Overloaded since this decomposition is view-dependent virtual Primitive2DSequence get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; }; } // end of namespace primitive2d } // end of namespace drawinglayer ////////////////////////////////////////////////////////////////////////////// -// tooling class for BasePrimitive2D baseed classes which are view-dependent -// regarding the viewport. The implementation of get2DDecomposition -// guards the buffered local decomposition and ensures that a createLocalDecomposition -// implementation may use an up-to-date Viewport accessible using getViewport() namespace drawinglayer { namespace primitive2d { - class ViewportDependentPrimitive2D : public BasePrimitive2D + /** ViewportDependentPrimitive2D class + + tooling class for BufferedDecompositionPrimitive2D baseed classes which are view-dependent + regarding the viewport. The implementation of get2DDecomposition + guards the buffered local decomposition and ensures that a create2DDecomposition + implementation may use an up-to-date Viewport accessible using getViewport() + */ + class ViewportDependentPrimitive2D : public BufferedDecompositionPrimitive2D { private: - // the last used Viewport definition for decomposition. Since this - // is checked and updated from get2DDecomposition() it will be current and - // usable in createLocalDecomposition() + /** the last used Viewport definition for decomposition. Since this + is checked and updated from get2DDecomposition() it will be current and + usable in create2DDecomposition() + */ basegfx::B2DRange maViewport; public: + /// constructor ViewportDependentPrimitive2D() - : BasePrimitive2D(), + : BufferedDecompositionPrimitive2D(), maViewport() { } - // data access + /// data read access const basegfx::B2DRange& getViewport() const { return maViewport; } - // get local decomposition. Overloaded since this decomposition is view-dependent + /// get local decomposition. Overloaded since this decomposition is view-dependent + virtual Primitive2DSequence get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + }; + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + /** ViewTransformationDependentPrimitive2D class + + tooling class for BufferedDecompositionPrimitive2D based classes which are view-dependent + regarding the complete Viewtransformation. The implementation of get2DDecomposition + guards the buffered local decomposition and ensures that a create2DDecomposition + implementation may use an up-to-date ViewTransformation accessible using getViewTransformation() + */ + class ViewTransformationDependentPrimitive2D : public BufferedDecompositionPrimitive2D + { + private: + /** the last used ViewTransformation definition for decomposition. Since this + is checked and updated from get2DDecomposition() it will be current and + usable in create2DDecomposition() + */ + basegfx::B2DHomMatrix maViewTransformation; + + public: + /// constructor + ViewTransformationDependentPrimitive2D() + : BufferedDecompositionPrimitive2D(), + maViewTransformation() + { + } + + /// data read access + const basegfx::B2DHomMatrix& getViewTransformation() const { return maViewTransformation; } + + /// get local decomposition. Overloaded since this decomposition is view-dependent + virtual Primitive2DSequence get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + }; + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + /** ObjectAndViewTransformationDependentPrimitive2D class + + tooling class for BufferedDecompositionPrimitive2D based classes which are view-dependent + and Object-Transform dependent. The implementation of get2DDecomposition + guards the buffered local decomposition and ensures that a create2DDecomposition + implementation may use an up-to-date ViewTransformation accessible using getViewTransformation() + and an object transformation via getObjectTransformation() + */ + class ObjectAndViewTransformationDependentPrimitive2D : public BufferedDecompositionPrimitive2D + { + private: + /** the last used ViewTransformation and the last ObjectTransformation + definition for decomposition. Since this is checked and updated from + get2DDecomposition() it will be current and usable in create2DDecomposition() + */ + basegfx::B2DHomMatrix maViewTransformation; + basegfx::B2DHomMatrix maObjectTransformation; + + public: + /// constructor + ObjectAndViewTransformationDependentPrimitive2D() + : BufferedDecompositionPrimitive2D(), + maViewTransformation(), + maObjectTransformation() + { + } + + /// data read access + const basegfx::B2DHomMatrix& getViewTransformation() const { return maViewTransformation; } + const basegfx::B2DHomMatrix& getObjectTransformation() const { return maObjectTransformation; } + + /// get local decomposition. Overloaded since this decomposition is view-dependent virtual Primitive2DSequence get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; }; } // end of namespace primitive2d diff --git a/drawinglayer/inc/drawinglayer/primitive2d/sceneprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/sceneprimitive2d.hxx index 8ffc9a332e5c..65d2bdf67f92 100644 --- a/drawinglayer/inc/drawinglayer/primitive2d/sceneprimitive2d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive2d/sceneprimitive2d.hxx @@ -49,33 +49,60 @@ namespace drawinglayer { namespace primitive2d { - class ScenePrimitive2D : public BasePrimitive2D + /** ScenePrimitive2D class + + This primitive defines a 3D scene as a 2D primitive and is the anchor point + for a 3D visualisation. The decomposition is view-dependent and will try to + re-use already rendered 3D content. + + The rendering is done using the default-3D renderer from basegfx which supports + AntiAliasing. + + The 2D primitive's geometric range is defined completely by the + ObjectTransformation combined with evtl. 2D shadows from the 3D objects. The + shadows of 3D objects are 2D polygons, projected with the 3D transformation. + + This is the class a renderer may process directly when he wants to implement + an own (e.g. system-specific) 3D renderer. + */ + class ScenePrimitive2D : public BufferedDecompositionPrimitive2D { private: - primitive3d::Primitive3DSequence mxChildren3D; // the 3d sub-primitives - attribute::SdrSceneAttribute maSdrSceneAttribute; // 3d scene attribute set - attribute::SdrLightingAttribute maSdrLightingAttribute; // lighting attribute set - basegfx::B2DHomMatrix maObjectTransformation; // object transformation for scene for 2d definition - geometry::ViewInformation3D maViewInformation3D; // scene transformation set and object transformation + /// the 3D geometry definition + primitive3d::Primitive3DSequence mxChildren3D; + + /// 3D scene attribute set + attribute::SdrSceneAttribute maSdrSceneAttribute; + + /// lighting attribute set + attribute::SdrLightingAttribute maSdrLightingAttribute; + + /// object transformation for scene for 2D definition + basegfx::B2DHomMatrix maObjectTransformation; + + /// scene transformation set and object transformation + geometry::ViewInformation3D maViewInformation3D; - // the primitiveSequence for on-demand created shadow primitives (see mbShadow3DChecked) + /// the primitiveSequence for on-demand created shadow primitives (see mbShadow3DChecked) Primitive2DSequence maShadowPrimitives; - // bitfield - // flag if given 3D geometry is already cheched for shadow definitions and 2d shadows - // are created in maShadowPrimitives + /// bitfield + /** flag if given 3D geometry is already cheched for shadow definitions and 2d shadows + are created in maShadowPrimitives + */ unsigned mbShadow3DChecked : 1; - // the last used NewDiscreteSize and NewUnitVisiblePart definitions for decomposition + /// the last used NewDiscreteSize and NewUnitVisiblePart definitions for decomposition double mfOldDiscreteSizeX; double mfOldDiscreteSizeY; basegfx::B2DRange maOldUnitVisiblePart; - // the last created BitmapEx, e.g. for fast HitTest. This does not really need - // memory since BitmapEx is internally RefCounted + /** the last created BitmapEx, e.g. for fast HitTest. This does not really need + memory since BitmapEx is internally RefCounted + */ BitmapEx maOldRenderedBitmap; - // private helpers + /// private helpers bool impGetShadow3D(const geometry::ViewInformation2D& rViewInformation) const; void calculateDiscreteSizes( const geometry::ViewInformation2D& rViewInformation, @@ -84,28 +111,30 @@ namespace drawinglayer basegfx::B2DRange& rUnitVisibleRange) const; protected: - // local decomposition. - virtual Primitive2DSequence createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + /// local decomposition. + virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; public: - // public helpers - // Geometry extractor. Shadow will be added as in createLocalDecomposition, but - // the 3D content is not converted to a bitmap visualisation but to projected 2D gemetry. This - // helper is useful e.g. for Contour extraction or HitTests. + /// public helpers + /** Geometry extractor. Shadow will be added as in create2DDecomposition, but + the 3D content is not converted to a bitmap visualisation but to projected 2D gemetry. This + helper is useful e.g. for Contour extraction or HitTests. + */ Primitive2DSequence getGeometry2D() const; Primitive2DSequence getShadow2D(const geometry::ViewInformation2D& rViewInformation) const; - // Fast HitTest which uses the last buffered BitmapEx from the last - // rendered area if available. The return value describes if the check - // could be done with the current information, so do NOT use o_rResult - // when it returns false. o_rResult will be changed on return true and - // then contains a definitive answer if content of this scene is hit or - // not. On return false, it is normally necessary to use the geometric - // HitTest (see CutFindProcessor usages). The given HitPoint - // has to be in logic coordinates in scene's ObjectCoordinateSystem. + /** Fast HitTest which uses the last buffered BitmapEx from the last + rendered area if available. The return value describes if the check + could be done with the current information, so do NOT use o_rResult + when it returns false. o_rResult will be changed on return true and + then contains a definitive answer if content of this scene is hit or + not. On return false, it is normally necessary to use the geometric + HitTest (see CutFindProcessor usages). The given HitPoint + has to be in logic coordinates in scene's ObjectCoordinateSystem. + */ bool tryToCheckLastVisualisationDirectHit(const basegfx::B2DPoint& rLogicHitPoint, bool& o_rResult) const; - // constructor/destructor + /// constructor ScenePrimitive2D( const primitive3d::Primitive3DSequence& rxChildren3D, const attribute::SdrSceneAttribute& rSdrSceneAttribute, @@ -113,23 +142,23 @@ namespace drawinglayer const basegfx::B2DHomMatrix& rObjectTransformation, const geometry::ViewInformation3D& rViewInformation3D); - // get data + /// data ead access const primitive3d::Primitive3DSequence& getChildren3D() const { return mxChildren3D; } const attribute::SdrSceneAttribute& getSdrSceneAttribute() const { return maSdrSceneAttribute; } const attribute::SdrLightingAttribute& getSdrLightingAttribute() const { return maSdrLightingAttribute; } const basegfx::B2DHomMatrix& getObjectTransformation() const { return maObjectTransformation; } const geometry::ViewInformation3D& getViewInformation3D() const { return maViewInformation3D; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive2D& rPrimitive) const; - // get range + /// get range virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const; - // provide unique ID + /// provide unique ID DeclPrimitrive2DIDBlock() - // get local decomposition. Overloaded since this decomposition is view-dependent + /// get local decomposition. Overloaded since this decomposition is view-dependent virtual Primitive2DSequence get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; }; } // end of namespace primitive2d diff --git a/drawinglayer/inc/drawinglayer/primitive2d/shadowprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/shadowprimitive2d.hxx index b749000ee566..0e3f7258441a 100644 --- a/drawinglayer/inc/drawinglayer/primitive2d/shadowprimitive2d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive2d/shadowprimitive2d.hxx @@ -46,33 +46,50 @@ namespace drawinglayer { namespace primitive2d { + /** ShadowPrimitive2D class + + This primitive defines a generic shadow geometry construction + for 2D objects. It decomposes to a TransformPrimitive2D embedded + into a ModifiedColorPrimitive2D. + + It's for primtive usage convenience, so that not everyone has + to implement the generic shadow construction by himself. + + The same geometry as sequence of primitives is used as geometry and + as shadow. Since these are RefCounted Uno-Api objects, no extra objects + are needed for the shadow itself; all the local decompositions of the + original geometry can be reused from the renderer for shadow visualisation. + */ class ShadowPrimitive2D : public GroupPrimitive2D { private: + /// the shadow transformation, normally just an offset basegfx::B2DHomMatrix maShadowTransform; - basegfx::BColor maShadowColor; - protected: - // create decomposition - virtual Primitive2DSequence createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + /// the shadow color to which all geometry is to be forced + basegfx::BColor maShadowColor; public: + /// constructor ShadowPrimitive2D( const basegfx::B2DHomMatrix& rShadowTransform, const basegfx::BColor& rShadowColor, const Primitive2DSequence& rChildren); - // get data + /// data read access const basegfx::B2DHomMatrix& getShadowTransform() const { return maShadowTransform; } const basegfx::BColor& getShadowColor() const { return maShadowColor; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive2D& rPrimitive) const; - // get range + /// get range virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const; - // provide unique ID + /// create decomposition + virtual Primitive2DSequence get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + + /// provide unique ID DeclPrimitrive2DIDBlock() }; } // end of namespace primitive2d diff --git a/drawinglayer/inc/drawinglayer/primitive2d/structuretagprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/structuretagprimitive2d.hxx index 9ccb91e7bebd..c86e4c91bb86 100644 --- a/drawinglayer/inc/drawinglayer/primitive2d/structuretagprimitive2d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive2d/structuretagprimitive2d.hxx @@ -45,30 +45,34 @@ namespace drawinglayer { namespace primitive2d { - // This class is used to provode simple support for adding grouped - // pdf writer structured element information like used in sd from - // unomodel.cxx where a ViewObjectContactRedirector is used to add - // such information for diverse objects. - // This primitive encapsulates these and the VCLPdfRenderer uses it - // to apply the needed infos directly to the pdf export in a compatible - // way. - // If a renderer ignores this, it just decomposes to it's child - // content. + /** StructureTagPrimitive2D class + + This class is used to provode simple support for adding grouped + pdf writer structured element information like used in sd from + unomodel.cxx where a ViewObjectContactRedirector is used to add + such information for diverse objects. + This primitive encapsulates these and the VCLPdfRenderer uses it + to apply the needed infos directly to the pdf export in a compatible + way. + If a renderer ignores this, it just decomposes to it's child + content. + */ class StructureTagPrimitive2D : public GroupPrimitive2D { private: - // the PDF structure element this grouping represents + /// the PDF structure element this grouping represents vcl::PDFWriter::StructElement maStructureElement; public: + /// constructor StructureTagPrimitive2D( const vcl::PDFWriter::StructElement& rStructureElement, const Primitive2DSequence& rChildren); - // data access + /// data read access const vcl::PDFWriter::StructElement& getStructureElement() const { return maStructureElement; } - // provide unique ID + /// provide unique ID DeclPrimitrive2DIDBlock() }; } // end of namespace primitive2d diff --git a/drawinglayer/inc/drawinglayer/primitive2d/textdecoratedprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/textdecoratedprimitive2d.hxx index 69023873760a..fe41c2e1824a 100644 --- a/drawinglayer/inc/drawinglayer/primitive2d/textdecoratedprimitive2d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive2d/textdecoratedprimitive2d.hxx @@ -37,13 +37,14 @@ #define INCLUDED_DRAWINGLAYER_PRIMITIVE2D_TEXTDECORATEDPRIMITIVE2D_HXX #include <drawinglayer/primitive2d/textprimitive2d.hxx> +#include <drawinglayer/primitive2d/textenumsprimitive2d.hxx> ////////////////////////////////////////////////////////////////////////////// // predeclarations -namespace basegfx { - class DecomposedB2DHomMatrixContainer; -} // end of namespace basegfx +namespace basegfx { namespace tools { + class B2DHomMatrixBufferedOnDemandDecompose; +}} namespace com { namespace sun { namespace star { namespace i18n { struct Boundary; @@ -55,153 +56,102 @@ namespace drawinglayer { namespace primitive2d { - // This is used for both underline and overline - enum FontUnderline - { - FONT_UNDERLINE_NONE, - FONT_UNDERLINE_SINGLE, - FONT_UNDERLINE_DOUBLE, - FONT_UNDERLINE_DOTTED, - FONT_UNDERLINE_DASH, - FONT_UNDERLINE_LONGDASH, - FONT_UNDERLINE_DASHDOT, - FONT_UNDERLINE_DASHDOTDOT, - FONT_UNDERLINE_SMALLWAVE, - FONT_UNDERLINE_WAVE, - FONT_UNDERLINE_DOUBLEWAVE, - FONT_UNDERLINE_BOLD, - FONT_UNDERLINE_BOLDDOTTED, - FONT_UNDERLINE_BOLDDASH, - FONT_UNDERLINE_BOLDLONGDASH, - FONT_UNDERLINE_BOLDDASHDOT, - FONT_UNDERLINE_BOLDDASHDOTDOT, - FONT_UNDERLINE_BOLDWAVE - }; - - enum FontStrikeout - { - FONT_STRIKEOUT_NONE, - FONT_STRIKEOUT_SINGLE, - FONT_STRIKEOUT_DOUBLE, - FONT_STRIKEOUT_BOLD, - FONT_STRIKEOUT_SLASH, - FONT_STRIKEOUT_X - }; - - enum FontEmphasisMark - { - FONT_EMPHASISMARK_NONE, - FONT_EMPHASISMARK_DOT, - FONT_EMPHASISMARK_CIRCLE, - FONT_EMPHASISMARK_DISC, - FONT_EMPHASISMARK_ACCENT - }; - - enum FontRelief - { - FONT_RELIEF_NONE, - FONT_RELIEF_EMBOSSED, - FONT_RELIEF_ENGRAVED - }; + /** TextDecoratedPortionPrimitive2D class + This primitive expands the TextSimplePortionPrimitive2D by common + decorations used in the office. It can be decomposed and will create + a TextSimplePortionPrimitive2D and all the contained decorations (if used) + as geometry. + */ class TextDecoratedPortionPrimitive2D : public TextSimplePortionPrimitive2D { private: + /// decoration definitions basegfx::BColor maOverlineColor; basegfx::BColor maTextlineColor; - FontUnderline meFontOverline; - FontUnderline meFontUnderline; - FontStrikeout meFontStrikeout; - FontEmphasisMark meFontEmphasisMark; - FontRelief meFontRelief; + TextLine meFontOverline; + TextLine meFontUnderline; + TextStrikeout meTextStrikeout; + TextEmphasisMark meTextEmphasisMark; + TextRelief meTextRelief; - // bitfield + /// bitfield unsigned mbUnderlineAbove : 1; unsigned mbWordLineMode : 1; unsigned mbEmphasisMarkAbove : 1; unsigned mbEmphasisMarkBelow : 1; unsigned mbShadow : 1; - // helper methods - void impCreateTextLine( - std::vector< Primitive2DReference >& rTarget, - basegfx::DecomposedB2DHomMatrixContainer& rDecTrans, - const basegfx::B2DHomMatrix &rUnscaledTransform, - FontUnderline eLineStyle, - double fLineOffset, - double fLineHeight, - double fLineWidth, - const basegfx::BColor& rLineColor) const; - + /// helper methods void impCreateGeometryContent( std::vector< Primitive2DReference >& rTarget, - basegfx::DecomposedB2DHomMatrixContainer& rDecTrans, + basegfx::tools::B2DHomMatrixBufferedOnDemandDecompose& rDecTrans, const String& rText, xub_StrLen aTextPosition, xub_StrLen aTextLength, const ::std::vector< double >& rDXArray, - const FontAttributes& rFontAttributes) const; + const attribute::FontAttribute& rFontAttribute) const; void impCorrectTextBoundary( ::com::sun::star::i18n::Boundary& rNextWordBoundary) const; void impSplitSingleWords( std::vector< Primitive2DReference >& rTarget, - basegfx::DecomposedB2DHomMatrixContainer& rDecTrans) const; + basegfx::tools::B2DHomMatrixBufferedOnDemandDecompose& rDecTrans) const; protected: - // local decomposition. - virtual Primitive2DSequence createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + /// local decomposition. + virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; public: + /// constructor TextDecoratedPortionPrimitive2D( - // TextSimplePortionPrimitive2D parameters + /// TextSimplePortionPrimitive2D parameters const basegfx::B2DHomMatrix& rNewTransform, const String& rText, xub_StrLen aTextPosition, xub_StrLen aTextLength, const ::std::vector< double >& rDXArray, - const FontAttributes& rFontAttributes, + const attribute::FontAttribute& rFontAttribute, const ::com::sun::star::lang::Locale& rLocale, const basegfx::BColor& rFontColor, - // local parameters + /// local parameters const basegfx::BColor& rOverlineColor, const basegfx::BColor& rTextlineColor, - FontUnderline eFontOverline = FONT_UNDERLINE_NONE, - FontUnderline eFontUnderline = FONT_UNDERLINE_NONE, + TextLine eFontOverline = TEXT_LINE_NONE, + TextLine eFontUnderline = TEXT_LINE_NONE, bool bUnderlineAbove = false, - FontStrikeout eFontStrikeout = FONT_STRIKEOUT_NONE, + TextStrikeout eTextStrikeout = TEXT_STRIKEOUT_NONE, bool bWordLineMode = false, - FontEmphasisMark eFontEmphasisMark = FONT_EMPHASISMARK_NONE, + TextEmphasisMark eTextEmphasisMark = TEXT_EMPHASISMARK_NONE, bool bEmphasisMarkAbove = true, bool bEmphasisMarkBelow = false, - FontRelief eFontRelief = FONT_RELIEF_NONE, + TextRelief eTextRelief = TEXT_RELIEF_NONE, bool bShadow = false); - // get data - FontUnderline getFontOverline() const { return meFontOverline; } - FontUnderline getFontUnderline() const { return meFontUnderline; } - FontStrikeout getFontStrikeout() const { return meFontStrikeout; } - FontEmphasisMark getFontEmphasisMark() const { return meFontEmphasisMark; } - FontRelief getFontRelief() const { return meFontRelief; } + /// data read access + TextLine getFontOverline() const { return meFontOverline; } + TextLine getFontUnderline() const { return meFontUnderline; } + TextStrikeout getTextStrikeout() const { return meTextStrikeout; } + TextEmphasisMark getTextEmphasisMark() const { return meTextEmphasisMark; } + TextRelief getTextRelief() const { return meTextRelief; } basegfx::BColor getOverlineColor() const { return maOverlineColor; } basegfx::BColor getTextlineColor() const { return maTextlineColor; } - bool getUnderlineAbove() const { return mbUnderlineAbove; } bool getWordLineMode() const { return mbWordLineMode; } bool getEmphasisMarkAbove() const { return mbEmphasisMarkAbove; } bool getEmphasisMarkBelow() const { return mbEmphasisMarkBelow; } bool getShadow() const { return mbShadow; } - // compare operator + /// compare operator virtual bool operator==( const BasePrimitive2D& rPrimitive ) const; - // get range + /// get range virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const; - // provide unique ID + /// provide unique ID DeclPrimitrive2DIDBlock() }; } // end of namespace primitive2d diff --git a/drawinglayer/inc/drawinglayer/primitive2d/texteffectprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/texteffectprimitive2d.hxx index 128b1ea5a210..77b64d16ea24 100644 --- a/drawinglayer/inc/drawinglayer/primitive2d/texteffectprimitive2d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive2d/texteffectprimitive2d.hxx @@ -36,7 +36,7 @@ #ifndef INCLUDED_DRAWINGLAYER_PRIMITIVE2D_TEXTEFFECTPRIMITIVE2D_HXX #define INCLUDED_DRAWINGLAYER_PRIMITIVE2D_TEXTEFFECTPRIMITIVE2D_HXX -#include <drawinglayer/primitive2d/groupprimitive2d.hxx> +#include <drawinglayer/primitive2d/baseprimitive2d.hxx> #include <basegfx/matrix/b2dhommatrix.hxx> ////////////////////////////////////////////////////////////////////////////// @@ -45,6 +45,7 @@ namespace drawinglayer { namespace primitive2d { + /** TextEffectStyle2D definition */ enum TextEffectStyle2D { TEXTEFFECTSTYLE2D_RELIEF_EMBOSSED_DEFAULT, @@ -54,46 +55,59 @@ namespace drawinglayer TEXTEFFECTSTYLE2D_OUTLINE }; - class TextEffectPrimitive2D : public GroupPrimitive2D + /** TextEffectPrimitive2D class + + This primitive embeds text primitives (normally, as can be seen can + also be used for any other primitives) which have some TextEffect applied + and create the needed geometry and embedding on decomposition. + */ + class TextEffectPrimitive2D : public BufferedDecompositionPrimitive2D { private: - // the style to apply, the direction and the rotation center + /// the text (or other) content + Primitive2DSequence maTextContent; + + /// the style to apply, the direction and the rotation center const basegfx::B2DPoint maRotationCenter; double mfDirection; TextEffectStyle2D meTextEffectStyle2D; - // the last used object to view transformtion used from getDecomposition - // for decide buffering + /** the last used object to view transformtion used from getDecomposition + for decide buffering + */ basegfx::B2DHomMatrix maLastObjectToViewTransformation; protected: - // create local decomposition - virtual Primitive2DSequence createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + /// create local decomposition + virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; public: + /// construcor TextEffectPrimitive2D( - const Primitive2DSequence& rChildren, + const Primitive2DSequence& rTextContent, const basegfx::B2DPoint& rRotationCenter, double fDirection, TextEffectStyle2D eTextEffectStyle2D); - // get data + /// data read access + const Primitive2DSequence& getTextContent() const { return maTextContent; } const basegfx::B2DPoint& getRotationCenter() const { return maRotationCenter; } double getDirection() const { return mfDirection; } TextEffectStyle2D getTextEffectStyle2D() const { return meTextEffectStyle2D; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive2D& rPrimitive) const; - // own get range implementation to solve more effective. Content is by definition displaced - // by a fixed discrete unit, thus the contained geometry needs only once be asked for it's - // own basegfx::B2DRange + /** own get range implementation to solve more effective. Content is by definition displaced + by a fixed discrete unit, thus the contained geometry needs only once be asked for it's + own basegfx::B2DRange + */ virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const; - // provide unique ID + /// provide unique ID DeclPrimitrive2DIDBlock() - // Overload standard getDecomposition call to be view-dependent here + /// Overload standard getDecomposition call to be view-dependent here virtual Primitive2DSequence get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; }; } // end of namespace primitive2d diff --git a/drawinglayer/inc/drawinglayer/primitive2d/textenumsprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/textenumsprimitive2d.hxx new file mode 100644 index 000000000000..b0e7dc8c241e --- /dev/null +++ b/drawinglayer/inc/drawinglayer/primitive2d/textenumsprimitive2d.hxx @@ -0,0 +1,119 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: wrongspellprimitive2d.hxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: aw $ $Date: 2008-05-27 14:11:17 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef INCLUDED_DRAWINGLAYER_PRIMITIVE2D_TEXTENUMSPRIMITIVE2D_HXX +#define INCLUDED_DRAWINGLAYER_PRIMITIVE2D_TEXTENUMSPRIMITIVE2D_HXX + +#include <drawinglayer/primitive2d/baseprimitive2d.hxx> +#include <vcl/vclenum.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + /** TextLine definition + + This is used for both underline and overline + */ + enum TextLine + { + TEXT_LINE_NONE, + TEXT_LINE_SINGLE, + TEXT_LINE_DOUBLE, + TEXT_LINE_DOTTED, + TEXT_LINE_DASH, + TEXT_LINE_LONGDASH, + TEXT_LINE_DASHDOT, + TEXT_LINE_DASHDOTDOT, + TEXT_LINE_SMALLWAVE, + TEXT_LINE_WAVE, + TEXT_LINE_DOUBLEWAVE, + TEXT_LINE_BOLD, + TEXT_LINE_BOLDDOTTED, + TEXT_LINE_BOLDDASH, + TEXT_LINE_BOLDLONGDASH, + TEXT_LINE_BOLDDASHDOT, + TEXT_LINE_BOLDDASHDOTDOT, + TEXT_LINE_BOLDWAVE + }; + + /** helper to convert LineStyle */ + TextLine mapFontUnderlineToTextLine(FontUnderline eLineStyle); + FontUnderline mapTextLineToFontUnderline(TextLine eLineStyle); + + /** FontStrikeout definition */ + enum TextStrikeout + { + TEXT_STRIKEOUT_NONE, + TEXT_STRIKEOUT_SINGLE, + TEXT_STRIKEOUT_DOUBLE, + TEXT_STRIKEOUT_BOLD, + TEXT_STRIKEOUT_SLASH, + TEXT_STRIKEOUT_X + }; + + /** helper to convert FontStrikeout */ + TextStrikeout mapFontStrikeoutToTextStrikeout(::FontStrikeout eFontStrikeout); + ::FontStrikeout mapTextStrikeoutToFontStrikeout(TextStrikeout eFontStrikeout); + + /** TextEmphasisMark definition */ + enum TextEmphasisMark + { + TEXT_EMPHASISMARK_NONE, + TEXT_EMPHASISMARK_DOT, + TEXT_EMPHASISMARK_CIRCLE, + TEXT_EMPHASISMARK_DISC, + TEXT_EMPHASISMARK_ACCENT + }; + + /** TextRelief definition */ + enum TextRelief + { + TEXT_RELIEF_NONE, + TEXT_RELIEF_EMBOSSED, + TEXT_RELIEF_ENGRAVED + }; + + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// + +#endif //INCLUDED_DRAWINGLAYER_PRIMITIVE2D_TEXTENUMSPRIMITIVE2D_HXX + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/drawinglayer/inc/drawinglayer/primitive2d/texthierarchyprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/texthierarchyprimitive2d.hxx index 1160704c0fa3..3f9c02b6e9bd 100644 --- a/drawinglayer/inc/drawinglayer/primitive2d/texthierarchyprimitive2d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive2d/texthierarchyprimitive2d.hxx @@ -45,17 +45,23 @@ namespace drawinglayer { namespace primitive2d { - // text format hierarchy helper class. It decomposes to it's - // content, so all direct renderers may ignore it. If You need - // to know more about line hierarchies You may react on it and - // also need to take care that the source of data uses it. + /** TextHierarchyLinePrimitive2D class + + Text format hierarchy helper class. It decomposes to it's + content, so all direct renderers may ignore it. If You need + to know more about line hierarchies You may react on it and + also need to take care that the source of data uses it. + + This primitive encapsulates text lines. + */ class TextHierarchyLinePrimitive2D : public GroupPrimitive2D { private: public: + /// constructor TextHierarchyLinePrimitive2D(const Primitive2DSequence& rChildren); - // provide unique ID + /// provide unique ID DeclPrimitrive2DIDBlock() }; } // end of namespace primitive2d @@ -67,14 +73,18 @@ namespace drawinglayer { namespace primitive2d { - // see TextHierarchyLinePrimitive2D comment + /** TextHierarchyBulletPrimitive2D class + + This primitive encapsulates text bullets. + */ class TextHierarchyBulletPrimitive2D : public GroupPrimitive2D { private: public: + /// constructor TextHierarchyBulletPrimitive2D(const Primitive2DSequence& rChildren); - // provide unique ID + /// provide unique ID DeclPrimitrive2DIDBlock() }; } // end of namespace primitive2d @@ -86,14 +96,18 @@ namespace drawinglayer { namespace primitive2d { - // see TextHierarchyLinePrimitive2D comment + /** TextHierarchyParagraphPrimitive2D class + + This primitive encapsulates text paragraphs. + */ class TextHierarchyParagraphPrimitive2D : public GroupPrimitive2D { private: public: + /// constructor TextHierarchyParagraphPrimitive2D(const Primitive2DSequence& rChildren); - // provide unique ID + /// provide unique ID DeclPrimitrive2DIDBlock() }; } // end of namespace primitive2d @@ -105,14 +119,18 @@ namespace drawinglayer { namespace primitive2d { - // see TextHierarchyLinePrimitive2D comment + /** TextHierarchyBlockPrimitive2D class + + This primitive encapsulates text blocks. + */ class TextHierarchyBlockPrimitive2D : public GroupPrimitive2D { private: public: + /// constructor TextHierarchyBlockPrimitive2D(const Primitive2DSequence& rChildren); - // provide unique ID + /// provide unique ID DeclPrimitrive2DIDBlock() }; } // end of namespace primitive2d @@ -124,19 +142,28 @@ namespace drawinglayer { namespace primitive2d { - // type enum + /** FieldType definition */ enum FieldType { - FIELD_TYPE_COMMON, // unspecified. If more info is needed for a FieldType, - // create a new type and it's handling - FIELD_TYPE_PAGE, // uses "FIELD_SEQ_BEGIN;PageField" -> special handling - FIELD_TYPE_URL // uses URL as string -> special handling + /** unspecified. If more info is needed for a FieldType, + create a new type and it's handling + */ + FIELD_TYPE_COMMON, + + /** uses "FIELD_SEQ_BEGIN;PageField" -> special handling */ + FIELD_TYPE_PAGE, + + /** uses URL as string -> special handling */ + FIELD_TYPE_URL }; - // see TextHierarchyLinePrimitive2D comment. - // Also: This type uses a type enum to transport the encapsulated field - // type. Also added is a String which is type-dependent. E.g. for URL - // fields, it contains the URL. + /** TextHierarchyFieldPrimitive2D class + + This primitive encapsulates text fields. + Also: This type uses a type enum to transport the encapsulated field + type. Also added is a String which is type-dependent. E.g. for URL + fields, it contains the URL. + */ class TextHierarchyFieldPrimitive2D : public GroupPrimitive2D { private: @@ -144,19 +171,20 @@ namespace drawinglayer rtl::OUString maString; public: + /// constructor TextHierarchyFieldPrimitive2D( const Primitive2DSequence& rChildren, const FieldType& rFieldType, const rtl::OUString& rString); - // get data + /// data read access FieldType getType() const { return meType; } const rtl::OUString& getString() const { return maString; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive2D& rPrimitive) const; - // provide unique ID + /// provide unique ID DeclPrimitrive2DIDBlock() }; } // end of namespace primitive2d @@ -168,20 +196,24 @@ namespace drawinglayer { namespace primitive2d { - // #i97628# - // Primitive to encapsulate text from an active text edit; some - // renderers need to suppress this output due to painting the - // edited text in e.g. an OutlinerEditView. It's derived from - // GroupPrimitive2D, so the implicit decomposition will use the - // content. To suppress, this primitive needs to be parsed by - // the renderer without taking any action + /** TextHierarchyEditPrimitive2D class + + #i97628# + Primitive to encapsulate text from an active text edit; some + renderers need to suppress this output due to painting the + edited text in e.g. an OutlinerEditView. It's derived from + GroupPrimitive2D, so the implicit decomposition will use the + content. To suppress, this primitive needs to be parsed by + the renderer without taking any action. + */ class TextHierarchyEditPrimitive2D : public GroupPrimitive2D { private: public: + /// constructor TextHierarchyEditPrimitive2D(const Primitive2DSequence& rChildren); - // provide unique ID + /// provide unique ID DeclPrimitrive2DIDBlock() }; } // end of namespace primitive2d diff --git a/drawinglayer/inc/drawinglayer/primitive2d/textlayoutdevice.hxx b/drawinglayer/inc/drawinglayer/primitive2d/textlayoutdevice.hxx index df09718a7582..f3de43c22fd7 100644 --- a/drawinglayer/inc/drawinglayer/primitive2d/textlayoutdevice.hxx +++ b/drawinglayer/inc/drawinglayer/primitive2d/textlayoutdevice.hxx @@ -49,9 +49,10 @@ class VirtualDevice; class Font; class String; class OutputDevice; +class GDIMetaFile; -namespace drawinglayer { namespace primitive2d { - class FontAttributes; +namespace drawinglayer { namespace attribute { + class FontAttribute; }} namespace basegfx { @@ -66,18 +67,27 @@ namespace drawinglayer { namespace primitive2d { + /** TextLayouterDevice class + + This helper class exists to isolate all accesses to VCL + text formatting/handling functionality for primitive implementations. + When in the future FontHandling may move to an own library independent + from VCL, primitives will be prepared. + */ class TextLayouterDevice { - // internally used VirtualDevice + /// internally used VirtualDevice VirtualDevice& mrDevice; public: + /// constructor/destructor TextLayouterDevice(); ~TextLayouterDevice(); + /// tooling methods void setFont(const Font& rFont); - void setFontAttributes( - const FontAttributes& rFontAttributes, + void setFontAttribute( + const attribute::FontAttribute& rFontAttribute, double fFontScaleX, double fFontScaleY, const ::com::sun::star::lang::Locale & rLocale); @@ -105,6 +115,15 @@ namespace drawinglayer const String& rText, xub_StrLen nIndex, xub_StrLen nLength) const; + + double getFontAscent() const; + double getFontDescent() const; + + void addTextRectActions( + const Rectangle& rRectangle, + const String& rText, + sal_uInt16 nStyle, + GDIMetaFile& rGDIMetaFile); }; } // end of namespace primitive2d } // end of namespace drawinglayer @@ -116,23 +135,25 @@ namespace drawinglayer { namespace primitive2d { - // Create a VCL-Font based on the definitions in FontAttributes - // and the given FontScaling. The FontScaling defines the FontHeight - // (fFontScaleY) and the FontWidth (fFontScaleX). The combination of - // both defines FontStretching, where no stretching happens at - // fFontScaleY == fFontScaleX - Font getVclFontFromFontAttributes( - const FontAttributes& rFontAttributes, + /** Create a VCL-Font based on the definitions in FontAttribute + and the given FontScaling. The FontScaling defines the FontHeight + (fFontScaleY) and the FontWidth (fFontScaleX). The combination of + both defines FontStretching, where no stretching happens at + fFontScaleY == fFontScaleX + */ + Font getVclFontFromFontAttribute( + const attribute::FontAttribute& rFontAttribute, double fFontScaleX, double fFontScaleY, double fFontRotation, const ::com::sun::star::lang::Locale & rLocale); - // Generate FontAttributes DataSet derived from the given VCL-Font. - // The FontScaling with fFontScaleY, fFontScaleX relationship (see - // above) will be set in return parameter o_rSize to allow further - // processing - FontAttributes getFontAttributesFromVclFont( + /** Generate FontAttribute DataSet derived from the given VCL-Font. + The FontScaling with fFontScaleY, fFontScaleX relationship (see + above) will be set in return parameter o_rSize to allow further + processing + */ + attribute::FontAttribute getFontAttributeFromVclFont( basegfx::B2DVector& o_rSize, const Font& rFont, bool bRTL, diff --git a/drawinglayer/inc/drawinglayer/primitive2d/textlineprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/textlineprimitive2d.hxx new file mode 100644 index 000000000000..a103d607e85f --- /dev/null +++ b/drawinglayer/inc/drawinglayer/primitive2d/textlineprimitive2d.hxx @@ -0,0 +1,99 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: textdecoratedprimitive2d.hxx,v $ + * + * $Revision: 1.6 $ + * + * last change: $Author: aw $ $Date: 2008-05-27 14:11:17 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef INCLUDED_DRAWINGLAYER_PRIMITIVE2D_TEXTLINEPRIMITIVE2D_HXX +#define INCLUDED_DRAWINGLAYER_PRIMITIVE2D_TEXTLINEPRIMITIVE2D_HXX + +#include <drawinglayer/primitive2d/baseprimitive2d.hxx> +#include <drawinglayer/primitive2d/textenumsprimitive2d.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/color/bcolor.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + class TextLinePrimitive2D : public BufferedDecompositionPrimitive2D + { + private: + /// geometric definitions + basegfx::B2DHomMatrix maObjectTransformation; + double mfWidth; + double mfOffset; + double mfHeight; + + /// decoration definitions + TextLine meTextLine; + basegfx::BColor maLineColor; + + protected: + /// local decomposition. + virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + + public: + /// constructor + TextLinePrimitive2D( + const basegfx::B2DHomMatrix& rObjectTransformation, + double fWidth, + double fOffset, + double fHeight, + TextLine eTextLine, + const basegfx::BColor& rLineColor); + + /// data read access + const basegfx::B2DHomMatrix& getObjectTransformation() const { return maObjectTransformation; } + double getWidth() const { return mfWidth; } + double getOffset() const { return mfOffset; } + double getHeight() const { return mfHeight; } + TextLine getTextLine() const { return meTextLine; } + const basegfx::BColor& getLineColor() const { return maLineColor; } + + /// compare operator + virtual bool operator==( const BasePrimitive2D& rPrimitive ) const; + + /// provide unique ID + DeclPrimitrive2DIDBlock() + }; + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// + +#endif //INCLUDED_DRAWINGLAYER_PRIMITIVE2D_TEXTLINEPRIMITIVE2D_HXX + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/drawinglayer/inc/drawinglayer/primitive2d/textprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/textprimitive2d.hxx index d7f9bdb1e89a..bbcd8e335e23 100644 --- a/drawinglayer/inc/drawinglayer/primitive2d/textprimitive2d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive2d/textprimitive2d.hxx @@ -43,6 +43,7 @@ #include <basegfx/color/bcolor.hxx> #include <vector> #include <com/sun/star/lang/Locale.hpp> +#include <drawinglayer/attribute/fontattribute.hxx> ////////////////////////////////////////////////////////////////////////////// // predefines @@ -60,123 +61,91 @@ namespace drawinglayer { namespace primitive2d { - class FontAttributes + /** TextSimplePortionPrimitive2D class + + This is the basic primitive for representing a text portion. It contains + all needed information. If it is not handled by a renderer, it's decomposition + will provide the text PolyPolygon outlines as filled polygons, correctly + transformed. + + To get better text quality, it is suggested to handle tis primitive directly + in a renderer. In that case, e.g. hintings on the system can be supported. + */ + class TextSimplePortionPrimitive2D : public BufferedDecompositionPrimitive2D { private: - // core data - String maFamilyName; // Font Family Name - String maStyleName; // Font Style Name - sal_uInt16 mnWeight; // Font weight - - // bitfield - unsigned mbSymbol : 1; // Symbol Font Flag - unsigned mbVertical : 1; // Vertical Text Flag - unsigned mbItalic : 1; // Italic Flag - unsigned mbOutline : 1; // Outline Flag - unsigned mbRTL : 1; // RTL Flag - unsigned mbBiDiStrong : 1; // BiDi Flag - // TODO: pair kerning and CJK kerning + /// text range transformation from unit range ([0.0 .. 1.0]) to text range + basegfx::B2DHomMatrix maTextTransform; - public: - FontAttributes( - const String& rFamilyName, - const String& rStyleName, - sal_uInt16 nWeight, - bool bSymbol = false, - bool bVertical = false, - bool bItalic = false, - bool bOutline = false, - bool bRTL = false, - bool bBiDiStrong = false) - : maFamilyName(rFamilyName), - maStyleName(rStyleName), - mnWeight(nWeight), - mbSymbol(bSymbol), - mbVertical(bVertical), - mbItalic(bItalic), - mbOutline(bOutline), - mbRTL(bRTL), - mbBiDiStrong(bBiDiStrong) - { - } - - // compare operator - bool operator==(const FontAttributes& rCompare) const; - - // data access - const String& getFamilyName() const { return maFamilyName; } - const String& getStyleName() const { return maStyleName; } - sal_uInt16 getWeight() const { return mnWeight; } - bool getSymbol() const { return mbSymbol; } - bool getVertical() const { return mbVertical; } - bool getItalic() const { return mbItalic; } - bool getOutline() const { return mbOutline; } - bool getRTL() const { return mbRTL; } - bool getBiDiStrong() const { return mbBiDiStrong; } - }; - } // end of namespace primitive2d -} // end of namespace drawinglayer + /// The text, used from maTextPosition up to maTextPosition + maTextLength + String maText; -////////////////////////////////////////////////////////////////////////////// + /// The index from where on maText is used + xub_StrLen maTextPosition; -namespace drawinglayer -{ - namespace primitive2d - { - class TextSimplePortionPrimitive2D : public BasePrimitive2D - { - private: - basegfx::B2DHomMatrix maTextTransform; // text range transformation from unit range ([0.0 .. 1.0]) to text range - String maText; // the text, used from maTextPosition up to maTextPosition + maTextLength - xub_StrLen maTextPosition; // the index from where on maText is used - xub_StrLen maTextLength; // the length for maText usage, starting from maTextPosition - ::std::vector< double > maDXArray; // the DX array scale-independent in unit coordinates - FontAttributes maFontAttributes; // the font to use - ::com::sun::star::lang::Locale maLocale; // the Locale for the text - basegfx::BColor maFontColor; // font color - - // #i96669# add simple range buffering for this primitive + /// The length for maText usage, starting from maTextPosition + xub_StrLen maTextLength; + + /// The DX array scale-independent in unit coordinates + ::std::vector< double > maDXArray; + + /// The font to use + attribute::FontAttribute maFontAttribute; + + /// The Locale for the text + ::com::sun::star::lang::Locale maLocale; + + /// font color + basegfx::BColor maFontColor; + + /// #i96669# add simple range buffering for this primitive basegfx::B2DRange maB2DRange; protected: - // local decomposition. - virtual Primitive2DSequence createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + /// local decomposition. + virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; public: + /// constructor TextSimplePortionPrimitive2D( const basegfx::B2DHomMatrix& rNewTransform, const String& rText, xub_StrLen aTextPosition, xub_StrLen aTextLength, const ::std::vector< double >& rDXArray, - const FontAttributes& rFontAttributes, + const attribute::FontAttribute& rFontAttribute, const ::com::sun::star::lang::Locale& rLocale, const basegfx::BColor& rFontColor); - // helpers - // get text outlines as polygons and their according ObjectTransformation. Handles all - // the necessary VCL outline extractins, scaling adaptions and other stuff. + /// helpers + /** get text outlines as polygons and their according ObjectTransformation. Handles all + the necessary VCL outline extractins, scaling adaptions and other stuff. + */ void getTextOutlinesAndTransformation(basegfx::B2DPolyPolygonVector& rTarget, basegfx::B2DHomMatrix& rTransformation) const; - // get data + /// data read access const basegfx::B2DHomMatrix& getTextTransform() const { return maTextTransform; } const String& getText() const { return maText; } xub_StrLen getTextPosition() const { return maTextPosition; } xub_StrLen getTextLength() const { return maTextLength; } const ::std::vector< double >& getDXArray() const { return maDXArray; } - const FontAttributes& getFontAttributes() const { return maFontAttributes; } + const attribute::FontAttribute& getFontAttribute() const { return maFontAttribute; } const ::com::sun::star::lang::Locale& getLocale() const { return maLocale; } const basegfx::BColor& getFontColor() const { return maFontColor; } - // compare operator + /// compare operator virtual bool operator==( const BasePrimitive2D& rPrimitive ) const; - // get range + /// get range virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const; - // provide unique ID + /// provide unique ID DeclPrimitrive2DIDBlock() }; + + /// small helper to have a compare operator for Locale + bool LocalesAreEqual(const ::com::sun::star::lang::Locale& rA, const ::com::sun::star::lang::Locale& rB); + } // end of namespace primitive2d } // end of namespace drawinglayer diff --git a/drawinglayer/inc/drawinglayer/primitive2d/textstrikeoutprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/textstrikeoutprimitive2d.hxx new file mode 100644 index 000000000000..34d7d31fb93a --- /dev/null +++ b/drawinglayer/inc/drawinglayer/primitive2d/textstrikeoutprimitive2d.hxx @@ -0,0 +1,167 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: textdecoratedprimitive2d.hxx,v $ + * + * $Revision: 1.6 $ + * + * last change: $Author: aw $ $Date: 2008-05-27 14:11:17 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef INCLUDED_DRAWINGLAYER_PRIMITIVE2D_TEXTSTRIKEOUTPRIMITIVE2D_HXX +#define INCLUDED_DRAWINGLAYER_PRIMITIVE2D_TEXTSTRIKEOUTPRIMITIVE2D_HXX + +#include <drawinglayer/primitive2d/baseprimitive2d.hxx> +#include <drawinglayer/primitive2d/textenumsprimitive2d.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/color/bcolor.hxx> +#include <drawinglayer/attribute/fontattribute.hxx> +#include <com/sun/star/lang/Locale.hpp> + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + class BaseTextStrikeoutPrimitive2D : public BufferedDecompositionPrimitive2D + { + private: + /// geometric definitions + basegfx::B2DHomMatrix maObjectTransformation; + double mfWidth; + + /// decoration definitions + basegfx::BColor maFontColor; + + public: + /// constructor + BaseTextStrikeoutPrimitive2D( + const basegfx::B2DHomMatrix& rObjectTransformation, + double fWidth, + const basegfx::BColor& rFontColor); + + /// data read access + const basegfx::B2DHomMatrix& getObjectTransformation() const { return maObjectTransformation; } + double getWidth() const { return mfWidth; } + const basegfx::BColor& getFontColor() const { return maFontColor; } + + /// compare operator + virtual bool operator==( const BasePrimitive2D& rPrimitive ) const; + }; + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + class TextCharacterStrikeoutPrimitive2D : public BaseTextStrikeoutPrimitive2D + { + private: + sal_Unicode maStrikeoutChar; + attribute::FontAttribute maFontAttribute; + ::com::sun::star::lang::Locale maLocale; + + protected: + /// local decomposition. + virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + + public: + /// constructor + TextCharacterStrikeoutPrimitive2D( + const basegfx::B2DHomMatrix& rObjectTransformation, + double fWidth, + const basegfx::BColor& rFontColor, + sal_Unicode aStrikeoutChar, + const attribute::FontAttribute& rFontAttribute, + const ::com::sun::star::lang::Locale& rLocale); + + /// data read access + sal_Unicode getStrikeoutChar() const { return maStrikeoutChar; } + const attribute::FontAttribute& getFontAttribute() const { return maFontAttribute; } + const ::com::sun::star::lang::Locale& getLocale() const { return maLocale; } + + /// compare operator + virtual bool operator==( const BasePrimitive2D& rPrimitive ) const; + + /// provide unique ID + DeclPrimitrive2DIDBlock() + }; + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + class TextGeometryStrikeoutPrimitive2D : public BaseTextStrikeoutPrimitive2D + { + private: + double mfHeight; + double mfOffset; + TextStrikeout meTextStrikeout; + + protected: + /// local decomposition. + virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + + public: + /// constructor + TextGeometryStrikeoutPrimitive2D( + const basegfx::B2DHomMatrix& rObjectTransformation, + double fWidth, + const basegfx::BColor& rFontColor, + double fHeight, + double fOffset, + TextStrikeout eTextStrikeout); + + /// data read access + double getHeight() const { return mfHeight; } + double getOffset() const { return mfOffset; } + TextStrikeout getTextStrikeout() const { return meTextStrikeout; } + + /// compare operator + virtual bool operator==( const BasePrimitive2D& rPrimitive ) const; + + /// provide unique ID + DeclPrimitrive2DIDBlock() + }; + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// + +#endif //INCLUDED_DRAWINGLAYER_PRIMITIVE2D_TEXTSTRIKEOUTPRIMITIVE2D_HXX + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/drawinglayer/inc/drawinglayer/primitive2d/transformprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/transformprimitive2d.hxx index 1646667342af..1723cc708ea8 100644 --- a/drawinglayer/inc/drawinglayer/primitive2d/transformprimitive2d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive2d/transformprimitive2d.hxx @@ -45,26 +45,47 @@ namespace drawinglayer { namespace primitive2d { + /** TransformPrimitive2D class + + This is one of the basic grouping primitives and it provides + embedding a sequence of primitives (a geometry) into a + transformation. All renderers have to handle this, usually by + building a current transformation stack (linear combination) + and applying this to all to-be-rendered geometry. If not handling + this, the output will be mostly wrong since this primitive is + widely used. + + It does transform by embedding an existing geometry into a + transformation as Child-content. This allows re-usage of the + refcounted Uno-Api primitives and their existung, buffered + decompositions. + + It could e.g. be used to show a single object geometry in 1000 + different, transformed states without the need to create those + thousand primitive contents. + */ class TransformPrimitive2D : public GroupPrimitive2D { private: + // the transformation to apply to the child geometry basegfx::B2DHomMatrix maTransformation; public: + /// constructor TransformPrimitive2D( const basegfx::B2DHomMatrix& rTransformation, const Primitive2DSequence& rChildren); - // get data + /// data read access const basegfx::B2DHomMatrix& getTransformation() const { return maTransformation; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive2D& rPrimitive) const; - // get range + /// get range virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const; - // provide unique ID + /// provide unique ID DeclPrimitrive2DIDBlock() }; } // end of namespace primitive2d diff --git a/drawinglayer/inc/drawinglayer/primitive2d/unifiedalphaprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/unifiedalphaprimitive2d.hxx index 44f3f738b67e..6e8970e7bee5 100644 --- a/drawinglayer/inc/drawinglayer/primitive2d/unifiedalphaprimitive2d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive2d/unifiedalphaprimitive2d.hxx @@ -44,27 +44,37 @@ namespace drawinglayer { namespace primitive2d { + /** UnifiedAlphaPrimitive2D class + + This primitive encapsualtes a child hierarchy and defines + that it shall be visualized with the given transparency. That + transparency is unique for all contained geometry, so that + e.g. overlapping polygons in the child geometry will not show + regions of combined transparency, but be all rendered with the + defined, single transparency. + */ class UnifiedAlphaPrimitive2D : public GroupPrimitive2D { private: - double mfAlpha; // unified transparence - - protected: - // create decomposition - virtual Primitive2DSequence createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + /// the unified alpha transparence + double mfAlpha; public: + /// constructor UnifiedAlphaPrimitive2D( const Primitive2DSequence& rChildren, double fAlpha); - // get data + /// data read access double getAlpha() const { return mfAlpha; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive2D& rPrimitive) const; - // provide unique ID + /// create decomposition + virtual Primitive2DSequence get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + + /// provide unique ID DeclPrimitrive2DIDBlock() }; } // end of namespace primitive2d diff --git a/drawinglayer/inc/drawinglayer/primitive2d/wallpaperprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/wallpaperprimitive2d.hxx new file mode 100644 index 000000000000..ffe47cfe1b72 --- /dev/null +++ b/drawinglayer/inc/drawinglayer/primitive2d/wallpaperprimitive2d.hxx @@ -0,0 +1,102 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: bitmapprimitive2d.hxx,v $ + * + * $Revision: 1.4 $ + * + * last change: $Author: aw $ $Date: 2008-05-27 14:11:16 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef INCLUDED_DRAWINGLAYER_PRIMITIVE2D_WALLPAPERPRIMITIVE2D_HXX +#define INCLUDED_DRAWINGLAYER_PRIMITIVE2D_WALLPAPERPRIMITIVE2D_HXX + +#include <drawinglayer/primitive2d/primitivetools2d.hxx> +#include <vcl/bitmapex.hxx> +#include <vcl/wall.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + /** WallpaperBitmapPrimitive2D class + + This is a specialized primtive for the Wallpaper definitions included in + VCL and Metafiles. The extraordinary about the bitmap definition part of + the Wallpaper is that it uses PIXEL size of the given Bitmap and not + the logic and/or discrete size derived by PrefMapMode/PrefSize methods. + To emulate this, a ViewTransformation dependent primitive is needed which + takes over the correct scaling(s). + + Since a specialized primitive is needed anyways, i opted to also add the + layouting which is dependent from WallpaperStyle; thus it does not need + to be handled anywhere else in the future. + */ + class WallpaperBitmapPrimitive2D : public ViewTransformationDependentPrimitive2D + { + private: + basegfx::B2DRange maObjectRange; + BitmapEx maBitmapEx; + WallpaperStyle meWallpaperStyle; + + protected: + /// create local decomposition + virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + + public: + /// constructor + WallpaperBitmapPrimitive2D( + const basegfx::B2DRange& rObjectRange, + const BitmapEx& rBitmapEx, + WallpaperStyle eWallpaperStyle); + + /// data read access + const basegfx::B2DRange& getLocalObjectRange() const { return maObjectRange; } + const BitmapEx& getBitmapEx() const { return maBitmapEx ; } + WallpaperStyle getWallpaperStyle() const { return meWallpaperStyle; } + + /// compare operator + virtual bool operator==(const BasePrimitive2D& rPrimitive) const; + + /// get B2Drange + virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const; + + /// provide unique ID + DeclPrimitrive2DIDBlock() + }; + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// + +#endif // INCLUDED_DRAWINGLAYER_PRIMITIVE2D_WALLPAPERPRIMITIVE2D_HXX + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/drawinglayer/inc/drawinglayer/primitive2d/wrongspellprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/wrongspellprimitive2d.hxx index 8bd739298059..3ceae01ed3b2 100644 --- a/drawinglayer/inc/drawinglayer/primitive2d/wrongspellprimitive2d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive2d/wrongspellprimitive2d.hxx @@ -47,35 +47,53 @@ namespace drawinglayer { namespace primitive2d { - class WrongSpellPrimitive2D : public BasePrimitive2D + /** WrongSpellPrimitive2D class + + This is a helper primitive to hold evtl. WrongSpell visualisations + in the sequence of primitives. The primitive holds this information + separated form the TextPortions to where it belongs to tot expand the + TextSimplePortionPrimitive2D more as needed. + + A renderer who does not want to visualize this (if contained at all) + can detect and ignore this primitive. If it's decomposition is used, + it will be visualized as red wavelines. + + The geometric definition defines a line on the X-Axis (no Y-coordinates) + which will when transformed by Transformation, create the coordinate data. + */ + class WrongSpellPrimitive2D : public BufferedDecompositionPrimitive2D { private: + /// geometry definition basegfx::B2DHomMatrix maTransformation; double mfStart; double mfStop; + + /// color (usually red) basegfx::BColor maColor; protected: - // create local decomposition - virtual Primitive2DSequence createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + /// create local decomposition + virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; public: + /// constructor WrongSpellPrimitive2D( const basegfx::B2DHomMatrix& rTransformation, double fStart, double fStop, const basegfx::BColor& rColor); - // get data + /// data read access const basegfx::B2DHomMatrix& getTransformation() const { return maTransformation; } double getStart() const { return mfStart; } double getStop() const { return mfStop; } const basegfx::BColor& getColor() const { return maColor; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive2D& rPrimitive) const; - // provide unique ID + /// provide unique ID DeclPrimitrive2DIDBlock() }; } // end of namespace primitive2d diff --git a/drawinglayer/inc/drawinglayer/primitive3d/baseprimitive3d.hxx b/drawinglayer/inc/drawinglayer/primitive3d/baseprimitive3d.hxx index faeac28b0c0c..9bf56edb2c53 100644 --- a/drawinglayer/inc/drawinglayer/primitive3d/baseprimitive3d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive3d/baseprimitive3d.hxx @@ -43,16 +43,17 @@ #include <basegfx/range/b3drange.hxx> ////////////////////////////////////////////////////////////////////////////// -// defines for DeclPrimitrive3DIDBlock and ImplPrimitrive3DIDBlock -// Added to be able to simply change identification stuff later, e.g. add -// a identification string and/or ID to the interface and to the implementation -// ATM used to delclare implement getPrimitiveID() +/** defines for DeclPrimitrive3DIDBlock and ImplPrimitrive3DIDBlock + Added to be able to simply change identification stuff later, e.g. add + a identification string and/or ID to the interface and to the implementation + ATM used to delclare implement getPrimitive3DID() + */ #define DeclPrimitrive3DIDBlock() \ - virtual sal_uInt32 getPrimitiveID() const; + virtual sal_uInt32 getPrimitive3DID() const; #define ImplPrimitrive3DIDBlock(TheClass, TheID) \ - sal_uInt32 TheClass::getPrimitiveID() const { return TheID; } + sal_uInt32 TheClass::getPrimitive3DID() const { return TheID; } ////////////////////////////////////////////////////////////////////////////// // predefines @@ -61,6 +62,13 @@ namespace drawinglayer { namespace geometry { class ViewInformation3D; }} +namespace drawinglayer { namespace primitive3d { + /// typedefs for basePrimitive3DImplBase, Primitive3DSequence and Primitive3DReference + typedef cppu::WeakComponentImplHelper1< ::com::sun::star::graphic::XPrimitive3D > BasePrimitive3DImplBase; + typedef ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XPrimitive3D > Primitive3DReference; + typedef ::com::sun::star::uno::Sequence< Primitive3DReference > Primitive3DSequence; +}} + ////////////////////////////////////////////////////////////////////////////// // basePrimitive3D class @@ -68,99 +76,145 @@ namespace drawinglayer { namespace primitive3d { - // typedefs for basePrimitive3DImplBase, Primitive3DSequence and Primitive3DReference - typedef cppu::WeakComponentImplHelper1< ::com::sun::star::graphic::XPrimitive3D > BasePrimitive3DImplBase; - typedef ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XPrimitive3D > Primitive3DReference; - typedef ::com::sun::star::uno::Sequence< Primitive3DReference > Primitive3DSequence; + /** BasePrimitive3D class + + Baseclass for all C++ implementations of com::sun::star::graphic::XPrimitive2D + + The description/functionality is identical with the 2D case in baseprimitive2d.hxx, + please see there for detailed information. + Current Basic 3D Primitives are: + + - PolygonHairlinePrimitive3D (for 3D hairlines) + - PolyPolygonMaterialPrimitive3D (for 3D filled plane polygons) + + That's all for 3D! + */ class BasePrimitive3D : private boost::noncopyable, protected comphelper::OBaseMutex, public BasePrimitive3DImplBase { private: - // a sequence used for buffering the last createLocalDecomposition() result. Use - // the protected access methods to change. Only implementations of getDecomposition() - // should make use. - Primitive3DSequence maLocalDecomposition; - protected: - // access methods to maLocalDecomposition. The usage of this methods may allow - // later thread-safe stuff to be added if needed. Only to be used by getDecomposition() - // implementations for buffering the last decomposition. - const Primitive3DSequence& getLocalDecomposition() const { return maLocalDecomposition; } - void setLocalDecomposition(const Primitive3DSequence& rNew) { maLocalDecomposition = rNew; } - - // method which is to be used to implement the local decomposition of a 2D primitive. The default - // implementation will just return an empty decomposition - virtual Primitive3DSequence createLocalDecomposition(const geometry::ViewInformation3D& rViewInformation) const; - public: - // constructor + // constructor/destructor BasePrimitive3D(); + virtual ~BasePrimitive3D(); - // the ==operator is mainly needed to allow testing newly-created high level primitives against their last - // incarnation which buffers/holds the decompositionsThe default implementation - // uses getPrimitiveID()-calls to test if it's the same ID at last. Overloaded implementation are then - // based on this implementation + /** the ==operator is mainly needed to allow testing newly-created high level primitives against their last + incarnation which buffers/holds the decompositionsThe default implementation + uses getPrimitive3DID()-calls to test if it's the same ID at last. Overloaded implementation are then + based on this implementation. + */ virtual bool operator==( const BasePrimitive3D& rPrimitive ) const; bool operator!=( const BasePrimitive3D& rPrimitive ) const { return !operator==(rPrimitive); } - // This method is for places where using the C++ implementation directly is possible. The subprocessing - // and range merging is more efficient when working directly on basegfx::B3DRange. The default implementation - // will use getDecomposition results to create the range + /** This method is for places where using the C++ implementation directly is possible. The subprocessing + and range merging is more efficient when working directly on basegfx::B3DRange. The default implementation + will use getDecomposition results to create the range + */ virtual basegfx::B3DRange getB3DRange(const geometry::ViewInformation3D& rViewInformation) const; - // provide unique ID for fast identifying of known primitive implementations in renderers. These use - // the the defines from primitivetypes3d.hxx to define unique IDs. - virtual sal_uInt32 getPrimitiveID() const = 0; + /** provide unique ID for fast identifying of known primitive implementations in renderers. These use + the the defines from primitivetypes3d.hxx to define unique IDs. + */ + virtual sal_uInt32 getPrimitive3DID() const = 0; - // The getDecomposition default implementation will on demand use createLocalDecomposition() if maLocalDecomposition is empty. - // It will set maLocalDecomposition to this obtained decomposition to buffer it. - // If the decomposition is also ViewInformation-dependent, this method needs to be overloaded and the - // ViewInformation for the last decomposition needs to be remembered, too, and be used in the next call to decide if - // the buffered decomposition may be reused or not. + /// The default implementation returns an empty sequence virtual Primitive3DSequence get3DDecomposition(const geometry::ViewInformation3D& rViewInformation) const; // // Methods from XPrimitive3D // - // The getDecomposition implementation for UNO API will use getDecomposition from this implementation. It - // will get the ViewInformation from the ViewParameters for that purpose + /** The getDecomposition implementation for UNO API will use getDecomposition from this implementation. It + will get the ViewInformation from the ViewParameters for that purpose + */ virtual Primitive3DSequence SAL_CALL getDecomposition( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rViewParameters ) throw ( ::com::sun::star::uno::RuntimeException ); - // the getRange default implemenation will use getDecomposition to create the range information from merging - // getRange results from the single local decomposition primitives. + /** the getRange default implemenation will use getDecomposition to create the range information from merging + getRange results from the single local decomposition primitives. + */ virtual ::com::sun::star::geometry::RealRectangle3D SAL_CALL getRange( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rViewParameters ) throw ( ::com::sun::star::uno::RuntimeException ); }; } // end of namespace primitive3d } // end of namespace drawinglayer ////////////////////////////////////////////////////////////////////////////// +// BufferedDecompositionPrimitive3D class + +namespace drawinglayer +{ + namespace primitive3d + { + /** BufferedDecompositionPrimitive3D class + + Baseclass for all C++ implementations of com::sun::star::graphic::XPrimitive2D + + The description/functionality is identical with the 2D case in baseprimitive2d.hxx, + please see there for detailed information + */ + class BufferedDecompositionPrimitive3D + : public BasePrimitive3D + { + private: + /// a sequence used for buffering the last create3DDecomposition() result + Primitive3DSequence maBuffered3DDecomposition; + + protected: + /** access methods to maBuffered3DDecomposition. The usage of this methods may allow + later thread-safe stuff to be added if needed. Only to be used by getDecomposition() + implementations for buffering the last decomposition. + */ + const Primitive3DSequence& getBuffered3DDecomposition() const { return maBuffered3DDecomposition; } + void setBuffered3DDecomposition(const Primitive3DSequence& rNew) { maBuffered3DDecomposition = rNew; } + + /** method which is to be used to implement the local decomposition of a 2D primitive. The default + implementation will just return an empty decomposition + */ + virtual Primitive3DSequence create3DDecomposition(const geometry::ViewInformation3D& rViewInformation) const; + + public: + // constructor + BufferedDecompositionPrimitive3D(); + + /** The getDecomposition default implementation will on demand use create3DDecomposition() if + maBuffered3DDecomposition is empty. It will set maBuffered3DDecomposition to this obtained decomposition + to buffer it. If the decomposition is also ViewInformation-dependent, this method needs to be + overloaded and the ViewInformation for the last decomposition needs to be remembered, too, and + be used in the next call to decide if the buffered decomposition may be reused or not. + */ + virtual Primitive3DSequence get3DDecomposition(const geometry::ViewInformation3D& rViewInformation) const; + }; + } // end of namespace primitive3d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// // tooling namespace drawinglayer { namespace primitive3d { - // get B3DRange from a given Primitive3DReference + /// get B3DRange from a given Primitive3DReference basegfx::B3DRange getB3DRangeFromPrimitive3DReference(const Primitive3DReference& rCandidate, const geometry::ViewInformation3D& aViewInformation); - // get range3D from a given Primitive3DSequence + /// get range3D from a given Primitive3DSequence basegfx::B3DRange getB3DRangeFromPrimitive3DSequence(const Primitive3DSequence& rCandidate, const geometry::ViewInformation3D& aViewInformation); - // compare two Primitive2DReferences for equality, including trying to get implementations (BasePrimitive2D) - // and using compare operator + /** compare two Primitive2DReferences for equality, including trying to get implementations (BasePrimitive2D) + and using compare operator + */ bool arePrimitive3DReferencesEqual(const Primitive3DReference& rA, const Primitive3DReference& rB); - // compare two Primitive3DReferences for equality, uses arePrimitive3DReferencesEqual internally + /// compare two Primitive3DReferences for equality, uses arePrimitive3DReferencesEqual internally bool arePrimitive3DSequencesEqual(const Primitive3DSequence& rA, const Primitive3DSequence& rB); - // concatenate sequence + /// concatenate sequence void appendPrimitive3DSequenceToPrimitive3DSequence(Primitive3DSequence& rDest, const Primitive3DSequence& rSource); - // concatenate single Primitive3D + /// concatenate single Primitive3D void appendPrimitive3DReferenceToPrimitive3DSequence(Primitive3DSequence& rDest, const Primitive3DReference& rSource); } // end of namespace primitive3d diff --git a/drawinglayer/inc/drawinglayer/primitive3d/groupprimitive3d.hxx b/drawinglayer/inc/drawinglayer/primitive3d/groupprimitive3d.hxx index 029b4c664fe2..69e406c75d67 100644 --- a/drawinglayer/inc/drawinglayer/primitive3d/groupprimitive3d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive3d/groupprimitive3d.hxx @@ -44,27 +44,45 @@ namespace drawinglayer { namespace primitive3d { + /** GroupPrimitive3D class + + Baseclass for all grouping 3D primitives + + The description/functionality is identical with the 2D case in groupprimitive2d.hxx, + please see there for detailed information. + + Current Basic 3D StatePrimitives are: + + - ModifiedColorPrimitive3D (for a stack of color modifications) + - ShadowPrimitive3D (for 3D objects with shadow; this is a special case + since the shadow of a 3D primitive is a 2D primitive set) + - TexturePrimitive3D (with the following variations) + - GradientTexturePrimitive3D (for 3D gradient fill) + - BitmapTexturePrimitive3D (for 3D Bitmap fill) + - AlphaTexturePrimitive3D (for 3D transparence) + - HatchTexturePrimitive3D (for 3D hatch fill) + - TransformPrimitive3D (for a transformation stack) + */ class GroupPrimitive3D : public BasePrimitive3D { private: - // the children. Declared private since this shall never be changed at all after construction + /// the children. Declared private since this shall never be changed at all after construction Primitive3DSequence maChildren; - protected: - // local decomposition. Implementation will just return children - virtual Primitive3DSequence createLocalDecomposition(const geometry::ViewInformation3D& rViewInformation) const; - public: - // constructor + /// constructor GroupPrimitive3D(const Primitive3DSequence& rChildren); - // data access + /// data read access Primitive3DSequence getChildren() const { return maChildren; } - // compare operator + /// compare operator virtual bool operator==( const BasePrimitive3D& rPrimitive ) const; - // provide unique ID + /// local decomposition. Implementation will just return children + virtual Primitive3DSequence get3DDecomposition(const geometry::ViewInformation3D& rViewInformation) const; + + /// provide unique ID DeclPrimitrive3DIDBlock() }; } // end of namespace primitive3d diff --git a/drawinglayer/inc/drawinglayer/primitive3d/hatchtextureprimitive3d.hxx b/drawinglayer/inc/drawinglayer/primitive3d/hatchtextureprimitive3d.hxx index c1feccaaa10c..2675a1284779 100644 --- a/drawinglayer/inc/drawinglayer/primitive3d/hatchtextureprimitive3d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive3d/hatchtextureprimitive3d.hxx @@ -44,16 +44,32 @@ namespace drawinglayer { namespace primitive3d { + /** HatchTexturePrimitive3D class + + HatchTexturePrimitive3D is derived from GroupPrimitive3D, but implements + a decomposition which is complicated enough for buffering. Since the group + primitive has no default buffering, it is necessary here to add a local + buffering mechanism for the decomposition + */ class HatchTexturePrimitive3D : public TexturePrimitive3D { private: + /// the hatch definition attribute::FillHatchAttribute maHatch; + /// the buffered decomposed hatch + Primitive3DSequence maBuffered3DDecomposition; + protected: - // local decomposition. - virtual Primitive3DSequence createLocalDecomposition(const geometry::ViewInformation3D& rViewInformation) const; + /// helper: local decomposition + Primitive3DSequence impCreate3DDecomposition() const; + + /// local access methods to maBufferedDecomposition + const Primitive3DSequence& getBuffered3DDecomposition() const { return maBuffered3DDecomposition; } + void setBuffered3DDecomposition(const Primitive3DSequence& rNew) { maBuffered3DDecomposition = rNew; } public: + /// constructor HatchTexturePrimitive3D( const attribute::FillHatchAttribute& rHatch, const Primitive3DSequence& rChildren, @@ -61,13 +77,16 @@ namespace drawinglayer bool bModulate, bool bFilter); - // get data + /// data read access const attribute::FillHatchAttribute& getHatch() const { return maHatch; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive3D& rPrimitive) const; - // provide unique ID + /// local decomposition. + virtual Primitive3DSequence get3DDecomposition(const geometry::ViewInformation3D& rViewInformation) const; + + /// provide unique ID DeclPrimitrive3DIDBlock() }; } // end of namespace primitive3d diff --git a/drawinglayer/inc/drawinglayer/primitive3d/hittestprimitive3d.hxx b/drawinglayer/inc/drawinglayer/primitive3d/hittestprimitive3d.hxx index 28029f223b1b..4779241033b0 100644 --- a/drawinglayer/inc/drawinglayer/primitive3d/hittestprimitive3d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive3d/hittestprimitive3d.hxx @@ -44,32 +44,37 @@ namespace drawinglayer { namespace primitive3d { - // This primitive is used to represent geometry for non-visible objects, - // e.g. a 3D cube without fill attributes. To still be able to use - // primitives for HitTest functionality, the 3d decompositions produce - // an as much as possible simplified fill geometry encapsulated in this - // primtive when there is no fill geometry. Currently, the 3d hit test - // uses only areas, so maybe in a further enchanced version this will change - // to 'if neither filled nor lines' creation criteria. The whole primitive - // decomposes to nothing, so no one not knowing it will be influenced. Only - // helper processors for hit test (and maybe BoundRect extractors) will - // use it and it's children subcontent. + /** HitTestPrimitive3D class + + This primitive is used to represent geometry for non-visible objects, + e.g. a 3D cube without fill attributes. To still be able to use + primitives for HitTest functionality, the 3d decompositions produce + an as much as possible simplified fill geometry encapsulated in this + primtive when there is no fill geometry. Currently, the 3d hit test + uses only areas, so maybe in a further enchanced version this will change + to 'if neither filled nor lines' creation criteria. The whole primitive + decomposes to nothing, so no one not knowing it will be influenced. Only + helper processors for hit test (and maybe BoundRect extractors) will + use it and it's children subcontent. + */ class HitTestPrimitive3D : public GroupPrimitive3D { - protected: - // local decomposition. Implementation will return empty Primitive3DSequence - // since this is no visualisation data - virtual Primitive3DSequence createLocalDecomposition(const geometry::ViewInformation3D& rViewInformation) const; - public: + /// constructor HitTestPrimitive3D(const Primitive3DSequence& rChildren); - // despite returning an empty decomposition since it's no visualisation data, - // range calculation is intended to use invisible replacement geometry, so - // the local implementation will return the children's range + /** despite returning an empty decomposition since it's no visualisation data, + range calculation is intended to use invisible replacement geometry, so + the local implementation will return the children's range + */ virtual basegfx::B3DRange getB3DRange(const geometry::ViewInformation3D& rViewInformation) const; - // provide unique ID + /** local decomposition. Implementation will return empty Primitive3DSequence + since this is no visualisation data + */ + virtual Primitive3DSequence get3DDecomposition(const geometry::ViewInformation3D& rViewInformation) const; + + /// provide unique ID DeclPrimitrive3DIDBlock() }; } // end of namespace primitive3d diff --git a/drawinglayer/inc/drawinglayer/primitive3d/modifiedcolorprimitive3d.hxx b/drawinglayer/inc/drawinglayer/primitive3d/modifiedcolorprimitive3d.hxx index 0771e8117fc5..3840bf71a397 100644 --- a/drawinglayer/inc/drawinglayer/primitive3d/modifiedcolorprimitive3d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive3d/modifiedcolorprimitive3d.hxx @@ -45,23 +45,32 @@ namespace drawinglayer { namespace primitive3d { + /** ModifiedColorPrimitive3D class + + This primitive is a grouping primitive and allows to define + how the colors of it's child content shall be modified for + visualisation. Please see the ModifiedColorPrimitive2D + description for more info. + */ class ModifiedColorPrimitive3D : public GroupPrimitive3D { private: + /// The ColorModifier to use basegfx::BColorModifier maColorModifier; public: + /// constructor ModifiedColorPrimitive3D( const Primitive3DSequence& rChildren, const basegfx::BColorModifier& rColorModifier); - // get data + /// data read access const basegfx::BColorModifier& getColorModifier() const { return maColorModifier; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive3D& rPrimitive) const; - // provide unique ID + /// provide unique ID DeclPrimitrive3DIDBlock() }; } // end of namespace primitive3d diff --git a/drawinglayer/inc/drawinglayer/primitive3d/polygonprimitive3d.hxx b/drawinglayer/inc/drawinglayer/primitive3d/polygonprimitive3d.hxx index 9de2dc5949e7..c73850e4f794 100644 --- a/drawinglayer/inc/drawinglayer/primitive3d/polygonprimitive3d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive3d/polygonprimitive3d.hxx @@ -48,28 +48,40 @@ namespace drawinglayer { namespace primitive3d { + /** PolygonHairlinePrimitive3D class + + This primitive defines a Hairline in 3D. Since hairlines are view-dependent, + this primitive is view-dependent, too. + + This is one of the non-decomposable 3D primitives, so a renderer + should proccess it. + */ class PolygonHairlinePrimitive3D : public BasePrimitive3D { private: + /// the hairline geometry basegfx::B3DPolygon maPolygon; + + /// the hairline color basegfx::BColor maBColor; public: + /// constructor PolygonHairlinePrimitive3D( const basegfx::B3DPolygon& rPolygon, const basegfx::BColor& rBColor); - // get data + /// data read access const basegfx::B3DPolygon& getB3DPolygon() const { return maPolygon; } const basegfx::BColor& getBColor() const { return maBColor; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive3D& rPrimitive) const; - // get range + /// get range virtual basegfx::B3DRange getB3DRange(const geometry::ViewInformation3D& rViewInformation) const; - // provide unique ID + /// provide unique ID DeclPrimitrive3DIDBlock() }; } // end of namespace primitive3d @@ -81,36 +93,49 @@ namespace drawinglayer { namespace primitive3d { - class PolygonStrokePrimitive3D : public BasePrimitive3D + /** PolygonStrokePrimitive3D class + + This primitive defines a 3D line with line width, line join, line color + and stroke attributes. It will be decomposed dependent on the definition + to the needed primitives, e.g. filled Tubes for fat lines. + */ + class PolygonStrokePrimitive3D : public BufferedDecompositionPrimitive3D { private: + /// the line geometry basegfx::B3DPolygon maPolygon; + + /// the line attributes like width, join and color attribute::LineAttribute maLineAttribute; + + /// the line stroking (if used) attribute::StrokeAttribute maStrokeAttribute; protected: - // local decomposition. - virtual Primitive3DSequence createLocalDecomposition(const geometry::ViewInformation3D& rViewInformation) const; + /// local decomposition. + virtual Primitive3DSequence create3DDecomposition(const geometry::ViewInformation3D& rViewInformation) const; public: + /// constructor PolygonStrokePrimitive3D( const basegfx::B3DPolygon& rPolygon, const attribute::LineAttribute& rLineAttribute, const attribute::StrokeAttribute& rStrokeAttribute); + /// constructor without stroking PolygonStrokePrimitive3D( const basegfx::B3DPolygon& rPolygon, const attribute::LineAttribute& rLineAttribute); - // get data + /// data read access basegfx::B3DPolygon getB3DPolygon() const { return maPolygon; } const attribute::LineAttribute& getLineAttribute() const { return maLineAttribute; } const attribute::StrokeAttribute& getStrokeAttribute() const { return maStrokeAttribute; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive3D& rPrimitive) const; - // provide unique ID + /// provide unique ID DeclPrimitrive3DIDBlock() }; } // end of namespace primitive3d diff --git a/drawinglayer/inc/drawinglayer/primitive3d/polygontubeprimitive3d.hxx b/drawinglayer/inc/drawinglayer/primitive3d/polygontubeprimitive3d.hxx index 8a9b293a8c5e..f5d45f7c1639 100644 --- a/drawinglayer/inc/drawinglayer/primitive3d/polygontubeprimitive3d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive3d/polygontubeprimitive3d.hxx @@ -52,19 +52,38 @@ namespace drawinglayer { namespace primitive3d { + /** PolygonStrokePrimitive3D class + + This 3D primitive extends a 3D hairline to a 3D tube which is + e.g. used for fat lines in 3D. It's decomposition will create all + 3D objects needed for the line tubes and the edge roundings + in full 3D. + */ class PolygonTubePrimitive3D : public PolygonHairlinePrimitive3D { private: + /// hold the last decompositon since it's expensive + Primitive3DSequence maLast3DDecomposition; + + /// visualisation parameters double mfRadius; double mfDegreeStepWidth; double mfMiterMinimumAngle; basegfx::B2DLineJoin maLineJoin; protected: - // local decomposition. - virtual Primitive3DSequence createLocalDecomposition(const geometry::ViewInformation3D& rViewInformation) const; + /** access methods to maLast3DDecomposition. The usage of this methods may allow + later thread-safe stuff to be added if needed. Only to be used by getDecomposition() + implementations for buffering the last decomposition. + */ + const Primitive3DSequence& getLast3DDecomposition() const { return maLast3DDecomposition; } + void setLast3DDecomposition(const Primitive3DSequence& rNew) { maLast3DDecomposition = rNew; } + + /// local decomposition. + Primitive3DSequence impCreate3DDecomposition(const geometry::ViewInformation3D& rViewInformation) const; public: + /// constructor PolygonTubePrimitive3D( const basegfx::B3DPolygon& rPolygon, const basegfx::BColor& rBColor, @@ -72,16 +91,21 @@ namespace drawinglayer double fDegreeStepWidth = 10.0 * F_PI180, double fMiterMinimumAngle = 15.0 * F_PI180); - // get data + /// data read access double getRadius() const { return mfRadius; } double getDegreeStepWidth() const { return mfDegreeStepWidth; } double getMiterMinimumAngle() const { return mfMiterMinimumAngle; } basegfx::B2DLineJoin getLineJoin() const { return maLineJoin; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive3D& rPrimitive) const; - // provide unique ID + /** local decomposition. Use own buffering since we are not derived from + BufferedDecompositionPrimitive3D + */ + virtual Primitive3DSequence get3DDecomposition(const geometry::ViewInformation3D& rViewInformation) const; + + /// provide unique ID DeclPrimitrive3DIDBlock() }; } // end of namespace primitive3d diff --git a/drawinglayer/inc/drawinglayer/primitive3d/polypolygonprimitive3d.hxx b/drawinglayer/inc/drawinglayer/primitive3d/polypolygonprimitive3d.hxx index 1c5b9e400bbb..091e8181e38f 100644 --- a/drawinglayer/inc/drawinglayer/primitive3d/polypolygonprimitive3d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive3d/polypolygonprimitive3d.hxx @@ -46,33 +46,45 @@ namespace drawinglayer { namespace primitive3d { + /** PolyPolygonMaterialPrimitive3D class + + This primitive defines a planar 3D PolyPolygon filled with a single color. + This is one of the non-decomposable primitives, so a renderer + should proccess it. + + It is assumed here that the PolyPolgon is a single plane in 3D. + */ class PolyPolygonMaterialPrimitive3D : public BasePrimitive3D { private: + /// the PolyPolygon geometry basegfx::B3DPolyPolygon maPolyPolygon; + + /// the fill parameters attribute::MaterialAttribute3D maMaterial; - // bitfield + /// bitfield unsigned mbDoubleSided : 1; public: + /// constructor PolyPolygonMaterialPrimitive3D( const basegfx::B3DPolyPolygon& rPolyPolygon, const attribute::MaterialAttribute3D& rMaterial, bool bDoubleSided); - // get data + /// data read access const basegfx::B3DPolyPolygon& getB3DPolyPolygon() const { return maPolyPolygon; } const attribute::MaterialAttribute3D& getMaterial() const { return maMaterial; } bool getDoubleSided() const { return mbDoubleSided; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive3D& rPrimitive) const; - // get range + /// get range virtual basegfx::B3DRange getB3DRange(const geometry::ViewInformation3D& rViewInformation) const; - // provide unique ID + /// provide unique ID DeclPrimitrive3DIDBlock() }; } // end of namespace primitive3d diff --git a/drawinglayer/inc/drawinglayer/primitive3d/sdrcubeprimitive3d.hxx b/drawinglayer/inc/drawinglayer/primitive3d/sdrcubeprimitive3d.hxx index 57f31a46a557..b3a57f2677dc 100644 --- a/drawinglayer/inc/drawinglayer/primitive3d/sdrcubeprimitive3d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive3d/sdrcubeprimitive3d.hxx @@ -44,26 +44,33 @@ namespace drawinglayer { namespace primitive3d { + /** SdrCubePrimitive3D class + + This 3D primitive expands the SdrPrimitive3D to a 3D cube definition. + The cube is implicitely in unit coordinates and the given transformation + defines it's geometry in space. + */ class SdrCubePrimitive3D : public SdrPrimitive3D { protected: - // local decomposition. - virtual Primitive3DSequence createLocalDecomposition(const geometry::ViewInformation3D& rViewInformation) const; + /// local decomposition. + virtual Primitive3DSequence create3DDecomposition(const geometry::ViewInformation3D& rViewInformation) const; public: + /// constructor SdrCubePrimitive3D( const basegfx::B3DHomMatrix& rTransform, const basegfx::B2DVector& rTextureSize, const attribute::SdrLineFillShadowAttribute& rSdrLFSAttribute, const attribute::Sdr3DObjectAttribute& rSdr3DObjectAttribute); - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive3D& rPrimitive) const; - // get range + /// get range virtual basegfx::B3DRange getB3DRange(const geometry::ViewInformation3D& rViewInformation) const; - // provide unique ID + /// provide unique ID DeclPrimitrive3DIDBlock() }; } // end of namespace primitive3d diff --git a/drawinglayer/inc/drawinglayer/primitive3d/sdrdecompositiontools3d.hxx b/drawinglayer/inc/drawinglayer/primitive3d/sdrdecompositiontools3d.hxx index 772e030781fe..5b793a6928f8 100644 --- a/drawinglayer/inc/drawinglayer/primitive3d/sdrdecompositiontools3d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive3d/sdrdecompositiontools3d.hxx @@ -42,6 +42,7 @@ ////////////////////////////////////////////////////////////////////////////// // predefines + namespace basegfx { class B3DPolygon; class B3DPolyPolygon; diff --git a/drawinglayer/inc/drawinglayer/primitive3d/sdrextrudelathetools3d.hxx b/drawinglayer/inc/drawinglayer/primitive3d/sdrextrudelathetools3d.hxx index 43ae13d4625f..b80198d127d2 100644 --- a/drawinglayer/inc/drawinglayer/primitive3d/sdrextrudelathetools3d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive3d/sdrextrudelathetools3d.hxx @@ -53,7 +53,7 @@ namespace drawinglayer { namespace primitive3d { - // Slice3D types + /** SliceType3D definition */ enum SliceType3D { SLICETYPE3D_REGULAR, // normal geoemtry Slice3D @@ -61,7 +61,7 @@ namespace drawinglayer SLICETYPE3D_BACKCAP // back cap }; - // class to hold one Slice3D + /// class to hold one Slice3D class Slice3D { protected: @@ -92,10 +92,10 @@ namespace drawinglayer SliceType3D getSliceType() const { return maSliceType; } }; - // typedef for a group of Slice3Ds + /// typedef for a group of Slice3Ds typedef ::std::vector< Slice3D > Slice3DVector; - // helpers for creation + /// helpers for creation void createLatheSlices( Slice3DVector& rSliceVector, const basegfx::B2DPolyPolygon& rSource, @@ -117,7 +117,7 @@ namespace drawinglayer bool bCloseFront, bool bCloseBack); - // helpers for geometry extraction + /// helpers for geometry extraction basegfx::B3DPolyPolygon extractHorizontalLinesFromSlice(const Slice3DVector& rSliceVector, bool bCloseHorLines); basegfx::B3DPolyPolygon extractVerticalLinesFromSlice(const Slice3DVector& rSliceVector); diff --git a/drawinglayer/inc/drawinglayer/primitive3d/sdrextrudeprimitive3d.hxx b/drawinglayer/inc/drawinglayer/primitive3d/sdrextrudeprimitive3d.hxx index a6d386bf194a..a810e0f5ec8e 100644 --- a/drawinglayer/inc/drawinglayer/primitive3d/sdrextrudeprimitive3d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive3d/sdrextrudeprimitive3d.hxx @@ -45,23 +45,34 @@ namespace drawinglayer { namespace primitive3d { + /** SdrExtrudePrimitive3D class + + This 3D primitive expands the SdrPrimitive3D to a 3D extrude definition. + The given 2D PolyPolygon geometry is imagined as lying on the XY-plane in 3D + and gets extruded in Z-Direction by Depth. + + Various possibilities e.g. for creating diagonals (edge roudings in 3D) + and similar are given. + + The decomposition will create all necessary 3D planes for visualisation. + */ class SdrExtrudePrimitive3D : public SdrPrimitive3D { private: - // geometry helper for slices + /// geometry helper for slices basegfx::B2DPolyPolygon maCorrectedPolyPolygon; Slice3DVector maSlices; - // primitive data + /// primitive geometry data basegfx::B2DPolyPolygon maPolyPolygon; double mfDepth; double mfDiagonal; double mfBackScale; - // decomposition data when ReducedLineGeometry is used, see get3DDecomposition + /// decomposition data when ReducedLineGeometry is used, see get3DDecomposition geometry::ViewInformation3D* mpLastRLGViewInformation; - // bitfield + /// bitfield unsigned mbSmoothNormals : 1; // Plane self unsigned mbSmoothHorizontalNormals : 1; // always unsigned mbSmoothLids : 1; // Front/back @@ -69,17 +80,18 @@ namespace drawinglayer unsigned mbCloseFront : 1; unsigned mbCloseBack : 1; - // create slices + /// create slices void impCreateSlices(); - // get (evtl. create) slices + /// get (evtl. create) slices const Slice3DVector& getSlices() const; protected: - // local decomposition. - virtual Primitive3DSequence createLocalDecomposition(const geometry::ViewInformation3D& rViewInformation) const; + /// local decomposition. + virtual Primitive3DSequence create3DDecomposition(const geometry::ViewInformation3D& rViewInformation) const; public: + /// constructor SdrExtrudePrimitive3D( const basegfx::B3DHomMatrix& rTransform, const basegfx::B2DVector& rTextureSize, @@ -97,7 +109,7 @@ namespace drawinglayer bool bCloseBack); virtual ~SdrExtrudePrimitive3D(); - // data access + /// data read access const basegfx::B2DPolyPolygon& getPolyPolygon() const { return maPolyPolygon; } double getDepth() const { return mfDepth; } double getDiagonal() const { return mfDiagonal; } @@ -109,16 +121,16 @@ namespace drawinglayer bool getCloseFront() const { return mbCloseFront; } bool getCloseBack() const { return mbCloseBack; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive3D& rPrimitive) const; - // get range + /// get range virtual basegfx::B3DRange getB3DRange(const geometry::ViewInformation3D& rViewInformation) const; - // Overloaded to allow for reduced line mode to decide if to buffer decomposition or not + /// Overloaded to allow for reduced line mode to decide if to buffer decomposition or not virtual Primitive3DSequence get3DDecomposition(const geometry::ViewInformation3D& rViewInformation) const; - // provide unique ID + /// provide unique ID DeclPrimitrive3DIDBlock() }; } // end of namespace primitive3d diff --git a/drawinglayer/inc/drawinglayer/primitive3d/sdrlatheprimitive3d.hxx b/drawinglayer/inc/drawinglayer/primitive3d/sdrlatheprimitive3d.hxx index 99d06e256431..084ce5bce35e 100644 --- a/drawinglayer/inc/drawinglayer/primitive3d/sdrlatheprimitive3d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive3d/sdrlatheprimitive3d.hxx @@ -45,14 +45,25 @@ namespace drawinglayer { namespace primitive3d { + /** SdrLathePrimitive3D class + + This 3D primitive expands the SdrPrimitive3D to a 3D rotation definition. + The given 2D PolyPolygon geometry is imagined as lying on the XY-plane in 3D + and gets rotated around the Y-Axis. + + Various possibilities e.g. for creating diagonals (edge roudings in 3D) + and similar are given. + + The decomposition will create all necessary 3D planes for visualisation. + */ class SdrLathePrimitive3D : public SdrPrimitive3D { private: - // geometry helper for slices + /// geometry helper for slices basegfx::B2DPolyPolygon maCorrectedPolyPolygon; Slice3DVector maSlices; - // primitive data + /// primitive geometry data basegfx::B2DPolyPolygon maPolyPolygon; sal_uInt32 mnHorizontalSegments; sal_uInt32 mnVerticalSegments; @@ -60,10 +71,10 @@ namespace drawinglayer double mfBackScale; double mfRotation; - // decomposition data when ReducedLineGeometry is used, see get3DDecomposition + /// decomposition data when ReducedLineGeometry is used, see get3DDecomposition geometry::ViewInformation3D* mpLastRLGViewInformation; - // bitfield + /// bitfield unsigned mbSmoothNormals : 1; // Plane self unsigned mbSmoothHorizontalNormals : 1; // always unsigned mbSmoothLids : 1; // Front/back @@ -71,14 +82,14 @@ namespace drawinglayer unsigned mbCloseFront : 1; unsigned mbCloseBack : 1; - // create slices + /// create slices void impCreateSlices(); - // get (evtl. create) slices + /// get (evtl. create) slices const Slice3DVector& getSlices() const; protected: - // local helpers + /// local helpers void impCreateOutlines( const geometry::ViewInformation3D& rViewInformation, const basegfx::B3DPolygon& rLoopA, @@ -90,10 +101,11 @@ namespace drawinglayer const basegfx::B2DPoint& rStart, const basegfx::B2DPoint& rEnd) const; - // local decomposition. - virtual Primitive3DSequence createLocalDecomposition(const geometry::ViewInformation3D& rViewInformation) const; + /// local decomposition. + virtual Primitive3DSequence create3DDecomposition(const geometry::ViewInformation3D& rViewInformation) const; public: + /// constructor SdrLathePrimitive3D( const basegfx::B3DHomMatrix& rTransform, const basegfx::B2DVector& rTextureSize, @@ -113,7 +125,7 @@ namespace drawinglayer bool bCloseBack); virtual ~SdrLathePrimitive3D(); - // data access + /// data read access const basegfx::B2DPolyPolygon& getPolyPolygon() const { return maPolyPolygon; } sal_uInt32 getHorizontalSegments() const { return mnHorizontalSegments; } sal_uInt32 getVerticalSegments() const { return mnVerticalSegments; } @@ -127,16 +139,16 @@ namespace drawinglayer bool getCloseFront() const { return mbCloseFront; } bool getCloseBack() const { return mbCloseBack; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive3D& rPrimitive) const; - // get range + /// get range virtual basegfx::B3DRange getB3DRange(const geometry::ViewInformation3D& rViewInformation) const; - // Overloaded to allow for reduced line mode to decide if to buffer decomposition or not + /// Overloaded to allow for reduced line mode to decide if to buffer decomposition or not virtual Primitive3DSequence get3DDecomposition(const geometry::ViewInformation3D& rViewInformation) const; - // provide unique ID + /// provide unique ID DeclPrimitrive3DIDBlock() }; } // end of namespace primitive3d diff --git a/drawinglayer/inc/drawinglayer/primitive3d/sdrpolypolygonprimitive3d.hxx b/drawinglayer/inc/drawinglayer/primitive3d/sdrpolypolygonprimitive3d.hxx index 4eec829afeb5..a6c68bd16da8 100644 --- a/drawinglayer/inc/drawinglayer/primitive3d/sdrpolypolygonprimitive3d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive3d/sdrpolypolygonprimitive3d.hxx @@ -44,17 +44,28 @@ namespace drawinglayer { namespace primitive3d { + /** SdrPolyPolygonPrimitive3D class + + This 3D primitive defines a PolyPolgon in space which may have + Line- and FillStyles and extra 3D surface attributes. It is assumed + that the given 3D PolyPolgon (which may contain texture and normal + information) is planar in 3D. + + The decomposition will include all needed 3D data for visualisation, + including FatLines and fill styles. + */ class SdrPolyPolygonPrimitive3D : public SdrPrimitive3D { private: - // the polyPolygon evtl with normals and texture coordinates + /// the planar polyPolygon evtl with normals and texture coordinates basegfx::B3DPolyPolygon maPolyPolygon3D; protected: - // local decomposition. - virtual Primitive3DSequence createLocalDecomposition(const geometry::ViewInformation3D& rViewInformation) const; + /// local decomposition. + virtual Primitive3DSequence create3DDecomposition(const geometry::ViewInformation3D& rViewInformation) const; public: + /// constructor SdrPolyPolygonPrimitive3D( const basegfx::B3DPolyPolygon& rPolyPolygon3D, const basegfx::B3DHomMatrix& rTransform, @@ -62,16 +73,16 @@ namespace drawinglayer const attribute::SdrLineFillShadowAttribute& rSdrLFSAttribute, const attribute::Sdr3DObjectAttribute& rSdr3DObjectAttribute); - // data access + /// data access const basegfx::B3DPolyPolygon& getPolyPolygon3D() const { return maPolyPolygon3D; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive3D& rPrimitive) const; - // get range + /// get range virtual basegfx::B3DRange getB3DRange(const geometry::ViewInformation3D& rViewInformation) const; - // provide unique ID + /// provide unique ID DeclPrimitrive3DIDBlock() }; } // end of namespace primitive3d diff --git a/drawinglayer/inc/drawinglayer/primitive3d/sdrprimitive3d.hxx b/drawinglayer/inc/drawinglayer/primitive3d/sdrprimitive3d.hxx index 6b381445716e..4dd620848387 100644 --- a/drawinglayer/inc/drawinglayer/primitive3d/sdrprimitive3d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive3d/sdrprimitive3d.hxx @@ -47,39 +47,49 @@ namespace drawinglayer { + /** SdrPrimitive3D class + + Base class for the more complicated geometric primitives, so + derive from buffered primitive to allow overloading of + create3DDecomposition there. + */ namespace primitive3d { - class SdrPrimitive3D : public BasePrimitive3D + class SdrPrimitive3D : public BufferedDecompositionPrimitive3D { private: + /// object surface attributes basegfx::B3DHomMatrix maTransform; basegfx::B2DVector maTextureSize; attribute::SdrLineFillShadowAttribute maSdrLFSAttribute; attribute::Sdr3DObjectAttribute maSdr3DObjectAttribute; protected: - // Standard implementation for primitive3D which - // will use maTransform as range and expand by evtl. line width / 2 + /** Standard implementation for primitive3D which + will use maTransform as range and expand by evtl. line width / 2 + */ basegfx::B3DRange getStandard3DRange() const; - // implementation for primitive3D which - // will use given Slice3Ds and expand by evtl. line width / 2 + /** implementation for primitive3D which + will use given Slice3Ds and expand by evtl. line width / 2 + */ basegfx::B3DRange get3DRangeFromSlices(const Slice3DVector& rSlices) const; public: + /// constructor SdrPrimitive3D( const basegfx::B3DHomMatrix& rTransform, const basegfx::B2DVector& rTextureSize, const attribute::SdrLineFillShadowAttribute& rSdrLFSAttribute, const attribute::Sdr3DObjectAttribute& rSdr3DObjectAttribute); - // data access + /// data read access const basegfx::B3DHomMatrix& getTransform() const { return maTransform; } const basegfx::B2DVector& getTextureSize() const { return maTextureSize; } const attribute::SdrLineFillShadowAttribute& getSdrLFSAttribute() const { return maSdrLFSAttribute; } const attribute::Sdr3DObjectAttribute getSdr3DObjectAttribute() const { return maSdr3DObjectAttribute; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive3D& rPrimitive) const; }; } // end of namespace primitive3d diff --git a/drawinglayer/inc/drawinglayer/primitive3d/sdrsphereprimitive3d.hxx b/drawinglayer/inc/drawinglayer/primitive3d/sdrsphereprimitive3d.hxx index 358298e30456..52e646e6b4dc 100644 --- a/drawinglayer/inc/drawinglayer/primitive3d/sdrsphereprimitive3d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive3d/sdrsphereprimitive3d.hxx @@ -44,17 +44,25 @@ namespace drawinglayer { namespace primitive3d { + /** SdrSpherePrimitive3D class + + This 3D primitive expands the SdrPrimitive3D to a 3D sphere definition. + The sphere is implicitely in unit coordinates and the given transformation + defines it's geometry in space. + */ class SdrSpherePrimitive3D : public SdrPrimitive3D { private: + /// additional geometry definitions sal_uInt32 mnHorizontalSegments; sal_uInt32 mnVerticalSegments; protected: - // local decomposition. - virtual Primitive3DSequence createLocalDecomposition(const geometry::ViewInformation3D& rViewInformation) const; + /// local decomposition. + virtual Primitive3DSequence create3DDecomposition(const geometry::ViewInformation3D& rViewInformation) const; public: + /// constructor SdrSpherePrimitive3D( const basegfx::B3DHomMatrix& rTransform, const basegfx::B2DVector& rTextureSize, @@ -63,17 +71,17 @@ namespace drawinglayer sal_uInt32 nHorizontalSegments, sal_uInt32 nVerticalSegments); - // data access + /// data read access sal_uInt32 getHorizontalSegments() const { return mnHorizontalSegments; } sal_uInt32 getVerticalSegments() const { return mnVerticalSegments; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive3D& rPrimitive) const; - // get range + /// get range virtual basegfx::B3DRange getB3DRange(const geometry::ViewInformation3D& rViewInformation) const; - // provide unique ID + /// provide unique ID DeclPrimitrive3DIDBlock() }; } // end of namespace primitive3d diff --git a/drawinglayer/inc/drawinglayer/primitive3d/shadowprimitive3d.hxx b/drawinglayer/inc/drawinglayer/primitive3d/shadowprimitive3d.hxx index d511c89a9998..cb8e9cd385d0 100644 --- a/drawinglayer/inc/drawinglayer/primitive3d/shadowprimitive3d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive3d/shadowprimitive3d.hxx @@ -46,17 +46,29 @@ namespace drawinglayer { namespace primitive3d { + /** ShadowPrimitive3D class + + This 3D grouping primitive is used to define a shadow for + 3d geometry by embedding it. The shadow of 3D objects are + 2D polygons, so the shadow transformation is a 2D transformation. + + If the Shadow3D flag is set, the shadow definition has to be + combined with the scene and camera definition to create the correct + projected shadow 2D-Polygons. + */ class ShadowPrimitive3D : public GroupPrimitive3D { protected: + /// 2D shadow definition basegfx::B2DHomMatrix maShadowTransform; basegfx::BColor maShadowColor; double mfShadowTransparence; - // bitfield + /// bitfield unsigned mbShadow3D : 1; public: + /// constructor ShadowPrimitive3D( const basegfx::B2DHomMatrix& rShadowTransform, const basegfx::BColor& rShadowColor, @@ -64,16 +76,16 @@ namespace drawinglayer bool bShadow3D, const Primitive3DSequence& rChildren); - // get data + /// data read access const basegfx::B2DHomMatrix& getShadowTransform() const { return maShadowTransform; } const basegfx::BColor& getShadowColor() const { return maShadowColor; } double getShadowTransparence() const { return mfShadowTransparence; } bool getShadow3D() const { return mbShadow3D; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive3D& rPrimitive) const; - // provide unique ID + /// provide unique ID DeclPrimitrive3DIDBlock() }; } // end of namespace primitive3d diff --git a/drawinglayer/inc/drawinglayer/primitive3d/textureprimitive3d.hxx b/drawinglayer/inc/drawinglayer/primitive3d/textureprimitive3d.hxx index 15b8e1265709..f8b81e357ea5 100644 --- a/drawinglayer/inc/drawinglayer/primitive3d/textureprimitive3d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive3d/textureprimitive3d.hxx @@ -47,31 +47,39 @@ namespace drawinglayer { namespace primitive3d { + /** TexturePrimitive3D class + + This 3D grouping primitive is used to define a texture for + 3d geometry by embedding it. It is used as bae class for + extended texture definitions + */ class TexturePrimitive3D : public GroupPrimitive3D { private: + /// texture geometry definition basegfx::B2DVector maTextureSize; - // bitfield - // flag if texture shall be modulated with white interpolated color + /// bitfield + /// flag if texture shall be modulated with white interpolated color unsigned mbModulate : 1; - // flag if texture shall be filtered + /// flag if texture shall be filtered unsigned mbFilter : 1; public: + /// constructor TexturePrimitive3D( const Primitive3DSequence& rChildren, const basegfx::B2DVector& rTextureSize, bool bModulate, bool bFilter); - // get data + /// data read access const basegfx::B2DVector& getTextureSize() const { return maTextureSize; } bool getModulate() const { return mbModulate; } bool getFilter() const { return mbFilter; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive3D& rPrimitive) const; }; } // end of namespace primitive3d @@ -83,27 +91,34 @@ namespace drawinglayer { namespace primitive3d { + /** UnifiedAlphaTexturePrimitive3D class + + This 3D primitive expands TexturePrimitive3D to a unified + alpha (transparence) texture definition. All 3D primitives + embedded here will be shown with the given transparency. + */ class UnifiedAlphaTexturePrimitive3D : public TexturePrimitive3D { private: + /// transparency definition double mfTransparence; - protected: - // local decomposition. - virtual Primitive3DSequence createLocalDecomposition(const geometry::ViewInformation3D& rViewInformation) const; - public: + /// constructor UnifiedAlphaTexturePrimitive3D( double fTransparence, const Primitive3DSequence& rChildren); - // get data + /// data read access double getTransparence() const { return mfTransparence; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive3D& rPrimitive) const; - // provide unique ID + /// local decomposition. + virtual Primitive3DSequence get3DDecomposition(const geometry::ViewInformation3D& rViewInformation) const; + + /// provide unique ID DeclPrimitrive3DIDBlock() }; } // end of namespace primitive3d @@ -115,16 +130,20 @@ namespace drawinglayer { namespace primitive3d { + /** GradientTexturePrimitive3D class + + This 3D primitive expands TexturePrimitive3D to a gradient texture + definition. All 3D primitives embedded here will be shown with the + defined gradient. + */ class GradientTexturePrimitive3D : public TexturePrimitive3D { private: + /// the gradient definition attribute::FillGradientAttribute maGradient; - protected: - // local decomposition. - virtual Primitive3DSequence createLocalDecomposition(const geometry::ViewInformation3D& rViewInformation) const; - public: + /// constructor GradientTexturePrimitive3D( const attribute::FillGradientAttribute& rGradient, const Primitive3DSequence& rChildren, @@ -132,13 +151,13 @@ namespace drawinglayer bool bModulate, bool bFilter); - // get data + /// data read access const attribute::FillGradientAttribute& getGradient() const { return maGradient; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive3D& rPrimitive) const; - // provide unique ID + /// provide unique ID DeclPrimitrive3DIDBlock() }; } // end of namespace primitive3d @@ -150,30 +169,34 @@ namespace drawinglayer { namespace primitive3d { + /** BitmapTexturePrimitive3D class + + This 3D primitive expands TexturePrimitive3D to a bitmap texture + definition. All 3D primitives embedded here will be shown with the + defined bitmap (maybe tiled if defined). + */ class BitmapTexturePrimitive3D : public TexturePrimitive3D { private: - attribute::FillBitmapAttribute maBitmap; - - protected: - // local decomposition. - virtual Primitive3DSequence createLocalDecomposition(const geometry::ViewInformation3D& rViewInformation) const; + /// bitmap fill attribute + attribute::FillBitmapAttribute maFillBitmapAttribute; public: + /// constructor BitmapTexturePrimitive3D( - const attribute::FillBitmapAttribute& rBitmap, + const attribute::FillBitmapAttribute& rFillBitmapAttribute, const Primitive3DSequence& rChildren, const basegfx::B2DVector& rTextureSize, bool bModulate, bool bFilter); - // get data - const attribute::FillBitmapAttribute& getBitmap() const { return maBitmap; } + /// data read access + const attribute::FillBitmapAttribute& getFillBitmapAttribute() const { return maFillBitmapAttribute; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive3D& rPrimitive) const; - // provide unique ID + /// provide unique ID DeclPrimitrive3DIDBlock() }; } // end of namespace primitive3d @@ -185,18 +208,26 @@ namespace drawinglayer { namespace primitive3d { + /** AlphaTexturePrimitive3D class + + This 3D primitive expands TexturePrimitive3D to a alpha texture + definition. For alpha definition, a gradient is used. The values in + that gradient will be interpreted as luminance Alpha-Values. All 3D + primitives embedded here will be shown with the defined transparence. + */ class AlphaTexturePrimitive3D : public GradientTexturePrimitive3D { public: + /// constructor AlphaTexturePrimitive3D( const attribute::FillGradientAttribute& rGradient, const Primitive3DSequence& rChildren, const basegfx::B2DVector& rTextureSize); - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive3D& rPrimitive) const; - // provide unique ID + /// provide unique ID DeclPrimitrive3DIDBlock() }; } // end of namespace primitive3d diff --git a/drawinglayer/inc/drawinglayer/primitive3d/transformprimitive3d.hxx b/drawinglayer/inc/drawinglayer/primitive3d/transformprimitive3d.hxx index 720f28445dec..bbf2b8444969 100644 --- a/drawinglayer/inc/drawinglayer/primitive3d/transformprimitive3d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive3d/transformprimitive3d.hxx @@ -45,26 +45,37 @@ namespace drawinglayer { namespace primitive3d { + /** TransformPrimitive3D class + + This is one of the basic grouping 3D primitives and it provides + embedding a sequence of primitives (a geometry) into a + 3D transformation. + + Please see the description for TransformPrimitive2D since these + primitives are pretty similar. + */ class TransformPrimitive3D : public GroupPrimitive3D { private: + // the 3D transformation to apply basegfx::B3DHomMatrix maTransformation; public: + /// constructor TransformPrimitive3D( const basegfx::B3DHomMatrix& rTransformation, const Primitive3DSequence& rChildren); - // get data + /// data read access const basegfx::B3DHomMatrix& getTransformation() const { return maTransformation; } - // compare operator + /// compare operator virtual bool operator==(const BasePrimitive3D& rPrimitive) const; - // get range + /// get range virtual basegfx::B3DRange getB3DRange(const geometry::ViewInformation3D& rViewInformation) const; - // provide unique ID + /// provide unique ID DeclPrimitrive3DIDBlock() }; } // end of namespace primitive3d diff --git a/drawinglayer/inc/drawinglayer/processor2d/vclprocessor2d.hxx b/drawinglayer/inc/drawinglayer/processor2d/vclprocessor2d.hxx index 66ca140c2e56..ff77cc3fd5d0 100644 --- a/drawinglayer/inc/drawinglayer/processor2d/vclprocessor2d.hxx +++ b/drawinglayer/inc/drawinglayer/processor2d/vclprocessor2d.hxx @@ -64,6 +64,7 @@ namespace drawinglayer { namespace primitive2d { class PolygonStrokePrimitive2D; class ControlPrimitive2D; class PagePreviewPrimitive2D; + class EpsPrimitive2D; }} ////////////////////////////////////////////////////////////////////////////// @@ -113,6 +114,7 @@ namespace drawinglayer void RenderMarkerArrayPrimitive2D(const primitive2d::MarkerArrayPrimitive2D& rMarkerArrayCandidate); void RenderPointArrayPrimitive2D(const primitive2d::PointArrayPrimitive2D& rPointArrayCandidate); void RenderPolygonStrokePrimitive2D(const primitive2d::PolygonStrokePrimitive2D& rPolygonStrokeCandidate); + void RenderEpsPrimitive2D(const primitive2d::EpsPrimitive2D& rEpsPrimitive2D); ///////////////////////////////////////////////////////////////////////////// // DrawMode adaption support diff --git a/drawinglayer/prj/d.lst b/drawinglayer/prj/d.lst index 1ba3c2e7b614..ee5b96d98a03 100644 --- a/drawinglayer/prj/d.lst +++ b/drawinglayer/prj/d.lst @@ -39,6 +39,7 @@ mkdir: %_DEST%\inc%_EXT%\drawinglayer\primitive2d ..\inc\drawinglayer\primitive2d\sceneprimitive2d.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive2d\sceneprimitive2d.hxx ..\inc\drawinglayer\primitive2d\shadowprimitive2d.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive2d\shadowprimitive2d.hxx ..\inc\drawinglayer\primitive2d\structuretagprimitive2d.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive2d\structuretagprimitive2d.hxx +..\inc\drawinglayer\primitive2d\textenumsprimitive2d.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive2d\textenumsprimitive2d.hxx ..\inc\drawinglayer\primitive2d\texteffectprimitive2d.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive2d\texteffectprimitive2d.hxx ..\inc\drawinglayer\primitive2d\textlayoutdevice.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive2d\textlayoutdevice.hxx ..\inc\drawinglayer\primitive2d\textprimitive2d.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive2d\textprimitive2d.hxx @@ -98,6 +99,7 @@ mkdir: %_DEST%\inc%_EXT%\drawinglayer\processor3d mkdir: %_DEST%\inc%_EXT%\drawinglayer\attribute ..\inc\drawinglayer\attribute\fillattribute.hxx %_DEST%\inc%_EXT%\drawinglayer\attribute\fillattribute.hxx ..\inc\drawinglayer\attribute\fillbitmapattribute.hxx %_DEST%\inc%_EXT%\drawinglayer\attribute\fillbitmapattribute.hxx +..\inc\drawinglayer\attribute\fontattribute.hxx %_DEST%\inc%_EXT%\drawinglayer\attribute\fontattribute.hxx ..\inc\drawinglayer\attribute\materialattribute3d.hxx %_DEST%\inc%_EXT%\drawinglayer\attribute\materialattribute3d.hxx ..\inc\drawinglayer\attribute\sdrallattribute3d.hxx %_DEST%\inc%_EXT%\drawinglayer\attribute\sdrallattribute3d.hxx ..\inc\drawinglayer\attribute\sdrattribute.hxx %_DEST%\inc%_EXT%\drawinglayer\attribute\sdrattribute.hxx diff --git a/drawinglayer/source/attribute/fillbitmapattribute.cxx b/drawinglayer/source/attribute/fillbitmapattribute.cxx index 539e85ab2733..99afb234bda5 100644 --- a/drawinglayer/source/attribute/fillbitmapattribute.cxx +++ b/drawinglayer/source/attribute/fillbitmapattribute.cxx @@ -44,8 +44,12 @@ namespace drawinglayer { namespace attribute { - FillBitmapAttribute::FillBitmapAttribute(const Bitmap& rBitmap, const basegfx::B2DPoint& rTopLeft, const basegfx::B2DVector& rSize, bool bTiling) - : maBitmap(rBitmap), + FillBitmapAttribute::FillBitmapAttribute( + const BitmapEx& rBitmapEx, + const basegfx::B2DPoint& rTopLeft, + const basegfx::B2DVector& rSize, + bool bTiling) + : maBitmapEx(rBitmapEx), maTopLeft(rTopLeft), maSize(rSize), mbTiling(bTiling) @@ -54,10 +58,10 @@ namespace drawinglayer bool FillBitmapAttribute::operator==(const FillBitmapAttribute& rCandidate) const { - return (maBitmap == rCandidate.maBitmap - && maTopLeft == rCandidate.maTopLeft - && maSize == rCandidate.maSize - && mbTiling == rCandidate.mbTiling); + return (getBitmapEx() == rCandidate.getBitmapEx() + && getTopLeft() == rCandidate.getTopLeft() + && getSize() == rCandidate.getSize() + && getTiling() == rCandidate.getTiling()); } } // end of namespace attribute } // end of namespace drawinglayer diff --git a/drawinglayer/source/attribute/fontattribute.cxx b/drawinglayer/source/attribute/fontattribute.cxx new file mode 100644 index 000000000000..5163e2f6a59a --- /dev/null +++ b/drawinglayer/source/attribute/fontattribute.cxx @@ -0,0 +1,63 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: strokeattribute.cxx,v $ + * + * $Revision: 1.3 $ + * + * last change: $Author: aw $ $Date: 2008-05-27 14:11:19 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_drawinglayer.hxx" + +#include <drawinglayer/attribute/fontattribute.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace attribute + { + bool FontAttribute::operator==(const FontAttribute& rCompare) const + { + return (getFamilyName() == rCompare.getFamilyName() + && getStyleName() == rCompare.getStyleName() + && getWeight() == rCompare.getWeight() + && getSymbol() == rCompare.getSymbol() + && getVertical() == rCompare.getVertical() + && getItalic() == rCompare.getItalic() + && getOutline() == rCompare.getOutline() + && getRTL() == rCompare.getRTL() + && getBiDiStrong() == rCompare.getBiDiStrong()); + } + } // end of namespace attribute +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/drawinglayer/source/attribute/makefile.mk b/drawinglayer/source/attribute/makefile.mk index fa91224e64b6..65f899f67177 100644 --- a/drawinglayer/source/attribute/makefile.mk +++ b/drawinglayer/source/attribute/makefile.mk @@ -47,6 +47,7 @@ ENABLE_EXCEPTIONS=TRUE SLOFILES= \ $(SLO)$/fillattribute.obj \ $(SLO)$/fillbitmapattribute.obj \ + $(SLO)$/fontattribute.obj \ $(SLO)$/materialattribute3d.obj \ $(SLO)$/sdrallattribute3d.obj \ $(SLO)$/sdrattribute.obj \ diff --git a/drawinglayer/source/attribute/sdrfillbitmapattribute.cxx b/drawinglayer/source/attribute/sdrfillbitmapattribute.cxx index c35d0ba5c15f..d7e9090b0f62 100644 --- a/drawinglayer/source/attribute/sdrfillbitmapattribute.cxx +++ b/drawinglayer/source/attribute/sdrfillbitmapattribute.cxx @@ -228,7 +228,7 @@ namespace drawinglayer aBitmapSize.setY(aBitmapSize.getY() / fRangeHeight); } - return FillBitmapAttribute(aBitmap, aBitmapTopLeft, aBitmapSize, mbTiling); + return FillBitmapAttribute(BitmapEx(aBitmap), aBitmapTopLeft, aBitmapSize, mbTiling); } } // end of namespace attribute } // end of namespace drawinglayer diff --git a/drawinglayer/source/geometry/viewinformation2d.cxx b/drawinglayer/source/geometry/viewinformation2d.cxx index 706684c5f7d8..3a3fd68831db 100644 --- a/drawinglayer/source/geometry/viewinformation2d.cxx +++ b/drawinglayer/source/geometry/viewinformation2d.cxx @@ -157,7 +157,7 @@ namespace drawinglayer mxExtendedInformation[nExtendedInsert++] = rProp; // for performance reasons, also cache content locally - sal_Bool bSalBool = sal_True; + sal_Bool bSalBool(false); rProp.Value >>= bSalBool; mbReducedDisplayQuality = bSalBool; } diff --git a/drawinglayer/source/primitive2d/animatedprimitive2d.cxx b/drawinglayer/source/primitive2d/animatedprimitive2d.cxx index 13f1f699f1ab..df38c627ec9f 100644 --- a/drawinglayer/source/primitive2d/animatedprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/animatedprimitive2d.cxx @@ -52,33 +52,12 @@ namespace drawinglayer { namespace primitive2d { - Primitive2DSequence AnimatedSwitchPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const - { - if(getChildren().hasElements()) - { - const double fState(getAnimationEntry().getStateAtTime(rViewInformation.getViewTime())); - const sal_uInt32 nLen(getChildren().getLength()); - sal_uInt32 nIndex(basegfx::fround(fState * (double)nLen)); - - if(nIndex >= nLen) - { - nIndex = nLen - 1L; - } - - const Primitive2DReference xRef(getChildren()[nIndex], uno::UNO_QUERY_THROW); - return Primitive2DSequence(&xRef, 1L); - } - - return Primitive2DSequence(); - } - AnimatedSwitchPrimitive2D::AnimatedSwitchPrimitive2D( const animation::AnimationEntry& rAnimationEntry, const Primitive2DSequence& rChildren, bool bIsTextAnimation) : GroupPrimitive2D(rChildren), mpAnimationEntry(0), - mfDecomposeViewTime(0.0), mbIsTextAnimation(bIsTextAnimation) { // clone given animation description @@ -105,29 +84,22 @@ namespace drawinglayer Primitive2DSequence AnimatedSwitchPrimitive2D::get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const { - ::osl::MutexGuard aGuard( m_aMutex ); - - if(getLocalDecomposition().hasElements() && mfDecomposeViewTime != rViewInformation.getViewTime()) + if(getChildren().hasElements()) { - // conditions of last local decomposition have changed, delete - const_cast< AnimatedSwitchPrimitive2D* >(this)->setLocalDecomposition(Primitive2DSequence()); - } + const double fState(getAnimationEntry().getStateAtTime(rViewInformation.getViewTime())); + const sal_uInt32 nLen(getChildren().getLength()); + sal_uInt32 nIndex(basegfx::fround(fState * (double)nLen)); - if(!getLocalDecomposition().hasElements()) - { - // remember time - const_cast< AnimatedSwitchPrimitive2D* >(this)->mfDecomposeViewTime = rViewInformation.getViewTime(); - } + if(nIndex >= nLen) + { + nIndex = nLen - 1L; + } - // use parent implementation - return GroupPrimitive2D::get2DDecomposition(rViewInformation); - } + const Primitive2DReference xRef(getChildren()[nIndex], uno::UNO_QUERY_THROW); + return Primitive2DSequence(&xRef, 1L); + } - basegfx::B2DRange AnimatedSwitchPrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const - { - // to get range from decomposition and not from group content, call implementation from - // BasePrimitive2D here - return BasePrimitive2D::getB2DRange(rViewInformation); + return Primitive2DSequence(); } // provide unique ID @@ -142,7 +114,15 @@ namespace drawinglayer { namespace primitive2d { - Primitive2DSequence AnimatedBlinkPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const + AnimatedBlinkPrimitive2D::AnimatedBlinkPrimitive2D( + const animation::AnimationEntry& rAnimationEntry, + const Primitive2DSequence& rChildren, + bool bIsTextAnimation) + : AnimatedSwitchPrimitive2D(rAnimationEntry, rChildren, bIsTextAnimation) + { + } + + Primitive2DSequence AnimatedBlinkPrimitive2D::get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const { if(getChildren().hasElements()) { @@ -157,14 +137,6 @@ namespace drawinglayer return Primitive2DSequence(); } - AnimatedBlinkPrimitive2D::AnimatedBlinkPrimitive2D( - const animation::AnimationEntry& rAnimationEntry, - const Primitive2DSequence& rChildren, - bool bIsTextAnimation) - : AnimatedSwitchPrimitive2D(rAnimationEntry, rChildren, bIsTextAnimation) - { - } - // provide unique ID ImplPrimitrive2DIDBlock(AnimatedBlinkPrimitive2D, PRIMITIVE2D_ID_ANIMATEDBLINKPRIMITIVE2D) @@ -172,41 +144,30 @@ namespace drawinglayer } // end of namespace drawinglayer ////////////////////////////////////////////////////////////////////////////// -// helper class for AnimatedInterpolatePrimitive2D namespace drawinglayer { namespace primitive2d { - BufferedMatrixDecompose::BufferedMatrixDecompose(const basegfx::B2DHomMatrix& rMatrix) - : maB2DHomMatrix(rMatrix), - maScale(0.0, 0.0), - maTranslate(0.0, 0.0), - mfRotate(0.0), - mfShearX(0.0), - mbDecomposed(false) + AnimatedInterpolatePrimitive2D::AnimatedInterpolatePrimitive2D( + const std::vector< basegfx::B2DHomMatrix >& rmMatrixStack, + const animation::AnimationEntry& rAnimationEntry, + const Primitive2DSequence& rChildren, + bool bIsTextAnimation) + : AnimatedSwitchPrimitive2D(rAnimationEntry, rChildren, bIsTextAnimation), + maMatrixStack() { - } + // copy matrices to locally pre-decomposed matrix stack + const sal_uInt32 nCount(rmMatrixStack.size()); + maMatrixStack.reserve(nCount); - void BufferedMatrixDecompose::ensureDecompose() const - { - if(!mbDecomposed) + for(sal_uInt32 a(0L); a < nCount; a++) { - BufferedMatrixDecompose* pThis = const_cast< BufferedMatrixDecompose* >(this); - maB2DHomMatrix.decompose(pThis->maScale, pThis->maTranslate, pThis->mfRotate, pThis->mfShearX); - pThis->mbDecomposed = true; + maMatrixStack.push_back(basegfx::tools::B2DHomMatrixBufferedDecompose(rmMatrixStack[a])); } } - } // end of anonymous namespace -} // end of namespace drawinglayer -////////////////////////////////////////////////////////////////////////////// - -namespace drawinglayer -{ - namespace primitive2d - { - Primitive2DSequence AnimatedInterpolatePrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const + Primitive2DSequence AnimatedInterpolatePrimitive2D::get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const { const sal_uInt32 nSize(maMatrixStack.size()); @@ -227,21 +188,18 @@ namespace drawinglayer const sal_uInt32 nIndA(sal_uInt32(floor(fIndex))); const double fOffset(fIndex - (double)nIndA); basegfx::B2DHomMatrix aTargetTransform; + std::vector< basegfx::tools::B2DHomMatrixBufferedDecompose >::const_iterator aMatA(maMatrixStack.begin() + nIndA); if(basegfx::fTools::equalZero(fOffset)) { // use matrix from nIndA directly - aTargetTransform = maMatrixStack[nIndA].getB2DHomMatrix(); + aTargetTransform = aMatA->getB2DHomMatrix(); } else { - // interpolate. Get involved matrices and ensure they are decomposed + // interpolate. Get involved buffered decomposed matrices const sal_uInt32 nIndB((nIndA + 1L) % nSize); - std::vector< BufferedMatrixDecompose >::const_iterator aMatA(maMatrixStack.begin() + nIndA); - std::vector< BufferedMatrixDecompose >::const_iterator aMatB(maMatrixStack.begin() + nIndB); - - aMatA->ensureDecompose(); - aMatB->ensureDecompose(); + std::vector< basegfx::tools::B2DHomMatrixBufferedDecompose >::const_iterator aMatB(maMatrixStack.begin() + nIndB); // interpolate for fOffset [0.0 .. 1.0[ const basegfx::B2DVector aScale(basegfx::interpolate(aMatA->getScale(), aMatB->getScale(), fOffset)); @@ -250,10 +208,8 @@ namespace drawinglayer const double fShearX(((aMatB->getShearX() - aMatA->getShearX()) * fOffset) + aMatA->getShearX()); // build matrix for state - aTargetTransform.scale(aScale.getX(), aScale.getY()); - aTargetTransform.shearX(fShearX); - aTargetTransform.rotate(fRotate); - aTargetTransform.translate(aTranslate.getX(), aTranslate.getY()); + aTargetTransform = basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix( + aScale, fShearX, fRotate, aTranslate); } // create new transform primitive reference, return new sequence @@ -266,23 +222,6 @@ namespace drawinglayer } } - AnimatedInterpolatePrimitive2D::AnimatedInterpolatePrimitive2D( - const std::vector< basegfx::B2DHomMatrix >& rmMatrixStack, - const animation::AnimationEntry& rAnimationEntry, - const Primitive2DSequence& rChildren, - bool bIsTextAnimation) - : AnimatedSwitchPrimitive2D(rAnimationEntry, rChildren, bIsTextAnimation), - maMatrixStack() - { - // copy matrices - const sal_uInt32 nCount(rmMatrixStack.size()); - - for(sal_uInt32 a(0L); a < nCount; a++) - { - maMatrixStack.push_back(BufferedMatrixDecompose(rmMatrixStack[a])); - } - } - // provide unique ID ImplPrimitrive2DIDBlock(AnimatedInterpolatePrimitive2D, PRIMITIVE2D_ID_ANIMATEDINTERPOLATEPRIMITIVE2D) diff --git a/drawinglayer/source/primitive2d/backgroundcolorprimitive2d.cxx b/drawinglayer/source/primitive2d/backgroundcolorprimitive2d.cxx index cff797451954..d425b1ea3138 100644 --- a/drawinglayer/source/primitive2d/backgroundcolorprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/backgroundcolorprimitive2d.cxx @@ -54,7 +54,7 @@ namespace drawinglayer { namespace primitive2d { - Primitive2DSequence BackgroundColorPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const + Primitive2DSequence BackgroundColorPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const { if(!rViewInformation.getViewport().isEmpty()) { @@ -70,7 +70,7 @@ namespace drawinglayer BackgroundColorPrimitive2D::BackgroundColorPrimitive2D( const basegfx::BColor& rBColor) - : BasePrimitive2D(), + : BufferedDecompositionPrimitive2D(), maBColor(rBColor), maLastViewport() { @@ -78,7 +78,7 @@ namespace drawinglayer bool BackgroundColorPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const { - if(BasePrimitive2D::operator==(rPrimitive)) + if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) { const BackgroundColorPrimitive2D& rCompare = (BackgroundColorPrimitive2D&)rPrimitive; @@ -98,20 +98,20 @@ namespace drawinglayer { ::osl::MutexGuard aGuard( m_aMutex ); - if(getLocalDecomposition().hasElements() && (maLastViewport != rViewInformation.getViewport())) + if(getBuffered2DDecomposition().hasElements() && (maLastViewport != rViewInformation.getViewport())) { // conditions of last local decomposition have changed, delete - const_cast< BackgroundColorPrimitive2D* >(this)->setLocalDecomposition(Primitive2DSequence()); + const_cast< BackgroundColorPrimitive2D* >(this)->setBuffered2DDecomposition(Primitive2DSequence()); } - if(!getLocalDecomposition().hasElements()) + if(!getBuffered2DDecomposition().hasElements()) { // remember ViewRange const_cast< BackgroundColorPrimitive2D* >(this)->maLastViewport = rViewInformation.getViewport(); } // use parent implementation - return BasePrimitive2D::get2DDecomposition(rViewInformation); + return BufferedDecompositionPrimitive2D::get2DDecomposition(rViewInformation); } // provide unique ID diff --git a/drawinglayer/source/primitive2d/baseprimitive2d.cxx b/drawinglayer/source/primitive2d/baseprimitive2d.cxx index 63941512bfb0..dffde631b8c3 100644 --- a/drawinglayer/source/primitive2d/baseprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/baseprimitive2d.cxx @@ -50,20 +50,18 @@ namespace drawinglayer { namespace primitive2d { - Primitive2DSequence BasePrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const + BasePrimitive2D::BasePrimitive2D() + : BasePrimitive2DImplBase(m_aMutex) { - return Primitive2DSequence(); } - BasePrimitive2D::BasePrimitive2D() - : BasePrimitive2DImplBase(m_aMutex), - maLocalDecomposition() + BasePrimitive2D::~BasePrimitive2D() { } bool BasePrimitive2D::operator==( const BasePrimitive2D& rPrimitive ) const { - return (getPrimitiveID() == rPrimitive.getPrimitiveID()); + return (getPrimitive2DID() == rPrimitive.getPrimitive2DID()); } basegfx::B2DRange BasePrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const @@ -71,17 +69,9 @@ namespace drawinglayer return getB2DRangeFromPrimitive2DSequence(get2DDecomposition(rViewInformation), rViewInformation); } - Primitive2DSequence BasePrimitive2D::get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const + Primitive2DSequence BasePrimitive2D::get2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const { - ::osl::MutexGuard aGuard( m_aMutex ); - - if(!getLocalDecomposition().hasElements()) - { - const Primitive2DSequence aNewSequence(createLocalDecomposition(rViewInformation)); - const_cast< BasePrimitive2D* >(this)->setLocalDecomposition(aNewSequence); - } - - return getLocalDecomposition(); + return Primitive2DSequence(); } Primitive2DSequence SAL_CALL BasePrimitive2D::getDecomposition( const uno::Sequence< beans::PropertyValue >& rViewParameters ) throw ( uno::RuntimeException ) @@ -99,6 +89,38 @@ namespace drawinglayer } // end of namespace drawinglayer ////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + Primitive2DSequence BufferedDecompositionPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const + { + return Primitive2DSequence(); + } + + BufferedDecompositionPrimitive2D::BufferedDecompositionPrimitive2D() + : BasePrimitive2D(), + maBuffered2DDecomposition() + { + } + + Primitive2DSequence BufferedDecompositionPrimitive2D::get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const + { + ::osl::MutexGuard aGuard( m_aMutex ); + + if(!getBuffered2DDecomposition().hasElements()) + { + const Primitive2DSequence aNewSequence(create2DDecomposition(rViewInformation)); + const_cast< BufferedDecompositionPrimitive2D* >(this)->setBuffered2DDecomposition(aNewSequence); + } + + return getBuffered2DDecomposition(); + } + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// // tooling namespace drawinglayer diff --git a/drawinglayer/source/primitive2d/bitmapprimitive2d.cxx b/drawinglayer/source/primitive2d/bitmapprimitive2d.cxx index 5900900bcf06..43de0ef3b514 100644 --- a/drawinglayer/source/primitive2d/bitmapprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/bitmapprimitive2d.cxx @@ -65,8 +65,8 @@ namespace drawinglayer { const BitmapPrimitive2D& rCompare = (BitmapPrimitive2D&)rPrimitive; - return (maBitmapEx == rCompare.maBitmapEx - && maTransform == rCompare.maTransform); + return (getBitmapEx() == rCompare.getBitmapEx() + && getTransform() == rCompare.getTransform()); } return false; diff --git a/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx b/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx index ba73f920cb08..1341a22f0d89 100644 --- a/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx @@ -49,7 +49,7 @@ namespace drawinglayer { namespace primitive2d { - Primitive2DSequence BorderLinePrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const + Primitive2DSequence BorderLinePrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const { Primitive2DSequence xRetval; @@ -194,7 +194,7 @@ namespace drawinglayer bool bCreateInside, bool bCreateOutside, const basegfx::BColor& rRGBColor) - : BasePrimitive2D(), + : BufferedDecompositionPrimitive2D(), maStart(rStart), maEnd(rEnd), mfLeftWidth(fLeftWidth), @@ -212,7 +212,7 @@ namespace drawinglayer bool BorderLinePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const { - if(BasePrimitive2D::operator==(rPrimitive)) + if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) { const BorderLinePrimitive2D& rCompare = (BorderLinePrimitive2D&)rPrimitive; diff --git a/drawinglayer/source/primitive2d/controlprimitive2d.cxx b/drawinglayer/source/primitive2d/controlprimitive2d.cxx index 6241eeb2fa73..5d536fa8812f 100644 --- a/drawinglayer/source/primitive2d/controlprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/controlprimitive2d.cxx @@ -54,6 +54,7 @@ #include <svtools/optionsdrawinglayer.hxx> #include <toolkit/awt/vclxwindow.hxx> #include <vcl/window.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> ////////////////////////////////////////////////////////////////////////////// @@ -230,12 +231,8 @@ namespace drawinglayer } // short form for scale and translate transformation - basegfx::B2DHomMatrix aBitmapTransform; - - aBitmapTransform.set(0L, 0L, aBitmapSizeLogic.getX()); - aBitmapTransform.set(1L, 1L, aBitmapSizeLogic.getY()); - aBitmapTransform.set(0L, 2L, aTranslate.getX()); - aBitmapTransform.set(1L, 2L, aTranslate.getY()); + const basegfx::B2DHomMatrix aBitmapTransform(basegfx::tools::createScaleTranslateB2DHomMatrix( + aBitmapSizeLogic.getX(), aBitmapSizeLogic.getY(), aTranslate.getX(), aTranslate.getY())); // create primitive xRetval = new BitmapPrimitive2D(BitmapEx(aContent), aBitmapTransform); @@ -266,7 +263,7 @@ namespace drawinglayer return xRetval; } - Primitive2DSequence ControlPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const + Primitive2DSequence ControlPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const { // try to create a bitmap decomposition. If that fails for some reason, // at least create a replacement decomposition. @@ -283,7 +280,7 @@ namespace drawinglayer ControlPrimitive2D::ControlPrimitive2D( const basegfx::B2DHomMatrix& rTransform, const uno::Reference< awt::XControlModel >& rxControlModel) - : BasePrimitive2D(), + : BufferedDecompositionPrimitive2D(), maTransform(rTransform), mxControlModel(rxControlModel), mxXControl(), @@ -295,7 +292,7 @@ namespace drawinglayer const basegfx::B2DHomMatrix& rTransform, const uno::Reference< awt::XControlModel >& rxControlModel, const uno::Reference< awt::XControl >& rxXControl) - : BasePrimitive2D(), + : BufferedDecompositionPrimitive2D(), maTransform(rTransform), mxControlModel(rxControlModel), mxXControl(rxXControl), @@ -316,7 +313,7 @@ namespace drawinglayer bool ControlPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const { // use base class compare operator - if(BasePrimitive2D::operator==(rPrimitive)) + if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) { const ControlPrimitive2D& rCompare = (ControlPrimitive2D&)rPrimitive; @@ -365,23 +362,23 @@ namespace drawinglayer ::osl::MutexGuard aGuard( m_aMutex ); const basegfx::B2DVector aNewScaling(rViewInformation.getObjectToViewTransformation() * basegfx::B2DVector(1.0, 1.0)); - if(getLocalDecomposition().hasElements()) + if(getBuffered2DDecomposition().hasElements()) { if(!maLastViewScaling.equal(aNewScaling)) { // conditions of last local decomposition have changed, delete - const_cast< ControlPrimitive2D* >(this)->setLocalDecomposition(Primitive2DSequence()); + const_cast< ControlPrimitive2D* >(this)->setBuffered2DDecomposition(Primitive2DSequence()); } } - if(!getLocalDecomposition().hasElements()) + if(!getBuffered2DDecomposition().hasElements()) { // remember ViewTransformation const_cast< ControlPrimitive2D* >(this)->maLastViewScaling = aNewScaling; } // use parent implementation - return BasePrimitive2D::get2DDecomposition(rViewInformation); + return BufferedDecompositionPrimitive2D::get2DDecomposition(rViewInformation); } // provide unique ID diff --git a/drawinglayer/source/primitive2d/discretebitmapprimitive2d.cxx b/drawinglayer/source/primitive2d/discretebitmapprimitive2d.cxx new file mode 100644 index 000000000000..6e3a5b8e516e --- /dev/null +++ b/drawinglayer/source/primitive2d/discretebitmapprimitive2d.cxx @@ -0,0 +1,124 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: bitmapprimitive2d.cxx,v $ + * + * $Revision: 1.5 $ + * + * last change: $Author: aw $ $Date: 2008-05-27 14:11:20 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_drawinglayer.hxx" + +#include <drawinglayer/primitive2d/discretebitmapprimitive2d.hxx> +#include <drawinglayer/primitive2d/bitmapprimitive2d.hxx> +#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + Primitive2DSequence DiscreteBitmapPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const + { + // use getViewTransformation() and getObjectTransformation() from + // ObjectAndViewTransformationDependentPrimitive2D to create a BitmapPrimitive2D + // with the correct mapping + Primitive2DSequence xRetval; + + if(!getBitmapEx().IsEmpty()) + { + // get discrete size + const Size& rSizePixel = getBitmapEx().GetSizePixel(); + const basegfx::B2DVector aDiscreteSize(rSizePixel.Width(), rSizePixel.Height()); + + // get inverse ViewTransformation + basegfx::B2DHomMatrix aInverseViewTransformation(getViewTransformation()); + aInverseViewTransformation.invert(); + + // get size and position in world coordinates + const basegfx::B2DVector aWorldSize(aInverseViewTransformation * aDiscreteSize); + const basegfx::B2DPoint aWorldTopLeft(getObjectTransformation() * getTopLeft()); + + // build object matrix in world coordinates so that the top-left + // position remains, but eventual transformations (e.g. rotations) + // in the ObjectToView stack remain and get correctly applied + basegfx::B2DHomMatrix aObjectTransform; + + aObjectTransform.set(0, 0, aWorldSize.getX()); + aObjectTransform.set(1, 1, aWorldSize.getY()); + aObjectTransform.set(0, 2, aWorldTopLeft.getX()); + aObjectTransform.set(1, 2, aWorldTopLeft.getY()); + + // get inverse ObjectTransformation + basegfx::B2DHomMatrix aInverseObjectTransformation(getObjectTransformation()); + aInverseObjectTransformation.invert(); + + // transform to object coordinate system + aObjectTransform = aInverseObjectTransformation * aObjectTransform; + + // create BitmapPrimitive2D with now object-local coordinate data + const Primitive2DReference xRef(new BitmapPrimitive2D(getBitmapEx(), aObjectTransform)); + xRetval = Primitive2DSequence(&xRef, 1); + } + + return xRetval; + } + + DiscreteBitmapPrimitive2D::DiscreteBitmapPrimitive2D( + const BitmapEx& rBitmapEx, + const basegfx::B2DPoint& rTopLeft) + : ObjectAndViewTransformationDependentPrimitive2D(), + maBitmapEx(rBitmapEx), + maTopLeft(rTopLeft) + { + } + + bool DiscreteBitmapPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const + { + if(ObjectAndViewTransformationDependentPrimitive2D::operator==(rPrimitive)) + { + const DiscreteBitmapPrimitive2D& rCompare = (DiscreteBitmapPrimitive2D&)rPrimitive; + + return (getBitmapEx() == rCompare.getBitmapEx() + && getTopLeft() == rCompare.getTopLeft()); + } + + return false; + } + + // provide unique ID + ImplPrimitrive2DIDBlock(DiscreteBitmapPrimitive2D, PRIMITIVE2D_ID_DISCRETEBITMAPPRIMITIVE2D) + + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/drawinglayer/source/primitive2d/embedded3dprimitive2d.cxx b/drawinglayer/source/primitive2d/embedded3dprimitive2d.cxx index 5805c02a61ed..0c0a863733de 100644 --- a/drawinglayer/source/primitive2d/embedded3dprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/embedded3dprimitive2d.cxx @@ -84,7 +84,7 @@ namespace drawinglayer return maShadowPrimitives.hasElements(); } - Primitive2DSequence Embedded3DPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const + Primitive2DSequence Embedded3DPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const { // use info to create a yellow 2d rectangle, similar to empty 3d scenes and/or groups const basegfx::B2DRange aLocal2DRange(getB2DRange(rViewInformation)); @@ -102,7 +102,7 @@ namespace drawinglayer const basegfx::B3DVector& rLightNormal, double fShadowSlant, const basegfx::B3DRange& rScene3DRange) - : BasePrimitive2D(), + : BufferedDecompositionPrimitive2D(), mxChildren3D(rxChildren3D), maObjectTransformation(rObjectTransformation), maViewInformation3D(rViewInformation3D), @@ -118,7 +118,7 @@ namespace drawinglayer bool Embedded3DPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const { - if(BasePrimitive2D::operator==(rPrimitive)) + if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) { const Embedded3DPrimitive2D& rCompare = static_cast< const Embedded3DPrimitive2D& >(rPrimitive); diff --git a/drawinglayer/source/primitive2d/epsprimitive2d.cxx b/drawinglayer/source/primitive2d/epsprimitive2d.cxx new file mode 100644 index 000000000000..5854e90cfb9f --- /dev/null +++ b/drawinglayer/source/primitive2d/epsprimitive2d.cxx @@ -0,0 +1,111 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: backgroundcolorprimitive2d.cxx,v $ + * + * $Revision: 1.5 $ + * + * last change: $Author: aw $ $Date: 2008-05-27 14:11:20 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_drawinglayer.hxx" + +#include <drawinglayer/primitive2d/epsprimitive2d.hxx> +#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx> +#include <drawinglayer/primitive2d/metafileprimitive2d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + Primitive2DSequence EpsPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const + { + Primitive2DSequence xRetval; + const GDIMetaFile& rSubstituteContent = getMetaFile(); + + if(rSubstituteContent.GetActionCount()) + { + // the default decomposition will use the Metafile replacement visualisation. + // To really use the Eps data, a renderer has to know and interpret this primitive + // directly. + xRetval.realloc(1); + + xRetval[0] = Primitive2DReference( + new MetafilePrimitive2D( + getEpsTransform(), + rSubstituteContent)); + } + + return xRetval; + } + + EpsPrimitive2D::EpsPrimitive2D( + const basegfx::B2DHomMatrix& rEpsTransform, + const GfxLink& rGfxLink, + const GDIMetaFile& rMetaFile) + : BufferedDecompositionPrimitive2D(), + maEpsTransform(rEpsTransform), + maGfxLink(rGfxLink), + maMetaFile(rMetaFile) + { + } + + bool EpsPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const + { + if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) + { + const EpsPrimitive2D& rCompare = (EpsPrimitive2D&)rPrimitive; + + return (getEpsTransform() == rCompare.getEpsTransform() + && getGfxLink().IsEqual(rCompare.getGfxLink()) + && getMetaFile() == rCompare.getMetaFile()); + } + + return false; + } + + basegfx::B2DRange EpsPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const + { + // use own implementation to quickly answer the getB2DRange question. + basegfx::B2DRange aRetval(0.0, 0.0, 1.0, 1.0); + aRetval.transform(getEpsTransform()); + + return aRetval; + } + + // provide unique ID + ImplPrimitrive2DIDBlock(EpsPrimitive2D, PRIMITIVE2D_ID_EPSPRIMITIVE2D) + + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/drawinglayer/source/primitive2d/fillbitmapprimitive2d.cxx b/drawinglayer/source/primitive2d/fillbitmapprimitive2d.cxx index 125c2cb42193..ab9e9d19f6d2 100644 --- a/drawinglayer/source/primitive2d/fillbitmapprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/fillbitmapprimitive2d.cxx @@ -54,9 +54,9 @@ namespace drawinglayer { namespace primitive2d { - Primitive2DSequence FillBitmapPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const + Primitive2DSequence FillBitmapPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const { - const Size aTileSizePixel(getFillBitmap().getBitmap().GetSizePixel()); + const Size aTileSizePixel(getFillBitmap().getBitmapEx().GetSizePixel()); Primitive2DSequence aRetval; // is there a tile with some size at all? @@ -79,7 +79,7 @@ namespace drawinglayer aNewMatrix *= getTransformation(); // create bitmap primitive and add to result - const Primitive2DReference xRef(new BitmapPrimitive2D(BitmapEx(getFillBitmap().getBitmap()), aNewMatrix)); + const Primitive2DReference xRef(new BitmapPrimitive2D(getFillBitmap().getBitmapEx(), aNewMatrix)); aRetval[a] = xRef; } } @@ -94,7 +94,7 @@ namespace drawinglayer aObjectTransform *= getTransformation(); // create bitmap primitive and add exclusive to decomposition (hand over ownership) - const Primitive2DReference xRef(new BitmapPrimitive2D(BitmapEx(getFillBitmap().getBitmap()), aObjectTransform)); + const Primitive2DReference xRef(new BitmapPrimitive2D(getFillBitmap().getBitmapEx(), aObjectTransform)); aRetval = Primitive2DSequence(&xRef, 1L); } } @@ -105,7 +105,7 @@ namespace drawinglayer FillBitmapPrimitive2D::FillBitmapPrimitive2D( const basegfx::B2DHomMatrix& rTransformation, const attribute::FillBitmapAttribute& rFillBitmap) - : BasePrimitive2D(), + : BufferedDecompositionPrimitive2D(), maTransformation(rTransformation), maFillBitmap(rFillBitmap) { @@ -113,7 +113,7 @@ namespace drawinglayer bool FillBitmapPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const { - if(BasePrimitive2D::operator==(rPrimitive)) + if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) { const FillBitmapPrimitive2D& rCompare = static_cast< const FillBitmapPrimitive2D& >(rPrimitive); diff --git a/drawinglayer/source/primitive2d/fillgradientprimitive2d.cxx b/drawinglayer/source/primitive2d/fillgradientprimitive2d.cxx index ff0c031b38a1..625dae6cb93a 100644 --- a/drawinglayer/source/primitive2d/fillgradientprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/fillgradientprimitive2d.cxx @@ -54,37 +54,27 @@ namespace drawinglayer { namespace primitive2d { - Primitive2DSequence FillGradientPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const + void FillGradientPrimitive2D::generateMatricesAndColors( + std::vector< basegfx::B2DHomMatrix >& rMatrices, + std::vector< basegfx::BColor >& rColors) const { - const attribute::GradientStyle aGradientStyle(maFillGradient.getStyle()); - ::std::vector< basegfx::B2DHomMatrix > aMatrices; - ::std::vector< basegfx::BColor > aColors; - basegfx::B2DPolygon aUnitPolygon; - sal_uInt32 nSteps(maFillGradient.getSteps()); - - if(attribute::GRADIENTSTYLE_RADIAL == aGradientStyle || attribute::GRADIENTSTYLE_ELLIPTICAL == aGradientStyle) - { - const basegfx::B2DPoint aCircleCenter(0.5, 0.5); - aUnitPolygon = basegfx::tools::createPolygonFromEllipse(aCircleCenter, 0.5, 0.5); - } - else - { - aUnitPolygon = basegfx::tools::createPolygonFromRect(basegfx::B2DRange(0.0, 0.0, 1.0, 1.0)); - } + rMatrices.clear(); + rColors.clear(); // make sure steps is not too high/low const basegfx::BColor aStart(maFillGradient.getStartColor()); const basegfx::BColor aEnd(maFillGradient.getEndColor()); const sal_uInt32 nMaxSteps(sal_uInt32((aStart.getMaximumDistance(aEnd) * 127.5) + 0.5)); + sal_uInt32 nSteps(maFillGradient.getSteps()); - if(nSteps == 0L) + if(nSteps == 0) { nSteps = nMaxSteps; } - if(nSteps < 2L) + if(nSteps < 2) { - nSteps = 2L; + nSteps = 2; } if(nSteps > nMaxSteps) @@ -92,82 +82,184 @@ namespace drawinglayer nSteps = nMaxSteps; } - switch(aGradientStyle) + switch(maFillGradient.getStyle()) { case attribute::GRADIENTSTYLE_LINEAR: { texture::GeoTexSvxGradientLinear aGradient(getObjectRange(), aStart, aEnd, nSteps, maFillGradient.getBorder(), -maFillGradient.getAngle()); - aGradient.appendTransformations(aMatrices); - aGradient.appendColors(aColors); + aGradient.appendTransformations(rMatrices); + aGradient.appendColors(rColors); break; } case attribute::GRADIENTSTYLE_AXIAL: { texture::GeoTexSvxGradientAxial aGradient(getObjectRange(), aStart, aEnd, nSteps, maFillGradient.getBorder(), -maFillGradient.getAngle()); - aGradient.appendTransformations(aMatrices); - aGradient.appendColors(aColors); + aGradient.appendTransformations(rMatrices); + aGradient.appendColors(rColors); break; } case attribute::GRADIENTSTYLE_RADIAL: { texture::GeoTexSvxGradientRadial aGradient(getObjectRange(), aStart, aEnd, nSteps, maFillGradient.getBorder(), maFillGradient.getOffsetX(), maFillGradient.getOffsetY()); - aGradient.appendTransformations(aMatrices); - aGradient.appendColors(aColors); + aGradient.appendTransformations(rMatrices); + aGradient.appendColors(rColors); break; } case attribute::GRADIENTSTYLE_ELLIPTICAL: { texture::GeoTexSvxGradientElliptical aGradient(getObjectRange(), aStart, aEnd, nSteps, maFillGradient.getBorder(), maFillGradient.getOffsetX(), maFillGradient.getOffsetY(), -maFillGradient.getAngle()); - aGradient.appendTransformations(aMatrices); - aGradient.appendColors(aColors); + aGradient.appendTransformations(rMatrices); + aGradient.appendColors(rColors); break; } case attribute::GRADIENTSTYLE_SQUARE: { texture::GeoTexSvxGradientSquare aGradient(getObjectRange(), aStart, aEnd, nSteps, maFillGradient.getBorder(), maFillGradient.getOffsetX(), maFillGradient.getOffsetY(), -maFillGradient.getAngle()); - aGradient.appendTransformations(aMatrices); - aGradient.appendColors(aColors); + aGradient.appendTransformations(rMatrices); + aGradient.appendColors(rColors); break; } case attribute::GRADIENTSTYLE_RECT: { texture::GeoTexSvxGradientRect aGradient(getObjectRange(), aStart, aEnd, nSteps, maFillGradient.getBorder(), maFillGradient.getOffsetX(), maFillGradient.getOffsetY(), -maFillGradient.getAngle()); - aGradient.appendTransformations(aMatrices); - aGradient.appendColors(aColors); + aGradient.appendTransformations(rMatrices); + aGradient.appendColors(rColors); break; } } + } + Primitive2DSequence FillGradientPrimitive2D::createOverlappingFill( + const std::vector< basegfx::B2DHomMatrix >& rMatrices, + const std::vector< basegfx::BColor >& rColors, + const basegfx::B2DPolygon& rUnitPolygon) const + { // prepare return value - Primitive2DSequence aRetval(aColors.size() ? aMatrices.size() + 1L : aMatrices.size()); + Primitive2DSequence aRetval(rColors.size() ? rMatrices.size() + 1 : rMatrices.size()); // create solid fill with start color - if(aColors.size()) + if(rColors.size()) { // create primitive - const Primitive2DReference xRef(new PolyPolygonColorPrimitive2D(basegfx::B2DPolyPolygon(basegfx::tools::createPolygonFromRect(getObjectRange())), aColors[0L])); - aRetval[0L] = xRef; + const Primitive2DReference xRef( + new PolyPolygonColorPrimitive2D( + basegfx::B2DPolyPolygon(basegfx::tools::createPolygonFromRect(getObjectRange())), + rColors[0])); + aRetval[0] = xRef; } // create solid fill steps - for(sal_uInt32 a(0L); a < aMatrices.size(); a++) + for(sal_uInt32 a(0); a < rMatrices.size(); a++) { // create part polygon - basegfx::B2DPolygon aNewPoly(aUnitPolygon); - aNewPoly.transform(aMatrices[a]); + basegfx::B2DPolygon aNewPoly(rUnitPolygon); + aNewPoly.transform(rMatrices[a]); // create solid fill - const Primitive2DReference xRef(new PolyPolygonColorPrimitive2D(basegfx::B2DPolyPolygon(aNewPoly), aColors[a + 1L])); - aRetval[a + 1L] = xRef; + const Primitive2DReference xRef( + new PolyPolygonColorPrimitive2D( + basegfx::B2DPolyPolygon(aNewPoly), + rColors[a + 1])); + aRetval[a + 1] = xRef; + } + + return aRetval; + } + + Primitive2DSequence FillGradientPrimitive2D::createNonOverlappingFill( + const std::vector< basegfx::B2DHomMatrix >& rMatrices, + const std::vector< basegfx::BColor >& rColors, + const basegfx::B2DPolygon& rUnitPolygon) const + { + // prepare return value + Primitive2DSequence aRetval; + const sal_uInt32 nMatricesSize(rMatrices.size()); + + if(nMatricesSize) + { + basegfx::B2DPolygon aOuterPoly(rUnitPolygon); + aOuterPoly.transform(rMatrices[0]); + basegfx::B2DPolyPolygon aCombinedPolyPoly(aOuterPoly); + const sal_uInt32 nEntryCount(rColors.size() ? rMatrices.size() + 1 : rMatrices.size()); + sal_uInt32 nIndex(0); + + aRetval.realloc(nEntryCount); + + if(rColors.size()) + { + basegfx::B2DRange aOuterPolyRange(aOuterPoly.getB2DRange()); + aOuterPolyRange.expand(getObjectRange()); + aCombinedPolyPoly.append(basegfx::tools::createPolygonFromRect(aOuterPolyRange)); + aRetval[nIndex++] = Primitive2DReference(new PolyPolygonColorPrimitive2D(aCombinedPolyPoly, rColors[0])); + aCombinedPolyPoly = basegfx::B2DPolyPolygon(aOuterPoly); + } + + for(sal_uInt32 a(1); a < nMatricesSize - 1; a++) + { + basegfx::B2DPolygon aInnerPoly(rUnitPolygon); + aInnerPoly.transform(rMatrices[a]); + aCombinedPolyPoly.append(aInnerPoly); + aRetval[nIndex++] = Primitive2DReference(new PolyPolygonColorPrimitive2D(aCombinedPolyPoly, rColors[a])); + aCombinedPolyPoly = basegfx::B2DPolyPolygon(aInnerPoly); + } + + if(rColors.size()) + { + aRetval[nIndex] = Primitive2DReference(new PolyPolygonColorPrimitive2D( + aCombinedPolyPoly, rColors[rColors.size() - 1])); + } } return aRetval; } + Primitive2DSequence FillGradientPrimitive2D::createFill(bool bOverlapping) const + { + // prepare shape of the Unit Polygon + basegfx::B2DPolygon aUnitPolygon; + + if(attribute::GRADIENTSTYLE_RADIAL == maFillGradient.getStyle() + || attribute::GRADIENTSTYLE_ELLIPTICAL == maFillGradient.getStyle()) + { + const basegfx::B2DPoint aCircleCenter(0.5, 0.5); + aUnitPolygon = basegfx::tools::createPolygonFromEllipse(aCircleCenter, 0.5, 0.5); + } + else + { + aUnitPolygon = basegfx::tools::createPolygonFromRect(basegfx::B2DRange(0.0, 0.0, 1.0, 1.0)); + } + + // get the transform matrices and colors (where colors + // will have one more entry that matrices) + std::vector< basegfx::B2DHomMatrix > aMatrices; + std::vector< basegfx::BColor > aColors; + generateMatricesAndColors(aMatrices, aColors); + + if(bOverlapping) + { + return createOverlappingFill(aMatrices, aColors, aUnitPolygon); + } + else + { + return createNonOverlappingFill(aMatrices, aColors, aUnitPolygon); + } + } + + Primitive2DSequence FillGradientPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const + { + // default creates overlapping fill which works with AntiAliasing and without. + // The non-overlapping version does not create single filled polygons, but + // PolyPolygons where each one describes a 'ring' for the gradient such + // that the rings will not overlap. This is useful fir the old XOR-paint + // 'trick' of VCL which is recorded in Metafiles; so this version may be + // used from the MetafilePrimitive2D in it's decomposition. + return createFill(true); + } + FillGradientPrimitive2D::FillGradientPrimitive2D( const basegfx::B2DRange& rObjectRange, const attribute::FillGradientAttribute& rFillGradient) - : BasePrimitive2D(), + : BufferedDecompositionPrimitive2D(), maObjectRange(rObjectRange), maFillGradient(rFillGradient) { @@ -175,7 +267,7 @@ namespace drawinglayer bool FillGradientPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const { - if(BasePrimitive2D::operator==(rPrimitive)) + if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) { const FillGradientPrimitive2D& rCompare = (FillGradientPrimitive2D&)rPrimitive; diff --git a/drawinglayer/source/primitive2d/fillhatchprimitive2d.cxx b/drawinglayer/source/primitive2d/fillhatchprimitive2d.cxx index 06d04111686d..9e6e69516d43 100644 --- a/drawinglayer/source/primitive2d/fillhatchprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/fillhatchprimitive2d.cxx @@ -55,7 +55,7 @@ namespace drawinglayer { namespace primitive2d { - Primitive2DSequence FillHatchPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const + Primitive2DSequence FillHatchPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const { // create hatch const basegfx::BColor aHatchColor(maFillHatch.getColor()); @@ -125,7 +125,7 @@ namespace drawinglayer const basegfx::B2DRange& rObjectRange, const basegfx::BColor& rBColor, const attribute::FillHatchAttribute& rFillHatch) - : BasePrimitive2D(), + : BufferedDecompositionPrimitive2D(), maObjectRange(rObjectRange), maFillHatch(rFillHatch), maBColor(rBColor) @@ -134,7 +134,7 @@ namespace drawinglayer bool FillHatchPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const { - if(BasePrimitive2D::operator==(rPrimitive)) + if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) { const FillHatchPrimitive2D& rCompare = (FillHatchPrimitive2D&)rPrimitive; diff --git a/drawinglayer/source/primitive2d/graphicprimitive2d.cxx b/drawinglayer/source/primitive2d/graphicprimitive2d.cxx index 1ed826dab562..6d1540594dc9 100644 --- a/drawinglayer/source/primitive2d/graphicprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/graphicprimitive2d.cxx @@ -56,6 +56,18 @@ #include <vcl/svapp.hxx> ////////////////////////////////////////////////////////////////////////////// +// includes for testing MetafilePrimitive2D::create2DDecomposition + +// this switch defines if the test code is included or not +#undef USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE + +#ifdef USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE +#include <vcl/gradient.hxx> +#include <vcl/pngread.hxx> +#include <vcl/lineinfo.hxx> +#endif // USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE + +////////////////////////////////////////////////////////////////////////////// namespace { @@ -211,19 +223,52 @@ namespace drawinglayer { namespace primitive2d { - Primitive2DSequence GraphicPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const + Primitive2DSequence GraphicPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& +#ifdef USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE + rViewInformation +#else + /*rViewInformation*/ +#endif // USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE + ) const { Primitive2DSequence aRetval; if(255L != getGraphicAttr().GetTransparency()) { - // get transformed graphic. Suppress rotation and cropping, only filtering is needed - // here (and may be replaced later on). Cropping is handled below as mask primitive (if set) + 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, + // but this implementation never worked. I reworked that implementations, + // but for security reasons i will try not to use it. + basegfx::B2DHomMatrix aTransform(getTransform()); + + if(getGraphicAttr().IsMirrored()) + { + // content needs mirroring + const bool bHMirr(getGraphicAttr().GetMirrorFlags() & BMP_MIRROR_HORZ); + const bool bVMirr(getGraphicAttr().GetMirrorFlags() & BMP_MIRROR_VERT); + + // mirror by applying negative scale to the unit primitive and + // applying the object transformation on it. + aTransform = basegfx::tools::createScaleB2DHomMatrix( + bHMirr ? -1.0 : 1.0, + bVMirr ? -1.0 : 1.0); + aTransform.translate( + bHMirr ? 1.0 : 0.0, + bVMirr ? 1.0 : 0.0); + aTransform = getTransform() * aTransform; + } + + // Get transformed graphic. Suppress rotation and cropping, only filtering is needed + // here (and may be replaced later on). Cropping is handled below as mask primitive (if set). + // Also need to suppress mirroring, it is part of the transformation now (see above). GraphicAttr aSuppressGraphicAttr(getGraphicAttr()); - aSuppressGraphicAttr.SetCrop(0L, 0L, 0L, 0L); + aSuppressGraphicAttr.SetCrop(0, 0, 0, 0); aSuppressGraphicAttr.SetRotation(0); - Graphic aTransformedGraphic(getGraphicObject().GetTransformedGraphic(&aSuppressGraphicAttr)); - Primitive2DReference xPrimitive; + aSuppressGraphicAttr.SetMirrorFlags(0); + const Graphic aTransformedGraphic(getGraphicObject().GetTransformedGraphic(&aSuppressGraphicAttr)); switch(aTransformedGraphic.GetType()) { @@ -244,7 +289,7 @@ namespace drawinglayer { animation::AnimationEntryFixed aTime((double)aData.stepTime(a), (double)a / (double)aData.count()); aAnimationLoop.append(aTime); - const Primitive2DReference xRef(new BitmapPrimitive2D(aData.stepBitmapEx(a), getTransform())); + const Primitive2DReference xRef(new BitmapPrimitive2D(aData.stepBitmapEx(a), aTransform)); aBitmapPrimitives[a] = xRef; } @@ -258,7 +303,7 @@ namespace drawinglayer } else { - xPrimitive = Primitive2DReference(new BitmapPrimitive2D(aTransformedGraphic.GetBitmapEx(), getTransform())); + xPrimitive = Primitive2DReference(new BitmapPrimitive2D(aTransformedGraphic.GetBitmapEx(), aTransform)); } break; @@ -266,37 +311,480 @@ namespace drawinglayer case GRAPHIC_GDIMETAFILE : { - // create MetafilePrimitive2D - const GDIMetaFile& rMetafile = aTransformedGraphic.GetGDIMetaFile(); - - xPrimitive = Primitive2DReference( - new MetafilePrimitive2D( - getTransform(), - 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()) +#ifdef USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE + static bool bDoTest(false); + + if(bDoTest) { - // clipping needed. Embed to MaskPrimitive2D. Create childs and mask polygon - const primitive2d::Primitive2DSequence aChildContent(&xPrimitive, 1); - basegfx::B2DPolygon aMaskPolygon( - basegfx::tools::createPolygonFromRect( - basegfx::B2DRange(0.0, 0.0, 1.0, 1.0))); - aMaskPolygon.transform(getTransform()); + // All this is/was test code for testing MetafilePrimitive2D::create2DDecomposition + // extensively. It may be needed again when diverse actions need debugging, so i leave + // it in here, but take it out using USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE. + // Use it by compiling with the code, insert any DrawObject, convert to Metafile. The + // debugger will then stop here (when breakpoint set, of course). You may enter single + // parts of actions and/or change to true what You want to check. + GDIMetaFile aMtf; + VirtualDevice aOut; + const basegfx::B2DRange aRange(getB2DRange(rViewInformation)); + const Rectangle aRectangle( + basegfx::fround(aRange.getMinX()), basegfx::fround(aRange.getMinY()), + basegfx::fround(aRange.getMaxX()), basegfx::fround(aRange.getMaxY())); + const Point aOrigin(aRectangle.TopLeft()); + const Fraction aScaleX(aRectangle.getWidth()); + const Fraction aScaleY(aRectangle.getHeight()); + MapMode aMapMode(MAP_100TH_MM, aOrigin, aScaleX, aScaleY); + + Size aDummySize(2, 2); + aOut.SetOutputSizePixel(aDummySize); + aOut.EnableOutput(FALSE); + aOut.SetMapMode(aMapMode); + + aMtf.Clear(); + aMtf.Record(&aOut); + + const Fraction aNeutralFraction(1, 1); + const MapMode aRelativeMapMode( + MAP_RELATIVE, + Point(-aRectangle.Left(), -aRectangle.Top()), + aNeutralFraction, aNeutralFraction); + aOut.SetMapMode(aRelativeMapMode); + + if(false) + { + const sal_Int32 nHor(aRectangle.getWidth() / 4); + const sal_Int32 nVer(aRectangle.getHeight() / 4); + const Rectangle aCenteredRectangle( + aRectangle.Left() + nHor, aRectangle.Top() + nVer, + aRectangle.Right() - nHor, aRectangle.Bottom() - nVer); + aOut.SetClipRegion(aCenteredRectangle); + } + + if(false) + { + const Rectangle aRightRectangle(aRectangle.TopCenter(), aRectangle.BottomRight()); + aOut.IntersectClipRegion(aRightRectangle); + } + + if(false) + { + const Rectangle aRightRectangle(aRectangle.TopCenter(), aRectangle.BottomRight()); + const Rectangle aBottomRectangle(aRectangle.LeftCenter(), aRectangle.BottomRight()); + Region aRegion(aRightRectangle); + aRegion.Intersect(aBottomRectangle); + aOut.IntersectClipRegion(aRegion); + } + + if(false) + { + const sal_Int32 nHor(aRectangle.getWidth() / 10); + const sal_Int32 nVer(aRectangle.getHeight() / 10); + aOut.MoveClipRegion(nHor, nVer); + } + + if(false) + { + Wallpaper aWallpaper(Color(COL_BLACK)); + aOut.DrawWallpaper(aRectangle, aWallpaper); + } + + if(false) + { + Wallpaper aWallpaper(Gradient(GRADIENT_LINEAR, Color(COL_RED), Color(COL_GREEN))); + aOut.DrawWallpaper(aRectangle, aWallpaper); + } + + if(false) + { + SvFileStream aRead((const String&)String(ByteString( "c:\\test.png" ), RTL_TEXTENCODING_UTF8), STREAM_READ); + vcl::PNGReader aPNGReader(aRead); + BitmapEx aBitmapEx(aPNGReader.Read()); + Wallpaper aWallpaper(aBitmapEx); + aOut.DrawWallpaper(aRectangle, aWallpaper); + } + + if(false) + { + const double fHor(aRectangle.getWidth()); + const double fVer(aRectangle.getHeight()); + Color aColor(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)); + + for(sal_uInt32 a(0); a < 5000; a++) + { + const Point aPoint( + aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)), + aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0))); + + if(!(a % 3)) + { + aColor = Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)); + } + + aOut.DrawPixel(aPoint, aColor); + } + } + + if(false) + { + const double fHor(aRectangle.getWidth()); + const double fVer(aRectangle.getHeight()); + + aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); + aOut.SetFillColor(); + + for(sal_uInt32 a(0); a < 5000; a++) + { + const Point aPoint( + aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)), + aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0))); + aOut.DrawPixel(aPoint); + } + } + + if(false) + { + const double fHor(aRectangle.getWidth()); + const double fVer(aRectangle.getHeight()); + + aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); + aOut.SetFillColor(); + + Point aStart( + aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)), + aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0))); + Point aStop( + aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)), + aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0))); + + LineInfo aLineInfo(LINE_SOLID, basegfx::fround(fHor / 50.0)); + bool bUseLineInfo(false); + + for(sal_uInt32 a(0); a < 20; a++) + { + if(!(a%6)) + { + bUseLineInfo = !bUseLineInfo; + } + + if(!(a%4)) + { + aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); + } + + if(a%3) + { + aStart = aStop; + aStop = Point( + aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)), + aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0))); + } + else + { + aStart = Point( + aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)), + aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0))); + aStop = Point( + aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)), + aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0))); + } + + if(bUseLineInfo) + { + aOut.DrawLine(aStart, aStop, aLineInfo); + } + else + { + aOut.DrawLine(aStart, aStop); + } + } + } + + if(false) + { + aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); + aOut.SetFillColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); + aOut.DrawRect(aRectangle); + } + + if(false) + { + aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); + aOut.SetFillColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); + const sal_uInt32 nHor(aRectangle.getWidth() / 10); + const sal_uInt32 nVer(aRectangle.getHeight() / 10); + aOut.DrawRect(aRectangle, nHor, nVer); + } + + if(false) + { + aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); + aOut.SetFillColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); + aOut.DrawEllipse(aRectangle); + } + + if(false) + { + aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); + aOut.SetFillColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); + aOut.DrawArc(aRectangle, aRectangle.TopLeft(), aRectangle.BottomCenter()); + } + + if(false) + { + aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); + aOut.SetFillColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); + aOut.DrawPie(aRectangle, aRectangle.TopLeft(), aRectangle.BottomCenter()); + } + + if(false) + { + aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); + aOut.SetFillColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); + aOut.DrawChord(aRectangle, aRectangle.TopLeft(), aRectangle.BottomCenter()); + } + + if(false) + { + const double fHor(aRectangle.getWidth()); + const double fVer(aRectangle.getHeight()); + + for(sal_uInt32 b(0); b < 5; b++) + { + const sal_uInt32 nCount(basegfx::fround(rand() * (20 / 32767.0))); + const bool bClose(basegfx::fround(rand() / 32767.0)); + Polygon aPolygon(nCount + (bClose ? 1 : 0)); + + for(sal_uInt32 a(0); a < nCount; a++) + { + const Point aPoint( + aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)), + aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0))); + aPolygon[a] = aPoint; + } + + if(bClose) + { + aPolygon[aPolygon.GetSize() - 1] = aPolygon[0]; + } + + aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); + aOut.SetFillColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); + + if(!(b%2)) + { + const LineInfo aLineInfo(LINE_SOLID, basegfx::fround(fHor / 50.0)); + aOut.DrawPolyLine(aPolygon, aLineInfo); + } + else + { + aOut.DrawPolyLine(aPolygon); + } + } + } + + if(false) + { + const double fHor(aRectangle.getWidth()); + const double fVer(aRectangle.getHeight()); + + for(sal_uInt32 b(0); b < 5; b++) + { + const sal_uInt32 nCount(basegfx::fround(rand() * (20 / 32767.0))); + const bool bClose(basegfx::fround(rand() / 32767.0)); + Polygon aPolygon(nCount + (bClose ? 1 : 0)); + + for(sal_uInt32 a(0); a < nCount; a++) + { + const Point aPoint( + aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)), + aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0))); + aPolygon[a] = aPoint; + } + + if(bClose) + { + aPolygon[aPolygon.GetSize() - 1] = aPolygon[0]; + } + + aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); + aOut.SetFillColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); + aOut.DrawPolygon(aPolygon); + } + } + + if(false) + { + const double fHor(aRectangle.getWidth()); + const double fVer(aRectangle.getHeight()); + PolyPolygon aPolyPolygon; + + for(sal_uInt32 b(0); b < 3; b++) + { + const sal_uInt32 nCount(basegfx::fround(rand() * (6 / 32767.0))); + const bool bClose(basegfx::fround(rand() / 32767.0)); + Polygon aPolygon(nCount + (bClose ? 1 : 0)); + + for(sal_uInt32 a(0); a < nCount; a++) + { + const Point aPoint( + aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)), + aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0))); + aPolygon[a] = aPoint; + } + + if(bClose) + { + aPolygon[aPolygon.GetSize() - 1] = aPolygon[0]; + } + + aPolyPolygon.Insert(aPolygon); + } + + aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); + aOut.SetFillColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); + aOut.DrawPolyPolygon(aPolyPolygon); + } + + if(false) + { + SvFileStream aRead((const String&)String(ByteString( "c:\\test.png" ), RTL_TEXTENCODING_UTF8), STREAM_READ); + vcl::PNGReader aPNGReader(aRead); + BitmapEx aBitmapEx(aPNGReader.Read()); + aOut.DrawBitmapEx(aRectangle.TopLeft(), aBitmapEx); + } + + if(false) + { + SvFileStream aRead((const String&)String(ByteString( "c:\\test.png" ), RTL_TEXTENCODING_UTF8), STREAM_READ); + vcl::PNGReader aPNGReader(aRead); + BitmapEx aBitmapEx(aPNGReader.Read()); + aOut.DrawBitmapEx(aRectangle.TopLeft(), aRectangle.GetSize(), aBitmapEx); + } + + if(false) + { + SvFileStream aRead((const String&)String(ByteString( "c:\\test.png" ), RTL_TEXTENCODING_UTF8), STREAM_READ); + vcl::PNGReader aPNGReader(aRead); + BitmapEx aBitmapEx(aPNGReader.Read()); + const Size aSizePixel(aBitmapEx.GetSizePixel()); + aOut.DrawBitmapEx( + aRectangle.TopLeft(), + aRectangle.GetSize(), + Point(0, 0), + Size(aSizePixel.Width() /2, aSizePixel.Height() / 2), + aBitmapEx); + } + + if(false) + { + const double fHor(aRectangle.getWidth()); + const double fVer(aRectangle.getHeight()); + const Point aPointA( + aRectangle.Left() + basegfx::fround(fHor * 0.2), + aRectangle.Top() + basegfx::fround(fVer * 0.3)); + const Point aPointB( + aRectangle.Left() + basegfx::fround(fHor * 0.2), + aRectangle.Top() + basegfx::fround(fVer * 0.5)); + const Point aPointC( + aRectangle.Left() + basegfx::fround(fHor * 0.2), + aRectangle.Top() + basegfx::fround(fVer * 0.7)); + const String aText(ByteString("Hello, World!"), RTL_TEXTENCODING_UTF8); + + const String aFontName(ByteString("Comic Sans MS"), RTL_TEXTENCODING_UTF8); + Font aFont(aFontName, Size(0, 1000)); + aFont.SetAlign(ALIGN_BASELINE); + aFont.SetColor(COL_RED); + //sal_Int32* pDXArray = new sal_Int32[aText.Len()]; + + aFont.SetOutline(true); + aOut.SetFont(aFont); + aOut.DrawText(aPointA, aText, 0, aText.Len()); + + aFont.SetShadow(true); + aOut.SetFont(aFont); + aOut.DrawText(aPointB, aText, 0, aText.Len()); + + aFont.SetRelief(RELIEF_EMBOSSED); + aOut.SetFont(aFont); + aOut.DrawText(aPointC, aText, 0, aText.Len()); + + //delete pDXArray; + } + + if(false) + { + const double fHor(aRectangle.getWidth()); + const double fVer(aRectangle.getHeight()); + const Point aPointA( + aRectangle.Left() + basegfx::fround(fHor * 0.2), + aRectangle.Top() + basegfx::fround(fVer * 0.3)); + const Point aPointB( + aRectangle.Left() + basegfx::fround(fHor * 0.2), + aRectangle.Top() + basegfx::fround(fVer * 0.5)); + const Point aPointC( + aRectangle.Left() + basegfx::fround(fHor * 0.2), + aRectangle.Top() + basegfx::fround(fVer * 0.7)); + const String aText(ByteString("Hello, World!"), RTL_TEXTENCODING_UTF8); + + const String aFontName(ByteString("Comic Sans MS"), RTL_TEXTENCODING_UTF8); + Font aFont(aFontName, Size(0, 1000)); + aFont.SetAlign(ALIGN_BASELINE); + aFont.SetColor(COL_RED); + + aOut.SetFont(aFont); + const sal_Int32 nWidth(aOut.GetTextWidth(aText, 0, aText.Len())); + aOut.DrawText(aPointA, aText, 0, aText.Len()); + aOut.DrawTextLine(aPointA, nWidth, STRIKEOUT_SINGLE, UNDERLINE_SINGLE, UNDERLINE_SMALLWAVE); + aOut.DrawTextLine(aPointB, nWidth, STRIKEOUT_SINGLE, UNDERLINE_SINGLE, UNDERLINE_SMALLWAVE); + aOut.DrawTextLine(aPointC, nWidth, STRIKEOUT_SINGLE, UNDERLINE_SINGLE, UNDERLINE_SMALLWAVE); + } + + aMtf.Stop(); + aMtf.WindStart(); + aMtf.SetPrefMapMode(MapMode(MAP_100TH_MM)); + aMtf.SetPrefSize(Size(aRectangle.getWidth(), aRectangle.getHeight())); + + xPrimitive = Primitive2DReference( + new MetafilePrimitive2D( + aTransform, + aMtf)); + } + else + { +#endif // USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE + // create MetafilePrimitive2D + const Graphic aGraphic(getGraphicObject().GetGraphic()); + const GDIMetaFile& rMetafile = aTransformedGraphic.GetGDIMetaFile(); xPrimitive = Primitive2DReference( - new MaskPrimitive2D( - basegfx::B2DPolyPolygon(aMaskPolygon), - aChildContent)); + 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::createPolygonFromRect( + basegfx::B2DRange(0.0, 0.0, 1.0, 1.0))); + aMaskPolygon.transform(aTransform); + + xPrimitive = Primitive2DReference( + new MaskPrimitive2D( + basegfx::B2DPolyPolygon(aMaskPolygon), + aChildContent)); + } +#ifdef USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE } +#endif // USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE break; } @@ -319,7 +807,9 @@ namespace drawinglayer getTransform().decompose(aScale, aTranslate, fRotate, fShearX); // create ranges. The current object range is just scale and translate - const basegfx::B2DRange aCurrent(aTranslate.getX(), aTranslate.getY(), aTranslate.getX() + aScale.getX(), aTranslate.getY() + aScale.getY()); + const basegfx::B2DRange aCurrent( + aTranslate.getX(), aTranslate.getY(), + aTranslate.getX() + aScale.getX(), aTranslate.getY() + aScale.getY()); // calculate scalings between real image size and logic object size. This // is necessary since the crop values are relative to original bitmap size @@ -369,11 +859,15 @@ namespace drawinglayer // build new object transformation for transform primitive which contains xPrimitive basegfx::B2DHomMatrix aNewObjectTransform(getTransform()); aNewObjectTransform.invert(); - aNewObjectTransform.scale(aCropped.getWidth(), aCropped.getHeight()); - aNewObjectTransform.translate(aCropped.getMinX() - aCurrent.getMinX(), aCropped.getMinY() - aCurrent.getMinY()); - aNewObjectTransform.shearX(fShearX); - aNewObjectTransform.rotate(fRotate); - aNewObjectTransform.translate(aTranslate.getX(), aTranslate.getY()); + aNewObjectTransform = basegfx::tools::createScaleTranslateB2DHomMatrix( + aCropped.getWidth(), aCropped.getHeight(), + aCropped.getMinX() - aCurrent.getMinX(), aCropped.getMinY() - aCurrent.getMinY()) + * aNewObjectTransform; + + // add shear, rotate and translate using combined matrix to speedup + const basegfx::B2DHomMatrix aCombinedMatrix(basegfx::tools::createShearXRotateTranslateB2DHomMatrix( + fShearX, fRotate, aTranslate.getX(), aTranslate.getY())); + aNewObjectTransform = aCombinedMatrix * aNewObjectTransform; // prepare TransformPrimitive2D with xPrimitive const Primitive2DReference xTransformPrimitive(new TransformPrimitive2D(aNewObjectTransform, Primitive2DSequence(&xPrimitive, 1L))); @@ -410,7 +904,7 @@ namespace drawinglayer const basegfx::B2DHomMatrix& rTransform, const GraphicObject& rGraphicObject, const GraphicAttr& rGraphicAttr) - : BasePrimitive2D(), + : BufferedDecompositionPrimitive2D(), maTransform(rTransform), maGraphicObject(rGraphicObject), maGraphicAttr(rGraphicAttr) @@ -420,7 +914,7 @@ namespace drawinglayer GraphicPrimitive2D::GraphicPrimitive2D( const basegfx::B2DHomMatrix& rTransform, const GraphicObject& rGraphicObject) - : BasePrimitive2D(), + : BufferedDecompositionPrimitive2D(), maTransform(rTransform), maGraphicObject(rGraphicObject), maGraphicAttr() @@ -429,7 +923,7 @@ namespace drawinglayer bool GraphicPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const { - if(BasePrimitive2D::operator==(rPrimitive)) + if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) { const GraphicPrimitive2D& rCompare = (GraphicPrimitive2D&)rPrimitive; diff --git a/drawinglayer/source/primitive2d/gridprimitive2d.cxx b/drawinglayer/source/primitive2d/gridprimitive2d.cxx index df4171309389..d2bd4b9d5243 100644 --- a/drawinglayer/source/primitive2d/gridprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/gridprimitive2d.cxx @@ -42,6 +42,7 @@ #include <drawinglayer/primitive2d/markerarrayprimitive2d.hxx> #include <drawinglayer/geometry/viewinformation2d.hxx> #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> ////////////////////////////////////////////////////////////////////////////// @@ -53,7 +54,7 @@ namespace drawinglayer { namespace primitive2d { - Primitive2DSequence GridPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const + Primitive2DSequence GridPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const { Primitive2DSequence aRetval; @@ -65,10 +66,8 @@ namespace drawinglayer getTransform().decompose(aScale, aTranslate, fRotate, fShearX); // create grid matrix which transforms from scaled logic to view - basegfx::B2DHomMatrix aRST; - aRST.shearX(fShearX); - aRST.rotate(fRotate); - aRST.translate(aTranslate.getX(), aTranslate.getY()); + basegfx::B2DHomMatrix aRST(basegfx::tools::createShearXRotateTranslateB2DHomMatrix( + fShearX, fRotate, aTranslate.getX(), aTranslate.getY())); aRST *= rViewInformation.getObjectToViewTransformation(); // get step widths @@ -248,7 +247,7 @@ namespace drawinglayer sal_uInt32 nSubdivisionsY, const basegfx::BColor& rBColor, const BitmapEx& rCrossMarker) - : BasePrimitive2D(), + : BufferedDecompositionPrimitive2D(), maTransform(rTransform), mfWidth(fWidth), mfHeight(fHeight), @@ -265,7 +264,7 @@ namespace drawinglayer bool GridPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const { - if(BasePrimitive2D::operator==(rPrimitive)) + if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) { const GridPrimitive2D& rCompare = (GridPrimitive2D&)rPrimitive; @@ -299,16 +298,16 @@ namespace drawinglayer { ::osl::MutexGuard aGuard( m_aMutex ); - if(getLocalDecomposition().hasElements()) + if(getBuffered2DDecomposition().hasElements()) { if(maLastViewport != rViewInformation.getViewport() || maLastObjectToViewTransformation != rViewInformation.getObjectToViewTransformation()) { // conditions of last local decomposition have changed, delete - const_cast< GridPrimitive2D* >(this)->setLocalDecomposition(Primitive2DSequence()); + const_cast< GridPrimitive2D* >(this)->setBuffered2DDecomposition(Primitive2DSequence()); } } - if(!getLocalDecomposition().hasElements()) + if(!getBuffered2DDecomposition().hasElements()) { // remember ViewRange and ViewTransformation const_cast< GridPrimitive2D* >(this)->maLastObjectToViewTransformation = rViewInformation.getObjectToViewTransformation(); @@ -316,7 +315,7 @@ namespace drawinglayer } // use parent implementation - return BasePrimitive2D::get2DDecomposition(rViewInformation); + return BufferedDecompositionPrimitive2D::get2DDecomposition(rViewInformation); } // provide unique ID diff --git a/drawinglayer/source/primitive2d/groupprimitive2d.cxx b/drawinglayer/source/primitive2d/groupprimitive2d.cxx index ae899af6e84d..c9e2a1ea1438 100644 --- a/drawinglayer/source/primitive2d/groupprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/groupprimitive2d.cxx @@ -49,12 +49,6 @@ namespace drawinglayer { namespace primitive2d { - /// default: just return children, so all renderers not supporting group will use it's content - Primitive2DSequence GroupPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const - { - return getChildren(); - } - GroupPrimitive2D::GroupPrimitive2D( const Primitive2DSequence& rChildren ) : BasePrimitive2D(), maChildren(rChildren) @@ -77,6 +71,12 @@ namespace drawinglayer return false; } + /// default: just return children, so all renderers not supporting group will use it's content + Primitive2DSequence GroupPrimitive2D::get2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const + { + return getChildren(); + } + // provide unique ID ImplPrimitrive2DIDBlock(GroupPrimitive2D, PRIMITIVE2D_ID_GROUPPRIMITIVE2D) diff --git a/drawinglayer/source/primitive2d/helplineprimitive2d.cxx b/drawinglayer/source/primitive2d/helplineprimitive2d.cxx index 3232e635b561..251ac110acd6 100644 --- a/drawinglayer/source/primitive2d/helplineprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/helplineprimitive2d.cxx @@ -54,7 +54,7 @@ namespace drawinglayer { namespace primitive2d { - Primitive2DSequence HelplinePrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const + Primitive2DSequence HelplinePrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const { std::vector< BasePrimitive2D* > aTempPrimitiveTarget; @@ -167,7 +167,7 @@ namespace drawinglayer const basegfx::BColor& rRGBColA, const basegfx::BColor& rRGBColB, double fDiscreteDashLength) - : BasePrimitive2D(), + : BufferedDecompositionPrimitive2D(), maPosition(rPosition), maDirection(rDirection), meStyle(eStyle), @@ -181,7 +181,7 @@ namespace drawinglayer bool HelplinePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const { - if(BasePrimitive2D::operator==(rPrimitive)) + if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) { const HelplinePrimitive2D& rCompare = (HelplinePrimitive2D&)rPrimitive; @@ -200,16 +200,16 @@ namespace drawinglayer { ::osl::MutexGuard aGuard( m_aMutex ); - if(getLocalDecomposition().hasElements()) + if(getBuffered2DDecomposition().hasElements()) { if(maLastViewport != rViewInformation.getViewport() || maLastObjectToViewTransformation != rViewInformation.getObjectToViewTransformation()) { // conditions of last local decomposition have changed, delete - const_cast< HelplinePrimitive2D* >(this)->setLocalDecomposition(Primitive2DSequence()); + const_cast< HelplinePrimitive2D* >(this)->setBuffered2DDecomposition(Primitive2DSequence()); } } - if(!getLocalDecomposition().hasElements()) + if(!getBuffered2DDecomposition().hasElements()) { // remember ViewRange and ViewTransformation const_cast< HelplinePrimitive2D* >(this)->maLastObjectToViewTransformation = rViewInformation.getObjectToViewTransformation(); @@ -217,7 +217,7 @@ namespace drawinglayer } // use parent implementation - return BasePrimitive2D::get2DDecomposition(rViewInformation); + return BufferedDecompositionPrimitive2D::get2DDecomposition(rViewInformation); } // provide unique ID diff --git a/drawinglayer/source/primitive2d/hittestprimitive2d.cxx b/drawinglayer/source/primitive2d/hittestprimitive2d.cxx index daf65abd81d4..137f8cf8ad5c 100644 --- a/drawinglayer/source/primitive2d/hittestprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/hittestprimitive2d.cxx @@ -49,12 +49,6 @@ namespace drawinglayer { namespace primitive2d { - Primitive2DSequence HitTestPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const - { - // return empty sequence - return Primitive2DSequence(); - } - HitTestPrimitive2D::HitTestPrimitive2D( const Primitive2DSequence& rChildren) : GroupPrimitive2D(rChildren) @@ -66,6 +60,12 @@ namespace drawinglayer return getB2DRangeFromPrimitive2DSequence(getChildren(), rViewInformation); } + Primitive2DSequence HitTestPrimitive2D::get2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const + { + // return empty sequence + return Primitive2DSequence(); + } + // provide unique ID ImplPrimitrive2DIDBlock(HitTestPrimitive2D, PRIMITIVE2D_ID_HITTESTPRIMITIVE2D) diff --git a/drawinglayer/source/primitive2d/makefile.mk b/drawinglayer/source/primitive2d/makefile.mk index e10d1ddbcc71..c9a3cc191a35 100644 --- a/drawinglayer/source/primitive2d/makefile.mk +++ b/drawinglayer/source/primitive2d/makefile.mk @@ -53,7 +53,9 @@ SLOFILES= \ $(SLO)$/borderlineprimitive2d.obj \ $(SLO)$/chartprimitive2d.obj \ $(SLO)$/controlprimitive2d.obj \ + $(SLO)$/discretebitmapprimitive2d.obj \ $(SLO)$/embedded3dprimitive2d.obj \ + $(SLO)$/epsprimitive2d.obj \ $(SLO)$/fillbitmapprimitive2d.obj \ $(SLO)$/fillgradientprimitive2d.obj \ $(SLO)$/fillhatchprimitive2d.obj \ @@ -77,12 +79,16 @@ SLOFILES= \ $(SLO)$/shadowprimitive2d.obj \ $(SLO)$/structuretagprimitive2d.obj \ $(SLO)$/texteffectprimitive2d.obj \ + $(SLO)$/textenumsprimitive2d.obj \ $(SLO)$/textlayoutdevice.obj \ + $(SLO)$/textlineprimitive2d.obj \ $(SLO)$/textprimitive2d.obj \ + $(SLO)$/textstrikeoutprimitive2d.obj \ $(SLO)$/textdecoratedprimitive2d.obj \ $(SLO)$/texthierarchyprimitive2d.obj \ $(SLO)$/transformprimitive2d.obj \ $(SLO)$/unifiedalphaprimitive2d.obj \ + $(SLO)$/wallpaperprimitive2d.obj \ $(SLO)$/wrongspellprimitive2d.obj # --- Targets ---------------------------------- diff --git a/drawinglayer/source/primitive2d/markerarrayprimitive2d.cxx b/drawinglayer/source/primitive2d/markerarrayprimitive2d.cxx index 5737b9ef6cec..acb2335c0d1f 100644 --- a/drawinglayer/source/primitive2d/markerarrayprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/markerarrayprimitive2d.cxx @@ -55,7 +55,7 @@ namespace drawinglayer { namespace primitive2d { - Primitive2DSequence MarkerArrayPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const + Primitive2DSequence MarkerArrayPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const { Primitive2DSequence xRetval; const std::vector< basegfx::B2DPoint >& rPositions = getPositions(); @@ -100,7 +100,7 @@ namespace drawinglayer MarkerArrayPrimitive2D::MarkerArrayPrimitive2D( const std::vector< basegfx::B2DPoint >& rPositions, const BitmapEx& rMarker) - : BasePrimitive2D(), + : BufferedDecompositionPrimitive2D(), maPositions(rPositions), maMarker(rMarker) { @@ -108,7 +108,7 @@ namespace drawinglayer bool MarkerArrayPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const { - if(BasePrimitive2D::operator==(rPrimitive)) + if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) { const MarkerArrayPrimitive2D& rCompare = (MarkerArrayPrimitive2D&)rPrimitive; diff --git a/drawinglayer/source/primitive2d/maskprimitive2d.cxx b/drawinglayer/source/primitive2d/maskprimitive2d.cxx index 20a4c98db67d..b32abae874ca 100644 --- a/drawinglayer/source/primitive2d/maskprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/maskprimitive2d.cxx @@ -69,6 +69,11 @@ namespace drawinglayer return false; } + basegfx::B2DRange MaskPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const + { + return getMask().getB2DRange(); + } + // provide unique ID ImplPrimitrive2DIDBlock(MaskPrimitive2D, PRIMITIVE2D_ID_MASKPRIMITIVE2D) diff --git a/drawinglayer/source/primitive2d/mediaprimitive2d.cxx b/drawinglayer/source/primitive2d/mediaprimitive2d.cxx index e8b6b6fbd5e6..76c2036eb71e 100644 --- a/drawinglayer/source/primitive2d/mediaprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/mediaprimitive2d.cxx @@ -53,7 +53,7 @@ namespace drawinglayer { namespace primitive2d { - Primitive2DSequence MediaPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const + Primitive2DSequence MediaPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const { Primitive2DSequence xRetval(1); @@ -114,7 +114,7 @@ namespace drawinglayer const rtl::OUString& rURL, const basegfx::BColor& rBackgroundColor, sal_uInt32 nDiscreteBorder) - : BasePrimitive2D(), + : BufferedDecompositionPrimitive2D(), maTransform(rTransform), maURL(rURL), maBackgroundColor(rBackgroundColor), @@ -124,7 +124,7 @@ namespace drawinglayer bool MediaPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const { - if(BasePrimitive2D::operator==(rPrimitive)) + if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) { const MediaPrimitive2D& rCompare = (MediaPrimitive2D&)rPrimitive; diff --git a/drawinglayer/source/primitive2d/metafileprimitive2d.cxx b/drawinglayer/source/primitive2d/metafileprimitive2d.cxx index 2d1c0428a6a3..2fb3d119d4bd 100644 --- a/drawinglayer/source/primitive2d/metafileprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/metafileprimitive2d.cxx @@ -39,6 +39,39 @@ #include <drawinglayer/primitive2d/metafileprimitive2d.hxx> #include <basegfx/tools/canvastools.hxx> #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx> +#include <basegfx/color/bcolor.hxx> +#include <drawinglayer/primitive2d/pointarrayprimitive2d.hxx> +#include <vcl/lineinfo.hxx> +#include <drawinglayer/attribute/lineattribute.hxx> +#include <drawinglayer/attribute/strokeattribute.hxx> +#include <drawinglayer/primitive2d/polygonprimitive2d.hxx> +#include <vcl/metaact.hxx> +#include <drawinglayer/primitive2d/transformprimitive2d.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> +#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <drawinglayer/primitive2d/discretebitmapprimitive2d.hxx> +#include <drawinglayer/primitive2d/bitmapprimitive2d.hxx> +#include <vcl/salbtype.hxx> +#include <drawinglayer/primitive2d/unifiedalphaprimitive2d.hxx> +#include <drawinglayer/primitive2d/fillgradientprimitive2d.hxx> +#include <vcl/svapp.hxx> +#include <drawinglayer/primitive2d/alphaprimitive2d.hxx> +#include <drawinglayer/primitive2d/fillhatchprimitive2d.hxx> +#include <drawinglayer/primitive2d/maskprimitive2d.hxx> +#include <basegfx/polygon/b2dpolygonclipper.hxx> +#include <drawinglayer/primitive2d/invertprimitive2d.hxx> +#include <drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx> +#include <drawinglayer/primitive2d/fillbitmapprimitive2d.hxx> +#include <drawinglayer/primitive2d/wallpaperprimitive2d.hxx> +#include <drawinglayer/primitive2d/textprimitive2d.hxx> +#include <drawinglayer/primitive2d/textlayoutdevice.hxx> +#include <drawinglayer/primitive2d/textdecoratedprimitive2d.hxx> +#include <i18npool/mslangid.hxx> +#include <drawinglayer/primitive2d/textlineprimitive2d.hxx> +#include <drawinglayer/primitive2d/textstrikeoutprimitive2d.hxx> +#include <drawinglayer/primitive2d/epsprimitive2d.hxx> +#include <numeric> ////////////////////////////////////////////////////////////////////////////// @@ -46,14 +79,2980 @@ using namespace com::sun::star; ////////////////////////////////////////////////////////////////////////////// +namespace +{ + /** helper class for graphic context + + This class allows to hold a complete status of classic + VCL OutputDevice stati. This data is needed for correct + interpretation of the MetaFile action flow. + */ + class PropertyHolder + { + private: + /// current transformation (aka MapMode) + basegfx::B2DHomMatrix maTransformation; + MapUnit maMapUnit; + + /// current colors + basegfx::BColor maLineColor; + basegfx::BColor maFillColor; + basegfx::BColor maTextColor; + basegfx::BColor maTextFillColor; + basegfx::BColor maTextLineColor; + basegfx::BColor maOverlineColor; + + /// clipping, font, etc. + Region maRegion; + Font maFont; + RasterOp maRasterOp; + sal_uInt32 mnLayoutMode; + LanguageType maLanguageType; + sal_uInt16 mnPushFlags; + + /// bitfield + /// contains all active markers + bool mbLineColor : 1; + bool mbFillColor : 1; + bool mbTextColor : 1; + bool mbTextFillColor : 1; + bool mbTextLineColor : 1; + bool mbOverlineColor : 1; + bool mbRegion : 1; + + public: + PropertyHolder() + : maTransformation(), + maMapUnit(MAP_100TH_MM), + maLineColor(), + maFillColor(), + maTextColor(COL_BLACK), + maTextFillColor(), + maTextLineColor(), + maOverlineColor(), + maRegion(), + maFont(), + maRasterOp(ROP_OVERPAINT), + mnLayoutMode(0), + maLanguageType(0), + mnPushFlags(0), + mbLineColor(false), + mbFillColor(false), + mbTextColor(true), + mbTextFillColor(false), + mbTextLineColor(false), + mbOverlineColor(false), + mbRegion(false) + { + } + + ~PropertyHolder() + { + } + + /// read/write accesses + const basegfx::B2DHomMatrix& getTransformation() const { return maTransformation; } + void setTransformation(const basegfx::B2DHomMatrix& rNew) { if(rNew != maTransformation) maTransformation = rNew; } + + MapUnit getMapUnit() const { return maMapUnit; } + void setMapUnit(MapUnit eNew) { if(eNew != maMapUnit) maMapUnit = eNew; } + + const basegfx::BColor& getLineColor() const { return maLineColor; } + void setLineColor(const basegfx::BColor& rNew) { if(rNew != maLineColor) maLineColor = rNew; } + bool getLineColorActive() const { return mbLineColor; } + void setLineColorActive(bool bNew) { if(bNew != mbLineColor) mbLineColor = bNew; } + + const basegfx::BColor& getFillColor() const { return maFillColor; } + void setFillColor(const basegfx::BColor& rNew) { if(rNew != maFillColor) maFillColor = rNew; } + bool getFillColorActive() const { return mbFillColor; } + void setFillColorActive(bool bNew) { if(bNew != mbFillColor) mbFillColor = bNew; } + + const basegfx::BColor& getTextColor() const { return maTextColor; } + void setTextColor(const basegfx::BColor& rNew) { if(rNew != maTextColor) maTextColor = rNew; } + bool getTextColorActive() const { return mbTextColor; } + void setTextColorActive(bool bNew) { if(bNew != mbTextColor) mbTextColor = bNew; } + + const basegfx::BColor& getTextFillColor() const { return maTextFillColor; } + void setTextFillColor(const basegfx::BColor& rNew) { if(rNew != maTextFillColor) maTextFillColor = rNew; } + bool getTextFillColorActive() const { return mbTextFillColor; } + void setTextFillColorActive(bool bNew) { if(bNew != mbTextFillColor) mbTextFillColor = bNew; } + + const basegfx::BColor& getTextLineColor() const { return maTextLineColor; } + void setTextLineColor(const basegfx::BColor& rNew) { if(rNew != maTextLineColor) maTextLineColor = rNew; } + bool getTextLineColorActive() const { return mbTextLineColor; } + void setTextLineColorActive(bool bNew) { if(bNew != mbTextLineColor) mbTextLineColor = bNew; } + + const basegfx::BColor& getOverlineColor() const { return maOverlineColor; } + void setOverlineColor(const basegfx::BColor& rNew) { if(rNew != maOverlineColor) maOverlineColor = rNew; } + bool getOverlineColorActive() const { return mbOverlineColor; } + void setOverlineColorActive(bool bNew) { if(bNew != mbOverlineColor) mbOverlineColor = bNew; } + + const Region& getRegion() const { return maRegion; } + void setRegion(const Region& rRegion) { if(rRegion != maRegion) maRegion = rRegion; } + bool getRegionActive() const { return mbRegion; } + void setRegionActive(bool bNew) { if(bNew != mbRegion) mbRegion = bNew; } + + const Font& getFont() const { return maFont; } + void setFont(const Font& rFont) { if(rFont != maFont) maFont = rFont; } + + const RasterOp& getRasterOp() const { return maRasterOp; } + void setRasterOp(const RasterOp& rRasterOp) { if(rRasterOp != maRasterOp) maRasterOp = rRasterOp; } + bool isRasterOpInvert() const { return (ROP_XOR == maRasterOp || ROP_INVERT == maRasterOp); } + bool isRasterOpForceBlack() const { return ROP_0 == maRasterOp; } + bool isRasterOpActive() const { return isRasterOpInvert() || isRasterOpForceBlack(); } + + sal_uInt32 getLayoutMode() const { return mnLayoutMode; } + void setLayoutMode(sal_uInt32 nNew) { if(nNew != mnLayoutMode) mnLayoutMode = nNew; } + + LanguageType getLanguageType() const { return maLanguageType; } + void setLanguageType(LanguageType aNew) { if(aNew != maLanguageType) maLanguageType = aNew; } + + sal_uInt16 getPushFlags() const { return mnPushFlags; } + void setPushFlags(sal_uInt16 nNew) { if(nNew != mnPushFlags) mnPushFlags = nNew; } + + bool getLineOrFillActive() const { return (mbLineColor || mbFillColor); } + }; +} // end of anonymous namespace + +////////////////////////////////////////////////////////////////////////////// + +namespace +{ + /** stack for properites + + This class builds a stack based on the PropertyHolder + class. It encapsulates the pointer/new/delete usage to + make it safe and implements the push/pop as needed by a + VCL Metafile interpreter. The critical part here are the + flag values VCL OutputDevice uses here; not all stuff is + pushed and thus needs to be copied at pop. + */ + class PropertyHolders + { + private: + std::vector< PropertyHolder* > maPropertyHolders; + + public: + PropertyHolders() + { + maPropertyHolders.push_back(new PropertyHolder()); + } + + sal_uInt32 size() + { + return maPropertyHolders.size(); + } + + void Push(sal_uInt16 nPushFlags) + { + if(nPushFlags) + { + OSL_ENSURE(maPropertyHolders.size(), "PropertyHolders: PUSH with no property holders (!)"); + PropertyHolder* pNew = new PropertyHolder(*maPropertyHolders.back()); + pNew->setPushFlags(nPushFlags); + maPropertyHolders.push_back(pNew); + } + } + + void Pop() + { + OSL_ENSURE(maPropertyHolders.size(), "PropertyHolders: POP with no property holders (!)"); + const sal_uInt32 nSize(maPropertyHolders.size()); + + if(nSize) + { + const PropertyHolder* pTip = maPropertyHolders.back(); + const sal_uInt16 nPushFlags(pTip->getPushFlags()); + + if(nPushFlags) + { + if(nSize > 1) + { + // copy back content for all non-set flags + PropertyHolder* pLast = maPropertyHolders[nSize - 2]; + + if(PUSH_ALL != nPushFlags) + { + if(!(nPushFlags & PUSH_LINECOLOR )) + { + pLast->setLineColor(pTip->getLineColor()); + pLast->setLineColorActive(pTip->getLineColorActive()); + } + if(!(nPushFlags & PUSH_FILLCOLOR )) + { + pLast->setFillColor(pTip->getFillColor()); + pLast->setFillColorActive(pTip->getFillColorActive()); + } + if(!(nPushFlags & PUSH_FONT )) + { + pLast->setFont(pTip->getFont()); + } + if(!(nPushFlags & PUSH_TEXTCOLOR )) + { + pLast->setTextColor(pTip->getTextColor()); + pLast->setTextColorActive(pTip->getTextColorActive()); + } + if(!(nPushFlags & PUSH_MAPMODE )) + { + pLast->setTransformation(pTip->getTransformation()); + pLast->setMapUnit(pTip->getMapUnit()); + } + if(!(nPushFlags & PUSH_CLIPREGION )) + { + pLast->setRegion(pTip->getRegion()); + pLast->setRegionActive(pTip->getRegionActive()); + } + if(!(nPushFlags & PUSH_RASTEROP )) + { + pLast->setRasterOp(pTip->getRasterOp()); + } + if(!(nPushFlags & PUSH_TEXTFILLCOLOR )) + { + pLast->setTextFillColor(pTip->getTextFillColor()); + pLast->setTextFillColorActive(pTip->getTextFillColorActive()); + } + if(!(nPushFlags & PUSH_TEXTALIGN )) + { + if(pLast->getFont().GetAlign() != pTip->getFont().GetAlign()) + { + Font aFont(pLast->getFont()); + aFont.SetAlign(pTip->getFont().GetAlign()); + pLast->setFont(aFont); + } + } + if(!(nPushFlags & PUSH_REFPOINT )) + { + // not supported + } + if(!(nPushFlags & PUSH_TEXTLINECOLOR )) + { + pLast->setTextLineColor(pTip->getTextLineColor()); + pLast->setTextLineColorActive(pTip->getTextLineColorActive()); + } + if(!(nPushFlags & PUSH_TEXTLAYOUTMODE )) + { + pLast->setLayoutMode(pTip->getLayoutMode()); + } + if(!(nPushFlags & PUSH_TEXTLANGUAGE )) + { + pLast->setLanguageType(pTip->getLanguageType()); + } + if(!(nPushFlags & PUSH_OVERLINECOLOR )) + { + pLast->setOverlineColor(pTip->getOverlineColor()); + pLast->setOverlineColorActive(pTip->getOverlineColorActive()); + } + } + } + + // execute the pop + delete maPropertyHolders.back(); + maPropertyHolders.pop_back(); + } + } + } + + PropertyHolder& Current() + { + OSL_ENSURE(maPropertyHolders.size(), "PropertyHolders: CURRENT with no property holders (!)"); + return *maPropertyHolders.back(); + } + + ~PropertyHolders() + { + while(maPropertyHolders.size()) + { + delete maPropertyHolders.back(); + maPropertyHolders.pop_back(); + } + } + }; +} // end of anonymous namespace + +////////////////////////////////////////////////////////////////////////////// + +namespace +{ + /** helper to convert a Region to a B2DPolyPolygon + when it does not yet contain one. In the future + this may be expanded to merge the polygons created + from rectangles or use a special algo to directly turn + the spans of regions to a single, already merged + PolyPolygon. + */ + basegfx::B2DPolyPolygon getB2DPolyPolygonFromRegion(const Region& rRegion) + { + basegfx::B2DPolyPolygon aRetval; + + if(!rRegion.IsEmpty()) + { + Region aRegion(rRegion); + aRetval = aRegion.GetB2DPolyPolygon(); + + if(!aRetval.count()) + { + RegionHandle aRegionHandle(aRegion.BeginEnumRects()); + Rectangle aRegionRectangle; + + while(aRegion.GetEnumRects(aRegionHandle, aRegionRectangle)) + { + if(!aRegionRectangle.IsEmpty()) + { + const basegfx::B2DRange aRegionRange( + aRegionRectangle.Left(), aRegionRectangle.Top(), + aRegionRectangle.Right(), aRegionRectangle.Bottom()); + aRetval.append(basegfx::tools::createPolygonFromRect(aRegionRange)); + } + } + + aRegion.EndEnumRects(aRegionHandle); + } + } + + return aRetval; + } +} // end of anonymous namespace + +////////////////////////////////////////////////////////////////////////////// + +namespace +{ + /** Helper class to buffer and hold a Primive target vector. It + encapsulates the new/delete functionality and aloows to work + on pointers of the implementation classes. All data will + be converted to uno sequences of uno references when accessing the + data. + */ + class TargetHolder + { + private: + std::vector< drawinglayer::primitive2d::BasePrimitive2D* > aTargets; + + public: + TargetHolder() + : aTargets() + { + } + + ~TargetHolder() + { + const sal_uInt32 nCount(aTargets.size()); + + for(sal_uInt32 a(0); a < nCount; a++) + { + delete aTargets[a]; + } + } + + sal_uInt32 size() + { + return aTargets.size(); + } + + void append(drawinglayer::primitive2d::BasePrimitive2D* pCandidate) + { + if(pCandidate) + { + aTargets.push_back(pCandidate); + } + } + + drawinglayer::primitive2d::Primitive2DSequence getPrimitive2DSequence(const PropertyHolder& rPropertyHolder) + { + const sal_uInt32 nCount(aTargets.size()); + drawinglayer::primitive2d::Primitive2DSequence xRetval(nCount); + + for(sal_uInt32 a(0); a < nCount; a++) + { + xRetval[a] = aTargets[a]; + } + + // All Targets were pointers, but do not need to be deleted since they + // were converted to UNO API references now, so they stay as long as + // referenced. Do NOT delete the C++ implementation classes here, but clear + // the buffer to not delete them in the destructor. + aTargets.clear(); + + if(xRetval.hasElements() && rPropertyHolder.getRegionActive()) + { + const Region& rRegion = rPropertyHolder.getRegion(); + + if(!rRegion.IsEmpty()) + { + basegfx::B2DPolyPolygon aClipPolyPolygon(getB2DPolyPolygonFromRegion(rRegion)); + + if(aClipPolyPolygon.count()) + { + aClipPolyPolygon.transform(rPropertyHolder.getTransformation()); + + const drawinglayer::primitive2d::Primitive2DReference xMask( + new drawinglayer::primitive2d::MaskPrimitive2D( + aClipPolyPolygon, + xRetval)); + + xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xMask, 1); + } + } + } + + return xRetval; + } + }; +} // end of anonymous namespace + +////////////////////////////////////////////////////////////////////////////// + +namespace +{ + /** Helper class which builds a stack on the TargetHolder class */ + class TargetHolders + { + private: + std::vector< TargetHolder* > maTargetHolders; + + public: + TargetHolders() + { + maTargetHolders.push_back(new TargetHolder()); + } + + sal_uInt32 size() + { + return maTargetHolders.size(); + } + + void Push() + { + maTargetHolders.push_back(new TargetHolder()); + } + + void Pop() + { + OSL_ENSURE(maTargetHolders.size(), "TargetHolders: POP with no property holders (!)"); + if(maTargetHolders.size()) + { + delete maTargetHolders.back(); + maTargetHolders.pop_back(); + } + } + + TargetHolder& Current() + { + OSL_ENSURE(maTargetHolders.size(), "TargetHolders: CURRENT with no property holders (!)"); + return *maTargetHolders.back(); + } + + ~TargetHolders() + { + while(maTargetHolders.size()) + { + delete maTargetHolders.back(); + maTargetHolders.pop_back(); + } + } + }; +} // end of anonymous namespace + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + /** NonOverlappingFillGradientPrimitive2D class + + This is a special version of the FillGradientPrimitive2D which decomposes + to a non-overlapping geometry version of the gradient. This needs to be + used to support the old XOR paint-'trick'. + + It does not need an own identifier since a renderer who wants to interpret + it itself may do so. It just overloads the decomposition of the C++ + implementation class to do an alternative decomposition. + */ + class NonOverlappingFillGradientPrimitive2D : public FillGradientPrimitive2D + { + protected: + /// local decomposition. + virtual Primitive2DSequence create2DDecomposition( + const geometry::ViewInformation2D& rViewInformation) const; + + public: + /// constructor + NonOverlappingFillGradientPrimitive2D( + const basegfx::B2DRange& rObjectRange, + const attribute::FillGradientAttribute& rFillGradient) + : FillGradientPrimitive2D(rObjectRange, rFillGradient) + { + } + }; + + Primitive2DSequence NonOverlappingFillGradientPrimitive2D::create2DDecomposition( + const geometry::ViewInformation2D& /*rViewInformation*/) const + { + return createFill(false); + } + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// + +namespace +{ + /** helper to convert a MapMode to a transformation */ + basegfx::B2DHomMatrix getTransformFromMapMode(const MapMode& rMapMode) + { + basegfx::B2DHomMatrix aMapping; + const Fraction aNoScale(1, 1); + const Point& rOrigin(rMapMode.GetOrigin()); + + if(0 != rOrigin.X() || 0 != rOrigin.Y()) + { + aMapping.translate(rOrigin.X(), rOrigin.Y()); + } + + if(rMapMode.GetScaleX() != aNoScale || rMapMode.GetScaleY() != aNoScale) + { + aMapping.scale( + double(rMapMode.GetScaleX()), + double(rMapMode.GetScaleY())); + } + + return aMapping; + } + + /** helper to create a PointArrayPrimitive2D based on current context */ + void createPointArrayPrimitive( + const std::vector< basegfx::B2DPoint >& rPositions, + TargetHolder& rTarget, + PropertyHolder& rProperties, + basegfx::BColor aBColor) + { + if(rPositions.size()) + { + if(rProperties.getTransformation().isIdentity()) + { + rTarget.append( + new drawinglayer::primitive2d::PointArrayPrimitive2D( + rPositions, + aBColor)); + } + else + { + std::vector< basegfx::B2DPoint > aPositions(rPositions); + + for(sal_uInt32 a(0); a < aPositions.size(); a++) + { + aPositions[a] = rProperties.getTransformation() * aPositions[a]; + } + + rTarget.append( + new drawinglayer::primitive2d::PointArrayPrimitive2D( + aPositions, + aBColor)); + } + } + } + + /** helper to create a PolygonHairlinePrimitive2D based on current context */ + void createHairlinePrimitive( + const basegfx::B2DPolygon& rLinePolygon, + TargetHolder& rTarget, + PropertyHolder& rProperties) + { + if(rLinePolygon.count()) + { + basegfx::B2DPolygon aLinePolygon(rLinePolygon); + aLinePolygon.transform(rProperties.getTransformation()); + rTarget.append( + new drawinglayer::primitive2d::PolygonHairlinePrimitive2D( + aLinePolygon, + rProperties.getLineColor())); + } + } + + /** helper to create a PolyPolygonColorPrimitive2D based on current context */ + void createFillPrimitive( + const basegfx::B2DPolyPolygon& rFillPolyPolygon, + TargetHolder& rTarget, + PropertyHolder& rProperties) + { + if(rFillPolyPolygon.count()) + { + basegfx::B2DPolyPolygon aFillPolyPolygon(rFillPolyPolygon); + aFillPolyPolygon.transform(rProperties.getTransformation()); + rTarget.append( + new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D( + aFillPolyPolygon, + rProperties.getFillColor())); + } + } + + /** helper to create a PolygonStrokePrimitive2D based on current context */ + void createLinePrimitive( + const basegfx::B2DPolygon& rLinePolygon, + const LineInfo& rLineInfo, + TargetHolder& rTarget, + PropertyHolder& rProperties) + { + if(rLinePolygon.count()) + { + const bool bDashDotUsed(LINE_DASH == rLineInfo.GetStyle()); + const bool bWidthUsed(rLineInfo.GetWidth() > 1); + + if(bDashDotUsed || bWidthUsed) + { + basegfx::B2DPolygon aLinePolygon(rLinePolygon); + aLinePolygon.transform(rProperties.getTransformation()); + const drawinglayer::attribute::LineAttribute aLineAttribute( + rProperties.getLineColor(), + bWidthUsed ? rLineInfo.GetWidth() : 0.0, + rLineInfo.GetLineJoin()); + + if(bDashDotUsed) + { + ::std::vector< double > fDotDashArray; + const double fDashLen(rLineInfo.GetDashLen()); + const double fDotLen(rLineInfo.GetDotLen()); + const double fDistance(rLineInfo.GetDistance()); + + for(sal_uInt16 a(0); a < rLineInfo.GetDashCount(); a++) + { + fDotDashArray.push_back(fDashLen); + fDotDashArray.push_back(fDistance); + } + + for(sal_uInt16 b(0); b < rLineInfo.GetDotCount(); b++) + { + fDotDashArray.push_back(fDotLen); + fDotDashArray.push_back(fDistance); + } + + const double fAccumulated(::std::accumulate(fDotDashArray.begin(), fDotDashArray.end(), 0.0)); + const drawinglayer::attribute::StrokeAttribute aStrokeAttribute( + fDotDashArray, + fAccumulated); + + rTarget.append( + new drawinglayer::primitive2d::PolygonStrokePrimitive2D( + aLinePolygon, + aLineAttribute, + aStrokeAttribute)); + } + else + { + rTarget.append( + new drawinglayer::primitive2d::PolygonStrokePrimitive2D( + aLinePolygon, + aLineAttribute)); + } + } + else + { + createHairlinePrimitive(rLinePolygon, rTarget, rProperties); + } + } + } + + /** helper to create needed line and fill primitives based on current context */ + void createHairlineAndFillPrimitive( + const basegfx::B2DPolygon& rPolygon, + TargetHolder& rTarget, + PropertyHolder& rProperties) + { + if(rProperties.getFillColorActive()) + { + createFillPrimitive(basegfx::B2DPolyPolygon(rPolygon), rTarget, rProperties); + } + + if(rProperties.getLineColorActive()) + { + createHairlinePrimitive(rPolygon, rTarget, rProperties); + } + } + + /** helper to create needed line and fill primitives based on current context */ + void createHairlineAndFillPrimitive( + const basegfx::B2DPolyPolygon& rPolyPolygon, + TargetHolder& rTarget, + PropertyHolder& rProperties) + { + if(rProperties.getFillColorActive()) + { + createFillPrimitive(rPolyPolygon, rTarget, rProperties); + } + + if(rProperties.getLineColorActive()) + { + for(sal_uInt32 a(0); a < rPolyPolygon.count(); a++) + { + createHairlinePrimitive(rPolyPolygon.getB2DPolygon(a), rTarget, rProperties); + } + } + } + + /** helper to create DiscreteBitmapPrimitive2D based on current context. + The DiscreteBitmapPrimitive2D is especially created for this usage + since no other usage defines a bitmap visualisation based on top-left + position and size in pixels. At the end it will create a view-dependent + transformed embedding of a BitmapPrimitive2D. + */ + void createBitmapExPrimitive( + const BitmapEx& rBitmapEx, + const Point& rPoint, + TargetHolder& rTarget, + PropertyHolder& rProperties) + { + if(!rBitmapEx.IsEmpty()) + { + basegfx::B2DPoint aPoint(rPoint.X(), rPoint.Y()); + aPoint = rProperties.getTransformation() * aPoint; + + rTarget.append( + new drawinglayer::primitive2d::DiscreteBitmapPrimitive2D( + rBitmapEx, + aPoint)); + } + } + + /** helper to create BitmapPrimitive2D based on current context */ + void createBitmapExPrimitive( + const BitmapEx& rBitmapEx, + const Point& rPoint, + const Size& rSize, + TargetHolder& rTarget, + PropertyHolder& rProperties) + { + if(!rBitmapEx.IsEmpty()) + { + basegfx::B2DHomMatrix aObjectTransform; + + aObjectTransform.set(0, 0, rSize.Width()); + aObjectTransform.set(1, 1, rSize.Height()); + aObjectTransform.set(0, 2, rPoint.X()); + aObjectTransform.set(1, 2, rPoint.Y()); + + aObjectTransform = rProperties.getTransformation() * aObjectTransform; + + rTarget.append( + new drawinglayer::primitive2d::BitmapPrimitive2D( + rBitmapEx, + aObjectTransform)); + } + } + + /** helper to create a regular BotmapEx from a MaskAction (definitions + which use a bitmap without alpha but define one of the colors as + transparent) + */ + BitmapEx createMaskBmpEx(const Bitmap& rBitmap, const Color& rMaskColor) + { + const Color aWhite(COL_WHITE); + BitmapPalette aBiLevelPalette(2); + + aBiLevelPalette[0] = aWhite; + aBiLevelPalette[1] = rMaskColor; + + Bitmap aMask(rBitmap.CreateMask(aWhite)); + Bitmap aSolid(rBitmap.GetSizePixel(), 1, &aBiLevelPalette); + + aSolid.Erase(rMaskColor); + + return BitmapEx(aSolid, aMask); + } + + /** helper to convert from a VCL Gradient definition to the corresponding + data for primitive representation + */ + drawinglayer::attribute::FillGradientAttribute createFillGradientAttribute(const Gradient& rGradient) + { + const Color aStartColor(rGradient.GetStartColor()); + const sal_uInt16 nStartIntens(rGradient.GetStartIntensity()); + basegfx::BColor aStart(aStartColor.getBColor()); + + if(nStartIntens != 100) + { + const basegfx::BColor aBlack; + aStart = interpolate(aBlack, aStart, (double)nStartIntens * 0.01); + } + + const Color aEndColor(rGradient.GetEndColor()); + const sal_uInt16 nEndIntens(rGradient.GetEndIntensity()); + basegfx::BColor aEnd(aEndColor.getBColor()); + + if(nEndIntens != 100) + { + const basegfx::BColor aBlack; + aEnd = interpolate(aBlack, aEnd, (double)nEndIntens * 0.01); + } + + drawinglayer::attribute::GradientStyle aGradientStyle(drawinglayer::attribute::GRADIENTSTYLE_RECT); + + switch(rGradient.GetStyle()) + { + case GRADIENT_LINEAR : + { + aGradientStyle = drawinglayer::attribute::GRADIENTSTYLE_LINEAR; + break; + } + case GRADIENT_AXIAL : + { + aGradientStyle = drawinglayer::attribute::GRADIENTSTYLE_AXIAL; + break; + } + case GRADIENT_RADIAL : + { + aGradientStyle = drawinglayer::attribute::GRADIENTSTYLE_RADIAL; + break; + } + case GRADIENT_ELLIPTICAL : + { + aGradientStyle = drawinglayer::attribute::GRADIENTSTYLE_ELLIPTICAL; + break; + } + case GRADIENT_SQUARE : + { + aGradientStyle = drawinglayer::attribute::GRADIENTSTYLE_SQUARE; + break; + } + default : // GRADIENT_RECT + { + aGradientStyle = drawinglayer::attribute::GRADIENTSTYLE_RECT; + break; + } + } + + return drawinglayer::attribute::FillGradientAttribute( + aGradientStyle, + (double)rGradient.GetBorder() * 0.01, + (double)rGradient.GetOfsX() * 0.01, + (double)rGradient.GetOfsY() * 0.01, + (double)rGradient.GetAngle() * F_PI1800, + aStart, + aEnd, + rGradient.GetSteps()); + } + + /** helper to convert from a VCL Hatch definition to the corresponding + data for primitive representation + */ + drawinglayer::attribute::FillHatchAttribute createFillHatchAttribute(const Hatch& rHatch) + { + drawinglayer::attribute::HatchStyle aHatchStyle(drawinglayer::attribute::HATCHSTYLE_SINGLE); + + switch(rHatch.GetStyle()) + { + default : // case HATCH_SINGLE : + { + aHatchStyle = drawinglayer::attribute::HATCHSTYLE_SINGLE; + } + case HATCH_DOUBLE : + { + aHatchStyle = drawinglayer::attribute::HATCHSTYLE_DOUBLE; + } + case HATCH_TRIPLE : + { + aHatchStyle = drawinglayer::attribute::HATCHSTYLE_TRIPLE; + } + } + + return drawinglayer::attribute::FillHatchAttribute( + aHatchStyle, + (double)rHatch.GetDistance(), + (double)rHatch.GetAngle() * F_PI1800, + rHatch.GetColor().getBColor(), + false); + } + + /** helper to take needed action on ClipRegion change. This method needs to be called + on any Region change, e.g. at the obvious actions doing this, but also at pop-calls + whcih change the Region of the current context. It takes care of creating the + current embeddec context, set the new Region at the context and eventually prepare + a new target for embracing new geometry to the current region + */ + void HandleNewClipRegion( + const Region* pRegion, + TargetHolders& rTargetHolders, + PropertyHolders& rPropertyHolders) + { + // process evtl. created primitives which belong to the current region settings + if(rPropertyHolders.Current().getRegionActive() && rTargetHolders.size() > 1) + { + drawinglayer::primitive2d::Primitive2DSequence aSubContent; + + if(!rPropertyHolders.Current().getRegion().IsEmpty() && rTargetHolders.Current().size()) + { + aSubContent = rTargetHolders.Current().getPrimitive2DSequence(rPropertyHolders.Current()); + } + + rTargetHolders.Pop(); + + if(aSubContent.hasElements()) + { + rTargetHolders.Current().append( + new drawinglayer::primitive2d::GroupPrimitive2D( + aSubContent)); + } + } + + // apply new settings + const bool bNewActive(pRegion && !pRegion->IsEmpty()); + rPropertyHolders.Current().setRegionActive(bNewActive); + + if(bNewActive) + { + rPropertyHolders.Current().setRegion(*pRegion); + + // prepare new content holder for new active region + rTargetHolders.Push(); + } + } + + /** helper to handle the change of RasterOp. It takes care of encapsulating all current + geometry to the current RasterOp (if changed) and needs to be called on any RasterOp + change. It will also start a new geometry target to embrace to the new RasterOp if + a changuing RasterOp is used. Currently, ROP_XOR and ROP_INVERT are supported using + InvertPrimitive2D, and ROP_0 by using a ModifiedColorPrimitive2D to force to black paint + */ + void HandleNewRasterOp( + RasterOp aRasterOp, + TargetHolders& rTargetHolders, + PropertyHolders& rPropertyHolders) + { + // check if currently active + if(rPropertyHolders.Current().isRasterOpActive() && rTargetHolders.size() > 1) + { + drawinglayer::primitive2d::Primitive2DSequence aSubContent; + + if(rTargetHolders.Current().size()) + { + aSubContent = rTargetHolders.Current().getPrimitive2DSequence(rPropertyHolders.Current()); + } + + rTargetHolders.Pop(); + + if(aSubContent.hasElements()) + { + if(rPropertyHolders.Current().isRasterOpForceBlack()) + { + // force content to black + rTargetHolders.Current().append( + new drawinglayer::primitive2d::ModifiedColorPrimitive2D( + aSubContent, + basegfx::BColorModifier(basegfx::BColor(0.0, 0.0, 0.0)))); + } + else // if(rPropertyHolders.Current().isRasterOpInvert()) + { + // invert content + rTargetHolders.Current().append( + new drawinglayer::primitive2d::InvertPrimitive2D( + aSubContent)); + } + } + } + + // apply new settings + rPropertyHolders.Current().setRasterOp(aRasterOp); + + // check if now active + if(rPropertyHolders.Current().isRasterOpActive()) + { + // prepare new content holder for new invert + rTargetHolders.Push(); + } + } + + /** helper to create needed data to emulate the VCL Wallpaper Metafile action. + It is a quite mighty action. This helper is for simple color filled background. + */ + drawinglayer::primitive2d::BasePrimitive2D* CreateColorWallpaper( + const basegfx::B2DRange& rRange, + const basegfx::BColor& rColor, + PropertyHolder& rPropertyHolder) + { + basegfx::B2DPolygon aOutline(basegfx::tools::createPolygonFromRect(rRange)); + aOutline.transform(rPropertyHolder.getTransformation()); + + return new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D( + basegfx::B2DPolyPolygon(aOutline), + rColor); + } + + /** helper to create needed data to emulate the VCL Wallpaper Metafile action. + It is a quite mighty action. This helper is for gradient filled background. + */ + drawinglayer::primitive2d::BasePrimitive2D* CreateGradientWallpaper( + const basegfx::B2DRange& rRange, + const Gradient& rGradient, + PropertyHolder& rPropertyHolder) + { + const drawinglayer::attribute::FillGradientAttribute aAttribute(createFillGradientAttribute(rGradient)); + + if(aAttribute.getStartColor() == aAttribute.getEndColor()) + { + // not really a gradient. Create filled rectangle + return CreateColorWallpaper(rRange, aAttribute.getStartColor(), rPropertyHolder); + } + else + { + // really a gradient + drawinglayer::primitive2d::BasePrimitive2D* pRetval = + new drawinglayer::primitive2d::FillGradientPrimitive2D( + rRange, + aAttribute); + + if(!rPropertyHolder.getTransformation().isIdentity()) + { + const drawinglayer::primitive2d::Primitive2DReference xPrim(pRetval); + const drawinglayer::primitive2d::Primitive2DSequence xSeq(&xPrim, 1); + + pRetval = new drawinglayer::primitive2d::TransformPrimitive2D( + rPropertyHolder.getTransformation(), + xSeq); + } + + return pRetval; + } + } + + /** helper to create needed data to emulate the VCL Wallpaper Metafile action. + It is a quite mighty action. This helper decides if color and/or gradient + background is needed for the wnated bitmap fill and then creates the needed + WallpaperBitmapPrimitive2D. This primitive was created for this purpose and + takes over all needed logic of orientations and tiling. + */ + void CreateAndAppendBitmapWallpaper( + basegfx::B2DRange aWallpaperRange, + const Wallpaper& rWallpaper, + TargetHolder& rTarget, + PropertyHolder& rProperty) + { + const BitmapEx aBitmapEx(rWallpaper.GetBitmap()); + const WallpaperStyle eWallpaperStyle(rWallpaper.GetStyle()); + + // if bitmap visualisation is transparent, maybe background + // needs to be filled. Create background + if(aBitmapEx.IsTransparent() + || (WALLPAPER_TILE != eWallpaperStyle && WALLPAPER_SCALE != eWallpaperStyle)) + { + if(rWallpaper.IsGradient()) + { + rTarget.append( + CreateGradientWallpaper( + aWallpaperRange, + rWallpaper.GetGradient(), + rProperty)); + } + else if(!rWallpaper.GetColor().GetTransparency()) + { + rTarget.append( + CreateColorWallpaper( + aWallpaperRange, + rWallpaper.GetColor().getBColor(), + rProperty)); + } + } + + // use wallpaper rect if set + if(rWallpaper.IsRect() && !rWallpaper.GetRect().IsEmpty()) + { + aWallpaperRange = basegfx::B2DRange( + rWallpaper.GetRect().Left(), rWallpaper.GetRect().Top(), + rWallpaper.GetRect().Right(), rWallpaper.GetRect().Bottom()); + } + + drawinglayer::primitive2d::BasePrimitive2D* pBitmapWallpaperFill = + new drawinglayer::primitive2d::WallpaperBitmapPrimitive2D( + aWallpaperRange, + aBitmapEx, + eWallpaperStyle); + + if(rProperty.getTransformation().isIdentity()) + { + // add directly + rTarget.append(pBitmapWallpaperFill); + } + else + { + // when a transformation is set, embed to it + const drawinglayer::primitive2d::Primitive2DReference xPrim(pBitmapWallpaperFill); + + rTarget.append( + new drawinglayer::primitive2d::TransformPrimitive2D( + rProperty.getTransformation(), + drawinglayer::primitive2d::Primitive2DSequence(&xPrim, 1))); + } + } + + /** helper to decide UnderlineAbove for text primitives */ + bool isUnderlineAbove(const Font& rFont) + { + if(!rFont.IsVertical()) + { + return false; + } + + if((LANGUAGE_JAPANESE == rFont.GetLanguage()) || (LANGUAGE_JAPANESE == rFont.GetCJKContextLanguage())) + { + // the underline is right for Japanese only + return true; + } + + return false; + } + + void createFontAttributeTransformAndAlignment( + drawinglayer::attribute::FontAttribute& rFontAttribute, + basegfx::B2DHomMatrix& rTextTransform, + basegfx::B2DVector& rAlignmentOffset, + PropertyHolder& rProperty) + { + const Font& rFont = rProperty.getFont(); + basegfx::B2DVector aFontScaling; + + rFontAttribute = drawinglayer::attribute::FontAttribute( + drawinglayer::primitive2d::getFontAttributeFromVclFont( + aFontScaling, + rFont, + 0 != (rProperty.getLayoutMode() & TEXT_LAYOUT_BIDI_RTL), + 0 != (rProperty.getLayoutMode() & TEXT_LAYOUT_BIDI_STRONG))); + + // add FontScaling + rTextTransform.scale(aFontScaling.getX(), aFontScaling.getY()); + + // take text align into account + if(ALIGN_BASELINE != rFont.GetAlign()) + { + drawinglayer::primitive2d::TextLayouterDevice aTextLayouterDevice; + aTextLayouterDevice.setFont(rFont); + + if(ALIGN_TOP == rFont.GetAlign()) + { + rAlignmentOffset.setY(aTextLayouterDevice.getFontAscent()); + } + else // ALIGN_BOTTOM + { + rAlignmentOffset.setY(-aTextLayouterDevice.getFontDescent()); + } + + rTextTransform.translate(rAlignmentOffset.getX(), rAlignmentOffset.getY()); + } + + // add FontRotation (if used) + if(rFont.GetOrientation()) + { + rTextTransform.rotate(-rFont.GetOrientation() * F_PI1800); + } + } + + /** helper which takes complete care for creating the needed text primitives. It + takes care of decorated stuff and all the geometry adaptions needed + */ + void proccessMetaTextAction( + const Point& rTextStartPosition, + const XubString& rText, + sal_uInt16 nTextStart, + sal_uInt16 nTextLength, + sal_Int32* pDXArray, + TargetHolder& rTarget, + PropertyHolder& rProperty) + { + drawinglayer::primitive2d::BasePrimitive2D* pResult = 0; + const Font& rFont = rProperty.getFont(); + std::vector< double > aDXArray; + basegfx::B2DVector aAlignmentOffset(0.0, 0.0); + + if(nTextLength) + { + drawinglayer::attribute::FontAttribute aFontAttribute; + basegfx::B2DHomMatrix aTextTransform; + + // fill parameters derived from current font + createFontAttributeTransformAndAlignment( + aFontAttribute, + aTextTransform, + aAlignmentOffset, + rProperty); + + // add TextStartPosition + aTextTransform.translate(rTextStartPosition.X(), rTextStartPosition.Y()); + + // preapare DXArray (if used) + if(pDXArray && nTextLength) + { + aDXArray.reserve(nTextLength); + + for(xub_StrLen a(0); a < nTextLength; a++) + { + aDXArray.push_back((double)(*(pDXArray + a))); + } + } + + // prepare FontColor and Locale + const basegfx::BColor aFontColor(rProperty.getTextColor()); + const com::sun::star::lang::Locale aLocale(MsLangId::convertLanguageToLocale(rProperty.getLanguageType())); + const bool bWordLineMode(rFont.IsWordLineMode()); + + const bool bDecoratedIsNeeded( + UNDERLINE_NONE != rFont.GetOverline() + || UNDERLINE_NONE != rFont.GetUnderline() + || STRIKEOUT_NONE != rFont.GetStrikeout() + || EMPHASISMARK_NONE != (rFont.GetEmphasisMark() & EMPHASISMARK_STYLE) + || RELIEF_NONE != rFont.GetRelief() + || rFont.IsShadow() + || bWordLineMode); + + if(bDecoratedIsNeeded) + { + // prepare overline, underline and srikeout data + const drawinglayer::primitive2d::TextLine eFontOverline(drawinglayer::primitive2d::mapFontUnderlineToTextLine(rFont.GetOverline())); + const drawinglayer::primitive2d::TextLine eFontUnderline(drawinglayer::primitive2d::mapFontUnderlineToTextLine(rFont.GetUnderline())); + const drawinglayer::primitive2d::TextStrikeout eTextStrikeout(drawinglayer::primitive2d::mapFontStrikeoutToTextStrikeout(rFont.GetStrikeout())); + + // check UndelineAbove + const bool bUnderlineAbove(drawinglayer::primitive2d::TEXT_LINE_NONE != eFontUnderline && isUnderlineAbove(rFont)); + + // prepare emphasis mark data + drawinglayer::primitive2d::TextEmphasisMark eTextEmphasisMark(drawinglayer::primitive2d::TEXT_EMPHASISMARK_NONE); + + switch(rFont.GetEmphasisMark() & EMPHASISMARK_STYLE) + { + case EMPHASISMARK_DOT : eTextEmphasisMark = drawinglayer::primitive2d::TEXT_EMPHASISMARK_DOT; break; + case EMPHASISMARK_CIRCLE : eTextEmphasisMark = drawinglayer::primitive2d::TEXT_EMPHASISMARK_CIRCLE; break; + case EMPHASISMARK_DISC : eTextEmphasisMark = drawinglayer::primitive2d::TEXT_EMPHASISMARK_DISC; break; + case EMPHASISMARK_ACCENT : eTextEmphasisMark = drawinglayer::primitive2d::TEXT_EMPHASISMARK_ACCENT; break; + } + + const bool bEmphasisMarkAbove(rFont.GetEmphasisMark() & EMPHASISMARK_POS_ABOVE); + const bool bEmphasisMarkBelow(rFont.GetEmphasisMark() & EMPHASISMARK_POS_BELOW); + + // prepare font relief data + drawinglayer::primitive2d::TextRelief eTextRelief(drawinglayer::primitive2d::TEXT_RELIEF_NONE); + + switch(rFont.GetRelief()) + { + case RELIEF_EMBOSSED : eTextRelief = drawinglayer::primitive2d::TEXT_RELIEF_EMBOSSED; break; + case RELIEF_ENGRAVED : eTextRelief = drawinglayer::primitive2d::TEXT_RELIEF_ENGRAVED; break; + default : break; // RELIEF_NONE, FontRelief_FORCE_EQUAL_SIZE + } + + // prepare shadow/outline data + const bool bShadow(rFont.IsShadow()); + + // TextDecoratedPortionPrimitive2D is needed, create one + pResult = new drawinglayer::primitive2d::TextDecoratedPortionPrimitive2D( + + // attributes for TextSimplePortionPrimitive2D + aTextTransform, + rText, + nTextStart, + nTextLength, + aDXArray, + aFontAttribute, + aLocale, + aFontColor, + + // attributes for TextDecoratedPortionPrimitive2D + rProperty.getOverlineColorActive() ? rProperty.getOverlineColor() : aFontColor, + rProperty.getTextLineColorActive() ? rProperty.getTextLineColor() : aFontColor, + eFontOverline, + eFontUnderline, + bUnderlineAbove, + eTextStrikeout, + bWordLineMode, + eTextEmphasisMark, + bEmphasisMarkAbove, + bEmphasisMarkBelow, + eTextRelief, + bShadow); + } + else + { + // TextSimplePortionPrimitive2D is enough + pResult = new drawinglayer::primitive2d::TextSimplePortionPrimitive2D( + aTextTransform, + rText, + nTextStart, + nTextLength, + aDXArray, + aFontAttribute, + aLocale, + aFontColor); + } + } + + if(pResult && rProperty.getTextFillColorActive()) + { + // text background is requested, add and encapsulate both to new primitive + drawinglayer::primitive2d::TextLayouterDevice aTextLayouterDevice; + aTextLayouterDevice.setFont(rFont); + + // get text width + double fTextWidth(0.0); + + if(aDXArray.empty()) + { + fTextWidth = aTextLayouterDevice.getTextWidth(rText, nTextStart, nTextLength); + } + else + { + fTextWidth = aDXArray.back(); + } + + if(basegfx::fTools::more(fTextWidth, 0.0)) + { + // build text range + const basegfx::B2DRange aTextRange( + 0.0, -aTextLayouterDevice.getFontAscent(), + fTextWidth, aTextLayouterDevice.getFontDescent()); + + // create Transform + basegfx::B2DHomMatrix aTextTransform; + + aTextTransform.translate(aAlignmentOffset.getX(), aAlignmentOffset.getY()); + + if(rFont.GetOrientation()) + { + aTextTransform.rotate(-rFont.GetOrientation() * F_PI1800); + } + + aTextTransform.translate(rTextStartPosition.X(), rTextStartPosition.Y()); + + // prepare Primitive2DSequence, put text in foreground + drawinglayer::primitive2d::Primitive2DSequence aSequence(2); + aSequence[1] = drawinglayer::primitive2d::Primitive2DReference(pResult); + + // prepare filled polygon + basegfx::B2DPolygon aOutline(basegfx::tools::createPolygonFromRect(aTextRange)); + aOutline.transform(aTextTransform); + + aSequence[0] = drawinglayer::primitive2d::Primitive2DReference( + new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D( + basegfx::B2DPolyPolygon(aOutline), + rProperty.getTextFillColor())); + + // set as group at pResult + pResult = new drawinglayer::primitive2d::GroupPrimitive2D(aSequence); + } + } + + if(pResult) + { + // add created text primitive to target + if(rProperty.getTransformation().isIdentity()) + { + rTarget.append(pResult); + } + else + { + // when a transformation is set, embed to it + const drawinglayer::primitive2d::Primitive2DReference aReference(pResult); + + rTarget.append( + new drawinglayer::primitive2d::TransformPrimitive2D( + rProperty.getTransformation(), + drawinglayer::primitive2d::Primitive2DSequence(&aReference, 1))); + } + } + } + + /** helper which takes complete care for creating the needed textLine primitives */ + void proccessMetaTextLineAction( + const MetaTextLineAction& rAction, + TargetHolder& rTarget, + PropertyHolder& rProperty) + { + const double fLineWidth(fabs((double)rAction.GetWidth())); + + if(fLineWidth > 0.0) + { + const drawinglayer::primitive2d::TextLine aOverlineMode(drawinglayer::primitive2d::mapFontUnderlineToTextLine(rAction.GetOverline())); + const drawinglayer::primitive2d::TextLine aUnderlineMode(drawinglayer::primitive2d::mapFontUnderlineToTextLine(rAction.GetUnderline())); + const drawinglayer::primitive2d::TextStrikeout aTextStrikeout(drawinglayer::primitive2d::mapFontStrikeoutToTextStrikeout(rAction.GetStrikeout())); + + const bool bOverlineUsed(drawinglayer::primitive2d::TEXT_LINE_NONE != aOverlineMode); + const bool bUnderlineUsed(drawinglayer::primitive2d::TEXT_LINE_NONE != aUnderlineMode); + const bool bStrikeoutUsed(drawinglayer::primitive2d::TEXT_STRIKEOUT_NONE != aTextStrikeout); + + if(bUnderlineUsed || bStrikeoutUsed || bOverlineUsed) + { + std::vector< drawinglayer::primitive2d::BasePrimitive2D* > aTargetVector; + basegfx::B2DVector aAlignmentOffset(0.0, 0.0); + drawinglayer::attribute::FontAttribute aFontAttribute; + basegfx::B2DHomMatrix aTextTransform; + + // fill parameters derived from current font + createFontAttributeTransformAndAlignment( + aFontAttribute, + aTextTransform, + aAlignmentOffset, + rProperty); + + // add TextStartPosition + aTextTransform.translate(rAction.GetStartPoint().X(), rAction.GetStartPoint().Y()); + + // prepare TextLayouter (used in most cases) + drawinglayer::primitive2d::TextLayouterDevice aTextLayouter; + aTextLayouter.setFont(rProperty.getFont()); + + if(bOverlineUsed) + { + // create primitive geometry for overline + aTargetVector.push_back( + new drawinglayer::primitive2d::TextLinePrimitive2D( + aTextTransform, + fLineWidth, + aTextLayouter.getOverlineOffset(), + aTextLayouter.getOverlineHeight(), + aOverlineMode, + rProperty.getOverlineColor())); + } + + if(bUnderlineUsed) + { + // create primitive geometry for underline + aTargetVector.push_back( + new drawinglayer::primitive2d::TextLinePrimitive2D( + aTextTransform, + fLineWidth, + aTextLayouter.getUnderlineOffset(), + aTextLayouter.getUnderlineHeight(), + aUnderlineMode, + rProperty.getTextLineColor())); + } + + if(bStrikeoutUsed) + { + // create primitive geometry for strikeout + if(drawinglayer::primitive2d::TEXT_STRIKEOUT_SLASH == aTextStrikeout + || drawinglayer::primitive2d::TEXT_STRIKEOUT_X == aTextStrikeout) + { + // strikeout with character + const sal_Unicode aStrikeoutChar( + drawinglayer::primitive2d::TEXT_STRIKEOUT_SLASH == aTextStrikeout ? '/' : 'X'); + const com::sun::star::lang::Locale aLocale(MsLangId::convertLanguageToLocale( + rProperty.getLanguageType())); + + aTargetVector.push_back( + new drawinglayer::primitive2d::TextCharacterStrikeoutPrimitive2D( + aTextTransform, + fLineWidth, + rProperty.getTextColor(), + aStrikeoutChar, + aFontAttribute, + aLocale)); + } + else + { + // strikeout with geometry + aTargetVector.push_back( + new drawinglayer::primitive2d::TextGeometryStrikeoutPrimitive2D( + aTextTransform, + fLineWidth, + rProperty.getTextColor(), + aTextLayouter.getUnderlineHeight(), + aTextLayouter.getStrikeoutOffset(), + aTextStrikeout)); + } + } + + if(aTargetVector.size()) + { + // add created text primitive to target + if(rProperty.getTransformation().isIdentity()) + { + for(sal_uInt32 a(0); a < aTargetVector.size(); a++) + { + rTarget.append(aTargetVector[a]); + } + } + else + { + // when a transformation is set, embed to it + drawinglayer::primitive2d::Primitive2DSequence xTargets(aTargetVector.size()); + + for(sal_uInt32 a(0); a < aTargetVector.size(); a++) + { + xTargets[a] = drawinglayer::primitive2d::Primitive2DReference(aTargetVector[a]); + } + + rTarget.append( + new drawinglayer::primitive2d::TransformPrimitive2D( + rProperty.getTransformation(), + xTargets)); + } + } + } + } + + } + + /** This is the main interpreter method. It is designed to handle the given Metafile + completely inside the given context and target. It may use and modify the context and + target. This design allows to call itself recursively wich adapted contexts and + targets as e.g. needed for the META_FLOATTRANSPARENT_ACTION where the content is expressed + as a metafile as sub-content. + + This interpreter is as free of VCL functionality as possible. It uses VCL data classes + (else reading the data would not be possible), but e.g. does NOT use a local OutputDevice + as most other MetaFile interpreters/exporters do to hold and work with the current context. + This is necessary to be able to get away from the strong internal VCL-binding. + + It tries to combine e.g. pixel and/or point actions and to stitch together single line primitives + where possible (which is not trivial with the possible line geometry definitions). + + It tries to handle clipping no longer as Regions and spans of Rectangles, but as PolyPolygon + ClipRegions with (where possible) high precision by using the best possible data quality + from the Region. The Region is unavoidable as data container, but nowadays allows the transport + of Polygon-based clip regions. Where this is not used, a Polygon is constructed from the + Region ranges. All primitive clipping uses the MaskPrimitive2D with Polygon-based clipping. + + I have marked the single MetaActions with: + + SIMPLE, DONE: + Simple, e.g nothing to do or value setting in the context + + CHECKED, WORKS WELL: + Thoroughly tested with extra written test code which created a replacement + Metafile just to test this action in various combinations + + NEEDS IMPLEMENTATION: + Not implemented and asserted, but also no usage found, neither in own Metafile + creations, nor in EMF/WMF imports (checked with a whole bunch of critical EMF/WMF + bugdocs) + + For more commens, see the single action implementations. + */ + void interpretMetafile( + const GDIMetaFile& rMetaFile, + TargetHolders& rTargetHolders, + PropertyHolders& rPropertyHolders, + const drawinglayer::geometry::ViewInformation2D& rViewInformation) + { + const sal_uInt32 nCount(rMetaFile.GetActionCount()); + + for(sal_uInt32 nAction(0); nAction < nCount; nAction++) + { + MetaAction* pAction = rMetaFile.GetAction(nAction); + + switch(pAction->GetType()) + { + case META_NULL_ACTION : + { + /** SIMPLE, DONE */ + break; + } + case META_PIXEL_ACTION : + { + /** CHECKED, WORKS WELL */ + std::vector< basegfx::B2DPoint > aPositions; + Color aLastColor(COL_BLACK); + + while(META_PIXEL_ACTION == pAction->GetType() && nAction < nCount) + { + const MetaPixelAction* pA = (const MetaPixelAction*)pAction; + + if(pA->GetColor() != aLastColor) + { + if(aPositions.size()) + { + createPointArrayPrimitive(aPositions, rTargetHolders.Current(), rPropertyHolders.Current(), aLastColor.getBColor()); + aPositions.clear(); + } + + aLastColor = pA->GetColor(); + } + + const Point& rPoint = pA->GetPoint(); + aPositions.push_back(basegfx::B2DPoint(rPoint.X(), rPoint.Y())); + nAction++; if(nAction < nCount) pAction = rMetaFile.GetAction(nAction); + } + + nAction--; + + if(aPositions.size()) + { + createPointArrayPrimitive(aPositions, rTargetHolders.Current(), rPropertyHolders.Current(), aLastColor.getBColor()); + } + + break; + } + case META_POINT_ACTION : + { + /** CHECKED, WORKS WELL */ + if(rPropertyHolders.Current().getLineColorActive()) + { + std::vector< basegfx::B2DPoint > aPositions; + + while(META_POINT_ACTION == pAction->GetType() && nAction < nCount) + { + const MetaPointAction* pA = (const MetaPointAction*)pAction; + const Point& rPoint = pA->GetPoint(); + aPositions.push_back(basegfx::B2DPoint(rPoint.X(), rPoint.Y())); + nAction++; if(nAction < nCount) pAction = rMetaFile.GetAction(nAction); + } + + nAction--; + + if(aPositions.size()) + { + createPointArrayPrimitive(aPositions, rTargetHolders.Current(), rPropertyHolders.Current(), rPropertyHolders.Current().getLineColor()); + } + } + + break; + } + case META_LINE_ACTION : + { + /** CHECKED, WORKS WELL */ + if(rPropertyHolders.Current().getLineColorActive()) + { + basegfx::B2DPolygon aLinePolygon; + LineInfo aLineInfo; + + while(META_LINE_ACTION == pAction->GetType() && nAction < nCount) + { + const MetaLineAction* pA = (const MetaLineAction*)pAction; + const Point& rStartPoint = pA->GetStartPoint(); + const Point& rEndPoint = pA->GetEndPoint(); + const basegfx::B2DPoint aStart(rStartPoint.X(), rStartPoint.Y()); + const basegfx::B2DPoint aEnd(rEndPoint.X(), rEndPoint.Y()); + + if(aLinePolygon.count()) + { + if(pA->GetLineInfo() == aLineInfo + && aStart == aLinePolygon.getB2DPoint(aLinePolygon.count() - 1)) + { + aLinePolygon.append(aEnd); + } + else + { + aLineInfo.SetLineJoin(basegfx::B2DLINEJOIN_NONE); // It were lines; force to NONE + createLinePrimitive(aLinePolygon, aLineInfo, rTargetHolders.Current(), rPropertyHolders.Current()); + aLinePolygon.clear(); + aLineInfo = pA->GetLineInfo(); + aLinePolygon.append(aStart); + aLinePolygon.append(aEnd); + } + } + else + { + aLineInfo = pA->GetLineInfo(); + aLinePolygon.append(aStart); + aLinePolygon.append(aEnd); + } + + nAction++; if(nAction < nCount) pAction = rMetaFile.GetAction(nAction); + } + + nAction--; + + if(aLinePolygon.count()) + { + aLineInfo.SetLineJoin(basegfx::B2DLINEJOIN_NONE); // It were lines; force to NONE + createLinePrimitive(aLinePolygon, aLineInfo, rTargetHolders.Current(), rPropertyHolders.Current()); + } + } + + break; + } + case META_RECT_ACTION : + { + /** CHECKED, WORKS WELL */ + if(rPropertyHolders.Current().getLineOrFillActive()) + { + const MetaRectAction* pA = (const MetaRectAction*)pAction; + const Rectangle& rRectangle = pA->GetRect(); + + if(!rRectangle.IsEmpty()) + { + const basegfx::B2DRange aRange(rRectangle.Left(), rRectangle.Top(), rRectangle.Right(), rRectangle.Bottom()); + + if(!aRange.isEmpty()) + { + const basegfx::B2DPolygon aOutline(basegfx::tools::createPolygonFromRect(aRange)); + createHairlineAndFillPrimitive(aOutline, rTargetHolders.Current(), rPropertyHolders.Current()); + } + } + } + + break; + } + case META_ROUNDRECT_ACTION : + { + /** CHECKED, WORKS WELL */ + /** The original OutputDevice::DrawRect paints nothing when nHor or nVer is zero; but just + because the tools::Polygon operator creating the rounding does produce nonsense. I assume + this an error and create an unrounded rectangle in that case (implicit in + createPolygonFromRect) + */ + if(rPropertyHolders.Current().getLineOrFillActive()) + { + const MetaRoundRectAction* pA = (const MetaRoundRectAction*)pAction; + const Rectangle& rRectangle = pA->GetRect(); + + if(!rRectangle.IsEmpty()) + { + const basegfx::B2DRange aRange(rRectangle.Left(), rRectangle.Top(), rRectangle.Right(), rRectangle.Bottom()); + + if(!aRange.isEmpty()) + { + const sal_uInt32 nHor(pA->GetHorzRound()); + const sal_uInt32 nVer(pA->GetVertRound()); + basegfx::B2DPolygon aOutline; + + if(nHor || nVer) + { + double fRadiusX((nHor * 2.0) / (aRange.getWidth() > 0.0 ? aRange.getWidth() : 1.0)); + double fRadiusY((nVer * 2.0) / (aRange.getHeight() > 0.0 ? aRange.getHeight() : 1.0)); + fRadiusX = std::max(0.0, std::min(1.0, fRadiusX)); + fRadiusY = std::max(0.0, std::min(1.0, fRadiusY)); + + aOutline = basegfx::tools::createPolygonFromRect(aRange, fRadiusX, fRadiusY); + } + else + { + aOutline = basegfx::tools::createPolygonFromRect(aRange); + } + + createHairlineAndFillPrimitive(aOutline, rTargetHolders.Current(), rPropertyHolders.Current()); + } + } + } + + break; + } + case META_ELLIPSE_ACTION : + { + /** CHECKED, WORKS WELL */ + if(rPropertyHolders.Current().getLineOrFillActive()) + { + const MetaEllipseAction* pA = (const MetaEllipseAction*)pAction; + const Rectangle& rRectangle = pA->GetRect(); + + if(!rRectangle.IsEmpty()) + { + const basegfx::B2DRange aRange(rRectangle.Left(), rRectangle.Top(), rRectangle.Right(), rRectangle.Bottom()); + + if(!aRange.isEmpty()) + { + const basegfx::B2DPolygon aOutline(basegfx::tools::createPolygonFromEllipse( + aRange.getCenter(), aRange.getWidth() * 0.5, aRange.getHeight() * 0.5)); + + createHairlineAndFillPrimitive(aOutline, rTargetHolders.Current(), rPropertyHolders.Current()); + } + } + } + + break; + } + case META_ARC_ACTION : + { + /** CHECKED, WORKS WELL */ + if(rPropertyHolders.Current().getLineColorActive()) + { + const MetaArcAction* pA = (const MetaArcAction*)pAction; + const Polygon aToolsPoly(pA->GetRect(), pA->GetStartPoint(), pA->GetEndPoint(), POLY_ARC); + const basegfx::B2DPolygon aOutline(aToolsPoly.getB2DPolygon()); + + createHairlinePrimitive(aOutline, rTargetHolders.Current(), rPropertyHolders.Current()); + } + + break; + } + case META_PIE_ACTION : + { + /** CHECKED, WORKS WELL */ + if(rPropertyHolders.Current().getLineOrFillActive()) + { + const MetaPieAction* pA = (const MetaPieAction*)pAction; + const Polygon aToolsPoly(pA->GetRect(), pA->GetStartPoint(), pA->GetEndPoint(), POLY_PIE); + const basegfx::B2DPolygon aOutline(aToolsPoly.getB2DPolygon()); + + createHairlineAndFillPrimitive(aOutline, rTargetHolders.Current(), rPropertyHolders.Current()); + } + + break; + } + case META_CHORD_ACTION : + { + /** CHECKED, WORKS WELL */ + if(rPropertyHolders.Current().getLineOrFillActive()) + { + const MetaChordAction* pA = (const MetaChordAction*)pAction; + const Polygon aToolsPoly(pA->GetRect(), pA->GetStartPoint(), pA->GetEndPoint(), POLY_CHORD); + const basegfx::B2DPolygon aOutline(aToolsPoly.getB2DPolygon()); + + createHairlineAndFillPrimitive(aOutline, rTargetHolders.Current(), rPropertyHolders.Current()); + } + + break; + } + case META_POLYLINE_ACTION : + { + /** CHECKED, WORKS WELL */ + if(rPropertyHolders.Current().getLineColorActive()) + { + const MetaPolyLineAction* pA = (const MetaPolyLineAction*)pAction; + createLinePrimitive(pA->GetPolygon().getB2DPolygon(), pA->GetLineInfo(), rTargetHolders.Current(), rPropertyHolders.Current()); + } + + break; + } + case META_POLYGON_ACTION : + { + /** CHECKED, WORKS WELL */ + if(rPropertyHolders.Current().getLineOrFillActive()) + { + const MetaPolygonAction* pA = (const MetaPolygonAction*)pAction; + basegfx::B2DPolygon aOutline(pA->GetPolygon().getB2DPolygon()); + + // the metafile play interprets the polygons from MetaPolygonAction + // always as closed and always paints an edge from last to first point, + // so force to closed here to emulate that + if(aOutline.count() > 1 && !aOutline.isClosed()) + { + aOutline.setClosed(true); + } + + createHairlineAndFillPrimitive(aOutline, rTargetHolders.Current(), rPropertyHolders.Current()); + } + + break; + } + case META_POLYPOLYGON_ACTION : + { + /** CHECKED, WORKS WELL */ + if(rPropertyHolders.Current().getLineOrFillActive()) + { + const MetaPolyPolygonAction* pA = (const MetaPolyPolygonAction*)pAction; + basegfx::B2DPolyPolygon aPolyPolygonOutline(pA->GetPolyPolygon().getB2DPolyPolygon()); + + // the metafile play interprets the single polygons from MetaPolyPolygonAction + // always as closed and always paints an edge from last to first point, + // so force to closed here to emulate that + for(sal_uInt32 b(0); b < aPolyPolygonOutline.count(); b++) + { + basegfx::B2DPolygon aPolygonOutline(aPolyPolygonOutline.getB2DPolygon(b)); + + if(aPolygonOutline.count() > 1 && !aPolygonOutline.isClosed()) + { + aPolygonOutline.setClosed(true); + aPolyPolygonOutline.setB2DPolygon(b, aPolygonOutline); + } + } + + createHairlineAndFillPrimitive(aPolyPolygonOutline, rTargetHolders.Current(), rPropertyHolders.Current()); + } + + break; + } + case META_TEXT_ACTION : + { + /** CHECKED, WORKS WELL */ + const MetaTextAction* pA = (const MetaTextAction*)pAction; + + if(pA->GetLen() && rPropertyHolders.Current().getTextColorActive()) + { + proccessMetaTextAction( + pA->GetPoint(), + pA->GetText(), + pA->GetIndex(), + pA->GetLen(), + 0, + rTargetHolders.Current(), + rPropertyHolders.Current()); + } + + break; + } + case META_TEXTARRAY_ACTION : + { + /** CHECKED, WORKS WELL */ + const MetaTextArrayAction* pA = (const MetaTextArrayAction*)pAction; + + if(pA->GetLen() && rPropertyHolders.Current().getTextColorActive()) + { + proccessMetaTextAction( + pA->GetPoint(), + pA->GetText(), + pA->GetIndex(), + pA->GetLen(), + pA->GetDXArray(), + rTargetHolders.Current(), + rPropertyHolders.Current()); + } + + break; + } + case META_STRETCHTEXT_ACTION : + { + /** NEEDS IMPLEMENTATION */ + OSL_ENSURE(false, "META_STRETCHTEXT_ACTION requested (!)"); + // use OutputDevice::GetTextArray() to map the... + // const MetaStretchTextAction* pA = (const MetaStretchTextAction*)pAction; + break; + } + case META_TEXTRECT_ACTION : + { + /** CHECKED, WORKS WELL */ + // OSL_ENSURE(false, "META_TEXTRECT_ACTION requested (!)"); + const MetaTextRectAction* pA = (const MetaTextRectAction*)pAction; + const Rectangle& rRectangle = pA->GetRect(); + + if(!rRectangle.IsEmpty() && 0 != pA->GetText().Len()) + { + // The problem with this action is that it describes unlayouted text + // and the layout capabilities are in EditEngine/Outliner in SVX. The + // same problem is true for VCL which internally has implementations + // to layout text in this case. There exists even a call + // OutputDevice::AddTextRectActions(...) to create the needed actions + // as 'sub-content' of a Metafile. Unfortunately i do not have an + // OutputDevice here since this interpreter tries to work without + // VCL AFAP. + // Since AddTextRectActions is the only way as long as we do not have + // a simple text layouter available, i will try to add it to the + // TextLayouterDevice isloation. + drawinglayer::primitive2d::TextLayouterDevice aTextLayouterDevice; + aTextLayouterDevice.setFont(rPropertyHolders.Current().getFont()); + GDIMetaFile aGDIMetaFile; + + aTextLayouterDevice.addTextRectActions( + rRectangle, pA->GetText(), pA->GetStyle(), aGDIMetaFile); + + if(aGDIMetaFile.GetActionCount()) + { + // cerate sub-content + drawinglayer::primitive2d::Primitive2DSequence xSubContent; + { + rTargetHolders.Push(); + interpretMetafile(aGDIMetaFile, rTargetHolders, rPropertyHolders, rViewInformation); + xSubContent = rTargetHolders.Current().getPrimitive2DSequence(rPropertyHolders.Current()); + rTargetHolders.Pop(); + } + + if(xSubContent.hasElements()) + { + // add with transformation + rTargetHolders.Current().append( + new drawinglayer::primitive2d::TransformPrimitive2D( + rPropertyHolders.Current().getTransformation(), + xSubContent)); + } + } + } + + break; + } + case META_BMP_ACTION : + { + /** CHECKED, WORKS WELL */ + const MetaBmpAction* pA = (const MetaBmpAction*)pAction; + const BitmapEx aBitmapEx(pA->GetBitmap()); + + createBitmapExPrimitive(aBitmapEx, pA->GetPoint(), rTargetHolders.Current(), rPropertyHolders.Current()); + + break; + } + case META_BMPSCALE_ACTION : + { + /** CHECKED, WORKS WELL */ + const MetaBmpScaleAction* pA = (const MetaBmpScaleAction*)pAction; + const Bitmap aBitmapEx(pA->GetBitmap()); + + createBitmapExPrimitive(aBitmapEx, pA->GetPoint(), pA->GetSize(), rTargetHolders.Current(), rPropertyHolders.Current()); + + break; + } + case META_BMPSCALEPART_ACTION : + { + /** CHECKED, WORKS WELL */ + const MetaBmpScalePartAction* pA = (const MetaBmpScalePartAction*)pAction; + const Bitmap& rBitmap = pA->GetBitmap(); + + if(!rBitmap.IsEmpty()) + { + Bitmap aCroppedBitmap(rBitmap); + const Rectangle aCropRectangle(pA->GetSrcPoint(), pA->GetSrcSize()); + + if(!aCropRectangle.IsEmpty()) + { + aCroppedBitmap.Crop(aCropRectangle); + } + + const BitmapEx aCroppedBitmapEx(aCroppedBitmap); + createBitmapExPrimitive(aCroppedBitmapEx, pA->GetDestPoint(), pA->GetDestSize(), rTargetHolders.Current(), rPropertyHolders.Current()); + } + + break; + } + case META_BMPEX_ACTION : + { + /** CHECKED, WORKS WELL: Simply same as META_BMP_ACTION */ + const MetaBmpExAction* pA = (const MetaBmpExAction*)pAction; + const BitmapEx& rBitmapEx = pA->GetBitmapEx(); + + createBitmapExPrimitive(rBitmapEx, pA->GetPoint(), rTargetHolders.Current(), rPropertyHolders.Current()); + + break; + } + case META_BMPEXSCALE_ACTION : + { + /** CHECKED, WORKS WELL: Simply same as META_BMPSCALE_ACTION */ + const MetaBmpExScaleAction* pA = (const MetaBmpExScaleAction*)pAction; + const BitmapEx& rBitmapEx = pA->GetBitmapEx(); + + createBitmapExPrimitive(rBitmapEx, pA->GetPoint(), pA->GetSize(), rTargetHolders.Current(), rPropertyHolders.Current()); + + break; + } + case META_BMPEXSCALEPART_ACTION : + { + /** CHECKED, WORKS WELL: Simply same as META_BMPSCALEPART_ACTION */ + const MetaBmpExScalePartAction* pA = (const MetaBmpExScalePartAction*)pAction; + const BitmapEx& rBitmapEx = pA->GetBitmapEx(); + + if(!rBitmapEx.IsEmpty()) + { + BitmapEx aCroppedBitmapEx(rBitmapEx); + const Rectangle aCropRectangle(pA->GetSrcPoint(), pA->GetSrcSize()); + + if(!aCropRectangle.IsEmpty()) + { + aCroppedBitmapEx.Crop(aCropRectangle); + } + + createBitmapExPrimitive(aCroppedBitmapEx, pA->GetDestPoint(), pA->GetDestSize(), rTargetHolders.Current(), rPropertyHolders.Current()); + } + + break; + } + case META_MASK_ACTION : + { + /** CHECKED, WORKS WELL: Simply same as META_BMP_ACTION */ + const MetaMaskAction* pA = (const MetaMaskAction*)pAction; + const BitmapEx aBitmapEx(createMaskBmpEx(pA->GetBitmap(), pA->GetColor())); + + createBitmapExPrimitive(aBitmapEx, pA->GetPoint(), rTargetHolders.Current(), rPropertyHolders.Current()); + + break; + } + case META_MASKSCALE_ACTION : + { + /** CHECKED, WORKS WELL: Simply same as META_BMPSCALE_ACTION */ + const MetaMaskScaleAction* pA = (const MetaMaskScaleAction*)pAction; + const BitmapEx aBitmapEx(createMaskBmpEx(pA->GetBitmap(), pA->GetColor())); + + createBitmapExPrimitive(aBitmapEx, pA->GetPoint(), pA->GetSize(), rTargetHolders.Current(), rPropertyHolders.Current()); + + break; + } + case META_MASKSCALEPART_ACTION : + { + /** CHECKED, WORKS WELL: Simply same as META_BMPSCALEPART_ACTION */ + const MetaMaskScalePartAction* pA = (const MetaMaskScalePartAction*)pAction; + const Bitmap& rBitmap = pA->GetBitmap(); + + if(!rBitmap.IsEmpty()) + { + Bitmap aCroppedBitmap(rBitmap); + const Rectangle aCropRectangle(pA->GetSrcPoint(), pA->GetSrcSize()); + + if(!aCropRectangle.IsEmpty()) + { + aCroppedBitmap.Crop(aCropRectangle); + } + + const BitmapEx aCroppedBitmapEx(createMaskBmpEx(aCroppedBitmap, pA->GetColor())); + createBitmapExPrimitive(aCroppedBitmapEx, pA->GetDestPoint(), pA->GetDestSize(), rTargetHolders.Current(), rPropertyHolders.Current()); + } + + break; + } + case META_GRADIENT_ACTION : + { + /** CHECKED, WORKS WELL */ + const MetaGradientAction* pA = (const MetaGradientAction*)pAction; + const Rectangle& rRectangle = pA->GetRect(); + + if(!rRectangle.IsEmpty()) + { + basegfx::B2DRange aRange(rRectangle.Left(), rRectangle.Top(), rRectangle.Right(), rRectangle.Bottom()); + + if(!aRange.isEmpty()) + { + const Gradient& rGradient = pA->GetGradient(); + const drawinglayer::attribute::FillGradientAttribute aAttribute(createFillGradientAttribute(rGradient)); + + if(aAttribute.getStartColor() == aAttribute.getEndColor()) + { + // not really a gradient. Create filled rectangle + const basegfx::B2DPolygon aOutline(basegfx::tools::createPolygonFromRect(aRange)); + createFillPrimitive(basegfx::B2DPolyPolygon(aOutline), rTargetHolders.Current(), rPropertyHolders.Current()); + } + else + { + // really a gradient + aRange.transform(rPropertyHolders.Current().getTransformation()); + + if(rPropertyHolders.Current().isRasterOpInvert()) + { + // use a special version of FillGradientPrimitive2D which creates + // non-overlapping geometry on decomposition to makethe old XOR + // paint 'trick' work. + rTargetHolders.Current().append( + new drawinglayer::primitive2d::NonOverlappingFillGradientPrimitive2D( + aRange, + aAttribute)); + } + else + { + rTargetHolders.Current().append( + new drawinglayer::primitive2d::FillGradientPrimitive2D( + aRange, + aAttribute)); + } + } + } + } + + break; + } + case META_HATCH_ACTION : + { + /** CHECKED, WORKS WELL */ + const MetaHatchAction* pA = (const MetaHatchAction*)pAction; + basegfx::B2DPolyPolygon aOutline(pA->GetPolyPolygon().getB2DPolyPolygon()); + + if(aOutline.count()) + { + const Hatch& rHatch = pA->GetHatch(); + const drawinglayer::attribute::FillHatchAttribute aAttribute(createFillHatchAttribute(rHatch)); + + aOutline.transform(rPropertyHolders.Current().getTransformation()); + + const basegfx::B2DRange aObjectRange(aOutline.getB2DRange()); + const drawinglayer::primitive2d::Primitive2DReference aFillHatch( + new drawinglayer::primitive2d::FillHatchPrimitive2D( + aObjectRange, + basegfx::BColor(), + aAttribute)); + + rTargetHolders.Current().append( + new drawinglayer::primitive2d::MaskPrimitive2D( + aOutline, + drawinglayer::primitive2d::Primitive2DSequence(&aFillHatch, 1))); + } + + break; + } + case META_WALLPAPER_ACTION : + { + /** CHECKED, WORKS WELL */ + const MetaWallpaperAction* pA = (const MetaWallpaperAction*)pAction; + Rectangle aWallpaperRectangle(pA->GetRect()); + + if(!aWallpaperRectangle.IsEmpty()) + { + const Wallpaper& rWallpaper = pA->GetWallpaper(); + const WallpaperStyle eWallpaperStyle(rWallpaper.GetStyle()); + basegfx::B2DRange aWallpaperRange( + aWallpaperRectangle.Left(), aWallpaperRectangle.Top(), + aWallpaperRectangle.Right(), aWallpaperRectangle.Bottom()); + + if(WALLPAPER_NULL != eWallpaperStyle) + { + if(rWallpaper.IsBitmap()) + { + // create bitmap background. Caution: This + // also will create gradient/color background(s) + // when the bitmap is transparent or not tiled + CreateAndAppendBitmapWallpaper( + aWallpaperRange, + rWallpaper, + rTargetHolders.Current(), + rPropertyHolders.Current()); + } + else if(rWallpaper.IsGradient()) + { + // create gradient background + rTargetHolders.Current().append( + CreateGradientWallpaper( + aWallpaperRange, + rWallpaper.GetGradient(), + rPropertyHolders.Current())); + } + else if(!rWallpaper.GetColor().GetTransparency()) + { + // create color background + rTargetHolders.Current().append( + CreateColorWallpaper( + aWallpaperRange, + rWallpaper.GetColor().getBColor(), + rPropertyHolders.Current())); + } + } + } + + break; + } + case META_CLIPREGION_ACTION : + { + /** CHECKED, WORKS WELL */ + const MetaClipRegionAction* pA = (const MetaClipRegionAction*)pAction; + + if(pA->IsClipping()) + { + // new clipping + HandleNewClipRegion(&pA->GetRegion(), rTargetHolders, rPropertyHolders); + } + else + { + // end clipping + HandleNewClipRegion(0, rTargetHolders, rPropertyHolders); + } + + break; + } + case META_ISECTRECTCLIPREGION_ACTION : + { + /** CHECKED, WORKS WELL */ + const MetaISectRectClipRegionAction* pA = (const MetaISectRectClipRegionAction*)pAction; + const Rectangle& rRectangle = pA->GetRect(); + + if(rRectangle.IsEmpty()) + { + // intersect with empty rectangle will always give empty + // region; start new clipping with empty region + const Region aNewRegion; + HandleNewClipRegion(&aNewRegion, rTargetHolders, rPropertyHolders); + } + else + { + if(rPropertyHolders.Current().getRegionActive()) + { + if(rPropertyHolders.Current().getRegion().IsEmpty()) + { + // nothing to do, empty active clip region will stay + // empty when intersecting + } + else + { + // AND existing region and new rectangle + const basegfx::B2DPolyPolygon aOriginalPolyPolygon( + getB2DPolyPolygonFromRegion(rPropertyHolders.Current().getRegion())); + basegfx::B2DPolyPolygon aClippedPolyPolygon; + + if(aOriginalPolyPolygon.count()) + { + const basegfx::B2DRange aIntersectRange( + rRectangle.Left(), rRectangle.Top(), + rRectangle.Right(), rRectangle.Bottom()); + + aClippedPolyPolygon = basegfx::tools::clipPolyPolygonOnRange( + aOriginalPolyPolygon, aIntersectRange, true, false); + } + + if(aClippedPolyPolygon != aOriginalPolyPolygon) + { + // start new clipping with intersected region + const Region aNewRegion(aClippedPolyPolygon); + HandleNewClipRegion(&aNewRegion, rTargetHolders, rPropertyHolders); + } + } + } + else + { + // start new clipping with rectangle + const Region aNewRegion(rRectangle); + HandleNewClipRegion(&aNewRegion, rTargetHolders, rPropertyHolders); + } + } + + break; + } + case META_ISECTREGIONCLIPREGION_ACTION : + { + /** CHECKED, WORKS WELL */ + const MetaISectRegionClipRegionAction* pA = (const MetaISectRegionClipRegionAction*)pAction; + const Region& rNewRegion = pA->GetRegion(); + + if(rNewRegion.IsEmpty()) + { + // intersect with empty region will always give empty + // region; start new clipping with empty region + const Region aNewRegion; + HandleNewClipRegion(&aNewRegion, rTargetHolders, rPropertyHolders); + } + else + { + if(rPropertyHolders.Current().getRegionActive()) + { + if(rPropertyHolders.Current().getRegion().IsEmpty()) + { + // nothing to do, empty active clip region will stay empty + // when intersecting with any region + } + else + { + // AND existing and new region + const basegfx::B2DPolyPolygon aOriginalPolyPolygon( + getB2DPolyPolygonFromRegion(rPropertyHolders.Current().getRegion())); + basegfx::B2DPolyPolygon aClippedPolyPolygon; + + if(aOriginalPolyPolygon.count()) + { + const basegfx::B2DPolyPolygon aClipPolyPolygon( + getB2DPolyPolygonFromRegion(rNewRegion)); + + if(aClipPolyPolygon.count()) + { + aClippedPolyPolygon = basegfx::tools::clipPolyPolygonOnPolyPolygon( + aOriginalPolyPolygon, aClipPolyPolygon, true, false); + } + } + + if(aClippedPolyPolygon != aOriginalPolyPolygon) + { + // start new clipping with intersected region + const Region aNewRegion(aClippedPolyPolygon); + HandleNewClipRegion(&aNewRegion, rTargetHolders, rPropertyHolders); + } + } + } + else + { + // start new clipping with new region + HandleNewClipRegion(&rNewRegion, rTargetHolders, rPropertyHolders); + } + } + + break; + } + case META_MOVECLIPREGION_ACTION : + { + /** CHECKED, WORKS WELL */ + const MetaMoveClipRegionAction* pA = (const MetaMoveClipRegionAction*)pAction; + + if(rPropertyHolders.Current().getRegionActive()) + { + if(rPropertyHolders.Current().getRegion().IsEmpty()) + { + // nothing to do + } + else + { + // move using old interface + Region aRegion(rPropertyHolders.Current().getRegion()); + + const sal_Int32 nHor(pA->GetHorzMove()); + const sal_Int32 nVer(pA->GetVertMove()); + + if(0 != nHor || 0 != nVer) + { + aRegion.Move(nHor, nVer); + HandleNewClipRegion(&aRegion, rTargetHolders, rPropertyHolders); + } + } + } + + break; + } + case META_LINECOLOR_ACTION : + { + /** CHECKED, WORKS WELL */ + const MetaLineColorAction* pA = (const MetaLineColorAction*)pAction; + const bool bActive(pA->IsSetting()); + + rPropertyHolders.Current().setLineColorActive(bActive); + if(bActive) + rPropertyHolders.Current().setLineColor(pA->GetColor().getBColor()); + + break; + } + case META_FILLCOLOR_ACTION : + { + /** CHECKED, WORKS WELL */ + const MetaFillColorAction* pA = (const MetaFillColorAction*)pAction; + const bool bActive(pA->IsSetting()); + + rPropertyHolders.Current().setFillColorActive(bActive); + if(bActive) + rPropertyHolders.Current().setFillColor(pA->GetColor().getBColor()); + + break; + } + case META_TEXTCOLOR_ACTION : + { + /** SIMPLE, DONE */ + const MetaTextColorAction* pA = (const MetaTextColorAction*)pAction; + const bool bActivate(COL_TRANSPARENT != pA->GetColor().GetColor()); + + rPropertyHolders.Current().setTextColorActive(bActivate); + rPropertyHolders.Current().setTextColor(pA->GetColor().getBColor()); + + break; + } + case META_TEXTFILLCOLOR_ACTION : + { + /** SIMPLE, DONE */ + const MetaTextFillColorAction* pA = (const MetaTextFillColorAction*)pAction; + const bool bWithColorArgument(pA->IsSetting()); + + if(bWithColorArgument) + { + // emulate OutputDevice::SetTextFillColor(...) WITH argument + const Color& rFontFillColor = pA->GetColor(); + rPropertyHolders.Current().setTextFillColor(rFontFillColor.getBColor()); + rPropertyHolders.Current().setTextFillColorActive(COL_TRANSPARENT != rFontFillColor.GetColor()); + } + else + { + // emulate SetFillColor() <- NO argument (!) + rPropertyHolders.Current().setTextFillColorActive(false); + } + + break; + } + case META_TEXTALIGN_ACTION : + { + /** SIMPLE, DONE */ + const MetaTextAlignAction* pA = (const MetaTextAlignAction*)pAction; + const TextAlign aNewTextAlign = pA->GetTextAlign(); + + // TextAlign is applied to the current font (as in + // OutputDevice::SetTextAlign which would be used when + // playing the Metafile) + if(rPropertyHolders.Current().getFont().GetAlign() != aNewTextAlign) + { + Font aNewFont(rPropertyHolders.Current().getFont()); + aNewFont.SetAlign(aNewTextAlign); + rPropertyHolders.Current().setFont(aNewFont); + } + + break; + } + case META_MAPMODE_ACTION : + { + /** CHECKED, WORKS WELL */ + // the most necessary MapMode to be interpreted is MAP_RELATIVE, + // but also the others may occur. Even not yet supported ones + // may need to be added here later + const MetaMapModeAction* pA = (const MetaMapModeAction*)pAction; + const MapMode& rMapMode = pA->GetMapMode(); + basegfx::B2DHomMatrix aMapping; + + if(MAP_RELATIVE == rMapMode.GetMapUnit()) + { + aMapping = getTransformFromMapMode(rMapMode); + } + else + { + switch(rMapMode.GetMapUnit()) + { + case MAP_100TH_MM : + { + if(MAP_TWIP == rPropertyHolders.Current().getMapUnit()) + { + // MAP_TWIP -> MAP_100TH_MM + const double fTwipTo100thMm(127.0 / 72.0); + aMapping.scale(fTwipTo100thMm, fTwipTo100thMm); + } + break; + } + case MAP_TWIP : + { + if(MAP_100TH_MM == rPropertyHolders.Current().getMapUnit()) + { + // MAP_100TH_MM -> MAP_TWIP + const double f100thMmToTwip(72.0 / 127.0); + aMapping.scale(f100thMmToTwip, f100thMmToTwip); + } + break; + } + default : + { + OSL_ENSURE(false, "interpretMetafile: META_MAPMODE_ACTION with unsupported MapUnit (!)"); + break; + } + } + + aMapping = getTransformFromMapMode(rMapMode) * aMapping; + rPropertyHolders.Current().setMapUnit(rMapMode.GetMapUnit()); + } + + if(!aMapping.isIdentity()) + { + aMapping = aMapping * rPropertyHolders.Current().getTransformation(); + rPropertyHolders.Current().setTransformation(aMapping); + } + + break; + } + case META_FONT_ACTION : + { + /** SIMPLE, DONE */ + const MetaFontAction* pA = (const MetaFontAction*)pAction; + rPropertyHolders.Current().setFont(pA->GetFont()); + Size aFontSize(pA->GetFont().GetSize()); + + if(0 == aFontSize.Height()) + { + // this should not happen but i got Metafiles where this was the + // case. A height needs to be guessed (similar to OutputDevice::ImplNewFont()) + Font aCorrectedFont(pA->GetFont()); + + // guess 16 pixel (as in VCL) + aFontSize = Size(0, 16); + + // convert to target MapUnit if not pixels + aFontSize = Application::GetDefaultDevice()->LogicToLogic( + aFontSize, MAP_PIXEL, rPropertyHolders.Current().getMapUnit()); + + aCorrectedFont.SetSize(aFontSize); + rPropertyHolders.Current().setFont(aCorrectedFont); + } + + // older Metafiles have no META_TEXTCOLOR_ACTION which defines + // the FontColor now, so use the Font's color when not transparent + const Color& rFontColor = pA->GetFont().GetColor(); + const bool bActivate(COL_TRANSPARENT != rFontColor.GetColor()); + + if(bActivate) + { + rPropertyHolders.Current().setTextColor(rFontColor.getBColor()); + } + + // caution: do NOT decativate here on transparet, see + // OutputDevice::SetFont(..) for more info + // rPropertyHolders.Current().setTextColorActive(bActivate); + + // for fill color emulate a MetaTextFillColorAction with !transparent as bool, + // see OutputDevice::SetFont(..) the if(mpMetaFile) case + if(bActivate) + { + const Color& rFontFillColor = pA->GetFont().GetFillColor(); + rPropertyHolders.Current().setTextFillColor(rFontFillColor.getBColor()); + rPropertyHolders.Current().setTextFillColorActive(COL_TRANSPARENT != rFontFillColor.GetColor()); + } + else + { + rPropertyHolders.Current().setTextFillColorActive(false); + } + + break; + } + case META_PUSH_ACTION : + { + /** CHECKED, WORKS WELL */ + const MetaPushAction* pA = (const MetaPushAction*)pAction; + rPropertyHolders.Push(pA->GetFlags()); + + break; + } + case META_POP_ACTION : + { + /** CHECKED, WORKS WELL */ + const bool bRegionMayChange(rPropertyHolders.Current().getPushFlags() & PUSH_CLIPREGION); + const bool bRasterOpMayChange(rPropertyHolders.Current().getPushFlags() & PUSH_RASTEROP); + + if(bRegionMayChange && rPropertyHolders.Current().getRegionActive()) + { + // end evtl. clipping + HandleNewClipRegion(0, rTargetHolders, rPropertyHolders); + } + + if(bRasterOpMayChange && rPropertyHolders.Current().isRasterOpActive()) + { + // end evtl. RasterOp + HandleNewRasterOp(ROP_OVERPAINT, rTargetHolders, rPropertyHolders); + } + + rPropertyHolders.Pop(); + + if(bRasterOpMayChange && rPropertyHolders.Current().isRasterOpActive()) + { + // start evtl. RasterOp + HandleNewRasterOp(rPropertyHolders.Current().getRasterOp(), rTargetHolders, rPropertyHolders); + } + + if(bRegionMayChange && rPropertyHolders.Current().getRegionActive()) + { + // start evtl. clipping + HandleNewClipRegion(&rPropertyHolders.Current().getRegion(), rTargetHolders, rPropertyHolders); + } + + break; + } + case META_RASTEROP_ACTION : + { + /** CHECKED, WORKS WELL */ + const MetaRasterOpAction* pA = (const MetaRasterOpAction*)pAction; + const RasterOp aRasterOp = pA->GetRasterOp(); + + HandleNewRasterOp(aRasterOp, rTargetHolders, rPropertyHolders); + + break; + } + case META_TRANSPARENT_ACTION : + { + /** CHECKED, WORKS WELL */ + const MetaTransparentAction* pA = (const MetaTransparentAction*)pAction; + const basegfx::B2DPolyPolygon aOutline(pA->GetPolyPolygon().getB2DPolyPolygon()); + + if(aOutline.count()) + { + const sal_uInt16 nTransparence(pA->GetTransparence()); + + if(0 == nTransparence) + { + // not transparent + createHairlineAndFillPrimitive(aOutline, rTargetHolders.Current(), rPropertyHolders.Current()); + } + else if(nTransparence >= 100) + { + // fully or more than transparent + } + else + { + // transparent. Create new target + rTargetHolders.Push(); + + // create primitives there and get them + createHairlineAndFillPrimitive(aOutline, rTargetHolders.Current(), rPropertyHolders.Current()); + const drawinglayer::primitive2d::Primitive2DSequence aSubContent( + rTargetHolders.Current().getPrimitive2DSequence(rPropertyHolders.Current())); + + // back to old target + rTargetHolders.Pop(); + + if(aSubContent.hasElements()) + { + rTargetHolders.Current().append( + new drawinglayer::primitive2d::UnifiedAlphaPrimitive2D( + aSubContent, + nTransparence * 0.01)); + } + } + } + + break; + } + case META_EPS_ACTION : + { + /** CHECKED, WORKS WELL */ + // To support this action, i have added a EpsPrimitive2D which will + // by default decompose to the Metafile replacement data. To support + // this EPS on screen, the renderer visualizing this has to support + // that primitive and visualize the Eps file (e.g. printing) + const MetaEPSAction* pA = (const MetaEPSAction*)pAction; + const Rectangle aRectangle(pA->GetPoint(), pA->GetSize()); + + if(!aRectangle.IsEmpty()) + { + // create object transform + basegfx::B2DHomMatrix aObjectTransform; + + aObjectTransform.set(0, 0, aRectangle.GetWidth()); + aObjectTransform.set(1, 1, aRectangle.GetHeight()); + aObjectTransform.set(0, 2, aRectangle.Left()); + aObjectTransform.set(1, 2, aRectangle.Top()); + + // add current transformation + aObjectTransform = rPropertyHolders.Current().getTransformation() * aObjectTransform; + + // embed using EpsPrimitive + rTargetHolders.Current().append( + new drawinglayer::primitive2d::EpsPrimitive2D( + aObjectTransform, + pA->GetLink(), + pA->GetSubstitute())); + } + + break; + } + case META_REFPOINT_ACTION : + { + /** SIMPLE, DONE */ + // only used for hatch and line pattern offsets, pretty much no longer + // supported today + // const MetaRefPointAction* pA = (const MetaRefPointAction*)pAction; + break; + } + case META_TEXTLINECOLOR_ACTION : + { + /** SIMPLE, DONE */ + const MetaTextLineColorAction* pA = (const MetaTextLineColorAction*)pAction; + const bool bActive(pA->IsSetting()); + + rPropertyHolders.Current().setTextLineColorActive(bActive); + if(bActive) + rPropertyHolders.Current().setTextLineColor(pA->GetColor().getBColor()); + + break; + } + case META_TEXTLINE_ACTION : + { + /** CHECKED, WORKS WELL */ + // actually creates overline, underline and strikeouts, so + // these should be isolated from TextDecoratedPortionPrimitive2D + // to own primitives. Done, available now. + // + // This Metaaction seems not to be used (was not used in any + // checked files). It's used in combination with the current + // Font. + const MetaTextLineAction* pA = (const MetaTextLineAction*)pAction; + + proccessMetaTextLineAction( + *pA, + rTargetHolders.Current(), + rPropertyHolders.Current()); + + break; + } + case META_FLOATTRANSPARENT_ACTION : + { + /** CHECKED, WORKS WELL */ + const MetaFloatTransparentAction* pA = (const MetaFloatTransparentAction*)pAction; + const Rectangle aTargetRectangle(pA->GetPoint(), pA->GetSize()); + + if(!aTargetRectangle.IsEmpty()) + { + const GDIMetaFile& rContent = pA->GetGDIMetaFile(); + + if(rContent.GetActionCount()) + { + // create the sub-content with no embedding specific to the + // sub-metafile, this seems not to be used. + drawinglayer::primitive2d::Primitive2DSequence xSubContent; + { + rTargetHolders.Push(); + interpretMetafile(rContent, rTargetHolders, rPropertyHolders, rViewInformation); + xSubContent = rTargetHolders.Current().getPrimitive2DSequence(rPropertyHolders.Current()); + rTargetHolders.Pop(); + } + + if(xSubContent.hasElements()) + { + // check if gradient is a real gradient + const Gradient& rGradient = pA->GetGradient(); + const drawinglayer::attribute::FillGradientAttribute aAttribute(createFillGradientAttribute(rGradient)); + + if(aAttribute.getStartColor() == aAttribute.getEndColor()) + { + // not really a gradient; create UnifiedAlphaPrimitive2D + rTargetHolders.Current().append( + new drawinglayer::primitive2d::UnifiedAlphaPrimitive2D( + xSubContent, + aAttribute.getStartColor().luminance())); + } + else + { + // really a gradient. Create gradient sub-content (with correct scaling) + basegfx::B2DRange aRange( + aTargetRectangle.Left(), aTargetRectangle.Top(), + aTargetRectangle.Right(), aTargetRectangle.Bottom()); + aRange.transform(rPropertyHolders.Current().getTransformation()); + + // prepare gradient for alpha content + const drawinglayer::primitive2d::Primitive2DReference xAlpha( + new drawinglayer::primitive2d::FillGradientPrimitive2D( + aRange, + aAttribute)); + + // create alpha primitive + rTargetHolders.Current().append( + new drawinglayer::primitive2d::AlphaPrimitive2D( + xSubContent, + drawinglayer::primitive2d::Primitive2DSequence(&xAlpha, 1))); + } + } + } + } + + break; + } + case META_GRADIENTEX_ACTION : + { + /** SIMPLE, DONE */ + // This is only a data holder which is interpreted inside comment actions, + // see META_COMMENT_ACTION for more info + // const MetaGradientExAction* pA = (const MetaGradientExAction*)pAction; + break; + } + case META_LAYOUTMODE_ACTION : + { + /** SIMPLE, DONE */ + const MetaLayoutModeAction* pA = (const MetaLayoutModeAction*)pAction; + rPropertyHolders.Current().setLayoutMode(pA->GetLayoutMode()); + break; + } + case META_TEXTLANGUAGE_ACTION : + { + /** SIMPLE, DONE */ + const MetaTextLanguageAction* pA = (const MetaTextLanguageAction*)pAction; + rPropertyHolders.Current().setLanguageType(pA->GetTextLanguage()); + break; + } + case META_OVERLINECOLOR_ACTION : + { + /** SIMPLE, DONE */ + const MetaOverlineColorAction* pA = (const MetaOverlineColorAction*)pAction; + const bool bActive(pA->IsSetting()); + + rPropertyHolders.Current().setOverlineColorActive(bActive); + if(bActive) + rPropertyHolders.Current().setOverlineColor(pA->GetColor().getBColor()); + + break; + } + case META_COMMENT_ACTION : + { + /** CHECKED, WORKS WELL */ + // I already implemented + // XPATHFILL_SEQ_BEGIN, XPATHFILL_SEQ_END + // XPATHSTROKE_SEQ_BEGIN, XPATHSTROKE_SEQ_END, + // but opted to remove these again; it works well without them + // and makes the code less dependent from those Metafile Add-Ons + const MetaCommentAction* pA = (const MetaCommentAction*)pAction; + + if(COMPARE_EQUAL == pA->GetComment().CompareIgnoreCaseToAscii("XGRAD_SEQ_BEGIN")) + { + // XGRAD_SEQ_BEGIN, XGRAD_SEQ_END should be supported since the + // pure recorded paint of the gradients uses the XOR paint functionality + // ('trick'). This is (and will be) broblematic with AntAliasing, so it's + // better to use this info + const MetaGradientExAction* pMetaGradientExAction = 0; + bool bDone(false); + sal_uInt32 b(nAction + 1); + + for(; !bDone && b < nCount; b++) + { + pAction = rMetaFile.GetAction(b); + + if(META_GRADIENTEX_ACTION == pAction->GetType()) + { + pMetaGradientExAction = (const MetaGradientExAction*)pAction; + } + else if(META_COMMENT_ACTION == pAction->GetType()) + { + if(COMPARE_EQUAL == ((const MetaCommentAction*)pAction)->GetComment().CompareIgnoreCaseToAscii("XGRAD_SEQ_END")) + { + bDone = true; + } + } + } + + if(bDone && pMetaGradientExAction) + { + // consume actions and skip forward + nAction = b - 1; + + // get geometry data + basegfx::B2DPolyPolygon aPolyPolygon(pMetaGradientExAction->GetPolyPolygon().getB2DPolyPolygon()); + + if(aPolyPolygon.count()) + { + // transform geometry + aPolyPolygon.transform(rPropertyHolders.Current().getTransformation()); + + // get and check if gradient is a real gradient + const Gradient& rGradient = pMetaGradientExAction->GetGradient(); + const drawinglayer::attribute::FillGradientAttribute aAttribute(createFillGradientAttribute(rGradient)); + + if(aAttribute.getStartColor() == aAttribute.getEndColor()) + { + // not really a gradient + rTargetHolders.Current().append( + new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D( + aPolyPolygon, + aAttribute.getStartColor())); + } + else + { + // really a gradient + rTargetHolders.Current().append( + new drawinglayer::primitive2d::PolyPolygonGradientPrimitive2D( + aPolyPolygon, + aAttribute)); + } + } + } + } + + break; + } + default: + { + OSL_ENSURE(false, "Unknown MetaFile Action (!)"); + break; + } + } + } + } +} // end of anonymous namespace + +////////////////////////////////////////////////////////////////////////////// + namespace drawinglayer { namespace primitive2d { + Primitive2DSequence MetafilePrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const + { + // prepare target and porperties; each will have one default entry + TargetHolders aTargetHolders; + PropertyHolders aPropertyHolders; + + // set target MapUnit at Properties + aPropertyHolders.Current().setMapUnit(getMetaFile().GetPrefMapMode().GetMapUnit()); + + // interpret the Metafile + interpretMetafile(getMetaFile(), aTargetHolders, aPropertyHolders, rViewInformation); + + // get the content. There should be ony one target, as in the start condition, + // but iterating will be the right thing to do when some push/pop is not closed + Primitive2DSequence xRetval; + + while(aTargetHolders.size() > 1) + { + appendPrimitive2DSequenceToPrimitive2DSequence(xRetval, + aTargetHolders.Current().getPrimitive2DSequence(aPropertyHolders.Current())); + aTargetHolders.Pop(); + } + + appendPrimitive2DSequenceToPrimitive2DSequence(xRetval, + aTargetHolders.Current().getPrimitive2DSequence(aPropertyHolders.Current())); + + if(xRetval.hasElements()) + { + // get target size + const Rectangle aMtfTarget(getMetaFile().GetPrefMapMode().GetOrigin(), getMetaFile().GetPrefSize()); + + // create transformation + basegfx::B2DHomMatrix aAdaptedTransform; + + aAdaptedTransform.translate(-aMtfTarget.Left(), -aMtfTarget.Top()); + aAdaptedTransform.scale( + aMtfTarget.getWidth() ? 1.0 / aMtfTarget.getWidth() : 1.0, + aMtfTarget.getHeight() ? 1.0 / aMtfTarget.getHeight() : 1.0); + aAdaptedTransform = getTransform() * aAdaptedTransform; + + // embed to target transformation + const Primitive2DReference aEmbeddedTransform( + new TransformPrimitive2D( + aAdaptedTransform, + xRetval)); + + xRetval = Primitive2DSequence(&aEmbeddedTransform, 1); + } + + return xRetval; + } + MetafilePrimitive2D::MetafilePrimitive2D( const basegfx::B2DHomMatrix& rMetaFileTransform, const GDIMetaFile& rMetaFile) - : BasePrimitive2D(), + : BufferedDecompositionPrimitive2D(), maMetaFileTransform(rMetaFileTransform), maMetaFile(rMetaFile) { @@ -61,7 +3060,7 @@ namespace drawinglayer bool MetafilePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const { - if(BasePrimitive2D::operator==(rPrimitive)) + if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) { const MetafilePrimitive2D& rCompare = (MetafilePrimitive2D&)rPrimitive; @@ -74,8 +3073,13 @@ namespace drawinglayer basegfx::B2DRange MetafilePrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const { + // use own implementation to quickly answer the getB2DRange question. The + // MetafilePrimitive2D assumes that all geometry is inside of the shape. If + // this is not the case (i have already seen some wrong Metafiles) it should + // be embedded to a MaskPrimitive2D basegfx::B2DRange aRetval(0.0, 0.0, 1.0, 1.0); aRetval.transform(getTransform()); + return aRetval; } diff --git a/drawinglayer/source/primitive2d/pagepreviewprimitive2d.cxx b/drawinglayer/source/primitive2d/pagepreviewprimitive2d.cxx index 01a82299682d..b747c79ee0c7 100644 --- a/drawinglayer/source/primitive2d/pagepreviewprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/pagepreviewprimitive2d.cxx @@ -42,6 +42,7 @@ #include <basegfx/polygon/b2dpolygontools.hxx> #include <basegfx/polygon/b2dpolygon.hxx> #include <drawinglayer/primitive2d/transformprimitive2d.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> ////////////////////////////////////////////////////////////////////////////// @@ -53,10 +54,10 @@ namespace drawinglayer { namespace primitive2d { - Primitive2DSequence PagePreviewPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const + Primitive2DSequence PagePreviewPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const { Primitive2DSequence xRetval; - Primitive2DSequence aContent(getChildren()); + Primitive2DSequence aContent(getPageContent()); if(aContent.hasElements() && basegfx::fTools::more(getContentWidth(), 0.0) @@ -112,9 +113,9 @@ namespace drawinglayer } // add the missing object transformation aspects - aPageTrans.shearX(fShearX); - aPageTrans.rotate(fRotate); - aPageTrans.translate(aTranslate.getX(), aTranslate.getY()); + const basegfx::B2DHomMatrix aCombined(basegfx::tools::createShearXRotateTranslateB2DHomMatrix( + fShearX, fRotate, aTranslate.getX(), aTranslate.getY())); + aPageTrans = aCombined * aPageTrans; } else { @@ -139,10 +140,11 @@ namespace drawinglayer const basegfx::B2DHomMatrix& rTransform, double fContentWidth, double fContentHeight, - const Primitive2DSequence& rChildren, + const Primitive2DSequence& rPageContent, bool bKeepAspectRatio) - : GroupPrimitive2D(rChildren), + : BufferedDecompositionPrimitive2D(), mxDrawPage(rxDrawPage), + maPageContent(rPageContent), maTransform(rTransform), mfContentWidth(fContentWidth), mfContentHeight(fContentHeight), @@ -152,11 +154,12 @@ namespace drawinglayer bool PagePreviewPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const { - if(GroupPrimitive2D::operator==(rPrimitive)) + if(BasePrimitive2D::operator==(rPrimitive)) { const PagePreviewPrimitive2D& rCompare = static_cast< const PagePreviewPrimitive2D& >(rPrimitive); return (getXDrawPage() == rCompare.getXDrawPage() + && getPageContent() == rCompare.getPageContent() && getTransform() == rCompare.getTransform() && getContentWidth() == rCompare.getContentWidth() && getContentHeight() == rCompare.getContentHeight() diff --git a/drawinglayer/source/primitive2d/polygonprimitive2d.cxx b/drawinglayer/source/primitive2d/polygonprimitive2d.cxx index b5212da54688..69cbd046efd2 100644 --- a/drawinglayer/source/primitive2d/polygonprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/polygonprimitive2d.cxx @@ -110,7 +110,7 @@ namespace drawinglayer { namespace primitive2d { - Primitive2DSequence PolygonMarkerPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const + Primitive2DSequence PolygonMarkerPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const { // calculate logic DashLength const basegfx::B2DVector aDashVector(rViewInformation.getInverseObjectToViewTransformation() * basegfx::B2DVector(getDiscreteDashLength(), 0.0)); @@ -147,7 +147,7 @@ namespace drawinglayer const basegfx::BColor& rRGBColorA, const basegfx::BColor& rRGBColorB, double fDiscreteDashLength) - : BasePrimitive2D(), + : BufferedDecompositionPrimitive2D(), maPolygon(rPolygon), maRGBColorA(rRGBColorA), maRGBColorB(rRGBColorB), @@ -158,7 +158,7 @@ namespace drawinglayer bool PolygonMarkerPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const { - if(BasePrimitive2D::operator==(rPrimitive)) + if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) { const PolygonMarkerPrimitive2D& rCompare = (PolygonMarkerPrimitive2D&)rPrimitive; @@ -198,7 +198,7 @@ namespace drawinglayer ::osl::MutexGuard aGuard( m_aMutex ); bool bNeedNewDecomposition(false); - if(getLocalDecomposition().hasElements()) + if(getBuffered2DDecomposition().hasElements()) { if(rViewInformation.getInverseObjectToViewTransformation() != maLastInverseObjectToViewTransformation) { @@ -209,10 +209,10 @@ namespace drawinglayer if(bNeedNewDecomposition) { // conditions of last local decomposition have changed, delete - const_cast< PolygonMarkerPrimitive2D* >(this)->setLocalDecomposition(Primitive2DSequence()); + const_cast< PolygonMarkerPrimitive2D* >(this)->setBuffered2DDecomposition(Primitive2DSequence()); } - if(!getLocalDecomposition().hasElements()) + if(!getBuffered2DDecomposition().hasElements()) { // remember last used InverseObjectToViewTransformation PolygonMarkerPrimitive2D* pThat = const_cast< PolygonMarkerPrimitive2D* >(this); @@ -220,7 +220,7 @@ namespace drawinglayer } // use parent implementation - return BasePrimitive2D::get2DDecomposition(rViewInformation); + return BufferedDecompositionPrimitive2D::get2DDecomposition(rViewInformation); } // provide unique ID @@ -235,7 +235,7 @@ namespace drawinglayer { namespace primitive2d { - Primitive2DSequence PolygonStrokePrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const + Primitive2DSequence PolygonStrokePrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const { if(getB2DPolygon().count()) { @@ -307,7 +307,7 @@ namespace drawinglayer const basegfx::B2DPolygon& rPolygon, const attribute::LineAttribute& rLineAttribute, const attribute::StrokeAttribute& rStrokeAttribute) - : BasePrimitive2D(), + : BufferedDecompositionPrimitive2D(), maPolygon(rPolygon), maLineAttribute(rLineAttribute), maStrokeAttribute(rStrokeAttribute) @@ -317,7 +317,7 @@ namespace drawinglayer PolygonStrokePrimitive2D::PolygonStrokePrimitive2D( const basegfx::B2DPolygon& rPolygon, const attribute::LineAttribute& rLineAttribute) - : BasePrimitive2D(), + : BufferedDecompositionPrimitive2D(), maPolygon(rPolygon), maLineAttribute(rLineAttribute), maStrokeAttribute() @@ -326,7 +326,7 @@ namespace drawinglayer bool PolygonStrokePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const { - if(BasePrimitive2D::operator==(rPrimitive)) + if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) { const PolygonStrokePrimitive2D& rCompare = (PolygonStrokePrimitive2D&)rPrimitive; @@ -348,7 +348,7 @@ namespace drawinglayer { // if line is mitered, use parent call since mitered line // geometry may use more space than the geometry grown by half line width - aRetval = BasePrimitive2D::getB2DRange(rViewInformation); + aRetval = BufferedDecompositionPrimitive2D::getB2DRange(rViewInformation); } else { @@ -392,7 +392,7 @@ namespace drawinglayer { namespace primitive2d { - Primitive2DSequence PolygonWavePrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const + Primitive2DSequence PolygonWavePrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const { Primitive2DSequence aRetval; @@ -505,7 +505,7 @@ namespace drawinglayer { namespace primitive2d { - Primitive2DSequence PolygonStrokeArrowPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const + Primitive2DSequence PolygonStrokeArrowPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const { // copy local polygon, it may be changed basegfx::B2DPolygon aLocalPolygon(getB2DPolygon()); @@ -614,7 +614,7 @@ namespace drawinglayer if(getStart().isActive() || getEnd().isActive()) { // use decomposition when line start/end is used - return BasePrimitive2D::getB2DRange(rViewInformation); + return BufferedDecompositionPrimitive2D::getB2DRange(rViewInformation); } else { diff --git a/drawinglayer/source/primitive2d/polypolygonprimitive2d.cxx b/drawinglayer/source/primitive2d/polypolygonprimitive2d.cxx index 9dd14aeb11e3..55c334434c70 100644 --- a/drawinglayer/source/primitive2d/polypolygonprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/polypolygonprimitive2d.cxx @@ -57,7 +57,7 @@ namespace drawinglayer { namespace primitive2d { - Primitive2DSequence PolyPolygonHairlinePrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const + Primitive2DSequence PolyPolygonHairlinePrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const { const basegfx::B2DPolyPolygon aPolyPolygon(getB2DPolyPolygon()); const sal_uInt32 nCount(aPolyPolygon.count()); @@ -80,7 +80,7 @@ namespace drawinglayer } PolyPolygonHairlinePrimitive2D::PolyPolygonHairlinePrimitive2D(const basegfx::B2DPolyPolygon& rPolyPolygon, const basegfx::BColor& rBColor) - : BasePrimitive2D(), + : BufferedDecompositionPrimitive2D(), maPolyPolygon(rPolyPolygon), maBColor(rBColor) { @@ -88,7 +88,7 @@ namespace drawinglayer bool PolyPolygonHairlinePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const { - if(BasePrimitive2D::operator==(rPrimitive)) + if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) { const PolyPolygonHairlinePrimitive2D& rCompare = (PolyPolygonHairlinePrimitive2D&)rPrimitive; @@ -117,7 +117,7 @@ namespace drawinglayer { namespace primitive2d { - Primitive2DSequence PolyPolygonMarkerPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const + Primitive2DSequence PolyPolygonMarkerPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const { const basegfx::B2DPolyPolygon aPolyPolygon(getB2DPolyPolygon()); const sal_uInt32 nCount(aPolyPolygon.count()); @@ -144,7 +144,7 @@ namespace drawinglayer const basegfx::BColor& rRGBColorA, const basegfx::BColor& rRGBColorB, double fDiscreteDashLength) - : BasePrimitive2D(), + : BufferedDecompositionPrimitive2D(), maPolyPolygon(rPolyPolygon), maRGBColorA(rRGBColorA), maRGBColorB(rRGBColorB), @@ -154,7 +154,7 @@ namespace drawinglayer bool PolyPolygonMarkerPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const { - if(BasePrimitive2D::operator==(rPrimitive)) + if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) { const PolyPolygonMarkerPrimitive2D& rCompare = (PolyPolygonMarkerPrimitive2D&)rPrimitive; @@ -185,7 +185,7 @@ namespace drawinglayer { namespace primitive2d { - Primitive2DSequence PolyPolygonStrokePrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const + Primitive2DSequence PolyPolygonStrokePrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const { const basegfx::B2DPolyPolygon aPolyPolygon(getB2DPolyPolygon()); const sal_uInt32 nCount(aPolyPolygon.count()); @@ -211,7 +211,7 @@ namespace drawinglayer const basegfx::B2DPolyPolygon& rPolyPolygon, const attribute::LineAttribute& rLineAttribute, const attribute::StrokeAttribute& rStrokeAttribute) - : BasePrimitive2D(), + : BufferedDecompositionPrimitive2D(), maPolyPolygon(rPolyPolygon), maLineAttribute(rLineAttribute), maStrokeAttribute(rStrokeAttribute) @@ -221,7 +221,7 @@ namespace drawinglayer PolyPolygonStrokePrimitive2D::PolyPolygonStrokePrimitive2D( const basegfx::B2DPolyPolygon& rPolyPolygon, const attribute::LineAttribute& rLineAttribute) - : BasePrimitive2D(), + : BufferedDecompositionPrimitive2D(), maPolyPolygon(rPolyPolygon), maLineAttribute(rLineAttribute), maStrokeAttribute() @@ -230,7 +230,7 @@ namespace drawinglayer bool PolyPolygonStrokePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const { - if(BasePrimitive2D::operator==(rPrimitive)) + if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) { const PolyPolygonStrokePrimitive2D& rCompare = (PolyPolygonStrokePrimitive2D&)rPrimitive; @@ -268,7 +268,7 @@ namespace drawinglayer { namespace primitive2d { - Primitive2DSequence PolyPolygonStrokeArrowPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const + Primitive2DSequence PolyPolygonStrokeArrowPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const { const basegfx::B2DPolyPolygon aPolyPolygon(getB2DPolyPolygon()); const sal_uInt32 nCount(aPolyPolygon.count()); @@ -343,7 +343,7 @@ namespace drawinglayer if(getStart().isActive() || getEnd().isActive()) { // use decomposition when line start/end is used - return BasePrimitive2D::getB2DRange(rViewInformation); + return BufferedDecompositionPrimitive2D::getB2DRange(rViewInformation); } else { @@ -404,7 +404,7 @@ namespace drawinglayer { namespace primitive2d { - Primitive2DSequence PolyPolygonGradientPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const + Primitive2DSequence PolyPolygonGradientPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const { // create SubSequence with FillGradientPrimitive2D const basegfx::B2DRange aPolyPolygonRange(getB2DPolyPolygon().getB2DRange()); @@ -420,16 +420,16 @@ namespace drawinglayer PolyPolygonGradientPrimitive2D::PolyPolygonGradientPrimitive2D( const basegfx::B2DPolyPolygon& rPolyPolygon, - const basegfx::BColor& rBColor, const attribute::FillGradientAttribute& rFillGradient) - : PolyPolygonColorPrimitive2D(rPolyPolygon, rBColor), + : BufferedDecompositionPrimitive2D(), + maPolyPolygon(rPolyPolygon), maFillGradient(rFillGradient) { } bool PolyPolygonGradientPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const { - if(PolyPolygonColorPrimitive2D::operator==(rPrimitive)) + if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) { const PolyPolygonGradientPrimitive2D& rCompare = (PolyPolygonGradientPrimitive2D&)rPrimitive; @@ -451,11 +451,11 @@ namespace drawinglayer { namespace primitive2d { - Primitive2DSequence PolyPolygonHatchPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const + Primitive2DSequence PolyPolygonHatchPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const { // create SubSequence with FillHatchPrimitive2D const basegfx::B2DRange aPolyPolygonRange(getB2DPolyPolygon().getB2DRange()); - FillHatchPrimitive2D* pNewHatch = new FillHatchPrimitive2D(aPolyPolygonRange, getBColor(), getFillHatch()); + FillHatchPrimitive2D* pNewHatch = new FillHatchPrimitive2D(aPolyPolygonRange, getBackgroundColor(), getFillHatch()); const Primitive2DReference xSubRef(pNewHatch); const Primitive2DSequence aSubSequence(&xSubRef, 1L); @@ -467,20 +467,23 @@ namespace drawinglayer PolyPolygonHatchPrimitive2D::PolyPolygonHatchPrimitive2D( const basegfx::B2DPolyPolygon& rPolyPolygon, - const basegfx::BColor& rBColor, + const basegfx::BColor& rBackgroundColor, const attribute::FillHatchAttribute& rFillHatch) - : PolyPolygonColorPrimitive2D(rPolyPolygon, rBColor), + : BufferedDecompositionPrimitive2D(), + maPolyPolygon(rPolyPolygon), + maBackgroundColor(rBackgroundColor), maFillHatch(rFillHatch) { } bool PolyPolygonHatchPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const { - if(PolyPolygonColorPrimitive2D::operator==(rPrimitive)) + if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) { const PolyPolygonHatchPrimitive2D& rCompare = (PolyPolygonHatchPrimitive2D&)rPrimitive; - return (getFillHatch() == rCompare.getFillHatch()); + return (getBackgroundColor() == rCompare.getBackgroundColor() + && getFillHatch() == rCompare.getFillHatch()); } return false; @@ -498,7 +501,7 @@ namespace drawinglayer { namespace primitive2d { - Primitive2DSequence PolyPolygonBitmapPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const + Primitive2DSequence PolyPolygonBitmapPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const { // create SubSequence with FillBitmapPrimitive2D const basegfx::B2DRange aPolyPolygonRange(getB2DPolyPolygon().getB2DRange()); @@ -519,16 +522,16 @@ namespace drawinglayer PolyPolygonBitmapPrimitive2D::PolyPolygonBitmapPrimitive2D( const basegfx::B2DPolyPolygon& rPolyPolygon, - const basegfx::BColor& rBColor, const attribute::FillBitmapAttribute& rFillBitmap) - : PolyPolygonColorPrimitive2D(rPolyPolygon, rBColor), + : BufferedDecompositionPrimitive2D(), + maPolyPolygon(rPolyPolygon), maFillBitmap(rFillBitmap) { } bool PolyPolygonBitmapPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const { - if(PolyPolygonColorPrimitive2D::operator==(rPrimitive)) + if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) { const PolyPolygonBitmapPrimitive2D& rCompare = (PolyPolygonBitmapPrimitive2D&)rPrimitive; diff --git a/drawinglayer/source/primitive2d/primitivetools2d.cxx b/drawinglayer/source/primitive2d/primitivetools2d.cxx index d288a697d729..2b25590bf1f4 100644 --- a/drawinglayer/source/primitive2d/primitivetools2d.cxx +++ b/drawinglayer/source/primitive2d/primitivetools2d.cxx @@ -53,20 +53,20 @@ namespace drawinglayer // get the current DiscreteUnit const double fDiscreteUnit((rViewInformation.getInverseObjectToViewTransformation() * basegfx::B2DVector(1.0, 0.0)).getLength()); - if(getLocalDecomposition().hasElements() && !basegfx::fTools::equal(fDiscreteUnit, getDiscreteUnit())) + if(getBuffered2DDecomposition().hasElements() && !basegfx::fTools::equal(fDiscreteUnit, getDiscreteUnit())) { // conditions of last local decomposition have changed, delete - const_cast< DiscreteMetricDependentPrimitive2D* >(this)->setLocalDecomposition(Primitive2DSequence()); + const_cast< DiscreteMetricDependentPrimitive2D* >(this)->setBuffered2DDecomposition(Primitive2DSequence()); } - if(!getLocalDecomposition().hasElements()) + if(!getBuffered2DDecomposition().hasElements()) { // remember new valid DiscreteUnit const_cast< DiscreteMetricDependentPrimitive2D* >(this)->mfDiscreteUnit = fDiscreteUnit; } // call base implementation - return BasePrimitive2D::get2DDecomposition(rViewInformation); + return BufferedDecompositionPrimitive2D::get2DDecomposition(rViewInformation); } } // end of namespace primitive2d } // end of namespace drawinglayer @@ -84,20 +84,92 @@ namespace drawinglayer // get the current Viewport const basegfx::B2DRange& rViewport = rViewInformation.getViewport(); - if(getLocalDecomposition().hasElements() && !rViewport.equal(getViewport())) + if(getBuffered2DDecomposition().hasElements() && !rViewport.equal(getViewport())) { // conditions of last local decomposition have changed, delete - const_cast< ViewportDependentPrimitive2D* >(this)->setLocalDecomposition(Primitive2DSequence()); + const_cast< ViewportDependentPrimitive2D* >(this)->setBuffered2DDecomposition(Primitive2DSequence()); } - if(!getLocalDecomposition().hasElements()) + if(!getBuffered2DDecomposition().hasElements()) { // remember new valid DiscreteUnit const_cast< ViewportDependentPrimitive2D* >(this)->maViewport = rViewport; } // call base implementation - return BasePrimitive2D::get2DDecomposition(rViewInformation); + return BufferedDecompositionPrimitive2D::get2DDecomposition(rViewInformation); + } + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + Primitive2DSequence ViewTransformationDependentPrimitive2D::get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const + { + ::osl::MutexGuard aGuard( m_aMutex ); + + // get the current ViewTransformation + const basegfx::B2DHomMatrix& rViewTransformation = rViewInformation.getViewTransformation(); + + if(getBuffered2DDecomposition().hasElements() && rViewTransformation != getViewTransformation()) + { + // conditions of last local decomposition have changed, delete + const_cast< ViewTransformationDependentPrimitive2D* >(this)->setBuffered2DDecomposition(Primitive2DSequence()); + } + + if(!getBuffered2DDecomposition().hasElements()) + { + // remember new valid ViewTransformation + const_cast< ViewTransformationDependentPrimitive2D* >(this)->maViewTransformation = rViewTransformation; + } + + // call base implementation + return BufferedDecompositionPrimitive2D::get2DDecomposition(rViewInformation); + } + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + Primitive2DSequence ObjectAndViewTransformationDependentPrimitive2D::get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const + { + ::osl::MutexGuard aGuard( m_aMutex ); + + // get the current ViewTransfromation + const basegfx::B2DHomMatrix& rViewTransformation = rViewInformation.getViewTransformation(); + + if(getBuffered2DDecomposition().hasElements() && rViewTransformation != getViewTransformation()) + { + // conditions of last local decomposition have changed, delete + const_cast< ObjectAndViewTransformationDependentPrimitive2D* >(this)->setBuffered2DDecomposition(Primitive2DSequence()); + } + + // get the current ObjectTransformation + const basegfx::B2DHomMatrix& rObjectTransformation = rViewInformation.getObjectTransformation(); + + if(getBuffered2DDecomposition().hasElements() && rObjectTransformation != getObjectTransformation()) + { + // conditions of last local decomposition have changed, delete + const_cast< ObjectAndViewTransformationDependentPrimitive2D* >(this)->setBuffered2DDecomposition(Primitive2DSequence()); + } + + if(!getBuffered2DDecomposition().hasElements()) + { + // remember new valid ViewTransformation, and ObjectTransformation + const_cast< ObjectAndViewTransformationDependentPrimitive2D* >(this)->maViewTransformation = rViewTransformation; + const_cast< ObjectAndViewTransformationDependentPrimitive2D* >(this)->maObjectTransformation = rObjectTransformation; + } + + // call base implementation + return BufferedDecompositionPrimitive2D::get2DDecomposition(rViewInformation); } } // end of namespace primitive2d } // end of namespace drawinglayer diff --git a/drawinglayer/source/primitive2d/sceneprimitive2d.cxx b/drawinglayer/source/primitive2d/sceneprimitive2d.cxx index ad36a40ea996..6b346d5abdc0 100644 --- a/drawinglayer/source/primitive2d/sceneprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/sceneprimitive2d.cxx @@ -147,7 +147,7 @@ namespace drawinglayer } } - Primitive2DSequence ScenePrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const + Primitive2DSequence ScenePrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const { Primitive2DSequence aRetval; @@ -356,7 +356,7 @@ namespace drawinglayer const attribute::SdrLightingAttribute& rSdrLightingAttribute, const basegfx::B2DHomMatrix& rObjectTransformation, const geometry::ViewInformation3D& rViewInformation3D) - : BasePrimitive2D(), + : BufferedDecompositionPrimitive2D(), mxChildren3D(rxChildren3D), maSdrSceneAttribute(rSdrSceneAttribute), maSdrLightingAttribute(rSdrLightingAttribute), @@ -373,7 +373,7 @@ namespace drawinglayer bool ScenePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const { - if(BasePrimitive2D::operator==(rPrimitive)) + if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) { const ScenePrimitive2D& rCompare = (ScenePrimitive2D&)rPrimitive; @@ -424,7 +424,7 @@ namespace drawinglayer bool bNeedNewDecomposition(false); bool bDiscreteSizesAreCalculated(false); - if(getLocalDecomposition().hasElements()) + if(getBuffered2DDecomposition().hasElements()) { basegfx::B2DRange aVisibleDiscreteRange; calculateDiscreteSizes(rViewInformation, aDiscreteRange, aVisibleDiscreteRange, aUnitVisibleRange); @@ -452,10 +452,10 @@ namespace drawinglayer if(bNeedNewDecomposition) { // conditions of last local decomposition have changed, delete - const_cast< ScenePrimitive2D* >(this)->setLocalDecomposition(Primitive2DSequence()); + const_cast< ScenePrimitive2D* >(this)->setBuffered2DDecomposition(Primitive2DSequence()); } - if(!getLocalDecomposition().hasElements()) + if(!getBuffered2DDecomposition().hasElements()) { if(!bDiscreteSizesAreCalculated) { @@ -471,7 +471,7 @@ namespace drawinglayer } // use parent implementation - return BasePrimitive2D::get2DDecomposition(rViewInformation); + return BufferedDecompositionPrimitive2D::get2DDecomposition(rViewInformation); } // provide unique ID diff --git a/drawinglayer/source/primitive2d/shadowprimitive2d.cxx b/drawinglayer/source/primitive2d/shadowprimitive2d.cxx index 5681f7f98d7e..b6ce7dc3248d 100644 --- a/drawinglayer/source/primitive2d/shadowprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/shadowprimitive2d.cxx @@ -55,25 +55,6 @@ namespace drawinglayer { namespace primitive2d { - Primitive2DSequence ShadowPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const - { - Primitive2DSequence aRetval; - - if(getChildren().hasElements()) - { - // create a modifiedColorPrimitive containing the shadow color and the content - const basegfx::BColorModifier aBColorModifier(getShadowColor()); - const Primitive2DReference xRefA(new ModifiedColorPrimitive2D(getChildren(), aBColorModifier)); - const Primitive2DSequence aSequenceB(&xRefA, 1L); - - // build transformed primitiveVector with shadow offset and add to target - const Primitive2DReference xRefB(new TransformPrimitive2D(getShadowTransform(), aSequenceB)); - aRetval = Primitive2DSequence(&xRefB, 1L); - } - - return aRetval; - } - ShadowPrimitive2D::ShadowPrimitive2D( const basegfx::B2DHomMatrix& rShadowTransform, const basegfx::BColor& rShadowColor, @@ -86,7 +67,7 @@ namespace drawinglayer bool ShadowPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const { - if(GroupPrimitive2D::operator==(rPrimitive)) + if(BasePrimitive2D::operator==(rPrimitive)) { const ShadowPrimitive2D& rCompare = static_cast< const ShadowPrimitive2D& >(rPrimitive); @@ -104,6 +85,25 @@ namespace drawinglayer return aRetval; } + Primitive2DSequence ShadowPrimitive2D::get2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const + { + Primitive2DSequence aRetval; + + if(getChildren().hasElements()) + { + // create a modifiedColorPrimitive containing the shadow color and the content + const basegfx::BColorModifier aBColorModifier(getShadowColor()); + const Primitive2DReference xRefA(new ModifiedColorPrimitive2D(getChildren(), aBColorModifier)); + const Primitive2DSequence aSequenceB(&xRefA, 1L); + + // build transformed primitiveVector with shadow offset and add to target + const Primitive2DReference xRefB(new TransformPrimitive2D(getShadowTransform(), aSequenceB)); + aRetval = Primitive2DSequence(&xRefB, 1L); + } + + return aRetval; + } + // provide unique ID ImplPrimitrive2DIDBlock(ShadowPrimitive2D, PRIMITIVE2D_ID_SHADOWPRIMITIVE2D) diff --git a/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx b/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx index d337950c6c6b..f9d245f76a34 100644 --- a/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx @@ -48,6 +48,8 @@ #include <drawinglayer/primitive2d/shadowprimitive2d.hxx> #include <com/sun/star/i18n/XBreakIterator.hpp> #include <drawinglayer/primitive2d/transformprimitive2d.hxx> +#include <drawinglayer/primitive2d/textlineprimitive2d.hxx> +#include <drawinglayer/primitive2d/textstrikeoutprimitive2d.hxx> ////////////////////////////////////////////////////////////////////////////// @@ -55,226 +57,14 @@ namespace drawinglayer { namespace primitive2d { - void TextDecoratedPortionPrimitive2D::impCreateTextLine( - std::vector< Primitive2DReference >& rTarget, - basegfx::DecomposedB2DHomMatrixContainer& rDecTrans, - const basegfx::B2DHomMatrix &rUnscaledTransform, - FontUnderline eLineStyle, - double fLineOffset, - double fLineHeight, - double fLineWidth, - const basegfx::BColor& rLineColor) const - { - bool bDoubleLine(false); - bool bWaveLine(false); - bool bBoldLine(false); - const int* pDotDashArray(0); - basegfx::B2DLineJoin eLineJoin(basegfx::B2DLINEJOIN_NONE); - - static const int aDottedArray[] = { 1, 1, 0}; // DOTTED LINE - static const int aDotDashArray[] = { 1, 1, 4, 1, 0}; // DASHDOT - static const int aDashDotDotArray[] = { 1, 1, 1, 1, 4, 1, 0}; // DASHDOTDOT - static const int aDashedArray[] = { 5, 2, 0}; // DASHED LINE - static const int aLongDashArray[] = { 7, 2, 0}; // LONGDASH - - switch(eLineStyle) - { - default: // case FONT_UNDERLINE_SINGLE: - { - break; - } - case FONT_UNDERLINE_DOUBLE: - { - bDoubleLine = true; - break; - } - case FONT_UNDERLINE_DOTTED: - { - pDotDashArray = aDottedArray; - break; - } - case FONT_UNDERLINE_DASH: - { - pDotDashArray = aDashedArray; - break; - } - case FONT_UNDERLINE_LONGDASH: - { - pDotDashArray = aLongDashArray; - break; - } - case FONT_UNDERLINE_DASHDOT: - { - pDotDashArray = aDotDashArray; - break; - } - case FONT_UNDERLINE_DASHDOTDOT: - { - pDotDashArray = aDashDotDotArray; - break; - } - case FONT_UNDERLINE_SMALLWAVE: - { - bWaveLine = true; - break; - } - case FONT_UNDERLINE_WAVE: - { - bWaveLine = true; - break; - } - case FONT_UNDERLINE_DOUBLEWAVE: - { - bDoubleLine = true; - bWaveLine = true; - break; - } - case FONT_UNDERLINE_BOLD: - { - bBoldLine = true; - break; - } - case FONT_UNDERLINE_BOLDDOTTED: - { - bBoldLine = true; - pDotDashArray = aDottedArray; - break; - } - case FONT_UNDERLINE_BOLDDASH: - { - bBoldLine = true; - pDotDashArray = aDashedArray; - break; - } - case FONT_UNDERLINE_BOLDLONGDASH: - { - bBoldLine = true; - pDotDashArray = aLongDashArray; - break; - } - case FONT_UNDERLINE_BOLDDASHDOT: - { - bBoldLine = true; - pDotDashArray = aDotDashArray; - break; - } - case FONT_UNDERLINE_BOLDDASHDOTDOT: - { - bBoldLine = true; - pDotDashArray = aDashDotDotArray; - break; - } - case FONT_UNDERLINE_BOLDWAVE: - { - bWaveLine = true; - bBoldLine = true; - break; - } - } - - if(bBoldLine) - { - fLineHeight *= 2.0; - } - - if(bDoubleLine) - { - fLineOffset -= 0.50 * fLineHeight; - fLineHeight *= 0.64; - } - - if(bWaveLine) - { - eLineJoin = basegfx::B2DLINEJOIN_ROUND; - fLineHeight *= 0.25; - } - - // prepare Line and Stroke Attributes - const attribute::LineAttribute aLineAttribute(rLineColor, fLineHeight, eLineJoin); - attribute::StrokeAttribute aStrokeAttribute; - - if(pDotDashArray) - { - ::std::vector< double > aDoubleArray; - - for(const int* p = pDotDashArray; *p; ++p) - { - aDoubleArray.push_back((double)(*p) * fLineHeight); - } - - aStrokeAttribute = attribute::StrokeAttribute(aDoubleArray); - } - - // create base polygon and new primitive - basegfx::B2DPolygon aLine; - Primitive2DReference aNewPrimitive; - - aLine.append(basegfx::B2DPoint(0.0, fLineOffset)); - aLine.append(basegfx::B2DPoint(fLineWidth, fLineOffset)); - aLine.transform(rUnscaledTransform); - - if(bWaveLine) - { - double fWaveWidth(10.6 * fLineHeight); - - if(FONT_UNDERLINE_SMALLWAVE == eLineStyle) - { - fWaveWidth *= 0.7; - } - else if(FONT_UNDERLINE_WAVE == eLineStyle) - { - // extra multiply to get the same WaveWidth as with the bold version - fWaveWidth *= 2.0; - } - - aNewPrimitive = Primitive2DReference(new PolygonWavePrimitive2D(aLine, aLineAttribute, aStrokeAttribute, fWaveWidth, fWaveWidth * 0.5)); - } - else - { - aNewPrimitive = Primitive2DReference(new PolygonStrokePrimitive2D(aLine, aLineAttribute, aStrokeAttribute)); - } - - // add primitive - rTarget.push_back(aNewPrimitive); - - if(bDoubleLine) - { - // double line, create 2nd primitive with offset using TransformPrimitive based on - // already created NewPrimitive - double fLineDist(2.3 * fLineHeight); - - if(bWaveLine) - { - fLineDist = 6.3 * fLineHeight; - } - - basegfx::B2DHomMatrix aTransform; - - // move base point of text to 0.0 and de-rotate - aTransform.translate(-rDecTrans.getTranslate().getX(), -rDecTrans.getTranslate().getY()); - aTransform.rotate(-rDecTrans.getRotate()); - - // translate in Y by offset - aTransform.translate(0.0, fLineDist); - - // move back and rotate - aTransform.rotate(rDecTrans.getRotate()); - aTransform.translate(rDecTrans.getTranslate().getX(), rDecTrans.getTranslate().getY()); - - // add transform primitive - const Primitive2DSequence aContent(&aNewPrimitive, 1); - rTarget.push_back(Primitive2DReference(new TransformPrimitive2D(aTransform, aContent))); - } - } - void TextDecoratedPortionPrimitive2D::impCreateGeometryContent( std::vector< Primitive2DReference >& rTarget, - basegfx::DecomposedB2DHomMatrixContainer& rDecTrans, + basegfx::tools::B2DHomMatrixBufferedOnDemandDecompose& rDecTrans, const String& rText, xub_StrLen aTextPosition, xub_StrLen aTextLength, const ::std::vector< double >& rDXArray, - const FontAttributes& rFontAttributes) const + const attribute::FontAttribute& rFontAttribute) const { // create the SimpleTextPrimitive needed in any case rTarget.push_back(Primitive2DReference( @@ -284,30 +74,24 @@ namespace drawinglayer aTextPosition, aTextLength, rDXArray, - rFontAttributes, + rFontAttribute, getLocale(), getFontColor()))); // see if something else needs to be done - const bool bOverlineUsed(FONT_UNDERLINE_NONE != getFontOverline()); - const bool bUnderlineUsed(FONT_UNDERLINE_NONE != getFontUnderline()); - const bool bStrikeoutUsed(FONT_STRIKEOUT_NONE != getFontStrikeout()); + const bool bOverlineUsed(TEXT_LINE_NONE != getFontOverline()); + const bool bUnderlineUsed(TEXT_LINE_NONE != getFontUnderline()); + const bool bStrikeoutUsed(TEXT_STRIKEOUT_NONE != getTextStrikeout()); if(bUnderlineUsed || bStrikeoutUsed || bOverlineUsed) { // common preparations - basegfx::B2DHomMatrix aUnscaledTransform; TextLayouterDevice aTextLayouter; - // unscaled is needed since scale contains already the font size - aUnscaledTransform.shearX(rDecTrans.getShearX()); - aUnscaledTransform.rotate(rDecTrans.getRotate()); - aUnscaledTransform.translate(rDecTrans.getTranslate().getX(), rDecTrans.getTranslate().getY()); - // TextLayouterDevice is needed to get metrics for text decorations like // underline/strikeout/emphasis marks from it. For setup, the font size is needed - aTextLayouter.setFontAttributes( - getFontAttributes(), + aTextLayouter.setFontAttribute( + getFontAttribute(), rDecTrans.getScale().getX(), rDecTrans.getScale().getY(), getLocale()); @@ -335,115 +119,57 @@ namespace drawinglayer if(bOverlineUsed) { // create primitive geometry for overline - impCreateTextLine(rTarget, rDecTrans, aUnscaledTransform, getFontOverline(), aTextLayouter.getOverlineOffset(), - aTextLayouter.getOverlineHeight(), fTextWidth, getOverlineColor()); + rTarget.push_back(Primitive2DReference( + new TextLinePrimitive2D( + rDecTrans.getB2DHomMatrix(), + fTextWidth, + aTextLayouter.getOverlineOffset(), + aTextLayouter.getOverlineHeight(), + getFontOverline(), + getOverlineColor()))); } if(bUnderlineUsed) { // create primitive geometry for underline - impCreateTextLine(rTarget, rDecTrans, aUnscaledTransform, getFontUnderline(), aTextLayouter.getUnderlineOffset(), - aTextLayouter.getUnderlineHeight(), fTextWidth, getTextlineColor()); + rTarget.push_back(Primitive2DReference( + new TextLinePrimitive2D( + rDecTrans.getB2DHomMatrix(), + fTextWidth, + aTextLayouter.getUnderlineOffset(), + aTextLayouter.getUnderlineHeight(), + getFontUnderline(), + getTextlineColor()))); } if(bStrikeoutUsed) { // create primitive geometry for strikeout - if(FONT_STRIKEOUT_SLASH == getFontStrikeout() || FONT_STRIKEOUT_X == getFontStrikeout()) + if(TEXT_STRIKEOUT_SLASH == getTextStrikeout() || TEXT_STRIKEOUT_X == getTextStrikeout()) { // strikeout with character - const sal_Unicode aStrikeoutChar(FONT_STRIKEOUT_SLASH == getFontStrikeout() ? '/' : 'X'); - const String aSingleCharString(aStrikeoutChar); - const double fStrikeCharWidth(aTextLayouter.getTextWidth(aSingleCharString, 0, 1)); - const double fStrikeCharCount(fabs(fTextWidth/fStrikeCharWidth)); - const sal_uInt32 nStrikeCharCount(static_cast< sal_uInt32 >(fStrikeCharCount + 0.5)); - std::vector<double> aDXArray(nStrikeCharCount); - String aStrikeoutString; - - for(sal_uInt32 a(0); a < nStrikeCharCount; a++) - { - aStrikeoutString += aSingleCharString; - aDXArray[a] = (a + 1) * fStrikeCharWidth; - } + const sal_Unicode aStrikeoutChar(TEXT_STRIKEOUT_SLASH == getTextStrikeout() ? '/' : 'X'); rTarget.push_back(Primitive2DReference( - new TextSimplePortionPrimitive2D( + new TextCharacterStrikeoutPrimitive2D( rDecTrans.getB2DHomMatrix(), - aStrikeoutString, - 0, - aStrikeoutString.Len(), - aDXArray, - rFontAttributes, - getLocale(), - getFontColor()))); + fTextWidth, + getFontColor(), + aStrikeoutChar, + getFontAttribute(), + getLocale()))); } else { // strikeout with geometry - double fStrikeoutHeight(aTextLayouter.getUnderlineHeight()); - double fStrikeoutOffset(aTextLayouter.getStrikeoutOffset()); - bool bDoubleLine(false); - - // set line attribute - switch(getFontStrikeout()) - { - default : // case primitive2d::FONT_STRIKEOUT_SINGLE: - { - break; - } - case primitive2d::FONT_STRIKEOUT_DOUBLE: - { - bDoubleLine = true; - break; - } - case primitive2d::FONT_STRIKEOUT_BOLD: - { - fStrikeoutHeight *= 2.0; - break; - } - } - - if(bDoubleLine) - { - fStrikeoutOffset -= 0.50 * fStrikeoutHeight; - fStrikeoutHeight *= 0.64; - } - - // create base polygon and new primitive - basegfx::B2DPolygon aStrikeoutLine; - - aStrikeoutLine.append(basegfx::B2DPoint(0.0, -fStrikeoutOffset)); - aStrikeoutLine.append(basegfx::B2DPoint(fTextWidth, -fStrikeoutOffset)); - aStrikeoutLine.transform(aUnscaledTransform); - - const attribute::LineAttribute aLineAttribute(getFontColor(), fStrikeoutHeight, basegfx::B2DLINEJOIN_NONE); - Primitive2DReference aNewPrimitive(new PolygonStrokePrimitive2D(aStrikeoutLine, aLineAttribute)); - - // add primitive - rTarget.push_back(aNewPrimitive); - - if(bDoubleLine) - { - // double line, create 2nd primitive with offset using TransformPrimitive based on - // already created NewPrimitive - const double fLineDist(2.0 * fStrikeoutHeight); - basegfx::B2DHomMatrix aTransform; - - // move base point of text to 0.0 and de-rotate - aTransform.translate(-rDecTrans.getTranslate().getX(), -rDecTrans.getTranslate().getY()); - aTransform.rotate(-rDecTrans.getRotate()); - - // translate in Y by offset - aTransform.translate(0.0, -fLineDist); - - // move back and rotate - aTransform.rotate(rDecTrans.getRotate()); - aTransform.translate(rDecTrans.getTranslate().getX(), rDecTrans.getTranslate().getY()); - - // add transform primitive - const Primitive2DSequence aContent(&aNewPrimitive, 1); - rTarget.push_back(Primitive2DReference(new TransformPrimitive2D(aTransform, aContent))); - } + rTarget.push_back(Primitive2DReference( + new TextGeometryStrikeoutPrimitive2D( + rDecTrans.getB2DHomMatrix(), + fTextWidth, + getFontColor(), + aTextLayouter.getUnderlineHeight(), + aTextLayouter.getStrikeoutOffset(), + getTextStrikeout()))); } } } @@ -480,7 +206,7 @@ namespace drawinglayer void TextDecoratedPortionPrimitive2D::impSplitSingleWords( std::vector< Primitive2DReference >& rTarget, - basegfx::DecomposedB2DHomMatrixContainer& rDecTrans) const + basegfx::tools::B2DHomMatrixBufferedOnDemandDecompose& rDecTrans) const { // break iterator support // made static so it only needs to be fetched once, even with many single @@ -510,21 +236,21 @@ namespace drawinglayer impCorrectTextBoundary(aNextWordBoundary); // prepare new font attributes WITHOUT outline - const FontAttributes aNewFontAttributes( - getFontAttributes().getFamilyName(), - getFontAttributes().getStyleName(), - getFontAttributes().getWeight(), - getFontAttributes().getSymbol(), - getFontAttributes().getVertical(), - getFontAttributes().getItalic(), + const attribute::FontAttribute aNewFontAttribute( + getFontAttribute().getFamilyName(), + getFontAttribute().getStyleName(), + getFontAttribute().getWeight(), + getFontAttribute().getSymbol(), + getFontAttribute().getVertical(), + getFontAttribute().getItalic(), false, // no outline anymore, handled locally - getFontAttributes().getRTL(), - getFontAttributes().getBiDiStrong()); + getFontAttribute().getRTL(), + getFontAttribute().getBiDiStrong()); if(aNextWordBoundary.startPos == getTextPosition() && aNextWordBoundary.endPos == getTextLength()) { // it IS only a single word, handle as one word - impCreateGeometryContent(rTarget, rDecTrans, getText(), getTextPosition(), getTextLength(), getDXArray(), aNewFontAttributes); + impCreateGeometryContent(rTarget, rDecTrans, getText(), getTextPosition(), getTextLength(), getDXArray(), aNewFontAttribute); } else { @@ -535,8 +261,8 @@ namespace drawinglayer if(bNoDXArray) { // ..but only completely when no DXArray - aTextLayouter.setFontAttributes( - getFontAttributes(), + aTextLayouter.setFontAttribute( + getFontAttribute(), rDecTrans.getScale().getX(), rDecTrans.getScale().getY(), getLocale()); @@ -612,10 +338,10 @@ namespace drawinglayer // create geometry content for the single word. Do not forget // to use the new transformation - basegfx::DecomposedB2DHomMatrixContainer aDecTrans(aNewTransform); + basegfx::tools::B2DHomMatrixBufferedOnDemandDecompose aDecTrans(aNewTransform); impCreateGeometryContent(rTarget, aDecTrans, getText(), nNewTextStart, - nNewTextEnd - nNewTextStart, aNewDXArray, aNewFontAttributes); + nNewTextEnd - nNewTextStart, aNewDXArray, aNewFontAttribute); if(aNextWordBoundary.endPos >= getTextPosition() + getTextLength()) { @@ -646,10 +372,10 @@ namespace drawinglayer } } - Primitive2DSequence TextDecoratedPortionPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const + Primitive2DSequence TextDecoratedPortionPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const { std::vector< Primitive2DReference > aNewPrimitives; - basegfx::DecomposedB2DHomMatrixContainer aDecTrans(getTextTransform()); + basegfx::tools::B2DHomMatrixBufferedOnDemandDecompose aDecTrans(getTextTransform()); Primitive2DSequence aRetval; // create basic geometry such as SimpleTextPrimitive, Overline, Underline, @@ -662,19 +388,19 @@ namespace drawinglayer else { // prepare new font attributes WITHOUT outline - const FontAttributes aNewFontAttributes( - getFontAttributes().getFamilyName(), - getFontAttributes().getStyleName(), - getFontAttributes().getWeight(), - getFontAttributes().getSymbol(), - getFontAttributes().getVertical(), - getFontAttributes().getItalic(), + const attribute::FontAttribute aNewFontAttribute( + getFontAttribute().getFamilyName(), + getFontAttribute().getStyleName(), + getFontAttribute().getWeight(), + getFontAttribute().getSymbol(), + getFontAttribute().getVertical(), + getFontAttribute().getItalic(), false, // no outline anymore, handled locally - getFontAttributes().getRTL(), - getFontAttributes().getBiDiStrong()); + getFontAttribute().getRTL(), + getFontAttribute().getBiDiStrong()); // handle as one word - impCreateGeometryContent(aNewPrimitives, aDecTrans, getText(), getTextPosition(), getTextLength(), getDXArray(), aNewFontAttributes); + impCreateGeometryContent(aNewPrimitives, aDecTrans, getText(), getTextPosition(), getTextLength(), getDXArray(), aNewFontAttribute); } // convert to Primitive2DSequence @@ -690,15 +416,15 @@ namespace drawinglayer } } - // Handle Shadow, Outline and FontRelief + // Handle Shadow, Outline and TextRelief if(aRetval.hasElements()) { - // outline AND shadow depend on NO FontRelief (see dialog) - const bool bHasFontRelief(FONT_RELIEF_NONE != getFontRelief()); - const bool bHasShadow(!bHasFontRelief && getShadow()); - const bool bHasOutline(!bHasFontRelief && getFontAttributes().getOutline()); + // outline AND shadow depend on NO TextRelief (see dialog) + const bool bHasTextRelief(TEXT_RELIEF_NONE != getTextRelief()); + const bool bHasShadow(!bHasTextRelief && getShadow()); + const bool bHasOutline(!bHasTextRelief && getFontAttribute().getOutline()); - if(bHasShadow || bHasFontRelief || bHasOutline) + if(bHasShadow || bHasTextRelief || bHasOutline) { Primitive2DReference aShadow; @@ -713,8 +439,8 @@ namespace drawinglayer static basegfx::BColor aShadowColor(0.3, 0.3, 0.3); // preapare shadow transform matrix - basegfx::B2DHomMatrix aShadowTransform; - aShadowTransform.translate(fTextShadowOffset, fTextShadowOffset); + const basegfx::B2DHomMatrix aShadowTransform(basegfx::tools::createTranslateB2DHomMatrix( + fTextShadowOffset, fTextShadowOffset)); // create shadow primitive aShadow = Primitive2DReference(new ShadowPrimitive2D( @@ -723,7 +449,7 @@ namespace drawinglayer aRetval)); } - if(bHasFontRelief) + if(bHasTextRelief) { // create emboss using an own helper primitive since this will // be view-dependent @@ -733,7 +459,7 @@ namespace drawinglayer if(bDefaultTextColor) { - if(FONT_RELIEF_ENGRAVED == getFontRelief()) + if(TEXT_RELIEF_ENGRAVED == getTextRelief()) { aTextEffectStyle2D = TEXTEFFECTSTYLE2D_RELIEF_ENGRAVED_DEFAULT; } @@ -744,7 +470,7 @@ namespace drawinglayer } else { - if(FONT_RELIEF_ENGRAVED == getFontRelief()) + if(TEXT_RELIEF_ENGRAVED == getTextRelief()) { aTextEffectStyle2D = TEXTEFFECTSTYLE2D_RELIEF_ENGRAVED; } @@ -795,31 +521,31 @@ namespace drawinglayer xub_StrLen aTextPosition, xub_StrLen aTextLength, const ::std::vector< double >& rDXArray, - const FontAttributes& rFontAttributes, + const attribute::FontAttribute& rFontAttribute, const ::com::sun::star::lang::Locale& rLocale, const basegfx::BColor& rFontColor, // local parameters const basegfx::BColor& rOverlineColor, const basegfx::BColor& rTextlineColor, - FontUnderline eFontOverline, - FontUnderline eFontUnderline, + TextLine eFontOverline, + TextLine eFontUnderline, bool bUnderlineAbove, - FontStrikeout eFontStrikeout, + TextStrikeout eTextStrikeout, bool bWordLineMode, - FontEmphasisMark eFontEmphasisMark, + TextEmphasisMark eTextEmphasisMark, bool bEmphasisMarkAbove, bool bEmphasisMarkBelow, - FontRelief eFontRelief, + TextRelief eTextRelief, bool bShadow) - : TextSimplePortionPrimitive2D(rNewTransform, rText, aTextPosition, aTextLength, rDXArray, rFontAttributes, rLocale, rFontColor), + : TextSimplePortionPrimitive2D(rNewTransform, rText, aTextPosition, aTextLength, rDXArray, rFontAttribute, rLocale, rFontColor), maOverlineColor(rOverlineColor), maTextlineColor(rTextlineColor), meFontOverline(eFontOverline), meFontUnderline(eFontUnderline), - meFontStrikeout(eFontStrikeout), - meFontEmphasisMark(eFontEmphasisMark), - meFontRelief(eFontRelief), + meTextStrikeout(eTextStrikeout), + meTextEmphasisMark(eTextEmphasisMark), + meTextRelief(eTextRelief), mbUnderlineAbove(bUnderlineAbove), mbWordLineMode(bWordLineMode), mbEmphasisMarkAbove(bEmphasisMarkAbove), @@ -838,9 +564,9 @@ namespace drawinglayer && getTextlineColor() == rCompare.getTextlineColor() && getFontOverline() == rCompare.getFontOverline() && getFontUnderline() == rCompare.getFontUnderline() - && getFontStrikeout() == rCompare.getFontStrikeout() - && getFontEmphasisMark() == rCompare.getFontEmphasisMark() - && getFontRelief() == rCompare.getFontRelief() + && getTextStrikeout() == rCompare.getTextStrikeout() + && getTextEmphasisMark() == rCompare.getTextEmphasisMark() + && getTextRelief() == rCompare.getTextRelief() && getUnderlineAbove() == rCompare.getUnderlineAbove() && getWordLineMode() == rCompare.getWordLineMode() && getEmphasisMarkAbove() == rCompare.getEmphasisMarkAbove() @@ -857,19 +583,19 @@ namespace drawinglayer basegfx::B2DRange TextDecoratedPortionPrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const { const bool bDecoratedIsNeeded( - FONT_UNDERLINE_NONE != getFontOverline() - || FONT_UNDERLINE_NONE != getFontUnderline() - || FONT_STRIKEOUT_NONE != getFontStrikeout() - || FONT_EMPHASISMARK_NONE != getFontEmphasisMark() - || FONT_RELIEF_NONE != getFontRelief() + TEXT_LINE_NONE != getFontOverline() + || TEXT_LINE_NONE != getFontUnderline() + || TEXT_STRIKEOUT_NONE != getTextStrikeout() + || TEXT_EMPHASISMARK_NONE != getTextEmphasisMark() + || TEXT_RELIEF_NONE != getTextRelief() || getShadow()); if(bDecoratedIsNeeded) { - // decoration is used, fallback to BasePrimitive2D::getB2DRange which uses + // decoration is used, fallback to BufferedDecompositionPrimitive2D::getB2DRange which uses // the own local decomposition for computation and thus creates all necessary // geometric objects - return BasePrimitive2D::getB2DRange(rViewInformation); + return BufferedDecompositionPrimitive2D::getB2DRange(rViewInformation); } else { diff --git a/drawinglayer/source/primitive2d/texteffectprimitive2d.cxx b/drawinglayer/source/primitive2d/texteffectprimitive2d.cxx index c1963f4ba2a4..5e98a9d6d34b 100644 --- a/drawinglayer/source/primitive2d/texteffectprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/texteffectprimitive2d.cxx @@ -41,6 +41,7 @@ #include <drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx> #include <drawinglayer/primitive2d/transformprimitive2d.hxx> #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> ////////////////////////////////////////////////////////////////////////////// @@ -50,7 +51,7 @@ namespace drawinglayer { static double fDiscreteSize(1.1); - Primitive2DSequence TextEffectPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const + Primitive2DSequence TextEffectPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const { Primitive2DSequence aRetval; @@ -68,13 +69,12 @@ namespace drawinglayer case TEXTEFFECTSTYLE2D_RELIEF_ENGRAVED_DEFAULT: { // prepare transform of sub-group back to (0,0) and align to X-Axis - basegfx::B2DHomMatrix aBackTransform; - aBackTransform.translate(-getRotationCenter().getX(), -getRotationCenter().getY()); + basegfx::B2DHomMatrix aBackTransform(basegfx::tools::createTranslateB2DHomMatrix( + -getRotationCenter().getX(), -getRotationCenter().getY())); aBackTransform.rotate(-getDirection()); // prepare transform of sub-group back to it's position and rotation - basegfx::B2DHomMatrix aForwardTransform; - aForwardTransform.rotate(getDirection()); + basegfx::B2DHomMatrix aForwardTransform(basegfx::tools::createRotateB2DHomMatrix(getDirection())); aForwardTransform.translate(getRotationCenter().getX(), getRotationCenter().getY()); // create transformation for one discrete unit @@ -104,22 +104,22 @@ namespace drawinglayer { // emboss/engrave in black, original forced to white const basegfx::BColorModifier aBColorModifierToGray(basegfx::BColor(0.0)); - const Primitive2DReference xModifiedColor(new ModifiedColorPrimitive2D(getChildren(), aBColorModifierToGray)); + const Primitive2DReference xModifiedColor(new ModifiedColorPrimitive2D(getTextContent(), aBColorModifierToGray)); aRetval[0] = Primitive2DReference(new TransformPrimitive2D(aTransform, Primitive2DSequence(&xModifiedColor, 1))); // add original, too const basegfx::BColorModifier aBColorModifierToWhite(basegfx::BColor(1.0)); - aRetval[1] = Primitive2DReference(new ModifiedColorPrimitive2D(getChildren(), aBColorModifierToWhite)); + aRetval[1] = Primitive2DReference(new ModifiedColorPrimitive2D(getTextContent(), aBColorModifierToWhite)); } else { // emboss/engrave in gray, keep original's color const basegfx::BColorModifier aBColorModifierToGray(basegfx::BColor(0.75)); // 192 - const Primitive2DReference xModifiedColor(new ModifiedColorPrimitive2D(getChildren(), aBColorModifierToGray)); + const Primitive2DReference xModifiedColor(new ModifiedColorPrimitive2D(getTextContent(), aBColorModifierToGray)); aRetval[0] = Primitive2DReference(new TransformPrimitive2D(aTransform, Primitive2DSequence(&xModifiedColor, 1))); // add original, too - aRetval[1] = Primitive2DReference(new GroupPrimitive2D(getChildren())); + aRetval[1] = Primitive2DReference(new GroupPrimitive2D(getTextContent())); } break; @@ -132,39 +132,39 @@ namespace drawinglayer aTransform.set(0, 2, aDistance.getX()); aTransform.set(1, 2, 0.0); - aRetval[0] = Primitive2DReference(new TransformPrimitive2D(aTransform, getChildren())); + aRetval[0] = Primitive2DReference(new TransformPrimitive2D(aTransform, getTextContent())); aTransform.set(0, 2, aDiagonalDistance.getX()); aTransform.set(1, 2, aDiagonalDistance.getY()); - aRetval[1] = Primitive2DReference(new TransformPrimitive2D(aTransform, getChildren())); + aRetval[1] = Primitive2DReference(new TransformPrimitive2D(aTransform, getTextContent())); aTransform.set(0, 2, 0.0); aTransform.set(1, 2, aDistance.getY()); - aRetval[2] = Primitive2DReference(new TransformPrimitive2D(aTransform, getChildren())); + aRetval[2] = Primitive2DReference(new TransformPrimitive2D(aTransform, getTextContent())); aTransform.set(0, 2, -aDiagonalDistance.getX()); aTransform.set(1, 2, aDiagonalDistance.getY()); - aRetval[3] = Primitive2DReference(new TransformPrimitive2D(aTransform, getChildren())); + aRetval[3] = Primitive2DReference(new TransformPrimitive2D(aTransform, getTextContent())); aTransform.set(0, 2, -aDistance.getX()); aTransform.set(1, 2, 0.0); - aRetval[4] = Primitive2DReference(new TransformPrimitive2D(aTransform, getChildren())); + aRetval[4] = Primitive2DReference(new TransformPrimitive2D(aTransform, getTextContent())); aTransform.set(0, 2, -aDiagonalDistance.getX()); aTransform.set(1, 2, -aDiagonalDistance.getY()); - aRetval[5] = Primitive2DReference(new TransformPrimitive2D(aTransform, getChildren())); + aRetval[5] = Primitive2DReference(new TransformPrimitive2D(aTransform, getTextContent())); aTransform.set(0, 2, 0.0); aTransform.set(1, 2, -aDistance.getY()); - aRetval[6] = Primitive2DReference(new TransformPrimitive2D(aTransform, getChildren())); + aRetval[6] = Primitive2DReference(new TransformPrimitive2D(aTransform, getTextContent())); aTransform.set(0, 2, aDiagonalDistance.getX()); aTransform.set(1, 2, -aDiagonalDistance.getY()); - aRetval[7] = Primitive2DReference(new TransformPrimitive2D(aTransform, getChildren())); + aRetval[7] = Primitive2DReference(new TransformPrimitive2D(aTransform, getTextContent())); // at last, place original over it, but force to white const basegfx::BColorModifier aBColorModifierToWhite(basegfx::BColor(1.0, 1.0, 1.0)); - aRetval[8] = Primitive2DReference(new ModifiedColorPrimitive2D(getChildren(), aBColorModifierToWhite)); + aRetval[8] = Primitive2DReference(new ModifiedColorPrimitive2D(getTextContent(), aBColorModifierToWhite)); break; } @@ -174,11 +174,12 @@ namespace drawinglayer } TextEffectPrimitive2D::TextEffectPrimitive2D( - const Primitive2DSequence& rChildren, + const Primitive2DSequence& rTextContent, const basegfx::B2DPoint& rRotationCenter, double fDirection, TextEffectStyle2D eTextEffectStyle2D) - : GroupPrimitive2D(rChildren), + : BufferedDecompositionPrimitive2D(), + maTextContent(rTextContent), maRotationCenter(rRotationCenter), mfDirection(fDirection), meTextEffectStyle2D(eTextEffectStyle2D) @@ -187,11 +188,12 @@ namespace drawinglayer bool TextEffectPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const { - if(GroupPrimitive2D::operator==(rPrimitive)) + if(BasePrimitive2D::operator==(rPrimitive)) { const TextEffectPrimitive2D& rCompare = (TextEffectPrimitive2D&)rPrimitive; - return (getRotationCenter() == rCompare.getRotationCenter() + return (getTextContent() == rCompare.getTextContent() + && getRotationCenter() == rCompare.getRotationCenter() && getDirection() == rCompare.getDirection() && getTextEffectStyle2D() == rCompare.getTextEffectStyle2D()); } @@ -206,7 +208,7 @@ namespace drawinglayer // then will ask 9 times at nearly the same content. This may even be refined here using the // TextEffectStyle information, e.g. for TEXTEFFECTSTYLE2D_RELIEF the grow needs only to // be in two directions - basegfx::B2DRange aRetval(getB2DRangeFromPrimitive2DSequence(getChildren(), rViewInformation)); + basegfx::B2DRange aRetval(getB2DRangeFromPrimitive2DSequence(getTextContent(), rViewInformation)); aRetval.grow(fDiscreteSize); return aRetval; @@ -216,23 +218,23 @@ namespace drawinglayer { ::osl::MutexGuard aGuard( m_aMutex ); - if(getLocalDecomposition().hasElements()) + if(getBuffered2DDecomposition().hasElements()) { if(maLastObjectToViewTransformation != rViewInformation.getObjectToViewTransformation()) { // conditions of last local decomposition have changed, delete - const_cast< TextEffectPrimitive2D* >(this)->setLocalDecomposition(Primitive2DSequence()); + const_cast< TextEffectPrimitive2D* >(this)->setBuffered2DDecomposition(Primitive2DSequence()); } } - if(!getLocalDecomposition().hasElements()) + if(!getBuffered2DDecomposition().hasElements()) { // remember ViewRange and ViewTransformation const_cast< TextEffectPrimitive2D* >(this)->maLastObjectToViewTransformation = rViewInformation.getObjectToViewTransformation(); } // use parent implementation - return BasePrimitive2D::get2DDecomposition(rViewInformation); + return BufferedDecompositionPrimitive2D::get2DDecomposition(rViewInformation); } // provide unique ID diff --git a/drawinglayer/source/primitive2d/textenumsprimitive2d.cxx b/drawinglayer/source/primitive2d/textenumsprimitive2d.cxx new file mode 100644 index 000000000000..8b24668cb056 --- /dev/null +++ b/drawinglayer/source/primitive2d/textenumsprimitive2d.cxx @@ -0,0 +1,129 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: textprimitive2d.cxx,v $ + * + * $Revision: 1.22 $ + * + * last change: $Author: aw $ $Date: 2008-05-27 14:11:20 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_drawinglayer.hxx" + +#include <drawinglayer/primitive2d/textenumsprimitive2d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + TextLine mapFontUnderlineToTextLine(FontUnderline eLineStyle) + { + switch(eLineStyle) + { + case UNDERLINE_SINGLE: return TEXT_LINE_SINGLE; + case UNDERLINE_DOUBLE: return TEXT_LINE_DOUBLE; + case UNDERLINE_DOTTED: return TEXT_LINE_DOTTED; + case UNDERLINE_DASH: return TEXT_LINE_DASH; + case UNDERLINE_LONGDASH: return TEXT_LINE_LONGDASH; + case UNDERLINE_DASHDOT: return TEXT_LINE_DASHDOT; + case UNDERLINE_DASHDOTDOT: return TEXT_LINE_DASHDOTDOT; + case UNDERLINE_SMALLWAVE: return TEXT_LINE_SMALLWAVE; + case UNDERLINE_WAVE: return TEXT_LINE_WAVE; + case UNDERLINE_DOUBLEWAVE: return TEXT_LINE_DOUBLEWAVE; + case UNDERLINE_BOLD: return TEXT_LINE_BOLD; + case UNDERLINE_BOLDDOTTED: return TEXT_LINE_BOLDDOTTED; + case UNDERLINE_BOLDDASH: return TEXT_LINE_BOLDDASH; + case UNDERLINE_BOLDLONGDASH: return TEXT_LINE_BOLDLONGDASH; + case UNDERLINE_BOLDDASHDOT: return TEXT_LINE_BOLDDASHDOT; + case UNDERLINE_BOLDDASHDOTDOT: return TEXT_LINE_BOLDDASHDOTDOT; + case UNDERLINE_BOLDWAVE: return TEXT_LINE_BOLDWAVE; + // FontUnderline_FORCE_EQUAL_SIZE, UNDERLINE_DONTKNOW, UNDERLINE_NONE + default: return TEXT_LINE_NONE; + } + } + + FontUnderline mapTextLineToFontUnderline(TextLine eLineStyle) + { + switch(eLineStyle) + { + default: /*TEXT_LINE_NONE*/ return UNDERLINE_NONE; + case TEXT_LINE_SINGLE: return UNDERLINE_SINGLE; + case TEXT_LINE_DOUBLE: return UNDERLINE_DOUBLE; + case TEXT_LINE_DOTTED: return UNDERLINE_DOTTED; + case TEXT_LINE_DASH: return UNDERLINE_DASH; + case TEXT_LINE_LONGDASH: return UNDERLINE_LONGDASH; + case TEXT_LINE_DASHDOT: return UNDERLINE_DASHDOT; + case TEXT_LINE_DASHDOTDOT: return UNDERLINE_DASHDOTDOT; + case TEXT_LINE_SMALLWAVE: return UNDERLINE_SMALLWAVE; + case TEXT_LINE_WAVE: return UNDERLINE_WAVE; + case TEXT_LINE_DOUBLEWAVE: return UNDERLINE_DOUBLEWAVE; + case TEXT_LINE_BOLD: return UNDERLINE_BOLD; + case TEXT_LINE_BOLDDOTTED: return UNDERLINE_BOLDDOTTED; + case TEXT_LINE_BOLDDASH: return UNDERLINE_BOLDDASH; + case TEXT_LINE_BOLDLONGDASH: return UNDERLINE_LONGDASH; + case TEXT_LINE_BOLDDASHDOT: return UNDERLINE_BOLDDASHDOT; + case TEXT_LINE_BOLDDASHDOTDOT:return UNDERLINE_BOLDDASHDOT; + case TEXT_LINE_BOLDWAVE: return UNDERLINE_BOLDWAVE; + } + } + + TextStrikeout mapFontStrikeoutToTextStrikeout(FontStrikeout eFontStrikeout) + { + switch(eFontStrikeout) + { + case STRIKEOUT_SINGLE: return TEXT_STRIKEOUT_SINGLE; + case STRIKEOUT_DOUBLE: return TEXT_STRIKEOUT_DOUBLE; + case STRIKEOUT_BOLD: return TEXT_STRIKEOUT_BOLD; + case STRIKEOUT_SLASH: return TEXT_STRIKEOUT_SLASH; + case STRIKEOUT_X: return TEXT_STRIKEOUT_X; + // FontStrikeout_FORCE_EQUAL_SIZE, STRIKEOUT_NONE, STRIKEOUT_DONTKNOW + default: return TEXT_STRIKEOUT_NONE; + } + } + + FontStrikeout mapTextStrikeoutToFontStrikeout(TextStrikeout eTextStrikeout) + { + switch(eTextStrikeout) + { + default: /*case primitive2d::TEXT_STRIKEOUT_NONE*/ return STRIKEOUT_NONE; + case TEXT_STRIKEOUT_SINGLE: return STRIKEOUT_SINGLE; + case TEXT_STRIKEOUT_DOUBLE: return STRIKEOUT_DOUBLE; + case TEXT_STRIKEOUT_BOLD: return STRIKEOUT_BOLD; + case TEXT_STRIKEOUT_SLASH: return STRIKEOUT_SLASH; + case TEXT_STRIKEOUT_X: return STRIKEOUT_X; + } + } + + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/drawinglayer/source/primitive2d/textlayoutdevice.cxx b/drawinglayer/source/primitive2d/textlayoutdevice.cxx index e321783c8406..2950427d6b57 100644 --- a/drawinglayer/source/primitive2d/textlayoutdevice.cxx +++ b/drawinglayer/source/primitive2d/textlayoutdevice.cxx @@ -167,14 +167,14 @@ namespace drawinglayer mrDevice.SetFont( rFont ); } - void TextLayouterDevice::setFontAttributes( - const FontAttributes& rFontAttributes, + void TextLayouterDevice::setFontAttribute( + const attribute::FontAttribute& rFontAttribute, double fFontScaleX, double fFontScaleY, const ::com::sun::star::lang::Locale& rLocale) { - setFont(getVclFontFromFontAttributes( - rFontAttributes, + setFont(getVclFontFromFontAttribute( + rFontAttribute, fFontScaleX, fFontScaleY, 0.0, @@ -297,6 +297,28 @@ namespace drawinglayer return basegfx::B2DRange(); } + + double TextLayouterDevice::getFontAscent() const + { + const ::FontMetric& rMetric = mrDevice.GetFontMetric(); + return rMetric.GetAscent(); + } + + double TextLayouterDevice::getFontDescent() const + { + const ::FontMetric& rMetric = mrDevice.GetFontMetric(); + return rMetric.GetDescent(); + } + + void TextLayouterDevice::addTextRectActions( + const Rectangle& rRectangle, + const String& rText, + sal_uInt16 nStyle, + GDIMetaFile& rGDIMetaFile) + { + mrDevice.AddTextRectActions( + rRectangle, rText, nStyle, rGDIMetaFile); + } } // end of namespace primitive2d } // end of namespace drawinglayer @@ -307,8 +329,8 @@ namespace drawinglayer { namespace primitive2d { - Font getVclFontFromFontAttributes( - const FontAttributes& rFontAttributes, + Font getVclFontFromFontAttribute( + const attribute::FontAttribute& rFontAttribute, double fFontScaleX, double fFontScaleY, double fFontRotation, @@ -324,8 +346,8 @@ namespace drawinglayer // is wanted, that width needs to be adapted using FontMetric again to get a // width of the unscaled font Font aRetval( - rFontAttributes.getFamilyName(), - rFontAttributes.getStyleName(), + rFontAttribute.getFamilyName(), + rFontAttribute.getStyleName(), Size(0, nHeight)); #else // for non-WIN32 systems things are easier since these accept a Font creation @@ -334,17 +356,17 @@ namespace drawinglayer // Font would be recorded in a MetaFile (The MetaFile FontAction WILL record a // set FontWidth; import that in a WIN32 system, and trouble is there) Font aRetval( - rFontAttributes.getFamilyName(), - rFontAttributes.getStyleName(), + rFontAttribute.getFamilyName(), + rFontAttribute.getStyleName(), Size(bFontIsScaled ? nWidth : 0, nHeight)); #endif - // define various other FontAttributes + // define various other FontAttribute aRetval.SetAlign(ALIGN_BASELINE); - aRetval.SetCharSet(rFontAttributes.getSymbol() ? RTL_TEXTENCODING_SYMBOL : RTL_TEXTENCODING_UNICODE); - aRetval.SetVertical(rFontAttributes.getVertical() ? TRUE : FALSE); - aRetval.SetWeight(static_cast<FontWeight>(rFontAttributes.getWeight())); - aRetval.SetItalic(rFontAttributes.getItalic() ? ITALIC_NORMAL : ITALIC_NONE); - aRetval.SetOutline(rFontAttributes.getOutline()); + aRetval.SetCharSet(rFontAttribute.getSymbol() ? RTL_TEXTENCODING_SYMBOL : RTL_TEXTENCODING_UNICODE); + aRetval.SetVertical(rFontAttribute.getVertical() ? TRUE : FALSE); + aRetval.SetWeight(static_cast<FontWeight>(rFontAttribute.getWeight())); + aRetval.SetItalic(rFontAttribute.getItalic() ? ITALIC_NORMAL : ITALIC_NONE); + aRetval.SetOutline(rFontAttribute.getOutline()); aRetval.SetLanguage(MsLangId::convertLocaleToLanguage(rLocale)); #ifdef WIN32 @@ -371,13 +393,13 @@ namespace drawinglayer return aRetval; } - FontAttributes getFontAttributesFromVclFont( + attribute::FontAttribute getFontAttributeFromVclFont( basegfx::B2DVector& o_rSize, const Font& rFont, bool bRTL, bool bBiDiStrong) { - const FontAttributes aRetval( + const attribute::FontAttribute aRetval( rFont.GetName(), rFont.GetStyleName(), static_cast<sal_uInt16>(rFont.GetWeight()), diff --git a/drawinglayer/source/primitive2d/textlineprimitive2d.cxx b/drawinglayer/source/primitive2d/textlineprimitive2d.cxx new file mode 100644 index 000000000000..45b2809be2ce --- /dev/null +++ b/drawinglayer/source/primitive2d/textlineprimitive2d.cxx @@ -0,0 +1,317 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: textdecoratedprimitive2d.cxx,v $ + * + * $Revision: 1.12 $ + * + * last change: $Author: aw $ $Date: 2008-05-27 14:11:20 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_drawinglayer.hxx" + +#include <drawinglayer/primitive2d/textlineprimitive2d.hxx> +#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx> +#include <drawinglayer/attribute/strokeattribute.hxx> +#include <drawinglayer/attribute/lineattribute.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> +#include <drawinglayer/primitive2d/polygonprimitive2d.hxx> +#include <drawinglayer/primitive2d/transformprimitive2d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + Primitive2DSequence TextLinePrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const + { + Primitive2DSequence xRetval; + + if(TEXT_LINE_NONE != getTextLine()) + { + bool bDoubleLine(false); + bool bWaveLine(false); + bool bBoldLine(false); + const int* pDotDashArray(0); + basegfx::B2DLineJoin eLineJoin(basegfx::B2DLINEJOIN_NONE); + double fOffset(getOffset()); + double fHeight(getHeight()); + + static const int aDottedArray[] = { 1, 1, 0}; // DOTTED LINE + static const int aDotDashArray[] = { 1, 1, 4, 1, 0}; // DASHDOT + static const int aDashDotDotArray[] = { 1, 1, 1, 1, 4, 1, 0}; // DASHDOTDOT + static const int aDashedArray[] = { 5, 2, 0}; // DASHED LINE + static const int aLongDashArray[] = { 7, 2, 0}; // LONGDASH + + // get decomposition + basegfx::B2DVector aScale, aTranslate; + double fRotate, fShearX; + getObjectTransformation().decompose(aScale, aTranslate, fRotate, fShearX); + + switch(getTextLine()) + { + default: // case TEXT_LINE_SINGLE: + { + break; + } + case TEXT_LINE_DOUBLE: + { + bDoubleLine = true; + break; + } + case TEXT_LINE_DOTTED: + { + pDotDashArray = aDottedArray; + break; + } + case TEXT_LINE_DASH: + { + pDotDashArray = aDashedArray; + break; + } + case TEXT_LINE_LONGDASH: + { + pDotDashArray = aLongDashArray; + break; + } + case TEXT_LINE_DASHDOT: + { + pDotDashArray = aDotDashArray; + break; + } + case TEXT_LINE_DASHDOTDOT: + { + pDotDashArray = aDashDotDotArray; + break; + } + case TEXT_LINE_SMALLWAVE: + { + bWaveLine = true; + break; + } + case TEXT_LINE_WAVE: + { + bWaveLine = true; + break; + } + case TEXT_LINE_DOUBLEWAVE: + { + bDoubleLine = true; + bWaveLine = true; + break; + } + case TEXT_LINE_BOLD: + { + bBoldLine = true; + break; + } + case TEXT_LINE_BOLDDOTTED: + { + bBoldLine = true; + pDotDashArray = aDottedArray; + break; + } + case TEXT_LINE_BOLDDASH: + { + bBoldLine = true; + pDotDashArray = aDashedArray; + break; + } + case TEXT_LINE_BOLDLONGDASH: + { + bBoldLine = true; + pDotDashArray = aLongDashArray; + break; + } + case TEXT_LINE_BOLDDASHDOT: + { + bBoldLine = true; + pDotDashArray = aDotDashArray; + break; + } + case TEXT_LINE_BOLDDASHDOTDOT: + { + bBoldLine = true; + pDotDashArray = aDashDotDotArray; + break; + } + case TEXT_LINE_BOLDWAVE: + { + bWaveLine = true; + bBoldLine = true; + break; + } + } + + if(bBoldLine) + { + fHeight *= 2.0; + } + + if(bDoubleLine) + { + fOffset -= 0.50 * fHeight; + fHeight *= 0.64; + } + + if(bWaveLine) + { + eLineJoin = basegfx::B2DLINEJOIN_ROUND; + fHeight *= 0.25; + } + + // prepare Line and Stroke Attributes + const attribute::LineAttribute aLineAttribute(getLineColor(), fHeight, eLineJoin); + attribute::StrokeAttribute aStrokeAttribute; + + if(pDotDashArray) + { + ::std::vector< double > aDoubleArray; + + for(const int* p = pDotDashArray; *p; ++p) + { + aDoubleArray.push_back((double)(*p) * fHeight); + } + + aStrokeAttribute = attribute::StrokeAttribute(aDoubleArray); + } + + // create base polygon and new primitive + basegfx::B2DPolygon aLine; + Primitive2DReference aNewPrimitive; + + aLine.append(basegfx::B2DPoint(0.0, fOffset)); + aLine.append(basegfx::B2DPoint(getWidth(), fOffset)); + + const basegfx::B2DHomMatrix aUnscaledTransform( + basegfx::tools::createShearXRotateTranslateB2DHomMatrix( + fShearX, fRotate, aTranslate)); + + aLine.transform(aUnscaledTransform); + + if(bWaveLine) + { + double fWaveWidth(10.6 * fHeight); + + if(TEXT_LINE_SMALLWAVE == getTextLine()) + { + fWaveWidth *= 0.7; + } + else if(TEXT_LINE_WAVE == getTextLine()) + { + // extra multiply to get the same WaveWidth as with the bold version + fWaveWidth *= 2.0; + } + + aNewPrimitive = Primitive2DReference(new PolygonWavePrimitive2D(aLine, aLineAttribute, aStrokeAttribute, fWaveWidth, fWaveWidth * 0.5)); + } + else + { + aNewPrimitive = Primitive2DReference(new PolygonStrokePrimitive2D(aLine, aLineAttribute, aStrokeAttribute)); + } + + // add primitive + appendPrimitive2DReferenceToPrimitive2DSequence(xRetval, aNewPrimitive); + + if(bDoubleLine) + { + // double line, create 2nd primitive with offset using TransformPrimitive based on + // already created NewPrimitive + double fLineDist(2.3 * fHeight); + + if(bWaveLine) + { + fLineDist = 6.3 * fHeight; + } + + // move base point of text to 0.0 and de-rotate + basegfx::B2DHomMatrix aTransform(basegfx::tools::createTranslateB2DHomMatrix( + -aTranslate.getX(), -aTranslate.getY())); + aTransform.rotate(-fRotate); + + // translate in Y by offset + aTransform.translate(0.0, fLineDist); + + // move back and rotate + aTransform.rotate(fRotate); + aTransform.translate(aTranslate.getX(), aTranslate.getY()); + + // add transform primitive + const Primitive2DSequence aContent(&aNewPrimitive, 1); + appendPrimitive2DReferenceToPrimitive2DSequence(xRetval, + Primitive2DReference(new TransformPrimitive2D(aTransform, aContent))); + } + } + + return xRetval; + } + + TextLinePrimitive2D::TextLinePrimitive2D( + const basegfx::B2DHomMatrix& rObjectTransformation, + double fWidth, + double fOffset, + double fHeight, + TextLine eTextLine, + const basegfx::BColor& rLineColor) + : BufferedDecompositionPrimitive2D(), + maObjectTransformation(rObjectTransformation), + mfWidth(fWidth), + mfOffset(fOffset), + mfHeight(fHeight), + meTextLine(eTextLine), + maLineColor(rLineColor) + { + } + + bool TextLinePrimitive2D::operator==( const BasePrimitive2D& rPrimitive ) const + { + if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) + { + const TextLinePrimitive2D& rCompare = (TextLinePrimitive2D&)rPrimitive; + + return (getObjectTransformation() == rCompare.getObjectTransformation() + && getWidth() == rCompare.getWidth() + && getOffset() == rCompare.getOffset() + && getHeight() == rCompare.getHeight() + && getTextLine() == rCompare.getTextLine() + && getLineColor() == rCompare.getLineColor()); + } + + return false; + } + + // provide unique ID + ImplPrimitrive2DIDBlock(TextLinePrimitive2D, PRIMITIVE2D_ID_TEXTLINEPRIMITIVE2D) + + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/drawinglayer/source/primitive2d/textprimitive2d.cxx b/drawinglayer/source/primitive2d/textprimitive2d.cxx index f8e413da0e8c..61a0c6d15897 100644 --- a/drawinglayer/source/primitive2d/textprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/textprimitive2d.cxx @@ -42,6 +42,7 @@ #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx> #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx> #include <drawinglayer/primitive2d/texteffectprimitive2d.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> ////////////////////////////////////////////////////////////////////////////// @@ -49,27 +50,6 @@ using namespace com::sun::star; ////////////////////////////////////////////////////////////////////////////// -namespace drawinglayer -{ - namespace primitive2d - { - bool FontAttributes::operator==(const FontAttributes& rCompare) const - { - return (getFamilyName() == rCompare.getFamilyName() - && getStyleName() == rCompare.getStyleName() - && getWeight() == rCompare.getWeight() - && getSymbol() == rCompare.getSymbol() - && getVertical() == rCompare.getVertical() - && getItalic() == rCompare.getItalic() - && getOutline() == rCompare.getOutline() - && getRTL() == rCompare.getRTL() - && getBiDiStrong() == rCompare.getBiDiStrong()); - } - } // end of namespace primitive2d -} // end of namespace drawinglayer - -////////////////////////////////////////////////////////////////////////////// - namespace { // adapts fontScale for usage with TextLayouter. Input is rScale which is the extracted @@ -155,8 +135,8 @@ namespace drawinglayer // prepare textlayoutdevice TextLayouterDevice aTextLayouter; - aTextLayouter.setFontAttributes( - getFontAttributes(), + aTextLayouter.setFontAttribute( + getFontAttribute(), aFontScale.getX(), aFontScale.getY(), getLocale()); @@ -199,17 +179,14 @@ namespace drawinglayer if(nCount) { // prepare object transformation for polygons - rTransformation.identity(); - rTransformation.scale(aScale.getX(), aScale.getY()); - rTransformation.shearX(fShearX); - rTransformation.rotate(fRotate); - rTransformation.translate(aTranslate.getX(), aTranslate.getY()); + rTransformation = basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix( + aScale, fShearX, fRotate, aTranslate); } } } } - Primitive2DSequence TextSimplePortionPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const + Primitive2DSequence TextSimplePortionPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const { Primitive2DSequence aRetval; @@ -238,7 +215,7 @@ namespace drawinglayer aRetval[a] = new PolyPolygonColorPrimitive2D(rPolyPolygon, getFontColor()); } - if(getFontAttributes().getOutline()) + if(getFontAttribute().getOutline()) { // decompose polygon transformation to single values basegfx::B2DVector aScale, aTranslate; @@ -266,16 +243,16 @@ namespace drawinglayer xub_StrLen aTextPosition, xub_StrLen aTextLength, const ::std::vector< double >& rDXArray, - const FontAttributes& rFontAttributes, + const attribute::FontAttribute& rFontAttribute, const ::com::sun::star::lang::Locale& rLocale, const basegfx::BColor& rFontColor) - : BasePrimitive2D(), + : BufferedDecompositionPrimitive2D(), maTextTransform(rNewTransform), maText(rText), maTextPosition(aTextPosition), maTextLength(aTextLength), maDXArray(rDXArray), - maFontAttributes(rFontAttributes), + maFontAttribute(rFontAttribute), maLocale(rLocale), maFontColor(rFontColor), maB2DRange() @@ -287,7 +264,7 @@ namespace drawinglayer #endif } - bool impLocalesAreEqual(const ::com::sun::star::lang::Locale& rA, const ::com::sun::star::lang::Locale& rB) + bool LocalesAreEqual(const ::com::sun::star::lang::Locale& rA, const ::com::sun::star::lang::Locale& rB) { return (rA.Language == rB.Language && rA.Country == rB.Country @@ -296,7 +273,7 @@ namespace drawinglayer bool TextSimplePortionPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const { - if(BasePrimitive2D::operator==(rPrimitive)) + if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) { const TextSimplePortionPrimitive2D& rCompare = (TextSimplePortionPrimitive2D&)rPrimitive; @@ -305,8 +282,8 @@ namespace drawinglayer && getTextPosition() == rCompare.getTextPosition() && getTextLength() == rCompare.getTextLength() && getDXArray() == rCompare.getDXArray() - && getFontAttributes() == rCompare.getFontAttributes() - && impLocalesAreEqual(getLocale(), rCompare.getLocale()) + && getFontAttribute() == rCompare.getFontAttribute() + && LocalesAreEqual(getLocale(), rCompare.getLocale()) && getFontColor() == rCompare.getFontColor()); } @@ -332,8 +309,8 @@ namespace drawinglayer // prepare textlayoutdevice TextLayouterDevice aTextLayouter; - aTextLayouter.setFontAttributes( - getFontAttributes(), + aTextLayouter.setFontAttribute( + getFontAttribute(), aFontScale.getX(), aFontScale.getY(), getLocale()); @@ -345,12 +322,8 @@ namespace drawinglayer if(!aNewRange.isEmpty()) { // prepare object transformation for range - basegfx::B2DHomMatrix aRangeTransformation; - - aRangeTransformation.scale(aScale.getX(), aScale.getY()); - aRangeTransformation.shearX(fShearX); - aRangeTransformation.rotate(fRotate); - aRangeTransformation.translate(aTranslate.getX(), aTranslate.getY()); + const basegfx::B2DHomMatrix aRangeTransformation(basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix( + aScale, fShearX, fRotate, aTranslate)); // apply range transformation to it aNewRange.transform(aRangeTransformation); diff --git a/drawinglayer/source/primitive2d/textstrikeoutprimitive2d.cxx b/drawinglayer/source/primitive2d/textstrikeoutprimitive2d.cxx new file mode 100644 index 000000000000..936c690d8af5 --- /dev/null +++ b/drawinglayer/source/primitive2d/textstrikeoutprimitive2d.cxx @@ -0,0 +1,294 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: textdecoratedprimitive2d.cxx,v $ + * + * $Revision: 1.12 $ + * + * last change: $Author: aw $ $Date: 2008-05-27 14:11:20 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_drawinglayer.hxx" + +#include <drawinglayer/primitive2d/textstrikeoutprimitive2d.hxx> +#include <drawinglayer/primitive2d/textlayoutdevice.hxx> +#include <drawinglayer/primitive2d/textprimitive2d.hxx> +#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> +#include <drawinglayer/attribute/lineattribute.hxx> +#include <drawinglayer/primitive2d/polygonprimitive2d.hxx> +#include <drawinglayer/primitive2d/transformprimitive2d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + BaseTextStrikeoutPrimitive2D::BaseTextStrikeoutPrimitive2D( + const basegfx::B2DHomMatrix& rObjectTransformation, + double fWidth, + const basegfx::BColor& rFontColor) + : BufferedDecompositionPrimitive2D(), + maObjectTransformation(rObjectTransformation), + mfWidth(fWidth), + maFontColor(rFontColor) + { + } + + bool BaseTextStrikeoutPrimitive2D::operator==( const BasePrimitive2D& rPrimitive ) const + { + if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) + { + const BaseTextStrikeoutPrimitive2D& rCompare = (BaseTextStrikeoutPrimitive2D&)rPrimitive; + + return (getObjectTransformation() == rCompare.getObjectTransformation() + && getWidth() == rCompare.getWidth() + && getFontColor() == rCompare.getFontColor()); + } + + return false; + } + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + Primitive2DSequence TextCharacterStrikeoutPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const + { + // strikeout with character + const String aSingleCharString(getStrikeoutChar()); + basegfx::B2DVector aScale, aTranslate; + double fRotate, fShearX; + + // get decomposition + getObjectTransformation().decompose(aScale, aTranslate, fRotate, fShearX); + + // prepare TextLayouter + TextLayouterDevice aTextLayouter; + + aTextLayouter.setFontAttribute( + getFontAttribute(), + aScale.getX(), + aScale.getY(), + getLocale()); + + const double fStrikeCharWidth(aTextLayouter.getTextWidth(aSingleCharString, 0, 1)); + const double fStrikeCharCount(fabs(getWidth()/fStrikeCharWidth)); + const sal_uInt32 nStrikeCharCount(static_cast< sal_uInt32 >(fStrikeCharCount + 0.5)); + std::vector<double> aDXArray(nStrikeCharCount); + String aStrikeoutString; + + for(sal_uInt32 a(0); a < nStrikeCharCount; a++) + { + aStrikeoutString += aSingleCharString; + aDXArray[a] = (a + 1) * fStrikeCharWidth; + } + + Primitive2DReference xReference( + new TextSimplePortionPrimitive2D( + getObjectTransformation(), + aStrikeoutString, + 0, + aStrikeoutString.Len(), + aDXArray, + getFontAttribute(), + getLocale(), + getFontColor())); + + return Primitive2DSequence(&xReference, 1); + } + + TextCharacterStrikeoutPrimitive2D::TextCharacterStrikeoutPrimitive2D( + const basegfx::B2DHomMatrix& rObjectTransformation, + double fWidth, + const basegfx::BColor& rFontColor, + sal_Unicode aStrikeoutChar, + const attribute::FontAttribute& rFontAttribute, + const ::com::sun::star::lang::Locale& rLocale) + : BaseTextStrikeoutPrimitive2D(rObjectTransformation, fWidth, rFontColor), + maStrikeoutChar(aStrikeoutChar), + maFontAttribute(rFontAttribute), + maLocale(rLocale) + { + } + + bool TextCharacterStrikeoutPrimitive2D::operator==( const BasePrimitive2D& rPrimitive ) const + { + if(BaseTextStrikeoutPrimitive2D::operator==(rPrimitive)) + { + const TextCharacterStrikeoutPrimitive2D& rCompare = (TextCharacterStrikeoutPrimitive2D&)rPrimitive; + + return (getStrikeoutChar() == rCompare.getStrikeoutChar() + && getFontAttribute() == rCompare.getFontAttribute() + && LocalesAreEqual(getLocale(), rCompare.getLocale())); + } + + return false; + } + + // provide unique ID + ImplPrimitrive2DIDBlock(TextCharacterStrikeoutPrimitive2D, PRIMITIVE2D_ID_TEXTCHARACTERSTRIKEOUTPRIMITIVE2D) + + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + Primitive2DSequence TextGeometryStrikeoutPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const + { + OSL_ENSURE(TEXT_STRIKEOUT_SLASH != getTextStrikeout() && TEXT_STRIKEOUT_X != getTextStrikeout(), + "Wrong TEXT_STRIKEOUT type; a TextCharacterStrikeoutPrimitive2D should be used (!)"); + + // strikeout with geometry + double fStrikeoutHeight(getHeight()); + double fStrikeoutOffset(getOffset()); + bool bDoubleLine(false); + + // get decomposition + basegfx::B2DVector aScale, aTranslate; + double fRotate, fShearX; + getObjectTransformation().decompose(aScale, aTranslate, fRotate, fShearX); + + // set line attribute + switch(getTextStrikeout()) + { + default : // case primitive2d::TEXT_STRIKEOUT_SINGLE: + { + break; + } + case primitive2d::TEXT_STRIKEOUT_DOUBLE: + { + bDoubleLine = true; + break; + } + case primitive2d::TEXT_STRIKEOUT_BOLD: + { + fStrikeoutHeight *= 2.0; + break; + } + } + + if(bDoubleLine) + { + fStrikeoutOffset -= 0.50 * fStrikeoutHeight; + fStrikeoutHeight *= 0.64; + } + + // create base polygon and new primitive + basegfx::B2DPolygon aStrikeoutLine; + + aStrikeoutLine.append(basegfx::B2DPoint(0.0, -fStrikeoutOffset)); + aStrikeoutLine.append(basegfx::B2DPoint(getWidth(), -fStrikeoutOffset)); + + const basegfx::B2DHomMatrix aUnscaledTransform( + basegfx::tools::createShearXRotateTranslateB2DHomMatrix( + fShearX, fRotate, aTranslate)); + + aStrikeoutLine.transform(aUnscaledTransform); + + // add primitive + const attribute::LineAttribute aLineAttribute(getFontColor(), fStrikeoutHeight, basegfx::B2DLINEJOIN_NONE); + Primitive2DSequence xRetval(1); + xRetval[0] = Primitive2DReference(new PolygonStrokePrimitive2D(aStrikeoutLine, aLineAttribute)); + + if(bDoubleLine) + { + // double line, create 2nd primitive with offset using TransformPrimitive based on + // already created NewPrimitive + const double fLineDist(2.0 * fStrikeoutHeight); + + // move base point of text to 0.0 and de-rotate + basegfx::B2DHomMatrix aTransform(basegfx::tools::createTranslateB2DHomMatrix( + -aTranslate.getX(), -aTranslate.getY())); + aTransform.rotate(-fRotate); + + // translate in Y by offset + aTransform.translate(0.0, -fLineDist); + + // move back and rotate + aTransform.rotate(fRotate); + aTransform.translate(aTranslate.getX(), aTranslate.getY()); + + // add transform primitive + appendPrimitive2DReferenceToPrimitive2DSequence(xRetval, + Primitive2DReference( + new TransformPrimitive2D( + aTransform, + xRetval))); + } + + return xRetval; + } + + TextGeometryStrikeoutPrimitive2D::TextGeometryStrikeoutPrimitive2D( + const basegfx::B2DHomMatrix& rObjectTransformation, + double fWidth, + const basegfx::BColor& rFontColor, + double fHeight, + double fOffset, + TextStrikeout eTextStrikeout) + : BaseTextStrikeoutPrimitive2D(rObjectTransformation, fWidth, rFontColor), + mfHeight(fHeight), + mfOffset(fOffset), + meTextStrikeout(eTextStrikeout) + { + } + + bool TextGeometryStrikeoutPrimitive2D::operator==( const BasePrimitive2D& rPrimitive ) const + { + if(BaseTextStrikeoutPrimitive2D::operator==(rPrimitive)) + { + const TextGeometryStrikeoutPrimitive2D& rCompare = (TextGeometryStrikeoutPrimitive2D&)rPrimitive; + + return (getHeight() == rCompare.getHeight() + && getOffset() == rCompare.getOffset() + && getTextStrikeout() == rCompare.getTextStrikeout()); + } + + return false; + } + + // provide unique ID + ImplPrimitrive2DIDBlock(TextGeometryStrikeoutPrimitive2D, PRIMITIVE2D_ID_TEXTGEOMETRYSTRIKEOUTPRIMITIVE2D) + + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/drawinglayer/source/primitive2d/unifiedalphaprimitive2d.cxx b/drawinglayer/source/primitive2d/unifiedalphaprimitive2d.cxx index 49039e1a6e5c..a66ac0f3a539 100644 --- a/drawinglayer/source/primitive2d/unifiedalphaprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/unifiedalphaprimitive2d.cxx @@ -55,7 +55,27 @@ namespace drawinglayer { namespace primitive2d { - Primitive2DSequence UnifiedAlphaPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const + UnifiedAlphaPrimitive2D::UnifiedAlphaPrimitive2D( + const Primitive2DSequence& rChildren, + double fAlpha) + : GroupPrimitive2D(rChildren), + mfAlpha(fAlpha) + { + } + + bool UnifiedAlphaPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const + { + if(GroupPrimitive2D::operator==(rPrimitive)) + { + const UnifiedAlphaPrimitive2D& rCompare = (UnifiedAlphaPrimitive2D&)rPrimitive; + + return (getAlpha() == rCompare.getAlpha()); + } + + return false; + } + + Primitive2DSequence UnifiedAlphaPrimitive2D::get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const { if(0.0 == getAlpha()) { @@ -99,26 +119,6 @@ namespace drawinglayer } } - UnifiedAlphaPrimitive2D::UnifiedAlphaPrimitive2D( - const Primitive2DSequence& rChildren, - double fAlpha) - : GroupPrimitive2D(rChildren), - mfAlpha(fAlpha) - { - } - - bool UnifiedAlphaPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const - { - if(GroupPrimitive2D::operator==(rPrimitive)) - { - const UnifiedAlphaPrimitive2D& rCompare = (UnifiedAlphaPrimitive2D&)rPrimitive; - - return (getAlpha() == rCompare.getAlpha()); - } - - return false; - } - // provide unique ID ImplPrimitrive2DIDBlock(UnifiedAlphaPrimitive2D, PRIMITIVE2D_ID_UNIFIEDALPHAPRIMITIVE2D) diff --git a/drawinglayer/source/primitive2d/wallpaperprimitive2d.cxx b/drawinglayer/source/primitive2d/wallpaperprimitive2d.cxx new file mode 100644 index 000000000000..621b0b25ad98 --- /dev/null +++ b/drawinglayer/source/primitive2d/wallpaperprimitive2d.cxx @@ -0,0 +1,276 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: bitmapprimitive2d.cxx,v $ + * + * $Revision: 1.5 $ + * + * last change: $Author: aw $ $Date: 2008-05-27 14:11:20 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_drawinglayer.hxx" + +#include <drawinglayer/primitive2d/wallpaperprimitive2d.hxx> +#include <drawinglayer/primitive2d/bitmapprimitive2d.hxx> +#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx> +#include <drawinglayer/primitive2d/fillbitmapprimitive2d.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <drawinglayer/primitive2d/maskprimitive2d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + Primitive2DSequence WallpaperBitmapPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const + { + Primitive2DSequence aRetval; + + if(!getLocalObjectRange().isEmpty() && !getBitmapEx().IsEmpty()) + { + // get bitmap PIXEL size + const Size& rPixelSize = getBitmapEx().GetSizePixel(); + + if(rPixelSize.Width() > 0 && rPixelSize.Height() > 0) + { + if(WALLPAPER_SCALE == getWallpaperStyle()) + { + // shortcut for scale; use simple BitmapPrimitive2D + 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()); + + Primitive2DReference xReference( + new BitmapPrimitive2D( + getBitmapEx(), + aObjectTransform)); + + aRetval = Primitive2DSequence(&xReference, 1); + } + else + { + // transform to logic size + basegfx::B2DHomMatrix aInverseViewTransformation(getViewTransformation()); + aInverseViewTransformation.invert(); + basegfx::B2DVector aLogicSize(rPixelSize.Width(), rPixelSize.Height()); + aLogicSize = aInverseViewTransformation * aLogicSize; + + // apply laout + basegfx::B2DPoint aTargetTopLeft(getLocalObjectRange().getMinimum()); + bool bUseTargetTopLeft(true); + bool bNeedsClipping(false); + + switch(getWallpaperStyle()) + { + default: //case WALLPAPER_TILE :, also WALLPAPER_NULL and WALLPAPER_APPLICATIONGRADIENT + { + bUseTargetTopLeft = false; + break; + } + case WALLPAPER_SCALE : + { + // handled by shortcut above + break; + } + case WALLPAPER_TOPLEFT : + { + // nothing to do + break; + } + case WALLPAPER_TOP : + { + const basegfx::B2DPoint aCenter(getLocalObjectRange().getCenter()); + aTargetTopLeft.setX(aCenter.getX() - (aLogicSize.getX() * 0.5)); + break; + } + case WALLPAPER_TOPRIGHT : + { + aTargetTopLeft.setX(getLocalObjectRange().getMaxX() - aLogicSize.getX()); + break; + } + case WALLPAPER_LEFT : + { + const basegfx::B2DPoint aCenter(getLocalObjectRange().getCenter()); + aTargetTopLeft.setY(aCenter.getY() - (aLogicSize.getY() * 0.5)); + break; + } + case WALLPAPER_CENTER : + { + const basegfx::B2DPoint aCenter(getLocalObjectRange().getCenter()); + aTargetTopLeft = aCenter - (aLogicSize * 0.5); + break; + } + case WALLPAPER_RIGHT : + { + const basegfx::B2DPoint aCenter(getLocalObjectRange().getCenter()); + aTargetTopLeft.setX(getLocalObjectRange().getMaxX() - aLogicSize.getX()); + aTargetTopLeft.setY(aCenter.getY() - (aLogicSize.getY() * 0.5)); + break; + } + case WALLPAPER_BOTTOMLEFT : + { + aTargetTopLeft.setY(getLocalObjectRange().getMaxY() - aLogicSize.getY()); + break; + } + case WALLPAPER_BOTTOM : + { + const basegfx::B2DPoint aCenter(getLocalObjectRange().getCenter()); + aTargetTopLeft.setX(aCenter.getX() - (aLogicSize.getX() * 0.5)); + aTargetTopLeft.setY(getLocalObjectRange().getMaxY() - aLogicSize.getY()); + break; + } + case WALLPAPER_BOTTOMRIGHT : + { + aTargetTopLeft = getLocalObjectRange().getMaximum() - aLogicSize; + break; + } + } + + if(bUseTargetTopLeft) + { + // fill target range + const basegfx::B2DRange aTargetRange(aTargetTopLeft, aTargetTopLeft + aLogicSize); + + // create aligned, single BitmapPrimitive2D + basegfx::B2DHomMatrix aObjectTransform; + + aObjectTransform.set(0, 0, aTargetRange.getWidth()); + aObjectTransform.set(1, 1, aTargetRange.getHeight()); + aObjectTransform.set(0, 2, aTargetRange.getMinX()); + aObjectTransform.set(1, 2, aTargetRange.getMinY()); + + Primitive2DReference xReference( + new BitmapPrimitive2D( + getBitmapEx(), + aObjectTransform)); + aRetval = Primitive2DSequence(&xReference, 1); + + // clip when not completely inside object range + bNeedsClipping = !getLocalObjectRange().isInside(aTargetRange); + } + else + { + // WALLPAPER_TILE, WALLPAPER_NULL, WALLPAPER_APPLICATIONGRADIENT + // convert to relative positions + const basegfx::B2DVector aRelativeSize( + aLogicSize.getX() / (getLocalObjectRange().getWidth() ? getLocalObjectRange().getWidth() : 1.0), + aLogicSize.getY() / (getLocalObjectRange().getHeight() ? getLocalObjectRange().getHeight() : 1.0)); + basegfx::B2DPoint aRelativeTopLeft(0.0, 0.0); + + if(WALLPAPER_TILE != getWallpaperStyle()) + { + aRelativeTopLeft.setX(0.5 - aRelativeSize.getX()); + aRelativeTopLeft.setY(0.5 - aRelativeSize.getY()); + } + + // prepare FillBitmapAttribute + const attribute::FillBitmapAttribute aFillBitmapAttribute( + getBitmapEx(), + 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()); + + // create FillBitmapPrimitive + const drawinglayer::primitive2d::Primitive2DReference xFillBitmap( + new drawinglayer::primitive2d::FillBitmapPrimitive2D( + aObjectTransform, + aFillBitmapAttribute)); + aRetval = Primitive2DSequence(&xFillBitmap, 1); + + // always embed tiled fill to clipping + bNeedsClipping = true; + } + + if(bNeedsClipping) + { + // embed to clipping; this is necessary for tiled fills + const basegfx::B2DPolyPolygon aPolyPolygon(basegfx::tools::createPolygonFromRect(getLocalObjectRange())); + const drawinglayer::primitive2d::Primitive2DReference xClippedFill( + new drawinglayer::primitive2d::MaskPrimitive2D( + aPolyPolygon, + aRetval)); + aRetval = Primitive2DSequence(&xClippedFill, 1); + } + } + } + } + + return aRetval; + } + + WallpaperBitmapPrimitive2D::WallpaperBitmapPrimitive2D( + const basegfx::B2DRange& rObjectRange, + const BitmapEx& rBitmapEx, + WallpaperStyle eWallpaperStyle) + : ViewTransformationDependentPrimitive2D(), + maObjectRange(rObjectRange), + maBitmapEx(rBitmapEx), + meWallpaperStyle(eWallpaperStyle) + { + } + + bool WallpaperBitmapPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const + { + if(ViewTransformationDependentPrimitive2D::operator==(rPrimitive)) + { + const WallpaperBitmapPrimitive2D& rCompare = (WallpaperBitmapPrimitive2D&)rPrimitive; + + return (getLocalObjectRange() == rCompare.getLocalObjectRange() + && getBitmapEx() == rCompare.getBitmapEx() + && getWallpaperStyle() == rCompare.getWallpaperStyle()); + } + + return false; + } + + basegfx::B2DRange WallpaperBitmapPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const + { + return getLocalObjectRange(); + } + + // provide unique ID + ImplPrimitrive2DIDBlock(WallpaperBitmapPrimitive2D, PRIMITIVE2D_ID_WALLPAPERBITMAPPRIMITIVE2D) + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/drawinglayer/source/primitive2d/wrongspellprimitive2d.cxx b/drawinglayer/source/primitive2d/wrongspellprimitive2d.cxx index 93a51d5379b3..4d50cb78da06 100644 --- a/drawinglayer/source/primitive2d/wrongspellprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/wrongspellprimitive2d.cxx @@ -48,7 +48,7 @@ namespace drawinglayer { namespace primitive2d { - Primitive2DSequence WrongSpellPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const + Primitive2DSequence WrongSpellPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const { // ATM this decompose is view-independent, what the original VCL-Display is not. To mimic // the old behaviour here if wanted it is necessary to add get2DDecomposition and implement @@ -97,7 +97,7 @@ namespace drawinglayer double fStart, double fStop, const basegfx::BColor& rColor) - : BasePrimitive2D(), + : BufferedDecompositionPrimitive2D(), maTransformation(rTransformation), mfStart(fStart), mfStop(fStop), @@ -107,7 +107,7 @@ namespace drawinglayer bool WrongSpellPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const { - if(BasePrimitive2D::operator==(rPrimitive)) + if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) { const WrongSpellPrimitive2D& rCompare = (WrongSpellPrimitive2D&)rPrimitive; diff --git a/drawinglayer/source/primitive3d/baseprimitive3d.cxx b/drawinglayer/source/primitive3d/baseprimitive3d.cxx index 032ae068003b..c30545e4f7c3 100644 --- a/drawinglayer/source/primitive3d/baseprimitive3d.cxx +++ b/drawinglayer/source/primitive3d/baseprimitive3d.cxx @@ -50,20 +50,18 @@ namespace drawinglayer { namespace primitive3d { - Primitive3DSequence BasePrimitive3D::createLocalDecomposition(const geometry::ViewInformation3D& /*rViewInformation*/) const + BasePrimitive3D::BasePrimitive3D() + : BasePrimitive3DImplBase(m_aMutex) { - return Primitive3DSequence(); } - BasePrimitive3D::BasePrimitive3D() - : BasePrimitive3DImplBase(m_aMutex), - maLocalDecomposition() + BasePrimitive3D::~BasePrimitive3D() { } bool BasePrimitive3D::operator==( const BasePrimitive3D& rPrimitive ) const { - return (getPrimitiveID() == rPrimitive.getPrimitiveID()); + return (getPrimitive3DID() == rPrimitive.getPrimitive3DID()); } basegfx::B3DRange BasePrimitive3D::getB3DRange(const geometry::ViewInformation3D& rViewInformation) const @@ -71,17 +69,9 @@ namespace drawinglayer return getB3DRangeFromPrimitive3DSequence(get3DDecomposition(rViewInformation), rViewInformation); } - Primitive3DSequence BasePrimitive3D::get3DDecomposition(const geometry::ViewInformation3D& rViewInformation) const + Primitive3DSequence BasePrimitive3D::get3DDecomposition(const geometry::ViewInformation3D& /*rViewInformation*/) const { - ::osl::MutexGuard aGuard( m_aMutex ); - - if(!getLocalDecomposition().hasElements()) - { - const Primitive3DSequence aNewSequence(createLocalDecomposition(rViewInformation)); - const_cast< BasePrimitive3D* >(this)->setLocalDecomposition(aNewSequence); - } - - return getLocalDecomposition(); + return Primitive3DSequence(); } Primitive3DSequence SAL_CALL BasePrimitive3D::getDecomposition( const uno::Sequence< beans::PropertyValue >& rViewParameters ) throw ( uno::RuntimeException ) @@ -99,6 +89,38 @@ namespace drawinglayer } // end of namespace drawinglayer ////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive3d + { + Primitive3DSequence BufferedDecompositionPrimitive3D::create3DDecomposition(const geometry::ViewInformation3D& /*rViewInformation*/) const + { + return Primitive3DSequence(); + } + + BufferedDecompositionPrimitive3D::BufferedDecompositionPrimitive3D() + : BasePrimitive3D(), + maBuffered3DDecomposition() + { + } + + Primitive3DSequence BufferedDecompositionPrimitive3D::get3DDecomposition(const geometry::ViewInformation3D& rViewInformation) const + { + ::osl::MutexGuard aGuard( m_aMutex ); + + if(!getBuffered3DDecomposition().hasElements()) + { + const Primitive3DSequence aNewSequence(create3DDecomposition(rViewInformation)); + const_cast< BufferedDecompositionPrimitive3D* >(this)->setBuffered3DDecomposition(aNewSequence); + } + + return getBuffered3DDecomposition(); + } + } // end of namespace primitive3d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// // tooling namespace drawinglayer diff --git a/drawinglayer/source/primitive3d/groupprimitive3d.cxx b/drawinglayer/source/primitive3d/groupprimitive3d.cxx index b8ed86ee952a..17736a276b38 100644 --- a/drawinglayer/source/primitive3d/groupprimitive3d.cxx +++ b/drawinglayer/source/primitive3d/groupprimitive3d.cxx @@ -49,12 +49,6 @@ namespace drawinglayer { namespace primitive3d { - /// default: just return children, so all renderers not supporting group will use it's content - Primitive3DSequence GroupPrimitive3D::createLocalDecomposition(const geometry::ViewInformation3D& /*rViewInformation*/) const - { - return getChildren(); - } - GroupPrimitive3D::GroupPrimitive3D( const Primitive3DSequence& rChildren ) : BasePrimitive3D(), maChildren(rChildren) @@ -77,6 +71,12 @@ namespace drawinglayer return false; } + /// default: just return children, so all renderers not supporting group will use it's content + Primitive3DSequence GroupPrimitive3D::get3DDecomposition(const geometry::ViewInformation3D& /*rViewInformation*/) const + { + return getChildren(); + } + // provide unique ID ImplPrimitrive3DIDBlock(GroupPrimitive3D, PRIMITIVE3D_ID_GROUPPRIMITIVE3D) diff --git a/drawinglayer/source/primitive3d/hatchtextureprimitive3d.cxx b/drawinglayer/source/primitive3d/hatchtextureprimitive3d.cxx index dd49f99b751c..381b70d4f6cc 100644 --- a/drawinglayer/source/primitive3d/hatchtextureprimitive3d.cxx +++ b/drawinglayer/source/primitive3d/hatchtextureprimitive3d.cxx @@ -59,7 +59,7 @@ namespace drawinglayer { namespace primitive3d { - Primitive3DSequence HatchTexturePrimitive3D::createLocalDecomposition(const geometry::ViewInformation3D& /*rViewInformation*/) const + Primitive3DSequence HatchTexturePrimitive3D::impCreate3DDecomposition() const { Primitive3DSequence aRetval; @@ -81,9 +81,9 @@ namespace drawinglayer if(pBasePrimitive) { - // it is a BasePrimitive3D implementation, use getPrimitiveID() call for switch + // it is a BasePrimitive3D implementation, use getPrimitive3DID() call for switch // not all content is needed, remove transparencies and ModifiedColorPrimitives - switch(pBasePrimitive->getPrimitiveID()) + switch(pBasePrimitive->getPrimitive3DID()) { case PRIMITIVE3D_ID_POLYPOLYGONMATERIALPRIMITIVE3D : { @@ -287,7 +287,8 @@ namespace drawinglayer bool bModulate, bool bFilter) : TexturePrimitive3D(rChildren, rTextureSize, bModulate, bFilter), - maHatch(rHatch) + maHatch(rHatch), + maBuffered3DDecomposition() { } @@ -303,6 +304,19 @@ namespace drawinglayer return false; } + Primitive3DSequence HatchTexturePrimitive3D::get3DDecomposition(const geometry::ViewInformation3D& /*rViewInformation*/) const + { + ::osl::MutexGuard aGuard( m_aMutex ); + + if(!getBuffered3DDecomposition().hasElements()) + { + const Primitive3DSequence aNewSequence(impCreate3DDecomposition()); + const_cast< HatchTexturePrimitive3D* >(this)->setBuffered3DDecomposition(aNewSequence); + } + + return getBuffered3DDecomposition(); + } + // provide unique ID ImplPrimitrive3DIDBlock(HatchTexturePrimitive3D, PRIMITIVE3D_ID_HATCHTEXTUREPRIMITIVE3D) diff --git a/drawinglayer/source/primitive3d/hittestprimitive3d.cxx b/drawinglayer/source/primitive3d/hittestprimitive3d.cxx index 50616ab1548b..65aede8142aa 100644 --- a/drawinglayer/source/primitive3d/hittestprimitive3d.cxx +++ b/drawinglayer/source/primitive3d/hittestprimitive3d.cxx @@ -49,12 +49,6 @@ namespace drawinglayer { namespace primitive3d { - Primitive3DSequence HitTestPrimitive3D::createLocalDecomposition(const geometry::ViewInformation3D& /*rViewInformation*/) const - { - // return empty sequence - return Primitive3DSequence(); - } - HitTestPrimitive3D::HitTestPrimitive3D( const Primitive3DSequence& rChildren) : GroupPrimitive3D(rChildren) @@ -66,6 +60,12 @@ namespace drawinglayer return getB3DRangeFromPrimitive3DSequence(getChildren(), rViewInformation); } + Primitive3DSequence HitTestPrimitive3D::get3DDecomposition(const geometry::ViewInformation3D& /*rViewInformation*/) const + { + // return empty sequence + return Primitive3DSequence(); + } + // provide unique ID ImplPrimitrive3DIDBlock(HitTestPrimitive3D, PRIMITIVE3D_ID_HITTESTPRIMITIVE3D) diff --git a/drawinglayer/source/primitive3d/polygonprimitive3d.cxx b/drawinglayer/source/primitive3d/polygonprimitive3d.cxx index b89499091dd0..ee38b8782cff 100644 --- a/drawinglayer/source/primitive3d/polygonprimitive3d.cxx +++ b/drawinglayer/source/primitive3d/polygonprimitive3d.cxx @@ -92,7 +92,7 @@ namespace drawinglayer { namespace primitive3d { - Primitive3DSequence PolygonStrokePrimitive3D::createLocalDecomposition(const geometry::ViewInformation3D& /*rViewInformation*/) const + Primitive3DSequence PolygonStrokePrimitive3D::create3DDecomposition(const geometry::ViewInformation3D& /*rViewInformation*/) const { Primitive3DSequence aRetval; @@ -145,7 +145,7 @@ namespace drawinglayer const basegfx::B3DPolygon& rPolygon, const attribute::LineAttribute& rLineAttribute, const attribute::StrokeAttribute& rStrokeAttribute) - : BasePrimitive3D(), + : BufferedDecompositionPrimitive3D(), maPolygon(rPolygon), maLineAttribute(rLineAttribute), maStrokeAttribute(rStrokeAttribute) @@ -155,7 +155,7 @@ namespace drawinglayer PolygonStrokePrimitive3D::PolygonStrokePrimitive3D( const basegfx::B3DPolygon& rPolygon, const attribute::LineAttribute& rLineAttribute) - : BasePrimitive3D(), + : BufferedDecompositionPrimitive3D(), maPolygon(rPolygon), maLineAttribute(rLineAttribute), maStrokeAttribute() @@ -164,7 +164,7 @@ namespace drawinglayer bool PolygonStrokePrimitive3D::operator==(const BasePrimitive3D& rPrimitive) const { - if(BasePrimitive3D::operator==(rPrimitive)) + if(BufferedDecompositionPrimitive3D::operator==(rPrimitive)) { const PolygonStrokePrimitive3D& rCompare = (PolygonStrokePrimitive3D&)rPrimitive; diff --git a/drawinglayer/source/primitive3d/polygontubeprimitive3d.cxx b/drawinglayer/source/primitive3d/polygontubeprimitive3d.cxx index 09c4acdcaed5..de28e3ad74e5 100644 --- a/drawinglayer/source/primitive3d/polygontubeprimitive3d.cxx +++ b/drawinglayer/source/primitive3d/polygontubeprimitive3d.cxx @@ -417,7 +417,7 @@ namespace drawinglayer { namespace primitive3d { - Primitive3DSequence PolygonTubePrimitive3D::createLocalDecomposition(const geometry::ViewInformation3D& /*rViewInformation*/) const + Primitive3DSequence PolygonTubePrimitive3D::impCreate3DDecomposition(const geometry::ViewInformation3D& /*rViewInformation*/) const { const sal_uInt32 nPointCount(getB3DPolygon().count()); std::vector< BasePrimitive3D* > aResultVector; @@ -541,6 +541,7 @@ namespace drawinglayer double fDegreeStepWidth, double fMiterMinimumAngle) : PolygonHairlinePrimitive3D(rPolygon, rBColor), + maLast3DDecomposition(), mfRadius(fRadius), mfDegreeStepWidth(fDegreeStepWidth), mfMiterMinimumAngle(fMiterMinimumAngle), @@ -563,6 +564,19 @@ namespace drawinglayer return false; } + Primitive3DSequence PolygonTubePrimitive3D::get3DDecomposition(const geometry::ViewInformation3D& rViewInformation) const + { + ::osl::MutexGuard aGuard( m_aMutex ); + + if(!getLast3DDecomposition().hasElements()) + { + const Primitive3DSequence aNewSequence(impCreate3DDecomposition(rViewInformation)); + const_cast< PolygonTubePrimitive3D* >(this)->setLast3DDecomposition(aNewSequence); + } + + return getLast3DDecomposition(); + } + // provide unique ID ImplPrimitrive3DIDBlock(PolygonTubePrimitive3D, PRIMITIVE3D_ID_POLYGONTUBEPRIMITIVE3D) diff --git a/drawinglayer/source/primitive3d/sdrcubeprimitive3d.cxx b/drawinglayer/source/primitive3d/sdrcubeprimitive3d.cxx index 341d2907a53d..739914562071 100644 --- a/drawinglayer/source/primitive3d/sdrcubeprimitive3d.cxx +++ b/drawinglayer/source/primitive3d/sdrcubeprimitive3d.cxx @@ -56,7 +56,7 @@ namespace drawinglayer { namespace primitive3d { - Primitive3DSequence SdrCubePrimitive3D::createLocalDecomposition(const geometry::ViewInformation3D& /*rViewInformation*/) const + Primitive3DSequence SdrCubePrimitive3D::create3DDecomposition(const geometry::ViewInformation3D& /*rViewInformation*/) const { const basegfx::B3DRange aUnitRange(0.0, 0.0, 0.0, 1.0, 1.0, 1.0); Primitive3DSequence aRetval; diff --git a/drawinglayer/source/primitive3d/sdrextrudeprimitive3d.cxx b/drawinglayer/source/primitive3d/sdrextrudeprimitive3d.cxx index e9ef154c95f3..3554e9266ec1 100644 --- a/drawinglayer/source/primitive3d/sdrextrudeprimitive3d.cxx +++ b/drawinglayer/source/primitive3d/sdrextrudeprimitive3d.cxx @@ -57,7 +57,7 @@ namespace drawinglayer { namespace primitive3d { - Primitive3DSequence SdrExtrudePrimitive3D::createLocalDecomposition(const geometry::ViewInformation3D& rViewInformation) const + Primitive3DSequence SdrExtrudePrimitive3D::create3DDecomposition(const geometry::ViewInformation3D& rViewInformation) const { Primitive3DSequence aRetval; @@ -510,14 +510,14 @@ namespace drawinglayer if(getSdr3DObjectAttribute().getReducedLineGeometry()) { if(!mpLastRLGViewInformation || - (getLocalDecomposition().hasElements() + (getBuffered3DDecomposition().hasElements() && *mpLastRLGViewInformation != rViewInformation)) { // conditions of last local decomposition with reduced lines have changed. Remember // new one and clear current decompositiopn ::osl::Mutex m_mutex; SdrExtrudePrimitive3D* pThat = const_cast< SdrExtrudePrimitive3D* >(this); - pThat->setLocalDecomposition(Primitive3DSequence()); + pThat->setBuffered3DDecomposition(Primitive3DSequence()); delete pThat->mpLastRLGViewInformation; pThat->mpLastRLGViewInformation = new geometry::ViewInformation3D(rViewInformation); } diff --git a/drawinglayer/source/primitive3d/sdrlatheprimitive3d.cxx b/drawinglayer/source/primitive3d/sdrlatheprimitive3d.cxx index 33008e762c0a..5e6c34e644de 100644 --- a/drawinglayer/source/primitive3d/sdrlatheprimitive3d.cxx +++ b/drawinglayer/source/primitive3d/sdrlatheprimitive3d.cxx @@ -57,7 +57,7 @@ namespace drawinglayer { namespace primitive3d { - Primitive3DSequence SdrLathePrimitive3D::createLocalDecomposition(const geometry::ViewInformation3D& rViewInformation) const + Primitive3DSequence SdrLathePrimitive3D::create3DDecomposition(const geometry::ViewInformation3D& rViewInformation) const { Primitive3DSequence aRetval; @@ -369,14 +369,14 @@ namespace drawinglayer if(getSdr3DObjectAttribute().getReducedLineGeometry()) { if(!mpLastRLGViewInformation || - (getLocalDecomposition().hasElements() + (getBuffered3DDecomposition().hasElements() && *mpLastRLGViewInformation != rViewInformation)) { // conditions of last local decomposition with reduced lines have changed. Remember // new one and clear current decompositiopn ::osl::Mutex m_mutex; SdrLathePrimitive3D* pThat = const_cast< SdrLathePrimitive3D* >(this); - pThat->setLocalDecomposition(Primitive3DSequence()); + pThat->setBuffered3DDecomposition(Primitive3DSequence()); delete pThat->mpLastRLGViewInformation; pThat->mpLastRLGViewInformation = new geometry::ViewInformation3D(rViewInformation); } diff --git a/drawinglayer/source/primitive3d/sdrpolypolygonprimitive3d.cxx b/drawinglayer/source/primitive3d/sdrpolypolygonprimitive3d.cxx index a0813d3202a8..69049fb7b24d 100644 --- a/drawinglayer/source/primitive3d/sdrpolypolygonprimitive3d.cxx +++ b/drawinglayer/source/primitive3d/sdrpolypolygonprimitive3d.cxx @@ -53,7 +53,7 @@ namespace drawinglayer { namespace primitive3d { - Primitive3DSequence SdrPolyPolygonPrimitive3D::createLocalDecomposition(const geometry::ViewInformation3D& /*rViewInformation*/) const + Primitive3DSequence SdrPolyPolygonPrimitive3D::create3DDecomposition(const geometry::ViewInformation3D& /*rViewInformation*/) const { Primitive3DSequence aRetval; diff --git a/drawinglayer/source/primitive3d/sdrprimitive3d.cxx b/drawinglayer/source/primitive3d/sdrprimitive3d.cxx index dc93d0c0f339..f8489b6418ff 100644 --- a/drawinglayer/source/primitive3d/sdrprimitive3d.cxx +++ b/drawinglayer/source/primitive3d/sdrprimitive3d.cxx @@ -103,7 +103,7 @@ namespace drawinglayer const basegfx::B2DVector& rTextureSize, const attribute::SdrLineFillShadowAttribute& rSdrLFSAttribute, const attribute::Sdr3DObjectAttribute& rSdr3DObjectAttribute) - : BasePrimitive3D(), + : BufferedDecompositionPrimitive3D(), maTransform(rTransform), maTextureSize(rTextureSize), maSdrLFSAttribute(rSdrLFSAttribute), @@ -113,7 +113,7 @@ namespace drawinglayer bool SdrPrimitive3D::operator==(const BasePrimitive3D& rPrimitive) const { - if(BasePrimitive3D::operator==(rPrimitive)) + if(BufferedDecompositionPrimitive3D::operator==(rPrimitive)) { const SdrPrimitive3D& rCompare = static_cast< const SdrPrimitive3D& >(rPrimitive); diff --git a/drawinglayer/source/primitive3d/sdrsphereprimitive3d.cxx b/drawinglayer/source/primitive3d/sdrsphereprimitive3d.cxx index e7149c611dd9..663ae6ad0d37 100644 --- a/drawinglayer/source/primitive3d/sdrsphereprimitive3d.cxx +++ b/drawinglayer/source/primitive3d/sdrsphereprimitive3d.cxx @@ -56,7 +56,7 @@ namespace drawinglayer { namespace primitive3d { - Primitive3DSequence SdrSpherePrimitive3D::createLocalDecomposition(const geometry::ViewInformation3D& /*rViewInformation*/) const + Primitive3DSequence SdrSpherePrimitive3D::create3DDecomposition(const geometry::ViewInformation3D& /*rViewInformation*/) const { Primitive3DSequence aRetval; const basegfx::B3DRange aUnitRange(0.0, 0.0, 0.0, 1.0, 1.0, 1.0); diff --git a/drawinglayer/source/primitive3d/textureprimitive3d.cxx b/drawinglayer/source/primitive3d/textureprimitive3d.cxx index 3393346d0b2d..deeed95a71fd 100644 --- a/drawinglayer/source/primitive3d/textureprimitive3d.cxx +++ b/drawinglayer/source/primitive3d/textureprimitive3d.cxx @@ -81,7 +81,27 @@ namespace drawinglayer { namespace primitive3d { - Primitive3DSequence UnifiedAlphaTexturePrimitive3D::createLocalDecomposition(const geometry::ViewInformation3D& /*rViewInformation*/) const + UnifiedAlphaTexturePrimitive3D::UnifiedAlphaTexturePrimitive3D( + double fTransparence, + const Primitive3DSequence& rChildren) + : TexturePrimitive3D(rChildren, basegfx::B2DVector(), false, false), + mfTransparence(fTransparence) + { + } + + bool UnifiedAlphaTexturePrimitive3D::operator==(const BasePrimitive3D& rPrimitive) const + { + if(TexturePrimitive3D::operator==(rPrimitive)) + { + const UnifiedAlphaTexturePrimitive3D& rCompare = (UnifiedAlphaTexturePrimitive3D&)rPrimitive; + + return (getTransparence() == rCompare.getTransparence()); + } + + return false; + } + + Primitive3DSequence UnifiedAlphaTexturePrimitive3D::get3DDecomposition(const geometry::ViewInformation3D& /*rViewInformation*/) const { if(0.0 == getTransparence()) { @@ -103,26 +123,6 @@ namespace drawinglayer } } - UnifiedAlphaTexturePrimitive3D::UnifiedAlphaTexturePrimitive3D( - double fTransparence, - const Primitive3DSequence& rChildren) - : TexturePrimitive3D(rChildren, basegfx::B2DVector(), false, false), - mfTransparence(fTransparence) - { - } - - bool UnifiedAlphaTexturePrimitive3D::operator==(const BasePrimitive3D& rPrimitive) const - { - if(TexturePrimitive3D::operator==(rPrimitive)) - { - const UnifiedAlphaTexturePrimitive3D& rCompare = (UnifiedAlphaTexturePrimitive3D&)rPrimitive; - - return (getTransparence() == rCompare.getTransparence()); - } - - return false; - } - // provide unique ID ImplPrimitrive3DIDBlock(UnifiedAlphaTexturePrimitive3D, PRIMITIVE3D_ID_UNIFIEDALPHATEXTUREPRIMITIVE3D) @@ -135,11 +135,6 @@ namespace drawinglayer { namespace primitive3d { - Primitive3DSequence GradientTexturePrimitive3D::createLocalDecomposition(const geometry::ViewInformation3D& /*rViewInformation*/) const - { - return getChildren(); - } - GradientTexturePrimitive3D::GradientTexturePrimitive3D( const attribute::FillGradientAttribute& rGradient, const Primitive3DSequence& rChildren, @@ -175,18 +170,13 @@ namespace drawinglayer { namespace primitive3d { - Primitive3DSequence BitmapTexturePrimitive3D::createLocalDecomposition(const geometry::ViewInformation3D& /*rViewInformation*/) const - { - return getChildren(); - } - BitmapTexturePrimitive3D::BitmapTexturePrimitive3D( - const attribute::FillBitmapAttribute& rBitmap, + const attribute::FillBitmapAttribute& rFillBitmapAttribute, const Primitive3DSequence& rChildren, const basegfx::B2DVector& rTextureSize, bool bModulate, bool bFilter) : TexturePrimitive3D(rChildren, rTextureSize, bModulate, bFilter), - maBitmap(rBitmap) + maFillBitmapAttribute(rFillBitmapAttribute) { } @@ -196,7 +186,7 @@ namespace drawinglayer { const BitmapTexturePrimitive3D& rCompare = (BitmapTexturePrimitive3D&)rPrimitive; - return (getBitmap() == rCompare.getBitmap()); + return (getFillBitmapAttribute() == rCompare.getFillBitmapAttribute()); } return false; diff --git a/drawinglayer/source/processor2d/canvasprocessor.cxx b/drawinglayer/source/processor2d/canvasprocessor.cxx index 43e40183bc6e..8eb713258b25 100644 --- a/drawinglayer/source/processor2d/canvasprocessor.cxx +++ b/drawinglayer/source/processor2d/canvasprocessor.cxx @@ -76,6 +76,7 @@ #include <helperchartrenderer.hxx> #include <drawinglayer/primitive2d/wrongspellprimitive2d.hxx> #include <helperwrongspellrenderer.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> ////////////////////////////////////////////////////////////////////////////// @@ -675,7 +676,7 @@ using namespace com::sun::star; // directdraw of text simple portion void canvasProcessor::impRender_STXP(const textSimplePortionPrimitive& rTextCandidate) { - const fontAttributes& rFontAttrs( rTextCandidate.getFontAttributes() ); + const fontAttributes& rFontAttrs( rTextCandidate.getFontAttribute() ); rendering::FontRequest aFontRequest; aFontRequest.FontDescription.FamilyName = rFontAttrs.maFamilyName; @@ -1341,10 +1342,9 @@ namespace drawinglayer // prepare discrete offset for XBitmap, do not forget that the buffer bitmap // may be truncated to discrete visible pixels - basegfx::B2DHomMatrix aDiscreteOffset; - aDiscreteOffset.translate( + const basegfx::B2DHomMatrix aDiscreteOffset(basegfx::tools::createTranslateB2DHomMatrix( aDiscreteRange.getMinX() > 0.0 ? -aDiscreteRange.getMinX() : 0.0, - aDiscreteRange.getMinY() > 0.0 ? -aDiscreteRange.getMinY() : 0.0); + aDiscreteRange.getMinY() > 0.0 ? -aDiscreteRange.getMinY() : 0.0)); // create new local ViewInformation2D with new transformation const geometry::ViewInformation2D aViewInformation2D( @@ -1517,16 +1517,16 @@ namespace drawinglayer } else { - const primitive2d::FontAttributes& rFontAttrs(rTextCandidate.getFontAttributes()); + const attribute::FontAttribute& rFontAttr(rTextCandidate.getFontAttribute()); rendering::FontRequest aFontRequest; - aFontRequest.FontDescription.FamilyName = rFontAttrs.getFamilyName(); - aFontRequest.FontDescription.StyleName = rFontAttrs.getStyleName(); - aFontRequest.FontDescription.IsSymbolFont = rFontAttrs.getSymbol() ? util::TriState_YES : util::TriState_NO; - aFontRequest.FontDescription.IsVertical = rFontAttrs.getVertical() ? util::TriState_YES : util::TriState_NO; + 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 >(rFontAttrs.getWeight()); - aFontRequest.FontDescription.FontDescription.Letterform = rFontAttrs.getItalic() ? 9 : 0; + aFontRequest.FontDescription.FontDescription.Weight = static_cast< sal_uInt8 >(rFontAttr.getWeight()); + 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; @@ -1600,16 +1600,14 @@ namespace drawinglayer // adapt object's transformation to the correct scale basegfx::B2DVector aScale, aTranslate; double fRotate, fShearX; - basegfx::B2DHomMatrix aNewMatrix; const Size aSizePixel(aModifiedBitmapEx.GetSizePixel()); if(0 != aSizePixel.Width() && 0 != aSizePixel.Height()) { rBitmapCandidate.getTransform().decompose(aScale, aTranslate, fRotate, fShearX); - aNewMatrix.scale(aScale.getX() / aSizePixel.Width(), aScale.getY() / aSizePixel.Height()); - aNewMatrix.shearX(fShearX); - aNewMatrix.rotate(fRotate); - aNewMatrix.translate(aTranslate.getX(), aTranslate.getY()); + 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); @@ -1658,10 +1656,9 @@ namespace drawinglayer // prepare discrete offset for XBitmap, do not forget that the buffer bitmap // may be truncated to discrete visible pixels - basegfx::B2DHomMatrix aDiscreteOffset; - aDiscreteOffset.translate( + const basegfx::B2DHomMatrix aDiscreteOffset(basegfx::tools::createTranslateB2DHomMatrix( aDiscreteRange.getMinX() > 0.0 ? -aDiscreteRange.getMinX() : 0.0, - aDiscreteRange.getMinY() > 0.0 ? -aDiscreteRange.getMinY() : 0.0); + aDiscreteRange.getMinY() > 0.0 ? -aDiscreteRange.getMinY() : 0.0)); // create new local ViewInformation2D with new transformation const geometry::ViewInformation2D aViewInformation2D( @@ -1798,7 +1795,7 @@ namespace drawinglayer if(rFillBitmapAttribute.getTiling()) { // apply possible color modification to Bitmap - const BitmapEx aChangedBitmapEx(impModifyBitmapEx(maBColorModifierStack, BitmapEx(rFillBitmapAttribute.getBitmap()))); + const BitmapEx aChangedBitmapEx(impModifyBitmapEx(maBColorModifierStack, rFillBitmapAttribute.getBitmapEx())); if(aChangedBitmapEx.IsEmpty()) { @@ -1821,13 +1818,9 @@ namespace drawinglayer { // create texture matrix from texture to object (where object is unit square here), // so use values directly - basegfx::B2DHomMatrix aTextureMatrix; - aTextureMatrix.scale( - rFillBitmapAttribute.getSize().getX(), - rFillBitmapAttribute.getSize().getY()); - aTextureMatrix.translate( - rFillBitmapAttribute.getTopLeft().getX(), - rFillBitmapAttribute.getTopLeft().getY()); + 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; @@ -1883,7 +1876,7 @@ namespace drawinglayer const primitive2d::Primitive2DReference xReference(rChildren[0]); const primitive2d::PolyPolygonColorPrimitive2D* pPoPoColor = dynamic_cast< const primitive2d::PolyPolygonColorPrimitive2D* >(xReference.get()); - if(pPoPoColor && PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D == pPoPoColor->getPrimitiveID()) + if(pPoPoColor && PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D == pPoPoColor->getPrimitive2DID()) { // direct draw of PolyPolygon with color and transparence const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(pPoPoColor->getBColor())); @@ -1922,7 +1915,7 @@ namespace drawinglayer void canvasProcessor2D::processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate) { - switch(rCandidate.getPrimitiveID()) + switch(rCandidate.getPrimitive2DID()) { case PRIMITIVE2D_ID_POLYGONHAIRLINEPRIMITIVE2D : { diff --git a/drawinglayer/source/processor2d/contourextractor2d.cxx b/drawinglayer/source/processor2d/contourextractor2d.cxx index 1f629cb25c9c..3225651a6754 100644 --- a/drawinglayer/source/processor2d/contourextractor2d.cxx +++ b/drawinglayer/source/processor2d/contourextractor2d.cxx @@ -70,7 +70,7 @@ namespace drawinglayer void ContourExtractor2D::processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate) { - switch(rCandidate.getPrimitiveID()) + switch(rCandidate.getPrimitive2DID()) { case PRIMITIVE2D_ID_POLYGONHAIRLINEPRIMITIVE2D : { diff --git a/drawinglayer/source/processor2d/hittestprocessor2d.cxx b/drawinglayer/source/processor2d/hittestprocessor2d.cxx index 4ffef7515389..b10e10706520 100644 --- a/drawinglayer/source/processor2d/hittestprocessor2d.cxx +++ b/drawinglayer/source/processor2d/hittestprocessor2d.cxx @@ -289,7 +289,7 @@ namespace drawinglayer return; } - switch(rCandidate.getPrimitiveID()) + switch(rCandidate.getPrimitive2DID()) { case PRIMITIVE2D_ID_TRANSFORMPRIMITIVE2D : { @@ -451,8 +451,9 @@ namespace drawinglayer { if(!getHitTextOnly()) { - const primitive2d::ScenePrimitive2D& rSceneCandidate(static_cast< const primitive2d::ScenePrimitive2D& >(rCandidate)); - check3DHit(rSceneCandidate); + const primitive2d::ScenePrimitive2D& rScenePrimitive2D( + static_cast< const primitive2d::ScenePrimitive2D& >(rCandidate)); + check3DHit(rScenePrimitive2D); } break; diff --git a/drawinglayer/source/processor2d/linegeometryextractor2d.cxx b/drawinglayer/source/processor2d/linegeometryextractor2d.cxx index 5f0ab63ee1b3..cc474b7c0736 100644 --- a/drawinglayer/source/processor2d/linegeometryextractor2d.cxx +++ b/drawinglayer/source/processor2d/linegeometryextractor2d.cxx @@ -66,7 +66,7 @@ namespace drawinglayer void LineGeometryExtractor2D::processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate) { - switch(rCandidate.getPrimitiveID()) + switch(rCandidate.getPrimitive2DID()) { case PRIMITIVE2D_ID_POLYGONSTROKEPRIMITIVE2D : case PRIMITIVE2D_ID_POLYGONSTROKEARROWPRIMITIVE2D : diff --git a/drawinglayer/source/processor2d/textaspolygonextractor2d.cxx b/drawinglayer/source/processor2d/textaspolygonextractor2d.cxx index 9358c7f39c57..ce53d1e86399 100644 --- a/drawinglayer/source/processor2d/textaspolygonextractor2d.cxx +++ b/drawinglayer/source/processor2d/textaspolygonextractor2d.cxx @@ -51,7 +51,7 @@ namespace drawinglayer { void TextAsPolygonExtractor2D::processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate) { - switch(rCandidate.getPrimitiveID()) + switch(rCandidate.getPrimitive2DID()) { case PRIMITIVE2D_ID_TEXTDECORATEDPORTIONPRIMITIVE2D : { diff --git a/drawinglayer/source/processor2d/vclhelperbitmaprender.cxx b/drawinglayer/source/processor2d/vclhelperbitmaprender.cxx index d517b603eea3..c1e7702e6933 100644 --- a/drawinglayer/source/processor2d/vclhelperbitmaprender.cxx +++ b/drawinglayer/source/processor2d/vclhelperbitmaprender.cxx @@ -43,6 +43,7 @@ #include <basegfx/range/b2drange.hxx> #include <vcl/outdev.hxx> #include <vclhelperbitmaptransform.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> ////////////////////////////////////////////////////////////////////////////// // support for different kinds of bitmap rendering using vcl @@ -84,10 +85,9 @@ namespace drawinglayer else { // if rotated, create the unrotated output rectangle for the GraphicManager paint - basegfx::B2DHomMatrix aSimpleObjectMatrix; - - aSimpleObjectMatrix.scale(fabs(aScale.getX()), fabs(aScale.getY())); - aSimpleObjectMatrix.translate(aTranslate.getX(), aTranslate.getY()); + const basegfx::B2DHomMatrix aSimpleObjectMatrix(basegfx::tools::createScaleTranslateB2DHomMatrix( + fabs(aScale.getX()), fabs(aScale.getY()), + aTranslate.getX(), aTranslate.getY())); aOutlineRange.transform(aSimpleObjectMatrix); } @@ -190,11 +190,11 @@ namespace drawinglayer } // build transform from pixel in aDestination to pixel in rBitmapEx - basegfx::B2DHomMatrix aTransform; - // from relative in aCroppedRectPixel to relative in aDestRectPixel // No need to take bNeedToReduce into account, TopLeft is unchanged - aTransform.translate(aCroppedRectPixel.Left() - aDestRectPixel.Left(), aCroppedRectPixel.Top() - aDestRectPixel.Top()); + basegfx::B2DHomMatrix aTransform(basegfx::tools::createTranslateB2DHomMatrix( + aCroppedRectPixel.Left() - aDestRectPixel.Left(), + aCroppedRectPixel.Top() - aDestRectPixel.Top())); // from relative in aDestRectPixel to absolute Logic. Here it // is essential to adapt to reduce factor (if used) @@ -207,8 +207,10 @@ namespace drawinglayer fAdaptedDRPHeight *= fReduceFactor; } - aTransform.scale(aDestRectLogic.getWidth() / fAdaptedDRPWidth, aDestRectLogic.getHeight() / fAdaptedDRPHeight); - aTransform.translate(aDestRectLogic.Left(), aDestRectLogic.Top()); + aTransform = basegfx::tools::createScaleTranslateB2DHomMatrix( + aDestRectLogic.getWidth() / fAdaptedDRPWidth, aDestRectLogic.getHeight() / fAdaptedDRPHeight, + aDestRectLogic.Left(), aDestRectLogic.Top()) + * aTransform; // from absolute in Logic to unified object coordinates (0.0 .. 1.0 in x and y) basegfx::B2DHomMatrix aInvBitmapTransform(rTransform); diff --git a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx index 8293fc048f5b..6e53677bbe09 100644 --- a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx +++ b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx @@ -74,6 +74,7 @@ #include <drawinglayer/primitive2d/pagepreviewprimitive2d.hxx> #include <helperchartrenderer.hxx> #include <drawinglayer/primitive2d/hittestprimitive2d.hxx> +#include <drawinglayer/primitive2d/epsprimitive2d.hxx> ////////////////////////////////////////////////////////////////////////////// // for PDFExtOutDevData Graphic support @@ -592,7 +593,7 @@ namespace drawinglayer void VclMetafileProcessor2D::processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate) { - switch(rCandidate.getPrimitiveID()) + switch(rCandidate.getPrimitive2DID()) { case PRIMITIVE2D_ID_WRONGSPELLPRIMITIVE2D : { @@ -1008,26 +1009,12 @@ namespace drawinglayer SvtGraphicStroke* pSvtGraphicStroke = impTryToCreateSvtGraphicStroke(rStrokePrimitive.getB2DPolygon(), 0, &rStrokePrimitive.getLineAttribute(), &rStrokePrimitive.getStrokeAttribute(), 0, 0); - // Adapt OutDev's DrawMode if special ones were used - const sal_uInt32 nOriginalDrawMode(mpOutputDevice->GetDrawMode()); - adaptLineToFillDrawMode(); - - impStartSvtGraphicStroke(pSvtGraphicStroke); - - // #i101491# - // Change default of fat line generation for MetaFiles: Create MetaPolyLineAction - // instead of decomposing all geometries when the polygon has more than given amount of - // points; else the decomposition will get too expensive quiclky. OTOH - // the decomposition provides the better quality e.g. taking edge roundings - // into account which will NOT be taken into account with LineInfo-based actions - const sal_uInt32 nSubPolygonCount(rStrokePrimitive.getB2DPolygon().count()); - bool bDone(0 == nSubPolygonCount); - - if(!bDone && nSubPolygonCount > 1000) + if(true) { - // create MetaPolyLineActions, but without LINE_DASH + impStartSvtGraphicStroke(pSvtGraphicStroke); const attribute::LineAttribute& rLine = rStrokePrimitive.getLineAttribute(); + // create MetaPolyLineActions, but without LINE_DASH if(basegfx::fTools::more(rLine.getWidth(), 0.0)) { const attribute::StrokeAttribute& rStroke = rStrokePrimitive.getStrokeAttribute(); @@ -1047,10 +1034,9 @@ namespace drawinglayer const basegfx::BColor aHairlineColor(maBColorModifierStack.getModifiedColor(rLine.getColor())); mpOutputDevice->SetLineColor(Color(aHairlineColor)); mpOutputDevice->SetFillColor(); - aHairLinePolyPolygon.transform(maCurrentTransformation); - - const LineInfo aLineInfo(LINE_SOLID, basegfx::fround(rLine.getWidth())); + LineInfo aLineInfo(LINE_SOLID, basegfx::fround(rLine.getWidth())); + aLineInfo.SetLineJoin(rLine.getLineJoin()); for(sal_uInt32 a(0); a < aHairLinePolyPolygon.count(); a++) { @@ -1063,22 +1049,88 @@ namespace drawinglayer mpMetaFile->AddAction(new MetaPolyLineAction(aToolsPolygon, aLineInfo)); } } - - bDone = true; } - } + else + { + process(rCandidate.get2DDecomposition(getViewInformation2D())); + } - if(!bDone) - { - // use decomposition (creates line geometry as filled polygon - // geometry) - process(rCandidate.get2DDecomposition(getViewInformation2D())); + impEndSvtGraphicStroke(pSvtGraphicStroke); } + else + { + // Adapt OutDev's DrawMode if special ones were used + const sal_uInt32 nOriginalDrawMode(mpOutputDevice->GetDrawMode()); + adaptLineToFillDrawMode(); + + impStartSvtGraphicStroke(pSvtGraphicStroke); + + // #i101491# + // Change default of fat line generation for MetaFiles: Create MetaPolyLineAction + // instead of decomposing all geometries when the polygon has more than given amount of + // points; else the decomposition will get too expensive quiclky. OTOH + // the decomposition provides the better quality e.g. taking edge roundings + // into account which will NOT be taken into account with LineInfo-based actions + const sal_uInt32 nSubPolygonCount(rStrokePrimitive.getB2DPolygon().count()); + bool bDone(0 == nSubPolygonCount); + + if(!bDone && nSubPolygonCount > 1000) + { + // create MetaPolyLineActions, but without LINE_DASH + const attribute::LineAttribute& rLine = rStrokePrimitive.getLineAttribute(); - impEndSvtGraphicStroke(pSvtGraphicStroke); + if(basegfx::fTools::more(rLine.getWidth(), 0.0)) + { + const attribute::StrokeAttribute& rStroke = rStrokePrimitive.getStrokeAttribute(); + basegfx::B2DPolyPolygon aHairLinePolyPolygon; - // restore DrawMode - mpOutputDevice->SetDrawMode(nOriginalDrawMode); + if(0.0 == rStroke.getFullDotDashLen()) + { + aHairLinePolyPolygon.append(rStrokePrimitive.getB2DPolygon()); + } + else + { + basegfx::tools::applyLineDashing( + rStrokePrimitive.getB2DPolygon(), rStroke.getDotDashArray(), + &aHairLinePolyPolygon, 0, rStroke.getFullDotDashLen()); + } + + const basegfx::BColor aHairlineColor(maBColorModifierStack.getModifiedColor(rLine.getColor())); + mpOutputDevice->SetLineColor(Color(aHairlineColor)); + mpOutputDevice->SetFillColor(); + + aHairLinePolyPolygon.transform(maCurrentTransformation); + + const LineInfo aLineInfo(LINE_SOLID, basegfx::fround(rLine.getWidth())); + + for(sal_uInt32 a(0); a < aHairLinePolyPolygon.count(); a++) + { + const basegfx::B2DPolygon aCandidate(aHairLinePolyPolygon.getB2DPolygon(a)); + + if(aCandidate.count() > 1) + { + const Polygon aToolsPolygon(aCandidate); + + mpMetaFile->AddAction(new MetaPolyLineAction(aToolsPolygon, aLineInfo)); + } + } + + bDone = true; + } + } + + if(!bDone) + { + // use decomposition (creates line geometry as filled polygon + // geometry) + process(rCandidate.get2DDecomposition(getViewInformation2D())); + } + + impEndSvtGraphicStroke(pSvtGraphicStroke); + + // restore DrawMode + mpOutputDevice->SetDrawMode(nOriginalDrawMode); + } break; } @@ -1124,8 +1176,8 @@ namespace drawinglayer const basegfx::B2DPoint aFillBitmapTopLeft(rFillBitmapAttribute.getTopLeft() * aOutlineSize); // the scaling needs scale from pixel to logic coordinate system - const Bitmap& rBitmap = rFillBitmapAttribute.getBitmap(); - Size aBmpSizePixel(rBitmap.GetSizePixel()); + const BitmapEx& rBitmapEx = rFillBitmapAttribute.getBitmapEx(); + Size aBmpSizePixel(rBitmapEx.GetSizePixel()); if(!aBmpSizePixel.Width()) { @@ -1149,7 +1201,7 @@ namespace drawinglayer aTransform.matrix[5] = aFillBitmapTopLeft.getY(); // setup fill graphic like in impgrfll - Graphic aFillGraphic = Graphic(rBitmap); + Graphic aFillGraphic = Graphic(rBitmapEx); aFillGraphic.SetPrefMapMode(MapMode(MAP_PIXEL)); aFillGraphic.SetPrefSize(aBmpSizePixel); @@ -1456,7 +1508,7 @@ namespace drawinglayer // PolyPolygonGradientPrimitive2D, PolyPolygonHatchPrimitive2D and // PolyPolygonBitmapPrimitive2D are derived from PolyPolygonColorPrimitive2D. // Check also for correct ID to exclude derived implementations - if(pPoPoColor && PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D == pPoPoColor->getPrimitiveID()) + if(pPoPoColor && PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D == pPoPoColor->getPrimitive2DID()) { // single transparent PolyPolygon identified, use directly const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(pPoPoColor->getBColor())); @@ -1567,7 +1619,7 @@ namespace drawinglayer } // Check also for correct ID to exclude derived implementations - if(pFiGradient && PRIMITIVE2D_ID_FILLGRADIENTPRIMITIVE2D == pFiGradient->getPrimitiveID()) + if(pFiGradient && PRIMITIVE2D_ID_FILLGRADIENTPRIMITIVE2D == pFiGradient->getPrimitive2DID()) { // various content, create content-metafile GDIMetaFile aContentMetafile; @@ -1754,6 +1806,11 @@ namespace drawinglayer break; } + case PRIMITIVE2D_ID_EPSPRIMITIVE2D : + { + RenderEpsPrimitive2D(static_cast< const primitive2d::EpsPrimitive2D& >(rCandidate)); + break; + } default : { // process recursively diff --git a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx index ef351002a1ea..5a74b0471b7f 100644 --- a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx +++ b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx @@ -67,6 +67,8 @@ #include <drawinglayer/primitive2d/invertprimitive2d.hxx> #include <cstdio> #include <drawinglayer/primitive2d/backgroundcolorprimitive2d.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> +#include <drawinglayer/primitive2d/epsprimitive2d.hxx> ////////////////////////////////////////////////////////////////////////////// @@ -111,7 +113,7 @@ namespace drawinglayer void VclPixelProcessor2D::processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate) { - switch(rCandidate.getPrimitiveID()) + switch(rCandidate.getPrimitive2DID()) { case PRIMITIVE2D_ID_WRONGSPELLPRIMITIVE2D : { @@ -204,18 +206,8 @@ namespace drawinglayer } case PRIMITIVE2D_ID_POLYPOLYGONGRADIENTPRIMITIVE2D : { - if(getOptionsDrawinglayer().IsAntiAliasing()) - { - // For AA, direct render has to be avoided since it uses XOR maskings which will not - // work with AA. Instead, the decompose which uses MaskPrimitive2D with fillings is - // used - process(rCandidate.get2DDecomposition(getViewInformation2D())); - } - else - { - // direct draw of gradient - RenderPolyPolygonGradientPrimitive2D(static_cast< const primitive2d::PolyPolygonGradientPrimitive2D& >(rCandidate)); - } + // direct draw of gradient + RenderPolyPolygonGradientPrimitive2D(static_cast< const primitive2d::PolyPolygonGradientPrimitive2D& >(rCandidate)); break; } case PRIMITIVE2D_ID_POLYPOLYGONBITMAPPRIMITIVE2D : @@ -241,8 +233,17 @@ namespace drawinglayer mpOutputDevice->SetAntialiasing(nOldAntiAliase | ANTIALIASING_PIXELSNAPHAIRLINE); } - // direct draw of MetaFile - RenderMetafilePrimitive2D(static_cast< const primitive2d::MetafilePrimitive2D& >(rCandidate)); + static bool bTestMetaFilePrimitiveDecomposition(true); + if(bTestMetaFilePrimitiveDecomposition) + { + // use new Metafile decomposition + process(rCandidate.get2DDecomposition(getViewInformation2D())); + } + else + { + // direct draw of MetaFile + RenderMetafilePrimitive2D(static_cast< const primitive2d::MetafilePrimitive2D& >(rCandidate)); + } if(bForceLineSnap) { @@ -280,7 +281,7 @@ namespace drawinglayer const primitive2d::Primitive2DReference xReference(rContent[0]); const primitive2d::PolyPolygonColorPrimitive2D* pPoPoColor = dynamic_cast< const primitive2d::PolyPolygonColorPrimitive2D* >(xReference.get()); - if(pPoPoColor && PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D == pPoPoColor->getPrimitiveID()) + if(pPoPoColor && PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D == pPoPoColor->getPrimitive2DID()) { // single transparent PolyPolygon identified, use directly const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(pPoPoColor->getBColor())); @@ -528,7 +529,6 @@ namespace drawinglayer // restore AA setting mpOutputDevice->SetAntialiasing(nOriginalAA); - break; } case PRIMITIVE2D_ID_TEXTHIERARCHYEDITPRIMITIVE2D : @@ -545,23 +545,23 @@ namespace drawinglayer case PRIMITIVE2D_ID_INVERTPRIMITIVE2D : { // invert primitive (currently only used for HighContrast fallback for selection in SW and SC). - // Set OutDev to XOR + // Set OutDev to XOR and switch AA off (XOR does not work with AA) mpOutputDevice->Push(); mpOutputDevice->SetRasterOp( ROP_XOR ); - - // force paint color to white by using ColorModifierStack - const basegfx::BColor aColWhite(1.0, 1.0, 1.0); - const basegfx::BColorModifier aColorModifier(aColWhite, 0.0, basegfx::BCOLORMODIFYMODE_REPLACE); - maBColorModifierStack.push(aColorModifier); + const sal_uInt16 nAntiAliasing(mpOutputDevice->GetAntialiasing()); + mpOutputDevice->SetAntialiasing(nAntiAliasing & ~ANTIALIASING_ENABLE_B2DDRAW); // process content recursively process(rCandidate.get2DDecomposition(getViewInformation2D())); - // restore ColorModifierStack - maBColorModifierStack.pop(); - // restore OutDev mpOutputDevice->Pop(); + mpOutputDevice->SetAntialiasing(nAntiAliasing); + break; + } + case PRIMITIVE2D_ID_EPSPRIMITIVE2D : + { + RenderEpsPrimitive2D(static_cast< const primitive2d::EpsPrimitive2D& >(rCandidate)); break; } default : diff --git a/drawinglayer/source/processor2d/vclprocessor2d.cxx b/drawinglayer/source/processor2d/vclprocessor2d.cxx index 3412b5db5598..bd9439ef9339 100644 --- a/drawinglayer/source/processor2d/vclprocessor2d.cxx +++ b/drawinglayer/source/processor2d/vclprocessor2d.cxx @@ -63,6 +63,8 @@ #include <drawinglayer/primitive2d/pagepreviewprimitive2d.hxx> #include <tools/diagnose_ex.h> #include <vcl/metric.hxx> +#include <drawinglayer/primitive2d/textenumsprimitive2d.hxx> +#include <drawinglayer/primitive2d/epsprimitive2d.hxx> ////////////////////////////////////////////////////////////////////////////// // control support @@ -99,34 +101,6 @@ namespace drawinglayer using ::com::sun::star::awt::XWindow; using ::com::sun::star::awt::PosSize::POSSIZE; - static FontUnderline mapTextLineStyle(primitive2d::FontUnderline eLineStyle) - { - switch(eLineStyle) - { - default: - DBG_WARNING1( "DrawingLayer: Unknown text line style attribute (%d)!", eLineStyle ); - // fall through - case primitive2d::FONT_UNDERLINE_NONE: return UNDERLINE_NONE; - case primitive2d::FONT_UNDERLINE_SINGLE: return UNDERLINE_SINGLE; - case primitive2d::FONT_UNDERLINE_DOUBLE: return UNDERLINE_DOUBLE; - case primitive2d::FONT_UNDERLINE_DOTTED: return UNDERLINE_DOTTED; - case primitive2d::FONT_UNDERLINE_DASH: return UNDERLINE_DASH; - case primitive2d::FONT_UNDERLINE_LONGDASH: return UNDERLINE_LONGDASH; - case primitive2d::FONT_UNDERLINE_DASHDOT: return UNDERLINE_DASHDOT; - case primitive2d::FONT_UNDERLINE_DASHDOTDOT: return UNDERLINE_DASHDOTDOT; - case primitive2d::FONT_UNDERLINE_SMALLWAVE: return UNDERLINE_SMALLWAVE; - case primitive2d::FONT_UNDERLINE_WAVE: return UNDERLINE_WAVE; - case primitive2d::FONT_UNDERLINE_DOUBLEWAVE: return UNDERLINE_DOUBLEWAVE; - case primitive2d::FONT_UNDERLINE_BOLD: return UNDERLINE_BOLD; - case primitive2d::FONT_UNDERLINE_BOLDDOTTED: return UNDERLINE_BOLDDOTTED; - case primitive2d::FONT_UNDERLINE_BOLDDASH: return UNDERLINE_BOLDDASH; - case primitive2d::FONT_UNDERLINE_BOLDLONGDASH: return UNDERLINE_LONGDASH; - case primitive2d::FONT_UNDERLINE_BOLDDASHDOT: return UNDERLINE_BOLDDASHDOT; - case primitive2d::FONT_UNDERLINE_BOLDDASHDOTDOT:return UNDERLINE_BOLDDASHDOT; - case primitive2d::FONT_UNDERLINE_BOLDWAVE: return UNDERLINE_BOLDWAVE; - } - } - ////////////////////////////////////////////////////////////////////////////// // rendering support @@ -157,8 +131,8 @@ namespace drawinglayer if(basegfx::fTools::more(aFontScaling.getX(), 0.0) && basegfx::fTools::more(aFontScaling.getY(), 0.0)) { // Get the VCL font (use FontHeight as FontWidth) - Font aFont(primitive2d::getVclFontFromFontAttributes( - rTextCandidate.getFontAttributes(), + Font aFont(primitive2d::getVclFontFromFontAttribute( + rTextCandidate.getFontAttribute(), aFontScaling.getX(), aFontScaling.getY(), fRotate, @@ -176,7 +150,7 @@ namespace drawinglayer mpOutputDevice->SetTextLineColor( Color(aTextlineColor) ); // set Overline attribute - FontUnderline eFontOverline = mapTextLineStyle( pTCPP->getFontOverline() ); + const FontUnderline eFontOverline(primitive2d::mapTextLineToFontUnderline( pTCPP->getFontOverline() )); if( eFontOverline != UNDERLINE_NONE ) { aFont.SetOverline( eFontOverline ); @@ -187,7 +161,7 @@ namespace drawinglayer } // set Underline attribute - FontUnderline eFontUnderline = mapTextLineStyle( pTCPP->getFontUnderline() ); + const FontUnderline eFontUnderline(primitive2d::mapTextLineToFontUnderline( pTCPP->getFontUnderline() )); if( eFontUnderline != UNDERLINE_NONE ) { aFont.SetUnderline( eFontUnderline ); @@ -198,35 +172,23 @@ namespace drawinglayer } // set Strikeout attribute - FontStrikeout eFontStrikeout = STRIKEOUT_NONE; - switch( pTCPP->getFontStrikeout() ) - { - default: - DBG_WARNING1( "DrawingLayer: Unknown strikeout attribute (%d)!", pTCPP->getFontStrikeout() ); - // fall through - case primitive2d::FONT_STRIKEOUT_NONE: eFontStrikeout = STRIKEOUT_NONE; break; - case primitive2d::FONT_STRIKEOUT_SINGLE: eFontStrikeout = STRIKEOUT_SINGLE; break; - case primitive2d::FONT_STRIKEOUT_DOUBLE: eFontStrikeout = STRIKEOUT_DOUBLE; break; - case primitive2d::FONT_STRIKEOUT_BOLD: eFontStrikeout = STRIKEOUT_BOLD; break; - case primitive2d::FONT_STRIKEOUT_SLASH: eFontStrikeout = STRIKEOUT_SLASH; break; - case primitive2d::FONT_STRIKEOUT_X: eFontStrikeout = STRIKEOUT_X; break; - } + const FontStrikeout eFontStrikeout(primitive2d::mapTextStrikeoutToFontStrikeout(pTCPP->getTextStrikeout())); if( eFontStrikeout != STRIKEOUT_NONE ) aFont.SetStrikeout( eFontStrikeout ); // set EmphasisMark attribute FontEmphasisMark eFontEmphasisMark = EMPHASISMARK_NONE; - switch( pTCPP->getFontEmphasisMark() ) + switch( pTCPP->getTextEmphasisMark() ) { default: - DBG_WARNING1( "DrawingLayer: Unknown EmphasisMark style (%d)!", pTCPP->getFontEmphasisMark() ); + DBG_WARNING1( "DrawingLayer: Unknown EmphasisMark style (%d)!", pTCPP->getTextEmphasisMark() ); // fall through - case primitive2d::FONT_EMPHASISMARK_NONE: eFontEmphasisMark = EMPHASISMARK_NONE; break; - case primitive2d::FONT_EMPHASISMARK_DOT: eFontEmphasisMark = EMPHASISMARK_DOT; break; - case primitive2d::FONT_EMPHASISMARK_CIRCLE: eFontEmphasisMark = EMPHASISMARK_CIRCLE; break; - case primitive2d::FONT_EMPHASISMARK_DISC: eFontEmphasisMark = EMPHASISMARK_DISC; break; - case primitive2d::FONT_EMPHASISMARK_ACCENT: eFontEmphasisMark = EMPHASISMARK_ACCENT; break; + case primitive2d::TEXT_EMPHASISMARK_NONE: eFontEmphasisMark = EMPHASISMARK_NONE; break; + case primitive2d::TEXT_EMPHASISMARK_DOT: eFontEmphasisMark = EMPHASISMARK_DOT; break; + case primitive2d::TEXT_EMPHASISMARK_CIRCLE: eFontEmphasisMark = EMPHASISMARK_CIRCLE; break; + case primitive2d::TEXT_EMPHASISMARK_DISC: eFontEmphasisMark = EMPHASISMARK_DISC; break; + case primitive2d::TEXT_EMPHASISMARK_ACCENT: eFontEmphasisMark = EMPHASISMARK_ACCENT; break; } if( eFontEmphasisMark != EMPHASISMARK_NONE ) @@ -242,14 +204,14 @@ namespace drawinglayer // set Relief attribute FontRelief eFontRelief = RELIEF_NONE; - switch( pTCPP->getFontRelief() ) + switch( pTCPP->getTextRelief() ) { default: - DBG_WARNING1( "DrawingLayer: Unknown Relief style (%d)!", pTCPP->getFontRelief() ); + DBG_WARNING1( "DrawingLayer: Unknown Relief style (%d)!", pTCPP->getTextRelief() ); // fall through - case primitive2d::FONT_RELIEF_NONE: eFontRelief = RELIEF_NONE; break; - case primitive2d::FONT_RELIEF_EMBOSSED: eFontRelief = RELIEF_EMBOSSED; break; - case primitive2d::FONT_RELIEF_ENGRAVED: eFontRelief = RELIEF_ENGRAVED; break; + case primitive2d::TEXT_RELIEF_NONE: eFontRelief = RELIEF_NONE; break; + case primitive2d::TEXT_RELIEF_EMBOSSED: eFontRelief = RELIEF_EMBOSSED; break; + case primitive2d::TEXT_RELIEF_ENGRAVED: eFontRelief = RELIEF_ENGRAVED; break; } if( eFontRelief != RELIEF_NONE ) @@ -282,7 +244,7 @@ namespace drawinglayer const Point aStartPoint(basegfx::fround(aPoint.getX()), basegfx::fround(aPoint.getY())); const sal_uInt32 nOldLayoutMode(mpOutputDevice->GetLayoutMode()); - if(rTextCandidate.getFontAttributes().getRTL()) + if(rTextCandidate.getFontAttribute().getRTL()) { sal_uInt32 nRTLLayoutMode(nOldLayoutMode & ~(TEXT_LAYOUT_COMPLEX_DISABLED|TEXT_LAYOUT_BIDI_STRONG)); nRTLLayoutMode |= TEXT_LAYOUT_BIDI_RTL|TEXT_LAYOUT_TEXTORIGIN_LEFT; @@ -310,7 +272,7 @@ namespace drawinglayer rTextCandidate.getTextLength()); } - if(rTextCandidate.getFontAttributes().getRTL()) + if(rTextCandidate.getFontAttribute().getRTL()) { mpOutputDevice->SetLayoutMode(nOldLayoutMode); } @@ -428,7 +390,7 @@ namespace drawinglayer { // no shear or rotate, draw direct in pixel coordinates bPrimitiveAccepted = true; - BitmapEx aBitmapEx(rFillBitmapAttribute.getBitmap()); + BitmapEx aBitmapEx(rFillBitmapAttribute.getBitmapEx()); bool bPainted(false); if(maBColorModifierStack.count()) @@ -547,21 +509,32 @@ namespace drawinglayer basegfx::BColor aStartColor(maBColorModifierStack.getModifiedColor(rGradient.getStartColor())); basegfx::BColor aEndColor(maBColorModifierStack.getModifiedColor(rGradient.getEndColor())); basegfx::B2DPolyPolygon aLocalPolyPolygon(rPolygonCandidate.getB2DPolyPolygon()); - aLocalPolyPolygon.transform(maCurrentTransformation); - if(aStartColor == aEndColor) - { - // no gradient at all, draw as polygon - mpOutputDevice->SetLineColor(); - mpOutputDevice->SetFillColor(Color(aStartColor)); - mpOutputDevice->DrawPolyPolygon(aLocalPolyPolygon); - } - else + if(aLocalPolyPolygon.count()) { - impDrawGradientToOutDev( - *mpOutputDevice, aLocalPolyPolygon, rGradient.getStyle(), rGradient.getSteps(), - aStartColor, aEndColor, rGradient.getBorder(), - -rGradient.getAngle(), rGradient.getOffsetX(), rGradient.getOffsetY(), false); + aLocalPolyPolygon.transform(maCurrentTransformation); + + if(aStartColor == aEndColor) + { + // no gradient at all, draw as polygon in AA and non-AA case + mpOutputDevice->SetLineColor(); + mpOutputDevice->SetFillColor(Color(aStartColor)); + mpOutputDevice->DrawPolyPolygon(aLocalPolyPolygon); + } + else if(getOptionsDrawinglayer().IsAntiAliasing()) + { + // For AA, direct render has to be avoided since it uses XOR maskings which will not + // work with AA. Instead, the decompose which uses MaskPrimitive2D with fillings is + // used + process(rPolygonCandidate.get2DDecomposition(getViewInformation2D())); + } + else + { + impDrawGradientToOutDev( + *mpOutputDevice, aLocalPolyPolygon, rGradient.getStyle(), rGradient.getSteps(), + aStartColor, aEndColor, rGradient.getBorder(), + -rGradient.getAngle(), rGradient.getOffsetX(), rGradient.getOffsetY(), false); + } } } @@ -574,9 +547,9 @@ namespace drawinglayer if(rPolyPolygon.count()) { const attribute::FillBitmapAttribute& rFillBitmapAttribute = rPolygonCandidate.getFillBitmap(); - const Bitmap& rBitmap = rFillBitmapAttribute.getBitmap(); + const BitmapEx& rBitmapEx = rFillBitmapAttribute.getBitmapEx(); - if(rBitmap.IsEmpty()) + if(rBitmapEx.IsEmpty()) { // empty bitmap, done bDone = true; @@ -668,7 +641,9 @@ namespace drawinglayer aLocalPolyPolygon.transform(maCurrentTransformation); mpOutputDevice->DrawPolyPolygon(aLocalPolyPolygon); - if(mnPolygonStrokePrimitive2D && getOptionsDrawinglayer().IsAntiAliasing()) + if(mnPolygonStrokePrimitive2D + && getOptionsDrawinglayer().IsAntiAliasing() + && (mpOutputDevice->GetAntialiasing() & ANTIALIASING_ENABLE_B2DDRAW)) { // when AA is on and this filled polygons are the result of stroked line geometry, // draw the geometry once extra as lines to avoid AA 'gaps' between partial polygons @@ -1256,6 +1231,43 @@ namespace drawinglayer } } + void VclProcessor2D::RenderEpsPrimitive2D(const primitive2d::EpsPrimitive2D& rEpsPrimitive2D) + { + // The new decomposition of Metafiles made it necessary to add an Eps + // primitive to handle embedded Eps data. On some devices, this can be + // painted directly (mac, printer). + // To be able to handle the replacement correctly, i need to handle it myself + // since DrawEPS will not be able e.g. to rotate the replacement. To be able + // to do that, i added a boolean return to OutputDevice::DrawEPS(..) + // to know when EPS was handled directly already. + basegfx::B2DRange aRange(0.0, 0.0, 1.0, 1.0); + aRange.transform(maCurrentTransformation * rEpsPrimitive2D.getEpsTransform()); + + if(!aRange.isEmpty()) + { + const Rectangle aRectangle( + (sal_Int32)floor(aRange.getMinX()), (sal_Int32)floor(aRange.getMinY()), + (sal_Int32)ceil(aRange.getMaxX()), (sal_Int32)ceil(aRange.getMaxY())); + + if(!aRectangle.IsEmpty()) + { + // try to paint EPS directly without fallback visualisation + const bool bEPSPaintedDirectly(mpOutputDevice->DrawEPS( + aRectangle.TopLeft(), + aRectangle.GetSize(), + rEpsPrimitive2D.getGfxLink(), + 0)); + + if(!bEPSPaintedDirectly) + { + // use the decomposition which will correctly handle the + // fallback visualisation using full transformation (e.g. rotation) + process(rEpsPrimitive2D.get2DDecomposition(getViewInformation2D())); + } + } + } + } + void VclProcessor2D::adaptLineToFillDrawMode() const { const sal_uInt32 nOriginalDrawMode(mpOutputDevice->GetDrawMode()); diff --git a/drawinglayer/source/processor3d/cutfindprocessor3d.cxx b/drawinglayer/source/processor3d/cutfindprocessor3d.cxx index 99f5801c60e3..42e2e1565803 100644 --- a/drawinglayer/source/processor3d/cutfindprocessor3d.cxx +++ b/drawinglayer/source/processor3d/cutfindprocessor3d.cxx @@ -73,8 +73,8 @@ namespace drawinglayer return; } - // it is a BasePrimitive3D implementation, use getPrimitiveID() call for switch - switch(rCandidate.getPrimitiveID()) + // it is a BasePrimitive3D implementation, use getPrimitive3DID() call for switch + switch(rCandidate.getPrimitive3DID()) { case PRIMITIVE3D_ID_TRANSFORMPRIMITIVE3D : { diff --git a/drawinglayer/source/processor3d/defaultprocessor3d.cxx b/drawinglayer/source/processor3d/defaultprocessor3d.cxx index d9194ca4b5eb..1be93d83b9a9 100644 --- a/drawinglayer/source/processor3d/defaultprocessor3d.cxx +++ b/drawinglayer/source/processor3d/defaultprocessor3d.cxx @@ -234,19 +234,19 @@ namespace drawinglayer texture::GeoTexSvx* pOldTex = mpGeoTexSvx; // create texture - const attribute::FillBitmapAttribute& rFillBitmapAttribute = rPrimitive.getBitmap(); + const attribute::FillBitmapAttribute& rFillBitmapAttribute = rPrimitive.getFillBitmapAttribute(); if(rFillBitmapAttribute.getTiling()) { mpGeoTexSvx = new texture::GeoTexSvxBitmapTiled( - rFillBitmapAttribute.getBitmap(), + rFillBitmapAttribute.getBitmapEx().GetBitmap(), rFillBitmapAttribute.getTopLeft() * rPrimitive.getTextureSize(), rFillBitmapAttribute.getSize() * rPrimitive.getTextureSize()); } else { mpGeoTexSvx = new texture::GeoTexSvxBitmap( - rFillBitmapAttribute.getBitmap(), + rFillBitmapAttribute.getBitmapEx().GetBitmap(), rFillBitmapAttribute.getTopLeft() * rPrimitive.getTextureSize(), rFillBitmapAttribute.getSize() * rPrimitive.getTextureSize()); } @@ -468,8 +468,8 @@ namespace drawinglayer void DefaultProcessor3D::processBasePrimitive3D(const primitive3d::BasePrimitive3D& rBasePrimitive) { - // it is a BasePrimitive3D implementation, use getPrimitiveID() call for switch - switch(rBasePrimitive.getPrimitiveID()) + // it is a BasePrimitive3D implementation, use getPrimitive3DID() call for switch + switch(rBasePrimitive.getPrimitive3DID()) { case PRIMITIVE3D_ID_GRADIENTTEXTUREPRIMITIVE3D : { diff --git a/drawinglayer/source/processor3d/geometry2dextractor.cxx b/drawinglayer/source/processor3d/geometry2dextractor.cxx index 8c19a4a2e3b8..c2e1c73b5181 100644 --- a/drawinglayer/source/processor3d/geometry2dextractor.cxx +++ b/drawinglayer/source/processor3d/geometry2dextractor.cxx @@ -62,8 +62,8 @@ namespace drawinglayer // virtual render method when the primitive implementation is BasePrimitive3D-based. void Geometry2DExtractingProcessor::processBasePrimitive3D(const primitive3d::BasePrimitive3D& rCandidate) { - // it is a BasePrimitive3D implementation, use getPrimitiveID() call for switch - switch(rCandidate.getPrimitiveID()) + // it is a BasePrimitive3D implementation, use getPrimitive3DID() call for switch + switch(rCandidate.getPrimitive3DID()) { case PRIMITIVE3D_ID_TRANSFORMPRIMITIVE3D : { diff --git a/drawinglayer/source/processor3d/shadow3dextractor.cxx b/drawinglayer/source/processor3d/shadow3dextractor.cxx index 66d3c073854f..5e6678fc3a8e 100644 --- a/drawinglayer/source/processor3d/shadow3dextractor.cxx +++ b/drawinglayer/source/processor3d/shadow3dextractor.cxx @@ -63,8 +63,8 @@ namespace drawinglayer // virtual render method when the primitive implementation is BasePrimitive3D-based. void Shadow3DExtractingProcessor::processBasePrimitive3D(const primitive3d::BasePrimitive3D& rCandidate) { - // it is a BasePrimitive3D implementation, use getPrimitiveID() call for switch - switch(rCandidate.getPrimitiveID()) + // it is a BasePrimitive3D implementation, use getPrimitive3DID() call for switch + switch(rCandidate.getPrimitive3DID()) { case PRIMITIVE3D_ID_SHADOWPRIMITIVE3D : { diff --git a/drawinglayer/source/processor3d/zbufferprocessor3d.cxx b/drawinglayer/source/processor3d/zbufferprocessor3d.cxx index b5a59e10a119..48c1bee86575 100644 --- a/drawinglayer/source/processor3d/zbufferprocessor3d.cxx +++ b/drawinglayer/source/processor3d/zbufferprocessor3d.cxx @@ -486,8 +486,8 @@ namespace drawinglayer // the processing method for a single, known primitive void ZBufferProcessor3D::processBasePrimitive3D(const primitive3d::BasePrimitive3D& rBasePrimitive) { - // it is a BasePrimitive3D implementation, use getPrimitiveID() call for switch - switch(rBasePrimitive.getPrimitiveID()) + // it is a BasePrimitive3D implementation, use getPrimitive3DID() call for switch + switch(rBasePrimitive.getPrimitive3DID()) { case PRIMITIVE3D_ID_ALPHATEXTUREPRIMITIVE3D : { diff --git a/drawinglayer/source/texture/texture.cxx b/drawinglayer/source/texture/texture.cxx index 4f784c71897f..1cc6730da33c 100644 --- a/drawinglayer/source/texture/texture.cxx +++ b/drawinglayer/source/texture/texture.cxx @@ -39,6 +39,7 @@ #include <drawinglayer/texture/texture.hxx> #include <basegfx/numeric/ftools.hxx> #include <basegfx/tools/gradienttools.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> ////////////////////////////////////////////////////////////////////////////// @@ -596,9 +597,8 @@ namespace drawinglayer basegfx::B2DPoint aCenter(0.5, 0.5); aCenter *= maTextureTransform; - maTextureTransform.translate(-aCenter.getX(), -aCenter.getY()); - maTextureTransform.rotate(fAngle); - maTextureTransform.translate(aCenter.getX(), aCenter.getY()); + maTextureTransform = basegfx::tools::createRotateAroundPoint(aCenter, fAngle) + * maTextureTransform; } // add object translate |