summaryrefslogtreecommitdiff
path: root/basegfx
diff options
context:
space:
mode:
authorArmin Le Grand <alg@apache.org>2011-12-19 15:41:21 +0000
committerArmin Le Grand <alg@apache.org>2011-12-19 15:41:21 +0000
commite2e16715893229b5d0ad2da6c8e84464e0c43a2e (patch)
tree79d1c632784b3de16fc82c1dfc27c1796a9ef451 /basegfx
parentea4f454ed956e08be47783b3bddd7789f905e350 (diff)
Svg: Reintegrated Svg replacement from /branches/alg/svgreplavement to trunk, first version of Svg stable and done
Diffstat (limited to 'basegfx')
-rw-r--r--basegfx/inc/basegfx/color/bcolor.hxx6
-rw-r--r--basegfx/inc/basegfx/color/bcolormodifier.hxx10
-rw-r--r--basegfx/inc/basegfx/matrix/b2dhommatrixtools.hxx4
-rw-r--r--basegfx/inc/basegfx/polygon/b2dpolygon.hxx4
-rw-r--r--basegfx/inc/basegfx/polygon/b2dpolypolygon.hxx4
-rw-r--r--basegfx/inc/basegfx/polygon/b2dpolypolygoncutter.hxx9
-rw-r--r--basegfx/source/color/bcolormodifier.cxx9
-rw-r--r--basegfx/source/polygon/b2dpolypolygon.cxx12
-rw-r--r--basegfx/source/polygon/b2dpolypolygoncutter.cxx96
-rw-r--r--basegfx/source/polygon/b2dsvgpolypolygon.cxx13
10 files changed, 143 insertions, 24 deletions
diff --git a/basegfx/inc/basegfx/color/bcolor.hxx b/basegfx/inc/basegfx/color/bcolor.hxx
index 76596bdb4d5f..724fe057afab 100644
--- a/basegfx/inc/basegfx/color/bcolor.hxx
+++ b/basegfx/inc/basegfx/color/bcolor.hxx
@@ -151,9 +151,9 @@ namespace basegfx
// luminance
double luminance() const
{
- const double fRedWeight(77.0 / 256.0);
- const double fGreenWeight(151.0 / 256.0);
- const double fBlueWeight(28.0 / 256.0);
+ const double fRedWeight(77.0 / 256.0); // 0.30
+ const double fGreenWeight(151.0 / 256.0); // 0.59
+ const double fBlueWeight(28.0 / 256.0); // 0.11
return (mfX * fRedWeight + mfY * fGreenWeight + mfZ * fBlueWeight);
}
diff --git a/basegfx/inc/basegfx/color/bcolormodifier.hxx b/basegfx/inc/basegfx/color/bcolormodifier.hxx
index 55ed936985e2..afdc38c8b9a7 100644
--- a/basegfx/inc/basegfx/color/bcolormodifier.hxx
+++ b/basegfx/inc/basegfx/color/bcolormodifier.hxx
@@ -35,10 +35,12 @@ namespace basegfx
*/
enum BColorModifyMode
{
- BCOLORMODIFYMODE_REPLACE, // replace all color with local color
- BCOLORMODIFYMODE_INTERPOLATE, // interpolate color between given and local with local value
- BCOLORMODIFYMODE_GRAY, // convert color to gray
- BCOLORMODIFYMODE_BLACKANDWHITE // convert color to B&W, local value is treshhold
+ BCOLORMODIFYMODE_REPLACE, // replace all color with local color
+ BCOLORMODIFYMODE_INTERPOLATE, // interpolate color between given and local with local value
+ BCOLORMODIFYMODE_GRAY, // convert color to gray
+ BCOLORMODIFYMODE_BLACKANDWHITE, // convert color to B&W, local value is treshhold
+ BCOLORMODIFYMODE_INVERT, // invert color
+ BCOLORMODIFYMODE_LUMINANCE_TO_ALPHA // convert color to alpha value (used for Svg Mask)
};
/** Class to hold a color, value and mode for a color modification. Color modification is
diff --git a/basegfx/inc/basegfx/matrix/b2dhommatrixtools.hxx b/basegfx/inc/basegfx/matrix/b2dhommatrixtools.hxx
index 51b955eb2dfe..267cf570b7ce 100644
--- a/basegfx/inc/basegfx/matrix/b2dhommatrixtools.hxx
+++ b/basegfx/inc/basegfx/matrix/b2dhommatrixtools.hxx
@@ -149,7 +149,7 @@ namespace basegfx
double mfShearX;
public:
- B2DHomMatrixBufferedDecompose(const B2DHomMatrix& rB2DHomMatrix)
+ B2DHomMatrixBufferedDecompose(const B2DHomMatrix& rB2DHomMatrix = B2DHomMatrix())
: maScale(),
maTranslate(),
mfRotate(0.0),
@@ -201,7 +201,7 @@ namespace basegfx
}
public:
- B2DHomMatrixBufferedOnDemandDecompose(const B2DHomMatrix& rB2DHomMatrix)
+ B2DHomMatrixBufferedOnDemandDecompose(const B2DHomMatrix& rB2DHomMatrix = B2DHomMatrix())
: maB2DHomMatrix(rB2DHomMatrix),
maScale(),
maTranslate(),
diff --git a/basegfx/inc/basegfx/polygon/b2dpolygon.hxx b/basegfx/inc/basegfx/polygon/b2dpolygon.hxx
index 12b8b8d34ee6..fd988a382f86 100644
--- a/basegfx/inc/basegfx/polygon/b2dpolygon.hxx
+++ b/basegfx/inc/basegfx/polygon/b2dpolygon.hxx
@@ -263,6 +263,10 @@ namespace basegfx
B2DPoint* begin();
B2DPoint* end();
};
+
+ // typedef for a vector of B2DPolygons
+ typedef ::std::vector< B2DPolygon > B2DPolygonVector;
+
} // end of namespace basegfx
//////////////////////////////////////////////////////////////////////////////
diff --git a/basegfx/inc/basegfx/polygon/b2dpolypolygon.hxx b/basegfx/inc/basegfx/polygon/b2dpolypolygon.hxx
index 75d2685593c9..68b7a5090ead 100644
--- a/basegfx/inc/basegfx/polygon/b2dpolypolygon.hxx
+++ b/basegfx/inc/basegfx/polygon/b2dpolypolygon.hxx
@@ -128,6 +128,10 @@ namespace basegfx
B2DPolygon* begin();
B2DPolygon* end();
};
+
+ // typedef for a vector of B2DPolyPolygons
+ typedef ::std::vector< B2DPolyPolygon > B2DPolyPolygonVector;
+
} // end of namespace basegfx
#endif /* _BGFX_POLYGON_B2DPOLYPOLYGON_HXX */
diff --git a/basegfx/inc/basegfx/polygon/b2dpolypolygoncutter.hxx b/basegfx/inc/basegfx/polygon/b2dpolypolygoncutter.hxx
index 1be6c1950af9..d43af8c53e7a 100644
--- a/basegfx/inc/basegfx/polygon/b2dpolypolygoncutter.hxx
+++ b/basegfx/inc/basegfx/polygon/b2dpolypolygoncutter.hxx
@@ -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.
@@ -104,7 +111,7 @@ namespace basegfx
@return A single PolyPolygon containing the Or-merged result
*/
- B2DPolyPolygon mergeToSinglePolyPolygon(const std::vector< basegfx::B2DPolyPolygon >& rInput);
+ B2DPolyPolygon mergeToSinglePolyPolygon(const B2DPolyPolygonVector& rInput);
} // end of namespace tools
} // end of namespace basegfx
diff --git a/basegfx/source/color/bcolormodifier.cxx b/basegfx/source/color/bcolormodifier.cxx
index 50215f3f71a2..517fe417cae6 100644
--- a/basegfx/source/color/bcolormodifier.cxx
+++ b/basegfx/source/color/bcolormodifier.cxx
@@ -56,6 +56,15 @@ namespace basegfx
return ::basegfx::BColor(1.0, 1.0, 1.0);
}
}
+ case BCOLORMODIFYMODE_INVERT :
+ {
+ return ::basegfx::BColor(1.0 - aSourceColor.getRed(), 1.0 - aSourceColor.getGreen(), 1.0 - aSourceColor.getBlue());
+ }
+ case BCOLORMODIFYMODE_LUMINANCE_TO_ALPHA:
+ {
+ const double fAlpha(1.0 - ((aSourceColor.getRed() * 0.2125) + (aSourceColor.getGreen() * 0.7154) + (aSourceColor.getBlue() * 0.0721)));
+ return ::basegfx::BColor(fAlpha, fAlpha, fAlpha);
+ }
default : // BCOLORMODIFYMODE_REPLACE
{
return maBColor;
diff --git a/basegfx/source/polygon/b2dpolypolygon.cxx b/basegfx/source/polygon/b2dpolypolygon.cxx
index 94b8745871a5..28f8270ece65 100644
--- a/basegfx/source/polygon/b2dpolypolygon.cxx
+++ b/basegfx/source/polygon/b2dpolypolygon.cxx
@@ -38,9 +38,7 @@
class ImplB2DPolyPolygon
{
- typedef ::std::vector< basegfx::B2DPolygon > PolygonVector;
-
- PolygonVector maPolygons;
+ basegfx::B2DPolygonVector maPolygons;
public:
ImplB2DPolyPolygon() : maPolygons()
@@ -80,7 +78,7 @@ public:
if(nCount)
{
// add nCount copies of rPolygon
- PolygonVector::iterator aIndex(maPolygons.begin());
+ basegfx::B2DPolygonVector::iterator aIndex(maPolygons.begin());
aIndex += nIndex;
maPolygons.insert(aIndex, nCount, rPolygon);
}
@@ -94,7 +92,7 @@ public:
{
// add nCount polygons from rPolyPolygon
maPolygons.reserve(maPolygons.size() + nCount);
- PolygonVector::iterator aIndex(maPolygons.begin());
+ basegfx::B2DPolygonVector::iterator aIndex(maPolygons.begin());
aIndex += nIndex;
for(sal_uInt32 a(0L); a < nCount; a++)
@@ -110,9 +108,9 @@ public:
if(nCount)
{
// remove polygon data
- PolygonVector::iterator aStart(maPolygons.begin());
+ basegfx::B2DPolygonVector::iterator aStart(maPolygons.begin());
aStart += nIndex;
- const PolygonVector::iterator aEnd(aStart + nCount);
+ const basegfx::B2DPolygonVector::iterator aEnd(aStart + nCount);
maPolygons.erase(aStart, aEnd);
}
diff --git a/basegfx/source/polygon/b2dpolypolygoncutter.cxx b/basegfx/source/polygon/b2dpolypolygoncutter.cxx
index 37a81ff334cb..849fc3811f0d 100644
--- a/basegfx/source/polygon/b2dpolypolygoncutter.cxx
+++ b/basegfx/source/polygon/b2dpolypolygoncutter.cxx
@@ -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());
@@ -922,15 +1010,15 @@ namespace basegfx
}
}
- B2DPolyPolygon mergeToSinglePolyPolygon(const std::vector< basegfx::B2DPolyPolygon >& rInput)
+ B2DPolyPolygon mergeToSinglePolyPolygon(const B2DPolyPolygonVector& rInput)
{
- std::vector< basegfx::B2DPolyPolygon > aInput(rInput);
+ B2DPolyPolygonVector aInput(rInput);
// first step: prepareForPolygonOperation and simple merge of non-overlapping
// PolyPolygons for speedup; this is possible for the wanted OR-operation
if(aInput.size())
{
- std::vector< basegfx::B2DPolyPolygon > aResult;
+ B2DPolyPolygonVector aResult;
aResult.reserve(aInput.size());
for(sal_uInt32 a(0); a < aInput.size(); a++)
@@ -972,7 +1060,7 @@ namespace basegfx
// second step: melt pairwise to a single PolyPolygon
while(aInput.size() > 1)
{
- std::vector< basegfx::B2DPolyPolygon > aResult;
+ B2DPolyPolygonVector aResult;
aResult.reserve((aInput.size() / 2) + 1);
for(sal_uInt32 a(0); a < aInput.size(); a += 2)
diff --git a/basegfx/source/polygon/b2dsvgpolypolygon.cxx b/basegfx/source/polygon/b2dsvgpolypolygon.cxx
index bfac98f3e5f1..1ac1258d7cdd 100644
--- a/basegfx/source/polygon/b2dsvgpolypolygon.cxx
+++ b/basegfx/source/polygon/b2dsvgpolypolygon.cxx
@@ -782,9 +782,16 @@ namespace basegfx
// (since
// createPolygonFromEllipseSegment()
// normalizes to e.g. cw arc)
- const bool bFlipSegment( (bLargeArcFlag!=0) ==
- (fmod(fTheta2+2*M_PI-fTheta1,
- 2*M_PI)<M_PI) );
+
+ // ALG: In my opinion flipping the segment only
+ // depends on the sweep flag. At least, this gives
+ // correct results forthe SVG example (see SVG doc 8.3.8 ff)
+ //
+ //const bool bFlipSegment( (bLargeArcFlag!=0) ==
+ // (fmod(fTheta2+2*M_PI-fTheta1,
+ // 2*M_PI)<M_PI) );
+ const bool bFlipSegment(!bSweepFlag);
+
if( bFlipSegment )
std::swap(fTheta1,fTheta2);