You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openoffice.apache.org by al...@apache.org on 2012/01/24 18:13:46 UTC
svn commit: r1235361 - in /incubator/ooo/trunk/main/drawinglayer:
inc/drawinglayer/primitive2d/ inc/drawinglayer/processor2d/
source/primitive2d/ source/processor2d/
Author: alg
Date: Tue Jan 24 17:13:46 2012
New Revision: 1235361
URL: http://svn.apache.org/viewvc?rev=1235361&view=rev
Log:
#118829# enhanced Svg gradient quality, obstacles avoided
Modified:
incubator/ooo/trunk/main/drawinglayer/inc/drawinglayer/primitive2d/svggradientprimitive2d.hxx
incubator/ooo/trunk/main/drawinglayer/inc/drawinglayer/processor2d/vclprocessor2d.hxx
incubator/ooo/trunk/main/drawinglayer/source/primitive2d/svggradientprimitive2d.cxx
incubator/ooo/trunk/main/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
incubator/ooo/trunk/main/drawinglayer/source/processor2d/vclprocessor2d.cxx
Modified: incubator/ooo/trunk/main/drawinglayer/inc/drawinglayer/primitive2d/svggradientprimitive2d.hxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/drawinglayer/inc/drawinglayer/primitive2d/svggradientprimitive2d.hxx?rev=1235361&r1=1235360&r2=1235361&view=diff
==============================================================================
--- incubator/ooo/trunk/main/drawinglayer/inc/drawinglayer/primitive2d/svggradientprimitive2d.hxx (original)
+++ incubator/ooo/trunk/main/drawinglayer/inc/drawinglayer/primitive2d/svggradientprimitive2d.hxx Tue Jan 24 17:13:46 2012
@@ -35,8 +35,8 @@
namespace drawinglayer
{
- namespace primitive2d
- {
+ namespace primitive2d
+ {
/// a single GradientStop defining a color and opacity at a distance
class SvgGradientEntry
{
@@ -77,7 +77,6 @@ namespace drawinglayer
//////////////////////////////////////////////////////////////////////////////
// SvgGradientHelper class
-#define DEFAULT_OVERLAPPING_VALUE (1.0/512.0)
namespace drawinglayer
{
@@ -93,11 +92,11 @@ namespace drawinglayer
/* helper for linear and radial gradient, both get derived from this
to share common definitions and functionality
**/
- class SvgGradientHelper
- {
- private:
+ class SvgGradientHelper
+ {
+ private:
/// geometric definition, the geometry to be filled
- basegfx::B2DPolyPolygon maPolyPolygon;
+ basegfx::B2DPolyPolygon maPolyPolygon;
/// the gradient definition
SvgGradientEntryVector maGradientEntries;
@@ -108,23 +107,6 @@ namespace drawinglayer
/// how to spread
SpreadMethod maSpreadMethod;
- /* allows to set an overlapping value to be able to create
- slightly overlapping PolyPolygons/Polygons for the decomposition.
- This is needed since when creating geometrically correct decompositions
- many visualisations will show artefacts at the borders, even when these
- borders are absolutely correctly defined. It is possible to define a
- useful value for this since the coordinate system we are working in is
- in unit coordinates so that the whole gradient is from [0.0 .. 1.0] range.
- This explains the default value which is 1/512 by a maximum possible
- color count of 255 steps per GradientStop.
- Give a 0.0 here to go to geometrically correct gradient decompositions if
- needed.
- An alternative would be to create no PolyPolygons from outside to inside
- (example for radial), but this leads to up to 255 filled polygons per
- GradientStop and thus to enormous rendering costs.
- **/
- double mfOverlapping;
-
/// bitfield
bool mbPreconditionsChecked : 1;
bool mbCreatesContent : 1;
@@ -133,7 +115,7 @@ namespace drawinglayer
protected:
/// local helpers
- Primitive2DSequence createSingleGradientEntryFill() const;
+ Primitive2DSequence createSingleGradientEntryFill() const;
virtual void createAtom(
Primitive2DVector& rTargetColor,
Primitive2DVector& rTargetOpacity,
@@ -161,24 +143,22 @@ namespace drawinglayer
public:
/// constructor
- SvgGradientHelper(
- const basegfx::B2DPolyPolygon& rPolyPolygon,
+ SvgGradientHelper(
+ const basegfx::B2DPolyPolygon& rPolyPolygon,
const SvgGradientEntryVector& rGradientEntries,
const basegfx::B2DPoint& rStart,
- SpreadMethod aSpreadMethod = Spread_pad,
- double fOverlapping = DEFAULT_OVERLAPPING_VALUE);
+ SpreadMethod aSpreadMethod = Spread_pad);
- /// data read access
+ /// data read access
const basegfx::B2DPolyPolygon& getPolyPolygon() const { return maPolyPolygon; }
const SvgGradientEntryVector& getGradientEntries() const { return maGradientEntries; }
const basegfx::B2DPoint& getStart() const { return maStart; }
SpreadMethod getSpreadMethod() const { return maSpreadMethod; }
- double getOverlapping() const { return mfOverlapping; }
/// compare operator
- virtual bool operator==(const SvgGradientHelper& rSvgGradientHelper) const;
- };
- } // end of namespace primitive2d
+ virtual bool operator==(const SvgGradientHelper& rSvgGradientHelper) const;
+ };
+ } // end of namespace primitive2d
} // end of namespace drawinglayer
//////////////////////////////////////////////////////////////////////////////
@@ -186,22 +166,15 @@ namespace drawinglayer
namespace drawinglayer
{
- namespace primitive2d
- {
+ namespace primitive2d
+ {
/// the basic linear gradient primitive
- class DRAWINGLAYER_DLLPUBLIC SvgLinearGradientPrimitive2D : public BufferedDecompositionPrimitive2D, public SvgGradientHelper
- {
- private:
+ class DRAWINGLAYER_DLLPUBLIC SvgLinearGradientPrimitive2D : public BufferedDecompositionPrimitive2D, public SvgGradientHelper
+ {
+ private:
/// the end point for linear gradient
basegfx::B2DPoint maEnd;
- /// local helpers
- void ensureGeometry(
- basegfx::B2DPolyPolygon& rPolyPolygon,
- const SvgGradientEntry& rFrom,
- const SvgGradientEntry& rTo,
- sal_Int32 nOffset) const;
-
protected:
/// local helpers
virtual void createAtom(
@@ -213,31 +186,30 @@ namespace drawinglayer
virtual void checkPreconditions();
/// local decomposition.
- virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const;
+ virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const;
- public:
+ public:
/// constructor
- SvgLinearGradientPrimitive2D(
- const basegfx::B2DPolyPolygon& rPolyPolygon,
+ SvgLinearGradientPrimitive2D(
+ const basegfx::B2DPolyPolygon& rPolyPolygon,
const SvgGradientEntryVector& rGradientEntries,
const basegfx::B2DPoint& rStart,
const basegfx::B2DPoint& rEnd,
- SpreadMethod aSpreadMethod = Spread_pad,
- double fOverlapping = DEFAULT_OVERLAPPING_VALUE);
+ SpreadMethod aSpreadMethod = Spread_pad);
- /// data read access
+ /// data read access
const basegfx::B2DPoint& getEnd() const { return maEnd; }
/// compare operator
- virtual bool operator==(const BasePrimitive2D& rPrimitive) const;
+ virtual bool operator==(const BasePrimitive2D& rPrimitive) const;
- /// get range
- virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const;
+ /// get range
+ virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const;
- /// provide unique ID
- DeclPrimitrive2DIDBlock()
- };
- } // end of namespace primitive2d
+ /// provide unique ID
+ DeclPrimitrive2DIDBlock()
+ };
+} // end of namespace primitive2d
} // end of namespace drawinglayer
//////////////////////////////////////////////////////////////////////////////
@@ -245,12 +217,12 @@ namespace drawinglayer
namespace drawinglayer
{
- namespace primitive2d
- {
+ namespace primitive2d
+ {
/// the basic radial gradient primitive
- class DRAWINGLAYER_DLLPUBLIC SvgRadialGradientPrimitive2D : public BufferedDecompositionPrimitive2D, public SvgGradientHelper
- {
- private:
+ class DRAWINGLAYER_DLLPUBLIC SvgRadialGradientPrimitive2D : public BufferedDecompositionPrimitive2D, public SvgGradientHelper
+ {
+ private:
/// the geometric definition
double mfRadius;
@@ -268,11 +240,6 @@ namespace drawinglayer
/// local helpers
const SvgGradientEntryVector& getMirroredGradientEntries() const;
void createMirroredGradientEntries();
- void ensureGeometry(
- basegfx::B2DPolyPolygon& rPolyPolygon,
- const SvgGradientEntry& rFrom,
- const SvgGradientEntry& rTo,
- sal_Int32 nOffset) const;
protected:
/// local helpers
@@ -285,34 +252,33 @@ namespace drawinglayer
virtual void checkPreconditions();
/// local decomposition.
- virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const;
+ virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const;
- public:
+ public:
/// constructor
- SvgRadialGradientPrimitive2D(
- const basegfx::B2DPolyPolygon& rPolyPolygon,
+ SvgRadialGradientPrimitive2D(
+ const basegfx::B2DPolyPolygon& rPolyPolygon,
const SvgGradientEntryVector& rGradientEntries,
const basegfx::B2DPoint& rStart,
double fRadius,
SpreadMethod aSpreadMethod = Spread_pad,
- const basegfx::B2DPoint* pFocal = 0,
- double fOverlapping = DEFAULT_OVERLAPPING_VALUE);
+ const basegfx::B2DPoint* pFocal = 0);
- /// data read access
+ /// data read access
double getRadius() const { return mfRadius; }
const basegfx::B2DPoint& getFocal() const { return maFocal; }
bool isFocalSet() const { return mbFocalSet; }
/// compare operator
- virtual bool operator==(const BasePrimitive2D& rPrimitive) const;
+ virtual bool operator==(const BasePrimitive2D& rPrimitive) const;
- /// get range
- virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const;
+ /// get range
+ virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const;
- /// provide unique ID
- DeclPrimitrive2DIDBlock()
- };
- } // end of namespace primitive2d
+ /// provide unique ID
+ DeclPrimitrive2DIDBlock()
+ };
+ } // end of namespace primitive2d
} // end of namespace drawinglayer
//////////////////////////////////////////////////////////////////////////////
@@ -320,56 +286,45 @@ namespace drawinglayer
namespace drawinglayer
{
- namespace primitive2d
- {
+ namespace primitive2d
+ {
/* basic primitive for a single linear GradientRun in unit coordiantes.
It's derived from DiscreteMetricDependentPrimitive2D to allow view-dependent
decompositions allowing reduced color steps
**/
- class DRAWINGLAYER_DLLPUBLIC SvgLinearAtomPrimitive2D : public DiscreteMetricDependentPrimitive2D
- {
- private:
+ class DRAWINGLAYER_DLLPUBLIC SvgLinearAtomPrimitive2D : public DiscreteMetricDependentPrimitive2D
+ {
+ private:
/// the geometric definition in unit coordiantes
basegfx::BColor maColorA;
basegfx::BColor maColorB;
double mfOffsetA;
double mfOffsetB;
- double mfOverlapping;
protected:
/// local decomposition.
- virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const;
+ virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const;
- public:
+ public:
/// constructor
- SvgLinearAtomPrimitive2D(
+ SvgLinearAtomPrimitive2D(
const basegfx::BColor& aColorA, double fOffsetA,
- const basegfx::BColor& aColorB, double fOffsetB,
- double fOverlapping = DEFAULT_OVERLAPPING_VALUE)
- : DiscreteMetricDependentPrimitive2D(),
- maColorA(aColorA),
- maColorB(aColorB),
- mfOffsetA(fOffsetA),
- mfOffsetB(fOffsetB),
- mfOverlapping(fOverlapping)
- {
- }
+ const basegfx::BColor& aColorB, double fOffsetB);
- /// data read access
+ /// data read access
const basegfx::BColor& getColorA() const { return maColorA; }
const basegfx::BColor& getColorB() const { return maColorB; }
double getOffsetA() const { return mfOffsetA; }
double getOffsetB() const { return mfOffsetB; }
- double getOverlapping() const { return mfOverlapping; }
/// compare operator
- virtual bool operator==(const BasePrimitive2D& rPrimitive) const;
+ virtual bool operator==(const BasePrimitive2D& rPrimitive) const;
- /// provide unique ID
- DeclPrimitrive2DIDBlock()
- };
- } // end of namespace primitive2d
+ /// provide unique ID
+ DeclPrimitrive2DIDBlock()
+ };
+ } // end of namespace primitive2d
} // end of namespace drawinglayer
//////////////////////////////////////////////////////////////////////////////
@@ -377,87 +332,68 @@ namespace drawinglayer
namespace drawinglayer
{
- namespace primitive2d
- {
+ namespace primitive2d
+ {
/* basic primitive for a single radial GradientRun in unit coordiantes.
It's derived from DiscreteMetricDependentPrimitive2D to allow view-dependent
decompositions allowing reduced color steps
**/
- class DRAWINGLAYER_DLLPUBLIC SvgRadialAtomPrimitive2D : public DiscreteMetricDependentPrimitive2D
- {
- private:
+ class DRAWINGLAYER_DLLPUBLIC SvgRadialAtomPrimitive2D : public DiscreteMetricDependentPrimitive2D
+ {
+ private:
/// the geometric definition in unit coordiantes
basegfx::BColor maColorA;
basegfx::BColor maColorB;
double mfScaleA;
double mfScaleB;
- /// Only used when focal is set
- basegfx::B2DVector maTranslateA;
- basegfx::B2DVector maTranslateB;
+ // helper to hold translation vectors when given (for focal)
+ struct VectorPair
+ {
+ basegfx::B2DVector maTranslateA;
+ basegfx::B2DVector maTranslateB;
- double mfOverlapping;
+ VectorPair(const basegfx::B2DVector& rTranslateA, const basegfx::B2DVector& rTranslateB)
+ : maTranslateA(rTranslateA),
+ maTranslateB(rTranslateB)
+ {
+ }
+ };
- /// bitfield
- bool mbTranslateSet : 1;
+ /// Only used when focal is set
+ VectorPair* mpTranslate;
protected:
/// local decomposition.
- virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const;
+ virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const;
- public:
+ public:
/// constructor
- SvgRadialAtomPrimitive2D(
+ SvgRadialAtomPrimitive2D(
const basegfx::BColor& aColorA, double fScaleA, const basegfx::B2DVector& rTranslateA,
- const basegfx::BColor& aColorB, double fScaleB, const basegfx::B2DVector& rTranslateB,
- double fOverlapping = DEFAULT_OVERLAPPING_VALUE)
- : DiscreteMetricDependentPrimitive2D(),
- maColorA(aColorA),
- maColorB(aColorB),
- mfScaleA(fScaleA),
- mfScaleB(fScaleB),
- maTranslateA(rTranslateA),
- maTranslateB(rTranslateB),
- mfOverlapping(fOverlapping),
- mbTranslateSet(true)
- {
- mbTranslateSet = !maTranslateA.equal(maTranslateB);
- }
-
+ const basegfx::BColor& aColorB, double fScaleB, const basegfx::B2DVector& rTranslateB);
SvgRadialAtomPrimitive2D(
const basegfx::BColor& aColorA, double fScaleA,
- const basegfx::BColor& aColorB, double fScaleB,
- double fOverlapping = DEFAULT_OVERLAPPING_VALUE)
- : DiscreteMetricDependentPrimitive2D(),
- maColorA(aColorA),
- maColorB(aColorB),
- mfScaleA(fScaleA),
- mfScaleB(fScaleB),
- maTranslateA(),
- maTranslateB(),
- mfOverlapping(fOverlapping),
- mbTranslateSet(false)
- {
- }
+ const basegfx::BColor& aColorB, double fScaleB);
+ virtual ~SvgRadialAtomPrimitive2D();
- /// data read access
+ /// data read access
const basegfx::BColor& getColorA() const { return maColorA; }
const basegfx::BColor& getColorB() const { return maColorB; }
double getScaleA() const { return mfScaleA; }
double getScaleB() const { return mfScaleB; }
- const basegfx::B2DVector& getTranslateA() const { return maTranslateA; }
- const basegfx::B2DVector& getTranslateB() const { return maTranslateB; }
- double getOverlapping() const { return mfOverlapping; }
- bool getTranslateSet() const { return mbTranslateSet; }
+ bool isTranslateSet() const { return (0 != mpTranslate); }
+ basegfx::B2DVector getTranslateA() const { if(mpTranslate) return mpTranslate->maTranslateA; return basegfx::B2DVector(); }
+ basegfx::B2DVector getTranslateB() const { if(mpTranslate) return mpTranslate->maTranslateB; return basegfx::B2DVector(); }
/// compare operator
- virtual bool operator==(const BasePrimitive2D& rPrimitive) const;
+ virtual bool operator==(const BasePrimitive2D& rPrimitive) const;
- /// provide unique ID
- DeclPrimitrive2DIDBlock()
- };
- } // end of namespace primitive2d
+ /// provide unique ID
+ DeclPrimitrive2DIDBlock()
+ };
+ } // end of namespace primitive2d
} // end of namespace drawinglayer
//////////////////////////////////////////////////////////////////////////////
Modified: incubator/ooo/trunk/main/drawinglayer/inc/drawinglayer/processor2d/vclprocessor2d.hxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/drawinglayer/inc/drawinglayer/processor2d/vclprocessor2d.hxx?rev=1235361&r1=1235360&r2=1235361&view=diff
==============================================================================
--- incubator/ooo/trunk/main/drawinglayer/inc/drawinglayer/processor2d/vclprocessor2d.hxx (original)
+++ incubator/ooo/trunk/main/drawinglayer/inc/drawinglayer/processor2d/vclprocessor2d.hxx Tue Jan 24 17:13:46 2012
@@ -54,6 +54,8 @@ namespace drawinglayer { namespace primi
class ControlPrimitive2D;
class PagePreviewPrimitive2D;
class EpsPrimitive2D;
+ class SvgLinearAtomPrimitive2D;
+ class SvgRadialAtomPrimitive2D;
}}
//////////////////////////////////////////////////////////////////////////////
@@ -109,6 +111,8 @@ namespace drawinglayer
void RenderPointArrayPrimitive2D(const primitive2d::PointArrayPrimitive2D& rPointArrayCandidate);
void RenderPolygonStrokePrimitive2D(const primitive2d::PolygonStrokePrimitive2D& rPolygonStrokeCandidate);
void RenderEpsPrimitive2D(const primitive2d::EpsPrimitive2D& rEpsPrimitive2D);
+ void RenderSvgLinearAtomPrimitive2D(const primitive2d::SvgLinearAtomPrimitive2D& rCandidate);
+ void RenderSvgRadialAtomPrimitive2D(const primitive2d::SvgRadialAtomPrimitive2D& rCandidate);
/////////////////////////////////////////////////////////////////////////////
// DrawMode adaption support
Modified: incubator/ooo/trunk/main/drawinglayer/source/primitive2d/svggradientprimitive2d.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/drawinglayer/source/primitive2d/svggradientprimitive2d.cxx?rev=1235361&r1=1235360&r2=1235361&view=diff
==============================================================================
--- incubator/ooo/trunk/main/drawinglayer/source/primitive2d/svggradientprimitive2d.cxx (original)
+++ incubator/ooo/trunk/main/drawinglayer/source/primitive2d/svggradientprimitive2d.cxx Tue Jan 24 17:13:46 2012
@@ -41,12 +41,37 @@ using namespace com::sun::star;
//////////////////////////////////////////////////////////////////////////////
+namespace
+{
+ sal_uInt32 calculateStepsForSvgGradient(const basegfx::BColor& rColorA, const basegfx::BColor& rColorB, double fDelta, double fDiscreteUnit)
+ {
+ // use color distance, assume to do every color step (full quality)
+ sal_uInt32 nSteps(basegfx::fround(rColorA.getDistance(rColorB) * 255.0));
+
+ if(nSteps)
+ {
+ // calc discrete length to change color all 1.5 disctete units (pixels)
+ const sal_uInt32 nDistSteps(basegfx::fround(fDelta / (fDiscreteUnit * 1.5)));
+
+ nSteps = std::min(nSteps, nDistSteps);
+ }
+
+ // roughly cut when too big or too small
+ nSteps = std::min(nSteps, sal_uInt32(255));
+ nSteps = std::max(nSteps, sal_uInt32(1));
+
+ return nSteps;
+ }
+} // end of anonymous namespace
+
+//////////////////////////////////////////////////////////////////////////////
+
namespace drawinglayer
{
- namespace primitive2d
- {
- Primitive2DSequence SvgGradientHelper::createSingleGradientEntryFill() const
- {
+ namespace primitive2d
+ {
+ Primitive2DSequence SvgGradientHelper::createSingleGradientEntryFill() const
+ {
const SvgGradientEntryVector& rEntries = getGradientEntries();
const sal_uInt32 nCount(rEntries.size());
Primitive2DSequence xRetval;
@@ -58,15 +83,15 @@ namespace drawinglayer
if(fOpacity > 0.0)
{
- Primitive2DReference xRef(
+ Primitive2DReference xRef(
new PolyPolygonColorPrimitive2D(
getPolyPolygon(),
rSingleEntry.getColor()));
if(fOpacity < 1.0)
{
- const Primitive2DSequence aContent(&xRef, 1);
-
+ const Primitive2DSequence aContent(&xRef, 1);
+
xRef = Primitive2DReference(
new UnifiedTransparencePrimitive2D(
aContent,
@@ -230,11 +255,11 @@ namespace drawinglayer
if(aTargetColorEntries.hasElements())
{
- Primitive2DReference xRefContent;
+ Primitive2DReference xRefContent;
if(aTargetOpacityEntries.hasElements())
{
- const Primitive2DReference xRefOpacity = new TransparencePrimitive2D(
+ const Primitive2DReference xRefOpacity = new TransparencePrimitive2D(
aTargetColorEntries,
aTargetOpacityEntries);
@@ -259,34 +284,31 @@ namespace drawinglayer
return xRetval;
}
- SvgGradientHelper::SvgGradientHelper(
- const basegfx::B2DPolyPolygon& rPolyPolygon,
+ SvgGradientHelper::SvgGradientHelper(
+ const basegfx::B2DPolyPolygon& rPolyPolygon,
const SvgGradientEntryVector& rGradientEntries,
const basegfx::B2DPoint& rStart,
- SpreadMethod aSpreadMethod,
- double fOverlapping)
- : maPolyPolygon(rPolyPolygon),
+ SpreadMethod aSpreadMethod)
+ : maPolyPolygon(rPolyPolygon),
maGradientEntries(rGradientEntries),
maStart(rStart),
maSpreadMethod(aSpreadMethod),
- mfOverlapping(fOverlapping),
mbPreconditionsChecked(false),
mbCreatesContent(false),
mbSingleEntry(false),
mbFullyOpaque(true)
- {
- }
+ {
+ }
- bool SvgGradientHelper::operator==(const SvgGradientHelper& rSvgGradientHelper) const
- {
- const SvgGradientHelper& rCompare = static_cast< const SvgGradientHelper& >(rSvgGradientHelper);
+ bool SvgGradientHelper::operator==(const SvgGradientHelper& rSvgGradientHelper) const
+ {
+ const SvgGradientHelper& rCompare = static_cast< const SvgGradientHelper& >(rSvgGradientHelper);
- return (getPolyPolygon() == rCompare.getPolyPolygon()
+ return (getPolyPolygon() == rCompare.getPolyPolygon()
&& getGradientEntries() == rCompare.getGradientEntries()
&& getStart() == rCompare.getStart()
- && getSpreadMethod() == rCompare.getSpreadMethod()
- && getOverlapping() == rCompare.getOverlapping());
- }
+ && getSpreadMethod() == rCompare.getSpreadMethod());
+ }
} // end of namespace primitive2d
} // end of namespace drawinglayer
@@ -296,7 +318,7 @@ namespace drawinglayer
namespace drawinglayer
{
namespace primitive2d
- {
+ {
void SvgLinearGradientPrimitive2D::checkPreconditions()
{
// call parent
@@ -315,24 +337,6 @@ namespace drawinglayer
}
}
- void SvgLinearGradientPrimitive2D::ensureGeometry(
- basegfx::B2DPolyPolygon& rPolyPolygon,
- const SvgGradientEntry& rFrom,
- const SvgGradientEntry& rTo,
- sal_Int32 nOffset) const
- {
- if(!rPolyPolygon.count())
- {
- rPolyPolygon.append(
- basegfx::tools::createPolygonFromRect(
- basegfx::B2DRange(
- rFrom.getOffset() - getOverlapping() + nOffset,
- 0.0,
- rTo.getOffset() + getOverlapping() + nOffset,
- 1.0)));
- }
- }
-
void SvgLinearGradientPrimitive2D::createAtom(
Primitive2DVector& rTargetColor,
Primitive2DVector& rTargetOpacity,
@@ -347,53 +351,23 @@ namespace drawinglayer
}
else
{
- const bool bColorChange(rFrom.getColor() != rTo.getColor());
- const bool bOpacityChange(rFrom.getOpacity() != rTo.getOpacity());
- basegfx::B2DPolyPolygon aPolyPolygon;
-
- if(bColorChange)
- {
- rTargetColor.push_back(
- new SvgLinearAtomPrimitive2D(
- rFrom.getColor(), rFrom.getOffset() + nOffset,
- rTo.getColor(), rTo.getOffset() + nOffset,
- getOverlapping()));
- }
- else
- {
- ensureGeometry(aPolyPolygon, rFrom, rTo, nOffset);
- rTargetColor.push_back(
- new PolyPolygonColorPrimitive2D(
- aPolyPolygon,
- rFrom.getColor()));
- }
-
- if(bOpacityChange)
- {
- const double fTransFrom(1.0 - rFrom.getOpacity());
- const double fTransTo(1.0 - rTo.getOpacity());
-
- rTargetOpacity.push_back(
- new SvgLinearAtomPrimitive2D(
- basegfx::BColor(fTransFrom, fTransFrom, fTransFrom), rFrom.getOffset() + nOffset,
- basegfx::BColor(fTransTo,fTransTo, fTransTo), rTo.getOffset() + nOffset,
- getOverlapping()));
- }
- else if(!getFullyOpaque())
- {
- const double fTransparence(1.0 - rFrom.getOpacity());
-
- ensureGeometry(aPolyPolygon, rFrom, rTo, nOffset);
- rTargetOpacity.push_back(
- new PolyPolygonColorPrimitive2D(
- aPolyPolygon,
- basegfx::BColor(fTransparence, fTransparence, fTransparence)));
- }
+ rTargetColor.push_back(
+ new SvgLinearAtomPrimitive2D(
+ rFrom.getColor(), rFrom.getOffset() + nOffset,
+ rTo.getColor(), rTo.getOffset() + nOffset));
+
+ const double fTransFrom(1.0 - rFrom.getOpacity());
+ const double fTransTo(1.0 - rTo.getOpacity());
+
+ rTargetOpacity.push_back(
+ new SvgLinearAtomPrimitive2D(
+ basegfx::BColor(fTransFrom, fTransFrom, fTransFrom), rFrom.getOffset() + nOffset,
+ basegfx::BColor(fTransTo,fTransTo, fTransTo), rTo.getOffset() + nOffset));
}
}
- Primitive2DSequence SvgLinearGradientPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
- {
+ Primitive2DSequence SvgLinearGradientPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
Primitive2DSequence xRetval;
if(!getPreconditionsChecked())
@@ -549,53 +523,52 @@ namespace drawinglayer
}
return xRetval;
- }
+ }
- SvgLinearGradientPrimitive2D::SvgLinearGradientPrimitive2D(
- const basegfx::B2DPolyPolygon& rPolyPolygon,
+ SvgLinearGradientPrimitive2D::SvgLinearGradientPrimitive2D(
+ const basegfx::B2DPolyPolygon& rPolyPolygon,
const SvgGradientEntryVector& rGradientEntries,
const basegfx::B2DPoint& rStart,
const basegfx::B2DPoint& rEnd,
- SpreadMethod aSpreadMethod,
- double fOverlapping)
- : BufferedDecompositionPrimitive2D(),
- SvgGradientHelper(rPolyPolygon, rGradientEntries, rStart, aSpreadMethod, fOverlapping),
+ SpreadMethod aSpreadMethod)
+ : BufferedDecompositionPrimitive2D(),
+ SvgGradientHelper(rPolyPolygon, rGradientEntries, rStart, aSpreadMethod),
maEnd(rEnd)
- {
- }
+ {
+ }
- bool SvgLinearGradientPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
- {
+ bool SvgLinearGradientPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
const SvgGradientHelper* pSvgGradientHelper = dynamic_cast< const SvgGradientHelper* >(&rPrimitive);
if(pSvgGradientHelper && SvgGradientHelper::operator==(*pSvgGradientHelper))
- {
- const SvgLinearGradientPrimitive2D& rCompare = static_cast< const SvgLinearGradientPrimitive2D& >(rPrimitive);
+ {
+ const SvgLinearGradientPrimitive2D& rCompare = static_cast< const SvgLinearGradientPrimitive2D& >(rPrimitive);
- return (getEnd() == rCompare.getEnd());
- }
+ return (getEnd() == rCompare.getEnd());
+ }
- return false;
- }
+ return false;
+ }
- basegfx::B2DRange SvgLinearGradientPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
- {
- // return ObjectRange
- return getPolyPolygon().getB2DRange();
- }
+ basegfx::B2DRange SvgLinearGradientPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ // return ObjectRange
+ return getPolyPolygon().getB2DRange();
+ }
- // provide unique ID
- ImplPrimitrive2DIDBlock(SvgLinearGradientPrimitive2D, PRIMITIVE2D_ID_SVGLINEARGRADIENTPRIMITIVE2D)
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(SvgLinearGradientPrimitive2D, PRIMITIVE2D_ID_SVGLINEARGRADIENTPRIMITIVE2D)
- } // end of namespace primitive2d
+ } // end of namespace primitive2d
} // end of namespace drawinglayer
//////////////////////////////////////////////////////////////////////////////
namespace drawinglayer
{
- namespace primitive2d
- {
+ namespace primitive2d
+ {
void SvgRadialGradientPrimitive2D::checkPreconditions()
{
// call parent
@@ -612,60 +585,6 @@ namespace drawinglayer
}
}
- void SvgRadialGradientPrimitive2D::ensureGeometry(
- basegfx::B2DPolyPolygon& rPolyPolygon,
- const SvgGradientEntry& rFrom,
- const SvgGradientEntry& rTo,
- sal_Int32 nOffset) const
- {
- if(!rPolyPolygon.count())
- {
- basegfx::B2DPolygon aPolygonA(basegfx::tools::createPolygonFromUnitCircle());
- basegfx::B2DPolygon aPolygonB(basegfx::tools::createPolygonFromUnitCircle());
- double fScaleFrom(rFrom.getOffset() + nOffset);
- const double fScaleTo(rTo.getOffset() + nOffset);
-
- if(fScaleFrom > getOverlapping())
- {
- fScaleFrom -= getOverlapping();
- }
-
- if(isFocalSet())
- {
- const basegfx::B2DVector aTranslateFrom(maFocalVector * (maFocalLength - fScaleFrom));
- const basegfx::B2DVector aTranslateTo(maFocalVector * (maFocalLength - fScaleTo));
-
- aPolygonA.transform(
- basegfx::tools::createScaleTranslateB2DHomMatrix(
- fScaleFrom,
- fScaleFrom,
- aTranslateFrom.getX(),
- aTranslateFrom.getY()));
- aPolygonB.transform(
- basegfx::tools::createScaleTranslateB2DHomMatrix(
- fScaleTo,
- fScaleTo,
- aTranslateTo.getX(),
- aTranslateTo.getY()));
- }
- else
- {
- aPolygonA.transform(
- basegfx::tools::createScaleB2DHomMatrix(
- fScaleFrom,
- fScaleFrom));
- aPolygonB.transform(
- basegfx::tools::createScaleB2DHomMatrix(
- fScaleTo,
- fScaleTo));
- }
-
- // add the outer polygon first
- rPolyPolygon.append(aPolygonB);
- rPolyPolygon.append(aPolygonA);
- }
- }
-
void SvgRadialGradientPrimitive2D::createAtom(
Primitive2DVector& rTargetColor,
Primitive2DVector& rTargetOpacity,
@@ -680,82 +599,48 @@ namespace drawinglayer
}
else
{
- const bool bColorChange(rFrom.getColor() != rTo.getColor());
- const bool bOpacityChange(rFrom.getOpacity() != rTo.getOpacity());
- basegfx::B2DPolyPolygon aPolyPolygon;
+ const double fScaleFrom(rFrom.getOffset() + nOffset);
+ const double fScaleTo(rTo.getOffset() + nOffset);
- if(bColorChange)
+ if(isFocalSet())
{
- const double fScaleFrom(rFrom.getOffset() + nOffset);
- const double fScaleTo(rTo.getOffset() + nOffset);
-
- if(isFocalSet())
- {
- const basegfx::B2DVector aTranslateFrom(maFocalVector * (maFocalLength - fScaleFrom));
- const basegfx::B2DVector aTranslateTo(maFocalVector * (maFocalLength - fScaleTo));
+ const basegfx::B2DVector aTranslateFrom(maFocalVector * (maFocalLength - fScaleFrom));
+ const basegfx::B2DVector aTranslateTo(maFocalVector * (maFocalLength - fScaleTo));
- rTargetColor.push_back(
- new SvgRadialAtomPrimitive2D(
- rFrom.getColor(), fScaleFrom, aTranslateFrom,
- rTo.getColor(), fScaleTo, aTranslateTo,
- getOverlapping()));
- }
- else
- {
- rTargetColor.push_back(
- new SvgRadialAtomPrimitive2D(
- rFrom.getColor(), fScaleFrom,
- rTo.getColor(), fScaleTo,
- getOverlapping()));
- }
+ rTargetColor.push_back(
+ new SvgRadialAtomPrimitive2D(
+ rFrom.getColor(), fScaleFrom, aTranslateFrom,
+ rTo.getColor(), fScaleTo, aTranslateTo));
}
else
{
- ensureGeometry(aPolyPolygon, rFrom, rTo, nOffset);
rTargetColor.push_back(
- new PolyPolygonColorPrimitive2D(
- aPolyPolygon,
- rFrom.getColor()));
+ new SvgRadialAtomPrimitive2D(
+ rFrom.getColor(), fScaleFrom,
+ rTo.getColor(), fScaleTo));
}
- if(bOpacityChange)
- {
- const double fTransFrom(1.0 - rFrom.getOpacity());
- const double fTransTo(1.0 - rTo.getOpacity());
- const basegfx::BColor aColorFrom(fTransFrom, fTransFrom, fTransFrom);
- const basegfx::BColor aColorTo(fTransTo, fTransTo, fTransTo);
- const double fScaleFrom(rFrom.getOffset() + nOffset);
- const double fScaleTo(rTo.getOffset() + nOffset);
+ const double fTransFrom(1.0 - rFrom.getOpacity());
+ const double fTransTo(1.0 - rTo.getOpacity());
+ const basegfx::BColor aColorFrom(fTransFrom, fTransFrom, fTransFrom);
+ const basegfx::BColor aColorTo(fTransTo, fTransTo, fTransTo);
- if(isFocalSet())
- {
- const basegfx::B2DVector aTranslateFrom(maFocalVector * (maFocalLength - fScaleFrom));
- const basegfx::B2DVector aTranslateTo(maFocalVector * (maFocalLength - fScaleTo));
+ if(isFocalSet())
+ {
+ const basegfx::B2DVector aTranslateFrom(maFocalVector * (maFocalLength - fScaleFrom));
+ const basegfx::B2DVector aTranslateTo(maFocalVector * (maFocalLength - fScaleTo));
- rTargetOpacity.push_back(
- new SvgRadialAtomPrimitive2D(
- aColorFrom, fScaleFrom, aTranslateFrom,
- aColorTo, fScaleTo, aTranslateTo,
- getOverlapping()));
- }
- else
- {
- rTargetOpacity.push_back(
- new SvgRadialAtomPrimitive2D(
- aColorFrom, fScaleFrom,
- aColorTo, fScaleTo,
- getOverlapping()));
- }
+ rTargetOpacity.push_back(
+ new SvgRadialAtomPrimitive2D(
+ aColorFrom, fScaleFrom, aTranslateFrom,
+ aColorTo, fScaleTo, aTranslateTo));
}
- else if(!getFullyOpaque())
+ else
{
- const double fTransparence(1.0 - rFrom.getOpacity());
-
- ensureGeometry(aPolyPolygon, rFrom, rTo, nOffset);
rTargetOpacity.push_back(
- new PolyPolygonColorPrimitive2D(
- aPolyPolygon,
- basegfx::BColor(fTransparence, fTransparence, fTransparence)));
+ new SvgRadialAtomPrimitive2D(
+ aColorFrom, fScaleFrom,
+ aColorTo, fScaleTo));
}
}
}
@@ -791,8 +676,8 @@ namespace drawinglayer
}
}
- Primitive2DSequence SvgRadialGradientPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
- {
+ Primitive2DSequence SvgRadialGradientPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
Primitive2DSequence xRetval;
if(!getPreconditionsChecked())
@@ -893,42 +778,41 @@ namespace drawinglayer
}
return xRetval;
- }
+ }
- SvgRadialGradientPrimitive2D::SvgRadialGradientPrimitive2D(
- const basegfx::B2DPolyPolygon& rPolyPolygon,
+ SvgRadialGradientPrimitive2D::SvgRadialGradientPrimitive2D(
+ const basegfx::B2DPolyPolygon& rPolyPolygon,
const SvgGradientEntryVector& rGradientEntries,
const basegfx::B2DPoint& rStart,
double fRadius,
SpreadMethod aSpreadMethod,
- const basegfx::B2DPoint* pFocal,
- double fOverlapping)
- : BufferedDecompositionPrimitive2D(),
- SvgGradientHelper(rPolyPolygon, rGradientEntries, rStart, aSpreadMethod, fOverlapping),
+ const basegfx::B2DPoint* pFocal)
+ : BufferedDecompositionPrimitive2D(),
+ SvgGradientHelper(rPolyPolygon, rGradientEntries, rStart, aSpreadMethod),
mfRadius(fRadius),
maFocal(rStart),
maFocalVector(0.0, 0.0),
maFocalLength(0.0),
maMirroredGradientEntries(),
mbFocalSet(false)
- {
+ {
if(pFocal)
{
maFocal = *pFocal;
maFocalVector = maFocal - getStart();
mbFocalSet = true;
}
- }
+ }
- bool SvgRadialGradientPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
- {
+ bool SvgRadialGradientPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
const SvgGradientHelper* pSvgGradientHelper = dynamic_cast< const SvgGradientHelper* >(&rPrimitive);
if(pSvgGradientHelper && SvgGradientHelper::operator==(*pSvgGradientHelper))
- {
- const SvgRadialGradientPrimitive2D& rCompare = static_cast< const SvgRadialGradientPrimitive2D& >(rPrimitive);
+ {
+ const SvgRadialGradientPrimitive2D& rCompare = static_cast< const SvgRadialGradientPrimitive2D& >(rPrimitive);
- if(getRadius() == rCompare.getRadius())
+ if(getRadius() == rCompare.getRadius())
{
if(isFocalSet() == rCompare.isFocalSet())
{
@@ -942,21 +826,21 @@ namespace drawinglayer
}
}
}
- }
+ }
- return false;
- }
+ return false;
+ }
- basegfx::B2DRange SvgRadialGradientPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
- {
- // return ObjectRange
- return getPolyPolygon().getB2DRange();
- }
+ basegfx::B2DRange SvgRadialGradientPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ // return ObjectRange
+ return getPolyPolygon().getB2DRange();
+ }
- // provide unique ID
- ImplPrimitrive2DIDBlock(SvgRadialGradientPrimitive2D, PRIMITIVE2D_ID_SVGRADIALGRADIENTPRIMITIVE2D)
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(SvgRadialGradientPrimitive2D, PRIMITIVE2D_ID_SVGRADIALGRADIENTPRIMITIVE2D)
- } // end of namespace primitive2d
+ } // end of namespace primitive2d
} // end of namespace drawinglayer
//////////////////////////////////////////////////////////////////////////////
@@ -964,8 +848,8 @@ namespace drawinglayer
namespace drawinglayer
{
- namespace primitive2d
- {
+ namespace primitive2d
+ {
Primitive2DSequence SvgLinearAtomPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
{
Primitive2DSequence xRetval;
@@ -973,81 +857,73 @@ namespace drawinglayer
if(!basegfx::fTools::equalZero(fDelta))
{
- if(getColorA() == getColorB())
- {
- const basegfx::B2DPolygon aPolygon(
- basegfx::tools::createPolygonFromRect(
- basegfx::B2DRange(
- getOffsetA() - getOverlapping(),
- 0.0,
- getOffsetB() + getOverlapping(),
- 1.0)));
-
- xRetval.realloc(1);
- xRetval[0] = new PolyPolygonColorPrimitive2D(
- basegfx::B2DPolyPolygon(aPolygon),
- getColorA());
- }
- else
- {
- // calc discrete length to change color all 2.5 pixels
- sal_uInt32 nSteps(basegfx::fround(fDelta / (getDiscreteUnit() * 2.5)));
+ // use one discrete unit for overlap (one pixel)
+ const double fDiscreteUnit(getDiscreteUnit());
- // use color distance, assume to do every 3rd
- const double fColorDistance(getColorA().getDistance(getColorB()));
- const sal_uInt32 nColorSteps(basegfx::fround(fColorDistance * (255.0 * 0.3)));
- nSteps = std::min(nSteps, nColorSteps);
+ // use color distance and discrete lengths to calculate step count
+ const sal_uInt32 nSteps(calculateStepsForSvgGradient(getColorA(), getColorB(), fDelta, fDiscreteUnit));
- // roughly cut when too big
- nSteps = std::min(nSteps, sal_uInt32(100));
- nSteps = std::max(nSteps, sal_uInt32(1));
+ // prepare loop and polygon (with overlap for linear gradients)
+ double fStart(0.0);
+ double fStep(fDelta / nSteps);
+ const basegfx::B2DPolygon aPolygon(
+ basegfx::tools::createPolygonFromRect(
+ basegfx::B2DRange(
+ getOffsetA() - fDiscreteUnit,
+ 0.0,
+ getOffsetA() + fStep + fDiscreteUnit,
+ 1.0)));
- // preapare iteration
- double fStart(0.0);
- double fStep(fDelta / nSteps);
+ // loop and create primitives
+ xRetval.realloc(nSteps);
- xRetval.realloc(nSteps);
+ for(sal_uInt32 a(0); a < nSteps; a++, fStart += fStep)
+ {
+ basegfx::B2DPolygon aNew(aPolygon);
- for(sal_uInt32 a(0); a < nSteps; a++, fStart += fStep)
- {
- const double fLeft(getOffsetA() + fStart);
- const double fRight(fLeft + fStep);
- const basegfx::B2DPolygon aPolygon(
- basegfx::tools::createPolygonFromRect(
- basegfx::B2DRange(
- fLeft - getOverlapping(),
- 0.0,
- fRight + getOverlapping(),
- 1.0)));
-
- xRetval[a] = new PolyPolygonColorPrimitive2D(
- basegfx::B2DPolyPolygon(aPolygon),
- basegfx::interpolate(getColorA(), getColorB(), fStart/fDelta));
- }
+ aNew.transform(basegfx::tools::createTranslateB2DHomMatrix(fStart, 0.0));
+ xRetval[a] = new PolyPolygonColorPrimitive2D(
+ basegfx::B2DPolyPolygon(aNew),
+ basegfx::interpolate(getColorA(), getColorB(), fStart/fDelta));
}
}
return xRetval;
}
+ SvgLinearAtomPrimitive2D::SvgLinearAtomPrimitive2D(
+ const basegfx::BColor& aColorA, double fOffsetA,
+ const basegfx::BColor& aColorB, double fOffsetB)
+ : DiscreteMetricDependentPrimitive2D(),
+ maColorA(aColorA),
+ maColorB(aColorB),
+ mfOffsetA(fOffsetA),
+ mfOffsetB(fOffsetB)
+ {
+ if(mfOffsetA > mfOffsetB)
+ {
+ OSL_ENSURE(false, "Wrong offset order (!)");
+ ::std::swap(mfOffsetA, mfOffsetB);
+ }
+ }
+
bool SvgLinearAtomPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
{
- if(DiscreteMetricDependentPrimitive2D::operator==(rPrimitive))
- {
- const SvgLinearAtomPrimitive2D& rCompare = static_cast< const SvgLinearAtomPrimitive2D& >(rPrimitive);
+ if(DiscreteMetricDependentPrimitive2D::operator==(rPrimitive))
+ {
+ const SvgLinearAtomPrimitive2D& rCompare = static_cast< const SvgLinearAtomPrimitive2D& >(rPrimitive);
- return (getColorA() == rCompare.getColorA()
+ return (getColorA() == rCompare.getColorA()
&& getColorB() == rCompare.getColorB()
&& getOffsetA() == rCompare.getOffsetA()
- && getOffsetB() == rCompare.getOffsetB()
- && getOverlapping() == rCompare.getOverlapping());
- }
+ && getOffsetB() == rCompare.getOffsetB());
+ }
- return false;
+ return false;
}
- // provide unique ID
- ImplPrimitrive2DIDBlock(SvgLinearAtomPrimitive2D, PRIMITIVE2D_ID_SVGLINEARATOMPRIMITIVE2D)
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(SvgLinearAtomPrimitive2D, PRIMITIVE2D_ID_SVGLINEARATOMPRIMITIVE2D)
} // end of namespace primitive2d
} // end of namespace drawinglayer
@@ -1057,8 +933,8 @@ namespace drawinglayer
namespace drawinglayer
{
- namespace primitive2d
- {
+ namespace primitive2d
+ {
Primitive2DSequence SvgRadialAtomPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
{
Primitive2DSequence xRetval;
@@ -1066,182 +942,151 @@ namespace drawinglayer
if(!basegfx::fTools::equalZero(fDeltaScale))
{
- if(getColorA() == getColorB())
- {
- basegfx::B2DPolygon aPolygonA(basegfx::tools::createPolygonFromUnitCircle());
- basegfx::B2DPolygon aPolygonB(basegfx::tools::createPolygonFromUnitCircle());
- double fScaleA(getScaleA());
- const double fScaleB(getScaleB());
+ // use one discrete unit for overlap (one pixel)
+ const double fDiscreteUnit(getDiscreteUnit());
- if(fScaleA > getOverlapping())
- {
- fScaleA -= getOverlapping();
- }
+ // use color distance and discrete lengths to calculate step count
+ const sal_uInt32 nSteps(calculateStepsForSvgGradient(getColorA(), getColorB(), fDeltaScale, fDiscreteUnit));
- const bool bUseA(basegfx::fTools::equalZero(fScaleA));
+ // prepare loop (outside to inside, full polygons, no polypolygons with holes)
+ double fEndScale(getScaleB());
+ double fStepScale(fDeltaScale / nSteps);
- if(getTranslateSet())
- {
- if(bUseA)
- {
- aPolygonA.transform(
- basegfx::tools::createScaleTranslateB2DHomMatrix(
- fScaleA,
- fScaleA,
- getTranslateA().getX(),
- getTranslateA().getY()));
- }
+ // loop and create primitives
+ xRetval.realloc(nSteps);
+
+ for(sal_uInt32 a(0); a < nSteps; a++, fEndScale -= fStepScale)
+ {
+ const double fUnitScale(fEndScale/fDeltaScale);
+ basegfx::B2DHomMatrix aTransform;
- aPolygonB.transform(
- basegfx::tools::createScaleTranslateB2DHomMatrix(
- fScaleB,
- fScaleB,
- getTranslateB().getX(),
- getTranslateB().getY()));
+ if(isTranslateSet())
+ {
+ const basegfx::B2DVector aTranslate(
+ basegfx::interpolate(
+ getTranslateA(),
+ getTranslateB(),
+ fUnitScale));
+
+ aTransform = basegfx::tools::createScaleTranslateB2DHomMatrix(
+ fEndScale,
+ fEndScale,
+ aTranslate.getX(),
+ aTranslate.getY());
}
else
{
- if(bUseA)
- {
- aPolygonA.transform(
- basegfx::tools::createScaleB2DHomMatrix(
- fScaleA,
- fScaleA));
- }
-
- aPolygonB.transform(
- basegfx::tools::createScaleB2DHomMatrix(
- fScaleB,
- fScaleB));
+ aTransform = basegfx::tools::createScaleB2DHomMatrix(
+ fEndScale,
+ fEndScale);
}
- basegfx::B2DPolyPolygon aPolyPolygon(aPolygonB);
-
- if(bUseA)
- {
- aPolyPolygon.append(aPolygonA);
- }
+ basegfx::B2DPolygon aNew(basegfx::tools::createPolygonFromUnitCircle());
- xRetval.realloc(1);
-
- xRetval[0] = new PolyPolygonColorPrimitive2D(
- aPolyPolygon,
- getColorA());
+ aNew.transform(aTransform);
+ xRetval[a] = new PolyPolygonColorPrimitive2D(
+ basegfx::B2DPolyPolygon(aNew),
+ basegfx::interpolate(getColorA(), getColorB(), fUnitScale));
}
- else
- {
- // calc discrete length to change color all 2.5 pixels
- sal_uInt32 nSteps(basegfx::fround(fDeltaScale / (getDiscreteUnit() * 2.5)));
-
- // use color distance, assume to do every 3rd
- const double fColorDistance(getColorA().getDistance(getColorB()));
- const sal_uInt32 nColorSteps(basegfx::fround(fColorDistance * (255.0 * 0.3)));
- nSteps = std::min(nSteps, nColorSteps);
-
- // roughly cut when too big
- nSteps = std::min(nSteps, sal_uInt32(100));
- nSteps = std::max(nSteps, sal_uInt32(1));
-
- // preapare iteration
- double fStartScale(0.0);
- double fStepScale(fDeltaScale / nSteps);
-
- xRetval.realloc(nSteps);
-
- for(sal_uInt32 a(0); a < nSteps; a++, fStartScale += fStepScale)
- {
- double fScaleA(getScaleA() + fStartScale);
- const double fScaleB(fScaleA + fStepScale);
- const double fUnitScale(fStartScale/fDeltaScale);
- basegfx::B2DPolygon aPolygonA(basegfx::tools::createPolygonFromUnitCircle());
- basegfx::B2DPolygon aPolygonB(basegfx::tools::createPolygonFromUnitCircle());
+ }
- if(fScaleA > getOverlapping())
- {
- fScaleA -= getOverlapping();
- }
-
- const bool bUseA(basegfx::fTools::equalZero(fScaleA));
+ return xRetval;
+ }
- if(getTranslateSet())
- {
- const double fUnitScaleEnd((fStartScale + fStepScale)/fDeltaScale);
- const basegfx::B2DVector aTranslateB(basegfx::interpolate(getTranslateA(), getTranslateB(), fUnitScaleEnd));
+ SvgRadialAtomPrimitive2D::SvgRadialAtomPrimitive2D(
+ const basegfx::BColor& aColorA, double fScaleA, const basegfx::B2DVector& rTranslateA,
+ const basegfx::BColor& aColorB, double fScaleB, const basegfx::B2DVector& rTranslateB)
+ : DiscreteMetricDependentPrimitive2D(),
+ maColorA(aColorA),
+ maColorB(aColorB),
+ mfScaleA(fScaleA),
+ mfScaleB(fScaleB),
+ mpTranslate(0)
+ {
+ // check and evtl. set translations
+ if(!rTranslateA.equal(rTranslateB))
+ {
+ mpTranslate = new VectorPair(rTranslateA, rTranslateB);
+ }
- if(bUseA)
- {
- const basegfx::B2DVector aTranslateA(basegfx::interpolate(getTranslateA(), getTranslateB(), fUnitScale));
-
- aPolygonA.transform(
- basegfx::tools::createScaleTranslateB2DHomMatrix(
- fScaleA,
- fScaleA,
- aTranslateA.getX(),
- aTranslateA.getY()));
- }
+ // scale A and B have to be positive
+ mfScaleA = ::std::max(mfScaleA, 0.0);
+ mfScaleB = ::std::max(mfScaleB, 0.0);
- aPolygonB.transform(
- basegfx::tools::createScaleTranslateB2DHomMatrix(
- fScaleB,
- fScaleB,
- aTranslateB.getX(),
- aTranslateB.getY()));
- }
- else
- {
- if(bUseA)
- {
- aPolygonA.transform(
- basegfx::tools::createScaleB2DHomMatrix(
- fScaleA,
- fScaleA));
- }
+ // scale B has to be bigger than scale A; swap if different
+ if(mfScaleA > mfScaleB)
+ {
+ OSL_ENSURE(false, "Wrong offset order (!)");
+ ::std::swap(mfScaleA, mfScaleB);
- aPolygonB.transform(
- basegfx::tools::createScaleB2DHomMatrix(
- fScaleB,
- fScaleB));
- }
+ if(mpTranslate)
+ {
+ ::std::swap(mpTranslate->maTranslateA, mpTranslate->maTranslateB);
+ }
+ }
+ }
- basegfx::B2DPolyPolygon aPolyPolygon(aPolygonB);
-
- if(bUseA)
- {
- aPolyPolygon.append(aPolygonA);
- }
+ SvgRadialAtomPrimitive2D::SvgRadialAtomPrimitive2D(
+ const basegfx::BColor& aColorA, double fScaleA,
+ const basegfx::BColor& aColorB, double fScaleB)
+ : DiscreteMetricDependentPrimitive2D(),
+ maColorA(aColorA),
+ maColorB(aColorB),
+ mfScaleA(fScaleA),
+ mfScaleB(fScaleB),
+ mpTranslate(0)
+ {
+ // scale A and B have to be positive
+ mfScaleA = ::std::max(mfScaleA, 0.0);
+ mfScaleB = ::std::max(mfScaleB, 0.0);
- xRetval[nSteps - 1 - a] = new PolyPolygonColorPrimitive2D(
- aPolyPolygon,
- basegfx::interpolate(getColorA(), getColorB(), fUnitScale));
- }
- }
+ // scale B has to be bigger than scale A; swap if different
+ if(mfScaleA > mfScaleB)
+ {
+ OSL_ENSURE(false, "Wrong offset order (!)");
+ ::std::swap(mfScaleA, mfScaleB);
}
+ }
- return xRetval;
+ SvgRadialAtomPrimitive2D::~SvgRadialAtomPrimitive2D()
+ {
+ if(mpTranslate)
+ {
+ delete mpTranslate;
+ mpTranslate = 0;
+ }
}
bool SvgRadialAtomPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
{
- if(DiscreteMetricDependentPrimitive2D::operator==(rPrimitive))
- {
- const SvgRadialAtomPrimitive2D& rCompare = static_cast< const SvgRadialAtomPrimitive2D& >(rPrimitive);
+ if(DiscreteMetricDependentPrimitive2D::operator==(rPrimitive))
+ {
+ const SvgRadialAtomPrimitive2D& rCompare = static_cast< const SvgRadialAtomPrimitive2D& >(rPrimitive);
- return (getColorA() == rCompare.getColorA()
+ if(getColorA() == rCompare.getColorA()
&& getColorB() == rCompare.getColorB()
&& getScaleA() == rCompare.getScaleA()
- && getScaleB() == rCompare.getScaleB()
- && getTranslateA() == rCompare.getTranslateA()
- && getTranslateB() == rCompare.getTranslateB()
- && getOverlapping() == rCompare.getOverlapping());
- }
+ && getScaleB() == rCompare.getScaleB())
+ {
+ if(isTranslateSet() && rCompare.isTranslateSet())
+ {
+ return (getTranslateA() == rCompare.getTranslateA()
+ && getTranslateB() == rCompare.getTranslateB());
+ }
+ else if(!isTranslateSet() && !rCompare.isTranslateSet())
+ {
+ return true;
+ }
+ }
+ }
- return false;
+ return false;
}
- // provide unique ID
- ImplPrimitrive2DIDBlock(SvgRadialAtomPrimitive2D, PRIMITIVE2D_ID_SVGRADIALATOMPRIMITIVE2D)
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(SvgRadialAtomPrimitive2D, PRIMITIVE2D_ID_SVGRADIALATOMPRIMITIVE2D)
- } // end of namespace primitive2d
+ } // end of namespace primitive2d
} // end of namespace drawinglayer
//////////////////////////////////////////////////////////////////////////////
Modified: incubator/ooo/trunk/main/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx?rev=1235361&r1=1235360&r2=1235361&view=diff
==============================================================================
--- incubator/ooo/trunk/main/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx (original)
+++ incubator/ooo/trunk/main/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx Tue Jan 24 17:13:46 2012
@@ -55,7 +55,7 @@
#include <drawinglayer/primitive2d/backgroundcolorprimitive2d.hxx>
#include <basegfx/matrix/b2dhommatrixtools.hxx>
#include <drawinglayer/primitive2d/epsprimitive2d.hxx>
-
+#include <drawinglayer/primitive2d/svggradientprimitive2d.hxx>
#include <toolkit/helper/vclunohelper.hxx>
#include <vcl/window.hxx>
@@ -573,6 +573,16 @@ namespace drawinglayer
RenderEpsPrimitive2D(static_cast< const primitive2d::EpsPrimitive2D& >(rCandidate));
break;
}
+ case PRIMITIVE2D_ID_SVGLINEARATOMPRIMITIVE2D:
+ {
+ RenderSvgLinearAtomPrimitive2D(static_cast< const primitive2d::SvgLinearAtomPrimitive2D& >(rCandidate));
+ break;
+ }
+ case PRIMITIVE2D_ID_SVGRADIALATOMPRIMITIVE2D:
+ {
+ RenderSvgRadialAtomPrimitive2D(static_cast< const primitive2d::SvgRadialAtomPrimitive2D& >(rCandidate));
+ break;
+ }
default :
{
// process recursively
Modified: incubator/ooo/trunk/main/drawinglayer/source/processor2d/vclprocessor2d.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/drawinglayer/source/processor2d/vclprocessor2d.cxx?rev=1235361&r1=1235360&r2=1235361&view=diff
==============================================================================
--- incubator/ooo/trunk/main/drawinglayer/source/processor2d/vclprocessor2d.cxx (original)
+++ incubator/ooo/trunk/main/drawinglayer/source/processor2d/vclprocessor2d.cxx Tue Jan 24 17:13:46 2012
@@ -56,6 +56,9 @@
#include <vcl/metric.hxx>
#include <drawinglayer/primitive2d/textenumsprimitive2d.hxx>
#include <drawinglayer/primitive2d/epsprimitive2d.hxx>
+#include <drawinglayer/primitive2d/svggradientprimitive2d.hxx>
+#include <basegfx/color/bcolor.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
//////////////////////////////////////////////////////////////////////////////
// control support
@@ -78,6 +81,34 @@ using namespace com::sun::star;
//////////////////////////////////////////////////////////////////////////////
+namespace
+{
+ sal_uInt32 calculateStepsForSvgGradient(const basegfx::BColor& rColorA, const basegfx::BColor& rColorB, double fDelta, double fDiscreteUnit)
+ {
+ // use color distance, assume to do every color step
+ sal_uInt32 nSteps(basegfx::fround(rColorA.getDistance(rColorB) * 255.0));
+
+ if(nSteps)
+ {
+ // calc discrete length to change color each disctete unit (pixel)
+ const sal_uInt32 nDistSteps(basegfx::fround(fDelta / fDiscreteUnit));
+
+ nSteps = std::min(nSteps, nDistSteps);
+ }
+
+ // reduce quality to 3 discrete units or every 3rd color step for rendering
+ nSteps /= 2;
+
+ // roughly cut when too big or too small (not full quality, reduce complexity)
+ nSteps = std::min(nSteps, sal_uInt32(255));
+ nSteps = std::max(nSteps, sal_uInt32(1));
+
+ return nSteps;
+ }
+} // end of anonymous namespace
+
+//////////////////////////////////////////////////////////////////////////////
+
namespace drawinglayer
{
namespace processor2d
@@ -1331,6 +1362,100 @@ namespace drawinglayer
}
}
+ void VclProcessor2D::RenderSvgLinearAtomPrimitive2D(const primitive2d::SvgLinearAtomPrimitive2D& rCandidate)
+ {
+ const double fDelta(rCandidate.getOffsetB() - rCandidate.getOffsetA());
+
+ if(basegfx::fTools::more(fDelta, 0.0))
+ {
+ const basegfx::BColor aColorA(maBColorModifierStack.getModifiedColor(rCandidate.getColorA()));
+ const basegfx::BColor aColorB(maBColorModifierStack.getModifiedColor(rCandidate.getColorB()));
+ const double fDiscreteUnit((getViewInformation2D().getInverseObjectToViewTransformation() * basegfx::B2DVector(1.0, 0.0)).getLength());
+
+ // use color distance and discrete lengths to calculate step count
+ const sal_uInt32 nSteps(calculateStepsForSvgGradient(aColorA, aColorB, fDelta, fDiscreteUnit));
+
+ // prepare loop and polygon
+ double fStart(0.0);
+ double fStep(fDelta / nSteps);
+ const basegfx::B2DPolygon aPolygon(
+ basegfx::tools::createPolygonFromRect(
+ basegfx::B2DRange(
+ rCandidate.getOffsetA() - fDiscreteUnit,
+ 0.0,
+ rCandidate.getOffsetA() + fStep + fDiscreteUnit,
+ 1.0)));
+
+ // switch off line painting
+ mpOutputDevice->SetLineColor();
+
+ // loop and paint
+ for(sal_uInt32 a(0); a < nSteps; a++, fStart += fStep)
+ {
+ basegfx::B2DPolygon aNew(aPolygon);
+
+ aNew.transform(maCurrentTransformation * basegfx::tools::createTranslateB2DHomMatrix(fStart, 0.0));
+ mpOutputDevice->SetFillColor(Color(basegfx::interpolate(aColorA, aColorB, fStart/fDelta)));
+ mpOutputDevice->DrawPolyPolygon(basegfx::B2DPolyPolygon(aNew));
+ }
+ }
+ }
+
+ void VclProcessor2D::RenderSvgRadialAtomPrimitive2D(const primitive2d::SvgRadialAtomPrimitive2D& rCandidate)
+ {
+ const double fDeltaScale(rCandidate.getScaleB() - rCandidate.getScaleA());
+
+ if(basegfx::fTools::more(fDeltaScale, 0.0))
+ {
+ const basegfx::BColor aColorA(maBColorModifierStack.getModifiedColor(rCandidate.getColorA()));
+ const basegfx::BColor aColorB(maBColorModifierStack.getModifiedColor(rCandidate.getColorB()));
+ const double fDiscreteUnit((getViewInformation2D().getInverseObjectToViewTransformation() * basegfx::B2DVector(1.0, 0.0)).getLength());
+
+ // use color distance and discrete lengths to calculate step count
+ const sal_uInt32 nSteps(calculateStepsForSvgGradient(aColorA, aColorB, fDeltaScale, fDiscreteUnit));
+
+ // switch off line painting
+ mpOutputDevice->SetLineColor();
+
+ // prepare loop (outside to inside)
+ double fEndScale(rCandidate.getScaleB());
+ double fStepScale(fDeltaScale / nSteps);
+
+ for(sal_uInt32 a(0); a < nSteps; a++, fEndScale -= fStepScale)
+ {
+ const double fUnitScale(fEndScale/fDeltaScale);
+ basegfx::B2DHomMatrix aTransform;
+
+ if(rCandidate.isTranslateSet())
+ {
+ const basegfx::B2DVector aTranslate(
+ basegfx::interpolate(
+ rCandidate.getTranslateA(),
+ rCandidate.getTranslateB(),
+ fUnitScale));
+
+ aTransform = basegfx::tools::createScaleTranslateB2DHomMatrix(
+ fEndScale,
+ fEndScale,
+ aTranslate.getX(),
+ aTranslate.getY());
+ }
+ else
+ {
+ aTransform = basegfx::tools::createScaleB2DHomMatrix(
+ fEndScale,
+ fEndScale);
+ }
+
+ basegfx::B2DPolygon aNew(basegfx::tools::createPolygonFromUnitCircle());
+
+ aNew.transform(maCurrentTransformation * aTransform);
+ mpOutputDevice->SetFillColor(Color(basegfx::interpolate(aColorA, aColorB, fUnitScale)));
+ mpOutputDevice->DrawPolyPolygon(basegfx::B2DPolyPolygon(aNew));
+ }
+ }
+ }
+
void VclProcessor2D::adaptLineToFillDrawMode() const
{
const sal_uInt32 nOriginalDrawMode(mpOutputDevice->GetDrawMode());