LCOV - code coverage report
Current view: top level - vcl/workben - vcldemo.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 0 824 0.0 %
Date: 2015-06-13 12:38:46 Functions: 0 148 0.0 %
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             : 
      10             : #include <math.h>
      11             : #include <rtl/math.hxx>
      12             : 
      13             : #include <comphelper/processfactory.hxx>
      14             : #include <comphelper/random.hxx>
      15             : #include <cppuhelper/bootstrap.hxx>
      16             : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
      17             : #include <com/sun/star/lang/XInitialization.hpp>
      18             : #include <com/sun/star/registry/XSimpleRegistry.hpp>
      19             : #include <com/sun/star/ucb/UniversalContentBroker.hpp>
      20             : 
      21             : #include <osl/time.h>
      22             : #include <vcl/vclmain.hxx>
      23             : #include <vcl/layout.hxx>
      24             : #include <salhelper/thread.hxx>
      25             : 
      26             : #include <tools/urlobj.hxx>
      27             : #include <tools/stream.hxx>
      28             : #include <vcl/svapp.hxx>
      29             : #include <vcl/pngread.hxx>
      30             : #include <vcl/wrkwin.hxx>
      31             : #include <vcl/virdev.hxx>
      32             : #include <vcl/graphicfilter.hxx>
      33             : #include <vcl/button.hxx>
      34             : #include <vcl/toolbox.hxx>
      35             : #include <vcl/pngwrite.hxx>
      36             : #include <vcl/floatwin.hxx>
      37             : #include <vcl/salbtype.hxx>
      38             : #include <vcl/bmpacc.hxx>
      39             : #include <vcl/help.hxx>
      40             : 
      41             : #include <basegfx/numeric/ftools.hxx>
      42             : #include <basegfx/matrix/b2dhommatrix.hxx>
      43             : #include <vcldemo-debug.hxx>
      44             : 
      45             : #include <rtl/math.hxx>
      46             : 
      47             : #define FIXME_SELF_INTERSECTING_WORKING 0
      48             : #define FIXME_BOUNCE_BUTTON 0
      49             : #define THUMB_REPEAT_FACTOR 10
      50             : 
      51             : using namespace com::sun::star;
      52             : 
      53             : namespace {
      54           0 :     double getTimeNow()
      55             :     {
      56             :         TimeValue aValue;
      57           0 :         osl_getSystemTime(&aValue);
      58           0 :         return (double)aValue.Seconds * 1000 +
      59           0 :             (double)aValue.Nanosec / (1000*1000);
      60             :     }
      61             : 
      62             : }
      63             : 
      64             : using namespace css;
      65             : 
      66             : enum RenderStyle {
      67             :     RENDER_THUMB,    // small view <n> to a page
      68             :     RENDER_EXPANDED, // expanded view of this renderer
      69             : };
      70             : 
      71           0 : class DemoRenderer
      72             : {
      73             :     Bitmap   maIntroBW;
      74             :     BitmapEx maIntro;
      75             : 
      76             :     int mnSegmentsX;
      77             :     int mnSegmentsY;
      78             : 
      79           0 :     struct RenderContext {
      80             :         RenderStyle   meStyle;
      81             :         bool          mbVDev;
      82             :         DemoRenderer *mpDemoRenderer;
      83             :         Size          maSize;
      84             :     };
      85             :     struct RegionRenderer {
      86             :     public:
      87           0 :         RegionRenderer() :
      88             :             sumTime(0),
      89           0 :             countTime(0)
      90           0 :         { }
      91           0 :         virtual ~RegionRenderer() {}
      92             :         virtual OUString getName() = 0;
      93             :         virtual sal_uInt16 getAccelerator() = 0;
      94             :         virtual void RenderRegion(OutputDevice &rDev, Rectangle r,
      95             :                                   const RenderContext &rCtx) = 0;
      96             :         // repeating count for profiling (to exceed the poor time resolution on Windows)
      97             :         virtual sal_uInt16 getTestRepeatCount() = 0;
      98             : #define RENDER_DETAILS(name,key,repeat) \
      99             :         virtual OUString getName() SAL_OVERRIDE \
     100             :             { return OUString(SAL_STRINGIFY(name)); } \
     101             :         virtual sal_uInt16 getAccelerator() SAL_OVERRIDE \
     102             :             { return key; } \
     103             :         virtual sal_uInt16 getTestRepeatCount() SAL_OVERRIDE \
     104             :             { return repeat; }
     105             : 
     106             :         double sumTime;
     107             :         int countTime;
     108             :     };
     109             : 
     110             :     std::vector< RegionRenderer * > maRenderers;
     111             :     sal_Int32  mnSelectedRenderer;
     112             :     sal_Int32  iterCount;
     113             : 
     114             :     void     InitRenderers();
     115             : 
     116             : public:
     117           0 :     DemoRenderer() : mnSegmentsX(0)
     118             :                    , mnSegmentsY(0)
     119             :                    , mnSelectedRenderer(-1)
     120           0 :                    , iterCount(0)
     121             : #if FIXME_BOUNCE_BUTTON
     122             :                    , mpButton(NULL)
     123             :                    , mpButtonWin(NULL)
     124             :                    , mnBounceX(1)
     125             :                    , mnBounceY(1)
     126             : #endif
     127             :     {
     128           0 :         if (!Application::LoadBrandBitmap("intro", maIntro))
     129           0 :             Application::Abort("Failed to load intro image");
     130             : 
     131           0 :         maIntroBW = maIntro.GetBitmap();
     132           0 :         maIntroBW.Filter(BMP_FILTER_EMBOSS_GREY);
     133             : 
     134           0 :         InitRenderers();
     135           0 :         mnSegmentsX = rtl::math::round(sqrt(maRenderers.size()), 0,
     136           0 :                                        rtl_math_RoundingMode_Up);
     137           0 :         mnSegmentsY = rtl::math::round(sqrt(maRenderers.size()), 0,
     138           0 :                                        rtl_math_RoundingMode_Down);
     139           0 :         mnSegmentsY = floor(sqrt(maRenderers.size()));
     140           0 :     }
     141             : 
     142             :     OUString getRendererList();
     143             :     double   getAndResetBenchmark(RenderStyle style);
     144             :     void     selectRenderer(const OUString &rName);
     145             :     int      selectNextRenderer();
     146             :     void     setIterCount(sal_Int32 iterCount);
     147             :     sal_Int32 getIterCount();
     148             :     void     addTime(int i, double t);
     149             : 
     150             :     Size maSize;
     151           0 :     void SetSizePixel(const Size &rSize) { maSize = rSize; }
     152           0 :     Size GetSizePixel() const            { return maSize;  }
     153             : 
     154             : 
     155             : // more of a 'Window' concept - push upwards ?
     156             : #if FIXME_BOUNCE_BUTTON
     157             :     // Bouncing windows on click ...
     158             :     PushButton     *mpButton;
     159             :     FloatingWindow *mpButtonWin;
     160             :     AutoTimer       maBounce;
     161             :     int             mnBounceX, mnBounceY;
     162             :     DECL_LINK(BounceTimerCb, void *);
     163             : #endif
     164             : 
     165             :     bool MouseButtonDown(const MouseEvent& rMEvt);
     166             :     void KeyInput(const KeyEvent& rKEvt);
     167             : 
     168           0 :     static std::vector<Rectangle> partition(const RenderContext &rCtx, int nX, int nY)
     169             :     {
     170           0 :         return partition(rCtx.maSize, nX, nY);
     171             :     }
     172             : 
     173           0 :     static std::vector<Rectangle> partition(Size aSize, int nX, int nY)
     174             :     {
     175           0 :         Rectangle r;
     176           0 :         std::vector<Rectangle> aRegions;
     177             : 
     178             :         // Make small cleared area for these guys
     179           0 :         long nBorderSize = aSize.Width() / 32;
     180           0 :         long nBoxWidth = (aSize.Width() - nBorderSize*(nX+1)) / nX;
     181           0 :         long nBoxHeight = (aSize.Height() - nBorderSize*(nY+1)) / nY;
     182           0 :         for (int y = 0; y < nY; y++)
     183             :         {
     184           0 :             for (int x = 0; x < nX; x++)
     185             :             {
     186           0 :                 r.SetPos(Point(nBorderSize + (nBorderSize + nBoxWidth) * x,
     187           0 :                                nBorderSize + (nBorderSize + nBoxHeight) * y));
     188           0 :                 r.SetSize(Size(nBoxWidth, nBoxHeight));
     189           0 :                 aRegions.push_back(r);
     190             :             }
     191             :         }
     192             : 
     193           0 :         return aRegions;
     194             :     }
     195             : 
     196           0 :     static void clearRects(OutputDevice &rDev, std::vector<Rectangle> &rRects)
     197             :     {
     198           0 :         for (size_t i = 0; i < rRects.size(); i++)
     199             :         {
     200             :             // knock up a nice little border
     201           0 :             rDev.SetLineColor(COL_GRAY);
     202           0 :             rDev.SetFillColor(COL_LIGHTGRAY);
     203           0 :             if (i % 2)
     204             :             {
     205           0 :                 int nBorderSize = rRects[i].GetWidth() / 5;
     206           0 :                 rDev.DrawRect(rRects[i], nBorderSize, nBorderSize);
     207             :             }
     208             :             else
     209           0 :                 rDev.DrawRect(rRects[i]);
     210             :         }
     211           0 :     }
     212             : 
     213           0 :     static void drawBackground(OutputDevice &rDev, const Rectangle& r)
     214             :     {
     215           0 :         rDev.Erase();
     216           0 :         Gradient aGradient;
     217           0 :         aGradient.SetStartColor(COL_BLUE);
     218           0 :         aGradient.SetEndColor(COL_GREEN);
     219           0 :         aGradient.SetStyle(GradientStyle_LINEAR);
     220           0 :         rDev.DrawGradient(r, aGradient);
     221           0 :     }
     222             : 
     223           0 :     struct DrawLines : public RegionRenderer
     224             :     {
     225           0 :         RENDER_DETAILS(lines,KEY_L,100)
     226           0 :         virtual void RenderRegion(OutputDevice &rDev, Rectangle r,
     227             :                                   const RenderContext &rCtx) SAL_OVERRIDE
     228             :         {
     229           0 :             if (rCtx.meStyle == RENDER_EXPANDED)
     230             :             {
     231           0 :                 AntialiasingFlags nOldAA = rDev.GetAntialiasing();
     232           0 :                 rDev.SetAntialiasing(AntialiasingFlags::EnableB2dDraw);
     233             : 
     234           0 :                 std::vector<Rectangle> aRegions(DemoRenderer::partition(rCtx, 4, 4));
     235           0 :                 DemoRenderer::clearRects(rDev, aRegions);
     236             : 
     237             : #if 0 // FIXME: get this through to the backend ...
     238             :                 double nTransparency[] = {
     239             :                     1.0, 1.0, 1.0, 1.0,
     240             :                     0.8, 0.8, 0.8, 0.8,
     241             :                     0.5, 0.5, 0.5, 0.5,
     242             :                     0.1, 0.1, 0.1, 0.1
     243             :                 };
     244             : #endif
     245             :                 drawing::LineCap eLineCaps[] = {
     246             :                     drawing::LineCap_BUTT, drawing::LineCap_ROUND, drawing::LineCap_SQUARE, drawing::LineCap_BUTT,
     247             :                     drawing::LineCap_BUTT, drawing::LineCap_ROUND, drawing::LineCap_SQUARE, drawing::LineCap_BUTT,
     248             :                     drawing::LineCap_BUTT, drawing::LineCap_ROUND, drawing::LineCap_SQUARE, drawing::LineCap_BUTT,
     249             :                     drawing::LineCap_BUTT, drawing::LineCap_ROUND, drawing::LineCap_SQUARE, drawing::LineCap_BUTT
     250           0 :                 };
     251             :                 ::basegfx::B2DLineJoin eJoins[] = {
     252             :                     basegfx::B2DLineJoin::NONE,  basegfx::B2DLineJoin::Middle, basegfx::B2DLineJoin::Bevel,  basegfx::B2DLineJoin::Miter,
     253             :                     basegfx::B2DLineJoin::Round, basegfx::B2DLineJoin::NONE,   basegfx::B2DLineJoin::Middle, basegfx::B2DLineJoin::Bevel,
     254             :                     basegfx::B2DLineJoin::Miter, basegfx::B2DLineJoin::Round,  basegfx::B2DLineJoin::NONE,   basegfx::B2DLineJoin::Middle,
     255             :                     basegfx::B2DLineJoin::Bevel, basegfx::B2DLineJoin::Miter,  basegfx::B2DLineJoin::Round,  basegfx::B2DLineJoin::NONE
     256           0 :                 };
     257             :                 double aLineWidths[] = {
     258             :                     10.0, 15.0, 20.0, 10.0,
     259             :                     10.0, 15.0, 20.0, 10.0,
     260             :                     10.0, 15.0, 20.0, 10.0,
     261             :                      0.1,  1.0, 10.0, 50.0
     262           0 :                 };
     263           0 :                 for (size_t i = 0; i < aRegions.size(); i++)
     264             :                 {
     265             :                     // Half of them not-anti-aliased ..
     266           0 :                     if (i >= aRegions.size()/2)
     267           0 :                         rDev.SetAntialiasing(nOldAA);
     268             : 
     269             :                     static const struct {
     270             :                         double nX, nY;
     271             :                     } aPoints[] = {
     272             :                         { 0.2, 0.2 }, { 0.8, 0.3 }, { 0.7, 0.8 }
     273             :                     };
     274           0 :                     rDev.SetLineColor(Color(COL_BLACK));
     275           0 :                     basegfx::B2DPolygon aPoly;
     276           0 :                     Rectangle aSub(aRegions[i]);
     277           0 :                     for (size_t j = 0; j < SAL_N_ELEMENTS(aPoints); j++)
     278             :                     {
     279           0 :                         aPoly.append(basegfx::B2DPoint(aSub.Left() + aSub.GetWidth() * aPoints[j].nX,
     280           0 :                                                        aSub.Top()  + aSub.GetHeight() * aPoints[j].nY));
     281             :                     }
     282           0 :                     rDev.DrawPolyLine(aPoly, aLineWidths[i], eJoins[i], eLineCaps[i]);
     283           0 :                 }
     284             :             }
     285             :             else
     286             :             {
     287           0 :                 rDev.SetFillColor(Color(COL_LIGHTRED));
     288           0 :                 rDev.SetLineColor(Color(COL_BLACK));
     289           0 :                 rDev.DrawRect(r);
     290             : 
     291           0 :                 for(long i=0; i<r.GetHeight(); i+=15)
     292           0 :                     rDev.DrawLine(Point(r.Left(), r.Top()+i), Point(r.Right(), r.Bottom()-i));
     293           0 :                 for(long i=0; i<r.GetWidth(); i+=15)
     294           0 :                     rDev.DrawLine(Point(r.Left()+i, r.Bottom()), Point(r.Right()-i, r.Top()));
     295             : 
     296             :                 // Should draw a white-line across the middle
     297           0 :                 Color aLastPixel(COL_WHITE);
     298           0 :                 Point aCenter((r.Left() + r.Right())/2 - 4,
     299           0 :                               (r.Top() + r.Bottom())/2 - 4);
     300           0 :                 for(int i=0; i<8; i++)
     301             :                 {
     302           0 :                     rDev.DrawPixel(aCenter, aLastPixel);
     303           0 :                     aLastPixel = rDev.GetPixel(aCenter);
     304           0 :                     aCenter.Move(1,1);
     305             :                 }
     306             :             }
     307           0 :         }
     308             :     };
     309             : 
     310           0 :     struct DrawText : public RegionRenderer
     311             :     {
     312           0 :         RENDER_DETAILS(text,KEY_T,1)
     313             : 
     314           0 :         virtual void RenderRegion(OutputDevice &rDev, Rectangle r,
     315             :                                   const RenderContext &rCtx) SAL_OVERRIDE
     316             :         {
     317           0 :             if (rCtx.meStyle == RENDER_EXPANDED)
     318             :             {
     319           0 :                 std::vector<Rectangle> aRegions(DemoRenderer::partition(rCtx, 4, 2));
     320           0 :                 DemoRenderer::clearRects(rDev, aRegions);
     321             : 
     322           0 :                 bool bClip=true, bArabicText=true, bRotate=true;
     323             : 
     324           0 :                 int nRegions=0;
     325             : 
     326           0 :                 for (int nClipRow=0; nClipRow < 2; nClipRow++)
     327             :                 {
     328           0 :                     if (!bArabicText)
     329           0 :                         bArabicText=true;
     330             : 
     331           0 :                     for (int nArabicRow=0; nArabicRow < 2; nArabicRow++)
     332             :                     {
     333           0 :                         if (!bRotate)
     334           0 :                             bRotate=true;
     335             : 
     336           0 :                         for (int nRotateRow=0; nRotateRow < 2; nRotateRow++)
     337             :                         {
     338           0 :                             drawText( rDev, aRegions[nRegions], bClip, bArabicText, bRotate );
     339             : 
     340           0 :                             nRegions++;
     341           0 :                             bRotate=false;
     342             :                         }
     343             : 
     344           0 :                         bArabicText=false;
     345             :                     }
     346             : 
     347           0 :                     bClip=false;
     348           0 :                 }
     349             :             }
     350             :             else
     351             :             {
     352           0 :                 drawText(rDev, r, false, false, false);
     353             :             }
     354           0 :         }
     355             : 
     356           0 :         static void drawText (OutputDevice &rDev, Rectangle r, bool bClip, bool bArabicText, bool bRotate)
     357             :         {
     358           0 :             rDev.SetClipRegion( vcl::Region(r) );
     359             : 
     360           0 :             OUString aLatinText("Click any rect to zoom!!!!");
     361             : 
     362             :             const unsigned char pTextUTF8[] = {
     363             :                 0xd9, 0x88, 0xd8, 0xa7, 0xd8, 0xad, 0xd9, 0x90,
     364             :                 0xd8, 0xaf, 0xd9, 0x92, 0x20, 0xd8, 0xa5, 0xd8,
     365             :                 0xab, 0xd9, 0x8d, 0xd9, 0x86, 0xd9, 0x8a, 0xd9,
     366             :                 0x86, 0x20, 0xd8, 0xab, 0xd9, 0x84, 0xd8, 0xa7,
     367             :                 0xd8, 0xab, 0xd8, 0xa9, 0xd9, 0x8c, 0x00
     368           0 :             };
     369             :             OUString aArabicText( reinterpret_cast<char const *>(pTextUTF8),
     370             :                             SAL_N_ELEMENTS( pTextUTF8 ) - 1,
     371           0 :                             RTL_TEXTENCODING_UTF8 );
     372             : 
     373           0 :             OUString aText;
     374             : 
     375             :             // To have more text displayed one after the other (overlapping, and in different colours), then
     376             :             // change this value
     377           0 :             const int nPrintNumCopies=1;
     378             : 
     379           0 :             if (bArabicText)
     380           0 :                 aText = aArabicText;
     381             :             else
     382           0 :                 aText = aLatinText;
     383             : 
     384           0 :             std::vector<OUString> maFontNames;
     385             : 
     386             :             sal_uInt32 nCols[] = {
     387             :                 COL_BLACK, COL_BLUE, COL_GREEN, COL_CYAN, COL_RED, COL_MAGENTA,
     388             :                 COL_BROWN, COL_GRAY, COL_LIGHTGRAY, COL_LIGHTBLUE, COL_LIGHTGREEN,
     389             :                 COL_LIGHTCYAN, COL_LIGHTRED, COL_LIGHTMAGENTA, COL_YELLOW, COL_WHITE
     390           0 :             };
     391             : 
     392             :             // a few fonts to start with
     393             :             const char *pNames[] = {
     394             :                 "Times", "Liberation Sans", "Arial", "Linux Biolinum G", "Linux Libertine Display G"
     395           0 :               };
     396             : 
     397           0 :             size_t nNumFontNames = SAL_N_ELEMENTS(pNames);
     398             : 
     399           0 :             for (size_t i = 0; i < nNumFontNames; i++)
     400           0 :                 maFontNames.push_back(OUString::createFromAscii(pNames[i]));
     401             : 
     402           0 :             if (bClip && !bRotate)
     403             :             {
     404             :                 // only show the first quarter of the text
     405           0 :                 Rectangle aRect( r.TopLeft(), Size( r.GetWidth()/2, r.GetHeight()/2 ) );
     406           0 :                 rDev.SetClipRegion( vcl::Region( aRect ) );
     407             :             }
     408             : 
     409           0 :             for (int i = 1; i < nPrintNumCopies+1; i++)
     410             :             {
     411           0 :                 int nFontHeight=0, nFontIndex=0, nFontColorIndex=0;
     412             : 
     413             :                 if (nPrintNumCopies == 1)
     414             :                 {
     415           0 :                     float nFontMagnitude = 0.25f;
     416             :                     // random font size to avoid buffering
     417           0 :                     nFontHeight = 1 + nFontMagnitude * (0.9 + comphelper::rng::uniform_real_distribution(0.0, std::nextafter(0.1, DBL_MAX))) * (r.Bottom() - r.Top());
     418           0 :                     nFontIndex=0;
     419           0 :                     nFontColorIndex=0;
     420             :                 }
     421             :                 else
     422             :                 {
     423             :                     // random font size to avoid buffering
     424             :                     nFontHeight = 1 + i * (0.9 + comphelper::rng::uniform_real_distribution(0.0, std::nextafter(0.1, DBL_MAX))) * (r.Top() - r.Bottom()) / nPrintNumCopies;
     425             :                     nFontIndex = (i % maFontNames.size());
     426             :                     nFontColorIndex=(i % maFontNames.size());
     427             :                 }
     428             : 
     429           0 :                 rDev.SetTextColor(Color(nCols[nFontColorIndex]));
     430           0 :                 vcl::Font aFont( maFontNames[nFontIndex], Size(0, nFontHeight ));
     431             : 
     432           0 :                 if (bRotate)
     433             :                 {
     434           0 :                     Rectangle aFontRect = r;
     435             : 
     436           0 :                     int nHeight = r.GetHeight();
     437             : 
     438             :                     // move the text to the bottom of the bounding rect before rotating
     439           0 :                     aFontRect.Top() += nHeight;
     440           0 :                     aFontRect.Bottom() += nHeight;
     441             : 
     442           0 :                     int nDegrees = 45;
     443             : 
     444           0 :                     aFont.SetOrientation(nDegrees * 10);
     445             : 
     446           0 :                     rDev.SetFont(aFont);
     447           0 :                     rDev.DrawText(aFontRect, aText);
     448             : 
     449           0 :                     if (bClip)
     450             :                     {
     451           0 :                         Rectangle aClipRect( Point( r.Left(), r.Top() + ( r.GetHeight()/2 ) ) , Size( r.GetWidth()/2, r.GetHeight()/2 ) );
     452           0 :                         rDev.SetClipRegion( vcl::Region( aClipRect ) );
     453             :                     }
     454             :                     else
     455           0 :                         rDev.SetClipRegion( vcl::Region(r) );
     456             :                 }
     457             :                 else
     458             :                 {
     459           0 :                     rDev.SetFont(aFont);
     460           0 :                     rDev.DrawText(r, aText);
     461             :                 }
     462           0 :             }
     463             : 
     464           0 :             rDev.SetClipRegion();
     465           0 :         }
     466             :     };
     467             : 
     468           0 :     struct DrawCheckered : public RegionRenderer
     469             :     {
     470           0 :         RENDER_DETAILS(checks,KEY_C,20)
     471           0 :         virtual void RenderRegion(OutputDevice &rDev, Rectangle r,
     472             :                                   const RenderContext &rCtx) SAL_OVERRIDE
     473             :         {
     474           0 :             if (rCtx.meStyle == RENDER_EXPANDED)
     475             :             {
     476           0 :                 std::vector<Rectangle> aRegions(DemoRenderer::partition(rCtx, 2, 2));
     477           0 :                 for (size_t i = 0; i < aRegions.size(); i++)
     478             :                 {
     479           0 :                     vcl::Region aRegion;
     480           0 :                     Rectangle aSub(aRegions[i]);
     481           0 :                     Rectangle aSmaller(aSub);
     482           0 :                     aSmaller.Move(10,10);
     483           0 :                     aSmaller.setWidth(aSmaller.getWidth()-20);
     484           0 :                     aSmaller.setHeight(aSmaller.getHeight()-24);
     485           0 :                     switch (i) {
     486             :                     case 0:
     487           0 :                         aRegion = vcl::Region(aSub);
     488           0 :                         break;
     489             :                     case 1:
     490           0 :                         aRegion = vcl::Region(aSmaller);
     491           0 :                         aRegion.XOr(aSub);
     492           0 :                         break;
     493             :                     case 2:
     494             :                     {
     495           0 :                         Polygon aPoly(aSub);
     496           0 :                         aPoly.Rotate(aSub.Center(), 450);
     497           0 :                         aPoly.Clip(aSmaller);
     498           0 :                         aRegion = vcl::Region(aPoly);
     499           0 :                         break;
     500             :                     }
     501             :                     case 3:
     502             :                     {
     503           0 :                         tools::PolyPolygon aPolyPoly;
     504           0 :                         sal_Int32 nTW = aSub.GetWidth()/6;
     505           0 :                         sal_Int32 nTH = aSub.GetHeight()/6;
     506           0 :                         Rectangle aTiny(Point(4, 4), Size(nTW*2, nTH*2));
     507           0 :                         aPolyPoly.Insert(Polygon(aTiny));
     508           0 :                         aTiny.Move(nTW*3, nTH*3);
     509           0 :                         aPolyPoly.Insert(Polygon(aTiny));
     510           0 :                         aTiny.Move(nTW, nTH);
     511           0 :                         aPolyPoly.Insert(Polygon(aTiny));
     512             : 
     513           0 :                         aRegion = vcl::Region(aPolyPoly);
     514           0 :                         break;
     515             :                     }
     516             :                     } // switch
     517           0 :                     rDev.SetClipRegion(aRegion);
     518           0 :                     rDev.DrawCheckered(aSub.TopLeft(), aSub.GetSize());
     519           0 :                     rDev.SetClipRegion();
     520           0 :                 }
     521             :             }
     522             :             else
     523             :             {
     524           0 :                 rDev.DrawCheckered(r.TopLeft(), r.GetSize());
     525             :             }
     526           0 :         }
     527             :     };
     528             : 
     529           0 :     struct DrawPoly : public RegionRenderer
     530             :     {
     531           0 :         RENDER_DETAILS(poly,KEY_P,20)
     532             :         DrawCheckered maCheckered;
     533           0 :         virtual void RenderRegion(OutputDevice &rDev, Rectangle r,
     534             :                                   const RenderContext &rCtx) SAL_OVERRIDE
     535             :         {
     536           0 :             maCheckered.RenderRegion(rDev, r, rCtx);
     537             : 
     538           0 :             long nDx = r.GetWidth()/20;
     539           0 :             long nDy = r.GetHeight()/20;
     540           0 :             Rectangle aShrunk(r);
     541           0 :             aShrunk.Move(nDx, nDy);
     542           0 :             aShrunk.SetSize(Size(r.GetWidth()-nDx*2,
     543           0 :                                  r.GetHeight()-nDy*2));
     544           0 :             Polygon aPoly(aShrunk);
     545           0 :             tools::PolyPolygon aPPoly(aPoly);
     546           0 :             rDev.SetLineColor(Color(COL_RED));
     547           0 :             rDev.SetFillColor(Color(COL_RED));
     548             :             // This hits the optional 'drawPolyPolygon' code-path
     549           0 :             rDev.DrawTransparent(aPPoly, 64);
     550           0 :         }
     551             :     };
     552             : 
     553           0 :     struct DrawEllipse : public RegionRenderer
     554             :     {
     555           0 :         RENDER_DETAILS(ellipse,KEY_E,5000)
     556           0 :         virtual void RenderRegion(OutputDevice &rDev, Rectangle r,
     557             :                                   const RenderContext &) SAL_OVERRIDE
     558             :         {
     559           0 :             rDev.SetLineColor(Color(COL_RED));
     560           0 :             rDev.SetFillColor(Color(COL_GREEN));
     561           0 :             rDev.DrawEllipse(r);
     562           0 :         }
     563             :     };
     564             : 
     565           0 :     struct DrawGradient : public RegionRenderer
     566             :     {
     567           0 :         RENDER_DETAILS(gradient,KEY_G,50)
     568           0 :         virtual void RenderRegion(OutputDevice &rDev, Rectangle r,
     569             :                                   const RenderContext &rCtx) SAL_OVERRIDE
     570             :         {
     571           0 :             if (rCtx.meStyle == RENDER_EXPANDED)
     572             :             {
     573           0 :                 std::vector<Rectangle> aRegions(DemoRenderer::partition(rCtx,5, 4));
     574             :                 sal_uInt32 nStartCols[] = {
     575             :                     COL_RED, COL_RED, COL_RED, COL_GREEN, COL_GREEN,
     576             :                     COL_BLUE, COL_BLUE, COL_BLUE, COL_CYAN, COL_CYAN,
     577             :                     COL_BLACK, COL_LIGHTGRAY, COL_WHITE, COL_BLUE, COL_CYAN,
     578             :                     COL_WHITE, COL_WHITE, COL_WHITE, COL_BLACK, COL_BLACK
     579           0 :                 };
     580             :                 sal_uInt32 nEndCols[] = {
     581             :                     COL_WHITE, COL_WHITE, COL_WHITE, COL_BLACK, COL_BLACK,
     582             :                     COL_RED, COL_RED, COL_RED, COL_GREEN, COL_GREEN,
     583             :                     COL_GRAY, COL_GRAY, COL_LIGHTGRAY, COL_LIGHTBLUE, COL_LIGHTCYAN,
     584             :                     COL_BLUE, COL_BLUE, COL_BLUE, COL_CYAN, COL_CYAN
     585           0 :                 };
     586             :                 GradientStyle eStyles[] = {
     587             :                     GradientStyle_LINEAR, GradientStyle_AXIAL, GradientStyle_RADIAL, GradientStyle_ELLIPTICAL, GradientStyle_SQUARE,
     588             :                     GradientStyle_RECT, GradientStyle_FORCE_EQUAL_SIZE, GradientStyle_LINEAR, GradientStyle_RADIAL, GradientStyle_LINEAR,
     589             :                     GradientStyle_LINEAR, GradientStyle_AXIAL, GradientStyle_RADIAL, GradientStyle_ELLIPTICAL, GradientStyle_SQUARE,
     590             :                     GradientStyle_RECT, GradientStyle_FORCE_EQUAL_SIZE, GradientStyle_LINEAR, GradientStyle_RADIAL, GradientStyle_LINEAR
     591           0 :                 };
     592             :                 sal_uInt16 nAngles[] = {
     593             :                     0, 0, 0, 0, 0,
     594             :                     15, 30, 45, 60, 75,
     595             :                     90, 120, 135, 160, 180,
     596             :                     0, 0, 0, 0, 0
     597           0 :                 };
     598             :                 sal_uInt16 nBorders[] = {
     599             :                     0, 0, 0, 0, 0,
     600             :                     1, 10, 100, 10, 1,
     601             :                     0, 0, 0, 0, 0,
     602             :                     1, 10, 20, 10, 1,
     603             :                     0, 0, 0, 0, 0
     604           0 :                 };
     605           0 :                 DemoRenderer::clearRects(rDev, aRegions);
     606             :                 assert(aRegions.size() <= SAL_N_ELEMENTS(nStartCols));
     607             :                 assert(aRegions.size() <= SAL_N_ELEMENTS(nEndCols));
     608             :                 assert(aRegions.size() <= SAL_N_ELEMENTS(eStyles));
     609             :                 assert(aRegions.size() <= SAL_N_ELEMENTS(nAngles));
     610             :                 assert(aRegions.size() <= SAL_N_ELEMENTS(nBorders));
     611           0 :                 for (size_t i = 0; i < aRegions.size(); i++)
     612             :                 {
     613           0 :                     Rectangle aSub = aRegions[i];
     614           0 :                     Gradient aGradient;
     615           0 :                     aGradient.SetStartColor(Color(nStartCols[i]));
     616           0 :                     aGradient.SetEndColor(Color(nEndCols[i]));
     617           0 :                     aGradient.SetStyle(eStyles[i]);
     618           0 :                     aGradient.SetAngle(nAngles[i]);
     619           0 :                     aGradient.SetBorder(nBorders[i]);
     620           0 :                     rDev.DrawGradient(aSub, aGradient);
     621           0 :                 }
     622             :             }
     623             :             else
     624             :             {
     625           0 :                 Gradient aGradient;
     626           0 :                 aGradient.SetStartColor(COL_YELLOW);
     627           0 :                 aGradient.SetEndColor(COL_RED);
     628           0 :                 aGradient.SetStyle(GradientStyle_RECT);
     629           0 :                 aGradient.SetBorder(r.GetSize().Width()/20);
     630           0 :                 rDev.DrawGradient(r, aGradient);
     631             :             }
     632           0 :         }
     633             :     };
     634             : 
     635           0 :     struct DrawBitmap : public RegionRenderer
     636             :     {
     637           0 :         RENDER_DETAILS(bitmap,KEY_B,10)
     638             : 
     639             :         // Simulate Page Borders rendering - which ultimately should
     640             :         // be done with a shader / gradient
     641           0 :         static void SimulateBorderStretch(OutputDevice &rDev, const Rectangle& r)
     642             :         {
     643           0 :             static BitmapEx aPageShadowMask("sw/res/page-shadow-mask.png");
     644             : 
     645           0 :             BitmapEx aRight(aPageShadowMask);
     646           0 :             sal_Int32 nSlice = (aPageShadowMask.GetSizePixel().Width() - 3) / 4;
     647             :             // a width x 1 slice
     648           0 :             aRight.Crop(Rectangle(Point((nSlice * 3) + 3, (nSlice * 2) + 1),
     649           0 :                                   Size(nSlice, 1)));
     650           0 :             AlphaMask aAlphaMask(aRight.GetBitmap());
     651           0 :             Bitmap aBlockColor = Bitmap(aAlphaMask.GetSizePixel(), 24);
     652           0 :             aBlockColor.Erase(COL_RED);
     653           0 :             BitmapEx aShadowStretch = BitmapEx(aBlockColor, aAlphaMask);
     654             : 
     655           0 :             Point aRenderPt(r.TopLeft());
     656             : 
     657           0 :             long aSizes[] = { 200, 100, 200, 100, 50, 5, 2 };
     658             : 
     659             :             // and yes - we really do this in the page border rendering code ...
     660           0 :             for (size_t i = 0; i < SAL_N_ELEMENTS(aSizes); i++)
     661             :             {
     662           0 :                 aShadowStretch.Scale(Size(aShadowStretch.GetSizePixel().Width(), aSizes[i]),
     663           0 :                                      BmpScaleFlag::Fast);
     664             : 
     665           0 :                 rDev.DrawBitmapEx(aRenderPt, aShadowStretch);
     666           0 :                 aRenderPt.Move(aShadowStretch.GetSizePixel().Width() + 4, 0);
     667             :             }
     668             : 
     669           0 :             AlphaMask aWholeMask(aPageShadowMask.GetBitmap());
     670           0 :             aBlockColor = Bitmap(aPageShadowMask.GetSizePixel(), 24);
     671           0 :             aBlockColor.Erase(COL_GREEN);
     672           0 :             BitmapEx aWhole(aBlockColor, aWholeMask);
     673             : 
     674           0 :             aRenderPt = Point(r.Center());
     675           0 :             aRenderPt.Move(nSlice+1, 0);
     676             : 
     677             :             // An offset background for alpha rendering
     678           0 :             rDev.SetFillColor(COL_BLUE);
     679           0 :             Rectangle aSurround(r.Center(), Size(aPageShadowMask.GetSizePixel()));
     680           0 :             rDev.DrawRect(aSurround);
     681           0 :             rDev.DrawBitmapEx(aRenderPt, aWhole);
     682           0 :         }
     683             : 
     684           0 :         virtual void RenderRegion(OutputDevice &rDev, Rectangle r,
     685             :                                   const RenderContext &rCtx) SAL_OVERRIDE
     686             :         {
     687           0 :             Bitmap aBitmap(rCtx.mpDemoRenderer->maIntroBW);
     688           0 :             aBitmap.Scale(r.GetSize(), BmpScaleFlag::BestQuality);
     689           0 :             rDev.DrawBitmap(r.TopLeft(), aBitmap);
     690             : 
     691           0 :             SimulateBorderStretch(rDev, r);
     692           0 :         }
     693             :     };
     694             : 
     695           0 :     struct DrawBitmapEx : public RegionRenderer
     696             :     {
     697           0 :         RENDER_DETAILS(bitmapex,KEY_X,2)
     698             :         DrawCheckered maCheckered;
     699           0 :         virtual void RenderRegion(OutputDevice &rDev, Rectangle r,
     700             :                                   const RenderContext &rCtx) SAL_OVERRIDE
     701             :         {
     702           0 :             maCheckered.RenderRegion(rDev, r, rCtx);
     703             : 
     704           0 :             BitmapEx aBitmap(rCtx.mpDemoRenderer->maIntro);
     705           0 :             aBitmap.Scale(r.GetSize(), BmpScaleFlag::BestQuality);
     706           0 :             AlphaMask aSemiTransp(aBitmap.GetSizePixel());
     707           0 :             aSemiTransp.Erase(64);
     708             :             rDev.DrawBitmapEx(r.TopLeft(), BitmapEx(aBitmap.GetBitmap(),
     709           0 :                                                     aSemiTransp));
     710           0 :         }
     711             :     };
     712             : 
     713           0 :     struct DrawPolyPolygons : public RegionRenderer
     714             :     {
     715           0 :         RENDER_DETAILS(polypoly,KEY_N,100)
     716           0 :         virtual void RenderRegion(OutputDevice &rDev, Rectangle r,
     717             :                                   const RenderContext &) SAL_OVERRIDE
     718             :         {
     719             :             struct {
     720             :                 double nX, nY;
     721             :             } aPoints[] = { { 0.1, 0.1 }, { 0.9, 0.9 },
     722             : #if FIXME_SELF_INTERSECTING_WORKING
     723             :                             { 0.9, 0.1 }, { 0.1, 0.9 },
     724             :                             { 0.1, 0.1 }
     725             : #else
     726             :                             { 0.1, 0.9 }, { 0.5, 0.5 },
     727             :                             { 0.9, 0.1 }, { 0.1, 0.1 }
     728             : #endif
     729           0 :             };
     730             : 
     731           0 :             tools::PolyPolygon aPolyPoly;
     732             :             // Render 4x polygons & aggregate into another PolyPolygon
     733           0 :             for (int x = 0; x < 2; x++)
     734             :             {
     735           0 :                 for (int y = 0; y < 2; y++)
     736             :                 {
     737           0 :                     Rectangle aSubRect(r);
     738           0 :                     aSubRect.Move(x * r.GetWidth()/3, y * r.GetHeight()/3);
     739           0 :                     aSubRect.SetSize(Size(r.GetWidth()/2, r.GetHeight()/4));
     740           0 :                     Polygon aPoly(SAL_N_ELEMENTS(aPoints));
     741           0 :                     for (size_t v = 0; v < SAL_N_ELEMENTS(aPoints); v++)
     742             :                     {
     743           0 :                         aPoly.SetPoint(Point(aSubRect.Left() +
     744           0 :                                              aSubRect.GetWidth() * aPoints[v].nX,
     745           0 :                                              aSubRect.Top() +
     746           0 :                                              aSubRect.GetHeight() * aPoints[v].nY),
     747           0 :                                        v);
     748             :                     }
     749           0 :                     rDev.SetLineColor(Color(COL_YELLOW));
     750           0 :                     rDev.SetFillColor(Color(COL_BLACK));
     751           0 :                     rDev.DrawPolygon(aPoly);
     752             : 
     753             :                     // now move and add to the polypolygon
     754           0 :                     aPoly.Move(0, r.GetHeight()/2);
     755           0 :                     aPolyPoly.Insert(aPoly);
     756           0 :                 }
     757             :             }
     758           0 :             rDev.SetLineColor(Color(COL_LIGHTRED));
     759           0 :             rDev.SetFillColor(Color(COL_GREEN));
     760           0 :             rDev.DrawTransparent(aPolyPoly, 50);
     761           0 :         }
     762             :     };
     763             : 
     764           0 :     struct DrawToVirtualDevice : public RegionRenderer
     765             :     {
     766           0 :         RENDER_DETAILS(vdev,KEY_V,1)
     767             :         enum RenderType {
     768             :             RENDER_AS_BITMAP,
     769             :             RENDER_AS_OUTDEV,
     770             :             RENDER_AS_BITMAPEX,
     771             :             RENDER_AS_ALPHA_OUTDEV
     772             :         };
     773             : 
     774           0 :         static void SizeAndRender(OutputDevice &rDev, const Rectangle& r, RenderType eType,
     775             :                            const RenderContext &rCtx)
     776             :         {
     777           0 :             ScopedVclPtr<VirtualDevice> pNested;
     778             : 
     779           0 :             if ((int)eType < RENDER_AS_BITMAPEX)
     780           0 :                 pNested = VclPtr<VirtualDevice>::Create(rDev).get();
     781             :             else
     782           0 :                 pNested = VclPtr<VirtualDevice>::Create(rDev,0,0).get();
     783             : 
     784           0 :             pNested->SetOutputSizePixel(r.GetSize());
     785           0 :             Rectangle aWhole(Point(0,0), r.GetSize());
     786             : 
     787             :             // mini me
     788           0 :             rCtx.mpDemoRenderer->drawToDevice(*pNested, r.GetSize(), true);
     789             : 
     790           0 :             if (eType == RENDER_AS_BITMAP)
     791             :             {
     792           0 :                 Bitmap aBitmap(pNested->GetBitmap(Point(0,0),aWhole.GetSize()));
     793           0 :                 rDev.DrawBitmap(r.TopLeft(), aBitmap);
     794             :             }
     795           0 :             else if (eType == RENDER_AS_BITMAPEX)
     796             :             {
     797           0 :                 BitmapEx aBitmapEx(pNested->GetBitmapEx(Point(0,0),aWhole.GetSize()));
     798           0 :                 rDev.DrawBitmapEx(r.TopLeft(), aBitmapEx);
     799             :             }
     800           0 :             else if (eType == RENDER_AS_OUTDEV ||
     801             :                      eType == RENDER_AS_ALPHA_OUTDEV)
     802             :             {
     803             :                 rDev.DrawOutDev(r.TopLeft(), r.GetSize(),
     804             :                                 aWhole.TopLeft(), aWhole.GetSize(),
     805           0 :                                 *pNested);
     806           0 :             }
     807           0 :         }
     808           0 :         virtual void RenderRegion(OutputDevice &rDev, Rectangle r,
     809             :                                   const RenderContext &rCtx) SAL_OVERRIDE
     810             :         {
     811             :             // avoid infinite recursion
     812           0 :             if (rCtx.mbVDev)
     813           0 :                 return;
     814             : 
     815           0 :             if (rCtx.meStyle == RENDER_EXPANDED)
     816             :             {
     817           0 :                 std::vector<Rectangle> aRegions(DemoRenderer::partition(rCtx,2, 2));
     818           0 :                 DemoRenderer::clearRects(rDev, aRegions);
     819             : 
     820             :                 RenderType eRenderTypes[] = { RENDER_AS_BITMAP, RENDER_AS_OUTDEV,
     821           0 :                                               RENDER_AS_BITMAPEX, RENDER_AS_ALPHA_OUTDEV };
     822           0 :                 for (size_t i = 0; i < aRegions.size(); i++)
     823           0 :                     SizeAndRender(rDev, aRegions[i], eRenderTypes[i], rCtx);
     824             :             }
     825             :             else
     826           0 :                 SizeAndRender(rDev, r, RENDER_AS_BITMAP, rCtx);
     827             :         }
     828             :     };
     829             : 
     830           0 :     struct DrawIcons : public RegionRenderer
     831             :     {
     832           0 :         RENDER_DETAILS(icons,KEY_I,1)
     833             : 
     834             :         std::vector<OUString> maIconNames;
     835             :         std::vector<BitmapEx> maIcons;
     836             :         bool bHasLoadedAll;
     837           0 :         DrawIcons() : bHasLoadedAll(false)
     838             :         {
     839             :             // a few icons to start with
     840             :             const char *pNames[] = {
     841             :                 "cmd/lc_openurl.png",
     842             :                 "cmd/lc_newdoc.png",
     843             :                 "cmd/lc_choosemacro.png",
     844             :                 "cmd/lc_save.png",
     845             :                 "cmd/lc_saveas.png",
     846             :                 "cmd/lc_importdialog.png",
     847             :                 "cmd/lc_sendmail.png",
     848             :                 "cmd/lc_editdoc.png",
     849             :                 "cmd/lc_print.png",
     850             :                 "cmd/lc_combobox.png",
     851             :                 "cmd/lc_insertformcombo.png",
     852             :                 "cmd/lc_printpreview.png",
     853             :                 "cmd/lc_cut.png",
     854             :                 "cmd/lc_copy.png",
     855             :                 "cmd/lc_paste.png",
     856             :                 "cmd/sc_autopilotmenu.png",
     857             :                 "cmd/lc_formatpaintbrush.png",
     858             :                 "cmd/lc_undo.png",
     859             :                 "cmd/lc_redo.png",
     860             :                 "cmd/lc_marks.png",
     861             :                 "cmd/lc_fieldnames.png",
     862             :                 "cmd/lc_hyperlinkdialog.png",
     863           0 :               };
     864           0 :             for (size_t i = 0; i < SAL_N_ELEMENTS(pNames); i++)
     865             :             {
     866           0 :                 maIconNames.push_back(OUString::createFromAscii(pNames[i]));
     867           0 :                 maIcons.push_back(BitmapEx(maIconNames[i]));
     868             :             }
     869           0 :         }
     870             : 
     871           0 :         void LoadAllImages()
     872             :         {
     873           0 :             if (bHasLoadedAll)
     874           0 :                 return;
     875           0 :             bHasLoadedAll = true;
     876             : 
     877           0 :             css::uno::Sequence< OUString > aAllIcons = ImageTree_getAllImageNames();
     878           0 :             for (sal_Int32 i = 0; i < aAllIcons.getLength(); i++)
     879             :             {
     880           0 :                 maIconNames.push_back(aAllIcons[i]);
     881           0 :                 maIcons.push_back(BitmapEx(aAllIcons[i]));
     882           0 :             }
     883             :         }
     884             : 
     885           0 :         void doDrawIcons(OutputDevice &rDev, Rectangle r, bool bExpanded)
     886             :         {
     887           0 :             long nMaxH = 0;
     888           0 :             Point p(r.LeftCenter());
     889           0 :             size_t nToRender = maIcons.size();
     890             : 
     891           0 :             if (!bExpanded && maIcons.size() > 64)
     892           0 :                 nToRender = 64;
     893           0 :             for (size_t i = 0; i < nToRender; i++)
     894             :             {
     895           0 :                 Size aSize(maIcons[i].GetSizePixel());
     896             : //              sAL_DEBUG("Draw icon '" << maIconNames[i] << "'");
     897             : 
     898           0 :                 if (!(i % 4))
     899           0 :                     rDev.DrawBitmapEx(p, maIcons[i]);
     900             :                 else
     901             :                 {
     902           0 :                     basegfx::B2DHomMatrix aTransform;
     903           0 :                     aTransform.scale(aSize.Width(), aSize.Height());
     904           0 :                     switch (i % 4)
     905             :                     {
     906             :                     case 2:
     907           0 :                         aTransform.shearX((double)((i >> 2) % 8) / 8);
     908           0 :                         aTransform.shearY((double)((i >> 4) % 8) / 8);
     909           0 :                         break;
     910             :                     case 3:
     911           0 :                         aTransform.translate(-aSize.Width()/2, -aSize.Height()/2);
     912           0 :                         aTransform.rotate(i);
     913           0 :                         if (i & 0x100)
     914             :                         {
     915           0 :                             aTransform.shearX((double)((i >> 2) % 8) / 8);
     916           0 :                             aTransform.shearY((double)((i >> 4) % 8) / 8);
     917             :                         }
     918           0 :                         aTransform.translate(aSize.Width()/2,  aSize.Height()/2);
     919           0 :                         break;
     920             :                     default:
     921           0 :                         aTransform.translate(-aSize.Width()/2, -aSize.Height()/2);
     922           0 :                         aTransform.rotate(2 * F_2PI * i / nToRender);
     923           0 :                         aTransform.translate(aSize.Width()/2,  aSize.Height()/2);
     924           0 :                         break;
     925             :                     }
     926           0 :                     aTransform.translate(p.X(), p.Y());
     927           0 :                     rDev.DrawTransformedBitmapEx(aTransform, maIcons[i]);
     928             :                 }
     929             : 
     930             :                 // next position
     931           0 :                 p.Move(aSize.Width(), 0);
     932           0 :                 if (aSize.Height() > nMaxH)
     933           0 :                     nMaxH = aSize.Height();
     934           0 :                 if (p.X() >= r.Right()) // wrap to next line
     935             :                 {
     936           0 :                     p = Point(r.Left(), p.Y() + nMaxH);
     937           0 :                     nMaxH = 0;
     938             :                 }
     939           0 :                 if (p.Y() >= r.Bottom()) // re-start at middle
     940           0 :                     p = r.LeftCenter();
     941             :             }
     942           0 :         }
     943             : 
     944           0 :         static BitmapEx AlphaRecovery(OutputDevice &rDev, Point aPt, BitmapEx &aSrc)
     945             :         {
     946             :             // Compositing onto 2x colors beyond our control
     947           0 :             ScopedVclPtrInstance< VirtualDevice > aWhite;
     948           0 :             ScopedVclPtrInstance< VirtualDevice > aBlack;
     949           0 :             aWhite->SetOutputSizePixel(aSrc.GetSizePixel());
     950           0 :             aWhite->SetBackground(Wallpaper(COL_WHITE));
     951           0 :             aWhite->Erase();
     952           0 :             aBlack->SetOutputSizePixel(aSrc.GetSizePixel());
     953           0 :             aBlack->SetBackground(Wallpaper(COL_BLACK));
     954           0 :             aBlack->Erase();
     955           0 :             aWhite->DrawBitmapEx(Point(), aSrc);
     956           0 :             aBlack->DrawBitmapEx(Point(), aSrc);
     957             : 
     958             :             // Now recover that alpha...
     959           0 :             Bitmap aWhiteBmp = aWhite->GetBitmap(Point(),aSrc.GetSizePixel());
     960           0 :             Bitmap aBlackBmp = aBlack->GetBitmap(Point(),aSrc.GetSizePixel());
     961           0 :             AlphaMask aMask(aSrc.GetSizePixel());
     962           0 :             Bitmap aRecovered(aSrc.GetSizePixel(), 24);
     963             :             {
     964           0 :                 AlphaMask::ScopedWriteAccess pMaskAcc(aMask);
     965           0 :                 Bitmap::ScopedWriteAccess pRecAcc(aRecovered);
     966           0 :                 Bitmap::ScopedReadAccess pAccW(aWhiteBmp); // a * pix + (1-a)
     967           0 :                 Bitmap::ScopedReadAccess pAccB(aBlackBmp); // a * pix + 0
     968           0 :                 int nSizeX = aSrc.GetSizePixel().Width();
     969           0 :                 int nSizeY = aSrc.GetSizePixel().Height();
     970           0 :                 for (int y = 0; y < nSizeY; y++)
     971             :                 {
     972           0 :                     for (int x = 0; x < nSizeX; x++)
     973             :                     {
     974           0 :                         BitmapColor aColW = pAccW->GetPixel(y,x);
     975           0 :                         BitmapColor aColB = pAccB->GetPixel(y,x);
     976           0 :                         long nAR = (long)(aColW.GetRed() - aColB.GetRed()); // (1-a)
     977           0 :                         long nAG = (long)(aColW.GetGreen() - aColB.GetGreen()); // (1-a)
     978           0 :                         long nAB = (long)(aColW.GetBlue() - aColB.GetBlue()); // (1-a)
     979             : 
     980             : #define CLAMP(a,b,c) (((a)<=(b))?(b):(((a)>=(c))?(c):(a)))
     981             : 
     982             :                         // we get the most precision from the largest delta
     983           0 :                         long nInverseAlpha = std::max(nAR, std::max(nAG, nAB)); // (1-a)
     984           0 :                         nInverseAlpha = CLAMP(nInverseAlpha, 0, 255);
     985           0 :                         long nAlpha = 255 - nInverseAlpha;
     986             : 
     987           0 :                         pMaskAcc->SetPixel(y,x,BitmapColor((sal_Int8)CLAMP(nInverseAlpha,0,255)));
     988             :                         // now recover the pixels
     989           0 :                         long nR = (aColW.GetRed() + aColB.GetRed() - nInverseAlpha) * 128;
     990           0 :                         long nG = (aColW.GetGreen() + aColB.GetGreen() - nInverseAlpha) * 128;
     991           0 :                         long nB = (aColW.GetBlue() + aColB.GetBlue() - nInverseAlpha) * 128;
     992           0 :                         if (nAlpha == 0)
     993             :                         { // doesn't matter what's behind transparency
     994           0 :                             nR = nG = nB = 0;
     995             :                         }
     996             :                         else
     997             :                         {
     998           0 :                             nR /= nAlpha; nG /= nAlpha; nB /= nAlpha;
     999             :                         }
    1000             :                         pRecAcc->SetPixel(y,x,BitmapColor(
    1001             :                                                 (sal_uInt8)CLAMP(nR,0,255),
    1002             :                                                 (sal_uInt8)CLAMP(nG,0,255),
    1003           0 :                                                 (sal_uInt8)CLAMP(nB,0,255)));
    1004             : #undef CLAMP
    1005           0 :                     }
    1006           0 :                 }
    1007             :             }
    1008           0 :             rDev.DrawBitmap(aPt, aWhiteBmp);
    1009           0 :             aPt.Move(aSrc.GetSizePixel().Width(), 0);
    1010           0 :             rDev.DrawBitmap(aPt, aBlackBmp);
    1011           0 :             aPt.Move(aSrc.GetSizePixel().Width(), 0);
    1012           0 :             rDev.DrawBitmap(aPt, aRecovered);
    1013           0 :             aPt.Move(aSrc.GetSizePixel().Width(), 0);
    1014           0 :             rDev.DrawBitmap(aPt, aMask.GetBitmap());
    1015           0 :             aPt.Move(aSrc.GetSizePixel().Width(), 0);
    1016             : 
    1017           0 :             return BitmapEx(aRecovered, aMask);
    1018             :         }
    1019             : 
    1020           0 :         virtual void RenderRegion(OutputDevice &rDev, Rectangle r,
    1021             :                                   const RenderContext &rCtx) SAL_OVERRIDE
    1022             :         {
    1023           0 :             if (rCtx.meStyle == RENDER_EXPANDED)
    1024             :             {
    1025           0 :                 LoadAllImages();
    1026             : 
    1027           0 :                 Point aLocation(0,maIcons[0].GetSizePixel().Height() + 8);
    1028           0 :                 for (size_t i = 0; i < 100; i++)
    1029             :                 {
    1030           0 :                     BitmapEx aSrc = maIcons[i];
    1031             : 
    1032             :                     // original above
    1033           0 :                     Point aAbove(aLocation);
    1034           0 :                     aAbove.Move(0,-aSrc.GetSizePixel().Height() - 4);
    1035           0 :                     rDev.DrawBitmapEx(aAbove, aSrc);
    1036           0 :                     aAbove.Move(aSrc.GetSizePixel().Width(),0);
    1037           0 :                     aAbove.Move(aSrc.GetSizePixel().Width(),0);
    1038           0 :                     rDev.DrawBitmap(aAbove, aSrc.GetBitmap());
    1039           0 :                     aAbove.Move(aSrc.GetSizePixel().Width(),0);
    1040           0 :                     rDev.DrawBitmap(aAbove, aSrc.GetMask());
    1041             : 
    1042             :                     // intermediates middle
    1043           0 :                     BitmapEx aResult = AlphaRecovery(rDev, aLocation, aSrc);
    1044             : 
    1045             :                     // result below
    1046           0 :                     Point aBelow(aLocation);
    1047           0 :                     aBelow.Move(0,aResult.GetSizePixel().Height());
    1048           0 :                     rDev.DrawBitmapEx(aBelow, aResult);
    1049             : 
    1050           0 :                     aLocation.Move(aSrc.GetSizePixel().Width()*6,0);
    1051           0 :                     if (aLocation.X() > r.Right())
    1052           0 :                         aLocation = Point(0,aLocation.Y()+aSrc.GetSizePixel().Height()*3+4);
    1053           0 :                 }
    1054             : 
    1055             :                 // now go crazy with random foo
    1056           0 :                 doDrawIcons(rDev, r, true);
    1057             :             }
    1058             :             else
    1059             :             {
    1060           0 :                 doDrawIcons(rDev, r, false);
    1061             :             }
    1062           0 :         }
    1063             :     };
    1064             : 
    1065           0 :     struct FetchDrawBitmap : public RegionRenderer
    1066             :     {
    1067           0 :         RENDER_DETAILS(fetchdraw,KEY_F,50)
    1068           0 :         virtual void RenderRegion(OutputDevice &rDev, Rectangle r,
    1069             :                                   const RenderContext &) SAL_OVERRIDE
    1070             :         {
    1071           0 :             Bitmap aBitmap(rDev.GetBitmap(Point(0,0),rDev.GetOutputSizePixel()));
    1072           0 :             aBitmap.Scale(r.GetSize(), BmpScaleFlag::BestQuality);
    1073           0 :             rDev.DrawBitmap(r.TopLeft(), aBitmap);
    1074           0 :         }
    1075             :     };
    1076             : 
    1077           0 :     void drawToDevice(vcl::RenderContext& rDev, Size aSize, bool bVDev)
    1078             :     {
    1079           0 :         RenderContext aCtx;
    1080             :         double mnStartTime;
    1081           0 :         aCtx.mbVDev = bVDev;
    1082           0 :         aCtx.mpDemoRenderer = this;
    1083           0 :         aCtx.maSize = aSize;
    1084           0 :         Rectangle aWholeWin(Point(0,0), rDev.GetOutputSizePixel());
    1085             : 
    1086           0 :         drawBackground(rDev, aWholeWin);
    1087             : 
    1088           0 :         if (!bVDev /* want everything in the vdev */ &&
    1089           0 :             mnSelectedRenderer >= 0)
    1090             :         {
    1091           0 :             aCtx.meStyle = RENDER_EXPANDED;
    1092           0 :             RegionRenderer * r = maRenderers[mnSelectedRenderer];
    1093             :             // profiling?
    1094           0 :             if (getIterCount() > 0)
    1095             :             {
    1096           0 :                 mnStartTime = getTimeNow();
    1097           0 :                 for (int i = 0; i < r->getTestRepeatCount(); i++)
    1098           0 :                     r->RenderRegion(rDev, aWholeWin, aCtx);
    1099           0 :                 addTime(mnSelectedRenderer, getTimeNow() - mnStartTime);
    1100             :             } else
    1101           0 :                 r->RenderRegion(rDev, aWholeWin, aCtx);
    1102             :         }
    1103             :         else
    1104             :         {
    1105           0 :             aCtx.meStyle = RENDER_THUMB;
    1106           0 :             std::vector<Rectangle> aRegions(partition(aSize, mnSegmentsX, mnSegmentsY));
    1107           0 :             DemoRenderer::clearRects(rDev, aRegions);
    1108           0 :             for (size_t i = 0; i < maRenderers.size(); i++)
    1109             :             {
    1110           0 :                 RegionRenderer * r = maRenderers[i];
    1111             : 
    1112           0 :                 rDev.SetClipRegion( vcl::Region( aRegions[i] ) );
    1113             : 
    1114             :                 // profiling?
    1115           0 :                 if (getIterCount() > 0)
    1116             :                 {
    1117           0 :                     if (!bVDev)
    1118             :                     {
    1119           0 :                         mnStartTime = getTimeNow();
    1120           0 :                         for (int j = 0; j < r->getTestRepeatCount() * THUMB_REPEAT_FACTOR; j++)
    1121           0 :                             r->RenderRegion(rDev, aRegions[i], aCtx);
    1122           0 :                         addTime(i, (getTimeNow() - mnStartTime) / THUMB_REPEAT_FACTOR);
    1123             :                     } else
    1124           0 :                         for (int j = 0; j < r->getTestRepeatCount(); j++)
    1125           0 :                             r->RenderRegion(rDev, aRegions[i], aCtx);
    1126             :                 }
    1127             :                 else
    1128             :                 {
    1129           0 :                     r->RenderRegion(rDev, aRegions[i], aCtx);
    1130             :                 }
    1131             : 
    1132           0 :                 rDev.SetClipRegion();
    1133           0 :             }
    1134             :         }
    1135           0 :     }
    1136             :     std::vector<VclPtr<vcl::Window> > maInvalidates;
    1137           0 :     void addInvalidate(vcl::Window *pWindow) { maInvalidates.push_back(pWindow); };
    1138           0 :     void removeInvalidate(vcl::Window *pWindow)
    1139             :     {
    1140           0 :         for (auto aIt = maInvalidates.begin(); aIt != maInvalidates.end(); ++aIt)
    1141             :         {
    1142           0 :             if (*aIt == pWindow)
    1143             :             {
    1144           0 :                 maInvalidates.erase(aIt);
    1145           0 :                 return;
    1146             :             }
    1147             :         }
    1148             :     }
    1149           0 :     void Invalidate()
    1150             :     {
    1151           0 :         for (size_t i = 0; i < maInvalidates.size(); ++i)
    1152           0 :             maInvalidates[i]->Invalidate();
    1153           0 :     }
    1154             : };
    1155             : 
    1156             : #if FIXME_BOUNCE_BUTTON
    1157             : IMPL_LINK_NOARG(DemoRenderer,BounceTimerCb)
    1158             : {
    1159             :     mpButton->Check(mnBounceX>0);
    1160             :     mpButton->SetPressed(mnBounceY>0);
    1161             : 
    1162             :     Point aCur = mpButtonWin->GetPosPixel();
    1163             :     static const int nMovePix = 10;
    1164             :     aCur.Move(mnBounceX * nMovePix, mnBounceX * nMovePix);
    1165             :     Size aWinSize = GetSizePixel();
    1166             :     if (aCur.X() <= 0 || aCur.X() >= aWinSize.Width())
    1167             :         mnBounceX *= -1;
    1168             :     if (aCur.Y() <= 0 || aCur.Y() >= aWinSize.Height())
    1169             :         mnBounceX *= -1;
    1170             :     mpButtonWin->SetPosPixel(aCur);
    1171             : 
    1172             :     // All smoke and mirrors to test sub-region invalidation underneath
    1173             :     Rectangle aRect(aCur, mpButtonWin->GetSizePixel());
    1174             :     Invalidate(aRect);
    1175             :     return 0;
    1176             : }
    1177             : #endif
    1178             : 
    1179           0 : void DemoRenderer::KeyInput(const KeyEvent &rKEvt)
    1180             : {
    1181           0 :     sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode();
    1182             : 
    1183             :     // click to zoom out
    1184           0 :     if (mnSelectedRenderer >= 0)
    1185             :     {
    1186           0 :         if (nCode == KEY_ESCAPE || nCode == KEY_BACKSPACE)
    1187             :         {
    1188           0 :             mnSelectedRenderer = -1;
    1189           0 :             Invalidate();
    1190           0 :             return;
    1191             :         }
    1192             :     }
    1193             :     else
    1194             :     {
    1195           0 :         for (size_t i = 0; i < maRenderers.size(); i++)
    1196             :         {
    1197           0 :             if (nCode == maRenderers[i]->getAccelerator())
    1198             :             {
    1199           0 :                 mnSelectedRenderer = i;
    1200           0 :                 Invalidate();
    1201           0 :                 return;
    1202             :             }
    1203             :         }
    1204             :     }
    1205             : }
    1206             : 
    1207           0 : bool DemoRenderer::MouseButtonDown(const MouseEvent& rMEvt)
    1208             : {
    1209             :     // click to zoom out
    1210           0 :     if (mnSelectedRenderer >= 0)
    1211             :     {
    1212           0 :         mnSelectedRenderer = -1;
    1213           0 :         Invalidate();
    1214           0 :         return true;
    1215             :     }
    1216             : 
    1217             :     // click on a region to zoom into it
    1218           0 :     std::vector<Rectangle> aRegions(partition(GetSizePixel(), mnSegmentsX, mnSegmentsY));
    1219           0 :     for (size_t i = 0; i < aRegions.size(); i++)
    1220             :     {
    1221           0 :         if (aRegions[i].IsInside(rMEvt.GetPosPixel()))
    1222             :         {
    1223           0 :             mnSelectedRenderer = i;
    1224           0 :             Invalidate();
    1225           0 :             return true;
    1226             :         }
    1227             :     }
    1228             : 
    1229             : #if FIXME_BOUNCE_BUTTON
    1230             :     // otherwise bounce floating windows
    1231             :     if (!mpButton)
    1232             :     {
    1233             :         mpButtonWin = VclPtr<FloatingWindow>::Create(this);
    1234             :         mpButton = VclPtr<PushButton>::Create(mpButtonWin);
    1235             :         mpButton->SetSymbol(SymbolType::HELP);
    1236             :         mpButton->SetText("PushButton demo");
    1237             :         mpButton->SetPosSizePixel(Point(0,0), mpButton->GetOptimalSize());
    1238             :         mpButton->Show();
    1239             :         mpButtonWin->SetPosSizePixel(Point(0,0), mpButton->GetOptimalSize());
    1240             :         mpButtonWin->Show();
    1241             :         mnBounceX = 1; mnBounceX = 1;
    1242             :         maBounce.SetTimeoutHdl(LINK(this,DemoRenderer,BounceTimerCb));
    1243             :         maBounce.SetTimeout(55);
    1244             :         maBounce.Start();
    1245             :     }
    1246             :     else
    1247             :     {
    1248             :         maBounce.Stop();
    1249             :         delete mpButtonWin;
    1250             :         mpButtonWin = NULL;
    1251             :         mpButton = NULL;
    1252             :     }
    1253             : #endif
    1254           0 :     return false;
    1255             : }
    1256             : 
    1257           0 : void DemoRenderer::InitRenderers()
    1258             : {
    1259           0 :     maRenderers.push_back(new DrawLines());
    1260           0 :     maRenderers.push_back(new DrawText());
    1261           0 :     maRenderers.push_back(new DrawPoly());
    1262           0 :     maRenderers.push_back(new DrawEllipse());
    1263           0 :     maRenderers.push_back(new DrawCheckered());
    1264           0 :     maRenderers.push_back(new DrawBitmapEx());
    1265           0 :     maRenderers.push_back(new DrawBitmap());
    1266           0 :     maRenderers.push_back(new DrawGradient());
    1267           0 :     maRenderers.push_back(new DrawPolyPolygons());
    1268           0 :     maRenderers.push_back(new DrawToVirtualDevice());
    1269           0 :     maRenderers.push_back(new DrawIcons());
    1270           0 :     maRenderers.push_back(new FetchDrawBitmap());
    1271           0 : }
    1272             : 
    1273           0 : OUString DemoRenderer::getRendererList()
    1274             : {
    1275           0 :     OUStringBuffer aBuf;
    1276           0 :     for (size_t i = 0; i < maRenderers.size(); i++)
    1277             :     {
    1278           0 :         aBuf.append(maRenderers[i]->getName());
    1279           0 :         aBuf.append(' ');
    1280             :     }
    1281           0 :     return aBuf.makeStringAndClear();
    1282             : }
    1283             : 
    1284           0 : double DemoRenderer::getAndResetBenchmark(const RenderStyle style)
    1285             : {
    1286           0 :     double geomean = 1.0;
    1287           0 :     fprintf(stderr, "Rendering: %s, Times (ms):\n", style == RENDER_THUMB ? "THUMB": "EXPANDED");
    1288           0 :     for (size_t i = 0; i < maRenderers.size(); i++)
    1289             :     {
    1290           0 :         double avgtime = maRenderers[i]->sumTime / maRenderers[i]->countTime;
    1291           0 :         geomean *= avgtime;
    1292             :         fprintf(stderr, "%s: %f (iteration: %d*%d*%d)\n",
    1293           0 :                 rtl::OUStringToOString(maRenderers[i]->getName(),
    1294             :                 RTL_TEXTENCODING_UTF8).getStr(), avgtime,
    1295           0 :                 maRenderers[i]->countTime, maRenderers[i]->getTestRepeatCount(),
    1296           0 :                 (style == RENDER_THUMB) ? THUMB_REPEAT_FACTOR : 1);
    1297           0 :         maRenderers[i]->sumTime = 0;
    1298           0 :         maRenderers[i]->countTime = 0;
    1299             :     }
    1300           0 :     geomean = pow(geomean, static_cast<double>(1.0)/maRenderers.size());
    1301           0 :     fprintf(stderr, "GEOMEAN_%s: %f\n", style == RENDER_THUMB ? "THUMB": "EXPANDED", geomean);
    1302           0 :     return geomean;
    1303             : }
    1304             : 
    1305           0 : void DemoRenderer::setIterCount(sal_Int32 i)
    1306             : {
    1307           0 :     iterCount = i;
    1308           0 : }
    1309             : 
    1310           0 : sal_Int32 DemoRenderer::getIterCount()
    1311             : {
    1312           0 :     return iterCount;
    1313             : }
    1314             : 
    1315           0 : void DemoRenderer::addTime(int i, double t)
    1316             : {
    1317           0 :     maRenderers[i]->sumTime += t / maRenderers[i]->getTestRepeatCount();
    1318           0 :     maRenderers[i]->countTime++;
    1319           0 : }
    1320             : 
    1321           0 : void DemoRenderer::selectRenderer(const OUString &rName )
    1322             : {
    1323           0 :     for (size_t i = 0; i < maRenderers.size(); i++)
    1324             :     {
    1325           0 :         if (maRenderers[i]->getName() == rName)
    1326             :         {
    1327           0 :             mnSelectedRenderer = i;
    1328           0 :             Invalidate();
    1329           0 :             return;
    1330             :         }
    1331             :     }
    1332             : }
    1333             : 
    1334           0 : int DemoRenderer::selectNextRenderer()
    1335             : {
    1336           0 :     mnSelectedRenderer++;
    1337           0 :     if (mnSelectedRenderer == (signed) maRenderers.size())
    1338           0 :         mnSelectedRenderer = -1;
    1339           0 :     Invalidate();
    1340           0 :     return mnSelectedRenderer;
    1341             : }
    1342             : 
    1343             : class DemoWin : public WorkWindow
    1344             : {
    1345             :     DemoRenderer &mrRenderer;
    1346             :     bool underTesting;
    1347             :     bool testThreads;
    1348             : 
    1349             :     class RenderThread : public salhelper::Thread {
    1350             :         DemoWin  &mrWin;
    1351             :         TimeValue maDelay;
    1352             :     public:
    1353           0 :         RenderThread(DemoWin &rWin, sal_uInt32 nDelaySecs)
    1354             :             : Thread("vcldemo render thread")
    1355           0 :             , mrWin(rWin)
    1356             :         {
    1357           0 :             maDelay.Seconds = nDelaySecs;
    1358           0 :             maDelay.Nanosec = 0;
    1359           0 :             launch();
    1360           0 :         }
    1361           0 :         virtual ~RenderThread()
    1362           0 :         {
    1363           0 :             join();
    1364           0 :         }
    1365           0 :         virtual void execute() SAL_OVERRIDE
    1366             :         {
    1367           0 :             osl_waitThread(&maDelay);
    1368             : 
    1369           0 :             SolarMutexGuard aGuard;
    1370           0 :             fprintf (stderr, "render from a different thread\n");
    1371           0 :             mrWin.Invalidate();
    1372           0 :         }
    1373             :     };
    1374             :     rtl::Reference<RenderThread> mxThread;
    1375             : 
    1376             : public:
    1377           0 :     DemoWin(DemoRenderer &rRenderer, bool bThreads) :
    1378             :         WorkWindow(NULL, WB_APP | WB_STDWORK),
    1379             :         mrRenderer(rRenderer),
    1380           0 :         testThreads(bThreads)
    1381             :     {
    1382           0 :         mrRenderer.addInvalidate(this);
    1383           0 :         underTesting = false;
    1384           0 :     }
    1385           0 :     virtual ~DemoWin()
    1386           0 :     {
    1387           0 :         disposeOnce();
    1388           0 :     }
    1389           0 :     virtual void dispose() SAL_OVERRIDE
    1390             :     {
    1391           0 :         mxThread.clear();
    1392           0 :         mrRenderer.removeInvalidate(this);
    1393           0 :         WorkWindow::dispose();
    1394           0 :     }
    1395           0 :     virtual void MouseButtonDown(const MouseEvent& rMEvt) SAL_OVERRIDE
    1396             :     {
    1397           0 :         mrRenderer.SetSizePixel(GetSizePixel());
    1398           0 :         if (!mrRenderer.MouseButtonDown(rMEvt))
    1399             :         {
    1400           0 :             if (testThreads)
    1401             :             { // render this window asynchronously in a new thread
    1402           0 :                 sal_uInt32 nDelaySecs = 0;
    1403           0 :                 if (rMEvt.GetButtons() & MOUSE_RIGHT)
    1404           0 :                     nDelaySecs = 5;
    1405           0 :                 mxThread = new RenderThread(*this, nDelaySecs);
    1406             :             }
    1407             :             else
    1408             :             { // spawn another window
    1409           0 :                 VclPtrInstance<DemoWin> pNewWin(mrRenderer, testThreads);
    1410           0 :                 pNewWin->SetText("Another interactive VCL demo window");
    1411           0 :                 pNewWin->Show();
    1412             :             }
    1413             :         }
    1414           0 :     }
    1415           0 :     virtual void KeyInput(const KeyEvent& rKEvt) SAL_OVERRIDE
    1416             :     {
    1417           0 :         mrRenderer.SetSizePixel(GetSizePixel());
    1418           0 :         mrRenderer.KeyInput(rKEvt);
    1419           0 :     }
    1420           0 :     virtual void Paint(vcl::RenderContext& rRenderContext, const Rectangle& rRect) SAL_OVERRIDE
    1421             :     {
    1422           0 :         mrRenderer.SetSizePixel(GetSizePixel());
    1423           0 :         fprintf(stderr, "DemoWin::Paint(%ld,%ld,%ld,%ld)\n", rRect.getX(), rRect.getY(), rRect.getWidth(), rRect.getHeight());
    1424           0 :         if (mrRenderer.getIterCount() == 0)
    1425           0 :             mrRenderer.drawToDevice(rRenderContext, GetSizePixel(), false);
    1426             :         else
    1427           0 :             TestAndQuit(rRenderContext);
    1428           0 :     }
    1429             : 
    1430           0 :     void TestAndQuit(vcl::RenderContext& rRenderContext)
    1431             :     {
    1432           0 :         if (underTesting)
    1433           0 :             return;
    1434           0 :         underTesting = true;
    1435           0 :         for (sal_Int32 i = 0; i < mrRenderer.getIterCount(); i++)
    1436             :         {
    1437           0 :             while (mrRenderer.selectNextRenderer() > -1)
    1438             :             {
    1439           0 :                 mrRenderer.drawToDevice(rRenderContext, GetSizePixel(), false);
    1440             :             }
    1441             :         }
    1442             : 
    1443           0 :         double expandedGEOMEAN = mrRenderer.getAndResetBenchmark(RENDER_EXPANDED);
    1444             : 
    1445           0 :         for (sal_Int32 i = 0; i < mrRenderer.getIterCount(); i++)
    1446           0 :             mrRenderer.drawToDevice(rRenderContext, GetSizePixel(), false);
    1447             : 
    1448           0 :         double thumbGEOMEAN = mrRenderer.getAndResetBenchmark(RENDER_THUMB);
    1449             : 
    1450           0 :         fprintf(stderr, "GEOMEAN_TOTAL: %f\n", pow(thumbGEOMEAN * expandedGEOMEAN, static_cast<double>(0.5)));
    1451           0 :         Application::Quit();
    1452             :     }
    1453             : };
    1454             : 
    1455             : class DemoWidgets : public WorkWindow
    1456             : {
    1457             :     VclPtr<VclBox> mpBox;
    1458             :     VclPtr<ToolBox> mpToolbox;
    1459             :     VclPtr<PushButton> mpButton;
    1460             : 
    1461             : public:
    1462           0 :     DemoWidgets() :
    1463             :         WorkWindow(NULL, WB_STDWORK),
    1464             :         mpBox(VclPtrInstance<VclVBox>(this, false, 3)),
    1465           0 :         mpToolbox(VclPtrInstance<ToolBox>(mpBox.get())),
    1466           0 :         mpButton(VclPtrInstance<PushButton>(mpBox.get()))
    1467             :     {
    1468           0 :         SetText("VCL widget demo");
    1469             : 
    1470           0 :         Wallpaper aWallpaper(BitmapEx("sfx2/res/startcenter-logo.png"));
    1471           0 :         aWallpaper.SetStyle(WALLPAPER_BOTTOMRIGHT);
    1472           0 :         aWallpaper.SetColor(COL_RED);
    1473             : 
    1474           0 :         mpBox->SetBackground(aWallpaper);
    1475           0 :         mpBox->Show();
    1476             : 
    1477           0 :         Help::EnableBalloonHelp();
    1478           0 :         mpToolbox->SetHelpText("Help text");
    1479           0 :         mpToolbox->InsertItem(0, "Toolbar item");
    1480           0 :         mpToolbox->SetQuickHelpText(0, "This is a tooltip popup");
    1481           0 :         mpToolbox->InsertSeparator();
    1482           0 :         mpToolbox->Show();
    1483             : 
    1484           0 :         mpButton->SetText("Click me; go on");
    1485           0 :         mpButton->Show();
    1486             : 
    1487           0 :         Show();
    1488           0 :     }
    1489           0 :     virtual ~DemoWidgets() { disposeOnce(); }
    1490           0 :     virtual void dispose() SAL_OVERRIDE
    1491             :     {
    1492           0 :         mpBox.disposeAndClear();
    1493           0 :         mpToolbox.disposeAndClear();
    1494           0 :         mpButton.disposeAndClear();
    1495           0 :         WorkWindow::dispose();
    1496           0 :     }
    1497           0 :     virtual void Paint(vcl::RenderContext& /*rRenderContext*/, const Rectangle&) SAL_OVERRIDE
    1498             :     {
    1499           0 :         Rectangle aWholeSize(Point(0, 0),GetOutputSizePixel());
    1500           0 :         vcl::Region aClip(aWholeSize);
    1501           0 :         Rectangle aExclude(Rectangle(Point(50,50),Size(100,100)));
    1502           0 :         aClip.Exclude(aExclude);
    1503             : 
    1504           0 :         Wallpaper aWallpaper(COL_GREEN);
    1505             : 
    1506           0 :         Push(PushFlags::CLIPREGION);
    1507           0 :         IntersectClipRegion(aClip);
    1508           0 :         DrawWallpaper(aWholeSize, aWallpaper);
    1509           0 :         Pop();
    1510             : 
    1511           0 :         ScopedVclPtrInstance< VirtualDevice > pDev(*this);
    1512           0 :         pDev->EnableRTL(IsRTLEnabled());
    1513           0 :         pDev->SetOutputSizePixel(aExclude.GetSize());
    1514             : 
    1515           0 :         Rectangle aSubRect(aWholeSize);
    1516           0 :         aSubRect.Move(-aExclude.Left(), -aExclude.Top());
    1517           0 :         pDev->DrawWallpaper(aSubRect, aWallpaper );
    1518             : 
    1519             :         DrawOutDev(aExclude.TopLeft(), aExclude.GetSize(),
    1520           0 :                    Point( 0, 0 ), aExclude.GetSize(), *pDev.get() );
    1521           0 :     }
    1522             : };
    1523             : 
    1524           0 : class DemoPopup : public FloatingWindow
    1525             : {
    1526             :  public:
    1527           0 :     DemoPopup() : FloatingWindow( NULL, WB_SYSTEMWINDOW|WB_TOOLTIPWIN)
    1528             :     {
    1529           0 :         SetType( WINDOW_HELPTEXTWINDOW );
    1530             : 
    1531           0 :         SetOutputSizePixel( Size( 300, 30 ) );
    1532           0 :         SetBackground(Wallpaper(COL_YELLOW));
    1533             : 
    1534           0 :         Show( true, ShowFlags::NoActivate );
    1535           0 :         Update();
    1536           0 :     }
    1537             : 
    1538           0 :     virtual void Paint(vcl::RenderContext& /*rRenderContext*/, const Rectangle&) SAL_OVERRIDE
    1539             :     {
    1540             :         // Interestingly in GL mode on Windows, this doesn't render.
    1541             : 
    1542           0 :         Size aSize = GetOutputSizePixel();
    1543           0 :         Rectangle aTextRect(Point(6, 6), aSize);
    1544             : 
    1545           0 :         SetTextColor(COL_BLACK);
    1546           0 :         SetTextAlign(ALIGN_TOP);
    1547             :         DrawText(aTextRect, "This is a standalone help text test",
    1548             :                  DrawTextFlags::MultiLine|DrawTextFlags::WordBreak|
    1549           0 :                  DrawTextFlags::Left|DrawTextFlags::Top);
    1550             : 
    1551           0 :         SetLineColor(COL_BLACK);
    1552           0 :         SetFillColor();
    1553           0 :         DrawRect( Rectangle( Point(), aSize ) );
    1554           0 :         aSize.Width() -= 2;
    1555           0 :         aSize.Height() -= 2;
    1556           0 :         Color aColor( GetLineColor() );
    1557           0 :         SetLineColor( ( COL_GRAY ) );
    1558           0 :         DrawRect( Rectangle( Point( 1, 1 ), aSize ) );
    1559           0 :         SetLineColor( aColor );
    1560           0 :     }
    1561             : };
    1562             : 
    1563           0 : class DemoApp : public Application
    1564             : {
    1565           0 :     static int showHelp(DemoRenderer &rRenderer)
    1566             :     {
    1567           0 :         fprintf(stderr,"vcldemo - a VCL test app\n");
    1568           0 :         fprintf(stderr,"  --help             - print this text\n");
    1569           0 :         fprintf(stderr,"  --show <renderer>  - start with a given renderer, options are:\n");
    1570           0 :         OUString aRenderers(rRenderer.getRendererList());
    1571             :         fprintf(stderr,"         %s\n",
    1572           0 :                 rtl::OUStringToOString(aRenderers, RTL_TEXTENCODING_UTF8).getStr());
    1573           0 :         fprintf(stderr,"  --test <iterCount> - create benchmark data\n");
    1574           0 :         fprintf(stderr,"  --widgets          - launch the widget test.\n");
    1575           0 :         fprintf(stderr,"  --threads          - render from multiple threads.\n");
    1576           0 :         fprintf(stderr, "\n");
    1577           0 :         return 0;
    1578             :     }
    1579             : 
    1580             : public:
    1581           0 :     DemoApp() {}
    1582             : 
    1583           0 :     virtual int Main() SAL_OVERRIDE
    1584             :     {
    1585             :         try
    1586             :         {
    1587           0 :             bool bWidgets = false, bThreads = false, bPopup = false;
    1588           0 :             DemoRenderer aRenderer;
    1589             : 
    1590           0 :             for (sal_Int32 i = 0; i < GetCommandLineParamCount(); i++)
    1591             :             {
    1592           0 :                 bool bLast = i == GetCommandLineParamCount() - 1;
    1593           0 :                 OUString aArg = GetCommandLineParam(i);
    1594           0 :                 if (aArg == "--help" || aArg == "-h")
    1595           0 :                     return showHelp(aRenderer);
    1596           0 :                 if (aArg == "--show")
    1597             :                 {
    1598           0 :                     if (bLast)
    1599           0 :                         return showHelp(aRenderer);
    1600             :                     else
    1601           0 :                         aRenderer.selectRenderer(GetCommandLineParam(++i));
    1602             :                 }
    1603           0 :                 else if (aArg == "--test")
    1604             :                 {
    1605           0 :                     if (bLast)
    1606           0 :                         return showHelp(aRenderer);
    1607             :                     else
    1608           0 :                         aRenderer.setIterCount(GetCommandLineParam(++i).toInt32());
    1609             :                 }
    1610           0 :                 else if (aArg == "--widgets")
    1611           0 :                     bWidgets = true;
    1612           0 :                 else if (aArg == "--popup")
    1613           0 :                     bPopup = true;
    1614           0 :                 else if (aArg == "--threads")
    1615           0 :                     bThreads = true;
    1616           0 :                 else if (aArg.startsWith("--"))
    1617             :                 {
    1618             :                     fprintf(stderr,"Unknown argument '%s'\n",
    1619           0 :                             rtl::OUStringToOString(aArg, RTL_TEXTENCODING_UTF8).getStr());
    1620           0 :                     return showHelp(aRenderer);
    1621             :                 }
    1622           0 :             }
    1623             : 
    1624           0 :             ScopedVclPtrInstance<DemoWin> aMainWin(aRenderer, bThreads);
    1625           0 :             VclPtr<DemoWidgets> xWidgets;
    1626           0 :             VclPtr<DemoPopup> xPopup;
    1627             : 
    1628           0 :             aMainWin->SetText("Interactive VCL demo #1");
    1629             : 
    1630           0 :             if (bWidgets)
    1631           0 :                 xWidgets = VclPtr< DemoWidgets >::Create ();
    1632           0 :             else if (bPopup)
    1633           0 :                 xPopup = VclPtrInstance< DemoPopup> ();
    1634             :             else
    1635           0 :                 aMainWin->Show();
    1636             : 
    1637           0 :             Application::Execute();
    1638             : 
    1639           0 :             xWidgets.disposeAndClear();
    1640           0 :             xPopup.disposeAndClear();
    1641             :         }
    1642           0 :         catch (const css::uno::Exception& e)
    1643             :         {
    1644             :             SAL_WARN("vcl.app", "Fatal exception: " << e.Message);
    1645           0 :             return 1;
    1646             :         }
    1647           0 :         catch (const std::exception& e)
    1648             :         {
    1649             :             SAL_WARN("vcl.app", "Fatal exception: " << e.what());
    1650           0 :             return 1;
    1651             :         }
    1652           0 :         return 0;
    1653             :     }
    1654             : 
    1655             : protected:
    1656             :     uno::Reference<lang::XMultiServiceFactory> xMSF;
    1657           0 :     void Init() SAL_OVERRIDE
    1658             :     {
    1659             :         try
    1660             :         {
    1661             :             uno::Reference<uno::XComponentContext> xComponentContext
    1662           0 :                 = ::cppu::defaultBootstrap_InitialComponentContext();
    1663           0 :             xMSF = uno::Reference<lang::XMultiServiceFactory>
    1664           0 :                 (xComponentContext->getServiceManager(), uno::UNO_QUERY);
    1665           0 :             if(!xMSF.is())
    1666           0 :                 Application::Abort("Bootstrap failure - no service manager");
    1667             : 
    1668           0 :             ::comphelper::setProcessServiceFactory(xMSF);
    1669             :         }
    1670           0 :         catch (const uno::Exception &e)
    1671             :         {
    1672           0 :             Application::Abort("Bootstrap exception " + e.Message);
    1673             :         }
    1674           0 :     }
    1675           0 :     void DeInit() SAL_OVERRIDE
    1676             :     {
    1677             :         uno::Reference< lang::XComponent >(
    1678             :             comphelper::getProcessComponentContext(),
    1679           0 :         uno::UNO_QUERY_THROW)-> dispose();
    1680           0 :         ::comphelper::setProcessServiceFactory(NULL);
    1681           0 :     }
    1682             : };
    1683             : 
    1684           0 : void vclmain::createApplication()
    1685             : {
    1686           0 :     static DemoApp aApp;
    1687           0 : }
    1688             : 
    1689             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11