diff options
author | Chris Sherlock <chris.sherlock79@gmail.com> | 2014-03-15 00:50:41 +1100 |
---|---|---|
committer | Norbert Thiebaud <nthiebaud@gmail.com> | 2014-03-22 02:08:36 +0000 |
commit | f84e7f573dd88cc814bdbc8c1678ed64f1edbf48 (patch) | |
tree | d70eda9aebeacbe13bf09da30175e3249579e5fb /vcl/source/gdi/outdev2.cxx | |
parent | 926435ef5ab26e647c09887d471bde25b24e1c16 (diff) |
fdo#74702 Move BitmapEx drawing code to seperate functions
New virtual functions DrawTransformBitmapExDirect() and
TransformReduceBitmapExTargetRange(). Printers cannot do either of
these things so I make it a noop in the Printer class, Window and
VirtualDevice will continue to work as intended.
I have documented these functions in OutputDevice.
Also made some small formatting changes to print.hxx to align tabs.
Change-Id: Idd31d230f95d3b5ea360c72dc8191d47bfd8402b
Reviewed-on: https://gerrit.libreoffice.org/8588
Reviewed-by: Norbert Thiebaud <nthiebaud@gmail.com>
Tested-by: Norbert Thiebaud <nthiebaud@gmail.com>
Diffstat (limited to 'vcl/source/gdi/outdev2.cxx')
-rw-r--r-- | vcl/source/gdi/outdev2.cxx | 220 |
1 files changed, 120 insertions, 100 deletions
diff --git a/vcl/source/gdi/outdev2.cxx b/vcl/source/gdi/outdev2.cxx index 2ff2dd14fead..fc1aaaebc9db 100644 --- a/vcl/source/gdi/outdev2.cxx +++ b/vcl/source/gdi/outdev2.cxx @@ -660,7 +660,124 @@ void OutputDevice::DrawBitmapEx( const Point& rDestPt, const Size& rDestSize, } } +bool OutputDevice::DrawTransformBitmapExDirect( + const basegfx::B2DHomMatrix& aFullTransform, + const BitmapEx& rBitmapEx) +{ + bool bDone = false; + + // try to paint directly + const basegfx::B2DPoint aNull(aFullTransform * basegfx::B2DPoint(0.0, 0.0)); + const basegfx::B2DPoint aTopX(aFullTransform * basegfx::B2DPoint(1.0, 0.0)); + const basegfx::B2DPoint aTopY(aFullTransform * basegfx::B2DPoint(0.0, 1.0)); + SalBitmap* pSalSrcBmp = rBitmapEx.GetBitmap().ImplGetImpBitmap()->ImplGetSalBitmap(); + SalBitmap* pSalAlphaBmp = 0; + + if(rBitmapEx.IsTransparent()) + { + if(rBitmapEx.IsAlpha()) + { + pSalAlphaBmp = rBitmapEx.GetAlpha().ImplGetImpBitmap()->ImplGetSalBitmap(); + } + else + { + pSalAlphaBmp = rBitmapEx.GetMask().ImplGetImpBitmap()->ImplGetSalBitmap(); + } + } + + bDone = mpGraphics->DrawTransformedBitmap( + aNull, + aTopX, + aTopY, + *pSalSrcBmp, + pSalAlphaBmp, + this); + + return bDone; +}; + +bool OutputDevice::TransformReduceBitmapExTargetRange( + const basegfx::B2DHomMatrix& aFullTransform, + basegfx::B2DRange &aVisibleRange, + double &fMaximumArea) +{ + // 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 false; + } + + // 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 false; + } + + // 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 false; + } + + // 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); + + return true; +} void OutputDevice::DrawTransformedBitmapEx( const basegfx::B2DHomMatrix& rTransformation, @@ -704,36 +821,11 @@ void OutputDevice::DrawTransformedBitmapEx( const bool bPrinter(OUTDEV_PRINTER == meOutDevType); bool bDone(false); const basegfx::B2DHomMatrix aFullTransform(GetViewTransformation() * rTransformation); - const bool bTryDirectPaint(!bInvert && !bBitmapChangedColor && !bMetafile && !bPrinter); + const bool bTryDirectPaint(!bInvert && !bBitmapChangedColor && !bMetafile ); if(!bForceToOwnTransformer && bTryDirectPaint) { - // try to paint directly - const basegfx::B2DPoint aNull(aFullTransform * basegfx::B2DPoint(0.0, 0.0)); - const basegfx::B2DPoint aTopX(aFullTransform * basegfx::B2DPoint(1.0, 0.0)); - const basegfx::B2DPoint aTopY(aFullTransform * basegfx::B2DPoint(0.0, 1.0)); - SalBitmap* pSalSrcBmp = rBitmapEx.GetBitmap().ImplGetImpBitmap()->ImplGetSalBitmap(); - SalBitmap* pSalAlphaBmp = 0; - - if(rBitmapEx.IsTransparent()) - { - if(rBitmapEx.IsAlpha()) - { - pSalAlphaBmp = rBitmapEx.GetAlpha().ImplGetImpBitmap()->ImplGetSalBitmap(); - } - else - { - pSalAlphaBmp = rBitmapEx.GetMask().ImplGetImpBitmap()->ImplGetSalBitmap(); - } - } - - bDone = mpGraphics->DrawTransformedBitmap( - aNull, - aTopX, - aTopY, - *pSalSrcBmp, - pSalAlphaBmp, - this); + bDone = DrawTransformBitmapExDirect(aFullTransform, rBitmapEx); } if(!bDone) @@ -765,80 +857,8 @@ void OutputDevice::DrawTransformedBitmapEx( 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 + if ( !TransformReduceBitmapExTargetRange( aFullTransform, aVisibleRange, fMaximumArea ) ) 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()) |