diff options
author | Armin Le Grand <alg@apache.org> | 2011-12-19 15:41:21 +0000 |
---|---|---|
committer | Armin Le Grand <alg@apache.org> | 2011-12-19 15:41:21 +0000 |
commit | e2e16715893229b5d0ad2da6c8e84464e0c43a2e (patch) | |
tree | 79d1c632784b3de16fc82c1dfc27c1796a9ef451 /basegfx | |
parent | ea4f454ed956e08be47783b3bddd7789f905e350 (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.hxx | 6 | ||||
-rw-r--r-- | basegfx/inc/basegfx/color/bcolormodifier.hxx | 10 | ||||
-rw-r--r-- | basegfx/inc/basegfx/matrix/b2dhommatrixtools.hxx | 4 | ||||
-rw-r--r-- | basegfx/inc/basegfx/polygon/b2dpolygon.hxx | 4 | ||||
-rw-r--r-- | basegfx/inc/basegfx/polygon/b2dpolypolygon.hxx | 4 | ||||
-rw-r--r-- | basegfx/inc/basegfx/polygon/b2dpolypolygoncutter.hxx | 9 | ||||
-rw-r--r-- | basegfx/source/color/bcolormodifier.cxx | 9 | ||||
-rw-r--r-- | basegfx/source/polygon/b2dpolypolygon.cxx | 12 | ||||
-rw-r--r-- | basegfx/source/polygon/b2dpolypolygoncutter.cxx | 96 | ||||
-rw-r--r-- | basegfx/source/polygon/b2dsvgpolypolygon.cxx | 13 |
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); |