summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArmin Le Grand <Armin.Le.Grand@Sun.COM>2010-06-03 19:01:17 +0200
committerArmin Le Grand <Armin.Le.Grand@Sun.COM>2010-06-03 19:01:17 +0200
commit0e68b7ca6c711f6d6edd1a8b815464e8548f1078 (patch)
treead762e7adbb6e424ea2348c5aa640575a5f2a50d
parent7eea21ded3cb64525a4d82555994736525a6af06 (diff)
parentdf9d75b5f7564818ba26cb7ea5d6fc11fd5c5fa0 (diff)
aw082: merged in aw081 due to the need of #i111235#
-rw-r--r--drawinglayer/inc/drawinglayer/primitive2d/textprimitive2d.hxx45
-rw-r--r--drawinglayer/source/primitive2d/metafileprimitive2d.cxx222
-rw-r--r--drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx6
-rw-r--r--drawinglayer/source/processor2d/vclpixelprocessor2d.cxx12
-rw-r--r--drawinglayer/source/processor3d/zbufferprocessor3d.cxx2
-rw-r--r--svx/inc/svx/sdrmasterpagedescriptor.hxx2
-rw-r--r--svx/inc/svx/svdpage.hxx1
-rw-r--r--svx/source/engine3d/scene3d.cxx14
-rw-r--r--svx/source/engine3d/view3d.cxx178
-rw-r--r--svx/source/sdr/contact/viewcontactofmasterpagedescriptor.cxx27
-rw-r--r--svx/source/sdr/contact/viewcontactofsdrpage.cxx16
-rw-r--r--svx/source/sdr/primitive2d/sdrpathprimitive2d.cxx8
-rw-r--r--svx/source/svdraw/sdrmasterpagedescriptor.cxx12
-rw-r--r--svx/source/svdraw/svdedtv.cxx6
-rw-r--r--svx/source/svdraw/svdocirc.cxx5
-rw-r--r--svx/source/svdraw/svdoedge.cxx41
-rw-r--r--svx/source/svdraw/svdotextpathdecomposition.cxx104
-rw-r--r--svx/source/svdraw/svdpage.cxx65
18 files changed, 439 insertions, 327 deletions
diff --git a/drawinglayer/inc/drawinglayer/primitive2d/textprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/textprimitive2d.hxx
index c1ea62e2aa..3d630d8551 100644
--- a/drawinglayer/inc/drawinglayer/primitive2d/textprimitive2d.hxx
+++ b/drawinglayer/inc/drawinglayer/primitive2d/textprimitive2d.hxx
@@ -62,11 +62,48 @@ namespace drawinglayer
To get better text quality, it is suggested to handle tis primitive directly
in a renderer. In that case, e.g. hintings on the system can be supported.
+
+ @param maTextTransform
+ The text transformation contains the text start position (always baselined)
+ as translation, the FontSize as scale (where width relative to height defines
+ font scaling and width == height means no font scaling) and the font rotation
+ and shear.
+ When shear is used and a renderer does not support it, it may be better to use
+ the decomposition which will do everything correctly. Same is true for mirroring
+ which would be expressed as negative scalings.
+
+ @param rText
+ The text to be used. Only a part may be used, but a bigger part of the string
+ may be necessary for correct layouting (e.g. international)
+
+ @param aTextPosition
+ The index to the first character to use from rText
+
+ @param aTextLength
+ The number of characters to use from rText
+
+ @param rDXArray
+ The distances between the characters. This parameter may be empty, in that case
+ the renderer is responsible to do something useful. If it is given, it has to be of
+ the size aTextLength. Its values are in logical coordinates and describe the
+ distance for each character to use. This is independent from the font width which
+ is given with maTextTransform. The first value is the offset to use from the start
+ point in FontCoordinateSystem X-Direction (given by maTextTransform) to the start
+ point of the second character
+
+ @param rFontAttribute
+ The font definition
+
+ @param rLocale
+ The locale to use
+
+ @param rFontColor
+ The font color to use
*/
class TextSimplePortionPrimitive2D : public BufferedDecompositionPrimitive2D
{
private:
- /// text range transformation from unit range ([0.0 .. 1.0]) to text range
+ /// text transformation (FontCoordinateSystem)
basegfx::B2DHomMatrix maTextTransform;
/// The text, used from maTextPosition up to maTextPosition + maTextLength
@@ -78,10 +115,10 @@ namespace drawinglayer
/// The length for maText usage, starting from maTextPosition
xub_StrLen maTextLength;
- /// The DX array scale-independent in unit coordinates
+ /// The DX array in logic units
::std::vector< double > maDXArray;
- /// The font to use
+ /// The font definition
attribute::FontAttribute maFontAttribute;
/// The Locale for the text
@@ -90,7 +127,7 @@ namespace drawinglayer
/// font color
basegfx::BColor maFontColor;
- /// #i96669# add simple range buffering for this primitive
+ /// #i96669# internal: add simple range buffering for this primitive
basegfx::B2DRange maB2DRange;
protected:
diff --git a/drawinglayer/source/primitive2d/metafileprimitive2d.cxx b/drawinglayer/source/primitive2d/metafileprimitive2d.cxx
index 53662c2d52..3acc312152 100644
--- a/drawinglayer/source/primitive2d/metafileprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/metafileprimitive2d.cxx
@@ -94,8 +94,10 @@ namespace
basegfx::BColor maTextLineColor;
basegfx::BColor maOverlineColor;
- /// clipping, font, etc.
- Region maRegion;
+ /// clipping
+ basegfx::B2DPolyPolygon maClipPolyPoygon;
+
+ /// font, etc.
Font maFont;
RasterOp maRasterOp;
sal_uInt32 mnLayoutMode;
@@ -110,7 +112,7 @@ namespace
bool mbTextFillColor : 1;
bool mbTextLineColor : 1;
bool mbOverlineColor : 1;
- bool mbRegion : 1;
+ bool mbClipPolyPolygonActive : 1;
public:
PropertyHolder()
@@ -122,7 +124,7 @@ namespace
maTextFillColor(),
maTextLineColor(),
maOverlineColor(),
- maRegion(),
+ maClipPolyPoygon(),
maFont(),
maRasterOp(ROP_OVERPAINT),
mnLayoutMode(0),
@@ -134,7 +136,7 @@ namespace
mbTextFillColor(false),
mbTextLineColor(false),
mbOverlineColor(false),
- mbRegion(false)
+ mbClipPolyPolygonActive(false)
{
}
@@ -179,10 +181,10 @@ namespace
bool getOverlineColorActive() const { return mbOverlineColor; }
void setOverlineColorActive(bool bNew) { if(bNew != mbOverlineColor) mbOverlineColor = bNew; }
- const Region& getRegion() const { return maRegion; }
- void setRegion(const Region& rRegion) { if(rRegion != maRegion) maRegion = rRegion; }
- bool getRegionActive() const { return mbRegion; }
- void setRegionActive(bool bNew) { if(bNew != mbRegion) mbRegion = bNew; }
+ const basegfx::B2DPolyPolygon& getClipPolyPolygon() const { return maClipPolyPoygon; }
+ void setClipPolyPolygon(const basegfx::B2DPolyPolygon& rNew) { if(rNew != maClipPolyPoygon) maClipPolyPoygon = rNew; }
+ bool getClipPolyPolygonActive() const { return mbClipPolyPolygonActive; }
+ void setClipPolyPolygonActive(bool bNew) { if(bNew != mbClipPolyPolygonActive) mbClipPolyPolygonActive = bNew; }
const Font& getFont() const { return maFont; }
void setFont(const Font& rFont) { if(rFont != maFont) maFont = rFont; }
@@ -291,8 +293,8 @@ namespace
}
if(!(nPushFlags & PUSH_CLIPREGION ))
{
- pLast->setRegion(pTip->getRegion());
- pLast->setRegionActive(pTip->getRegionActive());
+ pLast->setClipPolyPolygon(pTip->getClipPolyPolygon());
+ pLast->setClipPolyPolygonActive(pTip->getClipPolyPolygonActive());
}
if(!(nPushFlags & PUSH_RASTEROP ))
{
@@ -465,25 +467,18 @@ namespace
// the buffer to not delete them in the destructor.
aTargets.clear();
- if(xRetval.hasElements() && rPropertyHolder.getRegionActive())
+ if(xRetval.hasElements() && rPropertyHolder.getClipPolyPolygonActive())
{
- const Region& rRegion = rPropertyHolder.getRegion();
+ const basegfx::B2DPolyPolygon& rClipPolyPolygon = rPropertyHolder.getClipPolyPolygon();
- if(!rRegion.IsEmpty())
+ if(rClipPolyPolygon.count())
{
- basegfx::B2DPolyPolygon aClipPolyPolygon(getB2DPolyPolygonFromRegion(rRegion));
-
- if(aClipPolyPolygon.count())
- {
- aClipPolyPolygon.transform(rPropertyHolder.getTransformation());
-
- const drawinglayer::primitive2d::Primitive2DReference xMask(
- new drawinglayer::primitive2d::MaskPrimitive2D(
- aClipPolyPolygon,
- xRetval));
-
- xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xMask, 1);
- }
+ const drawinglayer::primitive2d::Primitive2DReference xMask(
+ new drawinglayer::primitive2d::MaskPrimitive2D(
+ rClipPolyPolygon,
+ xRetval));
+
+ xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xMask, 1);
}
}
@@ -972,53 +967,56 @@ namespace
a new target for embracing new geometry to the current region
*/
void HandleNewClipRegion(
- const Region* pRegion,
+ const basegfx::B2DPolyPolygon& rClipPolyPolygon,
TargetHolders& rTargetHolders,
PropertyHolders& rPropertyHolders)
{
- const bool bNewActive(pRegion && !pRegion->IsEmpty());
+ const bool bNewActive(rClipPolyPolygon.count());
- // #i108636# The handlig of new ClipRegions was not done as good as possible
- // in the first version of this interpreter; e.g. when a ClipRegion was set
+ // #i108636# The handlig of new ClipPolyPolygons was not done as good as possible
+ // in the first version of this interpreter; e.g. when a ClipPolyPolygon was set
// initially and then using a lot of push/pop actions, the pop always leads
- // to setting a 'new' ClipRegion which indeed is the return to the ClipRegion
+ // to setting a 'new' ClipPolyPolygon which indeed is the return to the ClipPolyPolygon
// of the properties next on the stack.
- // This ClipRegion is identical to the current one, so there is no need to
+ //
+ // This ClipPolyPolygon is identical to the current one, so there is no need to
// create a MaskPrimitive2D containing the up-to-now created primitives, but
// this was done before. While this does not lead to wrong primitive
// representations of the metafile data, it creates unneccesarily expensive
- // representations. Just detecting when no really 'new' ClipRegion gets set
+ // representations. Just detecting when no really 'new' ClipPolyPolygon gets set
// solves the problem.
- if(!rPropertyHolders.Current().getRegionActive() && !bNewActive)
+ if(!rPropertyHolders.Current().getClipPolyPolygonActive() && !bNewActive)
{
- // no active region exchanged by no new one, done
+ // no active ClipPolyPolygon exchanged by no new one, done
return;
}
- if(rPropertyHolders.Current().getRegionActive() && bNewActive)
+ if(rPropertyHolders.Current().getClipPolyPolygonActive() && bNewActive)
{
- // active region and new active region
- if(rPropertyHolders.Current().getRegion() == *pRegion)
+ // active ClipPolyPolygon and new active ClipPolyPolygon
+ if(rPropertyHolders.Current().getClipPolyPolygon() == rClipPolyPolygon)
{
- // new region is the same as the old region, done
+ // new is the same as old, done
return;
}
}
- // Here the old region and the new one are definitively different, maybe
+ // Here the old and the new are definitively different, maybe
// old one and/or new one is not active.
- // Handle deletion of old region.The process evtl. created primitives which
- // belong to this active region. These need to be embedded to a
+ // Handle deletion of old ClipPolyPolygon. The process evtl. created primitives which
+ // belong to this active ClipPolyPolygon. These need to be embedded to a
// MaskPrimitive2D accordingly.
- if(rPropertyHolders.Current().getRegionActive() && rTargetHolders.size() > 1)
+ if(rPropertyHolders.Current().getClipPolyPolygonActive() && rTargetHolders.size() > 1)
{
drawinglayer::primitive2d::Primitive2DSequence aSubContent;
- if(!rPropertyHolders.Current().getRegion().IsEmpty() && rTargetHolders.Current().size())
+ if(rPropertyHolders.Current().getClipPolyPolygon().count()
+ && rTargetHolders.Current().size())
{
- aSubContent = rTargetHolders.Current().getPrimitive2DSequence(rPropertyHolders.Current());
+ aSubContent = rTargetHolders.Current().getPrimitive2DSequence(
+ rPropertyHolders.Current());
}
rTargetHolders.Pop();
@@ -1033,11 +1031,11 @@ namespace
// apply new settings to current properties by setting
// the new region now
- rPropertyHolders.Current().setRegionActive(bNewActive);
+ rPropertyHolders.Current().setClipPolyPolygonActive(bNewActive);
if(bNewActive)
{
- rPropertyHolders.Current().setRegion(*pRegion);
+ rPropertyHolders.Current().setClipPolyPolygon(rClipPolyPolygon);
// prepare new content holder for new active region
rTargetHolders.Push();
@@ -2414,13 +2412,18 @@ namespace
if(pA->IsClipping())
{
- // new clipping
- HandleNewClipRegion(&pA->GetRegion(), rTargetHolders, rPropertyHolders);
+ // new clipping. Get PolyPolygon and transform with current transformation
+ basegfx::B2DPolyPolygon aNewClipPolyPolygon(getB2DPolyPolygonFromRegion(pA->GetRegion()));
+
+ aNewClipPolyPolygon.transform(rPropertyHolders.Current().getTransformation());
+ HandleNewClipRegion(aNewClipPolyPolygon, rTargetHolders, rPropertyHolders);
}
else
{
// end clipping
- HandleNewClipRegion(0, rTargetHolders, rPropertyHolders);
+ const basegfx::B2DPolyPolygon aEmptyPolyPolygon;
+
+ HandleNewClipRegion(aEmptyPolyPolygon, rTargetHolders, rPropertyHolders);
}
break;
@@ -2434,49 +2437,60 @@ namespace
if(rRectangle.IsEmpty())
{
// intersect with empty rectangle will always give empty
- // region; start new clipping with empty region
- const Region aNewRegion;
- HandleNewClipRegion(&aNewRegion, rTargetHolders, rPropertyHolders);
+ // ClipPolyPolygon; start new clipping with empty PolyPolygon
+ const basegfx::B2DPolyPolygon aEmptyPolyPolygon;
+
+ HandleNewClipRegion(aEmptyPolyPolygon, rTargetHolders, rPropertyHolders);
}
else
{
- if(rPropertyHolders.Current().getRegionActive())
+ // create transformed ClipRange
+ basegfx::B2DRange aClipRange(
+ rRectangle.Left(), rRectangle.Top(),
+ rRectangle.Right(), rRectangle.Bottom());
+
+ aClipRange.transform(rPropertyHolders.Current().getTransformation());
+
+ if(rPropertyHolders.Current().getClipPolyPolygonActive())
{
- if(rPropertyHolders.Current().getRegion().IsEmpty())
+ if(0 == rPropertyHolders.Current().getClipPolyPolygon().count())
{
- // nothing to do, empty active clip region will stay
+ // nothing to do, empty active clipPolyPolygon will stay
// empty when intersecting
}
else
{
- // AND existing region and new rectangle
+ // AND existing region and new ClipRange
const basegfx::B2DPolyPolygon aOriginalPolyPolygon(
- getB2DPolyPolygonFromRegion(rPropertyHolders.Current().getRegion()));
+ rPropertyHolders.Current().getClipPolyPolygon());
basegfx::B2DPolyPolygon aClippedPolyPolygon;
if(aOriginalPolyPolygon.count())
{
- const basegfx::B2DRange aIntersectRange(
- rRectangle.Left(), rRectangle.Top(),
- rRectangle.Right(), rRectangle.Bottom());
-
aClippedPolyPolygon = basegfx::tools::clipPolyPolygonOnRange(
- aOriginalPolyPolygon, aIntersectRange, true, false);
+ aOriginalPolyPolygon,
+ aClipRange,
+ true,
+ false);
}
if(aClippedPolyPolygon != aOriginalPolyPolygon)
{
// start new clipping with intersected region
- const Region aNewRegion(aClippedPolyPolygon);
- HandleNewClipRegion(&aNewRegion, rTargetHolders, rPropertyHolders);
+ HandleNewClipRegion(
+ aClippedPolyPolygon,
+ rTargetHolders,
+ rPropertyHolders);
}
}
}
else
{
- // start new clipping with rectangle
- const Region aNewRegion(rRectangle);
- HandleNewClipRegion(&aNewRegion, rTargetHolders, rPropertyHolders);
+ // start new clipping with ClipRange
+ const basegfx::B2DPolyPolygon aNewClipPolyPolygon(
+ basegfx::tools::createPolygonFromRect(aClipRange));
+
+ HandleNewClipRegion(aNewClipPolyPolygon, rTargetHolders, rPropertyHolders);
}
}
@@ -2491,50 +2505,48 @@ namespace
if(rNewRegion.IsEmpty())
{
// intersect with empty region will always give empty
- // region; start new clipping with empty region
- const Region aNewRegion;
- HandleNewClipRegion(&aNewRegion, rTargetHolders, rPropertyHolders);
+ // region; start new clipping with empty PolyPolygon
+ const basegfx::B2DPolyPolygon aEmptyPolyPolygon;
+
+ HandleNewClipRegion(aEmptyPolyPolygon, rTargetHolders, rPropertyHolders);
}
else
{
- if(rPropertyHolders.Current().getRegionActive())
+ // get new ClipPolyPolygon, transform it with current transformation
+ basegfx::B2DPolyPolygon aNewClipPolyPolygon(getB2DPolyPolygonFromRegion(rNewRegion));
+ aNewClipPolyPolygon.transform(rPropertyHolders.Current().getTransformation());
+
+ if(rPropertyHolders.Current().getClipPolyPolygonActive())
{
- if(rPropertyHolders.Current().getRegion().IsEmpty())
+ if(0 == rPropertyHolders.Current().getClipPolyPolygon().count())
{
- // nothing to do, empty active clip region will stay empty
+ // nothing to do, empty active clipPolyPolygon will stay empty
// when intersecting with any region
}
else
{
// AND existing and new region
const basegfx::B2DPolyPolygon aOriginalPolyPolygon(
- getB2DPolyPolygonFromRegion(rPropertyHolders.Current().getRegion()));
+ rPropertyHolders.Current().getClipPolyPolygon());
basegfx::B2DPolyPolygon aClippedPolyPolygon;
if(aOriginalPolyPolygon.count())
{
- const basegfx::B2DPolyPolygon aClipPolyPolygon(
- getB2DPolyPolygonFromRegion(rNewRegion));
-
- if(aClipPolyPolygon.count())
- {
- aClippedPolyPolygon = basegfx::tools::clipPolyPolygonOnPolyPolygon(
- aOriginalPolyPolygon, aClipPolyPolygon, true, false);
- }
+ aClippedPolyPolygon = basegfx::tools::clipPolyPolygonOnPolyPolygon(
+ aOriginalPolyPolygon, aNewClipPolyPolygon, true, false);
}
if(aClippedPolyPolygon != aOriginalPolyPolygon)
{
- // start new clipping with intersected region
- const Region aNewRegion(aClippedPolyPolygon);
- HandleNewClipRegion(&aNewRegion, rTargetHolders, rPropertyHolders);
+ // start new clipping with intersected ClipPolyPolygon
+ HandleNewClipRegion(aClippedPolyPolygon, rTargetHolders, rPropertyHolders);
}
}
}
else
{
- // start new clipping with new region
- HandleNewClipRegion(&rNewRegion, rTargetHolders, rPropertyHolders);
+ // start new clipping with new ClipPolyPolygon
+ HandleNewClipRegion(aNewClipPolyPolygon, rTargetHolders, rPropertyHolders);
}
}
@@ -2545,24 +2557,31 @@ namespace
/** CHECKED, WORKS WELL */
const MetaMoveClipRegionAction* pA = (const MetaMoveClipRegionAction*)pAction;
- if(rPropertyHolders.Current().getRegionActive())
+ if(rPropertyHolders.Current().getClipPolyPolygonActive())
{
- if(rPropertyHolders.Current().getRegion().IsEmpty())
+ if(0 == rPropertyHolders.Current().getClipPolyPolygon().count())
{
// nothing to do
}
else
{
- // move using old interface
- Region aRegion(rPropertyHolders.Current().getRegion());
-
const sal_Int32 nHor(pA->GetHorzMove());
const sal_Int32 nVer(pA->GetVertMove());
if(0 != nHor || 0 != nVer)
{
- aRegion.Move(nHor, nVer);
- HandleNewClipRegion(&aRegion, rTargetHolders, rPropertyHolders);
+ // prepare translation, add current transformation
+ basegfx::B2DVector aVector(pA->GetHorzMove(), pA->GetVertMove());
+ aVector *= rPropertyHolders.Current().getTransformation();
+ basegfx::B2DHomMatrix aTransform(
+ basegfx::tools::createTranslateB2DHomMatrix(aVector));
+
+ // transform existing region
+ basegfx::B2DPolyPolygon aClipPolyPolygon(
+ rPropertyHolders.Current().getClipPolyPolygon());
+
+ aClipPolyPolygon.transform(aTransform);
+ HandleNewClipRegion(aClipPolyPolygon, rTargetHolders, rPropertyHolders);
}
}
}
@@ -2767,10 +2786,12 @@ namespace
const bool bRegionMayChange(rPropertyHolders.Current().getPushFlags() & PUSH_CLIPREGION);
const bool bRasterOpMayChange(rPropertyHolders.Current().getPushFlags() & PUSH_RASTEROP);
- if(bRegionMayChange && rPropertyHolders.Current().getRegionActive())
+ if(bRegionMayChange && rPropertyHolders.Current().getClipPolyPolygonActive())
{
// end evtl. clipping
- HandleNewClipRegion(0, rTargetHolders, rPropertyHolders);
+ const basegfx::B2DPolyPolygon aEmptyPolyPolygon;
+
+ HandleNewClipRegion(aEmptyPolyPolygon, rTargetHolders, rPropertyHolders);
}
if(bRasterOpMayChange && rPropertyHolders.Current().isRasterOpActive())
@@ -2787,10 +2808,11 @@ namespace
HandleNewRasterOp(rPropertyHolders.Current().getRasterOp(), rTargetHolders, rPropertyHolders);
}
- if(bRegionMayChange && rPropertyHolders.Current().getRegionActive())
+ if(bRegionMayChange && rPropertyHolders.Current().getClipPolyPolygonActive())
{
// start evtl. clipping
- HandleNewClipRegion(&rPropertyHolders.Current().getRegion(), rTargetHolders, rPropertyHolders);
+ HandleNewClipRegion(
+ rPropertyHolders.Current().getClipPolyPolygon(), rTargetHolders, rPropertyHolders);
}
break;
diff --git a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
index f3ae8e5fb6..d2d68359cb 100644
--- a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
@@ -1441,7 +1441,11 @@ namespace drawinglayer
{
// there is already a clip polygon set; build clipped union of
// current mask polygon and new one
- maClipPolyPolygon = basegfx::tools::clipPolyPolygonOnPolyPolygon(aMask, maClipPolyPolygon, false, false);
+ maClipPolyPolygon = basegfx::tools::clipPolyPolygonOnPolyPolygon(
+ aMask,
+ maClipPolyPolygon,
+ true, // #i106516# we want the inside of aMask, not the outside
+ false);
}
else
{
diff --git a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
index 19f415faba..03164c47a3 100644
--- a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
@@ -469,19 +469,29 @@ namespace drawinglayer
// This is wrong in principle, but looks nicer. This could also be done here directly
// without VCL usage if needed
const primitive2d::FillHatchPrimitive2D& rFillHatchPrimitive = static_cast< const primitive2d::FillHatchPrimitive2D& >(rCandidate);
+ const attribute::FillHatchAttribute& rFillHatchAttributes = rFillHatchPrimitive.getFillHatch();
// create hatch polygon in range size and discrete coordinates
basegfx::B2DRange aHatchRange(rFillHatchPrimitive.getObjectRange());
aHatchRange.transform(maCurrentTransformation);
const basegfx::B2DPolygon aHatchPolygon(basegfx::tools::createPolygonFromRect(aHatchRange));
+ if(rFillHatchAttributes.isFillBackground())
+ {
+ // #i111846# background fill is active; draw fill polygon
+ const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(rFillHatchPrimitive.getBColor()));
+
+ mpOutputDevice->SetFillColor(Color(aPolygonColor));
+ mpOutputDevice->SetLineColor();
+ mpOutputDevice->DrawPolygon(aHatchPolygon);
+ }
+
// set hatch line color
const basegfx::BColor aHatchColor(maBColorModifierStack.getModifiedColor(rFillHatchPrimitive.getBColor()));
mpOutputDevice->SetFillColor();
mpOutputDevice->SetLineColor(Color(aHatchColor));
// get hatch style
- const attribute::FillHatchAttribute& rFillHatchAttributes = rFillHatchPrimitive.getFillHatch();
HatchStyle eHatchStyle(HATCH_SINGLE);
switch(rFillHatchAttributes.getStyle())
diff --git a/drawinglayer/source/processor3d/zbufferprocessor3d.cxx b/drawinglayer/source/processor3d/zbufferprocessor3d.cxx
index 679e918bda..c051942d64 100644
--- a/drawinglayer/source/processor3d/zbufferprocessor3d.cxx
+++ b/drawinglayer/source/processor3d/zbufferprocessor3d.cxx
@@ -487,7 +487,7 @@ private:
boost::shared_ptr< drawinglayer::texture::GeoTexSvx > mpTransparenceGeoTexSvx;
drawinglayer::attribute::MaterialAttribute3D maMaterial;
basegfx::B3DPolyPolygon maPolyPolygon;
- sal_uInt32 mfCenterZ;
+ double mfCenterZ;
// bitfield
bool mbModulate : 1;
diff --git a/svx/inc/svx/sdrmasterpagedescriptor.hxx b/svx/inc/svx/sdrmasterpagedescriptor.hxx
index 2fa6a603dd..29446b8a22 100644
--- a/svx/inc/svx/sdrmasterpagedescriptor.hxx
+++ b/svx/inc/svx/sdrmasterpagedescriptor.hxx
@@ -89,8 +89,6 @@ namespace sdr
// operators
sal_Bool operator==(const MasterPageDescriptor& rCandidate) const;
sal_Bool operator!=(const MasterPageDescriptor& rCandidate) const;
-
- const SfxItemSet& getCorrectFillAttributes() const;
};
} // end of namespace sdr
diff --git a/svx/inc/svx/svdpage.hxx b/svx/inc/svx/svdpage.hxx
index 6b387da6fe..435ab2fda1 100644
--- a/svx/inc/svx/svdpage.hxx
+++ b/svx/inc/svx/svdpage.hxx
@@ -376,7 +376,6 @@ private:
public:
// construct/destruct
SdrPageProperties(SdrPage& rSdrPage);
- SdrPageProperties(const SdrPageProperties& rCandidate);
virtual ~SdrPageProperties();
// Notify(...) from baseclass SfxListener
diff --git a/svx/source/engine3d/scene3d.cxx b/svx/source/engine3d/scene3d.cxx
index 01ddb1f308..0bd03d0229 100644
--- a/svx/source/engine3d/scene3d.cxx
+++ b/svx/source/engine3d/scene3d.cxx
@@ -336,8 +336,18 @@ UINT16 E3dScene::GetObjIdentifier() const
void E3dScene::SetBoundRectDirty()
{
- // avoid resetting aOutRect which in case of this object is model data,
- // not re-creatable view data
+ E3dScene* pScene = GetScene();
+
+ if(pScene == this)
+ {
+ // avoid resetting aOutRect which in case of a 3D scene used as 2d object
+ // is model data,not re-creatable view data
+ }
+ else
+ {
+ // if not the outmost scene it is used as group in 3d, call parent
+ E3dObject::SetBoundRectDirty();
+ }
}
/*************************************************************************
diff --git a/svx/source/engine3d/view3d.cxx b/svx/source/engine3d/view3d.cxx
index 0487ef0530..8f56c8b331 100644
--- a/svx/source/engine3d/view3d.cxx
+++ b/svx/source/engine3d/view3d.cxx
@@ -75,6 +75,7 @@
#include <svx/sdr/overlay/overlayprimitive2dsequenceobject.hxx>
#include <drawinglayer/primitive2d/transformprimitive2d.hxx>
#include <basegfx/matrix/b2dhommatrixtools.hxx>
+#include <basegfx/polygon/b2dpolypolygoncutter.hxx>
#define ITEMVALUE(ItemSet,Id,Cast) ((const Cast&)(ItemSet).Get(Id)).GetValue()
@@ -1066,77 +1067,39 @@ void E3dView::ConvertMarkedObjTo3D(BOOL bExtrude, basegfx::B2DPoint aPnt1, baseg
struct E3dDepthNeighbour
{
- E3dDepthNeighbour* pNext;
- E3dExtrudeObj* pObj;
-
- E3dDepthNeighbour() { pNext = NULL; pObj = NULL; }
+ E3dDepthNeighbour* mpNext;
+ E3dExtrudeObj* mpObj;
+ basegfx::B2DPolyPolygon maPreparedPolyPolygon;
+
+ E3dDepthNeighbour()
+ : mpNext(0),
+ mpObj(0),
+ maPreparedPolyPolygon()
+ {
+ }
};
struct E3dDepthLayer
{
- E3dDepthLayer* pDown;
- E3dDepthNeighbour* pNext;
-
- E3dDepthLayer() { pDown = NULL; pNext = NULL; }
- ~E3dDepthLayer() { while(pNext) { E3dDepthNeighbour* pSucc = pNext->pNext; delete pNext; pNext = pSucc; }}
-};
-
-bool ImpDoesOverlap(const basegfx::B2DPolygon& rPolygonA, const basegfx::B2DPolygon& rPolygonB)
-{
- bool bRetval(false);
- const basegfx::B2DRange aRangeA(basegfx::tools::getRange(rPolygonA));
- const basegfx::B2DRange aRangeB(basegfx::tools::getRange(rPolygonB));
-
- if(aRangeA.overlaps(aRangeB))
- {
- // A in B ?
- if(basegfx::tools::isInside(rPolygonA, rPolygonB))
- return true;
-
- // B in A ?
- if(basegfx::tools::isInside(rPolygonB, rPolygonA))
- return true;
+ E3dDepthLayer* mpDown;
+ E3dDepthNeighbour* mpNext;
- // A and B the same ?
- if(basegfx::tools::isInside(rPolygonB, rPolygonA, true))
- return true;
+ E3dDepthLayer()
+ : mpDown(0),
+ mpNext(0)
+ {
}
- return bRetval;
-}
-
-bool ImpDoesOverlap(const basegfx::B2DPolyPolygon& rPolyPolygonA, const basegfx::B2DPolyPolygon& rPolyPolygonB)
-{
- bool bRetval(false);
- const basegfx::B2DRange aRangeA(basegfx::tools::getRange(rPolyPolygonA));
- const basegfx::B2DRange aRangeB(basegfx::tools::getRange(rPolyPolygonB));
-
- if(aRangeA.overlaps(aRangeB))
- {
- const sal_uInt32 nCntA(rPolyPolygonA.count());
- const sal_uInt32 nCntB(rPolyPolygonB.count());
-
- for(sal_uInt32 a(0L); !bRetval && a < nCntA; a++)
- {
- const basegfx::B2DPolygon aPolygonA(rPolyPolygonA.getB2DPolygon(a));
-
- if(aPolygonA.isClosed())
- {
- for(sal_uInt32 b(0L); !bRetval && b < nCntB; b++)
- {
- const basegfx::B2DPolygon aPolygonB(rPolyPolygonB.getB2DPolygon(b));
-
- if(aPolygonB.isClosed())
- {
- bRetval = ImpDoesOverlap(aPolygonA, aPolygonB);
- }
- }
- }
+ ~E3dDepthLayer()
+ {
+ while(mpNext)
+ {
+ E3dDepthNeighbour* pSucc = mpNext->mpNext;
+ delete mpNext;
+ mpNext = pSucc;
}
}
-
- return bRetval;
-}
+};
void E3dView::DoDepthArrange(E3dScene* pScene, double fDepth)
{
@@ -1147,39 +1110,41 @@ void E3dView::DoDepthArrange(E3dScene* pScene, double fDepth)
E3dDepthLayer* pBaseLayer = NULL;
E3dDepthLayer* pLayer = NULL;
INT32 nNumLayers = 0;
- //SfxItemPool& rPool = pMod->GetItemPool();
while(aIter.IsMore())
{
- E3dObject* pSubObj = (E3dObject*)aIter.Next();
+ E3dExtrudeObj* pExtrudeObj = dynamic_cast< E3dExtrudeObj* >(aIter.Next());
- if(pSubObj && pSubObj->ISA(E3dExtrudeObj))
+ if(pExtrudeObj)
{
- E3dExtrudeObj* pExtrudeObj = (E3dExtrudeObj*)pSubObj;
- const basegfx::B2DPolyPolygon aExtrudePoly(pExtrudeObj->GetExtrudePolygon());
-
+ const basegfx::B2DPolyPolygon aExtrudePoly(
+ basegfx::tools::prepareForPolygonOperation(pExtrudeObj->GetExtrudePolygon()));
const SfxItemSet& rLocalSet = pExtrudeObj->GetMergedItemSet();
- XFillStyle eLocalFillStyle = ITEMVALUE(rLocalSet, XATTR_FILLSTYLE, XFillStyleItem);
- Color aLocalColor = ((const XFillColorItem&)(rLocalSet.Get(XATTR_FILLCOLOR))).GetColorValue();
+ const XFillStyle eLocalFillStyle = ITEMVALUE(rLocalSet, XATTR_FILLSTYLE, XFillStyleItem);
+ const Color aLocalColor = ((const XFillColorItem&)(rLocalSet.Get(XATTR_FILLCOLOR))).GetColorValue();
- // ExtrudeObj einordnen
+ // sort in ExtrudeObj
if(pLayer)
{
- // Gibt es eine Ueberschneidung mit einem Objekt dieses
- // Layers?
- BOOL bOverlap(FALSE);
- E3dDepthNeighbour* pAct = pLayer->pNext;
+ // do we have overlap with an object of this layer?
+ bool bOverlap(false);
+ E3dDepthNeighbour* pAct = pLayer->mpNext;
while(!bOverlap && pAct)
{
- // ueberlappen sich pAct->pObj und pExtrudeObj ?
- const basegfx::B2DPolyPolygon aActPoly(pAct->pObj->GetExtrudePolygon());
- bOverlap = ImpDoesOverlap(aExtrudePoly, aActPoly);
-
+ // do pAct->mpObj and pExtrudeObj overlap? Check by
+ // using logical AND clipping
+ const basegfx::B2DPolyPolygon aAndPolyPolygon(
+ basegfx::tools::solvePolygonOperationAnd(
+ aExtrudePoly,
+ pAct->maPreparedPolyPolygon));
+
+ bOverlap = (0 != aAndPolyPolygon.count());
+
if(bOverlap)
{
// second ciriteria: is another fillstyle or color used?
- const SfxItemSet& rCompareSet = pAct->pObj->GetMergedItemSet();
+ const SfxItemSet& rCompareSet = pAct->mpObj->GetMergedItemSet();
XFillStyle eCompareFillStyle = ITEMVALUE(rCompareSet, XATTR_FILLSTYLE, XFillStyleItem);
@@ -1201,71 +1166,74 @@ void E3dView::DoDepthArrange(E3dScene* pScene, double fDepth)
}
}
- pAct = pAct->pNext;
+ pAct = pAct->mpNext;
}
if(bOverlap)
{
- // ja, beginne einen neuen Layer
- pLayer->pDown = new E3dDepthLayer;
- pLayer = pLayer->pDown;
+ // yes, start a new layer
+ pLayer->mpDown = new E3dDepthLayer;
+ pLayer = pLayer->mpDown;
nNumLayers++;
- pLayer->pNext = new E3dDepthNeighbour;
- pLayer->pNext->pObj = pExtrudeObj;
+ pLayer->mpNext = new E3dDepthNeighbour;
+ pLayer->mpNext->mpObj = pExtrudeObj;
+ pLayer->mpNext->maPreparedPolyPolygon = aExtrudePoly;
}
else
{
- // nein, Objekt kann in aktuellen Layer
+ // no, add to current layer
E3dDepthNeighbour* pNewNext = new E3dDepthNeighbour;
- pNewNext->pObj = pExtrudeObj;
- pNewNext->pNext = pLayer->pNext;
- pLayer->pNext = pNewNext;
+ pNewNext->mpObj = pExtrudeObj;
+ pNewNext->maPreparedPolyPolygon = aExtrudePoly;
+ pNewNext->mpNext = pLayer->mpNext;
+ pLayer->mpNext = pNewNext;
}
}
else
{
- // erster Layer ueberhaupt
+ // first layer ever
pBaseLayer = new E3dDepthLayer;
pLayer = pBaseLayer;
nNumLayers++;
- pLayer->pNext = new E3dDepthNeighbour;
- pLayer->pNext->pObj = pExtrudeObj;
+ pLayer->mpNext = new E3dDepthNeighbour;
+ pLayer->mpNext->mpObj = pExtrudeObj;
+ pLayer->mpNext->maPreparedPolyPolygon = aExtrudePoly;
}
}
}
- // Anzahl Layer steht fest
+ // number of layers is done
if(nNumLayers > 1)
{
- // Arrangement ist notwendig
+ // need to be arranged
double fMinDepth = fDepth * 0.8;
double fStep = (fDepth - fMinDepth) / (double)nNumLayers;
pLayer = pBaseLayer;
while(pLayer)
{
- // an pLayer entlangspazieren
- E3dDepthNeighbour* pAct = pLayer->pNext;
+ // move along layer
+ E3dDepthNeighbour* pAct = pLayer->mpNext;
while(pAct)
{
- // Anpassen
- pAct->pObj->SetMergedItem(SfxUInt32Item(SDRATTR_3DOBJ_DEPTH, sal_uInt32(fMinDepth + 0.5)));
+ // adapt extrude value
+ pAct->mpObj->SetMergedItem(SfxUInt32Item(SDRATTR_3DOBJ_DEPTH, sal_uInt32(fMinDepth + 0.5)));
- // Naechster Eintrag
- pAct = pAct->pNext;
+ // next
+ pAct = pAct->mpNext;
}
- // naechster Layer
- pLayer = pLayer->pDown;
+ // next layer
+ pLayer = pLayer->mpDown;
fMinDepth += fStep;
}
}
- // angelegte Strukturen aufraeumen
+ // cleanup
while(pBaseLayer)
{
- pLayer = pBaseLayer->pDown;
+ pLayer = pBaseLayer->mpDown;
delete pBaseLayer;
pBaseLayer = pLayer;
}
diff --git a/svx/source/sdr/contact/viewcontactofmasterpagedescriptor.cxx b/svx/source/sdr/contact/viewcontactofmasterpagedescriptor.cxx
index d397917edf..1f6801f394 100644
--- a/svx/source/sdr/contact/viewcontactofmasterpagedescriptor.cxx
+++ b/svx/source/sdr/contact/viewcontactofmasterpagedescriptor.cxx
@@ -61,11 +61,30 @@ namespace sdr
drawinglayer::primitive2d::Primitive2DSequence ViewContactOfMasterPageDescriptor::createViewIndependentPrimitive2DSequence() const
{
drawinglayer::primitive2d::Primitive2DSequence xRetval;
+ drawinglayer::attribute::SdrFillAttribute aFill;
+ const SdrPage* pCorrectPage = &GetMasterPageDescriptor().GetOwnerPage();
+ const SdrPageProperties* pCorrectProperties = &pCorrectPage->getSdrPageProperties();
- // build primitive from page fill attributes
- const SfxItemSet& rPageFillAttributes = GetMasterPageDescriptor().getCorrectFillAttributes();
- const drawinglayer::attribute::SdrFillAttribute aFill(
- drawinglayer::primitive2d::createNewSdrFillAttribute(rPageFillAttributes));
+ if(XFILL_NONE == ((const XFillStyleItem&)pCorrectProperties->GetItemSet().Get(XATTR_FILLSTYLE)).GetValue())
+ {
+ pCorrectPage = &GetMasterPageDescriptor().GetUsedPage();
+ pCorrectProperties = &pCorrectPage->getSdrPageProperties();
+ }
+
+ if(pCorrectPage->IsMasterPage() && !pCorrectProperties->GetStyleSheet())
+ {
+ // #i110846# Suppress SdrPage FillStyle for MasterPages without StyleSheets,
+ // else the PoolDefault (XFILL_COLOR and Blue8) will be used. Normally, all
+ // MasterPages should have a StyleSheet excactly for this reason, but historically
+ // e.g. the Notes MasterPage has no StyleSheet set (and there maybe others).
+ pCorrectProperties = 0;
+ }
+
+ if(pCorrectProperties)
+ {
+ // create page fill attributes when correct properties were identified
+ aFill = drawinglayer::primitive2d::createNewSdrFillAttribute(pCorrectProperties->GetItemSet());
+ }
if(!aFill.isDefault())
{
diff --git a/svx/source/sdr/contact/viewcontactofsdrpage.cxx b/svx/source/sdr/contact/viewcontactofsdrpage.cxx
index 0bf51d58f9..2eacc9083d 100644
--- a/svx/source/sdr/contact/viewcontactofsdrpage.cxx
+++ b/svx/source/sdr/contact/viewcontactofsdrpage.cxx
@@ -203,10 +203,18 @@ namespace sdr
}
else
{
- // build primitive from pObject's attributes
- const SfxItemSet& rFillAttributes = rPage.getSdrPageProperties().GetItemSet();
- const drawinglayer::attribute::SdrFillAttribute aFill(
- drawinglayer::primitive2d::createNewSdrFillAttribute(rFillAttributes));
+ drawinglayer::attribute::SdrFillAttribute aFill;
+
+ // #i110846# Suppress SdrPage FillStyle for MasterPages without StyleSheets,
+ // else the PoolDefault (XFILL_COLOR and Blue8) will be used. Normally, all
+ // MasterPages should have a StyleSheet excactly for this reason, but historically
+ // e.g. the Notes MasterPage has no StyleSheet set (and there maybe others).
+ if(rPage.getSdrPageProperties().GetStyleSheet())
+ {
+ // create page fill attributes with correct properties
+ aFill = drawinglayer::primitive2d::createNewSdrFillAttribute(
+ rPage.getSdrPageProperties().GetItemSet());
+ }
if(!aFill.isDefault())
{
diff --git a/svx/source/sdr/primitive2d/sdrpathprimitive2d.cxx b/svx/source/sdr/primitive2d/sdrpathprimitive2d.cxx
index 9c36397600..2cd0dc02e2 100644
--- a/svx/source/sdr/primitive2d/sdrpathprimitive2d.cxx
+++ b/svx/source/sdr/primitive2d/sdrpathprimitive2d.cxx
@@ -51,13 +51,11 @@ namespace drawinglayer
if(!getSdrLFSTAttribute().getFill().isDefault()
&& getUnitPolyPolygon().isClosed())
{
- // take care for orientations
- const basegfx::B2DPolyPolygon aOrientedUnitPolyPolygon(
- basegfx::tools::correctOrientations(getUnitPolyPolygon()));
-
+ // #i108255# no need to use correctOrientations here; target is
+ // straight visualisation
appendPrimitive2DReferenceToPrimitive2DSequence(aRetval,
createPolyPolygonFillPrimitive(
- aOrientedUnitPolyPolygon,
+ getUnitPolyPolygon(),
getTransform(),
getSdrLFSTAttribute().getFill(),
getSdrLFSTAttribute().getFillFloatTransGradient()));
diff --git a/svx/source/svdraw/sdrmasterpagedescriptor.cxx b/svx/source/svdraw/sdrmasterpagedescriptor.cxx
index 3437567da3..9d6ba449d0 100644
--- a/svx/source/svdraw/sdrmasterpagedescriptor.cxx
+++ b/svx/source/svdraw/sdrmasterpagedescriptor.cxx
@@ -113,18 +113,6 @@ namespace sdr
|| &maUsedPage != &rCandidate.maUsedPage
|| maVisibleLayers != rCandidate.maVisibleLayers);
}
-
- const SfxItemSet& MasterPageDescriptor::getCorrectFillAttributes() const
- {
- const SfxItemSet& rOwnerPageAtributes = GetOwnerPage().getSdrPageProperties().GetItemSet();
-
- if(XFILL_NONE != ((const XFillStyleItem&)rOwnerPageAtributes.Get(XATTR_FILLSTYLE)).GetValue())
- {
- return rOwnerPageAtributes;
- }
-
- return GetUsedPage().getSdrPageProperties().GetItemSet();
- }
} // end of namespace sdr
//////////////////////////////////////////////////////////////////////////////
diff --git a/svx/source/svdraw/svdedtv.cxx b/svx/source/svdraw/svdedtv.cxx
index 7023aa8913..de7a564ff1 100644
--- a/svx/source/svdraw/svdedtv.cxx
+++ b/svx/source/svdraw/svdedtv.cxx
@@ -805,6 +805,12 @@ void SdrEditView::DeleteMarkedList(const SdrMarkList& rMark)
void SdrEditView::DeleteMarkedObj()
{
+ // #i110981# return when nothing is to be done at all
+ if(!GetMarkedObjectCount())
+ {
+ return;
+ }
+
// moved breaking action and undo start outside loop
BrkAction();
BegUndo(ImpGetResStr(STR_EditDelete),GetDescriptionOfMarkedObjects(),SDRREPFUNC_OBJ_DELETE);
diff --git a/svx/source/svdraw/svdocirc.cxx b/svx/source/svdraw/svdocirc.cxx
index 8c14a33564..288cfcc593 100644
--- a/svx/source/svdraw/svdocirc.cxx
+++ b/svx/source/svdraw/svdocirc.cxx
@@ -239,8 +239,9 @@ basegfx::B2DPolygon SdrCircObj::ImpCalcXPolyCirc(const SdrObjKind eCicrleKind, c
else
{
// mirror start, end for geometry creation since model coordinate system is mirrored in Y
- const double fStart(((36000 - nEnd) % 36000) * F_PI18000);
- const double fEnd(((36000 - nStart) % 36000) * F_PI18000);
+ // #i111715# increase numerical correctness by first dividing and not using F_PI1800
+ const double fStart((((36000 - nEnd) % 36000) / 18000.0) * F_PI);
+ const double fEnd((((36000 - nStart) % 36000) / 18000.0) * F_PI);
// create circle segment. This is not closed by default
aCircPolygon = basegfx::tools::createPolygonFromEllipseSegment(
diff --git a/svx/source/svdraw/svdoedge.cxx b/svx/source/svdraw/svdoedge.cxx
index 537703e622..7c5e4ac314 100644
--- a/svx/source/svdraw/svdoedge.cxx
+++ b/svx/source/svdraw/svdoedge.cxx
@@ -1674,6 +1674,11 @@ void SdrEdgeObj::SetEdgeTrackPath( const basegfx::B2DPolyPolygon& rPoly )
*pEdgeTrack = XPolygon( rPoly.getB2DPolygon( 0 ) );
bEdgeTrackDirty = sal_False;
bEdgeTrackUserDefined = sal_True;
+
+ // #i110629# also set aRect and maSnapeRect dependent from pEdgeTrack
+ const Rectangle aPolygonBounds(pEdgeTrack->GetBoundRect());
+ aRect = aPolygonBounds;
+ maSnapRect = aPolygonBounds;
}
}
@@ -2206,17 +2211,31 @@ FASTBOOL SdrEdgeObj::ImpFindConnector(const Point& rPt, const SdrPageView& rPV,
void SdrEdgeObj::NbcSetSnapRect(const Rectangle& rRect)
{
- Rectangle aOld(GetSnapRect());
- long nMulX = rRect.Right() - rRect.Left();
- long nDivX = aOld.Right() - aOld.Left();
- long nMulY = rRect.Bottom() - rRect.Top();
- long nDivY = aOld.Bottom() - aOld.Top();
- if ( nDivX == 0 ) { nMulX = 1; nDivX = 1; }
- if ( nDivY == 0 ) { nMulY = 1; nDivY = 1; }
- Fraction aX(nMulX, nDivX);
- Fraction aY(nMulY, nDivY);
- NbcResize(aOld.TopLeft(), aX, aY);
- NbcMove(Size(rRect.Left() - aOld.Left(), rRect.Top() - aOld.Top()));
+ const Rectangle aOld(GetSnapRect());
+
+ if(aOld != rRect)
+ {
+ if(aRect.IsEmpty() && 0 == pEdgeTrack->GetPointCount())
+ {
+ // #i110629# When initializing, do not scale on empty Rectangle; this
+ // will mirror the underlying text object (!)
+ aRect = rRect;
+ maSnapRect = rRect;
+ }
+ else
+ {
+ long nMulX = rRect.Right() - rRect.Left();
+ long nDivX = aOld.Right() - aOld.Left();
+ long nMulY = rRect.Bottom() - rRect.Top();
+ long nDivY = aOld.Bottom() - aOld.Top();
+ if ( nDivX == 0 ) { nMulX = 1; nDivX = 1; }
+ if ( nDivY == 0 ) { nMulY = 1; nDivY = 1; }
+ Fraction aX(nMulX, nDivX);
+ Fraction aY(nMulY, nDivY);
+ NbcResize(aOld.TopLeft(), aX, aY);
+ NbcMove(Size(rRect.Left() - aOld.Left(), rRect.Top() - aOld.Top()));
+ }
+ }
}
void SdrEdgeObj::NbcMove(const Size& rSiz)
diff --git a/svx/source/svdraw/svdotextpathdecomposition.cxx b/svx/source/svdraw/svdotextpathdecomposition.cxx
index afcef6b1b2..0b3fb3a2bf 100644
--- a/svx/source/svdraw/svdotextpathdecomposition.cxx
+++ b/svx/source/svdraw/svdotextpathdecomposition.cxx
@@ -107,15 +107,13 @@ namespace
maLocale(rInfo.mpLocale ? *rInfo.mpLocale : ::com::sun::star::lang::Locale()),
mbRTL(rInfo.mrFont.IsVertical() ? false : rInfo.IsRTL())
{
- if(mnTextLength)
+ if(mnTextLength && rInfo.mpDXArray)
{
maDblDXArray.reserve(mnTextLength);
- const sal_Int32 nFontWidth(0L == maFont.GetWidth() ? maFont.GetHeight() : maFont.GetWidth());
- const double fScaleFactor(0L != nFontWidth ? 1.0 / (double)nFontWidth : 1.0);
for(xub_StrLen a(0); a < mnTextLength; a++)
{
- maDblDXArray.push_back((double)rInfo.mpDXArray[a] * fScaleFactor);
+ maDblDXArray.push_back((double)rInfo.mpDXArray[a]);
}
}
}
@@ -291,7 +289,8 @@ namespace
const double fPolyLength(basegfx::tools::getLength(aPolygonCandidate));
double fPolyEnd(fPolyLength);
double fPolyStart(0.0);
- double fScaleFactor(1.0);
+ double fAutosizeScaleFactor(1.0);
+ bool bAutosizeScale(false);
if(maSdrFormTextAttribute.getFormTextMirror())
{
@@ -352,7 +351,8 @@ namespace
// if scale, prepare scale factor between curve length and text length
if(0.0 != fParagraphTextLength)
{
- fScaleFactor = (fPolyEnd - fPolyStart) / fParagraphTextLength;
+ fAutosizeScaleFactor = (fPolyEnd - fPolyStart) / fParagraphTextLength;
+ bAutosizeScale = true;
}
}
}
@@ -382,10 +382,10 @@ namespace
// prepare portion length. Takes RTL sections into account.
double fPortionLength(pCandidate->getDisplayLength(nUsedTextLength, nNextGlyphLen));
- if(XFT_AUTOSIZE == maSdrFormTextAttribute.getFormTextAdjust())
+ if(bAutosizeScale)
{
- // when scaling, expand portion length
- fPortionLength *= fScaleFactor;
+ // when autosize scaling, expand portion length
+ fPortionLength *= fAutosizeScaleFactor;
}
// create transformation
@@ -397,10 +397,10 @@ namespace
aNewTransformA.scale(aFontScaling.getX(), aFontScaling.getY());
// prepare scaling of text primitive
- if(XFT_AUTOSIZE == maSdrFormTextAttribute.getFormTextAdjust())
+ if(bAutosizeScale)
{
- // when scaling, expand text primitive scaling
- aNewTransformA.scale(fScaleFactor, fScaleFactor);
+ // when autosize scaling, expand text primitive scaling to it
+ aNewTransformA.scale(fAutosizeScaleFactor, fAutosizeScaleFactor);
}
// eventually create shadow primitives from aDecomposition and add to rDecomposition
@@ -497,17 +497,42 @@ namespace
aNewTransformB.translate(aPerpendicular.getX(), aPerpendicular.getY());
}
- // shadow primitive creation
- if(bShadow)
+ if(pCandidate->getText().Len() && nNextGlyphLen)
{
- if(pCandidate->getText().Len() && nNextGlyphLen)
+ const xub_StrLen nPortionIndex(pCandidate->getPortionIndex(nUsedTextLength, nNextGlyphLen));
+ ::std::vector< double > aNewDXArray;
+
+ if(nNextGlyphLen > 1 && pCandidate->getDoubleDXArray().size())
{
+ // copy DXArray for portion
+ aNewDXArray.insert(
+ aNewDXArray.begin(),
+ pCandidate->getDoubleDXArray().begin() + nPortionIndex,
+ pCandidate->getDoubleDXArray().begin() + (nPortionIndex + nNextGlyphLen));
+
+ if(nPortionIndex > 0)
+ {
+ // adapt to portion start
+ double fDXOffset= *(pCandidate->getDoubleDXArray().begin() + (nPortionIndex - 1));
+ ::std::transform(
+ aNewDXArray.begin(), aNewDXArray.end(),
+ aNewDXArray.begin(), ::std::bind2nd(::std::minus<double>(), fDXOffset));
+ }
+
+ if(bAutosizeScale)
+ {
+ // when autosize scaling, adapt to DXArray, too
+ ::std::transform(
+ aNewDXArray.begin(), aNewDXArray.end(),
+ aNewDXArray.begin(), ::std::bind2nd(::std::multiplies<double>(), fAutosizeScaleFactor));
+ }
+ }
+
+ if(bShadow)
+ {
+ // shadow primitive creation
const Color aShadowColor(maSdrFormTextAttribute.getFormTextShdwColor());
const basegfx::BColor aRGBShadowColor(aShadowColor.getBColor());
- const xub_StrLen nPortionIndex(pCandidate->getPortionIndex(nUsedTextLength, nNextGlyphLen));
- const ::std::vector< double > aNewDXArray(
- pCandidate->getDoubleDXArray().begin() + nPortionIndex,
- pCandidate->getDoubleDXArray().begin() + nPortionIndex + nNextGlyphLen);
drawinglayer::primitive2d::TextSimplePortionPrimitive2D* pNew =
new drawinglayer::primitive2d::TextSimplePortionPrimitive2D(
@@ -522,30 +547,25 @@ namespace
mrShadowDecomposition.push_back(pNew);
}
- }
- // primitive creation
- if(pCandidate->getText().Len() && nNextGlyphLen)
- {
- const Color aColor(pCandidate->getFont().GetColor());
- const basegfx::BColor aRGBColor(aColor.getBColor());
- const xub_StrLen nPortionIndex(pCandidate->getPortionIndex(nUsedTextLength, nNextGlyphLen));
- const ::std::vector< double > aNewDXArray(
- pCandidate->getDoubleDXArray().begin() + nPortionIndex,
- pCandidate->getDoubleDXArray().begin() + nPortionIndex + nNextGlyphLen);
-
- drawinglayer::primitive2d::TextSimplePortionPrimitive2D* pNew =
- new drawinglayer::primitive2d::TextSimplePortionPrimitive2D(
- aNewTransformB * aNewTransformA,
- pCandidate->getText(),
- nPortionIndex,
- nNextGlyphLen,
- aNewDXArray,
- aCandidateFontAttribute,
- pCandidate->getLocale(),
- aRGBColor);
-
- mrDecomposition.push_back(pNew);
+ {
+ // primitive creation
+ const Color aColor(pCandidate->getFont().GetColor());
+ const basegfx::BColor aRGBColor(aColor.getBColor());
+
+ drawinglayer::primitive2d::TextSimplePortionPrimitive2D* pNew =
+ new drawinglayer::primitive2d::TextSimplePortionPrimitive2D(
+ aNewTransformB * aNewTransformA,
+ pCandidate->getText(),
+ nPortionIndex,
+ nNextGlyphLen,
+ aNewDXArray,
+ aCandidateFontAttribute,
+ pCandidate->getLocale(),
+ aRGBColor);
+
+ mrDecomposition.push_back(pNew);
+ }
}
// consume from portion // no += here, xub_StrLen is USHORT and the compiler will gererate a warning here
diff --git a/svx/source/svdraw/svdpage.cxx b/svx/source/svdraw/svdpage.cxx
index 1e6cc56992..f9dc3c313d 100644
--- a/svx/source/svdraw/svdpage.cxx
+++ b/svx/source/svdraw/svdpage.cxx
@@ -1221,29 +1221,6 @@ SdrPageProperties::SdrPageProperties(SdrPage& rSdrPage)
}
}
-SdrPageProperties::SdrPageProperties(const SdrPageProperties& rCandidate)
-: SfxListener(),
- mpSdrPage(rCandidate.mpSdrPage),
- mpStyleSheet(0),
- mpProperties(0)
-{
- if(&mpSdrPage->GetModel()->GetItemPool() == rCandidate.mpProperties->GetPool())
- {
- mpProperties = new SfxItemSet(*rCandidate.mpProperties);
- }
- else
- {
- // #i111122# in doubt, use the ItemPool from the page, not the
- // ItemSet. This is e.g. used to set a new Model
- mpProperties = rCandidate.mpProperties->Clone(true, &mpSdrPage->GetModel()->GetItemPool());
- }
-
- if(rCandidate.GetStyleSheet())
- {
- ImpAddStyleSheet(*rCandidate.GetStyleSheet());
- }
-}
-
SdrPageProperties::~SdrPageProperties()
{
ImpRemoveStyleSheet();
@@ -1376,6 +1353,8 @@ SdrPage::SdrPage(const SdrPage& rSrcPage)
// Warning: this leads to slicing (see issue 93186) and has to be
// removed as soon as possible.
*this = rSrcPage;
+ OSL_ENSURE(mpSdrPageProperties,
+ "SdrPage::SdrPage: operator= did not create needed SdrPageProperties (!)");
// be careful and correct eListKind, a member of SdrObjList which
// will be changed by the SdrOIbjList::operator= before...
@@ -1393,8 +1372,6 @@ SdrPage::SdrPage(const SdrPage& rSrcPage)
mxUnoPage = NULL;
xComponent->dispose();
}
-
- mpSdrPageProperties = new SdrPageProperties(rSrcPage.getSdrPageProperties());
}
SdrPage::~SdrPage()
@@ -1489,8 +1466,28 @@ void SdrPage::operator=(const SdrPage& rSrcPage)
mbObjectsNotPersistent = rSrcPage.mbObjectsNotPersistent;
{
- delete mpSdrPageProperties;
- mpSdrPageProperties = new SdrPageProperties(rSrcPage.getSdrPageProperties());
+ // #i111122# delete SdrPageProperties when model is different
+ if(mpSdrPageProperties && GetModel() != rSrcPage.GetModel())
+ {
+ delete mpSdrPageProperties;
+ mpSdrPageProperties = 0;
+ }
+
+ if(!mpSdrPageProperties)
+ {
+ mpSdrPageProperties = new SdrPageProperties(*this);
+ }
+ else
+ {
+ mpSdrPageProperties->ClearItem(0);
+ }
+
+ if(!IsMasterPage())
+ {
+ mpSdrPageProperties->PutItemSet(rSrcPage.getSdrPageProperties().GetItemSet());
+ }
+
+ mpSdrPageProperties->SetStyleSheet(rSrcPage.getSdrPageProperties().GetStyleSheet());
}
// Now copy the contained obejcts (by cloning them)
@@ -1670,9 +1667,17 @@ void SdrPage::SetModel(SdrModel* pNewModel)
}
pLayerAdmin->SetModel(pNewModel);
- // #i111122# re-create SdrPageProperties to migrate it's items to the
- // new model
- SdrPageProperties *pNew = new SdrPageProperties(getSdrPageProperties());
+ // create new SdrPageProperties with new model (due to SfxItemSet there)
+ // and copy ItemSet and StyleSheet
+ SdrPageProperties *pNew = new SdrPageProperties(*this);
+
+ if(!IsMasterPage())
+ {
+ pNew->PutItemSet(getSdrPageProperties().GetItemSet());
+ }
+
+ pNew->SetStyleSheet(getSdrPageProperties().GetStyleSheet());
+
delete mpSdrPageProperties;
mpSdrPageProperties = pNew;
}