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 2011/12/12 12:00:26 UTC
svn commit: r1213186 - in /incubator/ooo/branches/alg/svgreplacement/main:
basegfx/inc/basegfx/polygon/ basegfx/source/polygon/
svgio/inc/svgio/svgreader/ svgio/source/svgreader/
Author: alg
Date: Mon Dec 12 11:00:25 2011
New Revision: 1213186
URL: http://svn.apache.org/viewvc?rev=1213186&view=rev
Log:
svg: added support fo rfillRule in clipPath and normal geometry
Modified:
incubator/ooo/branches/alg/svgreplacement/main/basegfx/inc/basegfx/polygon/b2dpolypolygoncutter.hxx
incubator/ooo/branches/alg/svgreplacement/main/basegfx/source/polygon/b2dpolypolygoncutter.cxx
incubator/ooo/branches/alg/svgreplacement/main/svgio/inc/svgio/svgreader/svgstyleattributes.hxx
incubator/ooo/branches/alg/svgreplacement/main/svgio/inc/svgio/svgreader/svgtoken.hxx
incubator/ooo/branches/alg/svgreplacement/main/svgio/inc/svgio/svgreader/svgtools.hxx
incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgstyleattributes.cxx
incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgtoken.cxx
incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgtools.cxx
Modified: incubator/ooo/branches/alg/svgreplacement/main/basegfx/inc/basegfx/polygon/b2dpolypolygoncutter.hxx
URL: http://svn.apache.org/viewvc/incubator/ooo/branches/alg/svgreplacement/main/basegfx/inc/basegfx/polygon/b2dpolypolygoncutter.hxx?rev=1213186&r1=1213185&r2=1213186&view=diff
==============================================================================
--- incubator/ooo/branches/alg/svgreplacement/main/basegfx/inc/basegfx/polygon/b2dpolypolygoncutter.hxx (original)
+++ incubator/ooo/branches/alg/svgreplacement/main/basegfx/inc/basegfx/polygon/b2dpolypolygoncutter.hxx Mon Dec 12 11:00:25 2011
@@ -65,6 +65,13 @@ namespace basegfx
// can be combined for logical polygon operations or polygon clipping.
B2DPolyPolygon stripDispensablePolygons(const B2DPolyPolygon& rCandidate, bool bKeepAboveZero = false);
+ // geometrically convert PolyPolygons which are proposed to use nonzero fill rule
+ // to a representation where evenodd paint will give the same result. To do this
+ // all intersections and self-intersections get solved (the polygons will be rearranged
+ // if needed). Then all polygons which are inside another one with the same orientation
+ // get deleted
+ B2DPolyPolygon createNonzeroConform(const B2DPolyPolygon& rCandidate);
+
// For convenience: The four basic operations OR, XOR, AND and DIFF for
// two PolyPolygons. These are combinations of the above methods. To not be forced
// to do evtl. already done preparations twice, You have to do the operations Yourself.
Modified: incubator/ooo/branches/alg/svgreplacement/main/basegfx/source/polygon/b2dpolypolygoncutter.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/branches/alg/svgreplacement/main/basegfx/source/polygon/b2dpolypolygoncutter.cxx?rev=1213186&r1=1213185&r2=1213186&view=diff
==============================================================================
--- incubator/ooo/branches/alg/svgreplacement/main/basegfx/source/polygon/b2dpolypolygoncutter.cxx (original)
+++ incubator/ooo/branches/alg/svgreplacement/main/basegfx/source/polygon/b2dpolypolygoncutter.cxx Mon Dec 12 11:00:25 2011
@@ -701,6 +701,94 @@ namespace basegfx
//////////////////////////////////////////////////////////////////////////////
+ B2DPolyPolygon createNonzeroConform(const B2DPolyPolygon& rCandidate)
+ {
+ B2DPolyPolygon aCandidate;
+
+ // remove all self-intersections and intersections
+ if(rCandidate.count() == 1)
+ {
+ aCandidate = basegfx::tools::solveCrossovers(rCandidate.getB2DPolygon(0));
+ }
+ else
+ {
+ aCandidate = basegfx::tools::solveCrossovers(rCandidate);
+ }
+
+ // cleanup evtl. neutral polygons
+ aCandidate = basegfx::tools::stripNeutralPolygons(aCandidate);
+
+ // remove all polygons which have the same orientation as the polygon they are directly contained in
+ const sal_uInt32 nCount(aCandidate.count());
+
+ if(nCount > 1)
+ {
+ sal_uInt32 a, b;
+ ::std::vector< StripHelper > aHelpers;
+ aHelpers.resize(nCount);
+
+ for(a = 0; a < nCount; a++)
+ {
+ const B2DPolygon aCand(aCandidate.getB2DPolygon(a));
+ StripHelper* pNewHelper = &(aHelpers[a]);
+ pNewHelper->maRange = tools::getRange(aCand);
+ pNewHelper->meOrinetation = tools::getOrientation(aCand);
+
+ // initialize with own orientation
+ pNewHelper->mnDepth = (ORIENTATION_NEGATIVE == pNewHelper->meOrinetation ? -1 : 1);
+ }
+
+ for(a = 0; a < nCount - 1; a++)
+ {
+ const B2DPolygon aCandA(aCandidate.getB2DPolygon(a));
+ StripHelper& rHelperA = aHelpers[a];
+
+ for(b = a + 1; b < nCount; b++)
+ {
+ const B2DPolygon aCandB(aCandidate.getB2DPolygon(b));
+ StripHelper& rHelperB = aHelpers[b];
+ const bool bAInB(rHelperB.maRange.isInside(rHelperA.maRange) && tools::isInside(aCandB, aCandA, true));
+
+ if(bAInB)
+ {
+ // A is inside B, add orientation of B to A
+ rHelperA.mnDepth += (ORIENTATION_NEGATIVE == rHelperB.meOrinetation ? -1 : 1);
+ }
+
+ const bool bBInA(rHelperA.maRange.isInside(rHelperB.maRange) && tools::isInside(aCandA, aCandB, true));
+
+ if(bBInA)
+ {
+ // B is inside A, add orientation of A to B
+ rHelperB.mnDepth += (ORIENTATION_NEGATIVE == rHelperA.meOrinetation ? -1 : 1);
+ }
+ }
+ }
+
+ const B2DPolyPolygon aSource(aCandidate);
+ aCandidate.clear();
+
+ for(a = 0L; a < nCount; a++)
+ {
+ const StripHelper& rHelper = aHelpers[a];
+ // for contained unequal oriented polygons sum will be 0
+ // for contained equal it will be >=2 or <=-2
+ // for free polygons (not contained) it will be 1 or -1
+ // -> accept all which are >=-1 && <= 1
+ bool bAcceptEntry(rHelper.mnDepth >= -1 && rHelper.mnDepth <= 1);
+
+ if(bAcceptEntry)
+ {
+ aCandidate.append(aSource.getB2DPolygon(a));
+ }
+ }
+ }
+
+ return aCandidate;
+ }
+
+ //////////////////////////////////////////////////////////////////////////////
+
B2DPolyPolygon stripDispensablePolygons(const B2DPolyPolygon& rCandidate, bool bKeepAboveZero)
{
const sal_uInt32 nCount(rCandidate.count());
Modified: incubator/ooo/branches/alg/svgreplacement/main/svgio/inc/svgio/svgreader/svgstyleattributes.hxx
URL: http://svn.apache.org/viewvc/incubator/ooo/branches/alg/svgreplacement/main/svgio/inc/svgio/svgreader/svgstyleattributes.hxx?rev=1213186&r1=1213185&r2=1213186&view=diff
==============================================================================
--- incubator/ooo/branches/alg/svgreplacement/main/svgio/inc/svgio/svgreader/svgstyleattributes.hxx (original)
+++ incubator/ooo/branches/alg/svgreplacement/main/svgio/inc/svgio/svgreader/svgstyleattributes.hxx Mon Dec 12 11:00:25 2011
@@ -179,6 +179,9 @@ namespace svgio
// vaules for fill, stroke, strokeWidth and others
bool mbIsClipPathContent : 1;
+ // ClipRule setting (only valid wne mbIsClipPathContent == true)
+ bool mbClipRule : 1; // true == nonzero(default), false == evenodd
+
/// internal helpers
void add_fillGradient(
const basegfx::B2DPolyPolygon& rPath,
@@ -328,7 +331,6 @@ namespace svgio
// MaskXLink content
const rtl::OUString getMaskXLink() const { return maMaskXLink; }
void setMaskXLink(const rtl::OUString& rNew) { maMaskXLink = rNew; }
-
};
} // end of namespace svgreader
} // end of namespace svgio
Modified: incubator/ooo/branches/alg/svgreplacement/main/svgio/inc/svgio/svgreader/svgtoken.hxx
URL: http://svn.apache.org/viewvc/incubator/ooo/branches/alg/svgreplacement/main/svgio/inc/svgio/svgreader/svgtoken.hxx?rev=1213186&r1=1213185&r2=1213186&view=diff
==============================================================================
--- incubator/ooo/branches/alg/svgreplacement/main/svgio/inc/svgio/svgreader/svgtoken.hxx (original)
+++ incubator/ooo/branches/alg/svgreplacement/main/svgio/inc/svgio/svgreader/svgtoken.hxx Mon Dec 12 11:00:25 2011
@@ -90,6 +90,7 @@ namespace svgio
SVGTokenClipPathUnits,
SVGTokenMaskUnits,
SVGTokenMaskContentUnits,
+ SVGTokenClipRule,
// AspectRatio and params
SVGTokenPreserveAspectRatio,
Modified: incubator/ooo/branches/alg/svgreplacement/main/svgio/inc/svgio/svgreader/svgtools.hxx
URL: http://svn.apache.org/viewvc/incubator/ooo/branches/alg/svgreplacement/main/svgio/inc/svgio/svgreader/svgtools.hxx?rev=1213186&r1=1213185&r2=1213186&view=diff
==============================================================================
--- incubator/ooo/branches/alg/svgreplacement/main/svgio/inc/svgio/svgreader/svgtools.hxx (original)
+++ incubator/ooo/branches/alg/svgreplacement/main/svgio/inc/svgio/svgreader/svgtools.hxx Mon Dec 12 11:00:25 2011
@@ -45,6 +45,8 @@ namespace svgio
{
static const rtl::OUString aStrUserSpaceOnUse;
static const rtl::OUString aStrObjectBoundingBox;
+ static const rtl::OUString aStrNonzero;
+ static const rtl::OUString aStrEvenOdd;
};
enum SvgUnits
Modified: incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgstyleattributes.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgstyleattributes.cxx?rev=1213186&r1=1213185&r2=1213186&view=diff
==============================================================================
--- incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgstyleattributes.cxx (original)
+++ incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgstyleattributes.cxx Mon Dec 12 11:00:25 2011
@@ -36,6 +36,8 @@
#include <basegfx/polygon/b2dpolypolygoncutter.hxx>
#include <svgio/svgreader/svgclippathnode.hxx>
#include <svgio/svgreader/svgmasknode.hxx>
+#include <basegfx/polygon/b2dpolypolygoncutter.hxx>
+#include <basegfx/polygon/b2dpolypolygontools.hxx>
//////////////////////////////////////////////////////////////////////////////
@@ -649,13 +651,23 @@ namespace svgio
}
drawinglayer::primitive2d::Primitive2DVector aNewPrimitives;
+ basegfx::B2DPolyPolygon aPath(rPath);
+ const bool bNeedToCheckClipRule(SVGTokenPath == mrOwner.getType() || SVGTokenPolygon == mrOwner.getType());
+ const bool bClipPathIsNonzero(!bIsLine && bNeedToCheckClipRule && mbIsClipPathContent && mbClipRule);
+ const bool bFillRuleIsNonzero(!bIsLine && bNeedToCheckClipRule && !mbIsClipPathContent && getFillRule());
+
+ if(bClipPathIsNonzero || bFillRuleIsNonzero)
+ {
+ // nonzero is wanted, solve geometrically (see description on basegfx)
+ aPath = basegfx::tools::createNonzeroConform(aPath);
+ }
if(!bIsLine)
{
- add_fill(rPath, aNewPrimitives, aGeoRange);
+ add_fill(aPath, aNewPrimitives, aGeoRange);
}
- add_stroke(rPath, aNewPrimitives, aGeoRange);
+ add_stroke(aPath, aNewPrimitives, aGeoRange);
if(pTransform && !aNewPrimitives.empty())
{
@@ -704,7 +716,8 @@ namespace svgio
maFillRule(true),
maFillRuleSet(false),
- mbIsClipPathContent(SVGTokenClipPathNode == mrOwner.getType())
+ mbIsClipPathContent(SVGTokenClipPathNode == mrOwner.getType()),
+ mbClipRule(true)
{
if(!mbIsClipPathContent)
{
@@ -763,15 +776,12 @@ namespace svgio
{
if(aContent.getLength())
{
- static rtl::OUString aStrNonzero(rtl::OUString::createFromAscii("nonzero"));
- static rtl::OUString aStrEvenOdd(rtl::OUString::createFromAscii("evenodd"));
-
- if(aContent.match(aStrNonzero))
+ if(aContent.match(commonStrings::aStrNonzero))
{
maFillRule = true;
maFillRuleSet = true;
}
- else if(aContent.match(aStrEvenOdd))
+ else if(aContent.match(commonStrings::aStrEvenOdd))
{
maFillRule = false;
maFillRuleSet = true;
@@ -1258,6 +1268,21 @@ namespace svgio
readLocalUrl(aContent, maMaskXLink);
break;
}
+ case SVGTokenClipRule:
+ {
+ if(aContent.getLength())
+ {
+ if(aContent.match(commonStrings::aStrNonzero))
+ {
+ mbClipRule = true;
+ }
+ else if(aContent.match(commonStrings::aStrEvenOdd))
+ {
+ mbClipRule = false;
+ }
+ }
+ break;
+ }
}
}
Modified: incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgtoken.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgtoken.cxx?rev=1213186&r1=1213185&r2=1213186&view=diff
==============================================================================
--- incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgtoken.cxx (original)
+++ incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgtoken.cxx Mon Dec 12 11:00:25 2011
@@ -81,6 +81,7 @@ namespace svgio
static rtl::OUString aSVGStrClipPathUnits(rtl::OUString::createFromAscii("clipPathUnits"));
static rtl::OUString aSVGStrMaskUnits(rtl::OUString::createFromAscii("maskUnits"));
static rtl::OUString aSVGStrMaskContentUnits(rtl::OUString::createFromAscii("maskContentUnits"));
+ static rtl::OUString aSVGStrClipRule(rtl::OUString::createFromAscii("clip-rule"));
static rtl::OUString aSVGStrPreserveAspectRatio(rtl::OUString::createFromAscii("preserveAspectRatio"));
static rtl::OUString aSVGStrDefer(rtl::OUString::createFromAscii("defer"));
@@ -204,6 +205,7 @@ namespace svgio
aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrClipPathUnits, SVGTokenClipPathUnits));
aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrMaskUnits, SVGTokenMaskUnits));
aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrMaskContentUnits, SVGTokenMaskContentUnits));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrClipRule, SVGTokenClipRule));
aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrPreserveAspectRatio, SVGTokenPreserveAspectRatio));
aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrDefer, SVGTokenDefer));
Modified: incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgtools.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgtools.cxx?rev=1213186&r1=1213185&r2=1213186&view=diff
==============================================================================
--- incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgtools.cxx (original)
+++ incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgtools.cxx Mon Dec 12 11:00:25 2011
@@ -49,6 +49,8 @@ namespace svgio
// common non-token strings
const rtl::OUString commonStrings::aStrUserSpaceOnUse(rtl::OUString::createFromAscii("userSpaceOnUse"));
const rtl::OUString commonStrings::aStrObjectBoundingBox(rtl::OUString::createFromAscii("objectBoundingBox"));
+ const rtl::OUString commonStrings::aStrNonzero(rtl::OUString::createFromAscii("nonzero"));
+ const rtl::OUString commonStrings::aStrEvenOdd(rtl::OUString::createFromAscii("evenodd"));
basegfx::B2DHomMatrix SvgAspectRatio::createLinearMapping(const basegfx::B2DRange& rTarget, const basegfx::B2DRange& rSource)
{