1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 25 // MARKER(update_precomp.py): autogen include statement, do not remove 26 #include "precompiled_canvas.hxx" 27 // This code strongly inspired by Miguel / Federico's Gnome Canvas demo code. 28 29 #include <comphelper/processfactory.hxx> 30 #include <comphelper/regpathhelper.hxx> 31 #include <cppuhelper/servicefactory.hxx> 32 #include <cppuhelper/bootstrap.hxx> 33 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 34 #include <com/sun/star/lang/XInitialization.hpp> 35 #include <com/sun/star/registry/XSimpleRegistry.hpp> 36 37 #include <ucbhelper/contentbroker.hxx> 38 #include <ucbhelper/configurationkeys.hxx> 39 40 #include <basegfx/polygon/b2dpolygon.hxx> 41 #include <basegfx/polygon/b2dpolygontools.hxx> 42 #include <basegfx/tools/canvastools.hxx> 43 44 #include <vcl/window.hxx> 45 #include <vcl/virdev.hxx> 46 #include <vcl/svapp.hxx> 47 #include <vcl/msgbox.hxx> 48 #include <vcl/unowrap.hxx> 49 #include <vcl/canvastools.hxx> 50 51 #include <rtl/bootstrap.hxx> 52 53 #include <com/sun/star/rendering/XCanvas.hpp> 54 #include <com/sun/star/rendering/FillRule.hpp> 55 #include <com/sun/star/rendering/ViewState.hpp> 56 #include <com/sun/star/rendering/RenderState.hpp> 57 #include <com/sun/star/rendering/PathCapType.hpp> 58 #include <com/sun/star/rendering/PathJoinType.hpp> 59 #include <com/sun/star/rendering/XSpriteCanvas.hpp> 60 #include <com/sun/star/rendering/XGraphicDevice.hpp> 61 #include <com/sun/star/rendering/CompositeOperation.hpp> 62 #include <com/sun/star/rendering/XBitmap.hpp> 63 64 #include <stdio.h> 65 #include <unistd.h> 66 67 68 // never import whole leaf namespaces, since this will result in 69 // absolutely weird effects during (Koenig) name lookup 70 using namespace ::com::sun::star; 71 72 73 class DemoApp : public Application 74 { 75 public: 76 virtual void Main(); 77 virtual USHORT Exception( USHORT nError ); 78 }; 79 80 static void PrintHelp() 81 { 82 fprintf( stdout, "canvasdemo - Exercise the new canvas impl\n" ); 83 } 84 85 class TestWindow : public Dialog 86 { 87 public: 88 TestWindow() : Dialog( (Window *) NULL ) 89 { 90 SetText( rtl::OUString::createFromAscii( "Canvas test" ) ); 91 SetSizePixel( Size( 600, 450 ) ); 92 EnablePaint( true ); 93 Show(); 94 } 95 virtual ~TestWindow() {} 96 virtual void MouseButtonUp( const MouseEvent& /*rMEvt*/ ) 97 { 98 //TODO: do something cool 99 EndDialog(); 100 } 101 virtual void Paint( const Rectangle& rRect ); 102 }; 103 104 class DemoRenderer 105 { 106 public: 107 Size maSize; 108 Size maBox; 109 rendering::ViewState maViewState; 110 rendering::RenderState maRenderState; 111 uno::Sequence< double > maColorBlack; 112 uno::Sequence< double > maColorWhite; 113 uno::Sequence< double > maColorRed; 114 uno::Reference< rendering::XCanvas > mxCanvas; 115 uno::Reference< rendering::XCanvasFont > mxDefaultFont; 116 uno::Reference< rendering::XGraphicDevice > mxDevice; 117 118 DemoRenderer( uno::Reference< rendering::XGraphicDevice > xDevice, 119 uno::Reference< rendering::XCanvas > xCanvas, 120 Size aSize ) : 121 maSize(aSize), 122 maBox(), 123 maViewState(), 124 maRenderState(), 125 maColorBlack( vcl::unotools::colorToStdColorSpaceSequence( Color(COL_BLACK)) ), 126 maColorWhite( vcl::unotools::colorToStdColorSpaceSequence( Color(COL_WHITE)) ), 127 maColorRed( vcl::unotools::colorToStdColorSpaceSequence( Color(COL_RED)) ), 128 mxCanvas(xCanvas), 129 mxDefaultFont(), 130 mxDevice( xDevice ) 131 { 132 // Geometry init 133 geometry::AffineMatrix2D aUnit( 1,0, 0, 134 0,1, 0 ); 135 maViewState.AffineTransform = aUnit; 136 maRenderState.AffineTransform = aUnit; 137 maRenderState.DeviceColor = maColorBlack; 138 139 //I can't figure out what the compsiteoperation stuff does 140 //it doesn't seem to do anything in either VCL or cairocanvas 141 //I was hoping that CLEAR would clear the canvas before we paint, 142 //but nothing changes 143 maRenderState.CompositeOperation = rendering::CompositeOperation::OVER; 144 145 maBox.Width() = aSize.Width() / 3; 146 maBox.Height() = aSize.Height() / 3; 147 148 lang::Locale aLocale; 149 rendering::FontInfo aFontInfo; 150 aFontInfo.FamilyName = ::rtl::OUString::createFromAscii( "Swiss" ); 151 aFontInfo.StyleName = ::rtl::OUString::createFromAscii( "SansSerif" ); 152 geometry::Matrix2D aFontMatrix( 1, 0, 153 0, 1 ); 154 rendering::FontRequest aFontRequest( aFontInfo, 12.0, 0.0, aLocale ); 155 uno::Sequence< beans::PropertyValue > aExtraFontProperties; 156 mxDefaultFont = xCanvas->createFont( aFontRequest, aExtraFontProperties, aFontMatrix ); 157 if( !mxDefaultFont.is() ) 158 fprintf( stderr, "Failed to create font\n" ); 159 } 160 161 void drawGrid() 162 { 163 double d, dIncr = maSize.Width() / 3; 164 for ( d = 0; d <= maSize.Width(); d += dIncr ) 165 mxCanvas->drawLine( geometry::RealPoint2D( d, 0 ), 166 geometry::RealPoint2D( d, maSize.Height() ), 167 maViewState, maRenderState ); 168 dIncr = maSize.Height() / 3; 169 for ( d = 0; d <= maSize.Height(); d += dIncr ) 170 mxCanvas->drawLine( geometry::RealPoint2D( 0, d ), 171 geometry::RealPoint2D( maSize.Width(), d ), 172 maViewState, maRenderState ); 173 } 174 175 void drawStringAt( ::rtl::OString aString, double x, double y ) 176 { 177 rendering::StringContext aText; 178 aText.Text = ::rtl::OStringToOUString( aString, RTL_TEXTENCODING_UTF8 ); 179 aText.StartPosition = 0; 180 aText.Length = aString.getLength(); 181 rendering::RenderState aRenderState( maRenderState ); 182 aRenderState.AffineTransform.m02 += x; 183 aRenderState.AffineTransform.m12 += y; 184 185 mxCanvas->drawText( aText, mxDefaultFont, maViewState, aRenderState, 0); 186 } 187 188 void drawRect( Rectangle rRect, uno::Sequence< double > &aColor, int /*nWidth*/ ) 189 { 190 uno::Sequence< geometry::RealPoint2D > aPoints(4); 191 uno::Reference< rendering::XLinePolyPolygon2D > xPoly; 192 193 aPoints[0] = geometry::RealPoint2D( rRect.Left(), rRect.Top() ); 194 aPoints[1] = geometry::RealPoint2D( rRect.Left(), rRect.Bottom() ); 195 aPoints[2] = geometry::RealPoint2D( rRect.Right(), rRect.Bottom() ); 196 aPoints[3] = geometry::RealPoint2D( rRect.Right(), rRect.Top() ); 197 198 uno::Sequence< uno::Sequence< geometry::RealPoint2D > > aPolys(1); 199 aPolys[0] = aPoints; 200 xPoly = mxDevice->createCompatibleLinePolyPolygon( aPolys ); 201 xPoly->setClosed( 0, true ); 202 uno::Reference< rendering::XPolyPolygon2D> xPP( xPoly, uno::UNO_QUERY ); 203 204 rendering::RenderState aRenderState( maRenderState ); 205 aRenderState.DeviceColor = aColor; 206 mxCanvas->drawPolyPolygon( xPP, maViewState, aRenderState ); 207 } 208 209 void translate( double x, double y) 210 { 211 maRenderState.AffineTransform.m02 += x; 212 maRenderState.AffineTransform.m12 += y; 213 } 214 215 void drawPolishDiamond( double center_x, double center_y) 216 { 217 const int VERTICES = 10; 218 const double RADIUS = 60.0; 219 int i, j; 220 double a; 221 222 rendering::RenderState maOldRenderState = maRenderState; // push 223 translate( center_x, center_y ); 224 225 for (i = 0; i < VERTICES; i++) 226 { 227 a = 2.0 * M_PI * i / VERTICES; 228 geometry::RealPoint2D aSrc( RADIUS * cos (a), RADIUS * sin (a) ); 229 230 for (j = i + 1; j < VERTICES; j++) 231 { 232 a = 2.0 * M_PI * j / VERTICES; 233 234 // FIXME: set cap_style to 'ROUND' 235 mxCanvas->drawLine( aSrc, 236 geometry::RealPoint2D( RADIUS * cos (a), 237 RADIUS * sin (a) ), 238 maViewState, maRenderState ); 239 } 240 } 241 242 maRenderState = maOldRenderState; // pop 243 } 244 245 void drawHilbert( double anchor_x, double anchor_y ) 246 { 247 const double SCALE=7.0; 248 const char hilbert[] = "urdrrulurulldluuruluurdrurddldrrruluurdrurddldrddlulldrdldrrurd"; 249 int nLength = sizeof( hilbert ) / sizeof (hilbert [0]); 250 251 uno::Sequence< geometry::RealPoint2D > aPoints( nLength ); 252 uno::Reference< rendering::XLinePolyPolygon2D > xPoly; 253 254 aPoints[0] = geometry::RealPoint2D( anchor_x, anchor_y ); 255 for (int i = 0; i < nLength; i++ ) 256 { 257 switch( hilbert[i] ) 258 { 259 case 'u': 260 aPoints[i+1] = geometry::RealPoint2D( aPoints[i].X, 261 aPoints[i].Y - SCALE ); 262 break; 263 case 'd': 264 aPoints[i+1] = geometry::RealPoint2D( aPoints[i].X, 265 aPoints[i].Y + SCALE ); 266 break; 267 case 'l': 268 aPoints[i+1] = geometry::RealPoint2D( aPoints[i].X - SCALE, 269 aPoints[i].Y ); 270 break; 271 case 'r': 272 aPoints[i+1] = geometry::RealPoint2D( aPoints[i].X + SCALE, 273 aPoints[i].Y ); 274 break; 275 } 276 } 277 278 uno::Sequence< uno::Sequence< geometry::RealPoint2D > > aPolys(1); 279 aPolys[0] = aPoints; 280 281 xPoly = mxDevice->createCompatibleLinePolyPolygon( aPolys ); 282 xPoly->setClosed( 0, false ); 283 uno::Reference< rendering::XPolyPolygon2D> xPP( xPoly, uno::UNO_QUERY ); 284 285 rendering::RenderState aRenderState( maRenderState ); 286 aRenderState.DeviceColor = maColorRed; 287 // aRenderState.DeviceColor[3] = 0.5; 288 rendering::StrokeAttributes aStrokeAttrs; 289 aStrokeAttrs.StrokeWidth = 4.0; 290 aStrokeAttrs.MiterLimit = 2.0; // ? 291 aStrokeAttrs.StartCapType = rendering::PathCapType::BUTT; 292 aStrokeAttrs.EndCapType = rendering::PathCapType::BUTT; 293 aStrokeAttrs.JoinType = rendering::PathJoinType::MITER; 294 //fprintf( stderr, "FIXME: stroking a PolyPolygon doesn't show up\n" ); 295 //yes it does 296 mxCanvas->strokePolyPolygon( xPP, maViewState, aRenderState, aStrokeAttrs ); 297 // FIXME: do this instead: 298 //mxCanvas->drawPolyPolygon( xPP, maViewState, aRenderState ); 299 } 300 301 void drawTitle( rtl::OString aTitle ) 302 { 303 // FIXME: text anchoring to be done 304 double nStringWidth = aTitle.getLength() * 8.0; 305 drawStringAt ( aTitle, (maBox.Width() - nStringWidth) / 2, 15 ); 306 } 307 308 void drawRectangles() 309 { 310 rendering::RenderState maOldRenderState = maRenderState; // push 311 312 drawTitle( ::rtl::OString( "Rectangles" ) ); 313 314 drawRect( Rectangle( 20, 30, 70, 60 ), maColorRed, 8 ); 315 // color mediumseagreen, stipple fill, outline black 316 drawRect( Rectangle( 90, 40, 180, 100 ), maColorBlack, 4 ); 317 // color steelblue, filled, no outline 318 drawRect( Rectangle( 10, 80, 80, 140 ), maColorBlack, 1 ); 319 320 maRenderState = maOldRenderState; // pop 321 } 322 323 void drawEllipses() 324 { 325 rendering::RenderState maOldRenderState = maRenderState; // push 326 translate( maBox.Width(), 0.0 ); 327 328 drawTitle( ::rtl::OString( "Ellipses" ) ); 329 330 const basegfx::B2DPoint aCenter( maBox.Width()*.5, 331 maBox.Height()*.5 ); 332 const basegfx::B2DPoint aRadii( maBox.Width()*.3, 333 maBox.Height()*.3 ); 334 const basegfx::B2DPolygon& rEllipse( 335 basegfx::tools::createPolygonFromEllipse( aCenter, 336 aRadii.getX(), 337 aRadii.getY() )); 338 339 uno::Reference< rendering::XPolyPolygon2D > xPoly( 340 basegfx::unotools::xPolyPolygonFromB2DPolygon(mxDevice, 341 rEllipse) ); 342 343 rendering::StrokeAttributes aStrokeAttrs; 344 aStrokeAttrs.StrokeWidth = 4.0; 345 aStrokeAttrs.MiterLimit = 2.0; // ? 346 aStrokeAttrs.StartCapType = rendering::PathCapType::BUTT; 347 aStrokeAttrs.EndCapType = rendering::PathCapType::BUTT; 348 aStrokeAttrs.JoinType = rendering::PathJoinType::MITER; 349 mxCanvas->strokePolyPolygon( xPoly, maViewState, maRenderState, aStrokeAttrs ); 350 351 maRenderState = maOldRenderState; // pop 352 } 353 354 void drawText() 355 { 356 rendering::RenderState maOldRenderState = maRenderState; // push 357 translate( maBox.Width() * 2.0, 0.0 ); 358 359 drawTitle( ::rtl::OString( "Text" ) ); 360 361 translate( 0.0, 362 maBox.Height() * .5 ); 363 drawTitle( ::rtl::OString( "This is lame" ) ); 364 365 maRenderState = maOldRenderState; // pop 366 } 367 368 void drawImages() 369 { 370 rendering::RenderState maOldRenderState = maRenderState; // push 371 translate( 0.0, maBox.Height() ); 372 373 drawTitle( ::rtl::OString( "Images" ) ); 374 375 uno::Reference< rendering::XBitmap > xBitmap(mxCanvas, uno::UNO_QUERY); 376 377 if( !xBitmap.is() ) 378 return; 379 380 translate( maBox.Width()*0.1, maBox.Height()*0.2 ); 381 maRenderState.AffineTransform.m00 *= 4.0/15; 382 maRenderState.AffineTransform.m11 *= 3.0/15; 383 384 mxCanvas->drawBitmap(xBitmap, maViewState, maRenderState); 385 386 // uno::Reference< rendering::XBitmap > xBitmap2( xBitmap->getScaledBitmap(geometry::RealSize2D(48, 48), false) ); 387 // mxCanvas->drawBitmap(xBitmap2, maViewState, maRenderState); //yes, but where? 388 //cairo-canvas says: 389 //called CanvasHelper::getScaledBitmap, we return NULL, TODO 390 //Exception 'BitmapEx vclcanvas::tools::bitmapExFromXBitmap(const com::sun::star::uno::Reference<com::sun::star::rendering::XBitmap>&), 391 //bitmapExFromXBitmap(): could not extract BitmapEx' thrown 392 // 393 //vcl-canvas says: 394 //Exception 'BitmapEx vclcanvas::tools::bitmapExFromXBitmap(const com::sun::star::uno::Reference<com::sun::star::rendering::XBitmap>&), 395 //bitmapExFromXBitmap(): could not extract bitmap' thrown 396 // Thorsten says that this is a bug, and Thorsten never lies. 397 398 maRenderState = maOldRenderState; // pop 399 } 400 401 void drawLines() 402 { 403 rendering::RenderState maOldRenderState = maRenderState; // push 404 translate( maBox.Width(), maBox.Height() ); 405 406 drawTitle( ::rtl::OString( "Lines" ) ); 407 408 drawPolishDiamond( 70.0, 80.0 ); 409 drawHilbert( 140.0, 140.0 ); 410 411 maRenderState = maOldRenderState; // pop 412 } 413 414 void drawCurves() 415 { 416 rendering::RenderState maOldRenderState = maRenderState; // push 417 translate( maBox.Width() * 2.0, maBox.Height() ); 418 419 drawTitle( ::rtl::OString( "Curves" ) ); 420 421 translate( maBox.Width() * .5, maBox.Height() * .5 ); 422 423 const double r= 30.0; 424 const int num_curves = 3; 425 426 //hacky hack hack 427 uno::Sequence< geometry::RealBezierSegment2D > aBeziers (num_curves); 428 uno::Reference< rendering::XBezierPolyPolygon2D > xPoly; 429 430 for (int i= 0; i < num_curves; i++) 431 aBeziers[i]= geometry::RealBezierSegment2D( r * cos(i*2*M_PI/num_curves), //Px 432 r * sin(i*2*M_PI/num_curves), //py 433 r * 2 * cos((i*2*M_PI + 2*M_PI)/num_curves), //C1x 434 r * 2 * sin((i*2*M_PI + 2*M_PI)/num_curves), //C1y 435 r * 2 * cos((i*2*M_PI + 2*M_PI)/num_curves), //C2x 436 r * 2 * sin((i*2*M_PI + 2*M_PI)/num_curves)); //C2y 437 uno::Sequence< uno::Sequence< geometry::RealBezierSegment2D > > aPolys(1); 438 aPolys[0] = aBeziers; 439 xPoly = mxDevice->createCompatibleBezierPolyPolygon(aPolys); 440 xPoly->setClosed( 0, true ); 441 //uno::Reference< rendering::XBezierPolyPolygon2D> xPP( xPoly, uno::UNO_QUERY ); 442 //compiles, but totally screws up. I think it is interpretting the bezier as a line 443 uno::Reference< rendering::XPolyPolygon2D> xPP( xPoly, uno::UNO_QUERY ); 444 445 rendering::StrokeAttributes aStrokeAttrs; 446 aStrokeAttrs.StrokeWidth = 4.0; 447 aStrokeAttrs.MiterLimit = 2.0; // ? 448 aStrokeAttrs.StartCapType = rendering::PathCapType::BUTT; 449 aStrokeAttrs.EndCapType = rendering::PathCapType::BUTT; 450 aStrokeAttrs.JoinType = rendering::PathJoinType::MITER; 451 mxCanvas->strokePolyPolygon( xPP, maViewState, maRenderState, aStrokeAttrs ); 452 //you can't draw a BezierPolyPolygon2D with this, even though it is derived from it 453 //mxCanvas->drawPolyPolygon( xPP, maViewState, maRenderState ); 454 455 maRenderState = maOldRenderState; // pop 456 } 457 458 double gimmerand() 459 { 460 return (double)(rand()) / RAND_MAX * 100 + 50; 461 } 462 463 void drawArcs() 464 { 465 rendering::RenderState maOldRenderState = maRenderState; // push 466 translate( 0.0, maBox.Height() * 2.0 ); 467 468 drawTitle( ::rtl::OString( "Arcs" ) ); 469 470 471 //begin hacks 472 //This stuff doesn't belong here, but probably in curves 473 //This stuff doesn't work in VCL b/c vcl doesn't do beziers 474 //Hah! Everytime the window redraws, we do this 475 double ax; 476 double ay; 477 double bx; 478 double by; 479 bx= gimmerand(); 480 by= gimmerand(); 481 482 for (int i= 0; i < 1; i++) 483 { 484 //point a= point b; 485 ax= bx; 486 ay= by; 487 //point b= rand; 488 bx= gimmerand(); 489 by= gimmerand(); 490 double c1x= gimmerand(); 491 double c1y= gimmerand(); 492 double c2x= gimmerand(); 493 double c2y= gimmerand(); 494 maRenderState.DeviceColor = maColorRed; 495 mxCanvas->drawLine(geometry::RealPoint2D(ax, ay), geometry::RealPoint2D(c1x, c1y), maViewState, maRenderState); 496 mxCanvas->drawLine(geometry::RealPoint2D(c1x, c1y), geometry::RealPoint2D(c2x, c2y), maViewState, maRenderState); 497 mxCanvas->drawLine(geometry::RealPoint2D(bx, by), geometry::RealPoint2D(c2x, c2y), maViewState, maRenderState); 498 //draw from a to b 499 geometry::RealBezierSegment2D aBezierSegment( 500 ax, //Px 501 ay, //Py 502 c1x, 503 c1x, 504 c2x, 505 c2y 506 ); 507 geometry::RealPoint2D aEndPoint(bx, by); 508 maRenderState.DeviceColor = maColorBlack; 509 mxCanvas->drawBezier( 510 aBezierSegment, 511 aEndPoint, 512 maViewState, maRenderState ); 513 } 514 maRenderState = maOldRenderState; // pop 515 } 516 517 518 void drawRegularPolygon(double centerx, double centery, int sides, double r) 519 { 520 //hacky hack hack 521 uno::Sequence< geometry::RealPoint2D > aPoints (sides); 522 uno::Reference< rendering::XLinePolyPolygon2D > xPoly; 523 524 for (int i= 0; i < sides; i++) 525 { 526 aPoints[i]= geometry::RealPoint2D( centerx + r * cos(i*2 * M_PI/sides), 527 centery + r * sin(i*2 * M_PI/sides)); 528 } 529 uno::Sequence< uno::Sequence< geometry::RealPoint2D > > aPolys(1); 530 aPolys[0] = aPoints; 531 xPoly = mxDevice->createCompatibleLinePolyPolygon( aPolys ); 532 xPoly->setClosed( 0, true ); 533 rendering::RenderState aRenderState( maRenderState ); 534 aRenderState.DeviceColor = maColorRed; 535 uno::Reference< rendering::XPolyPolygon2D> xPP( xPoly, uno::UNO_QUERY ); 536 mxCanvas->drawPolyPolygon( xPP, maViewState, aRenderState); 537 mxCanvas->fillPolyPolygon( xPP, 538 maViewState, 539 aRenderState ); 540 } 541 542 void drawPolygons() 543 { 544 rendering::RenderState maOldRenderState = maRenderState; // push 545 translate( maBox.Width() * 1.0, maBox.Height() * 2.0 ); 546 547 drawTitle( ::rtl::OString( "Polgyons" ) ); 548 549 int sides= 3; 550 for (int i= 1; i <= 4; i++) 551 { 552 drawRegularPolygon(35*i, 35, sides, 15); 553 sides++; 554 } 555 556 maRenderState = maOldRenderState; // pop 557 } 558 559 void drawWidgets() // FIXME: prolly makes no sense 560 { 561 rendering::RenderState maOldRenderState = maRenderState; // push 562 translate( maBox.Width() * 2.0, maBox.Height() * 2.0 ); 563 564 drawTitle( ::rtl::OString( "Widgets" ) ); 565 566 maRenderState = maOldRenderState; // pop 567 } 568 }; 569 570 571 void TestWindow::Paint( const Rectangle& /*rRect*/ ) 572 { 573 try 574 { 575 const Size aVDevSize(300,300); 576 VirtualDevice aVDev(*this); 577 aVDev.SetOutputSizePixel(aVDevSize); 578 uno::Reference< rendering::XCanvas > xVDevCanvas( aVDev.GetCanvas(), 579 uno::UNO_QUERY_THROW ); 580 uno::Reference< rendering::XGraphicDevice > xVDevDevice( xVDevCanvas->getDevice(), 581 uno::UNO_QUERY_THROW ); 582 DemoRenderer aVDevRenderer( xVDevDevice, xVDevCanvas, aVDevSize); 583 xVDevCanvas->clear(); 584 aVDevRenderer.drawGrid(); 585 aVDevRenderer.drawRectangles(); 586 aVDevRenderer.drawEllipses(); 587 aVDevRenderer.drawText(); 588 aVDevRenderer.drawLines(); 589 aVDevRenderer.drawCurves(); 590 aVDevRenderer.drawArcs(); 591 aVDevRenderer.drawPolygons(); 592 593 uno::Reference< rendering::XCanvas > xCanvas( GetSpriteCanvas(), 594 uno::UNO_QUERY_THROW ); 595 uno::Reference< rendering::XGraphicDevice > xDevice( xCanvas->getDevice(), 596 uno::UNO_QUERY_THROW ); 597 598 DemoRenderer aRenderer( xDevice, xCanvas, GetSizePixel() ); 599 xCanvas->clear(); 600 aRenderer.drawGrid(); 601 aRenderer.drawRectangles(); 602 aRenderer.drawEllipses(); 603 aRenderer.drawText(); 604 aRenderer.drawLines(); 605 aRenderer.drawCurves(); 606 aRenderer.drawArcs(); 607 aRenderer.drawPolygons(); 608 aRenderer.drawWidgets(); 609 aRenderer.drawImages(); 610 611 // check whether virdev actually contained something 612 uno::Reference< rendering::XBitmap > xBitmap(xVDevCanvas, uno::UNO_QUERY); 613 if( !xBitmap.is() ) 614 return; 615 616 aRenderer.maRenderState.AffineTransform.m02 += 100; 617 aRenderer.maRenderState.AffineTransform.m12 += 100; 618 xCanvas->drawBitmap(xBitmap, aRenderer.maViewState, aRenderer.maRenderState); 619 620 uno::Reference< rendering::XSpriteCanvas > xSpriteCanvas( xCanvas, 621 uno::UNO_QUERY ); 622 if( xSpriteCanvas.is() ) 623 xSpriteCanvas->updateScreen( sal_True ); // without 624 // updateScreen(), 625 // nothing is 626 // visible 627 } 628 catch (const uno::Exception &e) 629 { 630 fprintf( stderr, "Exception '%s' thrown\n" , 631 (const sal_Char *) ::rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_UTF8 ) ); 632 } 633 } 634 635 USHORT DemoApp::Exception( USHORT nError ) 636 { 637 switch( nError & EXC_MAJORTYPE ) 638 { 639 case EXC_RSCNOTLOADED: 640 Abort( String::CreateFromAscii( "Error: could not load language resources.\nPlease check your installation.\n" ) ); 641 break; 642 } 643 return 0; 644 } 645 646 void DemoApp::Main() 647 { 648 bool bHelp = false; 649 650 for( USHORT i = 0; i < GetCommandLineParamCount(); i++ ) 651 { 652 ::rtl::OUString aParam = GetCommandLineParam( i ); 653 654 if( aParam.equalsAscii( "--help" ) || 655 aParam.equalsAscii( "-h" ) ) 656 bHelp = true; 657 } 658 659 if( bHelp ) 660 { 661 PrintHelp(); 662 return; 663 } 664 665 //------------------------------------------------- 666 // create the global service-manager 667 //------------------------------------------------- 668 uno::Reference< lang::XMultiServiceFactory > xFactory; 669 try 670 { 671 uno::Reference< uno::XComponentContext > xCtx = ::cppu::defaultBootstrap_InitialComponentContext(); 672 xFactory = uno::Reference< lang::XMultiServiceFactory >( xCtx->getServiceManager(), 673 uno::UNO_QUERY ); 674 if( xFactory.is() ) 675 ::comphelper::setProcessServiceFactory( xFactory ); 676 } 677 catch( uno::Exception& ) 678 { 679 } 680 681 if( !xFactory.is() ) 682 { 683 fprintf( stderr, "Could not bootstrap UNO, installation must be in disorder. Exiting.\n" ); 684 exit( 1 ); 685 } 686 687 // Create UCB. 688 uno::Sequence< uno::Any > aArgs( 2 ); 689 aArgs[ 0 ] <<= rtl::OUString::createFromAscii( UCB_CONFIGURATION_KEY1_LOCAL ); 690 aArgs[ 1 ] <<= rtl::OUString::createFromAscii( UCB_CONFIGURATION_KEY2_OFFICE ); 691 ::ucbhelper::ContentBroker::initialize( xFactory, aArgs ); 692 693 InitVCL( xFactory ); 694 TestWindow pWindow; 695 pWindow.Execute(); 696 DeInitVCL(); 697 698 // clean up UCB 699 ::ucbhelper::ContentBroker::deinitialize(); 700 } 701 702 DemoApp aDemoApp; 703 704 // TODO 705 // - bouncing clip-rectangle mode - bounce a clip-rect around the window ... 706 // - complete all of pre-existing canvas bits 707 // - affine transform tweakage ... 708 709