diff options
-rw-r--r-- | basegfx/source/polygon/b2dlinegeometry.cxx | 8 | ||||
-rw-r--r-- | drawinglayer/source/primitive2d/patternfillprimitive2d.cxx | 205 | ||||
-rw-r--r-- | drawinglayer/source/processor2d/objectinfoextractor2d.cxx | 20 | ||||
-rw-r--r-- | drawinglayer/source/processor2d/vclpixelprocessor2d.cxx | 10 | ||||
-rw-r--r-- | drawinglayer/source/texture/texture.cxx | 53 | ||||
-rw-r--r-- | include/drawinglayer/primitive2d/patternfillprimitive2d.hxx | 20 | ||||
-rw-r--r-- | include/drawinglayer/texture/texture.hxx | 6 | ||||
-rw-r--r-- | vcl/win/gdi/gdiimpl.cxx | 125 |
8 files changed, 362 insertions, 85 deletions
diff --git a/basegfx/source/polygon/b2dlinegeometry.cxx b/basegfx/source/polygon/b2dlinegeometry.cxx index b5163ec1c957..abf80ccc59ce 100644 --- a/basegfx/source/polygon/b2dlinegeometry.cxx +++ b/basegfx/source/polygon/b2dlinegeometry.cxx @@ -955,6 +955,14 @@ namespace basegfx } } } + else + { + // point count, but no edge count -> single point + aRetval.append( + createPolygonFromCircle( + aCandidate.getB2DPoint(0), + fHalfLineWidth)); + } return aRetval; } diff --git a/drawinglayer/source/primitive2d/patternfillprimitive2d.cxx b/drawinglayer/source/primitive2d/patternfillprimitive2d.cxx index ff3e4452886b..39b695c4be7a 100644 --- a/drawinglayer/source/primitive2d/patternfillprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/patternfillprimitive2d.cxx @@ -21,19 +21,144 @@ #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx> #include <drawinglayer/primitive2d/transformprimitive2d.hxx> #include <drawinglayer/primitive2d/polygonprimitive2d.hxx> +#include <drawinglayer/primitive2d/bitmapprimitive2d.hxx> #include <basegfx/polygon/b2dpolygontools.hxx> #include <basegfx/matrix/b2dhommatrixtools.hxx> #include <drawinglayer/texture/texture.hxx> #include <drawinglayer/primitive2d/maskprimitive2d.hxx> - +#include <drawinglayer/tools/converters.hxx> +#include <drawinglayer/geometry/viewinformation2d.hxx> using namespace com::sun::star; +#define MAXIMUM_SQUARE_LENGTH (164.0) +#define MINIMUM_SQUARE_LENGTH (32.0) +#define MINIMUM_TILES_LENGTH (3) namespace drawinglayer { namespace primitive2d { + void PatternFillPrimitive2D::calculateNeededDiscreteBufferSize( + sal_uInt32& rWidth, + sal_uInt32& rHeight, + const geometry::ViewInformation2D& rViewInformation) const + { + // reset parameters + rWidth = rHeight = 0; + + // check if resolution is in the range which may be buffered + const basegfx::B2DPolyPolygon& rMaskPolygon = getMask(); + const basegfx::B2DRange aMaskRange(rMaskPolygon.getB2DRange()); + + // get discrete rounded up square size of a single tile + const basegfx::B2DHomMatrix aMaskRangeTransformation( + basegfx::tools::createScaleTranslateB2DHomMatrix( + aMaskRange.getRange(), + aMaskRange.getMinimum())); + const basegfx::B2DHomMatrix aTransform( + rViewInformation.getObjectToViewTransformation() * aMaskRangeTransformation); + const basegfx::B2DPoint aTopLeft(aTransform * getReferenceRange().getMinimum()); + const basegfx::B2DPoint aX(aTransform * basegfx::B2DPoint(getReferenceRange().getMaxX(), getReferenceRange().getMinY())); + const basegfx::B2DPoint aY(aTransform * basegfx::B2DPoint(getReferenceRange().getMinX(), getReferenceRange().getMaxY())); + const double fW(basegfx::B2DVector(aX - aTopLeft).getLength()); + const double fH(basegfx::B2DVector(aY - aTopLeft).getLength()); + const double fSquare(fW * fH); + + if(fSquare > 0.0) + { + // check if less than a maximum square pixels is used + static sal_uInt32 fMaximumSquare(MAXIMUM_SQUARE_LENGTH * MAXIMUM_SQUARE_LENGTH); + + if(fSquare < fMaximumSquare) + { + // calculate needed number of tiles and check if used more than a minimum count + const texture::GeoTexSvxTiled aTiling(getReferenceRange()); + const sal_uInt32 nTiles(aTiling.getNumberOfTiles()); + static sal_uInt32 nMinimumTiles(MINIMUM_TILES_LENGTH * MINIMUM_TILES_LENGTH); + + if(nTiles >= nMinimumTiles) + { + rWidth = basegfx::fround(ceil(fW)); + rHeight = basegfx::fround(ceil(fH)); + static sal_uInt32 fMinimumSquare(MINIMUM_SQUARE_LENGTH * MINIMUM_SQUARE_LENGTH); + + if(fSquare < fMinimumSquare) + { + const double fRel(fW/fH); + rWidth = basegfx::fround(sqrt(fMinimumSquare * fRel)); + rHeight = basegfx::fround(sqrt(fMinimumSquare / fRel)); + } + } + } + } + } + + Primitive2DContainer PatternFillPrimitive2D::createContent(const geometry::ViewInformation2D& rViewInformation) const + { + Primitive2DContainer aContent; + + // see if buffering is wanted. it is wanted, create buffered content in given resolution + if(0 != mnDiscreteWidth && 0 != mnDiscreteHeight) + { + const geometry::ViewInformation2D aViewInformation2D; + const primitive2d::Primitive2DReference xEmbedRef( + new primitive2d::TransformPrimitive2D( + basegfx::tools::createScaleB2DHomMatrix(mnDiscreteWidth, mnDiscreteHeight), + getChildren())); + const primitive2d::Primitive2DContainer xEmbedSeq { xEmbedRef }; + + const BitmapEx aBitmapEx( + tools::convertToBitmapEx( + xEmbedSeq, + aViewInformation2D, + mnDiscreteWidth, + mnDiscreteHeight, + mnDiscreteWidth * mnDiscreteHeight)); + + if(!aBitmapEx.IsEmpty()) + { + const Size& rBmpPix = aBitmapEx.GetSizePixel(); + + if(rBmpPix.Width() > 0 && rBmpPix.Height() > 0) + { + const primitive2d::Primitive2DReference xEmbedRefBitmap( + new primitive2d::BitmapPrimitive2D( + aBitmapEx, + basegfx::B2DHomMatrix())); + aContent = primitive2d::Primitive2DContainer { xEmbedRefBitmap }; + } + } + } + + if(aContent.empty()) + { + // buffering was not tried or did fail - reset remembered buffered size + // in any case + PatternFillPrimitive2D* pThat = const_cast< PatternFillPrimitive2D* >(this); + pThat->mnDiscreteWidth = pThat->mnDiscreteHeight = 0; + + // use children as default context + aContent = getChildren(); + + // check if content needs to be clipped + const basegfx::B2DRange aUnitRange(0.0, 0.0, 1.0, 1.0); + const basegfx::B2DRange aContentRange(getChildren().getB2DRange(rViewInformation)); + + if(!aUnitRange.isInside(aContentRange)) + { + const Primitive2DReference xRef( + new MaskPrimitive2D( + basegfx::B2DPolyPolygon(basegfx::tools::createPolygonFromRect(aUnitRange)), + aContent)); + + aContent = Primitive2DContainer { xRef }; + } + } + + return aContent; + } + Primitive2DContainer PatternFillPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const { Primitive2DContainer aRetval; @@ -52,20 +177,8 @@ namespace drawinglayer aTiling.appendTransformations(aMatrices); - // check if content needs to be clipped - const basegfx::B2DRange aUnitRange(0.0, 0.0, 1.0, 1.0); - const basegfx::B2DRange aContentRange(getChildren().getB2DRange(rViewInformation)); - Primitive2DContainer aContent(getChildren()); - - if(!aUnitRange.isInside(aContentRange)) - { - const Primitive2DReference xRef( - new MaskPrimitive2D( - basegfx::B2DPolyPolygon(basegfx::tools::createPolygonFromRect(aUnitRange)), - aContent)); - - aContent = Primitive2DContainer { xRef }; - } + // create content + const Primitive2DContainer aContent(createContent(rViewInformation)); // resize result aRetval.resize(aMatrices.size()); @@ -117,7 +230,9 @@ namespace drawinglayer : BufferedDecompositionPrimitive2D(), maMask(rMask), maChildren(rChildren), - maReferenceRange(rReferenceRange) + maReferenceRange(rReferenceRange), + mnDiscreteWidth(0), + mnDiscreteHeight(0) { } @@ -140,6 +255,64 @@ namespace drawinglayer return getMask().getB2DRange(); } + Primitive2DContainer PatternFillPrimitive2D::get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const + { + if(0 == mnDiscreteWidth || 0 == mnDiscreteHeight) + { + // Currently no buffering is used. Check if the resulting discrete sizes + // in the current situation would be good for buffering from now on + PatternFillPrimitive2D* pThat = const_cast< PatternFillPrimitive2D* >(this); + + calculateNeededDiscreteBufferSize(pThat->mnDiscreteWidth, pThat->mnDiscreteHeight, rViewInformation); + } + else + { + // The existing bufferd decomposition uses a buffer in the remembered + // size. Get new needed sizes which depend on the given ViewInformation + sal_uInt32 nW(0); + sal_uInt32 nH(0); + calculateNeededDiscreteBufferSize(nW, nH, rViewInformation); + + if(0 != nW && 0 != nH) + { + // buffering is possible - check if reset is needed + bool bResetBuffering = false; + + if(nW > mnDiscreteWidth || nH > mnDiscreteHeight) + { + // Higher resolution is needed than used in the existing buffered + // decomposition + bResetBuffering = true; + } + else if(double(nW * nH) / double(mnDiscreteWidth * mnDiscreteHeight) <= 0.5) + { + // Size has shrunk for 50% or more - it's worth to refresh the buffering + bResetBuffering = true; + } + + if(bResetBuffering) + { + PatternFillPrimitive2D* pThat = const_cast< PatternFillPrimitive2D* >(this); + pThat->mnDiscreteWidth = nW; + pThat->mnDiscreteHeight = nH; + pThat->setBuffered2DDecomposition(Primitive2DContainer()); + } + } + else + { + // no buffering wanted or possible - clear decomposition to create a + // new, unbuffered one + PatternFillPrimitive2D* pThat = const_cast< PatternFillPrimitive2D* >(this); + pThat->mnDiscreteWidth = 0; + pThat->mnDiscreteHeight = 0; + pThat->setBuffered2DDecomposition(Primitive2DContainer()); + } + } + + // call parent + return BufferedDecompositionPrimitive2D::get2DDecomposition(rViewInformation); + } + // provide unique ID ImplPrimitive2DIDBlock(PatternFillPrimitive2D, PRIMITIVE2D_ID_PATTERNFILLPRIMITIVE2D) diff --git a/drawinglayer/source/processor2d/objectinfoextractor2d.cxx b/drawinglayer/source/processor2d/objectinfoextractor2d.cxx index ad26620a1630..7ae806f2890b 100644 --- a/drawinglayer/source/processor2d/objectinfoextractor2d.cxx +++ b/drawinglayer/source/processor2d/objectinfoextractor2d.cxx @@ -40,8 +40,24 @@ namespace drawinglayer } default : { - // process recursively - process(rCandidate.get2DDecomposition(getViewInformation2D())); + // we look for an encapsulated primitive, so do not decompose primitives + // based on GroupPrimitive2D, just visit their children. It may be that more + // group-like primitives need to be added here, but all primitives with + // grouping functionality should be implemented based on the GroupPrimitive2D + // class and have their main content accessible as children + const primitive2d::GroupPrimitive2D* pGroupPrimitive2D = dynamic_cast< const primitive2d::GroupPrimitive2D* >(&rCandidate); + + if(pGroupPrimitive2D) + { + // process group children recursively + process(pGroupPrimitive2D->getChildren()); + } + else + { + // do not process recursively, we *only* want to find existing + // ObjectInfoPrimitive2D entries + } + break; } } diff --git a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx index 2e6bc257b337..1424d8a1f182 100644 --- a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx +++ b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx @@ -182,17 +182,19 @@ namespace drawinglayer bool VclPixelProcessor2D::tryDrawPolygonStrokePrimitive2DDirect(const drawinglayer::primitive2d::PolygonStrokePrimitive2D& rSource, double fTransparency) { - basegfx::B2DPolygon aLocalPolygon(rSource.getB2DPolygon()); - - if(!aLocalPolygon.count()) + if(!rSource.getB2DPolygon().count()) { // no geometry, done return true; } - aLocalPolygon = basegfx::tools::simplifyCurveSegments(aLocalPolygon); + // get geometry data, prepare hairline data + basegfx::B2DPolygon aLocalPolygon(rSource.getB2DPolygon()); basegfx::B2DPolyPolygon aHairLinePolyPolygon; + // simplify curve segments + aLocalPolygon = basegfx::tools::simplifyCurveSegments(aLocalPolygon); + if(rSource.getStrokeAttribute().isDefault() || 0.0 == rSource.getStrokeAttribute().getFullDotDashLen()) { // no line dashing, just copy diff --git a/drawinglayer/source/texture/texture.cxx b/drawinglayer/source/texture/texture.cxx index e205d89c53da..7d53a46e4d29 100644 --- a/drawinglayer/source/texture/texture.cxx +++ b/drawinglayer/source/texture/texture.cxx @@ -720,9 +720,20 @@ namespace drawinglayer && mfOffsetY == pCompare->mfOffsetY); } - void GeoTexSvxTiled::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices) + sal_uInt32 GeoTexSvxTiled::getNumberOfTiles() const + { + return iterateTiles(nullptr); + } + + void GeoTexSvxTiled::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices) const + { + iterateTiles(&rMatrices); + } + + sal_Int32 GeoTexSvxTiled::iterateTiles(::std::vector< basegfx::B2DHomMatrix >* pMatrices) const { const double fWidth(maRange.getWidth()); + sal_Int32 nTiles = 0; if(!basegfx::fTools::equalZero(fWidth)) { @@ -774,12 +785,19 @@ namespace drawinglayer for(double fPosY((nPosX % 2) ? fStartY - fHeight + (mfOffsetY * fHeight) : fStartY); basegfx::fTools::less(fPosY, 1.0); fPosY += fHeight) { - rMatrices.push_back( - basegfx::tools::createScaleTranslateB2DHomMatrix( - fWidth, - fHeight, - fPosX, - fPosY)); + if(pMatrices) + { + pMatrices->push_back( + basegfx::tools::createScaleTranslateB2DHomMatrix( + fWidth, + fHeight, + fPosX, + fPosY)); + } + else + { + nTiles++; + } } } } @@ -790,17 +808,26 @@ namespace drawinglayer for(double fPosX((nPosY % 2) ? fStartX - fWidth + (mfOffsetX * fWidth) : fStartX); basegfx::fTools::less(fPosX, 1.0); fPosX += fWidth) { - rMatrices.push_back( - basegfx::tools::createScaleTranslateB2DHomMatrix( - fWidth, - fHeight, - fPosX, - fPosY)); + if(pMatrices) + { + pMatrices->push_back( + basegfx::tools::createScaleTranslateB2DHomMatrix( + fWidth, + fHeight, + fPosX, + fPosY)); + } + else + { + nTiles++; + } } } } } } + + return nTiles; } } // end of namespace texture } // end of namespace drawinglayer diff --git a/include/drawinglayer/primitive2d/patternfillprimitive2d.hxx b/include/drawinglayer/primitive2d/patternfillprimitive2d.hxx index bdd8bbe35d4a..8e10564251b8 100644 --- a/include/drawinglayer/primitive2d/patternfillprimitive2d.hxx +++ b/include/drawinglayer/primitive2d/patternfillprimitive2d.hxx @@ -42,9 +42,24 @@ namespace drawinglayer { private: const basegfx::B2DPolyPolygon maMask; - const Primitive2DContainer maChildren; + const Primitive2DContainer maChildren; const basegfx::B2DRange maReferenceRange; + /// values holding the discrete buffer size + sal_uInt32 mnDiscreteWidth; + sal_uInt32 mnDiscreteHeight; + + /// helper that is capable to calculate the needed discrete buffer size for + /// eventually buffered content + void calculateNeededDiscreteBufferSize( + sal_uInt32& rWidth, + sal_uInt32& rHeight, + const geometry::ViewInformation2D& rViewInformation) const; + + /// helper which creates the content - checks if clipping is needed and eventually + /// creates buffered content to speed up rendering + Primitive2DContainer createContent(const geometry::ViewInformation2D& rViewInformation) const; + protected: /// create local decomposition virtual Primitive2DContainer create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const override; @@ -67,6 +82,9 @@ namespace drawinglayer /// get range virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const override; + /// overload to react on evtl. buffered content + virtual Primitive2DContainer get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const override; + /// provide unique ID DeclPrimitive2DIDBlock() }; diff --git a/include/drawinglayer/texture/texture.hxx b/include/drawinglayer/texture/texture.hxx index bbe620433a00..b4d78ba7a635 100644 --- a/include/drawinglayer/texture/texture.hxx +++ b/include/drawinglayer/texture/texture.hxx @@ -324,6 +324,9 @@ namespace drawinglayer double mfOffsetX; double mfOffsetY; + private: + sal_Int32 iterateTiles(::std::vector< basegfx::B2DHomMatrix >* pMatrices) const; + public: GeoTexSvxTiled( const basegfx::B2DRange& rRange, @@ -334,7 +337,8 @@ namespace drawinglayer // compare operator virtual bool operator==(const GeoTexSvx& rGeoTexSvx) const override; - void appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices); + void appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices) const; + sal_uInt32 getNumberOfTiles() const; }; } // end of namespace texture } // end of namespace drawinglayer diff --git a/vcl/win/gdi/gdiimpl.cxx b/vcl/win/gdi/gdiimpl.cxx index c5e591a2eaf7..3728755cb756 100644 --- a/vcl/win/gdi/gdiimpl.cxx +++ b/vcl/win/gdi/gdiimpl.cxx @@ -1896,9 +1896,10 @@ bool WinSalGraphicsImpl::drawPolyPolygonBezier( sal_uInt32 nPoly, const sal_uInt } void impAddB2DPolygonToGDIPlusGraphicsPathReal( - Gdiplus::GraphicsPath& rGraphicsPath, + Gdiplus::GpPath *pPath, const basegfx::B2DPolygon& rPolygon, - bool bNoLineJoin) + bool bNoLineJoin, + const basegfx::B2DVector* pLineWidths) { sal_uInt32 nCount(rPolygon.count()); @@ -1908,56 +1909,85 @@ void impAddB2DPolygonToGDIPlusGraphicsPathReal( const bool bControls(rPolygon.areControlPointsUsed()); basegfx::B2DPoint aCurr(rPolygon.getB2DPoint(0)); - for(sal_uInt32 a(0); a < nEdgeCount; a++) + if(nEdgeCount) { - const sal_uInt32 nNextIndex((a + 1) % nCount); - const basegfx::B2DPoint aNext(rPolygon.getB2DPoint(nNextIndex)); - const bool b1stControlPointUsed(bControls && rPolygon.isNextControlPointUsed(a)); - const bool b2ndControlPointUsed(bControls && rPolygon.isPrevControlPointUsed(nNextIndex)); - - if(b1stControlPointUsed || b2ndControlPointUsed) + for(sal_uInt32 a(0); a < nEdgeCount; a++) { - basegfx::B2DPoint aCa(rPolygon.getNextControlPoint(a)); - basegfx::B2DPoint aCb(rPolygon.getPrevControlPoint(nNextIndex)); - - // tdf#99165 MS Gdiplus cannot handle creating correct extra geometry for fat lines - // with LineCap or LineJoin when a bezier segment starts or ends trivial, e.g. has - // no 1st or 2nd control point, despite that these are mathematicaly correct definitions - // (basegfx can handle that). To solve, create replacement vectors to thre resp. next - // control point with 1/3rd of length (the default control vector for these cases). - // Only one of this can happen here, else the is(Next|Prev)ControlPointUsed wopuld have - // both been false. - // Caution: This error (and it's correction) might be necessary for other graphical - // sub-systems in a similar way - if(!b1stControlPointUsed) + const sal_uInt32 nNextIndex((a + 1) % nCount); + const basegfx::B2DPoint aNext(rPolygon.getB2DPoint(nNextIndex)); + const bool b1stControlPointUsed(bControls && rPolygon.isNextControlPointUsed(a)); + const bool b2ndControlPointUsed(bControls && rPolygon.isPrevControlPointUsed(nNextIndex)); + + if(b1stControlPointUsed || b2ndControlPointUsed) { - aCa = aCurr + ((aCb - aCurr) * 0.3); + basegfx::B2DPoint aCa(rPolygon.getNextControlPoint(a)); + basegfx::B2DPoint aCb(rPolygon.getPrevControlPoint(nNextIndex)); + + // tdf#99165 MS Gdiplus cannot handle creating correct extra geometry for fat lines + // with LineCap or LineJoin when a bezier segment starts or ends trivial, e.g. has + // no 1st or 2nd control point, despite that these are mathematicaly correct definitions + // (basegfx can handle that). To solve, create replacement vectors to thre resp. next + // control point with 1/3rd of length (the default control vector for these cases). + // Only one of this can happen here, else the is(Next|Prev)ControlPointUsed wopuld have + // both been false. + // Caution: This error (and it's correction) might be necessary for other graphical + // sub-systems in a similar way + if(!b1stControlPointUsed) + { + aCa = aCurr + ((aCb - aCurr) * 0.3); + } + else if(!b2ndControlPointUsed) + { + aCb = aNext + ((aCa - aNext) * 0.3); + } + + Gdiplus::DllExports::GdipAddPathBezier( + pPath, + aCurr.getX(), aCurr.getY(), + aCa.getX(), aCa.getY(), + aCb.getX(), aCb.getY(), + aNext.getX(), aNext.getY()); } - else if(!b2ndControlPointUsed) + else { - aCb = aNext + ((aCa - aNext) * 0.3); + if(pLineWidths && aCurr.equal(aNext)) + { + // For lines with no length Gdiplus unfortunately paints nothing, + // independent of LineCaps being set. This differs from e.g. SVG + // and other systems. To get geometry created, add some offset, + // based on line width to have something relative to current metrics + if(!basegfx::fTools::equalZero(pLineWidths->getX())) + { + Gdiplus::DllExports::GdipAddPathLine( + pPath, + aCurr.getX(), aCurr.getY(), + aNext.getX() + (pLineWidths->getX() * 0.1), aNext.getY()); + } + else + { + Gdiplus::DllExports::GdipAddPathLine( + pPath, + aCurr.getX(), aCurr.getY(), + aNext.getX(), aNext.getY() + (pLineWidths->getY() * 0.1)); + } + } + else + { + Gdiplus::DllExports::GdipAddPathLine( + pPath, + aCurr.getX(), aCurr.getY(), + aNext.getX(), aNext.getY()); + } } - rGraphicsPath.AddBezier( - static_cast< Gdiplus::REAL >(aCurr.getX()), static_cast< Gdiplus::REAL >(aCurr.getY()), - static_cast< Gdiplus::REAL >(aCa.getX()), static_cast< Gdiplus::REAL >(aCa.getY()), - static_cast< Gdiplus::REAL >(aCb.getX()), static_cast< Gdiplus::REAL >(aCb.getY()), - static_cast< Gdiplus::REAL >(aNext.getX()), static_cast< Gdiplus::REAL >(aNext.getY())); - } - else - { - rGraphicsPath.AddLine( - static_cast< Gdiplus::REAL >(aCurr.getX()), static_cast< Gdiplus::REAL >(aCurr.getY()), - static_cast< Gdiplus::REAL >(aNext.getX()), static_cast< Gdiplus::REAL >(aNext.getY())); - } - - if(a + 1 < nEdgeCount) - { - aCurr = aNext; - - if(bNoLineJoin) + if(a + 1 < nEdgeCount) { - rGraphicsPath.StartFigure(); + aCurr = aNext; + + if(bNoLineJoin) + { + Gdiplus::DllExports::GdipStartPathFigure(pPath); + } } } } @@ -1984,9 +2014,8 @@ bool WinSalGraphicsImpl::drawPolyPolygon( const basegfx::B2DPolyPolygon& rPolyPo aGraphicsPath.StartFigure(); } - impAddB2DPolygonToGDIPlusGraphicsPathReal(aGraphicsPath, rPolyPolygon.getB2DPolygon(a), false); - - aGraphicsPath.CloseFigure(); + impAddB2DPolygonToGDIPlusGraphicsPathReal(pPath, rPolyPolygon.getB2DPolygon(a), false, 0); + Gdiplus::DllExports::GdipClosePathFigure(pPath); } if(mrParent.getAntiAliasB2DDraw()) @@ -2098,7 +2127,7 @@ bool WinSalGraphicsImpl::drawPolyLine( } } - impAddB2DPolygonToGDIPlusGraphicsPathReal(aGraphicsPath, rPolygon, bNoLineJoin); + impAddB2DPolygonToGDIPlusGraphicsPathReal(pPath, rPolygon, bNoLineJoin, &rLineWidths); if(rPolygon.isClosed() && !bNoLineJoin) { |