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