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