1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 // This code strongly inspired by Miguel / Federico's Gnome Canvas demo code.
22 #include <sal/config.h>
24 #include <basegfx/polygon/b2dpolygon.hxx>
25 #include <basegfx/polygon/b2dpolygontools.hxx>
26 #include <basegfx/utils/canvastools.hxx>
27 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
28 #include <com/sun/star/rendering/CompositeOperation.hpp>
29 #include <com/sun/star/rendering/PathCapType.hpp>
30 #include <com/sun/star/rendering/PathJoinType.hpp>
31 #include <com/sun/star/rendering/RenderState.hpp>
32 #include <com/sun/star/rendering/ViewState.hpp>
33 #include <com/sun/star/rendering/XBitmap.hpp>
34 #include <com/sun/star/rendering/XCanvas.hpp>
35 #include <com/sun/star/rendering/XGraphicDevice.hpp>
36 #include <com/sun/star/rendering/XSpriteCanvas.hpp>
37 #include <com/sun/star/uno/XComponentContext.hpp>
38 #include <comphelper/processfactory.hxx>
39 #include <comphelper/random.hxx>
40 #include <cppuhelper/bootstrap.hxx>
41 #include <o3tl/deleter.hxx>
42 #include <o3tl/safeint.hxx>
44 #include <vcl/canvastools.hxx>
45 #include <vcl/svapp.hxx>
46 #include <vcl/vclmain.hxx>
47 #include <vcl/wrkwin.hxx>
49 using namespace ::com::sun::star
;
51 static void PrintHelp()
53 fprintf( stdout
, "canvasdemo - Exercise the new canvas impl\n" );
58 class TestWindow
: public WorkWindow
61 TestWindow() : WorkWindow(nullptr, WB_APP
| WB_STDWORK
)
63 SetText(u
"Canvas test"_ustr
);
64 SetSizePixel( Size( 600, 450 ) );
68 virtual ~TestWindow() override
{}
69 virtual void MouseButtonUp( const MouseEvent
& /*rMEvt*/ ) override
71 //TODO: do something cool
74 virtual void Paint(vcl::RenderContext
& rRenderContext
, const tools::Rectangle
& rRect
) override
;
82 rendering::ViewState maViewState
;
83 rendering::RenderState maRenderState
;
84 uno::Sequence
< double > maColorBlack
;
85 uno::Sequence
< double > maColorRed
;
86 uno::Reference
< rendering::XCanvas
> mxCanvas
;
87 uno::Reference
< rendering::XCanvasFont
> mxDefaultFont
;
88 uno::Reference
< rendering::XGraphicDevice
> mxDevice
;
90 DemoRenderer( uno::Reference
< rendering::XGraphicDevice
> xDevice
,
91 uno::Reference
< rendering::XCanvas
> xCanvas
,
94 maColorBlack( vcl::unotools::colorToStdColorSpaceSequence( COL_BLACK
) ),
95 maColorRed( vcl::unotools::colorToStdColorSpaceSequence( COL_RED
) ),
97 mxDevice(std::move( xDevice
))
100 geometry::AffineMatrix2D
aUnit( 1,0, 0,
102 maViewState
.AffineTransform
= aUnit
;
103 maRenderState
.AffineTransform
= aUnit
;
104 maRenderState
.DeviceColor
= maColorBlack
;
106 //I can't figure out what the compositeoperation stuff does
107 //it doesn't seem to do anything in either VCL or cairocanvas
108 //I was hoping that CLEAR would clear the canvas before we paint,
109 //but nothing changes
110 maRenderState
.CompositeOperation
= rendering::CompositeOperation::OVER
;
112 maBox
.setWidth(aSize
.Width() / 3);
113 maBox
.setHeight(aSize
.Height() / 3);
115 lang::Locale aLocale
;
116 rendering::FontInfo aFontInfo
;
117 aFontInfo
.FamilyName
= "Swiss";
118 aFontInfo
.StyleName
= "SansSerif";
119 geometry::Matrix2D
aFontMatrix( 1, 0,
121 rendering::FontRequest
aFontRequest( aFontInfo
, 12.0, 0.0, aLocale
);
122 uno::Sequence
< beans::PropertyValue
> aExtraFontProperties
;
123 mxDefaultFont
= xCanvas
->createFont( aFontRequest
, aExtraFontProperties
, aFontMatrix
);
124 if( !mxDefaultFont
.is() )
125 fprintf( stderr
, "Failed to create font\n" );
130 tools::Long d
, dIncr
= maSize
.Width() / 3;
131 for ( d
= 0; d
<= maSize
.Width(); d
+= dIncr
)
132 mxCanvas
->drawLine( geometry::RealPoint2D( d
, 0 ),
133 geometry::RealPoint2D( d
, maSize
.Height() ),
134 maViewState
, maRenderState
);
135 dIncr
= maSize
.Height() / 3;
136 for ( d
= 0; d
<= maSize
.Height(); d
+= dIncr
)
137 mxCanvas
->drawLine( geometry::RealPoint2D( 0, d
),
138 geometry::RealPoint2D( maSize
.Width(), d
),
139 maViewState
, maRenderState
);
142 void drawStringAt( OString aString
, double x
, double y
)
144 rendering::StringContext aText
;
145 aText
.Text
= OStringToOUString( aString
, RTL_TEXTENCODING_UTF8
);
146 aText
.StartPosition
= 0;
147 aText
.Length
= aString
.getLength();
148 rendering::RenderState
aRenderState( maRenderState
);
149 aRenderState
.AffineTransform
.m02
+= x
;
150 aRenderState
.AffineTransform
.m12
+= y
;
152 mxCanvas
->drawText( aText
, mxDefaultFont
, maViewState
, aRenderState
, 0);
155 void drawRect( tools::Rectangle rRect
, const uno::Sequence
< double > &aColor
, int /*nWidth*/ )
157 uno::Sequence
< uno::Sequence
< geometry::RealPoint2D
> > aPolys
160 { o3tl::narrowing
<double>(rRect
.Left()), o3tl::narrowing
<double>(rRect
.Top()) },
161 { o3tl::narrowing
<double>(rRect
.Left()), o3tl::narrowing
<double>(rRect
.Bottom()) },
162 { o3tl::narrowing
<double>(rRect
.Right()), o3tl::narrowing
<double>(rRect
.Bottom()) },
163 { o3tl::narrowing
<double>(rRect
.Right()), o3tl::narrowing
<double>(rRect
.Top()) }
166 auto xPoly
= mxDevice
->createCompatibleLinePolyPolygon( aPolys
);
167 xPoly
->setClosed( 0, true );
169 rendering::RenderState
aRenderState( maRenderState
);
170 aRenderState
.DeviceColor
= aColor
;
171 mxCanvas
->drawPolyPolygon( xPoly
, maViewState
, aRenderState
);
174 void translate( double x
, double y
)
176 maRenderState
.AffineTransform
.m02
+= x
;
177 maRenderState
.AffineTransform
.m12
+= y
;
180 void drawPolishDiamond( double center_x
, double center_y
)
182 const int VERTICES
= 10;
183 const double RADIUS
= 60.0;
186 rendering::RenderState aOldRenderState
= maRenderState
; // push
187 translate( center_x
, center_y
);
189 for (i
= 0; i
< VERTICES
; i
++)
191 double a
= 2.0 * M_PI
* i
/ VERTICES
;
192 geometry::RealPoint2D
aSrc( RADIUS
* cos (a
), RADIUS
* sin (a
) );
194 for (j
= i
+ 1; j
< VERTICES
; j
++)
196 a
= 2.0 * M_PI
* j
/ VERTICES
;
198 // FIXME: set cap_style to 'ROUND'
199 mxCanvas
->drawLine( aSrc
,
200 geometry::RealPoint2D( RADIUS
* cos (a
),
202 maViewState
, maRenderState
);
206 maRenderState
= std::move(aOldRenderState
); // pop
209 void drawHilbert( double anchor_x
, double anchor_y
)
211 const double SCALE
=7.0;
212 const char hilbert
[] = "urdrrulurulldluuruluurdrurddldrrruluurdrurddldrddlulldrdldrrurd";
213 int nLength
= std::size( hilbert
);
215 uno::Sequence
< geometry::RealPoint2D
> aPoints( nLength
);
216 auto pPoints
= aPoints
.getArray();
217 uno::Reference
< rendering::XLinePolyPolygon2D
> xPoly
;
219 pPoints
[0] = geometry::RealPoint2D( anchor_x
, anchor_y
);
220 for (int i
= 0; i
< nLength
; i
++ )
225 pPoints
[i
+1] = geometry::RealPoint2D( aPoints
[i
].X
,
226 aPoints
[i
].Y
- SCALE
);
229 pPoints
[i
+1] = geometry::RealPoint2D( aPoints
[i
].X
,
230 aPoints
[i
].Y
+ SCALE
);
233 pPoints
[i
+1] = geometry::RealPoint2D( aPoints
[i
].X
- SCALE
,
237 pPoints
[i
+1] = geometry::RealPoint2D( aPoints
[i
].X
+ SCALE
,
243 uno::Sequence
< uno::Sequence
< geometry::RealPoint2D
> > aPolys
{ aPoints
};
245 xPoly
= mxDevice
->createCompatibleLinePolyPolygon( aPolys
);
246 xPoly
->setClosed( 0, false );
248 rendering::RenderState
aRenderState( maRenderState
);
249 aRenderState
.DeviceColor
= maColorRed
;
250 // aRenderState.DeviceColor[3] = 0.5;
251 rendering::StrokeAttributes aStrokeAttrs
;
252 aStrokeAttrs
.StrokeWidth
= 4.0;
253 aStrokeAttrs
.MiterLimit
= 2.0; // ?
254 aStrokeAttrs
.StartCapType
= rendering::PathCapType::BUTT
;
255 aStrokeAttrs
.EndCapType
= rendering::PathCapType::BUTT
;
256 aStrokeAttrs
.JoinType
= rendering::PathJoinType::MITER
;
257 //fprintf( stderr, "FIXME: stroking a tools::PolyPolygon doesn't show up\n" );
259 mxCanvas
->strokePolyPolygon( xPoly
, maViewState
, aRenderState
, aStrokeAttrs
);
260 // FIXME: do this instead:
261 //mxCanvas->drawPolyPolygon( xPoly, maViewState, aRenderState );
264 void drawTitle( OString aTitle
)
266 // FIXME: text anchoring to be done
267 double nStringWidth
= aTitle
.getLength() * 8.0;
268 drawStringAt ( aTitle
, (maBox
.Width() - nStringWidth
) / 2, 15 );
271 void drawRectangles()
273 rendering::RenderState aOldRenderState
= maRenderState
; // push
275 drawTitle( "Rectangles"_ostr
);
277 drawRect( tools::Rectangle( 20, 30, 70, 60 ), maColorRed
, 8 );
278 // color mediumseagreen, stipple fill, outline black
279 drawRect( tools::Rectangle( 90, 40, 180, 100 ), maColorBlack
, 4 );
280 // color steelblue, filled, no outline
281 drawRect( tools::Rectangle( 10, 80, 80, 140 ), maColorBlack
, 1 );
283 maRenderState
= std::move(aOldRenderState
); // pop
288 rendering::RenderState aOldRenderState
= maRenderState
; // push
289 translate( maBox
.Width(), 0.0 );
291 drawTitle( "Ellipses"_ostr
);
293 const basegfx::B2DPoint
aCenter( maBox
.Width()*.5,
295 const basegfx::B2DPoint
aRadii( maBox
.Width()*.3,
297 const basegfx::B2DPolygon
& rEllipse(
298 basegfx::utils::createPolygonFromEllipse( aCenter
,
302 uno::Reference
< rendering::XPolyPolygon2D
> xPoly(
303 basegfx::unotools::xPolyPolygonFromB2DPolygon(mxDevice
,
306 rendering::StrokeAttributes aStrokeAttrs
;
307 aStrokeAttrs
.StrokeWidth
= 4.0;
308 aStrokeAttrs
.MiterLimit
= 2.0; // ?
309 aStrokeAttrs
.StartCapType
= rendering::PathCapType::BUTT
;
310 aStrokeAttrs
.EndCapType
= rendering::PathCapType::BUTT
;
311 aStrokeAttrs
.JoinType
= rendering::PathJoinType::MITER
;
312 mxCanvas
->strokePolyPolygon( xPoly
, maViewState
, maRenderState
, aStrokeAttrs
);
314 maRenderState
= std::move(aOldRenderState
); // pop
319 rendering::RenderState aOldRenderState
= maRenderState
; // push
320 translate( maBox
.Width() * 2.0, 0.0 );
322 drawTitle( "Text"_ostr
);
325 maBox
.Height() * .5 );
326 drawTitle( "This is lame"_ostr
);
328 maRenderState
= std::move(aOldRenderState
); // pop
333 rendering::RenderState aOldRenderState
= maRenderState
; // push
334 translate( 0.0, maBox
.Height() );
336 drawTitle( "Images"_ostr
);
338 uno::Reference
< rendering::XBitmap
> xBitmap(mxCanvas
, uno::UNO_QUERY
);
343 translate( maBox
.Width()*0.1, maBox
.Height()*0.2 );
344 maRenderState
.AffineTransform
.m00
*= 4.0/15;
345 maRenderState
.AffineTransform
.m11
*= 3.0/15;
347 mxCanvas
->drawBitmap(xBitmap
, maViewState
, maRenderState
);
349 // uno::Reference< rendering::XBitmap > xBitmap2( xBitmap->getScaledBitmap(geometry::RealSize2D(48, 48), false) );
350 // mxCanvas->drawBitmap(xBitmap2, maViewState, maRenderState); //yes, but where?
352 //called CanvasHelper::getScaledBitmap, we return NULL, TODO
353 //Exception 'BitmapEx vclcanvas::tools::bitmapExFromXBitmap(const css::uno::Reference<css::rendering::XBitmap>&),
354 //bitmapExFromXBitmap(): could not extract BitmapEx' thrown
357 //Exception 'BitmapEx vclcanvas::tools::bitmapExFromXBitmap(const css::uno::Reference<css::rendering::XBitmap>&),
358 //bitmapExFromXBitmap(): could not extract bitmap' thrown
359 // Thorsten says that this is a bug, and Thorsten never lies.
361 maRenderState
= std::move(aOldRenderState
); // pop
366 rendering::RenderState aOldRenderState
= maRenderState
; // push
367 translate( maBox
.Width(), maBox
.Height() );
369 drawTitle( "Lines"_ostr
);
371 drawPolishDiamond( 70.0, 80.0 );
372 drawHilbert( 140.0, 140.0 );
374 maRenderState
= std::move(aOldRenderState
); // pop
379 rendering::RenderState aOldRenderState
= maRenderState
; // push
380 translate( maBox
.Width() * 2.0, maBox
.Height() );
382 drawTitle( "Curves"_ostr
);
384 translate( maBox
.Width() * .5, maBox
.Height() * .5 );
386 const double r
= 30.0;
387 const int num_curves
= 3;
390 uno::Sequence
< geometry::RealBezierSegment2D
> aBeziers (num_curves
);
391 auto pBeziers
= aBeziers
.getArray();
392 uno::Reference
< rendering::XBezierPolyPolygon2D
> xPoly
;
394 for (int i
= 0; i
< num_curves
; i
++)
395 pBeziers
[i
]= geometry::RealBezierSegment2D( r
* cos(i
*2*M_PI
/num_curves
), //Px
396 r
* sin(i
*2*M_PI
/num_curves
), //py
397 r
* 2 * cos((i
*2*M_PI
+ 2*M_PI
)/num_curves
), //C1x
398 r
* 2 * sin((i
*2*M_PI
+ 2*M_PI
)/num_curves
), //C1y
399 r
* 2 * cos((i
*2*M_PI
+ 2*M_PI
)/num_curves
), //C2x
400 r
* 2 * sin((i
*2*M_PI
+ 2*M_PI
)/num_curves
)); //C2y
401 uno::Sequence
< uno::Sequence
< geometry::RealBezierSegment2D
> > aPolys
{ aBeziers
};
402 xPoly
= mxDevice
->createCompatibleBezierPolyPolygon(aPolys
);
403 xPoly
->setClosed( 0, true );
404 //uno::Reference< rendering::XBezierPolyPolygon2D> xPP( xPoly, uno::UNO_QUERY );
405 //compiles, but totally screws up. I think it is interpreting the bezier as a line
407 rendering::StrokeAttributes aStrokeAttrs
;
408 aStrokeAttrs
.StrokeWidth
= 4.0;
409 aStrokeAttrs
.MiterLimit
= 2.0; // ?
410 aStrokeAttrs
.StartCapType
= rendering::PathCapType::BUTT
;
411 aStrokeAttrs
.EndCapType
= rendering::PathCapType::BUTT
;
412 aStrokeAttrs
.JoinType
= rendering::PathJoinType::MITER
;
413 mxCanvas
->strokePolyPolygon( xPoly
, maViewState
, maRenderState
, aStrokeAttrs
);
414 //you can't draw a BezierPolyPolygon2D with this, even though it is derived from it
415 //mxCanvas->drawPolyPolygon( xPoly, maViewState, maRenderState );
417 maRenderState
= std::move(aOldRenderState
); // pop
422 return comphelper::rng::uniform_real_distribution(0, 100);
427 rendering::RenderState aOldRenderState
= maRenderState
; // push
428 translate( 0.0, maBox
.Height() * 2.0 );
430 drawTitle( "Arcs"_ostr
);
434 //This stuff doesn't belong here, but probably in curves
435 //This stuff doesn't work in VCL b/c vcl doesn't do beziers
436 //Hah! Every time the window redraws, we do this
442 for (int i
= 0; i
< 1; i
++)
452 double c1x
= gimmerand();
453 double c1y
= gimmerand();
454 double c2x
= gimmerand();
455 double c2y
= gimmerand();
456 maRenderState
.DeviceColor
= maColorRed
;
457 mxCanvas
->drawLine(geometry::RealPoint2D(ax
, ay
), geometry::RealPoint2D(c1x
, c1y
), maViewState
, maRenderState
);
458 mxCanvas
->drawLine(geometry::RealPoint2D(c1x
, c1y
), geometry::RealPoint2D(c2x
, c2y
), maViewState
, maRenderState
);
459 mxCanvas
->drawLine(geometry::RealPoint2D(bx
, by
), geometry::RealPoint2D(c2x
, c2y
), maViewState
, maRenderState
);
461 geometry::RealBezierSegment2D
aBezierSegment(
469 geometry::RealPoint2D
aEndPoint(bx
, by
);
470 maRenderState
.DeviceColor
= maColorBlack
;
471 mxCanvas
->drawBezier(
474 maViewState
, maRenderState
);
476 maRenderState
= std::move(aOldRenderState
); // pop
480 void drawRegularPolygon(double centerx
, double centery
, int sides
, double r
)
483 uno::Sequence
< geometry::RealPoint2D
> aPoints (sides
);
484 auto pPoints
= aPoints
.getArray();
485 uno::Reference
< rendering::XLinePolyPolygon2D
> xPoly
;
487 for (int i
= 0; i
< sides
; i
++)
489 pPoints
[i
]= geometry::RealPoint2D( centerx
+ r
* cos(i
*2 * M_PI
/sides
),
490 centery
+ r
* sin(i
*2 * M_PI
/sides
));
492 uno::Sequence
< uno::Sequence
< geometry::RealPoint2D
> > aPolys
{ aPoints
};
493 xPoly
= mxDevice
->createCompatibleLinePolyPolygon( aPolys
);
494 xPoly
->setClosed( 0, true );
495 rendering::RenderState
aRenderState( maRenderState
);
496 aRenderState
.DeviceColor
= maColorRed
;
497 mxCanvas
->drawPolyPolygon( xPoly
, maViewState
, aRenderState
);
498 mxCanvas
->fillPolyPolygon( xPoly
,
505 rendering::RenderState aOldRenderState
= maRenderState
; // push
506 translate( maBox
.Width() * 1.0, maBox
.Height() * 2.0 );
508 drawTitle( "Polygons"_ostr
);
511 for (int i
= 1; i
<= 4; i
++)
513 drawRegularPolygon(35*i
, 35, sides
, 15);
517 maRenderState
= std::move(aOldRenderState
); // pop
520 void drawWidgets() // FIXME: prolly makes no sense
522 rendering::RenderState aOldRenderState
= maRenderState
; // push
523 translate( maBox
.Width() * 2.0, maBox
.Height() * 2.0 );
525 drawTitle( "Widgets"_ostr
);
527 maRenderState
= std::move(aOldRenderState
); // pop
533 void TestWindow::Paint(vcl::RenderContext
&, const tools::Rectangle
&)
537 uno::Reference
< rendering::XCanvas
> xVDevCanvas( GetOutDev()->GetCanvas(),
538 uno::UNO_SET_THROW
);
539 uno::Reference
< rendering::XGraphicDevice
> xVDevDevice( xVDevCanvas
->getDevice(),
540 uno::UNO_SET_THROW
);
541 DemoRenderer
aVDevRenderer( xVDevDevice
, xVDevCanvas
, GetSizePixel());
542 xVDevCanvas
->clear();
543 aVDevRenderer
.drawGrid();
544 aVDevRenderer
.drawRectangles();
545 aVDevRenderer
.drawEllipses();
546 aVDevRenderer
.drawText();
547 aVDevRenderer
.drawLines();
548 aVDevRenderer
.drawCurves();
549 aVDevRenderer
.drawArcs();
550 aVDevRenderer
.drawPolygons();
552 uno::Reference
< rendering::XCanvas
> xCanvas( GetOutDev()->GetSpriteCanvas(),
553 uno::UNO_QUERY_THROW
);
554 uno::Reference
< rendering::XGraphicDevice
> xDevice( xCanvas
->getDevice(),
555 uno::UNO_SET_THROW
);
557 DemoRenderer
aRenderer( xDevice
, xCanvas
, GetSizePixel() );
559 aRenderer
.drawGrid();
560 aRenderer
.drawRectangles();
561 aRenderer
.drawEllipses();
562 aRenderer
.drawText();
563 aRenderer
.drawLines();
564 aRenderer
.drawCurves();
565 aRenderer
.drawArcs();
566 aRenderer
.drawPolygons();
567 aRenderer
.drawWidgets();
568 aRenderer
.drawImages();
570 // check whether virdev actually contained something
571 uno::Reference
< rendering::XBitmap
> xBitmap(xVDevCanvas
, uno::UNO_QUERY
);
575 aRenderer
.maRenderState
.AffineTransform
.m02
+= 100;
576 aRenderer
.maRenderState
.AffineTransform
.m12
+= 100;
577 xCanvas
->drawBitmap(xBitmap
, aRenderer
.maViewState
, aRenderer
.maRenderState
);
579 uno::Reference
< rendering::XSpriteCanvas
> xSpriteCanvas( xCanvas
,
581 if( xSpriteCanvas
.is() )
582 xSpriteCanvas
->updateScreen( true ); // without
587 catch (const uno::Exception
&e
)
589 fprintf( stderr
, "Exception '%s' thrown\n" ,
590 OUStringToOString( e
.Message
, RTL_TEXTENCODING_UTF8
).getStr() );
596 class DemoApp
: public Application
599 virtual int Main() override
;
600 virtual void Exception(ExceptionCategory nCategory
) override
;
603 void Init() override
;
604 void DeInit() override
;
613 for( unsigned int i
= 0; i
< GetCommandLineParamCount(); i
++ )
615 OUString aParam
= GetCommandLineParam( i
);
617 if( aParam
== "--help" || aParam
== "-h" )
627 ScopedVclPtr
<TestWindow
> aWindow
= VclPtr
<TestWindow
>::Create();
628 suppress_fun_call_w_exception(aWindow
->Show());
630 Application::Execute();
634 void DemoApp::Exception( ExceptionCategory
)
642 uno::Reference
<uno::XComponentContext
> xComponentContext
643 = ::cppu::defaultBootstrap_InitialComponentContext();
644 uno::Reference
<lang::XMultiServiceFactory
> xMSF
;
645 xMSF
.set(xComponentContext
->getServiceManager(), uno::UNO_QUERY
);
647 Application::Abort(u
"Bootstrap failure - no service manager"_ustr
);
649 ::comphelper::setProcessServiceFactory(xMSF
);
651 catch (const uno::Exception
&e
)
653 Application::Abort("Bootstrap exception " + e
.Message
);
657 void DemoApp::DeInit()
659 uno::Reference
< lang::XComponent
>(
660 comphelper::getProcessComponentContext(),
661 uno::UNO_QUERY_THROW
)-> dispose();
662 ::comphelper::setProcessServiceFactory(nullptr);
665 void vclmain::createApplication()
671 // - bouncing clip-rectangle mode - bounce a clip-rect around the window...
672 // - complete all of pre-existing canvas bits
673 // - affine transform tweakage...
675 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */