[Libreoffice-commits] core.git: 2 commits - canvas/source include/vcl vcl/inc vcl/Library_vcl.mk vcl/quartz vcl/source vcl/win

Jan Holesovsky kendy at collabora.com
Fri Jun 5 05:01:28 PDT 2015


 canvas/source/cairo/cairo_textlayout.cxx |   97 ++++++++++++++++++++-
 include/vcl/sysdata.hxx                  |   16 +--
 vcl/Library_vcl.mk                       |    2 
 vcl/inc/quartz/salgdi.h                  |    6 +
 vcl/inc/salgdi.hxx                       |    9 --
 vcl/inc/win/salgdi.h                     |    6 +
 vcl/quartz/salgdi.cxx                    |   10 ++
 vcl/quartz/salgdicommon.cxx              |  118 ++++++++++++++++++++++++++
 vcl/source/outdev/font.cxx               |    4 
 vcl/source/outdev/outdev.cxx             |    9 +-
 vcl/win/source/gdi/salgdi.cxx            |  139 +++++++++++++++++++++++++++++++
 vcl/win/source/gdi/salgdi3.cxx           |   15 +++
 12 files changed, 402 insertions(+), 29 deletions(-)

New commits:
commit d79fa4ee0fd5b6e9787838f74cc45c9c9b93a5b3
Author: Jan Holesovsky <kendy at collabora.com>
Date:   Fri Jun 5 14:00:34 2015 +0200

    Revert "Cleanup crossplatform cairo"
    
    Unfortunately this breaks Android and iOS.
    
    This reverts commit e4d55e8045c99af65a2cae57b26ec076825c9673.

diff --git a/canvas/source/cairo/cairo_textlayout.cxx b/canvas/source/cairo/cairo_textlayout.cxx
index 570daaf..03d31947 100644
--- a/canvas/source/cairo/cairo_textlayout.cxx
+++ b/canvas/source/cairo/cairo_textlayout.cxx
@@ -26,6 +26,15 @@
 
 #include <vcl/metric.hxx>
 #include <vcl/virdev.hxx>
+
+#ifdef WNT
+#ifdef max
+#undef max
+#endif
+#ifdef min
+#undef min
+#endif
+#endif
 #include <vcl/sysdata.hxx>
 
 #include <basegfx/matrix/b2dhommatrix.hxx>
@@ -36,12 +45,21 @@
 #include "cairo_textlayout.hxx"
 #include "cairo_spritecanvas.hxx"
 
-#if defined CAIRO_HAS_FT_FONT
+#ifdef CAIRO_HAS_QUARTZ_SURFACE
+#include <cairo-quartz.h>
+#elif defined CAIRO_HAS_WIN32_SURFACE
+# include "cairo_win32_cairo.hxx"
+# include <cairo-win32.h>
+#elif defined CAIRO_HAS_FT_FONT
 # include <cairo-ft.h>
 #else
 # error Native API needed.
 #endif
 
+#ifdef IOS
+#include <CoreText/CoreText.h>
+#endif
+
 using namespace ::cairo;
 using namespace ::com::sun::star;
 
@@ -291,7 +309,7 @@ namespace cairocanvas
    **/
     bool TextLayout::isCairoRenderable(SystemFontData aSysFontData) const
     {
-#if defined CAIRO_HAS_FT_FONT
+#if defined UNX && !defined MACOSX && !defined IOS
         // is font usable?
         if (!aSysFontData.nFontId)
             return false;
@@ -307,6 +325,46 @@ namespace cairocanvas
         return true;
     }
 
