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 | |
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>
-rw-r--r-- | include/vcl/outdev.hxx | 26 | ||||
-rw-r--r-- | include/vcl/print.hxx | 62 | ||||
-rw-r--r-- | vcl/source/gdi/outdev2.cxx | 220 | ||||
-rw-r--r-- | vcl/source/gdi/print.cxx | 23 |
4 files changed, 204 insertions, 127 deletions
diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx index 117ddb721493..933f199419ae 100644 --- a/include/vcl/outdev.hxx +++ b/include/vcl/outdev.hxx @@ -804,6 +804,32 @@ protected: const Point& rSrcPtPixel, const Size& rSrcSizePixel ); virtual long ImplGetGradientStepCount( long nMinRect ); + /** Transform and draw a bitmap directly + + @param aFullTransform The B2DHomMatrix used for the transformation + @param rBitmapEx Reference to the bitmap to be transformed and drawn + + @return true if it was able to draw the bitmap, false if not + */ + virtual bool DrawTransformBitmapExDirect( + const basegfx::B2DHomMatrix& aFullTransform, + const BitmapEx& rBitmapEx); + + /** Reduce the area that needs to be drawn of the bitmap and return the new + visible range and the maximum area. + + + @param aFullTransform B2DHomMatrix used for transformation + @param aVisibleRange The new visible area of the bitmap + @param fMaximumArea The maximum area of the bitmap + + @returns true if there is an area to be drawn, otherwise nothing is left to be drawn + so return false + */ + virtual bool TransformReduceBitmapExTargetRange( + const basegfx::B2DHomMatrix& aFullTransform, + basegfx::B2DRange &aVisibleRange, + double &fMaximumArea); private: typedef void ( OutputDevice::* FontUpdateHandler_t )( bool ); diff --git a/include/vcl/print.hxx b/include/vcl/print.hxx index 408ec66ce33e..deade5f894db 100644 --- a/include/vcl/print.hxx +++ b/include/vcl/print.hxx @@ -155,10 +155,10 @@ private: PrinterTransparencyMode meReducedTransparencyMode; bool mbReduceGradients; PrinterGradientMode meReducedGradientsMode; - sal_uInt16 mnReducedGradientStepCount; + sal_uInt16 mnReducedGradientStepCount; bool mbReduceBitmaps; PrinterBitmapMode meReducedBitmapMode; - sal_uInt16 mnReducedBitmapResolution; + sal_uInt16 mnReducedBitmapResolution; bool mbReducedBitmapsIncludeTransparency; bool mbConvertToGreyscales; bool mbPDFAsStandardPrintJobFormat; @@ -180,7 +180,7 @@ public: PrinterGradientMode GetReducedGradientMode() const { return meReducedGradientsMode; } void SetReducedGradientMode( PrinterGradientMode eMode ) { meReducedGradientsMode = eMode; } - sal_uInt16 GetReducedGradientStepCount() const { return mnReducedGradientStepCount; } + sal_uInt16 GetReducedGradientStepCount() const { return mnReducedGradientStepCount; } void SetReducedGradientStepCount( sal_uInt16 nStepCount ) { mnReducedGradientStepCount = nStepCount; } bool IsReduceBitmaps() const { return mbReduceBitmaps; } @@ -189,7 +189,7 @@ public: PrinterBitmapMode GetReducedBitmapMode() const { return meReducedBitmapMode; } void SetReducedBitmapMode( PrinterBitmapMode eMode ) { meReducedBitmapMode = eMode; } - sal_uInt16 GetReducedBitmapResolution() const { return mnReducedBitmapResolution; } + sal_uInt16 GetReducedBitmapResolution() const { return mnReducedBitmapResolution; } void SetReducedBitmapResolution( sal_uInt16 nResolution ) { mnReducedBitmapResolution = nResolution; } bool IsReducedBitmapIncludesTransparency() const { return mbReducedBitmapsIncludeTransparency; } @@ -286,6 +286,16 @@ protected: const Point& rDestPt, const Size& rDestSize, const Point& rSrcPtPixel, const Size& rSrcSizePixel ); + bool DrawTransformBitmapExDirect( + const basegfx::B2DHomMatrix& aFullTransform, + const BitmapEx& rBitmapEx); + + bool TransformReduceBitmapExTargetRange( + const basegfx::B2DHomMatrix& aFullTransform, + basegfx::B2DRange &aVisibleRange, + double &fMaximumArea); + + public: Printer(); Printer( const JobSetup& rJobSetup ); @@ -295,17 +305,17 @@ public: static const std::vector< OUString >& GetPrinterQueues(); static const QueueInfo* GetQueueInfo( const OUString& rPrinterName, bool bStatusUpdate ); - static OUString GetDefaultPrinterName(); + static OUString GetDefaultPrinterName(); virtual void Error(); - const OUString& GetName() const { return maPrinterName; } - const OUString& GetDriverName() const { return maDriver; } + const OUString& GetName() const { return maPrinterName; } + const OUString& GetDriverName() const { return maDriver; } bool IsDefPrinter() const { return mbDefPrinter; } bool IsDisplayPrinter() const { return mpDisplayDev != NULL; } bool IsValid() const { return !IsDisplayPrinter(); } - sal_uLong GetCapabilities( sal_uInt16 nType ) const; + sal_uLong GetCapabilities( sal_uInt16 nType ) const; bool HasSupport( PrinterSupport eFeature ) const; bool SetJobSetup( const JobSetup& rSetup ); @@ -330,21 +340,21 @@ public: // the current paper int GetLandscapeAngle() const; bool SetPaperBin( sal_uInt16 nPaperBin ); - sal_uInt16 GetPaperBin() const; + sal_uInt16 GetPaperBin() const; bool SetPaper( Paper ePaper ); bool SetPaperSizeUser( const Size& rSize ); bool SetPaperSizeUser( const Size& rSize, bool bMatchNearest ); - Paper GetPaper() const; - static OUString GetPaperName( Paper ePaper ); + Paper GetPaper() const; + static OUString GetPaperName( Paper ePaper ); // return a UI string for the current paper; i_bPaperUser == false means an empty string for PAPER_USER - OUString GetPaperName( bool i_bPaperUser = true ) const; + OUString GetPaperName( bool i_bPaperUser = true ) const; // returns number of available paper formats int GetPaperInfoCount() const; // returns info about paper format nPaper const PaperInfo& GetPaperInfo( int nPaper ) const; - sal_uInt16 GetPaperBinCount() const; - OUString GetPaperBinName( sal_uInt16 nPaperBin ) const; + sal_uInt16 GetPaperBinCount() const; + OUString GetPaperBinName( sal_uInt16 nPaperBin ) const; const Size& GetPaperSizePixel() const { return maPaperSize; } Size GetPaperSize() const { return PixelToLogic( maPaperSize ); } @@ -352,17 +362,17 @@ public: Point GetPageOffset() const { return PixelToLogic( maPageOffset ); } bool SetCopyCount( sal_uInt16 nCopy, bool bCollate = false ); - sal_uInt16 GetCopyCount() const { return mnCopyCount; } + sal_uInt16 GetCopyCount() const { return mnCopyCount; } bool IsCollateCopy() const { return mbCollateCopy; } bool IsPrinting() const { return mbPrinting; } - const OUString& GetCurJobName() const { return maJobName; } - sal_uInt16 GetCurPage() const { return mnCurPage; } + const OUString& GetCurJobName() const { return maJobName; } + sal_uInt16 GetCurPage() const { return mnCurPage; } bool IsJobActive() const { return mbJobActive; } - sal_uLong GetError() const { return ERRCODE_TOERROR(mnError); } - sal_uLong GetErrorCode() const { return mnError; } + sal_uLong GetError() const { return ERRCODE_TOERROR(mnError); } + sal_uLong GetErrorCode() const { return mnError; } void SetErrorHdl( const Link& rLink ) { maErrorHdl = rLink; } const Link& GetErrorHdl() const { return maErrorHdl; } @@ -372,24 +382,22 @@ public: * sends a DataChanged event of type DATACHANGED_PRINTER * if the printer list changed */ - static void updatePrinters(); + static void updatePrinters(); /** execute a print job starts a print job asynchronously (that is will return */ - static void PrintJob( const boost::shared_ptr<vcl::PrinterController>& i_pController, - const JobSetup& i_rInitSetup - ); + static void PrintJob( const boost::shared_ptr<vcl::PrinterController>& i_pController, + const JobSetup& i_rInitSetup ); - virtual bool HasMirroredGraphics() const; + virtual bool HasMirroredGraphics() const; // implementation detail of PrintJob being asynchronous // not exported, not usable outside vcl - static void SAL_DLLPRIVATE ImplPrintJob( const boost::shared_ptr<vcl::PrinterController>& i_pController, - const JobSetup& i_rInitSetup - ); + static void SAL_DLLPRIVATE ImplPrintJob( const boost::shared_ptr<vcl::PrinterController>& i_pController, + const JobSetup& i_rInitSetup ); }; namespace vcl 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()) diff --git a/vcl/source/gdi/print.cxx b/vcl/source/gdi/print.cxx index f33037c6d155..78d7eb5813e4 100644 --- a/vcl/source/gdi/print.cxx +++ b/vcl/source/gdi/print.cxx @@ -211,6 +211,29 @@ bool PrinterOptions::ReadFromConfig( bool i_bFile ) return bSuccess; } +bool Printer::DrawTransformBitmapExDirect( + const basegfx::B2DHomMatrix& aFullTransform, + const BitmapEx& rBitmapEx) +{ + // printers can't draw bitmaps directly + (void) aFullTransform; + (void) rBitmapEx; + return false; +} + +bool Printer::TransformReduceBitmapExTargetRange( + const basegfx::B2DHomMatrix& aFullTransform, + basegfx::B2DRange &aVisibleRange, + double &fMaximumArea) +{ + // deliberately do nothing - you can't reduce the + // target range for a printer at all + (void) aFullTransform; + (void) aVisibleRange; + (void) fMaximumArea; + return true; +} + void Printer::SetPrinterOptions( const PrinterOptions& i_rOptions ) { *mpPrinterOptions = i_rOptions; |