diff options
247 files changed, 9271 insertions, 11554 deletions
diff --git a/basebmp/test/basictest.cxx b/basebmp/test/basictest.cxx index 4129cebdbd3d..6f96cf56f492 100644 --- a/basebmp/test/basictest.cxx +++ b/basebmp/test/basictest.cxx @@ -27,7 +27,10 @@ // autogenerated file with codegen.pl -#include <testshl/simpleheader.hxx> +#include "cppunit/TestAssert.h" +#include "cppunit/TestFixture.h" +#include "cppunit/extensions/HelperMacros.h" +#include "cppunit/plugin/TestPlugIn.h" #include <basegfx/vector/b2isize.hxx> #include <basegfx/point/b2ipoint.hxx> @@ -291,13 +294,7 @@ public: }; // ----------------------------------------------------------------------------- -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(BasicTest, "BasicTest"); +CPPUNIT_TEST_SUITE_REGISTRATION(BasicTest); } - -// ----------------------------------------------------------------------------- - -// this macro creates an empty function, which will called by the RegisterAllFunctions() -// to let the user the possibility to also register some functions by hand. -NOADDITIONAL; - +CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/basebmp/test/bmpmasktest.cxx b/basebmp/test/bmpmasktest.cxx index e65c5e569d3c..9be504819fe8 100644 --- a/basebmp/test/bmpmasktest.cxx +++ b/basebmp/test/bmpmasktest.cxx @@ -27,7 +27,9 @@ // autogenerated file with codegen.pl -#include <testshl/simpleheader.hxx> +#include "cppunit/TestAssert.h" +#include "cppunit/TestFixture.h" +#include "cppunit/extensions/HelperMacros.h" #include <basegfx/vector/b2isize.hxx> #include <basegfx/range/b2irange.hxx> @@ -177,7 +179,7 @@ public: }; // ----------------------------------------------------------------------------- -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(BmpMaskTest, "BmpMaskTest"); +CPPUNIT_TEST_SUITE_REGISTRATION(BmpMaskTest); } diff --git a/basebmp/test/bmptest.cxx b/basebmp/test/bmptest.cxx index ce2e2440dcd1..9e33f0a8d713 100644 --- a/basebmp/test/bmptest.cxx +++ b/basebmp/test/bmptest.cxx @@ -27,7 +27,9 @@ // autogenerated file with codegen.pl -#include <testshl/simpleheader.hxx> +#include "cppunit/TestAssert.h" +#include "cppunit/TestFixture.h" +#include "cppunit/extensions/HelperMacros.h" #include <basegfx/vector/b2isize.hxx> #include <basegfx/range/b2irange.hxx> @@ -204,7 +206,7 @@ public: }; // ----------------------------------------------------------------------------- -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(BmpTest, "BmpTest"); +CPPUNIT_TEST_SUITE_REGISTRATION(BmpTest); } diff --git a/basebmp/test/cliptest.cxx b/basebmp/test/cliptest.cxx index 1c4a20bc0d86..875016d878cc 100644 --- a/basebmp/test/cliptest.cxx +++ b/basebmp/test/cliptest.cxx @@ -27,7 +27,9 @@ // autogenerated file with codegen.pl -#include <testshl/simpleheader.hxx> +#include "cppunit/TestAssert.h" +#include "cppunit/TestFixture.h" +#include "cppunit/extensions/HelperMacros.h" #include <basegfx/vector/b2isize.hxx> #include <basegfx/point/b2ipoint.hxx> @@ -271,7 +273,7 @@ public: }; // ----------------------------------------------------------------------------- -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(ClipTest, "ClipTest"); +CPPUNIT_TEST_SUITE_REGISTRATION(ClipTest); } diff --git a/basebmp/test/export.map b/basebmp/test/export.map index 709047ae63e5..3308588ef6f8 100644 --- a/basebmp/test/export.map +++ b/basebmp/test/export.map @@ -25,9 +25,9 @@ # #************************************************************************* -UDK_3.1 { +UDK_3_0_0 { global: - registerAllTestFunction; + cppunitTestPlugIn; local: *; diff --git a/basebmp/test/filltest.cxx b/basebmp/test/filltest.cxx index ea801de8111f..150fa11b3a72 100644 --- a/basebmp/test/filltest.cxx +++ b/basebmp/test/filltest.cxx @@ -27,7 +27,9 @@ // autogenerated file with codegen.pl -#include <testshl/simpleheader.hxx> +#include "cppunit/TestAssert.h" +#include "cppunit/TestFixture.h" +#include "cppunit/extensions/HelperMacros.h" #include <basegfx/vector/b2isize.hxx> #include <basegfx/range/b2drange.hxx> @@ -265,7 +267,7 @@ public: }; // ----------------------------------------------------------------------------- -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(FillTest, "FillTest"); +CPPUNIT_TEST_SUITE_REGISTRATION(FillTest); } diff --git a/basebmp/test/linetest.cxx b/basebmp/test/linetest.cxx index 3c30ed718b70..fcd383fccdb0 100644 --- a/basebmp/test/linetest.cxx +++ b/basebmp/test/linetest.cxx @@ -27,7 +27,9 @@ // autogenerated file with codegen.pl -#include <testshl/simpleheader.hxx> +#include "cppunit/TestAssert.h" +#include "cppunit/TestFixture.h" +#include "cppunit/extensions/HelperMacros.h" #include <basegfx/vector/b2isize.hxx> #include <basegfx/point/b2ipoint.hxx> @@ -213,7 +215,7 @@ public: }; // ----------------------------------------------------------------------------- -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(LineTest, "LineTest"); +CPPUNIT_TEST_SUITE_REGISTRATION(LineTest); } diff --git a/basebmp/test/makefile.mk b/basebmp/test/makefile.mk index a11dacc1125d..ca77721716f7 100644 --- a/basebmp/test/makefile.mk +++ b/basebmp/test/makefile.mk @@ -60,6 +60,8 @@ CDEFS+=-xalias_level=compatible .ENDIF .ENDIF +CFLAGSCXX += $(CPPUNIT_CFLAGS) + # --- Common ---------------------------------------------------------- .IF "$(L10N_framework)"=="" @@ -74,17 +76,10 @@ SHL1OBJS= \ $(SLO)$/linetest.obj \ $(SLO)$/masktest.obj \ $(SLO)$/polytest.obj \ - $(SLO)$/tools.obj \ - $(SLO)$/bitmapdevice.obj \ - $(SLO)$/debug.obj \ - $(SLO)$/polypolygonrenderer.obj -# last three objs are a bit of a hack: cannot link against LIBBASEBMP -# here, because not yet delivered. Need the functionality to test, so -# we're linking it in statically. Need to keep this in sync with -# source/makefile.mk + $(SLO)$/tools.obj SHL1TARGET= tests -SHL1STDLIBS= $(SALLIB) \ - $(TESTSHL2LIB)\ +SHL1STDLIBS= $(BASEBMPLIB) \ + $(SALLIB) \ $(CPPUNITLIB) \ $(BASEGFXLIB) @@ -92,6 +87,8 @@ SHL1IMPLIB= i$(SHL1TARGET) DEF1NAME =$(SHL1TARGET) SHL1VERSIONMAP = export.map +SHL1RPATH = NONE + .ENDIF # END ------------------------------------------------------------------ @@ -121,16 +118,8 @@ SLOFILES=$(SHL1OBJS) # --- Targets ------------------------------------------------------ .INCLUDE : target.mk -.INCLUDE : _cppunit.mk # --- Enable test execution in normal build ------------------------ .IF "$(L10N_framework)"=="" - -unittest : $(SHL1TARGETN) - @echo ---------------------------------------------------------- - @echo - start unit test on library $(SHL1TARGETN) - @echo ---------------------------------------------------------- - $(TESTSHL2) -sf $(mktmp ) $(SHL1TARGETN) - -ALLTAR : unittest +.INCLUDE : _cppunit.mk .ENDIF diff --git a/basebmp/test/masktest.cxx b/basebmp/test/masktest.cxx index e3843eba389a..77cd05588d5a 100644 --- a/basebmp/test/masktest.cxx +++ b/basebmp/test/masktest.cxx @@ -27,7 +27,9 @@ // autogenerated file with codegen.pl -#include <testshl/simpleheader.hxx> +#include "cppunit/TestAssert.h" +#include "cppunit/TestFixture.h" +#include "cppunit/extensions/HelperMacros.h" #include <basegfx/vector/b2isize.hxx> #include <basegfx/range/b2irange.hxx> @@ -165,7 +167,7 @@ public: }; // ----------------------------------------------------------------------------- -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(MaskTest, "MaskTest"); +CPPUNIT_TEST_SUITE_REGISTRATION(MaskTest); } diff --git a/basebmp/test/polytest.cxx b/basebmp/test/polytest.cxx index c8290668d1f8..f3b1f0018e17 100644 --- a/basebmp/test/polytest.cxx +++ b/basebmp/test/polytest.cxx @@ -27,7 +27,9 @@ // autogenerated file with codegen.pl -#include <testshl/simpleheader.hxx> +#include "cppunit/TestAssert.h" +#include "cppunit/TestFixture.h" +#include "cppunit/extensions/HelperMacros.h" #include <basegfx/vector/b2isize.hxx> #include <basegfx/range/b2irange.hxx> @@ -285,7 +287,7 @@ public: }; // ----------------------------------------------------------------------------- -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(PolyTest, "PolyTest"); +CPPUNIT_TEST_SUITE_REGISTRATION(PolyTest); } diff --git a/basegfx/inc/basegfx/matrix/b2dhommatrixtools.hxx b/basegfx/inc/basegfx/matrix/b2dhommatrixtools.hxx index 3941ee19cb42..7ce9e75c3058 100644 --- a/basegfx/inc/basegfx/matrix/b2dhommatrixtools.hxx +++ b/basegfx/inc/basegfx/matrix/b2dhommatrixtools.hxx @@ -32,6 +32,8 @@ #include <basegfx/matrix/b2dhommatrix.hxx> #include <basegfx/vector/b2dvector.hxx> +namespace rtl { class OUString; } + /////////////////////////////////////////////////////////////////////////////// namespace basegfx @@ -132,6 +134,7 @@ namespace basegfx rPoint.getX(), rPoint.getY(), fRadiant); } + } // end of namespace tools } // end of namespace basegfx @@ -220,6 +223,10 @@ namespace basegfx double getShearX() const { const_cast< B2DHomMatrixBufferedOnDemandDecompose* >(this)->impCheckDecompose(); return mfShearX; } }; } // end of namespace tools + + /// Returns a string with svg's "matrix(m00,m10,m01,m11,m02,m12)" representation + ::rtl::OUString exportToSvg( const B2DHomMatrix& rMatrix ); + } // end of namespace basegfx /////////////////////////////////////////////////////////////////////////////// diff --git a/basegfx/inc/basegfx/numeric/ftools.hxx b/basegfx/inc/basegfx/numeric/ftools.hxx index 0a4cdfcffdaa..65a6566dae25 100644 --- a/basegfx/inc/basegfx/numeric/ftools.hxx +++ b/basegfx/inc/basegfx/numeric/ftools.hxx @@ -109,7 +109,7 @@ namespace basegfx /** clamp given value against given minimum and maximum values */ - template <class T> const T& clamp(const T& value, const T& minimum, const T& maximum) + template <class T> inline const T& clamp(const T& value, const T& minimum, const T& maximum) { if(value < minimum) { diff --git a/basegfx/inc/basegfx/polygon/b2dpolygon.hxx b/basegfx/inc/basegfx/polygon/b2dpolygon.hxx index 30f7786a6981..a12120b5f441 100644 --- a/basegfx/inc/basegfx/polygon/b2dpolygon.hxx +++ b/basegfx/inc/basegfx/polygon/b2dpolygon.hxx @@ -260,6 +260,12 @@ namespace basegfx /// apply transformation given in matrix form void transform(const basegfx::B2DHomMatrix& rMatrix); + + // point iterators (same iterator validity conditions as for vector) + const B2DPoint* begin() const; + const B2DPoint* end() const; + B2DPoint* begin(); + B2DPoint* end(); }; } // end of namespace basegfx diff --git a/basegfx/inc/basegfx/polygon/b2dpolypolygon.hxx b/basegfx/inc/basegfx/polygon/b2dpolypolygon.hxx index 1ccaaa8330ec..0032cc47ce4e 100644 --- a/basegfx/inc/basegfx/polygon/b2dpolypolygon.hxx +++ b/basegfx/inc/basegfx/polygon/b2dpolypolygon.hxx @@ -125,6 +125,12 @@ namespace basegfx // apply transformation given in matrix form to the polygon void transform(const basegfx::B2DHomMatrix& rMatrix); + + // polygon iterators (same iterator validity conditions as for vector) + const B2DPolygon* begin() const; + const B2DPolygon* end() const; + B2DPolygon* begin(); + B2DPolygon* end(); }; } // end of namespace basegfx diff --git a/basegfx/inc/basegfx/polygon/b3dgeometry.hxx b/basegfx/inc/basegfx/polygon/b3dgeometry.hxx deleted file mode 100644 index ec66f3e3a570..000000000000 --- a/basegfx/inc/basegfx/polygon/b3dgeometry.hxx +++ /dev/null @@ -1,70 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#ifndef _BGFX_POLYGON_B3DGEOMETRY_HXX -#define _BGFX_POLYGON_B3DGEOMETRY_HXX - -////////////////////////////////////////////////////////////////////////////// -// predeclarations - -namespace basegfx -{ -} // end of namespace basegfx - -////////////////////////////////////////////////////////////////////////////// - -namespace basegfx -{ - class B3DGeometry - { - private: - B2DPolyPolygon maPolyPolygon; // the PolyPolygon geometry data, defines point number - B3DHomMatrix maPolygonTo3D; // transformation to create 3D PolyPolygon - B3DPolyPolygon maPolyNormal; // normal for each point or empty -> unified normal - B2DPolyPolygon maPolyTexture; // texture coordinate for each point or empty -> unified coordinate - B3DVector maUnifiedVector; // used when maNormal is empty - - // bitfield - unsigned mbUnifiedVectorValid : 1; // flag to know if uvec is calculated yet - - public: - B3DGeometry(); - ~B3DGeometry(); - - // compare operators - bool operator==(const B3DGeometry& rGeometry) const; - bool operator!=(const B3DGeometry& rGeometry) const { return (!operator==(rGeometry)); } - - // member count - sal_uInt32 count() const { return maPolyPolygon.count(); } - }; -} // end of namespace basegfx - -////////////////////////////////////////////////////////////////////////////// - - -#endif /* _BGFX_POLYGON_B3DPOLYGON_HXX */ diff --git a/basegfx/inc/basegfx/range/b2dmultirange.hxx b/basegfx/inc/basegfx/range/b2dmultirange.hxx deleted file mode 100644 index 4c1eb37be036..000000000000 --- a/basegfx/inc/basegfx/range/b2dmultirange.hxx +++ /dev/null @@ -1,114 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#ifndef _BGFX_RANGE_B2DMULTIRANGE_HXX -#define _BGFX_RANGE_B2DMULTIRANGE_HXX - -#include <o3tl/cow_wrapper.hxx> -#include <memory> - - -namespace basegfx -{ - class B2DTuple; - class B2DRange; - class B2DPolyPolygon; - class ImplB2DMultiRange; - - /** Multiple ranges in one object. - - This class combines multiple ranges in one object, providing a - total, enclosing range for it. - - You can use this class e.g. when updating views containing - rectangular objects. Add each modified object to a - B2DMultiRange, then test each viewable object against - intersection with the multi range. - */ - class B2DMultiRange - { - public: - B2DMultiRange(); - ~B2DMultiRange(); - - /** Create a multi range with exactly one containing range - */ - explicit B2DMultiRange( const B2DRange& rRange ); - - B2DMultiRange( const B2DMultiRange& ); - B2DMultiRange& operator=( const B2DMultiRange& ); - - /** Check whether range is empty. - - @return true, if this object either contains no ranges at - all, or all contained ranges are empty. - */ - bool isEmpty() const; - - /** Reset to empty. - - After this call, the object will not contain any ranges, - and isEmpty() will return true. - */ - void reset(); - - /** Test whether given tuple is inside one or more of the - included ranges. - */ - bool isInside( const B2DTuple& rTuple ) const; - - /** Test whether given range is inside one or more of the - included ranges. - */ - bool isInside( const B2DRange& rRange ) const; - - /** Test whether given range overlaps one or more of the - included ranges. - */ - bool overlaps( const B2DRange& rRange ) const; - - /** Add given range to the number of contained ranges. - */ - void addRange( const B2DRange& rRange ); - - /** Get overall bound rect for all included ranges. - */ - B2DRange getBounds() const; - - /** Request poly-polygon representing the added ranges. - - This method creates a poly-polygon, consisting exactly out - of the contained ranges. - */ - B2DPolyPolygon getPolyPolygon() const; - - private: - o3tl::cow_wrapper< ImplB2DMultiRange > mpImpl; - }; -} - -#endif /* _BGFX_RANGE_B2DMULTIRANGE_HXX */ diff --git a/basegfx/inc/basegfx/range/b2dpolyrange.hxx b/basegfx/inc/basegfx/range/b2dpolyrange.hxx new file mode 100644 index 000000000000..2202869dc921 --- /dev/null +++ b/basegfx/inc/basegfx/range/b2dpolyrange.hxx @@ -0,0 +1,145 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: b2dmultirange.hxx,v $ + * $Revision: 1.6 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _BGFX_RANGE_B2DPOLYRANGE_HXX +#define _BGFX_RANGE_B2DPOLYRANGE_HXX + +#include <o3tl/cow_wrapper.hxx> +#include <boost/tuple/tuple.hpp> +#include <basegfx/vector/b2enums.hxx> + +namespace basegfx +{ + class B2DTuple; + class B2DRange; + class B2DPolyPolygon; + class ImplB2DPolyRange; + + /** Multiple ranges in one object. + + This class combines multiple ranges in one object, providing a + total, enclosing range for it. + + You can use this class e.g. when updating views containing + rectangular objects. Add each modified object to a + B2DMultiRange, then test each viewable object against + intersection with the multi range. + + Similar in spirit to the poly-polygon vs. polygon relationship. + + Note that comparable to polygons, a poly-range can also + contain 'holes' - this is encoded via polygon orientation at + the poly-polygon, and via explicit flags for the poly-range. + */ + class B2DPolyRange + { + public: + typedef boost::tuple<B2DRange,B2VectorOrientation> ElementType ; + + B2DPolyRange(); + ~B2DPolyRange(); + + /** Create a multi range with exactly one containing range + */ + explicit B2DPolyRange( const ElementType& rElement ); + B2DPolyRange( const B2DRange& rRange, B2VectorOrientation eOrient ); + B2DPolyRange( const B2DPolyRange& ); + B2DPolyRange& operator=( const B2DPolyRange& ); + + /// unshare this poly-range with all internally shared instances + void makeUnique(); + + bool operator==(const B2DPolyRange&) const; + bool operator!=(const B2DPolyRange&) const; + + /// Number of included ranges + sal_uInt32 count() const; + + ElementType getElement(sal_uInt32 nIndex) const; + void setElement(sal_uInt32 nIndex, const ElementType& rElement ); + void setElement(sal_uInt32 nIndex, const B2DRange& rRange, B2VectorOrientation eOrient ); + + // insert/append a single range + void insertElement(sal_uInt32 nIndex, const ElementType& rElement, sal_uInt32 nCount = 1); + void insertElement(sal_uInt32 nIndex, const B2DRange& rRange, B2VectorOrientation eOrient, sal_uInt32 nCount = 1); + void appendElement(const ElementType& rElement, sal_uInt32 nCount = 1); + void appendElement(const B2DRange& rRange, B2VectorOrientation eOrient, sal_uInt32 nCount = 1); + + // insert/append multiple ranges + void insertPolyRange(sal_uInt32 nIndex, const B2DPolyRange&); + void appendPolyRange(const B2DPolyRange&); + + void remove(sal_uInt32 nIndex, sal_uInt32 nCount = 1); + void clear(); + + // flip range orientations - converts holes to solids, and vice versa + void flip(); + + /** Get overall range + + @return + The union range of all contained ranges + */ + B2DRange getBounds() const; + + /** Test whether given tuple is inside one or more of the + included ranges. Does *not* use overall range, but checks + individually. + */ + bool isInside( const B2DTuple& rTuple ) const; + + /** Test whether given range is inside one or more of the + included ranges. Does *not* use overall range, but checks + individually. + */ + bool isInside( const B2DRange& rRange ) const; + + /** Test whether given range overlaps one or more of the + included ranges. Does *not* use overall range, but checks + individually. + */ + bool overlaps( const B2DRange& rRange ) const; + + /** Request a poly-polygon with solved cross-overs + */ + B2DPolyPolygon solveCrossovers() const; + + // element iterators (same iterator validity conditions as for vector) + const B2DRange* begin() const; + const B2DRange* end() const; + B2DRange* begin(); + B2DRange* end(); + + private: + o3tl::cow_wrapper< ImplB2DPolyRange > mpImpl; + }; +} + +#endif /* _BGFX_RANGE_B2DPOLYRANGE_HXX */ diff --git a/basegfx/source/polygon/b3dgeometry.cxx b/basegfx/inc/basegfx/range/b2drangeclipper.hxx index 6c1537bac0a6..3285ffeaffe1 100644 --- a/basegfx/source/polygon/b3dgeometry.cxx +++ b/basegfx/inc/basegfx/range/b2drangeclipper.hxx @@ -2,10 +2,13 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2000, 2010 Oracle and/or its affiliates. + * Copyright 2008 by Sun Microsystems, Inc. * * OpenOffice.org - a multi-platform office productivity suite * + * $RCSfile: b2dmultirange.hxx,v $ + * $Revision: 1.6 $ + * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify @@ -25,31 +28,26 @@ * ************************************************************************/ -#include <osl/diagnose.h> -#include <basegfx/polygon/b3dgeometry.hxx> +#ifndef _BGFX_RANGE_B2DRANGECLIPPER_HXX +#define _BGFX_RANGE_B2DRANGECLIPPER_HXX -////////////////////////////////////////////////////////////////////////////// +#include <basegfx/range/b2dpolyrange.hxx> +#include <vector> namespace basegfx { - B3DGeometry::B3DGeometry() - : mbUnifiedVectorValid(false) + namespace tools { - } + /** Extract poly-polygon w/o self-intersections from poly-range - B3DGeometry::~B3DGeometry() - { + Similar to the solveCrossovers(const B2DPolyPolygon&) + method, this one calculates a self-intersection-free + poly-polygon with the same topology, and encoding + inside/outsidedness via polygon orientation and layering. + */ + B2DPolyPolygon solveCrossovers(const std::vector<B2DRange>& rRanges, + const std::vector<B2VectorOrientation>& rOrientations); } +} - bool B3DGeometry::operator==(const B3DGeometry& rGeometry) const - { - return (maPolyPolygon == maPolyPolygon - && maPolygonTo3D == maPolygonTo3D - && maPolyNormal == maPolyNormal - && maPolyTexture == maPolyTexture - } - -} // end of namespace basegfx - -////////////////////////////////////////////////////////////////////////////// -// eof +#endif /* _BGFX_RANGE_B2DRANGECLIPPER_HXX */ diff --git a/basegfx/inc/basegfx/tools/b2dclipstate.hxx b/basegfx/inc/basegfx/tools/b2dclipstate.hxx new file mode 100644 index 000000000000..7d336d8cb48e --- /dev/null +++ b/basegfx/inc/basegfx/tools/b2dclipstate.hxx @@ -0,0 +1,119 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: rectcliptools.hxx,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _BGFX_TOOLS_CLIPSTATE_HXX +#define _BGFX_TOOLS_CLIPSTATE_HXX + +#include <sal/types.h> +#include <o3tl/cow_wrapper.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace basegfx +{ + class B2DRange; + class B2DPolyRange; + class B2DPolygon; + class B2DPolyPolygon; + + namespace tools + { + class ImplB2DClipState; + + /** This class provides an optimized, symbolic clip state for graphical output + + Having a current 'clip' state is a common attribute of + almost all graphic output APIs, most of which internally + represent it via a list of rectangular bands. In contrast, + this implementation purely uses symbolic clips, but in a + quite efficient manner, deferring actual evaluation until + a clip representation is requested, and using faster code + paths for common special cases (like all-rectangle clips) + */ + class B2DClipState + { + public: + typedef o3tl::cow_wrapper< ImplB2DClipState > ImplType; + + private: + ImplType mpImpl; + + public: + /// Init clip, in 'cleared' state - everything is visible + B2DClipState(); + ~B2DClipState(); + B2DClipState( const B2DClipState& ); + explicit B2DClipState( const B2DRange& ); + explicit B2DClipState( const B2DPolygon& ); + explicit B2DClipState( const B2DPolyPolygon& ); + B2DClipState& operator=( const B2DClipState& ); + + /// unshare this poly-range with all internally shared instances + void makeUnique(); + + /// Set clip to 'null' - nothing is visible + void makeNull(); + /// returns true when clip is 'null' - nothing is visible + bool isNull() const; + + /// Set clip 'cleared' - everything is visible + void makeClear(); + /// returns true when clip is 'cleared' - everything is visible + bool isCleared() const; + + bool operator==(const B2DClipState&) const; + bool operator!=(const B2DClipState&) const; + + void unionRange(const B2DRange& ); + void unionPolygon(const B2DPolygon& ); + void unionPolyPolygon(const B2DPolyPolygon& ); + void unionClipState(const B2DClipState& ); + + void intersectRange(const B2DRange& ); + void intersectPolygon(const B2DPolygon& ); + void intersectPolyPolygon(const B2DPolyPolygon& ); + void intersectClipState(const B2DClipState& ); + + void subtractRange(const B2DRange& ); + void subtractPolygon(const B2DPolygon& ); + void subtractPolyPolygon(const B2DPolyPolygon& ); + void subtractClipState(const B2DClipState& ); + + void xorRange(const B2DRange& ); + void xorPolygon(const B2DPolygon& ); + void xorPolyPolygon(const B2DPolyPolygon& ); + void xorClipState(const B2DClipState& ); + + B2DPolyPolygon getClipPoly() const; + }; + } +} + +#endif // _BGFX_TOOLS_CLIPSTATE_HXX diff --git a/basegfx/inc/basegfx/tools/gradienttools.hxx b/basegfx/inc/basegfx/tools/gradienttools.hxx index 0dab1a5117ff..2f436fa1d717 100644 --- a/basegfx/inc/basegfx/tools/gradienttools.hxx +++ b/basegfx/inc/basegfx/tools/gradienttools.hxx @@ -34,6 +34,9 @@ #include <basegfx/matrix/b2dhommatrix.hxx> #include <basegfx/numeric/ftools.hxx> +#include <vector> +#include <algorithm> + namespace basegfx { /** Gradient definition as used in ODF 1.2 @@ -75,6 +78,8 @@ namespace basegfx { /** Create matrix for ODF's linear gradient definition + Note that odf linear gradients are varying in y direction. + @param o_rGradientInfo Receives the calculated texture transformation matrix (for use with standard [0,1]x[0,1] texture coordinates) @@ -106,7 +111,7 @@ namespace basegfx @param rUV Current uv coordinate. Values outside [0,1] will be - clamped. + clamped. Assumes gradient color varies along the y axis. @param rGradInfo Gradient info, for transformation and number of steps @@ -126,6 +131,14 @@ namespace basegfx /** Create matrix for ODF's axial gradient definition + Note that odf axial gradients are varying in y + direction. Note further that you can map the axial + gradient to a linear gradient (in case you want or need to + avoid an extra gradient renderer), by using + createLinearODFGradientInfo() instead, shifting the + resulting texture transformation by 0.5 to the top and + appending the same stop colors again, but mirrored. + @param o_rGradientInfo Receives the calculated texture transformation matrix (for use with standard [0,1]x[0,1] texture coordinates) @@ -157,7 +170,7 @@ namespace basegfx @param rUV Current uv coordinate. Values outside [0,1] will be - clamped. + clamped. Assumes gradient color varies along the y axis. @param rGradInfo Gradient info, for transformation and number of steps @@ -391,7 +404,6 @@ namespace basegfx { return getSquareGradientAlpha(rUV, rGradInfo); // only matrix setup differs } - } } diff --git a/basegfx/inc/basegfx/tools/keystoplerp.hxx b/basegfx/inc/basegfx/tools/keystoplerp.hxx new file mode 100644 index 000000000000..a54b3485b1a1 --- /dev/null +++ b/basegfx/inc/basegfx/tools/keystoplerp.hxx @@ -0,0 +1,100 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: canvastools.hxx,v $ + * $Revision: 1.10 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _BGFX_TOOLS_KEYSTOPLERP_HXX +#define _BGFX_TOOLS_KEYSTOPLERP_HXX + +#include <basegfx/numeric/ftools.hxx> +#include <vector> + +namespace com{ namespace sun{ namespace star{ namespace uno { + template<typename T> class Sequence; +}}}} + +namespace basegfx +{ + namespace tools + { + /** Lerp in a vector of key stops + + This class holds a key stop vector and provides the + functionality to lerp inside it. Useful e.g. for + multi-stop gradients, or the SMIL key time activity. + + For those, given a global [0,1] lerp alpha, one need to + find the suitable bucket index from key stop vector, and + then calculate the relative alpha between the two buckets + found. + */ + class KeyStopLerp + { + public: + typedef std::pair<std::ptrdiff_t,double> ResultType; + + /** Create lerper with given vector of stops + + @param rKeyStops + + Vector of stops, must contain at least two elements + (though preferrably more, otherwise you probably don't + need key stop lerping in the first place). All + elements must be of monotonically increasing value. + */ + explicit KeyStopLerp( const std::vector<double>& rKeyStops ); + + /** Create lerper with given sequence of stops + + @param rKeyStops + + Sequence of stops, must contain at least two elements + (though preferrably more, otherwise you probably don't + need key stop lerping in the first place). All + elements must be of monotonically increasing value. + */ + explicit KeyStopLerp( const ::com::sun::star::uno::Sequence<double>& rKeyStops ); + + /** Find two nearest bucket index & interpolate + + @param fAlpha + Find bucket index i, with keyStops[i] < fAlpha <= + keyStops[i+1]. Return new alpha value in [0,1), + proportional to fAlpha's position between keyStops[i] + and keyStops[i+1] + */ + ResultType lerp(double fAlpha) const; + + private: + std::vector<double> maKeyStops; + mutable std::ptrdiff_t mnLastIndex; + }; + } +} + +#endif diff --git a/basegfx/inc/basegfx/tools/lerp.hxx b/basegfx/inc/basegfx/tools/lerp.hxx new file mode 100644 index 000000000000..590ef34c2009 --- /dev/null +++ b/basegfx/inc/basegfx/tools/lerp.hxx @@ -0,0 +1,60 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: lerp.hxx,v $ + * $Revision: 1.6 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _BGFX_TOOLS_LERP_HXX +#define _BGFX_TOOLS_LERP_HXX + +#include <sal/types.h> + +namespace basegfx +{ + namespace tools + { + /** Generic linear interpolator + + @tpl ValueType + Must have operator+ and operator* defined, and should + have value semantics. + + @param t + As usual, t must be in the [0,1] range + */ + template< typename ValueType > ValueType lerp( const ValueType& rFrom, + const ValueType& rTo, + double t ) + { + // This is only to suppress a double->int warning. All other + // types should be okay here. + return static_cast<ValueType>( (1.0-t)*rFrom + t*rTo ); + } + } +} + +#endif /* _BGFX_TOOLS_LERP_HXX */ diff --git a/basegfx/prj/build.lst b/basegfx/prj/build.lst index 418b3822a7ee..fe3354b3f256 100644 --- a/basegfx/prj/build.lst +++ b/basegfx/prj/build.lst @@ -1,4 +1,4 @@ -fx basegfx : o3tl sal offuh cppuhelper cppu testshl2 NULL +fx basegfx : o3tl sal offuh cppuhelper cppu CPPUNIT:cppunit NULL fx basegfx usr1 - all fx_mkout NULL fx basegfx\inc nmake - all fx_inc NULL fx basegfx\prj get - all fx_prj NULL diff --git a/basegfx/prj/d.lst b/basegfx/prj/d.lst index 68ab880eef62..3d4d985f3ae6 100644 --- a/basegfx/prj/d.lst +++ b/basegfx/prj/d.lst @@ -27,7 +27,7 @@ mkdir: %_DEST%\inc%_EXT%\basegfx\range ..\inc\basegfx\range\basicrange.hxx %_DEST%\inc%_EXT%\basegfx\range\basicrange.hxx ..\inc\basegfx\range\basicbox.hxx %_DEST%\inc%_EXT%\basegfx\range\basicbox.hxx ..\inc\basegfx\range\b1drange.hxx %_DEST%\inc%_EXT%\basegfx\range\b1drange.hxx -..\inc\basegfx\range\b2dmultirange.hxx %_DEST%\inc%_EXT%\basegfx\range\b2dmultirange.hxx +..\inc\basegfx\range\b2dpolyrange.hxx %_DEST%\inc%_EXT%\basegfx\range\b2dpolyrange.hxx ..\inc\basegfx\range\b2drange.hxx %_DEST%\inc%_EXT%\basegfx\range\b2drange.hxx ..\inc\basegfx\range\b2drectangle.hxx %_DEST%\inc%_EXT%\basegfx\range\b2drectangle.hxx ..\inc\basegfx\range\b2dconnectedranges.hxx %_DEST%\inc%_EXT%\basegfx\range\b2dconnectedranges.hxx @@ -90,7 +90,10 @@ mkdir: %_DEST%\inc%_EXT%\basegfx\tuple mkdir: %_DEST%\inc%_EXT%\basegfx\tools ..\inc\basegfx\tools\canvastools.hxx %_DEST%\inc%_EXT%\basegfx\tools\canvastools.hxx +..\inc\basegfx\tools\keystoplerp.hxx %_DEST%\inc%_EXT%\basegfx\tools\keystoplerp.hxx +..\inc\basegfx\tools\lerp.hxx %_DEST%\inc%_EXT%\basegfx\tools\lerp.hxx ..\inc\basegfx\tools\unopolypolygon.hxx %_DEST%\inc%_EXT%\basegfx\tools\unopolypolygon.hxx +..\inc\basegfx\tools\b2dclipstate.hxx %_DEST%\inc%_EXT%\basegfx\tools\b2dclipstate.hxx ..\inc\basegfx\tools\rectcliptools.hxx %_DEST%\inc%_EXT%\basegfx\tools\rectcliptools.hxx ..\inc\basegfx\tools\tools.hxx %_DEST%\inc%_EXT%\basegfx\tools\tools.hxx ..\inc\basegfx\tools\gradienttools.hxx %_DEST%\inc%_EXT%\basegfx\tools\gradienttools.hxx diff --git a/basegfx/qa/mkpolygons.pl b/basegfx/qa/mkpolygons.pl new file mode 100644 index 000000000000..b465a4f845ab --- /dev/null +++ b/basegfx/qa/mkpolygons.pl @@ -0,0 +1,344 @@ +: +eval 'exec perl -wS $0 ${1+"$@"}' + if 0; + +# +# 2009 Copyright Novell, Inc. & Sun Microsystems, Inc. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# + +use IO::File; +use Cwd; +use File::Spec; +use File::Spec::Functions; +use File::Temp; +use File::Path; + +$TempDir = ""; + + +# all the XML package generation is a blatant rip from AF's +# write-calc-doc.pl + + +############################################################################### +# Open a file with the given name. +# First it is checked if the temporary directory, in which all files for +# the document are gathered, is already present and create it if it is not. +# Then create the path to the file inside the temporary directory. +# Finally open the file and return a file handle to it. +# +sub open_file +{ + my $filename = pop @_; + + # Create base directory of temporary directory tree if not alreay + # present. + if ($TempDir eq "") + { + $TempDir = File::Temp::tempdir (CLEANUP => 1); + } + + # Create the path to the file. + my $fullname = File::Spec->catfile ($TempDir, $filename); + my ($volume,$directories,$file) = File::Spec->splitpath ($fullname); + mkpath (File::Spec->catpath ($volume,$directories,"")); + + # Open the file and return a file handle to it. + return new IO::File ($fullname, "w"); +} + + +############################################################################### +# Zip the files in the directory tree into the given file. +# +sub zip_dirtree +{ + my $filename = pop @_; + + my $cwd = getcwd; + my $zip_name = $filename; + + # We are about to change the directory. + # Therefore create an absolute pathname for the zip archive. + + # First transfer the drive from $cwd to $zip_name. This is a + # workaround for a bug in file_name_is_absolute which thinks + # the the path \bla is an absolute path under DOS. + my ($volume,$directories,$file) = File::Spec->splitpath ($zip_name); + my ($volume_cwd,$directories_cwd,$file_cwd) = File::Spec->splitpath ($cwd); + $volume = $volume_cwd if ($volume eq ""); + $zip_name = File::Spec->catpath ($volume,$directories,$file); + + # Add the current working directory to a relative path. + if ( ! file_name_is_absolute ($zip_name)) + { + $zip_name = File::Spec->catfile ($cwd, $zip_name); + + # Try everything to clean up the name. + $zip_name = File::Spec->rel2abs ($filename); + $zip_name = File::Spec->canonpath ($zip_name); + + # Remove .. directories from the middle of the path. + while ($zip_name =~ /\/[^\/][^\.\/][^\/]*\/\.\.\//) + { + $zip_name = $` . "/" . $'; + } + } + + # Just in case the zip program gets confused by an existing file with the + # same name as the one to be written that file is removed first. + if ( -e $filename) + { + if (unlink ($filename) == 0) + { + print "Existing file $filename could not be deleted.\n"; + print "Please close the application that uses it, then try again.\n"; + return; + } + } + + # Finally create the zip file. First change into the temporary directory + # so that the resulting zip file contains only paths relative to it. + print "zipping [$ZipCmd $ZipFlags $zip_name *]\n"; + chdir ($TempDir); + system ("$ZipCmd $ZipFlags $zip_name *"); + chdir ($cwd); +} + + +sub writeHeader +{ + print $OUT qq~<?xml version="1.0" encoding="UTF-8"?> + +<office:document-content xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:presentation="urn:oasis:names:tc:opendocument:xmlns:presentation:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:smil="urn:oasis:names:tc:opendocument:xmlns:smil-compatible:1.0" xmlns:anim="urn:oasis:names:tc:opendocument:xmlns:animation:1.0" office:version="1.0"> + <office:scripts/> + <office:automatic-styles> + <style:style style:name="dp1" style:family="drawing-page"> + <style:drawing-page-properties presentation:background-visible="true" presentation:background-objects-visible="true" presentation:display-footer="true" presentation:display-page-number="false" presentation:display-date-time="true"/> + </style:style> + <style:style style:name="gr1" style:family="graphic" style:parent-style-name="standard"> + <style:graphic-properties draw:textarea-horizontal-align="center" draw:fill="none" draw:stroke="none" draw:textarea-vertical-align="middle"/> + </style:style> + <style:style style:name="gr2" style:family="graphic" style:parent-style-name="standard"> + <style:graphic-properties draw:textarea-horizontal-align="center" draw:textarea-vertical-align="middle"/> + </style:style> + <style:style style:name="pr1" style:family="presentation" style:parent-style-name="Default-title"> + <style:graphic-properties draw:fill-color="#ffffff" draw:auto-grow-height="true" fo:min-height="3.508cm"/> + </style:style> + <style:style style:name="pr2" style:family="presentation" style:parent-style-name="Default-notes"> + <style:graphic-properties draw:fill-color="#ffffff" draw:auto-grow-height="true" fo:min-height="13.367cm"/> + </style:style> + <style:style style:name="P1" style:family="paragraph"> + <style:paragraph-properties fo:margin-left="0cm" fo:margin-right="0cm" fo:text-indent="0cm"/> + </style:style> + <style:style style:name="P2" style:family="paragraph"> + <style:paragraph-properties fo:margin-left="0.6cm" fo:margin-right="0cm" fo:text-indent="-0.6cm"/> + </style:style> + <text:list-style style:name="L1"> + <text:list-level-style-bullet text:level="1" text:bullet-char="â—"> + <style:text-properties fo:font-family="StarSymbol" style:use-window-font-color="true" fo:font-size="45%"/> + </text:list-level-style-bullet> + <text:list-level-style-bullet text:level="2" text:bullet-char="â—"> + <style:list-level-properties text:space-before="0.6cm" text:min-label-width="0.6cm"/> + <style:text-properties fo:font-family="StarSymbol" style:use-window-font-color="true" fo:font-size="45%"/> + </text:list-level-style-bullet> + <text:list-level-style-bullet text:level="3" text:bullet-char="â—"> + <style:list-level-properties text:space-before="1.2cm" text:min-label-width="0.6cm"/> + <style:text-properties fo:font-family="StarSymbol" style:use-window-font-color="true" fo:font-size="45%"/> + </text:list-level-style-bullet> + <text:list-level-style-bullet text:level="4" text:bullet-char="â—"> + <style:list-level-properties text:space-before="1.8cm" text:min-label-width="0.6cm"/> + <style:text-properties fo:font-family="StarSymbol" style:use-window-font-color="true" fo:font-size="45%"/> + </text:list-level-style-bullet> + <text:list-level-style-bullet text:level="5" text:bullet-char="â—"> + <style:list-level-properties text:space-before="2.4cm" text:min-label-width="0.6cm"/> + <style:text-properties fo:font-family="StarSymbol" style:use-window-font-color="true" fo:font-size="45%"/> + </text:list-level-style-bullet> + <text:list-level-style-bullet text:level="6" text:bullet-char="â—"> + <style:list-level-properties text:space-before="3cm" text:min-label-width="0.6cm"/> + <style:text-properties fo:font-family="StarSymbol" style:use-window-font-color="true" fo:font-size="45%"/> + </text:list-level-style-bullet> + <text:list-level-style-bullet text:level="7" text:bullet-char="â—"> + <style:list-level-properties text:space-before="3.6cm" text:min-label-width="0.6cm"/> + <style:text-properties fo:font-family="StarSymbol" style:use-window-font-color="true" fo:font-size="45%"/> + </text:list-level-style-bullet> + <text:list-level-style-bullet text:level="8" text:bullet-char="â—"> + <style:list-level-properties text:space-before="4.2cm" text:min-label-width="0.6cm"/> + <style:text-properties fo:font-family="StarSymbol" style:use-window-font-color="true" fo:font-size="45%"/> + </text:list-level-style-bullet> + <text:list-level-style-bullet text:level="9" text:bullet-char="â—"> + <style:list-level-properties text:space-before="4.8cm" text:min-label-width="0.6cm"/> + <style:text-properties fo:font-family="StarSymbol" style:use-window-font-color="true" fo:font-size="45%"/> + </text:list-level-style-bullet> + </text:list-style> + </office:automatic-styles> + <office:body> + <office:presentation> +~; + +} + +sub writeSlideHeader +{ + my $titleText = pop @_; + my $slideNum = pop @_; + + print $OUT " <draw:page draw:name=\"page1\" draw:style-name=\"dp1\" draw:master-page-name=\"Default\">\n"; + print $OUT " <office:forms form:automatic-focus=\"false\" form:apply-design-mode=\"false\"/>\n"; + print $OUT " <draw:rect draw:style-name=\"gr1\" draw:text-style-name=\"P1\" draw:id=\"id$slideNum\" draw:layer=\"layout\" svg:width=\"17.5cm\" svg:height=\"6cm\" svg:x=\"5cm\" svg:y=\"4cm\">\n"; + print $OUT " <text:p text:style-name=\"P2\">Slide: $slideNum</text:p>\n"; + print $OUT " <text:p text:style-name=\"P2\">Path: $titleText</text:p>\n"; + print $OUT " </draw:rect>\n"; +} + + +sub writeSlideFooter +{ + print $OUT " <presentation:notes draw:style-name=\"dp1\">\n"; + print $OUT " <draw:page-thumbnail draw:style-name=\"gr1\" draw:layer=\"layout\" svg:width=\"14.851cm\" svg:height=\"11.138cm\" svg:x=\"3.068cm\" svg:y=\"2.257cm\" draw:page-number=\"1\" presentation:class=\"page\"/>\n"; + print $OUT " <draw:frame presentation:style-name=\"pr3\" draw:layer=\"layout\" svg:width=\"16.79cm\" svg:height=\"13.116cm\" svg:x=\"2.098cm\" svg:y=\"14.109cm\" presentation:class=\"notes\" presentation:placeholder=\"true\">\n"; + print $OUT " <draw:text-box/>\n"; + print $OUT " </draw:frame>\n"; + print $OUT " </presentation:notes>\n"; + print $OUT " </draw:page>\n"; +} + +sub writeFooter +{ + print $OUT qq~ <presentation:settings presentation:full-screen="false"/> + </office:presentation> + </office:body> +</office:document-content> +~; + +} + +sub writePath +{ + my $pathAry = pop @_; + my $path = $pathAry->[1]; + my $viewBox = $pathAry->[0]; + + print $OUT " <draw:path draw:style-name=\"gr2\" draw:text-style-name=\"P1\" draw:layer=\"layout\" svg:width=\"10cm\" svg:height=\"10cm\" svg:x=\"5cm\" svg:y=\"5cm\" svg:viewBox=\""; + print $OUT $viewBox; + print $OUT "\" svg:d=\""; + print $OUT $path; + print $OUT "\">\n"; + print $OUT " <text:p/>\n"; + print $OUT " </draw:path>\n"; +} + +sub writeManifest +{ + my $outFile = open_file("META-INF/manifest.xml"); + + print $outFile qq~<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE manifest:manifest PUBLIC "-//OpenOffice.org//DTD Manifest 1.0//EN" "Manifest.dtd"> +<manifest:manifest xmlns:manifest="urn:oasis:names:tc:opendocument:xmlns:manifest:1.0"> + <manifest:file-entry manifest:media-type="application/vnd.oasis.opendocument.presentation" manifest:full-path="/"/> + <manifest:file-entry manifest:media-type="text/xml" manifest:full-path="content.xml"/> +</manifest:manifest> +~; + + $outFile->close; +} + + +############################################################################### +# Print usage information. +# +sub usage () +{ + print <<END_OF_USAGE; +usage: $0 <option>* [<SvgD-values>] + +output-file-name defaults to polygons.odp. + + -h Print this usage information. + -o output-file-name +END_OF_USAGE +} + +############################################################################### +# Process the command line. +# +sub process_command_line +{ + foreach (@ARGV) + { + if (/^-h/) + { + usage; + exit 0; + } + } + + $global_output_name = "polygons.odp"; + my $j = 0, $noMoreOptions = 0; + for (my $i=0; $i<$#ARGV; $i++) + { + if ( !$noMoreOptions and $ARGV[$i] eq "-o") + { + $i++; + $global_output_name = $ARGV[$i]; + } + elsif ( !$noMoreOptions and $ARGV[$i] eq "--") + { + $noMoreOptions = 1; + } + elsif ( !$noMoreOptions and $ARGV[$i] =~ /^-/) + { + print "Unknown option $ARGV[$i]\n"; + usage; + exit 1; + } + else + { + push(@paths, [$ARGV[$i],$ARGV[$i+1]]); + $i++; + } + } + + print "output to $global_output_name\n"; +} + +############################################################################### +# Main +############################################################################### + +$ZipCmd = $ENV{LOG_FILE_ZIP_CMD}; +$ZipFlags = $ENV{LOG_FILE_ZIP_FLAGS}; +# Provide default values for the zip command and it's flags. +if ( ! defined $ZipCmd) +{ + $ZipCmd = "zip" unless defined $ZipCmd; + $ZipFlags = "-r -q" unless defined $ZipFlags; +} + +process_command_line(); + +writeManifest(); + +$OUT = open_file( "content.xml" ); + +writeHeader(); + +$pathNum=0; +foreach $path (@paths) +{ + writeSlideHeader($pathNum, $path->[1]); + writePath($path); + writeSlideFooter(); + $pathNum++; +} + +writeFooter(); + +$OUT->close; + +zip_dirtree ($global_output_name); + diff --git a/basegfx/source/color/bcolortools.cxx b/basegfx/source/color/bcolortools.cxx index f7f26c6dd843..543097de3d77 100644 --- a/basegfx/source/color/bcolortools.cxx +++ b/basegfx/source/color/bcolortools.cxx @@ -61,7 +61,7 @@ namespace basegfx { namespace tools else if( g == maxVal ) h = 2.0 + (b - r)/d; else - h = 4.0 + (r - h)/d; + h = 4.0 + (r - g)/d; h *= 60.0; diff --git a/basegfx/source/matrix/b2dhommatrixtools.cxx b/basegfx/source/matrix/b2dhommatrixtools.cxx index 0f294d6a262f..0b85ee229ecc 100644 --- a/basegfx/source/matrix/b2dhommatrixtools.cxx +++ b/basegfx/source/matrix/b2dhommatrixtools.cxx @@ -29,11 +29,39 @@ #include "precompiled_basegfx.hxx" #include <basegfx/matrix/b2dhommatrixtools.hxx> +#include <rtl/ustring.hxx> +#include <rtl/ustrbuf.hxx> /////////////////////////////////////////////////////////////////////////////// namespace basegfx { + ::rtl::OUString exportToSvg( const B2DHomMatrix& rMatrix ) + { + rtl::OUStringBuffer aStrBuf; + aStrBuf.appendAscii("matrix("); + + aStrBuf.append(rMatrix.get(0,0)); + aStrBuf.appendAscii(", "); + + aStrBuf.append(rMatrix.get(1,0)); + aStrBuf.appendAscii(", "); + + aStrBuf.append(rMatrix.get(0,1)); + aStrBuf.appendAscii(", "); + + aStrBuf.append(rMatrix.get(1,1)); + aStrBuf.appendAscii(", "); + + aStrBuf.append(rMatrix.get(0,2)); + aStrBuf.appendAscii(", "); + + aStrBuf.append(rMatrix.get(1,2)); + aStrBuf.appendAscii(")"); + + return aStrBuf.makeStringAndClear(); + } + namespace tools { void createSinCosOrthogonal(double& o_rSin, double& o_rCos, double fRadiant) diff --git a/basegfx/source/polygon/b2dpolygon.cxx b/basegfx/source/polygon/b2dpolygon.cxx index dc16938a3f99..d8255dc7ec10 100644 --- a/basegfx/source/polygon/b2dpolygon.cxx +++ b/basegfx/source/polygon/b2dpolygon.cxx @@ -41,38 +41,24 @@ ////////////////////////////////////////////////////////////////////////////// -class CoordinateData2D +struct CoordinateData2D : public basegfx::B2DPoint { - basegfx::B2DPoint maPoint; - public: - CoordinateData2D() - : maPoint() - {} + CoordinateData2D() {} explicit CoordinateData2D(const basegfx::B2DPoint& rData) - : maPoint(rData) + : B2DPoint(rData) {} - const basegfx::B2DPoint& getCoordinate() const + CoordinateData2D& operator=(const basegfx::B2DPoint& rData) { - return maPoint; - } - - void setCoordinate(const basegfx::B2DPoint& rValue) - { - if(rValue != maPoint) - maPoint = rValue; - } - - bool operator==(const CoordinateData2D& rData ) const - { - return (maPoint == rData.getCoordinate()); + B2DPoint::operator=(rData); + return *this; } void transform(const basegfx::B2DHomMatrix& rMatrix) { - maPoint *= rMatrix; + *this *= rMatrix; } }; @@ -112,12 +98,12 @@ public: const basegfx::B2DPoint& getCoordinate(sal_uInt32 nIndex) const { - return maVector[nIndex].getCoordinate(); + return maVector[nIndex]; } void setCoordinate(sal_uInt32 nIndex, const basegfx::B2DPoint& rValue) { - maVector[nIndex].setCoordinate(rValue); + maVector[nIndex] = rValue; } void reserve(sal_uInt32 nCount) @@ -228,6 +214,38 @@ public: aStart->transform(rMatrix); } } + + const basegfx::B2DPoint* begin() const + { + if(maVector.empty()) + return 0; + else + return &maVector.front(); + } + + const basegfx::B2DPoint* end() const + { + if(maVector.empty()) + return 0; + else + return (&maVector.back())+1; + } + + basegfx::B2DPoint* begin() + { + if(maVector.empty()) + return 0; + else + return &maVector.front(); + } + + basegfx::B2DPoint* end() + { + if(maVector.empty()) + return 0; + else + return (&maVector.back())+1; + } }; ////////////////////////////////////////////////////////////////////////////// @@ -1149,6 +1167,28 @@ public: maPoints.transform(rMatrix); } } + + const basegfx::B2DPoint* begin() const + { + return maPoints.begin(); + } + + const basegfx::B2DPoint* end() const + { + return maPoints.end(); + } + + basegfx::B2DPoint* begin() + { + mpBufferedData.reset(); + return maPoints.begin(); + } + + basegfx::B2DPoint* end() + { + mpBufferedData.reset(); + return maPoints.end(); + } }; ////////////////////////////////////////////////////////////////////////////// @@ -1586,6 +1626,26 @@ namespace basegfx mpPolygon->transform(rMatrix); } } + + const B2DPoint* B2DPolygon::begin() const + { + return mpPolygon->begin(); + } + + const B2DPoint* B2DPolygon::end() const + { + return mpPolygon->end(); + } + + B2DPoint* B2DPolygon::begin() + { + return mpPolygon->begin(); + } + + B2DPoint* B2DPolygon::end() + { + return mpPolygon->end(); + } } // end of namespace basegfx ////////////////////////////////////////////////////////////////////////////// diff --git a/basegfx/source/polygon/b2dpolygontools.cxx b/basegfx/source/polygon/b2dpolygontools.cxx index e54a5e2707c9..e9db491ecd48 100644 --- a/basegfx/source/polygon/b2dpolygontools.cxx +++ b/basegfx/source/polygon/b2dpolygontools.cxx @@ -2346,7 +2346,8 @@ namespace basegfx // polygon must be closed to resemble a rect, and contain // at least four points. if( !rPoly.isClosed() || - rPoly.count() < 4 ) + rPoly.count() < 4 || + rPoly.areControlPointsUsed() ) { return false; } diff --git a/basegfx/source/polygon/b2dpolypolygon.cxx b/basegfx/source/polygon/b2dpolypolygon.cxx index 767d2b25ced5..9b28dffd19af 100644 --- a/basegfx/source/polygon/b2dpolypolygon.cxx +++ b/basegfx/source/polygon/b2dpolypolygon.cxx @@ -163,6 +163,38 @@ public: maPolygons.end(), std::mem_fun_ref( &basegfx::B2DPolygon::makeUnique )); } + + const basegfx::B2DPolygon* begin() const + { + if(maPolygons.empty()) + return 0; + else + return &maPolygons.front(); + } + + const basegfx::B2DPolygon* end() const + { + if(maPolygons.empty()) + return 0; + else + return (&maPolygons.back())+1; + } + + basegfx::B2DPolygon* begin() + { + if(maPolygons.empty()) + return 0; + else + return &maPolygons.front(); + } + + basegfx::B2DPolygon* end() + { + if(maPolygons.empty()) + return 0; + else + return &(maPolygons.back())+1; + } }; ////////////////////////////////////////////////////////////////////////////// @@ -375,6 +407,26 @@ namespace basegfx mpPolyPolygon->transform(rMatrix); } } + + const B2DPolygon* B2DPolyPolygon::begin() const + { + return mpPolyPolygon->begin(); + } + + const B2DPolygon* B2DPolyPolygon::end() const + { + return mpPolyPolygon->end(); + } + + B2DPolygon* B2DPolyPolygon::begin() + { + return mpPolyPolygon->begin(); + } + + B2DPolygon* B2DPolyPolygon::end() + { + return mpPolyPolygon->end(); + } } // end of namespace basegfx // eof diff --git a/basegfx/source/polygon/b2dsvgpolypolygon.cxx b/basegfx/source/polygon/b2dsvgpolypolygon.cxx index bbb6db4c064a..d2815337edaf 100644 --- a/basegfx/source/polygon/b2dsvgpolypolygon.cxx +++ b/basegfx/source/polygon/b2dsvgpolypolygon.cxx @@ -65,10 +65,8 @@ namespace basegfx } } - inline bool lcl_isOnNumberChar(const ::rtl::OUString& rStr, const sal_Int32 nPos, bool bSignAllowed = true) + inline bool lcl_isOnNumberChar(const sal_Unicode aChar, bool bSignAllowed = true) { - const sal_Unicode aChar(rStr[nPos]); - const bool bPredicate( (sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar) || (bSignAllowed && sal_Unicode('+') == aChar) || (bSignAllowed && sal_Unicode('-') == aChar) ); @@ -76,6 +74,12 @@ namespace basegfx return bPredicate; } + inline bool lcl_isOnNumberChar(const ::rtl::OUString& rStr, const sal_Int32 nPos, bool bSignAllowed = true) + { + return lcl_isOnNumberChar(rStr[nPos], + bSignAllowed); + } + bool lcl_getDoubleChar(double& o_fRetval, sal_Int32& io_rPos, const ::rtl::OUString& rStr, @@ -231,16 +235,16 @@ namespace basegfx lcl_skipSpacesAndCommas(io_rPos, rStr, nLen); } - void lcl_putNumberChar( ::rtl::OUString& rStr, - double fValue ) + void lcl_putNumberChar( ::rtl::OUStringBuffer& rStr, + double fValue ) { - rStr += ::rtl::OUString::valueOf( fValue ); + rStr.append( fValue ); } - void lcl_putNumberCharWithSpace( ::rtl::OUString& rStr, - double fValue, - double fOldValue, - bool bUseRelativeCoordinates ) + void lcl_putNumberCharWithSpace( ::rtl::OUStringBuffer& rStr, + double fValue, + double fOldValue, + bool bUseRelativeCoordinates ) { if( bUseRelativeCoordinates ) fValue -= fOldValue; @@ -248,11 +252,10 @@ namespace basegfx const sal_Int32 aLen( rStr.getLength() ); if(aLen) { - if( lcl_isOnNumberChar(rStr, aLen - 1, false) && + if( lcl_isOnNumberChar(rStr.charAt(aLen - 1), false) && fValue >= 0.0 ) { - rStr += ::rtl::OUString::valueOf( - sal_Unicode(' ') ); + rStr.append( sal_Unicode(' ') ); } } @@ -876,7 +879,7 @@ namespace basegfx bool bDetectQuadraticBeziers) { const sal_uInt32 nCount(rPolyPolygon.count()); - ::rtl::OUString aResult; + ::rtl::OUStringBuffer aResult; B2DPoint aCurrentSVGPosition(0.0, 0.0); // SVG assumes (0,0) as the initial current point for(sal_uInt32 i(0); i < nCount; i++) @@ -893,7 +896,7 @@ namespace basegfx // handle polygon start point B2DPoint aEdgeStart(aPolygon.getB2DPoint(0)); - aResult += ::rtl::OUString::valueOf(lcl_getCommand('M', 'm', bUseRelativeCoordinates)); + aResult.append(lcl_getCommand('M', 'm', bUseRelativeCoordinates)); lcl_putNumberCharWithSpace(aResult, aEdgeStart.getX(), aCurrentSVGPosition.getX(), bUseRelativeCoordinates); lcl_putNumberCharWithSpace(aResult, aEdgeStart.getY(), aCurrentSVGPosition.getY(), bUseRelativeCoordinates); aLastSVGCommand = lcl_getCommand('L', 'l', bUseRelativeCoordinates); @@ -954,7 +957,7 @@ namespace basegfx if(aLastSVGCommand != aCommand) { - aResult += ::rtl::OUString::valueOf(aCommand); + aResult.append(aCommand); aLastSVGCommand = aCommand; } @@ -969,7 +972,7 @@ namespace basegfx if(aLastSVGCommand != aCommand) { - aResult += ::rtl::OUString::valueOf(aCommand); + aResult.append(aCommand); aLastSVGCommand = aCommand; } @@ -990,7 +993,7 @@ namespace basegfx if(aLastSVGCommand != aCommand) { - aResult += ::rtl::OUString::valueOf(aCommand); + aResult.append(aCommand); aLastSVGCommand = aCommand; } @@ -1007,7 +1010,7 @@ namespace basegfx if(aLastSVGCommand != aCommand) { - aResult += ::rtl::OUString::valueOf(aCommand); + aResult.append(aCommand); aLastSVGCommand = aCommand; } @@ -1046,7 +1049,7 @@ namespace basegfx if(aLastSVGCommand != aCommand) { - aResult += ::rtl::OUString::valueOf(aCommand); + aResult.append(aCommand); aLastSVGCommand = aCommand; } @@ -1060,7 +1063,7 @@ namespace basegfx if(aLastSVGCommand != aCommand) { - aResult += ::rtl::OUString::valueOf(aCommand); + aResult.append(aCommand); aLastSVGCommand = aCommand; } @@ -1074,7 +1077,7 @@ namespace basegfx if(aLastSVGCommand != aCommand) { - aResult += ::rtl::OUString::valueOf(aCommand); + aResult.append(aCommand); aLastSVGCommand = aCommand; } @@ -1092,12 +1095,12 @@ namespace basegfx // close path if closed poly (Z and z are equivalent here, but looks nicer when case is matched) if(aPolygon.isClosed()) { - aResult += ::rtl::OUString::valueOf(lcl_getCommand('Z', 'z', bUseRelativeCoordinates)); + aResult.append(lcl_getCommand('Z', 'z', bUseRelativeCoordinates)); } } } - return aResult; + return aResult.makeStringAndClear(); } } } diff --git a/basegfx/source/range/b2dmultirange.cxx b/basegfx/source/range/b2dmultirange.cxx deleted file mode 100644 index 3a47be3b7dc9..000000000000 --- a/basegfx/source/range/b2dmultirange.cxx +++ /dev/null @@ -1,279 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -// MARKER(update_precomp.py): autogen include statement, do not remove -#include "precompiled_basegfx.hxx" -#include <basegfx/range/b2drange.hxx> -#include <basegfx/tuple/b2dtuple.hxx> -#include <basegfx/polygon/b2dpolypolygon.hxx> -#include <basegfx/range/b2dmultirange.hxx> -#include <basegfx/polygon/b2dpolygontools.hxx> -#include <basegfx/polygon/b2dpolypolygontools.hxx> -#include <basegfx/polygon/b2dpolypolygoncutter.hxx> -#include <boost/bind.hpp> -#include <boost/mem_fn.hpp> -#include <algorithm> -#include <vector> - - -namespace basegfx -{ - class ImplB2DMultiRange - { - public: - ImplB2DMultiRange() : - maBounds(), - maRanges() - { - } - - explicit ImplB2DMultiRange( const B2DRange& rRange ) : - maBounds(), - maRanges( 1, rRange ) - { - } - - bool isEmpty() const - { - // no ranges at all, or all ranges empty - return maRanges.empty() || - ::std::count_if( maRanges.begin(), - maRanges.end(), - ::boost::mem_fn( &B2DRange::isEmpty ) ) - == static_cast<VectorOfRanges::difference_type>(maRanges.size()); - } - - void reset() - { - // swap in empty vector - VectorOfRanges aTmp; - maRanges.swap( aTmp ); - - maBounds.reset(); - } - - template< typename ValueType > bool isInside( const ValueType& rValue ) const - { - if( !maBounds.isInside( rValue ) ) - return false; - - // cannot use ::boost::bind here, since isInside is overloaded. - // It is currently not possible to resolve the overload - // by considering one of the other template arguments. - VectorOfRanges::const_iterator aCurr( maRanges.begin() ); - const VectorOfRanges::const_iterator aEnd ( maRanges.end() ); - while( aCurr != aEnd ) - if( aCurr->isInside( rValue ) ) - return true; - - return false; - } - - bool overlaps( const B2DRange& rRange ) const - { - if( !maBounds.overlaps( rRange ) ) - return false; - - const VectorOfRanges::const_iterator aEnd( maRanges.end() ); - return ::std::find_if( maRanges.begin(), - aEnd, - ::boost::bind<bool>( ::boost::mem_fn( &B2DRange::overlaps ), - _1, - rRange ) ) != aEnd; - } - - void addRange( const B2DRange& rRange ) - { - maRanges.push_back( rRange ); - maBounds.expand( rRange ); - } - - B2DRange getBounds() const - { - return maBounds; - } - - B2DPolyPolygon getPolyPolygon() const - { - B2DPolyPolygon aRes; - - // Make range vector unique ( have to avoid duplicate - // rectangles. The polygon clipper will return an empty - // result in this case). - VectorOfRanges aUniqueRanges; - aUniqueRanges.reserve( maRanges.size() ); - - VectorOfRanges::const_iterator aCurr( maRanges.begin() ); - const VectorOfRanges::const_iterator aEnd ( maRanges.end() ); - while( aCurr != aEnd ) - { - // TODO(F3): It's plain wasted resources to apply a - // general clipping algorithm to the problem at - // hand. Go for a dedicated, scan-line-based approach. - VectorOfRanges::const_iterator aCurrScan( aCurr+1 ); - VectorOfRanges::const_iterator aFound( aEnd ); - while( aCurrScan != aEnd ) - { - if( aCurrScan->equal( *aCurr ) || - aCurrScan->isInside( *aCurr ) ) - { - // current probe is equal to aCurr, or - // completely contains aCurr. Thus, stop - // searching, because aCurr is definitely not - // a member of the unique rect list - aFound = aCurrScan; - break; - } - - ++aCurrScan; - } - - if( aFound == aEnd ) - { - // check whether aCurr is fully contained in one - // of the already added rects. If yes, we can skip - // it. - bool bUnique( true ); - VectorOfRanges::const_iterator aCurrUnique( aUniqueRanges.begin() ); - VectorOfRanges::const_iterator aEndUnique ( aUniqueRanges.end() ); - while( aCurrUnique != aEndUnique ) - { - if( aCurrUnique->isInside( *aCurr ) ) - { - // fully contained, no need to add - bUnique = false; - break; - } - - ++aCurrUnique; - } - - if( bUnique ) - aUniqueRanges.push_back( *aCurr ); - } - - ++aCurr; - } - - VectorOfRanges::const_iterator aCurrUnique( aUniqueRanges.begin() ); - const VectorOfRanges::const_iterator aEndUnique ( aUniqueRanges.end() ); - while( aCurrUnique != aEndUnique ) - { - // simply merge all unique parts (OR) - aRes.append( tools::createPolygonFromRect( *aCurrUnique++ ) ); - } - - // remove redundant intersections. Note: since all added - // rectangles are positively oriented, this method cannot - // generate any holes. - aRes = basegfx::tools::solveCrossovers(aRes); - aRes = basegfx::tools::stripNeutralPolygons(aRes); - aRes = basegfx::tools::stripDispensablePolygons(aRes, false); - - return aRes; - } - - private: - typedef ::std::vector< B2DRange > VectorOfRanges; - - B2DRange maBounds; - VectorOfRanges maRanges; - }; - - - // ==================================================================== - - - B2DMultiRange::B2DMultiRange() : - mpImpl() - { - } - - B2DMultiRange::B2DMultiRange( const B2DRange& rRange ) : - mpImpl( ImplB2DMultiRange( rRange ) ) - { - } - - B2DMultiRange::~B2DMultiRange() - { - // otherwise, ImplB2DMultiRange would be an incomplete type - } - - B2DMultiRange::B2DMultiRange( const B2DMultiRange& rSrc ) : - mpImpl( rSrc.mpImpl ) - { - } - - B2DMultiRange& B2DMultiRange::operator=( const B2DMultiRange& rSrc ) - { - mpImpl = rSrc.mpImpl; - return *this; - } - - bool B2DMultiRange::isEmpty() const - { - return mpImpl->isEmpty(); - } - - void B2DMultiRange::reset() - { - mpImpl->reset(); - } - - bool B2DMultiRange::isInside( const B2DTuple& rTuple ) const - { - return mpImpl->isInside( rTuple ); - } - - bool B2DMultiRange::isInside( const B2DRange& rRange ) const - { - return mpImpl->isInside( rRange ); - } - - bool B2DMultiRange::overlaps( const B2DRange& rRange ) const - { - return mpImpl->overlaps( rRange ); - } - - void B2DMultiRange::addRange( const B2DRange& rRange ) - { - mpImpl->addRange( rRange ); - } - - B2DRange B2DMultiRange::getBounds() const - { - return mpImpl->getBounds(); - } - - B2DPolyPolygon B2DMultiRange::getPolyPolygon() const - { - return mpImpl->getPolyPolygon(); - } - -} // end of namespace basegfx - -// eof diff --git a/basegfx/source/range/b2dpolyrange.cxx b/basegfx/source/range/b2dpolyrange.cxx new file mode 100644 index 000000000000..e212e083ef55 --- /dev/null +++ b/basegfx/source/range/b2dpolyrange.cxx @@ -0,0 +1,423 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: b2dmultirange.cxx,v $ + * $Revision: 1.8 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_basegfx.hxx" +#include <basegfx/range/b2dpolyrange.hxx> + +#include <basegfx/range/b2drange.hxx> +#include <basegfx/range/b2drangeclipper.hxx> +#include <basegfx/tuple/b2dtuple.hxx> +#include <basegfx/polygon/b2dpolypolygon.hxx> + +#include <boost/bind.hpp> +#include <boost/tuple/tuple.hpp> +#include <algorithm> +#include <vector> + +static basegfx::B2VectorOrientation flipOrientation( + basegfx::B2VectorOrientation eOrient) +{ + return eOrient == basegfx::ORIENTATION_POSITIVE ? + basegfx::ORIENTATION_NEGATIVE : basegfx::ORIENTATION_POSITIVE; +} + +namespace basegfx +{ + class ImplB2DPolyRange + { + void updateBounds() + { + maBounds.reset(); + std::for_each(maRanges.begin(), + maRanges.end(), + boost::bind( + (void (B2DRange::*)(const B2DRange&))( + &B2DRange::expand), + boost::ref(maBounds), + _1)); + } + + public: + ImplB2DPolyRange() : + maBounds(), + maRanges(), + maOrient() + {} + + explicit ImplB2DPolyRange( const B2DPolyRange::ElementType& rElem ) : + maBounds( boost::get<0>(rElem) ), + maRanges( 1, boost::get<0>(rElem) ), + maOrient( 1, boost::get<1>(rElem) ) + {} + + explicit ImplB2DPolyRange( const B2DRange& rRange, B2VectorOrientation eOrient ) : + maBounds( rRange ), + maRanges( 1, rRange ), + maOrient( 1, eOrient ) + {} + + bool operator==(const ImplB2DPolyRange& rRHS) const + { + return maRanges == rRHS.maRanges && maOrient == rRHS.maOrient; + } + + sal_uInt32 count() const + { + return maRanges.size(); + } + + B2DPolyRange::ElementType getElement(sal_uInt32 nIndex) const + { + return boost::make_tuple(maRanges[nIndex], + maOrient[nIndex]); + } + + void setElement(sal_uInt32 nIndex, const B2DPolyRange::ElementType& rElement ) + { + maRanges[nIndex] = boost::get<0>(rElement); + maOrient[nIndex] = boost::get<1>(rElement); + updateBounds(); + } + + void setElement(sal_uInt32 nIndex, const B2DRange& rRange, B2VectorOrientation eOrient ) + { + maRanges[nIndex] = rRange; + maOrient[nIndex] = eOrient; + updateBounds(); + } + + void insertElement(sal_uInt32 nIndex, const B2DPolyRange::ElementType& rElement, sal_uInt32 nCount) + { + maRanges.insert(maRanges.begin()+nIndex, nCount, boost::get<0>(rElement)); + maOrient.insert(maOrient.begin()+nIndex, nCount, boost::get<1>(rElement)); + maBounds.expand(boost::get<0>(rElement)); + } + + void insertElement(sal_uInt32 nIndex, const B2DRange& rRange, B2VectorOrientation eOrient, sal_uInt32 nCount) + { + maRanges.insert(maRanges.begin()+nIndex, nCount, rRange); + maOrient.insert(maOrient.begin()+nIndex, nCount, eOrient); + maBounds.expand(rRange); + } + + void appendElement(const B2DPolyRange::ElementType& rElement, sal_uInt32 nCount) + { + maRanges.insert(maRanges.end(), nCount, boost::get<0>(rElement)); + maOrient.insert(maOrient.end(), nCount, boost::get<1>(rElement)); + maBounds.expand(boost::get<0>(rElement)); + } + + void appendElement(const B2DRange& rRange, B2VectorOrientation eOrient, sal_uInt32 nCount) + { + maRanges.insert(maRanges.end(), nCount, rRange); + maOrient.insert(maOrient.end(), nCount, eOrient); + maBounds.expand(rRange); + } + + void insertPolyRange(sal_uInt32 nIndex, const ImplB2DPolyRange& rPolyRange) + { + maRanges.insert(maRanges.begin()+nIndex, rPolyRange.maRanges.begin(), rPolyRange.maRanges.end()); + maOrient.insert(maOrient.begin()+nIndex, rPolyRange.maOrient.begin(), rPolyRange.maOrient.end()); + updateBounds(); + } + + void appendPolyRange(const ImplB2DPolyRange& rPolyRange) + { + maRanges.insert(maRanges.end(), + rPolyRange.maRanges.begin(), + rPolyRange.maRanges.end()); + maOrient.insert(maOrient.end(), + rPolyRange.maOrient.begin(), + rPolyRange.maOrient.end()); + updateBounds(); + } + + void remove(sal_uInt32 nIndex, sal_uInt32 nCount) + { + maRanges.erase(maRanges.begin()+nIndex,maRanges.begin()+nIndex+nCount); + maOrient.erase(maOrient.begin()+nIndex,maOrient.begin()+nIndex+nCount); + updateBounds(); + } + + void clear() + { + std::vector<B2DRange> aTmpRanges; + std::vector<B2VectorOrientation> aTmpOrient; + + maRanges.swap(aTmpRanges); + maOrient.swap(aTmpOrient); + + maBounds.reset(); + } + + void flip() + { + std::for_each(maOrient.begin(), + maOrient.end(), + boost::bind( + &flipOrientation, + _1)); + } + + B2DRange getBounds() const + { + return maBounds; + } + + template< typename ValueType > bool isInside( const ValueType& rValue ) const + { + if( !maBounds.isInside( rValue ) ) + return false; + + // cannot use boost::bind here, since isInside is overloaded. + // It is currently not possible to resolve the overload + // by considering one of the other template arguments. + std::vector<B2DRange>::const_iterator aCurr( maRanges.begin() ); + const std::vector<B2DRange>::const_iterator aEnd ( maRanges.end() ); + while( aCurr != aEnd ) + if( aCurr->isInside( rValue ) ) + return true; + + return false; + } + + bool overlaps( const B2DRange& rRange ) const + { + if( !maBounds.overlaps( rRange ) ) + return false; + + const std::vector<B2DRange>::const_iterator aEnd( maRanges.end() ); + return std::find_if( maRanges.begin(), + aEnd, + boost::bind<bool>( boost::mem_fn( &B2DRange::overlaps ), + _1, + boost::cref(rRange) ) ) != aEnd; + } + + B2DPolyPolygon solveCrossovers() const + { + return tools::solveCrossovers(maRanges,maOrient); + } + + const B2DRange* begin() const + { + if(maRanges.empty()) + return 0; + else + return &maRanges.front(); + } + + const B2DRange* end() const + { + if(maRanges.empty()) + return 0; + else + return (&maRanges.back())+1; + } + + B2DRange* begin() + { + if(maRanges.empty()) + return 0; + else + return &maRanges.front(); + } + + B2DRange* end() + { + if(maRanges.empty()) + return 0; + else + return (&maRanges.back())+1; + } + + private: + B2DRange maBounds; + std::vector<B2DRange> maRanges; + std::vector<B2VectorOrientation> maOrient; + }; + + B2DPolyRange::B2DPolyRange() : + mpImpl() + {} + + B2DPolyRange::~B2DPolyRange() + {} + + B2DPolyRange::B2DPolyRange( const ElementType& rElem ) : + mpImpl( ImplB2DPolyRange( rElem ) ) + {} + + B2DPolyRange::B2DPolyRange( const B2DRange& rRange, B2VectorOrientation eOrient ) : + mpImpl( ImplB2DPolyRange( rRange, eOrient ) ) + {} + + B2DPolyRange::B2DPolyRange( const B2DPolyRange& rRange ) : + mpImpl( rRange.mpImpl ) + {} + + B2DPolyRange& B2DPolyRange::operator=( const B2DPolyRange& rRange ) + { + mpImpl = rRange.mpImpl; + return *this; + } + + void B2DPolyRange::makeUnique() + { + mpImpl.make_unique(); + } + + bool B2DPolyRange::operator==(const B2DPolyRange& rRange) const + { + if(mpImpl.same_object(rRange.mpImpl)) + return true; + + return ((*mpImpl) == (*rRange.mpImpl)); + } + + bool B2DPolyRange::operator!=(const B2DPolyRange& rRange) const + { + return !(*this == rRange); + } + + sal_uInt32 B2DPolyRange::count() const + { + return mpImpl->count(); + } + + B2DPolyRange::ElementType B2DPolyRange::getElement(sal_uInt32 nIndex) const + { + return mpImpl->getElement(nIndex); + } + + void B2DPolyRange::setElement(sal_uInt32 nIndex, const ElementType& rElement ) + { + mpImpl->setElement(nIndex, rElement); + } + + void B2DPolyRange::setElement(sal_uInt32 nIndex, const B2DRange& rRange, B2VectorOrientation eOrient ) + { + mpImpl->setElement(nIndex, rRange, eOrient ); + } + + void B2DPolyRange::insertElement(sal_uInt32 nIndex, const ElementType& rElement, sal_uInt32 nCount) + { + mpImpl->insertElement(nIndex, rElement, nCount ); + } + + void B2DPolyRange::insertElement(sal_uInt32 nIndex, const B2DRange& rRange, B2VectorOrientation eOrient, sal_uInt32 nCount) + { + mpImpl->insertElement(nIndex, rRange, eOrient, nCount ); + } + + void B2DPolyRange::appendElement(const ElementType& rElement, sal_uInt32 nCount) + { + mpImpl->appendElement(rElement, nCount); + } + + void B2DPolyRange::appendElement(const B2DRange& rRange, B2VectorOrientation eOrient, sal_uInt32 nCount) + { + mpImpl->appendElement(rRange, eOrient, nCount ); + } + + void B2DPolyRange::insertPolyRange(sal_uInt32 nIndex, const B2DPolyRange& rRange) + { + mpImpl->insertPolyRange(nIndex, *rRange.mpImpl); + } + + void B2DPolyRange::appendPolyRange(const B2DPolyRange& rRange) + { + mpImpl->appendPolyRange(*rRange.mpImpl); + } + + void B2DPolyRange::remove(sal_uInt32 nIndex, sal_uInt32 nCount) + { + mpImpl->remove(nIndex, nCount); + } + + void B2DPolyRange::clear() + { + mpImpl->clear(); + } + + void B2DPolyRange::flip() + { + mpImpl->flip(); + } + + B2DRange B2DPolyRange::getBounds() const + { + return mpImpl->getBounds(); + } + + bool B2DPolyRange::isInside( const B2DTuple& rTuple ) const + { + return mpImpl->isInside(rTuple); + } + + bool B2DPolyRange::isInside( const B2DRange& rRange ) const + { + return mpImpl->isInside(rRange); + } + + bool B2DPolyRange::overlaps( const B2DRange& rRange ) const + { + return mpImpl->overlaps(rRange); + } + + B2DPolyPolygon B2DPolyRange::solveCrossovers() const + { + return mpImpl->solveCrossovers(); + } + + const B2DRange* B2DPolyRange::begin() const + { + return mpImpl->begin(); + } + + const B2DRange* B2DPolyRange::end() const + { + return mpImpl->end(); + } + + B2DRange* B2DPolyRange::begin() + { + return mpImpl->begin(); + } + + B2DRange* B2DPolyRange::end() + { + return mpImpl->end(); + } + +} // end of namespace basegfx + +// eof diff --git a/basegfx/source/range/b2drangeclipper.cxx b/basegfx/source/range/b2drangeclipper.cxx new file mode 100644 index 000000000000..524479b4fde0 --- /dev/null +++ b/basegfx/source/range/b2drangeclipper.cxx @@ -0,0 +1,950 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: b2dmultirange.cxx,v $ + * $Revision: 1.8 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_basegfx.hxx" + +#include <rtl/math.hxx> + +#include <basegfx/tuple/b2dtuple.hxx> +#include <basegfx/range/b2drange.hxx> +#include <basegfx/range/b2dpolyrange.hxx> +#include <basegfx/polygon/b2dpolypolygon.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/polygon/b2dpolypolygontools.hxx> + +#include <o3tl/vector_pool.hxx> +#include <boost/bind.hpp> +#include <boost/utility.hpp> + +#include <algorithm> +#include <deque> +#include <list> + + +namespace basegfx +{ + namespace + { + // Generating a poly-polygon from a bunch of rectangles + // + // Helper functionality for sweep-line algorithm + // ==================================================== + + typedef std::vector<B2DRange> VectorOfRanges; + + class ImplPolygon; + typedef o3tl::vector_pool<ImplPolygon> VectorOfPolygons; + + + /** This class represents an active edge + + As the sweep line traverses across the overall area, + rectangle edges parallel to it generate events, and + rectangle edges orthogonal to it generate active + edges. This class represents the latter. + */ + class ActiveEdge + { + public: + /** The two possible active rectangle edges differ by one + coordinate value - the upper edge has the lower, the + lower edge the higher value. + */ + enum EdgeType { + /// edge with lower coordinate value + UPPER=0, + /// edge with higher coordinate value + LOWER=1 + }; + + enum EdgeDirection { + /// edge proceeds to the left + PROCEED_LEFT=0, + /// edge proceeds to the right + PROCEED_RIGHT=1 + }; + + /** Create active edge + + @param rRect + Rectangle this edge is part of + + @param fInvariantCoord + The invariant ccordinate value of this edge + + @param eEdgeType + Is fInvariantCoord the lower or the higher value, for + this rect? + */ + ActiveEdge( const B2DRectangle& rRect, + const double& fInvariantCoord, + std::ptrdiff_t nPolyIdx, + EdgeType eEdgeType, + EdgeDirection eEdgeDirection ) : + mfInvariantCoord(fInvariantCoord), + mpAssociatedRect( &rRect ), + mnPolygonIdx( nPolyIdx ), + meEdgeType( eEdgeType ), + meEdgeDirection( eEdgeDirection ) + {} + + double getInvariantCoord() const { return mfInvariantCoord; } + const B2DRectangle& getRect() const { return *mpAssociatedRect; } + std::ptrdiff_t getTargetPolygonIndex() const { return mnPolygonIdx; } + void setTargetPolygonIndex( std::ptrdiff_t nIdx ) { mnPolygonIdx = nIdx; } + EdgeType getEdgeType() const { return meEdgeType; } + EdgeDirection getEdgeDirection() const { return meEdgeDirection; } + + /// For STL sort + bool operator<( const ActiveEdge& rRHS ) const { return mfInvariantCoord < rRHS.mfInvariantCoord; } + + private: + /** The invariant coordinate value of this edge (e.g. the + common y value, for a horizontal edge) + */ + double mfInvariantCoord; + + /** Associated rectangle + + This on the one hand saves some storage space (the + vector of rectangles is persistent, anyway), and on + the other hand provides an identifier to match active + edges and x events (see below) + + Ptr because class needs to be assignable + */ + const B2DRectangle* mpAssociatedRect; + + /** Index of the polygon this edge is currently involved + with. + + Note that this can change for some kinds of edge + intersection, as the algorithm tends to swap + associated polygons there. + + -1 denotes no assigned polygon + */ + std::ptrdiff_t mnPolygonIdx; + + /// 'upper' or 'lower' edge of original rectangle. + EdgeType meEdgeType; + + /// 'left' or 'right' + EdgeDirection meEdgeDirection; + }; + + // Needs to be list - various places hold ptrs to elements + typedef std::list< ActiveEdge > ListOfEdges; + + + /** Element of the sweep line event list + + As the sweep line traverses across the overall area, + rectangle edges parallel to it generate events, and + rectangle edges orthogonal to it generate active + edges. This class represents the former. + + The class defines an element of the sweep line list. The + sweep line's position jumps in steps defined by the + coordinates of the sorted SweepLineEvent entries. + */ + class SweepLineEvent + { + public: + /** The two possible sweep line rectangle edges differ by + one coordinate value - the starting edge has the + lower, the finishing edge the higher value. + */ + enum EdgeType { + /// edge with lower coordinate value + STARTING_EDGE=0, + /// edge with higher coordinate value + FINISHING_EDGE=1 + }; + + /** The two possible sweep line directions + */ + enum EdgeDirection { + PROCEED_UP=0, + PROCEED_DOWN=1 + }; + + /** Create sweep line event + + @param fPos + Coordinate position of the event + + @param rRect + Rectangle this event is generated for. + + @param eEdgeType + Is fPos the lower or the higher value, for the + rectangle this event is generated for? + */ + SweepLineEvent( double fPos, + const B2DRectangle& rRect, + EdgeType eEdgeType, + EdgeDirection eDirection) : + mfPos( fPos ), + mpAssociatedRect( &rRect ), + meEdgeType( eEdgeType ), + meEdgeDirection( eDirection ) + {} + + double getPos() const { return mfPos; } + const B2DRectangle& getRect() const { return *mpAssociatedRect; } + EdgeType getEdgeType() const { return meEdgeType; } + EdgeDirection getEdgeDirection() const { return meEdgeDirection; } + + /// For STL sort + bool operator<( const SweepLineEvent& rRHS ) const { return mfPos < rRHS.mfPos; } + + private: + /// position of the event, in the direction of the line sweep + double mfPos; + + /** Rectangle this event is generated for + + This on the one hand saves some storage space (the + vector of rectangles is persistent, anyway), and on + the other hand provides an identifier to match active + edges and events (see below) + + Ptr because class needs to be assignable + */ + const B2DRectangle* mpAssociatedRect; + + /// 'upper' or 'lower' edge of original rectangle. + EdgeType meEdgeType; + + /// 'up' or 'down' + EdgeDirection meEdgeDirection; + }; + + typedef std::vector< SweepLineEvent > VectorOfEvents; + + + /** Smart point container for B2DMultiRange::getPolyPolygon() + + This class provides methods needed only here, and is used + as a place to store some additional information per + polygon. Also, most of the intersection logic is + implemented here. + */ + class ImplPolygon + { + public: + /** Create polygon + */ + ImplPolygon() : + mpLeadingRightEdge(NULL), + mnIdx(-1), + maPoints(), + mbIsFinished(false) + { + // completely ad-hoc. but what the hell. + maPoints.reserve(11); + } + + void setPolygonPoolIndex( std::ptrdiff_t nIdx ) { mnIdx = nIdx; } + bool isFinished() const { return mbIsFinished; } + + /// Add point to the end of the existing points + void append( const B2DPoint& rPoint ) + { + OSL_PRECOND( maPoints.empty() || + maPoints.back().getX() == rPoint.getX() || + maPoints.back().getY() == rPoint.getY(), + "ImplPolygon::append(): added point violates 90 degree line angle constraint!" ); + + if( maPoints.empty() || + maPoints.back() != rPoint ) + { + // avoid duplicate points + maPoints.push_back( rPoint ); + } + } + + /** Perform the intersection of this polygon with an + active edge. + + @param rEvent + The vertical line event that generated the + intersection + + @param rActiveEdge + The active edge that generated the intersection + + @param rPolygonPool + Polygon pool, we sometimes need to allocate a new one + + @param bIsFinishingEdge + True, when this is hitting the last edge of the + vertical sweep - every vertical sweep starts and ends + with upper and lower edge of the _same_ rectangle. + + @return the new current polygon (that's the one + processing must proceed with, when going through the + list of upcoming active edges). + */ + std::ptrdiff_t intersect( SweepLineEvent& rEvent, + ActiveEdge& rActiveEdge, + VectorOfPolygons& rPolygonPool, + B2DPolyPolygon& rRes, + bool isFinishingEdge ) + { + OSL_PRECOND( !isFinished(), + "ImplPolygon::intersect(): called on already finished polygon!" ); + OSL_PRECOND( !isFinishingEdge + || (isFinishingEdge && &rEvent.getRect() == &rActiveEdge.getRect()), + "ImplPolygon::intersect(): inconsistent ending!" ); + + const B2DPoint aIntersectionPoint( rEvent.getPos(), + rActiveEdge.getInvariantCoord() ); + + // intersection point, goes to our polygon + // unconditionally + append(aIntersectionPoint); + + const bool isSweepLineEnteringRect( + rEvent.getEdgeType() == SweepLineEvent::STARTING_EDGE); + if( isFinishingEdge ) + { + if( isSweepLineEnteringRect ) + handleFinalOwnRightEdge(rActiveEdge); + else + handleFinalOwnLeftEdge(rActiveEdge, + rPolygonPool, + rRes); + + // we're done with this rect & sweep line + return -1; + } + else if( metOwnEdge(rEvent,rActiveEdge) ) + { + handleInitialOwnEdge(rEvent, rActiveEdge); + + // point already added, all init done, continue + // with same poly + return mnIdx; + } + else + { + OSL_ENSURE( rActiveEdge.getTargetPolygonIndex() != -1, + "ImplPolygon::intersect(): non-trivial intersection hit empty polygon!" ); + + const bool isHittingLeftEdge( + rActiveEdge.getEdgeDirection() == ActiveEdge::PROCEED_LEFT); + + if( isHittingLeftEdge ) + return handleComplexLeftEdge(rActiveEdge, + aIntersectionPoint, + rPolygonPool, + rRes); + else + return handleComplexRightEdge(rActiveEdge, + aIntersectionPoint, + rPolygonPool); + } + } + + private: + std::ptrdiff_t getPolygonPoolIndex() const { return mnIdx; } + + void handleInitialOwnEdge(SweepLineEvent& rEvent, + ActiveEdge& rActiveEdge) + { + const bool isActiveEdgeProceedLeft( + rActiveEdge.getEdgeDirection() == ActiveEdge::PROCEED_LEFT); + const bool isSweepLineEnteringRect( + rEvent.getEdgeType() == SweepLineEvent::STARTING_EDGE); + (void)isActiveEdgeProceedLeft; + (void)isSweepLineEnteringRect; + + OSL_ENSURE( isSweepLineEnteringRect == isActiveEdgeProceedLeft, + "ImplPolygon::intersect(): sweep initial own edge hit: wrong polygon order" ); + + OSL_ENSURE( isSweepLineEnteringRect || + mpLeadingRightEdge == &rActiveEdge, + "ImplPolygon::intersect(): sweep initial own edge hit: wrong leading edge" ); + } + + void handleFinalOwnRightEdge(ActiveEdge& rActiveEdge) + { + OSL_ENSURE( rActiveEdge.getEdgeDirection() == ActiveEdge::PROCEED_RIGHT, + "ImplPolygon::handleInitialOwnRightEdge(): start edge wrong polygon order" ); + + rActiveEdge.setTargetPolygonIndex(mnIdx); + mpLeadingRightEdge = &rActiveEdge; + } + + void handleFinalOwnLeftEdge(ActiveEdge& rActiveEdge, + VectorOfPolygons& rPolygonPool, + B2DPolyPolygon& rRes) + { + OSL_ENSURE( rActiveEdge.getEdgeDirection() == ActiveEdge::PROCEED_LEFT, + "ImplPolygon::handleFinalOwnLeftEdge(): end edge wrong polygon order" ); + + const bool isHittingOurTail( + rActiveEdge.getTargetPolygonIndex() == mnIdx); + + if( isHittingOurTail ) + finish(rRes); // just finish. no fuss. + else + { + // temp poly hits final left edge + const std::ptrdiff_t nTmpIdx=rActiveEdge.getTargetPolygonIndex(); + ImplPolygon& rTmp=rPolygonPool.get(nTmpIdx); + + // active edge's polygon has points + // already. ours need to go in front of them. + maPoints.insert(maPoints.end(), + rTmp.maPoints.begin(), + rTmp.maPoints.end()); + + // adjust leading edges, we're switching the polygon + ActiveEdge* const pFarEdge=rTmp.mpLeadingRightEdge; + + mpLeadingRightEdge = pFarEdge; + pFarEdge->setTargetPolygonIndex(mnIdx); + + // nTmpIdx is an empty shell, get rid of it + rPolygonPool.free(nTmpIdx); + } + } + + std::ptrdiff_t handleComplexLeftEdge(ActiveEdge& rActiveEdge, + const B2DPoint& rIntersectionPoint, + VectorOfPolygons& rPolygonPool, + B2DPolyPolygon& rRes) + { + const bool isHittingOurTail( + rActiveEdge.getTargetPolygonIndex() == mnIdx); + if( isHittingOurTail ) + { + finish(rRes); + + // so "this" is done - need new polygon to collect + // further points + const std::ptrdiff_t nIdxNewPolygon=rPolygonPool.alloc(); + rPolygonPool.get(nIdxNewPolygon).setPolygonPoolIndex(nIdxNewPolygon); + rPolygonPool.get(nIdxNewPolygon).append(rIntersectionPoint); + + rActiveEdge.setTargetPolygonIndex(nIdxNewPolygon); + + return nIdxNewPolygon; + } + else + { + const std::ptrdiff_t nTmpIdx=rActiveEdge.getTargetPolygonIndex(); + ImplPolygon& rTmp=rPolygonPool.get(nTmpIdx); + + // active edge's polygon has points + // already. ours need to go in front of them. + maPoints.insert(maPoints.end(), + rTmp.maPoints.begin(), + rTmp.maPoints.end()); + + rTmp.maPoints.clear(); + rTmp.append(rIntersectionPoint); + + // adjust leading edges, we're switching the polygon + ActiveEdge* const pFarEdge=rTmp.mpLeadingRightEdge; + ActiveEdge* const pNearEdge=&rActiveEdge; + + rTmp.mpLeadingRightEdge = NULL; + pNearEdge->setTargetPolygonIndex(nTmpIdx); + + mpLeadingRightEdge = pFarEdge; + pFarEdge->setTargetPolygonIndex(mnIdx); + + return nTmpIdx; + } + } + + std::ptrdiff_t handleComplexRightEdge(ActiveEdge& rActiveEdge, + const B2DPoint& rIntersectionPoint, + VectorOfPolygons& rPolygonPool) + { + const std::ptrdiff_t nTmpIdx=rActiveEdge.getTargetPolygonIndex(); + ImplPolygon& rTmp=rPolygonPool.get(nTmpIdx); + + rTmp.append(rIntersectionPoint); + + rActiveEdge.setTargetPolygonIndex(mnIdx); + mpLeadingRightEdge = &rActiveEdge; + + rTmp.mpLeadingRightEdge = NULL; + + return nTmpIdx; + } + + /// True when sweep line hits our own active edge + bool metOwnEdge(const SweepLineEvent& rEvent, + ActiveEdge& rActiveEdge) + { + const bool bHitOwnEdge=&rEvent.getRect() == &rActiveEdge.getRect(); + return bHitOwnEdge; + } + + /// Retrieve B2DPolygon from this object + B2DPolygon getPolygon() const + { + B2DPolygon aRes; + std::for_each( maPoints.begin(), + maPoints.end(), + boost::bind( + &B2DPolygon::append, + boost::ref(aRes), + _1, + 1 ) ); + aRes.setClosed( true ); + return aRes; + } + + /** Finish this polygon, push to result set. + */ + void finish(B2DPolyPolygon& rRes) + { + OSL_PRECOND( maPoints.empty() || + maPoints.front().getX() == maPoints.back().getX() || + maPoints.front().getY() == maPoints.back().getY(), + "ImplPolygon::finish(): first and last point violate 90 degree line angle constraint!" ); + + mbIsFinished = true; + mpLeadingRightEdge = NULL; + + rRes.append(getPolygon()); + } + + /** Refers to the current leading edge element of this + polygon, or NULL. The leading edge denotes the 'front' + of the polygon vertex sequence, i.e. the coordinates + at the polygon's leading edge are returned from + maPoints.front() + */ + ActiveEdge* mpLeadingRightEdge; + + /// current index into vector pool + std::ptrdiff_t mnIdx; + + /// Container for the actual polygon points + std::vector<B2DPoint> maPoints; + + /// When true, this polygon is 'done', i.e. nothing must be added anymore. + bool mbIsFinished; + }; + + /** Init sweep line event list + + This method fills the event list with the sweep line + events generated from the input rectangles, and sorts them + with increasing x. + */ + void setupSweepLineEventListFromRanges( VectorOfEvents& o_rEventVector, + const std::vector<B2DRange>& rRanges, + const std::vector<B2VectorOrientation>& rOrientations ) + { + // we need exactly 2*rectVec.size() events: one for the + // left, and one for the right edge of each rectangle + o_rEventVector.clear(); + o_rEventVector.reserve( 2*rRanges.size() ); + + // generate events + // =============== + + // first pass: add all left edges in increasing order + std::vector<B2DRange>::const_iterator aCurrRect=rRanges.begin(); + std::vector<B2VectorOrientation>::const_iterator aCurrOrientation=rOrientations.begin(); + const std::vector<B2DRange>::const_iterator aEnd=rRanges.end(); + const std::vector<B2VectorOrientation>::const_iterator aEndOrientation=rOrientations.end(); + while( aCurrRect != aEnd && aCurrOrientation != aEndOrientation ) + { + const B2DRectangle& rCurrRect( *aCurrRect++ ); + + o_rEventVector.push_back( + SweepLineEvent( rCurrRect.getMinX(), + rCurrRect, + SweepLineEvent::STARTING_EDGE, + (*aCurrOrientation++) == ORIENTATION_POSITIVE ? + SweepLineEvent::PROCEED_UP : SweepLineEvent::PROCEED_DOWN) ); + } + + // second pass: add all right edges in reversed order + std::vector<B2DRange>::const_reverse_iterator aCurrRectR=rRanges.rbegin(); + std::vector<B2VectorOrientation>::const_reverse_iterator aCurrOrientationR=rOrientations.rbegin(); + const std::vector<B2DRange>::const_reverse_iterator aEndR=rRanges.rend(); + const std::vector<B2VectorOrientation>::const_reverse_iterator aEndOrientationR=rOrientations.rend(); + while( aCurrRectR != aEndR ) + { + const B2DRectangle& rCurrRect( *aCurrRectR++ ); + + o_rEventVector.push_back( + SweepLineEvent( rCurrRect.getMaxX(), + rCurrRect, + SweepLineEvent::FINISHING_EDGE, + (*aCurrOrientationR++) == ORIENTATION_POSITIVE ? + SweepLineEvent::PROCEED_DOWN : SweepLineEvent::PROCEED_UP ) ); + } + + // sort events + // =========== + + // since we use stable_sort, the order of events with the + // same x value will not change. The elaborate two-pass + // add above thus ensures, that for each two rectangles + // with similar left and right x coordinates, the + // rectangle whose left event comes first will have its + // right event come last. This is advantageous for the + // clip algorithm below, see handleRightEdgeCrossing(). + + // TODO(P3): Use radix sort (from + // b2dpolypolygonrasterconverter, or have your own + // templatized version). + std::stable_sort( o_rEventVector.begin(), + o_rEventVector.end() ); + } + + /** Insert two active edge segments for the given rectangle. + + This method creates two active edge segments from the + given rect, and inserts them into the active edge list, + such that this stays sorted (if it was before). + + @param io_rEdgeList + Active edge list to insert into + + @param io_rPolygons + Vector of polygons. Each rectangle added creates one + tentative result polygon in this vector, and the edge list + entries holds a reference to that polygon (this _requires_ + that the polygon vector does not reallocate, i.e. it must + have at least the maximal number of rectangles reserved) + + @param o_CurrentPolygon + The then-current polygon when processing this sweep line + event + + @param rCurrEvent + The actual event that caused this call + */ + void createActiveEdgesFromStartEvent( ListOfEdges& io_rEdgeList, + VectorOfPolygons& io_rPolygonPool, + SweepLineEvent& rCurrEvent ) + { + ListOfEdges aNewEdges; + const B2DRectangle& rRect=rCurrEvent.getRect(); + const bool bGoesDown=rCurrEvent.getEdgeDirection() == SweepLineEvent::PROCEED_DOWN; + + // start event - new rect starts here, needs polygon to + // collect points into + const std::ptrdiff_t nIdxPolygon=io_rPolygonPool.alloc(); + io_rPolygonPool.get(nIdxPolygon).setPolygonPoolIndex(nIdxPolygon); + + // upper edge + aNewEdges.push_back( + ActiveEdge( + rRect, + rRect.getMinY(), + bGoesDown ? nIdxPolygon : -1, + ActiveEdge::UPPER, + bGoesDown ? ActiveEdge::PROCEED_LEFT : ActiveEdge::PROCEED_RIGHT) ); + // lower edge + aNewEdges.push_back( + ActiveEdge( + rRect, + rRect.getMaxY(), + bGoesDown ? -1 : nIdxPolygon, + ActiveEdge::LOWER, + bGoesDown ? ActiveEdge::PROCEED_RIGHT : ActiveEdge::PROCEED_LEFT ) ); + + // furthermore, have to respect a special tie-breaking + // rule here, for edges which share the same y value: + // newly added upper edges must be inserted _before_ any + // other edge with the same y value, and newly added lower + // edges must be _after_ all other edges with the same + // y. This ensures that the left vertical edge processing + // below encounters the upper edge of the current rect + // first, and the lower edge last, which automatically + // starts and finishes this rect correctly (as only then, + // the polygon will have their associated active edges + // set). + const double nMinY( rRect.getMinY() ); + const double nMaxY( rRect.getMaxY() ); + ListOfEdges::iterator aCurr( io_rEdgeList.begin() ); + const ListOfEdges::iterator aEnd ( io_rEdgeList.end() ); + while( aCurr != aEnd ) + { + const double nCurrY( aCurr->getInvariantCoord() ); + + if( nCurrY >= nMinY && + aNewEdges.size() == 2 ) // only add, if not yet done. + { + // insert upper edge _before_ aCurr. Thus, it will + // be the first entry for a range of equal y + // values. Using splice here, since we hold + // references to the moved list element! + io_rEdgeList.splice( aCurr, + aNewEdges, + aNewEdges.begin() ); + } + + if( nCurrY > nMaxY ) + { + // insert lower edge _before_ aCurr. Thus, it will + // be the last entry for a range of equal y values + // (aCurr is the first entry strictly larger than + // nMaxY). Using splice here, since we hold + // references to the moved list element! + io_rEdgeList.splice( aCurr, + aNewEdges, + aNewEdges.begin() ); + // done with insertion, can early-exit here. + return; + } + + ++aCurr; + } + + // append remainder of aNewList (might still contain 2 or + // 1 elements, depending of the contents of io_rEdgeList). + io_rEdgeList.splice( aCurr, + aNewEdges ); + } + + inline bool isSameRect(ActiveEdge& rEdge, + const basegfx::B2DRange& rRect) + { + return &rEdge.getRect() == &rRect; + } + + // wow what a hack. necessary because stl's list::erase does + // not eat reverse_iterator + template<typename Cont, typename Iter> Iter eraseFromList(Cont&, Iter); + template<> inline ListOfEdges::iterator eraseFromList( + ListOfEdges& rList, ListOfEdges::iterator aIter) + { + return rList.erase(aIter); + } + template<> inline ListOfEdges::reverse_iterator eraseFromList( + ListOfEdges& rList, ListOfEdges::reverse_iterator aIter) + { + return ListOfEdges::reverse_iterator( + rList.erase(boost::prior(aIter.base()))); + } + + template<int bPerformErase, + typename Iterator> inline void processActiveEdges( + Iterator first, + Iterator last, + ListOfEdges& rActiveEdgeList, + SweepLineEvent& rCurrEvent, + VectorOfPolygons& rPolygonPool, + B2DPolyPolygon& rRes ) + { + const basegfx::B2DRange& rCurrRect=rCurrEvent.getRect(); + + // fast-forward to rCurrEvent's first active edge (holds + // for both starting and finishing sweep line events, a + // rect is regarded _outside_ any rects whose events have + // started earlier + first = std::find_if(first, last, + boost::bind( + &isSameRect, + _1, + boost::cref(rCurrRect))); + + if(first == last) + return; + + int nCount=0; + std::ptrdiff_t nCurrPolyIdx=-1; + while(first != last) + { + if( nCurrPolyIdx == -1 ) + nCurrPolyIdx=first->getTargetPolygonIndex(); + + OSL_ASSERT(nCurrPolyIdx != -1); + + // second encounter of my rect -> second edge + // encountered, done + const bool bExit= + nCount && + isSameRect(*first, + rCurrRect); + + // deal with current active edge + nCurrPolyIdx = + rPolygonPool.get(nCurrPolyIdx).intersect( + rCurrEvent, + *first, + rPolygonPool, + rRes, + bExit); + + // prune upper & lower active edges, if requested + if( bPerformErase && (bExit || !nCount) ) + first = eraseFromList(rActiveEdgeList,first); + else + ++first; + + // delayed exit, had to prune first + if( bExit ) + return; + + ++nCount; + } + } + + template<int bPerformErase> inline void processActiveEdgesTopDown( + SweepLineEvent& rCurrEvent, + ListOfEdges& rActiveEdgeList, + VectorOfPolygons& rPolygonPool, + B2DPolyPolygon& rRes ) + { + processActiveEdges<bPerformErase>( + rActiveEdgeList. begin(), + rActiveEdgeList. end(), + rActiveEdgeList, + rCurrEvent, + rPolygonPool, + rRes); + } + + template<int bPerformErase> inline void processActiveEdgesBottomUp( + SweepLineEvent& rCurrEvent, + ListOfEdges& rActiveEdgeList, + VectorOfPolygons& rPolygonPool, + B2DPolyPolygon& rRes ) + { + processActiveEdges<bPerformErase>( + rActiveEdgeList. rbegin(), + rActiveEdgeList. rend(), + rActiveEdgeList, + rCurrEvent, + rPolygonPool, + rRes); + } + + enum{ NoErase=0, PerformErase=1 }; + + void handleStartingEdge( SweepLineEvent& rCurrEvent, + ListOfEdges& rActiveEdgeList, + VectorOfPolygons& rPolygonPool, + B2DPolyPolygon& rRes) + { + // inject two new active edges for rect + createActiveEdgesFromStartEvent( rActiveEdgeList, + rPolygonPool, + rCurrEvent ); + + if( SweepLineEvent::PROCEED_DOWN == rCurrEvent.getEdgeDirection() ) + processActiveEdgesTopDown<NoErase>( + rCurrEvent, rActiveEdgeList, rPolygonPool, rRes); + else + processActiveEdgesBottomUp<NoErase>( + rCurrEvent, rActiveEdgeList, rPolygonPool, rRes); + } + + void handleFinishingEdge( SweepLineEvent& rCurrEvent, + ListOfEdges& rActiveEdgeList, + VectorOfPolygons& rPolygonPool, + B2DPolyPolygon& rRes) + { + if( SweepLineEvent::PROCEED_DOWN == rCurrEvent.getEdgeDirection() ) + processActiveEdgesTopDown<PerformErase>( + rCurrEvent, rActiveEdgeList, rPolygonPool, rRes); + else + processActiveEdgesBottomUp<PerformErase>( + rCurrEvent, rActiveEdgeList, rPolygonPool, rRes); + } + + inline void handleSweepLineEvent( SweepLineEvent& rCurrEvent, + ListOfEdges& rActiveEdgeList, + VectorOfPolygons& rPolygonPool, + B2DPolyPolygon& rRes) + { + if( SweepLineEvent::STARTING_EDGE == rCurrEvent.getEdgeType() ) + handleStartingEdge(rCurrEvent,rActiveEdgeList,rPolygonPool,rRes); + else + handleFinishingEdge(rCurrEvent,rActiveEdgeList,rPolygonPool,rRes); + } + } + + namespace tools + { + B2DPolyPolygon solveCrossovers(const std::vector<B2DRange>& rRanges, + const std::vector<B2VectorOrientation>& rOrientations) + { + // sweep-line algorithm to generate a poly-polygon + // from a bunch of rectangles + // =============================================== + // + // This algorithm uses the well-known sweep line + // concept, explained in every good text book about + // computational geometry. + // + // We start with creating two structures for every + // rectangle, one representing the left x coordinate, + // one representing the right x coordinate (and both + // referencing the original rect). These structs are + // sorted with increasing x coordinates. + // + // Then, we start processing the resulting list from + // the beginning. Every entry in the list defines a + // point in time of the line sweeping from left to + // right across all rectangles. + VectorOfEvents aSweepLineEvents; + setupSweepLineEventListFromRanges( aSweepLineEvents, + rRanges, + rOrientations ); + + B2DPolyPolygon aRes; + VectorOfPolygons aPolygonPool; + ListOfEdges aActiveEdgeList; + + // sometimes not enough, but a usable compromise + aPolygonPool.reserve( rRanges.size() ); + + std::for_each( aSweepLineEvents.begin(), + aSweepLineEvents.end(), + boost::bind( + &handleSweepLineEvent, + _1, + boost::ref(aActiveEdgeList), + boost::ref(aPolygonPool), + boost::ref(aRes)) ); + + return aRes; + } + } +} + diff --git a/basegfx/source/range/makefile.mk b/basegfx/source/range/makefile.mk index 04d8e8e66fa2..5e05eeda94d9 100644 --- a/basegfx/source/range/makefile.mk +++ b/basegfx/source/range/makefile.mk @@ -43,7 +43,8 @@ SLOFILES= \ $(SLO)$/b1drange.obj \ $(SLO)$/b2drange.obj \ $(SLO)$/b2xrange.obj \ - $(SLO)$/b2dmultirange.obj \ + $(SLO)$/b2dpolyrange.obj \ + $(SLO)$/b2drangeclipper.obj \ $(SLO)$/b3drange.obj # --- Targets ---------------------------------- diff --git a/basegfx/source/tools/b2dclipstate.cxx b/basegfx/source/tools/b2dclipstate.cxx new file mode 100644 index 000000000000..005dca1aa66a --- /dev/null +++ b/basegfx/source/tools/b2dclipstate.cxx @@ -0,0 +1,662 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: b2dmultirange.cxx,v $ + * $Revision: 1.8 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_basegfx.hxx" +#include <basegfx/tools/b2dclipstate.hxx> + +#include <basegfx/range/b2drange.hxx> +#include <basegfx/range/b2dpolyrange.hxx> +#include <basegfx/range/b2drangeclipper.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/polygon/b2dpolypolygon.hxx> +#include <basegfx/polygon/b2dpolypolygontools.hxx> +#include <basegfx/polygon/b2dpolypolygoncutter.hxx> + +namespace basegfx +{ +namespace tools +{ + struct ImplB2DClipState + { + public: + enum Operation {UNION, INTERSECT, XOR, SUBTRACT}; + + ImplB2DClipState() : + maPendingPolygons(), + maPendingRanges(), + maClipPoly(), + mePendingOps(UNION) + {} + + explicit ImplB2DClipState( const B2DRange& rRange ) : + maPendingPolygons(), + maPendingRanges(), + maClipPoly( + tools::createPolygonFromRect(rRange)), + mePendingOps(UNION) + {} + + explicit ImplB2DClipState( const B2DPolygon& rPoly ) : + maPendingPolygons(), + maPendingRanges(), + maClipPoly(rPoly), + mePendingOps(UNION) + {} + + explicit ImplB2DClipState( const B2DPolyPolygon& rPoly ) : + maPendingPolygons(), + maPendingRanges(), + maClipPoly(rPoly), + mePendingOps(UNION) + {} + + bool isCleared() const + { + return !maClipPoly.count() + && !maPendingPolygons.count() + && !maPendingRanges.count(); + } + + void makeClear() + { + maPendingPolygons.clear(); + maPendingRanges.clear(); + maClipPoly.clear(); + mePendingOps = UNION; + } + + bool isNullClipPoly() const + { + return maClipPoly.count() == 1 + && !maClipPoly.getB2DPolygon(0).count(); + } + + bool isNull() const + { + return !maPendingPolygons.count() + && !maPendingRanges.count() + && isNullClipPoly(); + } + + void makeNull() + { + maPendingPolygons.clear(); + maPendingRanges.clear(); + maClipPoly.clear(); + maClipPoly.append(B2DPolygon()); + mePendingOps = UNION; + } + + bool operator==(const ImplB2DClipState& rRHS) const + { + return maPendingPolygons == rRHS.maPendingPolygons + && maPendingRanges == rRHS.maPendingRanges + && maClipPoly == rRHS.maClipPoly + && mePendingOps == rRHS.mePendingOps; + } + + void addRange(const B2DRange& rRange, Operation eOp) + { + if( rRange.isEmpty() ) + return; + + commitPendingPolygons(); + if( mePendingOps != eOp ) + commitPendingRanges(); + + mePendingOps = eOp; + maPendingRanges.appendElement( + rRange, + ORIENTATION_POSITIVE); + } + + void addPolygon(B2DPolygon aPoly, Operation eOp) + { + commitPendingRanges(); + if( mePendingOps != eOp ) + commitPendingPolygons(); + + mePendingOps = eOp; + maPendingPolygons.append(aPoly); + } + + void addPolyPolygon(B2DPolyPolygon aPoly, Operation eOp) + { + commitPendingRanges(); + if( mePendingOps != eOp ) + commitPendingPolygons(); + + mePendingOps = eOp; + maPendingPolygons.append(aPoly); + } + + void addClipState(const ImplB2DClipState& rOther, Operation eOp) + { + if( rOther.mePendingOps == mePendingOps + && !rOther.maClipPoly.count() + && !rOther.maPendingPolygons.count() ) + { + maPendingRanges.appendPolyRange( rOther.maPendingRanges ); + } + else + { + commitPendingRanges(); + commitPendingPolygons(); + rOther.commitPendingRanges(); + rOther.commitPendingPolygons(); + + maPendingPolygons = rOther.maClipPoly; + mePendingOps = eOp; + } + } + + void unionRange(const B2DRange& rRange) + { + if( isCleared() ) + return; + + addRange(rRange,UNION); + } + + void unionPolygon(const B2DPolygon& rPoly) + { + if( isCleared() ) + return; + + addPolygon(rPoly,UNION); + } + + void unionPolyPolygon(const B2DPolyPolygon& rPolyPoly) + { + if( isCleared() ) + return; + + addPolyPolygon(rPolyPoly,UNION); + } + + void unionClipState(const ImplB2DClipState& rOther) + { + if( isCleared() ) + return; + + addClipState(rOther, UNION); + } + + void intersectRange(const B2DRange& rRange) + { + if( isNull() ) + return; + + addRange(rRange,INTERSECT); + } + + void intersectPolygon(const B2DPolygon& rPoly) + { + if( isNull() ) + return; + + addPolygon(rPoly,INTERSECT); + } + + void intersectPolyPolygon(const B2DPolyPolygon& rPolyPoly) + { + if( isNull() ) + return; + + addPolyPolygon(rPolyPoly,INTERSECT); + } + + void intersectClipState(const ImplB2DClipState& rOther) + { + if( isNull() ) + return; + + addClipState(rOther, INTERSECT); + } + + void subtractRange(const B2DRange& rRange ) + { + if( isNull() ) + return; + + addRange(rRange,SUBTRACT); + } + + void subtractPolygon(const B2DPolygon& rPoly) + { + if( isNull() ) + return; + + addPolygon(rPoly,SUBTRACT); + } + + void subtractPolyPolygon(const B2DPolyPolygon& rPolyPoly) + { + if( isNull() ) + return; + + addPolyPolygon(rPolyPoly,SUBTRACT); + } + + void subtractClipState(const ImplB2DClipState& rOther) + { + if( isNull() ) + return; + + addClipState(rOther, SUBTRACT); + } + + void xorRange(const B2DRange& rRange) + { + addRange(rRange,XOR); + } + + void xorPolygon(const B2DPolygon& rPoly) + { + addPolygon(rPoly,XOR); + } + + void xorPolyPolygon(const B2DPolyPolygon& rPolyPoly) + { + addPolyPolygon(rPolyPoly,XOR); + } + + void xorClipState(const ImplB2DClipState& rOther) + { + addClipState(rOther, XOR); + } + + B2DPolyPolygon getClipPoly() const + { + commitPendingRanges(); + commitPendingPolygons(); + + return maClipPoly; + } + + private: + void commitPendingPolygons() const + { + if( !maPendingPolygons.count() ) + return; + + // assumption: maClipPoly has kept polygons prepared for + // clipping; i.e. no neutral polygons & correct + // orientation + maPendingPolygons = tools::prepareForPolygonOperation(maPendingPolygons); + const bool bIsEmpty=isNullClipPoly(); + const bool bIsCleared=!maClipPoly.count(); + switch(mePendingOps) + { + case UNION: + OSL_ASSERT( !bIsCleared ); + + if( bIsEmpty ) + maClipPoly = maPendingPolygons; + else + maClipPoly = tools::solvePolygonOperationOr( + maClipPoly, + maPendingPolygons); + break; + case INTERSECT: + OSL_ASSERT( !bIsEmpty ); + + if( bIsCleared ) + maClipPoly = maPendingPolygons; + else + maClipPoly = tools::solvePolygonOperationAnd( + maClipPoly, + maPendingPolygons); + break; + case XOR: + if( bIsEmpty ) + maClipPoly = maPendingPolygons; + else if( bIsCleared ) + { + // not representable, strictly speaking, + // using polygons with the common even/odd + // or nonzero winding number fill rule. If + // we'd want to represent it, fill rule + // would need to be "non-negative winding + // number" (and we then would return + // 'holes' here) + + // going for an ugly hack meanwhile + maClipPoly = tools::solvePolygonOperationXor( + B2DPolyPolygon( + tools::createPolygonFromRect(B2DRange(-1E20,-1E20,1E20,1E20))), + maPendingPolygons); + } + else + maClipPoly = tools::solvePolygonOperationXor( + maClipPoly, + maPendingPolygons); + break; + case SUBTRACT: + OSL_ASSERT( !bIsEmpty ); + + // first union all pending ones, subtract en bloc then + maPendingPolygons = solveCrossovers(maPendingPolygons); + maPendingPolygons = stripNeutralPolygons(maPendingPolygons); + maPendingPolygons = stripDispensablePolygons(maPendingPolygons, false); + + if( bIsCleared ) + { + // not representable, strictly speaking, + // using polygons with the common even/odd + // or nonzero winding number fill rule. If + // we'd want to represent it, fill rule + // would need to be "non-negative winding + // number" (and we then would return + // 'holes' here) + + // going for an ugly hack meanwhile + maClipPoly = tools::solvePolygonOperationDiff( + B2DPolyPolygon( + tools::createPolygonFromRect(B2DRange(-1E20,-1E20,1E20,1E20))), + maPendingPolygons); + } + else + maClipPoly = tools::solvePolygonOperationDiff( + maClipPoly, + maPendingPolygons); + break; + } + + maPendingPolygons.clear(); + mePendingOps = UNION; + } + + void commitPendingRanges() const + { + if( !maPendingRanges.count() ) + return; + + // use the specialized range clipper for the win + B2DPolyPolygon aCollectedRanges; + const bool bIsEmpty=isNullClipPoly(); + const bool bIsCleared=!maClipPoly.count(); + switch(mePendingOps) + { + case UNION: + OSL_ASSERT( !bIsCleared ); + + aCollectedRanges = maPendingRanges.solveCrossovers(); + aCollectedRanges = stripNeutralPolygons(aCollectedRanges); + aCollectedRanges = stripDispensablePolygons(aCollectedRanges, false); + if( bIsEmpty ) + maClipPoly = aCollectedRanges; + else + maClipPoly = tools::solvePolygonOperationOr( + maClipPoly, + aCollectedRanges); + break; + case INTERSECT: + OSL_ASSERT( !bIsEmpty ); + + aCollectedRanges = maPendingRanges.solveCrossovers(); + aCollectedRanges = stripNeutralPolygons(aCollectedRanges); + if( maPendingRanges.count() > 1 ) + aCollectedRanges = stripDispensablePolygons(aCollectedRanges, true); + + if( bIsCleared ) + maClipPoly = aCollectedRanges; + else + maClipPoly = tools::solvePolygonOperationAnd( + maClipPoly, + aCollectedRanges); + break; + case XOR: + aCollectedRanges = maPendingRanges.solveCrossovers(); + aCollectedRanges = stripNeutralPolygons(aCollectedRanges); + aCollectedRanges = correctOrientations(aCollectedRanges); + + if( bIsEmpty ) + maClipPoly = aCollectedRanges; + else if( bIsCleared ) + { + // not representable, strictly speaking, + // using polygons with the common even/odd + // or nonzero winding number fill rule. If + // we'd want to represent it, fill rule + // would need to be "non-negative winding + // number" (and we then would return + // 'holes' here) + + // going for an ugly hack meanwhile + maClipPoly = tools::solvePolygonOperationXor( + B2DPolyPolygon( + tools::createPolygonFromRect(B2DRange(-1E20,-1E20,1E20,1E20))), + aCollectedRanges); + } + else + maClipPoly = tools::solvePolygonOperationXor( + maClipPoly, + aCollectedRanges); + break; + case SUBTRACT: + OSL_ASSERT( !bIsEmpty ); + + // first union all pending ranges, subtract en bloc then + aCollectedRanges = maPendingRanges.solveCrossovers(); + aCollectedRanges = stripNeutralPolygons(aCollectedRanges); + aCollectedRanges = stripDispensablePolygons(aCollectedRanges, false); + + if( bIsCleared ) + { + // not representable, strictly speaking, + // using polygons with the common even/odd + // or nonzero winding number fill rule. If + // we'd want to represent it, fill rule + // would need to be "non-negative winding + // number" (and we then would return + // 'holes' here) + + // going for an ugly hack meanwhile + maClipPoly = tools::solvePolygonOperationDiff( + B2DPolyPolygon( + tools::createPolygonFromRect(B2DRange(-1E20,-1E20,1E20,1E20))), + aCollectedRanges); + } + else + maClipPoly = tools::solvePolygonOperationDiff( + maClipPoly, + aCollectedRanges); + break; + } + + maPendingRanges.clear(); + mePendingOps = UNION; + } + + mutable B2DPolyPolygon maPendingPolygons; + mutable B2DPolyRange maPendingRanges; + mutable B2DPolyPolygon maClipPoly; + mutable Operation mePendingOps; + }; + + B2DClipState::B2DClipState() : + mpImpl() + {} + + B2DClipState::~B2DClipState() + {} + + B2DClipState::B2DClipState( const B2DClipState& rOrig ) : + mpImpl(rOrig.mpImpl) + {} + + B2DClipState::B2DClipState( const B2DRange& rRange ) : + mpImpl( ImplB2DClipState(rRange) ) + {} + + B2DClipState::B2DClipState( const B2DPolygon& rPoly ) : + mpImpl( ImplB2DClipState(rPoly) ) + {} + + B2DClipState::B2DClipState( const B2DPolyPolygon& rPolyPoly ) : + mpImpl( ImplB2DClipState(rPolyPoly) ) + {} + + B2DClipState& B2DClipState::operator=( const B2DClipState& rRHS ) + { + mpImpl = rRHS.mpImpl; + return *this; + } + + void B2DClipState::makeUnique() + { + mpImpl.make_unique(); + } + + void B2DClipState::makeNull() + { + mpImpl->makeNull(); + } + + bool B2DClipState::isNull() const + { + return mpImpl->isNull(); + } + + void B2DClipState::makeClear() + { + mpImpl->makeClear(); + } + + bool B2DClipState::isCleared() const + { + return mpImpl->isCleared(); + } + + bool B2DClipState::operator==(const B2DClipState& rRHS) const + { + if(mpImpl.same_object(rRHS.mpImpl)) + return true; + + return ((*mpImpl) == (*rRHS.mpImpl)); + } + + bool B2DClipState::operator!=(const B2DClipState& rRHS) const + { + return !(*this == rRHS); + } + + void B2DClipState::unionRange(const B2DRange& rRange) + { + mpImpl->unionRange(rRange); + } + + void B2DClipState::unionPolygon(const B2DPolygon& rPoly) + { + mpImpl->unionPolygon(rPoly); + } + + void B2DClipState::unionPolyPolygon(const B2DPolyPolygon& rPolyPoly) + { + mpImpl->unionPolyPolygon(rPolyPoly); + } + + void B2DClipState::unionClipState(const B2DClipState& rState) + { + mpImpl->unionClipState(*rState.mpImpl); + } + + void B2DClipState::intersectRange(const B2DRange& rRange) + { + mpImpl->intersectRange(rRange); + } + + void B2DClipState::intersectPolygon(const B2DPolygon& rPoly) + { + mpImpl->intersectPolygon(rPoly); + } + + void B2DClipState::intersectPolyPolygon(const B2DPolyPolygon& rPolyPoly) + { + mpImpl->intersectPolyPolygon(rPolyPoly); + } + + void B2DClipState::intersectClipState(const B2DClipState& rState) + { + mpImpl->intersectClipState(*rState.mpImpl); + } + + void B2DClipState::subtractRange(const B2DRange& rRange) + { + mpImpl->subtractRange(rRange); + } + + void B2DClipState::subtractPolygon(const B2DPolygon& rPoly) + { + mpImpl->subtractPolygon(rPoly); + } + + void B2DClipState::subtractPolyPolygon(const B2DPolyPolygon& rPolyPoly) + { + mpImpl->subtractPolyPolygon(rPolyPoly); + } + + void B2DClipState::subtractClipState(const B2DClipState& rState) + { + mpImpl->subtractClipState(*rState.mpImpl); + } + + void B2DClipState::xorRange(const B2DRange& rRange) + { + mpImpl->xorRange(rRange); + } + + void B2DClipState::xorPolygon(const B2DPolygon& rPoly) + { + mpImpl->xorPolygon(rPoly); + } + + void B2DClipState::xorPolyPolygon(const B2DPolyPolygon& rPolyPoly) + { + mpImpl->xorPolyPolygon(rPolyPoly); + } + + void B2DClipState::xorClipState(const B2DClipState& rState) + { + mpImpl->xorClipState(*rState.mpImpl); + } + + B2DPolyPolygon B2DClipState::getClipPoly() const + { + return mpImpl->getClipPoly(); + } + +} // end of namespace tools +} // end of namespace basegfx + +// eof diff --git a/basegfx/source/tools/gradienttools.cxx b/basegfx/source/tools/gradienttools.cxx index 89293cfcb61c..857b668da68e 100644 --- a/basegfx/source/tools/gradienttools.cxx +++ b/basegfx/source/tools/gradienttools.cxx @@ -49,6 +49,8 @@ namespace basegfx o_rGradientInfo.maBackTextureTransform.identity(); o_rGradientInfo.mnSteps = nSteps; + fAngle = -fAngle; + double fTargetSizeX(rTargetRange.getWidth()); double fTargetSizeY(rTargetRange.getHeight()); double fTargetOffsetX(rTargetRange.getMinX()); @@ -67,17 +69,30 @@ namespace basegfx fTargetSizeY = fNewY; } - // add object scale before rotate + const double fSizeWithoutBorder=1.0 - fBorder; + if( bAxial ) + { + o_rGradientInfo.maTextureTransform.scale(1.0, fSizeWithoutBorder * .5); + o_rGradientInfo.maTextureTransform.translate(0.0, 0.5); + } + else + { + if(!fTools::equal(fSizeWithoutBorder, 1.0)) + { + o_rGradientInfo.maTextureTransform.scale(1.0, fSizeWithoutBorder); + o_rGradientInfo.maTextureTransform.translate(0.0, fBorder); + } + } + o_rGradientInfo.maTextureTransform.scale(fTargetSizeX, fTargetSizeY); // add texture rotate after scale to keep perpendicular angles if(0.0 != fAngle) { - B2DPoint aCenter(0.5, 0.5); - aCenter *= o_rGradientInfo.maTextureTransform; - - o_rGradientInfo.maTextureTransform = basegfx::tools::createRotateAroundPoint(aCenter, fAngle) - * o_rGradientInfo.maTextureTransform; + const B2DPoint aCenter(0.5*fTargetSizeX, + 0.5*fTargetSizeY); + o_rGradientInfo.maTextureTransform *= + basegfx::tools::createRotateAroundPoint(aCenter, fAngle); } // add object translate @@ -86,24 +101,9 @@ namespace basegfx // prepare aspect for texture o_rGradientInfo.mfAspectRatio = (0.0 != fTargetSizeY) ? fTargetSizeX / fTargetSizeY : 1.0; - // build transform from u,v to [0.0 .. 1.0]. As base, use inverse texture transform + // build transform from u,v to [0.0 .. 1.0]. o_rGradientInfo.maBackTextureTransform = o_rGradientInfo.maTextureTransform; o_rGradientInfo.maBackTextureTransform.invert(); - - double fSizeWithoutBorder=0; - if( bAxial ) - { - fSizeWithoutBorder = (1.0 - fBorder) * 0.5; - o_rGradientInfo.maBackTextureTransform.translate(0.0, -0.5); - } - else - { - fSizeWithoutBorder = 1.0 - fBorder; - o_rGradientInfo.maBackTextureTransform.translate(0.0, -fBorder); - } - - if(!fTools::equal(fSizeWithoutBorder, 0.0)) - o_rGradientInfo.maBackTextureTransform.scale(1.0, 1.0 / fSizeWithoutBorder); } /** Most of the setup for radial & ellipsoidal gradient is the same, @@ -121,6 +121,8 @@ namespace basegfx o_rGradientInfo.maBackTextureTransform.identity(); o_rGradientInfo.mnSteps = nSteps; + fAngle = -fAngle; + double fTargetSizeX(rTargetRange.getWidth()); double fTargetSizeY(rTargetRange.getHeight()); double fTargetOffsetX(rTargetRange.getMinX()); @@ -143,20 +145,19 @@ namespace basegfx fTargetSizeY = 1.4142 * fTargetSizeY; } - // add object scale before rotate + const double fHalfBorder((1.0 - fBorder) * 0.5); + o_rGradientInfo.maTextureTransform.scale(fHalfBorder, fHalfBorder); + + o_rGradientInfo.maTextureTransform.translate(0.5, 0.5); o_rGradientInfo.maTextureTransform.scale(fTargetSizeX, fTargetSizeY); - if( !bCircular ) + // add texture rotate after scale to keep perpendicular angles + if( !bCircular && 0.0 != fAngle) { - // add texture rotate after scale to keep perpendicular angles - if(0.0 != fAngle) - { - B2DPoint aCenter(0.5, 0.5); - aCenter *= o_rGradientInfo.maTextureTransform; - - o_rGradientInfo.maTextureTransform = basegfx::tools::createRotateAroundPoint(aCenter, fAngle) - * o_rGradientInfo.maTextureTransform; - } + const B2DPoint aCenter(0.5*fTargetSizeX, + 0.5*fTargetSizeY); + o_rGradientInfo.maTextureTransform *= + basegfx::tools::createRotateAroundPoint(aCenter, fAngle); } // add defined offsets after rotation @@ -173,17 +174,9 @@ namespace basegfx // prepare aspect for texture o_rGradientInfo.mfAspectRatio = (0.0 != fTargetSizeY) ? fTargetSizeX / fTargetSizeY : 1.0; - // build transform from u,v to [0.0 .. 1.0]. As base, use inverse texture transform + // build transform from u,v to [0.0 .. 1.0]. o_rGradientInfo.maBackTextureTransform = o_rGradientInfo.maTextureTransform; o_rGradientInfo.maBackTextureTransform.invert(); - o_rGradientInfo.maBackTextureTransform.translate(-0.5, -0.5); - const double fHalfBorder((1.0 - fBorder) * 0.5); - - if(!fTools::equal(fHalfBorder, 0.0)) - { - const double fFactor(1.0 / fHalfBorder); - o_rGradientInfo.maBackTextureTransform.scale(fFactor, fFactor); - } } /** Setup for rect & square gradient is exactly the same. Factored out @@ -200,6 +193,8 @@ namespace basegfx o_rGradientInfo.maBackTextureTransform.identity(); o_rGradientInfo.mnSteps = nSteps; + fAngle = -fAngle; + double fTargetSizeX(rTargetRange.getWidth()); double fTargetSizeY(rTargetRange.getHeight()); double fTargetOffsetX(rTargetRange.getMinX()); @@ -218,17 +213,19 @@ namespace basegfx fTargetSizeY = fNewY; } - // add object scale before rotate + const double fHalfBorder((1.0 - fBorder) * 0.5); + o_rGradientInfo.maTextureTransform.scale(fHalfBorder, fHalfBorder); + + o_rGradientInfo.maTextureTransform.translate(0.5, 0.5); o_rGradientInfo.maTextureTransform.scale(fTargetSizeX, fTargetSizeY); // add texture rotate after scale to keep perpendicular angles if(0.0 != fAngle) { - B2DPoint aCenter(0.5, 0.5); - aCenter *= o_rGradientInfo.maTextureTransform; - - o_rGradientInfo.maTextureTransform = basegfx::tools::createRotateAroundPoint(aCenter, fAngle) - * o_rGradientInfo.maTextureTransform; + const B2DPoint aCenter(0.5*fTargetSizeX, + 0.5*fTargetSizeY); + o_rGradientInfo.maTextureTransform *= + basegfx::tools::createRotateAroundPoint(aCenter, fAngle); } // add defined offsets after rotation @@ -248,14 +245,6 @@ namespace basegfx // build transform from u,v to [0.0 .. 1.0]. As base, use inverse texture transform o_rGradientInfo.maBackTextureTransform = o_rGradientInfo.maTextureTransform; o_rGradientInfo.maBackTextureTransform.invert(); - o_rGradientInfo.maBackTextureTransform.translate(-0.5, -0.5); - const double fHalfBorder((1.0 - fBorder) * 0.5); - - if(!fTools::equal(fHalfBorder, 0.0)) - { - const double fFactor(1.0 / fHalfBorder); - o_rGradientInfo.maBackTextureTransform.scale(fFactor, fFactor); - } } namespace tools diff --git a/basegfx/source/tools/keystoplerp.cxx b/basegfx/source/tools/keystoplerp.cxx new file mode 100644 index 000000000000..883bfec6bc96 --- /dev/null +++ b/basegfx/source/tools/keystoplerp.cxx @@ -0,0 +1,107 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: canvastools.hxx,v $ + * $Revision: 1.10 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_basegfx.hxx" + +#include "basegfx/tools/keystoplerp.hxx" +#include <com/sun/star/uno/Sequence.hxx> + +#include <algorithm> + +static void validateInput(const std::vector<double>& rKeyStops) +{ + (void)rKeyStops; +#ifdef DBG_UTIL + OSL_ENSURE( rKeyStops.size() > 1, + "KeyStopLerp::KeyStopLerp(): key stop vector must have two entries or more" ); + + // rKeyStops must be sorted in ascending order + for( ::std::size_t i=1, len=rKeyStops.size(); i<len; ++i ) + { + if( rKeyStops[i-1] > rKeyStops[i] ) + OSL_ENSURE( false, + "KeyStopLerp::KeyStopLerp(): time vector is not sorted in ascending order!" ); + } +#endif +} + +namespace basegfx +{ + namespace tools + { + KeyStopLerp::KeyStopLerp( const std::vector<double>& rKeyStops ) : + maKeyStops(rKeyStops), + mnLastIndex(0) + { + validateInput(maKeyStops); + } + + KeyStopLerp::KeyStopLerp( const ::com::sun::star::uno::Sequence<double>& rKeyStops ) : + maKeyStops(rKeyStops.getLength()), + mnLastIndex(0) + { + std::copy( rKeyStops.getConstArray(), + rKeyStops.getConstArray()+rKeyStops.getLength(), + maKeyStops.begin() ); + validateInput(maKeyStops); + } + + KeyStopLerp::ResultType KeyStopLerp::lerp(double fAlpha) const + { + // cached value still okay? + if( maKeyStops.at(mnLastIndex) < fAlpha || + maKeyStops.at(mnLastIndex+1) >= fAlpha ) + { + // nope, find new index + mnLastIndex = std::min<std::ptrdiff_t>( + maKeyStops.size()-2, + // range is ensured by max below + std::max<std::ptrdiff_t>( + 0, + std::distance( maKeyStops.begin(), + std::lower_bound( maKeyStops.begin(), + maKeyStops.end(), + fAlpha )) - 1 )); + } + + // lerp between stop and stop+1 + const double fRawLerp= + (fAlpha-maKeyStops.at(mnLastIndex)) / + (maKeyStops.at(mnLastIndex+1) - maKeyStops.at(mnLastIndex)); + + // clamp to permissible range (input fAlpha might be + // everything) + return ResultType( + mnLastIndex, + clamp(fRawLerp,0.0,1.0)); + } + } +} diff --git a/basegfx/source/tools/makefile.mk b/basegfx/source/tools/makefile.mk index c70b78be5d4b..0a0977f7305d 100755 --- a/basegfx/source/tools/makefile.mk +++ b/basegfx/source/tools/makefile.mk @@ -37,9 +37,11 @@ ENABLE_EXCEPTIONS=TRUE # --- Files ------------------------------------- -SLOFILES= $(SLO)$/canvastools.obj \ +SLOFILES= $(SLO)$/b2dclipstate.obj \ + $(SLO)$/canvastools.obj \ $(SLO)$/gradienttools.obj \ $(SLO)$/debugplotter.obj \ + $(SLO)$/keystoplerp.obj \ $(SLO)$/liangbarsky.obj \ $(SLO)$/tools.obj \ $(SLO)$/unopolypolygon.obj diff --git a/basegfx/test/basegfx1d.cxx b/basegfx/test/basegfx1d.cxx index 5cc823d3daca..41ac65da56e3 100644 --- a/basegfx/test/basegfx1d.cxx +++ b/basegfx/test/basegfx1d.cxx @@ -30,7 +30,10 @@ #include "precompiled_basegfx.hxx" // autogenerated file with codegen.pl -#include <testshl/simpleheader.hxx> +#include "cppunit/TestAssert.h" +#include "cppunit/TestFixture.h" +#include "cppunit/extensions/HelperMacros.h" +#include "cppunit/plugin/TestPlugIn.h" namespace basegfx1d { @@ -52,7 +55,6 @@ public: void EmptyMethod() { // CPPUNIT_ASSERT_MESSAGE("a message", 1 == 1); - CPPUNIT_ASSERT_STUB(); } // Change the following lines only, if you add, remove or rename @@ -65,13 +67,7 @@ public: }; // class b1drange // ----------------------------------------------------------------------------- -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(basegfx1d::b1drange, "basegfx1d"); +CPPUNIT_TEST_SUITE_REGISTRATION(basegfx1d::b1drange); } // namespace basegfx1d - -// ----------------------------------------------------------------------------- - -// this macro creates an empty function, which will called by the RegisterAllFunctions() -// to let the user the possibility to also register some functions by hand. -NOADDITIONAL; - +CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/basegfx/test/basegfx2d.cxx b/basegfx/test/basegfx2d.cxx index b169d35ed96a..31005a158982 100644 --- a/basegfx/test/basegfx2d.cxx +++ b/basegfx/test/basegfx2d.cxx @@ -30,7 +30,9 @@ #include "precompiled_basegfx.hxx" // autogenerated file with codegen.pl -#include <testshl/simpleheader.hxx> +#include "cppunit/TestAssert.h" +#include "cppunit/TestFixture.h" +#include "cppunit/extensions/HelperMacros.h" #include <basegfx/matrix/b2dhommatrix.hxx> #include <basegfx/polygon/b2dpolygon.hxx> @@ -38,7 +40,9 @@ #include <basegfx/curve/b2dcubicbezier.hxx> #include <basegfx/curve/b2dbeziertools.hxx> #include <basegfx/polygon/b2dpolypolygontools.hxx> -#include <basegfx/range/b2dmultirange.hxx> +#include <basegfx/polygon/b2dpolygonclipper.hxx> +#include <basegfx/polygon/b2dpolypolygon.hxx> +#include <basegfx/range/b2dpolyrange.hxx> #include <basegfx/numeric/ftools.hxx> #include <basegfx/color/bcolor.hxx> #include <basegfx/color/bcolortools.hxx> @@ -53,214 +57,6 @@ using namespace ::basegfx; namespace basegfx2d { -/// Gets a random ordinal [0,n) -inline double getRandomOrdinal( const ::std::size_t n ) -{ - return double(n) * rand() / (RAND_MAX + 1.0); -} - -class b2dmultirange : public CppUnit::TestFixture -{ -private: - B2DMultiRange aDisjunctRanges; - B2DMultiRange aEqualRanges; - B2DMultiRange aIntersectionN; - B2DMultiRange aIntersectionE; - B2DMultiRange aIntersectionS; - B2DMultiRange aIntersectionW; - B2DMultiRange aIntersectionNE; - B2DMultiRange aIntersectionSE; - B2DMultiRange aIntersectionSW; - B2DMultiRange aIntersectionNW; - B2DMultiRange aRingIntersection; - B2DMultiRange aComplexIntersections; - B2DMultiRange aRandomIntersections; - -public: - // initialise your test code values here. - void setUp() - { - B2DRange aCenter(1.0, 1.0, -1.0, -1.0); - B2DRange aOffside(9.0, 9.0, 11.0, 11.0); - B2DRange aNorth(1.0, 0.0, -1.0, -2.0); - B2DRange aSouth(1.0, 2.0, -1.0, 0.0); - B2DRange aEast(0.0, 1.0, 2.0, -1.0); - B2DRange aWest(-2.0, 1.0, 0.0, -1.0); - B2DRange aNorthEast(0.0, 0.0, 2.0, -2.0); - B2DRange aSouthEast(0.0, 0.0, 2.0, 2.0); - B2DRange aSouthWest(0.0, 0.0, -2.0, 2.0); - B2DRange aNorthWest(0.0, 0.0, -2.0, -2.0); - - B2DRange aNorth2(-1.5, 0.5, 1.5, 3.5); - B2DRange aSouth2(-1.5, -0.5, 1.5, -3.5); - B2DRange aEast2 (0.5, -1.5, 3.5, 1.5); - B2DRange aWest2 (-0.5, -1.5,-3.5, 1.5); - - ::std::ofstream output("multirange_testcases.gnuplot"); - DebugPlotter aPlotter( "multirange testcases", - output ); - - aPlotter.plot( aCenter, "center" ); - aPlotter.plot( aOffside, "offside" ); - aPlotter.plot( aNorth, "north" ); - aPlotter.plot( aSouth, "south" ); - aPlotter.plot( aEast, "east" ); - aPlotter.plot( aWest, "west" ); - aPlotter.plot( aNorthEast, "northeast" ); - aPlotter.plot( aSouthEast, "southeast" ); - aPlotter.plot( aSouthWest, "southwest" ); - aPlotter.plot( aNorthWest, "northwest" ); - - aDisjunctRanges.addRange( aCenter ); - aDisjunctRanges.addRange( aOffside ); - - aEqualRanges.addRange( aCenter ); - aEqualRanges.addRange( aCenter ); - - aIntersectionN.addRange( aCenter ); - aIntersectionN.addRange( aNorth ); - - aIntersectionE.addRange( aCenter ); - aIntersectionE.addRange( aEast ); - - aIntersectionS.addRange( aCenter ); - aIntersectionS.addRange( aSouth ); - - aIntersectionW.addRange( aCenter ); - aIntersectionW.addRange( aWest ); - - aIntersectionNE.addRange( aCenter ); - aIntersectionNE.addRange( aNorthEast ); - - aIntersectionSE.addRange( aCenter ); - aIntersectionSE.addRange( aSouthEast ); - - aIntersectionSW.addRange( aCenter ); - aIntersectionSW.addRange( aSouthWest ); - - aIntersectionNW.addRange( aCenter ); - aIntersectionNW.addRange( aNorthWest ); - - aRingIntersection.addRange( aNorth2 ); - aRingIntersection.addRange( aEast2 ); - aRingIntersection.addRange( aSouth2 ); - aRingIntersection.addRange( aWest2 ); - - aComplexIntersections.addRange( aCenter ); - aComplexIntersections.addRange( aOffside ); - aComplexIntersections.addRange( aCenter ); - aComplexIntersections.addRange( aNorth ); - aComplexIntersections.addRange( aEast ); - aComplexIntersections.addRange( aSouth ); - aComplexIntersections.addRange( aWest ); - aComplexIntersections.addRange( aNorthEast ); - aComplexIntersections.addRange( aSouthEast ); - aComplexIntersections.addRange( aSouthWest ); - aComplexIntersections.addRange( aNorthWest ); - -/* - for( int i=0; i<10; ++i ) - { - B2DRange aRandomRange( - getRandomOrdinal( 10 ), - getRandomOrdinal( 10 ), - getRandomOrdinal( 10 ), - getRandomOrdinal( 10 ) ); - - aRandomIntersections.addRange( aRandomRange ); - } -*/ - } - - void tearDown() - { - } - - ::basegfx::B2DPolyPolygon shiftPoly( int nCount, - const ::basegfx::B2DPolyPolygon& rPoly ) - { - B2DHomMatrix aMatrix; - aMatrix.translate( nCount*4.0, - 10.0-nCount*2.0 ); - - ::basegfx::B2DPolyPolygon aRes( rPoly ); - aRes.transform( aMatrix ); - - return aRes; - } - - void getPolyPolygon() - { - ::std::ofstream output("multirange_getpolypolygon.gnuplot"); - DebugPlotter aPlotter( "multirange getPolyPolygon", - output ); - - B2DPolyPolygon result; - - aPlotter.plot( shiftPoly( - 0, - aDisjunctRanges.getPolyPolygon() ), - "disjunct" ); - aPlotter.plot( shiftPoly( - 1, - aEqualRanges.getPolyPolygon() ), - "equal" ); - aPlotter.plot( shiftPoly( - 2, - aIntersectionN.getPolyPolygon() ), - "intersectionN" ); - aPlotter.plot( shiftPoly( - 3, - aIntersectionE.getPolyPolygon() ), - "intersectionE" ); - aPlotter.plot( shiftPoly( - 4, - aIntersectionS.getPolyPolygon() ), - "intersectionS" ); - aPlotter.plot( shiftPoly( - 5, - aIntersectionW.getPolyPolygon() ), - "intersectionW" ); - aPlotter.plot( shiftPoly( - 6, - aIntersectionNE.getPolyPolygon() ), - "intersectionNE" ); - aPlotter.plot( shiftPoly( - 7, - aIntersectionSE.getPolyPolygon() ), - "intersectionSE" ); - aPlotter.plot( shiftPoly( - 8, - aIntersectionSW.getPolyPolygon() ), - "intersectionSW" ); - aPlotter.plot( shiftPoly( - 9, - aIntersectionNW.getPolyPolygon() ), - "intersectionNW" ); - aPlotter.plot( shiftPoly( - 10, - aRingIntersection.getPolyPolygon() ), - "intersection ring" ); - aPlotter.plot( shiftPoly( - 11, - aComplexIntersections.getPolyPolygon() ), - "intersection complex" ); - aPlotter.plot( shiftPoly( - 12, - aRandomIntersections.getPolyPolygon() ), - "intersection random" ); - - CPPUNIT_ASSERT_MESSAGE("getPolyPolygon", true ); - } - - // Change the following lines only, if you add, remove or rename - // member functions of the current class, - // because these macros are need by auto register mechanism. - - CPPUNIT_TEST_SUITE(b2dmultirange); - CPPUNIT_TEST(getPolyPolygon); - CPPUNIT_TEST_SUITE_END(); -}; // class b2dmultirange class b2dsvgdimpex : public CppUnit::TestFixture { @@ -465,33 +261,6 @@ public: CPPUNIT_ASSERT_MESSAGE("exporting complex polygon to SVG-D (round-trip)", !aExport.compareToAscii(sExportString2)); - const B2DPolygon aCircle( - tools::createPolygonFromEllipse( B2DPoint(4000,4000), - 1000.0, 2000.0 )); - aExport = tools::exportToSvgD( B2DPolyPolygon(aCircle), false, false); - - // count number of spaces, in lieu of a better way - no real - // point in comparing with a gold standard, as fractional - // parts of the coordinates will differ between systems. - sal_Int32 nIndex=0, nCount=0; - do - { - rtl::OUString aToken = aExport.getToken( 0, ' ', nIndex ); - ++nCount; - } - while ( nIndex >= 0 ); - - // Adapted number of spaces to 50 and 67 because of the new circle construction - // methods which produce more points and thus more spaces, too. Use both since - // depending on float precision and the getContinuity() implemetation using - // fTools::equal, linux and mac produce more 'C' than 'S' statements, while WIN32 - // uses more 'S' statements (as it should be for circles) -#ifdef S390X - CPPUNIT_ASSERT_MESSAGE("exporting to circle does not produce the expected number of coordinates", nCount==61 ); -#else - CPPUNIT_ASSERT_MESSAGE("exporting to circle does not produce the expected number of coordinates", nCount==67 || nCount==50 ); -#endif - const B2DPolygon aRect( tools::createPolygonFromRect( B2DRange(0.0,0.0,4000.0,4000.0) )); aExport = tools::exportToSvgD( B2DPolyPolygon(aRect), false, false); @@ -510,6 +279,45 @@ public: CPPUNIT_TEST_SUITE_END(); }; // class b2dsvgdimpex +class b2dpolyrange : public CppUnit::TestFixture +{ +private: +public: + void setUp() + {} + + void tearDown() + {} + + void check() + { + B2DPolyRange aRange; + aRange.appendElement(B2DRange(0,0,1,1),ORIENTATION_POSITIVE); + aRange.appendElement(B2DRange(2,2,3,3),ORIENTATION_POSITIVE); + + CPPUNIT_ASSERT_MESSAGE("simple poly range - count", + aRange.count() == 2); + CPPUNIT_ASSERT_MESSAGE("simple poly range - first element", + aRange.getElement(0).head == B2DRange(0,0,1,1)); + CPPUNIT_ASSERT_MESSAGE("simple poly range - second element", + aRange.getElement(1).head == B2DRange(2,2,3,3)); + + // B2DPolyRange relies on correctly orientated rects + const B2DRange aRect(0,0,1,1); + CPPUNIT_ASSERT_MESSAGE("createPolygonFromRect - correct orientation", + tools::getOrientation( + tools::createPolygonFromRect(aRect)) == ORIENTATION_POSITIVE ); + } + + // Change the following lines only, if you add, remove or rename + // member functions of the current class, + // because these macros are need by auto register mechanism. + + CPPUNIT_TEST_SUITE(b2dpolyrange); + CPPUNIT_TEST(check); + CPPUNIT_TEST_SUITE_END(); +}; + class b2dbeziertools : public CppUnit::TestFixture { private: @@ -758,7 +566,6 @@ public: { // this is demonstration code // CPPUNIT_ASSERT_MESSAGE("a message", 1 == 1); - CPPUNIT_ASSERT_STUB(); } // Change the following lines only, if you add, remove or rename @@ -1110,7 +917,6 @@ public: // insert your test code here. void EmptyMethod() { - CPPUNIT_ASSERT_STUB(); } // Change the following lines only, if you add, remove or rename @@ -1140,7 +946,6 @@ public: void EmptyMethod() { // CPPUNIT_ASSERT_MESSAGE("a message", 1 == 1); - CPPUNIT_ASSERT_STUB(); } // Change the following lines only, if you add, remove or rename @@ -1283,6 +1088,14 @@ public: aNonRect4.append( B2DPoint(1,1) ); aNonRect4.append( B2DPoint(0,1) ); + B2DPolygon aNonRect5; + aNonRect5.append( B2DPoint(0,0) ); + aNonRect5.append( B2DPoint(1,0) ); + aNonRect5.append( B2DPoint(1,1) ); + aNonRect5.append( B2DPoint(0,1) ); + aNonRect5.setControlPoints(1,B2DPoint(1,0),B2DPoint(-11,0)); + aNonRect5.setClosed(true); + CPPUNIT_ASSERT_MESSAGE("checking rectangle-ness of rectangle 1", tools::isRectangle( aRect1 )); CPPUNIT_ASSERT_MESSAGE("checking rectangle-ness of rectangle 2", @@ -1295,6 +1108,8 @@ public: !tools::isRectangle( aNonRect3 )); CPPUNIT_ASSERT_MESSAGE("checking non-rectangle-ness of polygon 4", !tools::isRectangle( aNonRect4 )); + CPPUNIT_ASSERT_MESSAGE("checking non-rectangle-ness of polygon 5", + !tools::isRectangle( aNonRect5 )); } // Change the following lines only, if you add, remove or rename @@ -1322,7 +1137,6 @@ public: // insert your test code here. void EmptyMethod() { - CPPUNIT_ASSERT_STUB(); } // Change the following lines only, if you add, remove or rename @@ -1352,7 +1166,6 @@ public: void EmptyMethod() { // CPPUNIT_ASSERT_MESSAGE("a message", 1 == 1); - CPPUNIT_ASSERT_STUB(); } // Change the following lines only, if you add, remove or rename @@ -1380,7 +1193,6 @@ public: // insert your test code here. void EmptyMethod() { - CPPUNIT_ASSERT_STUB(); } // Change the following lines only, if you add, remove or rename @@ -1410,7 +1222,6 @@ public: void EmptyMethod() { // CPPUNIT_ASSERT_MESSAGE("a message", 1 == 1); - CPPUNIT_ASSERT_STUB(); } // Change the following lines only, if you add, remove or rename @@ -1438,7 +1249,6 @@ public: // insert your test code here. void EmptyMethod() { - CPPUNIT_ASSERT_STUB(); } // Change the following lines only, if you add, remove or rename @@ -1502,6 +1312,8 @@ public: tools::rgb2hsl(maMagenta) == BColor(300,1,0.5)); CPPUNIT_ASSERT_MESSAGE("cyan", tools::rgb2hsl(maCyan) == BColor(180,1,0.5)); + CPPUNIT_ASSERT_MESSAGE("third hue case", + tools::rgb2hsl(BColor(0,0.5,1)) == BColor(210,1,0.5)); CPPUNIT_ASSERT_MESSAGE("roundtrip white", tools::hsl2rgb(tools::rgb2hsl(maWhite)) == maWhite); @@ -1623,21 +1435,21 @@ public: }; // class b2dvector // ----------------------------------------------------------------------------- -//CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(basegfx2d::b2dmultirange, "basegfx2d"); -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(basegfx2d::b2dsvgdimpex, "basegfx2d"); -//CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(basegfx2d::b2dbeziertools, "basegfx2d"); -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(basegfx2d::b2dcubicbezier, "basegfx2d"); -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(basegfx2d::b2dhommatrix, "basegfx2d"); -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(basegfx2d::b2dhompoint, "basegfx2d"); -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(basegfx2d::b2dpoint, "basegfx2d"); -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(basegfx2d::b2dpolygon, "basegfx2d"); -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(basegfx2d::b2dpolygontools, "basegfx2d"); -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(basegfx2d::b2dpolypolygon, "basegfx2d"); -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(basegfx2d::b2dquadraticbezier, "basegfx2d"); -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(basegfx2d::b2drange, "basegfx2d"); -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(basegfx2d::b2dtuple, "basegfx2d"); -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(basegfx2d::b2dvector, "basegfx2d"); -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(basegfx2d::bcolor, "basegfx2d"); + +CPPUNIT_TEST_SUITE_REGISTRATION(basegfx2d::b2dsvgdimpex); +CPPUNIT_TEST_SUITE_REGISTRATION(basegfx2d::b2dpolyrange); +CPPUNIT_TEST_SUITE_REGISTRATION(basegfx2d::b2dcubicbezier); +CPPUNIT_TEST_SUITE_REGISTRATION(basegfx2d::b2dhommatrix); +CPPUNIT_TEST_SUITE_REGISTRATION(basegfx2d::b2dhompoint); +CPPUNIT_TEST_SUITE_REGISTRATION(basegfx2d::b2dpoint); +CPPUNIT_TEST_SUITE_REGISTRATION(basegfx2d::b2dpolygon); +CPPUNIT_TEST_SUITE_REGISTRATION(basegfx2d::b2dpolygontools); +CPPUNIT_TEST_SUITE_REGISTRATION(basegfx2d::b2dpolypolygon); +CPPUNIT_TEST_SUITE_REGISTRATION(basegfx2d::b2dquadraticbezier); +CPPUNIT_TEST_SUITE_REGISTRATION(basegfx2d::b2drange); +CPPUNIT_TEST_SUITE_REGISTRATION(basegfx2d::b2dtuple); +CPPUNIT_TEST_SUITE_REGISTRATION(basegfx2d::b2dvector); +CPPUNIT_TEST_SUITE_REGISTRATION(basegfx2d::bcolor); } // namespace basegfx2d diff --git a/basegfx/test/basegfx3d.cxx b/basegfx/test/basegfx3d.cxx index 23d3542e2d4a..a16132e0810f 100644 --- a/basegfx/test/basegfx3d.cxx +++ b/basegfx/test/basegfx3d.cxx @@ -30,7 +30,9 @@ #include "precompiled_basegfx.hxx" // autogenerated file with codegen.pl -#include <testshl/simpleheader.hxx> +#include "cppunit/TestAssert.h" +#include "cppunit/TestFixture.h" +#include "cppunit/extensions/HelperMacros.h" namespace basegfx3d { @@ -52,7 +54,6 @@ public: void EmptyMethod() { // CPPUNIT_ASSERT_MESSAGE("a message", 1 == 1); - CPPUNIT_ASSERT_STUB(); } // Change the following lines only, if you add, remove or rename @@ -80,7 +81,6 @@ public: // insert your test code here. void EmptyMethod() { - CPPUNIT_ASSERT_STUB(); } // Change the following lines only, if you add, remove or rename @@ -110,7 +110,6 @@ public: void EmptyMethod() { // CPPUNIT_ASSERT_MESSAGE("a message", 1 == 1); - CPPUNIT_ASSERT_STUB(); } // Change the following lines only, if you add, remove or rename @@ -138,7 +137,6 @@ public: // insert your test code here. void EmptyMethod() { - CPPUNIT_ASSERT_STUB(); } // Change the following lines only, if you add, remove or rename @@ -168,7 +166,6 @@ public: void EmptyMethod() { // CPPUNIT_ASSERT_MESSAGE("a message", 1 == 1); - CPPUNIT_ASSERT_STUB(); } // Change the following lines only, if you add, remove or rename @@ -196,7 +193,6 @@ public: // insert your test code here. void EmptyMethod() { - CPPUNIT_ASSERT_STUB(); } // Change the following lines only, if you add, remove or rename @@ -209,12 +205,12 @@ public: }; // class b3dvector // ----------------------------------------------------------------------------- -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(basegfx3d::b3dhommatrix, "basegfx3d"); -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(basegfx3d::b3dhompoint, "basegfx3d"); -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(basegfx3d::b3dpoint, "basegfx3d"); -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(basegfx3d::b3drange, "basegfx3d"); -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(basegfx3d::b3dtuple, "basegfx3d"); -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(basegfx3d::b3dvector, "basegfx3d"); +CPPUNIT_TEST_SUITE_REGISTRATION(basegfx3d::b3dhommatrix); +CPPUNIT_TEST_SUITE_REGISTRATION(basegfx3d::b3dhompoint); +CPPUNIT_TEST_SUITE_REGISTRATION(basegfx3d::b3dpoint); +CPPUNIT_TEST_SUITE_REGISTRATION(basegfx3d::b3drange); +CPPUNIT_TEST_SUITE_REGISTRATION(basegfx3d::b3dtuple); +CPPUNIT_TEST_SUITE_REGISTRATION(basegfx3d::b3dvector); } // namespace basegfx3d diff --git a/basegfx/test/basegfxtools.cxx b/basegfx/test/basegfxtools.cxx new file mode 100644 index 000000000000..1a8b97a559b2 --- /dev/null +++ b/basegfx/test/basegfxtools.cxx @@ -0,0 +1,110 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_basegfx.hxx" +// autogenerated file with codegen.pl + +#include "cppunit/TestAssert.h" +#include "cppunit/TestFixture.h" +#include "cppunit/extensions/HelperMacros.h" + +#include <basegfx/tools/keystoplerp.hxx> +#include <basegfx/numeric/ftools.hxx> + +#include <boost/tuple/tuple.hpp> + +using namespace ::basegfx; +using namespace ::boost::tuples; + +namespace basegfxtools +{ + +class KeyStopLerpTest : public CppUnit::TestFixture +{ + tools::KeyStopLerp maKeyStops; + + static std::vector<double> getTestVector() + { + std::vector<double> aStops(3); + aStops[0] = 0.1; + aStops[1] = 0.5; + aStops[2] = 0.9; + return aStops; + } + +public: + KeyStopLerpTest() : + maKeyStops(getTestVector()) + {} + + void setUp() + {} + + void tearDown() + {} + + void test() + { + double fAlpha; + std::ptrdiff_t nIndex; + + tie(nIndex,fAlpha) = maKeyStops.lerp(-1.0); + CPPUNIT_ASSERT_MESSAGE("-1.0", nIndex==0 && fAlpha==0.0); + + tie(nIndex,fAlpha) = maKeyStops.lerp(0.1); + CPPUNIT_ASSERT_MESSAGE("0.1", nIndex==0 && fAlpha==0.0); + + tie(nIndex,fAlpha) = maKeyStops.lerp(0.3); + CPPUNIT_ASSERT_MESSAGE("0.3", nIndex==0 && fTools::equal(fAlpha,0.5)); + + tie(nIndex,fAlpha) = maKeyStops.lerp(0.5); + CPPUNIT_ASSERT_MESSAGE("0.5", nIndex==0 && fTools::equal(fAlpha,1.0)); + + tie(nIndex,fAlpha) = maKeyStops.lerp(0.51); + CPPUNIT_ASSERT_MESSAGE("0.51", nIndex==1 && fTools::equal(fAlpha,0.025)); + + tie(nIndex,fAlpha) = maKeyStops.lerp(0.9); + CPPUNIT_ASSERT_MESSAGE("0.51", nIndex==1 && fTools::equal(fAlpha,1.0)); + + tie(nIndex,fAlpha) = maKeyStops.lerp(1.0); + CPPUNIT_ASSERT_MESSAGE("0.51", nIndex==1 && fAlpha==1.0); + } + + // Change the following lines only, if you add, remove or rename + // member functions of the current class, + // because these macros are need by auto register mechanism. + + CPPUNIT_TEST_SUITE(KeyStopLerpTest); + CPPUNIT_TEST(test); + CPPUNIT_TEST_SUITE_END(); +}; + +// ----------------------------------------------------------------------------- +CPPUNIT_TEST_SUITE_REGISTRATION(basegfxtools::KeyStopLerpTest); +} // namespace basegfxtools diff --git a/basegfx/test/boxclipper.cxx b/basegfx/test/boxclipper.cxx new file mode 100644 index 000000000000..d52218a51ee0 --- /dev/null +++ b/basegfx/test/boxclipper.cxx @@ -0,0 +1,419 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_basegfx.hxx" +// autogenerated file with codegen.pl + +#include "cppunit/TestAssert.h" +#include "cppunit/TestFixture.h" +#include "cppunit/extensions/HelperMacros.h" + +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/curve/b2dcubicbezier.hxx> +#include <basegfx/curve/b2dbeziertools.hxx> +#include <basegfx/range/b2dpolyrange.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/polygon/b2dpolypolygontools.hxx> +#include <basegfx/polygon/b2dpolypolygoncutter.hxx> +#include <basegfx/polygon/b2dpolygonclipper.hxx> +#include <basegfx/polygon/b2dpolypolygon.hxx> +#include <basegfx/numeric/ftools.hxx> + +#include <boost/bind.hpp> + +using namespace ::basegfx; + + +namespace basegfx2d +{ +/// Gets a random ordinal [0,n) +inline double getRandomOrdinal( const ::std::size_t n ) +{ + // use this one when displaying polygons in OOo, which still sucks + // great rocks when trying to import non-integer svg:d attributes + // return sal_Int64(double(n) * rand() / (RAND_MAX + 1.0)); + return double(n) * rand() / (RAND_MAX + 1.0); +} + +inline bool compare(const B2DPoint& left, const B2DPoint& right) +{ + return left.getX()<right.getX() + || (left.getX()==right.getX() && left.getY()<right.getY()); +} + + +class boxclipper : public CppUnit::TestFixture +{ +private: + B2DPolyRange aDisjunctRanges; + B2DPolyRange aEqualRanges; + B2DPolyRange aIntersectionN; + B2DPolyRange aIntersectionE; + B2DPolyRange aIntersectionS; + B2DPolyRange aIntersectionW; + B2DPolyRange aIntersectionNE; + B2DPolyRange aIntersectionSE; + B2DPolyRange aIntersectionSW; + B2DPolyRange aIntersectionNW; + B2DPolyRange aRingIntersection; + B2DPolyRange aRingIntersection2; + B2DPolyRange aRingIntersectExtraStrip; + B2DPolyRange aComplexIntersections; + B2DPolyRange aRandomIntersections; + +public: + // initialise your test code values here. + void setUp() + { + B2DRange aCenter(100, 100, -100, -100); + B2DRange aOffside(800, 800, 1000, 1000); + B2DRange aNorth(100, 0, -100, -200); + B2DRange aSouth(100, 200, -100, 0); + B2DRange aEast(0, 100, 200, -100); + B2DRange aWest(-200, 100, 0, -100); + B2DRange aNorthEast(0, 0, 200, -200); + B2DRange aSouthEast(0, 0, 200, 200); + B2DRange aSouthWest(0, 0, -200, 200); + B2DRange aNorthWest(0, 0, -200, -200); + + B2DRange aNorth2(-150, 50, 150, 350); + B2DRange aSouth2(-150, -50, 150, -350); + B2DRange aEast2 (50, -150, 350, 150); + B2DRange aWest2 (-50, -150,-350, 150); + + aDisjunctRanges.appendElement( aCenter, ORIENTATION_NEGATIVE ); + aDisjunctRanges.appendElement( aOffside, ORIENTATION_NEGATIVE ); + + aEqualRanges.appendElement( aCenter, ORIENTATION_NEGATIVE ); + aEqualRanges.appendElement( aCenter, ORIENTATION_NEGATIVE ); + + aIntersectionN.appendElement( aCenter, ORIENTATION_NEGATIVE ); + aIntersectionN.appendElement( aNorth, ORIENTATION_NEGATIVE ); + + aIntersectionE.appendElement( aCenter, ORIENTATION_NEGATIVE ); + aIntersectionE.appendElement( aEast, ORIENTATION_NEGATIVE ); + + aIntersectionS.appendElement( aCenter, ORIENTATION_NEGATIVE ); + aIntersectionS.appendElement( aSouth, ORIENTATION_NEGATIVE ); + + aIntersectionW.appendElement( aCenter, ORIENTATION_NEGATIVE ); + aIntersectionW.appendElement( aWest, ORIENTATION_NEGATIVE ); + + aIntersectionNE.appendElement( aCenter, ORIENTATION_NEGATIVE ); + aIntersectionNE.appendElement( aNorthEast, ORIENTATION_NEGATIVE ); + + aIntersectionSE.appendElement( aCenter, ORIENTATION_NEGATIVE ); + aIntersectionSE.appendElement( aSouthEast, ORIENTATION_NEGATIVE ); + + aIntersectionSW.appendElement( aCenter, ORIENTATION_NEGATIVE ); + aIntersectionSW.appendElement( aSouthWest, ORIENTATION_NEGATIVE ); + + aIntersectionNW.appendElement( aCenter, ORIENTATION_NEGATIVE ); + aIntersectionNW.appendElement( aNorthWest, ORIENTATION_NEGATIVE ); + + aRingIntersection.appendElement( aNorth2, ORIENTATION_NEGATIVE ); + aRingIntersection.appendElement( aEast2, ORIENTATION_NEGATIVE ); + aRingIntersection.appendElement( aSouth2, ORIENTATION_NEGATIVE ); + + aRingIntersection2 = aRingIntersection; + aRingIntersection2.appendElement( aWest2, ORIENTATION_NEGATIVE ); + + aRingIntersectExtraStrip = aRingIntersection2; + aRingIntersectExtraStrip.appendElement( B2DRange(0, -25, 200, 25), + ORIENTATION_NEGATIVE ); + + aComplexIntersections.appendElement( aCenter, ORIENTATION_NEGATIVE ); + aComplexIntersections.appendElement( aOffside, ORIENTATION_NEGATIVE ); + aComplexIntersections.appendElement( aCenter, ORIENTATION_NEGATIVE ); + aComplexIntersections.appendElement( aNorth, ORIENTATION_NEGATIVE ); + aComplexIntersections.appendElement( aEast, ORIENTATION_NEGATIVE ); + aComplexIntersections.appendElement( aSouth, ORIENTATION_NEGATIVE ); + aComplexIntersections.appendElement( aWest, ORIENTATION_NEGATIVE ); + aComplexIntersections.appendElement( aNorthEast, ORIENTATION_NEGATIVE ); + aComplexIntersections.appendElement( aSouthEast, ORIENTATION_NEGATIVE ); + aComplexIntersections.appendElement( aSouthWest, ORIENTATION_NEGATIVE ); + aComplexIntersections.appendElement( aNorthWest, ORIENTATION_NEGATIVE ); + +#ifdef GENERATE_RANDOM + for( int i=0; i<800; ++i ) + { + B2DRange aRandomRange( + getRandomOrdinal( 1000 ), + getRandomOrdinal( 1000 ), + getRandomOrdinal( 1000 ), + getRandomOrdinal( 1000 ) ); + + aRandomIntersections.appendElement( aRandomRange, ORIENTATION_NEGATIVE ); + } +#else + const char* randomSvg="m394 783h404v57h-404zm-197-505h571v576h-571zm356-634h75v200h-75zm-40-113h403v588h-403zm93-811h111v494h-111zm-364-619h562v121h-562zm-134-8h292v27h-292zm110 356h621v486h-621zm78-386h228v25h-228zm475-345h201v201h-201zm-2-93h122v126h-122zm-417-243h567v524h-567zm-266-738h863v456h-863zm262-333h315v698h-315zm-328-826h43v393h-43zm830-219h120v664h-120zm-311-636h221v109h-221zm-500 137h628v19h-628zm681-94h211v493h-211zm-366-646h384v355h-384zm-189-199h715v247h-715zm165-459h563v601h-563zm258-479h98v606h-98zm270-517h65v218h-65zm-44-259h96v286h-96zm-599-202h705v468h-705zm216-803h450v494h-450zm-150-22h26v167h-26zm-55-599h50v260h-50zm190-278h490v387h-490zm-290-453h634v392h-634zm257 189h552v300h-552zm-151-690h136v455h-136zm12-597h488v432h-488zm501-459h48v39h-48zm-224-112h429v22h-429zm-281 102h492v621h-492zm519-158h208v17h-208zm-681-563h56v427h-56zm126-451h615v392h-615zm-47-410h598v522h-598zm-32 316h79v110h-79zm-71-129h18v127h-18zm126-993h743v589h-743zm211-430h428v750h-428zm61-554h100v220h-100zm-353-49h658v157h-658zm778-383h115v272h-115zm-249-541h119v712h-119zm203 86h94v40h-94z"; + B2DPolyPolygon randomPoly; + tools::importFromSvgD( + randomPoly, + rtl::OUString::createFromAscii(randomSvg)); + std::for_each(randomPoly.begin(), + randomPoly.end(), + boost::bind( + &B2DPolyRange::appendElement, + boost::ref(aRandomIntersections), + boost::bind( + &B2DPolygon::getB2DRange, + _1), + ORIENTATION_NEGATIVE, + 1)); +#endif + } + + void tearDown() + { + } + + B2DPolyPolygon normalizePoly( const B2DPolyPolygon& rPoly ) + { + B2DPolyPolygon aRes; + for( sal_uInt32 i=0; i<rPoly.count(); ++i ) + { + B2DPolygon aTmp=rPoly.getB2DPolygon(i); + if( ORIENTATION_NEGATIVE == tools::getOrientation(aTmp) ) + aTmp.flip(); + + aTmp=tools::removeNeutralPoints(aTmp); + + B2DPoint* pSmallest=0; + for(B2DPoint* pCurr=aTmp.begin(); pCurr!=aTmp.end(); ++pCurr) + { + if( ! pSmallest || compare(*pCurr, *pSmallest) ) + { + pSmallest=pCurr; + } + } + + if( pSmallest ) + std::rotate(aTmp.begin(),pSmallest,aTmp.end()); + + aRes.append(aTmp); + } + + // boxclipper & generic clipper disagree slightly on area-less + // polygons (one or two points only) + aRes = tools::stripNeutralPolygons(aRes); + + // now, sort all polygons with increasing 0th point + std::sort(aRes.begin(), + aRes.end(), + boost::bind( + &compare, + boost::bind( + &B2DPolygon::getB2DPoint, + _1,0), + boost::bind( + &B2DPolygon::getB2DPoint, + _2,0))); + + return aRes; + } + + void verifyPoly(const char* sName, const char* sSvg, const B2DPolyRange& toTest) + { + B2DPolyPolygon aTmp1; + CPPUNIT_ASSERT_MESSAGE(sName, + tools::importFromSvgD( + aTmp1, + rtl::OUString::createFromAscii(sSvg))); + + const rtl::OUString aSvg= + tools::exportToSvgD(toTest.solveCrossovers()); + B2DPolyPolygon aTmp2; + CPPUNIT_ASSERT_MESSAGE(sName, + tools::importFromSvgD( + aTmp2, + aSvg)); + + CPPUNIT_ASSERT_MESSAGE( + sName, + normalizePoly(aTmp2) == normalizePoly(aTmp1)); + } + + void verifyPoly() + { + const char* disjunct="m100 100v-200h-200v200zm1100 900v-200h-200v200z"; + const char* equal="m100 100v-200h-200v200zm200 0v-200h-200v200h200z"; + const char* intersectionN="m100 0v-100h-200v100zm200 100v-200-100h-200v100 200z"; + const char* intersectionE="m100 100v-200h-100v200zm200 0v-200h-200-100v200h100z"; + const char* intersectionS="m100 100v-200h-200v200 100h200v-100zm0 0v-100h-200v100z"; + const char* intersectionW="m0 100v-200h-100v200zm200 0v-200h-200-100v200h100z"; + const char* intersectionNE="m100 0v-100h-100v100zm200 0v-200h-200v100h-100v200h200v-100z"; + const char* intersectionSE="m200 200v-200h-100v-100h-200v200h100v100zm100-100v-100h-100v100z"; + const char* intersectionSW="m0 100v-100h-100v100zm200 0v-200h-200v100h-100v200h200v-100z"; + const char* intersectionNW="m100 100v-200h-100v-100h-200v200h100v100zm100-100v-100h-100v100z"; + const char* ringIntersection="m150 150v-100h-100v100zm300 0v-300h-200v-200h-300v300h200v100h-200v300h300v-200zm0-200v-100h-100v100z"; + const char* ringIntersection2="m-50-50v-100h-100v100zm100 200v-100h-100v100zm500 0v-300h-200v-200h-300v200h-200v300h200v200h300v-200zm-200-100v-100h100v100zm100-100v-100h-100v100zm100 200v-100h-100v100z"; + const char* ringIntersectExtraStrip="m-50-50v-100h-100v100zm100 200v-100h-100v100zm500 0v-300h-200v-200h-300v200h-200v300h200v200h300v-200zm-200-100v-100h100v25h-50v50h50v25zm150-25v-50h-150v50zm100-75v-100h-100v100zm100 200v-100h-100v100z"; + // TODO: old clipper impl. debug difference + //const char* complexIntersections="m100 0h-100v-100 100h-100 100v100-100zm0 0zm200 0h-100v-100h-100v-100 100h-100v100h-100 100v100h100v100-100h100v-100zm0 0h-100v-100 100h-100 100v100-100h100zm0 0v-100h-100-100v100 100h100 100v-100zm100 0v-100h-100v-100h-100-100v100h-100v100 100h100v100h100 100v-100h100v-100zm-200 0zm100 0v-100h-100-100v100 100h100 100v-100zm100 100v-200-100h-200-100-100v100 200 100h100 100 200v-100zm-200-100zm1000 1000v-200h-200v200z"; + const char* complexIntersections="m0 0zm0 0zm0 0zm0 0v-100 100h-100 100v100-100h100zm-100 0v-100 100h-100 100v100-100h100zm0 0v-100h-100-100v100 100h100 100v-100zm0 0v-100h-100-100v100 100h100 100v-100zm0 0v-100h-100v-100 100h-100v100h-100 100v100h100v100-100h100v-100h100zm-100-100v-100h-100-100v100h-100v100 100h100v100h100 100v-100h100v-100-100zm0 0v-100h-200-100-100v100 200 100h100 100 200v-100-200zm600 900v200h200v-200z"; + const char* randomIntersections="m63 457v-393h-43v393zm114 63v-8h-48v8zm-14 477v-127h-18v127zm693-923v-5h-119v5zm-260 457v-1h-14v1zm-220-375v-27h-8v27zm78 755v-22h-7v22zm203-774v-8h-158v8zm-108 375v-17h23v17zm813-19v-189h-21v-12h-26v-54h-17v-69h-25v-22h-62v-73h104v-5h-104-15v-17h-49v-1h-8v-16h-119v16h-386v18h-38-24v34h-23v26h-23v-26h-8v26h-18v27h18v339h8v-339h23v339h8v17h-8v13h8v5h-8v1h8v42h15v20h17v94h18 3v224h165v39h130v2h75v4h98v-4h153v-2h77v-20h4v-28h11v-218h-11v-27h3v-1h8v-17h-8v-63h8v-51h18v-32zm-581 32v-13h-14v13zm-78-78v-7h-32v7zm124 14v-21h-14v21zm595 32v-189h-26v-12h-4v-9h-13v-45h-13v-10h-12v-59h-62v-22h-26v-10h11v-63h15v-5h-15-49v-17h-8v-1h-119v1h-107v17h-279-38v34h-24v26h-23v27h23v284h-15v55h15v17h-15v13h15v5h-15v1h15v42h17v20h18v94h3 14v62h8v48h90v32h18v61h35v21h8v2h122v37h75v2h98v-2h153v-20h77v-28h4v-29h5v-40h-5v-149h-1v-27h1v-1h3v-17h-3v-46h3v-17-51h8v-32zm-563 2v-13h-14v13zm198 30v-13h-39v13zm204-43v-21h3v21zm-168-21v-21h-39v21zm306 0v-21h-5v21zm178 115v-272h-20v-12h-2v-54h-21v-164h1v-22h-27v-48h-743v47h-23v18h-71v24h-8v419h-39v19h60v156h66 32v202h-72v110h79v-88h11v39h3v48h621v-14h96v-82h35v-326zm-570-420v-4h-156v4zm63 481v-18h-11v18zm72 0v-25h-14v25zm465-112v-13h-5v13zm-46-43v-21h1v21zm-37-21v-21h-12v21zm-352 21v-21h23v21zm-23 30v-17h23v17zm-23 18v-5h23v5zm-23 82v-19h23v19zm272 75v-3h-35v3zm-76-192v-13h-39v13zm150 30v-13h-35v13zm-76 6v-1h-39v1zm11 106v-25h-11v25zm150 160v-14h-75v14zm318-304v-11h-13v-43h-2v-2h-10v-37h-4v37h-27v3h-31v-3-37h-5v37h-43v3h-2v21h2v21h-2v30h-1v-30h-8v-21h8v-21h-8v-3h-5v-62h5v-11h-5v-29h-8v-52h-15v-17-38h-15v-52h-89v16h-22v36h-175v55h-15v1h-25v51h-23v-41h-14v41h-2v105h-4v21h4v21h-4v13h4v17h-4-18v13h18v5h-18v1h18v42h4v11h2v9h14v-9h23v9h40v19h-40v25h40v2h82v2h75v43h-75v3h75 40v60h35v-60h23 34 12 15v-3h-15v-43h15v-48h10v-37h11v-31h1v1h45v30h5v-30h20v-1h11v1h8v30h19v20h3v-20h1v-30h10v-1h2v-32zm-146-329v-1h-2v1zm-117 211v-11 11zm-76 0v-11h-13v11zm13 65v-65h1v65zm-1 42v-21h1v16h35v5zm-36 30v-17h36v17zm-36 18v-5h36v5zm180-5v-13h-13v-17h5v-13h-5v-21h5v-21h-5v-3h-8v-62h8v-11h-8v-29h-9v-51h-6v-1-17h-15v-38h-54v-36h-35v36h-22v38h-67v17h-108v1h-15v51h-25v105h-23v-105h-14v105h-2v21h2v21h-2v13h2v17h-2-4v13h4v5h-4v1h4v42h2v11h14v-11h23v11h40v9h82v19h-82v25h82v2h75v2h40v43h-40v3h40 35 23v-3h-23v-43h23v-2h34v2h12v-2h6v-46h9v-20h8v-17h2v-26h-2v-5zm-127-64v-21 21zm89 51v-17h3v17zm-57-17v-13h-35v13zm58 61v-26h-19v-5h19v-13h-23v-17h23v-13h-23v-21h23v-21h-23v-65h23v-11h-23v-14h-35v-15 15h-22v14h-18v11h18v65h-18v21h18v16h22v5h-22v13h22v17h-22-18v13h18v5h-18v1h18v25h22v17h35v-17zm0-25v-1h-35v1zm-22-390v6h-175v5h-31v-15h228v4zm344 352v-189h-2v-12h-21v-54h-26v-164h26v-5h-26v-17h-119v-36h-562v35h-62v18h-23v34h-23v-10h-48v419h-8v8h8v5h71v5h-58v1h58v42h8v114h32 18v224h3v39h165v34h456v-32h77v-2h4v-20h11v-28h4v-218h-4v-28h36v-17h-36v-63h39v-83zm-50 0v-11h-1v-43h-3v-2h-6v-39h-4v-34h-13v-60h-12v-12h-31v72h-31v-72-9h-59v-17-38h-5v-59h-8v-5h8v-1h-8v-16h-2v16h-13v-11h-15v-5h-89v5h-22v11h-175v6h-15v7h-25v16h-43v36h-18v66h-54v-107h-32v107h-4v41h-8v105h-6v7h6v14h8v21h-8v13h8v17h-8-14v13h14v5h-14v1h14v42h8v20h90v19h-34v7h-15v68h26v-50h23v50h18 4v62h16v-62h15v110h8v10h3v22h119v11h75v50h75v-50h23v-11h34v11h48v-11h30v-22h21v-120h20v-3h11v3h30v-3h13-13v-27h13v-1h17v-17h-17v-46h17v-17h6v-51h3v-32zm-256-32v-21h-35v-65h35v-11h-35v-14 14h-22v11h22v65h-22v21h22v16-16zm89 69v-5h3v5zm-3 26v-26h-31v-5h31v-13h-31v-17h31v-13h-31v-21h31v-21h-31v-65h31v-11h-31v-14h-23v-15h-35v-51 51h-22v15h-18v14h-35v11h35v65h-35v21h35v16h18v5h-18v13h18v17h-18-36-39-61v13h61v5h-61v1h61v25h39v-25h36v25h18v17h22v11h35v-11h23v-17zm-19-25v-1h-4v-5h4v-13h-4-35-22v13h22v5h-22v1h22v25h35v-25zm23 252v-36h34v36zm-34-99v-43h34v43zm35-128v-26h-8v-5h8v-13h-8v-17h8v-13h-8v-21h8v-21h-8v-3h-9v-62h9v-11h-9v-29h-6v-51-1h-15v-17h-54v-38h-35v38h-22v11h-53v6h-14v1h-108v51h-15v105h-25v21h25v21h-25v13h25v17h-25-23-14-2v13h2v5h-2v1h2v42h14v-42h23v42h40v11h82v9h75v46h40v2h35v-2h23v-4h31v-42h3v46h12v-46h6v-20h9v-17zm-15-61v-13h-12v13zm12 30v-13h-12v13zm12 31v-26h-12v26zm12 131v-3h-12v3zm12 110v-14h-12v14zm27-241v-26h-9v-5h9v-13h-9v-17h9v-13h-9v-21h9v-21h-9v-3h-6v-62h6v-11h-6v-29-51h-15v-1h-54v-17h-35v11h-22v6h-53v1h-14v51h-108v105h-15v21h15v21h-15v13h15v17h-15-25v13h25v5h-25v1h25v25h15v17h21v6h61v5h75v9h18v42h22v4h35v-4h23v-42h31v-9h3v9h12v-9-11h6v-17zm0 0v-26h-6v-5h6v-13h-6v-17h6v-13h-6v-21h6v-21h-6v-3-62-11-29h-15v-51h-54v-1h-35v-6 6h-22v1h-53v51h-14v24h-87v81h-21v21h21v21h-21v13h21v17h-21-15v13h15v5h-15v1h15v25h21v17h61v6h39v-6h36v11h18v9h22v42h35v-42h23v-9h31v-11h3v11h12v-11-17zm0 0v-26-5-13-17-13-21-21-3h-12v3h-3v-65h15v-11h-15v-29h-54v-51h-35v-1 1h-22v51h-53v29h-1v-5h-13v5h-26v76h-61v21h61v21h-61v13h61v17h-61-21v13h21v5h-21v1h21v25h61v17h39v-17h36v17h18v11h22v9h35v-9h23v-11h31v-17h3v17h12v-17zm15-419v-12h-2v12zm186 356v-56h-8v-133h-4v-12h-13v-9h-13v-45h-12v-10h-62v-59-6h-26v-16h-33v-10h33v-12h-33v-22h-5v-29h49v-5h-49-8v-17h-119v17h-107-279v34h-38v26h-24v27h24v179h-7v105h-17v55h17v17h-17v13h17v5h-17v1h17v42h18v20h3v94h14 8v62h41v37h26v-37h23v48h18v32h35v61h8v21h122v2h75v37h98v-37h34v17h119v-57h11v29h66v-29h4v-40h-4v-26h3v-123h-3v-27h3v-1h1v-17h-1v-46h1v-17h3v-51-32zm0 0v-54h-4v-2h-3v-73h-10v-60h-13v-12h-12v-9h-31v9h-31v-9-55h-59v-59h-5v-5h5v-1h-5v-16h-8v-10h8v-12h-8v-22h-119v34h117v10h-28v-6h-89v6h-22v5h-175v11h-40v13h-147v11h-4v107h-8v41h-6v105h-22v21h28v21h-17v13h17v17h-14-3v13h3v5h-3v1h3v42h14v20h8v94h41 26 23 18v62h4v48h31v10h8v22h3v11h119v50h75v21h98v-71h34v71h48v-71h30v-11h21v-22h20v-120h11v120h43v-123h17-17v-27h17v-1h6v-17h-6v-46h6v-17h3v-51h1v-32zm-4 0v-11h-6v-43h-4v-2h-13v-39h-12v-34h-4v34h-27v2h-31v-2-34h-48v36h-2v37h-1v-73h-8v-29-52h-5v-17h-8v-38h-15v-59h-15v-6h-89v6h-22v7h-175v16h-15v36h-25v55h-39v11h-4v41h-18v105h-54v-105h-32v105h-4v7h4v14h86v21h-86v13h86v17h-86-4v13h4v5h-4v1h4v42h86v11h18v9h4v19h-4v25h4v50h16v-48h23v45h-8v3h8 122v96h-119v14h119v10h75v22h75v-22h23v-10h34v10h48v-24h-36v-36h15v-60h21v-3h-11v-43h2v15h9v-15h46v15h5v-15h20v-2h-20v-46h20v-37h11v37h8v46h-8v2h8v15h22v-15h1v-2h-1v-46h1v-17h12v-20h13v-31h4v-32zm-142 148v-2h-9v2zm9-2v-46h46v46zm-46 45v-28h46v28zm67-191v-11h-1v-42h-3v42h-19v11h19v32h3v-32zm-61 0v-11h-5v11zm96 0v-11h-4v-43h-13v-2h-2v-37h-10v-2h-4v2h-27v37h-31v-37-2h-5v2h-43v37h-2v3h-1v-3h-8v-62-11-29h-5v-52h-8v-17h-15v-38-52h-15v-7h-89v7h-22v16h-175v36h-15v55h-25v1h-37v10h-2v41h-4v105h-18v21h18v21h-18v13h18v17h-18-86v13h86v5h-86v1h86v42h18v11h4v9h2v19h-2v25h2v2h14v-2h23v2h40v2h82v43h-122v3h122 75v96h-75v14h75v10h75v-10h23v-14h-23v-36h23v-60h34v60h12v-60h15 10v-3h-10v-43h10v-48h11v-37h46v37h5v-37h20v-30h11v30h8v37h22v-17h1v-20h12v-31h13v-32zm-13 0v-11h-2v-43h-10v-2h-4v2h-19v1h-8v42h-31v-21-21-3h-5v3h-43v21h43v21h-43v11h43v19h-45v13h45v1h5v-1h20v-13h-20v-19h31v32h8v1h19v30h3v-30h1v-1h10v-32zm-72 148v-2h-5v2zm5 43h-5zm66-191v-11h-3v11zm-38 146v-46h11v46zm-11 45v-28h11v28zm-11 149v-4h11v4zm-11 40v-40h-8v40zm92-380v-54-2h-4v-133h-13v-12h-13v-9h-12v-45h-31v45h-31v-55-59h-59v-5h33v-1h-33v-16h-5v-10h5v-12h-5v-22h-8v-29h8v-5h-8-119-107v5h107v29h-386v26h-38v27h40v20h-4v11h-14v148h-22v105h-7v55h18v17h-18v13h18v5h-18v1h18v42h3v20h14v94h8 41v62h26v-62h23v62h18v48h4v10h31v22h8v61h122v21h75v2h98v-2h34v2h99v-84h20v-22h11v22h43v-22h23v-123h-6v-27h6v-1h3v-17h-3v-46h3v-17h1v-51h3v-32zm-43 148v-2h-22v2zm22 43h-30zm66 189v-40h-66v40zm41-380v-11h-10v-43h-4v1h-19v42h-8v11h8v32h19v1h3v-1h1v-32zm38 0v-11h-3v-43h-6v-2h-4v-39h-13v-34h-12v-60h-4v60h-27v34h-31v-34-72h-48v72h-3v-29h-8v-52-17h-5v-38h-8v-59h-15v-6h-15v-11h-89v11h-22v6h-175v7h-15v16h-25v36h-43v66h-18v41h-54v-41h-32v41h-4v105h-8v7h8v14h4v21h-4v13h4v17h-4-8v13h8v5h-8v1h8v42h4v11h86v9h18v19h-18v25h18v50h4 16 15 8v110h3v10h119v22h75v11h75v-11h23v-22h34v22h48v-22h30v-24h-30v-96h51v-3h20-20v-28h20v-15h11v15h8v1h22v-1h13v-17h-12v-46h12v-17h17v-51h6v-32z"; + + verifyPoly("disjunct", disjunct, aDisjunctRanges); + verifyPoly("equal", equal, aEqualRanges); + verifyPoly("intersectionN", intersectionN, aIntersectionN); + verifyPoly("intersectionE", intersectionE, aIntersectionE); + verifyPoly("intersectionS", intersectionS, aIntersectionS); + verifyPoly("intersectionW", intersectionW, aIntersectionW); + verifyPoly("intersectionNE", intersectionNE, aIntersectionNE); + verifyPoly("intersectionSE", intersectionSE, aIntersectionSE); + verifyPoly("intersectionSW", intersectionSW, aIntersectionSW); + verifyPoly("intersectionNW", intersectionNW, aIntersectionNW); + verifyPoly("ringIntersection", ringIntersection, aRingIntersection); + verifyPoly("ringIntersection2", ringIntersection2, aRingIntersection2); + verifyPoly("ringIntersectExtraStrip", ringIntersectExtraStrip, aRingIntersectExtraStrip); + verifyPoly("complexIntersections", complexIntersections, aComplexIntersections); + verifyPoly("randomIntersections", randomIntersections, aRandomIntersections); + } + + void dumpSvg(const char* pName, + const ::basegfx::B2DPolyPolygon& rPoly) + { + (void)pName; (void)rPoly; +#if defined(VERBOSE) + fprintf(stderr, "%s - svg:d=\"%s\"\n", + pName, rtl::OUStringToOString( + basegfx::tools::exportToSvgD(rPoly), + RTL_TEXTENCODING_UTF8).getStr() ); +#endif + } + + void getPolyPolygon() + { + dumpSvg("disjunct",aDisjunctRanges.solveCrossovers()); + dumpSvg("equal",aEqualRanges.solveCrossovers()); + dumpSvg("intersectionN",aIntersectionN.solveCrossovers()); + dumpSvg("intersectionE",aIntersectionE.solveCrossovers()); + dumpSvg("intersectionS",aIntersectionS.solveCrossovers()); + dumpSvg("intersectionW",aIntersectionW.solveCrossovers()); + dumpSvg("intersectionNE",aIntersectionNE.solveCrossovers()); + dumpSvg("intersectionSE",aIntersectionSE.solveCrossovers()); + dumpSvg("intersectionSW",aIntersectionSW.solveCrossovers()); + dumpSvg("intersectionNW",aIntersectionNW.solveCrossovers()); + dumpSvg("ringIntersection",aRingIntersection.solveCrossovers()); + dumpSvg("ringIntersection2",aRingIntersection2.solveCrossovers()); + dumpSvg("aRingIntersectExtraStrip",aRingIntersectExtraStrip.solveCrossovers()); + dumpSvg("complexIntersections",aComplexIntersections.solveCrossovers()); + dumpSvg("randomIntersections",aRandomIntersections.solveCrossovers()); + + CPPUNIT_ASSERT_MESSAGE("getPolyPolygon", true ); + } + + void validatePoly( const char* pName, const B2DPolyRange& rRange ) + { + B2DPolyPolygon genericClip; + const sal_uInt32 nCount=rRange.count(); + for( sal_uInt32 i=0; i<nCount; ++i ) + { + B2DPolygon aRect=tools::createPolygonFromRect( + rRange.getElement(i).head); + if( rRange.getElement(i).tail.head == ORIENTATION_NEGATIVE ) + aRect.flip(); + + genericClip.append(aRect); + } + +#if defined(VERBOSE) + fprintf(stderr, "%s input - svg:d=\"%s\"\n", + pName, rtl::OUStringToOString( + basegfx::tools::exportToSvgD( + genericClip), + RTL_TEXTENCODING_UTF8).getStr() ); +#endif + + const B2DPolyPolygon boxClipResult=rRange.solveCrossovers(); + const rtl::OUString boxClipSvg( + basegfx::tools::exportToSvgD( + normalizePoly( + boxClipResult))); +#if defined(VERBOSE) + fprintf(stderr, "%s boxclipper - svg:d=\"%s\"\n", + pName, rtl::OUStringToOString( + boxClipSvg, + RTL_TEXTENCODING_UTF8).getStr() ); +#endif + + genericClip = tools::solveCrossovers(genericClip); + const rtl::OUString genericClipSvg( + basegfx::tools::exportToSvgD( + normalizePoly( + genericClip))); +#if defined(VERBOSE) + fprintf(stderr, "%s genclipper - svg:d=\"%s\"\n", + pName, rtl::OUStringToOString( + genericClipSvg, + RTL_TEXTENCODING_UTF8).getStr() ); +#endif + + CPPUNIT_ASSERT_MESSAGE(pName, + genericClipSvg == boxClipSvg); + } + + void validatePoly() + { + validatePoly("disjunct", aDisjunctRanges); + validatePoly("equal", aEqualRanges); + validatePoly("intersectionN", aIntersectionN); + validatePoly("intersectionE", aIntersectionE); + validatePoly("intersectionS", aIntersectionS); + validatePoly("intersectionW", aIntersectionW); + validatePoly("intersectionNE", aIntersectionNE); + validatePoly("intersectionSE", aIntersectionSE); + validatePoly("intersectionSW", aIntersectionSW); + validatePoly("intersectionNW", aIntersectionNW); + // subtle differences on Solaris Intel, comparison not smart enough + // (due to floating point inaccuracies) + //validatePoly("ringIntersection", aRingIntersection); + //validatePoly("ringIntersection2", aRingIntersection2); + //validatePoly("ringIntersectExtraStrip", aRingIntersectExtraStrip); + // generic clipper buggy here, likely + //validatePoly("complexIntersections", aComplexIntersections); + //validatePoly("randomIntersections", aRandomIntersections); + } + + // Change the following lines only, if you add, remove or rename + // member functions of the current class, + // because these macros are need by auto register mechanism. + + CPPUNIT_TEST_SUITE(boxclipper); + CPPUNIT_TEST(validatePoly); + CPPUNIT_TEST(verifyPoly); + CPPUNIT_TEST(getPolyPolygon); + CPPUNIT_TEST_SUITE_END(); +}; + +// ----------------------------------------------------------------------------- +CPPUNIT_TEST_SUITE_REGISTRATION(basegfx2d::boxclipper); +} // namespace basegfx2d diff --git a/basegfx/test/clipstate.cxx b/basegfx/test/clipstate.cxx new file mode 100644 index 000000000000..3d9f59979aa7 --- /dev/null +++ b/basegfx/test/clipstate.cxx @@ -0,0 +1,178 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_basegfx.hxx" +// autogenerated file with codegen.pl + +#include "cppunit/TestAssert.h" +#include "cppunit/TestFixture.h" +#include "cppunit/extensions/HelperMacros.h" + +#include <basegfx/tools/b2dclipstate.hxx> +#include <basegfx/range/b2dpolyrange.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/polygon/b2dpolypolygontools.hxx> +#include <basegfx/polygon/b2dpolypolygon.hxx> +#include <basegfx/numeric/ftools.hxx> + +#include <boost/bind.hpp> + +using namespace ::basegfx; + + +namespace basegfx2d +{ + +class clipstate : public CppUnit::TestFixture +{ +private: + tools::B2DClipState aUnion1; + tools::B2DClipState aUnion2; + tools::B2DClipState aIntersect; + tools::B2DClipState aXor; + tools::B2DClipState aSubtract; + +public: + void setUp() + { + B2DRange aCenter(100, 100, -100, -100); + B2DRange aNorth(-10, -110, 10, -90); + B2DRange aWest(-110, -10, -90, 10); + B2DRange aSouth(-10, 110, 10, 90); + B2DRange aEast(110, -10, 90, 10); + + aUnion1.unionRange(aCenter); + aUnion1.unionRange(aNorth); + aUnion1.unionRange(aWest); + aUnion1.unionRange(aSouth); + aUnion1.unionRange(aEast); + + aUnion2.makeNull(); + aUnion2.unionRange(aCenter); + aUnion2.unionRange(aNorth); + aUnion2.unionRange(aWest); + aUnion2.unionRange(aSouth); + aUnion2.unionRange(aEast); + + aIntersect.intersectRange(aCenter); + aIntersect.intersectRange(aNorth); + aIntersect.intersectRange(aWest); + aIntersect.intersectRange(aSouth); + aIntersect.intersectRange(aEast); + + aXor.makeNull(); + aXor.xorRange(aCenter); + aXor.xorRange(aNorth); + aXor.xorRange(aWest); + aXor.xorRange(aSouth); + aXor.xorRange(aEast); + + aSubtract.intersectRange(aCenter); + aSubtract.subtractRange(aNorth); + aSubtract.subtractRange(aWest); + aSubtract.subtractRange(aSouth); + aSubtract.subtractRange(aEast); + } + + void tearDown() + {} + + void verifyPoly(const char* sName, const char* sSvg, const tools::B2DClipState& toTest) + { +#if defined(VERBOSE) + fprintf(stderr, "%s - svg:d=\"%s\"\n", + sName, rtl::OUStringToOString( + basegfx::tools::exportToSvgD(toTest.getClipPoly()), + RTL_TEXTENCODING_UTF8).getStr() ); +#endif + + B2DPolyPolygon aTmp1; + CPPUNIT_ASSERT_MESSAGE(sName, + tools::importFromSvgD( + aTmp1, + rtl::OUString::createFromAscii(sSvg))); + + const rtl::OUString aSvg= + tools::exportToSvgD(toTest.getClipPoly()); + B2DPolyPolygon aTmp2; + CPPUNIT_ASSERT_MESSAGE(sName, + tools::importFromSvgD( + aTmp2, + aSvg)); + + CPPUNIT_ASSERT_MESSAGE( + sName, + aTmp2 == aTmp1); + } + + void verifySimpleRange() + { + const char* unionSvg="m100 10v90h-90v10h-20v-10h-90v-90h-10v-20h10v-90h90v-10h20v10h90v90h10v20z"; + const char* intersectSvg="m-100 10v-20h10v20zm80 90v-10h20v10zm-20-190v-10h20v10zm80 100v-20h10v20z"; + const char* xorSvg="m-100 10h10v-20h-10zm90 110h20v-10h-20zm0-180h20v-10h-20zm100 110h10v-20h-10zm10 20v90h-90v10h-20v-10h-90v-90h-10v-20h10v-90h90v-10h20v10h90v90h10v20z"; + const char* subtractSvg="m-90 10v-20h-10v-90h90v10h20v-10h90v90h-10v20h10v90h-90v-10h-20v10h-90v-90z"; + + CPPUNIT_ASSERT_MESSAGE("cleared clip stays empty under union operation", + aUnion1.isCleared()); + verifyPoly("union", unionSvg, aUnion2); + verifyPoly("intersect", intersectSvg, aIntersect); + verifyPoly("xor", xorSvg, aXor); + verifyPoly("subtract", subtractSvg, aSubtract); + } + + void verifyMixedClips() + { + tools::B2DClipState aMixedClip; + + const char* unionSvg="m100 10v90h-90v10h-20v-10h-90v-90h-10v-20h10v-90h90v-10h20v10h90v90h10v20z"; + + B2DPolyPolygon aTmp1; + tools::importFromSvgD( + aTmp1, + rtl::OUString::createFromAscii(unionSvg)); + + aMixedClip.intersectPolyPolygon(aTmp1); + aMixedClip.subtractRange(B2DRange(-20,-150,20,0)); + aMixedClip.subtractRange(B2DRange(-150,-20,0,20)); + aMixedClip.xorRange(B2DRange(-150,-150,150,150)); + + const char* mixedClipSvg="m0 0v20h-100v80h90v10h20v-10h90v-90h10v-20h-10v-90h-80v100zm-40-20v-80h-80v80zm-50 170v-300h300v300z"; + verifyPoly("mixed clip", mixedClipSvg, aMixedClip); + } + + CPPUNIT_TEST_SUITE(clipstate); + CPPUNIT_TEST(verifySimpleRange); + CPPUNIT_TEST(verifyMixedClips); + CPPUNIT_TEST_SUITE_END(); +}; + +// ----------------------------------------------------------------------------- +CPPUNIT_TEST_SUITE_REGISTRATION(basegfx2d::clipstate); +} // namespace basegfx2d diff --git a/basegfx/test/export.map b/basegfx/test/export.map index 709047ae63e5..3308588ef6f8 100644 --- a/basegfx/test/export.map +++ b/basegfx/test/export.map @@ -25,9 +25,9 @@ # #************************************************************************* -UDK_3.1 { +UDK_3_0_0 { global: - registerAllTestFunction; + cppunitTestPlugIn; local: *; diff --git a/basegfx/test/genericclipper.cxx b/basegfx/test/genericclipper.cxx new file mode 100644 index 000000000000..84230a084493 --- /dev/null +++ b/basegfx/test/genericclipper.cxx @@ -0,0 +1,159 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_basegfx.hxx" +// autogenerated file with codegen.pl + +#include "cppunit/TestAssert.h" +#include "cppunit/TestFixture.h" +#include "cppunit/extensions/HelperMacros.h" + +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/curve/b2dcubicbezier.hxx> +#include <basegfx/curve/b2dbeziertools.hxx> +#include <basegfx/range/b2dpolyrange.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/polygon/b2dpolypolygontools.hxx> +#include <basegfx/polygon/b2dpolypolygoncutter.hxx> +#include <basegfx/polygon/b2dpolygonclipper.hxx> +#include <basegfx/polygon/b2dpolypolygon.hxx> +#include <basegfx/numeric/ftools.hxx> + +#include <boost/bind.hpp> + +using namespace ::basegfx; + + +namespace basegfx2d +{ + +class genericclipper : public CppUnit::TestFixture +{ +private: + B2DPolygon aSelfIntersecting; + B2DPolygon aShiftedRectangle; + +public: + // initialise your test code values here. + void setUp() + { + aSelfIntersecting.append(B2DPoint(0, 0)); + aSelfIntersecting.append(B2DPoint(0, 100)); + aSelfIntersecting.append(B2DPoint(75, 100)); + aSelfIntersecting.append(B2DPoint(75, 50)); + aSelfIntersecting.append(B2DPoint(25, 50)); + aSelfIntersecting.append(B2DPoint(25, 150)); + aSelfIntersecting.append(B2DPoint(100,150)); + aSelfIntersecting.append(B2DPoint(100,0)); + aSelfIntersecting.setClosed(true); + + aShiftedRectangle = tools::createPolygonFromRect( + B2DRange(0,90,20,150)); + } + + void tearDown() + {} + + void validate(const char* pName, + const char* pValidSvgD, + B2DPolyPolygon (*pFunc)(const B2DPolyPolygon&, const B2DPolyPolygon&)) + { + const B2DPolyPolygon aSelfIntersect( + tools::prepareForPolygonOperation(aSelfIntersecting)); + const B2DPolyPolygon aRect( + tools::prepareForPolygonOperation(aShiftedRectangle)); +#if defined(VERBOSE) + fprintf(stderr, "%s input LHS - svg:d=\"%s\"\n", + pName, rtl::OUStringToOString( + basegfx::tools::exportToSvgD( + aSelfIntersect), + RTL_TEXTENCODING_UTF8).getStr() ); + fprintf(stderr, "%s input RHS - svg:d=\"%s\"\n", + pName, rtl::OUStringToOString( + basegfx::tools::exportToSvgD( + aRect), + RTL_TEXTENCODING_UTF8).getStr() ); +#endif + + const B2DPolyPolygon aRes= + pFunc(aSelfIntersect, aRect); + +#if defined(VERBOSE) + fprintf(stderr, "%s - svg:d=\"%s\"\n", + pName, rtl::OUStringToOString( + basegfx::tools::exportToSvgD(aRes), + RTL_TEXTENCODING_UTF8).getStr() ); +#endif + + rtl::OUString aValid=rtl::OUString::createFromAscii(pValidSvgD); + + CPPUNIT_ASSERT_MESSAGE(pName, + basegfx::tools::exportToSvgD(aRes) == aValid); + } + + void validateOr() + { + const char* pValid="m0 0h100v150h-75v-50h-5v50h-20v-50-10zm75 10v-50h-50v50z"; + validate("validateOr", pValid, &tools::solvePolygonOperationOr); + } + + void validateXor() + { + const char* pValid="m0 0h100v150h-75v-50h-5v50h-20v-50-10zm0 10h20v-10h-20zm75 10v-50h-50v50z"; + validate("validateXor", pValid, &tools::solvePolygonOperationXor); + } + + void validateAnd() + { + const char* pValid="m0 100v-10h20v10z"; + validate("validateAnd", pValid, &tools::solvePolygonOperationAnd); + } + + void validateDiff() + { + const char* pValid="m0 90v-90h100v150h-75v-50h-5v-10zm55 10v-50h-50v50z"; + validate("validateDiff", pValid, &tools::solvePolygonOperationDiff); + } + + // Change the following lines only, if you add, remove or rename + // member functions of the current class, + // because these macros are need by auto register mechanism. + + CPPUNIT_TEST_SUITE(genericclipper); + CPPUNIT_TEST(validateOr); + CPPUNIT_TEST(validateXor); + CPPUNIT_TEST(validateAnd); + CPPUNIT_TEST(validateDiff); + CPPUNIT_TEST_SUITE_END(); +}; + +// ----------------------------------------------------------------------------- +CPPUNIT_TEST_SUITE_REGISTRATION(basegfx2d::genericclipper); +} // namespace basegfx2d diff --git a/basegfx/test/makefile.mk b/basegfx/test/makefile.mk index dd92dfedaa0c..2c0f30c291a9 100644 --- a/basegfx/test/makefile.mk +++ b/basegfx/test/makefile.mk @@ -36,39 +36,33 @@ ENABLE_EXCEPTIONS=TRUE .INCLUDE : settings.mk +CFLAGSCXX += $(CPPUNIT_CFLAGS) + # --- Common ---------------------------------------------------------- SHL1OBJS= \ - $(SLO)$/basegfx1d.obj \ - $(SLO)$/basegfx2d.obj \ - $(SLO)$/basegfx3d.obj \ - $(SLO)$/testtools.obj - -# linking statically against basegfx parts -SHL1LIBS=\ - $(SLB)$/curve.lib \ - $(SLB)$/matrix.lib \ - $(SLB)$/numeric.lib \ - $(SLB)$/point.lib \ - $(SLB)$/polygon.lib \ - $(SLB)$/range.lib \ - $(SLB)$/tuple.lib \ - $(SLB)$/tools.lib \ - $(SLB)$/color.lib \ - $(SLB)$/vector.lib + $(SLO)$/basegfx1d.obj \ + $(SLO)$/basegfx2d.obj \ + $(SLO)$/basegfx3d.obj \ + $(SLO)$/boxclipper.obj \ + $(SLO)$/basegfxtools.obj \ + $(SLO)$/clipstate.obj \ + $(SLO)$/genericclipper.obj \ + $(SLO)$/testtools.obj SHL1TARGET= basegfx_tests SHL1STDLIBS= \ + $(BASEGFXLIB) \ $(SALLIB) \ $(CPPUHELPERLIB) \ - $(CPPULIB) \ - $(TESTSHL2LIB) \ + $(CPPULIB) \ $(CPPUNITLIB) SHL1IMPLIB= i$(SHL1TARGET) DEF1NAME =$(SHL1TARGET) SHL1VERSIONMAP = export.map +SHL1RPATH = NONE # END ------------------------------------------------------------------ @@ -81,13 +75,6 @@ SLOFILES=$(SHL1OBJS) .INCLUDE : target.mk .INCLUDE : _cppunit.mk -# --- Enable testshl2 execution in normal build ------------------------ - -$(MISC)$/unittest_succeeded : $(SHL1TARGETN) - @echo ---------------------------------------------------------- - @echo - start unit test on library $(SHL1TARGETN) - @echo ---------------------------------------------------------- - $(TESTSHL2) -sf $(mktmp ) -forward $(BIN)$/ $(SHL1TARGETN) - $(TOUCH) $@ - -ALLTAR : $(MISC)$/unittest_succeeded +.IF "$(verbose)"!="" || "$(VERBOSE)"!="" +CDEFS+= -DVERBOSE +.ENDIF diff --git a/basegfx/test/tests.txt b/basegfx/test/tests.txt deleted file mode 100644 index fc2d33ab51d5..000000000000 --- a/basegfx/test/tests.txt +++ /dev/null @@ -1,20 +0,0 @@ -# Jobfile -basegfx1d.b1drange -basegfx2d.b2dcubicbezier -basegfx2d.b2dhommatrix -basegfx2d.b2dhompoint -basegfx2d.b2dpoint -basegfx2d.b2dpolygon -basegfx2d.b2dpolygontools -basegfx2d.b2dpolypolygon -basegfx2d.b2dquadraticbezier -basegfx2d.b2drange -basegfx2d.b2dtuple -basegfx2d.b2dvector -basegfx3d.b3dhommatrix -basegfx3d.b3dhompoint -basegfx3d.b3dhompoint -basegfx3d.b3dpoint -basegfx3d.b3drange -basegfx3d.b3dtuple -basegfx3d.b3dvector diff --git a/canvas/inc/canvas/base/graphicdevicebase.hxx b/canvas/inc/canvas/base/graphicdevicebase.hxx index 20de68094028..6750c28e22c8 100644 --- a/canvas/inc/canvas/base/graphicdevicebase.hxx +++ b/canvas/inc/canvas/base/graphicdevicebase.hxx @@ -30,11 +30,11 @@ #include <rtl/ref.hxx> #include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> #include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/util/XUpdatable.hpp> #include <com/sun/star/rendering/XGraphicDevice.hpp> #include <com/sun/star/rendering/XColorSpace.hpp> -#include <com/sun/star/rendering/XParametricPolyPolygon2DFactory.hpp> #include <canvas/parametricpolypolygon.hxx> #include <canvas/propertysethelper.hxx> @@ -47,8 +47,7 @@ namespace canvas /** Helper template base class for XGraphicDevice implementations. This base class provides partial implementations of the - XGraphicDevice-related interface, such as - XParametricPolyPolygon2DFactory and XColorSpace. + XGraphicDevice-related interface, such as XColorSpace. This template basically interposes itself between the full interface you implement (i.e. not restricted to XGraphicDevice @@ -246,7 +245,7 @@ namespace canvas return maDeviceHelper.createVolatileAlphaBitmap( this, size ); } - virtual ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XParametricPolyPolygon2DFactory > SAL_CALL getParametricPolyPolygonFactory( ) throw (::com::sun::star::uno::RuntimeException) + virtual ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > SAL_CALL getParametricPolyPolygonFactory( ) throw (::com::sun::star::uno::RuntimeException) { return this; } @@ -265,79 +264,26 @@ namespace canvas return maDeviceHelper.enterFullScreenMode( bEnter ); } - // XParametricPolyPolygon2DFactory - virtual ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XParametricPolyPolygon2D > SAL_CALL createLinearHorizontalGradient( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< double > >& colors, const ::com::sun::star::uno::Sequence< double >& stops ) throw (::com::sun::star::lang::IllegalArgumentException, - ::com::sun::star::uno::RuntimeException) + // XMultiServiceFactory + virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL createInstance( const ::rtl::OUString& aServiceSpecifier ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) { return ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XParametricPolyPolygon2D >( - ParametricPolyPolygon::createLinearHorizontalGradient( this, - colors, - stops ) ); + ParametricPolyPolygon::create(this, + aServiceSpecifier, + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >())); } - virtual ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XParametricPolyPolygon2D > SAL_CALL createAxialHorizontalGradient( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< double > >& colors, const ::com::sun::star::uno::Sequence< double >& stops ) throw (::com::sun::star::lang::IllegalArgumentException, - ::com::sun::star::uno::RuntimeException) + virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL createInstanceWithArguments( const ::rtl::OUString& aServiceSpecifier, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& Arguments ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) { return ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XParametricPolyPolygon2D >( - ParametricPolyPolygon::createAxialHorizontalGradient( this, - colors, - stops ) ); + ParametricPolyPolygon::create(this, + aServiceSpecifier, + Arguments)); } - virtual ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XParametricPolyPolygon2D > SAL_CALL createEllipticalGradient( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< double > >& colors, const ::com::sun::star::uno::Sequence< double >& stops, const ::com::sun::star::geometry::RealRectangle2D& boundRect ) throw (::com::sun::star::lang::IllegalArgumentException, - ::com::sun::star::uno::RuntimeException) + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getAvailableServiceNames( ) throw (::com::sun::star::uno::RuntimeException) { - return ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XParametricPolyPolygon2D >( - ParametricPolyPolygon::createEllipticalGradient( this, - colors, - stops, - boundRect ) ); - } - - virtual ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XParametricPolyPolygon2D > SAL_CALL createRectangularGradient( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< double > >& colors, const ::com::sun::star::uno::Sequence< double >& stops, const ::com::sun::star::geometry::RealRectangle2D& boundRect ) throw (::com::sun::star::lang::IllegalArgumentException, - ::com::sun::star::uno::RuntimeException) - { - return ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XParametricPolyPolygon2D >( - ParametricPolyPolygon::createRectangularGradient( this, - colors, - stops, - boundRect ) ); - } - - virtual ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XParametricPolyPolygon2D > SAL_CALL createVerticalLinesHatch( const ::com::sun::star::uno::Sequence< double >& /*leftColor*/, - const ::com::sun::star::uno::Sequence< double >& /*rightColor*/ ) throw (::com::sun::star::lang::IllegalArgumentException, - ::com::sun::star::uno::RuntimeException) - { - // TODO(F1): hatch factory NYI - return ::com::sun::star::uno::Reference< - ::com::sun::star::rendering::XParametricPolyPolygon2D >(); - } - - virtual ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XParametricPolyPolygon2D > SAL_CALL createOrthogonalLinesHatch( const ::com::sun::star::uno::Sequence< double >& /*leftTopColor*/, - const ::com::sun::star::uno::Sequence< double >& /*rightBottomColor*/ ) throw (::com::sun::star::lang::IllegalArgumentException, - ::com::sun::star::uno::RuntimeException) - { - // TODO(F1): hatch factory NYI - return ::com::sun::star::uno::Reference< - ::com::sun::star::rendering::XParametricPolyPolygon2D >(); - } - - virtual ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XParametricPolyPolygon2D > SAL_CALL createThreeCrossingLinesHatch( const ::com::sun::star::uno::Sequence< double >& /*startColor*/, - const ::com::sun::star::uno::Sequence< double >& /*endColor*/ ) throw (::com::sun::star::lang::IllegalArgumentException, - ::com::sun::star::uno::RuntimeException) - { - // TODO(F1): hatch factory NYI - return ::com::sun::star::uno::Reference< - ::com::sun::star::rendering::XParametricPolyPolygon2D >(); - } - - virtual ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XParametricPolyPolygon2D > SAL_CALL createFourCrossingLinesHatch( const ::com::sun::star::uno::Sequence< double >& /*startColor*/, - const ::com::sun::star::uno::Sequence< double >& /*endColor*/ ) throw (::com::sun::star::lang::IllegalArgumentException, - ::com::sun::star::uno::RuntimeException) - { - // TODO(F1): hatch factory NYI - return ::com::sun::star::uno::Reference< - ::com::sun::star::rendering::XParametricPolyPolygon2D >(); + return ParametricPolyPolygon::getAvailableServiceNames(); } diff --git a/canvas/inc/canvas/canvastools.hxx b/canvas/inc/canvas/canvastools.hxx index de4785346909..6c9fdfee484a 100644..100755 --- a/canvas/inc/canvas/canvastools.hxx +++ b/canvas/inc/canvas/canvastools.hxx @@ -66,6 +66,7 @@ namespace com { namespace sun { namespace star { namespace rendering struct ViewState; struct IntegerBitmapLayout; class XCanvas; + struct Texture; class XIntegerBitmapColorSpace; class XPolyPolygon2D; @@ -414,28 +415,6 @@ namespace canvas */ ::basegfx::B2IRange spritePixelAreaFromB2DRange( const ::basegfx::B2DRange& rRange ); - /** This method clamps the given value to the specified range - - @param val - The value to clamp - - @param minVal - The minimal value val is allowed to attain - - @param maxVal - The maximal value val is allowed to attain - - @return the clamped value - */ - template< typename T > T clamp( T val, - T minVal, - T maxVal ) - { - return ::std::max( minVal, - ::std::min( maxVal, - val ) ); - } - /** Retrieve various internal properties of the actual canvas implementation. This method retrieves a bunch of internal, implementation- @@ -518,6 +497,18 @@ namespace canvas */ ::basegfx::B2DPolyPolygon getBoundMarksPolyPolygon( const ::basegfx::B2DRange& rRange ); + /** Calculate number of gradient "strips" to generate (takes + into account device resolution) + + @param nColorSteps + Maximal integer difference between all color stops, needed + for smooth gradient color differences + */ + int calcGradientStepCount( ::basegfx::B2DHomMatrix& rTotalTransform, + const ::com::sun::star::rendering::ViewState& viewState, + const ::com::sun::star::rendering::RenderState& renderState, + const ::com::sun::star::rendering::Texture& texture, + int nColorSteps ); /** A very simplistic map for ASCII strings and arbitrary value types. diff --git a/canvas/inc/canvas/parametricpolypolygon.hxx b/canvas/inc/canvas/parametricpolypolygon.hxx index 4bd7e14b0229..aac98a67a713 100644 --- a/canvas/inc/canvas/parametricpolypolygon.hxx +++ b/canvas/inc/canvas/parametricpolypolygon.hxx @@ -30,7 +30,7 @@ #include <com/sun/star/lang/XServiceInfo.hpp> #include <com/sun/star/rendering/XGraphicDevice.hpp> -#include <com/sun/star/rendering/XParametricPolyPolygon2DFactory.hpp> +#include <com/sun/star/rendering/XParametricPolyPolygon2D.hpp> #include <cppuhelper/compbase2.hxx> #include <comphelper/broadcasthelper.hxx> #include <basegfx/polygon/b2dpolygon.hxx> @@ -59,7 +59,6 @@ namespace canvas enum GradientType { GRADIENT_LINEAR, - GRADIENT_AXIAL, GRADIENT_ELLIPTICAL, GRADIENT_RECTANGULAR }; @@ -100,24 +99,11 @@ namespace canvas const GradientType meType; }; - static ParametricPolyPolygon* createLinearHorizontalGradient( const ::com::sun::star::uno::Reference< - ::com::sun::star::rendering::XGraphicDevice >& rDevice, - const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< double > >& colors, - const ::com::sun::star::uno::Sequence< double >& stops ); - static ParametricPolyPolygon* createAxialHorizontalGradient( const ::com::sun::star::uno::Reference< - ::com::sun::star::rendering::XGraphicDevice >& rDevice, - const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< double > >& colors, - const ::com::sun::star::uno::Sequence< double >& stops ); - static ParametricPolyPolygon* createEllipticalGradient( const ::com::sun::star::uno::Reference< - ::com::sun::star::rendering::XGraphicDevice >& rDevice, - const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< double > >& colors, - const ::com::sun::star::uno::Sequence< double >& stops, - const ::com::sun::star::geometry::RealRectangle2D& boundRect ); - static ParametricPolyPolygon* createRectangularGradient( const ::com::sun::star::uno::Reference< - ::com::sun::star::rendering::XGraphicDevice >& rDevice, - const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< double > >& colors, - const ::com::sun::star::uno::Sequence< double >& stops, - const ::com::sun::star::geometry::RealRectangle2D& boundRect ); + static ::com::sun::star::uno::Sequence< ::rtl::OUString > getAvailableServiceNames(); + static ParametricPolyPolygon* create( + const ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XGraphicDevice >& rDevice, + const ::rtl::OUString& rServiceName, + const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& rArgs ); /// Dispose all internal references virtual void SAL_CALL disposing(); @@ -140,6 +126,20 @@ namespace canvas ~ParametricPolyPolygon(); // we're a ref-counted UNO class. _We_ destroy ourselves. private: + static ParametricPolyPolygon* createLinearHorizontalGradient( const ::com::sun::star::uno::Reference< + ::com::sun::star::rendering::XGraphicDevice >& rDevice, + const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< double > >& colors, + const ::com::sun::star::uno::Sequence< double >& stops ); + static ParametricPolyPolygon* createEllipticalGradient( const ::com::sun::star::uno::Reference< + ::com::sun::star::rendering::XGraphicDevice >& rDevice, + const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< double > >& colors, + const ::com::sun::star::uno::Sequence< double >& stops, + double fAspect ); + static ParametricPolyPolygon* createRectangularGradient( const ::com::sun::star::uno::Reference< + ::com::sun::star::rendering::XGraphicDevice >& rDevice, + const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< double > >& colors, + const ::com::sun::star::uno::Sequence< double >& stops, + double fAspect ); /// Private, because objects can only be created from the static factories ParametricPolyPolygon( const ::com::sun::star::uno::Reference< diff --git a/canvas/prj/build.lst b/canvas/prj/build.lst index 28e8524a9b38..cacbdb5bb894 100644 --- a/canvas/prj/build.lst +++ b/canvas/prj/build.lst @@ -7,5 +7,4 @@ cv canvas\source\simplecanvas nmake - all cv_simplecanvas cv_tools cv_inc cv canvas\source\cairo nmake - all cv_cairo cv_tools cv_inc NULL cv canvas\source\directx nmake - w cv_directx cv_tools cv_inc NULL cv canvas\source\null nmake - all cv_null cv_tools cv_inc NULL -cv canvas\source\java nmake - all cv_java cv_inc NULL cv canvas\source\factory nmake - all cv_factory cv_inc NULL diff --git a/canvas/source/cairo/cairo_canvas.hxx b/canvas/source/cairo/cairo_canvas.hxx index 26e2904cf71f..bbcb89c54c7d 100644 --- a/canvas/source/cairo/cairo_canvas.hxx +++ b/canvas/source/cairo/cairo_canvas.hxx @@ -41,7 +41,6 @@ #include <com/sun/star/rendering/XIntegerBitmap.hpp> #include <com/sun/star/rendering/XGraphicDevice.hpp> #include <com/sun/star/rendering/XBufferController.hpp> -#include <com/sun/star/rendering/XParametricPolyPolygon2DFactory.hpp> #include <cppuhelper/compbase7.hxx> #include <comphelper/uno3.hxx> @@ -65,7 +64,7 @@ namespace cairocanvas typedef ::cppu::WeakComponentImplHelper7< ::com::sun::star::rendering::XBitmapCanvas, ::com::sun::star::rendering::XIntegerBitmap, ::com::sun::star::rendering::XGraphicDevice, - ::com::sun::star::rendering::XParametricPolyPolygon2DFactory, + ::com::sun::star::lang::XMultiServiceFactory, ::com::sun::star::util::XUpdatable, ::com::sun::star::beans::XPropertySet, ::com::sun::star::lang::XServiceName > GraphicDeviceBase_Base; diff --git a/canvas/source/cairo/cairo_canvashelper.cxx b/canvas/source/cairo/cairo_canvashelper.cxx index 17d187d46b27..eec6a09fb215 100644 --- a/canvas/source/cairo/cairo_canvashelper.cxx +++ b/canvas/source/cairo/cairo_canvashelper.cxx @@ -53,6 +53,8 @@ #include <basegfx/polygon/b2dpolypolygon.hxx> #include <basegfx/polygon/b2dpolygontools.hxx> #include <basegfx/tools/canvastools.hxx> +#include <basegfx/tools/keystoplerp.hxx> +#include <basegfx/tools/lerp.hxx> #include <comphelper/sequence.hxx> #include <cppuhelper/compbase1.hxx> @@ -70,6 +72,7 @@ #include "cairo_canvashelper.hxx" #include "cairo_canvasbitmap.hxx" +#include <boost/tuple/tuple.hpp> #include <algorithm> using namespace ::cairo; @@ -119,9 +122,29 @@ namespace cairocanvas mpCairo = pSurface->getCairo(); } + static void setColor( Cairo* pCairo, + const uno::Sequence<double>& rColor ) + { + if( rColor.getLength() > 3 ) + { + const double alpha = rColor[3]; + + cairo_set_source_rgba( pCairo, + alpha*rColor[0], + alpha*rColor[1], + alpha*rColor[2], + alpha ); + } + else if( rColor.getLength() == 3 ) + cairo_set_source_rgb( pCairo, + rColor[0], + rColor[1], + rColor[2] ); + } + void CanvasHelper::useStates( const rendering::ViewState& viewState, const rendering::RenderState& renderState, - bool setColor ) + bool bSetColor ) { Matrix aViewMatrix; Matrix aRenderMatrix; @@ -155,19 +178,8 @@ namespace cairocanvas OSL_TRACE ("render clip END"); } - if( setColor ) { - if( renderState.DeviceColor.getLength() > 3 ) - cairo_set_source_rgba( mpCairo.get(), - renderState.DeviceColor [0], - renderState.DeviceColor [1], - renderState.DeviceColor [2], - renderState.DeviceColor [3] ); - else if (renderState.DeviceColor.getLength() == 3) - cairo_set_source_rgb( mpCairo.get(), - renderState.DeviceColor [0], - renderState.DeviceColor [1], - renderState.DeviceColor [2] ); - } + if( bSetColor ) + setColor(mpCairo.get(),renderState.DeviceColor); cairo_operator_t compositingMode( CAIRO_OPERATOR_OVER ); switch( renderState.CompositeOperation ) @@ -662,11 +674,33 @@ namespace cairocanvas double alpha = rColor[3]; // cairo expects premultiplied alpha cairo_pattern_add_color_stop_rgba( pPattern, stop, rColor[0]*alpha, rColor[1]*alpha, rColor[2]*alpha, alpha ); - //cairo_pattern_add_color_stop_rgba( pPattern, stop, rColor[0], rColor[1], rColor[2], alpha ); } } } + static uno::Sequence<double> lerp(const uno::Sequence<double>& rLeft, const uno::Sequence<double>& rRight, double fAlpha) + { + if( rLeft.getLength() == 3 ) + { + uno::Sequence<double> aRes(3); + aRes[0] = basegfx::tools::lerp(rLeft[0],rRight[0],fAlpha); + aRes[1] = basegfx::tools::lerp(rLeft[1],rRight[1],fAlpha); + aRes[2] = basegfx::tools::lerp(rLeft[2],rRight[2],fAlpha); + return aRes; + } + else if( rLeft.getLength() == 4 ) + { + uno::Sequence<double> aRes(4); + aRes[0] = basegfx::tools::lerp(rLeft[0],rRight[0],fAlpha); + aRes[1] = basegfx::tools::lerp(rLeft[1],rRight[1],fAlpha); + aRes[2] = basegfx::tools::lerp(rLeft[2],rRight[2],fAlpha); + aRes[3] = basegfx::tools::lerp(rLeft[3],rRight[3],fAlpha); + return aRes; + } + + return uno::Sequence<double>(); + } + static Pattern* patternFromParametricPolyPolygon( ::canvas::ParametricPolyPolygon& rPolygon ) { Pattern* pPattern = NULL; @@ -675,7 +709,6 @@ namespace cairocanvas // undef macros from vclenum.hxx which conflicts with GradientType enum values #undef GRADIENT_LINEAR -#undef GRADIENT_AXIAL #undef GRADIENT_ELLIPTICAL switch( aValues.meType ) { @@ -688,26 +721,17 @@ namespace cairocanvas addColorStops( pPattern, aValues.maColors, aValues.maStops ); break; - // FIXME: NYI - case ::canvas::ParametricPolyPolygon::GRADIENT_RECTANGULAR: - case ::canvas::ParametricPolyPolygon::GRADIENT_AXIAL: - x0 = 0; - y0 = 0; - x1 = 1; - y1 = 0; - pPattern = cairo_pattern_create_linear( x0, y0, x1, y1 ); - addColorStops( pPattern, aValues.maColors, aValues.maStops ); - break; - case ::canvas::ParametricPolyPolygon::GRADIENT_ELLIPTICAL: - cx = 0.5; - cy = 0.5; + cx = 0; + cy = 0; r0 = 0; - r1 = 0.5; + r1 = 1; - pPattern = cairo_pattern_create_radial( cx, cy, r0, cx, cy, r1 ); + pPattern = cairo_pattern_create_radial( cx, cy, r0, cy, cy, r1 ); addColorStops( pPattern, aValues.maColors, aValues.maStops, true ); break; + default: + break; } return pPattern; @@ -716,7 +740,8 @@ namespace cairocanvas static void doOperation( Operation aOperation, Cairo* pCairo, const uno::Sequence< rendering::Texture >* pTextures, - const SurfaceProviderRef& pDevice ) + const SurfaceProviderRef& pDevice, + const basegfx::B2DRange& rBounds ) { switch( aOperation ) { case Fill: @@ -751,7 +776,20 @@ namespace cairocanvas if( aTexture.RepeatModeX == rendering::TexturingMode::REPEAT && aTexture.RepeatModeY == rendering::TexturingMode::REPEAT ) + { cairo_pattern_set_extend( pPattern, CAIRO_EXTEND_REPEAT ); + } + else if ( aTexture.RepeatModeX == rendering::TexturingMode::NONE && + aTexture.RepeatModeY == rendering::TexturingMode::NONE ) + { + cairo_pattern_set_extend( pPattern, CAIRO_EXTEND_NONE ); + } + else if ( aTexture.RepeatModeX == rendering::TexturingMode::CLAMP && + aTexture.RepeatModeY == rendering::TexturingMode::CLAMP ) + { + cairo_pattern_set_extend( pPattern, CAIRO_EXTEND_PAD ); + } + aScaledTextureMatrix.x0 = basegfx::fround( aScaledTextureMatrix.x0 ); aScaledTextureMatrix.y0 = basegfx::fround( aScaledTextureMatrix.y0 ); cairo_pattern_set_matrix( pPattern, &aScaledTextureMatrix ); @@ -787,19 +825,70 @@ namespace cairocanvas cairo_matrix_init( &aTextureMatrix, aTransform.m00, aTransform.m10, aTransform.m01, aTransform.m11, aTransform.m02, aTransform.m12); - Pattern* pPattern = patternFromParametricPolyPolygon( *pPolyImpl ); + if( pPolyImpl->getValues().meType == canvas::ParametricPolyPolygon::GRADIENT_RECTANGULAR ) + { + // no general path gradient yet in cairo; emulate then + cairo_save( pCairo ); + cairo_clip( pCairo ); + + // fill bound rect with start color + cairo_rectangle( pCairo, rBounds.getMinX(), rBounds.getMinY(), + rBounds.getWidth(), rBounds.getHeight() ); + setColor(pCairo,pPolyImpl->getValues().maColors[0]); + cairo_fill(pCairo); + + cairo_transform( pCairo, &aTextureMatrix ); + + // longest line in gradient bound rect + const unsigned int nGradientSize( + static_cast<unsigned int>( + ::basegfx::B2DVector(rBounds.getMinimum() - rBounds.getMaximum()).getLength() + 1.0 ) ); + + // typical number for pixel of the same color (strip size) + const unsigned int nStripSize( nGradientSize < 50 ? 2 : 4 ); + + // use at least three steps, and at utmost the number of color + // steps + const unsigned int nStepCount( + ::std::max( + 3U, + ::std::min( + nGradientSize / nStripSize, + 128U )) + 1 ); + + const uno::Sequence<double>* pColors=&pPolyImpl->getValues().maColors[0]; + basegfx::tools::KeyStopLerp aLerper(pPolyImpl->getValues().maStops); + for( unsigned int i=1; i<nStepCount; ++i ) + { + const double fT( i/double(nStepCount) ); - if( pPattern ) { - OSL_TRACE( "filling with pattern" ); + std::ptrdiff_t nIndex; + double fAlpha; + boost::tuples::tie(nIndex,fAlpha)=aLerper.lerp(fT); - cairo_save( pCairo ); + setColor(pCairo, lerp(pColors[nIndex], pColors[nIndex+1], fAlpha)); + cairo_rectangle( pCairo, -1+fT, -1+fT, 2-2*fT, 2-2*fT ); + cairo_fill(pCairo); + } - cairo_transform( pCairo, &aTextureMatrix ); - cairo_set_source( pCairo, pPattern ); - cairo_fill( pCairo ); cairo_restore( pCairo ); + } + else + { + Pattern* pPattern = patternFromParametricPolyPolygon( *pPolyImpl ); + + if( pPattern ) { + OSL_TRACE( "filling with pattern" ); - cairo_pattern_destroy( pPattern ); + cairo_save( pCairo ); + + cairo_transform( pCairo, &aTextureMatrix ); + cairo_set_source( pCairo, pPattern ); + cairo_fill( pCairo ); + cairo_restore( pCairo ); + + cairo_pattern_destroy( pPattern ); + } } } } @@ -932,7 +1021,7 @@ namespace cairocanvas if( aOperation == Fill && pTextures ) { cairo_set_matrix( pCairo, &aOrigMatrix ); - doOperation( aOperation, pCairo, pTextures, pDevice ); + doOperation( aOperation, pCairo, pTextures, pDevice, aPolyPolygon.getB2DRange() ); cairo_set_matrix( pCairo, &aIdentityMatrix ); } } else { @@ -945,7 +1034,7 @@ namespace cairocanvas } } if( bOpToDo && ( aOperation != Fill || !pTextures ) ) - doOperation( aOperation, pCairo, pTextures, pDevice ); + doOperation( aOperation, pCairo, pTextures, pDevice, aPolyPolygon.getB2DRange() ); cairo_set_matrix( pCairo, &aOrigMatrix ); @@ -980,11 +1069,11 @@ namespace cairocanvas aEdge.append(aCandidate.getB2DPoint(0)); aEdge.append(basegfx::B2DPoint(0.0, 0.0)); - for(sal_uInt32 a(0); a < nEdgeCount; a++) + for(sal_uInt32 b(0); b < nEdgeCount; b++) { - const sal_uInt32 nNextIndex((a + 1) % nPointCount); + const sal_uInt32 nNextIndex((b + 1) % nPointCount); aEdge.setB2DPoint(1, aCandidate.getB2DPoint(nNextIndex)); - aEdge.setNextControlPoint(0, aCandidate.getNextControlPoint(a)); + aEdge.setNextControlPoint(0, aCandidate.getNextControlPoint(b)); aEdge.setPrevControlPoint(1, aCandidate.getPrevControlPoint(nNextIndex)); doPolyPolygonImplementation( basegfx::B2DPolyPolygon(aEdge), @@ -1209,12 +1298,12 @@ namespace cairocanvas const rendering::ViewState& viewState, const rendering::RenderState& renderState, const geometry::IntegerSize2D& rSize, - bool /*bModulateColors*/, + bool bModulateColors, bool bHasAlpha ) { SurfaceSharedPtr pSurface=pInputSurface; uno::Reference< rendering::XCachedPrimitive > rv = uno::Reference< rendering::XCachedPrimitive >(NULL); - geometry::IntegerSize2D aBitmapSize = rSize; + geometry::IntegerSize2D aBitmapSize = rSize; if( mpCairo ) { cairo_save( mpCairo.get() ); @@ -1236,38 +1325,38 @@ namespace cairocanvas ::rtl::math::approxEqual( aMatrix.y0, 0 ) && basegfx::fround( rSize.Width * aMatrix.xx ) > 8 && basegfx::fround( rSize.Height* aMatrix.yy ) > 8 ) - { - double dWidth, dHeight; - - dWidth = basegfx::fround( rSize.Width * aMatrix.xx ); - dHeight = basegfx::fround( rSize.Height* aMatrix.yy ); - aBitmapSize.Width = static_cast<sal_Int32>( dWidth ); - aBitmapSize.Height = static_cast<sal_Int32>( dHeight ); - - SurfaceSharedPtr pScaledSurface = mpSurfaceProvider->createSurface( - ::basegfx::B2ISize( aBitmapSize.Width, aBitmapSize.Height ), - bHasAlpha ? CAIRO_CONTENT_COLOR_ALPHA : CAIRO_CONTENT_COLOR ); - CairoSharedPtr pCairo = pScaledSurface->getCairo(); - - cairo_set_operator( pCairo.get(), CAIRO_OPERATOR_SOURCE ); - // add 0.5px to size to avoid rounding errors in cairo, leading sometimes to random data on the image right/bottom borders - cairo_scale( pCairo.get(), (dWidth+0.5)/rSize.Width, (dHeight+0.5)/rSize.Height ); - cairo_set_source_surface( pCairo.get(), pSurface->getCairoSurface().get(), 0, 0 ); - cairo_paint( pCairo.get() ); - - pSurface = pScaledSurface; - - aMatrix.xx = aMatrix.yy = 1; - cairo_set_matrix( mpCairo.get(), &aMatrix ); - - rv = uno::Reference< rendering::XCachedPrimitive >( - new CachedBitmap( pSurface, viewState, renderState, - // cast away const, need to - // change refcount (as this is - // ~invisible to client code, - // still logically const) - const_cast< rendering::XCanvas* >(pCanvas)) ); - } + { + double dWidth, dHeight; + + dWidth = basegfx::fround( rSize.Width * aMatrix.xx ); + dHeight = basegfx::fround( rSize.Height* aMatrix.yy ); + aBitmapSize.Width = static_cast<sal_Int32>( dWidth ); + aBitmapSize.Height = static_cast<sal_Int32>( dHeight ); + + SurfaceSharedPtr pScaledSurface = mpSurfaceProvider->createSurface( + ::basegfx::B2ISize( aBitmapSize.Width, aBitmapSize.Height ), + bHasAlpha ? CAIRO_CONTENT_COLOR_ALPHA : CAIRO_CONTENT_COLOR ); + CairoSharedPtr pCairo = pScaledSurface->getCairo(); + + cairo_set_operator( pCairo.get(), CAIRO_OPERATOR_SOURCE ); + // add 0.5px to size to avoid rounding errors in cairo, leading sometimes to random data on the image right/bottom borders + cairo_scale( pCairo.get(), (dWidth+0.5)/rSize.Width, (dHeight+0.5)/rSize.Height ); + cairo_set_source_surface( pCairo.get(), pSurface->getCairoSurface().get(), 0, 0 ); + cairo_paint( pCairo.get() ); + + pSurface = pScaledSurface; + + aMatrix.xx = aMatrix.yy = 1; + cairo_set_matrix( mpCairo.get(), &aMatrix ); + + rv = uno::Reference< rendering::XCachedPrimitive >( + new CachedBitmap( pSurface, viewState, renderState, + // cast away const, need to + // change refcount (as this is + // ~invisible to client code, + // still logically const) + const_cast< rendering::XCanvas* >(pCanvas)) ); + } if( !bHasAlpha && mbHaveAlpha ) { @@ -1308,7 +1397,11 @@ namespace cairocanvas cairo_set_operator( mpCairo.get(), CAIRO_OPERATOR_SOURCE ); cairo_rectangle( mpCairo.get(), 0, 0, aBitmapSize.Width, aBitmapSize.Height ); cairo_clip( mpCairo.get() ); - cairo_paint( mpCairo.get() ); + + if( bModulateColors ) + cairo_paint_with_alpha( mpCairo.get(), renderState.DeviceColor[3] ); + else + cairo_paint( mpCairo.get() ); cairo_restore( mpCairo.get() ); } else OSL_TRACE ("CanvasHelper called after it was disposed"); @@ -1347,15 +1440,35 @@ namespace cairocanvas return rv; } - uno::Reference< rendering::XCachedPrimitive > CanvasHelper::drawBitmapModulated( const rendering::XCanvas* , - const uno::Reference< rendering::XBitmap >& /*xBitmap*/, - const rendering::ViewState& /*viewState*/, - const rendering::RenderState& /*renderState*/ ) + uno::Reference< rendering::XCachedPrimitive > CanvasHelper::drawBitmapModulated( const rendering::XCanvas* pCanvas, + const uno::Reference< rendering::XBitmap >& xBitmap, + const rendering::ViewState& viewState, + const rendering::RenderState& renderState ) { - // TODO(F3): Implement modulated bitmap! +#ifdef CAIRO_CANVAS_PERF_TRACE + struct timespec aTimer; + mxDevice->startPerfTrace( &aTimer ); +#endif - // TODO(P1): Provide caching here. - return uno::Reference< rendering::XCachedPrimitive >(NULL); + uno::Reference< rendering::XCachedPrimitive > rv; + unsigned char* data = NULL; + bool bHasAlpha = false; + SurfaceSharedPtr pSurface = surfaceFromXBitmap( xBitmap, mpSurfaceProvider, data, bHasAlpha ); + geometry::IntegerSize2D aSize = xBitmap->getSize(); + + if( pSurface ) { + rv = implDrawBitmapSurface( pCanvas, pSurface, viewState, renderState, aSize, true, bHasAlpha ); + + if( data ) + free( data ); + } else + rv = uno::Reference< rendering::XCachedPrimitive >(NULL); + +#ifdef CAIRO_CANVAS_PERF_TRACE + mxDevice->stopPerfTrace( &aTimer, "drawBitmap" ); +#endif + + return rv; } uno::Reference< rendering::XGraphicDevice > CanvasHelper::getDevice() @@ -1678,12 +1791,12 @@ namespace cairocanvas rendering::RGBColor* pOut( aRes.getArray() ); for( sal_Size i=0; i<nLen; i+=4 ) { - const sal_Int8 nAlpha(pIn[3]); - if( nAlpha ) + const double fAlpha((sal_uInt8)pIn[3]); + if( fAlpha ) *pOut++ = rendering::RGBColor( - vcl::unotools::toDoubleColor(pIn[2]/nAlpha), - vcl::unotools::toDoubleColor(pIn[1]/nAlpha), - vcl::unotools::toDoubleColor(pIn[0]/nAlpha)); + pIn[2]/fAlpha, + pIn[1]/fAlpha, + pIn[0]/fAlpha); else *pOut++ = rendering::RGBColor(0,0,0); pIn += 4; @@ -1703,13 +1816,13 @@ namespace cairocanvas rendering::ARGBColor* pOut( aRes.getArray() ); for( sal_Size i=0; i<nLen; i+=4 ) { - const sal_Int8 nAlpha(pIn[3]); - if( nAlpha ) + const double fAlpha((sal_uInt8)pIn[3]); + if( fAlpha ) *pOut++ = rendering::ARGBColor( - vcl::unotools::toDoubleColor(nAlpha), - vcl::unotools::toDoubleColor(pIn[2]/nAlpha), - vcl::unotools::toDoubleColor(pIn[1]/nAlpha), - vcl::unotools::toDoubleColor(pIn[0]/nAlpha)); + fAlpha/255.0, + pIn[2]/fAlpha, + pIn[1]/fAlpha, + pIn[0]/fAlpha); else *pOut++ = rendering::ARGBColor(0,0,0,0); pIn += 4; diff --git a/canvas/source/cairo/cairo_spritecanvas.hxx b/canvas/source/cairo/cairo_spritecanvas.hxx index 0c942cac1ed3..fcc0ae76839b 100644 --- a/canvas/source/cairo/cairo_spritecanvas.hxx +++ b/canvas/source/cairo/cairo_spritecanvas.hxx @@ -39,7 +39,6 @@ #include <com/sun/star/rendering/XIntegerBitmap.hpp> #include <com/sun/star/rendering/XGraphicDevice.hpp> #include <com/sun/star/rendering/XBufferController.hpp> -#include <com/sun/star/rendering/XParametricPolyPolygon2DFactory.hpp> #include <cppuhelper/compbase9.hxx> #include <comphelper/uno3.hxx> @@ -63,7 +62,7 @@ namespace cairocanvas typedef ::cppu::WeakComponentImplHelper9< ::com::sun::star::rendering::XSpriteCanvas, ::com::sun::star::rendering::XIntegerBitmap, ::com::sun::star::rendering::XGraphicDevice, - ::com::sun::star::rendering::XParametricPolyPolygon2DFactory, + ::com::sun::star::lang::XMultiServiceFactory, ::com::sun::star::rendering::XBufferController, ::com::sun::star::awt::XWindowListener, ::com::sun::star::util::XUpdatable, diff --git a/canvas/source/cairo/exports.map b/canvas/source/cairo/exports.map deleted file mode 100644 index 4101b0d761a9..000000000000 --- a/canvas/source/cairo/exports.map +++ /dev/null @@ -1,8 +0,0 @@ -CAN_1_0 { - global: - component_getImplementationEnvironment; - component_writeInfo; - component_getFactory; - local: - *; -}; diff --git a/canvas/source/cairo/makefile.mk b/canvas/source/cairo/makefile.mk index 2c568a4efdbd..b0ff10fe96b0 100644 --- a/canvas/source/cairo/makefile.mk +++ b/canvas/source/cairo/makefile.mk @@ -87,7 +87,7 @@ SHL1STDLIBS= $(CPPULIB) $(TKLIB) $(SALLIB) $(VCLLIB) $(COMPHELPERLIB) $(CPPUHELP .IF "$(SYSTEM_CAIRO)" == "YES" SHL1STDLIBS+= $(CAIRO_LIBS) .ELSE -SHL1STDLIBS+= -lcairo +SHL1STDLIBS+= -lcairo -lpixman-1 .ENDIF .IF "$(GUIBASE)"=="aqua" @@ -98,7 +98,7 @@ CFLAGSCXX+=$(OBJCXXFLAGS) # Xlib SLOFILES+= $(SLO)$/cairo_xlib_cairo.obj -SHL1STDLIBS+= -lfontconfig -lX11 -lXrender -lpixman-1 $(FREETYPE_LIBS) +SHL1STDLIBS+= -lfontconfig -lX11 -lXrender $(FREETYPE_LIBS) CFLAGS+=$(FREETYPE_CFLAGS) .ENDIF # "$(GUIBASE)"=="aqua" @@ -121,7 +121,7 @@ SHL1IMPLIB=i$(TARGET) SHL1LIBS=$(SLB)$/$(TARGET).lib SHL1DEF=$(MISC)$/$(SHL1TARGET).def -SHL1VERSIONMAP=exports.map +SHL1VERSIONMAP=$(SOLARENV)/src/component.map DEF1NAME=$(SHL1TARGET) DEF1EXPORTFILE=exports.dxp diff --git a/canvas/source/directx/dx_canvas.hxx b/canvas/source/directx/dx_canvas.hxx index aca9873387dc..be15b875c4b6 100644 --- a/canvas/source/directx/dx_canvas.hxx +++ b/canvas/source/directx/dx_canvas.hxx @@ -38,7 +38,6 @@ #include <com/sun/star/rendering/XIntegerBitmap.hpp> #include <com/sun/star/rendering/XGraphicDevice.hpp> #include <com/sun/star/rendering/XBufferController.hpp> -#include <com/sun/star/rendering/XParametricPolyPolygon2DFactory.hpp> #include <cppuhelper/compbase7.hxx> #include <cppuhelper/compbase6.hxx> @@ -59,7 +58,7 @@ namespace dxcanvas { typedef ::cppu::WeakComponentImplHelper6< ::com::sun::star::rendering::XCanvas, ::com::sun::star::rendering::XGraphicDevice, - ::com::sun::star::rendering::XParametricPolyPolygon2DFactory, + ::com::sun::star::lang::XMultiServiceFactory, ::com::sun::star::util::XUpdatable, ::com::sun::star::beans::XPropertySet, ::com::sun::star::lang::XServiceName > GraphicDeviceBase1_Base; @@ -116,7 +115,7 @@ namespace dxcanvas typedef ::cppu::WeakComponentImplHelper7< ::com::sun::star::rendering::XBitmapCanvas, ::com::sun::star::rendering::XIntegerBitmap, ::com::sun::star::rendering::XGraphicDevice, - ::com::sun::star::rendering::XParametricPolyPolygon2DFactory, + ::com::sun::star::lang::XMultiServiceFactory, ::com::sun::star::util::XUpdatable, ::com::sun::star::beans::XPropertySet, ::com::sun::star::lang::XServiceName > GraphicDeviceBase2_Base; diff --git a/canvas/source/directx/dx_canvashelper_texturefill.cxx b/canvas/source/directx/dx_canvashelper_texturefill.cxx index 026545d6c339..60d62dad338a 100755 --- a/canvas/source/directx/dx_canvashelper_texturefill.cxx +++ b/canvas/source/directx/dx_canvashelper_texturefill.cxx @@ -38,7 +38,10 @@ #include <basegfx/point/b2dpoint.hxx> #include <basegfx/range/b2drectangle.hxx> #include <basegfx/numeric/ftools.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> #include <basegfx/tools/tools.hxx> +#include <basegfx/tools/lerp.hxx> +#include <basegfx/tools/keystoplerp.hxx> #include <basegfx/tools/canvastools.hxx> #include <basegfx/matrix/b2dhommatrixtools.hxx> @@ -49,6 +52,8 @@ #include "dx_impltools.hxx" #include <boost/scoped_ptr.hpp> +#include <boost/bind.hpp> +#include <boost/tuple/tuple.hpp> using namespace ::com::sun::star; @@ -59,26 +64,31 @@ namespace dxcanvas { typedef ::boost::shared_ptr< Gdiplus::PathGradientBrush > PathGradientBrushSharedPtr; - bool fillLinearGradient( GraphicsSharedPtr& rGraphics, - const Gdiplus::Color& rColor1, - const Gdiplus::Color& rColor2, - const GraphicsPathSharedPtr& rFillPath, - const rendering::Texture& texture ) + bool fillLinearGradient( GraphicsSharedPtr& rGraphics, + const ::canvas::ParametricPolyPolygon::Values& /*rValues*/, + const std::vector< Gdiplus::Color >& rColors, + const std::vector< Gdiplus::REAL >& rStops, + const GraphicsPathSharedPtr& rFillPath, + const rendering::Texture& texture ) { - // setup a linear gradient with two colors - // --------------------------------------- + // setup a linear gradient with given colors + // ----------------------------------------- Gdiplus::LinearGradientBrush aBrush( Gdiplus::PointF(0.0f, 0.5f), Gdiplus::PointF(1.0f, 0.5f), - rColor1, - rColor2 ); + rColors[0], + rColors[1] ); + + aBrush.SetInterpolationColors(&rColors[0], + &rStops[0], + rColors.size()); // render background color, as LinearGradientBrush does not // properly support the WrapModeClamp repeat mode - Gdiplus::SolidBrush aBackgroundBrush( rColor1 ); + Gdiplus::SolidBrush aBackgroundBrush( rColors[0] ); rGraphics->FillPath( &aBackgroundBrush, rFillPath.get() ); // TODO(F2): This does not yet support other repeat modes @@ -152,7 +162,7 @@ namespace dxcanvas return false; } - Gdiplus::SolidBrush aBackgroundBrush2( rColor2 ); + Gdiplus::SolidBrush aBackgroundBrush2( rColors.back() ); rGraphics->FillPath( &aBackgroundBrush2, &aSolidFillPath ); // generate clip polygon from the extended parallelogram @@ -188,167 +198,33 @@ namespace dxcanvas return true; } - bool fillAxialGradient( GraphicsSharedPtr& rGraphics, - const Gdiplus::Color& rColor1, - const Gdiplus::Color& rColor2, - const GraphicsPathSharedPtr& rFillPath, - const rendering::Texture& texture ) + int numColorSteps( const Gdiplus::Color& rColor1, const Gdiplus::Color& rColor2 ) { - // setup a linear gradient with three colors - // ----------------------------------------- - - Gdiplus::LinearGradientBrush aBrush( - Gdiplus::PointF(0.0f, - 0.5f), - Gdiplus::PointF(1.0f, - 0.5f), - rColor1, - rColor1 ); - - Gdiplus::Color aColors[] = - { - rColor1, // at 0.0 - rColor2, // at 0.5 - rColor1 // at 1.0 - }; - - Gdiplus::REAL aPositions[] = - { - 0.0, - 0.5, - 1.0 - }; - - if( Gdiplus::Ok != aBrush.SetInterpolationColors( aColors, - aPositions, - sizeof( aPositions ) / sizeof(Gdiplus::REAL) ) ) - { - return false; - } - - // render background color, as LinearGradientBrush does not - // properly support the WrapModeClamp repeat mode - Gdiplus::SolidBrush aBackgroundBrush( rColor1 ); - rGraphics->FillPath( &aBackgroundBrush, rFillPath.get() ); - - // TODO(F2): This does not yet support other repeat modes - // except clamp, and probably also no multi-texturing - - // calculate parallelogram of gradient in object space, extend - // top and bottom of it such that they cover the whole fill - // path bound area - ::basegfx::B2DHomMatrix aTextureTransform; - ::basegfx::unotools::homMatrixFromAffineMatrix( aTextureTransform, - texture.AffineTransform ); - - ::basegfx::B2DPoint aLeftTop( 0.0, 0.0 ); - ::basegfx::B2DPoint aLeftBottom( 0.0, 1.0 ); - ::basegfx::B2DPoint aRightTop( 1.0, 0.0 ); - ::basegfx::B2DPoint aRightBottom( 1.0, 1.0 ); - - aLeftTop *= aTextureTransform; - aLeftBottom *= aTextureTransform; - aRightTop *= aTextureTransform; - aRightBottom*= aTextureTransform; - - Gdiplus::RectF aBounds; - rFillPath->GetBounds( &aBounds, NULL, NULL ); - - // now, we potentially have to enlarge our gradient area - // atop and below the transformed [0,1]x[0,1] unit rect, - // for the gradient to fill the complete bound rect. - ::basegfx::tools::infiniteLineFromParallelogram( aLeftTop, - aLeftBottom, - aRightTop, - aRightBottom, - tools::b2dRangeFromGdiPlusRectF( aBounds ) ); - - // generate clip polygon from the extended parallelogram - // (exploit the feature that distinct lines in a figure are - // automatically closed by a straight line) - Gdiplus::GraphicsPath aClipPath; - aClipPath.AddLine( static_cast<Gdiplus::REAL>(aLeftTop.getX()), - static_cast<Gdiplus::REAL>(aLeftTop.getY()), - static_cast<Gdiplus::REAL>(aRightTop.getX()), - static_cast<Gdiplus::REAL>(aRightTop.getY()) ); - aClipPath.AddLine( static_cast<Gdiplus::REAL>(aRightBottom.getX()), - static_cast<Gdiplus::REAL>(aRightBottom.getY()), - static_cast<Gdiplus::REAL>(aLeftBottom.getX()), - static_cast<Gdiplus::REAL>(aLeftBottom.getY()) ); - aClipPath.CloseFigure(); - - // limit output to a _single_ strip of the gradient (have to - // clip here, since GDI+ wrapmode clamp does not work here) - if( Gdiplus::Ok != rGraphics->SetClip( rFillPath.get(), - Gdiplus::CombineModeIntersect ) ) - { - return false; - } - if( Gdiplus::Ok != rGraphics->SetClip( &aClipPath, - Gdiplus::CombineModeIntersect ) ) - { - return false; - } - - // now, finally, output the gradient - Gdiplus::Matrix aMatrix; - tools::gdiPlusMatrixFromAffineMatrix2D( aMatrix, - texture.AffineTransform ); - aBrush.SetTransform( &aMatrix ); - - rGraphics->FillRectangle( &aBrush, aBounds ); - - return true; - } - - PathGradientBrushSharedPtr createPathGradientBrush( const GraphicsPathSharedPtr& rGradientPath, - const Gdiplus::Color& rColor1, - const Gdiplus::Color& rColor2 ) - { - PathGradientBrushSharedPtr pGradientBrush( - new Gdiplus::PathGradientBrush( rGradientPath.get() ) ); - - Gdiplus::Color aColors[] = - { - rColor1 - }; - - INT nCount(1); - - pGradientBrush->SetSurroundColors( aColors, - &nCount ); - pGradientBrush->SetCenterColor( rColor2 ); - - return pGradientBrush; + return ::std::max( + labs( rColor1.GetRed() - rColor2.GetRed() ), + ::std::max( + labs( rColor1.GetGreen() - rColor2.GetGreen() ), + labs( rColor1.GetBlue() - rColor2.GetBlue() ) ) ); } bool fillPolygonalGradient( const ::canvas::ParametricPolyPolygon::Values& rValues, + const std::vector< Gdiplus::Color >& rColors, + const std::vector< Gdiplus::REAL >& rStops, GraphicsSharedPtr& rGraphics, - const Gdiplus::Color& rColor1, - const Gdiplus::Color& rColor2, const GraphicsPathSharedPtr& rPath, + const rendering::ViewState& viewState, + const rendering::RenderState& renderState, const rendering::Texture& texture ) { - Gdiplus::Matrix aMatrix; - tools::gdiPlusMatrixFromAffineMatrix2D( aMatrix, - texture.AffineTransform ); - // copy original fill path object, might have to change it // below GraphicsPathSharedPtr pFillPath( rPath ); - - // clone original gradient path object, we need to change it - // below - GraphicsPathSharedPtr pGradientPath( - tools::graphicsPathFromB2DPolygon( rValues.maGradientPoly ) ); - - ENSURE_OR_RETURN_FALSE( pGradientPath.get(), - "ParametricPolyPolygon::fillPolygonalGradient(): Could not clone path" ); + const ::basegfx::B2DPolygon& rGradientPoly( rValues.maGradientPoly ); PathGradientBrushSharedPtr pGradientBrush; // fill background uniformly with end color - Gdiplus::SolidBrush aBackgroundBrush( rColor1 ); + Gdiplus::SolidBrush aBackgroundBrush( rColors[0] ); rGraphics->FillPath( &aBackgroundBrush, pFillPath.get() ); // scale focus according to aspect ratio: for wider-than-tall @@ -377,8 +253,6 @@ namespace dxcanvas return false; } - rGraphics->MultiplyTransform( &aMatrix ); - // disable anti-aliasing, if any const Gdiplus::SmoothingMode eOldAAMode( rGraphics->GetSmoothingMode() ); rGraphics->SetSmoothingMode( Gdiplus::SmoothingModeHighSpeed ); @@ -388,105 +262,107 @@ namespace dxcanvas // -------------------------------- // TODO(Q2): Unify step calculations with VCL canvas - const int nColorSteps( - ::std::max( - labs( rColor1.GetRed() - rColor2.GetRed() ), - ::std::max( - labs( rColor1.GetGreen() - rColor2.GetGreen() ), - labs( rColor1.GetBlue() - rColor2.GetBlue() ) ) ) ); - - Gdiplus::Matrix aWorldTransformMatrix; - rGraphics->GetTransform( &aWorldTransformMatrix ); - - Gdiplus::RectF aBounds; - pGradientPath->GetBounds( &aBounds, &aWorldTransformMatrix, NULL ); - - // longest line in gradient bound rect - const int nGradientSize( - static_cast<int>( hypot( aBounds.Width, aBounds.Height ) + 1.0 ) ); - - // typical number for pixel of the same color (strip size) - const int nStripSize( 2 ); - - // use at least three steps, and at utmost the number of - // color steps. - const int nStepCount( - ::std::max( - 3, - ::std::min( - nGradientSize / nStripSize, - nColorSteps ) ) + 1 ); - - - Gdiplus::SolidBrush aFillBrush( rColor1 ); - Gdiplus::Matrix aGDIScaleMatrix; - ::basegfx::B2DHomMatrix aScaleMatrix; - - // calc relative size for anisotrophic polygon scaling: - // when the aspect ratio is e.g. 2.0, that denotes a - // gradient which is twice as wide as high. Then, to - // generate a symmetric gradient, the x direction is only - // scaled to 0.5 times the gradient width. Similarly, when - // the aspect ratio is 4.0, the focus has 3/4 the width of - // the overall gradient. - const double nRelativeFocusSize( rValues.mnAspectRatio > 1.0 ? - 1.0 - 1.0/rValues.mnAspectRatio : - 1.0 - rValues.mnAspectRatio ); + int nColorSteps = 0; + for( size_t i=0; i<rColors.size()-1; ++i ) + nColorSteps += numColorSteps(rColors[i],rColors[i+1]); + ::basegfx::B2DHomMatrix aTotalTransform; + const int nStepCount= + ::canvas::tools::calcGradientStepCount(aTotalTransform, + viewState, + renderState, + texture, + nColorSteps); + + ::basegfx::B2DHomMatrix aTextureTransform; + ::basegfx::unotools::homMatrixFromAffineMatrix( aTextureTransform, + texture.AffineTransform ); + // determine overall transformation for inner polygon (might + // have to be prefixed by anisotrophic scaling) + ::basegfx::B2DHomMatrix aInnerPolygonTransformMatrix; + + // For performance reasons, we create a temporary VCL polygon + // here, keep it all the way and only change the vertex values + // in the loop below (as ::Polygon is a pimpl class, creating + // one every loop turn would really stress the mem allocator) + ::basegfx::B2DPolygon aOuterPoly( rGradientPoly ); + ::basegfx::B2DPolygon aInnerPoly; + + // subdivide polygon _before_ rendering, would otherwise have + // to be performed on every loop turn. + if( aOuterPoly.areControlPointsUsed() ) + aOuterPoly = ::basegfx::tools::adaptiveSubdivideByAngle(aOuterPoly); + + aInnerPoly = aOuterPoly; + aOuterPoly.transform(aTextureTransform); + + + // apply scaling (possibly anisotrophic) to inner polygon + // ------------------------------------------------------ + + // scale inner polygon according to aspect ratio: for + // wider-than-tall bounds (nAspectRatio > 1.0), the inner + // polygon, representing the gradient focus, must have + // non-zero width. Specifically, a bound rect twice as wide as + // tall has a focus polygon of half it's width. + const double nAspectRatio( rValues.mnAspectRatio ); + if( nAspectRatio > 1.0 ) + { + // width > height case + aInnerPolygonTransformMatrix.scale( 1.0 - 1.0/nAspectRatio, + 0.0 ); + } + else if( nAspectRatio < 1.0 ) + { + // width < height case + aInnerPolygonTransformMatrix.scale( 0.0, + 1.0 - nAspectRatio ); + } + else + { + // isotrophic case + aInnerPolygonTransformMatrix.scale( 0.0, 0.0 ); + } + + // and finally, add texture transform to it. + aInnerPolygonTransformMatrix *= aTextureTransform; + // apply final matrix to polygon + aInnerPoly.transform( aInnerPolygonTransformMatrix ); + + Gdiplus::GraphicsPath aCurrPath; + Gdiplus::SolidBrush aFillBrush( rColors[0] ); + const sal_uInt32 nNumPoints( aOuterPoly.count() ); + basegfx::tools::KeyStopLerp aLerper(rValues.maStops); for( int i=1; i<nStepCount; ++i ) { - // lerp color. Funnily, the straight-forward integer - // lerp ((nStepCount - i)*val + i*val)/nStepCount gets - // fully botched by MSVC, at least for anything that - // really inlines inlines (i.e. every compile without - // debug=t) - const double nFrac( (double)i/nStepCount ); + std::ptrdiff_t nIndex; + double fAlpha; + const double fT( i/double(nStepCount) ); + boost::tuples::tie(nIndex,fAlpha)=aLerper.lerp(fT); const Gdiplus::Color aFillColor( - static_cast<BYTE>( (1.0 - nFrac)*rColor1.GetRed() + nFrac*rColor2.GetRed() ), - static_cast<BYTE>( (1.0 - nFrac)*rColor1.GetGreen() + nFrac*rColor2.GetGreen() ), - static_cast<BYTE>( (1.0 - nFrac)*rColor1.GetBlue() + nFrac*rColor2.GetBlue() ) ); + static_cast<BYTE>( basegfx::tools::lerp(rColors[nIndex].GetRed(),rColors[nIndex+1].GetRed(),fAlpha) ), + static_cast<BYTE>( basegfx::tools::lerp(rColors[nIndex].GetGreen(),rColors[nIndex+1].GetGreen(),fAlpha) ), + static_cast<BYTE>( basegfx::tools::lerp(rColors[nIndex].GetBlue(),rColors[nIndex+1].GetBlue(),fAlpha) ) ); aFillBrush.SetColor( aFillColor ); - - const double nCurrScale( (nStepCount-i)/(double)nStepCount ); - aScaleMatrix = basegfx::tools::createTranslateB2DHomMatrix(-0.5, -0.5); - - // handle anisotrophic polygon scaling - if( rValues.mnAspectRatio < 1.0 ) - { - // height > width case - aScaleMatrix.scale( nCurrScale, - // lerp with nCurrScale - // between 1.0 and - // relative focus height - nCurrScale + (1.0-nCurrScale)*nRelativeFocusSize ); - } - else if( rValues.mnAspectRatio > 1.0 ) - { - // width > height case - aScaleMatrix.scale( nCurrScale + (1.0-nCurrScale)*nRelativeFocusSize, - // lerp with nCurrScale - // between 1.0 and - // relative focus width - nCurrScale ); - } - else + aCurrPath.Reset(); aCurrPath.StartFigure(); + for( unsigned int p=1; p<nNumPoints; ++p ) { - aScaleMatrix.scale( nCurrScale, - nCurrScale ); + const ::basegfx::B2DPoint& rOuterPoint1( aOuterPoly.getB2DPoint(p-1) ); + const ::basegfx::B2DPoint& rInnerPoint1( aInnerPoly.getB2DPoint(p-1) ); + const ::basegfx::B2DPoint& rOuterPoint2( aOuterPoly.getB2DPoint(p) ); + const ::basegfx::B2DPoint& rInnerPoint2( aInnerPoly.getB2DPoint(p) ); + + aCurrPath.AddLine( + Gdiplus::REAL(fT*rInnerPoint1.getX() + (1-fT)*rOuterPoint1.getX()), + Gdiplus::REAL(fT*rInnerPoint1.getY() + (1-fT)*rOuterPoint1.getY()), + Gdiplus::REAL(fT*rInnerPoint2.getX() + (1-fT)*rOuterPoint2.getX()), + Gdiplus::REAL(fT*rInnerPoint2.getY() + (1-fT)*rOuterPoint2.getY())); } + aCurrPath.CloseFigure(); - aScaleMatrix.translate( 0.5, 0.5 ); - - tools::gdiPlusMatrixFromB2DHomMatrix( aGDIScaleMatrix, - aScaleMatrix ); - - GraphicsPathSharedPtr pScaledGradientPath( - tools::graphicsPathFromB2DPolygon( rValues.maGradientPoly ) ); - pScaledGradientPath->Transform( &aGDIScaleMatrix ); - - rGraphics->FillPath( &aFillBrush, pScaledGradientPath.get() ); + rGraphics->FillPath( &aFillBrush, &aCurrPath ); } // reset to old anti-alias mode @@ -507,18 +383,24 @@ namespace dxcanvas // one sets both, only the translational components of the // texture is respected. + Gdiplus::Matrix aMatrix; + tools::gdiPlusMatrixFromAffineMatrix2D( aMatrix, + texture.AffineTransform ); + GraphicsPathSharedPtr pGradientPath( + tools::graphicsPathFromB2DPolygon( rValues.maGradientPoly )); pGradientPath->Transform( &aMatrix ); - pGradientBrush = createPathGradientBrush( - pGradientPath, - rColor1, - rColor2 ); + pGradientBrush.reset( + new Gdiplus::PathGradientBrush( pGradientPath.get() ) ); + pGradientBrush->SetInterpolationColors( &rColors[0], + &rStops[0], + rStops.size() ); // explicitely setup center point. Since the center of GDI+ // gradients are by default the _centroid_ of the path // (i.e. the weighted sum of edge points), it will not // necessarily coincide with our notion of center. - Gdiplus::PointF aCenterPoint(0.5, 0.5); + Gdiplus::PointF aCenterPoint(0, 0); aMatrix.TransformPoints( &aCenterPoint ); pGradientBrush->SetCenterPoint( aCenterPoint ); @@ -554,38 +436,35 @@ namespace dxcanvas } bool fillGradient( const ::canvas::ParametricPolyPolygon::Values& rValues, - const Gdiplus::Color& rColor1, - const Gdiplus::Color& rColor2, + const std::vector< Gdiplus::Color >& rColors, + const std::vector< Gdiplus::REAL >& rStops, GraphicsSharedPtr& rGraphics, const GraphicsPathSharedPtr& rPath, + const rendering::ViewState& viewState, + const rendering::RenderState& renderState, const rendering::Texture& texture ) { switch( rValues.meType ) { case ::canvas::ParametricPolyPolygon::GRADIENT_LINEAR: fillLinearGradient( rGraphics, - rColor1, - rColor2, + rValues, + rColors, + rStops, rPath, texture ); break; - case ::canvas::ParametricPolyPolygon::GRADIENT_AXIAL: - fillAxialGradient( rGraphics, - rColor1, - rColor2, - rPath, - texture ); - break; - case ::canvas::ParametricPolyPolygon::GRADIENT_ELLIPTICAL: // FALLTHROUGH intended case ::canvas::ParametricPolyPolygon::GRADIENT_RECTANGULAR: fillPolygonalGradient( rValues, + rColors, + rStops, rGraphics, - rColor1, - rColor2, rPath, + viewState, + renderState, texture ); break; @@ -606,13 +485,13 @@ namespace dxcanvas rTexture.RepeatModeY, "CanvasHelper::fillBitmap(): GDI+ cannot handle differing X/Y repeat mode." ); - const bool bClamp( rTexture.RepeatModeX == rendering::TexturingMode::CLAMP && - rTexture.RepeatModeY == rendering::TexturingMode::CLAMP ); + const bool bClamp( rTexture.RepeatModeX == rendering::TexturingMode::NONE && + rTexture.RepeatModeY == rendering::TexturingMode::NONE ); const geometry::IntegerSize2D aBmpSize( xBitmap->getSize() ); ENSURE_ARG_OR_THROW( aBmpSize.Width != 0 && - aBmpSize.Height != 0, - "CanvasHelper::fillBitmap(): zero-sized texture bitmap" ); + aBmpSize.Height != 0, + "CanvasHelper::fillBitmap(): zero-sized texture bitmap" ); // TODO(P3): Detect case that path is rectangle and // bitmap is just scaled into that. Then, we can @@ -624,7 +503,6 @@ namespace dxcanvas tools::bitmapFromXBitmap( xBitmap ) ); TextureBrushSharedPtr pBrush; - if( ::rtl::math::approxEqual( rTexture.Alpha, 1.0 ) ) { @@ -662,9 +540,9 @@ namespace dxcanvas // scale down bitmap to [0,1]x[0,1] rect, as required // from the XCanvas interface. + pBrush->MultiplyTransform( &aTextureTransform ); pBrush->ScaleTransform( static_cast< Gdiplus::REAL >(1.0/aBmpSize.Width), static_cast< Gdiplus::REAL >(1.0/aBmpSize.Height) ); - pBrush->MultiplyTransform( &aTextureTransform ); // TODO(F1): FillRule ENSURE_OR_THROW( @@ -706,17 +584,29 @@ namespace dxcanvas const ::canvas::ParametricPolyPolygon::Values& rValues( pGradient->getValues() ); - // TODO: use all the colors and place them on given positions/stops - const Gdiplus::Color aColor1(tools::sequenceToArgb(rValues.maColors[0])); - const Gdiplus::Color aColor2(tools::sequenceToArgb(rValues.maColors[rValues.maColors.getLength () - 1] )); + OSL_ASSERT(rValues.maColors.getLength() == rValues.maStops.getLength() + && rValues.maColors.getLength() > 1); + + std::vector< Gdiplus::Color > aColors(rValues.maColors.getLength()); + std::transform(&rValues.maColors[0], + &rValues.maColors[0]+rValues.maColors.getLength(), + aColors.begin(), + boost::bind( + (Gdiplus::ARGB (*)( const uno::Sequence< double >& ))( + &tools::sequenceToArgb), + _1)); + std::vector< Gdiplus::REAL > aStops; + comphelper::sequenceToContainer(aStops,rValues.maStops); // TODO(E1): Return value // TODO(F1): FillRule fillGradient( rValues, - aColor1, - aColor2, + aColors, + aStops, pGraphics, tools::graphicsPathFromXPolyPolygon2D( xPolyPolygon ), + viewState, + renderState, textures[0] ); } } diff --git a/canvas/source/directx/dx_impltools.cxx b/canvas/source/directx/dx_impltools.cxx index 30bd11a2271a..c298fb9238f9 100755 --- a/canvas/source/directx/dx_impltools.cxx +++ b/canvas/source/directx/dx_impltools.cxx @@ -196,7 +196,7 @@ namespace dxcanvas { const sal_uInt32 nPoints( rPoly.count() ); - if( !nPoints ) + if( nPoints < 2 ) return; rOutput->StartFigure(); diff --git a/canvas/source/directx/dx_spritecanvas.hxx b/canvas/source/directx/dx_spritecanvas.hxx index 5d5e65c23230..b14d79050ccf 100755 --- a/canvas/source/directx/dx_spritecanvas.hxx +++ b/canvas/source/directx/dx_spritecanvas.hxx @@ -39,7 +39,6 @@ #include <com/sun/star/rendering/XIntegerBitmap.hpp> #include <com/sun/star/rendering/XGraphicDevice.hpp> #include <com/sun/star/rendering/XBufferController.hpp> -#include <com/sun/star/rendering/XParametricPolyPolygon2DFactory.hpp> #include <cppuhelper/compbase9.hxx> #include <comphelper/uno3.hxx> @@ -58,14 +57,14 @@ namespace dxcanvas { typedef ::cppu::WeakComponentImplHelper9< ::com::sun::star::rendering::XSpriteCanvas, - ::com::sun::star::rendering::XIntegerBitmap, - ::com::sun::star::rendering::XGraphicDevice, - ::com::sun::star::rendering::XParametricPolyPolygon2DFactory, - ::com::sun::star::rendering::XBufferController, - ::com::sun::star::awt::XWindowListener, - ::com::sun::star::util::XUpdatable, - ::com::sun::star::beans::XPropertySet, - ::com::sun::star::lang::XServiceName > WindowGraphicDeviceBase_Base; + ::com::sun::star::rendering::XIntegerBitmap, + ::com::sun::star::rendering::XGraphicDevice, + ::com::sun::star::lang::XMultiServiceFactory, + ::com::sun::star::rendering::XBufferController, + ::com::sun::star::awt::XWindowListener, + ::com::sun::star::util::XUpdatable, + ::com::sun::star::beans::XPropertySet, + ::com::sun::star::lang::XServiceName > WindowGraphicDeviceBase_Base; typedef ::canvas::BufferedGraphicDeviceBase< ::canvas::BaseMutexHelper< WindowGraphicDeviceBase_Base >, SpriteDeviceHelper, ::osl::MutexGuard, diff --git a/canvas/source/factory/canvasfactory.map b/canvas/source/factory/canvasfactory.map deleted file mode 100644 index 44fb01f37126..000000000000 --- a/canvas/source/factory/canvasfactory.map +++ /dev/null @@ -1,8 +0,0 @@ -CAN_1_0 { - global: - component_getImplementationEnvironment; - component_writeInfo; - component_getFactory; - local: - *; -}; diff --git a/canvas/source/factory/makefile.mk b/canvas/source/factory/makefile.mk index 94e3f0d04255..fc6d423192d6 100644 --- a/canvas/source/factory/makefile.mk +++ b/canvas/source/factory/makefile.mk @@ -43,7 +43,7 @@ SHL1STDLIBS = \ $(CPPULIB) \ $(CPPUHELPERLIB) \ $(SALLIB) -SHL1VERSIONMAP = canvasfactory.map +SHL1VERSIONMAP = $(SOLARENV)/src/component.map SHL1DEPN = SHL1IMPLIB = i$(TARGET) diff --git a/canvas/source/java/BackBuffer.java b/canvas/source/java/BackBuffer.java deleted file mode 100644 index 472f6603c33c..000000000000 --- a/canvas/source/java/BackBuffer.java +++ /dev/null @@ -1,112 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -// Java AWT -import java.awt.*; -import java.awt.image.*; - -public class BackBuffer -{ - private BufferedImage backBuffer; - //private VolatileImage backBuffer; - private Graphics2D backBufferGraphics; - private Graphics2D referenceDevice; - - public BackBuffer( Graphics2D _referenceDevice, - int width, - int height ) - { - referenceDevice = _referenceDevice; - setSize( width, height ); - } - - public Graphics2D getGraphics() - { - return backBufferGraphics; - } - - public void setSize( int width, - int height ) - { - if( backBuffer != null && - width == backBuffer.getWidth() && - height == backBuffer.getHeight() ) - { - return; - } - - if( backBufferGraphics != null ) - backBufferGraphics.dispose(); - - if( backBuffer != null ) - backBuffer.flush(); - - // TODO: Maybe VolatileImage with another BufferedImage as a backup is - // a tad faster here. - backBuffer = referenceDevice.getDeviceConfiguration().createCompatibleImage(width, - height); -// backBuffer = referenceDevice.getDeviceConfiguration().createCompatibleVolatileImage(width, -// height); - - backBufferGraphics = backBuffer.createGraphics(); - CanvasUtils.initGraphics( backBufferGraphics ); - - // clear the buffer to white (to have a defined state here) - backBufferGraphics.setColor( java.awt.Color.white ); - backBufferGraphics.fillRect( 0,0,width,height ); - } - - public void redraw( Graphics2D graph ) - { - if( graph != null && - backBuffer != null ) - { - CanvasUtils.printLog("BackBuffer.redraw(): using buffer of size (" + - backBuffer.getWidth() + "," + backBuffer.getHeight() + ")" ); - - graph.drawImage(backBuffer, 0, 0, null); - - // TODO: this is just twiddled to work. I cannot be sure - // that this volatile backbuffer will survive in the first - // place, nor that it wise to leave it in VRAM. - - // only flush non-volatile images - // CanvasUtils.postRenderImageTreatment( backBuffer ); - } - } - - public java.awt.Image getBackBuffer() - { - return backBuffer; - } - - public void dispose() - { - backBufferGraphics.dispose(); - backBuffer.flush(); - } -} diff --git a/canvas/source/java/BezierPolyPolygon.java b/canvas/source/java/BezierPolyPolygon.java deleted file mode 100644 index ed6c08a21abc..000000000000 --- a/canvas/source/java/BezierPolyPolygon.java +++ /dev/null @@ -1,151 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -// Canvas -import com.sun.star.rendering.*; -import com.sun.star.geometry.*; - -public class BezierPolyPolygon - extends com.sun.star.lib.uno.helper.ComponentBase - implements com.sun.star.lang.XServiceInfo, - com.sun.star.rendering.XBezierPolyPolygon2D -{ - private java.awt.geom.GeneralPath path; - - //---------------------------------------------------------------------------------- - - public BezierPolyPolygon( RealBezierSegment2D[][] points ) - { - setBezierSegments( points, 0 ); - } - - public java.awt.geom.GeneralPath getJavaPath() - { - return path; - } - - //---------------------------------------------------------------------------------- - - // - // XPolyPolygon implementation - // =========================== - // - public void addPolyPolygon( RealPoint2D position, XPolyPolygon2D polyPolygon ) - { - } - - public int getNumberOfPolygons( ) - { - return 0; - } - - public int getNumberOfPolygonPoints( int polygon ) - { - return 0; - } - - public FillRule getFillRule( ) - { - if( path.getWindingRule() == java.awt.geom.GeneralPath.WIND_EVEN_ODD ) - return FillRule.EVEN_ODD; - else - return FillRule.NON_ZERO; - } - - public void setFillRule( FillRule fillRule ) - { - if( fillRule == FillRule.EVEN_ODD ) - path.setWindingRule( java.awt.geom.GeneralPath.WIND_EVEN_ODD ); - else - path.setWindingRule( java.awt.geom.GeneralPath.WIND_NON_ZERO ); - } - - public boolean isClosed( int index ) - { - // TODO - return false; - } - - public void setClosed( int index, boolean closedState ) - { - // TODO - } - - //---------------------------------------------------------------------------------- - - // - // XBezierPolyPolygon implementation - // ================================= - // - public RealBezierSegment2D[][] getBezierSegments( int nPolygonIndex, int nNumberOfPolygons, int nPointIndex, int nNumberOfPoints ) - { - return null; - } - - public void setBezierSegments( RealBezierSegment2D[][] points, int nPolygonIndex ) - { - if( nPolygonIndex != 0 ) - CanvasUtils.printLog( "LinePolyPolygon.setPoints: subset not yet implemented!" ); - - path = CanvasUtils.makeGenPathFromBezierPoints( points ); - } - - public RealBezierSegment2D getBezierSegment( int nPolygonIndex, int nPointIndex ) - { - return null; - } - - public void setBezierSegment( RealBezierSegment2D point, int nPolygonIndex, int nPointIndex ) - { - CanvasUtils.printLog( "LinePolyPolygon.setPoint: not yet implemented!" ); - } - - //---------------------------------------------------------------------------------- - - // - // XServiceInfo impl - // ================= - // - - private static final String s_implName = "XBezierPolyPolygon2D.java.impl"; - private static final String s_serviceName = "com.sun.star.rendering.BezierPolyPolygon2D"; - - public String getImplementationName() - { - return s_implName; - } - - public String [] getSupportedServiceNames() - { - return new String [] { s_serviceName }; - } - - public boolean supportsService( String serviceName ) - { - return serviceName.equals( s_serviceName ); - } -} diff --git a/canvas/source/java/BitmapCanvas.java b/canvas/source/java/BitmapCanvas.java deleted file mode 100644 index f40c9bf34c3a..000000000000 --- a/canvas/source/java/BitmapCanvas.java +++ /dev/null @@ -1,136 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -// UNO -import com.sun.star.uno.UnoRuntime; -import com.sun.star.uno.XComponentContext; -import com.sun.star.uno.AnyConverter; -import com.sun.star.uno.IQueryInterface; -import com.sun.star.lang.XInitialization; -import com.sun.star.lib.uno.helper.WeakBase; - -// OOo AWT -import com.sun.star.awt.*; - -// Canvas -import com.sun.star.rendering.*; -import com.sun.star.geometry.*; - -// Java AWT -import java.awt.*; -import java.awt.image.*; -import java.awt.geom.*; - -public class BitmapCanvas - extends CanvasBase - implements com.sun.star.rendering.XBitmapCanvas, - com.sun.star.lang.XServiceInfo -{ - private Graphics2D graphics; - - public Graphics2D getGraphics() - { - return graphics; - } - - //---------------------------------------------------------------------------------- - - public BitmapCanvas( Graphics2D _graphics ) - { - graphics = _graphics; - } - - //---------------------------------------------------------------------------------- - - // - // XBitmapCanvas impl - // ================== - // - - public synchronized void copyRect( com.sun.star.rendering.XBitmapCanvas sourceCanvas, - com.sun.star.geometry.RealRectangle2D sourceRect, - com.sun.star.rendering.ViewState sourceViewState, - com.sun.star.rendering.RenderState sourceRenderState, - com.sun.star.geometry.RealRectangle2D destRect, - com.sun.star.rendering.ViewState destViewState, - com.sun.star.rendering.RenderState destRenderState ) - { - // TODO: create temp image when transform is non-trivial - - if( sourceCanvas == this ) - { - // copy rectangle within the canvas - graphics.copyArea((int)sourceRect.X1, - (int)sourceRect.Y1, - (int)(sourceRect.X2 - sourceRect.X1), - (int)(sourceRect.Y2 - sourceRect.Y1), - (int)(destRect.X1 - sourceRect.X1), - (int)(destRect.Y1 - sourceRect.Y1) ); - } - else - { - if( sourceCanvas instanceof JavaCanvas ) - { - // cache - CanvasUtils.setupGraphicsState( graphics, destViewState, destRenderState, CanvasUtils.alsoSetupPaint ); - - // TODO: really extract correct source rect here - BufferedImage backBuffer = ((BufferedGraphics2D)((JavaCanvas)sourceCanvas).getGraphics()).getBackBuffer(); - graphics.drawImage( backBuffer, 0, 0, null ); - CanvasUtils.postRenderImageTreatment( backBuffer ); - - } - // TODO: foreign canvas - } - } - - //---------------------------------------------------------------------------------- - - private static final String s_implName = "XBitmapCanvas.java.impl"; - private static final String s_serviceName = "com.sun.star.rendering.BitmapCanvas"; - - //---------------------------------------------------------------------------------- - - // - // XServiceInfo impl - // ================= - // - public String getImplementationName() - { - return s_implName; - } - - public String [] getSupportedServiceNames() - { - return new String [] { s_serviceName }; - } - - public boolean supportsService( String serviceName ) - { - return serviceName.equals( s_serviceName ); - } -} diff --git a/canvas/source/java/BufferedGraphics2D.java b/canvas/source/java/BufferedGraphics2D.java deleted file mode 100644 index 88691351809e..000000000000 --- a/canvas/source/java/BufferedGraphics2D.java +++ /dev/null @@ -1,600 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -// Java AWT -import java.awt.*; -import java.awt.geom.*; -import java.awt.image.*; -import java.awt.image.renderable.*; -import java.awt.font.*; -import java.text.*; -import java.util.*; - - -public class BufferedGraphics2D - extends java.awt.Graphics2D -{ - // TODO: Somehow, get rid of this duplicate graphics (the graphics member, - // and this object itself, extending a Graphics2D) - private Graphics2D graphics; - private BufferedImage backBuffer; - private Graphics2D backBufferGraphics; - - //---------------------------------------------------------------------------------- - - public BufferedGraphics2D( java.awt.Graphics2D _graphics, int width, int height ) - { - setGraphics( _graphics, Math.max(1,width), Math.max(1,height) ); - } - - public void redraw( Graphics2D graph ) - { - if( graph != null && - backBuffer != null ) - { - CanvasUtils.printLog("BufferedGraphics2D.redraw: using buffer of size (" + - backBuffer.getWidth() + "," + backBuffer.getHeight() + ")" ); - - // set transform to identity - graph.setTransform( new AffineTransform() ); - graph.drawImage(backBuffer, 0, 0, null); - CanvasUtils.postRenderImageTreatment( backBuffer ); - } - } - - public BufferedImage getBackBuffer() - { - return backBuffer; - } - - public void setSize( int width, int height ) - { - if( backBuffer != null && - width == backBuffer.getWidth() && - height == backBuffer.getHeight() ) - { - return; - } - - if( backBufferGraphics != null ) - backBufferGraphics.dispose(); - - if( backBuffer != null ) - backBuffer.flush(); - - // TODO: Maybe VolatileImage with another BufferedImage as a backup is - // a tad faster here. - backBuffer = graphics.getDeviceConfiguration().createCompatibleImage(width, - height); - - backBufferGraphics = backBuffer.createGraphics(); - CanvasUtils.initGraphics( backBufferGraphics ); - - // clear the buffer to white (to have a defined state here) - backBufferGraphics.setColor( java.awt.Color.white ); - backBufferGraphics.fillRect( 0,0,width,height ); - } - - public void setGraphics( Graphics2D _graphics, int width, int height ) - { - if( graphics != null ) - graphics.dispose(); - - graphics = _graphics; - - setSize(width,height); - } - - //---------------------------------------------------------------------------------- - - // - // Graphics - // ======== - // - public void clearRect(int x, int y, int width, int height) - { - graphics.clearRect(x,y,width,height); - backBufferGraphics.clearRect(x,y,width,height); - } - - public void clipRect(int x, int y, int width, int height) - { - graphics.clipRect(x,y,width,height); - backBufferGraphics.clipRect(x,y,width,height); - } - - public void copyArea(int x, int y, int width, int height, int dx, int dy) - { - graphics.copyArea(x,y,width,height,dx,dy); - backBufferGraphics.copyArea(x,y,width,height,dx,dy); - } - - public Graphics create() - { - return null; - } - - public Graphics create(int x, int y, int width, int height) - { - return null; - } - - public void dispose() - { - graphics.dispose(); - backBufferGraphics.dispose(); - backBuffer.flush(); - } - - public void draw3DRect(int x, int y, int width, int height, boolean raised) - { - graphics.draw3DRect(x,y,width,height,raised); - backBufferGraphics.draw3DRect(x,y,width,height,raised); - } - - public void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle) - { - graphics.drawArc(x,y,width,height,startAngle,arcAngle); - backBufferGraphics.drawArc(x,y,width,height,startAngle,arcAngle); - } - - public void drawBytes(byte[] data, int offset, int length, int x, int y) - { - graphics.drawBytes(data,offset,length,x,y); - backBufferGraphics.drawBytes(data,offset,length,x,y); - } - - public void drawChars(char[] data, int offset, int length, int x, int y) - { - graphics.drawChars(data,offset,length,x,y); - backBufferGraphics.drawChars(data,offset,length,x,y); - } - - public boolean drawImage(Image img, int x, int y, Color bgcolor, ImageObserver observer) - { - backBufferGraphics.drawImage(img,x,y,bgcolor,observer); - return graphics.drawImage(img,x,y,bgcolor,observer); - } - - public boolean drawImage(Image img, int x, int y, ImageObserver observer) - { - backBufferGraphics.drawImage(img,x,y,observer); - return graphics.drawImage(img,x,y,observer); - } - - public boolean drawImage(Image img, int x, int y, int width, int height, Color bgcolor, ImageObserver observer) - { - backBufferGraphics.drawImage(img,x,y,width,height,bgcolor,observer); - return graphics.drawImage(img,x,y,width,height,bgcolor,observer); - } - - public boolean drawImage(Image img, int x, int y, int width, int height, ImageObserver observer) - { - backBufferGraphics.drawImage(img,x,y,width,height,observer); - return graphics.drawImage(img,x,y,width,height,observer); - } - - public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, Color bgcolor, ImageObserver observer) - { - backBufferGraphics.drawImage(img,dx1,dy1,dx2,dy2,sx1,sy1,sx2,sy2,bgcolor,observer); - return graphics.drawImage(img,dx1,dy1,dx2,dy2,sx1,sy1,sx2,sy2,bgcolor,observer); - } - - public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver observer) - { - backBufferGraphics.drawImage(img,dx1,dy1,dx2,dy2,sx1,sy1,sx2,sy2,observer); - return graphics.drawImage(img,dx1,dy1,dx2,dy2,sx1,sy1,sx2,sy2,observer); - } - - public void drawLine(int x1, int y1, int x2, int y2) - { - graphics.drawLine(x1,y1,x2,y2); - backBufferGraphics.drawLine(x1,y1,x2,y2); - } - - public void drawOval(int x, int y, int width, int height) - { - graphics.drawOval(x,y,width,height); - backBufferGraphics.drawOval(x,y,width,height); - } - - public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints) - { - graphics.drawPolygon(xPoints,yPoints,nPoints); - backBufferGraphics.drawPolygon(xPoints,yPoints,nPoints); - } - - public void drawPolygon(Polygon p) - { - graphics.drawPolygon(p); - backBufferGraphics.drawPolygon(p); - } - - public void drawPolyline(int[] xPoints, int[] yPoints, int nPoints) - { - graphics.drawPolyline(xPoints,yPoints,nPoints); - backBufferGraphics.drawPolyline(xPoints,yPoints,nPoints); - } - - public void drawRect(int x, int y, int width, int height) - { - graphics.drawRect(x,y,width,height); - backBufferGraphics.drawRect(x,y,width,height); - } - - public void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) - { - graphics.drawRoundRect(x,y,width,height,arcWidth,arcHeight); - backBufferGraphics.drawRoundRect(x,y,width,height,arcWidth,arcHeight); - } - - public void drawString(AttributedCharacterIterator iterator, int x, int y) - { - graphics.drawString(iterator,x,y); - backBufferGraphics.drawString(iterator,x,y); - } - - public void drawString(String str, int x, int y) - { - graphics.drawString(str,x,y); - backBufferGraphics.drawString(str,x,y); - } - - public void fill3DRect(int x, int y, int width, int height, boolean raised) - { - graphics.fill3DRect(x,y,width,height,raised); - backBufferGraphics.fill3DRect(x,y,width,height,raised); - } - - public void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle) - { - graphics.fillArc(x,y,width,height,startAngle,arcAngle); - backBufferGraphics.fillArc(x,y,width,height,startAngle,arcAngle); - } - - public void fillOval(int x, int y, int width, int height) - { - graphics.fillOval(x,y,width,height); - backBufferGraphics.fillOval(x,y,width,height); - } - - public void fillPolygon(int[] xPoints, int[] yPoints, int nPoints) - { - graphics.fillPolygon(xPoints,yPoints,nPoints); - backBufferGraphics.fillPolygon(xPoints,yPoints,nPoints); - } - - public void fillPolygon(Polygon p) - { - graphics.fillPolygon(p); - backBufferGraphics.fillPolygon(p); - } - - public void fillRect(int x, int y, int width, int height) - { - graphics.fillRect(x,y,width,height); - backBufferGraphics.fillRect(x,y,width,height); - } - - public void fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) - { - graphics.fillRoundRect(x,y,width,height,arcWidth,arcHeight); - backBufferGraphics.fillRoundRect(x,y,width,height,arcWidth,arcHeight); - } - - public Shape getClip() - { - return graphics.getClip(); - } - - public Rectangle getClipBounds() - { - return graphics.getClipBounds(); - } - - public Rectangle getClipBounds(Rectangle r) - { - return graphics.getClipBounds(r); - } - - public Rectangle getClipRect() - { - return graphics.getClipRect(); - } - - public Color getColor() - { - return getColor(); - } - - public Font getFont() - { - return getFont(); - } - - public FontMetrics getFontMetrics() - { - return getFontMetrics(); - } - - public FontMetrics getFontMetrics(Font f) - { - return getFontMetrics(f); - } - - public boolean hitClip(int x, int y, int width, int height) - { - return graphics.hitClip(x,y,width,height); - } - - public void setClip(int x, int y, int width, int height) - { - graphics.setClip(x,y,width,height); - backBufferGraphics.setClip(x,y,width,height); - } - - public void setClip(Shape clip) - { - graphics.setClip(clip); - backBufferGraphics.setClip(clip); - } - - public void setColor(Color c) - { - graphics.setColor(c); - backBufferGraphics.setColor(c); - } - - public void setFont(Font font) - { - graphics.setFont(font); - backBufferGraphics.setFont(font); - } - - public void setPaintMode() - { - graphics.setPaintMode(); - backBufferGraphics.setPaintMode(); - } - - public void setXORMode(Color c1) - { - graphics.setXORMode(c1); - backBufferGraphics.setXORMode(c1); - } - - public String toString() - { - return graphics.toString(); - } - - public void translate(int x, int y) - { - graphics.translate(x,y); - backBufferGraphics.translate(x,y); - } - - //---------------------------------------------------------------------------------- - - // - // Graphics2D - // ========== - // - public void addRenderingHints(Map hints) - { - graphics.addRenderingHints(hints); - backBufferGraphics.addRenderingHints(hints); - } - - public void clip(Shape s) - { - graphics.clip(s); - backBufferGraphics.clip(s); - } - - public void draw(Shape s) - { - graphics.draw(s); - backBufferGraphics.draw(s); - } - - public void drawGlyphVector(GlyphVector g, float x, float y) - { - graphics.drawGlyphVector(g,x,y); - backBufferGraphics.drawGlyphVector(g,x,y); - } - - public void drawImage(BufferedImage img, BufferedImageOp op, int x, int y) - { - graphics.drawImage(img,op,x,y); - backBufferGraphics.drawImage(img,op,x,y); - } - - public boolean drawImage(Image img, AffineTransform xform, ImageObserver obs) - { - backBufferGraphics.drawImage(img,xform,obs); - return graphics.drawImage(img,xform,obs); - } - - public void drawRenderableImage(RenderableImage img, AffineTransform xform) - { - graphics.drawRenderableImage(img,xform); - backBufferGraphics.drawRenderableImage(img,xform); - } - - public void drawRenderedImage(RenderedImage img, AffineTransform xform) - { - graphics.drawRenderedImage(img,xform); - backBufferGraphics.drawRenderedImage(img,xform); - } - - public void drawString(AttributedCharacterIterator iterator, float x, float y) - { - graphics.drawString(iterator,x,y); - backBufferGraphics.drawString(iterator,x,y); - } - - public void drawString(String s, float x, float y) - { - graphics.drawString(s,x,y); - backBufferGraphics.drawString(s,x,y); - } - - public void fill(Shape s) - { - graphics.fill(s); - backBufferGraphics.fill(s); - } - - public Color getBackground() - { - return graphics.getBackground(); - } - - public Composite getComposite() - { - return graphics.getComposite(); - } - - public GraphicsConfiguration getDeviceConfiguration() - { - return graphics.getDeviceConfiguration(); - } - - public FontRenderContext getFontRenderContext() - { - return graphics.getFontRenderContext(); - } - - public Paint getPaint() - { - return graphics.getPaint(); - } - - public Object getRenderingHint(RenderingHints.Key hintKey) - { - return graphics.getRenderingHint(hintKey); - } - - public RenderingHints getRenderingHints() - { - return graphics.getRenderingHints(); - } - - public Stroke getStroke() - { - return graphics.getStroke(); - } - - public AffineTransform getTransform() - { - return graphics.getTransform(); - } - - public boolean hit(Rectangle rect, Shape s, boolean onStroke) - { - return graphics.hit(rect,s,onStroke); - } - - public void rotate(double theta) - { - graphics.rotate(theta); - backBufferGraphics.rotate(theta); - } - - public void rotate(double theta, double x, double y) - { - graphics.rotate(theta,x,y); - backBufferGraphics.rotate(theta,x,y); - } - - public void scale(double sx, double sy) - { - graphics.scale(sx,sy); - backBufferGraphics.scale(sx,sy); - } - - public void setBackground(Color color) - { - graphics.setBackground(color); - backBufferGraphics.setBackground(color); - } - - public void setComposite(Composite comp) - { - graphics.setComposite(comp); - backBufferGraphics.setComposite(comp); - } - - public void setPaint(Paint paint) - { - graphics.setPaint(paint); - backBufferGraphics.setPaint(paint); - } - - public void setRenderingHint(RenderingHints.Key hintKey, Object hintValue) - { - graphics.setRenderingHint(hintKey,hintValue); - backBufferGraphics.setRenderingHint(hintKey,hintValue); - } - - public void setRenderingHints(Map hints) - { - graphics.setRenderingHints(hints); - backBufferGraphics.setRenderingHints(hints); - } - - public void setStroke(Stroke s) - { - graphics.setStroke(s); - backBufferGraphics.setStroke(s); - } - - public void setTransform(AffineTransform Tx) - { - graphics.setTransform(Tx); - backBufferGraphics.setTransform(Tx); - } - - public void shear(double shx, double shy) - { - graphics.shear(shx,shy); - backBufferGraphics.shear(shx,shy); - } - - public void transform(AffineTransform Tx) - { - graphics.transform(Tx); - backBufferGraphics.transform(Tx); - } - - public void translate(double tx, double ty) - { - graphics.translate(tx,ty); - backBufferGraphics.translate(tx,ty); - } -} diff --git a/canvas/source/java/CanvasBase.java b/canvas/source/java/CanvasBase.java deleted file mode 100644 index 2df796d06f84..000000000000 --- a/canvas/source/java/CanvasBase.java +++ /dev/null @@ -1,341 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -// Canvas -import com.sun.star.rendering.*; -import com.sun.star.geometry.*; - -// Java AWT -import java.awt.*; -import java.awt.geom.*; - -public abstract class CanvasBase - extends com.sun.star.lib.uno.helper.ComponentBase - implements com.sun.star.rendering.XCanvas -{ - // to be overridden - public abstract Graphics2D getGraphics(); - - //---------------------------------------------------------------------------------- - - // - // XCanvas interface - // ================= - // - public synchronized void clear() - { - Graphics2D graphics = getGraphics(); - // TODO(F3): retrieve true dimensions of the Graphics - graphics.clearRect(0,0,1000,1000); - } - - public synchronized void drawPoint( RealPoint2D aPoint, - ViewState viewState, - RenderState renderState ) throws com.sun.star.lang.IllegalArgumentException - { - // cache - Graphics2D graphics = getGraphics(); - - // initialize the Graphics2D - CanvasUtils.setupGraphicsState( graphics, viewState, renderState, CanvasUtils.alsoSetupPaint ); - - // calculate the domain value for a single device pixel. we're - // using delta mapping here, to avoid later subtraction of two - // mapped values (as we really only need a transformed size, - // not a transformed point). - AffineTransform transform = graphics.getTransform(); - AffineTransform inverse; - try - { - inverse = transform.createInverse(); - } - catch( NoninvertibleTransformException e ) - { - // transformation not invertible. Nothing to render then. - return; - } - - java.awt.geom.Point2D.Double pointSize = new java.awt.geom.Point2D.Double(1.0,1.0); - java.awt.geom.Point2D.Double domainPointSize = new java.awt.geom.Point2D.Double(); - inverse.deltaTransform( pointSize, domainPointSize ); - - // render a circle one device pixel wide - Ellipse2D.Double ellipse = new Ellipse2D.Double(aPoint.X, aPoint.Y, domainPointSize.x, domainPointSize.y); - - // render, at last - graphics.fill( ellipse ); - - CanvasUtils.printLog( "XCanvas: drawPoint called" ); - } - - public synchronized void drawLine( RealPoint2D aStartPoint, - RealPoint2D aEndPoint, - ViewState viewState, - RenderState renderState ) throws com.sun.star.lang.IllegalArgumentException - { - // cache - Graphics2D graphics = getGraphics(); - - // initialize the Graphics2D - CanvasUtils.setupGraphicsState( graphics, viewState, renderState, CanvasUtils.alsoSetupPaint ); - graphics.setStroke( new BasicStroke() ); - - // setup line object - Line2D.Double line = new Line2D.Double(aStartPoint.X, aStartPoint.Y, aEndPoint.X, aEndPoint.Y); - - // render, at last - graphics.draw( line ); - - CanvasUtils.printLog( "XCanvas: drawLine called" ); - } - - public synchronized void drawBezier( RealBezierSegment2D aBezierSegment, - RealPoint2D aEndPoint, - ViewState viewState, - RenderState renderState ) throws com.sun.star.lang.IllegalArgumentException - { - // cache - Graphics2D graphics = getGraphics(); - - // initialize the Graphics2D - CanvasUtils.setupGraphicsState( graphics, viewState, renderState, CanvasUtils.alsoSetupPaint ); - graphics.setStroke( new BasicStroke() ); - - // setup bezier object - CubicCurve2D.Double curve = new CubicCurve2D.Double(aBezierSegment.Px, aBezierSegment.Py, - aBezierSegment.C1x, aBezierSegment.C1y, - aBezierSegment.C2x, aBezierSegment.C2y, - aEndPoint.X, aEndPoint.Y); - - // render, at last - graphics.draw( curve ); - - CanvasUtils.printLog( "XCanvas: drawbezier called" ); - } - - public synchronized XCachedPrimitive drawPolyPolygon( XPolyPolygon2D xPolyPolygon, - ViewState viewState, - RenderState renderState ) throws com.sun.star.lang.IllegalArgumentException - { - CanvasUtils.printLog( "CanvasBase.drawPolyPolygon() called" ); - - // cache - Graphics2D graphics = getGraphics(); - - // initialize the Graphics2D - CanvasUtils.setupGraphicsState( graphics, viewState, renderState, CanvasUtils.alsoSetupPaint ); - graphics.setStroke( new BasicStroke() ); - - // render the polygon - // TODO: maybe use Graphics.drawPolyline here! - graphics.draw( CanvasUtils.makeGeneralPath(xPolyPolygon) ); - - CanvasUtils.printLog( "XCanvas: drawPolyPolygon called" ); - - return null; - } - - public synchronized XCachedPrimitive strokePolyPolygon( XPolyPolygon2D xPolyPolygon, - ViewState viewState, - RenderState renderState, - StrokeAttributes strokeAttributes ) throws com.sun.star.lang.IllegalArgumentException - { - // cache - Graphics2D graphics = getGraphics(); - - // initialize the Graphics2D - CanvasUtils.setupGraphicsState( graphics, viewState, renderState, CanvasUtils.alsoSetupPaint ); - CanvasUtils.applyStrokeAttributes( graphics, strokeAttributes ); - - // stroke the polygon - graphics.draw( CanvasUtils.makeGeneralPath(xPolyPolygon) ); - - CanvasUtils.printLog( "XCanvas: strokePolyPolygon called" ); - - return null; - } - - public synchronized XCachedPrimitive strokeTexturedPolyPolygon( XPolyPolygon2D xPolyPolygon, - ViewState viewState, - RenderState renderState, - Texture[] textures, - StrokeAttributes strokeAttributes ) throws com.sun.star.lang.IllegalArgumentException, VolatileContentDestroyedException - { - return null; - } - - public synchronized XCachedPrimitive strokeTextureMappedPolyPolygon( XPolyPolygon2D xPolyPolygon, - ViewState viewState, - RenderState renderState, - Texture[] textures, - com.sun.star.geometry.XMapping2D xMapping, - StrokeAttributes strokeAttributes ) throws com.sun.star.lang.IllegalArgumentException, VolatileContentDestroyedException - { - return null; - } - - public synchronized XPolyPolygon2D queryStrokeShapes( com.sun.star.rendering.XPolyPolygon2D xPolyPolygon, - com.sun.star.rendering.ViewState viewState, - com.sun.star.rendering.RenderState renderState, - com.sun.star.rendering.StrokeAttributes strokeAttributes ) throws com.sun.star.lang.IllegalArgumentException - { - return null; - } - - public synchronized XCachedPrimitive fillPolyPolygon( com.sun.star.rendering.XPolyPolygon2D xPolyPolygon, - com.sun.star.rendering.ViewState viewState, - com.sun.star.rendering.RenderState renderState ) throws com.sun.star.lang.IllegalArgumentException - { - CanvasUtils.printLog( "CanvasBase.fillPolyPolygon() called" ); - - // cache - Graphics2D graphics = getGraphics(); - - // initialize the Graphics2D - CanvasUtils.setupGraphicsState( graphics, viewState, renderState, CanvasUtils.alsoSetupPaint ); - - // fill the polygon - graphics.fill( CanvasUtils.makeGeneralPath(xPolyPolygon) ); - - CanvasUtils.printLog( "XCanvas: fillPolyPolygon called" ); - - return null; - } - - public synchronized XCachedPrimitive fillTexturedPolyPolygon( com.sun.star.rendering.XPolyPolygon2D xPolyPolygon, - com.sun.star.rendering.ViewState viewState, - com.sun.star.rendering.RenderState renderState, - com.sun.star.rendering.Texture [] textures ) throws com.sun.star.lang.IllegalArgumentException - { - return null; - } - - public synchronized XCachedPrimitive fillTextureMappedPolyPolygon( XPolyPolygon2D xPolyPolygon, - ViewState viewState, - RenderState renderState, - Texture[] textures, - com.sun.star.geometry.XMapping2D xMapping ) throws com.sun.star.lang.IllegalArgumentException, VolatileContentDestroyedException - { - return null; - } - - public synchronized XCanvasFont createFont( FontRequest fontRequest, com.sun.star.beans.PropertyValue[] extraFontProperties, com.sun.star.geometry.Matrix2D fontMatrix ) throws com.sun.star.lang.IllegalArgumentException - { - // TODO: support extra arguments - return new CanvasFont( fontRequest, this ); - } - - public FontInfo[] queryAvailableFonts( FontInfo aFilter, com.sun.star.beans.PropertyValue[] aFontProperties ) throws com.sun.star.lang.IllegalArgumentException - { - // TODO - return null; - } - - public XCachedPrimitive drawText( StringContext text, XCanvasFont xFont, ViewState viewState, RenderState renderState, byte textDirection ) throws com.sun.star.lang.IllegalArgumentException - { - CanvasUtils.printLog( "CanvasBase.drawText() called" ); - - // cache - Graphics2D graphics = getGraphics(); - - CanvasUtils.printLog( "XCanvas: drawText called" ); - - CanvasUtils.setupGraphicsState( graphics, viewState, renderState, CanvasUtils.alsoSetupPaint ); - CanvasUtils.setupGraphicsFont( graphics, viewState, renderState, xFont ); - - CanvasUtils.printLog( "XCanvas: drawText rendering \""+ text.Text.substring(text.StartPosition, text.StartPosition+text.Length) + "\"" ); - - graphics.drawString( text.Text.substring(text.StartPosition, text.StartPosition+text.Length), (float)0.0, (float)0.0 ); - return null; - } - - public XCachedPrimitive drawTextLayout( XTextLayout layoutetText, ViewState viewState, RenderState renderState ) throws com.sun.star.lang.IllegalArgumentException - { - CanvasUtils.printLog( "CanvasBase.drawOffsettedText() called" ); - - // cache - Graphics2D graphics = getGraphics(); - - CanvasUtils.printLog( "XCanvas: drawOffsettedText called" ); - - CanvasUtils.setupGraphicsState( graphics, viewState, renderState, CanvasUtils.alsoSetupPaint ); - CanvasUtils.setupGraphicsFont( graphics, viewState, renderState, layoutetText.getFont() ); - - CanvasUtils.printLog( "XCanvas: drawOffsettedText canvas setup done" ); - - if( layoutetText instanceof TextLayout ) - { - ((TextLayout)layoutetText).draw( graphics ); - } - else - { - CanvasUtils.printLog( "drawTextLayout: mismatching TextLayout object." ); - throw new com.sun.star.lang.IllegalArgumentException(); - } - - return null; - } - - public synchronized XCachedPrimitive drawBitmap( com.sun.star.rendering.XBitmap xBitmap, - com.sun.star.rendering.ViewState viewState, - com.sun.star.rendering.RenderState renderState ) throws com.sun.star.lang.IllegalArgumentException - { - CanvasUtils.printLog( "CanvasBase.drawBitmap() called" ); - - // cache - Graphics2D graphics = getGraphics(); - - CanvasUtils.setupGraphicsState( graphics, viewState, renderState, CanvasUtils.alsoSetupPaint ); - - java.awt.image.BufferedImage bitmap = CanvasUtils.getBufferedImage( xBitmap ); - - if( !graphics.drawImage(bitmap, 0, 0, null) ) - CanvasUtils.printLog( "CanvasBase.drawBitmap: image paint incomplete" ); - - CanvasUtils.postRenderImageTreatment( bitmap ); - - return null; - } - - public synchronized XCachedPrimitive drawBitmapModulated( com.sun.star.rendering.XBitmap xBitmap, - com.sun.star.rendering.ViewState viewState, - com.sun.star.rendering.RenderState renderState ) throws com.sun.star.lang.IllegalArgumentException - { - CanvasUtils.printLog( "CanvasBase.drawBitmapModulated() called" ); - - // TODO(F3): Implement channel modulation - return drawBitmap(xBitmap, - viewState, - renderState); - } - - public synchronized XGraphicDevice getDevice() - { - CanvasUtils.printLog( "CanvasBase.getDevice() called" ); - return new CanvasGraphicDevice( getGraphics() ); - } -} diff --git a/canvas/source/java/CanvasBitmap.java b/canvas/source/java/CanvasBitmap.java deleted file mode 100644 index cfb7617dc094..000000000000 --- a/canvas/source/java/CanvasBitmap.java +++ /dev/null @@ -1,252 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -// Canvas -import com.sun.star.rendering.*; -import com.sun.star.geometry.*; - -public class CanvasBitmap - extends CanvasBase - implements com.sun.star.lang.XServiceInfo, - com.sun.star.rendering.XBitmapCanvas, - com.sun.star.rendering.XIntegerBitmap -{ - private java.awt.image.BufferedImage bitmap; - private java.awt.Graphics2D graphics; - - public CanvasBitmap( java.awt.image.BufferedImage _bitmap ) - { - bitmap = _bitmap; - graphics = bitmap.createGraphics(); - } - - public CanvasBitmap( IntegerSize2D mySize ) - { - bitmap = new java.awt.image.BufferedImage(mySize.Width, mySize.Height, - java.awt.image.BufferedImage.TYPE_4BYTE_ABGR); - graphics = bitmap.createGraphics(); - } - - public CanvasBitmap( RealSize2D newSize, boolean beFast, CanvasBitmap source ) - { -// java.awt.geom.AffineTransform transform = new java.awt.geom.AffineTransform(); -// transform.scale( newSize.width/size.Width, newSize.height/size.Height ); - -// // TODO: Maybe keep the image returned via -// // bitmap.getScaledInstance, and do scaling lazy. -// bitmap = new java.awt.image.BufferedImage((int)(newSize.width+.5), -// (int)(newSize.height+.5), -// java.awt.image.BufferedImage.TYPE_4BYTE_ABGR); - -// java.awt.image.AffineTransformOp transformer = -// new java.awt.image.AffineTransformOp( transform, -// java.awt.image.AffineTransformOp.TYPE_BILINEAR); - -// transformer.filter(source.getBufferedImage(), bitmap); - } - - public synchronized java.awt.image.BufferedImage getBufferedImage() - { - return bitmap; - } - - public java.awt.Graphics2D getGraphics() - { - return graphics; - } - - // - // XBitmap implementation - // ====================== - // - - public synchronized IntegerSize2D getSize() - { - return new IntegerSize2D( bitmap.getWidth(), - bitmap.getHeight() ); - } - - //---------------------------------------------------------------------------------- - - public synchronized XBitmapCanvas queryBitmapCanvas() - { - return this; - } - - //---------------------------------------------------------------------------------- - - public synchronized com.sun.star.rendering.XBitmap getScaledBitmap( RealSize2D newSize, boolean beFast ) throws com.sun.star.lang.IllegalArgumentException, VolatileContentDestroyedException - { - return new CanvasBitmap( newSize, beFast, this ); - } - - //---------------------------------------------------------------------------------- - - public synchronized boolean hasAlpha() - { - // TODO - return false; - } - - //---------------------------------------------------------------------------------- - - // - // XBitmapCanvas impl - // ================== - // - - public synchronized void copyRect( com.sun.star.rendering.XBitmapCanvas sourceCanvas, - com.sun.star.geometry.RealRectangle2D sourceRect, - com.sun.star.rendering.ViewState sourceViewState, - com.sun.star.rendering.RenderState sourceRenderState, - com.sun.star.geometry.RealRectangle2D destRect, - com.sun.star.rendering.ViewState destViewState, - com.sun.star.rendering.RenderState destRenderState ) - { - CanvasUtils.printLog( "JavaCanvas.copyRect() called" ); - - // TODO: create temp image when transform is non-trivial - - if( sourceCanvas == this ) - { - // copy rectangle within the canvas - getGraphics().copyArea((int)sourceRect.X1, - (int)sourceRect.Y1, - (int)(sourceRect.X2 - sourceRect.X1), - (int)(sourceRect.Y2 - sourceRect.Y1), - (int)(destRect.X1 - sourceRect.X1), - (int)(destRect.Y1 - sourceRect.Y1) ); - } - else - { - if( sourceCanvas instanceof JavaCanvas ) - { - // cache - CanvasUtils.setupGraphicsState( getGraphics(), destViewState, destRenderState, CanvasUtils.alsoSetupPaint ); - - java.awt.Image backBuffer = ((JavaCanvas)sourceCanvas).backBuffer.getBackBuffer(); - - // TODO: really extract correct source rect here - getGraphics().drawImage( backBuffer, 0, 0, null); - CanvasUtils.postRenderImageTreatment( backBuffer ); - } - // TODO: foreign canvas - } - } - - //---------------------------------------------------------------------------------- - - // - // XIntegerBitmap implementation - // ============================= - // - - public synchronized byte[] getData( IntegerBitmapLayout[] bitmapLayout, - IntegerRectangle2D rect ) - { - int [] pixelData = bitmap.getRGB( rect.X1, rect.Y1, rect.X2 - rect.X1, rect.Y1 - rect.Y2, null, 0, 0 ); - - return CanvasUtils.int2byte( pixelData ); - } - - //---------------------------------------------------------------------------------- - - public synchronized void setData( byte[] data, IntegerBitmapLayout bitmapLayout, com.sun.star.geometry.IntegerRectangle2D rect ) - { - int [] pixelData = CanvasUtils.byte2int( data ); - bitmap.setRGB( rect.X1, rect.Y1, rect.X2 - rect.X1, rect.Y2 - rect.Y1, pixelData, 0, bitmap.getWidth() ); - } - - //---------------------------------------------------------------------------------- - - public synchronized void setPixel( byte[] color, IntegerBitmapLayout bitmapLayout, com.sun.star.geometry.IntegerPoint2D pos ) - { - if( color.length != 4 ) - CanvasUtils.printLog( "CanvasBitmap.setPixel: Wrong color format" ); - - int pixel = color[0] + (color[1] + (color[2] + color[3]*256)*256)*256; - bitmap.setRGB( pos.X, pos.Y, pixel ); - } - - //---------------------------------------------------------------------------------- - - public synchronized byte[] getPixel( IntegerBitmapLayout[] bitmapLayout, - IntegerPoint2D pos ) - { - int pixel = bitmap.getRGB( pos.X, pos.Y ); - - byte[] res = new byte[4]; - res[0] = (byte)(pixel & 255); - res[1] = (byte)((pixel/256) & 255); - res[2] = (byte)((pixel/256/256) & 255); - res[3] = (byte)((pixel/256/256/256) & 255); - - return res; - } - - //---------------------------------------------------------------------------------- - - public synchronized XBitmapPalette getPalette() - { - return null; - } - - //---------------------------------------------------------------------------------- - - public synchronized IntegerBitmapLayout getMemoryLayout() - { - // TODO: finish that one - IntegerBitmapLayout layout = new IntegerBitmapLayout(); - - return layout; - } - - //---------------------------------------------------------------------------------- - - // - // XServiceInfo impl - // ================= - // - - private static final String s_implName = "XIntegerBitmap.java.impl"; - private static final String s_serviceName = "com.sun.star.rendering.IntegerBitmap"; - - public String getImplementationName() - { - return s_implName; - } - - public String [] getSupportedServiceNames() - { - return new String [] { s_serviceName }; - } - - public boolean supportsService( String serviceName ) - { - return serviceName.equals( s_serviceName ); - } -} diff --git a/canvas/source/java/CanvasClonedSprite.java b/canvas/source/java/CanvasClonedSprite.java deleted file mode 100644 index d5f85678db4f..000000000000 --- a/canvas/source/java/CanvasClonedSprite.java +++ /dev/null @@ -1,185 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -// Canvas -import com.sun.star.rendering.*; -import com.sun.star.geometry.*; - -// Java AWT -import java.awt.geom.*; - -public class CanvasClonedSprite - extends com.sun.star.lib.uno.helper.ComponentBase - implements com.sun.star.rendering.XSprite, - com.sun.star.lang.XServiceInfo, - SpriteBase -{ - private JavaCanvas canvas; - private double alpha; - private java.awt.geom.Point2D.Double outputPosition; - private SpriteRep spriteRep; - private SpriteBase original; - - //---------------------------------------------------------------------------------- - - public CanvasClonedSprite( JavaCanvas _canvas, - XSprite _original ) - { - CanvasUtils.printLog( "CanvasClonesSprite constructor called!" ); - - canvas = _canvas; - - if( _original instanceof SpriteBase ) - { - original = (SpriteBase)_original; - } - - alpha = 0.0; - outputPosition = new java.awt.geom.Point2D.Double(0.0,0.0); - - // TODO: throw on error here! - } - - //---------------------------------------------------------------------------------- - - // - // SpriteBase - // ========== - // - public SpriteRep getSpriteRep() - { - if( spriteRep == null ) - { - spriteRep = new SpriteRep( original.getSpriteRep() ); - - spriteRep.moveSprite( outputPosition ); - spriteRep.setSpriteAlpha( alpha ); - - // TODO: Check for spriteRep.buffer != null here, throw otherwise - } - return spriteRep; - } - - //---------------------------------------------------------------------------------- - - // - // XComponent - // ========== - // - public void dispose() - { - canvas = null; - spriteRep = null; - original = null; - - super.dispose(); - } - - //---------------------------------------------------------------------------------- - - // - // XSprite impl - // ================== - // - - public synchronized void setPriority( double nPriority ) - { - // TODO - } - - public synchronized void setAlpha( double _alpha ) - { - alpha = _alpha; - - if( spriteRep != null ) - { - spriteRep.setSpriteAlpha( alpha ); - } - } - - public synchronized void move( RealPoint2D _aNewPos, - ViewState _viewState, - RenderState _renderState ) - { - // transform given point with concatenated transformation - AffineTransform transform = CanvasUtils.ViewConcatRenderTransform( _viewState, _renderState ); - transform.transform( new java.awt.geom.Point2D.Double(_aNewPos.X, - _aNewPos.Y), - outputPosition ); - - if( spriteRep != null ) - { - spriteRep.moveSprite( outputPosition ); - } - } - - public synchronized void transform( AffineMatrix2D aTransformation ) throws com.sun.star.lang.IllegalArgumentException - { - // TODO - } - - public synchronized void clip( XPolyPolygon2D aClip ) - { - // TODO - } - - public synchronized void show() - { - canvas.showSprite( this ); - canvas.updateScreen( false ); - } - - public synchronized void hide() - { - canvas.hideSprite( this ); - } - //---------------------------------------------------------------------------------- - - private static final String s_implName = "XSprite.java.impl"; - private static final String s_serviceName = "com.sun.star.rendering.Sprite"; - - //---------------------------------------------------------------------------------- - - // - // XServiceInfo impl - // ================= - // - public String getImplementationName() - { - return s_implName; - } - - public String [] getSupportedServiceNames() - { - return new String [] { s_serviceName }; - } - - public boolean supportsService( String serviceName ) - { - return serviceName.equals( s_serviceName ); - } -} diff --git a/canvas/source/java/CanvasCustomSprite.java b/canvas/source/java/CanvasCustomSprite.java deleted file mode 100644 index c3165fa68e80..000000000000 --- a/canvas/source/java/CanvasCustomSprite.java +++ /dev/null @@ -1,204 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -// Canvas -import com.sun.star.rendering.*; -import com.sun.star.geometry.*; - -// Java AWT -import java.awt.*; -import java.awt.geom.*; - -public class CanvasCustomSprite - extends com.sun.star.lib.uno.helper.ComponentBase - implements com.sun.star.rendering.XCustomSprite, - com.sun.star.lang.XServiceInfo, - SpriteBase -{ - private JavaCanvas canvas; - private RealSize2D spriteSize; - private Graphics2D referenceGraphics; - private double alpha; - private java.awt.geom.Point2D.Double outputPosition; - private SpriteRep spriteRep; - - //---------------------------------------------------------------------------------- - - public CanvasCustomSprite( RealSize2D _spriteSize, - JavaCanvas _canvas, - Graphics2D _referenceGraphics ) - { - CanvasUtils.printLog( "CanvasCustomSprite constructor called, size is (" + _spriteSize.Width + ", " + _spriteSize.Height + ")" ); - - canvas = _canvas; - spriteSize = _spriteSize; - referenceGraphics = _referenceGraphics; - alpha = 0.0; - outputPosition = new java.awt.geom.Point2D.Double(0.0,0.0); - } - - //---------------------------------------------------------------------------------- - - // - // SpriteBase - // ========== - // - public synchronized SpriteRep getSpriteRep() - { - if( spriteRep == null ) - { - spriteRep = new SpriteRep(); - - spriteRep.setupBuffer(referenceGraphics, (int)(spriteSize.Width+.5), (int)(spriteSize.Height+.5) ); - - spriteRep.moveSprite( outputPosition ); - spriteRep.setSpriteAlpha( alpha ); - } - return spriteRep; - } - - //---------------------------------------------------------------------------------- - - // - // XComponent - // ========== - // - public void dispose() - { - if( spriteRep != null ) - spriteRep.dispose(); - - canvas = null; - referenceGraphics = null; - spriteRep = null; - - super.dispose(); - } - - //---------------------------------------------------------------------------------- - - // - // XCustomSprite impl - // ================== - // - - public synchronized void setPriority( double nPriority ) - { - // TODO - } - - public synchronized void setAlpha( double _alpha ) - { - CanvasUtils.printLog( "CanvasCustomSprite.setAlpha() called" ); - - alpha = _alpha; - - if( spriteRep != null ) - { - spriteRep.setSpriteAlpha( alpha ); - } - } - - public synchronized void move( RealPoint2D _aNewPos, - ViewState _viewState, - RenderState _renderState ) - { - CanvasUtils.printLog( "CanvasCustomSprite.move() called" ); - - // transform given point with concatenated transformation - AffineTransform transform = CanvasUtils.ViewConcatRenderTransform( _viewState, _renderState ); - transform.transform( new java.awt.geom.Point2D.Double(_aNewPos.X, - _aNewPos.Y), - outputPosition ); - - if( spriteRep != null ) - { - spriteRep.moveSprite( outputPosition ); - } - } - - public synchronized void transform( AffineMatrix2D aTransformation ) throws com.sun.star.lang.IllegalArgumentException - { - // TODO - } - - public synchronized void clip( XPolyPolygon2D aClip ) - { - // TODO - } - - public synchronized void show() - { - CanvasUtils.printLog( "CanvasCustomSprite.show() called" ); - - canvas.showSprite( this ); - canvas.updateScreen( false ); - } - - public synchronized void hide() - { - CanvasUtils.printLog( "CanvasCustomSprite.hide() called" ); - - canvas.hideSprite( this ); - - // do _not_ dispose clear SpriteRep, since we cannot actively - // repaint ourselves - } - - public synchronized com.sun.star.rendering.XCanvas getContentCanvas() - { - CanvasUtils.printLog( "CanvasCustomSprite.getContentCanvas() called" ); - - return getSpriteRep().getContentCanvas(); - } - - //---------------------------------------------------------------------------------- - - private static final String s_implName = "XCustomSprite.java.impl"; - private static final String s_serviceName = "com.sun.star.rendering.CustomSprite"; - - //---------------------------------------------------------------------------------- - - // - // XServiceInfo impl - // ================= - // - public String getImplementationName() - { - return s_implName; - } - - public String [] getSupportedServiceNames() - { - return new String [] { s_serviceName }; - } - - public boolean supportsService( String serviceName ) - { - return serviceName.equals( s_serviceName ); - } -} diff --git a/canvas/source/java/CanvasFont.java b/canvas/source/java/CanvasFont.java deleted file mode 100644 index 1ca2cc1aa3ec..000000000000 --- a/canvas/source/java/CanvasFont.java +++ /dev/null @@ -1,116 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -// Canvas -import com.sun.star.rendering.*; - -public class CanvasFont - extends com.sun.star.lib.uno.helper.ComponentBase - implements com.sun.star.lang.XServiceInfo, - com.sun.star.rendering.XCanvasFont -{ - private CanvasBase associatedCanvas; - private com.sun.star.rendering.FontRequest fontRequest; - private java.awt.Font font; - - //---------------------------------------------------------------------------------- - - public CanvasFont( com.sun.star.rendering.FontRequest _fontRequest, - CanvasBase _canvas ) - { - associatedCanvas = _canvas; - fontRequest = _fontRequest; - - // TODO: Use proper attributes here, first of all, use fractional point font size - font = new java.awt.Font( fontRequest.FontDescription.FamilyName, java.awt.Font.PLAIN, (int)(fontRequest.CellSize + .5) ); - } - - public java.awt.Font getFont() - { - return font; - } - - //---------------------------------------------------------------------------------- - - // - // XCanvasFont implementation - // =========================== - // - - public XTextLayout createTextLayout( StringContext aText, byte nDirection, long nRandomSeed ) - { - return new TextLayout( aText, nDirection, nRandomSeed, this, associatedCanvas ); - } - - public FontRequest getFontRequest( ) - { - return fontRequest; - } - - public FontMetrics getFontMetrics( ) - { - // TODO - return null; - } - - public double[] getAvailableSizes( ) - { - // TODO - return null; - } - - public com.sun.star.beans.PropertyValue[] getExtraFontProperties( ) - { - // TODO - return null; - } - - //---------------------------------------------------------------------------------- - - // - // XServiceInfo impl - // ================= - // - - private static final String s_implName = "CanvasFont.java.impl"; - private static final String s_serviceName = "com.sun.star.rendering.XCanvasFont"; - - public String getImplementationName() - { - return s_implName; - } - - public String [] getSupportedServiceNames() - { - return new String [] { s_serviceName }; - } - - public boolean supportsService( String serviceName ) - { - return serviceName.equals( s_serviceName ); - } -} diff --git a/canvas/source/java/CanvasGraphicDevice.java b/canvas/source/java/CanvasGraphicDevice.java deleted file mode 100644 index c521d627f1a9..000000000000 --- a/canvas/source/java/CanvasGraphicDevice.java +++ /dev/null @@ -1,222 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -// Canvas -import com.sun.star.rendering.*; -import com.sun.star.geometry.*; - -// Java AWT -import java.awt.*; - -public class CanvasGraphicDevice - extends com.sun.star.lib.uno.helper.ComponentBase - implements com.sun.star.lang.XServiceInfo, - com.sun.star.beans.XPropertySet, - com.sun.star.rendering.XGraphicDevice -{ - private java.awt.Graphics2D graphics; - private java.awt.GraphicsConfiguration graphicsConfig; - - //---------------------------------------------------------------------------------- - - public CanvasGraphicDevice( java.awt.Graphics2D _graphics ) - { - graphics = _graphics; - graphicsConfig = graphics.getDeviceConfiguration(); - } - - //---------------------------------------------------------------------------------- - - // - // GraphicsDevice implementation - // ============================= - // - public synchronized XBufferController getBufferController() - { - // Use java.awt.image.BufferStrategy to implement XBufferController - CanvasUtils.printLog( "CanvasGraphicDevice.getBufferController!" ); - return null; - } - - public synchronized XColorSpace getDeviceColorSpace() - { - CanvasUtils.printLog( "CanvasGraphicDevice.getDeviceColorSpace!" ); - return null; - } - - public synchronized com.sun.star.geometry.RealSize2D getPhysicalResolution() - { - CanvasUtils.printLog( "CanvasGraphicDevice.getPhysicalResolution!" ); - // TODO: getDefaultTransform + getNormalizingTransform - return new com.sun.star.geometry.RealSize2D(100,100); - } - - public synchronized com.sun.star.geometry.RealSize2D getPhysicalSize() - { - CanvasUtils.printLog( "CanvasGraphicDevice.getSize!" ); - java.awt.Rectangle bounds = graphicsConfig.getBounds(); - - return new com.sun.star.geometry.RealSize2D(bounds.width, bounds.height); - } - - public synchronized XLinePolyPolygon2D createCompatibleLinePolyPolygon( RealPoint2D[][] points ) - { - CanvasUtils.printLog( "createCompatibleLinePolyPolygon" ); - return new LinePolyPolygon( points ); - } - - public synchronized XBezierPolyPolygon2D createCompatibleBezierPolyPolygon( RealBezierSegment2D[][] points ) - { - CanvasUtils.printLog( "createCompatibleBezierPolyPolygon" ); - return new BezierPolyPolygon( points ); - } - - public synchronized com.sun.star.rendering.XBitmap createCompatibleBitmap( IntegerSize2D size ) - { - CanvasUtils.printLog( "createCompatibleBitmap called with size (" + size.Width + ", " + size.Height + ")" ); - return new CanvasBitmap( graphicsConfig.createCompatibleImage( size.Width, - size.Height, - Transparency.OPAQUE ) ); - } - - public synchronized com.sun.star.rendering.XVolatileBitmap createVolatileBitmap( IntegerSize2D size ) - { - CanvasUtils.printLog( "createVolatileBitmap called with size (" + size.Width + ", " + size.Height + ")" ); - //return new CanvasBitmap( graphicsConfig.createCompatibleVolatileImage( size.Width, size.Height ) ); - return null; - } - - public synchronized com.sun.star.rendering.XBitmap createCompatibleAlphaBitmap( IntegerSize2D size ) - { - CanvasUtils.printLog( "createCompatibleBitmap called with size (" + size.Width + ", " + size.Height + ")" ); - return new CanvasBitmap( graphicsConfig.createCompatibleImage( size.Width, - size.Height, - Transparency.TRANSLUCENT ) ); - } - - public synchronized com.sun.star.rendering.XVolatileBitmap createVolatileAlphaBitmap( IntegerSize2D size ) - { - CanvasUtils.printLog( "createVolatileBitmap called with size (" + size.Width + ", " + size.Height + ")" ); - //return new CanvasBitmap( graphicsConfig.createCompatibleVolatileImage( size.Width, size.Height ) ); - return null; - } - - public synchronized com.sun.star.rendering.XParametricPolyPolygon2DFactory getParametricPolyPolygonFactory() - { - // TODO - return null; - } - - public synchronized com.sun.star.beans.XPropertySetInfo getPropertySetInfo() - { - // This is a stealth property set - return null; - } - - public synchronized void setPropertyValue( String aPropertyName, java.lang.Object aValue ) throws com.sun.star.beans.PropertyVetoException - { - // all our properties are read-only - throw new com.sun.star.beans.PropertyVetoException(); - } - - public synchronized java.lang.Object getPropertyValue( String PropertyName ) throws com.sun.star.beans.UnknownPropertyException - { - if( PropertyName == "DeviceHandle" ) - return graphics; - - throw new com.sun.star.beans.UnknownPropertyException(); - } - - public synchronized void addPropertyChangeListener( String aPropertyName, com.sun.star.beans.XPropertyChangeListener xListener ) throws com.sun.star.beans.UnknownPropertyException - { - if( aPropertyName == "DeviceHandle" ) - return; - - throw new com.sun.star.beans.UnknownPropertyException(); - } - - public synchronized void removePropertyChangeListener( String aPropertyName, com.sun.star.beans.XPropertyChangeListener aListener ) throws com.sun.star.beans.UnknownPropertyException - { - if( aPropertyName == "DeviceHandle" ) - return; - - throw new com.sun.star.beans.UnknownPropertyException(); - } - - public synchronized void addVetoableChangeListener( String PropertyName, com.sun.star.beans.XVetoableChangeListener aListener ) throws com.sun.star.beans.UnknownPropertyException - { - if( PropertyName == "DeviceHandle" ) - return; - - throw new com.sun.star.beans.UnknownPropertyException(); - } - - public synchronized void removeVetoableChangeListener( String PropertyName, com.sun.star.beans.XVetoableChangeListener aListener ) throws com.sun.star.beans.UnknownPropertyException - { - if( PropertyName == "DeviceHandle" ) - return; - - throw new com.sun.star.beans.UnknownPropertyException(); - } - - - public synchronized boolean hasFullScreenMode() - { - return graphicsConfig.getDevice().isFullScreenSupported(); - } - - public synchronized boolean enterFullScreenMode( boolean bEnter ) - { - return false; - } - - //---------------------------------------------------------------------------------- - - // - // XServiceInfo impl - // ================= - // - - private static final String s_implName = "XGraphicsDevice.java.impl"; - private static final String s_serviceName = "com.sun.star.rendering.GraphicsDevice"; - - public String getImplementationName() - { - return s_implName; - } - - public String [] getSupportedServiceNames() - { - return new String [] { s_serviceName }; - } - - public boolean supportsService( String serviceName ) - { - return serviceName.equals( s_serviceName ); - } - -} diff --git a/canvas/source/java/CanvasSprite.java b/canvas/source/java/CanvasSprite.java deleted file mode 100644 index 9b2cfc0debad..000000000000 --- a/canvas/source/java/CanvasSprite.java +++ /dev/null @@ -1,308 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -// Canvas -import com.sun.star.rendering.*; -import com.sun.star.geometry.*; - -// Java AWT -import java.awt.*; -import java.awt.geom.*; - -public class CanvasSprite - extends com.sun.star.lib.uno.helper.ComponentBase - implements com.sun.star.rendering.XAnimatedSprite, - com.sun.star.lang.XServiceInfo, - SpriteBase -{ - private XAnimation spriteAnimation; - private JavaCanvas canvas; - private Graphics2D referenceGraphics; - private SpriteRunner runner; - private ViewState viewState; - private double alpha; - private java.awt.geom.Point2D.Double outputPosition; - private SpriteRep spriteRep; - - //---------------------------------------------------------------------------------- - - public CanvasSprite( XAnimation _animation, JavaCanvas _canvas, Graphics2D _referenceGraphics ) - { - CanvasUtils.printLog( "CanvasSprite constructor called!" ); - - spriteAnimation = _animation; - canvas = _canvas; - referenceGraphics = _referenceGraphics; - alpha = 0.0; - outputPosition = new java.awt.geom.Point2D.Double(0.0,0.0); - - runner = new SpriteRunner( this, spriteAnimation, canvas ); - } - - public synchronized ViewState getViewState() - { - return viewState; - } - - //---------------------------------------------------------------------------------- - - // - // SpriteBase - // ========== - // - public synchronized SpriteRep getSpriteRep() - { - if( spriteRep == null ) - { - spriteRep = new SpriteRep(); - - setupSpriteBuffering( CanvasUtils.makeTransform( getViewState().AffineTransform ) ); - - spriteRep.moveSprite( outputPosition ); - spriteRep.setSpriteAlpha( alpha ); - - // render initial sprite content - updateAnimation(); - } - return spriteRep; - } - - //---------------------------------------------------------------------------------- - - // - // XComponent - // ========== - // - public void dispose() - { - // end the animation thread - if( runner != null ) - { - runner.quit(); - try - { - runner.join(0); // and wait until it's really over - } - catch( java.lang.InterruptedException e ) {} - } - - if( spriteRep != null ) - spriteRep.dispose(); - - canvas = null; - spriteAnimation = null; - runner = null; - referenceGraphics = null; - spriteRep = null; - - super.dispose(); - } - - //---------------------------------------------------------------------------------- - - // - // XSprite impl - // ============ - // - - public synchronized void startAnimation( double speed ) - { - runner.startAnimation( speed ); - } - - public synchronized void stopAnimation() - { - runner.stopAnimation(); - } - - public synchronized void resetAnimation() - { - runner.resetAnimation(); - } - - public synchronized void updateAnimation() - { - // only call render explicitely, if animation not - // running. Otherwise, next animation render will update - // anyway. - if( spriteRep != null && - !runner.isAnimationActive() ) - { - spriteRep.renderAnimation( spriteAnimation, getViewState(), runner.getCurrentT() ); - } - } - - public synchronized void setPriority( double nPriority ) - { - // TODO - } - - public synchronized void setAlpha( double _alpha ) - { - alpha = _alpha; - - if( spriteRep != null ) - { - spriteRep.setSpriteAlpha( alpha ); - } - } - - public synchronized void move( com.sun.star.geometry.RealPoint2D _aNewPos, - com.sun.star.rendering.ViewState _viewState, - com.sun.star.rendering.RenderState _renderState ) - { - // transform given point with concatenated transformation - AffineTransform transform = CanvasUtils.ViewConcatRenderTransform( _viewState, _renderState ); - transform.transform( new java.awt.geom.Point2D.Double(_aNewPos.X, - _aNewPos.Y), - outputPosition ); - - if( spriteRep != null ) - { - spriteRep.moveSprite( outputPosition ); - } - } - - public synchronized void transform( AffineMatrix2D aTransformation ) throws com.sun.star.lang.IllegalArgumentException - { - // TODO - } - - public synchronized void clip( XPolyPolygon2D aClip ) - { - // TODO - } - - public synchronized void show() - { - canvas.showSprite( this ); - canvas.updateScreen( false ); - } - - public synchronized void hide() - { - canvas.hideSprite( this ); - - // dispose and clear SpriteRep, animation content can be - // regenerated at any time - if( spriteRep != null ) - spriteRep.dispose(); - - spriteRep = null; - } - - public synchronized void setViewState( ViewState _viewState ) - { - viewState = CanvasUtils.createAnimationViewState(_viewState, - getAnimationAttributes()); - - CanvasUtils.printTransform( CanvasUtils.makeTransform( viewState.AffineTransform ), - "CanvasSprite.setViewState" ); - - if( spriteRep != null ) - { - // calculate bounds of view-transformed animation output rectangle - setupSpriteBuffering( CanvasUtils.makeTransform(getViewState().AffineTransform) ); - updateAnimation(); - } - } - - public synchronized AnimationAttributes getAnimationAttributes() - { - return spriteAnimation.getAnimationAttributes(); - } - - public synchronized void setAll( RealPoint2D _aNewPos, - ViewState _viewState, - RenderState _renderState, - double _alpha, - boolean bUpdateAnimation ) - { - alpha = _alpha; - - // transform given point with concatenated transformation - AffineTransform transform = CanvasUtils.ViewConcatRenderTransform( _viewState, _renderState ); - transform.transform( new java.awt.geom.Point2D.Double(_aNewPos.X, - _aNewPos.Y), - outputPosition ); - - if( spriteRep != null ) - { - spriteRep.setSpriteAlpha( alpha ); - spriteRep.moveSprite( outputPosition ); - - if( bUpdateAnimation ) - updateAnimation(); - } - } - - //---------------------------------------------------------------------------------- - - private void setupSpriteBuffering( AffineTransform _viewTransform ) - { - // determine bounds of view-transformed animation output rectangle - com.sun.star.geometry.RealSize2D animSize = getAnimationAttributes().UntransformedSize; - - java.awt.geom.Rectangle2D.Double aTransformedBounds = - CanvasUtils.calcTransformedRectBounds( new java.awt.geom.Rectangle2D.Double(0.0,0.0, - animSize.Width, - animSize.Height), - _viewTransform ); - CanvasUtils.printTransform( _viewTransform, "setupSpriteBuffering" ); - CanvasUtils.printLog( "setupSpriteBuffering: bounds are (" + aTransformedBounds.width + ", " + aTransformedBounds.height + ")" ); - - // create a buffer of the appropriate size - spriteRep.setupBuffer(referenceGraphics, (int)(aTransformedBounds.width+.5), - (int)(aTransformedBounds.height+.5) ); - } - - //---------------------------------------------------------------------------------- - - private static final String s_implName = "XSprite.java.impl"; - private static final String s_serviceName = "com.sun.star.rendering.Sprite"; - - //---------------------------------------------------------------------------------- - - // - // XServiceInfo impl - // ================= - // - public String getImplementationName() - { - return s_implName; - } - - public String [] getSupportedServiceNames() - { - return new String [] { s_serviceName }; - } - - public boolean supportsService( String serviceName ) - { - return serviceName.equals( s_serviceName ); - } -} diff --git a/canvas/source/java/CanvasTest_perftest.java b/canvas/source/java/CanvasTest_perftest.java deleted file mode 100644 index 047c9de3b16b..000000000000 --- a/canvas/source/java/CanvasTest_perftest.java +++ /dev/null @@ -1,676 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -// UNO -import com.sun.star.uno.UnoRuntime; -import com.sun.star.uno.XComponentContext; -import com.sun.star.uno.AnyConverter; -import com.sun.star.uno.IQueryInterface; -import com.sun.star.lang.XInitialization; -import com.sun.star.lib.uno.helper.WeakBase; - -// OOo AWT -import com.sun.star.awt.*; - -// Canvas -import com.sun.star.rendering.*; - -// Java AWT -import java.awt.*; -import java.awt.image.*; -import java.awt.geom.*; - -public class CanvasTest - extends CanvasBase - implements com.sun.star.awt.XWindow, - com.sun.star.rendering.XSpriteCanvas, - com.sun.star.lang.XServiceInfo, - com.sun.star.lang.XInitialization -{ - private WindowAdapter dummyFrame; - private BackBuffer backBuffer; - private java.awt.image.BufferStrategy bufferStrategy; - - private java.awt.Font fpsFont; - private long lastTime; - - - // TEST ONLY { - private static int testWidth = 1600; - private static int testHeight = 1200; - private BufferedImage backgroundBuffer; - private BufferedImage buffer; - private BufferedImage buffer2; - private Graphics2D backBufGraphics; - private Graphics2D bufferGraphics; - private Graphics2D buffer2Graphics; - private float currAlpha; - // TEST ONLY } - - - - public Graphics2D getGraphics() - { - return backBuffer.getGraphics(); - } - - //---------------------------------------------------------------------------------- - - // - // XInitialization - // =============== - // - public void initialize( java.lang.Object[] arguments ) - { - CanvasUtils.printLog( "CanvasTest.initialize called!" ); - - // Do that as the very first thing. The Java2D internal - // classes choose their render path at initialization time, - // thus this must happen before doing _any_ GUI. - - // TODO: Put those flags into javarc/java.ini, we're maybe - // coming late into a running JVM! - - // now, we're getting slightly system dependent here. - String os = (String) System.getProperty("os.name"); - - CanvasUtils.printLog( "System detected: " + os ); - - // tweak some speed knobs... - if( os.startsWith("Windows") ) - { - System.setProperty("sun.java2d.translaccel", "true"); - System.setProperty("sun.java2d.ddforcevram", "true"); - //System.setProperty("sun.java2d.accthreshold", "0"); - - CanvasUtils.printLog( "Optimizing for Windows" ); - } - else - { - System.setProperty("sun.java2d.opengl", "true"); - - CanvasUtils.printLog( "Optimizing for Unix" ); - } - - /* we're initialized with the following array of anys: - - arguments[0] = pointer to VCL window - arguments[1] = Integer (operating system window handle) - arguments[2] = com.sun.star.awt.Rectangle (position and size within that OS window) - arguments[3] = boolean (fullsize window or not) - - We then generate a dummy Java frame with that window as the - parent, to fake a root window for the Java implementation. - */ - try - { - com.sun.star.awt.Rectangle boundRect = (com.sun.star.awt.Rectangle) arguments[2]; - - //boolean isFullScreen = arguments[1]; - boolean isFullScreen = true; - //AnyConverter.toBoolean( arguments[3] ) ); - - // fake a root for Java in VCL window. Pass the flag - // whether we shall run fullscreen, too. - dummyFrame = new WindowAdapter( AnyConverter.toInt( arguments[1] ), isFullScreen ); - - if( isFullScreen ) - { - // blow window up to fullscreen. Otherwise, we cannot clear the whole screen, - // which results in ugly flickering - Dimension screenSize = dummyFrame.frame.getToolkit().getScreenSize(); - boundRect.X = 0; - boundRect.Y = 0; - boundRect.Width = screenSize.width-1; - boundRect.Height = screenSize.height-1; - } - - dummyFrame.setPosSize( boundRect.X, boundRect.Y, boundRect.Width, boundRect.Height, (short)0 ); - CanvasUtils.printLog( "Window size: " + boundRect.Width + ", " + boundRect.Height ); - - // TEST - if( true ) - { - backBuffer = new BackBuffer( (Graphics2D) dummyFrame.frame.getGraphics(), - Math.max(1,boundRect.Width), - Math.max(1,boundRect.Height) ); - } - else - { - backBuffer = new BackBuffer( (Graphics2D) dummyFrame.frame.getGraphics(), - 10, 10 ); - } - - // TODO: Maybe delay double buffer init until first sprite creation - dummyFrame.frame.createBufferStrategy(2); - bufferStrategy = dummyFrame.frame.getBufferStrategy(); - - if( bufferStrategy.getCapabilities().isPageFlipping() ) - CanvasUtils.printLog( "CanvasTest.initialize double buffering is using page flipping!" ); - else - CanvasUtils.printLog( "CanvasTest.initialize double buffering is using blitting!" ); - - lastTime = System.currentTimeMillis(); - fpsFont = new java.awt.Font( "Times", Font.PLAIN, 20 ); - - - if( false ) - { - // TEST ONLY { - Graphics2D frameGraphics= (Graphics2D) dummyFrame.frame.getGraphics(); - backgroundBuffer = frameGraphics.getDeviceConfiguration().createCompatibleImage(testWidth,testHeight); // TODO: size dynamic - buffer = frameGraphics.getDeviceConfiguration().createCompatibleImage(testWidth,testHeight, - Transparency.TRANSLUCENT); - buffer2 = frameGraphics.getDeviceConfiguration().createCompatibleImage(testWidth,testHeight, - Transparency.TRANSLUCENT); - bufferGraphics = (Graphics2D)buffer.getGraphics(); - buffer2Graphics = (Graphics2D)buffer2.getGraphics(); - backBufGraphics = (Graphics2D)backgroundBuffer.getGraphics(); - currAlpha = 0.1f; - - // init content - Font font = new Font( "Times", Font.PLAIN, 100 ); - - bufferGraphics.setComposite( AlphaComposite.getInstance(AlphaComposite.CLEAR)); - bufferGraphics.fillRect( 0,0,testWidth,testHeight ); - - bufferGraphics.setComposite( AlphaComposite.getInstance(AlphaComposite.SRC_OVER)); - bufferGraphics.setColor( Color.red ); - bufferGraphics.fillRect( 0,0,testWidth/2,testHeight/2 ); - bufferGraphics.setColor( Color.green ); - bufferGraphics.fillRect( testWidth/2,0,testWidth,testHeight/2 ); - bufferGraphics.setColor( Color.blue ); - bufferGraphics.fillRect( 0,testHeight/2,testWidth/2,testHeight ); - - buffer2Graphics.setColor( Color.red ); - buffer2Graphics.fillRect( 0,0,testWidth/2,testHeight/2 ); - buffer2Graphics.setColor( Color.green ); - buffer2Graphics.fillRect( testWidth/2,0,testWidth,testHeight/2 ); - buffer2Graphics.setColor( Color.blue ); - buffer2Graphics.fillRect( 0,testHeight/2,testWidth/2,testHeight ); - - backBufGraphics.setColor( Color.white ); - backBufGraphics.fillRect(0,0,testWidth,testHeight); - backBufGraphics.setColor( Color.red ); - backBufGraphics.setFont( font ); - int i, turns=15; - for(i=0; i<turns; ++i) - { - backBufGraphics.drawString( "Crossfade test", testWidth*i/turns, testHeight*i/turns ); - } - // TEST ONLY } - } - - CanvasUtils.printLog( "CanvasTest.initialize finished!" ); - } - catch( com.sun.star.lang.IllegalArgumentException e ) - { - CanvasUtils.printLog( "Cannot create EmbeddedFrame within VCL window hierarchy!" ); - } - } - - //---------------------------------------------------------------------------------- - - // - // XComponent - // ========== - // - public void dispose() - { - CanvasUtils.printLog( "CanvasTest: disposed!" ); - - // destroy all active sprites - java.util.Set entries = activeSprites.entrySet(); - java.util.Iterator iter = entries.iterator(); - - while( iter.hasNext() ) - { - java.util.Map.Entry entry = (java.util.Map.Entry)iter.next(); - if( entry.getValue() != null ) - ((SpriteRep)entry.getValue()).dispose(); - } - - if( bufferStrategy != null ) - bufferStrategy.getDrawGraphics().dispose(); // really necessary? - - if( dummyFrame != null ) - dummyFrame.dispose(); - - if( backBuffer != null) - backBuffer.dispose(); - - bufferStrategy = null; - dummyFrame = null; - backBuffer = null; - - super.dispose(); - } - - //---------------------------------------------------------------------------------- - - public CanvasTest( XComponentContext xContext ) - { - CanvasUtils.printLog( "CanvasTest constructor called!" ); - activeSprites = new java.util.HashMap( 33 ); - } - - //---------------------------------------------------------------------------------- - - // - // XWindow interface - // ================= - // - // This is delegated to WindowAdapter! - // - public synchronized void setPosSize( int X, int Y, int Width, int Height, short Flags ) - { - if( dummyFrame != null ) - { - dummyFrame.setPosSize( X, Y, Width, Height, Flags ); - - Width = Math.max(1,Width); - Height= Math.max(1,Height); - - CanvasUtils.printLog( "CanvasTest graphics set to " + Width + "," + Height ); - backBuffer.setSize(Width,Height); - } - } - - public synchronized com.sun.star.awt.Rectangle getPosSize( ) - { - if( dummyFrame != null ) - return dummyFrame.getPosSize(); - - return new com.sun.star.awt.Rectangle(); - } - - public synchronized void setVisible( boolean visible ) - { - if( dummyFrame != null ) - dummyFrame.setVisible( visible ); - } - - public synchronized void setEnable( boolean enable ) - { - if( dummyFrame != null ) - dummyFrame.setEnable( enable ); - } - - public synchronized void setFocus() - { - if( dummyFrame != null ) - dummyFrame.setFocus(); - } - - public synchronized void addWindowListener( XWindowListener xListener ) - { - if( dummyFrame != null ) - dummyFrame.addWindowListener( xListener ); - } - - public synchronized void removeWindowListener( XWindowListener xListener ) - { - if( dummyFrame != null ) - dummyFrame.removeWindowListener( xListener ); - } - - public synchronized void addFocusListener( XFocusListener xListener ) - { - if( dummyFrame != null ) - dummyFrame.addFocusListener( xListener ); - } - - public synchronized void removeFocusListener( XFocusListener xListener ) - { - if( dummyFrame != null ) - dummyFrame.removeFocusListener( xListener ); - } - - public synchronized void addKeyListener( XKeyListener xListener ) - { - if( dummyFrame != null ) - dummyFrame.addKeyListener( xListener ); - } - - public synchronized void removeKeyListener( XKeyListener xListener ) - { - if( dummyFrame != null ) - dummyFrame.removeKeyListener( xListener ); - } - - public synchronized void addMouseListener( XMouseListener xListener ) - { - if( dummyFrame != null ) - dummyFrame.addMouseListener( xListener ); - } - - public synchronized void removeMouseListener( XMouseListener xListener ) - { - if( dummyFrame != null ) - dummyFrame.removeMouseListener( xListener ); - } - - public synchronized void addMouseMotionListener( XMouseMotionListener xListener ) - { - if( dummyFrame != null ) - dummyFrame.addMouseMotionListener( xListener ); - } - - public synchronized void removeMouseMotionListener( XMouseMotionListener xListener ) - { - if( dummyFrame != null ) - dummyFrame.removeMouseMotionListener( xListener ); - } - - public synchronized void addPaintListener( XPaintListener xListener ) - { - if( dummyFrame != null ) - dummyFrame.addPaintListener( xListener ); - } - - public synchronized void removePaintListener( XPaintListener xListener ) - { - if( dummyFrame != null ) - dummyFrame.removePaintListener( xListener ); - } - - //---------------------------------------------------------------------------------- - - // - // XBitmapCanvas impl - // ================== - // - - public synchronized void copyRect( com.sun.star.rendering.XBitmapCanvas sourceCanvas, - com.sun.star.rendering.Rectangle2D sourceRect, - com.sun.star.rendering.ViewState sourceViewState, - com.sun.star.rendering.RenderState sourceRenderState, - com.sun.star.rendering.Rectangle2D destRect, - com.sun.star.rendering.ViewState destViewState, - com.sun.star.rendering.RenderState destRenderState ) - { - CanvasUtils.printLog( "CanvasTest.copyRect() called" ); - - // TODO: create temp image when transform is non-trivial - - if( sourceCanvas == this ) - { - // copy rectangle within the canvas - getGraphics().copyArea((int)sourceRect.x1, - (int)sourceRect.y1, - (int)(sourceRect.x2 - sourceRect.x1), - (int)(sourceRect.y2 - sourceRect.y1), - (int)(destRect.x1 - sourceRect.x1), - (int)(destRect.y1 - sourceRect.y1) ); - } - else - { - if( sourceCanvas instanceof CanvasTest ) - { - // cache - CanvasUtils.setupGraphicsState( getGraphics(), destViewState, destRenderState, CanvasUtils.alsoSetupPaint ); - - java.awt.Image backBuffer = ((CanvasTest)sourceCanvas).backBuffer.getBackBuffer(); - - // TODO: really extract correct source rect here - getGraphics().drawImage( backBuffer, 0, 0, null); - CanvasUtils.postRenderImageTreatment( backBuffer ); - } - // TODO: foreign canvas - } - } - - //---------------------------------------------------------------------------------- - - // a map of SpriteReps, with Sprite object as keys. Contains all - // active (i.e. visible) sprites, the SpriteReps are used to - // repaint the sprite content at any time. - private java.util.HashMap activeSprites; - - // - // XSpriteCanvas impl - // ================== - // - - public synchronized com.sun.star.rendering.XAnimatedSprite createSpriteFromAnimation( XAnimation animation ) - { - CanvasUtils.printLog( "CanvasTest.createSpriteFromAnimation called" ); - - return new CanvasSprite( animation, this, (Graphics2D)dummyFrame.frame.getGraphics() ); - } - - public synchronized XAnimatedSprite createSpriteFromBitmaps( com.sun.star.rendering.XBitmap[] animationBitmaps, - short interpolationMode ) - { - return null; - } - - public synchronized XCustomSprite createCustomSprite( Size2D spriteSize ) - { - CanvasUtils.printLog( "CanvasTest.createCustomSprite called" ); - - return new CanvasCustomSprite( spriteSize, this, (Graphics2D)dummyFrame.frame.getGraphics() ); - } - - public synchronized XSprite createClonedSprite( XSprite original ) - { - return new CanvasClonedSprite( this, original ); - } - - public synchronized void updateScreen() - { - redrawAllLayers(); - } - - //---------------------------------------------------------------------------------- - - // - // XSpriteCanvas helper - // ==================== - // - public synchronized void renderAnimation( CanvasSprite sprite, XAnimation animation, double t ) - { - SpriteRep spriteRep = (SpriteRep)activeSprites.get( sprite ); - if( spriteRep != null ) - { - //Graphics2D graph = getWindowGraphics(); - - // TODO: ensure update of graphics object externally, e.g. when - // VCL moves the toplevel window. - //java.awt.Rectangle bounds = dummyFrame.frame.getBounds(); - //graphics.setGraphics(graph, bounds.width, bounds.height); - - spriteRep.renderAnimation( animation, sprite.getViewState(), t ); - } - else - { - CanvasUtils.printLog( "CanvasTest.renderAnimation sprite not active!" ); - } - } - - public synchronized void showSprite( SpriteBase sprite ) - { - CanvasUtils.printLog( "CanvasTest.showSprite() called" ); - - SpriteRep spriteRep = (SpriteRep)activeSprites.get( sprite ); - if( spriteRep != null ) - { - CanvasUtils.printLog( "CanvasTest.showSprite sprite already active!" ); - } - else - { - spriteRep = sprite.getSpriteRep(); - - // a valid SpriteRep for a given Sprite in the - // activeSprites hash denotes 'sprite active' - activeSprites.put( sprite, spriteRep ); - - // TODO: TEMP! Just for testing! Set empty cursor for presentation -// dummyFrame.frame.setCursor( dummyFrame.frame.getToolkit().createCustomCursor(new java.awt.image.BufferedImage(0,0, -// java.awt.image.BufferedImage.TYPE_INT_RGB), -// new java.awt.Point(0,0), -// "") ); - } - } - - public synchronized void hideSprite( SpriteBase sprite ) - { - CanvasUtils.printLog( "CanvasTest.hideSprite() called" ); - - SpriteRep spriteRep = (SpriteRep)activeSprites.get( sprite ); - if( spriteRep != null ) - { - activeSprites.put( sprite, null ); - redrawAllLayers(); - } - else - { - CanvasUtils.printLog( "CanvasTest.hideSprite sprite not active!" ); - } - } - - private void redrawAllLayers() - { - // fetch the Graphics object to draw into (we're doing double - // buffering here, the content is later shown via - // bufferStrategy.show(). - Graphics2D graph = null; - - try - { - graph = (Graphics2D)bufferStrategy.getDrawGraphics(); - - GraphicsDevice device = graph.getDeviceConfiguration().getDevice(); - CanvasUtils.printLog( "Available vram: " + device.getAvailableAcceleratedMemory() ); - - if( false ) - { - // TEST ONLY { - // repaint background - graph.setComposite( AlphaComposite.getInstance(AlphaComposite.SRC_OVER) ); - graph.drawImage(backgroundBuffer, 0, 0, null); - //backgroundBuffer.flush(); - - // alpha-composite foreground on top of that - graph.setComposite( AlphaComposite.getInstance(AlphaComposite.SRC_OVER, currAlpha) ); - - graph.drawImage(buffer, 0, 0, null); - //buffer.flush(); - - currAlpha += 0.1f; if( currAlpha > 1.0 ) currAlpha = 0.1f; - // TEST ONLY } - } - - if( true ) - { - // repaint background - backBuffer.redraw( graph ); - - // repaint all active sprites - java.util.Set entries = activeSprites.entrySet(); - java.util.Iterator iter = entries.iterator(); - while( iter.hasNext() ) - { - java.util.Map.Entry entry = (java.util.Map.Entry)iter.next(); - if( entry.getValue() != null ) - ((SpriteRep)entry.getValue()).redraw(graph); - } - } - - long currTime = System.currentTimeMillis(); - graph.setComposite( AlphaComposite.getInstance(AlphaComposite.SRC_OVER) ); - graph.setFont( fpsFont ); - graph.setColor( java.awt.Color.black ); - - try - { - String fps = new String( String.valueOf(1000.0/(currTime-lastTime)) ); - graph.drawString( fps.substring(0,5) + " fps", 0, 20); - CanvasUtils.printLog( fps.substring(0,5) + " fps" ); - } - catch( Exception e ) - { - graph.drawString( "0 fps", 0, 20); - } - - lastTime = currTime; - } - finally - { - if( graph != null ) - graph.dispose(); - } - - bufferStrategy.show(); - } - - //---------------------------------------------------------------------------------- - - private static final String s_implName = "XCanvas.java.impl"; - private static final String s_serviceName = "com.sun.star.rendering.Canvas"; - - //---------------------------------------------------------------------------------- - - // - // XServiceInfo impl - // ================= - // - public synchronized String getImplementationName() - { - return s_implName; - } - - public synchronized String [] getSupportedServiceNames() - { - return new String [] { s_serviceName }; - } - - public synchronized boolean supportsService( String serviceName ) - { - return serviceName.equals( s_serviceName ); - } - - public static com.sun.star.lang.XSingleServiceFactory __getServiceFactory( - String implName, - com.sun.star.lang.XMultiServiceFactory multiFactory, - com.sun.star.registry.XRegistryKey regKey ) - { - if (implName.equals( s_implName )) - { - return com.sun.star.comp.loader.FactoryHelper.getServiceFactory( - CanvasTest.class, s_serviceName, multiFactory, regKey ); - } - return null; - } - - public static boolean __writeRegistryServiceInfo( - com.sun.star.registry.XRegistryKey regKey ) - { - return com.sun.star.comp.loader.FactoryHelper.writeRegistryServiceInfo( - s_implName, s_serviceName, regKey ); - } -} diff --git a/canvas/source/java/CanvasUtils.java b/canvas/source/java/CanvasUtils.java deleted file mode 100644 index 8b2245176e03..000000000000 --- a/canvas/source/java/CanvasUtils.java +++ /dev/null @@ -1,627 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -// UNO -import com.sun.star.uno.UnoRuntime; - -// Canvas -import com.sun.star.rendering.*; -import com.sun.star.geometry.*; - -// Java AWT -import java.awt.*; -import java.awt.geom.*; - -public class CanvasUtils -{ - // - // Canvas utilities - // ================ - // - public static java.awt.geom.AffineTransform makeTransform( AffineMatrix2D ooTransform ) - { - return new AffineTransform( ooTransform.m00, - ooTransform.m10, - ooTransform.m01, - ooTransform.m11, - ooTransform.m02, - ooTransform.m12 ); - } - - public static AffineMatrix2D makeAffineMatrix2D( java.awt.geom.AffineTransform transform ) - { - double[] matrix = new double[6]; - transform.getMatrix( matrix ); - - return new AffineMatrix2D( matrix[0], matrix[2], matrix[4], - matrix[1], matrix[3], matrix[5] ); - } - - public static void initGraphics( Graphics2D graphics ) - { - if( graphics != null ) - { - java.awt.RenderingHints hints = new java.awt.RenderingHints(null); - boolean hq = true; - - if( hq ) - { - hints.add( new java.awt.RenderingHints( java.awt.RenderingHints.KEY_FRACTIONALMETRICS, - java.awt.RenderingHints.VALUE_FRACTIONALMETRICS_ON ) ); -// hints.add( new java.awt.RenderingHints( java.awt.RenderingHints.KEY_ALPHA_INTERPOLATION, -// java.awt.RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY) ); - hints.add( new java.awt.RenderingHints( java.awt.RenderingHints.KEY_ALPHA_INTERPOLATION, - java.awt.RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED) ); -// hints.add( new java.awt.RenderingHints( java.awt.RenderingHints.KEY_INTERPOLATION, -// java.awt.RenderingHints.VALUE_INTERPOLATION_BICUBIC) ); - hints.add( new java.awt.RenderingHints( java.awt.RenderingHints.KEY_INTERPOLATION, - java.awt.RenderingHints.VALUE_INTERPOLATION_BILINEAR) ); -// hints.add( new java.awt.RenderingHints( java.awt.RenderingHints.KEY_RENDERING, -// java.awt.RenderingHints.VALUE_RENDER_QUALITY) ); - hints.add( new java.awt.RenderingHints( java.awt.RenderingHints.KEY_RENDERING, - java.awt.RenderingHints.VALUE_RENDER_SPEED) ); -// hints.add( new java.awt.RenderingHints( java.awt.RenderingHints.KEY_STROKE_CONTROL, -// java.awt.RenderingHints.VALUE_STROKE_NORMALIZE) ); - hints.add( new java.awt.RenderingHints( java.awt.RenderingHints.KEY_STROKE_CONTROL, - java.awt.RenderingHints.VALUE_STROKE_DEFAULT) ); - hints.add( new java.awt.RenderingHints( java.awt.RenderingHints.KEY_ANTIALIASING, - java.awt.RenderingHints.VALUE_ANTIALIAS_ON) ); - } - else - { - hints.add( new java.awt.RenderingHints( java.awt.RenderingHints.KEY_ALPHA_INTERPOLATION, - java.awt.RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED) ); - hints.add( new java.awt.RenderingHints( java.awt.RenderingHints.KEY_INTERPOLATION, - java.awt.RenderingHints.VALUE_INTERPOLATION_BILINEAR) ); - hints.add( new java.awt.RenderingHints( java.awt.RenderingHints.KEY_RENDERING, - java.awt.RenderingHints.VALUE_RENDER_SPEED) ); - hints.add( new java.awt.RenderingHints( java.awt.RenderingHints.KEY_STROKE_CONTROL, - java.awt.RenderingHints.VALUE_STROKE_DEFAULT) ); - hints.add( new java.awt.RenderingHints( java.awt.RenderingHints.KEY_ANTIALIASING, - java.awt.RenderingHints.VALUE_ANTIALIAS_OFF) ); - } - - // the least common denominator standard - hints.add( new java.awt.RenderingHints( java.awt.RenderingHints.KEY_FRACTIONALMETRICS, - java.awt.RenderingHints.VALUE_FRACTIONALMETRICS_ON) ); - hints.add( new java.awt.RenderingHints( java.awt.RenderingHints.KEY_TEXT_ANTIALIASING, - java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_ON) ); - - graphics.setRenderingHints( hints ); - } - } - - //---------------------------------------------------------------------------------- - - public static java.awt.geom.GeneralPath makeGenPathFromBezierPoints( RealBezierSegment2D [][] points ) - { - java.awt.geom.GeneralPath path = new java.awt.geom.GeneralPath(); - - // extract every polygon into GeneralPath object - for( int i=0; i<points.length; ++i ) - { - if( points[i].length > 0 ) - path.moveTo((float) points[i][0].Px, (float) points[i][0].Py); - - for( int j=1; j<points[i].length; ++j ) - { - CanvasUtils.printLog( "makeGenPathFromBezierPoints: point added." ); - path.curveTo((float)(points[i][j-1].C1x), (float)(points[i][j-1].C1y), - (float)(points[i][j-1].C2x), (float)(points[i][j-1].C2y), - (float) points[i][j].Px, (float) points[i][j].Py ); - } - - // TODO: closePath? - } - - return path; - } - - public static java.awt.geom.GeneralPath makeGenPathFromBezierPoly( com.sun.star.rendering.XBezierPolyPolygon2D poly ) - { - try - { - com.sun.star.geometry.RealBezierSegment2D [][] points = poly.getBezierSegments(0,-1,0,-1); - - return makeGenPathFromBezierPoints( points ); - } - catch( com.sun.star.lang.IndexOutOfBoundsException e ) - { - } - - return new java.awt.geom.GeneralPath(); - } - - public static java.awt.geom.GeneralPath makeGenPathFromLinePoints( RealPoint2D [][] points ) - { - java.awt.geom.GeneralPath path = new java.awt.geom.GeneralPath(); - - // extract every polygon into GeneralPath object - for( int i=0; i<points.length; ++i ) - { - if( points[i].length > 0 ) - path.moveTo((float) points[i][0].X, (float) points[i][0].Y); - - for( int j=1; j<points[i].length; ++j ) - { - CanvasUtils.printLog( "makeGenPathFromLinePoints: point (" + - points[i][j].X + "," + points[i][j].Y + ") added." ); - path.lineTo((float) points[i][j].X, (float) points[i][j].Y ); - } - - // TODO: closePath? - } - - return path; - } - - public static java.awt.geom.GeneralPath makeGenPathFromLinePoly( com.sun.star.rendering.XLinePolyPolygon2D poly ) - { - try - { - com.sun.star.geometry.RealPoint2D [][] points = poly.getPoints(0,-1,0,-1); - - return makeGenPathFromLinePoints( points ); - } - catch( com.sun.star.lang.IndexOutOfBoundsException e ) - { - } - - return new java.awt.geom.GeneralPath(); - } - - public static java.awt.geom.GeneralPath makeGeneralPath( com.sun.star.rendering.XPolyPolygon2D poly ) - { - if( poly instanceof BezierPolyPolygon ) - { - CanvasUtils.printLog( "makeGeneralPath: bezier impl used." ); - return ((BezierPolyPolygon)poly).getJavaPath(); - } - - if( poly instanceof LinePolyPolygon ) - { - CanvasUtils.printLog( "makeGeneralPath: line impl used." ); - return ((LinePolyPolygon)poly).getJavaPath(); - } - - XBezierPolyPolygon2D bezierPoly = (XBezierPolyPolygon2D) UnoRuntime.queryInterface(XBezierPolyPolygon2D.class, poly); - - if( bezierPoly != null ) - { - // extract polygon data. Prefer bezier interface, because - // that's the more high-level data. - return makeGenPathFromBezierPoly( bezierPoly ); - } - - XLinePolyPolygon2D linePoly = (XLinePolyPolygon2D) UnoRuntime.queryInterface(XLinePolyPolygon2D.class, poly); - - if( linePoly != null ) - { - // extract polygon data. Fallback to line polygon, if no - // curves are available. - return makeGenPathFromLinePoly( linePoly ); - } - - // Only opaque general interface. No chance to get to the - // data. Empty path, then - CanvasUtils.printLog( "makeGeneralPath: Cannot access polygon data, given interface has class" + poly.getClass().getName() ); - return new GeneralPath(); - } - - public static java.awt.image.BufferedImage getBufferedImage( com.sun.star.rendering.XBitmap bitmap ) - { - if( bitmap instanceof CanvasBitmap ) - { - CanvasUtils.printLog( "getBufferedImage: CanvasBitmap impl used." ); - return ((CanvasBitmap)bitmap).getBufferedImage(); - } - - XIntegerBitmap integerBitmap = (XIntegerBitmap) UnoRuntime.queryInterface(XIntegerBitmap.class, bitmap); - - if( integerBitmap != null ) - { - // extract bitmap data. TODO. - return null; - } - - // check other types. TODO. - return null; - } - - public static byte [] int2byte( int [] input ) - { - byte [] output = new byte[4*input.length]; - - int i, j; - for( i=0, j=0; i<input.length; ++i ) - { - output[j] = (byte)(input[i] & 255); - output[j+1] = (byte)((input[i]/256) & 255); - output[j+2] = (byte)((input[i]/256/256) & 255); - output[j+3] = (byte)((input[i]/256/256/256) & 255); - j += 4; - } - - return output; - } - - public static int [] byte2int( byte [] input ) - { - int [] output = new int[(input.length+3)/4]; - - int i, j; - for( i=0,j=0; j<output.length; ++j ) - { - output[j] = input[i] + (input[i+1] + (input[i+2] + input[i+3]*256)*256)*256; - i += 4; - } - - return output; - } - - public static int javaRuleFromCompositeOp( byte compositeOp ) - { - // TODO: Finish mapping of Canvas and Java compositing magics - int rule = java.awt.AlphaComposite.SRC_OVER; - switch( compositeOp ) - { - case com.sun.star.rendering.CompositeOperation.CLEAR: - CanvasUtils.printLog( "javaRuleFromCompositeOp: clear selected" ); - rule = java.awt.AlphaComposite.CLEAR; - break; - - case com.sun.star.rendering.CompositeOperation.SOURCE: - CanvasUtils.printLog( "javaRuleFromCompositeOp: src selected" ); - rule = java.awt.AlphaComposite.SRC; - break; - - case com.sun.star.rendering.CompositeOperation.DESTINATION: - CanvasUtils.printLog( "javaRuleFromCompositeOp: dst selected" ); - rule = java.awt.AlphaComposite.DST; - break; - - case com.sun.star.rendering.CompositeOperation.OVER: - CanvasUtils.printLog( "javaRuleFromCompositeOp: over selected" ); - rule = java.awt.AlphaComposite.SRC_OVER; - break; - - case com.sun.star.rendering.CompositeOperation.UNDER: - CanvasUtils.printLog( "javaRuleFromCompositeOp: under selected" ); - rule = java.awt.AlphaComposite.DST_OVER; - break; - - case com.sun.star.rendering.CompositeOperation.INSIDE: - CanvasUtils.printLog( "javaRuleFromCompositeOp: inside selected" ); - rule = java.awt.AlphaComposite.CLEAR; - break; - - case com.sun.star.rendering.CompositeOperation.INSIDE_REVERSE: - CanvasUtils.printLog( "javaRuleFromCompositeOp: inReverse selected" ); - rule = java.awt.AlphaComposite.CLEAR; - break; - - case com.sun.star.rendering.CompositeOperation.OUTSIDE: - CanvasUtils.printLog( "javaRuleFromCompositeOp: outside selected" ); - rule = java.awt.AlphaComposite.CLEAR; - break; - - case com.sun.star.rendering.CompositeOperation.OUTSIDE_REVERSE: - CanvasUtils.printLog( "javaRuleFromCompositeOp: outReverse selected" ); - rule = java.awt.AlphaComposite.CLEAR; - break; - - case com.sun.star.rendering.CompositeOperation.XOR: - CanvasUtils.printLog( "javaRuleFromCompositeOp: xor selected" ); - rule = java.awt.AlphaComposite.CLEAR; - break; - - case com.sun.star.rendering.CompositeOperation.ADD: - CanvasUtils.printLog( "javaRuleFromCompositeOp: add selected" ); - rule = java.awt.AlphaComposite.CLEAR; - break; - - case com.sun.star.rendering.CompositeOperation.SATURATE: - CanvasUtils.printLog( "javaRuleFromCompositeOp: saturate selected" ); - rule = java.awt.AlphaComposite.CLEAR; - break; - - default: - CanvasUtils.printLog( "javaRuleFromCompositeOp: Unexpected compositing rule" ); - break; - } - - return rule; - } - - public static java.awt.AlphaComposite makeAlphaComposite( byte compositeOp ) - { - return java.awt.AlphaComposite.getInstance( javaRuleFromCompositeOp( compositeOp ) ); - } - - public static java.awt.AlphaComposite makeAlphaCompositeAlpha( byte compositeOp, double alpha ) - { - return java.awt.AlphaComposite.getInstance( javaRuleFromCompositeOp( compositeOp ), (float)alpha ); - } - - // when given to setupGraphicsState, makes that method to also - // setup the Paint with the color specified in the render state. - public static final byte alsoSetupPaint=0; - - // when given to setupGraphicsState, makes that method to _not_ - // setup the Paint with the color specified in the render state. - public static final byte dontSetupPaint=1; - - public static java.awt.geom.AffineTransform ViewConcatRenderTransform( ViewState viewState, - RenderState renderState ) - { - // calculate overall affine transform - AffineTransform transform = makeTransform( viewState.AffineTransform ); - transform.concatenate( makeTransform( renderState.AffineTransform ) ); - - printTransform( transform, "ViewConcatRenderTransform" ); - - return transform; - } - - public static void setupGraphicsState( java.awt.Graphics2D graphics, - ViewState viewState, - RenderState renderState, - byte paintTouchMode ) - { - // calculate overall affine transform - graphics.setTransform( ViewConcatRenderTransform(viewState, renderState ) ); - - // setup overall clip polyPolygon - if( viewState.Clip != null ) - { - Area clipArea = new Area( makeGeneralPath( viewState.Clip ) ); - - if( renderState.Clip != null ) - clipArea.intersect( new Area( makeGeneralPath( renderState.Clip ) ) ); - - graphics.setClip( clipArea ); - } - else if( renderState.Clip != null ) - { - Area clipArea = new Area( makeGeneralPath( renderState.Clip ) ); - graphics.setClip( clipArea ); - } - else - { - // TODO: HACK! Use true visible area here! - graphics.setClip( new java.awt.Rectangle(-1000000,-1000000,2000000,2000000) ); - } - - // setup current output color - // TODO: Complete color handling here - if( paintTouchMode == alsoSetupPaint ) - { - switch( renderState.DeviceColor.length ) - { - case 3: - CanvasUtils.printLog( "setupGraphicsState: Color(" + - renderState.DeviceColor[0] + "," + - renderState.DeviceColor[1] + "," + - renderState.DeviceColor[2] + ") set." ); - graphics.setColor( new Color( (float)renderState.DeviceColor[0], - (float)renderState.DeviceColor[1], - (float)renderState.DeviceColor[2] ) ); - break; - - case 4: - CanvasUtils.printLog( "setupGraphicsState: Color(" + - renderState.DeviceColor[0] + "," + - renderState.DeviceColor[1] + "," + - renderState.DeviceColor[2] + "," + - renderState.DeviceColor[3] + ") set." ); - graphics.setColor( new Color( (float)renderState.DeviceColor[0], - (float)renderState.DeviceColor[1], - (float)renderState.DeviceColor[2], - (float)renderState.DeviceColor[3] ) ); - break; - - default: - CanvasUtils.printLog( "setupGraphicsState: unexpected number of " + - renderState.DeviceColor.length + " color components!" ); - break; - } - } - - // setup current composite mode - graphics.setComposite( makeAlphaComposite( renderState.CompositeOperation ) ); - } - - public static void applyStrokeAttributes( java.awt.Graphics2D graphics, - StrokeAttributes attributes ) - { - int cap = java.awt.BasicStroke.CAP_BUTT; - - if( attributes.StartCapType != attributes.EndCapType ) - CanvasUtils.printLog( "applyStrokeAttributes: different start and end caps are not yet supported!" ); - - if( attributes.LineArray.length != 0 ) - CanvasUtils.printLog( "applyStrokeAttributes: multi-strokes are not yet supported!" ); - - if( attributes.StartCapType == PathCapType.BUTT ) - cap = java.awt.BasicStroke.CAP_BUTT; - else if( attributes.StartCapType == PathCapType.ROUND ) - cap = java.awt.BasicStroke.CAP_ROUND; - else if( attributes.StartCapType == PathCapType.SQUARE ) - cap = java.awt.BasicStroke.CAP_SQUARE; - - int join = java.awt.BasicStroke.JOIN_MITER; - - if( attributes.JoinType == PathJoinType.MITER ) - cap = java.awt.BasicStroke.JOIN_MITER; - else if( attributes.JoinType == PathJoinType.ROUND ) - cap = java.awt.BasicStroke.JOIN_ROUND; - else if( attributes.JoinType == PathJoinType.BEVEL ) - cap = java.awt.BasicStroke.JOIN_BEVEL; - else - CanvasUtils.printLog( "applyStrokeAttributes: current join type not yet supported!" ); - - float [] dashArray = null; - - if( attributes.DashArray.length != 0 ) - { - dashArray = new float [attributes.DashArray.length]; - - for( int i=0; i<attributes.DashArray.length; ++i ) - dashArray[i] = (float)attributes.DashArray[i]; - } - - graphics.setStroke( new java.awt.BasicStroke( (float)attributes.StrokeWidth, - cap, - join, - (float)attributes.MiterLimit, - dashArray, - 0) ); - } - - public static void setupGraphicsFont( java.awt.Graphics2D graphics, - ViewState viewState, - RenderState renderState, - com.sun.star.rendering.XCanvasFont xFont ) - { - if( xFont instanceof CanvasFont ) - { - CanvasUtils.printLog( "setupGraphicsFont: font impl used." ); - graphics.setFont( ((CanvasFont)xFont).getFont() ); - } - else - { - CanvasUtils.printLog( "setupGraphicsFont: creating Java font anew." ); - CanvasFont canvasFont; - canvasFont = new CanvasFont( xFont.getFontRequest(), null ); - graphics.setFont( canvasFont.getFont() ); - } - } - - static java.awt.geom.Rectangle2D.Double calcTransformedRectBounds( java.awt.geom.Rectangle2D.Double aRect, - AffineTransform aTransform ) - { - // transform rect by given transformation - java.awt.geom.Point2D.Double aPointTopLeft = new java.awt.geom.Point2D.Double(aRect.x, aRect.y); - aTransform.transform(aPointTopLeft, aPointTopLeft); - - java.awt.geom.Point2D.Double aPointTopRight = new java.awt.geom.Point2D.Double(aRect.x + aRect.width, - aRect.y); - aTransform.transform(aPointTopRight, aPointTopRight); - - java.awt.geom.Point2D.Double aPointBottomLeft = new java.awt.geom.Point2D.Double(aRect.x, - aRect.y + aRect.height); - aTransform.transform(aPointBottomLeft, aPointBottomLeft); - - java.awt.geom.Point2D.Double aPointBottomRight = new java.awt.geom.Point2D.Double(aRect.x + aRect.width, - aRect.y + aRect.height); - aTransform.transform(aPointBottomRight, aPointBottomRight); - - // calc bounding rect of those four points - java.awt.geom.Point2D.Double aResTopLeft = new java.awt.geom.Point2D.Double( Math.min(aPointTopLeft.x, - Math.min(aPointTopRight.x, - Math.min(aPointBottomLeft.x,aPointBottomRight.x))), - Math.min(aPointTopLeft.y, - Math.min(aPointTopRight.y, - Math.min(aPointBottomLeft.y,aPointBottomRight.y))) ); - - java.awt.geom.Point2D.Double aResBottomRight = new java.awt.geom.Point2D.Double( Math.max(aPointTopLeft.x, - Math.max(aPointTopRight.x, - Math.max(aPointBottomLeft.x,aPointBottomRight.x))), - Math.max(aPointTopLeft.y, - Math.max(aPointTopRight.y, - Math.max(aPointBottomLeft.y,aPointBottomRight.y))) ); - return new java.awt.geom.Rectangle2D.Double( aResTopLeft.x, aResTopLeft.y, - aResBottomRight.x - aResTopLeft.x, - aResBottomRight.y - aResTopLeft.y ); - } - - // Create a corrected view transformation out of the give one, - // which ensures that the rectangle given by (0,0) and - // attributes.untransformedSize is mapped with its left,top corner - // to (0,0) again. This is required to properly render sprite - // animations to buffer bitmaps. - public static ViewState createAnimationViewState( ViewState inputViewState, - AnimationAttributes attributes ) - { - // TODO: Properly respect clip here. Might have to be transformed, too. - - AffineTransform aViewTransform = makeTransform( inputViewState.AffineTransform ); - - // transform Rect(0,0,attributes.untransformedSize) by - // viewTransform - java.awt.geom.Rectangle2D.Double aTransformedRect = - calcTransformedRectBounds( new java.awt.geom.Rectangle2D.Double(0.0, 0.0, - attributes.UntransformedSize.Width, - attributes.UntransformedSize.Height), - aViewTransform ); - - printTransform( aViewTransform, "createAnimationViewState" ); - - CanvasUtils.printLog( "createAnimationViewState: transformed origin is: (" + aTransformedRect.x + ", " + aTransformedRect.y + ")" ); - - // now move resulting left,top point of bounds to (0,0) - AffineTransform animationViewTransform = new AffineTransform(); - animationViewTransform.translate( -aTransformedRect.x, -aTransformedRect.y ); - animationViewTransform.concatenate( aViewTransform ); - - printTransform( animationViewTransform, "createAnimationViewState" ); - - return new ViewState( makeAffineMatrix2D( animationViewTransform ), inputViewState.Clip ); - } - - public static void postRenderImageTreatment( Image buffer ) - { - // TODO: This is specific to Sun's JREs 1.4 and upwards. Make this more portable - buffer.flush(); // as long as we force images to VRAM, - // we need to flush them afterwards, to - // avoid eating up all VRAM. - } - - public static void printTransform( AffineTransform transform, - String stringPrefix ) - { - CanvasUtils.printLog( stringPrefix + ": Transform is" ); - double [] matrix = new double[6]; - transform.getMatrix(matrix); - int i; - for( i=0; i<6; ++i ) - System.err.print( matrix[i] + ", " ); - CanvasUtils.printLog( "" ); - } - - public static void preCondition( boolean bCondition, - String methodName ) - { - if( !bCondition ) - printLog("Precondition violated: " + methodName); - } - - public static void printLog( String s ) - { - System.err.println( s ); - } -} diff --git a/canvas/source/java/JavaCanvas.java b/canvas/source/java/JavaCanvas.java deleted file mode 100644 index fbee763fc272..000000000000 --- a/canvas/source/java/JavaCanvas.java +++ /dev/null @@ -1,675 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -// UNO -import com.sun.star.uno.XComponentContext; -import com.sun.star.uno.AnyConverter; - -// OOo AWT -import com.sun.star.awt.*; - -// Canvas -import com.sun.star.rendering.*; -import com.sun.star.geometry.*; - -// Java AWT -import java.awt.*; - -public class JavaCanvas - extends CanvasBase - implements com.sun.star.awt.XWindow, - com.sun.star.rendering.XSpriteCanvas, - com.sun.star.rendering.XIntegerBitmap, - com.sun.star.lang.XServiceInfo, - com.sun.star.lang.XInitialization -{ - private WindowAdapter dummyFrame; - public BackBuffer backBuffer; - private java.awt.image.BufferStrategy bufferStrategy; - - private java.awt.Font fpsFont; - private long lastTime; - private com.sun.star.awt.Rectangle boundRect; - - public Graphics2D getGraphics() - { - return backBuffer.getGraphics(); - } - - //---------------------------------------------------------------------------------- - - // - // XInitialization - // =============== - // - public void initialize( java.lang.Object[] arguments ) - { - CanvasUtils.printLog( "JavaCanvas.initialize called!" ); - - // Do that as the very first thing. The Java2D internal - // classes choose their render path at initialization time, - // thus this must happen before doing _any_ GUI. - - // TODO: Put those flags into javarc/java.ini, we're maybe - // coming late into a running JVM! - - // now, we're getting slightly system dependent here. - String os = (String) System.getProperty("os.name"); - - CanvasUtils.printLog( "System detected: " + os ); - - // tweak some speed knobs... -// if( os.startsWith("Windows") ) -// { -// System.setProperty("sun.java2d.translaccel", "true"); -// System.setProperty("sun.java2d.ddforcevram", "true"); -// //System.setProperty("sun.java2d.accthreshold", "0"); - -// CanvasUtils.printLog( "Optimizing for Windows" ); -// } -// else -// { -// System.setProperty("sun.java2d.opengl", "true"); - -// CanvasUtils.printLog( "Optimizing for Unix" ); -// } - - /* we're initialized with the following array of anys: - - arguments[0] = pointer to VCL window - arguments[1] = Integer (operating system window handle) - arguments[2] = com.sun.star.awt.Rectangle (position and size within that OS window) - arguments[3] = boolean (fullsize window or not) - - We then generate a dummy Java frame with that window as the - parent, to fake a root window for the Java implementation. - */ - try - { - boundRect = (com.sun.star.awt.Rectangle) arguments[2]; - - //boolean isFullScreen = arguments[1]; - boolean isFullScreen = true; - //AnyConverter.toBoolean( arguments[3] ) ); - - // fake a root for Java in VCL window. Pass the flag - // whether we shall run fullscreen, too. - dummyFrame = new WindowAdapter( AnyConverter.toInt( arguments[1] ), isFullScreen ); - - if( isFullScreen ) - { - // blow window up to fullscreen. Otherwise, we cannot clear the whole screen, - // which results in ugly flickering - Dimension screenSize = dummyFrame.frame.getToolkit().getScreenSize(); - boundRect.X = 0; - boundRect.Y = 0; - boundRect.Width = screenSize.width-1; - boundRect.Height = screenSize.height-1; - } - - dummyFrame.setPosSize( boundRect.X, boundRect.Y, boundRect.Width, boundRect.Height, (short)0 ); - CanvasUtils.printLog( "Window size: " + boundRect.Width + ", " + boundRect.Height ); - - backBuffer = new BackBuffer( (Graphics2D) dummyFrame.frame.getGraphics(), - Math.max(1,boundRect.Width), - Math.max(1,boundRect.Height) ); - - // TODO: Maybe delay double buffer init until first sprite creation - dummyFrame.frame.createBufferStrategy(2); - bufferStrategy = dummyFrame.frame.getBufferStrategy(); - - if( bufferStrategy.getCapabilities().isPageFlipping() ) - CanvasUtils.printLog( "JavaCanvas.initialize double buffering is using page flipping!" ); - else - CanvasUtils.printLog( "JavaCanvas.initialize double buffering is using blitting!" ); - - lastTime = System.currentTimeMillis(); - fpsFont = new java.awt.Font( "Times", Font.PLAIN, 20 ); - - CanvasUtils.printLog( "JavaCanvas.initialize finished!" ); - } - catch( com.sun.star.lang.IllegalArgumentException e ) - { - CanvasUtils.printLog( "Cannot create EmbeddedFrame within VCL window hierarchy!" ); - } - } - - //---------------------------------------------------------------------------------- - - // - // XComponent - // ========== - // - public void dispose() - { - CanvasUtils.printLog( "JavaCanvas: disposed!" ); - - // destroy all active sprites - java.util.Set entries = activeSprites.entrySet(); - java.util.Iterator iter = entries.iterator(); - - while( iter.hasNext() ) - { - java.util.Map.Entry entry = (java.util.Map.Entry)iter.next(); - if( entry.getValue() != null ) - ((SpriteRep)entry.getValue()).dispose(); - } - - if( bufferStrategy != null ) - bufferStrategy.getDrawGraphics().dispose(); // really necessary? - - if( dummyFrame != null ) - dummyFrame.dispose(); - - if( backBuffer != null) - backBuffer.dispose(); - - bufferStrategy = null; - dummyFrame = null; - backBuffer = null; - - super.dispose(); - } - - //---------------------------------------------------------------------------------- - - public JavaCanvas( XComponentContext xContext ) - { - CanvasUtils.printLog( "JavaCanvas constructor called!" ); - activeSprites = new java.util.HashMap( 33 ); - } - - //---------------------------------------------------------------------------------- - - // - // XWindow interface - // ================= - // - // This is delegated to WindowAdapter! - // - public synchronized void setPosSize( int X, int Y, int Width, int Height, short Flags ) - { - if( dummyFrame != null ) - { - dummyFrame.setPosSize( X, Y, Width, Height, Flags ); - - Width = Math.max(1,Width); - Height= Math.max(1,Height); - - CanvasUtils.printLog( "JavaCanvas graphics set to " + Width + "," + Height ); - backBuffer.setSize(Width,Height); - } - } - - public synchronized com.sun.star.awt.Rectangle getPosSize( ) - { - if( dummyFrame != null ) - return dummyFrame.getPosSize(); - - return new com.sun.star.awt.Rectangle(); - } - - public synchronized void setVisible( boolean visible ) - { - if( dummyFrame != null ) - dummyFrame.setVisible( visible ); - } - - public synchronized void setEnable( boolean enable ) - { - if( dummyFrame != null ) - dummyFrame.setEnable( enable ); - } - - public synchronized void setFocus() - { - if( dummyFrame != null ) - dummyFrame.setFocus(); - } - - public synchronized void addWindowListener( XWindowListener xListener ) - { - if( dummyFrame != null ) - dummyFrame.addWindowListener( xListener ); - } - - public synchronized void removeWindowListener( XWindowListener xListener ) - { - if( dummyFrame != null ) - dummyFrame.removeWindowListener( xListener ); - } - - public synchronized void addFocusListener( XFocusListener xListener ) - { - if( dummyFrame != null ) - dummyFrame.addFocusListener( xListener ); - } - - public synchronized void removeFocusListener( XFocusListener xListener ) - { - if( dummyFrame != null ) - dummyFrame.removeFocusListener( xListener ); - } - - public synchronized void addKeyListener( XKeyListener xListener ) - { - if( dummyFrame != null ) - dummyFrame.addKeyListener( xListener ); - } - - public synchronized void removeKeyListener( XKeyListener xListener ) - { - if( dummyFrame != null ) - dummyFrame.removeKeyListener( xListener ); - } - - public synchronized void addMouseListener( XMouseListener xListener ) - { - if( dummyFrame != null ) - dummyFrame.addMouseListener( xListener ); - } - - public synchronized void removeMouseListener( XMouseListener xListener ) - { - if( dummyFrame != null ) - dummyFrame.removeMouseListener( xListener ); - } - - public synchronized void addMouseMotionListener( XMouseMotionListener xListener ) - { - if( dummyFrame != null ) - dummyFrame.addMouseMotionListener( xListener ); - } - - public synchronized void removeMouseMotionListener( XMouseMotionListener xListener ) - { - if( dummyFrame != null ) - dummyFrame.removeMouseMotionListener( xListener ); - } - - public synchronized void addPaintListener( XPaintListener xListener ) - { - if( dummyFrame != null ) - dummyFrame.addPaintListener( xListener ); - } - - public synchronized void removePaintListener( XPaintListener xListener ) - { - if( dummyFrame != null ) - dummyFrame.removePaintListener( xListener ); - } - - //---------------------------------------------------------------------------------- - - // - // XBitmapCanvas impl - // ================== - // - - public synchronized void copyRect( com.sun.star.rendering.XBitmapCanvas sourceCanvas, - com.sun.star.geometry.RealRectangle2D sourceRect, - com.sun.star.rendering.ViewState sourceViewState, - com.sun.star.rendering.RenderState sourceRenderState, - com.sun.star.geometry.RealRectangle2D destRect, - com.sun.star.rendering.ViewState destViewState, - com.sun.star.rendering.RenderState destRenderState ) - { - CanvasUtils.printLog( "JavaCanvas.copyRect() called" ); - - // TODO: create temp image when transform is non-trivial - - if( sourceCanvas == this ) - { - // copy rectangle within the canvas - getGraphics().copyArea((int)sourceRect.X1, - (int)sourceRect.Y1, - (int)(sourceRect.X2 - sourceRect.X1), - (int)(sourceRect.Y2 - sourceRect.Y1), - (int)(destRect.X1 - sourceRect.X1), - (int)(destRect.Y1 - sourceRect.Y1) ); - } - else - { - if( sourceCanvas instanceof JavaCanvas ) - { - // cache - CanvasUtils.setupGraphicsState( getGraphics(), destViewState, destRenderState, CanvasUtils.alsoSetupPaint ); - - java.awt.Image backBuffer = ((JavaCanvas)sourceCanvas).backBuffer.getBackBuffer(); - - // TODO: really extract correct source rect here - getGraphics().drawImage( backBuffer, 0, 0, null); - CanvasUtils.postRenderImageTreatment( backBuffer ); - } - // TODO: foreign canvas - } - } - - //---------------------------------------------------------------------------------- - - // a map of SpriteReps, with Sprite object as keys. Contains all - // active (i.e. visible) sprites, the SpriteReps are used to - // repaint the sprite content at any time. - private java.util.HashMap activeSprites; - - // - // XSpriteCanvas impl - // ================== - // - - public synchronized com.sun.star.rendering.XAnimatedSprite createSpriteFromAnimation( XAnimation animation ) - { - CanvasUtils.printLog( "JavaCanvas.createSpriteFromAnimation called" ); - - return new CanvasSprite( animation, this, (Graphics2D)dummyFrame.frame.getGraphics() ); - } - - public synchronized XAnimatedSprite createSpriteFromBitmaps( com.sun.star.rendering.XBitmap[] animationBitmaps, - byte interpolationMode ) - { - return null; - } - - public synchronized XCustomSprite createCustomSprite( RealSize2D spriteSize ) - { - CanvasUtils.printLog( "JavaCanvas.createCustomSprite called" ); - - return new CanvasCustomSprite( spriteSize, this, (Graphics2D)dummyFrame.frame.getGraphics() ); - } - - public synchronized XSprite createClonedSprite( XSprite original ) - { - return new CanvasClonedSprite( this, original ); - } - - public synchronized boolean updateScreen( boolean bUpdateAll ) - { - redrawAllLayers(); - - return true; - } - - // - // XBitmap implementation - // ====================== - // - - public synchronized IntegerSize2D getSize() - { - return new IntegerSize2D( boundRect.Width, - boundRect.Height ); - } - - //---------------------------------------------------------------------------------- - - public synchronized XBitmapCanvas queryBitmapCanvas() - { - return this; - } - - //---------------------------------------------------------------------------------- - - public synchronized com.sun.star.rendering.XBitmap getScaledBitmap( RealSize2D newSize, boolean beFast ) throws com.sun.star.lang.IllegalArgumentException, VolatileContentDestroyedException - { - // TODO - return null; - } - - //---------------------------------------------------------------------------------- - - public synchronized boolean hasAlpha() - { - // TODO - return false; - } - - //---------------------------------------------------------------------------------- - - // - // XIntegerBitmap implementation - // ============================= - // - - public synchronized byte[] getData( IntegerBitmapLayout[] bitmapLayout, - IntegerRectangle2D rect ) - { - // TODO - return null; - } - - //---------------------------------------------------------------------------------- - - public synchronized void setData( byte[] data, IntegerBitmapLayout bitmapLayout, com.sun.star.geometry.IntegerRectangle2D rect ) - { - // TODO - } - - //---------------------------------------------------------------------------------- - - public synchronized void setPixel( byte[] color, IntegerBitmapLayout bitmapLayout, com.sun.star.geometry.IntegerPoint2D pos ) - { - // TODO - } - - //---------------------------------------------------------------------------------- - - public synchronized byte[] getPixel( IntegerBitmapLayout[] bitmapLayout, - IntegerPoint2D pos ) - { - // TODO - return null; - } - - //---------------------------------------------------------------------------------- - - public synchronized XBitmapPalette getPalette() - { - // TODO - return null; - } - - //---------------------------------------------------------------------------------- - - public synchronized IntegerBitmapLayout getMemoryLayout() - { - // TODO: finish that one - IntegerBitmapLayout layout = new IntegerBitmapLayout(); - - return layout; - } - - //---------------------------------------------------------------------------------- - - // - // XSpriteCanvas helper - // ==================== - // - public synchronized void renderAnimation( CanvasSprite sprite, XAnimation animation, double t ) - { - SpriteRep spriteRep = (SpriteRep)activeSprites.get( sprite ); - if( spriteRep != null ) - { - //Graphics2D graph = getWindowGraphics(); - - // TODO: ensure update of graphics object externally, e.g. when - // VCL moves the toplevel window. - //java.awt.Rectangle bounds = dummyFrame.frame.getBounds(); - //graphics.setGraphics(graph, bounds.width, bounds.height); - - spriteRep.renderAnimation( animation, sprite.getViewState(), t ); - } - else - { - CanvasUtils.printLog( "JavaCanvas.renderAnimation sprite not active!" ); - } - } - - public synchronized void showSprite( SpriteBase sprite ) - { - CanvasUtils.printLog( "JavaCanvas.showSprite() called" ); - - SpriteRep spriteRep = (SpriteRep)activeSprites.get( sprite ); - if( spriteRep != null ) - { - CanvasUtils.printLog( "JavaCanvas.showSprite sprite already active!" ); - } - else - { - spriteRep = sprite.getSpriteRep(); - - // a valid SpriteRep for a given Sprite in the - // activeSprites hash denotes 'sprite active' - activeSprites.put( sprite, spriteRep ); - - // TODO: TEMP! Just for testing! Set empty cursor for presentation -// dummyFrame.frame.setCursor( dummyFrame.frame.getToolkit().createCustomCursor(new java.awt.image.BufferedImage(0,0, -// java.awt.image.BufferedImage.TYPE_INT_RGB), -// new java.awt.Point(0,0), -// "") ); - } - } - - public synchronized void hideSprite( SpriteBase sprite ) - { - CanvasUtils.printLog( "JavaCanvas.hideSprite() called" ); - - SpriteRep spriteRep = (SpriteRep)activeSprites.get( sprite ); - if( spriteRep != null ) - { - activeSprites.put( sprite, null ); - redrawAllLayers(); - } - else - { - CanvasUtils.printLog( "JavaCanvas.hideSprite sprite not active!" ); - } - } - - private void redrawAllLayers() - { - // fetch the Graphics object to draw into (we're doing double - // buffering here, the content is later shown via - // bufferStrategy.show(). - Graphics2D graph = null; - - try - { - graph = (Graphics2D)bufferStrategy.getDrawGraphics(); - - GraphicsDevice device = graph.getDeviceConfiguration().getDevice(); - CanvasUtils.printLog( "Available vram: " + device.getAvailableAcceleratedMemory() ); - - // repaint background - backBuffer.redraw( graph ); - - // repaint all active sprites - java.util.Set entries = activeSprites.entrySet(); - java.util.Iterator iter = entries.iterator(); - while( iter.hasNext() ) - { - java.util.Map.Entry entry = (java.util.Map.Entry)iter.next(); - if( entry.getValue() != null ) - ((SpriteRep)entry.getValue()).redraw(graph); - } - - long currTime = System.currentTimeMillis(); - graph.setComposite( AlphaComposite.getInstance(AlphaComposite.SRC_OVER) ); - graph.setFont( fpsFont ); - graph.setColor( java.awt.Color.black ); - - try - { - String fps = new String( String.valueOf(1000.0/(currTime-lastTime)) ); - graph.drawString( fps.substring(0,5) + " fps", 0, 20); - CanvasUtils.printLog( fps.substring(0,5) + " fps" ); - } - catch( Exception e ) - { - graph.drawString( "0 fps", 0, 20); - } - - lastTime = currTime; - } - catch( Exception e ) - { - CanvasUtils.printLog( "Exception thrown in redrawAllLayers" ); - } - finally - { - if( graph != null ) - graph.dispose(); - } - - bufferStrategy.show(); - } - - //---------------------------------------------------------------------------------- - - private static final String s_implName = "XCanvas.java.impl"; - private static final String s_serviceName = "com.sun.star.rendering.JavaCanvas"; - - //---------------------------------------------------------------------------------- - - // - // XServiceInfo impl - // ================= - // - public synchronized String getImplementationName() - { - return s_implName; - } - - public synchronized String [] getSupportedServiceNames() - { - return new String [] { s_serviceName }; - } - - public synchronized boolean supportsService( String serviceName ) - { - return serviceName.equals( s_serviceName ); - } - - public static com.sun.star.lang.XSingleServiceFactory __getServiceFactory( - String implName, - com.sun.star.lang.XMultiServiceFactory multiFactory, - com.sun.star.registry.XRegistryKey regKey ) - { - if (implName.equals( s_implName )) - { - return com.sun.star.comp.loader.FactoryHelper.getServiceFactory( - JavaCanvas.class, s_serviceName, multiFactory, regKey ); - } - return null; - } - - public static boolean __writeRegistryServiceInfo( - com.sun.star.registry.XRegistryKey regKey ) - { - return com.sun.star.comp.loader.FactoryHelper.writeRegistryServiceInfo( - s_implName, s_serviceName, regKey ); - } -} diff --git a/canvas/source/java/LinePolyPolygon.java b/canvas/source/java/LinePolyPolygon.java deleted file mode 100644 index 3ab19d97ba19..000000000000 --- a/canvas/source/java/LinePolyPolygon.java +++ /dev/null @@ -1,192 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -// Canvas -import com.sun.star.rendering.*; -import com.sun.star.geometry.*; - -public class LinePolyPolygon - extends com.sun.star.lib.uno.helper.ComponentBase - implements com.sun.star.lang.XServiceInfo, - com.sun.star.rendering.XLinePolyPolygon2D -{ - private java.awt.geom.GeneralPath path; - - //---------------------------------------------------------------------------------- - - public LinePolyPolygon( RealPoint2D[][] points ) - { - setPoints( points, 0 ); - } - - public java.awt.geom.GeneralPath getJavaPath() - { - return path; - } - - //---------------------------------------------------------------------------------- - - // - // XPolyPolygon implementation - // =========================== - // - public synchronized void addPolyPolygon( RealPoint2D position, XPolyPolygon2D polyPolygon ) - { - } - - public synchronized int getNumberOfPolygons( ) - { - return 0; - } - - public synchronized int getNumberOfPolygonPoints( int polygon ) - { - return 0; - } - - public synchronized FillRule getFillRule( ) - { - if( path.getWindingRule() == java.awt.geom.GeneralPath.WIND_EVEN_ODD ) - return FillRule.EVEN_ODD; - else - return FillRule.NON_ZERO; - } - - public synchronized void setFillRule( FillRule fillRule ) - { - if( fillRule == FillRule.EVEN_ODD ) - path.setWindingRule( java.awt.geom.GeneralPath.WIND_EVEN_ODD ); - else - path.setWindingRule( java.awt.geom.GeneralPath.WIND_NON_ZERO ); - } - - public synchronized boolean isClosed( int index ) - { - // TODO - return false; - } - - public synchronized void setClosed( int index, boolean closedState ) - { - // TODO - } - - //---------------------------------------------------------------------------------- - - // - // XLinePolyPolygon implementation - // =============================== - // - public synchronized RealPoint2D[][] getPoints( int nPolygonIndex, int nNumberOfPolygons, int nPointIndex, int nNumberOfPoints ) - { - // TODO: Implement subsetting - -// double [] points = new double[6]; - -// // BAH! Use util.Vector here! - -// // find number of subpaths -// PathIterator aIter = path.getPathIterator( new AffineTransform() ); -// int nNumSubPaths = 0; -// while( !aIter.isDone() ) -// { -// if( aIter.currentSegment(points) == SEG_MOVETO ) -// ++nNumSubPaths; - -// aIter.next(); -// } - -// Point2D [][] aRes = new Point2D[nNumSubPaths][]; -// aIter = path.getPathIterator( new AffineTransform() ); -// while( !aIter.isDone() ) -// { -// switch( aIter.currentSegment(points) ) -// { -// case SEG_MOVETO: -// break; - -// case SEG_LINETO: -// break; - -// case SEG_CLOSE: -// break; - -// default: -// CanvasUtils.printLog( "LinePolyPolygon.getPoints(): unexpected path type" ); -// break; -// } - -// aIter.next(); -// } -// double [] points = new double[6]; - - return null; - } - - public synchronized void setPoints( RealPoint2D[][] points, int nPolygonIndex ) - { - if( nPolygonIndex != 0 ) - CanvasUtils.printLog( "LinePolyPolygon.setPoints: subset not yet implemented!" ); - - path = CanvasUtils.makeGenPathFromLinePoints( points ); - } - - public synchronized RealPoint2D getPoint( int nPolygonIndex, int nPointIndex ) - { - return null; - } - - public synchronized void setPoint( RealPoint2D point, int nPolygonIndex, int nPointIndex ) - { - CanvasUtils.printLog( "LinePolyPolygon.setPoint: not yet implemented!" ); - } - - //---------------------------------------------------------------------------------- - - // - // XServiceInfo impl - // ================= - // - - private static final String s_implName = "XLinePolyPolygon2D.java.impl"; - private static final String s_serviceName = "com.sun.star.rendering.LinePolyPolygon2D"; - - public String getImplementationName() - { - return s_implName; - } - - public String [] getSupportedServiceNames() - { - return new String [] { s_serviceName }; - } - - public boolean supportsService( String serviceName ) - { - return serviceName.equals( s_serviceName ); - } -} diff --git a/canvas/source/java/SpriteRep.java b/canvas/source/java/SpriteRep.java deleted file mode 100644 index 046a45f2d9bb..000000000000 --- a/canvas/source/java/SpriteRep.java +++ /dev/null @@ -1,175 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -// Canvas -import com.sun.star.rendering.*; - -// Java AWT -import java.awt.*; -import java.awt.geom.*; - -public class SpriteRep -{ - private java.awt.image.BufferedImage buffer; - private CanvasBitmap canvasBitmap; - private double alpha; - private java.awt.geom.Point2D.Double outputPosition; - private boolean bufferOwned; - - //---------------------------------------------------------------------------------- - - // TODO: Everything in this class - // TODO: Implement lifetime control for buffer object, which is shared between SpriteReps - public SpriteRep() - { - CanvasUtils.printLog( "SpriteRep constructor called!" ); - - alpha = 0.0; - outputPosition = new java.awt.geom.Point2D.Double(0.0,0.0); - bufferOwned = true; // the buffer member is our own, and has to be disposed - } - - public SpriteRep( SpriteRep original ) - { - CanvasUtils.printLog( "SpriteRep clone constructor called!" ); - - alpha = 0.0; - outputPosition = new java.awt.geom.Point2D.Double(0.0,0.0); - cloneBuffer( original ); - bufferOwned = false; // the buffer member is not our own, and must not be disposed - } - - //---------------------------------------------------------------------------------- - - public synchronized void renderAnimation( XAnimation animation, ViewState viewState, double t ) - { - if( canvasBitmap != null ) - { - // clear buffer with all transparent - Graphics2D bitmapGraphics = canvasBitmap.getGraphics(); - - // before that, setup _everything_ we might have changed in CanvasUtils.setupGraphicsState - bitmapGraphics.setColor( new Color( 0.0f, 0.0f, 0.0f, 1.0f ) ); - bitmapGraphics.setComposite( - java.awt.AlphaComposite.getInstance(java.awt.AlphaComposite.CLEAR)); - bitmapGraphics.setTransform( new AffineTransform() ); - bitmapGraphics.setClip( new java.awt.Rectangle(0,0,buffer.getWidth(),buffer.getHeight()) ); - bitmapGraphics.fillRect(0,0,buffer.getWidth(),buffer.getHeight()); - - try - { - // now push the animation at time instance t into the - // virginal graphics - animation.render(canvasBitmap, viewState, t); - } - catch( com.sun.star.lang.IllegalArgumentException e ) - { - CanvasUtils.printLog( "Cannot create EmbeddedFrame within VCL window hierarchy!" ); - } - } - } - - public synchronized void setSpriteAlpha( double _alpha ) - { - CanvasUtils.printLog("SpriteRep.setSpriteAlpha called with alpha=" + alpha); - alpha = _alpha; - } - - public synchronized void moveSprite( java.awt.geom.Point2D.Double aNewPos ) - { - outputPosition = aNewPos; - CanvasUtils.printLog( "SpriteRep.moveSprite: moving to (" + outputPosition.x + ", " + outputPosition.y + ")" ); - } - - public synchronized void redraw( Graphics2D output ) - { - if( buffer != null ) - { - CanvasUtils.printLog( "SpriteRep.redraw: compositing with alpha=" + alpha ); - output.setComposite( java.awt.AlphaComposite.getInstance(java.awt.AlphaComposite.SRC_OVER, (float)alpha) ); - - output.drawImage( buffer, - (int)(outputPosition.getX() + .5), - (int)(outputPosition.getY() + .5), - null ); - - //CanvasUtils.postRenderImageTreatment( buffer ); - - CanvasUtils.printLog( "SpriteRep.redraw called, output rect is (" + - outputPosition.getX() + ", " + - outputPosition.getY() + ", " + - buffer.getWidth() + ", " + - buffer.getHeight() + ")" ); - } - } - - public synchronized void setupBuffer( java.awt.Graphics2D graphics, int width, int height ) - { - if( canvasBitmap != null ) - canvasBitmap.dispose(); - - if( buffer != null ) - buffer.flush(); - - buffer = graphics.getDeviceConfiguration().createCompatibleImage(Math.max(1,width), - Math.max(1,height), - Transparency.TRANSLUCENT); - canvasBitmap = new CanvasBitmap( buffer ); - CanvasUtils.initGraphics( canvasBitmap.getGraphics() ); - - CanvasUtils.printLog( "SpriteRep.setupBuffer called, with dimensions (" + width + ", " + height + ")" ); - } - - public synchronized void cloneBuffer( SpriteRep original ) - { - buffer = original.buffer; - } - - public synchronized com.sun.star.rendering.XCanvas getContentCanvas() - { - CanvasUtils.printLog( "SpriteRep.getContentCanvas() called" ); - - Graphics2D graphics = canvasBitmap.getGraphics(); - graphics.setTransform( new AffineTransform() ); - graphics.setComposite( AlphaComposite.getInstance(AlphaComposite.CLEAR)); - graphics.fillRect( 0,0,buffer.getWidth(),buffer.getHeight() ); - - return canvasBitmap; - } - - public void dispose() - { - if( canvasBitmap != null ) - canvasBitmap.dispose(); - - if( buffer != null && bufferOwned ) - buffer.flush(); - - canvasBitmap = null; - buffer = null; - } -} diff --git a/canvas/source/java/SpriteRunner.java b/canvas/source/java/SpriteRunner.java deleted file mode 100644 index 17e472e7e5c7..000000000000 --- a/canvas/source/java/SpriteRunner.java +++ /dev/null @@ -1,200 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -// Canvas -import com.sun.star.rendering.*; - -// -// HOWTO get a Graphics2D from a window -// - -// import javax.swing.*; -// import java.awt.*; -// import java.awt.geom.*; - -// public class Stroke1 extends JFrame { -// Stroke drawingStroke = new BasicStroke(5); -// Rectangle2D rect = -// new Rectangle2D.Double(20, 40, 100, 40); - -// public void paint(Graphics g) { -// Graphics2D g2d = (Graphics2D)g; -// g2d.setStroke(drawingStroke); -// g2d.draw(rect); -// } - -// public static void main(String args[]) { -// JFrame frame = new Stroke1(); -// frame.setDefaultCloseOperation(EXIT_ON_CLOSE); -// frame.setSize(200, 100); -// frame.show(); -// } -// } - - -public class SpriteRunner - extends Thread -{ - private CanvasSprite sprite; - private XAnimation spriteAnimation; - private JavaCanvas canvas; - private double startTime; - private double currentSpeed; - private double currentT; - private boolean animationActive; - private boolean stayAlive; - - //---------------------------------------------------------------------------------- - - public SpriteRunner( CanvasSprite _sprite, XAnimation _animation, JavaCanvas _canvas ) - { - CanvasUtils.printLog( "SpriteRunner constructor called!" ); - - sprite = _sprite; - spriteAnimation = _animation; - canvas = _canvas; - startTime = 0.0; - currentSpeed = 0.0; - currentT = 0.0; - animationActive = false; - stayAlive = true; - - // Set priority to lower-than-normal, as this thread runs the - // animation in a busy loop. - setPriority( MIN_PRIORITY ); - } - - //---------------------------------------------------------------------------------- - - // - // Thread - // ====== - // - // Overriding - // - public void run() - { - // perform the animation rendering (as fast as possible, for now) - - while( stayAlive ) - { - while( animationActive ) - { - // to determine the current animation step to render, calc the - // elapsed time since this animation was started - double elapsedTime = getCurrentTime() - startTime; - - // the frame to render is determined by mapping the cycle - // duration (currentSpeed) to the [0,1] range of the animation. - currentT = (elapsedTime % currentSpeed) / currentSpeed; - - // delegate animation rendering to SpriteCanvas, as - // only this instance can enforce consistency (on-time - // saving of background etc.) - canvas.renderAnimation( sprite, spriteAnimation, currentT ); - - // TODO: Consolidate _all_ sprites per canvas into one - // thread, call updateScreen() only after all sprites - // have been processed. - - //Make changes visible - canvas.updateScreen( false ); - - // TODO: Evaluate vs. setPriority and other means -// try -// { -// // give other tasks some time to breathe (10ms - this is only meant symbolically) -// sleep(10); -// } catch( InterruptedException e ) { } - } - - // wait until animation is activated again - try - { - wait(); - } - catch( InterruptedException e ) { } - catch( IllegalMonitorStateException e ) { } - } - } - - public synchronized void startAnimation( double speed ) - { - resetAnimation(); - currentSpeed = speed; - - // start us, if not done already - if( !isAlive() ) - start(); - - // enable animation thread - animationActive = true; - - try - { - notify(); - } catch( IllegalMonitorStateException e ) { } - } - - public synchronized void stopAnimation() - { - // stop animation after the current frame has been completely - // rendered - animationActive = false; - } - - public synchronized void resetAnimation() - { - startTime = getCurrentTime(); - } - - public synchronized boolean isAnimationActive() - { - return animationActive; - } - - public synchronized void quit() - { - stayAlive = false; - stopAnimation(); - } - - public synchronized double getCurrentT() - { - return currentT; - } - - //---------------------------------------------------------------------------------- - - // helper - static double getCurrentTime() - { - // determine current time in seconds - java.util.Calendar cal = new java.util.GregorianCalendar(); - return cal.getTimeInMillis() / 1000.0; - } -} diff --git a/canvas/source/java/TextLayout.java b/canvas/source/java/TextLayout.java deleted file mode 100644 index 1a443fcbeeac..000000000000 --- a/canvas/source/java/TextLayout.java +++ /dev/null @@ -1,205 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -// Canvas -import com.sun.star.rendering.*; - -public class TextLayout - extends com.sun.star.lib.uno.helper.ComponentBase - implements com.sun.star.lang.XServiceInfo, - com.sun.star.rendering.XTextLayout -{ - private double[] advancements; - private StringContext text; - private byte direction; - private CanvasBase associatedCanvas; - private CanvasFont font; - - //---------------------------------------------------------------------------------- - - public TextLayout( StringContext aText, - byte nDirection, - long nRandomSeed, - CanvasFont _font, - CanvasBase _canvas ) - { - text = aText; - direction = nDirection; - associatedCanvas = _canvas; - font = _font; - } - - // - // XTextLayout implementation - // ========================== - // - - public XPolyPolygon2D[] queryTextShapes( ) - { - // TODO - return null; - } - - public com.sun.star.geometry.RealRectangle2D[] queryInkMeasures( ) - { - // TODO - return null; - } - - public com.sun.star.geometry.RealRectangle2D[] queryMeasures( ) - { - // TODO - return null; - } - - public double[] queryLogicalAdvancements( ) - { - // TODO - return null; - } - - public void applyLogicalAdvancements( double[] aAdvancements ) throws com.sun.star.lang.IllegalArgumentException - { - if( aAdvancements.length != text.Length ) - throw new com.sun.star.lang.IllegalArgumentException(); - - advancements = aAdvancements; - } - - public com.sun.star.geometry.RealRectangle2D queryTextBounds( ) - { - // TODO - return null; - } - - public double justify( double nSize ) throws com.sun.star.lang.IllegalArgumentException - { - // TODO - return 0; - } - - public double combinedJustify( XTextLayout[] aNextLayouts, double nSize ) throws com.sun.star.lang.IllegalArgumentException - { - // TODO - return 0; - } - - public TextHit getTextHit( /*IN*/com.sun.star.geometry.RealPoint2D aHitPoint ) - { - // TODO - return null; - } - - public Caret getCaret( int nInsertionIndex, boolean bExcludeLigatures ) throws com.sun.star.lang.IndexOutOfBoundsException - { - // TODO - return null; - } - - public int getNextInsertionIndex( int nStartIndex, int nCaretAdvancement, boolean bExcludeLigatures ) throws com.sun.star.lang.IndexOutOfBoundsException - { - // TODO - return 0; - } - - public XPolyPolygon2D queryVisualHighlighting( int nStartIndex, int nEndIndex ) throws com.sun.star.lang.IndexOutOfBoundsException - { - // TODO - return null; - } - - public XPolyPolygon2D queryLogicalHighlighting( int nStartIndex, int nEndIndex ) throws com.sun.star.lang.IndexOutOfBoundsException - { - // TODO - return null; - } - - public double getBaselineOffset( ) - { - // TODO - return 0.0; - } - - public byte getMainTextDirection( ) - { - return direction; - } - - public XCanvasFont getFont( ) - { - return font; - } - - public StringContext getText( ) - { - return text; - } - - public boolean draw( java.awt.Graphics2D graphics ) - { - // TODO: use proper advancement. Text direction need not be horizontal! - // TODO: given text string need not have a one-to-one relationship between code point and glyph (offset)! - graphics.drawString( text.Text.substring(text.StartPosition, text.StartPosition + 1), (float)0.0, (float)0.0 ); - for( int i=1; i<advancements.length && i<text.Length; ++i ) - { - CanvasUtils.printLog( "XCanvas: drawOffsettedText rendering a \"" + - text.Text.substring(text.StartPosition + i, - text.StartPosition + i + 1) + - "\" (position " + (text.StartPosition + i) + - " of " + text.Text + ", offset " + advancements[i] + ")" ); - - graphics.drawString( text.Text.substring(text.StartPosition + i, text.StartPosition + i + 1), (float)advancements[i-1], (float)0.0 ); - } - - return true; - } - - //---------------------------------------------------------------------------------- - - // - // XServiceInfo impl - // ================= - // - - private static final String s_implName = "CanvasFont.java.impl"; - private static final String s_serviceName = "com.sun.star.rendering.XCanvasFont"; - - public String getImplementationName() - { - return s_implName; - } - - public String [] getSupportedServiceNames() - { - return new String [] { s_serviceName }; - } - - public boolean supportsService( String serviceName ) - { - return serviceName.equals( s_serviceName ); - } -} diff --git a/canvas/source/java/aqua/WindowAdapter.java b/canvas/source/java/aqua/WindowAdapter.java deleted file mode 100644 index 2529bb56e55c..000000000000 --- a/canvas/source/java/aqua/WindowAdapter.java +++ /dev/null @@ -1,202 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -// UNO -import com.sun.star.uno.UnoRuntime; -import com.sun.star.uno.XComponentContext; -import com.sun.star.uno.AnyConverter; -import com.sun.star.lang.XInitialization; -import com.sun.star.lib.uno.helper.WeakBase; - -// OOo AWT -import com.sun.star.awt.*; - -// system-dependent stuff -import sun.awt.*; - -//Apple specifics -import apple.awt.*; - - -public class WindowAdapter -// defacto implementing the interface, but not deriving from it, since -// we're no real XInterface here -// implements com.sun.star.awt.XWindow -{ - public java.awt.Frame frame; - private boolean fullscreen; - - public WindowAdapter( int windowHandle, - boolean _fullscreen ) - { - fullscreen = false; - - if( _fullscreen ) - { - // create a normal Java frame, and set it into fullscreen mode - frame = new javax.swing.JFrame( "Presentation" ); - frame.setUndecorated( true ); - frame.setVisible( true ); - - java.awt.Graphics2D graphics = (java.awt.Graphics2D)frame.getGraphics(); - if( graphics.getDeviceConfiguration().getDevice().isFullScreenSupported() ) - { - CanvasUtils.printLog( "WindowAdapter(Aqua): entering fullscreen mode" ); - graphics.getDeviceConfiguration().getDevice().setFullScreenWindow( frame ); - fullscreen = true; - } - else - { - CanvasUtils.printLog( "WindowAdapter(Aqua): fullscreen not supported" ); - } - - graphics.dispose(); - } - else - { - // we're initialized with the operating system window handle - // as the parameter. We then generate a dummy Java frame with - // that window as the parent, to fake a root window for the - // Java implementation. - - // now, we're getting slightly system dependent here. - String os = (String) System.getProperty("os.name"); - - // create the embedded frame - if( os.startsWith("Mac OS X") ) - frame = new apple.awt.CEmbeddedFrame( windowHandle ); - else - throw new com.sun.star.uno.RuntimeException(); - - -// frame = new javax.swing.JFrame( "Test window" ); - -// // resize it according to the given bounds -// frame.setBounds( boundRect ); -// frame.setVisible( true ); - } - } - - //---------------------------------------------------------------------------------- - - public void dispose() - { - if( fullscreen ) - { - java.awt.Graphics2D graphics = (java.awt.Graphics2D)frame.getGraphics(); - if( graphics.getDeviceConfiguration().getDevice().isFullScreenSupported() ) - { - CanvasUtils.printLog( "WindowAdapter(Aqua): leaving fullscreen mode" ); - graphics.getDeviceConfiguration().getDevice().setFullScreenWindow( null ); - } - graphics.dispose(); - } - - if( frame != null ) - frame.dispose(); - } - - //---------------------------------------------------------------------------------- - - // - // XWindow interface - // ================= - // - public void setPosSize( int X, int Y, int Width, int Height, short Flags ) - { - frame.setBounds( new java.awt.Rectangle( X, Y, Width, Height ) ); - } - - public com.sun.star.awt.Rectangle getPosSize( ) - { - java.awt.Rectangle bounds = frame.getBounds(); - - return new com.sun.star.awt.Rectangle( bounds.x, bounds.y, bounds.width, bounds.height ); - } - - public void setVisible( boolean visible ) - { - frame.setVisible( visible ); - } - - public void setEnable( boolean enable ) - { - frame.setEnabled( enable ); - } - - public void setFocus() - { - } - - public void addWindowListener( XWindowListener xListener ) - { - } - - public void removeWindowListener( XWindowListener xListener ) - { - } - - public void addFocusListener( XFocusListener xListener ) - { - } - - public void removeFocusListener( XFocusListener xListener ) - { - } - - public void addKeyListener( XKeyListener xListener ) - { - } - - public void removeKeyListener( XKeyListener xListener ) - { - } - - public void addMouseListener( XMouseListener xListener ) - { - } - - public void removeMouseListener( XMouseListener xListener ) - { - } - - public void addMouseMotionListener( XMouseMotionListener xListener ) - { - } - - public void removeMouseMotionListener( XMouseMotionListener xListener ) - { - } - - public void addPaintListener( XPaintListener xListener ) - { - } - - public void removePaintListener( XPaintListener xListener ) - { - } -} diff --git a/canvas/source/java/java_Service.java b/canvas/source/java/java_Service.java deleted file mode 100644 index 6fcaa1581ca8..000000000000 --- a/canvas/source/java/java_Service.java +++ /dev/null @@ -1,118 +0,0 @@ - -import com.sun.star.uno.UnoRuntime; -import com.sun.star.uno.XComponentContext; -import com.sun.star.awt.*; - -public class java_Service - extends com.sun.star.lib.uno.helper.WeakBase - implements com.sun.star.lang.XServiceInfo, foo.XBar -{ - private XToolkit m_xToolkit; - private XVclWindowPeer m_xPeer; - private javax.swing.JFrame m_frame; - - public java_Service( XComponentContext xContext ) - { - try - { - m_xToolkit = - (XToolkit) UnoRuntime.queryInterface( - XToolkit.class, - xContext.getServiceManager().createInstanceWithContext( - "com.sun.star.awt.Toolkit", xContext ) ); - } - catch (com.sun.star.uno.Exception exc) - { - throw new com.sun.star.uno.RuntimeException( - "exception occured gettin toolkit: " + exc, this ); - } - } - - // XBar impl - public void raiseAndCloseWindows( foo.XBar [] seq ) - throws com.sun.star.uno.Exception - { - for ( int nPos = 0; nPos < seq.length; ++nPos ) - seq[ nPos ].raiseWindows( "called by Java code" ); - - // modal dialog before closing - javax.swing.JOptionPane.showMessageDialog( - null, "[Java] all windows created." ); - - for ( int nPos = 0; nPos < seq.length; ++nPos ) - seq[ nPos ].closeWindows(); - } - - public void raiseWindows( String msg ) - throws com.sun.star.uno.Exception - { - // create java frame - m_frame = new javax.swing.JFrame( - "[java frame created by Java code] " + msg ); - m_frame.setSize( 500, 50 ); - m_frame.setLocation( 200, 500 ); - m_frame.setVisible( true ); - - // create office workwindow - m_xPeer = (XVclWindowPeer) UnoRuntime.queryInterface( - XVclWindowPeer.class, - m_xToolkit.createWindow( - new WindowDescriptor( - WindowClass.TOP, "workwindow", null, (short) -1, - new Rectangle( 800, 500, 500, 50 ), - WindowAttribute.SHOW | - WindowAttribute.BORDER | - WindowAttribute.SIZEABLE | - WindowAttribute.MOVEABLE | - WindowAttribute.CLOSEABLE ) ) ); - m_xPeer.setProperty( - "Title", "[office window created by Java code] " + msg ); - } - - public void closeWindows() - throws com.sun.star.uno.Exception - { - m_frame.dispose(); - m_xPeer.dispose(); - } - - - private static final String s_implName = "foo.java.impl"; - private static final String s_serviceName = "foo.java"; - - // XServiceInfo impl - public String getImplementationName() - { - return s_implName; - } - - public String [] getSupportedServiceNames() - { - return new String [] { s_serviceName }; - } - - public boolean supportsService( String serviceName ) - { - return serviceName.equals( s_serviceName ); - } - - public static com.sun.star.lang.XSingleServiceFactory __getServiceFactory( - String implName, - com.sun.star.lang.XMultiServiceFactory multiFactory, - com.sun.star.registry.XRegistryKey regKey ) - { - if (implName.equals( s_implName )) - { - return com.sun.star.comp.loader.FactoryHelper.getServiceFactory( - java_Service.class, s_serviceName, multiFactory, regKey ); - } - return null; - } - - public static boolean __writeRegistryServiceInfo( - com.sun.star.registry.XRegistryKey regKey ) - { - return com.sun.star.comp.loader.FactoryHelper.writeRegistryServiceInfo( - s_implName, s_serviceName, regKey ); - } -} diff --git a/canvas/source/java/makefile.mk b/canvas/source/java/makefile.mk deleted file mode 100644 index 86f329e4fe3b..000000000000 --- a/canvas/source/java/makefile.mk +++ /dev/null @@ -1,93 +0,0 @@ -#************************************************************************* -# -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# Copyright 2000, 2010 Oracle and/or its affiliates. -# -# OpenOffice.org - a multi-platform office productivity suite -# -# This file is part of OpenOffice.org. -# -# OpenOffice.org is free software: you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License version 3 -# only, as published by the Free Software Foundation. -# -# OpenOffice.org is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Lesser General Public License version 3 for more details -# (a copy is included in the LICENSE file that accompanied this code). -# -# You should have received a copy of the GNU Lesser General Public License -# version 3 along with OpenOffice.org. If not, see -# <http://www.openoffice.org/license.html> -# for a copy of the LGPLv3 License. -# -#************************************************************************* - -# Builds the Java Canvas implementation. - -PRJNAME = canvas -PRJ = ..$/.. -TARGET = javacanvas -PACKAGE = canvas - -USE_JAVAVER:=TRUE - -# --- Settings ----------------------------------------------------- - -.INCLUDE: settings.mk - -.IF "$(SOLAR_JAVA)"=="TRUE" -# Since Canvas needs newer features like -# e.g. java.awt.image.BufferStrategy, -# disabled for now for everything <1.4 -.IF "$(JAVANUMVER:s/.//)" >= "000100040000" - -JAVAFILES = \ - SpriteBase.java \ - JavaCanvas.java \ - CanvasGraphicDevice.java \ - CanvasUtils.java \ - CanvasFont.java \ - CanvasBitmap.java \ - CanvasSprite.java \ - CanvasCustomSprite.java \ - CanvasClonedSprite.java \ - TextLayout.java \ - BackBuffer.java \ - LinePolyPolygon.java \ - BezierPolyPolygon.java \ - SpriteRunner.java - -.IF "$(GUIBASE)"=="unx" - -JAVAFILES += x11/WindowAdapter.java - -.ELIF "$(GUIBASE)"=="aqua" - -JAVAFILES += aqua/WindowAdapter.java - -.ELSE - -JAVAFILES += win/WindowAdapter.java - -.ENDIF # "$(GUIBASE)"=="unx" - -JARFILES = jurt.jar unoil.jar ridl.jar juh.jar java_uno.jar -#JAVACLASSFILES = $(foreach,i,$(JAVAFILES) $(CLASSDIR)$/$(PACKAGE)$/$(i:b).class) - -JARTARGET = $(TARGET).uno.jar -JARCOMPRESS = TRUE -#JARCLASSDIRS = $(PACKAGE) -CUSTOMMANIFESTFILE = manifest - -.ENDIF # "$(JAVANUMVER:s/.//)" >= "000100040000" -.ENDIF # "$(SOLAR_JAVA)"=="TRUE" - -# --- Targets ------------------------------------------------------ - -.INCLUDE: target.mk - -#dist: $(JAVA_FILES:b:+".class") -# +jar -cvfm $(CLASSDIR)/JavaCanvas.jar $(JARMANIFEST) $(JAVACLASSFILES) diff --git a/canvas/source/java/manifest b/canvas/source/java/manifest deleted file mode 100644 index 6ddc3ab0ae51..000000000000 --- a/canvas/source/java/manifest +++ /dev/null @@ -1 +0,0 @@ -RegistrationClassName: JavaCanvas diff --git a/canvas/source/java/perftest/PerfTest.java b/canvas/source/java/perftest/PerfTest.java deleted file mode 100644 index 98e3cc5c3de5..000000000000 --- a/canvas/source/java/perftest/PerfTest.java +++ /dev/null @@ -1,314 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -import java.awt.*; -import java.awt.image.*; -import java.awt.geom.*; - - -public class PerfTest -{ - // the frame object we're generating. TODO: Remove public access. - private Frame frame; - private boolean fullscreen; - - public PerfTest() - { - fullscreen = false; - - // create a normal Java frame, and set it into fullscreen mode - frame = new javax.swing.JFrame( "PerformanceTest" ); - frame.setBounds( new Rectangle(0,0,1600,1200) ); - frame.setUndecorated( true ); - frame.setVisible( true ); - - Graphics2D graphics = (Graphics2D)frame.getGraphics(); - if( graphics.getDeviceConfiguration().getDevice().isFullScreenSupported() ) - { - System.err.println( "entering fullscreen mode" ); - graphics.getDeviceConfiguration().getDevice().setFullScreenWindow( frame ); - fullscreen = true; - } - else - { - System.err.println( "fullscreen not supported" ); - } - - graphics.dispose(); - } - - //---------------------------------------------------------------------------------- - - public void dispose() - { - if( fullscreen ) - { - Graphics2D graphics = (Graphics2D)frame.getGraphics(); - if( graphics.getDeviceConfiguration().getDevice().isFullScreenSupported() ) - { - System.err.println( "leaving fullscreen mode" ); - graphics.getDeviceConfiguration().getDevice().setFullScreenWindow( null ); - } - graphics.dispose(); - } - - if( frame != null ) - frame.dispose(); - } - - //---------------------------------------------------------------------------------- - - public static void initGraphics( Graphics2D graphics ) - { - if( graphics != null ) - { - RenderingHints hints = new RenderingHints(null); - boolean hq = true; - - if( hq ) - { - hints.add( new RenderingHints( RenderingHints.KEY_FRACTIONALMETRICS, - RenderingHints.VALUE_FRACTIONALMETRICS_ON ) ); -// hints.add( new RenderingHints( RenderingHints.KEY_ALPHA_INTERPOLATION, -// RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY) ); - hints.add( new RenderingHints( RenderingHints.KEY_ALPHA_INTERPOLATION, - RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED) ); -// hints.add( new RenderingHints( RenderingHints.KEY_INTERPOLATION, -// RenderingHints.VALUE_INTERPOLATION_BICUBIC) ); - hints.add( new RenderingHints( RenderingHints.KEY_INTERPOLATION, - RenderingHints.VALUE_INTERPOLATION_BILINEAR) ); -// hints.add( new RenderingHints( RenderingHints.KEY_RENDERING, -// RenderingHints.VALUE_RENDER_QUALITY) ); - hints.add( new RenderingHints( RenderingHints.KEY_RENDERING, - RenderingHints.VALUE_RENDER_SPEED) ); -// hints.add( new RenderingHints( RenderingHints.KEY_STROKE_CONTROL, -// RenderingHints.VALUE_STROKE_NORMALIZE) ); - hints.add( new RenderingHints( RenderingHints.KEY_STROKE_CONTROL, - RenderingHints.VALUE_STROKE_DEFAULT) ); - hints.add( new RenderingHints( RenderingHints.KEY_ANTIALIASING, - RenderingHints.VALUE_ANTIALIAS_ON) ); - } - else - { - hints.add( new RenderingHints( RenderingHints.KEY_ALPHA_INTERPOLATION, - RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED) ); - hints.add( new RenderingHints( RenderingHints.KEY_INTERPOLATION, - RenderingHints.VALUE_INTERPOLATION_BILINEAR) ); - hints.add( new RenderingHints( RenderingHints.KEY_RENDERING, - RenderingHints.VALUE_RENDER_SPEED) ); - hints.add( new RenderingHints( RenderingHints.KEY_STROKE_CONTROL, - RenderingHints.VALUE_STROKE_DEFAULT) ); - hints.add( new RenderingHints( RenderingHints.KEY_ANTIALIASING, - RenderingHints.VALUE_ANTIALIAS_OFF) ); - } - - // the least common denominator standard - hints.add( new RenderingHints( RenderingHints.KEY_FRACTIONALMETRICS, - RenderingHints.VALUE_FRACTIONALMETRICS_ON) ); - hints.add( new RenderingHints( RenderingHints.KEY_TEXT_ANTIALIASING, - RenderingHints.VALUE_TEXT_ANTIALIAS_ON) ); - - graphics.setRenderingHints( hints ); - } - } - - public void run() - { - frame.createBufferStrategy(2); - BufferStrategy bufferStrategy = frame.getBufferStrategy(); - - if( bufferStrategy.getCapabilities().isPageFlipping() ) - System.err.println( "double buffering is using page flipping" ); - else - System.err.println( "double buffering is using blitting" ); - - int width = 1600; - int height = 1200; - Graphics2D graphics = (Graphics2D)frame.getGraphics(); - VolatileImage backBuffer = graphics.getDeviceConfiguration().createCompatibleVolatileImage(width,height); // TODO: size dynamic - BufferedImage buffer = graphics.getDeviceConfiguration().createCompatibleImage(width,height, - Transparency.TRANSLUCENT); - BufferedImage buffer2 = graphics.getDeviceConfiguration().createCompatibleImage(width,height, - Transparency.TRANSLUCENT); - BufferedImage buffer3 = graphics.getDeviceConfiguration().createCompatibleImage(width,height, - Transparency.TRANSLUCENT); - - GraphicsDevice device = graphics.getDeviceConfiguration().getDevice(); - System.err.println( "Images generated. Available vram: " + device.getAvailableAcceleratedMemory() ); - - Graphics2D bufferGraphics = (Graphics2D)buffer.getGraphics(); - Graphics2D buffer2Graphics = (Graphics2D)buffer2.getGraphics(); - Graphics2D buffer3Graphics = (Graphics2D)buffer3.getGraphics(); - Graphics2D backBufGraphics = (Graphics2D)backBuffer.getGraphics(); - - System.err.println( "Image graphics generated. Available vram: " + device.getAvailableAcceleratedMemory() ); - - // init Graphics - initGraphics( graphics ); - initGraphics( bufferGraphics ); - initGraphics( buffer2Graphics ); - initGraphics( backBufGraphics ); - - // init content - Font font = new Font( "Times", Font.PLAIN, 100 ); - Font fpsFont = new Font( "Times", Font.PLAIN, 20 ); - - bufferGraphics.setComposite( AlphaComposite.getInstance(AlphaComposite.CLEAR)); - bufferGraphics.fillRect( 0,0,width,height ); - - bufferGraphics.setComposite( AlphaComposite.getInstance(AlphaComposite.SRC_OVER)); - bufferGraphics.setColor( Color.red ); - bufferGraphics.fillRect( 0,0,width/2,height/2 ); - bufferGraphics.setColor( Color.green ); - bufferGraphics.fillRect( width/2,0,width,height/2 ); - bufferGraphics.setColor( Color.blue ); - bufferGraphics.fillRect( 0,height/2,width/2,height ); - - buffer2Graphics.setColor( Color.red ); - buffer2Graphics.fillRect( 0,0,width/2,height/2 ); - buffer2Graphics.setColor( Color.green ); - buffer2Graphics.fillRect( width/2,0,width,height/2 ); - buffer2Graphics.setColor( Color.blue ); - buffer2Graphics.fillRect( 0,height/2,width/2,height ); - - buffer3Graphics.setColor( Color.blue ); - buffer3Graphics.fillRect( 0,0,width/2,height/2 ); - buffer3Graphics.setColor( Color.white ); - buffer3Graphics.fillRect( width/2,0,width,height/2 ); - buffer3Graphics.setColor( Color.gray ); - buffer3Graphics.fillRect( 0,height/2,width/2,height ); - - backBufGraphics.setColor( Color.white ); - backBufGraphics.fillRect(0,0,width,height); - backBufGraphics.setColor( Color.red ); - backBufGraphics.setFont( font ); - int i, turns=15; - for(i=0; i<turns; ++i) - { - backBufGraphics.drawString( "Crossfade test", width*i/turns, height*i/turns ); - } - - System.err.println( "Images filled with content. Available vram: " + device.getAvailableAcceleratedMemory() ); - - long lastTime = System.currentTimeMillis(); - int turn, numTurns = 100; - for(turn=0; turn<numTurns; ++turn) - { - // fetch the Graphics object to draw into (we're doing double - // buffering here, the content is later shown via - // bufferStrategy.show(). - Graphics2D graph = null; - - try - { - graph = (Graphics2D)bufferStrategy.getDrawGraphics(); - - try - { - // repaint background - graph.setComposite( AlphaComposite.getInstance(AlphaComposite.SRC_OVER) ); - graph.drawImage(backBuffer, 0, 0, null); - - // alpha-composite foreground on top of that - float alpha = turn/(float)numTurns; - graph.setComposite( AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha) ); - - graph.drawImage(buffer, 0, 0, null); - buffer.flush(); - graph.drawImage(buffer2, 100, 100, null); - buffer2.flush(); - - long currTime = System.currentTimeMillis(); - graph.setComposite( AlphaComposite.getInstance(AlphaComposite.SRC_OVER) ); - graph.setFont( fpsFont ); - graph.setColor( Color.black ); - String fps = new String( String.valueOf(1000.0/(currTime-lastTime)) ); - System.err.println( "Images composited. Framerate: " + fps + " fps" ); - graph.drawString( fps.substring(0,5) + " fps", 0, 20); - lastTime = currTime; - - System.err.println( "Available vram: " + device.getAvailableAcceleratedMemory() ); - } - catch( Exception e ) - { - } - - System.err.println( "Turn: " + turn ); - } - finally - { - if( graph != null ) - graph.dispose(); - } - - bufferStrategy.show(); - } - - try - { - Thread.sleep(2000); - } - catch( Exception e ) - { - } - } - - //---------------------------------------------------------------------------------- - - public static void main(String[] args) - { - // now, we're getting slightly system dependent here. - String os = (String) System.getProperty("os.name"); - - System.err.println( "System detected: " + os ); - - // tweak some speed knobs... - if( os.startsWith("Windows") ) - { - System.setProperty("sun.java2d.translaccel", "true"); - System.setProperty("sun.java2d.ddforcevram", "true"); - //System.setProperty("sun.java2d.accthreshold", "0"); - - System.err.println( "Optimizing for Windows" ); - } - else - { - System.setProperty("sun.java2d.opengl", "true"); - - System.err.println( "Optimizing for Unix" ); - } - - PerfTest test = new PerfTest(); - - test.run(); - - test.dispose(); - } - - //---------------------------------------------------------------------------------- - -} diff --git a/canvas/source/java/perftest/WindowAdapter.java b/canvas/source/java/perftest/WindowAdapter.java deleted file mode 100644 index fa34e6720fc7..000000000000 --- a/canvas/source/java/perftest/WindowAdapter.java +++ /dev/null @@ -1,197 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -import sun.awt.*; -import com.sun.star.awt.*; - - -public class WindowAdapter -// defacto implementing the interface, but not deriving from it, since -// we're no real XInterface here -// implements com.sun.star.awt.XWindow -{ - // the frame object we're generating. TODO: Remove public access. - public java.awt.Frame frame; - private boolean fullscreen; - - public WindowAdapter( int windowHandle, - boolean _fullscreen ) - { - CanvasUtils.printLog( "WindowAdapter(X11): constructor called" ); - fullscreen = false; - - if( _fullscreen ) - { - // create a normal Java frame, and set it into fullscreen mode - frame = new javax.swing.JFrame( "Presentation" ); - frame.setUndecorated( true ); - frame.setVisible( true ); - - java.awt.Graphics2D graphics = (java.awt.Graphics2D)frame.getGraphics(); - if( graphics.getDeviceConfiguration().getDevice().isFullScreenSupported() ) - { - CanvasUtils.printLog( "WindowAdapter(X11): entering fullscreen mode" ); - graphics.getDeviceConfiguration().getDevice().setFullScreenWindow( frame ); - fullscreen = true; - } - else - { - CanvasUtils.printLog( "WindowAdapter(X11): fullscreen not supported" ); - } - - graphics.dispose(); - } - else - { - // we're initialized with the operating system window handle - // as the parameter. We then generate a dummy Java frame with - // that window as the parent, to fake a root window for the - // Java implementation. - - // now, we're getting slightly system dependent here. - String os = (String) System.getProperty("os.name"); - - System.err.println("WindowAdapter created"); - - // create the embedded frame - if( os.startsWith("Linux") ) - { - // create a java frame from that - // TODO: Maybe that's the reason why we crash on Linux 1.5beta - // immediately: Try XAWT here, or naked X: sun.awt.X11.XEmbeddedFrame - - //frame = new sun.awt.motif.MEmbeddedFrame( windowHandle ); - //frame = new sun.awt.X11.XEmbeddedFrame( windowHandle ); // cannot currently compile - CanvasUtils.printLog( "WindowAdapter(X11): no frame created for now" ); - frame = null; - } - else - { - throw new com.sun.star.uno.RuntimeException(); - } - } - } - - //---------------------------------------------------------------------------------- - - public void dispose() - { - if( fullscreen ) - { - java.awt.Graphics2D graphics = (java.awt.Graphics2D)frame.getGraphics(); - if( graphics.getDeviceConfiguration().getDevice().isFullScreenSupported() ) - { - CanvasUtils.printLog( "WindowAdapter(X11): leaving fullscreen mode" ); - graphics.getDeviceConfiguration().getDevice().setFullScreenWindow( null ); - } - graphics.dispose(); - } - - if( frame != null ) - frame.dispose(); - } - - //---------------------------------------------------------------------------------- - - // - // XWindow interface - // ================= - // - public void setPosSize( int X, int Y, int Width, int Height, short Flags ) - { - frame.setBounds( new java.awt.Rectangle( X, Y, Width, Height ) ); - } - - public com.sun.star.awt.Rectangle getPosSize( ) - { - java.awt.Rectangle bounds = frame.getBounds(); - - return new com.sun.star.awt.Rectangle( bounds.x, bounds.y, bounds.width, bounds.height ); - } - - public void setVisible( boolean visible ) - { - frame.setVisible( visible ); - } - - public void setEnable( boolean enable ) - { - frame.setEnabled( enable ); - } - - public void setFocus() - { - } - - public void addWindowListener( XWindowListener xListener ) - { - } - - public void removeWindowListener( XWindowListener xListener ) - { - } - - public void addFocusListener( XFocusListener xListener ) - { - } - - public void removeFocusListener( XFocusListener xListener ) - { - } - - public void addKeyListener( XKeyListener xListener ) - { - } - - public void removeKeyListener( XKeyListener xListener ) - { - } - - public void addMouseListener( XMouseListener xListener ) - { - } - - public void removeMouseListener( XMouseListener xListener ) - { - } - - public void addMouseMotionListener( XMouseMotionListener xListener ) - { - } - - public void removeMouseMotionListener( XMouseMotionListener xListener ) - { - } - - public void addPaintListener( XPaintListener xListener ) - { - } - - public void removePaintListener( XPaintListener xListener ) - { - } -} diff --git a/canvas/source/java/perftest/makefile.mk b/canvas/source/java/perftest/makefile.mk deleted file mode 100644 index 787a42adfb74..000000000000 --- a/canvas/source/java/perftest/makefile.mk +++ /dev/null @@ -1,55 +0,0 @@ -#************************************************************************* -# -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# Copyright 2000, 2010 Oracle and/or its affiliates. -# -# OpenOffice.org - a multi-platform office productivity suite -# -# This file is part of OpenOffice.org. -# -# OpenOffice.org is free software: you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License version 3 -# only, as published by the Free Software Foundation. -# -# OpenOffice.org is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Lesser General Public License version 3 for more details -# (a copy is included in the LICENSE file that accompanied this code). -# -# You should have received a copy of the GNU Lesser General Public License -# version 3 along with OpenOffice.org. If not, see -# <http://www.openoffice.org/license.html> -# for a copy of the LGPLv3 License. -# -#************************************************************************* - -# Builds the Java Canvas implementation. - -PRJNAME = canvas -PRJ = ../../.. -TARGET = PerfTest -PACKAGE = test - -# --- Settings ----------------------------------------------------- - -.INCLUDE: settings.mk - -JAVAFILES = \ - PerfTest.java - -JARFILES = jurt.jar unoil.jar ridl.jar juh.jar java_uno.jar -JAVACLASSFILES = $(foreach,i,$(JAVAFILES) $(CLASSDIR)$/$(PACKAGE)$/$(i:b).class) - -JARTARGET = $(TARGET).jar -JARCOMPRESS = TRUE -#JARCLASSDIRS = $(PACKAGE) -CUSTOMMANIFESTFILE = manifest - -# --- Targets ------------------------------------------------------ - -.INCLUDE: target.mk - -#dist: $(JAVA_FILES:b:+".class") -# +jar -cvfm $(CLASSDIR)/PerfTest.jar $(JARMANIFEST) $(JAVACLASSFILES) diff --git a/canvas/source/java/perftest/manifest b/canvas/source/java/perftest/manifest deleted file mode 100644 index 805a87d47b57..000000000000 --- a/canvas/source/java/perftest/manifest +++ /dev/null @@ -1 +0,0 @@ -RegistrationClassName: PerfTest diff --git a/canvas/source/java/win/WindowAdapter.java b/canvas/source/java/win/WindowAdapter.java deleted file mode 100644 index 6cfe54db5991..000000000000 --- a/canvas/source/java/win/WindowAdapter.java +++ /dev/null @@ -1,199 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -// UNO -import com.sun.star.uno.UnoRuntime; -import com.sun.star.uno.XComponentContext; -import com.sun.star.uno.AnyConverter; -import com.sun.star.lang.XInitialization; -import com.sun.star.lib.uno.helper.WeakBase; - -// OOo AWT -import com.sun.star.awt.*; - -// system-dependent stuff -import sun.awt.*; - - -public class WindowAdapter -// defacto implementing the interface, but not deriving from it, since -// we're no real XInterface here -// implements com.sun.star.awt.XWindow -{ - public java.awt.Frame frame; - private boolean fullscreen; - - public WindowAdapter( int windowHandle, - boolean _fullscreen ) - { - fullscreen = false; - - if( _fullscreen ) - { - // create a normal Java frame, and set it into fullscreen mode - frame = new javax.swing.JFrame( "Presentation" ); - frame.setUndecorated( true ); - frame.setVisible( true ); - - java.awt.Graphics2D graphics = (java.awt.Graphics2D)frame.getGraphics(); - if( graphics.getDeviceConfiguration().getDevice().isFullScreenSupported() ) - { - CanvasUtils.printLog( "WindowAdapter(Win32): entering fullscreen mode" ); - graphics.getDeviceConfiguration().getDevice().setFullScreenWindow( frame ); - fullscreen = true; - } - else - { - CanvasUtils.printLog( "WindowAdapter(Win32): fullscreen not supported" ); - } - - graphics.dispose(); - } - else - { - // we're initialized with the operating system window handle - // as the parameter. We then generate a dummy Java frame with - // that window as the parent, to fake a root window for the - // Java implementation. - - // now, we're getting slightly system dependent here. - String os = (String) System.getProperty("os.name"); - - // create the embedded frame - if( os.startsWith("Windows") ) - frame = new sun.awt.windows.WEmbeddedFrame( windowHandle ); - else - throw new com.sun.star.uno.RuntimeException(); - - -// frame = new javax.swing.JFrame( "Test window" ); - -// // resize it according to the given bounds -// frame.setBounds( boundRect ); -// frame.setVisible( true ); - } - } - - //---------------------------------------------------------------------------------- - - public void dispose() - { - if( fullscreen ) - { - java.awt.Graphics2D graphics = (java.awt.Graphics2D)frame.getGraphics(); - if( graphics.getDeviceConfiguration().getDevice().isFullScreenSupported() ) - { - CanvasUtils.printLog( "WindowAdapter(Win32): leaving fullscreen mode" ); - graphics.getDeviceConfiguration().getDevice().setFullScreenWindow( null ); - } - graphics.dispose(); - } - - if( frame != null ) - frame.dispose(); - } - - //---------------------------------------------------------------------------------- - - // - // XWindow interface - // ================= - // - public void setPosSize( int X, int Y, int Width, int Height, short Flags ) - { - frame.setBounds( new java.awt.Rectangle( X, Y, Width, Height ) ); - } - - public com.sun.star.awt.Rectangle getPosSize( ) - { - java.awt.Rectangle bounds = frame.getBounds(); - - return new com.sun.star.awt.Rectangle( bounds.x, bounds.y, bounds.width, bounds.height ); - } - - public void setVisible( boolean visible ) - { - frame.setVisible( visible ); - } - - public void setEnable( boolean enable ) - { - frame.setEnabled( enable ); - } - - public void setFocus() - { - } - - public void addWindowListener( XWindowListener xListener ) - { - } - - public void removeWindowListener( XWindowListener xListener ) - { - } - - public void addFocusListener( XFocusListener xListener ) - { - } - - public void removeFocusListener( XFocusListener xListener ) - { - } - - public void addKeyListener( XKeyListener xListener ) - { - } - - public void removeKeyListener( XKeyListener xListener ) - { - } - - public void addMouseListener( XMouseListener xListener ) - { - } - - public void removeMouseListener( XMouseListener xListener ) - { - } - - public void addMouseMotionListener( XMouseMotionListener xListener ) - { - } - - public void removeMouseMotionListener( XMouseMotionListener xListener ) - { - } - - public void addPaintListener( XPaintListener xListener ) - { - } - - public void removePaintListener( XPaintListener xListener ) - { - } -} diff --git a/canvas/source/java/x11/WindowAdapter.java b/canvas/source/java/x11/WindowAdapter.java deleted file mode 100644 index 555f6c8ca1b8..000000000000 --- a/canvas/source/java/x11/WindowAdapter.java +++ /dev/null @@ -1,197 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -import com.sun.star.awt.*; - - -public class WindowAdapter -// defacto implementing the interface, but not deriving from it, since -// we're no real XInterface here -// implements com.sun.star.awt.XWindow -{ - // the frame object we're generating. TODO: Remove public access. - public java.awt.Frame frame; - private boolean fullscreen; - - public WindowAdapter( int windowHandle, - boolean _fullscreen ) - { - CanvasUtils.printLog( "WindowAdapter(X11): constructor called" ); - fullscreen = false; - - if( _fullscreen ) - { - // create a normal Java frame, and set it into fullscreen mode - frame = new javax.swing.JFrame( "Presentation" ); - frame.setUndecorated( true ); - frame.setVisible( true ); - - java.awt.Graphics2D graphics = (java.awt.Graphics2D)frame.getGraphics(); - if( graphics.getDeviceConfiguration().getDevice().isFullScreenSupported() ) - { - CanvasUtils.printLog( "WindowAdapter(X11): entering fullscreen mode" ); - graphics.getDeviceConfiguration().getDevice().setFullScreenWindow( frame ); - fullscreen = true; - } - else - { - CanvasUtils.printLog( "WindowAdapter(X11): fullscreen not supported" ); - } - - graphics.dispose(); - } - else - { - // we're initialized with the operating system window handle - // as the parameter. We then generate a dummy Java frame with - // that window as the parent, to fake a root window for the - // Java implementation. - - // now, we're getting slightly system dependent here. - String os = (String) System.getProperty("os.name"); - - System.err.println("WindowAdapter created"); - - // create the embedded frame - if( os.startsWith("Linux") ) - { - // create a java frame from that - // TODO: Maybe that's the reason why we crash on Linux 1.5beta - // immediately: Try XAWT here, or naked X: sun.awt.X11.XEmbeddedFrame - - // TODO - //frame = new sun.awt.motif.MEmbeddedFrame( windowHandle ); // Crashes 1.5, because class is unknown - //frame = new sun.awt.X11.XEmbeddedFrame( windowHandle ); // cannot currently compile, because class is not in 1.4. - CanvasUtils.printLog( "WindowAdapter(X11): no frame created for now" ); - frame = null; // disabled for now - } - else - { - throw new com.sun.star.uno.RuntimeException(); - } - } - } - - //---------------------------------------------------------------------------------- - - public void dispose() - { - if( fullscreen ) - { - java.awt.Graphics2D graphics = (java.awt.Graphics2D)frame.getGraphics(); - if( graphics.getDeviceConfiguration().getDevice().isFullScreenSupported() ) - { - CanvasUtils.printLog( "WindowAdapter(X11): leaving fullscreen mode" ); - graphics.getDeviceConfiguration().getDevice().setFullScreenWindow( null ); - } - graphics.dispose(); - } - - if( frame != null ) - frame.dispose(); - } - - //---------------------------------------------------------------------------------- - - // - // XWindow interface - // ================= - // - public void setPosSize( int X, int Y, int Width, int Height, short Flags ) - { - frame.setBounds( new java.awt.Rectangle( X, Y, Width, Height ) ); - } - - public com.sun.star.awt.Rectangle getPosSize( ) - { - java.awt.Rectangle bounds = frame.getBounds(); - - return new com.sun.star.awt.Rectangle( bounds.x, bounds.y, bounds.width, bounds.height ); - } - - public void setVisible( boolean visible ) - { - frame.setVisible( visible ); - } - - public void setEnable( boolean enable ) - { - frame.setEnabled( enable ); - } - - public void setFocus() - { - } - - public void addWindowListener( XWindowListener xListener ) - { - } - - public void removeWindowListener( XWindowListener xListener ) - { - } - - public void addFocusListener( XFocusListener xListener ) - { - } - - public void removeFocusListener( XFocusListener xListener ) - { - } - - public void addKeyListener( XKeyListener xListener ) - { - } - - public void removeKeyListener( XKeyListener xListener ) - { - } - - public void addMouseListener( XMouseListener xListener ) - { - } - - public void removeMouseListener( XMouseListener xListener ) - { - } - - public void addMouseMotionListener( XMouseMotionListener xListener ) - { - } - - public void removeMouseMotionListener( XMouseMotionListener xListener ) - { - } - - public void addPaintListener( XPaintListener xListener ) - { - } - - public void removePaintListener( XPaintListener xListener ) - { - } -} diff --git a/canvas/source/null/exports.map b/canvas/source/null/exports.map deleted file mode 100644 index 4101b0d761a9..000000000000 --- a/canvas/source/null/exports.map +++ /dev/null @@ -1,8 +0,0 @@ -CAN_1_0 { - global: - component_getImplementationEnvironment; - component_writeInfo; - component_getFactory; - local: - *; -}; diff --git a/canvas/source/null/makefile.mk b/canvas/source/null/makefile.mk index 98bf2c5c9b71..07971ef8153e 100644 --- a/canvas/source/null/makefile.mk +++ b/canvas/source/null/makefile.mk @@ -60,7 +60,7 @@ SHL1IMPLIB=i$(TARGET) SHL1LIBS=$(SLB)$/$(TARGET).lib SHL1DEF=$(MISC)$/$(SHL1TARGET).def -SHL1VERSIONMAP=exports.map +SHL1VERSIONMAP=$(SOLARENV)/src/component.map DEF1NAME=$(SHL1TARGET) DEF1EXPORTFILE=exports.dxp diff --git a/canvas/source/null/null_spritecanvas.hxx b/canvas/source/null/null_spritecanvas.hxx index 662897a3df10..136e09a291db 100644 --- a/canvas/source/null/null_spritecanvas.hxx +++ b/canvas/source/null/null_spritecanvas.hxx @@ -38,7 +38,7 @@ #include <com/sun/star/rendering/XIntegerBitmap.hpp> #include <com/sun/star/rendering/XGraphicDevice.hpp> #include <com/sun/star/rendering/XBufferController.hpp> -#include <com/sun/star/rendering/XParametricPolyPolygon2DFactory.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> #include <cppuhelper/compbase8.hxx> #include <comphelper/uno3.hxx> @@ -57,7 +57,7 @@ namespace nullcanvas typedef ::cppu::WeakComponentImplHelper8< ::com::sun::star::rendering::XSpriteCanvas, ::com::sun::star::rendering::XIntegerBitmap, ::com::sun::star::rendering::XGraphicDevice, - ::com::sun::star::rendering::XParametricPolyPolygon2DFactory, + ::com::sun::star::lang::XMultiServiceFactory, ::com::sun::star::rendering::XBufferController, ::com::sun::star::awt::XWindowListener, ::com::sun::star::beans::XPropertySet, diff --git a/canvas/source/simplecanvas/exports.map b/canvas/source/simplecanvas/exports.map deleted file mode 100644 index 4101b0d761a9..000000000000 --- a/canvas/source/simplecanvas/exports.map +++ /dev/null @@ -1,8 +0,0 @@ -CAN_1_0 { - global: - component_getImplementationEnvironment; - component_writeInfo; - component_getFactory; - local: - *; -}; diff --git a/canvas/source/simplecanvas/makefile.mk b/canvas/source/simplecanvas/makefile.mk index dc99c0a9bbc9..4d5a7e7bb3a1 100644 --- a/canvas/source/simplecanvas/makefile.mk +++ b/canvas/source/simplecanvas/makefile.mk @@ -52,7 +52,7 @@ SHL1IMPLIB=i$(TARGET) SHL1LIBS=$(SLB)$/$(TARGET).lib SHL1DEF=$(MISC)$/$(SHL1TARGET).def -SHL1VERSIONMAP=exports.map +SHL1VERSIONMAP=$(SOLARENV)/src/component.map DEF1NAME=$(SHL1TARGET) DEF1EXPORTFILE=exports.dxp diff --git a/canvas/source/tools/canvastools.cxx b/canvas/source/tools/canvastools.cxx index 7ce8d02038b9..ad833cc3ca40 100644..100755 --- a/canvas/source/tools/canvastools.cxx +++ b/canvas/source/tools/canvastools.cxx @@ -991,6 +991,54 @@ namespace canvas return aPolyPoly; } + int calcGradientStepCount( ::basegfx::B2DHomMatrix& rTotalTransform, + const rendering::ViewState& viewState, + const rendering::RenderState& renderState, + const rendering::Texture& texture, + int nColorSteps ) + { + // calculate overall texture transformation (directly from + // texture to device space). + ::basegfx::B2DHomMatrix aMatrix; + + rTotalTransform.identity(); + ::basegfx::unotools::homMatrixFromAffineMatrix( rTotalTransform, + texture.AffineTransform ); + ::canvas::tools::mergeViewAndRenderTransform(aMatrix, + viewState, + renderState); + rTotalTransform *= aMatrix; // prepend total view/render transformation + + // determine size of gradient in device coordinate system + // (to e.g. determine sensible number of gradient steps) + ::basegfx::B2DPoint aLeftTop( 0.0, 0.0 ); + ::basegfx::B2DPoint aLeftBottom( 0.0, 1.0 ); + ::basegfx::B2DPoint aRightTop( 1.0, 0.0 ); + ::basegfx::B2DPoint aRightBottom( 1.0, 1.0 ); + + aLeftTop *= rTotalTransform; + aLeftBottom *= rTotalTransform; + aRightTop *= rTotalTransform; + aRightBottom*= rTotalTransform; + + // longest line in gradient bound rect + const int nGradientSize( + static_cast<int>( + ::std::max( + ::basegfx::B2DVector(aRightBottom-aLeftTop).getLength(), + ::basegfx::B2DVector(aRightTop-aLeftBottom).getLength() ) + 1.0 ) ); + + // typical number for pixel of the same color (strip size) + const int nStripSize( nGradientSize < 50 ? 2 : 4 ); + + // use at least three steps, and at utmost the number of color + // steps + return ::std::max( 3, + ::std::min( + nGradientSize / nStripSize, + nColorSteps ) ); + } + } // namespace tools } // namespace canvas diff --git a/canvas/source/tools/image.cxx b/canvas/source/tools/image.cxx index 2b7d38abc8ea..b6183e463e99 100644 --- a/canvas/source/tools/image.cxx +++ b/canvas/source/tools/image.cxx @@ -1512,7 +1512,7 @@ void Image::fillGradientImpl( const ParametricPolyPolygon::Values& rValues, typedef color_generator_adaptor<color_type> color_generator_type; unsigned int dwNumSteps = static_cast<unsigned int>(rBounds.getWidth()); color_generator_type colors(color1,color2,dwNumSteps); - colors.set_linear(rValues.meType != ParametricPolyPolygon::GRADIENT_AXIAL); + colors.set_linear(true); // color = f(x,y) gradient_polymorphic_wrapper<agg::gradient_x> gf_x; diff --git a/canvas/source/tools/parametricpolypolygon.cxx b/canvas/source/tools/parametricpolypolygon.cxx index db449f6c15f8..368f04a572e3 100644 --- a/canvas/source/tools/parametricpolypolygon.cxx +++ b/canvas/source/tools/parametricpolypolygon.cxx @@ -50,68 +50,126 @@ using namespace ::com::sun::star; namespace canvas { - ParametricPolyPolygon* ParametricPolyPolygon::createLinearHorizontalGradient( - const uno::Reference< rendering::XGraphicDevice >& rDevice, - const uno::Sequence< uno::Sequence< double > >& colors, - const uno::Sequence< double >& stops ) + uno::Sequence<rtl::OUString> ParametricPolyPolygon::getAvailableServiceNames() { - // TODO(P2): hold gradient brush statically, and only setup - // the colors - return new ParametricPolyPolygon( rDevice, GRADIENT_LINEAR, colors, stops ); + uno::Sequence<rtl::OUString> aRet(3); + aRet[0] = rtl::OUString::createFromAscii("LinearGradient"); + aRet[1] = rtl::OUString::createFromAscii("EllipticalGradient"); + aRet[2] = rtl::OUString::createFromAscii("RectangularGradient"); + + return aRet; + } + + ParametricPolyPolygon* ParametricPolyPolygon::create( + const uno::Reference< rendering::XGraphicDevice >& rDevice, + const ::rtl::OUString& rServiceName, + const uno::Sequence< uno::Any >& rArgs ) + { + uno::Sequence< uno::Sequence< double > > colorSequence(2); + uno::Sequence< double > colorStops(2); + double fAspectRatio=1.0; + + // defaults + uno::Sequence< rendering::RGBColor > rgbColors(1); + rgbColors[0] = rendering::RGBColor(0,0,0); + colorSequence[0] = rDevice->getDeviceColorSpace()->convertFromRGB(rgbColors); + rgbColors[0] = rendering::RGBColor(1,1,1); + colorSequence[1] = rDevice->getDeviceColorSpace()->convertFromRGB(rgbColors); + colorStops[0] = 0; + colorStops[1] = 1; + + // extract args + for( sal_Int32 i=0; i<rArgs.getLength(); ++i ) + { + beans::PropertyValue aProp; + if( (rArgs[i] >>= aProp) ) + { + if( aProp.Name.equalsAscii("Colors") ) + { + aProp.Value >>= colorSequence; + } + else if( aProp.Name.equalsAscii("Stops") ) + { + aProp.Value >>= colorStops; + } + else if( aProp.Name.equalsAscii("AspectRatio") ) + { + aProp.Value >>= fAspectRatio; + } + } + } + + if( rServiceName.equalsAscii("LinearGradient") ) + { + return createLinearHorizontalGradient(rDevice, colorSequence, colorStops); + } + else if( rServiceName.equalsAscii("EllipticalGradient") ) + { + return createEllipticalGradient(rDevice, colorSequence, colorStops, fAspectRatio); + } + else if( rServiceName.equalsAscii("RectangularGradient") ) + { + return createRectangularGradient(rDevice, colorSequence, colorStops, fAspectRatio); + } + else if( rServiceName.equalsAscii("VerticalLineHatch") ) + { + // TODO: NYI + } + else if( rServiceName.equalsAscii("OrthogonalLinesHatch") ) + { + // TODO: NYI + } + else if( rServiceName.equalsAscii("ThreeCrossingLinesHatch") ) + { + // TODO: NYI + } + else if( rServiceName.equalsAscii("FourCrossingLinesHatch") ) + { + // TODO: NYI + } + + return NULL; } - ParametricPolyPolygon* ParametricPolyPolygon::createAxialHorizontalGradient( + ParametricPolyPolygon* ParametricPolyPolygon::createLinearHorizontalGradient( const uno::Reference< rendering::XGraphicDevice >& rDevice, const uno::Sequence< uno::Sequence< double > >& colors, const uno::Sequence< double >& stops ) { // TODO(P2): hold gradient brush statically, and only setup // the colors - return new ParametricPolyPolygon( rDevice, GRADIENT_AXIAL, colors, stops ); - } - - namespace - { - double calcAspectRatio( const geometry::RealRectangle2D& rBoundRect ) - { - const double nWidth( rBoundRect.X2 - rBoundRect.X1 ); - const double nHeight( rBoundRect.Y2 - rBoundRect.Y1 ); - - return ::basegfx::fTools::equalZero( nHeight ) ? 1.0 : fabs( nWidth / nHeight ); - } + return new ParametricPolyPolygon( rDevice, GRADIENT_LINEAR, colors, stops ); } ParametricPolyPolygon* ParametricPolyPolygon::createEllipticalGradient( const uno::Reference< rendering::XGraphicDevice >& rDevice, const uno::Sequence< uno::Sequence< double > >& colors, const uno::Sequence< double >& stops, - const geometry::RealRectangle2D& boundRect ) + double fAspectRatio ) { // TODO(P2): hold gradient polygon statically, and only setup // the colors return new ParametricPolyPolygon( rDevice, ::basegfx::tools::createPolygonFromCircle( - ::basegfx::B2DPoint( 0.5, 0.5), 0.5 ), + ::basegfx::B2DPoint(0,0), 1 ), GRADIENT_ELLIPTICAL, - colors, stops, - calcAspectRatio( boundRect ) ); + colors, stops, fAspectRatio ); } ParametricPolyPolygon* ParametricPolyPolygon::createRectangularGradient( const uno::Reference< rendering::XGraphicDevice >& rDevice, const uno::Sequence< uno::Sequence< double > >& colors, const uno::Sequence< double >& stops, - const geometry::RealRectangle2D& boundRect ) + double fAspectRatio ) { // TODO(P2): hold gradient polygon statically, and only setup // the colors return new ParametricPolyPolygon( rDevice, ::basegfx::tools::createPolygonFromRect( - ::basegfx::B2DRectangle( 0.0, 0.0, 1.0, 1.0 ) ), + ::basegfx::B2DRectangle( -1, -1, 1, 1 ) ), GRADIENT_RECTANGULAR, - colors, stops, - calcAspectRatio( boundRect ) ); + colors, stops, fAspectRatio ); } void SAL_CALL ParametricPolyPolygon::disposing() diff --git a/canvas/source/tools/verifyinput.cxx b/canvas/source/tools/verifyinput.cxx index c2ee4ed968a0..42ab1c7aee19 100644 --- a/canvas/source/tools/verifyinput.cxx +++ b/canvas/source/tools/verifyinput.cxx @@ -426,7 +426,7 @@ namespace canvas #endif } - if( texture.RepeatModeX < rendering::TexturingMode::CLAMP || + if( texture.RepeatModeX < rendering::TexturingMode::NONE || texture.RepeatModeX > rendering::TexturingMode::REPEAT ) { #if OSL_DEBUG_LEVEL > 0 @@ -442,7 +442,7 @@ namespace canvas #endif } - if( texture.RepeatModeY < rendering::TexturingMode::CLAMP || + if( texture.RepeatModeY < rendering::TexturingMode::NONE || texture.RepeatModeY > rendering::TexturingMode::REPEAT ) { #if OSL_DEBUG_LEVEL > 0 diff --git a/canvas/source/vcl/canvas.hxx b/canvas/source/vcl/canvas.hxx index f7667d8f2c19..adda8d8eea40 100644 --- a/canvas/source/vcl/canvas.hxx +++ b/canvas/source/vcl/canvas.hxx @@ -38,7 +38,6 @@ #include <com/sun/star/rendering/XIntegerBitmap.hpp> #include <com/sun/star/rendering/XGraphicDevice.hpp> #include <com/sun/star/rendering/XBufferController.hpp> -#include <com/sun/star/rendering/XParametricPolyPolygon2DFactory.hpp> #include <cppuhelper/compbase7.hxx> #include <comphelper/uno3.hxx> @@ -60,7 +59,7 @@ namespace vclcanvas typedef ::cppu::WeakComponentImplHelper7< ::com::sun::star::rendering::XBitmapCanvas, ::com::sun::star::rendering::XIntegerBitmap, ::com::sun::star::rendering::XGraphicDevice, - ::com::sun::star::rendering::XParametricPolyPolygon2DFactory, + ::com::sun::star::lang::XMultiServiceFactory, ::com::sun::star::util::XUpdatable, ::com::sun::star::beans::XPropertySet, ::com::sun::star::lang::XServiceName > GraphicDeviceBase_Base; diff --git a/canvas/source/vcl/canvashelper_texturefill.cxx b/canvas/source/vcl/canvashelper_texturefill.cxx index 11350c0b4f9f..023ceb2b5005 100644..100755 --- a/canvas/source/vcl/canvashelper_texturefill.cxx +++ b/canvas/source/vcl/canvashelper_texturefill.cxx @@ -54,6 +54,8 @@ #include <basegfx/polygon/b2dpolypolygontools.hxx> #include <basegfx/polygon/b2dlinegeometry.hxx> #include <basegfx/tools/tools.hxx> +#include <basegfx/tools/lerp.hxx> +#include <basegfx/tools/keystoplerp.hxx> #include <basegfx/tools/canvastools.hxx> #include <basegfx/numeric/ftools.hxx> @@ -62,6 +64,9 @@ #include <canvas/canvastools.hxx> #include <canvas/parametricpolypolygon.hxx> +#include <boost/bind.hpp> +#include <boost/tuple/tuple.hpp> + #include "spritecanvas.hxx" #include "canvashelper.hxx" #include "impltools.hxx" @@ -115,17 +120,13 @@ namespace vclcanvas Since most of the code for linear and axial gradients are the same, we've a unified method here */ - void fillGeneralLinearGradient( OutputDevice& rOutDev, - const ::basegfx::B2DHomMatrix& rTextureTransform, - const ::Rectangle& rBounds, - int nStepCount, - const ::Color& rColor1, - const ::Color& rColor2, - bool bFillNonOverlapping, - bool bAxialGradient ) + void fillLinearGradient( OutputDevice& rOutDev, + const ::basegfx::B2DHomMatrix& rTextureTransform, + const ::Rectangle& rBounds, + unsigned int nStepCount, + const ::canvas::ParametricPolyPolygon::Values& rValues, + const std::vector< ::Color >& rColors ) { - (void)bFillNonOverlapping; - // determine general position of gradient in relation to // the bound rect // ===================================================== @@ -204,36 +205,26 @@ namespace vclcanvas // iteratively render all other strips // ----------------------------------- - // ensure that nStepCount is odd, to have a well-defined - // middle index for axial gradients. - if( bAxialGradient && !(nStepCount % 2) ) + // ensure that nStepCount matches color stop parity, to + // have a well-defined middle color e.g. for axial + // gradients. + if( (rColors.size() % 2) != (nStepCount % 2) ) ++nStepCount; - const int nStepCountHalved( nStepCount / 2 ); + basegfx::tools::KeyStopLerp aLerper(rValues.maStops); // only iterate nStepCount-1 steps, as the last strip is // explicitely painted below - for( int i=0; i<nStepCount-1; ++i ) + for( unsigned int i=0; i<nStepCount-1; ++i ) { - // lerp color - if( bAxialGradient ) - { - // axial gradient has a triangle-like interpolation function - const int iPrime( i<=nStepCountHalved ? i : nStepCount-i-1); + std::ptrdiff_t nIndex; + double fAlpha; + boost::tuples::tie(nIndex,fAlpha)=aLerper.lerp(double(i)/nStepCount); - rOutDev.SetFillColor( - Color( (UINT8)(((nStepCountHalved - iPrime)*rColor1.GetRed() + iPrime*rColor2.GetRed())/nStepCountHalved), - (UINT8)(((nStepCountHalved - iPrime)*rColor1.GetGreen() + iPrime*rColor2.GetGreen())/nStepCountHalved), - (UINT8)(((nStepCountHalved - iPrime)*rColor1.GetBlue() + iPrime*rColor2.GetBlue())/nStepCountHalved) ) ); - } - else - { - // linear gradient has a plain lerp between start and end color - rOutDev.SetFillColor( - Color( (UINT8)(((nStepCount - i)*rColor1.GetRed() + i*rColor2.GetRed())/nStepCount), - (UINT8)(((nStepCount - i)*rColor1.GetGreen() + i*rColor2.GetGreen())/nStepCount), - (UINT8)(((nStepCount - i)*rColor1.GetBlue() + i*rColor2.GetBlue())/nStepCount) ) ); - } + rOutDev.SetFillColor( + Color( (UINT8)(basegfx::tools::lerp(rColors[nIndex].GetRed(),rColors[nIndex+1].GetRed(),fAlpha)), + (UINT8)(basegfx::tools::lerp(rColors[nIndex].GetGreen(),rColors[nIndex+1].GetGreen(),fAlpha)), + (UINT8)(basegfx::tools::lerp(rColors[nIndex].GetBlue(),rColors[nIndex+1].GetBlue(),fAlpha)) )); // copy right egde of polygon to left edge (and also // copy the closing point) @@ -280,59 +271,18 @@ namespace vclcanvas aTempPoly[3] = ::Point( ::basegfx::fround( rPoint4.getX() ), ::basegfx::fround( rPoint4.getY() ) ); - if( bAxialGradient ) - rOutDev.SetFillColor( rColor1 ); - else - rOutDev.SetFillColor( rColor2 ); + rOutDev.SetFillColor( rColors.back() ); rOutDev.DrawPolygon( aTempPoly ); } - - inline void fillLinearGradient( OutputDevice& rOutDev, - const ::Color& rColor1, - const ::Color& rColor2, - const ::basegfx::B2DHomMatrix& rTextureTransform, - const ::Rectangle& rBounds, - int nStepCount, - bool bFillNonOverlapping ) - { - fillGeneralLinearGradient( rOutDev, - rTextureTransform, - rBounds, - nStepCount, - rColor1, - rColor2, - bFillNonOverlapping, - false ); - } - - inline void fillAxialGradient( OutputDevice& rOutDev, - const ::Color& rColor1, - const ::Color& rColor2, - const ::basegfx::B2DHomMatrix& rTextureTransform, - const ::Rectangle& rBounds, - int nStepCount, - bool bFillNonOverlapping ) - { - fillGeneralLinearGradient( rOutDev, - rTextureTransform, - rBounds, - nStepCount, - rColor1, - rColor2, - bFillNonOverlapping, - true ); - } - void fillPolygonalGradient( OutputDevice& rOutDev, - const ::canvas::ParametricPolyPolygon::Values& rValues, - const ::Color& rColor1, - const ::Color& rColor2, const ::basegfx::B2DHomMatrix& rTextureTransform, const ::Rectangle& rBounds, - int nStepCount, - bool bFillNonOverlapping ) + unsigned int nStepCount, + bool bFillNonOverlapping, + const ::canvas::ParametricPolyPolygon::Values& rValues, + const std::vector< ::Color >& rColors ) { const ::basegfx::B2DPolygon& rGradientPoly( rValues.maGradientPoly ); @@ -366,9 +316,6 @@ namespace vclcanvas // apply scaling (possibly anisotrophic) to inner polygon // ------------------------------------------------------ - // move center of scaling to origin - aInnerPolygonTransformMatrix.translate( -0.5, -0.5 ); - // scale inner polygon according to aspect ratio: for // wider-than-tall bounds (nAspectRatio > 1.0), the inner // polygon, representing the gradient focus, must have @@ -393,9 +340,6 @@ namespace vclcanvas aInnerPolygonTransformMatrix.scale( 0.0, 0.0 ); } - // move origin back to former center of polygon - aInnerPolygonTransformMatrix.translate( 0.5, 0.5 ); - // and finally, add texture transform to it. aInnerPolygonTransformMatrix *= rTextureTransform; @@ -403,8 +347,8 @@ namespace vclcanvas aInnerPoly.transform( aInnerPolygonTransformMatrix ); - const sal_Int32 nNumPoints( aOuterPoly.count() ); - ::Polygon aTempPoly( static_cast<USHORT>(nNumPoints+1) ); + const sal_uInt32 nNumPoints( aOuterPoly.count() ); + ::Polygon aTempPoly( static_cast<USHORT>(nNumPoints+1) ); // increase number of steps by one: polygonal gradients have // the outermost polygon rendered in rColor2, and the @@ -422,37 +366,42 @@ namespace vclcanvas // color). ++nStepCount; + basegfx::tools::KeyStopLerp aLerper(rValues.maStops); + if( !bFillNonOverlapping ) { // fill background - rOutDev.SetFillColor( rColor1 ); + rOutDev.SetFillColor( rColors.front() ); rOutDev.DrawRect( rBounds ); // render polygon // ============== - for( int i=1,p; i<nStepCount; ++i ) + for( unsigned int i=1,p; i<nStepCount; ++i ) { + const double fT( i/double(nStepCount) ); + + std::ptrdiff_t nIndex; + double fAlpha; + boost::tuples::tie(nIndex,fAlpha)=aLerper.lerp(fT); + // lerp color rOutDev.SetFillColor( - Color( (UINT8)(((nStepCount - i)*rColor1.GetRed() + i*rColor2.GetRed())/nStepCount), - (UINT8)(((nStepCount - i)*rColor1.GetGreen() + i*rColor2.GetGreen())/nStepCount), - (UINT8)(((nStepCount - i)*rColor1.GetBlue() + i*rColor2.GetBlue())/nStepCount) ) ); + Color( (UINT8)(basegfx::tools::lerp(rColors[nIndex].GetRed(),rColors[nIndex+1].GetRed(),fAlpha)), + (UINT8)(basegfx::tools::lerp(rColors[nIndex].GetGreen(),rColors[nIndex+1].GetGreen(),fAlpha)), + (UINT8)(basegfx::tools::lerp(rColors[nIndex].GetBlue(),rColors[nIndex+1].GetBlue(),fAlpha)) )); // scale and render polygon, by interpolating between // outer and inner polygon. - // calc interpolation parameter in [0,1] range - const double nT( (nStepCount-i)/double(nStepCount) ); - for( p=0; p<nNumPoints; ++p ) { const ::basegfx::B2DPoint& rOuterPoint( aOuterPoly.getB2DPoint(p) ); const ::basegfx::B2DPoint& rInnerPoint( aInnerPoly.getB2DPoint(p) ); aTempPoly[(USHORT)p] = ::Point( - basegfx::fround( (1.0-nT)*rInnerPoint.getX() + nT*rOuterPoint.getX() ), - basegfx::fround( (1.0-nT)*rInnerPoint.getY() + nT*rOuterPoint.getY() ) ); + basegfx::fround( fT*rInnerPoint.getX() + (1-fT)*rOuterPoint.getX() ), + basegfx::fround( fT*rInnerPoint.getY() + (1-fT)*rOuterPoint.getY() ) ); } // close polygon explicitely @@ -486,13 +435,19 @@ namespace vclcanvas aTempPolyPoly.Insert( aTempPoly ); aTempPolyPoly.Insert( aTempPoly2 ); - for( int i=0,p; i<nStepCount; ++i ) + for( unsigned int i=0,p; i<nStepCount; ++i ) { + const double fT( (i+1)/double(nStepCount) ); + + std::ptrdiff_t nIndex; + double fAlpha; + boost::tuples::tie(nIndex,fAlpha)=aLerper.lerp(fT); + // lerp color rOutDev.SetFillColor( - Color( (UINT8)(((nStepCount - i)*rColor1.GetRed() + i*rColor2.GetRed())/nStepCount), - (UINT8)(((nStepCount - i)*rColor1.GetGreen() + i*rColor2.GetGreen())/nStepCount), - (UINT8)(((nStepCount - i)*rColor1.GetBlue() + i*rColor2.GetBlue())/nStepCount) ) ); + Color( (UINT8)(basegfx::tools::lerp(rColors[nIndex].GetRed(),rColors[nIndex+1].GetRed(),fAlpha)), + (UINT8)(basegfx::tools::lerp(rColors[nIndex].GetGreen(),rColors[nIndex+1].GetGreen(),fAlpha)), + (UINT8)(basegfx::tools::lerp(rColors[nIndex].GetBlue(),rColors[nIndex+1].GetBlue(),fAlpha)) )); #if defined(VERBOSE) && OSL_DEBUG_LEVEL > 0 if( i && !(i % 10) ) @@ -503,17 +458,14 @@ namespace vclcanvas // calculate the inner polygon, which is actually the // start of the _next_ color strip. Thus, i+1 - // calc interpolation parameter in [0,1] range - const double nT( (nStepCount-i-1)/double(nStepCount) ); - for( p=0; p<nNumPoints; ++p ) { const ::basegfx::B2DPoint& rOuterPoint( aOuterPoly.getB2DPoint(p) ); const ::basegfx::B2DPoint& rInnerPoint( aInnerPoly.getB2DPoint(p) ); aTempPoly[(USHORT)p] = ::Point( - basegfx::fround( (1.0-nT)*rInnerPoint.getX() + nT*rOuterPoint.getX() ), - basegfx::fround( (1.0-nT)*rInnerPoint.getY() + nT*rOuterPoint.getY() ) ); + basegfx::fround( fT*rInnerPoint.getX() + (1-fT)*rOuterPoint.getX() ), + basegfx::fround( fT*rInnerPoint.getY() + (1-fT)*rOuterPoint.getY() ) ); } // close polygon explicitely @@ -546,46 +498,33 @@ namespace vclcanvas void doGradientFill( OutputDevice& rOutDev, const ::canvas::ParametricPolyPolygon::Values& rValues, - const ::Color& rColor1, - const ::Color& rColor2, + const std::vector< ::Color >& rColors, const ::basegfx::B2DHomMatrix& rTextureTransform, const ::Rectangle& rBounds, - int nStepCount, + unsigned int nStepCount, bool bFillNonOverlapping ) { switch( rValues.meType ) { case ::canvas::ParametricPolyPolygon::GRADIENT_LINEAR: fillLinearGradient( rOutDev, - rColor1, - rColor2, rTextureTransform, rBounds, nStepCount, - bFillNonOverlapping ); - break; - - case ::canvas::ParametricPolyPolygon::GRADIENT_AXIAL: - fillAxialGradient( rOutDev, - rColor1, - rColor2, - rTextureTransform, - rBounds, - nStepCount, - bFillNonOverlapping ); + rValues, + rColors ); break; case ::canvas::ParametricPolyPolygon::GRADIENT_ELLIPTICAL: // FALLTHROUGH intended case ::canvas::ParametricPolyPolygon::GRADIENT_RECTANGULAR: fillPolygonalGradient( rOutDev, - rValues, - rColor1, - rColor2, rTextureTransform, rBounds, nStepCount, - bFillNonOverlapping ); + bFillNonOverlapping, + rValues, + rColors ); break; default: @@ -594,11 +533,19 @@ namespace vclcanvas } } + int numColorSteps( const ::Color& rColor1, const ::Color& rColor2 ) + { + return ::std::max( + labs( rColor1.GetRed() - rColor2.GetRed() ), + ::std::max( + labs( rColor1.GetGreen() - rColor2.GetGreen() ), + labs( rColor1.GetBlue() - rColor2.GetBlue() ) ) ); + } + bool gradientFill( OutputDevice& rOutDev, OutputDevice* p2ndOutDev, const ::canvas::ParametricPolyPolygon::Values& rValues, - const ::Color& rColor1, - const ::Color& rColor2, + const std::vector< ::Color >& rColors, const PolyPolygon& rPoly, const rendering::ViewState& viewState, const rendering::RenderState& renderState, @@ -612,65 +559,27 @@ namespace vclcanvas // deadlocks, canvashelper calls this method with locked own // mutex. - // calculate overall texture transformation (directly from - // texture to device space). - ::basegfx::B2DHomMatrix aMatrix; - ::basegfx::B2DHomMatrix aTextureTransform; - - ::basegfx::unotools::homMatrixFromAffineMatrix( aTextureTransform, - texture.AffineTransform ); - ::canvas::tools::mergeViewAndRenderTransform(aMatrix, - viewState, - renderState); - aTextureTransform *= aMatrix; // prepend total view/render transformation - - // determine maximal bound rect of gradient-filled polygon - const ::Rectangle aPolygonDeviceRectOrig( - rPoly.GetBoundRect() ); - - // determine size of gradient in device coordinate system - // (to e.g. determine sensible number of gradient steps) - ::basegfx::B2DPoint aLeftTop( 0.0, 0.0 ); - ::basegfx::B2DPoint aLeftBottom( 0.0, 1.0 ); - ::basegfx::B2DPoint aRightTop( 1.0, 0.0 ); - ::basegfx::B2DPoint aRightBottom( 1.0, 1.0 ); - - aLeftTop *= aTextureTransform; - aLeftBottom *= aTextureTransform; - aRightTop *= aTextureTransform; - aRightBottom*= aTextureTransform; - - // calc step size // -------------- - const int nColorSteps( - ::std::max( - labs( rColor1.GetRed() - rColor2.GetRed() ), - ::std::max( - labs( rColor1.GetGreen() - rColor2.GetGreen() ), - labs( rColor1.GetBlue() - rColor2.GetBlue() ) ) ) ); - - // longest line in gradient bound rect - const int nGradientSize( - static_cast<int>( - ::std::max( - ::basegfx::B2DVector(aRightBottom-aLeftTop).getLength(), - ::basegfx::B2DVector(aRightTop-aLeftBottom).getLength() ) + 1.0 ) ); - - // typical number for pixel of the same color (strip size) - const int nStripSize( nGradientSize < 50 ? 2 : 4 ); - - // use at least three steps, and at utmost the number of color - // steps - const int nStepCount( - ::std::max( - 3, - ::std::min( - nGradientSize / nStripSize, - nColorSteps ) ) ); + int nColorSteps = 0; + for( size_t i=0; i<rColors.size()-1; ++i ) + nColorSteps += numColorSteps(rColors[i],rColors[i+1]); + + ::basegfx::B2DHomMatrix aTotalTransform; + const int nStepCount= + ::canvas::tools::calcGradientStepCount(aTotalTransform, + viewState, + renderState, + texture, + nColorSteps); rOutDev.SetLineColor(); + // determine maximal bound rect of texture-filled + // polygon + const ::Rectangle aPolygonDeviceRectOrig( + rPoly.GetBoundRect() ); + if( tools::isRectangle( rPoly ) ) { // use optimized output path @@ -687,9 +596,8 @@ namespace vclcanvas rOutDev.IntersectClipRegion( aPolygonDeviceRectOrig ); doGradientFill( rOutDev, rValues, - rColor1, - rColor2, - aTextureTransform, + rColors, + aTotalTransform, aPolygonDeviceRectOrig, nStepCount, false ); @@ -701,9 +609,8 @@ namespace vclcanvas p2ndOutDev->IntersectClipRegion( aPolygonDeviceRectOrig ); doGradientFill( *p2ndOutDev, rValues, - rColor1, - rColor2, - aTextureTransform, + rColors, + aTotalTransform, aPolygonDeviceRectOrig, nStepCount, false ); @@ -720,9 +627,8 @@ namespace vclcanvas doGradientFill( rOutDev, rValues, - rColor1, - rColor2, - aTextureTransform, + rColors, + aTotalTransform, aPolygonDeviceRectOrig, nStepCount, false ); @@ -734,9 +640,8 @@ namespace vclcanvas p2ndOutDev->SetClipRegion( aPolyClipRegion ); doGradientFill( *p2ndOutDev, rValues, - rColor1, - rColor2, - aTextureTransform, + rColors, + aTotalTransform, aPolygonDeviceRectOrig, nStepCount, false ); @@ -750,9 +655,8 @@ namespace vclcanvas rOutDev.SetRasterOp( ROP_XOR ); doGradientFill( rOutDev, rValues, - rColor1, - rColor2, - aTextureTransform, + rColors, + aTotalTransform, aPolygonDeviceRectOrig, nStepCount, true ); @@ -762,9 +666,8 @@ namespace vclcanvas rOutDev.SetRasterOp( ROP_XOR ); doGradientFill( rOutDev, rValues, - rColor1, - rColor2, - aTextureTransform, + rColors, + aTotalTransform, aPolygonDeviceRectOrig, nStepCount, true ); @@ -776,9 +679,8 @@ namespace vclcanvas p2ndOutDev->SetRasterOp( ROP_XOR ); doGradientFill( *p2ndOutDev, rValues, - rColor1, - rColor2, - aTextureTransform, + rColors, + aTotalTransform, aPolygonDeviceRectOrig, nStepCount, true ); @@ -788,9 +690,8 @@ namespace vclcanvas p2ndOutDev->SetRasterOp( ROP_XOR ); doGradientFill( *p2ndOutDev, rValues, - rColor1, - rColor2, - aTextureTransform, + rColors, + aTotalTransform, aPolygonDeviceRectOrig, nStepCount, true ); @@ -852,33 +753,41 @@ namespace vclcanvas ::canvas::ParametricPolyPolygon* pGradient = dynamic_cast< ::canvas::ParametricPolyPolygon* >( textures[0].Gradient.get() ); - if( pGradient ) + if( pGradient && pGradient->getValues().maColors.getLength() ) { // copy state from Gradient polypoly locally // (given object might change!) const ::canvas::ParametricPolyPolygon::Values& rValues( pGradient->getValues() ); - // TODO: use all the colors and place them on given positions/stops - const ::Color aColor1( - ::vcl::unotools::stdColorSpaceSequenceToColor( - rValues.maColors [0] ) ); - const ::Color aColor2( - ::vcl::unotools::stdColorSpaceSequenceToColor( - rValues.maColors [rValues.maColors.getLength () - 1] ) ); - - // TODO(E1): Return value - // TODO(F1): FillRule - gradientFill( mpOutDev->getOutDev(), - mp2ndOutDev.get() ? &mp2ndOutDev->getOutDev() : (OutputDevice*)NULL, - rValues, - aColor1, - aColor2, - aPolyPoly, - viewState, - renderState, - textures[0], - nTransparency ); + if( rValues.maColors.getLength() < 2 ) + { + rendering::RenderState aTempState=renderState; + aTempState.DeviceColor = rValues.maColors[0]; + fillPolyPolygon(pCanvas, xPolyPolygon, viewState, aTempState); + } + else + { + std::vector< ::Color > aColors(rValues.maColors.getLength()); + std::transform(&rValues.maColors[0], + &rValues.maColors[0]+rValues.maColors.getLength(), + aColors.begin(), + boost::bind( + &vcl::unotools::stdColorSpaceSequenceToColor, + _1)); + + // TODO(E1): Return value + // TODO(F1): FillRule + gradientFill( mpOutDev->getOutDev(), + mp2ndOutDev.get() ? &mp2ndOutDev->getOutDev() : (OutputDevice*)NULL, + rValues, + aColors, + aPolyPoly, + viewState, + renderState, + textures[0], + nTransparency ); + } } else { @@ -889,10 +798,6 @@ namespace vclcanvas } else if( textures[0].Bitmap.is() ) { -// OSL_ENSURE( textures[0].RepeatModeX == rendering::TexturingMode::REPEAT && -// textures[0].RepeatModeY == rendering::TexturingMode::REPEAT, -// "CanvasHelper::fillTexturedPolyPolygon(): VCL canvas cannot currently clamp textures." ); - const geometry::IntegerSize2D aBmpSize( textures[0].Bitmap->getSize() ); ENSURE_ARG_OR_THROW( aBmpSize.Width != 0 && @@ -967,23 +872,6 @@ namespace vclcanvas aLocalState ); } } - else if ( textures[0].RepeatModeX == rendering::TexturingMode::CLAMP && - textures[0].RepeatModeY == rendering::TexturingMode::CLAMP ) - { - rendering::RenderState aLocalState( renderState ); - ::canvas::tools::appendToRenderState(aLocalState, - aTextureTransform); - ::basegfx::B2DHomMatrix aScaleCorrection; - aScaleCorrection.scale( 1.0/aBmpSize.Width, - 1.0/aBmpSize.Height ); - ::canvas::tools::appendToRenderState(aLocalState, - aScaleCorrection); - - return drawBitmap( pCanvas, - textures[0].Bitmap, - viewState, - aLocalState ); - } else { // No easy mapping to drawBitmap() - calculate @@ -1117,15 +1005,21 @@ namespace vclcanvas aSingleTextureRect, aPureTotalTransform ); - const ::Point aPt( ::vcl::unotools::pointFromB2DPoint( - aSingleDeviceTextureRect.getMinimum() ) ); + const ::Point aPtRepeat( ::vcl::unotools::pointFromB2DPoint( + aSingleDeviceTextureRect.getMinimum() ) ); const ::Size aSz( ::basegfx::fround( aScale.getX() * aBmpSize.Width ), ::basegfx::fround( aScale.getY() * aBmpSize.Height ) ); const ::Size aIntegerNextTileX( ::vcl::unotools::sizeFromB2DSize(aNextTileX) ); const ::Size aIntegerNextTileY( ::vcl::unotools::sizeFromB2DSize(aNextTileY) ); - const sal_Int32 nTilesX( nX2 - nX1 ); - const sal_Int32 nTilesY( nY2 - nY1 ); + const ::Point aPt( textures[0].RepeatModeX == rendering::TexturingMode::NONE ? + ::basegfx::fround( aOutputPos.getX() ) : aPtRepeat.X(), + textures[0].RepeatModeY == rendering::TexturingMode::NONE ? + ::basegfx::fround( aOutputPos.getY() ) : aPtRepeat.Y() ); + const sal_Int32 nTilesX( textures[0].RepeatModeX == rendering::TexturingMode::NONE ? + 1 : nX2 - nX1 ); + const sal_Int32 nTilesY( textures[0].RepeatModeX == rendering::TexturingMode::NONE ? + 1 : nY2 - nY1 ); OutputDevice& rOutDev( mpOutDev->getOutDev() ); @@ -1206,20 +1100,9 @@ namespace vclcanvas aPolyPoly.Translate( ::Point( -aPolygonDeviceRect.Left(), -aPolygonDeviceRect.Top() ) ); - aVDev.SetRasterOp( ROP_XOR ); - textureFill( aVDev, - *pGrfObj, - aOutPos, - aIntegerNextTileX, - aIntegerNextTileY, - nTilesX, - nTilesY, - aSz, - aGrfAttr ); - aVDev.SetFillColor( COL_BLACK ); - aVDev.SetRasterOp( ROP_0 ); - aVDev.DrawPolyPolygon( aPolyPoly ); - aVDev.SetRasterOp( ROP_XOR ); + const Region aPolyClipRegion( aPolyPoly ); + + aVDev.SetClipRegion( aPolyClipRegion ); textureFill( aVDev, *pGrfObj, aOutPos, @@ -1251,7 +1134,6 @@ namespace vclcanvas aOutputBmpEx ); } else -#if defined(QUARTZ) // TODO: other ports should avoid the XOR-trick too (implementation vs. interface!) { const Region aPolyClipRegion( aPolyPoly ); @@ -1287,66 +1169,6 @@ namespace vclcanvas r2ndOutDev.Pop(); } } -#else // TODO: remove once doing the XOR-trick in the canvas-layer becomes redundant - { - // output via repeated XORing - rOutDev.Push( PUSH_RASTEROP ); - rOutDev.SetRasterOp( ROP_XOR ); - textureFill( rOutDev, - *pGrfObj, - aPt, - aIntegerNextTileX, - aIntegerNextTileY, - nTilesX, - nTilesY, - aSz, - aGrfAttr ); - rOutDev.SetFillColor( COL_BLACK ); - rOutDev.SetRasterOp( ROP_0 ); - rOutDev.DrawPolyPolygon( aPolyPoly ); - rOutDev.SetRasterOp( ROP_XOR ); - textureFill( rOutDev, - *pGrfObj, - aPt, - aIntegerNextTileX, - aIntegerNextTileY, - nTilesX, - nTilesY, - aSz, - aGrfAttr ); - rOutDev.Pop(); - - if( mp2ndOutDev ) - { - OutputDevice& r2ndOutDev( mp2ndOutDev->getOutDev() ); - r2ndOutDev.Push( PUSH_RASTEROP ); - r2ndOutDev.SetRasterOp( ROP_XOR ); - textureFill( r2ndOutDev, - *pGrfObj, - aPt, - aIntegerNextTileX, - aIntegerNextTileY, - nTilesX, - nTilesY, - aSz, - aGrfAttr ); - r2ndOutDev.SetFillColor( COL_BLACK ); - r2ndOutDev.SetRasterOp( ROP_0 ); - r2ndOutDev.DrawPolyPolygon( aPolyPoly ); - r2ndOutDev.SetRasterOp( ROP_XOR ); - textureFill( r2ndOutDev, - *pGrfObj, - aPt, - aIntegerNextTileX, - aIntegerNextTileY, - nTilesX, - nTilesY, - aSz, - aGrfAttr ); - r2ndOutDev.Pop(); - } - } -#endif // complex-clipping vs. XOR-trick } } } diff --git a/canvas/source/vcl/exports.map b/canvas/source/vcl/exports.map deleted file mode 100644 index 4101b0d761a9..000000000000 --- a/canvas/source/vcl/exports.map +++ /dev/null @@ -1,8 +0,0 @@ -CAN_1_0 { - global: - component_getImplementationEnvironment; - component_writeInfo; - component_getFactory; - local: - *; -}; diff --git a/canvas/source/vcl/makefile.mk b/canvas/source/vcl/makefile.mk index 21eed478123a..be2fc69894a4 100644 --- a/canvas/source/vcl/makefile.mk +++ b/canvas/source/vcl/makefile.mk @@ -75,7 +75,7 @@ SHL1IMPLIB=i$(TARGET) SHL1LIBS=$(SLB)$/$(TARGET).lib SHL1DEF=$(MISC)$/$(SHL1TARGET).def -SHL1VERSIONMAP=exports.map +SHL1VERSIONMAP=$(SOLARENV)/src/component.map DEF1NAME=$(SHL1TARGET) DEF1EXPORTFILE=exports.dxp diff --git a/canvas/source/vcl/spritecanvas.hxx b/canvas/source/vcl/spritecanvas.hxx index a5d4a6fe1e10..db4b05ddb9b2 100644 --- a/canvas/source/vcl/spritecanvas.hxx +++ b/canvas/source/vcl/spritecanvas.hxx @@ -39,7 +39,6 @@ #include <com/sun/star/rendering/XIntegerBitmap.hpp> #include <com/sun/star/rendering/XGraphicDevice.hpp> #include <com/sun/star/rendering/XBufferController.hpp> -#include <com/sun/star/rendering/XParametricPolyPolygon2DFactory.hpp> #include <cppuhelper/compbase9.hxx> #include <comphelper/uno3.hxx> @@ -62,7 +61,7 @@ namespace vclcanvas typedef ::cppu::WeakComponentImplHelper9< ::com::sun::star::rendering::XSpriteCanvas, ::com::sun::star::rendering::XIntegerBitmap, ::com::sun::star::rendering::XGraphicDevice, - ::com::sun::star::rendering::XParametricPolyPolygon2DFactory, + ::com::sun::star::lang::XMultiServiceFactory, ::com::sun::star::rendering::XBufferController, ::com::sun::star::awt::XWindowListener, ::com::sun::star::util::XUpdatable, diff --git a/comphelper/qa/makefile.mk b/comphelper/qa/makefile.mk index 6e715675bb03..0360d308529e 100644 --- a/comphelper/qa/makefile.mk +++ b/comphelper/qa/makefile.mk @@ -33,6 +33,8 @@ ENABLE_EXCEPTIONS := TRUE .INCLUDE: settings.mk +CFLAGSCXX += $(CPPUNIT_CFLAGS) + DLLPRE = # no leading "lib" on .so files INCPRE += $(MISC)$/$(TARGET)$/inc diff --git a/cppcanvas/source/mtfrenderer/implrenderer.cxx b/cppcanvas/source/mtfrenderer/implrenderer.cxx index e6fb12cb2003..1423cd42ed93 100644 --- a/cppcanvas/source/mtfrenderer/implrenderer.cxx +++ b/cppcanvas/source/mtfrenderer/implrenderer.cxx @@ -41,7 +41,6 @@ #include <cppcanvas/canvas.hxx> #include <com/sun/star/rendering/XGraphicDevice.hpp> #include <com/sun/star/rendering/TexturingMode.hpp> -#include <com/sun/star/rendering/XParametricPolyPolygon2DFactory.hpp> #include <com/sun/star/uno/Sequence.hxx> #include <com/sun/star/geometry/RealPoint2D.hpp> #include <com/sun/star/rendering/ViewState.hpp> @@ -52,6 +51,7 @@ #include <com/sun/star/rendering/PathCapType.hpp> #include <com/sun/star/rendering/PathJoinType.hpp> #include <basegfx/tools/canvastools.hxx> +#include <basegfx/tools/gradienttools.hxx> #include <basegfx/numeric/ftools.hxx> #include <basegfx/polygon/b2dpolypolygontools.hxx> #include <basegfx/polygon/b2dpolygontools.hxx> @@ -591,13 +591,12 @@ namespace cppcanvas // discernible difference should be visible. nSteps > 64 ) { - uno::Reference< rendering::XParametricPolyPolygon2DFactory > xFactory( + uno::Reference< lang::XMultiServiceFactory> xFactory( rParms.mrCanvas->getUNOCanvas()->getDevice()->getParametricPolyPolygonFactory() ); if( xFactory.is() ) { - ::basegfx::B2DHomMatrix aTextureTransformation; - rendering::Texture aTexture; + rendering::Texture aTexture; aTexture.RepeatModeX = rendering::TexturingMode::CLAMP; aTexture.RepeatModeY = rendering::TexturingMode::CLAMP; @@ -632,240 +631,118 @@ namespace cppcanvas uno::Sequence< uno::Sequence < double > > aColors(2); uno::Sequence< double > aStops(2); - aStops[0] = 0.0; - aStops[1] = 1.0; + if( rGradient.GetStyle() == GRADIENT_AXIAL ) + { + aStops.realloc(3); + aColors.realloc(3); - aColors[0] = aStartColor; - aColors[1] = aEndColor; + aStops[0] = 0.0; + aStops[1] = 0.5; + aStops[2] = 1.0; + aColors[0] = aEndColor; + aColors[1] = aStartColor; + aColors[2] = aEndColor; + } + else + { + aStops[0] = 0.0; + aStops[1] = 1.0; - // Setup texture transformation - // ---------------------------- + aColors[0] = aStartColor; + aColors[1] = aEndColor; + } const ::basegfx::B2DRectangle aBounds( ::basegfx::tools::getRange(aDevicePoly) ); + const ::basegfx::B2DVector aOffset( + rGradient.GetOfsX() / 100.0, + rGradient.GetOfsY() / 100.0); + double fRotation( rGradient.GetAngle() * M_PI / 1800.0 ); + const double fBorder( rGradient.GetBorder() / 100.0 ); - // setup rotation angle. VCL rotates - // counter-clockwise, while canvas transformation - // rotates clockwise - double nRotation( -rGradient.GetAngle() * M_PI / 1800.0 ); + basegfx::B2DHomMatrix aRot90; + aRot90.rotate(M_PI_2); + basegfx::ODFGradientInfo aGradInfo; + rtl::OUString aGradientService; switch( rGradient.GetStyle() ) { case GRADIENT_LINEAR: - // FALLTHROUGH intended + basegfx::tools::createLinearODFGradientInfo(aGradInfo, + aBounds, + nSteps, + fBorder, + fRotation); + // map odf to svg gradient orientation - x + // instead of y direction + aGradInfo.maTextureTransform = aGradInfo.maTextureTransform * aRot90; + aGradientService = rtl::OUString::createFromAscii("LinearGradient"); + break; + case GRADIENT_AXIAL: { - // standard orientation for VCL linear - // gradient is vertical, thus, rotate 90 - // degrees - nRotation += M_PI/2.0; - - const double nBorder( - ::basegfx::pruneScaleValue( - (1.0 - rGradient.GetBorder() / 100.0) ) ); - - // shrink texture, to account for border - // (only in x direction, linear gradient - // is constant in y direction, anyway) - aTextureTransformation.scale( nBorder, - 1.0 ); - - // 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, axial gradients have - // border on both sides. As both gradients - // are invariant in y direction: leave y - // offset alone. - double nOffsetX( rGradient.GetBorder() / 200.0 ); - - // determine type of gradient (and necessary - // transformation matrix, should it be emulated by a - // generic gradient) - switch( rGradient.GetStyle() ) - { - case GRADIENT_LINEAR: - nOffsetX = rGradient.GetBorder() / 100.0; - aTexture.Gradient = xFactory->createLinearHorizontalGradient( aColors, - aStops ); - break; - - case GRADIENT_AXIAL: - // vcl considers center color as start color - ::std::swap(aColors[0],aColors[1]); - aTexture.Gradient = xFactory->createAxialHorizontalGradient( aColors, - aStops ); - break; - - default: // other cases can't happen - break; - } - - // apply border offset values - aTextureTransformation.translate( nOffsetX, - 0.0 ); - - // rotate texture according to gradient rotation - aTextureTransformation.translate( -0.5, -0.5 ); - aTextureTransformation.rotate( nRotation ); - - // 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(alpha) + x/2 cos(alpha) - // - // (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( aBounds.getHeight()*sin(nRotation) ) + - fabs( aBounds.getWidth()*cos(nRotation) ))); - - // scale and translate back origin to center of - // primitive - aTextureTransformation = basegfx::tools::createScaleTranslateB2DHomMatrix( - nScale, nScale, 0.5*aBounds.getWidth(), 0.5*aBounds.getHeight()) - * aTextureTransformation; + basegfx::tools::createLinearODFGradientInfo(aGradInfo, + aBounds, + nSteps, + fBorder, + fRotation); + // map odf to svg gradient orientation - x + // instead of y direction + aGradInfo.maTextureTransform = aGradInfo.maTextureTransform * aRot90; + + // map odf axial gradient to 3-stop linear + // gradient - shift left by 0.5 + basegfx::B2DHomMatrix aShift; + aShift.translate(-0.5,0); + aGradInfo.maTextureTransform = aGradInfo.maTextureTransform * aShift; + + aGradientService = rtl::OUString::createFromAscii("LinearGradient"); + break; } - break; case GRADIENT_RADIAL: - // FALLTHROUGH intended - case GRADIENT_ELLIPTICAL: - // FALLTHROUGH intended - case GRADIENT_SQUARE: - // FALLTHROUGH intended - case GRADIENT_RECT: - { - // 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( aBounds.getWidth() * (1.0 - rGradient.GetBorder() / 100.0) ); - double nScaleY( aBounds.getHeight()* (1.0 - rGradient.GetBorder() / 100.0) ); - - // determine offset values. Since the border is - // divided half-by-half to both sides of the - // gradient, divide translation offset by an - // additional 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( aBounds.getWidth() * - (2.0 * rGradient.GetOfsX() - 100.0 + rGradient.GetBorder()) / 200.0 ); - double nOffsetY( aBounds.getHeight() * - (2.0 * rGradient.GetOfsY() - 100.0 + rGradient.GetBorder()) / 200.0 ); - - // determine type of gradient (and necessary - // transformation matrix, should it be emulated by a - // generic gradient) - switch( rGradient.GetStyle() ) - { - case GRADIENT_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(aBounds.getWidth(), aBounds.getHeight()) / nScaleX ); - aTextureTransformation.scale( nScale, nScale ); - aTextureTransformation.translate( 0.5, 0.5 ); - - aTexture.Gradient = xFactory->createEllipticalGradient( aColors, - aStops, - geometry::RealRectangle2D(0.0,0.0, - 1.0,1.0) ); - } - break; - - case GRADIENT_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( - aColors, - aStops, - ::basegfx::unotools::rectangle2DFromB2DRectangle( - aBounds )); - } - break; - - case GRADIENT_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( aColors, - aStops, - geometry::RealRectangle2D(0.0,0.0, - 1.0,1.0) ); - break; - - case GRADIENT_RECT: - aTexture.Gradient = xFactory->createRectangularGradient( - aColors, - aStops, - ::basegfx::unotools::rectangle2DFromB2DRectangle( - aBounds ) ); - break; - - default: // other cases can't happen - break; - } - - nScaleX = ::basegfx::pruneScaleValue( nScaleX ); - nScaleY = ::basegfx::pruneScaleValue( nScaleY ); + basegfx::tools::createRadialODFGradientInfo(aGradInfo, + aBounds, + aOffset, + nSteps, + fBorder); + aGradientService = rtl::OUString::createFromAscii("EllipticalGradient"); + break; - aTextureTransformation.scale( nScaleX, nScaleY ); + case GRADIENT_ELLIPTICAL: + basegfx::tools::createEllipticalODFGradientInfo(aGradInfo, + aBounds, + aOffset, + nSteps, + fBorder, + fRotation); + aGradientService = rtl::OUString::createFromAscii("EllipticalGradient"); + break; - // rotate texture according to gradient rotation - aTextureTransformation = basegfx::tools::createRotateAroundPoint(0.5*nScaleX, 0.5*nScaleY, nRotation) - * aTextureTransformation; + case GRADIENT_SQUARE: + basegfx::tools::createSquareODFGradientInfo(aGradInfo, + aBounds, + aOffset, + nSteps, + fBorder, + fRotation); + aGradientService = rtl::OUString::createFromAscii("RectangularGradient"); + break; - aTextureTransformation.translate( nOffsetX, nOffsetY ); - } - break; + case GRADIENT_RECT: + basegfx::tools::createRectangularODFGradientInfo(aGradInfo, + aBounds, + aOffset, + nSteps, + fBorder, + fRotation); + aGradientService = rtl::OUString::createFromAscii("RectangularGradient"); + break; default: ENSURE_OR_THROW( false, - "ImplRenderer::createGradientAction(): Unexpected gradient type" ); + "ImplRenderer::createGradientAction(): Unexpected gradient type" ); break; } @@ -876,31 +753,49 @@ namespace cppcanvas // gradient will always display at the origin, and // not within the polygon bound (which might be // miles away from the origin). - aTextureTransformation.translate( aBounds.getMinX(), - aBounds.getMinY() ); - + aGradInfo.maTextureTransform.translate( aBounds.getMinX(), + aBounds.getMinY() ); ::basegfx::unotools::affineMatrixFromHomMatrix( aTexture.AffineTransform, - aTextureTransformation ); + aGradInfo.maTextureTransform ); + + uno::Sequence<uno::Any> args(3); + beans::PropertyValue aProp; + aProp.Name = rtl::OUString::createFromAscii("Colors"); + aProp.Value <<= aColors; + args[0] <<= aProp; + aProp.Name = rtl::OUString::createFromAscii("Stops"); + aProp.Value <<= aStops; + args[1] <<= aProp; + aProp.Name = rtl::OUString::createFromAscii("AspectRatio"); + aProp.Value <<= aGradInfo.mfAspectRatio; + args[2] <<= aProp; + + aTexture.Gradient.set( + xFactory->createInstanceWithArguments(aGradientService, + args), + uno::UNO_QUERY); + if( aTexture.Gradient.is() ) + { + ActionSharedPtr pPolyAction( + internal::PolyPolyActionFactory::createPolyPolyAction( + aDevicePoly, + rParms.mrCanvas, + getState( rParms.mrStates ), + aTexture ) ); - ActionSharedPtr pPolyAction( - internal::PolyPolyActionFactory::createPolyPolyAction( - aDevicePoly, - rParms.mrCanvas, - getState( rParms.mrStates ), - aTexture ) ); + if( pPolyAction ) + { + maActions.push_back( + MtfAction( + pPolyAction, + rParms.mrCurrActionIndex ) ); - if( pPolyAction ) - { - maActions.push_back( - MtfAction( - pPolyAction, - rParms.mrCurrActionIndex ) ); + rParms.mrCurrActionIndex += pPolyAction->getActionCount()-1; + } - rParms.mrCurrActionIndex += pPolyAction->getActionCount()-1; + // done, using native gradients + return; } - - // done, using native gradients - return; } } @@ -1880,8 +1775,8 @@ namespace cppcanvas } else { - aTexture.RepeatModeX = rendering::TexturingMode::CLAMP; - aTexture.RepeatModeY = rendering::TexturingMode::CLAMP; + aTexture.RepeatModeX = rendering::TexturingMode::NONE; + aTexture.RepeatModeY = rendering::TexturingMode::NONE; } ::PolyPolygon aPath; diff --git a/dtrans/source/generic/exports.map b/dtrans/source/generic/exports.map deleted file mode 100644 index 28449cc0f4a8..000000000000 --- a/dtrans/source/generic/exports.map +++ /dev/null @@ -1,9 +0,0 @@ -DTRANS_1_0 { - global: - component_getImplementationEnvironment; - component_writeInfo; - component_getFactory; - local: - *; -}; - diff --git a/dtrans/source/generic/makefile.mk b/dtrans/source/generic/makefile.mk index c1afa848d7ed..e015400c32d9 100644 --- a/dtrans/source/generic/makefile.mk +++ b/dtrans/source/generic/makefile.mk @@ -46,7 +46,7 @@ SLOFILES= \ SHL1TARGET= dtrans -SHL1VERSIONMAP= exports.map +SHL1VERSIONMAP=$(SOLARENV)/src/component.map SHL1STDLIBS= \ $(SALLIB) \ diff --git a/dtrans/util/exports.map b/dtrans/util/exports.map deleted file mode 100644 index 7c56baa9bd73..000000000000 --- a/dtrans/util/exports.map +++ /dev/null @@ -1,10 +0,0 @@ -UDK_3_0_0 { - global: - GetVersionInfo; - component_getImplementationEnvironment; - component_getFactory; - component_writeInfo; - - local: - *; -}; diff --git a/dtrans/util/makefile.mk b/dtrans/util/makefile.mk index 921f4458b43c..0443c131ccb6 100644 --- a/dtrans/util/makefile.mk +++ b/dtrans/util/makefile.mk @@ -64,7 +64,7 @@ SHL1IMPLIB=i$(SHL1TARGET) SHL1DEF= $(MISC)$/$(SHL1TARGET).def DEF1NAME= $(SHL1TARGET) DEF1EXPORTFILE= exports.dxp -SHL1VERSIONMAP=exports.map +SHL1VERSIONMAP=$(SOLARENV)/src/component.map .IF "$(GUI)"=="WNT" diff --git a/i18npool/source/breakiterator/data/dict.map b/i18npool/source/breakiterator/data/dict.map index 271ba8b2b83c..ebd4f9185d1f 100644 --- a/i18npool/source/breakiterator/data/dict.map +++ b/i18npool/source/breakiterator/data/dict.map @@ -1,4 +1,4 @@ -OOO_1.1 { +UDK_3_0_0 { global: GetVersionInfo; getDataArea; diff --git a/i18npool/source/breakiterator/data/dict_word.txt b/i18npool/source/breakiterator/data/dict_word.txt index 367a82db9e6f..f69f038e7f7e 100644 --- a/i18npool/source/breakiterator/data/dict_word.txt +++ b/i18npool/source/breakiterator/data/dict_word.txt @@ -35,7 +35,7 @@ $ALetter = [\u0002 [:Alphabetic:] [:name= COMMERCIAL AT:] [:name= HEBREW PUNCT $MidLetter = [[:name = APOSTROPHE:] [:name = GRAVE ACCENT:] \u0084 [:name = SOFT HYPHEN:] [:name = MIDDLE DOT:] [:name = GREEK TONOS:] [:name= FULL STOP:] [:name = HEBREW PUNCTUATION GERSHAYIM:] [:name = DOUBLE VERTICAL LINE:] [:name = LEFT SINGLE QUOTATION MARK:] [:name = RIGHT SINGLE QUOTATION MARK:] [:name = HYPHENATION POINT:] [:name = PRIME:] - [:name = HYPHEN-MINUS:] [:name = EN DASH:] [:name = EM DASH:] ]; + [:name = HYPHEN-MINUS:] ]; $SufixLetter = [:name= FULL STOP:]; diff --git a/i18npool/source/breakiterator/data/dict_word_prepostdash.txt b/i18npool/source/breakiterator/data/dict_word_prepostdash.txt index 1bf94451fae2..0a60cc5d4924 100644 --- a/i18npool/source/breakiterator/data/dict_word_prepostdash.txt +++ b/i18npool/source/breakiterator/data/dict_word_prepostdash.txt @@ -27,7 +27,7 @@ $Hangul = [:Script = HANGUL:]; # list of dashes or hyphens that should be accepted as part of the word if a single one of these # pre- or postfixes a word. E.g. in German: "Arbeits-" or "-nehmer" where that hyphen needs to # be part of the word in order to have it properly spell checked etc. -$PrePostDashHyphen = [ [:name = HYPHEN-MINUS:] [:name = EN DASH:] [:name = EM DASH:] ]; +$PrePostDashHyphen = [ [:name = HYPHEN-MINUS:] ]; $ALetter = [\u0002 [:Alphabetic:] [:name= COMMERCIAL AT:] [:name= HEBREW PUNCTUATION GERESH:] @@ -41,7 +41,7 @@ $ALetter = [\u0002 [:Alphabetic:] [:name= COMMERCIAL AT:] [:name= HEBREW PUNCT $MidLetter = [[:name = APOSTROPHE:] [:name = GRAVE ACCENT:] \u0084 [:name = SOFT HYPHEN:] [:name = MIDDLE DOT:] [:name = GREEK TONOS:] [:name= FULL STOP:] [:name = HEBREW PUNCTUATION GERSHAYIM:] [:name = DOUBLE VERTICAL LINE:] [:name = LEFT SINGLE QUOTATION MARK:] [:name = RIGHT SINGLE QUOTATION MARK:] [:name = HYPHENATION POINT:] [:name = PRIME:] - [:name = HYPHEN-MINUS:] [:name = EN DASH:] [:name = EM DASH:] ]; + [:name = HYPHEN-MINUS:] ]; $SufixLetter = [:name= FULL STOP:]; diff --git a/i18npool/source/collator/data/collator_data.map b/i18npool/source/collator/data/collator_data.map index 09f298912ee9..412635f19eed 100644 --- a/i18npool/source/collator/data/collator_data.map +++ b/i18npool/source/collator/data/collator_data.map @@ -1,4 +1,4 @@ -OOO_1.1 { +UDK_3_0_0 { global: GetVersionInfo; get_zh_charset; diff --git a/i18npool/source/indexentry/data/index_data.map b/i18npool/source/indexentry/data/index_data.map index b9add8b3a6f8..30d03853d6ad 100644 --- a/i18npool/source/indexentry/data/index_data.map +++ b/i18npool/source/indexentry/data/index_data.map @@ -1,4 +1,4 @@ -OOO_1.1 { +UDK_3_0_0 { global: GetVersionInfo; get_indexdata_ko_dict; diff --git a/i18npool/source/localedata/data/localedata_en.map b/i18npool/source/localedata/data/localedata_en.map index 10e5a998c932..ab13f033745c 100644 --- a/i18npool/source/localedata/data/localedata_en.map +++ b/i18npool/source/localedata/data/localedata_en.map @@ -1,4 +1,4 @@ -OOO_1.1 { +UDK_3_0_0 { global: GetVersionInfo; getAllCalendars_en_AU; diff --git a/i18npool/source/localedata/data/localedata_es.map b/i18npool/source/localedata/data/localedata_es.map index edcdd4e153e3..7743539232a6 100644 --- a/i18npool/source/localedata/data/localedata_es.map +++ b/i18npool/source/localedata/data/localedata_es.map @@ -1,4 +1,4 @@ -OOO_1.1 { +UDK_3_0_0 { global: GetVersionInfo; getAllCalendars_es_AR; diff --git a/i18npool/source/localedata/data/localedata_euro.map b/i18npool/source/localedata/data/localedata_euro.map index bc93cbfc5d89..130a3c5a249f 100644 --- a/i18npool/source/localedata/data/localedata_euro.map +++ b/i18npool/source/localedata/data/localedata_euro.map @@ -1,4 +1,4 @@ -OOO_1.1 { +UDK_3_0_0 { global: GetVersionInfo; getAllCalendars_ast_ES; diff --git a/i18npool/source/localedata/data/localedata_others.map b/i18npool/source/localedata/data/localedata_others.map index 6857e29ce5db..fd9e13cfb779 100644 --- a/i18npool/source/localedata/data/localedata_others.map +++ b/i18npool/source/localedata/data/localedata_others.map @@ -1,4 +1,4 @@ -OOO_1.1 { +UDK_3_0_0 { global: getAllCalendars_af_NA; getAllCalendars_af_ZA; diff --git a/i18npool/source/search/i18nsearch.map b/i18npool/source/search/i18nsearch.map deleted file mode 100644 index 02fe32ac5839..000000000000 --- a/i18npool/source/search/i18nsearch.map +++ /dev/null @@ -1,10 +0,0 @@ -UDK_3_0_0 { -global: - GetVersionInfo; - component_getImplementationEnvironment; - component_getFactory; - component_writeInfo; - -local: - *; -}; diff --git a/i18npool/source/search/makefile.mk b/i18npool/source/search/makefile.mk index 0a0d804c5c06..aed976edd896 100644 --- a/i18npool/source/search/makefile.mk +++ b/i18npool/source/search/makefile.mk @@ -68,7 +68,7 @@ SHL1STDLIBS= \ $(I18NREGEXPLIB) SHL1DEPN= makefile.mk -SHL1VERSIONMAP= i18nsearch.map +SHL1VERSIONMAP= $(SOLARENV)/src/component.map SHL1DEF= $(MISC)$/$(SHL1TARGET).def DEF1NAME= $(SHL1TARGET) diff --git a/i18npool/source/textconversion/data/textconv_dict.map b/i18npool/source/textconversion/data/textconv_dict.map index 03f9073c5d86..afd873b6f38e 100644 --- a/i18npool/source/textconversion/data/textconv_dict.map +++ b/i18npool/source/textconversion/data/textconv_dict.map @@ -1,4 +1,4 @@ -OOO_1.1 { +UDK_3_0_0 { global: GetVersionInfo; getHangul2HanjaData; diff --git a/i18npool/util/i18npool.map b/i18npool/util/i18npool.map deleted file mode 100644 index 02fe32ac5839..000000000000 --- a/i18npool/util/i18npool.map +++ /dev/null @@ -1,10 +0,0 @@ -UDK_3_0_0 { -global: - GetVersionInfo; - component_getImplementationEnvironment; - component_getFactory; - component_writeInfo; - -local: - *; -}; diff --git a/i18npool/util/makefile.mk b/i18npool/util/makefile.mk index 5bf520eaad4d..d9b87d19e6ca 100644 --- a/i18npool/util/makefile.mk +++ b/i18npool/util/makefile.mk @@ -60,7 +60,7 @@ SHL1IMPLIB= i$(SHL1TARGET) SHL1DEPN= makefile.mk \ $(SLB)/i18nisolang$(ISOLANG_MAJOR)$(COMID).lib -SHL1VERSIONMAP=$(PRJNAME).map +SHL1VERSIONMAP=$(SOLARENV)/src/component.map SHL1DEF=$(MISC)$/$(SHL1TARGET).def DEF1NAME=$(SHL1TARGET) diff --git a/l10ntools/inc/wrdtrans.hxx b/l10ntools/inc/wrdtrans.hxx deleted file mode 100644 index b0b65526a2a2..000000000000 --- a/l10ntools/inc/wrdtrans.hxx +++ /dev/null @@ -1,87 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ -/* - -// OBSOLETE // - -#ifndef TX3_WRDTRANS_HXX -#define TX3_WRDTRANS_HXX - -// USED - // Base Classes - // Components -class WordTransTree; -class WordTrans_ErrorList; - // Parameters -#include <tools/string.hxx> - -class WordTransformer -{ - public: - enum E_Error - { - OK = 0, - ERROR_NO_WORDLIST, - ERROR_HOTKEY, - ERROR_OUTPUTSTRING_TOO_LONG, - OTHER_ERROR - }; - - // LIFECYCLE - WordTransformer(); - ~WordTransformer(); - BOOL LoadWordlist( /// @return False, if file could not be read, or there is already a wordlist loaded. - const ByteString & i_sWordlist_Filepath, - CharSet i_nWorkingCharSet = RTL_TEXTENCODING_MS_1252, - CharSet i_nFileCharSet = RTL_TEXTENCODING_MS_1252 ); - - // OPERATIONS - USHORT Transform( /// @return The number of errors during transforming. - ByteString & io_sText); - - // INQUIRY - USHORT NrOfErrors() const; - E_Error GetError( - USHORT i_nNr, /// [0 .. NrOfErrors()-1], other values return an empty error. - ByteString * o_pErrorText = 0) const; /// If o_pErrorText != 0, the String is filled with the description of the error. - - private: - // SERVICE FUNCTION - void CreateError(); - - // DATA - WordTransTree * dpTransformer; - WordTrans_ErrorList * - dpErrors; -}; - - - -#endif - - -*/ diff --git a/l10ntools/java/receditor/java/transex3/model/SdfString.java b/l10ntools/java/receditor/java/transex3/model/SdfString.java index 7419aeb5578b..7eec2151b7c3 100644 --- a/l10ntools/java/receditor/java/transex3/model/SdfString.java +++ b/l10ntools/java/receditor/java/transex3/model/SdfString.java @@ -97,32 +97,7 @@ public class SdfString { public void setModuleName(String modulename) { this.modulename = modulename; } - /* - public String getRealFileName(){ - //String srcroot = "U:\\cws01\\l10ncleanup\\SRC680\\src.m213";//java.lang.System.getProperty( "SOLARSRC"); - //String isWindows = "4nt";//java.lang.System.getProperty( "USE_SHELL"); - String srcroot = java.lang.System.getProperty( "SOLARSRC" ); - String isWindows = java.lang.System.getProperty( "USE_SHELL" ); - //System.out.println("srcroot="+srcroot+" isWindows="+isWindows ); - //if( true ) return; - //String relpath = sourceString.getFileId().substring( sourceString.getFileId().lastIndexOf("\\") - // , sourceString.getFileId().length() ); - String filename; - if( isWindows != null && isWindows.compareTo( "4nt") == 0 ) - { - filename = srcroot + "\\" + //sourceString.getProject() + "\\" + - sourceString.getFileId() +".recommand"; - } - else - { - String filepart = sourceString.getFileId(); - filepart = filepart.replaceAll( "\\\\" , "/" ); - filename = srcroot + "/" + //sourceString.getProject() + "//" + - filepart +".recommand"; - } - return filename; - }*/ public String getRealFileName(){ String filepart = sourceString.getFileId(); filepart = filepart.replaceAll( "\\\\" , "_" ); diff --git a/l10ntools/scripts/fast_merge.pl b/l10ntools/scripts/fast_merge.pl index e2980fafddda..5dc63cf95d79 100644 --- a/l10ntools/scripts/fast_merge.pl +++ b/l10ntools/scripts/fast_merge.pl @@ -45,12 +45,8 @@ my $last_localize_file; my $first_run = "1"; my $sdf_filename; my $merge_dir; -my $WIN; my $state = "none"; -if ( defined $ENV{USE_SHELL} && $ENV{USE_SHELL} eq '4nt' ) { $WIN = 'TRUE'; } -else { $WIN = ''; } - $SIG{INT} = 'inthandler'; $SIG{QUIT} = 'quithandler'; @@ -67,7 +63,6 @@ struct ( sdf_obj => parse_options(); my $lock_file = $merge_dir."/lock.mk"; -$lock_file =~ s/\//\\/g , if ( $WIN ) ; acquire_lock(); read_sdf_file_names(); init(); @@ -247,10 +242,9 @@ sub make_paths { my $localizeFile = $merge_dir."\\".$current[ 0 ]->module."\\".$current[ 0 ]->file; my $path = getDir( $localizeFile ); - if ( !$WIN ) { $path =~ s/\\/\//g; } + $path =~ s/\\/\//g; - $localizeFile = $path."\\localize.sdf"; - if ( !$WIN ) { $localizeFile =~ s/\\/\//g; } + $localizeFile = $path."/localize.sdf"; return ( $path , $localizeFile ); } diff --git a/l10ntools/scripts/localize.pl b/l10ntools/scripts/localize.pl index 8b6a8231ebce..82ef331a63d5 100755 --- a/l10ntools/scripts/localize.pl +++ b/l10ntools/scripts/localize.pl @@ -70,14 +70,12 @@ my $no_gsicheck = ''; my $mode = ''; my $bVerbose = "0"; my $srcpath = ''; -my $WIN; my $languages; #my %sl_modules; # Contains all modules where en-US and de is source language my $use_default_date = '0'; my $force_ooo_module = '0'; my %is_ooo_module; my %is_so_module; -my $DELIMITER; # ( leftpart ) ( rightpart ) # prj file dummy type gid lid helpid pform width lang text helptext qhelptext title timestamp @@ -91,23 +89,14 @@ my @sdfparticles; parse_options(); check_modules_scm(); -if ( defined $ENV{USE_SHELL} && $ENV{USE_SHELL} eq '4nt' ) { - $WIN = 'TRUE'; - $DELIMITER = "\\"; -} - else { - $WIN = ''; - $DELIMITER = "/"; -} - my $binpath = ''; if( defined $ENV{UPDMINOREXT} ) { - $binpath = $ENV{SOLARVER}.$DELIMITER.$ENV{INPATH}.$DELIMITER."bin".$ENV{UPDMINOREXT}.$DELIMITER ; + $binpath = $ENV{SOLARVER}."/".$ENV{INPATH}."/bin".$ENV{UPDMINOREXT}."/" ; } else { - $binpath = $ENV{SOLARVER}.$DELIMITER.$ENV{INPATH}.$DELIMITER."bin".$DELIMITER ; + $binpath = $ENV{SOLARVER}."/".$ENV{INPATH}."/bin/" ; } #%sl_modules = fetch_sourcelanguage_dirlist(); @@ -187,9 +176,8 @@ sub splitfile{ exit( -1 ); } my $src_root = $ENV{SRC_ROOT}; - #print $WIN eq "TRUE" ? $src_root."\\l10n_so\n" : $src_root."/l10n_so\n"; - my $so_l10n_path = $WIN eq "TRUE" ? $src_root."\\l10n_so\\source" : $src_root."/l10n_so/source"; - my $ooo_l10n_path = $WIN eq "TRUE" ? $src_root."\\l10n\\source" : $src_root."/l10n/source"; + my $so_l10n_path = $src_root."/l10n_so/source"; + my $ooo_l10n_path = $src_root."/l10n/source"; #print "$so_l10n_path\n"; #print "$ooo_l10n_path\n"; @@ -286,7 +274,7 @@ sub write_sdf my @sdf_file; # mkdir!!!! - my $current_l10n_file = $WIN eq "TRUE" ? $l10n_file."\\$lang\\localize.sdf" : $l10n_file."/$lang/localize.sdf"; + my $current_l10n_file = $l10n_file."/$lang/localize.sdf"; print "Writing '$current_l10n_file'\n"; if( open DESTFILE , "< $current_l10n_file" ){ @@ -430,17 +418,17 @@ sub add_paths { my $langhash_ref = shift; my $root_dir = $ENV{ SRC_ROOT }; - my $ooo_l10n_dir = "$root_dir"."$DELIMITER"."l10n"."$DELIMITER"."source"; - my $so_l10n_dir = "$root_dir"."$DELIMITER"."l10n_so"."$DELIMITER"."source"; + my $ooo_l10n_dir = "$root_dir/l10n/source"; + my $so_l10n_dir = "$root_dir/l10n_so/source"; if( -e $ooo_l10n_dir ) { foreach my $lang ( keys( %{ $langhash_ref } ) ) { - my $loc_file = "$ooo_l10n_dir"."$DELIMITER"."$lang"."$DELIMITER"."localize.sdf"; + my $loc_file = "$ooo_l10n_dir/$lang/localize.sdf"; if( -e $loc_file ) { - push @sdfparticles , "$ooo_l10n_dir"."$DELIMITER"."$lang"."$DELIMITER"."localize.sdf"; + push @sdfparticles , "$ooo_l10n_dir/$lang/localize.sdf"; } else { print "WARNING: $loc_file not found ....\n"; } } @@ -450,10 +438,10 @@ sub add_paths { foreach my $lang ( keys( %{ $langhash_ref } ) ) { - my $loc_file = "$so_l10n_dir"."$DELIMITER"."$lang"."$DELIMITER"."localize.sdf"; + my $loc_file = "$so_l10n_dir/$lang/localize.sdf"; if( -e $loc_file ) { - push @sdfparticles , "$ooo_l10n_dir"."$DELIMITER"."$lang"."$DELIMITER"."localize.sdf"; + push @sdfparticles , "$ooo_l10n_dir/$lang/localize.sdf"; } else { #print "WARNING: $loc_file not found ....\n"; } @@ -530,10 +518,6 @@ sub collectfiles{ } #foreach } # if } # if -# if ( !$bVerbose ){ -# if ( $WIN eq "TRUE" ) { $args .= " > $my_localize_log"; } -# else { $args .= " >& $my_localize_log"; } -# } if ( $bVerbose ) { print STDOUT $command.$args."\n"; } my $rc = system( $command.$args ); diff --git a/l10ntools/scripts/localize_old.pl b/l10ntools/scripts/localize_old.pl index fe63ba9a93de..d6b66d6bb535 100755 --- a/l10ntools/scripts/localize_old.pl +++ b/l10ntools/scripts/localize_old.pl @@ -63,7 +63,6 @@ my $outputfile = ''; my $mode = ''; my $bVerbose="0"; my $srcpath = ''; -my $WIN; my $languages; #my %sl_modules; # Contains all modules where en-US and de is source language my $use_default_date = '0'; @@ -78,13 +77,6 @@ my $default_date = "2002-02-02 02:02:02"; #### main #### parse_options(); -if ( defined $ENV{USE_SHELL} && $ENV{USE_SHELL} eq '4nt' ) { - $WIN = 'TRUE'; -} - else { - $WIN = ''; -} - #%sl_modules = fetch_sourcelanguage_dirlist(); @@ -136,13 +128,11 @@ sub splitfile{ next if( $prj eq "binfilter" ); # Don't merge strings into binfilter module chomp( $line ); $currentFile = $srcpath . '\\' . $prj . '\\' . $file; - if ( $WIN ) { $currentFile =~ s/\//\\/g; } - else { $currentFile =~ s/\\/\//g; } + $currentFile =~ s/\\/\//g; $cur_sdffile = $currentFile; #if( $cur_sdffile =~ /\.$file_types[\s]*$/ ){ - if( $WIN ) { $cur_sdffile =~ s/\\[^\\]*\.$file_types[\s]*$/\\localize.sdf/; } - else { $cur_sdffile =~ s/\/[^\/]*\.$file_types[\s]*$/\/localize.sdf/; } + $cur_sdffile =~ s/\/[^\/]*\.$file_types[\s]*$/\/localize.sdf/; #} # Set default date @@ -182,41 +172,6 @@ sub splitfile{ } ######################################################### -#sub fetch_sourcelanguage_dirlist -#{ -# -# my $working_path = getcwd(); -# my %sl_dirlist; -# -# chdir $srcpath; -# my @all_dirs = csh_glob( "*" ); -# -# foreach my $file ( @all_dirs ) -# { -# if( -d $file ) -# { -# my $module = $file; -# $file .= "/prj/l10n"; -# $file =~ s/\//\\/ , if( $WIN ) ; -# -# if( -f $file ) # Test file <module>/prj/l10n -# { -# $sl_dirlist{ $module } = 1; -# if( $bVerbose eq "1" ) { print STDOUT "$module: de and en-US source language detected\n"; } -# } -# } -# } -# -# chdir $working_path; -# -# return %sl_dirlist; -#} - -#sub has_two_sourcelanguages -#{ -# my $module = shift; -# return defined $sl_modules{ $module } ; -#} sub writesdf{ my $lastFile = shift; @@ -225,8 +180,7 @@ sub writesdf{ my %index=(); if( $localizeFile =~ /\.$file_types[\s]*$/ ){ - if( $WIN ) { $localizeFile =~ s/\\[^\\]*\.$file_types[\s]*$/\\localize.sdf/; } - else { $localizeFile =~ s/\/[^\/]*\.$file_types[\s]*$/\/localize.sdf/; } + $localizeFile =~ s/\/[^\/]*\.$file_types[\s]*$/\/localize.sdf/; }else { print STDERR "Strange filetype found '$localizeFile'\n"; return; @@ -471,10 +425,6 @@ sub collectfiles{ } #foreach } # if } # if -# if ( !$bVerbose ){ -# if ( $WIN eq "TRUE" ) { $args .= " > $my_localize_log"; } -# else { $args .= " >& $my_localize_log"; } -# } if ( $bVerbose ) { print STDOUT $command.$args."\n"; } my $rc = system( $command.$args ); diff --git a/l10ntools/source/help/makefile.mk b/l10ntools/source/help/makefile.mk index 50351913fe55..b66077501a8d 100644 --- a/l10ntools/source/help/makefile.mk +++ b/l10ntools/source/help/makefile.mk @@ -101,7 +101,7 @@ JAVACLASSFILES = \ $(CLASSDIR)$/$(PACKAGE)$/HelpFileDocument.class .IF "$(SYSTEM_LUCENE)" == "YES" -CLASSPATH!:=$(CLASSPATH)$(PATH_SEPERATOR)$(LUCENE_CORE_JAR)$(PATH_SEPERATOR)$(LUCENE_ANALYZERS_JAR) +EXTRAJARFILES += $(LUCENE_CORE_JAR) $(LUCENE_ANALYZERS_JAR) .ELSE JARFILES += lucene-core-2.3.jar lucene-analyzers-2.3.jar .ENDIF diff --git a/l10ntools/source/wrdtrans.cxx b/l10ntools/source/wrdtrans.cxx deleted file mode 100644 index 10d6f472640f..000000000000 --- a/l10ntools/source/wrdtrans.cxx +++ /dev/null @@ -1,245 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -// MARKER(update_precomp.py): autogen include statement, do not remove -#include "precompiled_l10ntools.hxx" - -/* -#include "wrdtrans.hxx" - - -// NOT FULLY DECLARED SERVICES -#include <vector> -#include <vos/macros.hxx> - - -#include <tools/stream.hxx> -#include "wtratree.hxx" - -#include <tools/string.hxx> -*/ -//************** Declaration WordTrans_ErrorList ******************// -/* -typedef NAMESPACE_STD(vector)<ByteString> Stl_ByteStringList; - -class WordTrans_ErrorList -{ - public: - // OPERATIONS - void AddError( - WordTransformer::E_Error - i_eType, - const char * i_sErrorDescription ); - void Clear(); /// Empties the list. - - // INQUIRY - USHORT NrOfErrors() const; - WordTransformer::E_Error - GetError( - USHORT i_nNr, /// [0 .. NrOfErrors()-1], other values return an empty error. - ByteString * o_pErrorText ) const; /// If o_pErrorText != 0, the String is filled with the description of the error. - private: - // DATA - Stl_ByteStringList aErrors; -}; - -*/ - -//************** Implementation WordTransformer ******************// - -/* -WordTransformer::WordTransformer() - : dpTransformer(0), - dpErrors(new WordTrans_ErrorList) -{ -} - -WordTransformer::~WordTransformer() -{ - if (dpTransformer != 0) - delete dpTransformer; - delete dpErrors; -} - -BOOL -WordTransformer::LoadWordlist( const ByteString & i_sWordlist_Filepath, - CharSet i_nWorkingCharSet, - CharSet i_nFileCharSet ) -{ - if (dpTransformer != 0) - return FALSE; - - SvFileStream aFile(String(i_sWordlist_Filepath,RTL_TEXTENCODING_ASCII_US),STREAM_STD_READ); - if (! aFile.IsOpen()) - return FALSE; - aFile.SetStreamCharSet( i_nFileCharSet ) ; -// aFile.SetTargetCharSet( i_nWorkingCharSet ); - - dpTransformer = new WordTransTree; - - ByteString sTrans; - while ( aFile.ReadLine(sTrans) ) - { - dpTransformer->AddWordPair(sTrans.GetToken(0,';'),sTrans.GetToken(1,';')); - } - - aFile.Close(); - return TRUE; -} - -USHORT -WordTransformer::Transform(ByteString & io_sText) -{ - // Initialization and precondition testing: - dpErrors->Clear(); - if (dpTransformer == 0) - { - dpErrors->AddError(ERROR_NO_WORDLIST,"Error: No wordlist was loaded."); - return dpErrors->NrOfErrors(); - } - else if (io_sText.Len() > 63 * 1024) - { - dpErrors->AddError(ERROR_OUTPUTSTRING_TOO_LONG,"Error: Inputstring was too long (bigger than 63 KB)."); - return dpErrors->NrOfErrors(); - } - else if (io_sText.Len() == 0) - { - return 0; - } - - // Transform: - dpTransformer->InitTransformation( - io_sText.GetBuffer(), - io_sText.Len() ); - - for ( ; !dpTransformer->TextEndReached(); ) - { - if (dpTransformer->TransformNextToken() != WordTransTree::OK) - { - CreateError(); - } - } - io_sText = dpTransformer->Output(); - return dpErrors->NrOfErrors(); -} - -USHORT -WordTransformer::NrOfErrors() const -{ - return dpErrors->NrOfErrors(); -} - -WordTransformer::E_Error -WordTransformer::GetError( USHORT i_nNr, - ByteString * o_pErrorText) const -{ - return dpErrors->GetError(i_nNr,o_pErrorText); -} - -void -WordTransformer::CreateError() -{ - ByteString sErr; - - switch (dpTransformer->CurResult()) - { - case WordTransTree::OK: - break; - case WordTransTree::HOTKEY_LOST: - sErr = ByteString("Error: By replacement of string "); - sErr += dpTransformer->CurReplacedString(); - sErr += " by "; - sErr += dpTransformer->CurReplacingString(); - sErr += "the hotkey at char '"; - sErr += dpTransformer->CurHotkey(); - sErr += "' was lost."; - dpErrors->AddError( ERROR_HOTKEY,sErr.GetBufferAccess()); - sErr.ReleaseBufferAccess(); - break; - case WordTransTree::OUTPUT_OVERFLOW: - dpErrors->AddError(ERROR_OUTPUTSTRING_TOO_LONG,"Error: Output buffer overflow."); - break; - default: - dpErrors->AddError(OTHER_ERROR,"Error: Unknown error."); - } -} -*/ -//************** Implementation WordTrans_ErrorList ******************// -/* -void -WordTrans_ErrorList::AddError( WordTransformer::E_Error i_eType, - const char * i_sErrorDescription ) -{ - ByteString sErrorType = "xxx"; - char * pErrorChars = sErrorType.GetBufferAccess(); - pErrorChars[0] = char(i_eType / 100 + '0'); - pErrorChars[1] = char( (i_eType % 100) / 10 + '0'); - pErrorChars[2] = char(i_eType % 10 + '0'); - sErrorType += i_sErrorDescription; - - aErrors.push_back(sErrorType); - sErrorType.ReleaseBufferAccess(); -} - -void -WordTrans_ErrorList::Clear() -{ - aErrors.erase(aErrors.begin(),aErrors.end()); -} - -USHORT -WordTrans_ErrorList::NrOfErrors() const -{ - return aErrors.size(); -} - -WordTransformer::E_Error -WordTrans_ErrorList::GetError( USHORT i_nNr, - ByteString * o_pErrorText ) const -{ - if ( i_nNr < aErrors.size() ) - { - const ByteString & rError = aErrors[i_nNr]; - const char * pErrorChars = rError.GetBuffer(); - - USHORT nError = USHORT( (pErrorChars[0] - '0') ) * 100 - + (pErrorChars[1] - '0') * 10 - + pErrorChars[2] - '0'; - - if (o_pErrorText != 0) - *o_pErrorText = pErrorChars+3; - - return WordTransformer::E_Error(nError); - } - else - { - if (o_pErrorText != 0) - *o_pErrorText = ""; - return WordTransformer::OK; - } -} -*/ diff --git a/o3tl/inc/o3tl/vector_pool.hxx b/o3tl/inc/o3tl/vector_pool.hxx new file mode 100644 index 000000000000..19fc3d6d74c4 --- /dev/null +++ b/o3tl/inc/o3tl/vector_pool.hxx @@ -0,0 +1,132 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: lazy_update.hxx,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef INCLUDED_O3TL_VECTOR_POOL_HXX +#define INCLUDED_O3TL_VECTOR_POOL_HXX + +#include <sal/types.h> +#include <vector> + +namespace o3tl +{ + namespace detail + { + template<typename ValueType, class Container> class simple_pool_impl : + public Container + { + typedef typename Container::value_type value_type; + std::ptrdiff_t mnFirstFreeIndex; + + public: + simple_pool_impl() : + mnFirstFreeIndex(-1) + {} + + std::ptrdiff_t alloc() + { + return store(ValueType()); + } + + std::ptrdiff_t store(const ValueType& rCopy) + { + if( mnFirstFreeIndex != -1 ) + { + std::ptrdiff_t nIdx=mnFirstFreeIndex; + mnFirstFreeIndex = this->at(mnFirstFreeIndex).nextFree; + this->at(nIdx).value = rCopy; + this->at(nIdx).nextFree = -1; + + return nIdx; + } + else + { + push_back(value_type(rCopy)); + return this->size()-1; + } + } + + void free( std::ptrdiff_t nIdx ) + { + this->at(nIdx).nextFree = mnFirstFreeIndex; + mnFirstFreeIndex = nIdx; + } + + const ValueType& get( std::ptrdiff_t nIdx ) const + { + return this->operator[](nIdx).value; + } + ValueType& get( std::ptrdiff_t nIdx ) + { + return this->operator[](nIdx).value; + } + }; + + template< typename ValueType > struct struct_from_value + { + struct type + { + type() : + value(), + nextFree(-1) + {} + explicit type( const ValueType& val ) : + value(val), + nextFree(-1) + {} + + ValueType value; + std::ptrdiff_t nextFree; + }; + }; + } + + /** Simple vector-based memory pool allocator + + This template can be used to provide simple pooled memory + allocation from a container class that adheres to the stl + random access container concept. Note that alloc/free works + with _indices_ into the container! + + @example + <pre> +vector_pool<type> myPool; +int nIdx=myPool.alloc(); +myPool[nIdx] = myVal; + ... do stuff ... +myPool.free(nIdx); + </pre> + */ + template<typename ValueType> struct vector_pool : + public detail::simple_pool_impl<ValueType, + std::vector<typename detail::struct_from_value<ValueType>::type > > + {}; +} + +#endif /* INCLUDED_O3TL_VECTOR_POOL_HXX */ diff --git a/o3tl/prj/build.lst b/o3tl/prj/build.lst index 98293257e4bd..2606d1df8586 100644 --- a/o3tl/prj/build.lst +++ b/o3tl/prj/build.lst @@ -1,4 +1,4 @@ -ot o3tl : sal testshl2 BOOST:boost NULL +ot o3tl : sal CPPUNIT:cppunit BOOST:boost NULL ot o3tl usr1 - all ot_mkout NULL ot o3tl\inc get - all ot_inc NULL ot o3tl\prj get - all ot_prj NULL diff --git a/o3tl/qa/export.map b/o3tl/qa/export.map index 709047ae63e5..3308588ef6f8 100644 --- a/o3tl/qa/export.map +++ b/o3tl/qa/export.map @@ -25,9 +25,9 @@ # #************************************************************************* -UDK_3.1 { +UDK_3_0_0 { global: - registerAllTestFunction; + cppunitTestPlugIn; local: *; diff --git a/o3tl/qa/makefile.mk b/o3tl/qa/makefile.mk index 7effe534bbee..3475aeeca9bb 100644 --- a/o3tl/qa/makefile.mk +++ b/o3tl/qa/makefile.mk @@ -35,6 +35,9 @@ ENABLE_EXCEPTIONS=TRUE # --- Settings ----------------------------------------------------- .INCLUDE : settings.mk + +CFLAGSCXX += $(CPPUNIT_CFLAGS) + .IF "$(L10N_framework)"=="" # --- Common ---------------------------------------------------------- @@ -42,18 +45,19 @@ ENABLE_EXCEPTIONS=TRUE SHL1OBJS= \ $(SLO)$/cow_wrapper_clients.obj \ $(SLO)$/test-cow_wrapper.obj \ + $(SLO)$/test-vector_pool.obj \ $(SLO)$/test-heap_ptr.obj \ $(SLO)$/test-range.obj SHL1TARGET= tests SHL1STDLIBS= $(SALLIB) \ - $(TESTSHL2LIB)\ $(CPPUNITLIB) SHL1IMPLIB= i$(SHL1TARGET) DEF1NAME =$(SHL1TARGET) SHL1VERSIONMAP = export.map +SHL1RPATH = NONE # END ------------------------------------------------------------------ @@ -65,16 +69,9 @@ SLOFILES=$(SHL1OBJS) .ENDIF # L10N_framework .INCLUDE : target.mk -.INCLUDE : _cppunit.mk # --- Enable test execution in normal build ------------------------ .IF "$(L10N_framework)"=="" -unittest : $(SHL1TARGETN) - @echo ---------------------------------------------------------- - @echo - start unit test on library $(SHL1TARGETN) - @echo ---------------------------------------------------------- - $(TESTSHL2) -sf $(mktmp ) $(SHL1TARGETN) - -ALLTAR : unittest +.INCLUDE : _cppunit.mk .ENDIF # L10N_framework diff --git a/o3tl/qa/test-cow_wrapper.cxx b/o3tl/qa/test-cow_wrapper.cxx index eebbb633f82b..84d615fca3db 100644 --- a/o3tl/qa/test-cow_wrapper.cxx +++ b/o3tl/qa/test-cow_wrapper.cxx @@ -1,6 +1,9 @@ // autogenerated file with codegen.pl -#include <testshl/simpleheader.hxx> +#include "cppunit/TestAssert.h" +#include "cppunit/TestFixture.h" +#include "cppunit/extensions/HelperMacros.h" +#include "cppunit/plugin/TestPlugIn.h" #include "cow_wrapper_clients.hxx" @@ -119,15 +122,6 @@ public: }; // ----------------------------------------------------------------------------- -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(cow_wrapper_test, "cow_wrapper_test"); - - -// ----------------------------------------------------------------------------- - -// this macro creates an empty function, which will called by the RegisterAllFunctions() -// to let the user the possibility to also register some functions by hand. -void RegisterAdditionalFunctions(FktRegFuncPtr ) -{ -} -// NOADDITIONAL; +CPPUNIT_TEST_SUITE_REGISTRATION(cow_wrapper_test); +CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/o3tl/qa/test-heap_ptr.cxx b/o3tl/qa/test-heap_ptr.cxx index 44dc2083947a..fe2f78eec8af 100644 --- a/o3tl/qa/test-heap_ptr.cxx +++ b/o3tl/qa/test-heap_ptr.cxx @@ -25,7 +25,9 @@ * ************************************************************************/ -#include <testshl/simpleheader.hxx> +#include "cppunit/TestAssert.h" +#include "cppunit/TestFixture.h" +#include "cppunit/extensions/HelperMacros.h" #include <o3tl/heap_ptr.hxx> @@ -160,4 +162,4 @@ class heap_ptr_test : public CppUnit::TestFixture }; // class heap_ptr_test // ----------------------------------------------------------------------------- -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(heap_ptr_test, "o3tltests"); +CPPUNIT_TEST_SUITE_REGISTRATION(heap_ptr_test); diff --git a/o3tl/qa/test-range.cxx b/o3tl/qa/test-range.cxx index 9ead908675b9..31cf2aec7c10 100644 --- a/o3tl/qa/test-range.cxx +++ b/o3tl/qa/test-range.cxx @@ -25,8 +25,9 @@ * ************************************************************************/ - -#include <testshl/simpleheader.hxx> +#include "cppunit/TestAssert.h" +#include "cppunit/TestFixture.h" +#include "cppunit/extensions/HelperMacros.h" #include <o3tl/range.hxx> #include <vector> @@ -230,4 +231,4 @@ public: }; // class range_test // ----------------------------------------------------------------------------- -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(range_test, "o3tltests"); +CPPUNIT_TEST_SUITE_REGISTRATION(range_test); diff --git a/o3tl/qa/test-vector_pool.cxx b/o3tl/qa/test-vector_pool.cxx new file mode 100644 index 000000000000..4efaebdd3414 --- /dev/null +++ b/o3tl/qa/test-vector_pool.cxx @@ -0,0 +1,69 @@ +// autogenerated file with codegen.pl + +#include "cppunit/TestAssert.h" +#include "cppunit/TestFixture.h" +#include "cppunit/extensions/HelperMacros.h" + +#include <o3tl/vector_pool.hxx> + +using namespace ::o3tl; + +class vector_pool_test : public CppUnit::TestFixture +{ +public: + void testPoolBasics() + { + vector_pool<int> aPool; + + std::ptrdiff_t nIdx1 = aPool.alloc(); + std::ptrdiff_t nIdx2 = aPool.alloc(); + std::ptrdiff_t nIdx3 = aPool.alloc(); + + CPPUNIT_ASSERT_MESSAGE("allocator idx order 1", nIdx1 < nIdx2 ); + CPPUNIT_ASSERT_MESSAGE("allocator idx order 2", nIdx2 < nIdx3 ); + + aPool.free(nIdx2); + aPool.free(nIdx3); + + nIdx2 = aPool.alloc(); + nIdx3 = aPool.alloc(); + + CPPUNIT_ASSERT_MESSAGE("allocator idx order 1 after fragmentation", nIdx1 < nIdx3 ); + CPPUNIT_ASSERT_MESSAGE("allocator idx order 2 after fragmentation", nIdx3 < nIdx2 ); + } + + void testPoolValueSemantics() + { + vector_pool<int> aPool; + + std::ptrdiff_t nIdx1 = aPool.store(0); + CPPUNIT_ASSERT_MESSAGE("allocator value semantics 1", aPool.get(nIdx1) == 0 ); + + std::ptrdiff_t nIdx2 = aPool.store(1); + CPPUNIT_ASSERT_MESSAGE("allocator value semantics 2", aPool.get(nIdx2) == 1 ); + + std::ptrdiff_t nIdx3 = aPool.store(2); + CPPUNIT_ASSERT_MESSAGE("allocator value semantics 3", aPool.get(nIdx3) == 2 ); + + aPool.free(nIdx2); + aPool.free(nIdx3); + + nIdx2 = aPool.store(1); + CPPUNIT_ASSERT_MESSAGE("allocator value semantics 2 after fragmentation", aPool.get(nIdx2) == 1 ); + + nIdx3 = aPool.store(2); + CPPUNIT_ASSERT_MESSAGE("allocator value semantics 3 after fragmentation", aPool.get(nIdx3) == 2 ); + } + + // Change the following lines only, if you add, remove or rename + // member functions of the current class, + // because these macros are need by auto register mechanism. + + CPPUNIT_TEST_SUITE(vector_pool_test); + CPPUNIT_TEST(testPoolBasics); + CPPUNIT_TEST(testPoolValueSemantics); + CPPUNIT_TEST_SUITE_END(); +}; + +// ----------------------------------------------------------------------------- +CPPUNIT_TEST_SUITE_REGISTRATION(vector_pool_test); diff --git a/rsc/source/parser/erscerr.cxx b/rsc/source/parser/erscerr.cxx index 11aaf9cce85f..158aea21b6e3 100644 --- a/rsc/source/parser/erscerr.cxx +++ b/rsc/source/parser/erscerr.cxx @@ -200,7 +200,7 @@ void RscError::WriteError( const ERRTYPE& rError, const char * pMessage ) case ERR_NOINPUT: StdLstErr( "Input file was not specified.\n"); case ERR_USAGE: - StdLstOut( "Copyright (C) 1990-92 STAR DIVISION GmbH\n" ); + StdLstOut( "Copyright (C) 2000, 2010 Oracle and/or its affiliates.\n" ); { char buf[40]; diff --git a/rsc/source/prj/gui.cxx b/rsc/source/prj/gui.cxx index 0ff0549d161f..67d86a8b35cf 100644 --- a/rsc/source/prj/gui.cxx +++ b/rsc/source/prj/gui.cxx @@ -30,6 +30,7 @@ #include <stdlib.h> #include <stdio.h> +#include <sal/main.h> #include <rscrsc.hxx> #include <rscdb.hxx> @@ -68,15 +69,7 @@ RscVerbosity lcl_determineVerbosity( int argc, char ** argv ) return RscVerbosityNormal; } -#if defined( UNX ) || ( defined( OS2 ) && ( defined( CSET ) || defined ( GCC ))) || defined (WTC) || defined(ICC) || defined(__MINGW32__) -int main ( int argc, char ** argv) { -#else -#if defined( MTW ) -int main ( int argc, char const ** argv) { -#else -int cdecl main ( int argc, char ** argv) { -#endif -#endif +SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv) { #ifndef UNX #ifdef CSET atexit( ExitProgram ); diff --git a/rsc/source/prj/start.cxx b/rsc/source/prj/start.cxx index 8b952acb75f9..a2841dd9765b 100644 --- a/rsc/source/prj/start.cxx +++ b/rsc/source/prj/start.cxx @@ -54,6 +54,7 @@ #endif // UNX #include <rsctools.hxx> #include <rscerror.h> +#include <sal/main.h> #include <tools/fsys.hxx> /*************** C O D E ************************************************/ @@ -322,14 +323,8 @@ static BOOL CallRsc2( ByteString aRsc2Name, |* Letzte Aenderung MM 05.09.91 |* *************************************************************************/ -#if defined UNX || (defined OS2 && (defined CSET || defined GCC )) || defined WTC || defined MTW || defined ICC || defined(__MINGW32__) -int main ( int argc, char ** argv) +SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv) { -#else -int cdecl main ( int argc, char ** argv) -{ -#endif - BOOL bPrePro = TRUE; BOOL bResFile = TRUE; BOOL bHelp = FALSE; diff --git a/sax/source/fastparser/fastparser.cxx b/sax/source/fastparser/fastparser.cxx index 84941bee8e37..a43c7e52a353 100644 --- a/sax/source/fastparser/fastparser.cxx +++ b/sax/source/fastparser/fastparser.cxx @@ -31,6 +31,7 @@ #include <boost/scoped_ptr.hpp> #include <osl/diagnose.h> +#include <rtl/ustrbuf.hxx> #include <com/sun/star/lang/DisposedException.hpp> #include <com/sun/star/xml/sax/XFastContextHandler.hpp> @@ -41,8 +42,9 @@ #include <string.h> -using ::rtl::OUString; using ::rtl::OString; +using ::rtl::OUString; +using ::rtl::OUStringBuffer; using namespace ::std; using namespace ::osl; using namespace ::cppu; @@ -51,8 +53,8 @@ using namespace ::com::sun::star::lang; using namespace ::com::sun::star::xml::sax; //using namespace ::com::sun::star::util; using namespace ::com::sun::star::io; -namespace sax_fastparser -{ + +namespace sax_fastparser { // -------------------------------------------------------------------- @@ -111,30 +113,35 @@ private: // the implementation part //--------------------------------------------- -extern "C" +extern "C" { + +static void call_callbackStartElement(void *userData, const XML_Char *name , const XML_Char **atts) { - static void call_callbackStartElement(void *userData, const XML_Char *name , const XML_Char **atts) - { - FastSaxParser::callbackStartElement(userData,name,atts); - } - static void call_callbackEndElement(void *userData, const XML_Char *name) - { - FastSaxParser::callbackEndElement(userData,name); - } - static void call_callbackCharacters( void *userData , const XML_Char *s , int nLen ) - { - FastSaxParser::callbackCharacters(userData,s,nLen); - } - static int call_callbackExternalEntityRef(XML_Parser parser, - const XML_Char *openEntityNames, - const XML_Char *base, - const XML_Char *systemId, - const XML_Char *publicId) - { - return FastSaxParser::callbackExternalEntityRef(parser,openEntityNames,base,systemId,publicId); - } + FastSaxParser* pFastParser = reinterpret_cast< FastSaxParser* >( userData ); + pFastParser->callbackStartElement( name, atts ); +} + +static void call_callbackEndElement(void *userData, const XML_Char *name) +{ + FastSaxParser* pFastParser = reinterpret_cast< FastSaxParser* >( userData ); + pFastParser->callbackEndElement( name ); +} + +static void call_callbackCharacters( void *userData , const XML_Char *s , int nLen ) +{ + FastSaxParser* pFastParser = reinterpret_cast< FastSaxParser* >( userData ); + pFastParser->callbackCharacters( s, nLen ); } +static int call_callbackExternalEntityRef( XML_Parser parser, + const XML_Char *openEntityNames, const XML_Char *base, const XML_Char *systemId, const XML_Char *publicId ) +{ + FastSaxParser* pFastParser = reinterpret_cast< FastSaxParser* >( XML_GetUserData( parser ) ); + return pFastParser->callbackExternalEntityRef( parser, openEntityNames, base, systemId, publicId ); +} + +} // extern "C" + // -------------------------------------------------------------------- // FastLocatorImpl implementation // -------------------------------------------------------------------- @@ -172,15 +179,13 @@ OUString SAL_CALL FastLocatorImpl::getSystemId(void) throw (RuntimeException) // FastSaxParser implementation // -------------------------------------------------------------------- -FastSaxParser::FastSaxParser( ) +FastSaxParser::FastSaxParser() { mxDocumentLocator.set( new FastLocatorImpl( this ) ); // performance-Improvment. Reference is needed when calling the startTag callback. // Handing out the same object with every call is allowed (see sax-specification) mxAttributes.set( new FastAttributeList( mxTokenHandler ) ); - - mbExceptionWasThrown = sal_False; } // -------------------------------------------------------------------- @@ -419,34 +424,27 @@ void FastSaxParser::parseStream( const InputSource& maStructSource) throw (SAXEx struct Entity entity; entity.maStructSource = maStructSource; - if( ! entity.maStructSource.aInputStream.is() ) - { - throw SAXException( OUString::createFromAscii( "No input source" ), Reference< XInterface > () , Any() ); - } + if( !entity.maStructSource.aInputStream.is() ) + throw SAXException( OUString( RTL_CONSTASCII_USTRINGPARAM( "No input source" ) ), Reference< XInterface >(), Any() ); entity.maConverter.setInputStream( entity.maStructSource.aInputStream ); if( entity.maStructSource.sEncoding.getLength() ) - { - entity.maConverter.setEncoding( OUStringToOString( entity.maStructSource.sEncoding , RTL_TEXTENCODING_ASCII_US ) ); - } + entity.maConverter.setEncoding( OUStringToOString( entity.maStructSource.sEncoding, RTL_TEXTENCODING_ASCII_US ) ); // create parser with proper encoding entity.mpParser = XML_ParserCreate( 0 ); - if( ! entity.mpParser ) - { - throw SAXException( OUString::createFromAscii( "Couldn't create parser" ), Reference< XInterface > (), Any() ); - } + if( !entity.mpParser ) + throw SAXException( OUString( RTL_CONSTASCII_USTRINGPARAM( "Couldn't create parser" ) ), Reference< XInterface >(), Any() ); // set all necessary C-Callbacks - XML_SetUserData( entity.mpParser , this ); - XML_SetElementHandler( entity.mpParser , - call_callbackStartElement , - call_callbackEndElement ); - XML_SetCharacterDataHandler( entity.mpParser , call_callbackCharacters ); - XML_SetExternalEntityRefHandler( entity.mpParser, - call_callbackExternalEntityRef); + XML_SetUserData( entity.mpParser, this ); + XML_SetElementHandler( entity.mpParser, call_callbackStartElement, call_callbackEndElement ); + XML_SetCharacterDataHandler( entity.mpParser, call_callbackCharacters ); + XML_SetExternalEntityRefHandler( entity.mpParser, call_callbackExternalEntityRef ); + // maSavedException used to transport exceptions through C callbacks maSavedException.clear(); + pushEntity( entity ); try { @@ -569,112 +567,71 @@ Sequence< OUString > FastSaxParser::getSupportedServiceNames(void) throw (Runtim * Helper functions and classes * *-------------------------------------------*/ -OUString getErrorMessage( XML_Error xmlE, OUString sSystemId , sal_Int32 nLine ) -{ - OUString Message; - if( XML_ERROR_NONE == xmlE ) { - Message = OUString::createFromAscii( "No" ); - } - else if( XML_ERROR_NO_MEMORY == xmlE ) { - Message = OUString::createFromAscii( "no memory" ); - } - else if( XML_ERROR_SYNTAX == xmlE ) { - Message = OUString::createFromAscii( "syntax" ); - } - else if( XML_ERROR_NO_ELEMENTS == xmlE ) { - Message = OUString::createFromAscii( "no elements" ); - } - else if( XML_ERROR_INVALID_TOKEN == xmlE ) { - Message = OUString::createFromAscii( "invalid token" ); - } - else if( XML_ERROR_UNCLOSED_TOKEN == xmlE ) { - Message = OUString::createFromAscii( "unclosed token" ); - } - else if( XML_ERROR_PARTIAL_CHAR == xmlE ) { - Message = OUString::createFromAscii( "partial char" ); - } - else if( XML_ERROR_TAG_MISMATCH == xmlE ) { - Message = OUString::createFromAscii( "tag mismatch" ); - } - else if( XML_ERROR_DUPLICATE_ATTRIBUTE == xmlE ) { - Message = OUString::createFromAscii( "duplicate attribute" ); - } - else if( XML_ERROR_JUNK_AFTER_DOC_ELEMENT == xmlE ) { - Message = OUString::createFromAscii( "junk after doc element" ); - } - else if( XML_ERROR_PARAM_ENTITY_REF == xmlE ) { - Message = OUString::createFromAscii( "parameter entity reference" ); - } - else if( XML_ERROR_UNDEFINED_ENTITY == xmlE ) { - Message = OUString::createFromAscii( "undefined entity" ); - } - else if( XML_ERROR_RECURSIVE_ENTITY_REF == xmlE ) { - Message = OUString::createFromAscii( "recursive entity reference" ); - } - else if( XML_ERROR_ASYNC_ENTITY == xmlE ) { - Message = OUString::createFromAscii( "async entity" ); - } - else if( XML_ERROR_BAD_CHAR_REF == xmlE ) { - Message = OUString::createFromAscii( "bad char reference" ); - } - else if( XML_ERROR_BINARY_ENTITY_REF == xmlE ) { - Message = OUString::createFromAscii( "binary entity reference" ); - } - else if( XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF == xmlE ) { - Message = OUString::createFromAscii( "attribute external entity reference" ); - } - else if( XML_ERROR_MISPLACED_XML_PI == xmlE ) { - Message = OUString::createFromAscii( "misplaced xml processing instruction" ); - } - else if( XML_ERROR_UNKNOWN_ENCODING == xmlE ) { - Message = OUString::createFromAscii( "unknown encoding" ); - } - else if( XML_ERROR_INCORRECT_ENCODING == xmlE ) { - Message = OUString::createFromAscii( "incorrect encoding" ); - } - else if( XML_ERROR_UNCLOSED_CDATA_SECTION == xmlE ) { - Message = OUString::createFromAscii( "unclosed cdata section" ); - } - else if( XML_ERROR_EXTERNAL_ENTITY_HANDLING == xmlE ) { - Message = OUString::createFromAscii( "external entity reference" ); - } - else if( XML_ERROR_NOT_STANDALONE == xmlE ) { - Message = OUString::createFromAscii( "not standalone" ); - } - OUString str = OUString::createFromAscii( "[" ); - str += sSystemId; - str += OUString::createFromAscii( " line " ); - str += OUString::valueOf( nLine ); - str += OUString::createFromAscii( "]: " ); - str += Message; - str += OUString::createFromAscii( "error" ); +namespace { - return str; +OUString lclGetErrorMessage( XML_Error xmlE, const OUString& sSystemId, sal_Int32 nLine ) +{ + const sal_Char* pMessage = ""; + switch( xmlE ) + { + case XML_ERROR_NONE: pMessage = "No"; break; + case XML_ERROR_NO_MEMORY: pMessage = "no memory"; break; + case XML_ERROR_SYNTAX: pMessage = "syntax"; break; + case XML_ERROR_NO_ELEMENTS: pMessage = "no elements"; break; + case XML_ERROR_INVALID_TOKEN: pMessage = "invalid token"; break; + case XML_ERROR_UNCLOSED_TOKEN: pMessage = "unclosed token"; break; + case XML_ERROR_PARTIAL_CHAR: pMessage = "partial char"; break; + case XML_ERROR_TAG_MISMATCH: pMessage = "tag mismatch"; break; + case XML_ERROR_DUPLICATE_ATTRIBUTE: pMessage = "duplicate attribute"; break; + case XML_ERROR_JUNK_AFTER_DOC_ELEMENT: pMessage = "junk after doc element"; break; + case XML_ERROR_PARAM_ENTITY_REF: pMessage = "parameter entity reference"; break; + case XML_ERROR_UNDEFINED_ENTITY: pMessage = "undefined entity"; break; + case XML_ERROR_RECURSIVE_ENTITY_REF: pMessage = "recursive entity reference"; break; + case XML_ERROR_ASYNC_ENTITY: pMessage = "async entity"; break; + case XML_ERROR_BAD_CHAR_REF: pMessage = "bad char reference"; break; + case XML_ERROR_BINARY_ENTITY_REF: pMessage = "binary entity reference"; break; + case XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF: pMessage = "attribute external entity reference"; break; + case XML_ERROR_MISPLACED_XML_PI: pMessage = "misplaced xml processing instruction"; break; + case XML_ERROR_UNKNOWN_ENCODING: pMessage = "unknown encoding"; break; + case XML_ERROR_INCORRECT_ENCODING: pMessage = "incorrect encoding"; break; + case XML_ERROR_UNCLOSED_CDATA_SECTION: pMessage = "unclosed cdata section"; break; + case XML_ERROR_EXTERNAL_ENTITY_HANDLING: pMessage = "external entity reference"; break; + case XML_ERROR_NOT_STANDALONE: pMessage = "not standalone"; break; + default:; + } + + OUStringBuffer aBuffer( sal_Unicode( '[' ) ); + aBuffer.append( sSystemId ); + aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( " line " ) ); + aBuffer.append( nLine ); + aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( "]: " ) ); + aBuffer.appendAscii( pMessage ); + aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( " error" ) ); + return aBuffer.makeStringAndClear(); } +} // namespace // starts parsing with actual parser ! -void FastSaxParser::parse( ) +void FastSaxParser::parse() { - const int nBufSize = 16*1024; + const int BUFFER_SIZE = 16 * 1024; + Sequence< sal_Int8 > seqOut( BUFFER_SIZE ); - int nRead = nBufSize; - Sequence< sal_Int8 > seqOut(nBufSize); - - while( nRead ) + int nRead = 0; + do { - nRead = getEntity().maConverter.readAndConvert( seqOut, nBufSize ); - - if( ! nRead ) + nRead = getEntity().maConverter.readAndConvert( seqOut, BUFFER_SIZE ); + if( nRead <= 0 ) { - XML_Parse( getEntity().mpParser, ( const char * ) seqOut.getArray(), 0 , 1 ); + XML_Parse( getEntity().mpParser, (const char*) seqOut.getConstArray(), 0, 1 ); break; } - sal_Bool bContinue = ( XML_Parse( getEntity().mpParser, (const char *) seqOut.getArray(), nRead, 0 ) != 0 ); - - if( !bContinue || mbExceptionWasThrown ) + bool bContinue = XML_Parse( getEntity().mpParser, (const char*) seqOut.getConstArray(), nRead, 0 ) != 0; + // callbacks used inside XML_Parse may have caught an exception + if( !bContinue || maSavedException.hasValue() ) { // Error during parsing ! XML_Error xmlE = XML_GetErrorCode( getEntity().mpParser ); @@ -682,26 +639,25 @@ void FastSaxParser::parse( ) sal_Int32 nLine = mxDocumentLocator->getLineNumber(); SAXParseException aExcept( - getErrorMessage(xmlE , sSystemId, nLine) , + lclGetErrorMessage( xmlE, sSystemId, nLine ), Reference< XInterface >(), - Any( &maSavedException , getCppuType( &maSavedException) ), + Any( &maSavedException, getCppuType( &maSavedException ) ), mxDocumentLocator->getPublicId(), mxDocumentLocator->getSystemId(), mxDocumentLocator->getLineNumber(), mxDocumentLocator->getColumnNumber() - ); + ); + // error handler is set, it may throw the exception if( mxErrorHandler.is() ) - { - // error handler is set, so the handler may throw the maSavedException mxErrorHandler->fatalError( Any( aExcept ) ); - } - // Error handler has not thrown an maSavedException, but parsing cannot go on, - // so an maSavedException MUST be thrown. + // error handler has not thrown, but parsing cannot go on, the + // exception MUST be thrown throw aExcept; } } + while( nRead > 0 ); } //------------------------------------------ @@ -721,25 +677,23 @@ struct AttributeData } // namespace -void FastSaxParser::callbackStartElement( void *pvThis, const XML_Char *pwName, const XML_Char **awAttributes ) +void FastSaxParser::callbackStartElement( const XML_Char* pwName, const XML_Char** awAttributes ) { - FastSaxParser *pThis = (FastSaxParser*)pvThis; - Reference< XFastContextHandler > xParentContext; - if( !pThis->maContextStack.empty() ) + if( !maContextStack.empty() ) { - xParentContext = pThis->maContextStack.top()->mxContext; + xParentContext = maContextStack.top()->mxContext; if( !xParentContext.is() ) { // we ignore current elements, so no processing needed - pThis->pushContext(); + pushContext(); return; } } - pThis->pushContext(); + pushContext(); - pThis->mxAttributes->clear(); + mxAttributes->clear(); // create attribute map and process namespace instructions int i = 0; @@ -747,108 +701,100 @@ void FastSaxParser::callbackStartElement( void *pvThis, const XML_Char *pwName, const XML_Char *pName; const XML_Char *pPrefix; - /* #158414# Each element may define new namespaces, also for attribues. - First, process all namespace attributes and cache other attributes in a - vector. Second, process the attributes after namespaces have been - initialized. */ - ::std::vector< AttributeData > aAttribs; - - // #158414# first: get namespaces - for( ; awAttributes[i]; i += 2 ) + try { - OSL_ASSERT( awAttributes[i+1] ); + /* #158414# Each element may define new namespaces, also for attribues. + First, process all namespace attributes and cache other attributes in a + vector. Second, process the attributes after namespaces have been + initialized. */ + ::std::vector< AttributeData > aAttribs; - pThis->splitName( awAttributes[i], pPrefix, nPrefixLen, pName, nNameLen ); - if( nPrefixLen ) + // #158414# first: get namespaces + for( ; awAttributes[i]; i += 2 ) { - if( (nPrefixLen == 5) && (strncmp( pPrefix, "xmlns", 5 ) == 0) ) + OSL_ASSERT( awAttributes[i+1] ); + + splitName( awAttributes[i], pPrefix, nPrefixLen, pName, nNameLen ); + if( nPrefixLen ) { - pThis->DefineNamespace( OString( pName, nNameLen ), awAttributes[i+1] ); + if( (nPrefixLen == 5) && (strncmp( pPrefix, "xmlns", 5 ) == 0) ) + { + DefineNamespace( OString( pName, nNameLen ), awAttributes[i+1] ); + } + else + { + aAttribs.resize( aAttribs.size() + 1 ); + aAttribs.back().maPrefix = OString( pPrefix, nPrefixLen ); + aAttribs.back().maName = OString( pName, nNameLen ); + aAttribs.back().maValue = OString( awAttributes[i+1] ); + } } else { - aAttribs.resize( aAttribs.size() + 1 ); - aAttribs.back().maPrefix = OString( pPrefix, nPrefixLen ); - aAttribs.back().maName = OString( pName, nNameLen ); - aAttribs.back().maValue = OString( awAttributes[i+1] ); + if( (nNameLen == 5) && (strcmp( pName, "xmlns" ) == 0) ) + { + // namespace of the element found + maContextStack.top()->maNamespace = OUString( awAttributes[i+1], strlen( awAttributes[i+1] ), RTL_TEXTENCODING_UTF8 ); + } + else + { + aAttribs.resize( aAttribs.size() + 1 ); + aAttribs.back().maName = OString( pName, nNameLen ); + aAttribs.back().maValue = OString( awAttributes[i+1] ); + } } } - else + + // #158414# second: fill attribute list with other attributes + for( ::std::vector< AttributeData >::const_iterator aIt = aAttribs.begin(), aEnd = aAttribs.end(); aIt != aEnd; ++aIt ) { - if( (nNameLen == 5) && (strcmp( pName, "xmlns" ) == 0) ) + if( aIt->maPrefix.getLength() > 0 ) { - // namespace of the element found - pThis->maContextStack.top()->maNamespace = OUString( awAttributes[i+1], strlen( awAttributes[i+1] ), RTL_TEXTENCODING_UTF8 ); + sal_Int32 nAttributeToken = GetTokenWithPrefix( aIt->maPrefix, aIt->maName ); + if( nAttributeToken != FastToken::DONTKNOW ) + mxAttributes->add( nAttributeToken, aIt->maValue ); + else + mxAttributes->addUnknown( GetNamespaceURL( aIt->maPrefix ), aIt->maName, aIt->maValue ); } else { - aAttribs.resize( aAttribs.size() + 1 ); - aAttribs.back().maName = OString( pName, nNameLen ); - aAttribs.back().maValue = OString( awAttributes[i+1] ); + sal_Int32 nAttributeToken = GetToken( aIt->maName ); + if( nAttributeToken != FastToken::DONTKNOW ) + mxAttributes->add( nAttributeToken, aIt->maValue ); + else + mxAttributes->addUnknown( aIt->maName, aIt->maValue ); } } - } - // #158414# second: fill attribute list with other attributes - for( ::std::vector< AttributeData >::const_iterator aIt = aAttribs.begin(), aEnd = aAttribs.end(); aIt != aEnd; ++aIt ) - { - if( aIt->maPrefix.getLength() ) - { - const sal_Int32 nAttributeToken = pThis->GetTokenWithPrefix( aIt->maPrefix, aIt->maName ); - if( nAttributeToken != FastToken::DONTKNOW ) - pThis->mxAttributes->add( nAttributeToken, aIt->maValue ); - else - pThis->mxAttributes->addUnknown( pThis->GetNamespaceURL( aIt->maPrefix ), aIt->maName, aIt->maValue ); - } + sal_Int32 nElementToken; + splitName( pwName, pPrefix, nPrefixLen, pName, nNameLen ); + if( nPrefixLen > 0 ) + nElementToken = GetTokenWithPrefix( pPrefix, nPrefixLen, pName, nNameLen ); + else if( maContextStack.top()->maNamespace.getLength() > 0 ) + nElementToken = GetTokenWithNamespaceURL( maContextStack.top()->maNamespace, pName, nNameLen ); else - { - const sal_Int32 nAttributeToken = pThis->GetToken( aIt->maName ); - if( nAttributeToken != FastToken::DONTKNOW ) - pThis->mxAttributes->add( nAttributeToken, aIt->maValue ); - else - pThis->mxAttributes->addUnknown( aIt->maName, aIt->maValue ); - } - } + nElementToken = GetToken( pName ); + maContextStack.top()->mnElementToken = nElementToken; - sal_Int32 nElementToken; - pThis->splitName( pwName, pPrefix, nPrefixLen, pName, nNameLen ); - if( nPrefixLen ) - { - nElementToken = pThis->GetTokenWithPrefix( pPrefix, nPrefixLen, pName, nNameLen ); - } - else if( pThis->maContextStack.top()->maNamespace.getLength() ) - { - nElementToken = pThis->GetTokenWithNamespaceURL( pThis->maContextStack.top()->maNamespace, pName, nNameLen ); - } - else - { - nElementToken = pThis->GetToken( pName ); - } - pThis->maContextStack.top()->mnElementToken = nElementToken; - - try - { - Reference< XFastAttributeList > xAttr( pThis->mxAttributes.get() ); + Reference< XFastAttributeList > xAttr( mxAttributes.get() ); Reference< XFastContextHandler > xContext; if( nElementToken == FastToken::DONTKNOW ) { - if( nPrefixLen ) - { - pThis->maContextStack.top()->maNamespace = pThis->GetNamespaceURL( pPrefix, nPrefixLen ); - } + if( nPrefixLen > 0 ) + maContextStack.top()->maNamespace = GetNamespaceURL( pPrefix, nPrefixLen ); - const OUString aNamespace( pThis->maContextStack.top()->maNamespace ); + const OUString aNamespace( maContextStack.top()->maNamespace ); const OUString aElementName( pPrefix, nPrefixLen, RTL_TEXTENCODING_UTF8 ); - pThis->maContextStack.top()->maElementName = aElementName; + maContextStack.top()->maElementName = aElementName; if( xParentContext.is() ) xContext = xParentContext->createUnknownChildContext( aNamespace, aElementName, xAttr ); else - xContext = pThis->mxDocumentHandler->createUnknownChildContext( aNamespace, aElementName, xAttr ); + xContext = mxDocumentHandler->createUnknownChildContext( aNamespace, aElementName, xAttr ); if( xContext.is() ) { - pThis->maContextStack.top()->mxContext = xContext; + maContextStack.top()->mxContext = xContext; xContext->startUnknownElement( aNamespace, aElementName, xAttr ); } } @@ -857,142 +803,125 @@ void FastSaxParser::callbackStartElement( void *pvThis, const XML_Char *pwName, if( xParentContext.is() ) xContext = xParentContext->createFastChildContext( nElementToken, xAttr ); else - xContext = pThis->mxDocumentHandler->createFastChildContext( nElementToken, xAttr ); + xContext = mxDocumentHandler->createFastChildContext( nElementToken, xAttr ); if( xContext.is() ) { - pThis->maContextStack.top()->mxContext = xContext; + maContextStack.top()->mxContext = xContext; xContext->startFastElement( nElementToken, xAttr ); } } } catch( Exception& e ) { - pThis->maSavedException <<= e; + maSavedException <<= e; } } -void FastSaxParser::callbackEndElement( void *pvThis , const XML_Char * ) +void FastSaxParser::callbackEndElement( const XML_Char* ) { - FastSaxParser *pThis = (FastSaxParser*)pvThis; - - if( !pThis->maContextStack.empty() ) + OSL_ENSURE( !maContextStack.empty(), "FastSaxParser::callbackEndElement - no context" ); + if( !maContextStack.empty() ) { - SaxContextImplPtr pContext( pThis->maContextStack.top() ); + SaxContextImplPtr pContext( maContextStack.top() ); const Reference< XFastContextHandler >& xContext( pContext->mxContext ); if( xContext.is() ) try { sal_Int32 nElementToken = pContext->mnElementToken; if( nElementToken != FastToken::DONTKNOW ) - { xContext->endFastElement( nElementToken ); - } else - { xContext->endUnknownElement( pContext->maNamespace, pContext->maElementName ); - } } catch( Exception& e ) { - pThis->maSavedException <<= e; + maSavedException <<= e; } - pThis->popContext(); - } - else - { - OSL_ENSURE( false, "no context on sax::FastSaxParser::callbackEndElement() ??? "); + popContext(); } } -void FastSaxParser::callbackCharacters( void *pvThis , const XML_Char *s , int nLen ) +void FastSaxParser::callbackCharacters( const XML_Char* s, int nLen ) { - FastSaxParser *pThis = (FastSaxParser*)pvThis; - - const Reference< XFastContextHandler >& xContext( pThis->maContextStack.top()->mxContext ); + const Reference< XFastContextHandler >& xContext( maContextStack.top()->mxContext ); if( xContext.is() ) try { xContext->characters( OUString( s, nLen, RTL_TEXTENCODING_UTF8 ) ); } catch( Exception& e ) { - pThis->maSavedException <<= e; + maSavedException <<= e; } } int FastSaxParser::callbackExternalEntityRef( XML_Parser parser, - const XML_Char *context, - const XML_Char * /*base*/, - const XML_Char *systemId, - const XML_Char *publicId) + const XML_Char *context, const XML_Char * /*base*/, const XML_Char *systemId, const XML_Char *publicId ) { bool bOK = true; InputSource source; - FastSaxParser *pImpl = ((FastSaxParser*)XML_GetUserData( parser )); struct Entity entity; - if( pImpl->mxEntityResolver.is() ) { - try - { - entity.maStructSource = pImpl->mxEntityResolver->resolveEntity( - OUString( publicId, strlen( publicId ), RTL_TEXTENCODING_UTF8 ) , - OUString( systemId, strlen( systemId ), RTL_TEXTENCODING_UTF8 ) ); - } - catch( SAXParseException & e ) - { - pImpl->maSavedException <<= e; - bOK = false; - } - catch( SAXException & e ) - { - pImpl->maSavedException <<= SAXParseException( - e.Message , e.Context , e.WrappedException , - pImpl->mxDocumentLocator->getPublicId(), - pImpl->mxDocumentLocator->getSystemId(), - pImpl->mxDocumentLocator->getLineNumber(), - pImpl->mxDocumentLocator->getColumnNumber() ); - bOK = false; - } + if( mxEntityResolver.is() ) try + { + entity.maStructSource = mxEntityResolver->resolveEntity( + OUString( publicId, strlen( publicId ), RTL_TEXTENCODING_UTF8 ) , + OUString( systemId, strlen( systemId ), RTL_TEXTENCODING_UTF8 ) ); + } + catch( SAXParseException & e ) + { + maSavedException <<= e; + bOK = false; + } + catch( SAXException & e ) + { + maSavedException <<= SAXParseException( + e.Message, e.Context, e.WrappedException, + mxDocumentLocator->getPublicId(), + mxDocumentLocator->getSystemId(), + mxDocumentLocator->getLineNumber(), + mxDocumentLocator->getColumnNumber() ); + bOK = false; } if( entity.maStructSource.aInputStream.is() ) { - entity.mpParser = XML_ExternalEntityParserCreate( parser , context, 0 ); + entity.mpParser = XML_ExternalEntityParserCreate( parser, context, 0 ); if( ! entity.mpParser ) { return false; } entity.maConverter.setInputStream( entity.maStructSource.aInputStream ); - pImpl->pushEntity( entity ); + pushEntity( entity ); try { - pImpl->parse(); + parse(); } catch( SAXParseException & e ) { - pImpl->maSavedException <<= e; + maSavedException <<= e; bOK = false; } catch( IOException &e ) { SAXException aEx; aEx.WrappedException <<= e; - pImpl->maSavedException <<= aEx; + maSavedException <<= aEx; bOK = false; } catch( RuntimeException &e ) { SAXException aEx; aEx.WrappedException <<= e; - pImpl->maSavedException <<= aEx; + maSavedException <<= aEx; bOK = false; } - pImpl->popEntity(); + popEntity(); XML_ParserFree( entity.mpParser ); } @@ -1000,4 +929,4 @@ int FastSaxParser::callbackExternalEntityRef( XML_Parser parser, return bOK; } -} +} // namespace sax_fastparser diff --git a/sax/source/fastparser/fastparser.hxx b/sax/source/fastparser/fastparser.hxx index 236db124c99e..3d494a6d3c81 100644 --- a/sax/source/fastparser/fastparser.hxx +++ b/sax/source/fastparser/fastparser.hxx @@ -94,14 +94,12 @@ public: virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw (::com::sun::star::uno::RuntimeException); virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw (::com::sun::star::uno::RuntimeException); -public: - // the C-Callbacks for the expat parser - void static callbackStartElement(void *userData, const XML_Char *name , const XML_Char **atts); - void static callbackEndElement(void *userData, const XML_Char *name); - void static callbackCharacters( void *userData , const XML_Char *s , int nLen ); - int static callbackExternalEntityRef( XML_Parser parser, const XML_Char *openEntityNames, const XML_Char *base, const XML_Char *systemId, const XML_Char *publicId); + // called by the C callbacks of the expat parser + void callbackStartElement( const XML_Char* name, const XML_Char** atts ); + void callbackEndElement( const XML_Char* name ); + void callbackCharacters( const XML_Char* s, int nLen ); + int callbackExternalEntityRef( XML_Parser parser, const XML_Char *openEntityNames, const XML_Char *base, const XML_Char *systemId, const XML_Char *publicId); -public: void pushEntity( const struct Entity &entity ) { vecEntity.push_back( entity ); } void popEntity() { vecEntity.pop_back( ); } struct Entity &getEntity() { return vecEntity.back(); } @@ -139,10 +137,9 @@ private: // External entity stack std::vector< struct Entity > vecEntity; - // Exception cannot be thrown through the C-XmlParser (possible resource leaks), - // therefor the maSavedException must be saved somewhere. + // Exceptions cannot be thrown through the C-XmlParser (possible resource leaks), + // therefore the exception must be saved somewhere. ::com::sun::star::uno::Any maSavedException; - sal_Bool mbExceptionWasThrown; ::com::sun::star::lang::Locale maLocale; diff --git a/sot/source/sdstor/sdintern.hdb b/sot/source/sdstor/sdintern.hdb deleted file mode 100644 index 4dfbc69be013..000000000000 --- a/sot/source/sdstor/sdintern.hdb +++ /dev/null @@ -1,22 +0,0 @@ -write "/*************************************************************************" -write "* SDINTERN.HXX" -write "* __DATE__" -write "* (c) 1992-1995 STAR DIVISION" -write "*************************************************************************/" -write "#ifndef _SDINTERN_HXX" -write "#define _SDINTERN_HXX" -write "#ifndef _SOLAR_H" -write "#include <tools/solar.h>" -write "#endif" -write "#ifndef _STREAM_HXX" -write "#include <tools/stream.hxx>" -write "#endif" -file stg.hxx -file stgelem.hxx -file stgcache.hxx -file stgio.hxx -file stgstrms.hxx -file stgavl.hxx -file stgdir.hxx -write "#endif" - diff --git a/svl/qa/complex/ConfigItems/helper/exports.map b/svl/qa/complex/ConfigItems/helper/exports.map deleted file mode 100644 index 85610ad80888..000000000000 --- a/svl/qa/complex/ConfigItems/helper/exports.map +++ /dev/null @@ -1,10 +0,0 @@ -UDK_3_0_0 { - global: - GetVersionInfo; - component_getImplementationEnvironment; - component_getFactory; - component_writeInfo; - - local: - *; -}; diff --git a/svl/qa/complex/ConfigItems/helper/makefile.mk b/svl/qa/complex/ConfigItems/helper/makefile.mk index 2c949da7b168..13ea12106792 100644 --- a/svl/qa/complex/ConfigItems/helper/makefile.mk +++ b/svl/qa/complex/ConfigItems/helper/makefile.mk @@ -65,7 +65,7 @@ SHL1DEF= $(MISC)$/$(SHL1TARGET).def DEF1NAME= $(SHL1TARGET) -SHL1VERSIONMAP= exports.map +SHL1VERSIONMAP= $(SOLARENV)/src/component.map # --- Targets ------------------------------------------------------ diff --git a/svl/qa/makefile.mk b/svl/qa/makefile.mk index 4e107e31f924..7e8c7ee795cc 100644 --- a/svl/qa/makefile.mk +++ b/svl/qa/makefile.mk @@ -35,6 +35,8 @@ ENABLE_EXCEPTIONS = true .INCLUDE : settings.mk +CFLAGSCXX += $(CPPUNIT_CFLAGS) + # BEGIN ---------------------------------------------------------------- # auto generated Target:job by codegen.pl SHL1OBJS= \ diff --git a/svl/source/fsstor/exports.map b/svl/source/fsstor/exports.map deleted file mode 100644 index f4ed78b9e970..000000000000 --- a/svl/source/fsstor/exports.map +++ /dev/null @@ -1,8 +0,0 @@ -UDK_3_0_0 { - global: - component_getImplementationEnvironment; - component_writeInfo; - component_getFactory; - local: - *; -}; diff --git a/svl/source/fsstor/makefile.mk b/svl/source/fsstor/makefile.mk index 43515155d63d..dc91814772f9 100644 --- a/svl/source/fsstor/makefile.mk +++ b/svl/source/fsstor/makefile.mk @@ -56,7 +56,7 @@ SHL1STDLIBS=\ $(CPPULIB) \ $(SALLIB) -SHL1VERSIONMAP=exports.map +SHL1VERSIONMAP=$(SOLARENV)/src/component.map SHL1DEF= $(MISC)$/$(SHL1TARGET).def DEF1NAME= $(SHL1TARGET) diff --git a/svl/source/passwordcontainer/exports.map b/svl/source/passwordcontainer/exports.map deleted file mode 100644 index f4ed78b9e970..000000000000 --- a/svl/source/passwordcontainer/exports.map +++ /dev/null @@ -1,8 +0,0 @@ -UDK_3_0_0 { - global: - component_getImplementationEnvironment; - component_writeInfo; - component_getFactory; - local: - *; -}; diff --git a/svl/source/passwordcontainer/makefile.mk b/svl/source/passwordcontainer/makefile.mk index 92a9993fd251..d9eb9615cf80 100644 --- a/svl/source/passwordcontainer/makefile.mk +++ b/svl/source/passwordcontainer/makefile.mk @@ -52,7 +52,7 @@ SHL1STDLIBS=\ $(CPPULIB) \ $(SALLIB) -SHL1VERSIONMAP=exports.map +SHL1VERSIONMAP=$(SOLARENV)/src/component.map SHL1DEF= $(MISC)$/$(SHL1TARGET).def DEF1NAME= $(SHL1TARGET) diff --git a/svtools/inc/svtools/accessibletable.hxx b/svtools/inc/svtools/accessibletable.hxx index 457b63a0a488..198a24b8eb62 100755 --- a/svtools/inc/svtools/accessibletable.hxx +++ b/svtools/inc/svtools/accessibletable.hxx @@ -94,9 +94,8 @@ public: virtual ::rtl::OUString GetAccessibleObjectDescription(AccessibleTableControlObjType eObjType, sal_Int32 _nPosition = -1) const= 0; /** Fills the StateSet with all states (except DEFUNC and SHOWING, done by - the accessible object), depending on the specified object type. */ - virtual void FillAccessibleStateSet( - ::utl::AccessibleStateSetHelper& rStateSet, + the accessible object), depending on the specified object type. */ + virtual void FillAccessibleStateSet( ::utl::AccessibleStateSetHelper& rStateSet, AccessibleTableControlObjType eObjType ) const= 0; // Window @@ -122,8 +121,10 @@ public: virtual ::rtl::OUString GetRowName(sal_Int32 _nIndex) const = 0; virtual ::rtl::OUString GetColumnDescription( sal_uInt16 _nColumnPos ) const = 0; virtual ::rtl::OUString GetColumnName( sal_Int32 _nIndex ) const = 0; - virtual ::rtl::OUString GetCellContent( sal_Int32 _nRowPos, sal_Int32 _nColPos) const = 0; + virtual ::com::sun::star::uno::Any GetCellContent( sal_Int32 _nRowPos, sal_Int32 _nColPos) const = 0; virtual std::vector<sal_Int32>& GetSelectedRows() = 0; + virtual void RemoveSelectedRow(sal_Int32 _nRowPos) = 0; + virtual ::rtl::OUString GetAccessibleCellText(sal_Int32 _nRowPos, sal_Int32 _nColPos) = 0; }; // ---------------------------------------------------------------------------- diff --git a/svtools/inc/svtools/table/abstracttablecontrol.hxx b/svtools/inc/svtools/table/abstracttablecontrol.hxx index 8e92abc6c04c..2b3951f6aaf3 100644 --- a/svtools/inc/svtools/table/abstracttablecontrol.hxx +++ b/svtools/inc/svtools/table/abstracttablecontrol.hxx @@ -30,6 +30,7 @@ #include <sal/types.h> #include <vcl/event.hxx> #include <vcl/seleng.hxx> +#include "tabletypes.hxx" //........................................................................ namespace svt { namespace table { @@ -112,14 +113,15 @@ namespace svt { namespace table @see TableControlAction */ virtual bool dispatchAction( TableControlAction _eAction ) = 0; - /** to be called on mouse button up/down - @return - <TRUE/> if the click was in the visible area of the table control, - <FALSE/> otherwise.*/ - virtual bool isClickInVisibleArea( const Point& _rPoint ) = 0; - /** returns selection engine*/ - virtual SelectionEngine* getSelEngine() = 0; - virtual void setCursorAtCurrentCell(const Point& rPoint) = 0; + /** returns selection engine*/ + virtual SelectionEngine* getSelEngine() = 0; + virtual void setCursorAtCurrentCell(const Point& rPoint) = 0; + virtual rtl::OUString& setTooltip(const Point& rPoint ) = 0; + virtual RowPos getCurrentRow(const Point& rPoint ) = 0; + virtual void resizeColumn(const Point& rPoint ) = 0; + virtual bool startResizeColumn(const Point& rPoint) = 0; + virtual bool endResizeColumn(const Point& rPoint) = 0; + virtual bool isRowSelected(RowPos _nRow) = 0; virtual ~IAbstractTableControl() {}; }; diff --git a/svtools/inc/svtools/table/defaultinputhandler.hxx b/svtools/inc/svtools/table/defaultinputhandler.hxx index b9e2db31ca01..ca760896d539 100644 --- a/svtools/inc/svtools/table/defaultinputhandler.hxx +++ b/svtools/inc/svtools/table/defaultinputhandler.hxx @@ -44,6 +44,7 @@ namespace svt { namespace table friend class TableDataWindow; private: DefaultInputHandler_Impl* m_pImpl; + bool m_bResize; public: DefaultInputHandler(); diff --git a/svtools/inc/svtools/table/gridtablerenderer.hxx b/svtools/inc/svtools/table/gridtablerenderer.hxx index 13d44617d523..e474306c0423 100644 --- a/svtools/inc/svtools/table/gridtablerenderer.hxx +++ b/svtools/inc/svtools/table/gridtablerenderer.hxx @@ -90,10 +90,14 @@ namespace svt { namespace table bool _bActive, bool _bSelected, OutputDevice& _rDevice, const Rectangle& _rArea, const StyleSettings& _rStyle, rtl::OUString& _rText ); - virtual void PaintCell( ColPos _nColumn, + virtual void PaintCellImage( ColPos _nColumn, bool _bActive, bool _bSelected, OutputDevice& _rDevice, const Rectangle& _rArea, - const StyleSettings& _rStyle, rtl::OUString& _rText ); + const StyleSettings& _rStyle, Image* _pCellData ); + virtual void PaintCellString( ColPos _nColumn, + bool _bActive, bool _bSelected, + OutputDevice& _rDevice, const Rectangle& _rArea, + const StyleSettings& _rStyle, rtl::OUString& _rText ); virtual void ShowCellCursor( Window& _rView, const Rectangle& _rCursorRect); virtual void HideCellCursor( Window& _rView, const Rectangle& _rCursorRect); }; diff --git a/svtools/inc/svtools/table/tablecontrol.hxx b/svtools/inc/svtools/table/tablecontrol.hxx index cbe22da4a9d5..f08a1723c143 100644 --- a/svtools/inc/svtools/table/tablecontrol.hxx +++ b/svtools/inc/svtools/table/tablecontrol.hxx @@ -27,12 +27,14 @@ #ifndef SVTOOLS_INC_TABLE_TABLECONTROL_HXX #define SVTOOLS_INC_TABLE_TABLECONTROL_HXX +#include "svtools/svtdllapi.h" #include <svtools/table/tablemodel.hxx> #include <vcl/ctrl.hxx> #include <vcl/seleng.hxx> #include <svtools/table/tabledatawindow.hxx> #include <svtools/accessibletable.hxx> -#include "svtaccessiblefactory.hxx" +#include <com/sun/star/util/Color.hpp> +#include <svtools/accessiblefactory.hxx> //........................................................................ namespace svt { namespace table @@ -64,13 +66,19 @@ namespace svt { namespace table // TODO: scrolling? */ - class TableControl : public Control, public IAccessibleTable + class SVT_DLLPUBLIC TableControl : public Control, public IAccessibleTable { private: - DECL_LINK( ImplMouseButtonDownHdl, MouseEvent* ); - DECL_LINK( ImplMouseButtonUpHdl, MouseEvent* ); + DECL_DLLPRIVATE_LINK( ImplMouseButtonDownHdl, MouseEvent* ); + DECL_DLLPRIVATE_LINK( ImplMouseButtonUpHdl, MouseEvent* ); + + DECL_DLLPRIVATE_LINK( ImplSelectHdl, void* ); TableControl_Impl* m_pImpl; + ::com::sun::star::uno::Sequence< sal_Int32 > m_nCols; + ::com::sun::star::uno::Sequence< ::rtl::OUString > m_aText; + Link m_aSelectHdl; + bool m_bSelectionChanged; public: ::std::auto_ptr< AccessibleTableControl_Impl > m_pAccessTable; @@ -78,7 +86,7 @@ namespace svt { namespace table ~TableControl(); /// sets a new table model - void SetModel( PTableModel _pModel ); + SVT_DLLPRIVATE void SetModel( PTableModel _pModel ); /// retrieves the current table model PTableModel GetModel() const; @@ -148,66 +156,72 @@ namespace svt { namespace table { return GoTo( GetCurrentColumn(), _nRow ); } - virtual void Resize(); + SVT_DLLPRIVATE virtual void Resize(); + virtual void Select(); + SVT_DLLPRIVATE void SetSelectHdl( const Link& rLink ) { m_aSelectHdl = rLink; } + const Link& GetSelectHdl() const { return m_aSelectHdl; } - /**invalidates the table if table has been changed e.g. new row added - */ - void InvalidateDataWindow(RowPos _nRowStart, bool _bRemoved); - /**gets the vector, which contains the selected rows - */ - std::vector<sal_Int32>& GetSelectedRows(); - /**after removing a row, updates the vector which contains the selected rows - if the row, which should be removed, is selected, it will be erased from the vector - */ - void removeSelectedRow(RowPos _nRowPos); - SelectionEngine* getSelEngine(); - TableDataWindow* getDataWindow(); + /**invalidates the table if table has been changed e.g. new row added + */ + void InvalidateDataWindow(RowPos _nRowStart, RowPos _nRowEnd, bool _bRemoved); + /**gets the vector, which contains the selected rows + */ + std::vector<sal_Int32>& GetSelectedRows(); + /**after removing a row, updates the vector which contains the selected rows + if the row, which should be removed, is selected, it will be erased from the vector + */ + SelectionEngine* getSelEngine(); + TableDataWindow* getDataWindow(); // Window overridables virtual void GetFocus(); virtual void LoseFocus(); virtual void KeyInput( const KeyEvent& rKEvt ); - //virtual long Notify(NotifyEvent& rNEvt); - - /** Creates and returns the accessible object of the whole BrowseBox. */ - virtual XACC CreateAccessible(); - virtual XACC CreateAccessibleControl( sal_Int32 _nIndex ); - virtual ::rtl::OUString GetAccessibleObjectName(AccessibleTableControlObjType eObjType, sal_Int32 _nRow, sal_Int32 _nCol) const; - virtual sal_Bool GoToCell( sal_Int32 _nColumnPos, sal_Int32 _nRow ); - virtual ::rtl::OUString GetAccessibleObjectDescription(AccessibleTableControlObjType eObjType, sal_Int32 _nPosition = -1) const; - virtual void FillAccessibleStateSet( - ::utl::AccessibleStateSetHelper& rStateSet, - AccessibleTableControlObjType eObjType ) const; - - //// Window - virtual Rectangle GetWindowExtentsRelative( Window *pRelativeWindow ) const; - virtual void GrabFocus(); - virtual XACC GetAccessible( BOOL bCreate = TRUE ); - virtual Window* GetAccessibleParentWindow() const; - virtual Window* GetWindowInstance(); - virtual sal_Int32 GetAccessibleControlCount() const; - virtual sal_Bool ConvertPointToControlIndex( sal_Int32& _rnIndex, const Point& _rPoint ); - virtual long GetRowCount() const; - virtual long GetColumnCount() const; - virtual sal_Bool HasRowHeader() const; - virtual sal_Int32 GetSelectedRowCount() const; - virtual bool IsRowSelected( long _nRow ) const; - virtual sal_Bool ConvertPointToCellAddress( sal_Int32& _rnRow, sal_Int32& _rnColPos, const Point& _rPoint ); - virtual Rectangle calcHeaderRect( sal_Bool _bIsColumnBar, BOOL _bOnScreen = TRUE ); - virtual Rectangle calcTableRect( BOOL _bOnScreen = TRUE ); - virtual Rectangle GetFieldCharacterBounds(sal_Int32 _nRow,sal_Int32 _nColumnPos,sal_Int32 nIndex); - virtual sal_Int32 GetFieldIndexAtPoint(sal_Int32 _nRow,sal_Int32 _nColumnPos,const Point& _rPoint); - virtual void FillAccessibleStateSetForCell( ::utl::AccessibleStateSetHelper& _rStateSet, sal_Int32 _nRow, sal_uInt16 _nColumnPos ) const; - virtual ::rtl::OUString GetRowDescription( sal_Int32 _nRow ) const; - virtual ::rtl::OUString GetRowName(sal_Int32 _nIndex) const; - virtual ::rtl::OUString GetColumnDescription( sal_uInt16 _nColumnPos ) const; - virtual ::rtl::OUString GetColumnName( sal_Int32 _nIndex ) const; - virtual ::rtl::OUString GetCellContent( sal_Int32 _nRowPos, sal_Int32 _nColPos) const; - virtual sal_Bool HasRowHeader(); - virtual sal_Bool HasColHeader(); - virtual sal_Bool isAccessibleAlive( ) const; - virtual void commitGridControlEvent( sal_Int16 _nEventId, const com::sun::star::uno::Any& _rNewValue, const com::sun::star::uno::Any& _rOldValue ); - + //virtual long Notify(NotifyEvent& rNEvt); + + /** Creates and returns the accessible object of the whole GridControl. */ + SVT_DLLPRIVATE virtual XACC CreateAccessible(); + SVT_DLLPRIVATE virtual XACC CreateAccessibleControl( sal_Int32 _nIndex ); + SVT_DLLPRIVATE virtual ::rtl::OUString GetAccessibleObjectName(AccessibleTableControlObjType eObjType, sal_Int32 _nRow, sal_Int32 _nCol) const; + SVT_DLLPRIVATE virtual sal_Bool GoToCell( sal_Int32 _nColumnPos, sal_Int32 _nRow ); + SVT_DLLPRIVATE virtual ::rtl::OUString GetAccessibleObjectDescription(AccessibleTableControlObjType eObjType, sal_Int32 _nPosition = -1) const; + virtual void FillAccessibleStateSet( + ::utl::AccessibleStateSetHelper& rStateSet, + AccessibleTableControlObjType eObjType ) const; + //// Window + virtual Rectangle GetWindowExtentsRelative( Window *pRelativeWindow ) const; + virtual void GrabFocus(); + virtual XACC GetAccessible( BOOL bCreate = TRUE ); + virtual Window* GetAccessibleParentWindow() const; + virtual Window* GetWindowInstance(); + virtual sal_Int32 GetAccessibleControlCount() const; + virtual sal_Bool ConvertPointToControlIndex( sal_Int32& _rnIndex, const Point& _rPoint ); + virtual long GetRowCount() const; + virtual long GetColumnCount() const; + virtual sal_Bool HasRowHeader() const; + virtual sal_Int32 GetSelectedRowCount() const; + virtual bool IsRowSelected( long _nRow ) const; + virtual sal_Bool ConvertPointToCellAddress( sal_Int32& _rnRow, sal_Int32& _rnColPos, const Point& _rPoint ); + virtual Rectangle calcHeaderRect( sal_Bool _bIsColumnBar, BOOL _bOnScreen = TRUE ); + virtual Rectangle calcTableRect( BOOL _bOnScreen = TRUE ); + virtual Rectangle GetFieldCharacterBounds(sal_Int32 _nRow,sal_Int32 _nColumnPos,sal_Int32 nIndex); + virtual sal_Int32 GetFieldIndexAtPoint(sal_Int32 _nRow,sal_Int32 _nColumnPos,const Point& _rPoint); + virtual void FillAccessibleStateSetForCell( ::utl::AccessibleStateSetHelper& _rStateSet, sal_Int32 _nRow, sal_uInt16 _nColumnPos ) const; + virtual ::rtl::OUString GetRowDescription( sal_Int32 _nRow ) const; + virtual ::rtl::OUString GetRowName(sal_Int32 _nIndex) const; + virtual ::rtl::OUString GetColumnDescription( sal_uInt16 _nColumnPos ) const; + virtual ::rtl::OUString GetColumnName( sal_Int32 _nIndex ) const; + virtual ::com::sun::star::uno::Any GetCellContent( sal_Int32 _nRowPos, sal_Int32 _nColPos) const; + virtual sal_Bool HasRowHeader(); + virtual sal_Bool HasColHeader(); + virtual sal_Bool isAccessibleAlive( ) const; + virtual void commitGridControlEvent( sal_Int16 _nEventId, const com::sun::star::uno::Any& _rNewValue, const com::sun::star::uno::Any& _rOldValue ); + virtual void RemoveSelectedRow(RowPos _nRowPos); + virtual ::rtl::OUString GetAccessibleCellText(sal_Int32 _nRowPos, sal_Int32 _nColPos); + ::com::sun::star::uno::Sequence< sal_Int32 >& getColumnsForTooltip(); + ::com::sun::star::uno::Sequence< ::rtl::OUString >& getTextForTooltip(); + void setTooltip(const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aText, const ::com::sun::star::uno::Sequence< sal_Int32 >& nCols); + void selectionChanged(bool _bChanged); protected: /// retrieves the XAccessible implementation associated with the GridControl instance @@ -219,27 +233,6 @@ namespace svt { namespace table TableControl& operator=( const TableControl& ); // never implemented }; - class AccessibleTableControl_Impl - { - public: - AccessibleFactoryAccess m_aFactoryAccess; - IAccessibleTableControl* m_pAccessible; - - public: - AccessibleTableControl_Impl() : m_pAccessible(NULL) - { - } - - - /// @see AccessibleTableControl::getTableRowHeader - ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > - getAccessibleTableHeader( AccessibleTableControlObjType _eObjType ); - /// @see AccessibleTableControl::getTable - ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > - getAccessibleTable( ); - - }; - //........................................................................ } } // namespace svt::table //........................................................................ diff --git a/svtools/inc/svtools/table/tabledatawindow.hxx b/svtools/inc/svtools/table/tabledatawindow.hxx index d14a25289c99..c9f96483d943 100644 --- a/svtools/inc/svtools/table/tabledatawindow.hxx +++ b/svtools/inc/svtools/table/tabledatawindow.hxx @@ -53,21 +53,27 @@ namespace svt { namespace table private: TableControl_Impl& m_rTableControl; Link m_aMouseButtonDownHdl; - Link m_aMouseButtonUpHdl; - + Link m_aMouseButtonUpHdl; + Link m_aSelectHdl; + RowPos m_nRowAlreadySelected; public: TableDataWindow( TableControl_Impl& _rTableControl ); inline void SetMouseButtonDownHdl( const Link& rLink ) { m_aMouseButtonDownHdl = rLink; } inline const Link& GetMouseButtonDownHdl() const { return m_aMouseButtonDownHdl; } inline void SetMouseButtonUpHdl( const Link& rLink ) { m_aMouseButtonUpHdl = rLink; } inline const Link& GetMouseButtonUpHdl() const { return m_aMouseButtonUpHdl; } + inline void SetSelectHdl( const Link& rLink ) { m_aSelectHdl = rLink; } + inline const Link& GetSelectHdl() const { return m_aSelectHdl; } // Window overridables virtual void Paint( const Rectangle& rRect ); virtual void MouseMove( const MouseEvent& rMEvt); virtual void MouseButtonDown( const MouseEvent& rMEvt); virtual void MouseButtonUp( const MouseEvent& rMEvt); - + virtual void SetPointer( const Pointer& rPointer ); + virtual void CaptureMouse(); + virtual void ReleaseMouse(); + virtual long Notify(NotifyEvent& rNEvt); }; //........................................................................ } } // namespace svt::table diff --git a/svtools/inc/svtools/table/tablemodel.hxx b/svtools/inc/svtools/table/tablemodel.hxx index 34a89cb03e6b..3da396d9d86c 100644 --- a/svtools/inc/svtools/table/tablemodel.hxx +++ b/svtools/inc/svtools/table/tablemodel.hxx @@ -27,13 +27,16 @@ #ifndef SVTOOLS_INC_TABLE_TABLEMODEL_HXX #define SVTOOLS_INC_TABLE_TABLEMODEL_HXX +#include "svtools/svtdllapi.h" #include <svtools/table/tabletypes.hxx> #include <svtools/table/tablerenderer.hxx> #include <svtools/table/tableinputhandler.hxx> - +#include <rtl/ref.hxx> #include <sal/types.h> - +#include <com/sun/star/util/Color.hpp> #include <boost/shared_ptr.hpp> +#include <com/sun/star/style/VerticalAlignment.hpp> +#include <com/sun/star/style/HorizontalAlignment.hpp> //........................................................................ namespace svt { namespace table @@ -44,21 +47,16 @@ namespace svt { namespace table //==================================================================== //= cell data //==================================================================== - struct CellEntryType + struct TableContentType { - String m_aStr; - //Image m_aImage; - //Control m_aControl; - CellEntryType( const String& _rStr ) : - m_aStr( _rStr ) - {} + ::rtl::OUString sContent; + Image* pImage; + TableContentType() : + sContent(), + pImage( ) + { + } }; - - //typedef ::std::vector<CellEntryType*> CellColumnContent; - //vector, which contains text data for each cell - typedef ::std::vector<String> CellColumnContent; - //vector, which contains data for rows - typedef ::std::vector<CellColumnContent> CellContent; //==================================================================== //= ScrollbarVisibility //==================================================================== @@ -285,7 +283,24 @@ namespace svt { namespace table */ virtual void setMaxWidth( TableMetrics _nMaxWidth ) = 0; + /** returns the preferred width of the column, or 0 if the column + does not have a preferred width. + + @see setMaxWidth + @see getMinWidth + @see getWidth + */ + virtual TableMetrics getPreferredWidth() const = 0; + /** sets the preferred width of the column, to be used when user resizes column + + @see getMaxWidth + @see setMinWidth + @see setWidth + */ + virtual void setPreferredWidth( TableMetrics _nPrefWidth ) = 0; + virtual ::com::sun::star::style::HorizontalAlignment getHorizontalAlign() = 0; + virtual void setHorizontalAlign(::com::sun::star::style::HorizontalAlignment _xAlign) = 0; /// deletes the column model instance virtual ~IColumnModel() { } }; @@ -296,7 +311,7 @@ namespace svt { namespace table //==================================================================== /** declares the interface to implement by an abtract table model */ - class SAL_NO_VTABLE ITableModel + class SAL_NO_VTABLE SVT_DLLPUBLIC ITableModel { public: /** returns the number of columns in the table @@ -307,8 +322,8 @@ namespace svt { namespace table */ virtual TableSize getRowCount() const = 0; - virtual void setColumnCount(TableSize _nColCount) = 0; - virtual void setRowCount(TableSize _nRowCount) = 0; + SVT_DLLPRIVATE virtual void setColumnCount(TableSize _nColCount) = 0; + SVT_DLLPRIVATE virtual void setRowCount(TableSize _nRowCount) = 0; /** determines whether the table has column headers @@ -321,12 +336,12 @@ namespace svt { namespace table /** sets whether the table should have row headers @see IColumnRenderer */ - virtual void setRowHeaders( bool rowHeaders) = 0; + SVT_DLLPRIVATE virtual void setRowHeaders( bool rowHeaders) = 0; /** sets whether the table should have column headers @see IColumnRenderer */ - virtual void setColumnHeaders( bool columnHeaders) = 0; + SVT_DLLPRIVATE virtual void setColumnHeaders( bool columnHeaders) = 0; /** determines whether the table has row headers @@ -346,11 +361,11 @@ namespace svt { namespace table /** adds the given listener to the list of ->ITableModelListener's */ - virtual void addTableModelListener( const PTableModelListener& listener ) = 0; + SVT_DLLPRIVATE virtual void addTableModelListener( const PTableModelListener& listener ) = 0; /** revokes the given listener from the list of ->ITableModelListener's */ - virtual void removeTableModelListener( const PTableModelListener& listener ) = 0; + SVT_DLLPRIVATE virtual void removeTableModelListener( const PTableModelListener& listener ) = 0; /** returns a model for a certain column @@ -380,7 +395,7 @@ namespace svt { namespace table @return the renderer to use. Must not be <NULL/> */ - virtual PTableRenderer getRenderer() const = 0; + SVT_DLLPRIVATE virtual PTableRenderer getRenderer() const = 0; /** returns the component handling input in a view associated with the model */ @@ -392,9 +407,9 @@ namespace svt { namespace table the logical height of rows in the table, in 1/100 millimeters. The height must be greater 0. */ - virtual TableMetrics getRowHeight() const = 0; + SVT_DLLPRIVATE virtual TableMetrics getRowHeight() const = 0; - virtual void setRowHeight(TableMetrics _nRowHeight) = 0; + SVT_DLLPRIVATE virtual void setRowHeight(TableMetrics _nRowHeight) = 0; /** determines the height of the column header row @@ -405,7 +420,7 @@ namespace svt { namespace table the logical height of the column header row, in 1/100 millimeters. Must be greater than 0. */ - virtual TableMetrics getColumnHeaderHeight() const = 0; + SVT_DLLPRIVATE virtual TableMetrics getColumnHeaderHeight() const = 0; /** determines the width of the row header column @@ -416,7 +431,7 @@ namespace svt { namespace table the logical width of the row header column, in 1/100 millimeters. Must be greater than 0. */ - virtual TableMetrics getRowHeaderWidth() const = 0; + SVT_DLLPRIVATE virtual TableMetrics getRowHeaderWidth() const = 0; /** determines the visibility of the vertical scrollbar of the table control @param overAllHeight the height of the table with all rows @@ -429,19 +444,32 @@ namespace svt { namespace table @param actWidth the given width of the table */ virtual ScrollbarVisibility getHorizontalScrollbarVisibility(int overAllWidth, int actWidth) const = 0; - - /** fills cells with content - */ - virtual void setCellContent(std::vector<std::vector<rtl::OUString> > cellContent)=0; - /** gets the content of the cells - */ - virtual std::vector<std::vector<rtl::OUString> >& getCellContent() = 0; - /**sets title of header rows - */ - virtual void setRowHeaderName(std::vector<rtl::OUString> cellColumnContent)=0; - /** gets title of header rows - */ - virtual std::vector<rtl::OUString>& getRowHeaderName() = 0; + virtual bool hasVerticalScrollbar() =0; + virtual bool hasHorizontalScrollbar() = 0; + /** fills cells with content + */ + virtual void setCellContent(const std::vector< std::vector< ::com::sun::star::uno::Any > >& cellContent)=0; + /** gets the content of the cells + */ + virtual std::vector< std::vector< ::com::sun::star::uno::Any > >& getCellContent() = 0; + /**sets title of header rows + */ + SVT_DLLPRIVATE virtual void setRowHeaderName(const std::vector<rtl::OUString>& cellColumnContent)=0; + /** gets title of header rows + */ + virtual std::vector<rtl::OUString>& getRowHeaderName() = 0; + SVT_DLLPRIVATE virtual ::com::sun::star::util::Color getLineColor() = 0; + SVT_DLLPRIVATE virtual void setLineColor(::com::sun::star::util::Color _rColor) = 0; + SVT_DLLPRIVATE virtual ::com::sun::star::util::Color getHeaderBackgroundColor() = 0; + SVT_DLLPRIVATE virtual void setHeaderBackgroundColor(::com::sun::star::util::Color _rColor) = 0; + SVT_DLLPRIVATE virtual ::com::sun::star::util::Color getTextColor() = 0; + SVT_DLLPRIVATE virtual void setTextColor(::com::sun::star::util::Color _rColor) = 0; + SVT_DLLPRIVATE virtual ::com::sun::star::util::Color getOddRowBackgroundColor() = 0; + SVT_DLLPRIVATE virtual void setOddRowBackgroundColor(::com::sun::star::util::Color _rColor) = 0; + SVT_DLLPRIVATE virtual ::com::sun::star::util::Color getEvenRowBackgroundColor() = 0; + SVT_DLLPRIVATE virtual void setEvenRowBackgroundColor(::com::sun::star::util::Color _rColor) = 0; + SVT_DLLPRIVATE virtual ::com::sun::star::style::VerticalAlignment getVerticalAlign() = 0; + SVT_DLLPRIVATE virtual void setVerticalAlign(::com::sun::star::style::VerticalAlignment _xAlign) = 0; /// destroys the table model instance virtual ~ITableModel() { } diff --git a/svtools/inc/svtools/table/tablerenderer.hxx b/svtools/inc/svtools/table/tablerenderer.hxx index cf8cd20680c2..f81771dd22e6 100644 --- a/svtools/inc/svtools/table/tablerenderer.hxx +++ b/svtools/inc/svtools/table/tablerenderer.hxx @@ -45,7 +45,7 @@ namespace svt { namespace table */ class SAL_NO_VTABLE ITableRenderer { - public: + public: /** paints a (part of) header area There are two header areas in a table control: @@ -178,10 +178,9 @@ namespace svt { namespace table @param _rText the title of the header row */ - virtual void PaintRowHeader( - bool _bActive, bool _bSelected, + virtual void PaintRowHeader( bool _bActive, bool _bSelected, OutputDevice& _rDevice, const Rectangle& _rArea, - const StyleSettings& _rStyle, rtl::OUString& _rText ) = 0; + const StyleSettings& _rStyle, rtl::OUString& _rText ) = 0; /** paints a certain cell @@ -208,13 +207,46 @@ namespace svt { namespace table the are into which the cell should be painted @param _rStyle the style to be used for drawing + @param _pCellData + the content of the cell + */ + virtual void PaintCellImage( ColPos _nColumn, + bool _bActive, bool _bSelected, + OutputDevice& _rDevice, const Rectangle& _rArea, + const StyleSettings& _rStyle, Image* _pCellData ) = 0; + + /** paints a certain cell + + The row to be painted is denoted by the most recent call to + ->PrepareRow. + + @param _bSelected + <TRUE/> if and only if the cell to be painted is + selected currently. This is the case if either + the row or the column of the cell is currently selected. + <br/> + Note that this flag is equal to the respective flag in the + previous ->PrepareRow call, it's passed here for convinience + only. + @param _bActive + <TRUE/> if the cell is currently active. + <br/> + Note that this flag is equal to the respective flag in the + previous ->PrepareRow call, it's passed here for convinience + only. + @param _rDevice + denotes the device to paint onto + @param _rArea + the are into which the cell should be painted + @param _rStyle + the style to be used for drawing @param _rText the content of the cell */ - virtual void PaintCell( ColPos _nColumn, + virtual void PaintCellString( ColPos _nColumn, bool _bActive, bool _bSelected, OutputDevice& _rDevice, const Rectangle& _rArea, - const StyleSettings& _rStyle, rtl::OUString& _rText ) = 0; + const StyleSettings& _rStyle, rtl::OUString& _rText ) = 0; /** draws a cell cursor in the given rectangle diff --git a/svtools/inc/svtools/table/tabletypes.hxx b/svtools/inc/svtools/table/tabletypes.hxx index f423b64c2faa..645120e30d4b 100644 --- a/svtools/inc/svtools/table/tabletypes.hxx +++ b/svtools/inc/svtools/table/tabletypes.hxx @@ -56,17 +56,17 @@ namespace svt { namespace table /** special column width value which indicates that the column should be automatically resized to fit the view */ -#define COLWIDTH_FIT_TO_VIEW ((TableMetrics)-1) +#define COLWIDTH_FIT_TO_VIEW ((::svt::table::TableMetrics)-1) /// denotes the column containing the row headers -#define COL_ROW_HEADERS ((ColPos)-1) +#define COL_ROW_HEADERS ((::svt::table::ColPos)-1) /// denotes the row containing the column headers -#define ROW_COL_HEADERS ((RowPos)-1) +#define ROW_COL_HEADERS ((::svt::table::RowPos)-1) /// denotes an invalid column index -#define COL_INVALID ((ColPos)-2) +#define COL_INVALID ((::svt::table::ColPos)-2) /// denotes an invalid row index -#define ROW_INVALID ((RowPos)-2) +#define ROW_INVALID ((::svt::table::RowPos)-2) //........................................................................ diff --git a/svtools/prj/build.lst b/svtools/prj/build.lst index 1fd12bb50b6c..2645b9e6bf6a 100644 --- a/svtools/prj/build.lst +++ b/svtools/prj/build.lst @@ -29,3 +29,4 @@ st svtools\source\hatchwindow nmake - all st_hatchwin st_inc NULL st svtools\source\productregistration nmake - all st_prodreg st_util st_inc NULL st svtools\workben\unodialog nmake - all st_workben_udlg st_util NULL st svtools\workben\toolpanel nmake - all st_workben_toolpanel st_util st_toolpanel NULL +st svtools\qa\unoapi nmake - all st_qa_unoapi NULL diff --git a/svtools/prj/d.lst b/svtools/prj/d.lst index fa3fbb2371dd..b46ddef72311 100644 --- a/svtools/prj/d.lst +++ b/svtools/prj/d.lst @@ -2,6 +2,7 @@ mkdir: %COMMON_DEST%\bin%_EXT%\hid mkdir: %COMMON_DEST%\res%_EXT% mkdir: %_DEST%\inc%_EXT%\svtools mkdir: %_DEST%\inc%_EXT%\svtools\toolpanel +mkdir: %_DEST%\inc%_EXT%\svtools\table ..\%COMMON_OUTDIR%\misc\*.hid %COMMON_DEST%\bin%_EXT%\hid\*.hid ..\%__SRC%\srs\ehdl.srs %_DEST%\res%_EXT%\svtools.srs @@ -26,6 +27,7 @@ mkdir: %_DEST%\inc%_EXT%\svtools\toolpanel ..\inc\svtools\*.hxx %_DEST%\inc%_EXT%\svtools\*.hxx ..\inc\svtools\*.h %_DEST%\inc%_EXT%\svtools\*.h ..\inc\svtools\*.hrc %_DEST%\inc%_EXT%\svtools\*.hrc +..\inc\svtools\table\*.hxx %_DEST%\inc%_EXT%\svtools\table\*.hxx ..\inc\*.hxx %_DEST%\inc%_EXT%\svtools\*.hxx ..\inc\*.h %_DEST%\inc%_EXT%\svtools\*.h ..\inc\*.hrc %_DEST%\inc%_EXT%\svtools\*.hrc diff --git a/svtools/qa/unoapi/Test.java b/svtools/qa/unoapi/Test.java new file mode 100644 index 000000000000..8ae4af55ed61 --- /dev/null +++ b/svtools/qa/unoapi/Test.java @@ -0,0 +1,51 @@ +/************************************************************************* +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* Copyright 2000, 2010 Oracle and/or its affiliates. +* +* OpenOffice.org - a multi-platform office productivity suite +* +* This file is part of OpenOffice.org. +* +* OpenOffice.org is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License version 3 +* only, as published by the Free Software Foundation. +* +* OpenOffice.org is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License version 3 for more details +* (a copy is included in the LICENSE file that accompanied this code). +* +* You should have received a copy of the GNU Lesser General Public License +* version 3 along with OpenOffice.org. If not, see +* <http://www.openoffice.org/license.html> +* for a copy of the LGPLv3 License. +************************************************************************/ + +package org.openoffice.svtools.qa.unoapi; + +import org.openoffice.Runner; +import org.openoffice.test.OfficeConnection; +import static org.junit.Assert.*; + +public final class Test { + @org.junit.Before public void setUp() throws Exception { + connection.setUp(); + } + + @org.junit.After public void tearDown() + throws InterruptedException, com.sun.star.uno.Exception + { + connection.tearDown(); + } + + @org.junit.Test public void test() { + assertTrue( + Runner.run( + "-sce", "svtools.sce", "-xcl", "knownissues.xcl", "-cs", + connection.getDescription())); + } + + private final OfficeConnection connection = new OfficeConnection(); +} diff --git a/svtools/qa/unoapi/makefile.mk b/svtools/qa/unoapi/makefile.mk index 2d75735d4b0d..e3afb77e637a 100644 --- a/svtools/qa/unoapi/makefile.mk +++ b/svtools/qa/unoapi/makefile.mk @@ -1,7 +1,6 @@ #************************************************************************* -# # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# +# # Copyright 2000, 2010 Oracle and/or its affiliates. # # OpenOffice.org - a multi-platform office productivity suite @@ -22,19 +21,28 @@ # version 3 along with OpenOffice.org. If not, see # <http://www.openoffice.org/license.html> # for a copy of the LGPLv3 License. -# -#************************************************************************* +#***********************************************************************/ -PRJ=..$/.. +.IF "$(OOO_SUBSEQUENT_TESTS)" == "" +nothing .PHONY: +.ELSE -PRJNAME=svtools -TARGET=qa_unoapi +PRJ = ../.. +PRJNAME = svtools +TARGET = qa_unoapi -.INCLUDE: settings.mk +.IF "$(OOO_JUNIT_JAR)" != "" +PACKAGE = org/openoffice/svtools/qa/unoapi +JAVATESTFILES = Test.java +JAVAFILES = $(JAVATESTFILES) +JARFILES = OOoRunner.jar ridl.jar test.jar +EXTRAJARFILES = $(OOO_JUNIT_JAR) +.END +.INCLUDE: settings.mk .INCLUDE: target.mk +.INCLUDE: installationtest.mk -ALLTAR : UNOAPI_TEST +ALLTAR : javatest -UNOAPI_TEST: - +$(SOLARENV)$/bin$/checkapi -sce svtools.sce -xcl knownissues.xcl -tdoc $(PWD)$/testdocuments +.END diff --git a/svtools/source/hatchwindow/exports.map b/svtools/source/hatchwindow/exports.map deleted file mode 100644 index f4ed78b9e970..000000000000 --- a/svtools/source/hatchwindow/exports.map +++ /dev/null @@ -1,8 +0,0 @@ -UDK_3_0_0 { - global: - component_getImplementationEnvironment; - component_writeInfo; - component_getFactory; - local: - *; -}; diff --git a/svtools/source/hatchwindow/makefile.mk b/svtools/source/hatchwindow/makefile.mk index c5a4dab09762..316e4ab1bfe2 100644 --- a/svtools/source/hatchwindow/makefile.mk +++ b/svtools/source/hatchwindow/makefile.mk @@ -55,7 +55,7 @@ SHL1STDLIBS=\ $(CPPULIB) \ $(SALLIB) -SHL1VERSIONMAP=exports.map +SHL1VERSIONMAP=$(SOLARENV)/src/component.map SHL1DEF= $(MISC)$/$(SHL1TARGET).def DEF1NAME= $(SHL1TARGET) diff --git a/svtools/source/inc/accessibletableimp.hxx b/svtools/source/inc/accessibletableimp.hxx new file mode 100644 index 000000000000..3a01c01567d3 --- /dev/null +++ b/svtools/source/inc/accessibletableimp.hxx @@ -0,0 +1,62 @@ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * +************************************************************************/ + +#ifndef SVTOOLS_SOURCE_INC_ACCESSIBLETABLEIMP_HXX +#define SVTOOLS_SOURCE_INC_ACCESSIBLETABLEIMP_HXX + +#include "svtaccessiblefactory.hxx" + +namespace svt { namespace table +{ +//........................................................................ + + + class AccessibleTableControl_Impl + { + public: + AccessibleFactoryAccess m_aFactoryAccess; + IAccessibleTableControl* m_pAccessible; + + public: + AccessibleTableControl_Impl() : m_pAccessible(NULL) + { + } + + + /// @see AccessibleTableControl::getTableRowHeader + ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > + getAccessibleTableHeader( AccessibleTableControlObjType _eObjType ); + /// @see AccessibleTableControl::getTable + ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > + getAccessibleTable( ); + + }; + +//........................................................................ +} } // namespace svt::table +//........................................................................ + +#endif // SVTOOLS_SOURCE_INC_ACCESSIBLETABLEIMP_HXX diff --git a/svtools/source/misc/transfer.cxx b/svtools/source/misc/transfer.cxx index 4628c0d4b846..268533ebb8c8 100644 --- a/svtools/source/misc/transfer.cxx +++ b/svtools/source/misc/transfer.cxx @@ -42,6 +42,7 @@ #include <vos/mutex.hxx> #include <rtl/memory.h> #include <rtl/uuid.h> +#include <rtl/uri.hxx> #ifndef DEBUG_HXX #include <tools/debug.hxx> #endif @@ -154,6 +155,10 @@ SvStream& operator<<( SvStream& rOStm, const TransferableObjectDescriptor& rObjD } // ----------------------------------------------------------------------------- +// the reading of the parameter is done using the special service ::com::sun::star::datatransfer::MimeContentType, +// a similar approach should be implemented for creation of the mimetype string; +// for now the set of acceptable characters has to be hardcoded, in future it should be part of the service that creates the mimetype +const ::rtl::OUString aQuotedParamChars = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "()<>@,;:\\\"/[]?=!#$%&'*+-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~. " ) ); static ::rtl::OUString ImplGetParameterString( const TransferableObjectDescriptor& rObjDesc ) { @@ -177,8 +182,21 @@ static ::rtl::OUString ImplGetParameterString( const TransferableObjectDescripto if( rObjDesc.maDisplayName.Len() ) { + // the display name might contain unacceptable characters, encode all of them + // this seems to be the only parameter currently that might contain such characters + sal_Bool pToAccept[128]; + for ( sal_Int32 nBInd = 0; nBInd < 128; nBInd++ ) + pToAccept[nBInd] = sal_False; + + for ( sal_Int32 nInd = 0; nInd < aQuotedParamChars.getLength(); nInd++ ) + { + sal_Unicode nChar = aQuotedParamChars.getStr()[nInd]; + if ( nChar < 128 ) + pToAccept[nChar] = sal_True; + } + aParams += ::rtl::OUString::createFromAscii( ";displayname=\"" ); - aParams += rObjDesc.maDisplayName; + aParams += ::rtl::Uri::encode( rObjDesc.maDisplayName, pToAccept, rtl_UriEncodeIgnoreEscapes, RTL_TEXTENCODING_UTF8 ); aParams += aChar; } @@ -248,7 +266,9 @@ static void ImplSetParameterString( TransferableObjectDescriptor& rObjDesc, cons if( xMimeType->hasParameter( aDisplayNameString ) ) { - rObjDesc.maDisplayName = xMimeType->getParameterValue( aDisplayNameString ); + // the display name might contain unacceptable characters, in this case they should be encoded + // this seems to be the only parameter currently that might contain such characters + rObjDesc.maDisplayName = ::rtl::Uri::decode( xMimeType->getParameterValue( aDisplayNameString ), rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 ); } if( xMimeType->hasParameter( aViewAspectString ) ) diff --git a/svtools/source/productregistration/exports.map b/svtools/source/productregistration/exports.map deleted file mode 100644 index f4ed78b9e970..000000000000 --- a/svtools/source/productregistration/exports.map +++ /dev/null @@ -1,8 +0,0 @@ -UDK_3_0_0 { - global: - component_getImplementationEnvironment; - component_writeInfo; - component_getFactory; - local: - *; -}; diff --git a/svtools/source/productregistration/makefile.mk b/svtools/source/productregistration/makefile.mk index 0b970b651059..a26e8feca753 100644 --- a/svtools/source/productregistration/makefile.mk +++ b/svtools/source/productregistration/makefile.mk @@ -59,7 +59,7 @@ SHL1STDLIBS=\ $(CPPULIB) \ $(SALLIB) -SHL1VERSIONMAP=exports.map +SHL1VERSIONMAP=$(SOLARENV)/src/component.map SHL1DEF= $(MISC)$/$(SHL1TARGET).def DEF1NAME= $(SHL1TARGET) diff --git a/svtools/source/table/defaultinputhandler.cxx b/svtools/source/table/defaultinputhandler.cxx index b11357db95d1..ad8f7a7562d3 100644 --- a/svtools/source/table/defaultinputhandler.cxx +++ b/svtools/source/table/defaultinputhandler.cxx @@ -50,6 +50,7 @@ namespace svt { namespace table //-------------------------------------------------------------------- DefaultInputHandler::DefaultInputHandler() :m_pImpl( new DefaultInputHandler_Impl ) + ,m_bResize(false) { } @@ -62,8 +63,12 @@ namespace svt { namespace table //-------------------------------------------------------------------- bool DefaultInputHandler::MouseMove( IAbstractTableControl& _rControl, const MouseEvent& _rMEvt ) { - (void)_rControl; - (void)_rMEvt; + Point aPoint = _rMEvt.GetPosPixel(); + if(m_bResize) + { + _rControl.resizeColumn(aPoint); + return true; + } return false; } @@ -72,41 +77,60 @@ namespace svt { namespace table { bool bHandled = false; Point aPoint = _rMEvt.GetPosPixel(); - if(_rControl.isClickInVisibleArea(aPoint)) + RowPos nRow = _rControl.getCurrentRow(aPoint); + if(nRow == -1) + { + m_bResize = _rControl.startResizeColumn(aPoint); + bHandled = true; + } + else if(nRow >= 0) { if(_rControl.getSelEngine()->GetSelectionMode() == NO_SELECTION) { - LoseFocus(_rControl); _rControl.setCursorAtCurrentCell(aPoint); bHandled = true; } else { - bHandled = _rControl.getSelEngine()->SelMouseButtonDown(_rMEvt); + if(!_rControl.isRowSelected(nRow)) + bHandled = _rControl.getSelEngine()->SelMouseButtonDown(_rMEvt); + else + bHandled = true; } } return bHandled; } - //-------------------------------------------------------------------- bool DefaultInputHandler::MouseButtonUp( IAbstractTableControl& _rControl, const MouseEvent& _rMEvt ) { bool bHandled = false; Point aPoint = _rMEvt.GetPosPixel(); - if(_rControl.isClickInVisibleArea(aPoint)) + if(_rControl.getCurrentRow(aPoint) >= 0) { - if(_rControl.getSelEngine()->GetSelectionMode() == NO_SELECTION) + if(m_bResize) + { + m_bResize = _rControl.endResizeColumn(aPoint); + bHandled = true; + } + else if(_rControl.getSelEngine()->GetSelectionMode() == NO_SELECTION) { - GetFocus(_rControl); - _rControl.setCursorAtCurrentCell(aPoint); bHandled = true; } else + { bHandled = _rControl.getSelEngine()->SelMouseButtonUp(_rMEvt); + } + } + else + { + if(m_bResize) + { + m_bResize = _rControl.endResizeColumn(aPoint); + bHandled = true; + } } return bHandled; } - //-------------------------------------------------------------------- bool DefaultInputHandler::KeyInput( IAbstractTableControl& _rControl, const KeyEvent& rKEvt ) { @@ -134,11 +158,11 @@ namespace svt { namespace table { KEY_PAGEDOWN, KEY_MOD1, cursorToLastLine }, { KEY_HOME, KEY_MOD1, cursorTopLeft }, { KEY_END, KEY_MOD1, cursorBottomRight }, - { KEY_SPACE, KEY_MOD1, cursorSelectRow }, - { KEY_UP, KEY_SHIFT, cursorSelectRowUp }, - { KEY_DOWN, KEY_SHIFT, cursorSelectRowDown }, - { KEY_END, KEY_SHIFT, cursorSelectRowAreaBottom }, - { KEY_HOME, KEY_SHIFT, cursorSelectRowAreaTop }, + { KEY_SPACE, KEY_MOD1, cursorSelectRow }, + { KEY_UP, KEY_SHIFT, cursorSelectRowUp }, + { KEY_DOWN, KEY_SHIFT, cursorSelectRowDown }, + { KEY_END, KEY_SHIFT, cursorSelectRowAreaBottom }, + { KEY_HOME, KEY_SHIFT, cursorSelectRowAreaTop }, { 0, 0, invalidTableControlAction } }; @@ -205,7 +229,6 @@ namespace svt { namespace table // TODO return false; } - //........................................................................ } } // namespace svt::table //........................................................................ diff --git a/svtools/source/table/gridtablerenderer.cxx b/svtools/source/table/gridtablerenderer.cxx index ada2e463c8af..a3f954e0bef5 100644 --- a/svtools/source/table/gridtablerenderer.cxx +++ b/svtools/source/table/gridtablerenderer.cxx @@ -31,6 +31,7 @@ #include <tools/debug.hxx> #include <vcl/window.hxx> +#include <vcl/image.hxx> //........................................................................ namespace svt { namespace table @@ -78,15 +79,15 @@ namespace svt { namespace table OSL_PRECOND( _bIsColHeaderArea || _bIsRowHeaderArea, "GridTableRenderer::PaintHeaderArea: invalid area flags!" ); - // fill the rows with alternating background colors - _rDevice.Push( PUSH_FILLCOLOR | PUSH_LINECOLOR ); - - _rDevice.SetLineColor(); - _rDevice.SetFillColor( _rStyle.GetDialogColor() ); + _rDevice.Push( PUSH_FILLCOLOR | PUSH_LINECOLOR); + Color background = m_pImpl->rModel.getHeaderBackgroundColor(); + if( background != 0xFFFFFF) + _rDevice.SetFillColor(background); + else + _rDevice.SetFillColor(_rStyle.GetDialogColor()); + _rDevice.SetLineColor(_rStyle.GetSeparatorColor()); _rDevice.DrawRect( _rArea ); - // delimiter lines at bottom/right - _rDevice.SetLineColor( _rStyle.GetDialogTextColor() ); _rDevice.DrawLine( _rArea.BottomLeft(), _rArea.BottomRight() ); _rDevice.DrawLine( _rArea.BottomRight(), _rArea.TopRight() ); @@ -99,31 +100,38 @@ namespace svt { namespace table void GridTableRenderer::PaintColumnHeader( ColPos _nCol, bool _bActive, bool _bSelected, OutputDevice& _rDevice, const Rectangle& _rArea, const StyleSettings& _rStyle ) { - _rDevice.Push( PUSH_LINECOLOR ); - - _rDevice.SetLineColor( _rStyle.GetDialogTextColor() ); - _rDevice.DrawLine( _rArea.BottomRight(), _rArea.TopRight() ); + _rDevice.Push( PUSH_LINECOLOR); + _rDevice.SetLineColor(_rStyle.GetSeparatorColor()); + _rDevice.DrawLine( _rArea.BottomRight(), _rArea.TopRight()); String sHeaderText; - PColumnModel pColumn = m_pImpl->rModel.getColumnModel( _nCol ); DBG_ASSERT( !!pColumn, "GridTableRenderer::PaintColumnHeader: invalid column model object!" ); if ( !!pColumn ) sHeaderText = pColumn->getName(); - Color aRowBackground = _rStyle.GetFieldColor(); - if ( _bSelected ) - { - aRowBackground = COL_BLUE; - } - _rDevice.DrawText( _rArea, sHeaderText, TEXT_DRAW_LEFT | TEXT_DRAW_TOP ); + _rDevice.SetTextColor(m_pImpl->rModel.getTextColor()); + ULONG nHorFlag = TEXT_DRAW_LEFT; + ULONG nVerFlag = TEXT_DRAW_TOP; + if(m_pImpl->rModel.getVerticalAlign() == 1) + nVerFlag = TEXT_DRAW_VCENTER; + else if(m_pImpl->rModel.getVerticalAlign() == 2) + nVerFlag = TEXT_DRAW_BOTTOM; + if(m_pImpl->rModel.getColumnModel(_nCol)->getHorizontalAlign() == 1) + nHorFlag = TEXT_DRAW_CENTER; + else if(m_pImpl->rModel.getColumnModel(_nCol)->getHorizontalAlign() == 2) + nHorFlag = TEXT_DRAW_RIGHT; + Rectangle aRect(_rArea); + aRect.Left()+=4; aRect.Right()-=4; + aRect.Bottom()-=2; + _rDevice.DrawText( aRect, sHeaderText, nHorFlag | nVerFlag | TEXT_DRAW_CLIP); _rDevice.DrawLine( _rArea.BottomLeft(), _rArea.BottomRight() ); _rDevice.Pop(); (void)_bActive; // no special painting for the active column at the moment - //(void)_bSelected; - // TODO: selection not yet implemented + (void)_bSelected; + //selection for column header not yet implemented } //-------------------------------------------------------------------- @@ -133,86 +141,218 @@ namespace svt { namespace table // remember the row for subsequent calls to the other ->ITableRenderer methods m_pImpl->nCurrentRow = _nRow; - // fill the rows with alternating background colors - _rDevice.Push( PUSH_FILLCOLOR | PUSH_LINECOLOR ); - - _rDevice.SetLineColor(); - - Color aRowBackground = _rStyle.GetFieldColor(); + _rDevice.Push( PUSH_FILLCOLOR | PUSH_LINECOLOR); + Color aRowBackground = m_pImpl->rModel.getOddRowBackgroundColor(); + Color line = m_pImpl->rModel.getLineColor(); + Color aRowBackground2 = m_pImpl->rModel.getEvenRowBackgroundColor(); + //if row is selected background color becomes blue, and lines should be also blue + //if they aren't user defined + if(_bSelected) + { + Color aSelected(_rStyle.GetHighlightColor()); + aRowBackground = aSelected; + if(line == 0xFFFFFF) + _rDevice.SetLineColor(aRowBackground); + else + _rDevice.SetLineColor(line); + } + //if row not selected, check the cases whether user defined backgrounds are set + //and set line color to be the same + else + { + if(aRowBackground2 != 0xFFFFFF && _nRow%2) + { + aRowBackground = aRowBackground2; + if(line == 0xFFFFFF) + _rDevice.SetLineColor(aRowBackground); + else + _rDevice.SetLineColor(line); + } + //fill the rows with alternating background colors if second background color is specified + else if(aRowBackground != 0xFFFFFF && line == 0xFFFFFF) + _rDevice.SetLineColor(aRowBackground); + else + { + //if Line color is set, then it was user defined and should be visible + //if it wasn't set, it'll be the same as the default background color, so lines still won't be visible + _rDevice.SetLineColor(line); + } + } _rDevice.SetFillColor( aRowBackground ); - _rDevice.DrawRect( _rRowArea ); - // TODO: active? selected? + // TODO: active? _rDevice.Pop(); - (void) _bSelected; (void)_bActive; - - // no special painting for the active row at the moment - - //(void)_bSelected; - // TODO: selection not yet implemented } //-------------------------------------------------------------------- void GridTableRenderer::PaintRowHeader( bool _bActive, bool _bSelected, OutputDevice& _rDevice, const Rectangle& _rArea, const StyleSettings& _rStyle, rtl::OUString& _rText ) { - _rDevice.Push( PUSH_FILLCOLOR | PUSH_LINECOLOR ); - - _rDevice.SetLineColor( _rStyle.GetDialogTextColor() ); + _rDevice.Push( PUSH_LINECOLOR); + _rDevice.SetLineColor(_rStyle.GetSeparatorColor()); _rDevice.DrawLine( _rArea.BottomLeft(), _rArea.BottomRight() ); - _rDevice.DrawText( _rArea, _rText, TEXT_DRAW_LEFT); + _rDevice.SetTextColor(m_pImpl->rModel.getTextColor()); + ULONG nHorFlag = TEXT_DRAW_LEFT; + ULONG nVerFlag = TEXT_DRAW_TOP; + if(m_pImpl->rModel.getVerticalAlign() == 1) + nVerFlag = TEXT_DRAW_VCENTER; + else if(m_pImpl->rModel.getVerticalAlign() == 2) + nVerFlag = TEXT_DRAW_BOTTOM; + if(m_pImpl->rModel.getColumnModel(0)->getHorizontalAlign() == 1) + nHorFlag = TEXT_DRAW_CENTER; + else if(m_pImpl->rModel.getColumnModel(0)->getHorizontalAlign() == 2) + nHorFlag = TEXT_DRAW_RIGHT; + Rectangle aRect(_rArea); + aRect.Left()+=4; aRect.Right()-=4; + aRect.Bottom()-=2; + _rDevice.DrawText( aRect, _rText, nHorFlag | nVerFlag | TEXT_DRAW_CLIP); // TODO: active? selected? (void)_bActive; (void)_bSelected; - + //at the moment no special paint for selected row header _rDevice.Pop(); } //-------------------------------------------------------------------- - void GridTableRenderer::PaintCell( ColPos _nColumn, bool _bSelected, bool _bActive, - OutputDevice& _rDevice, const Rectangle& _rArea, const StyleSettings& _rStyle, rtl::OUString& _rText ) + void GridTableRenderer::PaintCellImage( ColPos _nColumn, bool _bSelected, bool _bActive, + OutputDevice& _rDevice, const Rectangle& _rArea, const StyleSettings& _rStyle, Image* _pCellData ) { - _rDevice.Push( PUSH_LINECOLOR ); - - // draw the grid - _rDevice.SetLineColor( COL_LIGHTGRAY ); - // TODO: the LIGHTGRAY should probably be a property/setting - _rDevice.DrawLine( _rArea.BottomRight(), _rArea.TopRight() ); - _rDevice.DrawLine( _rArea.BottomLeft(), _rArea.BottomRight() ); - + _rDevice.Push( PUSH_LINECOLOR | PUSH_FILLCOLOR | PUSH_CLIPREGION); + _rDevice.IntersectClipRegion( _rArea ); + Color background1 = m_pImpl->rModel.getOddRowBackgroundColor(); + Color background2 = m_pImpl->rModel.getEvenRowBackgroundColor(); + Color line = m_pImpl->rModel.getLineColor(); + //if row is selected and line color isn't user specified, set it blue + if(_bSelected) + { + if(line == 0xFFFFFF) + _rDevice.SetLineColor(_rStyle.GetHighlightColor()); + else + _rDevice.SetLineColor(line); + } + //else set line color to the color of row background + else + { + if(background2 != 0xFFFFFF && m_pImpl->nCurrentRow%2) + { + if(line == 0xFFFFFF) + _rDevice.SetLineColor(background2); + else + _rDevice.SetLineColor(line); + } + else if(background1 != 0xFFFFFF && line == 0xFFFFFF) + _rDevice.SetLineColor(background1); + else { + //if line color is set, then it was user defined and should be visible + //if it wasn't set, it'll be the same as the default background color, so lines still won't be visible + _rDevice.SetLineColor(line); + } + } + _rDevice.DrawLine( _rArea.BottomRight(), _rArea.TopRight() ); + { // TODO: remove those temporary place holders Rectangle aRect( _rArea ); ++aRect.Left(); --aRect.Right(); - ++aRect.Top(); --aRect.Bottom(); + aRect.Top(); aRect.Bottom(); + Point imagePos(Point(aRect.Left(), aRect.Top())); + Size imageSize = _pCellData->GetSizePixel(); + if(aRect.GetWidth() > imageSize.Width()) + { + if(m_pImpl->rModel.getColumnModel(_nColumn)->getHorizontalAlign() == 1) + imagePos.X() = aRect.Left()+((double)(aRect.GetWidth() - imageSize.Width()))/2; + else if(m_pImpl->rModel.getColumnModel(_nColumn)->getHorizontalAlign() == 2) + imagePos.X() = aRect.Right() - imageSize.Width(); + } + else + imageSize.Width() = aRect.GetWidth(); + if(aRect.GetHeight() > imageSize.Height()) + { + if(m_pImpl->rModel.getVerticalAlign() == 1) + imagePos.Y() = aRect.Top()+((double)(aRect.GetHeight() - imageSize.Height()))/2; + else if(m_pImpl->rModel.getVerticalAlign() == 2) + imagePos.Y() = aRect.Bottom() - imageSize.Height(); + } + else + imageSize.Height() = aRect.GetHeight()-1; + Image& image (*_pCellData); + _rDevice.DrawImage(imagePos, imageSize, image, 0); + } + _rDevice.Pop(); - String sText; - if(_bSelected) - { - Color aRed(COL_BLUE); - _rDevice.SetFillColor( aRed ); - _rDevice.SetTextColor(COL_WHITE); - } - _rDevice.DrawRect( _rArea ); - (void)_nColumn; - _rDevice.DrawText( aRect, _rText, TEXT_DRAW_LEFT | TEXT_DRAW_TOP); + (void)_bActive; + // no special painting for the active cell at the moment + } + + //-------------------------------------------------------------------- + void GridTableRenderer::PaintCellString( ColPos _nColumn, bool _bSelected, bool _bActive, + OutputDevice& _rDevice, const Rectangle& _rArea, const StyleSettings& _rStyle, rtl::OUString& _rText ) + { + _rDevice.Push( PUSH_LINECOLOR | PUSH_FILLCOLOR ); + Color background1 = m_pImpl->rModel.getOddRowBackgroundColor(); + Color background2 = m_pImpl->rModel.getEvenRowBackgroundColor(); + Color line = m_pImpl->rModel.getLineColor(); + //if row is selected and line color isn't user specified, set it blue + if(_bSelected) + { + if(line == 0xFFFFFF) + _rDevice.SetLineColor(_rStyle.GetHighlightColor()); + else + _rDevice.SetLineColor(line); + } + //else set line color to the color of row background + else + { + if(background2 != 0xFFFFFF && m_pImpl->nCurrentRow%2) + { + if(line == 0xFFFFFF) + _rDevice.SetLineColor(background2); + else + _rDevice.SetLineColor(line); + } + else if(background1 != 0xFFFFFF && line == 0xFFFFFF) + _rDevice.SetLineColor(background1); + else + { + //if Line color is set, then it was user defined and should be visible + //if it wasn't set, it'll be the same as the default background color, so lines still won't be visible + _rDevice.SetLineColor(line); } + } + _rDevice.DrawLine( _rArea.BottomRight(), _rArea.TopRight() ); + { + // TODO: remove those temporary place holders + Rectangle aRect( _rArea ); + ++aRect.Left(); --aRect.Right(); + aRect.Top(); aRect.Bottom(); if(_bSelected) { - _rDevice.SetFillColor( _rStyle.GetFieldColor() ); - _rDevice.SetTextColor(COL_BLACK); + _rDevice.SetTextColor(_rStyle.GetHighlightTextColor()); + } + else + _rDevice.SetTextColor(m_pImpl->rModel.getTextColor()); + ULONG nHorFlag = TEXT_DRAW_LEFT; + ULONG nVerFlag = TEXT_DRAW_TOP; + if(m_pImpl->rModel.getVerticalAlign() == 1) + nVerFlag = TEXT_DRAW_VCENTER; + else if(m_pImpl->rModel.getVerticalAlign() == 2) + nVerFlag = TEXT_DRAW_BOTTOM; + if(m_pImpl->rModel.getColumnModel(_nColumn)->getHorizontalAlign() == 1) + nHorFlag = TEXT_DRAW_CENTER; + else if(m_pImpl->rModel.getColumnModel(_nColumn)->getHorizontalAlign() == 2) + nHorFlag = TEXT_DRAW_RIGHT; + Rectangle textRect(_rArea); + textRect.Left()+=4; textRect.Right()-=4; + textRect.Bottom()-=2; + _rDevice.DrawText( textRect, _rText, nHorFlag | nVerFlag | TEXT_DRAW_CLIP); } - _rDevice.Pop(); - (void)_bActive; -// // no special painting for the active cell at the moment - (void)_rStyle; -// // TODO: do we need this? + // no special painting for the active cell at the moment } //-------------------------------------------------------------------- @@ -224,7 +364,7 @@ namespace svt { namespace table //-------------------------------------------------------------------- void GridTableRenderer::HideCellCursor( Window& _rView, const Rectangle& _rCursorRect) { - (void)_rCursorRect; + (void)_rCursorRect; _rView.HideFocus(); } diff --git a/svtools/source/table/tablecontrol.cxx b/svtools/source/table/tablecontrol.cxx index 262c32ae8ebc..8c95fab6120b 100644 --- a/svtools/source/table/tablecontrol.cxx +++ b/svtools/source/table/tablecontrol.cxx @@ -30,6 +30,7 @@ #include "svtools/table/tablecontrol.hxx" #include "tablegeometry.hxx" #include "tablecontrol_impl.hxx" +#include "accessibletableimp.hxx" #include "svtools/table/tabledatawindow.hxx" #include <com/sun/star/accessibility/AccessibleStateType.hpp> #include <com/sun/star/accessibility/AccessibleRole.hpp> @@ -68,15 +69,19 @@ namespace svt { namespace table TableControl::TableControl( Window* _pParent, WinBits _nStyle ) :Control( _pParent, _nStyle ) ,m_pImpl( new TableControl_Impl( *this ) ) + ,m_bSelectionChanged(false) { - m_pImpl->getDataWindow()->SetMouseButtonDownHdl( LINK( this, TableControl, ImplMouseButtonDownHdl ) ); - m_pImpl->getDataWindow()->SetMouseButtonUpHdl( LINK( this, TableControl, ImplMouseButtonUpHdl ) ); + TableDataWindow* aTableData = m_pImpl->getDataWindow(); + aTableData->SetMouseButtonDownHdl( LINK( this, TableControl, ImplMouseButtonDownHdl ) ); + aTableData->SetMouseButtonUpHdl( LINK( this, TableControl, ImplMouseButtonUpHdl ) ); + aTableData->SetSelectHdl( LINK( this, TableControl, ImplSelectHdl ) ); m_pAccessTable.reset(new ::svt::table::AccessibleTableControl_Impl()); } //-------------------------------------------------------------------- TableControl::~TableControl() { + ImplCallEventListeners( VCLEVENT_OBJECT_DYING ); DELETEZ( m_pImpl ); if ( m_pAccessTable->m_pAccessible ) { @@ -106,6 +111,14 @@ namespace svt { namespace table { if ( !m_pImpl->getInputHandler()->KeyInput( *m_pImpl, rKEvt ) ) Control::KeyInput( rKEvt ); + else + { + if(m_bSelectionChanged) + { + Select(); + m_bSelectionChanged = false; + } + } } //-------------------------------------------------------------------- void TableControl::Resize() @@ -162,13 +175,21 @@ namespace svt { namespace table return m_pImpl->goTo( _nColPos, _nRowPos ); } //-------------------------------------------------------------------- - void TableControl::InvalidateDataWindow(RowPos _nRowStart, bool _bRemoved) + void TableControl::InvalidateDataWindow(RowPos _nRowStart, RowPos _nRowEnd, bool _bRemoved) { Rectangle _rRect; if(_bRemoved) - return m_pImpl->invalidateRows(_nRowStart, _rRect); + m_pImpl->invalidateRows(); else - return m_pImpl->invalidateRow(_nRowStart, _rRect); + { + if(m_bSelectionChanged) + { + m_pImpl->invalidateSelectedRegion(_nRowStart, _nRowEnd, _rRect); + m_bSelectionChanged = false; + } + else + m_pImpl->invalidateRow(_nRowStart, _rRect); + } } //-------------------------------------------------------------------- std::vector<sal_Int32>& TableControl::GetSelectedRows() @@ -176,7 +197,7 @@ namespace svt { namespace table return m_pImpl->getSelectedRows(); } //-------------------------------------------------------------------- - void TableControl::removeSelectedRow(RowPos _nRowPos) + void TableControl::RemoveSelectedRow(RowPos _nRowPos) { m_pImpl->removeSelectedRow(_nRowPos); } @@ -187,20 +208,6 @@ namespace svt { namespace table return m_pImpl->getCurrentRow( rPoint ); } - //-------------------------------------------------------------------- - - IMPL_LINK( TableControl, ImplMouseButtonDownHdl, MouseEvent*, pData ) - { - CallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONDOWN, pData ); - return 1; - } - - IMPL_LINK( TableControl, ImplMouseButtonUpHdl, MouseEvent*, pData ) - { - CallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONUP, pData ); - return 1; - } - SelectionEngine* TableControl::getSelEngine() { return m_pImpl->getSelEngine(); @@ -240,6 +247,7 @@ namespace svt { namespace table ::rtl::OUString TableControl::GetAccessibleObjectName( AccessibleTableControlObjType eObjType, sal_Int32 _nRow, sal_Int32 _nCol) const { ::rtl::OUString aRetText; + //Window* pWin; switch( eObjType ) { case TCTYPE_GRIDCONTROL: @@ -255,7 +263,7 @@ namespace svt { namespace table aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ColumnHeaderBar" ) ); break; case TCTYPE_TABLECELL: - aRetText = GetCellContent(_nRow, _nCol); + aRetText = GetRowName(_nRow); break; case TCTYPE_ROWHEADERCELL: aRetText = GetRowName(_nRow); @@ -328,20 +336,23 @@ namespace svt { namespace table // ----------------------------------------------------------------------------- -::rtl::OUString TableControl::GetCellContent( sal_Int32 _nRowPos, sal_Int32 _nColPos) const +::com::sun::star::uno::Any TableControl::GetCellContent( sal_Int32 _nRowPos, sal_Int32 _nColPos) const { - ::rtl::OUString cellContent = ::rtl::OUString::createFromAscii(""); - std::vector<std::vector<rtl::OUString> >& aTableContent = GetModel()->getCellContent(); + ::com::sun::star::uno::Any cellContent(::com::sun::star::uno::Any(::rtl::OUString::createFromAscii(""))); + std::vector<std::vector< ::com::sun::star::uno::Any > >& aTableContent = GetModel()->getCellContent(); if(&aTableContent) - { - std::vector<rtl::OUString>& aRowContent = aTableContent[_nRowPos]; - if(&aRowContent) - cellContent = aRowContent[_nColPos]; - } + cellContent = aTableContent[_nRowPos][_nColPos]; return cellContent; } // ----------------------------------------------------------------------------- +::rtl::OUString TableControl::GetAccessibleCellText( sal_Int32 _nRowPos, sal_Int32 _nColPos) +{ + ::com::sun::star::uno::Any cellContent = GetCellContent(_nRowPos, _nColPos); + return m_pImpl->convertToString(cellContent); +} +// ----------------------------------------------------------------------------- + void TableControl::FillAccessibleStateSet( ::utl::AccessibleStateSetHelper& rStateSet, AccessibleTableControlObjType eObjType ) const @@ -374,10 +385,6 @@ void TableControl::FillAccessibleStateSet( break; case TCTYPE_TABLECELL: { - //sal_Int32 nRow = GetCurRow(); - //sal_uInt16 nColumn = GetCurColumnId(); - //if ( IsFieldVisible(nRow,nColumn) ) - // rStateSet.AddState( AccessibleStateType::VISIBLE ); rStateSet.AddState( AccessibleStateType::TRANSIENT ); rStateSet.AddState( AccessibleStateType::SELECTABLE); if( GetSelectedRowCount()>0) @@ -516,25 +523,56 @@ void TableControl::commitGridControlEvent( sal_Int16 _nEventId, const Any& _rNew Rectangle TableControl::calcHeaderRect(sal_Bool _bIsColumnBar,BOOL _bOnScreen) { (void)_bOnScreen; - Rectangle aRectTable, aRectTableWithHeaders; - m_pImpl->impl_getAllVisibleDataCellArea(aRectTable); - m_pImpl->impl_getAllVisibleCellsArea(aRectTableWithHeaders); - Size aSizeTable(aRectTable.GetSize()); - Size aSizeTableWithHeaders(aRectTableWithHeaders.GetSize()); - if(_bIsColumnBar) - return Rectangle(aRectTableWithHeaders.TopLeft(),Size(aSizeTableWithHeaders.Width()-aSizeTable.Width(), aSizeTableWithHeaders.Height())); - else - return Rectangle(aRectTableWithHeaders.TopLeft(),Size(aSizeTableWithHeaders.Width(), aSizeTableWithHeaders.Height()-aSizeTable.Height())); + return m_pImpl->calcHeaderRect(_bIsColumnBar); } // ----------------------------------------------------------------------------- Rectangle TableControl::calcTableRect(BOOL _bOnScreen) { (void)_bOnScreen; - Rectangle aRect; - m_pImpl->impl_getAllVisibleDataCellArea(aRect); - return aRect; + return m_pImpl->calcTableRect(); +} +//-------------------------------------------------------------------- +::com::sun::star::uno::Sequence< sal_Int32 >& TableControl::getColumnsForTooltip() +{ + return m_nCols; +} +//-------------------------------------------------------------------- +::com::sun::star::uno::Sequence< ::rtl::OUString >& TableControl::getTextForTooltip() +{ + return m_aText; +} +//-------------------------------------------------------------------- +void TableControl::setTooltip(const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aText, const ::com::sun::star::uno::Sequence< sal_Int32 >& nCols ) +{ + m_aText = aText; + m_nCols = nCols; +} +// ----------------------------------------------------------------------- +void TableControl::selectionChanged(bool _bChanged) +{ + m_bSelectionChanged = _bChanged; +} +// ----------------------------------------------------------------------- +IMPL_LINK( TableControl, ImplSelectHdl, void*, EMPTYARG ) +{ + Select(); + return 1; +} +IMPL_LINK( TableControl, ImplMouseButtonDownHdl, MouseEvent*, pData ) +{ + CallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONDOWN, pData ); + return 1; +} +IMPL_LINK( TableControl, ImplMouseButtonUpHdl, MouseEvent*, pData ) +{ + CallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONUP, pData ); + return 1; +} +// ----------------------------------------------------------------------- +void TableControl::Select() +{ + ImplCallEventListenersAndHandler( VCLEVENT_TABLEROW_SELECT, m_aSelectHdl, this ); } - //........................................................................ }} // namespace svt::table //........................................................................ diff --git a/svtools/source/table/tablecontrol_impl.cxx b/svtools/source/table/tablecontrol_impl.cxx index aacfc28d05be..1526dbdb778d 100644 --- a/svtools/source/table/tablecontrol_impl.cxx +++ b/svtools/source/table/tablecontrol_impl.cxx @@ -33,9 +33,13 @@ #include "tablecontrol_impl.hxx" #include "tablegeometry.hxx" #include "svtools/table/tabledatawindow.hxx" - +#include <com/sun/star/awt/XControl.hpp> #include <vcl/scrbar.hxx> #include <vcl/seleng.hxx> +#include <rtl/ref.hxx> +#include <toolkit/awt/vclxwindow.hxx> +#include <vcl/image.hxx> +#include <com/sun/star/graphic/XGraphic.hpp> #include <functional> #include <stdlib.h> @@ -98,22 +102,22 @@ namespace svt { namespace table { return false; } - virtual void setRowHeaders(bool _bRowHeaders) + virtual void setRowHeaders(bool _bRowHeaders) { (void)_bRowHeaders; } - virtual void setColumnHeaders(bool _bColumnHeaders) - { - (void)_bColumnHeaders; - } - void setColumnCount(TableSize _nColCount) - { - (void) _nColCount; - } - void setRowCount(TableSize _nRowCount) + virtual void setColumnHeaders(bool _bColumnHeaders) { - (void)_nRowCount; + (void)_bColumnHeaders; } + void setColumnCount(TableSize _nColCount) + { + (void) _nColCount; + } + void setRowCount(TableSize _nRowCount) + { + (void)_nRowCount; + } virtual bool isCellEditable( ColPos col, RowPos row ) const { (void)col; @@ -166,39 +170,83 @@ namespace svt { namespace table { return 0; } - virtual ScrollbarVisibility getVerticalScrollbarVisibility(int overAllHeight, int actHeight) const - { - (void)overAllHeight; - (void)actHeight; - return ScrollbarShowNever; - } - virtual ScrollbarVisibility getHorizontalScrollbarVisibility(int overAllWidth, int actWidth) const - { - (void)overAllWidth; - (void)actWidth; - return ScrollbarShowNever; - } - virtual void setCellContent(std::vector<std::vector<rtl::OUString> > pCellEntryType) - { - (void)pCellEntryType; - } - virtual std::vector<std::vector<rtl::OUString> >& getCellContent() + virtual ScrollbarVisibility getVerticalScrollbarVisibility(int , int ) const { - return *( new std::vector<std::vector<rtl::OUString> >); + return ScrollbarShowNever; } - virtual void setRowHeaderName(std::vector<rtl::OUString> pCellEntryType) + virtual ScrollbarVisibility getHorizontalScrollbarVisibility(int , int ) const { - (void)pCellEntryType; + return ScrollbarShowNever; } - virtual std::vector<rtl::OUString>& getRowHeaderName() - { - aRowHeaderNames.clear(); - aRowHeaderNames.push_back(rtl::OUString::createFromAscii("")); - return aRowHeaderNames; - } - - private: - std::vector<rtl::OUString> aRowHeaderNames; + virtual bool hasVerticalScrollbar() + { + return false; + } + virtual bool hasHorizontalScrollbar() + { + return false; + } + virtual void setCellContent(const std::vector<std::vector< ::com::sun::star::uno::Any > >& ) + { + } + virtual ::com::sun::star::util::Color getLineColor() + { + return 0; + } + virtual void setLineColor(::com::sun::star::util::Color ) + { + } + virtual ::com::sun::star::util::Color getHeaderBackgroundColor() + { + return -1; + } + virtual void setHeaderBackgroundColor(::com::sun::star::util::Color ) + { + } + virtual ::com::sun::star::util::Color getTextColor() + { + return 0; + } + virtual void setTextColor(::com::sun::star::util::Color ) + { + } + virtual ::com::sun::star::util::Color getOddRowBackgroundColor() + { + return -1; + } + virtual void setOddRowBackgroundColor(::com::sun::star::util::Color ) + { + } + virtual ::com::sun::star::style::VerticalAlignment getVerticalAlign() + { + return com::sun::star::style::VerticalAlignment(0); + } + virtual void setVerticalAlign(com::sun::star::style::VerticalAlignment ) + { + } + virtual ::com::sun::star::util::Color getEvenRowBackgroundColor() + { + return -1; + } + virtual void setEvenRowBackgroundColor(::com::sun::star::util::Color ) + { + } + virtual std::vector<std::vector< ::com::sun::star::uno::Any > >& getCellContent() + { + return m_aCellContent; + } + virtual void setRowHeaderName(const std::vector<rtl::OUString>& ) + { + } + virtual std::vector<rtl::OUString>& getRowHeaderName() + { + aRowHeaderNames.clear(); + aRowHeaderNames.push_back(rtl::OUString::createFromAscii("")); + return aRowHeaderNames; + } + private: + std::vector<rtl::OUString> aRowHeaderNames; + std::vector<std::vector< ::com::sun::star::uno::Any > > m_aCellContent; }; @@ -222,8 +270,8 @@ namespace svt { namespace table :m_rTable( _rTable ) ,m_nSuspendFlags( _nSuspendFlags ) { - DBG_ASSERT( ( m_rTable.m_nRequiredInvariants & m_nSuspendFlags ) == m_nSuspendFlags, - "SuspendInvariants: cannot suspend what is already suspended!" ); + //DBG_ASSERT( ( m_rTable.m_nRequiredInvariants & m_nSuspendFlags ) == m_nSuspendFlags, + // "SuspendInvariants: cannot suspend what is already suspended!" ); const_cast< TableControl_Impl& >( m_rTable ).m_nRequiredInvariants &= ~m_nSuspendFlags; } ~SuspendInvariants() @@ -303,7 +351,7 @@ namespace svt { namespace table // m_nColHeaderHeightPixel consistent with the model's value? { TableMetrics nHeaderHeight = m_pModel->hasColumnHeaders() ? m_pModel->getColumnHeaderHeight() : 0; - nHeaderHeight = m_rAntiImpl.LogicToPixel( Size( 0, nHeaderHeight ), MAP_100TH_MM ).Height(); + nHeaderHeight = m_rAntiImpl.LogicToPixel( Size( 0, nHeaderHeight ), MAP_APPFONT ).Height(); if ( nHeaderHeight != m_nColHeaderHeightPixel ) return "column header heights are inconsistent!"; } @@ -312,7 +360,7 @@ namespace svt { namespace table if ( !isDummyModel ) { TableMetrics nRowHeight = m_pModel->getRowHeight(); - nRowHeight = m_rAntiImpl.LogicToPixel( Size( 0, nRowHeight ), MAP_100TH_MM ).Height(); + nRowHeight = m_rAntiImpl.LogicToPixel( Size( 0, nRowHeight ), MAP_APPFONT).Height(); if ( nRowHeight != m_nRowHeightPixel ) return "row heights are inconsistent!"; } @@ -320,13 +368,12 @@ namespace svt { namespace table // m_nRowHeaderWidthPixel consistent with the model's value? { TableMetrics nHeaderWidth = m_pModel->hasRowHeaders() ? m_pModel->getRowHeaderWidth() : 0; - nHeaderWidth = m_rAntiImpl.LogicToPixel( Size( nHeaderWidth, 0 ), MAP_100TH_MM ).Width(); + nHeaderWidth = m_rAntiImpl.LogicToPixel( Size( nHeaderWidth, 0 ), MAP_APPFONT ).Width(); if ( nHeaderWidth != m_nRowHeaderWidthPixel ) return "row header widths are inconsistent!"; } // TODO: check m_aColumnWidthsPixel and m_aAccColumnWidthsPixel - if ( m_nCursorHidden < 0 ) return "invalid hidden count for the cursor!"; @@ -369,30 +416,33 @@ namespace svt { namespace table ,m_pModel ( new EmptyTableModel ) ,m_pInputHandler ( ) ,m_nRowHeightPixel ( 15 ) - ,m_nColHeaderHeightPixel( 0 ) + ,m_nColHeaderHeightPixel( 0 ) ,m_nRowHeaderWidthPixel ( 0 ) ,m_nColumnCount ( 0 ) ,m_nRowCount ( 0 ) ,m_nCurColumn ( COL_INVALID ) ,m_nCurRow ( ROW_INVALID ) ,m_nLeftColumn ( 0 ) - ,m_nTopRow ( 0 ) + ,m_nTopRow ( 0 ) ,m_nCursorHidden ( 1 ) ,m_pDataWindow ( new TableDataWindow( *this ) ) - ,m_pVScroll ( NULL ) + ,m_pVScroll ( NULL ) ,m_pHScroll ( NULL ) ,m_pScrollCorner ( NULL ) - ,m_pSelEngine ( ) - ,m_nRowSelected ( ) - ,m_pTableFunctionSet ( new TableFunctionSet(this ) ) - ,m_nAnchor (-1 ) + ,m_pSelEngine ( ) + ,m_nRowSelected ( ) + ,m_pTableFunctionSet ( new TableFunctionSet(this ) ) + ,m_nAnchor (-1 ) + ,m_bResizing ( false ) + ,m_nResizingColumn ( 0 ) + ,m_bResizingGrid ( false ) #if DBG_UTIL ,m_nRequiredInvariants ( INV_SCROLL_POSITION ) #endif { DBG_CTOR( TableControl_Impl, TableControl_Impl_checkInvariants ); - m_pSelEngine = new SelectionEngine(m_pDataWindow, m_pTableFunctionSet); - m_pSelEngine->SetSelectionMode(SINGLE_SELECTION); + m_pSelEngine = new SelectionEngine(m_pDataWindow, m_pTableFunctionSet); + m_pSelEngine->SetSelectionMode(SINGLE_SELECTION); m_pDataWindow->SetPosPixel( Point( 0, 0 ) ); m_pDataWindow->Show(); } @@ -427,14 +477,10 @@ namespace svt { namespace table TempHideCursor aHideCursor( *this ); - // TODO: revoke as table listener from the model - m_pModel = _pModel; - if ( !m_pModel ) + if ( !m_pModel) m_pModel.reset( new EmptyTableModel ); - // TODO: register as table listener - //m_pModel->addTableModelListener(PTableModelListener(m_pTableModelListener)); m_nCurRow = ROW_INVALID; m_nCurColumn = COL_INVALID; @@ -504,11 +550,11 @@ namespace svt { namespace table m_pInputHandler.reset(); m_nColumnCount = m_nRowCount = 0; - m_nRowHeightPixel = m_rAntiImpl.LogicToPixel( Size( 0, m_pModel->getRowHeight() ), MAP_100TH_MM ).Height(); - if ( m_pModel->hasColumnHeaders() ) - m_nColHeaderHeightPixel = m_rAntiImpl.LogicToPixel( Size( 0, m_pModel->getColumnHeaderHeight() ), MAP_100TH_MM ).Height(); + m_nRowHeightPixel = m_rAntiImpl.LogicToPixel( Size( 0, m_pModel->getRowHeight() ), MAP_APPFONT ).Height(); + if ( m_pModel->hasColumnHeaders() ) + m_nColHeaderHeightPixel = m_rAntiImpl.LogicToPixel( Size( 0, m_pModel->getColumnHeaderHeight() ), MAP_APPFONT ).Height(); if ( m_pModel->hasRowHeaders() ) - m_nRowHeaderWidthPixel = m_rAntiImpl.LogicToPixel( Size( m_pModel->getRowHeaderWidth(), 0 ), MAP_100TH_MM ).Width(); + m_nRowHeaderWidthPixel = m_rAntiImpl.LogicToPixel( Size( m_pModel->getRowHeaderWidth(), 0 ), MAP_APPFONT).Width(); impl_ni_updateColumnWidths(); @@ -529,34 +575,116 @@ namespace svt { namespace table return; TableSize colCount = m_pModel->getColumnCount(); + m_aColumnWidthsPixel.reserve( colCount ); m_aAccColumnWidthsPixel.reserve( colCount ); - long accumulatedPixelWidth = 0; - for ( ColPos col = 0; col < colCount; ++col ) + if(colCount>0) { - PColumnModel pColumn = m_pModel->getColumnModel( col ); - DBG_ASSERT( !!pColumn, "TableControl_Impl::impl_ni_updateColumnWidths: invalid column returned by the model!" ); - if ( !pColumn ) - continue; - - TableMetrics colWidth = pColumn->getWidth(); - DBG_ASSERT( ( colWidth == COLWIDTH_FIT_TO_VIEW ) || ( colWidth > 0 ), - "TableControl_Impl::impl_ni_updateColumnWidths: invalid column width!" ); - - long pixelWidth = 0; - if ( colWidth == COLWIDTH_FIT_TO_VIEW ) + std::vector<sal_Int32> aPrePixelWidths(0); + long accumulatedPixelWidth = 0; + int lastResizableCol = -1; + double gridWidth = m_rAntiImpl.GetOutputSizePixel().Width(); + if(m_pModel->hasRowHeaders()) + { + TableMetrics rowHeaderWidth = m_pModel->getRowHeaderWidth(); + gridWidth-= m_rAntiImpl.LogicToPixel( Size( rowHeaderWidth, 0 ), MAP_APPFONT ).Width(); + } + if(m_pModel->hasVerticalScrollbar()) { - // TODO - DBG_ERROR( "TableControl_Impl::impl_ni_updateColumnWidths: COLWIDTH_FIT_TO_VIEW not implemented, yet!" ); + sal_Int32 scrollbarWidth = m_rAntiImpl.GetSettings().GetStyleSettings().GetScrollBarSize(); + gridWidth-=scrollbarWidth; + } + double colWidthsSum = 0.0; + double colWithoutFixedWidthsSum = 0.0; + double minColWithoutFixedSum = 0.0; + for ( ColPos col = 0; col < colCount; ++col ) + { + PColumnModel pColumn = m_pModel->getColumnModel( col ); + DBG_ASSERT( !!pColumn, "TableControl_Impl::impl_ni_updateColumnWidths: invalid column returned by the model!" ); + if ( !pColumn ) + continue; + TableMetrics colWidth = 0; + TableMetrics colPrefWidth = pColumn->getPreferredWidth(); + bool bResizable = pColumn->isResizable(); + if(pColumn->getMinWidth() == 0 && bResizable) + { + pColumn->setMinWidth(1); + minColWithoutFixedSum+=m_rAntiImpl.LogicToPixel( Size( 1, 0 ), MAP_APPFONT ).Width(); + } + if(pColumn->getMaxWidth() == 0 && bResizable) + pColumn->setMaxWidth(m_rAntiImpl.LogicToPixel( Size( (int)gridWidth, 0 ), MAP_APPFONT ).Width()); + if( colPrefWidth != 0) + { + if(m_bResizingGrid) + { + colWidth = pColumn->getWidth(); + pColumn->setPreferredWidth(0); + } + else + { + colWidth = colPrefWidth; + pColumn->setWidth(colPrefWidth); + } + } + else + colWidth = pColumn->getWidth(); + long pixelWidth = m_rAntiImpl.LogicToPixel( Size( colWidth, 0 ), MAP_APPFONT ).Width(); + if(bResizable && colPrefWidth == 0) + { + colWithoutFixedWidthsSum+=pixelWidth; + lastResizableCol = col; + } + colWidthsSum+=pixelWidth; + aPrePixelWidths.push_back(pixelWidth); + } + double gridWidthWithoutFixed = gridWidth - colWidthsSum + colWithoutFixedWidthsSum; + double scalingFactor = 1.0; + if(m_bResizingGrid) + { + if(gridWidthWithoutFixed > (minColWithoutFixedSum+colWidthsSum - colWithoutFixedWidthsSum)) + scalingFactor = gridWidthWithoutFixed/colWithoutFixedWidthsSum; } else { - pixelWidth = m_rAntiImpl.LogicToPixel( Size( colWidth, 0 ), MAP_100TH_MM ).Width(); + if(colWidthsSum < gridWidthWithoutFixed) + { + if(colWithoutFixedWidthsSum>0) + scalingFactor = gridWidthWithoutFixed/colWithoutFixedWidthsSum; + } + } + for ( ColPos i = 0; i < colCount; ++i ) + { + PColumnModel pColumn = m_pModel->getColumnModel( i ); + DBG_ASSERT( !!pColumn, "TableControl_Impl::impl_ni_updateColumnWidths: invalid column returned by the model!" ); + if ( !pColumn ) + continue; + if(pColumn->isResizable() && pColumn->getPreferredWidth() == 0) + { + aPrePixelWidths[i]*=scalingFactor; + TableMetrics logicColWidth = m_rAntiImpl.PixelToLogic( Size( aPrePixelWidths[i], 0 ), MAP_APPFONT ).Width(); + pColumn->setWidth(logicColWidth); + } + m_aColumnWidthsPixel.push_back( aPrePixelWidths[i] ); + m_aAccColumnWidthsPixel.push_back( accumulatedPixelWidth += aPrePixelWidths[i] ); + } + if(gridWidth > m_aAccColumnWidthsPixel[colCount-1]) + { + if(lastResizableCol >= 0) + { + PColumnModel pColumn = m_pModel->getColumnModel(lastResizableCol); + m_aColumnWidthsPixel[lastResizableCol]+=gridWidth-m_aAccColumnWidthsPixel[colCount-1]; + TableMetrics logicColWidth1 = m_rAntiImpl.PixelToLogic( Size( m_aColumnWidthsPixel[lastResizableCol], 0 ), MAP_APPFONT ).Width(); + pColumn->setWidth(logicColWidth1); + while(lastResizableCol < colCount) + { + if(lastResizableCol == 0) + m_aAccColumnWidthsPixel[0] = m_aColumnWidthsPixel[lastResizableCol]; + else + m_aAccColumnWidthsPixel[lastResizableCol]=m_aAccColumnWidthsPixel[lastResizableCol-1]+m_aColumnWidthsPixel[lastResizableCol]; + ++lastResizableCol; + } + } } - - m_aColumnWidthsPixel.push_back( pixelWidth ); - - m_aAccColumnWidthsPixel.push_back( accumulatedPixelWidth += pixelWidth ); } } @@ -678,6 +806,13 @@ namespace svt { namespace table Rectangle aDataCellPlayground( Point( 0, 0 ), m_rAntiImpl.GetOutputSizePixel() ); aDataCellPlayground.Left() = m_nRowHeaderWidthPixel; aDataCellPlayground.Top() = m_nColHeaderHeightPixel; + m_nRowCount = m_pModel->getRowCount(); + m_nColumnCount = m_pModel->getColumnCount(); + + if(m_aAccColumnWidthsPixel.empty()) + { + impl_ni_updateColumnWidths(); + } // do we need a vertical scrollbar? bool bFirstRoundVScrollNeed = false; @@ -709,15 +844,6 @@ namespace svt { namespace table aDataCellPlayground.Right() -= nScrollbarMetrics; } } - else - { - Size regionWithoutHeader = m_rAntiImpl.PixelToLogic(Size(aDataCellPlayground.Right() - aDataCellPlayground.Left(),0),MAP_100TH_MM); - TableMetrics nColWidth = regionWithoutHeader.Width()/m_nColumnCount; - for ( ColPos col = 0; col < m_nColumnCount; ++col ) - m_pModel->getColumnModel(col)->setWidth(nColWidth); - m_rAntiImpl.SetModel(m_pModel); - } - // create or destroy the vertical scrollbar, as needed lcl_updateScrollbar( m_rAntiImpl, @@ -780,6 +906,11 @@ namespace svt { namespace table m_pScrollCorner->SetPosPixel( Point( aDataCellPlayground.Right() + 1, aDataCellPlayground.Bottom() + 1 ) ); m_pScrollCorner->Show(); } + else if(bHaveScrollCorner && bNeedScrollCorner) + { + m_pScrollCorner->SetPosPixel( Point( aDataCellPlayground.Right() + 1, aDataCellPlayground.Bottom() + 1 ) ); + m_pScrollCorner->Show(); + } // resize the data window m_pDataWindow->SetSizePixel( Size( @@ -792,10 +923,26 @@ namespace svt { namespace table void TableControl_Impl::onResize() { DBG_CHECK_ME(); - impl_ni_updateScrollbars(); - //Rectangle aAllCells; - // impl_getAllVisibleCellsArea( aAllCells ); - //m_pSelEngine->SetVisibleArea(aAllCells); + if(m_nRowCount != 0) + { + if(m_nColumnCount != 0) + { + if(m_bResizingGrid) + impl_ni_updateColumnWidths(); + invalidateRows(); + m_bResizingGrid = true; + } + } + else + { + //In the case that column headers are defined but data hasn't yet been set, + //only column headers will be shown + if(m_pModel->hasColumnHeaders()) + if(m_nColHeaderHeightPixel>1) + m_pDataWindow->SetSizePixel( m_rAntiImpl.GetOutputSizePixel()); + if(m_nColumnCount != 0) + impl_ni_updateScrollbars(); + } } //-------------------------------------------------------------------- @@ -805,7 +952,6 @@ namespace svt { namespace table if ( !getModel() ) return; - PTableRenderer pRenderer = getModel()->getRenderer(); DBG_ASSERT( !!pRenderer, "TableDataWindow::Paint: invalid renderer!" ); if ( !pRenderer ) @@ -813,21 +959,28 @@ namespace svt { namespace table // our current style settings, to be passed to the renderer const StyleSettings& rStyle = m_rAntiImpl.GetSettings().GetStyleSettings(); - + m_nRowCount = m_pModel->getRowCount(); + TableSize nVisibleRows = impl_getVisibleRows(true); + TableSize nActualRows = m_nRowCount; + if(m_nRowCount>nVisibleRows) + nActualRows = nVisibleRows; // the area occupied by all (at least partially) visible cells, including // headers Rectangle aAllCellsWithHeaders; impl_getAllVisibleCellsArea( aAllCellsWithHeaders ); - m_nRowCount = m_pModel->getRowCount(); // ............................ // draw the header column area - if ( getModel()->hasColumnHeaders() ) + if ( m_pModel->hasColumnHeaders() ) { TableRowGeometry aHeaderRow( *this, Rectangle( Point( 0, 0 ), aAllCellsWithHeaders.BottomRight() ), ROW_COL_HEADERS ); + Rectangle aColRect(aHeaderRow.getRect()); + //to avoid double lines when scrolling horizontally + if(m_nLeftColumn != 0) + --aColRect.Left(); pRenderer->PaintHeaderArea( - *m_pDataWindow, aHeaderRow.getRect(), true, false, rStyle + *m_pDataWindow, aColRect, true, false, rStyle ); // Note that strictly, aHeaderRow.getRect() also contains the intersection between column // and row header area. However, below we go to paint this intersection, again, @@ -850,14 +1003,18 @@ namespace svt { namespace table // the area occupied by the row header, if any Rectangle aRowHeaderArea; - if ( getModel()->hasRowHeaders() ) + if ( m_pModel->hasRowHeaders() ) { aRowHeaderArea = aAllCellsWithHeaders; aRowHeaderArea.Right() = m_nRowHeaderWidthPixel - 1; - aRowHeaderArea.Bottom() = m_nRowHeightPixel * m_nRowCount + m_nColHeaderHeightPixel - 1; - pRenderer->PaintHeaderArea( - *m_pDataWindow, aRowHeaderArea, false, true, rStyle - ); + if(m_nTopRow+nActualRows>m_nRowCount) + aRowHeaderArea.Bottom() = m_nRowHeightPixel * (nActualRows -1)+ m_nColHeaderHeightPixel - 1; + else + aRowHeaderArea.Bottom() = m_nRowHeightPixel * nActualRows + m_nColHeaderHeightPixel - 1; + //to avoid double lines when scrolling vertically + if(m_nTopRow != 0) + --aRowHeaderArea.Top(); + pRenderer->PaintHeaderArea(*m_pDataWindow, aRowHeaderArea, false, true, rStyle); // Note that strictly, aRowHeaderArea also contains the intersection between column // and row header area. However, below we go to paint this intersection, again, // so this hopefully doesn't hurt if we already paint it here. @@ -866,8 +1023,15 @@ namespace svt { namespace table { TableCellGeometry aIntersection( *this, Rectangle( Point( 0, 0 ), aAllCellsWithHeaders.BottomRight() ), COL_ROW_HEADERS, ROW_COL_HEADERS ); + Rectangle aInters(aIntersection.getRect()); + //to avoid double line when scrolling vertically + if( m_nTopRow != 0 ) + { + --aInters.Top(); + --aInters.Bottom(); + } pRenderer->PaintHeaderArea( - *m_pDataWindow, aIntersection.getRect(), true, true, rStyle + *m_pDataWindow, aInters, true, true, rStyle ); } } @@ -880,113 +1044,69 @@ namespace svt { namespace table // paint all rows Rectangle aAllDataCellsArea; impl_getAllVisibleDataCellArea( aAllDataCellsArea ); - - //get the vector, which contains row vectors, each containing the data for the cells in this row - std::vector<std::vector<rtl::OUString> >& aCellContent = m_pModel->getCellContent(); - //if the vector is empty, fill it with empty data, so the table can be painted - if(aCellContent.empty()) - { - std::vector<rtl::OUString> emptyCells; - while(m_nRowCount!=0) - { - aCellContent.push_back(emptyCells); - --m_nRowCount; - } - } - std::vector<std::vector<rtl::OUString> >::iterator it = aCellContent.begin()+m_nTopRow; - //get the vector, which contains the row header titles - std::vector<rtl::OUString>& aRowHeaderContent = m_pModel->getRowHeaderName(); - ::std::vector<rtl::OUString>::iterator itRowName = aRowHeaderContent.begin(); - - if(m_pModel->hasRowHeaders()) - { - aRowHeaderContent = m_pModel->getRowHeaderName(); - //if the vector is empty, fill it with empty strings, so the table can be painted - if(aRowHeaderContent.empty()) - { - while(m_nRowCount!=0) - { - aRowHeaderContent.push_back(rtl::OUString::createFromAscii("")); - --m_nRowCount; - } - } - itRowName = aRowHeaderContent.begin()+m_nTopRow; - } + ::std::vector< std::vector< ::com::sun::star::uno::Any > >& aCellContent = m_pModel->getCellContent(); for ( TableRowGeometry aRowIterator( *this, aAllCellsWithHeaders, getTopRow() ); aRowIterator.isValid(); aRowIterator.moveDown() ) { if ( _rUpdateRect.GetIntersection( aRowIterator.getRect() ).IsEmpty() ) - { - if(m_pModel->hasRowHeaders()) - ++itRowName; - ++it; continue; - } bool isActiveRow = ( aRowIterator.getRow() == getCurRow() ); bool isSelectedRow = false; if(!m_nRowSelected.empty()) { for(std::vector<RowPos>::iterator itSel=m_nRowSelected.begin(); - itSel!=m_nRowSelected.end();++itSel) + itSel!=m_nRowSelected.end();++itSel) { if(*itSel == aRowIterator.getRow()) isSelectedRow = true; } } - std::vector<rtl::OUString> aCellData; - if(it != aCellContent.end()) - { - aCellData = *it; - ++it; - } - ::std::vector<rtl::OUString>::iterator iter = aCellData.begin()+m_nLeftColumn; - + Rectangle aRect = aRowIterator.getRect().GetIntersection( aAllDataCellsArea ); + //to avoid double lines + if( aRowIterator.getRow() != 0 ) + --aRect.Top(); + if(m_nLeftColumn != 0) + --aRect.Left(); // give the redenderer a chance to prepare the row pRenderer->PrepareRow( aRowIterator.getRow(), isActiveRow, isSelectedRow, - *m_pDataWindow, aRowIterator.getRect().GetIntersection( aAllDataCellsArea ), rStyle ); + *m_pDataWindow, aRect, rStyle ); // paint the row header if ( m_pModel->hasRowHeaders() ) { - rtl::OUString rowHeaderName; - if(itRowName != aRowHeaderContent.end()) - { - rowHeaderName = *itRowName; - ++itRowName; - } Rectangle aCurrentRowHeader( aRowHeaderArea.GetIntersection( aRowIterator.getRect() ) ); + rtl::OUString rowHeaderName = m_pModel->getRowHeaderName()[aRowIterator.getRow()]; pRenderer->PaintRowHeader( isActiveRow, isSelectedRow, *m_pDataWindow, aCurrentRowHeader, rStyle, rowHeaderName ); } if ( !colCount ) continue; - // paint all cells in this row for ( TableCellGeometry aCell( aRowIterator, m_nLeftColumn ); aCell.isValid(); aCell.moveRight() ) { - // if ( _rUpdateRect.GetIntersection( aCell.getRect() ).IsEmpty() ) - // continue; - - //bool isActiveCell = isActiveRow && ( aCell.getColumn() == getCurColumn() ); bool isSelectedColumn = false; - rtl::OUString cellData; - if(aCellData.empty()) - cellData=rtl::OUString::createFromAscii(""); - else if(iter != aCellData.end()) + ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphic >xGraphic; + ::com::sun::star::uno::Any rCellData = aCellContent[aRowIterator.getRow()][aCell.getColumn()]; + if(rCellData>>=xGraphic) + { + Image* pImage = new Image(xGraphic); + if(pImage!=NULL) + pRenderer->PaintCellImage( aCell.getColumn(), isSelectedRow || isSelectedColumn, isActiveRow, + *m_pDataWindow, aCell.getRect(), rStyle, pImage ); + } + else { - cellData = *iter; - ++iter; + ::rtl::OUString sContent = convertToString(rCellData); + pRenderer->PaintCellString( aCell.getColumn(), isSelectedRow || isSelectedColumn, isActiveRow, + *m_pDataWindow, aCell.getRect(), rStyle, sContent ); } - pRenderer->PaintCell( aCell.getColumn(), isSelectedRow || isSelectedColumn, isActiveRow, - *m_pDataWindow, aCell.getRect(), rStyle, cellData ); - } + } } } - //-------------------------------------------------------------------- void TableControl_Impl::hideCursor() { @@ -1016,70 +1136,70 @@ namespace svt { namespace table switch ( _eAction ) { case cursorDown: - if(m_pSelEngine->GetSelectionMode() == SINGLE_SELECTION) + if(m_pSelEngine->GetSelectionMode() == SINGLE_SELECTION) + { + //if other rows already selected, deselect them + if(m_nRowSelected.size()>0) { - //if other rows already selected, deselect them - if(m_nRowSelected.size()>0) - { - for(std::vector<RowPos>::iterator it=m_nRowSelected.begin(); - it!=m_nRowSelected.end();++it) - { - invalidateSelectedRow(*it,rCells); - m_pDataWindow->Invalidate(rCells); - } - m_nRowSelected.clear(); - } - if(m_nCurRow < m_nRowCount-1) + for(std::vector<RowPos>::iterator it=m_nRowSelected.begin(); + it!=m_nRowSelected.end();++it) { - ++m_nCurRow; - m_nRowSelected.push_back(m_nCurRow); + invalidateSelectedRegion(*it, *it, rCells); } - else - m_nRowSelected.push_back(m_nCurRow); - invalidateSelectedRow(m_nCurRow, rCells); - ensureVisible(m_nCurColumn,m_nCurRow,false); - bSuccess = true; + m_nRowSelected.clear(); } - else + if(m_nCurRow < m_nRowCount-1) { - if ( m_nCurRow < m_nRowCount - 1 ) - bSuccess = goTo( m_nCurColumn, m_nCurRow + 1 ); + ++m_nCurRow; + m_nRowSelected.push_back(m_nCurRow); } + else + m_nRowSelected.push_back(m_nCurRow); + invalidateSelectedRegion(m_nCurRow, m_nCurRow, rCells); + ensureVisible(m_nCurColumn,m_nCurRow,false); + m_rAntiImpl.selectionChanged(true); + bSuccess = true; + } + else + { + if ( m_nCurRow < m_nRowCount - 1 ) + bSuccess = goTo( m_nCurColumn, m_nCurRow + 1 ); + } break; case cursorUp: - if(m_pSelEngine->GetSelectionMode() == SINGLE_SELECTION) + if(m_pSelEngine->GetSelectionMode() == SINGLE_SELECTION) + { + if(m_nRowSelected.size()>0) { - if(m_nRowSelected.size()>0) - { - for(std::vector<RowPos>::iterator it=m_nRowSelected.begin(); + for(std::vector<RowPos>::iterator it=m_nRowSelected.begin(); it!=m_nRowSelected.end();++it) - { - invalidateSelectedRow(*it,rCells); - m_pDataWindow->Invalidate(rCells); - } - m_nRowSelected.clear(); - } - if(m_nCurRow>0) { - --m_nCurRow; - m_nRowSelected.push_back(m_nCurRow); - invalidateSelectedRow(m_nCurRow, rCells); + invalidateSelectedRegion(*it, *it, rCells); } - else - { - m_nRowSelected.push_back(m_nCurRow); - invalidateSelectedRow(m_nCurRow, rCells); - } - ensureVisible(m_nCurColumn,m_nCurRow,false); - bSuccess = true; + m_nRowSelected.clear(); + } + if(m_nCurRow>0) + { + --m_nCurRow; + m_nRowSelected.push_back(m_nCurRow); + invalidateSelectedRegion(m_nCurRow, m_nCurRow, rCells); } else { - if ( m_nCurRow > 0 ) - bSuccess = goTo( m_nCurColumn, m_nCurRow - 1 ); + m_nRowSelected.push_back(m_nCurRow); + invalidateSelectedRegion(m_nCurRow, m_nCurRow, rCells); } - break; + ensureVisible(m_nCurColumn,m_nCurRow,false); + m_rAntiImpl.selectionChanged(true); + bSuccess = true; + } + else + { + if ( m_nCurRow > 0 ) + bSuccess = goTo( m_nCurColumn, m_nCurRow - 1 ); + } + break; case cursorLeft: if ( m_nCurColumn > 0 ) bSuccess = goTo( m_nCurColumn - 1, m_nCurRow ); @@ -1133,225 +1253,251 @@ namespace svt { namespace table case cursorBottomRight: bSuccess = goTo( m_nColumnCount - 1, m_nRowCount - 1 ); break; - - case cursorSelectRow: + case cursorSelectRow: + { + if(m_pSelEngine->GetSelectionMode() == NO_SELECTION) + return bSuccess = false; + //pos is the position of the current row in the vector of selected rows, if current row is selected + int pos = getRowSelectedNumber(m_nRowSelected, m_nCurRow); + //if current row is selected, it should be deselected, when ALT+SPACE are pressed + if(pos>-1) + { + m_nRowSelected.erase(m_nRowSelected.begin()+pos); + if(m_nRowSelected.empty() && m_nAnchor != -1) + m_nAnchor = -1; + } + //else select the row->put it in the vector + else + m_nRowSelected.push_back(m_nCurRow); + invalidateSelectedRegion(m_nCurRow, m_nCurRow, rCells); + m_rAntiImpl.selectionChanged(true); + bSuccess = true; + } + break; + case cursorSelectRowUp: + { + if(m_pSelEngine->GetSelectionMode() == NO_SELECTION) + return bSuccess = false; + else if(m_pSelEngine->GetSelectionMode() == SINGLE_SELECTION) { - if(m_pSelEngine->GetSelectionMode() == NO_SELECTION) - return bSuccess = false; - //pos is the position of the current row in the vector of selected rows, if current row is selected - int pos = getRowSelectedNumber(m_nRowSelected, m_nCurRow); - //if current row is selected, it should be deselected, when ALT+SPACE are pressed - if(pos>-1) - m_nRowSelected.erase(m_nRowSelected.begin()+pos); - //else select the row->put it in the vector - else - m_nRowSelected.push_back(m_nCurRow); - invalidateSelectedRow(m_nCurRow, rCells); - bSuccess = true; + //if there are other selected rows, deselect them + return false; } - break; - case cursorSelectRowUp: + else { - if(m_pSelEngine->GetSelectionMode() == NO_SELECTION) - return bSuccess = false; - else if(m_pSelEngine->GetSelectionMode() == SINGLE_SELECTION) + //there are other selected rows + if(m_nRowSelected.size()>0) { - //if there are other selected rows, deselect them - return false; - } - else - { - //there are other selected rows - if(m_nRowSelected.size()>0) + //the anchor wasn't set -> a region is not selected, that's why clear all selection + //and select the current row + if(m_nAnchor==-1) { - //the anchor wasn't set -> a region is not selected, that's why clear all selection - //and select the current row - if(m_nAnchor==-1) - { - for(std::vector<RowPos>::iterator it=m_nRowSelected.begin(); + for(std::vector<RowPos>::iterator it=m_nRowSelected.begin(); it!=m_nRowSelected.end();++it) - { - invalidateSelectedRow(*it,rCells); - m_pDataWindow->Invalidate(rCells); - } - m_nRowSelected.clear(); - m_nRowSelected.push_back(m_nCurRow); - invalidateSelectedRow(m_nCurRow, rCells); + { + invalidateSelectedRegion(*it, *it, rCells); } + m_nRowSelected.clear(); + m_nRowSelected.push_back(m_nCurRow); + invalidateSelectedRegion(m_nCurRow, m_nCurRow, rCells); + } + else + { + //a region is already selected, prevRow is last selected row and the row above - nextRow - should be selected + int prevRow = getRowSelectedNumber(m_nRowSelected, m_nCurRow); + int nextRow = getRowSelectedNumber(m_nRowSelected, m_nCurRow-1); + if(prevRow>-1) + { + //if m_nCurRow isn't the upper one, can move up, otherwise not + if(m_nCurRow>0) + m_nCurRow--; + else + return bSuccess = true; + //if nextRow already selected, deselect it, otherwise select it + if(nextRow>-1 && m_nRowSelected[nextRow] == m_nCurRow) + { + m_nRowSelected.erase(m_nRowSelected.begin()+prevRow); + invalidateSelectedRegion(m_nCurRow+1, m_nCurRow+1, rCells); + } + else + { + m_nRowSelected.push_back(m_nCurRow); + invalidateSelectedRegion(m_nCurRow, m_nCurRow, rCells); + } + } else { - //a region is already selected, prevRow is last selected row and the row above - nextRow - should be selected - int prevRow = getRowSelectedNumber(m_nRowSelected, m_nCurRow); - int nextRow = getRowSelectedNumber(m_nRowSelected, m_nCurRow-1); - if(prevRow>-1) + if(m_nCurRow>0) { - //if m_nCurRow isn't the upper one, can move up, otherwise not - if(m_nCurRow>0) - m_nCurRow--; - else - return bSuccess = true; - //if nextRow already selected, deselect it, otherwise select it - if(m_nRowSelected[nextRow] == m_nCurRow) - { - m_nRowSelected.erase(m_nRowSelected.begin()+prevRow); - invalidateSelectedRow(m_nCurRow+1, rCells); - } - else - { - m_nRowSelected.push_back(m_nCurRow); - invalidateSelectedRow(m_nCurRow, rCells); - } + m_nRowSelected.push_back(m_nCurRow); + m_nCurRow--; + m_nRowSelected.push_back(m_nCurRow); + invalidateSelectedRegion(m_nCurRow+1, m_nCurRow, rCells); } } } + } + else + { + //if nothing is selected and the current row isn't the upper one + //select the current and one row above + //otherwise select only the upper row + if(m_nCurRow>0) + { + m_nRowSelected.push_back(m_nCurRow); + m_nCurRow--; + m_nRowSelected.push_back(m_nCurRow); + invalidateSelectedRegion(m_nCurRow+1, m_nCurRow, rCells); + } else { - //if nothing is selected and the current row isn't the upper one - //select the current and one row above - //otherwise select only the upper row - if(m_nCurRow>0) - { - m_nRowSelected.push_back(m_nCurRow); - m_nCurRow--; - m_nRowSelected.push_back(m_nCurRow); - invalidateSelectedRegion(m_nCurRow+1, m_nCurRow, rCells); - } - else - { - m_nRowSelected.push_back(m_nCurRow); - invalidateSelectedRow(m_nCurRow, rCells); - } + m_nRowSelected.push_back(m_nCurRow); + invalidateSelectedRegion(m_nCurRow, m_nCurRow, rCells); } - m_pSelEngine->SetAnchor(TRUE); - m_nAnchor = m_nCurRow; - ensureVisible(m_nCurColumn, m_nCurRow, false); - bSuccess = true; } + m_pSelEngine->SetAnchor(TRUE); + m_nAnchor = m_nCurRow; + ensureVisible(m_nCurColumn, m_nCurRow, false); + m_rAntiImpl.selectionChanged(true); + bSuccess = true; } - break; - case cursorSelectRowDown: + } + break; + case cursorSelectRowDown: + { + if(m_pSelEngine->GetSelectionMode() == NO_SELECTION) + bSuccess = false; + else if(m_pSelEngine->GetSelectionMode() == SINGLE_SELECTION) { - if(m_pSelEngine->GetSelectionMode() == NO_SELECTION) - bSuccess = false; - else if(m_pSelEngine->GetSelectionMode() == SINGLE_SELECTION) - { - bSuccess = false; - } - else + bSuccess = false; + } + else + { + if(m_nRowSelected.size()>0) { - if(m_nRowSelected.size()>0) + //the anchor wasn't set -> a region is not selected, that's why clear all selection + //and select the current row + if(m_nAnchor==-1) { - //the anchor wasn't set -> a region is not selected, that's why clear all selection - //and select the current row - if(m_nAnchor==-1) - { - for(std::vector<RowPos>::iterator it=m_nRowSelected.begin(); + for(std::vector<RowPos>::iterator it=m_nRowSelected.begin(); it!=m_nRowSelected.end();++it) - { - invalidateSelectedRow(*it,rCells); - m_pDataWindow->Invalidate(rCells); - } - m_nRowSelected.clear(); - m_nRowSelected.push_back(m_nCurRow); - invalidateSelectedRow(m_nCurRow, rCells); - } - else { - //a region is already selected, prevRow is last selected row and the row beneath - nextRow - should be selected - int prevRow = getRowSelectedNumber(m_nRowSelected, m_nCurRow); - int nextRow = getRowSelectedNumber(m_nRowSelected, m_nCurRow+1); - if(prevRow>-1) - { - //if m_nCurRow isn't the last one, can move down, otherwise not - if(m_nCurRow<m_nRowCount) - m_nCurRow++; - else - return bSuccess = true; - //if net row already selected, deselect it, otherwise select it - if(m_nRowSelected[nextRow] == m_nCurRow) - { - m_nRowSelected.erase(m_nRowSelected.begin()+prevRow); - invalidateSelectedRow(m_nCurRow-1, rCells); - } - else - { - m_nRowSelected.push_back(m_nCurRow); - invalidateSelectedRow(m_nCurRow, rCells); - } - } + invalidateSelectedRegion(*it, *it, rCells); + } + m_nRowSelected.clear(); + m_nRowSelected.push_back(m_nCurRow); + invalidateSelectedRegion(m_nCurRow, m_nCurRow, rCells); } - } else { - //there wasn't any selection, select curennt and row beneath, otherwise onlyrow beneath - if(m_nCurRow<m_nRowCount-1) - { - m_nRowSelected.push_back(m_nCurRow); - m_nCurRow++; - m_nRowSelected.push_back(m_nCurRow); - invalidateSelectedRegion(m_nCurRow-1, m_nCurRow, rCells); + //a region is already selected, prevRow is last selected row and the row beneath - nextRow - should be selected + int prevRow = getRowSelectedNumber(m_nRowSelected, m_nCurRow); + int nextRow = getRowSelectedNumber(m_nRowSelected, m_nCurRow+1); + if(prevRow>-1) + { + //if m_nCurRow isn't the last one, can move down, otherwise not + if(m_nCurRow<m_nRowCount-1) + m_nCurRow++; + else + return bSuccess = true; + //if next row already selected, deselect it, otherwise select it + if(nextRow>-1 && m_nRowSelected[nextRow] == m_nCurRow) + { + m_nRowSelected.erase(m_nRowSelected.begin()+prevRow); + invalidateSelectedRegion(m_nCurRow-1, m_nCurRow-1, rCells); + } + else + { + m_nRowSelected.push_back(m_nCurRow); + invalidateSelectedRegion(m_nCurRow, m_nCurRow, rCells); + } } else { - m_nRowSelected.push_back(m_nCurRow); - invalidateSelectedRow(m_nCurRow, rCells); + if(m_nCurRow<m_nRowCount-1) + { + m_nRowSelected.push_back(m_nCurRow); + m_nCurRow++; + m_nRowSelected.push_back(m_nCurRow); + invalidateSelectedRegion(m_nCurRow-1, m_nCurRow, rCells); + } } } - m_pSelEngine->SetAnchor(TRUE); - m_nAnchor = m_nCurRow; - ensureVisible(m_nCurColumn, m_nCurRow, false); - bSuccess = true; } - } - break; - case cursorSelectRowAreaTop: - { - if(m_pSelEngine->GetSelectionMode() == NO_SELECTION) - bSuccess = false; - else if(m_pSelEngine->GetSelectionMode() == SINGLE_SELECTION) - bSuccess = false; else { - //select the region between the current and the upper row - RowPos iter = m_nCurRow; - invalidateSelectedRegion(m_nCurRow, 0, rCells); - //put the rows in vector - while(iter>=0) + //there wasn't any selection, select current and row beneath, otherwise only row beneath + if(m_nCurRow<m_nRowCount-1) + { + m_nRowSelected.push_back(m_nCurRow); + m_nCurRow++; + m_nRowSelected.push_back(m_nCurRow); + invalidateSelectedRegion(m_nCurRow-1, m_nCurRow, rCells); + } + else { - if(!isRowSelected(m_nRowSelected, iter)) - m_nRowSelected.push_back(iter); - --iter; + m_nRowSelected.push_back(m_nCurRow); + invalidateSelectedRegion(m_nCurRow, m_nCurRow, rCells); } - m_nCurRow = 0; - m_nAnchor = m_nCurRow; - m_pSelEngine->SetAnchor(TRUE); - ensureVisible(m_nCurColumn, 0, false); - bSuccess = true; } + m_pSelEngine->SetAnchor(TRUE); + m_nAnchor = m_nCurRow; + ensureVisible(m_nCurColumn, m_nCurRow, false); + m_rAntiImpl.selectionChanged(true); + bSuccess = true; } + } break; - case cursorSelectRowAreaBottom: + case cursorSelectRowAreaTop: + { + if(m_pSelEngine->GetSelectionMode() == NO_SELECTION) + bSuccess = false; + else if(m_pSelEngine->GetSelectionMode() == SINGLE_SELECTION) + bSuccess = false; + else { - if(m_pSelEngine->GetSelectionMode() == NO_SELECTION) - return bSuccess = false; - else if(m_pSelEngine->GetSelectionMode() == SINGLE_SELECTION) - return bSuccess = false; - //select the region between the current and the last row + //select the region between the current and the upper row RowPos iter = m_nCurRow; - invalidateSelectedRegion(m_nCurRow, m_nRowCount-1, rCells); - //put the rows in the vector - while(iter<=m_nRowCount) + invalidateSelectedRegion(m_nCurRow, 0, rCells); + //put the rows in vector + while(iter>=0) { if(!isRowSelected(m_nRowSelected, iter)) m_nRowSelected.push_back(iter); - ++iter; + --iter; } - m_nCurRow = m_nRowCount-1; + m_nCurRow = 0; m_nAnchor = m_nCurRow; m_pSelEngine->SetAnchor(TRUE); - ensureVisible(m_nCurColumn, m_nRowCount, false); + ensureVisible(m_nCurColumn, 0, false); + m_rAntiImpl.selectionChanged(true); bSuccess = true; } + } + break; + case cursorSelectRowAreaBottom: + { + if(m_pSelEngine->GetSelectionMode() == NO_SELECTION) + return bSuccess = false; + else if(m_pSelEngine->GetSelectionMode() == SINGLE_SELECTION) + return bSuccess = false; + //select the region between the current and the last row + RowPos iter = m_nCurRow; + invalidateSelectedRegion(m_nCurRow, m_nRowCount-1, rCells); + //put the rows in the vector + while(iter<=m_nRowCount) + { + if(!isRowSelected(m_nRowSelected, iter)) + m_nRowSelected.push_back(iter); + ++iter; + } + m_nCurRow = m_nRowCount-1; + m_nAnchor = m_nCurRow; + m_pSelEngine->SetAnchor(TRUE); + ensureVisible(m_nCurColumn, m_nRowCount-1, false); + m_rAntiImpl.selectionChanged(true); + bSuccess = true; + } break; default: DBG_ERROR( "TableControl_Impl::dispatchAction: unsupported action!" ); @@ -1367,16 +1513,12 @@ namespace svt { namespace table { Rectangle aCellRect; impl_getCellRect( m_nCurColumn, m_nCurRow, aCellRect ); - - // const StyleSettings& rStyle = m_rAntiImpl.GetSettings().GetStyleSettings(); + if(!m_pModel->hasRowHeaders() && m_nCurColumn == 0) + aCellRect.Left()++; if ( _bShow ) - { pRenderer->ShowCellCursor( *m_pDataWindow, aCellRect); - } else - { pRenderer->HideCellCursor( *m_pDataWindow, aCellRect); - } } } @@ -1394,16 +1536,12 @@ namespace svt { namespace table return; } - DBG_ASSERT( ( _nColumn >= 0 ) && ( _nColumn < m_pModel->getColumnCount() ), - "TableControl_Impl::impl_getCellRect: invalid column index!" ); - DBG_ASSERT( ( _nRow >= 0 ) && ( _nRow < m_pModel->getRowCount() ), - "TableControl_Impl::impl_getCellRect: invalid row index!" ); - Rectangle aAllCells; impl_getAllVisibleCellsArea( aAllCells ); TableCellGeometry aCell( *this, aAllCells, _nColumn, _nRow ); _rCellRect = aCell.getRect(); + _rCellRect.Top()--;_rCellRect.Left()--; } //------------------------------------------------------------------------------- RowPos TableControl_Impl::getCurrentRow(const Point& rPoint) @@ -1412,8 +1550,7 @@ namespace svt { namespace table Rectangle rCellRect; RowPos newRowPos = -2;//-1 is HeaderRow ColPos newColPos = 0; - //To Do: when only row position needed, the second loop isn't necessary, Please proove this!!! - for(int i=0;i<m_nRowCount;i++) + for(int i=-1;i<m_nRowCount;i++) { for(int j=-1;j<m_nColumnCount;j++) { @@ -1422,9 +1559,7 @@ namespace svt { namespace table { newRowPos = i; newColPos = j; - if(newColPos == -1) - m_nCurColumn = 0; - else + if(newColPos != -1) m_nCurColumn = newColPos; return newRowPos; } @@ -1432,7 +1567,7 @@ namespace svt { namespace table } return newRowPos; } - //------------------------------------------------------------------------------- + //------------------------------------------------------------------------------- void TableControl_Impl::setCursorAtCurrentCell(const Point& rPoint) { DBG_CHECK_ME(); @@ -1440,7 +1575,6 @@ namespace svt { namespace table Rectangle rCellRect; RowPos newRowPos = -2;//-1 is HeaderRow ColPos newColPos = 0; - //To Do: when only row position needed, the second loop isn't necessary, Please proove this!!! for(int i=0;i<m_nRowCount;i++) { for(int j=-1;j<m_nColumnCount;j++) @@ -1460,7 +1594,6 @@ namespace svt { namespace table } showCursor(); } - //------------------------------------------------------------------------------- void TableControl_Impl::invalidateSelectedRegion(RowPos _nPrevRow, RowPos _nCurRow, Rectangle& _rCellRect) { @@ -1475,14 +1608,14 @@ namespace svt { namespace table if(_nPrevRow == _nCurRow) { impl_getCellRect(m_nCurColumn,_nCurRow,rCells); - _rCellRect.Top()=rCells.Top(); + _rCellRect.Top()=--rCells.Top(); _rCellRect.Bottom()=rCells.Bottom(); } //if the region is above the current row else if(_nPrevRow < _nCurRow ) { impl_getCellRect(m_nCurColumn,_nPrevRow,rCells); - _rCellRect.Top()=rCells.Top(); + _rCellRect.Top()= --rCells.Top(); impl_getCellRect(m_nCurColumn,_nCurRow,rCells); _rCellRect.Bottom()=rCells.Bottom(); } @@ -1490,46 +1623,31 @@ namespace svt { namespace table else { impl_getCellRect(m_nCurColumn,_nCurRow,rCells); - _rCellRect.Top()=rCells.Top(); + _rCellRect.Top()= --rCells.Top(); impl_getCellRect(m_nCurColumn,_nPrevRow,rCells); _rCellRect.Bottom()=rCells.Bottom(); } m_pDataWindow->Invalidate(_rCellRect); } - - //------------------------------------------------------------------------------- - //To Do: not really needed, because in method above one row can be invalidate. Please Prove this!!! - void TableControl_Impl::invalidateSelectedRow(RowPos _nCurRow, Rectangle& _rCellRect) - { - DBG_CHECK_ME(); - Rectangle aAllCells; - impl_getAllVisibleCellsArea( aAllCells ); - _rCellRect.Left() = aAllCells.Left(); - _rCellRect.Right() = aAllCells.Right(); - Rectangle rCells; - impl_getCellRect(m_nCurColumn,_nCurRow,rCells); - _rCellRect.Top()=rCells.Top(); - _rCellRect.Bottom()=rCells.Bottom(); - m_pDataWindow->Invalidate(_rCellRect); - } //------------------------------------------------------------------------------- //this method is to be called, when a new row is added void TableControl_Impl::invalidateRow(RowPos _nRowPos, Rectangle& _rCellRect) { - //DBG_CHECK_ME(); - TempHideCursor aHideCursor( *this ); + if(m_nCurRow < 0) + m_nCurRow = 0; + if(m_nCursorHidden == 2) + --m_nCursorHidden; impl_getAllVisibleCellsArea( _rCellRect ); TableRowGeometry _rRow( *this, _rCellRect, _nRowPos); impl_ni_updateScrollbars(); m_pDataWindow->Invalidate(_rRow.getRect()); } - //------------------------------------------------------------------------------- std::vector<RowPos>& TableControl_Impl::getSelectedRows() { return m_nRowSelected; } - + //------------------------------------------------------------------------------- void TableControl_Impl::removeSelectedRow(RowPos _nRowPos) { int i =0; @@ -1556,57 +1674,23 @@ namespace svt { namespace table else m_nCurRow = _nRowPos-1; } - //------------------------------------------------------------------------------- - void TableControl_Impl::invalidateRows(RowPos _nRowStart, Rectangle& _rCellRect) + //------------------------------------------------------------------------------ + void TableControl_Impl::invalidateRows() { - //DBG_CHECK_ME(); - (void)_nRowStart; - (void)_rCellRect; - /*TempHideCursor aHideCursor(*this); - Rectangle aAllCells; - impl_getAllVisibleCellsArea( aAllCells ); - TableRowGeometry _rRow( *this, aAllCells, _nRowStart); - _rCellRect = _rRow.getRect(); - Rectangle rCells1; - impl_getCellRect(m_nCurColumn,m_nRowCount,rCells1); - _rCellRect.Bottom() = rCells1.Bottom();*/ - /*if(_nRowStart != _nRowEnd) - { - TableRowGeometry _rRow( *this, aAllCells, _nRowEnd); - _rCellRect.Bottom() = _rRow.getRect().Bottom(); - } - */ - //_rCellRect.Right() = aAllCells.Right(); - //_rCellRect.Left() = aAllCells.Left(); - //Rectangle rCells1; - //impl_getCellRect(m_nCurColumn,_nRowStart,rCells1); - //_rCellRect.Top()=rCells1.Top(); - //Rectangle rCells2; - //impl_getCellRect(m_nCurColumn,_nRowEnd,rCells2); - //_rCellRect.Bottom()=rCells2.Bottom(); impl_ni_updateScrollbars(); - //m_pDataWindow->Invalidate(_rCellRect); + TableSize nVisibleRows = impl_getVisibleRows(true); + TableSize nVisibleCols = impl_getVisibleColumns(true); + if(m_nTopRow+nVisibleRows>m_nRowCount && m_nRowCount>=nVisibleRows) + m_nTopRow--; + else + m_nTopRow = 0; + if(m_nLeftColumn+nVisibleCols>m_nColumnCount && m_nColumnCount>=nVisibleCols) + m_nLeftColumn--; + else + m_nLeftColumn = 0; m_pDataWindow->Invalidate(); } - - //------------------------------------------------------------------------------- - bool TableControl_Impl::isClickInVisibleArea(const Point& rPoint) - { - DBG_CHECK_ME(); - long nScrollbarMetrics = m_rAntiImpl.GetSettings().GetStyleSettings().GetScrollBarSize(); - //clickable area is in the visible table control area without the scrollbars - Rectangle aDataCellPlayground( Point( 0, 0 ), m_rAntiImpl.GetOutputSizePixel() ); - aDataCellPlayground.Top() = m_nColHeaderHeightPixel; - aDataCellPlayground.Right() -= nScrollbarMetrics; - aDataCellPlayground.Bottom() -= nScrollbarMetrics; - if((rPoint.X() >= aDataCellPlayground.Left() && rPoint.X() <= aDataCellPlayground.Right()) && rPoint.Y() >= aDataCellPlayground.Top() && rPoint.Y() <= aDataCellPlayground.Bottom()) - { - return true; - } - else - return false; - } //-------------------------------------------------------------------- TableSize TableControl_Impl::impl_getVisibleRows( bool _bAcceptPartialRow ) const { @@ -1654,20 +1738,6 @@ namespace svt { namespace table // ensure that the new cell is visible ensureVisible( m_nCurColumn, m_nCurRow, false ); - - // TODO: invalidate all and new column/row header, if present, to enforce - // re-painting them - //if(!m_nRowSelected.empty()) - //{ - // Rectangle rCells; - // for(std::vector<RowPos>::iterator it=m_nRowSelected.begin(); - // it!=m_nRowSelected.end();++it) - // { - // invalidateSelectedRow(*it,rCells); - // } - // m_nRowSelected.clear(); - //} - // TODO: notify listeners about new position return true; } @@ -1735,7 +1805,7 @@ namespace svt { namespace table && abs( nPixelDelta ) < aDataArea.GetHeight() ) { - m_pDataWindow->Scroll( 0, (long)-nPixelDelta, aDataArea, SCROLL_CLIP | SCROLL_UPDATE ); + m_pDataWindow->Scroll( 0, (long)-nPixelDelta, aDataArea, SCROLL_CLIP | SCROLL_UPDATE | SCROLL_CHILDREN); } else m_pDataWindow->Invalidate( INVALIDATE_UPDATE ); @@ -1791,42 +1861,310 @@ namespace svt { namespace table return (TableSize)( m_nLeftColumn - nOldLeftColumn ); } - + //------------------------------------------------------------------------------- SelectionEngine* TableControl_Impl::getSelEngine() { return m_pSelEngine; } + //------------------------------------------------------------------------------- TableDataWindow* TableControl_Impl::getDataWindow() { return m_pDataWindow; } - BOOL TableControl_Impl::isRowSelected(::std::vector<RowPos> selectedRows, RowPos current) + //------------------------------------------------------------------------------- + ScrollBar* TableControl_Impl::getHorzScrollbar() + { + return m_pHScroll; + } + //------------------------------------------------------------------------------- + ScrollBar* TableControl_Impl::getVertScrollbar() + { + return m_pVScroll; + } + //------------------------------------------------------------------------------- + BOOL TableControl_Impl::isRowSelected(const ::std::vector<RowPos>& selectedRows, RowPos current) + { + return ::std::find(selectedRows.begin(),selectedRows.end(),current) != selectedRows.end(); + } + //------------------------------------------------------------------------------- + bool TableControl_Impl::isRowSelected(RowPos current) + { + return ::std::find(m_nRowSelected.begin(),m_nRowSelected.end(),current) != m_nRowSelected.end(); + } + //------------------------------------------------------------------------------- + int TableControl_Impl::getRowSelectedNumber(const ::std::vector<RowPos>& selectedRows, RowPos current) { - for(::std::vector<RowPos>::iterator it=selectedRows.begin(); - it!=selectedRows.end();++it) + std::vector<RowPos>::const_iterator it = ::std::find(selectedRows.begin(),selectedRows.end(),current); + if ( it != selectedRows.end() ) { - if(*it == current) - return TRUE; + return it - selectedRows.begin(); } - return FALSE; + return -1; } - - int TableControl_Impl::getRowSelectedNumber(::std::vector<RowPos> selectedRows, RowPos current) + //------------------------------------------------------------------------------- + ::rtl::OUString& TableControl_Impl::setTooltip(const Point& rPoint ) { - int pos = -1; - int i = 0; - for(std::vector<RowPos>::iterator it=selectedRows.begin();it!=selectedRows.end();++it) + ::rtl::OUString aTooltipText; + RowPos current = getCurrentRow(rPoint); + com::sun::star::uno::Sequence< sal_Int32 > cols = m_rAntiImpl.getColumnsForTooltip(); + com::sun::star::uno::Sequence< ::rtl::OUString > text = m_rAntiImpl.getTextForTooltip(); + if(text.getLength()==0 && cols.getLength()==0) { - if(*it == current) - return pos = i; - ++i; + ::com::sun::star::uno::Any content = m_pModel->getCellContent()[current][m_nCurColumn]; + aTooltipText = convertToString(content); + } + else if(text.getLength() == 0) + { + for(int i=0; i<cols.getLength(); i++) + { + if(i==0) + { + ::com::sun::star::uno::Any content = m_pModel->getCellContent()[current][cols[i]]; + aTooltipText = convertToString(content); + } + else + { + aTooltipText+= ::rtl::OUString::createFromAscii("\n"); + ::com::sun::star::uno::Any content = m_pModel->getCellContent()[current][cols[i]]; + aTooltipText += convertToString(content); + } + } } - return pos; + else if(cols.getLength() == 0) + { + for(int i=0; i<text.getLength(); i++) + { + if(i==0) + aTooltipText = text[i]; + else + { + aTooltipText+= ::rtl::OUString::createFromAscii("\n"); + aTooltipText+= text[i]; + } + } + } + else + { + int nCols = cols.getLength(); + int mText = text.getLength(); + if(nCols < mText ) + cols.realloc(mText); + else if(mText < nCols) + text.realloc(nCols); + for(int i=0; i<cols.getLength(); i++) + { + if(i==0) + { + ::com::sun::star::uno::Any content = m_pModel->getCellContent()[current][cols[i]]; + aTooltipText = text[i] + convertToString(content); + } + else + { + aTooltipText+= ::rtl::OUString::createFromAscii("\n"); + aTooltipText+= text[i]; + if(nCols > i) + { + ::com::sun::star::uno::Any content = m_pModel->getCellContent()[current][cols[i]]; + ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphic >xGraphic; + aTooltipText += convertToString(content); + } + } + } + } + return m_aTooltipText = aTooltipText; } - - void TableControl_Impl::setCellContent(CellEntryType* pCellEntryType) + //-------------------------------------------------------------------- + void TableControl_Impl::resizeColumn(const Point& rPoint) + { + Pointer aNewPointer(POINTER_ARROW); + int headerRowWidth = 0; + if(m_pModel->hasRowHeaders()) + headerRowWidth = m_rAntiImpl.LogicToPixel( Size(m_pModel->getRowHeaderWidth(), 0 ), MAP_APPFONT ).Width(); + int resizingColumn=m_nCurColumn-m_nLeftColumn; + PColumnModel pColumn = m_pModel->getColumnModel(m_nCurColumn); + impl_ni_getAccVisibleColWidths(); + int newColWidth = m_aColumnWidthsPixel[m_nCurColumn]; + //subtract 1 from m_aAccColumnWidthPixel because right border should be part of the current cell + if(m_aVisibleColumnWidthsPixel[resizingColumn]-1 == rPoint.X() && pColumn->isResizable()) + aNewPointer = Pointer( POINTER_HSPLIT ); + //MouseButton was pressed but not yet released, mouse is moving + if(m_bResizing) + { + if(rPoint.X() > m_pDataWindow->GetOutputSizePixel().Width() || rPoint.X() < m_aVisibleColumnWidthsPixel[resizingColumn]-newColWidth) + aNewPointer = Pointer( POINTER_NOTALLOWED); + else + aNewPointer = Pointer( POINTER_HSPLIT ); + m_pDataWindow->HideTracking(); + int lineHeight = 0; + if(m_pModel->hasColumnHeaders()) + lineHeight+= m_nColHeaderHeightPixel; + lineHeight+=m_nRowHeightPixel*m_nRowCount; + int gridHeight = m_pDataWindow->GetOutputSizePixel().Height(); + if(lineHeight >= gridHeight) + lineHeight = gridHeight; + m_pDataWindow->ShowTracking(Rectangle(Point(rPoint.X(),0), Size(1, lineHeight )), + SHOWTRACK_SPLIT | SHOWTRACK_WINDOW); + } + m_pDataWindow->SetPointer(aNewPointer); + } + //-------------------------------------------------------------------- + bool TableControl_Impl::startResizeColumn(const Point& rPoint) + { + m_bResizingGrid = false; + m_nResizingColumn = m_nCurColumn; + PColumnModel pColumn = m_pModel->getColumnModel(m_nResizingColumn); + if(m_aVisibleColumnWidthsPixel[m_nResizingColumn-m_nLeftColumn]-1 == rPoint.X() && pColumn->isResizable()) + { + m_pDataWindow->CaptureMouse(); + m_bResizing = true; + } + return m_bResizing; + } + //-------------------------------------------------------------------- + bool TableControl_Impl::endResizeColumn(const Point& rPoint) { - (void)pCellEntryType; + if(m_bResizing) + { + m_pDataWindow->HideTracking(); + PColumnModel pColumn = m_pModel->getColumnModel(m_nResizingColumn); + int maxWidth = pColumn->getMaxWidth(); + int minWidth = pColumn->getMinWidth(); + int resizeCol = m_nResizingColumn-m_nLeftColumn; + //new position of mouse + int actX = rPoint.X(); + //old position of right border + int oldX = m_aVisibleColumnWidthsPixel[resizeCol]; + //position of left border if cursor in the first cell + int leftX = 0; + if(m_nResizingColumn > m_nLeftColumn) + leftX = m_aVisibleColumnWidthsPixel[resizeCol-1]; + else if(m_nResizingColumn == 0 && m_pModel->hasRowHeaders()) + leftX = m_rAntiImpl.LogicToPixel( Size( m_pModel->getRowHeaderWidth(), 0 ), MAP_APPFONT ).Width(); + int actWidth = actX - leftX; + int newActWidth = 0; + //minimize the column width + if(oldX > actX && actX >= leftX) + { + if(minWidth < actWidth) + { + newActWidth = m_rAntiImpl.PixelToLogic( Size( actWidth, 0 ), MAP_APPFONT ).Width(); + pColumn->setPreferredWidth(newActWidth); + } + else + pColumn->setPreferredWidth(minWidth); + if(m_nLeftColumn != 0) + impl_updateLeftColumn(); + } + else if(oldX < actX) + { + if(actWidth < maxWidth) + { + newActWidth = m_rAntiImpl.PixelToLogic( Size( actWidth, 0 ), MAP_APPFONT ).Width(); + pColumn->setPreferredWidth(newActWidth); + } + else + pColumn->setPreferredWidth(maxWidth); + } + m_nCurColumn = m_nResizingColumn; + impl_ni_updateColumnWidths(); + impl_ni_updateScrollbars(); + m_pDataWindow->Invalidate(INVALIDATE_UPDATE); + m_pDataWindow->SetPointer(Pointer()); + m_bResizing = false; + m_bResizingGrid = true; + } + m_pDataWindow->ReleaseMouse(); + return m_bResizing; + } + //------------------------------------------------------------------------------- + void TableControl_Impl::impl_ni_getAccVisibleColWidths() + { + TableSize nVisCols = impl_getVisibleColumns(true); + int widthsPixel = 0; + m_aVisibleColumnWidthsPixel.resize(0); + m_aVisibleColumnWidthsPixel.reserve(nVisCols); + int headerRowWidth = 0; + if(m_pModel->hasRowHeaders()) + { + headerRowWidth = m_rAntiImpl.LogicToPixel( Size(m_pModel->getRowHeaderWidth(), 0 ), MAP_APPFONT ).Width(); + widthsPixel+=headerRowWidth; + } + int col = m_nLeftColumn; + while(nVisCols) + { + m_aVisibleColumnWidthsPixel.push_back(widthsPixel+=m_aColumnWidthsPixel[col]); + col++; + nVisCols--; + } + } + //------------------------------------------------------------------------------- + void TableControl_Impl::impl_updateLeftColumn() + { + int nVisCols = m_aVisibleColumnWidthsPixel.size(); + int headerRowWidth = 0; + //sum of currently visible columns + int widthsPixel = 0; + //header pixel should be added, because header doesn't vanish when scrolling + if(m_pModel->hasRowHeaders()) + { + headerRowWidth = m_rAntiImpl.LogicToPixel( Size(m_pModel->getRowHeaderWidth(), 0 ), MAP_APPFONT ).Width(); + widthsPixel+=headerRowWidth; + } + int col = m_nLeftColumn; + //add column width of the neighbour of the left column + widthsPixel+=m_aColumnWidthsPixel[col-1]; + //compute the sum of the new column widths + while(nVisCols) + { + PColumnModel pColumn = m_pModel->getColumnModel(col); + int colWidth = pColumn->getWidth(); + int colPrefWidth = pColumn->getPreferredWidth(); + if(colPrefWidth!=0) + colWidth = colPrefWidth; + widthsPixel += m_rAntiImpl.LogicToPixel( Size( colWidth, 0 ), MAP_APPFONT ).Width(); + col++; + nVisCols--; + } + //when the sum of all visible columns and the next to the left column is smaller than + //window width, then update m_nLeftColumn + if(widthsPixel<m_pDataWindow->GetOutputSizePixel().Width()) + m_nLeftColumn--; + } + //-------------------------------------------------------------------- + rtl::OUString TableControl_Impl::convertToString(const ::com::sun::star::uno::Any& value) + { + sal_Int32 nInt = 0; + sal_Bool bBool = false; + double fDouble = 0; + ::rtl::OUString sNewString; + ::rtl::OUString sConvertString; + if(value >>= sConvertString) + sNewString = sConvertString; + else if(value >>= nInt) + sNewString = sConvertString.valueOf(nInt); + else if(value >>= bBool) + sNewString = sConvertString.valueOf(bBool); + else if(value >>= fDouble) + sNewString = sConvertString.valueOf(fDouble); + return sNewString; + } + Rectangle TableControl_Impl::calcHeaderRect(bool bColHeader) + { + Rectangle aRectTable, aRectTableWithHeaders; + impl_getAllVisibleDataCellArea(aRectTable); + impl_getAllVisibleCellsArea(aRectTableWithHeaders); + Size aSizeTable(aRectTable.GetSize()); + Size aSizeTableWithHeaders(aRectTableWithHeaders.GetSize()); + if(bColHeader) + return Rectangle(aRectTableWithHeaders.TopLeft(),Size(aSizeTableWithHeaders.Width()-aSizeTable.Width(), aSizeTableWithHeaders.Height())); + else + return Rectangle(aRectTableWithHeaders.TopLeft(),Size(aSizeTableWithHeaders.Width(), aSizeTableWithHeaders.Height()-aSizeTable.Height())); + } + Rectangle TableControl_Impl::calcTableRect() + { + Rectangle aRect; + impl_getAllVisibleDataCellArea(aRect); + return aRect; } //-------------------------------------------------------------------- @@ -1842,34 +2180,33 @@ namespace svt { namespace table return 0L; } - //--------------------------------------------------------------------------------------- - TableFunctionSet::TableFunctionSet(TableControl_Impl* _pTableControl): - m_pTableControl( _pTableControl) - ,m_nCurrentRow (-2) + TableFunctionSet::TableFunctionSet(TableControl_Impl* _pTableControl) + :m_pTableControl( _pTableControl) + ,m_nCurrentRow (-2) { } - + //------------------------------------------------------------------------------- TableFunctionSet::~TableFunctionSet() { } - + //------------------------------------------------------------------------------- void TableFunctionSet::BeginDrag() { } - + //------------------------------------------------------------------------------- void TableFunctionSet::CreateAnchor() { m_pTableControl->m_nAnchor = m_pTableControl->m_nCurRow; } - - void TableFunctionSet::DestroyAnchor() - { + //------------------------------------------------------------------------------- + void TableFunctionSet::DestroyAnchor() + { m_pTableControl->m_nAnchor = -1; - } - - BOOL TableFunctionSet::SetCursorAtPoint(const Point& rPoint, BOOL bDontSelectAtCursor) - { + } + //------------------------------------------------------------------------------- + BOOL TableFunctionSet::SetCursorAtPoint(const Point& rPoint, BOOL bDontSelectAtCursor) + { BOOL bHandled = FALSE; Rectangle rCells; //curRow is the row where the mouse click happened, m_nCurRow is the last selected row, before the mouse click @@ -1886,9 +2223,6 @@ namespace svt { namespace table { //selecting region, int diff = m_pTableControl->m_nCurRow - curRow; - //bool isAlreadySelected = m_pTableControl->isRowSelected(m_pTableControl->m_nRowSelected, m_pTableControl->m_nAnchor); - /* if(!isAlreadySelected && m_nCurrentRow != m_pTableControl->m_nCurRow) - m_pTableControl->m_nRowSelected.push_back(m_nAnchor);*/ //selected region lies above the last selection if( diff >= 0) { @@ -1924,9 +2258,7 @@ namespace svt { namespace table else { if(m_pTableControl->m_nRowSelected.empty()) - { m_pTableControl->m_nRowSelected.push_back(curRow); - } else { if(m_pTableControl->m_pSelEngine->GetSelectionMode()==SINGLE_SELECTION) @@ -1943,14 +2275,14 @@ namespace svt { namespace table } if(m_pTableControl->m_nRowSelected.size()>1 && m_pTableControl->m_pSelEngine->GetSelectionMode()!=SINGLE_SELECTION) m_pTableControl->m_pSelEngine->AddAlways(TRUE); - m_pTableControl->invalidateSelectedRow(curRow,rCells); + m_pTableControl->invalidateSelectedRegion(curRow, curRow, rCells); bHandled = TRUE; } m_pTableControl->m_nCurRow = curRow; m_pTableControl->ensureVisible(m_pTableControl->m_nCurColumn,m_pTableControl->m_nCurRow,false); return bHandled; } - + //------------------------------------------------------------------------------- BOOL TableFunctionSet::IsSelectionAtPoint( const Point& rPoint ) { m_pTableControl->m_pSelEngine->AddAlways(FALSE); @@ -1965,7 +2297,7 @@ namespace svt { namespace table return selected; } } - + //------------------------------------------------------------------------------- void TableFunctionSet::DeselectAtPoint( const Point& rPoint ) { (void)rPoint; @@ -1978,21 +2310,22 @@ namespace svt { namespace table if(*it == m_nCurrentRow) { pos = i; - m_pTableControl->invalidateSelectedRow(*it,rCells); + m_pTableControl->invalidateSelectedRegion(*it, *it, rCells); } ++i; } m_pTableControl->m_nRowSelected.erase(m_pTableControl->m_nRowSelected.begin()+pos); } + //------------------------------------------------------------------------------- void TableFunctionSet::DeselectAll() { if(!m_pTableControl->m_nRowSelected.empty()) { Rectangle rCells; for(std::vector<RowPos>::iterator it=m_pTableControl->m_nRowSelected.begin(); - it!=m_pTableControl->m_nRowSelected.end();++it) + it!=m_pTableControl->m_nRowSelected.end();++it) { - m_pTableControl->invalidateSelectedRow(*it,rCells); + m_pTableControl->invalidateSelectedRegion(*it, *it, rCells); } m_pTableControl->m_nRowSelected.clear(); } diff --git a/svtools/source/table/tablecontrol_impl.hxx b/svtools/source/table/tablecontrol_impl.hxx index dc875cd137fe..0a487c77c76c 100644 --- a/svtools/source/table/tablecontrol_impl.hxx +++ b/svtools/source/table/tablecontrol_impl.hxx @@ -39,6 +39,7 @@ #include <vector> #include <vcl/seleng.hxx> + class ScrollBar; class ScrollBarBox; @@ -62,60 +63,64 @@ namespace svt { namespace table friend class TableRowGeometry; friend class TableColumnGeometry; friend class SuspendInvariants; - friend class TableFunctionSet; + friend class TableFunctionSet; private: /// the control whose impl-instance we implemnt - TableControl& m_rAntiImpl; + TableControl& m_rAntiImpl; /// the model of the table control - PTableModel m_pModel; + PTableModel m_pModel; /// the input handler to use, usually the input handler as provided by ->m_pModel - PTableInputHandler m_pInputHandler; + PTableInputHandler m_pInputHandler; /// the widths of the single columns, measured in pixel - ArrayOfLong m_aColumnWidthsPixel; + ArrayOfLong m_aColumnWidthsPixel; /** the accumulated widths of the single columns, i.e. their exclusive right borders, <strong<not</strong> counting the space for a possible row header column */ - ArrayOfLong m_aAccColumnWidthsPixel; + ArrayOfLong m_aAccColumnWidthsPixel; + + ArrayOfLong m_aVisibleColumnWidthsPixel; /// the height of a single row in the table, measured in pixels - long m_nRowHeightPixel; + long m_nRowHeightPixel; /// the height of the column header row in the table, measured in pixels - long m_nColHeaderHeightPixel; + long m_nColHeaderHeightPixel; /// the width of the row header column in the table, measured in pixels - long m_nRowHeaderWidthPixel; + long m_nRowHeaderWidthPixel; /// the number of columns in the table control. Cached model value. - TableSize m_nColumnCount; + TableSize m_nColumnCount; /// the number of rows in the table control. Cached model value. - TableSize m_nRowCount; + TableSize m_nRowCount; - ColPos m_nCurColumn; - RowPos m_nCurRow; - ColPos m_nLeftColumn; - RowPos m_nTopRow; + ColPos m_nCurColumn; + RowPos m_nCurRow; + ColPos m_nLeftColumn; + RowPos m_nTopRow; - sal_Int32 m_nCursorHidden; + sal_Int32 m_nCursorHidden; /** the window to contain all data content, including header bars The window's upper left corner is at position (0,0), relative to the table control, which is the direct parent of the data window. */ - TableDataWindow* m_pDataWindow; + TableDataWindow* m_pDataWindow; /// the vertical scrollbar, if any - ScrollBar* m_pVScroll; + ScrollBar* m_pVScroll; /// the horizontal scrollbar, if any ScrollBar* m_pHScroll; - ScrollBarBox* m_pScrollCorner; - //selection engine - for determining selection range, e.g. single, multiple - SelectionEngine* m_pSelEngine; - //vector which contains the selected rows - std::vector<RowPos> m_nRowSelected; - //part of selection engine - TableFunctionSet* m_pTableFunctionSet; - //part of selection engine - RowPos m_nAnchor; - - + ScrollBarBox* m_pScrollCorner; + //selection engine - for determining selection range, e.g. single, multiple + SelectionEngine* m_pSelEngine; + //vector which contains the selected rows + std::vector<RowPos> m_nRowSelected; + //part of selection engine + TableFunctionSet* m_pTableFunctionSet; + //part of selection engine + RowPos m_nAnchor; + bool m_bResizing; + ColPos m_nResizingColumn; + bool m_bResizingGrid; + rtl::OUString m_aTooltipText; #if DBG_UTIL #define INV_SCROLL_POSITION 1 @@ -146,7 +151,6 @@ namespace svt { namespace table inline const TableControl& getAntiImpl() const { return m_rAntiImpl; } inline TableControl& getAntiImpl() { return m_rAntiImpl; } - void setCellContent(CellEntryType* pCellEntryType); public: TableControl_Impl( TableControl& _rAntiImpl ); @@ -181,53 +185,42 @@ namespace svt { namespace table <TRUE/> if it's okay that the given cooordinate is only partially visible */ void ensureVisible( ColPos _nColumn, RowPos _nRow, bool _bAcceptPartialVisibility ); - /** returns the row, which contains the input point*/ - RowPos getCurrentRow (const Point& rPoint); - - void setCursorAtCurrentCell(const Point& rPoint); - /** proves whether the vector with the selected rows contains the current row*/ - BOOL isRowSelected(::std::vector<RowPos> selectedRows, RowPos current); - /** returns the position of the current row in the selecttion vector */ - int getRowSelectedNumber(::std::vector<RowPos> selectedRows, RowPos current); - /** _rCellRect contains the region, which should be invalidate after some action e.g. selectiong row*/ - void invalidateSelectedRegion(RowPos _nPrevRow, RowPos _nCurRow, Rectangle& _rCellRect ); - /** _rCellRect contains the region, which should be invalidate after some action e.g. selectiong row*/ - //vielleicht kann man mit den anderen verschmelzen, mit einer Überprüfung ob prev==curr? - void invalidateSelectedRow( RowPos _nCurRow, Rectangle& _rCellRect ); - /** to be called when a new row is added to the control*/ - void invalidateRow(RowPos _nRowPos, Rectangle& _rCellRect ); - /** returns the vector, which contains the selected rows*/ - std::vector<RowPos>& getSelectedRows(); - /** updates the vector, which contains the selected rows after removing the row nRowPos*/ - void removeSelectedRow(RowPos _nRowPos); - void invalidateRows(RowPos _nRowStart, Rectangle& _rCellRect ); - //virtual void DoubleClick(); - + /** returns the row, which contains the input point*/ + virtual RowPos getCurrentRow (const Point& rPoint); + + void setCursorAtCurrentCell(const Point& rPoint); + /** checks whether the vector with the selected rows contains the current row*/ + BOOL isRowSelected(const ::std::vector<RowPos>& selectedRows, RowPos current); + + bool isRowSelected(RowPos current); + /** returns the position of the current row in the selection vector */ + int getRowSelectedNumber(const ::std::vector<RowPos>& selectedRows, RowPos current); + /** _rCellRect contains the region, which should be invalidate after some action e.g. selecting row*/ + void invalidateSelectedRegion(RowPos _nPrevRow, RowPos _nCurRow, Rectangle& _rCellRect ); + /** to be called when a new row is added to the control*/ + void invalidateRow(RowPos _nRowPos, Rectangle& _rCellRect ); + /** returns the vector, which contains the selected rows*/ + std::vector<RowPos>& getSelectedRows(); + /** updates the vector, which contains the selected rows after removing the row nRowPos*/ + void removeSelectedRow(RowPos _nRowPos); + void invalidateRows(); // IAbstractTableControl virtual void hideCursor(); virtual void showCursor(); virtual bool dispatchAction( TableControlAction _eAction ); - virtual bool isClickInVisibleArea(const Point& rPoint); - virtual SelectionEngine* getSelEngine(); - - TableDataWindow* getDataWindow(); - /** retrieves the area occupied by the totality of (at least partially) visible cells - - The returned area includes row and column headers. Also, it takes into - account the the fact that there might be less columns than would normally - find room in the control. - - As a result of respecting the partial visibility of rows and columns, - the returned area might be larger than the data window's output size. - */ - void impl_getAllVisibleCellsArea( Rectangle& _rCellArea ) const; - - /** retrieves the area occupied by all (at least partially) visible data cells. - - Effectively, the returned area is the same as returned by ->impl_getAllVisibleCellsArea, - minus the row and column header areas. - */ - void impl_getAllVisibleDataCellArea( Rectangle& _rCellArea ) const; + virtual SelectionEngine* getSelEngine(); + virtual rtl::OUString& setTooltip(const Point& rPoint ); + virtual void resizeColumn(const Point& rPoint); + virtual bool startResizeColumn(const Point& rPoint); + virtual bool endResizeColumn(const Point& rPoint); + + TableDataWindow* getDataWindow(); + ScrollBar* getHorzScrollbar(); + ScrollBar* getVertScrollbar(); + + ::rtl::OUString convertToString(const ::com::sun::star::uno::Any& _value); + Rectangle calcHeaderRect(bool bColHeader); + Rectangle calcTableRect(); private: /** toggles the cursor visibility @@ -312,10 +305,30 @@ namespace svt { namespace table column range were reached. */ TableSize impl_ni_ScrollColumns( TableSize _nRowDelta ); + /** retrieves the area occupied by the totality of (at least partially) visible cells + + The returned area includes row and column headers. Also, it takes into + account the the fact that there might be less columns than would normally + find room in the control. + + As a result of respecting the partial visibility of rows and columns, + the returned area might be larger than the data window's output size. + */ + void impl_getAllVisibleCellsArea( Rectangle& _rCellArea ) const; + + /** retrieves the area occupied by all (at least partially) visible data cells. + + Effectively, the returned area is the same as returned by ->impl_getAllVisibleCellsArea, + minus the row and column header areas. + */ + void impl_getAllVisibleDataCellArea( Rectangle& _rCellArea ) const; + + void impl_ni_getAccVisibleColWidths(); + void impl_updateLeftColumn(); DECL_LINK( OnScroll, ScrollBar* ); }; - //see seleng.hxx, seleng.cxx, FunctionSet overwritables, part of selection engine + //see seleng.hxx, seleng.cxx, FunctionSet overridables, part of selection engine class TableFunctionSet : public FunctionSet { friend class TableDataWindow; diff --git a/svtools/source/table/tabledatawindow.cxx b/svtools/source/table/tabledatawindow.cxx index 246710488b42..e307071e2699 100644 --- a/svtools/source/table/tabledatawindow.cxx +++ b/svtools/source/table/tabledatawindow.cxx @@ -30,6 +30,7 @@ #include "svtools/table/tablecontrol.hxx" #include "svtools/table/tabledatawindow.hxx" #include "tablecontrol_impl.hxx" +#include <vcl/help.hxx> //........................................................................ namespace svt { namespace table @@ -44,10 +45,8 @@ namespace svt { namespace table TableDataWindow::TableDataWindow( TableControl_Impl& _rTableControl ) :Window( &_rTableControl.getAntiImpl() ) ,m_rTableControl ( _rTableControl ) + ,m_nRowAlreadySelected( -1 ) { - Color backgroundColor = m_rTableControl.getAntiImpl().GetSettings().GetStyleSettings().GetFieldColor(); - SetBackground( backgroundColor ); - SetControlBackground( backgroundColor ); } //-------------------------------------------------------------------- @@ -55,28 +54,99 @@ namespace svt { namespace table { m_rTableControl.doPaintContent( rUpdateRect ); } + //-------------------------------------------------------------------- void TableDataWindow::MouseMove( const MouseEvent& rMEvt ) { + Point aPoint = rMEvt.GetPosPixel(); if ( !m_rTableControl.getInputHandler()->MouseMove( m_rTableControl, rMEvt ) ) - Window::MouseMove( rMEvt ); + { + if(m_rTableControl.getCurrentRow(aPoint)>=0 ) + { + SetPointer(POINTER_ARROW); + rtl::OUString& rHelpText = m_rTableControl.setTooltip(aPoint); + Help::EnableBalloonHelp(); + Window::SetHelpText( rHelpText.getStr()); + } + else if(m_rTableControl.getCurrentRow(aPoint) == -1) + { + if(Help::IsBalloonHelpEnabled()) + Help::DisableBalloonHelp(); + m_rTableControl.resizeColumn(aPoint); + } + else + { + if(Help::IsBalloonHelpEnabled()) + Help::DisableBalloonHelp(); + Window::MouseMove( rMEvt ); + } + } } + //-------------------------------------------------------------------- void TableDataWindow::MouseButtonDown( const MouseEvent& rMEvt ) { + Point aPoint = rMEvt.GetPosPixel(); + RowPos nCurRow = m_rTableControl.getCurrentRow(aPoint); if ( !m_rTableControl.getInputHandler()->MouseButtonDown( m_rTableControl, rMEvt ) ) Window::MouseButtonDown( rMEvt ); else - m_aMouseButtonDownHdl.Call( (MouseEvent*) &rMEvt); + { + if(nCurRow >= 0 && m_rTableControl.getSelEngine()->GetSelectionMode() != NO_SELECTION) + { + if( m_nRowAlreadySelected != nCurRow ) + { + m_nRowAlreadySelected = nCurRow; + m_aSelectHdl.Call( NULL ); + } + else + m_aMouseButtonDownHdl.Call((MouseEvent*) &rMEvt); + } + else + m_aMouseButtonDownHdl.Call((MouseEvent*) &rMEvt); + } m_rTableControl.getAntiImpl().LoseFocus(); } + //-------------------------------------------------------------------- void TableDataWindow::MouseButtonUp( const MouseEvent& rMEvt ) { if ( !m_rTableControl.getInputHandler()->MouseButtonUp( m_rTableControl, rMEvt ) ) Window::MouseButtonUp( rMEvt ); else - m_aMouseButtonUpHdl.Call( (MouseEvent*) &rMEvt); + m_aMouseButtonUpHdl.Call((MouseEvent*) &rMEvt); m_rTableControl.getAntiImpl().GetFocus(); } - + //-------------------------------------------------------------------- + void TableDataWindow::SetPointer( const Pointer& rPointer ) + { + Window::SetPointer(rPointer); + } + //-------------------------------------------------------------------- + void TableDataWindow::CaptureMouse() + { + Window::CaptureMouse(); + } + //-------------------------------------------------------------------- + void TableDataWindow::ReleaseMouse( ) + { + Window::ReleaseMouse(); + } + // ----------------------------------------------------------------------- + long TableDataWindow::Notify(NotifyEvent& rNEvt ) + { + long nDone = 0; + if ( rNEvt.GetType() == EVENT_COMMAND ) + { + const CommandEvent& rCEvt = *rNEvt.GetCommandEvent(); + if ( rCEvt.GetCommand() == COMMAND_WHEEL ) + { + const CommandWheelData* pData = rCEvt.GetWheelData(); + if( !pData->GetModifier() && ( pData->GetMode() == COMMAND_WHEEL_SCROLL ) ) + { + nDone = HandleScrollCommand( rCEvt, m_rTableControl.getHorzScrollbar(), m_rTableControl.getVertScrollbar() ); + } + } + } + return nDone ? nDone : Window::Notify( rNEvt ); + } //........................................................................ } } // namespace svt::table //........................................................................ diff --git a/svtools/source/table/tablegeometry.cxx b/svtools/source/table/tablegeometry.cxx index 58bdb531c921..d60de9e6438f 100644 --- a/svtools/source/table/tablegeometry.cxx +++ b/svtools/source/table/tablegeometry.cxx @@ -49,8 +49,8 @@ namespace svt { namespace table { if ( m_nRowPos == ROW_COL_HEADERS ) { - DBG_ASSERT( m_rControl.m_pModel->hasColumnHeaders(), - "TableRowGeometry::TableRowGeometry: why asking for the geoemtry of the non-existent column header row?" ); + //DBG_ASSERT( m_rControl.m_pModel->hasColumnHeaders(), + // "TableRowGeometry::TableRowGeometry: why asking for the geoemtry of the non-existent column header row?" ); m_aRect.Top() = 0; m_aRect.Bottom() = m_rControl.m_nColHeaderHeightPixel - 1; } @@ -87,8 +87,8 @@ namespace svt { namespace table { if ( m_nColPos == COL_ROW_HEADERS ) { - DBG_ASSERT( m_rControl.m_pModel->hasRowHeaders(), - "TableColumnGeometry::TableColumnGeometry: why asking for the geoemtry of the non-existent row header column?" ); +/* DBG_ASSERT( m_rControl.m_pModel->hasRowHeaders(), + "TableColumnGeometry::TableColumnGeometry: why asking for the geoemtry of the non-existent row header column?" )*/; m_aRect.Left() = 0; m_aRect.Right() = m_rControl.m_nRowHeaderWidthPixel - 1; } diff --git a/svtools/source/uno/svtxgridcontrol.cxx b/svtools/source/uno/svtxgridcontrol.cxx index 80c31e65d4f1..b411181c2aab 100755 --- a/svtools/source/uno/svtxgridcontrol.cxx +++ b/svtools/source/uno/svtxgridcontrol.cxx @@ -28,6 +28,7 @@ #include "precompiled_svtools.hxx" #include "svtxgridcontrol.hxx" +#include "accessibletableimp.hxx" #include <com/sun/star/view/SelectionType.hpp> #include "svtools/table/gridtablerenderer.hxx" #include "svtools/table/defaultinputhandler.hxx" @@ -37,12 +38,17 @@ #include <rtl/ref.hxx> #include <tools/debug.hxx> #include <toolkit/helper/property.hxx> +#include <toolkit/helper/vclunohelper.hxx> #include <comphelper/processfactory.hxx> #include <com/sun/star/awt/grid/XGridColumn.hpp> #include <com/sun/star/accessibility/AccessibleTableModelChange.hpp> #include <com/sun/star/accessibility/AccessibleTableModelChangeType.hpp> #include <com/sun/star/accessibility/AccessibleEventId.hpp> - +#include <com/sun/star/awt/XControl.hpp> +#include <com/sun/star/awt/grid/GridInvalidDataException.hpp> +#include <com/sun/star/awt/grid/GridInvalidModelException.hpp> +#include <com/sun/star/util/Color.hpp> +#include <com/sun/star/awt/FontDescriptor.hpp> using ::rtl::OUString; using namespace ::svt::table; @@ -63,7 +69,10 @@ SVTXGridControl::SVTXGridControl() m_bHasColumnHeaders(false), m_bHasRowHeaders(false), m_bVScroll(false), - m_bHScroll(false) + m_bHScroll(false), + m_bUpdate(false), + m_nSelectedRowCount(0), + m_aSelectionListeners( *this ) { } @@ -76,9 +85,10 @@ SVTXGridControl::~SVTXGridControl() ::com::sun::star::uno::Any SVTXGridControl::queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException) { ::com::sun::star::uno::Any aRet = ::cppu::queryInterface( rType, - SAL_STATIC_CAST( ::com::sun::star::awt::grid::XGridControl*, this ), - SAL_STATIC_CAST( ::com::sun::star::awt::grid::XGridDataListener*, this ), - SAL_STATIC_CAST( ::com::sun::star::lang::XTypeProvider*, this ) ); + SAL_STATIC_CAST( ::com::sun::star::awt::grid::XGridControl*, this ), + SAL_STATIC_CAST( ::com::sun::star::awt::grid::XGridDataListener*, this ), + SAL_STATIC_CAST( ::com::sun::star::awt::grid::XGridColumnListener*, this ), + SAL_STATIC_CAST( ::com::sun::star::lang::XTypeProvider*, this ) ); return (aRet.hasValue() ? aRet : VCLXWindow::queryInterface( rType )); } @@ -90,36 +100,26 @@ IMPL_XTYPEPROVIDER_START( SVTXGridControl ) VCLXWindow::getTypes() IMPL_XTYPEPROVIDER_END -::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumnModel > SAL_CALL SVTXGridControl::getColumnModel( ) throw (::com::sun::star::uno::RuntimeException) -{ - return NULL; -} -void SAL_CALL SVTXGridControl::setColumnModel( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumnModel >& model ) throw (::com::sun::star::uno::RuntimeException) -{ - (void)model; -} -::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridDataModel > SAL_CALL SVTXGridControl::getDataModel( ) throw (::com::sun::star::uno::RuntimeException) -{ - return NULL; -} -void SAL_CALL SVTXGridControl::setDataModel( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridDataModel >& model ) throw (::com::sun::star::uno::RuntimeException) -{ - (void)model; -} sal_Int32 SAL_CALL SVTXGridControl::getItemIndexAtPoint(::sal_Int32 x, ::sal_Int32 y) throw (::com::sun::star::uno::RuntimeException) { TableControl* pTable = (TableControl*)GetWindow(); return pTable->GetCurrentRow( Point(x,y) ); } +void SAL_CALL SVTXGridControl::setToolTip(const ::com::sun::star::uno::Sequence< ::rtl::OUString >& text, const com::sun::star::uno::Sequence< sal_Int32 >& columns) throw (::com::sun::star::uno::RuntimeException) +{ + TableControl* pTable = (TableControl*)GetWindow(); + pTable->setTooltip(text, columns); +} + void SAL_CALL SVTXGridControl::addSelectionListener(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridSelectionListener > & listener) throw (::com::sun::star::uno::RuntimeException) { - (void)listener; + m_aSelectionListeners.addInterface(listener); } void SAL_CALL SVTXGridControl::removeSelectionListener(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridSelectionListener > & listener) throw (::com::sun::star::uno::RuntimeException) { - (void) listener; + m_aSelectionListeners.removeInterface(listener); } void SVTXGridControl::setProperty( const ::rtl::OUString& PropertyName, const Any& aValue) throw(RuntimeException) @@ -127,7 +127,6 @@ void SVTXGridControl::setProperty( const ::rtl::OUString& PropertyName, const An ::vos::OGuard aGuard( GetMutex() ); TableControl* pTable = (TableControl*)GetWindow(); - switch( GetPropertyId( PropertyName ) ) { case BASEPROPERTY_GRID_SELECTIONMODE: @@ -155,6 +154,7 @@ void SVTXGridControl::setProperty( const ::rtl::OUString& PropertyName, const An if( aValue >>= bHScroll ) { m_bHScroll = bHScroll; + m_pTableModel->setHorizontalScrollbarVisibility(bHScroll); } break; } @@ -164,9 +164,11 @@ void SVTXGridControl::setProperty( const ::rtl::OUString& PropertyName, const An if( aValue >>= bVScroll ) { m_bVScroll = bVScroll; + m_pTableModel->setVerticalScrollbarVisibility(bVScroll); } break; } + case BASEPROPERTY_GRID_SHOWROWHEADER: { sal_Bool rowHeader = true; @@ -176,6 +178,66 @@ void SVTXGridControl::setProperty( const ::rtl::OUString& PropertyName, const An } break; } + case BASEPROPERTY_GRID_HEADER_BACKGROUND: + { + sal_Int32 colorHeader = 0x000000; + if( aValue >>= colorHeader ) + { + m_pTableModel->setHeaderBackgroundColor(colorHeader); + } + break; + } + case BASEPROPERTY_GRID_LINE_COLOR: + { + sal_Int32 colorLine = 0x000000; + if( aValue >>= colorLine ) + { + m_pTableModel->setLineColor(colorLine); + } + break; + } + case BASEPROPERTY_GRID_EVEN_ROW_BACKGROUND: + { + sal_Int32 colorEvenRow = 0x000000; + if( aValue >>= colorEvenRow ) + { + m_pTableModel->setEvenRowBackgroundColor(colorEvenRow); + } + break; + } + case BASEPROPERTY_GRID_ROW_BACKGROUND: + { + sal_Int32 colorBackground = 0x000000; + if( aValue >>= colorBackground ) + { + m_pTableModel->setOddRowBackgroundColor(colorBackground); + } + break; + } + case BASEPROPERTY_TEXTCOLOR: + { + sal_Int32 colorText = 0xFFFFFF; + if( aValue >>= colorText ) + { + m_pTableModel->setTextColor(colorText); + } + break; + } + case BASEPROPERTY_VERTICALALIGN: + { + com::sun::star::style::VerticalAlignment vAlign(com::sun::star::style::VerticalAlignment(0)); + if( aValue >>= vAlign ) + { + switch( vAlign ) + { + case com::sun::star::style::VerticalAlignment_TOP: m_pTableModel->setVerticalAlign(com::sun::star::style::VerticalAlignment(0)); break; + case com::sun::star::style::VerticalAlignment_MIDDLE: m_pTableModel->setVerticalAlign(com::sun::star::style::VerticalAlignment(1)); break; + case com::sun::star::style::VerticalAlignment_BOTTOM: m_pTableModel->setVerticalAlign(com::sun::star::style::VerticalAlignment(2)); break; + default: m_pTableModel->setVerticalAlign(com::sun::star::style::VerticalAlignment(0)); break; + } + } + break; + } case BASEPROPERTY_GRID_SHOWCOLUMNHEADER: { @@ -188,40 +250,97 @@ void SVTXGridControl::setProperty( const ::rtl::OUString& PropertyName, const An } case BASEPROPERTY_GRID_DATAMODEL: { - m_xDataModel = Reference< XGridDataModel >( aValue, UNO_QUERY ); - Sequence<Sequence< ::rtl::OUString > > cellData = m_xDataModel->getData(); - Sequence<rtl::OUString> rowData(0); - std::vector< std::vector< rtl::OUString > > aCellContent(0); - for(int i = 0; i< m_xDataModel->getRowCount();++i) { - rowData = cellData[i]; - std::vector<rtl::OUString> newRow( - comphelper::sequenceToContainer< std::vector<rtl::OUString > >(rowData)); - if(newRow.size() < (unsigned)m_pTableModel->getColumnCount()) - newRow.resize( m_pTableModel->getColumnCount(),rtl::OUString::createFromAscii("")); - aCellContent.push_back(newRow); + m_xDataModel = Reference< XGridDataModel >( aValue, UNO_QUERY ); + if(m_xDataModel != NULL) + { + Sequence<Sequence< Any > > cellData = m_xDataModel->getData(); + if(cellData.getLength()!= 0) + { + for (int i = 0; i < cellData.getLength(); i++) + { + std::vector< Any > newRow; + Sequence< Any > rawRowData = cellData[i]; + //check whether the data row vector length matches with the column count + if(m_xColumnModel->getColumnCount() == 0) + { + for ( ::svt::table::ColPos col = 0; col < rawRowData.getLength(); ++col ) + { + UnoControlTableColumn* tableColumn = new UnoControlTableColumn(); + m_pTableModel->getColumnModel().push_back((PColumnModel)tableColumn); + } + m_xColumnModel->setDefaultColumns(rawRowData.getLength()); + } + else + if((unsigned int)rawRowData.getLength()!=(unsigned)m_pTableModel->getColumnCount()) + throw GridInvalidDataException(rtl::OUString::createFromAscii("The column count doesn't match with the length of row data"), m_xDataModel); + + for ( int k = 0; k < rawRowData.getLength(); k++) + { + newRow.push_back(rawRowData[k]); + } + m_pTableModel->getCellContent().push_back(newRow); + } + + Sequence< ::rtl::OUString > rowHeaders = m_xDataModel->getRowHeaders(); + std::vector< rtl::OUString > newRow( + comphelper::sequenceToContainer< std::vector<rtl::OUString > >(rowHeaders)); + m_pTableModel->setRowCount(m_xDataModel->getRowCount()); + m_pTableModel->setRowHeaderName(newRow); + } + } + else + throw GridInvalidDataException(rtl::OUString::createFromAscii("The data model isn't set!"), m_xDataModel); + sal_Int32 fontHeight = pTable->PixelToLogic( Size( 0, pTable->GetTextHeight()+3 ), MAP_APPFONT ).Height(); + if(m_xDataModel->getRowHeight() == 0) + { + m_pTableModel->setRowHeight(fontHeight); + m_xDataModel->setRowHeight(fontHeight); + } + else + m_pTableModel->setRowHeight(m_xDataModel->getRowHeight()); + m_pTableModel->setRowHeaderWidth(m_xDataModel->getRowHeaderWidth()); } - m_pTableModel->setCellContent(aCellContent); - Sequence< ::rtl::OUString > rowHeaders = m_xDataModel->getRowHeaders(); - std::vector< rtl::OUString > newRow( - comphelper::sequenceToContainer< std::vector<rtl::OUString > >(rowHeaders)); - m_pTableModel->setRowCount(m_xDataModel->getRowCount()); - m_pTableModel->setRowHeaderName(newRow); break; } case BASEPROPERTY_GRID_COLUMNMODEL: { m_xColumnModel = Reference< XGridColumnModel >( aValue, UNO_QUERY ); - Sequence<Reference< XGridColumn > > columns = m_xColumnModel->getColumns(); - std::vector<Reference< XGridColumn > > aNewColumns( - comphelper::sequenceToContainer<std::vector<Reference< XGridColumn > > >(columns)); - /* if(m_pTable->GetColumnCount().size()>0) - m_pTable->GetColumnName.clear();*/ - for ( ::svt::table::ColPos col = 0; col < m_xColumnModel->getColumnCount(); ++col ) + if(m_xColumnModel != NULL) { - UnoControlTableColumn* tableColumn = new UnoControlTableColumn(aNewColumns[col]); - m_pTableModel->getColumnModel().push_back((PColumnModel)tableColumn); + if(m_xColumnModel->getColumnCount() != 0) + { + Sequence<Reference< XGridColumn > > columns = m_xColumnModel->getColumns(); + std::vector<Reference< XGridColumn > > aNewColumns( + comphelper::sequenceToContainer<std::vector<Reference< XGridColumn > > >(columns)); + sal_Int32 fontHeight = pTable->PixelToLogic( Size( 0, pTable->GetTextHeight()+3 ), MAP_APPFONT ).Height(); + if(m_xColumnModel->getColumnHeaderHeight() == 0) + { + m_pTableModel->setColumnHeaderHeight(fontHeight); + m_xColumnModel->setColumnHeaderHeight(fontHeight); + } + else + m_pTableModel->setColumnHeaderHeight(m_xColumnModel->getColumnHeaderHeight()); + for ( ::svt::table::ColPos col = 0; col < m_xColumnModel->getColumnCount(); ++col ) + { + UnoControlTableColumn* tableColumn = new UnoControlTableColumn(aNewColumns[col]); + Reference< XGridColumn > xGridColumn = m_xColumnModel->getColumn(col); + m_pTableModel->getColumnModel().push_back((PColumnModel)tableColumn); + tableColumn->setHorizontalAlign(xGridColumn->getHorizontalAlign()); + tableColumn->setWidth(xGridColumn->getColumnWidth()); + if(xGridColumn->getPreferredWidth() != 0) + tableColumn->setPreferredWidth(xGridColumn->getPreferredWidth()); + if(xGridColumn->getMaxWidth() != 0) + tableColumn->setMaxWidth(xGridColumn->getMaxWidth()); + if(xGridColumn->getMinWidth() != 0) + tableColumn->setMinWidth(xGridColumn->getMinWidth()); + tableColumn->setResizable(xGridColumn->getResizeable()); + } + } } + else + throw GridInvalidModelException(rtl::OUString::createFromAscii("The column model isn't set!"), m_xColumnModel); + break; } default: @@ -281,7 +400,11 @@ void SVTXGridControl::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds ) BASEPROPERTY_GRID_SHOWCOLUMNHEADER, BASEPROPERTY_GRID_DATAMODEL, BASEPROPERTY_GRID_COLUMNMODEL, - BASEPROPERTY_GRID_SELECTIONMODE, + BASEPROPERTY_GRID_SELECTIONMODE, + BASEPROPERTY_GRID_EVEN_ROW_BACKGROUND, + BASEPROPERTY_GRID_HEADER_BACKGROUND, + BASEPROPERTY_GRID_LINE_COLOR, + BASEPROPERTY_GRID_ROW_BACKGROUND, 0); VCLXWindow::ImplGetPropertyIds( rIds, true ); } @@ -291,7 +414,6 @@ void SAL_CALL SVTXGridControl::setVisible( sal_Bool bVisible ) throw(::com::sun: if ( pTable ) { pTable->SetModel(PTableModel(m_pTableModel)); - //m_pTable->SetPosSizePixel( Point( nPosX, nPosY ), Size(nWidth, nHeight) ); pTable->Show( bVisible ); } } @@ -303,17 +425,32 @@ void SAL_CALL SVTXGridControl::setFocus() throw(::com::sun::star::uno::RuntimeEx } void SAL_CALL SVTXGridControl::rowAdded(const ::com::sun::star::awt::grid::GridDataEvent& Event ) throw (::com::sun::star::uno::RuntimeException) { - std::vector<OUString> aNewRow( - comphelper::sequenceToContainer< std::vector<rtl::OUString > >(Event.rowData)); - if(aNewRow.size()< (unsigned)m_pTableModel->getColumnCount()) - aNewRow.resize(m_pTableModel->getColumnCount(),rtl::OUString::createFromAscii("")); - m_pTableModel->getCellContent().push_back(aNewRow); + std::vector< Any > newRow; + Sequence< Any > rawRowData = Event.rowData; + int colCount = m_xColumnModel->getColumnCount(); + if(colCount == 0) + { + Reference<XGridColumnListener> listener(*this,UNO_QUERY_THROW); + m_xColumnModel->setDefaultColumns(rawRowData.getLength()); + for ( ::svt::table::ColPos col = 0; col < rawRowData.getLength(); ++col ) + { + UnoControlTableColumn* tableColumn = new UnoControlTableColumn(); + m_pTableModel->getColumnModel().push_back((PColumnModel)tableColumn); + m_xColumnModel->getColumn(col)->addColumnListener(listener); + } + + } + else if((unsigned int)rawRowData.getLength()!=(unsigned)colCount) + throw GridInvalidDataException(rtl::OUString::createFromAscii("The column count doesn't match with the length of row data"), m_xDataModel); + + for ( int k = 0; k < rawRowData.getLength(); k++) + newRow.push_back(rawRowData[k]); + m_pTableModel->getCellContent().push_back(newRow); if(m_pTableModel->hasRowHeaders()) m_pTableModel->getRowHeaderName().push_back(Event.headerName); - m_pTableModel->setRowCount(m_pTableModel->getRowHeaderName().size()); + m_pTableModel->setRowCount(m_pTableModel->getCellContent().size()); TableControl* pTable = (TableControl*)GetWindow(); - pTable->InvalidateDataWindow(m_pTableModel->getRowHeaderName().size()-1, false); - //pTable->GrabFocus(); + pTable->InvalidateDataWindow(m_pTableModel->getCellContent().size()-1, 0, false); if(pTable->isAccessibleAlive()) { pTable->commitGridControlEvent(TABLE_MODEL_CHANGED, @@ -335,9 +472,10 @@ void SAL_CALL SVTXGridControl::rowAdded(const ::com::sun::star::awt::grid::GridD void SAL_CALL SVTXGridControl::rowRemoved(const ::com::sun::star::awt::grid::GridDataEvent& Event ) throw (::com::sun::star::uno::RuntimeException) { TableControl* pTable = (TableControl*)GetWindow(); - //unsigned int rows =m_pImpl->aCellContent.size()-1; if(Event.index == -1) { + if(!isSelectionEmpty()) + deselectAllRows(); if(m_pTableModel->hasRowHeaders()) m_pTableModel->getRowHeaderName().clear(); m_pTableModel->getCellContent().clear(); @@ -348,76 +486,242 @@ void SAL_CALL SVTXGridControl::rowRemoved(const ::com::sun::star::awt::grid::Gri Any()); } } - else + else if(Event.index >= 0 && Event.index < m_pTableModel->getRowCount()) { - pTable->removeSelectedRow(Event.index); - if(m_pTableModel->getCellContent().size()>1) + if(isSelectedIndex(Event.index)) { - if(m_pTableModel->hasRowHeaders()) - m_pTableModel->getRowHeaderName().erase(m_pTableModel->getRowHeaderName().begin()+Event.index); - m_pTableModel->getCellContent().erase(m_pTableModel->getCellContent().begin()+Event.index); - - } - else - { - if(m_pTableModel->hasRowHeaders()) - m_pTableModel->getRowHeaderName().clear(); - m_pTableModel->getCellContent().clear(); - //m_pImpl->nRowCount=0; + Sequence<sal_Int32> selected(1); + selected[0]=Event.index; + deselectRows(selected); } + if(m_pTableModel->hasRowHeaders()) + m_pTableModel->getRowHeaderName().erase(m_pTableModel->getRowHeaderName().begin()+Event.index); + std::vector<std::vector<Any> >::iterator rowPos =m_pTableModel->getCellContent().begin() + Event.index; + m_pTableModel->getCellContent().erase( rowPos ); } - //pTable->InvalidateDataWindow(Event.index, true); m_pTableModel->setRowCount(m_pTableModel->getCellContent().size()); - pTable->InvalidateDataWindow(Event.index, true); + pTable->InvalidateDataWindow(Event.index, Event.index, true); if(pTable->isAccessibleAlive()) { pTable->commitGridControlEvent(TABLE_MODEL_CHANGED, makeAny( AccessibleTableModelChange(DELETE, Event.index, Event.index+1, 0, m_pTableModel->getColumnCount())), Any()); - //pTable->commitGridControlEvent(CHILD, - // makeAny( pTable->m_pAccessTable->m_pAccessible->getTableHeader(TCTYPE_ROWHEADERBAR)), - // Any()); - //for (sal_Int32 i = 0 ; i <= m_pTableModel->getColumnCount() ; ++i) - //{ - // pTable->commitGridControlEvent( - // CHILD, - // makeAny( pTable->m_pAccessTable->m_pAccessible->getTable() ), - // Any()); - //} } - //pTable->Invalidate(); } +void SAL_CALL SVTXGridControl::columnChanged(const ::com::sun::star::awt::grid::GridColumnEvent& Event ) throw (::com::sun::star::uno::RuntimeException) +{ + TableControl* pTable = (TableControl*)GetWindow(); + if(Event.valueName == rtl::OUString::createFromAscii("ColumnResize")) + { + bool resizable = m_pTableModel->getColumnModel()[Event.index]->isResizable(); + Event.newValue>>=resizable; + m_pTableModel->getColumnModel()[Event.index]->setResizable(resizable); + } + else if(Event.valueName == rtl::OUString::createFromAscii("ColWidth")) + { + sal_Int32 colWidth = m_pTableModel->getColumnModel()[Event.index]->getWidth(); + Event.newValue>>=colWidth; + m_pTableModel->getColumnModel()[Event.index]->setWidth(colWidth); + } + else if(Event.valueName == rtl::OUString::createFromAscii("MaxWidth")) + { + sal_Int32 maxWidth = m_pTableModel->getColumnModel()[Event.index]->getMaxWidth(); + Event.newValue>>=maxWidth; + m_pTableModel->getColumnModel()[Event.index]->setMaxWidth(maxWidth); + } + else if(Event.valueName == rtl::OUString::createFromAscii("MinWidth")) + { + sal_Int32 minWidth = m_pTableModel->getColumnModel()[Event.index]->getMinWidth(); + Event.newValue>>=minWidth; + m_pTableModel->getColumnModel()[Event.index]->setMinWidth(minWidth); + } + else if(Event.valueName == rtl::OUString::createFromAscii("PrefWidth")) + { + sal_Int32 prefWidth = m_pTableModel->getColumnModel()[Event.index]->getPreferredWidth(); + Event.newValue>>=prefWidth; + m_pTableModel->getColumnModel()[Event.index]->setPreferredWidth(prefWidth); + } + else if(Event.valueName == rtl::OUString::createFromAscii("HAlign")) + { + ::com::sun::star::style::HorizontalAlignment hAlign = m_pTableModel->getColumnModel()[Event.index]->getHorizontalAlign(); + Event.newValue>>=hAlign; + m_pTableModel->getColumnModel()[Event.index]->setHorizontalAlign(hAlign); + } + else if(Event.valueName == rtl::OUString::createFromAscii("UpdateWidth")) + { + if(m_pTableModel->getColumnModel()[Event.index]->getPreferredWidth() != 0) + m_xColumnModel->getColumn(Event.index)->updateColumn(rtl::OUString::createFromAscii("PrefWidth"), m_pTableModel->getColumnModel()[Event.index]->getPreferredWidth()); + m_xColumnModel->getColumn(Event.index)->updateColumn(rtl::OUString::createFromAscii("ColWidth"), m_pTableModel->getColumnModel()[Event.index]->getWidth()); + } + pTable->Invalidate(); +} void SAL_CALL SVTXGridControl::dataChanged(const ::com::sun::star::awt::grid::GridDataEvent& Event ) throw (::com::sun::star::uno::RuntimeException) { - (void) Event; + TableControl* pTable = (TableControl*)GetWindow(); + if(Event.valueName == rtl::OUString::createFromAscii("RowHeight")) + { + sal_Int32 rowHeight = m_pTableModel->getRowHeight(); + Event.newValue>>=rowHeight; + m_pTableModel->setRowHeight(rowHeight); + pTable->Invalidate(); + } + else if(Event.valueName == rtl::OUString::createFromAscii("RowHeaderWidth")) + { + sal_Int32 rowHeaderWidth = m_pTableModel->getRowHeaderWidth(); + Event.newValue>>=rowHeaderWidth; + m_pTableModel->setRowHeaderWidth(rowHeaderWidth); + pTable->Invalidate(); + } + else if(Event.valueName == rtl::OUString::createFromAscii("RowHeaders")) + { + Sequence< rtl::OUString > headers(0); + Event.newValue>>=headers; + std::vector< rtl::OUString > headerNames( comphelper::sequenceToContainer <std::vector< rtl::OUString > >(headers) ); + m_pTableModel->setRowHeaderName(headerNames); + pTable->Invalidate(); + } + else if(Event.valueName == rtl::OUString::createFromAscii("CellUpdated")) + { + std::vector< std::vector< Any > >& rowContent = m_pTableModel->getCellContent(); + sal_Int32 col = -1; + Event.oldValue>>=col; + rowContent[Event.index][col] = Event.newValue; + pTable->InvalidateDataWindow(Event.index, Event.index, false); + } + else if(Event.valueName == rtl::OUString::createFromAscii("RowUpdated")) + { + std::vector<std::vector< Any > >& rowContent = m_pTableModel->getCellContent(); + Sequence< sal_Int32 > cols(0); + Sequence< Any > values(0); + Event.oldValue>>=cols; + Event.newValue>>=values; + for(int i = 0; i< cols.getLength(); i++) + { + if(cols[i]>=0 && cols[i]<m_pTableModel->getColumnCount()) + rowContent[Event.index][cols[i]]=values[i]; + else + break; + } + pTable->InvalidateDataWindow(Event.index, Event.index, false); + } } - void SAL_CALL SVTXGridControl::disposing( const ::com::sun::star::lang::EventObject& Source ) throw(::com::sun::star::uno::RuntimeException) - { +void SAL_CALL SVTXGridControl::disposing( const ::com::sun::star::lang::EventObject& Source ) throw(::com::sun::star::uno::RuntimeException) +{ VCLXWindow::disposing( Source ); - } +} ::sal_Int32 SAL_CALL SVTXGridControl::getMinSelectionIndex() throw (::com::sun::star::uno::RuntimeException) { - return 0; + TableControl* pTable = (TableControl*)GetWindow(); + std::vector<RowPos>& selectedRows = pTable->GetSelectedRows(); + if(selectedRows.empty()) + return -1; + else + { + std::vector<RowPos>::iterator itStart = selectedRows.begin(); + std::vector<RowPos>::iterator itEnd = selectedRows.end(); + return *(std::min_element(itStart, itEnd)); + } } ::sal_Int32 SAL_CALL SVTXGridControl::getMaxSelectionIndex() throw (::com::sun::star::uno::RuntimeException) { - return 0; + TableControl* pTable = (TableControl*)GetWindow(); + std::vector<RowPos>& selectedRows = pTable->GetSelectedRows(); + if(selectedRows.empty()) + return -1; + else + { + std::vector<RowPos>::iterator itStart = selectedRows.begin(); + std::vector<RowPos>::iterator itEnd = selectedRows.end(); + return *(std::max_element(itStart, itEnd)); + } +} + +void SAL_CALL SVTXGridControl::selectRows(const ::com::sun::star::uno::Sequence< ::sal_Int32 >& rangeOfRows) throw (::com::sun::star::uno::RuntimeException) +{ + TableControl* pTable = (TableControl*)GetWindow(); + SelectionMode eSelMode = pTable->getSelEngine()->GetSelectionMode(); + if(eSelMode != NO_SELECTION) + { + sal_Int32 start = rangeOfRows[0]; + int seqSize = rangeOfRows.getLength(); + sal_Int32 end = rangeOfRows[seqSize-1]; + if((start >= 0 && start < m_pTableModel->getRowCount()) && (end >= 0 && end < m_pTableModel->getRowCount())) + { + std::vector<RowPos>& selectedRows = pTable->GetSelectedRows(); + if(!selectedRows.empty()) + selectedRows.clear(); + if(eSelMode == SINGLE_SELECTION) + { + if(rangeOfRows.getLength() == 1) + selectedRows.push_back(start); + else + return; + } + else + { + for(int i=0;i<seqSize;i++) + selectedRows.push_back(rangeOfRows[i]); + } + pTable->selectionChanged(true); + pTable->InvalidateDataWindow(start, end, false); + SetSynthesizingVCLEvent( sal_True ); + pTable->Select(); + SetSynthesizingVCLEvent( sal_False ); + } + } } -void SAL_CALL SVTXGridControl::insertIndexIntervall(::sal_Int32 start, ::sal_Int32 length) throw (::com::sun::star::uno::RuntimeException) +void SAL_CALL SVTXGridControl::selectAllRows() throw (::com::sun::star::uno::RuntimeException) { - (void)length; - (void)start; + TableControl* pTable = (TableControl*)GetWindow(); + SelectionMode eSelMode = pTable->getSelEngine()->GetSelectionMode(); + if(eSelMode != NO_SELECTION) + { + std::vector<RowPos>& selectedRows = pTable->GetSelectedRows(); + if(!selectedRows.empty()) + selectedRows.clear(); + for(int i=0;i<m_pTableModel->getRowCount();i++) + selectedRows.push_back(i); + pTable->Invalidate(); + SetSynthesizingVCLEvent( sal_True ); + pTable->Select(); + SetSynthesizingVCLEvent( sal_False ); + } +} +void SAL_CALL SVTXGridControl::deselectRows(const ::com::sun::star::uno::Sequence< ::sal_Int32 >& rangeOfRows) throw (::com::sun::star::uno::RuntimeException) +{ + TableControl* pTable = (TableControl*)GetWindow(); + std::vector<RowPos>& selectedRows = pTable->GetSelectedRows(); + std::vector<RowPos>::iterator itStart = selectedRows.begin(); + std::vector<RowPos>::iterator itEnd = selectedRows.end(); + sal_Int32 start = rangeOfRows[0]; + sal_Int32 end = rangeOfRows[rangeOfRows.getLength()-1]; + if((start >= 0 && start < m_pTableModel->getRowCount()) && (end >= 0 && end < m_pTableModel->getRowCount())) + { + std::vector<RowPos>::iterator iter = std::find(itStart, itEnd, start); + selectedRows.erase(iter, iter+(end-start)+1); + pTable->selectionChanged(true); + pTable->InvalidateDataWindow(start, end, false); + SetSynthesizingVCLEvent( sal_True ); + pTable->Select(); + SetSynthesizingVCLEvent( sal_False ); + } } -void SAL_CALL SVTXGridControl::removeIndexIntervall(::sal_Int32 start, ::sal_Int32 end) throw (::com::sun::star::uno::RuntimeException) +void SAL_CALL SVTXGridControl::deselectAllRows() throw (::com::sun::star::uno::RuntimeException) { - (void)end; - (void)start; + TableControl* pTable = (TableControl*)GetWindow(); + std::vector<RowPos>& selectedRows = pTable->GetSelectedRows(); + if(!selectedRows.empty()) + selectedRows.clear(); + pTable->Invalidate(); + SetSynthesizingVCLEvent( sal_True ); + pTable->Select(); + SetSynthesizingVCLEvent( sal_False ); } ::com::sun::star::uno::Sequence< ::sal_Int32 > SAL_CALL SVTXGridControl::getSelection() throw (::com::sun::star::uno::RuntimeException) @@ -435,21 +739,138 @@ void SAL_CALL SVTXGridControl::removeIndexIntervall(::sal_Int32 start, ::sal_Int ::sal_Bool SAL_CALL SVTXGridControl::isSelectionEmpty() throw (::com::sun::star::uno::RuntimeException) { - return sal_False; + TableControl* pTable = (TableControl*)GetWindow(); + std::vector<RowPos>& selectedRows = pTable->GetSelectedRows(); + if(selectedRows.empty()) + return sal_True; + else + return sal_False; } ::sal_Bool SAL_CALL SVTXGridControl::isSelectedIndex(::sal_Int32 index) throw (::com::sun::star::uno::RuntimeException) { - (void)index; - return sal_False; + TableControl* pTable = (TableControl*)GetWindow(); + std::vector<RowPos>& selectedRows = pTable->GetSelectedRows(); + return std::find(selectedRows.begin(),selectedRows.end(), index) != selectedRows.end(); } -void SAL_CALL SVTXGridControl::selectRow(::sal_Int32 y) throw (::com::sun::star::uno::RuntimeException) +void SAL_CALL SVTXGridControl::selectRow(::sal_Int32 index) throw (::com::sun::star::uno::RuntimeException) { - (void)y; + if(index<0 || index>=m_pTableModel->getRowCount()) + return; + TableControl* pTable = (TableControl*)GetWindow(); + SelectionMode eSelMode = pTable->getSelEngine()->GetSelectionMode(); + if(eSelMode != NO_SELECTION) + { + std::vector<RowPos>& selectedRows = pTable->GetSelectedRows(); + if(eSelMode == MULTIPLE_SELECTION) + { + if(!isSelectedIndex(index)) + selectedRows.push_back(index); + else + return; + } + else if(eSelMode == SINGLE_SELECTION) + { + if(!selectedRows.empty()) + { + if(!isSelectedIndex(index)) + deselectRows(getSelection()); + else + return; + } + selectedRows.push_back(index); + } + pTable->selectionChanged(true); + pTable->InvalidateDataWindow(index, index, false); + SetSynthesizingVCLEvent( sal_True ); + pTable->Select(); + SetSynthesizingVCLEvent( sal_False ); + } } void SAL_CALL SVTXGridControl::selectColumn(::sal_Int32 x) throw (::com::sun::star::uno::RuntimeException) { (void)x; } +void SVTXGridControl::dispose() throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + ::com::sun::star::lang::EventObject aObj; + aObj.Source = (::cppu::OWeakObject*)this; + m_aSelectionListeners.disposeAndClear( aObj ); + VCLXWindow::dispose(); +} + +void SVTXGridControl::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) +{ + ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow > xKeepAlive( this ); + + switch ( rVclWindowEvent.GetId() ) + { + case VCLEVENT_TABLEROW_SELECT: + { + TableControl* pTable = (TableControl*)GetWindow(); + + if( pTable ) + { + if ( m_aSelectionListeners.getLength() ) + { + ImplCallItemListeners(); + } + } + } + break; + + default: + VCLXWindow::ProcessWindowEvent( rVclWindowEvent ); + break; + } +} + +void SVTXGridControl::ImplCallItemListeners() +{ + TableControl* pTable = (TableControl*) GetWindow(); + if ( pTable && m_aSelectionListeners.getLength() ) + { + ::std::vector<sal_Int32> selRows = pTable->GetSelectedRows(); + ::com::sun::star::awt::grid::GridSelectionEvent aEvent; + aEvent.Source = (::cppu::OWeakObject*)this; + aEvent.Column = 0; + sal_Int32 actSelRowCount = selRows.size(); + sal_Int32 diff = actSelRowCount - m_nSelectedRowCount; + //row added to selection + if(diff >= 1) + { + aEvent.Action = com::sun::star::awt::grid::SelectionEventType(0); + aEvent.Row = selRows[actSelRowCount-1]; + aEvent.Range = diff; + } + //selected row changed + else if(diff == 0) + { + aEvent.Row = selRows[actSelRowCount-1]; + aEvent.Action = com::sun::star::awt::grid::SelectionEventType(2); + aEvent.Range = 0; + } + else + { + //selection changed: multiple row deselected, only 1 row is selected + if(actSelRowCount == 1) + { + aEvent.Row = selRows[actSelRowCount-1]; + aEvent.Action = com::sun::star::awt::grid::SelectionEventType(2); + } + //row is deselected + else + { + aEvent.Row = pTable->GetCurrentRow(); + aEvent.Action = com::sun::star::awt::grid::SelectionEventType(1); + } + aEvent.Range = 0; + } + m_nSelectedRowCount=actSelRowCount; + m_aSelectionListeners.selectionChanged( aEvent ); + } +} diff --git a/svtools/source/uno/svtxgridcontrol.hxx b/svtools/source/uno/svtxgridcontrol.hxx index 8e6931d0d805..bcb8badf72e5 100755 --- a/svtools/source/uno/svtxgridcontrol.hxx +++ b/svtools/source/uno/svtxgridcontrol.hxx @@ -32,21 +32,23 @@ #include <svtools/table/tablecontrol.hxx> #include <com/sun/star/awt/grid/XGridControl.hpp> #include <com/sun/star/awt/grid/XGridDataListener.hpp> +#include <com/sun/star/awt/grid/XGridColumnListener.hpp> #include <com/sun/star/awt/grid/GridDataEvent.hpp> +#include <com/sun/star/awt/grid/GridColumnEvent.hpp> #include <com/sun/star/awt/grid/XGridColumnModel.hpp> #include <com/sun/star/awt/grid/XGridDataModel.hpp> #include <com/sun/star/awt/grid/XGridSelectionListener.hpp> #include <toolkit/awt/vclxwindow.hxx> #include <toolkit/awt/vclxwindows.hxx> #include <cppuhelper/typeprovider.hxx> -#include <cppuhelper/implbase2.hxx> -//#include <toolkit/helper/listenermultiplexer.hxx> +#include <cppuhelper/implbase3.hxx> +#include <toolkit/helper/listenermultiplexer.hxx> using namespace ::svt::table; -class SVTXGridControl : public ::cppu::ImplInheritanceHelper2< VCLXWindow, ::com::sun::star::awt::grid::XGridControl, - ::com::sun::star::awt::grid::XGridDataListener> +class SVTXGridControl : public ::cppu::ImplInheritanceHelper3< VCLXWindow, ::com::sun::star::awt::grid::XGridControl, + ::com::sun::star::awt::grid::XGridDataListener, ::com::sun::star::awt::grid::XGridColumnListener> { private: UnoControlTableModel* m_pTableModel; @@ -56,34 +58,42 @@ private: bool m_bHasRowHeaders; bool m_bVScroll; bool m_bHScroll; + bool m_bUpdate; + sal_Int32 m_nSelectedRowCount; + SelectionListenerMultiplexer m_aSelectionListeners; + +protected: + virtual void ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ); + void ImplCallItemListeners(); public: - SVTXGridControl(); + SVTXGridControl(); ~SVTXGridControl(); //XGridDataListener overridables virtual void SAL_CALL rowAdded(const ::com::sun::star::awt::grid::GridDataEvent& Event) throw (::com::sun::star::uno::RuntimeException); virtual void SAL_CALL rowRemoved(const ::com::sun::star::awt::grid::GridDataEvent & Event) throw (::com::sun::star::uno::RuntimeException); virtual void SAL_CALL dataChanged(const ::com::sun::star::awt::grid::GridDataEvent & Event) throw (::com::sun::star::uno::RuntimeException); + + //XGridColumnListener overridables + virtual void SAL_CALL columnChanged(const ::com::sun::star::awt::grid::GridColumnEvent & Event) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw(::com::sun::star::uno::RuntimeException); - ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException); - void SAL_CALL acquire() throw() { VCLXWindow::acquire(); } - void SAL_CALL release() throw() { VCLXWindow::release(); } + ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException); + void SAL_CALL acquire() throw() { VCLXWindow::acquire(); } + void SAL_CALL release() throw() { VCLXWindow::release(); } // ::com::sun::star::lang::XTypeProvider ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes() throw(::com::sun::star::uno::RuntimeException); ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() throw(::com::sun::star::uno::RuntimeException); //::com::sun::star::awt::grid::XGridControl - ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumnModel > SAL_CALL getColumnModel( ) throw (::com::sun::star::uno::RuntimeException); - void SAL_CALL setColumnModel( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumnModel >& model ) throw (::com::sun::star::uno::RuntimeException); - ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridDataModel > SAL_CALL getDataModel( ) throw (::com::sun::star::uno::RuntimeException); - void SAL_CALL setDataModel( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridDataModel >& model ) throw (::com::sun::star::uno::RuntimeException); - virtual ::sal_Int32 SAL_CALL getMinSelectionIndex() throw (::com::sun::star::uno::RuntimeException); virtual ::sal_Int32 SAL_CALL getMaxSelectionIndex() throw (::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL insertIndexIntervall(::sal_Int32 start, ::sal_Int32 length) throw (::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL removeIndexIntervall(::sal_Int32 start, ::sal_Int32 end) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL selectRows(const ::com::sun::star::uno::Sequence< ::sal_Int32 >& rangeOfRows) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL selectAllRows() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL deselectRows(const ::com::sun::star::uno::Sequence< ::sal_Int32 >& rangeOfRows) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL deselectAllRows() throw (::com::sun::star::uno::RuntimeException); virtual ::com::sun::star::uno::Sequence< ::sal_Int32 > SAL_CALL getSelection() throw (::com::sun::star::uno::RuntimeException); virtual ::sal_Bool SAL_CALL isCellEditable() throw (::com::sun::star::uno::RuntimeException); virtual ::sal_Bool SAL_CALL isSelectionEmpty() throw (::com::sun::star::uno::RuntimeException); @@ -93,11 +103,15 @@ public: virtual void SAL_CALL addSelectionListener(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridSelectionListener > & listener) throw (::com::sun::star::uno::RuntimeException); virtual void SAL_CALL removeSelectionListener(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridSelectionListener > & listener) throw (::com::sun::star::uno::RuntimeException); virtual ::sal_Int32 SAL_CALL getItemIndexAtPoint(::sal_Int32 x, ::sal_Int32 y) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setToolTip(const ::com::sun::star::uno::Sequence< ::rtl::OUString >& text, const ::com::sun::star::uno::Sequence< sal_Int32 >& columns) throw (::com::sun::star::uno::RuntimeException); void SAL_CALL setProperty( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Any& Value ) throw(::com::sun::star::uno::RuntimeException); ::com::sun::star::uno::Any SAL_CALL getProperty( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::uno::RuntimeException); static void ImplGetPropertyIds( std::list< sal_uInt16 > &aIds ); void SAL_CALL setVisible(sal_Bool bVisible) throw(::com::sun::star::uno::RuntimeException); void SAL_CALL setFocus() throw(::com::sun::star::uno::RuntimeException); + + // ::com::sun::star::lang::XComponent + void SAL_CALL dispose( ) throw(::com::sun::star::uno::RuntimeException); }; #endif // _SVT_GRIDCONTROL_HXX_ diff --git a/svtools/source/uno/unocontroltablemodel.cxx b/svtools/source/uno/unocontroltablemodel.cxx index febb187fb289..d239ee3c740d 100644 --- a/svtools/source/uno/unocontroltablemodel.cxx +++ b/svtools/source/uno/unocontroltablemodel.cxx @@ -42,21 +42,32 @@ using ::rtl::OUString; using namespace ::svt::table; using namespace ::com::sun::star::uno; -using namespace ::com::sun::star::awt::grid; //-------------------------------------------------------------------- UnoControlTableColumn::UnoControlTableColumn(Reference<XGridColumn> m_xGridColumn) :m_nID( 0 ) ,m_sName() - ,m_bIsResizable( false ) - ,m_nWidth( 10 * 100 ) // 1 cm - ,m_nMinWidth( 0 ) // no min width - ,m_nMaxWidth( 0 ) // no max width + ,m_bIsResizable( true ) + ,m_nWidth( 4 ) + ,m_nMinWidth( 0 ) + ,m_nMaxWidth( 0 ) + ,m_nPrefWidth ( 0 ) + ,m_xHorizontalAlign(com::sun::star::style::HorizontalAlignment(0)) + { + m_sName = m_xGridColumn->getTitle(); + } + //-------------------------------------------------------------------- + UnoControlTableColumn::UnoControlTableColumn() + :m_nID( 0 ) + ,m_sName() + ,m_bIsResizable( true ) + ,m_nWidth( 4 ) + ,m_nMinWidth( 0 ) + ,m_nMaxWidth( 0 ) + ,m_nPrefWidth ( 0 ) + ,m_xHorizontalAlign(com::sun::star::style::HorizontalAlignment(0)) { - //m_nID = m_xGridColumn->getIdentifier(); - //m_nWidth = m_xGridColumn->getColumnWidth(); - m_sName = m_xGridColumn->getTitle(); } //-------------------------------------------------------------------- @@ -68,11 +79,7 @@ using namespace ::com::sun::star::awt::grid; //-------------------------------------------------------------------- bool UnoControlTableColumn::setID( const ColumnID _nID ) { - // TODO: conflict check - m_nID = _nID; - // TODO: notifications? - return true; } @@ -86,9 +93,7 @@ using namespace ::com::sun::star::awt::grid; void UnoControlTableColumn::setName( const String& _rName ) { m_sName = _rName; - // TODO: notifications? } - //-------------------------------------------------------------------- bool UnoControlTableColumn::isResizable() const { @@ -99,7 +104,6 @@ using namespace ::com::sun::star::awt::grid; void UnoControlTableColumn::setResizable( bool _bResizable ) { m_bIsResizable = _bResizable; - // TODO: notifications? } //-------------------------------------------------------------------- @@ -112,7 +116,6 @@ using namespace ::com::sun::star::awt::grid; void UnoControlTableColumn::setWidth( TableMetrics _nWidth ) { m_nWidth = _nWidth; - // TODO: notifications? } //-------------------------------------------------------------------- @@ -125,7 +128,6 @@ using namespace ::com::sun::star::awt::grid; void UnoControlTableColumn::setMinWidth( TableMetrics _nMinWidth ) { m_nMinWidth = _nMinWidth; - // TODO: notifications? } //-------------------------------------------------------------------- @@ -138,7 +140,28 @@ using namespace ::com::sun::star::awt::grid; void UnoControlTableColumn::setMaxWidth( TableMetrics _nMaxWidth ) { m_nMaxWidth = _nMaxWidth; - // TODO: notifications? + } + //-------------------------------------------------------------------- + TableMetrics UnoControlTableColumn::getPreferredWidth() const + { + return m_nPrefWidth; + } + + //-------------------------------------------------------------------- + void UnoControlTableColumn::setPreferredWidth( TableMetrics _nPrefWidth ) + { + m_nPrefWidth = _nPrefWidth; + } + //-------------------------------------------------------------------- + ::com::sun::star::style::HorizontalAlignment UnoControlTableColumn::getHorizontalAlign() + { + return m_xHorizontalAlign; + } + + //-------------------------------------------------------------------- + void UnoControlTableColumn::setHorizontalAlign( com::sun::star::style::HorizontalAlignment _align ) + { + m_xHorizontalAlign = _align; } //==================================================================== @@ -146,30 +169,46 @@ using namespace ::com::sun::star::awt::grid; //==================================================================== struct UnoControlTableModel_Impl { - ::std::vector< PColumnModel >& aColumns; + ::std::vector< PColumnModel > aColumns; TableSize nRowCount; bool bHasColumnHeaders; bool bHasRowHeaders; + bool bVScroll; + bool bHScroll; PTableRenderer pRenderer; PTableInputHandler pInputHandler; TableMetrics nRowHeight; TableMetrics nColumnHeaderHeight; TableMetrics nRowHeaderWidth; - std::vector<rtl::OUString>& aRowHeadersTitle; - std::vector<std::vector<rtl::OUString> >& aCellContent; + std::vector<rtl::OUString> aRowHeadersTitle; + std::vector<std::vector< Any > > aCellContent; + ::com::sun::star::util::Color m_xLineColor; + ::com::sun::star::util::Color m_xHeaderColor; + ::com::sun::star::util::Color m_xTextColor; + ::com::sun::star::util::Color m_xRowColor1; + ::com::sun::star::util::Color m_xRowColor2; + ::com::sun::star::style::VerticalAlignment m_xVerticalAlign; UnoControlTableModel_Impl() - :aColumns ( *(new std::vector< PColumnModel> (0))) - ,nRowCount ( 0 ) + :aColumns ( ) + ,nRowCount ( 0 ) ,bHasColumnHeaders ( false ) ,bHasRowHeaders ( false ) + ,bVScroll ( false ) + ,bHScroll ( false ) ,pRenderer ( ) ,pInputHandler ( ) - ,nRowHeight ( 4 * 100 ) // 40 mm - ,nColumnHeaderHeight( 5 * 100 ) // 50 mm - ,nRowHeaderWidth ( 10 * 100 ) // 50 mm - ,aRowHeadersTitle ( *(new std::vector<rtl::OUString>(0))) - ,aCellContent ( *(new std::vector<std::vector<OUString> >(0))) + ,nRowHeight ( 0 ) + ,nColumnHeaderHeight( 0 ) + ,nRowHeaderWidth ( 10 ) + ,aRowHeadersTitle ( ) + ,aCellContent ( ) + ,m_xLineColor ( 0xFFFFFF ) + ,m_xHeaderColor ( 0xFFFFFF ) + ,m_xTextColor ( 0 )//black as default + ,m_xRowColor1 ( 0xFFFFFF ) + ,m_xRowColor2 ( 0xFFFFFF ) + ,m_xVerticalAlign (com::sun::star::style::VerticalAlignment(0)) { } }; @@ -196,7 +235,6 @@ using namespace ::com::sun::star::awt::grid; //-------------------------------------------------------------------- TableSize UnoControlTableModel::getColumnCount() const { - //m_pImpl->aColumns.resize( m_xColumnModel->getColumnCount()); return (TableSize)m_pImpl->aColumns.size(); } @@ -250,7 +288,6 @@ using namespace ::com::sun::star::awt::grid; void UnoControlTableModel::addTableModelListener( const PTableModelListener& listener ) { (void) listener; - //listener->onTableModelChanged(PTableModel(this)); // TODO DBG_ERROR( "DefaultTableModel::addTableModelListener: not yet implemented!" ); } @@ -321,6 +358,17 @@ using namespace ::com::sun::star::awt::grid; DBG_ASSERT( hasRowHeaders(), "DefaultTableModel::getRowHeaderWidth: invalid call!" ); return m_pImpl->nRowHeaderWidth; } + //-------------------------------------------------------------------- + void UnoControlTableModel::setColumnHeaderHeight(TableMetrics _nHeight) + { + m_pImpl->nColumnHeaderHeight = _nHeight; + } + + //-------------------------------------------------------------------- + void UnoControlTableModel::setRowHeaderWidth(TableMetrics _nWidth) + { + m_pImpl->nRowHeaderWidth = _nWidth; + } //-------------------------------------------------------------------- void UnoControlTableModel::SetTitleHeight( TableMetrics _nHeight ) @@ -341,7 +389,7 @@ using namespace ::com::sun::star::awt::grid; //-------------------------------------------------------------------- ScrollbarVisibility UnoControlTableModel::getVerticalScrollbarVisibility(int overAllHeight, int actHeight) const { - if(overAllHeight>=actHeight)// && !m_bVScroll) + if(overAllHeight>=actHeight && !m_pImpl->bVScroll) return ScrollbarShowNever; else return ScrollbarShowAlways; @@ -350,59 +398,116 @@ using namespace ::com::sun::star::awt::grid; //-------------------------------------------------------------------- ScrollbarVisibility UnoControlTableModel::getHorizontalScrollbarVisibility(int overAllWidth, int actWidth) const { - if(overAllWidth>=actWidth)// && !m_bHScroll) + if(overAllWidth>=actWidth && !m_pImpl->bHScroll) return ScrollbarShowNever; else return ScrollbarShowAlways; } //-------------------------------------------------------------------- - void UnoControlTableModel::setCellContent(std::vector<std::vector<rtl::OUString> > cellContent) + void UnoControlTableModel::setVerticalScrollbarVisibility(bool _bVScroll) const { - //if(cellContent.empty()) - //{ - // unsigned int i = m_pImpl->aColumns.size(); - // std::vector<rtl::OUString>& emptyCells; - // while(i!=0) - // { - // cellContent.push_back(emptyCells); - // --i; - // } - //} - //std::vector<rtl::OUString> cCC; - //for(::std::vector<std::vector<rtl::OUString> >::iterator iter = cellContent.begin(); iter!= cellContent.end();++iter) - //{ - // cCC = *iter; - // m_pImpl->aCellContent.push_back(cCC); - //} - m_pImpl->aCellContent.swap( cellContent ); + m_pImpl->bVScroll = _bVScroll; } - std::vector<std::vector<rtl::OUString> >& UnoControlTableModel::getCellContent() + //-------------------------------------------------------------------- + void UnoControlTableModel::setHorizontalScrollbarVisibility(bool _bHScroll) const { - return m_pImpl->aCellContent; + m_pImpl->bHScroll = _bHScroll; + } + //-------------------------------------------------------------------- + bool UnoControlTableModel::hasVerticalScrollbar() + { + return m_pImpl->bVScroll; + } + //-------------------------------------------------------------------- + bool UnoControlTableModel::hasHorizontalScrollbar() + { + return m_pImpl->bHScroll; + } + //-------------------------------------------------------------------- + void UnoControlTableModel::setCellContent(const std::vector<std::vector< Any > >& cellContent) + { + m_pImpl->aCellContent = cellContent; } + std::vector<std::vector< Any > >& UnoControlTableModel::getCellContent() + { + return m_pImpl->aCellContent; + } //-------------------------------------------------------------------- - void UnoControlTableModel::setRowHeaderName(std::vector<rtl::OUString> cellColumnContent) + void UnoControlTableModel::setRowHeaderName(const std::vector<rtl::OUString>& cellColumnContent) { - if(cellColumnContent.empty()) - { - unsigned int i = m_pImpl->aColumns.size(); - while(i!=0) - { - cellColumnContent.push_back(rtl::OUString::createFromAscii("")); - --i; - } - } - for(::std::vector<rtl::OUString>::iterator iter = cellColumnContent.begin(); iter!= cellColumnContent.end();++iter) - { - rtl::OUString s = *iter; - m_pImpl->aRowHeadersTitle.push_back(*iter); - } + m_pImpl->aRowHeadersTitle = cellColumnContent; } std::vector<rtl::OUString>& UnoControlTableModel::getRowHeaderName() { return m_pImpl->aRowHeadersTitle; } + //-------------------------------------------------------------------- + ::com::sun::star::util::Color UnoControlTableModel::getLineColor() + { + return m_pImpl->m_xLineColor; + } + + //-------------------------------------------------------------------- + void UnoControlTableModel::setLineColor( ::com::sun::star::util::Color _rColor ) + { + m_pImpl->m_xLineColor = _rColor; + } + //-------------------------------------------------------------------- + ::com::sun::star::util::Color UnoControlTableModel::getHeaderBackgroundColor() + { + return m_pImpl->m_xHeaderColor; + } + + //-------------------------------------------------------------------- + void UnoControlTableModel::setHeaderBackgroundColor( ::com::sun::star::util::Color _rColor ) + { + m_pImpl->m_xHeaderColor = _rColor; + } + //-------------------------------------------------------------------- + ::com::sun::star::util::Color UnoControlTableModel::getTextColor() + { + return m_pImpl->m_xTextColor; + } + + //-------------------------------------------------------------------- + void UnoControlTableModel::setTextColor( ::com::sun::star::util::Color _rColor ) + { + m_pImpl->m_xTextColor = _rColor; + } + //-------------------------------------------------------------------- + ::com::sun::star::util::Color UnoControlTableModel::getOddRowBackgroundColor() + { + return m_pImpl->m_xRowColor1; + } + + //-------------------------------------------------------------------- + void UnoControlTableModel::setOddRowBackgroundColor( ::com::sun::star::util::Color _rColor ) + { + m_pImpl->m_xRowColor1 = _rColor; + } + //-------------------------------------------------------------------- + ::com::sun::star::util::Color UnoControlTableModel::getEvenRowBackgroundColor() + { + return m_pImpl->m_xRowColor2; + } + + //-------------------------------------------------------------------- + void UnoControlTableModel::setEvenRowBackgroundColor( ::com::sun::star::util::Color _rColor ) + { + m_pImpl->m_xRowColor2 = _rColor; + } + //-------------------------------------------------------------------- + ::com::sun::star::style::VerticalAlignment UnoControlTableModel::getVerticalAlign() + { + return m_pImpl->m_xVerticalAlign; + } + + //-------------------------------------------------------------------- + void UnoControlTableModel::setVerticalAlign( com::sun::star::style::VerticalAlignment _xAlign ) + { + m_pImpl->m_xVerticalAlign = _xAlign; + } diff --git a/svtools/source/uno/unocontroltablemodel.hxx b/svtools/source/uno/unocontroltablemodel.hxx index 5be4ff2a16f7..c00642448f79 100644 --- a/svtools/source/uno/unocontroltablemodel.hxx +++ b/svtools/source/uno/unocontroltablemodel.hxx @@ -41,7 +41,9 @@ #include <cppuhelper/typeprovider.hxx> #include <cppuhelper/implbase2.hxx> #include <com/sun/star/awt/grid/XGridColumn.hpp> -//#include <toolkit/helper/listenermultiplexer.hxx> +#include <com/sun/star/util/Color.hpp> +#include <com/sun/star/style/VerticalAlignment.hpp> +#include <com/sun/star/style/HorizontalAlignment.hpp> using namespace ::svt::table; @@ -49,7 +51,7 @@ using namespace ::com::sun::star::uno; using namespace ::com::sun::star::awt::grid; class UnoControlTableColumn : public IColumnModel - { +{ private: ColumnID m_nID; String m_sName; @@ -57,9 +59,12 @@ class UnoControlTableColumn : public IColumnModel TableMetrics m_nWidth; TableMetrics m_nMinWidth; TableMetrics m_nMaxWidth; + TableMetrics m_nPrefWidth; + ::com::sun::star::style::HorizontalAlignment m_xHorizontalAlign; public: UnoControlTableColumn(Reference<XGridColumn>); + UnoControlTableColumn(); // IColumnModel overridables virtual ColumnID getID() const; @@ -74,12 +79,16 @@ class UnoControlTableColumn : public IColumnModel virtual void setMinWidth( TableMetrics _nMinWidth ); virtual TableMetrics getMaxWidth() const; virtual void setMaxWidth( TableMetrics _nMaxWidth ); - }; + virtual TableMetrics getPreferredWidth() const; + virtual void setPreferredWidth( TableMetrics _nPrefWidth ); + virtual ::com::sun::star::style::HorizontalAlignment getHorizontalAlign(); + virtual void setHorizontalAlign(::com::sun::star::style::HorizontalAlignment _xAlign); +}; - struct UnoControlTableModel_Impl; +struct UnoControlTableModel_Impl; - class UnoControlTableModel : public ITableModel - { +class UnoControlTableModel : public ITableModel +{ private: UnoControlTableModel_Impl* m_pImpl; @@ -91,6 +100,10 @@ class UnoControlTableColumn : public IColumnModel inline TableMetrics GetRowHeight() const { return getRowHeight(); } /// sets a new row height. void setRowHeight( TableMetrics _nHeight ); + /// sets a new row header width. + void setRowHeaderWidth( TableMetrics _nWidth ); + /// sets a new column header height. + void setColumnHeaderHeight( TableMetrics _nHeight ); /// returns the height of the title row (containing the column headers) inline TableMetrics GetTitleHeight() const { return getColumnHeaderHeight(); } @@ -107,23 +120,21 @@ class UnoControlTableColumn : public IColumnModel /// retrieves the width of a column, in 1/100th millimeters inline TableMetrics GetColumnWidth( ColPos _nColumn ); - // TODO: setters and getters for ID, Name, Resizable, MinWidth, MaxWidth - public: // ITableModel overridables virtual TableSize getColumnCount() const; virtual TableSize getRowCount() const; - virtual void setColumnCount(TableSize _nColCount); + virtual void setColumnCount(TableSize _nColCount); virtual void setRowCount(TableSize _nRowCount); virtual bool hasColumnHeaders() const; virtual bool hasRowHeaders() const; - virtual void setRowHeaders(bool _bRowHeaders); - virtual void setColumnHeaders(bool _bColumnHeaders); + virtual void setRowHeaders(bool _bRowHeaders); + virtual void setColumnHeaders(bool _bColumnHeaders); virtual bool isCellEditable( ColPos col, RowPos row ) const; virtual void addTableModelListener( const PTableModelListener& listener ); virtual void removeTableModelListener( const PTableModelListener& listener ); virtual PColumnModel getColumnModel( ColPos column ); - virtual std::vector<PColumnModel>& getColumnModel(); + virtual std::vector<PColumnModel>& getColumnModel(); virtual PColumnModel getColumnModelByID( ColumnID id ); virtual PTableRenderer getRenderer() const; virtual PTableInputHandler getInputHandler() const; @@ -132,19 +143,35 @@ class UnoControlTableColumn : public IColumnModel virtual TableMetrics getRowHeaderWidth() const; virtual ScrollbarVisibility getVerticalScrollbarVisibility(int overAllHeight, int actHeight) const; virtual ScrollbarVisibility getHorizontalScrollbarVisibility(int overAllWidth, int actWidth) const; - virtual void setCellContent(std::vector<std::vector<rtl::OUString> > cellContent); - virtual std::vector<std::vector<rtl::OUString> >& getCellContent(); - virtual void setRowHeaderName(std::vector<rtl::OUString> cellColumnContent); - virtual std::vector<rtl::OUString>& getRowHeaderName(); - }; - - inline void UnoControlTableModel::SetColumnWidth( ColPos _nColumn, TableMetrics _nWidth100thMM ) - { + virtual void setVerticalScrollbarVisibility(bool _bVScroll) const; + virtual void setHorizontalScrollbarVisibility(bool _bHScroll) const; + virtual void setCellContent(const std::vector<std::vector< Any > >& cellContent); + virtual std::vector<std::vector< Any > >& getCellContent(); + virtual void setRowHeaderName(const std::vector<rtl::OUString>& cellColumnContent); + virtual std::vector<rtl::OUString>& getRowHeaderName(); + virtual ::com::sun::star::util::Color getLineColor(); + virtual void setLineColor(::com::sun::star::util::Color _rColor); + virtual ::com::sun::star::util::Color getHeaderBackgroundColor(); + virtual void setHeaderBackgroundColor(::com::sun::star::util::Color _rColor); + virtual ::com::sun::star::util::Color getTextColor(); + virtual void setTextColor(::com::sun::star::util::Color _rColor); + virtual ::com::sun::star::util::Color getOddRowBackgroundColor(); + virtual void setOddRowBackgroundColor(::com::sun::star::util::Color _rColor); + virtual ::com::sun::star::util::Color getEvenRowBackgroundColor(); + virtual void setEvenRowBackgroundColor(::com::sun::star::util::Color _rColor); + virtual ::com::sun::star::style::VerticalAlignment getVerticalAlign(); + virtual void setVerticalAlign(::com::sun::star::style::VerticalAlignment _rAlign); + virtual bool hasVerticalScrollbar(); + virtual bool hasHorizontalScrollbar(); +}; + +inline void UnoControlTableModel::SetColumnWidth( ColPos _nColumn, TableMetrics _nWidth100thMM ) +{ getColumnModel( _nColumn )->setWidth( _nWidth100thMM ); - } +} - inline TableMetrics UnoControlTableModel::GetColumnWidth( ColPos _nColumn ) - { - return getColumnModel( _nColumn )->getWidth(); - } +inline TableMetrics UnoControlTableModel::GetColumnWidth( ColPos _nColumn ) +{ + return getColumnModel( _nColumn )->getWidth(); +} #endif // _UNOCONTROL_TABLEMODEL_HXX_ diff --git a/svtools/workben/unodialog/makefile.mk b/svtools/workben/unodialog/makefile.mk index e9adb63d9b09..f18feffce5c3 100644 --- a/svtools/workben/unodialog/makefile.mk +++ b/svtools/workben/unodialog/makefile.mk @@ -56,7 +56,7 @@ SLOFILES= $(SLO)$/unodialogsample.obj \ # --- library ----------------------------------- SHL1TARGET=$(TARGET)$(DLLPOSTFIX) -SHL1VERSIONMAP=$(TARGET).map +SHL1VERSIONMAP=$(SOLARENV)/src/component.map SHL1STDLIBS= \ $(CPPULIB) \ diff --git a/svtools/workben/unodialog/udlg.map b/svtools/workben/unodialog/udlg.map deleted file mode 100644 index 276f9673d067..000000000000 --- a/svtools/workben/unodialog/udlg.map +++ /dev/null @@ -1,8 +0,0 @@ -UDLG_1_0 { - global: - component_getImplementationEnvironment; - component_writeInfo; - component_getFactory; - local: - *; -}; diff --git a/toolkit/inc/toolkit/helper/listenermultiplexer.hxx b/toolkit/inc/toolkit/helper/listenermultiplexer.hxx index 65e555f9d799..b9fb82c3d4bb 100644 --- a/toolkit/inc/toolkit/helper/listenermultiplexer.hxx +++ b/toolkit/inc/toolkit/helper/listenermultiplexer.hxx @@ -54,7 +54,7 @@ #include <osl/mutex.hxx> #include <toolkit/helper/mutexhelper.hxx> #include <toolkit/helper/macros.hxx> - +#include <com/sun/star/awt/grid/XGridSelectionListener.hpp> // ---------------------------------------------------- // class ListenerMultiplexerBase // ---------------------------------------------------- @@ -244,8 +244,12 @@ DECL_LISTENERMULTIPLEXER_START_DLLPUB( TreeEditListenerMultiplexer, ::com::sun:: virtual void SAL_CALL nodeEdited( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode >& Node, const ::rtl::OUString& NewText ) throw (::com::sun::star::uno::RuntimeException); DECL_LISTENERMULTIPLEXER_END - - +// ---------------------------------------------------- +// class SelectionListenerMultiplexer +// ---------------------------------------------------- +DECL_LISTENERMULTIPLEXER_START_DLLPUB( SelectionListenerMultiplexer, ::com::sun::star::awt::grid::XGridSelectionListener ) + void SAL_CALL selectionChanged( const ::com::sun::star::awt::grid::GridSelectionEvent& aEvent ) throw (::com::sun::star::uno::RuntimeException); +DECL_LISTENERMULTIPLEXER_END #endif // _TOOLKIT_HELPER_LISTENERMULTIPLEXER_HXX_ diff --git a/toolkit/inc/toolkit/helper/property.hxx b/toolkit/inc/toolkit/helper/property.hxx index d9adc182f4d7..d5f484145316 100644 --- a/toolkit/inc/toolkit/helper/property.hxx +++ b/toolkit/inc/toolkit/helper/property.hxx @@ -196,6 +196,10 @@ namespace rtl { #define BASEPROPERTY_ENABLEVISIBLE 145 // sal_Bool #define BASEPROPERTY_REFERENCE_DEVICE 146 #define BASEPROPERTY_HIGHCONTRASTMODE 147 +#define BASEPROPERTY_GRID_EVEN_ROW_BACKGROUND 148 +#define BASEPROPERTY_GRID_HEADER_BACKGROUND 149 +#define BASEPROPERTY_GRID_LINE_COLOR 150 +#define BASEPROPERTY_GRID_ROW_BACKGROUND 151 // Keine gebundenen Properties, werden immer aus der Property BASEPROPERTY_FONTDESCRIPTOR entnommen. diff --git a/toolkit/prj/build.lst b/toolkit/prj/build.lst index 304d0e7c978f..126eea24c66c 100644 --- a/toolkit/prj/build.lst +++ b/toolkit/prj/build.lst @@ -11,3 +11,4 @@ ti toolkit\source\controls\grid nmake - all ti_grid NULL ti toolkit\source\layout\core nmake - all ti_layout_core NULL ti toolkit\source\layout\vcl nmake - all ti_layout_vcl NULL ti toolkit\util nmake - all ti_util ti_awt ti_controls ti_layout_core ti_helper ti_tree ti_grid ti_layout_vcl NULL +ti toolkit\qa\unoapi nmake - all ti_qa_unoapi NULL diff --git a/toolkit/qa/unoapi/Test.java b/toolkit/qa/unoapi/Test.java new file mode 100644 index 000000000000..f27d882314d2 --- /dev/null +++ b/toolkit/qa/unoapi/Test.java @@ -0,0 +1,51 @@ +/************************************************************************* +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* Copyright 2000, 2010 Oracle and/or its affiliates. +* +* OpenOffice.org - a multi-platform office productivity suite +* +* This file is part of OpenOffice.org. +* +* OpenOffice.org is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License version 3 +* only, as published by the Free Software Foundation. +* +* OpenOffice.org is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License version 3 for more details +* (a copy is included in the LICENSE file that accompanied this code). +* +* You should have received a copy of the GNU Lesser General Public License +* version 3 along with OpenOffice.org. If not, see +* <http://www.openoffice.org/license.html> +* for a copy of the LGPLv3 License. +************************************************************************/ + +package org.openoffice.toolkit.qa.unoapi; + +import org.openoffice.Runner; +import org.openoffice.test.OfficeConnection; +import static org.junit.Assert.*; + +public final class Test { + @org.junit.Before public void setUp() throws Exception { + connection.setUp(); + } + + @org.junit.After public void tearDown() + throws InterruptedException, com.sun.star.uno.Exception + { + connection.tearDown(); + } + + @org.junit.Test public void test() { + assertTrue( + Runner.run( + "-sce", "toolkit.sce", "-xcl", "knownissues.xcl", "-tdoc", + "testdocuments", "-cs", connection.getDescription())); + } + + private final OfficeConnection connection = new OfficeConnection(); +} diff --git a/toolkit/qa/unoapi/knownissues.xcl b/toolkit/qa/unoapi/knownissues.xcl index ef954f00eeeb..6f57f37536a2 100644 --- a/toolkit/qa/unoapi/knownissues.xcl +++ b/toolkit/qa/unoapi/knownissues.xcl @@ -90,11 +90,6 @@ toolkit.AccessibleRadioButton toolkit.AccessibleToolBox # -> disabled in toolkit.sce -### i80788 ### -toolkit.Toolkit -toolkit.UnoControlDialog -# -> disabled in toolkit.sce - ### i86011 ### toolkit.UnoControlFileControl # -> disabled in toolkit.sce @@ -239,4 +234,9 @@ toolkit.AccessibleScrollBar::com::sun::star::accessibility::XAccessibleComponent toolkit.UnoScrollBarControl::com::sun::star::awt::XScrollBar ### i94344 ### -toolkit.AccessibleTabPage::com::sun::star::accessibility::XAccessibleText
\ No newline at end of file +toolkit.AccessibleTabPage::com::sun::star::accessibility::XAccessibleText + +### i109643 ### +toolkit.AccessibleMenu::com::sun::star::accessibility::XAccessibleValue +toolkit.AccessibleMenuBar::com::sun::star::accessibility::XAccessibleEventBroadcaster +toolkit.AccessibleMenuBar::com::sun::star::accessibility::XAccessibleSelection diff --git a/toolkit/qa/unoapi/makefile.mk b/toolkit/qa/unoapi/makefile.mk index a24f81d7c6ef..9517601c3917 100644 --- a/toolkit/qa/unoapi/makefile.mk +++ b/toolkit/qa/unoapi/makefile.mk @@ -1,7 +1,6 @@ #************************************************************************* -# # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# +# # Copyright 2000, 2010 Oracle and/or its affiliates. # # OpenOffice.org - a multi-platform office productivity suite @@ -22,22 +21,28 @@ # version 3 along with OpenOffice.org. If not, see # <http://www.openoffice.org/license.html> # for a copy of the LGPLv3 License. -# -#************************************************************************* +#***********************************************************************/ -PRJ=..$/.. +.IF "$(OOO_SUBSEQUENT_TESTS)" == "" +nothing .PHONY: +.ELSE -PRJNAME=toolkit -TARGET=qa_unoapi +PRJ = ../.. +PRJNAME = toolkit +TARGET = qa_unoapi -.INCLUDE: settings.mk +.IF "$(OOO_JUNIT_JAR)" != "" +PACKAGE = org/openoffice/toolkit/qa/unoapi +JAVATESTFILES = Test.java +JAVAFILES = $(JAVATESTFILES) +JARFILES = OOoRunner.jar ridl.jar test.jar +EXTRAJARFILES = $(OOO_JUNIT_JAR) +.END +.INCLUDE: settings.mk .INCLUDE: target.mk +.INCLUDE: installationtest.mk -ALLTAR : UNOAPI_TEST +ALLTAR : javatest -UNOAPI_TEST: - +$(SOLARENV)$/bin$/checkapi -sce toolkit.sce -xcl knownissues.xcl -tdoc $(PWD)$/testdocuments - @echo ======================================================================= - @echo In case you noticed a failures of toolkit.AccessibleToolBoxItem make sure that the object bar is configured as text and not as icons - @echo ======================================================================= +.END diff --git a/toolkit/qa/unoapi/toolkit.sce b/toolkit/qa/unoapi/toolkit.sce index dad24165e2d2..1c8ad0c95181 100644 --- a/toolkit/qa/unoapi/toolkit.sce +++ b/toolkit/qa/unoapi/toolkit.sce @@ -17,8 +17,8 @@ -o toolkit.AccessibleScrollBar -o toolkit.AccessibleStatusBar -o toolkit.AccessibleStatusBarItem --o toolkit.AccessibleTabControl --o toolkit.AccessibleTabPage +#i109643 -o toolkit.AccessibleTabControl +#i109643 -o toolkit.AccessibleTabPage #i86287 -o toolkit.AccessibleToolBox #i88605 -o toolkit.AccessibleToolBoxItem -o toolkit.AccessibleWindow @@ -26,7 +26,7 @@ -o toolkit.MutableTreeNode -o toolkit.TabController -o toolkit.TabControllerModel -#i80788 -o toolkit.Toolkit +-o toolkit.Toolkit -o toolkit.UnoControlButton -o toolkit.UnoControlButtonModel -o toolkit.UnoControlCheckBox @@ -39,7 +39,7 @@ -o toolkit.UnoControlCurrencyFieldModel -o toolkit.UnoControlDateField -o toolkit.UnoControlDateFieldModel -#i80788 -o toolkit.UnoControlDialog +#allegedly was i80788, but still broken: -o toolkit.UnoControlDialog -o toolkit.UnoControlDialogModel -o toolkit.UnoControlEdit -o toolkit.UnoControlEditModel diff --git a/toolkit/source/controls/grid/defaultgridcolumnmodel.cxx b/toolkit/source/controls/grid/defaultgridcolumnmodel.cxx index fdf91d6a6593..011f3502cdd8 100644 --- a/toolkit/source/controls/grid/defaultgridcolumnmodel.cxx +++ b/toolkit/source/controls/grid/defaultgridcolumnmodel.cxx @@ -30,6 +30,7 @@ #include "defaultgridcolumnmodel.hxx" #include <comphelper/sequence.hxx> #include <toolkit/helper/servicenames.hxx> +#include <com/sun/star/awt/XVclWindowPeer.hpp> #include <rtl/ref.hxx> using ::rtl::OUString; @@ -38,8 +39,7 @@ using namespace ::com::sun::star::uno; using namespace ::com::sun::star::awt; using namespace ::com::sun::star::awt::grid; using namespace ::com::sun::star::lang; - -#define COLUMNSELECTIONALLOWED ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ColumnSelectionAllowed" )) +using namespace ::com::sun::star::style; namespace toolkit { @@ -48,8 +48,10 @@ namespace toolkit // class DefaultGridColumnModel /////////////////////////////////////////////////////////////////////// -DefaultGridColumnModel::DefaultGridColumnModel() +DefaultGridColumnModel::DefaultGridColumnModel(const Reference< XMultiServiceFactory >& xFactory) : columns(std::vector< Reference< XGridColumn > >()) + ,m_nColumnHeaderHeight(0) + ,m_xFactory(xFactory) { } @@ -61,71 +63,6 @@ DefaultGridColumnModel::~DefaultGridColumnModel() //--------------------------------------------------------------------- -void DefaultGridColumnModel::broadcast( broadcast_type eType, const GridColumnEvent& aEvent ) -{ - ::cppu::OInterfaceContainerHelper* pIter = BrdcstHelper.getContainer( XGridColumnListener::static_type() ); - if( pIter ) - { - ::cppu::OInterfaceIteratorHelper aListIter(*pIter); - while(aListIter.hasMoreElements()) - { - XGridColumnListener* pListener = static_cast<XGridColumnListener*>(aListIter.next()); - switch( eType ) - { - case column_added: pListener->columnAdded(aEvent); break; - case column_removed: pListener->columnRemoved(aEvent); break; - case column_changed: pListener->columnChanged(aEvent); break; - } - } - } -} - -//--------------------------------------------------------------------- - -void DefaultGridColumnModel::broadcast_changed( ::rtl::OUString name, Any oldValue, Any newValue ) -{ - Reference< XInterface > xSource( static_cast< ::cppu::OWeakObject* >( this ) ); - GridColumnEvent aEvent( xSource, name, oldValue, newValue, 0, NULL ); - broadcast( column_changed, aEvent); -} - -//--------------------------------------------------------------------- - -void DefaultGridColumnModel::broadcast_add( sal_Int32 index, const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumn > & rColumn ) -{ - Reference< XInterface > xSource( static_cast< ::cppu::OWeakObject* >( this ) ); - GridColumnEvent aEvent( xSource, ::rtl::OUString(), Any(), Any(), index, rColumn ); - broadcast( column_added, aEvent); -} - -//--------------------------------------------------------------------- - -void DefaultGridColumnModel::broadcast_remove( sal_Int32 index, const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumn > & rColumn ) -{ - Reference< XInterface > xSource( static_cast< ::cppu::OWeakObject* >( this ) ); - GridColumnEvent aEvent( xSource, ::rtl::OUString(), Any(), Any(), index, rColumn ); - broadcast( column_changed, aEvent); -} - -//--------------------------------------------------------------------- -// XDefaultGridColumnModel -//--------------------------------------------------------------------- -::sal_Bool SAL_CALL DefaultGridColumnModel::getColumnSelectionAllowed() throw (::com::sun::star::uno::RuntimeException) -{ - return selectionAllowed; -} - -//--------------------------------------------------------------------- - -void SAL_CALL DefaultGridColumnModel::setColumnSelectionAllowed(::sal_Bool value) throw (::com::sun::star::uno::RuntimeException) -{ - sal_Bool oldValue = selectionAllowed; - selectionAllowed = value; - broadcast_changed( COLUMNSELECTIONALLOWED, Any(oldValue) , Any(selectionAllowed)); -} - -//--------------------------------------------------------------------- - ::sal_Int32 SAL_CALL DefaultGridColumnModel::getColumnCount() throw (::com::sun::star::uno::RuntimeException) { return columns.size(); @@ -136,11 +73,10 @@ void SAL_CALL DefaultGridColumnModel::setColumnSelectionAllowed(::sal_Bool value ::sal_Int32 SAL_CALL DefaultGridColumnModel::addColumn(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumn > & column) throw (::com::sun::star::uno::RuntimeException) { ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); - - columns.push_back(column); - + Reference<XGridColumn> xColumn(column); + columns.push_back(xColumn); sal_Int32 index = columns.size() - 1; - broadcast_add(index, column ); + xColumn->setIndex(index); return index; } @@ -156,23 +92,48 @@ void SAL_CALL DefaultGridColumnModel::setColumnSelectionAllowed(::sal_Bool value ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumn > SAL_CALL DefaultGridColumnModel::getColumn(::sal_Int32 index) throw (::com::sun::star::uno::RuntimeException) { if ( index >=0 && index < ((sal_Int32)columns.size())) + { return columns[index]; + } else return Reference< XGridColumn >(); } - -void SAL_CALL DefaultGridColumnModel::addColumnListener( const Reference< XGridColumnListener >& xListener ) throw (RuntimeException) +//--------------------------------------------------------------------- +void SAL_CALL DefaultGridColumnModel::setColumnHeaderHeight(sal_Int32 _value) throw (::com::sun::star::uno::RuntimeException) +{ + m_nColumnHeaderHeight = _value; +} +//--------------------------------------------------------------------- +sal_Int32 SAL_CALL DefaultGridColumnModel::getColumnHeaderHeight() throw (::com::sun::star::uno::RuntimeException) { - BrdcstHelper.addListener( XGridColumnListener::static_type(), xListener ); + return m_nColumnHeaderHeight; } //--------------------------------------------------------------------- +void SAL_CALL DefaultGridColumnModel::setDefaultColumns(sal_Int32 rowElements) throw (::com::sun::star::uno::RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); -void SAL_CALL DefaultGridColumnModel::removeColumnListener( const Reference< XGridColumnListener >& xListener ) throw (RuntimeException) + for(sal_Int32 i=0;i<rowElements;i++) + { + Reference<XGridColumn> xColumn( m_xFactory->createInstance ( OUString::createFromAscii( "com.sun.star.awt.grid.GridColumn" ) ), UNO_QUERY ); + columns.push_back(xColumn); + xColumn->setIndex(i); + } +} +::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumn > SAL_CALL DefaultGridColumnModel::copyColumn(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumn > & column) throw (::com::sun::star::uno::RuntimeException) { - BrdcstHelper.removeListener( XGridColumnListener::static_type(), xListener ); + Reference<XGridColumn> xColumn( m_xFactory->createInstance ( OUString::createFromAscii( "com.sun.star.awt.grid.GridColumn" ) ), UNO_QUERY ); + xColumn->setColumnWidth(column->getColumnWidth()); + xColumn->setPreferredWidth(column->getPreferredWidth()); + xColumn->setMaxWidth(column->getMaxWidth()); + xColumn->setMinWidth(column->getMinWidth()); + xColumn->setPreferredWidth(column->getPreferredWidth()); + xColumn->setResizeable(column->getResizeable()); + xColumn->setTitle(column->getTitle()); + xColumn->setHorizontalAlign(column->getHorizontalAlign()); + return xColumn; } - //--------------------------------------------------------------------- // XComponent //--------------------------------------------------------------------- @@ -232,8 +193,8 @@ sal_Bool SAL_CALL DefaultGridColumnModel::supportsService( const ::rtl::OUString } -Reference< XInterface > SAL_CALL DefaultGridColumnModel_CreateInstance( const Reference< XMultiServiceFactory >& ) +Reference< XInterface > SAL_CALL DefaultGridColumnModel_CreateInstance( const Reference< XMultiServiceFactory >& _rFactory) { - return Reference < XInterface >( ( ::cppu::OWeakObject* ) new ::toolkit::DefaultGridColumnModel ); + return Reference < XInterface >( ( ::cppu::OWeakObject* ) new ::toolkit::DefaultGridColumnModel( _rFactory ) ); } diff --git a/toolkit/source/controls/grid/defaultgridcolumnmodel.hxx b/toolkit/source/controls/grid/defaultgridcolumnmodel.hxx index 896427ce3e2b..8b8c8bfc795c 100644 --- a/toolkit/source/controls/grid/defaultgridcolumnmodel.hxx +++ b/toolkit/source/controls/grid/defaultgridcolumnmodel.hxx @@ -29,7 +29,7 @@ #include "precompiled_toolkit.hxx" #include <com/sun/star/awt/grid/XGridColumnModel.hpp> #include <com/sun/star/awt/grid/XGridColumn.hpp> -#include <com/sun/star/awt/grid/GridColumnEvent.hpp> +//#include <com/sun/star/awt/grid/GridColumnEvent.hpp> #include <com/sun/star/lang/XEventListener.hpp> #include <com/sun/star/lang/XServiceInfo.hpp> #include <com/sun/star/lang/XUnoTunnel.hpp> @@ -38,6 +38,9 @@ #include <rtl/ref.hxx> #include <vector> #include <toolkit/helper/mutexandbroadcasthelper.hxx> +#include <com/sun/star/util/Color.hpp> +#include <com/sun/star/style/VerticalAlignment.hpp> +#include <com/sun/star/awt/grid/XGridColumnListener.hpp> using ::rtl::OUString; using namespace ::com::sun::star; @@ -49,45 +52,49 @@ using namespace ::com::sun::star::lang; namespace toolkit { -enum broadcast_type { column_added, column_removed, column_changed}; +//enum broadcast_type { column_added, column_removed, column_changed}; class DefaultGridColumnModel : public ::cppu::WeakImplHelper2< XGridColumnModel, XServiceInfo >, public MutexAndBroadcastHelper { public: - DefaultGridColumnModel(); + DefaultGridColumnModel(const Reference< XMultiServiceFactory >& xFactory); virtual ~DefaultGridColumnModel(); // XGridColumnModel - virtual ::sal_Bool SAL_CALL getColumnSelectionAllowed() throw (::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL setColumnSelectionAllowed(::sal_Bool the_value) throw (::com::sun::star::uno::RuntimeException); + //virtual ::sal_Bool SAL_CALL getColumnSelectionAllowed() throw (::com::sun::star::uno::RuntimeException); + //virtual void SAL_CALL setColumnSelectionAllowed(::sal_Bool the_value) throw (::com::sun::star::uno::RuntimeException); virtual ::sal_Int32 SAL_CALL getColumnCount() throw (::com::sun::star::uno::RuntimeException); virtual ::sal_Int32 SAL_CALL addColumn(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumn > & column) throw (::com::sun::star::uno::RuntimeException); virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumn > > SAL_CALL getColumns() throw (::com::sun::star::uno::RuntimeException); virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumn > SAL_CALL getColumn(::sal_Int32 index) throw (::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL addColumnListener( const Reference< XGridColumnListener >& xListener ) throw (RuntimeException); - virtual void SAL_CALL removeColumnListener( const Reference< XGridColumnListener >& xListener ) throw (RuntimeException); - + //virtual void SAL_CALL addColumnListener( const Reference< XGridColumnListener >& xListener ) throw (RuntimeException); + //virtual void SAL_CALL removeColumnListener( const Reference< XGridColumnListener >& xListener ) throw (RuntimeException); + virtual void SAL_CALL setColumnHeaderHeight( sal_Int32 _value) throw (com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getColumnHeaderHeight() throw (com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setDefaultColumns(sal_Int32 rowElements) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumn > SAL_CALL copyColumn(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumn > & column) throw (::com::sun::star::uno::RuntimeException); // XComponent virtual void SAL_CALL dispose( ) throw (RuntimeException); virtual void SAL_CALL addEventListener( const Reference< XEventListener >& xListener ) throw (RuntimeException); virtual void SAL_CALL removeEventListener( const Reference< XEventListener >& aListener ) throw (RuntimeException); // XServiceInfo - virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw (RuntimeException); - virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw (RuntimeException); - virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw (RuntimeException); - + virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw (::com::sun::star::uno::RuntimeException); private: - void broadcast( broadcast_type eType, const GridColumnEvent& aEvent ); - void broadcast_changed( ::rtl::OUString name, Any oldValue, Any newValue ); + /*void broadcast( broadcast_type eType, const GridColumnEvent& aEvent ); + void broadcast_changed( ::rtl::OUString name, Any oldValue, Any newValue, sal_Int32 index,const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumn > & rColumn ); void broadcast_add( sal_Int32 index,const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumn > & rColumn ); - void broadcast_remove( sal_Int32 index, const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumn > & rColumn ); + void broadcast_remove( sal_Int32 index, const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumn > & rColumn );*/ std::vector< ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumn > > columns; sal_Bool selectionAllowed; + sal_Int32 m_nColumnHeaderHeight; + Reference< XMultiServiceFactory > m_xFactory; }; } diff --git a/toolkit/source/controls/grid/defaultgriddatamodel.cxx b/toolkit/source/controls/grid/defaultgriddatamodel.cxx index 70c79e0bcbfa..7ffafdf0ddb6 100644 --- a/toolkit/source/controls/grid/defaultgriddatamodel.cxx +++ b/toolkit/source/controls/grid/defaultgriddatamodel.cxx @@ -41,6 +41,9 @@ using namespace ::com::sun::star::lang; #define ROWHEIGHT ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "RowHeight" )) #define ROWHEADERS ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "RowHeaders" )) +#define CELLUPDATED ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "CellUpdated" )) +#define ROWUPDATED ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "RowUpdated" )) +#define ROWHEADERWIDTH ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "RowHeaderWidth" )) namespace toolkit { @@ -51,7 +54,8 @@ namespace toolkit DefaultGridDataModel::DefaultGridDataModel() : rowHeight(0), - rowHeaders(std::vector< ::rtl::OUString >()) + rowHeaders(std::vector< ::rtl::OUString >()), + m_nRowHeaderWidth(10) { } @@ -61,7 +65,7 @@ DefaultGridDataModel::~DefaultGridDataModel() { } -void DefaultGridDataModel::broadcast( broadcast_type eType, const GridDataEvent& aEvent ) +void DefaultGridDataModel::broadcast( broadcast_type eType, const GridDataEvent& aEvent ) throw (::com::sun::star::uno::RuntimeException) { ::cppu::OInterfaceContainerHelper* pIter = BrdcstHelper.getContainer( XGridDataListener::static_type() ); if( pIter ) @@ -82,25 +86,27 @@ void DefaultGridDataModel::broadcast( broadcast_type eType, const GridDataEvent& //--------------------------------------------------------------------- -void DefaultGridDataModel::broadcast_changed( ::rtl::OUString name, Any oldValue, Any newValue ) +void DefaultGridDataModel::broadcast_changed( ::rtl::OUString name, sal_Int32 index, Any oldValue, Any newValue) throw (::com::sun::star::uno::RuntimeException) { Reference< XInterface > xSource( static_cast< ::cppu::OWeakObject* >( this ) ); - GridDataEvent aEvent( xSource, name, oldValue, newValue, 0, ::rtl::OUString(), Sequence< ::rtl::OUString>() ); + GridDataEvent aEvent( xSource, name, oldValue, newValue, index, ::rtl::OUString(), Sequence< Any >()); broadcast( data_changed, aEvent); } //--------------------------------------------------------------------- -void DefaultGridDataModel::broadcast_add( sal_Int32 index, const ::rtl::OUString & headerName, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rowData ) +void DefaultGridDataModel::broadcast_add( sal_Int32 index, const ::rtl::OUString & headerName, + ::com::sun::star::uno::Sequence< Any > rowData ) throw (::com::sun::star::uno::RuntimeException) { Reference< XInterface > xSource( static_cast< ::cppu::OWeakObject* >( this ) ); - GridDataEvent aEvent( xSource, ::rtl::OUString(), Any(), Any(), index, headerName, rowData ); + GridDataEvent aEvent( xSource, ::rtl::OUString(), Any(), Any(), index, headerName, (const ::com::sun::star::uno::Sequence< Any >&)rowData ); broadcast( row_added, aEvent); } //--------------------------------------------------------------------- -void DefaultGridDataModel::broadcast_remove( sal_Int32 index, const ::rtl::OUString & headerName, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rowData ) +void DefaultGridDataModel::broadcast_remove( sal_Int32 index, const ::rtl::OUString & headerName, + ::com::sun::star::uno::Sequence< Any > rowData ) throw (::com::sun::star::uno::RuntimeException) { Reference< XInterface > xSource( static_cast< ::cppu::OWeakObject* >( this ) ); GridDataEvent aEvent( xSource, ::rtl::OUString(), Any(), Any(), index, headerName, rowData ); @@ -124,7 +130,7 @@ void SAL_CALL DefaultGridDataModel::setRowHeight(::sal_Int32 value) throw (::com sal_Int32 oldValue = rowHeight; rowHeight = value; - broadcast_changed( ROWHEIGHT, Any(oldValue), Any(value) ); + broadcast_changed( ROWHEIGHT, 0, Any(oldValue), Any(value)); } //--------------------------------------------------------------------- @@ -160,24 +166,26 @@ void SAL_CALL DefaultGridDataModel::setRowHeaders(const ::com::sun::star::uno::S i++; } - broadcast_changed( ROWHEADERS, Any(oldValue), Any(comphelper::containerToSequence(rowHeaders)) ); + broadcast_changed( ROWHEADERS, 0, Any(oldValue), Any(comphelper::containerToSequence(rowHeaders)) ); } //--------------------------------------------------------------------- -void SAL_CALL DefaultGridDataModel::addRow(const ::rtl::OUString & headername, const ::com::sun::star::uno::Sequence< ::rtl::OUString > & rRowdata) throw (::com::sun::star::uno::RuntimeException) +void SAL_CALL DefaultGridDataModel::addRow(const ::rtl::OUString & headername, const ::com::sun::star::uno::Sequence< Any > & rRowdata) throw (::com::sun::star::uno::RuntimeException) { // store header name rowHeaders.push_back(headername); - // store row data - std::vector< rtl::OUString > newRow( - comphelper::sequenceToContainer< std::vector<rtl::OUString > >(rRowdata)); + std::vector< Any > newRow; + for ( int i = 0; i < rRowdata.getLength();i++) + { + newRow.push_back(rRowdata[i]); + } data.push_back( newRow ); - broadcast_add( data.size()-1, headername, rRowdata); + broadcast_add( data.size()-1, headername, comphelper::containerToSequence(newRow)); } @@ -187,16 +195,10 @@ void SAL_CALL DefaultGridDataModel::removeRow(::sal_Int32 index) throw (::com::s { if ( index >= 0 && index <= getRowCount()-1) { - /* if(Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->isSelectedIndex( index )) - { - ::com::sun::star::uno::Sequence<::sal_Int32> selectedRows = Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->getSelection(); - selectedRow.erase(selectedRows.begin()+index); - }*/ - ::rtl::OUString headerName( (::rtl::OUString) rowHeaders[index] ); rowHeaders.erase(rowHeaders.begin() + index); - Sequence< ::rtl::OUString >& rowData ( (Sequence< ::rtl::OUString >&)data[index] ); + Sequence< Any >& rowData ( (Sequence< Any >&)data[index] ); data.erase(data.begin() + index); broadcast_remove( index, headerName, rowData); } @@ -204,19 +206,19 @@ void SAL_CALL DefaultGridDataModel::removeRow(::sal_Int32 index) throw (::com::s return; } //--------------------------------------------------------------------- -::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::rtl::OUString > > SAL_CALL DefaultGridDataModel::getData() throw (::com::sun::star::uno::RuntimeException) +::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< Any > > SAL_CALL DefaultGridDataModel::getData() throw (::com::sun::star::uno::RuntimeException) { - std::vector< std::vector< ::rtl::OUString > >::iterator iterator; - std::vector< Sequence< ::rtl::OUString > > dummyContainer(0); + std::vector< std::vector< Any > >::iterator iterator; + std::vector< Sequence< Any > > dummyContainer(0); for(iterator = data.begin(); iterator != data.end(); iterator++) { - Sequence< ::rtl::OUString > cols(comphelper::containerToSequence(*iterator)); + Sequence< Any > cols(comphelper::containerToSequence(*iterator)); dummyContainer.push_back( cols ); } - Sequence< Sequence< ::rtl::OUString > > dataSequence(comphelper::containerToSequence(dummyContainer)); + Sequence< Sequence< Any > > dataSequence(comphelper::containerToSequence(dummyContainer)); return dataSequence; } @@ -234,14 +236,52 @@ void SAL_CALL DefaultGridDataModel::removeDataListener( const Reference< XGridDa { BrdcstHelper.removeListener( XGridDataListener::static_type(), xListener ); } - +//--------------------------------------------------------------------- void SAL_CALL DefaultGridDataModel::removeAll() throw (RuntimeException) { rowHeaders.clear(); data.clear(); broadcast_remove( -1, ::rtl::OUString(), 0); } - +//--------------------------------------------------------------------- +void SAL_CALL DefaultGridDataModel::setRowHeaderWidth(sal_Int32 _value) throw (::com::sun::star::uno::RuntimeException) +{ + sal_Int32 oldValue = m_nRowHeaderWidth; + m_nRowHeaderWidth = _value; + broadcast_changed( ROWHEADERWIDTH, 0, Any(oldValue), Any(_value) ); +} +//--------------------------------------------------------------------- +sal_Int32 SAL_CALL DefaultGridDataModel::getRowHeaderWidth() throw (::com::sun::star::uno::RuntimeException) +{ + return m_nRowHeaderWidth; +} +//--------------------------------------------------------------------- +void SAL_CALL DefaultGridDataModel::updateCell(::sal_Int32 row, ::sal_Int32 column, const Any& value) throw (::com::sun::star::uno::RuntimeException) +{ + if(row >= 0 && row < (signed)data.size()) + { + if(column >= 0 && column < (signed)data[0].size()) + { + data[row][column] = value; + Sequence< Any >dataSeq(comphelper::containerToSequence(data[row])); + broadcast_changed( CELLUPDATED, row, Any(column), value ); + } + } +} +//--------------------------------------------------------------------- +void SAL_CALL DefaultGridDataModel::updateRow(::sal_Int32 row, const ::com::sun::star::uno::Sequence< ::sal_Int32 > & columns, const ::com::sun::star::uno::Sequence< Any > & values) throw (::com::sun::star::uno::RuntimeException) +{ + if(row >= 0 && row < (signed)data.size()) + { + if(columns.getLength() == values.getLength()) + { + for(int i = 0; i < columns.getLength(); i++) + data[row][i] = values[i]; + Sequence< Any >dataSeq(comphelper::containerToSequence(data[row])); + broadcast_changed( ROWUPDATED, row, Any(columns), Any(values) ); + } + } +} //--------------------------------------------------------------------- // XComponent //--------------------------------------------------------------------- @@ -302,6 +342,5 @@ sal_Bool SAL_CALL DefaultGridDataModel::supportsService( const ::rtl::OUString& Reference< XInterface > SAL_CALL DefaultGridDataModel_CreateInstance( const Reference< XMultiServiceFactory >& ) { - return Reference < XInterface >( ( ::cppu::OWeakObject* ) new ::toolkit::DefaultGridDataModel ); + return Reference < XInterface >( ( ::cppu::OWeakObject* ) new ::toolkit::DefaultGridDataModel() ); } - diff --git a/toolkit/source/controls/grid/defaultgriddatamodel.hxx b/toolkit/source/controls/grid/defaultgriddatamodel.hxx index 1aebc07bc2a8..ea11a8a9a00a 100644 --- a/toolkit/source/controls/grid/defaultgriddatamodel.hxx +++ b/toolkit/source/controls/grid/defaultgriddatamodel.hxx @@ -30,6 +30,7 @@ #include <com/sun/star/awt/grid/XGridDataModel.hpp> #include <com/sun/star/awt/grid/GridDataEvent.hpp> #include <com/sun/star/awt/grid/XGridDataListener.hpp> +#include <com/sun/star/awt/XControl.hpp> #include <com/sun/star/lang/XEventListener.hpp> #include <com/sun/star/lang/XServiceInfo.hpp> #include <com/sun/star/lang/XUnoTunnel.hpp> @@ -64,13 +65,16 @@ public: virtual ::sal_Int32 SAL_CALL getRowCount() throw (::com::sun::star::uno::RuntimeException); virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getRowHeaders() throw (::com::sun::star::uno::RuntimeException); virtual void SAL_CALL setRowHeaders(const ::com::sun::star::uno::Sequence< ::rtl::OUString > & value) throw (::com::sun::star::uno::RuntimeException); - virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::rtl::OUString > > SAL_CALL getData() throw (::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL addRow(const ::rtl::OUString & headername, const ::com::sun::star::uno::Sequence< ::rtl::OUString > & data) throw (::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL removeRow(::sal_Int32 index) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< Any > > SAL_CALL getData() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addRow(const ::rtl::OUString & headername, const ::com::sun::star::uno::Sequence< Any > & data) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeRow(::sal_Int32 index) throw (::com::sun::star::uno::RuntimeException); virtual void SAL_CALL addDataListener( const Reference< XGridDataListener >& xListener ) throw (RuntimeException); virtual void SAL_CALL removeDataListener( const Reference< XGridDataListener >& xListener ) throw (RuntimeException); virtual void SAL_CALL removeAll() throw (RuntimeException); - + virtual void SAL_CALL setRowHeaderWidth(sal_Int32 _value) throw (::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getRowHeaderWidth() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL updateCell( ::sal_Int32 row, ::sal_Int32 column, const ::com::sun::star::uno::Any& value ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL updateRow( ::sal_Int32 row, const ::com::sun::star::uno::Sequence< ::sal_Int32 >& columns, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& values ) throw (::com::sun::star::uno::RuntimeException); // XComponent virtual void SAL_CALL dispose( ) throw (RuntimeException); virtual void SAL_CALL addEventListener( const Reference< XEventListener >& xListener ) throw (RuntimeException); @@ -83,14 +87,15 @@ public: private: - void broadcast( broadcast_type eType, const GridDataEvent& aEvent ); - void broadcast_changed( ::rtl::OUString name, Any oldValue, Any newValue ); - void broadcast_add( sal_Int32 index, const ::rtl::OUString & headerName, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rowData ); - void broadcast_remove( sal_Int32 index, const ::rtl::OUString & headerName, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rowData ); + void broadcast( broadcast_type eType, const GridDataEvent& aEvent ) throw (::com::sun::star::uno::RuntimeException); + void broadcast_changed( ::rtl::OUString name, sal_Int32 index, Any oldValue, Any newValue ) throw (::com::sun::star::uno::RuntimeException); + void broadcast_add( sal_Int32 index, const ::rtl::OUString & headerName, const ::com::sun::star::uno::Sequence< Any > rowData ) throw (::com::sun::star::uno::RuntimeException); + void broadcast_remove( sal_Int32 index, const ::rtl::OUString & headerName, const ::com::sun::star::uno::Sequence< Any > rowData ) throw (::com::sun::star::uno::RuntimeException); sal_Int32 rowHeight; - std::vector< std::vector < ::rtl::OUString > > data; + std::vector< std::vector < Any > > data; std::vector< ::rtl::OUString > rowHeaders; + sal_Int32 m_nRowHeaderWidth; }; } diff --git a/toolkit/source/controls/grid/gridcolumn.cxx b/toolkit/source/controls/grid/gridcolumn.cxx index 39c4960351d3..6720d639f5c1 100644 --- a/toolkit/source/controls/grid/gridcolumn.cxx +++ b/toolkit/source/controls/grid/gridcolumn.cxx @@ -38,6 +38,16 @@ using namespace ::com::sun::star::uno; using namespace ::com::sun::star::awt; using namespace ::com::sun::star::awt::grid; using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::style; + +#define COLWIDTH ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ColWidth" )) +#define MAXWIDTH ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "MaxWidth" )) +#define MINWIDTH ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "MinWidth" )) +#define PREFWIDTH ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "PrefWidth" )) +#define HALIGN ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "HAlign" )) +#define TITLE ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Title" )) +#define COLRESIZE ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ColumnResize" )) +#define UPDATE ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "UpdateWidth" )) namespace toolkit { @@ -48,6 +58,13 @@ namespace toolkit GridColumn::GridColumn() : identifier(Any()) +,index(0) +,columnWidth(4) +,preferredWidth(0) +,maxWidth(0) +,minWidth(0) +,bResizeable(true) +,horizontalAlign(HorizontalAlignment(0)) { } @@ -59,6 +76,39 @@ GridColumn::~GridColumn() //--------------------------------------------------------------------- +void GridColumn::broadcast( broadcast_column_type eType, const GridColumnEvent& aEvent ) +{ + ::cppu::OInterfaceContainerHelper* pIter = BrdcstHelper.getContainer( XGridColumnListener::static_type() ); + if( pIter ) + { + ::cppu::OInterfaceIteratorHelper aListIter(*pIter); + while(aListIter.hasMoreElements()) + { + XGridColumnListener* pListener = static_cast<XGridColumnListener*>(aListIter.next()); + switch( eType ) + { + case column_attribute_changed: pListener->columnChanged(aEvent); break; + } + } + } +} + +//--------------------------------------------------------------------- + +void GridColumn::broadcast_changed(::rtl::OUString name, Any oldValue, Any newValue) +{ + Reference< XInterface > xSource( static_cast< ::cppu::OWeakObject* >( this ) ); + GridColumnEvent aEvent( xSource, name, oldValue, newValue, index); + broadcast( column_attribute_changed, aEvent); +} + +void SAL_CALL GridColumn::updateColumn(const ::rtl::OUString& name, sal_Int32 width) throw (::com::sun::star::uno::RuntimeException) +{ + if(PREFWIDTH == name) + preferredWidth = width; + else if (COLWIDTH == name) + columnWidth = width; +} //--------------------------------------------------------------------- // XGridColumn //--------------------------------------------------------------------- @@ -79,6 +129,7 @@ void SAL_CALL GridColumn::setIdentifier(const ::com::sun::star::uno::Any & value ::sal_Int32 SAL_CALL GridColumn::getColumnWidth() throw (::com::sun::star::uno::RuntimeException) { + broadcast_changed(UPDATE, Any(columnWidth), Any()); return columnWidth; } @@ -87,6 +138,50 @@ void SAL_CALL GridColumn::setIdentifier(const ::com::sun::star::uno::Any & value void SAL_CALL GridColumn::setColumnWidth(::sal_Int32 value) throw (::com::sun::star::uno::RuntimeException) { columnWidth = value; + broadcast_changed(COLWIDTH, Any(columnWidth),Any(value)); +} +//-------------------------------------------------------------------- + +::sal_Int32 SAL_CALL GridColumn::getPreferredWidth() throw (::com::sun::star::uno::RuntimeException) +{ + broadcast_changed(UPDATE, Any(preferredWidth), Any()); + return preferredWidth; +} + +//-------------------------------------------------------------------- + +void SAL_CALL GridColumn::setPreferredWidth(::sal_Int32 value) throw (::com::sun::star::uno::RuntimeException) +{ + preferredWidth = value; + broadcast_changed(PREFWIDTH, Any(preferredWidth),Any(value)); +} +//-------------------------------------------------------------------- + +::sal_Int32 SAL_CALL GridColumn::getMaxWidth() throw (::com::sun::star::uno::RuntimeException) +{ + return maxWidth; +} + +//-------------------------------------------------------------------- + +void SAL_CALL GridColumn::setMaxWidth(::sal_Int32 value) throw (::com::sun::star::uno::RuntimeException) +{ + maxWidth = value; + broadcast_changed(MAXWIDTH, Any(maxWidth),Any(value)); +} +//-------------------------------------------------------------------- + +::sal_Int32 SAL_CALL GridColumn::getMinWidth() throw (::com::sun::star::uno::RuntimeException) +{ + return minWidth; +} + +//-------------------------------------------------------------------- + +void SAL_CALL GridColumn::setMinWidth(::sal_Int32 value) throw (::com::sun::star::uno::RuntimeException) +{ + minWidth = value; + broadcast_changed(MINWIDTH, Any(minWidth),Any(value)); } //-------------------------------------------------------------------- @@ -101,6 +196,45 @@ void SAL_CALL GridColumn::setColumnWidth(::sal_Int32 value) throw (::com::sun::s void SAL_CALL GridColumn::setTitle(const ::rtl::OUString & value) throw (::com::sun::star::uno::RuntimeException) { title = value; + broadcast_changed(TITLE, Any(title),Any(value)); +} +//-------------------------------------------------------------------- + +sal_Bool SAL_CALL GridColumn::getResizeable() throw (::com::sun::star::uno::RuntimeException) +{ + return bResizeable; +} + +//-------------------------------------------------------------------- + +void SAL_CALL GridColumn::setResizeable(sal_Bool value) throw (::com::sun::star::uno::RuntimeException) +{ + bResizeable = value; + broadcast_changed(COLRESIZE, Any(bResizeable),Any(value)); +} +//--------------------------------------------------------------------- +HorizontalAlignment SAL_CALL GridColumn::getHorizontalAlign() throw (::com::sun::star::uno::RuntimeException) +{ + return horizontalAlign; +} +//--------------------------------------------------------------------- + +void SAL_CALL GridColumn::setHorizontalAlign(HorizontalAlignment align) throw (::com::sun::star::uno::RuntimeException) +{ + horizontalAlign = align; + broadcast_changed(HALIGN, Any(horizontalAlign),Any(align)); +} +//--------------------------------------------------------------------- +void SAL_CALL GridColumn::addColumnListener( const Reference< XGridColumnListener >& xListener ) throw (RuntimeException) +{ + BrdcstHelper.addListener( XGridColumnListener::static_type(), xListener ); +} + +//--------------------------------------------------------------------- + +void SAL_CALL GridColumn::removeColumnListener( const Reference< XGridColumnListener >& xListener ) throw (RuntimeException) +{ + BrdcstHelper.removeListener( XGridColumnListener::static_type(), xListener ); } //--------------------------------------------------------------------- @@ -109,22 +243,30 @@ void SAL_CALL GridColumn::setTitle(const ::rtl::OUString & value) throw (::com:: void SAL_CALL GridColumn::dispose() throw (RuntimeException) { + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + ::com::sun::star::lang::EventObject aEvent; + aEvent.Source.set( static_cast< ::cppu::OWeakObject* >( this ) ); + BrdcstHelper.aLC.disposeAndClear( aEvent ); } //--------------------------------------------------------------------- void SAL_CALL GridColumn::addEventListener( const Reference< XEventListener >& xListener ) throw (RuntimeException) { - (void) xListener; + BrdcstHelper.addListener( XEventListener::static_type(), xListener ); } //--------------------------------------------------------------------- void SAL_CALL GridColumn::removeEventListener( const Reference< XEventListener >& xListener ) throw (RuntimeException) { - (void) xListener; + BrdcstHelper.removeListener( XEventListener::static_type(), xListener ); +} +void SAL_CALL GridColumn::setIndex(sal_Int32 _nIndex) throw (::com::sun::star::uno::RuntimeException) +{ + index = _nIndex; } - //--------------------------------------------------------------------- // XServiceInfo //--------------------------------------------------------------------- diff --git a/toolkit/source/controls/grid/gridcolumn.hxx b/toolkit/source/controls/grid/gridcolumn.hxx index 7f6d104127ec..38d43d55a07b 100644 --- a/toolkit/source/controls/grid/gridcolumn.hxx +++ b/toolkit/source/controls/grid/gridcolumn.hxx @@ -28,6 +28,8 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_toolkit.hxx" #include <com/sun/star/awt/grid/XGridColumn.hpp> +#include <com/sun/star/awt/grid/XGridColumnListener.hpp> +#include <com/sun/star/awt/grid/GridColumnEvent.hpp> #include <com/sun/star/lang/XEventListener.hpp> #include <com/sun/star/lang/XServiceInfo.hpp> #include <com/sun/star/lang/XUnoTunnel.hpp> @@ -36,6 +38,7 @@ #include <rtl/ref.hxx> #include <vector> #include <toolkit/helper/mutexandbroadcasthelper.hxx> +#include <com/sun/star/style/HorizontalAlignment.hpp> using ::rtl::OUString; using namespace ::com::sun::star; @@ -47,6 +50,7 @@ using namespace ::com::sun::star::lang; namespace toolkit { +enum broadcast_column_type { column_attribute_changed}; class GridColumn : public ::cppu::WeakImplHelper2< XGridColumn, XServiceInfo >, public MutexAndBroadcastHelper { @@ -59,9 +63,21 @@ public: virtual void SAL_CALL setIdentifier(const ::com::sun::star::uno::Any & value) throw (::com::sun::star::uno::RuntimeException); virtual ::sal_Int32 SAL_CALL getColumnWidth() throw (::com::sun::star::uno::RuntimeException); virtual void SAL_CALL setColumnWidth(::sal_Int32 the_value) throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Int32 SAL_CALL getPreferredWidth() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setPreferredWidth(::sal_Int32 the_value) throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Int32 SAL_CALL getMaxWidth() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setMaxWidth(::sal_Int32 the_value) throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Int32 SAL_CALL getMinWidth() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setMinWidth(::sal_Int32 the_value) throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL getResizeable() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setResizeable(::sal_Bool the_value) throw (::com::sun::star::uno::RuntimeException); virtual ::rtl::OUString SAL_CALL getTitle() throw (::com::sun::star::uno::RuntimeException); virtual void SAL_CALL setTitle(const ::rtl::OUString & value) throw (::com::sun::star::uno::RuntimeException); - + virtual ::com::sun::star::style::HorizontalAlignment SAL_CALL getHorizontalAlign() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setHorizontalAlign(::com::sun::star::style::HorizontalAlignment align) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addColumnListener( const Reference< XGridColumnListener >& xListener ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeColumnListener( const Reference< XGridColumnListener >& xListener ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL updateColumn( const ::rtl::OUString& name, ::sal_Int32 width ) throw (::com::sun::star::uno::RuntimeException); // XComponent virtual void SAL_CALL dispose( ) throw (RuntimeException); virtual void SAL_CALL addEventListener( const Reference< XEventListener >& xListener ) throw (RuntimeException); @@ -72,11 +88,20 @@ public: virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw (RuntimeException); virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw (RuntimeException); - + virtual void SAL_CALL setIndex(sal_Int32 _nIndex)throw (::com::sun::star::uno::RuntimeException); private: + void broadcast( broadcast_column_type eType, const GridColumnEvent& aEvent ); + void broadcast_changed( ::rtl::OUString name, Any oldValue, Any newValue); + Any identifier; + sal_Int32 index; sal_Int32 columnWidth; + sal_Int32 preferredWidth; + sal_Int32 maxWidth; + sal_Int32 minWidth; + sal_Bool bResizeable; ::rtl::OUString title; + ::com::sun::star::style::HorizontalAlignment horizontalAlign; }; } diff --git a/toolkit/source/controls/grid/gridcontrol.cxx b/toolkit/source/controls/grid/gridcontrol.cxx index f19648ab0af2..5125c1349ade 100644 --- a/toolkit/source/controls/grid/gridcontrol.cxx +++ b/toolkit/source/controls/grid/gridcontrol.cxx @@ -33,6 +33,7 @@ #include <com/sun/star/lang/XMultiServiceFactory.hpp> #include <com/sun/star/view/SelectionType.hpp> #include <com/sun/star/awt/grid/XGridDataModel.hpp> +#include <com/sun/star/awt/grid/XGridColumnModel.hpp> #include <com/sun/star/awt/grid/ScrollBarMode.hpp> #include <toolkit/helper/unopropertyarrayhelper.hxx> #include <toolkit/helper/property.hxx> @@ -68,12 +69,21 @@ UnoGridModel::UnoGridModel() ImplRegisterProperty( BASEPROPERTY_SIZEABLE ); // resizeable ImplRegisterProperty( BASEPROPERTY_HSCROLL ); ImplRegisterProperty( BASEPROPERTY_VSCROLL ); + ImplRegisterProperty( BASEPROPERTY_TABSTOP ); ImplRegisterProperty( BASEPROPERTY_GRID_SHOWROWHEADER ); ImplRegisterProperty( BASEPROPERTY_GRID_SHOWCOLUMNHEADER ); ImplRegisterProperty( BASEPROPERTY_GRID_DATAMODEL ); ImplRegisterProperty( BASEPROPERTY_GRID_COLUMNMODEL ); ImplRegisterProperty( BASEPROPERTY_GRID_SELECTIONMODE ); - + ImplRegisterProperty( BASEPROPERTY_FONTRELIEF ); + ImplRegisterProperty( BASEPROPERTY_FONTEMPHASISMARK ); + ImplRegisterProperty( BASEPROPERTY_FONTDESCRIPTOR ); + ImplRegisterProperty( BASEPROPERTY_TEXTCOLOR ); + ImplRegisterProperty( BASEPROPERTY_VERTICALALIGN ); + ImplRegisterProperty( BASEPROPERTY_GRID_EVEN_ROW_BACKGROUND ); + ImplRegisterProperty( BASEPROPERTY_GRID_HEADER_BACKGROUND ); + ImplRegisterProperty( BASEPROPERTY_GRID_LINE_COLOR ); + ImplRegisterProperty( BASEPROPERTY_GRID_ROW_BACKGROUND ); } UnoGridModel::UnoGridModel( const UnoGridModel& rModel ) @@ -99,6 +109,22 @@ Any UnoGridModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const return uno::makeAny( ::rtl::OUString::createFromAscii( szServiceName_GridControl ) ); case BASEPROPERTY_GRID_SELECTIONMODE: return uno::makeAny( SelectionType(1) ); + case BASEPROPERTY_GRID_SHOWROWHEADER: + return uno::makeAny( (sal_Bool)sal_False ); + case BASEPROPERTY_GRID_SHOWCOLUMNHEADER: + return uno::makeAny( (sal_Bool)sal_False ); + case BASEPROPERTY_GRID_DATAMODEL: + return uno::makeAny( Reference<XGridDataModel> ()); + case BASEPROPERTY_GRID_COLUMNMODEL: + return uno::makeAny(Reference<XGridColumnModel>() ); + case BASEPROPERTY_GRID_EVEN_ROW_BACKGROUND: + return uno::makeAny( com::sun::star::util::Color(0xFFFFFF) ); + case BASEPROPERTY_GRID_HEADER_BACKGROUND: + return uno::makeAny( com::sun::star::util::Color(0xFFFFFF) ); + case BASEPROPERTY_GRID_LINE_COLOR: + return uno::makeAny( com::sun::star::util::Color(0xFFFFFF) ); + case BASEPROPERTY_GRID_ROW_BACKGROUND: + return uno::makeAny(com::sun::star::util::Color(0xFFFFFF) ); default: return UnoControlModel::ImplGetDefaultValue( nPropId ); } @@ -128,7 +154,8 @@ Reference< XPropertySetInfo > UnoGridModel::getPropertySetInfo( ) throw(Runtime // class UnoGridControl // ---------------------------------------------------- UnoGridControl::UnoGridControl() -: mSelectionMode(SelectionType(1)) +: mSelectionMode(SelectionType(1)), + m_aSelectionListeners( *this ) { } @@ -139,6 +166,9 @@ OUString UnoGridControl::GetComponentServiceName() void SAL_CALL UnoGridControl::dispose( ) throw(RuntimeException) { + lang::EventObject aEvt; + aEvt.Source = (::cppu::OWeakObject*)this; + m_aSelectionListeners.disposeAndClear( aEvt ); UnoControl::dispose(); } @@ -147,63 +177,39 @@ void UnoGridControl::createPeer( const uno::Reference< awt::XToolkit > & rxToolk UnoControlBase::createPeer( rxToolkit, rParentPeer ); Reference< XGridControl > xGrid( getPeer(), UNO_QUERY_THROW ); + xGrid->addSelectionListener(&m_aSelectionListeners); Reference<XGridDataListener> xListener ( getPeer(), UNO_QUERY_THROW ); + Reference<XGridColumnListener> xColListener ( getPeer(), UNO_QUERY_THROW ); Reference<XPropertySet> xPropSet ( getModel(), UNO_QUERY_THROW ); Reference<XGridDataModel> xGridDataModel ( xPropSet->getPropertyValue(OUString::createFromAscii( "GridDataModel" )), UNO_QUERY_THROW ); - xGridDataModel->addDataListener(xListener); + if(xGridDataModel != NULL) + xGridDataModel->addDataListener(xListener); + Reference<XGridColumnModel> xGridColumnModel ( xPropSet->getPropertyValue(OUString::createFromAscii( "ColumnModel" )), UNO_QUERY_THROW ); + if(xGridColumnModel != NULL) + { + for(int i = 0;i<xGridColumnModel->getColumnCount();i++) + { + xGridColumnModel->getColumn(i)->addColumnListener(xColListener); + } + } } // ------------------------------------------------------------------- // XGridControl -// ------------------------------------------------------------------- - -::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumnModel > SAL_CALL UnoGridControl::getColumnModel() throw (::com::sun::star::uno::RuntimeException) -{ - Reference<XPropertySet> xPropSet ( getModel(), UNO_QUERY_THROW ); - Reference<XGridColumnModel> xGridColumnModel ( xPropSet->getPropertyValue(OUString::createFromAscii( "ColumnModel" )), UNO_QUERY_THROW ); - - return xGridColumnModel; -} - -void SAL_CALL UnoGridControl::setColumnModel(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumnModel > & model) throw (::com::sun::star::uno::RuntimeException) -{ - Reference<XPropertySet> xPropSet ( getModel(), UNO_QUERY_THROW ); - xPropSet->setPropertyValue(OUString::createFromAscii( "ColumnModel" ), Any (model)); -} - -::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridDataModel > SAL_CALL UnoGridControl::getDataModel() throw (::com::sun::star::uno::RuntimeException) -{ - Reference<XPropertySet> xPropSet ( getModel(), UNO_QUERY_THROW ); - Reference<XGridDataModel> xGridDataModel ( xPropSet->getPropertyValue(OUString::createFromAscii( "GridDataModel" )), UNO_QUERY_THROW ); - - return xGridDataModel; -} - -void SAL_CALL UnoGridControl::setDataModel(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridDataModel > & model) throw (::com::sun::star::uno::RuntimeException) -{ - Reference<XPropertySet> xPropSet ( getModel(), UNO_QUERY_THROW ); - xPropSet->setPropertyValue(OUString::createFromAscii( "GridDataModel" ), Any(model)); -} ::sal_Int32 UnoGridControl::getItemIndexAtPoint(::sal_Int32 x, ::sal_Int32 y) throw (::com::sun::star::uno::RuntimeException) { - return Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->getItemIndexAtPoint( x, y ); + Reference< XGridControl > xGrid ( getPeer(), UNO_QUERY_THROW ); + return xGrid->getItemIndexAtPoint( x, y ); } -/* -void SAL_CALL UnoGridControl::addMouseListener(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XMouseListener > & listener) throw (::com::sun::star::uno::RuntimeException) +void SAL_CALL UnoGridControl::setToolTip(const ::com::sun::star::uno::Sequence< ::rtl::OUString >& text, const ::com::sun::star::uno::Sequence< ::sal_Int32 >& columns) throw (::com::sun::star::uno::RuntimeException) { - Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->addMouseListener( listener ); + Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->setToolTip( text, columns ); } - -void SAL_CALL UnoGridControl::removeMouseListener(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XMouseListener > & listener) throw (::com::sun::star::uno::RuntimeException) -{ - Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->removeMouseListener( listener ); -} -*/ // ------------------------------------------------------------------- // XGridSelection // ------------------------------------------------------------------- @@ -218,16 +224,24 @@ void SAL_CALL UnoGridControl::removeMouseListener(const ::com::sun::star::uno::R return Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->getMaxSelectionIndex(); } -void SAL_CALL UnoGridControl::insertIndexIntervall(::sal_Int32 start, ::sal_Int32 length) throw (::com::sun::star::uno::RuntimeException) +void SAL_CALL UnoGridControl::selectRows(const ::com::sun::star::uno::Sequence< ::sal_Int32 >& rangeOfRows) throw (::com::sun::star::uno::RuntimeException) { - Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->insertIndexIntervall( start, length); + Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->selectRows( rangeOfRows); } -void SAL_CALL UnoGridControl::removeIndexIntervall(::sal_Int32 start, ::sal_Int32 length) throw (::com::sun::star::uno::RuntimeException) +void SAL_CALL UnoGridControl::selectAllRows() throw (::com::sun::star::uno::RuntimeException) +{ + Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->selectAllRows(); +} +void SAL_CALL UnoGridControl::deselectRows(const ::com::sun::star::uno::Sequence< ::sal_Int32 >& rangeOfRows) throw (::com::sun::star::uno::RuntimeException) { - Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->removeIndexIntervall( start, length ); + Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->deselectRows( rangeOfRows); } +void SAL_CALL UnoGridControl::deselectAllRows() throw (::com::sun::star::uno::RuntimeException) +{ + Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->deselectAllRows(); +} ::com::sun::star::uno::Sequence< ::sal_Int32 > SAL_CALL UnoGridControl::getSelection() throw (::com::sun::star::uno::RuntimeException) { return Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->getSelection(); @@ -250,14 +264,14 @@ void SAL_CALL UnoGridControl::selectRow(::sal_Int32 y) throw (::com::sun::star:: void SAL_CALL UnoGridControl::addSelectionListener(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridSelectionListener > & listener) throw (::com::sun::star::uno::RuntimeException) { - Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->addSelectionListener( listener ); + m_aSelectionListeners.addInterface( listener ); } void SAL_CALL UnoGridControl::removeSelectionListener(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridSelectionListener > & listener) throw (::com::sun::star::uno::RuntimeException) { - Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->removeSelectionListener( listener ); -} + m_aSelectionListeners.removeInterface( listener ); } +}//namespace toolkit Reference< XInterface > SAL_CALL GridControl_CreateInstance( const Reference< XMultiServiceFactory >& ) { diff --git a/toolkit/source/controls/grid/gridcontrol.hxx b/toolkit/source/controls/grid/gridcontrol.hxx index 4195a1f624e5..0c8ddb1c02b6 100644 --- a/toolkit/source/controls/grid/gridcontrol.hxx +++ b/toolkit/source/controls/grid/gridcontrol.hxx @@ -30,10 +30,11 @@ #include <com/sun/star/awt/grid/XGridControl.hpp> #include <com/sun/star/view/SelectionType.hpp> -#include <toolkit/controls/unocontrols.hxx> +#include <toolkit/controls/unocontrolbase.hxx> #include <toolkit/controls/unocontrolmodel.hxx> #include <toolkit/helper/servicenames.hxx> #include <cppuhelper/implbase1.hxx> +#include <comphelper/sequence.hxx> #include <toolkit/helper/listenermultiplexer.hxx> @@ -87,20 +88,18 @@ public: void SAL_CALL createPeer( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XToolkit >& Toolkit, const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer >& Parent ) throw(::com::sun::star::uno::RuntimeException); // ::com::sun::star::awt::grid::XGridControl - virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumnModel > SAL_CALL getColumnModel() throw (::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL setColumnModel(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumnModel > & model) throw (::com::sun::star::uno::RuntimeException); - virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridDataModel > SAL_CALL getDataModel() throw (::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL setDataModel(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridDataModel > & model) throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Int32 SAL_CALL getItemIndexAtPoint(::sal_Int32 x, ::sal_Int32 y) throw (::com::sun::star::uno::RuntimeException); - //virtual void SAL_CALL addMouseListener(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XMouseListener > & listener) throw (::com::sun::star::uno::RuntimeException); - //virtual void SAL_CALL removeMouseListener(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XMouseListener > & listener) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setToolTip(const ::com::sun::star::uno::Sequence< ::rtl::OUString >& text, const ::com::sun::star::uno::Sequence< ::sal_Int32 >& columns) throw (::com::sun::star::uno::RuntimeException); // ::com::sun::star::awt::grid::XGridSelection virtual ::sal_Int32 SAL_CALL getMinSelectionIndex() throw (::com::sun::star::uno::RuntimeException); virtual ::sal_Int32 SAL_CALL getMaxSelectionIndex() throw (::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL insertIndexIntervall(::sal_Int32 start, ::sal_Int32 length) throw (::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL removeIndexIntervall(::sal_Int32 start, ::sal_Int32 length) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL selectRows(const ::com::sun::star::uno::Sequence< ::sal_Int32 >& rangeOfRows) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL selectAllRows() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL deselectRows(const ::com::sun::star::uno::Sequence< ::sal_Int32 >& rangeOfRows) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL deselectAllRows() throw (::com::sun::star::uno::RuntimeException); virtual ::com::sun::star::uno::Sequence< ::sal_Int32 > SAL_CALL getSelection() throw (::com::sun::star::uno::RuntimeException); virtual ::sal_Bool SAL_CALL isSelectionEmpty() throw (::com::sun::star::uno::RuntimeException); virtual ::sal_Bool SAL_CALL isSelectedIndex(::sal_Int32 index) throw (::com::sun::star::uno::RuntimeException); @@ -114,6 +113,7 @@ public: using UnoControl::getPeer; private: ::com::sun::star::view::SelectionType mSelectionMode; + SelectionListenerMultiplexer m_aSelectionListeners; }; } // toolkit diff --git a/toolkit/source/helper/listenermultiplexer.cxx b/toolkit/source/helper/listenermultiplexer.cxx index fcfd6214780e..9b8df60521ae 100644 --- a/toolkit/source/helper/listenermultiplexer.cxx +++ b/toolkit/source/helper/listenermultiplexer.cxx @@ -206,3 +206,8 @@ IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD( TreeExpansionListenerMultiplexer, ::com // ---------------------------------------------------- IMPL_LISTENERMULTIPLEXER_BASEMETHODS( TreeEditListenerMultiplexer, ::com::sun::star::awt::tree::XTreeEditListener ) +// ---------------------------------------------------- +// class SelectionListenerMultiplexer +// ---------------------------------------------------- +IMPL_LISTENERMULTIPLEXER_BASEMETHODS( SelectionListenerMultiplexer, ::com::sun::star::awt::grid::XGridSelectionListener ) +IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD( SelectionListenerMultiplexer, ::com::sun::star::awt::grid::XGridSelectionListener, selectionChanged, ::com::sun::star::awt::grid::GridSelectionEvent ) diff --git a/toolkit/source/helper/property.cxx b/toolkit/source/helper/property.cxx index 7ede81d485d7..6711e4503511 100644 --- a/toolkit/source/helper/property.cxx +++ b/toolkit/source/helper/property.cxx @@ -281,8 +281,12 @@ ImplPropertyInfo* ImplGetPropertyInfos( sal_uInt16& rElementCount ) DECL_PROP_3 ( "ColumnModel", GRID_COLUMNMODEL, Reference< ::com::sun::star::awt::grid::XGridColumnModel >, BOUND, MAYBEDEFAULT, MAYBEVOID ), DECL_PROP_3 ( "SelectionModel", GRID_SELECTIONMODE, ::com::sun::star::view::SelectionType, BOUND, MAYBEDEFAULT, MAYBEVOID ), DECL_PROP_2 ( "EnableVisible", ENABLEVISIBLE, sal_Bool, BOUND, MAYBEDEFAULT ), - DECL_PROP_3 ( "ReferenceDevice", REFERENCE_DEVICE, Reference< XDevice >,BOUND, MAYBEDEFAULT, TRANSIENT ) - }; + DECL_PROP_3 ( "ReferenceDevice", REFERENCE_DEVICE, Reference< XDevice >,BOUND, MAYBEDEFAULT, TRANSIENT ), + DECL_PROP_3 ( "EvenRowBackgroundColor", GRID_EVEN_ROW_BACKGROUND, sal_Int32, BOUND, MAYBEDEFAULT, MAYBEVOID ), + DECL_PROP_3 ( "HeaderBackgroundColor", GRID_HEADER_BACKGROUND, sal_Int32, BOUND, MAYBEDEFAULT, MAYBEVOID ), + DECL_PROP_3 ( "LineColor", GRID_LINE_COLOR, sal_Int32, BOUND, MAYBEDEFAULT, MAYBEVOID ), + DECL_PROP_3 ( "RowBackgroundColor", GRID_ROW_BACKGROUND, sal_Int32, BOUND, MAYBEDEFAULT, MAYBEVOID ) + }; pPropertyInfos = aImplPropertyInfos; nElements = sizeof( aImplPropertyInfos ) / sizeof( ImplPropertyInfo ); } diff --git a/tools/bootstrp/command.cxx b/tools/bootstrp/command.cxx index 605965339b0e..2ab0cc8dc4a6 100644 --- a/tools/bootstrp/command.cxx +++ b/tools/bootstrp/command.cxx @@ -355,7 +355,7 @@ CCommand::CCommand( ByteString &rString ) { rString.SearchAndReplace( '\t', ' ' ); aCommand = rString.GetToken( 0, ' ' ); - aCommandLine = Search(); + aCommandLine = Search( "PATH" ); #ifndef UNX aCommandLine += " /c "; #else @@ -365,7 +365,7 @@ CCommand::CCommand( ByteString &rString ) ByteString sCmd( rString.GetToken( 0, ' ' )); ByteString sParam( rString.Copy( sCmd.Len())); - aCommandLine += Search( thePath, sCmd ); + aCommandLine += Search( "PATH", sCmd ); aCommandLine += sParam; ImplInit(); @@ -379,7 +379,7 @@ CCommand::CCommand( const char *pChar ) aString.SearchAndReplace( '\t', ' ' ); aCommand = aString.GetToken( 0, ' ' ); - aCommandLine = Search(); + aCommandLine = Search( "PATH" ); #ifndef UNX aCommandLine += " /c "; #else @@ -390,7 +390,7 @@ CCommand::CCommand( const char *pChar ) ByteString sCmd( rString.GetToken( 0, ' ' )); ByteString sParam( rString.Copy( sCmd.Len())); - aCommandLine += Search( thePath, sCmd ); + aCommandLine += Search( "PATH", sCmd ); aCommandLine += sParam; ImplInit(); diff --git a/tools/bootstrp/rscdep.cxx b/tools/bootstrp/rscdep.cxx index 35968654b5cd..5c18793c9833 100644 --- a/tools/bootstrp/rscdep.cxx +++ b/tools/bootstrp/rscdep.cxx @@ -36,6 +36,7 @@ #include <string.h> #include "bootstrp/prj.hxx" +#include "sal/main.h" #include <tools/string.hxx> #include <tools/list.hxx> @@ -78,12 +79,7 @@ static int optopt = 0; static int opterr = 0; #endif - -int -#ifdef WNT -_cdecl -#endif -main( int argc, char **argv ) +SAL_IMPLEMENT_MAIN_WITH_ARGS( argc, argv ) { int c; char aBuf[255]; diff --git a/tools/inc/bootstrp/command.hxx b/tools/inc/bootstrp/command.hxx index e0d8f1e39aeb..638beb6cce1f 100644 --- a/tools/inc/bootstrp/command.hxx +++ b/tools/inc/bootstrp/command.hxx @@ -92,8 +92,6 @@ public: void Print(); }; -static ByteString thePath( "PATH" ); - /** Declares and spawns a child process. The spawned programm could be a native executable or a schell script. */ @@ -127,7 +125,7 @@ public: @param sItem specifies the system shell @return the Location (when programm was found) */ - static ByteString Search( ByteString sEnv = thePath, + static ByteString Search( ByteString sEnv, ByteString sItem = COMMAND_SHELL ); /** Spawns the Process diff --git a/tools/inc/tools/debug.hxx b/tools/inc/tools/debug.hxx index e764ed2fc79a..b8aa1c8b59fe 100644 --- a/tools/inc/tools/debug.hxx +++ b/tools/inc/tools/debug.hxx @@ -125,19 +125,18 @@ struct DbgDataType #define DBG_FUNC_SAVEDATA 5 #define DBG_FUNC_SETPRINTMSGBOX 6 #define DBG_FUNC_SETPRINTWINDOW 7 -#define DBG_FUNC_SETPRINTSHELL 8 -#define DBG_FUNC_SETPRINTTESTTOOL 9 -#define DBG_FUNC_MEMTEST 10 -#define DBG_FUNC_XTORINFO 11 -#define DBG_FUNC_MEMINFO 12 -#define DBG_FUNC_COREDUMP 13 -#define DBG_FUNC_ALLERROROUT 14 -#define DBG_FUNC_SETTESTSOLARMUTEX 15 -#define DBG_FUNC_TESTSOLARMUTEX 16 -#define DBG_FUNC_PRINTFILE 17 -#define DBG_FUNC_GETPRINTMSGBOX 18 -#define DBG_FUNC_FILTERMESSAGE 19 // new for #i38967 -#define DBG_FUNC_UPDATEOSLHOOK 20 +#define DBG_FUNC_SETPRINTTESTTOOL 8 +#define DBG_FUNC_MEMTEST 9 +#define DBG_FUNC_XTORINFO 10 +#define DBG_FUNC_MEMINFO 11 +#define DBG_FUNC_COREDUMP 12 +#define DBG_FUNC_ALLERROROUT 13 +#define DBG_FUNC_SETTESTSOLARMUTEX 14 +#define DBG_FUNC_TESTSOLARMUTEX 15 +#define DBG_FUNC_PRINTFILE 16 +#define DBG_FUNC_GETPRINTMSGBOX 17 +#define DBG_FUNC_FILTERMESSAGE 18 // new for #i38967 +#define DBG_FUNC_UPDATEOSLHOOK 19 TOOLS_DLLPUBLIC void* DbgFunc( USHORT nAction, void* pData = NULL ); @@ -176,11 +175,6 @@ inline void DbgSetPrintWindow( DbgPrintLine pProc ) DbgFunc( DBG_FUNC_SETPRINTWINDOW, (void*)(long)pProc ); } -inline void DbgSetPrintShell( DbgPrintLine pProc ) -{ - DbgFunc( DBG_FUNC_SETPRINTSHELL, (void*)(long)pProc ); -} - inline void DbgSetPrintTestTool( DbgPrintLine pProc ) { DbgFunc( DBG_FUNC_SETPRINTTESTTOOL, (void*)(long)pProc ); @@ -344,6 +338,7 @@ void DbgPrintStackTree( void* p ); TOOLS_DLLPUBLIC void DbgOut( const sal_Char* pMsg, USHORT nOutType = DBG_OUT_TRACE, const sal_Char* pFile = NULL, USHORT nLine = 0 ); +TOOLS_DLLPUBLIC void DbgPrintShell(char const * message); TOOLS_DLLPUBLIC void DbgOutTypef( USHORT nOutType, const sal_Char* pFStr, ... ); TOOLS_DLLPUBLIC void DbgOutf( const sal_Char* pFStr, ... ); TOOLS_DLLPUBLIC void ImpDbgOutfBuf( sal_Char* pBuf, const sal_Char* pFStr, ... ); diff --git a/canvas/source/java/SpriteBase.java b/tools/inc/tools/postextstl.h index 5f2ed3c57ecc..81a21e25c15b 100644 --- a/canvas/source/java/SpriteBase.java +++ b/tools/inc/tools/postextstl.h @@ -25,10 +25,12 @@ * ************************************************************************/ -// Canvas - -public interface SpriteBase -{ - // to be overridden - public SpriteRep getSpriteRep(); -} +#ifdef std_was_redefined_as_stlport +// put things back the way they were +# define std std_was_redefined_as_stlport +# undef _STLP_OUTERMOST_HEADER_ID +// force config to be re-read +# undef _STLP_NOTHROW_INHERENTLY +# undef _STLP_CONFIG_H +# include <stddef.h> +#endif diff --git a/tools/inc/tools/preextstl.h b/tools/inc/tools/preextstl.h new file mode 100644 index 000000000000..4d0418d01c57 --- /dev/null +++ b/tools/inc/tools/preextstl.h @@ -0,0 +1,64 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#if defined(ADAPT_EXT_STL) +# include <ostream> +# include <istream> +# include <fstream> +# include <iostream> +# include <vector> +# include <list> +# include <map> +# include <algorithm> +# if defined(std) +# define std_was_redefined_as_stlport std +# undef std +# define _STLP_OUTERMOST_HEADER_ID 0xdeadbeaf +# pragma GCC visibility push(default) +# include _STLP_NATIVE_HEADER(exception_defines.h) +# include _STLP_NATIVE_HEADER(limits) +# include _STLP_NATIVE_HEADER(memory) +# include _STLP_NATIVE_HEADER(exception) +# include _STLP_NATIVE_HEADER(iosfwd) +# include _STLP_NATIVE_HEADER(algorithm) +# include _STLP_NATIVE_HEADER(string) +# include _STLP_NATIVE_HEADER(streambuf) +# include _STLP_NATIVE_HEADER(ios) +# include _STLP_NATIVE_HEADER(locale) +# include _STLP_NATIVE_HEADER(stdexcept) +# include _STLP_NATIVE_HEADER(ostream) +# include _STLP_NATIVE_HEADER(istream) +# include _STLP_NATIVE_HEADER(iostream) +# include _STLP_NATIVE_HEADER(vector) +# include _STLP_NATIVE_HEADER(list) +# include _STLP_NATIVE_HEADER(map) +# pragma GCC visibility pop +# endif +#endif +//ext_std resolves to the std that external c++ libs, e.g. Graphite were built +//against regardless of whether that is stlport or system stl +namespace ext_std = std; diff --git a/tools/prj/d.lst b/tools/prj/d.lst index 76cb0107453c..6b4a99a3a676 100644 --- a/tools/prj/d.lst +++ b/tools/prj/d.lst @@ -34,6 +34,9 @@ mkdir: %_DEST%\inc%_EXT%\bootstrp ..\inc\tools\postx.h %_DEST%\inc%_EXT%\tools\postx.h ..\inc\tools\prex.h %_DEST%\inc%_EXT%\tools\prex.h +..\inc\tools\postextstl.h %_DEST%\inc%_EXT%\tools\postextstl.h +..\inc\tools\preextstl.h %_DEST%\inc%_EXT%\tools\preextstl.h + ..\inc\tools\solarmutex.hxx %_DEST%\inc%_EXT%\tools\solarmutex.hxx ..\inc\tools\wintypes.hxx %_DEST%\inc%_EXT%\tools\wintypes.hxx ..\inc\tools\mapunit.hxx %_DEST%\inc%_EXT%\tools\mapunit.hxx diff --git a/tools/qa/makefile.mk b/tools/qa/makefile.mk index 66ed19e20737..abaea848c1db 100644 --- a/tools/qa/makefile.mk +++ b/tools/qa/makefile.mk @@ -32,6 +32,7 @@ ENABLE_EXCEPTIONS = TRUE .INCLUDE: settings.mk +CFLAGSCXX += $(CPPUNIT_CFLAGS) DLLPRE = # no leading "lib" on .so files SHL1TARGET = test_pathutils diff --git a/tools/source/debug/debug.cxx b/tools/source/debug/debug.cxx index 62f36e662ea9..e17457c60525 100644 --- a/tools/source/debug/debug.cxx +++ b/tools/source/debug/debug.cxx @@ -151,7 +151,6 @@ struct DebugData USHORT bInit; DbgPrintLine pDbgPrintMsgBox; DbgPrintLine pDbgPrintWindow; - DbgPrintLine pDbgPrintShell; DbgPrintLine pDbgPrintTestTool; ::std::vector< DbgPrintLine > aDbgPrintUserChannels; @@ -166,7 +165,6 @@ struct DebugData :bInit( FALSE ) ,pDbgPrintMsgBox( FALSE ) ,pDbgPrintWindow( NULL ) - ,pDbgPrintShell( NULL ) ,pDbgPrintTestTool( NULL ) ,pProfList( NULL ) ,pXtorList( NULL ) @@ -1037,9 +1035,7 @@ static void DebugDeInit() pData->aDbgData.nTestFlags &= (DBG_TEST_MEM | DBG_TEST_PROFILING); pData->aDbgPrintUserChannels.clear(); pData->pDbgPrintTestTool = NULL; - pData->pDbgPrintShell = NULL; pData->pDbgPrintWindow = NULL; - pData->pDbgPrintShell = NULL; pData->pOldDebugMessageFunc = NULL; ImplDbgDeInitLock(); } @@ -1199,10 +1195,6 @@ void* DbgFunc( USHORT nAction, void* pParam ) pDebugData->pDbgPrintWindow = (DbgPrintLine)(long)pParam; break; - case DBG_FUNC_SETPRINTSHELL: - pDebugData->pDbgPrintShell = (DbgPrintLine)(long)pParam; - break; - case DBG_FUNC_SETPRINTTESTTOOL: pDebugData->pDbgPrintTestTool = (DbgPrintLine)(long)pParam; break; @@ -1739,14 +1731,6 @@ void DbgOut( const sal_Char* pMsg, USHORT nDbgOut, const sal_Char* pFile, USHORT if ( pData->pDbgPrintMsgBox ) pData->pDbgPrintMsgBox( aBufOut ); else - nOut = DBG_OUT_SHELL; - } - - if ( nOut == DBG_OUT_SHELL ) - { - if ( pData->pDbgPrintShell ) - pData->pDbgPrintShell( aBufOut ); - else nOut = DBG_OUT_WINDOW; } @@ -1758,14 +1742,28 @@ void DbgOut( const sal_Char* pMsg, USHORT nDbgOut, const sal_Char* pFile, USHORT nOut = DBG_OUT_FILE; } - if ( nOut == DBG_OUT_FILE ) + switch ( nOut ) + { + case DBG_OUT_SHELL: + DbgPrintShell( aBufOut ); + break; + case DBG_OUT_FILE: ImplDbgPrintFile( aBufOut ); + break; + } ImplDbgUnlock(); bIn = FALSE; } +void DbgPrintShell(char const * message) { + fprintf(stderr, "%s\n", message); +#if defined WNT + OutputDebugStringA(message); +#endif +} + // ----------------------------------------------------------------------- void DbgOutTypef( USHORT nDbgOut, const sal_Char* pFStr, ... ) diff --git a/tools/source/fsys/tdir.cxx b/tools/source/fsys/tdir.cxx index 429835d35ab3..b6bf48a8cdf9 100644 --- a/tools/source/fsys/tdir.cxx +++ b/tools/source/fsys/tdir.cxx @@ -266,7 +266,7 @@ void Dir::Construct( DirEntryKind nKindFlags ) strcpy( pBuffer, aTStr.GetBuffer() ); CharLowerBuff( pBuffer, aTStr.Len() ); aNameMask = WildCard( String(pBuffer, osl_getThreadTextEncoding()), ';' ); - delete pBuffer; + delete [] pBuffer; } #else aNameMask = WildCard( CutName(), ';' ); diff --git a/tools/source/stream/strmunx.cxx b/tools/source/stream/strmunx.cxx index 8a3504a417c0..9e4f501d1823 100644 --- a/tools/source/stream/strmunx.cxx +++ b/tools/source/stream/strmunx.cxx @@ -91,7 +91,7 @@ InternalStreamLock::InternalStreamLock( #if OSL_DEBUG_LEVEL > 1 fprintf( stderr, "locked %s", aFileName.GetBuffer() ); if( m_nStartPos || m_nEndPos ) - fprintf(stderr, " [ %d ... %d ]", m_nStartPos, m_nEndPos ); + fprintf(stderr, " [ %ld ... %ld ]", m_nStartPos, m_nEndPos ); fprintf( stderr, "\n" ); #endif } @@ -103,7 +103,7 @@ InternalStreamLock::~InternalStreamLock() ByteString aFileName(m_pStream->GetFileName(), osl_getThreadTextEncoding()); fprintf( stderr, "unlocked %s", aFileName.GetBuffer() ); if( m_nStartPos || m_nEndPos ) - fprintf(stderr, " [ %d ... %d ]", m_nStartPos, m_nEndPos ); + fprintf(stderr, " [ %ld ... %ld ]", m_nStartPos, m_nEndPos ); fprintf( stderr, "\n" ); #endif } @@ -514,7 +514,7 @@ sal_Bool SvFileStream::LockRange( sal_Size nByteOffset, sal_Size nBytes ) if( ! InternalStreamLock::LockFile( nByteOffset, nByteOffset+nBytes, this ) ) { #if OSL_DEBUG_LEVEL > 1 - fprintf( stderr, "InternalLock on %s [ %d ... %d ] failed\n", + fprintf( stderr, "InternalLock on %s [ %ld ... %ld ] failed\n", ByteString(aFilename, osl_getThreadTextEncoding()).GetBuffer(), nByteOffset, nByteOffset+nBytes ); #endif return sal_False; diff --git a/tools/test/export.map b/tools/test/export.map index 709047ae63e5..7321bbca16ad 100644 --- a/tools/test/export.map +++ b/tools/test/export.map @@ -25,7 +25,7 @@ # #************************************************************************* -UDK_3.1 { +UDK_3_0_0 { global: registerAllTestFunction; diff --git a/tools/test/makefile.mk b/tools/test/makefile.mk index 5dea8ce6f960..ab2cfd8e6676 100644 --- a/tools/test/makefile.mk +++ b/tools/test/makefile.mk @@ -36,6 +36,8 @@ ENABLE_EXCEPTIONS=TRUE .INCLUDE : settings.mk +CFLAGSCXX += $(CPPUNIT_CFLAGS) + # --- Common ---------------------------------------------------------- SHL1OBJS= \ diff --git a/ucbhelper/workben/myucp/exports.map b/ucbhelper/workben/myucp/exports.map deleted file mode 100644 index f4ed78b9e970..000000000000 --- a/ucbhelper/workben/myucp/exports.map +++ /dev/null @@ -1,8 +0,0 @@ -UDK_3_0_0 { - global: - component_getImplementationEnvironment; - component_writeInfo; - component_getFactory; - local: - *; -}; diff --git a/ucbhelper/workben/myucp/makefile.mk b/ucbhelper/workben/myucp/makefile.mk index 0d7f273fe877..77faad2e0396 100644 --- a/ucbhelper/workben/myucp/makefile.mk +++ b/ucbhelper/workben/myucp/makefile.mk @@ -68,7 +68,7 @@ LIB1OBJFILES=$(SLOFILES) SHL1TARGET=$(TARGET) SHL1IMPLIB=i$(TARGET) -SHL1VERSIONMAP=exports.map +SHL1VERSIONMAP=$(SOLARENV)/src/component.map # @@@ Add additional libs here. SHL1STDLIBS=\ diff --git a/unotools/source/misc/desktopterminationobserver.cxx b/unotools/source/misc/desktopterminationobserver.cxx index 23d5089f545e..3900449f03c9 100644 --- a/unotools/source/misc/desktopterminationobserver.cxx +++ b/unotools/source/misc/desktopterminationobserver.cxx @@ -211,12 +211,6 @@ namespace utl void DesktopTerminationObserver::revokeTerminationListener( ITerminationListener* _pListener ) { ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); - if ( getListenerAdminData().bAlreadyTerminated ) - { - _pListener->notifyTermination(); - return; - } - Listeners& rListeners = getListenerAdminData().aListeners; for ( Listeners::iterator lookup = rListeners.begin(); lookup != rListeners.end(); diff --git a/vcl/aqua/source/dtrans/aqua_clipboard.cxx b/vcl/aqua/source/dtrans/aqua_clipboard.cxx index d3a4e9bc604c..52fb13e1e11f 100644 --- a/vcl/aqua/source/dtrans/aqua_clipboard.cxx +++ b/vcl/aqua/source/dtrans/aqua_clipboard.cxx @@ -189,6 +189,10 @@ void SAL_CALL AquaClipboard::setContents(const Reference<XTransferable>& xTransf const Reference<XClipboardOwner>& xClipboardOwner) throw( RuntimeException ) { + NSArray* types = xTransferable.is() ? + mpDataFlavorMapper->flavorSequenceToTypesArray(xTransferable->getTransferDataFlavors()) : + [NSArray array]; + ClearableMutexGuard aGuard(m_aMutex); Reference<XClipboardOwner> oldOwner(mXClipboardOwner); @@ -197,11 +201,10 @@ void SAL_CALL AquaClipboard::setContents(const Reference<XTransferable>& xTransf Reference<XTransferable> oldContent(mXClipboardContent); mXClipboardContent = xTransferable; - NSArray* types = mXClipboardContent.is() ? - mpDataFlavorMapper->flavorSequenceToTypesArray(mXClipboardContent->getTransferDataFlavors()) : - [NSArray array]; mPasteboardChangeCount = [mPasteboard declareTypes: types owner: mEventListener]; + aGuard.clear(); + // if we are already the owner of the clipboard // then fire lost ownership event if (oldOwner.is()) @@ -253,7 +256,7 @@ void SAL_CALL AquaClipboard::removeClipboardListener(const Reference< XClipboard void AquaClipboard::applicationDidBecomeActive(NSNotification* aNotification) { - MutexGuard aGuard(m_aMutex); + ClearableMutexGuard aGuard(m_aMutex); int currentPboardChgCount = [mPasteboard changeCount]; @@ -270,6 +273,8 @@ void AquaClipboard::applicationDidBecomeActive(NSNotification* aNotification) Reference<XTransferable> oldContent(mXClipboardContent); mXClipboardContent = Reference<XTransferable>(); + aGuard.clear(); + if (oldOwner.is()) { fireLostClipboardOwnershipEvent(oldOwner, oldContent); diff --git a/vcl/aqua/source/gdi/aquaprintaccessoryview.mm b/vcl/aqua/source/gdi/aquaprintaccessoryview.mm index 74c66ab1401d..d00fc9a6cd0e 100644 --- a/vcl/aqua/source/gdi/aquaprintaccessoryview.mm +++ b/vcl/aqua/source/gdi/aquaprintaccessoryview.mm @@ -318,6 +318,12 @@ class ControllerProperties double fScaleX = double(aLogicSize.Width())/double(aPageSize.aSize.Width()); double fScaleY = double(aLogicSize.Height())/double(aPageSize.aSize.Height()); double fScale = (fScaleX < fScaleY) ? fScaleX : fScaleY; + // #i104784# if we render the page too small then rounding issues result in + // layout artifacts looking really bad. So scale the page unto a device that is not + // full page size but not too small either. This also results in much better visual + // quality of the preview, e.g. when its height approaches the number of text lines + if( fScale < 0.1 ) + fScale = 0.1; aMtf.WindStart(); aMtf.Scale( fScale, fScale ); aMtf.WindStart(); @@ -358,9 +364,10 @@ class ControllerProperties NSSize aMargins = [mpPreviewBox contentViewMargins]; aPreviewFrame.origin.x = 0; aPreviewFrame.origin.y = 34; + aPreviewFrame.size.width -= 2*(aMargins.width+1); aPreviewFrame.size.height -= 61; mpPreview = [[NSImageView alloc] initWithFrame: aPreviewFrame]; - [mpPreview setImageScaling: NSScaleNone]; + [mpPreview setImageScaling: NSScaleProportionally]; [mpPreview setImageAlignment: NSImageAlignCenter]; [mpPreview setImageFrameStyle: NSImageFrameNone]; [mpPreviewBox addSubview: [mpPreview autorelease]]; diff --git a/vcl/aqua/source/gdi/salgdi.cxx b/vcl/aqua/source/gdi/salgdi.cxx index a54a7fad7ac5..38fb068bb353 100644 --- a/vcl/aqua/source/gdi/salgdi.cxx +++ b/vcl/aqua/source/gdi/salgdi.cxx @@ -1095,7 +1095,8 @@ void AquaSalGraphics::copyBits( const SalTwoRect *pPosAry, SalGraphics *pSrcGrap DBG_ASSERT( pSrc->mxLayer!=NULL, "AquaSalGraphics::copyBits() from non-layered graphics" ); const CGPoint aDstPoint = { +pPosAry->mnDestX - pPosAry->mnSrcX, pPosAry->mnDestY - pPosAry->mnSrcY }; - if( !mnBitmapDepth || (aDstPoint.x + pSrc->mnWidth) <= mnWidth ) // workaround a Quartz crasher + if( (pPosAry->mnSrcWidth == pPosAry->mnDestWidth && pPosAry->mnSrcHeight == pPosAry->mnDestHeight) && + (!mnBitmapDepth || (aDstPoint.x + pSrc->mnWidth) <= mnWidth) ) // workaround a Quartz crasher { // in XOR mode the drawing context is redirected to the XOR mask // if source and target are identical then copyBits() paints onto the target context though diff --git a/vcl/aqua/source/gdi/salprn.cxx b/vcl/aqua/source/gdi/salprn.cxx index cee243093ff3..1c0401f769b5 100644 --- a/vcl/aqua/source/gdi/salprn.cxx +++ b/vcl/aqua/source/gdi/salprn.cxx @@ -532,8 +532,6 @@ BOOL AquaSalInfoPrinter::StartJob( const String* i_pFileName, PrintAccessoryViewState aAccViewState; sal_Int32 nAllPages = 0; - aAccViewState.bNeedRestart = true; - // reset IsLastPage i_rController.setLastPage( sal_False ); @@ -549,111 +547,133 @@ BOOL AquaSalInfoPrinter::StartJob( const String* i_pFileName, if( ! i_rController.isShowDialogs() ) bShowProgressPanel = sal_False; + // possibly create one job for collated output + sal_Bool bSinglePrintJobs = sal_False; + beans::PropertyValue* pSingleValue = i_rController.getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintCollateAsSingleJobs" ) ) ); + if( pSingleValue ) + { + pSingleValue->Value >>= bSinglePrintJobs; + } + // FIXME: jobStarted() should be done after the print dialog has ended (if there is one) // how do I know when that might be ? i_rController.jobStarted(); - do - { - if( aAccViewState.bNeedRestart ) - { - mnCurPageRangeStart = 0; - mnCurPageRangeCount = 0; - nAllPages = i_rController.getFilteredPageCount(); - } - aAccViewState.bNeedRestart = false; - Size aCurSize( 21000, 29700 ); - if( nAllPages > 0 ) + int nCopies = i_rController.getPrinter()->GetCopyCount(); + int nJobs = 1; + if( bSinglePrintJobs ) + { + nJobs = nCopies; + nCopies = 1; + } + + for( int nCurJob = 0; nCurJob < nJobs; nCurJob++ ) + { + aAccViewState.bNeedRestart = true; + do { - mnCurPageRangeCount = 1; - aCurSize = getPageSize( i_rController, mnCurPageRangeStart ); - Size aNextSize( aCurSize ); + if( aAccViewState.bNeedRestart ) + { + mnCurPageRangeStart = 0; + mnCurPageRangeCount = 0; + nAllPages = i_rController.getFilteredPageCount(); + } - // print pages up to a different size - while( mnCurPageRangeCount + mnCurPageRangeStart < nAllPages ) + aAccViewState.bNeedRestart = false; + + Size aCurSize( 21000, 29700 ); + if( nAllPages > 0 ) { - aNextSize = getPageSize( i_rController, mnCurPageRangeStart + mnCurPageRangeCount ); - if( aCurSize == aNextSize // same page size - || - (aCurSize.Width() == aNextSize.Height() && aCurSize.Height() == aNextSize.Width()) // same size, but different orientation - ) + mnCurPageRangeCount = 1; + aCurSize = getPageSize( i_rController, mnCurPageRangeStart ); + Size aNextSize( aCurSize ); + + // print pages up to a different size + while( mnCurPageRangeCount + mnCurPageRangeStart < nAllPages ) { - mnCurPageRangeCount++; + aNextSize = getPageSize( i_rController, mnCurPageRangeStart + mnCurPageRangeCount ); + if( aCurSize == aNextSize // same page size + || + (aCurSize.Width() == aNextSize.Height() && aCurSize.Height() == aNextSize.Width()) // same size, but different orientation + ) + { + mnCurPageRangeCount++; + } + else + break; } - else - break; } - } - else - mnCurPageRangeCount = 0; - - // now for the current run - mnStartPageOffsetX = mnStartPageOffsetY = 0; - // setup the paper size and orientation - // do this on our associated Printer object, since that is - // out interface to the applications which occasionally rely on the paper - // information (e.g. brochure printing scales to the found paper size) - // also SetPaperSizeUser has the advantage that we can share a - // platform independent paper matching algorithm - boost::shared_ptr<Printer> pPrinter( i_rController.getPrinter() ); - pPrinter->SetMapMode( MapMode( MAP_100TH_MM ) ); - pPrinter->SetPaperSizeUser( aCurSize, true ); - - // create view - NSView* pPrintView = [[AquaPrintView alloc] initWithController: &i_rController withInfoPrinter: this]; - - NSMutableDictionary* pPrintDict = [mpPrintInfo dictionary]; - - // set filename - if( i_pFileName ) - { - [mpPrintInfo setJobDisposition: NSPrintSaveJob]; - NSString* pPath = CreateNSString( *i_pFileName ); - [pPrintDict setObject: pPath forKey: NSPrintSavePath]; - [pPath release]; - } + else + mnCurPageRangeCount = 0; + + // now for the current run + mnStartPageOffsetX = mnStartPageOffsetY = 0; + // setup the paper size and orientation + // do this on our associated Printer object, since that is + // out interface to the applications which occasionally rely on the paper + // information (e.g. brochure printing scales to the found paper size) + // also SetPaperSizeUser has the advantage that we can share a + // platform independent paper matching algorithm + boost::shared_ptr<Printer> pPrinter( i_rController.getPrinter() ); + pPrinter->SetMapMode( MapMode( MAP_100TH_MM ) ); + pPrinter->SetPaperSizeUser( aCurSize, true ); + + // create view + NSView* pPrintView = [[AquaPrintView alloc] initWithController: &i_rController withInfoPrinter: this]; + + NSMutableDictionary* pPrintDict = [mpPrintInfo dictionary]; + + // set filename + if( i_pFileName ) + { + [mpPrintInfo setJobDisposition: NSPrintSaveJob]; + NSString* pPath = CreateNSString( *i_pFileName ); + [pPrintDict setObject: pPath forKey: NSPrintSavePath]; + [pPath release]; + } - [pPrintDict setObject: [[NSNumber numberWithInt: (int)i_rController.getPrinter()->GetCopyCount()] autorelease] forKey: NSPrintCopies]; - [pPrintDict setObject: [[NSNumber numberWithBool: YES] autorelease] forKey: NSPrintDetailedErrorReporting]; - [pPrintDict setObject: [[NSNumber numberWithInt: 1] autorelease] forKey: NSPrintFirstPage]; - // #i103253# weird: for some reason, autoreleasing the value below like the others above - // leads do a double free malloc error. Why this value should behave differently from all the others - // is a mystery. - [pPrintDict setObject: [NSNumber numberWithInt: mnCurPageRangeCount] forKey: NSPrintLastPage]; + [pPrintDict setObject: [[NSNumber numberWithInt: nCopies] autorelease] forKey: NSPrintCopies]; + [pPrintDict setObject: [[NSNumber numberWithBool: YES] autorelease] forKey: NSPrintDetailedErrorReporting]; + [pPrintDict setObject: [[NSNumber numberWithInt: 1] autorelease] forKey: NSPrintFirstPage]; + // #i103253# weird: for some reason, autoreleasing the value below like the others above + // leads do a double free malloc error. Why this value should behave differently from all the others + // is a mystery. + [pPrintDict setObject: [NSNumber numberWithInt: mnCurPageRangeCount] forKey: NSPrintLastPage]; - // create print operation - NSPrintOperation* pPrintOperation = [NSPrintOperation printOperationWithView: pPrintView printInfo: mpPrintInfo]; + // create print operation + NSPrintOperation* pPrintOperation = [NSPrintOperation printOperationWithView: pPrintView printInfo: mpPrintInfo]; - if( pPrintOperation ) - { - NSObject* pReleaseAfterUse = nil; - bool bShowPanel = (! i_rController.isDirectPrint() && getUseNativeDialog() && i_rController.isShowDialogs() ); - [pPrintOperation setShowsPrintPanel: bShowPanel ? YES : NO ]; - [pPrintOperation setShowsProgressPanel: bShowProgressPanel ? YES : NO]; - - // set job title (since MacOSX 10.5) - if( [pPrintOperation respondsToSelector: @selector(setJobTitle:)] ) - [pPrintOperation performSelector: @selector(setJobTitle:) withObject: [CreateNSString( i_rJobName ) autorelease]]; - - if( bShowPanel && mnCurPageRangeStart == 0 ) // only the first range of pages gets the accesory view - pReleaseAfterUse = [AquaPrintAccessoryView setupPrinterPanel: pPrintOperation withController: &i_rController withState: &aAccViewState]; - - bSuccess = TRUE; - mbJob = true; - pInst->startedPrintJob(); - [pPrintOperation runOperation]; - pInst->endedPrintJob(); - bWasAborted = [[[pPrintOperation printInfo] jobDisposition] compare: NSPrintCancelJob] == NSOrderedSame; - mbJob = false; - if( pReleaseAfterUse ) - [pReleaseAfterUse release]; - } + if( pPrintOperation ) + { + NSObject* pReleaseAfterUse = nil; + bool bShowPanel = (! i_rController.isDirectPrint() && getUseNativeDialog() && i_rController.isShowDialogs() ); + [pPrintOperation setShowsPrintPanel: bShowPanel ? YES : NO ]; + [pPrintOperation setShowsProgressPanel: bShowProgressPanel ? YES : NO]; + + // set job title (since MacOSX 10.5) + if( [pPrintOperation respondsToSelector: @selector(setJobTitle:)] ) + [pPrintOperation performSelector: @selector(setJobTitle:) withObject: [CreateNSString( i_rJobName ) autorelease]]; + + if( bShowPanel && mnCurPageRangeStart == 0 && nCurJob == 0) // only the first range of pages (in the first job) gets the accesory view + pReleaseAfterUse = [AquaPrintAccessoryView setupPrinterPanel: pPrintOperation withController: &i_rController withState: &aAccViewState]; + + bSuccess = TRUE; + mbJob = true; + pInst->startedPrintJob(); + [pPrintOperation runOperation]; + pInst->endedPrintJob(); + bWasAborted = [[[pPrintOperation printInfo] jobDisposition] compare: NSPrintCancelJob] == NSOrderedSame; + mbJob = false; + if( pReleaseAfterUse ) + [pReleaseAfterUse release]; + } - mnCurPageRangeStart += mnCurPageRangeCount; - mnCurPageRangeCount = 1; - } while( aAccViewState.bNeedRestart || mnCurPageRangeStart + mnCurPageRangeCount < nAllPages ); + mnCurPageRangeStart += mnCurPageRangeCount; + mnCurPageRangeCount = 1; + } while( aAccViewState.bNeedRestart || mnCurPageRangeStart + mnCurPageRangeCount < nAllPages ); + } // inform application that it can release its data // this is awkward, but the XRenderable interface has no method for this, diff --git a/vcl/inc/postgraphitestl.h b/vcl/inc/postgraphitestl.h deleted file mode 100644 index 736aa248b7ff..000000000000 --- a/vcl/inc/postgraphitestl.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifdef std_was_redefined_as_stlport -// put things back the way they were -# define std std_was_redefined_as_stlport -# undef _STLP_OUTERMOST_HEADER_ID -// force config to be re-read -# undef _STLP_NOTHROW_INHERENTLY -# undef _STLP_CONFIG_H -# include <stddef.h> -#endif diff --git a/vcl/inc/pregraphitestl.h b/vcl/inc/pregraphitestl.h deleted file mode 100644 index ece0af477113..000000000000 --- a/vcl/inc/pregraphitestl.h +++ /dev/null @@ -1,30 +0,0 @@ -#if defined(GRAPHITEADAPTSTL) && defined(std) -# include <ostream> -# include <istream> -# include <fstream> -# include <iostream> -# include <vector> -# include <algorithm> -# define std_was_redefined_as_stlport std -# undef std -# define _STLP_OUTERMOST_HEADER_ID 0xdeadbeaf -# pragma GCC visibility push(default) -# include _STLP_NATIVE_HEADER(exception_defines.h) -# include _STLP_NATIVE_HEADER(limits) -# include _STLP_NATIVE_HEADER(memory) -# include _STLP_NATIVE_HEADER(exception) -# include _STLP_NATIVE_HEADER(iosfwd) -# include _STLP_NATIVE_HEADER(algorithm) -# include _STLP_NATIVE_HEADER(string) -# include _STLP_NATIVE_HEADER(streambuf) -# include _STLP_NATIVE_HEADER(ios) -# include _STLP_NATIVE_HEADER(locale) -# include _STLP_NATIVE_HEADER(stdexcept) -# include _STLP_NATIVE_HEADER(ostream) -# include _STLP_NATIVE_HEADER(istream) -# include _STLP_NATIVE_HEADER(iostream) -# include _STLP_NATIVE_HEADER(vector) -# pragma GCC visibility pop -#endif -//sil_std resolves to the std that Graphite was built with -namespace sil_std = std; diff --git a/vcl/inc/vcl/graphite_adaptors.hxx b/vcl/inc/vcl/graphite_adaptors.hxx index 0b5f88184ce4..43c2e37a5fb2 100644 --- a/vcl/inc/vcl/graphite_adaptors.hxx +++ b/vcl/inc/vcl/graphite_adaptors.hxx @@ -55,11 +55,11 @@ #include "vcl/dllapi.h" // Libraries -#include "pregraphitestl.h" +#include <tools/preextstl.h> #include <graphite/GrClient.h> #include <graphite/Font.h> #include <graphite/ITextSource.h> -#include "postgraphitestl.h" +#include <tools/postextstl.h> // Module type definitions and forward declarations. // @@ -119,7 +119,7 @@ public: const grutils::GrFeatureParser * features() const { return mpFeatures; }; private: - virtual void UniqueCacheInfo(sil_std::wstring &, bool &, bool &); + virtual void UniqueCacheInfo(ext_std::wstring &, bool &, bool &); FreetypeServerFont& mrFont; FontProperties maFontProperties; diff --git a/vcl/inc/vcl/graphite_features.hxx b/vcl/inc/vcl/graphite_features.hxx index 9f63a029eb5f..47f4c3a01e7f 100644 --- a/vcl/inc/vcl/graphite_features.hxx +++ b/vcl/inc/vcl/graphite_features.hxx @@ -29,11 +29,11 @@ // Parse a string of features specified as ; separated pairs. // e.g. // 1001=1&2002=2&fav1=0 -#include "pregraphitestl.h" +#include <tools/preextstl.h> #include <graphite/GrClient.h> #include <graphite/Font.h> #include <graphite/GrFeature.h> -#include "postgraphitestl.h" +#include <tools/postextstl.h> namespace grutils { diff --git a/vcl/inc/vcl/graphite_layout.hxx b/vcl/inc/vcl/graphite_layout.hxx index b3a3814e9ce6..1fbb11211ca0 100644 --- a/vcl/inc/vcl/graphite_layout.hxx +++ b/vcl/inc/vcl/graphite_layout.hxx @@ -40,13 +40,13 @@ #include <vector> #include <utility> // Libraries -#include "pregraphitestl.h" +#include <tools/preextstl.h> #include <graphite/GrClient.h> #include <graphite/Font.h> #include <graphite/GrConstants.h> #include <graphite/GrAppData.h> #include <graphite/SegmentAux.h> -#include "postgraphitestl.h" +#include <tools/postextstl.h> // Platform #include <vcl/sallayout.hxx> #include <vcl/dllapi.h> diff --git a/vcl/inc/vcl/ppdparser.hxx b/vcl/inc/vcl/ppdparser.hxx index 12e8a16f6264..c7a1e09b81e4 100644 --- a/vcl/inc/vcl/ppdparser.hxx +++ b/vcl/inc/vcl/ppdparser.hxx @@ -221,7 +221,7 @@ public: bool isType42Capable() const { return m_bType42Capable; } ULONG getLanguageLevel() const { return m_nLanguageLevel; } - const String& getDefaultPaperDimension() const; + String getDefaultPaperDimension() const; void getDefaultPaperDimension( int& rWidth, int& rHeight ) const { getPaperDimension( getDefaultPaperDimension(), rWidth, rHeight ); } bool getPaperDimension( const String& rPaperName, @@ -230,12 +230,12 @@ public: // returns false if paper not found int getPaperDimensions() const { return m_pPaperDimensions ? m_pPaperDimensions->countValues() : 0; } - const String& getPaperDimension( int ) const; - const String& getPaperDimensionCommand( int ) const; - const String& getPaperDimensionCommand( const String & ) const; + String getPaperDimension( int ) const; + String getPaperDimensionCommand( int ) const; + String getPaperDimensionCommand( const String & ) const; // match the best paper for width and height - const String& matchPaper( int nWidth, int nHeight ) const; + String matchPaper( int nWidth, int nHeight ) const; bool getMargins( const String& rPaperName, int &rLeft, int& rRight, @@ -245,27 +245,27 @@ public: // values int pt - const String& getDefaultInputSlot() const; + String getDefaultInputSlot() const; int getInputSlots() const { return m_pInputSlots ? m_pInputSlots->countValues() : 0; } - const String& getSlot( int ) const; - const String& getSlotCommand( int ) const; - const String& getSlotCommand( const String& ) const; + String getSlot( int ) const; + String getSlotCommand( int ) const; + String getSlotCommand( const String& ) const; void getDefaultResolution( int& rXRes, int& rYRes ) const; int getResolutions() const; void getResolution( int, int& rXRes, int& rYRes ) const; - const String& getResolutionCommand( int nXRes, int nYRes ) const; + String getResolutionCommand( int nXRes, int nYRes ) const; // values in dpi void getResolutionFromString( const String&, int&, int& ) const; // helper function - const String& getDefaultDuplexType() const; + String getDefaultDuplexType() const; int getDuplexTypes() const { return m_pDuplexTypes ? m_pDuplexTypes->countValues() : 0; } - const String& getDuplex( int ) const; - const String& getDuplexCommand( int ) const; - const String& getDuplexCommand( const String& ) const; + String getDuplex( int ) const; + String getDuplexCommand( int ) const; + String getDuplexCommand( const String& ) const; int getFonts() const { return m_pFontList ? m_pFontList->countValues() : 0; } @@ -275,7 +275,7 @@ public: void getFontAttributes( const String&, String& rEncoding, String& rCharset ) const; - const String& getFont( int ) const; + String getFont( int ) const; rtl::OUString translateKey( const rtl::OUString& i_rKey, diff --git a/vcl/inc/vcl/prndlg.hxx b/vcl/inc/vcl/prndlg.hxx index bec612b65593..fdaf06c9854e 100644 --- a/vcl/inc/vcl/prndlg.hxx +++ b/vcl/inc/vcl/prndlg.hxx @@ -55,9 +55,12 @@ namespace vcl { GDIMetaFile maMtf; Size maOrigSize; + Size maPreviewSize; VirtualDevice maPageVDev; rtl::OUString maReplacementString; rtl::OUString maToolTipString; + + bool useHCColorReplacement() const; public: PrintPreviewWindow( Window* pParent, const ResId& ); virtual ~PrintPreviewWindow(); @@ -293,6 +296,7 @@ namespace vcl bool isPrintToFile(); int getCopyCount(); bool isCollate(); + bool isSingleJobs(); void previewForward(); void previewBackward(); @@ -321,6 +325,7 @@ namespace vcl bool isCanceled() const { return mbCanceled; } void setProgress( int i_nCurrent, int i_nMax = -1 ); void tick(); + void reset(); virtual void Paint( const Rectangle& ); }; diff --git a/vcl/inc/vcl/vclevent.hxx b/vcl/inc/vcl/vclevent.hxx index 21fbe32f0440..8ccb880fce34 100644 --- a/vcl/inc/vcl/vclevent.hxx +++ b/vcl/inc/vcl/vclevent.hxx @@ -192,6 +192,7 @@ namespace com { namespace sun { namespace star { #define VCLEVENT_TOOLBOX_BUTTONSTATECHANGED 1223 // pData = itempos #define VCLEVENT_TABLECELL_NAMECHANGED 1224 // pData = struct(Entry, Column, oldText) +#define VCLEVENT_TABLEROW_SELECT 1225 class VCL_DLLPUBLIC VclSimpleEvent { diff --git a/vcl/source/app/dbggui.cxx b/vcl/source/app/dbggui.cxx index b22a7d21f357..dd9a5b4a15ee 100644 --- a/vcl/source/app/dbggui.cxx +++ b/vcl/source/app/dbggui.cxx @@ -1783,8 +1783,6 @@ void DbgDialogTest( Window* pWindow ) } // ======================================================================= -void DbgPrintShell( const char* pLine ); - #ifndef WNT #define USE_VCL_MSGBOX #define COPY_BUTTON_ID 25 @@ -1963,27 +1961,6 @@ void DbgPrintWindow( const char* pLine ) bIn = FALSE; } -// ----------------------------------------------------------------------- - -void DbgPrintShell( const char* pLine ) -{ -#if defined( WNT ) - // TODO: Shouldn't this be a IsDebuggerPresent()? - if ( GetSystemMetrics( SM_DEBUG ) ) - { - strcpy( aDbgOutBuf, pLine ); - strcat( aDbgOutBuf, "\r\n" ); - OutputDebugString( aDbgOutBuf ); - return; - } - - DbgPrintWindow( pLine ); -#endif -#ifdef UNX - fprintf( stderr, "%s\n", pLine ); -#endif -} - // ======================================================================= #ifdef WNT @@ -1996,7 +1973,6 @@ void DbgGUIInit() { DbgSetPrintMsgBox( DbgPrintMsgBox ); DbgSetPrintWindow( DbgPrintWindow ); - DbgSetPrintShell( DbgPrintShell ); #ifdef WNT DbgSetTestSolarMutex( ImplDbgTestSolarMutex ); #endif @@ -2008,7 +1984,6 @@ void DbgGUIDeInit() { DbgSetPrintMsgBox( NULL ); DbgSetPrintWindow( NULL ); - DbgSetPrintShell( NULL ); #ifdef WNT DbgSetTestSolarMutex( NULL ); #endif diff --git a/vcl/source/gdi/outdev3.cxx b/vcl/source/gdi/outdev3.cxx index e13ae6cbe64a..630e58a1f2bf 100644 --- a/vcl/source/gdi/outdev3.cxx +++ b/vcl/source/gdi/outdev3.cxx @@ -2091,11 +2091,14 @@ ImplDevFontListData* ImplDevFontList::FindDefaultFont() const ImplDevFontList* ImplDevFontList::Clone( bool bScalable, bool bEmbeddable ) const { ImplDevFontList* pClonedList = new ImplDevFontList; - pClonedList->mbMatchData = mbMatchData; +// pClonedList->mbMatchData = mbMatchData; pClonedList->mbMapNames = mbMapNames; pClonedList->mpPreMatchHook = mpPreMatchHook; pClonedList->mpFallbackHook = mpFallbackHook; + // TODO: clone the config-font attributes too? + pClonedList->mbMatchData = false; + DevFontList::const_iterator it = maDevFontList.begin(); for(; it != maDevFontList.end(); ++it ) { diff --git a/vcl/source/gdi/print3.cxx b/vcl/source/gdi/print3.cxx index de7cd2e139da..191f8f26dc75 100644 --- a/vcl/source/gdi/print3.cxx +++ b/vcl/source/gdi/print3.cxx @@ -36,6 +36,7 @@ #include "vcl/svids.hrc" #include "vcl/metaact.hxx" #include "vcl/msgbox.hxx" +#include "vcl/configsettings.hxx" #include "tools/urlobj.hxx" @@ -171,13 +172,15 @@ public: // set by user through printer config dialog // if set, pages are centered and trimmed onto the fixed page Size maFixedPageSize; + sal_Int32 mnDefaultPaperBin; ImplPrinterControllerData() : mbFirstPage( sal_True ), mbLastPage( sal_False ), mbReversePageOrder( sal_False ), meJobState( view::PrintableState_JOB_STARTED ), - mpProgress( NULL ) + mpProgress( NULL ), + mnDefaultPaperBin( -1 ) {} ~ImplPrinterControllerData() { delete mpProgress; } @@ -327,9 +330,25 @@ void Printer::ImplPrintJob( const boost::shared_ptr<PrinterController>& i_pContr // setup printer // if no specific printer is already set, create one + + // #i108686# + // in case of a UI (platform independent or system dialog) print job, make the printer persistent over jobs + // however if no printer was already set by the print job's originator, + // and this is an API job, then use the system default location (because + // this is the only sensible default available if the user has no means of changing + // the destination if( ! pController->getPrinter() ) { - boost::shared_ptr<Printer> pPrinter( new Printer( i_rInitSetup.GetPrinterName() ) ); + rtl::OUString aPrinterName( i_rInitSetup.GetPrinterName() ); + if( ! aPrinterName.getLength() && pController->isShowDialogs() && ! pController->isDirectPrint() ) + { + // get printer name from configuration + SettingsConfigItem* pItem = SettingsConfigItem::get(); + aPrinterName = pItem->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ), + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LastPrinterUsed" ) ) ); + } + + boost::shared_ptr<Printer> pPrinter( new Printer( aPrinterName ) ); pController->setPrinter( pPrinter ); } @@ -440,7 +459,12 @@ void Printer::ImplPrintJob( const boost::shared_ptr<PrinterController>& i_pContr return; } pController->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LocalFileName" ) ), - makeAny( aFile ) ); + makeAny( aFile ) ); + } + else if( aDlg.isSingleJobs() ) + { + pController->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintCollateAsSingleJobs" ) ), + makeAny( sal_True ) ); } } catch( std::bad_alloc& ) @@ -501,6 +525,13 @@ bool Printer::StartJob( const rtl::OUString& i_rJobName, boost::shared_ptr<vcl:: if ( !mpPrinter ) return FALSE; + sal_Bool bSinglePrintJobs = sal_False; + beans::PropertyValue* pSingleValue = i_pController->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintCollateAsSingleJobs" ) ) ); + if( pSingleValue ) + { + pSingleValue->Value >>= bSinglePrintJobs; + } + // remark: currently it is still possible to use EnablePrintFile and // SetPrintFileName to redirect printout into file // it can be argued that those methods should be removed in favor @@ -514,6 +545,7 @@ bool Printer::StartJob( const rtl::OUString& i_rJobName, boost::shared_ptr<vcl:: { mbPrintFile = TRUE; maPrintFile = aFile; + bSinglePrintJobs = sal_False; } } @@ -561,49 +593,90 @@ bool Printer::StartJob( const rtl::OUString& i_rJobName, boost::shared_ptr<vcl:: i_pController->setJobState( view::PrintableState_JOB_STARTED ); i_pController->jobStarted(); - if( mpPrinter->StartJob( pPrintFile, - i_rJobName, - Application::GetDisplayName(), - nCopies, - bCollateCopy, - i_pController->isDirectPrint(), - maJobSetup.ImplGetConstData() ) ) + int nJobs = 1; + int nRepeatCount = bUserCopy ? mnCopyCount : 1; + if( bSinglePrintJobs ) { - mbJobActive = TRUE; - i_pController->createProgressDialog(); - int nPages = i_pController->getFilteredPageCount(); - int nRepeatCount = bUserCopy ? mnCopyCount : 1; - for( int nIteration = 0; nIteration < nRepeatCount; nIteration++ ) + nJobs = mnCopyCount; + nCopies = 1; + nRepeatCount = 1; + } + + for( int nJobIteration = 0; nJobIteration < nJobs; nJobIteration++ ) + { + bool bError = false; + if( mpPrinter->StartJob( pPrintFile, + i_rJobName, + Application::GetDisplayName(), + nCopies, + bCollateCopy, + i_pController->isDirectPrint(), + maJobSetup.ImplGetConstData() ) ) { - for( int nPage = 0; nPage < nPages; nPage++ ) + mbJobActive = TRUE; + i_pController->createProgressDialog(); + int nPages = i_pController->getFilteredPageCount(); + for( int nIteration = 0; nIteration < nRepeatCount; nIteration++ ) { - if( nPage == nPages-1 && nIteration == nRepeatCount-1 ) - i_pController->setLastPage( sal_True ); - i_pController->printFilteredPage( nPage ); + for( int nPage = 0; nPage < nPages; nPage++ ) + { + if( nPage == nPages-1 && nIteration == nRepeatCount-1 && nJobIteration == nJobs-1 ) + i_pController->setLastPage( sal_True ); + i_pController->printFilteredPage( nPage ); + } + // FIXME: duplex ? + } + EndJob(); + + if( nJobIteration < nJobs-1 ) + { + mpPrinter = pSVData->mpDefInst->CreatePrinter( mpInfoPrinter ); + + if ( mpPrinter ) + { + maJobName = i_rJobName; + mnCurPage = 1; + mnCurPrintPage = 1; + mbPrinting = TRUE; + } + else + bError = true; } - // FIXME: duplex ? } - EndJob(); + else + bError = true; - if( i_pController->getJobState() == view::PrintableState_JOB_STARTED ) - i_pController->setJobState( view::PrintableState_JOB_SPOOLED ); + if( bError ) + { + mnError = ImplSalPrinterErrorCodeToVCL( mpPrinter->GetErrorCode() ); + if ( !mnError ) + mnError = PRINTER_GENERALERROR; + i_pController->setJobState( mnError == PRINTER_ABORT + ? view::PrintableState_JOB_ABORTED + : view::PrintableState_JOB_FAILED ); + if( mpPrinter ) + pSVData->mpDefInst->DestroyPrinter( mpPrinter ); + mnCurPage = 0; + mnCurPrintPage = 0; + mbPrinting = FALSE; + mpPrinter = NULL; + + return false; + } } - else - { - mnError = ImplSalPrinterErrorCodeToVCL( mpPrinter->GetErrorCode() ); - if ( !mnError ) - mnError = PRINTER_GENERALERROR; - i_pController->setJobState( mnError == PRINTER_ABORT - ? view::PrintableState_JOB_ABORTED - : view::PrintableState_JOB_FAILED ); - pSVData->mpDefInst->DestroyPrinter( mpPrinter ); - mnCurPage = 0; - mnCurPrintPage = 0; - mbPrinting = FALSE; - mpPrinter = NULL; - return false; - } + if( i_pController->getJobState() == view::PrintableState_JOB_STARTED ) + i_pController->setJobState( view::PrintableState_JOB_SPOOLED ); + } + + // make last used printer persistent for UI jobs + if( i_pController->isShowDialogs() && ! i_pController->isDirectPrint() ) + { + SettingsConfigItem* pItem = SettingsConfigItem::get(); + pItem->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ), + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LastPrinterUsed" ) ), + GetName() + ); } return true; @@ -634,6 +707,7 @@ void PrinterController::setPrinter( const boost::shared_ptr<Printer>& i_rPrinter mpImplData->mpPrinter = i_rPrinter; setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Name" ) ), makeAny( rtl::OUString( i_rPrinter->GetName() ) ) ); + mpImplData->mnDefaultPaperBin = mpImplData->mpPrinter->GetPaperBin(); } bool PrinterController::setupPrinter( Window* i_pParent ) @@ -668,27 +742,55 @@ PrinterController::PageSize vcl::ImplPrinterControllerData::modifyJobSetup( cons { PrinterController::PageSize aPageSize; aPageSize.aSize = mpPrinter->GetPaperSize(); + awt::Size aSetSize, aIsSize; + sal_Int32 nPaperBin = mnDefaultPaperBin; for( sal_Int32 nProperty = 0, nPropertyCount = i_rProps.getLength(); nProperty < nPropertyCount; ++nProperty ) { - if( i_rProps[ nProperty ].Name.equalsAscii( "PageSize" ) ) + if( i_rProps[ nProperty ].Name.equalsAscii( "PreferredPageSize" ) ) { - awt::Size aSize; - i_rProps[ nProperty].Value >>= aSize; - aPageSize.aSize.Width() = aSize.Width; - aPageSize.aSize.Height() = aSize.Height; - - Size aCurSize( mpPrinter->GetPaperSize() ); - Size aRealPaperSize( getRealPaperSize( aPageSize.aSize ) ); - if( aRealPaperSize != aCurSize ) - mpPrinter->SetPaperSizeUser( aRealPaperSize, ! isFixedPageSize() ); + i_rProps[ nProperty ].Value >>= aSetSize; } - if( i_rProps[ nProperty ].Name.equalsAscii( "PageIncludesNonprintableArea" ) ) + else if( i_rProps[ nProperty ].Name.equalsAscii( "PageSize" ) ) + { + i_rProps[ nProperty ].Value >>= aIsSize; + } + else if( i_rProps[ nProperty ].Name.equalsAscii( "PageIncludesNonprintableArea" ) ) { sal_Bool bVal = sal_False; - i_rProps[ nProperty].Value >>= bVal; + i_rProps[ nProperty ].Value >>= bVal; aPageSize.bFullPaper = static_cast<bool>(bVal); } + else if( i_rProps[ nProperty ].Name.equalsAscii( "PrinterPaperTray" ) ) + { + sal_Int32 nBin = -1; + i_rProps[ nProperty ].Value >>= nBin; + if( nBin >= 0 && nBin < mpPrinter->GetPaperBinCount() ) + nPaperBin = nBin; + } + } + + Size aCurSize( mpPrinter->GetPaperSize() ); + if( aSetSize.Width && aSetSize.Height ) + { + Size aSetPaperSize( aSetSize.Width, aSetSize.Height ); + Size aRealPaperSize( getRealPaperSize( aSetPaperSize ) ); + if( aRealPaperSize != aCurSize ) + aIsSize = aSetSize; } + + if( aIsSize.Width && aIsSize.Height ) + { + aPageSize.aSize.Width() = aIsSize.Width; + aPageSize.aSize.Height() = aIsSize.Height; + + Size aRealPaperSize( getRealPaperSize( aPageSize.aSize ) ); + if( aRealPaperSize != aCurSize ) + mpPrinter->SetPaperSizeUser( aRealPaperSize, ! isFixedPageSize() ); + } + + if( nPaperBin != -1 && nPaperBin != mpPrinter->GetPaperBin() ) + mpPrinter->SetPaperBin( nPaperBin ); + return aPageSize; } @@ -1393,6 +1495,8 @@ void PrinterController::createProgressDialog() mpImplData->mpProgress->Show(); } } + else + mpImplData->mpProgress->reset(); } void PrinterController::setMultipage( const MultiPageSetup& i_rMPS ) diff --git a/vcl/source/glyphs/graphite_adaptors.cxx b/vcl/source/glyphs/graphite_adaptors.cxx index 4afced765612..f66f5b48e39e 100644 --- a/vcl/source/glyphs/graphite_adaptors.cxx +++ b/vcl/source/glyphs/graphite_adaptors.cxx @@ -168,7 +168,7 @@ GraphiteFontAdaptor::~GraphiteFontAdaptor() throw() mpFeatures = NULL; } -void GraphiteFontAdaptor::UniqueCacheInfo(sil_std::wstring & face_name_out, bool & bold_out, bool & italic_out) +void GraphiteFontAdaptor::UniqueCacheInfo(ext_std::wstring & face_name_out, bool & bold_out, bool & italic_out) { face_name_out = maFontProperties.szFaceName; bold_out = maFontProperties.fBold; diff --git a/vcl/source/glyphs/graphite_cache.cxx b/vcl/source/glyphs/graphite_cache.cxx index 713f3c1ed088..64bbb0a38d60 100644 --- a/vcl/source/glyphs/graphite_cache.cxx +++ b/vcl/source/glyphs/graphite_cache.cxx @@ -36,10 +36,10 @@ #include <tools/debug.hxx> #include <vcl/sallayout.hxx> -#include "pregraphitestl.h" +#include <tools/preextstl.h> #include <graphite/GrClient.h> #include <graphite/Segment.h> -#include "postgraphitestl.h" +#include <tools/postextstl.h> #include <rtl/ustring.hxx> #include <vcl/graphite_layout.hxx> diff --git a/vcl/source/glyphs/graphite_features.cxx b/vcl/source/glyphs/graphite_features.cxx index bae96642da30..1cb25306c4ee 100644 --- a/vcl/source/glyphs/graphite_features.cxx +++ b/vcl/source/glyphs/graphite_features.cxx @@ -88,7 +88,7 @@ GrFeatureParser::GrFeatureParser(gr::Font & font, const std::string features, co gr::isocode aLang = maLang; for (size_t i = pos; i < nFeatEnd; i++) aLang.rgch[i-pos] = features[i]; - sil_std::pair<gr::LanguageIterator,gr::LanguageIterator> aSupported + ext_std::pair<gr::LanguageIterator,gr::LanguageIterator> aSupported = font.getSupportedLanguages(); gr::LanguageIterator iL = aSupported.first; while (iL != aSupported.second) @@ -139,7 +139,7 @@ void GrFeatureParser::setLang(gr::Font & font, const std::string & lang) if (lang[i] == '-') break; aLang.rgch[i] = lang[i]; } - sil_std::pair<gr::LanguageIterator,gr::LanguageIterator> aSupported + ext_std::pair<gr::LanguageIterator,gr::LanguageIterator> aSupported = font.getSupportedLanguages(); gr::LanguageIterator iL = aSupported.first; while (iL != aSupported.second) @@ -186,7 +186,7 @@ bool GrFeatureParser::isValid(gr::Font & font, gr::FeatureSetting & setting) { return false; } - sil_std::pair< gr::FeatureSettingIterator, gr::FeatureSettingIterator > + ext_std::pair< gr::FeatureSettingIterator, gr::FeatureSettingIterator > validValues = font.getFeatureSettings(i); gr::FeatureSettingIterator j = validValues.first; while (j != validValues.second) diff --git a/vcl/source/glyphs/graphite_layout.cxx b/vcl/source/glyphs/graphite_layout.cxx index 25ea77dd07a3..6e75d1fde868 100644 --- a/vcl/source/glyphs/graphite_layout.cxx +++ b/vcl/source/glyphs/graphite_layout.cxx @@ -63,13 +63,13 @@ #include <unicode/uscript.h> // Graphite Libraries (must be after vcl headers on windows) -#include "pregraphitestl.h" +#include <tools/preextstl.h> #include <graphite/GrClient.h> #include <graphite/Font.h> #include <graphite/ITextSource.h> #include <graphite/Segment.h> #include <graphite/SegmentPainter.h> -#include "postgraphitestl.h" +#include <tools/postextstl.h> #include <vcl/graphite_layout.hxx> #include <vcl/graphite_features.hxx> @@ -104,8 +104,8 @@ FILE * grLog() namespace { - typedef sil_std::pair<gr::GlyphIterator, gr::GlyphIterator> glyph_range_t; - typedef sil_std::pair<gr::GlyphSetIterator, gr::GlyphSetIterator> glyph_set_range_t; + typedef ext_std::pair<gr::GlyphIterator, gr::GlyphIterator> glyph_range_t; + typedef ext_std::pair<gr::GlyphSetIterator, gr::GlyphSetIterator> glyph_set_range_t; inline long round(const float n) { return long(n + (n < 0 ? -0.5 : 0.5)); @@ -170,7 +170,7 @@ GraphiteLayout::Glyphs::fill_from(gr::Segment & rSegment, ImplLayoutArgs &rArgs, bool bRtl, long &rWidth, float fScaling, std::vector<int> & rChar2Base, std::vector<int> & rGlyph2Char, std::vector<int> & rCharDxs) { // Create a glyph item for each of the glyph and append it to the base class glyph list. - typedef sil_std::pair< gr::GlyphSetIterator, gr::GlyphSetIterator > GrGlyphSet; + typedef ext_std::pair< gr::GlyphSetIterator, gr::GlyphSetIterator > GrGlyphSet; int nChar = rArgs.mnEndCharPos - rArgs.mnMinCharPos; glyph_range_t iGlyphs = rSegment.glyphs(); int nGlyphs = iGlyphs.second - iGlyphs.first; @@ -585,7 +585,7 @@ public: sal_Int32 hashCode(const grutils::GrFeatureParser * mpFeatures) { // is this sufficient? - sil_std::wstring aFace; + ext_std::wstring aFace; bool bBold; bool bItalic; UniqueCacheInfo(aFace, bBold, bItalic); diff --git a/vcl/source/glyphs/graphite_textsrc.cxx b/vcl/source/glyphs/graphite_textsrc.cxx index d7547662e065..5764ba9454c9 100644 --- a/vcl/source/glyphs/graphite_textsrc.cxx +++ b/vcl/source/glyphs/graphite_textsrc.cxx @@ -135,16 +135,16 @@ gr::isocode TextSourceAdaptor::getLanguage(gr::toffset) return unknown; } -sil_std::pair<gr::toffset, gr::toffset> TextSourceAdaptor::propertyRange(gr::toffset nCharIdx) +ext_std::pair<gr::toffset, gr::toffset> TextSourceAdaptor::propertyRange(gr::toffset nCharIdx) { if (nCharIdx < unsigned(maLayoutArgs.mnMinCharPos)) - return sil_std::make_pair(0, maLayoutArgs.mnMinCharPos); + return ext_std::make_pair(0, maLayoutArgs.mnMinCharPos); if (nCharIdx < mnEnd) - return sil_std::make_pair(maLayoutArgs.mnMinCharPos, mnEnd); + return ext_std::make_pair(maLayoutArgs.mnMinCharPos, mnEnd); - return sil_std::make_pair(mnEnd, maLayoutArgs.mnLength); + return ext_std::make_pair(mnEnd, maLayoutArgs.mnLength); } size_t TextSourceAdaptor::getFontFeatures(gr::toffset, gr::FeatureSetting * settings) @@ -156,7 +156,7 @@ size_t TextSourceAdaptor::getFontFeatures(gr::toffset, gr::FeatureSetting * sett bool TextSourceAdaptor::sameSegment(gr::toffset char_idx1, gr::toffset char_idx2) { - const sil_std::pair<gr::toffset, gr::toffset> + const ext_std::pair<gr::toffset, gr::toffset> range1 = propertyRange(char_idx1), range2 = propertyRange(char_idx2); diff --git a/vcl/source/glyphs/graphite_textsrc.hxx b/vcl/source/glyphs/graphite_textsrc.hxx index 2397d6a5f701..2b9c705a5ea7 100644 --- a/vcl/source/glyphs/graphite_textsrc.hxx +++ b/vcl/source/glyphs/graphite_textsrc.hxx @@ -59,11 +59,11 @@ #include "vcl/dllapi.h" // Libraries -#include "pregraphitestl.h" +#include <tools/preextstl.h> #include <graphite/GrClient.h> #include <graphite/Font.h> #include <graphite/ITextSource.h> -#include "postgraphitestl.h" +#include <tools/postextstl.h> // Module type definitions and forward declarations. // @@ -90,7 +90,7 @@ public: virtual float getVerticalOffset(gr::toffset ich); virtual gr::isocode getLanguage(gr::toffset ich); - virtual sil_std::pair<gr::toffset, gr::toffset> propertyRange(gr::toffset ich); + virtual ext_std::pair<gr::toffset, gr::toffset> propertyRange(gr::toffset ich); virtual size_t getFontFeatures(gr::toffset ich, gr::FeatureSetting * prgfset); virtual bool sameSegment(gr::toffset ich1, gr::toffset ich2); diff --git a/vcl/source/helper/xconnection.cxx b/vcl/source/helper/xconnection.cxx index 19ac9103bf96..caf7ee237d67 100644 --- a/vcl/source/helper/xconnection.cxx +++ b/vcl/source/helper/xconnection.cxx @@ -141,12 +141,16 @@ bool DisplayConnection::dispatchEvent( void* pThis, void* pData, int nBytes ) SolarMutexReleaser aRel; DisplayConnection* This = (DisplayConnection*)pThis; - MutexGuard aGuard( This->m_aMutex ); Sequence< sal_Int8 > aSeq( (sal_Int8*)pData, nBytes ); Any aEvent; aEvent <<= aSeq; - for( ::std::list< Reference< XEventHandler > >::const_iterator it = This->m_aHandlers.begin(); it != This->m_aHandlers.end(); ++it ) + ::std::list< Reference< XEventHandler > > handlers; + { + MutexGuard aGuard( This->m_aMutex ); + handlers = This->m_aHandlers; + } + for( ::std::list< Reference< XEventHandler > >::const_iterator it = handlers.begin(); it != handlers.end(); ++it ) if( (*it)->handleEvent( aEvent ) ) return true; return false; @@ -157,12 +161,16 @@ bool DisplayConnection::dispatchErrorEvent( void* pThis, void* pData, int nBytes SolarMutexReleaser aRel; DisplayConnection* This = (DisplayConnection*)pThis; - MutexGuard aGuard( This->m_aMutex ); Sequence< sal_Int8 > aSeq( (sal_Int8*)pData, nBytes ); Any aEvent; aEvent <<= aSeq; - for( ::std::list< Reference< XEventHandler > >::const_iterator it = This->m_aErrorHandlers.begin(); it != This->m_aErrorHandlers.end(); ++it ) + ::std::list< Reference< XEventHandler > > handlers; + { + MutexGuard aGuard( This->m_aMutex ); + handlers = This->m_aErrorHandlers; + } + for( ::std::list< Reference< XEventHandler > >::const_iterator it = handlers.begin(); it != handlers.end(); ++it ) if( (*it)->handleEvent( aEvent ) ) return true; diff --git a/vcl/source/window/printdlg.cxx b/vcl/source/window/printdlg.cxx index caf5705cbcd9..33e58b51d6d0 100644 --- a/vcl/source/window/printdlg.cxx +++ b/vcl/source/window/printdlg.cxx @@ -42,16 +42,22 @@ #include "vcl/help.hxx" #include "vcl/decoview.hxx" #include "vcl/svapp.hxx" +#include "vcl/unohelp.hxx" #include "unotools/localedatawrapper.hxx" #include "rtl/ustrbuf.hxx" +#include "com/sun/star/lang/XMultiServiceFactory.hpp" +#include "com/sun/star/container/XNameAccess.hpp" +#include "com/sun/star/beans/PropertyValue.hpp" #include "com/sun/star/awt/Size.hpp" using namespace vcl; using namespace com::sun::star; using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::container; using namespace com::sun::star::beans; #define HELPID_PREFIX ".HelpId:vcl:PrintDialog" @@ -66,7 +72,7 @@ PrintDialog::PrintPreviewWindow::PrintPreviewWindow( Window* i_pParent, const Re { SetPaintTransparent( TRUE ); SetBackground(); - if( GetSettings().GetStyleSettings().GetHighContrastMode() ) + if( useHCColorReplacement() ) maPageVDev.SetBackground( GetSettings().GetStyleSettings().GetWindowColor() ); else maPageVDev.SetBackground( Color( COL_WHITE ) ); @@ -76,12 +82,76 @@ PrintDialog::PrintPreviewWindow::~PrintPreviewWindow() { } +bool PrintDialog::PrintPreviewWindow::useHCColorReplacement() const +{ + bool bRet = false; + if( GetSettings().GetStyleSettings().GetHighContrastMode() ) + { + try + { + // get service provider + Reference< XMultiServiceFactory > xSMgr( unohelper::GetMultiServiceFactory() ); + // create configuration hierachical access name + if( xSMgr.is() ) + { + try + { + Reference< XMultiServiceFactory > xConfigProvider( + Reference< XMultiServiceFactory >( + xSMgr->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.configuration.ConfigurationProvider" ))), + UNO_QUERY ) + ); + if( xConfigProvider.is() ) + { + Sequence< Any > aArgs(1); + PropertyValue aVal; + aVal.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" ) ); + aVal.Value <<= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.Common/Accessibility" ) ); + aArgs.getArray()[0] <<= aVal; + Reference< XNameAccess > xConfigAccess( + Reference< XNameAccess >( + xConfigProvider->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.configuration.ConfigurationAccess" )), + aArgs ), + UNO_QUERY ) + ); + if( xConfigAccess.is() ) + { + try + { + sal_Bool bValue = sal_False; + Any aAny = xConfigAccess->getByName( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsForPagePreviews" ) ) ); + if( aAny >>= bValue ) + bRet = bool(bValue); + } + catch( NoSuchElementException& ) + { + } + catch( WrappedTargetException& ) + { + } + } + } + } + catch( Exception& ) + { + } + } + } + catch( WrappedTargetException& ) + { + } + } + return bRet; +} + void PrintDialog::PrintPreviewWindow::DataChanged( const DataChangedEvent& i_rDCEvt ) { // react on settings changed if( i_rDCEvt.GetType() == DATACHANGED_SETTINGS ) { - if( GetSettings().GetStyleSettings().GetHighContrastMode() ) + if( useHCColorReplacement() ) maPageVDev.SetBackground( GetSettings().GetStyleSettings().GetWindowColor() ); else maPageVDev.SetBackground( Color( COL_WHITE ) ); @@ -118,6 +188,23 @@ void PrintDialog::PrintPreviewWindow::Resize() } aScaledSize.Width() = long(aScaledSize.Width()*fScale); aScaledSize.Height() = long(aScaledSize.Height()*fScale); + + maPreviewSize = aScaledSize; + + // #i104784# if we render the page too small then rounding issues result in + // layout artifacts looking really bad. So scale the page unto a device that is not + // full page size but not too small either. This also results in much better visual + // quality of the preview, e.g. when its height approaches the number of text lines + // find a good scaling factor + Size aPreviewMMSize( maPageVDev.PixelToLogic( aScaledSize, MapMode( MAP_100TH_MM ) ) ); + double fZoom = double(maOrigSize.Height())/double(aPreviewMMSize.Height()); + while( fZoom > 10 ) + { + aScaledSize.Width() *= 2; + aScaledSize.Height() *= 2; + fZoom /= 2.0; + } + maPageVDev.SetOutputSizePixel( aScaledSize, FALSE ); } @@ -129,9 +216,14 @@ void PrintDialog::PrintPreviewWindow::Paint( const Rectangle& ) // replacement is active Push(); Rectangle aTextRect( Point( 0, 0 ), aSize ); - Font aFont( GetSettings().GetStyleSettings().GetFieldFont() ); - aFont.SetSize( Size( 0, aSize.Height()/12 ) ); - SetFont( aFont ); + DecorationView aVw( this ); + aVw.DrawFrame( aTextRect, FRAME_DRAW_GROUP ); + aTextRect.Left() += 2; + aTextRect.Top() += 2; + aTextRect.Right() -= 2; + aTextRect.Bottom() -= 2; + Font aFont( GetSettings().GetStyleSettings().GetLabelFont() ); + SetZoomedPointFont( aFont ); DrawText( aTextRect, maReplacementString, TEXT_DRAW_CENTER | TEXT_DRAW_VCENTER | TEXT_DRAW_WORDBREAK | TEXT_DRAW_MULTILINE ); @@ -141,11 +233,11 @@ void PrintDialog::PrintPreviewWindow::Paint( const Rectangle& ) { GDIMetaFile aMtf( maMtf ); - Size aPreviewSize = maPageVDev.GetOutputSizePixel(); - Point aOffset( (aSize.Width() - aPreviewSize.Width()) / 2, - (aSize.Height() - aPreviewSize.Height()) / 2 ); + Point aOffset( (aSize.Width() - maPreviewSize.Width()) / 2, + (aSize.Height() - maPreviewSize.Height()) / 2 ); - const Size aLogicSize( maPageVDev.PixelToLogic( aPreviewSize, MapMode( MAP_100TH_MM ) ) ); + Size aVDevSize( maPageVDev.GetOutputSizePixel() ); + const Size aLogicSize( maPageVDev.PixelToLogic( aVDevSize, MapMode( MAP_100TH_MM ) ) ); Size aOrigSize( maOrigSize ); if( aOrigSize.Width() < 1 ) aOrigSize.Width() = aLogicSize.Width(); @@ -165,11 +257,11 @@ void PrintDialog::PrintPreviewWindow::Paint( const Rectangle& ) SetMapMode( MAP_PIXEL ); maPageVDev.SetMapMode( MAP_PIXEL ); - DrawOutDev( aOffset, aPreviewSize, Point( 0, 0 ), aPreviewSize, maPageVDev ); + DrawOutDev( aOffset, maPreviewSize, Point( 0, 0 ), aVDevSize, maPageVDev ); DecorationView aVw( this ); - aOffset.X() -= 1; aOffset.Y() -=1; aPreviewSize.Width() += 2; aPreviewSize.Height() += 2; - aVw.DrawFrame( Rectangle( aOffset, aPreviewSize ), FRAME_DRAW_GROUP ); + Rectangle aFrame( aOffset + Point( -1, -1 ), Size( maPreviewSize.Width() + 2, maPreviewSize.Height() + 2 ) ); + aVw.DrawFrame( aFrame, FRAME_DRAW_GROUP ); } } @@ -211,9 +303,7 @@ void PrintDialog::PrintPreviewWindow::setPreview( const GDIMetaFile& i_rNewPrevi #endif SetQuickHelpText( aBuf.makeStringAndClear() ); maMtf = i_rNewPreview; - if( GetSettings().GetStyleSettings().GetHighContrastMode() && - GetSettings().GetStyleSettings().GetWindowColor().IsDark() - ) + if( useHCColorReplacement() ) { maMtf.ReplaceColors( Color( COL_BLACK ), Color( COL_WHITE ), 30 ); } @@ -834,6 +924,7 @@ PrintDialog::PrintDialog( Window* i_pParent, const boost::shared_ptr<PrinterCont maNUpPage.maBorderCB.SetClickHdl( LINK( this, PrintDialog, ClickHdl ) ); maOptionsPage.maToFileBox.SetToggleHdl( LINK( this, PrintDialog, ClickHdl ) ); maOptionsPage.maReverseOrderBox.SetToggleHdl( LINK( this, PrintDialog, ClickHdl ) ); + maOptionsPage.maCollateSingleJobsBox.SetToggleHdl( LINK( this, PrintDialog, ClickHdl ) ); maNUpPage.maPagesBtn.SetToggleHdl( LINK( this, PrintDialog, ClickHdl ) ); // setup modify hdl @@ -1027,6 +1118,11 @@ bool PrintDialog::isCollate() return maJobPage.maCopyCountField.GetValue() > 1 ? maJobPage.maCollateBox.IsChecked() : FALSE; } +bool PrintDialog::isSingleJobs() +{ + return maOptionsPage.maCollateSingleJobsBox.IsChecked(); +} + static void setSmartId( Window* i_pWindow, const char* i_pType, sal_Int32 i_nId = -1, const rtl::OUString& i_rPropName = rtl::OUString() ) { rtl::OUStringBuffer aBuf( 256 ); @@ -1049,10 +1145,17 @@ static void setSmartId( Window* i_pWindow, const char* i_pType, sal_Int32 i_nId i_pWindow->SetSmartHelpId( SmartId( aBuf.makeStringAndClear(), HID_PRINTDLG ) ); } -static void setHelpText( Window* i_pWindow, const Sequence< rtl::OUString >& i_rHelpTexts, sal_Int32 i_nIndex ) +static void setHelpText( Window* /*i_pWindow*/, const Sequence< rtl::OUString >& /*i_rHelpTexts*/, sal_Int32 /*i_nIndex*/ ) { + // without a help text set and the correct smartID, + // help texts will be retrieved from the online help system + + // passed help texts for optional UI is used only for native dialogs which currently + // cannot access the same (rather implicit) mechanism + #if 0 if( i_nIndex >= 0 && i_nIndex < i_rHelpTexts.getLength() ) i_pWindow->SetHelpText( i_rHelpTexts.getConstArray()[i_nIndex] ); + #endif } void updateMaxSize( const Size& i_rCheckSize, Size& o_rMaxSize ) @@ -1572,6 +1675,12 @@ void PrintDialog::setupOptionalUI() maJobPage.maLayout.setBorders( nIndex-1, 0, 0, 0, aBorder.Width() ); #endif + // create auto mnemomnics now so they can be calculated in layout + ImplWindowAutoMnemonic( &maJobPage ); + ImplWindowAutoMnemonic( &maNUpPage ); + ImplWindowAutoMnemonic( &maOptionsPage ); + ImplWindowAutoMnemonic( this ); + // calculate job page Size aMaxSize = maJobPage.maLayout.getOptimalSize( WINDOWSIZE_PREFERRED ); // and layout page @@ -1654,6 +1763,7 @@ void PrintDialog::checkControlDependencies() maJobPage.maCollateImage.SetSizePixel( aImgSize ); maJobPage.maCollateImage.SetImage( bHC ? aHCImg : aImg ); maJobPage.maCollateImage.SetModeImage( aHCImg, BMP_COLOR_HIGHCONTRAST ); + maJobPage.maLayout.resize(); // enable setup button only for printers that can be setup bool bHaveSetup = maPController->getPrinter()->HasSupport( SUPPORT_SETUPDIALOG ); @@ -2444,6 +2554,11 @@ void PrintProgressDialog::tick() setProgress( ++mnCur ); } +void PrintProgressDialog::reset() +{ + setProgress( 0 ); +} + void PrintProgressDialog::Paint( const Rectangle& ) { if( maProgressRect.IsEmpty() ) diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx index aadef164282b..ca92d9ed6c5b 100644 --- a/vcl/source/window/window.cxx +++ b/vcl/source/window/window.cxx @@ -8163,7 +8163,7 @@ const XubString& Window::GetHelpText() const { rtl::OUStringBuffer aTxt( 64+mpWindowImpl->maHelpText.Len() ); aTxt.append( mpWindowImpl->maHelpText ); - aTxt.appendAscii( "\n+++++++++++++++\n" ); + aTxt.appendAscii( "\n------------------\n" ); if( bStrHelpId ) aTxt.append( rtl::OUString( aStrHelpId ) ); else diff --git a/vcl/unx/headless/svpinst.cxx b/vcl/unx/headless/svpinst.cxx index 485062bf0617..466b56868900 100644 --- a/vcl/unx/headless/svpinst.cxx +++ b/vcl/unx/headless/svpinst.cxx @@ -55,6 +55,19 @@ extern "C" } } +bool SvpSalInstance::isFrameAlive( const SalFrame* pFrame ) const +{ + for( std::list< SalFrame* >::const_iterator it = m_aFrames.begin(); + it != m_aFrames.end(); ++it ) + { + if( *it == pFrame ) + { + return true; + } + } + return false; +} + SvpSalInstance* SvpSalInstance::s_pDefaultInstance = NULL; SvpSalInstance::SvpSalInstance() @@ -346,12 +359,15 @@ void SvpSalInstance::Yield( bool bWait, bool bHandleAllCurrentEvents ) { for( std::list<SalUserEvent>::const_iterator it = aEvents.begin(); it != aEvents.end(); ++it ) { - it->m_pFrame->CallCallback( it->m_nEvent, it->m_pData ); - if( it->m_nEvent == SALEVENT_RESIZE ) + if ( isFrameAlive( it->m_pFrame ) ) { - // this would be a good time to post a paint - const SvpSalFrame* pSvpFrame = static_cast<const SvpSalFrame*>(it->m_pFrame); - pSvpFrame->PostPaint(); + it->m_pFrame->CallCallback( it->m_nEvent, it->m_pData ); + if( it->m_nEvent == SALEVENT_RESIZE ) + { + // this would be a good time to post a paint + const SvpSalFrame* pSvpFrame = static_cast<const SvpSalFrame*>(it->m_pFrame); + pSvpFrame->PostPaint(); + } } } } diff --git a/vcl/unx/headless/svpinst.hxx b/vcl/unx/headless/svpinst.hxx index d37c1c7e126e..284a2d11cd82 100644 --- a/vcl/unx/headless/svpinst.hxx +++ b/vcl/unx/headless/svpinst.hxx @@ -108,6 +108,9 @@ class SvpSalInstance : public SalInstance std::list< SalUserEvent > m_aUserEvents; std::list< SalFrame* > m_aFrames; + + bool isFrameAlive( const SalFrame* pFrame ) const; + public: static SvpSalInstance* s_pDefaultInstance; diff --git a/vcl/unx/source/printer/ppdparser.cxx b/vcl/unx/source/printer/ppdparser.cxx index 971db860cf42..b2549573d099 100644 --- a/vcl/unx/source/printer/ppdparser.cxx +++ b/vcl/unx/source/printer/ppdparser.cxx @@ -258,7 +258,6 @@ using namespace rtl; std::list< PPDParser* > PPDParser::aAllParsers; std::hash_map< OUString, OUString, OUStringHash >* PPDParser::pAllPPDFiles = NULL; -static String aEmptyString; class PPDDecompressStream { @@ -1284,12 +1283,12 @@ void PPDParser::parseConstraint( const ByteString& rLine ) m_aConstraints.push_back( aConstraint ); } -const String& PPDParser::getDefaultPaperDimension() const +String PPDParser::getDefaultPaperDimension() const { if( m_pDefaultPaperDimension ) return m_pDefaultPaperDimension->m_aOption; - return aEmptyString; + return String(); } bool PPDParser::getMargins( @@ -1356,10 +1355,10 @@ bool PPDParser::getPaperDimension( return true; } -const String& PPDParser::matchPaper( int nWidth, int nHeight ) const +String PPDParser::matchPaper( int nWidth, int nHeight ) const { if( ! m_pPaperDimensions ) - return aEmptyString; + return String(); int nPDim = -1; double PDWidth, PDHeight; @@ -1393,51 +1392,51 @@ const String& PPDParser::matchPaper( int nWidth, int nHeight ) const { // swap portrait/landscape and try again bDontSwap = true; - const String& rRet = matchPaper( nHeight, nWidth ); + String rRet = matchPaper( nHeight, nWidth ); bDontSwap = false; return rRet; } - return nPDim != -1 ? m_pPaperDimensions->getValue( nPDim )->m_aOption : aEmptyString; + return nPDim != -1 ? m_pPaperDimensions->getValue( nPDim )->m_aOption : String(); } -const String& PPDParser::getDefaultInputSlot() const +String PPDParser::getDefaultInputSlot() const { if( m_pDefaultInputSlot ) return m_pDefaultInputSlot->m_aValue; - return aEmptyString; + return String(); } -const String& PPDParser::getSlot( int nSlot ) const +String PPDParser::getSlot( int nSlot ) const { if( ! m_pInputSlots ) - return aEmptyString; + return String(); if( nSlot > 0 && nSlot < m_pInputSlots->countValues() ) return m_pInputSlots->getValue( nSlot )->m_aOption; else if( m_pInputSlots->countValues() > 0 ) return m_pInputSlots->getValue( (ULONG)0 )->m_aOption; - return aEmptyString; + return String(); } -const String& PPDParser::getSlotCommand( int nSlot ) const +String PPDParser::getSlotCommand( int nSlot ) const { if( ! m_pInputSlots ) - return aEmptyString; + return String(); if( nSlot > 0 && nSlot < m_pInputSlots->countValues() ) return m_pInputSlots->getValue( nSlot )->m_aValue; else if( m_pInputSlots->countValues() > 0 ) return m_pInputSlots->getValue( (ULONG)0 )->m_aValue; - return aEmptyString; + return String(); } -const String& PPDParser::getSlotCommand( const String& rSlot ) const +String PPDParser::getSlotCommand( const String& rSlot ) const { if( ! m_pInputSlots ) - return aEmptyString; + return String(); for( int i=0; i < m_pInputSlots->countValues(); i++ ) { @@ -1445,39 +1444,39 @@ const String& PPDParser::getSlotCommand( const String& rSlot ) const if( pValue->m_aOption == rSlot ) return pValue->m_aValue; } - return aEmptyString; + return String(); } -const String& PPDParser::getPaperDimension( int nPaperDimension ) const +String PPDParser::getPaperDimension( int nPaperDimension ) const { if( ! m_pPaperDimensions ) - return aEmptyString; + return String(); if( nPaperDimension > 0 && nPaperDimension < m_pPaperDimensions->countValues() ) return m_pPaperDimensions->getValue( nPaperDimension )->m_aOption; else if( m_pPaperDimensions->countValues() > 0 ) return m_pPaperDimensions->getValue( (ULONG)0 )->m_aOption; - return aEmptyString; + return String(); } -const String& PPDParser::getPaperDimensionCommand( int nPaperDimension ) const +String PPDParser::getPaperDimensionCommand( int nPaperDimension ) const { if( ! m_pPaperDimensions ) - return aEmptyString; + return String(); if( nPaperDimension > 0 && nPaperDimension < m_pPaperDimensions->countValues() ) return m_pPaperDimensions->getValue( nPaperDimension )->m_aValue; else if( m_pPaperDimensions->countValues() > 0 ) return m_pPaperDimensions->getValue( (ULONG)0 )->m_aValue; - return aEmptyString; + return String(); } -const String& PPDParser::getPaperDimensionCommand( const String& rPaperDimension ) const +String PPDParser::getPaperDimensionCommand( const String& rPaperDimension ) const { if( ! m_pPaperDimensions ) - return aEmptyString; + return String(); for( int i=0; i < m_pPaperDimensions->countValues(); i++ ) { @@ -1485,7 +1484,7 @@ const String& PPDParser::getPaperDimensionCommand( const String& rPaperDimension if( pValue->m_aOption == rPaperDimension ) return pValue->m_aValue; } - return aEmptyString; + return String(); } void PPDParser::getResolutionFromString( @@ -1543,13 +1542,13 @@ void PPDParser::getResolution( int nNr, int& rXRes, int& rYRes ) const rXRes, rYRes ); } -const String& PPDParser::getResolutionCommand( int nXRes, int nYRes ) const +String PPDParser::getResolutionCommand( int nXRes, int nYRes ) const { if( ( ! m_pResolutions || m_pResolutions->countValues() == 0 ) && m_pDefaultResolution ) return m_pDefaultResolution->m_aValue; if( ! m_pResolutions ) - return aEmptyString; + return String(); int nX, nY; for( int i = 0; i < m_pResolutions->countValues(); i++ ) @@ -1559,46 +1558,46 @@ const String& PPDParser::getResolutionCommand( int nXRes, int nYRes ) const if( nX == nXRes && nY == nYRes ) return m_pResolutions->getValue( i )->m_aValue; } - return aEmptyString; + return String(); } -const String& PPDParser::getDefaultDuplexType() const +String PPDParser::getDefaultDuplexType() const { if( m_pDefaultDuplexType ) return m_pDefaultDuplexType->m_aValue; - return aEmptyString; + return String(); } -const String& PPDParser::getDuplex( int nDuplex ) const +String PPDParser::getDuplex( int nDuplex ) const { if( ! m_pDuplexTypes ) - return aEmptyString; + return String(); if( nDuplex > 0 && nDuplex < m_pDuplexTypes->countValues() ) return m_pDuplexTypes->getValue( nDuplex )->m_aOption; else if( m_pDuplexTypes->countValues() > 0 ) return m_pDuplexTypes->getValue( (ULONG)0 )->m_aOption; - return aEmptyString; + return String(); } -const String& PPDParser::getDuplexCommand( int nDuplex ) const +String PPDParser::getDuplexCommand( int nDuplex ) const { if( ! m_pDuplexTypes ) - return aEmptyString; + return String(); if( nDuplex > 0 && nDuplex < m_pDuplexTypes->countValues() ) return m_pDuplexTypes->getValue( nDuplex )->m_aValue; else if( m_pDuplexTypes->countValues() > 0 ) return m_pDuplexTypes->getValue( (ULONG)0 )->m_aValue; - return aEmptyString; + return String(); } -const String& PPDParser::getDuplexCommand( const String& rDuplex ) const +String PPDParser::getDuplexCommand( const String& rDuplex ) const { if( ! m_pDuplexTypes ) - return aEmptyString; + return String(); for( int i=0; i < m_pDuplexTypes->countValues(); i++ ) { @@ -1606,7 +1605,7 @@ const String& PPDParser::getDuplexCommand( const String& rDuplex ) const if( pValue->m_aOption == rDuplex ) return pValue->m_aValue; } - return aEmptyString; + return String(); } void PPDParser::getFontAttributes( @@ -1636,14 +1635,14 @@ void PPDParser::getFontAttributes( } } -const String& PPDParser::getFont( int nFont ) const +String PPDParser::getFont( int nFont ) const { if( ! m_pFontList ) - return aEmptyString; + return String(); if( nFont >=0 && nFont < m_pFontList->countValues() ) return m_pFontList->getValue( nFont )->m_aOption; - return aEmptyString; + return String(); } rtl::OUString PPDParser::translateKey( const rtl::OUString& i_rKey, diff --git a/vcl/util/makefile2.pmk b/vcl/util/makefile2.pmk index 56102a256ea3..df9ba1a214d7 100644 --- a/vcl/util/makefile2.pmk +++ b/vcl/util/makefile2.pmk @@ -36,6 +36,6 @@ CFLAGSCXX+=$(OBJCXXFLAGS) #building with stlport, but graphite was not built with stlport .IF "$(USE_SYSTEM_STL)"!="YES" .IF "$(SYSTEM_GRAPHITE)"=="YES" -CDEFS += -DGRAPHITEADAPTSTL +CDEFS += -DADAPT_EXT_STL .ENDIF .ENDIF |