LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/drawinglayer/source/primitive2d - graphicprimitivehelper2d.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 20 113 17.7 %
Date: 2013-07-09 Functions: 3 13 23.1 %
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 <drawinglayer/primitive2d/graphicprimitivehelper2d.hxx>
      21             : #include <drawinglayer/animation/animationtiming.hxx>
      22             : #include <drawinglayer/primitive2d/bitmapprimitive2d.hxx>
      23             : #include <drawinglayer/primitive2d/animatedprimitive2d.hxx>
      24             : #include <drawinglayer/primitive2d/metafileprimitive2d.hxx>
      25             : #include <drawinglayer/primitive2d/transformprimitive2d.hxx>
      26             : #include <drawinglayer/primitive2d/maskprimitive2d.hxx>
      27             : #include <basegfx/polygon/b2dpolygon.hxx>
      28             : #include <basegfx/polygon/b2dpolygontools.hxx>
      29             : 
      30             : //////////////////////////////////////////////////////////////////////////////
      31             : // helper class for animated graphics
      32             : 
      33             : #include <vcl/animate.hxx>
      34             : #include <vcl/graph.hxx>
      35             : #include <vcl/virdev.hxx>
      36             : #include <vcl/svapp.hxx>
      37             : #include <vcl/metaact.hxx>
      38             : 
      39             : //////////////////////////////////////////////////////////////////////////////
      40             : // includes for testing MetafilePrimitive2D::create2DDecomposition
      41             : 
      42             : //////////////////////////////////////////////////////////////////////////////
      43             : 
      44             : namespace
      45             : {
      46           0 :     struct animationStep
      47             :     {
      48             :         BitmapEx                                maBitmapEx;
      49             :         sal_uInt32                              mnTime;
      50             :     };
      51             : 
      52           0 :     class animatedBitmapExPreparator
      53             :     {
      54             :         ::Animation                             maAnimation;
      55             :         ::std::vector< animationStep >          maSteps;
      56             : 
      57             :         sal_uInt32 generateStepTime(sal_uInt32 nIndex) const;
      58             : 
      59             :     public:
      60             :         animatedBitmapExPreparator(const Graphic& rGraphic);
      61             : 
      62           0 :         sal_uInt32 count() const { return maSteps.size(); }
      63           0 :         sal_uInt32 loopCount() const { return (sal_uInt32)maAnimation.GetLoopCount(); }
      64           0 :         sal_uInt32 stepTime(sal_uInt32 a) const { return maSteps[a].mnTime; }
      65           0 :         const BitmapEx& stepBitmapEx(sal_uInt32 a) const { return maSteps[a].maBitmapEx; }
      66             :     };
      67             : 
      68           0 :     sal_uInt32 animatedBitmapExPreparator::generateStepTime(sal_uInt32 nIndex) const
      69             :     {
      70           0 :         const AnimationBitmap& rAnimBitmap = maAnimation.Get(sal_uInt16(nIndex));
      71           0 :         sal_uInt32 nWaitTime(rAnimBitmap.nWait * 10);
      72             : 
      73             :         // #115934#
      74             :         // Take care of special value for MultiPage TIFFs. ATM these shall just
      75             :         // show their first page. Later we will offer some switching when object
      76             :         // is selected.
      77           0 :         if(ANIMATION_TIMEOUT_ON_CLICK == rAnimBitmap.nWait)
      78             :         {
      79             :             // ATM the huge value would block the timer, so
      80             :             // use a long time to show first page (whole day)
      81           0 :             nWaitTime = 100 * 60 * 60 * 24;
      82             :         }
      83             : 
      84             :         // Bad trap: There are animated gifs with no set WaitTime (!).
      85             :         // In that case use a default value.
      86           0 :         if(0L == nWaitTime)
      87             :         {
      88           0 :             nWaitTime = 100L;
      89             :         }
      90             : 
      91           0 :         return nWaitTime;
      92             :     }
      93             : 
      94           0 :     animatedBitmapExPreparator::animatedBitmapExPreparator(const Graphic& rGraphic)
      95           0 :     :   maAnimation(rGraphic.GetAnimation())
      96             :     {
      97             :         OSL_ENSURE(GRAPHIC_BITMAP == rGraphic.GetType() && rGraphic.IsAnimated(), "animatedBitmapExPreparator: graphic is not animated (!)");
      98             : 
      99             :         // #128539# secure access to Animation, looks like there exist animated GIFs out there
     100             :         // with a step count of zero
     101           0 :         if(maAnimation.Count())
     102             :         {
     103           0 :             VirtualDevice aVirtualDevice(*Application::GetDefaultDevice());
     104           0 :             VirtualDevice aVirtualDeviceMask(*Application::GetDefaultDevice(), 1L);
     105             : 
     106             :             // Prepare VirtualDevices and their states
     107           0 :             aVirtualDevice.EnableMapMode(sal_False);
     108           0 :             aVirtualDeviceMask.EnableMapMode(sal_False);
     109           0 :             aVirtualDevice.SetOutputSizePixel(maAnimation.GetDisplaySizePixel());
     110           0 :             aVirtualDeviceMask.SetOutputSizePixel(maAnimation.GetDisplaySizePixel());
     111           0 :             aVirtualDevice.Erase();
     112           0 :             aVirtualDeviceMask.Erase();
     113             : 
     114           0 :             for(sal_uInt16 a(0L); a < maAnimation.Count(); a++)
     115             :             {
     116           0 :                 animationStep aNextStep;
     117           0 :                 aNextStep.mnTime = generateStepTime(a);
     118             : 
     119             :                 // prepare step
     120           0 :                 const AnimationBitmap& rAnimBitmap = maAnimation.Get(sal_uInt16(a));
     121             : 
     122           0 :                 switch(rAnimBitmap.eDisposal)
     123             :                 {
     124             :                     case DISPOSE_NOT:
     125             :                     {
     126           0 :                         aVirtualDevice.DrawBitmapEx(rAnimBitmap.aPosPix, rAnimBitmap.aBmpEx);
     127           0 :                         Bitmap aMask = rAnimBitmap.aBmpEx.GetMask();
     128             : 
     129           0 :                         if(aMask.IsEmpty())
     130             :                         {
     131           0 :                             const Point aEmpty;
     132           0 :                             const Rectangle aRect(aEmpty, aVirtualDeviceMask.GetOutputSizePixel());
     133           0 :                             const Wallpaper aWallpaper(COL_BLACK);
     134           0 :                             aVirtualDeviceMask.DrawWallpaper(aRect, aWallpaper);
     135             :                         }
     136             :                         else
     137             :                         {
     138           0 :                             BitmapEx aExpandVisibilityMask = BitmapEx(aMask, aMask);
     139           0 :                             aVirtualDeviceMask.DrawBitmapEx(rAnimBitmap.aPosPix, aExpandVisibilityMask);
     140             :                         }
     141             : 
     142           0 :                         break;
     143             :                     }
     144             :                     case DISPOSE_BACK:
     145             :                     {
     146             :                         // #i70772# react on no mask, for primitives, too.
     147           0 :                         const Bitmap aMask(rAnimBitmap.aBmpEx.GetMask());
     148           0 :                         const Bitmap aContent(rAnimBitmap.aBmpEx.GetBitmap());
     149             : 
     150           0 :                         aVirtualDeviceMask.Erase();
     151           0 :                         aVirtualDevice.DrawBitmap(rAnimBitmap.aPosPix, aContent);
     152             : 
     153           0 :                         if(aMask.IsEmpty())
     154             :                         {
     155           0 :                             const Rectangle aRect(rAnimBitmap.aPosPix, aContent.GetSizePixel());
     156           0 :                             aVirtualDeviceMask.SetFillColor(COL_BLACK);
     157           0 :                             aVirtualDeviceMask.SetLineColor();
     158           0 :                             aVirtualDeviceMask.DrawRect(aRect);
     159             :                         }
     160             :                         else
     161             :                         {
     162           0 :                             aVirtualDeviceMask.DrawBitmap(rAnimBitmap.aPosPix, aMask);
     163             :                         }
     164             : 
     165           0 :                         break;
     166             :                     }
     167             :                     case DISPOSE_FULL:
     168             :                     {
     169           0 :                         aVirtualDevice.DrawBitmapEx(rAnimBitmap.aPosPix, rAnimBitmap.aBmpEx);
     170           0 :                         break;
     171             :                     }
     172             :                     case DISPOSE_PREVIOUS :
     173             :                     {
     174           0 :                         aVirtualDevice.DrawBitmapEx(rAnimBitmap.aPosPix, rAnimBitmap.aBmpEx);
     175           0 :                         aVirtualDeviceMask.DrawBitmap(rAnimBitmap.aPosPix, rAnimBitmap.aBmpEx.GetMask());
     176           0 :                         break;
     177             :                     }
     178             :                 }
     179             : 
     180             :                 // create BitmapEx
     181           0 :                 Bitmap aMainBitmap = aVirtualDevice.GetBitmap(Point(), aVirtualDevice.GetOutputSizePixel());
     182             : #if defined(MACOSX)
     183             :                 AlphaMask aMaskBitmap( aVirtualDeviceMask.GetBitmap( Point(), aVirtualDeviceMask.GetOutputSizePixel()));
     184             : #else
     185           0 :                 Bitmap aMaskBitmap = aVirtualDeviceMask.GetBitmap( Point(), aVirtualDeviceMask.GetOutputSizePixel());
     186             : #endif
     187           0 :                 aNextStep.maBitmapEx = BitmapEx(aMainBitmap, aMaskBitmap);
     188             : 
     189             :                 // add to vector
     190           0 :                 maSteps.push_back(aNextStep);
     191           0 :             }
     192             :         }
     193           0 :     }
     194             : } // end of anonymous namespace
     195             : 
     196             : //////////////////////////////////////////////////////////////////////////////
     197             : 
     198             : namespace drawinglayer
     199             : {
     200             :     namespace primitive2d
     201             :     {
     202          18 :         Primitive2DSequence create2DDecompositionOfGraphic(
     203             :             const Graphic& rGraphic,
     204             :             const basegfx::B2DHomMatrix& rTransform)
     205             :         {
     206          18 :             Primitive2DSequence aRetval;
     207             : 
     208          18 :             switch(rGraphic.GetType())
     209             :             {
     210             :                 case GRAPHIC_BITMAP :
     211             :                 {
     212          14 :                     if(rGraphic.IsAnimated())
     213             :                     {
     214             :                         // prepare animation data
     215           0 :                         animatedBitmapExPreparator aData(rGraphic);
     216             : 
     217           0 :                         if(aData.count())
     218             :                         {
     219             :                             // create sub-primitives for animated bitmap and the needed animation loop
     220           0 :                             animation::AnimationEntryLoop aAnimationLoop(aData.loopCount() ? aData.loopCount() : 0xffff);
     221           0 :                             Primitive2DSequence aBitmapPrimitives(aData.count());
     222             : 
     223           0 :                             for(sal_uInt32 a(0); a < aData.count(); a++)
     224             :                             {
     225           0 :                                 animation::AnimationEntryFixed aTime((double)aData.stepTime(a), (double)a / (double)aData.count());
     226           0 :                                 aAnimationLoop.append(aTime);
     227           0 :                                 aBitmapPrimitives[a] = new BitmapPrimitive2D(
     228             :                                     aData.stepBitmapEx(a),
     229           0 :                                     rTransform);
     230           0 :                             }
     231             : 
     232             :                             // prepare animation list
     233           0 :                             animation::AnimationEntryList aAnimationList;
     234           0 :                             aAnimationList.append(aAnimationLoop);
     235             : 
     236             :                             // create and add animated switch primitive
     237           0 :                             aRetval.realloc(1);
     238           0 :                             aRetval[0] = new AnimatedSwitchPrimitive2D(
     239             :                                 aAnimationList,
     240             :                                 aBitmapPrimitives,
     241           0 :                                 false);
     242           0 :                         }
     243             :                     }
     244          14 :                     else if(rGraphic.getSvgData().get())
     245             :                     {
     246             :                         // embedded Svg fill, create embed transform
     247           0 :                         const basegfx::B2DRange& rSvgRange(rGraphic.getSvgData()->getRange());
     248             : 
     249           0 :                         if(basegfx::fTools::more(rSvgRange.getWidth(), 0.0) && basegfx::fTools::more(rSvgRange.getHeight(), 0.0))
     250             :                         {
     251             :                             // translate back to origin, scale to unit coordinates
     252             :                             basegfx::B2DHomMatrix aEmbedSvg(
     253             :                                 basegfx::tools::createTranslateB2DHomMatrix(
     254           0 :                                     -rSvgRange.getMinX(),
     255           0 :                                     -rSvgRange.getMinY()));
     256             : 
     257             :                             aEmbedSvg.scale(
     258           0 :                                 1.0 / rSvgRange.getWidth(),
     259           0 :                                 1.0 / rSvgRange.getHeight());
     260             : 
     261             :                             // apply created object transformation
     262           0 :                             aEmbedSvg = rTransform * aEmbedSvg;
     263             : 
     264             :                             // add Svg primitives embedded
     265           0 :                             aRetval.realloc(1);
     266           0 :                             aRetval[0] = new TransformPrimitive2D(
     267             :                                 aEmbedSvg,
     268           0 :                                 rGraphic.getSvgData()->getPrimitive2DSequence());
     269             :                         }
     270             :                     }
     271             :                     else
     272             :                     {
     273          14 :                         aRetval.realloc(1);
     274          42 :                         aRetval[0] = new BitmapPrimitive2D(
     275             :                             rGraphic.GetBitmapEx(),
     276          28 :                             rTransform);
     277             :                     }
     278             : 
     279          14 :                     break;
     280             :                 }
     281             : 
     282             :                 case GRAPHIC_GDIMETAFILE :
     283             :                 {
     284             :                     // create MetafilePrimitive2D
     285           4 :                     const GDIMetaFile& rMetafile = rGraphic.GetGDIMetaFile();
     286             : 
     287           4 :                     aRetval.realloc(1);
     288           8 :                     aRetval[0] = new MetafilePrimitive2D(
     289             :                         rTransform,
     290           8 :                         rMetafile);
     291             : 
     292             :                     // #i100357# find out if clipping is needed for this primitive. Unfortunately,
     293             :                     // there exist Metafiles who's content is bigger than the proposed PrefSize set
     294             :                     // at them. This is an error, but we need to work around this
     295           4 :                     const Size aMetaFilePrefSize(rMetafile.GetPrefSize());
     296             :                     const Size aMetaFileRealSize(
     297             :                         const_cast< GDIMetaFile& >(rMetafile).GetBoundRect(
     298           4 :                             *Application::GetDefaultDevice()).GetSize());
     299             : 
     300           8 :                     if(aMetaFileRealSize.getWidth() > aMetaFilePrefSize.getWidth()
     301           4 :                         || aMetaFileRealSize.getHeight() > aMetaFilePrefSize.getHeight())
     302             :                     {
     303             :                         // clipping needed. Embed to MaskPrimitive2D. Create childs and mask polygon
     304           0 :                         basegfx::B2DPolygon aMaskPolygon(basegfx::tools::createUnitPolygon());
     305           0 :                         aMaskPolygon.transform(rTransform);
     306             : 
     307           0 :                         aRetval[0] = new MaskPrimitive2D(
     308             :                             basegfx::B2DPolyPolygon(aMaskPolygon),
     309           0 :                             aRetval);
     310             :                     }
     311           4 :                     break;
     312             :                 }
     313             : 
     314             :                 default:
     315             :                 {
     316             :                     // nothing to create
     317           0 :                     break;
     318             :                 }
     319             :             }
     320             : 
     321          18 :             return aRetval;
     322             :         }
     323             :     } // end of namespace primitive2d
     324         408 : } // end of namespace drawinglayer
     325             : 
     326             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10