+#ifdef CAIRO_HAS_WIN32_SURFACE
+    namespace
+    {
+        /**
+         * cairo::ucs4toindex: Convert ucs4 char to glyph index
+         * @param ucs4 an ucs4 char
+         * @param hfont current font
+         *
+         * @return true if successful
+         **/
+        unsigned long ucs4toindex(unsigned int ucs4, HFONT hfont)
+        {
+            wchar_t unicode[2];
+            WORD glyph_index;
+            HDC hdc = NULL;
+
+            hdc = CreateCompatibleDC (NULL);
+
+            if (!hdc) return 0;
+            if (!SetGraphicsMode (hdc, GM_ADVANCED))
+            {
+                DeleteDC (hdc);
+                return 0;
+            }
+
+            SelectObject (hdc, hfont);
+            SetMapMode (hdc, MM_TEXT);
+
+            unicode[0] = ucs4;
+            unicode[1] = 0;
+            if (GetGlyphIndicesW (hdc, unicode, 1, &glyph_index, 0) == GDI_ERROR)
+            {
+                glyph_index = 0;
+            }
+
+            DeleteDC (hdc);
+            return glyph_index;
+        }
+    }
+#endif
 
   /**
    * TextLayout::draw
@@ -327,6 +385,9 @@ namespace cairocanvas
     {
         ::osl::MutexGuard aGuard( m_aMutex );
         SystemTextLayoutData aSysLayoutData;
+#if (defined CAIRO_HAS_WIN32_SURFACE) && (OSL_DEBUG_LEVEL > 1)
+        LOGFONTW logfont;
+#endif
         setupLayoutMode( rOutDev, mnTextDirection );
 
         // TODO(P2): cache that
@@ -423,6 +484,11 @@ namespace cairocanvas
 
                 cairo_glyph_t aGlyph;
                 aGlyph.index = systemGlyph.index;
+#ifdef CAIRO_HAS_WIN32_SURFACE
+                // Cairo requires standard glyph indexes (ETO_GLYPH_INDEX), while vcl/win/* uses ucs4 chars.
+                // Convert to standard indexes
+                aGlyph.index = ucs4toindex((unsigned int) aGlyph.index, rSysFontData.hFont);
+#endif
                 aGlyph.x = systemGlyph.x;
                 aGlyph.y = systemGlyph.y;
                 cairo_glyphs.push_back(aGlyph);
@@ -436,7 +502,24 @@ namespace cairocanvas
              **/
             cairo_font_face_t* font_face = NULL;
 
-#if defined CAIRO_HAS_FT_FONT
+#ifdef CAIRO_HAS_QUARTZ_SURFACE
+# ifdef MACOSX
+            // TODO: use cairo_quartz_font_face_create_for_cgfont(cgFont)
+            //       when CGFont (Mac OS X 10.5 API) is provided by the AQUA VCL backend.
+            font_face = cairo_quartz_font_face_create_for_atsu_font_id((ATSUFontID) rSysFontData.aATSUFontID);
+# else // iOS
+            font_face = cairo_quartz_font_face_create_for_cgfont( CTFontCopyGraphicsFont( rSysFontData.rCTFont, NULL ) );
+# endif
+
+#elif defined CAIRO_HAS_WIN32_SURFACE
+# if (OSL_DEBUG_LEVEL > 1)
+            GetObjectW( rSysFontData.hFont, sizeof(logfont), &logfont );
+# endif
+            // Note: cairo library uses logfont fallbacks when lfEscapement, lfOrientation and lfWidth are not zero.
+            // VCL always has non-zero value for lfWidth
+            font_face = cairo_win32_font_face_create_for_hfont(rSysFontData.hFont);
+
+#elif defined CAIRO_HAS_FT_FONT
             font_face = cairo_ft_font_face_create_for_ft_face(static_cast<FT_Face>(rSysFontData.nFontId),
                                                               rSysFontData.nFontFlags);
 #else
@@ -484,6 +567,11 @@ namespace cairocanvas
 
             cairo_set_font_matrix(pSCairo.get(), &m);
 
+#if (defined CAIRO_HAS_WIN32_SURFACE) && (OSL_DEBUG_LEVEL > 1)
+# define TEMP_TRACE_FONT OUString(reinterpret_cast<const sal_Unicode*> (logfont.lfFaceName))
+#else
+# define TEMP_TRACE_FONT aFont.GetName()
+#endif
             SAL_INFO(
                 "canvas.cairo",
                 "Size:(" << aFont.GetWidth() << "," << aFont.GetHeight()
@@ -498,8 +586,9 @@ namespace cairocanvas
                     << (rSysFontData.bAntialias ? "AA " : "")
                     << (rSysFontData.bFakeBold ? "FB " : "")
                     << (rSysFontData.bFakeItalic ? "FI " : "") << " || Name:"
-                    << aFont.GetName() << " - "
+                    << TEMP_TRACE_FONT << " - "
                     << maText.Text.copy(maText.StartPosition, maText.Length));
