Return-Path: X-Original-To: apmail-incubator-ooo-commits-archive@minotaur.apache.org Delivered-To: apmail-incubator-ooo-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 51C36910B for ; Thu, 26 Jan 2012 15:17:59 +0000 (UTC) Received: (qmail 57852 invoked by uid 500); 26 Jan 2012 15:17:59 -0000 Delivered-To: apmail-incubator-ooo-commits-archive@incubator.apache.org Received: (qmail 57620 invoked by uid 500); 26 Jan 2012 15:17:58 -0000 Mailing-List: contact ooo-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: ooo-dev@incubator.apache.org Delivered-To: mailing list ooo-commits@incubator.apache.org Received: (qmail 57211 invoked by uid 99); 26 Jan 2012 15:17:58 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 26 Jan 2012 15:17:58 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 26 Jan 2012 15:17:56 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id A08AE2388860; Thu, 26 Jan 2012 15:17:36 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1236232 - /incubator/ooo/trunk/main/basegfx/source/polygon/b2dlinegeometry.cxx Date: Thu, 26 Jan 2012 15:17:36 -0000 To: ooo-commits@incubator.apache.org From: alg@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20120126151736.A08AE2388860@eris.apache.org> Author: alg Date: Thu Jan 26 15:17:36 2012 New Revision: 1236232 URL: http://svn.apache.org/viewvc?rev=1236232&view=rev Log: #118838# LineGeometry creation for complicated cases optimized to create single Polygons Modified: incubator/ooo/trunk/main/basegfx/source/polygon/b2dlinegeometry.cxx Modified: incubator/ooo/trunk/main/basegfx/source/polygon/b2dlinegeometry.cxx URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/basegfx/source/polygon/b2dlinegeometry.cxx?rev=1236232&r1=1236231&r2=1236232&view=diff ============================================================================== --- incubator/ooo/trunk/main/basegfx/source/polygon/b2dlinegeometry.cxx (original) +++ incubator/ooo/trunk/main/basegfx/source/polygon/b2dlinegeometry.cxx Thu Jan 26 15:17:36 2012 @@ -35,6 +35,7 @@ #include #include #include +#include ////////////////////////////////////////////////////////////////////////////// @@ -339,7 +340,7 @@ namespace basegfx } } - B2DPolyPolygon createAreaGeometryForEdge( + B2DPolygon createAreaGeometryForEdge( const B2DCubicBezier& rEdge, double fHalfLineWidth, bool bStartRound, @@ -354,7 +355,6 @@ namespace basegfx if(rEdge.isBezier()) { // prepare target and data common for upper and lower - B2DPolyPolygon aRetval; B2DPolygon aBezierPolygon; const B2DVector aPureEdgeVector(rEdge.getEndPoint() - rEdge.getStartPoint()); const double fEdgeLength(aPureEdgeVector.getLength()); @@ -386,50 +386,40 @@ namespace basegfx // check if cut happens const bool bCut(bCutA || bCutB); + B2DPoint aCutPoint; // create left edge if(bStartRound || bStartSquare) { - basegfx::B2DPolygon aStartPolygon; - if(bStartRound) { - aStartPolygon = tools::createHalfUnitCircle(); + basegfx::B2DPolygon aStartPolygon(tools::createHalfUnitCircle()); + aStartPolygon.transform( tools::createScaleShearXRotateTranslateB2DHomMatrix( fHalfLineWidth, fHalfLineWidth, 0.0, atan2(aTangentA.getY(), aTangentA.getX()) + F_PI2, rEdge.getStartPoint().getX(), rEdge.getStartPoint().getY())); + aBezierPolygon.append(aStartPolygon); } else // bStartSquare { const basegfx::B2DPoint aStart(rEdge.getStartPoint() - (aTangentA * fHalfLineWidth)); - if(bCut) + if(bCutB) { - aStartPolygon.append(rEdge.getStartPoint() + aPerpendStartB); + aBezierPolygon.append(rEdge.getStartPoint() + aPerpendStartB); } - aStartPolygon.append(aStart + aPerpendStartB); - aStartPolygon.append(aStart + aPerpendStartA); + aBezierPolygon.append(aStart + aPerpendStartB); + aBezierPolygon.append(aStart + aPerpendStartA); - if(bCut) + if(bCutA) { - aStartPolygon.append(rEdge.getStartPoint() + aPerpendStartA); + aBezierPolygon.append(rEdge.getStartPoint() + aPerpendStartA); } } - - if(bCut) - { - aStartPolygon.append(rEdge.getStartPoint()); - aStartPolygon.setClosed(true); - aRetval.append(aStartPolygon); - } - else - { - aBezierPolygon.append(aStartPolygon); - } } else { @@ -442,7 +432,7 @@ namespace basegfx if(bCutA) { // calculate cut point and add - const B2DPoint aCutPoint(rEdge.getStartPoint() + (aPerpendStartA * fCutA)); + aCutPoint = rEdge.getStartPoint() + (aPerpendStartA * fCutA); aBezierPolygon.append(aCutPoint); } else @@ -464,46 +454,35 @@ namespace basegfx // create right edge if(bEndRound || bEndSquare) { - basegfx::B2DPolygon aEndPolygon; - if(bEndRound) { - aEndPolygon = tools::createHalfUnitCircle(); + basegfx::B2DPolygon aEndPolygon(tools::createHalfUnitCircle()); + aEndPolygon.transform( tools::createScaleShearXRotateTranslateB2DHomMatrix( fHalfLineWidth, fHalfLineWidth, 0.0, atan2(aTangentB.getY(), aTangentB.getX()) - F_PI2, rEdge.getEndPoint().getX(), rEdge.getEndPoint().getY())); + aBezierPolygon.append(aEndPolygon); } else // bEndSquare { const basegfx::B2DPoint aEnd(rEdge.getEndPoint() + (aTangentB * fHalfLineWidth)); - if(bCut) + if(bCutA) { - aEndPolygon.append(rEdge.getEndPoint() + aPerpendEndA); + aBezierPolygon.append(rEdge.getEndPoint() + aPerpendEndA); } - aEndPolygon.append(aEnd + aPerpendEndA); - aEndPolygon.append(aEnd + aPerpendEndB); + aBezierPolygon.append(aEnd + aPerpendEndA); + aBezierPolygon.append(aEnd + aPerpendEndB); - if(bCut) + if(bCutB) { - aEndPolygon.append(rEdge.getEndPoint() + aPerpendEndB); + aBezierPolygon.append(rEdge.getEndPoint() + aPerpendEndB); } } - - if(bCut) - { - aEndPolygon.append(rEdge.getEndPoint()); - aEndPolygon.setClosed(true); - aRetval.append(aEndPolygon); - } - else - { - aBezierPolygon.append(aEndPolygon); - } } else { @@ -516,7 +495,7 @@ namespace basegfx if(bCutB) { // calculate cut point and add - const B2DPoint aCutPoint(rEdge.getEndPoint() + (aPerpendEndB * fCutB)); + aCutPoint = rEdge.getEndPoint() + (aPerpendEndB * fCutB); aBezierPolygon.append(aCutPoint); } else @@ -535,11 +514,69 @@ namespace basegfx } } - // close and return + // close aBezierPolygon.setClosed(true); - aRetval.append(aBezierPolygon); - - return aRetval; + + if(bStartRound || bEndRound) + { + // double points possible when round caps are used at start or end + aBezierPolygon.removeDoublePoints(); + } + + if(bCut && ((bStartRound || bStartSquare) && (bEndRound || bEndSquare))) + { + // When cut exists and both ends are extended with caps, a self-intersecting polygon + // is created; one cut point is known, but there is a 2nd one in the caps geometry. + // Solve by using tooling. + // Remark: This nearly never happens due to curve preparations to extreme points + // and maximum angle turning, but I constructed a test case and checkd that it is + // working propery. + const B2DPolyPolygon aTemp(tools::solveCrossovers(aBezierPolygon)); + const sal_uInt32 nTempCount(aTemp.count()); + + if(nTempCount) + { + if(nTempCount > 1) + { + // as expected, multiple polygons (with same orientation). Remove + // the one which contains aCutPoint, or better take the one without + for (sal_uInt32 a(0); a < nTempCount; a++) + { + aBezierPolygon = aTemp.getB2DPolygon(a); + + const sal_uInt32 nCandCount(aBezierPolygon.count()); + + for(sal_uInt32 b(0); b < nCandCount; b++) + { + if(aCutPoint.equal(aBezierPolygon.getB2DPoint(b))) + { + aBezierPolygon.clear(); + break; + } + } + + if(aBezierPolygon.count()) + { + break; + } + } + + OSL_ENSURE(aBezierPolygon.count(), "Error in line geometry creation, could not solve self-intersection (!)"); + } + else + { + // none found, use result + aBezierPolygon = aTemp.getB2DPolygon(0); + } + } + else + { + OSL_ENSURE(false, "Error in line geometry creation, could not solve self-intersection (!)"); + } + } + + // return + return aBezierPolygon; } else { @@ -636,7 +673,7 @@ namespace basegfx // close and return aEdgePolygon.setClosed(true); - return B2DPolyPolygon(aEdgePolygon); + return aEdgePolygon; } }