LCOV - code coverage report
Current view: top level - libreoffice/drawinglayer/source/processor2d - vclhelperbitmaprender.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 17 95 17.9 %
Date: 2012-12-27 Functions: 1 3 33.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <vclhelperbitmaprender.hxx>
      21             : #include <svtools/grfmgr.hxx>
      22             : #include <basegfx/vector/b2dvector.hxx>
      23             : #include <basegfx/matrix/b2dhommatrix.hxx>
      24             : #include <basegfx/range/b2drange.hxx>
      25             : #include <vcl/outdev.hxx>
      26             : #include <vclhelperbitmaptransform.hxx>
      27             : #include <basegfx/matrix/b2dhommatrixtools.hxx>
      28             : 
      29             : //////////////////////////////////////////////////////////////////////////////
      30             : // support for different kinds of bitmap rendering using vcl
      31             : 
      32             : namespace drawinglayer
      33             : {
      34           8 :     void RenderBitmapPrimitive2D_GraphicManager(
      35             :         OutputDevice& rOutDev,
      36             :         const BitmapEx& rBitmapEx,
      37             :         const basegfx::B2DHomMatrix& rTransform)
      38             :     {
      39             :         // prepare attributes
      40           8 :         GraphicAttr aAttributes;
      41             : 
      42             :         // decompose matrix to check for shear, rotate and mirroring
      43           8 :         basegfx::B2DVector aScale, aTranslate;
      44             :         double fRotate, fShearX;
      45           8 :         rTransform.decompose(aScale, aTranslate, fRotate, fShearX);
      46             : 
      47             :         // mirror flags
      48           8 :         const bool bMirrorX(basegfx::fTools::less(aScale.getX(), 0.0));
      49           8 :         const bool bMirrorY(basegfx::fTools::less(aScale.getY(), 0.0));
      50           8 :         aAttributes.SetMirrorFlags((bMirrorX ? BMP_MIRROR_HORZ : 0)|(bMirrorY ? BMP_MIRROR_VERT : 0));
      51             : 
      52             :         // rotation
      53           8 :         if(!basegfx::fTools::equalZero(fRotate))
      54             :         {
      55           0 :             double fRotation(fmod(3600.0 - (fRotate * (10.0 / F_PI180)), 3600.0));
      56           0 :             aAttributes.SetRotation((sal_uInt16)(fRotation));
      57             :         }
      58             : 
      59             :         // prepare Bitmap
      60           8 :         basegfx::B2DRange aOutlineRange(0.0, 0.0, 1.0, 1.0);
      61             : 
      62           8 :         if(basegfx::fTools::equalZero(fRotate))
      63             :         {
      64           8 :             aOutlineRange.transform(rTransform);
      65             :         }
      66             :         else
      67             :         {
      68             :             // if rotated, create the unrotated output rectangle for the GraphicManager paint
      69             :             // #118824# Caution! When mirrored, adapt transformation accordingly
      70             :             const basegfx::B2DHomMatrix aSimpleObjectMatrix(
      71             :                 basegfx::tools::createScaleTranslateB2DHomMatrix(
      72           0 :                     fabs(aScale.getX()),
      73           0 :                     fabs(aScale.getY()),
      74           0 :                     bMirrorX ? aTranslate.getX() - fabs(aScale.getX()): aTranslate.getX(),
      75           0 :                     bMirrorY ? aTranslate.getY() - fabs(aScale.getY()): aTranslate.getY()));
      76             : 
      77           0 :             aOutlineRange.transform(aSimpleObjectMatrix);
      78             :         }
      79             : 
      80             :         // prepare dest coordinates
      81             :         const Point aPoint(
      82             :                 basegfx::fround(aOutlineRange.getMinX()),
      83           8 :                 basegfx::fround(aOutlineRange.getMinY()));
      84             :         const Size aSize(
      85             :                 basegfx::fround(aOutlineRange.getWidth()),
      86           8 :                 basegfx::fround(aOutlineRange.getHeight()));
      87             : 
      88             :         // paint it using GraphicManager
      89           8 :         Graphic aGraphic(rBitmapEx);
      90           8 :         GraphicObject aGraphicObject(aGraphic);
      91           8 :         aGraphicObject.Draw(&rOutDev, aPoint, aSize, &aAttributes);
      92           8 :     }
      93             : 
      94           0 :     void RenderBitmapPrimitive2D_BitmapEx(
      95             :         OutputDevice& rOutDev,
      96             :         const BitmapEx& rBitmapEx,
      97             :         const basegfx::B2DHomMatrix& rTransform)
      98             :     {
      99             :         // only translate and scale, use vcl's DrawBitmapEx().
     100           0 :         BitmapEx aContent(rBitmapEx);
     101             : 
     102             :         // prepare dest coor. Necessary to expand since vcl's DrawBitmapEx draws one pix less
     103           0 :         basegfx::B2DRange aOutlineRange(0.0, 0.0, 1.0, 1.0);
     104           0 :         aOutlineRange.transform(rTransform);
     105             :         // prepare dest coordinates
     106             :         const Point aPoint(
     107             :                 basegfx::fround(aOutlineRange.getMinX()),
     108           0 :                 basegfx::fround(aOutlineRange.getMinY()));
     109             :         const Size aSize(
     110             :                 basegfx::fround(aOutlineRange.getWidth()),
     111           0 :                 basegfx::fround(aOutlineRange.getHeight()));
     112             : 
     113             :         // decompose matrix to check for shear, rotate and mirroring
     114           0 :         basegfx::B2DVector aScale, aTranslate;
     115             :         double fRotate, fShearX;
     116           0 :         rTransform.decompose(aScale, aTranslate, fRotate, fShearX);
     117             : 
     118             :         // Check mirroring.
     119           0 :         sal_uInt32 nMirrorFlags(BMP_MIRROR_NONE);
     120             : 
     121           0 :         if(basegfx::fTools::less(aScale.getX(), 0.0))
     122             :         {
     123           0 :             nMirrorFlags |= BMP_MIRROR_HORZ;
     124             :         }
     125             : 
     126           0 :         if(basegfx::fTools::less(aScale.getY(), 0.0))
     127             :         {
     128           0 :             nMirrorFlags |= BMP_MIRROR_VERT;
     129             :         }
     130             : 
     131           0 :         if(BMP_MIRROR_NONE != nMirrorFlags)
     132             :         {
     133           0 :             aContent.Mirror(nMirrorFlags);
     134             :         }
     135             : 
     136             :         // draw bitmap
     137           0 :         rOutDev.DrawBitmapEx(aPoint, aSize, aContent);
     138           0 :     }
     139             : 
     140           0 :     void RenderBitmapPrimitive2D_self(
     141             :         OutputDevice& rOutDev,
     142             :         const BitmapEx& rBitmapEx,
     143             :         const basegfx::B2DHomMatrix& rTransform)
     144             :     {
     145             :         // process self with free transformation (containing shear and rotate). Get dest rect in pixels.
     146           0 :         basegfx::B2DRange aOutlineRange(0.0, 0.0, 1.0, 1.0);
     147           0 :         aOutlineRange.transform(rTransform);
     148             :         const Rectangle aDestRectLogic(
     149             :             basegfx::fround(aOutlineRange.getMinX()),
     150             :             basegfx::fround(aOutlineRange.getMinY()),
     151             :             basegfx::fround(aOutlineRange.getMaxX()),
     152           0 :             basegfx::fround(aOutlineRange.getMaxY()));
     153           0 :         const Rectangle aDestRectPixel(rOutDev.LogicToPixel(aDestRectLogic));
     154             : 
     155             :         // #i96708# check if Metafile is recorded
     156           0 :         const GDIMetaFile* pMetaFile = rOutDev.GetConnectMetaFile();
     157           0 :         const bool bRecordToMetaFile(pMetaFile && pMetaFile->IsRecord() && !pMetaFile->IsPause());
     158             : 
     159             :         // intersect with output pixel size, but only
     160             :         // when not recording to metafile
     161           0 :         const Rectangle aOutputRectPixel(Point(), rOutDev.GetOutputSizePixel());
     162           0 :         Rectangle aCroppedRectPixel(bRecordToMetaFile ? aDestRectPixel : aDestRectPixel.GetIntersection(aOutputRectPixel));
     163             : 
     164           0 :         if(!aCroppedRectPixel.IsEmpty())
     165             :         {
     166             :             // as maximum for destination, orientate at aOutputRectPixel, but
     167             :             // take a rotation of 45 degrees (sqrt(2)) as maximum expansion into account
     168           0 :             const Size aSourceSizePixel(rBitmapEx.GetSizePixel());
     169             :             const double fMaximumArea(
     170           0 :                 (double)aOutputRectPixel.getWidth() *
     171           0 :                 (double)aOutputRectPixel.getHeight() *
     172           0 :                 1.4142136); // 1.4142136 taken as sqrt(2.0)
     173             : 
     174             :             // test if discrete view size (pixel) maybe too big and limit it
     175           0 :             const double fArea(aCroppedRectPixel.getWidth() * aCroppedRectPixel.getHeight());
     176           0 :             const bool bNeedToReduce(fArea > fMaximumArea);
     177           0 :             double fReduceFactor(1.0);
     178           0 :             const Size aDestSizePixel(aCroppedRectPixel.GetSize());
     179             : 
     180           0 :             if(bNeedToReduce)
     181             :             {
     182           0 :                 fReduceFactor = sqrt(fMaximumArea / fArea);
     183           0 :                 aCroppedRectPixel.setWidth(basegfx::fround(aCroppedRectPixel.getWidth() * fReduceFactor));
     184           0 :                 aCroppedRectPixel.setHeight(basegfx::fround(aCroppedRectPixel.getHeight() * fReduceFactor));
     185             :             }
     186             : 
     187             :             // build transform from pixel in aDestination to pixel in rBitmapEx
     188             :             // from relative in aCroppedRectPixel to relative in aDestRectPixel
     189             :             // No need to take bNeedToReduce into account, TopLeft is unchanged
     190             :             basegfx::B2DHomMatrix aTransform(basegfx::tools::createTranslateB2DHomMatrix(
     191           0 :                 aCroppedRectPixel.Left() - aDestRectPixel.Left(),
     192           0 :                 aCroppedRectPixel.Top() - aDestRectPixel.Top()));
     193             : 
     194             :             // from relative in aDestRectPixel to absolute Logic. Here it
     195             :             // is essential to adapt to reduce factor (if used)
     196           0 :             double fAdaptedDRPWidth((double)aDestRectPixel.getWidth());
     197           0 :             double fAdaptedDRPHeight((double)aDestRectPixel.getHeight());
     198             : 
     199           0 :             if(bNeedToReduce)
     200             :             {
     201           0 :                 fAdaptedDRPWidth *= fReduceFactor;
     202           0 :                 fAdaptedDRPHeight *= fReduceFactor;
     203             :             }
     204             : 
     205             :             aTransform = basegfx::tools::createScaleTranslateB2DHomMatrix(
     206           0 :                 aDestRectLogic.getWidth() / fAdaptedDRPWidth, aDestRectLogic.getHeight() / fAdaptedDRPHeight,
     207           0 :                 aDestRectLogic.Left(), aDestRectLogic.Top())
     208           0 :                 * aTransform;
     209             : 
     210             :             // from absolute in Logic to unified object coordinates (0.0 .. 1.0 in x and y)
     211           0 :             basegfx::B2DHomMatrix aInvBitmapTransform(rTransform);
     212           0 :             aInvBitmapTransform.invert();
     213           0 :             aTransform = aInvBitmapTransform * aTransform;
     214             : 
     215             :             // from unit object coordinates to rBitmapEx pixel coordintes
     216           0 :             aTransform.scale(aSourceSizePixel.getWidth() - 1L, aSourceSizePixel.getHeight() - 1L);
     217             : 
     218             :             // create bitmap using source, destination and linear back-transformation
     219           0 :             BitmapEx aDestination = impTransformBitmapEx(rBitmapEx, aCroppedRectPixel, aTransform);
     220             : 
     221             :             // paint
     222           0 :             if(bNeedToReduce)
     223             :             {
     224             :                 // paint in target size
     225           0 :                 if(bRecordToMetaFile)
     226             :                 {
     227             :                     rOutDev.DrawBitmapEx(
     228           0 :                         rOutDev.PixelToLogic(aCroppedRectPixel.TopLeft()),
     229             :                         rOutDev.PixelToLogic(aDestSizePixel),
     230           0 :                         aDestination);
     231             :                 }
     232             :                 else
     233             :                 {
     234           0 :                     const bool bWasEnabled(rOutDev.IsMapModeEnabled());
     235           0 :                     rOutDev.EnableMapMode(false);
     236             : 
     237             :                     rOutDev.DrawBitmapEx(
     238             :                         aCroppedRectPixel.TopLeft(),
     239             :                         aDestSizePixel,
     240           0 :                         aDestination);
     241             : 
     242           0 :                     rOutDev.EnableMapMode(bWasEnabled);
     243             :                 }
     244             :             }
     245             :             else
     246             :             {
     247           0 :                 if(bRecordToMetaFile)
     248             :                 {
     249             :                     rOutDev.DrawBitmapEx(
     250           0 :                         rOutDev.PixelToLogic(aCroppedRectPixel.TopLeft()),
     251           0 :                         aDestination);
     252             :                 }
     253             :                 else
     254             :                 {
     255           0 :                     const bool bWasEnabled(rOutDev.IsMapModeEnabled());
     256           0 :                     rOutDev.EnableMapMode(false);
     257             : 
     258             :                     rOutDev.DrawBitmapEx(
     259             :                         aCroppedRectPixel.TopLeft(),
     260           0 :                         aDestination);
     261             : 
     262           0 :                     rOutDev.EnableMapMode(bWasEnabled);
     263             :                 }
     264           0 :             }
     265             :         }
     266           0 :     }
     267             : } // end of namespace drawinglayer
     268             : 
     269             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10