+#undef TEMP_TRACE_FONT
 
             cairo_show_glyphs(pSCairo.get(), &cairo_glyphs[0], cairo_glyphs.size());
 
diff --git a/include/vcl/sysdata.hxx b/include/vcl/sysdata.hxx
index 57217df..a525f77 100644
--- a/include/vcl/sysdata.hxx
+++ b/include/vcl/sysdata.hxx
@@ -23,8 +23,6 @@
 #include <vector>
 #include <cstddef>
 
-#include <config_cairo_canvas.h>
-
 #ifdef MACOSX
 // predeclare the native classes to avoid header/include problems
 typedef struct CGContext *CGContextRef;
@@ -202,12 +200,13 @@ struct SystemGlyphData
     int                  fallbacklevel;
 };
 
-#if ENABLE_CAIRO_CANVAS
-
 struct SystemFontData
 {
     unsigned long   nSize;          // size in bytes of this structure
-#if defined( UNX )
+#if defined( WNT )
+    HFONT           hFont;          // native font object
+#elif defined( MACOSX )
+#elif defined( UNX )
     void*           nFontId;        // native font id
     int             nFontFlags;     // native font flags
 #endif
@@ -218,7 +217,10 @@ struct SystemFontData
 
     SystemFontData()
         : nSize( sizeof( SystemFontData ) )
-#if defined( UNX )
+#if defined( WNT )
+        , hFont( 0 )
+#elif defined( MACOSX )
+#elif defined( UNX )
         , nFontId( NULL )
         , nFontFlags( 0 )
 #endif
@@ -230,8 +232,6 @@ struct SystemFontData
     }
 };
 
-#endif // ENABLE_CAIRO_CANVAS
-
 typedef std::vector<SystemGlyphData> SystemGlyphDataVector;
 
 struct SystemTextLayoutData
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index 0ce40d3..7c99bed 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -499,6 +499,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
     vcl/osx/PictToBmpFlt \
     vcl/osx/clipboard \
     vcl/osx/service_entry \
+    vcl/quartz/cairo_quartz_cairo \
     $(vcl_quartz_code) \
     vcl/quartz/salgdiutils \
     vcl/osx/salnativewidgets \
@@ -668,6 +669,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
     vcl/win/source/app/salinst \
     vcl/win/source/app/salshl \
     vcl/win/source/app/saltimer \
+    vcl/win/source/gdi/cairo_win32_cairo \
     vcl/win/source/gdi/gdiimpl \
     vcl/win/source/gdi/salbmp \
     vcl/win/source/gdi/salgdi \
diff --git a/vcl/inc/quartz/salgdi.h b/vcl/inc/quartz/salgdi.h
index 7292479..12c3144 100644
--- a/vcl/inc/quartz/salgdi.h
+++ b/vcl/inc/quartz/salgdi.h
@@ -414,6 +414,12 @@ public:
 
     virtual SystemGraphicsData
                             GetGraphicsData() const SAL_OVERRIDE;
+    virtual bool            SupportsCairo() const SAL_OVERRIDE;
+    virtual cairo::SurfaceSharedPtr CreateSurface(const cairo::CairoSurfaceSharedPtr& rSurface) const SAL_OVERRIDE;
+    virtual cairo::SurfaceSharedPtr CreateSurface(const OutputDevice& rRefDevice, int x, int y, int width, int height) const SAL_OVERRIDE;
+    virtual cairo::SurfaceSharedPtr CreateBitmapSurface(const OutputDevice& rRefDevice, const BitmapSystemData& rData, const Size& rSize) const SAL_OVERRIDE;
+    virtual css::uno::Any   GetNativeSurfaceHandle(cairo::SurfaceSharedPtr& rSurface, const ::basegfx::B2ISize& rSize) const SAL_OVERRIDE;
+    virtual SystemFontData  GetSysFontData( int /* nFallbacklevel */ ) const SAL_OVERRIDE;
 
     virtual void            BeginPaint() SAL_OVERRIDE { };
     virtual void            EndPaint() SAL_OVERRIDE { };
diff --git a/vcl/inc/salgdi.hxx b/vcl/inc/salgdi.hxx
index 8c98d08..50e5e5a 100644
--- a/vcl/inc/salgdi.hxx
+++ b/vcl/inc/salgdi.hxx
@@ -36,8 +36,6 @@
 #include <map>
 #include <set>
 
