Author: alg Date: Tue Aug 27 12:46:41 2013 New Revision: 1517803 URL: http://svn.apache.org/r1517803 Log: i122778 Enhanced own transformer for drawing transformed bitmaps which is used in the cases where no fallback for direct system support is there (Linux)
Modified: openoffice/trunk/main/vcl/inc/vcl/bitmapex.hxx openoffice/trunk/main/vcl/inc/vcl/bmpacc.hxx openoffice/trunk/main/vcl/source/gdi/bitmapex.cxx openoffice/trunk/main/vcl/source/gdi/bmpacc.cxx openoffice/trunk/main/vcl/source/gdi/outdev2.cxx Modified: openoffice/trunk/main/vcl/inc/vcl/bitmapex.hxx URL: http://svn.apache.org/viewvc/openoffice/trunk/main/vcl/inc/vcl/bitmapex.hxx?rev=1517803&r1=1517802&r2=1517803&view=diff ============================================================================== --- openoffice/trunk/main/vcl/inc/vcl/bitmapex.hxx (original) +++ openoffice/trunk/main/vcl/inc/vcl/bitmapex.hxx Tue Aug 27 12:46:41 2013 @@ -393,25 +393,42 @@ public: @param rTransformation The back transformation for each pixel in (0 .. fWidth),(0 .. fHeight) to local pixel coordiantes + + @param bSmooth + Defines if pixel interpolation is to be used to create the result */ BitmapEx TransformBitmapEx( double fWidth, double fHeight, - const basegfx::B2DHomMatrix& rTransformation) const; + const basegfx::B2DHomMatrix& rTransformation, + bool bSmooth = true) const; /** Create transformed Bitmap @param rTransformation - The transformation from unit coordinates to target + The transformation from unit coordinates to the unit range + + @param rVisibleRange + The relative visible range in unit coordinates, relative to (0,0,1,1) which + defines the whole target area @param fMaximumArea A limitation for the maximum size of pixels to use for the result + @param bSmooth + Defines if pixel interpolation is to be used to create the result + + The traget size of the result bitmap is defined by transforming the given + rTargetRange with the given rTransformation; the area of the result is + linearly scaled to not exceed the given fMaximumArea + @return The transformed bitmap */ BitmapEx getTransformed( const basegfx::B2DHomMatrix& rTransformation, - double fMaximumArea = 500000.0) const; + const basegfx::B2DRange& rVisibleRange, + double fMaximumArea = 500000.0, + bool bSmooth = true) const; /** Create ColorStack-modified version of this BitmapEx Modified: openoffice/trunk/main/vcl/inc/vcl/bmpacc.hxx URL: http://svn.apache.org/viewvc/openoffice/trunk/main/vcl/inc/vcl/bmpacc.hxx?rev=1517803&r1=1517802&r2=1517803&view=diff ============================================================================== --- openoffice/trunk/main/vcl/inc/vcl/bmpacc.hxx (original) +++ openoffice/trunk/main/vcl/inc/vcl/bmpacc.hxx Tue Aug 27 12:46:41 2013 @@ -171,6 +171,16 @@ public: inline BitmapColor GetColor( long nY, long nX ) const; inline sal_uInt8 GetPixelIndex( long nY, long nX ) const; inline sal_uInt8 GetLuminance( long nY, long nX ) const; + + /** Get the interpolated color at coordinates fY, fX; if outside, return rFallback */ + BitmapColor GetInterpolatedColorWithFallback( double fY, double fX, const BitmapColor& rFallback ) const; + + /** Get the color at coordinates fY, fX; if outside, return rFallback. Automatically does the correct + inside/outside checks, e.g. static_cast< sal_uInt32 >(-0.25) *is* 0, not -1 and has to be outside */ + BitmapColor GetColorWithFallback( double fY, double fX, const BitmapColor& rFallback ) const; + + /** Get the color at coordinates nY, nX; if outside, return rFallback */ + BitmapColor GetColorWithFallback( long nY, long nX, const BitmapColor& rFallback ) const; }; // --------------------- Modified: openoffice/trunk/main/vcl/source/gdi/bitmapex.cxx URL: http://svn.apache.org/viewvc/openoffice/trunk/main/vcl/source/gdi/bitmapex.cxx?rev=1517803&r1=1517802&r2=1517803&view=diff ============================================================================== --- openoffice/trunk/main/vcl/source/gdi/bitmapex.cxx (original) +++ openoffice/trunk/main/vcl/source/gdi/bitmapex.cxx Tue Aug 27 12:46:41 2013 @@ -837,180 +837,87 @@ sal_uInt8 BitmapEx::GetTransparency(sal_ namespace { - void impSmoothPoint(BitmapColor& rValue, const basegfx::B2DPoint& rSource, sal_Int32 nIntX, sal_Int32 nIntY, BitmapReadAccess& rRead) - { - double fDeltaX(rSource.getX() - nIntX); - double fDeltaY(rSource.getY() - nIntY); - sal_Int32 nIndX(0L); - sal_Int32 nIndY(0L); - - if(fDeltaX > 0.0 && nIntX + 1L < rRead.Width()) - { - nIndX++; - } - else if(fDeltaX < 0.0 && nIntX >= 1L) - { - fDeltaX = -fDeltaX; - nIndX--; - } - - if(fDeltaY > 0.0 && nIntY + 1L < rRead.Height()) - { - nIndY++; - } - else if(fDeltaY < 0.0 && nIntY >= 1L) - { - fDeltaY = -fDeltaY; - nIndY--; - } - - if(nIndX || nIndY) - { - const double fColorToReal(1.0 / 255.0); - double fR(rValue.GetRed() * fColorToReal); - double fG(rValue.GetGreen() * fColorToReal); - double fB(rValue.GetBlue() * fColorToReal); - double fRBottom(0.0), fGBottom(0.0), fBBottom(0.0); - - if(nIndX) - { - const double fMulA(fDeltaX * fColorToReal); - double fMulB(1.0 - fDeltaX); - const BitmapColor aTopPartner(rRead.GetColor(nIntY, nIntX + nIndX)); - - fR = (fR * fMulB) + (aTopPartner.GetRed() * fMulA); - fG = (fG * fMulB) + (aTopPartner.GetGreen() * fMulA); - fB = (fB * fMulB) + (aTopPartner.GetBlue() * fMulA); - - if(nIndY) - { - fMulB *= fColorToReal; - const BitmapColor aBottom(rRead.GetColor(nIntY + nIndY, nIntX)); - const BitmapColor aBottomPartner(rRead.GetColor(nIntY + nIndY, nIntX + nIndX)); - - fRBottom = (aBottom.GetRed() * fMulB) + (aBottomPartner.GetRed() * fMulA); - fGBottom = (aBottom.GetGreen() * fMulB) + (aBottomPartner.GetGreen() * fMulA); - fBBottom = (aBottom.GetBlue() * fMulB) + (aBottomPartner.GetBlue() * fMulA); - } - } - - if(nIndY) - { - if(!nIndX) - { - const BitmapColor aBottom(rRead.GetColor(nIntY + nIndY, nIntX)); - - fRBottom = aBottom.GetRed() * fColorToReal; - fGBottom = aBottom.GetGreen() * fColorToReal; - fBBottom = aBottom.GetBlue() * fColorToReal; - } - - const double fMulB(1.0 - fDeltaY); - - fR = (fR * fMulB) + (fRBottom * fDeltaY); - fG = (fG * fMulB) + (fGBottom * fDeltaY); - fB = (fB * fMulB) + (fBBottom * fDeltaY); - } - - rValue.SetRed((sal_uInt8)(fR * 255.0)); - rValue.SetGreen((sal_uInt8)(fG * 255.0)); - rValue.SetBlue((sal_uInt8)(fB * 255.0)); - } - } - - Bitmap impTransformBitmap( + Bitmap impTransformBitmap( const Bitmap& rSource, const Size aDestinationSize, const basegfx::B2DHomMatrix& rTransform, bool bSmooth) - { + { Bitmap aDestination(aDestinationSize, 24); BitmapWriteAccess* pWrite = aDestination.AcquireWriteAccess(); - if(pWrite) - { - const Size aContentSizePixel(rSource.GetSizePixel()); - BitmapReadAccess* pRead = (const_cast< Bitmap& >(rSource)).AcquireReadAccess(); - - if(pRead) - { - const Size aDestinationSizePixel(aDestination.GetSizePixel()); - bool bWorkWithIndex(rSource.GetBitCount() <= 8); - BitmapColor aOutside(BitmapColor(0xff, 0xff, 0xff)); - - for(sal_Int32 y(0L); y < aDestinationSizePixel.getHeight(); y++) - { - for(sal_Int32 x(0L); x < aDestinationSizePixel.getWidth(); x++) - { - const basegfx::B2DPoint aSourceCoor(rTransform * basegfx::B2DPoint(x, y)); - const sal_Int32 nIntX(basegfx::fround(aSourceCoor.getX())); + if(pWrite) + { + //const Size aContentSizePixel(rSource.GetSizePixel()); + BitmapReadAccess* pRead = (const_cast< Bitmap& >(rSource)).AcquireReadAccess(); - if(nIntX >= 0L && nIntX < aContentSizePixel.getWidth()) - { - const sal_Int32 nIntY(basegfx::fround(aSourceCoor.getY())); + if(pRead) + { + const Size aDestinationSizePixel(aDestination.GetSizePixel()); + const BitmapColor aOutside(BitmapColor(0xff, 0xff, 0xff)); - if(nIntY >= 0L && nIntY < aContentSizePixel.getHeight()) - { - // inside pixel - BitmapColor aValue; - - if(bWorkWithIndex) - { - aValue = pRead->GetPaletteColor(pRead->GetPixelIndex(nIntY, nIntX)); - } - else - { - aValue = pRead->GetPixel(nIntY, nIntX); - } - - if(bSmooth) - { - impSmoothPoint(aValue, aSourceCoor, nIntX, nIntY, *pRead); - } - - pWrite->SetPixel(y, x, aValue); - continue; - } - } + for(sal_Int32 y(0L); y < aDestinationSizePixel.getHeight(); y++) + { + for(sal_Int32 x(0L); x < aDestinationSizePixel.getWidth(); x++) + { + const basegfx::B2DPoint aSourceCoor(rTransform * basegfx::B2DPoint(x, y)); - // here are outside pixels. Complete mask - if(bWorkWithIndex) - { - pWrite->SetPixel(y, x, aOutside); - } - } - } + if(bSmooth) + { + pWrite->SetPixel( + y, + x, + pRead->GetInterpolatedColorWithFallback( + aSourceCoor.getY(), + aSourceCoor.getX(), + aOutside)); + } + else + { + // this version does the correct <= 0.0 checks, so no need + // to do the static_cast< sal_Int32 > self and make an error + pWrite->SetPixel( + y, + x, + pRead->GetColorWithFallback( + aSourceCoor.getY(), + aSourceCoor.getX(), + aOutside)); + } + } + } - delete pRead; - } + delete pRead; + } - delete pWrite; - } + delete pWrite; + } rSource.AdaptBitCount(aDestination); return aDestination; - } + } } // end of anonymous namespace + BitmapEx BitmapEx::TransformBitmapEx( double fWidth, double fHeight, - const basegfx::B2DHomMatrix& rTransformation) const + const basegfx::B2DHomMatrix& rTransformation, + bool bSmooth) const { if(fWidth <= 1 || fHeight <= 1) return BitmapEx(); // force destination to 24 bit, we want to smooth output const Size aDestinationSize(basegfx::fround(fWidth), basegfx::fround(fHeight)); - static bool bDoSmoothAtAll(true); - const Bitmap aDestination(impTransformBitmap(GetBitmap(), aDestinationSize, rTransformation, bDoSmoothAtAll)); + const Bitmap aDestination(impTransformBitmap(GetBitmap(), aDestinationSize, rTransformation, bSmooth)); // create mask if(IsTransparent()) { if(IsAlpha()) { - const Bitmap aAlpha(impTransformBitmap(GetAlpha().GetBitmap(), aDestinationSize, rTransformation, bDoSmoothAtAll)); + const Bitmap aAlpha(impTransformBitmap(GetAlpha().GetBitmap(), aDestinationSize, rTransformation, bSmooth)); return BitmapEx(aDestination, AlphaMask(aAlpha)); } else @@ -1027,7 +934,9 @@ BitmapEx BitmapEx::TransformBitmapEx( BitmapEx BitmapEx::getTransformed( const basegfx::B2DHomMatrix& rTransformation, - double fMaximumArea) const + const basegfx::B2DRange& rVisibleRange, + double fMaximumArea, + bool bSmooth) const { BitmapEx aRetval; @@ -1040,20 +949,31 @@ BitmapEx BitmapEx::getTransformed( if(!nSourceWidth || !nSourceHeight) return aRetval; - // Get dest range + // Get aOutlineRange basegfx::B2DRange aOutlineRange(0.0, 0.0, 1.0, 1.0); + aOutlineRange.transform(rTransformation); - // get target size - double fWidth(aOutlineRange.getWidth()); - double fHeight(aOutlineRange.getHeight()); + // create visible range from it by moving from relative to absolute + basegfx::B2DRange aVisibleRange(rVisibleRange); + + aVisibleRange.transform( + basegfx::tools::createScaleTranslateB2DHomMatrix( + aOutlineRange.getRange(), + aOutlineRange.getMinimum())); + + // get target size (which is visible range's size) + double fWidth(aVisibleRange.getWidth()); + double fHeight(aVisibleRange.getHeight()); if(fWidth < 1.0 || fHeight < 1.0) + { return aRetval; + } // test if discrete size (pixel) maybe too big and limit it const double fArea(fWidth * fHeight); - const bool bNeedToReduce(fArea > fMaximumArea); + const bool bNeedToReduce(basegfx::fTools::more(fArea, fMaximumArea)); double fReduceFactor(1.0); if(bNeedToReduce) @@ -1074,8 +994,10 @@ BitmapEx BitmapEx::getTransformed( // aOutlineRange aTransform = rTransformation * aTransform; - // substract top-left of aOutlineRange - aTransform.translate(-aOutlineRange.getMinX(), -aOutlineRange.getMinY()); + // substract top-left of absolute VisibleRange + aTransform.translate( + -aVisibleRange.getMinX(), + -aVisibleRange.getMinY()); // scale to target pixels (if needed) if(bNeedToReduce) @@ -1087,7 +1009,7 @@ BitmapEx BitmapEx::getTransformed( aTransform.invert(); // create bitmap using source, destination and linear back-transformation - aRetval = TransformBitmapEx(fWidth, fHeight, aTransform); + aRetval = TransformBitmapEx(fWidth, fHeight, aTransform, bSmooth); return aRetval; } Modified: openoffice/trunk/main/vcl/source/gdi/bmpacc.cxx URL: http://svn.apache.org/viewvc/openoffice/trunk/main/vcl/source/gdi/bmpacc.cxx?rev=1517803&r1=1517802&r2=1517803&view=diff ============================================================================== --- openoffice/trunk/main/vcl/source/gdi/bmpacc.cxx (original) +++ openoffice/trunk/main/vcl/source/gdi/bmpacc.cxx Tue Aug 27 12:46:41 2013 @@ -324,6 +324,126 @@ sal_uInt16 BitmapReadAccess::GetBestPale return( HasPalette() ? mpBuffer->maPalette.GetBestIndex( rBitmapColor ) : 0 ); } +BitmapColor BitmapReadAccess::GetInterpolatedColorWithFallback( double fY, double fX, const BitmapColor& rFallback ) const +{ + // ask directly doubles >= 0.0 here to avoid rounded values of 0 at small negative + // double values, e.g. static_cast< sal_Int32 >(-0.25) is 0, not -1, but *has* to be outside (!) + if(mpBuffer && fX >= 0.0 && fY >= 0.0) + { + const sal_Int32 nX(static_cast< sal_Int32 >(fX)); + const sal_Int32 nY(static_cast< sal_Int32 >(fY)); + + if(nX < mpBuffer->mnWidth && nY < mpBuffer->mnHeight) + { + // get base-return value from inside pixel + BitmapColor aRetval(GetColor(nY, nX)); + + // calculate deltas and indices for neighbour accesses + sal_Int16 nDeltaX((fX - (nX + 0.5)) * 255.0); // [-255 .. 255] + sal_Int16 nDeltaY((fY - (nY + 0.5)) * 255.0); // [-255 .. 255] + sal_Int16 nIndX(0); + sal_Int16 nIndY(0); + + if(nDeltaX > 0) + { + nIndX = nX + 1; + } + else + { + nIndX = nX - 1; + nDeltaX = -nDeltaX; + } + + if(nDeltaY > 0) + { + nIndY = nY + 1; + } + else + { + nIndY = nY - 1; + nDeltaY = -nDeltaY; + } + + // get right/left neighbour + BitmapColor aXCol(rFallback); + + if(nDeltaX && nIndX >= 0 && nIndX < mpBuffer->mnWidth) + { + aXCol = GetColor(nY, nIndX); + } + + // get top/bottom neighbour + BitmapColor aYCol(rFallback); + + if(nDeltaY && nIndY >= 0 && nIndY < mpBuffer->mnHeight) + { + aYCol = GetColor(nIndY, nX); + } + + // get one of four edge neighbours + BitmapColor aXYCol(rFallback); + + if(nDeltaX && nDeltaY && nIndX >=0 && nIndY >= 0 && nIndX < mpBuffer->mnWidth && nIndY < mpBuffer->mnHeight) + { + aXYCol = GetColor(nIndY, nIndX); + } + + // merge return value with right/left neighbour + if(aXCol != aRetval) + { + aRetval.Merge(aXCol, 255 - nDeltaX); + } + + // merge top/bottom neighbour with edge + if(aYCol != aXYCol) + { + aYCol.Merge(aXYCol, 255 - nDeltaX); + } + + // merge return value with already merged top/bottom neighbour + if(aRetval != aYCol) + { + aRetval.Merge(aYCol, 255 - nDeltaY); + } + + return aRetval; + } + } + + return rFallback; +} + +BitmapColor BitmapReadAccess::GetColorWithFallback( double fY, double fX, const BitmapColor& rFallback ) const +{ + // ask directly doubles >= 0.0 here to avoid rounded values of 0 at small negative + // double values, e.g. static_cast< sal_Int32 >(-0.25) is 0, not -1, but *has* to be outside (!) + if(mpBuffer && fX >= 0.0 && fY >= 0.0) + { + const sal_Int32 nX(static_cast< sal_Int32 >(fX)); + const sal_Int32 nY(static_cast< sal_Int32 >(fY)); + + if(nX < mpBuffer->mnWidth && nY < mpBuffer->mnHeight) + { + return GetColor(nY, nX); + } + } + + return rFallback; +} + +BitmapColor BitmapReadAccess::GetColorWithFallback( long nY, long nX, const BitmapColor& rFallback ) const +{ + if(mpBuffer) + { + if(nX >= 0 && nY >= 0 && nX < mpBuffer->mnWidth && nY < mpBuffer->mnHeight) + { + return GetColor(nY, nX); + } + } + + return rFallback; +} + // --------------------- // - BitmapWriteAccess - // --------------------- Modified: openoffice/trunk/main/vcl/source/gdi/outdev2.cxx URL: http://svn.apache.org/viewvc/openoffice/trunk/main/vcl/source/gdi/outdev2.cxx?rev=1517803&r1=1517802&r2=1517803&view=diff ============================================================================== --- openoffice/trunk/main/vcl/source/gdi/outdev2.cxx (original) +++ openoffice/trunk/main/vcl/source/gdi/outdev2.cxx Tue Aug 27 12:46:41 2013 @@ -43,6 +43,7 @@ #include <window.h> #include <outdata.hxx> #include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> #define BAND_MAX_SIZE 512000 @@ -818,8 +819,9 @@ void OutputDevice::DrawTransformedBitmap const bool bSheared(!basegfx::fTools::equalZero(fShearX)); const bool bMirroredX(basegfx::fTools::less(aScale.getX(), 0.0)); const bool bMirroredY(basegfx::fTools::less(aScale.getY(), 0.0)); + static bool bForceToOwnTransformer(false); - if(!bRotated && !bSheared && !bMirroredX && !bMirroredY) + if(!bForceToOwnTransformer && !bRotated && !bSheared && !bMirroredX && !bMirroredY) { // with no rotation, shear or mirroring it can be mapped to DrawBitmapEx // do *not* execute the mirroring here, it's done in the fallback @@ -840,7 +842,7 @@ void OutputDevice::DrawTransformedBitmap const basegfx::B2DHomMatrix aFullTransform(GetViewTransformation() * rTransformation); const bool bTryDirectPaint(!bInvert && !bBitmapChangedColor && !bMetafile && !bPrinter); - if(bTryDirectPaint) + if(!bForceToOwnTransformer && bTryDirectPaint) { // try to paint directly const basegfx::B2DPoint aNull(aFullTransform * basegfx::B2DPoint(0.0, 0.0)); @@ -873,7 +875,7 @@ void OutputDevice::DrawTransformedBitmap if(!bDone) { // take the fallback when no rotate and shear, but mirror (else we would have done this above) - if(!bRotated && !bSheared) + if(!bForceToOwnTransformer && !bRotated && !bSheared) { // with no rotation or shear it can be mapped to DrawBitmapEx // do *not* execute the mirroring here, it's done in the fallback @@ -886,14 +888,115 @@ void OutputDevice::DrawTransformedBitmap // fallback; create transformed bitmap the hard way (back-transform // the pixels) and paint - basegfx::B2DRange aTargetRange(0.0, 0.0, 1.0, 1.0); - const double fMaximumArea(bMetafile ? 800000.0 : 200000.0); - const BitmapEx aTransformed(rBitmapEx.getTransformed(aFullTransform, fMaximumArea)); - aTargetRange.transform(rTransformation); - const Point aDestPt(basegfx::fround(aTargetRange.getMinX()), basegfx::fround(aTargetRange.getMinY())); - const Size aDestSize(basegfx::fround(aTargetRange.getWidth()), basegfx::fround(aTargetRange.getHeight())); + basegfx::B2DRange aVisibleRange(0.0, 0.0, 1.0, 1.0); - DrawBitmapEx(aDestPt, aDestSize, aTransformed); + // limit maximum area to something looking good for non-pixel-based targets (metafile, printer) + double fMaximumArea(1000000.0); + + if(!bMetafile && !bPrinter) + { + // limit TargetRange to existing pixels (if pixel device) + // first get discrete range of object + basegfx::B2DRange aFullPixelRange(aVisibleRange); + + aFullPixelRange.transform(aFullTransform); + + if(basegfx::fTools::equalZero(aFullPixelRange.getWidth()) || basegfx::fTools::equalZero(aFullPixelRange.getHeight())) + { + // object is outside of visible area + return; + } + + // now get discrete target pixels; start with OutDev pixel size and evtl. + // intersect with active clipping area + basegfx::B2DRange aOutPixel( + 0.0, + 0.0, + GetOutputSizePixel().Width(), + GetOutputSizePixel().Height()); + + if(IsClipRegion()) + { + const Rectangle aRegionRectangle(GetActiveClipRegion().GetBoundRect()); + + aOutPixel.intersect( // caution! Range from rectangle, one too much (!) + basegfx::B2DRange( + aRegionRectangle.Left(), + aRegionRectangle.Top(), + aRegionRectangle.Right() + 1, + aRegionRectangle.Bottom() + 1)); + } + + if(aOutPixel.isEmpty()) + { + // no active output area + return; + } + + // if aFullPixelRange is not completely inside of aOutPixel, + // reduction of target pixels is possible + basegfx::B2DRange aVisiblePixelRange(aFullPixelRange); + + if(!aOutPixel.isInside(aFullPixelRange)) + { + aVisiblePixelRange.intersect(aOutPixel); + + if(aVisiblePixelRange.isEmpty()) + { + // nothing in visible part, reduces to nothing + return; + } + + // aVisiblePixelRange contains the reduced output area in + // discrete coordinates. To make it useful everywhere, make it relative to + // the object range + basegfx::B2DHomMatrix aMakeVisibleRangeRelative; + + aVisibleRange = aVisiblePixelRange; + aMakeVisibleRangeRelative.translate( + -aFullPixelRange.getMinX(), + -aFullPixelRange.getMinY()); + aMakeVisibleRangeRelative.scale( + 1.0 / aFullPixelRange.getWidth(), + 1.0 / aFullPixelRange.getHeight()); + aVisibleRange.transform(aMakeVisibleRangeRelative); + } + + // for pixel devices, do *not* limit size, else OutputDevice::ImplDrawAlpha + // will create another, badly scaled bitmap to do the job. Nonetheless, do a + // maximum clipping of something big (1600x1280x2). Add 1.0 to avoid rounding + // errors in rough estimations + const double fNewMaxArea(aVisiblePixelRange.getWidth() * aVisiblePixelRange.getHeight()); + + fMaximumArea = std::min(4096000.0, fNewMaxArea + 1.0); + } + + if(!aVisibleRange.isEmpty()) + { + static bool bDoSmoothAtAll(true); + const BitmapEx aTransformed( + rBitmapEx.getTransformed( + aFullTransform, + aVisibleRange, + fMaximumArea, + bDoSmoothAtAll)); + basegfx::B2DRange aTargetRange(0.0, 0.0, 1.0, 1.0); + + // get logic object target range + aTargetRange.transform(rTransformation); + + // get from unified/relative VisibleRange to logoc one + aVisibleRange.transform( + basegfx::tools::createScaleTranslateB2DHomMatrix( + aTargetRange.getRange(), + aTargetRange.getMinimum())); + + // extract point and size; do not remove size, the bitmap may have been prepared reduced by purpose + const Point aDestPt(basegfx::fround(aVisibleRange.getMinX()), basegfx::fround(aVisibleRange.getMinY())); + const Size aDestSize(basegfx::fround(aVisibleRange.getWidth()), basegfx::fround(aVisibleRange.getHeight())); + + DrawBitmapEx(aDestPt, aDestSize, aTransformed); + } } }