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: */
|