-#include <config_cairo_canvas.h>
-
 class PhysicalFontCollection;
 class SalBitmap;
 class FontSelectPattern;
@@ -51,10 +49,7 @@ class OpenGLContext;
 class OutputDevice;
 class ServerFontLayout;
 struct SystemGraphicsData;
-
-#if ENABLE_CAIRO_CANVAS
 struct SystemFontData;
-#endif // ENABLE_CAIRO_CANVAS
 
 namespace basegfx {
     class B2DVector;
@@ -443,8 +438,6 @@ public:
 
     virtual SystemGraphicsData  GetGraphicsData() const = 0;
 
-#if ENABLE_CAIRO_CANVAS
-
     /// Check whether cairo will work
     virtual bool                SupportsCairo() const = 0;
     /// Create Surface from given cairo surface
@@ -457,8 +450,6 @@ public:
 
     virtual SystemFontData      GetSysFontData( int nFallbacklevel ) const = 0;
 
-#endif // ENABLE_CAIRO_CANVAS
-
 protected:
     virtual bool                setClipRegion( const vcl::Region& ) = 0;
 
diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h
index 504737a..fdd931c 100644
--- a/vcl/inc/win/salgdi.h
+++ b/vcl/inc/win/salgdi.h
@@ -448,6 +448,12 @@ public:
     virtual bool            IsNativeControlSupported( ControlType nType, ControlPart nPart ) SAL_OVERRIDE;
 
     virtual SystemGraphicsData GetGraphicsData() const SAL_OVERRIDE;
+    virtual bool               SupportsCairo() const SAL_OVERRIDE;
+    virtual cairo::SurfaceSharedPtr CreateSurface(const cairo::CairoSurfaceSharedPtr& rSurface) const SAL_OVERRIDE;
+    virtual cairo::SurfaceSharedPtr CreateSurface(const OutputDevice& rRefDevice, int x, int y, int width, int height) const SAL_OVERRIDE;
+    virtual cairo::SurfaceSharedPtr CreateBitmapSurface(const OutputDevice& rRefDevice, const BitmapSystemData& rData, const Size& rSize) const SAL_OVERRIDE;
+    virtual css::uno::Any      GetNativeSurfaceHandle(cairo::SurfaceSharedPtr& rSurface, const ::basegfx::B2ISize& rSize) const SAL_OVERRIDE;
+    virtual SystemFontData     GetSysFontData( int nFallbacklevel ) const SAL_OVERRIDE;
 
     virtual void               BeginPaint() SAL_OVERRIDE;
     virtual void               EndPaint() SAL_OVERRIDE;
diff --git a/vcl/quartz/salgdi.cxx b/vcl/quartz/salgdi.cxx
index 4f2104d..52cf48a 100644
--- a/vcl/quartz/salgdi.cxx
+++ b/vcl/quartz/salgdi.cxx
@@ -750,6 +750,16 @@ void AquaSalGraphics::FreeEmbedFontData( const void* pData, long /*nDataLen*/ )
     DBG_ASSERT( (pData!=NULL), "AquaSalGraphics::FreeEmbedFontData() is not implemented\n");
 }
 
+SystemFontData AquaSalGraphics::GetSysFontData( int /* nFallbacklevel */ ) const
+{
+    SystemFontData aSysFontData;
+    aSysFontData.nSize = sizeof( SystemFontData );
+
+    aSysFontData.bAntialias = !mbNonAntialiasedText;
+
+    return aSysFontData;
+}
+
 bool AquaSalGraphics::IsFlipped() const
 {
 #ifdef MACOSX
diff --git a/vcl/quartz/salgdicommon.cxx b/vcl/quartz/salgdicommon.cxx
index b4e50e4..1464f18 100644
--- a/vcl/quartz/salgdicommon.cxx
+++ b/vcl/quartz/salgdicommon.cxx
@@ -39,6 +39,11 @@
 #include <vcl/sysdata.hxx>
 #endif
 
+#include <config_cairo_canvas.h>
+#if ENABLE_CAIRO_CANVAS
+#include "cairo_quartz_cairo.hxx"
+#endif
+
 #if defined(IOS) && defined(DBG_UTIL)
 
 // Variables in TiledView.m
@@ -1445,6 +1450,119 @@ SystemGraphicsData AquaSalGraphics::GetGraphicsData() const
     return aRes;
 }
 
