You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openoffice.apache.org by al...@apache.org on 2012/01/17 18:54:06 UTC

svn commit: r1232507 [2/3] - in /incubator/ooo/trunk: ./ main/basegfx/inc/basegfx/polygon/ main/basegfx/source/polygon/ main/canvas/source/vcl/ main/cppcanvas/source/mtfrenderer/ main/cui/source/inc/ main/cui/source/tabpages/ main/drawinglayer/inc/draw...

Modified: incubator/ooo/trunk/main/drawinglayer/source/primitive3d/polygontubeprimitive3d.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/drawinglayer/source/primitive3d/polygontubeprimitive3d.cxx?rev=1232507&r1=1232506&r2=1232507&view=diff
==============================================================================
--- incubator/ooo/trunk/main/drawinglayer/source/primitive3d/polygontubeprimitive3d.cxx (original)
+++ incubator/ooo/trunk/main/drawinglayer/source/primitive3d/polygontubeprimitive3d.cxx Tue Jan 17 17:54:04 2012
@@ -156,6 +156,76 @@ namespace drawinglayer
 				return aLineCapList;
 			}
 
+            Primitive3DSequence getLineCapRoundSegments(
+                sal_uInt32 nSegments, 
+                const attribute::MaterialAttribute3D& rMaterial)
+            {
+                // static data for buffered tube primitives
+                static Primitive3DSequence aLineCapRoundList;
+                static sal_uInt32 nLineCapRoundSegments(0);
+                static attribute::MaterialAttribute3D aLineMaterial;
+
+                // may exclusively change static data, use mutex
+                ::osl::Mutex m_mutex;
+
+                if(nSegments != nLineCapRoundSegments || !(rMaterial == aLineMaterial))
+                {
+                    nLineCapRoundSegments = nSegments;
+                    aLineMaterial = rMaterial;
+                    aLineCapRoundList = Primitive3DSequence();
+                }
+                
+                if(!aLineCapRoundList.hasElements() && nLineCapRoundSegments)
+                {
+                    // calculate new horizontal segments
+                    sal_uInt32 nVerSeg(nSegments / 2);
+
+                    if(nVerSeg < 1)
+                    {
+                        nVerSeg = 1;
+                    }
+
+                    // create half-sphere; upper half of unit sphere
+                    basegfx::B3DPolyPolygon aSphere(
+                        basegfx::tools::createUnitSphereFillPolyPolygon(
+                            nSegments, 
+                            nVerSeg, 
+                            true, 
+                            F_PI2, 0.0, 
+                            0.0, F_2PI));
+                    const sal_uInt32 nCount(aSphere.count());
+
+                    if(nCount)
+                    {
+                        // rotate to have sphere cap orientned to negative X-Axis; do not
+                        // forget to transform normals, too
+                        basegfx::B3DHomMatrix aSphereTrans;
+
+                        aSphereTrans.rotate(0.0, 0.0, F_PI2);
+                        aSphere.transform(aSphereTrans);
+                        aSphere.transformNormals(aSphereTrans);
+
+                        // realloc for primitives and create based on polygon snippets
+                        aLineCapRoundList.realloc(nCount);
+
+                        for(sal_uInt32 a(0); a < nCount; a++)
+                        {
+                            const basegfx::B3DPolygon aPartPolygon(aSphere.getB3DPolygon(a));
+                            const basegfx::B3DPolyPolygon aPartPolyPolygon(aPartPolygon);
+
+                            // need to create one primitive per Polygon since the primitive
+                            // is for planar PolyPolygons which is definitely not the case here
+                            aLineCapRoundList[a] = new PolyPolygonMaterialPrimitive3D(
+                                aPartPolyPolygon, 
+                                rMaterial, 
+                                false);
+                        }
+                    }
+                }
+                
+                return aLineCapRoundList;
+            }
+
 			Primitive3DSequence getLineJoinSegments(
 				sal_uInt32 nSegments, 
 				const attribute::MaterialAttribute3D& rMaterial, 
@@ -173,7 +243,7 @@ namespace drawinglayer
 					if(basegfx::B2DLINEJOIN_ROUND == aLineJoin)
 					{
 						// calculate new horizontal segments
-						const sal_uInt32 nHorSeg((sal_uInt32)((fAngle / F_2PI) * (double)nSegments));
+						const sal_uInt32 nHorSeg(basegfx::fround((fAngle / F_2PI) * (double)nSegments));
 
 						if(nHorSeg)
 						{
@@ -403,100 +473,188 @@ using namespace com::sun::star;
 
 namespace drawinglayer
 {
-	namespace primitive3d
-	{
-		Primitive3DSequence PolygonTubePrimitive3D::impCreate3DDecomposition(const geometry::ViewInformation3D& /*rViewInformation*/) const
-		{
-			const sal_uInt32 nPointCount(getB3DPolygon().count());
-			std::vector< BasePrimitive3D* > aResultVector;
-
-			if(0L != nPointCount)
-			{
-				if(basegfx::fTools::more(getRadius(), 0.0))
-				{
-					const attribute::MaterialAttribute3D aMaterial(getBColor());
-					static sal_uInt32 nSegments(8L); // default for 3d line segments, for more quality just raise this value (in even steps)
-					const bool bClosed(getB3DPolygon().isClosed());
-					const bool bNoLineJoin(basegfx::B2DLINEJOIN_NONE == getLineJoin());
-					const sal_uInt32 nLoopCount(bClosed ? nPointCount : nPointCount - 1L);
-					basegfx::B3DPoint aLast(getB3DPolygon().getB3DPoint(nPointCount - 1L));
-					basegfx::B3DPoint aCurr(getB3DPolygon().getB3DPoint(0L));
-
-					for(sal_uInt32 a(0L); a < nLoopCount; a++)
-					{
-						// get next data
-						const basegfx::B3DPoint aNext(getB3DPolygon().getB3DPoint((a + 1L) % nPointCount));
-						const basegfx::B3DVector aForw(aNext - aCurr);
-						const double fForwLen(aForw.getLength());
-
-						if(basegfx::fTools::more(fForwLen, 0.0))
-						{
-							// get rotation from vector, this describes rotation from (1, 0, 0) to aForw
-							basegfx::B3DHomMatrix aRotVector(getRotationFromVector(aForw));
-
-							// create default transformation with scale and rotate
-							basegfx::B3DHomMatrix aVectorTrans;
-							aVectorTrans.scale(fForwLen, getRadius(), getRadius());
-							aVectorTrans *= aRotVector;
-							aVectorTrans.translate(aCurr.getX(), aCurr.getY(), aCurr.getZ());
-
-							if(bNoLineJoin || (!bClosed && !a))
-							{
-								// line start edge, build transformed primitiveVector3D
-								TransformPrimitive3D* pNewTransformedA = new TransformPrimitive3D(aVectorTrans, getLineCapSegments(nSegments, aMaterial));
-								aResultVector.push_back(pNewTransformedA);
-							}
-							else
-							{
-								const basegfx::B3DVector aBack(aCurr - aLast);
-								const double fCross(basegfx::cross(aBack, aForw).getLength());
-
-								if(!basegfx::fTools::equalZero(fCross))
-								{
-									// line connect non-parallel, aBack, aForw, use getLineJoin()
-									const double fAngle(acos(aBack.scalar(aForw) / (fForwLen * aBack.getLength()))); // 0.0 .. F_PI2
-									Primitive3DSequence aNewList(getLineJoinSegments(nSegments, aMaterial, fAngle, getDegreeStepWidth(), getMiterMinimumAngle(), getLineJoin()));
-
-									// calculate transformation. First, get angle in YZ between nForw projected on (1, 0, 0) and nBack
-									basegfx::B3DHomMatrix aInvRotVector(aRotVector);
-									aInvRotVector.invert();
-									basegfx::B3DVector aTransBack(aInvRotVector * aBack);
-									const double fRotInYZ(atan2(aTransBack.getY(), aTransBack.getZ()));
-
-									// create trans by rotating unit sphere with angle 90 degrees around Y, then 180-fRot in X.
-									// Also apply usual scaling and translation
-									basegfx::B3DHomMatrix aSphereTrans;
-									aSphereTrans.rotate(0.0, F_PI2, 0.0);
-									aSphereTrans.rotate(F_PI - fRotInYZ, 0.0, 0.0);
-									aSphereTrans *= aRotVector;
-									aSphereTrans.scale(getRadius(), getRadius(), getRadius());
-									aSphereTrans.translate(aCurr.getX(), aCurr.getY(), aCurr.getZ());
-
-									// line start edge, build transformed primitiveVector3D
-									TransformPrimitive3D* pNewTransformedB = new TransformPrimitive3D(aSphereTrans, aNewList);
-									aResultVector.push_back(pNewTransformedB);
-								}
-							}
-
-							// create line segments, build transformed primitiveVector3D
-							TransformPrimitive3D* pNewTransformedC = new TransformPrimitive3D(aVectorTrans, getLineTubeSegments(nSegments, aMaterial));
-							aResultVector.push_back(pNewTransformedC);
-
-							if(bNoLineJoin || (!bClosed && ((a + 1L) == nLoopCount)))
-							{
-								// line end edge, first rotate (mirror) and translate, then use use aRotVector
-								basegfx::B3DHomMatrix aBackTrans;
-								aBackTrans.rotate(0.0, F_PI, 0.0);
-								aBackTrans.translate(1.0, 0.0, 0.0);
-								aBackTrans.scale(fForwLen, getRadius(), getRadius());
-								aBackTrans *= aRotVector;
-								aBackTrans.translate(aCurr.getX(), aCurr.getY(), aCurr.getZ());
-								
-								// line end edge, build transformed primitiveVector3D
-								TransformPrimitive3D* pNewTransformedD = new TransformPrimitive3D(aBackTrans, getLineCapSegments(nSegments, aMaterial));
-								aResultVector.push_back(pNewTransformedD);
-							}
-						}
+    namespace primitive3d
+    {
+        Primitive3DSequence PolygonTubePrimitive3D::impCreate3DDecomposition(const geometry::ViewInformation3D& /*rViewInformation*/) const
+        {
+            const sal_uInt32 nPointCount(getB3DPolygon().count());
+            std::vector< BasePrimitive3D* > aResultVector;
+            
+            if(nPointCount)
+            {
+                if(basegfx::fTools::more(getRadius(), 0.0))
+                {
+                    const attribute::MaterialAttribute3D aMaterial(getBColor());
+                    static sal_uInt32 nSegments(8); // default for 3d line segments, for more quality just raise this value (in even steps)
+                    const bool bClosed(getB3DPolygon().isClosed());
+                    const bool bNoLineJoin(basegfx::B2DLINEJOIN_NONE == getLineJoin());
+                    const sal_uInt32 nLoopCount(bClosed ? nPointCount : nPointCount - 1);
+                    basegfx::B3DPoint aLast(getB3DPolygon().getB3DPoint(nPointCount - 1));
+                    basegfx::B3DPoint aCurr(getB3DPolygon().getB3DPoint(0));
+                    
+                    for(sal_uInt32 a(0); a < nLoopCount; a++)
+                    {
+                        // get next data
+                        const basegfx::B3DPoint aNext(getB3DPolygon().getB3DPoint((a + 1) % nPointCount));
+                        const basegfx::B3DVector aForw(aNext - aCurr);
+                        const double fForwLen(aForw.getLength());
+                        
+                        if(basegfx::fTools::more(fForwLen, 0.0))
+                        {
+                            // find out if linecap is active
+                            const bool bFirst(!a);
+                            const bool bLast(a + 1 == nLoopCount);
+                            const bool bLineCapPossible(!bClosed && (bFirst || bLast));
+                            const bool bLineCapRound(bLineCapPossible && com::sun::star::drawing::LineCap_ROUND == getLineCap());
+                            const bool bLineCapSquare(bLineCapPossible && com::sun::star::drawing::LineCap_SQUARE == getLineCap());
+
+                            // get rotation from vector, this describes rotation from (1, 0, 0) to aForw
+                            basegfx::B3DHomMatrix aRotVector(getRotationFromVector(aForw));
+
+                            // prepare transformations for tube and cap
+                            basegfx::B3DHomMatrix aTubeTrans;
+                            basegfx::B3DHomMatrix aCapTrans;
+
+                            // cap gets radius size
+                            aCapTrans.scale(getRadius(), getRadius(), getRadius());
+
+                            if(bLineCapSquare)
+                            {
+                                // when square line cap just prolong line segment in X, maybe 2 x radius when
+                                // first and last (simple line segment)
+                                const double fExtraLength(bFirst && bLast ? getRadius() * 2.0 : getRadius());
+                                
+                                aTubeTrans.scale(fForwLen + fExtraLength, getRadius(), getRadius());
+
+                                if(bFirst)
+                                {
+                                    // correct start positions for tube and cap when first and square prolonged
+                                    aTubeTrans.translate(-getRadius(), 0.0, 0.0);
+                                    aCapTrans.translate(-getRadius(), 0.0, 0.0);
+                                }
+                            }
+                            else
+                            {
+                                // normal tube size
+                                aTubeTrans.scale(fForwLen, getRadius(), getRadius());
+                            }
+
+                            // rotate and translate tube and cap
+                            aTubeTrans *= aRotVector;
+                            aTubeTrans.translate(aCurr.getX(), aCurr.getY(), aCurr.getZ());
+                            aCapTrans *= aRotVector;
+                            aCapTrans.translate(aCurr.getX(), aCurr.getY(), aCurr.getZ());
+
+                            if(bNoLineJoin || (!bClosed && bFirst))
+                            {
+                                // line start edge, build transformed primitiveVector3D
+                                Primitive3DSequence aSequence;
+
+                                if(bLineCapRound && bFirst)
+                                {
+                                    // LineCapRound used
+                                    aSequence = getLineCapRoundSegments(nSegments, aMaterial);
+                                }
+                                else
+                                {
+                                    // simple closing cap
+                                    aSequence = getLineCapSegments(nSegments, aMaterial);
+                                }
+
+                                TransformPrimitive3D* pNewTransformedA = new TransformPrimitive3D(aCapTrans, aSequence);
+                                aResultVector.push_back(pNewTransformedA);
+                            }
+                            else
+                            {
+                                const basegfx::B3DVector aBack(aCurr - aLast);
+                                const double fCross(basegfx::cross(aBack, aForw).getLength());
+
+                                if(!basegfx::fTools::equalZero(fCross))
+                                {
+                                    // line connect non-parallel, aBack, aForw, use getLineJoin()
+                                    const double fAngle(acos(aBack.scalar(aForw) / (fForwLen * aBack.getLength()))); // 0.0 .. F_PI2
+                                    Primitive3DSequence aNewList(
+                                        getLineJoinSegments(
+                                            nSegments, 
+                                            aMaterial, 
+                                            fAngle, 
+                                            getDegreeStepWidth(), 
+                                            getMiterMinimumAngle(), 
+                                            getLineJoin()));
+
+                                    // calculate transformation. First, get angle in YZ between nForw projected on (1, 0, 0) and nBack
+                                    basegfx::B3DHomMatrix aInvRotVector(aRotVector);
+                                    aInvRotVector.invert();
+                                    basegfx::B3DVector aTransBack(aInvRotVector * aBack);
+                                    const double fRotInYZ(atan2(aTransBack.getY(), aTransBack.getZ()));
+                                    
+                                    // create trans by rotating unit sphere with angle 90 degrees around Y, then 180-fRot in X.
+                                    // Also apply usual scaling and translation
+                                    basegfx::B3DHomMatrix aSphereTrans;
+                                    aSphereTrans.rotate(0.0, F_PI2, 0.0);
+                                    aSphereTrans.rotate(F_PI - fRotInYZ, 0.0, 0.0);
+                                    aSphereTrans *= aRotVector;
+                                    aSphereTrans.scale(getRadius(), getRadius(), getRadius());
+                                    aSphereTrans.translate(aCurr.getX(), aCurr.getY(), aCurr.getZ());
+                                    
+                                    // line start edge, build transformed primitiveVector3D
+                                    aResultVector.push_back(
+                                        new TransformPrimitive3D(
+                                            aSphereTrans, 
+                                            aNewList));
+                                }
+                            }
+
+                            // create line segments, build transformed primitiveVector3D
+                            aResultVector.push_back(
+                                new TransformPrimitive3D(
+                                    aTubeTrans, 
+                                    getLineTubeSegments(nSegments, aMaterial)));
+
+                            if(bNoLineJoin || (!bClosed && bLast))
+                            {
+                                // line end edge
+                                basegfx::B3DHomMatrix aBackCapTrans;
+
+                                // Mirror (line end) and radius scale
+                                aBackCapTrans.rotate(0.0, F_PI, 0.0);
+                                aBackCapTrans.scale(getRadius(), getRadius(), getRadius());
+
+                                if(bLineCapSquare && bLast)
+                                {
+                                    // correct position when square and prolonged
+                                    aBackCapTrans.translate(fForwLen + getRadius(), 0.0, 0.0);
+                                }
+                                else
+                                {
+                                    // standard position
+                                    aBackCapTrans.translate(fForwLen, 0.0, 0.0);
+                                }
+
+                                // rotate and translate to destination
+                                aBackCapTrans *= aRotVector;
+                                aBackCapTrans.translate(aCurr.getX(), aCurr.getY(), aCurr.getZ());
+
+                                // get primitiveVector3D
+                                Primitive3DSequence aSequence;
+
+                                if(bLineCapRound && bLast)
+                                {
+                                    // LineCapRound used
+                                    aSequence = getLineCapRoundSegments(nSegments, aMaterial);
+                                }
+                                else
+                                {
+                                    // simple closing cap
+                                    aSequence = getLineCapSegments(nSegments, aMaterial);
+                                }
+
+                                aResultVector.push_back(
+                                    new TransformPrimitive3D(
+                                        aBackCapTrans, 
+                                        aSequence));
+                            }
+                        }
 
 						// prepare next loop step
 						aLast = aCurr;
@@ -526,6 +684,7 @@ namespace drawinglayer
 			const basegfx::B3DPolygon& rPolygon, 
 			const basegfx::BColor& rBColor,
 			double fRadius, basegfx::B2DLineJoin aLineJoin,
+            com::sun::star::drawing::LineCap aLineCap,
 			double fDegreeStepWidth,
 			double fMiterMinimumAngle)
 		:	PolygonHairlinePrimitive3D(rPolygon, rBColor),
@@ -533,7 +692,8 @@ namespace drawinglayer
             mfRadius(fRadius),
 			mfDegreeStepWidth(fDegreeStepWidth),
 			mfMiterMinimumAngle(fMiterMinimumAngle),
-			maLineJoin(aLineJoin)
+			maLineJoin(aLineJoin),
+            maLineCap(aLineCap)
 		{
 		}
 
@@ -546,7 +706,8 @@ namespace drawinglayer
 				return (getRadius() == rCompare.getRadius()
 					&& getDegreeStepWidth() == rCompare.getDegreeStepWidth()
 					&& getMiterMinimumAngle() == rCompare.getMiterMinimumAngle()
-					&& getLineJoin() == rCompare.getLineJoin());
+					&& getLineJoin() == rCompare.getLineJoin()
+                    && getLineCap() == rCompare.getLineCap());
 			}
 
 			return false;

Modified: incubator/ooo/trunk/main/drawinglayer/source/primitive3d/sdrdecompositiontools3d.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/drawinglayer/source/primitive3d/sdrdecompositiontools3d.cxx?rev=1232507&r1=1232506&r2=1232507&view=diff
==============================================================================
--- incubator/ooo/trunk/main/drawinglayer/source/primitive3d/sdrdecompositiontools3d.cxx (original)
+++ incubator/ooo/trunk/main/drawinglayer/source/primitive3d/sdrdecompositiontools3d.cxx Tue Jan 17 17:54:04 2012
@@ -150,7 +150,7 @@ namespace drawinglayer
 			aScaledPolyPolygon.transform(rObjectTransform);
 
 			// create line and stroke attribute
-			const attribute::LineAttribute aLineAttribute(rLine.getColor(), rLine.getWidth(), rLine.getJoin());
+			const attribute::LineAttribute aLineAttribute(rLine.getColor(), rLine.getWidth(), rLine.getJoin(), rLine.getCap());
 			const attribute::StrokeAttribute aStrokeAttribute(rLine.getDotDashArray(), rLine.getFullDotDashLen());
 
 			// create primitives

Modified: incubator/ooo/trunk/main/drawinglayer/source/processor2d/canvasprocessor.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/drawinglayer/source/processor2d/canvasprocessor.cxx?rev=1232507&r1=1232506&r2=1232507&view=diff
==============================================================================
--- incubator/ooo/trunk/main/drawinglayer/source/processor2d/canvasprocessor.cxx (original)
+++ incubator/ooo/trunk/main/drawinglayer/source/processor2d/canvasprocessor.cxx Tue Jan 17 17:54:04 2012
@@ -57,6 +57,7 @@
 #include <com/sun/star/rendering/CompositeOperation.hpp>
 #include <com/sun/star/rendering/StrokeAttributes.hpp>
 #include <com/sun/star/rendering/PathJoinType.hpp>
+#include <com/sun/star/rendering/PathCapType.hpp>
 #include <drawinglayer/primitive2d/fillbitmapprimitive2d.hxx>
 #include <com/sun/star/rendering/TexturingMode.hpp>
 #include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx>
@@ -1752,7 +1753,23 @@ namespace drawinglayer
                             aStrokeAttribute.JoinType = rendering::PathJoinType::ROUND;
                             break;
                     }
-            
+
+                    switch(rLineAttribute.getLineCap())
+                    {
+                        case com::sun::star::drawing::LineCap_ROUND:
+                            aStrokeAttribute.StartCapType = rendering::PathCapType::ROUND;
+                            aStrokeAttribute.EndCapType = rendering::PathCapType::ROUND;
+                            break;
+                        case com::sun::star::drawing::LineCap_SQUARE:
+                            aStrokeAttribute.StartCapType = rendering::PathCapType::SQUARE;
+                            aStrokeAttribute.EndCapType = rendering::PathCapType::SQUARE;
+                            break;
+                        default: // com::sun::star::drawing::LineCap_BUTT
+                            aStrokeAttribute.StartCapType = rendering::PathCapType::BUTT;
+                            aStrokeAttribute.EndCapType = rendering::PathCapType::BUTT;
+                            break;
+                    }
+
 			        const basegfx::BColor aHairlineColor(maBColorModifierStack.getModifiedColor(rLineAttribute.getColor()));
                     maRenderState.DeviceColor = aHairlineColor.colorToDoubleSequence(mxCanvas->getDevice());
 					canvas::tools::setRenderStateTransform(maRenderState, getViewInformation2D().getObjectTransformation());

Modified: incubator/ooo/trunk/main/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx?rev=1232507&r1=1232506&r2=1232507&view=diff
==============================================================================
--- incubator/ooo/trunk/main/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx (original)
+++ incubator/ooo/trunk/main/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx Tue Jan 17 17:54:04 2012
@@ -415,7 +415,8 @@ namespace drawinglayer
 					}
 				}
 
-	            SvtGraphicStroke::JoinType eJoin(SvtGraphicStroke::joinNone);
+                SvtGraphicStroke::JoinType eJoin(SvtGraphicStroke::joinNone);
+                SvtGraphicStroke::CapType eCap(SvtGraphicStroke::capButt);
 				double fLineWidth(0.0);
 				double fMiterLength(0.0);
 				SvtGraphicStroke::DashArray aDashArray;
@@ -455,6 +456,26 @@ namespace drawinglayer
 							break;
 						}
 					}
+
+                    // get stroke
+                    switch(pLineAttribute->getLineCap())
+                    {
+                        default: /* com::sun::star::drawing::LineCap_BUTT */
+                        {
+                            eCap = SvtGraphicStroke::capButt;
+                            break;
+                        }
+                        case com::sun::star::drawing::LineCap_ROUND:
+                        {
+                            eCap = SvtGraphicStroke::capRound;
+                            break;
+                        }
+                        case com::sun::star::drawing::LineCap_SQUARE:
+                        {
+                            eCap = SvtGraphicStroke::capSquare;
+                            break;
+                        }
+                    }
                 }
 
 				if(pStrokeAttribute)
@@ -482,7 +503,7 @@ namespace drawinglayer
 					PolyPolygon(aEndArrow),
 					mfCurrentUnifiedTransparence,
 					fLineWidth,
-					SvtGraphicStroke::capButt,
+					eCap,
 					eJoin,
 					fMiterLength,
 					aDashArray);
@@ -1203,6 +1224,7 @@ namespace drawinglayer
 
 							LineInfo aLineInfo(LINE_SOLID, basegfx::fround(fDiscreteLineWidth));
 						    aLineInfo.SetLineJoin(rLine.getLineJoin());
+                            aLineInfo.SetLineCap(rLine.getLineCap());
 
 						    for(sal_uInt32 a(0); a < aHairLinePolyPolygon.count(); a++)
 						    {

Modified: incubator/ooo/trunk/main/editeng/inc/editeng/unoprnms.hxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/editeng/inc/editeng/unoprnms.hxx?rev=1232507&r1=1232506&r2=1232507&view=diff
==============================================================================
--- incubator/ooo/trunk/main/editeng/inc/editeng/unoprnms.hxx (original)
+++ incubator/ooo/trunk/main/editeng/inc/editeng/unoprnms.hxx Tue Jan 17 17:54:04 2012
@@ -92,6 +92,7 @@
 #define	UNO_NAME_LINESTARTCENTER				"LineStartCenter"
 #define	UNO_NAME_LINEENDCENTER					"LineEndCenter"
 #define	UNO_NAME_LINETRANSPARENCE				"LineTransparence"
+#define UNO_NAME_LINECAP                        "LineCap"
 
 #define	UNO_NAME_SHADOW							"Shadow"
 #define	UNO_NAME_SHADOWCOLOR					"ShadowColor"

Modified: incubator/ooo/trunk/main/filter/source/graphicfilter/eps/eps.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/filter/source/graphicfilter/eps/eps.cxx?rev=1232507&r1=1232506&r2=1232507&view=diff
==============================================================================
--- incubator/ooo/trunk/main/filter/source/graphicfilter/eps/eps.cxx (original)
+++ incubator/ooo/trunk/main/filter/source/graphicfilter/eps/eps.cxx Tue Jan 17 17:54:04 2012
@@ -2370,6 +2370,7 @@ void PSWriter::ImplWriteLineInfo( const 
 		l_aDashArray.push_back( 2 );
 	const double fLWidth(( ( rLineInfo.GetWidth() + 1 ) + ( rLineInfo.GetWidth() + 1 ) ) * 0.5);
     SvtGraphicStroke::JoinType aJoinType(SvtGraphicStroke::joinMiter);
+    SvtGraphicStroke::CapType aCapType(SvtGraphicStroke::capButt);
 
     switch(rLineInfo.GetLineJoin())
     {
@@ -2389,7 +2390,26 @@ void PSWriter::ImplWriteLineInfo( const 
             break;
     }
 
-	ImplWriteLineInfo( fLWidth, fMiterLimit, SvtGraphicStroke::capButt, aJoinType, l_aDashArray );
+    switch(rLineInfo.GetLineCap())
+    {
+        default: /* com::sun::star::drawing::LineCap_BUTT */
+        {
+            aCapType = SvtGraphicStroke::capButt;
+            break;
+        }
+        case com::sun::star::drawing::LineCap_ROUND:
+        {
+            aCapType = SvtGraphicStroke::capRound;
+            break;
+        }
+        case com::sun::star::drawing::LineCap_SQUARE:
+        {
+            aCapType = SvtGraphicStroke::capSquare;
+            break;
+        }
+    }
+
+	ImplWriteLineInfo( fLWidth, fMiterLimit, aCapType, aJoinType, l_aDashArray );
 }
 
 //---------------------------------------------------------------------------------

Modified: incubator/ooo/trunk/main/filter/source/msfilter/escherex.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/filter/source/msfilter/escherex.cxx?rev=1232507&r1=1232506&r2=1232507&view=diff
==============================================================================
--- incubator/ooo/trunk/main/filter/source/msfilter/escherex.cxx (original)
+++ incubator/ooo/trunk/main/filter/source/msfilter/escherex.cxx Tue Jan 17 17:54:04 2012
@@ -51,6 +51,7 @@
 #include <com/sun/star/awt/Gradient.hpp>
 #include <com/sun/star/drawing/LineStyle.hpp>
 #include <com/sun/star/drawing/LineJoint.hpp>
+#include <com/sun/star/drawing/LineCap.hpp>
 #include <com/sun/star/drawing/FillStyle.hpp>
 #include <com/sun/star/drawing/LineDash.hpp>
 #include <com/sun/star/drawing/BezierPoint.hpp>
@@ -853,6 +854,35 @@ void EscherPropertyContainer::CreateLine
         AddOpt( ESCHER_Prop_lineEndArrowhead, eLineEnd );
         nLineFlags |= 0x100010;
 	}
+
+    // support LineCaps
+    if(EscherPropertyValueHelper::GetPropertyValue(aAny, rXPropSet, String(RTL_CONSTASCII_USTRINGPARAM("LineCap")), sal_False))
+    {
+        ::com::sun::star::drawing::LineCap aLineCap(com::sun::star::drawing::LineCap_BUTT);
+
+        if(aAny >>= aLineCap)
+        {
+            switch (aLineCap)
+            {
+                default: /* com::sun::star::drawing::LineCap_BUTT */
+                {
+                    AddOpt(ESCHER_Prop_lineEndCapStyle, ESCHER_LineEndCapFlat);
+                    break;
+                }
+                case com::sun::star::drawing::LineCap_ROUND:
+                {
+                    AddOpt(ESCHER_Prop_lineEndCapStyle, ESCHER_LineEndCapRound);
+                    break;
+                }
+                case com::sun::star::drawing::LineCap_SQUARE:
+                {
+                    AddOpt(ESCHER_Prop_lineEndCapStyle, ESCHER_LineEndCapSquare);
+                    break;
+                }
+            }
+        }
+    }
+
 	if ( EscherPropertyValueHelper::GetPropertyValue(
 		aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "LineStyle"  ) ), sal_False ) )
     {

Modified: incubator/ooo/trunk/main/filter/source/msfilter/msdffimp.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/filter/source/msfilter/msdffimp.cxx?rev=1232507&r1=1232506&r2=1232507&view=diff
==============================================================================
--- incubator/ooo/trunk/main/filter/source/msfilter/msdffimp.cxx (original)
+++ incubator/ooo/trunk/main/filter/source/msfilter/msdffimp.cxx Tue Jan 17 17:54:04 2012
@@ -920,19 +920,41 @@ void DffPropertyReader::ApplyLineAttribu
 		// Linienattribute
 		sal_Int32 nLineWidth = (sal_Int32)GetPropertyValue( DFF_Prop_lineWidth, 9525 );
 
+        // support LineCap
+        const MSO_LineCap eLineCap((MSO_LineCap)GetPropertyValue(DFF_Prop_lineEndCapStyle, mso_lineEndCapSquare));
+
+        switch(eLineCap)
+        {
+            default: /* case mso_lineEndCapFlat */
+            {
+                // no need to set, it is the default. If this changes, this needs to be activated
+                // rSet.Put(XLineCapItem(com::sun::star::drawing::LineCap_BUTT));
+                break;
+            }
+            case mso_lineEndCapRound:
+            {
+                rSet.Put(XLineCapItem(com::sun::star::drawing::LineCap_ROUND));
+                break;
+            }
+            case mso_lineEndCapSquare:
+            {
+                rSet.Put(XLineCapItem(com::sun::star::drawing::LineCap_SQUARE));
+                break;
+            }
+        }
+
 		MSO_LineDashing eLineDashing = (MSO_LineDashing)GetPropertyValue( DFF_Prop_lineDashing, mso_lineSolid );
 		if ( eLineDashing == mso_lineSolid )
 			rSet.Put(XLineStyleItem( XLINE_SOLID ) );
 		else
 		{
-//			MSO_LineCap eLineCap = (MSO_LineCap)GetPropertyValue( DFF_Prop_lineEndCapStyle, mso_lineEndCapSquare );
 
 			XDashStyle  eDash = XDASH_RECT;
 			sal_uInt16	nDots = 1;
 			sal_uInt32	nDotLen	= nLineWidth / 360;
 			sal_uInt16	nDashes = 0;
 			sal_uInt32	nDashLen = ( 8 * nLineWidth ) / 360;
-			sal_uInt32	nDistance = ( 3 * nLineWidth ) / 360;;
+			sal_uInt32	nDistance = ( 3 * nLineWidth ) / 360;
 
 			switch ( eLineDashing )
 			{
@@ -1049,24 +1071,27 @@ void DffPropertyReader::ApplyLineAttribu
 				rSet.Put( XLineEndItem( aArrowName, basegfx::B2DPolyPolygon(aPoly) ) );
 				rSet.Put( XLineEndCenterItem( bArrowCenter ) );
 			}
-			if ( IsProperty( DFF_Prop_lineEndCapStyle ) )
-			{
-				MSO_LineCap eLineCap = (MSO_LineCap)GetPropertyValue( DFF_Prop_lineEndCapStyle );
-				const SfxPoolItem* pPoolItem = NULL;
-				if ( rSet.GetItemState( XATTR_LINEDASH, sal_False, &pPoolItem ) == SFX_ITEM_SET )
-				{
-					XDashStyle eNewStyle = XDASH_RECT;
-					if ( eLineCap == mso_lineEndCapRound )
-						eNewStyle = XDASH_ROUND;
-					const XDash& rOldDash = ( (const XLineDashItem*)pPoolItem )->GetDashValue();
-					if ( rOldDash.GetDashStyle() != eNewStyle )
-					{
-						XDash aNew( rOldDash );
-						aNew.SetDashStyle( eNewStyle );
-						rSet.Put( XLineDashItem( XubString(), aNew ) );
-					}
-				}
-			}
+
+            // this was used to at least adapt the lineDash to the lineCap before lineCap was
+            // supported, so with supporting lineCap this is no longer needed
+			//if ( IsProperty( DFF_Prop_lineEndCapStyle ) )
+			//{
+			//	MSO_LineCap eLineCap = (MSO_LineCap)GetPropertyValue( DFF_Prop_lineEndCapStyle );
+			//	const SfxPoolItem* pPoolItem = NULL;
+			//	if ( rSet.GetItemState( XATTR_LINEDASH, sal_False, &pPoolItem ) == SFX_ITEM_SET )
+			//	{
+			//		XDashStyle eNewStyle = XDASH_RECT;
+			//		if ( eLineCap == mso_lineEndCapRound )
+			//			eNewStyle = XDASH_ROUND;
+			//		const XDash& rOldDash = ( (const XLineDashItem*)pPoolItem )->GetDashValue();
+			//		if ( rOldDash.GetDashStyle() != eNewStyle )
+			//		{
+			//			XDash aNew( rOldDash );
+			//			aNew.SetDashStyle( eNewStyle );
+			//			rSet.Put( XLineDashItem( XubString(), aNew ) );
+			//		}
+			//	}
+			//}
 		}
 	}
 	else

Modified: incubator/ooo/trunk/main/filter/source/svg/svgwriter.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/filter/source/svg/svgwriter.cxx?rev=1232507&r1=1232506&r2=1232507&view=diff
==============================================================================
--- incubator/ooo/trunk/main/filter/source/svg/svgwriter.cxx (original)
+++ incubator/ooo/trunk/main/filter/source/svg/svgwriter.cxx Tue Jan 17 17:54:04 2012
@@ -83,6 +83,10 @@ static const char   aXMLAttrGradientUnit
 static const char   aXMLAttrOffset[] = "offset";
 static const char   aXMLAttrStopColor[] = "stop-color";
 
+// added support for LineJoin and LineCap
+static const char   aXMLAttrStrokeLinejoin[] = "stroke-linejoin";
+static const char   aXMLAttrStrokeLinecap[] = "stroke-linecap";
+
 // -----------------------------------------------------------------------------
 
 static const sal_Unicode pBase64[] = 
@@ -673,7 +677,52 @@ void SVGActionWriter::ImplWriteShape( co
         sal_Int32 nStrokeWidth = ( bApplyMapping ? ImplMap( rShape.mnStrokeWidth ) : rShape.mnStrokeWidth );
         mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrStrokeWidth, ::rtl::OUString::valueOf( nStrokeWidth ) );
     }
-        
+
+    // support for LineJoin
+    switch(rShape.maLineJoin)
+    {
+        default: // B2DLINEJOIN_NONE, B2DLINEJOIN_MIDDLE
+        case basegfx::B2DLINEJOIN_MITER:
+        {
+            // miter is Svg default, so no need to write until the exporter might write styles.
+            // If this happens, activate here
+            // mrExport.AddAttribute(XML_NAMESPACE_NONE, aXMLAttrStrokeLinejoin, ::rtl::OUString::createFromAscii("miter"));
+            break;
+        }
+        case basegfx::B2DLINEJOIN_BEVEL:
+        {
+            mrExport.AddAttribute(XML_NAMESPACE_NONE, aXMLAttrStrokeLinejoin, ::rtl::OUString::createFromAscii("bevel"));
+            break;
+        }
+        case basegfx::B2DLINEJOIN_ROUND:
+        {
+            mrExport.AddAttribute(XML_NAMESPACE_NONE, aXMLAttrStrokeLinejoin, ::rtl::OUString::createFromAscii("round"));
+            break;
+        }
+    }
+
+    // support for LineCap
+    switch(rShape.maLineCap)
+    {
+        default: /* com::sun::star::drawing::LineCap_BUTT */
+        {
+            // butt is Svg default, so no need to write until the exporter might write styles.
+            // If this happens, activate here
+            // mrExport.AddAttribute(XML_NAMESPACE_NONE, aXMLAttrStrokeLinecap, ::rtl::OUString::createFromAscii("butt"));
+            break;
+        }
+        case com::sun::star::drawing::LineCap_ROUND:
+        {
+            mrExport.AddAttribute(XML_NAMESPACE_NONE, aXMLAttrStrokeLinecap, ::rtl::OUString::createFromAscii("round"));
+            break;
+        }
+        case com::sun::star::drawing::LineCap_SQUARE:
+        {
+            mrExport.AddAttribute(XML_NAMESPACE_NONE, aXMLAttrStrokeLinecap, ::rtl::OUString::createFromAscii("square"));
+            break;
+        }
+    }
+
     if( rShape.maDashArray.size() )
     {
         const ::rtl::OUString   aComma( B2UCONST( "," ) );
@@ -1486,6 +1535,46 @@ void SVGActionWriter::ImplWriteActions( 
                         mapCurShape->maShapeLineColor.SetTransparency( (sal_uInt8) FRound( aStroke.getTransparency() * 255.0 ) );
                         mapCurShape->mnStrokeWidth = FRound( aStroke.getStrokeWidth() ); 
                         aStroke.getDashArray( mapCurShape->maDashArray );
+
+                        // added support for LineJoin
+                        switch(aStroke.getJoinType())
+                        {
+                            default: /* SvtGraphicStroke::joinMiter,  SvtGraphicStroke::joinNone */
+                            {
+                                mapCurShape->maLineJoin = basegfx::B2DLINEJOIN_MITER;
+                                break;
+                            }
+                            case SvtGraphicStroke::joinRound:
+                            {
+                                mapCurShape->maLineJoin = basegfx::B2DLINEJOIN_ROUND;
+                                break;
+                            }
+                            case SvtGraphicStroke::joinBevel:
+                            {
+                                mapCurShape->maLineJoin = basegfx::B2DLINEJOIN_BEVEL;
+                                break;
+                            }
+                        }
+
+                        // added support for LineCap
+                        switch(aStroke.getCapType())
+                        {
+                            default: /* SvtGraphicStroke::capButt */
+                            {
+                                mapCurShape->maLineCap = com::sun::star::drawing::LineCap_BUTT;
+                                break;
+                            }
+                            case SvtGraphicStroke::capRound:
+                            {
+                                mapCurShape->maLineCap = com::sun::star::drawing::LineCap_ROUND;
+                                break;
+                            }
+                            case SvtGraphicStroke::capSquare:
+                            {
+                                mapCurShape->maLineCap = com::sun::star::drawing::LineCap_SQUARE;
+                                break;
+                            }
+                        }
                     }
                     
                     // write open shape in every case

Modified: incubator/ooo/trunk/main/filter/source/svg/svgwriter.hxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/filter/source/svg/svgwriter.hxx?rev=1232507&r1=1232506&r2=1232507&view=diff
==============================================================================
--- incubator/ooo/trunk/main/filter/source/svg/svgwriter.hxx (original)
+++ incubator/ooo/trunk/main/filter/source/svg/svgwriter.hxx Tue Jan 17 17:54:04 2012
@@ -137,20 +137,26 @@ public:
 
 struct SVGShapeDescriptor
 {
-    PolyPolygon                 maShapePolyPoly;
-    Color                       maShapeFillColor;
-    Color                       maShapeLineColor;
-    sal_Int32                   mnStrokeWidth;
-    SvtGraphicStroke::DashArray maDashArray;
-    ::std::auto_ptr< Gradient > mapShapeGradient;
-    ::rtl::OUString             maId;
+    PolyPolygon                         maShapePolyPoly;
+    Color                               maShapeFillColor;
+    Color                               maShapeLineColor;
+    sal_Int32                           mnStrokeWidth;
+    SvtGraphicStroke::DashArray         maDashArray;
+    ::std::auto_ptr< Gradient >         mapShapeGradient;
+    ::rtl::OUString                     maId;
+
+    // added support for LineJoin and LineCap
+    basegfx::B2DLineJoin                maLineJoin;
+    com::sun::star::drawing::LineCap    maLineCap;
 
     // -------------------------------------------------------------------------
 
     SVGShapeDescriptor() :
         maShapeFillColor( Color( COL_TRANSPARENT ) ),
         maShapeLineColor( Color( COL_TRANSPARENT ) ),
-        mnStrokeWidth( 0 )
+        mnStrokeWidth( 0 ),
+        maLineJoin(basegfx::B2DLINEJOIN_MITER), // miter is Svg 'stroke-linejoin' default
+        maLineCap(com::sun::star::drawing::LineCap_BUTT) // butt is Svg 'stroke-linecap' default
     {
     }
 };

Modified: incubator/ooo/trunk/main/offapi/com/sun/star/drawing/LineProperties.idl
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/offapi/com/sun/star/drawing/LineProperties.idl?rev=1232507&r1=1232506&r2=1232507&view=diff
==============================================================================
--- incubator/ooo/trunk/main/offapi/com/sun/star/drawing/LineProperties.idl (original)
+++ incubator/ooo/trunk/main/offapi/com/sun/star/drawing/LineProperties.idl Tue Jan 17 17:54:04 2012
@@ -23,26 +23,12 @@
 #ifndef __com_sun_star_drawing_LineProperties_idl__
 #define __com_sun_star_drawing_LineProperties_idl__
 
-#ifndef __com_sun_star_drawing_LineStyle_idl__
 #include <com/sun/star/drawing/LineStyle.idl>
-#endif
-
-#ifndef __com_sun_star_util_Color_idl__
 #include <com/sun/star/util/Color.idl>
-#endif
-
-#ifndef __com_sun_star_drawing_LineDash_idl__
 #include <com/sun/star/drawing/LineDash.idl>
-#endif
-
-#ifndef __com_sun_star_drawing_PolyPolygonBezierCoords_idl__
 #include <com/sun/star/drawing/PolyPolygonBezierCoords.idl>
-#endif
-
-#ifndef __com_sun_star_drawing_LineJoint_idl__
 #include <com/sun/star/drawing/LineJoint.idl>
-#endif
-
+#include <com/sun/star/drawing/LineCap.idl>
 
 //=============================================================================
 
@@ -98,6 +84,12 @@ published service LineProperties
 
 	//-------------------------------------------------------------------------
 
+    /** This property defines the rendering of ends of thick lines
+     */
+    [optional, property] com::sun::star::drawing::LineCap LineCap;
+
+    //-------------------------------------------------------------------------
+
 	/** This property contains the name of the line start poly polygon bezier.
 		<p>If this string is empty, no line start polygon is rendered.
 	 */

Modified: incubator/ooo/trunk/main/offapi/com/sun/star/drawing/makefile.mk
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/offapi/com/sun/star/drawing/makefile.mk?rev=1232507&r1=1232506&r2=1232507&view=diff
==============================================================================
--- incubator/ooo/trunk/main/offapi/com/sun/star/drawing/makefile.mk (original)
+++ incubator/ooo/trunk/main/offapi/com/sun/star/drawing/makefile.mk Tue Jan 17 17:54:04 2012
@@ -120,6 +120,7 @@ IDLFILES=\
 	Layer.idl\
 	LayerManager.idl\
 	LayerType.idl\
+	LineCap.idl\
 	LineDash.idl\
 	LineEndType.idl\
 	LineJoint.idl\

Modified: incubator/ooo/trunk/main/svgio/source/svgreader/svgstyleattributes.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/svgio/source/svgreader/svgstyleattributes.cxx?rev=1232507&r1=1232506&r2=1232507&view=diff
==============================================================================
--- incubator/ooo/trunk/main/svgio/source/svgreader/svgstyleattributes.cxx (original)
+++ incubator/ooo/trunk/main/svgio/source/svgreader/svgstyleattributes.cxx Tue Jan 17 17:54:04 2012
@@ -63,6 +63,28 @@ namespace svgio
             return basegfx::B2DLINEJOIN_MITER;
         }
 
+        com::sun::star::drawing::LineCap StrokeLinecapToDrawingLineCap(StrokeLinecap aStrokeLinecap)
+        {
+            switch(aStrokeLinecap)
+            {
+                default: /* StrokeLinecap_notset, StrokeLinecap_butt */
+                {
+                    return com::sun::star::drawing::LineCap_BUTT;
+                    break;
+                }
+                case StrokeLinecap_round:
+                {
+                    return com::sun::star::drawing::LineCap_ROUND;
+                    break;
+                }
+                case StrokeLinecap_square:
+                {
+                    return com::sun::star::drawing::LineCap_SQUARE;
+                    break;
+                }
+            }
+        }
+
         FontStretch getWider(FontStretch aSource)
         {
             switch(aSource)
@@ -658,8 +680,9 @@ namespace svgio
 
                     if(basegfx::fTools::more(fStrokeWidth, 0.0))
                     {
-                        // get LineJoin and stroke array
+                        // get LineJoin, LineCap and stroke array
                         const basegfx::B2DLineJoin aB2DLineJoin(StrokeLinejoinToB2DLineJoin(getStrokeLinejoin()));
+                        const com::sun::star::drawing::LineCap aLineCap(StrokeLinecapToDrawingLineCap(getStrokeLinecap()));
                         ::std::vector< double > aDashArray;
                     
                         if(!getStrokeDasharray().empty())
@@ -668,14 +691,14 @@ namespace svgio
                         }
 
                         // todo: Handle getStrokeDashOffset()
-                        // todo: Handle getStrokeLinecap()
                         
                         // prepare line attribute
                         drawinglayer::primitive2d::Primitive2DReference aNewLinePrimitive;
                         const drawinglayer::attribute::LineAttribute aLineAttribute(
                             pStroke ? *pStroke : basegfx::BColor(0.0, 0.0, 0.0),
                             fStrokeWidth,
-                            aB2DLineJoin);
+                            aB2DLineJoin,
+                            aLineCap);
 
                         if(aDashArray.empty())
                         {

Modified: incubator/ooo/trunk/main/svx/Package_inc.mk
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/svx/Package_inc.mk?rev=1232507&r1=1232506&r2=1232507&view=diff
==============================================================================
--- incubator/ooo/trunk/main/svx/Package_inc.mk (original)
+++ incubator/ooo/trunk/main/svx/Package_inc.mk Tue Jan 17 17:54:04 2012
@@ -172,6 +172,7 @@ $(eval $(call gb_Package_add_file,svx_in
 $(eval $(call gb_Package_add_file,svx_inc,inc/svx/unomaster.hxx,svx/unomaster.hxx))
 $(eval $(call gb_Package_add_file,svx_inc,inc/svx/svdedtv.hxx,svx/svdedtv.hxx))
 $(eval $(call gb_Package_add_file,svx_inc,inc/svx/xlinjoit.hxx,svx/xlinjoit.hxx))
+$(eval $(call gb_Package_add_file,svx_inc,inc/svx/xlncapit.hxx,svx/xlncapit.hxx))
 $(eval $(call gb_Package_add_file,svx_inc,inc/svx/sxmbritm.hxx,svx/sxmbritm.hxx))
 $(eval $(call gb_Package_add_file,svx_inc,inc/svx/AccessibleGraphicShape.hxx,svx/AccessibleGraphicShape.hxx))
 $(eval $(call gb_Package_add_file,svx_inc,inc/svx/xlnstit.hxx,svx/xlnstit.hxx))

Modified: incubator/ooo/trunk/main/svx/inc/svx/dialogs.hrc
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/svx/inc/svx/dialogs.hrc?rev=1232507&r1=1232506&r2=1232507&view=diff
==============================================================================
--- incubator/ooo/trunk/main/svx/inc/svx/dialogs.hrc (original)
+++ incubator/ooo/trunk/main/svx/inc/svx/dialogs.hrc Tue Jan 17 17:54:04 2012
@@ -633,6 +633,11 @@
 #define RID_SVXSTR_TBLAFMT_YELLOW			(RID_SVX_START + 575)
 #define RID_SVXSTR_TBLAFMT_END  			(RID_SVX_START + 576)
 
+// string resources for XLineCap item
+#define RID_SVXSTR_LINECAP_BUTT             (RID_SVX_START + 586 )
+#define RID_SVXSTR_LINECAP_ROUND            (RID_SVX_START + 587 )
+#define RID_SVXSTR_LINECAP_SQUARE           (RID_SVX_START + 588 )
+
 // string resources for XLineJoint item
 #define	RID_SVXSTR_LINEJOINT_NONE			RID_SVXSTR_NONE
 #define RID_SVXSTR_LINEJOINT_MIDDLE			(RID_SVX_START + 589 )

Modified: incubator/ooo/trunk/main/svx/inc/svx/unoshprp.hxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/svx/inc/svx/unoshprp.hxx?rev=1232507&r1=1232506&r2=1232507&view=diff
==============================================================================
--- incubator/ooo/trunk/main/svx/inc/svx/unoshprp.hxx (original)
+++ incubator/ooo/trunk/main/svx/inc/svx/unoshprp.hxx Tue Jan 17 17:54:04 2012
@@ -32,6 +32,7 @@
 #include <com/sun/star/awt/Gradient.hpp>
 #include <com/sun/star/drawing/Hatch.hpp>
 #include <com/sun/star/drawing/FillStyle.hpp>
+#include <com/sun/star/drawing/LineCap.hpp>
 #include <com/sun/star/drawing/LineDash.hpp>
 #include <com/sun/star/drawing/LineJoint.hpp>
 #include <com/sun/star/drawing/LineStyle.hpp>
@@ -211,6 +212,7 @@
 	{ MAP_CHAR_LEN(UNO_NAME_SHADOWYDIST),		SDRATTR_SHADOWYDIST,		&::getCppuType((const sal_Int32*)0),	0,		SFX_METRIC_ITEM},
 
 #define LINE_PROPERTIES_DEFAULTS\
+    { MAP_CHAR_LEN(UNO_NAME_LINECAP),           XATTR_LINECAP,          &::getCppuType((const ::com::sun::star::drawing::LineCap*)0),     0,     0}, \
 	{ MAP_CHAR_LEN(UNO_NAME_LINECOLOR),			XATTR_LINECOLOR,		&::getCppuType((const sal_Int32*)0) , 			0,     0}, \
 	{ MAP_CHAR_LEN(UNO_NAME_LINEENDCENTER),		XATTR_LINEENDCENTER,	&::getBooleanCppuType() , 			0,     0}, \
 	{ MAP_CHAR_LEN(UNO_NAME_LINEENDWIDTH),		XATTR_LINEENDWIDTH,		&::getCppuType((const sal_Int32*)0) , 			0,     SFX_METRIC_ITEM}, \

Modified: incubator/ooo/trunk/main/svx/inc/svx/xattr.hxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/svx/inc/svx/xattr.hxx?rev=1232507&r1=1232506&r2=1232507&view=diff
==============================================================================
--- incubator/ooo/trunk/main/svx/inc/svx/xattr.hxx (original)
+++ incubator/ooo/trunk/main/svx/inc/svx/xattr.hxx Tue Jan 17 17:54:04 2012
@@ -57,6 +57,7 @@ class XGradientTable;
 #include <svx/xtextit0.hxx>
 #include <svx/xsetit.hxx>
 #include <svx/xlinjoit.hxx>
+#include <svx/xlncapit.hxx>
 
 
 #endif      // _XATTR_HXX

Modified: incubator/ooo/trunk/main/svx/inc/svx/xdef.hxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/svx/inc/svx/xdef.hxx?rev=1232507&r1=1232506&r2=1232507&view=diff
==============================================================================
--- incubator/ooo/trunk/main/svx/inc/svx/xdef.hxx (original)
+++ incubator/ooo/trunk/main/svx/inc/svx/xdef.hxx Tue Jan 17 17:54:04 2012
@@ -50,7 +50,8 @@
 #define XATTR_LINEENDCENTER     (XATTR_LINE_FIRST + 9)   		/* V3: 1009  V2: 1009 */
 #define XATTR_LINETRANSPARENCE  (XATTR_LINE_FIRST + 10)  		/* V3: 1010  V2: 1010 */
 #define XATTR_LINEJOINT		    (XATTR_LINE_FIRST + 11)			/* V3: 1011  V2: 1011 */
-#define XATTR_LINE_LAST         XATTR_LINEJOINT
+#define XATTR_LINECAP           (XATTR_LINE_FIRST + 12)         /* V3: 1012 */
+#define XATTR_LINE_LAST         XATTR_LINECAP
 #define XATTRSET_LINE           (XATTR_LINE_LAST + 1)    		/* V3: 1017  V2: 1017 */
 
 #define XATTR_FILL_FIRST        	(XATTRSET_LINE + 1)      	/* V3: 1018  V2: 1018 */

Modified: incubator/ooo/trunk/main/svx/source/dialog/sdstring.src
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/svx/source/dialog/sdstring.src?rev=1232507&r1=1232506&r2=1232507&view=diff
==============================================================================
--- incubator/ooo/trunk/main/svx/source/dialog/sdstring.src (original)
+++ incubator/ooo/trunk/main/svx/source/dialog/sdstring.src Tue Jan 17 17:54:04 2012
@@ -359,6 +359,19 @@ String RID_SVXSTR_LINEJOINT_ROUND
 {
 	Text [ en-US ] = "Line joint round";
 };
+String RID_SVXSTR_LINECAP_BUTT
+{
+    Text [ en-US ] = "Line cap flat";  // string as in Excel
+};
+String RID_SVXSTR_LINECAP_ROUND
+{
+    Text [ en-US ] = "Line cap round";
+};
+String RID_SVXSTR_LINECAP_SQUARE
+{
+    Text [ en-US ] = "Line cap square";
+};
+
 
 ///////////////////////////////////////////////////////////////////////////////
 //

Modified: incubator/ooo/trunk/main/svx/source/sdr/attribute/sdrformtextattribute.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/svx/source/sdr/attribute/sdrformtextattribute.cxx?rev=1232507&r1=1232506&r2=1232507&view=diff
==============================================================================
--- incubator/ooo/trunk/main/svx/source/sdr/attribute/sdrformtextattribute.cxx (original)
+++ incubator/ooo/trunk/main/svx/source/sdr/attribute/sdrformtextattribute.cxx Tue Jan 17 17:54:04 2012
@@ -42,12 +42,14 @@
 #include <svx/xlnclit.hxx>
 #include <svx/xlnwtit.hxx>
 #include <svx/xlinjoit.hxx>
+#include <svx/xlncapit.hxx>
 #include <svx/xlineit0.hxx>
 #include <svx/xdash.hxx>
 #include <svx/xlndsit.hxx>
 #include <drawinglayer/attribute/lineattribute.hxx>
 #include <drawinglayer/attribute/strokeattribute.hxx>
 #include <svx/sdr/attribute/sdrformtextoutlineattribute.hxx>
+#include <com/sun/star/drawing/LineCap.hpp>
 
 //////////////////////////////////////////////////////////////////////////////
 // helper to get line, stroke and transparence attributes from SfxItemSet
@@ -114,8 +116,13 @@ namespace
 
 		const sal_uInt32 nLineWidth = ((const XLineWidthItem&)(rSet.Get(XATTR_LINEWIDTH))).GetValue();
 		const XLineJoint eLineJoint = ((const XLineJointItem&)(rSet.Get(XATTR_LINEJOINT))).GetValue();
+		const com::sun::star::drawing::LineCap eLineCap = ((const XLineCapItem&)(rSet.Get(XATTR_LINECAP))).GetValue();
 
-		return drawinglayer::attribute::LineAttribute(aColorAttribute, (double)nLineWidth, impGetB2DLineJoin(eLineJoint));
+		return drawinglayer::attribute::LineAttribute(
+            aColorAttribute, 
+            (double)nLineWidth, 
+            impGetB2DLineJoin(eLineJoint),
+            eLineCap);
 	}
 
     drawinglayer::attribute::StrokeAttribute impGetStrokeAttribute(const SfxItemSet& rSet)

Modified: incubator/ooo/trunk/main/svx/source/sdr/primitive2d/sdrattributecreator.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/svx/source/sdr/primitive2d/sdrattributecreator.cxx?rev=1232507&r1=1232506&r2=1232507&view=diff
==============================================================================
--- incubator/ooo/trunk/main/svx/source/sdr/primitive2d/sdrattributecreator.cxx (original)
+++ incubator/ooo/trunk/main/svx/source/sdr/primitive2d/sdrattributecreator.cxx Tue Jan 17 17:54:04 2012
@@ -31,6 +31,7 @@
 #include <svx/xlntrit.hxx>
 #include <svx/xlnwtit.hxx>
 #include <svx/xlinjoit.hxx>
+#include <svx/xlncapit.hxx>
 #include <svx/xlnclit.hxx>
 #include <svx/xlnstwit.hxx>
 #include <svx/xlnedwit.hxx>
@@ -78,6 +79,7 @@
 #include <drawinglayer/attribute/sdrlightingattribute3d.hxx>
 #include <drawinglayer/attribute/sdrlightattribute3d.hxx>
 #include <svx/sdr/attribute/sdrfilltextattribute.hxx>
+#include <com/sun/star/drawing/LineCap.hpp>
 
 //////////////////////////////////////////////////////////////////////////////
 
@@ -237,6 +239,7 @@ namespace drawinglayer
 					const sal_uInt32 nWidth(((const XLineWidthItem&)(rSet.Get(XATTR_LINEWIDTH))).GetValue());
 					const Color aColor(((const XLineColorItem&)(rSet.Get(XATTR_LINECOLOR))).GetColorValue());
 					const XLineJoint eJoint(((const XLineJointItem&)(rSet.Get(XATTR_LINEJOINT))).GetValue());
+					const com::sun::star::drawing::LineCap eCap(((const XLineCapItem&)(rSet.Get(XATTR_LINECAP))).GetValue());
 					::std::vector< double > aDotDashArray;
 					double fFullDotDashLen(0.0);
 
@@ -255,6 +258,7 @@ namespace drawinglayer
 						(double)nWidth,
 						(double)nTransparence * 0.01,
 						aColor.getBColor(),
+                        eCap,
 						aDotDashArray,
 						fFullDotDashLen);
 				}

Modified: incubator/ooo/trunk/main/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx?rev=1232507&r1=1232506&r2=1232507&view=diff
==============================================================================
--- incubator/ooo/trunk/main/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx (original)
+++ incubator/ooo/trunk/main/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx Tue Jan 17 17:54:04 2012
@@ -129,7 +129,7 @@ namespace drawinglayer
 			aScaledPolygon.transform(rObjectTransform);
 
 			// create line and stroke attribute
-			const attribute::LineAttribute aLineAttribute(rLine.getColor(), rLine.getWidth(), rLine.getJoin());
+			const attribute::LineAttribute aLineAttribute(rLine.getColor(), rLine.getWidth(), rLine.getJoin(), rLine.getCap());
 			const attribute::StrokeAttribute aStrokeAttribute(rLine.getDotDashArray(), rLine.getFullDotDashLen());
 			BasePrimitive2D* pNewLinePrimitive = 0L;
 

Modified: incubator/ooo/trunk/main/svx/source/svdraw/svdfmtf.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/svx/source/svdraw/svdfmtf.cxx?rev=1232507&r1=1232506&r2=1232507&view=diff
==============================================================================
--- incubator/ooo/trunk/main/svx/source/svdraw/svdfmtf.cxx (original)
+++ incubator/ooo/trunk/main/svx/source/svdraw/svdfmtf.cxx Tue Jan 17 17:54:04 2012
@@ -37,6 +37,7 @@
 #include <editeng/crsditem.hxx>
 #include <editeng/shdditem.hxx>
 #include <svx/xlnclit.hxx>
+#include <svx/xlncapit.hxx>
 #include <svx/xlnwtit.hxx>
 #include <svx/xflclit.hxx>
 #include <svx/xgrad.hxx>
@@ -76,6 +77,7 @@ ImpSdrGDIMetaFileImport::ImpSdrGDIMetaFi
 	pPage(NULL),pModel(NULL),nLayer(0),
 	nLineWidth(0),
 	maLineJoin(basegfx::B2DLINEJOIN_NONE),
+	maLineCap(com::sun::star::drawing::LineCap_BUTT),
 	maDash(XDASH_RECT, 0, 0, 0, 0, 0),
 	bFntDirty(sal_True),
 	bLastObjWasPolyWithoutLine(sal_False),bNoLine(sal_False),bNoFill(sal_False),bLastObjWasLine(sal_False)
@@ -305,6 +307,9 @@ void ImpSdrGDIMetaFileImport::SetAttribu
 				break;
 		}
 
+        // Add LineCap support
+        pLineAttr->Put(XLineCapItem(maLineCap));
+
 		if(((maDash.GetDots() && maDash.GetDotLen()) || (maDash.GetDashes() && maDash.GetDashLen())) && maDash.GetDistance())
 		{
 			pLineAttr->Put(XLineDashItem(String(), maDash));
@@ -480,6 +485,7 @@ void ImpSdrGDIMetaFileImport::DoAction(M
 			SdrPathObj* pPath = new SdrPathObj(OBJ_LINE, basegfx::B2DPolyPolygon(aLine));
 			nLineWidth = nNewLineWidth;
 			maLineJoin = rLineInfo.GetLineJoin();
+            maLineCap = rLineInfo.GetLineCap();
 			maDash = XDash(XDASH_RECT,
 				rLineInfo.GetDotCount(), rLineInfo.GetDotLen(),
 				rLineInfo.GetDashCount(), rLineInfo.GetDashLen(),
@@ -685,6 +691,7 @@ void ImpSdrGDIMetaFileImport::DoAction( 
 			basegfx::B2DPolyPolygon(aSource));
 		nLineWidth = nNewLineWidth;
 		maLineJoin = rLineInfo.GetLineJoin();
+        maLineCap = rLineInfo.GetLineCap();
 		maDash = XDash(XDASH_RECT,
 			rLineInfo.GetDotCount(), rLineInfo.GetDotLen(),
 			rLineInfo.GetDashCount(), rLineInfo.GetDashLen(),

Modified: incubator/ooo/trunk/main/svx/source/svdraw/svdfmtf.hxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/svx/source/svdraw/svdfmtf.hxx?rev=1232507&r1=1232506&r2=1232507&view=diff
==============================================================================
--- incubator/ooo/trunk/main/svx/source/svdraw/svdfmtf.hxx (original)
+++ incubator/ooo/trunk/main/svx/source/svdraw/svdfmtf.hxx Tue Jan 17 17:54:04 2012
@@ -80,6 +80,7 @@ protected:
 	Color						aOldLineColor;
 	sal_Int32					nLineWidth;
 	basegfx::B2DLineJoin		maLineJoin;
+	com::sun::star::drawing::LineCap    maLineCap;
 	XDash						maDash;
 
 	sal_Bool					bMov;

Modified: incubator/ooo/trunk/main/svx/source/xoutdev/xattr2.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/svx/source/xoutdev/xattr2.cxx?rev=1232507&r1=1232506&r2=1232507&view=diff
==============================================================================
--- incubator/ooo/trunk/main/svx/source/xoutdev/xattr2.cxx (original)
+++ incubator/ooo/trunk/main/svx/source/xoutdev/xattr2.cxx Tue Jan 17 17:54:04 2012
@@ -28,6 +28,7 @@
 
 
 #include <com/sun/star/drawing/LineJoint.hpp>
+#include <com/sun/star/drawing/LineCap.hpp>
 #include <com/sun/star/uno/Any.hxx>
 
 #include <svx/dialogs.hrc>
@@ -309,6 +310,150 @@ sal_uInt16 XLineJointItem::GetValueCount
 	return 5;
 }
 
+//-----------------------
+// class XLineCapItem -
+//-----------------------
+
+TYPEINIT1_AUTOFACTORY(XLineCapItem, SfxEnumItem);
+
+// -----------------------------------------------------------------------------
+
+XLineCapItem::XLineCapItem(com::sun::star::drawing::LineCap eLineCap) 
+:   SfxEnumItem(XATTR_LINECAP, sal::static_int_cast< sal_uInt16 >(eLineCap))
+{
+}
+
+// -----------------------------------------------------------------------------
+
+XLineCapItem::XLineCapItem( SvStream& rIn )
+:   SfxEnumItem(XATTR_LINECAP, rIn)
+{
+}
+
+// -----------------------------------------------------------------------------
+
+sal_uInt16 XLineCapItem::GetVersion( sal_uInt16 /*nFileFormatVersion*/) const
+{
+    return 1;
+}
+
+// -----------------------------------------------------------------------------
+
+SfxPoolItem* XLineCapItem::Create( SvStream& rIn, sal_uInt16 nVer ) const
+{
+    XLineCapItem* pRet = new XLineCapItem( rIn );
+
+    if(nVer < 1)
+        pRet->SetValue(com::sun::star::drawing::LineCap_BUTT);
+
+    return pRet;
+}
+
+// -----------------------------------------------------------------------------
+
+SfxPoolItem* XLineCapItem::Clone(SfxItemPool* /*pPool*/) const
+{
+    return new XLineCapItem( *this );
+}
+
+// -----------------------------------------------------------------------------
+
+SfxItemPresentation XLineCapItem::GetPresentation( SfxItemPresentation ePres, SfxMapUnit /*eCoreUnit*/,
+                                                     SfxMapUnit /*ePresUnit*/, XubString& rText, const IntlWrapper*) const
+{
+    rText.Erase();
+
+    switch( ePres )
+    {
+        case SFX_ITEM_PRESENTATION_NONE: return ePres;
+
+        case SFX_ITEM_PRESENTATION_COMPLETE:
+        case SFX_ITEM_PRESENTATION_NAMELESS:
+        {
+            sal_uInt16 nId = 0;
+
+            switch( GetValue() )
+            {
+                default: /*com::sun::star::drawing::LineCap_BUTT*/
+                    nId = RID_SVXSTR_LINECAP_BUTT;
+                break;
+
+                case(com::sun::star::drawing::LineCap_ROUND):
+                    nId = RID_SVXSTR_LINECAP_ROUND;
+                break;
+
+                case(com::sun::star::drawing::LineCap_SQUARE):
+                    nId = RID_SVXSTR_LINECAP_SQUARE;
+                break;
+            }
+
+            if( nId )
+                rText = SVX_RESSTR( nId );
+
+            return ePres;
+        }
+        default:
+            return SFX_ITEM_PRESENTATION_NONE;
+    }
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool XLineCapItem::QueryValue( ::com::sun::star::uno::Any& rVal, sal_uInt8 /*nMemberId*/) const
+{
+    const com::sun::star::drawing::LineCap eCap(GetValue());
+    rVal <<= eCap;
+    return true;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool XLineCapItem::PutValue( const ::com::sun::star::uno::Any& rVal, sal_uInt8 /*nMemberId*/)
+{
+    com::sun::star::drawing::LineCap eUnoCap;
+
+    if(!(rVal >>= eUnoCap))
+    {
+        // also try an int (for Basic)
+        sal_Int32 nLJ(0);
+        
+        if(!(rVal >>= nLJ))
+        {
+            return false;
+        }
+
+        eUnoCap = (com::sun::star::drawing::LineCap)nLJ;
+    }
+
+    OSL_ENSURE(com::sun::star::drawing::LineCap_BUTT == eUnoCap
+        || com::sun::star::drawing::LineCap_ROUND == eUnoCap
+        || com::sun::star::drawing::LineCap_SQUARE == eUnoCap, "Unknown enum value in XATTR_LINECAP (!)");
+
+    SetValue(sal::static_int_cast< sal_uInt16 >(eUnoCap));
+
+    return true;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_uInt16 XLineCapItem::GetValueCount() const
+{
+    // don't forget to update the api interface also
+    return 3;
+}
+
+// -----------------------------------------------------------------------------
+
+com::sun::star::drawing::LineCap XLineCapItem::GetValue() const 
+{ 
+    const com::sun::star::drawing::LineCap eRetval((com::sun::star::drawing::LineCap)SfxEnumItem::GetValue());
+    OSL_ENSURE(com::sun::star::drawing::LineCap_BUTT == eRetval
+        || com::sun::star::drawing::LineCap_ROUND == eRetval
+        || com::sun::star::drawing::LineCap_SQUARE == eRetval, "Unknown enum value in XATTR_LINECAP (!)");
+
+    return (com::sun::star::drawing::LineCap)SfxEnumItem::GetValue(); 
+}
+
 //------------------------------
 // class XFillTransparenceItem
 //------------------------------

Modified: incubator/ooo/trunk/main/svx/source/xoutdev/xpool.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/svx/source/xoutdev/xpool.cxx?rev=1232507&r1=1232506&r2=1232507&view=diff
==============================================================================
--- incubator/ooo/trunk/main/svx/source/xoutdev/xpool.cxx (original)
+++ incubator/ooo/trunk/main/svx/source/xoutdev/xpool.cxx Tue Jan 17 17:54:04 2012
@@ -87,6 +87,7 @@ XOutdevItemPool::XOutdevItemPool(
 	mppLocalPoolDefaults[XATTR_LINEENDCENTER      -XATTR_START] = new XLineEndCenterItem;
 	mppLocalPoolDefaults[XATTR_LINETRANSPARENCE   -XATTR_START] = new XLineTransparenceItem;
 	mppLocalPoolDefaults[XATTR_LINEJOINT	        -XATTR_START] = new XLineJointItem;
+    mppLocalPoolDefaults[XATTR_LINECAP            -XATTR_START] = new XLineCapItem;
 	mppLocalPoolDefaults[XATTR_FILLSTYLE				-XATTR_START] = new XFillStyleItem;
 	mppLocalPoolDefaults[XATTR_FILLCOLOR				-XATTR_START] = new XFillColorItem   (aNullStr,aNullFillCol);
 	mppLocalPoolDefaults[XATTR_FILLGRADIENT			-XATTR_START] = new XFillGradientItem(this,aNullGrad);

Modified: incubator/ooo/trunk/main/vcl/aqua/source/gdi/salgdi.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/vcl/aqua/source/gdi/salgdi.cxx?rev=1232507&r1=1232506&r2=1232507&view=diff
==============================================================================
--- incubator/ooo/trunk/main/vcl/aqua/source/gdi/salgdi.cxx (original)
+++ incubator/ooo/trunk/main/vcl/aqua/source/gdi/salgdi.cxx Tue Jan 17 17:54:04 2012
@@ -980,10 +980,12 @@ bool AquaSalGraphics::drawPolyPolygon( c
 
 // -----------------------------------------------------------------------
 
-bool AquaSalGraphics::drawPolyLine( const ::basegfx::B2DPolygon& rPolyLine,
+bool AquaSalGraphics::drawPolyLine( 
+    const ::basegfx::B2DPolygon& rPolyLine,
 	double fTransparency,
 	const ::basegfx::B2DVector& rLineWidths,
-	basegfx::B2DLineJoin eLineJoin )
+	basegfx::B2DLineJoin eLineJoin,
+    com::sun::star::drawing::LineCap eLineCap)
 {
 	// short circuit if there is nothing to do
 	const int nPointCount = rPolyLine.count();

Modified: incubator/ooo/trunk/main/vcl/inc/aqua/salgdi.h
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/vcl/inc/aqua/salgdi.h?rev=1232507&r1=1232506&r2=1232507&view=diff
==============================================================================
--- incubator/ooo/trunk/main/vcl/inc/aqua/salgdi.h (original)
+++ incubator/ooo/trunk/main/vcl/inc/aqua/salgdi.h Tue Jan 17 17:54:04 2012
@@ -186,7 +186,12 @@ public:
     virtual sal_Bool	drawPolyLineBezier( sal_uLong nPoints, const SalPoint* pPtAry, const sal_uInt8* pFlgAry );
     virtual sal_Bool	drawPolygonBezier( sal_uLong nPoints, const SalPoint* pPtAry, const sal_uInt8* pFlgAry );
     virtual sal_Bool	drawPolyPolygonBezier( sal_uLong nPoly, const sal_uLong* pPoints, const SalPoint* const* pPtAry, const sal_uInt8* const* pFlgAry );
-    virtual bool        drawPolyLine( const ::basegfx::B2DPolygon&, double fTransparency, const ::basegfx::B2DVector& rLineWidths, basegfx::B2DLineJoin );
+    virtual bool        drawPolyLine( 
+        const ::basegfx::B2DPolygon&, 
+        double fTransparency, 
+        const ::basegfx::B2DVector& rLineWidths, 
+        basegfx::B2DLineJoin,
+        com::sun::star::drawing::LineCap eLineCap);
 
     // CopyArea --> No RasterOp, but ClipRegion
     virtual void		copyArea( long nDestX, long nDestY, long nSrcX, long nSrcY, long nSrcWidth,

Modified: incubator/ooo/trunk/main/vcl/inc/os2/salgdi.h
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/vcl/inc/os2/salgdi.h?rev=1232507&r1=1232506&r2=1232507&view=diff
==============================================================================
--- incubator/ooo/trunk/main/vcl/inc/os2/salgdi.h (original)
+++ incubator/ooo/trunk/main/vcl/inc/os2/salgdi.h Tue Jan 17 17:54:04 2012
@@ -166,7 +166,12 @@ protected:
     virtual void		drawPolygon( ULONG nPoints, const SalPoint* pPtAry );
     virtual void		drawPolyPolygon( ULONG nPoly, const ULONG* pPoints, PCONSTSALPOINT* pPtAry );
     virtual bool        drawPolyPolygon( const ::basegfx::B2DPolyPolygon&, double fTransparency );
-    virtual bool        drawPolyLine( const ::basegfx::B2DPolygon&, double fTransparency, const ::basegfx::B2DVector& rLineWidth, basegfx::B2DLineJoin );
+    virtual bool        drawPolyLine( 
+        const ::basegfx::B2DPolygon&, 
+        double fTransparency, 
+        const ::basegfx::B2DVector& rLineWidth, 
+        basegfx::B2DLineJoin,
+        com::sun::star::drawing::LineCap);
     virtual sal_Bool	drawPolyLineBezier( sal_uIntPtr nPoints, const SalPoint* pPtAry, const sal_uInt8* pFlgAry );
     virtual sal_Bool	drawPolygonBezier( sal_uIntPtr nPoints, const SalPoint* pPtAry, const sal_uInt8* pFlgAry );
     virtual sal_Bool	drawPolyPolygonBezier( sal_uInt32 nPoly, const sal_uInt32* pPoints, const SalPoint* const* pPtAry, const sal_uInt8* const* pFlgAry );

Modified: incubator/ooo/trunk/main/vcl/inc/salgdi.hxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/vcl/inc/salgdi.hxx?rev=1232507&r1=1232506&r2=1232507&view=diff
==============================================================================
--- incubator/ooo/trunk/main/vcl/inc/salgdi.hxx (original)
+++ incubator/ooo/trunk/main/vcl/inc/salgdi.hxx Tue Jan 17 17:54:04 2012
@@ -119,7 +119,12 @@ protected:
     virtual void		drawPolygon( sal_uLong nPoints, const SalPoint* pPtAry ) = 0;
     virtual void		drawPolyPolygon( sal_uInt32 nPoly, const sal_uInt32* pPoints, PCONSTSALPOINT* pPtAry ) = 0;
     virtual bool        drawPolyPolygon( const ::basegfx::B2DPolyPolygon&, double fTransparency ) = 0;
-    virtual bool        drawPolyLine( const ::basegfx::B2DPolygon&, double fTransparency, const ::basegfx::B2DVector& rLineWidths, basegfx::B2DLineJoin ) = 0;
+    virtual bool        drawPolyLine( 
+        const ::basegfx::B2DPolygon&, 
+        double fTransparency, 
+        const ::basegfx::B2DVector& rLineWidths, 
+        basegfx::B2DLineJoin,
+        com::sun::star::drawing::LineCap) = 0;
     virtual sal_Bool	drawPolyLineBezier( sal_uLong nPoints, const SalPoint* pPtAry, const sal_uInt8* pFlgAry ) = 0;
     virtual sal_Bool	drawPolygonBezier( sal_uLong nPoints, const SalPoint* pPtAry, const sal_uInt8* pFlgAry ) = 0;
     virtual sal_Bool	drawPolyPolygonBezier( sal_uInt32 nPoly, const sal_uInt32* pPoints, const SalPoint* const* pPtAry, const sal_uInt8* const* pFlgAry ) = 0;
@@ -361,7 +366,15 @@ public:
                                              PCONSTSALPOINT* pPtAry,
                                              const OutputDevice *pOutDev );
     bool                    DrawPolyPolygon( const ::basegfx::B2DPolyPolygon&, double fTransparency, const OutputDevice* );
-    bool                    DrawPolyLine( const basegfx::B2DPolygon&, double fTransparency, const basegfx::B2DVector& rLineWidths, basegfx::B2DLineJoin, const OutputDevice* );
+    
+    bool DrawPolyLine( 
+        const basegfx::B2DPolygon& i_rPolygon, 
+        double i_fTransparency, 
+        const basegfx::B2DVector& i_rLineWidth, 
+        basegfx::B2DLineJoin i_eLineJoin, 
+        com::sun::star::drawing::LineCap i_eLineCap,
+        const OutputDevice* i_pOutDev);
+
     sal_Bool                DrawPolyLineBezier( sal_uLong nPoints,
                                                 const SalPoint* pPtAry,
                                                 const sal_uInt8* pFlgAry,

Modified: incubator/ooo/trunk/main/vcl/inc/unx/pspgraphics.h
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/vcl/inc/unx/pspgraphics.h?rev=1232507&r1=1232506&r2=1232507&view=diff
==============================================================================
--- incubator/ooo/trunk/main/vcl/inc/unx/pspgraphics.h (original)
+++ incubator/ooo/trunk/main/vcl/inc/unx/pspgraphics.h Tue Jan 17 17:54:04 2012
@@ -136,7 +136,12 @@ public:
                                              const sal_uInt32* pPoints,
                                              PCONSTSALPOINT* pPtAry );
     virtual bool			drawPolyPolygon( const ::basegfx::B2DPolyPolygon&, double fTransparency );
-    virtual bool            drawPolyLine( const basegfx::B2DPolygon&, double fTransparency, const basegfx::B2DVector& rLineWidths, basegfx::B2DLineJoin);
+    virtual bool            drawPolyLine( 
+        const basegfx::B2DPolygon&, 
+        double fTransparency, 
+        const basegfx::B2DVector& rLineWidths, 
+        basegfx::B2DLineJoin,
+        com::sun::star::drawing::LineCap);
     virtual sal_Bool		drawPolyLineBezier( sal_uIntPtr nPoints,
                                                 const SalPoint* pPtAry,
                                                 const sal_uInt8* pFlgAry );

Modified: incubator/ooo/trunk/main/vcl/inc/unx/salgdi.h
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/vcl/inc/unx/salgdi.h?rev=1232507&r1=1232506&r2=1232507&view=diff
==============================================================================
--- incubator/ooo/trunk/main/vcl/inc/unx/salgdi.h (original)
+++ incubator/ooo/trunk/main/vcl/inc/unx/salgdi.h Tue Jan 17 17:54:04 2012
@@ -284,7 +284,12 @@ public:
                                              const sal_uInt32* pPoints,
                                              PCONSTSALPOINT* pPtAry );
     virtual bool			drawPolyPolygon( const ::basegfx::B2DPolyPolygon&, double fTransparency );
-    virtual bool			drawPolyLine( const ::basegfx::B2DPolygon&, double fTransparency, const ::basegfx::B2DVector& rLineWidth, basegfx::B2DLineJoin );
+    virtual bool			drawPolyLine( 
+        const ::basegfx::B2DPolygon&, 
+        double fTransparency, 
+        const ::basegfx::B2DVector& rLineWidth, 
+        basegfx::B2DLineJoin,
+        com::sun::star::drawing::LineCap);
     virtual bool			drawFilledTrapezoids( const ::basegfx::B2DTrapezoid*, int nTrapCount, double fTransparency );
 
 #if 1 // TODO: remove these obselete methods

Modified: incubator/ooo/trunk/main/vcl/inc/vcl/cvtsvm.hxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/vcl/inc/vcl/cvtsvm.hxx?rev=1232507&r1=1232506&r2=1232507&view=diff
==============================================================================
--- incubator/ooo/trunk/main/vcl/inc/vcl/cvtsvm.hxx (original)
+++ incubator/ooo/trunk/main/vcl/inc/vcl/cvtsvm.hxx Tue Jan 17 17:54:04 2012
@@ -82,6 +82,9 @@
 #define GDI_EXTENDEDPOLYGON_ACTION		1034
 #define GDI_LINEDASHDOT_ACTION			1035
 
+// Added LineCap support
+#define GDI_LINECAP_ACTION				1036
+
 // ----------------
 // - SVMConverter -
 // ----------------

Modified: incubator/ooo/trunk/main/vcl/inc/vcl/lineinfo.hxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/vcl/inc/vcl/lineinfo.hxx?rev=1232507&r1=1232506&r2=1232507&view=diff
==============================================================================
--- incubator/ooo/trunk/main/vcl/inc/vcl/lineinfo.hxx (original)
+++ incubator/ooo/trunk/main/vcl/inc/vcl/lineinfo.hxx Tue Jan 17 17:54:04 2012
@@ -28,6 +28,7 @@
 #include <tools/gen.hxx>
 #include <vcl/vclenum.hxx>
 #include <basegfx/vector/b2enums.hxx>
+#include <com/sun/star/drawing/LineCap.hpp>
 
 // ----------------
 // - ImplLineInfo -
@@ -48,6 +49,7 @@ struct ImplLineInfo
 	long				    mnDistance;
     
     basegfx::B2DLineJoin    meLineJoin;
+    com::sun::star::drawing::LineCap meLineCap;
 
 						ImplLineInfo();
 						ImplLineInfo( const ImplLineInfo& rImplLineInfo );
@@ -108,7 +110,10 @@ public:
     void SetLineJoin(basegfx::B2DLineJoin eLineJoin);
     basegfx::B2DLineJoin GetLineJoin() const { return mpImplLineInfo->meLineJoin; }
 
-	sal_Bool			IsDefault() const { return( !mpImplLineInfo->mnWidth && ( LINE_SOLID == mpImplLineInfo->meStyle ) ); }
+    void SetLineCap(com::sun::star::drawing::LineCap eLineCap);
+    com::sun::star::drawing::LineCap GetLineCap() const { return mpImplLineInfo->meLineCap; }
+
+    sal_Bool			IsDefault() const;
 
     friend VCL_DLLPUBLIC SvStream& operator>>( SvStream& rIStm, LineInfo& rLineInfo );
     friend VCL_DLLPUBLIC SvStream& operator<<( SvStream& rOStm, const LineInfo& rLineInfo );

Modified: incubator/ooo/trunk/main/vcl/inc/vcl/outdev.hxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/vcl/inc/vcl/outdev.hxx?rev=1232507&r1=1232506&r2=1232507&view=diff
==============================================================================
--- incubator/ooo/trunk/main/vcl/inc/vcl/outdev.hxx (original)
+++ incubator/ooo/trunk/main/vcl/inc/vcl/outdev.hxx Tue Jan 17 17:54:04 2012
@@ -41,7 +41,7 @@
 #include <com/sun/star/uno/Reference.h>
 #include <unotools/fontdefs.hxx>
 #include <basegfx/polygon/b2dpolypolygon.hxx>
-
+#include <com/sun/star/drawing/LineCap.hpp>
 #include <vector>
 
 struct ImplOutDevData;
@@ -556,7 +556,11 @@ public:
 
 	// #i101491#
 	// Helper who tries to use SalGDI's DrawPolyLine direct and returns it's bool. Contains no AA check.
-	SAL_DLLPRIVATE bool ImpTryDrawPolyLineDirect(const basegfx::B2DPolygon& rB2DPolygon, double fLineWidth, basegfx::B2DLineJoin eLineJoin);
+	SAL_DLLPRIVATE bool ImpTryDrawPolyLineDirect(
+        const basegfx::B2DPolygon& rB2DPolygon, 
+        double fLineWidth = 0.0, 
+        basegfx::B2DLineJoin eLineJoin = basegfx::B2DLINEJOIN_NONE,
+        com::sun::star::drawing::LineCap eLineCap = com::sun::star::drawing::LineCap_BUTT);
 
 	// Helper for line geometry paint with support for graphic expansion (pattern and fat_to_area)
     void impPaintLineGeometryWithEvtlExpand(const LineInfo& rInfo, basegfx::B2DPolyPolygon aLinePolyPolygon);
@@ -687,7 +691,11 @@ public:
         @see DrawPolyPolygon
      */
     void                DrawPolyLine( const Polygon& rPoly );
-    void                DrawPolyLine( const basegfx::B2DPolygon&, double fLineWidth = 0.0, basegfx::B2DLineJoin = basegfx::B2DLINEJOIN_ROUND );
+    void DrawPolyLine( 
+        const basegfx::B2DPolygon&, 
+        double fLineWidth = 0.0, 
+        basegfx::B2DLineJoin = basegfx::B2DLINEJOIN_ROUND,
+        com::sun::star::drawing::LineCap = com::sun::star::drawing::LineCap_BUTT);
 
     /** Render the given polygon as a line stroke
 

Modified: incubator/ooo/trunk/main/vcl/inc/vcl/print.hxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/vcl/inc/vcl/print.hxx?rev=1232507&r1=1232506&r2=1232507&view=diff
==============================================================================
--- incubator/ooo/trunk/main/vcl/inc/vcl/print.hxx (original)
+++ incubator/ooo/trunk/main/vcl/inc/vcl/print.hxx Tue Jan 17 17:54:04 2012
@@ -84,11 +84,6 @@ public:
     GDIMetaFile*    GetGDIMetaFile() const { return mpMtf; }
     const JobSetup& GetJobSetup() const { return maJobSetup; }
     sal_Bool            IsNewJobSetup() const { return (mbNewJobSetup != 0); }
-
-    friend VCL_DLLPUBLIC SvStream& operator<<( SvStream& rOStm, const PrinterPage& rPage )
-    { rOStm << rPage.mbNewJobSetup; rOStm << rPage.maJobSetup; rPage.mpMtf->Write( rOStm ); return rOStm; }
-    friend VCL_DLLPUBLIC SvStream& operator>>( SvStream& rIStm, PrinterPage& rPage )
-    { return rIStm >> rPage.mbNewJobSetup >> rPage.maJobSetup >> *rPage.mpMtf; }
 };
 
 

Modified: incubator/ooo/trunk/main/vcl/inc/win/salgdi.h
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/vcl/inc/win/salgdi.h?rev=1232507&r1=1232506&r2=1232507&view=diff
==============================================================================
--- incubator/ooo/trunk/main/vcl/inc/win/salgdi.h (original)
+++ incubator/ooo/trunk/main/vcl/inc/win/salgdi.h Tue Jan 17 17:54:04 2012
@@ -186,7 +186,12 @@ protected:
     virtual void		drawPolygon( sal_uIntPtr nPoints, const SalPoint* pPtAry );
     virtual void		drawPolyPolygon( sal_uInt32 nPoly, const sal_uInt32* pPoints, PCONSTSALPOINT* pPtAry );
     virtual bool        drawPolyPolygon( const ::basegfx::B2DPolyPolygon&, double fTransparency );
-    virtual bool        drawPolyLine( const ::basegfx::B2DPolygon&, double fTransparency, const ::basegfx::B2DVector& rLineWidth, basegfx::B2DLineJoin );
+    virtual bool        drawPolyLine( 
+        const ::basegfx::B2DPolygon&, 
+        double fTransparency, 
+        const ::basegfx::B2DVector& rLineWidth, 
+        basegfx::B2DLineJoin,
+        com::sun::star::drawing::LineCap);
     virtual sal_Bool	drawPolyLineBezier( sal_uIntPtr nPoints, const SalPoint* pPtAry, const sal_uInt8* pFlgAry );
     virtual sal_Bool	drawPolygonBezier( sal_uIntPtr nPoints, const SalPoint* pPtAry, const sal_uInt8* pFlgAry );
     virtual sal_Bool	drawPolyPolygonBezier( sal_uInt32 nPoly, const sal_uInt32* pPoints, const SalPoint* const* pPtAry, const BYTE* const* pFlgAry );

Modified: incubator/ooo/trunk/main/vcl/source/gdi/cvtsvm.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/vcl/source/gdi/cvtsvm.cxx?rev=1232507&r1=1232506&r2=1232507&view=diff
==============================================================================
--- incubator/ooo/trunk/main/vcl/source/gdi/cvtsvm.cxx (original)
+++ incubator/ooo/trunk/main/vcl/source/gdi/cvtsvm.cxx Tue Jan 17 17:54:04 2012
@@ -599,6 +599,14 @@ void SVMConverter::ImplConvertFromSVM1( 
 				}
 				break;
 
+                case (GDI_LINECAP_ACTION) :
+                {
+                    sal_Int16 nLineCap(0);
+                    rIStm >> nLineCap;
+                    aLineInfo.SetLineCap((com::sun::star::drawing::LineCap)nLineCap);
+                }
+                break;
+
 				case (GDI_LINEDASHDOT_ACTION) :
 				{
 					sal_Int16 a(0);
@@ -1457,6 +1465,7 @@ sal_uLong SVMConverter::ImplWriteActions
 				const LineInfo& rInfo = pAct->GetLineInfo();
 				const bool bFatLine(!rInfo.IsDefault() && (LINE_NONE != rInfo.GetStyle()));
 				const bool bLineJoin(bFatLine && basegfx::B2DLINEJOIN_ROUND != rInfo.GetLineJoin());
+                const bool bLineCap(bFatLine && com::sun::star::drawing::LineCap_BUTT != rInfo.GetLineCap());
 				const bool bLineDashDot(LINE_DASH == rInfo.GetStyle());
 
 				if( bFatLine )
@@ -1471,16 +1480,23 @@ sal_uLong SVMConverter::ImplWriteActions
 						rOStm << (sal_Int16) rInfo.GetLineJoin();
 					}
 
-					if(bLineDashDot)
-					{
-						rOStm << (sal_Int16) GDI_LINEDASHDOT_ACTION;
-						rOStm << (sal_Int32) 4 + 16;
-						rOStm << (sal_Int16)rInfo.GetDashCount();
-						rOStm << (sal_Int32)rInfo.GetDashLen();
-						rOStm << (sal_Int16)rInfo.GetDotCount();
-						rOStm << (sal_Int32)rInfo.GetDotLen();
-						rOStm << (sal_Int32)rInfo.GetDistance();
-					}
+                    if(bLineCap)
+                    {
+                        rOStm << (sal_Int16) GDI_LINECAP_ACTION;
+                        rOStm << (sal_Int32) 6;
+                        rOStm << (sal_Int16) rInfo.GetLineCap();
+                    }
+				}
+
+				if(bLineDashDot)
+				{
+					rOStm << (sal_Int16) GDI_LINEDASHDOT_ACTION;
+					rOStm << (sal_Int32) 4 + 16;
+					rOStm << (sal_Int16)rInfo.GetDashCount();
+					rOStm << (sal_Int32)rInfo.GetDashLen();
+					rOStm << (sal_Int16)rInfo.GetDotCount();
+					rOStm << (sal_Int32)rInfo.GetDotLen();
+					rOStm << (sal_Int32)rInfo.GetDistance();
 				}
 
 				rOStm << (sal_Int16) GDI_LINE_ACTION;
@@ -1498,11 +1514,16 @@ sal_uLong SVMConverter::ImplWriteActions
 					{
 						nCount += 1;
 					}
-					
-					if(bLineDashDot)
-					{
-						nCount += 1;
-					}
+
+                    if(bLineCap)
+                    {
+                        nCount += 1;
+                    }
+				}
+
+                if(bLineDashDot)
+				{
+					nCount += 1;
 				}
 			}
 			break;
@@ -1600,6 +1621,7 @@ sal_uLong SVMConverter::ImplWriteActions
  				const sal_uInt16 nPoints(aSimplePoly.GetSize());
 				const bool bFatLine(!rInfo.IsDefault() && (LINE_NONE != rInfo.GetStyle()));
 				const bool bLineJoin(bFatLine && basegfx::B2DLINEJOIN_ROUND != rInfo.GetLineJoin());
+                const bool bLineCap(bFatLine && com::sun::star::drawing::LineCap_BUTT != rInfo.GetLineCap());
 				const bool bLineDashDot(LINE_DASH == rInfo.GetStyle());
 
 				if( bFatLine )
@@ -1613,6 +1635,13 @@ sal_uLong SVMConverter::ImplWriteActions
 						rOStm << (sal_Int32) 6;
 						rOStm << (sal_Int16) rInfo.GetLineJoin();
 					}
+
+                    if(bLineCap)
+                    {
+                        rOStm << (sal_Int16) GDI_LINECAP_ACTION;
+                        rOStm << (sal_Int32) 6;
+                        rOStm << (sal_Int16) rInfo.GetLineCap();
+                    }
 				}
 
 				if(bLineDashDot)
@@ -1652,6 +1681,11 @@ sal_uLong SVMConverter::ImplWriteActions
 					{
 						nCount += 1;
 					}
+
+                    if(bLineCap)
+                    {
+                        nCount += 1;
+                    }
 				}
 					
 				if(bLineDashDot)