--- canvas/prj/build.lst
+++ canvas/prj/build.lst
@@ -0,8 +1,8 @@
-uc	canvas	:	javaunohelper comphelper cppuhelper offuh unoil tools goodies vcl AGG:agg basegfx NULL
+uc	canvas	:	javaunohelper comphelper cppuhelper offuh unoil tools goodies vcl AGG:agg basegfx CAIRO:cairo NULL
 uc	canvas											 usr1	-	all	uc_mkout NULL
 uc	canvas\source\tools								 nmake	-	all uc_tools NULL
 uc	canvas\source\vcl								 nmake	-	all	uc_vcl uc_tools NULL
-uc	canvas\source\cairo								 nmake	-	u	uc_cairo uc_tools NULL
+uc	canvas\source\cairo								 nmake	-	all	uc_cairo uc_tools NULL
 uc	canvas\source\null								 nmake	-	all	uc_null uc_tools NULL
 uc	canvas\source\java								 nmake	-	all uc_java NULL
 uc	canvas\source\factory							 nmake	-	all uc_factory NULL
dummy line to avoid confusing diff-mode
--- canvas/source/cairo/makefile.mk
+++ canvas/source/cairo/makefile.mk
@@ -79,7 +79,6 @@
 
 # --- Common ----------------------------------------------------------
 
-.IF "$(GUI)"=="UNX"
 
 .IF "$(SYSTEM_CAIRO)" == "YES"
 CFLAGS+=$(CAIRO_CFLAGS)
@@ -108,11 +108,20 @@
 
 SHL1STDLIBS= $(CPPULIB) $(SALLIB) $(VCLLIB) $(COMPHELPERLIB) $(CPPUHELPERLIB) $(BASEGFXLIB) $(CANVASTOOLSLIB) $(TOOLSLIB)
 
+.IF "$(GUI)"=="UNX"
 .IF "$(SYSTEM_CAIRO)" == "YES"
 SHL1STDLIBS+= $(CAIRO_LIBS) -lX11 -lXrender
 .ELSE
 SHL1STDLIBS+= -lcairo -lX11 -lXrender
 .ENDIF
+.ELSE
+.IF "$(GUI)"=="WNT"
+#We build cairo and pixman as separate (static) libs as I couldn't be
+#bothered to dig into the obscure makefile.mk stuff enough to combine
+#them into one as is normally done.
+SHL1STDLIBS+= cairo.lib pixman.lib gdi32.lib
+.ENDIF
+.ENDIF
 
 SHL1IMPLIB=i$(TARGET)
 SHL1LIBS=$(SLB)$/$(TARGET).lib
@@ -127,7 +127,6 @@
 DEF1NAME=$(SHL1TARGET)
 DEF1EXPORTFILE=exports.dxp
 
-.ENDIF
 
 # ==========================================================================
 
dummy line to avoid confusing diff-mode
--- canvas/source/cairo/cairo_cairo.hxx
+++ canvas/source/cairo/cairo_cairo.hxx
@@ -1,6 +1,8 @@
 #ifndef _CAIROCANVAS_CAIRO_HXX
 #define _CAIROCANVAS_CAIRO_HXX
 