+bool AquaSalGraphics::SupportsCairo() const
+{
+#if ENABLE_CAIRO_CANVAS
+    return true;
+#else
+    return false;
+#endif
+}
+
+/**
+ * cairo::createSurface:     Create generic Canvas surface using given Cairo Surface
+ *
+ * @param rSurface Cairo Surface
+ *
+ * @return new Surface
+ */
+cairo::SurfaceSharedPtr AquaSalGraphics::CreateSurface(const cairo::CairoSurfaceSharedPtr& rSurface) const
+{
+#if ENABLE_CAIRO_CANVAS
+    return cairo::SurfaceSharedPtr(new cairo::QuartzSurface(rSurface));
+#else
+    (void)rSurface;
+    return cairo::SurfaceSharedPtr();
+#endif
+}
+
+/**
+ * cairo::createSurface:     Create Canvas surface using given VCL Window or Virtualdevice
+ *
+ * @param rSurface Cairo Surface
+ *
+ *  For VCL Window, use platform native system environment data (struct SystemEnvData in vcl/inc/sysdata.hxx)
+ *  For VCL Virtualdevice, use platform native system graphics data (struct SystemGraphicsData in vcl/inc/sysdata.hxx)
+ *
+ * @return new Surface
+ */
+cairo::SurfaceSharedPtr AquaSalGraphics::CreateSurface( const OutputDevice& rRefDevice,
+                                int x, int y, int width, int height ) const
+{
+    cairo::SurfaceSharedPtr surf;
+#if ENABLE_CAIRO_CANVAS
+    if( rRefDevice.GetOutDevType() == OUTDEV_WINDOW )
+    {
+        const vcl::Window &rWindow = (const vcl::Window &) rRefDevice;
+        const SystemEnvData* pSysData = GetSysData(&rWindow);
+        if (pSysData)
+            surf = cairo::SurfaceSharedPtr(new cairo::QuartzSurface(pSysData->pView, x, y, width, height));
+    }
+    else if( rRefDevice.GetOutDevType() == OUTDEV_VIRDEV )
+    {
+        SystemGraphicsData aSysData = ((const VirtualDevice&) rRefDevice).GetSystemGfxData();
+
+        if (aSysData.rCGContext)
+            surf = cairo::SurfaceSharedPtr(new cairo::QuartzSurface(aSysData.rCGContext, x, y, width, height));
+    }
+#else
+    (void)rRefDevice;
+    (void)x;
+    (void)y;
+    (void)width;
+    (void)height;
+#endif
+    return surf;
+}
+
+/**
+ * cairo::createBitmapSurface:   Create platform native Canvas surface from BitmapSystemData
+ * @param OutputDevice (not used)
+ * @param rData Platform native image data (struct BitmapSystemData in vcl/inc/bitmap.hxx)
+ * @param rSize width and height of the new surface
+ *
+ * Create a surface based on image data on rData
+ *
+ * @return new surface or empty surface
+ **/
+cairo::SurfaceSharedPtr AquaSalGraphics::CreateBitmapSurface( const OutputDevice&     /* rRefDevice */,
+                                      const BitmapSystemData& rData,
+                                      const Size&             rSize ) const
+{
+#if ENABLE_CAIRO_CANVAS
+    OSL_TRACE( "requested size: %d x %d available size: %d x %d",
+               rSize.Width(), rSize.Height(), rData.mnWidth, rData.mnHeight );
+
+    if ( rData.mnWidth == rSize.Width() && rData.mnHeight == rSize.Height() )
+    {
+        CGContextRef rContext = (CGContextRef)rData.rImageContext;
+        OSL_TRACE("Canvas::cairo::createBitmapSurface(): New native image surface, context = %p.", rData.rImageContext);
+
+        return cairo::SurfaceSharedPtr(new cairo::QuartzSurface(rContext, 0, 0, rData.mnWidth, rData.mnHeight));
+    }
+#else
+    (void)rData;
+    (void)rSize;
+#endif
+    return cairo::SurfaceSharedPtr();
+}
+
+css::uno::Any AquaSalGraphics::GetNativeSurfaceHandle(cairo::SurfaceSharedPtr& rSurface, const ::basegfx::B2ISize& /*rSize*/) const
+{
+    sal_IntPtr handle;
+#if ENABLE_CAIRO_CANVAS
+    cairo::QuartzSurface* pQuartzSurface = dynamic_cast<cairo::QuartzSurface*>(rSurface.get());
+    OSL_ASSERT(pQuartzSurface);
+    handle = sal_IntPtr (pQuartzSurface->getCGContext());
+#else
+    handle = 0;
+    (void)rSurface;
+#endif
+    css::uno::Sequence< css::uno::Any > args( 1 );
+    args[0] = css::uno::Any( handle );
+    return css::uno::Any( args );
+}
+
 long AquaSalGraphics::GetGraphicsWidth() const
 {
     long w = 0;
diff --git a/vcl/source/outdev/font.cxx b/vcl/source/outdev/font.cxx
index d9f239b..216c8a6 100644
--- a/vcl/source/outdev/font.cxx
+++ b/vcl/source/outdev/font.cxx
@@ -280,8 +280,6 @@ bool OutputDevice::GetFontCapabilities( vcl::FontCapabilities& rFontCapabilities
     return mpGraphics->GetFontCapabilities(rFontCapabilities);
 }
 
-#if ENABLE_CAIRO_CANVAS
-
 SystemFontData OutputDevice::GetSysFontData(int nFallbacklevel) const
 {
     SystemFontData aSysFontData;
@@ -296,8 +294,6 @@ SystemFontData OutputDevice::GetSysFontData(int nFallbacklevel) const
     return aSysFontData;
 }
 
-#endif // ENABLE_CAIRO_CANVAS
-
 void OutputDevice::ImplGetEmphasisMark( tools::PolyPolygon& rPolyPoly, bool& rPolyLine,
                                         Rectangle& rRect1, Rectangle& rRect2,
                                         long& rYOff, long& rWidth,
diff --git a/vcl/source/outdev/outdev.cxx b/vcl/source/outdev/outdev.cxx
index 0b6d0aa..2ae452e 100644
--- a/vcl/source/outdev/outdev.cxx
+++ b/vcl/source/outdev/outdev.cxx
@@ -324,10 +324,9 @@ SystemGraphicsData OutputDevice::GetSystemGfxData() const
     return mpGraphics->GetGraphicsData();
 }
 
-#if ENABLE_CAIRO_CANVAS
-
 bool OutputDevice::SupportsCairo() const
 {
+#if ENABLE_CAIRO_CANVAS
     if (!mpGraphics)
     {
         if (!AcquireGraphics())
@@ -335,6 +334,10 @@ bool OutputDevice::SupportsCairo() const
     }
 
     return mpGraphics->SupportsCairo();
+#else
+    (void) this; // loplugin:staticmethods
+    return false;
+#endif
 }
 
 cairo::SurfaceSharedPtr OutputDevice::CreateSurface(const cairo::CairoSurfaceSharedPtr& rSurface) const
@@ -377,8 +380,6 @@ css::uno::Any OutputDevice::GetNativeSurfaceHandle(cairo::SurfaceSharedPtr& rSur
     return mpGraphics->GetNativeSurfaceHandle(rSurface, rSize);
 }
 
-#endif // ENABLE_CAIRO_CANVAS
-
 css::uno::Any OutputDevice::GetSystemGfxDataAny() const
 {
     const SystemGraphicsData aSysData = GetSystemGfxData();
diff --git a/vcl/win/source/gdi/salgdi.cxx b/vcl/win/source/gdi/salgdi.cxx
index 95a5e94..23d4e5c 100644
--- a/vcl/win/source/gdi/salgdi.cxx
+++ b/vcl/win/source/gdi/salgdi.cxx
@@ -36,6 +36,10 @@
 #include "salgdiimpl.hxx"
 #include "gdiimpl.hxx"
 #include "opengl/win/gdiimpl.hxx"
+#include <config_cairo_canvas.h>
+#if ENABLE_CAIRO_CANVAS
+#include "cairo_win32_cairo.cxx"
+#endif
 
 #include <vcl/opengl/OpenGLHelper.hxx>
 
@@ -1074,6 +1078,141 @@ SystemGraphicsData WinSalGraphics::GetGraphicsData() const
     return aRes;
 }
 
+bool WinSalGraphics::SupportsCairo() const
+{
+#if ENABLE_CAIRO_CANVAS
+    return true;
+#else
+    return false;
+#endif
+}
+
+/**
+ * cairo::createSurface:     Create generic Canvas surface using given Cairo Surface
+ *
+ * @param rSurface Cairo Surface
+ *
+ * @return new Surface
+ */
+cairo::SurfaceSharedPtr WinSalGraphics::CreateSurface(const cairo::CairoSurfaceSharedPtr& rSurface) const
+{
+#if ENABLE_CAIRO_CANVAS
+    return cairo::SurfaceSharedPtr(new cairo::Win32Surface(rSurface));
+#else
+    (void)rSurface;
+    return cairo::SurfaceSharedPtr();
+#endif
+}
+
+/**
+ * cairo::createSurface:     Create Canvas surface using given VCL Window or Virtualdevice
+ *
+ * @param rSurface Cairo Surface
+ *
+ *  For VCL Window, use platform native system environment data (struct SystemEnvData in vcl/inc/sysdata.hxx)
+ *  For VCL Virtualdevice, use platform native system graphics data (struct SystemGraphicsData in vcl/inc/sysdata.hxx)
+ *
+ * @return new Surface
+ */
+cairo::SurfaceSharedPtr WinSalGraphics::CreateSurface( const OutputDevice& rRefDevice,
+                                int x, int y, int /* width */, int /* height */) const
+{
+    cairo::SurfaceSharedPtr surf;
+
+#if ENABLE_CAIRO_CANVAS
+    if( rRefDevice.GetOutDevType() == OUTDEV_WINDOW )
+    {
+        const vcl::Window &rWindow = (const vcl::Window &) rRefDevice;
+        const SystemEnvData* pSysData = GetSysData(&rWindow);
+        if (pSysData && pSysData->hWnd)
+            surf = cairo::SurfaceSharedPtr(new cairo::Win32Surface(GetDC((HWND) pSysData->hWnd), x, y));
+    }
+    else if( rRefDevice.GetOutDevType() == OUTDEV_VIRDEV )
+    {
+        SystemGraphicsData aSysData = ((const VirtualDevice&) rRefDevice).GetSystemGfxData();
+        if (aSysData.hDC)
+            surf = cairo::SurfaceSharedPtr(new cairo::Win32Surface((HDC) aSysData.hDC, x, y));
+    }
+#else
+    (void)rRefDevice;
+    (void)x;
+    (void)y;
+#endif
+
+    return surf;
+}
+
+/**
+ * cairo::createBitmapSurface:   Create platform native Canvas surface from BitmapSystemData
+ * @param OutputDevice (not used)
+ * @param rData Platform native image data (struct BitmapSystemData in vcl/inc/bitmap.hxx)
+ * @param rSize width and height of the new surface
+ *
+ * Create a surface based on image data on rData
+ *
+ * @return new surface or empty surface
+ **/
+cairo::SurfaceSharedPtr WinSalGraphics::CreateBitmapSurface( const OutputDevice&     /* rRefDevice */,
+                                      const BitmapSystemData& rData,
+                                      const Size&             rSize ) const
+{
+    OSL_TRACE( "requested size: %d x %d available size: %d x %d",
+               rSize.Width(), rSize.Height(), rData.mnWidth, rData.mnHeight );
+
+#if ENABLE_CAIRO_CANVAS
+    if ( rData.mnWidth == rSize.Width() && rData.mnHeight == rSize.Height() )
+        return cairo::SurfaceSharedPtr(new cairo::Win32Surface( rData ));
+#else
+    (void)rData;
+    (void)rSize;
+#endif
+    return cairo::SurfaceSharedPtr();
+}
+
+#if ENABLE_CAIRO_CANVAS
+namespace
+{
+    HBITMAP surface2HBitmap( const SurfaceSharedPtr& rSurface, const basegfx::B2ISize& rSize )
+    {
+        // can't seem to retrieve HBITMAP from cairo. copy content then
+        HDC hScreenDC=GetDC(NULL);
+        HBITMAP hBmpBitmap = CreateCompatibleBitmap( hScreenDC,
+                                                     rSize.getX(),
+                                                     rSize.getY() );
+
+        HDC     hBmpDC = CreateCompatibleDC( 0 );
+        HBITMAP hBmpOld = (HBITMAP) SelectObject( hBmpDC, hBmpBitmap );
+
+        BitBlt( hBmpDC, 0, 0, rSize.getX(), rSize.getX(),
+                cairo_win32_surface_get_dc(rSurface->getCairoSurface().get()),
+                0, 0, SRCCOPY );
+
+        SelectObject( hBmpDC, hBmpOld );
+        DeleteDC( hBmpDC );
+
+        return hBmpBitmap;
+    }
+}
+#endif
+
+css::uno::Any WinSalGraphics::GetNativeSurfaceHandle(cairo::SurfaceSharedPtr& rSurface, const ::basegfx::B2ISize& rSize) const
+{
+    // TODO(F2): check whether under all circumstances,
+    // the alpha channel is ignored here.
+    css::uno::Sequence< css::uno::Any > args( 1 );
+    sal_Int64 nHandle;
+#if ENABLE_CAIRO_CANVAS
+    nHandle = sal_Int64(surface2HBitmap(rSurface, rSize));
+#else
+    (void)rSurface;
+    (void)rSize;
+    nHandle = 0;
+#endif
+    args[1] = css::uno::Any(nHandle);
+    // caller frees the bitmap
+    return css::uno::Any( args );
+}
+
 void WinSalGraphics::BeginPaint()
 {
     return mpImpl->beginPaint();
diff --git a/vcl/win/source/gdi/salgdi3.cxx b/vcl/win/source/gdi/salgdi3.cxx
index 76cbc22..89b8d96 100644
--- a/vcl/win/source/gdi/salgdi3.cxx
+++ b/vcl/win/source/gdi/salgdi3.cxx
@@ -2773,4 +2773,19 @@ void WinSalGraphics::GetGlyphWidths( const PhysicalFontFace* pFont,
 void WinSalGraphics::DrawServerFontLayout( const ServerFontLayout& )
 {}
 
+SystemFontData WinSalGraphics::GetSysFontData( int nFallbacklevel ) const
+{
+    SystemFontData aSysFontData;
+
+    if (nFallbacklevel >= MAX_FALLBACK) nFallbacklevel = MAX_FALLBACK - 1;
+    if (nFallbacklevel < 0 ) nFallbacklevel = 0;
+
+    aSysFontData.hFont = mhFonts[nFallbacklevel];
+
+    OSL_TRACE("\r\n:WinSalGraphics::GetSysFontData(): FontID: %p, Fallback level: %d",
+              aSysFontData.hFont, nFallbacklevel);
+
+    return aSysFontData;
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 0394d49a70e14e176c047ced39e2e754fcc26f3d
Author: Jan Holesovsky <kendy at collabora.com>
Date:   Fri Jun 5 13:59:57 2015 +0200

    Revert "vcl: fix Android build"
    
    "Cleanup crossplatform cairo" breaks Android and iOS.
    
    This reverts commit e152b756b3558a3619e5bedb6b258cc7f0879e90.

diff --git a/include/vcl/sysdata.hxx b/include/vcl/sysdata.hxx
index 7a3ee4c..57217df 100644
--- a/include/vcl/sysdata.hxx
+++ b/include/vcl/sysdata.hxx
@@ -202,7 +202,7 @@ struct SystemGlyphData
     int                  fallbacklevel;
 };
 
-#if ENABLE_CAIRO_CANVAS || defined(ANDROID)
+#if ENABLE_CAIRO_CANVAS
 
 struct SystemFontData
 {
diff --git a/vcl/inc/salgdi.hxx b/vcl/inc/salgdi.hxx
index 21095f9..8c98d08 100644
--- a/vcl/inc/salgdi.hxx
+++ b/vcl/inc/salgdi.hxx
@@ -443,7 +443,7 @@ public:
 
     virtual SystemGraphicsData  GetGraphicsData() const = 0;
 
-#if ENABLE_CAIRO_CANVAS || defined(ANDROID)
+#if ENABLE_CAIRO_CANVAS
 
     /// Check whether cairo will work
     virtual bool                SupportsCairo() const = 0;


More information about the Libreoffice-commits mailing list