From 9702ac0546ec4941cb7527e7b4b439f3e7723172 Mon Sep 17 00:00:00 2001 From: Ivo Hinkelmann Date: Thu, 23 Apr 2009 14:51:28 +0000 Subject: CWS-TOOLING: integrate CWS aw070_DEV300 2009-04-14 15:12:41 +0200 hdu r270783 : #i100951# avoid expensive calls to basegfx::tools::clipPolygonOnRange() if possible 2009-04-14 15:04:05 +0200 hdu r270780 : #i100922# prevent needless stl::priority_queue reallacations by reserving 2009-04-14 14:44:18 +0200 aw r270776 : #i100851# corrected unxlngi4 warning 2009-04-14 14:41:44 +0200 aw r270774 : #i100851# applied suggested patch from task 2009-04-14 14:32:30 +0200 aw r270769 : #i101075# corrected offset usage for wrong spell and transformation mapping for page preview primitives with aspect ratio 2009-04-14 13:56:13 +0200 aw r270763 : #i101075# changed to empty range usage when collecting page conent for page preview object --- .../source/primitive2d/pagepreviewprimitive2d.cxx | 101 ++++++++------- .../processor2d/helperwrongspellrenderer.cxx | 8 +- .../source/processor2d/vclpixelprocessor2d.cxx | 2 +- drawinglayer/source/processor2d/vclprocessor2d.cxx | 135 +++++++++++++++++---- .../sdr/contact/viewobjectcontactofpageobj.cxx | 10 +- 5 files changed, 181 insertions(+), 75 deletions(-) diff --git a/drawinglayer/source/primitive2d/pagepreviewprimitive2d.cxx b/drawinglayer/source/primitive2d/pagepreviewprimitive2d.cxx index 9695368576..a6e292eeec 100644 --- a/drawinglayer/source/primitive2d/pagepreviewprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/pagepreviewprimitive2d.cxx @@ -58,66 +58,77 @@ namespace drawinglayer Primitive2DSequence xRetval; Primitive2DSequence aContent(getChildren()); - if(aContent.hasElements()) + if(aContent.hasElements() + && basegfx::fTools::more(getContentWidth(), 0.0) + && basegfx::fTools::more(getContentHeight(), 0.0)) { - // check if content overlaps with tageted size and needs to be embedded with a - // clipping primitive - const basegfx::B2DRange aRealContentRange(getB2DRangeFromPrimitive2DSequence(aContent, rViewInformation)); - const basegfx::B2DRange aAllowedContentRange(0.0, 0.0, getContentWidth(), getContentHeight()); - - if(!aAllowedContentRange.isInside(aRealContentRange)) - { - const Primitive2DReference xReferenceA(new MaskPrimitive2D(basegfx::B2DPolyPolygon(basegfx::tools::createPolygonFromRect(aAllowedContentRange)), aContent)); - aContent = Primitive2DSequence(&xReferenceA, 1); - } - - // content is not scaled or rotated and occupates aContentRange. Create a mapping - // to own local geometry. Create matrix describing the content by setting scaling - basegfx::B2DHomMatrix aPageTrans; - aPageTrans.set(0, 0, getContentWidth()); - aPageTrans.set(1, 1, getContentHeight()); - - // decompose to access own scaling + // the decomposed matrix will be needed basegfx::B2DVector aScale, aTranslate; double fRotate, fShearX; getTransform().decompose(aScale, aTranslate, fRotate, fShearX); - if(getKeepAspectRatio()) + if(basegfx::fTools::more(aScale.getX(), 0.0) && basegfx::fTools::more(aScale.getY(), 0.0)) { - // look at the aspect ratio of the content and the local geometry - const double fRatioOwn(aScale.getX() ? (aScale.getY() / aScale.getX()) : 1.0); - const double fRatioContent(getContentWidth() ? (getContentHeight() / getContentWidth()) : 1.0); + // check if content overlaps with tageted size and needs to be embedded with a + // clipping primitive + const basegfx::B2DRange aRealContentRange(getB2DRangeFromPrimitive2DSequence(aContent, rViewInformation)); + const basegfx::B2DRange aAllowedContentRange(0.0, 0.0, getContentWidth(), getContentHeight()); + + if(!aAllowedContentRange.isInside(aRealContentRange)) + { + const Primitive2DReference xReferenceA(new MaskPrimitive2D(basegfx::B2DPolyPolygon(basegfx::tools::createPolygonFromRect(aAllowedContentRange)), aContent)); + aContent = Primitive2DSequence(&xReferenceA, 1); + } - // the ratios are based on different coordinate systems, so look if they differ really more - // than 0,1 percent - if(fabs(fRatioOwn - fRatioContent) > 0.001) + // create a mapping from content to object. + basegfx::B2DHomMatrix aPageTrans; + + if(getKeepAspectRatio()) { - if(basegfx::fTools::more(fRatioOwn, fRatioContent)) + // #i101075# when keeping the aspect ratio is wanted, it is necessary to calculate + // an equidistant scaling in X and Y and a corresponding translation to + // center the output. Calculate needed scale factors + const double fScaleX(aScale.getX() / getContentWidth()); + const double fScaleY(aScale.getY() / getContentHeight()); + + // to keep the aspect, use the smaller scale and adapt missing size by translation + if(fScaleX < fScaleY) { - // vertically center the page by translating - const double fFullY(aScale.getX() ? (aScale.getY() * getContentWidth()) / aScale.getX() : 0.0); - const double fTransY((fFullY - getContentHeight()) * 0.5); - aPageTrans.set(1, 2, fTransY); + // height needs to be adapted + const double fNeededHeight(aScale.getY() / fScaleX); + const double fSpaceToAdd(fNeededHeight - getContentHeight()); + + aPageTrans.translate(0.0, fSpaceToAdd * 0.5); + aPageTrans.scale(fScaleX, aScale.getY() / fNeededHeight); } else { - // horizontally center the page by translating - const double fFullX(aScale.getY() ? (aScale.getX() * getContentHeight()) / aScale.getY() : 0.0); - const double fTransX((fFullX - getContentWidth()) * 0.5); - aPageTrans.set(0, 2, fTransX); + // width needs to be adapted + const double fNeededWidth(aScale.getX() / fScaleY); + const double fSpaceToAdd(fNeededWidth - getContentWidth()); + + aPageTrans.translate(fSpaceToAdd * 0.5, 0.0); + aPageTrans.scale(aScale.getX() / fNeededWidth, fScaleY); } + + // add the missing object transformation aspects + aPageTrans.shearX(fShearX); + aPageTrans.rotate(fRotate); + aPageTrans.translate(aTranslate.getX(), aTranslate.getY()); + } + else + { + // completely scale to PageObject size. Scale to unit size. + aPageTrans.scale(1.0/ getContentWidth(), 1.0 / getContentHeight()); + + // apply object matrix + aPageTrans *= getTransform(); } + + // embed in necessary transformation to map from SdrPage to SdrPageObject + const Primitive2DReference xReferenceB(new TransformPrimitive2D(aPageTrans, aContent)); + xRetval = Primitive2DSequence(&xReferenceB, 1); } - - // create composed transformation from content to local geometry. An - // eventually needed clipping is already added, so directly go to local coordinates - basegfx::B2DHomMatrix aPageToObject(aPageTrans); - aPageToObject.invert(); - aPageToObject *= getTransform(); - - // embed in necessary transformation to map from SdrPage to SdrPageObject - const Primitive2DReference xReferenceB(new TransformPrimitive2D(aPageToObject, aContent)); - xRetval = Primitive2DSequence(&xReferenceB, 1); } return xRetval; diff --git a/drawinglayer/source/processor2d/helperwrongspellrenderer.cxx b/drawinglayer/source/processor2d/helperwrongspellrenderer.cxx index e95b54f53d..902ba55ea5 100644 --- a/drawinglayer/source/processor2d/helperwrongspellrenderer.cxx +++ b/drawinglayer/source/processor2d/helperwrongspellrenderer.cxx @@ -81,13 +81,17 @@ namespace drawinglayer nWaveStyle = WAVE_SMALL; } + // #i101075# draw it. Do not forget to use the evtl. offsetted origin of the target device, + // e.g. when used with mask/transparence buffer device + const Point aOrigin(rOutputDevice.GetMapMode().GetOrigin()); + const basegfx::BColor aProcessedColor(rBColorModifierStack.getModifiedColor(rWrongSpellCandidate.getColor())); const bool bMapModeEnabledState(rOutputDevice.IsMapModeEnabled()); - + rOutputDevice.EnableMapMode(false); rOutputDevice.SetLineColor(Color(aProcessedColor)); rOutputDevice.SetFillColor(); - rOutputDevice.DrawWaveLine(aVclStart, aVclStop, nWaveStyle); + rOutputDevice.DrawWaveLine(aOrigin + aVclStart, aOrigin + aVclStop, nWaveStyle); rOutputDevice.EnableMapMode(bMapModeEnabledState); } diff --git a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx index 5754e5a29c..7e7a909bec 100644 --- a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx +++ b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx @@ -389,7 +389,7 @@ namespace drawinglayer // polygon stroke primitive static bool bSuppressFatToHairlineCorrection(false); - if(getOptionsDrawinglayer().IsAntiAliasing() || bSuppressFatToHairlineCorrection) + if(bSuppressFatToHairlineCorrection) { // remeber that we enter a PolygonStrokePrimitive2D decomposition, // used for AA thick line drawing diff --git a/drawinglayer/source/processor2d/vclprocessor2d.cxx b/drawinglayer/source/processor2d/vclprocessor2d.cxx index 1cc4da81f3..3fcbc605e7 100644 --- a/drawinglayer/source/processor2d/vclprocessor2d.cxx +++ b/drawinglayer/source/processor2d/vclprocessor2d.cxx @@ -1014,8 +1014,10 @@ namespace drawinglayer { const basegfx::B2DVector aDiscreteUnit(maCurrentTransformation * basegfx::B2DVector(fLineWidth, 0.0)); const double fDiscreteLineWidth(aDiscreteUnit.getLength()); + const bool bAntiAliased(getOptionsDrawinglayer().IsAntiAliasing()); + const double fAllowedUpperBound(bAntiAliased ? 3.0 : 2.5); - if(basegfx::fTools::lessOrEqual(fDiscreteLineWidth, 2.5)) + if(basegfx::fTools::lessOrEqual(fDiscreteLineWidth, fAllowedUpperBound)) { // force to hairline const attribute::StrokeAttribute& rStrokeAttribute = rPolygonStrokeCandidate.getStrokeAttribute(); @@ -1044,43 +1046,117 @@ namespace drawinglayer { aHairlinePolyPolygon.transform(maCurrentTransformation); - if(basegfx::fTools::more(fDiscreteLineWidth, 1.5)) + if(bAntiAliased) { - // line width is in range ]1.5 .. 2.5], use four hairlines - // drawn in a square - basegfx::B2DHomMatrix aMat; - for(sal_uInt32 a(0); a < nCount; a++) { basegfx::B2DPolygon aCandidate(aHairlinePolyPolygon.getB2DPolygon(a)); - mpOutputDevice->DrawPolyLine(aCandidate, 0.0); - aMat.set(0, 2, 1.0); - aMat.set(1, 2, 0.0); - aCandidate.transform(aMat); + if(basegfx::fTools::lessOrEqual(fDiscreteLineWidth, 1.0)) + { + // line in range ]0.0 .. 1.0[ + // paint as simple hairline + mpOutputDevice->DrawPolyLine(aCandidate, 0.0); + } + else if(basegfx::fTools::lessOrEqual(fDiscreteLineWidth, 2.0)) + { + // line in range [1.0 .. 2.0[ + // paint as 2x2 with dynamic line distance + basegfx::B2DHomMatrix aMat; + const double fDistance(fDiscreteLineWidth - 1.0); + const double fHalfDistance(fDistance * 0.5); + + aMat.set(0, 2, -fHalfDistance); + aMat.set(1, 2, -fHalfDistance); + aCandidate.transform(aMat); + mpOutputDevice->DrawPolyLine(aCandidate, 0.0); + + aMat.set(0, 2, fDistance); + aMat.set(1, 2, 0.0); + aCandidate.transform(aMat); + mpOutputDevice->DrawPolyLine(aCandidate, 0.0); + + aMat.set(0, 2, 0.0); + aMat.set(1, 2, fDistance); + aCandidate.transform(aMat); + mpOutputDevice->DrawPolyLine(aCandidate, 0.0); + + aMat.set(0, 2, -fDistance); + aMat.set(1, 2, 0.0); + aCandidate.transform(aMat); + mpOutputDevice->DrawPolyLine(aCandidate, 0.0); + } + else + { + // line in range [2.0 .. 3.0] + // paint as cross in a 3x3 with dynamic line distance + basegfx::B2DHomMatrix aMat; + const double fDistance((fDiscreteLineWidth - 1.0) * 0.5); + + mpOutputDevice->DrawPolyLine(aCandidate, 0.0); + + aMat.set(0, 2, -fDistance); + aMat.set(1, 2, 0.0); + aCandidate.transform(aMat); + mpOutputDevice->DrawPolyLine(aCandidate, 0.0); + + aMat.set(0, 2, fDistance); + aMat.set(1, 2, -fDistance); + aCandidate.transform(aMat); + mpOutputDevice->DrawPolyLine(aCandidate, 0.0); + + aMat.set(0, 2, fDistance); + aMat.set(1, 2, fDistance); + aCandidate.transform(aMat); + mpOutputDevice->DrawPolyLine(aCandidate, 0.0); + + aMat.set(0, 2, -fDistance); + aMat.set(1, 2, fDistance); + aCandidate.transform(aMat); + mpOutputDevice->DrawPolyLine(aCandidate, 0.0); + } + } + } + else + { + if(basegfx::fTools::more(fDiscreteLineWidth, 1.5)) + { + // line width is in range ]1.5 .. 2.5], use four hairlines + // drawn in a square + basegfx::B2DHomMatrix aMat; + + for(sal_uInt32 a(0); a < nCount; a++) + { + basegfx::B2DPolygon aCandidate(aHairlinePolyPolygon.getB2DPolygon(a)); + mpOutputDevice->DrawPolyLine(aCandidate, 0.0); - mpOutputDevice->DrawPolyLine(aCandidate, 0.0); + aMat.set(0, 2, 1.0); + aMat.set(1, 2, 0.0); + aCandidate.transform(aMat); - aMat.set(0, 2, 0.0); - aMat.set(1, 2, 1.0); - aCandidate.transform(aMat); + mpOutputDevice->DrawPolyLine(aCandidate, 0.0); - mpOutputDevice->DrawPolyLine(aCandidate, 0.0); + aMat.set(0, 2, 0.0); + aMat.set(1, 2, 1.0); + aCandidate.transform(aMat); - aMat.set(0, 2, -1.0); - aMat.set(1, 2, 0.0); - aCandidate.transform(aMat); + mpOutputDevice->DrawPolyLine(aCandidate, 0.0); - mpOutputDevice->DrawPolyLine(aCandidate, 0.0); + aMat.set(0, 2, -1.0); + aMat.set(1, 2, 0.0); + aCandidate.transform(aMat); + + mpOutputDevice->DrawPolyLine(aCandidate, 0.0); + } } - } - else - { - for(sal_uInt32 a(0); a < nCount; a++) + else { - // draw the basic hairline polygon - const basegfx::B2DPolygon aCandidate(aHairlinePolyPolygon.getB2DPolygon(a)); - mpOutputDevice->DrawPolyLine(aCandidate, 0.0); + for(sal_uInt32 a(0); a < nCount; a++) + { + // draw the basic hairline polygon + const basegfx::B2DPolygon aCandidate(aHairlinePolyPolygon.getB2DPolygon(a)); + mpOutputDevice->DrawPolyLine(aCandidate, 0.0); + } } } } @@ -1091,8 +1167,15 @@ namespace drawinglayer if(!bDone) { + // remeber that we enter a PolygonStrokePrimitive2D decomposition, + // used for AA thick line drawing + mnPolygonStrokePrimitive2D++; + // line width is big enough for standard filled polygon visualisation or zero process(rPolygonStrokeCandidate.get2DDecomposition(getViewInformation2D())); + + // leave PolygonStrokePrimitive2D + mnPolygonStrokePrimitive2D--; } } diff --git a/svx/source/sdr/contact/viewobjectcontactofpageobj.cxx b/svx/source/sdr/contact/viewobjectcontactofpageobj.cxx index d4b0c692c1..f69f4d5550 100644 --- a/svx/source/sdr/contact/viewobjectcontactofpageobj.cxx +++ b/svx/source/sdr/contact/viewobjectcontactofpageobj.cxx @@ -147,7 +147,15 @@ namespace sdr const drawinglayer::geometry::ViewInformation2D aNewViewInformation2D( rOriginalViewInformation.getObjectTransformation(), rOriginalViewInformation.getViewTransformation(), - rOriginalViewInformation.getViewport(), + + // #i101075# use empty range for page content here to force + // the content not to be physically clipped in any way. This + // would be possible, but would require the internal transformation + // which maps between the page visualisation object and the page + // content, including the aspect ratios (for details see in + // PagePreviewPrimitive2D::createLocalDecomposition) + basegfx::B2DRange(), + GetXDrawPageForSdrPage(const_cast< SdrPage* >(pStartPage)), 0.0, // no time; page previews are not animated rOriginalViewInformation.getExtendedInformationSequence()); -- cgit v1.2.3