From 8eeb1400c138e4e1b35c017b228fd358a34d55ed Mon Sep 17 00:00:00 2001 From: Armin Le Grand Date: Tue, 8 Dec 2009 19:05:15 +0100 Subject: aw079: #i107360# test code for trapezoid decomposer --- drawinglayer/source/processor2d/vclprocessor2d.cxx | 84 +++++++++++++--------- 1 file changed, 52 insertions(+), 32 deletions(-) diff --git a/drawinglayer/source/processor2d/vclprocessor2d.cxx b/drawinglayer/source/processor2d/vclprocessor2d.cxx index ede5aee730cf..2866bb292e58 100644 --- a/drawinglayer/source/processor2d/vclprocessor2d.cxx +++ b/drawinglayer/source/processor2d/vclprocessor2d.cxx @@ -77,6 +77,7 @@ // for test, can be removed again #include +#include ////////////////////////////////////////////////////////////////////////////// @@ -666,51 +667,70 @@ namespace drawinglayer basegfx::B2DPolyPolygon aLocalPolyPolygon(rPolygonCandidate.getB2DPolyPolygon()); aLocalPolyPolygon.transform(maCurrentTransformation); - mpOutputDevice->DrawPolyPolygon(aLocalPolyPolygon); - if(mnPolygonStrokePrimitive2D && getOptionsDrawinglayer().IsAntiAliasing()) + static bool bCheckTrapezoidDecomposition(false); + static bool bShowOutlinesThere(false); + if(bCheckTrapezoidDecomposition) { - // when AA is on and this filled polygons are the result of stroked line geometry, - // draw the geometry once extra as lines to avoid AA 'gaps' between partial polygons - mpOutputDevice->SetFillColor(); - mpOutputDevice->SetLineColor(Color(aPolygonColor)); - const sal_uInt32 nCount(aLocalPolyPolygon.count()); + // clip against discrete ViewPort + const basegfx::B2DRange& rDiscreteViewport = getViewInformation2D().getDiscreteViewport(); + aLocalPolyPolygon = basegfx::tools::clipPolyPolygonOnRange( + aLocalPolyPolygon, rDiscreteViewport, true, false); - for(sal_uInt32 a(0); a < nCount; a++) + if(aLocalPolyPolygon.count()) { - mpOutputDevice->DrawPolyLine(aLocalPolyPolygon.getB2DPolygon(a), 0.0); - } - } + // subdivide + aLocalPolyPolygon = basegfx::tools::adaptiveSubdivideByDistance( + aLocalPolyPolygon, 0.5); - static bool bTestPolygonClipping(false); - if(bTestPolygonClipping) - { - static bool bInside(true); - static bool bFilled(false); - static bool bLine(false); + // trapezoidize + const basegfx::B2DTrapezoidVector aB2DTrapezoidVector(basegfx::tools::trapezoidSubdivide( + aLocalPolyPolygon)); - basegfx::B2DRange aRange(aLocalPolyPolygon.getB2DRange()); - aRange.grow(aRange.getWidth() * -0.1); + const sal_uInt32 nCount(aB2DTrapezoidVector.size()); - if(bFilled) - { - basegfx::B2DPolyPolygon aFilledClipped(basegfx::tools::clipPolyPolygonOnRange(aLocalPolyPolygon, aRange, bInside, false)); - basegfx::BColor aRand(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0); - mpOutputDevice->SetFillColor(Color(aRand)); - mpOutputDevice->SetLineColor(); - mpOutputDevice->DrawPolyPolygon(aFilledClipped); + if(nCount) + { + basegfx::BColor aInvPolygonColor(aPolygonColor); + aInvPolygonColor.invert(); + + for(sal_uInt32 a(0); a < nCount; a++) + { + const basegfx::B2DPolygon aTempPolygon(aB2DTrapezoidVector[a].getB2DPolygon()); + + if(bShowOutlinesThere) + { + mpOutputDevice->SetFillColor(Color(aPolygonColor)); + mpOutputDevice->SetLineColor(); + } + + mpOutputDevice->DrawPolygon(aTempPolygon); + + if(bShowOutlinesThere) + { + mpOutputDevice->SetFillColor(); + mpOutputDevice->SetLineColor(Color(aInvPolygonColor)); + mpOutputDevice->DrawPolyLine(aTempPolygon, 0.0); + } + } + } } + } + else + { + mpOutputDevice->DrawPolyPolygon(aLocalPolyPolygon); - if(bLine) + if(mnPolygonStrokePrimitive2D && getOptionsDrawinglayer().IsAntiAliasing()) { - basegfx::B2DPolyPolygon aLineClipped(basegfx::tools::clipPolyPolygonOnRange(aLocalPolyPolygon, aRange, bInside, true)); - basegfx::BColor aRand(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0); + // when AA is on and this filled polygons are the result of stroked line geometry, + // draw the geometry once extra as lines to avoid AA 'gaps' between partial polygons mpOutputDevice->SetFillColor(); - mpOutputDevice->SetLineColor(Color(aRand)); + mpOutputDevice->SetLineColor(Color(aPolygonColor)); + const sal_uInt32 nCount(aLocalPolyPolygon.count()); - for(sal_uInt32 a(0); a < aLineClipped.count(); a++) + for(sal_uInt32 a(0); a < nCount; a++) { - mpOutputDevice->DrawPolyLine(aLineClipped.getB2DPolygon(a), 0.0); + mpOutputDevice->DrawPolyLine(aLocalPolyPolygon.getB2DPolygon(a), 0.0); } } } -- cgit From 33bfbf7debee613fa83d8a450226aecb5f9c672f Mon Sep 17 00:00:00 2001 From: Armin Le Grand Date: Tue, 8 Dec 2009 19:09:16 +0100 Subject: aw079: #i107346# flag for WrongSpell in SdrTextAttribute --- svx/inc/svx/sdr/attribute/sdrtextattribute.hxx | 5 ++++- svx/source/sdr/attribute/sdrtextattribute.cxx | 13 +++++++++---- svx/source/sdr/primitive2d/sdrattributecreator.cxx | 10 +++++++++- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/svx/inc/svx/sdr/attribute/sdrtextattribute.hxx b/svx/inc/svx/sdr/attribute/sdrtextattribute.hxx index 1759eb18d319..f672086ea5cd 100644 --- a/svx/inc/svx/sdr/attribute/sdrtextattribute.hxx +++ b/svx/inc/svx/sdr/attribute/sdrtextattribute.hxx @@ -81,6 +81,7 @@ namespace drawinglayer unsigned mbScroll : 1; unsigned mbInEditMode : 1; unsigned mbFixedCellHeight : 1; + unsigned mbWrongSpell : 1; public: SdrTextAttribute( @@ -99,7 +100,8 @@ namespace drawinglayer bool bBlink, bool bScroll, bool bInEditMode, - bool bFixedCellHeight); + bool bFixedCellHeight, + bool bWrongSpell); ~SdrTextAttribute(); // copy constructor and assigment operator @@ -119,6 +121,7 @@ namespace drawinglayer bool isScroll() const { return mbScroll; } bool isInEditMode() const { return mbInEditMode; } bool isFixedCellHeight() const { return mbFixedCellHeight; } + bool isWrongSpell() const { return mbWrongSpell; } const SdrFormTextAttribute* getSdrFormTextAttribute() const { return mpSdrFormTextAttribute; } sal_Int32 getTextLeftDistance() const { return maTextLeftDistance; } sal_Int32 getTextUpperDistance() const { return maTextUpperDistance; } diff --git a/svx/source/sdr/attribute/sdrtextattribute.cxx b/svx/source/sdr/attribute/sdrtextattribute.cxx index ae6204d15bef..3afc03d1600d 100644 --- a/svx/source/sdr/attribute/sdrtextattribute.cxx +++ b/svx/source/sdr/attribute/sdrtextattribute.cxx @@ -65,7 +65,8 @@ namespace drawinglayer bool bBlink, bool bScroll, bool bInEditMode, - bool bFixedCellHeight) + bool bFixedCellHeight, + bool bWrongSpell) : mpSdrText(&rSdrText), maOutlinerParaObject(rOutlinerParaObject), mpSdrFormTextAttribute(0), @@ -82,7 +83,8 @@ namespace drawinglayer mbBlink(bBlink), mbScroll(bScroll), mbInEditMode(bInEditMode), - mbFixedCellHeight(bFixedCellHeight) + mbFixedCellHeight(bFixedCellHeight), + mbWrongSpell(bWrongSpell) { if(XFT_NONE != eFormTextStyle) { @@ -123,7 +125,8 @@ namespace drawinglayer mbBlink(rCandidate.isBlink()), mbScroll(rCandidate.isScroll()), mbInEditMode(rCandidate.isInEditMode()), - mbFixedCellHeight(rCandidate.isFixedCellHeight()) + mbFixedCellHeight(rCandidate.isFixedCellHeight()), + mbWrongSpell(rCandidate.isWrongSpell()) { if(rCandidate.getSdrFormTextAttribute()) { @@ -164,6 +167,7 @@ namespace drawinglayer mbScroll = rCandidate.isScroll(); mbInEditMode = rCandidate.isInEditMode(); mbFixedCellHeight = rCandidate.isFixedCellHeight(); + mbWrongSpell = rCandidate.isWrongSpell(); return *this; } @@ -197,7 +201,8 @@ namespace drawinglayer && isBlink() == rCandidate.isBlink() && isScroll() == rCandidate.isScroll() && isInEditMode() == rCandidate.isInEditMode() - && isFixedCellHeight() == rCandidate.isFixedCellHeight()); + && isFixedCellHeight() == rCandidate.isFixedCellHeight() + && isWrongSpell() == rCandidate.isWrongSpell()); } void SdrTextAttribute::getBlinkTextTiming(drawinglayer::animation::AnimationEntryList& rAnimList) const diff --git a/svx/source/sdr/primitive2d/sdrattributecreator.cxx b/svx/source/sdr/primitive2d/sdrattributecreator.cxx index 4e57166b4723..f778cccdee40 100644 --- a/svx/source/sdr/primitive2d/sdrattributecreator.cxx +++ b/svx/source/sdr/primitive2d/sdrattributecreator.cxx @@ -77,6 +77,9 @@ #include #include #include +#include +#include +#include ////////////////////////////////////////////////////////////////////////////// @@ -523,6 +526,10 @@ namespace drawinglayer const SdrFitToSizeType eFit(rTextObj.GetFitToSize()); const SdrTextAniKind eAniKind(rTextObj.GetTextAniKind()); + // #i107346# + const SdrOutliner& rDrawTextOutliner = rText.GetModel()->GetDrawOutliner(&rTextObj); + const bool bWrongSpell(rDrawTextOutliner.GetControlWord() & EE_CNTRL_ONLINESPELLING); + pRetval = new attribute::SdrTextAttribute( rText, aOutlinerParaObject, @@ -539,7 +546,8 @@ namespace drawinglayer SDRTEXTANI_BLINK == eAniKind, SDRTEXTANI_SCROLL == eAniKind || SDRTEXTANI_ALTERNATE == eAniKind || SDRTEXTANI_SLIDE == eAniKind, bInEditMode, - ((const SdrTextFixedCellHeightItem&)rSet.Get(SDRATTR_TEXT_USEFIXEDCELLHEIGHT)).GetValue()); + ((const SdrTextFixedCellHeightItem&)rSet.Get(SDRATTR_TEXT_USEFIXEDCELLHEIGHT)).GetValue(), + bWrongSpell); } return pRetval; -- cgit From 9f6018ec1472d7e4f2f26b300d8c00b09fda1fe8 Mon Sep 17 00:00:00 2001 From: Armin Le Grand Date: Wed, 6 Jan 2010 11:29:46 +0100 Subject: aw079: #i107500# changed 3D renderer to be able to render overlapping transparent parts from back to front (Z-sorted) --- .../processor3d/defaultprocessor3d.hxx | 13 +- .../processor3d/zbufferprocessor3d.hxx | 20 +- .../source/primitive2d/sceneprimitive2d.cxx | 5 +- drawinglayer/source/processor2d/vclprocessor2d.cxx | 72 ++++- .../source/processor3d/defaultprocessor3d.cxx | 54 ++-- .../source/processor3d/zbufferprocessor3d.cxx | 331 ++++++++++++++------- 6 files changed, 319 insertions(+), 176 deletions(-) diff --git a/drawinglayer/inc/drawinglayer/processor3d/defaultprocessor3d.hxx b/drawinglayer/inc/drawinglayer/processor3d/defaultprocessor3d.hxx index e965d22ab880..d0f886cca703 100644 --- a/drawinglayer/inc/drawinglayer/processor3d/defaultprocessor3d.hxx +++ b/drawinglayer/inc/drawinglayer/processor3d/defaultprocessor3d.hxx @@ -41,6 +41,7 @@ #include #include #include +#include ////////////////////////////////////////////////////////////////////////////// // predefines @@ -90,14 +91,17 @@ namespace drawinglayer basegfx::BColorModifierStack maBColorModifierStack; // the current active texture - texture::GeoTexSvx* mpGeoTexSvx; + boost::shared_ptr< texture::GeoTexSvx > mpGeoTexSvx; // the current active transparence texture - texture::GeoTexSvx* mpTransparenceGeoTexSvx; + boost::shared_ptr< texture::GeoTexSvx > mpTransparenceGeoTexSvx; // SvtOptionsDrawinglayer incarnation to react on diverse settings const SvtOptionsDrawinglayer maDrawinglayerOpt; + // counter for entered transparence textures + sal_uInt32 mnTransparenceCounter; + // bitfield unsigned mbModulate : 1; unsigned mbFilter : 1; @@ -135,8 +139,9 @@ namespace drawinglayer // data read access renderer stuff const basegfx::BColorModifierStack& getBColorModifierStack() const { return maBColorModifierStack; } - const texture::GeoTexSvx* getGeoTexSvx() const { return mpGeoTexSvx; } - const texture::GeoTexSvx* getTransparenceGeoTexSvx() const { return mpTransparenceGeoTexSvx; } + const boost::shared_ptr< texture::GeoTexSvx >& getGeoTexSvx() const { return mpGeoTexSvx; } + const boost::shared_ptr< texture::GeoTexSvx >& getTransparenceGeoTexSvx() const { return mpTransparenceGeoTexSvx; } + sal_uInt32 getTransparenceCounter() const { return mnTransparenceCounter; } bool getModulate() const { return mbModulate; } bool getFilter() const { return mbFilter; } bool getSimpleTextureActive() const { return mbSimpleTextureActive; } diff --git a/drawinglayer/inc/drawinglayer/processor3d/zbufferprocessor3d.hxx b/drawinglayer/inc/drawinglayer/processor3d/zbufferprocessor3d.hxx index d2ef8bd7f249..b2e09205dba9 100644 --- a/drawinglayer/inc/drawinglayer/processor3d/zbufferprocessor3d.hxx +++ b/drawinglayer/inc/drawinglayer/processor3d/zbufferprocessor3d.hxx @@ -58,6 +58,7 @@ namespace drawinglayer { } class ZBufferRasterConverter3D; +class RasterPrimitive3D; ////////////////////////////////////////////////////////////////////////////// @@ -81,21 +82,15 @@ namespace drawinglayer // will switch it off while e.g. 2 will use 2x2 pixels for each pixel to create sal_uInt16 mnAntiAlialize; - // bitfield - // a combination of bools to allow two-pass rendering to render - // the transparent parts in the 2nd run (if any) as needed for Z-Buffer - unsigned mbProcessTransparent : 1; - unsigned mbContainsTransparent : 1; - + // remembered RasterPrimitive3D's which need to be painted back to front + // for transparent 3D parts + std::vector< RasterPrimitive3D >* mpRasterPrimitive3Ds; ////////////////////////////////////////////////////////////////////////////// // rasterconversions for filled and non-filled polygons virtual void rasterconvertB3DPolygon(const attribute::MaterialAttribute3D& rMaterial, const basegfx::B3DPolygon& rHairline) const; virtual void rasterconvertB3DPolyPolygon(const attribute::MaterialAttribute3D& rMaterial, const basegfx::B3DPolyPolygon& rFill) const; - // the processing method for a single, known primitive - virtual void processBasePrimitive3D(const primitive3d::BasePrimitive3D& rBasePrimitive); - public: ZBufferProcessor3D( const geometry::ViewInformation3D& rViewInformation3D, @@ -108,12 +103,7 @@ namespace drawinglayer sal_uInt16 nAntiAlialize); virtual ~ZBufferProcessor3D(); - // helpers for drawing transparent parts in 2nd run. To use this - // processor, call processNonTransparent and then processTransparent - // with the same primitives. The 2nd call will only do something, - // when transparent parts are contained - void processNonTransparent(const primitive3d::Primitive3DSequence& rSource); - void processTransparent(const primitive3d::Primitive3DSequence& rSource); + void finish(); // get the result as bitmapEx BitmapEx getBitmapEx() const; diff --git a/drawinglayer/source/primitive2d/sceneprimitive2d.cxx b/drawinglayer/source/primitive2d/sceneprimitive2d.cxx index ad36a40ea996..9c32c50e7160 100644 --- a/drawinglayer/source/primitive2d/sceneprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/sceneprimitive2d.cxx @@ -235,8 +235,9 @@ namespace drawinglayer aUnitVisibleRange, nOversampleValue); - aZBufferProcessor3D.processNonTransparent(getChildren3D()); - aZBufferProcessor3D.processTransparent(getChildren3D()); + aZBufferProcessor3D.process(getChildren3D()); + aZBufferProcessor3D.finish(); + const_cast< ScenePrimitive2D* >(this)->maOldRenderedBitmap = aZBufferProcessor3D.getBitmapEx(); const Size aBitmapSizePixel(maOldRenderedBitmap.GetSizePixel()); diff --git a/drawinglayer/source/processor2d/vclprocessor2d.cxx b/drawinglayer/source/processor2d/vclprocessor2d.cxx index 2866bb292e58..bb0bdfe34154 100644 --- a/drawinglayer/source/processor2d/vclprocessor2d.cxx +++ b/drawinglayer/source/processor2d/vclprocessor2d.cxx @@ -337,17 +337,69 @@ namespace drawinglayer basegfx::B2DPolygon aLocalPolygon(rPolygonCandidate.getB2DPolygon()); aLocalPolygon.transform(maCurrentTransformation); - if(bPixelBased && getOptionsDrawinglayer().IsAntiAliasing() && getOptionsDrawinglayer().IsSnapHorVerLinesToDiscrete()) + static bool bCheckTrapezoidDecomposition(false); + static bool bShowOutlinesThere(false); + if(bCheckTrapezoidDecomposition) { - // #i98289# - // when a Hairline is painted and AntiAliasing is on the option SnapHorVerLinesToDiscrete - // allows to suppress AntiAliasing for pure horizontal or vertical lines. This is done since - // not-AntiAliased such lines look more pleasing to the eye (e.g. 2D chart content). This - // NEEDS to be done in discrete coordinates, so only useful for pixel based rendering. - aLocalPolygon = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aLocalPolygon); + // clip against discrete ViewPort + const basegfx::B2DRange& rDiscreteViewport = getViewInformation2D().getDiscreteViewport(); + basegfx::B2DPolyPolygon aLocalPolyPolygon(basegfx::tools::clipPolygonOnRange( + aLocalPolygon, rDiscreteViewport, true, false)); + + if(aLocalPolyPolygon.count()) + { + // subdivide + aLocalPolyPolygon = basegfx::tools::adaptiveSubdivideByDistance( + aLocalPolyPolygon, 0.5); + + // trapezoidize + static double fLineWidth(2.0); + basegfx::B2DTrapezoidVector aB2DTrapezoidVector; + basegfx::tools::createLineTrapezoidFromB2DPolyPolygon(aB2DTrapezoidVector, aLocalPolyPolygon, fLineWidth); + + const sal_uInt32 nCount(aB2DTrapezoidVector.size()); + + if(nCount) + { + basegfx::BColor aInvPolygonColor(aHairlineColor); + aInvPolygonColor.invert(); + + for(sal_uInt32 a(0); a < nCount; a++) + { + const basegfx::B2DPolygon aTempPolygon(aB2DTrapezoidVector[a].getB2DPolygon()); + + if(bShowOutlinesThere) + { + mpOutputDevice->SetFillColor(Color(aHairlineColor)); + mpOutputDevice->SetLineColor(); + } + + mpOutputDevice->DrawPolygon(aTempPolygon); + + if(bShowOutlinesThere) + { + mpOutputDevice->SetFillColor(); + mpOutputDevice->SetLineColor(Color(aInvPolygonColor)); + mpOutputDevice->DrawPolyLine(aTempPolygon, 0.0); + } + } + } + } } + else + { + if(bPixelBased && getOptionsDrawinglayer().IsAntiAliasing() && getOptionsDrawinglayer().IsSnapHorVerLinesToDiscrete()) + { + // #i98289# + // when a Hairline is painted and AntiAliasing is on the option SnapHorVerLinesToDiscrete + // allows to suppress AntiAliasing for pure horizontal or vertical lines. This is done since + // not-AntiAliased such lines look more pleasing to the eye (e.g. 2D chart content). This + // NEEDS to be done in discrete coordinates, so only useful for pixel based rendering. + aLocalPolygon = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aLocalPolygon); + } - mpOutputDevice->DrawPolyLine(aLocalPolygon, 0.0); + mpOutputDevice->DrawPolyLine(aLocalPolygon, 0.0); + } } // direct draw of transformed BitmapEx primitive @@ -684,8 +736,8 @@ namespace drawinglayer aLocalPolyPolygon, 0.5); // trapezoidize - const basegfx::B2DTrapezoidVector aB2DTrapezoidVector(basegfx::tools::trapezoidSubdivide( - aLocalPolyPolygon)); + basegfx::B2DTrapezoidVector aB2DTrapezoidVector; + basegfx::tools::trapezoidSubdivide(aB2DTrapezoidVector, aLocalPolyPolygon); const sal_uInt32 nCount(aB2DTrapezoidVector.size()); diff --git a/drawinglayer/source/processor3d/defaultprocessor3d.cxx b/drawinglayer/source/processor3d/defaultprocessor3d.cxx index d9194ca4b5eb..d4ed86de3b6e 100644 --- a/drawinglayer/source/processor3d/defaultprocessor3d.cxx +++ b/drawinglayer/source/processor3d/defaultprocessor3d.cxx @@ -71,8 +71,8 @@ namespace drawinglayer // rescue values const bool bOldModulate(getModulate()); mbModulate = rPrimitive.getModulate(); const bool bOldFilter(getFilter()); mbFilter = rPrimitive.getFilter(); - const bool bOldSimpleTextureActive(mbSimpleTextureActive); - texture::GeoTexSvx* pOldTex = (bTransparence) ? mpTransparenceGeoTexSvx : mpGeoTexSvx; + const bool bOldSimpleTextureActive(getSimpleTextureActive()); + boost::shared_ptr< texture::GeoTexSvx > pOldTex = (bTransparence) ? mpTransparenceGeoTexSvx : mpGeoTexSvx; // create texture const attribute::FillGradientAttribute& rFillGradient = rPrimitive.getGradient(); @@ -82,7 +82,7 @@ namespace drawinglayer const basegfx::BColor aStart(rFillGradient.getStartColor()); const basegfx::BColor aEnd(rFillGradient.getEndColor()); const sal_uInt32 nMaxSteps(sal_uInt32((aStart.getMaximumDistance(aEnd) * 127.5) + 0.5)); - texture::GeoTexSvx* pNewTex = 0L; + boost::shared_ptr< texture::GeoTexSvx > pNewTex; if(nMaxSteps) { @@ -106,32 +106,32 @@ namespace drawinglayer { case attribute::GRADIENTSTYLE_LINEAR: { - pNewTex = new texture::GeoTexSvxGradientLinear(aOutlineRange, aStart, aEnd, nSteps, rFillGradient.getBorder(), -rFillGradient.getAngle()); + pNewTex.reset(new texture::GeoTexSvxGradientLinear(aOutlineRange, aStart, aEnd, nSteps, rFillGradient.getBorder(), -rFillGradient.getAngle())); break; } case attribute::GRADIENTSTYLE_AXIAL: { - pNewTex = new texture::GeoTexSvxGradientAxial(aOutlineRange, aStart, aEnd, nSteps, rFillGradient.getBorder(), -rFillGradient.getAngle()); + pNewTex.reset(new texture::GeoTexSvxGradientAxial(aOutlineRange, aStart, aEnd, nSteps, rFillGradient.getBorder(), -rFillGradient.getAngle())); break; } case attribute::GRADIENTSTYLE_RADIAL: { - pNewTex = new texture::GeoTexSvxGradientRadial(aOutlineRange, aStart, aEnd, nSteps, rFillGradient.getBorder(), rFillGradient.getOffsetX(), rFillGradient.getOffsetY()); + pNewTex.reset(new texture::GeoTexSvxGradientRadial(aOutlineRange, aStart, aEnd, nSteps, rFillGradient.getBorder(), rFillGradient.getOffsetX(), rFillGradient.getOffsetY())); break; } case attribute::GRADIENTSTYLE_ELLIPTICAL: { - pNewTex = new texture::GeoTexSvxGradientElliptical(aOutlineRange, aStart, aEnd, nSteps, rFillGradient.getBorder(), rFillGradient.getOffsetX(), rFillGradient.getOffsetY(), -rFillGradient.getAngle()); + pNewTex.reset(new texture::GeoTexSvxGradientElliptical(aOutlineRange, aStart, aEnd, nSteps, rFillGradient.getBorder(), rFillGradient.getOffsetX(), rFillGradient.getOffsetY(), -rFillGradient.getAngle())); break; } case attribute::GRADIENTSTYLE_SQUARE: { - pNewTex = new texture::GeoTexSvxGradientSquare(aOutlineRange, aStart, aEnd, nSteps, rFillGradient.getBorder(), rFillGradient.getOffsetX(), rFillGradient.getOffsetY(), -rFillGradient.getAngle()); + pNewTex.reset(new texture::GeoTexSvxGradientSquare(aOutlineRange, aStart, aEnd, nSteps, rFillGradient.getBorder(), rFillGradient.getOffsetX(), rFillGradient.getOffsetY(), -rFillGradient.getAngle())); break; } case attribute::GRADIENTSTYLE_RECT: { - pNewTex = new texture::GeoTexSvxGradientRect(aOutlineRange, aStart, aEnd, nSteps, rFillGradient.getBorder(), rFillGradient.getOffsetX(), rFillGradient.getOffsetY(), -rFillGradient.getAngle()); + pNewTex.reset(new texture::GeoTexSvxGradientRect(aOutlineRange, aStart, aEnd, nSteps, rFillGradient.getBorder(), rFillGradient.getOffsetX(), rFillGradient.getOffsetY(), -rFillGradient.getAngle())); break; } } @@ -141,7 +141,7 @@ namespace drawinglayer else { // no color distance -> same color, use simple texture - pNewTex = new texture::GeoTexSvxMono(aStart, 1.0 - aStart.luminance()); + pNewTex.reset(new texture::GeoTexSvxMono(aStart, 1.0 - aStart.luminance())); mbSimpleTextureActive = true; } @@ -158,9 +158,6 @@ namespace drawinglayer // process sub-list process(rSubSequence); - // delete texture - delete pNewTex; - // restore values mbModulate = bOldModulate; mbFilter = bOldFilter; @@ -186,7 +183,7 @@ namespace drawinglayer // rescue values const bool bOldModulate(getModulate()); mbModulate = rPrimitive.getModulate(); const bool bOldFilter(getFilter()); mbFilter = rPrimitive.getFilter(); - texture::GeoTexSvx* pOldTex = mpGeoTexSvx; + boost::shared_ptr< texture::GeoTexSvx > pOldTex = mpGeoTexSvx; // calculate logic pixel size in object coordinates. Create transformation view // to object by inverting ObjectToView @@ -206,15 +203,11 @@ namespace drawinglayer const double fLogicTexSize(fLogicTexSizeX > fLogicTexSizeY ? fLogicTexSizeX : fLogicTexSizeY); // create texture and set - texture::GeoTexSvxMultiHatch* pNewTex = new texture::GeoTexSvxMultiHatch(rPrimitive, fLogicTexSize); - mpGeoTexSvx = pNewTex; + mpGeoTexSvx.reset(new texture::GeoTexSvxMultiHatch(rPrimitive, fLogicTexSize)); // process sub-list process(rSubSequence); - // delete texture - delete mpGeoTexSvx; - // restore values mbModulate = bOldModulate; mbFilter = bOldFilter; @@ -231,32 +224,29 @@ namespace drawinglayer // rescue values const bool bOldModulate(getModulate()); mbModulate = rPrimitive.getModulate(); const bool bOldFilter(getFilter()); mbFilter = rPrimitive.getFilter(); - texture::GeoTexSvx* pOldTex = mpGeoTexSvx; + boost::shared_ptr< texture::GeoTexSvx > pOldTex = mpGeoTexSvx; // create texture const attribute::FillBitmapAttribute& rFillBitmapAttribute = rPrimitive.getBitmap(); if(rFillBitmapAttribute.getTiling()) { - mpGeoTexSvx = new texture::GeoTexSvxBitmapTiled( + mpGeoTexSvx.reset(new texture::GeoTexSvxBitmapTiled( rFillBitmapAttribute.getBitmap(), rFillBitmapAttribute.getTopLeft() * rPrimitive.getTextureSize(), - rFillBitmapAttribute.getSize() * rPrimitive.getTextureSize()); + rFillBitmapAttribute.getSize() * rPrimitive.getTextureSize())); } else { - mpGeoTexSvx = new texture::GeoTexSvxBitmap( + mpGeoTexSvx.reset(new texture::GeoTexSvxBitmap( rFillBitmapAttribute.getBitmap(), rFillBitmapAttribute.getTopLeft() * rPrimitive.getTextureSize(), - rFillBitmapAttribute.getSize() * rPrimitive.getTextureSize()); + rFillBitmapAttribute.getSize() * rPrimitive.getTextureSize())); } // process sub-list process(rSubSequence); - // delete texture - delete mpGeoTexSvx; - // restore values mbModulate = bOldModulate; mbFilter = bOldFilter; @@ -320,7 +310,7 @@ namespace drawinglayer if(bPaintIt) { // get rid of texture coordinates if there is no texture - if(aFill.areTextureCoordinatesUsed() && !getGeoTexSvx() && !getTransparenceGeoTexSvx()) + if(aFill.areTextureCoordinatesUsed() && !getGeoTexSvx().get() && !getTransparenceGeoTexSvx().get()) { aFill.clearTextureCoordinates(); } @@ -507,7 +497,9 @@ namespace drawinglayer { // AlphaTexturePrimitive3D const primitive3d::AlphaTexturePrimitive3D& rPrimitive = static_cast< const primitive3d::AlphaTexturePrimitive3D& >(rBasePrimitive); + mnTransparenceCounter++; impRenderGradientTexturePrimitive3D(rPrimitive, true); + mnTransparenceCounter--; break; } case PRIMITIVE3D_ID_MODIFIEDCOLORPRIMITIVE3D : @@ -556,8 +548,10 @@ namespace drawinglayer mrSdrLightingAttribute(rSdrLightingAttribute), maRasterRange(), maBColorModifierStack(), - mpGeoTexSvx(0), - mpTransparenceGeoTexSvx(0), + mpGeoTexSvx(), + mpTransparenceGeoTexSvx(), + maDrawinglayerOpt(), + mnTransparenceCounter(0), mbModulate(false), mbFilter(false), mbSimpleTextureActive(false) diff --git a/drawinglayer/source/processor3d/zbufferprocessor3d.cxx b/drawinglayer/source/processor3d/zbufferprocessor3d.cxx index b5a59e10a119..9346958f6b69 100644 --- a/drawinglayer/source/processor3d/zbufferprocessor3d.cxx +++ b/drawinglayer/source/processor3d/zbufferprocessor3d.cxx @@ -50,6 +50,7 @@ #include #include #include +#include ////////////////////////////////////////////////////////////////////////////// @@ -233,14 +234,14 @@ private: basegfx::B2DPoint aTexCoor(0.0, 0.0); getTextureCoor(aTexCoor); - if(mrProcessor.getGeoTexSvx()) + if(mrProcessor.getGeoTexSvx().get()) { // calc color in spot. This may also set to invisible already when // e.g. bitmap textures have transparent parts mrProcessor.getGeoTexSvx()->modifyBColor(aTexCoor, rColor, fOpacity); } - if(basegfx::fTools::more(fOpacity, 0.0) && mrProcessor.getTransparenceGeoTexSvx()) + if(basegfx::fTools::more(fOpacity, 0.0) && mrProcessor.getTransparenceGeoTexSvx().get()) { // calc opacity. Object has a 2nd texture, a transparence texture mrProcessor.getTransparenceGeoTexSvx()->modifyOpacity(aTexCoor, fOpacity); @@ -249,7 +250,7 @@ private: if(basegfx::fTools::more(fOpacity, 0.0)) { - if(mrProcessor.getGeoTexSvx()) + if(mrProcessor.getGeoTexSvx().get()) { if(mbUseNrm) { @@ -317,9 +318,9 @@ private: mbModifyColor = mrProcessor.getBColorModifierStack().count(); mbHasTexCoor = SCANLINE_EMPTY_INDEX != rA.getTextureIndex() && SCANLINE_EMPTY_INDEX != rB.getTextureIndex(); mbHasInvTexCoor = SCANLINE_EMPTY_INDEX != rA.getInverseTextureIndex() && SCANLINE_EMPTY_INDEX != rB.getInverseTextureIndex(); - const bool bTextureActive(mrProcessor.getGeoTexSvx() || mrProcessor.getTransparenceGeoTexSvx()); + const bool bTextureActive(mrProcessor.getGeoTexSvx().get() || mrProcessor.getTransparenceGeoTexSvx().get()); mbUseTex = bTextureActive && (mbHasTexCoor || mbHasInvTexCoor || mrProcessor.getSimpleTextureActive()); - const bool bUseColorTex(mbUseTex && mrProcessor.getGeoTexSvx()); + const bool bUseColorTex(mbUseTex && mrProcessor.getGeoTexSvx().get()); const bool bNeedNrmOrCol(!bUseColorTex || (bUseColorTex && mrProcessor.getModulate())); mbUseNrm = bNeedNrmOrCol && SCANLINE_EMPTY_INDEX != rA.getNormalIndex() && SCANLINE_EMPTY_INDEX != rB.getNormalIndex(); mbUseCol = !mbUseNrm && bNeedNrmOrCol && SCANLINE_EMPTY_INDEX != rA.getColorIndex() && SCANLINE_EMPTY_INDEX != rB.getColorIndex(); @@ -434,7 +435,7 @@ void ZBufferRasterConverter3D::processLineSpan(const basegfx::RasterConversionLi if(nOpacity >= 0x00ff) { - // full opacity, set z and color + // full opacity (not transparent), set z and color rOldZ = nNewZ; mrBuffer.getBPixel(nScanlineIndex) = basegfx::BPixel(aNewColor, 0xff); } @@ -444,8 +445,8 @@ void ZBufferRasterConverter3D::processLineSpan(const basegfx::RasterConversionLi if(rDest.getOpacity()) { - // both transparent, mix color based on front pixel's opacity - // (the new one) + // mix new color by using + // color' = color * (1 - opacity) + newcolor * opacity const sal_uInt16 nTransparence(0x0100 - nOpacity); rDest.setRed((sal_uInt8)(((rDest.getRed() * nTransparence) + ((sal_uInt16)(255.0 * aNewColor.getRed()) * nOpacity)) >> 8)); rDest.setGreen((sal_uInt8)(((rDest.getGreen() * nTransparence) + ((sal_uInt16)(255.0 * aNewColor.getGreen()) * nOpacity)) >> 8)); @@ -453,14 +454,14 @@ void ZBufferRasterConverter3D::processLineSpan(const basegfx::RasterConversionLi if(0xff != rDest.getOpacity()) { - // destination is also transparent, mix opacities by weighting - // old opacity with new pixel's transparence and adding new opacity - rDest.setOpacity((sal_uInt8)(((rDest.getOpacity() * nTransparence) >> 8) + nOpacity)); + // both are transparent, mix new opacity by using + // opacity = newopacity * (1 - oldopacity) + oldopacity + rDest.setOpacity(((sal_uInt8)((nOpacity * (0x0100 - rDest.getOpacity())) >> 8)) + rDest.getOpacity()); } } else { - // dest is not visible. Set color. + // dest is unused, set color rDest = basegfx::BPixel(aNewColor, (sal_uInt8)nOpacity); } } @@ -477,135 +478,162 @@ void ZBufferRasterConverter3D::processLineSpan(const basegfx::RasterConversionLi } } +////////////////////////////////////////////////////////////////////////////// +// helper class to buffer output for transparent rasterprimitives (filled areas +// and lines) until the end of processing. To ensure correct transparent +// visualisation, ZBuffers require to not set Z and to mix with the transparent +// color. If transparent rasterprimitives overlap, it gets necessary to +// paint transparent rasterprimitives from back to front to ensure that the +// mixing happens from back to front. For that purpose, transparent +// rasterprimitives are held in this class during the processing run, remember +// all data and will be rendered + +class RasterPrimitive3D +{ +private: + boost::shared_ptr< drawinglayer::texture::GeoTexSvx > mpGeoTexSvx; + boost::shared_ptr< drawinglayer::texture::GeoTexSvx > mpTransparenceGeoTexSvx; + drawinglayer::attribute::MaterialAttribute3D maMaterial; + basegfx::B3DPolyPolygon maPolyPolygon; + sal_uInt32 mfCenterZ; + + // bitfield + bool mbModulate : 1; + bool mbFilter : 1; + bool mbSimpleTextureActive : 1; + bool mbIsLine : 1; + +public: + RasterPrimitive3D( + const boost::shared_ptr< drawinglayer::texture::GeoTexSvx >& pGeoTexSvx, + const boost::shared_ptr< drawinglayer::texture::GeoTexSvx >& pTransparenceGeoTexSvx, + const drawinglayer::attribute::MaterialAttribute3D& rMaterial, + const basegfx::B3DPolyPolygon& rPolyPolygon, + bool bModulate, + bool bFilter, + bool bSimpleTextureActive, + bool bIsLine) + : mpGeoTexSvx(pGeoTexSvx), + mpTransparenceGeoTexSvx(pTransparenceGeoTexSvx), + maMaterial(rMaterial), + maPolyPolygon(rPolyPolygon), + mfCenterZ(basegfx::tools::getRange(rPolyPolygon).getCenter().getZ()), + mbModulate(bModulate), + mbFilter(bFilter), + mbSimpleTextureActive(bSimpleTextureActive), + mbIsLine(bIsLine) + { + } + + RasterPrimitive3D& operator=(const RasterPrimitive3D& rComp) + { + mpGeoTexSvx = rComp.mpGeoTexSvx; + mpTransparenceGeoTexSvx = rComp.mpTransparenceGeoTexSvx; + maMaterial = rComp.maMaterial; + maPolyPolygon = rComp.maPolyPolygon; + mfCenterZ = rComp.mfCenterZ; + mbModulate = rComp.mbModulate; + mbFilter = rComp.mbFilter; + mbSimpleTextureActive = rComp.mbSimpleTextureActive; + mbIsLine = rComp.mbIsLine; + + return *this; + } + + bool operator<(const RasterPrimitive3D& rComp) const + { + return mfCenterZ < rComp.mfCenterZ; + } + + const boost::shared_ptr< drawinglayer::texture::GeoTexSvx >& getGeoTexSvx() const { return mpGeoTexSvx; } + const boost::shared_ptr< drawinglayer::texture::GeoTexSvx >& getTransparenceGeoTexSvx() const { return mpTransparenceGeoTexSvx; } + const drawinglayer::attribute::MaterialAttribute3D& getMaterial() const { return maMaterial; } + const basegfx::B3DPolyPolygon& getPolyPolygon() const { return maPolyPolygon; } + bool getModulate() const { return mbModulate; } + bool getFilter() const { return mbFilter; } + bool getSimpleTextureActive() const { return mbSimpleTextureActive; } + bool getIsLine() const { return mbIsLine; } +}; + ////////////////////////////////////////////////////////////////////////////// namespace drawinglayer { namespace processor3d { - // the processing method for a single, known primitive - void ZBufferProcessor3D::processBasePrimitive3D(const primitive3d::BasePrimitive3D& rBasePrimitive) + void ZBufferProcessor3D::rasterconvertB3DPolygon(const attribute::MaterialAttribute3D& rMaterial, const basegfx::B3DPolygon& rHairline) const { - // it is a BasePrimitive3D implementation, use getPrimitiveID() call for switch - switch(rBasePrimitive.getPrimitiveID()) + if(mpBZPixelRaster) { - case PRIMITIVE3D_ID_ALPHATEXTUREPRIMITIVE3D : + if(getTransparenceCounter()) { - // AlphaTexturePrimitive3D - const primitive3d::AlphaTexturePrimitive3D& rPrimitive = static_cast< const primitive3d::AlphaTexturePrimitive3D& >(rBasePrimitive); - - if(mbProcessTransparent) - { - impRenderGradientTexturePrimitive3D(rPrimitive, true); - } - else + // transparent output; record for later sorting and painting from + // back to front + if(!mpRasterPrimitive3Ds) { - mbContainsTransparent = true; + const_cast< ZBufferProcessor3D* >(this)->mpRasterPrimitive3Ds = new std::vector< RasterPrimitive3D >; } - break; - } - case PRIMITIVE3D_ID_POLYGONHAIRLINEPRIMITIVE3D : - { - // directdraw of PolygonHairlinePrimitive3D - const primitive3d::PolygonHairlinePrimitive3D& rPrimitive = static_cast< const primitive3d::PolygonHairlinePrimitive3D& >(rBasePrimitive); - // do something when either not transparent and no transMap, or transparent and a TransMap - if((bool)mbProcessTransparent == (0 != getTransparenceGeoTexSvx())) - { - impRenderPolygonHairlinePrimitive3D(rPrimitive); - } - break; + mpRasterPrimitive3Ds->push_back(RasterPrimitive3D( + getGeoTexSvx(), + getTransparenceGeoTexSvx(), + rMaterial, + basegfx::B3DPolyPolygon(rHairline), + getModulate(), + getFilter(), + getSimpleTextureActive(), + true)); } - case PRIMITIVE3D_ID_POLYPOLYGONMATERIALPRIMITIVE3D : + else { - // directdraw of PolyPolygonMaterialPrimitive3D - const primitive3d::PolyPolygonMaterialPrimitive3D& rPrimitive = static_cast< const primitive3d::PolyPolygonMaterialPrimitive3D& >(rBasePrimitive); + // do rasterconversion + mpZBufferRasterConverter3D->setCurrentMaterial(rMaterial); - // do something when either not transparent and no transMap, or transparent and a TransMap - if((bool)mbProcessTransparent == (0 != getTransparenceGeoTexSvx())) + if(mnAntiAlialize > 1) { - impRenderPolyPolygonMaterialPrimitive3D(rPrimitive); - } - break; - } - default: - { - // use the DefaultProcessor3D::processBasePrimitive3D() - DefaultProcessor3D::processBasePrimitive3D(rBasePrimitive); - break; - } - } - } - - void ZBufferProcessor3D::processNonTransparent(const primitive3d::Primitive3DSequence& rSource) - { - if(mpBZPixelRaster) - { - mbProcessTransparent = false; - mbContainsTransparent = false; - process(rSource); - } - } - - void ZBufferProcessor3D::processTransparent(const primitive3d::Primitive3DSequence& rSource) - { - if(mpBZPixelRaster && mbContainsTransparent) - { - mbProcessTransparent = true; - process(rSource); - } - } + const bool bForceLineSnap(getOptionsDrawinglayer().IsAntiAliasing() && getOptionsDrawinglayer().IsSnapHorVerLinesToDiscrete()); - void ZBufferProcessor3D::rasterconvertB3DPolygon(const attribute::MaterialAttribute3D& rMaterial, const basegfx::B3DPolygon& rHairline) const - { - if(mpBZPixelRaster) - { - mpZBufferRasterConverter3D->setCurrentMaterial(rMaterial); + if(bForceLineSnap) + { + basegfx::B3DHomMatrix aTransform; + basegfx::B3DPolygon aSnappedHairline(rHairline); + const double fScaleDown(1.0 / mnAntiAlialize); + const double fScaleUp(mnAntiAlialize); - if(mnAntiAlialize > 1) - { - const bool bForceLineSnap(getOptionsDrawinglayer().IsAntiAliasing() && getOptionsDrawinglayer().IsSnapHorVerLinesToDiscrete()); + // take oversampling out + aTransform.scale(fScaleDown, fScaleDown, 1.0); + aSnappedHairline.transform(aTransform); - if(bForceLineSnap) - { - basegfx::B3DHomMatrix aTransform; - basegfx::B3DPolygon aSnappedHairline(rHairline); - const double fScaleDown(1.0 / mnAntiAlialize); - const double fScaleUp(mnAntiAlialize); + // snap to integer + aSnappedHairline = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aSnappedHairline); - // take oversampling out - aTransform.scale(fScaleDown, fScaleDown, 1.0); - aSnappedHairline.transform(aTransform); + // add oversampling again + aTransform.identity(); + aTransform.scale(fScaleUp, fScaleUp, 1.0); - // snap to integer - aSnappedHairline = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aSnappedHairline); + if(false) + { + // when really want to go to single pixel lines, move to center. + // Without this translation, all hor/ver hairlines will be centered exactly + // between two pixel lines (which looks best) + const double fTranslateToCenter(mnAntiAlialize * 0.5); + aTransform.translate(fTranslateToCenter, fTranslateToCenter, 0.0); + } - // add oversampling again - aTransform.identity(); - aTransform.scale(fScaleUp, fScaleUp, 1.0); + aSnappedHairline.transform(aTransform); - if(false) + mpZBufferRasterConverter3D->rasterconvertB3DPolygon(aSnappedHairline, 0, mpBZPixelRaster->getHeight(), mnAntiAlialize); + } + else { - // when really want to go to single pixel lines, move to center. - // Without this translation, all hor/ver hairlines will be centered exactly - // between two pixel lines (which looks best) - const double fTranslateToCenter(mnAntiAlialize * 0.5); - aTransform.translate(fTranslateToCenter, fTranslateToCenter, 0.0); + mpZBufferRasterConverter3D->rasterconvertB3DPolygon(rHairline, 0, mpBZPixelRaster->getHeight(), mnAntiAlialize); } - - aSnappedHairline.transform(aTransform); - - mpZBufferRasterConverter3D->rasterconvertB3DPolygon(aSnappedHairline, 0, mpBZPixelRaster->getHeight(), mnAntiAlialize); } else { - mpZBufferRasterConverter3D->rasterconvertB3DPolygon(rHairline, 0, mpBZPixelRaster->getHeight(), mnAntiAlialize); + mpZBufferRasterConverter3D->rasterconvertB3DPolygon(rHairline, 0, mpBZPixelRaster->getHeight(), 1); } } - else - { - mpZBufferRasterConverter3D->rasterconvertB3DPolygon(rHairline, 0, mpBZPixelRaster->getHeight(), 1); - } } } @@ -613,8 +641,30 @@ namespace drawinglayer { if(mpBZPixelRaster) { - mpZBufferRasterConverter3D->setCurrentMaterial(rMaterial); - mpZBufferRasterConverter3D->rasterconvertB3DPolyPolygon(rFill, &maInvEyeToView, 0, mpBZPixelRaster->getHeight()); + if(getTransparenceCounter()) + { + // transparent output; record for later sorting and painting from + // back to front + if(!mpRasterPrimitive3Ds) + { + const_cast< ZBufferProcessor3D* >(this)->mpRasterPrimitive3Ds = new std::vector< RasterPrimitive3D >; + } + + mpRasterPrimitive3Ds->push_back(RasterPrimitive3D( + getGeoTexSvx(), + getTransparenceGeoTexSvx(), + rMaterial, + rFill, + getModulate(), + getFilter(), + getSimpleTextureActive(), + false)); + } + else + { + mpZBufferRasterConverter3D->setCurrentMaterial(rMaterial); + mpZBufferRasterConverter3D->rasterconvertB3DPolyPolygon(rFill, &maInvEyeToView, 0, mpBZPixelRaster->getHeight()); + } } } @@ -632,8 +682,7 @@ namespace drawinglayer maInvEyeToView(), mpZBufferRasterConverter3D(0), mnAntiAlialize(nAntiAlialize), - mbProcessTransparent(false), - mbContainsTransparent(false) + mpRasterPrimitive3Ds(0) { // generate ViewSizes const double fFullViewSizeX((rViewInformation2D.getObjectToViewTransformation() * basegfx::B2DVector(fSizeX, 0.0)).getLength()); @@ -729,6 +778,58 @@ namespace drawinglayer delete mpZBufferRasterConverter3D; delete mpBZPixelRaster; } + + if(mpRasterPrimitive3Ds) + { + OSL_ASSERT("ZBufferProcessor3D: destructed, but there are unrendered transparent geometries. Use ZBufferProcessor3D::finish() to render these (!)"); + delete mpRasterPrimitive3Ds; + } + } + + void ZBufferProcessor3D::finish() + { + if(mpRasterPrimitive3Ds) + { + // there are transparent rasterprimitives + const sal_uInt32 nSize(mpRasterPrimitive3Ds->size()); + + if(nSize > 1) + { + // sort them from back to front + std::sort(mpRasterPrimitive3Ds->begin(), mpRasterPrimitive3Ds->end()); + } + + for(sal_uInt32 a(0); a < nSize; a++) + { + // paint each one by setting the remembered data and calling + // the render method + const RasterPrimitive3D& rCandidate = (*mpRasterPrimitive3Ds)[a]; + + mpGeoTexSvx = rCandidate.getGeoTexSvx(); + mpTransparenceGeoTexSvx = rCandidate.getTransparenceGeoTexSvx(); + mbModulate = rCandidate.getModulate(); + mbFilter = rCandidate.getFilter(); + mbSimpleTextureActive = rCandidate.getSimpleTextureActive(); + + if(rCandidate.getIsLine()) + { + rasterconvertB3DPolygon( + rCandidate.getMaterial(), + rCandidate.getPolyPolygon().getB3DPolygon(0)); + } + else + { + rasterconvertB3DPolyPolygon( + rCandidate.getMaterial(), + rCandidate.getPolyPolygon()); + } + } + + // delete them to signal the destructor that all is done and + // to allow asserting there + delete mpRasterPrimitive3Ds; + mpRasterPrimitive3Ds = 0; + } } BitmapEx ZBufferProcessor3D::getBitmapEx() const -- cgit From 064e40d3714c7deeba0d8cbcb7086de9ba1f5144 Mon Sep 17 00:00:00 2001 From: Armin Le Grand Date: Wed, 6 Jan 2010 16:34:35 +0100 Subject: aw079: #i107987# corrected selection and rotation for 3D light control --- svx/source/dialog/dlgctl3d.cxx | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/svx/source/dialog/dlgctl3d.cxx b/svx/source/dialog/dlgctl3d.cxx index 8123a353bc63..b5956b3949df 100644 --- a/svx/source/dialog/dlgctl3d.cxx +++ b/svx/source/dialog/dlgctl3d.cxx @@ -514,8 +514,17 @@ void Svx3DLightControl::TrySelection(Point aPosPixel) if(aResult.size()) { - // take the frontmost one - const E3dCompoundObject* pResult = aResult[0]; + // exclude expansion object which will be part of + // the hits. It's invisible, but for HitTest, it's included + const E3dCompoundObject* pResult = 0; + + for(sal_uInt32 b(0); !pResult && b < aResult.size(); b++) + { + if(aResult[b] && aResult[b] != mpExpansionObject) + { + pResult = aResult[b]; + } + } if(pResult == mp3DObj) { @@ -780,8 +789,8 @@ void Svx3DLightControl::GetPosition(double& rHor, double& rVer) } if(IsGeometrySelected()) { - rHor = mfRotateY; - rVer = mfRotateX; + rHor = mfRotateY / F_PI180; // 0..360.0 + rVer = mfRotateX / F_PI180; // -90.0..90.0 } } @@ -824,8 +833,8 @@ void Svx3DLightControl::SetPosition(double fHor, double fVer) { if(mfRotateX != fVer || mfRotateY != fHor) { - mfRotateX = fVer; - mfRotateY = fHor; + mfRotateX = fVer * F_PI180; + mfRotateY = fHor * F_PI180; if(mp3DObj) { -- cgit From 108c876c1c9a723b92f876662e02ee105a55bbfe Mon Sep 17 00:00:00 2001 From: Armin Le Grand Date: Wed, 6 Jan 2010 18:33:15 +0100 Subject: aw079: #i107557# Re-added the edge rounding control handle to text frame visualisations --- svx/source/svdraw/svdorect.cxx | 79 +++++++++++++++++++++++++----------------- 1 file changed, 48 insertions(+), 31 deletions(-) diff --git a/svx/source/svdraw/svdorect.cxx b/svx/source/svdraw/svdorect.cxx index 7d69955ec441..3e9b4b0cfa54 100644 --- a/svx/source/svdraw/svdorect.cxx +++ b/svx/source/svdraw/svdorect.cxx @@ -319,50 +319,67 @@ void SdrRectObj::NbcSetLogicRect(const Rectangle& rRect) sal_uInt32 SdrRectObj::GetHdlCount() const { - return 9L; + return IsTextFrame() ? 10 : 9; } SdrHdl* SdrRectObj::GetHdl(sal_uInt32 nHdlNum) const { - SdrHdl* pH=NULL; + SdrHdl* pH = NULL; Point aPnt; - SdrHdlKind eKind=HDL_MOVE; - if( IsTextFrame() && !nHdlNum ) + SdrHdlKind eKind = HDL_MOVE; + + if(!IsTextFrame()) { - pH=new ImpTextframeHdl(aRect); - pH->SetObj((SdrObject*)this); - pH->SetDrehWink(aGeo.nDrehWink); - return pH; + nHdlNum++; } - else + + switch(nHdlNum) { - switch (nHdlNum) { - case 0: { - long a=GetEckenradius(); - long b=Max(aRect.GetWidth(),aRect.GetHeight())/2; // Wird aufgerundet, da GetWidth() eins draufaddiert - if (a>b) a=b; - if (a<0) a=0; - aPnt=aRect.TopLeft(); - aPnt.X()+=a; - eKind=HDL_CIRC; - } break; // Eckenradius - case 1: aPnt=aRect.TopLeft(); eKind=HDL_UPLFT; break; // Oben links - case 2: aPnt=aRect.TopCenter(); eKind=HDL_UPPER; break; // Oben - case 3: aPnt=aRect.TopRight(); eKind=HDL_UPRGT; break; // Oben rechts - case 4: aPnt=aRect.LeftCenter(); eKind=HDL_LEFT ; break; // Links - case 5: aPnt=aRect.RightCenter(); eKind=HDL_RIGHT; break; // Rechts - case 6: aPnt=aRect.BottomLeft(); eKind=HDL_LWLFT; break; // Unten links - case 7: aPnt=aRect.BottomCenter(); eKind=HDL_LOWER; break; // Unten - case 8: aPnt=aRect.BottomRight(); eKind=HDL_LWRGT; break; // Unten rechts + case 0: + { + pH = new ImpTextframeHdl(aRect); + pH->SetObj((SdrObject*)this); + pH->SetDrehWink(aGeo.nDrehWink); + break; + } + case 1: + { + long a = GetEckenradius(); + long b = Max(aRect.GetWidth(),aRect.GetHeight())/2; // Wird aufgerundet, da GetWidth() eins draufaddiert + if (a>b) a=b; + if (a<0) a=0; + aPnt=aRect.TopLeft(); + aPnt.X()+=a; + eKind = HDL_CIRC; + break; } + case 2: aPnt=aRect.TopLeft(); eKind = HDL_UPLFT; break; // Oben links + case 3: aPnt=aRect.TopCenter(); eKind = HDL_UPPER; break; // Oben + case 4: aPnt=aRect.TopRight(); eKind = HDL_UPRGT; break; // Oben rechts + case 5: aPnt=aRect.LeftCenter(); eKind = HDL_LEFT ; break; // Links + case 6: aPnt=aRect.RightCenter(); eKind = HDL_RIGHT; break; // Rechts + case 7: aPnt=aRect.BottomLeft(); eKind = HDL_LWLFT; break; // Unten links + case 8: aPnt=aRect.BottomCenter(); eKind = HDL_LOWER; break; // Unten + case 9: aPnt=aRect.BottomRight(); eKind = HDL_LWRGT; break; // Unten rechts } - if (aGeo.nShearWink!=0) ShearPoint(aPnt,aRect.TopLeft(),aGeo.nTan); - if (aGeo.nDrehWink!=0) RotatePoint(aPnt,aRect.TopLeft(),aGeo.nSin,aGeo.nCos); - if (eKind!=HDL_MOVE) { - pH=new SdrHdl(aPnt,eKind); + + if(!pH) + { + if(aGeo.nShearWink) + { + ShearPoint(aPnt,aRect.TopLeft(),aGeo.nTan); + } + + if(aGeo.nDrehWink) + { + RotatePoint(aPnt,aRect.TopLeft(),aGeo.nSin,aGeo.nCos); + } + + pH = new SdrHdl(aPnt,eKind); pH->SetObj((SdrObject*)this); pH->SetDrehWink(aGeo.nDrehWink); } + return pH; } -- cgit