+#include <stdio.h>
+
 namespace cairo {
 
 #include <cairo.h>
@@ -15,8 +15,14 @@
 
 	class Surface {
 		const void* mpSysData;
+#ifdef CAIRO_HAS_XLIB_SURFACE
 		void* mpDisplay;
 		long mhDrawable;
 		void *mpRenderFormat;
+#elif defined (CAIRO_HAS_WIN32_SURFACE)
+		enum {NONE, GET, CREATE} meDCKind;
+		void *mhDC;
+		void *mhOrigBitmap;
+#endif
 		int mnRefCount;
 		bool mbFreePixmap;
@@ -23,9 +23,17 @@
 	public:
 		cairo_surface_t* mpSurface;
 
+#ifdef CAIRO_HAS_XLIB_SURFACE
 		Surface( const void* pSysData, void* pDisplay, long hDrawable, void* pRenderFormat, cairo_surface_t* pSurface )
+#elif defined (CAIRO_HAS_WIN32_SURFACE)
+		Surface( const void* pSysData, cairo_surface_t* pSurface )
+#endif
 			: mpSysData( pSysData ),
+#ifdef CAIRO_HAS_XLIB_SURFACE
 			  mpDisplay( pDisplay ),
 			  mhDrawable( hDrawable ),
 			  mpRenderFormat( pRenderFormat ),
+#elif defined (CAIRO_HAS_WIN32_SURFACE)
+			  meDCKind( NONE ),
+#endif
 			  mpSurface( pSurface ),
@@ -36,10 +36,14 @@
 
 		Surface( cairo_surface_t* pSurface )
 			: mpSurface( pSurface ),
+#ifdef CAIRO_HAS_XLIB_SURFACE
 			  mpDisplay( NULL ),
 			  mhDrawable( 0 ),
+			  mpRenderFormat( NULL ),
+#elif defined (CAIRO_HAS_WIN32_SURFACE)
+			  meDCKind( NONE ),
+#endif
 			  mpSysData( NULL ),
-			  mpRenderFormat( NULL ),
 			  mbFreePixmap( false ),
 			  mnRefCount( 1 )
 		{
@@ -82,15 +82,17 @@
 
 		Surface* getSimilar( Content aContent, int width, int height );
 
+#ifdef CAIRO_HAS_XLIB_SURFACE
 		long getPixmap()
 		{
 			return mhDrawable;
 		}
 
 		void* getRenderFormat()
 		{
 			return mpRenderFormat;
 		}
+#endif
 
 		// use only for surfaces made on X Drawables
 		void Resize( int width, int height );
dummy line to avoid confusing diff-mode
--- canvas/source/cairo/cairo_cairo.cxx
+++ canvas/source/cairo/cairo_cairo.cxx
@@ -1,21 +1,52 @@
+#ifndef WNT
 #include <X11/extensions/Xrender.h>
 #include <X11/Xlib.h>
+#endif
 #include "cairo_cairo.hxx"
+#ifdef CAIRO_HAS_XLIB_SURFACE
 #include "cairo_helper.hxx"
+#endif
 
+#ifdef CAIRO_HAS_WIN32_SURFACE
+#include <tools/prewin.h>
+#include <windows.h> 
+#include <tools/postwin.h>
+#ifndef _SV_SYSDATA_HXX
+#include <vcl/sysdata.hxx>
+#endif
+#ifndef _SV_BITMAP_HXX
+#include <vcl/bitmap.hxx>
+#endif
+#endif
+
 namespace cairo
 {
 
+#ifdef CAIRO_HAS_XLIB_SURFACE
 #include <cairo-xlib.h>
 #include <cairo-xlib-xrender.h>
+#elif defined (CAIRO_HAS_WIN32_SURFACE)
+#include <cairo-win32.h>
+#endif
  
 	Surface::Surface( const void* pSysData, int x, int y, int width, int height )
 		: mnRefCount( 1 ),
 		  mpSysData( pSysData ),
 		  mbFreePixmap( false )
 	{
+#ifdef CAIRO_HAS_XLIB_SURFACE
 		mpSurface = (cairo_surface_t*) cairoHelperGetSurface( pSysData, x, y, width, height );
 		mpDisplay = (Display*) cairoHelperGetDisplay( pSysData );
 		mhDrawable = cairoHelperGetWindow( pSysData );
+#elif defined (CAIRO_HAS_WIN32_SURFACE)
+		HDC hDC;
+		const SystemEnvData* p_SysData = (const SystemEnvData*) pSysData;
+
+		meDCKind = GET;
+		hDC = GetDC( p_SysData->hWnd );
+		mhDC = (void*) hDC;
+		mpSurface = cairo_win32_surface_create( hDC );
+		cairo_surface_set_device_offset( mpSurface, x, y );
+#endif
 	}
 
@@ -25,7 +25,52 @@
 		  mbFreePixmap( false )
 	{
+#ifdef CAIRO_HAS_XLIB_SURFACE
 		mpSurface = (cairo_surface_t*) cairoHelperGetSurface( pSysData, pBmpData, width, height );
 		mpDisplay = (Display*) cairoHelperGetDisplay( pSysData );
 		mhDrawable = cairoHelperGetWindow( pSysData );
+#elif defined (CAIRO_HAS_WIN32_SURFACE)
+		const BitmapSystemData* p_BmpData = (const BitmapSystemData*) pBmpData;
+
+		OSL_ASSERT (p_BmpData->pDIB == NULL);
+		if (p_BmpData->pDIB != NULL) {
+#if 0
+			// This code will not work anyway, as most (?) DIBs that
+			// come here will be in bottom-down order (upside-down)
+			// and in any case have a different order of colour
+			// channels compared to what cairo expects.
+			PBITMAPINFOHEADER pBIH = (PBITMAPINFOHEADER) GlobalLock ((HANDLE) p_BmpData->pDIB);
+			cairo_format_t fmt;
+			OSL_ASSERT (pBIH->biBitCount == 24 && pBIH->biCompression == BI_RGB);
+			meDCKind = DIB;
+			mhDIB = p_BmpData->pDIB;
+			if (pBIH->biBitCount == 24 && pBIH->biCompression == BI_RGB) {
+				mpSurface = cairo_image_surface_create_for_data (((unsigned char *) pBIH) + pBIH->biSize,
+																 CAIRO_FORMAT_RGB24,
+																 pBIH->biWidth, pBIH->biHeight,
+																 4*((3*pBIH->biWidth-1)/4+1));
+			} else {
+				mpSurface = NULL;
+			}
+#else
+			// So just set mpSurface to NULL, little else we can do at
+			// this stage. Hopefully the Win32 patch to
+			// cairocanvas::DeviceHelper::getSurface(BitmapSystemData&,
+			// const Size&) will catch the cases where this
+			// constructor would be called with a DIB bitmap, and we
+			// will never get here. At least it worked for Ballmer.ppt.
+			mpSurface = NULL;
+#endif
+		} else {
+			HDC hDC;
+			meDCKind = CREATE;
+			hDC = CreateCompatibleDC( NULL );
+			mhDC = (void*) hDC;
+			OSL_TRACE ("::cairo::cairo::Surface::Surface(): Selecting bitmap %p into DC %p\n", p_BmpData->pDDB, hDC);
+			mhOrigBitmap = SelectObject( hDC, (HANDLE) p_BmpData->pDDB );
+			if (mhOrigBitmap == NULL)
+				OSL_TRACE ("SelectObject failed: %d\n", GetLastError ());
+			mpSurface = cairo_win32_surface_create( hDC );
+		}
+#endif
 	}
 
@@ -38,54 +38,106 @@
 			mpSurface = NULL;
 		}
+#ifdef CAIRO_HAS_XLIB_SURFACE
 		if( mbFreePixmap && mhDrawable )
 			XFreePixmap( (Display*) mpDisplay, mhDrawable );
+#elif defined (CAIRO_HAS_WIN32_SURFACE)
+		if (meDCKind == GET) {
+			ReleaseDC( ((const SystemEnvData*) mpSysData)->hWnd, (HDC) mhDC );
+		} else if (meDCKind == CREATE) {
+			SelectObject( (HDC) mhDC, (HGDIOBJ) mhOrigBitmap );
+			DeleteDC( (HDC) mhDC );
+#if 0
+		} else if (meDCKind == DIB) {
+			GlobalUnlock ((HANDLE) mhDIB);
+#endif
+		}
+#endif
 	}
 
 	Surface* Surface::getSimilar( Content aContent, int width, int height )
 	{
+#ifdef CAIRO_HAS_XLIB_SURFACE
 		Pixmap hPixmap;
 
 		if( mpSysData && mpDisplay && mhDrawable ) {
 			XRenderPictFormat *pFormat;
 			int	nFormat;
+#elif defined (CAIRO_HAS_WIN32_SURFACE)
+		if( mpSysData ) {
+			Format	nFormat;
+#endif
 
 			switch (aContent) {
 			case CAIRO_CONTENT_ALPHA:
+#ifdef CAIRO_HAS_XLIB_SURFACE
 				nFormat = PictStandardA8;
+#elif defined (CAIRO_HAS_WIN32_SURFACE)
+				nFormat = CAIRO_FORMAT_A8;
+#endif
 				break;
 			case CAIRO_CONTENT_COLOR:
+#ifdef CAIRO_HAS_XLIB_SURFACE
 				nFormat = PictStandardRGB24;
+#elif defined (CAIRO_HAS_WIN32_SURFACE)
+				nFormat = CAIRO_FORMAT_RGB24;
+#endif
 				break;
 			case CAIRO_CONTENT_COLOR_ALPHA:
 			default:
+#ifdef CAIRO_HAS_XLIB_SURFACE
 				nFormat = PictStandardARGB32;
+#elif defined (CAIRO_HAS_WIN32_SURFACE)
+				nFormat = CAIRO_FORMAT_ARGB32;
+#endif
 				break;
 			}
 
+#ifdef CAIRO_HAS_XLIB_SURFACE
 			pFormat = XRenderFindStandardFormat( (Display*) mpDisplay, nFormat );
 			hPixmap = XCreatePixmap( (Display*) mpDisplay, cairoHelperGetWindow( mpSysData ),
 									 width > 0 ? width : 1, height > 0 ? height : 1,
 									 pFormat->depth );
 
 			return new Surface( mpSysData, mpDisplay, (long) hPixmap, pFormat,
 								cairo_xlib_surface_create_with_xrender_format( (Display*) mpDisplay, hPixmap,
 																			   DefaultScreenOfDisplay( (Display *) mpDisplay ),
 																			   pFormat, width, height ) );
+#elif defined (CAIRO_HAS_WIN32_SURFACE)
+			return new Surface( mpSysData, cairo_win32_surface_create_with_dib( nFormat, width, height ) );
+#endif
 		} else
+#ifdef CAIRO_HAS_XLIB_SURFACE
 			return new Surface( mpSysData, mpDisplay, 0, NULL, cairo_surface_create_similar( mpSurface, aContent, width, height ) );
+#elif defined (CAIRO_HAS_WIN32_SURFACE)
+			return new Surface( mpSysData, cairo_surface_create_similar( mpSurface, aContent, width, height ) );
+#endif
 	}
 
 	void
 	Surface::Resize( int width, int height )
 	{
+#ifdef CAIRO_HAS_XLIB_SURFACE
 		cairo_xlib_surface_set_size( mpSurface, width, height );
+#elif defined (CAIRO_HAS_WIN32_SURFACE)
+#endif
 	}
 
 	int
 	Surface::getDepth()
 	{
+#ifdef CAIRO_HAS_XLIB_SURFACE
 		if( mpRenderFormat )
 			return ( ( XRenderPictFormat * ) mpRenderFormat )->depth;
+#elif defined (CAIRO_HAS_WIN32_SURFACE)
+		switch (cairo_surface_get_content (mpSurface)) {
+		case CAIRO_CONTENT_COLOR:
+			return 24;
+		case CAIRO_CONTENT_ALPHA:
+			return 8;
+		case CAIRO_CONTENT_COLOR_ALPHA:
+			return 32;
+		}
+#endif
 
 		return -1;
 	}
dummy line to avoid confusing diff-mode
--- canvas/source/cairo/cairo_canvashelper.cxx
+++ canvas/source/cairo/cairo_canvashelper.cxx
@@ -156,14 +156,14 @@
         if( viewState.Clip.is() ) {
 	    OSL_TRACE ("view clip\n");
 
-	    aViewMatrix.x0 = round( aViewMatrix.x0 );
-	    aViewMatrix.y0 = round( aViewMatrix.y0 );
+	    aViewMatrix.x0 = ::rtl::math::round( aViewMatrix.x0 );
+	    aViewMatrix.y0 = ::rtl::math::round( aViewMatrix.y0 );
 	    cairo_set_matrix( mpCairo, &aViewMatrix );
 	    doPolyPolygonPath( viewState.Clip, Clip );
 	}
 
-	aCombinedMatrix.x0 = round( aCombinedMatrix.x0 );
-	aCombinedMatrix.y0 = round( aCombinedMatrix.y0 );
+	aCombinedMatrix.x0 = ::rtl::math::round( aCombinedMatrix.x0 );
+	aCombinedMatrix.y0 = ::rtl::math::round( aCombinedMatrix.y0 );
 	cairo_set_matrix( mpCairo, &aCombinedMatrix );
 
         if( renderState.Clip.is() ) {
@@ -614,8 +614,8 @@
  			if( aTexture.RepeatModeX == rendering::TexturingMode::REPEAT &&
 			    aTexture.RepeatModeY == rendering::TexturingMode::REPEAT )
 			    cairo_pattern_set_extend( pPattern, CAIRO_EXTEND_REPEAT );
-			aScaledTextureMatrix.x0 = round( aScaledTextureMatrix.x0 );
-			aScaledTextureMatrix.y0 = round( aScaledTextureMatrix.y0 );
+			aScaledTextureMatrix.x0 = ::rtl::math::round( aScaledTextureMatrix.x0 );
+			aScaledTextureMatrix.y0 = ::rtl::math::round( aScaledTextureMatrix.y0 );
 			cairo_pattern_set_matrix( pPattern, &aScaledTextureMatrix );
 
 			cairo_set_source( pCairo, pPattern );
@@ -741,8 +741,8 @@
 		cairo_matrix_transform_point( &aOrigMatrix, &nX, &nY );
 
 		if( ! bIsBezier ) {
-		    nX = round( nX );
-		    nY = round( nY );
+		    nX = ::rtl::math::round( nX );
+		    nY = ::rtl::math::round( nY );
 		}
 
 		if( aOperation == Stroke ) {
@@ -766,8 +766,8 @@
 		    cairo_matrix_transform_point( &aOrigMatrix, &nX, &nY );
 
 		    if( ! bIsBezier ) {
-			nX = round( nX );
-			nY = round( nY );
+			nX = ::rtl::math::round( nX );
+			nY = ::rtl::math::round( nY );
 		    }
 
 		    if( aOperation == Stroke ) {
@@ -1058,13 +1058,13 @@
 				! ::rtl::math::approxEqual( aMatrix.yy, 1 ) &&
 				::rtl::math::approxEqual( aMatrix.x0, 0 ) &&
 				::rtl::math::approxEqual( aMatrix.y0, 0 ) &&
-				round( rSize.Width * aMatrix.xx ) > 8 &&
-				round( rSize.Height* aMatrix.yy ) > 8 )
+				::rtl::math::round( rSize.Width * aMatrix.xx ) > 8 &&
+				::rtl::math::round( rSize.Height* aMatrix.yy ) > 8 )
 				{
 					double dWidth, dHeight;
 
-					dWidth = round( rSize.Width * aMatrix.xx );
-					dHeight = round( rSize.Height* aMatrix.yy );
+					dWidth = ::rtl::math::round( rSize.Width * aMatrix.xx );
+					dHeight = ::rtl::math::round( rSize.Height* aMatrix.yy );
                                         aBitmapSize.Width = static_cast<sal_Int32>( dWidth );
                                         aBitmapSize.Height = static_cast<sal_Int32>( dHeight );
 
dummy line to avoid confusing diff-mode
--- canvas/source/cairo/cairo_canvashelper_text.cxx
+++ canvas/source/cairo/cairo_canvashelper_text.cxx
@@ -37,6 +37,16 @@
 #include <canvas/canvastools.hxx>
 
 #include <vcl/virdev.hxx>
+#ifdef WNT
+#include <tools/prewin.h>
+#include <windows.h> 
+#include <tools/postwin.h>
+namespace cairo
+{
+#include <cairo.h>
+#include <cairo-win32.h>
+}
+#endif
 #include <vcl/sysdata.hxx>
 #include <vcl/metric.hxx>
 #include <vcl/canvastools.hxx>
@@ -87,8 +87,12 @@
 		SystemGraphicsData aSystemGraphicsData;
 
 		aSystemGraphicsData.nSize = sizeof(SystemGraphicsData);
+#ifdef CAIRO_HAS_XLIB_SURFACE
 		aSystemGraphicsData.hDrawable = pSurface->getPixmap();
 		aSystemGraphicsData.pRenderFormat = pSurface->getRenderFormat();
+#elif defined (CAIRO_HAS_WIN32_SURFACE)
+		aSystemGraphicsData.hDC = cairo_win32_surface_get_dc(pSurface->mpSurface);
+#endif
 
 		return new VirtualDevice( &aSystemGraphicsData, pSurface->getDepth() );
 	}
@@ -129,7 +129,7 @@
 			io_rVCLFont.SetHeight( ::basegfx::fround(nFontHeight * aScale.getY()) );
 		}
 
-		io_rVCLFont.SetOrientation( static_cast< short >( ::basegfx::fround(-fmod(nRotate, 2*M_PI)*(1800.0/M_PI)) ) );
+		io_rVCLFont.SetOrientation( static_cast< short >( ::basegfx::fround(-fmod(nRotate, 2*F_PI)*(1800.0/F_PI)) ) );
 
 		// TODO(F2): Missing functionality in VCL: shearing
 		o_rPoint.X() = ::basegfx::fround(aTranslate.getX());
dummy line to avoid confusing diff-mode
--- canvas/source/cairo/cairo_helper.cxx
+++ canvas/source/cairo/cairo_helper.cxx
@@ -1,17 +1,20 @@
+#include <cairo.h>
+
+#ifdef CAIRO_HAS_XLIB_SURFACE
+
 #ifndef _SV_SYSDATA_HXX
 #include <vcl/sysdata.hxx>
 #endif
 
 #ifndef _SV_BITMAP_HXX
 #include <vcl/bitmap.hxx>
 #endif
 
 namespace cairo {
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
 
-#include <cairo.h>
 #include <cairo-xlib.h>
 
 #ifdef CAIRO_HAS_GLITZ_SURFACE
 #include <GL/glx.h>
@@ -223,3 +223,5 @@
 	OSL_TRACE("depth: %d", ((const SystemEnvData*) pSysData)->nDepth);
 	return ((const SystemEnvData*) pSysData)->nDepth;
 }
+
+#endif // CAIRO_HAS_XLIB_SURFACE
dummy line to avoid confusing diff-mode
--- canvas/source/cairo/cairo_devicehelper.cxx
+++ canvas/source/cairo/cairo_devicehelper.cxx
@@ -384,6 +384,8 @@
 
     void DeviceHelper::flush()
     {
+#ifdef CAIRO_HAS_XLIB_SURFACE
 	cairoHelperFlush( mpSysData );
+#endif
     }
 }
dummy line to avoid confusing diff-mode
--- canvas/source/cairo/cairo_spritehelper.cxx
+++ canvas/source/cairo/cairo_spritehelper.cxx
@@ -135,8 +135,8 @@
  				       aTransform.get( 0, 0 ), aTransform.get( 1, 0 ), aTransform.get( 0, 1 ),
  				       aTransform.get( 1, 1 ), aTransform.get( 0, 2 ), aTransform.get( 1, 2 ) );
 
- 		    aMatrix.x0 = round( aMatrix.x0 );
- 		    aMatrix.y0 = round( aMatrix.y0 );
+ 		    aMatrix.x0 = ::rtl::math::round( aMatrix.x0 );
+ 		    aMatrix.y0 = ::rtl::math::round( aMatrix.y0 );
 
 		    cairo_matrix_init( &aInverseMatrix, aMatrix.xx, aMatrix.yx, aMatrix.xy, aMatrix.yy, aMatrix.x0, aMatrix.y0 );
 		    cairo_matrix_invert( &aInverseMatrix );
@@ -145,8 +145,8 @@
  		    cairo_set_matrix( pCairo, &aMatrix );
  		}
 
- 		fX = round( fX );
- 		fY = round( fY );
+ 		fX = ::rtl::math::round( fX );
+ 		fY = ::rtl::math::round( fY );
 
 		cairo_matrix_t aOrigMatrix;
 		cairo_get_matrix( pCairo, &aOrigMatrix );
dummy line to avoid confusing diff-mode
