[Libreoffice-commits] core.git: Branch 'aoo/trunk' - vcl/inc vcl/source
Armin Le Grand
alg at apache.org
Tue Aug 27 07:07:43 PDT 2013
vcl/inc/vcl/bitmapex.hxx | 23 +++++
vcl/inc/vcl/bmpacc.hxx | 10 ++
vcl/source/gdi/bitmapex.cxx | 176 ++++++++++++--------------------------------
vcl/source/gdi/bmpacc.cxx | 120 ++++++++++++++++++++++++++++++
vcl/source/gdi/outdev2.cxx | 125 ++++++++++++++++++++++++++++---
5 files changed, 313 insertions(+), 141 deletions(-)
New commits:
commit 75e9010730525ed6122655ac3c3899359c305104
Author: Armin Le Grand <alg at apache.org>
Date: Tue Aug 27 12:46:41 2013 +0000
i122778 Enhanced own transformer for drawing transformed bitmaps which is used in the cases where no fallback for direct system support is there (Linux)
diff --git a/vcl/inc/vcl/bitmapex.hxx b/vcl/inc/vcl/bitmapex.hxx
index a7663bd..cfc7a8f 100644
--- a/vcl/inc/vcl/bitmapex.hxx
+++ b/vcl/inc/vcl/bitmapex.hxx
@@ -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
diff --git a/vcl/inc/vcl/bmpacc.hxx b/vcl/inc/vcl/bmpacc.hxx
index c22e865..2a51304 100644
--- a/vcl/inc/vcl/bmpacc.hxx
+++ b/vcl/inc/vcl/bmpacc.hxx
@@ -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;
};
// ---------------------
diff --git a/vcl/source/gdi/bitmapex.cxx b/vcl/source/gdi/bitmapex.cxx
index 6925142..5e34624b 100644
--- a/vcl/source/gdi/bitmapex.cxx
+++ b/vcl/source/gdi/bitmapex.cxx
@@ -837,87 +837,6 @@ sal_uInt8 BitmapEx::GetTransparency(sal_Int32 nX, sal_Int32 nY) const
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(
const Bitmap& rSource,
const Size aDestinationSize,
@@ -929,54 +848,41 @@ namespace
if(pWrite)
{
- const Size aContentSizePixel(rSource.GetSizePixel());
+ //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));
+ const 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(nIntX >= 0L && nIntX < aContentSizePixel.getWidth())
+ if(bSmooth)
{
- const sal_Int32 nIntY(basegfx::fround(aSourceCoor.getY()));
-
- 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;
- }
+ pWrite->SetPixel(
+ y,
+ x,
+ pRead->GetInterpolatedColorWithFallback(
+ aSourceCoor.getY(),
+ aSourceCoor.getX(),
+ aOutside));
}
-
- // here are outside pixels. Complete mask
- if(bWorkWithIndex)
+ else
{
- pWrite->SetPixel(y, x, aOutside);
+ // 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));
}
}
}
@@ -992,25 +898,26 @@ namespace
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;
}
diff --git a/vcl/source/gdi/bmpacc.cxx b/vcl/source/gdi/bmpacc.cxx
index ae41737..9e2ab2d 100644
--- a/vcl/source/gdi/bmpacc.cxx
+++ b/vcl/source/gdi/bmpacc.cxx
@@ -324,6 +324,126 @@ sal_uInt16 BitmapReadAccess::GetBestPaletteIndex( const BitmapColor& rBitmapColo
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 -
// ---------------------
diff --git a/vcl/source/gdi/outdev2.cxx b/vcl/source/gdi/outdev2.cxx
index 1ec5f75..cbec937 100644
--- a/vcl/source/gdi/outdev2.cxx
+++ b/vcl/source/gdi/outdev2.cxx
@@ -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::DrawTransformedBitmapEx(
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::DrawTransformedBitmapEx(
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::DrawTransformedBitmapEx(
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::DrawTransformedBitmapEx(
// 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()));
-
- DrawBitmapEx(aDestPt, aDestSize, aTransformed);
+ basegfx::B2DRange aVisibleRange(0.0, 0.0, 1.0, 1.0);
+
+ // 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);
+ }
}
}
More information about the Libreoffice-commits
mailing list