summaryrefslogtreecommitdiff
path: root/drawinglayer
diff options
context:
space:
mode:
authorArmin Le Grand <alg@apache.org>2012-10-16 08:44:02 +0000
committerArmin Le Grand <alg@apache.org>2012-10-16 08:44:02 +0000
commit7a652a2b2ab5e0d37e32185c8c5fac3af482bb76 (patch)
tree3cf859e86a5d4ba2a39e75d1f5bc65a5d8bc10b2 /drawinglayer
parent9d483a7b084404ed9df6525f09a3bb600a5859f8 (diff)
#121194# Better support for graphic fill styles which are not bitmaps (svg, metafiles, ..)
Notes
Notes: merged as: 37aa7d81aacaae12dfe0fd2ade2779235bbf72f1
Diffstat (limited to 'drawinglayer')
-rw-r--r--drawinglayer/Library_drawinglayer.mk8
-rw-r--r--drawinglayer/Package_inc.mk8
-rwxr-xr-x[-rw-r--r--]drawinglayer/inc/drawinglayer/attribute/fillgraphicattribute.hxx (renamed from drawinglayer/inc/drawinglayer/attribute/fillbitmapattribute.hxx)45
-rw-r--r--drawinglayer/inc/drawinglayer/attribute/sdrfillattribute.hxx6
-rwxr-xr-x[-rw-r--r--]drawinglayer/inc/drawinglayer/attribute/sdrfillgraphicattribute.hxx (renamed from drawinglayer/inc/drawinglayer/attribute/sdrfillbitmapattribute.hxx)36
-rw-r--r--drawinglayer/inc/drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx4
-rwxr-xr-x[-rw-r--r--]drawinglayer/inc/drawinglayer/primitive2d/fillgraphicprimitive2d.hxx (renamed from drawinglayer/inc/drawinglayer/primitive2d/fillbitmapprimitive2d.hxx)22
-rwxr-xr-xdrawinglayer/inc/drawinglayer/primitive2d/graphicprimitivehelper2d.hxx60
-rw-r--r--drawinglayer/inc/drawinglayer/primitive2d/polypolygonprimitive2d.hxx18
-rw-r--r--drawinglayer/inc/drawinglayer/primitive3d/textureprimitive3d.hxx8
-rw-r--r--drawinglayer/inc/drawinglayer/processor2d/canvasprocessor.hxx125
-rw-r--r--drawinglayer/inc/drawinglayer/processor2d/vclprocessor2d.hxx8
-rw-r--r--drawinglayer/inc/drawinglayer/texture/texture.hxx19
-rw-r--r--drawinglayer/inc/drawinglayer/texture/texture3d.hxx58
-rw-r--r--drawinglayer/source/attribute/fillbitmapattribute.cxx195
-rwxr-xr-xdrawinglayer/source/attribute/fillgraphicattribute.cxx215
-rw-r--r--drawinglayer/source/attribute/sdrfillattribute.cxx25
-rwxr-xr-x[-rw-r--r--]drawinglayer/source/attribute/sdrfillgraphicattribute.cxx (renamed from drawinglayer/source/attribute/sdrfillbitmapattribute.cxx)199
-rw-r--r--drawinglayer/source/primitive2d/fillbitmapprimitive2d.cxx138
-rw-r--r--drawinglayer/source/primitive2d/fillgraphicprimitive2d.cxx147
-rw-r--r--drawinglayer/source/primitive2d/graphicprimitive2d.cxx755
-rwxr-xr-xdrawinglayer/source/primitive2d/graphicprimitivehelper2d.cxx782
-rw-r--r--drawinglayer/source/primitive2d/metafileprimitive2d.cxx2
-rw-r--r--drawinglayer/source/primitive2d/patternfillprimitive2d.cxx3
-rw-r--r--drawinglayer/source/primitive2d/polypolygonprimitive2d.cxx71
-rw-r--r--drawinglayer/source/primitive2d/wallpaperprimitive2d.cxx27
-rw-r--r--drawinglayer/source/primitive3d/sdrdecompositiontools3d.cxx14
-rw-r--r--drawinglayer/source/primitive3d/textureprimitive3d.cxx6
-rw-r--r--drawinglayer/source/processor2d/_vclmetafileprocessor2d.cxx2086
-rw-r--r--drawinglayer/source/processor2d/canvasprocessor.cxx2213
-rw-r--r--drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx73
-rw-r--r--drawinglayer/source/processor2d/vclpixelprocessor2d.cxx10
-rw-r--r--drawinglayer/source/processor2d/vclprocessor2d.cxx390
-rw-r--r--drawinglayer/source/processor3d/defaultprocessor3d.cxx34
-rw-r--r--drawinglayer/source/texture/texture.cxx129
-rw-r--r--drawinglayer/source/texture/texture3d.cxx217
36 files changed, 4163 insertions, 3993 deletions
diff --git a/drawinglayer/Library_drawinglayer.mk b/drawinglayer/Library_drawinglayer.mk
index 441f1e7be2be..7279af460e8c 100644
--- a/drawinglayer/Library_drawinglayer.mk
+++ b/drawinglayer/Library_drawinglayer.mk
@@ -66,7 +66,7 @@ $(eval $(call gb_Library_add_exception_objects,drawinglayer,\
drawinglayer/source/animation/animationtiming \
drawinglayer/source/attribute/fillgradientattribute \
drawinglayer/source/attribute/fillhatchattribute \
- drawinglayer/source/attribute/fillbitmapattribute \
+ drawinglayer/source/attribute/fillgraphicattribute \
drawinglayer/source/attribute/fontattribute \
drawinglayer/source/attribute/materialattribute3d \
drawinglayer/source/attribute/sdrallattribute3d \
@@ -78,7 +78,7 @@ $(eval $(call gb_Library_add_exception_objects,drawinglayer,\
drawinglayer/source/attribute/sdrlightattribute3d \
drawinglayer/source/attribute/sdrlightingattribute3d \
drawinglayer/source/attribute/sdrsceneattribute3d \
- drawinglayer/source/attribute/sdrfillbitmapattribute \
+ drawinglayer/source/attribute/sdrfillgraphicattribute \
drawinglayer/source/attribute/lineattribute \
drawinglayer/source/attribute/linestartendattribute \
drawinglayer/source/attribute/strokeattribute \
@@ -96,9 +96,10 @@ $(eval $(call gb_Library_add_exception_objects,drawinglayer,\
drawinglayer/source/primitive2d/discreteshadowprimitive2d \
drawinglayer/source/primitive2d/embedded3dprimitive2d \
drawinglayer/source/primitive2d/epsprimitive2d \
- drawinglayer/source/primitive2d/fillbitmapprimitive2d \
+ drawinglayer/source/primitive2d/fillgraphicprimitive2d \
drawinglayer/source/primitive2d/fillgradientprimitive2d \
drawinglayer/source/primitive2d/fillhatchprimitive2d \
+ drawinglayer/source/primitive2d/graphicprimitivehelper2d \
drawinglayer/source/primitive2d/graphicprimitive2d \
drawinglayer/source/primitive2d/gridprimitive2d \
drawinglayer/source/primitive2d/groupprimitive2d \
@@ -165,7 +166,6 @@ $(eval $(call gb_Library_add_exception_objects,drawinglayer,\
drawinglayer/source/processor2d/vclmetafileprocessor2d \
drawinglayer/source/processor2d/contourextractor2d \
drawinglayer/source/processor2d/linegeometryextractor2d \
- drawinglayer/source/processor2d/canvasprocessor \
drawinglayer/source/processor2d/hittestprocessor2d \
drawinglayer/source/processor2d/textaspolygonextractor2d \
drawinglayer/source/processor2d/objectinfoextractor2d \
diff --git a/drawinglayer/Package_inc.mk b/drawinglayer/Package_inc.mk
index 7f677dfda91d..e27a64f3d0fb 100644
--- a/drawinglayer/Package_inc.mk
+++ b/drawinglayer/Package_inc.mk
@@ -35,10 +35,11 @@ $(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive2d/
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive2d/discretebitmapprimitive2d.hxx,drawinglayer/primitive2d/discretebitmapprimitive2d.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive2d/discreteshadowprimitive2d.hxx,drawinglayer/primitive2d/discreteshadowprimitive2d.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive2d/embedded3dprimitive2d.hxx,drawinglayer/primitive2d/embedded3dprimitive2d.hxx))
-$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive2d/fillbitmapprimitive2d.hxx,drawinglayer/primitive2d/fillbitmapprimitive2d.hxx))
+$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive2d/fillgraphicprimitive2d.hxx,drawinglayer/primitive2d/fillgraphicprimitive2d.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive2d/fillgradientprimitive2d.hxx,drawinglayer/primitive2d/fillgradientprimitive2d.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive2d/fillhatchprimitive2d.hxx,drawinglayer/primitive2d/fillhatchprimitive2d.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive2d/graphicprimitive2d.hxx,drawinglayer/primitive2d/graphicprimitive2d.hxx))
+$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive2d/graphicprimitivehelper2d.hxx,drawinglayer/primitive2d/graphicprimitivehelper2d.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive2d/gridprimitive2d.hxx,drawinglayer/primitive2d/gridprimitive2d.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive2d/groupprimitive2d.hxx,drawinglayer/primitive2d/groupprimitive2d.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive2d/helplineprimitive2d.hxx,drawinglayer/primitive2d/helplineprimitive2d.hxx))
@@ -104,7 +105,6 @@ $(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/processor2d/
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/processor2d/vclprocessor2d.hxx,drawinglayer/processor2d/vclprocessor2d.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/processor2d/vclpixelprocessor2d.hxx,drawinglayer/processor2d/vclpixelprocessor2d.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/processor2d/vclmetafileprocessor2d.hxx,drawinglayer/processor2d/vclmetafileprocessor2d.hxx))
-$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/processor2d/canvasprocessor.hxx,drawinglayer/processor2d/canvasprocessor.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/processor2d/contourextractor2d.hxx,drawinglayer/processor2d/contourextractor2d.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/processor2d/linegeometryextractor2d.hxx,drawinglayer/processor2d/linegeometryextractor2d.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/processor2d/hittestprocessor2d.hxx,drawinglayer/processor2d/hittestprocessor2d.hxx))
@@ -120,7 +120,7 @@ $(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/processor3d/
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/attribute/fillgradientattribute.hxx,drawinglayer/attribute/fillgradientattribute.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/attribute/fillhatchattribute.hxx,drawinglayer/attribute/fillhatchattribute.hxx))
-$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/attribute/fillbitmapattribute.hxx,drawinglayer/attribute/fillbitmapattribute.hxx))
+$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/attribute/fillgraphicattribute.hxx,drawinglayer/attribute/fillgraphicattribute.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/attribute/fontattribute.hxx,drawinglayer/attribute/fontattribute.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/attribute/materialattribute3d.hxx,drawinglayer/attribute/materialattribute3d.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/attribute/sdrallattribute3d.hxx,drawinglayer/attribute/sdrallattribute3d.hxx))
@@ -132,7 +132,7 @@ $(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/attribute/sd
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/attribute/sdrlightattribute3d.hxx,drawinglayer/attribute/sdrlightattribute3d.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/attribute/sdrlightingattribute3d.hxx,drawinglayer/attribute/sdrlightingattribute3d.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/attribute/sdrsceneattribute3d.hxx,drawinglayer/attribute/sdrsceneattribute3d.hxx))
-$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/attribute/sdrfillbitmapattribute.hxx,drawinglayer/attribute/sdrfillbitmapattribute.hxx))
+$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/attribute/sdrfillgraphicattribute.hxx,drawinglayer/attribute/sdrfillgraphicattribute.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/attribute/strokeattribute.hxx,drawinglayer/attribute/strokeattribute.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/attribute/lineattribute.hxx,drawinglayer/attribute/lineattribute.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/attribute/linestartendattribute.hxx,drawinglayer/attribute/linestartendattribute.hxx))
diff --git a/drawinglayer/inc/drawinglayer/attribute/fillbitmapattribute.hxx b/drawinglayer/inc/drawinglayer/attribute/fillgraphicattribute.hxx
index 776b3483b791..9e70ef79b026 100644..100755
--- a/drawinglayer/inc/drawinglayer/attribute/fillbitmapattribute.hxx
+++ b/drawinglayer/inc/drawinglayer/attribute/fillgraphicattribute.hxx
@@ -21,22 +21,21 @@
-#ifndef INCLUDED_DRAWINGLAYER_ATTRIBUTE_FILLBITMAPATTRIBUTE_HXX
-#define INCLUDED_DRAWINGLAYER_ATTRIBUTE_FILLBITMAPATTRIBUTE_HXX
+#ifndef INCLUDED_DRAWINGLAYER_ATTRIBUTE_FILLGRAPHICATTRIBUTE_HXX
+#define INCLUDED_DRAWINGLAYER_ATTRIBUTE_FILLGRAPHICATTRIBUTE_HXX
#include <drawinglayer/drawinglayerdllapi.h>
//////////////////////////////////////////////////////////////////////////////
// predefines
-class BitmapEx;
+class Graphic;
namespace basegfx {
- class B2DPoint;
- class B2DVector;
+ class B2DRange;
}
namespace drawinglayer { namespace attribute {
- class ImpFillBitmapAttribute;
+ class ImpFillGraphicAttribute;
}}
//////////////////////////////////////////////////////////////////////////////
@@ -45,40 +44,42 @@ namespace drawinglayer
{
namespace attribute
{
- class DRAWINGLAYER_DLLPUBLIC FillBitmapAttribute
+ class DRAWINGLAYER_DLLPUBLIC FillGraphicAttribute
{
private:
- ImpFillBitmapAttribute* mpFillBitmapAttribute;
+ ImpFillGraphicAttribute* mpFillGraphicAttribute;
public:
/// constructors/assignmentoperator/destructor
- FillBitmapAttribute(
- const BitmapEx& rBitmapEx,
- const basegfx::B2DPoint& rTopLeft,
- const basegfx::B2DVector& rSize,
- bool bTiling);
- FillBitmapAttribute();
- FillBitmapAttribute(const FillBitmapAttribute& rCandidate);
- FillBitmapAttribute& operator=(const FillBitmapAttribute& rCandidate);
- ~FillBitmapAttribute();
+ FillGraphicAttribute(
+ const Graphic& rGraphic,
+ const basegfx::B2DRange& rGraphicRange,
+ bool bTiling = false,
+ double fOffsetX = 0.0,
+ double fOffsetY = 0.0);
+ FillGraphicAttribute();
+ FillGraphicAttribute(const FillGraphicAttribute& rCandidate);
+ FillGraphicAttribute& operator=(const FillGraphicAttribute& rCandidate);
+ ~FillGraphicAttribute();
// checks if the incarnation is default constructed
bool isDefault() const;
// compare operator
- bool operator==(const FillBitmapAttribute& rCandidate) const;
+ bool operator==(const FillGraphicAttribute& rCandidate) const;
// data read access
- const BitmapEx& getBitmapEx() const;
- const basegfx::B2DPoint& getTopLeft() const;
- const basegfx::B2DVector& getSize() const;
+ const Graphic& getGraphic() const;
+ const basegfx::B2DRange& getGraphicRange() const;
bool getTiling() const;
+ double getOffsetX() const;
+ double getOffsetY() const;
};
} // end of namespace attribute
} // end of namespace drawinglayer
//////////////////////////////////////////////////////////////////////////////
-#endif //INCLUDED_DRAWINGLAYER_ATTRIBUTE_FILLBITMAPATTRIBUTE_HXX
+#endif //INCLUDED_DRAWINGLAYER_ATTRIBUTE_FILLGRAPHICATTRIBUTE_HXX
// eof
diff --git a/drawinglayer/inc/drawinglayer/attribute/sdrfillattribute.hxx b/drawinglayer/inc/drawinglayer/attribute/sdrfillattribute.hxx
index bb1576023172..ecf15e0c80ae 100644
--- a/drawinglayer/inc/drawinglayer/attribute/sdrfillattribute.hxx
+++ b/drawinglayer/inc/drawinglayer/attribute/sdrfillattribute.hxx
@@ -34,7 +34,7 @@ namespace drawinglayer { namespace attribute {
class ImpSdrFillAttribute;
class FillGradientAttribute;
class FillHatchAttribute;
- class SdrFillBitmapAttribute;
+ class SdrFillGraphicAttribute;
}}
//////////////////////////////////////////////////////////////////////////////
@@ -55,7 +55,7 @@ namespace drawinglayer
const basegfx::BColor& rColor,
const FillGradientAttribute& rGradient,
const FillHatchAttribute& rHatch,
- const SdrFillBitmapAttribute& rBitmap);
+ const SdrFillGraphicAttribute& rFillGraphic);
SdrFillAttribute();
SdrFillAttribute(const SdrFillAttribute& rCandidate);
SdrFillAttribute& operator=(const SdrFillAttribute& rCandidate);
@@ -72,7 +72,7 @@ namespace drawinglayer
const basegfx::BColor& getColor() const;
const FillGradientAttribute& getGradient() const;
const FillHatchAttribute& getHatch() const;
- const SdrFillBitmapAttribute& getBitmap() const;
+ const SdrFillGraphicAttribute& getFillGraphic() const;
};
} // end of namespace attribute
} // end of namespace drawinglayer
diff --git a/drawinglayer/inc/drawinglayer/attribute/sdrfillbitmapattribute.hxx b/drawinglayer/inc/drawinglayer/attribute/sdrfillgraphicattribute.hxx
index 6a9e9c4a9121..3a4acac21a80 100644..100755
--- a/drawinglayer/inc/drawinglayer/attribute/sdrfillbitmapattribute.hxx
+++ b/drawinglayer/inc/drawinglayer/attribute/sdrfillgraphicattribute.hxx
@@ -21,15 +21,15 @@
-#ifndef INCLUDED_DRAWINGLAYER_ATTRIBUTE_SDRFILLBITMAPATTRIBUTE_HXX
-#define INCLUDED_DRAWINGLAYER_ATTRIBUTE_SDRFILLBITMAPATTRIBUTE_HXX
+#ifndef INCLUDED_DRAWINGLAYER_ATTRIBUTE_SDRFILLGRAPHICATTRIBUTE_HXX
+#define INCLUDED_DRAWINGLAYER_ATTRIBUTE_SDRFILLGRAPHICATTRIBUTE_HXX
#include <drawinglayer/drawinglayerdllapi.h>
//////////////////////////////////////////////////////////////////////////////
// predefines
-class BitmapEx;
+class Graphic;
namespace basegfx {
class B2DRange;
@@ -37,8 +37,8 @@ namespace basegfx {
}
namespace drawinglayer { namespace attribute {
- class FillBitmapAttribute;
- class ImpSdrFillBitmapAttribute;
+ class FillGraphicAttribute;
+ class ImpSdrFillGraphicAttribute;
}}
//////////////////////////////////////////////////////////////////////////////
@@ -47,15 +47,15 @@ namespace drawinglayer
{
namespace attribute
{
- class DRAWINGLAYER_DLLPUBLIC SdrFillBitmapAttribute
+ class DRAWINGLAYER_DLLPUBLIC SdrFillGraphicAttribute
{
private:
- ImpSdrFillBitmapAttribute* mpSdrFillBitmapAttribute;
+ ImpSdrFillGraphicAttribute* mpSdrFillGraphicAttribute;
public:
/// constructors/assignmentoperator/destructor
- SdrFillBitmapAttribute(
- const BitmapEx& rBitmapEx,
+ SdrFillGraphicAttribute(
+ const Graphic& rFillGraphic,
const basegfx::B2DVector& rSize,
const basegfx::B2DVector& rOffset,
const basegfx::B2DVector& rOffsetPosition,
@@ -63,19 +63,19 @@ namespace drawinglayer
bool bTiling,
bool bStretch,
bool bLogSize);
- SdrFillBitmapAttribute();
- SdrFillBitmapAttribute(const SdrFillBitmapAttribute& rCandidate);
- SdrFillBitmapAttribute& operator=(const SdrFillBitmapAttribute& rCandidate);
- ~SdrFillBitmapAttribute();
+ SdrFillGraphicAttribute();
+ SdrFillGraphicAttribute(const SdrFillGraphicAttribute& rCandidate);
+ SdrFillGraphicAttribute& operator=(const SdrFillGraphicAttribute& rCandidate);
+ ~SdrFillGraphicAttribute();
// checks if the incarnation is default constructed
bool isDefault() const;
// compare operator
- bool operator==(const SdrFillBitmapAttribute& rCandidate) const;
+ bool operator==(const SdrFillGraphicAttribute& rCandidate) const;
// data read access
- const BitmapEx& getBitmapEx() const;
+ const Graphic& getFillGraphic() const;
const basegfx::B2DVector& getSize() const;
const basegfx::B2DVector& getOffset() const;
const basegfx::B2DVector& getOffsetPosition() const;
@@ -84,14 +84,14 @@ namespace drawinglayer
bool getStretch() const;
bool getLogSize() const;
- // FillBitmapAttribute generator
- FillBitmapAttribute getFillBitmapAttribute(const basegfx::B2DRange& rRange) const;
+ // FillGraphicAttribute generator
+ FillGraphicAttribute createFillGraphicAttribute(const basegfx::B2DRange& rRange) const;
};
} // end of namespace attribute
} // end of namespace drawinglayer
//////////////////////////////////////////////////////////////////////////////
-#endif //INCLUDED_DRAWINGLAYER_ATTRIBUTE_SDRFILLBITMAPATTRIBUTE_HXX
+#endif //INCLUDED_DRAWINGLAYER_ATTRIBUTE_SDRFILLGRAPHICATTRIBUTE_HXX
// eof
diff --git a/drawinglayer/inc/drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx
index aac9dfb7e170..bc80af9cb3f3 100644
--- a/drawinglayer/inc/drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx
+++ b/drawinglayer/inc/drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx
@@ -44,7 +44,7 @@
#define PRIMITIVE2D_ID_BITMAPPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 5)
#define PRIMITIVE2D_ID_CONTROLPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 6)
#define PRIMITIVE2D_ID_EMBEDDED3DPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 7)
-#define PRIMITIVE2D_ID_FILLBITMAPPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 8)
+#define PRIMITIVE2D_ID_FILLGRAPHICPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 8)
#define PRIMITIVE2D_ID_FILLGRADIENTPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 9)
#define PRIMITIVE2D_ID_FILLHATCHPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 10)
#define PRIMITIVE2D_ID_GRAPHICPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 11)
@@ -65,7 +65,7 @@
#define PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 26)
#define PRIMITIVE2D_ID_POLYPOLYGONGRADIENTPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 27)
#define PRIMITIVE2D_ID_POLYPOLYGONHATCHPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 28)
-#define PRIMITIVE2D_ID_POLYPOLYGONBITMAPPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 29)
+#define PRIMITIVE2D_ID_POLYPOLYGONGRAPHICPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 29)
#define PRIMITIVE2D_ID_SCENEPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 30)
#define PRIMITIVE2D_ID_SHADOWPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 31)
#define PRIMITIVE2D_ID_TEXTSIMPLEPORTIONPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 32)
diff --git a/drawinglayer/inc/drawinglayer/primitive2d/fillbitmapprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/fillgraphicprimitive2d.hxx
index 0ce8a3683bda..6658e6d01b43 100644..100755
--- a/drawinglayer/inc/drawinglayer/primitive2d/fillbitmapprimitive2d.hxx
+++ b/drawinglayer/inc/drawinglayer/primitive2d/fillgraphicprimitive2d.hxx
@@ -21,13 +21,13 @@
-#ifndef INCLUDED_DRAWINGLAYER_PRIMITIVE2D_FILLBITMAPPRIMITIVE2D_HXX
-#define INCLUDED_DRAWINGLAYER_PRIMITIVE2D_FILLBITMAPPRIMITIVE2D_HXX
+#ifndef INCLUDED_DRAWINGLAYER_PRIMITIVE2D_FILLGRAPHICPRIMITIVE2D_HXX
+#define INCLUDED_DRAWINGLAYER_PRIMITIVE2D_FILLGRAPHICPRIMITIVE2D_HXX
#include <drawinglayer/drawinglayerdllapi.h>
#include <drawinglayer/primitive2d/baseprimitive2d.hxx>
#include <basegfx/matrix/b2dhommatrix.hxx>
-#include <drawinglayer/attribute/fillbitmapattribute.hxx>
+#include <drawinglayer/attribute/fillgraphicattribute.hxx>
//////////////////////////////////////////////////////////////////////////////
// FillbitmapPrimitive2D class
@@ -36,10 +36,10 @@ namespace drawinglayer
{
namespace primitive2d
{
- /** FillBitmapPrimitive2D class
+ /** FillGraphicPrimitive2D class
This class defines a bitmap filling for a rectangular area. The
- Range is defined by the Transformation, the fill by the FillBitmapAttribute.
+ Range is defined by the Transformation, the fill by the FillGraphicAttribute.
There, the fill consists of a Bitmap (not transparent) defining the fill data
and a Point/Vector pair defining the relative position/size [0.0 .. 1.0]
inside the area where the bitmap is positioned. A flag defines then if this
@@ -49,14 +49,14 @@ namespace drawinglayer
decomposition, but on pixel oututs the areas where the tiled pieces are
aligned tend to show up (one overlapping or empty pixel)
*/
- class DRAWINGLAYER_DLLPUBLIC FillBitmapPrimitive2D : public BufferedDecompositionPrimitive2D
+ class DRAWINGLAYER_DLLPUBLIC FillGraphicPrimitive2D : public BufferedDecompositionPrimitive2D
{
private:
/// the geometric definition
basegfx::B2DHomMatrix maTransformation;
/// the fill attributes
- attribute::FillBitmapAttribute maFillBitmap;
+ attribute::FillGraphicAttribute maFillGraphic;
protected:
/// local decomposition.
@@ -64,13 +64,13 @@ namespace drawinglayer
public:
/// constructor
- FillBitmapPrimitive2D(
+ FillGraphicPrimitive2D(
const basegfx::B2DHomMatrix& rTransformation,
- const attribute::FillBitmapAttribute& rFillBitmap);
+ const attribute::FillGraphicAttribute& rFillGraphic);
/// data read access
const basegfx::B2DHomMatrix& getTransformation() const { return maTransformation; }
- const attribute::FillBitmapAttribute& getFillBitmap() const { return maFillBitmap; }
+ const attribute::FillGraphicAttribute& getFillGraphic() const { return maFillGraphic; }
/// compare operator
virtual bool operator==( const BasePrimitive2D& rPrimitive ) const;
@@ -86,7 +86,7 @@ namespace drawinglayer
//////////////////////////////////////////////////////////////////////////////
-#endif //INCLUDED_DRAWINGLAYER_PRIMITIVE2D_FILLBITMAPPRIMITIVE2D_HXX
+#endif //INCLUDED_DRAWINGLAYER_PRIMITIVE2D_FILLGRAPHICPRIMITIVE2D_HXX
//////////////////////////////////////////////////////////////////////////////
// eof
diff --git a/drawinglayer/inc/drawinglayer/primitive2d/graphicprimitivehelper2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/graphicprimitivehelper2d.hxx
new file mode 100755
index 000000000000..e47ad3e331d7
--- /dev/null
+++ b/drawinglayer/inc/drawinglayer/primitive2d/graphicprimitivehelper2d.hxx
@@ -0,0 +1,60 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+
+
+#ifndef INCLUDED_DRAWINGLAYER_PRIMITIVE2D_GRAPHICPRIMITIVEHELPER2D_HXX
+#define INCLUDED_DRAWINGLAYER_PRIMITIVE2D_GRAPHICPRIMITIVEHELPER2D_HXX
+
+#include <drawinglayer/drawinglayerdllapi.h>
+#include <drawinglayer/primitive2d/baseprimitive2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+// predefines
+
+class Graphic;
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ /** Helper method with supports decomposing a Graphic with all
+ possible contents to lower level primitives.
+
+ #121194# Unified to use this helper for FillGraphicPrimitive2D
+ and GraphicPrimitive2D at the same time. It is able to handle
+ Bitmaps (with the sub-categories animated bitmap, and SVG),
+ and Metafiles.
+ */
+ Primitive2DSequence create2DDecompositionOfGraphic(
+ const Graphic& rGraphic,
+ const basegfx::B2DHomMatrix& rTransform);
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif // INCLUDED_DRAWINGLAYER_PRIMITIVE2D_GRAPHICPRIMITIVEHELPER2D_HXX
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/inc/drawinglayer/primitive2d/polypolygonprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/polypolygonprimitive2d.hxx
index ebd3a7361506..1fd133d3f629 100644
--- a/drawinglayer/inc/drawinglayer/primitive2d/polypolygonprimitive2d.hxx
+++ b/drawinglayer/inc/drawinglayer/primitive2d/polypolygonprimitive2d.hxx
@@ -26,7 +26,7 @@
#include <drawinglayer/drawinglayerdllapi.h>
#include <drawinglayer/primitive2d/baseprimitive2d.hxx>
-#include <drawinglayer/attribute/fillbitmapattribute.hxx>
+#include <drawinglayer/attribute/fillgraphicattribute.hxx>
#include <basegfx/polygon/b2dpolypolygon.hxx>
#include <drawinglayer/attribute/lineattribute.hxx>
#include <drawinglayer/attribute/strokeattribute.hxx>
@@ -391,26 +391,26 @@ namespace drawinglayer
} // end of namespace drawinglayer
//////////////////////////////////////////////////////////////////////////////
-// PolyPolygonBitmapPrimitive2D class
+// PolyPolygonGraphicPrimitive2D class
namespace drawinglayer
{
namespace primitive2d
{
- /** PolyPolygonBitmapPrimitive2D class
+ /** PolyPolygonGraphicPrimitive2D class
This primitive defines a PolyPolygon filled with bitmap data
(including transparence). The decomosition will create a MaskPrimitive2D
- containing a FillBitmapPrimitive2D.
+ containing a FillGraphicPrimitive2D.
*/
- class DRAWINGLAYER_DLLPUBLIC PolyPolygonBitmapPrimitive2D : public BufferedDecompositionPrimitive2D
+ class DRAWINGLAYER_DLLPUBLIC PolyPolygonGraphicPrimitive2D : public BufferedDecompositionPrimitive2D
{
private:
/// the PolyPolygon geometry
basegfx::B2DPolyPolygon maPolyPolygon;
/// the bitmap fill definition (may include tiling)
- attribute::FillBitmapAttribute maFillBitmap;
+ attribute::FillGraphicAttribute maFillGraphic;
protected:
/// local decomposition.
@@ -418,13 +418,13 @@ namespace drawinglayer
public:
/// constructor
- PolyPolygonBitmapPrimitive2D(
+ PolyPolygonGraphicPrimitive2D(
const basegfx::B2DPolyPolygon& rPolyPolygon,
- const attribute::FillBitmapAttribute& rFillBitmap);
+ const attribute::FillGraphicAttribute& rFillGraphic);
/// data read access
const basegfx::B2DPolyPolygon& getB2DPolyPolygon() const { return maPolyPolygon; }
- const attribute::FillBitmapAttribute& getFillBitmap() const { return maFillBitmap; }
+ const attribute::FillGraphicAttribute& getFillGraphic() const { return maFillGraphic; }
/// compare operator
virtual bool operator==(const BasePrimitive2D& rPrimitive) const;
diff --git a/drawinglayer/inc/drawinglayer/primitive3d/textureprimitive3d.hxx b/drawinglayer/inc/drawinglayer/primitive3d/textureprimitive3d.hxx
index 8dc7cbe66d09..0422251837ca 100644
--- a/drawinglayer/inc/drawinglayer/primitive3d/textureprimitive3d.hxx
+++ b/drawinglayer/inc/drawinglayer/primitive3d/textureprimitive3d.hxx
@@ -26,7 +26,7 @@
#include <drawinglayer/drawinglayerdllapi.h>
#include <drawinglayer/primitive3d/groupprimitive3d.hxx>
-#include <drawinglayer/attribute/fillbitmapattribute.hxx>
+#include <drawinglayer/attribute/fillgraphicattribute.hxx>
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <basegfx/vector/b2dvector.hxx>
#include <drawinglayer/attribute/fillgradientattribute.hxx>
@@ -172,19 +172,19 @@ namespace drawinglayer
{
private:
/// bitmap fill attribute
- attribute::FillBitmapAttribute maFillBitmapAttribute;
+ attribute::FillGraphicAttribute maFillGraphicAttribute;
public:
/// constructor
BitmapTexturePrimitive3D(
- const attribute::FillBitmapAttribute& rFillBitmapAttribute,
+ const attribute::FillGraphicAttribute& rFillGraphicAttribute,
const Primitive3DSequence& rChildren,
const basegfx::B2DVector& rTextureSize,
bool bModulate,
bool bFilter);
/// data read access
- const attribute::FillBitmapAttribute& getFillBitmapAttribute() const { return maFillBitmapAttribute; }
+ const attribute::FillGraphicAttribute& getFillGraphicAttribute() const { return maFillGraphicAttribute; }
/// compare operator
virtual bool operator==(const BasePrimitive3D& rPrimitive) const;
diff --git a/drawinglayer/inc/drawinglayer/processor2d/canvasprocessor.hxx b/drawinglayer/inc/drawinglayer/processor2d/canvasprocessor.hxx
deleted file mode 100644
index 2b3851899448..000000000000
--- a/drawinglayer/inc/drawinglayer/processor2d/canvasprocessor.hxx
+++ /dev/null
@@ -1,125 +0,0 @@
-/**************************************************************
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- *************************************************************/
-
-
-
-#ifndef _DRAWINGLAYER_PROCESSOR_CANVASPROCESSOR_HXX
-#define _DRAWINGLAYER_PROCESSOR_CANVASPROCESSOR_HXX
-
-#include <drawinglayer/drawinglayerdllapi.h>
-#include <drawinglayer/processor2d/baseprocessor2d.hxx>
-#include <basegfx/matrix/b2dhommatrix.hxx>
-#include <basegfx/color/bcolormodifier.hxx>
-#include <svtools/optionsdrawinglayer.hxx>
-#include <com/sun/star/rendering/ViewState.hpp>
-#include <com/sun/star/rendering/RenderState.hpp>
-#include <i18npool/lang.h>
-#include <basegfx/polygon/b2dpolypolygon.hxx>
-#include <vcl/mapmod.hxx>
-
-//////////////////////////////////////////////////////////////////////////////
-// forward declaration
-
-namespace basegfx {
- class BColor;
- class B2DPolygon;
-}
-
-namespace com { namespace sun { namespace star { namespace rendering {
- class XCanvas;
- class XPolyPolygon2D;
-}}}}
-
-namespace drawinglayer { namespace primitive2d {
- class MaskPrimitive2D;
- class MetafilePrimitive2D;
- class TextSimplePortionPrimitive2D;
- class BitmapPrimitive2D;
- class TransparencePrimitive2D;
- class PolygonStrokePrimitive2D;
- class FillBitmapPrimitive2D;
- class UnifiedTransparencePrimitive2D;
-}}
-
-//////////////////////////////////////////////////////////////////////////////
-
-namespace drawinglayer
-{
- namespace processor2d
- {
- /** canvasProcessor2D class
-
- A basic implementation of a renderer for com::sun::star::rendering::XCanvas
- as a target
- */
- class DRAWINGLAYER_DLLPUBLIC canvasProcessor2D : public BaseProcessor2D
- {
- private:
- // the (current) destination OutDev and canvas
- OutputDevice* mpOutputDevice;
- com::sun::star::uno::Reference< com::sun::star::rendering::XCanvas > mxCanvas;
- com::sun::star::rendering::ViewState maViewState;
- com::sun::star::rendering::RenderState maRenderState;
-
- // the modifiedColorPrimitive stack
- basegfx::BColorModifierStack maBColorModifierStack;
-
- // SvtOptionsDrawinglayer incarnation to react on diverse settings
- const SvtOptionsDrawinglayer maDrawinglayerOpt;
-
- // the current clipping PolyPolygon from MaskPrimitive2D, always in
- // object coordinates
- basegfx::B2DPolyPolygon maClipPolyPolygon;
-
- // determined LanguageType
- LanguageType meLang;
-
- // as tooling, the process() implementation takes over API handling and calls this
- // virtual render method when the primitive implementation is BasePrimitive2D-based.
- virtual void processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate);
-
- // direct primitive renderer support
- void impRenderMaskPrimitive2D(const primitive2d::MaskPrimitive2D& rMaskCandidate);
- void impRenderMetafilePrimitive2D(const primitive2d::MetafilePrimitive2D& rMetaCandidate);
- void impRenderTextSimplePortionPrimitive2D(const primitive2d::TextSimplePortionPrimitive2D& rTextCandidate);
- void impRenderBitmapPrimitive2D(const primitive2d::BitmapPrimitive2D& rBitmapCandidate);
- void impRenderTransparencePrimitive2D(const primitive2d::TransparencePrimitive2D& rTransparenceCandidate);
- void impRenderPolygonStrokePrimitive2D(const primitive2d::PolygonStrokePrimitive2D& rPolygonStrokePrimitive);
- void impRenderFillBitmapPrimitive2D(const primitive2d::FillBitmapPrimitive2D& rFillBitmapPrimitive2D);
- void impRenderUnifiedTransparencePrimitive2D(const primitive2d::UnifiedTransparencePrimitive2D& rUniTransparenceCandidate);
-
- public:
- canvasProcessor2D(
- const geometry::ViewInformation2D& rViewInformation,
- OutputDevice& rOutDev);
- virtual ~canvasProcessor2D();
-
- // access to Drawinglayer configuration options
- const SvtOptionsDrawinglayer& getOptionsDrawinglayer() const { return maDrawinglayerOpt; }
- };
- } // end of namespace processor2d
-} // end of namespace drawinglayer
-
-//////////////////////////////////////////////////////////////////////////////
-
-#endif //_DRAWINGLAYER_PROCESSOR_CANVASPROCESSOR_HXX
-
-// eof
diff --git a/drawinglayer/inc/drawinglayer/processor2d/vclprocessor2d.hxx b/drawinglayer/inc/drawinglayer/processor2d/vclprocessor2d.hxx
index 41fc262299e4..286995436b9a 100644
--- a/drawinglayer/inc/drawinglayer/processor2d/vclprocessor2d.hxx
+++ b/drawinglayer/inc/drawinglayer/processor2d/vclprocessor2d.hxx
@@ -38,9 +38,9 @@ namespace drawinglayer { namespace primitive2d {
class TextSimplePortionPrimitive2D;
class PolygonHairlinePrimitive2D;
class BitmapPrimitive2D;
- class FillBitmapPrimitive2D;
+ class FillGraphicPrimitive2D;
class PolyPolygonGradientPrimitive2D;
- class PolyPolygonBitmapPrimitive2D;
+ class PolyPolygonGraphicPrimitive2D;
class PolyPolygonColorPrimitive2D;
class MetafilePrimitive2D;
class MaskPrimitive2D;
@@ -96,9 +96,9 @@ namespace drawinglayer
void RenderTextSimpleOrDecoratedPortionPrimitive2D(const primitive2d::TextSimplePortionPrimitive2D& rTextCandidate);
void RenderPolygonHairlinePrimitive2D(const primitive2d::PolygonHairlinePrimitive2D& rPolygonCandidate, bool bPixelBased);
void RenderBitmapPrimitive2D(const primitive2d::BitmapPrimitive2D& rBitmapCandidate);
- void RenderFillBitmapPrimitive2D(const primitive2d::FillBitmapPrimitive2D& rFillBitmapCandidate);
+ void RenderFillGraphicPrimitive2D(const primitive2d::FillGraphicPrimitive2D& rFillBitmapCandidate);
void RenderPolyPolygonGradientPrimitive2D(const primitive2d::PolyPolygonGradientPrimitive2D& rPolygonCandidate);
- void RenderPolyPolygonBitmapPrimitive2D(const primitive2d::PolyPolygonBitmapPrimitive2D& rPolygonCandidate);
+ void RenderPolyPolygonGraphicPrimitive2D(const primitive2d::PolyPolygonGraphicPrimitive2D& rPolygonCandidate);
void RenderPolyPolygonColorPrimitive2D(const primitive2d::PolyPolygonColorPrimitive2D& rPolygonCandidate);
void RenderMetafilePrimitive2D(const primitive2d::MetafilePrimitive2D& rPolygonCandidate);
void RenderMaskPrimitive2DPixel(const primitive2d::MaskPrimitive2D& rMaskCandidate);
diff --git a/drawinglayer/inc/drawinglayer/texture/texture.hxx b/drawinglayer/inc/drawinglayer/texture/texture.hxx
index d5a4721f6112..aa62d1eb3d58 100644
--- a/drawinglayer/inc/drawinglayer/texture/texture.hxx
+++ b/drawinglayer/inc/drawinglayer/texture/texture.hxx
@@ -309,16 +309,27 @@ namespace drawinglayer
{
namespace texture
{
+ // This class applies a tiling to the unit range. The given range
+ // will be repeated inside the unit range in X and Y and for each
+ // tile a matrix will be created (by appendTransformations) that
+ // represents the needed transformation to map a filling in unit
+ // coordinates to that tile.
+ // When offsetX is given, every 2nd line will be ofsetted by the
+ // given percentage value (offsetX has to be 0.0 <= offsetX <= 1.0).
+ // Accordingly to offsetY. If both are given, offsetX is preferred
+ // and offsetY is ignored.
class DRAWINGLAYER_DLLPUBLIC GeoTexSvxTiled : public GeoTexSvx
{
protected:
- basegfx::B2DPoint maTopLeft;
- basegfx::B2DVector maSize;
+ basegfx::B2DRange maRange;
+ double mfOffsetX;
+ double mfOffsetY;
public:
GeoTexSvxTiled(
- const basegfx::B2DPoint& rTopLeft,
- const basegfx::B2DVector& rSize);
+ const basegfx::B2DRange& rRange,
+ double fOffsetX = 0.0,
+ double fOffsetY = 0.0);
virtual ~GeoTexSvxTiled();
// compare operator
diff --git a/drawinglayer/inc/drawinglayer/texture/texture3d.hxx b/drawinglayer/inc/drawinglayer/texture/texture3d.hxx
index bda0b17b4c77..33173fc2cf43 100644
--- a/drawinglayer/inc/drawinglayer/texture/texture3d.hxx
+++ b/drawinglayer/inc/drawinglayer/texture/texture3d.hxx
@@ -26,7 +26,7 @@
#include <drawinglayer/drawinglayerdllapi.h>
#include <drawinglayer/texture/texture.hxx>
-#include <vcl/bitmap.hxx>
+#include <vcl/bitmapex.hxx>
//////////////////////////////////////////////////////////////////////////////
// predeclarations
@@ -48,7 +48,9 @@ namespace drawinglayer
double mfOpacity;
public:
- GeoTexSvxMono(const basegfx::BColor& rSingleColor, double fOpacity);
+ GeoTexSvxMono(
+ const basegfx::BColor& rSingleColor,
+ double fOpacity);
// compare operator
virtual bool operator==(const GeoTexSvx& rGeoTexSvx) const;
@@ -64,22 +66,32 @@ namespace drawinglayer
{
namespace texture
{
- class DRAWINGLAYER_DLLPUBLIC GeoTexSvxBitmap : public GeoTexSvx
+ class DRAWINGLAYER_DLLPUBLIC GeoTexSvxBitmapEx : public GeoTexSvx
{
protected:
- Bitmap maBitmap;
- BitmapReadAccess* mpRead;
+ BitmapEx maBitmapEx;
+ BitmapReadAccess* mpReadBitmap;
+ Bitmap maTransparence;
+ BitmapReadAccess* mpReadTransparence;
basegfx::B2DPoint maTopLeft;
basegfx::B2DVector maSize;
double mfMulX;
double mfMulY;
+ /// bitfield
+ bool mbIsAlpha : 1;
+ bool mbIsTransparent : 1;
+
// helpers
bool impIsValid(const basegfx::B2DPoint& rUV, sal_Int32& rX, sal_Int32& rY) const;
+ sal_uInt8 impGetTransparence(sal_Int32& rX, sal_Int32& rY) const;
public:
- GeoTexSvxBitmap(const Bitmap& rBitmap, const basegfx::B2DPoint& rTopLeft, const basegfx::B2DVector& rSize);
- virtual ~GeoTexSvxBitmap();
+ GeoTexSvxBitmapEx(
+ const BitmapEx& rBitmapEx,
+ const basegfx::B2DRange& rRange);
+ virtual ~GeoTexSvxBitmapEx();
+
virtual void modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& rfOpacity) const;
virtual void modifyOpacity(const basegfx::B2DPoint& rUV, double& rfOpacity) const;
};
@@ -92,30 +104,26 @@ namespace drawinglayer
{
namespace texture
{
- class DRAWINGLAYER_DLLPUBLIC GeoTexSvxBitmapTiled : public GeoTexSvxBitmap
+ class DRAWINGLAYER_DLLPUBLIC GeoTexSvxBitmapExTiled : public GeoTexSvxBitmapEx
{
protected:
- // helpers
- basegfx::B2DPoint impGetCorrected(const basegfx::B2DPoint& rUV) const
- {
- double fX(fmod(rUV.getX() - maTopLeft.getX(), maSize.getX()));
- double fY(fmod(rUV.getY() - maTopLeft.getY(), maSize.getY()));
+ double mfOffsetX;
+ double mfOffsetY;
- if(fX < 0.0)
- {
- fX += maSize.getX();
- }
+ /// bitfield
+ bool mbUseOffsetX : 1;
+ bool mbUseOffsetY : 1;
- if(fY < 0.0)
- {
- fY += maSize.getY();
- }
-
- return basegfx::B2DPoint(fX + maTopLeft.getX(), fY + maTopLeft.getY());
- }
+ // helpers
+ basegfx::B2DPoint impGetCorrected(const basegfx::B2DPoint& rUV) const;
public:
- GeoTexSvxBitmapTiled(const Bitmap& rBitmap, const basegfx::B2DPoint& rTopLeft, const basegfx::B2DVector& rSize);
+ GeoTexSvxBitmapExTiled(
+ const BitmapEx& rBitmapEx,
+ const basegfx::B2DRange& rRange,
+ double fOffsetX = 0.0,
+ double fOffsetY = 0.0);
+
virtual void modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& rfOpacity) const;
virtual void modifyOpacity(const basegfx::B2DPoint& rUV, double& rfOpacity) const;
};
diff --git a/drawinglayer/source/attribute/fillbitmapattribute.cxx b/drawinglayer/source/attribute/fillbitmapattribute.cxx
deleted file mode 100644
index d0a42828518b..000000000000
--- a/drawinglayer/source/attribute/fillbitmapattribute.cxx
+++ /dev/null
@@ -1,195 +0,0 @@
-/**************************************************************
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- *************************************************************/
-
-
-
-// MARKER(update_precomp.py): autogen include statement, do not remove
-#include "precompiled_drawinglayer.hxx"
-
-#include <drawinglayer/attribute/fillbitmapattribute.hxx>
-#include <vcl/bitmapex.hxx>
-
-//////////////////////////////////////////////////////////////////////////////
-
-namespace drawinglayer
-{
- namespace attribute
- {
- class ImpFillBitmapAttribute
- {
- public:
- // refcounter
- sal_uInt32 mnRefCount;
-
- // data definitions
- BitmapEx maBitmapEx;
- basegfx::B2DPoint maTopLeft;
- basegfx::B2DVector maSize;
-
- // bitfield
- unsigned mbTiling : 1;
-
- ImpFillBitmapAttribute(
- const BitmapEx& rBitmapEx,
- const basegfx::B2DPoint& rTopLeft,
- const basegfx::B2DVector& rSize,
- bool bTiling)
- : mnRefCount(0),
- maBitmapEx(rBitmapEx),
- maTopLeft(rTopLeft),
- maSize(rSize),
- mbTiling(bTiling)
- {
- }
-
- bool operator==(const ImpFillBitmapAttribute& rCandidate) const
- {
- return (maBitmapEx == rCandidate.maBitmapEx
- && maTopLeft == rCandidate.maTopLeft
- && maSize == rCandidate.maSize
- && mbTiling == rCandidate.mbTiling);
- }
-
- // data read access
- const BitmapEx& getBitmapEx() const { return maBitmapEx; }
- const basegfx::B2DPoint& getTopLeft() const { return maTopLeft; }
- const basegfx::B2DVector& getSize() const { return maSize; }
- bool getTiling() const { return mbTiling; }
-
- static ImpFillBitmapAttribute* get_global_default()
- {
- static ImpFillBitmapAttribute* pDefault = 0;
-
- if(!pDefault)
- {
- pDefault = new ImpFillBitmapAttribute(
- BitmapEx(),
- basegfx::B2DPoint(),
- basegfx::B2DVector(),
- false);
-
- // never delete; start with RefCount 1, not 0
- pDefault->mnRefCount++;
- }
-
- return pDefault;
- }
- };
-
- FillBitmapAttribute::FillBitmapAttribute(
- const BitmapEx& rBitmapEx,
- const basegfx::B2DPoint& rTopLeft,
- const basegfx::B2DVector& rSize,
- bool bTiling)
- : mpFillBitmapAttribute(new ImpFillBitmapAttribute(
- rBitmapEx, rTopLeft, rSize, bTiling))
- {
- }
-
- FillBitmapAttribute::FillBitmapAttribute()
- : mpFillBitmapAttribute(ImpFillBitmapAttribute::get_global_default())
- {
- mpFillBitmapAttribute->mnRefCount++;
- }
-
- FillBitmapAttribute::FillBitmapAttribute(const FillBitmapAttribute& rCandidate)
- : mpFillBitmapAttribute(rCandidate.mpFillBitmapAttribute)
- {
- mpFillBitmapAttribute->mnRefCount++;
- }
-
- FillBitmapAttribute::~FillBitmapAttribute()
- {
- if(mpFillBitmapAttribute->mnRefCount)
- {
- mpFillBitmapAttribute->mnRefCount--;
- }
- else
- {
- delete mpFillBitmapAttribute;
- }
- }
-
- bool FillBitmapAttribute::isDefault() const
- {
- return mpFillBitmapAttribute == ImpFillBitmapAttribute::get_global_default();
- }
-
- FillBitmapAttribute& FillBitmapAttribute::operator=(const FillBitmapAttribute& rCandidate)
- {
- if(rCandidate.mpFillBitmapAttribute != mpFillBitmapAttribute)
- {
- if(mpFillBitmapAttribute->mnRefCount)
- {
- mpFillBitmapAttribute->mnRefCount--;
- }
- else
- {
- delete mpFillBitmapAttribute;
- }
-
- mpFillBitmapAttribute = rCandidate.mpFillBitmapAttribute;
- mpFillBitmapAttribute->mnRefCount++;
- }
-
- return *this;
- }
-
- bool FillBitmapAttribute::operator==(const FillBitmapAttribute& rCandidate) const
- {
- if(rCandidate.mpFillBitmapAttribute == mpFillBitmapAttribute)
- {
- return true;
- }
-
- if(rCandidate.isDefault() != isDefault())
- {
- return false;
- }
-
- return (*rCandidate.mpFillBitmapAttribute == *mpFillBitmapAttribute);
- }
-
- const BitmapEx& FillBitmapAttribute::getBitmapEx() const
- {
- return mpFillBitmapAttribute->getBitmapEx();
- }
-
- const basegfx::B2DPoint& FillBitmapAttribute::getTopLeft() const
- {
- return mpFillBitmapAttribute->getTopLeft();
- }
-
- const basegfx::B2DVector& FillBitmapAttribute::getSize() const
- {
- return mpFillBitmapAttribute->getSize();
- }
-
- bool FillBitmapAttribute::getTiling() const
- {
- return mpFillBitmapAttribute->getTiling();
- }
-
- } // end of namespace attribute
-} // end of namespace drawinglayer
-
-//////////////////////////////////////////////////////////////////////////////
-// eof
diff --git a/drawinglayer/source/attribute/fillgraphicattribute.cxx b/drawinglayer/source/attribute/fillgraphicattribute.cxx
new file mode 100755
index 000000000000..366947652517
--- /dev/null
+++ b/drawinglayer/source/attribute/fillgraphicattribute.cxx
@@ -0,0 +1,215 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/attribute/fillgraphicattribute.hxx>
+#include <vcl/graph.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace attribute
+ {
+ class ImpFillGraphicAttribute
+ {
+ public:
+ // refcounter
+ sal_uInt32 mnRefCount;
+
+ // data definitions
+ Graphic maGraphic;
+ basegfx::B2DRange maGraphicRange;
+
+ // tiling definitions, offsets in X/Y in percent for each 2nd row.
+ // If both are set, Y is ignored (X has precedence)
+ double mfOffsetX;
+ double mfOffsetY;
+
+ // bitfield
+ unsigned mbTiling : 1;
+
+ ImpFillGraphicAttribute(
+ const Graphic& rGraphic,
+ const basegfx::B2DRange& rGraphicRange,
+ bool bTiling,
+ double fOffsetX,
+ double fOffsetY)
+ : mnRefCount(0),
+ maGraphic(rGraphic),
+ maGraphicRange(rGraphicRange),
+ mbTiling(bTiling),
+ mfOffsetX(fOffsetX),
+ mfOffsetY(fOffsetY)
+ {
+ }
+
+ // data read access
+ const Graphic& getGraphic() const { return maGraphic; }
+ const basegfx::B2DRange& getGraphicRange() const { return maGraphicRange; }
+ bool getTiling() const { return mbTiling; }
+ double getOffsetX() const { return mfOffsetX; }
+ double getOffsetY() const { return mfOffsetY; }
+
+ bool operator==(const ImpFillGraphicAttribute& rCandidate) const
+ {
+ return (getGraphic() == rCandidate.getGraphic()
+ && getGraphicRange() == rCandidate.getGraphicRange()
+ && getTiling() == rCandidate.getTiling()
+ && getOffsetX() == rCandidate.getOffsetX()
+ && getOffsetY() == rCandidate.getOffsetY());
+ }
+
+ static ImpFillGraphicAttribute* get_global_default()
+ {
+ static ImpFillGraphicAttribute* pDefault = 0;
+
+ if(!pDefault)
+ {
+ pDefault = new ImpFillGraphicAttribute(
+ Graphic(),
+ basegfx::B2DRange(),
+ false,
+ 0.0,
+ 0.0);
+
+ // never delete; start with RefCount 1, not 0
+ pDefault->mnRefCount++;
+ }
+
+ return pDefault;
+ }
+ };
+
+ FillGraphicAttribute::FillGraphicAttribute(
+ const Graphic& rGraphic,
+ const basegfx::B2DRange& rGraphicRange,
+ bool bTiling,
+ double fOffsetX,
+ double fOffsetY)
+ : mpFillGraphicAttribute(
+ new ImpFillGraphicAttribute(
+ rGraphic,
+ rGraphicRange,
+ bTiling,
+ basegfx::clamp(fOffsetX, 0.0, 1.0),
+ basegfx::clamp(fOffsetY, 0.0, 1.0)))
+ {
+ }
+
+ FillGraphicAttribute::FillGraphicAttribute()
+ : mpFillGraphicAttribute(ImpFillGraphicAttribute::get_global_default())
+ {
+ mpFillGraphicAttribute->mnRefCount++;
+ }
+
+ FillGraphicAttribute::FillGraphicAttribute(const FillGraphicAttribute& rCandidate)
+ : mpFillGraphicAttribute(rCandidate.mpFillGraphicAttribute)
+ {
+ mpFillGraphicAttribute->mnRefCount++;
+ }
+
+ FillGraphicAttribute::~FillGraphicAttribute()
+ {
+ if(mpFillGraphicAttribute->mnRefCount)
+ {
+ mpFillGraphicAttribute->mnRefCount--;
+ }
+ else
+ {
+ delete mpFillGraphicAttribute;
+ }
+ }
+
+ bool FillGraphicAttribute::isDefault() const
+ {
+ return mpFillGraphicAttribute == ImpFillGraphicAttribute::get_global_default();
+ }
+
+ FillGraphicAttribute& FillGraphicAttribute::operator=(const FillGraphicAttribute& rCandidate)
+ {
+ if(rCandidate.mpFillGraphicAttribute != mpFillGraphicAttribute)
+ {
+ if(mpFillGraphicAttribute->mnRefCount)
+ {
+ mpFillGraphicAttribute->mnRefCount--;
+ }
+ else
+ {
+ delete mpFillGraphicAttribute;
+ }
+
+ mpFillGraphicAttribute = rCandidate.mpFillGraphicAttribute;
+ mpFillGraphicAttribute->mnRefCount++;
+ }
+
+ return *this;
+ }
+
+ bool FillGraphicAttribute::operator==(const FillGraphicAttribute& rCandidate) const
+ {
+ if(rCandidate.mpFillGraphicAttribute == mpFillGraphicAttribute)
+ {
+ return true;
+ }
+
+ if(rCandidate.isDefault() != isDefault())
+ {
+ return false;
+ }
+
+ return (*rCandidate.mpFillGraphicAttribute == *mpFillGraphicAttribute);
+ }
+
+ const Graphic& FillGraphicAttribute::getGraphic() const
+ {
+ return mpFillGraphicAttribute->getGraphic();
+ }
+
+ const basegfx::B2DRange& FillGraphicAttribute::getGraphicRange() const
+ {
+ return mpFillGraphicAttribute->getGraphicRange();
+ }
+
+ bool FillGraphicAttribute::getTiling() const
+ {
+ return mpFillGraphicAttribute->getTiling();
+ }
+
+ double FillGraphicAttribute::getOffsetX() const
+ {
+ return mpFillGraphicAttribute->getOffsetX();
+ }
+
+ double FillGraphicAttribute::getOffsetY() const
+ {
+ return mpFillGraphicAttribute->getOffsetY();
+ }
+
+ } // end of namespace attribute
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/attribute/sdrfillattribute.cxx b/drawinglayer/source/attribute/sdrfillattribute.cxx
index 0de0bd913da9..61d3209e9600 100644
--- a/drawinglayer/source/attribute/sdrfillattribute.cxx
+++ b/drawinglayer/source/attribute/sdrfillattribute.cxx
@@ -24,7 +24,7 @@
#include <drawinglayer/attribute/sdrfillattribute.hxx>
#include <basegfx/color/bcolor.hxx>
-#include <drawinglayer/attribute/sdrfillbitmapattribute.hxx>
+#include <drawinglayer/attribute/sdrfillgraphicattribute.hxx>
#include <drawinglayer/attribute/fillhatchattribute.hxx>
#include <drawinglayer/attribute/fillgradientattribute.hxx>
@@ -45,7 +45,7 @@ namespace drawinglayer
basegfx::BColor maColor; // fill color
FillGradientAttribute maGradient; // fill gradient (if used)
FillHatchAttribute maHatch; // fill hatch (if used)
- SdrFillBitmapAttribute maBitmap; // fill bitmap (if used)
+ SdrFillGraphicAttribute maFillGraphic; // fill graphic (if used)
public:
ImpSdrFillAttribute(
@@ -53,13 +53,13 @@ namespace drawinglayer
const basegfx::BColor& rColor,
const FillGradientAttribute& rGradient,
const FillHatchAttribute& rHatch,
- const SdrFillBitmapAttribute& rBitmap)
+ const SdrFillGraphicAttribute& rFillGraphic)
: mnRefCount(0),
mfTransparence(fTransparence),
maColor(rColor),
maGradient(rGradient),
maHatch(rHatch),
- maBitmap(rBitmap)
+ maFillGraphic(rFillGraphic)
{
}
@@ -68,7 +68,7 @@ namespace drawinglayer
const basegfx::BColor& getColor() const { return maColor; }
const FillGradientAttribute& getGradient() const { return maGradient; }
const FillHatchAttribute& getHatch() const { return maHatch; }
- const SdrFillBitmapAttribute& getBitmap() const { return maBitmap; }
+ const SdrFillGraphicAttribute& getFillGraphic() const { return maFillGraphic; }
// compare operator
bool operator==(const ImpSdrFillAttribute& rCandidate) const
@@ -77,7 +77,7 @@ namespace drawinglayer
&& getColor() == rCandidate.getColor()
&& getGradient() == rCandidate.getGradient()
&& getHatch() == rCandidate.getHatch()
- && getBitmap() == rCandidate.getBitmap());
+ && getFillGraphic() == rCandidate.getFillGraphic());
}
static ImpSdrFillAttribute* get_global_default()
@@ -91,7 +91,7 @@ namespace drawinglayer
basegfx::BColor(),
FillGradientAttribute(),
FillHatchAttribute(),
- SdrFillBitmapAttribute());
+ SdrFillGraphicAttribute());
// never delete; start with RefCount 1, not 0
pDefault->mnRefCount++;
@@ -106,9 +106,10 @@ namespace drawinglayer
const basegfx::BColor& rColor,
const FillGradientAttribute& rGradient,
const FillHatchAttribute& rHatch,
- const SdrFillBitmapAttribute& rBitmap)
- : mpSdrFillAttribute(new ImpSdrFillAttribute(
- fTransparence, rColor, rGradient, rHatch, rBitmap))
+ const SdrFillGraphicAttribute& rFillGraphic)
+ : mpSdrFillAttribute(
+ new ImpSdrFillAttribute(
+ fTransparence, rColor, rGradient, rHatch, rFillGraphic))
{
}
@@ -196,9 +197,9 @@ namespace drawinglayer
return mpSdrFillAttribute->getHatch();
}
- const SdrFillBitmapAttribute& SdrFillAttribute::getBitmap() const
+ const SdrFillGraphicAttribute& SdrFillAttribute::getFillGraphic() const
{
- return mpSdrFillAttribute->getBitmap();
+ return mpSdrFillAttribute->getFillGraphic();
}
} // end of namespace attribute
} // end of namespace drawinglayer
diff --git a/drawinglayer/source/attribute/sdrfillbitmapattribute.cxx b/drawinglayer/source/attribute/sdrfillgraphicattribute.cxx
index f122c7c9c5b5..77fa080158ee 100644..100755
--- a/drawinglayer/source/attribute/sdrfillbitmapattribute.cxx
+++ b/drawinglayer/source/attribute/sdrfillgraphicattribute.cxx
@@ -24,9 +24,9 @@
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_drawinglayer.hxx"
-#include <drawinglayer/attribute/sdrfillbitmapattribute.hxx>
-#include <drawinglayer/attribute/fillbitmapattribute.hxx>
-#include <vcl/bitmapex.hxx>
+#include <drawinglayer/attribute/sdrfillgraphicattribute.hxx>
+#include <drawinglayer/attribute/fillgraphicattribute.hxx>
+#include <vcl/graph.hxx>
//////////////////////////////////////////////////////////////////////////////
@@ -34,14 +34,14 @@ namespace drawinglayer
{
namespace attribute
{
- class ImpSdrFillBitmapAttribute
+ class ImpSdrFillGraphicAttribute
{
public:
// refcounter
sal_uInt32 mnRefCount;
// data definitions
- BitmapEx maBitmapEx;
+ Graphic maFillGraphic;
basegfx::B2DVector maSize;
basegfx::B2DVector maOffset;
basegfx::B2DVector maOffsetPosition;
@@ -52,8 +52,8 @@ namespace drawinglayer
unsigned mbStretch : 1;
unsigned mbLogSize : 1;
- ImpSdrFillBitmapAttribute(
- const BitmapEx& rBitmapEx,
+ ImpSdrFillGraphicAttribute(
+ const Graphic& rFillGraphic,
const basegfx::B2DVector& rSize,
const basegfx::B2DVector& rOffset,
const basegfx::B2DVector& rOffsetPosition,
@@ -62,7 +62,7 @@ namespace drawinglayer
bool bStretch,
bool bLogSize)
: mnRefCount(0),
- maBitmapEx(rBitmapEx),
+ maFillGraphic(rFillGraphic),
maSize(rSize),
maOffset(rOffset),
maOffsetPosition(rOffsetPosition),
@@ -74,7 +74,7 @@ namespace drawinglayer
}
// data read access
- const BitmapEx& getBitmapEx() const { return maBitmapEx; }
+ const Graphic& getFillGraphic() const { return maFillGraphic; }
const basegfx::B2DVector& getSize() const { return maSize; }
const basegfx::B2DVector& getOffset() const { return maOffset; }
const basegfx::B2DVector& getOffsetPosition() const { return maOffsetPosition; }
@@ -83,9 +83,9 @@ namespace drawinglayer
bool getStretch() const { return mbStretch; }
bool getLogSize() const { return mbLogSize; }
- bool operator==(const ImpSdrFillBitmapAttribute& rCandidate) const
+ bool operator==(const ImpSdrFillGraphicAttribute& rCandidate) const
{
- return (getBitmapEx() == rCandidate.getBitmapEx()
+ return (getFillGraphic() == rCandidate.getFillGraphic()
&& getSize() == rCandidate.getSize()
&& getOffset() == rCandidate.getOffset()
&& getOffsetPosition() == rCandidate.getOffsetPosition()
@@ -95,14 +95,14 @@ namespace drawinglayer
&& getLogSize() == rCandidate.getLogSize());
}
- static ImpSdrFillBitmapAttribute* get_global_default()
+ static ImpSdrFillGraphicAttribute* get_global_default()
{
- static ImpSdrFillBitmapAttribute* pDefault = 0;
+ static ImpSdrFillGraphicAttribute* pDefault = 0;
if(!pDefault)
{
- pDefault = new ImpSdrFillBitmapAttribute(
- BitmapEx(),
+ pDefault = new ImpSdrFillGraphicAttribute(
+ Graphic(),
basegfx::B2DVector(),
basegfx::B2DVector(),
basegfx::B2DVector(),
@@ -119,8 +119,8 @@ namespace drawinglayer
}
};
- SdrFillBitmapAttribute::SdrFillBitmapAttribute(
- const BitmapEx& rBitmapEx,
+ SdrFillGraphicAttribute::SdrFillGraphicAttribute(
+ const Graphic& rFillGraphic,
const basegfx::B2DVector& rSize,
const basegfx::B2DVector& rOffset,
const basegfx::B2DVector& rOffsetPosition,
@@ -128,9 +128,9 @@ namespace drawinglayer
bool bTiling,
bool bStretch,
bool bLogSize)
- : mpSdrFillBitmapAttribute(
- new ImpSdrFillBitmapAttribute(
- rBitmapEx,
+ : mpSdrFillGraphicAttribute(
+ new ImpSdrFillGraphicAttribute(
+ rFillGraphic,
rSize,
rOffset,
rOffsetPosition,
@@ -141,58 +141,58 @@ namespace drawinglayer
{
}
- SdrFillBitmapAttribute::SdrFillBitmapAttribute()
- : mpSdrFillBitmapAttribute(ImpSdrFillBitmapAttribute::get_global_default())
+ SdrFillGraphicAttribute::SdrFillGraphicAttribute()
+ : mpSdrFillGraphicAttribute(ImpSdrFillGraphicAttribute::get_global_default())
{
- mpSdrFillBitmapAttribute->mnRefCount++;
+ mpSdrFillGraphicAttribute->mnRefCount++;
}
- SdrFillBitmapAttribute::SdrFillBitmapAttribute(const SdrFillBitmapAttribute& rCandidate)
- : mpSdrFillBitmapAttribute(rCandidate.mpSdrFillBitmapAttribute)
+ SdrFillGraphicAttribute::SdrFillGraphicAttribute(const SdrFillGraphicAttribute& rCandidate)
+ : mpSdrFillGraphicAttribute(rCandidate.mpSdrFillGraphicAttribute)
{
- mpSdrFillBitmapAttribute->mnRefCount++;
+ mpSdrFillGraphicAttribute->mnRefCount++;
}
- SdrFillBitmapAttribute::~SdrFillBitmapAttribute()
+ SdrFillGraphicAttribute::~SdrFillGraphicAttribute()
{
- if(mpSdrFillBitmapAttribute->mnRefCount)
+ if(mpSdrFillGraphicAttribute->mnRefCount)
{
- mpSdrFillBitmapAttribute->mnRefCount--;
+ mpSdrFillGraphicAttribute->mnRefCount--;
}
else
{
- delete mpSdrFillBitmapAttribute;
+ delete mpSdrFillGraphicAttribute;
}
}
- bool SdrFillBitmapAttribute::isDefault() const
+ bool SdrFillGraphicAttribute::isDefault() const
{
- return mpSdrFillBitmapAttribute == ImpSdrFillBitmapAttribute::get_global_default();
+ return mpSdrFillGraphicAttribute == ImpSdrFillGraphicAttribute::get_global_default();
}
- SdrFillBitmapAttribute& SdrFillBitmapAttribute::operator=(const SdrFillBitmapAttribute& rCandidate)
+ SdrFillGraphicAttribute& SdrFillGraphicAttribute::operator=(const SdrFillGraphicAttribute& rCandidate)
{
- if(rCandidate.mpSdrFillBitmapAttribute != mpSdrFillBitmapAttribute)
+ if(rCandidate.mpSdrFillGraphicAttribute != mpSdrFillGraphicAttribute)
{
- if(mpSdrFillBitmapAttribute->mnRefCount)
+ if(mpSdrFillGraphicAttribute->mnRefCount)
{
- mpSdrFillBitmapAttribute->mnRefCount--;
+ mpSdrFillGraphicAttribute->mnRefCount--;
}
else
{
- delete mpSdrFillBitmapAttribute;
+ delete mpSdrFillGraphicAttribute;
}
- mpSdrFillBitmapAttribute = rCandidate.mpSdrFillBitmapAttribute;
- mpSdrFillBitmapAttribute->mnRefCount++;
+ mpSdrFillGraphicAttribute = rCandidate.mpSdrFillGraphicAttribute;
+ mpSdrFillGraphicAttribute->mnRefCount++;
}
return *this;
}
- bool SdrFillBitmapAttribute::operator==(const SdrFillBitmapAttribute& rCandidate) const
+ bool SdrFillGraphicAttribute::operator==(const SdrFillGraphicAttribute& rCandidate) const
{
- if(rCandidate.mpSdrFillBitmapAttribute == mpSdrFillBitmapAttribute)
+ if(rCandidate.mpSdrFillGraphicAttribute == mpSdrFillGraphicAttribute)
{
return true;
}
@@ -202,112 +202,60 @@ namespace drawinglayer
return false;
}
- return (*rCandidate.mpSdrFillBitmapAttribute == *mpSdrFillBitmapAttribute);
+ return (*rCandidate.mpSdrFillGraphicAttribute == *mpSdrFillGraphicAttribute);
}
- const BitmapEx& SdrFillBitmapAttribute::getBitmapEx() const
+ const Graphic& SdrFillGraphicAttribute::getFillGraphic() const
{
- return mpSdrFillBitmapAttribute->getBitmapEx();
+ return mpSdrFillGraphicAttribute->getFillGraphic();
}
- const basegfx::B2DVector& SdrFillBitmapAttribute::getSize() const
+ const basegfx::B2DVector& SdrFillGraphicAttribute::getSize() const
{
- return mpSdrFillBitmapAttribute->getSize();
+ return mpSdrFillGraphicAttribute->getSize();
}
- const basegfx::B2DVector& SdrFillBitmapAttribute::getOffset() const
+ const basegfx::B2DVector& SdrFillGraphicAttribute::getOffset() const
{
- return mpSdrFillBitmapAttribute->getOffset();
+ return mpSdrFillGraphicAttribute->getOffset();
}
- const basegfx::B2DVector& SdrFillBitmapAttribute::getOffsetPosition() const
+ const basegfx::B2DVector& SdrFillGraphicAttribute::getOffsetPosition() const
{
- return mpSdrFillBitmapAttribute->getOffsetPosition();
+ return mpSdrFillGraphicAttribute->getOffsetPosition();
}
- const basegfx::B2DVector& SdrFillBitmapAttribute::getRectPoint() const
+ const basegfx::B2DVector& SdrFillGraphicAttribute::getRectPoint() const
{
- return mpSdrFillBitmapAttribute->getRectPoint();
+ return mpSdrFillGraphicAttribute->getRectPoint();
}
- bool SdrFillBitmapAttribute::getTiling() const
+ bool SdrFillGraphicAttribute::getTiling() const
{
- return mpSdrFillBitmapAttribute->getTiling();
+ return mpSdrFillGraphicAttribute->getTiling();
}
- bool SdrFillBitmapAttribute::getStretch() const
+ bool SdrFillGraphicAttribute::getStretch() const
{
- return mpSdrFillBitmapAttribute->getStretch();
+ return mpSdrFillGraphicAttribute->getStretch();
}
- bool SdrFillBitmapAttribute::getLogSize() const
+ bool SdrFillGraphicAttribute::getLogSize() const
{
- return mpSdrFillBitmapAttribute->getLogSize();
+ return mpSdrFillGraphicAttribute->getLogSize();
}
- FillBitmapAttribute SdrFillBitmapAttribute::getFillBitmapAttribute(const basegfx::B2DRange& rRange) const
+ FillGraphicAttribute SdrFillGraphicAttribute::createFillGraphicAttribute(const basegfx::B2DRange& rRange) const
{
// get logical size of bitmap (before expanding eventually)
- BitmapEx aBitmapEx(getBitmapEx());
- const basegfx::B2DVector aLogicalSize(aBitmapEx.GetPrefSize().getWidth(), aBitmapEx.GetPrefSize().getHeight());
-
- // get hor/ver shiftings and apply them eventually to the bitmap, but only
- // when tiling is on
- bool bExpandWidth(false);
- bool bExpandHeight(false);
-
- if(getTiling())
- {
- if(0.0 != getOffset().getX() || 0.0 != getOffset().getY())
- {
- const sal_uInt32 nWidth(aBitmapEx.GetSizePixel().getWidth());
- const sal_uInt32 nHeight(aBitmapEx.GetSizePixel().getHeight());
-
- if(0.0 != getOffset().getX())
- {
- bExpandHeight = true;
- const sal_uInt32 nOffset(basegfx::fround(((double)nWidth * getOffset().getX()) / 100.0));
- aBitmapEx.Expand(0L, nHeight);
-
- const Size aSizeA(nOffset, nHeight);
- const Rectangle aDstA(Point(0L, nHeight), aSizeA);
- const Rectangle aSrcA(Point(nWidth - nOffset, 0L), aSizeA);
- aBitmapEx.CopyPixel(aDstA, aSrcA);
-
- const Size aSizeB(nWidth - nOffset, nHeight);
- const Rectangle aDstB(Point(nOffset, nHeight), aSizeB);
- const Rectangle aSrcB(Point(0L, 0L), aSizeB);
- aBitmapEx.CopyPixel(aDstB, aSrcB);
- }
- else
- {
- bExpandWidth = true;
- const sal_uInt32 nOffset(basegfx::fround(((double)nHeight * getOffset().getY()) / 100.0));
- aBitmapEx.Expand(nWidth, 0L);
-
- const Size aSize(nWidth, nHeight);
- const Rectangle aDst(Point(nWidth, 0L), aSize);
- const Rectangle aSrc(Point(0L, 0L), aSize);
- aBitmapEx.CopyPixel(aDst, aSrc);
-
- const Size aSizeA(nWidth, nOffset);
- const Rectangle aDstA(Point(0L, 0L), aSizeA);
- const Rectangle aSrcA(Point(nWidth, nHeight - nOffset), aSizeA);
- aBitmapEx.CopyPixel(aDstA, aSrcA);
-
- const Size aSizeB(nWidth, nHeight - nOffset);
- const Rectangle aDstB(Point(0L, nOffset), aSizeB);
- const Rectangle aSrcB(Point(nWidth, 0L), aSizeB);
- aBitmapEx.CopyPixel(aDstB, aSrcB);
- }
- }
- }
+ Graphic aGraphic(getFillGraphic());
+ const basegfx::B2DVector aLogicalSize(aGraphic.GetPrefSize().getWidth(), aGraphic.GetPrefSize().getHeight());
// init values with defaults
basegfx::B2DPoint aBitmapSize(1.0, 1.0);
basegfx::B2DVector aBitmapTopLeft(0.0, 0.0);
- // are canges needed?
+ // are changes needed?
if(getTiling() || !getStretch())
{
// init values with range sizes
@@ -381,17 +329,6 @@ namespace drawinglayer
aBitmapTopLeft.setY(aBitmapTopLeft.getY() + (aBitmapSize.getY() * (getOffsetPosition().getY() * 0.01)));
}
- // apply expand
- if(bExpandWidth)
- {
- aBitmapSize.setX(aBitmapSize.getX() * 2.0);
- }
-
- if(bExpandHeight)
- {
- aBitmapSize.setY(aBitmapSize.getY() * 2.0);
- }
-
// apply bitmap size scaling to unit rectangle
aBitmapTopLeft.setX(aBitmapTopLeft.getX() / fRangeWidth);
aBitmapTopLeft.setY(aBitmapTopLeft.getY() / fRangeHeight);
@@ -399,7 +336,17 @@ namespace drawinglayer
aBitmapSize.setY(aBitmapSize.getY() / fRangeHeight);
}
- return FillBitmapAttribute(aBitmapEx, aBitmapTopLeft, aBitmapSize, getTiling());
+ // get offset in percent
+ const double fOffsetX(basegfx::clamp(getOffset().getX() * 0.01, 0.0, 1.0));
+ const double fOffsetY(basegfx::clamp(getOffset().getY() * 0.01, 0.0, 1.0));
+
+ // create FillGraphicAttribute
+ return FillGraphicAttribute(
+ aGraphic,
+ basegfx::B2DRange(aBitmapTopLeft, aBitmapTopLeft + aBitmapSize),
+ getTiling(),
+ fOffsetX,
+ fOffsetY);
}
} // end of namespace attribute
} // end of namespace drawinglayer
diff --git a/drawinglayer/source/primitive2d/fillbitmapprimitive2d.cxx b/drawinglayer/source/primitive2d/fillbitmapprimitive2d.cxx
deleted file mode 100644
index 58fcc361ecd8..000000000000
--- a/drawinglayer/source/primitive2d/fillbitmapprimitive2d.cxx
+++ /dev/null
@@ -1,138 +0,0 @@
-/**************************************************************
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- *************************************************************/
-
-
-
-// MARKER(update_precomp.py): autogen include statement, do not remove
-#include "precompiled_drawinglayer.hxx"
-
-#include <drawinglayer/primitive2d/fillbitmapprimitive2d.hxx>
-#include <drawinglayer/primitive2d/bitmapprimitive2d.hxx>
-#include <basegfx/polygon/b2dpolygon.hxx>
-#include <basegfx/polygon/b2dpolygontools.hxx>
-#include <drawinglayer/texture/texture.hxx>
-#include <basegfx/tools/canvastools.hxx>
-#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
-
-//////////////////////////////////////////////////////////////////////////////
-
-using namespace com::sun::star;
-
-//////////////////////////////////////////////////////////////////////////////
-
-namespace drawinglayer
-{
- namespace primitive2d
- {
- Primitive2DSequence FillBitmapPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
- {
- Primitive2DSequence aRetval;
-
- if(!getFillBitmap().isDefault())
- {
- const Size aTileSizePixel(getFillBitmap().getBitmapEx().GetSizePixel());
-
- // is there a tile with some size at all?
- if(aTileSizePixel.getWidth() && aTileSizePixel.getHeight())
- {
- if(getFillBitmap().getTiling())
- {
- // get object range and create tiling matrices
- ::std::vector< basegfx::B2DHomMatrix > aMatrices;
- texture::GeoTexSvxTiled aTiling(getFillBitmap().getTopLeft(), getFillBitmap().getSize());
- aTiling.appendTransformations(aMatrices);
-
- // resize result
- aRetval.realloc(aMatrices.size());
-
- // create one primitive for each matrix
- for(sal_uInt32 a(0L); a < aMatrices.size(); a++)
- {
- basegfx::B2DHomMatrix aNewMatrix = aMatrices[a];
- aNewMatrix *= getTransformation();
-
- // create bitmap primitive and add to result
- const Primitive2DReference xRef(
- new BitmapPrimitive2D(getFillBitmap().getBitmapEx(), aNewMatrix));
-
- aRetval[a] = xRef;
- }
- }
- else
- {
- // create new object transform
- basegfx::B2DHomMatrix aObjectTransform;
- aObjectTransform.set(0L, 0L, getFillBitmap().getSize().getX());
- aObjectTransform.set(1L, 1L, getFillBitmap().getSize().getY());
- aObjectTransform.set(0L, 2L, getFillBitmap().getTopLeft().getX());
- aObjectTransform.set(1L, 2L, getFillBitmap().getTopLeft().getY());
- aObjectTransform *= getTransformation();
-
- // create bitmap primitive and add exclusive to decomposition (hand over ownership)
- const Primitive2DReference xRef(
- new BitmapPrimitive2D(getFillBitmap().getBitmapEx(), aObjectTransform));
-
- aRetval = Primitive2DSequence(&xRef, 1L);
- }
- }
- }
-
- return aRetval;
- }
-
- FillBitmapPrimitive2D::FillBitmapPrimitive2D(
- const basegfx::B2DHomMatrix& rTransformation,
- const attribute::FillBitmapAttribute& rFillBitmap)
- : BufferedDecompositionPrimitive2D(),
- maTransformation(rTransformation),
- maFillBitmap(rFillBitmap)
- {
- }
-
- bool FillBitmapPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
- {
- if(BufferedDecompositionPrimitive2D::operator==(rPrimitive))
- {
- const FillBitmapPrimitive2D& rCompare = static_cast< const FillBitmapPrimitive2D& >(rPrimitive);
-
- return (getTransformation() == rCompare.getTransformation()
- && getFillBitmap() == rCompare.getFillBitmap());
- }
-
- return false;
- }
-
- basegfx::B2DRange FillBitmapPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
- {
- // return range of it
- basegfx::B2DPolygon aPolygon(basegfx::tools::createUnitPolygon());
- aPolygon.transform(getTransformation());
- return basegfx::tools::getRange(aPolygon);
- }
-
- // provide unique ID
- ImplPrimitrive2DIDBlock(FillBitmapPrimitive2D, PRIMITIVE2D_ID_FILLBITMAPPRIMITIVE2D)
-
- } // end of namespace primitive2d
-} // end of namespace drawinglayer
-
-//////////////////////////////////////////////////////////////////////////////
-// eof
diff --git a/drawinglayer/source/primitive2d/fillgraphicprimitive2d.cxx b/drawinglayer/source/primitive2d/fillgraphicprimitive2d.cxx
new file mode 100644
index 000000000000..5da9d85dc4a1
--- /dev/null
+++ b/drawinglayer/source/primitive2d/fillgraphicprimitive2d.cxx
@@ -0,0 +1,147 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/primitive2d/fillgraphicprimitive2d.hxx>
+#include <drawinglayer/primitive2d/graphicprimitive2d.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <drawinglayer/texture/texture.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+#include <drawinglayer/primitive2d/bitmapprimitive2d.hxx>
+#include <drawinglayer/primitive2d/metafileprimitive2d.hxx>
+#include <drawinglayer/primitive2d/transformprimitive2d.hxx>
+#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+#include <drawinglayer/primitive2d/graphicprimitivehelper2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+using namespace com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ Primitive2DSequence FillGraphicPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ Primitive2DSequence aRetval;
+ const attribute::FillGraphicAttribute& rAttribute = getFillGraphic();
+
+ if(!rAttribute.isDefault())
+ {
+ const Graphic& rGraphic = rAttribute.getGraphic();
+
+ if(GRAPHIC_BITMAP == rGraphic.GetType() || GRAPHIC_GDIMETAFILE == rGraphic.GetType())
+ {
+ const Size aSize(rGraphic.GetPrefSize());
+
+ if(aSize.Width() && aSize.Height())
+ {
+ // we have a graphic (bitmap or metafile) with some size
+ if(rAttribute.getTiling())
+ {
+ // get object range and create tiling matrices
+ ::std::vector< basegfx::B2DHomMatrix > aMatrices;
+ texture::GeoTexSvxTiled aTiling(
+ rAttribute.getGraphicRange(),
+ rAttribute.getOffsetX(),
+ rAttribute.getOffsetY());
+
+ // get matrices and realloc retval
+ aTiling.appendTransformations(aMatrices);
+ aRetval.realloc(aMatrices.size());
+
+ // prepare content primitive
+ const Primitive2DSequence xSeq = create2DDecompositionOfGraphic(
+ rGraphic,
+ basegfx::B2DHomMatrix());
+
+ for(sal_uInt32 a(0); a < aMatrices.size(); a++)
+ {
+ aRetval[a] = new TransformPrimitive2D(
+ getTransformation() * aMatrices[a],
+ xSeq);
+ }
+ }
+ else
+ {
+ // add graphic without tiling
+ const basegfx::B2DHomMatrix aObjectTransform(
+ getTransformation() * basegfx::tools::createScaleTranslateB2DHomMatrix(
+ rAttribute.getGraphicRange().getRange(),
+ rAttribute.getGraphicRange().getMinimum()));
+
+ aRetval = create2DDecompositionOfGraphic(
+ rGraphic,
+ aObjectTransform);
+ }
+ }
+ }
+ }
+
+ return aRetval;
+ }
+
+ FillGraphicPrimitive2D::FillGraphicPrimitive2D(
+ const basegfx::B2DHomMatrix& rTransformation,
+ const attribute::FillGraphicAttribute& rFillGraphic)
+ : BufferedDecompositionPrimitive2D(),
+ maTransformation(rTransformation),
+ maFillGraphic(rFillGraphic)
+ {
+ }
+
+ bool FillGraphicPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(BufferedDecompositionPrimitive2D::operator==(rPrimitive))
+ {
+ const FillGraphicPrimitive2D& rCompare = static_cast< const FillGraphicPrimitive2D& >(rPrimitive);
+
+ return (getTransformation() == rCompare.getTransformation()
+ && getFillGraphic() == rCompare.getFillGraphic());
+ }
+
+ return false;
+ }
+
+ basegfx::B2DRange FillGraphicPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ // return range of it
+ basegfx::B2DPolygon aPolygon(basegfx::tools::createUnitPolygon());
+ aPolygon.transform(getTransformation());
+
+ return basegfx::tools::getRange(aPolygon);
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(FillGraphicPrimitive2D, PRIMITIVE2D_ID_FILLGRAPHICPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/primitive2d/graphicprimitive2d.cxx b/drawinglayer/source/primitive2d/graphicprimitive2d.cxx
index 0703f9225b45..088a31581459 100644
--- a/drawinglayer/source/primitive2d/graphicprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/graphicprimitive2d.cxx
@@ -25,187 +25,13 @@
#include "precompiled_drawinglayer.hxx"
#include <drawinglayer/primitive2d/graphicprimitive2d.hxx>
-#include <drawinglayer/animation/animationtiming.hxx>
-#include <drawinglayer/primitive2d/bitmapprimitive2d.hxx>
-#include <drawinglayer/primitive2d/animatedprimitive2d.hxx>
-#include <drawinglayer/primitive2d/metafileprimitive2d.hxx>
-#include <drawinglayer/primitive2d/transformprimitive2d.hxx>
-#include <basegfx/polygon/b2dpolygon.hxx>
-#include <basegfx/polygon/b2dpolygontools.hxx>
#include <drawinglayer/primitive2d/cropprimitive2d.hxx>
#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
#include <drawinglayer/primitive2d/maskprimitive2d.hxx>
-
-//////////////////////////////////////////////////////////////////////////////
-// helper class for animated graphics
-
-#include <vcl/animate.hxx>
-#include <vcl/graph.hxx>
-#include <vcl/virdev.hxx>
+#include <drawinglayer/primitive2d/graphicprimitivehelper2d.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
#include <vcl/svapp.hxx>
-#include <vcl/metaact.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
-{
- struct animationStep
- {
- BitmapEx maBitmapEx;
- sal_uInt32 mnTime;
- };
-
- class animatedBitmapExPreparator
- {
- ::Animation maAnimation;
- ::std::vector< animationStep > maSteps;
-
- sal_uInt32 generateStepTime(sal_uInt32 nIndex) const;
-
- public:
- animatedBitmapExPreparator(const Graphic& rGraphic);
-
- sal_uInt32 count() const { return maSteps.size(); }
- sal_uInt32 loopCount() const { return (sal_uInt32)maAnimation.GetLoopCount(); }
- sal_uInt32 stepTime(sal_uInt32 a) const { return maSteps[a].mnTime; }
- const BitmapEx& stepBitmapEx(sal_uInt32 a) const { return maSteps[a].maBitmapEx; }
- };
-
- sal_uInt32 animatedBitmapExPreparator::generateStepTime(sal_uInt32 nIndex) const
- {
- const AnimationBitmap& rAnimBitmap = maAnimation.Get(sal_uInt16(nIndex));
- sal_uInt32 nWaitTime(rAnimBitmap.nWait * 10);
-
- // #115934#
- // Take care of special value for MultiPage TIFFs. ATM these shall just
- // show their first page. Later we will offer some switching when object
- // is selected.
- if(ANIMATION_TIMEOUT_ON_CLICK == rAnimBitmap.nWait)
- {
- // ATM the huge value would block the timer, so
- // use a long time to show first page (whole day)
- nWaitTime = 100 * 60 * 60 * 24;
- }
-
- // Bad trap: There are animated gifs with no set WaitTime (!).
- // In that case use a default value.
- if(0L == nWaitTime)
- {
- nWaitTime = 100L;
- }
-
- return nWaitTime;
- }
-
- animatedBitmapExPreparator::animatedBitmapExPreparator(const Graphic& rGraphic)
- : maAnimation(rGraphic.GetAnimation())
- {
- OSL_ENSURE(GRAPHIC_BITMAP == rGraphic.GetType() && rGraphic.IsAnimated(), "animatedBitmapExPreparator: graphic is not animated (!)");
-
- // #128539# secure access to Animation, looks like there exist animated GIFs out there
- // with a step count of zero
- if(maAnimation.Count())
- {
- VirtualDevice aVirtualDevice(*Application::GetDefaultDevice());
- VirtualDevice aVirtualDeviceMask(*Application::GetDefaultDevice(), 1L);
-
- // Prepare VirtualDevices and their states
- aVirtualDevice.EnableMapMode(sal_False);
- aVirtualDeviceMask.EnableMapMode(sal_False);
- aVirtualDevice.SetOutputSizePixel(maAnimation.GetDisplaySizePixel());
- aVirtualDeviceMask.SetOutputSizePixel(maAnimation.GetDisplaySizePixel());
- aVirtualDevice.Erase();
- aVirtualDeviceMask.Erase();
-
- for(sal_uInt16 a(0L); a < maAnimation.Count(); a++)
- {
- animationStep aNextStep;
- aNextStep.mnTime = generateStepTime(a);
-
- // prepare step
- const AnimationBitmap& rAnimBitmap = maAnimation.Get(sal_uInt16(a));
-
- switch(rAnimBitmap.eDisposal)
- {
- case DISPOSE_NOT:
- {
- aVirtualDevice.DrawBitmapEx(rAnimBitmap.aPosPix, rAnimBitmap.aBmpEx);
- Bitmap aMask = rAnimBitmap.aBmpEx.GetMask();
-
- if(aMask.IsEmpty())
- {
- const Point aEmpty;
- const Rectangle aRect(aEmpty, aVirtualDeviceMask.GetOutputSizePixel());
- const Wallpaper aWallpaper(COL_BLACK);
- aVirtualDeviceMask.DrawWallpaper(aRect, aWallpaper);
- }
- else
- {
- BitmapEx aExpandVisibilityMask = BitmapEx(aMask, aMask);
- aVirtualDeviceMask.DrawBitmapEx(rAnimBitmap.aPosPix, aExpandVisibilityMask);
- }
-
- break;
- }
- case DISPOSE_BACK:
- {
- // #i70772# react on no mask, for primitives, too.
- const Bitmap aMask(rAnimBitmap.aBmpEx.GetMask());
- const Bitmap aContent(rAnimBitmap.aBmpEx.GetBitmap());
-
- aVirtualDeviceMask.Erase();
- aVirtualDevice.DrawBitmap(rAnimBitmap.aPosPix, aContent);
-
- if(aMask.IsEmpty())
- {
- const Rectangle aRect(rAnimBitmap.aPosPix, aContent.GetSizePixel());
- aVirtualDeviceMask.SetFillColor(COL_BLACK);
- aVirtualDeviceMask.SetLineColor();
- aVirtualDeviceMask.DrawRect(aRect);
- }
- else
- {
- aVirtualDeviceMask.DrawBitmap(rAnimBitmap.aPosPix, aMask);
- }
-
- break;
- }
- case DISPOSE_FULL:
- {
- aVirtualDevice.DrawBitmapEx(rAnimBitmap.aPosPix, rAnimBitmap.aBmpEx);
- break;
- }
- case DISPOSE_PREVIOUS :
- {
- aVirtualDevice.DrawBitmapEx(rAnimBitmap.aPosPix, rAnimBitmap.aBmpEx);
- aVirtualDeviceMask.DrawBitmap(rAnimBitmap.aPosPix, rAnimBitmap.aBmpEx.GetMask());
- break;
- }
- }
-
- // create BitmapEx
- Bitmap aMainBitmap = aVirtualDevice.GetBitmap(Point(), aVirtualDevice.GetOutputSizePixel());
- Bitmap aMaskBitmap = aVirtualDeviceMask.GetBitmap(Point(), aVirtualDeviceMask.GetOutputSizePixel());
- aNextStep.maBitmapEx = BitmapEx(aMainBitmap, aMaskBitmap);
-
- // add to vector
- maSteps.push_back(aNextStep);
- }
- }
- }
-} // end of anonymous namespace
+#include <vcl/outdev.hxx>
//////////////////////////////////////////////////////////////////////////////
@@ -225,8 +51,6 @@ namespace drawinglayer
if(255L != getGraphicAttr().GetTransparency())
{
- Primitive2DReference xPrimitive;
-
// do not apply mirroring from GraphicAttr to the Metafile by calling
// GetTransformedGraphic, this will try to mirror the Metafile using Scale()
// at the Metafile. This again calls Scale at the single MetaFile actions,
@@ -262,556 +86,11 @@ namespace drawinglayer
const GraphicObject& rGraphicObject = getGraphicObject();
const Graphic aTransformedGraphic(rGraphicObject.GetTransformedGraphic(&aSuppressGraphicAttr));
- switch(aTransformedGraphic.GetType())
- {
- case GRAPHIC_BITMAP :
- {
- if(aTransformedGraphic.IsAnimated())
- {
- // prepare animation data
- animatedBitmapExPreparator aData(aTransformedGraphic);
-
- if(aData.count())
- {
- // create sub-primitives for animated bitmap and the needed animation loop
- animation::AnimationEntryLoop aAnimationLoop(aData.loopCount() ? aData.loopCount() : 0xffff);
- Primitive2DSequence aBitmapPrimitives(aData.count());
-
- for(sal_uInt32 a(0L); a < aData.count(); a++)
- {
- animation::AnimationEntryFixed aTime((double)aData.stepTime(a), (double)a / (double)aData.count());
- aAnimationLoop.append(aTime);
- const Primitive2DReference xRef(new BitmapPrimitive2D(aData.stepBitmapEx(a), aTransform));
- aBitmapPrimitives[a] = xRef;
- }
-
- // prepare animation list
- animation::AnimationEntryList aAnimationList;
- aAnimationList.append(aAnimationLoop);
-
- // create and add animated switch primitive
- xPrimitive = Primitive2DReference(new AnimatedSwitchPrimitive2D(aAnimationList, aBitmapPrimitives, false));
- }
- }
- else if(aTransformedGraphic.getSvgData().get())
- {
- // embedded Svg fill, create embed transform
- const basegfx::B2DRange& rSvgRange(aTransformedGraphic.getSvgData()->getRange());
-
- if(basegfx::fTools::more(rSvgRange.getWidth(), 0.0) && basegfx::fTools::more(rSvgRange.getHeight(), 0.0))
- {
- // translate back to origin, scale to unit coordinates
- basegfx::B2DHomMatrix aEmbedSvg(
- basegfx::tools::createTranslateB2DHomMatrix(
- -rSvgRange.getMinX(),
- -rSvgRange.getMinY()));
-
- aEmbedSvg.scale(
- 1.0 / rSvgRange.getWidth(),
- 1.0 / rSvgRange.getHeight());
+ aRetval = create2DDecompositionOfGraphic(
+ aTransformedGraphic,
+ aTransform);
- // apply created object transformation
- aEmbedSvg = aTransform * aEmbedSvg;
-
- // add Svg primitives embedded
- xPrimitive = new TransformPrimitive2D(
- aEmbedSvg,
- aTransformedGraphic.getSvgData()->getPrimitive2DSequence());
- }
- }
- else
- {
- xPrimitive = Primitive2DReference(new BitmapPrimitive2D(aTransformedGraphic.GetBitmapEx(), aTransform));
- }
-
- break;
- }
-
- case GRAPHIC_GDIMETAFILE :
- {
-#ifdef USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE
- static bool bDoTest(false);
-
- if(bDoTest)
- {
- // 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 GDIMetaFile& rMetafile = aTransformedGraphic.GetGDIMetaFile();
-
- xPrimitive = Primitive2DReference(
- new MetafilePrimitive2D(
- aTransform,
- rMetafile));
-
- // #i100357# find out if clipping is needed for this primitive. Unfortunately,
- // there exist Metafiles who's content is bigger than the proposed PrefSize set
- // at them. This is an error, but we need to work around this
- const Size aMetaFilePrefSize(rMetafile.GetPrefSize());
- const Size aMetaFileRealSize(
- const_cast< GDIMetaFile& >(rMetafile).GetBoundRect(
- *Application::GetDefaultDevice()).GetSize());
-
- if(aMetaFileRealSize.getWidth() > aMetaFilePrefSize.getWidth()
- || aMetaFileRealSize.getHeight() > aMetaFilePrefSize.getHeight())
- {
- // clipping needed. Embed to MaskPrimitive2D. Create childs and mask polygon
- const primitive2d::Primitive2DSequence aChildContent(&xPrimitive, 1);
- basegfx::B2DPolygon aMaskPolygon(basegfx::tools::createUnitPolygon());
- aMaskPolygon.transform(aTransform);
-
- xPrimitive = Primitive2DReference(
- new MaskPrimitive2D(
- basegfx::B2DPolyPolygon(aMaskPolygon),
- aChildContent));
- }
-#ifdef USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE
- }
-#endif // USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE
-
- break;
- }
-
- default:
- {
- // nothing to create
- break;
- }
- }
-
- if(xPrimitive.is())
+ if(aRetval.getLength())
{
// check for cropping
if(getGraphicAttr().IsCropped())
@@ -851,17 +130,17 @@ namespace drawinglayer
}
// embed content in cropPrimitive
- xPrimitive = new CropPrimitive2D(
- Primitive2DSequence(&xPrimitive, 1),
- aTransform,
- getGraphicAttr().GetLeftCrop() * fFactorX,
- getGraphicAttr().GetTopCrop() * fFactorY,
- getGraphicAttr().GetRightCrop() * fFactorX,
- getGraphicAttr().GetBottomCrop() * fFactorY);
+ Primitive2DReference xPrimitive(
+ new CropPrimitive2D(
+ aRetval,
+ aTransform,
+ getGraphicAttr().GetLeftCrop() * fFactorX,
+ getGraphicAttr().GetTopCrop() * fFactorY,
+ getGraphicAttr().GetRightCrop() * fFactorX,
+ getGraphicAttr().GetBottomCrop() * fFactorY));
+
+ aRetval = Primitive2DSequence(&xPrimitive, 1);
}
-
- // add to decomposition
- appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, xPrimitive);
}
}
diff --git a/drawinglayer/source/primitive2d/graphicprimitivehelper2d.cxx b/drawinglayer/source/primitive2d/graphicprimitivehelper2d.cxx
new file mode 100755
index 000000000000..7b93bc0efd88
--- /dev/null
+++ b/drawinglayer/source/primitive2d/graphicprimitivehelper2d.cxx
@@ -0,0 +1,782 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/primitive2d/graphicprimitivehelper2d.hxx>
+#include <drawinglayer/animation/animationtiming.hxx>
+#include <drawinglayer/primitive2d/bitmapprimitive2d.hxx>
+#include <drawinglayer/primitive2d/animatedprimitive2d.hxx>
+#include <drawinglayer/primitive2d/metafileprimitive2d.hxx>
+#include <drawinglayer/primitive2d/transformprimitive2d.hxx>
+#include <drawinglayer/primitive2d/maskprimitive2d.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+// helper class for animated graphics
+
+#include <vcl/animate.hxx>
+#include <vcl/graph.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/metaact.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
+{
+ struct animationStep
+ {
+ BitmapEx maBitmapEx;
+ sal_uInt32 mnTime;
+ };
+
+ class animatedBitmapExPreparator
+ {
+ ::Animation maAnimation;
+ ::std::vector< animationStep > maSteps;
+
+ sal_uInt32 generateStepTime(sal_uInt32 nIndex) const;
+
+ public:
+ animatedBitmapExPreparator(const Graphic& rGraphic);
+
+ sal_uInt32 count() const { return maSteps.size(); }
+ sal_uInt32 loopCount() const { return (sal_uInt32)maAnimation.GetLoopCount(); }
+ sal_uInt32 stepTime(sal_uInt32 a) const { return maSteps[a].mnTime; }
+ const BitmapEx& stepBitmapEx(sal_uInt32 a) const { return maSteps[a].maBitmapEx; }
+ };
+
+ sal_uInt32 animatedBitmapExPreparator::generateStepTime(sal_uInt32 nIndex) const
+ {
+ const AnimationBitmap& rAnimBitmap = maAnimation.Get(sal_uInt16(nIndex));
+ sal_uInt32 nWaitTime(rAnimBitmap.nWait * 10);
+
+ // #115934#
+ // Take care of special value for MultiPage TIFFs. ATM these shall just
+ // show their first page. Later we will offer some switching when object
+ // is selected.
+ if(ANIMATION_TIMEOUT_ON_CLICK == rAnimBitmap.nWait)
+ {
+ // ATM the huge value would block the timer, so
+ // use a long time to show first page (whole day)
+ nWaitTime = 100 * 60 * 60 * 24;
+ }
+
+ // Bad trap: There are animated gifs with no set WaitTime (!).
+ // In that case use a default value.
+ if(0L == nWaitTime)
+ {
+ nWaitTime = 100L;
+ }
+
+ return nWaitTime;
+ }
+
+ animatedBitmapExPreparator::animatedBitmapExPreparator(const Graphic& rGraphic)
+ : maAnimation(rGraphic.GetAnimation())
+ {
+ OSL_ENSURE(GRAPHIC_BITMAP == rGraphic.GetType() && rGraphic.IsAnimated(), "animatedBitmapExPreparator: graphic is not animated (!)");
+
+ // #128539# secure access to Animation, looks like there exist animated GIFs out there
+ // with a step count of zero
+ if(maAnimation.Count())
+ {
+ VirtualDevice aVirtualDevice(*Application::GetDefaultDevice());
+ VirtualDevice aVirtualDeviceMask(*Application::GetDefaultDevice(), 1L);
+
+ // Prepare VirtualDevices and their states
+ aVirtualDevice.EnableMapMode(sal_False);
+ aVirtualDeviceMask.EnableMapMode(sal_False);
+ aVirtualDevice.SetOutputSizePixel(maAnimation.GetDisplaySizePixel());
+ aVirtualDeviceMask.SetOutputSizePixel(maAnimation.GetDisplaySizePixel());
+ aVirtualDevice.Erase();
+ aVirtualDeviceMask.Erase();
+
+ for(sal_uInt16 a(0L); a < maAnimation.Count(); a++)
+ {
+ animationStep aNextStep;
+ aNextStep.mnTime = generateStepTime(a);
+
+ // prepare step
+ const AnimationBitmap& rAnimBitmap = maAnimation.Get(sal_uInt16(a));
+
+ switch(rAnimBitmap.eDisposal)
+ {
+ case DISPOSE_NOT:
+ {
+ aVirtualDevice.DrawBitmapEx(rAnimBitmap.aPosPix, rAnimBitmap.aBmpEx);
+ Bitmap aMask = rAnimBitmap.aBmpEx.GetMask();
+
+ if(aMask.IsEmpty())
+ {
+ const Point aEmpty;
+ const Rectangle aRect(aEmpty, aVirtualDeviceMask.GetOutputSizePixel());
+ const Wallpaper aWallpaper(COL_BLACK);
+ aVirtualDeviceMask.DrawWallpaper(aRect, aWallpaper);
+ }
+ else
+ {
+ BitmapEx aExpandVisibilityMask = BitmapEx(aMask, aMask);
+ aVirtualDeviceMask.DrawBitmapEx(rAnimBitmap.aPosPix, aExpandVisibilityMask);
+ }
+
+ break;
+ }
+ case DISPOSE_BACK:
+ {
+ // #i70772# react on no mask, for primitives, too.
+ const Bitmap aMask(rAnimBitmap.aBmpEx.GetMask());
+ const Bitmap aContent(rAnimBitmap.aBmpEx.GetBitmap());
+
+ aVirtualDeviceMask.Erase();
+ aVirtualDevice.DrawBitmap(rAnimBitmap.aPosPix, aContent);
+
+ if(aMask.IsEmpty())
+ {
+ const Rectangle aRect(rAnimBitmap.aPosPix, aContent.GetSizePixel());
+ aVirtualDeviceMask.SetFillColor(COL_BLACK);
+ aVirtualDeviceMask.SetLineColor();
+ aVirtualDeviceMask.DrawRect(aRect);
+ }
+ else
+ {
+ aVirtualDeviceMask.DrawBitmap(rAnimBitmap.aPosPix, aMask);
+ }
+
+ break;
+ }
+ case DISPOSE_FULL:
+ {
+ aVirtualDevice.DrawBitmapEx(rAnimBitmap.aPosPix, rAnimBitmap.aBmpEx);
+ break;
+ }
+ case DISPOSE_PREVIOUS :
+ {
+ aVirtualDevice.DrawBitmapEx(rAnimBitmap.aPosPix, rAnimBitmap.aBmpEx);
+ aVirtualDeviceMask.DrawBitmap(rAnimBitmap.aPosPix, rAnimBitmap.aBmpEx.GetMask());
+ break;
+ }
+ }
+
+ // create BitmapEx
+ Bitmap aMainBitmap = aVirtualDevice.GetBitmap(Point(), aVirtualDevice.GetOutputSizePixel());
+ Bitmap aMaskBitmap = aVirtualDeviceMask.GetBitmap(Point(), aVirtualDeviceMask.GetOutputSizePixel());
+ aNextStep.maBitmapEx = BitmapEx(aMainBitmap, aMaskBitmap);
+
+ // add to vector
+ maSteps.push_back(aNextStep);
+ }
+ }
+ }
+} // end of anonymous namespace
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ Primitive2DSequence create2DDecompositionOfGraphic(
+ const Graphic& rGraphic,
+ const basegfx::B2DHomMatrix& rTransform)
+ {
+ Primitive2DSequence aRetval;
+
+ switch(rGraphic.GetType())
+ {
+ case GRAPHIC_BITMAP :
+ {
+ if(rGraphic.IsAnimated())
+ {
+ // prepare animation data
+ animatedBitmapExPreparator aData(rGraphic);
+
+ if(aData.count())
+ {
+ // create sub-primitives for animated bitmap and the needed animation loop
+ animation::AnimationEntryLoop aAnimationLoop(aData.loopCount() ? aData.loopCount() : 0xffff);
+ Primitive2DSequence aBitmapPrimitives(aData.count());
+
+ for(sal_uInt32 a(0); a < aData.count(); a++)
+ {
+ animation::AnimationEntryFixed aTime((double)aData.stepTime(a), (double)a / (double)aData.count());
+ aAnimationLoop.append(aTime);
+ aBitmapPrimitives[a] = new BitmapPrimitive2D(
+ aData.stepBitmapEx(a),
+ rTransform);
+ }
+
+ // prepare animation list
+ animation::AnimationEntryList aAnimationList;
+ aAnimationList.append(aAnimationLoop);
+
+ // create and add animated switch primitive
+ aRetval.realloc(1);
+ aRetval[0] = new AnimatedSwitchPrimitive2D(
+ aAnimationList,
+ aBitmapPrimitives,
+ false);
+ }
+ }
+ else if(rGraphic.getSvgData().get())
+ {
+ // embedded Svg fill, create embed transform
+ const basegfx::B2DRange& rSvgRange(rGraphic.getSvgData()->getRange());
+
+ if(basegfx::fTools::more(rSvgRange.getWidth(), 0.0) && basegfx::fTools::more(rSvgRange.getHeight(), 0.0))
+ {
+ // translate back to origin, scale to unit coordinates
+ basegfx::B2DHomMatrix aEmbedSvg(
+ basegfx::tools::createTranslateB2DHomMatrix(
+ -rSvgRange.getMinX(),
+ -rSvgRange.getMinY()));
+
+ aEmbedSvg.scale(
+ 1.0 / rSvgRange.getWidth(),
+ 1.0 / rSvgRange.getHeight());
+
+ // apply created object transformation
+ aEmbedSvg = rTransform * aEmbedSvg;
+
+ // add Svg primitives embedded
+ aRetval.realloc(1);
+ aRetval[0] = new TransformPrimitive2D(
+ aEmbedSvg,
+ rGraphic.getSvgData()->getPrimitive2DSequence());
+ }
+ }
+ else
+ {
+ aRetval.realloc(1);
+ aRetval[0] = new BitmapPrimitive2D(
+ rGraphic.GetBitmapEx(),
+ rTransform);
+ }
+
+ break;
+ }
+
+ case GRAPHIC_GDIMETAFILE :
+ {
+#ifdef USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE
+ static bool bDoTest(false);
+
+ if(bDoTest)
+ {
+ // 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()));
+
+ aRetval.realloc(1);
+ aRetval[0] = new MetafilePrimitive2D(
+ rTransform,
+ aMtf);
+ }
+ else
+ {
+#endif // USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE
+ // create MetafilePrimitive2D
+ const GDIMetaFile& rMetafile = rGraphic.GetGDIMetaFile();
+
+ aRetval.realloc(1);
+ aRetval[0] = new MetafilePrimitive2D(
+ rTransform,
+ rMetafile);
+
+ // #i100357# find out if clipping is needed for this primitive. Unfortunately,
+ // there exist Metafiles who's content is bigger than the proposed PrefSize set
+ // at them. This is an error, but we need to work around this
+ const Size aMetaFilePrefSize(rMetafile.GetPrefSize());
+ const Size aMetaFileRealSize(
+ const_cast< GDIMetaFile& >(rMetafile).GetBoundRect(
+ *Application::GetDefaultDevice()).GetSize());
+
+ if(aMetaFileRealSize.getWidth() > aMetaFilePrefSize.getWidth()
+ || aMetaFileRealSize.getHeight() > aMetaFilePrefSize.getHeight())
+ {
+ // clipping needed. Embed to MaskPrimitive2D. Create childs and mask polygon
+ basegfx::B2DPolygon aMaskPolygon(basegfx::tools::createUnitPolygon());
+ aMaskPolygon.transform(rTransform);
+
+ aRetval[0] = new MaskPrimitive2D(
+ basegfx::B2DPolyPolygon(aMaskPolygon),
+ aRetval);
+ }
+#ifdef USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE
+ }
+#endif // USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE
+
+ break;
+ }
+
+ default:
+ {
+ // nothing to create
+ break;
+ }
+ }
+
+ return aRetval;
+ }
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/primitive2d/metafileprimitive2d.cxx b/drawinglayer/source/primitive2d/metafileprimitive2d.cxx
index 2663043b9f39..11f9fd790f5b 100644
--- a/drawinglayer/source/primitive2d/metafileprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/metafileprimitive2d.cxx
@@ -50,7 +50,7 @@
#include <basegfx/polygon/b2dpolygonclipper.hxx>
#include <drawinglayer/primitive2d/invertprimitive2d.hxx>
#include <drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx>
-#include <drawinglayer/primitive2d/fillbitmapprimitive2d.hxx>
+#include <drawinglayer/primitive2d/fillgraphicprimitive2d.hxx>
#include <drawinglayer/primitive2d/wallpaperprimitive2d.hxx>
#include <drawinglayer/primitive2d/textprimitive2d.hxx>
#include <drawinglayer/primitive2d/textlayoutdevice.hxx>
diff --git a/drawinglayer/source/primitive2d/patternfillprimitive2d.cxx b/drawinglayer/source/primitive2d/patternfillprimitive2d.cxx
index 9b0f9ef844f5..8c0893ff3d11 100644
--- a/drawinglayer/source/primitive2d/patternfillprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/patternfillprimitive2d.cxx
@@ -57,7 +57,8 @@ namespace drawinglayer
{
// create tiling matrices
::std::vector< basegfx::B2DHomMatrix > aMatrices;
- texture::GeoTexSvxTiled aTiling(getReferenceRange().getMinimum(), getReferenceRange().getRange());
+ texture::GeoTexSvxTiled aTiling(getReferenceRange());
+
aTiling.appendTransformations(aMatrices);
// check if content needs to be clipped
diff --git a/drawinglayer/source/primitive2d/polypolygonprimitive2d.cxx b/drawinglayer/source/primitive2d/polypolygonprimitive2d.cxx
index 7be70aa83aa1..be8300fdba69 100644
--- a/drawinglayer/source/primitive2d/polypolygonprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/polypolygonprimitive2d.cxx
@@ -31,9 +31,11 @@
#include <drawinglayer/primitive2d/maskprimitive2d.hxx>
#include <drawinglayer/primitive2d/fillhatchprimitive2d.hxx>
#include <basegfx/matrix/b2dhommatrix.hxx>
-#include <drawinglayer/primitive2d/fillbitmapprimitive2d.hxx>
+#include <drawinglayer/primitive2d/fillgraphicprimitive2d.hxx>
#include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+#include <vcl/graph.hxx>
//////////////////////////////////////////////////////////////////////////////
@@ -510,56 +512,69 @@ namespace drawinglayer
{
namespace primitive2d
{
- Primitive2DSequence PolyPolygonBitmapPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ Primitive2DSequence PolyPolygonGraphicPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
{
- if(!getFillBitmap().isDefault())
+ if(!getFillGraphic().isDefault())
{
- // create SubSequence with FillBitmapPrimitive2D
- const basegfx::B2DRange aPolyPolygonRange(getB2DPolyPolygon().getB2DRange());
- basegfx::B2DHomMatrix aNewObjectTransform;
- aNewObjectTransform.set(0, 0, aPolyPolygonRange.getWidth());
- aNewObjectTransform.set(1, 1, aPolyPolygonRange.getHeight());
- aNewObjectTransform.set(0, 2, aPolyPolygonRange.getMinX());
- aNewObjectTransform.set(1, 2, aPolyPolygonRange.getMinY());
- FillBitmapPrimitive2D* pNewBitmap = new FillBitmapPrimitive2D(aNewObjectTransform, getFillBitmap());
- const Primitive2DReference xSubRef(pNewBitmap);
- const Primitive2DSequence aSubSequence(&xSubRef, 1L);
+ const Graphic& rGraphic = getFillGraphic().getGraphic();
+ const GraphicType aType(rGraphic.GetType());
- // create mask primitive
- MaskPrimitive2D* pNewMask = new MaskPrimitive2D(getB2DPolyPolygon(), aSubSequence);
- const Primitive2DReference xRef(pNewMask);
+ // is there a bitmap or a metafile (do we have content)?
+ if(GRAPHIC_BITMAP == aType || GRAPHIC_GDIMETAFILE == aType)
+ {
+ const Size aPrefSize(rGraphic.GetPrefSize());
- return Primitive2DSequence(&xRef, 1);
- }
- else
- {
- return Primitive2DSequence();
+ // does content have a size?
+ if(aPrefSize.Width() && aPrefSize.Height())
+ {
+ // create SubSequence with FillGraphicPrimitive2D based on polygon range
+ const basegfx::B2DRange aPolyPolygonRange(getB2DPolyPolygon().getB2DRange());
+ const basegfx::B2DHomMatrix aNewObjectTransform(
+ basegfx::tools::createScaleTranslateB2DHomMatrix(
+ aPolyPolygonRange.getRange(),
+ aPolyPolygonRange.getMinimum()));
+ const Primitive2DReference xSubRef(
+ new FillGraphicPrimitive2D(
+ aNewObjectTransform,
+ getFillGraphic()));
+
+ // embed to mask primitive
+ const Primitive2DReference xRef(
+ new MaskPrimitive2D(
+ getB2DPolyPolygon(),
+ Primitive2DSequence(&xSubRef, 1)));
+
+ return Primitive2DSequence(&xRef, 1);
+ }
+ }
}
+
+ return Primitive2DSequence();
}
- PolyPolygonBitmapPrimitive2D::PolyPolygonBitmapPrimitive2D(
+ PolyPolygonGraphicPrimitive2D::PolyPolygonGraphicPrimitive2D(
const basegfx::B2DPolyPolygon& rPolyPolygon,
- const attribute::FillBitmapAttribute& rFillBitmap)
+ const attribute::FillGraphicAttribute& rFillGraphic)
: BufferedDecompositionPrimitive2D(),
maPolyPolygon(rPolyPolygon),
- maFillBitmap(rFillBitmap)
+ maFillGraphic(rFillGraphic)
{
}
- bool PolyPolygonBitmapPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ bool PolyPolygonGraphicPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
{
if(BufferedDecompositionPrimitive2D::operator==(rPrimitive))
{
- const PolyPolygonBitmapPrimitive2D& rCompare = (PolyPolygonBitmapPrimitive2D&)rPrimitive;
+ const PolyPolygonGraphicPrimitive2D& rCompare = (PolyPolygonGraphicPrimitive2D&)rPrimitive;
- return (getFillBitmap() == rCompare.getFillBitmap());
+ return (getFillGraphic() == rCompare.getFillGraphic());
}
return false;
}
// provide unique ID
- ImplPrimitrive2DIDBlock(PolyPolygonBitmapPrimitive2D, PRIMITIVE2D_ID_POLYPOLYGONBITMAPPRIMITIVE2D)
+ ImplPrimitrive2DIDBlock(PolyPolygonGraphicPrimitive2D, PRIMITIVE2D_ID_POLYPOLYGONGRAPHICPRIMITIVE2D)
} // end of namespace primitive2d
} // end of namespace drawinglayer
diff --git a/drawinglayer/source/primitive2d/wallpaperprimitive2d.cxx b/drawinglayer/source/primitive2d/wallpaperprimitive2d.cxx
index bcb81a566ee9..ffb341c4fe64 100644
--- a/drawinglayer/source/primitive2d/wallpaperprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/wallpaperprimitive2d.cxx
@@ -27,10 +27,12 @@
#include <drawinglayer/primitive2d/wallpaperprimitive2d.hxx>
#include <drawinglayer/primitive2d/bitmapprimitive2d.hxx>
#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
-#include <drawinglayer/primitive2d/fillbitmapprimitive2d.hxx>
+#include <drawinglayer/primitive2d/fillgraphicprimitive2d.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <basegfx/polygon/b2dpolygon.hxx>
#include <drawinglayer/primitive2d/maskprimitive2d.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+#include <vcl/graph.hxx>
//////////////////////////////////////////////////////////////////////////////
@@ -182,26 +184,23 @@ namespace drawinglayer
aRelativeTopLeft.setY(0.5 - aRelativeSize.getY());
}
- // prepare FillBitmapAttribute
- const attribute::FillBitmapAttribute aFillBitmapAttribute(
- getBitmapEx(),
- aRelativeTopLeft,
- aRelativeSize,
+ // prepare FillGraphicAttribute
+ const attribute::FillGraphicAttribute aFillGraphicAttribute(
+ Graphic(getBitmapEx()),
+ basegfx::B2DRange(aRelativeTopLeft, aRelativeTopLeft+ aRelativeSize),
true);
// create ObjectTransform
- basegfx::B2DHomMatrix aObjectTransform;
-
- aObjectTransform.set(0, 0, getLocalObjectRange().getWidth());
- aObjectTransform.set(1, 1, getLocalObjectRange().getHeight());
- aObjectTransform.set(0, 2, getLocalObjectRange().getMinX());
- aObjectTransform.set(1, 2, getLocalObjectRange().getMinY());
+ const basegfx::B2DHomMatrix aObjectTransform(
+ basegfx::tools::createScaleTranslateB2DHomMatrix(
+ getLocalObjectRange().getRange(),
+ getLocalObjectRange().getMinimum()));
// create FillBitmapPrimitive
const drawinglayer::primitive2d::Primitive2DReference xFillBitmap(
- new drawinglayer::primitive2d::FillBitmapPrimitive2D(
+ new drawinglayer::primitive2d::FillGraphicPrimitive2D(
aObjectTransform,
- aFillBitmapAttribute));
+ aFillGraphicAttribute));
aRetval = Primitive2DSequence(&xFillBitmap, 1);
// always embed tiled fill to clipping
diff --git a/drawinglayer/source/primitive3d/sdrdecompositiontools3d.cxx b/drawinglayer/source/primitive3d/sdrdecompositiontools3d.cxx
index 08c79e7c8226..3152efad65f8 100644
--- a/drawinglayer/source/primitive3d/sdrdecompositiontools3d.cxx
+++ b/drawinglayer/source/primitive3d/sdrdecompositiontools3d.cxx
@@ -32,8 +32,8 @@
#include <basegfx/polygon/b3dpolypolygon.hxx>
#include <drawinglayer/primitive3d/polypolygonprimitive3d.hxx>
#include <vcl/vclenum.hxx>
-#include <drawinglayer/attribute/fillbitmapattribute.hxx>
-#include <drawinglayer/attribute/sdrfillbitmapattribute.hxx>
+#include <drawinglayer/attribute/fillgraphicattribute.hxx>
+#include <drawinglayer/attribute/sdrfillgraphicattribute.hxx>
#include <vcl/bmpacc.hxx>
#include <basegfx/polygon/b3dpolypolygontools.hxx>
#include <drawinglayer/primitive3d/textureprimitive3d.hxx>
@@ -208,7 +208,7 @@ namespace drawinglayer
// look for and evtl. build texture sub-group primitive
if(!rFill.getGradient().isDefault()
|| !rFill.getHatch().isDefault()
- || !rFill.getBitmap().isDefault())
+ || !rFill.getFillGraphic().isDefault())
{
bool bModulate(::com::sun::star::drawing::TextureMode_MODULATE == aSdr3DObjectAttribute.getTextureMode());
bool bFilter(aSdr3DObjectAttribute.getTextureFilter());
@@ -234,13 +234,13 @@ namespace drawinglayer
bModulate,
bFilter);
}
- else // if(!rFill.getBitmap().isDefault())
+ else // if(!rFill.getFillGraphic().isDefault())
{
// create bitmapTexture3D with sublist, add to local aRetval
- basegfx::B2DRange aTexRange(0.0, 0.0, rTextureSize.getX(), rTextureSize.getY());
+ const basegfx::B2DRange aTexRange(0.0, 0.0, rTextureSize.getX(), rTextureSize.getY());
pNewTexturePrimitive3D = new BitmapTexturePrimitive3D(
- rFill.getBitmap().getFillBitmapAttribute(aTexRange),
+ rFill.getFillGraphic().createFillGraphicAttribute(aTexRange),
aRetval,
rTextureSize,
bModulate,
@@ -313,7 +313,7 @@ namespace drawinglayer
basegfx::BColor(),
attribute::FillGradientAttribute(),
attribute::FillHatchAttribute(),
- attribute::SdrFillBitmapAttribute());
+ attribute::SdrFillGraphicAttribute());
const Primitive3DReference aHidden(
new HiddenGeometryPrimitive3D(
diff --git a/drawinglayer/source/primitive3d/textureprimitive3d.cxx b/drawinglayer/source/primitive3d/textureprimitive3d.cxx
index 10b525724530..77ffb85991b2 100644
--- a/drawinglayer/source/primitive3d/textureprimitive3d.cxx
+++ b/drawinglayer/source/primitive3d/textureprimitive3d.cxx
@@ -167,12 +167,12 @@ namespace drawinglayer
namespace primitive3d
{
BitmapTexturePrimitive3D::BitmapTexturePrimitive3D(
- const attribute::FillBitmapAttribute& rFillBitmapAttribute,
+ const attribute::FillGraphicAttribute& rFillGraphicAttribute,
const Primitive3DSequence& rChildren,
const basegfx::B2DVector& rTextureSize,
bool bModulate, bool bFilter)
: TexturePrimitive3D(rChildren, rTextureSize, bModulate, bFilter),
- maFillBitmapAttribute(rFillBitmapAttribute)
+ maFillGraphicAttribute(rFillGraphicAttribute)
{
}
@@ -182,7 +182,7 @@ namespace drawinglayer
{
const BitmapTexturePrimitive3D& rCompare = (BitmapTexturePrimitive3D&)rPrimitive;
- return (getFillBitmapAttribute() == rCompare.getFillBitmapAttribute());
+ return (getFillGraphicAttribute() == rCompare.getFillGraphicAttribute());
}
return false;
diff --git a/drawinglayer/source/processor2d/_vclmetafileprocessor2d.cxx b/drawinglayer/source/processor2d/_vclmetafileprocessor2d.cxx
new file mode 100644
index 000000000000..a1f00503fd1f
--- /dev/null
+++ b/drawinglayer/source/processor2d/_vclmetafileprocessor2d.cxx
@@ -0,0 +1,2086 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/processor2d/vclmetafileprocessor2d.hxx>
+#include <tools/gen.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/gdimtf.hxx>
+#include <vcl/gradient.hxx>
+#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+#include <drawinglayer/primitive2d/textprimitive2d.hxx>
+#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
+#include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
+#include <drawinglayer/primitive2d/bitmapprimitive2d.hxx>
+#include <drawinglayer/primitive2d/metafileprimitive2d.hxx>
+#include <drawinglayer/primitive2d/maskprimitive2d.hxx>
+#include <basegfx/polygon/b2dpolygonclipper.hxx>
+#include <basegfx/polygon/b2dpolypolygontools.hxx>
+#include <drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx>
+#include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx>
+#include <drawinglayer/primitive2d/transparenceprimitive2d.hxx>
+#include <drawinglayer/primitive2d/fillgradientprimitive2d.hxx>
+#include <drawinglayer/processor2d/vclpixelprocessor2d.hxx>
+#include <tools/stream.hxx>
+#include <drawinglayer/primitive2d/transformprimitive2d.hxx>
+#include <drawinglayer/primitive2d/markerarrayprimitive2d.hxx>
+#include <drawinglayer/primitive2d/pointarrayprimitive2d.hxx>
+#include <vcl/graphictools.hxx>
+#include <vcl/metaact.hxx>
+#include <drawinglayer/primitive2d/texthierarchyprimitive2d.hxx>
+#include <drawinglayer/primitive2d/textdecoratedprimitive2d.hxx>
+#include <comphelper/processfactory.hxx>
+#include <rtl/ustring.hxx>
+#include <com/sun/star/i18n/CharacterIteratorMode.hdl>
+#include <com/sun/star/i18n/WordType.hpp>
+#include <drawinglayer/primitive2d/controlprimitive2d.hxx>
+#include <drawinglayer/primitive2d/graphicprimitive2d.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <drawinglayer/primitive2d/pagepreviewprimitive2d.hxx>
+#include <drawinglayer/primitive2d/epsprimitive2d.hxx>
+#include <basegfx/polygon/b2dlinegeometry.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+// for PDFExtOutDevData Graphic support
+
+#include <vcl/graph.hxx>
+#include <vcl/svapp.hxx>
+#include <toolkit/helper/formpdfexport.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+// for Control printing
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+//////////////////////////////////////////////////////////////////////////////
+// for StructureTagPrimitive support in sd's unomodel.cxx
+
+#include <drawinglayer/primitive2d/structuretagprimitive2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+using namespace com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////////
+// #112245# definition for maximum allowed point count due to Metafile target.
+// To be on the safe side with the old tools polygon, use slightly less then
+// the theoretical maximum (bad experiences with tools polygon)
+
+#define MAX_POLYGON_POINT_COUNT_METAFILE (0x0000fff0)
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace
+{
+ // #112245# helper to split line polygon in half
+ void splitLinePolygon(
+ const basegfx::B2DPolygon& rBasePolygon,
+ basegfx::B2DPolygon& o_aLeft,
+ basegfx::B2DPolygon& o_aRight)
+ {
+ const sal_uInt32 nCount(rBasePolygon.count());
+
+ if(nCount)
+ {
+ const sal_uInt32 nHalfCount((nCount - 1) >> 1);
+
+ o_aLeft = basegfx::B2DPolygon(rBasePolygon, 0, nHalfCount + 1);
+ o_aLeft.setClosed(false);
+
+ o_aRight = basegfx::B2DPolygon(rBasePolygon, nHalfCount, nCount - nHalfCount);
+ o_aRight.setClosed(false);
+
+ if(rBasePolygon.isClosed())
+ {
+ o_aRight.append(rBasePolygon.getB2DPoint(0));
+
+ if(rBasePolygon.areControlPointsUsed())
+ {
+ o_aRight.setControlPoints(
+ o_aRight.count() - 1,
+ rBasePolygon.getPrevControlPoint(0),
+ rBasePolygon.getNextControlPoint(0));
+ }
+ }
+ }
+ else
+ {
+ o_aLeft.clear();
+ o_aRight.clear();
+ }
+ }
+
+ // #112245# helper to evtl. split filled polygons to maximum metafile point count
+ bool fillPolyPolygonNeededToBeSplit(basegfx::B2DPolyPolygon& rPolyPolygon)
+ {
+ bool bRetval(false);
+ const sal_uInt32 nPolyCount(rPolyPolygon.count());
+
+ if(nPolyCount)
+ {
+ basegfx::B2DPolyPolygon aSplitted;
+
+ for(sal_uInt32 a(0); a < nPolyCount; a++)
+ {
+ const basegfx::B2DPolygon aCandidate(rPolyPolygon.getB2DPolygon(a));
+ const sal_uInt32 nPointCount(aCandidate.count());
+ bool bNeedToSplit(false);
+
+ if(aCandidate.areControlPointsUsed())
+ {
+ // compare with the maximum for bezier curved polygons
+ bNeedToSplit = nPointCount > ((MAX_POLYGON_POINT_COUNT_METAFILE / 3L) - 1L);
+ }
+ else
+ {
+ // compare with the maximum for simple point polygons
+ bNeedToSplit = nPointCount > (MAX_POLYGON_POINT_COUNT_METAFILE - 1);
+ }
+
+ if(bNeedToSplit)
+ {
+ // need to split the partial polygon
+ const basegfx::B2DRange aRange(aCandidate.getB2DRange());
+ const basegfx::B2DPoint aCenter(aRange.getCenter());
+
+ if(aRange.getWidth() > aRange.getHeight())
+ {
+ // clip in left and right
+ const basegfx::B2DPolyPolygon aLeft(
+ basegfx::tools::clipPolygonOnParallelAxis(
+ aCandidate,
+ false,
+ true,
+ aCenter.getX(),
+ false));
+ const basegfx::B2DPolyPolygon aRight(
+ basegfx::tools::clipPolygonOnParallelAxis(
+ aCandidate,
+ false,
+ false,
+ aCenter.getX(),
+ false));
+
+ aSplitted.append(aLeft);
+ aSplitted.append(aRight);
+ }
+ else
+ {
+ // clip in top and bottom
+ const basegfx::B2DPolyPolygon aTop(
+ basegfx::tools::clipPolygonOnParallelAxis(
+ aCandidate,
+ true,
+ true,
+ aCenter.getY(),
+ false));
+ const basegfx::B2DPolyPolygon aBottom(
+ basegfx::tools::clipPolygonOnParallelAxis(
+ aCandidate,
+ true,
+ false,
+ aCenter.getY(),
+ false));
+
+ aSplitted.append(aTop);
+ aSplitted.append(aBottom);
+ }
+ }
+ else
+ {
+ aSplitted.append(aCandidate);
+ }
+ }
+
+ if(aSplitted.count() != nPolyCount)
+ {
+ rPolyPolygon = aSplitted;
+ }
+ }
+
+ return bRetval;
+ }
+} // end of anonymous namespace
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace processor2d
+ {
+ Rectangle VclMetafileProcessor2D::impDumpToMetaFile(
+ const primitive2d::Primitive2DSequence& rContent,
+ GDIMetaFile& o_rContentMetafile)
+ {
+ // Prepare VDev, MetaFile and connections
+ OutputDevice* pLastOutputDevice = mpOutputDevice;
+ GDIMetaFile* pLastMetafile = mpMetaFile;
+ basegfx::B2DRange aPrimitiveRange(primitive2d::getB2DRangeFromPrimitive2DSequence(rContent, getViewInformation2D()));
+
+ // transform primitive range with current transformation (e.g shadow offset)
+ aPrimitiveRange.transform(maCurrentTransformation);
+
+ const Rectangle aPrimitiveRectangle(
+ basegfx::fround(aPrimitiveRange.getMinX()), basegfx::fround(aPrimitiveRange.getMinY()),
+ basegfx::fround(aPrimitiveRange.getMaxX()), basegfx::fround(aPrimitiveRange.getMaxY()));
+ VirtualDevice aContentVDev;
+ MapMode aNewMapMode(pLastOutputDevice->GetMapMode());
+
+ mpOutputDevice = &aContentVDev;
+ mpMetaFile = &o_rContentMetafile;
+ aContentVDev.EnableOutput(false);
+ aContentVDev.SetMapMode(pLastOutputDevice->GetMapMode());
+ o_rContentMetafile.Record(&aContentVDev);
+ aContentVDev.SetLineColor(pLastOutputDevice->GetLineColor());
+ aContentVDev.SetFillColor(pLastOutputDevice->GetFillColor());
+ aContentVDev.SetFont(pLastOutputDevice->GetFont());
+ aContentVDev.SetDrawMode(pLastOutputDevice->GetDrawMode());
+ aContentVDev.SetSettings(pLastOutputDevice->GetSettings());
+ aContentVDev.SetRefPoint(pLastOutputDevice->GetRefPoint());
+
+ // dump to MetaFile
+ process(rContent);
+
+ // cleanups
+ o_rContentMetafile.Stop();
+ o_rContentMetafile.WindStart();
+ aNewMapMode.SetOrigin(aPrimitiveRectangle.TopLeft());
+ o_rContentMetafile.SetPrefMapMode(aNewMapMode);
+ o_rContentMetafile.SetPrefSize(aPrimitiveRectangle.GetSize());
+ mpOutputDevice = pLastOutputDevice;
+ mpMetaFile = pLastMetafile;
+
+ return aPrimitiveRectangle;
+ }
+
+ void VclMetafileProcessor2D::impConvertFillGradientAttributeToVCLGradient(
+ Gradient& o_rVCLGradient,
+ const attribute::FillGradientAttribute& rFiGrAtt,
+ bool bIsTransparenceGradient)
+ {
+ if(bIsTransparenceGradient)
+ {
+ // it's about transparence channel intensities (black/white), do not use color modifier
+ o_rVCLGradient.SetStartColor(Color(rFiGrAtt.getStartColor()));
+ o_rVCLGradient.SetEndColor(Color(rFiGrAtt.getEndColor()));
+ }
+ else
+ {
+ // use color modifier to influence start/end color of gradient
+ o_rVCLGradient.SetStartColor(Color(maBColorModifierStack.getModifiedColor(rFiGrAtt.getStartColor())));
+ o_rVCLGradient.SetEndColor(Color(maBColorModifierStack.getModifiedColor(rFiGrAtt.getEndColor())));
+ }
+
+ o_rVCLGradient.SetAngle(static_cast< sal_uInt16 >(rFiGrAtt.getAngle() * (1.0 / F_PI1800)));
+ o_rVCLGradient.SetBorder(static_cast< sal_uInt16 >(rFiGrAtt.getBorder() * 100.0));
+ o_rVCLGradient.SetOfsX(static_cast< sal_uInt16 >(rFiGrAtt.getOffsetX() * 100.0));
+ o_rVCLGradient.SetOfsY(static_cast< sal_uInt16 >(rFiGrAtt.getOffsetY() * 100.0));
+ o_rVCLGradient.SetSteps(rFiGrAtt.getSteps());
+
+ // defaults for intensity; those were computed into the start/end colors already
+ o_rVCLGradient.SetStartIntensity(100);
+ o_rVCLGradient.SetEndIntensity(100);
+
+ switch(rFiGrAtt.getStyle())
+ {
+ default : // attribute::GRADIENTSTYLE_LINEAR :
+ {
+ o_rVCLGradient.SetStyle(GRADIENT_LINEAR);
+ break;
+ }
+ case attribute::GRADIENTSTYLE_AXIAL :
+ {
+ o_rVCLGradient.SetStyle(GRADIENT_AXIAL);
+ break;
+ }
+ case attribute::GRADIENTSTYLE_RADIAL :
+ {
+ o_rVCLGradient.SetStyle(GRADIENT_RADIAL);
+ break;
+ }
+ case attribute::GRADIENTSTYLE_ELLIPTICAL :
+ {
+ o_rVCLGradient.SetStyle(GRADIENT_ELLIPTICAL);
+ break;
+ }
+ case attribute::GRADIENTSTYLE_SQUARE :
+ {
+ o_rVCLGradient.SetStyle(GRADIENT_SQUARE);
+ break;
+ }
+ case attribute::GRADIENTSTYLE_RECT :
+ {
+ o_rVCLGradient.SetStyle(GRADIENT_RECT);
+ break;
+ }
+ }
+ }
+
+ void VclMetafileProcessor2D::impStartSvtGraphicFill(SvtGraphicFill* pSvtGraphicFill)
+ {
+ if(pSvtGraphicFill && !mnSvtGraphicFillCount)
+ {
+ SvMemoryStream aMemStm;
+
+ aMemStm << *pSvtGraphicFill;
+ mpMetaFile->AddAction(new MetaCommentAction("XPATHFILL_SEQ_BEGIN", 0, static_cast< const sal_uInt8* >(aMemStm.GetData()), aMemStm.Seek(STREAM_SEEK_TO_END)));
+ mnSvtGraphicFillCount++;
+ }
+ }
+
+ void VclMetafileProcessor2D::impEndSvtGraphicFill(SvtGraphicFill* pSvtGraphicFill)
+ {
+ if(pSvtGraphicFill && mnSvtGraphicFillCount)
+ {
+ mnSvtGraphicFillCount--;
+ mpMetaFile->AddAction(new MetaCommentAction("XPATHFILL_SEQ_END"));
+ delete pSvtGraphicFill;
+ }
+ }
+
+ SvtGraphicStroke* VclMetafileProcessor2D::impTryToCreateSvtGraphicStroke(
+ const basegfx::B2DPolygon& rB2DPolygon,
+ const basegfx::BColor* pColor,
+ const attribute::LineAttribute* pLineAttribute,
+ const attribute::StrokeAttribute* pStrokeAttribute,
+ const attribute::LineStartEndAttribute* pStart,
+ const attribute::LineStartEndAttribute* pEnd)
+ {
+ SvtGraphicStroke* pRetval = 0;
+
+ if(rB2DPolygon.count() && !mnSvtGraphicStrokeCount)
+ {
+ basegfx::BColor aStrokeColor;
+ basegfx::B2DPolyPolygon aStartArrow;
+ basegfx::B2DPolyPolygon aEndArrow;
+
+ if(pColor)
+ {
+ aStrokeColor = *pColor;
+ }
+ else if(pLineAttribute)
+ {
+ aStrokeColor = maBColorModifierStack.getModifiedColor(pLineAttribute->getColor());
+ }
+
+ // It IS needed to record the stroke color at all in the metafile,
+ // SvtGraphicStroke has NO entry for stroke color(!)
+ mpOutputDevice->SetLineColor(Color(aStrokeColor));
+
+ if(!rB2DPolygon.isClosed())
+ {
+ double fPolyLength(0.0);
+
+ if(pStart && pStart->isActive())
+ {
+ fPolyLength = basegfx::tools::getLength(rB2DPolygon);
+
+ aStartArrow = basegfx::tools::createAreaGeometryForLineStartEnd(
+ rB2DPolygon, pStart->getB2DPolyPolygon(), true, pStart->getWidth(),
+ fPolyLength, pStart->isCentered() ? 0.5 : 0.0, 0);
+ }
+
+ if(pEnd && pEnd->isActive())
+ {
+ if(basegfx::fTools::equalZero(fPolyLength))
+ {
+ fPolyLength = basegfx::tools::getLength(rB2DPolygon);
+ }
+
+ aEndArrow = basegfx::tools::createAreaGeometryForLineStartEnd(
+ rB2DPolygon, pEnd->getB2DPolyPolygon(), false, pEnd->getWidth(),
+ fPolyLength, pEnd->isCentered() ? 0.5 : 0.0, 0);
+ }
+ }
+
+ SvtGraphicStroke::JoinType eJoin(SvtGraphicStroke::joinNone);
+ SvtGraphicStroke::CapType eCap(SvtGraphicStroke::capButt);
+ double fLineWidth(0.0);
+ double fMiterLength(0.0);
+ SvtGraphicStroke::DashArray aDashArray;
+
+ if(pLineAttribute)
+ {
+ // pre-fill fLineWidth #119198# Need to apply maCurrentTransformation, too (!)
+ const basegfx::B2DVector aDiscreteUnit(maCurrentTransformation * basegfx::B2DVector(pLineAttribute->getWidth(), 0.0));
+ fLineWidth = aDiscreteUnit.getLength();
+
+ // pre-fill fMiterLength
+ fMiterLength = fLineWidth;
+
+ // get Join
+ switch(pLineAttribute->getLineJoin())
+ {
+ default : // basegfx::B2DLINEJOIN_NONE :
+ {
+ eJoin = SvtGraphicStroke::joinNone;
+ break;
+ }
+ case basegfx::B2DLINEJOIN_BEVEL :
+ {
+ eJoin = SvtGraphicStroke::joinBevel;
+ break;
+ }
+ case basegfx::B2DLINEJOIN_MIDDLE :
+ case basegfx::B2DLINEJOIN_MITER :
+ {
+ eJoin = SvtGraphicStroke::joinMiter;
+ // ATM 15 degrees is assumed
+ fMiterLength /= rtl::math::sin(M_PI * (15.0 / 360.0));
+ break;
+ }
+ case basegfx::B2DLINEJOIN_ROUND :
+ {
+ eJoin = SvtGraphicStroke::joinRound;
+ break;
+ }
+ }
+
+ // get stroke
+ switch(pLineAttribute->getLineCap())
+ {
+ default: /* com::sun::star::drawing::LineCap_BUTT */
+ {
+ eCap = SvtGraphicStroke::capButt;
+ break;
+ }
+ case com::sun::star::drawing::LineCap_ROUND:
+ {
+ eCap = SvtGraphicStroke::capRound;
+ break;
+ }
+ case com::sun::star::drawing::LineCap_SQUARE:
+ {
+ eCap = SvtGraphicStroke::capSquare;
+ break;
+ }
+ }
+ }
+
+ if(pStrokeAttribute)
+ {
+ // copy dash array
+ aDashArray = pStrokeAttribute->getDotDashArray();
+ }
+
+ // #i101734# apply current object transformation to created geometry.
+ // This is a partial fix. When a object transformation is used which
+ // e.g. contains a scaleX != scaleY, an unproportional scaling would
+ // have to be applied to the evtl. existing fat line. The current
+ // concept of PDF export and SvtGraphicStroke usage does simply not
+ // allow handling such definitions. The only clean way would be to
+ // add the transformation to SvtGraphicStroke and to handle it there
+ basegfx::B2DPolygon aB2DPolygon(rB2DPolygon);
+
+ aB2DPolygon.transform(maCurrentTransformation);
+ aStartArrow.transform(maCurrentTransformation);
+ aEndArrow.transform(maCurrentTransformation);
+
+ pRetval = new SvtGraphicStroke(
+ Polygon(aB2DPolygon),
+ PolyPolygon(aStartArrow),
+ PolyPolygon(aEndArrow),
+ mfCurrentUnifiedTransparence,
+ fLineWidth,
+ eCap,
+ eJoin,
+ fMiterLength,
+ aDashArray);
+ }
+
+ return pRetval;
+ }
+
+ void VclMetafileProcessor2D::impStartSvtGraphicStroke(SvtGraphicStroke* pSvtGraphicStroke)
+ {
+ if(pSvtGraphicStroke && !mnSvtGraphicStrokeCount)
+ {
+ SvMemoryStream aMemStm;
+
+ aMemStm << *pSvtGraphicStroke;
+ mpMetaFile->AddAction(new MetaCommentAction("XPATHSTROKE_SEQ_BEGIN", 0, static_cast< const sal_uInt8* >(aMemStm.GetData()), aMemStm.Seek(STREAM_SEEK_TO_END)));
+ mnSvtGraphicStrokeCount++;
+ }
+ }
+
+ void VclMetafileProcessor2D::impEndSvtGraphicStroke(SvtGraphicStroke* pSvtGraphicStroke)
+ {
+ if(pSvtGraphicStroke && mnSvtGraphicStrokeCount)
+ {
+ mnSvtGraphicStrokeCount--;
+ mpMetaFile->AddAction(new MetaCommentAction("XPATHSTROKE_SEQ_END"));
+ delete pSvtGraphicStroke;
+ }
+ }
+
+ // init static break iterator
+ uno::Reference< ::com::sun::star::i18n::XBreakIterator > VclMetafileProcessor2D::mxBreakIterator;
+
+ VclMetafileProcessor2D::VclMetafileProcessor2D(const geometry::ViewInformation2D& rViewInformation, OutputDevice& rOutDev)
+ : VclProcessor2D(rViewInformation, rOutDev),
+ mpMetaFile(rOutDev.GetConnectMetaFile()),
+ mnSvtGraphicFillCount(0),
+ mnSvtGraphicStrokeCount(0),
+ mfCurrentUnifiedTransparence(0.0),
+ mpPDFExtOutDevData(dynamic_cast< vcl::PDFExtOutDevData* >(rOutDev.GetExtOutDevData()))
+ {
+ OSL_ENSURE(rOutDev.GetConnectMetaFile(), "VclMetafileProcessor2D: Used on OutDev which has no MetaFile Target (!)");
+ // draw to logic coordinates, do not initialize maCurrentTransformation to viewTransformation
+ // but only to ObjectTransformation. Do not change MapMode of destination.
+ maCurrentTransformation = rViewInformation.getObjectTransformation();
+ }
+
+ VclMetafileProcessor2D::~VclMetafileProcessor2D()
+ {
+ // MapMode was not changed, no restore necessary
+ }
+
+ /***********************************************************************************************
+
+ Support of MetaCommentActions in the VclMetafileProcessor2D
+ Found MetaCommentActions and how they are supported:
+
+ XGRAD_SEQ_BEGIN, XGRAD_SEQ_END:
+
+ Used inside OutputDevice::DrawGradient to mark the start and end of a MetaGradientEx action.
+ It is used in various exporters/importers to have direct access to the gradient before it
+ is rendered by VCL (and thus fragmented to polygon color actions and others). On that base, e.g.
+ the Metafile to SdrObject import creates it's gradient objects.
+ Best (and safest) way to support it here is to use PRIMITIVE2D_ID_POLYPOLYGONGRADIENTPRIMITIVE2D,
+ map it back to the corresponding tools PolyPolygon and the Gradient and just call
+ OutputDevice::DrawGradient which creates the necessary compatible actions.
+
+ XPATHFILL_SEQ_BEGIN, XPATHFILL_SEQ_END:
+
+ Two producers, one is vcl/source/gdi/gdimtf.cxx, line 1273. There, it is transformed
+ inside GDIMetaFile::Rotate, nothing to take care of here.
+ The second producer is in graphics/svx/source/svdraw/impgrfll.cxx, line 374. This is used
+ with each incarnation of Imp_GraphicFill when a metafile is recorded, fillstyle is not
+ XFILL_NONE and not completely transparent. It creates a SvtGraphicFill and streams it
+ to the comment action. A closing end token is created in the destructor.
+ Usages of Imp_GraphicFill are in Do_Paint_Object-methods of SdrCircObj, SdrPathObj and
+ SdrRectObj.
+ The token users pick various actions from SvtGraphicFill, so it may need to be added for all kind
+ of filled objects, even simple colored polygons. It is added as extra information; the
+ Metafile actions between the two tokens are interpreted as output generated from those
+ fills. Thus, users have the choice to use the SvtGraphicFill info or the created output
+ actions.
+ Even for XFillTransparenceItem it is used, thus it may need to be supported in
+ UnifiedTransparencePrimitive2D, too, when interpreted as normally filled PolyPolygon.
+ Implemented for:
+ PRIMITIVE2D_ID_POLYPOLYGONBITMAPPRIMITIVE2D,
+ PRIMITIVE2D_ID_POLYPOLYGONHATCHPRIMITIVE2D,
+ PRIMITIVE2D_ID_POLYPOLYGONGRADIENTPRIMITIVE2D,
+ PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D,
+ and for PRIMITIVE2D_ID_UNIFIEDTRANSPARENCEPRIMITIVE2D when detected unified transparence
+
+ XPATHSTROKE_SEQ_BEGIN, XPATHSTROKE_SEQ_END:
+
+ Similar to pathfill, but using SvtGraphicStroke instead. It also has two producers where one
+ is also the GDIMetaFile::Rotate. Another user is MetaCommentAction::Move which modifies the
+ contained path accordingly.
+ The other one is SdrObject::Imp_DrawLineGeometry. It's done when MetaFile is set at OutDev and
+ only when geometry is a single polygon (!). I see no reason for that; in the PS exporter this
+ would hinder to make use of PolyPolygon strokes. I will need to add support at:
+ PRIMITIVE2D_ID_POLYGONHAIRLINEPRIMITIVE2D
+ PRIMITIVE2D_ID_POLYGONSTROKEPRIMITIVE2D
+ PRIMITIVE2D_ID_POLYGONSTROKEARROWPRIMITIVE2D
+ This can be done hierarchical, too.
+ Okay, base implementation done based on those three primitives.
+
+ FIELD_SEQ_BEGIN, FIELD_SEQ_END
+
+ Used from slideshow for URLs, created from diverse SvxField implementations inside
+ createBeginComment()/createEndComment(). createBeginComment() is used from editeng\impedit3.cxx
+ inside ImpEditEngine::Paint.
+ Created TextHierarchyFieldPrimitive2D and added needed infos there; it is an group primitive and wraps
+ text primitives (but is not limited to that). It contains the field type if special actions for the
+ support of FIELD_SEQ_BEGIN/END are needed; this is the case for Page and URL fields. If more is
+ needed, it may be supported there.
+ FIELD_SEQ_BEGIN;PageField
+ FIELD_SEQ_END
+ Okay, these are now completely supported by TextHierarchyFieldPrimitive2D. URL works, too.
+
+ XTEXT
+
+ XTEXT_EOC(i) end of character
+ XTEXT_EOW(i) end of word
+ XTEXT_EOS(i) end of sentence
+
+ this three are with index and are created with the help of a i18n::XBreakIterator in
+ ImplDrawWithComments. Simplifying, moving out text painting, reworking to create some
+ data structure for holding those TEXT infos.
+ Supported directly by TextSimplePortionPrimitive2D with adding a Locale to the basic text
+ primitive. In the MetaFileRenderer, the creation is now done (see below). This has the advantage
+ that this creations do not need to be done for all paints all the time. This would be
+ expensive since the BreakIterator and it's usage is expensive and for each paint also the
+ whole character stops would need to be created.
+ Created only for TextDecoratedPortionPrimitive2D due to XTEXT_EOL and XTEXT_EOP (see below)
+
+ XTEXT_EOL() end of line
+ XTEXT_EOP() end of paragraph
+
+ First try with boolean marks at TextDecoratedPortionPrimitive2D did not work too well,
+ i decided to solve it with structure. I added the TextHierarchyPrimitives for this,
+ namely:
+ - TextHierarchyLinePrimitive2D: Encapsulates single line
+ - TextHierarchyParagraphPrimitive2D: Encapsulates single paragraph
+ - TextHierarchyBlockPrimitive2D: encapsulates object texts (only one ATM)
+ Those are now supported in hierarchy. This means the MetaFile renderer will support them
+ by using them, reculrively using their content and adding MetaFile comments as needed.
+ This also means that when another text layouter will be used it will be necessary to
+ create/support the same HierarchyPrimitives to support users.
+ To transport the information using this hierarchy is best suited to all future needs;
+ the slideshow will be able to profit from it directly when using primitives; all other
+ renderers not interested in the text structure will just ignore the encapsulations.
+
+ XTEXT_PAINTSHAPE_BEGIN, XTEXT_PAINTSHAPE_END
+ Supported now by the TextHierarchyBlockPrimitive2D.
+
+ EPSReplacementGraphic:
+ Only used in goodies\source\filter.vcl\ieps\ieps.cxx and svx\source\xml\xmlgrhlp.cxx to
+ hold the original EPS which was imported in the same MetaFile as first 2 entries. Only
+ used to export the original again (if exists).
+ Not necessary to support with MetaFuleRenderer.
+
+ XTEXT_SCROLLRECT, XTEXT_PAINTRECT
+ Currently used to get extra MetaFile infos using GraphicExporter which again uses
+ SdrTextObj::GetTextScrollMetaFileAndRectangle(). ATM works with primitives since
+ the rectangle data is added directly by the GraphicsExporter as comment. Does not need
+ to be adapted at once.
+ When adapting later, the only user - the diashow - should directly use the provided
+ Anination infos in the appropriate primitives (e.g. AnimatedSwitchPrimitive2D)
+
+ PRNSPOOL_TRANSPARENTBITMAP_BEGIN, PRNSPOOL_TRANSPARENTBITMAP_END
+ VCL usage when printing PL -> THB. Okay, THB confirms that it is only used as
+ a fix (hack) while VCL printing. It is needed to not downscale a bitmap which
+ was explicitely created for the printer already again to some default maximum
+ bitmap sizes.
+ Nothing to do here for the primitive renderer.
+
+ Support for vcl::PDFExtOutDevData:
+ PL knows that SJ did that stuff, it's used to hold a pointer to PDFExtOutDevData at
+ the OutDev. When set, some extra data is written there. Trying simple PDF export and
+ watching if i get those infos.
+ Well, a PDF export does not use e.g. ImpEditEngine::Paint since the PdfFilter uses
+ the SdXImpressDocument::render and thus uses the VclMetafileProcessor2D. I will check
+ if i get a PDFExtOutDevData at the target output device.
+ Indeed, i get one. Checking what all may be done when that extra-device-info is there.
+
+ All in all i have to talk to SJ. I will need to emulate some of those actions, but
+ i need to discuss which ones.
+ In the future, all those infos would be taken from the primitive sequence anyways,
+ thus these extensions would potentially be temporary, too.
+ Discussed with SJ, added the necessary support and tested it. Details follow.
+
+ - In ImpEditEngine::Paint, paragraph infos and URL stuff is added.
+ Added in primitive MetaFile renderer.
+ Checking URL: Indeed, current version exports it, but it is missing in primitive
+ CWS version. Adding support.
+ Okay, URLs work. Checked, Done.
+
+ - UnoControlPDFExportContact is only created when PDFExtOutDevData is used at the
+ target and uno control data is created in UnoControlPDFExportContact::do_PaintObject.
+ This may be added in primitive MetaFile renderer.
+ Adding support...
+ OOps, the necessary helper stuff is in svx/source/form/formpdxexport.cxx in namespace
+ svxform. Have to talk to FS if this has to be like that. Especially since
+ ::vcl::PDFWriter::AnyWidget is filled out, which is already part of vcl.
+ Wrote an eMail to FS, he is on vacation currently. I see no reason why not to move
+ that stuff to somewhere else, maybe tools or svtools ?!? We will see...
+ Moved to toolkit, so i have to link against it. I tried VCL first, but it did
+ not work since VCLUnoHelper::CreateFont is unresolved in VCL (!). Other then the name
+ may imply, it is defined in toolkit (!). Since toolkit is linked against VCL itself,
+ the lowest move,ment plave is toolkit.
+ Checked form control export, it works well. Done.
+
+ - In goodies, in GraphicObject::Draw, when the used Graphic is linked, infos are
+ generated. I will need to check what happens here with primitives.
+ To support, use of GraphicPrimitive2D (PRIMITIVE2D_ID_GRAPHICPRIMITIVE2D) may be needed.
+ Added support, but feature is broken in main version, so i cannot test at all.
+ Writing a bug to CL (or SJ) and seeing what happens (#i80380#).
+ SJ took a look and we got it working. Tested VCL MetaFile Renderer based export,
+ as intended, the original file is exported. Works, Done.
+
+
+
+
+ To be done:
+
+ - Maybe there are more places to take care of for vcl::PDFExtOutDevData!
+
+
+
+ ****************************************************************************************************/
+
+ void VclMetafileProcessor2D::processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate)
+ {
+ switch(rCandidate.getPrimitive2DID())
+ {
+ case PRIMITIVE2D_ID_WRONGSPELLPRIMITIVE2D :
+ {
+ // directdraw of wrong spell primitive
+ // Ignore for VclMetafileProcessor2D, this is for printing and MetaFile recording only
+ break;
+ }
+ case PRIMITIVE2D_ID_GRAPHICPRIMITIVE2D :
+ {
+ const primitive2d::GraphicPrimitive2D& rGraphicPrimitive = static_cast< const primitive2d::GraphicPrimitive2D& >(rCandidate);
+ bool bUsingPDFExtOutDevData(false);
+ basegfx::B2DVector aTranslate, aScale;
+ static bool bSuppressPDFExtOutDevDataSupport(false);
+
+ if(mpPDFExtOutDevData && !bSuppressPDFExtOutDevDataSupport)
+ {
+ // emulate data handling from UnoControlPDFExportContact, original see
+ // svtools/source/graphic/grfmgr.cxx
+ const Graphic& rGraphic = rGraphicPrimitive.getGraphicObject().GetGraphic();
+
+ if(rGraphic.IsLink())
+ {
+ const GraphicAttr& rAttr = rGraphicPrimitive.getGraphicAttr();
+
+ if(!rAttr.IsSpecialDrawMode() && !rAttr.IsAdjusted())
+ {
+ const basegfx::B2DHomMatrix& rTransform = rGraphicPrimitive.getTransform();
+ double fRotate, fShearX;
+ rTransform.decompose(aScale, aTranslate, fRotate, fShearX);
+
+ if( basegfx::fTools::equalZero( fRotate ) && ( aScale.getX() > 0.0 ) && ( aScale.getY() > 0.0 ) )
+ {
+ bUsingPDFExtOutDevData = true;
+ mpPDFExtOutDevData->BeginGroup();
+ }
+ }
+ }
+ }
+
+ // process recursively and add MetaFile comment
+ process(rGraphicPrimitive.get2DDecomposition(getViewInformation2D()));
+
+ if(bUsingPDFExtOutDevData)
+ {
+ // emulate data handling from UnoControlPDFExportContact, original see
+ // svtools/source/graphic/grfmgr.cxx
+ const basegfx::B2DRange aCurrentRange(
+ aTranslate.getX(), aTranslate.getY(),
+ aTranslate.getX() + aScale.getX(), aTranslate.getY() + aScale.getY());
+ const Rectangle aCurrentRect(
+ sal_Int32(floor(aCurrentRange.getMinX())), sal_Int32(floor(aCurrentRange.getMinY())),
+ sal_Int32(ceil(aCurrentRange.getMaxX())), sal_Int32(ceil(aCurrentRange.getMaxY())));
+ const GraphicAttr& rAttr = rGraphicPrimitive.getGraphicAttr();
+ Rectangle aCropRect;
+
+ if(rAttr.IsCropped())
+ {
+ // calculate scalings between real image size and logic object size. This
+ // is necessary since the crop values are relative to original bitmap size
+ double fFactorX(1.0);
+ double fFactorY(1.0);
+
+ {
+ const MapMode aMapMode100thmm(MAP_100TH_MM);
+ const Size aBitmapSize(Application::GetDefaultDevice()->LogicToLogic(
+ rGraphicPrimitive.getGraphicObject().GetPrefSize(),
+ rGraphicPrimitive.getGraphicObject().GetPrefMapMode(), aMapMode100thmm));
+ const double fDivX(aBitmapSize.Width() - rAttr.GetLeftCrop() - rAttr.GetRightCrop());
+ const double fDivY(aBitmapSize.Height() - rAttr.GetTopCrop() - rAttr.GetBottomCrop());
+
+ if(!basegfx::fTools::equalZero(fDivX))
+ {
+ fFactorX = aScale.getX() / fDivX;
+ }
+
+ if(!basegfx::fTools::equalZero(fDivY))
+ {
+ fFactorY = aScale.getY() / fDivY;
+ }
+ }
+
+ // calculate crop range and rect
+ basegfx::B2DRange aCropRange;
+ aCropRange.expand(aCurrentRange.getMinimum() - basegfx::B2DPoint(rAttr.GetLeftCrop() * fFactorX, rAttr.GetTopCrop() * fFactorY));
+ aCropRange.expand(aCurrentRange.getMaximum() + basegfx::B2DPoint(rAttr.GetRightCrop() * fFactorX, rAttr.GetBottomCrop() * fFactorY));
+
+ aCropRect = Rectangle(
+ sal_Int32(floor(aCropRange.getMinX())), sal_Int32(floor(aCropRange.getMinY())),
+ sal_Int32(ceil(aCropRange.getMaxX())), sal_Int32(ceil(aCropRange.getMaxY())));
+ }
+
+ mpPDFExtOutDevData->EndGroup(rGraphicPrimitive.getGraphicObject().GetGraphic(),
+ rAttr.GetTransparency(),
+ aCurrentRect,
+ aCropRect);
+ }
+
+ break;
+ }
+ case PRIMITIVE2D_ID_CONTROLPRIMITIVE2D :
+ {
+ const primitive2d::ControlPrimitive2D& rControlPrimitive = static_cast< const primitive2d::ControlPrimitive2D& >(rCandidate);
+ const uno::Reference< awt::XControl >& rXControl(rControlPrimitive.getXControl());
+ bool bIsPrintableControl(false);
+
+ // find out if control is printable
+ if(rXControl.is())
+ {
+ try
+ {
+ uno::Reference< beans::XPropertySet > xModelProperties(rXControl->getModel(), uno::UNO_QUERY);
+ uno::Reference< beans::XPropertySetInfo > xPropertyInfo(xModelProperties.is()
+ ? xModelProperties->getPropertySetInfo()
+ : uno::Reference< beans::XPropertySetInfo >());
+ const ::rtl::OUString sPrintablePropertyName(RTL_CONSTASCII_USTRINGPARAM("Printable"));
+
+ if(xPropertyInfo.is() && xPropertyInfo->hasPropertyByName(sPrintablePropertyName))
+ {
+ OSL_VERIFY(xModelProperties->getPropertyValue(sPrintablePropertyName) >>= bIsPrintableControl);
+ }
+ }
+ catch(const uno::Exception&)
+ {
+ OSL_ENSURE(false, "VclMetafileProcessor2D: No access to printable flag of Control, caught an exception!");
+ }
+ }
+
+ // PDF export and printing only for printable controls
+ if(bIsPrintableControl)
+ {
+ const bool bPDFExport(mpPDFExtOutDevData && mpPDFExtOutDevData->GetIsExportFormFields());
+ bool bDoProcessRecursively(true);
+
+ if(bPDFExport)
+ {
+ // PDF export. Emulate data handling from UnoControlPDFExportContact
+ // I have now moved describePDFControl to toolkit, thus i can implement the PDF
+ // form control support now as follows
+ ::std::auto_ptr< ::vcl::PDFWriter::AnyWidget > pPDFControl;
+ ::toolkitform::describePDFControl( rXControl, pPDFControl, *mpPDFExtOutDevData );
+
+ if(pPDFControl.get())
+ {
+ // still need to fill in the location (is a class Rectangle)
+ const basegfx::B2DRange aRangeLogic(rControlPrimitive.getB2DRange(getViewInformation2D()));
+ const Rectangle aRectLogic(
+ (sal_Int32)floor(aRangeLogic.getMinX()), (sal_Int32)floor(aRangeLogic.getMinY()),
+ (sal_Int32)ceil(aRangeLogic.getMaxX()), (sal_Int32)ceil(aRangeLogic.getMaxY()));
+ pPDFControl->Location = aRectLogic;
+
+ Size aFontSize(pPDFControl->TextFont.GetSize());
+ aFontSize = mpOutputDevice->LogicToLogic(aFontSize, MapMode(MAP_POINT), mpOutputDevice->GetMapMode());
+ pPDFControl->TextFont.SetSize(aFontSize);
+
+ mpPDFExtOutDevData->BeginStructureElement(vcl::PDFWriter::Form);
+ mpPDFExtOutDevData->CreateControl(*pPDFControl.get());
+ mpPDFExtOutDevData->EndStructureElement();
+
+ // no normal paint needed (see original UnoControlPDFExportContact::do_PaintObject);
+ // do not process recursively
+ bDoProcessRecursively = false;
+ }
+ else
+ {
+ // PDF export did not work, try simple output.
+ // Fallback to printer output by not setting bDoProcessRecursively
+ // to false.
+ }
+ }
+
+ // #i93169# used flag the wrong way; true means that nothing was done yet
+ if(bDoProcessRecursively)
+ {
+ // printer output
+ try
+ {
+ // remember old graphics and create new
+ uno::Reference< awt::XView > xControlView(rXControl, uno::UNO_QUERY_THROW);
+ const uno::Reference< awt::XGraphics > xOriginalGraphics(xControlView->getGraphics());
+ const uno::Reference< awt::XGraphics > xNewGraphics(mpOutputDevice->CreateUnoGraphics());
+
+ if(xNewGraphics.is())
+ {
+ // link graphics and view
+ xControlView->setGraphics(xNewGraphics);
+
+ // get position
+ const basegfx::B2DHomMatrix aObjectToDiscrete(getViewInformation2D().getObjectToViewTransformation() * rControlPrimitive.getTransform());
+ const basegfx::B2DPoint aTopLeftDiscrete(aObjectToDiscrete * basegfx::B2DPoint(0.0, 0.0));
+
+ // draw it
+ xControlView->draw(basegfx::fround(aTopLeftDiscrete.getX()), basegfx::fround(aTopLeftDiscrete.getY()));
+ bDoProcessRecursively = false;
+
+ // restore original graphics
+ xControlView->setGraphics(xOriginalGraphics);
+ }
+ }
+ catch( const uno::Exception& )
+ {
+ OSL_ENSURE(false, "VclMetafileProcessor2D: Printing of Control failed, caught an exception!");
+ }
+ }
+
+ // process recursively if not done yet to export as decomposition (bitmap)
+ if(bDoProcessRecursively)
+ {
+ process(rControlPrimitive.get2DDecomposition(getViewInformation2D()));
+ }
+ }
+
+ break;
+ }
+ case PRIMITIVE2D_ID_TEXTHIERARCHYFIELDPRIMITIVE2D :
+ {
+ // support for FIELD_SEQ_BEGIN, FIELD_SEQ_END and URL. It wraps text primitives (but is not limited to)
+ // thus do the MetafileAction embedding stuff but just handle recursively.
+ const primitive2d::TextHierarchyFieldPrimitive2D& rFieldPrimitive = static_cast< const primitive2d::TextHierarchyFieldPrimitive2D& >(rCandidate);
+ static const ByteString aCommentStringCommon("FIELD_SEQ_BEGIN");
+ static const ByteString aCommentStringPage("FIELD_SEQ_BEGIN;PageField");
+ static const ByteString aCommentStringEnd("FIELD_SEQ_END");
+
+ switch(rFieldPrimitive.getType())
+ {
+ default : // case drawinglayer::primitive2d::FIELD_TYPE_COMMON :
+ {
+ mpMetaFile->AddAction(new MetaCommentAction(aCommentStringCommon));
+ break;
+ }
+ case drawinglayer::primitive2d::FIELD_TYPE_PAGE :
+ {
+ mpMetaFile->AddAction(new MetaCommentAction(aCommentStringPage));
+ break;
+ }
+ case drawinglayer::primitive2d::FIELD_TYPE_URL :
+ {
+ const rtl::OUString& rURL = rFieldPrimitive.getString();
+ const String aOldString(rURL);
+ mpMetaFile->AddAction(new MetaCommentAction(aCommentStringCommon, 0, reinterpret_cast< const sal_uInt8* >(aOldString.GetBuffer()), 2 * aOldString.Len()));
+ break;
+ }
+ }
+
+ // process recursively
+ const primitive2d::Primitive2DSequence rContent = rFieldPrimitive.get2DDecomposition(getViewInformation2D());
+ process(rContent);
+
+ // for the end comment the type is not relevant yet, they are all the same. Just add.
+ mpMetaFile->AddAction(new MetaCommentAction(aCommentStringEnd));
+
+ if(mpPDFExtOutDevData && drawinglayer::primitive2d::FIELD_TYPE_URL == rFieldPrimitive.getType())
+ {
+ // emulate data handling from ImpEditEngine::Paint
+ const basegfx::B2DRange aViewRange(primitive2d::getB2DRangeFromPrimitive2DSequence(rContent, getViewInformation2D()));
+ const Rectangle aRectLogic(
+ (sal_Int32)floor(aViewRange.getMinX()), (sal_Int32)floor(aViewRange.getMinY()),
+ (sal_Int32)ceil(aViewRange.getMaxX()), (sal_Int32)ceil(aViewRange.getMaxY()));
+ vcl::PDFExtOutDevBookmarkEntry aBookmark;
+ aBookmark.nLinkId = mpPDFExtOutDevData->CreateLink(aRectLogic);
+ aBookmark.aBookmark = rFieldPrimitive.getString();
+ std::vector< vcl::PDFExtOutDevBookmarkEntry >& rBookmarks = mpPDFExtOutDevData->GetBookmarks();
+ rBookmarks.push_back( aBookmark );
+ }
+
+ break;
+ }
+ case PRIMITIVE2D_ID_TEXTHIERARCHYLINEPRIMITIVE2D :
+ {
+ const primitive2d::TextHierarchyLinePrimitive2D& rLinePrimitive = static_cast< const primitive2d::TextHierarchyLinePrimitive2D& >(rCandidate);
+ static const ByteString aCommentString("XTEXT_EOL");
+
+ // process recursively and add MetaFile comment
+ process(rLinePrimitive.get2DDecomposition(getViewInformation2D()));
+ mpMetaFile->AddAction(new MetaCommentAction(aCommentString));
+
+ break;
+ }
+ case PRIMITIVE2D_ID_TEXTHIERARCHYBULLETPRIMITIVE2D :
+ {
+ // in Outliner::PaintBullet(), a MetafileComment for bullets is added, too. The
+ // "XTEXT_EOC" is used, use here, too.
+ const primitive2d::TextHierarchyBulletPrimitive2D& rBulletPrimitive = static_cast< const primitive2d::TextHierarchyBulletPrimitive2D& >(rCandidate);
+ static const ByteString aCommentString("XTEXT_EOC");
+
+ // process recursively and add MetaFile comment
+ process(rBulletPrimitive.get2DDecomposition(getViewInformation2D()));
+ mpMetaFile->AddAction(new MetaCommentAction(aCommentString));
+
+ break;
+ }
+ case PRIMITIVE2D_ID_TEXTHIERARCHYPARAGRAPHPRIMITIVE2D :
+ {
+ const primitive2d::TextHierarchyParagraphPrimitive2D& rParagraphPrimitive = static_cast< const primitive2d::TextHierarchyParagraphPrimitive2D& >(rCandidate);
+ static const ByteString aCommentString("XTEXT_EOP");
+
+ if(mpPDFExtOutDevData)
+ {
+ // emulate data handling from ImpEditEngine::Paint
+ mpPDFExtOutDevData->BeginStructureElement( vcl::PDFWriter::Paragraph );
+ }
+
+ // process recursively and add MetaFile comment
+ process(rParagraphPrimitive.get2DDecomposition(getViewInformation2D()));
+ mpMetaFile->AddAction(new MetaCommentAction(aCommentString));
+
+ if(mpPDFExtOutDevData)
+ {
+ // emulate data handling from ImpEditEngine::Paint
+ mpPDFExtOutDevData->EndStructureElement();
+ }
+
+ break;
+ }
+ case PRIMITIVE2D_ID_TEXTHIERARCHYBLOCKPRIMITIVE2D :
+ {
+ const primitive2d::TextHierarchyBlockPrimitive2D& rBlockPrimitive = static_cast< const primitive2d::TextHierarchyBlockPrimitive2D& >(rCandidate);
+ static const ByteString aCommentStringA("XTEXT_PAINTSHAPE_BEGIN");
+ static const ByteString aCommentStringB("XTEXT_PAINTSHAPE_END");
+
+ // add MetaFile comment, process recursively and add MetaFile comment
+ mpMetaFile->AddAction(new MetaCommentAction(aCommentStringA));
+ process(rBlockPrimitive.get2DDecomposition(getViewInformation2D()));
+ mpMetaFile->AddAction(new MetaCommentAction(aCommentStringB));
+
+ break;
+ }
+ case PRIMITIVE2D_ID_TEXTSIMPLEPORTIONPRIMITIVE2D :
+ case PRIMITIVE2D_ID_TEXTDECORATEDPORTIONPRIMITIVE2D :
+ {
+ // for supporting TEXT_ MetaFile actions there is more to do here; get the candidate
+ const primitive2d::TextSimplePortionPrimitive2D& rTextCandidate = static_cast< const primitive2d::TextSimplePortionPrimitive2D& >(rCandidate);
+ // const primitive2d::TextDecoratedPortionPrimitive2D* pTextDecoratedCandidate = dynamic_cast< const primitive2d::TextDecoratedPortionPrimitive2D* >(&rCandidate);
+
+ // Adapt evtl. used special DrawMode
+ const sal_uInt32 nOriginalDrawMode(mpOutputDevice->GetDrawMode());
+ adaptTextToFillDrawMode();
+
+ // directdraw of text simple portion; use default processing
+ RenderTextSimpleOrDecoratedPortionPrimitive2D(rTextCandidate);
+
+ // restore DrawMode
+ mpOutputDevice->SetDrawMode(nOriginalDrawMode);
+
+ // #i101169# if(pTextDecoratedCandidate)
+ {
+ // support for TEXT_ MetaFile actions only for decorated texts
+ if(!mxBreakIterator.is())
+ {
+ uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xMSF(::comphelper::getProcessServiceFactory());
+ mxBreakIterator.set(xMSF->createInstance(rtl::OUString::createFromAscii("com.sun.star.i18n.BreakIterator")), uno::UNO_QUERY);
+ }
+
+ if(mxBreakIterator.is())
+ {
+ const rtl::OUString& rTxt = rTextCandidate.getText();
+ const sal_Int32 nTextLength(rTextCandidate.getTextLength()); // rTxt.getLength());
+
+ if(nTextLength)
+ {
+ const ::com::sun::star::lang::Locale& rLocale = rTextCandidate.getLocale();
+ const sal_Int32 nTextPosition(rTextCandidate.getTextPosition());
+
+ sal_Int32 nDone;
+ sal_Int32 nNextCellBreak(mxBreakIterator->nextCharacters(rTxt, nTextPosition, rLocale, ::com::sun::star::i18n::CharacterIteratorMode::SKIPCELL, 0, nDone));
+ ::com::sun::star::i18n::Boundary nNextWordBoundary(mxBreakIterator->getWordBoundary(rTxt, nTextPosition, rLocale, ::com::sun::star::i18n::WordType::ANY_WORD, sal_True));
+ sal_Int32 nNextSentenceBreak(mxBreakIterator->endOfSentence(rTxt, nTextPosition, rLocale));
+ static const ByteString aCommentStringA("XTEXT_EOC");
+ static const ByteString aCommentStringB("XTEXT_EOW");
+ static const ByteString aCommentStringC("XTEXT_EOS");
+
+ for(sal_Int32 i(nTextPosition); i < nTextPosition + nTextLength; i++)
+ {
+ // create the entries for the respective break positions
+ if(i == nNextCellBreak)
+ {
+ mpMetaFile->AddAction(new MetaCommentAction(aCommentStringA, i - nTextPosition));
+ nNextCellBreak = mxBreakIterator->nextCharacters(rTxt, i, rLocale, ::com::sun::star::i18n::CharacterIteratorMode::SKIPCELL, 1, nDone);
+ }
+ if(i == nNextWordBoundary.endPos)
+ {
+ mpMetaFile->AddAction(new MetaCommentAction(aCommentStringB, i - nTextPosition));
+ nNextWordBoundary = mxBreakIterator->getWordBoundary(rTxt, i + 1, rLocale, ::com::sun::star::i18n::WordType::ANY_WORD, sal_True);
+ }
+ if(i == nNextSentenceBreak)
+ {
+ mpMetaFile->AddAction(new MetaCommentAction(aCommentStringC, i - nTextPosition));
+ nNextSentenceBreak = mxBreakIterator->endOfSentence(rTxt, i + 1, rLocale);
+ }
+ }
+ }
+ }
+ }
+
+ break;
+ }
+ case PRIMITIVE2D_ID_POLYGONHAIRLINEPRIMITIVE2D :
+ {
+ const primitive2d::PolygonHairlinePrimitive2D& rHairlinePrimitive = static_cast< const primitive2d::PolygonHairlinePrimitive2D& >(rCandidate);
+ const basegfx::B2DPolygon& rBasePolygon = rHairlinePrimitive.getB2DPolygon();
+
+ if(rBasePolygon.count() > (MAX_POLYGON_POINT_COUNT_METAFILE - 1))
+ {
+ // #i112245# Metafiles use tools Polygon and are not able to have more than 65535 points
+ // per polygon. If there are more, split the polygon in half and call recursively
+ basegfx::B2DPolygon aLeft, aRight;
+ splitLinePolygon(rBasePolygon, aLeft, aRight);
+ const primitive2d::PolygonHairlinePrimitive2D aPLeft(aLeft, rHairlinePrimitive.getBColor());
+ const primitive2d::PolygonHairlinePrimitive2D aPRight(aRight, rHairlinePrimitive.getBColor());
+
+ processBasePrimitive2D(aPLeft);
+ processBasePrimitive2D(aPRight);
+ }
+ else
+ {
+ // direct draw of hairline; use default processing
+ // support SvtGraphicStroke MetaCommentAction
+ const basegfx::BColor aLineColor(maBColorModifierStack.getModifiedColor(rHairlinePrimitive.getBColor()));
+ SvtGraphicStroke* pSvtGraphicStroke = impTryToCreateSvtGraphicStroke(
+ rHairlinePrimitive.getB2DPolygon(),
+ &aLineColor,
+ 0, 0, 0, 0);
+
+ impStartSvtGraphicStroke(pSvtGraphicStroke);
+ RenderPolygonHairlinePrimitive2D(static_cast< const primitive2d::PolygonHairlinePrimitive2D& >(rCandidate), false);
+ impEndSvtGraphicStroke(pSvtGraphicStroke);
+ }
+ break;
+ }
+ case PRIMITIVE2D_ID_POLYGONSTROKEPRIMITIVE2D :
+ {
+ const primitive2d::PolygonStrokePrimitive2D& rStrokePrimitive = static_cast< const primitive2d::PolygonStrokePrimitive2D& >(rCandidate);
+ const basegfx::B2DPolygon& rBasePolygon = rStrokePrimitive.getB2DPolygon();
+
+ if(rBasePolygon.count() > (MAX_POLYGON_POINT_COUNT_METAFILE - 1))
+ {
+ // #i112245# Metafiles use tools Polygon and are not able to have more than 65535 points
+ // per polygon. If there are more, split the polygon in half and call recursively
+ basegfx::B2DPolygon aLeft, aRight;
+ splitLinePolygon(rBasePolygon, aLeft, aRight);
+ const primitive2d::PolygonStrokePrimitive2D aPLeft(
+ aLeft, rStrokePrimitive.getLineAttribute(), rStrokePrimitive.getStrokeAttribute());
+ const primitive2d::PolygonStrokePrimitive2D aPRight(
+ aRight, rStrokePrimitive.getLineAttribute(), rStrokePrimitive.getStrokeAttribute());
+
+ processBasePrimitive2D(aPLeft);
+ processBasePrimitive2D(aPRight);
+ }
+ else
+ {
+ // support SvtGraphicStroke MetaCommentAction
+ SvtGraphicStroke* pSvtGraphicStroke = impTryToCreateSvtGraphicStroke(
+ rBasePolygon, 0,
+ &rStrokePrimitive.getLineAttribute(),
+ &rStrokePrimitive.getStrokeAttribute(),
+ 0, 0);
+
+ 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();
+ basegfx::B2DPolyPolygon aHairLinePolyPolygon;
+
+ if(0.0 == rStroke.getFullDotDashLen())
+ {
+ aHairLinePolyPolygon.append(rBasePolygon);
+ }
+ else
+ {
+ basegfx::tools::applyLineDashing(
+ rBasePolygon, rStroke.getDotDashArray(),
+ &aHairLinePolyPolygon, 0, rStroke.getFullDotDashLen());
+ }
+
+ const basegfx::BColor aHairlineColor(maBColorModifierStack.getModifiedColor(rLine.getColor()));
+ mpOutputDevice->SetLineColor(Color(aHairlineColor));
+ mpOutputDevice->SetFillColor();
+ aHairLinePolyPolygon.transform(maCurrentTransformation);
+
+ // #i113922# LineWidth needs to be transformed, too
+ const basegfx::B2DVector aDiscreteUnit(maCurrentTransformation * basegfx::B2DVector(rLine.getWidth(), 0.0));
+ const double fDiscreteLineWidth(aDiscreteUnit.getLength());
+
+ LineInfo aLineInfo(LINE_SOLID, basegfx::fround(fDiscreteLineWidth));
+ aLineInfo.SetLineJoin(rLine.getLineJoin());
+ aLineInfo.SetLineCap(rLine.getLineCap());
+
+ 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));
+ }
+ }
+ }
+ else
+ {
+ process(rCandidate.get2DDecomposition(getViewInformation2D()));
+ }
+
+ impEndSvtGraphicStroke(pSvtGraphicStroke);
+ }
+
+ break;
+ }
+ case PRIMITIVE2D_ID_POLYGONSTROKEARROWPRIMITIVE2D :
+ {
+ const primitive2d::PolygonStrokeArrowPrimitive2D& rStrokeArrowPrimitive = static_cast< const primitive2d::PolygonStrokeArrowPrimitive2D& >(rCandidate);
+ const basegfx::B2DPolygon& rBasePolygon = rStrokeArrowPrimitive.getB2DPolygon();
+
+ if(rBasePolygon.count() > (MAX_POLYGON_POINT_COUNT_METAFILE - 1))
+ {
+ // #i112245# Metafiles use tools Polygon and are not able to have more than 65535 points
+ // per polygon. If there are more, split the polygon in half and call recursively
+ basegfx::B2DPolygon aLeft, aRight;
+ splitLinePolygon(rBasePolygon, aLeft, aRight);
+ const attribute::LineStartEndAttribute aEmpty;
+ const primitive2d::PolygonStrokeArrowPrimitive2D aPLeft(
+ aLeft,
+ rStrokeArrowPrimitive.getLineAttribute(),
+ rStrokeArrowPrimitive.getStrokeAttribute(),
+ rStrokeArrowPrimitive.getStart(),
+ aEmpty);
+ const primitive2d::PolygonStrokeArrowPrimitive2D aPRight(
+ aRight,
+ rStrokeArrowPrimitive.getLineAttribute(),
+ rStrokeArrowPrimitive.getStrokeAttribute(),
+ aEmpty,
+ rStrokeArrowPrimitive.getEnd());
+
+ processBasePrimitive2D(aPLeft);
+ processBasePrimitive2D(aPRight);
+ }
+ else
+ {
+ // support SvtGraphicStroke MetaCommentAction
+ SvtGraphicStroke* pSvtGraphicStroke = impTryToCreateSvtGraphicStroke(
+ rBasePolygon, 0,
+ &rStrokeArrowPrimitive.getLineAttribute(),
+ &rStrokeArrowPrimitive.getStrokeAttribute(),
+ &rStrokeArrowPrimitive.getStart(),
+ &rStrokeArrowPrimitive.getEnd());
+
+ impStartSvtGraphicStroke(pSvtGraphicStroke);
+ process(rCandidate.get2DDecomposition(getViewInformation2D()));
+ impEndSvtGraphicStroke(pSvtGraphicStroke);
+ }
+
+ break;
+ }
+ case PRIMITIVE2D_ID_BITMAPPRIMITIVE2D :
+ {
+ // direct draw of transformed BitmapEx primitive; use default processing
+ RenderBitmapPrimitive2D(static_cast< const primitive2d::BitmapPrimitive2D& >(rCandidate));
+ break;
+ }
+ case PRIMITIVE2D_ID_POLYPOLYGONBITMAPPRIMITIVE2D :
+ {
+ // need to handle PolyPolygonBitmapPrimitive2D here to support XPATHFILL_SEQ_BEGIN/XPATHFILL_SEQ_END
+ const primitive2d::PolyPolygonBitmapPrimitive2D& rBitmapCandidate = static_cast< const primitive2d::PolyPolygonBitmapPrimitive2D& >(rCandidate);
+ basegfx::B2DPolyPolygon aLocalPolyPolygon(rBitmapCandidate.getB2DPolyPolygon());
+
+ if(fillPolyPolygonNeededToBeSplit(aLocalPolyPolygon))
+ {
+ // #i112245# Metafiles use tools Polygon and are not able to have more than 65535 points
+ // per polygon. If there are more use the splitted polygon and call recursively
+ const primitive2d::PolyPolygonBitmapPrimitive2D aSplitted(
+ aLocalPolyPolygon,
+ rBitmapCandidate.getFillBitmap());
+
+ processBasePrimitive2D(aSplitted);
+ }
+ else
+ {
+ SvtGraphicFill* pSvtGraphicFill = 0;
+
+ if(!mnSvtGraphicFillCount && aLocalPolyPolygon.count())
+ {
+ aLocalPolyPolygon.transform(maCurrentTransformation);
+ // calculate transformation. Get real object size, all values in FillBitmapAttribute
+ // are relative to the unified object
+ const attribute::FillBitmapAttribute& rFillBitmapAttribute = rBitmapCandidate .getFillBitmap();
+ const basegfx::B2DRange aOutlineRange(basegfx::tools::getRange(aLocalPolyPolygon));
+ const basegfx::B2DVector aOutlineSize(aOutlineRange.getRange());
+
+ // get absolute values
+ const basegfx::B2DVector aFillBitmapSize(rFillBitmapAttribute.getSize() * aOutlineSize);
+ const basegfx::B2DPoint aFillBitmapTopLeft(rFillBitmapAttribute.getTopLeft() * aOutlineSize);
+
+ // the scaling needs scale from pixel to logic coordinate system
+ const BitmapEx& rBitmapEx = rFillBitmapAttribute.getBitmapEx();
+ Size aBmpSizePixel(rBitmapEx.GetSizePixel());
+
+ if(!aBmpSizePixel.Width())
+ {
+ aBmpSizePixel.Width() = 1;
+ }
+
+ if(!aBmpSizePixel.Height())
+ {
+ aBmpSizePixel.Height() = 1;
+ }
+
+ // setup transformation like in impgrfll
+ SvtGraphicFill::Transform aTransform;
+
+ // scale values are divided by bitmap pixel sizes
+ aTransform.matrix[0] = aFillBitmapSize.getX() / aBmpSizePixel.Width();
+ aTransform.matrix[4] = aFillBitmapSize.getY() / aBmpSizePixel.Height();
+
+ // translates are absolute
+ aTransform.matrix[2] = aFillBitmapTopLeft.getX();
+ aTransform.matrix[5] = aFillBitmapTopLeft.getY();
+
+ // setup fill graphic like in impgrfll
+ Graphic aFillGraphic = Graphic(rBitmapEx);
+ aFillGraphic.SetPrefMapMode(MapMode(MAP_PIXEL));
+ aFillGraphic.SetPrefSize(aBmpSizePixel);
+
+ pSvtGraphicFill = new SvtGraphicFill(
+ PolyPolygon(aLocalPolyPolygon),
+ Color(),
+ 0.0,
+ SvtGraphicFill::fillEvenOdd,
+ SvtGraphicFill::fillTexture,
+ aTransform,
+ rFillBitmapAttribute.getTiling(),
+ SvtGraphicFill::hatchSingle,
+ Color(),
+ SvtGraphicFill::gradientLinear,
+ Color(),
+ Color(),
+ 0,
+ aFillGraphic);
+ }
+
+ // Do use decomposition; encapsulate with SvtGraphicFill
+ impStartSvtGraphicFill(pSvtGraphicFill);
+ process(rCandidate.get2DDecomposition(getViewInformation2D()));
+ impEndSvtGraphicFill(pSvtGraphicFill);
+ }
+
+ break;
+ }
+ case PRIMITIVE2D_ID_POLYPOLYGONHATCHPRIMITIVE2D :
+ {
+ // need to handle PolyPolygonHatchPrimitive2D here to support XPATHFILL_SEQ_BEGIN/XPATHFILL_SEQ_END
+ const primitive2d::PolyPolygonHatchPrimitive2D& rHatchCandidate = static_cast< const primitive2d::PolyPolygonHatchPrimitive2D& >(rCandidate);
+ const attribute::FillHatchAttribute& rFillHatchAttribute = rHatchCandidate.getFillHatch();
+ basegfx::B2DPolyPolygon aLocalPolyPolygon(rHatchCandidate.getB2DPolyPolygon());
+
+ // #i112245# Metafiles use tools Polygon and are not able to have more than 65535 points
+ // per polygon. Split polygon until there are less than that
+ while(fillPolyPolygonNeededToBeSplit(aLocalPolyPolygon))
+ ;
+
+ if(rFillHatchAttribute.isFillBackground())
+ {
+ // with fixing #i111954# (see below) the possible background
+ // fill of a hatched object was lost.Generate a background fill
+ // primitive and render it
+ const primitive2d::Primitive2DReference xBackground(
+ new primitive2d::PolyPolygonColorPrimitive2D(
+ aLocalPolyPolygon,
+ rHatchCandidate.getBackgroundColor()));
+
+ process(primitive2d::Primitive2DSequence(&xBackground, 1));
+ }
+
+ SvtGraphicFill* pSvtGraphicFill = 0;
+ aLocalPolyPolygon.transform(maCurrentTransformation);
+
+ if(!mnSvtGraphicFillCount && aLocalPolyPolygon.count())
+ {
+ // re-create a VCL hatch as base data
+ SvtGraphicFill::HatchType eHatch(SvtGraphicFill::hatchSingle);
+
+ switch(rFillHatchAttribute.getStyle())
+ {
+ default: // attribute::HATCHSTYLE_SINGLE :
+ {
+ eHatch = SvtGraphicFill::hatchSingle;
+ break;
+ }
+ case attribute::HATCHSTYLE_DOUBLE :
+ {
+ eHatch = SvtGraphicFill::hatchDouble;
+ break;
+ }
+ case attribute::HATCHSTYLE_TRIPLE :
+ {
+ eHatch = SvtGraphicFill::hatchTriple;
+ break;
+ }
+ }
+
+ SvtGraphicFill::Transform aTransform;
+
+ // scale
+ aTransform.matrix[0] *= rFillHatchAttribute.getDistance();
+ aTransform.matrix[4] *= rFillHatchAttribute.getDistance();
+
+ // rotate (was never correct in impgrfll anyways, use correct angle now)
+ aTransform.matrix[0] *= cos(rFillHatchAttribute.getAngle());
+ aTransform.matrix[1] *= -sin(rFillHatchAttribute.getAngle());
+ aTransform.matrix[3] *= sin(rFillHatchAttribute.getAngle());
+ aTransform.matrix[4] *= cos(rFillHatchAttribute.getAngle());
+
+ pSvtGraphicFill = new SvtGraphicFill(
+ PolyPolygon(aLocalPolyPolygon),
+ Color(),
+ 0.0,
+ SvtGraphicFill::fillEvenOdd,
+ SvtGraphicFill::fillHatch,
+ aTransform,
+ false,
+ eHatch,
+ Color(rFillHatchAttribute.getColor()),
+ SvtGraphicFill::gradientLinear,
+ Color(),
+ Color(),
+ 0,
+ Graphic());
+ }
+
+ // Do use decomposition; encapsulate with SvtGraphicFill
+ impStartSvtGraphicFill(pSvtGraphicFill);
+
+ // #i111954# do NOT use decomposition, but use direct VCL-command
+ // process(rCandidate.get2DDecomposition(getViewInformation2D()));
+ const PolyPolygon aToolsPolyPolygon(aLocalPolyPolygon);
+ const HatchStyle aHatchStyle(
+ attribute::HATCHSTYLE_SINGLE == rFillHatchAttribute.getStyle() ? HATCH_SINGLE :
+ attribute::HATCHSTYLE_DOUBLE == rFillHatchAttribute.getStyle() ? HATCH_DOUBLE :
+ HATCH_TRIPLE);
+
+ mpOutputDevice->DrawHatch(aToolsPolyPolygon,
+ Hatch(aHatchStyle,
+ Color(rFillHatchAttribute.getColor()),
+ basegfx::fround(rFillHatchAttribute.getDistance()),
+ basegfx::fround(rFillHatchAttribute.getAngle() / F_PI1800)));
+
+ impEndSvtGraphicFill(pSvtGraphicFill);
+
+ break;
+ }
+ case PRIMITIVE2D_ID_POLYPOLYGONGRADIENTPRIMITIVE2D :
+ {
+ basegfx::B2DVector aScale, aTranslate;
+ double fRotate, fShearX;
+
+ maCurrentTransformation.decompose(aScale, aTranslate, fRotate, fShearX);
+
+ if(!basegfx::fTools::equalZero(fRotate) || !basegfx::fTools::equalZero(fShearX))
+ {
+ // #121185# When rotation or shear is used, a VCL Gradient cannot be used directly.
+ // This is because VCL Gradient mechanism does *not* support to rotate the gradient
+ // with objects and this case is not expressable in a Metafile (and cannot be added
+ // since the FileFormats used, e.g. *.wmf, do not support it either).
+ // Such cases happen when a graphic object uses a Metafile as graphic information or
+ // a fill style definition uses a Metafile. In this cases the graphic content is
+ // rotated with the graphic or filled object; this is not supported by the target
+ // format of this conversion renderer - Metafiles.
+ // To solve this, not a Gradient is written, but the decomposition of this object
+ // is written to the Metafile. This is the PolyPolygons building the gradient fill.
+ // These will need more space and time, but the result will be as if the Gradient
+ // was rotated with the object.
+ // This mechanism is used by all exporters still not using Primtives (e.g. Print,
+ // Slideshow, Export rto PDF, export to Picture, ...) but relying on Metafile
+ // transfers. One more reason to *change* these to primitives.
+ // BTW: One more example how useful the principles of primitives are; the decomposition
+ // is by definition a simpler, maybe more expensive representation of the same content.
+ process(rCandidate.get2DDecomposition(getViewInformation2D()));
+ }
+ else
+ {
+ const primitive2d::PolyPolygonGradientPrimitive2D& rGradientCandidate = static_cast< const primitive2d::PolyPolygonGradientPrimitive2D& >(rCandidate);
+ basegfx::B2DPolyPolygon aLocalPolyPolygon(rGradientCandidate.getB2DPolyPolygon());
+
+ // #i112245# Metafiles use tools Polygon and are not able to have more than 65535 points
+ // per polygon. Split polygon until there are less than that
+ while(fillPolyPolygonNeededToBeSplit(aLocalPolyPolygon))
+ ;
+
+ // for support of MetaCommentActions of the form XGRAD_SEQ_BEGIN, XGRAD_SEQ_END
+ // it is safest to use the VCL OutputDevice::DrawGradient method which creates those.
+ // re-create a VCL-gradient from FillGradientPrimitive2D and the needed tools PolyPolygon
+ Gradient aVCLGradient;
+ impConvertFillGradientAttributeToVCLGradient(aVCLGradient, rGradientCandidate.getFillGradient(), false);
+ aLocalPolyPolygon.transform(maCurrentTransformation);
+
+ // #i82145# ATM VCL printing of gradients using curved shapes does not work,
+ // i submitted the bug with the given ID to THB. When that task is fixed it is
+ // necessary to again remove this subdivision since it decreases possible
+ // printing quality (not even resolution-dependent for now). THB will tell
+ // me when that task is fixed in the master
+ const PolyPolygon aToolsPolyPolygon(basegfx::tools::adaptiveSubdivideByAngle(aLocalPolyPolygon));
+
+ // XPATHFILL_SEQ_BEGIN/XPATHFILL_SEQ_END support
+ SvtGraphicFill* pSvtGraphicFill = 0;
+
+ if(!mnSvtGraphicFillCount && aLocalPolyPolygon.count())
+ {
+ // setup gradient stuff like in like in impgrfll
+ SvtGraphicFill::GradientType eGrad(SvtGraphicFill::gradientLinear);
+
+ switch(aVCLGradient.GetStyle())
+ {
+ default : // GRADIENT_LINEAR:
+ case GRADIENT_AXIAL:
+ eGrad = SvtGraphicFill::gradientLinear;
+ break;
+ case GRADIENT_RADIAL:
+ case GRADIENT_ELLIPTICAL:
+ eGrad = SvtGraphicFill::gradientRadial;
+ break;
+ case GRADIENT_SQUARE:
+ case GRADIENT_RECT:
+ eGrad = SvtGraphicFill::gradientRectangular;
+ break;
+ }
+
+ pSvtGraphicFill = new SvtGraphicFill(
+ aToolsPolyPolygon,
+ Color(),
+ 0.0,
+ SvtGraphicFill::fillEvenOdd,
+ SvtGraphicFill::fillGradient,
+ SvtGraphicFill::Transform(),
+ false,
+ SvtGraphicFill::hatchSingle,
+ Color(),
+ eGrad,
+ aVCLGradient.GetStartColor(),
+ aVCLGradient.GetEndColor(),
+ aVCLGradient.GetSteps(),
+ Graphic());
+ }
+
+ // call VCL directly; encapsulate with SvtGraphicFill
+ impStartSvtGraphicFill(pSvtGraphicFill);
+ mpOutputDevice->DrawGradient(aToolsPolyPolygon, aVCLGradient);
+ impEndSvtGraphicFill(pSvtGraphicFill);
+
+ // NO usage of common own gradient randerer, not used ATM for VCL MetaFile, see text above
+ // RenderPolyPolygonGradientPrimitive2D(static_cast< const primitive2d::PolyPolygonGradientPrimitive2D& >(rCandidate));
+ }
+
+ break;
+ }
+ case PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D :
+ {
+ const primitive2d::PolyPolygonColorPrimitive2D& rPolygonCandidate(static_cast< const primitive2d::PolyPolygonColorPrimitive2D& >(rCandidate));
+ basegfx::B2DPolyPolygon aLocalPolyPolygon(rPolygonCandidate.getB2DPolyPolygon());
+
+ // #i112245# Metafiles use tools Polygon and are not able to have more than 65535 points
+ // per polygon. Split polygon until there are less than that
+ while(fillPolyPolygonNeededToBeSplit(aLocalPolyPolygon))
+ ;
+
+ const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(rPolygonCandidate.getBColor()));
+ aLocalPolyPolygon.transform(maCurrentTransformation);
+
+ // XPATHFILL_SEQ_BEGIN/XPATHFILL_SEQ_END support
+ SvtGraphicFill* pSvtGraphicFill = 0;
+
+ if(!mnSvtGraphicFillCount && aLocalPolyPolygon.count())
+ {
+ // setup simple color fill stuff like in impgrfll
+ pSvtGraphicFill = new SvtGraphicFill(
+ PolyPolygon(aLocalPolyPolygon),
+ Color(aPolygonColor),
+ 0.0,
+ SvtGraphicFill::fillEvenOdd,
+ SvtGraphicFill::fillSolid,
+ SvtGraphicFill::Transform(),
+ false,
+ SvtGraphicFill::hatchSingle,
+ Color(),
+ SvtGraphicFill::gradientLinear,
+ Color(),
+ Color(),
+ 0,
+ Graphic());
+ }
+
+ // set line and fill color
+ mpOutputDevice->SetFillColor(Color(aPolygonColor));
+ mpOutputDevice->SetLineColor();
+
+ // call VCL directly; encapsulate with SvtGraphicFill
+ impStartSvtGraphicFill(pSvtGraphicFill);
+ mpOutputDevice->DrawPolyPolygon(aLocalPolyPolygon);
+ impEndSvtGraphicFill(pSvtGraphicFill);
+
+ break;
+ }
+ case PRIMITIVE2D_ID_METAFILEPRIMITIVE2D :
+ {
+ static bool bUseMetaFilePrimitiveDecomposition(true);
+
+ if(bUseMetaFilePrimitiveDecomposition)
+ {
+ // use new Metafile decomposition
+ process(rCandidate.get2DDecomposition(getViewInformation2D()));
+ }
+ else
+ {
+ // direct draw of MetaFile, use default pocessing
+ RenderMetafilePrimitive2D(static_cast< const primitive2d::MetafilePrimitive2D& >(rCandidate));
+ }
+
+ break;
+ }
+ case PRIMITIVE2D_ID_MASKPRIMITIVE2D :
+ {
+ // mask group. Special handling for MetaFiles.
+ const primitive2d::MaskPrimitive2D& rMaskCandidate = static_cast< const primitive2d::MaskPrimitive2D& >(rCandidate);
+
+ if(rMaskCandidate.getChildren().hasElements())
+ {
+ basegfx::B2DPolyPolygon aMask(rMaskCandidate.getMask());
+
+ if(aMask.count())
+ {
+ // prepare new mask polygon and rescue current one
+ aMask.transform(maCurrentTransformation);
+ const basegfx::B2DPolyPolygon aLastClipPolyPolygon(maClipPolyPolygon);
+
+ if(maClipPolyPolygon.count())
+ {
+ // there is already a clip polygon set; build clipped union of
+ // current mask polygon and new one
+ maClipPolyPolygon = basegfx::tools::clipPolyPolygonOnPolyPolygon(
+ aMask,
+ maClipPolyPolygon,
+ true, // #i106516# we want the inside of aMask, not the outside
+ false);
+ }
+ else
+ {
+ // use mask directly
+ maClipPolyPolygon = aMask;
+ }
+
+ if(maClipPolyPolygon.count())
+ {
+ // set VCL clip region; subdivide before conversion to tools polygon. Subdivision necessary (!)
+ // Removed subdivision and fixed in Region::ImplPolyPolyRegionToBandRegionFunc() in VCL where
+ // the ClipRegion is built from the Polygon. A AdaptiveSubdivide on the source polygon was missing there
+ mpOutputDevice->Push(PUSH_CLIPREGION);
+ //mpOutputDevice->SetClipRegion(Region(PolyPolygon(basegfx::tools::adaptiveSubdivideByAngle(maClipPolyPolygon))));
+ //mpOutputDevice->SetClipRegion(Region(PolyPolygon(maClipPolyPolygon)));
+ mpOutputDevice->SetClipRegion(Region(maClipPolyPolygon));
+ }
+
+ // recursively paint content
+ process(rMaskCandidate.getChildren());
+
+ if(maClipPolyPolygon.count())
+ {
+ // restore VCL clip region
+ mpOutputDevice->Pop();
+ }
+
+ // restore to rescued clip polygon
+ maClipPolyPolygon = aLastClipPolyPolygon;
+ }
+ else
+ {
+ // no mask, no clipping. recursively paint content
+ process(rMaskCandidate.getChildren());
+ }
+ }
+
+ break;
+ }
+ case PRIMITIVE2D_ID_MODIFIEDCOLORPRIMITIVE2D :
+ {
+ // modified color group. Force output to unified color. Use default pocessing.
+ RenderModifiedColorPrimitive2D(static_cast< const primitive2d::ModifiedColorPrimitive2D& >(rCandidate));
+ break;
+ }
+ case PRIMITIVE2D_ID_HIDDENGEOMETRYPRIMITIVE2D :
+ {
+ // HiddenGeometryPrimitive2D; to rebuilt the old MetaFile creation, it is necessary to
+ // not ignore them (as it was thought), but to add a MetaFile entry for them.
+ basegfx::B2DRange aInvisibleRange(rCandidate.getB2DRange(getViewInformation2D()));
+
+ if(!aInvisibleRange.isEmpty())
+ {
+ aInvisibleRange.transform(maCurrentTransformation);
+ const Rectangle aRectLogic(
+ (sal_Int32)floor(aInvisibleRange.getMinX()), (sal_Int32)floor(aInvisibleRange.getMinY()),
+ (sal_Int32)ceil(aInvisibleRange.getMaxX()), (sal_Int32)ceil(aInvisibleRange.getMaxY()));
+
+ mpOutputDevice->SetFillColor();
+ mpOutputDevice->SetLineColor();
+ mpOutputDevice->DrawRect(aRectLogic);
+ }
+
+ break;
+ }
+ case PRIMITIVE2D_ID_UNIFIEDTRANSPARENCEPRIMITIVE2D :
+ {
+ // for metafile: Need to examine what the pure vcl version is doing here actually
+ // - uses DrawTransparent with metafile for content and a gradient
+ // - uses DrawTransparent for single PolyPoylgons directly. Can be detected by
+ // checking the content for single PolyPolygonColorPrimitive2D
+ const primitive2d::UnifiedTransparencePrimitive2D& rUniTransparenceCandidate = static_cast< const primitive2d::UnifiedTransparencePrimitive2D& >(rCandidate);
+ const primitive2d::Primitive2DSequence rContent = rUniTransparenceCandidate.getChildren();
+
+ if(rContent.hasElements())
+ {
+ if(0.0 == rUniTransparenceCandidate.getTransparence())
+ {
+ // not transparent at all, use content
+ process(rUniTransparenceCandidate.getChildren());
+ }
+ else if(rUniTransparenceCandidate.getTransparence() > 0.0 && rUniTransparenceCandidate.getTransparence() < 1.0)
+ {
+ // try to identify a single PolyPolygonColorPrimitive2D in the
+ // content part of the transparence primitive
+ const primitive2d::PolyPolygonColorPrimitive2D* pPoPoColor = 0;
+ static bool bForceToMetafile(false);
+
+ if(!bForceToMetafile && 1 == rContent.getLength())
+ {
+ const primitive2d::Primitive2DReference xReference(rContent[0]);
+ pPoPoColor = dynamic_cast< const primitive2d::PolyPolygonColorPrimitive2D* >(xReference.get());
+ }
+
+ // PolyPolygonGradientPrimitive2D, PolyPolygonHatchPrimitive2D and
+ // PolyPolygonBitmapPrimitive2D are derived from PolyPolygonColorPrimitive2D.
+ // Check also for correct ID to exclude derived implementations
+ if(pPoPoColor && PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D == pPoPoColor->getPrimitive2DID())
+ {
+ // single transparent PolyPolygon identified, use directly
+ const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(pPoPoColor->getBColor()));
+ basegfx::B2DPolyPolygon aLocalPolyPolygon(pPoPoColor->getB2DPolyPolygon());
+
+ // #i112245# Metafiles use tools Polygon and are not able to have more than 65535 points
+ // per polygon. Split polygon until there are less than that
+ while(fillPolyPolygonNeededToBeSplit(aLocalPolyPolygon))
+ ;
+
+ // now transform
+ aLocalPolyPolygon.transform(maCurrentTransformation);
+
+ // XPATHFILL_SEQ_BEGIN/XPATHFILL_SEQ_END support
+ SvtGraphicFill* pSvtGraphicFill = 0;
+
+ if(!mnSvtGraphicFillCount && aLocalPolyPolygon.count())
+ {
+ // setup simple color with transparence fill stuff like in impgrfll
+ pSvtGraphicFill = new SvtGraphicFill(
+ PolyPolygon(aLocalPolyPolygon),
+ Color(aPolygonColor),
+ rUniTransparenceCandidate.getTransparence(),
+ SvtGraphicFill::fillEvenOdd,
+ SvtGraphicFill::fillSolid,
+ SvtGraphicFill::Transform(),
+ false,
+ SvtGraphicFill::hatchSingle,
+ Color(),
+ SvtGraphicFill::gradientLinear,
+ Color(),
+ Color(),
+ 0,
+ Graphic());
+ }
+
+ // set line and fill color
+ const sal_uInt16 nTransPercentVcl((sal_uInt16)basegfx::fround(rUniTransparenceCandidate.getTransparence() * 100.0));
+ mpOutputDevice->SetFillColor(Color(aPolygonColor));
+ mpOutputDevice->SetLineColor();
+
+ // call VCL directly; encapsulate with SvtGraphicFill
+ impStartSvtGraphicFill(pSvtGraphicFill);
+ mpOutputDevice->DrawTransparent(
+ PolyPolygon(aLocalPolyPolygon),
+ nTransPercentVcl);
+ impEndSvtGraphicFill(pSvtGraphicFill);
+ }
+ else
+ {
+ // svae old mfCurrentUnifiedTransparence and set new one
+ // so that contained SvtGraphicStroke may use the current one
+ const double fLastCurrentUnifiedTransparence(mfCurrentUnifiedTransparence);
+ // #i105377# paint the content metafile opaque as the transparency gets
+ // split of into the gradient below
+ // mfCurrentUnifiedTransparence = rUniTransparenceCandidate.getTransparence();
+ mfCurrentUnifiedTransparence = 0;
+
+ // various content, create content-metafile
+ GDIMetaFile aContentMetafile;
+ const Rectangle aPrimitiveRectangle(impDumpToMetaFile(rContent, aContentMetafile));
+
+ // restore mfCurrentUnifiedTransparence; it may have been used
+ // while processing the sub-content in impDumpToMetaFile
+ mfCurrentUnifiedTransparence = fLastCurrentUnifiedTransparence;
+
+ // create uniform VCL gradient for uniform transparency
+ Gradient aVCLGradient;
+ const sal_uInt8 nTransPercentVcl((sal_uInt8)basegfx::fround(rUniTransparenceCandidate.getTransparence() * 255.0));
+ const Color aTransColor(nTransPercentVcl, nTransPercentVcl, nTransPercentVcl);
+
+ aVCLGradient.SetStyle(GRADIENT_LINEAR);
+ aVCLGradient.SetStartColor(aTransColor);
+ aVCLGradient.SetEndColor(aTransColor);
+ aVCLGradient.SetAngle(0);
+ aVCLGradient.SetBorder(0);
+ aVCLGradient.SetOfsX(0);
+ aVCLGradient.SetOfsY(0);
+ aVCLGradient.SetStartIntensity(100);
+ aVCLGradient.SetEndIntensity(100);
+ aVCLGradient.SetSteps(2);
+
+ // render it to VCL
+ mpOutputDevice->DrawTransparent(
+ aContentMetafile, aPrimitiveRectangle.TopLeft(),
+ aPrimitiveRectangle.GetSize(), aVCLGradient);
+ }
+ }
+ }
+
+ break;
+ }
+ case PRIMITIVE2D_ID_TRANSPARENCEPRIMITIVE2D :
+ {
+ // for metafile: Need to examine what the pure vcl version is doing here actually
+ // - uses DrawTransparent with metafile for content and a gradient
+ // i can detect this here with checking the gradient part for a single
+ // FillGradientPrimitive2D and reconstruct the gradient.
+ // If that detection goes wrong, i have to create an transparence-blended bitmap. Eventually
+ // do that in stripes, else RenderTransparencePrimitive2D may just be used
+ const primitive2d::TransparencePrimitive2D& rTransparenceCandidate = static_cast< const primitive2d::TransparencePrimitive2D& >(rCandidate);
+ const primitive2d::Primitive2DSequence rContent = rTransparenceCandidate.getChildren();
+ const primitive2d::Primitive2DSequence rTransparence = rTransparenceCandidate.getTransparence();
+
+ if(rContent.hasElements() && rTransparence.hasElements())
+ {
+ // try to identify a single FillGradientPrimitive2D in the
+ // transparence part of the primitive
+ const primitive2d::FillGradientPrimitive2D* pFiGradient = 0;
+ static bool bForceToBigTransparentVDev(false);
+
+ if(!bForceToBigTransparentVDev && 1 == rTransparence.getLength())
+ {
+ const primitive2d::Primitive2DReference xReference(rTransparence[0]);
+ pFiGradient = dynamic_cast< const primitive2d::FillGradientPrimitive2D* >(xReference.get());
+ }
+
+ // Check also for correct ID to exclude derived implementations
+ if(pFiGradient && PRIMITIVE2D_ID_FILLGRADIENTPRIMITIVE2D == pFiGradient->getPrimitive2DID())
+ {
+ // various content, create content-metafile
+ GDIMetaFile aContentMetafile;
+ const Rectangle aPrimitiveRectangle(impDumpToMetaFile(rContent, aContentMetafile));
+
+ // re-create a VCL-gradient from FillGradientPrimitive2D
+ Gradient aVCLGradient;
+ impConvertFillGradientAttributeToVCLGradient(aVCLGradient, pFiGradient->getFillGradient(), true);
+
+ // render it to VCL
+ mpOutputDevice->DrawTransparent(
+ aContentMetafile, aPrimitiveRectangle.TopLeft(),
+ aPrimitiveRectangle.GetSize(), aVCLGradient);
+ }
+ else
+ {
+ // sub-transparence group. Draw to VDev first.
+ // this may get refined to tiling when resolution is too big here
+
+ // need to avoid switching off MapMode stuff here; maybe need another
+ // tooling class, cannot just do the same as with the pixel renderer.
+ // Need to experiment...
+
+ // Okay, basic implementation finished and tested. The DPI stuff was hard
+ // and not easy to find out that it's needed.
+ // Since this will not yet happen normally (as long as noone constructs
+ // transparence primitives with non-trivial transparence content) i will for now not
+ // refine to tiling here.
+
+ basegfx::B2DRange aViewRange(primitive2d::getB2DRangeFromPrimitive2DSequence(rContent, getViewInformation2D()));
+ aViewRange.transform(maCurrentTransformation);
+ const Rectangle aRectLogic(
+ (sal_Int32)floor(aViewRange.getMinX()), (sal_Int32)floor(aViewRange.getMinY()),
+ (sal_Int32)ceil(aViewRange.getMaxX()), (sal_Int32)ceil(aViewRange.getMaxY()));
+ const Rectangle aRectPixel(mpOutputDevice->LogicToPixel(aRectLogic));
+ Size aSizePixel(aRectPixel.GetSize());
+ const Point aEmptyPoint;
+ VirtualDevice aBufferDevice;
+ const sal_uInt32 nMaxQuadratPixels(500000);
+ const sal_uInt32 nViewVisibleArea(aSizePixel.getWidth() * aSizePixel.getHeight());
+ double fReduceFactor(1.0);
+
+ if(nViewVisibleArea > nMaxQuadratPixels)
+ {
+ // reduce render size
+ fReduceFactor = sqrt((double)nMaxQuadratPixels / (double)nViewVisibleArea);
+ aSizePixel = Size(basegfx::fround((double)aSizePixel.getWidth() * fReduceFactor),
+ basegfx::fround((double)aSizePixel.getHeight() * fReduceFactor));
+ }
+
+ if(aBufferDevice.SetOutputSizePixel(aSizePixel))
+ {
+ // create and set MapModes for target devices
+ MapMode aNewMapMode(mpOutputDevice->GetMapMode());
+ aNewMapMode.SetOrigin(Point(-aRectLogic.Left(), -aRectLogic.Top()));
+ aBufferDevice.SetMapMode(aNewMapMode);
+
+ // prepare view transformation for target renderers
+ // ATTENTION! Need to apply another scaling because of the potential DPI differences
+ // between Printer and VDev (mpOutputDevice and aBufferDevice here).
+ // To get the DPI, LogicToPixel from (1,1) from MAP_INCH needs to be used.
+ basegfx::B2DHomMatrix aViewTransform(aBufferDevice.GetViewTransformation());
+ const Size aDPIOld(mpOutputDevice->LogicToPixel(Size(1, 1), MAP_INCH));
+ const Size aDPINew(aBufferDevice.LogicToPixel(Size(1, 1), MAP_INCH));
+ const double fDPIXChange((double)aDPIOld.getWidth() / (double)aDPINew.getWidth());
+ const double fDPIYChange((double)aDPIOld.getHeight() / (double)aDPINew.getHeight());
+
+ if(!basegfx::fTools::equal(fDPIXChange, 1.0) || !basegfx::fTools::equal(fDPIYChange, 1.0))
+ {
+ aViewTransform.scale(fDPIXChange, fDPIYChange);
+ }
+
+ // also take scaling from Size reduction into acount
+ if(!basegfx::fTools::equal(fReduceFactor, 1.0))
+ {
+ aViewTransform.scale(fReduceFactor, fReduceFactor);
+ }
+
+ // create view information and pixel renderer. Reuse known ViewInformation
+ // except new transformation and range
+ const geometry::ViewInformation2D aViewInfo(
+ getViewInformation2D().getObjectTransformation(),
+ aViewTransform,
+ aViewRange,
+ getViewInformation2D().getVisualizedPage(),
+ getViewInformation2D().getViewTime(),
+ getViewInformation2D().getExtendedInformationSequence());
+
+ VclPixelProcessor2D aBufferProcessor(aViewInfo, aBufferDevice);
+
+ // draw content using pixel renderer
+ aBufferProcessor.process(rContent);
+ const Bitmap aBmContent(aBufferDevice.GetBitmap(aEmptyPoint, aSizePixel));
+
+ // draw transparence using pixel renderer
+ aBufferDevice.Erase();
+ aBufferProcessor.process(rTransparence);
+ const AlphaMask aBmAlpha(aBufferDevice.GetBitmap(aEmptyPoint, aSizePixel));
+
+#ifdef DBG_UTIL
+ static bool bDoSaveForVisualControl(false);
+ if(bDoSaveForVisualControl)
+ {
+ SvFileStream aNew(String(ByteString( "c:\\test.bmp" ), RTL_TEXTENCODING_UTF8), STREAM_WRITE|STREAM_TRUNC);
+ aNew << aBmContent;
+ }
+#endif
+
+ // paint
+ mpOutputDevice->DrawBitmapEx(
+ aRectLogic.TopLeft(),
+ aRectLogic.GetSize(),
+ BitmapEx(aBmContent, aBmAlpha));
+ }
+ }
+ }
+
+ break;
+ }
+ case PRIMITIVE2D_ID_TRANSFORMPRIMITIVE2D :
+ {
+ // use default transform group pocessing
+ RenderTransformPrimitive2D(static_cast< const primitive2d::TransformPrimitive2D& >(rCandidate));
+ break;
+ }
+ case PRIMITIVE2D_ID_PAGEPREVIEWPRIMITIVE2D :
+ {
+ // new XDrawPage for ViewInformation2D
+ RenderPagePreviewPrimitive2D(static_cast< const primitive2d::PagePreviewPrimitive2D& >(rCandidate));
+ break;
+ }
+ case PRIMITIVE2D_ID_MARKERARRAYPRIMITIVE2D :
+ {
+ // use default marker array pocessing
+ RenderMarkerArrayPrimitive2D(static_cast< const primitive2d::MarkerArrayPrimitive2D& >(rCandidate));
+ break;
+ }
+ case PRIMITIVE2D_ID_POINTARRAYPRIMITIVE2D :
+ {
+ // use default point array pocessing
+ RenderPointArrayPrimitive2D(static_cast< const primitive2d::PointArrayPrimitive2D& >(rCandidate));
+ break;
+ }
+ case PRIMITIVE2D_ID_STRUCTURETAGPRIMITIVE2D :
+ {
+ // structured tag primitive
+ const primitive2d::StructureTagPrimitive2D& rStructureTagCandidate = static_cast< const primitive2d::StructureTagPrimitive2D& >(rCandidate);
+ const vcl::PDFWriter::StructElement& rTagElement(rStructureTagCandidate.getStructureElement());
+ const bool bTagUsed(vcl::PDFWriter::NonStructElement != rTagElement);
+
+ if(mpPDFExtOutDevData && bTagUsed)
+ {
+ // write start tag
+ mpPDFExtOutDevData->BeginStructureElement(rTagElement);
+ }
+
+ // proccess childs normally
+ process(rStructureTagCandidate.getChildren());
+
+ if(mpPDFExtOutDevData && bTagUsed)
+ {
+ // write end tag
+ mpPDFExtOutDevData->EndStructureElement();
+ }
+
+ break;
+ }
+ case PRIMITIVE2D_ID_EPSPRIMITIVE2D :
+ {
+ RenderEpsPrimitive2D(static_cast< const primitive2d::EpsPrimitive2D& >(rCandidate));
+ break;
+ }
+ default :
+ {
+ // process recursively
+ process(rCandidate.get2DDecomposition(getViewInformation2D()));
+ break;
+ }
+ }
+ }
+ } // end of namespace processor2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/processor2d/canvasprocessor.cxx b/drawinglayer/source/processor2d/canvasprocessor.cxx
deleted file mode 100644
index 875f28003699..000000000000
--- a/drawinglayer/source/processor2d/canvasprocessor.cxx
+++ /dev/null
@@ -1,2213 +0,0 @@
-/**************************************************************
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- *************************************************************/
-
-
-
-// MARKER(update_precomp.py): autogen include statement, do not remove
-#include "precompiled_drawinglayer.hxx"
-
-#include <drawinglayer/processor2d/canvasprocessor.hxx>
-#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
-#include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
-#include <com/sun/star/rendering/XCanvas.hpp>
-#include <vcl/canvastools.hxx>
-#include <basegfx/tools/canvastools.hxx>
-#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
-#include <drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx>
-#include <drawinglayer/primitive2d/transformprimitive2d.hxx>
-#include <canvas/canvastools.hxx>
-#include <svl/ctloptions.hxx>
-#include <vcl/svapp.hxx>
-#include <drawinglayer/primitive2d/maskprimitive2d.hxx>
-#include <basegfx/polygon/b2dpolygonclipper.hxx>
-#include <drawinglayer/primitive2d/pagepreviewprimitive2d.hxx>
-#include <drawinglayer/primitive2d/metafileprimitive2d.hxx>
-#include <cppcanvas/basegfxfactory.hxx>
-#include <com/sun/star/rendering/XBitmapCanvas.hpp>
-#include <cppcanvas/vclfactory.hxx>
-#include <drawinglayer/primitive2d/pointarrayprimitive2d.hxx>
-#include <drawinglayer/primitive2d/textprimitive2d.hxx>
-#include <com/sun/star/rendering/TextDirection.hpp>
-#include <vclhelperbitmaptransform.hxx>
-#include <drawinglayer/primitive2d/bitmapprimitive2d.hxx>
-#include <basegfx/polygon/b2dpolygontools.hxx>
-#include <drawinglayer/primitive2d/transparenceprimitive2d.hxx>
-#include <basegfx/tuple/b2i64tuple.hxx>
-#include <basegfx/range/b2irange.hxx>
-#include <com/sun/star/rendering/XIntegerReadOnlyBitmap.hpp>
-#include <com/sun/star/rendering/PanoseProportion.hpp>
-#include <com/sun/star/rendering/CompositeOperation.hpp>
-#include <com/sun/star/rendering/StrokeAttributes.hpp>
-#include <com/sun/star/rendering/PathJoinType.hpp>
-#include <com/sun/star/rendering/PathCapType.hpp>
-#include <drawinglayer/primitive2d/fillbitmapprimitive2d.hxx>
-#include <com/sun/star/rendering/TexturingMode.hpp>
-#include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx>
-#include <vclhelperbufferdevice.hxx>
-#include <drawinglayer/primitive2d/wrongspellprimitive2d.hxx>
-#include <helperwrongspellrenderer.hxx>
-#include <basegfx/matrix/b2dhommatrixtools.hxx>
-
-//////////////////////////////////////////////////////////////////////////////
-
-using namespace com::sun::star;
-
-//////////////////////////////////////////////////////////////////////////////
-// AW: Adding the canvas example from THB here to extract stuff later
-/*
- // TODO(Q3): share impCreateEmptyBitmapWithPattern() and other
- // helper methods with vclprocessor.cxx
- Bitmap impCreateEmptyBitmapWithPattern(Bitmap aSource, const Size& aTargetSizePixel)
- {
- Bitmap aRetval;
- BitmapReadAccess* pReadAccess = aSource.AcquireReadAccess();
-
- if(pReadAccess)
- {
- if(aSource.GetBitCount() <= 8)
- {
- BitmapPalette aPalette(pReadAccess->GetPalette());
- aRetval = Bitmap(aTargetSizePixel, aSource.GetBitCount(), &aPalette);
- }
- else
- {
- aRetval = Bitmap(aTargetSizePixel, aSource.GetBitCount());
- }
-
- delete pReadAccess;
- }
-
- return aRetval;
- }
-
- Bitmap impModifyBitmap(const basegfx::BColorModifier& rModifier, const Bitmap& rSource)
- {
- Bitmap aRetval(rSource);
-
- switch(rModifier.getMode())
- {
- case basegfx::BCOLORMODIFYMODE_REPLACE :
- {
- aRetval = impCreateEmptyBitmapWithPattern(aRetval, Size(1L, 1L));
- aRetval.Erase(Color(rModifier.getBColor()));
- break;
- }
-
- default : // BCOLORMODIFYMODE_INTERPOLATE, BCOLORMODIFYMODE_GRAY, BCOLORMODIFYMODE_BLACKANDWHITE
- {
- BitmapWriteAccess* pContent = aRetval.AcquireWriteAccess();
-
- if(pContent)
- {
- for(sal_uInt32 y(0L); y < (sal_uInt32)pContent->Height(); y++)
- {
- for(sal_uInt32 x(0L); x < (sal_uInt32)pContent->Width(); x++)
- {
- const Color aColor = pContent->GetPixel(y, x);
- const basegfx::BColor aBColor(rModifier.getModifiedColor(aColor.getBColor()));
- pContent->SetPixel(y, x, BitmapColor(Color(aBColor)));
- }
- }
-
- delete pContent;
- }
-
- break;
- }
- }
-
- return aRetval;
- }
-
- Bitmap impModifyBitmap(const basegfx::BColorModifierStack& rBColorModifierStack, const Bitmap& rSource)
- {
- Bitmap aRetval(rSource);
-
- for(sal_uInt32 a(rBColorModifierStack.count()); a; )
- {
- const basegfx::BColorModifier& rModifier = rBColorModifierStack.getBColorModifier(--a);
- aRetval = impModifyBitmap(rModifier, aRetval);
- }
-
- return aRetval;
- }
-
- sal_uInt32 impCalcGradientSteps(sal_uInt32 nSteps, const basegfx::B2DRange& rRange, sal_uInt32 nMaxDist)
- {
- if(nSteps == 0L)
- nSteps = (sal_uInt32)(rRange.getWidth() + rRange.getHeight()) / 8;
-
- if(nSteps < 2L)
- {
- nSteps = 2L;
- }
-
- if(nSteps > nMaxDist)
- {
- nSteps = nMaxDist;
- }
-
- return nSteps;
- }
-
- void canvasProcessor::impDrawGradientSimple(
- const basegfx::B2DPolyPolygon& rTargetForm,
- const ::std::vector< basegfx::B2DHomMatrix >& rMatrices,
- const ::std::vector< basegfx::BColor >& rColors,
- const basegfx::B2DPolygon& rUnitPolygon)
- {
- uno::Reference< rendering::XPolyPolygon2D > xPoly(
- basegfx::unotools::xPolyPolygonFromB2DPolygon(
- mxCanvas->getDevice(),
- rUnitPolygon));
- uno::Reference< rendering::XPolyPolygon2D > xTargetPoly(
- basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(
- mxCanvas->getDevice(),
- rTargetForm));
-
- for(sal_uInt32 a(0L); a < rColors.size(); a++)
- {
- // set correct color
- const basegfx::BColor aFillColor(rColors[a]);
-
- maRenderState.DeviceColor = basegfx::unotools::colorToDoubleSequence(
- mxCanvas->getDevice(),
- aFillColor);
-
- if(a)
- {
- if(a - 1L < rMatrices.size())
- {
- canvas::tools::setRenderStateTransform( maRenderState,
- rMatrices[a - 1L] );
- mxCanvas->fillPolyPolygon(xPoly,maViewState,maRenderState);
- }
- }
- else
- {
- canvas::tools::setRenderStateTransform( maRenderState,
- basegfx::B2DHomMatrix() );
- mxCanvas->fillPolyPolygon(xTargetPoly,maViewState,maRenderState);
- }
- }
- }
-
- void canvasProcessor::impDrawGradientComplex(
- const basegfx::B2DPolyPolygon& rTargetForm,
- const ::std::vector< basegfx::B2DHomMatrix >& rMatrices,
- const ::std::vector< basegfx::BColor >& rColors,
- const basegfx::B2DPolygon& rUnitPolygon)
- {
- uno::Reference< rendering::XPolyPolygon2D > xPoly(
- basegfx::unotools::xPolyPolygonFromB2DPolygon(
- mxCanvas->getDevice(),
- rUnitPolygon));
- uno::Reference< rendering::XPolyPolygon2D > xTargetPoly(
- basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(
- mxCanvas->getDevice(),
- rTargetForm));
-
- maRenderState.Clip = xTargetPoly;
-
- // draw gradient PolyPolygons
- for(std::size_t a = 0L; a < rMatrices.size(); a++)
- {
- // set correct color
- if(rColors.size() > a)
- {
- const basegfx::BColor aFillColor(rColors[a]);
-
- maRenderState.DeviceColor = basegfx::unotools::colorToDoubleSequence(
- mxCanvas->getDevice(),
- aFillColor);
- }
-
- canvas::tools::setRenderStateTransform( maRenderState,
- rMatrices[a] );
-
- if(a)
- mxCanvas->fillPolyPolygon(xPoly,maViewState,maRenderState);
- else
- mxCanvas->fillPolyPolygon(xTargetPoly,maViewState,maRenderState);
- }
-
- maRenderState.Clip.clear();
- }
-
- void canvasProcessor::impDrawGradient(
- const basegfx::B2DPolyPolygon& rTargetForm,
- ::drawinglayer::primitive::GradientStyle eGradientStyle,
- sal_uInt32 nSteps,
- const basegfx::BColor& rStart,
- const basegfx::BColor& rEnd,
- double fBorder, double fAngle, double fOffsetX, double fOffsetY, bool bSimple)
- {
- fprintf(stderr,"impDrawGradient\n");
-
- basegfx::B2DPolyPolygon aTmp(rTargetForm);
- aTmp.transform( maWorldToView );
- const basegfx::B2DRange aOutlineRangePixel(basegfx::tools::getRange(aTmp));
- const basegfx::B2DRange aOutlineRange(basegfx::tools::getRange(rTargetForm));
-
- fprintf(stderr,"impDrawGradient: #%d\n",nSteps);
-
- if( // step count is infinite, can use native canvas
- // gradients here
- nSteps == 0 ||
- // step count is sufficiently high, such that no
- // discernible difference should be visible.
- nSteps > 64 )
- {
- uno::Reference< rendering::XParametricPolyPolygon2DFactory > xFactory(
- mxCanvas->getDevice()->getParametricPolyPolygonFactory() );
-
- if( xFactory.is() )
- {
- fprintf(stderr,"native gradient #1\n");
-
- basegfx::B2DHomMatrix aTextureTransformation;
- rendering::Texture aTexture;
-
- aTexture.RepeatModeX = rendering::TexturingMode::CLAMP;
- aTexture.RepeatModeY = rendering::TexturingMode::CLAMP;
- aTexture.Alpha = 1.0;
-
-
- // setup start/end color values
- // ----------------------------
-
- const uno::Sequence< double > aStartColor(
- basegfx::unotools::colorToDoubleSequence( mxCanvas->getDevice(),
- rStart ));
- const uno::Sequence< double > aEndColor(
- basegfx::unotools::colorToDoubleSequence( mxCanvas->getDevice(),
- rEnd ));
-
- // Setup texture transformation
- // ----------------------------
-
- const basegfx::B2DRange& rBounds(
- basegfx::tools::getRange( rTargetForm ));
-
- // setup rotation angle. VCL rotates
- // counter-clockwise, while canvas transformation
- // rotates clockwise
- //fAngle = -fAngle;
-
- switch(eGradientStyle)
- {
- case ::drawinglayer::primitive::GRADIENTSTYLE_LINEAR:
- // FALLTHROUGH intended
- case ::drawinglayer::primitive::GRADIENTSTYLE_AXIAL:
- {
- // standard orientation for VCL linear
- // gradient is vertical, thus, rotate 90
- // degrees
- fAngle += M_PI/2.0;
-
- // shrink texture, to account for border
- // (only in x direction, linear gradient
- // is constant in y direction, anyway)
- aTextureTransformation.scale(
- basegfx::pruneScaleValue(1.0 - fBorder),
- 1.0 );
-
- double fBorderX(0.0);
-
- // determine type of gradient (and necessary
- // transformation matrix, should it be emulated by a
- // generic gradient)
- switch(eGradientStyle)
- {
- case ::drawinglayer::primitive::GRADIENTSTYLE_LINEAR:
- // linear gradients don't respect
- // offsets (they are implicitely
- // assumed to be 50%). linear
- // gradients don't have border on
- // both sides, only on the
- // startColor side. Gradient is
- // invariant in y direction: leave
- // y offset alone.
- fBorderX = fBorder;
- aTexture.Gradient = xFactory->createLinearHorizontalGradient( aStartColor,
- aEndColor );
- break;
-
- case ::drawinglayer::primitive::GRADIENTSTYLE_AXIAL:
- // axial gradients have border on
- // both sides. Gradient is
- // invariant in y direction: leave
- // y offset alone.
- fBorderX = fBorder * .5;
- aTexture.Gradient = xFactory->createAxialHorizontalGradient( aStartColor,
- aEndColor );
- break;
- }
-
- // apply border offset values
- aTextureTransformation.translate( fBorderX,
- 0.0 );
-
- // rotate texture according to gradient rotation
- aTextureTransformation.translate( -0.5, -0.5 );
- aTextureTransformation.rotate( fAngle );
-
- // to let the first strip of a rotated
- // gradient start at the _edge_ of the
- // bound rect (and not, due to rotation,
- // slightly inside), slightly enlarge the
- // gradient:
- //
- // y/2 sin(transparence) + x/2 cos(transparence)
- //
- // (values to change are not actual
- // gradient scales, but original bound
- // rect dimensions. Since we still want
- // the border setting to apply after that,
- // we multiply with that as above for
- // nScaleX)
- const double nScale(
- basegfx::pruneScaleValue(
- fabs( rBounds.getHeight()*sin(fAngle) ) +
- fabs( rBounds.getWidth()*cos(fAngle) )));
-
- aTextureTransformation.scale( nScale, nScale );
-
- // translate back origin to center of
- // primitive
- aTextureTransformation.translate( 0.5*rBounds.getWidth(),
- 0.5*rBounds.getHeight() );
- break;
- }
-
- case ::drawinglayer::primitive::GRADIENTSTYLE_RADIAL:
- // FALLTHROUGH intended
- case ::drawinglayer::primitive::GRADIENTSTYLE_ELLIPTICAL:
- // FALLTHROUGH intended
- case ::drawinglayer::primitive::GRADIENTSTYLE_SQUARE:
- // FALLTHROUGH intended
- case ::drawinglayer::primitive::GRADIENTSTYLE_RECT:
- {
- fprintf(stderr,"native gradient #2\n");
-
- // determine scale factors for the gradient (must
- // be scaled up from [0,1]x[0,1] rect to object
- // bounds). Will potentially changed in switch
- // statement below.
- // Respect border value, while doing so, the VCL
- // gradient's border will effectively shrink the
- // resulting gradient.
- double nScaleX( rBounds.getWidth() * (1.0 - fBorder) );
- double nScaleY( rBounds.getHeight()* (1.0 - fBorder) );
-
- // determine offset values. Since the
- // border is divided half-by-half to both
- // sides of the gradient, divide
- // translation offset by an additional
- // factor of 2. Also respect offset here,
- // but since VCL gradients have their
- // center at [0,0] for zero offset, but
- // canvas gradients have their top, left
- // edge aligned with the primitive, and
- // offset of 50% effectively must yield
- // zero shift. Both values will
- // potentially be adapted in switch
- // statement below.
- double nOffsetX( rBounds.getWidth() *
- (2.0 * fOffsetX - 1.0 + fBorder)*.5 );
- double nOffsetY( rBounds.getHeight() *
- (2.0 * fOffsetY - 1.0 + fBorder)*.5 );
-
- // determine type of gradient (and necessary
- // transformation matrix, should it be emulated by a
- // generic gradient)
- switch(eGradientStyle)
- {
- case ::drawinglayer::primitive::GRADIENTSTYLE_RADIAL:
- {
- // create isotrophic scaling
- if( nScaleX > nScaleY )
- {
- nOffsetY -= (nScaleX - nScaleY) * 0.5;
- nScaleY = nScaleX;
- }
- else
- {
- nOffsetX -= (nScaleY - nScaleX) * 0.5;
- nScaleX = nScaleY;
- }
-
- // enlarge gradient to match bound rect diagonal
- aTextureTransformation.translate( -0.5, -0.5 );
- const double nScale( hypot(rBounds.getWidth(),
- rBounds.getHeight()) / nScaleX );
- aTextureTransformation.scale( nScale, nScale );
- aTextureTransformation.translate( 0.5, 0.5 );
-
- aTexture.Gradient = xFactory->createEllipticalGradient(
- aEndColor,
- aStartColor,
- cssgeom::RealRectangle2D(0.0,0.0,
- 1.0,1.0) );
- }
- break;
-
- case ::drawinglayer::primitive::GRADIENTSTYLE_ELLIPTICAL:
- {
- // enlarge gradient slightly
- aTextureTransformation.translate( -0.5, -0.5 );
- const double nSqrt2( sqrt(2.0) );
- aTextureTransformation.scale( nSqrt2,nSqrt2 );
- aTextureTransformation.translate( 0.5, 0.5 );
-
- aTexture.Gradient = xFactory->createEllipticalGradient(
- aEndColor,
- aStartColor,
- cssgeom::RealRectangle2D( rBounds.getMinX(),
- rBounds.getMinY(),
- rBounds.getMaxX(),
- rBounds.getMaxY() ));
- }
- break;
-
- case ::drawinglayer::primitive::GRADIENTSTYLE_SQUARE:
- {
- // create isotrophic scaling
- if( nScaleX > nScaleY )
- {
- nOffsetY -= (nScaleX - nScaleY) * 0.5;
- nScaleY = nScaleX;
- }
- else
- {
- nOffsetX -= (nScaleY - nScaleX) * 0.5;
- nScaleX = nScaleY;
- }
-
- aTexture.Gradient = xFactory->createRectangularGradient(
- aEndColor,
- aStartColor,
- cssgeom::RealRectangle2D(0.0,0.0,
- 1.0,1.0));
- }
- break;
-
- case ::drawinglayer::primitive::GRADIENTSTYLE_RECT:
- {
- aTexture.Gradient = xFactory->createRectangularGradient(
- aEndColor,
- aStartColor,
- cssgeom::RealRectangle2D( rBounds.getMinX(),
- rBounds.getMinY(),
- rBounds.getMaxX(),
- rBounds.getMaxY() ));
- }
- break;
- }
-
- nScaleX = basegfx::pruneScaleValue( nScaleX );
- nScaleY = basegfx::pruneScaleValue( nScaleY );
-
- aTextureTransformation.scale( nScaleX, nScaleY );
-
- // rotate texture according to gradient rotation
- aTextureTransformation.translate( -0.5*nScaleX, -0.5*nScaleY );
- aTextureTransformation.rotate( fAngle );
- aTextureTransformation.translate( 0.5*nScaleX, 0.5*nScaleY );
-
- aTextureTransformation.translate( nOffsetX, nOffsetY );
- }
- break;
-
- default:
- OSL_ENSURE( false,
- "canvasProcessor::impDrawGradient(): Unexpected gradient type" );
- break;
- }
-
- // As the texture coordinate space is relative to
- // the polygon coordinate space (NOT to the
- // polygon itself), move gradient to the start of
- // the actual polygon. If we skip this, the
- // gradient will always display at the origin, and
- // not within the polygon bound (which might be
- // miles away from the origin).
- aTextureTransformation.translate( rBounds.getMinX(),
- rBounds.getMinY() );
-
- basegfx::unotools::affineMatrixFromHomMatrix( aTexture.AffineTransform,
- aTextureTransformation );
- uno::Sequence< rendering::Texture > aSeq(1);
- aSeq[0] = aTexture;
-
- mxCanvas->fillTexturedPolyPolygon(
- basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(
- mxCanvas->getDevice(),
- rTargetForm),
- maViewState,
- maRenderState,
- aSeq );
-
- // done, using native gradients
- return;
- }
- }
- else
- {
- // make sure steps is not too high/low
- nSteps = impCalcGradientSteps(nSteps,
- aOutlineRangePixel,
- sal_uInt32((rStart.getMaximumDistance(rEnd) * 127.5) + 0.5));
-
-
- ::std::vector< basegfx::B2DHomMatrix > aMatrices;
- ::std::vector< basegfx::BColor > aColors;
- basegfx::B2DPolygon aUnitPolygon;
-
- if( drawinglayer::primitive::GRADIENTSTYLE_RADIAL == eGradientStyle ||
- drawinglayer::primitive::GRADIENTSTYLE_ELLIPTICAL == eGradientStyle)
- {
- const basegfx::B2DPoint aCircleCenter(0.5, 0.5);
- aUnitPolygon = basegfx::tools::createPolygonFromEllipse(aCircleCenter, 0.5, 0.5);
- aUnitPolygon = basegfx::tools::adaptiveSubdivideByAngle(aUnitPolygon);
- }
- else
- {
- aUnitPolygon = basegfx::tools::createUnitPolygon();
- }
-
- // create geometries
- switch(eGradientStyle)
- {
- case ::drawinglayer::primitive::GRADIENTSTYLE_LINEAR:
- {
- ::drawinglayer::primitive::geoTexSvxGradientLinear aGradient(aOutlineRange, rStart, rEnd, nSteps, fBorder, fAngle);
- aGradient.appendTransformations(aMatrices);
- aGradient.appendColors(aColors);
- break;
- }
- case ::drawinglayer::primitive::GRADIENTSTYLE_AXIAL:
- {
- ::drawinglayer::primitive::geoTexSvxGradientAxial aGradient(aOutlineRange, rStart, rEnd, nSteps, fBorder, fAngle);
- aGradient.appendTransformations(aMatrices);
- aGradient.appendColors(aColors);
- break;
- }
- case ::drawinglayer::primitive::GRADIENTSTYLE_RADIAL:
- {
- ::drawinglayer::primitive::geoTexSvxGradientRadial aGradient(aOutlineRange, rStart, rEnd, nSteps, fBorder, fOffsetX, fOffsetY);
- aGradient.appendTransformations(aMatrices);
- aGradient.appendColors(aColors);
- break;
- }
- case ::drawinglayer::primitive::GRADIENTSTYLE_ELLIPTICAL:
- {
- ::drawinglayer::primitive::geoTexSvxGradientElliptical aGradient(aOutlineRange, rStart, rEnd, nSteps, fBorder, fOffsetX, fOffsetX, fAngle);
- aGradient.appendTransformations(aMatrices);
- aGradient.appendColors(aColors);
- break;
- }
- case ::drawinglayer::primitive::GRADIENTSTYLE_SQUARE:
- {
- ::drawinglayer::primitive::geoTexSvxGradientSquare aGradient(aOutlineRange, rStart, rEnd, nSteps, fBorder, fOffsetX, fOffsetX, fAngle);
- aGradient.appendTransformations(aMatrices);
- aGradient.appendColors(aColors);
- break;
- }
- case ::drawinglayer::primitive::GRADIENTSTYLE_RECT:
- {
- ::drawinglayer::primitive::geoTexSvxGradientRect aGradient(aOutlineRange, rStart, rEnd, nSteps, fBorder, fOffsetX, fOffsetX, fAngle);
- aGradient.appendTransformations(aMatrices);
- aGradient.appendColors(aColors);
- break;
- }
- }
-
- // paint them with mask using the XOR method
- if(aMatrices.size())
- {
- if(bSimple)
- {
- impDrawGradientSimple(rTargetForm, aMatrices, aColors, aUnitPolygon);
- }
- else
- {
- impDrawGradientComplex(rTargetForm, aMatrices, aColors, aUnitPolygon);
- }
- }
- }
- }
-
-
- //////////////////////////////////////////////////////////////////////////////
- // rendering support
-
- // directdraw of text simple portion
- void canvasProcessor::impRender_STXP(const textSimplePortionPrimitive& rTextCandidate)
- {
- const fontAttributes& rFontAttrs( rTextCandidate.getFontAttribute() );
- rendering::FontRequest aFontRequest;
-
- aFontRequest.FontDescription.FamilyName = rFontAttrs.maFamilyName;
- aFontRequest.FontDescription.StyleName = rFontAttrs.maStyleName;
- aFontRequest.FontDescription.IsSymbolFont = rFontAttrs.mbSymbol ? util::TriState_YES : util::TriState_NO;
- aFontRequest.FontDescription.IsVertical = rFontAttrs.mbVertical ? util::TriState_YES : util::TriState_NO;
-
- // TODO(F2): improve vclenum->panose conversion
- aFontRequest.FontDescription.FontDescription.Weight =
- rFontAttrs.mnWeight;
- aFontRequest.FontDescription.FontDescription.Letterform =
- rFontAttrs.mbItalic ? 9 : 0;
-
- // font matrix should only be used for glyph rotations etc.
- css::geometry::Matrix2D aFontMatrix;
- canvas::tools::setIdentityMatrix2D( aFontMatrix );
-
- uno::Reference<rendering::XCanvasFont> xFont(
- mxCanvas->createFont( aFontRequest,
- uno::Sequence< beans::PropertyValue >(),
- aFontMatrix ));
-
- if( !xFont.is() )
- return;
-
- uno::Reference<rendering::XTextLayout> xLayout(
- xFont->createTextLayout(
- rendering::StringContext( rTextCandidate.getText(),
- 0,
- rTextCandidate.getText().Len() ),
- // TODO(F3): Is this sufficient?
- rendering::TextDirection::WEAK_LEFT_TO_RIGHT,
- 0 ));
- if( !xLayout.is() )
- return;
-
- xLayout->applyLogicalAdvancements(
- uno::Sequence<double>(&rTextCandidate.getDXArray()[0],
- rTextCandidate.getDXArray().size() ));
-
- const basegfx::BColor aRGBColor(
- maBColorModifierStack.getModifiedColor(
- rTextCandidate.getFontColor()));
-
- maRenderState.DeviceColor = basegfx::unotools::colorToDoubleSequence(
- mxCanvas->getDevice(),
- aRGBColor);
-
- // get render parameters and paint
- mxCanvas->drawTextLayout( xLayout,
- maViewState,
- maRenderState );
- }
-
- // direct draw of hairline
- void canvasProcessor::impRender_POHL(const polygonHairlinePrimitive& rPolygonCandidate)
- {
- const basegfx::BColor aRGBColor(
- maBColorModifierStack.getModifiedColor(
- rPolygonCandidate.getBColor()));
-
- maRenderState.DeviceColor = basegfx::unotools::colorToDoubleSequence(
- mxCanvas->getDevice(),
- aRGBColor);
-
- mxCanvas->drawPolyPolygon( basegfx::unotools::xPolyPolygonFromB2DPolygon(
- mxCanvas->getDevice(),
- rPolygonCandidate.getB2DPolygon()),
- maViewState,
- maRenderState );
- }
-
- // direct draw of transformed BitmapEx primitive
- void canvasProcessor::impRender_BMPR(const bitmapPrimitive& rBitmapCandidate)
- {
- BitmapEx aBitmapEx(rBitmapCandidate.getBitmapEx());
-
- if(maBColorModifierStack.count())
- {
- // TODO(Q3): Share common bmp modification code with
- // vclprocessor.cxx
- Bitmap aChangedBitmap(impModifyBitmap(maBColorModifierStack, aBitmapEx.GetBitmap()));
-
- if(aBitmapEx.IsTransparent())
- {
- if(aBitmapEx.IsAlpha())
- aBitmapEx = BitmapEx(aChangedBitmap, aBitmapEx.GetAlpha());
- else
- aBitmapEx = BitmapEx(aChangedBitmap, aBitmapEx.GetMask());
- }
- else
- aBitmapEx = BitmapEx(aChangedBitmap);
- }
-
- mxCanvas->drawBitmap(
- vcl::unotools::xBitmapFromBitmapEx( mxCanvas->getDevice(),
- aBitmapEx ),
- maViewState,
- maRenderState);
- }
-
- void canvasProcessor::impRender_PPLB(const polyPolygonBitmapPrimitive& rPolyBitmapCandidate )
- {
- const fillBitmapAttribute& rFillBmpAttr( rPolyBitmapCandidate.getFillBitmap() );
- const basegfx::B2DPolyPolygon& rPoly( rPolyBitmapCandidate.getB2DPolyPolygon() );
-
- // TODO(Q3): Share common bmp modification code with
- // vclprocessor.cxx
- Bitmap aChangedBitmap(
- impModifyBitmap(maBColorModifierStack,
- rFillBmpAttr.getBitmap()));
-
- rendering::Texture aTexture;
- const basegfx::B2DVector aBmpSize( rFillBmpAttr.getSize() );
-
- const basegfx::B2DRange& rBounds(
- basegfx::tools::getRange( rPoly ));
-
- basegfx::B2DHomMatrix aScale;
- aScale.scale( aBmpSize.getX() * rBounds.getWidth(),
- aBmpSize.getY() * rBounds.getHeight() );
-
- basegfx::unotools::affineMatrixFromHomMatrix(
- aTexture.AffineTransform,
- aScale );
-
- aTexture.Alpha = 1.0;
- aTexture.Bitmap =
- ::vcl::unotools::xBitmapFromBitmapEx(
- mxCanvas->getDevice(),
- aChangedBitmap );
- aTexture.RepeatModeX = rendering::TexturingMode::REPEAT;
- aTexture.RepeatModeY = rendering::TexturingMode::REPEAT;
-
- uno::Sequence< rendering::Texture > aSeq(1);
- aSeq[0] = aTexture;
-
- mxCanvas->fillTexturedPolyPolygon(
- basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(
- mxCanvas->getDevice(),
- rPoly),
- maViewState,
- maRenderState,
- aSeq );
- }
-
- // direct draw of gradient
- void canvasProcessor::impRender_PPLG(const polyPolygonGradientPrimitive& rPolygonCandidate)
- {
- const fillGradientAttribute& rGradient(rPolygonCandidate.getFillGradient());
- basegfx::BColor aStartColor(maBColorModifierStack.getModifiedColor(rGradient.getStartColor()));
- basegfx::BColor aEndColor(maBColorModifierStack.getModifiedColor(rGradient.getEndColor()));
- basegfx::B2DPolyPolygon aLocalPolyPolygon(rPolygonCandidate.getB2DPolyPolygon());
-
- if(aStartColor == aEndColor)
- {
- // no gradient at all, draw as polygon
-
- maRenderState.DeviceColor = basegfx::unotools::colorToDoubleSequence(
- mxCanvas->getDevice(),
- aStartColor);
-
- mxCanvas->drawPolyPolygon( basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(
- mxCanvas->getDevice(),
- aLocalPolyPolygon),
- maViewState,
- maRenderState );
- }
- else
- {
- // TODO(F3): if rGradient.getSteps() > 0, render
- // gradient manually!
- impDrawGradient(
- aLocalPolyPolygon, rGradient.getStyle(), rGradient.getSteps(),
- aStartColor, aEndColor, rGradient.getBorder(),
- -rGradient.getAngle(), rGradient.getOffsetX(), rGradient.getOffsetY(), false);
- }
- }
-
- // direct draw of PolyPolygon with color
- void canvasProcessor::impRender_PPLC(const polyPolygonColorPrimitive& rPolygonCandidate)
- {
- const basegfx::BColor aRGBColor(
- maBColorModifierStack.getModifiedColor(
- rPolygonCandidate.getBColor()));
-
- maRenderState.DeviceColor = basegfx::unotools::colorToDoubleSequence(
- mxCanvas->getDevice(),
- aRGBColor);
-
- mxCanvas->fillPolyPolygon( basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(
- mxCanvas->getDevice(),
- rPolygonCandidate.getB2DPolyPolygon()),
- maViewState,
- maRenderState );
- }
-
- // direct draw of MetaFile
- void canvasProcessor::impRender_META(const metafilePrimitive& rMetaCandidate)
- {
- // get metafile (copy it)
- GDIMetaFile aMetaFile;
-
- // TODO(Q3): Share common metafile modification code with
- // vclprocessor.cxx
- if(maBColorModifierStack.count())
- {
- const basegfx::BColor aRGBBaseColor(0, 0, 0);
- const basegfx::BColor aRGBColor(maBColorModifierStack.getModifiedColor(aRGBBaseColor));
- aMetaFile = rMetaCandidate.getMetaFile().GetMonochromeMtf(Color(aRGBColor));
- }
- else
- {
- aMetaFile = rMetaCandidate.getMetaFile();
- }
-
- cppcanvas::BitmapCanvasSharedPtr pCanvas(
- cppcanvas::VCLFactory::getInstance().createCanvas(
- uno::Reference<rendering::XBitmapCanvas>(
- mxCanvas,
- uno::UNO_QUERY_THROW) ));
- cppcanvas::RendererSharedPtr pMtfRenderer(
- cppcanvas::VCLFactory::getInstance().createRenderer(
- pCanvas,
- aMetaFile,
- cppcanvas::Renderer::Parameters() ));
- if( pMtfRenderer )
- {
- pCanvas->setTransformation(maWorldToView);
- pMtfRenderer->setTransformation(rMetaCandidate.getTransform());
- pMtfRenderer->draw();
- }
- }
-
- // mask group. Set mask polygon as clip
- void canvasProcessor::impRender_MASK(const maskPrimitive& rMaskCandidate)
- {
- const primitiveVector& rSubList = rMaskCandidate.getPrimitiveVector();
-
- if(!rSubList.empty())
- {
- // TODO(F3): cannot use state-global renderstate, when recursing!
- maRenderState.Clip =
- basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(
- mxCanvas->getDevice(),
- rMaskCandidate.getMask());
-
- // paint to it
- process(rSubList);
-
- maRenderState.Clip.clear();
- }
- }
-
- // modified color group. Force output to unified color.
- void canvasProcessor::impRender_MCOL(const modifiedColorPrimitive& rModifiedCandidate)
- {
- const primitiveVector& rSubList = rModifiedCandidate.getPrimitiveVector();
-
- if(!rSubList.empty())
- {
- maBColorModifierStack.push(rModifiedCandidate.getColorModifier());
- process(rModifiedCandidate.getPrimitiveVector());
- maBColorModifierStack.pop();
- }
- }
-
- // sub-transparence group. Draw to bitmap device first.
- void canvasProcessor::impRender_TRPR(const transparencePrimitive& rTransCandidate)
- {
- const primitiveVector& rSubList = rTransCandidate.getPrimitiveVector();
-
- if(!rSubList.empty())
- {
- basegfx::B2DRange aRange(
- get2DRangeFromVector(rSubList,
- getViewInformation()));
- aRange.transform(maWorldToView);
- const basegfx::B2I64Tuple& rSize(
- canvas::tools::spritePixelAreaFromB2DRange(aRange).getRange());
- uno::Reference< rendering::XCanvas > xBitmap(
- mxCanvas->getDevice()->createCompatibleAlphaBitmap(
- css::geometry::IntegerSize2D(rSize.getX(),
- rSize.getY())),
- uno::UNO_QUERY_THROW);
-
- // remember last worldToView and add pixel offset
- basegfx::B2DHomMatrix aLastWorldToView(maWorldToView);
- basegfx::B2DHomMatrix aPixelOffset;
- aPixelOffset.translate(aRange.getMinX(),
- aRange.getMinY());
- setWorldToView(aPixelOffset * maWorldToView);
-
- // remember last canvas, set bitmap as target
- uno::Reference< rendering::XCanvas > xLastCanvas( mxCanvas );
- mxCanvas = xBitmap;
-
- // paint content to it
- process(rSubList);
-
- // TODO(F3): render transparent list to transparence
- // channel. Note that the OutDev implementation has a
- // shortcoming, in that nested transparency groups
- // don't work - transparence is not combined properly.
-
- // process(rTransCandidate.getTransparenceList());
-
- // back to old OutDev and worldToView
- mxCanvas = xLastCanvas;
- setWorldToView(aLastWorldToView);
-
- // DUMMY: add transparence modulation value to DeviceColor
- // TODO(F3): color management
- canvas::tools::setDeviceColor( maRenderState,
- 1.0, 1.0, 1.0, 0.5 );
- // finally, draw bitmap
- mxCanvas->drawBitmapModulated(
- uno::Reference< rendering::XBitmap >(
- xBitmap,
- uno::UNO_QUERY_THROW),
- maViewState,
- maRenderState );
- }
- }
-
- // transform group.
- void canvasProcessor::impRender_TRN2(const transformPrimitive& rTransformCandidate)
- {
- // remember current transformation
- basegfx::B2DHomMatrix aLastWorldToView(maWorldToView);
-
- // create new transformations
- setWorldToView(maWorldToView * rTransformCandidate.getTransformation());
-
- // let break down
- process(rTransformCandidate.getPrimitiveVector());
-
- // restore transformations
- setWorldToView(aLastWorldToView);
- }
-
- // marker
- void canvasProcessor::impRender_MARK(const markerPrimitive& rMarkCandidate)
- {
- const basegfx::BColor aRGBColor(maBColorModifierStack.getModifiedColor(rMarkCandidate.getRGBColor()));
-
- canvas::tools::initRenderState(maMarkerRenderState);
- maMarkerRenderState.DeviceColor = basegfx::unotools::colorToDoubleSequence(
- mxCanvas->getDevice(),
- aRGBColor);
-
- // Markers are special objects - their position is
- // determined by the view transformation, but their size
- // is always the same
- const basegfx::B2DPoint aViewPos(maWorldToView * rMarkCandidate.getPosition());
-
- uno::Reference< rendering::XPolyPolygon2D > xMarkerPoly;
- uno::Reference< rendering::XPolyPolygon2D > xHighlightMarkerPoly;
- switch(rMarkCandidate.getStyle())
- {
- default:
- case MARKERSTYLE_POINT:
- mxCanvas->drawPoint( basegfx::unotools::point2DFromB2DPoint(aViewPos),
- maMarkerViewState,
- maMarkerRenderState );
- return;
-
- case MARKERSTYLE_CROSS:
- if( !mxCrossMarkerPoly.is() )
- {
- basegfx::B2DPolyPolygon aPoly;
- basegfx::tools::importFromSvgD(
- aPoly,
- rtl::OUString::createFromAscii(
- "m-1 0 h2 m0 -1 v2" ));
- mxCrossMarkerPoly =
- basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(
- mxCanvas->getDevice(),
- aPoly );
- }
- xMarkerPoly = mxCrossMarkerPoly;
- break;
-
- case MARKERSTYLE_GLUEPOINT :
- if( !mxGluePointPoly.is() )
- {
- basegfx::B2DPolyPolygon aPoly;
- basegfx::tools::importFromSvgD(
- aPoly,
- rtl::OUString::createFromAscii(
- "m-2 -3 l5 5 m-3 -2 l5 5 m-3 2 l5 -5 m-2 3 l5 -5" ));
- mxGluePointPoly =
- basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(
- mxCanvas->getDevice(),
- aPoly );
- }
- if( !mxGluePointHighlightPoly.is() )
- {
- basegfx::B2DPolyPolygon aPoly;
- basegfx::tools::importFromSvgD(
- aPoly,
- rtl::OUString::createFromAscii(
- "m-2 -2 l4 4 m-2 2 l4 -4" ));
- mxGluePointHighlightPoly =
- basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(
- mxCanvas->getDevice(),
- aPoly );
- }
- xMarkerPoly = mxGluePointPoly;
- xHighlightMarkerPoly = mxGluePointHighlightPoly;
- break;
- }
-
- basegfx::B2DRange aRange;
- rMarkCandidate.getRealtiveViewRange(aRange);
- const basegfx::B2DPoint aCenter(aRange.getCenter());
-
- basegfx::B2DHomMatrix aTranslate;
- aTranslate.translate(aViewPos.getX()+aCenter.getX(),
- aViewPos.getY()+aCenter.getY());
-
- canvas::tools::setRenderStateTransform( maMarkerRenderState,
- aTranslate );
-
-
- mxCanvas->drawPolyPolygon( xMarkerPoly,
- maMarkerViewState,
- maMarkerRenderState );
- if( xHighlightMarkerPoly.is() )
- {
- // TODO(F3): color management
- canvas::tools::setDeviceColor(maMarkerRenderState,
- 0.0, 0.0, 1.0, 1.0);
- mxCanvas->drawPolyPolygon( xMarkerPoly,
- maMarkerViewState,
- maMarkerRenderState );
- }
- }
-
- void canvasProcessor::setWorldToView(const basegfx::B2DHomMatrix& rMat)
- {
- maWorldToView = rMat;
- canvas::tools::setViewStateTransform(maViewState,
- maWorldToView);
- }
-
- //////////////////////////////////////////////////////////////////////////////
- // internal processing support
-
- void canvasProcessor::process(const primitiveVector& rSource)
- {
- primitiveVector::const_iterator aCurr = rSource.begin();
- const primitiveVector::const_iterator aEnd = rSource.end();
- while( aCurr != aEnd )
- {
- const referencedPrimitive& rCandidate = *aCurr;
-
- switch(rCandidate.getID())
- {
- case CreatePrimitiveID('S', 'T', 'X', 'P'):
- {
- // directdraw of text simple portion
- impRender_STXP(static_cast< const textSimplePortionPrimitive& >(rCandidate.getBasePrimitive()));
- break;
- }
-
- case CreatePrimitiveID('P', 'O', 'H', 'L'):
- {
- // direct draw of hairline
- impRender_POHL(static_cast< const polygonHairlinePrimitive& >(rCandidate.getBasePrimitive()));
- break;
- }
-
- case CreatePrimitiveID('B', 'M', 'P', 'R'):
- {
- // direct draw of transformed BitmapEx primitive
- impRender_BMPR(static_cast< const bitmapPrimitive& >(rCandidate.getBasePrimitive()));
- break;
- }
-
- case CreatePrimitiveID('F', 'B', 'M', 'P'):
- {
- OSL_ENSURE(false,"fillBitmapPrimitive not yet implemented");
- break;
- }
-
- case CreatePrimitiveID('P', 'P', 'L', 'B'):
- {
- // direct draw of polygon with bitmap fill
- impRender_PPLB(static_cast< const polyPolygonBitmapPrimitive& >(rCandidate.getBasePrimitive()));
- break;
- }
-
- case CreatePrimitiveID('P', 'P', 'L', 'G'):
- {
- // direct draw of gradient
- impRender_PPLG(static_cast< const polyPolygonGradientPrimitive& >(rCandidate.getBasePrimitive()));
- break;
- }
-
- case CreatePrimitiveID('P', 'P', 'L', 'C'):
- {
- // direct draw of PolyPolygon with color
- impRender_PPLC(static_cast< const polyPolygonColorPrimitive& >(rCandidate.getBasePrimitive()));
- break;
- }
-
- case CreatePrimitiveID('M', 'E', 'T', 'A'):
- {
- // direct draw of MetaFile
- impRender_META(static_cast< const metafilePrimitive& >(rCandidate.getBasePrimitive()));
- break;
- }
-
- case CreatePrimitiveID('M', 'A', 'S', 'K'):
- {
- // mask group. Force output to VDev and create mask from given mask
- impRender_MASK(static_cast< const maskPrimitive& >(rCandidate.getBasePrimitive()));
- break;
- }
-
- case CreatePrimitiveID('M', 'C', 'O', 'L'):
- {
- // modified color group. Force output to unified color.
- impRender_MCOL(static_cast< const modifiedColorPrimitive& >(rCandidate.getBasePrimitive()));
- break;
- }
-
- case CreatePrimitiveID('T', 'R', 'P', 'R'):
- {
- // sub-transparence group. Draw to VDev first.
- impRender_TRPR(static_cast< const transparencePrimitive& >(rCandidate.getBasePrimitive()));
- break;
- }
-
- case CreatePrimitiveID('T', 'R', 'N', '2'):
- {
- // transform group.
- impRender_TRN2(static_cast< const transformPrimitive& >(rCandidate.getBasePrimitive()));
- break;
- }
-
- case CreatePrimitiveID('M', 'A', 'R', 'K'):
- {
- // marker
- impRender_MARK(static_cast< const markerPrimitive& >(rCandidate.getBasePrimitive()));
- break;
- }
-
- case CreatePrimitiveID('A', 'N', 'S', 'W'):
- case CreatePrimitiveID('A', 'N', 'B', 'L'):
- case CreatePrimitiveID('A', 'N', 'I', 'N'):
- {
- // check timing, but do not accept
- const animatedSwitchPrimitive& rAnimatedCandidate(static_cast< const animatedSwitchPrimitive& >(rCandidate.getBasePrimitive()));
- const ::drawinglayer::animation::animationEntryList& rAnimationList = rAnimatedCandidate.getAnimationList();
- const double fNewTime(rAnimationList.getNextEventTime(getViewInformation().getViewTime()));
-
- // let break down
- process(rAnimatedCandidate.getDecomposition(getViewInformation()));
-
- break;
- }
-
- default:
- {
- // let break down
- process(rCandidate.getBasePrimitive().getDecomposition(getViewInformation()));
- }
- }
-
- ++aCurr;
- }
- }
-
- canvasProcessor::canvasProcessor( const ::drawinglayer::geometry::viewInformation& rViewInformation,
- const uno::Reference<rendering::XCanvas>& rCanvas ) :
- processor(rViewInformation),
- mxCanvas( rCanvas ),
- mxCrossMarkerPoly(),
- mxGluePointPoly(),
- mxGluePointHighlightPoly(),
- maBColorModifierStack(),
- maWorldToView(),
- maViewState(),
- maRenderState(),
- maMarkerViewState(),
- maMarkerRenderState()
- {
- canvas::tools::initViewState(maViewState);
- canvas::tools::initRenderState(maRenderState);
- canvas::tools::initViewState(maMarkerViewState);
- canvas::tools::initRenderState(maMarkerRenderState);
-
- maWorldToView = maViewInformation.getViewTransformation();
-
- canvas::tools::setViewStateTransform(maViewState,
- maWorldToView);
- }
-
- canvasProcessor::~canvasProcessor()
- {}
-*/
-//////////////////////////////////////////////////////////////////////////////
-
-namespace drawinglayer
-{
- namespace processor2d
- {
- //////////////////////////////////////////////////////////////////////////////
- // single primitive renderers
-
- void canvasProcessor2D::impRenderMaskPrimitive2D(const primitive2d::MaskPrimitive2D& rMaskCandidate)
- {
- const primitive2d::Primitive2DSequence& rChildren = rMaskCandidate.getChildren();
- static bool bUseMaskBitmapMethod(true);
-
- if(rChildren.hasElements())
- {
- basegfx::B2DPolyPolygon aMask(rMaskCandidate.getMask());
-
- if(!aMask.count())
- {
- // no mask, no clipping. recursively paint content
- process(rChildren);
- }
- else
- {
- // there are principally two methods for implementing the mask primitive. One
- // is to set a clip polygon at the canvas, the other is to create and use a
- // transparence-using XBitmap for content and draw the mask as transparence. Both have their
- // advantages and disadvantages, so here are both with a bool allowing simple
- // change
- if(bUseMaskBitmapMethod)
- {
- // get logic range of transparent part, clip with ViewRange
- basegfx::B2DRange aLogicRange(aMask.getB2DRange());
-
- if(!getViewInformation2D().getViewport().isEmpty())
- {
- aLogicRange.intersect(getViewInformation2D().getViewport());
- }
-
- if(!aLogicRange.isEmpty())
- {
- // get discrete range of transparent part
- basegfx::B2DRange aDiscreteRange(aLogicRange);
- aDiscreteRange.transform(getViewInformation2D().getObjectToViewTransformation());
-
- // expand to next covering discrete values (pixel bounds)
- aDiscreteRange.expand(basegfx::B2DTuple(floor(aDiscreteRange.getMinX()), floor(aDiscreteRange.getMinY())));
- aDiscreteRange.expand(basegfx::B2DTuple(ceil(aDiscreteRange.getMaxX()), ceil(aDiscreteRange.getMaxY())));
-
- // use VCL-based buffer device
- impBufferDevice aBufferDevice(*mpOutputDevice, aDiscreteRange, false);
-
- if(aBufferDevice.isVisible())
- {
- // remember current OutDev, Canvas and ViewInformation
- OutputDevice* pLastOutputDevice = mpOutputDevice;
- uno::Reference< rendering::XCanvas > xLastCanvas(mxCanvas);
- const geometry::ViewInformation2D aLastViewInformation2D(getViewInformation2D());
-
- // prepare discrete offset for XBitmap, do not forget that the buffer bitmap
- // may be truncated to discrete visible pixels
- const basegfx::B2DHomMatrix aDiscreteOffset(basegfx::tools::createTranslateB2DHomMatrix(
- aDiscreteRange.getMinX() > 0.0 ? -aDiscreteRange.getMinX() : 0.0,
- aDiscreteRange.getMinY() > 0.0 ? -aDiscreteRange.getMinY() : 0.0));
-
- // create new local ViewInformation2D with new transformation
- const geometry::ViewInformation2D aViewInformation2D(
- getViewInformation2D().getObjectTransformation(),
- aDiscreteOffset * getViewInformation2D().getViewTransformation(),
- getViewInformation2D().getViewport(),
- getViewInformation2D().getVisualizedPage(),
- getViewInformation2D().getViewTime(),
- getViewInformation2D().getExtendedInformationSequence());
- updateViewInformation(aViewInformation2D);
-
- // set OutDev and Canvas to content target
- mpOutputDevice = &aBufferDevice.getContent();
- mxCanvas = mpOutputDevice->GetCanvas();
- canvas::tools::setViewStateTransform(maViewState, getViewInformation2D().getViewTransformation());
-
- // if ViewState transform is changed, the clipping polygon needs to be adapted, too
- const basegfx::B2DPolyPolygon aOldClipPolyPolygon(maClipPolyPolygon);
-
- if(maClipPolyPolygon.count())
- {
- maClipPolyPolygon.transform(aDiscreteOffset);
- maViewState.Clip = basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(mxCanvas->getDevice(), maClipPolyPolygon);
- }
-
- // paint content
- process(rChildren);
-
- // draw mask
- const basegfx::BColor aBlack(0.0, 0.0, 0.0);
- maRenderState.DeviceColor = aBlack.colorToDoubleSequence(mxCanvas->getDevice());
-
- if(getOptionsDrawinglayer().IsAntiAliasing())
- {
- // with AA, use 8bit AlphaMask to get nice borders
- VirtualDevice& rTransparence = aBufferDevice.getTransparence();
- rTransparence.GetCanvas()->fillPolyPolygon(
- basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(mxCanvas->getDevice(), aMask),
- maViewState, maRenderState);
- }
- else
- {
- // No AA, use 1bit mask
- VirtualDevice& rMask = aBufferDevice.getMask();
- rMask.GetCanvas()->fillPolyPolygon(
- basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(mxCanvas->getDevice(), aMask),
- maViewState, maRenderState);
- }
-
- // back to old color stack, OutDev, Canvas and ViewTransform
- mpOutputDevice = pLastOutputDevice;
- mxCanvas = xLastCanvas;
- updateViewInformation(aLastViewInformation2D);
- canvas::tools::setViewStateTransform(maViewState, getViewInformation2D().getViewTransformation());
-
- // restore clipping polygon
- maClipPolyPolygon = aOldClipPolyPolygon;
-
- if(maClipPolyPolygon.count())
- {
- maViewState.Clip = basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(mxCanvas->getDevice(), maClipPolyPolygon);
- }
-
- // dump buffer to outdev
- aBufferDevice.paint();
- }
- }
- }
- else
- {
- // transform new mask polygon to view coordinates for processing. All masks
- // are processed in view coordinates and clipped against each other evtl. to
- // create multi-clips
- aMask.transform(getViewInformation2D().getObjectTransformation());
-
- // remember last current clip polygon
- const basegfx::B2DPolyPolygon aLastClipPolyPolygon(maClipPolyPolygon);
-
- if(maClipPolyPolygon.count())
- {
- // there is already a clip polygon set; build clipped union of
- // current mask polygon and new one
- maClipPolyPolygon = basegfx::tools::clipPolyPolygonOnPolyPolygon(aMask, maClipPolyPolygon, false, false);
- }
- else
- {
- // use mask directly
- maClipPolyPolygon = aMask;
- }
-
- // set at ViewState
- if(maClipPolyPolygon.count())
- {
- // set new as clip polygon
- maViewState.Clip = basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(mxCanvas->getDevice(), maClipPolyPolygon);
- }
- else
- {
- // empty, reset
- maViewState.Clip.clear();
- }
-
- // paint content
- process(rChildren);
-
- // restore local current to rescued clip polygon
- maClipPolyPolygon = aLastClipPolyPolygon;
-
- // set at ViewState
- if(maClipPolyPolygon.count())
- {
- // set new as clip polygon
- maViewState.Clip = basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(mxCanvas->getDevice(), maClipPolyPolygon);
- }
- else
- {
- // empty, reset
- maViewState.Clip.clear();
- }
- }
- }
- }
- }
-
- void canvasProcessor2D::impRenderMetafilePrimitive2D(const primitive2d::MetafilePrimitive2D& rMetaCandidate)
- {
- GDIMetaFile aMetaFile;
-
- if(maBColorModifierStack.count())
- {
- const basegfx::BColor aRGBBaseColor(0, 0, 0);
- const basegfx::BColor aRGBColor(maBColorModifierStack.getModifiedColor(aRGBBaseColor));
- aMetaFile = rMetaCandidate.getMetaFile().GetMonochromeMtf(Color(aRGBColor));
- }
- else
- {
- aMetaFile = rMetaCandidate.getMetaFile();
- }
-
- cppcanvas::BitmapCanvasSharedPtr pCanvas(cppcanvas::VCLFactory::getInstance().createCanvas(
- uno::Reference<rendering::XBitmapCanvas>(mxCanvas, uno::UNO_QUERY_THROW)));
- cppcanvas::RendererSharedPtr pMtfRenderer(cppcanvas::VCLFactory::getInstance().createRenderer(
- pCanvas, aMetaFile, cppcanvas::Renderer::Parameters()));
-
- if(pMtfRenderer)
- {
- pCanvas->setTransformation(getViewInformation2D().getObjectToViewTransformation());
- pMtfRenderer->setTransformation(rMetaCandidate.getTransform());
- pMtfRenderer->draw();
- }
- }
-
- void canvasProcessor2D::impRenderTextSimplePortionPrimitive2D(const primitive2d::TextSimplePortionPrimitive2D& rTextCandidate)
- {
- if(rTextCandidate.getTextLength())
- {
- double fShearX(0.0);
- {
- const basegfx::B2DHomMatrix aLocalTransform(getViewInformation2D().getObjectToViewTransformation() * rTextCandidate.getTextTransform());
- basegfx::B2DVector aScale, aTranslate;
- double fRotate;
- aLocalTransform.decompose(aScale, aTranslate, fRotate, fShearX);
- }
-
- if(!basegfx::fTools::equalZero(fShearX))
- {
- // text is sheared. As long as the canvas renderers do not support this,
- // use the decomposed primitive
- process(rTextCandidate.get2DDecomposition(getViewInformation2D()));
- }
- else
- {
- const attribute::FontAttribute& rFontAttr(rTextCandidate.getFontAttribute());
- rendering::FontRequest aFontRequest;
-
- aFontRequest.FontDescription.FamilyName = rFontAttr.getFamilyName();
- aFontRequest.FontDescription.StyleName = rFontAttr.getStyleName();
- aFontRequest.FontDescription.IsSymbolFont = rFontAttr.getSymbol() ? util::TriState_YES : util::TriState_NO;
- aFontRequest.FontDescription.IsVertical = rFontAttr.getVertical() ? util::TriState_YES : util::TriState_NO;
- // TODO(F2): improve vclenum->panose conversion
- aFontRequest.FontDescription.FontDescription.Weight = static_cast< sal_uInt8 >(rFontAttr.getWeight());
- aFontRequest.FontDescription.FontDescription.Proportion =
- rFontAttr.getMonospaced()
- ? rendering::PanoseProportion::MONO_SPACED
- : rendering::PanoseProportion::ANYTHING;
- aFontRequest.FontDescription.FontDescription.Letterform = rFontAttr.getItalic() ? 9 : 0;
-
- // init CellSize to 1.0, else a default font height will be used
- aFontRequest.CellSize = 1.0;
- aFontRequest.Locale = rTextCandidate.getLocale();
-
- // font matrix should only be used for glyph rotations etc.
- com::sun::star::geometry::Matrix2D aFontMatrix;
- canvas::tools::setIdentityMatrix2D(aFontMatrix);
-
- uno::Reference<rendering::XCanvasFont> xFont(mxCanvas->createFont(
- aFontRequest, uno::Sequence< beans::PropertyValue >(), aFontMatrix));
-
- if(xFont.is())
- {
- // got a font, now try to get a TextLayout
- const rendering::StringContext aStringContext(
- rTextCandidate.getText(), rTextCandidate.getTextPosition(), rTextCandidate.getTextLength());
- uno::Reference<rendering::XTextLayout> xLayout(xFont->createTextLayout(
- aStringContext, com::sun::star::rendering::TextDirection::WEAK_LEFT_TO_RIGHT, 0));
-
- if(xLayout.is())
- {
- // got a text layout, apply DXArray if given
- const ::std::vector< double >& rDXArray = rTextCandidate.getDXArray();
- const sal_uInt32 nDXCount(rDXArray.size());
-
- if(nDXCount)
- {
- // DXArray does not need to be adapted to getTextPosition/getTextLength,
- // it is already provided correctly
- const uno::Sequence< double > aDXSequence(&rDXArray[0], nDXCount);
- xLayout->applyLogicalAdvancements(aDXSequence);
- }
-
- // set text color
- const basegfx::BColor aRGBColor(maBColorModifierStack.getModifiedColor(rTextCandidate.getFontColor()));
- maRenderState.DeviceColor = aRGBColor.colorToDoubleSequence(mxCanvas->getDevice());
-
- // set text transformation
- canvas::tools::setRenderStateTransform(maRenderState,
- getViewInformation2D().getObjectTransformation() * rTextCandidate.getTextTransform());
-
- // paint
- mxCanvas->drawTextLayout(xLayout, maViewState, maRenderState);
- }
- }
- }
- }
- }
-
- void canvasProcessor2D::impRenderBitmapPrimitive2D(const primitive2d::BitmapPrimitive2D& rBitmapCandidate)
- {
- // apply possible color modification to BitmapEx
- BitmapEx aModifiedBitmapEx(impModifyBitmapEx(maBColorModifierStack, rBitmapCandidate.getBitmapEx()));
-
- if(aModifiedBitmapEx.IsEmpty())
- {
- // replace with color filled polygon
- const basegfx::BColor aModifiedColor(maBColorModifierStack.getModifiedColor(basegfx::BColor()));
- const basegfx::B2DPolygon aPolygon(basegfx::tools::createUnitPolygon());
-
- maRenderState.DeviceColor = aModifiedColor.colorToDoubleSequence(mxCanvas->getDevice());
- canvas::tools::setRenderStateTransform(maRenderState,
- getViewInformation2D().getObjectTransformation() * rBitmapCandidate.getTransform());
-
- mxCanvas->fillPolyPolygon(basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(
- mxCanvas->getDevice(), basegfx::B2DPolyPolygon(aPolygon)), maViewState, maRenderState);
- }
- else
- {
- // adapt object's transformation to the correct scale
- basegfx::B2DVector aScale, aTranslate;
- double fRotate, fShearX;
- const Size aSizePixel(aModifiedBitmapEx.GetSizePixel());
-
- if(0 != aSizePixel.Width() && 0 != aSizePixel.Height())
- {
- rBitmapCandidate.getTransform().decompose(aScale, aTranslate, fRotate, fShearX);
- const basegfx::B2DHomMatrix aNewMatrix(basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix(
- aScale.getX() / aSizePixel.Width(), aScale.getY() / aSizePixel.Height(),
- fShearX, fRotate, aTranslate.getX(), aTranslate.getY()));
-
- canvas::tools::setRenderStateTransform(maRenderState,
- getViewInformation2D().getObjectTransformation() * aNewMatrix);
-
- mxCanvas->drawBitmap(
- vcl::unotools::xBitmapFromBitmapEx(mxCanvas->getDevice(), aModifiedBitmapEx),
- maViewState, maRenderState);
- }
- }
- }
-
- void canvasProcessor2D::impRenderTransparencePrimitive2D(const primitive2d::TransparencePrimitive2D& rTransparenceCandidate)
- {
- const primitive2d::Primitive2DSequence& rChildren = rTransparenceCandidate.getChildren();
- const primitive2d::Primitive2DSequence& rTransparence = rTransparenceCandidate.getTransparence();
-
- if(rChildren.hasElements() && rTransparence.hasElements())
- {
- // get logic range of transparent part and clip with ViewRange
- basegfx::B2DRange aLogicRange(primitive2d::getB2DRangeFromPrimitive2DSequence(rChildren, getViewInformation2D()));
-
- if(!getViewInformation2D().getViewport().isEmpty())
- {
- aLogicRange.intersect(getViewInformation2D().getViewport());
- }
-
- if(!aLogicRange.isEmpty())
- {
- // get discrete range of transparent part
- basegfx::B2DRange aDiscreteRange(aLogicRange);
- aDiscreteRange.transform(getViewInformation2D().getObjectToViewTransformation());
-
- // expand to next covering discrete values (pixel bounds)
- aDiscreteRange.expand(basegfx::B2DTuple(floor(aDiscreteRange.getMinX()), floor(aDiscreteRange.getMinY())));
- aDiscreteRange.expand(basegfx::B2DTuple(ceil(aDiscreteRange.getMaxX()), ceil(aDiscreteRange.getMaxY())));
-
- // use VCL-based buffer device
- impBufferDevice aBufferDevice(*mpOutputDevice, aDiscreteRange, false);
-
- if(aBufferDevice.isVisible())
- {
- // remember current OutDev, Canvas and ViewInformation
- OutputDevice* pLastOutputDevice = mpOutputDevice;
- uno::Reference< rendering::XCanvas > xLastCanvas(mxCanvas);
- const geometry::ViewInformation2D aLastViewInformation2D(getViewInformation2D());
-
- // prepare discrete offset for XBitmap, do not forget that the buffer bitmap
- // may be truncated to discrete visible pixels
- const basegfx::B2DHomMatrix aDiscreteOffset(basegfx::tools::createTranslateB2DHomMatrix(
- aDiscreteRange.getMinX() > 0.0 ? -aDiscreteRange.getMinX() : 0.0,
- aDiscreteRange.getMinY() > 0.0 ? -aDiscreteRange.getMinY() : 0.0));
-
- // create new local ViewInformation2D with new transformation
- const geometry::ViewInformation2D aViewInformation2D(
- getViewInformation2D().getObjectTransformation(),
- aDiscreteOffset * getViewInformation2D().getViewTransformation(),
- getViewInformation2D().getViewport(),
- getViewInformation2D().getVisualizedPage(),
- getViewInformation2D().getViewTime(),
- getViewInformation2D().getExtendedInformationSequence());
- updateViewInformation(aViewInformation2D);
-
- // set OutDev and Canvas to content target
- mpOutputDevice = &aBufferDevice.getContent();
- mxCanvas = mpOutputDevice->GetCanvas();
- canvas::tools::setViewStateTransform(maViewState, getViewInformation2D().getViewTransformation());
-
- // if ViewState transform is changed, the clipping polygon needs to be adapted, too
- const basegfx::B2DPolyPolygon aOldClipPolyPolygon(maClipPolyPolygon);
-
- if(maClipPolyPolygon.count())
- {
- maClipPolyPolygon.transform(aDiscreteOffset);
- maViewState.Clip = basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(mxCanvas->getDevice(), maClipPolyPolygon);
- }
-
- // paint content
- process(rChildren);
-
- // set to mask
- mpOutputDevice = &aBufferDevice.getTransparence();
- mxCanvas = mpOutputDevice->GetCanvas();
- canvas::tools::setViewStateTransform(maViewState, getViewInformation2D().getViewTransformation());
-
- // when painting transparence masks, reset the color stack
- basegfx::BColorModifierStack aLastBColorModifierStack(maBColorModifierStack);
- maBColorModifierStack = basegfx::BColorModifierStack();
-
- // paint mask to it (always with transparence intensities, evtl. with AA)
- process(rTransparence);
-
- // back to old color stack, OutDev, Canvas and ViewTransform
- maBColorModifierStack = aLastBColorModifierStack;
- mpOutputDevice = pLastOutputDevice;
- mxCanvas = xLastCanvas;
- updateViewInformation(aLastViewInformation2D);
- canvas::tools::setViewStateTransform(maViewState, getViewInformation2D().getViewTransformation());
-
- // restore clipping polygon
- maClipPolyPolygon = aOldClipPolyPolygon;
-
- if(maClipPolyPolygon.count())
- {
- maViewState.Clip = basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(mxCanvas->getDevice(), maClipPolyPolygon);
- }
-
- // dump buffer to outdev
- aBufferDevice.paint();
- }
- }
- }
- }
-
- void canvasProcessor2D::impRenderPolygonStrokePrimitive2D(const primitive2d::PolygonStrokePrimitive2D& rPolygonStrokePrimitive)
- {
- // support direct fat line geometry. This moves the decomposition to the canvas.
- // As long as our canvases are used (which also use basegfx tooling) this makes
- // no difference, but potentially canvases may better support this
- static bool bSupportFatLineDirectly(true);
- bool bOutputDone(false);
-
- if(bSupportFatLineDirectly)
- {
- const attribute::LineAttribute& rLineAttribute = rPolygonStrokePrimitive.getLineAttribute();
- const attribute::StrokeAttribute& rStrokeAttribute = rPolygonStrokePrimitive.getStrokeAttribute();
-
- if(0.0 < rLineAttribute.getWidth() || 0 != rStrokeAttribute.getDotDashArray().size())
- {
- rendering::StrokeAttributes aStrokeAttribute;
-
- aStrokeAttribute.StrokeWidth = rLineAttribute.getWidth();
- aStrokeAttribute.MiterLimit = 15.0; // degrees; maybe here (15.0 * F_PI180) is needed, not clear in the documentation
- const ::std::vector< double >& rDotDashArray = rStrokeAttribute.getDotDashArray();
-
- if(rDotDashArray.size())
- {
- aStrokeAttribute.DashArray = uno::Sequence< double >(&rDotDashArray[0], rDotDashArray.size());
- }
-
- switch(rLineAttribute.getLineJoin())
- {
- default: // B2DLINEJOIN_NONE, B2DLINEJOIN_MIDDLE
- aStrokeAttribute.JoinType = rendering::PathJoinType::NONE;
- break;
- case basegfx::B2DLINEJOIN_BEVEL:
- aStrokeAttribute.JoinType = rendering::PathJoinType::BEVEL;
- break;
- case basegfx::B2DLINEJOIN_MITER:
- aStrokeAttribute.JoinType = rendering::PathJoinType::MITER;
- break;
- case basegfx::B2DLINEJOIN_ROUND:
- aStrokeAttribute.JoinType = rendering::PathJoinType::ROUND;
- break;
- }
-
- switch(rLineAttribute.getLineCap())
- {
- case com::sun::star::drawing::LineCap_ROUND:
- aStrokeAttribute.StartCapType = rendering::PathCapType::ROUND;
- aStrokeAttribute.EndCapType = rendering::PathCapType::ROUND;
- break;
- case com::sun::star::drawing::LineCap_SQUARE:
- aStrokeAttribute.StartCapType = rendering::PathCapType::SQUARE;
- aStrokeAttribute.EndCapType = rendering::PathCapType::SQUARE;
- break;
- default: // com::sun::star::drawing::LineCap_BUTT
- aStrokeAttribute.StartCapType = rendering::PathCapType::BUTT;
- aStrokeAttribute.EndCapType = rendering::PathCapType::BUTT;
- break;
- }
-
- const basegfx::BColor aHairlineColor(maBColorModifierStack.getModifiedColor(rLineAttribute.getColor()));
- maRenderState.DeviceColor = aHairlineColor.colorToDoubleSequence(mxCanvas->getDevice());
- canvas::tools::setRenderStateTransform(maRenderState, getViewInformation2D().getObjectTransformation());
-
- mxCanvas->strokePolyPolygon(
- basegfx::unotools::xPolyPolygonFromB2DPolygon(mxCanvas->getDevice(), rPolygonStrokePrimitive.getB2DPolygon()),
- maViewState, maRenderState, aStrokeAttribute);
-
- bOutputDone = true;
- }
- }
-
- if(!bOutputDone)
- {
- // process decomposition
- process(rPolygonStrokePrimitive.get2DDecomposition(getViewInformation2D()));
- }
- }
-
- void canvasProcessor2D::impRenderFillBitmapPrimitive2D(const primitive2d::FillBitmapPrimitive2D& rFillBitmapPrimitive2D)
- {
- // support tiled fills directly when tiling is on
- static bool bSupportFillBitmapDirectly(true);
- bool bOutputDone(false);
-
- if(bSupportFillBitmapDirectly)
- {
- const attribute::FillBitmapAttribute& rFillBitmapAttribute = rFillBitmapPrimitive2D.getFillBitmap();
-
- if(rFillBitmapAttribute.getTiling())
- {
- // apply possible color modification to Bitmap
- const BitmapEx aChangedBitmapEx(impModifyBitmapEx(maBColorModifierStack, rFillBitmapAttribute.getBitmapEx()));
-
- if(aChangedBitmapEx.IsEmpty())
- {
- // replace with color filled polygon
- const basegfx::BColor aModifiedColor(maBColorModifierStack.getModifiedColor(basegfx::BColor()));
- const basegfx::B2DPolygon aPolygon(basegfx::tools::createUnitPolygon());
-
- maRenderState.DeviceColor = aModifiedColor.colorToDoubleSequence(mxCanvas->getDevice());
- canvas::tools::setRenderStateTransform(maRenderState,
- getViewInformation2D().getObjectTransformation() * rFillBitmapPrimitive2D.getTransformation());
-
- mxCanvas->fillPolyPolygon(basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(
- mxCanvas->getDevice(), basegfx::B2DPolyPolygon(aPolygon)), maViewState, maRenderState);
- }
- else
- {
- const Size aSizePixel(aChangedBitmapEx.GetSizePixel());
-
- if(0 != aSizePixel.Width() && 0 != aSizePixel.Height())
- {
- // create texture matrix from texture to object (where object is unit square here),
- // so use values directly
- const basegfx::B2DHomMatrix aTextureMatrix(basegfx::tools::createScaleTranslateB2DHomMatrix(
- rFillBitmapAttribute.getSize().getX(), rFillBitmapAttribute.getSize().getY(),
- rFillBitmapAttribute.getTopLeft().getX(), rFillBitmapAttribute.getTopLeft().getY()));
-
- // create and fill texture
- rendering::Texture aTexture;
-
- basegfx::unotools::affineMatrixFromHomMatrix(aTexture.AffineTransform, aTextureMatrix);
- aTexture.Alpha = 1.0;
- aTexture.Bitmap = vcl::unotools::xBitmapFromBitmapEx(mxCanvas->getDevice(), aChangedBitmapEx);
- aTexture.RepeatModeX = rendering::TexturingMode::REPEAT;
- aTexture.RepeatModeY = rendering::TexturingMode::REPEAT;
-
- // canvas needs a polygon to fill, create unit rectangle polygon
- const basegfx::B2DPolygon aOutlineRectangle(basegfx::tools::createUnitPolygon());
-
- // set primitive's transformation as render state transform
- canvas::tools::setRenderStateTransform(maRenderState,
- getViewInformation2D().getObjectTransformation() * rFillBitmapPrimitive2D.getTransformation());
-
- // put texture into a uno sequence for handover
- uno::Sequence< rendering::Texture > aSeq(1);
- aSeq[0] = aTexture;
-
- // draw textured rectangle
- mxCanvas->fillTexturedPolyPolygon(
- basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(mxCanvas->getDevice(), basegfx::B2DPolyPolygon(aOutlineRectangle)),
- maViewState, maRenderState, aSeq);
- }
- }
-
- bOutputDone = true;
- }
- }
-
- if(!bOutputDone)
- {
- // process decomposition
- process(rFillBitmapPrimitive2D.get2DDecomposition(getViewInformation2D()));
- }
- }
-
- void canvasProcessor2D::impRenderUnifiedTransparencePrimitive2D(const primitive2d::UnifiedTransparencePrimitive2D& rUniTransparenceCandidate)
- {
- if(0.0 == rUniTransparenceCandidate.getTransparence())
- {
- // not transparent at all, directly use content
- process(rUniTransparenceCandidate.getChildren());
- }
- else if(rUniTransparenceCandidate.getTransparence() > 0.0 && rUniTransparenceCandidate.getTransparence() < 1.0)
- {
- const primitive2d::Primitive2DSequence rChildren = rUniTransparenceCandidate.getChildren();
-
- if(rChildren.hasElements())
- {
- bool bOutputDone(false);
-
- // Detect if a single PolyPolygonColorPrimitive2D is contained; in that case,
- // use the fillPolyPolygon method with correctly set transparence. This is a often used
- // case, so detectiong it is valuable
- if(1 == rChildren.getLength())
- {
- const primitive2d::Primitive2DReference xReference(rChildren[0]);
- const primitive2d::PolyPolygonColorPrimitive2D* pPoPoColor = dynamic_cast< const primitive2d::PolyPolygonColorPrimitive2D* >(xReference.get());
-
- if(pPoPoColor && PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D == pPoPoColor->getPrimitive2DID())
- {
- // direct draw of PolyPolygon with color and transparence
- const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(pPoPoColor->getBColor()));
-
- // add transparence modulation value to DeviceColor
- uno::Sequence< double > aColor(4);
-
- aColor[0] = aPolygonColor.getRed();
- aColor[1] = aPolygonColor.getGreen();
- aColor[2] = aPolygonColor.getBlue();
- aColor[3] = 1.0 - rUniTransparenceCandidate.getTransparence();
- maRenderState.DeviceColor = aColor;
-
- canvas::tools::setRenderStateTransform(maRenderState, getViewInformation2D().getObjectTransformation());
- mxCanvas->fillPolyPolygon(
- basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(mxCanvas->getDevice(), pPoPoColor->getB2DPolyPolygon()),
- maViewState, maRenderState);
- bOutputDone = true;
- }
- }
-
- if(!bOutputDone)
- {
- // process decomposition. This will be decomposed to an TransparencePrimitive2D
- // with the same child context and a single polygon for transparent context. This could be
- // directly handled here with known VCL-buffer technology, but would only
- // make a small difference compared to directly rendering the TransparencePrimitive2D
- // using impRenderTransparencePrimitive2D above.
- process(rUniTransparenceCandidate.get2DDecomposition(getViewInformation2D()));
- }
- }
- }
- }
-
- //////////////////////////////////////////////////////////////////////////////
- // internal processing support
-
- void canvasProcessor2D::processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate)
- {
- switch(rCandidate.getPrimitive2DID())
- {
- case PRIMITIVE2D_ID_POLYGONHAIRLINEPRIMITIVE2D :
- {
- // direct draw of hairline
- const primitive2d::PolygonHairlinePrimitive2D& rPolygonCandidate = static_cast< const primitive2d::PolygonHairlinePrimitive2D& >(rCandidate);
- const basegfx::BColor aHairlineColor(maBColorModifierStack.getModifiedColor(rPolygonCandidate.getBColor()));
-
- maRenderState.DeviceColor = aHairlineColor.colorToDoubleSequence(mxCanvas->getDevice());
- canvas::tools::setRenderStateTransform(maRenderState, getViewInformation2D().getObjectTransformation());
- mxCanvas->drawPolyPolygon(
- basegfx::unotools::xPolyPolygonFromB2DPolygon(mxCanvas->getDevice(), rPolygonCandidate.getB2DPolygon()),
- maViewState, maRenderState);
-
- break;
- }
- case PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D :
- {
- // direct draw of PolyPolygon with color
- const primitive2d::PolyPolygonColorPrimitive2D& rPolygonCandidate = static_cast< const primitive2d::PolyPolygonColorPrimitive2D& >(rCandidate);
- const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(rPolygonCandidate.getBColor()));
-
- maRenderState.DeviceColor = aPolygonColor.colorToDoubleSequence(mxCanvas->getDevice());
- canvas::tools::setRenderStateTransform(maRenderState, getViewInformation2D().getObjectTransformation());
- mxCanvas->fillPolyPolygon(
- basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(mxCanvas->getDevice(), rPolygonCandidate.getB2DPolyPolygon()),
- maViewState, maRenderState);
-
- break;
- }
- case PRIMITIVE2D_ID_MODIFIEDCOLORPRIMITIVE2D :
- {
- // modified color group. Force output to unified color.
- const primitive2d::ModifiedColorPrimitive2D& rModifiedCandidate = static_cast< const primitive2d::ModifiedColorPrimitive2D& >(rCandidate);
-
- if(rModifiedCandidate.getChildren().hasElements())
- {
- maBColorModifierStack.push(rModifiedCandidate.getColorModifier());
- process(rModifiedCandidate.getChildren());
- maBColorModifierStack.pop();
- }
-
- break;
- }
- case PRIMITIVE2D_ID_MASKPRIMITIVE2D :
- {
- // mask group
- impRenderMaskPrimitive2D(static_cast< const primitive2d::MaskPrimitive2D& >(rCandidate));
-
- break;
- }
- case PRIMITIVE2D_ID_TRANSFORMPRIMITIVE2D :
- {
- // transform group. Remember current ViewInformation2D
- const primitive2d::TransformPrimitive2D& rTransformCandidate = static_cast< const primitive2d::TransformPrimitive2D& >(rCandidate);
- const geometry::ViewInformation2D aLastViewInformation2D(getViewInformation2D());
-
- // create new local ViewInformation2D with new transformation
- const geometry::ViewInformation2D aViewInformation2D(
- getViewInformation2D().getObjectTransformation() * rTransformCandidate.getTransformation(),
- getViewInformation2D().getViewTransformation(),
- getViewInformation2D().getViewport(),
- getViewInformation2D().getVisualizedPage(),
- getViewInformation2D().getViewTime(),
- getViewInformation2D().getExtendedInformationSequence());
- updateViewInformation(aViewInformation2D);
-
- // set at canvas
- canvas::tools::setRenderStateTransform(maRenderState, getViewInformation2D().getObjectTransformation());
-
- // proccess content
- process(rTransformCandidate.getChildren());
-
- // restore transformations
- updateViewInformation(aLastViewInformation2D);
-
- // restore at canvas
- canvas::tools::setRenderStateTransform(maRenderState, getViewInformation2D().getObjectTransformation());
-
- break;
- }
- case PRIMITIVE2D_ID_PAGEPREVIEWPRIMITIVE2D :
- {
- // new XDrawPage for ViewInformation2D
- const primitive2d::PagePreviewPrimitive2D& rPagePreviewCandidate = static_cast< const primitive2d::PagePreviewPrimitive2D& >(rCandidate);
-
- // remember current transformation and ViewInformation
- const geometry::ViewInformation2D aLastViewInformation2D(getViewInformation2D());
-
- // create new local ViewInformation2D
- const geometry::ViewInformation2D aViewInformation2D(
- getViewInformation2D().getObjectTransformation(),
- getViewInformation2D().getViewTransformation(),
- getViewInformation2D().getViewport(),
- rPagePreviewCandidate.getXDrawPage(),
- getViewInformation2D().getViewTime(),
- getViewInformation2D().getExtendedInformationSequence());
- updateViewInformation(aViewInformation2D);
-
- // proccess decomposed content
- process(rPagePreviewCandidate.get2DDecomposition(getViewInformation2D()));
-
- // restore transformations
- updateViewInformation(aLastViewInformation2D);
- break;
- }
- case PRIMITIVE2D_ID_METAFILEPRIMITIVE2D :
- {
- // MetaFile primitive
- impRenderMetafilePrimitive2D(static_cast< const primitive2d::MetafilePrimitive2D& >(rCandidate));
-
- break;
- }
- case PRIMITIVE2D_ID_POINTARRAYPRIMITIVE2D :
- {
- // PointArray primitive
- const primitive2d::PointArrayPrimitive2D& rPointArrayCandidate = static_cast< const primitive2d::PointArrayPrimitive2D& >(rCandidate);
-
- // set point color
- const basegfx::BColor aRGBColor(maBColorModifierStack.getModifiedColor(rPointArrayCandidate.getRGBColor()));
- maRenderState.DeviceColor = aRGBColor.colorToDoubleSequence(mxCanvas->getDevice());
- canvas::tools::setRenderStateTransform(maRenderState, getViewInformation2D().getObjectTransformation());
-
- const std::vector< basegfx::B2DPoint >& rPointVector = rPointArrayCandidate.getPositions();
- const sal_uInt32 nPointCount(rPointVector.size());
-
- for(sal_uInt32 a(0); a < nPointCount; a++)
- {
- const basegfx::B2DPoint& rPoint = rPointVector[a];
- mxCanvas->drawPoint(basegfx::unotools::point2DFromB2DPoint(rPoint), maViewState, maRenderState);
- }
-
- break;
- }
- case PRIMITIVE2D_ID_TEXTSIMPLEPORTIONPRIMITIVE2D :
- {
- // TextSimplePortion primitive
- impRenderTextSimplePortionPrimitive2D(static_cast< const primitive2d::TextSimplePortionPrimitive2D& >(rCandidate));
-
- break;
- }
- case PRIMITIVE2D_ID_BITMAPPRIMITIVE2D :
- {
- // Bitmap primitive
- impRenderBitmapPrimitive2D(static_cast< const primitive2d::BitmapPrimitive2D& >(rCandidate));
-
- break;
- }
- case PRIMITIVE2D_ID_TRANSPARENCEPRIMITIVE2D :
- {
- // Transparence primitive
- impRenderTransparencePrimitive2D(static_cast< const primitive2d::TransparencePrimitive2D& >(rCandidate));
-
- break;
- }
- case PRIMITIVE2D_ID_POLYGONSTROKEPRIMITIVE2D:
- {
- // PolygonStrokePrimitive
- impRenderPolygonStrokePrimitive2D(static_cast< const primitive2d::PolygonStrokePrimitive2D& >(rCandidate));
-
- break;
- }
- case PRIMITIVE2D_ID_FILLBITMAPPRIMITIVE2D :
- {
- // FillBitmapPrimitive2D
- impRenderFillBitmapPrimitive2D(static_cast< const primitive2d::FillBitmapPrimitive2D& >(rCandidate));
-
- break;
- }
- case PRIMITIVE2D_ID_UNIFIEDTRANSPARENCEPRIMITIVE2D :
- {
- // UnifiedTransparencePrimitive2D
- impRenderUnifiedTransparencePrimitive2D(static_cast< const primitive2d::UnifiedTransparencePrimitive2D& >(rCandidate));
-
- break;
- }
- case PRIMITIVE2D_ID_WRONGSPELLPRIMITIVE2D :
- {
- // wrong spell primitive. Handled directly here using VCL since VCL has a nice and
- // very direct waveline painting which is needed for this. If VCL is to be avoided,
- // this can be removed anytime and the decomposition may be used
- const primitive2d::WrongSpellPrimitive2D& rWrongSpellPrimitive = static_cast< const primitive2d::WrongSpellPrimitive2D& >(rCandidate);
-
- if(!renderWrongSpellPrimitive2D(
- rWrongSpellPrimitive,
- *mpOutputDevice,
- getViewInformation2D().getObjectToViewTransformation(),
- maBColorModifierStack))
- {
- // fallback to decomposition (MetaFile)
- process(rWrongSpellPrimitive.get2DDecomposition(getViewInformation2D()));
- }
-
- break;
- }
-
- // nice to have:
- //
- // case PRIMITIVE2D_ID_CONTROLPRIMITIVE2D :
- // - support FormControls more direct eventually, not sure if this is needed
- // with the canvas renderer. The decomposition provides a bitmap representation
- // of the control which will work
- //
-
- default :
- {
- // process recursively
- process(rCandidate.get2DDecomposition(getViewInformation2D()));
-
- break;
- }
- }
- }
-
- //////////////////////////////////////////////////////////////////////////////
- // process support
-
- canvasProcessor2D::canvasProcessor2D(
- const geometry::ViewInformation2D& rViewInformation,
- OutputDevice& rOutDev)
- : BaseProcessor2D(rViewInformation),
- mpOutputDevice(&rOutDev),
- mxCanvas(rOutDev.GetCanvas()),
- maViewState(),
- maRenderState(),
- maBColorModifierStack(),
- maDrawinglayerOpt(),
- maClipPolyPolygon(),
- meLang(LANGUAGE_SYSTEM)
- {
- const SvtCTLOptions aSvtCTLOptions;
-
- canvas::tools::initViewState(maViewState);
- canvas::tools::initRenderState(maRenderState);
- canvas::tools::setViewStateTransform(maViewState, getViewInformation2D().getViewTransformation());
-
- // set digit language, derived from SvtCTLOptions to have the correct
- // number display for arabic/hindi numerals
- if(SvtCTLOptions::NUMERALS_HINDI == aSvtCTLOptions.GetCTLTextNumerals())
- {
- meLang = LANGUAGE_ARABIC_SAUDI_ARABIA;
- }
- else if(SvtCTLOptions::NUMERALS_ARABIC == aSvtCTLOptions.GetCTLTextNumerals())
- {
- meLang = LANGUAGE_ENGLISH;
- }
- else
- {
- meLang = (LanguageType)Application::GetSettings().GetLanguage();
- }
-
- rOutDev.SetDigitLanguage(meLang);
-
- // prepare output directly to pixels
- mpOutputDevice->Push(PUSH_MAPMODE);
- mpOutputDevice->SetMapMode();
-
- // react on AntiAliasing settings
- if(getOptionsDrawinglayer().IsAntiAliasing())
- {
- mpOutputDevice->SetAntialiasing(mpOutputDevice->GetAntialiasing() | ANTIALIASING_ENABLE_B2DDRAW);
- }
- else
- {
- mpOutputDevice->SetAntialiasing(mpOutputDevice->GetAntialiasing() & ~ANTIALIASING_ENABLE_B2DDRAW);
- }
- }
-
- canvasProcessor2D::~canvasProcessor2D()
- {
- // restore MapMode
- mpOutputDevice->Pop();
-
- // restore AntiAliasing
- mpOutputDevice->SetAntialiasing(mpOutputDevice->GetAntialiasing() & ~ANTIALIASING_ENABLE_B2DDRAW);
- }
- } // end of namespace processor2d
-} // end of namespace drawinglayer
-
-//////////////////////////////////////////////////////////////////////////////
-// eof
diff --git a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
index b39534b739fb..d93dfa5e21b6 100644
--- a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
@@ -590,7 +590,7 @@ namespace drawinglayer
Even for XFillTransparenceItem it is used, thus it may need to be supported in
UnifiedTransparencePrimitive2D, too, when interpreted as normally filled PolyPolygon.
Implemented for:
- PRIMITIVE2D_ID_POLYPOLYGONBITMAPPRIMITIVE2D,
+ PRIMITIVE2D_ID_POLYPOLYGONGRAPHICPRIMITIVE2D,
PRIMITIVE2D_ID_POLYPOLYGONHATCHPRIMITIVE2D,
PRIMITIVE2D_ID_POLYPOLYGONGRADIENTPRIMITIVE2D,
PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D,
@@ -1300,19 +1300,19 @@ namespace drawinglayer
RenderBitmapPrimitive2D(static_cast< const primitive2d::BitmapPrimitive2D& >(rCandidate));
break;
}
- case PRIMITIVE2D_ID_POLYPOLYGONBITMAPPRIMITIVE2D :
+ case PRIMITIVE2D_ID_POLYPOLYGONGRAPHICPRIMITIVE2D :
{
- // need to handle PolyPolygonBitmapPrimitive2D here to support XPATHFILL_SEQ_BEGIN/XPATHFILL_SEQ_END
- const primitive2d::PolyPolygonBitmapPrimitive2D& rBitmapCandidate = static_cast< const primitive2d::PolyPolygonBitmapPrimitive2D& >(rCandidate);
+ // need to handle PolyPolygonGraphicPrimitive2D here to support XPATHFILL_SEQ_BEGIN/XPATHFILL_SEQ_END
+ const primitive2d::PolyPolygonGraphicPrimitive2D& rBitmapCandidate = static_cast< const primitive2d::PolyPolygonGraphicPrimitive2D& >(rCandidate);
basegfx::B2DPolyPolygon aLocalPolyPolygon(rBitmapCandidate.getB2DPolyPolygon());
if(fillPolyPolygonNeededToBeSplit(aLocalPolyPolygon))
{
// #i112245# Metafiles use tools Polygon and are not able to have more than 65535 points
// per polygon. If there are more use the splitted polygon and call recursively
- const primitive2d::PolyPolygonBitmapPrimitive2D aSplitted(
+ const primitive2d::PolyPolygonGraphicPrimitive2D aSplitted(
aLocalPolyPolygon,
- rBitmapCandidate.getFillBitmap());
+ rBitmapCandidate.getFillGraphic());
processBasePrimitive2D(aSplitted);
}
@@ -1322,46 +1322,41 @@ namespace drawinglayer
if(!mnSvtGraphicFillCount && aLocalPolyPolygon.count())
{
- aLocalPolyPolygon.transform(maCurrentTransformation);
- // calculate transformation. Get real object size, all values in FillBitmapAttribute
- // are relative to the unified object
- const attribute::FillBitmapAttribute& rFillBitmapAttribute = rBitmapCandidate .getFillBitmap();
- const basegfx::B2DRange aOutlineRange(basegfx::tools::getRange(aLocalPolyPolygon));
- const basegfx::B2DVector aOutlineSize(aOutlineRange.getRange());
+ // #121194# Changed implementation and checked usages fo convert to metafile,
+ // presentation start (uses SvtGraphicFill) and printing.
- // get absolute values
- const basegfx::B2DVector aFillBitmapSize(rFillBitmapAttribute.getSize() * aOutlineSize);
- const basegfx::B2DPoint aFillBitmapTopLeft(rFillBitmapAttribute.getTopLeft() * aOutlineSize);
+ // calculate transformation. Get real object size, all values in FillGraphicAttribute
+ // are relative to the unified object
+ aLocalPolyPolygon.transform(maCurrentTransformation);
+ const basegfx::B2DVector aOutlineSize(aLocalPolyPolygon.getB2DRange().getRange());
// the scaling needs scale from pixel to logic coordinate system
- const BitmapEx& rBitmapEx = rFillBitmapAttribute.getBitmapEx();
- Size aBmpSizePixel(rBitmapEx.GetSizePixel());
-
- if(!aBmpSizePixel.Width())
- {
- aBmpSizePixel.Width() = 1;
- }
-
- if(!aBmpSizePixel.Height())
- {
- aBmpSizePixel.Height() = 1;
- }
+ const attribute::FillGraphicAttribute& rFillGraphicAttribute = rBitmapCandidate.getFillGraphic();
+ const Size aBmpSizePixel(rFillGraphicAttribute.getGraphic().GetSizePixel());
+
+ // setup transformation like in impgrfll. Multiply with aOutlineSize
+ // to get from unit coordinates in rFillGraphicAttribute.getGraphicRange()
+ // to object coordinates with object's top left being at (0,0). Divide
+ // by pixel size so that scale from pixel to logic will work in SvtGraphicFill.
+ const basegfx::B2DVector aTransformScale(
+ rFillGraphicAttribute.getGraphicRange().getRange() /
+ basegfx::B2DVector(
+ std::max(1.0, double(aBmpSizePixel.Width())),
+ std::max(1.0, double(aBmpSizePixel.Height()))) *
+ aOutlineSize);
+ const basegfx::B2DPoint aTransformPosition(
+ rFillGraphicAttribute.getGraphicRange().getMinimum() * aOutlineSize);
// setup transformation like in impgrfll
SvtGraphicFill::Transform aTransform;
// scale values are divided by bitmap pixel sizes
- aTransform.matrix[0] = aFillBitmapSize.getX() / aBmpSizePixel.Width();
- aTransform.matrix[4] = aFillBitmapSize.getY() / aBmpSizePixel.Height();
+ aTransform.matrix[0] = aTransformScale.getX();
+ aTransform.matrix[4] = aTransformScale.getY();
// translates are absolute
- aTransform.matrix[2] = aFillBitmapTopLeft.getX();
- aTransform.matrix[5] = aFillBitmapTopLeft.getY();
-
- // setup fill graphic like in impgrfll
- Graphic aFillGraphic = Graphic(rBitmapEx);
- aFillGraphic.SetPrefMapMode(MapMode(MAP_PIXEL));
- aFillGraphic.SetPrefSize(aBmpSizePixel);
+ aTransform.matrix[2] = aTransformPosition.getX();
+ aTransform.matrix[5] = aTransformPosition.getY();
pSvtGraphicFill = new SvtGraphicFill(
PolyPolygon(aLocalPolyPolygon),
@@ -1370,14 +1365,14 @@ namespace drawinglayer
SvtGraphicFill::fillEvenOdd,
SvtGraphicFill::fillTexture,
aTransform,
- rFillBitmapAttribute.getTiling(),
+ rFillGraphicAttribute.getTiling(),
SvtGraphicFill::hatchSingle,
Color(),
SvtGraphicFill::gradientLinear,
Color(),
Color(),
0,
- aFillGraphic);
+ rFillGraphicAttribute.getGraphic());
}
// Do use decomposition; encapsulate with SvtGraphicFill
@@ -1748,7 +1743,7 @@ namespace drawinglayer
}
// PolyPolygonGradientPrimitive2D, PolyPolygonHatchPrimitive2D and
- // PolyPolygonBitmapPrimitive2D are derived from PolyPolygonColorPrimitive2D.
+ // PolyPolygonGraphicPrimitive2D are derived from PolyPolygonColorPrimitive2D.
// Check also for correct ID to exclude derived implementations
if(pPoPoColor && PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D == pPoPoColor->getPrimitive2DID())
{
diff --git a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
index 92b3351025bf..1c88543168fb 100644
--- a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
@@ -31,7 +31,7 @@
#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
#include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
#include <drawinglayer/primitive2d/bitmapprimitive2d.hxx>
-#include <drawinglayer/primitive2d/fillbitmapprimitive2d.hxx>
+#include <drawinglayer/primitive2d/fillgraphicprimitive2d.hxx>
#include <drawinglayer/primitive2d/metafileprimitive2d.hxx>
#include <drawinglayer/primitive2d/maskprimitive2d.hxx>
#include <drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx>
@@ -186,10 +186,10 @@ namespace drawinglayer
RenderBitmapPrimitive2D(static_cast< const primitive2d::BitmapPrimitive2D& >(rCandidate));
break;
}
- case PRIMITIVE2D_ID_FILLBITMAPPRIMITIVE2D :
+ case PRIMITIVE2D_ID_FILLGRAPHICPRIMITIVE2D :
{
// direct draw of fillBitmapPrimitive
- RenderFillBitmapPrimitive2D(static_cast< const primitive2d::FillBitmapPrimitive2D& >(rCandidate));
+ RenderFillGraphicPrimitive2D(static_cast< const primitive2d::FillGraphicPrimitive2D& >(rCandidate));
break;
}
case PRIMITIVE2D_ID_POLYPOLYGONGRADIENTPRIMITIVE2D :
@@ -198,10 +198,10 @@ namespace drawinglayer
RenderPolyPolygonGradientPrimitive2D(static_cast< const primitive2d::PolyPolygonGradientPrimitive2D& >(rCandidate));
break;
}
- case PRIMITIVE2D_ID_POLYPOLYGONBITMAPPRIMITIVE2D :
+ case PRIMITIVE2D_ID_POLYPOLYGONGRAPHICPRIMITIVE2D :
{
// direct draw of bitmap
- RenderPolyPolygonBitmapPrimitive2D(static_cast< const primitive2d::PolyPolygonBitmapPrimitive2D& >(rCandidate));
+ RenderPolyPolygonGraphicPrimitive2D(static_cast< const primitive2d::PolyPolygonGraphicPrimitive2D& >(rCandidate));
break;
}
case PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D :
diff --git a/drawinglayer/source/processor2d/vclprocessor2d.cxx b/drawinglayer/source/processor2d/vclprocessor2d.cxx
index 80f1344ddf92..c63a8aa5ed9b 100644
--- a/drawinglayer/source/processor2d/vclprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclprocessor2d.cxx
@@ -34,8 +34,8 @@
#include <vclhelperbitmaptransform.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <vclhelperbitmaprender.hxx>
-#include <drawinglayer/attribute/sdrfillbitmapattribute.hxx>
-#include <drawinglayer/primitive2d/fillbitmapprimitive2d.hxx>
+#include <drawinglayer/attribute/sdrfillgraphicattribute.hxx>
+#include <drawinglayer/primitive2d/fillgraphicprimitive2d.hxx>
#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
#include <vclhelpergradient.hxx>
#include <drawinglayer/primitive2d/metafileprimitive2d.hxx>
@@ -59,6 +59,7 @@
#include <drawinglayer/primitive2d/svggradientprimitive2d.hxx>
#include <basegfx/color/bcolor.hxx>
#include <basegfx/matrix/b2dhommatrixtools.hxx>
+#include <vcl/graph.hxx>
//////////////////////////////////////////////////////////////////////////////
// control support
@@ -448,122 +449,192 @@ namespace drawinglayer
}
}
- void VclProcessor2D::RenderFillBitmapPrimitive2D(const primitive2d::FillBitmapPrimitive2D& rFillBitmapCandidate)
+ void VclProcessor2D::RenderFillGraphicPrimitive2D(const primitive2d::FillGraphicPrimitive2D& rFillBitmapCandidate)
{
- const attribute::FillBitmapAttribute& rFillBitmapAttribute(rFillBitmapCandidate.getFillBitmap());
+ const attribute::FillGraphicAttribute& rFillGraphicAttribute(rFillBitmapCandidate.getFillGraphic());
bool bPrimitiveAccepted(false);
+ static bool bTryTilingDirect = true;
- if(rFillBitmapAttribute.getTiling())
- {
- // decompose matrix to check for shear, rotate and mirroring
- basegfx::B2DHomMatrix aLocalTransform(maCurrentTransformation * rFillBitmapCandidate.getTransformation());
- basegfx::B2DVector aScale, aTranslate;
- double fRotate, fShearX;
- aLocalTransform.decompose(aScale, aTranslate, fRotate, fShearX);
+ // #121194# when tiling is used and content is bitmap-based, do direct tiling in the
+ // renderer on pixel base to ensure tight fitting. Do not do this when
+ // the fill is rotated or sheared.
- if(basegfx::fTools::equalZero(fRotate) && basegfx::fTools::equalZero(fShearX))
+ // ovveride static bool (for debug) and tiling is active
+ if(bTryTilingDirect && rFillGraphicAttribute.getTiling())
+ {
+ // content is bitmap(ex)
+ //
+ // for SVG support, force decomposition when SVG is present. This will lead to use
+ // the primitive representation of the svg directly.
+ //
+ // when graphic is animated, force decomposition to use the correct graphic, else
+ // fill style will not be animated
+ if(GRAPHIC_BITMAP == rFillGraphicAttribute.getGraphic().GetType()
+ && !rFillGraphicAttribute.getGraphic().getSvgData().get()
+ && !rFillGraphicAttribute.getGraphic().IsAnimated())
{
- // no shear or rotate, draw direct in pixel coordinates
- bPrimitiveAccepted = true;
- BitmapEx aBitmapEx(rFillBitmapAttribute.getBitmapEx());
- bool bPainted(false);
-
- if(maBColorModifierStack.count())
+ // decompose matrix to check for shear, rotate and mirroring
+ basegfx::B2DHomMatrix aLocalTransform(maCurrentTransformation * rFillBitmapCandidate.getTransformation());
+ basegfx::B2DVector aScale, aTranslate;
+ double fRotate, fShearX;
+ aLocalTransform.decompose(aScale, aTranslate, fRotate, fShearX);
+
+ // when nopt rotated/sheared
+ if(basegfx::fTools::equalZero(fRotate) && basegfx::fTools::equalZero(fShearX))
{
- aBitmapEx = impModifyBitmapEx(maBColorModifierStack, aBitmapEx);
-
- if(aBitmapEx.IsEmpty())
- {
- // color gets completely replaced, get it
- const basegfx::BColor aModifiedColor(maBColorModifierStack.getModifiedColor(basegfx::BColor()));
- basegfx::B2DPolygon aPolygon(basegfx::tools::createUnitPolygon());
- aPolygon.transform(aLocalTransform);
+ // no shear or rotate, draw direct in pixel coordinates
+ bPrimitiveAccepted = true;
- mpOutputDevice->SetFillColor(Color(aModifiedColor));
- mpOutputDevice->SetLineColor();
- mpOutputDevice->DrawPolygon(aPolygon);
+ // transform object range to device coordinates (pixels). Use
+ // the device transformation for better accuracy
+ basegfx::B2DRange aObjectRange(aTranslate, aTranslate + aScale);
+ aObjectRange.transform(mpOutputDevice->GetViewTransformation());
- bPainted = true;
- }
- }
-
- if(!bPainted)
- {
- const basegfx::B2DPoint aObjTopLeft(aTranslate.getX(), aTranslate.getY());
- const basegfx::B2DPoint aObjBottomRight(aTranslate.getX() + aScale.getX(), aTranslate.getY() + aScale.getY());
- const Point aObjTL(mpOutputDevice->LogicToPixel(Point((sal_Int32)aObjTopLeft.getX(), (sal_Int32)aObjTopLeft.getY())));
- const Point aObjBR(mpOutputDevice->LogicToPixel(Point((sal_Int32)aObjBottomRight.getX(), (sal_Int32)aObjBottomRight.getY())));
-
- const basegfx::B2DPoint aBmpTopLeft(aLocalTransform * rFillBitmapAttribute.getTopLeft());
- const basegfx::B2DPoint aBmpBottomRight(aLocalTransform * basegfx::B2DPoint(rFillBitmapAttribute.getTopLeft() + rFillBitmapAttribute.getSize()));
- const Point aBmpTL(mpOutputDevice->LogicToPixel(Point((sal_Int32)aBmpTopLeft.getX(), (sal_Int32)aBmpTopLeft.getY())));
- const Point aBmpBR(mpOutputDevice->LogicToPixel(Point((sal_Int32)aBmpBottomRight.getX(), (sal_Int32)aBmpBottomRight.getY())));
-
- sal_Int32 nOWidth(aObjBR.X() - aObjTL.X());
- sal_Int32 nOHeight(aObjBR.Y() - aObjTL.Y());
+ // extract discrete size of object
+ const sal_Int32 nOWidth(basegfx::fround(aObjectRange.getWidth()));
+ const sal_Int32 nOHeight(basegfx::fround(aObjectRange.getHeight()));
// only do something when object has a size in discrete units
if(nOWidth > 0 && nOHeight > 0)
{
- sal_Int32 nBWidth(aBmpBR.X() - aBmpTL.X());
- sal_Int32 nBHeight(aBmpBR.Y() - aBmpTL.Y());
+ // transform graphic range to device coordinates (pixels). Use
+ // the device transformation for better accuracy
+ basegfx::B2DRange aGraphicRange(rFillGraphicAttribute.getGraphicRange());
+ aGraphicRange.transform(mpOutputDevice->GetViewTransformation() * aLocalTransform);
+
+ // extract discrete size of graphic
+ const sal_Int32 nBWidth(basegfx::fround(aGraphicRange.getWidth()));
+ const sal_Int32 nBHeight(basegfx::fround(aGraphicRange.getHeight()));
// only do something when bitmap fill has a size in discrete units
if(nBWidth > 0 && nBHeight > 0)
{
- sal_Int32 nBLeft(aBmpTL.X());
- sal_Int32 nBTop(aBmpTL.Y());
-
- if(nBLeft > aObjTL.X())
+ // nBWidth, nBHeight is the pixel size of the neede bitmap. To not need to scale it
+ // in vcl many times, create a size-optimized version
+ const Size aNeededBitmapSizePixel(nBWidth, nBHeight);
+ BitmapEx aBitmapEx(rFillGraphicAttribute.getGraphic().GetBitmapEx(
+ GraphicConversionParameters(
+ aNeededBitmapSizePixel, // get the correct size immediately
+ false, // no unlimited size
+ false, // Use AntiAliasing
+ false, //SnapHorVerLines
+ true // ScaleHighQuality
+ )));
+ bool bPainted(false);
+
+ if(maBColorModifierStack.count())
{
- nBLeft -= ((nBLeft / nBWidth) + 1L) * nBWidth;
- }
+ // when color modifier, apply to bitmap
+ aBitmapEx = impModifyBitmapEx(maBColorModifierStack, aBitmapEx);
- if(nBLeft + nBWidth <= aObjTL.X())
- {
- nBLeft -= (nBLeft / nBWidth) * nBWidth;
- }
+ // impModifyBitmapEx uses empty bitmap as sign to return that
+ // the content will be completely replaced to mono color, use shortcut
+ if(aBitmapEx.IsEmpty())
+ {
+ // color gets completely replaced, get it
+ const basegfx::BColor aModifiedColor(maBColorModifierStack.getModifiedColor(basegfx::BColor()));
+ basegfx::B2DPolygon aPolygon(basegfx::tools::createUnitPolygon());
+ aPolygon.transform(aLocalTransform);
- if(nBTop > aObjTL.Y())
- {
- nBTop -= ((nBTop / nBHeight) + 1L) * nBHeight;
+ mpOutputDevice->SetFillColor(Color(aModifiedColor));
+ mpOutputDevice->SetLineColor();
+ mpOutputDevice->DrawPolygon(aPolygon);
+
+ bPainted = true;
+ }
}
- if(nBTop + nBHeight <= aObjTL.Y())
+ if(!bPainted)
{
- nBTop -= (nBTop / nBHeight) * nBHeight;
- }
+ sal_Int32 nBLeft(basegfx::fround(aGraphicRange.getMinX()));
+ sal_Int32 nBTop(basegfx::fround(aGraphicRange.getMinY()));
+ const sal_Int32 nOLeft(basegfx::fround(aObjectRange.getMinX()));
+ const sal_Int32 nOTop(basegfx::fround(aObjectRange.getMinY()));
+ sal_Int32 nPosX(0);
+ sal_Int32 nPosY(0);
+
+ if(nBLeft > nOLeft)
+ {
+ const sal_Int32 nDiff((nBLeft / nBWidth) + 1);
- // nBWidth, nBHeight is the pixel size of the neede bitmap. To not need to scale it
- // in vcl many times, create a size-optimized version
- const Size aNeededBitmapSizePixel(nBWidth, nBHeight);
+ nPosX -= nDiff;
+ nBLeft -= nDiff * nBWidth;
+ }
- if(aNeededBitmapSizePixel != aBitmapEx.GetSizePixel())
- {
- aBitmapEx.Scale(aNeededBitmapSizePixel);
- }
+ if(nBLeft + nBWidth <= nOLeft)
+ {
+ const sal_Int32 nDiff(-nBLeft / nBWidth);
- // prepare OutDev
- const Point aEmptyPoint(0, 0);
- const Rectangle aVisiblePixel(aEmptyPoint, mpOutputDevice->GetOutputSizePixel());
- const bool bWasEnabled(mpOutputDevice->IsMapModeEnabled());
- mpOutputDevice->EnableMapMode(false);
+ nPosX += nDiff;
+ nBLeft += nDiff * nBWidth;
+ }
- for(sal_Int32 nXPos(nBLeft); nXPos < aObjTL.X() + nOWidth; nXPos += nBWidth)
- {
- for(sal_Int32 nYPos(nBTop); nYPos < aObjTL.Y() + nOHeight; nYPos += nBHeight)
+ if(nBTop > nOTop)
+ {
+ const sal_Int32 nDiff((nBTop / nBHeight) + 1);
+
+ nPosY -= nDiff;
+ nBTop -= nDiff * nBHeight;
+ }
+
+ if(nBTop + nBHeight <= nOTop)
+ {
+ const sal_Int32 nDiff(-nBTop / nBHeight);
+
+ nPosY += nDiff;
+ nBTop += nDiff * nBHeight;
+ }
+
+ // prepare OutDev
+ const Point aEmptyPoint(0, 0);
+ const Rectangle aVisiblePixel(aEmptyPoint, mpOutputDevice->GetOutputSizePixel());
+ const bool bWasEnabled(mpOutputDevice->IsMapModeEnabled());
+ mpOutputDevice->EnableMapMode(false);
+
+ // check if offset is used
+ const sal_Int32 nOffsetX(basegfx::fround(rFillGraphicAttribute.getOffsetX() * nBWidth));
+
+ if(nOffsetX)
+ {
+ // offset in X, so iterate over Y first and draw lines
+ for(sal_Int32 nYPos(nBTop); nYPos < nOTop + nOHeight; nYPos += nBHeight, nPosY++)
+ {
+ for(sal_Int32 nXPos(nPosY % 2 ? nBLeft - nBWidth + nOffsetX : nBLeft);
+ nXPos < nOLeft + nOWidth; nXPos += nBWidth)
+ {
+ const Rectangle aOutRectPixel(Point(nXPos, nYPos), aNeededBitmapSizePixel);
+
+ if(aOutRectPixel.IsOver(aVisiblePixel))
+ {
+ mpOutputDevice->DrawBitmapEx(aOutRectPixel.TopLeft(), aBitmapEx);
+ }
+ }
+ }
+ }
+ else
{
- const Rectangle aOutRectPixel(Point(nXPos, nYPos), aNeededBitmapSizePixel);
+ // check if offset is used
+ const sal_Int32 nOffsetY(basegfx::fround(rFillGraphicAttribute.getOffsetY() * nBHeight));
- if(aOutRectPixel.IsOver(aVisiblePixel))
+ // possible offset in Y, so iterate over X first and draw columns
+ for(sal_Int32 nXPos(nBLeft); nXPos < nOLeft + nOWidth; nXPos += nBWidth, nPosX++)
{
- mpOutputDevice->DrawBitmapEx(aOutRectPixel.TopLeft(), aBitmapEx);
+ for(sal_Int32 nYPos(nPosX % 2 ? nBTop - nBHeight + nOffsetY : nBTop);
+ nYPos < nOTop + nOHeight; nYPos += nBHeight)
+ {
+ const Rectangle aOutRectPixel(Point(nXPos, nYPos), aNeededBitmapSizePixel);
+
+ if(aOutRectPixel.IsOver(aVisiblePixel))
+ {
+ mpOutputDevice->DrawBitmapEx(aOutRectPixel.TopLeft(), aBitmapEx);
+ }
+ }
}
}
- }
- // restore OutDev
- mpOutputDevice->EnableMapMode(bWasEnabled);
+ // restore OutDev
+ mpOutputDevice->EnableMapMode(bWasEnabled);
+ }
}
}
}
@@ -615,90 +686,105 @@ namespace drawinglayer
}
}
- // direct draw of bitmap
- void VclProcessor2D::RenderPolyPolygonBitmapPrimitive2D(const primitive2d::PolyPolygonBitmapPrimitive2D& rPolygonCandidate)
+ // direct draw of Graphic
+ void VclProcessor2D::RenderPolyPolygonGraphicPrimitive2D(const primitive2d::PolyPolygonGraphicPrimitive2D& rPolygonCandidate)
{
bool bDone(false);
const basegfx::B2DPolyPolygon& rPolyPolygon = rPolygonCandidate.getB2DPolyPolygon();
- if(rPolyPolygon.count())
+ // #121194# Todo: check if this works
+ if(!rPolyPolygon.count())
{
- const attribute::FillBitmapAttribute& rFillBitmapAttribute = rPolygonCandidate.getFillBitmap();
- const BitmapEx& rBitmapEx = rFillBitmapAttribute.getBitmapEx();
+ // empty polyPolygon, done
+ bDone = true;
+ }
+ else
+ {
+ const attribute::FillGraphicAttribute& rFillGraphicAttribute = rPolygonCandidate.getFillGraphic();
- if(rBitmapEx.IsEmpty())
- {
- // empty bitmap, done
- bDone = true;
- }
- else
+ // try to catch cases where the graphic will be color-modified to a single
+ // color (e.g. shadow)
+ switch(rFillGraphicAttribute.getGraphic().GetType())
{
- // try to catch cases where the bitmap will be color-modified to a single
- // color (e.g. shadow). This would NOT be optimizable with an transparence channel
- // at the Bitmap which we do not have here. When this should change, this
- // optimization has to be reworked accordingly.
- const sal_uInt32 nBColorModifierStackCount(maBColorModifierStack.count());
-
- if(nBColorModifierStackCount)
+ case GRAPHIC_GDIMETAFILE:
{
- const basegfx::BColorModifier& rTopmostModifier = maBColorModifierStack.getBColorModifier(nBColorModifierStackCount - 1);
-
- if(basegfx::BCOLORMODIFYMODE_REPLACE == rTopmostModifier.getMode())
+ // metafiles are potentially transparent, cannot optimize, not done
+ break;
+ }
+ case GRAPHIC_BITMAP:
+ {
+ if(!rFillGraphicAttribute.getGraphic().IsTransparent() && !rFillGraphicAttribute.getGraphic().IsAlpha())
{
- // the bitmap fill is in unified color, so we can replace it with
- // a single polygon fill. The form of the fill depends on tiling
- if(rFillBitmapAttribute.getTiling())
- {
- // with tiling, fill the whole PolyPolygon with the modifier color
- basegfx::B2DPolyPolygon aLocalPolyPolygon(rPolyPolygon);
+ // bitmap is not transparent and has no alpha
+ const sal_uInt32 nBColorModifierStackCount(maBColorModifierStack.count());
- aLocalPolyPolygon.transform(maCurrentTransformation);
- mpOutputDevice->SetLineColor();
- mpOutputDevice->SetFillColor(Color(rTopmostModifier.getBColor()));
- mpOutputDevice->DrawPolyPolygon(aLocalPolyPolygon);
- }
- else
+ if(nBColorModifierStackCount)
{
- // without tiling, only the area common to the bitmap tile and the
- // PolyPolygon is filled. Create the bitmap tile area in object
- // coordinates. For this, the object transformation needs to be created
- // from the already scaled PolyPolygon. The tile area in object
- // coordinates wil always be non-rotated, so it's not necessary to
- // work with a polygon here
- basegfx::B2DRange aTileRange(rFillBitmapAttribute.getTopLeft(),
- rFillBitmapAttribute.getTopLeft() + rFillBitmapAttribute.getSize());
- const basegfx::B2DRange aPolyPolygonRange(rPolyPolygon.getB2DRange());
- basegfx::B2DHomMatrix aNewObjectTransform;
-
- aNewObjectTransform.set(0, 0, aPolyPolygonRange.getWidth());
- aNewObjectTransform.set(1, 1, aPolyPolygonRange.getHeight());
- aNewObjectTransform.set(0, 2, aPolyPolygonRange.getMinX());
- aNewObjectTransform.set(1, 2, aPolyPolygonRange.getMinY());
- aTileRange.transform(aNewObjectTransform);
-
- // now clip the object polyPolygon against the tile range
- // to get the common area (OR)
- basegfx::B2DPolyPolygon aTarget = basegfx::tools::clipPolyPolygonOnRange(rPolyPolygon, aTileRange, true, false);
-
- if(aTarget.count())
+ const basegfx::BColorModifier& rTopmostModifier = maBColorModifierStack.getBColorModifier(nBColorModifierStackCount - 1);
+
+ if(basegfx::BCOLORMODIFYMODE_REPLACE == rTopmostModifier.getMode())
{
- aTarget.transform(maCurrentTransformation);
- mpOutputDevice->SetLineColor();
- mpOutputDevice->SetFillColor(Color(rTopmostModifier.getBColor()));
- mpOutputDevice->DrawPolyPolygon(aTarget);
+ // the bitmap fill is in unified color, so we can replace it with
+ // a single polygon fill. The form of the fill depends on tiling
+ if(rFillGraphicAttribute.getTiling())
+ {
+ // with tiling, fill the whole PolyPolygon with the modifier color
+ basegfx::B2DPolyPolygon aLocalPolyPolygon(rPolyPolygon);
+
+ aLocalPolyPolygon.transform(maCurrentTransformation);
+ mpOutputDevice->SetLineColor();
+ mpOutputDevice->SetFillColor(Color(rTopmostModifier.getBColor()));
+ mpOutputDevice->DrawPolyPolygon(aLocalPolyPolygon);
+ }
+ else
+ {
+ // without tiling, only the area common to the bitmap tile and the
+ // PolyPolygon is filled. Create the bitmap tile area in object
+ // coordinates. For this, the object transformation needs to be created
+ // from the already scaled PolyPolygon. The tile area in object
+ // coordinates wil always be non-rotated, so it's not necessary to
+ // work with a polygon here
+ basegfx::B2DRange aTileRange(rFillGraphicAttribute.getGraphicRange());
+ const basegfx::B2DRange aPolyPolygonRange(rPolyPolygon.getB2DRange());
+ const basegfx::B2DHomMatrix aNewObjectTransform(
+ basegfx::tools::createScaleTranslateB2DHomMatrix(
+ aPolyPolygonRange.getRange(),
+ aPolyPolygonRange.getMinimum()));
+
+ aTileRange.transform(aNewObjectTransform);
+
+ // now clip the object polyPolygon against the tile range
+ // to get the common area
+ basegfx::B2DPolyPolygon aTarget = basegfx::tools::clipPolyPolygonOnRange(
+ rPolyPolygon,
+ aTileRange,
+ true,
+ false);
+
+ if(aTarget.count())
+ {
+ aTarget.transform(maCurrentTransformation);
+ mpOutputDevice->SetLineColor();
+ mpOutputDevice->SetFillColor(Color(rTopmostModifier.getBColor()));
+ mpOutputDevice->DrawPolyPolygon(aTarget);
+ }
+ }
+
+ // simplified output executed, we are done
+ bDone = true;
}
}
-
- bDone = true;
}
+ break;
+ }
+ default: //GRAPHIC_NONE, GRAPHIC_DEFAULT
+ {
+ // empty graphic, we are done
+ bDone = true;
+ break;
}
}
}
- else
- {
- // empty polyPolygon, done
- bDone = true;
- }
if(!bDone)
{
diff --git a/drawinglayer/source/processor3d/defaultprocessor3d.cxx b/drawinglayer/source/processor3d/defaultprocessor3d.cxx
index aeb269f69a22..0745920b516f 100644
--- a/drawinglayer/source/processor3d/defaultprocessor3d.cxx
+++ b/drawinglayer/source/processor3d/defaultprocessor3d.cxx
@@ -41,6 +41,8 @@
#include <vcl/bitmapex.hxx>
#include <drawinglayer/attribute/sdrsceneattribute3d.hxx>
#include <drawinglayer/attribute/sdrlightingattribute3d.hxx>
+#include <vcl/graph.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
//////////////////////////////////////////////////////////////////////////////
@@ -217,21 +219,33 @@ namespace drawinglayer
boost::shared_ptr< texture::GeoTexSvx > pOldTex = mpGeoTexSvx;
// create texture
- const attribute::FillBitmapAttribute& rFillBitmapAttribute = rPrimitive.getFillBitmapAttribute();
+ const attribute::FillGraphicAttribute& rFillGraphicAttribute = rPrimitive.getFillGraphicAttribute();
- if(rFillBitmapAttribute.getTiling())
+ // #121194# For 3D texture we will use the BitmapRex representation
+ const BitmapEx aBitmapEx(rFillGraphicAttribute.getGraphic().GetBitmapEx());
+
+ // create range scaled by texture size
+ basegfx::B2DRange aGraphicRange(rFillGraphicAttribute.getGraphicRange());
+
+ aGraphicRange.transform(
+ basegfx::tools::createScaleB2DHomMatrix(
+ rPrimitive.getTextureSize()));
+
+ if(rFillGraphicAttribute.getTiling())
{
- mpGeoTexSvx.reset(new texture::GeoTexSvxBitmapTiled(
- rFillBitmapAttribute.getBitmapEx().GetBitmap(),
- rFillBitmapAttribute.getTopLeft() * rPrimitive.getTextureSize(),
- rFillBitmapAttribute.getSize() * rPrimitive.getTextureSize()));
+ mpGeoTexSvx.reset(
+ new texture::GeoTexSvxBitmapExTiled(
+ aBitmapEx,
+ aGraphicRange,
+ rFillGraphicAttribute.getOffsetX(),
+ rFillGraphicAttribute.getOffsetY()));
}
else
{
- mpGeoTexSvx.reset(new texture::GeoTexSvxBitmap(
- rFillBitmapAttribute.getBitmapEx().GetBitmap(),
- rFillBitmapAttribute.getTopLeft() * rPrimitive.getTextureSize(),
- rFillBitmapAttribute.getSize() * rPrimitive.getTextureSize()));
+ mpGeoTexSvx.reset(
+ new texture::GeoTexSvxBitmapEx(
+ aBitmapEx,
+ aGraphicRange));
}
// process sub-list
diff --git a/drawinglayer/source/texture/texture.cxx b/drawinglayer/source/texture/texture.cxx
index acabc397f4cb..937018c7ecde 100644
--- a/drawinglayer/source/texture/texture.cxx
+++ b/drawinglayer/source/texture/texture.cxx
@@ -610,19 +610,16 @@ namespace drawinglayer
namespace texture
{
GeoTexSvxTiled::GeoTexSvxTiled(
- const basegfx::B2DPoint& rTopLeft,
- const basegfx::B2DVector& rSize)
- : maTopLeft(rTopLeft),
- maSize(rSize)
+ const basegfx::B2DRange& rRange,
+ double fOffsetX,
+ double fOffsetY)
+ : maRange(rRange),
+ mfOffsetX(basegfx::clamp(fOffsetX, 0.0, 1.0)),
+ mfOffsetY(basegfx::clamp(fOffsetY, 0.0, 1.0))
{
- if(basegfx::fTools::lessOrEqual(maSize.getX(), 0.0))
- {
- maSize.setX(1.0);
- }
-
- if(basegfx::fTools::lessOrEqual(maSize.getY(), 0.0))
+ if(!basegfx::fTools::equalZero(mfOffsetX))
{
- maSize.setY(1.0);
+ mfOffsetY = 0.0;
}
}
@@ -633,48 +630,92 @@ namespace drawinglayer
bool GeoTexSvxTiled::operator==(const GeoTexSvx& rGeoTexSvx) const
{
const GeoTexSvxTiled* pCompare = dynamic_cast< const GeoTexSvxTiled* >(&rGeoTexSvx);
+
return (pCompare
- && maTopLeft == pCompare->maTopLeft
- && maSize == pCompare->maSize);
+ && maRange == pCompare->maRange
+ && mfOffsetX == pCompare->mfOffsetX
+ && mfOffsetY == pCompare->mfOffsetY);
}
void GeoTexSvxTiled::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
{
- double fStartX(maTopLeft.getX());
- double fStartY(maTopLeft.getY());
+ const double fWidth(maRange.getWidth());
- if(basegfx::fTools::more(fStartX, 0.0))
+ if(!basegfx::fTools::equalZero(fWidth))
{
- fStartX -= (floor(fStartX / maSize.getX()) + 1.0) * maSize.getX();
- }
-
- if(basegfx::fTools::less(fStartX + maSize.getX(), 0.0))
- {
- fStartX += floor(-fStartX / maSize.getX()) * maSize.getX();
- }
+ const double fHeight(maRange.getHeight());
- if(basegfx::fTools::more(fStartY, 0.0))
- {
- fStartY -= (floor(fStartY / maSize.getY()) + 1.0) * maSize.getY();
- }
-
- if(basegfx::fTools::less(fStartY + maSize.getY(), 0.0))
- {
- fStartY += floor(-fStartY / maSize.getY()) * maSize.getY();
- }
-
- for(double fPosY(fStartY); basegfx::fTools::less(fPosY, 1.0); fPosY += maSize.getY())
- {
- for(double fPosX(fStartX); basegfx::fTools::less(fPosX, 1.0); fPosX += maSize.getX())
+ if(!basegfx::fTools::equalZero(fHeight))
{
- basegfx::B2DHomMatrix aNew;
-
- aNew.set(0, 0, maSize.getX());
- aNew.set(1, 1, maSize.getY());
- aNew.set(0, 2, fPosX);
- aNew.set(1, 2, fPosY);
-
- rMatrices.push_back(aNew);
+ double fStartX(maRange.getMinX());
+ double fStartY(maRange.getMinY());
+ sal_Int32 nPosX(0);
+ sal_Int32 nPosY(0);
+
+ if(basegfx::fTools::more(fStartX, 0.0))
+ {
+ const sal_Int32 nDiff(static_cast<sal_Int32>(floor(fStartX / fWidth)) + 1);
+
+ nPosX -= nDiff;
+ fStartX -= nDiff * fWidth;
+ }
+
+ if(basegfx::fTools::less(fStartX + fWidth, 0.0))
+ {
+ const sal_Int32 nDiff(static_cast<sal_Int32>(floor(-fStartX / fWidth)));
+
+ nPosX += nDiff;
+ fStartX += nDiff * fWidth;
+ }
+
+ if(basegfx::fTools::more(fStartY, 0.0))
+ {
+ const sal_Int32 nDiff(static_cast<sal_Int32>(floor(fStartY / fHeight)) + 1);
+
+ nPosY -= nDiff;
+ fStartY -= nDiff * fHeight;
+ }
+
+ if(basegfx::fTools::less(fStartY + fHeight, 0.0))
+ {
+ const sal_Int32 nDiff(static_cast<sal_Int32>(floor(-fStartY / fHeight)));
+
+ nPosY += nDiff;
+ fStartY += nDiff * fHeight;
+ }
+
+ if(!basegfx::fTools::equalZero(mfOffsetY))
+ {
+ for(double fPosX(fStartX); basegfx::fTools::less(fPosX, 1.0); fPosX += fWidth, nPosX++)
+ {
+ for(double fPosY(nPosX % 2 ? fStartY - fHeight + (mfOffsetY * fHeight) : fStartY);
+ basegfx::fTools::less(fPosY, 1.0); fPosY += fHeight)
+ {
+ rMatrices.push_back(
+ basegfx::tools::createScaleTranslateB2DHomMatrix(
+ fWidth,
+ fHeight,
+ fPosX,
+ fPosY));
+ }
+ }
+ }
+ else
+ {
+ for(double fPosY(fStartY); basegfx::fTools::less(fPosY, 1.0); fPosY += fHeight, nPosY++)
+ {
+ for(double fPosX(nPosY % 2 ? fStartX - fWidth + (mfOffsetX * fWidth) : fStartX);
+ basegfx::fTools::less(fPosX, 1.0); fPosX += fWidth)
+ {
+ rMatrices.push_back(
+ basegfx::tools::createScaleTranslateB2DHomMatrix(
+ fWidth,
+ fHeight,
+ fPosX,
+ fPosY));
+ }
+ }
+ }
}
}
}
diff --git a/drawinglayer/source/texture/texture3d.cxx b/drawinglayer/source/texture/texture3d.cxx
index 3f10cd0d50f5..27cd94984953 100644
--- a/drawinglayer/source/texture/texture3d.cxx
+++ b/drawinglayer/source/texture/texture3d.cxx
@@ -34,7 +34,9 @@ namespace drawinglayer
{
namespace texture
{
- GeoTexSvxMono::GeoTexSvxMono(const basegfx::BColor& rSingleColor, double fOpacity)
+ GeoTexSvxMono::GeoTexSvxMono(
+ const basegfx::BColor& rSingleColor,
+ double fOpacity)
: maSingleColor(rSingleColor),
mfOpacity(fOpacity)
{
@@ -43,6 +45,7 @@ namespace drawinglayer
bool GeoTexSvxMono::operator==(const GeoTexSvx& rGeoTexSvx) const
{
const GeoTexSvxMono* pCompare = dynamic_cast< const GeoTexSvxMono* >(&rGeoTexSvx);
+
return (pCompare
&& maSingleColor == pCompare->maSingleColor
&& mfOpacity == pCompare->mfOpacity);
@@ -66,56 +69,144 @@ namespace drawinglayer
{
namespace texture
{
- GeoTexSvxBitmap::GeoTexSvxBitmap(const Bitmap& rBitmap, const basegfx::B2DPoint& rTopLeft, const basegfx::B2DVector& rSize)
- : maBitmap(rBitmap),
- mpRead(0L),
- maTopLeft(rTopLeft),
- maSize(rSize),
+ GeoTexSvxBitmapEx::GeoTexSvxBitmapEx(
+ const BitmapEx& rBitmapEx,
+ const basegfx::B2DRange& rRange)
+ : maBitmapEx(rBitmapEx),
+ mpReadBitmap(0),
+ maTransparence(),
+ mpReadTransparence(0),
+ maTopLeft(rRange.getMinimum()),
+ maSize(rRange.getRange()),
mfMulX(0.0),
- mfMulY(0.0)
+ mfMulY(0.0),
+ mbIsAlpha(false),
+ mbIsTransparent(maBitmapEx.IsTransparent())
+ {
+ // #121194# Todo: use alpha channel, too (for 3d)
+ mpReadBitmap = maBitmapEx.GetBitmap().AcquireReadAccess();
+ OSL_ENSURE(mpReadBitmap, "GeoTexSvxBitmapEx: Got no read access to Bitmap (!)");
+
+ if(mbIsTransparent)
+ {
+ if(maBitmapEx.IsAlpha())
+ {
+ mbIsAlpha = true;
+ maTransparence = rBitmapEx.GetAlpha().GetBitmap();
+ }
+ else
+ {
+ maTransparence = rBitmapEx.GetMask();
+ }
+
+ mpReadTransparence = maTransparence.AcquireReadAccess();
+ }
+
+ mfMulX = (double)mpReadBitmap->Width() / maSize.getX();
+ mfMulY = (double)mpReadBitmap->Height() / maSize.getY();
+
+ if(maSize.getX() <= 1.0)
+ {
+ maSize.setX(1.0);
+ }
+
+ if(maSize.getY() <= 1.0)
+ {
+ maSize.setY(1.0);
+ }
+ }
+
+ GeoTexSvxBitmapEx::~GeoTexSvxBitmapEx()
{
- mpRead = maBitmap.AcquireReadAccess();
- OSL_ENSURE(mpRead, "GeoTexSvxBitmap: Got no read access to Bitmap (!)");
- mfMulX = (double)mpRead->Width() / maSize.getX();
- mfMulY = (double)mpRead->Height() / maSize.getY();
+ delete mpReadTransparence;
+ delete mpReadBitmap;
}
- GeoTexSvxBitmap::~GeoTexSvxBitmap()
+ sal_uInt8 GeoTexSvxBitmapEx::impGetTransparence(sal_Int32& rX, sal_Int32& rY) const
{
- delete mpRead;
+ switch(maBitmapEx.GetTransparentType())
+ {
+ case TRANSPARENT_NONE:
+ {
+ break;
+ }
+ case TRANSPARENT_COLOR:
+ {
+ const Color aColor(mpReadBitmap->GetColor(rY, rX));
+
+ if(maBitmapEx.GetTransparentColor() == aColor)
+ {
+ return 255;
+ }
+
+ break;
+ }
+ case TRANSPARENT_BITMAP:
+ {
+ OSL_ENSURE(mpReadTransparence, "OOps, transparence type Bitmap, but no read access created in the constructor (?)");
+ const BitmapColor aBitmapColor(mpReadTransparence->GetPixel(rY, rX));
+
+ if(mbIsAlpha)
+ {
+ return aBitmapColor.GetIndex();
+ }
+ else
+ {
+ if(0x00 != aBitmapColor.GetIndex())
+ {
+ return 255;
+ }
+ }
+ break;
+ }
+ }
+
+ return 0;
}
- bool GeoTexSvxBitmap::impIsValid(const basegfx::B2DPoint& rUV, sal_Int32& rX, sal_Int32& rY) const
+ bool GeoTexSvxBitmapEx::impIsValid(const basegfx::B2DPoint& rUV, sal_Int32& rX, sal_Int32& rY) const
{
- if(mpRead)
+ if(mpReadBitmap)
{
rX = (sal_Int32)((rUV.getX() - maTopLeft.getX()) * mfMulX);
- if(rX >= 0L && rX < mpRead->Width())
+ if(rX >= 0L && rX < mpReadBitmap->Width())
{
rY = (sal_Int32)((rUV.getY() - maTopLeft.getY()) * mfMulY);
- return (rY >= 0L && rY < mpRead->Height());
+ return (rY >= 0L && rY < mpReadBitmap->Height());
}
}
return false;
}
- void GeoTexSvxBitmap::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& rfOpacity) const
+ void GeoTexSvxBitmapEx::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& rfOpacity) const
{
sal_Int32 nX, nY;
if(impIsValid(rUV, nX, nY))
{
const double fConvertColor(1.0 / 255.0);
- const BitmapColor aBMCol(mpRead->GetColor(nY, nX));
+ const BitmapColor aBMCol(mpReadBitmap->GetColor(nY, nX));
const basegfx::BColor aBSource(
(double)aBMCol.GetRed() * fConvertColor,
(double)aBMCol.GetGreen() * fConvertColor,
(double)aBMCol.GetBlue() * fConvertColor);
rBColor = aBSource;
+
+ if(mbIsTransparent)
+ {
+ // when we have a transparence, make use of it
+ const sal_uInt8 aLuminance(impGetTransparence(nX, nY));
+
+ rfOpacity = ((double)(0xff - aLuminance) * (1.0 / 255.0));
+ }
+ else
+ {
+ rfOpacity = 1.0;
+ }
}
else
{
@@ -123,16 +214,28 @@ namespace drawinglayer
}
}
- void GeoTexSvxBitmap::modifyOpacity(const basegfx::B2DPoint& rUV, double& rfOpacity) const
+ void GeoTexSvxBitmapEx::modifyOpacity(const basegfx::B2DPoint& rUV, double& rfOpacity) const
{
sal_Int32 nX, nY;
if(impIsValid(rUV, nX, nY))
{
- const BitmapColor aBMCol(mpRead->GetColor(nY, nX));
- const Color aColor(aBMCol.GetRed(), aBMCol.GetGreen(), aBMCol.GetBlue());
+ if(mbIsTransparent)
+ {
+ // this texture has an alpha part, use it
+ const sal_uInt8 aLuminance(impGetTransparence(nX, nY));
+ const double fNewOpacity((double)(0xff - aLuminance) * (1.0 / 255.0));
+
+ rfOpacity = 1.0 - ((1.0 - fNewOpacity) * (1.0 - rfOpacity));
+ }
+ else
+ {
+ // this texture is a color bitmap used as transparence map
+ const BitmapColor aBMCol(mpReadBitmap->GetColor(nY, nX));
+ const Color aColor(aBMCol.GetRed(), aBMCol.GetGreen(), aBMCol.GetBlue());
- rfOpacity = ((double)(0xff - aColor.GetLuminance()) * (1.0 / 255.0));
+ rfOpacity = ((double)(0xff - aColor.GetLuminance()) * (1.0 / 255.0));
+ }
}
else
{
@@ -148,24 +251,72 @@ namespace drawinglayer
{
namespace texture
{
- GeoTexSvxBitmapTiled::GeoTexSvxBitmapTiled(const Bitmap& rBitmap, const basegfx::B2DPoint& rTopLeft, const basegfx::B2DVector& rSize)
- : GeoTexSvxBitmap(rBitmap, rTopLeft, rSize)
+ basegfx::B2DPoint GeoTexSvxBitmapExTiled::impGetCorrected(const basegfx::B2DPoint& rUV) const
+ {
+ double fX(rUV.getX() - maTopLeft.getX());
+ double fY(rUV.getY() - maTopLeft.getY());
+
+ if(mbUseOffsetX)
+ {
+ const sal_Int32 nCol(static_cast< sal_Int32 >((fY < 0.0 ? maSize.getY() -fY : fY) / maSize.getY()));
+
+ if(nCol % 2)
+ {
+ fX += mfOffsetX * maSize.getX();
+ }
+ }
+ else if(mbUseOffsetY)
+ {
+ const sal_Int32 nRow(static_cast< sal_Int32 >((fX < 0.0 ? maSize.getX() -fX : fX) / maSize.getX()));
+
+ if(nRow % 2)
+ {
+ fY += mfOffsetY * maSize.getY();
+ }
+ }
+
+ fX = fmod(fX, maSize.getX());
+ fY = fmod(fY, maSize.getY());
+
+ if(fX < 0.0)
+ {
+ fX += maSize.getX();
+ }
+
+ if(fY < 0.0)
+ {
+ fY += maSize.getY();
+ }
+
+ return basegfx::B2DPoint(fX + maTopLeft.getX(), fY + maTopLeft.getY());
+ }
+
+ GeoTexSvxBitmapExTiled::GeoTexSvxBitmapExTiled(
+ const BitmapEx& rBitmapEx,
+ const basegfx::B2DRange& rRange,
+ double fOffsetX,
+ double fOffsetY)
+ : GeoTexSvxBitmapEx(rBitmapEx, rRange),
+ mfOffsetX(basegfx::clamp(fOffsetX, 0.0, 1.0)),
+ mfOffsetY(basegfx::clamp(fOffsetY, 0.0, 1.0)),
+ mbUseOffsetX(!basegfx::fTools::equalZero(mfOffsetX)),
+ mbUseOffsetY(!mbUseOffsetX && !basegfx::fTools::equalZero(mfOffsetY))
{
}
- void GeoTexSvxBitmapTiled::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& rfOpacity) const
+ void GeoTexSvxBitmapExTiled::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& rfOpacity) const
{
- if(mpRead)
+ if(mpReadBitmap)
{
- GeoTexSvxBitmap::modifyBColor(impGetCorrected(rUV), rBColor, rfOpacity);
+ GeoTexSvxBitmapEx::modifyBColor(impGetCorrected(rUV), rBColor, rfOpacity);
}
}
- void GeoTexSvxBitmapTiled::modifyOpacity(const basegfx::B2DPoint& rUV, double& rfOpacity) const
+ void GeoTexSvxBitmapExTiled::modifyOpacity(const basegfx::B2DPoint& rUV, double& rfOpacity) const
{
- if(mpRead)
+ if(mpReadBitmap)
{
- GeoTexSvxBitmap::modifyOpacity(impGetCorrected(rUV), rfOpacity);
+ GeoTexSvxBitmapEx::modifyOpacity(impGetCorrected(rUV), rfOpacity);
}
}
} // end of namespace texture
@@ -177,7 +328,9 @@ namespace drawinglayer
{
namespace texture
{
- GeoTexSvxMultiHatch::GeoTexSvxMultiHatch(const primitive3d::HatchTexturePrimitive3D& rPrimitive, double fLogicPixelSize)
+ GeoTexSvxMultiHatch::GeoTexSvxMultiHatch(
+ const primitive3d::HatchTexturePrimitive3D& rPrimitive,
+ double fLogicPixelSize)
: mfLogicPixelSize(fLogicPixelSize),
mp0(0L),
mp1(0L),