canvas/Library_cairocanvas.mk | 7 canvas/source/cairo/cairo_cairo.cxx | 4 canvas/source/cairo/cairo_canvas.cxx | 4 canvas/source/cairo/cairo_canvasbitmap.cxx | 5 canvas/source/cairo/cairo_os2_cairo.cxx | 348 +++++++++++++++++++++++++++++ canvas/source/cairo/cairo_os2_cairo.hxx | 62 +++++ canvas/source/cairo/cairo_textlayout.cxx | 34 ++ scp2/source/canvas/cairocanvas.scp | 2 vcl/os2/source/gdi/salvd.cxx | 7 9 files changed, 469 insertions(+), 4 deletions(-)
New commits: commit 72e77eb1bf361865f05ba4664406381cbc24af31 Author: Yuri Dario <yda...@apache.org> Date: Fri Mar 2 15:50:41 2018 +0000 #i127723# add cairo graphics support also on OS/2. diff --git a/canvas/Library_cairocanvas.mk b/canvas/Library_cairocanvas.mk index 5d2c09e48dfc..3715db898003 100644 --- a/canvas/Library_cairocanvas.mk +++ b/canvas/Library_cairocanvas.mk @@ -87,6 +87,13 @@ $(eval $(call gb_Library_add_linked_libs,cairocanvas,\ user32 \ )) +else ifeq ($(OS),OS2) +$(eval $(call gb_Library_add_exception_objects,cairocanvas,\ + canvas/source/cairo/cairo_os2_cairo \ +)) +$(eval $(call gb_Library_add_libs,cairocanvas,\ + -lft2lib \ +)) else ifeq ($(OS),MACOSX) diff --git a/canvas/source/cairo/cairo_cairo.cxx b/canvas/source/cairo/cairo_cairo.cxx index 9e65da700f05..d86fb1f03cbc 100644 --- a/canvas/source/cairo/cairo_cairo.cxx +++ b/canvas/source/cairo/cairo_cairo.cxx @@ -33,6 +33,10 @@ # include <tools/postwin.h> #endif +#ifdef OS2 +# include <svpm.h> +#endif + #include <vcl/sysdata.hxx> #include <vcl/syschild.hxx> diff --git a/canvas/source/cairo/cairo_canvas.cxx b/canvas/source/cairo/cairo_canvas.cxx index cdbec4c73af5..a6361eed4e76 100644 --- a/canvas/source/cairo/cairo_canvas.cxx +++ b/canvas/source/cairo/cairo_canvas.cxx @@ -49,6 +49,10 @@ # include <tools/postwin.h> #endif +#ifdef OS2 +# include <svpm.h> +#endif + #include <vcl/sysdata.hxx> #include "cairo_canvas.hxx" diff --git a/canvas/source/cairo/cairo_canvasbitmap.cxx b/canvas/source/cairo/cairo_canvasbitmap.cxx index 02200d0a6583..068e82cdb488 100644 --- a/canvas/source/cairo/cairo_canvasbitmap.cxx +++ b/canvas/source/cairo/cairo_canvasbitmap.cxx @@ -37,6 +37,7 @@ #elif defined CAIRO_HAS_WIN32_SURFACE # include "cairo_win32_cairo.hxx" # include <cairo-win32.h> +#elif defined OS2 #else # error Native API needed. #endif @@ -179,6 +180,8 @@ namespace cairocanvas aRV = uno::Any( args ); // caller frees the bitmap +#elif defined CAIRO_HAS_OS2_SURFACE + OSL_TRACE( "CanvasBitmap::getFastPropertyValue case 1"); #else # error Please define fast prop retrieval for your platform! #endif @@ -248,6 +251,8 @@ namespace cairocanvas aRV = uno::Any( args ); // caller frees the bitmap +#elif defined CAIRO_HAS_OS2_SURFACE + OSL_TRACE( "CanvasBitmap::getFastPropertyValue case 2"); #else # error Please define fast prop retrieval for your platform! #endif diff --git a/canvas/source/cairo/cairo_os2_cairo.cxx b/canvas/source/cairo/cairo_os2_cairo.cxx new file mode 100644 index 000000000000..788b51e3897f --- /dev/null +++ b/canvas/source/cairo/cairo_os2_cairo.cxx @@ -0,0 +1,348 @@ +/************************************************************** + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + *************************************************************/ + + + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_canvas.hxx" + +#ifdef OS2 +/************************************************************************ + * OS/2 surface backend for Apache OpenOffice Cairo Canvas * + ************************************************************************/ + +#define INCL_WIN +#include <os2.h> + +#include <osl/diagnose.h> +#include <vcl/bitmap.hxx> +#include <vcl/virdev.hxx> +#include <vcl/sysdata.hxx> + +#include "cairo_os2_cairo.hxx" + +namespace cairo +{ + +#include <cairo/cairo-os2.h> + +// workaround for svpm.h definitions +#define sal_Bool BOOL +#define PM_FIXED FIXED +#define LPGLYPHMETRICS void* +#define MAT2 void +#include <ft2lib.h> + + bool IsCairoWorking( OutputDevice* ) + { + // trivially true for OS/2 + return true; + } + + /** + * Surface::Surface: Create generic Canvas surface using given Cairo Surface + * + * @param pSurface Cairo Surface + * + * This constructor only stores data, it does no processing. + * It is used with e.g. cairo_image_surface_create_for_data() + * and Surface::getSimilar() + * + * Set the mpSurface to the new surface or NULL + **/ + Os2Surface::Os2Surface( const CairoSurfaceSharedPtr& pSurface ) : + mpSurface( pSurface ) + {} + + /** + * Surface::Surface: Create Canvas surface from Window reference. + * @param pSysData Platform native system environment data (struct SystemEnvData in vcl/inc/sysdata.hxx) + * @param x horizontal location of the new surface + * @param y vertical location of the new surface + * + * pSysData contains the platform native Window reference. + * pSysData is used to create a surface on the Window + * + * Set the mpSurface to the new surface or NULL + **/ + Os2Surface::Os2Surface( HWND hwnd, int x, int y, int w, int h) : + mpSurface( + cairo_os2_surface_create_for_window( hwnd, w + x, h + y), + &cairo_surface_destroy) + { + OSL_TRACE( "Os2Surface::Os2Surface hwnd:%x offset: %d,%d size %d x %d", + hwnd, x, y, w, h); + cairo_surface_set_device_offset( mpSurface.get(), 0, 0); + } + + /** + * Surface::Surface: Create platform native Canvas surface from BitmapSystemData + * @param pBmpData Platform native image data (struct BitmapSystemData in vcl/inc/bitmap.hxx) + * + * Create a surface based on image data on pBmpData + * + * Set the mpSurface to the new surface or NULL + **/ + Os2Surface::Os2Surface( const BitmapSystemData& rBmpData ) : + mpSurface() + { + OSL_TRACE( "Os2Surface::Os2Surface bitmap"); +#if 0 + OSL_ASSERT(rBmpData.pDIB == NULL); + + if(rBmpData.pDIB != NULL) { + // So just leave 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. + } + else + { + HDC hDC = CreateCompatibleDC(NULL); + void* hOrigBitmap; + OSL_TRACE ("Surface::Surface(): Selecting bitmap %p into DC %p", rBmpData.pDDB, hDC); + hOrigBitmap = SelectObject( hDC, (HANDLE)rBmpData.pDDB ); + if(hOrigBitmap == NULL) + OSL_TRACE ("SelectObject failed: %d", GetLastError ()); + mpSurface.reset( + cairo_win32_surface_create(hDC), + &cairo_surface_destroy); + } +#endif + } + + /** + * Surface::getCairo: Create Cairo (drawing object) for the Canvas surface + * + * @return new Cairo or NULL + **/ + CairoSharedPtr Os2Surface::getCairo() const + { + return CairoSharedPtr( cairo_create(mpSurface.get()), + &cairo_destroy ); + } + + /** + * Surface::getSimilar: Create new similar Canvas surface + * @param aContent format of the new surface (cairo_content_t from cairo/src/cairo.h) + * @param width width of the new surface + * @param height height of the new surface + * + * Creates a new Canvas surface. This normally creates platform native surface, even though + * generic function is used. + * + * Cairo surface from aContent (cairo_content_t) + * + * @return new surface or NULL + **/ + SurfaceSharedPtr Os2Surface::getSimilar( Content aContent, int width, int height ) const + { + OSL_TRACE( "Os2Surface::getSimilar size: %d x %d", width, height); + // cairo hits assertion in cairo-surface.c#535 if size is 0x0 + int w = (width == 0 ? 1 : width); + int h = (height == 0 ? 1 : height); + return SurfaceSharedPtr( + new Os2Surface( + CairoSurfaceSharedPtr( + cairo_surface_create_similar( mpSurface.get(), aContent, w, h), + &cairo_surface_destroy ))); + } + + /** + * Surface::Resize: Resizes the Canvas surface. + * @param width new width of the surface + * @param height new height of the surface + * + * Only used on X11. + * + * @return The new surface or NULL + **/ + void Os2Surface::Resize( int width, int height) + { + cairo_os2_surface_set_size( mpSurface.get(), width, height, false); + } + + void Os2Surface::flush() const + { + OSL_TRACE( "Os2Surface::flush"); + cairo_os2_surface_paint_window( mpSurface.get(), NULL, NULL, 0); + } + + /** + * Surface::getDepth: Get the color depth of the Canvas surface. + * + * @return color depth + **/ + int Os2Surface::getDepth() const + { + OSL_TRACE( "Os2Surface::getDepth"); + if (mpSurface) { + switch (cairo_surface_get_content (mpSurface.get())) { + case CAIRO_CONTENT_ALPHA: return 8; break; + case CAIRO_CONTENT_COLOR: return 24; break; + case CAIRO_CONTENT_COLOR_ALPHA: return 32; break; + } + } + OSL_TRACE("Canvas::cairo::Surface::getDepth(): ERROR - depth unspecified!"); + return -1; + } + + + /** + * cairo::createVirtualDevice: Create a VCL virtual device for the CGContext in the cairo Surface + * + * @return The new virtual device + **/ + boost::shared_ptr<VirtualDevice> Os2Surface::createVirtualDevice() const + { + SystemGraphicsData aSystemGraphicsData; + aSystemGraphicsData.nSize = sizeof(SystemGraphicsData); + //aSystemGraphicsData.hDC = cairo_win32_surface_get_dc( mpSurface.get() ); + OSL_TRACE( "Os2Surface::createVirtualDevice"); + + return boost::shared_ptr<VirtualDevice>( + new VirtualDevice( &aSystemGraphicsData, sal::static_int_cast<USHORT>(getDepth()) )); + } + + + /** + * cairo::createSurface: Create generic Canvas surface using given Cairo Surface + * + * @param rSurface Cairo Surface + * + * @return new Surface + */ + SurfaceSharedPtr createSurface( const CairoSurfaceSharedPtr& rSurface ) + { + OSL_TRACE( "Os2Surface createSurface from surface"); + return SurfaceSharedPtr(new Os2Surface(rSurface)); + } + + + /** + * 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 + */ + SurfaceSharedPtr createSurface( const OutputDevice& rRefDevice, + int x, int y, int width, int height) + { + SurfaceSharedPtr surf; + // cairo hits assertion in cairo-surface.c#535 if size is 0x0 + int w = (width == 0 ? 1 : width); + int h = (height == 0 ? 1 : height); + OSL_TRACE( "createSurface refDev:%x, offset: %d x %d", &rRefDevice, x, y); + + if( rRefDevice.GetOutDevType() == OUTDEV_WINDOW ) + { + OSL_TRACE( "Os2Surface createSurface for WINDOW"); + const Window &rWindow = (const Window &) rRefDevice; + const SystemEnvData* pSysData = GetSysData(&rWindow); + if (pSysData && pSysData->hWnd) + surf = SurfaceSharedPtr(new Os2Surface( + pSysData->hWnd, x, y, w, h)); + } + else if( rRefDevice.GetOutDevType() == OUTDEV_VIRDEV ) + { + OSL_TRACE( "Os2Surface createSurface for VIRDEV"); + //SystemGraphicsData aSysData = ((const VirtualDevice&) rRefDevice).GetSystemGfxData(); + //if (aSysData.hDC) + // surf = SurfaceSharedPtr(new Os2Surface((HDC) aSysData.hDC, x, y)); + } + 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 + **/ + SurfaceSharedPtr createBitmapSurface( const OutputDevice& /* rRefDevice */, + const BitmapSystemData& rData, + const Size& rSize ) + { + OSL_TRACE( "createBitmapSurface 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() ) + return SurfaceSharedPtr(new Os2Surface( rData )); + else + return SurfaceSharedPtr(); + } + + typedef USHORT WCHAR; + extern "C" ULONG APIENTRY Ft2GetGlyphIndices( HPS, WCHAR *, int, USHORT *, ULONG ); + + /** + * 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, const char* font) + { + WCHAR unicode[2]; + USHORT glyph_index; + HPS hps = NULL; + FATTRS fontAttrs; + APIRET rc; + + hps = WinGetPS( HWND_DESKTOP); + if (!hps) return 0; + + memset( &fontAttrs, 0, sizeof( fontAttrs)); + fontAttrs.usRecordLength = sizeof( FATTRS); + fontAttrs.usCodePage = 850; + fontAttrs.fsType = FATTR_TYPE_MBCS; + fontAttrs.fsFontUse = FATTR_FONTUSE_NOMIX; + strcpy( fontAttrs.szFacename, font); + rc = Ft2CreateLogFont( hps, NULL, 1L, &fontAttrs); + rc = Ft2SetCharSet( hps, 1L); + + unicode[0] = ucs4; + unicode[1] = 0; + if (Ft2GetGlyphIndices( hps, unicode, 1, &glyph_index, 0) == -1) { + glyph_index = 0; + } + + WinReleasePS( hps); + + return glyph_index; + } + + +} // namespace cairo + +#endif // OS2 diff --git a/canvas/source/cairo/cairo_os2_cairo.hxx b/canvas/source/cairo/cairo_os2_cairo.hxx new file mode 100644 index 000000000000..6de36baf7a6e --- /dev/null +++ b/canvas/source/cairo/cairo_os2_cairo.hxx @@ -0,0 +1,62 @@ +/************************************************************** + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + *************************************************************/ + + + +#ifndef _CAIROCANVAS_OS2_CAIRO_HXX +#define _CAIROCANVAS_OS2_CAIRO_HXX + +#include "cairo_cairo.hxx" + +typedef ULONG HFONT; + +namespace cairo { + + class Os2Surface : public Surface + { + CairoSurfaceSharedPtr mpSurface; + + public: + /// takes over ownership of passed cairo_surface + explicit Os2Surface( const CairoSurfaceSharedPtr& pSurface ); + /// create surface on subarea of given drawable + Os2Surface( HWND hWnd, int x, int y, int w, int h); + /// create surface for given bitmap data + Os2Surface( const BitmapSystemData& rBmpData ); + + // Surface interface + virtual CairoSharedPtr getCairo() const; + virtual CairoSurfaceSharedPtr getCairoSurface() const { return mpSurface; } + virtual SurfaceSharedPtr getSimilar( Content aContent, int width, int height ) const; + + virtual boost::shared_ptr<VirtualDevice> createVirtualDevice() const; + + virtual void Resize( int width, int height ); + + virtual void flush() const; + + int getDepth() const; + }; + + unsigned long ucs4toindex(unsigned int ucs4, const char* font); +} + +#endif diff --git a/canvas/source/cairo/cairo_textlayout.cxx b/canvas/source/cairo/cairo_textlayout.cxx index 4a776bb7e734..4fb559ec8a0a 100644 --- a/canvas/source/cairo/cairo_textlayout.cxx +++ b/canvas/source/cairo/cairo_textlayout.cxx @@ -44,6 +44,12 @@ #undef min #endif #endif + +#ifdef OS2 +#define INCL_WIN +#include <os2.h> +#endif + #include <vcl/sysdata.hxx> #include <basegfx/matrix/b2dhommatrix.hxx> @@ -62,6 +68,9 @@ #elif defined CAIRO_HAS_XLIB_SURFACE # include "cairo_xlib_cairo.hxx" # include <cairo-ft.h> +#elif defined CAIRO_HAS_OS2_SURFACE +# include "cairo_os2_cairo.hxx" +# include <cairo-os2.h> #else # error Native API needed. #endif @@ -486,6 +495,12 @@ namespace cairocanvas // Cairo requires standard glyph indexes (ETO_GLYPH_INDEX), while vcl/win/* uses ucs4 chars. // Convert to standard indexes aGlyph.index = cairo::ucs4toindex((unsigned int) aGlyph.index, rSysFontData.hFont); + #elif defined(CAIRO_HAS_OS2_SURFACE) + // Cairo requires standard glyph indexes (ETO_GLYPH_INDEX), while vcl/os2/* uses codepage chars. + // Convert to standard indexes + ::rtl::OString aFontName = ::rtl::OUStringToOString( + rOutDev.GetFont().GetName(), RTL_TEXTENCODING_UTF8); + aGlyph.index = cairo::ucs4toindex((unsigned int) aGlyph.index, aFontName); #endif aGlyph.x = systemGlyph.x; aGlyph.y = systemGlyph.y; @@ -516,13 +531,27 @@ namespace cairocanvas #elif defined CAIRO_HAS_XLIB_SURFACE font_face = cairo_ft_font_face_create_for_ft_face((FT_Face)rSysFontData.nFontId, rSysFontData.nFontFlags); + #elif defined CAIRO_HAS_OS2_SURFACE + // see below #else # error Native API needed. #endif CairoSharedPtr pSCairo = pSurface->getCairo(); - cairo_set_font_face( pSCairo.get(), font_face); + #if defined CAIRO_HAS_OS2_SURFACE + ::rtl::OString aFontName = ::rtl::OUStringToOString( + rOutDev.GetFont().GetName(), RTL_TEXTENCODING_UTF8); + cairo_font_slant_t slant = (rOutDev.GetFont().GetItalic() == ITALIC_NONE ? + CAIRO_FONT_SLANT_NORMAL : CAIRO_FONT_SLANT_ITALIC); + cairo_font_weight_t weight = (rOutDev.GetFont().GetWeight() == WEIGHT_NORMAL ? + CAIRO_FONT_WEIGHT_NORMAL : CAIRO_FONT_WEIGHT_BOLD); + cairo_select_font_face( pSCairo.get(), aFontName, + slant, weight); + #endif + + if (font_face) + cairo_set_font_face( pSCairo.get(), font_face); // create default font options. cairo_get_font_options() does not retrieve the surface defaults, // only what has been set before with cairo_set_font_options() @@ -611,7 +640,8 @@ namespace cairocanvas } cairo_restore( pSCairo.get() ); - cairo_font_face_destroy(font_face); + if (font_face) + cairo_font_face_destroy(font_face); } return true; } diff --git a/scp2/source/canvas/cairocanvas.scp b/scp2/source/canvas/cairocanvas.scp index ba9422f83620..cc7bf3d1004a 100644 --- a/scp2/source/canvas/cairocanvas.scp +++ b/scp2/source/canvas/cairocanvas.scp @@ -29,6 +29,8 @@ File gid_File_Lib_CairoCanvas Dir = SCP2_OOO_BIN_DIR; #ifdef UNX Name = STRING(CONCAT2(cairocanvas.uno,UNXSUFFIX)); + #elif defined OS2 + Name = "cairocnv.dll"; #else Name = "cairocanvas.uno.dll"; #endif diff --git a/vcl/os2/source/gdi/salvd.cxx b/vcl/os2/source/gdi/salvd.cxx index 994b7464d0ec..e333ebdd55fd 100644 --- a/vcl/os2/source/gdi/salvd.cxx +++ b/vcl/os2/source/gdi/salvd.cxx @@ -202,6 +202,9 @@ sal_Bool Os2SalVirtualDevice::SetSize( long nDX, long nDY ) void Os2SalVirtualDevice::GetSize( long& rWidth, long& rHeight ) { - DevQueryCaps( mpGraphics->mhDC, CAPS_WIDTH, CAPS_WIDTH, (LONG*)rWidth ); - DevQueryCaps( mpGraphics->mhDC, CAPS_HEIGHT, CAPS_HEIGHT, (LONG*)rHeight ); + LONG alData; + DevQueryCaps( mpGraphics->mhDC, CAPS_WIDTH, 1L, &alData); + rWidth = alData; + DevQueryCaps( mpGraphics->mhDC, CAPS_HEIGHT, 1L, &alData); + rHeight = alData; } _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits